// LogicView.cpp : implementation file // #include "stdafx.h" #include "LogicView.h" #include "math.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CLogicView IMPLEMENT_DYNCREATE(CLogicView, CView) CLogicView::CLogicView() { displayMemory = new CDC; windowActive = False; currentOperation = Waiting; currentTrace = -1; peekingMessages = False; startMove = -1; subMode = Select; bugEnabled = False; zoomInCursor = AfxGetApp()->LoadCursor(IDC_ZOOM_IN); zoomOutCursor = AfxGetApp()->LoadCursor(IDC_ZOOM_OUT); zoomSelCursor = AfxGetApp()->LoadCursor(IDC_ZOOM_SEL); openHandCursor = AfxGetApp()->LoadCursor(IDC_OPEN_HAND); closeHandCursor = AfxGetApp()->LoadCursor(IDC_CLOSE_HAND); arrowCursor = AfxGetApp()->LoadStandardCursor(IDC_ARROW); } CLogicView::~CLogicView() { delete displayMemory; } BEGIN_MESSAGE_MAP(CLogicView, CView) //{{AFX_MSG_MAP(CLogicView) ON_WM_SIZE() ON_WM_HSCROLL() ON_WM_VSCROLL() ON_WM_LBUTTONDOWN() ON_WM_LBUTTONUP() ON_WM_MOUSEMOVE() ON_WM_SETCURSOR() ON_WM_KEYDOWN() ON_WM_KEYUP() ON_WM_CONTEXTMENU() //}}AFX_MSG_MAP ON_MESSAGE(WM_DRAW_BACKGROUND, OnDrawBackground) ON_COMMAND_RANGE(START_MESSAGE_ID, LAST_MESSAGE_ID, OnPlugIn) END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CLogicView drawing void CLogicView::OnDraw(CDC* pDC) { //CDocument* pDoc = GetDocument(); // TODO: add draw code here CRect client_rect; GetClientRect(client_rect); CBitmap *old_bitmap; old_bitmap = displayMemory->SelectObject(myParent->screenBitmap); pDC->BitBlt(0,0,client_rect.right,client_rect.bottom, displayMemory, myParent->logicSize.left, myParent->logicSize.top, SRCCOPY); displayMemory->SelectObject(old_bitmap); } ///////////////////////////////////////////////////////////////////////////// // CLogicView diagnostics #ifdef _DEBUG void CLogicView::AssertValid() const { CView::AssertValid(); } void CLogicView::Dump(CDumpContext& dc) const { CView::Dump(dc); } #endif //_DEBUG ///////////////////////////////////////////////////////////////////////////// // CLogicView message handlers void CLogicView::OnInitialUpdate() { //afxDump << "CLogicView::OnInitialUpdate" << endl; CView::OnInitialUpdate(); windowActive = True; CClientDC client_dc(this); if(displayMemory->GetSafeHdc() == NULL) { displayMemory->CreateCompatibleDC(&client_dc); } int h_Min, h_Max; h_Min = 0; h_Max = (int)(myParent->document->lastTrace - myParent->document->firstTrace); SetScrollRange(SB_HORZ, h_Min, h_Max); SetScrollPos(SB_HORZ, 0); // The -2 is one trace of messages and leave the last trace on screen SetScrollRange(SB_VERT, 0, myParent->document->traceCount - 2); SetScrollPos(SB_VERT, 0); myParent->SaveSize(); myParent->Draw(this); } ///////////////////////////////////////////////////////////////////////////// // BOOL CLogicView::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext) { // TODO: Add your specialized code here and/or call the base class return CWnd::Create(lpszClassName, lpszWindowName, dwStyle | WS_VSCROLL | WS_HSCROLL, rect, pParentWnd, nID, pContext); } void CLogicView::OnSize(UINT nType, int cx, int cy) { //afxDump << "CLogicView::OnSize" << endl; CView::OnSize(nType, cx, cy); if (windowActive) { myParent->SaveSize(); myParent->SetTime(); myParent->Draw(this); } } void CLogicView::Render(CRect placement) { MY_RGB color; color.red = 255; color.blue = 255; color.green = 255; myParent->DrawCRect( placement,color); currentOperation = MakingTrace; currentTrace = 0; CRect size; myParent->logicView->GetClientRect(size); myParent->logicView->InvalidateRect(size); if (windowActive) { //drawingTimer = SetTimer(1, 10, NULL); color.red = 255; color.blue = 0; color.green = 0; myParent->DrawLine( myParent->viewedTime.startTime + (myParent->viewedTime.pixelToTime * (myParent->timeSize.left + myParent->timeView->refrenceLinePixel)), myParent->viewedTime.startTime + (myParent->viewedTime.pixelToTime * (myParent->timeSize.left + myParent->timeView->refrenceLinePixel)), myParent->logicSize.top, myParent->logicSize.bottom, 0, color, 1); SetScrollPos(SB_HORZ, (int)myParent->viewedTime.startTime); if (!peekingMessages) { PostMessage(WM_DRAW_BACKGROUND); } } } void CLogicView::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* /*pScrollBar*/) { // TODO: Add your message handler code here and/or call default int old_position, current_position, temp_position; old_position = current_position = GetScrollPos(SB_VERT); BOOL absolute = FALSE; switch(nSBCode) { case SB_THUMBPOSITION: case SB_THUMBTRACK: current_position = nPos; absolute = TRUE; break; case SB_LINELEFT: temp_position = 1; current_position -= temp_position; break; case SB_LINERIGHT: temp_position = 1; current_position += temp_position; break; case SB_PAGELEFT: temp_position = 3; current_position -= temp_position; break; case SB_PAGERIGHT: temp_position = 3; current_position += temp_position; break; case SB_RIGHT: temp_position = 5; current_position += temp_position; break; case SB_LEFT: temp_position = 5; current_position -= temp_position; break; default: break; } SetScrollPos(SB_VERT,current_position); if (old_position != current_position) { myParent->Draw(myParent->nameView); myParent->Draw(this); } } void CLogicView::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* /*pScrollBar*/) { int old_position, current_position, temp_position; old_position = current_position = GetScrollPos(SB_HORZ); BOOL absolute = FALSE; switch(nSBCode) { case SB_THUMBPOSITION: case SB_THUMBTRACK: current_position = nPos; absolute = TRUE; break; case SB_LINELEFT: temp_position = 1; current_position -= temp_position; break; case SB_LINERIGHT: temp_position = 1; current_position += temp_position; break; case SB_PAGELEFT: temp_position = 10; current_position -= temp_position; break; case SB_PAGERIGHT: temp_position = 10; current_position += temp_position; break; case SB_RIGHT: temp_position = 20; current_position += temp_position; break; case SB_LEFT: temp_position = 20; current_position -= temp_position; break; default: break; } MoveTime(current_position, absolute); myParent->Draw(myParent->timeView); myParent->Draw(this); } void CLogicView::MoveTime(int current_position, BOOL absolute) { //CScrollBar *pScrollBar = GetScrollBarCtrl(SB_HORZ); CLabRatDoc *document = (CLabRatDoc *)GetDocument(); int old_position = GetScrollPos(SB_HORZ); old_position += (int)document->firstTrace; current_position += (int)document->firstTrace; Time diffrence = (Time)old_position - (Time)current_position; if (absolute == TRUE) { myParent->viewedTime.startTime = current_position; } else { myParent->viewedTime.startTime -= (diffrence)*(SCALES[myParent->viewedTime.secondEnum] * myParent->viewedTime.step)*0.5f; } Max_Clamp(myParent->viewedTime.startTime, document->lastTrace); Min_Clamp(myParent->viewedTime.startTime, document->firstTrace); myParent->viewedTime.endTime = ((Time)myParent->viewedTime.startTime) + (myParent->viewedTime.pixelToTime * myParent->timeSize.Width()); Max_Clamp(myParent->viewedTime.endTime, document->lastTrace); SetScrollPos(SB_HORZ,(int)myParent->viewedTime.startTime - ((int)document->firstTrace)); } void CLogicView::ScaleTime(int scale_factor, CPoint point) { myParent->viewedTime.startTime = myParent->viewedTime.startTime + (point.x * myParent->viewedTime.pixelToTime); int step_enum = 0; for (int i = SCALE_STEP_COUNT-1; i >= 0; --i) { if (myParent->viewedTime.step <= SCALE_STEP[i]) { step_enum = i; } } int new_step = step_enum + scale_factor; int new_second = myParent->viewedTime.secondEnum; int seconds_to_add = 0; if (new_step > 0.0f) { seconds_to_add = (int)new_step / SCALE_STEP_COUNT; new_step = new_step - (seconds_to_add * SCALE_STEP_COUNT); new_second += seconds_to_add; } else if (new_step < 0.0f) { int over = -new_step + SCALE_STEP_COUNT - 1; seconds_to_add = ((int)over / SCALE_STEP_COUNT); new_step = new_step + (seconds_to_add * SCALE_STEP_COUNT); new_second -= seconds_to_add; } if (!(new_second >= SCALES_COUNT) && !(new_second < 0)) { myParent->viewedTime.secondEnum = new_second; step_enum = new_step; myParent->viewedTime.step = SCALE_STEP[new_step]; } else { return; } myParent->SetComboBox(step_enum, myParent->viewedTime.secondEnum); myParent->SetTime(); } LONG CLogicView::OnDrawBackground(UINT /*wParam*/, LONG /*lParam*/) { #if 0 peekingMessages = True; MSG message; while(::PeekMessage(&message, NULL,0,0, PM_REMOVE)) { ::TranslateMessage(&message); ::DispatchMessage(&message); } peekingMessages = False; #else if (bugEnabled) { peekingMessages = True; MSG message; while(::PeekMessage(&message, NULL,0,0, PM_NOREMOVE)) { AfxGetApp()->PumpMessage(); } peekingMessages = False; } #endif if (currentTrace == myParent->traceCount) { return 0L; } if (currentOperation == MakingTrace) { //afxDump << "Making : " << currentTrace << endl; TraceLine *trace_line; trace_line = (TraceLine *)myParent->traceListArray->GetAt(currentTrace); trace_line->MakeTrace( myParent->viewedTime.startTime, myParent->viewedTime.endTime, myParent->viewedTime.timeToPixel); ++currentTrace; if (currentTrace == myParent->traceCount) { currentTrace = GetScrollPos(SB_VERT); currentOperation = DrawingTrace; } PostMessage(WM_DRAW_BACKGROUND); } else if (currentOperation == DrawingTrace) { //afxDump << "Drawing : " << currentTrace << endl; int place_to_draw = myParent->borderSize + myParent->logicSize.top; int start = GetScrollPos(SB_VERT); for (int i = start; i < myParent->traceCount; ++i) { if (place_to_draw >= myParent->logicSize.bottom && currentTrace != (myParent->traceCount - 1)) { currentTrace = myParent->traceCount - 1; // if off of the screen just // draw the markers break; } TraceLine *trace_line; trace_line = (TraceLine *)myParent->traceListArray->GetAt(i); if (i == currentTrace) { trace_line->Draw(place_to_draw); ++currentTrace; CRect size; myParent->logicView->GetClientRect(size); myParent->logicView->InvalidateRect(size); break; } place_to_draw += trace_line->CalculateSize(); place_to_draw += myParent->borderSize; } if (currentTrace == myParent->traceCount) { currentTrace = 0; currentOperation = Waiting; myParent->Draw(myParent->valueView); // let it end } else { PostMessage(WM_DRAW_BACKGROUND); } } return 0L; } void CLogicView::OnLButtonDown(UINT /*nFlags*/, CPoint point) { if (subMode == Move) { startMove = point.x * myParent->viewedTime.pixelToTime; } else if (subMode == Select) { myParent->viewedTime.startTimeSel = myParent->viewedTime.startTime + (point.x * myParent->viewedTime.pixelToTime); myParent->viewedTime.endTimeSel = myParent->viewedTime.startTime + (point.x * myParent->viewedTime.pixelToTime); Min_Clamp(myParent->viewedTime.startTimeSel,myParent->document->firstTrace); Max_Clamp(myParent->viewedTime.endTimeSel,myParent->document->lastTrace); SetStatusBar(); myParent->Draw(myParent->timeView); } else if (subMode == SelectRegion) { myParent->viewedTime.endTimeSel = myParent->viewedTime.startTime + (point.x * myParent->viewedTime.pixelToTime); Max_Clamp(myParent->viewedTime.endTimeSel,myParent->document->lastTrace); SetStatusBar(); myParent->Draw(myParent->timeView); } } void CLogicView::OnLButtonUp(UINT /*nFlags*/, CPoint point) { if (subMode == ZoomIn) { ScaleTime(-1, point); myParent->Draw(myParent->timeView); myParent->Draw(this); } else if (subMode == ZoomOut) { ScaleTime(1, point); myParent->Draw(myParent->timeView); myParent->Draw(this); } else if (subMode == Move) { DragTime(point); myParent->Draw(myParent->timeView); myParent->Draw(this); startMove = -1; } if (subMode == Select) { myParent->viewedTime.endTimeSel = myParent->viewedTime.startTime + (point.x * myParent->viewedTime.pixelToTime); Max_Clamp(myParent->viewedTime.endTimeSel,myParent->document->lastTrace); SetStatusBar(); myParent->Draw(myParent->timeView); } if (subMode == SelectRegion) { myParent->viewedTime.endTimeSel = myParent->viewedTime.startTime + (point.x * myParent->viewedTime.pixelToTime); Max_Clamp(myParent->viewedTime.endTimeSel,myParent->document->lastTrace); SetStatusBar(); myParent->Draw(myParent->timeView); } } void CLogicView::OnMouseMove(UINT nFlags, CPoint point) { if (subMode == Move) { if (startMove != -1) { DragTime(point); myParent->Draw(myParent->timeView); if(bugEnabled) { myParent->Draw(this); } } } if (subMode == Select || subMode == SelectRegion) { if (nFlags & MK_LBUTTON) { myParent->viewedTime.endTimeSel = myParent->viewedTime.startTime + (point.x * myParent->viewedTime.pixelToTime); Max_Clamp(myParent->viewedTime.endTimeSel,myParent->document->lastTrace); SetStatusBar(); myParent->Draw(myParent->timeView); } } CView::OnMouseMove(nFlags, point); } void CLogicView::DragTime(CPoint points_to_move) { Time time_to_move = points_to_move.x * myParent->viewedTime.pixelToTime; time_to_move = startMove - time_to_move; startMove = points_to_move.x * myParent->viewedTime.pixelToTime; //afxDump << time_to_move << endl; myParent->viewedTime.startTime += time_to_move; myParent->viewedTime.endTime = myParent->viewedTime.startTime + (myParent->viewedTime.pixelToTime * myParent->timeSize.Width()); Max_Clamp(myParent->viewedTime.endTime, myParent->document->lastTrace); SetScrollPos(SB_HORZ, (int)myParent->viewedTime.startTime); } BOOL CLogicView::OnSetCursor(CWnd* /* pWnd */, UINT /*nHitTest*/, UINT /* message */) { switch(subMode) { case ZoomIn: ::SetCursor(zoomInCursor); break; case ZoomOut: ::SetCursor(zoomOutCursor); break; case ZoomSelect: ::SetCursor(zoomSelCursor); break; case Select: case SelectRegion: ::SetCursor(arrowCursor); break; case Move: ::SetCursor(openHandCursor); break; } return True; } void CLogicView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) { // TODO: Add your message handler code here and/or call default CView::OnKeyDown(nChar, nRepCnt, nFlags); switch(nChar) { case VK_SHIFT : if (subMode == Select || subMode == SelectRegion) { subMode = SelectRegion; } else { subMode = Select; } ::SetCursor(arrowCursor); break; case VK_CONTROL : subMode = Move; ::SetCursor(openHandCursor); break; case 'Z': subMode = ZoomIn; ::SetCursor(zoomInCursor); break; case 'X': subMode = ZoomOut; ::SetCursor(zoomOutCursor); break; } } void CLogicView::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) { // TODO: Add your message handler code here and/or call default CView::OnKeyUp(nChar, nRepCnt, nFlags); switch(nChar) { case VK_SHIFT: case VK_CONTROL : case 'Z': case 'X': if (myParent->currentMode == CChildFrame::ZoomMode) { subMode = ZoomIn; ::SetCursor(zoomInCursor); } else if (myParent->currentMode == CChildFrame::MoveMode) { subMode = Move; ::SetCursor(openHandCursor); } if (myParent->currentMode == CChildFrame::SelectMode) { subMode = Select; ::SetCursor(arrowCursor); } break; } } void CLogicView::OnContextMenu(CWnd* /*pWnd*/, CPoint point) { int selection = FindSelectionScreen(point); if (selection != -1) { CMenu menu; menu.CreateMenu(); CMenu *sub_menu; TraceLine *trace_line; menuOnTraceIndex = selection; trace_line = (TraceLine *)myParent->traceListArray->GetAt(selection); sub_menu = myParent->analyzerRegistry.CreateMenu(trace_line->GetTraceType()); menu.AppendMenu( MF_POPUP, (int)sub_menu->GetSafeHmenu()); menu.GetSubMenu(0)->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y, this); sub_menu->DestroyMenu(); menu.DestroyMenu(); delete sub_menu; } } int CLogicView::FindSelectionScreen(CPoint point) { CRect c_rect; GetClientRect(c_rect); ClientToScreen(c_rect); point.x -= c_rect.left; point.y -= c_rect.top; int trace_hit = -1; int top = myParent->borderSize; int start = GetScrollPos(SB_VERT); for (int i = start; i < myParent->traceCount; ++i) { TraceLine *trace_line; trace_line = (TraceLine *)myParent->traceListArray->GetAt(i); int bottom = top + trace_line->CalculateSize(); if (point.y < bottom && point.y > top) { trace_hit = i; } top = bottom; top += myParent->borderSize; } return trace_hit; } void CLogicView::OnPlugIn( UINT nID ) { myParent->analyzerRegistry.Analyze(myParent, menuOnTraceIndex, nID); } void CLogicView::SetStatusBar(void) { char temp[60]; char time[60]; sprintf(time, "%8.4f", (myParent->viewedTime.startTimeSel) / SCALES[myParent->viewedTime.secondEnum]); strcpy(temp, time); strcat(temp, SCALES_TEXT[myParent->viewedTime.secondEnum]); CString str; str = "StartSel : "; str += temp; str += " "; sprintf(time, "%8.4f", (myParent->viewedTime.endTimeSel) / SCALES[myParent->viewedTime.secondEnum]); strcpy(temp, time); strcat(temp, SCALES_TEXT[myParent->viewedTime.secondEnum]); str += "EndSel : "; str += temp; str += " "; sprintf(time, "%8.4f", (fabs(myParent->viewedTime.endTimeSel-myParent->viewedTime.startTimeSel)) / SCALES[myParent->viewedTime.secondEnum]); strcpy(temp, time); strcat(temp, SCALES_TEXT[myParent->viewedTime.secondEnum]); str += "TotalTimeSelected : "; str += temp; #if 0 str.Format("StartSel: %fs EndSel: %fs TotalTimeSelected: %fs", myParent->viewedTime.startTimeSel, myParent->viewedTime.endTimeSel, fabs(myParent->viewedTime.endTimeSel-myParent->viewedTime.startTimeSel)); #endif CMainFrame *mainfrm = (CMainFrame*) AfxGetApp()->m_pMainWnd; CStatusBar *status = &mainfrm->m_wndStatusBar; status->SetPaneText(1, str); }