// XTPTrackHeader.cpp : implementation of the CXTPTrackHeader class. // // This file is a part of the XTREME REPORTCONTROL MFC class library. // (c)1998-2012 Codejock Software, All Rights Reserved. // // THIS SOURCE FILE IS THE PROPERTY OF CODEJOCK SOFTWARE AND IS NOT TO BE // RE-DISTRIBUTED BY ANY MEANS WHATSOEVER WITHOUT THE EXPRESSED WRITTEN // CONSENT OF CODEJOCK SOFTWARE. // // THIS SOURCE CODE CAN ONLY BE USED UNDER THE TERMS AND CONDITIONS OUTLINED // IN THE XTREME TOOLKIT PRO LICENSE AGREEMENT. CODEJOCK SOFTWARE GRANTS TO // YOU (ONE SOFTWARE DEVELOPER) THE LIMITED RIGHT TO USE THIS SOFTWARE ON A // SINGLE COMPUTER. // // CONTACT INFORMATION: // support@codejock.com // http://www.codejock.com // ///////////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "Common/XTPCustomHeap.h" #include "Common/XTPSystemHelpers.h" #include "Common/XTPSmartPtrInternalT.h" #include "Common/XTPColorManager.h" #include "../XTPReportDefines.h" #include "../XTPReportColumn.h" #include "../XTPReportHeader.h" #include "../XTPReportControl.h" #include "../XTPReportPaintManager.h" #include "XTPTrackHeader.h" #include "XTPTrackControl.h" #include "XTPTrackPaintManager.h" #include "XTPTrackUndoManager.h" #include "XTPTrackBlock.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CXTPTrackHeader CXTPTrackHeader::CXTPTrackHeader(CXTPReportControl* pControl, CXTPReportColumns* pColumns) : CXTPReportHeader(pControl, pColumns) { } CXTPTrackHeader::~CXTPTrackHeader() { } void CXTPTrackHeader::Draw(CDC* pDC, CRect rcHeader, int nLeftOffset) { CXTPReportHeader::Draw(pDC, rcHeader, nLeftOffset); CXTPTrackControl* pTrackControl = (CXTPTrackControl*)m_pControl; pTrackControl->GetTrackPaintManager()->DrawTrackHeader(pDC); } void CXTPTrackHeader::OnMoveScrollBar(CPoint pt, BOOL bResize) { CXTPTrackControl* pControl = (CXTPTrackControl*)GetControl(); int fromPosition = pControl->TrackToPosition(m_ptStartDrag.x); int toPosition = pControl->TrackToPosition(pt.x); int delta = toPosition - fromPosition; if (pControl->IsLayoutRTL()) delta = -delta; int nWorkAreaMin = m_nOldWorkAreaMin + (bResize != 2 ? delta : 0); int nWorkAreaMax = m_nOldWorkAreaMax + (bResize != 1 ? delta : 0); if (nWorkAreaMin < pControl->GetTimeLineMin()) { if (bResize != 1) nWorkAreaMax = pControl->GetTimeLineMin() + nWorkAreaMax - nWorkAreaMin; nWorkAreaMin = pControl->GetTimeLineMin(); } if (nWorkAreaMax > pControl->GetTimeLineMax()) { if (bResize != 2) nWorkAreaMin = pControl->GetTimeLineMax() - (nWorkAreaMax - nWorkAreaMin); nWorkAreaMax = pControl->GetTimeLineMax(); } if (nWorkAreaMax < nWorkAreaMin) if (bResize == 1) nWorkAreaMin = nWorkAreaMax; else nWorkAreaMax = nWorkAreaMin; pControl->SetWorkArea(nWorkAreaMin, nWorkAreaMax); pControl->RedrawControl(); } void CXTPTrackHeader::StartDragScrollBar(BOOL bResize) { // set capture to the window which received this message m_pControl->SetCapture(); CXTPTrackControl* pControl = (CXTPTrackControl*)GetControl(); CPoint pt(0, 0); GetCursorPos(&pt); m_ptStartDrag = pt; m_nOldWorkAreaMin = pControl->GetWorkAreaMin(); m_nOldWorkAreaMax = pControl->GetWorkAreaMax(); ::SetCursor(((CXTPTrackControl*)pControl)->m_hResizeCursor); // get messages until capture lost or cancelled/accepted while (CWnd::GetCapture() == m_pControl) { MSG msg; if (!::GetMessage(&msg, NULL, 0, 0)) { AfxPostQuitMessage((int)msg.wParam); break; } if (msg.message == WM_LBUTTONUP) break; else if (msg.message == WM_MOUSEMOVE && pt != msg.pt) { pt = msg.pt; OnMoveScrollBar(pt, bResize); } else if (msg.message == WM_KEYDOWN) { if (msg.wParam == VK_ESCAPE) { break; } } else DispatchMessage(&msg); } ReleaseCapture(); } void CXTPTrackHeader::OnMoveSlider(CPoint pt, BOOL bResize) { CXTPTrackControl* pControl = (CXTPTrackControl*)GetControl(); CXTPTrackControl* pTrackControl = (CXTPTrackControl*)m_pControl; CRect rcTimeLineArea = pTrackControl->GetTimelineArea(); CRect rcHeaderArea = pTrackControl->GetElementRect(xtpReportElementRectHeaderArea); CXTPReportColumn* pTrackColumn = pTrackControl->GetTrackColumn(); int nLeftOffset = pTrackColumn->GetRect().left; int nRightOffset = pTrackColumn->GetRect().right; CRect rcSliderArea(nLeftOffset, rcTimeLineArea.top, nRightOffset, rcTimeLineArea.top + 10); int fromPosition = MulDiv(m_ptStartDrag.x, (pControl->GetTimeLineMax() - pControl->GetTimeLineMin()), rcSliderArea.Width()); int toPosition = MulDiv(pt.x, (pControl->GetTimeLineMax() - pControl->GetTimeLineMin()), rcSliderArea.Width()); int delta = toPosition - fromPosition; if (pControl->IsLayoutRTL()) delta = -delta; int nViewPortMin = m_nOldViewPortMin + (bResize != 2 ? delta : 0); int nViewPortMax = m_nOldViewPortMax + (bResize != 1 ? delta : 0); if (nViewPortMin < pControl->GetTimeLineMin()) { if (bResize != 1) nViewPortMax = pControl->GetTimeLineMin() + nViewPortMax - nViewPortMin; nViewPortMin = pControl->GetTimeLineMin(); } if (nViewPortMax > pControl->GetTimeLineMax()) { if (bResize != 2) nViewPortMin = pControl->GetTimeLineMax() - (nViewPortMax - nViewPortMin); nViewPortMax = pControl->GetTimeLineMax(); } if (nViewPortMax <= nViewPortMin) { if (bResize == 1) nViewPortMin = nViewPortMax - 1; else nViewPortMax = nViewPortMin + 1; } pControl->SetViewPort(nViewPortMin, nViewPortMax); } void CXTPTrackHeader::StartDragSlider(BOOL bResize) { // set capture to the window which received this message m_pControl->SetCapture(); CXTPTrackControl* pControl = (CXTPTrackControl*)GetControl(); CPoint pt(0, 0); GetCursorPos(&pt); m_ptStartDrag = pt; m_nOldViewPortMin= pControl->GetViewPortMin(); m_nOldViewPortMax = pControl->GetViewPortMax(); ::SetCursor(((CXTPTrackControl*)pControl)->m_hResizeCursor); // get messages until capture lost or cancelled/accepted while (CWnd::GetCapture() == m_pControl) { MSG msg; if (!::GetMessage(&msg, NULL, 0, 0)) { AfxPostQuitMessage((int)msg.wParam); break; } if (msg.message == WM_LBUTTONUP) break; else if (msg.message == WM_MOUSEMOVE && pt != msg.pt) { pt = msg.pt; OnMoveSlider(pt, bResize); } else if (msg.message == WM_KEYDOWN) { if (msg.wParam == VK_ESCAPE) { break; } } else DispatchMessage(&msg); } ReleaseCapture(); } void CXTPTrackHeader::OnMoveMarker(CPoint pt, int nMarkerIndex) { CXTPTrackControl* pControl = (CXTPTrackControl*)GetControl(); int fromPosition = pControl->TrackToPosition(m_ptStartDrag.x); int toPosition = pControl->TrackToPosition(pt.x); int delta = toPosition - fromPosition; if (pControl->IsLayoutRTL()) delta = -delta; if (nMarkerIndex == -1) { int nPosition = max(pControl->GetTimeLineMin(), min(pControl->GetTimeLineMax(), m_nOldMarkerPos + delta)); pControl->SetTimeLinePosition(nPosition); pControl->SendMessageToParent(XTP_NM_TRACK_TIMELINECHANGED); } else { CXTPTrackMarker* pMarker = pControl->GetMarkers()->GetAt(nMarkerIndex); int nPosition = max(pControl->GetTimeLineMin(), min(pControl->GetTimeLineMax(), m_nOldMarkerPos + delta)); pMarker->SetPosition(nPosition); pControl->SendMessageToParent(XTP_NM_TRACK_MARKERCHANGED, 0, pMarker); } pControl->RedrawControl(); } void CXTPTrackHeader::StartDragMarker(int nMarkerIndex) { // set capture to the window which received this message m_pControl->SetCapture(); CXTPTrackControl* pControl = (CXTPTrackControl*)GetControl(); pControl->GetUndoManager()->StartGroup(); CPoint pt(0, 0); GetCursorPos(&pt); m_ptStartDrag = pt; m_nOldMarkerPos = nMarkerIndex == -1 ? pControl->GetTimeLinePosition() : pControl->GetMarkers()->GetAt(nMarkerIndex)->GetPosition(); ::SetCursor(((CXTPTrackControl*)pControl)->m_hMoveCursor); // get messages until capture lost or cancelled/accepted while (CWnd::GetCapture() == m_pControl) { MSG msg; if (!::GetMessage(&msg, NULL, 0, 0)) { AfxPostQuitMessage((int)msg.wParam); break; } if (msg.message == WM_LBUTTONUP) break; else if (msg.message == WM_MOUSEMOVE && pt != msg.pt) { pt = msg.pt; OnMoveMarker(pt, nMarkerIndex); } else if (msg.message == WM_KEYDOWN) { if (msg.wParam == VK_ESCAPE) { break; } } else DispatchMessage(&msg); } pControl->GetUndoManager()->EndGroup(); ReleaseCapture(); } void CXTPTrackHeader::OnLButtonDown(CPoint point) { CXTPTrackControl* pTrackControl = (CXTPTrackControl*)m_pControl; CRect rcTimeLineArea = pTrackControl->GetTimelineArea(); CRect rcHeaderArea = pTrackControl->GetElementRect(xtpReportElementRectHeaderArea); CXTPReportColumn* pTrackColumn = pTrackControl->GetTrackColumn(); if (!pTrackColumn || !pTrackColumn->IsVisible()) { CXTPReportHeader::OnLButtonDown(point); return; } int nLeftOffset = pTrackColumn->GetRect().left; int nRightOffset = pTrackColumn->GetRect().right; CRect rcSliderArea(nLeftOffset, rcTimeLineArea.top, nRightOffset, rcTimeLineArea.top + 10); CRect rcTimeArea(nLeftOffset, rcSliderArea.bottom, nRightOffset, rcHeaderArea.bottom); CRect rcColumnArea(nLeftOffset, rcHeaderArea.top, nRightOffset, rcHeaderArea.bottom - 3); int nMarker = pTrackControl->GetMarkers()->HitTest(point); if (nMarker != -1) { StartDragMarker(nMarker); return; } if (pTrackControl->m_bShowWorkArea) { int nWorkAreaMin = pTrackControl->PositionToTrack(pTrackControl->GetWorkAreaMin()); int nWorkAreaMax = pTrackControl->PositionToTrack(pTrackControl->GetWorkAreaMax()); CRect rcWorkAreaScrollBar(max(nLeftOffset, nWorkAreaMin), rcColumnArea.top, min(nRightOffset, nWorkAreaMax), rcColumnArea.bottom); rcWorkAreaScrollBar.InflateRect(7, 0); if (rcWorkAreaScrollBar.PtInRect(point)) { int nResize = 0; if (point.x < rcWorkAreaScrollBar.left + 7) nResize = 1; else if (point.x > rcWorkAreaScrollBar.right - 7) nResize = 2; StartDragScrollBar(nResize); return; } } rcSliderArea.DeflateRect(7, 0); int nZoomAreaMin = rcSliderArea.left + MulDiv(pTrackControl->GetViewPortMin() - pTrackControl->GetTimeLineMin(), rcSliderArea.Width(), pTrackControl->GetTimeLineMax() - pTrackControl->GetTimeLineMin()); int nZoomAreaMax = rcSliderArea.left + MulDiv(pTrackControl->GetViewPortMax() - pTrackControl->GetTimeLineMin(), rcSliderArea.Width(), pTrackControl->GetTimeLineMax() - pTrackControl->GetTimeLineMin()); CRect rcZoomSlider(nZoomAreaMin, rcSliderArea.top, nZoomAreaMax, rcSliderArea.bottom); rcZoomSlider.InflateRect(7, 0); if (rcZoomSlider.PtInRect(point)) { int nResize = 0; if (point.x < rcZoomSlider.left + 7) nResize = 1; else if (point.x > rcZoomSlider.right - 7) nResize = 2; StartDragSlider(nResize); return; } CRect rcRullerArea(rcTimeArea.left, rcTimeArea.top, rcTimeArea.right, rcColumnArea.top); if (rcRullerArea.PtInRect(point)) { pTrackControl->SetTimeLinePosition(pTrackControl->TrackToPosition(point.x)); StartDragMarker(-1); return; } if (rcColumnArea.PtInRect(point)) return; CXTPReportHeader::OnLButtonDown(point); } void CXTPTrackHeader::OnMouseMove(UINT nFlags, CPoint point) { if (::GetCapture() != NULL) { CXTPReportHeader::OnMouseMove(nFlags, point); return; } CXTPTrackControl* pTrackControl = (CXTPTrackControl*)m_pControl; CXTPReportColumn* pTrackColumn = pTrackControl->GetTrackColumn(); if (!pTrackColumn || !pTrackColumn->IsVisible()) { CXTPReportHeader::OnMouseMove(nFlags, point); return; } CRect rcTimeLineArea = pTrackControl->GetTimelineArea(); CRect rcHeaderArea = pTrackControl->GetElementRect(xtpReportElementRectHeaderArea); int nLeftOffset = pTrackColumn->GetRect().left; int nRightOffset = pTrackColumn->GetRect().right; CRect rcSliderArea(nLeftOffset, rcTimeLineArea.top, nRightOffset, rcTimeLineArea.top + 10); CRect rcTimeArea(nLeftOffset, rcSliderArea.bottom, nRightOffset, rcHeaderArea.bottom); CRect rcColumnArea(nLeftOffset, rcHeaderArea.top, nRightOffset, rcHeaderArea.bottom - 3); int nMarker = pTrackControl->GetMarkers()->HitTest(point); if (nMarker != -1) { ::SetCursor(((CXTPTrackControl*)GetControl())->m_hMoveCursor); return; } if (pTrackControl->m_bShowWorkArea) { int nWorkAreaMin = pTrackControl->PositionToTrack(pTrackControl->GetWorkAreaMin()); int nWorkAreaMax = pTrackControl->PositionToTrack(pTrackControl->GetWorkAreaMax()); CRect rcWorkAreaScrollBar(max(nLeftOffset, nWorkAreaMin), rcColumnArea.top, min(nRightOffset, nWorkAreaMax), rcColumnArea.bottom); rcWorkAreaScrollBar.InflateRect(7, 0); if (rcWorkAreaScrollBar.PtInRect(point)) { ::SetCursor(((CXTPTrackControl*)GetControl())->m_hResizeCursor); return; } } int nZoomAreaMin = rcSliderArea.left + MulDiv(pTrackControl->GetViewPortMin() - pTrackControl->GetTimeLineMin(), rcSliderArea.Width(), pTrackControl->GetTimeLineMax() - pTrackControl->GetTimeLineMin()); int nZoomAreaMax = rcSliderArea.left + MulDiv(pTrackControl->GetViewPortMax() - pTrackControl->GetTimeLineMin(), rcSliderArea.Width(), pTrackControl->GetTimeLineMax() - pTrackControl->GetTimeLineMin()); CRect rcZoomSlider(nZoomAreaMin, rcSliderArea.top, nZoomAreaMax, rcSliderArea.bottom); rcZoomSlider.InflateRect(7, 0); if (rcZoomSlider.PtInRect(point)) { ::SetCursor(((CXTPTrackControl*)GetControl())->m_hResizeCursor); return; } CXTPReportHeader::OnMouseMove(nFlags, point); }