// GaugeBrowserView.cpp : implementation of the CGaugeBrowserView class // // (c)1998-2025 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 "GaugeBrowser.h" #include "GaugeRectTracker.h" #include "GaugeBrowserDoc.h" #include "GaugeBrowserView.h" #include "PaneGauges.h" #include "PaneAssets.h" #include "MainFrm.h" #include #ifdef _DEBUG # define new DEBUG_NEW # undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CGaugeBrowserView construction/destruction CGaugeBrowserView::CGaugeBrowserView() { m_bShowCheckerboard = theApp.GetProfileInt(_T("GaugeBrowser"), _T("Checkboard"), FALSE); m_bShowResizeBox = theApp.GetProfileInt(_T("GaugeBrowser"), _T("ResizeBox"), FALSE); } CGaugeBrowserView::~CGaugeBrowserView() { theApp.WriteProfileInt(_T("GaugeBrowser"), _T("Checkboard"), m_bShowCheckerboard); theApp.WriteProfileInt(_T("GaugeBrowser"), _T("ResizeBox"), m_bShowResizeBox); } ///////////////////////////////////////////////////////////////////////////// // CGaugeBrowserView IMPLEMENT_DYNCREATE(CGaugeBrowserView, CView) BEGIN_MESSAGE_MAP(CGaugeBrowserView, CView) //{{AFX_MSG_MAP(CGaugeBrowserView) ON_WM_CREATE() ON_WM_LBUTTONDOWN() ON_WM_SETCURSOR() ON_WM_ERASEBKGND() ON_COMMAND(ID_VIEW_CHECKER, OnViewChecker) ON_UPDATE_COMMAND_UI(ID_VIEW_CHECKER, OnUpdateViewChecker) ON_COMMAND(ID_VIEW_RESIZEBOX, OnViewResizeBox) ON_UPDATE_COMMAND_UI(ID_VIEW_RESIZEBOX, OnUpdateViewResizeBox) //}}AFX_MSG_MAP ON_REGISTERED_MESSAGE(WM_ONCHANGEDRECT, CGaugeBrowserView::OnChangedRect) ON_NOTIFY(XTP_SBN_SCROLL, ID_INDICATOR_SLIDER, CGaugeBrowserView::OnSliderScroll) ON_COMMAND(ID_INDICATOR_RESET, CGaugeBrowserView::OnResetPos) ON_UPDATE_COMMAND_UI(ID_INDICATOR_SLIDER, CGaugeBrowserView::OnUpdateSlider) ON_COMMAND(ID_FILE_MIN, CGaugeBrowserView::OnFileMin) ON_COMMAND(ID_FILE_MAX, CGaugeBrowserView::OnFileMax) ON_COMMAND(ID_FILE_RESET, CGaugeBrowserView::OnFileReset) ON_UPDATE_COMMAND_UI_RANGE(ID_FILE_MIN, ID_FILE_RESET, OnUpdateFileResize) ON_XTP_WM_GAUGEUPDATE(OnGaugeUpdated) END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CView drawing void CGaugeBrowserView::OnDraw(CDC* pDC) { CXTPClientRect rClient(this); CXTPBufferDC memDC(*pDC, rClient, ::GetSysColor(COLOR_WINDOW)); memDC.FillSolidRect(rClient, ::GetSysColor(COLOR_APPWORKSPACE)); if (m_bShowCheckerboard) theApp.DrawCheckerBoard(&memDC, m_tracker.m_rect); // draw tracker on outside if (m_bShowResizeBox) m_tracker.Draw(&memDC, RGB(17, 17, 17), RGB(17, 17, 17)); } BOOL CGaugeBrowserView::PreCreateWindow(CREATESTRUCT& cs) { if (!CView::PreCreateWindow(cs)) return FALSE; cs.style |= WS_CLIPCHILDREN | WS_CLIPSIBLINGS; cs.dwExStyle &= ~WS_EX_CLIENTEDGE; return TRUE; } ///////////////////////////////////////////////////////////////////////////// // CGaugeBrowserView diagnostics #ifdef _DEBUG CGaugeBrowserDoc* CGaugeBrowserView::GetDocument() // non-debug version is inline { ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CGaugeBrowserDoc))); return (CGaugeBrowserDoc*)m_pDocument; } #endif //_DEBUG ///////////////////////////////////////////////////////////////////////////// // CGaugeBrowserView message handlers void CGaugeBrowserView::ResizeGauge(CRect* pRect) { if (::IsWindow(m_wndGauge.m_hWnd)) { m_wndGauge.MoveWindow(pRect, FALSE); m_wndGauge.Invalidate(FALSE); Invalidate(FALSE); } } void CGaugeBrowserView::SetGaugeRect(CSize size) { //-- save gauge default size. m_rcGauge = CRect(0, 0, XTP_DPI_X(size.cx), XTP_DPI_Y(size.cy)); //-- offset rect. m_rcGauge.OffsetRect(XTP_DPI_X(10), XTP_DPI_Y(10)); //-- set tracker size. m_tracker.SetTrackRect(this, &m_rcGauge); m_tracker.SetHandleMask(CGaugeRectTracker::thBottomRight | CGaugeRectTracker::thRight | CGaugeRectTracker::thBottom); ResizeGauge(&m_rcGauge); } void CGaugeBrowserView::OnFileMin() { CSize sizeMin(m_gi.size); sizeMin.cx = XTP_DPI_X(150); sizeMin.cy = XTP_DPI_Y(150); SetGaugeRect(sizeMin); } void CGaugeBrowserView::OnFileMax() { CXTPClientRect rClient(this); rClient.DeflateRect(XTP_DPI_X(10), XTP_DPI_Y(10), XTP_DPI_X(10), XTP_DPI_Y(10)); SetGaugeRect(rClient.Size()); } void CGaugeBrowserView::OnFileReset() { SetGaugeRect(m_gi.size); } int CGaugeBrowserView::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CView::OnCreate(lpCreateStruct) == -1) return -1; if (!m_wndGauge.Create(WS_VISIBLE | WS_CHILD, CRect(0, 0, 0, 0), this, IDR_GAUGE_CTRL)) { TRACE(_T("Error creating gauge control.\n")); return FALSE; } return 0; } BOOL CGaugeBrowserView::LoadGauge() { CWaitCursor wait; CGaugeBrowserDoc* pDoc = GetDocument(); if (NULL == pDoc) return FALSE; const CGaugeRepo::RepoItem* pRepoItem = pDoc->GetRepoItem(); if (NULL == pRepoItem) return FALSE; if (NULL == pRepoItem) { AfxMessageBox(_T("Unable to find a gauge in ") + pRepoItem->strPath, MB_ICONEXCLAMATION); return FALSE; } if (!LoadGaugeInfo(pRepoItem)) return FALSE; CRuntimeClass* pClass = NULL; switch (m_gi.type) { case gtMeter: pClass = RUNTIME_CLASS(CXTPGaugeMeterType); break; case gtState: pClass = RUNTIME_CLASS(CXTPGaugeStateType); break; } if (pClass == NULL) { AfxMessageBox(_T("Failed to set runtime class"), MB_ICONEXCLAMATION); return FALSE; } IStreamPtr stmTraits; if (FAILED(XTPCreateReadOnlyFileStream(m_gi.pRepoItem->strTraitsPath, &stmTraits))) { AfxMessageBox(_T("Failed to load gauge traits file"), MB_ICONEXCLAMATION); return FALSE; } CString strTraitsArgs; if (!m_gi.pRepoItem->strInitTraitsPath.IsEmpty()) { if (!XTPLoadFileText(m_gi.pRepoItem->strInitTraitsPath, strTraitsArgs)) { AfxMessageBox(_T("Failed to load gauge init traits file"), MB_ICONEXCLAMATION); return FALSE; } } CXTPGaugeTraits traits(*stmTraits, strTraitsArgs); traits.SetResourcePath(m_gi.pRepoItem->strPath); IStreamPtr stmStyle; if (FAILED(XTPCreateReadOnlyFileStream(m_gi.pRepoItem->strStylePath, &stmStyle))) { AfxMessageBox(_T("Failed to load gauge style file"), MB_ICONEXCLAMATION); return FALSE; } if (NULL == m_wndGauge.Load(pClass, *stmStyle, traits)) { AfxMessageBox(_T("Failed to load gauge"), MB_ICONEXCLAMATION); return FALSE; } #ifdef _DEBUG CString strFinalTraits; if (m_wndGauge.GetType()->DumpTraits(strFinalTraits)) { TRACE(_T("Final traits: %s\n"), strFinalTraits.operator LPCTSTR()); } #endif //-- resize the gauge. SetGaugeRect(m_gi.size); UpdateGaugePos(m_gi.pos); if (!m_gi.strStartAction.IsEmpty()) m_wndGauge.GetType()->InvokeAction(m_gi.strStartAction); return TRUE; } static BOOL FindString(LPCTSTR lpszBuff, LPCTSTR lpszFind, TCHAR chStart, TCHAR chStop, CString& strOut) { strOut = lpszBuff; if (strOut.Find(lpszFind) != -1) { int iFirst = strOut.Find(chStart) + 1; int iCount = strOut.Find(chStop, iFirst) - iFirst; strOut = strOut.Mid(iFirst, iCount); return !strOut.IsEmpty(); } return FALSE; } BOOL CGaugeBrowserView::LoadGaugeInfo(const CGaugeRepo::RepoItem* pRepoItem) { m_gi.Reset(); m_gi.pRepoItem = pRepoItem; CStdioFile file; if (!file.Open(pRepoItem->strTraitsPath, CFile::modeRead | CFile::typeText)) { TRACE(_T("Failed to open traits file: '%s'\n"), pRepoItem->strTraitsPath); return FALSE; } CString strBuffer; while (file.ReadString(strBuffer)) { CString strLine(strBuffer); strLine.Replace(_T(" "), _T("")); if (strLine.Find(_T("//")) == 0) continue; CString strOut; if (FindString(strLine, _T(".svg"), _T('\''), _T('\''), strOut)) { if (!m_gi.svgList.Exists(strOut)) m_gi.svgList.Add(strOut); } else if (FindString(strLine, _T("gaugeMin"), _T('='), _T(';'), strOut)) m_gi.min = _ttoi(strOut); else if (FindString(strLine, _T("gaugeMax"), _T('='), _T(';'), strOut)) { m_gi.max = _ttoi(strOut); if (m_gi.max > 25) m_gi.step = (m_gi.max % 5) ? 1 : 5; else m_gi.step = 1; } else if (FindString(strLine, _T("gaugePos"), _T('='), _T(';'), strOut)) m_gi.pos = _ttoi(strOut); else if (FindString(strLine, _T("gaugeWidth"), _T('='), _T(';'), strOut)) m_gi.size.cx = _ttoi(strOut) / 2; else if (FindString(strLine, _T("gaugeHeight"), _T('='), _T(';'), strOut)) m_gi.size.cy = _ttoi(strOut) / 2; else if (FindString(strLine, _T("gaugeType"), _T('='), _T(';'), strOut)) m_gi.type = (GaugeType)_ttoi(strOut); else if (FindString(strLine, _T("gaugeStartAction"), _T('='), _T(';'), strOut)) m_gi.strStartAction = strOut.Mid(1, strOut.GetLength() - 2); } file.Close(); if (m_gi.svgList.GetSize() > 0) { CMainFrame* pFrame = DYNAMIC_DOWNCAST(CMainFrame, AfxGetMainWnd()); if (NULL != pFrame) { pFrame->PostMessage(WM_UPDATEASSETSCOMBO, (WPARAM)&m_gi); return TRUE; } } return FALSE; } void CGaugeBrowserView::OnLButtonDown(UINT nFlags, CPoint point) { if (m_bShowResizeBox) { int nHit = m_tracker.HitTest(point); if (nHit != CRectTracker::hitMiddle) { if (m_tracker.Track(this, point)) Invalidate(FALSE); } } CView::OnLButtonDown(nFlags, point); } BOOL CGaugeBrowserView::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) { if (m_bShowResizeBox && pWnd == this && m_tracker.SetCursor(this)) return TRUE; return CView::OnSetCursor(pWnd, nHitTest, message); } LRESULT CGaugeBrowserView::OnChangedRect(WPARAM wParam, LPARAM /*lParam*/) { CRect* pRect = (CRect*)wParam; if (pRect) { ResizeGauge(pRect); CMainFrame* pFrame = DYNAMIC_DOWNCAST(CMainFrame, AfxGetMainWnd()); if (pFrame) { CString strMessage; strMessage.Format(IDS_GAUGEMESSAGE, pRect->Size().cx, pRect->Size().cy, m_gi.pos); pFrame->SendMessage(WM_SETMESSAGESTRING, (WPARAM)1, (LPARAM)(LPCTSTR)strMessage); } return 0; } return -1; } BOOL CGaugeBrowserView::OnEraseBkgnd(CDC* /*pDC*/) { return FALSE; } void CGaugeBrowserView::OnUpdateSlider(CCmdUI* pCmdUI) { pCmdUI->Enable(); } void CGaugeBrowserView::OnSliderScroll(NMHDR* pNMHDR, LRESULT* pResult) { NMXTPSCROLL* pNMScroll = (NMXTPSCROLL*)pNMHDR; int nPos = m_gi.pos; switch (pNMScroll->nSBCode) { case SB_TOP: nPos = m_gi.min; break; case SB_BOTTOM: nPos = m_gi.max; break; case SB_LINEUP: nPos = max(((m_gi.pos / m_gi.step) - 1) * m_gi.step, m_gi.min); break; case SB_LINEDOWN: nPos = min(((m_gi.pos / m_gi.step) + 1) * m_gi.step, m_gi.max); break; case SB_THUMBTRACK: nPos = pNMScroll->nPos; break; case SB_PAGEUP: nPos = max(m_gi.pos - m_gi.step, m_gi.min); break; case SB_PAGEDOWN: nPos = min(m_gi.pos + m_gi.step, m_gi.max); break; } if (nPos != m_gi.pos) UpdateGaugePos(nPos); *pResult = 0; } void CGaugeBrowserView::OnResetPos() { UpdateGaugePos(0); } void CGaugeBrowserView::UpdateGaugePos(int nPos) { m_gi.pos = nPos; if (m_wndGauge.IsMeterType()) m_wndGauge.GetMeterType()->SetCurrent(m_gi.pos); else if (m_wndGauge.IsStateType()) m_wndGauge.GetStateType()->SetState(m_gi.pos); m_wndGauge.GetType()->Update(); CMainFrame* pFrame = DYNAMIC_DOWNCAST(CMainFrame, AfxGetMainWnd()); if (NULL == pFrame) return; pFrame->GetSliderPane()->SetPos(m_gi.pos); CXTPWindowRect rcGauge(&m_wndGauge); CString strMessage; strMessage.Format(IDS_GAUGEMESSAGE, rcGauge.Size().cx, rcGauge.Size().cy, m_gi.pos); pFrame->SendMessage(WM_SETMESSAGESTRING, (WPARAM)1, (LPARAM)(LPCTSTR)strMessage); } void CGaugeBrowserView::OnInitialUpdate() { CView::OnInitialUpdate(); if (!LoadGauge()) { TRACE(_T("Failed to load gauge.\n")); } } void CGaugeBrowserView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint) { CGaugeBrowserDoc* pDoc = GetDocument(); if (pDoc) { CString strPathName = pDoc->GetPathName(); } } void CGaugeBrowserView::OnViewChecker() { m_bShowCheckerboard = !m_bShowCheckerboard; RedrawWindow(); } void CGaugeBrowserView::OnUpdateViewChecker(CCmdUI* pCmdUI) { pCmdUI->SetCheck(m_bShowCheckerboard); } void CGaugeBrowserView::OnViewResizeBox() { m_bShowResizeBox = !m_bShowResizeBox; RedrawWindow(); } void CGaugeBrowserView::OnUpdateViewResizeBox(CCmdUI* pCmdUI) { pCmdUI->SetCheck(m_bShowResizeBox); } void CGaugeBrowserView::OnUpdateFileResize(CCmdUI* pCmdUI) { pCmdUI->Enable(m_bShowResizeBox); } LRESULT CGaugeBrowserView::OnGaugeUpdated(WPARAM wParam, LPARAM lParam) { CXTPGaugeBaseType* pType = reinterpret_cast(lParam); _ASSERTE(NULL != pType); CXTPGaugeStateType* pStateType = DYNAMIC_DOWNCAST(CXTPGaugeStateType, pType); if (NULL != pStateType) { UINT nState = pStateType->GetState(); CMainFrame* pFrame = DYNAMIC_DOWNCAST(CMainFrame, AfxGetMainWnd()); if (NULL == pFrame) return 0; pFrame->GetSliderPane()->SetPos(XTPToIntChecked(nState)); } return 0; }