From 86e1f42eadf82199c66d669e9f333cf6fa71f527 Mon Sep 17 00:00:00 2001 From: Bill Su Date: Sat, 17 Jan 2026 13:09:31 -0500 Subject: [PATCH 01/80] wxWidgets: update wxTipWindow fixes wxScrolled<> improvements --- deps/wxWidgets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/wxWidgets b/deps/wxWidgets index 0396c266..d05c5c1d 160000 --- a/deps/wxWidgets +++ b/deps/wxWidgets @@ -1 +1 @@ -Subproject commit 0396c2661f434176c5198f2cac84ef91e5f1b540 +Subproject commit d05c5c1d3e55542e63711778193175c099774f60 From 117e954ba82c66d784a9fd07e57138e7ce6bceb4 Mon Sep 17 00:00:00 2001 From: Bill Su Date: Sat, 17 Jan 2026 19:58:32 -0500 Subject: [PATCH 02/80] CB::ToolTip: match wxTipWindow updates --- GShr/CyberBoard.h | 3 +-- GShr/LBoxGrfx.cpp | 2 +- GShr/LBoxGrfx.h | 2 +- GShr/LibMfc.cpp | 3 +-- 4 files changed, 4 insertions(+), 6 deletions(-) diff --git a/GShr/CyberBoard.h b/GShr/CyberBoard.h index 83bcf539..0f4eb7a8 100644 --- a/GShr/CyberBoard.h +++ b/GShr/CyberBoard.h @@ -2310,8 +2310,7 @@ namespace CB // tool shown by tipWindow decltype(toolInfos)::iterator tipTool = toolInfos.end(); - // owned by wx - wxTipWindow* tipWindow = nullptr; + wxTipWindow::Ref tipWindow; enum State { sNoTool, diff --git a/GShr/LBoxGrfx.cpp b/GShr/LBoxGrfx.cpp index 10864890..e923ee75 100644 --- a/GShr/LBoxGrfx.cpp +++ b/GShr/LBoxGrfx.cpp @@ -865,7 +865,7 @@ void CGrafixListBoxWx::DoToolTipHitProcessing(wxPoint point) if (!strTip.empty()) { wxRect screenTool(ClientToScreen(rctTool.GetTopLeft()), rctTool.GetSize()); - m_toolTip = new wxTipWindow(this, strTip, MAX_LISTITEM_TIP_WIDTH, &m_toolTip, &screenTool); + m_toolTip = wxTipWindow::New(this, strTip, MAX_LISTITEM_TIP_WIDTH, &screenTool); } } } diff --git a/GShr/LBoxGrfx.h b/GShr/LBoxGrfx.h index ce44d038..944c2d0b 100644 --- a/GShr/LBoxGrfx.h +++ b/GShr/LBoxGrfx.h @@ -525,7 +525,7 @@ class CGrafixListBoxWx : public CB::VListBoxHScroll #if 0 CToolTipCtrl m_toolMsgTip; // Tooltip for notifications #endif - wxTipWindow* m_toolTip = nullptr; // Tooltip of tile text popups + wxTipWindow::Ref m_toolTip; // Tooltip of tile text popups GameElement m_nCurItemCode; // current active tip item code // Drag and scroll support vars diff --git a/GShr/LibMfc.cpp b/GShr/LibMfc.cpp index 55975a4c..b36bf028 100644 --- a/GShr/LibMfc.cpp +++ b/GShr/LibMfc.cpp @@ -1140,9 +1140,8 @@ void CB::ToolTip::Notify() { screenRect = tipTool->wnd.get().GetScreenRect(); } - tipWindow = new wxTipWindow(&tipTool->wnd.get(), + tipWindow = wxTipWindow::New(&tipTool->wnd.get(), tipTool->tip, maxWidth, - &tipWindow, &screenRect); if (tipTool->flags & CENTER) { From dd889431801603d6756b073fe93e2ada307241ae Mon Sep 17 00:00:00 2001 From: Bill Su Date: Thu, 11 Dec 2025 14:47:00 -0500 Subject: [PATCH 03/80] FrmBited: work around wxWidgets 56bd4a --- GM/FrmBited.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/GM/FrmBited.cpp b/GM/FrmBited.cpp index 4b953c7d..20bad4db 100644 --- a/GM/FrmBited.cpp +++ b/GM/FrmBited.cpp @@ -50,7 +50,10 @@ CBitEditFrame::CBitEditFrame(wxDocument& doc, BASE(&doc, &view, &parent, wxID_ANY, doc.GetUserReadableName() + " - Tile Editor"), m_wndSplitter([this, &view]{ - wxSplitterWindow* retval = new wxSplitterWindow(this, + wxSplitterWindow* retval = new wxSplitterWindow; + // KLUDGE: prevent events until m_wndSplitter set + retval->Hide(); + retval->Create(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, @@ -76,6 +79,7 @@ CBitEditFrame::CBitEditFrame(wxDocument& doc, return retval; }()) { + m_wndSplitter->Show(); SetIcon(wxIcon(std::format("#{}", IDR_BITEDITOR), wxBITMAP_TYPE_ICO_RESOURCE, 16, 16)); From 3c3e915bb87525a4e34a9d0fc63eced50772e56b Mon Sep 17 00:00:00 2001 From: Bill Su Date: Mon, 8 Dec 2025 13:41:34 -0500 Subject: [PATCH 04/80] update to match wxWidgets 30de8f wxDC::GetClippingBox changes --- GM/VwEdtbrd.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GM/VwEdtbrd.cpp b/GM/VwEdtbrd.cpp index 933a661c..3d929e31 100644 --- a/GM/VwEdtbrd.cpp +++ b/GM/VwEdtbrd.cpp @@ -263,7 +263,7 @@ void CBrdEditView::OnDraw(wxDC& pDC) wxRect oRct; wxDC* pDrawDC = &pDC; - CB_VERIFY(pDC.GetClippingBox(oRct)); + pDC.GetClippingBox(oRct); if (oRct.IsEmpty()) { return; // Nothing to do From 95165601f96355bbca2805c5388b691a8dad2545 Mon Sep 17 00:00:00 2001 From: Bill Su Date: Sat, 21 Mar 2026 00:42:12 -0400 Subject: [PATCH 05/80] fixup! Improve support for parallel file format changes (#115) --- GShr/WinState.cpp | 2 ++ GShr/WinState.h | 2 ++ 2 files changed, 4 insertions(+) diff --git a/GShr/WinState.cpp b/GShr/WinState.cpp index 123e66c6..a1562e27 100644 --- a/GShr/WinState.cpp +++ b/GShr/WinState.cpp @@ -172,6 +172,7 @@ BOOL CWinStateManager::RestoreWindowState(CWnd* pWnd, CWinStateElement& pWse) { CMemFile file(pWse.m_pWinStateBfr, value_preserving_cast(pWse.m_pWinStateBfr.GetSize())); CArchive ar(&file, CArchive::load); + SetFileFeaturesGuard setFileFeaturesGuard(ar, fileFeatures); bOK = (BOOL)pWnd->SendMessage(WM_WINSTATE, (WPARAM)&ar, 1); ar.Close(); file.Detach(); @@ -260,6 +261,7 @@ void CWinStateManager::Serialize(CArchive& ar) if (dwCount == size_t(0)) return; fileVersion = CB::GetVersion(ar); + fileFeatures = CB::GetFeatures(ar); m_pList = MakeOwner(); while (dwCount--) { diff --git a/GShr/WinState.h b/GShr/WinState.h index 57006fcd..09e948c1 100644 --- a/GShr/WinState.h +++ b/GShr/WinState.h @@ -26,6 +26,7 @@ #define _WINSTATE_H #include "Board.h" +#include "Versions.h" /////////////////////////////////////////////////////////////////////// @@ -141,6 +142,7 @@ class CWinStateManager protected: CDocument* m_pDoc; int fileVersion = INT_MAX; + Features fileFeatures; typedef std::list> CWinStateList; OwnerOrNullPtr m_pList; // Win state element list }; From fd2cab72384d806bb348a3277aa28cb1d1e3f4a7 Mon Sep 17 00:00:00 2001 From: Bill Su Date: Wed, 18 Feb 2026 23:46:43 -0500 Subject: [PATCH 06/80] fixup! Frm*: add wxNativeContainerWindow to all frames to support docview --- GShr/LibMfc.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/GShr/LibMfc.cpp b/GShr/LibMfc.cpp index b36bf028..ef4db589 100644 --- a/GShr/LibMfc.cpp +++ b/GShr/LibMfc.cpp @@ -785,7 +785,8 @@ CB::wxNativeContainerWindowMixin::operator const wxNativeContainerWindow*() cons // N.B.: this is a dirty hack wxNativeContainerWindowMixin* ncThis = const_cast(this); - wxWindow& rThis = const_cast(*ncThis); + wxWindow& rThis = *ncThis; + CPP20_TRACE("{}({}:{}) === {}:{}\n", typeid(*mfcWnd).name(), (const void*)&*mfcWnd, (void*)mfcWnd->m_hWnd, rThis, WXHANDLE(rThis.GetHWND())); // fill in wx children list for (CWnd* mfcChild = mfcWnd->GetWindow(GW_CHILD) ; From 2477ed4bf4686c36b08e1d7458372478b4441686 Mon Sep 17 00:00:00 2001 From: Bill Su Date: Sun, 8 Feb 2026 01:09:42 -0500 Subject: [PATCH 07/80] CB::ToolTip: fix default width MFC default -1 means unlimited width (https://learn.microsoft.com/en-us/windows/win32/controls/ttm-setmaxtipwidth), but wxWidgets interprets -1 as -1. For compatibility with CB3.1, convert -1 to max int when passing to wx. --- GShr/LibMfc.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GShr/LibMfc.cpp b/GShr/LibMfc.cpp index ef4db589..598f72bd 100644 --- a/GShr/LibMfc.cpp +++ b/GShr/LibMfc.cpp @@ -1142,7 +1142,7 @@ void CB::ToolTip::Notify() screenRect = tipTool->wnd.get().GetScreenRect(); } tipWindow = wxTipWindow::New(&tipTool->wnd.get(), - tipTool->tip, maxWidth, + tipTool->tip, maxWidth != -1 ? maxWidth : std::numeric_limits::max(), &screenRect); if (tipTool->flags & CENTER) { From 6fa75dd5a52127ae3a3a1d7b620e6dc39d972cb3 Mon Sep 17 00:00:00 2001 From: Bill Su Date: Sat, 31 Jan 2026 04:39:13 -0500 Subject: [PATCH 08/80] VwBitedt: fix no-select check --- GM/VwBitedt.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GM/VwBitedt.cpp b/GM/VwBitedt.cpp index b0148818..12864968 100644 --- a/GM/VwBitedt.cpp +++ b/GM/VwBitedt.cpp @@ -1081,7 +1081,7 @@ void CBitEditView::OnImageBoardMask(wxCommandEvent& /*event*/) CBoardManager& pBMgr = GetDocument().GetBoardManager(); CBoardMaskDialog dlg(pBMgr); - if (dlg.ShowModal() != wxID_OK || dlg.m_nBrdNum == Invalid_v) + if (dlg.ShowModal() != wxID_OK || dlg.m_nBrdNum == wxNOT_FOUND) return; CBoard& pBoard = pBMgr.GetBoard(value_preserving_cast(dlg.m_nBrdNum)); From cb75723aee5ee436ed246b279e9ff9ee6d7653d0 Mon Sep 17 00:00:00 2001 From: Bill Su Date: Mon, 15 Sep 2025 11:06:18 -0400 Subject: [PATCH 09/80] VwEdtbrd: enable tile tool the tile palette works now, so tile tool can as well --- GM/VwEdtbrd.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/GM/VwEdtbrd.cpp b/GM/VwEdtbrd.cpp index 3d929e31..a00e2947 100644 --- a/GM/VwEdtbrd.cpp +++ b/GM/VwEdtbrd.cpp @@ -1389,11 +1389,7 @@ void CBrdEditView::OnUpdateToolPalette(wxUpdateUIEvent& pCmdUI) if (pCmdUI.GetId() == XRCID("ID_TOOL_TILE")) { -#if 0 tid = GetDocument().GetTilePalWnd().GetCurrentTileID(); -#else - tid = nullTid; -#endif bEnable = tid != nullTid; if (tid == nullTid && m_nCurToolID == XRCID("ID_TOOL_TILE")) { From e41ee3b62b8b353647a6920f497661174badce23 Mon Sep 17 00:00:00 2001 From: Bill Su Date: Sun, 7 Dec 2025 00:28:20 -0500 Subject: [PATCH 10/80] CBDesign: fix Delete command ID to wxID_CLEAR --- GM/CBDesign.fbp | 2 +- GM/CBDesign.xrc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/GM/CBDesign.fbp b/GM/CBDesign.fbp index ad6e88a2..77771262 100644 --- a/GM/CBDesign.fbp +++ b/GM/CBDesign.fbp @@ -20509,7 +20509,7 @@ wxID_ANY wxITEM_NORMAL &Delete - wxID_DELETE + wxID_CLEAR none Del diff --git a/GM/CBDesign.xrc b/GM/CBDesign.xrc index c71d01b9..a5e3fba2 100644 --- a/GM/CBDesign.xrc +++ b/GM/CBDesign.xrc @@ -3894,7 +3894,7 @@ Ctrl+M Move clipboard objects to new locations\nMove - + Del Erase the current selection\nDelete (Del) From b0083a77afc10c7d7ef1ad3eebfc2ef201a74555 Mon Sep 17 00:00:00 2001 From: Bill Su Date: Sun, 25 Jan 2026 01:24:20 -0500 Subject: [PATCH 11/80] GamDoc: re-order cleanup Closing palettes may trigger repaints of other palettes, so close palettes before deleting data members --- GP/GamDoc.cpp | 64 ++++++++++++++++++++++++++------------------------- 1 file changed, 33 insertions(+), 31 deletions(-) diff --git a/GP/GamDoc.cpp b/GP/GamDoc.cpp index 626b1874..137de940 100644 --- a/GP/GamDoc.cpp +++ b/GP/GamDoc.cpp @@ -355,6 +355,39 @@ BOOL CGamDoc::OnSaveDocument(LPCTSTR pszPathName) void CGamDoc::DeleteContents() { + /* close may trigger paint of other windows, + so close before delete */ + if (m_palTrayA.m_hWnd != NULL) + { + CDockTrayPalette* pFrame = (CDockTrayPalette*)m_palTrayA.GetDockingFrame(); + if (pFrame) + { + ASSERT_KINDOF(CDockTrayPalette, pFrame); + pFrame->SetChild(NULL); // Need to remove pointer from Tray's UI Frame. + } + m_palTrayA.DestroyWindow(); + } + if (m_palTrayB.m_hWnd != NULL) + { + CDockTrayPalette* pFrame = (CDockTrayPalette*)m_palTrayB.GetDockingFrame(); + if (pFrame) + { + ASSERT_KINDOF(CDockTrayPalette, pFrame); + pFrame->SetChild(NULL); // Need to remove pointer from Tray's UI Frame. + } + m_palTrayB.DestroyWindow(); + } + if (m_palMark.m_hWnd != NULL) + { + CDockMarkPalette* pFrame = (CDockMarkPalette*)m_palMark.GetDockingFrame(); + if (pFrame) + { + ASSERT_KINDOF(CDockMarkPalette, pFrame); + pFrame->SetChild(NULL); // Need to remove pointer from Marker's UI Frame. + } + m_palMark.DestroyWindow(); + } + // m_wReserved1 = 0; m_wReserved2 = 0; m_wReserved3 = 0; @@ -399,37 +432,6 @@ void CGamDoc::DeleteContents() m_nMoveInterlock = 0; m_bQuietPlayback = FALSE; - if (m_palTrayA.m_hWnd != NULL) - { - CDockTrayPalette* pFrame = (CDockTrayPalette*)m_palTrayA.GetDockingFrame(); - if (pFrame) - { - ASSERT_KINDOF(CDockTrayPalette, pFrame); - pFrame->SetChild(NULL); // Need to remove pointer from Tray's UI Frame. - } - m_palTrayA.DestroyWindow(); - } - if (m_palTrayB.m_hWnd != NULL) - { - CDockTrayPalette* pFrame = (CDockTrayPalette*)m_palTrayB.GetDockingFrame(); - if (pFrame) - { - ASSERT_KINDOF(CDockTrayPalette, pFrame); - pFrame->SetChild(NULL); // Need to remove pointer from Tray's UI Frame. - } - m_palTrayB.DestroyWindow(); - } - if (m_palMark.m_hWnd != NULL) - { - CDockMarkPalette* pFrame = (CDockMarkPalette*)m_palMark.GetDockingFrame(); - if (pFrame) - { - ASSERT_KINDOF(CDockMarkPalette, pFrame); - pFrame->SetChild(NULL); // Need to remove pointer from Marker's UI Frame. - } - m_palMark.DestroyWindow(); - } - DiscardWindowState(); if (m_pPlayerMgr != NULL) delete m_pPlayerMgr; From 1a960d940acee80e2ddca2e33b825ac2e43fd57a Mon Sep 17 00:00:00 2001 From: Bill Su Date: Fri, 12 Dec 2025 21:09:25 -0500 Subject: [PATCH 12/80] support 3-state checkbox in updateUI adapter --- GShr/LibMfc.cpp | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/GShr/LibMfc.cpp b/GShr/LibMfc.cpp index 598f72bd..5bd30871 100644 --- a/GShr/LibMfc.cpp +++ b/GShr/LibMfc.cpp @@ -1485,6 +1485,7 @@ BOOL CB::RelayOnCmdMsg(wxEvtHandler& dest, { CCmdUI& pCmdUI = CheckedDeref(static_cast(pExtra)); wxUpdateUIEvent event(CB::ToWxID(nID)); + event.Allow3rdState(); #if !defined(GPLAY) CColorCmdUI* colorCmdUI = dynamic_cast(&pCmdUI); if (colorCmdUI) @@ -1509,7 +1510,20 @@ BOOL CB::RelayOnCmdMsg(wxEvtHandler& dest, } if (event.GetSetChecked()) { - pCmdUI.SetCheck(event.GetChecked()); + switch (event.Get3StateValue()) + { + case wxCHK_UNCHECKED: + pCmdUI.SetCheck(0); + break; + case wxCHK_CHECKED: + pCmdUI.SetCheck(1); + break; + case wxCHK_UNDETERMINED: + pCmdUI.SetCheck(2); + break; + default: + wxASSERT(!"impossible value"); + } } if (event.GetSetText()) { From 5a172d94056d90668d7ee5148903f1ef11d64582 Mon Sep 17 00:00:00 2001 From: Bill Su Date: Thu, 4 Sep 2025 23:59:50 -0400 Subject: [PATCH 13/80] CyberBoard.h: CB::ToolTip enhancements CB::ToolTip: tool rect should be non-empty --- GShr/CyberBoard.h | 10 ++++++++++ GShr/LibMfc.cpp | 11 +++++++++++ 2 files changed, 21 insertions(+) diff --git a/GShr/CyberBoard.h b/GShr/CyberBoard.h index 0f4eb7a8..8cf1695f 100644 --- a/GShr/CyberBoard.h +++ b/GShr/CyberBoard.h @@ -2262,6 +2262,15 @@ namespace CB void SetReshow(long milliseconds); // set maximum width for the new tooltips: -1 disables wrapping void SetMaxWidth(int width); + /* WARNING: balloon mode is ignored: + wxTipWindow doesn't have a balloon shape, + but wxRichToolTip doesn't support setting + tip position, and demands title. If we + really want the balloon shape, we will have + to implement the paint ourselves. */ + void SetBalloonMode(bool b) { balloon = b; } + void TrackActivate(bool b); + void TrackPosition(wxPoint p); void Add(wxWindow& wnd, const wxRect& rect, wxString tip, Flags flags = NONE) @@ -2295,6 +2304,7 @@ namespace CB int autopopMs = -1; int maxWidth = -1; bool enabled = false; + bool balloon = false; struct ToolInfo { diff --git a/GShr/LibMfc.cpp b/GShr/LibMfc.cpp index 5bd30871..d2b8e552 100644 --- a/GShr/LibMfc.cpp +++ b/GShr/LibMfc.cpp @@ -1076,6 +1076,7 @@ void CB::ToolTip::Add(wxWindow& wnd, std::optional&& rect, wxASSERT(!(flags & TRACK) || !"TRACK not implemented"); // center shouldn't move, track should move wxASSERT((flags & (CENTER | TRACK)) != (CENTER | TRACK)); + wxASSERT(!rect || !rect->IsEmpty()); auto it = std::find_if(toolInfos.begin(), toolInfos.end(), [&wnd](const ToolInfo& ti) @@ -1090,6 +1091,9 @@ void CB::ToolTip::Add(wxWindow& wnd, std::optional&& rect, if (it == toolInfos.end()) { wnd.Bind(wxEVT_MOTION, &ToolTip::OnMouseMove, this); + /* leaving the window may need to be handled + as a move to a location outside the tool */ + wnd.Bind(wxEVT_LEAVE_WINDOW, &ToolTip::OnMouseMove, this); } toolInfos.emplace_back(wnd, std::move(rect), std::move(tip), flags); Enable(enabled); @@ -1120,6 +1124,7 @@ void CB::ToolTip::Delete(wxWindow& wnd, std::optional rect) if (it == toolInfos.end()) { wnd.Unbind(wxEVT_MOTION, &ToolTip::OnMouseMove, this); + wnd.Unbind(wxEVT_LEAVE_WINDOW, &ToolTip::OnMouseMove, this); } } @@ -1186,6 +1191,12 @@ void CB::ToolTip::OnMouseMove(wxMouseEvent& event) return &ti.wnd.get() == &wnd && (!ti.rect || ti.rect->Contains(pt)); }); + if (it != toolInfos.end() && + !it->rect && + event.GetEventType() == wxEVT_LEAVE_WINDOW) + { + it = toolInfos.end(); + } if (it != toolInfos.end()) { From 2bc27acea7a9533bbd1d901cfcd25be8651e05e0 Mon Sep 17 00:00:00 2001 From: Bill Su Date: Sat, 11 Oct 2025 18:50:26 -0400 Subject: [PATCH 14/80] CyberBoard.h: wxDC::SetLogicalOrigin helper --- GShr/CyberBoard.h | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/GShr/CyberBoard.h b/GShr/CyberBoard.h index 8cf1695f..94aa775d 100644 --- a/GShr/CyberBoard.h +++ b/GShr/CyberBoard.h @@ -2513,6 +2513,51 @@ namespace CB wxDC* dc = nullptr; wxRasterOperationMode oldRop; }; + + class DCLogicalOriginChanger + { + public: + DCLogicalOriginChanger() = default; + DCLogicalOriginChanger(wxDC& d, wxPoint org) : + dc(&d) + { + oldOrigin = dc->GetLogicalOrigin(); + dc->SetLogicalOrigin(org.x, org.y); + } + DCLogicalOriginChanger(const DCLogicalOriginChanger&) = delete; + DCLogicalOriginChanger(DCLogicalOriginChanger&& other) noexcept + { + *this = std::move(other); + } + DCLogicalOriginChanger& operator=(const DCLogicalOriginChanger&) = delete; + DCLogicalOriginChanger& operator=(DCLogicalOriginChanger&& other) noexcept + { + if (this != &other) + { + Reset(); + dc = other.dc; + other.dc = nullptr; + oldOrigin = other.oldOrigin; + } + return *this; + } + ~DCLogicalOriginChanger() + { + Reset(); + } + + private: + void Reset() + { + if (dc) + { + dc->SetLogicalOrigin(oldOrigin.x, oldOrigin.y); + } + } + + wxDC* dc = nullptr; + wxPoint oldOrigin; + }; } // provide wxMouseState equivalent of wxKeyboardState::GetModifiers() From 05440230685ff719c5997aab1777cbf7e3b9bb02 Mon Sep 17 00:00:00 2001 From: Bill Su Date: Sat, 16 Aug 2025 19:02:04 -0400 Subject: [PATCH 15/80] WinState: provide wx version of WM_WINSTATE --- GShr/WinState.cpp | 2 ++ GShr/WinState.h | 26 +++++++++++++++++++++++++- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/GShr/WinState.cpp b/GShr/WinState.cpp index a1562e27..55eba22a 100644 --- a/GShr/WinState.cpp +++ b/GShr/WinState.cpp @@ -31,6 +31,8 @@ #include "GamDoc.h" #endif +wxDEFINE_EVENT(WM_WINSTATE_WX, WinStateEvent); + /////////////////////////////////////////////////////////////////////////// // Returns FALSE if no frame restoration data is supplied by frames. diff --git a/GShr/WinState.h b/GShr/WinState.h index 09e948c1..86558d53 100644 --- a/GShr/WinState.h +++ b/GShr/WinState.h @@ -1,6 +1,6 @@ // WinState.h - classes used to manage window state. // -// Copyright (c) 1994-2020 By Dale L. Larson, All Rights Reserved. +// Copyright (c) 1994-2025 By Dale L. Larson & William Su, All Rights Reserved. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the @@ -35,6 +35,30 @@ // the frame's *contents* to it's current visual state. #define WM_WINSTATE (WM_USER + 300) // WPARAM = CArchive*, LPARAM = 0 if save, 1 if restore +class WinStateEvent : public wxEvent +{ +public: + WinStateEvent(CArchive& ar, bool restore); + + CArchive& GetArchive() const { return ar; } + + wxEvent* Clone() const override { return new WinStateEvent(*this); } + +private: + CArchive& ar; +}; +wxDECLARE_EVENT(WM_WINSTATE_WX, WinStateEvent); +inline WinStateEvent::WinStateEvent(CArchive& a, bool restore) : + wxEvent(wxID_ANY, WM_WINSTATE_WX), + ar(a) +{ + WXUNUSED_UNLESS_DEBUG(restore); + wxASSERT(bool(ar.IsLoading()) == restore); +} +typedef void (wxEvtHandler::* WinStateEventFunction)(WinStateEvent&); +#define WinStateEventHandler(func) wxEVENT_HANDLER_CAST(WinStateEventFunction, func) +#define EVT_WINSTATE(func) \ + wx__DECLARE_EVT0(WM_WINSTATE_WX, WinStateEventHandler(func)) /////////////////////////////////////////////////////////////////////// // Helper class for working with the Windows WINDOWPLACEMENT structure From ae7f48ff377cb5f4c009be5e63953beb4b5ef89e Mon Sep 17 00:00:00 2001 From: Bill Su Date: Tue, 19 Aug 2025 00:25:11 -0400 Subject: [PATCH 16/80] VwTbrd: const-, NULL-, and override-correctness --- GP/VwTbrd.cpp | 67 +++++++++++++++++++++++++------------------------ GP/VwTbrd.h | 36 +++++++++++++------------- GP/WinPoptb.cpp | 2 +- GP/WinPoptb.h | 2 +- 4 files changed, 54 insertions(+), 53 deletions(-) diff --git a/GP/VwTbrd.cpp b/GP/VwTbrd.cpp index 4cab291b..f5d24121 100644 --- a/GP/VwTbrd.cpp +++ b/GP/VwTbrd.cpp @@ -1,6 +1,6 @@ // VwTbrd.cpp : Small scale playing board view. // -// Copyright (c) 1994-2023 By Dale L. Larson & William Su, All Rights Reserved. +// Copyright (c) 1994-2025 By Dale L. Larson & William Su, All Rights Reserved. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the @@ -80,7 +80,7 @@ void CTinyBoardView::OnInitialUpdate() { CScrollView::OnInitialUpdate(); - m_pPBoard = (CPlayBoard*)GetDocument()->GetNewViewParameter(); + m_pPBoard = static_cast(GetDocument().GetNewViewParameter()); CBoard* pBoard = m_pPBoard->GetBoard(); SetScrollSizes(MM_TEXT, pBoard->GetSize(smallScale)); } @@ -92,7 +92,7 @@ void CTinyBoardView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint) { CRect rct; rct = ph->GetArgs().m_pDrawObj->GetEnclosingRect(); // In board coords. - InvalidateWorkspaceRect(&rct); + InvalidateWorkspaceRect(rct); } else if (lHint == HINT_UPDATEOBJLIST && ph->GetArgs().m_pPBoard == m_pPBoard) { @@ -101,7 +101,7 @@ void CTinyBoardView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint) { CDrawObj& pDObj = *pPtrList[i]; CRect rct = pDObj.GetEnclosingRect(); // In board coords. - InvalidateWorkspaceRect(&rct); + InvalidateWorkspaceRect(rct); } } else if (lHint == HINT_UPDATEBOARD && ph->GetArgs().m_pPBoard == m_pPBoard) @@ -144,7 +144,7 @@ LRESULT CTinyBoardView::OnMessageWindowState(WPARAM wParam, LPARAM lParam) void CTinyBoardView::OnDraw(CDC* pDC) { if (!m_pBMap) - RegenCachedMap(pDC); + RegenCachedMap(CheckedDeref(pDC)); ASSERT(m_pBMap); CDC dcMem; @@ -177,11 +177,11 @@ void CTinyBoardView::OnDraw(CDC* pDC) // Draw pieces etc. (Need to rescale the DC and the update rect) CRect rct(&oRct); - SetupDrawListDC(&dcMem, rct); + SetupDrawListDC(dcMem, rct); m_pPBoard->Draw(dcMem, &rct, smallScale); - RestoreDrawListDC(&dcMem); + RestoreDrawListDC(dcMem); if (m_pPBoard->IsBoardRotated180()) { @@ -201,15 +201,16 @@ void CTinyBoardView::OnDraw(CDC* pDC) dcMem.SelectObject(pPrvBMap); } -void CTinyBoardView::DrawFullMap(CDC* pDC, CBitmap& bmap) +OwnerPtr CTinyBoardView::DrawFullMap(CDC& pDC) { + OwnerPtr bmap = MakeOwner(); CDC dcMem; CSize size = m_pPBoard->GetBoard()->GetSize(smallScale); - bmap.Attach(CreateRGBDIBSection(size.cx, size.cy)->Detach()); - dcMem.CreateCompatibleDC(pDC); - CBitmap* pPrvBMap = dcMem.SelectObject(&bmap); + bmap->Attach(CreateRGBDIBSection(size.cx, size.cy)->Detach()); + dcMem.CreateCompatibleDC(&pDC); + CBitmap* pPrvBMap = dcMem.SelectObject(&*bmap); // Draw updated part of board image BitmapBlt(dcMem, CPoint(0, 0), *m_pBMap); @@ -217,24 +218,26 @@ void CTinyBoardView::DrawFullMap(CDC* pDC, CBitmap& bmap) // Draw pieces etc. (Need to rescale the DC and the update rect) CRect rct(CPoint(0,0), size); - SetupDrawListDC(&dcMem, rct); + SetupDrawListDC(dcMem, rct); m_pPBoard->Draw(dcMem, &rct, smallScale); - RestoreDrawListDC(&dcMem); + RestoreDrawListDC(dcMem); dcMem.SelectObject(pPrvBMap); + + return bmap; } -void CTinyBoardView::RegenCachedMap(CDC* pDC) +void CTinyBoardView::RegenCachedMap(CDC& pDC) { - BeginWaitCursor(); + CWaitCursor waitCursor; CBoard* pBoard = m_pPBoard->GetBoard(); CSize size = pBoard->GetSize(smallScale); // Get pixel size of board m_pBMap = CreateRGBDIBSection(size.cx, size.cy); CDC dcMem; - dcMem.CreateCompatibleDC(pDC); + dcMem.CreateCompatibleDC(&pDC); CBitmap* pPrvBMap = dcMem.SelectObject(&*m_pBMap); CRect rct(CPoint(0, 0), size); @@ -242,33 +245,32 @@ void CTinyBoardView::RegenCachedMap(CDC* pDC) pBoard->Draw(dcMem, rct, smallScale, m_pPBoard->m_bSmallCellBorders); dcMem.SelectObject(pPrvBMap); - EndWaitCursor(); } ///////////////////////////////////////////////////////////////////////////// -void CTinyBoardView::SetupDrawListDC(CDC* pDC, CRect& rct) +void CTinyBoardView::SetupDrawListDC(CDC& pDC, CRect& rct) const { CSize wsize, vsize; m_pPBoard->GetBoard()->GetBoardArray(). GetBoardScaling(smallScale, wsize, vsize); - pDC->SaveDC(); - pDC->SetMapMode(MM_ANISOTROPIC); - pDC->SetWindowExt(wsize); - pDC->SetViewportExt(vsize); + pDC.SaveDC(); + pDC.SetMapMode(MM_ANISOTROPIC); + pDC.SetWindowExt(wsize); + pDC.SetViewportExt(vsize); ScaleRect(rct, wsize, vsize); } -void CTinyBoardView::RestoreDrawListDC(CDC *pDC) +void CTinyBoardView::RestoreDrawListDC(CDC &pDC) const { - pDC->RestoreDC(-1); + pDC.RestoreDC(-1); } ///////////////////////////////////////////////////////////////////////////// -void CTinyBoardView::WorkspaceToClient(CRect& rect) +void CTinyBoardView::WorkspaceToClient(CRect& rect) const { CPoint dpnt = GetDeviceScrollPosition(); CSize wsize, vsize; @@ -284,14 +286,14 @@ void CTinyBoardView::WorkspaceToClient(CRect& rect) rect -= dpnt; } -void CTinyBoardView::InvalidateWorkspaceRect(const CRect* pRect, BOOL bErase) +void CTinyBoardView::InvalidateWorkspaceRect(const CRect& pRect, BOOL bErase) { CRect rct(pRect); WorkspaceToClient(rct); InvalidateRect(&rct, bErase); } -void CTinyBoardView::ClientToWorkspace(CPoint& pnt) +void CTinyBoardView::ClientToWorkspace(CPoint& pnt) const { pnt += GetDeviceScrollPosition(); CSize wsize, vsize; @@ -305,11 +307,9 @@ void CTinyBoardView::ClientToWorkspace(CPoint& pnt) ///////////////////////////////////////////////////////////////////////////// #ifdef _DEBUG -CGamDoc* CTinyBoardView::GetDocument() // non-debug version is inline +CGamDoc& CTinyBoardView::GetDocument() // non-debug version is inline { - CGamDoc* retval = CB::ToCGamDoc(m_pDocument); - wxASSERT(retval); - return retval; + return CheckedDeref(CB::ToCGamDoc(m_pDocument)); } #endif //_DEBUG @@ -328,11 +328,12 @@ void CTinyBoardView::OnRButtonDown(UINT nFlags, CPoint point) if (!m_pBMap) return; - CTinyBoardPopup* pTBrd = new CTinyBoardPopup; + // owned by MFC + RefPtr pTBrd(new CTinyBoardPopup); { CWindowDC dcRef(NULL); - DrawFullMap(&dcRef, pTBrd->m_bmap); + pTBrd->m_bmap = DrawFullMap(dcRef); } pTBrd->m_pWnd = GetParentFrame(); diff --git a/GP/VwTbrd.h b/GP/VwTbrd.h index 22ac9a8e..c045930a 100644 --- a/GP/VwTbrd.h +++ b/GP/VwTbrd.h @@ -1,6 +1,6 @@ // VwTbrd.h : header file // -// Copyright (c) 1994-2020 By Dale L. Larson, All Rights Reserved. +// Copyright (c) 1994-2025 By Dale L. Larson & William Su, All Rights Reserved. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the @@ -32,38 +32,38 @@ class CTinyBoardView : public CScrollView CTinyBoardView(); // protected constructor used by dynamic creation // Attributes -public: - CGamDoc* GetDocument(); +private: + CGamDoc& GetDocument(); // Operations public: // Implementation protected: - CPlayBoard* m_pPBoard; // The playing board we are viewing + CB::propagate_const m_pPBoard; // The playing board we are viewing OwnerOrNullPtr m_pBMap; // Cached predrawn board bitmap TileScale m_nZoom; - void RegenCachedMap(CDC* pDC); - void DrawFullMap(CDC* pDC, CBitmap& bmap); + void RegenCachedMap(CDC& pDC); + OwnerPtr DrawFullMap(CDC& pDC); // Implementation protected: - void SetupDrawListDC(CDC* pDC, CRect& rct); - void RestoreDrawListDC(CDC *pDC); + void SetupDrawListDC(CDC& pDC, CRect& rct) const; + void RestoreDrawListDC(CDC &pDC) const; // -------- // - void WorkspaceToClient(CRect& rect); - void ClientToWorkspace(CPoint& pnt); - void InvalidateWorkspaceRect(const CRect* pRect, BOOL bErase = FALSE); + void WorkspaceToClient(CRect& rect) const; + void ClientToWorkspace(CPoint& pnt) const; + void InvalidateWorkspaceRect(const CRect& pRect, BOOL bErase = FALSE); // Implementation protected: - virtual ~CTinyBoardView() = default; - virtual BOOL PreCreateWindow(CREATESTRUCT& cs); - virtual void OnInitialUpdate(); // first time after construct - virtual void OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint); - virtual void OnDraw(CDC* pDC); // overridden to draw this view + ~CTinyBoardView() override = default; + BOOL PreCreateWindow(CREATESTRUCT& cs) override; + void OnInitialUpdate() override; // first time after construct + void OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint) override; + void OnDraw(CDC* pDC) override; // overridden to draw this view // Generated message map functions //{{AFX_MSG(CTinyBoardView) @@ -76,8 +76,8 @@ class CTinyBoardView : public CScrollView }; #ifndef _DEBUG // debug version in vwmbrd.cpp -inline CGamDoc* CTinyBoardView::GetDocument() - { return CB::ToCGamDoc(m_pDocument); } +inline CGamDoc& CTinyBoardView::GetDocument() + { return CheckedDeref(CB::ToCGamDoc(m_pDocument)); } #endif diff --git a/GP/WinPoptb.cpp b/GP/WinPoptb.cpp index 8036c0d3..6590638f 100644 --- a/GP/WinPoptb.cpp +++ b/GP/WinPoptb.cpp @@ -124,7 +124,7 @@ void CTinyBoardPopup::OnPaint() CRect oRct; dcMem.CreateCompatibleDC(&dc); - CBitmap* pPrvBMap = dcMem.SelectObject(&m_bmap); + CBitmap* pPrvBMap = dcMem.SelectObject(&*m_bmap); CRect rctClient; GetClientRect(rctClient); diff --git a/GP/WinPoptb.h b/GP/WinPoptb.h index ae6d4fe2..278f94a3 100644 --- a/GP/WinPoptb.h +++ b/GP/WinPoptb.h @@ -41,7 +41,7 @@ class CTinyBoardPopup : public CWnd // Attributes public: CWnd* m_pWnd; - CBitmap m_bmap; + OwnerPtr m_bmap = MakeOwner(); CSize m_wsize; CSize m_vsize; BOOL m_bRotate180; // Board is rotated by 180 degrees From 3850a0695a05c43e5b9918c645a7742749a975d4 Mon Sep 17 00:00:00 2001 From: Bill Su Date: Sun, 17 Aug 2025 21:57:51 -0400 Subject: [PATCH 17/80] VwTbrd: create an extra window to simplify wx conversion MFC manages doc/frame/view objects, so split CTinyBoardView into a parent window that MFC can manage and a child window that has the main implementation. That way we can convert the main implementation to wx while still letting MFC's doc/frame/view code work. --- GP/FrmPbrd.cpp | 2 +- GP/VwTbrd.cpp | 60 +++++++++++++++++++++++++++++++++++++++++++++++++- GP/VwTbrd.h | 24 +++++++++++++++++--- 3 files changed, 81 insertions(+), 5 deletions(-) diff --git a/GP/FrmPbrd.cpp b/GP/FrmPbrd.cpp index eda068ca..a344091d 100644 --- a/GP/FrmPbrd.cpp +++ b/GP/FrmPbrd.cpp @@ -220,7 +220,7 @@ BOOL CPlayBoardFrame::OnCreateClient(LPCREATESTRUCT lpcs, return FALSE; } if (!m_wndSplitter2.CreateView(1, 0, - RUNTIME_CLASS(CTinyBoardView), + RUNTIME_CLASS(CTinyBoardViewContainer), CSize(rct.Width() - xSize, rct.Height() - ySize), pContext)) { TRACE("Failed to create small scale map pane\n"); diff --git a/GP/VwTbrd.cpp b/GP/VwTbrd.cpp index f5d24121..ec584cd8 100644 --- a/GP/VwTbrd.cpp +++ b/GP/VwTbrd.cpp @@ -37,7 +37,7 @@ static char THIS_FILE[] = __FILE__; #endif -IMPLEMENT_DYNCREATE(CTinyBoardView, CScrollView) +IMPLEMENT_DYNCREATE(CTinyBoardViewContainer, CView) #ifdef _DEBUG #define new DEBUG_NEW @@ -54,6 +54,13 @@ BEGIN_MESSAGE_MAP(CTinyBoardView, CScrollView) ON_MESSAGE(WM_WINSTATE, OnMessageWindowState) END_MESSAGE_MAP() +BEGIN_MESSAGE_MAP(CTinyBoardViewContainer, CView) + ON_WM_CREATE() + ON_WM_SIZE() + ON_WM_MOUSEACTIVATE() + ON_MESSAGE(WM_WINSTATE, OnMessageWindowState) +END_MESSAGE_MAP() + ///////////////////////////////////////////////////////////////////////////// // CTinyBoardView @@ -353,3 +360,54 @@ int CTinyBoardView::OnMouseActivate(CWnd* pDesktopWnd, UINT nHitTest, UINT messa // "active" view. return CWnd::OnMouseActivate(pDesktopWnd, nHitTest, message); } + +void CTinyBoardViewContainer::OnDraw(CDC* pDC) +{ + // do nothing because child covers entire client rect +} + +CTinyBoardViewContainer::CTinyBoardViewContainer() : + child(new CTinyBoardView) +{ +} + +int CTinyBoardViewContainer::OnCreate(LPCREATESTRUCT lpCreateStruct) +{ + if (CView::OnCreate(lpCreateStruct) == -1) + { + return -1; + } + + DWORD dwStyle = AFX_WS_DEFAULT_VIEW & ~WS_BORDER; + // Create with the right size (wrong position) + CRect rect; + GetClientRect(rect); + CCreateContext context; + context.m_pCurrentDoc = GetDocument(); + if (!child->Create(NULL, NULL, dwStyle, + rect, this, 0, &context)) + { + return -1; + } + + return 0; +} + +void CTinyBoardViewContainer::OnSize(UINT nType, int cx, int cy) +{ + child->MoveWindow(0, 0, cx, cy); + return CView::OnSize(nType, cx, cy); +} + +int CTinyBoardViewContainer::OnMouseActivate(CWnd* pDesktopWnd, UINT nHitTest, UINT message) +{ + // We don't want the frame to ever consider this view to be the + // "active" view. + return CWnd::OnMouseActivate(pDesktopWnd, nHitTest, message); +} + +LRESULT CTinyBoardViewContainer::OnMessageWindowState(WPARAM wParam, LPARAM lParam) +{ + child->SendMessage(WM_WINSTATE, wParam, lParam); + return (LRESULT)1; +} diff --git a/GP/VwTbrd.h b/GP/VwTbrd.h index c045930a..092ad083 100644 --- a/GP/VwTbrd.h +++ b/GP/VwTbrd.h @@ -27,9 +27,8 @@ class CTinyBoardView : public CScrollView { - DECLARE_DYNCREATE(CTinyBoardView) -protected: - CTinyBoardView(); // protected constructor used by dynamic creation +public: + CTinyBoardView(); // Attributes private: @@ -80,4 +79,23 @@ inline CGamDoc& CTinyBoardView::GetDocument() { return CheckedDeref(CB::ToCGamDoc(m_pDocument)); } #endif +class CTinyBoardViewContainer : public CView +{ +public: + void OnDraw(CDC* pDC) override; + +private: + CTinyBoardViewContainer(); // used by dynamic creation + DECLARE_DYNCREATE(CTinyBoardViewContainer) + + afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); + afx_msg void OnSize(UINT nType, int cx, int cy); + afx_msg int OnMouseActivate(CWnd* pDesktopWnd, UINT nHitTest, UINT message); + afx_msg LRESULT OnMessageWindowState(WPARAM wParam, LPARAM lParam); + DECLARE_MESSAGE_MAP() + + // owned by MFC + RefPtr child; +}; + From b3f70ba5891b39e07fb527b914c8b5fde112487f Mon Sep 17 00:00:00 2001 From: Bill Su Date: Thu, 21 Aug 2025 22:25:02 -0400 Subject: [PATCH 18/80] PBoard: implement some wx drawing support --- GP/PBoard.cpp | 14 ++++++++++++++ GP/PBoard.h | 1 + GShr/DrawObj.cpp | 1 - 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/GP/PBoard.cpp b/GP/PBoard.cpp index 6ef2f59f..68195e35 100644 --- a/GP/PBoard.cpp +++ b/GP/PBoard.cpp @@ -141,6 +141,20 @@ void CPlayBoard::Draw(CDC& pDC, const CRect& pDrawRct, TileScale eScale) m_pIndList->Draw(pDC, pDrawRct, eScale); } +void CPlayBoard::Draw(wxDC& pDC, const wxRect& pDrawRct, TileScale eScale) +{ + wxASSERT(m_pBoard); + wxASSERT(m_pPceList); + + if (m_bIVisible && !m_bIndOnTop) + m_pIndList->Draw(pDC, pDrawRct, eScale); + + m_pPceList->Draw(pDC, pDrawRct, eScale, TRUE, FALSE, !m_bPVisible, m_bLockedDrawnBeneath); + + if (m_bIVisible && m_bIndOnTop) + m_pIndList->Draw(pDC, pDrawRct, eScale); +} + ////////////////////////////////////////////////////////////////////// // Piece is centered on point. diff --git a/GP/PBoard.h b/GP/PBoard.h index 3cb7ad2c..a34d8f32 100644 --- a/GP/PBoard.h +++ b/GP/PBoard.h @@ -107,6 +107,7 @@ class CPlayBoard // Operations public: void Draw(CDC& pDC, const CRect& pDrawRct, TileScale eScale); + void Draw(wxDC& pDC, const wxRect& pDrawRct, TileScale eScale); // ------- // CPieceObj& AddPiece(CPoint pnt, PieceID pid); const CPieceObj* FindPieceID(PieceID pid) const; diff --git a/GShr/DrawObj.cpp b/GShr/DrawObj.cpp index f6856df2..2ca8bab4 100644 --- a/GShr/DrawObj.cpp +++ b/GShr/DrawObj.cpp @@ -1645,7 +1645,6 @@ static void DrawObjTile(CDC& pDC, CPoint pnt, CTileManager* pTMgr, TileID tid, static void DrawObjTile(wxDC& pDC, wxPoint pnt, CTileManager& pTMgr, TileID tid, TileScale eScale) { - wxASSERT(!"needs testing"); CTile tile = pTMgr.GetTile(tid, eScale); CB::DCUserScaleChanger setScale; From f1113108843c5a4f1c62bf17902e0970e813feec Mon Sep 17 00:00:00 2001 From: Bill Su Date: Wed, 20 Aug 2025 19:36:52 -0400 Subject: [PATCH 19/80] VwTbrd: replace MFC with wx --- GP/VwPrjgsn.h | 5 +- GP/VwTbrd.cpp | 305 ++++++++++++++++++++++++------------------------ GP/VwTbrd.h | 94 ++++++++++----- GP/WinPoptb.cpp | 6 +- GP/WinPoptb.h | 4 +- 5 files changed, 224 insertions(+), 190 deletions(-) diff --git a/GP/VwPrjgsn.h b/GP/VwPrjgsn.h index 943d6537..dcb76f8e 100644 --- a/GP/VwPrjgsn.h +++ b/GP/VwPrjgsn.h @@ -68,7 +68,8 @@ class CProjListBoxGsn : public CProjListBoxWx, private CB::Impl::CGsnProjViewBase { -public: + friend class CGsnProjViewContainer; +private: CGsnProjView(CGsnProjViewContainer& p); // Attributes @@ -181,8 +182,6 @@ class CGsnProjView : public CB::ProcessEventOverride, private CB::Impl: RefPtr parent; RefPtr document; - - friend class CGsnProjViewContainer; }; class CGsnProjViewContainer : public CB::OnCmdMsgOverride, diff --git a/GP/VwTbrd.cpp b/GP/VwTbrd.cpp index ec584cd8..49f0cafe 100644 --- a/GP/VwTbrd.cpp +++ b/GP/VwTbrd.cpp @@ -45,18 +45,20 @@ IMPLEMENT_DYNCREATE(CTinyBoardViewContainer, CView) ///////////////////////////////////////////////////////////////////////////// -BEGIN_MESSAGE_MAP(CTinyBoardView, CScrollView) - //{{AFX_MSG_MAP(CTinyBoardView) - ON_WM_LBUTTONDOWN() - ON_WM_RBUTTONDOWN() +wxBEGIN_EVENT_TABLE(CTinyBoardView, CB::ProcessEventOverride) + EVT_LEFT_DOWN(OnLButtonDown) + EVT_RIGHT_DOWN(OnRButtonDown) +#if 0 ON_WM_MOUSEACTIVATE() - //}}AFX_MSG_MAP - ON_MESSAGE(WM_WINSTATE, OnMessageWindowState) -END_MESSAGE_MAP() +#endif + EVT_WINSTATE(OnMessageWindowState) +wxEND_EVENT_TABLE() -BEGIN_MESSAGE_MAP(CTinyBoardViewContainer, CView) +BEGIN_MESSAGE_MAP(CTinyBoardViewContainer, CTinyBoardViewContainer::BASE) ON_WM_CREATE() +#if 0 ON_WM_SIZE() +#endif ON_WM_MOUSEACTIVATE() ON_MESSAGE(WM_WINSTATE, OnMessageWindowState) END_MESSAGE_MAP() @@ -64,11 +66,20 @@ END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CTinyBoardView -CTinyBoardView::CTinyBoardView() +CTinyBoardView::CTinyBoardView(CTinyBoardViewContainer& p) : + parent(&p), + document(dynamic_cast(parent->GetDocument())), + m_pPBoard(static_cast(document->GetNewViewParameter())) { - m_pPBoard = NULL; + // use sizers for scrolling + wxSizer* sizer = new wxBoxSizer(wxVERTICAL); + SetSizer(sizer); + sizer->Add(0, 0); + BASE::Create(*parent, 0); + OnInitialUpdate(); } +#if 0 BOOL CTinyBoardView::PreCreateWindow(CREATESTRUCT& cs) { if (!CScrollView::PreCreateWindow(cs)) @@ -80,16 +91,13 @@ BOOL CTinyBoardView::PreCreateWindow(CREATESTRUCT& cs) return TRUE; } +#endif ///////////////////////////////////////////////////////////////////////////// void CTinyBoardView::OnInitialUpdate() { - CScrollView::OnInitialUpdate(); - - m_pPBoard = static_cast(GetDocument().GetNewViewParameter()); - CBoard* pBoard = m_pPBoard->GetBoard(); - SetScrollSizes(MM_TEXT, pBoard->GetSize(smallScale)); + RecalcScrollLimits(); } void CTinyBoardView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint) @@ -97,307 +105,301 @@ void CTinyBoardView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint) CGamDocHint* ph = (CGamDocHint*)pHint; if (lHint == HINT_UPDATEOBJECT && ph->GetArgs().m_pPBoard == m_pPBoard) { - CRect rct; - rct = ph->GetArgs().m_pDrawObj->GetEnclosingRect(); // In board coords. + wxRect rct; + rct = CB::Convert(ph->GetArgs().m_pDrawObj->GetEnclosingRect()); // In board coords. InvalidateWorkspaceRect(rct); } else if (lHint == HINT_UPDATEOBJLIST && ph->GetArgs().m_pPBoard == m_pPBoard) { + wxASSERT(!"untested code"); const std::vector>& pPtrList = *ph->GetArgs().m_pPtrList; for (size_t i = size_t(0); i < pPtrList.size(); ++i) { CDrawObj& pDObj = *pPtrList[i]; - CRect rct = pDObj.GetEnclosingRect(); // In board coords. + wxRect rct = CB::Convert(pDObj.GetEnclosingRect()); // In board coords. InvalidateWorkspaceRect(rct); } } else if (lHint == HINT_UPDATEBOARD && ph->GetArgs().m_pPBoard == m_pPBoard) { - m_pBMap = nullptr; - Invalidate(); + m_pBMap = wxBitmap(); + Refresh(); } else if (lHint == HINT_ALWAYSUPDATE || lHint == HINT_GAMESTATEUSED) - CScrollView::OnUpdate(pSender, lHint, pHint); + { + parent->CTinyBoardViewContainer::BASE::OnUpdate(pSender, lHint, pHint); + } } /////////////////////////////////////////////////////////////////////// // This message is sent when a document is being saved. -// WPARAM = CArchive*, LPARAM = 0 if save, 1 if restore -LRESULT CTinyBoardView::OnMessageWindowState(WPARAM wParam, LPARAM lParam) +void CTinyBoardView::OnMessageWindowState(WinStateEvent& event) { - ASSERT(wParam != NULL); - CArchive& ar = *((CArchive*)wParam); + CArchive& ar = event.GetArchive(); if (ar.IsStoring()) { - CPoint pnt = GetScrollPosition(); - ar << (DWORD)pnt.x; - ar << (DWORD)pnt.y; + wxPoint pnt = GetViewStart(); + ar << value_preserving_cast(pnt.x); + ar << value_preserving_cast(pnt.y); } else { - CPoint pnt; - DWORD dwTmp; - ar >> dwTmp; pnt.x = (LONG)dwTmp; - ar >> dwTmp; pnt.y = (LONG)dwTmp; - ScrollToPosition(pnt); + wxPoint pnt; + uint32_t dwTmp; + ar >> dwTmp; pnt.x = value_preserving_cast(dwTmp); + ar >> dwTmp; pnt.y = value_preserving_cast(dwTmp); + Scroll(pnt); } - return (LRESULT)1; } ///////////////////////////////////////////////////////////////////////////// // CTinyBoardView drawing -void CTinyBoardView::OnDraw(CDC* pDC) +void CTinyBoardView::OnDraw(wxDC& pDC) { - if (!m_pBMap) - RegenCachedMap(CheckedDeref(pDC)); - ASSERT(m_pBMap); + if (!m_pBMap.IsOk()) + RegenCachedMap(pDC); + wxASSERT(m_pBMap.IsOk()); - CDC dcMem; - CRect oRct; - CRect oRctSave; - CBitmap* pPrvBMap; + wxMemoryDC dcMem; + wxRect oRct; + wxRect oRctSave; - pDC->GetClipBox(&oRct); - if (oRct.IsRectEmpty()) + pDC.GetClippingBox(oRct); + if (oRct.IsEmpty()) return; // Nothing to do - OwnerPtr bmMem = CreateRGBDIBSection(oRct.Width(), oRct.Height()); - dcMem.CreateCompatibleDC(pDC); - pPrvBMap = dcMem.SelectObject(&*bmMem); - dcMem.PatBlt(0, 0, oRct.Width(), oRct.Height(), WHITENESS); + wxBitmap bmMem(oRct.GetWidth(), oRct.GetHeight(), pDC); + dcMem.SelectObject(bmMem); + { + wxDCBrushChanger setBrush(dcMem, *wxWHITE_BRUSH); + wxDCPenChanger setPen(dcMem, *wxTRANSPARENT_PEN); + dcMem.DrawRectangle(0, 0, oRct.GetWidth(), oRct.GetHeight()); + } if (m_pPBoard->IsBoardRotated180()) { oRctSave = oRct; - CSize sizeBrd = m_pPBoard->GetBoard()->GetSize(smallScale); - oRct = CRect(CPoint(sizeBrd.cx - oRct.left - oRct.Width(), - sizeBrd.cy - oRct.top - oRct.Height()), oRct.Size()); + wxSize sizeBrd = CB::Convert(m_pPBoard->GetBoard()->GetSize(smallScale)); + oRct = wxRect(wxPoint(sizeBrd.x - oRct.GetLeft() - oRct.GetWidth(), + sizeBrd.y - oRct.GetTop() - oRct.GetHeight()), oRct.GetSize()); } - dcMem.SetViewportOrg(-oRct.left, -oRct.top); + dcMem.SetDeviceOrigin(-oRct.GetLeft(), -oRct.GetTop()); // Draw updated part of board image - BitmapBlt(dcMem, CPoint(0, 0), *m_pBMap); + dcMem.DrawBitmap(m_pBMap, 0, 0); // Draw pieces etc. (Need to rescale the DC and the update rect) - CRect rct(&oRct); - SetupDrawListDC(dcMem, rct); + wxRect rct(oRct); + { + DCSetupDrawListDC setupDrawListDC(*this, dcMem, rct); - m_pPBoard->Draw(dcMem, &rct, smallScale); + m_pPBoard->Draw(dcMem, rct, smallScale); - RestoreDrawListDC(dcMem); + } if (m_pPBoard->IsBoardRotated180()) { // Xfer to output - dcMem.SetViewportOrg(0, 0); - pDC->StretchBlt(oRctSave.left, oRctSave.top, oRctSave.Width(), oRctSave.Height(), - &dcMem, oRctSave.Width() - 1, oRctSave.Height() - 1, - -oRctSave.Width(), -oRctSave.Height(), SRCCOPY); + dcMem.SetDeviceOrigin(0, 0); + pDC.StretchBlit(oRctSave.GetLeft(), oRctSave.GetTop(), oRctSave.GetWidth(), oRctSave.GetHeight(), + &dcMem, oRctSave.GetWidth() - 1, oRctSave.GetHeight() - 1, + -oRctSave.GetWidth(), -oRctSave.GetHeight()); } else { // Copy to output area - pDC->BitBlt(oRct.left, oRct.top, oRct.Width(), oRct.Height(), - &dcMem, oRct.left, oRct.top, SRCCOPY); + pDC.Blit(oRct.GetLeft(), oRct.GetTop(), oRct.GetWidth(), oRct.GetHeight(), + &dcMem, oRct.GetLeft(), oRct.GetTop(), wxCOPY); } - - dcMem.SelectObject(pPrvBMap); } -OwnerPtr CTinyBoardView::DrawFullMap(CDC& pDC) +wxBitmap CTinyBoardView::DrawFullMap() { - OwnerPtr bmap = MakeOwner(); - CDC dcMem; + wxBitmap bmap; + wxMemoryDC dcMem; - CSize size = m_pPBoard->GetBoard()->GetSize(smallScale); + wxSize size = CB::Convert(m_pPBoard->GetBoard()->GetSize(smallScale)); - bmap->Attach(CreateRGBDIBSection(size.cx, size.cy)->Detach()); - dcMem.CreateCompatibleDC(&pDC); - CBitmap* pPrvBMap = dcMem.SelectObject(&*bmap); + bmap = wxBitmap(size.x, size.y); + dcMem.SelectObject(bmap); // Draw updated part of board image - BitmapBlt(dcMem, CPoint(0, 0), *m_pBMap); + dcMem.DrawBitmap(m_pBMap, 0, 0); // Draw pieces etc. (Need to rescale the DC and the update rect) - CRect rct(CPoint(0,0), size); - SetupDrawListDC(dcMem, rct); + wxRect rct(wxPoint(0,0), size); + { + DCSetupDrawListDC setupDrawList(*this, dcMem, rct); - m_pPBoard->Draw(dcMem, &rct, smallScale); + m_pPBoard->Draw(dcMem, rct, smallScale); - RestoreDrawListDC(dcMem); - dcMem.SelectObject(pPrvBMap); + } return bmap; } -void CTinyBoardView::RegenCachedMap(CDC& pDC) +void CTinyBoardView::RegenCachedMap(wxDC& pDC) { - CWaitCursor waitCursor; + wxBusyCursor waitCursor; CBoard* pBoard = m_pPBoard->GetBoard(); - CSize size = pBoard->GetSize(smallScale); // Get pixel size of board - m_pBMap = CreateRGBDIBSection(size.cx, size.cy); + wxSize size = CB::Convert(pBoard->GetSize(smallScale)); // Get pixel size of board + m_pBMap = wxBitmap(size.x, size.y, pDC); - CDC dcMem; - dcMem.CreateCompatibleDC(&pDC); - CBitmap* pPrvBMap = dcMem.SelectObject(&*m_pBMap); + wxMemoryDC dcMem; + dcMem.SelectObject(m_pBMap); - CRect rct(CPoint(0, 0), size); + wxRect rct(wxPoint(0, 0), size); pBoard->SetMaxDrawLayer(); // Make sure all layers are drawn pBoard->Draw(dcMem, rct, smallScale, m_pPBoard->m_bSmallCellBorders); - - dcMem.SelectObject(pPrvBMap); } ///////////////////////////////////////////////////////////////////////////// -void CTinyBoardView::SetupDrawListDC(CDC& pDC, CRect& rct) const +CTinyBoardView::DCSetupDrawListDC::DCSetupDrawListDC(const CTinyBoardView& rThis, wxDC& pDC, wxRect& rct) { - CSize wsize, vsize; - m_pPBoard->GetBoard()->GetBoardArray(). + wxSize wsize, vsize; + rThis.m_pPBoard->GetBoard()->GetBoardArray(). GetBoardScaling(smallScale, wsize, vsize); - pDC.SaveDC(); - pDC.SetMapMode(MM_ANISOTROPIC); - pDC.SetWindowExt(wsize); - pDC.SetViewportExt(vsize); + scaleChanger = CB::DCUserScaleChanger(pDC, double(vsize.x)/wsize.x, double(vsize.y)/wsize.y); ScaleRect(rct, wsize, vsize); } -void CTinyBoardView::RestoreDrawListDC(CDC &pDC) const -{ - pDC.RestoreDC(-1); -} - ///////////////////////////////////////////////////////////////////////////// -void CTinyBoardView::WorkspaceToClient(CRect& rect) const +void CTinyBoardView::WorkspaceToClient(wxRect& rect) const { - CPoint dpnt = GetDeviceScrollPosition(); - CSize wsize, vsize; + wxSize wsize, vsize; m_pPBoard->GetBoard()->GetBoardArray(). GetBoardScaling(smallScale, wsize, vsize); if (m_pPBoard->IsBoardRotated180()) { - rect = CRect(wsize.cx - rect.left, wsize.cy - rect.top, - wsize.cx - rect.right, wsize.cy - rect.bottom); - rect.NormalizeRect(); + rect = wxRect(wxPoint(wsize.x - rect.GetLeft(), wsize.y - rect.GetTop()), + wxPoint(wsize.x - rect.GetRight(), wsize.y - rect.GetBottom())); + CB::Normalize(rect); } ScaleRect(rect, vsize, wsize); - rect -= dpnt; + rect.SetLeftTop(CalcScrolledPosition(rect.GetTopLeft())); } -void CTinyBoardView::InvalidateWorkspaceRect(const CRect& pRect, BOOL bErase) +void CTinyBoardView::InvalidateWorkspaceRect(const wxRect& pRect, BOOL bErase) { - CRect rct(pRect); + wxRect rct(pRect); WorkspaceToClient(rct); - InvalidateRect(&rct, bErase); + RefreshRect(rct, bErase); } -void CTinyBoardView::ClientToWorkspace(CPoint& pnt) const +void CTinyBoardView::ClientToWorkspace(wxPoint& pnt) const { - pnt += GetDeviceScrollPosition(); - CSize wsize, vsize; + pnt = CalcUnscrolledPosition(pnt); + wxSize wsize, vsize; m_pPBoard->GetBoard()->GetBoardArray(). GetBoardScaling(smallScale, wsize, vsize); ScalePoint(pnt, wsize, vsize); if (m_pPBoard->IsBoardRotated180()) - pnt = CPoint(wsize.cx - pnt.x, wsize.cy - pnt.y); + pnt = wxPoint(wsize.x - pnt.x, wsize.y - pnt.y); } -///////////////////////////////////////////////////////////////////////////// - -#ifdef _DEBUG -CGamDoc& CTinyBoardView::GetDocument() // non-debug version is inline -{ - return CheckedDeref(CB::ToCGamDoc(m_pDocument)); -} -#endif //_DEBUG - ///////////////////////////////////////////////////////////////////////////// // CTinyBoardView message handlers -void CTinyBoardView::OnLButtonDown(UINT nFlags, CPoint point) +void CTinyBoardView::OnLButtonDown(wxMouseEvent& event) { + wxPoint point = event.GetPosition(); ClientToWorkspace(point); - CFrameWnd* pFrame = GetParentFrame(); - pFrame->SendMessage(WM_CENTERBOARDONPOINT, (WPARAM)&point); + // TODO: convert to wx when frame handles wxEvent + CFrameWnd* pFrame = parent->GetParentFrame(); + CPoint cpoint = CB::Convert(point); + pFrame->SendMessage(WM_CENTERBOARDONPOINT, reinterpret_cast(&cpoint)); } -void CTinyBoardView::OnRButtonDown(UINT nFlags, CPoint point) +void CTinyBoardView::OnRButtonDown(wxMouseEvent& event) { - if (!m_pBMap) + if (!m_pBMap.IsOk()) return; // owned by MFC RefPtr pTBrd(new CTinyBoardPopup); - { - CWindowDC dcRef(NULL); - pTBrd->m_bmap = DrawFullMap(dcRef); - } + pTBrd->m_bmap = DrawFullMap(); - pTBrd->m_pWnd = GetParentFrame(); + pTBrd->m_pWnd = parent->GetParentFrame(); m_pPBoard->GetBoard()->GetBoardArray(). GetBoardScaling(smallScale, pTBrd->m_wsize, pTBrd->m_vsize); pTBrd->m_bRotate180 = m_pPBoard->IsBoardRotated180(); - CRect rct; - GetWindowRect(&rct); - pTBrd->Create(GetMainFrame(), rct.CenterPoint()); + wxRect rct = GetScreenRect(); + pTBrd->Create(GetMainFrame(), GetMidRect(rct)); - CScrollView::OnRButtonDown(nFlags, point); + event.Skip(); } +#if 0 int CTinyBoardView::OnMouseActivate(CWnd* pDesktopWnd, UINT nHitTest, UINT message) { // We don't want the frame to ever consider this view to be the // "active" view. return CWnd::OnMouseActivate(pDesktopWnd, nHitTest, message); } +#endif + +void CTinyBoardView::RecalcScrollLimits() +{ + wxSizer& sizer = CheckedDeref(GetSizer()); + wxSizerItemList& items = sizer.GetChildren(); + wxASSERT(items.size() == 1); + wxSizerItem& item = CheckedDeref(items[0]); + wxASSERT(item.IsSpacer()); + + CBoard* pBoard = m_pPBoard->GetBoard(); + wxSize size = CB::Convert(pBoard->GetSize(smallScale)); + item.AssignSpacer(size); + SetScrollRate(size.x/100, size.y/100); + sizer.FitInside(this); +} void CTinyBoardViewContainer::OnDraw(CDC* pDC) { // do nothing because child covers entire client rect } +void CTinyBoardViewContainer::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint) +{ + child->OnUpdate(pSender, lHint, pHint); + + BASE::OnUpdate(pSender, lHint, pHint); +} + CTinyBoardViewContainer::CTinyBoardViewContainer() : - child(new CTinyBoardView) + CB::wxNativeContainerWindowMixin(static_cast(*this)) { } int CTinyBoardViewContainer::OnCreate(LPCREATESTRUCT lpCreateStruct) { - if (CView::OnCreate(lpCreateStruct) == -1) + if (BASE::OnCreate(lpCreateStruct) == -1) { return -1; } - DWORD dwStyle = AFX_WS_DEFAULT_VIEW & ~WS_BORDER; - // Create with the right size (wrong position) - CRect rect; - GetClientRect(rect); - CCreateContext context; - context.m_pCurrentDoc = GetDocument(); - if (!child->Create(NULL, NULL, dwStyle, - rect, this, 0, &context)) - { - return -1; - } + child = new CTinyBoardView(*this); return 0; } +#if 0 void CTinyBoardViewContainer::OnSize(UINT nType, int cx, int cy) { child->MoveWindow(0, 0, cx, cy); return CView::OnSize(nType, cx, cy); } +#endif int CTinyBoardViewContainer::OnMouseActivate(CWnd* pDesktopWnd, UINT nHitTest, UINT message) { @@ -408,6 +410,7 @@ int CTinyBoardViewContainer::OnMouseActivate(CWnd* pDesktopWnd, UINT nHitTest, U LRESULT CTinyBoardViewContainer::OnMessageWindowState(WPARAM wParam, LPARAM lParam) { - child->SendMessage(WM_WINSTATE, wParam, lParam); + WinStateEvent event(*reinterpret_cast(wParam), bool(lParam)); + child->ProcessWindowEvent(event); return (LRESULT)1; } diff --git a/GP/VwTbrd.h b/GP/VwTbrd.h index 092ad083..cbfbf43f 100644 --- a/GP/VwTbrd.h +++ b/GP/VwTbrd.h @@ -25,77 +25,107 @@ ///////////////////////////////////////////////////////////////////////////// // CTinyBoardView view -class CTinyBoardView : public CScrollView +class CTinyBoardView : public CB::ProcessEventOverride { -public: - CTinyBoardView(); +private: + friend class CTinyBoardViewContainer; + typedef CB::ProcessEventOverride BASE; + CTinyBoardView(CTinyBoardViewContainer& parent); // Attributes -private: - CGamDoc& GetDocument(); // Operations public: // Implementation +private: + // member declaration order determines construction order + RefPtr parent; + RefPtr document; protected: - CB::propagate_const m_pPBoard; // The playing board we are viewing - OwnerOrNullPtr m_pBMap; // Cached predrawn board bitmap + RefPtr m_pPBoard; // The playing board we are viewing + wxBitmap m_pBMap; // Cached predrawn board bitmap TileScale m_nZoom; - void RegenCachedMap(CDC& pDC); - OwnerPtr DrawFullMap(CDC& pDC); + void RegenCachedMap(wxDC& pDC); + wxBitmap DrawFullMap(); // Implementation protected: - void SetupDrawListDC(CDC& pDC, CRect& rct) const; - void RestoreDrawListDC(CDC &pDC) const; + class DCSetupDrawListDC + { + public: + DCSetupDrawListDC(const CTinyBoardView& rThis, wxDC& pDC, wxRect& rct); + private: + CB::DCUserScaleChanger scaleChanger; + }; // -------- // - void WorkspaceToClient(CRect& rect) const; - void ClientToWorkspace(CPoint& pnt) const; - void InvalidateWorkspaceRect(const CRect& pRect, BOOL bErase = FALSE); + void WorkspaceToClient(wxRect& rect) const; + void ClientToWorkspace(wxPoint& pnt) const; + void InvalidateWorkspaceRect(const wxRect& pRect, BOOL bErase = FALSE); // Implementation protected: ~CTinyBoardView() override = default; +#if 0 BOOL PreCreateWindow(CREATESTRUCT& cs) override; - void OnInitialUpdate() override; // first time after construct - void OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint) override; - void OnDraw(CDC* pDC) override; // overridden to draw this view +#endif + void OnInitialUpdate(); // first time after construct + void OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint); + void OnDraw(wxDC& pDC) override; // overridden to draw this view - // Generated message map functions - //{{AFX_MSG(CTinyBoardView) - afx_msg void OnLButtonDown(UINT nFlags, CPoint point); - afx_msg void OnRButtonDown(UINT nFlags, CPoint point); + void OnLButtonDown(wxMouseEvent& event); + void OnRButtonDown(wxMouseEvent& event); +#if 0 afx_msg int OnMouseActivate(CWnd* pDesktopWnd, UINT nHitTest, UINT message); - //}}AFX_MSG - afx_msg LRESULT OnMessageWindowState(WPARAM wParam, LPARAM lParam); - DECLARE_MESSAGE_MAP() -}; - -#ifndef _DEBUG // debug version in vwmbrd.cpp -inline CGamDoc& CTinyBoardView::GetDocument() - { return CheckedDeref(CB::ToCGamDoc(m_pDocument)); } #endif + void OnMessageWindowState(WinStateEvent& event); + wxDECLARE_EVENT_TABLE(); -class CTinyBoardViewContainer : public CView +private: + // IGetCmdTarget + CCmdTarget& Get() override; + + void RecalcScrollLimits(); +}; + +class CTinyBoardViewContainer : public CB::OnCmdMsgOverride, + public CB::wxNativeContainerWindowMixin { public: void OnDraw(CDC* pDC) override; + void OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint) override; + private: CTinyBoardViewContainer(); // used by dynamic creation DECLARE_DYNCREATE(CTinyBoardViewContainer) afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); +#if 0 afx_msg void OnSize(UINT nType, int cx, int cy); +#endif afx_msg int OnMouseActivate(CWnd* pDesktopWnd, UINT nHitTest, UINT message); afx_msg LRESULT OnMessageWindowState(WPARAM wParam, LPARAM lParam); DECLARE_MESSAGE_MAP() - // owned by MFC - RefPtr child; + // IGetEvtHandler + wxEvtHandler& Get() override + { + return CheckedDeref(CheckedDeref(child).GetEventHandler()); + } + + // owned by wx + CB::propagate_const child = nullptr; + + typedef CB::OnCmdMsgOverride BASE; + friend CTinyBoardView; }; +inline CCmdTarget& CTinyBoardView::Get() +{ + return *parent; +} + diff --git a/GP/WinPoptb.cpp b/GP/WinPoptb.cpp index 6590638f..d3f27e2e 100644 --- a/GP/WinPoptb.cpp +++ b/GP/WinPoptb.cpp @@ -28,6 +28,7 @@ #include "Gmisc.h" #include "GdiTools.h" #include "WinPoptb.h" +#include "CDib.h" #ifdef _DEBUG #define new DEBUG_NEW @@ -60,7 +61,7 @@ CTinyBoardPopup::~CTinyBoardPopup() ///////////////////////////////////////////////////////////////////////////// -BOOL CTinyBoardPopup::Create(CWnd* pParent, CPoint ptCenter) +BOOL CTinyBoardPopup::Create(CWnd* pParent, wxPoint ptCenter) { CRect rct(CPoint(0,0), m_vsize); DWORD dwStyle = WS_BORDER | WS_POPUP | WS_VISIBLE; @@ -124,7 +125,8 @@ void CTinyBoardPopup::OnPaint() CRect oRct; dcMem.CreateCompatibleDC(&dc); - CBitmap* pPrvBMap = dcMem.SelectObject(&*m_bmap); + OwnerPtr cm_bmap = CB::Convert(m_bmap); + CBitmap* pPrvBMap = dcMem.SelectObject(&*cm_bmap); CRect rctClient; GetClientRect(rctClient); diff --git a/GP/WinPoptb.h b/GP/WinPoptb.h index 278f94a3..c3b7388b 100644 --- a/GP/WinPoptb.h +++ b/GP/WinPoptb.h @@ -41,14 +41,14 @@ class CTinyBoardPopup : public CWnd // Attributes public: CWnd* m_pWnd; - OwnerPtr m_bmap = MakeOwner(); + wxBitmap m_bmap; CSize m_wsize; CSize m_vsize; BOOL m_bRotate180; // Board is rotated by 180 degrees // Operations public: - BOOL Create(CWnd* pParent, CPoint ptCenter); + BOOL Create(CWnd* pParent, wxPoint ptCenter); // Overrides // ClassWizard generated virtual function overrides From d58930a92f7b69483d805c5ec2d01a389d0aa22f Mon Sep 17 00:00:00 2001 From: Bill Su Date: Sat, 23 Aug 2025 03:27:54 -0400 Subject: [PATCH 20/80] WinPoptb: const-, null-, and override-correctness improvements --- GP/VwTbrd.cpp | 5 ++--- GP/WinPoptb.cpp | 10 +++++----- GP/WinPoptb.h | 15 ++++++++------- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/GP/VwTbrd.cpp b/GP/VwTbrd.cpp index 49f0cafe..bb6b1242 100644 --- a/GP/VwTbrd.cpp +++ b/GP/VwTbrd.cpp @@ -326,16 +326,15 @@ void CTinyBoardView::OnRButtonDown(wxMouseEvent& event) return; // owned by MFC - RefPtr pTBrd(new CTinyBoardPopup); + RefPtr pTBrd(new CTinyBoardPopup(CheckedDeref(parent->GetParentFrame()))); pTBrd->m_bmap = DrawFullMap(); - pTBrd->m_pWnd = parent->GetParentFrame(); m_pPBoard->GetBoard()->GetBoardArray(). GetBoardScaling(smallScale, pTBrd->m_wsize, pTBrd->m_vsize); pTBrd->m_bRotate180 = m_pPBoard->IsBoardRotated180(); wxRect rct = GetScreenRect(); - pTBrd->Create(GetMainFrame(), GetMidRect(rct)); + pTBrd->Create(CheckedDeref(GetMainFrame()), GetMidRect(rct)); event.Skip(); } diff --git a/GP/WinPoptb.cpp b/GP/WinPoptb.cpp index d3f27e2e..155f9b9f 100644 --- a/GP/WinPoptb.cpp +++ b/GP/WinPoptb.cpp @@ -1,6 +1,6 @@ // WinPoptb.cpp : implementation file // -// Copyright (c) 1994-2020 By Dale L. Larson, All Rights Reserved. +// Copyright (c) 1994-2025 By Dale L. Larson & William Su, All Rights Reserved. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the @@ -49,9 +49,9 @@ END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CTinyBoardPopup -CTinyBoardPopup::CTinyBoardPopup() +CTinyBoardPopup::CTinyBoardPopup(CWnd& pWnd) : + m_pWnd(&pWnd) { - m_pWnd = NULL; m_bRotate180 = FALSE; } @@ -61,7 +61,7 @@ CTinyBoardPopup::~CTinyBoardPopup() ///////////////////////////////////////////////////////////////////////////// -BOOL CTinyBoardPopup::Create(CWnd* pParent, wxPoint ptCenter) +BOOL CTinyBoardPopup::Create(CWnd& pParent, wxPoint ptCenter) { CRect rct(CPoint(0,0), m_vsize); DWORD dwStyle = WS_BORDER | WS_POPUP | WS_VISIBLE; @@ -91,7 +91,7 @@ BOOL CTinyBoardPopup::Create(CWnd* pParent, wxPoint ptCenter) return CWnd::CreateEx(dwExStyle, AfxRegisterWndClass(0, AfxGetApp()->LoadStandardCursor(IDC_ARROW), - (HBRUSH)(COLOR_BTNFACE + 1)), ""_cbstring, dwStyle, rct, pParent, NULL, NULL); + (HBRUSH)(COLOR_BTNFACE + 1)), ""_cbstring, dwStyle, rct, &pParent, NULL, NULL); } int CTinyBoardPopup::OnCreate(LPCREATESTRUCT lpCreateStruct) diff --git a/GP/WinPoptb.h b/GP/WinPoptb.h index c3b7388b..6107bc5f 100644 --- a/GP/WinPoptb.h +++ b/GP/WinPoptb.h @@ -1,6 +1,6 @@ // WinPoptb.h : header file // -// Copyright (c) 1994-2020 By Dale L. Larson, All Rights Reserved. +// Copyright (c) 1994-2025 By Dale L. Larson & William Su, All Rights Reserved. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the @@ -36,11 +36,12 @@ class CTinyBoardPopup : public CWnd { // Construction public: - CTinyBoardPopup(); + CTinyBoardPopup(CWnd& pWnd); // Attributes +private: + RefPtr m_pWnd; public: - CWnd* m_pWnd; wxBitmap m_bmap; CSize m_wsize; CSize m_vsize; @@ -48,24 +49,24 @@ class CTinyBoardPopup : public CWnd // Operations public: - BOOL Create(CWnd* pParent, wxPoint ptCenter); + BOOL Create(CWnd& pParent, wxPoint ptCenter); // Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CTinyBoardPopup) public: protected: - virtual void PostNcDestroy(); + void PostNcDestroy() override; //}}AFX_VIRTUAL // Implementation public: - virtual ~CTinyBoardPopup(); + ~CTinyBoardPopup() override; +private: void ProcessBoardHit(UINT nFlags, CPoint point); // Generated message map functions -protected: //{{AFX_MSG(CTinyBoardPopup) afx_msg void OnRButtonDown(UINT nFlags, CPoint point); afx_msg void OnLButtonDown(UINT nFlags, CPoint point); From e778075af507d3b5390a70335a604e5b0ec1e811 Mon Sep 17 00:00:00 2001 From: Bill Su Date: Mon, 25 Aug 2025 23:45:44 -0400 Subject: [PATCH 21/80] WinPoptb: replace MFC with wx --- GP/WinPoptb.cpp | 194 ++++++++++++++++++++++++++++++------------------ GP/WinPoptb.h | 43 ++++++----- 2 files changed, 147 insertions(+), 90 deletions(-) diff --git a/GP/WinPoptb.cpp b/GP/WinPoptb.cpp index 155f9b9f..58848505 100644 --- a/GP/WinPoptb.cpp +++ b/GP/WinPoptb.cpp @@ -36,15 +36,17 @@ static char THIS_FILE[] = __FILE__; #endif -BEGIN_MESSAGE_MAP(CTinyBoardPopup, CWnd) - //{{AFX_MSG_MAP(CTinyBoardPopup) - ON_WM_RBUTTONDOWN() - ON_WM_LBUTTONDOWN() +wxBEGIN_EVENT_TABLE(CTinyBoardPopup, wxPopupTransientWindow) + EVT_RIGHT_DOWN(OnRButtonDown) +#if 1 + EVT_LEFT_DOWN(OnLButtonDown) +#endif +#if 0 ON_WM_CREATE() - ON_WM_PAINT() - ON_WM_CHAR() - //}}AFX_MSG_MAP -END_MESSAGE_MAP() +#endif + EVT_PAINT(OnPaint) + EVT_CHAR(OnChar) +wxEND_EVENT_TABLE() ///////////////////////////////////////////////////////////////////////////// // CTinyBoardPopup @@ -61,39 +63,23 @@ CTinyBoardPopup::~CTinyBoardPopup() ///////////////////////////////////////////////////////////////////////////// -BOOL CTinyBoardPopup::Create(CWnd& pParent, wxPoint ptCenter) +BOOL CTinyBoardPopup::Create(wxWindow& pParent, wxPoint ptCenter) { - CRect rct(CPoint(0,0), m_vsize); - DWORD dwStyle = WS_BORDER | WS_POPUP | WS_VISIBLE; - DWORD dwExStyle = WS_EX_CLIENTEDGE; - - AdjustWindowRectEx(&rct, dwStyle, FALSE, dwExStyle); - rct.OffsetRect(ptCenter.x - rct.Width()/2, ptCenter.y - rct.Height()/2); - - // Make sure on screen... - CRect rctWrk; - SystemParametersInfo(SPI_GETWORKAREA, 0, &rctWrk, 0); - if (rct.right > rctWrk.right) - rct.OffsetRect(rctWrk.right - rct.right, 0); - if (rct.bottom > rctWrk.bottom) - rct.OffsetRect(0, rctWrk.bottom - rct.bottom); - - if (rct.Width() > rctWrk.Width()) + // wxPU_CONTAINS_CONTROLS required to enable having focus + BOOL retval = wxPopupTransientWindow::Create(&pParent, + wxPU_CONTAINS_CONTROLS | wxBORDER_SUNKEN); + if (retval) { - rct.left = rctWrk.left; - rct.right = rctWrk.right; + SetClientSize(m_vsize); + wxRect rct(wxPoint(0, 0), GetSize()); + rct.Offset(ptCenter.x - rct.GetWidth()/2, ptCenter.y - rct.GetHeight()/2); + Position(rct.GetLeftTop(), wxDefaultSize); + Popup(); } - if (rct.Height() > rctWrk.Height()) - { - rct.top = rctWrk.top; - rct.bottom = rctWrk.bottom; - } - - return CWnd::CreateEx(dwExStyle, - AfxRegisterWndClass(0, AfxGetApp()->LoadStandardCursor(IDC_ARROW), - (HBRUSH)(COLOR_BTNFACE + 1)), ""_cbstring, dwStyle, rct, &pParent, NULL, NULL); + return retval; } +#if 0 int CTinyBoardPopup::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CWnd::OnCreate(lpCreateStruct) == -1) @@ -108,74 +94,136 @@ int CTinyBoardPopup::OnCreate(LPCREATESTRUCT lpCreateStruct) return 0; } +#endif ///////////////////////////////////////////////////////////////////////////// // CTinyBoardPopup message handlers -void CTinyBoardPopup::PostNcDestroy() +void CTinyBoardPopup::OnPaint(wxPaintEvent& event) { - delete this; -} + wxPaintDC dc(this); // device context for painting -void CTinyBoardPopup::OnPaint() -{ - CPaintDC dc(this); // device context for painting + wxMemoryDC dcMem; + wxRect oRct; - CDC dcMem; - CRect oRct; + dcMem.SelectObject(m_bmap); - dcMem.CreateCompatibleDC(&dc); - OwnerPtr cm_bmap = CB::Convert(m_bmap); - CBitmap* pPrvBMap = dcMem.SelectObject(&*cm_bmap); - - CRect rctClient; - GetClientRect(rctClient); + wxRect rctClient = GetClientRect(); if (m_bRotate180) { - dc.StretchBlt(0, 0, rctClient.right, rctClient.bottom, &dcMem, - m_vsize.cx - 1,m_vsize.cy - 1, -m_vsize.cx, -m_vsize.cy, SRCCOPY); + dc.StretchBlit(0, 0, rctClient.GetRight(), rctClient.GetBottom(), &dcMem, + m_vsize.x - 1,m_vsize.y - 1, -m_vsize.x, -m_vsize.y); } else { - dc.StretchBlt(0, 0, rctClient.right, rctClient.bottom, &dcMem, 0, 0, - m_vsize.cx, m_vsize.cy, SRCCOPY); + dc.StretchBlit(0, 0, rctClient.GetRight(), rctClient.GetBottom(), &dcMem, 0, 0, + m_vsize.x, m_vsize.y); } - - dcMem.SelectObject(pPrvBMap); } -void CTinyBoardPopup::ProcessBoardHit(UINT nFlags, CPoint point) +void CTinyBoardPopup::ProcessBoardHit(wxMouseEvent& event) { - ReleaseCapture(); + wxPoint point = event.GetPosition(); - CRect rctClient; - GetClientRect(&rctClient); - if (rctClient.PtInRect(point)) + wxRect rctClient = GetClientRect(); + if (rctClient.Contains(point)) { - ScalePoint(point, m_wsize, rctClient.Size()); + ScalePoint(point, m_wsize, rctClient.GetSize()); if (m_bRotate180) - point = CPoint(m_wsize.cx - point.x, m_wsize.cy - point.y); - m_pWnd->SendMessage(WM_CENTERBOARDONPOINT, (WPARAM)&point); + point = wxPoint(m_wsize.x - point.x, m_wsize.y - point.y); + CPoint cpoint = CB::Convert(point); + m_pWnd->SendMessage(WM_CENTERBOARDONPOINT, (WPARAM)&cpoint); } - DestroyWindow(); + Dismiss(); } -void CTinyBoardPopup::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) +void CTinyBoardPopup::OnChar(wxKeyEvent& event) { - if (nChar == VK_ESCAPE) + if (event.GetUnicodeKey() == WXK_ESCAPE) { - ReleaseCapture(); - DestroyWindow(); + Dismiss(); } } -void CTinyBoardPopup::OnRButtonDown(UINT nFlags, CPoint point) +void CTinyBoardPopup::OnRButtonDown(wxMouseEvent& event) { - ProcessBoardHit(nFlags, point); + ProcessBoardHit(event); } -void CTinyBoardPopup::OnLButtonDown(UINT nFlags, CPoint point) +#if 1 +void CTinyBoardPopup::OnLButtonDown(wxMouseEvent& event) +#else +bool CTinyBoardPopup::ProcessLeftDown(wxMouseEvent& event) +#endif +{ + ProcessBoardHit(event); +#if 1 +#else + return false; +#endif +} + +/* default position policy wants no overlap between arg rect + and this, but we want as close to leftTop as screen + permits */ +void CTinyBoardPopup::Position(const wxPoint& ptOrigin, + const wxSize& sizePopup) { - ProcessBoardHit(nFlags, point); + // based on wxPopupWindowBase::Position() + // determine the position and size of the screen we clamp the popup to + wxPoint posScreen; + wxSize sizeScreen; + + const int displayNum = wxDisplay::GetFromPoint(ptOrigin); + if ( displayNum != wxNOT_FOUND ) + { + const wxRect rectScreen = wxDisplay(displayNum).GetGeometry(); + posScreen = rectScreen.GetPosition(); + sizeScreen = rectScreen.GetSize(); + } + else // outside of any display? + { + // just use the primary one then + posScreen = wxPoint(0, 0); + sizeScreen = wxGetDisplaySize(); + } + + + const wxSize sizeSelf = GetSize(); + + wxCoord y = ptOrigin.y; + if ( y + sizeSelf.y > posScreen.y + sizeScreen.y ) + { + y = posScreen.y + sizeScreen.y - sizeSelf.y; + } + + // now check left/right too + wxCoord x = ptOrigin.x; + + if ( wxTheApp->GetLayoutDirection() == wxLayout_RightToLeft ) + { + wxASSERT(!"untested code"); + // shift the window to the left instead of the right. + x -= sizeSelf.x; // also shift it by window width. + } + + + if ( x + sizeSelf.x > posScreen.x + sizeScreen.x ) + { + x = posScreen.x + sizeScreen.x - sizeSelf.x; + } + + Move(x, y, wxSIZE_NO_ADJUSTMENTS); +} + +void CTinyBoardPopup::Dismiss() +{ + /* KLUDGE: sometimes getting multiple dismisses, but should + not destroy multiple times */ + if (IsShown()) + { + wxPopupTransientWindow::Dismiss(); + Destroy(); + } } diff --git a/GP/WinPoptb.h b/GP/WinPoptb.h index 6107bc5f..35493130 100644 --- a/GP/WinPoptb.h +++ b/GP/WinPoptb.h @@ -32,7 +32,7 @@ ///////////////////////////////////////////////////////////////////////////// // CTinyBoardPopup window -class CTinyBoardPopup : public CWnd +class CTinyBoardPopup : public wxPopupTransientWindow { // Construction public: @@ -43,38 +43,47 @@ class CTinyBoardPopup : public CWnd RefPtr m_pWnd; public: wxBitmap m_bmap; - CSize m_wsize; - CSize m_vsize; + wxSize m_wsize; + wxSize m_vsize; BOOL m_bRotate180; // Board is rotated by 180 degrees // Operations public: - BOOL Create(CWnd& pParent, wxPoint ptCenter); + BOOL Create(wxWindow& pParent, wxPoint ptCenter); // Overrides - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CTinyBoardPopup) public: protected: - void PostNcDestroy() override; - //}}AFX_VIRTUAL // Implementation public: ~CTinyBoardPopup() override; private: - void ProcessBoardHit(UINT nFlags, CPoint point); + void ProcessBoardHit(wxMouseEvent& event); - // Generated message map functions - //{{AFX_MSG(CTinyBoardPopup) - afx_msg void OnRButtonDown(UINT nFlags, CPoint point); - afx_msg void OnLButtonDown(UINT nFlags, CPoint point); + void OnRButtonDown(wxMouseEvent& event); + /* N.B.: OnLButtonDown() instead of ProcessLeftDown() + see https://groups.google.com/g/wx-dev/c/506M_PpcsZk/m/FODigxNUAQAJ + */ +#if 1 + void OnLButtonDown(wxMouseEvent& event); +#else + bool ProcessLeftDown(wxMouseEvent& event) override; +#endif +#if 0 afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); - afx_msg void OnPaint(); - afx_msg void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags); - //}}AFX_MSG - DECLARE_MESSAGE_MAP() +#endif + void OnPaint(wxPaintEvent& event); + void OnChar(wxKeyEvent& event); + wxDECLARE_EVENT_TABLE(); + + /* default position policy wants no overlap between arg rect + and this, but we want as close to leftTop as screen + permits */ + void Position(const wxPoint& leftTop, + const wxSize&) override; + void Dismiss() override; }; ///////////////////////////////////////////////////////////////////////////// From 364fddc3b5b69a9bca2bb80a055dbf3df56a33b3 Mon Sep 17 00:00:00 2001 From: Bill Su Date: Tue, 26 Aug 2025 20:52:18 -0400 Subject: [PATCH 22/80] VwSelpce: improve const-, null-, override-correctness --- GP/VwSelpce.cpp | 13 ++++++------- GP/VwSelpce.h | 22 +++++++++++----------- 2 files changed, 17 insertions(+), 18 deletions(-) diff --git a/GP/VwSelpce.cpp b/GP/VwSelpce.cpp index edc71c7c..59fb7ecd 100644 --- a/GP/VwSelpce.cpp +++ b/GP/VwSelpce.cpp @@ -1,6 +1,6 @@ // VwSelpce.cpp : Selected Piece List View // -// Copyright (c) 1994-2020 By Dale L. Larson, All Rights Reserved. +// Copyright (c) 1994-2025 By Dale L. Larson & William Su, All Rights Reserved. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the @@ -121,9 +121,9 @@ BOOL CSelectedPieceView::PreTranslateMessage(MSG* pMsg) void CSelectedPieceView::OnInitialUpdate() { - m_pPBoard = (CPlayBoard*)GetDocument()->GetNewViewParameter(); + m_pPBoard = static_cast(GetDocument().GetNewViewParameter()); CView::OnInitialUpdate(); - m_listSel.SetDocument(GetDocument()); + m_listSel.SetDocument(&GetDocument()); } void CSelectedPieceView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint) @@ -182,11 +182,10 @@ BOOL CSelectedPieceView::OnEraseBkgnd(CDC* pDC) ///////////////////////////////////////////////////////////////////////////// #ifdef _DEBUG -CGamDoc* CSelectedPieceView::GetDocument() // non-debug version is inline +CGamDoc& CSelectedPieceView::GetDocument() // non-debug version is inline { CGamDoc* retval = CB::ToCGamDoc(m_pDocument); - wxASSERT(retval); - return retval; + return CheckedDeref(retval); } #endif //_DEBUG @@ -250,7 +249,7 @@ void CSelectedPieceView::ModifySelectionsBasedOnListItems(BOOL bRemoveSelectedIt } } CPlayBoardFrame* pFrame = (CPlayBoardFrame*)GetParentFrame(); - pFrame->SendMessageToActiveBoardPane(WM_SELECT_BOARD_OBJLIST, (WPARAM)m_pPBoard, + pFrame->SendMessageToActiveBoardPane(WM_SELECT_BOARD_OBJLIST, (WPARAM)&*m_pPBoard, (LPARAM)&listDObj); } diff --git a/GP/VwSelpce.h b/GP/VwSelpce.h index e4bc7425..49212647 100644 --- a/GP/VwSelpce.h +++ b/GP/VwSelpce.h @@ -1,6 +1,6 @@ // VwSelpce.h : header file // -// Copyright (c) 1994-2020 By Dale L. Larson, All Rights Reserved. +// Copyright (c) 1994-2025 By Dale L. Larson & William Su, All Rights Reserved. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the @@ -38,15 +38,15 @@ class CSelectedPieceView : public CView CSelectedPieceView(); // protected constructor used by dynamic creation // Attributes -public: - CGamDoc* GetDocument(); +private: + CGamDoc& GetDocument(); // Operations public: // Implementation protected: - CPlayBoard* m_pPBoard; // Board that contains selections + CB::propagate_const m_pPBoard; // Board that contains selections CSelectListBox m_listSel; std::vector> m_tblSel; @@ -56,11 +56,11 @@ class CSelectedPieceView : public CView protected: void ModifySelectionsBasedOnListItems(BOOL bRemoveSelectedItems); - virtual ~CSelectedPieceView(); - virtual void OnDraw(CDC* pDC); // overridden to draw this view - virtual void OnInitialUpdate(); - virtual void OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint); - virtual BOOL PreTranslateMessage(MSG* pMsg); + ~CSelectedPieceView() override; + void OnDraw(CDC* pDC) override; // overridden to draw this view + void OnInitialUpdate() override; + void OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint) override; + BOOL PreTranslateMessage(MSG* pMsg) override; // Generated message map functions protected: @@ -76,7 +76,7 @@ class CSelectedPieceView : public CView }; #ifndef _DEBUG // debug version in vwselpce.cpp -inline CGamDoc* CSelectedPieceView::GetDocument() - { return CB::ToCGamDoc(m_pDocument); } +inline CGamDoc& CSelectedPieceView::GetDocument() + { return CheckedDeref(CB::ToCGamDoc(m_pDocument)); } #endif From 5c77f4e674c6235c5d4abb14f7bc9c5ab92920b2 Mon Sep 17 00:00:00 2001 From: Bill Su Date: Wed, 27 Aug 2025 00:01:17 -0400 Subject: [PATCH 23/80] VwSelpce: create an extra window to simplify wx conversion MFC manages doc/frame/view objects, so split CSelectedPieceView into a parent window that MFC can manage and a child window that has the main implementation. That way we can convert the main implementation to wx while still letting MFC's doc/frame/view code work. --- GP/FrmPbrd.cpp | 2 +- GP/VwSelpce.cpp | 60 ++++++++++++++++++++++++++++++++++++++++++++++++- GP/VwSelpce.h | 22 ++++++++++++++++-- 3 files changed, 80 insertions(+), 4 deletions(-) diff --git a/GP/FrmPbrd.cpp b/GP/FrmPbrd.cpp index a344091d..87e284fc 100644 --- a/GP/FrmPbrd.cpp +++ b/GP/FrmPbrd.cpp @@ -213,7 +213,7 @@ BOOL CPlayBoardFrame::OnCreateClient(LPCREATESTRUCT lpcs, } if (!m_wndSplitter2.CreateView(0, 0, - RUNTIME_CLASS(CSelectedPieceView), + RUNTIME_CLASS(CSelectedPieceViewContainer), CSize(rct.Width() - xSize, ySize), pContext)) { TRACE("Failed to create second Selected Piece pane\n"); diff --git a/GP/VwSelpce.cpp b/GP/VwSelpce.cpp index 59fb7ecd..0e76a7a1 100644 --- a/GP/VwSelpce.cpp +++ b/GP/VwSelpce.cpp @@ -36,7 +36,7 @@ static char THIS_FILE[] = __FILE__; #endif -IMPLEMENT_DYNCREATE(CSelectedPieceView, CView) +IMPLEMENT_DYNCREATE(CSelectedPieceViewContainer, CView) #ifdef _DEBUG #define new DEBUG_NEW @@ -55,6 +55,13 @@ BEGIN_MESSAGE_MAP(CSelectedPieceView, CView) ON_MESSAGE(WM_WINSTATE, OnMessageWindowState) END_MESSAGE_MAP() +BEGIN_MESSAGE_MAP(CSelectedPieceViewContainer, CView) + ON_WM_CREATE() + ON_WM_SIZE() + ON_WM_MOUSEACTIVATE() + ON_MESSAGE(WM_WINSTATE, OnMessageWindowState) +END_MESSAGE_MAP() + ///////////////////////////////////////////////////////////////////////////// // CSelectedPieceView @@ -253,3 +260,54 @@ void CSelectedPieceView::ModifySelectionsBasedOnListItems(BOOL bRemoveSelectedIt (LPARAM)&listDObj); } +void CSelectedPieceViewContainer::OnDraw(CDC* pDC) +{ + // do nothing because child covers entire client rect +} + +CSelectedPieceViewContainer::CSelectedPieceViewContainer() : + child(new CSelectedPieceView) +{ +} + +int CSelectedPieceViewContainer::OnCreate(LPCREATESTRUCT lpCreateStruct) +{ + if (CView::OnCreate(lpCreateStruct) == -1) + { + return -1; + } + + DWORD dwStyle = AFX_WS_DEFAULT_VIEW & ~WS_BORDER; + // Create with the right size (wrong position) + CRect rect; + GetClientRect(rect); + CCreateContext context; + context.m_pCurrentDoc = GetDocument(); + if (!child->Create(NULL, NULL, dwStyle, + rect, this, 0, &context)) + { + return -1; + } + + return 0; +} + +void CSelectedPieceViewContainer::OnSize(UINT nType, int cx, int cy) +{ + child->MoveWindow(0, 0, cx, cy); + return CView::OnSize(nType, cx, cy); +} + +int CSelectedPieceViewContainer::OnMouseActivate(CWnd* pDesktopWnd, UINT nHitTest, UINT message) +{ + // We don't want the frame to ever consider this view to be the + // "active" view. + return CWnd::OnMouseActivate(pDesktopWnd, nHitTest, message); +} + +LRESULT CSelectedPieceViewContainer::OnMessageWindowState(WPARAM wParam, LPARAM lParam) +{ + child->SendMessage(WM_WINSTATE, wParam, lParam); + return (LRESULT)1; +} + diff --git a/GP/VwSelpce.h b/GP/VwSelpce.h index 49212647..2ffa8a39 100644 --- a/GP/VwSelpce.h +++ b/GP/VwSelpce.h @@ -33,8 +33,8 @@ class CPlayBoard; class CSelectedPieceView : public CView { - DECLARE_DYNCREATE(CSelectedPieceView) -protected: +private: + friend class CSelectedPieceViewContainer; CSelectedPieceView(); // protected constructor used by dynamic creation // Attributes @@ -80,3 +80,21 @@ inline CGamDoc& CSelectedPieceView::GetDocument() { return CheckedDeref(CB::ToCGamDoc(m_pDocument)); } #endif +class CSelectedPieceViewContainer : public CView +{ +public: + void OnDraw(CDC* pDC) override; + +private: + CSelectedPieceViewContainer(); // used by dynamic creation + DECLARE_DYNCREATE(CSelectedPieceViewContainer) + + afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); + afx_msg void OnSize(UINT nType, int cx, int cy); + afx_msg int OnMouseActivate(CWnd* pDesktopWnd, UINT nHitTest, UINT message); + afx_msg LRESULT OnMessageWindowState(WPARAM wParam, LPARAM lParam); + DECLARE_MESSAGE_MAP() + + // owned by MFC + RefPtr child; +}; From 3d74642627f0f0706ab9569afcd3154298459dd7 Mon Sep 17 00:00:00 2001 From: Bill Su Date: Mon, 8 Sep 2025 21:45:21 -0400 Subject: [PATCH 24/80] LBoxGfx2: improve const-correctness --- GP/GamDoc.h | 18 +++++++++--------- GP/GamDoc1.cpp | 40 +++++++++++++++++++-------------------- GP/LBoxSlct.cpp | 14 +++++++------- GP/MoveMgr.cpp | 2 +- GP/PalTray.cpp | 2 +- GP/SelOPlay.cpp | 8 ++++++++ GP/SelOPlay.h | 2 ++ GP/ToolPlay.cpp | 2 +- GP/VwPbrd.cpp | 14 +++++++------- GP/VwPbrd.h | 2 +- GP/VwSelpce.h | 2 +- GP/VwTbrd.cpp | 4 ++-- GShr/CyberBoard.h | 14 ++++++++++++++ GShr/DrawObj.cpp | 48 ++++++++++++++++++++++++++++++++++------------- GShr/DrawObj.h | 8 +++++--- GShr/LBoxGfx2.cpp | 2 +- GShr/LBoxGfx2.h | 6 +++--- 17 files changed, 118 insertions(+), 70 deletions(-) diff --git a/GP/GamDoc.h b/GP/GamDoc.h index e32537cf..7c1350ea 100644 --- a/GP/GamDoc.h +++ b/GP/GamDoc.h @@ -143,14 +143,14 @@ class CGamDocHint : public CObject struct Args { const CPlayBoard* m_pPBoard; - CDrawObj* m_pDrawObj; + const CDrawObj* m_pDrawObj; }; template<> struct Args { CPlayBoard* m_pPBoard; - const std::vector>* m_pPtrList; + const std::vector>* m_pPtrList; }; template<> @@ -428,7 +428,7 @@ class CGamDoc : public CDocument void PlacePieceListOnBoard(CPoint pnt, const std::vector& pTbl, int xStagger, int yStagger, CPlayBoard *pPBrd); size_t PlacePieceListInTray(const std::vector& pTbl, CTraySet& pYGrp, size_t nPos = Invalid_v); - size_t PlaceObjectTableInTray(const std::vector> & pTbl, CTraySet& pYGrp, size_t nPos = Invalid_v); + size_t PlaceObjectTableInTray(const std::vector>& pTbl, CTraySet& pYGrp, size_t nPos = Invalid_v); void PlaceObjectTableOnBoard(const std::vector>& pLst, CPoint pntUpLeft, CPlayBoard* pPBrd, PlacePos ePos = placeDefault); void PlaceObjectTableOnBoard(CPoint pnt, const std::vector>& pTbl, @@ -438,7 +438,7 @@ class CGamDoc : public CDocument CSize sizeDelta, PlacePos ePos = placeDefault); void InvertPlayingPieceInTray(PieceID pid, CPieceTable::Flip flip, size_t side, bool bOkToNotifyTray, bool forceHide); - void InvertPlayingPieceOnBoard(CPieceObj& pObj, const CPlayBoard& pPBrd, CPieceTable::Flip flip, size_t side = Invalid_v); + void InvertPlayingPieceOnBoard(const CPieceObj& pObj, const CPlayBoard& pPBrd, CPieceTable::Flip flip, size_t side = Invalid_v); void InvertPlayingPieceTableOnBoard(const std::vector>& pLst, const CPlayBoard& pPBrd, CPieceTable::Flip flip); void ChangePlayingPieceFacingOnBoard(CPieceObj& pObj, CPlayBoard* pPBrd, @@ -457,18 +457,18 @@ class CGamDoc : public CDocument CPoint ptEnd, UINT nLineWd, COLORREF crLine, ObjectID dwObjID = ObjectID()); void ModifyLineObject(CPlayBoard* pPBrd, CPoint ptBeg, CPoint ptEnd, UINT nLineWd, COLORREF crLine, CLine* pObj); - void ReorgObjsInDrawList(CPlayBoard *pPBrd, std::vector>& pList, BOOL bToFront); - void DeleteObjectsInTable(const std::vector>& pList); + void ReorgObjsInDrawList(CPlayBoard *pPBrd, std::vector>& pList, BOOL bToFront); + void DeleteObjectsInTable(const std::vector>& pList); void SetObjectText(GameElement elem, const CB::string* pszObjText); void SetObjectLockdownTable(const std::vector>& pLst, BOOL bLockState); void SetObjectLockdown(CDrawObj& pDObj, BOOL bLockState); BOOL RemovePieceFromCurrentLocation(PieceID pid, BOOL bDeleteIfBoard, BOOL bTrayHintAllowed = TRUE); - void RemoveObjectFromCurrentLocation(CDrawObj* pObj); + void RemoveObjectFromCurrentLocation(const CDrawObj& pObj); void ExpungeUnusedPiecesFromBoards(); - void FindObjectTableUnionRect(const std::vector>& pLst, CRect& rct) const; + void FindObjectTableUnionRect(const std::vector>& pLst, CRect& rct) const; // Object and piece locator methods... BOOL FindPieceCurrentLocation(PieceID pid, const CTraySet*& pTraySet, @@ -496,7 +496,7 @@ class CGamDoc : public CDocument { return const_cast(std::as_const(*this).FindObjectOnBoard(dwObjID, const_cast(ppObj))); } - CPlayBoard* FindObjectOnBoard(CDrawObj* pObj); + CPlayBoard* FindObjectOnBoard(const CDrawObj& pObj); // Support for playback... void EnsureBoardVisible(CPlayBoard& pPBoard); diff --git a/GP/GamDoc1.cpp b/GP/GamDoc1.cpp index 19de48e8..223c9849 100644 --- a/GP/GamDoc1.cpp +++ b/GP/GamDoc1.cpp @@ -144,7 +144,7 @@ void CGamDoc::PlaceObjectOnBoard(CPlayBoard *pPBrd, CDrawObj::OwnerPtr opObj, } } else - RemoveObjectFromCurrentLocation(&pObj); + RemoveObjectFromCurrentLocation(pObj); pObj.MoveObject(pObj.GetRect().TopLeft() + sizeDelta); @@ -186,7 +186,7 @@ void CGamDoc::PlaceObjectTableOnBoard(const std::vector> CDrawList* pDwg = pPBrd->GetPieceList(); ASSERT(pDwg); CRect rct; - FindObjectTableUnionRect(pLst, rct); + FindObjectTableUnionRect(ToRefPtr(pLst), rct); CSize size(pntUpLeft.x - rct.left, pntUpLeft.y - rct.top); if (pPBrd->GetPlotMoveMode()) @@ -291,14 +291,14 @@ void CGamDoc::PlaceObjectTableOnBoard(const std::vector> // Record processing if (pObj.GetType() == CDrawObj::drawPieceObj) { - CPieceObj& pPObj = static_cast(pObj); + const CPieceObj& pPObj = static_cast(pObj); CRect rctPce = pPObj.GetRect(); RecordPieceMoveToBoard(pPBrd, pPObj.m_pid, GetMidRect(rctPce) + size, ePos); } else if (pObj.GetType() == CDrawObj::drawMarkObj) { - CMarkObj& pMObj = static_cast(pObj); + const CMarkObj& pMObj = static_cast(pObj); CRect rctMrk = pMObj.GetRect(); RecordMarkMoveToBoard(pPBrd, pMObj.GetObjectID(), pMObj.m_mid, GetMidRect(rctMrk) + size, ePos); @@ -317,7 +317,7 @@ void CGamDoc::PlaceObjectTableOnBoard(const std::vector> } } else - RemoveObjectFromCurrentLocation(&pObj); + RemoveObjectFromCurrentLocation(pObj); pObj.MoveObject(pObj.GetRect().TopLeft() + size); @@ -446,17 +446,17 @@ size_t CGamDoc::PlacePieceListInTray(const std::vector& pTbl, CTraySet& ////////////////////////////////////////////////////////////////////// // Returns index of last piece inserted. -size_t CGamDoc::PlaceObjectTableInTray(const std::vector>& pLst, CTraySet& pYGrp, size_t nPos) +size_t CGamDoc::PlaceObjectTableInTray(const std::vector>& pLst, CTraySet& pYGrp, size_t nPos) { // Scan this list in reverse order so they show up in the // same visual order. for (size_t i = pLst.size() ; i != size_t(0) ; --i) { - CDrawObj& pObj = *pLst[i - size_t(1)]; + const CDrawObj& pObj = *pLst[i - size_t(1)]; // Only pieces are placed. Other objects are left as they were. if (pObj.GetType() == CDrawObj::drawPieceObj) { - PlacePieceInTray(static_cast(pObj).m_pid, pYGrp, nPos); + PlacePieceInTray(static_cast(pObj).m_pid, pYGrp, nPos); if (nPos != Invalid_v) nPos++; } @@ -466,7 +466,7 @@ size_t CGamDoc::PlaceObjectTableInTray(const std::vector ////////////////////////////////////////////////////////////////////// // (RECORDS) -void CGamDoc::InvertPlayingPieceOnBoard(CPieceObj& pObj, const CPlayBoard& pPBrd, CPieceTable::Flip flip, size_t side /*= Invalid_v*/) +void CGamDoc::InvertPlayingPieceOnBoard(const CPieceObj& pObj, const CPlayBoard& pPBrd, CPieceTable::Flip flip, size_t side /*= Invalid_v*/) { if (m_pPTbl->GetSides(pObj.m_pid) <= size_t(1)) return; @@ -618,18 +618,18 @@ void CGamDoc::ChangeMarkerFacingOnBoard(CMarkObj& pObj, CPlayBoard* pPBrd, ////////////////////////////////////////////////////////////////////// // (RECORDS) -void CGamDoc::DeleteObjectsInTable(const std::vector>& pLst) +void CGamDoc::DeleteObjectsInTable(const std::vector>& pLst) { for (auto pos = pLst.begin() ; pos != pLst.end() ; ++pos) { - CDrawObj& pObj = **pos; + const CDrawObj& pObj = **pos; // Only nonpieces are deleted. Pieces are left as they were. if (pObj.GetType() != CDrawObj::drawPieceObj) { if (pObj.GetType() == CDrawObj::drawMarkObj) RecordObjectDelete(pObj.GetObjectID()); - CPlayBoard* pPBrd = FindObjectOnBoard(&pObj); + CPlayBoard* pPBrd = FindObjectOnBoard(pObj); ASSERT(pPBrd != NULL); pPBrd->RemoveObject(pObj); @@ -824,7 +824,7 @@ void CGamDoc::ModifyLineObject(CPlayBoard* pPBrd, CPoint ptBeg, ////////////////////////////////////////////////////////////////////// -void CGamDoc::ReorgObjsInDrawList(CPlayBoard *pPBrd, std::vector>& pList, +void CGamDoc::ReorgObjsInDrawList(CPlayBoard *pPBrd, std::vector>& pList, BOOL bToFront) { CDrawList* pDwg = pPBrd->GetPieceList(); @@ -866,10 +866,10 @@ const CPlayBoard* CGamDoc::FindObjectOnBoard(ObjectID dwObjID, const CDrawObj*& return m_pPBMgr->FindObjectOnBoard(dwObjID, ppObj); } -CPlayBoard* CGamDoc::FindObjectOnBoard(CDrawObj* pObj) +CPlayBoard* CGamDoc::FindObjectOnBoard(const CDrawObj& pObj) { ASSERT(m_pPBMgr != NULL); - return m_pPBMgr->FindObjectOnBoard(*pObj); + return m_pPBMgr->FindObjectOnBoard(pObj); } const CPlayBoard* CGamDoc::FindPieceOnBoard(PieceID pid, const CPieceObj*& ppObj) const @@ -944,18 +944,18 @@ BOOL CGamDoc::FindPieceCurrentLocation(PieceID pid, const CTraySet*& pTraySet, //////////////////////////////////////////////////////////////////// -void CGamDoc::RemoveObjectFromCurrentLocation(CDrawObj* pObj) +void CGamDoc::RemoveObjectFromCurrentLocation(const CDrawObj& pObj) { CPlayBoard* pPBoard = FindObjectOnBoard(pObj); if (pPBoard != NULL) { - pPBoard->RemoveObject(*pObj); + pPBoard->RemoveObject(pObj); if (!IsQuietPlayback()) { // Cause it's former location to be invalidated... CGamDocHint hint; hint.GetArgs().m_pPBoard = pPBoard; - hint.GetArgs().m_pDrawObj = pObj; + hint.GetArgs().m_pDrawObj = &pObj; UpdateAllViews(NULL, HINT_UPDATEOBJECT, &hint); } } @@ -963,13 +963,13 @@ void CGamDoc::RemoveObjectFromCurrentLocation(CDrawObj* pObj) //////////////////////////////////////////////////////////////////// -void CGamDoc::FindObjectTableUnionRect(const std::vector>& pLst, CRect& rct) const +void CGamDoc::FindObjectTableUnionRect(const std::vector>& pLst, CRect& rct) const { rct.SetRectEmpty(); for (auto pos = pLst.begin() ; pos != pLst.end() ; ++pos) { - CDrawObj& pObj = **pos; + const CDrawObj& pObj = **pos; if (rct.IsRectEmpty()) rct = pObj.GetRect(); else diff --git a/GP/LBoxSlct.cpp b/GP/LBoxSlct.cpp index d03e283d..d68b4d73 100644 --- a/GP/LBoxSlct.cpp +++ b/GP/LBoxSlct.cpp @@ -227,7 +227,7 @@ BOOL CSelectListBox::OnActTurnOver(UINT id) case ID_ACT_TURNOVER_RANDOM: { bool b = view.OnCmdMsg(id, CN_COMMAND, nullptr, nullptr); - ASSERT(b); + wxASSERT(b); return b; } case ID_ACT_TURNOVER_SELECT: @@ -239,19 +239,19 @@ BOOL CSelectListBox::OnActTurnOver(UINT id) PieceID pid = static_cast(menuGameElement); auto it = std::find_if(GetItemMap()->begin(), GetItemMap()->end(), - [pid](CB::not_null drawObj) + [pid](const RefPtr& drawObj) { if (drawObj->GetType() != CDrawObj::drawPieceObj) { return false; } - CPieceObj& pieceObj = static_cast(*drawObj); + const CPieceObj& pieceObj = static_cast(*drawObj); return pieceObj.m_pid == pid; }); - ASSERT(it != GetItemMap()->end()); - CDrawObj& drawObj = **it; - ASSERT(drawObj.GetType() == CDrawObj::drawPieceObj); - CPieceObj& pieceObj = static_cast(drawObj); + wxASSERT(it != GetItemMap()->end()); + const CDrawObj& drawObj = **it; + wxASSERT(drawObj.GetType() == CDrawObj::drawPieceObj); + const CPieceObj& pieceObj = static_cast(drawObj); size_t side = menuGameElement.GetSide(); m_pDoc->InvertPlayingPieceOnBoard(pieceObj, playBoard, CPieceTable::fSelect, side); diff --git a/GP/MoveMgr.cpp b/GP/MoveMgr.cpp index 8039f240..278d2102 100644 --- a/GP/MoveMgr.cpp +++ b/GP/MoveMgr.cpp @@ -1025,7 +1025,7 @@ void CObjectDelete::DoMove(CGamDoc& pDoc, int nMoveWithinGroup) const if (pPBoard != NULL) { - std::vector> list; + std::vector> list; list.push_back(pObj); pDoc.DeleteObjectsInTable(list); } diff --git a/GP/PalTray.cpp b/GP/PalTray.cpp index 6e0d0723..0ce8bc22 100644 --- a/GP/PalTray.cpp +++ b/GP/PalTray.cpp @@ -741,7 +741,7 @@ LRESULT CTrayPalette::OnDragItem(WPARAM wParam, LPARAM lParam) else // DRAG_SELECTLIST { ASSERT(pdi->GetDragType() == DRAG_SELECTLIST); - std::vector> m_listPtr; + std::vector> m_listPtr; CSelList* pSLst = pdi->GetSubInfo().m_selectList; pSLst->LoadTableWithObjectPtrs(m_listPtr, CSelList::otAll, FALSE); pSLst->PurgeList(FALSE); diff --git a/GP/SelOPlay.cpp b/GP/SelOPlay.cpp index 83f6cc70..6362a0f7 100644 --- a/GP/SelOPlay.cpp +++ b/GP/SelOPlay.cpp @@ -629,6 +629,14 @@ void CSelList::LoadTableWithObjectPtrs(std::vector>& pTb pDwg->ArrangeObjectPtrTableInDrawOrder(pTbl); } +void CSelList::LoadTableWithObjectPtrs(std::vector>& pTbl, ObjTypes objTypes, + BOOL bVisualOrder) +{ + std::vector> temp; + LoadTableWithObjectPtrs(temp, objTypes, bVisualOrder); + pTbl = ToRefPtr(temp); +} + BOOL CSelList::HasPieces() const { for (const_iterator pos = begin() ; pos != end() ; ++pos) diff --git a/GP/SelOPlay.h b/GP/SelOPlay.h index a642614d..33c6f4be 100644 --- a/GP/SelOPlay.h +++ b/GP/SelOPlay.h @@ -239,6 +239,8 @@ class CSelList : private std::list> enum ObjTypes { otInvalid, otPieces, otPiecesMarks, otAll }; void LoadTableWithObjectPtrs(std::vector>& pTbl, ObjTypes objTypes, BOOL bVisualOrder); + void LoadTableWithObjectPtrs(std::vector>& pTbl, ObjTypes objTypes, + BOOL bVisualOrder); void LoadTableWithPieceIDs(std::vector& pTbl, BOOL bVisualOrder = TRUE); // -------- // enum LoadFilter { LF_NOTOWNED, LF_OWNED, LF_BOTH }; diff --git a/GP/ToolPlay.cpp b/GP/ToolPlay.cpp index cab40fac..e779f73e 100644 --- a/GP/ToolPlay.cpp +++ b/GP/ToolPlay.cpp @@ -746,7 +746,7 @@ void CPPlotTool::OnLButtonDown(CPlayBoardView* pView, UINT nFlags, if (pntPrev == CPoint(-1, -1)) { // Draw a line for each piece to the opening location - std::vector> listObjs; + std::vector> listObjs; pView->GetSelectList()->LoadTableWithObjectPtrs(listObjs, CSelList::otAll, FALSE); for (auto pos = listObjs.begin() ; pos != listObjs.end() ; ++pos) { diff --git a/GP/VwPbrd.cpp b/GP/VwPbrd.cpp index 6560a604..a0d6ff15 100644 --- a/GP/VwPbrd.cpp +++ b/GP/VwPbrd.cpp @@ -231,10 +231,10 @@ void CPlayBoardView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint) } else if (lHint == HINT_UPDATEOBJLIST && ph->GetArgs().m_pPBoard == m_pPBoard) { - const std::vector>& pPtrList = CheckedDeref(ph->GetArgs().m_pPtrList); + const std::vector>& pPtrList = CheckedDeref(ph->GetArgs().m_pPtrList); for (size_t i = size_t(0); i < pPtrList.size(); ++i) { - CDrawObj& pDObj = *pPtrList[i]; + const CDrawObj& pDObj = *pPtrList[i]; CRect rct = pDObj.GetEnclosingRect(); // In board coords. InvalidateWorkspaceRect(&rct); } @@ -359,7 +359,7 @@ LRESULT CPlayBoardView::OnMessageWindowState(WPARAM wParam, LPARAM lParam) // Save the select list if (!m_selList.empty()) { - std::vector> tblObjPtrs; + std::vector> tblObjPtrs; m_selList.LoadTableWithObjectPtrs(tblObjPtrs, CSelList::otPiecesMarks, TRUE); ar << value_preserving_cast(tblObjPtrs.size()); for (size_t i = 0; i < tblObjPtrs.size(); i++) @@ -1228,7 +1228,7 @@ void CPlayBoardView::OnEditClear() if (AfxMessageBox(IDS_WARN_DELETEMARKERS, MB_YESNO | MB_ICONQUESTION) != IDYES) return; - std::vector> listPtr; + std::vector> listPtr; m_selList.LoadTableWithObjectPtrs(listPtr, CSelList::otAll, FALSE); m_selList.PurgeList(TRUE); // Purge selections GetDocument()->AssignNewMoveGroup(); @@ -1458,7 +1458,7 @@ void CPlayBoardView::OnActShuffleSelectedObjects() CPoint pntCenter(MidPnt(rct.left, rct.right), MidPnt(rct.top, rct.bottom)); - std::vector> tblObjs; + std::vector> tblObjs; m_selList.LoadTableWithObjectPtrs(tblObjs, CSelList::otPiecesMarks, TRUE); m_selList.PurgeList(TRUE); // Purge former selections @@ -1473,8 +1473,8 @@ void CPlayBoardView::OnActShuffleSelectedObjects() // Create a shuffled table of objects... std::vector> tblRandObjs; tblRandObjs.reserve(tblObjs.size()); - for (int i = 0; i < value_preserving_cast(tblObjs.size()); i++) - tblRandObjs.push_back(tblObjs[value_preserving_cast(pnIndices[i])]); + for (size_t i = size_t(0); i < tblObjs.size(); i++) + tblRandObjs.emplace_back(&*tblObjs[value_preserving_cast(pnIndices[i])]); pDoc->AssignNewMoveGroup(); diff --git a/GP/VwPbrd.h b/GP/VwPbrd.h index 51d17c82..cac70a60 100644 --- a/GP/VwPbrd.h +++ b/GP/VwPbrd.h @@ -155,7 +155,7 @@ class CPlayBoardView : public CScrollView BOOL m_bWheelRotation; // Indicates the type of rotation being done CPoint m_pntWheelMid; // The wheel rotation point std::vector m_tblCurAngles; // Original angles of pieces - std::vector> m_tblCurPieces; // Pieces being rotated + std::vector> m_tblCurPieces; // Pieces being rotated CUIntArray m_tblXMidPnt; // X coord of piece midpoint CUIntArray m_tblYMidPnt; // Y coord of piece midpoint diff --git a/GP/VwSelpce.h b/GP/VwSelpce.h index 2ffa8a39..7fec819e 100644 --- a/GP/VwSelpce.h +++ b/GP/VwSelpce.h @@ -49,7 +49,7 @@ class CSelectedPieceView : public CView CB::propagate_const m_pPBoard; // Board that contains selections CSelectListBox m_listSel; - std::vector> m_tblSel; + std::vector> m_tblSel; CToolTipCtrl m_toolTip; // Implementation diff --git a/GP/VwTbrd.cpp b/GP/VwTbrd.cpp index bb6b1242..ba54a880 100644 --- a/GP/VwTbrd.cpp +++ b/GP/VwTbrd.cpp @@ -112,10 +112,10 @@ void CTinyBoardView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint) else if (lHint == HINT_UPDATEOBJLIST && ph->GetArgs().m_pPBoard == m_pPBoard) { wxASSERT(!"untested code"); - const std::vector>& pPtrList = *ph->GetArgs().m_pPtrList; + const std::vector>& pPtrList = *ph->GetArgs().m_pPtrList; for (size_t i = size_t(0); i < pPtrList.size(); ++i) { - CDrawObj& pDObj = *pPtrList[i]; + const CDrawObj& pDObj = *pPtrList[i]; wxRect rct = CB::Convert(pDObj.GetEnclosingRect()); // In board coords. InvalidateWorkspaceRect(rct); } diff --git a/GShr/CyberBoard.h b/GShr/CyberBoard.h index 94aa775d..acfc75cb 100644 --- a/GShr/CyberBoard.h +++ b/GShr/CyberBoard.h @@ -2649,4 +2649,18 @@ namespace CB dc.DrawEllipse(temp); } } + +template +std::vector> ToRefPtr(const std::vector>& v) +{ + static_assert(!std::is_const_v); + std::vector> retval; + retval.reserve(v.size()); + for (size_t i = size_t(0) ; i < v.size() ; ++i) + { + // v[i] is not_null, so this is safe + retval.emplace_back(&*v[i]); + } + return retval; +} #endif diff --git a/GShr/DrawObj.cpp b/GShr/DrawObj.cpp index 2ca8bab4..8f36b592 100644 --- a/GShr/DrawObj.cpp +++ b/GShr/DrawObj.cpp @@ -2141,12 +2141,12 @@ void CDrawList::DrillDownHitTest(CPoint point, std::vector>& pLst) +void CDrawList::ArrangeObjectListInDrawOrder(std::vector>& pLst) { // Loop through the drawing list looking for objects that are // selected. Add them to a local list. When done, purge the caller's // list and transfer temp list to the callers list. - std::vector> tmpLst; + std::vector> tmpLst; for (iterator pos = begin() ; pos != end() ; ++pos) { @@ -2157,12 +2157,12 @@ void CDrawList::ArrangeObjectListInDrawOrder(std::vector pLst = std::move(tmpLst); } -void CDrawList::ArrangeObjectListInVisualOrder(std::vector>& pLst) +void CDrawList::ArrangeObjectListInVisualOrder(std::vector>& pLst) { // Loop backwards through the drawing list looking for objects that are // selected. Add them to a local list. When done, purge the caller's // list and transfer temp list to the callers list. - std::vector> tmpLst; + std::vector> tmpLst; for (reverse_iterator pos = rbegin() ; pos != rend() ; ++pos) { @@ -2229,12 +2229,12 @@ void CDrawList::ArrangePieceTableInVisualOrder(std::vector& pTbl) const pTbl = std::move(tmpTbl); } -void CDrawList::ArrangeObjectPtrTableInDrawOrder(std::vector>& pTbl) const +void CDrawList::ArrangeObjectPtrTableInDrawOrder(std::vector>& pTbl) const { // Loop through the drawing list looking for objects that are // selected. Add them to a local list. When done, purge the caller's // list and transfer temp list to the callers list. - std::vector> tmpTbl; + std::vector> tmpTbl; tmpTbl.reserve(pTbl.size()); for (const_iterator pos = begin(); pos != end(); ++pos) @@ -2244,7 +2244,7 @@ void CDrawList::ArrangeObjectPtrTableInDrawOrder(std::vector>& pTbl) const +void CDrawList::ArrangeObjectPtrTableInDrawOrder(std::vector>& pTbl) const +{ + std::vector> temp = ToRefPtr(pTbl); + ArrangeObjectPtrTableInDrawOrder(temp); + pTbl.clear(); + for (size_t i = size_t(0) ; i < temp.size() ; ++i) + { + pTbl.emplace_back(&*temp[i]); + } +} + +void CDrawList::ArrangeObjectPtrTableInVisualOrder(std::vector>& pTbl) const { // Loop through the drawing list looking for objects that are // selected. Add them to a local list. When done, purge the caller's // list and transfer temp list to the callers list. - std::vector> tmpTbl; + std::vector> tmpTbl; tmpTbl.reserve(pTbl.size()); for (const_reverse_iterator pos = rbegin(); pos != rend(); ++pos) @@ -2269,16 +2280,27 @@ void CDrawList::ArrangeObjectPtrTableInVisualOrder(std::vector>& pTbl) const +{ + std::vector> temp = ToRefPtr(pTbl); + ArrangeObjectPtrTableInVisualOrder(temp); + pTbl.clear(); + for (size_t i = size_t(0) ; i < temp.size() ; ++i) + { + pTbl.emplace_back(&*temp[i]); + } +} + #endif // GPLAY CDrawList::const_iterator CDrawList::Find(const CDrawObj& drawObj) const @@ -2292,11 +2314,11 @@ CDrawList::iterator CDrawList::Find(const CDrawObj& drawObj) } // NOTE: RemoveObject* do not erase -void CDrawList::RemoveObjectsInList(const std::vector>& pLst) +void CDrawList::RemoveObjectsInList(const std::vector>& pLst) { for (size_t i = size_t(0) ; i < pLst.size() ; ++i) { - CDrawObj& pDObj = *pLst[i]; + const CDrawObj& pDObj = *pLst[i]; RemoveObject(pDObj); } } diff --git a/GShr/DrawObj.h b/GShr/DrawObj.h index 10624cd3..8d85d43a 100644 --- a/GShr/DrawObj.h +++ b/GShr/DrawObj.h @@ -1104,7 +1104,7 @@ class CDrawList : private std::list iterator Find(const CDrawObj& drawObj); // NOTE: See WARNING: above void RemoveObject(const CDrawObj& pDrawObj); - void RemoveObjectsInList(const std::vector>& pLst); + void RemoveObjectsInList(const std::vector>& pLst); void AddToBack(CDrawObj::OwnerPtr pDrawObj) { push_front(std::move(pDrawObj)); } void AddToFront(CDrawObj::OwnerPtr pDrawObj) { push_back(std::move(pDrawObj)); } CDrawObj& Front() { return *back(); } @@ -1124,9 +1124,11 @@ class CDrawList : private std::list void ArrangePieceTableInDrawOrder(std::vector& pTbl) const; void ArrangePieceTableInVisualOrder(std::vector& pTbl) const; #endif - void ArrangeObjectListInDrawOrder(std::vector>& pLst); - void ArrangeObjectListInVisualOrder(std::vector>& pLst); + void ArrangeObjectListInDrawOrder(std::vector>& pLst); + void ArrangeObjectListInVisualOrder(std::vector>& pLst); + void ArrangeObjectPtrTableInDrawOrder(std::vector>& pTbl) const; void ArrangeObjectPtrTableInDrawOrder(std::vector>& pTbl) const; + void ArrangeObjectPtrTableInVisualOrder(std::vector>& pTbl) const; void ArrangeObjectPtrTableInVisualOrder(std::vector>& pTbl) const; #ifdef GPLAY void SetOwnerMasks(PlayerMask dwOwnerMask); diff --git a/GShr/LBoxGfx2.cpp b/GShr/LBoxGfx2.cpp index 29ca86df..a5699fa9 100644 --- a/GShr/LBoxGfx2.cpp +++ b/GShr/LBoxGfx2.cpp @@ -74,7 +74,7 @@ CGrafixListBox2::CGrafixListBox2() ///////////////////////////////////////////////////////////////////////////// -void CGrafixListBox2::SetItemMap(const std::vector>* pMap, +void CGrafixListBox2::SetItemMap(const std::vector>* pMap, BOOL bKeepPosition /* = TRUE */) { m_pItemMap = pMap; diff --git a/GShr/LBoxGfx2.h b/GShr/LBoxGfx2.h index 78e26236..2f2aa8c5 100644 --- a/GShr/LBoxGfx2.h +++ b/GShr/LBoxGfx2.h @@ -60,7 +60,7 @@ class CGrafixListBox2 : public CListBox void EnableDrag(BOOL bEnable = TRUE) { m_bAllowDrag = bEnable; } void EnableSelfDrop(BOOL bEnable = TRUE) { m_bAllowSelfDrop = bEnable; } void EnableDropScroll(BOOL bEnable = TRUE) { m_bAllowDropScroll = bEnable; } - const std::vector>* GetItemMap() const { return m_pItemMap; } + const std::vector>* GetItemMap() const { return m_pItemMap; } const CDrawObj& GetCurMapItem() const; std::vector> GetCurMappedItemList() const; BOOL IsMultiSelect() const @@ -76,7 +76,7 @@ class CGrafixListBox2 : public CListBox // Operations public: - void SetItemMap(const std::vector>* pMap, BOOL bKeepPosition = TRUE); + void SetItemMap(const std::vector>* pMap, BOOL bKeepPosition = TRUE); void UpdateList(BOOL bKeepPosition = TRUE); void SetCurSelMapped(const CDrawObj& pMapVal); void SetCurSelsMapped(const std::vector>& items); @@ -111,7 +111,7 @@ class CGrafixListBox2 : public CListBox protected: /* N.B.: this class could be templatized to hold any pointer, but that generality isn't actually needed yet */ - const std::vector>* m_pItemMap; // Maps index to item + const std::vector>* m_pItemMap; // Maps index to item std::vector> m_multiSelList; // Holds mapped multi select items on drop // Tool tip support From 3dc22aa98a78e5ddce5481840616f5a692a357ba Mon Sep 17 00:00:00 2001 From: Bill Su Date: Thu, 28 Aug 2025 00:03:44 -0400 Subject: [PATCH 25/80] LBoxGfx2: remove messages with no handlers --- GShr/LBoxGfx2.cpp | 19 ------------------- GShr/LBoxGfx2.h | 7 ------- 2 files changed, 26 deletions(-) diff --git a/GShr/LBoxGfx2.cpp b/GShr/LBoxGfx2.cpp index a5699fa9..17861b7f 100644 --- a/GShr/LBoxGfx2.cpp +++ b/GShr/LBoxGfx2.cpp @@ -370,25 +370,6 @@ void CGrafixListBox2::OnLButtonUp(UINT nFlags, CPoint point) #if defined(GPLAY) m_pDoc->AssignNewMoveGroup(); #endif - if (IsMultiSelect()) - { - CWnd *pWnd = GetParent(); - ASSERT(pWnd != NULL); - pWnd->SendMessage(WM_OVERRIDE_SELECTED_ITEM_LIST2, (WPARAM)&m_multiSelList); - } - else - { - ASSERT(!"unreachable code"); - ASSERT(!"what is m_dragType here?"); -#if 0 - // The parent may want to override the value. - int nValueOverride = di.m_dwVal; - CWnd *pWnd = GetParent(); - ASSERT(pWnd != NULL); - pWnd->SendMessage(WM_OVERRIDE_SELECTED_ITEM2, (WPARAM)&nValueOverride); - di.m_dwVal = nValueOverride; -#endif - } ReleaseCapture(); SetCursor(LoadCursor(NULL, IDC_ARROW)); diff --git a/GShr/LBoxGfx2.h b/GShr/LBoxGfx2.h index 2f2aa8c5..67c1cdcf 100644 --- a/GShr/LBoxGfx2.h +++ b/GShr/LBoxGfx2.h @@ -38,13 +38,6 @@ class CDrawObj; #define ID_TIP_LISTITEM_HIT 1 #define MAX_LISTITEM_TIP_WIDTH 200 // Max pixel width of tips -///////////////////////////////////////////////////////////////////////////// -// These messages are sent by the CGrafixListBox2 to its parent window. -// It allows the list's content to be overridden. It's primary use -// is to deliver a random selection of pieces or markers. -#define WM_OVERRIDE_SELECTED_ITEM2 (WM_USER + 502) // WPARAM = int* -#define WM_OVERRIDE_SELECTED_ITEM_LIST2 (WM_USER + 503) // WPARAM = CDWordArray* - ///////////////////////////////////////////////////////////////////////////// // Custom Listbox - containing colors From 0e845eac3430a5e70fcdebacd40c25f72d4dadf2 Mon Sep 17 00:00:00 2001 From: Bill Su Date: Sat, 30 Aug 2025 16:48:57 -0400 Subject: [PATCH 26/80] LBoxGfx2: mark unreachable code --- GShr/LBoxGfx2.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/GShr/LBoxGfx2.cpp b/GShr/LBoxGfx2.cpp index 17861b7f..dfb9c0ec 100644 --- a/GShr/LBoxGfx2.cpp +++ b/GShr/LBoxGfx2.cpp @@ -132,6 +132,7 @@ const CDrawObj& CGrafixListBox2::MapIndexToItem(size_t nIndex) const size_t CGrafixListBox2::MapItemToIndex(const CDrawObj& pItem) const { + wxASSERT(!"dead code?"); ASSERT(m_pItemMap); for (size_t i = 0; i < m_pItemMap->size(); i++) { @@ -143,6 +144,7 @@ size_t CGrafixListBox2::MapItemToIndex(const CDrawObj& pItem) const const CDrawObj& CGrafixListBox2::GetCurMapItem() const { + wxASSERT(!"dead code?"); ASSERT(!IsMultiSelect()); ASSERT(m_pItemMap); int nItem = GetCurSel(); @@ -168,6 +170,7 @@ std::vector> CGrafixListBox2::GetCurMappedItemList void CGrafixListBox2::SetCurSelMapped(const CDrawObj& nMapVal) { + wxASSERT(!"dead code?"); ASSERT(m_pItemMap); for (size_t i = 0; i < m_pItemMap->size(); i++) { @@ -181,6 +184,7 @@ void CGrafixListBox2::SetCurSelMapped(const CDrawObj& nMapVal) void CGrafixListBox2::SetCurSelsMapped(const std::vector>& items) { + wxASSERT(!"dead code?"); ASSERT(m_pItemMap); ASSERT(IsMultiSelect()); @@ -199,6 +203,7 @@ void CGrafixListBox2::SetCurSelsMapped(const std::vector void CGrafixListBox2::ShowFirstSelection() { + wxASSERT(!"dead code?"); int nTopSel = GetTopSelectedItem(); CRect rctLBoxClient; GetClientRect(&rctLBoxClient); @@ -210,6 +215,7 @@ void CGrafixListBox2::ShowFirstSelection() int CGrafixListBox2::GetTopSelectedItem() const { + wxASSERT(!"dead code?"); int nTopSel; if (IsMultiSelect()) { @@ -231,6 +237,7 @@ int CGrafixListBox2::GetTopSelectedItem() const void CGrafixListBox2::MakeItemVisible(int nItem) { + wxASSERT(!"dead code?"); CRect rctLBoxClient; GetClientRect(&rctLBoxClient); CRect rct; @@ -243,6 +250,7 @@ void CGrafixListBox2::MakeItemVisible(int nItem) void CGrafixListBox2::SetSelFromPoint(CPoint point) { + wxASSERT(!"dead code?"); // Short circuit drag processing m_bAllowDrag = FALSE; SendMessage(WM_LBUTTONDOWN, (WPARAM)MK_LBUTTON, @@ -475,6 +483,7 @@ void CGrafixListBox2::OnMouseMove(UINT nFlags, CPoint point) CWnd* CGrafixListBox2::GetWindowFromPoint(CPoint point) const { + wxASSERT(!"dead code?"); ClientToScreen(&point); CWnd* pWnd = WindowFromPoint(point); @@ -507,6 +516,7 @@ void CGrafixListBox2::DoInsertLineProcessing(const DragInfo& pdi) { if (m_bAllowDropScroll) { + wxASSERT(!"dead code"); // Handle drawing of insert line CPoint pnt = pdi.m_point; int nSel = SpecialItemFromPoint(pnt); @@ -533,6 +543,7 @@ void CGrafixListBox2::DoAutoScrollProcessing(const DragInfo& pdi) { if (m_bAllowDropScroll && m_nTimerID == uintptr_t(0)) { + wxASSERT(!"dead code"); CRect rct; GetClientRect(&rct); rct.InflateRect(0, -scrollZonePixels); @@ -550,6 +561,7 @@ void CGrafixListBox2::DoAutoScrollProcessing(const DragInfo& pdi) LRESULT CGrafixListBox2::OnDragItem(WPARAM wParam, LPARAM lParam) { + wxASSERT(!"dead code"); if (wParam != GetProcessId(GetCurrentProcess())) { return -1; @@ -571,6 +583,7 @@ void CGrafixListBox2::OnTimer(uintptr_t nIDEvent) if (nIDEvent != m_nTimerID) return; + wxASSERT(!"dead code"); CPoint point; CRect rctClient; CRect rct; @@ -634,6 +647,7 @@ void CGrafixListBox2::OnTimer(uintptr_t nIDEvent) int CGrafixListBox2::SpecialItemFromPoint(CPoint pnt) const { + wxASSERT(!"dead code"); BOOL bBucket; int nSel = (int)ItemFromPoint(pnt, bBucket); CRect rct; From 9116852f6c61678ed7a2cbbf93495b9eea5682a7 Mon Sep 17 00:00:00 2001 From: Bill Su Date: Sun, 31 Aug 2025 21:22:15 -0400 Subject: [PATCH 27/80] LBoxGfx2: prefer function return value to out-param --- GP/LBoxSlct.cpp | 10 ++++++---- GP/LBoxSlct.h | 2 +- GShr/LBoxGfx2.cpp | 2 +- GShr/LBoxGfx2.h | 2 +- 4 files changed, 9 insertions(+), 7 deletions(-) diff --git a/GP/LBoxSlct.cpp b/GP/LBoxSlct.cpp index d68b4d73..bce6cc3e 100644 --- a/GP/LBoxSlct.cpp +++ b/GP/LBoxSlct.cpp @@ -340,12 +340,14 @@ GameElement CSelectListBox::OnGetHitItemCodeAtPoint(GetGameElementCodeForObject_ return Invalid_v; } -void CSelectListBox::OnGetTipTextForItemCode(GameElement nItemCode, - CB::string& strTip) const +CB::string CSelectListBox::OnGetTipTextForItemCode(GameElement nItemCode) const { if (nItemCode == Invalid_v) - return; - strTip = m_pDoc->GetGameElementString(nItemCode); + { + wxASSERT(!"invalid gameelement"); + return CB::string(); + } + return m_pDoc->GetGameElementString(nItemCode); } ///////////////////////////////////////////////////////////////////////////// diff --git a/GP/LBoxSlct.h b/GP/LBoxSlct.h index 07ce9876..c21d84e1 100644 --- a/GP/LBoxSlct.h +++ b/GP/LBoxSlct.h @@ -85,7 +85,7 @@ class CSelectListBox : public CTileBaseListBox2 typedef GameElement (CGamDoc::*GetGameElementCodeForObject_t)(const CDrawObj& pDObj, size_t nSide) const; GameElement OnGetHitItemCodeAtPoint(GetGameElementCodeForObject_t func, CPoint point, CRect& rct) const; public: - virtual void OnGetTipTextForItemCode(GameElement nItemCode, CB::string& strTip) const override; + virtual CB::string OnGetTipTextForItemCode(GameElement nItemCode) const override; virtual BOOL OnDoesItemHaveTipText(size_t nItem) const override; //{{AFX_MSG(CSelectListBox) diff --git a/GShr/LBoxGfx2.cpp b/GShr/LBoxGfx2.cpp index dfb9c0ec..7aa964ed 100644 --- a/GShr/LBoxGfx2.cpp +++ b/GShr/LBoxGfx2.cpp @@ -287,7 +287,7 @@ void CGrafixListBox2::DoToolTipHitProcessing(CPoint point) CB::string strTip; // Call subclass for info - OnGetTipTextForItemCode(nItemCode, strTip); + strTip = OnGetTipTextForItemCode(nItemCode); if (!strTip.empty()) { diff --git a/GShr/LBoxGfx2.h b/GShr/LBoxGfx2.h index 67c1cdcf..be2f9a18 100644 --- a/GShr/LBoxGfx2.h +++ b/GShr/LBoxGfx2.h @@ -98,7 +98,7 @@ class CGrafixListBox2 : public CListBox // For tool tip processing virtual BOOL OnIsToolTipsEnabled() const /* override */ { return FALSE; } virtual GameElement OnGetHitItemCodeAtPoint(CPoint point, CRect& rct) const /* override */ { return Invalid_v; } - virtual void OnGetTipTextForItemCode(GameElement nItemCode, CB::string& strTip) const /* override */ { } + virtual CB::string OnGetTipTextForItemCode(GameElement nItemCode) const /* override */ { return CB::string(); } // Implementation protected: From e9c844f9f29770ad073a02d2d5bb1da1e7e5e2c5 Mon Sep 17 00:00:00 2001 From: Bill Su Date: Sun, 31 Aug 2025 17:31:26 -0400 Subject: [PATCH 28/80] LBoxSlct: improve const-correctness --- GP/GamDoc.cpp | 2 +- GP/GamDoc.h | 6 +++++- GP/LBoxSlct.cpp | 14 +++++++------- GP/LBoxSlct.h | 4 ++-- GP/VwSelpce.cpp | 2 +- GShr/DragDrop.h | 2 +- 6 files changed, 17 insertions(+), 13 deletions(-) diff --git a/GP/GamDoc.cpp b/GP/GamDoc.cpp index 137de940..c91b91fd 100644 --- a/GP/GamDoc.cpp +++ b/GP/GamDoc.cpp @@ -965,7 +965,7 @@ const CTileManager& CGamDoc::GetTileManager() const return CheckedDeref(CheckedDeref(m_pGbx).GetTileManager()); } -CMarkManager& CGamDoc::GetMarkManager() +const CMarkManager& CGamDoc::GetMarkManager() const { return CheckedDeref(CheckedDeref(m_pGbx).GetMarkManager()); } diff --git a/GP/GamDoc.h b/GP/GamDoc.h index 7c1350ea..7d40a932 100644 --- a/GP/GamDoc.h +++ b/GP/GamDoc.h @@ -316,7 +316,11 @@ class CGamDoc : public CDocument // Major game related objects... const CTileManager& GetTileManager() const; CTileManager& GetTileManager() { return const_cast(std::as_const(*this).GetTileManager()); } - CMarkManager& GetMarkManager(); + const CMarkManager& GetMarkManager() const; + CMarkManager& GetMarkManager() + { + return const_cast(std::as_const(*this).GetMarkManager()); + } const CBoardManager& GetBoardManager() const; CBoardManager& GetBoardManager() { diff --git a/GP/LBoxSlct.cpp b/GP/LBoxSlct.cpp index bce6cc3e..69f3a0e0 100644 --- a/GP/LBoxSlct.cpp +++ b/GP/LBoxSlct.cpp @@ -91,7 +91,7 @@ BOOL CSelectListBox::OnDragSetup(DragInfo& pDI) const pDI.SetDragType(DRAG_SELECTVIEW); pDI.GetSubInfo().m_ptrArray = &GetMappedMultiSelectList(); pDI.m_hcsrSuggest = g_res.hcrDragTile; - pDI.GetSubInfo().m_gamDoc = m_pDoc; + pDI.GetSubInfo().m_gamDoc = &*m_pDoc; return TRUE; } @@ -326,13 +326,13 @@ GameElement CSelectListBox::OnGetHitItemCodeAtPoint(GetGameElementCodeForObject_ if (pObj.GetType() == CDrawObj::drawPieceObj) { const CPieceObj& pieceObj = static_cast(pObj); - CPieceTable& pieceTbl = m_pDoc->GetPieceTable(); + const CPieceTable& pieceTbl = m_pDoc->GetPieceTable(); uint8_t side = pieceTbl.GetSide(pieceObj.m_pid, i); - return (m_pDoc->*func)(pieceObj, side); + return ((*m_pDoc).*func)(pieceObj, side); } else { - return (m_pDoc->*func)(pObj, Invalid_v); + return ((*m_pDoc).*func)(pObj, Invalid_v); } } } @@ -358,7 +358,7 @@ BOOL CSelectListBox::OnDoesItemHaveTipText(size_t nItem) const if (pDObj.GetType() == CDrawObj::drawPieceObj) { const CPieceObj& pObj = static_cast(pDObj); - CPieceTable& pieceTbl = m_pDoc->GetPieceTable(); + const CPieceTable& pieceTbl = m_pDoc->GetPieceTable(); size_t sides = pieceTbl.GetSides(pObj.m_pid); for (size_t i = size_t(0); i < sides; ++i) { @@ -426,7 +426,7 @@ std::vector CSelectListBox::GetTileIDs(size_t nIndex) const if (pDObj.GetType() == CDrawObj::drawPieceObj) { - CPieceTable& pPTbl = m_pDoc->GetPieceTable(); + const CPieceTable& pPTbl = m_pDoc->GetPieceTable(); PieceID pid = static_cast(pDObj).m_pid; @@ -460,7 +460,7 @@ std::vector CSelectListBox::GetTileIDs(size_t nIndex) const else if (pDObj.GetType() == CDrawObj::drawMarkObj) { MarkID mid = static_cast(pDObj).m_mid; - CMarkManager& pMMgr = m_pDoc->GetMarkManager(); + const CMarkManager& pMMgr = m_pDoc->GetMarkManager(); std::vector retval; retval.push_back(pMMgr.GetMark(mid).m_tid); return retval; diff --git a/GP/LBoxSlct.h b/GP/LBoxSlct.h index c21d84e1..225376e4 100644 --- a/GP/LBoxSlct.h +++ b/GP/LBoxSlct.h @@ -58,11 +58,11 @@ class CSelectListBox : public CTileBaseListBox2 // Operations public: - void SetDocument(CGamDoc* pDoc) { CTileBaseListBox2::SetDocument(CheckedDeref(pDoc)); m_pDoc = pDoc; } + void SetDocument(CGamDoc& pDoc) { CTileBaseListBox2::SetDocument(pDoc); m_pDoc = &pDoc; } // Implementation protected: - CGamDoc* m_pDoc; + CB::propagate_const m_pDoc; GameElement menuGameElement = Invalid_v; diff --git a/GP/VwSelpce.cpp b/GP/VwSelpce.cpp index 0e76a7a1..82016768 100644 --- a/GP/VwSelpce.cpp +++ b/GP/VwSelpce.cpp @@ -130,7 +130,7 @@ void CSelectedPieceView::OnInitialUpdate() { m_pPBoard = static_cast(GetDocument().GetNewViewParameter()); CView::OnInitialUpdate(); - m_listSel.SetDocument(&GetDocument()); + m_listSel.SetDocument(GetDocument()); } void CSelectedPieceView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint) diff --git a/GShr/DragDrop.h b/GShr/DragDrop.h index 9277139c..5a5b3807 100644 --- a/GShr/DragDrop.h +++ b/GShr/DragDrop.h @@ -174,7 +174,7 @@ struct DragInfo struct SubInfo { const std::vector>* m_ptrArray; - CGamDoc* m_gamDoc; + const CGamDoc* m_gamDoc; }; // TODO: when upgrade to c++ 17, use std::variant private: From 718677923da3a7aeae73b34a0fe150e3377c879c Mon Sep 17 00:00:00 2001 From: Bill Su Date: Sat, 30 Aug 2025 20:50:41 -0400 Subject: [PATCH 29/80] LBoxGfx2/LBoxTileBase2/LBoxSlct: prepare to convert LBoxGfx2 to wx --- GP/LBoxSlct.cpp | 439 ++++++++++++++++++++++++++ GP/LBoxSlct.h | 68 +++- GP/VwSelpce.h | 2 +- GShr/LBoxGfx2.cpp | 685 ++++++++++++++++++++++++++++++++++++++++- GShr/LBoxGfx2.h | 118 ++++++- GShr/LBoxTileBase2.cpp | 227 +++++++++++++- GShr/LBoxTileBase2.h | 55 +++- 7 files changed, 1588 insertions(+), 6 deletions(-) diff --git a/GP/LBoxSlct.cpp b/GP/LBoxSlct.cpp index 69f3a0e0..19f16037 100644 --- a/GP/LBoxSlct.cpp +++ b/GP/LBoxSlct.cpp @@ -42,6 +42,7 @@ const int tileBorder = 3; const int tileGap = 6; +#if 0 ///////////////////////////////////////////////////////////////////////////// BEGIN_MESSAGE_MAP(CSelectListBox, CTileBaseListBox2) @@ -479,3 +480,441 @@ const CPlayBoardView& CSelectListBox::GetBoardView() const return pbrdFrame.GetActiveBoardView(); } +#endif +///////////////////////////////////////////////////////////////////////////// + +BEGIN_MESSAGE_MAP(CSelectListBoxMfc, CTileBaseListBox2Mfc) + //{{AFX_MSG_MAP(CSelectListBox) + ON_REGISTERED_MESSAGE(WM_DRAGDROP, OnDragItem) + ON_WM_CONTEXTMENU() + ON_WM_INITMENUPOPUP() + ON_COMMAND_EX(ID_ACT_TURNOVER, OnActTurnOver) + ON_COMMAND_EX(ID_ACT_TURNOVER_PREV, OnActTurnOver) + ON_COMMAND_EX(ID_ACT_TURNOVER_RANDOM, OnActTurnOver) + ON_COMMAND_EX(ID_ACT_TURNOVER_SELECT, OnActTurnOver) + ON_UPDATE_COMMAND_UI(ID_ACT_TURNOVER, OnUpdateActTurnOver) + ON_UPDATE_COMMAND_UI(ID_ACT_TURNOVER_PREV, OnUpdateActTurnOver) + ON_UPDATE_COMMAND_UI(ID_ACT_TURNOVER_RANDOM, OnUpdateActTurnOver) + ON_UPDATE_COMMAND_UI(ID_ACT_TURNOVER_SELECT, OnUpdateActTurnOver) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// + +const CTileManager& CSelectListBoxMfc::GetTileManager() const +{ + ASSERT(m_pDoc != NULL); + return m_pDoc->GetTileManager(); +} + +///////////////////////////////////////////////////////////////////////////// + +BOOL CSelectListBoxMfc::OnDragSetup(DragInfo& pDI) const +{ + ASSERT(!"untested code"); + if (GetCount() <= 1) + { + pDI.SetDragType(DRAG_INVALID); + return FALSE; + } + + if (!IsMultiSelect()) + { + ASSERT(!"unreachable code"); + /* if this ever happens, rewrite like LBoxGrfx w/ + list/single distinction + m_multiSelList.clear(); + m_multiSelList.push_back(&GetCurMapItem()); + */ + } + pDI.SetDragType(DRAG_SELECTVIEW); + pDI.GetSubInfo().m_ptrArray = &GetMappedMultiSelectList(); + pDI.m_hcsrSuggest = g_res.hcrDragTile; + pDI.GetSubInfo().m_gamDoc = &*m_pDoc; + return TRUE; +} + +LRESULT CSelectListBoxMfc::OnDragItem(WPARAM wParam, LPARAM lParam) +{ + if (wParam != GetProcessId(GetCurrentProcess())) + { + return -1; + } + const DragInfo& pdi = CheckedDeref(reinterpret_cast(lParam)); + + DoInsertLineProcessing(pdi); + + if (pdi.GetDragType() != DRAG_SELECTVIEW) + return -1; // Only our drops allowed + + ASSERT(!"untested code"); + if (pdi.GetSubInfo().m_gamDoc != m_pDoc) + return -1; // Only pieces from our document. + + // no size restriction + + DoAutoScrollProcessing(pdi); + + if (pdi.m_phase == PhaseDrag::Over) + return (LRESULT)(LPVOID)pdi.m_hcsrSuggest; + else if (pdi.m_phase == PhaseDrag::Drop) + { + int nSel = SpecialItemFromPoint(pdi.m_point); + + if (nSel < GetCount()) + { + // If the selection is out of view, force it into view. + MakeItemVisible(nSel); + } + } + return 1; +} + +void CSelectListBoxMfc::OnContextMenu(CWnd* /*pWnd*/, CPoint point) +{ + // remember clicked side in case of ID_ACT_TURNOVER_SELECT + CPoint clientPoint(point); + ScreenToClient(&clientPoint); + CRect rect; + menuGameElement = OnGetHitItemCodeAtPoint(&CGamDoc::GetGameElementCodeForObject, clientPoint, rect); + + CMenu bar; + if (bar.LoadMenuW(IDR_MENU_PLAYER_POPUPS)) + { + CMenu& popup = *bar.GetSubMenu(MENU_PV_SELCT_BOX); + ASSERT(popup.m_hMenu != NULL); + + // Make sure we clean up even if exception is tossed. + TRY + { + popup.TrackPopupMenu(TPM_LEFTBUTTON | + TPM_LEFTALIGN | + TPM_RIGHTBUTTON, + point.x, point.y, this); // Route commands through tray window + } + END_TRY + } + else + { + ASSERT(!"LoadMenu error"); + } +} + +void CSelectListBoxMfc::OnInitMenuPopup(CMenu* pMenu, UINT /*nIndex*/, BOOL bSysMenu) +{ + // based on CFrameWnd::OnInitMenuPopup() + ASSERT(!bSysMenu); + + CCmdUI state; + state.m_pMenu = pMenu; + ASSERT(state.m_pOther == NULL); + ASSERT(state.m_pParentMenu == NULL); + + state.m_nIndexMax = pMenu->GetMenuItemCount(); + for (state.m_nIndex = 0; state.m_nIndex < state.m_nIndexMax; + state.m_nIndex++) + { + state.m_nID = pMenu->GetMenuItemID(state.m_nIndex); + if (state.m_nID == 0) + continue; // menu separator or invalid cmd - ignore it + + ASSERT(state.m_pOther == NULL); + ASSERT(state.m_pMenu != NULL); + if (state.m_nID == (UINT)-1) + { + // possibly a popup menu, route to first item of that popup + state.m_pSubMenu = pMenu->GetSubMenu(state.m_nIndex); + if (state.m_pSubMenu == NULL || + (state.m_nID = state.m_pSubMenu->GetMenuItemID(0)) == 0 || + state.m_nID == (UINT)-1) + { + continue; // first item of popup can't be routed to + } + state.DoUpdate(this, FALSE); // popups are never auto disabled + } + else + { + // normal menu item + // Auto enable/disable if frame window has 'm_bAutoMenuEnable' + // set and command is _not_ a system command. + state.m_pSubMenu = NULL; + state.DoUpdate(this, true); + } + + // adjust for menu deletions and additions + UINT nCount = pMenu->GetMenuItemCount(); + if (nCount < state.m_nIndexMax) + { + state.m_nIndex -= (state.m_nIndexMax - nCount); + while (state.m_nIndex < nCount && + pMenu->GetMenuItemID(state.m_nIndex) == state.m_nID) + { + state.m_nIndex++; + } + } + state.m_nIndexMax = nCount; + } +} + +BOOL CSelectListBoxMfc::OnActTurnOver(UINT id) +{ + CPlayBoardView& view = GetBoardView(); + switch (id) + { + case ID_ACT_TURNOVER: + case ID_ACT_TURNOVER_PREV: + case ID_ACT_TURNOVER_RANDOM: + { + bool b = view.OnCmdMsg(id, CN_COMMAND, nullptr, nullptr); + ASSERT(b); + return b; + } + case ID_ACT_TURNOVER_SELECT: + { + const CPlayBoard& playBoard = CheckedDeref(view.GetPlayBoard()); + + m_pDoc->AssignNewMoveGroup(); + + PieceID pid = static_cast(menuGameElement); + auto it = std::find_if(GetItemMap()->begin(), + GetItemMap()->end(), + [pid](const RefPtr& drawObj) + { + if (drawObj->GetType() != CDrawObj::drawPieceObj) + { + return false; + } + const CPieceObj& pieceObj = static_cast(*drawObj); + return pieceObj.m_pid == pid; + }); + wxASSERT(it != GetItemMap()->end()); + const CDrawObj& drawObj = **it; + wxASSERT(drawObj.GetType() == CDrawObj::drawPieceObj); + const CPieceObj& pieceObj = static_cast(drawObj); + size_t side = menuGameElement.GetSide(); + m_pDoc->InvertPlayingPieceOnBoard(pieceObj, playBoard, CPieceTable::fSelect, side); + + return true; + } + default: + AfxThrowInvalidArgException(); + } +} + +void CSelectListBoxMfc::OnUpdateActTurnOver(CCmdUI* pCmdUI) +{ + switch (pCmdUI->m_nID) + { + case ID_ACT_TURNOVER: + case ID_ACT_TURNOVER_PREV: + case ID_ACT_TURNOVER_RANDOM: + pCmdUI->DoUpdate(&GetBoardView(), TRUE); + break; + case ID_ACT_TURNOVER_SELECT: + { + bool enable = menuGameElement != Invalid_v && + menuGameElement.IsAPiece(); + pCmdUI->Enable(enable); + if (pCmdUI->m_pSubMenu != NULL) + { + // Need to handle menu that the submenu is connected to. + pCmdUI->m_pMenu->EnableMenuItem(pCmdUI->m_nIndex, + MF_BYPOSITION | (enable ? MF_ENABLED : (MF_DISABLED | MF_GRAYED))); + } + break; + } + default: + AfxThrowInvalidArgException(); + } +} + +///////////////////////////////////////////////////////////////////////////// +// Tool tip processing + +BOOL CSelectListBoxMfc::OnIsToolTipsEnabled() const +{ + return m_pDoc->IsShowingObjectTips(); +} + +GameElement CSelectListBoxMfc::OnGetHitItemCodeAtPoint(CPoint point, CRect& rct) const +{ + return OnGetHitItemCodeAtPoint(&CGamDoc::GetVerifiedGameElementCodeForObject, point, rct); +} + +GameElement CSelectListBoxMfc::OnGetHitItemCodeAtPoint(GetGameElementCodeForObject_t func, CPoint point, CRect& rct) const +{ + point = ClientToItem(point); + + BOOL bOutsideClient; + UINT nIndex = ItemFromPoint(point, bOutsideClient); + if (nIndex >= 65535 || GetCount() <= 0) + return Invalid_v; + + std::vector tids = GetTileIDs(nIndex); + ASSERT(!tids.empty() && tids[size_t(0)] != nullTid); + + std::vector rcts = GetTileRectsForItem(value_preserving_cast(nIndex), tids); + + for (size_t i = size_t(0); i < rcts.size(); ++i) + { + ASSERT(!rcts[i].IsRectEmpty()); + if (rcts[i].PtInRect(point)) + { + rct = ItemToClient(rcts[i]); + const CDrawObj& pObj = MapIndexToItem(nIndex); + if (pObj.GetType() == CDrawObj::drawPieceObj) + { + const CPieceObj& pieceObj = static_cast(pObj); + const CPieceTable& pieceTbl = m_pDoc->GetPieceTable(); + uint8_t side = pieceTbl.GetSide(pieceObj.m_pid, i); + return ((*m_pDoc).*func)(pieceObj, side); + } + else + { + return ((*m_pDoc).*func)(pObj, Invalid_v); + } + } + } + + return Invalid_v; +} + +CB::string CSelectListBoxMfc::OnGetTipTextForItemCode(GameElement nItemCode) const +{ + if (nItemCode == Invalid_v) + { + wxASSERT(!"invalid gameelement"); + return CB::string(); + } + return m_pDoc->GetGameElementString(nItemCode); +} + +///////////////////////////////////////////////////////////////////////////// + +BOOL CSelectListBoxMfc::OnDoesItemHaveTipText(size_t nItem) const +{ + const CDrawObj& pDObj = MapIndexToItem(nItem); + if (pDObj.GetType() == CDrawObj::drawPieceObj) + { + const CPieceObj& pObj = static_cast(pDObj); + const CPieceTable& pieceTbl = m_pDoc->GetPieceTable(); + size_t sides = pieceTbl.GetSides(pObj.m_pid); + for (size_t i = size_t(0); i < sides; ++i) + { + GameElement elem = m_pDoc->GetVerifiedGameElementCodeForObject(pObj, i); + if (elem != Invalid_v) + { + return true; + } + } + return false; + } + else + { + GameElement elem = m_pDoc->GetVerifiedGameElementCodeForObject(pDObj); + return elem != Invalid_v; + } +} + +///////////////////////////////////////////////////////////////////////////// + +CB::string CSelectListBoxMfc::OnGetItemDebugString(size_t nIndex) const +{ + const CDrawObj& pDObj = MapIndexToItem(nIndex); + if (pDObj.GetType() == CDrawObj::drawPieceObj) + { + PieceID pid = static_cast(pDObj).m_pid; + return std::format(L"[pid:{}] ", pid); + } + else if (pDObj.GetType() == CDrawObj::drawMarkObj) + { + MarkID mid = static_cast(pDObj).m_mid; + return std::format(L"[mid:{}] ", mid); + } + return CB::string(); +} + +///////////////////////////////////////////////////////////////////////////// + +CSize CSelectListBoxMfc::OnItemSize(size_t nIndex) const +{ + ASSERT(m_pDoc != NULL); + + std::vector tids = GetTileIDs(nIndex); + ASSERT(!tids.empty() && tids[size_t(0)] != nullTid); + + return DoOnItemSize(nIndex, tids); +} + +void CSelectListBoxMfc::OnItemDraw(CDC& pDC, size_t nIndex, UINT nAction, UINT nState, + CRect rctItem) const +{ + // see https://docs.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-drawitemstruct + if (nIndex == UINT(-1)) + return; // Nothing to draw. + + std::vector tids = GetTileIDs(nIndex); + ASSERT(!tids.empty() && tids[size_t(0)] != nullTid); + DoOnDrawItem(pDC, nIndex, nAction, nState, rctItem, tids); +} + +// retval[0] is active face, followed by inactives +std::vector CSelectListBoxMfc::GetTileIDs(size_t nIndex) const +{ + const CDrawObj& pDObj = MapIndexToItem(nIndex); + + if (pDObj.GetType() == CDrawObj::drawPieceObj) + { + const CPieceTable& pPTbl = m_pDoc->GetPieceTable(); + + PieceID pid = static_cast(pDObj).m_pid; + + if (!m_pDoc->IsScenario() && pPTbl.IsPieceOwned(pid) && + !pPTbl.IsPieceOwnedBy(pid, m_pDoc->GetCurrentPlayerMask())) + { + std::vector retval; + retval.push_back(pPTbl.GetFrontTileID(pid)); + return retval; + } + + const PieceDef& pPce = m_pDoc->GetPieceManager().GetPiece(pid); + + std::vector retval; + if ((pPce.m_flags & PieceDef::flagShowOnlyVisibleSide) && + (!pPTbl.IsPieceOwnedBy(pid, m_pDoc->GetCurrentPlayerMask()) || + pPce.m_flags & PieceDef::flagShowOnlyOwnersToo)) + { + retval.push_back(pPTbl.GetActiveTileID(pid)); + } + else + { + retval.reserve(pPTbl.GetSides(pid)); + retval.push_back(pPTbl.GetActiveTileID(pid)); + std::vector inactives = pPTbl.GetInactiveTileIDs(pid); + retval.insert(retval.end(), inactives.begin(), inactives.end()); + } + return retval; + + } + else if (pDObj.GetType() == CDrawObj::drawMarkObj) + { + MarkID mid = static_cast(pDObj).m_mid; + const CMarkManager& pMMgr = m_pDoc->GetMarkManager(); + std::vector retval; + retval.push_back(pMMgr.GetMark(mid).m_tid); + return retval; + } + else + { + ASSERT(FALSE); // Shouldn't happen + return std::vector(); + } +} + +const CPlayBoardView& CSelectListBoxMfc::GetBoardView() const +{ + CFrameWnd& frame = CheckedDeref(AFXGetParentFrame(this)); + const CPlayBoardFrame& pbrdFrame = CheckedDeref(DYNAMIC_DOWNCAST(CPlayBoardFrame, &frame)); + return pbrdFrame.GetActiveBoardView(); +} + diff --git a/GP/LBoxSlct.h b/GP/LBoxSlct.h index 225376e4..212f8795 100644 --- a/GP/LBoxSlct.h +++ b/GP/LBoxSlct.h @@ -1,6 +1,6 @@ // LBoxSlct.h // -// Copyright (c) 1994-2020 By Dale L. Larson, All Rights Reserved. +// Copyright (c) 1994-2025 By Dale L. Larson & William Su, All Rights Reserved. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the @@ -41,6 +41,7 @@ class CGamDoc; +#if 0 ///////////////////////////////////////////////////////////////////////////// class CSelectListBox : public CTileBaseListBox2 @@ -106,4 +107,69 @@ class CSelectListBox : public CTileBaseListBox2 }; #endif +///////////////////////////////////////////////////////////////////////////// + +class CSelectListBoxMfc : public CTileBaseListBox2Mfc +{ +// Construction +public: + CSelectListBoxMfc() + { + m_pDoc = NULL; + } + +// Attributes +public: + virtual const CTileManager& GetTileManager() const override; + +// Operations +public: + void SetDocument(CGamDoc& pDoc) { CTileBaseListBox2Mfc::SetDocument(pDoc); m_pDoc = &pDoc; } + +// Implementation +protected: + CB::propagate_const m_pDoc; + + GameElement menuGameElement = Invalid_v; + + // Misc + // retval[0] is active face, followed by inactives + std::vector GetTileIDs(size_t nIndex) const; + + // Overrides + virtual CSize OnItemSize(size_t nIndex) const override; + virtual void OnItemDraw(CDC& pDC, size_t nIndex, UINT nAction, UINT nState, + CRect rctItem) const override; + virtual BOOL OnDragSetup(DragInfo& pDI) const override; + + virtual CB::string OnGetItemDebugString(size_t nItem) const override; + + // Tool tip processing + virtual BOOL OnIsToolTipsEnabled() const override; + virtual GameElement OnGetHitItemCodeAtPoint(CPoint point, CRect& rct) const override; +private: + typedef GameElement (CGamDoc::*GetGameElementCodeForObject_t)(const CDrawObj& pDObj, size_t nSide) const; + GameElement OnGetHitItemCodeAtPoint(GetGameElementCodeForObject_t func, CPoint point, CRect& rct) const; +public: + virtual CB::string OnGetTipTextForItemCode(GameElement nItemCode) const override; + virtual BOOL OnDoesItemHaveTipText(size_t nItem) const override; + + //{{AFX_MSG(CSelectListBox) + afx_msg LRESULT OnDragItem(WPARAM wParam, LPARAM lParam); + afx_msg void OnContextMenu(CWnd* pWnd, CPoint point); + afx_msg void OnInitMenuPopup(CMenu* pPopupMenu, UINT nIndex, BOOL bSysMenu); + afx_msg BOOL OnActTurnOver(UINT id); + afx_msg void OnUpdateActTurnOver(CCmdUI* pCmdUI); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() + +private: + const CPlayBoardView& GetBoardView() const; + CPlayBoardView& GetBoardView() + { + return const_cast(std::as_const(*this).GetBoardView()); + } +}; + +#endif diff --git a/GP/VwSelpce.h b/GP/VwSelpce.h index 7fec819e..c3eecdf9 100644 --- a/GP/VwSelpce.h +++ b/GP/VwSelpce.h @@ -48,7 +48,7 @@ class CSelectedPieceView : public CView protected: CB::propagate_const m_pPBoard; // Board that contains selections - CSelectListBox m_listSel; + CSelectListBoxMfc m_listSel; std::vector> m_tblSel; CToolTipCtrl m_toolTip; diff --git a/GShr/LBoxGfx2.cpp b/GShr/LBoxGfx2.cpp index 7aa964ed..9e1c236e 100644 --- a/GShr/LBoxGfx2.cpp +++ b/GShr/LBoxGfx2.cpp @@ -1,6 +1,6 @@ // LBoxGfx2.cpp // -// Copyright (c) 1994-2023 By Dale L. Larson & William Su, All Rights Reserved. +// Copyright (c) 1994-2025 By Dale L. Larson & William Su, All Rights Reserved. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the @@ -47,6 +47,7 @@ const int timerScroll = 125; const uintptr_t timerScrollIDStart = 900; const int timerScrollID = 901; +#if 0 ///////////////////////////////////////////////////////////////////////////// BEGIN_MESSAGE_MAP(CGrafixListBox2, CListBox) @@ -728,3 +729,685 @@ CRect CGrafixListBox2::ItemToClient(CRect rect) const return rect; } +#endif +///////////////////////////////////////////////////////////////////////////// + +BEGIN_MESSAGE_MAP(CGrafixListBox2Mfc, CListBox) + //{{AFX_MSG_MAP(CGrafixListBox2) + ON_WM_LBUTTONDOWN() + ON_WM_MOUSEMOVE() + ON_WM_LBUTTONUP() + ON_WM_TIMER() + ON_WM_CREATE() + ON_REGISTERED_MESSAGE(WM_DRAGDROP, OnDragItem) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// + +CGrafixListBox2Mfc::CGrafixListBox2Mfc() +{ + m_nLastInsert = -1; + m_nTimerID = uintptr_t(0); + m_bAllowDrag = FALSE; + m_bAllowSelfDrop = FALSE; + m_bAllowDropScroll = FALSE; + m_pItemMap = NULL; +} + +///////////////////////////////////////////////////////////////////////////// + +void CGrafixListBox2Mfc::SetItemMap(const std::vector>* pMap, + BOOL bKeepPosition /* = TRUE */) +{ + m_pItemMap = pMap; + UpdateList(bKeepPosition); +} + +// bKeepPosition == TRUE means current selection is maintained. +void CGrafixListBox2Mfc::UpdateList(BOOL bKeepPosition /* = TRUE */) +{ + if (m_pItemMap == NULL) + { + ResetContent(); + return; + } + int nCurSel = GetCurSel(); + int nTopIdx = GetTopIndex(); + int nFcsIdx = GetCaretIndex(); + int horzScroll = GetScrollPos(SB_HORZ); + SetRedraw(FALSE); + ResetContent(); + + LONG width = 0; + int nItem; + for (nItem = 0; nItem < value_preserving_cast(m_pItemMap->size()); nItem++) + { + AddString(" "_cbstring); // Fill with dummy data + width = CB::max(width, OnItemSize(value_preserving_cast(nItem)).cx); + } + SetHorizontalExtent(value_preserving_cast(width)); + if (bKeepPosition) + { + if (nTopIdx >= 0) + SetTopIndex(CB::min(nTopIdx, nItem - 1)); + if (nFcsIdx >= 0) + SetCaretIndex(CB::min(nFcsIdx, nItem - 1), FALSE); + if (nCurSel >= 0) + SetCurSel(CB::min(nCurSel, nItem - 1)); + } + SetRedraw(TRUE); + if (bKeepPosition) + { + SendMessage(WM_HSCROLL, MAKELONG(int16_t(SB_THUMBPOSITION), value_preserving_cast(horzScroll)), NULL); + } + Invalidate(); +} + +///////////////////////////////////////////////////////////////////////////// + +const CDrawObj& CGrafixListBox2Mfc::MapIndexToItem(size_t nIndex) const +{ + ASSERT(m_pItemMap); + ASSERT(nIndex < m_pItemMap->size()); + return *m_pItemMap->at(nIndex); +} + +size_t CGrafixListBox2Mfc::MapItemToIndex(const CDrawObj& pItem) const +{ + wxASSERT(!"dead code?"); + ASSERT(m_pItemMap); + for (size_t i = size_t(0); i < m_pItemMap->size(); i++) + { + if (&pItem == m_pItemMap->at(i)) + return i; + } + return Invalid_v; // Failed to find it +} + +const CDrawObj& CGrafixListBox2Mfc::GetCurMapItem() const +{ + wxASSERT(!"dead code?"); + ASSERT(!IsMultiSelect()); + ASSERT(m_pItemMap); + int nItem = GetCurSel(); + ASSERT(nItem >= 0); + ASSERT(value_preserving_cast(nItem) < m_pItemMap->size()); + return *m_pItemMap->at(value_preserving_cast(nItem)); +} + +std::vector> CGrafixListBox2Mfc::GetCurMappedItemList() const +{ + std::vector> pLst; + ASSERT(IsMultiSelect()); + int nSels = GetSelCount(); + if (nSels == LB_ERR || nSels == 0) + return pLst; + std::vector pSelTbl(value_preserving_cast(nSels)); + GetSelItems(nSels, pSelTbl.data()); + pLst.reserve(pSelTbl.size()); + for (size_t i = size_t(0); i < pSelTbl.size(); i++) + pLst.push_back(&MapIndexToItem(value_preserving_cast(pSelTbl[i]))); + return pLst; +} + +void CGrafixListBox2Mfc::SetCurSelMapped(const CDrawObj& nMapVal) +{ + wxASSERT(!"dead code?"); + ASSERT(m_pItemMap); + for (size_t i = size_t(0); i < m_pItemMap->size(); i++) + { + if (m_pItemMap->at(i) == &nMapVal) + { + SetCurSel(value_preserving_cast(i)); + SetTopIndex(value_preserving_cast(i)); + } + } +} + +void CGrafixListBox2Mfc::SetCurSelsMapped(const std::vector>& items) +{ + wxASSERT(!"dead code?"); + ASSERT(m_pItemMap); + ASSERT(IsMultiSelect()); + + SetSel(-1, FALSE); // Deselect all + for (size_t i = size_t(0); i < items.size(); i++) + { + for (size_t j = size_t(0); j < m_pItemMap->size(); j++) + { + if (m_pItemMap->at(j) == items[i]) + SetSel(value_preserving_cast(j)); + } + } +} + +///////////////////////////////////////////////////////////////////////////// + +void CGrafixListBox2Mfc::ShowFirstSelection() +{ + wxASSERT(!"dead code?"); + int nTopSel = GetTopSelectedItem(); + CRect rctLBoxClient; + GetClientRect(&rctLBoxClient); + CRect rct; + GetItemRect(nTopSel, &rct); + if (!rct.IntersectRect(rct, rctLBoxClient)) + SetTopIndex(nTopSel); +} + +int CGrafixListBox2Mfc::GetTopSelectedItem() const +{ + wxASSERT(!"dead code?"); + int nTopSel; + if (IsMultiSelect()) + { + if (GetSelCount() == 0) + return LB_ERR; + VERIFY(GetSelItems(1, &nTopSel)); + } + else + { + nTopSel = GetCurSel(); + if (nTopSel == LB_ERR) + return LB_ERR; + } + return nTopSel; +} + +///////////////////////////////////////////////////////////////////////////// +// If the selection is out of view, force it into view. + +void CGrafixListBox2Mfc::MakeItemVisible(int nItem) +{ + wxASSERT(!"dead code?"); + CRect rctLBoxClient; + GetClientRect(&rctLBoxClient); + CRect rct; + GetItemRect(nItem, &rct); + if (!rct.IntersectRect(rct, rctLBoxClient)) + SetTopIndex(nItem); +} + +///////////////////////////////////////////////////////////////////////////// + +void CGrafixListBox2Mfc::SetSelFromPoint(CPoint point) +{ + wxASSERT(!"dead code?"); + // Short circuit drag processing + m_bAllowDrag = FALSE; + SendMessage(WM_LBUTTONDOWN, (WPARAM)MK_LBUTTON, + MAKELPARAM(static_cast(point.x), static_cast(point.y))); + SendMessage(WM_LBUTTONUP, (WPARAM)MK_LBUTTON, + MAKELPARAM(static_cast(point.x), static_cast(point.y))); + m_bAllowDrag = TRUE; +} + +///////////////////////////////////////////////////////////////////////////// + +void CGrafixListBox2Mfc::DoToolTipHitProcessing(CPoint point) +{ + if (!OnIsToolTipsEnabled()) + return; + + if (m_toolTip.m_hWnd == NULL) + { + m_toolTip.Create(this, TTS_ALWAYSTIP | TTS_BALLOON | TTS_NOPREFIX); + m_toolTip.SetMaxTipWidth(MAX_LISTITEM_TIP_WIDTH); + } + + CRect rctTool; + GameElement nItemCode = OnGetHitItemCodeAtPoint(point, rctTool); + + if (nItemCode != m_nCurItemCode) + { + // Object changed so delete previous tool definition + m_toolTip.DelTool(this, ID_TIP_LISTITEM_HIT); + m_nCurItemCode = nItemCode; + if (nItemCode != Invalid_v) + { + // New object found so create a new tip + CB::string strTip; + + // Call subclass for info + strTip = OnGetTipTextForItemCode(nItemCode); + + if (!strTip.empty()) + { + m_toolTip.AddTool(this, strTip, rctTool, ID_TIP_LISTITEM_HIT); + m_toolTip.Activate(TRUE); + } + } + else + m_toolTip.Activate(FALSE); + } +} + +LRESULT CGrafixListBox2Mfc::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) +{ + if (m_toolTip.m_hWnd != NULL && message >= WM_MOUSEFIRST && + message <= WM_MOUSELAST) + { + MSG msg; + memset(&msg, 0, sizeof(MSG)); + msg.hwnd = m_hWnd; + msg.message = message; + msg.wParam = wParam; + msg.lParam = lParam; + + m_toolTip.RelayEvent(&msg); + } + return CListBox::WindowProc(message, wParam, lParam); +} + +///////////////////////////////////////////////////////////////////////////// + +void CGrafixListBox2Mfc::MeasureItem(LPMEASUREITEMSTRUCT lpMIS) +{ + unsigned nHt = value_preserving_cast(OnItemSize(lpMIS->itemID).cy); + + if (nHt >= unsigned(256)) nHt = unsigned(255); + if (nHt == unsigned(0)) nHt = defaultItemHeight; + + lpMIS->itemHeight = value_preserving_cast(nHt); +} + +void CGrafixListBox2Mfc::DrawItem(LPDRAWITEMSTRUCT lpDIS) +{ + size_t nIndex = lpDIS->itemID; + CDC* pDC = CDC::FromHandle(lpDIS->hDC); + + CRect rct(lpDIS->rcItem); + OnItemDraw(CheckedDeref(pDC), nIndex, lpDIS->itemAction, lpDIS->itemState, rct); +} + +///////////////////////////////////////////////////////////////////////////// +// CGrafixListBox2 Message Processing + +void CGrafixListBox2Mfc::OnLButtonDown(UINT nFlags, CPoint point) +{ + CListBox::OnLButtonDown(nFlags, point); // Allow field selection + + int nIdx; + if ((nIdx = GetCurSel()) == -1) + return; + if (m_bAllowDrag) + { + m_hLastWnd = NULL; + m_clickPoint = point; // For hysteresis + m_triggeredCursor = FALSE; // -Ditto- + } +} + +void CGrafixListBox2Mfc::OnLButtonUp(UINT nFlags, CPoint point) +{ + if (m_nTimerID) + { + KillTimer(m_nTimerID); + m_nTimerID = uintptr_t(0); + } + if (m_bAllowDrag) + { + ASSERT(!"unreachable code"); + BOOL bWasDragging = CWnd::GetCapture() == this; + CListBox::OnLButtonUp(nFlags, point); + + // Get the final selection results after the mouse was released. + if (IsMultiSelect()) + m_multiSelList = GetCurMappedItemList(); + + if (bWasDragging && m_triggeredCursor) + { +#if defined(GPLAY) + m_pDoc->AssignNewMoveGroup(); +#endif + + ReleaseCapture(); + SetCursor(LoadCursor(NULL, IDC_ARROW)); + + CWnd* pWnd = GetWindowFromPoint(point); + if (pWnd == NULL || (!m_bAllowSelfDrop && pWnd == this)) + { + OnDragCleanup(di); // Tell subclass we're all done. + return; + } + di.m_point = point; + di.m_pointClient = point; // list box relative + ClientToScreen(&di.m_point); + pWnd->ScreenToClient(&di.m_point); + + di.m_phase = PhaseDrag::Drop; + pWnd->SendMessage(WM_DRAGDROP, GetProcessId(GetCurrentProcess()), + (LPARAM)(LPVOID)&di); + OnDragCleanup(di); // Tell subclass we're all done. + m_multiSelList.clear(); + } + } + else + CListBox::OnLButtonUp(nFlags, point); +} + +void CGrafixListBox2Mfc::OnMouseMove(UINT nFlags, CPoint point) +{ + if (CWnd::GetCapture() != this) + { + // Only process tool tips when we aren't draggin stuff around + DoToolTipHitProcessing(point); + } + + if (m_bAllowDrag) + { + ASSERT(!"unreachable code"); + if (CWnd::GetCapture() != this) + return; + // OK...We are dragging. Let's check if the cursor has been + // triggered. If not, check if we've moved far enough from + // the initial mouse down position. + if (!m_triggeredCursor) + { + if (abs(point.x - m_clickPoint.x) < TRIGGER_THRESHOLD && + abs(point.y - m_clickPoint.y) < TRIGGER_THRESHOLD) + { + return; + } + m_triggeredCursor = TRUE; + } + OnDragSetup(di); // Get stuff from subclass + + // If we got here, dragging is under way.... + CWnd* pWnd = GetWindowFromPoint(point); + if (pWnd == NULL) + { + // No window underneath + SetCursor(g_res.hcrNoDrop); + return; + } + if (pWnd == this && !m_bAllowSelfDrop) + { + // The mouse is over us...show drop cursor + SetCursor(g_res.hcrDragTile); + return; + } + HWND hWnd = pWnd->m_hWnd; // Get actual window handle + HCURSOR hCursor = NULL; + + di.m_point = point; + di.m_pointClient = point; // list box relative + ClientToScreen(&di.m_point); + pWnd->ScreenToClient(&di.m_point); + + if (hWnd != m_hLastWnd) + { + if (m_hLastWnd != NULL) + { + // Inform previous window we are leaving them + CWnd* pLstWnd = CWnd::FromHandle(m_hLastWnd); + di.m_phase = PhaseDrag::Exit; + pLstWnd->SendMessage(WM_DRAGDROP, GetProcessId(GetCurrentProcess()), + (LPARAM)(LPVOID)&di); + } + di.m_phase = PhaseDrag::Enter; + pWnd->SendMessage(WM_DRAGDROP, GetProcessId(GetCurrentProcess()), (LPARAM)(LPVOID)&di); + } + m_hLastWnd = pWnd->m_hWnd; + di.m_phase = PhaseDrag::Over; + hCursor = (HCURSOR)pWnd->SendMessage(WM_DRAGDROP, GetProcessId(GetCurrentProcess()), + (LPARAM)(LPVOID)&di); + if (hCursor) + SetCursor(hCursor); + else + SetCursor(g_res.hcrNoDrop); + } + else + CListBox::OnMouseMove(nFlags, point); +} + +///////////////////////////////////////////////////////////////////////////// + +CWnd* CGrafixListBox2Mfc::GetWindowFromPoint(CPoint point) const +{ + wxASSERT(!"dead code?"); + ClientToScreen(&point); + CWnd* pWnd = WindowFromPoint(point); + + if (pWnd == NULL) + return NULL; + + pWnd->ScreenToClient(&point); + pWnd = pWnd->ChildWindowFromPoint(point); + + if (pWnd == NULL) + return NULL; + + return pWnd->IsWindowVisible() ? pWnd : NULL; +} + +int CGrafixListBox2Mfc::OnCreate(LPCREATESTRUCT lpCreateStruct) +{ + if (CListBox::OnCreate(lpCreateStruct) == -1) + return -1; + + m_pItemMap = NULL; + m_nTimerID = uintptr_t(0); + + return 0; +} + +///////////////////////////////////////////////////////////////// + +void CGrafixListBox2Mfc::DoInsertLineProcessing(const DragInfo& pdi) +{ + if (m_bAllowDropScroll) + { + wxASSERT(!"dead code"); + // Handle drawing of insert line + CPoint pnt = pdi.m_point; + int nSel = SpecialItemFromPoint(pnt); + if (pdi.m_phase == PhaseDrag::Enter) + { + m_nLastInsert = nSel; + DrawSingle(m_nLastInsert); // Turn line on + } + else if (pdi.m_phase == PhaseDrag::Exit || pdi.m_phase == PhaseDrag::Drop) + { + DrawSingle(m_nLastInsert); // Turn line off + m_nLastInsert = -1; + } + else + { + DrawInsert(nSel); // Move insert line + } + } +} + +///////////////////////////////////////////////////////////////// + +void CGrafixListBox2Mfc::DoAutoScrollProcessing(const DragInfo& pdi) +{ + if (m_bAllowDropScroll && m_nTimerID == uintptr_t(0)) + { + wxASSERT(!"dead code"); + CRect rct; + GetClientRect(&rct); + rct.InflateRect(0, -scrollZonePixels); + rct.NormalizeRect(); + if (!rct.PtInRect(pdi.m_point)) + { + // Trigger time is usually longer + m_nTimerID = SetTimer(timerScrollIDStart, timerScrollStart, NULL); + } + } +} + +///////////////////////////////////////////////////////////////// +// Pass it up to the parent by default. + +LRESULT CGrafixListBox2Mfc::OnDragItem(WPARAM wParam, LPARAM lParam) +{ + wxASSERT(!"dead code"); + if (wParam != GetProcessId(GetCurrentProcess())) + { + return -1; + } + const DragInfo& pdi = CheckedDeref(reinterpret_cast(lParam)); + DoInsertLineProcessing(pdi); + + CWnd *pWnd = GetParent(); + ASSERT(pWnd != NULL); + LRESULT lResult = pWnd->SendMessage(WM_DRAGDROP, wParam, lParam); + + if (pdi.m_phase == PhaseDrag::Over && lResult != 0) + DoAutoScrollProcessing(di); + return lResult; +} + +void CGrafixListBox2Mfc::OnTimer(uintptr_t nIDEvent) +{ + if (nIDEvent != m_nTimerID) + return; + + wxASSERT(!"dead code"); + CPoint point; + CRect rctClient; + CRect rct; + + GetCursorPos(&point); + ScreenToClient(&point); + GetClientRect(&rctClient); + rct = rctClient; + rct.InflateRect(0, -scrollZonePixels); + rct.NormalizeRect(); + + if (rctClient.PtInRect(point) && !rct.PtInRect(point)) + { + // Restart the timer. + if (m_nTimerID == timerScrollIDStart) + { + KillTimer(m_nTimerID); + m_nTimerID = SetTimer(timerScrollID, timerScroll, NULL); + } + BOOL bHaveFocus = GetFocus() == this; + if (bHaveFocus) + { + GetParent()->SetFocus(); + SetCapture(); // Reestablish the mouse capture + } + + // Hide insert line + DrawSingle(m_nLastInsert); + + int nTopIndex = GetTopIndex(); + if (point.y <= rct.top) + { + if (nTopIndex > 0) + SetTopIndex(nTopIndex - 1); + } + else + { + if (nTopIndex < GetCount() - 1 && nTopIndex >= 0) + SetTopIndex(nTopIndex + 1); + } + // Restore insert line in new position + CPoint pnt; + GetCursorPos(&pnt); + ScreenToClient(&pnt); + m_nLastInsert = SpecialItemFromPoint(pnt); + DrawSingle(m_nLastInsert); + + if (bHaveFocus) + SetFocus(); + } + else + { + KillTimer(m_nTimerID); + m_nTimerID = uintptr_t(0); + } +} + +///////////////////////////////////////////////////////////////// +// This routine selects the next item if the point is past +// the y midpoint of the item. + +int CGrafixListBox2Mfc::SpecialItemFromPoint(CPoint pnt) const +{ + wxASSERT(!"dead code"); + BOOL bBucket; + int nSel = (int)ItemFromPoint(pnt, bBucket); + CRect rct; + GetItemRect(nSel, &rct); + // Note: it is possible for the item number to exceed the + // number of items in the listbox. This is figured into our + // coding. + if (pnt.y > (rct.top + rct.bottom) / 2) + nSel++; // Step to next item + return nSel; +} + +///////////////////////////////////////////////////////////////// + +void CGrafixListBox2Mfc::DrawInsert(int nIndex) +{ + if (m_nLastInsert != nIndex) + { + DrawSingle(m_nLastInsert); + DrawSingle(nIndex); + m_nLastInsert = nIndex; + } +} + +void CGrafixListBox2Mfc::DrawSingle(int nIndex) +{ + if (nIndex == -1) + return; + CBrush* pBrush = CDC::GetHalftoneBrush(); + CRect rect; + GetClientRect(&rect); + CRgn rgn; + rgn.CreateRectRgnIndirect(&rect); + + CDC* pDC = GetDC(); + // Prevent drawing outside of listbox. This can happen at the + // top of the listbox since the listbox's DC is the parent's DC. + pDC->SelectClipRgn(&rgn); + + // Account for possibility of nIndex equal to number + // of listbox items.... + if (nIndex < GetCount()) + { + GetItemRect(nIndex, &rect); + rect.bottom = rect.top + 2; + rect.top -= 2; + } + else + { + GetItemRect(nIndex - 1, &rect); + rect.top = rect.bottom - 2; + rect.bottom += 2; + } + + CBrush* pBrushOld = pDC->SelectObject(pBrush); + // Draw main line + pDC->PatBlt(rect.left, rect.top, rect.Width(), rect.Height(), PATINVERT); + + pDC->SelectObject(pBrushOld); + ReleaseDC(pDC); +} + +CPoint CGrafixListBox2Mfc::ClientToItem(CPoint point) const +{ + // account for horz scroll + int xOffset = GetScrollPos(SB_HORZ); + ASSERT(xOffset >= 0); + point.x += xOffset; + return point; +} + +CRect CGrafixListBox2Mfc::ItemToClient(CRect rect) const +{ + // account for horz scroll + int xOffset = GetScrollPos(SB_HORZ); + ASSERT(xOffset >= 0); + rect.OffsetRect(-xOffset, 0); + return rect; +} + diff --git a/GShr/LBoxGfx2.h b/GShr/LBoxGfx2.h index be2f9a18..1f8ea37b 100644 --- a/GShr/LBoxGfx2.h +++ b/GShr/LBoxGfx2.h @@ -1,6 +1,6 @@ // LBoxGfx2.h // -// Copyright (c) 1994-2020 By Dale L. Larson, All Rights Reserved. +// Copyright (c) 1994-2025 By Dale L. Larson & William Su, All Rights Reserved. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the @@ -41,6 +41,7 @@ class CDrawObj; ///////////////////////////////////////////////////////////////////////////// // Custom Listbox - containing colors +#if 0 class CGrafixListBox2 : public CListBox { // Construction @@ -151,6 +152,121 @@ class CGrafixListBox2 : public CListBox //}}AFX_MSG DECLARE_MESSAGE_MAP() +private: + CB::propagate_const m_pDoc = nullptr; +}; +#endif + +class CGrafixListBox2Mfc : public CListBox +{ +// Construction +public: + CGrafixListBox2Mfc(); + +// Attributes +public: + int GetTopSelectedItem() const; + void EnableDrag(BOOL bEnable = TRUE) { m_bAllowDrag = bEnable; } + void EnableSelfDrop(BOOL bEnable = TRUE) { m_bAllowSelfDrop = bEnable; } + void EnableDropScroll(BOOL bEnable = TRUE) { m_bAllowDropScroll = bEnable; } + const std::vector>* GetItemMap() const { return m_pItemMap; } + const CDrawObj& GetCurMapItem() const; + std::vector> GetCurMappedItemList() const; + BOOL IsMultiSelect() const + { return (GetStyle() & (LBS_EXTENDEDSEL | LBS_MULTIPLESEL)) != 0; } + // Note: the following pointer is only good during drag and drop. + // the data is only good during the drop. It is essentially a + // hack to have valid data when selecting items with Shift-Click. + // Ask Microsoft why I had to do this. The number of selections + // data in the case of a shift click isn't valid until the button + // is released. Makes it tough to use a pre setup list during the + // drag operation. + const std::vector>& GetMappedMultiSelectList() const { return m_multiSelList; } + +// Operations +public: + void SetItemMap(const std::vector>* pMap, BOOL bKeepPosition = TRUE); + void UpdateList(BOOL bKeepPosition = TRUE); + void SetCurSelMapped(const CDrawObj& pMapVal); + void SetCurSelsMapped(const std::vector>& items); + void SetSelFromPoint(CPoint point); + void ShowFirstSelection(); + const CDrawObj& MapIndexToItem(size_t nIndex) const; + CDrawObj& MapIndexToItem(size_t nIndex) + { + return const_cast(std::as_const(*this).MapIndexToItem(nIndex)); + } + size_t MapItemToIndex(const CDrawObj& pItem) const; + void MakeItemVisible(int nItem); + +// Overrides - the subclass of this class must override these +public: + virtual CSize OnItemSize(size_t nIndex) const /* override */ = 0; + virtual void OnItemDraw(CDC& pDC, size_t nIndex, UINT nAction, UINT nState, + CRect rctItem) const /* override */ = 0; + virtual BOOL OnDragSetup(DragInfo& pDI) const /* override */ + { + pDI.SetDragType(DRAG_INVALID); + return FALSE; + } + virtual void OnDragCleanup(const DragInfo& pDI) const /* override */ { } + + // For tool tip processing + virtual BOOL OnIsToolTipsEnabled() const /* override */ { return FALSE; } + virtual GameElement OnGetHitItemCodeAtPoint(CPoint point, CRect& rct) const /* override */ { return Invalid_v; } + virtual CB::string OnGetTipTextForItemCode(GameElement nItemCode) const /* override */ { return CB::string(); } + +// Implementation +protected: + /* N.B.: this class could be templatized to hold any pointer, + but that generality isn't actually needed yet */ + const std::vector>* m_pItemMap; // Maps index to item + std::vector> m_multiSelList; // Holds mapped multi select items on drop + + // Tool tip support + CToolTipCtrl m_toolTip; + GameElement m_nCurItemCode; + + // Drag and scroll support vars + BOOL m_bAllowDrag; + BOOL m_bAllowSelfDrop; // Only if m_bAllowDrag == TRUE + BOOL m_bAllowDropScroll; // Scroll on OnDragItem + + CPoint m_clickPoint; + uintptr_t m_nTimerID; + BOOL m_triggeredCursor; + HWND m_hLastWnd; + + int m_nLastInsert; // Last index with insert line + + void SetDocument(CGamDoc& doc) { m_pDoc = &doc; } + void DoInsertLineProcessing(const DragInfo& pdi); + void DoAutoScrollProcessing(const DragInfo& pdi); + void DoToolTipHitProcessing(CPoint point); + + CWnd* GetWindowFromPoint(CPoint point) const; + int SpecialItemFromPoint(CPoint pnt) const; + void DrawInsert(int nIndex); + void DrawSingle(int nIndex); + + CPoint ClientToItem(CPoint point) const; + CRect ItemToClient(CRect rect) const; + + // Overrides + virtual void MeasureItem(LPMEASUREITEMSTRUCT lpMIS) override; + virtual void DrawItem(LPDRAWITEMSTRUCT lpDIS) override; + virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam) override; + + //{{AFX_MSG(CGrafixListBox2) + afx_msg void OnLButtonDown(UINT nFlags, CPoint point); + afx_msg void OnMouseMove(UINT nFlags, CPoint point); + afx_msg void OnLButtonUp(UINT nFlags, CPoint point); + afx_msg void OnTimer(uintptr_t nIDEvent); + afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); + afx_msg LRESULT OnDragItem(WPARAM wParam, LPARAM lParam); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() + private: CB::propagate_const m_pDoc = nullptr; }; diff --git a/GShr/LBoxTileBase2.cpp b/GShr/LBoxTileBase2.cpp index cb8eb246..167c6d4d 100644 --- a/GShr/LBoxTileBase2.cpp +++ b/GShr/LBoxTileBase2.cpp @@ -1,7 +1,7 @@ // LBoxTileBase2.cpp - base class used to handle a variety of tile oriented // listbox functions. // -// Copyright (c) 1994-2023 By Dale L. Larson & William Su, All Rights Reserved. +// Copyright (c) 1994-2025 By Dale L. Larson & William Su, All Rights Reserved. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the @@ -38,6 +38,7 @@ const int tileBorder = 3; const int tileGap = 6; +#if 0 ///////////////////////////////////////////////////////////////////////////// BEGIN_MESSAGE_MAP(CTileBaseListBox2, CGrafixListBox2) @@ -261,3 +262,227 @@ int CTileBaseListBox2::OnCreate(LPCREATESTRUCT lpCreateStruct) } +#endif +///////////////////////////////////////////////////////////////////////////// + +BEGIN_MESSAGE_MAP(CTileBaseListBox2Mfc, CGrafixListBox2Mfc) + //{{AFX_MSG_MAP(CTileBaseListBox2) + ON_WM_CREATE() + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// + +CTileBaseListBox2Mfc::CTileBaseListBox2Mfc() +{ + m_bDisplayIDs = AfxGetApp()->GetProfileInt("Settings"_cbstring, "DisplayIDs"_cbstring, 0); + + m_bTipMarkItems = TRUE; + m_sizeTipMark = CSize(0, 0); +} + +///////////////////////////////////////////////////////////////////////////// + +CSize CTileBaseListBox2Mfc::DoOnItemSize(size_t nItem, const std::vector& tids) const +{ + ASSERT(!tids.empty() && tids[size_t(0)] != nullTid); // At least one tile needs to exist + + int nHt = 0; + for (size_t i = size_t(0); i < tids.size(); ++i) + { + CTile tile = GetTileManager().GetTile(tids[i], fullScale); + nHt = CB::max(nHt, tile.GetHeight()); + } + + // Listbox lines can only be 255 pixels high. + nHt = CB::min(2 * tileBorder + nHt, 255); + + if (m_bDisplayIDs || m_bTipMarkItems) // See if we're drawing debug ID's + nHt = CB::max(nHt, value_preserving_cast(g_res.tm8ss.tmHeight + g_res.tm8ss.tmExternalLeading)); + + BOOL bItemHasTipText = OnDoesItemHaveTipText(nItem); + + // only using DC for measurement, so const_cast safe + CClientDC pDC(const_cast(this)); + CRect rctItem(0, 0, 32000, 32000); + + pDC.SaveDC(); + + int x = rctItem.left + tileBorder; + + DrawTipMarker(pDC, rctItem, bItemHasTipText, x); + DrawItemDebugIDCode(pDC, nItem, rctItem, false, x); + for (size_t i = size_t(0); i < tids.size(); ++i) + { + DrawTileImage(pDC, rctItem, false, x, tids[i]); + } + + pDC.RestoreDC(-1); + + return CSize(x, nHt); +} + +///////////////////////////////////////////////////////////////////////////// + +void CTileBaseListBox2Mfc::DoOnDrawItem(CDC& pDC, size_t nItem, UINT nAction, UINT nState, + CRect rctItem, const std::vector& tids) const +{ + if (nAction & (ODA_DRAWENTIRE | ODA_SELECT)) + { + ASSERT(!tids.empty() && tids[size_t(0)] != nullTid); + + BOOL bItemHasTipText = OnDoesItemHaveTipText(nItem); + + pDC.SaveDC(); + pDC.IntersectClipRect(&rctItem); + pDC.SetBkMode(TRANSPARENT); + + CBrush brBack(GetSysColor(nState & ODS_SELECTED ? + COLOR_HIGHLIGHT : COLOR_WINDOW)); + pDC.FillRect(&rctItem, &brBack); // Fill background color + + pDC.SetTextColor(GetSysColor(nState & ODS_SELECTED ? + COLOR_HIGHLIGHTTEXT : COLOR_WINDOWTEXT)); + + int x = rctItem.left + tileBorder; + + DrawTipMarker(pDC, rctItem, bItemHasTipText, x); + DrawItemDebugIDCode(pDC, nItem, rctItem, TRUE, x); + for (size_t i = size_t(0); i < tids.size(); ++i) + { + DrawTileImage(pDC, rctItem, true, x, tids[i]); + } + + pDC.RestoreDC(-1); + } + if (nAction & ODA_FOCUS) + pDC.DrawFocusRect(&rctItem); +} + +///////////////////////////////////////////////////////////////////////////// + +void CTileBaseListBox2Mfc::DrawTileImage(CDC& pDC, CRect rctItem, BOOL bDrawIt, int& x, TileID tid) const +{ + if (tid == nullTid) + return; // Nothing to do + + CTile tile = GetTileManager().GetTile(tid, fullScale); + + if (bDrawIt) + { + if (tile.GetHeight() >= 255) + tile.BitBlt(pDC, x, rctItem.top + tileBorder);// Too large. Don't draw vertically centered + else + tile.BitBlt(pDC, x, (rctItem.Height() - tile.GetHeight()) / 2 + rctItem.top); + } + x += tile.GetWidth() + tileGap; +} + +///////////////////////////////////////////////////////////////////////////// +// Optionally draw debug code string for item. If bDrawIt is false, +// x is advanced the size of the string anyway but nothing is rendered + +void CTileBaseListBox2Mfc::DrawItemDebugIDCode(CDC& pDC, size_t nItem, CRect rctItem, BOOL bDrawIt, int& x) const +{ + if (m_bDisplayIDs) + { + CB::string str = OnGetItemDebugString(nItem); + + CFont* prvFont = (CFont*)pDC.SelectObject(CFont::FromHandle(g_res.h8ss)); + int y = rctItem.top + rctItem.Height() / 2 - + (g_res.tm8ss.tmHeight + g_res.tm8ss.tmExternalLeading) / 2; + if (bDrawIt) + pDC.TextOut(x, y, str); + x += pDC.GetTextExtent(str).cx; + pDC.SelectObject(prvFont); + } +} + +///////////////////////////////////////////////////////////////////////////// + +void CTileBaseListBox2Mfc::SetupTipMarkerIfRequired() +{ + if (m_bTipMarkItems) + { + ASSERT(m_hWnd != NULL); + if (m_sizeTipMark.cx == 0) + { + // Hasn't been initialized yet. + m_strTipMark = CB::string::LoadString(IDS_TIP_LBOXITEM_MARKER); + + CDC* pDC = GetDC(); + + CFont* prvFont = (CFont*)pDC->SelectObject(CFont::FromHandle(g_res.h8ss)); + m_sizeTipMark.cx = pDC->GetTextExtent(m_strTipMark).cx; + m_sizeTipMark.cy = g_res.tm8ss.tmHeight + g_res.tm8ss.tmExternalLeading; + pDC->SelectObject(prvFont); + + ReleaseDC(pDC); + } + } +} + +void CTileBaseListBox2Mfc::DrawTipMarker(CDC& pDC, CRect rctItem, BOOL bVisible, int& x) const +{ + if (m_bTipMarkItems) + { + CFont* prvFont = (CFont*)pDC.SelectObject(CFont::FromHandle(g_res.h8ss)); + if (bVisible) // Draw only if visible. Else just move 'x' + { + int y = rctItem.top + (rctItem.Height() - m_sizeTipMark.cy) / 2; + pDC.TextOut(x, y, m_strTipMark); + } + x += m_sizeTipMark.cx; + pDC.SelectObject(prvFont); + } +} + +CB::string CTileBaseListBox2Mfc::OnGetItemDebugString(size_t nItem) const +{ + return std::format(L"[{}] ", OnGetItemDebugIDCode(nItem)); +} + +///////////////////////////////////////////////////////////////////////////// + +std::vector CTileBaseListBox2Mfc::GetTileRectsForItem(size_t nItem, + const std::vector& tids) const +{ + ASSERT(!tids.empty() && tids[size_t(0)] != nullTid); + + CRect rctItem; + GetItemRect(value_preserving_cast(nItem), &rctItem); + + int x = rctItem.left + tileBorder; // Set starting x position + + // Need to account for possible markers and debug strings + // rendered to left of tile images + // only using DC for measurement, so const_cast safe + CDC& pDC = CheckedDeref(const_cast(this)->GetDC()); + DrawTipMarker(pDC, rctItem, FALSE, x); + DrawItemDebugIDCode(pDC, nItem, rctItem, FALSE, x); + const_cast(this)->ReleaseDC(&pDC); + + std::vector retval(tids.size()); + for (size_t i = size_t(0); i < tids.size(); ++i) + { + retval[i].SetRectEmpty(); + retval[i].top = rctItem.top; // Set the top & bottom values + retval[i].bottom = rctItem.bottom; + retval[i].left = x; + DrawTileImage(pDC, rctItem, FALSE, x, tids[i]); + retval[i].right = x; + } + return retval; +} + +int CTileBaseListBox2Mfc::OnCreate(LPCREATESTRUCT lpCreateStruct) +{ + int retval = CGrafixListBox2Mfc::OnCreate(lpCreateStruct); + if (retval == 0) + { + SetupTipMarkerIfRequired(); + } + return retval; +} + + diff --git a/GShr/LBoxTileBase2.h b/GShr/LBoxTileBase2.h index e73baaa1..6a300402 100644 --- a/GShr/LBoxTileBase2.h +++ b/GShr/LBoxTileBase2.h @@ -1,7 +1,7 @@ // LBoxTileBase.h - class used to handle a variety of tile // oriented listbox functions // -// Copyright (c) 1994-2020 By Dale L. Larson, All Rights Reserved. +// Copyright (c) 1994-2025 By Dale L. Larson & William Su, All Rights Reserved. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the @@ -34,6 +34,7 @@ #include "Tile.h" #endif +#if 0 /////////////////////////////////////////////////////////////////////// class CTileBaseListBox2 : public CGrafixListBox2 @@ -85,4 +86,56 @@ class CTileBaseListBox2 : public CGrafixListBox2 }; +#endif +/////////////////////////////////////////////////////////////////////// + +class CTileBaseListBox2Mfc : public CGrafixListBox2Mfc +{ +public: + CTileBaseListBox2Mfc(); + + void SetTipMarkVisibility(BOOL bShow = TRUE) { m_bTipMarkItems = bShow; } + BOOL GetTipMarkVisibility() const { return m_bTipMarkItems; } + +// Vars... +protected: + int m_bDisplayIDs; // Set by property [Settings]:DisplayIDs + + BOOL m_bTipMarkItems; + CB::string m_strTipMark; + CSize m_sizeTipMark; + +// Helpers... +protected: + void DrawTileImage(CDC& pDC, CRect rctItem, BOOL bDrawIt, int& x, TileID tid) const; + void DrawItemDebugIDCode(CDC& pDC, size_t nItem, CRect rctItem, BOOL bDrawIt, int& x) const; + + void SetupTipMarkerIfRequired(); + void DrawTipMarker(CDC& pDC, CRect rctItem, BOOL bVisible, int& x) const; + + CSize DoOnItemSize(size_t nItem, const std::vector& tids) const; + void DoOnDrawItem(CDC& pDC, size_t nItem, UINT nAction, UINT nState, CRect rctItem, + const std::vector& tids) const; + + std::vector GetTileRectsForItem(size_t nItem, const std::vector& tids) const; + +// Overrides... +public: + virtual const CTileManager& GetTileManager() const /* override */ = 0; + +// Overrides... +protected: + virtual BOOL OnDoesItemHaveTipText(size_t nItem) const /* override */ { return FALSE; } + + // Subclass should only override one of these if any... + virtual const void* OnGetItemDebugIDCode(size_t nItem) const /* override */ { return &MapIndexToItem(nItem); } + virtual CB::string OnGetItemDebugString(size_t nItem) const /* override */; + + //{{AFX_MSG(CTileBaseListBox) + afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + + #endif From 83729e6f6818c0bd3e2ffd45b55976466a45f3d9 Mon Sep 17 00:00:00 2001 From: Bill Su Date: Thu, 4 Sep 2025 22:39:07 -0400 Subject: [PATCH 30/80] CBPlay: disable MFC commands that aren't explicitly enabled --- GP/Gp.cpp | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/GP/Gp.cpp b/GP/Gp.cpp index eab940e2..27372ca9 100644 --- a/GP/Gp.cpp +++ b/GP/Gp.cpp @@ -177,6 +177,42 @@ namespace { return true; } + + protected: + /* for safety, and to approximate MFC, + disable MFC toolbar/menu commands that aren't + explicitly enabled */ + bool TryAfter(wxEvent& event) override + { + if (wxAppWithMFC::TryAfter(event)) + { + return true; + } + + /* for safety, and to approximate MFC, + disable toolbar/menu commands that aren't + explicitly enabled */ + if (event.GetEventType() == wxEVT_UPDATE_UI) + { + wxUpdateUIEvent& pCmdUI = static_cast(event); + wxString xrcid = wxXmlResource::FindXRCIDById(pCmdUI.GetId()); + // !event.obj suggests MFC + /* if xrcid is empty, then id is something + wx-internal (e.g., wxAUI_BUTTON_WINDOWLIST), + so don't interfere with it */ + if (!event.GetEventObject() && !xrcid.empty()) + { + if (pCmdUI.IsCheckable()) + { + pCmdUI.Check(false); + } + pCmdUI.Enable(false); + return true; + } + } + + return false; + } }; } wxDECLARE_APP(wxCGpApp); From 78147b1d755cd1029c55f1e204e9f6d9b15d7265 Mon Sep 17 00:00:00 2001 From: Bill Su Date: Thu, 4 Sep 2025 23:25:12 -0400 Subject: [PATCH 31/80] LBoxGfx2: provide wx version --- GShr/LBoxGfx2.cpp | 208 +++++++++++++++++++++++++++------------------- GShr/LBoxGfx2.h | 80 +++++++++++------- 2 files changed, 174 insertions(+), 114 deletions(-) diff --git a/GShr/LBoxGfx2.cpp b/GShr/LBoxGfx2.cpp index 9e1c236e..bbd63ff9 100644 --- a/GShr/LBoxGfx2.cpp +++ b/GShr/LBoxGfx2.cpp @@ -47,26 +47,27 @@ const int timerScroll = 125; const uintptr_t timerScrollIDStart = 900; const int timerScrollID = 901; -#if 0 ///////////////////////////////////////////////////////////////////////////// -BEGIN_MESSAGE_MAP(CGrafixListBox2, CListBox) - //{{AFX_MSG_MAP(CGrafixListBox2) - ON_WM_LBUTTONDOWN() - ON_WM_MOUSEMOVE() - ON_WM_LBUTTONUP() +wxBEGIN_EVENT_TABLE(CGrafixListBox2, CB::VListBoxHScroll) + EVT_LEFT_DOWN(OnLButtonDown) + EVT_MOTION(OnMouseMove) + EVT_LEFT_UP(OnLButtonUp) +#if 0 ON_WM_TIMER() - ON_WM_CREATE() - ON_REGISTERED_MESSAGE(WM_DRAGDROP, OnDragItem) - //}}AFX_MSG_MAP -END_MESSAGE_MAP() +#endif + EVT_WINDOW_CREATE(OnCreate) + EVT_DRAGDROP(OnDragItem) +wxEND_EVENT_TABLE() ///////////////////////////////////////////////////////////////////////////// CGrafixListBox2::CGrafixListBox2() { m_nLastInsert = -1; +#if 0 m_nTimerID = uintptr_t(0); +#endif m_bAllowDrag = FALSE; m_bAllowSelfDrop = FALSE; m_bAllowDropScroll = FALSE; @@ -87,50 +88,49 @@ void CGrafixListBox2::UpdateList(BOOL bKeepPosition /* = TRUE */) { if (m_pItemMap == NULL) { - ResetContent(); + Clear(); return; } - int nCurSel = GetCurSel(); - int nTopIdx = GetTopIndex(); - int nFcsIdx = GetCaretIndex(); - int horzScroll = GetScrollPos(SB_HORZ); - SetRedraw(FALSE); - ResetContent(); + int nCurSel = IsMultiSelect() ? wxNOT_FOUND : GetSelection(); + size_t nTopIdx = GetVisibleRowsBegin(); + int nFcsIdx = GetCurrent(); + int horzScroll = GetScrollPos(wxHORIZONTAL); +{ + wxWindowUpdateLocker freezer(this); + Clear(); - LONG width = 0; - int nItem; - for (nItem = 0; nItem < value_preserving_cast(m_pItemMap->size()); nItem++) - { - AddString(" "_cbstring); // Fill with dummy data - width = CB::max(width, OnItemSize(value_preserving_cast(nItem)).cx); - } - SetHorizontalExtent(value_preserving_cast(width)); + size_t nItem = CB::max(size_t(1), m_pItemMap->size()); + SetItemCount(m_pItemMap->size()); if (bKeepPosition) { - if (nTopIdx >= 0) - SetTopIndex(std::min(nTopIdx, nItem - 1)); - if (nFcsIdx >= 0) - SetCaretIndex(std::min(nFcsIdx, nItem - 1), FALSE); - if (nCurSel >= 0) - SetCurSel(std::min(nCurSel, nItem - 1)); + ScrollToRow(CB::min(nTopIdx, nItem - size_t(1))); + if (nFcsIdx != wxNOT_FOUND) + { + SetCurrent(CB::min(nFcsIdx, value_preserving_cast(nItem - size_t(1)))); + } + if (nCurSel != wxNOT_FOUND) + { + SetSelection(CB::min(nCurSel, value_preserving_cast(nItem - size_t(1)))); + } } - SetRedraw(TRUE); +} if (bKeepPosition) { - SendMessage(WM_HSCROLL, MAKELONG(int16_t(SB_THUMBPOSITION), value_preserving_cast(horzScroll)), NULL); + SetScrollPos(wxHORIZONTAL, horzScroll); } - Invalidate(); + Refresh(); } ///////////////////////////////////////////////////////////////////////////// const CDrawObj& CGrafixListBox2::MapIndexToItem(size_t nIndex) const { - ASSERT(m_pItemMap); - ASSERT(nIndex < m_pItemMap->size()); + wxASSERT(m_pItemMap); + wxASSERT(nIndex < m_pItemMap->size()); return *m_pItemMap->at(nIndex); } +#if 0 size_t CGrafixListBox2::MapItemToIndex(const CDrawObj& pItem) const { wxASSERT(!"dead code?"); @@ -260,27 +260,28 @@ void CGrafixListBox2::SetSelFromPoint(CPoint point) MAKELPARAM(static_cast(point.x), static_cast(point.y))); m_bAllowDrag = TRUE; } +#endif ///////////////////////////////////////////////////////////////////////////// -void CGrafixListBox2::DoToolTipHitProcessing(CPoint point) +void CGrafixListBox2::DoToolTipHitProcessing(wxPoint point) { if (!OnIsToolTipsEnabled()) return; - if (m_toolTip.m_hWnd == NULL) - { - m_toolTip.Create(this, TTS_ALWAYSTIP | TTS_BALLOON | TTS_NOPREFIX); - m_toolTip.SetMaxTipWidth(MAX_LISTITEM_TIP_WIDTH); - } + m_toolTip.SetMaxWidth(MAX_LISTITEM_TIP_WIDTH); - CRect rctTool; + wxRect rctTool; GameElement nItemCode = OnGetHitItemCodeAtPoint(point, rctTool); if (nItemCode != m_nCurItemCode) { // Object changed so delete previous tool definition - m_toolTip.DelTool(this, ID_TIP_LISTITEM_HIT); + if (!m_rectToolTip.IsEmpty()) + { + m_toolTip.Delete(*this, m_rectToolTip); + m_rectToolTip = wxRect(); + } m_nCurItemCode = nItemCode; if (nItemCode != Invalid_v) { @@ -292,15 +293,17 @@ void CGrafixListBox2::DoToolTipHitProcessing(CPoint point) if (!strTip.empty()) { - m_toolTip.AddTool(this, strTip, rctTool, ID_TIP_LISTITEM_HIT); - m_toolTip.Activate(TRUE); + m_toolTip.Add(*this, rctTool, strTip); + m_rectToolTip = rctTool; + m_toolTip.Enable(TRUE); } } else - m_toolTip.Activate(FALSE); + m_toolTip.Enable(FALSE); } } +#if 0 LRESULT CGrafixListBox2::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) { if (m_toolTip.m_hWnd != NULL && message >= WM_MOUSEFIRST && @@ -338,35 +341,45 @@ void CGrafixListBox2::DrawItem(LPDRAWITEMSTRUCT lpDIS) CRect rct(lpDIS->rcItem); OnItemDraw(CheckedDeref(pDC), nIndex, lpDIS->itemAction, lpDIS->itemState, rct); } +#endif ///////////////////////////////////////////////////////////////////////////// // CGrafixListBox2 Message Processing -void CGrafixListBox2::OnLButtonDown(UINT nFlags, CPoint point) +void CGrafixListBox2::OnLButtonDown(wxMouseEvent& event) { - CListBox::OnLButtonDown(nFlags, point); // Allow field selection + ExecutePostProcessEvents(); + wxASSERT(!GetCapture()); + event.Skip(); // Allow field selection - int nIdx; - if ((nIdx = GetCurSel()) == -1) - return; - if (m_bAllowDrag) - { - m_hLastWnd = NULL; - m_clickPoint = point; // For hysteresis - m_triggeredCursor = FALSE; // -Ditto- - } + PushPostProcessEvent([this, event]{ + wxASSERT(GetCapture() == this); + if (GetSelectedCount() == 0) + return; + if (m_bAllowDrag) + { + wxASSERT(!"unreachable code"); + m_hLastWnd = NULL; + m_clickPoint = event.GetPosition(); // For hysteresis + m_triggeredCursor = FALSE; // -Ditto- + } + }); } -void CGrafixListBox2::OnLButtonUp(UINT nFlags, CPoint point) +void CGrafixListBox2::OnLButtonUp(wxMouseEvent& event) { + ExecutePostProcessEvents(); +#if 0 if (m_nTimerID) { KillTimer(m_nTimerID); m_nTimerID = uintptr_t(0); } +#endif if (m_bAllowDrag) { ASSERT(!"unreachable code"); +#if 0 BOOL bWasDragging = CWnd::GetCapture() == this; CListBox::OnLButtonUp(nFlags, point); @@ -400,22 +413,27 @@ void CGrafixListBox2::OnLButtonUp(UINT nFlags, CPoint point) OnDragCleanup(di); // Tell subclass we're all done. m_multiSelList.clear(); } +#endif } else - CListBox::OnLButtonUp(nFlags, point); + { + event.Skip(); + } } -void CGrafixListBox2::OnMouseMove(UINT nFlags, CPoint point) +void CGrafixListBox2::OnMouseMove(wxMouseEvent& event) { - if (CWnd::GetCapture() != this) + ExecutePostProcessEvents(); + if (!HasCapture()) { // Only process tool tips when we aren't draggin stuff around - DoToolTipHitProcessing(point); + DoToolTipHitProcessing(event.GetPosition()); } if (m_bAllowDrag) { - ASSERT(!"unreachable code"); + wxASSERT(!"unreachable code"); +#if 0 if (CWnd::GetCapture() != this) return; // OK...We are dragging. Let's check if the cursor has been @@ -475,13 +493,17 @@ void CGrafixListBox2::OnMouseMove(UINT nFlags, CPoint point) SetCursor(hCursor); else SetCursor(g_res.hcrNoDrop); +#endif } else - CListBox::OnMouseMove(nFlags, point); + { + event.Skip(); + } } ///////////////////////////////////////////////////////////////////////////// +#if 0 CWnd* CGrafixListBox2::GetWindowFromPoint(CPoint point) const { wxASSERT(!"dead code?"); @@ -499,25 +521,26 @@ CWnd* CGrafixListBox2::GetWindowFromPoint(CPoint point) const return pWnd->IsWindowVisible() ? pWnd : NULL; } +#endif -int CGrafixListBox2::OnCreate(LPCREATESTRUCT lpCreateStruct) +void CGrafixListBox2::OnCreate(wxWindowCreateEvent& event) { - if (CListBox::OnCreate(lpCreateStruct) == -1) - return -1; + event.Skip(); m_pItemMap = NULL; +#if 0 m_nTimerID = uintptr_t(0); - - return 0; +#endif } ///////////////////////////////////////////////////////////////// -void CGrafixListBox2::DoInsertLineProcessing(const DragInfo& pdi) +void CGrafixListBox2::DoInsertLineProcessing(const DragInfoWx& pdi) { if (m_bAllowDropScroll) { wxASSERT(!"dead code"); +#if 0 // Handle drawing of insert line CPoint pnt = pdi.m_point; int nSel = SpecialItemFromPoint(pnt); @@ -535,13 +558,16 @@ void CGrafixListBox2::DoInsertLineProcessing(const DragInfo& pdi) { DrawInsert(nSel); // Move insert line } +#endif } } ///////////////////////////////////////////////////////////////// -void CGrafixListBox2::DoAutoScrollProcessing(const DragInfo& pdi) +void CGrafixListBox2::DoAutoScrollProcessing(const DragInfoWx& pdi) { + wxASSERT(!m_bAllowDropScroll); +#if 0 if (m_bAllowDropScroll && m_nTimerID == uintptr_t(0)) { wxASSERT(!"dead code"); @@ -555,14 +581,16 @@ void CGrafixListBox2::DoAutoScrollProcessing(const DragInfo& pdi) m_nTimerID = SetTimer(timerScrollIDStart, timerScrollStart, NULL); } } +#endif } ///////////////////////////////////////////////////////////////// // Pass it up to the parent by default. -LRESULT CGrafixListBox2::OnDragItem(WPARAM wParam, LPARAM lParam) +void CGrafixListBox2::OnDragItem(DragDropEvent& /*event*/) { wxASSERT(!"dead code"); +#if 0 if (wParam != GetProcessId(GetCurrentProcess())) { return -1; @@ -577,8 +605,10 @@ LRESULT CGrafixListBox2::OnDragItem(WPARAM wParam, LPARAM lParam) if (pdi.m_phase == PhaseDrag::Over && lResult != 0) DoAutoScrollProcessing(di); return lResult; +#endif } +#if 0 void CGrafixListBox2::OnTimer(uintptr_t nIDEvent) { if (nIDEvent != m_nTimerID) @@ -711,25 +741,31 @@ void CGrafixListBox2::DrawSingle(int nIndex) ReleaseDC(pDC); } -CPoint CGrafixListBox2::ClientToItem(CPoint point) const +#endif + +void CGrafixListBox2::PushPostProcessEvent(std::function&& f) { - // account for horz scroll - int xOffset = GetScrollPos(SB_HORZ); - ASSERT(xOffset >= 0); - point.x += xOffset; - return point; + // I'm pretty sure we should have at most one partial event + /* TODO: after confirming at most one, + convert to std::optional<> instead of queue<> */ + wxASSERT(postProcessEvents.empty()); + postProcessEvents.push(std::move(f)); + CallAfter([this]{ ExecutePostProcessEvents(); }); } -CRect CGrafixListBox2::ItemToClient(CRect rect) const +void CGrafixListBox2::ExecutePostProcessEvents() { - // account for horz scroll - int xOffset = GetScrollPos(SB_HORZ); - ASSERT(xOffset >= 0); - rect.OffsetRect(-xOffset, 0); - return rect; + // I'm pretty sure we should have at most one partial event + wxASSERT(postProcessEvents.size() <= 1); + while (!postProcessEvents.empty()) + { + // need to pop before executing to avoid recursion + std::function f = std::move(postProcessEvents.front()); + postProcessEvents.pop(); + f(); + } } -#endif ///////////////////////////////////////////////////////////////////////////// BEGIN_MESSAGE_MAP(CGrafixListBox2Mfc, CListBox) diff --git a/GShr/LBoxGfx2.h b/GShr/LBoxGfx2.h index 1f8ea37b..e2263e72 100644 --- a/GShr/LBoxGfx2.h +++ b/GShr/LBoxGfx2.h @@ -25,11 +25,14 @@ #ifndef _LBOXGFX2_H #define _LBOXGFX2_H +#include + #ifndef _DRAGDROP_H #include "DragDrop.h" #endif #include "MapStrng.h" +#include "LBoxVHScrl.h" class CDrawObj; @@ -41,8 +44,8 @@ class CDrawObj; ///////////////////////////////////////////////////////////////////////////// // Custom Listbox - containing colors -#if 0 -class CGrafixListBox2 : public CListBox +#if 1 +class CGrafixListBox2 : public CB::VListBoxHScroll { // Construction public: @@ -58,7 +61,7 @@ class CGrafixListBox2 : public CListBox const CDrawObj& GetCurMapItem() const; std::vector> GetCurMappedItemList() const; BOOL IsMultiSelect() const - { return (GetStyle() & (LBS_EXTENDEDSEL | LBS_MULTIPLESEL)) != 0; } + { return HasMultipleSelection(); } // Note: the following pointer is only good during drag and drop. // the data is only good during the drop. It is essentially a // hack to have valid data when selecting items with Shift-Click. @@ -74,7 +77,7 @@ class CGrafixListBox2 : public CListBox void UpdateList(BOOL bKeepPosition = TRUE); void SetCurSelMapped(const CDrawObj& pMapVal); void SetCurSelsMapped(const std::vector>& items); - void SetSelFromPoint(CPoint point); + void SetSelFromPoint(wxPoint point); void ShowFirstSelection(); const CDrawObj& MapIndexToItem(size_t nIndex) const; CDrawObj& MapIndexToItem(size_t nIndex) @@ -86,19 +89,21 @@ class CGrafixListBox2 : public CListBox // Overrides - the subclass of this class must override these public: +#if 0 virtual CSize OnItemSize(size_t nIndex) const /* override */ = 0; virtual void OnItemDraw(CDC& pDC, size_t nIndex, UINT nAction, UINT nState, CRect rctItem) const /* override */ = 0; - virtual BOOL OnDragSetup(DragInfo& pDI) const /* override */ +#endif + virtual BOOL OnDragSetup(DragInfoWx& pDI) const /* override */ { pDI.SetDragType(DRAG_INVALID); return FALSE; } - virtual void OnDragCleanup(const DragInfo& pDI) const /* override */ { } + virtual void OnDragCleanup(const DragInfoWx& pDI) const /* override */ { } // For tool tip processing virtual BOOL OnIsToolTipsEnabled() const /* override */ { return FALSE; } - virtual GameElement OnGetHitItemCodeAtPoint(CPoint point, CRect& rct) const /* override */ { return Invalid_v; } + virtual GameElement OnGetHitItemCodeAtPoint(wxPoint point, wxRect& rct) const /* override */ { return Invalid_v; } virtual CB::string OnGetTipTextForItemCode(GameElement nItemCode) const /* override */ { return CB::string(); } // Implementation @@ -109,51 +114,70 @@ class CGrafixListBox2 : public CListBox std::vector> m_multiSelList; // Holds mapped multi select items on drop // Tool tip support - CToolTipCtrl m_toolTip; - GameElement m_nCurItemCode; + CB::ToolTip m_toolTip; // Tooltip of tile text popups + GameElement m_nCurItemCode = Invalid_v; + wxRect m_rectToolTip = wxRect(); // Drag and scroll support vars BOOL m_bAllowDrag; BOOL m_bAllowSelfDrop; // Only if m_bAllowDrag == TRUE BOOL m_bAllowDropScroll; // Scroll on OnDragItem - CPoint m_clickPoint; - uintptr_t m_nTimerID; + wxPoint m_clickPoint; +#if 0 + wxTimer m_nTimerID; +#endif BOOL m_triggeredCursor; - HWND m_hLastWnd; + wxWindow* m_hLastWnd; int m_nLastInsert; // Last index with insert line void SetDocument(CGamDoc& doc) { m_pDoc = &doc; } - void DoInsertLineProcessing(const DragInfo& pdi); - void DoAutoScrollProcessing(const DragInfo& pdi); - void DoToolTipHitProcessing(CPoint point); + void DoInsertLineProcessing(const DragInfoWx& pdi); + void DoAutoScrollProcessing(const DragInfoWx& pdi); + void DoToolTipHitProcessing(wxPoint point); - CWnd* GetWindowFromPoint(CPoint point) const; - int SpecialItemFromPoint(CPoint pnt) const; + wxWindow* GetWindowFromPoint(wxPoint point); + int SpecialItemFromPoint(wxPoint pnt) const; void DrawInsert(int nIndex); void DrawSingle(int nIndex); - CPoint ClientToItem(CPoint point) const; - CRect ItemToClient(CRect rect) const; + wxPoint ClientToItem(wxPoint point) const + { + return CalcUnscrolledPosition(point); + } + wxRect ItemToClient(wxRect rect) const + { + return wxRect(CalcScrolledPosition(rect.GetTopLeft()), rect.GetSize()); + } // Overrides +#if 0 virtual void MeasureItem(LPMEASUREITEMSTRUCT lpMIS) override; virtual void DrawItem(LPDRAWITEMSTRUCT lpDIS) override; virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam) override; +#endif - //{{AFX_MSG(CGrafixListBox2) - afx_msg void OnLButtonDown(UINT nFlags, CPoint point); - afx_msg void OnMouseMove(UINT nFlags, CPoint point); - afx_msg void OnLButtonUp(UINT nFlags, CPoint point); - afx_msg void OnTimer(uintptr_t nIDEvent); - afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); - afx_msg LRESULT OnDragItem(WPARAM wParam, LPARAM lParam); - //}}AFX_MSG - DECLARE_MESSAGE_MAP() + void OnLButtonDown(wxMouseEvent& event); + void OnMouseMove(wxMouseEvent& event); + void OnLButtonUp(wxMouseEvent& event); +#if 0 + void OnTimer(wxTimerEvent& event); +#endif + void OnCreate(wxWindowCreateEvent& event); + void OnDragItem(DragDropEvent& event); + wxDECLARE_EVENT_TABLE(); private: CB::propagate_const m_pDoc = nullptr; + + /* wxWidgets does not support post-processing of events + (see https://docs.wxwidgets.org/stable/overview_events.html#overview_events_virtual), + so we need to use wxEvtHandler::CallAfter() to + approximate post-processing. */ + void PushPostProcessEvent(std::function&& f); + void ExecutePostProcessEvents(); + std::queue> postProcessEvents; }; #endif From 2276c2cd75510f4003dd871add4e1d2c65062b3d Mon Sep 17 00:00:00 2001 From: Bill Su Date: Thu, 4 Sep 2025 23:41:54 -0400 Subject: [PATCH 32/80] LBoxTileBase2: provide wx version --- GShr/LBoxTileBase2.cpp | 146 ++++++++++++++++------------------------- GShr/LBoxTileBase2.h | 22 +++---- 2 files changed, 66 insertions(+), 102 deletions(-) diff --git a/GShr/LBoxTileBase2.cpp b/GShr/LBoxTileBase2.cpp index 167c6d4d..58afe896 100644 --- a/GShr/LBoxTileBase2.cpp +++ b/GShr/LBoxTileBase2.cpp @@ -38,14 +38,11 @@ const int tileBorder = 3; const int tileGap = 6; -#if 0 ///////////////////////////////////////////////////////////////////////////// -BEGIN_MESSAGE_MAP(CTileBaseListBox2, CGrafixListBox2) - //{{AFX_MSG_MAP(CTileBaseListBox2) - ON_WM_CREATE() - //}}AFX_MSG_MAP -END_MESSAGE_MAP() +wxBEGIN_EVENT_TABLE(CTileBaseListBox2, CGrafixListBox2) + EVT_WINDOW_CREATE(OnCreate) +wxEND_EVENT_TABLE() ///////////////////////////////////////////////////////////////////////////// @@ -54,14 +51,14 @@ CTileBaseListBox2::CTileBaseListBox2() m_bDisplayIDs = AfxGetApp()->GetProfileInt("Settings"_cbstring, "DisplayIDs"_cbstring, 0); m_bTipMarkItems = TRUE; - m_sizeTipMark = CSize(0,0); + m_sizeTipMark = wxSize(0,0); } ///////////////////////////////////////////////////////////////////////////// -CSize CTileBaseListBox2::DoOnItemSize(size_t nItem, const std::vector& tids) const +wxSize CTileBaseListBox2::DoOnItemSize(size_t nItem, const std::vector& tids) const { - ASSERT(!tids.empty() && tids[size_t(0)] != nullTid); // At least one tile needs to exist + wxASSERT(!tids.empty() && tids[size_t(0)] != nullTid); // At least one tile needs to exist int nHt = 0; for (size_t i = size_t(0) ; i < tids.size() ; ++i) @@ -79,12 +76,10 @@ CSize CTileBaseListBox2::DoOnItemSize(size_t nItem, const std::vector& t BOOL bItemHasTipText = OnDoesItemHaveTipText(nItem); // only using DC for measurement, so const_cast safe - CClientDC pDC(const_cast(this)); - CRect rctItem(0, 0, 32000, 32000); + wxWindowDC pDC(const_cast(this)); + wxRect rctItem(0, 0, 32000, 32000); - pDC.SaveDC(); - - int x = rctItem.left + tileBorder; + int x = rctItem.GetLeft() + tileBorder; DrawTipMarker(pDC, rctItem, bItemHasTipText, x); DrawItemDebugIDCode(pDC, nItem, rctItem, false, x); @@ -93,51 +88,36 @@ CSize CTileBaseListBox2::DoOnItemSize(size_t nItem, const std::vector& t DrawTileImage(pDC, rctItem, false, x, tids[i]); } - pDC.RestoreDC(-1); - - return CSize(x, nHt); + return wxSize(x, nHt); } ///////////////////////////////////////////////////////////////////////////// -void CTileBaseListBox2::DoOnDrawItem(CDC& pDC, size_t nItem, UINT nAction, UINT nState, - CRect rctItem, const std::vector& tids) const +void CTileBaseListBox2::DoOnDrawItem(wxDC& pDC, size_t nItem, + wxRect rctItem, const std::vector& tids) const { - if (nAction & (ODA_DRAWENTIRE | ODA_SELECT)) - { - ASSERT(!tids.empty() && tids[size_t(0)] != nullTid); + wxASSERT(!tids.empty() && tids[size_t(0)] != nullTid); - BOOL bItemHasTipText = OnDoesItemHaveTipText(nItem); - - pDC.SaveDC(); - pDC.IntersectClipRect(&rctItem); - pDC.SetBkMode(TRANSPARENT); - - CBrush brBack(GetSysColor(nState & ODS_SELECTED ? - COLOR_HIGHLIGHT : COLOR_WINDOW)); - pDC.FillRect(&rctItem, &brBack); // Fill background color + BOOL bItemHasTipText = OnDoesItemHaveTipText(nItem); - pDC.SetTextColor(GetSysColor(nState & ODS_SELECTED ? - COLOR_HIGHLIGHTTEXT : COLOR_WINDOWTEXT)); + pDC.SetClippingRegion(rctItem); - int x = rctItem.left + tileBorder; + pDC.SetTextForeground(wxSystemSettings::GetColour(IsSelected(nItem) ? + wxSYS_COLOUR_HIGHLIGHTTEXT : wxSYS_COLOUR_WINDOWTEXT)); - DrawTipMarker(pDC, rctItem, bItemHasTipText, x); - DrawItemDebugIDCode(pDC, nItem, rctItem, TRUE, x); - for (size_t i = size_t(0); i < tids.size(); ++i) - { - DrawTileImage(pDC, rctItem, true, x, tids[i]); - } + wxCoord x = rctItem.GetLeft() + tileBorder; - pDC.RestoreDC(-1); + DrawTipMarker(pDC, rctItem, bItemHasTipText, x); + DrawItemDebugIDCode(pDC, nItem, rctItem, TRUE, x); + for (size_t i = size_t(0); i < tids.size(); ++i) + { + DrawTileImage(pDC, rctItem, true, x, tids[i]); } - if (nAction & ODA_FOCUS) - pDC.DrawFocusRect(&rctItem); } ///////////////////////////////////////////////////////////////////////////// -void CTileBaseListBox2::DrawTileImage(CDC& pDC, CRect rctItem, BOOL bDrawIt, int& x, TileID tid) const +void CTileBaseListBox2::DrawTileImage(wxDC& pDC, wxRect rctItem, BOOL bDrawIt, wxCoord& x, TileID tid) const { if (tid == nullTid) return; // Nothing to do @@ -146,10 +126,7 @@ void CTileBaseListBox2::DrawTileImage(CDC& pDC, CRect rctItem, BOOL bDrawIt, int if (bDrawIt) { - if (tile.GetHeight() >= 255) - tile.BitBlt(pDC, x, rctItem.top + tileBorder);// Too large. Don't draw vertically centered - else - tile.BitBlt(pDC, x, (rctItem.Height() - tile.GetHeight()) / 2 + rctItem.top); + tile.BitBlt(pDC, CalcScrolledX(x), (rctItem.GetHeight() - tile.GetHeight()) / 2 + rctItem.GetTop()); } x += tile.GetWidth() + tileGap; } @@ -158,19 +135,20 @@ void CTileBaseListBox2::DrawTileImage(CDC& pDC, CRect rctItem, BOOL bDrawIt, int // Optionally draw debug code string for item. If bDrawIt is false, // x is advanced the size of the string anyway but nothing is rendered -void CTileBaseListBox2::DrawItemDebugIDCode(CDC& pDC, size_t nItem, CRect rctItem, BOOL bDrawIt, int& x) const +void CTileBaseListBox2::DrawItemDebugIDCode(wxDC& pDC, size_t nItem, wxRect rctItem, BOOL bDrawIt, wxCoord& x) const { if (m_bDisplayIDs) { CB::string str = OnGetItemDebugString(nItem); - CFont* prvFont = (CFont*)pDC.SelectObject(CFont::FromHandle(g_res.h8ss)); - int y = rctItem.top + rctItem.Height() / 2 - + pDC.SetFont(g_res.h8ssWx); + wxCoord y = rctItem.GetTop() + rctItem.GetHeight() / 2 - (g_res.tm8ss.tmHeight + g_res.tm8ss.tmExternalLeading) / 2; if (bDrawIt) - pDC.TextOut(x, y, str); - x += pDC.GetTextExtent(str).cx; - pDC.SelectObject(prvFont); + { + pDC.DrawText(str, CalcScrolledX(x), y); + } + x += pDC.GetTextExtent(str).x; } } @@ -180,36 +158,32 @@ void CTileBaseListBox2::SetupTipMarkerIfRequired() { if (m_bTipMarkItems) { - ASSERT(m_hWnd != NULL); - if (m_sizeTipMark.cx == 0) + wxASSERT(GetHandle()); + if (m_sizeTipMark.x == 0) { // Hasn't been initialized yet. m_strTipMark = CB::string::LoadString(IDS_TIP_LBOXITEM_MARKER); - CDC* pDC = GetDC(); - - CFont* prvFont = (CFont*)pDC->SelectObject(CFont::FromHandle(g_res.h8ss)); - m_sizeTipMark.cx = pDC->GetTextExtent(m_strTipMark).cx; - m_sizeTipMark.cy = g_res.tm8ss.tmHeight + g_res.tm8ss.tmExternalLeading; - pDC->SelectObject(prvFont); + wxWindowDC pDC(this); - ReleaseDC(pDC); + pDC.SetFont(g_res.h8ssWx); + m_sizeTipMark.x = pDC.GetTextExtent(m_strTipMark).x; + m_sizeTipMark.y = g_res.tm8ss.tmHeight + g_res.tm8ss.tmExternalLeading; } } } -void CTileBaseListBox2::DrawTipMarker(CDC& pDC, CRect rctItem, BOOL bVisible, int& x) const +void CTileBaseListBox2::DrawTipMarker(wxDC& pDC, wxRect rctItem, BOOL bVisible, int& x) const { if (m_bTipMarkItems) { - CFont* prvFont = (CFont*)pDC.SelectObject(CFont::FromHandle(g_res.h8ss)); + pDC.SetFont(g_res.h8ssWx); if (bVisible) // Draw only if visible. Else just move 'x' { - int y = rctItem.top + (rctItem.Height() - m_sizeTipMark.cy) / 2; - pDC.TextOut(x, y, m_strTipMark); + wxCoord y = rctItem.GetTop() + (rctItem.GetHeight() - m_sizeTipMark.y) / 2; + pDC.DrawText(m_strTipMark, CalcScrolledX(x), y); } - x += m_sizeTipMark.cx; - pDC.SelectObject(prvFont); + x += m_sizeTipMark.x; } } @@ -220,49 +194,41 @@ CB::string CTileBaseListBox2::OnGetItemDebugString(size_t nItem) const ///////////////////////////////////////////////////////////////////////////// -std::vector CTileBaseListBox2::GetTileRectsForItem(size_t nItem, +std::vector CTileBaseListBox2::GetTileRectsForItem(size_t nItem, const std::vector& tids) const { - ASSERT(!tids.empty() && tids[size_t(0)] != nullTid); + wxASSERT(!tids.empty() && tids[size_t(0)] != nullTid); - CRect rctItem; - GetItemRect(value_preserving_cast(nItem), &rctItem); + wxRect rctItem = GetItemRect(nItem); - int x = rctItem.left + tileBorder; // Set starting x position + wxCoord x = CalcScrolledX(rctItem.GetLeft()) + tileBorder; // Set starting x position // Need to account for possible markers and debug strings // rendered to left of tile images // only using DC for measurement, so const_cast safe - CDC& pDC = CheckedDeref(const_cast(this)->GetDC()); + wxWindowDC pDC(const_cast(this)); DrawTipMarker(pDC, rctItem, FALSE, x); DrawItemDebugIDCode(pDC, nItem, rctItem, FALSE, x); - const_cast(this)->ReleaseDC(&pDC); - std::vector retval(tids.size()); + std::vector retval(tids.size()); for (size_t i = size_t(0) ; i < tids.size() ; ++i) { - retval[i].SetRectEmpty(); - retval[i].top = rctItem.top; // Set the top & bottom values - retval[i].bottom = rctItem.bottom; - retval[i].left = x; + retval[i].SetTop(rctItem.GetTop()); // Set the top & bottom values + retval[i].SetBottom(rctItem.GetBottom()); + retval[i].SetLeft(x); DrawTileImage(pDC, rctItem, FALSE, x, tids[i]); - retval[i].right = x; + retval[i].SetRight(x); } return retval; } -int CTileBaseListBox2::OnCreate(LPCREATESTRUCT lpCreateStruct) +void CTileBaseListBox2::OnCreate(wxWindowCreateEvent& event) { - int retval = CGrafixListBox2::OnCreate(lpCreateStruct); - if (retval == 0) - { - SetupTipMarkerIfRequired(); - } - return retval; + event.Skip(); + SetupTipMarkerIfRequired(); } -#endif ///////////////////////////////////////////////////////////////////////////// BEGIN_MESSAGE_MAP(CTileBaseListBox2Mfc, CGrafixListBox2Mfc) diff --git a/GShr/LBoxTileBase2.h b/GShr/LBoxTileBase2.h index 6a300402..119ddcb5 100644 --- a/GShr/LBoxTileBase2.h +++ b/GShr/LBoxTileBase2.h @@ -34,7 +34,7 @@ #include "Tile.h" #endif -#if 0 +#if 1 /////////////////////////////////////////////////////////////////////// class CTileBaseListBox2 : public CGrafixListBox2 @@ -51,21 +51,21 @@ class CTileBaseListBox2 : public CGrafixListBox2 BOOL m_bTipMarkItems; CB::string m_strTipMark; - CSize m_sizeTipMark; + wxSize m_sizeTipMark; // Helpers... protected: - void DrawTileImage(CDC& pDC, CRect rctItem, BOOL bDrawIt, int& x, TileID tid) const; - void DrawItemDebugIDCode(CDC& pDC, size_t nItem, CRect rctItem, BOOL bDrawIt, int& x) const; + void DrawTileImage(wxDC& pDC, wxRect rctItem, BOOL bDrawIt, wxCoord& x, TileID tid) const; + void DrawItemDebugIDCode(wxDC& pDC, size_t nItem, wxRect rctItem, BOOL bDrawIt, wxCoord& x) const; void SetupTipMarkerIfRequired(); - void DrawTipMarker(CDC& pDC, CRect rctItem, BOOL bVisible, int& x) const; + void DrawTipMarker(wxDC& pDC, wxRect rctItem, BOOL bVisible, int& x) const; - CSize DoOnItemSize(size_t nItem, const std::vector& tids) const; - void DoOnDrawItem(CDC& pDC, size_t nItem, UINT nAction, UINT nState, CRect rctItem, + wxSize DoOnItemSize(size_t nItem, const std::vector& tids) const; + void DoOnDrawItem(wxDC& pDC, size_t nItem, wxRect rctItem, const std::vector& tids) const; - std::vector GetTileRectsForItem(size_t nItem, const std::vector& tids) const; + std::vector GetTileRectsForItem(size_t nItem, const std::vector& tids) const; // Overrides... public: @@ -79,10 +79,8 @@ class CTileBaseListBox2 : public CGrafixListBox2 virtual const void* OnGetItemDebugIDCode(size_t nItem) const /* override */ { return &MapIndexToItem(nItem); } virtual CB::string OnGetItemDebugString(size_t nItem) const /* override */; - //{{AFX_MSG(CTileBaseListBox) - afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); - //}}AFX_MSG - DECLARE_MESSAGE_MAP() + void OnCreate(wxWindowCreateEvent& event); + wxDECLARE_EVENT_TABLE(); }; From 0838fe9828d9711a9c038f2fedcee67a4968b56b Mon Sep 17 00:00:00 2001 From: Bill Su Date: Fri, 5 Sep 2025 00:26:00 -0400 Subject: [PATCH 33/80] LBoxSlct: provide wx version --- GP/CBPlay.fbp | 52 ++++++++++ GP/CBPlay.xrc | 20 ++++ GP/LBoxSlct.cpp | 254 +++++++++++++++++++++++++----------------------- GP/LBoxSlct.h | 29 +++--- GShr/LibMfc.cpp | 12 +++ 5 files changed, 230 insertions(+), 137 deletions(-) diff --git a/GP/CBPlay.fbp b/GP/CBPlay.fbp index 9a5a2cd4..df491de3 100644 --- a/GP/CBPlay.fbp +++ b/GP/CBPlay.fbp @@ -15789,6 +15789,58 @@ 8=PV_SELCT_BOX MENU_PV_SELCT_BOX protected + + + 0 + 1 + Turn the selected piece over to the next side + wxID_ANY + wxITEM_NORMAL + &Next + ID_ACT_TURNOVER + none + + + + + + 0 + 1 + Turn the selected piece over to the prev side + wxID_ANY + wxITEM_NORMAL + &Prev + ID_ACT_TURNOVER_PREV + none + + + + + + 0 + 1 + Turn the selected piece over to a random side + wxID_ANY + wxITEM_NORMAL + &Random + ID_ACT_TURNOVER_RANDOM + none + + + + + + 0 + 1 + Turn the clicked piece over to the clicked side + wxID_ANY + wxITEM_NORMAL + &Clicked Side + ID_ACT_TURNOVER_SELECT + none + + + diff --git a/GP/CBPlay.xrc b/GP/CBPlay.xrc index 40590c72..3e0e8724 100644 --- a/GP/CBPlay.xrc +++ b/GP/CBPlay.xrc @@ -3028,6 +3028,26 @@ + + + + Turn the selected piece over to the next side + + + + + Turn the selected piece over to the prev side + + + + + Turn the selected piece over to a random side + + + + + Turn the clicked piece over to the clicked side + diff --git a/GP/LBoxSlct.cpp b/GP/LBoxSlct.cpp index 19f16037..241acd61 100644 --- a/GP/LBoxSlct.cpp +++ b/GP/LBoxSlct.cpp @@ -42,38 +42,38 @@ const int tileBorder = 3; const int tileGap = 6; -#if 0 ///////////////////////////////////////////////////////////////////////////// -BEGIN_MESSAGE_MAP(CSelectListBox, CTileBaseListBox2) - //{{AFX_MSG_MAP(CSelectListBox) - ON_REGISTERED_MESSAGE(WM_DRAGDROP, OnDragItem) - ON_WM_CONTEXTMENU() - ON_WM_INITMENUPOPUP() - ON_COMMAND_EX(ID_ACT_TURNOVER, OnActTurnOver) - ON_COMMAND_EX(ID_ACT_TURNOVER_PREV, OnActTurnOver) - ON_COMMAND_EX(ID_ACT_TURNOVER_RANDOM, OnActTurnOver) - ON_COMMAND_EX(ID_ACT_TURNOVER_SELECT, OnActTurnOver) - ON_UPDATE_COMMAND_UI(ID_ACT_TURNOVER, OnUpdateActTurnOver) - ON_UPDATE_COMMAND_UI(ID_ACT_TURNOVER_PREV, OnUpdateActTurnOver) - ON_UPDATE_COMMAND_UI(ID_ACT_TURNOVER_RANDOM, OnUpdateActTurnOver) - ON_UPDATE_COMMAND_UI(ID_ACT_TURNOVER_SELECT, OnUpdateActTurnOver) - //}}AFX_MSG_MAP -END_MESSAGE_MAP() +wxIMPLEMENT_DYNAMIC_CLASS(CSelectListBox, CTileBaseListBox2); + +wxBEGIN_EVENT_TABLE(CSelectListBox, CTileBaseListBox2) + EVT_DRAGDROP(OnDragItem) + EVT_CONTEXT_MENU(OnContextMenu) + EVT_MENU_OPEN(OnInitMenuPopup) + EVT_MENU(XRCID("ID_ACT_TURNOVER"), OnActTurnOver) + EVT_MENU(XRCID("ID_ACT_TURNOVER_PREV"), OnActTurnOver) + EVT_MENU(XRCID("ID_ACT_TURNOVER_RANDOM"), OnActTurnOver) + EVT_MENU(XRCID("ID_ACT_TURNOVER_SELECT"), OnActTurnOver) + EVT_UPDATE_UI(XRCID("ID_ACT_TURNOVER"), OnUpdateActTurnOver) + EVT_UPDATE_UI(XRCID("ID_ACT_TURNOVER_PREV"), OnUpdateActTurnOver) + EVT_UPDATE_UI(XRCID("ID_ACT_TURNOVER_RANDOM"), OnUpdateActTurnOver) + EVT_UPDATE_UI(XRCID("ID_ACT_TURNOVER_SELECT"), OnUpdateActTurnOver) +wxEND_EVENT_TABLE() ///////////////////////////////////////////////////////////////////////////// const CTileManager& CSelectListBox::GetTileManager() const { - ASSERT(m_pDoc != NULL); + wxASSERT(m_pDoc != NULL); return m_pDoc->GetTileManager(); } ///////////////////////////////////////////////////////////////////////////// -BOOL CSelectListBox::OnDragSetup(DragInfo& pDI) const +BOOL CSelectListBox::OnDragSetup(DragInfoWx& pDI) const { - ASSERT(!"untested code"); + wxASSERT(!"untested code"); +#if 0 if (GetCount() <= 1) { pDI.SetDragType(DRAG_INVALID); @@ -82,7 +82,7 @@ BOOL CSelectListBox::OnDragSetup(DragInfo& pDI) const if (!IsMultiSelect()) { - ASSERT(!"unreachable code"); + wxASSERT(!"unreachable code"); /* if this ever happens, rewrite like LBoxGrfx w/ list/single distinction m_multiSelList.clear(); @@ -93,23 +93,26 @@ BOOL CSelectListBox::OnDragSetup(DragInfo& pDI) const pDI.GetSubInfo().m_ptrArray = &GetMappedMultiSelectList(); pDI.m_hcsrSuggest = g_res.hcrDragTile; pDI.GetSubInfo().m_gamDoc = &*m_pDoc; +#endif return TRUE; } -LRESULT CSelectListBox::OnDragItem(WPARAM wParam, LPARAM lParam) +void CSelectListBox::OnDragItem(DragDropEvent& event) { - if (wParam != GetProcessId(GetCurrentProcess())) + if (event.GetProcessId() != wxGetProcessId()) { - return -1; + wxASSERT(!"bad event process"); + return; } - const DragInfo& pdi = CheckedDeref(reinterpret_cast(lParam)); + const DragInfoWx& pdi = event.GetDragInfo(); DoInsertLineProcessing(pdi); if (pdi.GetDragType() != DRAG_SELECTVIEW) - return -1; // Only our drops allowed + return; // Only our drops allowed ASSERT(!"untested code"); +#if 0 if (pdi.GetSubInfo().m_gamDoc != m_pDoc) return -1; // Only pieces from our document. @@ -130,40 +133,44 @@ LRESULT CSelectListBox::OnDragItem(WPARAM wParam, LPARAM lParam) } } return 1; +#endif } -void CSelectListBox::OnContextMenu(CWnd* /*pWnd*/, CPoint point) +void CSelectListBox::OnContextMenu(wxContextMenuEvent& event) { + const wxPoint& point = event.GetPosition(); // remember clicked side in case of ID_ACT_TURNOVER_SELECT - CPoint clientPoint(point); - ScreenToClient(&clientPoint); - CRect rect; + wxPoint clientPoint(point); + clientPoint = ScreenToClient(clientPoint); + wxRect rect; menuGameElement = OnGetHitItemCodeAtPoint(&CGamDoc::GetGameElementCodeForObject, clientPoint, rect); - CMenu bar; - if (bar.LoadMenuW(IDR_MENU_PLAYER_POPUPS)) + std::unique_ptr bar(wxXmlResource::Get()->LoadMenuBar("IDR_MENU_PLAYER_POPUPS")); + if (bar) { - CMenu& popup = *bar.GetSubMenu(MENU_PV_SELCT_BOX); - ASSERT(popup.m_hMenu != NULL); + int index = bar->FindMenu("8=PV_SELCT_BOX"); + wxASSERT(index != wxNOT_FOUND); + std::unique_ptr popup(bar->Remove(value_preserving_cast(index))); // Make sure we clean up even if exception is tossed. - TRY + try { - popup.TrackPopupMenu(TPM_LEFTBUTTON | - TPM_LEFTALIGN | - TPM_RIGHTBUTTON, - point.x, point.y, this); // Route commands through tray window + PopupMenu(&*popup, clientPoint); + } + catch (...) + { + wxASSERT(!"exception"); } - END_TRY } else { - ASSERT(!"LoadMenu error"); + wxASSERT(!"LoadMenuBar error"); } } -void CSelectListBox::OnInitMenuPopup(CMenu* pMenu, UINT /*nIndex*/, BOOL bSysMenu) +void CSelectListBox::OnInitMenuPopup(wxMenuEvent& event) { +#if 0 // based on CFrameWnd::OnInitMenuPopup() ASSERT(!bSysMenu); @@ -216,77 +223,82 @@ void CSelectListBox::OnInitMenuPopup(CMenu* pMenu, UINT /*nIndex*/, BOOL bSysMen } state.m_nIndexMax = nCount; } +#else + event.Skip(); +#endif } -BOOL CSelectListBox::OnActTurnOver(UINT id) +void CSelectListBox::OnActTurnOver(wxCommandEvent& event) { + int id = event.GetId(); CPlayBoardView& view = GetBoardView(); - switch (id) + if (id == XRCID("ID_ACT_TURNOVER") || + id == XRCID("ID_ACT_TURNOVER_PREV") || + id == XRCID("ID_ACT_TURNOVER_RANDOM")) { - case ID_ACT_TURNOVER: - case ID_ACT_TURNOVER_PREV: - case ID_ACT_TURNOVER_RANDOM: - { - bool b = view.OnCmdMsg(id, CN_COMMAND, nullptr, nullptr); - wxASSERT(b); - return b; - } - case ID_ACT_TURNOVER_SELECT: - { - const CPlayBoard& playBoard = CheckedDeref(view.GetPlayBoard()); + CB_VERIFY(CB::RelayProcessEvent(view, event)); + return; + } + else if (id == XRCID("ID_ACT_TURNOVER_SELECT")) + { + const CPlayBoard& playBoard = CheckedDeref(view.GetPlayBoard()); - m_pDoc->AssignNewMoveGroup(); + m_pDoc->AssignNewMoveGroup(); - PieceID pid = static_cast(menuGameElement); - auto it = std::find_if(GetItemMap()->begin(), - GetItemMap()->end(), - [pid](const RefPtr& drawObj) + PieceID pid = static_cast(menuGameElement); + auto it = std::find_if(GetItemMap()->begin(), + GetItemMap()->end(), + [pid](const RefPtr& drawObj) + { + if (drawObj->GetType() != CDrawObj::drawPieceObj) { - if (drawObj->GetType() != CDrawObj::drawPieceObj) - { - return false; - } - const CPieceObj& pieceObj = static_cast(*drawObj); - return pieceObj.m_pid == pid; - }); - wxASSERT(it != GetItemMap()->end()); - const CDrawObj& drawObj = **it; - wxASSERT(drawObj.GetType() == CDrawObj::drawPieceObj); - const CPieceObj& pieceObj = static_cast(drawObj); - size_t side = menuGameElement.GetSide(); - m_pDoc->InvertPlayingPieceOnBoard(pieceObj, playBoard, CPieceTable::fSelect, side); - - return true; - } - default: - AfxThrowInvalidArgException(); + return false; + } + const CPieceObj& pieceObj = static_cast(*drawObj); + return pieceObj.m_pid == pid; + }); + wxASSERT(it != GetItemMap()->end()); + const CDrawObj& drawObj = **it; + wxASSERT(drawObj.GetType() == CDrawObj::drawPieceObj); + const CPieceObj& pieceObj = static_cast(drawObj); + size_t side = menuGameElement.GetSide(); + m_pDoc->InvertPlayingPieceOnBoard(pieceObj, playBoard, CPieceTable::fSelect, side); + + return; + } + else + { + AfxThrowInvalidArgException(); } } -void CSelectListBox::OnUpdateActTurnOver(CCmdUI* pCmdUI) +void CSelectListBox::OnUpdateActTurnOver(wxUpdateUIEvent& pCmdUI) { - switch (pCmdUI->m_nID) + int id = pCmdUI.GetId(); + if (id == XRCID("ID_ACT_TURNOVER") || + id == XRCID("ID_ACT_TURNOVER_PREV") || + id == XRCID("ID_ACT_TURNOVER_RANDOM")) { - case ID_ACT_TURNOVER: - case ID_ACT_TURNOVER_PREV: - case ID_ACT_TURNOVER_RANDOM: - pCmdUI->DoUpdate(&GetBoardView(), TRUE); - break; - case ID_ACT_TURNOVER_SELECT: + CB_VERIFY(CB::RelayProcessEvent(GetBoardView(), pCmdUI)); + return; + } + else if (id == XRCID("ID_ACT_TURNOVER_SELECT")) + { + bool enable = menuGameElement != Invalid_v && + menuGameElement.IsAPiece(); + pCmdUI.Enable(enable); +#if 0 + if (pCmdUI->m_pSubMenu != NULL) { - bool enable = menuGameElement != Invalid_v && - menuGameElement.IsAPiece(); - pCmdUI->Enable(enable); - if (pCmdUI->m_pSubMenu != NULL) - { - // Need to handle menu that the submenu is connected to. - pCmdUI->m_pMenu->EnableMenuItem(pCmdUI->m_nIndex, - MF_BYPOSITION | (enable ? MF_ENABLED : (MF_DISABLED | MF_GRAYED))); - } - break; + // Need to handle menu that the submenu is connected to. + pCmdUI->m_pMenu->EnableMenuItem(pCmdUI->m_nIndex, + MF_BYPOSITION | (enable ? MF_ENABLED : (MF_DISABLED | MF_GRAYED))); } - default: - AfxThrowInvalidArgException(); +#endif + } + else + { + AfxThrowInvalidArgException(); } } @@ -298,32 +310,33 @@ BOOL CSelectListBox::OnIsToolTipsEnabled() const return m_pDoc->IsShowingObjectTips(); } -GameElement CSelectListBox::OnGetHitItemCodeAtPoint(CPoint point, CRect& rct) const +GameElement CSelectListBox::OnGetHitItemCodeAtPoint(wxPoint point, wxRect& rct) const { return OnGetHitItemCodeAtPoint(&CGamDoc::GetVerifiedGameElementCodeForObject, point, rct); } -GameElement CSelectListBox::OnGetHitItemCodeAtPoint(GetGameElementCodeForObject_t func, CPoint point, CRect& rct) const +GameElement CSelectListBox::OnGetHitItemCodeAtPoint(GetGameElementCodeForObject_t func, wxPoint point, wxRect& rct) const { point = ClientToItem(point); - BOOL bOutsideClient; - UINT nIndex = ItemFromPoint(point, bOutsideClient); - if (nIndex >= 65535 || GetCount() <= 0) + int nIndex = VirtualHitTest(point.y); + if (nIndex == wxNOT_FOUND) + { return Invalid_v; + } - std::vector tids = GetTileIDs(nIndex); - ASSERT(!tids.empty() && tids[size_t(0)] != nullTid); + std::vector tids = GetTileIDs(value_preserving_cast(nIndex)); + wxASSERT(!tids.empty() && tids[size_t(0)] != nullTid); - std::vector rcts = GetTileRectsForItem(value_preserving_cast(nIndex), tids); + std::vector rcts = GetTileRectsForItem(value_preserving_cast(nIndex), tids); for (size_t i = size_t(0); i < rcts.size(); ++i) { - ASSERT(!rcts[i].IsRectEmpty()); - if (rcts[i].PtInRect(point)) + wxASSERT(!rcts[i].IsEmpty()); + if (rcts[i].Contains(point)) { rct = ItemToClient(rcts[i]); - const CDrawObj& pObj = MapIndexToItem(nIndex); + const CDrawObj& pObj = MapIndexToItem(value_preserving_cast(nIndex)); if (pObj.GetType() == CDrawObj::drawPieceObj) { const CPieceObj& pieceObj = static_cast(pObj); @@ -398,26 +411,21 @@ CB::string CSelectListBox::OnGetItemDebugString(size_t nIndex) const ///////////////////////////////////////////////////////////////////////////// -CSize CSelectListBox::OnItemSize(size_t nIndex) const +wxSize CSelectListBox::GetItemSize(size_t nIndex) const { - ASSERT(m_pDoc != NULL); + wxASSERT(m_pDoc != NULL); std::vector tids = GetTileIDs(nIndex); - ASSERT(!tids.empty() && tids[size_t(0)] != nullTid); + wxASSERT(!tids.empty() && tids[size_t(0)] != nullTid); return DoOnItemSize(nIndex, tids); } -void CSelectListBox::OnItemDraw(CDC& pDC, size_t nIndex, UINT nAction, UINT nState, - CRect rctItem) const +void CSelectListBox::OnDrawItem(wxDC& pDC, const wxRect& rctItem, size_t nIndex) const { - // see https://docs.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-drawitemstruct - if (nIndex == size_t(UINT(-1))) - return; // Nothing to draw. - std::vector tids = GetTileIDs(nIndex); - ASSERT(!tids.empty() && tids[size_t(0)] != nullTid); - DoOnDrawItem(pDC, nIndex, nAction, nState, rctItem, tids); + wxASSERT(!tids.empty() && tids[size_t(0)] != nullTid); + DoOnDrawItem(pDC, nIndex, rctItem, tids); } // retval[0] is active face, followed by inactives @@ -468,19 +476,21 @@ std::vector CSelectListBox::GetTileIDs(size_t nIndex) const } else { - ASSERT(FALSE); // Shouldn't happen + wxASSERT(FALSE); // Shouldn't happen return std::vector(); } } const CPlayBoardView& CSelectListBox::GetBoardView() const { - CFrameWnd& frame = CheckedDeref(AFXGetParentFrame(this)); + wxWindow& view = CheckedDeref(GetParent()); + wxWindow& container = CheckedDeref(view.GetParent()); + CWnd& cwndContainer = CheckedDeref(CB::ToCWnd(container)); + CFrameWnd& frame = CheckedDeref(AFXGetParentFrame(&cwndContainer)); const CPlayBoardFrame& pbrdFrame = CheckedDeref(DYNAMIC_DOWNCAST(CPlayBoardFrame, &frame)); return pbrdFrame.GetActiveBoardView(); } -#endif ///////////////////////////////////////////////////////////////////////////// BEGIN_MESSAGE_MAP(CSelectListBoxMfc, CTileBaseListBox2Mfc) diff --git a/GP/LBoxSlct.h b/GP/LBoxSlct.h index 212f8795..b9724fc8 100644 --- a/GP/LBoxSlct.h +++ b/GP/LBoxSlct.h @@ -41,7 +41,7 @@ class CGamDoc; -#if 0 +#if 1 ///////////////////////////////////////////////////////////////////////////// class CSelectListBox : public CTileBaseListBox2 @@ -72,31 +72,28 @@ class CSelectListBox : public CTileBaseListBox2 std::vector GetTileIDs(size_t nIndex) const; // Overrides - virtual CSize OnItemSize(size_t nIndex) const override; - virtual void OnItemDraw(CDC& pDC, size_t nIndex, UINT nAction, UINT nState, - CRect rctItem) const override; - virtual BOOL OnDragSetup(DragInfo& pDI) const override; + wxSize GetItemSize(size_t nIndex) const override; + void OnDrawItem(wxDC& pDC, const wxRect& rctItem, size_t nIndex) const override; + virtual BOOL OnDragSetup(DragInfoWx& pDI) const override; virtual CB::string OnGetItemDebugString(size_t nItem) const override; // Tool tip processing virtual BOOL OnIsToolTipsEnabled() const override; - virtual GameElement OnGetHitItemCodeAtPoint(CPoint point, CRect& rct) const override; + virtual GameElement OnGetHitItemCodeAtPoint(wxPoint point, wxRect& rct) const override; private: typedef GameElement (CGamDoc::*GetGameElementCodeForObject_t)(const CDrawObj& pDObj, size_t nSide) const; - GameElement OnGetHitItemCodeAtPoint(GetGameElementCodeForObject_t func, CPoint point, CRect& rct) const; + GameElement OnGetHitItemCodeAtPoint(GetGameElementCodeForObject_t func, wxPoint point, wxRect& rct) const; public: virtual CB::string OnGetTipTextForItemCode(GameElement nItemCode) const override; virtual BOOL OnDoesItemHaveTipText(size_t nItem) const override; - //{{AFX_MSG(CSelectListBox) - afx_msg LRESULT OnDragItem(WPARAM wParam, LPARAM lParam); - afx_msg void OnContextMenu(CWnd* pWnd, CPoint point); - afx_msg void OnInitMenuPopup(CMenu* pPopupMenu, UINT nIndex, BOOL bSysMenu); - afx_msg BOOL OnActTurnOver(UINT id); - afx_msg void OnUpdateActTurnOver(CCmdUI* pCmdUI); - //}}AFX_MSG - DECLARE_MESSAGE_MAP() + void OnDragItem(DragDropEvent& event); + void OnContextMenu(wxContextMenuEvent& event); + void OnInitMenuPopup(wxMenuEvent& event); + void OnActTurnOver(wxCommandEvent& event); + void OnUpdateActTurnOver(wxUpdateUIEvent& pCmdUI); + wxDECLARE_EVENT_TABLE(); private: const CPlayBoardView& GetBoardView() const; @@ -104,6 +101,8 @@ class CSelectListBox : public CTileBaseListBox2 { return const_cast(std::as_const(*this).GetBoardView()); } + + wxDECLARE_DYNAMIC_CLASS(CSelectListBox); }; #endif diff --git a/GShr/LibMfc.cpp b/GShr/LibMfc.cpp index d2b8e552..26723077 100644 --- a/GShr/LibMfc.cpp +++ b/GShr/LibMfc.cpp @@ -1318,6 +1318,14 @@ namespace CB #if defined(GPLAY) switch (id) { + case ID_ACT_TURNOVER: + return XRCID("ID_ACT_TURNOVER"); + case ID_ACT_TURNOVER_PREV: + return XRCID("ID_ACT_TURNOVER_PREV"); + case ID_ACT_TURNOVER_RANDOM: + return XRCID("ID_ACT_TURNOVER_RANDOM"); + case ID_ACT_TURNOVER_SELECT: + return XRCID("ID_ACT_TURNOVER_SELECT"); case ID_EDIT_BRDPROP: return XRCID("ID_EDIT_BRDPROP"); case ID_PPROJITEM_DELETE: @@ -1562,6 +1570,10 @@ namespace CB { XRCID("ID_TOOLS_ROT180"), ID_TOOLS_ROT180 }, { XRCID("ID_TOOLS_ROT270"), ID_TOOLS_ROT270 }, #else + { XRCID("ID_ACT_TURNOVER"), ID_ACT_TURNOVER }, + { XRCID("ID_ACT_TURNOVER_PREV"), ID_ACT_TURNOVER_PREV }, + { XRCID("ID_ACT_TURNOVER_RANDOM"), ID_ACT_TURNOVER_RANDOM }, + { XRCID("ID_ACT_TURNOVER_SELECT"), ID_ACT_TURNOVER_SELECT }, { XRCID("ID_EDIT_CREATE_GEOMORPHIC"), ID_EDIT_CREATE_GEOMORPHIC }, { XRCID("ID_EDIT_CREATETRAY"), ID_EDIT_CREATETRAY }, { XRCID("ID_EDIT_SELECTBOARDS"), ID_EDIT_SELECTBOARDS }, From a152c7a13ebc778d9a36e04618b50abd33ff3b4e Mon Sep 17 00:00:00 2001 From: Bill Su Date: Sun, 21 Sep 2025 23:20:37 -0400 Subject: [PATCH 34/80] VwSelpce: replace MFC with wx --- GP/VwSelpce.cpp | 164 +++++++++++++++++++++++------------------------- GP/VwSelpce.h | 65 ++++++++++++------- 2 files changed, 123 insertions(+), 106 deletions(-) diff --git a/GP/VwSelpce.cpp b/GP/VwSelpce.cpp index 82016768..fc4528c6 100644 --- a/GP/VwSelpce.cpp +++ b/GP/VwSelpce.cpp @@ -36,6 +36,7 @@ static char THIS_FILE[] = __FILE__; #endif +// KLUDGE: compile fails for base CSelectedPieceViewContainer::BASE IMPLEMENT_DYNCREATE(CSelectedPieceViewContainer, CView) #ifdef _DEBUG @@ -44,18 +45,21 @@ IMPLEMENT_DYNCREATE(CSelectedPieceViewContainer, CView) ///////////////////////////////////////////////////////////////////////////// -BEGIN_MESSAGE_MAP(CSelectedPieceView, CView) - //{{AFX_MSG_MAP(CSelectedPieceView) +wxBEGIN_EVENT_TABLE(CSelectedPieceView, CSelectedPieceView::BASE) +#if 0 ON_WM_CREATE() - ON_WM_SIZE() - ON_WM_ERASEBKGND() +#endif + EVT_SIZE(OnSize) +#if 0 ON_WM_MOUSEACTIVATE() +#endif + /* see ctor ON_WM_VKEYTOITEM() - //}}AFX_MSG_MAP - ON_MESSAGE(WM_WINSTATE, OnMessageWindowState) -END_MESSAGE_MAP() + */ + EVT_WINSTATE(OnMessageWindowState) +wxEND_EVENT_TABLE() -BEGIN_MESSAGE_MAP(CSelectedPieceViewContainer, CView) +BEGIN_MESSAGE_MAP(CSelectedPieceViewContainer, CSelectedPieceViewContainer::BASE) ON_WM_CREATE() ON_WM_SIZE() ON_WM_MOUSEACTIVATE() @@ -65,9 +69,26 @@ END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CSelectedPieceView -CSelectedPieceView::CSelectedPieceView() +CSelectedPieceView::CSelectedPieceView(CSelectedPieceViewContainer& p) : + parent(&p), + document(dynamic_cast(parent->GetDocument())), + m_pPBoard(static_cast(document->GetNewViewParameter())), + m_listSel(new CSelectListBox) { - m_pPBoard = NULL; + BASE::Create(*parent, 0); + m_listSel->Create(this, wxID_ANY, + wxDefaultPosition, wxDefaultSize, + wxLB_MULTIPLE); + /* wx doesn't support WM_VKEYTOITEM, + and wxEVT_CHAR doesn't propagate to parent */ + m_listSel->Bind(wxEVT_CHAR, &CSelectedPieceView::OnVKeyToItem, this); + + CB::string str = CB::string::LoadString(IDS_TIP_SELLIST_HELP); + m_toolTip.Add(*m_listSel, str, CB::ToolTip::CENTER); + + m_toolTip.Enable(TRUE); + + OnInitialUpdate(); } CSelectedPieceView::~CSelectedPieceView() @@ -76,6 +97,7 @@ CSelectedPieceView::~CSelectedPieceView() ///////////////////////////////////////////////////////////////////////////// +#if 0 int CSelectedPieceView::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CView::OnCreate(lpCreateStruct) == -1) @@ -104,33 +126,21 @@ int CSelectedPieceView::OnCreate(LPCREATESTRUCT lpCreateStruct) return 0; } +#endif -void CSelectedPieceView::OnSize(UINT nType, int cx, int cy) -{ - CView::OnSize(nType, cx, cy); - m_listSel.MoveWindow(-1, -1, cx + 1, cy + 1, TRUE); - m_toolTip.SetMaxTipWidth(4 * cx); -} - -///////////////////////////////////////////////////////////////////////////// - -BOOL CSelectedPieceView::PreTranslateMessage(MSG* pMsg) +void CSelectedPieceView::OnSize(wxSizeEvent& event) { - // RelayEvent is required for CToolTipCtrl objects - - // it passes mouse messages on to the tool tip control - // so it can decide when to show the tool tip - m_toolTip.RelayEvent(pMsg); - - return CView::PreTranslateMessage(pMsg); + event.Skip(); + m_listSel->SetSize(0, 0, event.GetSize().x, event.GetSize().y); + m_toolTip.SetMaxWidth(4 * event.GetSize().x); } ///////////////////////////////////////////////////////////////////////////// void CSelectedPieceView::OnInitialUpdate() { - m_pPBoard = static_cast(GetDocument().GetNewViewParameter()); - CView::OnInitialUpdate(); - m_listSel.SetDocument(GetDocument()); + parent->OnInitialUpdate(); + m_listSel->SetDocument(GetDocument()); } void CSelectedPieceView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint) @@ -138,28 +148,28 @@ void CSelectedPieceView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint) CGamDocHint* ph = (CGamDocHint*)pHint; if (lHint == HINT_UPDATESELECT && ph->GetArgs().m_pPBoard == m_pPBoard) { - ASSERT(ph->GetArgs().m_pSelList != NULL); + wxASSERT(ph->GetArgs().m_pSelList != NULL); CSelList* pSLst = ph->GetArgs().m_pSelList; if (!pSLst->HasPieces() && !pSLst->HasMarkers()) { - m_listSel.SetItemMap(NULL); + m_listSel->SetItemMap(NULL); m_tblSel.clear(); return; } pSLst->LoadTableWithObjectPtrs(m_tblSel, CSelList::otPiecesMarks, TRUE); - m_listSel.SetItemMap(&m_tblSel); + m_listSel->SetItemMap(&m_tblSel); } else if (lHint == HINT_GAMESTATEUSED) { - m_listSel.SetItemMap(NULL); + m_listSel->SetItemMap(NULL); m_tblSel.clear(); return; } else if (lHint == HINT_UPDATEOBJECT && ph->GetArgs().m_pPBoard == m_pPBoard) { - Invalidate(); + Refresh(); } } @@ -167,95 +177,81 @@ void CSelectedPieceView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint) // This message is sent when a document is being saved. // WPARAM = CArchive*, LPARAM = 0 if save, 1 if restore -LRESULT CSelectedPieceView::OnMessageWindowState(WPARAM wParam, LPARAM lParam) +void CSelectedPieceView::OnMessageWindowState(WinStateEvent& /*event*/) { - return (LRESULT)0; } ///////////////////////////////////////////////////////////////////////////// // CSelectedPieceView drawing -void CSelectedPieceView::OnDraw(CDC* pDC) -{ - // Eat this since view is filled with a list box. -} - -BOOL CSelectedPieceView::OnEraseBkgnd(CDC* pDC) -{ - // Eat this since view is filled with a list box. - return TRUE; -} - ///////////////////////////////////////////////////////////////////////////// #ifdef _DEBUG CGamDoc& CSelectedPieceView::GetDocument() // non-debug version is inline { - CGamDoc* retval = CB::ToCGamDoc(m_pDocument); - return CheckedDeref(retval); + return *document; } #endif //_DEBUG ///////////////////////////////////////////////////////////////////////////// // CSelectedPieceView message handlers +#if 0 int CSelectedPieceView::OnMouseActivate(CWnd* pDesktopWnd, UINT nHitTest, UINT message) { // We don't want the frame to ever consider this view to be the // "active" view. return CWnd::OnMouseActivate(pDesktopWnd, nHitTest, message); } +#endif -int CSelectedPieceView::OnVKeyToItem(UINT nKey, CListBox* pListBox, UINT nIndex) +void CSelectedPieceView::OnVKeyToItem(wxKeyEvent& event) { - if (nKey == VK_DELETE) + int nKey = event.GetKeyCode(); + if (nKey == WXK_DELETE) { ModifySelectionsBasedOnListItems(TRUE); - return -2; } - else if (nKey == VK_INSERT) + else if (nKey == WXK_INSERT) { ModifySelectionsBasedOnListItems(FALSE); - return -2; } else - return CView::OnVKeyToItem(nKey, pListBox, nIndex); + { + event.Skip(); + } } // Either removes or keeps items selected in listbox. void CSelectedPieceView::ModifySelectionsBasedOnListItems(BOOL bRemoveSelectedItems) { // Get the indexes of all the selected items. - int nCount = m_listSel.GetSelCount(); - CArray tblListBoxSel; - - tblListBoxSel.SetSize(nCount); - m_listSel.GetSelItems(nCount, tblListBoxSel.GetData()); + std::vector tblListBoxSel = m_listSel->GetSelections(); // Create a list containing all items that are *not* selected. // Rather than try to be real clever I'll just brute force the search. std::vector> listDObj; - for (int nItem = 0; nItem < m_listSel.GetCount(); nItem++) + for (size_t nItem = size_t(0) ; nItem < m_listSel->GetItemCount() ; ++nItem) { // Loop and see if item is in selected list. - int nSelItem; - for (nSelItem = 0; nSelItem < tblListBoxSel.GetSize(); nSelItem++) + size_t nSelItem; + for (nSelItem = size_t(0) ; nSelItem < tblListBoxSel.size() ; ++nSelItem) { - if (tblListBoxSel.GetAt(nSelItem) == nItem) + if (tblListBoxSel.at(nSelItem) == nItem) break; } - if (bRemoveSelectedItems && nSelItem == tblListBoxSel.GetSize()) + if (bRemoveSelectedItems && nSelItem == tblListBoxSel.size()) { // Not a listbox selection so add it to new select list. - listDObj.push_back(&m_listSel.MapIndexToItem(value_preserving_cast(nItem))); + listDObj.push_back(&m_listSel->MapIndexToItem(nItem)); } - else if (!bRemoveSelectedItems && nSelItem < tblListBoxSel.GetSize()) + else if (!bRemoveSelectedItems && nSelItem < tblListBoxSel.size()) { // It is a listbox selection so add it to new select list. - listDObj.push_back(&m_listSel.MapIndexToItem(value_preserving_cast(nItem))); + listDObj.push_back(&m_listSel->MapIndexToItem(nItem)); } } - CPlayBoardFrame* pFrame = (CPlayBoardFrame*)GetParentFrame(); + CPlayBoardFrame* pFrame = static_cast(parent->GetParentFrame()); pFrame->SendMessageToActiveBoardPane(WM_SELECT_BOARD_OBJLIST, (WPARAM)&*m_pPBoard, (LPARAM)&listDObj); } @@ -265,37 +261,34 @@ void CSelectedPieceViewContainer::OnDraw(CDC* pDC) // do nothing because child covers entire client rect } +void CSelectedPieceViewContainer::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint) +{ + child->OnUpdate(pSender, lHint, pHint); + + BASE::OnUpdate(pSender, lHint, pHint); +} + CSelectedPieceViewContainer::CSelectedPieceViewContainer() : - child(new CSelectedPieceView) + CB::wxNativeContainerWindowMixin(static_cast(*this)) { } int CSelectedPieceViewContainer::OnCreate(LPCREATESTRUCT lpCreateStruct) { - if (CView::OnCreate(lpCreateStruct) == -1) + if (BASE::OnCreate(lpCreateStruct) == -1) { return -1; } - DWORD dwStyle = AFX_WS_DEFAULT_VIEW & ~WS_BORDER; - // Create with the right size (wrong position) - CRect rect; - GetClientRect(rect); - CCreateContext context; - context.m_pCurrentDoc = GetDocument(); - if (!child->Create(NULL, NULL, dwStyle, - rect, this, 0, &context)) - { - return -1; - } + child = new CSelectedPieceView(*this); return 0; } void CSelectedPieceViewContainer::OnSize(UINT nType, int cx, int cy) { - child->MoveWindow(0, 0, cx, cy); - return CView::OnSize(nType, cx, cy); + child->SetSize(0, 0, cx, cy); + return BASE::OnSize(nType, cx, cy); } int CSelectedPieceViewContainer::OnMouseActivate(CWnd* pDesktopWnd, UINT nHitTest, UINT message) @@ -307,7 +300,8 @@ int CSelectedPieceViewContainer::OnMouseActivate(CWnd* pDesktopWnd, UINT nHitTes LRESULT CSelectedPieceViewContainer::OnMessageWindowState(WPARAM wParam, LPARAM lParam) { - child->SendMessage(WM_WINSTATE, wParam, lParam); + WinStateEvent event(*reinterpret_cast(wParam), bool(lParam)); + child->ProcessWindowEvent(event); return (LRESULT)1; } diff --git a/GP/VwSelpce.h b/GP/VwSelpce.h index c3eecdf9..2c7e91e4 100644 --- a/GP/VwSelpce.h +++ b/GP/VwSelpce.h @@ -31,11 +31,12 @@ class CPlayBoard; ///////////////////////////////////////////////////////////////////////////// // CSelectedPieceView view -class CSelectedPieceView : public CView +class CSelectedPieceView : public CB::ProcessEventOverride { private: friend class CSelectedPieceViewContainer; - CSelectedPieceView(); // protected constructor used by dynamic creation + typedef CB::ProcessEventOverride BASE; + CSelectedPieceView(CSelectedPieceViewContainer& parent); // Attributes private: @@ -45,46 +46,55 @@ class CSelectedPieceView : public CView public: // Implementation +private: + RefPtr parent; + RefPtr document; protected: - CB::propagate_const m_pPBoard; // Board that contains selections + RefPtr m_pPBoard; // Board that contains selections - CSelectListBoxMfc m_listSel; + // owned by wx + RefPtr m_listSel; std::vector> m_tblSel; - CToolTipCtrl m_toolTip; + CB::ToolTip m_toolTip; // Implementation protected: void ModifySelectionsBasedOnListItems(BOOL bRemoveSelectedItems); ~CSelectedPieceView() override; - void OnDraw(CDC* pDC) override; // overridden to draw this view - void OnInitialUpdate() override; - void OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint) override; - BOOL PreTranslateMessage(MSG* pMsg) override; + void OnInitialUpdate(); // first time after construct + void OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint); -// Generated message map functions protected: - //{{AFX_MSG(CSelectedPieceView) +#if 0 afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); - afx_msg void OnSize(UINT nType, int cx, int cy); - afx_msg BOOL OnEraseBkgnd(CDC* pDC); +#endif + void OnSize(wxSizeEvent& event); +#if 0 afx_msg int OnMouseActivate(CWnd* pDesktopWnd, UINT nHitTest, UINT message); - afx_msg int OnVKeyToItem(UINT nKey, CListBox* pListBox, UINT nIndex); - //}}AFX_MSG - afx_msg LRESULT OnMessageWindowState(WPARAM wParam, LPARAM lParam); - DECLARE_MESSAGE_MAP() +#endif + void OnVKeyToItem(wxKeyEvent& event); + void OnMessageWindowState(WinStateEvent& event); + wxDECLARE_EVENT_TABLE(); + +private: + // IGetCmdTarget + CCmdTarget& Get() override; }; #ifndef _DEBUG // debug version in vwselpce.cpp inline CGamDoc& CSelectedPieceView::GetDocument() - { return CheckedDeref(CB::ToCGamDoc(m_pDocument)); } + { return *document; } #endif -class CSelectedPieceViewContainer : public CView +class CSelectedPieceViewContainer : public CB::OnCmdMsgOverride, + public CB::wxNativeContainerWindowMixin { public: void OnDraw(CDC* pDC) override; + void OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint) override; + private: CSelectedPieceViewContainer(); // used by dynamic creation DECLARE_DYNCREATE(CSelectedPieceViewContainer) @@ -95,6 +105,19 @@ class CSelectedPieceViewContainer : public CView afx_msg LRESULT OnMessageWindowState(WPARAM wParam, LPARAM lParam); DECLARE_MESSAGE_MAP() - // owned by MFC - RefPtr child; + // IGetEvtHandler + wxEvtHandler& Get() override + { + return CheckedDeref(CheckedDeref(child).GetEventHandler()); + } + + // owned by wx + CB::propagate_const child = nullptr; + + typedef CB::OnCmdMsgOverride BASE; }; + +inline CCmdTarget& CSelectedPieceView::Get() +{ + return *parent; +} From 456a476c64f3e20d3df007cdfc5b0a7429f0755f Mon Sep 17 00:00:00 2001 From: Bill Su Date: Mon, 22 Sep 2025 00:46:10 -0400 Subject: [PATCH 35/80] LBoxGfx2/LBoxTileBase2/LBoxSlct/LBoxTile: remove obsolete MFC version --- GM/LBoxTile.cpp | 2 + GP/LBoxSlct.cpp | 437 -------------------------- GP/LBoxSlct.h | 67 ---- GShr/LBoxGfx2.cpp | 681 ----------------------------------------- GShr/LBoxGfx2.h | 117 ------- GShr/LBoxTileBase2.cpp | 223 -------------- GShr/LBoxTileBase2.h | 53 ---- 7 files changed, 2 insertions(+), 1578 deletions(-) diff --git a/GM/LBoxTile.cpp b/GM/LBoxTile.cpp index 1963d7c1..5f294f47 100644 --- a/GM/LBoxTile.cpp +++ b/GM/LBoxTile.cpp @@ -34,6 +34,7 @@ const int tileBorder = 3; ///////////////////////////////////////////////////////////////////////////// +#if 0 BEGIN_MESSAGE_MAP(CTileListBox, CGrafixListBox) //{{AFX_MSG_MAP(CTileListBox) //}}AFX_MSG_MAP @@ -171,6 +172,7 @@ BOOL CTileListBox::OnDragSetup(DragInfo& pDI) const } return TRUE; } +#endif ///////////////////////////////////////////////////////////////////////////// diff --git a/GP/LBoxSlct.cpp b/GP/LBoxSlct.cpp index 241acd61..f437e4cb 100644 --- a/GP/LBoxSlct.cpp +++ b/GP/LBoxSlct.cpp @@ -491,440 +491,3 @@ const CPlayBoardView& CSelectListBox::GetBoardView() const return pbrdFrame.GetActiveBoardView(); } -///////////////////////////////////////////////////////////////////////////// - -BEGIN_MESSAGE_MAP(CSelectListBoxMfc, CTileBaseListBox2Mfc) - //{{AFX_MSG_MAP(CSelectListBox) - ON_REGISTERED_MESSAGE(WM_DRAGDROP, OnDragItem) - ON_WM_CONTEXTMENU() - ON_WM_INITMENUPOPUP() - ON_COMMAND_EX(ID_ACT_TURNOVER, OnActTurnOver) - ON_COMMAND_EX(ID_ACT_TURNOVER_PREV, OnActTurnOver) - ON_COMMAND_EX(ID_ACT_TURNOVER_RANDOM, OnActTurnOver) - ON_COMMAND_EX(ID_ACT_TURNOVER_SELECT, OnActTurnOver) - ON_UPDATE_COMMAND_UI(ID_ACT_TURNOVER, OnUpdateActTurnOver) - ON_UPDATE_COMMAND_UI(ID_ACT_TURNOVER_PREV, OnUpdateActTurnOver) - ON_UPDATE_COMMAND_UI(ID_ACT_TURNOVER_RANDOM, OnUpdateActTurnOver) - ON_UPDATE_COMMAND_UI(ID_ACT_TURNOVER_SELECT, OnUpdateActTurnOver) - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - -///////////////////////////////////////////////////////////////////////////// - -const CTileManager& CSelectListBoxMfc::GetTileManager() const -{ - ASSERT(m_pDoc != NULL); - return m_pDoc->GetTileManager(); -} - -///////////////////////////////////////////////////////////////////////////// - -BOOL CSelectListBoxMfc::OnDragSetup(DragInfo& pDI) const -{ - ASSERT(!"untested code"); - if (GetCount() <= 1) - { - pDI.SetDragType(DRAG_INVALID); - return FALSE; - } - - if (!IsMultiSelect()) - { - ASSERT(!"unreachable code"); - /* if this ever happens, rewrite like LBoxGrfx w/ - list/single distinction - m_multiSelList.clear(); - m_multiSelList.push_back(&GetCurMapItem()); - */ - } - pDI.SetDragType(DRAG_SELECTVIEW); - pDI.GetSubInfo().m_ptrArray = &GetMappedMultiSelectList(); - pDI.m_hcsrSuggest = g_res.hcrDragTile; - pDI.GetSubInfo().m_gamDoc = &*m_pDoc; - return TRUE; -} - -LRESULT CSelectListBoxMfc::OnDragItem(WPARAM wParam, LPARAM lParam) -{ - if (wParam != GetProcessId(GetCurrentProcess())) - { - return -1; - } - const DragInfo& pdi = CheckedDeref(reinterpret_cast(lParam)); - - DoInsertLineProcessing(pdi); - - if (pdi.GetDragType() != DRAG_SELECTVIEW) - return -1; // Only our drops allowed - - ASSERT(!"untested code"); - if (pdi.GetSubInfo().m_gamDoc != m_pDoc) - return -1; // Only pieces from our document. - - // no size restriction - - DoAutoScrollProcessing(pdi); - - if (pdi.m_phase == PhaseDrag::Over) - return (LRESULT)(LPVOID)pdi.m_hcsrSuggest; - else if (pdi.m_phase == PhaseDrag::Drop) - { - int nSel = SpecialItemFromPoint(pdi.m_point); - - if (nSel < GetCount()) - { - // If the selection is out of view, force it into view. - MakeItemVisible(nSel); - } - } - return 1; -} - -void CSelectListBoxMfc::OnContextMenu(CWnd* /*pWnd*/, CPoint point) -{ - // remember clicked side in case of ID_ACT_TURNOVER_SELECT - CPoint clientPoint(point); - ScreenToClient(&clientPoint); - CRect rect; - menuGameElement = OnGetHitItemCodeAtPoint(&CGamDoc::GetGameElementCodeForObject, clientPoint, rect); - - CMenu bar; - if (bar.LoadMenuW(IDR_MENU_PLAYER_POPUPS)) - { - CMenu& popup = *bar.GetSubMenu(MENU_PV_SELCT_BOX); - ASSERT(popup.m_hMenu != NULL); - - // Make sure we clean up even if exception is tossed. - TRY - { - popup.TrackPopupMenu(TPM_LEFTBUTTON | - TPM_LEFTALIGN | - TPM_RIGHTBUTTON, - point.x, point.y, this); // Route commands through tray window - } - END_TRY - } - else - { - ASSERT(!"LoadMenu error"); - } -} - -void CSelectListBoxMfc::OnInitMenuPopup(CMenu* pMenu, UINT /*nIndex*/, BOOL bSysMenu) -{ - // based on CFrameWnd::OnInitMenuPopup() - ASSERT(!bSysMenu); - - CCmdUI state; - state.m_pMenu = pMenu; - ASSERT(state.m_pOther == NULL); - ASSERT(state.m_pParentMenu == NULL); - - state.m_nIndexMax = pMenu->GetMenuItemCount(); - for (state.m_nIndex = 0; state.m_nIndex < state.m_nIndexMax; - state.m_nIndex++) - { - state.m_nID = pMenu->GetMenuItemID(state.m_nIndex); - if (state.m_nID == 0) - continue; // menu separator or invalid cmd - ignore it - - ASSERT(state.m_pOther == NULL); - ASSERT(state.m_pMenu != NULL); - if (state.m_nID == (UINT)-1) - { - // possibly a popup menu, route to first item of that popup - state.m_pSubMenu = pMenu->GetSubMenu(state.m_nIndex); - if (state.m_pSubMenu == NULL || - (state.m_nID = state.m_pSubMenu->GetMenuItemID(0)) == 0 || - state.m_nID == (UINT)-1) - { - continue; // first item of popup can't be routed to - } - state.DoUpdate(this, FALSE); // popups are never auto disabled - } - else - { - // normal menu item - // Auto enable/disable if frame window has 'm_bAutoMenuEnable' - // set and command is _not_ a system command. - state.m_pSubMenu = NULL; - state.DoUpdate(this, true); - } - - // adjust for menu deletions and additions - UINT nCount = pMenu->GetMenuItemCount(); - if (nCount < state.m_nIndexMax) - { - state.m_nIndex -= (state.m_nIndexMax - nCount); - while (state.m_nIndex < nCount && - pMenu->GetMenuItemID(state.m_nIndex) == state.m_nID) - { - state.m_nIndex++; - } - } - state.m_nIndexMax = nCount; - } -} - -BOOL CSelectListBoxMfc::OnActTurnOver(UINT id) -{ - CPlayBoardView& view = GetBoardView(); - switch (id) - { - case ID_ACT_TURNOVER: - case ID_ACT_TURNOVER_PREV: - case ID_ACT_TURNOVER_RANDOM: - { - bool b = view.OnCmdMsg(id, CN_COMMAND, nullptr, nullptr); - ASSERT(b); - return b; - } - case ID_ACT_TURNOVER_SELECT: - { - const CPlayBoard& playBoard = CheckedDeref(view.GetPlayBoard()); - - m_pDoc->AssignNewMoveGroup(); - - PieceID pid = static_cast(menuGameElement); - auto it = std::find_if(GetItemMap()->begin(), - GetItemMap()->end(), - [pid](const RefPtr& drawObj) - { - if (drawObj->GetType() != CDrawObj::drawPieceObj) - { - return false; - } - const CPieceObj& pieceObj = static_cast(*drawObj); - return pieceObj.m_pid == pid; - }); - wxASSERT(it != GetItemMap()->end()); - const CDrawObj& drawObj = **it; - wxASSERT(drawObj.GetType() == CDrawObj::drawPieceObj); - const CPieceObj& pieceObj = static_cast(drawObj); - size_t side = menuGameElement.GetSide(); - m_pDoc->InvertPlayingPieceOnBoard(pieceObj, playBoard, CPieceTable::fSelect, side); - - return true; - } - default: - AfxThrowInvalidArgException(); - } -} - -void CSelectListBoxMfc::OnUpdateActTurnOver(CCmdUI* pCmdUI) -{ - switch (pCmdUI->m_nID) - { - case ID_ACT_TURNOVER: - case ID_ACT_TURNOVER_PREV: - case ID_ACT_TURNOVER_RANDOM: - pCmdUI->DoUpdate(&GetBoardView(), TRUE); - break; - case ID_ACT_TURNOVER_SELECT: - { - bool enable = menuGameElement != Invalid_v && - menuGameElement.IsAPiece(); - pCmdUI->Enable(enable); - if (pCmdUI->m_pSubMenu != NULL) - { - // Need to handle menu that the submenu is connected to. - pCmdUI->m_pMenu->EnableMenuItem(pCmdUI->m_nIndex, - MF_BYPOSITION | (enable ? MF_ENABLED : (MF_DISABLED | MF_GRAYED))); - } - break; - } - default: - AfxThrowInvalidArgException(); - } -} - -///////////////////////////////////////////////////////////////////////////// -// Tool tip processing - -BOOL CSelectListBoxMfc::OnIsToolTipsEnabled() const -{ - return m_pDoc->IsShowingObjectTips(); -} - -GameElement CSelectListBoxMfc::OnGetHitItemCodeAtPoint(CPoint point, CRect& rct) const -{ - return OnGetHitItemCodeAtPoint(&CGamDoc::GetVerifiedGameElementCodeForObject, point, rct); -} - -GameElement CSelectListBoxMfc::OnGetHitItemCodeAtPoint(GetGameElementCodeForObject_t func, CPoint point, CRect& rct) const -{ - point = ClientToItem(point); - - BOOL bOutsideClient; - UINT nIndex = ItemFromPoint(point, bOutsideClient); - if (nIndex >= 65535 || GetCount() <= 0) - return Invalid_v; - - std::vector tids = GetTileIDs(nIndex); - ASSERT(!tids.empty() && tids[size_t(0)] != nullTid); - - std::vector rcts = GetTileRectsForItem(value_preserving_cast(nIndex), tids); - - for (size_t i = size_t(0); i < rcts.size(); ++i) - { - ASSERT(!rcts[i].IsRectEmpty()); - if (rcts[i].PtInRect(point)) - { - rct = ItemToClient(rcts[i]); - const CDrawObj& pObj = MapIndexToItem(nIndex); - if (pObj.GetType() == CDrawObj::drawPieceObj) - { - const CPieceObj& pieceObj = static_cast(pObj); - const CPieceTable& pieceTbl = m_pDoc->GetPieceTable(); - uint8_t side = pieceTbl.GetSide(pieceObj.m_pid, i); - return ((*m_pDoc).*func)(pieceObj, side); - } - else - { - return ((*m_pDoc).*func)(pObj, Invalid_v); - } - } - } - - return Invalid_v; -} - -CB::string CSelectListBoxMfc::OnGetTipTextForItemCode(GameElement nItemCode) const -{ - if (nItemCode == Invalid_v) - { - wxASSERT(!"invalid gameelement"); - return CB::string(); - } - return m_pDoc->GetGameElementString(nItemCode); -} - -///////////////////////////////////////////////////////////////////////////// - -BOOL CSelectListBoxMfc::OnDoesItemHaveTipText(size_t nItem) const -{ - const CDrawObj& pDObj = MapIndexToItem(nItem); - if (pDObj.GetType() == CDrawObj::drawPieceObj) - { - const CPieceObj& pObj = static_cast(pDObj); - const CPieceTable& pieceTbl = m_pDoc->GetPieceTable(); - size_t sides = pieceTbl.GetSides(pObj.m_pid); - for (size_t i = size_t(0); i < sides; ++i) - { - GameElement elem = m_pDoc->GetVerifiedGameElementCodeForObject(pObj, i); - if (elem != Invalid_v) - { - return true; - } - } - return false; - } - else - { - GameElement elem = m_pDoc->GetVerifiedGameElementCodeForObject(pDObj); - return elem != Invalid_v; - } -} - -///////////////////////////////////////////////////////////////////////////// - -CB::string CSelectListBoxMfc::OnGetItemDebugString(size_t nIndex) const -{ - const CDrawObj& pDObj = MapIndexToItem(nIndex); - if (pDObj.GetType() == CDrawObj::drawPieceObj) - { - PieceID pid = static_cast(pDObj).m_pid; - return std::format(L"[pid:{}] ", pid); - } - else if (pDObj.GetType() == CDrawObj::drawMarkObj) - { - MarkID mid = static_cast(pDObj).m_mid; - return std::format(L"[mid:{}] ", mid); - } - return CB::string(); -} - -///////////////////////////////////////////////////////////////////////////// - -CSize CSelectListBoxMfc::OnItemSize(size_t nIndex) const -{ - ASSERT(m_pDoc != NULL); - - std::vector tids = GetTileIDs(nIndex); - ASSERT(!tids.empty() && tids[size_t(0)] != nullTid); - - return DoOnItemSize(nIndex, tids); -} - -void CSelectListBoxMfc::OnItemDraw(CDC& pDC, size_t nIndex, UINT nAction, UINT nState, - CRect rctItem) const -{ - // see https://docs.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-drawitemstruct - if (nIndex == UINT(-1)) - return; // Nothing to draw. - - std::vector tids = GetTileIDs(nIndex); - ASSERT(!tids.empty() && tids[size_t(0)] != nullTid); - DoOnDrawItem(pDC, nIndex, nAction, nState, rctItem, tids); -} - -// retval[0] is active face, followed by inactives -std::vector CSelectListBoxMfc::GetTileIDs(size_t nIndex) const -{ - const CDrawObj& pDObj = MapIndexToItem(nIndex); - - if (pDObj.GetType() == CDrawObj::drawPieceObj) - { - const CPieceTable& pPTbl = m_pDoc->GetPieceTable(); - - PieceID pid = static_cast(pDObj).m_pid; - - if (!m_pDoc->IsScenario() && pPTbl.IsPieceOwned(pid) && - !pPTbl.IsPieceOwnedBy(pid, m_pDoc->GetCurrentPlayerMask())) - { - std::vector retval; - retval.push_back(pPTbl.GetFrontTileID(pid)); - return retval; - } - - const PieceDef& pPce = m_pDoc->GetPieceManager().GetPiece(pid); - - std::vector retval; - if ((pPce.m_flags & PieceDef::flagShowOnlyVisibleSide) && - (!pPTbl.IsPieceOwnedBy(pid, m_pDoc->GetCurrentPlayerMask()) || - pPce.m_flags & PieceDef::flagShowOnlyOwnersToo)) - { - retval.push_back(pPTbl.GetActiveTileID(pid)); - } - else - { - retval.reserve(pPTbl.GetSides(pid)); - retval.push_back(pPTbl.GetActiveTileID(pid)); - std::vector inactives = pPTbl.GetInactiveTileIDs(pid); - retval.insert(retval.end(), inactives.begin(), inactives.end()); - } - return retval; - - } - else if (pDObj.GetType() == CDrawObj::drawMarkObj) - { - MarkID mid = static_cast(pDObj).m_mid; - const CMarkManager& pMMgr = m_pDoc->GetMarkManager(); - std::vector retval; - retval.push_back(pMMgr.GetMark(mid).m_tid); - return retval; - } - else - { - ASSERT(FALSE); // Shouldn't happen - return std::vector(); - } -} - -const CPlayBoardView& CSelectListBoxMfc::GetBoardView() const -{ - CFrameWnd& frame = CheckedDeref(AFXGetParentFrame(this)); - const CPlayBoardFrame& pbrdFrame = CheckedDeref(DYNAMIC_DOWNCAST(CPlayBoardFrame, &frame)); - return pbrdFrame.GetActiveBoardView(); -} - diff --git a/GP/LBoxSlct.h b/GP/LBoxSlct.h index b9724fc8..0b1495fd 100644 --- a/GP/LBoxSlct.h +++ b/GP/LBoxSlct.h @@ -41,7 +41,6 @@ class CGamDoc; -#if 1 ///////////////////////////////////////////////////////////////////////////// class CSelectListBox : public CTileBaseListBox2 @@ -106,69 +105,3 @@ class CSelectListBox : public CTileBaseListBox2 }; #endif -///////////////////////////////////////////////////////////////////////////// - -class CSelectListBoxMfc : public CTileBaseListBox2Mfc -{ -// Construction -public: - CSelectListBoxMfc() - { - m_pDoc = NULL; - } - -// Attributes -public: - virtual const CTileManager& GetTileManager() const override; - -// Operations -public: - void SetDocument(CGamDoc& pDoc) { CTileBaseListBox2Mfc::SetDocument(pDoc); m_pDoc = &pDoc; } - -// Implementation -protected: - CB::propagate_const m_pDoc; - - GameElement menuGameElement = Invalid_v; - - // Misc - // retval[0] is active face, followed by inactives - std::vector GetTileIDs(size_t nIndex) const; - - // Overrides - virtual CSize OnItemSize(size_t nIndex) const override; - virtual void OnItemDraw(CDC& pDC, size_t nIndex, UINT nAction, UINT nState, - CRect rctItem) const override; - virtual BOOL OnDragSetup(DragInfo& pDI) const override; - - virtual CB::string OnGetItemDebugString(size_t nItem) const override; - - // Tool tip processing - virtual BOOL OnIsToolTipsEnabled() const override; - virtual GameElement OnGetHitItemCodeAtPoint(CPoint point, CRect& rct) const override; -private: - typedef GameElement (CGamDoc::*GetGameElementCodeForObject_t)(const CDrawObj& pDObj, size_t nSide) const; - GameElement OnGetHitItemCodeAtPoint(GetGameElementCodeForObject_t func, CPoint point, CRect& rct) const; -public: - virtual CB::string OnGetTipTextForItemCode(GameElement nItemCode) const override; - virtual BOOL OnDoesItemHaveTipText(size_t nItem) const override; - - //{{AFX_MSG(CSelectListBox) - afx_msg LRESULT OnDragItem(WPARAM wParam, LPARAM lParam); - afx_msg void OnContextMenu(CWnd* pWnd, CPoint point); - afx_msg void OnInitMenuPopup(CMenu* pPopupMenu, UINT nIndex, BOOL bSysMenu); - afx_msg BOOL OnActTurnOver(UINT id); - afx_msg void OnUpdateActTurnOver(CCmdUI* pCmdUI); - //}}AFX_MSG - DECLARE_MESSAGE_MAP() - -private: - const CPlayBoardView& GetBoardView() const; - CPlayBoardView& GetBoardView() - { - return const_cast(std::as_const(*this).GetBoardView()); - } -}; - -#endif - diff --git a/GShr/LBoxGfx2.cpp b/GShr/LBoxGfx2.cpp index bbd63ff9..937dd65f 100644 --- a/GShr/LBoxGfx2.cpp +++ b/GShr/LBoxGfx2.cpp @@ -766,684 +766,3 @@ void CGrafixListBox2::ExecutePostProcessEvents() } } -///////////////////////////////////////////////////////////////////////////// - -BEGIN_MESSAGE_MAP(CGrafixListBox2Mfc, CListBox) - //{{AFX_MSG_MAP(CGrafixListBox2) - ON_WM_LBUTTONDOWN() - ON_WM_MOUSEMOVE() - ON_WM_LBUTTONUP() - ON_WM_TIMER() - ON_WM_CREATE() - ON_REGISTERED_MESSAGE(WM_DRAGDROP, OnDragItem) - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - -///////////////////////////////////////////////////////////////////////////// - -CGrafixListBox2Mfc::CGrafixListBox2Mfc() -{ - m_nLastInsert = -1; - m_nTimerID = uintptr_t(0); - m_bAllowDrag = FALSE; - m_bAllowSelfDrop = FALSE; - m_bAllowDropScroll = FALSE; - m_pItemMap = NULL; -} - -///////////////////////////////////////////////////////////////////////////// - -void CGrafixListBox2Mfc::SetItemMap(const std::vector>* pMap, - BOOL bKeepPosition /* = TRUE */) -{ - m_pItemMap = pMap; - UpdateList(bKeepPosition); -} - -// bKeepPosition == TRUE means current selection is maintained. -void CGrafixListBox2Mfc::UpdateList(BOOL bKeepPosition /* = TRUE */) -{ - if (m_pItemMap == NULL) - { - ResetContent(); - return; - } - int nCurSel = GetCurSel(); - int nTopIdx = GetTopIndex(); - int nFcsIdx = GetCaretIndex(); - int horzScroll = GetScrollPos(SB_HORZ); - SetRedraw(FALSE); - ResetContent(); - - LONG width = 0; - int nItem; - for (nItem = 0; nItem < value_preserving_cast(m_pItemMap->size()); nItem++) - { - AddString(" "_cbstring); // Fill with dummy data - width = CB::max(width, OnItemSize(value_preserving_cast(nItem)).cx); - } - SetHorizontalExtent(value_preserving_cast(width)); - if (bKeepPosition) - { - if (nTopIdx >= 0) - SetTopIndex(CB::min(nTopIdx, nItem - 1)); - if (nFcsIdx >= 0) - SetCaretIndex(CB::min(nFcsIdx, nItem - 1), FALSE); - if (nCurSel >= 0) - SetCurSel(CB::min(nCurSel, nItem - 1)); - } - SetRedraw(TRUE); - if (bKeepPosition) - { - SendMessage(WM_HSCROLL, MAKELONG(int16_t(SB_THUMBPOSITION), value_preserving_cast(horzScroll)), NULL); - } - Invalidate(); -} - -///////////////////////////////////////////////////////////////////////////// - -const CDrawObj& CGrafixListBox2Mfc::MapIndexToItem(size_t nIndex) const -{ - ASSERT(m_pItemMap); - ASSERT(nIndex < m_pItemMap->size()); - return *m_pItemMap->at(nIndex); -} - -size_t CGrafixListBox2Mfc::MapItemToIndex(const CDrawObj& pItem) const -{ - wxASSERT(!"dead code?"); - ASSERT(m_pItemMap); - for (size_t i = size_t(0); i < m_pItemMap->size(); i++) - { - if (&pItem == m_pItemMap->at(i)) - return i; - } - return Invalid_v; // Failed to find it -} - -const CDrawObj& CGrafixListBox2Mfc::GetCurMapItem() const -{ - wxASSERT(!"dead code?"); - ASSERT(!IsMultiSelect()); - ASSERT(m_pItemMap); - int nItem = GetCurSel(); - ASSERT(nItem >= 0); - ASSERT(value_preserving_cast(nItem) < m_pItemMap->size()); - return *m_pItemMap->at(value_preserving_cast(nItem)); -} - -std::vector> CGrafixListBox2Mfc::GetCurMappedItemList() const -{ - std::vector> pLst; - ASSERT(IsMultiSelect()); - int nSels = GetSelCount(); - if (nSels == LB_ERR || nSels == 0) - return pLst; - std::vector pSelTbl(value_preserving_cast(nSels)); - GetSelItems(nSels, pSelTbl.data()); - pLst.reserve(pSelTbl.size()); - for (size_t i = size_t(0); i < pSelTbl.size(); i++) - pLst.push_back(&MapIndexToItem(value_preserving_cast(pSelTbl[i]))); - return pLst; -} - -void CGrafixListBox2Mfc::SetCurSelMapped(const CDrawObj& nMapVal) -{ - wxASSERT(!"dead code?"); - ASSERT(m_pItemMap); - for (size_t i = size_t(0); i < m_pItemMap->size(); i++) - { - if (m_pItemMap->at(i) == &nMapVal) - { - SetCurSel(value_preserving_cast(i)); - SetTopIndex(value_preserving_cast(i)); - } - } -} - -void CGrafixListBox2Mfc::SetCurSelsMapped(const std::vector>& items) -{ - wxASSERT(!"dead code?"); - ASSERT(m_pItemMap); - ASSERT(IsMultiSelect()); - - SetSel(-1, FALSE); // Deselect all - for (size_t i = size_t(0); i < items.size(); i++) - { - for (size_t j = size_t(0); j < m_pItemMap->size(); j++) - { - if (m_pItemMap->at(j) == items[i]) - SetSel(value_preserving_cast(j)); - } - } -} - -///////////////////////////////////////////////////////////////////////////// - -void CGrafixListBox2Mfc::ShowFirstSelection() -{ - wxASSERT(!"dead code?"); - int nTopSel = GetTopSelectedItem(); - CRect rctLBoxClient; - GetClientRect(&rctLBoxClient); - CRect rct; - GetItemRect(nTopSel, &rct); - if (!rct.IntersectRect(rct, rctLBoxClient)) - SetTopIndex(nTopSel); -} - -int CGrafixListBox2Mfc::GetTopSelectedItem() const -{ - wxASSERT(!"dead code?"); - int nTopSel; - if (IsMultiSelect()) - { - if (GetSelCount() == 0) - return LB_ERR; - VERIFY(GetSelItems(1, &nTopSel)); - } - else - { - nTopSel = GetCurSel(); - if (nTopSel == LB_ERR) - return LB_ERR; - } - return nTopSel; -} - -///////////////////////////////////////////////////////////////////////////// -// If the selection is out of view, force it into view. - -void CGrafixListBox2Mfc::MakeItemVisible(int nItem) -{ - wxASSERT(!"dead code?"); - CRect rctLBoxClient; - GetClientRect(&rctLBoxClient); - CRect rct; - GetItemRect(nItem, &rct); - if (!rct.IntersectRect(rct, rctLBoxClient)) - SetTopIndex(nItem); -} - -///////////////////////////////////////////////////////////////////////////// - -void CGrafixListBox2Mfc::SetSelFromPoint(CPoint point) -{ - wxASSERT(!"dead code?"); - // Short circuit drag processing - m_bAllowDrag = FALSE; - SendMessage(WM_LBUTTONDOWN, (WPARAM)MK_LBUTTON, - MAKELPARAM(static_cast(point.x), static_cast(point.y))); - SendMessage(WM_LBUTTONUP, (WPARAM)MK_LBUTTON, - MAKELPARAM(static_cast(point.x), static_cast(point.y))); - m_bAllowDrag = TRUE; -} - -///////////////////////////////////////////////////////////////////////////// - -void CGrafixListBox2Mfc::DoToolTipHitProcessing(CPoint point) -{ - if (!OnIsToolTipsEnabled()) - return; - - if (m_toolTip.m_hWnd == NULL) - { - m_toolTip.Create(this, TTS_ALWAYSTIP | TTS_BALLOON | TTS_NOPREFIX); - m_toolTip.SetMaxTipWidth(MAX_LISTITEM_TIP_WIDTH); - } - - CRect rctTool; - GameElement nItemCode = OnGetHitItemCodeAtPoint(point, rctTool); - - if (nItemCode != m_nCurItemCode) - { - // Object changed so delete previous tool definition - m_toolTip.DelTool(this, ID_TIP_LISTITEM_HIT); - m_nCurItemCode = nItemCode; - if (nItemCode != Invalid_v) - { - // New object found so create a new tip - CB::string strTip; - - // Call subclass for info - strTip = OnGetTipTextForItemCode(nItemCode); - - if (!strTip.empty()) - { - m_toolTip.AddTool(this, strTip, rctTool, ID_TIP_LISTITEM_HIT); - m_toolTip.Activate(TRUE); - } - } - else - m_toolTip.Activate(FALSE); - } -} - -LRESULT CGrafixListBox2Mfc::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) -{ - if (m_toolTip.m_hWnd != NULL && message >= WM_MOUSEFIRST && - message <= WM_MOUSELAST) - { - MSG msg; - memset(&msg, 0, sizeof(MSG)); - msg.hwnd = m_hWnd; - msg.message = message; - msg.wParam = wParam; - msg.lParam = lParam; - - m_toolTip.RelayEvent(&msg); - } - return CListBox::WindowProc(message, wParam, lParam); -} - -///////////////////////////////////////////////////////////////////////////// - -void CGrafixListBox2Mfc::MeasureItem(LPMEASUREITEMSTRUCT lpMIS) -{ - unsigned nHt = value_preserving_cast(OnItemSize(lpMIS->itemID).cy); - - if (nHt >= unsigned(256)) nHt = unsigned(255); - if (nHt == unsigned(0)) nHt = defaultItemHeight; - - lpMIS->itemHeight = value_preserving_cast(nHt); -} - -void CGrafixListBox2Mfc::DrawItem(LPDRAWITEMSTRUCT lpDIS) -{ - size_t nIndex = lpDIS->itemID; - CDC* pDC = CDC::FromHandle(lpDIS->hDC); - - CRect rct(lpDIS->rcItem); - OnItemDraw(CheckedDeref(pDC), nIndex, lpDIS->itemAction, lpDIS->itemState, rct); -} - -///////////////////////////////////////////////////////////////////////////// -// CGrafixListBox2 Message Processing - -void CGrafixListBox2Mfc::OnLButtonDown(UINT nFlags, CPoint point) -{ - CListBox::OnLButtonDown(nFlags, point); // Allow field selection - - int nIdx; - if ((nIdx = GetCurSel()) == -1) - return; - if (m_bAllowDrag) - { - m_hLastWnd = NULL; - m_clickPoint = point; // For hysteresis - m_triggeredCursor = FALSE; // -Ditto- - } -} - -void CGrafixListBox2Mfc::OnLButtonUp(UINT nFlags, CPoint point) -{ - if (m_nTimerID) - { - KillTimer(m_nTimerID); - m_nTimerID = uintptr_t(0); - } - if (m_bAllowDrag) - { - ASSERT(!"unreachable code"); - BOOL bWasDragging = CWnd::GetCapture() == this; - CListBox::OnLButtonUp(nFlags, point); - - // Get the final selection results after the mouse was released. - if (IsMultiSelect()) - m_multiSelList = GetCurMappedItemList(); - - if (bWasDragging && m_triggeredCursor) - { -#if defined(GPLAY) - m_pDoc->AssignNewMoveGroup(); -#endif - - ReleaseCapture(); - SetCursor(LoadCursor(NULL, IDC_ARROW)); - - CWnd* pWnd = GetWindowFromPoint(point); - if (pWnd == NULL || (!m_bAllowSelfDrop && pWnd == this)) - { - OnDragCleanup(di); // Tell subclass we're all done. - return; - } - di.m_point = point; - di.m_pointClient = point; // list box relative - ClientToScreen(&di.m_point); - pWnd->ScreenToClient(&di.m_point); - - di.m_phase = PhaseDrag::Drop; - pWnd->SendMessage(WM_DRAGDROP, GetProcessId(GetCurrentProcess()), - (LPARAM)(LPVOID)&di); - OnDragCleanup(di); // Tell subclass we're all done. - m_multiSelList.clear(); - } - } - else - CListBox::OnLButtonUp(nFlags, point); -} - -void CGrafixListBox2Mfc::OnMouseMove(UINT nFlags, CPoint point) -{ - if (CWnd::GetCapture() != this) - { - // Only process tool tips when we aren't draggin stuff around - DoToolTipHitProcessing(point); - } - - if (m_bAllowDrag) - { - ASSERT(!"unreachable code"); - if (CWnd::GetCapture() != this) - return; - // OK...We are dragging. Let's check if the cursor has been - // triggered. If not, check if we've moved far enough from - // the initial mouse down position. - if (!m_triggeredCursor) - { - if (abs(point.x - m_clickPoint.x) < TRIGGER_THRESHOLD && - abs(point.y - m_clickPoint.y) < TRIGGER_THRESHOLD) - { - return; - } - m_triggeredCursor = TRUE; - } - OnDragSetup(di); // Get stuff from subclass - - // If we got here, dragging is under way.... - CWnd* pWnd = GetWindowFromPoint(point); - if (pWnd == NULL) - { - // No window underneath - SetCursor(g_res.hcrNoDrop); - return; - } - if (pWnd == this && !m_bAllowSelfDrop) - { - // The mouse is over us...show drop cursor - SetCursor(g_res.hcrDragTile); - return; - } - HWND hWnd = pWnd->m_hWnd; // Get actual window handle - HCURSOR hCursor = NULL; - - di.m_point = point; - di.m_pointClient = point; // list box relative - ClientToScreen(&di.m_point); - pWnd->ScreenToClient(&di.m_point); - - if (hWnd != m_hLastWnd) - { - if (m_hLastWnd != NULL) - { - // Inform previous window we are leaving them - CWnd* pLstWnd = CWnd::FromHandle(m_hLastWnd); - di.m_phase = PhaseDrag::Exit; - pLstWnd->SendMessage(WM_DRAGDROP, GetProcessId(GetCurrentProcess()), - (LPARAM)(LPVOID)&di); - } - di.m_phase = PhaseDrag::Enter; - pWnd->SendMessage(WM_DRAGDROP, GetProcessId(GetCurrentProcess()), (LPARAM)(LPVOID)&di); - } - m_hLastWnd = pWnd->m_hWnd; - di.m_phase = PhaseDrag::Over; - hCursor = (HCURSOR)pWnd->SendMessage(WM_DRAGDROP, GetProcessId(GetCurrentProcess()), - (LPARAM)(LPVOID)&di); - if (hCursor) - SetCursor(hCursor); - else - SetCursor(g_res.hcrNoDrop); - } - else - CListBox::OnMouseMove(nFlags, point); -} - -///////////////////////////////////////////////////////////////////////////// - -CWnd* CGrafixListBox2Mfc::GetWindowFromPoint(CPoint point) const -{ - wxASSERT(!"dead code?"); - ClientToScreen(&point); - CWnd* pWnd = WindowFromPoint(point); - - if (pWnd == NULL) - return NULL; - - pWnd->ScreenToClient(&point); - pWnd = pWnd->ChildWindowFromPoint(point); - - if (pWnd == NULL) - return NULL; - - return pWnd->IsWindowVisible() ? pWnd : NULL; -} - -int CGrafixListBox2Mfc::OnCreate(LPCREATESTRUCT lpCreateStruct) -{ - if (CListBox::OnCreate(lpCreateStruct) == -1) - return -1; - - m_pItemMap = NULL; - m_nTimerID = uintptr_t(0); - - return 0; -} - -///////////////////////////////////////////////////////////////// - -void CGrafixListBox2Mfc::DoInsertLineProcessing(const DragInfo& pdi) -{ - if (m_bAllowDropScroll) - { - wxASSERT(!"dead code"); - // Handle drawing of insert line - CPoint pnt = pdi.m_point; - int nSel = SpecialItemFromPoint(pnt); - if (pdi.m_phase == PhaseDrag::Enter) - { - m_nLastInsert = nSel; - DrawSingle(m_nLastInsert); // Turn line on - } - else if (pdi.m_phase == PhaseDrag::Exit || pdi.m_phase == PhaseDrag::Drop) - { - DrawSingle(m_nLastInsert); // Turn line off - m_nLastInsert = -1; - } - else - { - DrawInsert(nSel); // Move insert line - } - } -} - -///////////////////////////////////////////////////////////////// - -void CGrafixListBox2Mfc::DoAutoScrollProcessing(const DragInfo& pdi) -{ - if (m_bAllowDropScroll && m_nTimerID == uintptr_t(0)) - { - wxASSERT(!"dead code"); - CRect rct; - GetClientRect(&rct); - rct.InflateRect(0, -scrollZonePixels); - rct.NormalizeRect(); - if (!rct.PtInRect(pdi.m_point)) - { - // Trigger time is usually longer - m_nTimerID = SetTimer(timerScrollIDStart, timerScrollStart, NULL); - } - } -} - -///////////////////////////////////////////////////////////////// -// Pass it up to the parent by default. - -LRESULT CGrafixListBox2Mfc::OnDragItem(WPARAM wParam, LPARAM lParam) -{ - wxASSERT(!"dead code"); - if (wParam != GetProcessId(GetCurrentProcess())) - { - return -1; - } - const DragInfo& pdi = CheckedDeref(reinterpret_cast(lParam)); - DoInsertLineProcessing(pdi); - - CWnd *pWnd = GetParent(); - ASSERT(pWnd != NULL); - LRESULT lResult = pWnd->SendMessage(WM_DRAGDROP, wParam, lParam); - - if (pdi.m_phase == PhaseDrag::Over && lResult != 0) - DoAutoScrollProcessing(di); - return lResult; -} - -void CGrafixListBox2Mfc::OnTimer(uintptr_t nIDEvent) -{ - if (nIDEvent != m_nTimerID) - return; - - wxASSERT(!"dead code"); - CPoint point; - CRect rctClient; - CRect rct; - - GetCursorPos(&point); - ScreenToClient(&point); - GetClientRect(&rctClient); - rct = rctClient; - rct.InflateRect(0, -scrollZonePixels); - rct.NormalizeRect(); - - if (rctClient.PtInRect(point) && !rct.PtInRect(point)) - { - // Restart the timer. - if (m_nTimerID == timerScrollIDStart) - { - KillTimer(m_nTimerID); - m_nTimerID = SetTimer(timerScrollID, timerScroll, NULL); - } - BOOL bHaveFocus = GetFocus() == this; - if (bHaveFocus) - { - GetParent()->SetFocus(); - SetCapture(); // Reestablish the mouse capture - } - - // Hide insert line - DrawSingle(m_nLastInsert); - - int nTopIndex = GetTopIndex(); - if (point.y <= rct.top) - { - if (nTopIndex > 0) - SetTopIndex(nTopIndex - 1); - } - else - { - if (nTopIndex < GetCount() - 1 && nTopIndex >= 0) - SetTopIndex(nTopIndex + 1); - } - // Restore insert line in new position - CPoint pnt; - GetCursorPos(&pnt); - ScreenToClient(&pnt); - m_nLastInsert = SpecialItemFromPoint(pnt); - DrawSingle(m_nLastInsert); - - if (bHaveFocus) - SetFocus(); - } - else - { - KillTimer(m_nTimerID); - m_nTimerID = uintptr_t(0); - } -} - -///////////////////////////////////////////////////////////////// -// This routine selects the next item if the point is past -// the y midpoint of the item. - -int CGrafixListBox2Mfc::SpecialItemFromPoint(CPoint pnt) const -{ - wxASSERT(!"dead code"); - BOOL bBucket; - int nSel = (int)ItemFromPoint(pnt, bBucket); - CRect rct; - GetItemRect(nSel, &rct); - // Note: it is possible for the item number to exceed the - // number of items in the listbox. This is figured into our - // coding. - if (pnt.y > (rct.top + rct.bottom) / 2) - nSel++; // Step to next item - return nSel; -} - -///////////////////////////////////////////////////////////////// - -void CGrafixListBox2Mfc::DrawInsert(int nIndex) -{ - if (m_nLastInsert != nIndex) - { - DrawSingle(m_nLastInsert); - DrawSingle(nIndex); - m_nLastInsert = nIndex; - } -} - -void CGrafixListBox2Mfc::DrawSingle(int nIndex) -{ - if (nIndex == -1) - return; - CBrush* pBrush = CDC::GetHalftoneBrush(); - CRect rect; - GetClientRect(&rect); - CRgn rgn; - rgn.CreateRectRgnIndirect(&rect); - - CDC* pDC = GetDC(); - // Prevent drawing outside of listbox. This can happen at the - // top of the listbox since the listbox's DC is the parent's DC. - pDC->SelectClipRgn(&rgn); - - // Account for possibility of nIndex equal to number - // of listbox items.... - if (nIndex < GetCount()) - { - GetItemRect(nIndex, &rect); - rect.bottom = rect.top + 2; - rect.top -= 2; - } - else - { - GetItemRect(nIndex - 1, &rect); - rect.top = rect.bottom - 2; - rect.bottom += 2; - } - - CBrush* pBrushOld = pDC->SelectObject(pBrush); - // Draw main line - pDC->PatBlt(rect.left, rect.top, rect.Width(), rect.Height(), PATINVERT); - - pDC->SelectObject(pBrushOld); - ReleaseDC(pDC); -} - -CPoint CGrafixListBox2Mfc::ClientToItem(CPoint point) const -{ - // account for horz scroll - int xOffset = GetScrollPos(SB_HORZ); - ASSERT(xOffset >= 0); - point.x += xOffset; - return point; -} - -CRect CGrafixListBox2Mfc::ItemToClient(CRect rect) const -{ - // account for horz scroll - int xOffset = GetScrollPos(SB_HORZ); - ASSERT(xOffset >= 0); - rect.OffsetRect(-xOffset, 0); - return rect; -} - diff --git a/GShr/LBoxGfx2.h b/GShr/LBoxGfx2.h index e2263e72..cd9b8cbd 100644 --- a/GShr/LBoxGfx2.h +++ b/GShr/LBoxGfx2.h @@ -44,7 +44,6 @@ class CDrawObj; ///////////////////////////////////////////////////////////////////////////// // Custom Listbox - containing colors -#if 1 class CGrafixListBox2 : public CB::VListBoxHScroll { // Construction @@ -181,119 +180,3 @@ class CGrafixListBox2 : public CB::VListBoxHScroll }; #endif -class CGrafixListBox2Mfc : public CListBox -{ -// Construction -public: - CGrafixListBox2Mfc(); - -// Attributes -public: - int GetTopSelectedItem() const; - void EnableDrag(BOOL bEnable = TRUE) { m_bAllowDrag = bEnable; } - void EnableSelfDrop(BOOL bEnable = TRUE) { m_bAllowSelfDrop = bEnable; } - void EnableDropScroll(BOOL bEnable = TRUE) { m_bAllowDropScroll = bEnable; } - const std::vector>* GetItemMap() const { return m_pItemMap; } - const CDrawObj& GetCurMapItem() const; - std::vector> GetCurMappedItemList() const; - BOOL IsMultiSelect() const - { return (GetStyle() & (LBS_EXTENDEDSEL | LBS_MULTIPLESEL)) != 0; } - // Note: the following pointer is only good during drag and drop. - // the data is only good during the drop. It is essentially a - // hack to have valid data when selecting items with Shift-Click. - // Ask Microsoft why I had to do this. The number of selections - // data in the case of a shift click isn't valid until the button - // is released. Makes it tough to use a pre setup list during the - // drag operation. - const std::vector>& GetMappedMultiSelectList() const { return m_multiSelList; } - -// Operations -public: - void SetItemMap(const std::vector>* pMap, BOOL bKeepPosition = TRUE); - void UpdateList(BOOL bKeepPosition = TRUE); - void SetCurSelMapped(const CDrawObj& pMapVal); - void SetCurSelsMapped(const std::vector>& items); - void SetSelFromPoint(CPoint point); - void ShowFirstSelection(); - const CDrawObj& MapIndexToItem(size_t nIndex) const; - CDrawObj& MapIndexToItem(size_t nIndex) - { - return const_cast(std::as_const(*this).MapIndexToItem(nIndex)); - } - size_t MapItemToIndex(const CDrawObj& pItem) const; - void MakeItemVisible(int nItem); - -// Overrides - the subclass of this class must override these -public: - virtual CSize OnItemSize(size_t nIndex) const /* override */ = 0; - virtual void OnItemDraw(CDC& pDC, size_t nIndex, UINT nAction, UINT nState, - CRect rctItem) const /* override */ = 0; - virtual BOOL OnDragSetup(DragInfo& pDI) const /* override */ - { - pDI.SetDragType(DRAG_INVALID); - return FALSE; - } - virtual void OnDragCleanup(const DragInfo& pDI) const /* override */ { } - - // For tool tip processing - virtual BOOL OnIsToolTipsEnabled() const /* override */ { return FALSE; } - virtual GameElement OnGetHitItemCodeAtPoint(CPoint point, CRect& rct) const /* override */ { return Invalid_v; } - virtual CB::string OnGetTipTextForItemCode(GameElement nItemCode) const /* override */ { return CB::string(); } - -// Implementation -protected: - /* N.B.: this class could be templatized to hold any pointer, - but that generality isn't actually needed yet */ - const std::vector>* m_pItemMap; // Maps index to item - std::vector> m_multiSelList; // Holds mapped multi select items on drop - - // Tool tip support - CToolTipCtrl m_toolTip; - GameElement m_nCurItemCode; - - // Drag and scroll support vars - BOOL m_bAllowDrag; - BOOL m_bAllowSelfDrop; // Only if m_bAllowDrag == TRUE - BOOL m_bAllowDropScroll; // Scroll on OnDragItem - - CPoint m_clickPoint; - uintptr_t m_nTimerID; - BOOL m_triggeredCursor; - HWND m_hLastWnd; - - int m_nLastInsert; // Last index with insert line - - void SetDocument(CGamDoc& doc) { m_pDoc = &doc; } - void DoInsertLineProcessing(const DragInfo& pdi); - void DoAutoScrollProcessing(const DragInfo& pdi); - void DoToolTipHitProcessing(CPoint point); - - CWnd* GetWindowFromPoint(CPoint point) const; - int SpecialItemFromPoint(CPoint pnt) const; - void DrawInsert(int nIndex); - void DrawSingle(int nIndex); - - CPoint ClientToItem(CPoint point) const; - CRect ItemToClient(CRect rect) const; - - // Overrides - virtual void MeasureItem(LPMEASUREITEMSTRUCT lpMIS) override; - virtual void DrawItem(LPDRAWITEMSTRUCT lpDIS) override; - virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam) override; - - //{{AFX_MSG(CGrafixListBox2) - afx_msg void OnLButtonDown(UINT nFlags, CPoint point); - afx_msg void OnMouseMove(UINT nFlags, CPoint point); - afx_msg void OnLButtonUp(UINT nFlags, CPoint point); - afx_msg void OnTimer(uintptr_t nIDEvent); - afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); - afx_msg LRESULT OnDragItem(WPARAM wParam, LPARAM lParam); - //}}AFX_MSG - DECLARE_MESSAGE_MAP() - -private: - CB::propagate_const m_pDoc = nullptr; -}; - -#endif - diff --git a/GShr/LBoxTileBase2.cpp b/GShr/LBoxTileBase2.cpp index 58afe896..bf87b3ed 100644 --- a/GShr/LBoxTileBase2.cpp +++ b/GShr/LBoxTileBase2.cpp @@ -229,226 +229,3 @@ void CTileBaseListBox2::OnCreate(wxWindowCreateEvent& event) } -///////////////////////////////////////////////////////////////////////////// - -BEGIN_MESSAGE_MAP(CTileBaseListBox2Mfc, CGrafixListBox2Mfc) - //{{AFX_MSG_MAP(CTileBaseListBox2) - ON_WM_CREATE() - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - -///////////////////////////////////////////////////////////////////////////// - -CTileBaseListBox2Mfc::CTileBaseListBox2Mfc() -{ - m_bDisplayIDs = AfxGetApp()->GetProfileInt("Settings"_cbstring, "DisplayIDs"_cbstring, 0); - - m_bTipMarkItems = TRUE; - m_sizeTipMark = CSize(0, 0); -} - -///////////////////////////////////////////////////////////////////////////// - -CSize CTileBaseListBox2Mfc::DoOnItemSize(size_t nItem, const std::vector& tids) const -{ - ASSERT(!tids.empty() && tids[size_t(0)] != nullTid); // At least one tile needs to exist - - int nHt = 0; - for (size_t i = size_t(0); i < tids.size(); ++i) - { - CTile tile = GetTileManager().GetTile(tids[i], fullScale); - nHt = CB::max(nHt, tile.GetHeight()); - } - - // Listbox lines can only be 255 pixels high. - nHt = CB::min(2 * tileBorder + nHt, 255); - - if (m_bDisplayIDs || m_bTipMarkItems) // See if we're drawing debug ID's - nHt = CB::max(nHt, value_preserving_cast(g_res.tm8ss.tmHeight + g_res.tm8ss.tmExternalLeading)); - - BOOL bItemHasTipText = OnDoesItemHaveTipText(nItem); - - // only using DC for measurement, so const_cast safe - CClientDC pDC(const_cast(this)); - CRect rctItem(0, 0, 32000, 32000); - - pDC.SaveDC(); - - int x = rctItem.left + tileBorder; - - DrawTipMarker(pDC, rctItem, bItemHasTipText, x); - DrawItemDebugIDCode(pDC, nItem, rctItem, false, x); - for (size_t i = size_t(0); i < tids.size(); ++i) - { - DrawTileImage(pDC, rctItem, false, x, tids[i]); - } - - pDC.RestoreDC(-1); - - return CSize(x, nHt); -} - -///////////////////////////////////////////////////////////////////////////// - -void CTileBaseListBox2Mfc::DoOnDrawItem(CDC& pDC, size_t nItem, UINT nAction, UINT nState, - CRect rctItem, const std::vector& tids) const -{ - if (nAction & (ODA_DRAWENTIRE | ODA_SELECT)) - { - ASSERT(!tids.empty() && tids[size_t(0)] != nullTid); - - BOOL bItemHasTipText = OnDoesItemHaveTipText(nItem); - - pDC.SaveDC(); - pDC.IntersectClipRect(&rctItem); - pDC.SetBkMode(TRANSPARENT); - - CBrush brBack(GetSysColor(nState & ODS_SELECTED ? - COLOR_HIGHLIGHT : COLOR_WINDOW)); - pDC.FillRect(&rctItem, &brBack); // Fill background color - - pDC.SetTextColor(GetSysColor(nState & ODS_SELECTED ? - COLOR_HIGHLIGHTTEXT : COLOR_WINDOWTEXT)); - - int x = rctItem.left + tileBorder; - - DrawTipMarker(pDC, rctItem, bItemHasTipText, x); - DrawItemDebugIDCode(pDC, nItem, rctItem, TRUE, x); - for (size_t i = size_t(0); i < tids.size(); ++i) - { - DrawTileImage(pDC, rctItem, true, x, tids[i]); - } - - pDC.RestoreDC(-1); - } - if (nAction & ODA_FOCUS) - pDC.DrawFocusRect(&rctItem); -} - -///////////////////////////////////////////////////////////////////////////// - -void CTileBaseListBox2Mfc::DrawTileImage(CDC& pDC, CRect rctItem, BOOL bDrawIt, int& x, TileID tid) const -{ - if (tid == nullTid) - return; // Nothing to do - - CTile tile = GetTileManager().GetTile(tid, fullScale); - - if (bDrawIt) - { - if (tile.GetHeight() >= 255) - tile.BitBlt(pDC, x, rctItem.top + tileBorder);// Too large. Don't draw vertically centered - else - tile.BitBlt(pDC, x, (rctItem.Height() - tile.GetHeight()) / 2 + rctItem.top); - } - x += tile.GetWidth() + tileGap; -} - -///////////////////////////////////////////////////////////////////////////// -// Optionally draw debug code string for item. If bDrawIt is false, -// x is advanced the size of the string anyway but nothing is rendered - -void CTileBaseListBox2Mfc::DrawItemDebugIDCode(CDC& pDC, size_t nItem, CRect rctItem, BOOL bDrawIt, int& x) const -{ - if (m_bDisplayIDs) - { - CB::string str = OnGetItemDebugString(nItem); - - CFont* prvFont = (CFont*)pDC.SelectObject(CFont::FromHandle(g_res.h8ss)); - int y = rctItem.top + rctItem.Height() / 2 - - (g_res.tm8ss.tmHeight + g_res.tm8ss.tmExternalLeading) / 2; - if (bDrawIt) - pDC.TextOut(x, y, str); - x += pDC.GetTextExtent(str).cx; - pDC.SelectObject(prvFont); - } -} - -///////////////////////////////////////////////////////////////////////////// - -void CTileBaseListBox2Mfc::SetupTipMarkerIfRequired() -{ - if (m_bTipMarkItems) - { - ASSERT(m_hWnd != NULL); - if (m_sizeTipMark.cx == 0) - { - // Hasn't been initialized yet. - m_strTipMark = CB::string::LoadString(IDS_TIP_LBOXITEM_MARKER); - - CDC* pDC = GetDC(); - - CFont* prvFont = (CFont*)pDC->SelectObject(CFont::FromHandle(g_res.h8ss)); - m_sizeTipMark.cx = pDC->GetTextExtent(m_strTipMark).cx; - m_sizeTipMark.cy = g_res.tm8ss.tmHeight + g_res.tm8ss.tmExternalLeading; - pDC->SelectObject(prvFont); - - ReleaseDC(pDC); - } - } -} - -void CTileBaseListBox2Mfc::DrawTipMarker(CDC& pDC, CRect rctItem, BOOL bVisible, int& x) const -{ - if (m_bTipMarkItems) - { - CFont* prvFont = (CFont*)pDC.SelectObject(CFont::FromHandle(g_res.h8ss)); - if (bVisible) // Draw only if visible. Else just move 'x' - { - int y = rctItem.top + (rctItem.Height() - m_sizeTipMark.cy) / 2; - pDC.TextOut(x, y, m_strTipMark); - } - x += m_sizeTipMark.cx; - pDC.SelectObject(prvFont); - } -} - -CB::string CTileBaseListBox2Mfc::OnGetItemDebugString(size_t nItem) const -{ - return std::format(L"[{}] ", OnGetItemDebugIDCode(nItem)); -} - -///////////////////////////////////////////////////////////////////////////// - -std::vector CTileBaseListBox2Mfc::GetTileRectsForItem(size_t nItem, - const std::vector& tids) const -{ - ASSERT(!tids.empty() && tids[size_t(0)] != nullTid); - - CRect rctItem; - GetItemRect(value_preserving_cast(nItem), &rctItem); - - int x = rctItem.left + tileBorder; // Set starting x position - - // Need to account for possible markers and debug strings - // rendered to left of tile images - // only using DC for measurement, so const_cast safe - CDC& pDC = CheckedDeref(const_cast(this)->GetDC()); - DrawTipMarker(pDC, rctItem, FALSE, x); - DrawItemDebugIDCode(pDC, nItem, rctItem, FALSE, x); - const_cast(this)->ReleaseDC(&pDC); - - std::vector retval(tids.size()); - for (size_t i = size_t(0); i < tids.size(); ++i) - { - retval[i].SetRectEmpty(); - retval[i].top = rctItem.top; // Set the top & bottom values - retval[i].bottom = rctItem.bottom; - retval[i].left = x; - DrawTileImage(pDC, rctItem, FALSE, x, tids[i]); - retval[i].right = x; - } - return retval; -} - -int CTileBaseListBox2Mfc::OnCreate(LPCREATESTRUCT lpCreateStruct) -{ - int retval = CGrafixListBox2Mfc::OnCreate(lpCreateStruct); - if (retval == 0) - { - SetupTipMarkerIfRequired(); - } - return retval; -} - - diff --git a/GShr/LBoxTileBase2.h b/GShr/LBoxTileBase2.h index 119ddcb5..6640ea6e 100644 --- a/GShr/LBoxTileBase2.h +++ b/GShr/LBoxTileBase2.h @@ -34,7 +34,6 @@ #include "Tile.h" #endif -#if 1 /////////////////////////////////////////////////////////////////////// class CTileBaseListBox2 : public CGrafixListBox2 @@ -84,56 +83,4 @@ class CTileBaseListBox2 : public CGrafixListBox2 }; -#endif -/////////////////////////////////////////////////////////////////////// - -class CTileBaseListBox2Mfc : public CGrafixListBox2Mfc -{ -public: - CTileBaseListBox2Mfc(); - - void SetTipMarkVisibility(BOOL bShow = TRUE) { m_bTipMarkItems = bShow; } - BOOL GetTipMarkVisibility() const { return m_bTipMarkItems; } - -// Vars... -protected: - int m_bDisplayIDs; // Set by property [Settings]:DisplayIDs - - BOOL m_bTipMarkItems; - CB::string m_strTipMark; - CSize m_sizeTipMark; - -// Helpers... -protected: - void DrawTileImage(CDC& pDC, CRect rctItem, BOOL bDrawIt, int& x, TileID tid) const; - void DrawItemDebugIDCode(CDC& pDC, size_t nItem, CRect rctItem, BOOL bDrawIt, int& x) const; - - void SetupTipMarkerIfRequired(); - void DrawTipMarker(CDC& pDC, CRect rctItem, BOOL bVisible, int& x) const; - - CSize DoOnItemSize(size_t nItem, const std::vector& tids) const; - void DoOnDrawItem(CDC& pDC, size_t nItem, UINT nAction, UINT nState, CRect rctItem, - const std::vector& tids) const; - - std::vector GetTileRectsForItem(size_t nItem, const std::vector& tids) const; - -// Overrides... -public: - virtual const CTileManager& GetTileManager() const /* override */ = 0; - -// Overrides... -protected: - virtual BOOL OnDoesItemHaveTipText(size_t nItem) const /* override */ { return FALSE; } - - // Subclass should only override one of these if any... - virtual const void* OnGetItemDebugIDCode(size_t nItem) const /* override */ { return &MapIndexToItem(nItem); } - virtual CB::string OnGetItemDebugString(size_t nItem) const /* override */; - - //{{AFX_MSG(CTileBaseListBox) - afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - - #endif From 581b53a31e046fc2c27d06ef440dd4d9c04e48fd Mon Sep 17 00:00:00 2001 From: Bill Su Date: Sat, 27 Sep 2025 14:42:55 -0400 Subject: [PATCH 36/80] VwPbrd: code cleanup improve const, null, and override correctness replace MFC UIntArray with std::vector use return values instead of out-params --- GP/GamDoc.cpp | 2 +- GP/GamDoc4.cpp | 2 +- GP/GamDoc5.cpp | 2 +- GP/LBoxSlct.cpp | 2 +- GP/SelOPlay.cpp | 28 ++-- GP/ToolPlay.cpp | 140 ++++++++-------- GP/VwPbrd.cpp | 420 ++++++++++++++++++++++++------------------------ GP/VwPbrd.h | 65 ++++---- GP/VwPbrd1.cpp | 98 ++++++----- 9 files changed, 382 insertions(+), 377 deletions(-) diff --git a/GP/GamDoc.cpp b/GP/GamDoc.cpp index c91b91fd..8e39b292 100644 --- a/GP/GamDoc.cpp +++ b/GP/GamDoc.cpp @@ -551,7 +551,7 @@ CView* CGamDoc::FindPBoardView(const CPlayBoard& pPBoard) const CPlayBoardView* pView = (CPlayBoardView*)GetNextView(pos); if (pView->IsKindOf(RUNTIME_CLASS(CPlayBoardView))) { - if (pView->GetPlayBoard() == &pPBoard) + if (&pView->GetPlayBoard() == &pPBoard) return pView; } } diff --git a/GP/GamDoc4.cpp b/GP/GamDoc4.cpp index cb8a0a1c..5e7d6c8d 100644 --- a/GP/GamDoc4.cpp +++ b/GP/GamDoc4.cpp @@ -669,7 +669,7 @@ void CGamDoc::IndicateTextTipOnBoard(const CPlayBoard& pPBoard, if (IsQuietPlayback()) return; CPlayBoardView* pView = (CPlayBoardView*)FindPBoardView(pPBoard); ASSERT(pView != NULL); - pView->WorkspaceToClient(pointWorkspace); + pointWorkspace = pView->WorkspaceToClient(pointWorkspace); pView->SetNotificationTip(pointWorkspace, &pszStr); } diff --git a/GP/GamDoc5.cpp b/GP/GamDoc5.cpp index a18bd17d..1fa34add 100644 --- a/GP/GamDoc5.cpp +++ b/GP/GamDoc5.cpp @@ -331,7 +331,7 @@ void CGamDoc::EventShowBoardNotification(BoardID nBrdSerNum, CPoint pntTipLoc, c { EnsureBoardLocationVisible(*pPBoard, pntTipLoc); pView = (CPlayBoardView*)FindPBoardView(*pPBoard); - pView->WorkspaceToClient(pntTipLoc); + pntTipLoc = pView->WorkspaceToClient(pntTipLoc); } pView->SetNotificationTip(pntTipLoc, &strMsg); } diff --git a/GP/LBoxSlct.cpp b/GP/LBoxSlct.cpp index f437e4cb..8038a71b 100644 --- a/GP/LBoxSlct.cpp +++ b/GP/LBoxSlct.cpp @@ -241,7 +241,7 @@ void CSelectListBox::OnActTurnOver(wxCommandEvent& event) } else if (id == XRCID("ID_ACT_TURNOVER_SELECT")) { - const CPlayBoard& playBoard = CheckedDeref(view.GetPlayBoard()); + const CPlayBoard& playBoard = view.GetPlayBoard(); m_pDoc->AssignNewMoveGroup(); diff --git a/GP/SelOPlay.cpp b/GP/SelOPlay.cpp index 6362a0f7..8a560ca3 100644 --- a/GP/SelOPlay.cpp +++ b/GP/SelOPlay.cpp @@ -129,12 +129,12 @@ CRect CSelection::GetHandleRect(int nHandleID) const CPoint point = GetHandleLoc(nHandleID); // Convert point to client coords - m_pView->WorkspaceToClient(point); + point = m_pView->WorkspaceToClient(point); // Calc CRect of handle in device coords CRect rect(point.x-3, point.y-3, point.x+3, point.y+3); - m_pView->ClientToWorkspace(rect); + rect = m_pView->ClientToWorkspace(rect); return rect; } @@ -249,9 +249,9 @@ void CSelLine::UpdateObject(BOOL bInvalidate, CRect rctB; pObj.GetLine(rctB); rctB.NormalizeRect(); - m_pView->WorkspaceToClient(rctB); + rctB = m_pView->WorkspaceToClient(rctB); rctB.InflateRect(handleHalfWidth, handleHalfWidth); - m_pView->ClientToWorkspace(rctB); + rctB = m_pView->ClientToWorkspace(rctB); rctA |= rctB; // Make sure we erase the handles m_pView->InvalidateWorkspaceRect(&rctA, FALSE); } @@ -315,9 +315,9 @@ void CSelGeneric::UpdateObject(BOOL bInvalidate, if (bInvalidate) { CRect rct = m_pObj->GetRect(); - m_pView->WorkspaceToClient(rct); + rct = m_pView->WorkspaceToClient(rct); rct.InflateRect(handleHalfWidth, handleHalfWidth); - m_pView->ClientToWorkspace(rct); + rct = m_pView->ClientToWorkspace(rct); m_pView->InvalidateWorkspaceRect(&rct); } if (bUpdateObjectExtent) @@ -621,7 +621,7 @@ void CSelList::LoadTableWithObjectPtrs(std::vector>& pTb // This is a bit of a cheat....Since we know the originating view and // thus the board associated with it, we can call the draw list // method the arrange the pieces in the proper visual order. - CDrawList* pDwg = m_pView->GetPlayBoard()->GetPieceList(); + CDrawList* pDwg = m_pView->GetPlayBoard().GetPieceList(); ASSERT(pDwg != NULL); if (bVisualOrder) pDwg->ArrangeObjectPtrTableInVisualOrder(pTbl); @@ -650,7 +650,7 @@ BOOL CSelList::HasPieces() const BOOL CSelList::HasNonOwnedPieces() const { - const CPieceTable& pPTbl = m_pView->GetDocument()->GetPieceTable(); + const CPieceTable& pPTbl = m_pView->GetDocument().GetPieceTable(); for (const_iterator pos = begin() ; pos != end() ; ++pos) { const CSelection& pSel = **pos; @@ -666,7 +666,7 @@ BOOL CSelList::HasNonOwnedPieces() const BOOL CSelList::HasOwnedPieces() const { - const CPieceTable& pPTbl = m_pView->GetDocument()->GetPieceTable(); + const CPieceTable& pPTbl = m_pView->GetDocument().GetPieceTable(); for (const_iterator pos = begin() ; pos != end() ; ++pos) { const CSelection& pSel = **pos; @@ -682,7 +682,7 @@ BOOL CSelList::HasOwnedPieces() const BOOL CSelList::HasOwnedPiecesNotMatching(PlayerMask dwOwnerMask) const { - const CPieceTable& pPTbl = m_pView->GetDocument()->GetPieceTable(); + const CPieceTable& pPTbl = m_pView->GetDocument().GetPieceTable(); for (const_iterator pos = begin() ; pos != end() ; ++pos) { const CSelection& pSel = **pos; @@ -717,7 +717,7 @@ BOOL CSelList::HasFlippablePieces() const const CSelection& pSel = **pos; if (pSel.m_pObj->GetType() == CDrawObj::drawPieceObj) { - if (m_pView->GetDocument()->GetPieceTable().GetSides( + if (m_pView->GetDocument().GetPieceTable().GetSides( static_cast(*pSel.m_pObj).m_pid) >= size_t(2)) return TRUE; } @@ -780,7 +780,7 @@ void CSelList::LoadTableWithPieceIDs(std::vector& pTbl, BOOL bVisualOrd // This is a bit of a cheat....Since we know the originating view and // thus the board associated with it, we can call the draw list // method the arrange the pieces in the proper visual order. - CDrawList* pDwg = m_pView->GetPlayBoard()->GetPieceList(); + CDrawList* pDwg = m_pView->GetPlayBoard().GetPieceList(); ASSERT(pDwg != NULL); if (bVisualOrder) pDwg->ArrangePieceTableInVisualOrder(pTbl); @@ -791,7 +791,7 @@ void CSelList::LoadTableWithPieceIDs(std::vector& pTbl, BOOL bVisualOrd void CSelList::LoadTableWithOwnerStatePieceIDs(std::vector& pTbl, LoadFilter eWantOwned, BOOL bVisualOrder /* = TRUE */) { - CPieceTable& pPTbl = m_pView->GetDocument()->GetPieceTable(); + CPieceTable& pPTbl = m_pView->GetDocument().GetPieceTable(); pTbl.clear(); pTbl.reserve(size()); @@ -814,7 +814,7 @@ void CSelList::LoadTableWithOwnerStatePieceIDs(std::vector& pTbl, LoadF // This is a bit of a cheat....Since we know the originating view and // thus the board associated with it, we can call the draw list // method the arrange the pieces in the proper visual order. - CDrawList* pDwg = m_pView->GetPlayBoard()->GetPieceList(); + CDrawList* pDwg = m_pView->GetPlayBoard().GetPieceList(); ASSERT(pDwg != NULL); if (bVisualOrder) pDwg->ArrangePieceTableInVisualOrder(pTbl); diff --git a/GP/ToolPlay.cpp b/GP/ToolPlay.cpp index e779f73e..0ef633bb 100644 --- a/GP/ToolPlay.cpp +++ b/GP/ToolPlay.cpp @@ -1,6 +1,6 @@ // ToolPlay.cpp // -// Copyright (c) 1994-2020 By Dale L. Larson, All Rights Reserved. +// Copyright (c) 1994-2025 By Dale L. Larson & William Su, All Rights Reserved. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the @@ -111,12 +111,12 @@ bool CPlayTool::OnLButtonUp(CPlayBoardView* pView, UINT, CPoint point) void CPSelectTool::OnLButtonDown(CPlayBoardView* pView, UINT nFlags, CPoint point) { - CSelList* pSLst = pView->GetSelectList(); - CPlayBoard *pPBoard = pView->GetPlayBoard(); + CSelList& pSLst = pView->GetSelectList(); + CPlayBoard& pPBoard = pView->GetPlayBoard(); // If a a handle is clicked on, immediately start tracking the // resize. - if ((m_nHandleID = pSLst->HitTestHandles(point)) >= 0) + if ((m_nHandleID = pSLst.HitTestHandles(point)) >= 0) { StartSizingOperation(pView, nFlags, point); return; @@ -127,9 +127,9 @@ void CPSelectTool::OnLButtonDown(CPlayBoardView* pView, UINT nFlags, if (pObj != NULL && pObj->GetType() == CDrawObj::drawPieceObj) { CPieceObj* pPObj = (CPieceObj*)pObj; - PlayerMask dwCurrentPlayer = pView->GetDocument()->GetCurrentPlayerMask(); - bOwnedButNotOkToSelect = !pView->GetDocument()->IsScenario() && - !pPBoard->IsNonOwnerAccessAllowed() && + PlayerMask dwCurrentPlayer = pView->GetDocument().GetCurrentPlayerMask(); + bOwnedButNotOkToSelect = !pView->GetDocument().IsScenario() && + !pPBoard.IsNonOwnerAccessAllowed() && pPObj->IsOwned() && !pPObj->IsOwnedBy(dwCurrentPlayer); } @@ -138,10 +138,10 @@ void CPSelectTool::OnLButtonDown(CPlayBoardView* pView, UINT nFlags, // than the current player. if (pObj == NULL || bOwnedButNotOkToSelect || - (pPBoard->GetLocksEnforced() && (pObj->GetDObjFlags() & dobjFlgLockDown))) + (pPBoard.GetLocksEnforced() && (pObj->GetDObjFlags() & dobjFlgLockDown))) { if ((nFlags & MK_SHIFT) == 0) // Shift click adds to list - pSLst->PurgeList(TRUE); // Clear current select list + pSLst.PurgeList(TRUE); // Clear current select list // No objects were under the mouse click. m_eSelMode = smodeNet; // Net type selection CPlayTool::OnLButtonDown(pView, nFlags, point); @@ -152,15 +152,15 @@ void CPSelectTool::OnLButtonDown(CPlayBoardView* pView, UINT nFlags, } // Object is under mouse. See if also selected. If not, // add to list. - if (!pSLst->IsObjectSelected(*pObj)) + if (!pSLst.IsObjectSelected(*pObj)) { if ((nFlags & MK_SHIFT) == 0) // Shift click adds to list - pSLst->PurgeList(TRUE); // Clear current select list + pSLst.PurgeList(TRUE); // Clear current select list if ((nFlags & MK_CONTROL) != 0) // Control click drills down pView->SelectAllUnderPoint(point); else { - pSLst->AddObject(*pObj, TRUE); + pSLst.AddObject(*pObj, TRUE); if (pObj->GetType() == CDrawObj::drawPieceObj || pObj->GetType() == CDrawObj::drawMarkObj) pView->NotifySelectListChange(); @@ -168,9 +168,9 @@ void CPSelectTool::OnLButtonDown(CPlayBoardView* pView, UINT nFlags, CPlayTool::OnLButtonDown(pView, nFlags, point); StartDragTimer(pView); - CRect rct = pSLst->GetEnclosingRect(); + CRect rct = pSLst.GetEnclosingRect(); CSize sizeOff = point - rct.TopLeft(); - pSLst->SetMouseOffset(sizeOff); + pSLst.SetMouseOffset(sizeOff); return; } // At this point we know s/he clicked on an object that was @@ -179,22 +179,22 @@ void CPSelectTool::OnLButtonDown(CPlayBoardView* pView, UINT nFlags, // wont start until it expires. if ((nFlags & MK_SHIFT) != 0) { - pSLst->RemoveObject(*pObj, TRUE); + pSLst.RemoveObject(*pObj, TRUE); return; } CPlayTool::OnLButtonDown(pView, nFlags, point); - pSLst->SetSnapReferenceObject(pObj); - CRect rct = pSLst->GetSnapReferenceRect(); + pSLst.SetSnapReferenceObject(pObj); + CRect rct = pSLst.GetSnapReferenceRect(); CSize sizeOff = point - rct.TopLeft(); - pSLst->SetMouseOffset(sizeOff); + pSLst.SetMouseOffset(sizeOff); StartDragTimer(pView); } void CPSelectTool::OnMouseMove(CPlayBoardView* pView, UINT nFlags, CPoint point) { - CSelList* pSLst = pView->GetSelectList(); + CSelList& pSLst = pView->GetSelectList(); if (CWnd::GetCapture() != pView) return; @@ -242,24 +242,24 @@ void CPSelectTool::OnMouseMove(CPlayBoardView* pView, UINT nFlags, CPoint point) // tracking image. if (m_eSelMode == smodeMove) { - pView->WorkspaceToClient(point); + point = pView->WorkspaceToClient(point); DoDragDrop(pView, point); return; } else if (m_eSelMode == smodeSizing) { - pView->AdjustPoint(point); + point = pView->AdjustPoint(point); if (point == c_ptLast) return; CClientDC dc(pView); pView->OnPrepareScaledDC(dc, TRUE); - pSLst->DrawTracker(dc, trkSizing); // Erase previous tracker + pSLst.DrawTracker(dc, trkSizing); // Erase previous tracker - MoveSelections(pSLst, point); + MoveSelections(&pSLst, point); - pSLst->DrawTracker(dc, trkSizing); // Erase previous tracker + pSLst.DrawTracker(dc, trkSizing); // Erase previous tracker } c_ptLast = point; // Save new 'last' position } @@ -281,24 +281,24 @@ bool CPSelectTool::OnLButtonUp(CPlayBoardView* pView, UINT nFlags, CPoint point) CRect rect(c_ptDown.x, c_ptDown.y, c_ptLast.x, c_ptLast.y); rect.NormalizeRect(); pView->SelectWithinRect(rect, (nFlags & MK_CONTROL) != 0); - CSelList* pSLst = pView->GetSelectList(); - pSLst->InvalidateListHandles(); + CSelList& pSLst = pView->GetSelectList(); + pSLst.InvalidateListHandles(); } else if (m_eSelMode != smodeNormal) { - CSelList* pSLst = pView->GetSelectList(); + CSelList& pSLst = pView->GetSelectList(); if (m_eSelMode == smodeMove) { CPoint pnt = point; - pSLst->SetTrackingMode(trkSelected); - pView->WorkspaceToClient(pnt); + pSLst.SetTrackingMode(trkSelected); + pnt = pView->WorkspaceToClient(pnt); retval = DoDragDropEnd(pView, pnt) && retval; } else { - pSLst->SetTrackingMode(trkSelected); - pSLst->UpdateObjects(TRUE); - pSLst->InvalidateListHandles(); + pSLst.SetTrackingMode(trkSelected); + pSLst.UpdateObjects(TRUE); + pSLst.InvalidateListHandles(); } } } @@ -323,7 +323,7 @@ void CPSelectTool::OnTimer(CPlayBoardView* pView, uintptr_t nIDEvent) } if (m_eSelMode == smodeNormal) { - CSelList* pSLst = pView->GetSelectList(); + CSelList& pSLst = pView->GetSelectList(); // Mouse is captured and no particular drag operation // is underway. Therefore we want a move that draws @@ -333,16 +333,16 @@ void CPSelectTool::OnTimer(CPlayBoardView* pView, uintptr_t nIDEvent) CClientDC dc(pView); pView->OnPrepareScaledDC(dc, TRUE); - pSLst->DrawTracker(dc, trkSelected); // Turn off handles + pSLst.DrawTracker(dc, trkSelected); // Turn off handles CPoint point; GetCursorPos(&point); pView->ScreenToClient(&point); - pView->ClientToWorkspace(point); + point = pView->ClientToWorkspace(point); - pSLst->SetTrackingMode(trkMoving); + pSLst.SetTrackingMode(trkMoving); DoDragDropStart(pView); - pView->WorkspaceToClient(point); + point = pView->WorkspaceToClient(point); DoDragDrop(pView, point); } else if (m_eSelMode != smodeMove) @@ -358,7 +358,7 @@ void CPSelectTool::OnLButtonDblClk(CPlayBoardView* pView, UINT nFlags, // Normal DblClk opens some property view of the selected // object. Only recognized if only one selection is active. CPlayTool::OnLButtonDblClk(pView, nFlags, point); - pView->GetSelectList()->Open(); + pView->GetSelectList().Open(); } BOOL CPSelectTool::OnSetCursor(CPlayBoardView* pView, UINT nHitTest) @@ -371,16 +371,16 @@ BOOL CPSelectTool::OnSetCursor(CPlayBoardView* pView, UINT nHitTest) CPoint point; GetCursorPos(&point); pView->ScreenToClient(&point); - pView->ClientToWorkspace(point); + point = pView->ClientToWorkspace(point); // Check for movement through handle areas. Set the // cursor to the appropriate shape. - CSelList* pSLst = pView->GetSelectList(); - if (pSLst->IsSingleSelect()) + CSelList& pSLst = pView->GetSelectList(); + if (pSLst.IsSingleSelect()) { // Check if cursor is over a handle. If it is, // get handle cursor. - CSelection& pSelObj = *pSLst->front(); + CSelection& pSelObj = *pSLst.front(); int nHandle = pSelObj.HitTestHandles(point); if (nHandle >= 0) { @@ -394,14 +394,14 @@ BOOL CPSelectTool::OnSetCursor(CPlayBoardView* pView, UINT nHitTest) void CPSelectTool::StartSizingOperation(CPlayBoardView* pView, UINT nFlags, CPoint point, int nHandleID) { - CSelList* pSLst = pView->GetSelectList(); + CSelList& pSLst = pView->GetSelectList(); if (nHandleID != -1) m_nHandleID = nHandleID; m_eSelMode = smodeSizing; CPlayTool::OnLButtonDown(pView, nFlags, point); CClientDC dc(pView); pView->OnPrepareScaledDC(dc, TRUE); - pSLst->DrawTracker(dc, trkSizing); + pSLst.DrawTracker(dc, trkSizing); } void CPSelectTool::DrawSelectionRect(CDC* pDC, CRect* pRct) @@ -459,8 +459,8 @@ BOOL CPSelectTool::ProcessAutoScroll(CPlayBoardView* pView) BOOL bValidScroll = pView->OnScroll(nScrollID, 0, FALSE); if (bValidScroll) { - CSelList* pSLst = pView->GetSelectList(); - pView->ClientToWorkspace(point); + CSelList& pSLst = pView->GetSelectList(); + point = pView->ClientToWorkspace(point); CClientDC dc(pView); pView->OnPrepareScaledDC(dc, TRUE); @@ -473,14 +473,14 @@ BOOL CPSelectTool::ProcessAutoScroll(CPlayBoardView* pView) DrawSelectionRect(&dc, &rect); } else - pSLst->DrawTracker(dc); // Turn off tracker + pSLst.DrawTracker(dc); // Turn off tracker pView->OnScroll(nScrollID, 0, TRUE); pView->UpdateWindow(); // Redraw image content. AdjustPoint(pView, point); - MoveSelections(pSLst, point); // Offset the tracking data + MoveSelections(&pSLst, point); // Offset the tracking data c_ptLast = point; // Save new 'last' position pView->OnPrepareScaledDC(dc, TRUE); @@ -488,7 +488,7 @@ BOOL CPSelectTool::ProcessAutoScroll(CPlayBoardView* pView) { GetCursorPos(&point); pView->ScreenToClient(&point); - pView->ClientToWorkspace(point); + point = pView->ClientToWorkspace(point); c_ptLast = point; // Set new 'last' position // Draw updated net rect CRect rect(c_ptDown.x, c_ptDown.y, c_ptLast.x, c_ptLast.y); @@ -497,9 +497,9 @@ BOOL CPSelectTool::ProcessAutoScroll(CPlayBoardView* pView) } else { - MoveSelections(pSLst, point);// Offset the tracking data + MoveSelections(&pSLst, point);// Offset the tracking data c_ptLast = point; // Save new 'last' position - pSLst->DrawTracker(dc); // Turn off tracker + pSLst.DrawTracker(dc); // Turn off tracker } return TRUE; } @@ -520,12 +520,12 @@ void CPSelectTool::MoveSelections(CSelList *pSLst, CPoint point) BOOL CPSelectTool::AdjustPoint(CPlayBoardView* pView, CPoint& point) { - pView->AdjustPoint(point); + point = pView->AdjustPoint(point); if (point == c_ptLast) return FALSE; if (m_eSelMode == smodeMove) { - CRect rct = pView->GetSelectList()->GetEnclosingRect(); + CRect rct = pView->GetSelectList().GetEnclosingRect(); CPoint pnt = pView->GetWorkspaceDim(); if (rct.left + point.x - c_ptLast.x < 0) // Clamp point.x = c_ptLast.x - rct.left; @@ -574,8 +574,8 @@ void CPSelectTool::KillScrollTimer(CPlayBoardView* pView) void CPSelectTool::DoDragDropStart(CPlayBoardView* pView) { m_di.SetDragType(DRAG_SELECTLIST); - m_di.GetSubInfo().m_selectList = pView->GetSelectList(); - m_di.GetSubInfo().m_gamDoc = pView->GetDocument(); + m_di.GetSubInfo().m_selectList = &pView->GetSelectList(); + m_di.GetSubInfo().m_gamDoc = &pView->GetDocument(); m_di.m_hcsrSuggest = g_res.hcrDragTile; m_hLastWnd = NULL; @@ -646,12 +646,12 @@ bool CPSelectTool::DoDragDropEnd(CPlayBoardView* pView, CPoint pntClient) void CPShapeTool::OnLButtonDown(CPlayBoardView* pView, UINT nFlags, CPoint point) { - CSelList* pSLst = pView->GetSelectList(); - pSLst->PurgeList(TRUE); // Clear current select list + CSelList& pSLst = pView->GetSelectList(); + pSLst.PurgeList(TRUE); // Clear current select list int nDragHandle; - pView->AdjustPoint(point); + point = pView->AdjustPoint(point); m_pObj = CreateDrawObj(pView, point, nDragHandle); - pSLst->AddObject(*m_pObj, TRUE); + pSLst.AddObject(*m_pObj, TRUE); s_plySelectTool.StartSizingOperation(pView, nFlags, point, nDragHandle); } @@ -661,7 +661,7 @@ bool CPShapeTool::OnLButtonUp(CPlayBoardView* pView, UINT nFlags, CPoint point) return false; bool retval = true; retval = s_plySelectTool.OnLButtonUp(pView, nFlags, point) && retval; - pView->GetSelectList()->PurgeList(TRUE); // Clear current select list + pView->GetSelectList().PurgeList(TRUE); // Clear current select list if (!IsEmptyObject()) pView->AddDrawObject(m_pObj); else @@ -734,20 +734,20 @@ BOOL CPTextBoxTool::OnSetCursor(CPlayBoardView* pView, UINT nHitTest) void CPPlotTool::OnLButtonDown(CPlayBoardView* pView, UINT nFlags, CPoint point) { - CGamDoc* pDoc = pView->GetDocument(); - CPlayBoard* pPBrd = pView->GetPlayBoard(); - ASSERT(pPBrd->GetPlotMoveMode()); + CGamDoc& pDoc = pView->GetDocument(); + CPlayBoard& pPBrd = pView->GetPlayBoard(); + ASSERT(pPBrd.GetPlotMoveMode()); - if (pPBrd->m_bSnapMovePlot) - pView->AdjustPoint(point); // Keep on the grid (if enabled) + if (pPBrd.m_bSnapMovePlot) + point = pView->AdjustPoint(point); // Keep on the grid (if enabled) - CPoint pntPrev = pPBrd->GetPrevPlotPoint(); + CPoint pntPrev = pPBrd.GetPrevPlotPoint(); if (pntPrev == CPoint(-1, -1)) { // Draw a line for each piece to the opening location std::vector> listObjs; - pView->GetSelectList()->LoadTableWithObjectPtrs(listObjs, CSelList::otAll, FALSE); + pView->GetSelectList().LoadTableWithObjectPtrs(listObjs, CSelList::otAll, FALSE); for (auto pos = listObjs.begin() ; pos != listObjs.end() ; ++pos) { CDrawObj& pObj = **pos; @@ -755,12 +755,12 @@ void CPPlotTool::OnLButtonDown(CPlayBoardView* pView, UINT nFlags, pObj.GetType() == CDrawObj::drawMarkObj); CRect rct = pObj.GetRect(); CPoint pnt = GetMidRect(rct); - pDoc->IndicateBoardPlotLine(*pPBrd, pnt, point); + pDoc.IndicateBoardPlotLine(pPBrd, pnt, point); } } else - pDoc->IndicateBoardPlotLine(*pPBrd, pntPrev, point); - pPBrd->SetPrevPlotPoint(point); + pDoc.IndicateBoardPlotLine(pPBrd, pntPrev, point); + pPBrd.SetPrevPlotPoint(point); } BOOL CPPlotTool::OnSetCursor(CPlayBoardView* pView, UINT nHitTest) diff --git a/GP/VwPbrd.cpp b/GP/VwPbrd.cpp index a0d6ff15..d83b5c28 100644 --- a/GP/VwPbrd.cpp +++ b/GP/VwPbrd.cpp @@ -191,14 +191,14 @@ void CPlayBoardView::OnInitialUpdate() m_toolHitTip.SetMaxTipWidth(MAX_PLAYBOARD_TIP_WIDTH); m_pCurTipObj = NULL; - m_pPBoard = (CPlayBoard*)GetDocument()->GetNewViewParameter(); + m_pPBoard = (CPlayBoard*)GetDocument().GetNewViewParameter(); if (m_pPBoard == NULL) { // See if we can get our playing board from the (0, 0) pane in the splitter. CSplitterWndEx* pParent = (CSplitterWndEx*)GetParent(); CPlayBoardView* pPlay = (CPlayBoardView*)pParent->GetPane(0, 0); - m_pPBoard = pPlay->GetPlayBoard(); + m_pPBoard = &pPlay->GetPlayBoard(); } ASSERT(m_pPBoard != NULL); @@ -216,7 +216,7 @@ void CPlayBoardView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint) else if (lHint == HINT_BOARDCHANGE) { // Make sure we still exist! - if (GetDocument()->GetPBoardManager().FindPBoardByRef(CheckedDeref(m_pPBoard)) == Invalid_v) + if (GetDocument().GetPBoardManager().FindPBoardByRef(CheckedDeref(m_pPBoard)) == Invalid_v) { CFrameWnd* pFrm = GetParentFrame(); ASSERT(pFrm != NULL); @@ -315,7 +315,7 @@ void CPlayBoardView::NotifySelectListChange() CGamDocHint hint; hint.GetArgs().m_pPBoard = m_pPBoard.get(); hint.GetArgs().m_pSelList = &m_selList; - GetDocument()->UpdateAllViews(this, HINT_UPDATESELECT, &hint); + GetDocument().UpdateAllViews(this, HINT_UPDATESELECT, &hint); } /////////////////////////////////////////////////////////////////////// @@ -365,7 +365,7 @@ LRESULT CPlayBoardView::OnMessageWindowState(WPARAM wParam, LPARAM lParam) for (size_t i = 0; i < tblObjPtrs.size(); i++) { CDrawObj& pObj = *tblObjPtrs.at(i); - ar << GetDocument()->GetGameElementCodeForObject(pObj); + ar << GetDocument().GetGameElementCodeForObject(pObj); } } else @@ -476,7 +476,7 @@ void CPlayBoardView::OnDraw(CDC* pDC) m_pPBoard->Draw(dcMem, &rct, m_nZoom); wxASSERT(!pDC->IsPrinting()); - if (!pDC->IsPrinting() && GetPlayBoard()->GetPiecesVisible()) + if (!pDC->IsPrinting() && GetPlayBoard().GetPiecesVisible()) m_selList.OnDraw(dcMem); // Handle selections. RestoreDrawListDC(dcMem); @@ -507,10 +507,10 @@ LRESULT CPlayBoardView::OnDragItem(WPARAM wParam, LPARAM lParam) { return -1; } - if (GetDocument()->IsPlaying()) + if (GetDocument().IsPlaying()) return -1; // Drags not supported during play - DragInfo& pdi = CheckedDeref(reinterpret_cast(lParam)); + const DragInfo& pdi = CheckedDeref(reinterpret_cast(lParam)); if (pdi.GetDragType() == DRAG_PIECE) return DoDragPiece(pdi); @@ -527,10 +527,10 @@ LRESULT CPlayBoardView::OnDragItem(WPARAM wParam, LPARAM lParam) return 0; } -LRESULT CPlayBoardView::DoDragPiece(DragInfo& pdi) +LRESULT CPlayBoardView::DoDragPiece(const DragInfo& pdi) { ASSERT(FALSE); //!!!NOT USED???? //TODO: WHAT'S GOING ON HERE? 20200618 - if (pdi.GetSubInfo().m_gamDoc != GetDocument()) + if (pdi.GetSubInfo().m_gamDoc != &GetDocument()) return -1; // Only pieces from our document. // if piece can't fit on board, reject drop @@ -554,16 +554,16 @@ LRESULT CPlayBoardView::DoDragPiece(DragInfo& pdi) else if (pdi.m_phase == PhaseDrag::Drop) { CPoint pnt = pdi.m_point; - ClientToWorkspace(pnt); + pnt = ClientToWorkspace(pnt); AddPiece(pnt, pdi.GetSubInfo().m_pieceID); DragKillAutoScroll(); } return 1; } -LRESULT CPlayBoardView::DoDragPieceList(DragInfo& pdi) +LRESULT CPlayBoardView::DoDragPieceList(const DragInfo& pdi) { - if (pdi.GetSubInfo().m_gamDoc != GetDocument()) + if (pdi.GetSubInfo().m_gamDoc != &GetDocument()) return -1; // Only pieces from our document. // if piece can't fit on board, reject drop @@ -586,27 +586,27 @@ LRESULT CPlayBoardView::DoDragPieceList(DragInfo& pdi) } else if (pdi.m_phase == PhaseDrag::Drop) { - CGamDoc* pDoc = GetDocument(); + CGamDoc& pDoc = GetDocument(); CPoint pnt = pdi.m_point; const std::vector& pTbl = CheckedDeref(pdi.GetSubInfo().m_pieceIDList); - ClientToWorkspace(pnt); + pnt = ClientToWorkspace(pnt); // If the snap grid is on, adjust the point. - CSize sz = GetDocument()->GetPieceTable().GetStackedSize(pTbl, + CSize sz = GetDocument().GetPieceTable().GetStackedSize(pTbl, m_pPBoard->m_xStackStagger, m_pPBoard->m_yStackStagger); ASSERT(sz.cx != 0 && sz.cy != 0); CRect rct(CPoint(pnt.x - sz.cx/2, pnt.y - sz.cy/2), sz); - AdjustRect(rct); + rct = AdjustRect(rct); pnt = GetMidRect(rct); m_selList.PurgeList(TRUE); // Purge former selections - GetDocument()->AssignNewMoveGroup(); - GetDocument()->PlacePieceListOnBoard(pnt, pTbl, + GetDocument().AssignNewMoveGroup(); + GetDocument().PlacePieceListOnBoard(pnt, pTbl, m_pPBoard->m_xStackStagger, m_pPBoard->m_yStackStagger, m_pPBoard.get()); - if (!pDoc->HasPlayers() || !m_pPBoard->IsOwned() || + if (!pDoc.HasPlayers() || !m_pPBoard->IsOwned() || m_pPBoard->IsNonOwnerAccessAllowed() || - m_pPBoard->IsOwnedBy(pDoc->GetCurrentPlayerMask())) + m_pPBoard->IsOwnedBy(pDoc.GetCurrentPlayerMask())) { CDrawList* pDwg = m_pPBoard->GetPieceList(); std::vector> pceList; @@ -623,11 +623,11 @@ LRESULT CPlayBoardView::DoDragPieceList(DragInfo& pdi) #define MARKER_DROP_GAP_X 8 -LRESULT CPlayBoardView::DoDragMarker(DragInfo& pdi) +LRESULT CPlayBoardView::DoDragMarker(const DragInfo& pdi) { ASSERT(pdi.GetDragType() == DRAG_MARKER); - CGamDoc* pDoc = GetDocument(); - if (pdi.GetSubInfo().m_gamDoc != pDoc) + CGamDoc& pDoc = GetDocument(); + if (pdi.GetSubInfo().m_gamDoc != &pDoc) return -1; // Only markers from our document. // if marker can't fit on board, reject drop @@ -650,10 +650,10 @@ LRESULT CPlayBoardView::DoDragMarker(DragInfo& pdi) } else if (pdi.m_phase == PhaseDrag::Drop) { - CMarkManager& pMMgr = pDoc->GetMarkManager(); + CMarkManager& pMMgr = pDoc.GetMarkManager(); CPoint pnt = pdi.m_point; MarkID mid = pdi.GetSubInfo().m_markID; - ClientToWorkspace(pnt); + pnt = ClientToWorkspace(pnt); // If Control is held and the marker tray is set to // deliver random markers, prompt for a count of markers @@ -664,7 +664,7 @@ LRESULT CPlayBoardView::DoDragMarker(DragInfo& pdi) // I'm going to cheat. I happen to know that marker drops // can only originate at the marker palette. I can find out // the current marker set this way. - size_t nMrkGrp = pDoc->m_palMark.GetSelectedMarkerGroup(); + size_t nMrkGrp = pDoc.m_palMark.GetSelectedMarkerGroup(); ASSERT(nMrkGrp != Invalid_v); if (nMrkGrp == Invalid_v) goto NASTY_GOTO_TARGET; @@ -684,7 +684,7 @@ LRESULT CPlayBoardView::DoDragMarker(DragInfo& pdi) // Pull markers randomly from the marker group. tblMarks.reserve(1); tblMarks.push_back(mid); // Add the first one that was dropped - pMSet.GetRandomSelection(value_preserving_cast(dlg.m_nMarkerCount - 1), tblMarks, pDoc); + pMSet.GetRandomSelection(value_preserving_cast(dlg.m_nMarkerCount - 1), tblMarks, &pDoc); } else { @@ -705,9 +705,9 @@ LRESULT CPlayBoardView::DoDragMarker(DragInfo& pdi) sizeMin += CSize(MARKER_DROP_GAP_X, 0); } CRect rct(CPoint(pnt.x - sizeMin.cx/2, pnt.y - sizeMin.cy), sizeMin); - LimitRect(rct); // Make sure stays on board. + rct = LimitRect(rct); // Make sure stays on board. - pDoc->AssignNewMoveGroup(); + pDoc.AssignNewMoveGroup(); int x = rct.right; int y = (rct.top + rct.bottom) / 2; // Load the list from right ot left so the objects @@ -716,7 +716,7 @@ LRESULT CPlayBoardView::DoDragMarker(DragInfo& pdi) for (i = dlg.m_nMarkerCount - 1; i >= 0; i--) { CSize size = pMMgr.GetMarkSize(tblMarks[value_preserving_cast(i)]); - CDrawObj& pObj = pDoc->CreateMarkerObject(m_pPBoard.get(), tblMarks[value_preserving_cast(i)], + CDrawObj& pObj = pDoc.CreateMarkerObject(m_pPBoard.get(), tblMarks[value_preserving_cast(i)], CPoint(x - size.cx / 2, y), ObjectID()); x -= size.cx + MARKER_DROP_GAP_X; m_selList.AddObject(pObj, TRUE); @@ -731,11 +731,11 @@ LRESULT CPlayBoardView::DoDragMarker(DragInfo& pdi) CSize sz = pMMgr.GetMarkSize(mid); ASSERT(sz.cx != 0 && sz.cy != 0); CRect rct(CPoint(pnt.x - sz.cx/2, pnt.y - sz.cy/2), sz); - AdjustRect(rct); + rct = AdjustRect(rct); pnt = GetMidRect(rct); - pDoc->AssignNewMoveGroup(); - CDrawObj& pObj = pDoc->CreateMarkerObject(m_pPBoard.get(), mid, pnt, ObjectID()); + pDoc.AssignNewMoveGroup(); + CDrawObj& pObj = pDoc.CreateMarkerObject(m_pPBoard.get(), mid, pnt, ObjectID()); // If marker is set to prompt for text on drop, show the // dialog. @@ -743,12 +743,12 @@ LRESULT CPlayBoardView::DoDragMarker(DragInfo& pdi) { CEditElementTextDialog dlg; - dlg.m_strText = pDoc->GetGameElementString(MakeMarkerElement(mid)); + dlg.m_strText = pDoc.GetGameElementString(MakeMarkerElement(mid)); if (dlg.ShowModal() == wxID_OK) { - GameElement elem = pDoc->GetGameElementCodeForObject(pObj); - pDoc->SetObjectText(elem, dlg.m_strText.empty() ? NULL : + GameElement elem = pDoc.GetGameElementCodeForObject(pObj); + pDoc.SetObjectText(elem, dlg.m_strText.empty() ? NULL : &dlg.m_strText); } } @@ -756,12 +756,12 @@ LRESULT CPlayBoardView::DoDragMarker(DragInfo& pdi) return 1; } -LRESULT CPlayBoardView::DoDragSelectList(DragInfo& pdi) +LRESULT CPlayBoardView::DoDragSelectList(const DragInfo& pdi) { - if (pdi.GetSubInfo().m_gamDoc != GetDocument()) + if (pdi.GetSubInfo().m_gamDoc != &GetDocument()) return -1; // Only pieces from our document. - ClientToWorkspace(pdi.m_point); + CPoint pdi_m_point = ClientToWorkspace(pdi.m_point); CSelList *pSLst = pdi.GetSubInfo().m_selectList; CDC& pDC = CheckedDeref(GetDC()); @@ -780,10 +780,10 @@ LRESULT CPlayBoardView::DoDragSelectList(DragInfo& pdi) CPoint pntSnapRefTopLeft = rctSnapRef.TopLeft(); CPoint pntMseOff = pntSnapRefTopLeft + pSLst->GetMouseOffset(); - CSize sizeDelta = pdi.m_point - pntMseOff; // Trial delta + CSize sizeDelta = pdi_m_point - pntMseOff; // Trial delta rctSnapRef += (CPoint)sizeDelta; // Calc trial new position - AdjustRect(rctSnapRef); // Force onto grid. + rctSnapRef = AdjustRect(rctSnapRef); // Force onto grid. sizeDelta = rctSnapRef.TopLeft() - pntSnapRefTopLeft; // Calc actual offset if (sizeDelta.cx != 0 || sizeDelta.cy != 0) @@ -796,7 +796,7 @@ LRESULT CPlayBoardView::DoDragSelectList(DragInfo& pdi) if (!IsRectFullyOnBoard(rctObjs, &bXOK, &bYOK)) { CRect temp = rctObjs; - LimitRect(temp); + temp = LimitRect(temp); // if enclosing rect can't fit on board, reject drop if (!IsRectFullyOnBoard(temp, &bXOK, &bYOK)) { @@ -829,7 +829,7 @@ LRESULT CPlayBoardView::DoDragSelectList(DragInfo& pdi) } else if (pdi.m_phase == PhaseDrag::Drop) { - CGamDoc* pDoc = GetDocument(); + CGamDoc& pDoc = GetDocument(); // Whoooopppp...Whoooopppp!!! Drop occurred here.... DragKillAutoScroll(); @@ -837,14 +837,14 @@ LRESULT CPlayBoardView::DoDragSelectList(DragInfo& pdi) pSLst->LoadTableWithObjectPtrs(listObjs, CSelList::otAll, FALSE); pSLst->PurgeList(FALSE); // Purge source list - pDoc->AssignNewMoveGroup(); - pDoc->PlaceObjectTableOnBoard(listObjs, rctObjs.TopLeft(), m_pPBoard.get()); + pDoc.AssignNewMoveGroup(); + pDoc.PlaceObjectTableOnBoard(listObjs, rctObjs.TopLeft(), m_pPBoard.get()); m_selList.PurgeList(TRUE); // Purge former selections - if (!pDoc->HasPlayers() || !m_pPBoard->IsOwned() || + if (!pDoc.HasPlayers() || !m_pPBoard->IsOwned() || m_pPBoard->IsNonOwnerAccessAllowed() || - m_pPBoard->IsOwnedBy(pDoc->GetCurrentPlayerMask())) + m_pPBoard->IsOwnedBy(pDoc.GetCurrentPlayerMask())) { SelectAllObjectsInTable(listObjs); // Reselect on this board. } @@ -852,7 +852,7 @@ LRESULT CPlayBoardView::DoDragSelectList(DragInfo& pdi) CFrameWnd* pFrame = GetParentFrame(); pFrame->SetActiveView(this); - pDoc->UpdateAllViews(this, HINT_UPDATESELECTLIST); + pDoc.UpdateAllViews(this, HINT_UPDATESELECTLIST); NotifySelectListChange(); } @@ -862,7 +862,7 @@ LRESULT CPlayBoardView::DoDragSelectList(DragInfo& pdi) void CPlayBoardView::DragDoAutoScroll() { CPoint ptBefore(0, 0); - ClientToWorkspace(ptBefore); + ptBefore = ClientToWorkspace(ptBefore); CDC *pDC = NULL; if (m_pDragSelList != NULL) @@ -881,7 +881,7 @@ void CPlayBoardView::DragDoAutoScroll() if (m_pDragSelList != NULL && bScrolled) { CPoint ptAfter(0, 0); - ClientToWorkspace(ptAfter); + ptAfter = ClientToWorkspace(ptAfter); CSize sizeDelta = ptAfter - ptBefore; if (sizeDelta.cx != 0 || sizeDelta.cy != 0) { @@ -943,7 +943,7 @@ void CPlayBoardView::DragKillAutoScroll() void CPlayBoardView::AddPiece(CPoint pnt, PieceID pid) { ASSERT(FALSE); //!!!!NO LONGER USED?!!!!! - GetDocument()->PlacePieceOnBoard(pnt, pid, m_pPBoard.get()); + GetDocument().PlacePieceOnBoard(pnt, pid, m_pPBoard.get()); } ///////////////////////////////////////////////////////////////////////////// @@ -993,10 +993,9 @@ void CPlayBoardView::RestoreDrawListDC(CDC& pDC) const ///////////////////////////////////////////////////////////////////////////// #ifdef _DEBUG -const CGamDoc* CPlayBoardView::GetDocument() const // non-debug version is inline +const CGamDoc& CPlayBoardView::GetDocument() const // non-debug version is inline { - const CGamDoc* retval = CB::ToCGamDoc(m_pDocument); - wxASSERT(retval); + const CGamDoc& retval = CheckedDeref(CB::ToCGamDoc(m_pDocument)); return retval; } #endif //_DEBUG @@ -1013,9 +1012,9 @@ void CPlayBoardView::OnContextMenu(CWnd* pWnd, CPoint point) if (bar.LoadMenuW(IDR_MENU_PLAYER_POPUPS)) { UINT nMenuNum; - if (GetDocument()->IsPlaying()) + if (GetDocument().IsPlaying()) nMenuNum = MENU_PV_PLAYMODE; - else if (GetDocument()->IsScenario()) + else if (GetDocument().IsScenario()) nMenuNum = MENU_PV_SCNMODE; else nMenuNum = MENU_PV_MOVEMODE; @@ -1041,10 +1040,10 @@ void CPlayBoardView::OnContextMenu(CWnd* pWnd, CPoint point) BOOL CPlayBoardView::IsBoardContentsAvailableToCurrentPlayer() const { if (m_pPBoard->IsNonOwnerAccessAllowed() || !m_pPBoard->IsOwned() || - GetDocument()->IsScenario()) + GetDocument().IsScenario()) return TRUE; - return m_pPBoard->IsOwnedBy(GetDocument()->GetCurrentPlayerMask()); + return m_pPBoard->IsOwnedBy(GetDocument().GetCurrentPlayerMask()); } void CPlayBoardView::OnLButtonDown(UINT nFlags, CPoint point) @@ -1058,7 +1057,7 @@ void CPlayBoardView::OnLButtonDown(UINT nFlags, CPoint point) PToolType eToolType = MapToolType(m_nCurToolID); CPlayTool& pTool = CPlayTool::GetTool(eToolType); // Allow pieces to be selected even during playback - ClientToWorkspace(point); + point = ClientToWorkspace(point); pTool.OnLButtonDown(this, nFlags, point); } @@ -1072,11 +1071,11 @@ void CPlayBoardView::OnMouseMove(UINT nFlags, CPoint point) DoToolTipHitProcessing(point); - if (!GetDocument()->IsPlaying()) + if (!GetDocument().IsPlaying()) { PToolType eToolType = MapToolType(m_nCurToolID); CPlayTool& pTool = CPlayTool::GetTool(eToolType); - ClientToWorkspace(point); + point = ClientToWorkspace(point); pTool.OnMouseMove(this, nFlags, point); } else @@ -1094,7 +1093,7 @@ void CPlayBoardView::OnLButtonUp(UINT nFlags, CPoint point) PToolType eToolType = MapToolType(m_nCurToolID); CPlayTool& pTool = CPlayTool::GetTool(eToolType); // Allow pieces to be selected even during playback - ClientToWorkspace(point); + point = ClientToWorkspace(point); bool rc = pTool.OnLButtonUp(this, nFlags, point); ASSERT(rc || pTool.m_eToolType == ptypeSelect); if (!rc && pTool.m_eToolType == ptypeSelect) @@ -1115,11 +1114,11 @@ void CPlayBoardView::OnLButtonDblClk(UINT nFlags, CPoint point) return; } - if (!GetDocument()->IsPlaying()) + if (!GetDocument().IsPlaying()) { PToolType eToolType = MapToolType(m_nCurToolID); CPlayTool& pTool = CPlayTool::GetTool(eToolType); - ClientToWorkspace(point); + point = ClientToWorkspace(point); pTool.OnLButtonDblClk(this, nFlags, point); } else @@ -1143,7 +1142,7 @@ void CPlayBoardView::OnTimer(uintptr_t nIDEvent) } else { - if (!GetDocument()->IsPlaying()) + if (!GetDocument().IsPlaying()) { PToolType eToolType = MapToolType(m_nCurToolID); CPlayTool& pTool = CPlayTool::GetTool(eToolType); @@ -1156,7 +1155,7 @@ void CPlayBoardView::OnTimer(uintptr_t nIDEvent) BOOL CPlayBoardView::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) { - if (GetDocument()->IsPlaying()) + if (GetDocument().IsPlaying()) return CScrollView::OnSetCursor(pWnd, nHitTest, message); PToolType eToolType = MapToolType(m_nCurToolID); @@ -1166,7 +1165,7 @@ BOOL CPlayBoardView::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) if (pTool.OnSetCursor(this, nHitTest)) return TRUE; } - if (GetDocument()->IsRecordingCompoundMove()) + if (GetDocument().IsRecordingCompoundMove()) { ::SetCursor(g_res.hcrCompMoveActive); return TRUE; @@ -1179,13 +1178,13 @@ BOOL CPlayBoardView::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) void CPlayBoardView::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) { - CGamDoc* pDoc = GetDocument(); - if (!pDoc->IsPlaying()) + CGamDoc& pDoc = GetDocument(); + if (!pDoc.IsPlaying()) { if (nChar == VK_ESCAPE) { - if (pDoc->IsRecordingCompoundMove()) - pDoc->RecordCompoundMoveDiscard(); + if (pDoc.IsRecordingCompoundMove()) + pDoc.RecordCompoundMoveDiscard(); else if (m_pPBoard->GetPlotMoveMode()) OnActPlotDiscard(); else @@ -1193,8 +1192,8 @@ void CPlayBoardView::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) } else if (nChar == VK_RETURN) { - if (pDoc->IsRecordingCompoundMove()) - pDoc->RecordCompoundMoveEnd(); + if (pDoc.IsRecordingCompoundMove()) + pDoc.RecordCompoundMoveEnd(); else if (m_pPBoard->GetPlotMoveMode()) OnActPlotDone(); } @@ -1207,7 +1206,7 @@ void CPlayBoardView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) if (!IsBoardContentsAvailableToCurrentPlayer()) return; - if (GetDocument()->IsPlaying()) + if (GetDocument().IsPlaying()) return; if (nChar == VK_DELETE) @@ -1221,7 +1220,7 @@ void CPlayBoardView::OnEditClear() if (!m_selList.HasMarkers()) return; // Nothing to do - ASSERT(!GetDocument()->IsPlaying() && m_selList.HasMarkers()); + ASSERT(!GetDocument().IsPlaying() && m_selList.HasMarkers()); if (m_pPBoard->GetPlotMoveMode()) OnActPlotDiscard(); @@ -1231,13 +1230,13 @@ void CPlayBoardView::OnEditClear() std::vector> listPtr; m_selList.LoadTableWithObjectPtrs(listPtr, CSelList::otAll, FALSE); m_selList.PurgeList(TRUE); // Purge selections - GetDocument()->AssignNewMoveGroup(); - GetDocument()->DeleteObjectsInTable(listPtr); + GetDocument().AssignNewMoveGroup(); + GetDocument().DeleteObjectsInTable(listPtr); } void CPlayBoardView::OnUpdateEditClear(CCmdUI* pCmdUI) { - pCmdUI->Enable(!GetDocument()->IsPlaying() && m_selList.HasMarkers()); + pCmdUI->Enable(!GetDocument().IsPlaying() && m_selList.HasMarkers()); } ////////////////////////////////////////////////////////////////////// @@ -1295,7 +1294,7 @@ void CPlayBoardView::DoViewScaleBrd(TileScale nZoom) CRect rctClient; GetClientRect(&rctClient); pntMid = rctClient.CenterPoint(); - ClientToWorkspace(pntMid); + pntMid = ClientToWorkspace(pntMid); } m_nZoom = nZoom; @@ -1373,7 +1372,7 @@ void CPlayBoardView::OnViewBoardRotate180() m_pPBoard->SetRotateBoard180(!m_pPBoard->IsBoardRotated180()); CGamDocHint hint; hint.GetArgs().m_pPBoard = m_pPBoard.get(); - GetDocument()->UpdateAllViews(NULL, HINT_UPDATEBOARD, &hint); + GetDocument().UpdateAllViews(NULL, HINT_UPDATEBOARD, &hint); } void CPlayBoardView::OnUpdateViewBoardRotate180(CCmdUI* pCmdUI) @@ -1396,7 +1395,7 @@ void CPlayBoardView::OnUpdatePlayTool(CCmdUI* pCmdUI) { // NOTE!!: The control ID's are assumed to be consecutive and // in the same order as the tool codes defined in MAINFRM.C - if (GetDocument()->IsPlaying()) + if (GetDocument().IsPlaying()) pCmdUI->Enable(FALSE); else pCmdUI->Enable(pCmdUI->m_nID == m_nCurToolID); @@ -1422,8 +1421,8 @@ void CPlayBoardView::DoAutostackOfSelectedObjects(int xStagger, int yStagger) m_selList.PurgeList(TRUE); // Purge former selections - GetDocument()->AssignNewMoveGroup(); - GetDocument()->PlaceObjectTableOnBoard(pntCenter, tblObjs, + GetDocument().AssignNewMoveGroup(); + GetDocument().PlaceObjectTableOnBoard(pntCenter, tblObjs, xStagger, yStagger, m_pPBoard.get()); // Reselect the pieces. @@ -1432,7 +1431,7 @@ void CPlayBoardView::DoAutostackOfSelectedObjects(int xStagger, int yStagger) void CPlayBoardView::OnUpdateActStack(CCmdUI* pCmdUI) { - if (GetDocument()->IsPlaying()) + if (GetDocument().IsPlaying()) pCmdUI->Enable(FALSE); else pCmdUI->Enable(m_selList.IsMultipleSelects()); @@ -1454,7 +1453,7 @@ void CPlayBoardView::OnActShuffleSelectedObjects() if (rct.IsRectEmpty()) return; - CGamDoc* pDoc = GetDocument(); // Shorthand pointer + CGamDoc& pDoc = GetDocument(); // Shorthand pointer CPoint pntCenter(MidPnt(rct.left, rct.right), MidPnt(rct.top, rct.bottom)); @@ -1464,11 +1463,11 @@ void CPlayBoardView::OnActShuffleSelectedObjects() m_selList.PurgeList(TRUE); // Purge former selections // Generate a shuffled index vector for the number of selected items - uint32_t nRandSeed = pDoc->GetRandomNumberSeed(); + uint32_t nRandSeed = pDoc.GetRandomNumberSeed(); size_t nNumIndices = tblObjs.size(); std::vector pnIndices = AllocateAndCalcRandomIndexVector(nNumIndices, nNumIndices, nRandSeed, &nRandSeed); - pDoc->SetRandomNumberSeed(nRandSeed); + pDoc.SetRandomNumberSeed(nRandSeed); // Create a shuffled table of objects... std::vector> tblRandObjs; @@ -1476,18 +1475,18 @@ void CPlayBoardView::OnActShuffleSelectedObjects() for (size_t i = size_t(0); i < tblObjs.size(); i++) tblRandObjs.emplace_back(&*tblObjs[value_preserving_cast(pnIndices[i])]); - pDoc->AssignNewMoveGroup(); + pDoc.AssignNewMoveGroup(); - if (pDoc->IsRecording()) + if (pDoc.IsRecording()) { // Insert a notification tip so there is some information // feedback during playback. CB::string strMsg = CB::string::Format(IDS_TIP_OBJS_SHUFFLED, tblRandObjs.size()); - pDoc->RecordEventMessage(strMsg, m_pPBoard->GetSerialNumber(), + pDoc.RecordEventMessage(strMsg, m_pPBoard->GetSerialNumber(), value_preserving_cast(pntCenter.x), value_preserving_cast(pntCenter.y)); } - pDoc->PlaceObjectTableOnBoard(tblRandObjs, m_pPBoard.get()); + pDoc.PlaceObjectTableOnBoard(tblRandObjs, m_pPBoard.get()); // Reselect the pieces. SelectAllObjectsInTable(tblRandObjs); // Reselect objects @@ -1495,7 +1494,7 @@ void CPlayBoardView::OnActShuffleSelectedObjects() void CPlayBoardView::OnUpdateActShuffleSelectedObjects(CCmdUI* pCmdUI) { - if (GetDocument()->IsPlaying()) + if (GetDocument().IsPlaying()) pCmdUI->Enable(FALSE); else pCmdUI->Enable(m_selList.IsMultipleSelects()); @@ -1512,8 +1511,8 @@ void CPlayBoardView::OnActToFront() m_selList.PurgeList(TRUE); // Purge former selections - GetDocument()->AssignNewMoveGroup(); - GetDocument()->PlaceObjectTableOnBoard(listObjs, rct.TopLeft(), + GetDocument().AssignNewMoveGroup(); + GetDocument().PlaceObjectTableOnBoard(listObjs, rct.TopLeft(), m_pPBoard.get(), placeTop); SelectAllObjectsInTable(listObjs); // Reselect pieces @@ -1521,7 +1520,7 @@ void CPlayBoardView::OnActToFront() void CPlayBoardView::OnUpdateActToFront(CCmdUI* pCmdUI) { - if (GetDocument()->IsPlaying()) + if (GetDocument().IsPlaying()) pCmdUI->Enable(FALSE); else pCmdUI->Enable(m_selList.IsAnySelects()); @@ -1538,8 +1537,8 @@ void CPlayBoardView::OnActToBack() m_selList.PurgeList(TRUE); // Purge former selections - GetDocument()->AssignNewMoveGroup(); - GetDocument()->PlaceObjectTableOnBoard(listObjs, rct.TopLeft(), + GetDocument().AssignNewMoveGroup(); + GetDocument().PlaceObjectTableOnBoard(listObjs, rct.TopLeft(), m_pPBoard.get(), placeBack); SelectAllObjectsInTable(listObjs); // Reselect pieces @@ -1547,7 +1546,7 @@ void CPlayBoardView::OnActToBack() void CPlayBoardView::OnUpdateActToBack(CCmdUI* pCmdUI) { - if (GetDocument()->IsPlaying()) + if (GetDocument().IsPlaying()) pCmdUI->Enable(FALSE); else pCmdUI->Enable(m_selList.IsAnySelects()); @@ -1583,19 +1582,19 @@ BOOL CPlayBoardView::OnActTurnOver(UINT id) m_selList.PurgeList(TRUE); // Purge former selections - CGamDoc* pDoc = GetDocument(); - pDoc->AssignNewMoveGroup(); + CGamDoc& pDoc = GetDocument(); + pDoc.AssignNewMoveGroup(); - if (pDoc->IsRecording() && flip == CPieceTable::fRandom) + if (pDoc.IsRecording() && flip == CPieceTable::fRandom) { // Insert a notification tip so there is some information // feedback during playback. CB::string strMsg = CB::string::LoadString(IDS_TIP_FLIP_RANDOM); - pDoc->RecordEventMessage(strMsg, m_pPBoard->GetSerialNumber(), + pDoc.RecordEventMessage(strMsg, m_pPBoard->GetSerialNumber(), value_preserving_cast(pntCenter.x), value_preserving_cast(pntCenter.y)); } - pDoc->InvertPlayingPieceTableOnBoard(listObjs, *m_pPBoard, flip); + pDoc.InvertPlayingPieceTableOnBoard(listObjs, *m_pPBoard, flip); SelectAllObjectsInTable(listObjs); // Reselect pieces @@ -1605,9 +1604,9 @@ BOOL CPlayBoardView::OnActTurnOver(UINT id) void CPlayBoardView::OnUpdateActTurnOver(CCmdUI* pCmdUI) { bool bEnabled = false; - CGamDoc* pDoc = GetDocument(); - if (pDoc->IsPlaying() || !pDoc->IsScenario() && - m_selList.HasOwnedPiecesNotMatching(pDoc->GetCurrentPlayerMask())) + CGamDoc& pDoc = GetDocument(); + if (pDoc.IsPlaying() || !pDoc.IsScenario() && + m_selList.HasOwnedPiecesNotMatching(pDoc.GetCurrentPlayerMask())) bEnabled = false; else bEnabled = m_selList.HasFlippablePieces(); @@ -1624,7 +1623,7 @@ void CPlayBoardView::OnActPlotMove() { // Do this call so we don't record the plot list in the // restoration record. - GetDocument()->CreateRecordListIfRequired(); + GetDocument().CreateRecordListIfRequired(); // Ok...finish plot setup m_pPBoard->SetPlotMoveMode(TRUE); m_pPBoard->InitPlotStartPoint(); @@ -1633,8 +1632,8 @@ void CPlayBoardView::OnActPlotMove() void CPlayBoardView::OnUpdateActPlotMove(CCmdUI* pCmdUI) { - if (GetDocument()->IsPlaying() || (!m_selList.HasPieces() && - !m_selList.HasMarkers()) || GetDocument()->IsScenario()) + if (GetDocument().IsPlaying() || (!m_selList.HasPieces() && + !m_selList.HasMarkers()) || GetDocument().IsScenario()) { if (pCmdUI->m_pSubMenu != NULL) { @@ -1662,29 +1661,29 @@ void CPlayBoardView::OnActPlotDone() CRect rct = m_selList.GetPiecesEnclosingRect(); CPoint ptPrev = m_pPBoard->GetPrevPlotPoint(); ptPrev -= CSize(rct.Width() / 2, rct.Height() / 2); - AdjustPoint(ptPrev); + ptPrev = AdjustPoint(ptPrev); std::vector> listObjs; m_selList.LoadTableWithObjectPtrs(listObjs, CSelList::otAll, FALSE); m_selList.PurgeList(TRUE); - GetDocument()->AssignNewMoveGroup(); + GetDocument().AssignNewMoveGroup(); // Note that PlaceObjectListOnBoard() automatically detects the // plotted move case and records that fact. - GetDocument()->PlaceObjectTableOnBoard(listObjs, ptPrev, m_pPBoard.get()); + GetDocument().PlaceObjectTableOnBoard(listObjs, ptPrev, m_pPBoard.get()); m_selList.PurgeList(TRUE); // Purge former selections SelectAllObjectsInTable(listObjs); // Select on this board. } m_pPBoard->SetPlotMoveMode(FALSE); - GetDocument()->UpdateAllBoardIndicators(*m_pPBoard); + GetDocument().UpdateAllBoardIndicators(*m_pPBoard); m_pPBoard->FlushAllIndicators(); m_nCurToolID = ID_PTOOL_SELECT; } void CPlayBoardView::OnUpdateActPlotDone(CCmdUI* pCmdUI) { - if (GetDocument()->IsPlaying() || GetDocument()->IsScenario()) + if (GetDocument().IsPlaying() || GetDocument().IsScenario()) { pCmdUI->Enable(FALSE); return; @@ -1695,14 +1694,14 @@ void CPlayBoardView::OnUpdateActPlotDone(CCmdUI* pCmdUI) void CPlayBoardView::OnActPlotDiscard() { m_pPBoard->SetPlotMoveMode(FALSE); - GetDocument()->UpdateAllBoardIndicators(*m_pPBoard); + GetDocument().UpdateAllBoardIndicators(*m_pPBoard); m_pPBoard->FlushAllIndicators(); m_nCurToolID = ID_PTOOL_SELECT; } void CPlayBoardView::OnUpdateActPlotDiscard(CCmdUI* pCmdUI) { - if (GetDocument()->IsPlaying() || GetDocument()->IsScenario()) + if (GetDocument().IsPlaying() || GetDocument().IsScenario()) { pCmdUI->Enable(FALSE); return; @@ -1717,7 +1716,7 @@ void CPlayBoardView::OnViewSnapGrid() void CPlayBoardView::OnUpdateViewSnapGrid(CCmdUI* pCmdUI) { - pCmdUI->Enable(!GetDocument()->IsPlaying()); + pCmdUI->Enable(!GetDocument().IsPlaying()); pCmdUI->SetCheck(m_pPBoard->m_bGridSnap); } @@ -1730,16 +1729,16 @@ void CPlayBoardView::OnUpdateEditSelAllMarkers(CCmdUI* pCmdUI) { CDrawList* pDwg = m_pPBoard->GetPieceList(); ASSERT(pDwg); - pCmdUI->Enable(!GetDocument()->IsPlaying() && pDwg->HasMarker()); + pCmdUI->Enable(!GetDocument().IsPlaying() && pDwg->HasMarker()); } void CPlayBoardView::OnActRotate() // ** TEST CODE ** // { std::vector tbl; - CGamDoc* pDoc = GetDocument(); + CGamDoc& pDoc = GetDocument(); m_selList.LoadTableWithPieceIDs(tbl); - TileID tid = pDoc->GetPieceTable().GetActiveTileID(tbl.front()); - CTile tile = pDoc->GetTileManager().GetTile(tid); + TileID tid = pDoc.GetPieceTable().GetActiveTileID(tbl.front()); + CTile tile = pDoc.GetTileManager().GetTile(tid); OwnerPtr bmap = tile.CreateBitmapOfTile(); wxASSERT(!"dead code"); #if 0 @@ -1752,9 +1751,9 @@ void CPlayBoardView::OnActRotate() // ** TEST CODE ** // void CPlayBoardView::OnUpdateActRotate(CCmdUI* pCmdUI) // ** TEST CODE ** // { - CGamDoc* pDoc = GetDocument(); - if (pDoc->IsPlaying() || m_pPBoard->GetPlotMoveMode() || !pDoc->IsScenario() && - m_selList.HasOwnedPiecesNotMatching(pDoc->GetCurrentPlayerMask())) + CGamDoc& pDoc = GetDocument(); + if (pDoc.IsPlaying() || m_pPBoard->GetPlotMoveMode() || !pDoc.IsScenario() && + m_selList.HasOwnedPiecesNotMatching(pDoc.GetCurrentPlayerMask())) pCmdUI->Enable(FALSE); else pCmdUI->Enable(m_selList.HasPieces()); @@ -1774,8 +1773,8 @@ void CPlayBoardView::OnRotatePiece(UINT nID) m_selList.PurgeList(TRUE); // Purge former selections - GetDocument()->AssignNewMoveGroup(); - GetDocument()->ChangePlayingPieceFacingTableOnBoard(listObjs, m_pPBoard.get(), + GetDocument().AssignNewMoveGroup(); + GetDocument().ChangePlayingPieceFacingTableOnBoard(listObjs, m_pPBoard.get(), uint16_t(5) * nFacing5DegCW); // Convert to degrees SelectAllObjectsInTable(listObjs); // Reselect pieces @@ -1783,10 +1782,10 @@ void CPlayBoardView::OnRotatePiece(UINT nID) void CPlayBoardView::OnUpdateRotatePiece(CCmdUI* pCmdUI, UINT nID) { - CGamDoc* pDoc = GetDocument(); - BOOL bEnabled = (m_selList.HasPieces() || m_selList.HasMarkers()) && !pDoc->IsPlaying(); - if (bEnabled && !pDoc->IsScenario() && - m_selList.HasOwnedPiecesNotMatching(pDoc->GetCurrentPlayerMask())) + CGamDoc& pDoc = GetDocument(); + BOOL bEnabled = (m_selList.HasPieces() || m_selList.HasMarkers()) && !pDoc.IsPlaying(); + if (bEnabled && !pDoc.IsScenario() && + m_selList.HasOwnedPiecesNotMatching(pDoc.GetCurrentPlayerMask())) { bEnabled = FALSE; } @@ -1817,7 +1816,7 @@ LRESULT CPlayBoardView::OnMessageCenterBoardOnPoint(WPARAM wParam, LPARAM lParam LRESULT CPlayBoardView::OnMessageRotateRelative(WPARAM wParam, LPARAM lParam) { - CGamDoc* pDoc = GetDocument(); + CGamDoc& pDoc = GetDocument(); int nRelativeRotation = (int)wParam; ASSERT(!m_tblCurPieces.empty()); ASSERT(m_tblCurAngles.size() == m_tblCurPieces.size()); @@ -1830,17 +1829,17 @@ LRESULT CPlayBoardView::OnMessageRotateRelative(WPARAM wParam, LPARAM lParam) CDrawObj& pDObj = *m_tblCurPieces[i]; if (pDObj.GetType() == CDrawObj::drawPieceObj) - pDoc->ChangePlayingPieceFacingOnBoard(static_cast(pDObj), m_pPBoard.get(), value_preserving_cast(nAngle)); + pDoc.ChangePlayingPieceFacingOnBoard(static_cast(pDObj), m_pPBoard.get(), value_preserving_cast(nAngle)); else if (pDObj.GetType() == CDrawObj::drawMarkObj) - pDoc->ChangeMarkerFacingOnBoard(static_cast(pDObj), m_pPBoard.get(), value_preserving_cast(nAngle)); + pDoc.ChangeMarkerFacingOnBoard(static_cast(pDObj), m_pPBoard.get(), value_preserving_cast(nAngle)); if (m_bWheelRotation && (pDObj.GetType() == CDrawObj::drawPieceObj || pDObj.GetType() == CDrawObj::drawMarkObj)) { // Calculate new rotated mid-point for object. CPoint pntRotate = RotatePointAroundPoint(m_pntWheelMid, - CPoint(m_tblXMidPnt[value_preserving_cast(i)], m_tblYMidPnt[value_preserving_cast(i)]), nRelativeRotation); + m_tblMidPnt[i], nRelativeRotation); CSize sizeDelta = pntRotate - GetMidRect(pDObj.GetEnclosingRect()); - pDoc->PlaceObjectOnBoard(m_pPBoard.get(), &pDObj, sizeDelta); + pDoc.PlaceObjectOnBoard(m_pPBoard.get(), &pDObj, sizeDelta); } } return (LRESULT)0; @@ -1861,15 +1860,14 @@ void CPlayBoardView::DoRotateRelative(BOOL bWheelRotation) m_bWheelRotation = bWheelRotation; CRotatePieceDialog dlg(*this); - CGamDoc* pDoc = GetDocument(); - CPieceTable& pPTbl = pDoc->GetPieceTable(); + CGamDoc& pDoc = GetDocument(); + CPieceTable& pPTbl = pDoc.GetPieceTable(); // Get a list of the selected pieces and save their current // rotations. m_tblCurAngles.clear(); m_tblCurPieces.clear(); - m_tblXMidPnt.RemoveAll(); - m_tblYMidPnt.RemoveAll(); + m_tblMidPnt.clear(); m_selList.LoadTableWithObjectPtrs(m_tblCurPieces, CSelList::otAll, FALSE); @@ -1893,8 +1891,7 @@ void CPlayBoardView::DoRotateRelative(BOOL bWheelRotation) (pDObj.GetType() == CDrawObj::drawPieceObj || pDObj.GetType() == CDrawObj::drawMarkObj)) { CPoint midPoint = GetMidRect(pDObj.GetEnclosingRect()); - m_tblXMidPnt.Add((UINT)midPoint.x); - m_tblYMidPnt.Add((UINT)midPoint.y); + m_tblMidPnt.push_back(midPoint); } } // If we're recording moves right now, suspend it for the moment. @@ -1920,7 +1917,7 @@ void CPlayBoardView::DoRotateRelative(BOOL bWheelRotation) private: CGamDoc& doc; BOOL bRecording = doc.IsRecording(); - } suspendRecording(*pDoc); + } suspendRecording(pDoc); // Show the rotation dialog nDlgResult = dlg.ShowModal(); @@ -1931,21 +1928,21 @@ void CPlayBoardView::DoRotateRelative(BOOL bWheelRotation) CDrawObj& pDObj = *m_tblCurPieces[i]; if (pDObj.GetType() == CDrawObj::drawPieceObj) { - pDoc->ChangePlayingPieceFacingOnBoard(static_cast(pDObj), + pDoc.ChangePlayingPieceFacingOnBoard(static_cast(pDObj), m_pPBoard.get(), m_tblCurAngles[i]); } else if (pDObj.GetType() == CDrawObj::drawMarkObj) { - pDoc->ChangeMarkerFacingOnBoard(static_cast(pDObj), m_pPBoard.get(), + pDoc.ChangeMarkerFacingOnBoard(static_cast(pDObj), m_pPBoard.get(), m_tblCurAngles[i]); } if (m_bWheelRotation && (pDObj.GetType() == CDrawObj::drawPieceObj || pDObj.GetType() == CDrawObj::drawMarkObj)) { // Restore original position - CSize sizeDelta = CPoint(m_tblXMidPnt[value_preserving_cast(i)], m_tblYMidPnt[value_preserving_cast(i)]) - + CSize sizeDelta = m_tblMidPnt[i] - GetMidRect(pDObj.GetEnclosingRect()); - pDoc->PlaceObjectOnBoard(m_pPBoard.get(), &pDObj, sizeDelta); + pDoc.PlaceObjectOnBoard(m_pPBoard.get(), &pDObj, sizeDelta); } } // Restore recording mode if it was active. @@ -1953,7 +1950,7 @@ void CPlayBoardView::DoRotateRelative(BOOL bWheelRotation) if (nDlgResult == wxID_OK) { // Rotation was accepted. Make the final changes. - pDoc->AssignNewMoveGroup(); + pDoc.AssignNewMoveGroup(); for (size_t i = size_t(0) ; i < m_tblCurPieces.size() ; ++i) { int nAngle = m_tblCurAngles[i] + dlg.m_nRelativeRotation; @@ -1964,20 +1961,20 @@ void CPlayBoardView::DoRotateRelative(BOOL bWheelRotation) if (pDObj.GetType() == CDrawObj::drawPieceObj) { - pDoc->ChangePlayingPieceFacingOnBoard(static_cast(pDObj), m_pPBoard.get(), value_preserving_cast(nAngle)); + pDoc.ChangePlayingPieceFacingOnBoard(static_cast(pDObj), m_pPBoard.get(), value_preserving_cast(nAngle)); } else if (pDObj.GetType() == CDrawObj::drawMarkObj) { - pDoc->ChangeMarkerFacingOnBoard(static_cast(pDObj), m_pPBoard.get(), value_preserving_cast(nAngle)); + pDoc.ChangeMarkerFacingOnBoard(static_cast(pDObj), m_pPBoard.get(), value_preserving_cast(nAngle)); } if (m_bWheelRotation && (pDObj.GetType() == CDrawObj::drawPieceObj || pDObj.GetType() == CDrawObj::drawMarkObj)) { // Calculate new rotated mid-point for object. CPoint pntRotate = RotatePointAroundPoint(m_pntWheelMid, - CPoint(m_tblXMidPnt[value_preserving_cast(i)], m_tblYMidPnt[value_preserving_cast(i)]), dlg.m_nRelativeRotation); + m_tblMidPnt[i], dlg.m_nRelativeRotation); CSize sizeDelta = pntRotate - GetMidRect(pDObj.GetEnclosingRect()); - pDoc->PlaceObjectOnBoard(m_pPBoard.get(), &pDObj, sizeDelta); + pDoc.PlaceObjectOnBoard(m_pPBoard.get(), &pDObj, sizeDelta); } } m_selList.UpdateObjects(TRUE, FALSE); @@ -1987,15 +1984,14 @@ void CPlayBoardView::DoRotateRelative(BOOL bWheelRotation) } m_tblCurAngles.clear(); m_tblCurPieces.clear(); - m_tblXMidPnt.RemoveAll(); - m_tblYMidPnt.RemoveAll(); + m_tblMidPnt.clear(); } void CPlayBoardView::OnUpdateActRotateRelative(CCmdUI* pCmdUI) { - CGamDoc* pDoc = GetDocument(); - if (pDoc->IsPlaying() || !pDoc->IsScenario() && - m_selList.HasOwnedPiecesNotMatching(pDoc->GetCurrentPlayerMask())) + CGamDoc& pDoc = GetDocument(); + if (pDoc.IsPlaying() || !pDoc.IsScenario() && + m_selList.HasOwnedPiecesNotMatching(pDoc.GetCurrentPlayerMask())) pCmdUI->Enable(FALSE); else pCmdUI->Enable(m_selList.HasPieces() || m_selList.HasMarkers()); @@ -2003,9 +1999,9 @@ void CPlayBoardView::OnUpdateActRotateRelative(CCmdUI* pCmdUI) void CPlayBoardView::OnUpdateActRotateGroupRelative(CCmdUI *pCmdUI) { - CGamDoc* pDoc = GetDocument(); - if (pDoc->IsPlaying() || !pDoc->IsScenario() && - m_selList.HasOwnedPiecesNotMatching(pDoc->GetCurrentPlayerMask())) + CGamDoc& pDoc = GetDocument(); + if (pDoc.IsPlaying() || !pDoc.IsScenario() && + m_selList.HasOwnedPiecesNotMatching(pDoc.GetCurrentPlayerMask())) pCmdUI->Enable(FALSE); else { @@ -2018,15 +2014,15 @@ void CPlayBoardView::OnUpdateActRotateGroupRelative(CCmdUI *pCmdUI) void CPlayBoardView::OnViewPieces() { - GetPlayBoard()->SetPiecesVisible(!GetPlayBoard()->GetPiecesVisible()); + GetPlayBoard().SetPiecesVisible(!GetPlayBoard().GetPiecesVisible()); CGamDocHint hint; hint.GetArgs().m_pPBoard = m_pPBoard.get(); - GetDocument()->UpdateAllViews(NULL, HINT_UPDATEBOARD, &hint); + GetDocument().UpdateAllViews(NULL, HINT_UPDATEBOARD, &hint); } void CPlayBoardView::OnUpdateViewPieces(CCmdUI* pCmdUI) { - pCmdUI->SetCheck(!GetPlayBoard()->GetPiecesVisible()); + pCmdUI->SetCheck(!GetPlayBoard().GetPiecesVisible()); } /////////////////////////////////////////////////////////////////////// @@ -2128,7 +2124,7 @@ void CPlayBoardView::OnEditBoardToFile() void CPlayBoardView::OnEditBoardProperties() { - GetDocument()->DoBoardProperties(CheckedDeref(GetPlayBoard())); + GetDocument().DoBoardProperties(GetPlayBoard()); } void CPlayBoardView::OnSelectGroupMarkers(UINT nID) @@ -2140,7 +2136,7 @@ void CPlayBoardView::OnUpdateSelectGroupMarkers(CCmdUI* pCmdUI, UINT nID) { if (pCmdUI->m_pSubMenu != NULL) { - CMarkManager& pMgr = GetDocument()->GetMarkManager(); + CMarkManager& pMgr = GetDocument().GetMarkManager(); if (pMgr.IsEmpty()) return; std::vector tbl; @@ -2166,15 +2162,15 @@ void CPlayBoardView::OnUpdateSelectGroupMarkers(CCmdUI* pCmdUI, UINT nID) void CPlayBoardView::OnViewDrawIndOnTop() { - GetPlayBoard()->SetIndicatorsOnTop(!GetPlayBoard()->GetIndicatorsOnTop()); + GetPlayBoard().SetIndicatorsOnTop(!GetPlayBoard().GetIndicatorsOnTop()); CGamDocHint hint; hint.GetArgs().m_pPBoard = m_pPBoard.get(); - GetDocument()->UpdateAllViews(NULL, HINT_UPDATEBOARD, &hint); + GetDocument().UpdateAllViews(NULL, HINT_UPDATEBOARD, &hint); } void CPlayBoardView::OnUpdateViewDrawIndOnTop(CCmdUI* pCmdUI) { - pCmdUI->SetCheck(GetPlayBoard()->GetIndicatorsOnTop()); + pCmdUI->SetCheck(GetPlayBoard().GetIndicatorsOnTop()); } void CPlayBoardView::OnEditElementText() @@ -2182,15 +2178,15 @@ void CPlayBoardView::OnEditElementText() ASSERT(m_selList.IsSingleSelect() && (m_selList.HasMarkers() || m_selList.HasPieces())); CDrawObj& pDObj = *m_selList.front()->m_pObj; - GetDocument()->DoEditObjectText(pDObj); + GetDocument().DoEditObjectText(pDObj); NotifySelectListChange(); // Make sure indicators are updated } void CPlayBoardView::OnUpdateEditElementText(CCmdUI* pCmdUI) { - CGamDoc* pDoc = GetDocument(); - if (pDoc->IsPlaying() || !pDoc->IsScenario() && - m_selList.HasOwnedPiecesNotMatching(pDoc->GetCurrentPlayerMask())) + CGamDoc& pDoc = GetDocument(); + if (pDoc.IsPlaying() || !pDoc.IsScenario() && + m_selList.HasOwnedPiecesNotMatching(pDoc.GetCurrentPlayerMask())) pCmdUI->Enable(FALSE); else { @@ -2212,8 +2208,8 @@ void CPlayBoardView::OnActLockObject() std::vector> listObjs; m_selList.LoadTableWithObjectPtrs(listObjs, CSelList::otAll, FALSE); - GetDocument()->AssignNewMoveGroup(); - GetDocument()->SetObjectLockdownTable(listObjs, bLockState); + GetDocument().AssignNewMoveGroup(); + GetDocument().SetObjectLockdownTable(listObjs, bLockState); if (m_pPBoard->GetLocksEnforced() && bLockState) m_selList.PurgeList(TRUE); // Purge former selections @@ -2221,7 +2217,7 @@ void CPlayBoardView::OnActLockObject() void CPlayBoardView::OnUpdateActLockObject(CCmdUI* pCmdUI) { - if (GetDocument()->IsPlaying()) + if (GetDocument().IsPlaying()) { pCmdUI->Enable(FALSE); return; @@ -2251,7 +2247,7 @@ void CPlayBoardView::OnActLockSuspend() void CPlayBoardView::OnUpdateActLockSuspend(CCmdUI* pCmdUI) { - if (GetDocument()->IsPlaying()) + if (GetDocument().IsPlaying()) pCmdUI->Enable(FALSE); else { @@ -2269,44 +2265,44 @@ void CPlayBoardView::OnActTakeOwnership() CPoint pntCenter(MidPnt(rct.left, rct.right), MidPnt(rct.top, rct.bottom)); - CGamDoc* pDoc = GetDocument(); + CGamDoc& pDoc = GetDocument(); std::vector tblPieces; m_selList.LoadTableWithOwnerStatePieceIDs(tblPieces, m_selList.LF_NOTOWNED); - pDoc->AssignNewMoveGroup(); + pDoc.AssignNewMoveGroup(); - if (pDoc->IsRecording()) + if (pDoc.IsRecording()) { // Insert a notification tip so there is some information // feedback during playback. CB::string strMsg = CB::string::LoadString(IDS_TIP_OWNER_ACQUIRED); - pDoc->RecordEventMessage(strMsg, m_pPBoard->GetSerialNumber(), + pDoc.RecordEventMessage(strMsg, m_pPBoard->GetSerialNumber(), value_preserving_cast(pntCenter.x), value_preserving_cast(pntCenter.y)); } - pDoc->SetPieceOwnershipTable(tblPieces, pDoc->GetCurrentPlayerMask()); + pDoc.SetPieceOwnershipTable(tblPieces, pDoc.GetCurrentPlayerMask()); CGamDocHint hint; hint.GetArgs().m_pPBoard = m_pPBoard.get(); - pDoc->UpdateAllViews(NULL, HINT_UPDATEBOARD, &hint); + pDoc.UpdateAllViews(NULL, HINT_UPDATEBOARD, &hint); NotifySelectListChange(); } void CPlayBoardView::OnUpdateActTakeOwnership(CCmdUI* pCmdUI) { - CGamDoc* pDoc = GetDocument(); + CGamDoc& pDoc = GetDocument(); // Can't take ownership while residing on an owned board. - if (pDoc->IsPlaying() || m_pPBoard->IsOwned()) + if (pDoc.IsPlaying() || m_pPBoard->IsOwned()) pCmdUI->Enable(FALSE); - else if (pDoc->IsCurrentPlayerReferee()) + else if (pDoc.IsCurrentPlayerReferee()) pCmdUI->Enable(FALSE); // No owner to acquire. He's the Referee! else { - pCmdUI->Enable(pDoc->HasPlayers() && m_selList.HasNonOwnedPieces() && - pDoc->GetCurrentPlayerMask() != OWNER_MASK_SPECTATOR); + pCmdUI->Enable(pDoc.HasPlayers() && m_selList.HasNonOwnedPieces() && + pDoc.GetCurrentPlayerMask() != OWNER_MASK_SPECTATOR); } } @@ -2318,57 +2314,57 @@ void CPlayBoardView::OnActReleaseOwnership() CPoint pntCenter(MidPnt(rct.left, rct.right), MidPnt(rct.top, rct.bottom)); - CGamDoc* pDoc = GetDocument(); + CGamDoc& pDoc = GetDocument(); std::vector tblPieces; m_selList.LoadTableWithOwnerStatePieceIDs(tblPieces, m_selList.LF_OWNED); - pDoc->AssignNewMoveGroup(); + pDoc.AssignNewMoveGroup(); - if (pDoc->IsRecording()) + if (pDoc.IsRecording()) { // Insert a notification tip so there is some information // feedback during playback. CB::string strMsg = CB::string::LoadString(IDS_TIP_OWNER_RELEASED); - pDoc->RecordEventMessage(strMsg, m_pPBoard->GetSerialNumber(), + pDoc.RecordEventMessage(strMsg, m_pPBoard->GetSerialNumber(), value_preserving_cast(pntCenter.x), value_preserving_cast(pntCenter.y)); } - pDoc->SetPieceOwnershipTable(tblPieces, OWNER_MASK_SPECTATOR); + pDoc.SetPieceOwnershipTable(tblPieces, OWNER_MASK_SPECTATOR); CGamDocHint hint; hint.GetArgs().m_pPBoard = m_pPBoard.get(); - pDoc->UpdateAllViews(NULL, HINT_UPDATEBOARD, &hint); + pDoc.UpdateAllViews(NULL, HINT_UPDATEBOARD, &hint); NotifySelectListChange(); } void CPlayBoardView::OnUpdateActReleaseOwnership(CCmdUI* pCmdUI) { - CGamDoc* pDoc = GetDocument(); + CGamDoc& pDoc = GetDocument(); // Can't release ownership while residing on an owned board. - if (pDoc->IsPlaying() || m_pPBoard->IsOwned()) + if (pDoc.IsPlaying() || m_pPBoard->IsOwned()) pCmdUI->Enable(FALSE); - else if (pDoc->IsCurrentPlayerReferee() && m_selList.HasPieces()) + else if (pDoc.IsCurrentPlayerReferee() && m_selList.HasPieces()) pCmdUI->Enable(TRUE); else { - pCmdUI->Enable(pDoc->HasPlayers() && m_selList.HasOwnedPieces() && - pDoc->GetCurrentPlayerMask() != OWNER_MASK_SPECTATOR); + pCmdUI->Enable(pDoc.HasPlayers() && m_selList.HasOwnedPieces() && + pDoc.GetCurrentPlayerMask() != OWNER_MASK_SPECTATOR); } } void CPlayBoardView::OnActSetOwner() { - CGamDoc* pDoc = GetDocument(); + CGamDoc& pDoc = GetDocument(); CRect rct = m_selList.GetPiecesEnclosingRect(FALSE); if (rct.IsRectEmpty()) return; - CSelectNewOwnerDialog dlg(CheckedDeref(pDoc->GetPlayerManager())); - if (!pDoc->IsCurrentPlayerReferee()) - dlg.m_nPlayer = CPlayerManager::GetPlayerNumFromMask(pDoc->GetCurrentPlayerMask()); + CSelectNewOwnerDialog dlg(CheckedDeref(pDoc.GetPlayerManager())); + if (!pDoc.IsCurrentPlayerReferee()) + dlg.m_nPlayer = CPlayerManager::GetPlayerNumFromMask(pDoc.GetCurrentPlayerMask()); if (dlg.ShowModal() != wxID_OK) return; @@ -2380,38 +2376,38 @@ void CPlayBoardView::OnActSetOwner() std::vector tblPieces; m_selList.LoadTableWithOwnerStatePieceIDs(tblPieces, m_selList.LF_BOTH); - pDoc->AssignNewMoveGroup(); + pDoc.AssignNewMoveGroup(); - if (pDoc->IsRecording()) + if (pDoc.IsRecording()) { // Insert a notification tip so there is some information // feedback during playback. CB::string strMsg = CB::string::LoadString(IDS_TIP_OWNER_ACQUIRED); - pDoc->RecordEventMessage(strMsg, m_pPBoard->GetSerialNumber(), + pDoc.RecordEventMessage(strMsg, m_pPBoard->GetSerialNumber(), value_preserving_cast(pntCenter.x), value_preserving_cast(pntCenter.y)); } - pDoc->SetPieceOwnershipTable(tblPieces, dwNewOwnerMask); + pDoc.SetPieceOwnershipTable(tblPieces, dwNewOwnerMask); CGamDocHint hint; hint.GetArgs().m_pPBoard = m_pPBoard.get(); - pDoc->UpdateAllViews(NULL, HINT_UPDATEBOARD, &hint); + pDoc.UpdateAllViews(NULL, HINT_UPDATEBOARD, &hint); NotifySelectListChange(); } void CPlayBoardView::OnUpdateActSetOwner(CCmdUI* pCmdUI) { - CGamDoc* pDoc = GetDocument(); + CGamDoc& pDoc = GetDocument(); // Can't take ownership while residing on an owned board. - if (pDoc->IsPlaying() || m_pPBoard->IsOwned()) + if (pDoc.IsPlaying() || m_pPBoard->IsOwned()) pCmdUI->Enable(FALSE); - else if (pDoc->IsCurrentPlayerReferee() && m_selList.HasPieces()) + else if (pDoc.IsCurrentPlayerReferee() && m_selList.HasPieces()) pCmdUI->Enable(TRUE); else { - pCmdUI->Enable(pDoc->HasPlayers() && - (m_selList.HasPieces() && pDoc->GetCurrentPlayerMask() != OWNER_MASK_SPECTATOR)); + pCmdUI->Enable(pDoc.HasPlayers() && + (m_selList.HasPieces() && pDoc.GetCurrentPlayerMask() != OWNER_MASK_SPECTATOR)); } } diff --git a/GP/VwPbrd.h b/GP/VwPbrd.h index cac70a60..7f5718b3 100644 --- a/GP/VwPbrd.h +++ b/GP/VwPbrd.h @@ -1,6 +1,6 @@ // VwPbrd.h : interface of the CPlayBoardView class // -// Copyright (c) 1994-2020 By Dale L. Larson, All Rights Reserved. +// Copyright (c) 1994-2025 By Dale L. Larson & William Su, All Rights Reserved. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the @@ -51,26 +51,26 @@ class CPlayBoardView : public CScrollView // Attributes public: - const CGamDoc* GetDocument() const; - CGamDoc* GetDocument() { return const_cast(std::as_const(*this).GetDocument()); } - const CPlayBoard* GetPlayBoard() const { return m_pPBoard.get(); } - CPlayBoard* GetPlayBoard() { return const_cast(std::as_const(*this).GetPlayBoard()); } + const CGamDoc& GetDocument() const; + CGamDoc& GetDocument() { return const_cast(std::as_const(*this).GetDocument()); } + const CPlayBoard& GetPlayBoard() const { return CheckedDeref(m_pPBoard); } + CPlayBoard& GetPlayBoard() { return const_cast(std::as_const(*this).GetPlayBoard()); } // Operations public: // Implementation public: - virtual ~CPlayBoardView(); - virtual void OnDraw(CDC* pDC) override; // Overridden to draw this view + ~CPlayBoardView() override; + void OnDraw(CDC* pDC) override; // Overridden to draw this view // Tools and selection support public: CSelList m_selList; // List of selected objects. void NotifySelectListChange(); - const CSelList* GetSelectList() const { return &m_selList; } - CSelList* GetSelectList() { return const_cast(std::as_const(*this).GetSelectList()); } + const CSelList& GetSelectList() const { return m_selList; } + CSelList& GetSelectList() { return const_cast(std::as_const(*this).GetSelectList()); } CPoint GetWorkspaceDim() const; void AddDrawObject(CDrawObj::OwnerPtr pObj); @@ -79,8 +79,8 @@ class CPlayBoardView : public CScrollView void PrepareScaledDC(CDC& pDC, CRect* pRct = NULL, BOOL bHonor180Flip = FALSE) const; void OnPrepareScaledDC(CDC& pDC, BOOL bHonor180Flip = FALSE); - void AdjustPoint(CPoint& pnt) const; // Limit and grid processing - void AdjustRect(CRect& rct) const; + [[nodiscard]] CPoint AdjustPoint(CPoint pnt) const; // Limit and grid processing + [[nodiscard]] CRect AdjustRect(CRect rct) const; void SelectWithinRect(CRect rctNet, BOOL bInclIntersects = FALSE); void SelectAllUnderPoint(CPoint point); @@ -97,10 +97,10 @@ class CPlayBoardView : public CScrollView // Coordinate scaling... public: - void WorkspaceToClient(CPoint& point) const; - void WorkspaceToClient(CRect& rect) const; - void ClientToWorkspace(CPoint& point) const; - void ClientToWorkspace(CRect& rect) const; + [[nodiscard]] CPoint WorkspaceToClient(CPoint point) const; + [[nodiscard]] CRect WorkspaceToClient(CRect rect) const; + [[nodiscard]] CPoint ClientToWorkspace(CPoint point) const; + [[nodiscard]] CRect ClientToWorkspace(CRect rect) const; void InvalidateWorkspaceRect(const CRect& pRect, BOOL bErase = FALSE); // View support @@ -126,14 +126,14 @@ class CPlayBoardView : public CScrollView protected: BOOL IsGridizeActive() const; #ifdef WIN32 - void GridizeX(long& xPos) const; - void GridizeY(long& yPos) const; + [[nodiscard]] long GridizeX(long xPos) const; + [[nodiscard]] long GridizeY(long yPos) const; #else void GridizeX(int& xPos) const; void GridizeY(int& yPos) const; #endif - void LimitPoint(POINT& pPnt) const; - void LimitRect(RECT& pRct) const; + [[nodiscard]] POINT LimitPoint(POINT pPnt) const; + [[nodiscard]] RECT LimitRect(RECT pRct) const; BOOL IsRectFullyOnBoard(const RECT& pRct, BOOL* pbXOK = NULL, BOOL* pbYOK = NULL) const; // Implementation @@ -156,8 +156,7 @@ class CPlayBoardView : public CScrollView CPoint m_pntWheelMid; // The wheel rotation point std::vector m_tblCurAngles; // Original angles of pieces std::vector> m_tblCurPieces; // Pieces being rotated - CUIntArray m_tblXMidPnt; // X coord of piece midpoint - CUIntArray m_tblYMidPnt; // Y coord of piece midpoint + std::vector m_tblMidPnt; // X coord of piece midpoint // Implementation protected: @@ -170,10 +169,10 @@ class CPlayBoardView : public CScrollView void SetupDrawListDC(CDC& pDC, CRect& pRct) const; void RestoreDrawListDC(CDC& pDC) const; - LRESULT DoDragPiece(DragInfo& pdi); - LRESULT DoDragMarker(DragInfo& pdi); - LRESULT DoDragPieceList(DragInfo& pdi); - LRESULT DoDragSelectList(DragInfo& pdi); + LRESULT DoDragPiece(const DragInfo& pdi); + LRESULT DoDragMarker(const DragInfo& pdi); + LRESULT DoDragPieceList(const DragInfo& pdi); + LRESULT DoDragSelectList(const DragInfo& pdi); void DragDoAutoScroll(); void DragCheckAutoScroll(); @@ -185,12 +184,12 @@ class CPlayBoardView : public CScrollView BOOL DoMouseWheelFix(UINT fFlags, short zDelta, CPoint point); protected: - virtual void OnInitialUpdate(); - virtual void OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint); - virtual BOOL PreCreateWindow(CREATESTRUCT& cs); - virtual BOOL PreTranslateMessage(MSG* pMsg); - virtual void OnActivateView(BOOL bActivate, CView* pActivateView, - CView* pDeactiveView); + void OnInitialUpdate() override; + void OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint) override; + BOOL PreCreateWindow(CREATESTRUCT& cs) override; + BOOL PreTranslateMessage(MSG* pMsg) override; + void OnActivateView(BOOL bActivate, CView* pActivateView, + CView* pDeactiveView) override; // Generated message map functions protected: @@ -282,8 +281,8 @@ class CPlayBoardView : public CScrollView }; #ifndef _DEBUG // debug version in vwmbrd.cpp -inline const CGamDoc* CPlayBoardView::GetDocument() const - { return CB::ToCGamDoc(m_pDocument); } +inline const CGamDoc& CPlayBoardView::GetDocument() const + { return *CB::ToCGamDoc(m_pDocument); } #endif ///////////////////////////////////////////////////////////////////////////// diff --git a/GP/VwPbrd1.cpp b/GP/VwPbrd1.cpp index a76fc701..fb7169f3 100644 --- a/GP/VwPbrd1.cpp +++ b/GP/VwPbrd1.cpp @@ -1,6 +1,6 @@ // VwPbrd1.cpp : implementation of the CPlayBoardView class // -// Copyright (c) 1994-2023 By Dale L. Larson & William Su, All Rights Reserved. +// Copyright (c) 1994-2025 By Dale L. Larson & William Su, All Rights Reserved. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the @@ -52,8 +52,8 @@ const int scrollZone = 16; void CPlayBoardView::DoToolTipHitProcessing(CPoint pointClient) { - CGamDoc* pDoc = GetDocument(); - if (!pDoc->IsShowingObjectTips() && pDoc->IsOwnerTipsDisabled()) + CGamDoc& pDoc = GetDocument(); + if (!pDoc.IsShowingObjectTips() && pDoc.IsOwnerTipsDisabled()) { // Delete previous tool definition m_toolHitTip.DelTool(this, ID_TIP_PLAYBOARD_HIT); @@ -62,18 +62,18 @@ void CPlayBoardView::DoToolTipHitProcessing(CPoint pointClient) } CPoint pnt(pointClient); - ClientToWorkspace(pnt); + pnt = ClientToWorkspace(pnt); CDrawObj* pDObj = ObjectHitTest(pnt); - if (pDoc->IsOwnerTipsDisabled() && pDoc->HasPlayers()) + if (pDoc.IsOwnerTipsDisabled() && pDoc.HasPlayers()) { if (pDObj != NULL && pDObj->GetType() == CDrawObj::drawPieceObj) { CPieceObj* pPObj = (CPieceObj*)pDObj; if (pPObj->IsOwned() && - !pDoc->GetPieceTable().IsPieceInvisible(pPObj->m_pid)) + !pDoc.GetPieceTable().IsPieceInvisible(pPObj->m_pid)) { - CB::string strOwner = pDoc->GetPieceOwnerName(pPObj->m_pid); + CB::string strOwner = pDoc.GetPieceOwnerName(pPObj->m_pid); CB::string strOwnedBy = CB::string::Format(IDS_TIP_OWNED_BY_UC, strOwner); GetMainFrame()->GetStatusBar()->SetWindowText(strOwnedBy); } @@ -93,33 +93,33 @@ void CPlayBoardView::DoToolTipHitProcessing(CPoint pointClient) { // New object found so create a new tip CRect rct = pDObj->GetRect(); - WorkspaceToClient(rct); + rct = WorkspaceToClient(rct); CB::string strTip; CB::string strTitle; - if (pDoc->IsShowingObjectTips()) - pDoc->GetTipTextForObject(*pDObj, strTip, &strTitle); + if (pDoc.IsShowingObjectTips()) + pDoc.GetTipTextForObject(*pDObj, strTip, &strTitle); // All this stuff is used to annotate tips with owner names // when player accounts are active. - if (pDoc->HasPlayers() && pDObj->GetType() == CDrawObj::drawPieceObj) + if (pDoc.HasPlayers() && pDObj->GetType() == CDrawObj::drawPieceObj) { CPieceObj* pPObj = (CPieceObj*)pDObj; if (pPObj->IsOwned() && - !pDoc->GetPieceTable().IsPieceInvisible(pPObj->m_pid)) + !pDoc.GetPieceTable().IsPieceInvisible(pPObj->m_pid)) { - CB::string strOwner = pDoc->GetPieceOwnerName(pPObj->m_pid); + CB::string strOwner = pDoc.GetPieceOwnerName(pPObj->m_pid); CB::string strOwnedBy = CB::string::Format(IDS_TIP_OWNED_BY_UC, strOwner); - if (!pDoc->IsScenario() && !pPObj->IsOwnedBy(pDoc->GetCurrentPlayerMask())) + if (!pDoc.IsScenario() && !pPObj->IsOwnedBy(pDoc.GetCurrentPlayerMask())) { strTip.clear(); // Current player isn't allowed to see text. - if (!pDoc->IsOwnerTipsDisabled() && !strOwner.empty())// Replace tip with special "Owned by" tip + if (!pDoc.IsOwnerTipsDisabled() && !strOwner.empty())// Replace tip with special "Owned by" tip strTip = strOwnedBy; } else { - if (!pDoc->IsOwnerTipsDisabled()) + if (!pDoc.IsOwnerTipsDisabled()) { // Append actual tip to owner string. if (strTip.empty()) @@ -224,7 +224,7 @@ CDrawObj* CPlayBoardView::ObjectHitTest(CPoint point) void CPlayBoardView::SelectWithinRect(CRect rctNet, BOOL bInclIntersects) { - CGamDoc* pDoc = GetDocument(); + CGamDoc& pDoc = GetDocument(); CDrawList& pDwg = CheckedDeref(m_pPBoard->GetPieceList()); BOOL bPieceSelected = FALSE; @@ -242,7 +242,7 @@ void CPlayBoardView::SelectWithinRect(CRect rctNet, BOOL bInclIntersects) if (pObj.GetType() == CDrawObj::drawPieceObj) { CPieceObj& pPObj = static_cast(pObj); - PlayerMask dwCurrentPlayer = pDoc->GetCurrentPlayerMask(); + PlayerMask dwCurrentPlayer = pDoc.GetCurrentPlayerMask(); bOwnedByCurrentPlayer = !pPObj.IsOwned() || pPObj.IsOwnedBy(dwCurrentPlayer) || m_pPBoard->IsNonOwnerAccessAllowed(); @@ -261,7 +261,7 @@ void CPlayBoardView::SelectWithinRect(CRect rctNet, BOOL bInclIntersects) // - Owned by the current player OR // - Owned but non-owner access is allowed. // (the last three conditions were checked above.) - if (pDoc->IsScenario() || bOwnedByCurrentPlayer) + if (pDoc.IsScenario() || bOwnedByCurrentPlayer) { m_selList.AddObject(pObj, TRUE); bPieceSelected |= pObj.GetType() == CDrawObj::drawPieceObj || @@ -293,7 +293,7 @@ void CPlayBoardView::SelectAllUnderPoint(CPoint point) if (pObj.GetType() == CDrawObj::drawPieceObj) { CPieceObj& pPObj = static_cast(pObj); - PlayerMask dwCurrentPlayer = GetDocument()->GetCurrentPlayerMask(); + PlayerMask dwCurrentPlayer = GetDocument().GetCurrentPlayerMask(); bOwnedByCurrentPlayer = !pPObj.IsOwned() || pPObj.IsOwnedBy(dwCurrentPlayer); } @@ -377,7 +377,7 @@ void CPlayBoardView::SelectAllMarkers() void CPlayBoardView::SelectMarkersInGroup(size_t nGroup) { CDrawList& pDwg = CheckedDeref(m_pPBoard->GetPieceList()); - CMarkManager& pMgr = GetDocument()->GetMarkManager(); + CMarkManager& pMgr = GetDocument().GetMarkManager(); m_selList.PurgeList(); @@ -408,7 +408,7 @@ void CPlayBoardView::AddDrawObject(CDrawObj::OwnerPtr pObj) if (pDwg != NULL) { pDwg->AddToFront(std::move(pObj)); - GetDocument()->SetModifiedFlag(); + GetDocument().SetModifiedFlag(); } } @@ -445,7 +445,7 @@ void CPlayBoardView::MoveObjsInSelectList(BOOL bToFront, BOOL bInvalidate) } if (bInvalidate) m_selList.InvalidateList(); - GetDocument()->SetModifiedFlag(); + GetDocument().SetModifiedFlag(); } ///////////////////////////////////////////////////////////////////////////// @@ -457,13 +457,13 @@ CPoint CPlayBoardView::GetWorkspaceDim() const // Translate to current scaling mode. pnt -= (CSize)GetDeviceScrollPosition(); - ClientToWorkspace(pnt); + pnt = ClientToWorkspace(pnt); return pnt; } ///////////////////////////////////////////////////////////////////////////// -void CPlayBoardView::WorkspaceToClient(CPoint& point) const +CPoint CPlayBoardView::WorkspaceToClient(CPoint point) const { CPoint dpnt = GetDeviceScrollPosition(); CSize wsize, vsize; @@ -473,9 +473,10 @@ void CPlayBoardView::WorkspaceToClient(CPoint& point) const point = CPoint(wsize.cx - point.x, wsize.cy - point.y); ScalePoint(point, vsize, wsize); point -= (CSize)dpnt; + return point; } -void CPlayBoardView::WorkspaceToClient(CRect& rect) const +CRect CPlayBoardView::WorkspaceToClient(CRect rect) const { CPoint dpnt = GetDeviceScrollPosition(); CSize wsize, vsize; @@ -489,17 +490,18 @@ void CPlayBoardView::WorkspaceToClient(CRect& rect) const } ScaleRect(rect, vsize, wsize); rect -= dpnt; + return rect; } void CPlayBoardView::InvalidateWorkspaceRect(const CRect& pRect, BOOL bErase) { CRect rct(pRect); - WorkspaceToClient(rct); + rct = WorkspaceToClient(rct); rct.InflateRect(1, 1); InvalidateRect(&rct, bErase); } -void CPlayBoardView::ClientToWorkspace(CPoint& point) const +CPoint CPlayBoardView::ClientToWorkspace(CPoint point) const { CPoint dpnt = GetDeviceScrollPosition(); point += (CSize)dpnt; @@ -509,9 +511,10 @@ void CPlayBoardView::ClientToWorkspace(CPoint& point) const ScalePoint(point, wsize, vsize); if (m_pPBoard->IsBoardRotated180()) point = CPoint(wsize.cx - point.x, wsize.cy - point.y); + return point; } -void CPlayBoardView::ClientToWorkspace(CRect& rect) const +CRect CPlayBoardView::ClientToWorkspace(CRect rect) const { CPoint dpnt = GetDeviceScrollPosition(); rect += dpnt; @@ -525,6 +528,7 @@ void CPlayBoardView::ClientToWorkspace(CRect& rect) const wsize.cx - rect.right, wsize.cy - rect.bottom); rect.NormalizeRect(); } + return rect; } ////////////////////////////////////////////////////////////////////// @@ -536,25 +540,27 @@ BOOL CPlayBoardView::IsGridizeActive() const return !(bControl && bGridSnap || !bControl && !bGridSnap); } -void CPlayBoardView::GridizeX(long& xPos) const +long CPlayBoardView::GridizeX(long xPos) const { if (IsGridizeActive()) { xPos = GridizeClosest1000(value_preserving_cast(xPos), value_preserving_cast(m_pPBoard->m_xGridSnap), value_preserving_cast(m_pPBoard->m_xGridSnapOff)); } + return xPos; } -void CPlayBoardView::GridizeY(long& yPos) const +long CPlayBoardView::GridizeY(long yPos) const { if (IsGridizeActive()) { yPos = GridizeClosest1000(value_preserving_cast(yPos), value_preserving_cast(m_pPBoard->m_yGridSnap), value_preserving_cast(m_pPBoard->m_yGridSnapOff)); } + return yPos; } -void CPlayBoardView::LimitPoint(POINT& pPnt) const +POINT CPlayBoardView::LimitPoint(POINT pPnt) const { const CBoard* pBoard = m_pPBoard->GetBoard(); if (pPnt.x < 0) pPnt.x = 0; @@ -563,9 +569,10 @@ void CPlayBoardView::LimitPoint(POINT& pPnt) const if (pPnt.y < 0) pPnt.y = 0; if (pPnt.y > pBoard->GetHeight(fullScale)) pPnt.y = pBoard->GetHeight(fullScale); + return pPnt; } -void CPlayBoardView::LimitRect(RECT& pRct) const +RECT CPlayBoardView::LimitRect(RECT pRct) const { CRect rct(pRct); const CBoard* pBoard = m_pPBoard->GetBoard(); @@ -579,6 +586,7 @@ void CPlayBoardView::LimitRect(RECT& pRct) const if (rct.bottom > pBoard->GetHeight(fullScale)) rct.OffsetRect(0, pBoard->GetHeight(fullScale) - rct.bottom); pRct = rct; + return pRct; } BOOL CPlayBoardView::IsRectFullyOnBoard(const RECT& pRct, BOOL* pbXOK, BOOL* pbYOK) const @@ -604,14 +612,15 @@ BOOL CPlayBoardView::IsRectFullyOnBoard(const RECT& pRct, BOOL* pbXOK, BOOL* pbY return bOK; } -void CPlayBoardView::AdjustPoint(CPoint& pnt) const +CPoint CPlayBoardView::AdjustPoint(CPoint pnt) const { - GridizeX(pnt.x); - GridizeY(pnt.y); - LimitPoint(pnt); + pnt.x = GridizeX(pnt.x); + pnt.y = GridizeY(pnt.y); + pnt = LimitPoint(pnt); + return pnt; } -void CPlayBoardView::AdjustRect(CRect& rct) const +CRect CPlayBoardView::AdjustRect(CRect rct) const { CPoint pnt; if (m_pPBoard->m_bGridRectCenters) @@ -619,9 +628,9 @@ void CPlayBoardView::AdjustRect(CRect& rct) const else pnt = rct.TopLeft(); - GridizeX(pnt.x); - GridizeY(pnt.y); - LimitPoint(pnt); + pnt.x = GridizeX(pnt.x); + pnt.y = GridizeY(pnt.y); + pnt = LimitPoint(pnt); if (m_pPBoard->m_bGridRectCenters) { @@ -633,7 +642,8 @@ void CPlayBoardView::AdjustRect(CRect& rct) const if (pnt != rct.TopLeft()) rct.OffsetRect(pnt - rct.TopLeft()); } - LimitRect(rct); + rct = LimitRect(rct); + return rct; } ////////////////////////////////////////////////////////////////////// @@ -649,7 +659,7 @@ void CPlayBoardView::ScrollWorkspacePointIntoView(CPoint point) return; } rct.InflateRect(-viewZone, -viewZone); - ClientToWorkspace(rct); + rct = ClientToWorkspace(rct); if (rct.PtInRect(point)) return; // Everthing is ok CenterViewOnWorkspacePoint(point); @@ -657,7 +667,7 @@ void CPlayBoardView::ScrollWorkspacePointIntoView(CPoint point) void CPlayBoardView::CenterViewOnWorkspacePoint(CPoint point) { - WorkspaceToClient(point); + point = WorkspaceToClient(point); CRect rct; GetClientRect(&rct); CPoint pt = GetMidRect(rct); From 72551f280de041c8e1d1fc701398730803b1fd53 Mon Sep 17 00:00:00 2001 From: Bill Su Date: Wed, 24 Sep 2025 00:22:00 -0400 Subject: [PATCH 37/80] VwPbrd: create an extra window to simplify wx conversion MFC manages doc/frame/view objects, so split CPlayBoardView into a parent window that MFC can manage and a child window that has the main implementation. That way we can convert the main implementation to wx while still letting MFC's doc/frame/view code work. --- GP/FrmPbrd.cpp | 11 ++++++++++- GP/Gp.cpp | 2 +- GP/VwPbrd.cpp | 53 +++++++++++++++++++++++++++++++++++++++++++++++++- GP/VwPbrd.h | 28 ++++++++++++++++++++++++-- 4 files changed, 89 insertions(+), 5 deletions(-) diff --git a/GP/FrmPbrd.cpp b/GP/FrmPbrd.cpp index 87e284fc..5d22e464 100644 --- a/GP/FrmPbrd.cpp +++ b/GP/FrmPbrd.cpp @@ -443,7 +443,16 @@ CCbSplitterWnd& CPlayBoardFrame::GetBoardSplitter() const CPlayBoardView& CPlayBoardFrame::GetActiveBoardView() const { CCbSplitterWnd& pSplitWnd = CheckedDeref((CCbSplitterWnd*)m_wndSplitter1.GetPane(0, 0)); - return CheckedDeref((CPlayBoardView*)pSplitWnd.GetActivePane()); + const CWnd* view = GetActiveView(); + if (view && + view->IsKindOf(RUNTIME_CLASS(CPlayBoardView)) && + view->GetParent()->GetParent() == &pSplitWnd) + { + return static_cast(*view); + } + const CWnd& wnd = CheckedDeref(pSplitWnd.GetActivePane()); + const CPlayBoardViewContainer& container = dynamic_cast(wnd); + return static_cast(container); } void CPlayBoardFrame::OnViewHalfScaleBrd() diff --git a/GP/Gp.cpp b/GP/Gp.cpp index 27372ca9..b3890bb6 100644 --- a/GP/Gp.cpp +++ b/GP/Gp.cpp @@ -301,7 +301,7 @@ BOOL CGpApp::InitInstance() IDR_GP_BOARDVIEW, RUNTIME_CLASS(CGamDoc), RUNTIME_CLASS(CPlayBoardFrame), - RUNTIME_CLASS(CPlayBoardView)); + RUNTIME_CLASS(CPlayBoardViewContainer)); EnableLoadWindowPlacement(FALSE); diff --git a/GP/VwPbrd.cpp b/GP/VwPbrd.cpp index d83b5c28..58a0621d 100644 --- a/GP/VwPbrd.cpp +++ b/GP/VwPbrd.cpp @@ -49,7 +49,8 @@ static char THIS_FILE[] = __FILE__; #endif -IMPLEMENT_DYNCREATE(CPlayBoardView, CScrollView) +IMPLEMENT_DYNAMIC(CPlayBoardView, CScrollView) +IMPLEMENT_DYNCREATE(CPlayBoardViewContainer, CView) #ifdef _DEBUG #define new DEBUG_NEW @@ -151,6 +152,12 @@ BEGIN_MESSAGE_MAP(CPlayBoardView, CScrollView) ON_MESSAGE(WM_SELECT_BOARD_OBJLIST, OnMessageSelectBoardObjectList) END_MESSAGE_MAP() +BEGIN_MESSAGE_MAP(CPlayBoardViewContainer, CView) + ON_WM_CREATE() + ON_WM_SIZE() + ON_MESSAGE(WM_WINSTATE, OnMessageWindowState) +END_MESSAGE_MAP() + ///////////////////////////////////////////////////////////////////////////// // CPlayBoardView construction/destruction @@ -2560,3 +2567,47 @@ BOOL CPlayBoardView::DoMouseWheelFix(UINT fFlags, short zDelta, CPoint point) return bResult; } } + +void CPlayBoardViewContainer::OnDraw(CDC* pDC) +{ + // do nothing because child covers entire client rect +} + +CPlayBoardViewContainer::CPlayBoardViewContainer() : + child(new CPlayBoardView) +{ +} + +int CPlayBoardViewContainer::OnCreate(LPCREATESTRUCT lpCreateStruct) +{ + if (CView::OnCreate(lpCreateStruct) == -1) + { + return -1; + } + + DWORD dwStyle = AFX_WS_DEFAULT_VIEW & ~WS_BORDER; + // Create with the right size (wrong position) + CRect rect; + GetClientRect(rect); + CCreateContext context; + context.m_pCurrentDoc = GetDocument(); + if (!child->Create(NULL, NULL, dwStyle, + rect, this, 0, &context)) + { + return -1; + } + + return 0; +} + +void CPlayBoardViewContainer::OnSize(UINT nType, int cx, int cy) +{ + child->MoveWindow(0, 0, cx, cy); + return CView::OnSize(nType, cx, cy); +} + +LRESULT CPlayBoardViewContainer::OnMessageWindowState(WPARAM wParam, LPARAM lParam) +{ + child->SendMessage(WM_WINSTATE, wParam, lParam); + return (LRESULT)1; +} diff --git a/GP/VwPbrd.h b/GP/VwPbrd.h index 7f5718b3..a29c1f63 100644 --- a/GP/VwPbrd.h +++ b/GP/VwPbrd.h @@ -45,9 +45,10 @@ class CPlayBoardView : public CScrollView { friend class CPlayBoardFrame; -protected: // create from serialization only +public: CPlayBoardView(); - DECLARE_DYNCREATE(CPlayBoardView) +protected: + DECLARE_DYNAMIC(CPlayBoardView) // Attributes public: @@ -285,5 +286,28 @@ inline const CGamDoc& CPlayBoardView::GetDocument() const { return *CB::ToCGamDoc(m_pDocument); } #endif +class CPlayBoardViewContainer : public CView +{ +public: + void OnDraw(CDC* pDC) override; + operator const CPlayBoardView&() const { return *child; } + operator CPlayBoardView&() + { + return const_cast(static_cast(std::as_const(*this))); + } + +private: + CPlayBoardViewContainer(); // used by dynamic creation + DECLARE_DYNCREATE(CPlayBoardViewContainer) + + afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); + afx_msg void OnSize(UINT nType, int cx, int cy); + afx_msg LRESULT OnMessageWindowState(WPARAM wParam, LPARAM lParam); + DECLARE_MESSAGE_MAP() + + // owned by MFC + RefPtr child; +}; + ///////////////////////////////////////////////////////////////////////////// From 3e9054d528760e1d8e8e4fd50fa3cd8ebe7115b4 Mon Sep 17 00:00:00 2001 From: Bill Su Date: Thu, 2 Oct 2025 21:46:37 -0400 Subject: [PATCH 38/80] Gp: provide wx version of some WM messages WM_ROTATEPIECE_DELTA_WX, WM_CENTERBOARDONPOINT_WX, WM_SELECT_BOARD_OBJLIST_WX --- GP/Gp.cpp | 3 +++ GP/Gp.h | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 82 insertions(+), 1 deletion(-) diff --git a/GP/Gp.cpp b/GP/Gp.cpp index b3890bb6..15469f33 100644 --- a/GP/Gp.cpp +++ b/GP/Gp.cpp @@ -48,8 +48,11 @@ static char THIS_FILE[] = __FILE__; #define new DEBUG_NEW #endif +wxDEFINE_EVENT(WM_ROTATEPIECE_DELTA_WX, RotatePieceDeltaEvent); +wxDEFINE_EVENT(WM_CENTERBOARDONPOINT_WX, CenterBoardOnPointEvent); wxDEFINE_EVENT(WM_SHOWPLAYINGBOARD_WX, ShowPlayingBoardEvent); wxDEFINE_EVENT(WM_WINSTATE_RESTORE_WX, WinStateRestoreEvent); +wxDEFINE_EVENT(WM_SELECT_BOARD_OBJLIST_WX, SelectBoardObjListEvent); ///////////////////////////////////////////////////////////////////////////// // Registry keys... diff --git a/GP/Gp.h b/GP/Gp.h index 7f07452e..905e53b8 100644 --- a/GP/Gp.h +++ b/GP/Gp.h @@ -1,6 +1,6 @@ // Gp.h : main header file for the GP application // -// Copyright (c) 1994-2020 By Dale L. Larson, All Rights Reserved. +// Copyright (c) 1994-2025 By Dale L. Larson & William Su, All Rights Reserved. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the @@ -33,6 +33,9 @@ #include "versions.h" #include "FrmMain.h" +class CPlayBoard; +class CDrawObj; + ///////////////////////////////////////////////////////////////////////////// #define IDW_TOOLBAR_MAIN AFX_IDW_TOOLBAR @@ -47,7 +50,52 @@ ///////////////////////////////////////////////////////////////////////////// #define WM_ROTATEPIECE_DELTA (WM_USER + 210) // WPARAM = (int)relative rotation delta +class RotatePieceDeltaEvent : public wxEvent +{ +public: + RotatePieceDeltaEvent(int delta); + + int GetDelta() const { return delta; } + + wxEvent* Clone() const override { return new RotatePieceDeltaEvent(*this); } + +private: + const int delta; +}; +wxDECLARE_EVENT(WM_ROTATEPIECE_DELTA_WX, RotatePieceDeltaEvent); +inline RotatePieceDeltaEvent::RotatePieceDeltaEvent(int d) : + wxEvent(wxID_ANY, WM_ROTATEPIECE_DELTA_WX), + delta(d) +{ +} +typedef void (wxEvtHandler::* RotatePieceDeltaEventFunction)(RotatePieceDeltaEvent&); +#define RotatePieceDeltaEventHandler(func) wxEVENT_HANDLER_CAST(RotatePieceDeltaEventFunction, func) +#define EVT_ROTATEPIECE_DELTA(func) \ + wx__DECLARE_EVT0(WM_ROTATEPIECE_DELTA_WX, RotatePieceDeltaEventHandler(func)) + #define WM_CENTERBOARDONPOINT (WM_USER + 211) // WPARAM = POINT* in board coords +class CenterBoardOnPointEvent : public wxEvent +{ +public: + CenterBoardOnPointEvent(const wxPoint& point); + + const wxPoint& GetPoint() const { return point; } + + wxEvent* Clone() const override { return new CenterBoardOnPointEvent(*this); } + +private: + const wxPoint point; +}; +wxDECLARE_EVENT(WM_CENTERBOARDONPOINT_WX, CenterBoardOnPointEvent); +inline CenterBoardOnPointEvent::CenterBoardOnPointEvent(const wxPoint& p) : + wxEvent(wxID_ANY, WM_CENTERBOARDONPOINT_WX), + point(p) +{ +} +typedef void (wxEvtHandler::* CenterBoardOnPointEventFunction)(CenterBoardOnPointEvent&); +#define CenterBoardOnPointEventHandler(func) wxEVENT_HANDLER_CAST(CenterBoardOnPointEventFunction, func) +#define EVT_CENTERBOARDONPOINT(func) \ + wx__DECLARE_EVT0(WM_CENTERBOARDONPOINT_WX, CenterBoardOnPointEventHandler(func)) #define WM_SHOWPLAYINGBOARD (WM_USER + 212) // WPARAM = size_t Playing Board Index class ShowPlayingBoardEvent : public wxEvent @@ -92,6 +140,36 @@ typedef void (wxEvtHandler::* WinStateRestoreEventFunction)(WinStateRestoreEvent wx__DECLARE_EVT0(WM_WINSTATE_RESTORE_WX, WinStateRestoreEventHandler(func)) #define WM_SELECT_BOARD_OBJLIST (WM_USER + 214) // WPARAM = CPlayBoard*, LPARAM = const std::vector>* +class SelectBoardObjListEvent : public wxEvent +{ +public: + SelectBoardObjListEvent(const CPlayBoard& b, + const std::vector>& l); + + const CPlayBoard& GetBoard() const { return board; } + const std::vector>& GetObjList() const + { + return objList; + } + + wxEvent* Clone() const override { return new SelectBoardObjListEvent(*this); } + +private: + const CPlayBoard& board; + const std::vector>& objList; +}; +wxDECLARE_EVENT(WM_SELECT_BOARD_OBJLIST_WX, SelectBoardObjListEvent); +inline SelectBoardObjListEvent::SelectBoardObjListEvent(const CPlayBoard& b, + const std::vector>& l) : + wxEvent(wxID_ANY, WM_SELECT_BOARD_OBJLIST_WX), + board(b), + objList(l) +{ +} +typedef void (wxEvtHandler::* SelectBoardObjListEventFunction)(SelectBoardObjListEvent&); +#define SelectBoardObjListEventHandler(func) wxEVENT_HANDLER_CAST(SelectBoardObjListEventFunction, func) +#define EVT_SELECT_BOARD_OBJLIST(func) \ + wx__DECLARE_EVT0(WM_SELECT_BOARD_OBJLIST_WX, SelectBoardObjListEventHandler(func)) #define WM_MESSAGEBOX (WM_USER + 215) // WPARAM = Opts. LPARAM = Msg ID or Ptr enum From 325b046e499203d39a8db455c48c6a28eb140dd2 Mon Sep 17 00:00:00 2001 From: Bill Su Date: Sat, 31 Jan 2026 19:26:27 -0500 Subject: [PATCH 39/80] LBoxGrfx: provide wx version of some WM messages Provide WM_OVERRIDE_SELECTED_ITEM_WX and WM_OVERRIDE_SELECTED_ITEM_LIST_WX and their wxEvent types. Since the MFC events passed custom data anyway, rewrite the MFC code to use the wxEvent types to verify that the new types work as intended. --- GP/PalMark.cpp | 5 +- GP/PalTray.cpp | 10 ++-- GShr/LBoxGrfx.cpp | 2 + GShr/LBoxGrfx.h | 117 +++++++++++++++++++++++++++++++--------------- 4 files changed, 89 insertions(+), 45 deletions(-) diff --git a/GP/PalMark.cpp b/GP/PalMark.cpp index 312f3d19..05ad2bac 100644 --- a/GP/PalMark.cpp +++ b/GP/PalMark.cpp @@ -195,15 +195,14 @@ LRESULT CMarkerPalette::OnOverrideSelectedItem(WPARAM wParam, LPARAM lParam) CMarkSet& pMSet = pMMgr.GetMarkSet(nSel); if (pMSet.IsRandomMarkerPull()) { - COverrideInfo& oi = *reinterpret_cast*>(wParam); - oi.CheckType(); + OverrideSelectedItemEvent& oi = *reinterpret_cast(wParam); uint32_t nRandSeed = m_pDoc->GetRandomNumberSeed(); int32_t nRandNum = CalcRandomNumberUsingSeed(0, value_preserving_cast(pMSet.GetMarkIDTable().size()), nRandSeed, &nRandSeed); - oi.m_markID = pMSet.GetMarkIDTable().at(value_preserving_cast(nRandNum)); + oi.ID() = pMSet.GetMarkIDTable().at(value_preserving_cast(nRandNum)); m_pDoc->SetRandomNumberSeed(nRandSeed); } diff --git a/GP/PalTray.cpp b/GP/PalTray.cpp index 0ce8bc22..2068060a 100644 --- a/GP/PalTray.cpp +++ b/GP/PalTray.cpp @@ -335,12 +335,12 @@ void CTrayPalette::OnLButtonUp(UINT nFlags, CPoint point) // of items. It gives the tray the chance to mess with the list's // contents prior to commiting it. -LRESULT CTrayPalette::OnOverrideSelectedItemList(WPARAM wParam, LPARAM lParam) +LRESULT CTrayPalette::OnOverrideSelectedItemList(WPARAM wParam, LPARAM /*lParam*/) { - wchar_t prefix = value_preserving_cast(lParam); - ASSERT(prefix == L'P' && wParam); + wxASSERT(dynamic_cast(reinterpret_cast(wParam))); + OverrideSelectedItemListEvent& oil = *reinterpret_cast(wParam); size_t nSel = GetSelectedTray(); - if (nSel == Invalid_v || !wParam || prefix != L'P') + if (nSel == Invalid_v) return (LRESULT)0; CTrayManager& pYMgr = m_pDoc->GetTrayManager(); @@ -349,7 +349,7 @@ LRESULT CTrayPalette::OnOverrideSelectedItemList(WPARAM wParam, LPARAM lParam) if (pYSet.IsRandomPiecePull() || pYSet.IsRandomSidePull()) { - std::vector& pPceArray = *reinterpret_cast*>(wParam); + std::vector& pPceArray = oil.Vector(); uint32_t nRandSeed = m_pDoc->GetRandomNumberSeed(); diff --git a/GShr/LBoxGrfx.cpp b/GShr/LBoxGrfx.cpp index e923ee75..205d93bd 100644 --- a/GShr/LBoxGrfx.cpp +++ b/GShr/LBoxGrfx.cpp @@ -34,6 +34,8 @@ #define new DEBUG_NEW #endif +wxDEFINE_EVENT(WM_OVERRIDE_SELECTED_ITEM_WX, OverrideSelectedItemEvent); +wxDEFINE_EVENT(WM_OVERRIDE_SELECTED_ITEM_LIST_WX, OverrideSelectedItemListEvent); wxDEFINE_EVENT(WM_GET_DRAG_SIZE_WX, GetDragSizeEvent); DragInfo CGrafixListBox::di; diff --git a/GShr/LBoxGrfx.h b/GShr/LBoxGrfx.h index 944c2d0b..38b20fbe 100644 --- a/GShr/LBoxGrfx.h +++ b/GShr/LBoxGrfx.h @@ -26,6 +26,7 @@ #define _LBOXGRFX_H #include +#include #ifndef _DRAGDROP_H #include "DragDrop.h" @@ -48,55 +49,95 @@ // These messages are sent by the CGrafixListBox to its parent window. // It allows the list's content to be overridden. It's primary use // is to deliver a random selection of pieces or markers. -#define WM_OVERRIDE_SELECTED_ITEM (WM_USER + 500) // WPARAM = COverrideInfoBase<>* -struct COverrideInfoBase +#define WM_OVERRIDE_SELECTED_ITEM (WM_USER + 500) // WPARAM = OverrideSelectedItemEvent* +class OverrideSelectedItemEvent : public wxEvent { -protected: - COverrideInfoBase(DragType dt) : m_dragType(dt) {} +public: + /* currently supports MarkID and TileID + (easy to add more to variant) */ + template + OverrideSelectedItemEvent(T& id); - template - void CheckTypeBase() const + template + const T& ID() const { - ASSERT(m_dragType == DT); - /* TODO: This check could be removed to improve release - build performance if we trust ourselves to always - catch any m_dragType mistakes in testing. */ - if (m_dragType != DT) - { - AfxThrowInvalidArgException(); - } + return std::get>(id).get(); + } + + template + T& ID() + { + return const_cast(std::as_const(*this).ID()); } + wxEvent* Clone() const override { return new OverrideSelectedItemEvent(*this); } + private: - const DragType m_dragType; + std::variant< + std::reference_wrapper, + std::reference_wrapper, + std::nullptr_t // dummy for allowing , on previous line + > id; }; +wxDECLARE_EVENT(WM_OVERRIDE_SELECTED_ITEM_WX, OverrideSelectedItemEvent); -template -struct COverrideInfo +template +OverrideSelectedItemEvent::OverrideSelectedItemEvent(T& id) : + wxEvent(wxID_ANY, WM_OVERRIDE_SELECTED_ITEM_WX), + id(std::ref(id)) { -}; +} + +typedef void (wxEvtHandler::* OverrideSelectedItemEventFunction)(OverrideSelectedItemEvent&); +#define OverrideSelectedItemEventHandler(func) wxEVENT_HANDLER_CAST(OverrideSelectedItemEventFunction, func) +#define EVT_OVERRIDE_SELECTED_ITEM(func) \ + wx__DECLARE_EVT0(WM_OVERRIDE_SELECTED_ITEM_WX, OverrideSelectedItemEventHandler(func)) -template<> -struct COverrideInfo : private COverrideInfoBase +#define WM_OVERRIDE_SELECTED_ITEM_LIST (WM_USER + 501) // WPARAM = OverrideSelectedItemListEvent* +class OverrideSelectedItemListEvent : public wxEvent { - COverrideInfo(MarkID& mid) : COverrideInfoBase(DRAG_MARKER), m_markID(mid) {} +public: + /* currently supports MarkID, PieceID, and TileID + (easy to add more to variant) */ + template + OverrideSelectedItemListEvent(std::vector& id); + + template + const std::vector& Vector() const + { + return std::get>>(vector).get(); + } + + template + std::vector& Vector() + { + return const_cast&>(std::as_const(*this).Vector()); + } - void CheckType() const { CheckTypeBase(); } + wxEvent* Clone() const override { return new OverrideSelectedItemListEvent(*this); } - MarkID& m_markID; +private: + std::variant< + std::reference_wrapper>, + std::reference_wrapper>, + std::reference_wrapper>, + std::nullptr_t // dummy for allowing , on previous line + > vector; }; +wxDECLARE_EVENT(WM_OVERRIDE_SELECTED_ITEM_LIST_WX, OverrideSelectedItemListEvent); -template<> -struct COverrideInfo : private COverrideInfoBase +template +OverrideSelectedItemListEvent::OverrideSelectedItemListEvent(std::vector& v) : + wxEvent(wxID_ANY, WM_OVERRIDE_SELECTED_ITEM_LIST_WX), + vector(std::ref(v)) { - COverrideInfo(TileID& tid) : COverrideInfoBase(DRAG_TILE), m_tileID(tid) {} +} - void CheckType() const { CheckTypeBase(); } - - TileID& m_tileID; -}; +typedef void (wxEvtHandler::* OverrideSelectedItemListEventFunction)(OverrideSelectedItemListEvent&); +#define OverrideSelectedItemListEventHandler(func) wxEVENT_HANDLER_CAST(OverrideSelectedItemListEventFunction, func) +#define EVT_OVERRIDE_SELECTED_ITEM_LIST(func) \ + wx__DECLARE_EVT0(WM_OVERRIDE_SELECTED_ITEM_LIST_WX, OverrideSelectedItemListEventHandler(func)) -#define WM_OVERRIDE_SELECTED_ITEM_LIST (WM_USER + 501) // WPARAM = std::vector>*, LPARAM = XxxxID::PREFIX /* We don't allow drop if the dropped objects are too big for the destination, but checking requires knowing the size of the dropped objects. So, parallel to @@ -398,21 +439,22 @@ class CGrafixListBoxData : public BASE_WND CWnd* pWnd = this->GetParent(); ASSERT(pWnd != NULL); - pWnd->SendMessage(WM_OVERRIDE_SELECTED_ITEM_LIST, reinterpret_cast(&m_multiSelList), T::PREFIX); + OverrideSelectedItemListEvent oil(m_multiSelList); + pWnd->SendMessage(WM_OVERRIDE_SELECTED_ITEM_LIST, reinterpret_cast(&oil)); } else { // The parent may want to override the value. if (BASE_WND::di.GetDragType() == DRAG_MARKER) { - COverrideInfo oi(BASE_WND::di.GetSubInfo().m_markID); + OverrideSelectedItemEvent oi(BASE_WND::di.GetSubInfo().m_markID); CWnd* pWnd = this->GetParent(); ASSERT(pWnd != NULL); pWnd->SendMessage(WM_OVERRIDE_SELECTED_ITEM, reinterpret_cast(&oi)); } else if (BASE_WND::di.GetDragType() == DRAG_TILE) { - COverrideInfo oi(BASE_WND::di.GetSubInfo().m_tileID); + OverrideSelectedItemEvent oi(BASE_WND::di.GetSubInfo().m_tileID); CWnd* pWnd = this->GetParent(); ASSERT(pWnd != NULL); pWnd->SendMessage(WM_OVERRIDE_SELECTED_ITEM, reinterpret_cast(&oi)); @@ -751,7 +793,8 @@ class CGrafixListBoxDataWx : public BASE_WND #if 0 CWnd* pWnd = this->GetParent(); ASSERT(pWnd != NULL); - pWnd->SendMessage(WM_OVERRIDE_SELECTED_ITEM_LIST, reinterpret_cast(&m_multiSelList), T::PREFIX); + OverrideSelectedItemListEvent oil(m_multiSelList); + pWnd->SendMessage(WM_OVERRIDE_SELECTED_ITEM_LIST, reinterpret_cast(&oil)); #endif #endif } @@ -762,7 +805,7 @@ class CGrafixListBoxDataWx : public BASE_WND { wxASSERT(!"TODO:"); #if 0 - COverrideInfo oi(BASE_WND::di.GetSubInfo().m_markID); + OverrideSelectedItemEvent oi(BASE_WND::di.GetSubInfo().m_markID); CWnd* pWnd = this->GetParent(); ASSERT(pWnd != NULL); pWnd->SendMessage(WM_OVERRIDE_SELECTED_ITEM, reinterpret_cast(&oi)); @@ -773,7 +816,7 @@ class CGrafixListBoxDataWx : public BASE_WND #if defined(GPLAY) wxASSERT(!"TODO:"); #if 0 - COverrideInfo oi(BASE_WND::di.GetSubInfo().m_tileID); + OverrideSelectedItemEvent oi(BASE_WND::di.GetSubInfo().m_tileID); CWnd* pWnd = this->GetParent(); ASSERT(pWnd != NULL); pWnd->SendMessage(WM_OVERRIDE_SELECTED_ITEM, reinterpret_cast(&oi)); From 5ee3cb31e20a057c459a50d045108e198e735057 Mon Sep 17 00:00:00 2001 From: Bill Su Date: Fri, 3 Oct 2025 23:49:37 -0400 Subject: [PATCH 40/80] GamDoc: remove dead code so CB::ToolTip doesn't need to support titles --- GP/GamDoc.h | 2 +- GP/GamDoc5.cpp | 5 ++--- GP/VwPbrd1.cpp | 6 +----- 3 files changed, 4 insertions(+), 9 deletions(-) diff --git a/GP/GamDoc.h b/GP/GamDoc.h index 7d40a932..35298db0 100644 --- a/GP/GamDoc.h +++ b/GP/GamDoc.h @@ -378,7 +378,7 @@ class CGamDoc : public CDocument CB::string GetGameElementString(GameElement gelem) const; BOOL HasGameElementString(GameElement gelem) const; void SetGameElementString(GameElement gelem, const CB::string* pszString); - void GetTipTextForObject(const CDrawObj& pDObj, CB::string &strTip, CB::string* pStrTitle = NULL) const; + void GetTipTextForObject(const CDrawObj& pDObj, CB::string &strTip) const; // Invalid_v = top GameElement GetGameElementCodeForObject(const CDrawObj& pDObj, size_t nSide = Invalid_v) const; GameElement GetVerifiedGameElementCodeForObject(const CDrawObj& pDObj, size_t nSide = Invalid_v) const; diff --git a/GP/GamDoc5.cpp b/GP/GamDoc5.cpp index 1fa34add..ea46f6cd 100644 --- a/GP/GamDoc5.cpp +++ b/GP/GamDoc5.cpp @@ -198,8 +198,7 @@ GameElement CGamDoc::GetVerifiedGameElementCodeForObject(const CDrawObj& pDObj, return elem; } -void CGamDoc::GetTipTextForObject(const CDrawObj& pDObj, CB::string &strTip, - CB::string* pStrTitle /* = NULL */) const +void CGamDoc::GetTipTextForObject(const CDrawObj& pDObj, CB::string &strTip) const { if (pDObj.GetType() == CDrawObj::drawPieceObj) { @@ -273,7 +272,7 @@ void CGamDoc::DoEditObjectText(const CDrawObj& pDObj) CEditElementTextDialog dlg; CB::string strTip; - GetTipTextForObject(pDObj, strTip, NULL); + GetTipTextForObject(pDObj, strTip); dlg.m_strText = strTip; diff --git a/GP/VwPbrd1.cpp b/GP/VwPbrd1.cpp index fb7169f3..9cd9957d 100644 --- a/GP/VwPbrd1.cpp +++ b/GP/VwPbrd1.cpp @@ -96,9 +96,8 @@ void CPlayBoardView::DoToolTipHitProcessing(CPoint pointClient) rct = WorkspaceToClient(rct); CB::string strTip; - CB::string strTitle; if (pDoc.IsShowingObjectTips()) - pDoc.GetTipTextForObject(*pDObj, strTip, &strTitle); + pDoc.GetTipTextForObject(*pDObj, strTip); // All this stuff is used to annotate tips with owner names // when player accounts are active. @@ -137,9 +136,6 @@ void CPlayBoardView::DoToolTipHitProcessing(CPoint pointClient) { m_toolHitTip.AddTool(this, strTip, rct, ID_TIP_PLAYBOARD_HIT); - if (!strTitle.empty()) - m_toolHitTip.SendMessage(TTM_SETTITLE, 0, reinterpret_cast(strTitle.v_str())); - m_toolHitTip.Activate(TRUE); } else From a9156cd4aefad9625d4edea3207c5cf66f7892bb Mon Sep 17 00:00:00 2001 From: Bill Su Date: Thu, 23 Oct 2025 00:08:49 -0400 Subject: [PATCH 41/80] ToolPlay: improve const/null/override/ownership correctness --- GP/ToolPlay.cpp | 288 ++++++++++++++++++++++++------------------------ GP/ToolPlay.h | 104 ++++++++--------- GP/VwPbrd.cpp | 12 +- 3 files changed, 202 insertions(+), 202 deletions(-) diff --git a/GP/ToolPlay.cpp b/GP/ToolPlay.cpp index 0ef633bb..59d2e4d6 100644 --- a/GP/ToolPlay.cpp +++ b/GP/ToolPlay.cpp @@ -82,24 +82,24 @@ CPlayTool& CPlayTool::GetTool(PToolType eToolType) return retval; } -void CPlayTool::OnLButtonDown(CPlayBoardView* pView, UINT nFlags, CPoint point) +void CPlayTool::OnLButtonDown(CPlayBoardView& pView, UINT nFlags, CPoint point) { - pView->SetCapture(); + pView.SetCapture(); c_ptDown = point; c_ptLast = point; } -void CPlayTool::OnMouseMove(CPlayBoardView* pView, UINT nFlags, CPoint point) +void CPlayTool::OnMouseMove(CPlayBoardView& pView, UINT nFlags, CPoint point) { - if (CWnd::GetCapture() == pView) + if (CWnd::GetCapture() == &pView) c_ptLast = point; SetCursor(AfxGetApp()->LoadStandardCursor(IDC_ARROW)); } -bool CPlayTool::OnLButtonUp(CPlayBoardView* pView, UINT, CPoint point) +bool CPlayTool::OnLButtonUp(CPlayBoardView& pView, UINT nFlags, CPoint point) { - if (CWnd::GetCapture() != pView) + if (CWnd::GetCapture() != &pView) return false; ReleaseCapture(); return true; @@ -108,11 +108,11 @@ bool CPlayTool::OnLButtonUp(CPlayBoardView* pView, UINT, CPoint point) //////////////////////////////////////////////////////////////////////// // CPSelectTool - Object Selection/Manipulation tool -void CPSelectTool::OnLButtonDown(CPlayBoardView* pView, UINT nFlags, +void CPSelectTool::OnLButtonDown(CPlayBoardView& pView, UINT nFlags, CPoint point) { - CSelList& pSLst = pView->GetSelectList(); - CPlayBoard& pPBoard = pView->GetPlayBoard(); + CSelList& pSLst = pView.GetSelectList(); + CPlayBoard& pPBoard = pView.GetPlayBoard(); // If a a handle is clicked on, immediately start tracking the // resize. @@ -121,14 +121,14 @@ void CPSelectTool::OnLButtonDown(CPlayBoardView* pView, UINT nFlags, StartSizingOperation(pView, nFlags, point); return; } - CDrawObj* pObj = pView->ObjectHitTest(point); + CDrawObj* pObj = pView.ObjectHitTest(point); BOOL bOwnedButNotOkToSelect = FALSE; if (pObj != NULL && pObj->GetType() == CDrawObj::drawPieceObj) { CPieceObj* pPObj = (CPieceObj*)pObj; - PlayerMask dwCurrentPlayer = pView->GetDocument().GetCurrentPlayerMask(); - bOwnedButNotOkToSelect = !pView->GetDocument().IsScenario() && + PlayerMask dwCurrentPlayer = pView.GetDocument().GetCurrentPlayerMask(); + bOwnedButNotOkToSelect = !pView.GetDocument().IsScenario() && !pPBoard.IsNonOwnerAccessAllowed() && pPObj->IsOwned() && !pPObj->IsOwnedBy(dwCurrentPlayer); } @@ -145,9 +145,9 @@ void CPSelectTool::OnLButtonDown(CPlayBoardView* pView, UINT nFlags, // No objects were under the mouse click. m_eSelMode = smodeNet; // Net type selection CPlayTool::OnLButtonDown(pView, nFlags, point); - CClientDC dc(pView); - pView->OnPrepareScaledDC(dc, TRUE); - DrawNetRect(&dc, pView); + CClientDC dc(&pView); + pView.OnPrepareScaledDC(dc, TRUE); + DrawNetRect(dc, pView); return; } // Object is under mouse. See if also selected. If not, @@ -157,13 +157,13 @@ void CPSelectTool::OnLButtonDown(CPlayBoardView* pView, UINT nFlags, if ((nFlags & MK_SHIFT) == 0) // Shift click adds to list pSLst.PurgeList(TRUE); // Clear current select list if ((nFlags & MK_CONTROL) != 0) // Control click drills down - pView->SelectAllUnderPoint(point); + pView.SelectAllUnderPoint(point); else { pSLst.AddObject(*pObj, TRUE); if (pObj->GetType() == CDrawObj::drawPieceObj || pObj->GetType() == CDrawObj::drawMarkObj) - pView->NotifySelectListChange(); + pView.NotifySelectListChange(); } CPlayTool::OnLButtonDown(pView, nFlags, point); StartDragTimer(pView); @@ -192,11 +192,11 @@ void CPSelectTool::OnLButtonDown(CPlayBoardView* pView, UINT nFlags, StartDragTimer(pView); } -void CPSelectTool::OnMouseMove(CPlayBoardView* pView, UINT nFlags, CPoint point) +void CPSelectTool::OnMouseMove(CPlayBoardView& pView, UINT nFlags, CPoint point) { - CSelList& pSLst = pView->GetSelectList(); + CSelList& pSLst = pView.GetSelectList(); - if (CWnd::GetCapture() != pView) + if (CWnd::GetCapture() != &pView) return; if (m_eSelMode != smodeNormal && m_eSelMode != smodeMove) @@ -207,8 +207,8 @@ void CPSelectTool::OnMouseMove(CPlayBoardView* pView, UINT nFlags, CPoint point) CRect rct; CPoint pt; GetCursorPos(&pt); - pView->ScreenToClient(&pt); - pView->GetClientRect(&rct); + pView.ScreenToClient(&pt); + pView.GetClientRect(rct); if (rct.PtInRect(pt)) // In client area { rct.InflateRect(-scrollZone, -scrollZone); @@ -230,11 +230,11 @@ void CPSelectTool::OnMouseMove(CPlayBoardView* pView, UINT nFlags, CPoint point) // we are doing a "net select". if (m_eSelMode == smodeNet) { - CClientDC dc(pView); - pView->OnPrepareScaledDC(dc, TRUE); - DrawNetRect(&dc, pView); // Erase previous position + CClientDC dc(&pView); + pView.OnPrepareScaledDC(dc, TRUE); + DrawNetRect(dc, pView); // Erase previous position CPlayTool::OnMouseMove(pView, nFlags, point); // Update position - DrawNetRect(&dc, pView); // Draw new position rect + DrawNetRect(dc, pView); // Draw new position rect return; } // If object(s) are being moved or sized, removed last tracking @@ -242,56 +242,56 @@ void CPSelectTool::OnMouseMove(CPlayBoardView* pView, UINT nFlags, CPoint point) // tracking image. if (m_eSelMode == smodeMove) { - point = pView->WorkspaceToClient(point); + point = pView.WorkspaceToClient(point); DoDragDrop(pView, point); return; } else if (m_eSelMode == smodeSizing) { - point = pView->AdjustPoint(point); + point = pView.AdjustPoint(point); if (point == c_ptLast) return; - CClientDC dc(pView); - pView->OnPrepareScaledDC(dc, TRUE); + CClientDC dc(&pView); + pView.OnPrepareScaledDC(dc, TRUE); pSLst.DrawTracker(dc, trkSizing); // Erase previous tracker - MoveSelections(&pSLst, point); + MoveSelections(pSLst, point); pSLst.DrawTracker(dc, trkSizing); // Erase previous tracker } c_ptLast = point; // Save new 'last' position } -bool CPSelectTool::OnLButtonUp(CPlayBoardView* pView, UINT nFlags, CPoint point) +bool CPSelectTool::OnLButtonUp(CPlayBoardView& pView, UINT nFlags, CPoint point) { bool retval = true; - if (CWnd::GetCapture() == pView) + if (CWnd::GetCapture() == &pView) { if (m_eSelMode == smodeNet) { - CClientDC dc(pView); - pView->OnPrepareScaledDC(dc, TRUE); - DrawNetRect(&dc, pView); // Erase previous position + CClientDC dc(&pView); + pView.OnPrepareScaledDC(dc, TRUE); + DrawNetRect(dc, pView); // Erase previous position // If the control key is down when button was released, fields // that intersect the select rect will selected. Otherwise only // those fields that are entirely within the select rect // will be selected. CRect rect(c_ptDown.x, c_ptDown.y, c_ptLast.x, c_ptLast.y); rect.NormalizeRect(); - pView->SelectWithinRect(rect, (nFlags & MK_CONTROL) != 0); - CSelList& pSLst = pView->GetSelectList(); + pView.SelectWithinRect(rect, (nFlags & MK_CONTROL) != 0); + CSelList& pSLst = pView.GetSelectList(); pSLst.InvalidateListHandles(); } else if (m_eSelMode != smodeNormal) { - CSelList& pSLst = pView->GetSelectList(); + CSelList& pSLst = pView.GetSelectList(); if (m_eSelMode == smodeMove) { CPoint pnt = point; pSLst.SetTrackingMode(trkSelected); - pnt = pView->WorkspaceToClient(pnt); + pnt = pView.WorkspaceToClient(pnt); retval = DoDragDropEnd(pView, pnt) && retval; } else @@ -312,9 +312,9 @@ bool CPSelectTool::OnLButtonUp(CPlayBoardView* pView, UINT nFlags, CPoint point) return CPlayTool::OnLButtonUp(pView, nFlags, point) && retval; } -void CPSelectTool::OnTimer(CPlayBoardView* pView, uintptr_t nIDEvent) +void CPSelectTool::OnTimer(CPlayBoardView& pView, uintptr_t nIDEvent) { - if (CWnd::GetCapture() != pView) + if (CWnd::GetCapture() != &pView) { m_eSelMode = smodeNormal; KillDragTimer(pView); @@ -323,7 +323,7 @@ void CPSelectTool::OnTimer(CPlayBoardView* pView, uintptr_t nIDEvent) } if (m_eSelMode == smodeNormal) { - CSelList& pSLst = pView->GetSelectList(); + CSelList& pSLst = pView.GetSelectList(); // Mouse is captured and no particular drag operation // is underway. Therefore we want a move that draws @@ -331,18 +331,18 @@ void CPSelectTool::OnTimer(CPlayBoardView* pView, uintptr_t nIDEvent) m_eSelMode = smodeMove; KillDragTimer(pView); - CClientDC dc(pView); - pView->OnPrepareScaledDC(dc, TRUE); + CClientDC dc(&pView); + pView.OnPrepareScaledDC(dc, TRUE); pSLst.DrawTracker(dc, trkSelected); // Turn off handles CPoint point; GetCursorPos(&point); - pView->ScreenToClient(&point); - point = pView->ClientToWorkspace(point); + pView.ScreenToClient(&point); + point = pView.ClientToWorkspace(point); pSLst.SetTrackingMode(trkMoving); DoDragDropStart(pView); - point = pView->WorkspaceToClient(point); + point = pView.WorkspaceToClient(point); DoDragDrop(pView, point); } else if (m_eSelMode != smodeMove) @@ -352,16 +352,16 @@ void CPSelectTool::OnTimer(CPlayBoardView* pView, uintptr_t nIDEvent) } } -void CPSelectTool::OnLButtonDblClk(CPlayBoardView* pView, UINT nFlags, +void CPSelectTool::OnLButtonDblClk(CPlayBoardView& pView, UINT nFlags, CPoint point) { // Normal DblClk opens some property view of the selected // object. Only recognized if only one selection is active. CPlayTool::OnLButtonDblClk(pView, nFlags, point); - pView->GetSelectList().Open(); + pView.GetSelectList().Open(); } -BOOL CPSelectTool::OnSetCursor(CPlayBoardView* pView, UINT nHitTest) +BOOL CPSelectTool::OnSetCursor(const CPlayBoardView& pView, UINT nHitTest) const { // Process only within the client area if (nHitTest != HTCLIENT) @@ -370,17 +370,17 @@ BOOL CPSelectTool::OnSetCursor(CPlayBoardView* pView, UINT nHitTest) // Convert cursor position to document coordinates CPoint point; GetCursorPos(&point); - pView->ScreenToClient(&point); - point = pView->ClientToWorkspace(point); + pView.ScreenToClient(&point); + point = pView.ClientToWorkspace(point); // Check for movement through handle areas. Set the // cursor to the appropriate shape. - CSelList& pSLst = pView->GetSelectList(); + const CSelList& pSLst = pView.GetSelectList(); if (pSLst.IsSingleSelect()) { // Check if cursor is over a handle. If it is, // get handle cursor. - CSelection& pSelObj = *pSLst.front(); + const CSelection& pSelObj = *pSLst.front(); int nHandle = pSelObj.HitTestHandles(point); if (nHandle >= 0) { @@ -391,52 +391,52 @@ BOOL CPSelectTool::OnSetCursor(CPlayBoardView* pView, UINT nHitTest) return FALSE; // Show default cursor } -void CPSelectTool::StartSizingOperation(CPlayBoardView* pView, UINT nFlags, - CPoint point, int nHandleID) +void CPSelectTool::StartSizingOperation(CPlayBoardView& pView, UINT nFlags, + const CPoint& point, int nHandleID) { - CSelList& pSLst = pView->GetSelectList(); + CSelList& pSLst = pView.GetSelectList(); if (nHandleID != -1) m_nHandleID = nHandleID; m_eSelMode = smodeSizing; CPlayTool::OnLButtonDown(pView, nFlags, point); - CClientDC dc(pView); - pView->OnPrepareScaledDC(dc, TRUE); + CClientDC dc(&pView); + pView.OnPrepareScaledDC(dc, TRUE); pSLst.DrawTracker(dc, trkSizing); } -void CPSelectTool::DrawSelectionRect(CDC* pDC, CRect* pRct) +void CPSelectTool::DrawSelectionRect(CDC& pDC, const CRect& pRct) const { CPen pen; pen.CreateStockObject(WHITE_PEN); - CPen* pPrvPen = pDC->SelectObject(&pen); - int nPrvROP2 = pDC->SetROP2(R2_XORPEN); + CPen* pPrvPen = pDC.SelectObject(&pen); + int nPrvROP2 = pDC.SetROP2(R2_XORPEN); - pDC->MoveTo(pRct->TopLeft()); - pDC->LineTo(pRct->right, pRct->top); - pDC->LineTo(pRct->BottomRight()); - pDC->LineTo(pRct->left, pRct->bottom); - pDC->LineTo(pRct->TopLeft()); + pDC.MoveTo(pRct.TopLeft()); + pDC.LineTo(pRct.right, pRct.top); + pDC.LineTo(pRct.BottomRight()); + pDC.LineTo(pRct.left, pRct.bottom); + pDC.LineTo(pRct.TopLeft()); - pDC->SetROP2(nPrvROP2); - pDC->SelectObject(pPrvPen); + pDC.SetROP2(nPrvROP2); + pDC.SelectObject(pPrvPen); } -void CPSelectTool::DrawNetRect(CDC* pDC, CPlayBoardView* pView) +void CPSelectTool::DrawNetRect(CDC& pDC, const CPlayBoardView& /*pView*/) const { CRect rect(c_ptDown.x, c_ptDown.y, c_ptLast.x, c_ptLast.y); rect.NormalizeRect(); DrawSelectionRect(pDC, &rect); } -BOOL CPSelectTool::ProcessAutoScroll(CPlayBoardView* pView) +BOOL CPSelectTool::ProcessAutoScroll(CPlayBoardView& pView) { CPoint point; CRect rectClient; CRect rect; GetCursorPos(&point); - pView->ScreenToClient(&point); - pView->GetClientRect(&rectClient); + pView.ScreenToClient(&point); + pView.GetClientRect(&rectClient); rect = rectClient; rect.InflateRect(-scrollZone, -scrollZone); rect.NormalizeRect(); @@ -456,48 +456,48 @@ BOOL CPSelectTool::ProcessAutoScroll(CPlayBoardView* pView) nScrollID = MAKEWORD(LOBYTE(nScrollID), SB_LINEDOWN); ASSERT(nScrollID != MAKEWORD(-1, -1)); // First check if scroll can happen. - BOOL bValidScroll = pView->OnScroll(nScrollID, 0, FALSE); + BOOL bValidScroll = pView.OnScroll(nScrollID, 0, FALSE); if (bValidScroll) { - CSelList& pSLst = pView->GetSelectList(); - point = pView->ClientToWorkspace(point); + CSelList& pSLst = pView.GetSelectList(); + point = pView.ClientToWorkspace(point); - CClientDC dc(pView); - pView->OnPrepareScaledDC(dc, TRUE); + CClientDC dc(&pView); + pView.OnPrepareScaledDC(dc, TRUE); if (m_eSelMode == smodeNet) { // Erase previous position CRect rect(c_ptDown.x, c_ptDown.y, c_ptLast.x, c_ptLast.y); rect.NormalizeRect(); - DrawSelectionRect(&dc, &rect); + DrawSelectionRect(dc, rect); } else pSLst.DrawTracker(dc); // Turn off tracker - pView->OnScroll(nScrollID, 0, TRUE); - pView->UpdateWindow(); // Redraw image content. + pView.OnScroll(nScrollID, 0, TRUE); + pView.UpdateWindow(); // Redraw image content. - AdjustPoint(pView, point); + point = AdjustPoint(pView, point); - MoveSelections(&pSLst, point); // Offset the tracking data + MoveSelections(pSLst, point); // Offset the tracking data c_ptLast = point; // Save new 'last' position - pView->OnPrepareScaledDC(dc, TRUE); + pView.OnPrepareScaledDC(dc, TRUE); if (m_eSelMode == smodeNet) { GetCursorPos(&point); - pView->ScreenToClient(&point); - point = pView->ClientToWorkspace(point); + pView.ScreenToClient(&point); + point = pView.ClientToWorkspace(point); c_ptLast = point; // Set new 'last' position // Draw updated net rect CRect rect(c_ptDown.x, c_ptDown.y, c_ptLast.x, c_ptLast.y); rect.NormalizeRect(); - DrawSelectionRect(&dc, &rect); + DrawSelectionRect(dc, rect); } else { - MoveSelections(&pSLst, point);// Offset the tracking data + MoveSelections(pSLst, point);// Offset the tracking data c_ptLast = point; // Save new 'last' position pSLst.DrawTracker(dc); // Turn off tracker } @@ -507,26 +507,26 @@ BOOL CPSelectTool::ProcessAutoScroll(CPlayBoardView* pView) return FALSE; } -void CPSelectTool::MoveSelections(CSelList *pSLst, CPoint point) +void CPSelectTool::MoveSelections(CSelList &pSLst, const CPoint& point) { if (m_eSelMode == smodeMove) { CPoint ptDelta = (CPoint)(point - c_ptLast); - pSLst->Offset(ptDelta); + pSLst.Offset(ptDelta); } else - pSLst->MoveHandle(m_nHandleID, point); + pSLst.MoveHandle(m_nHandleID, point); } -BOOL CPSelectTool::AdjustPoint(CPlayBoardView* pView, CPoint& point) +CPoint CPSelectTool::AdjustPoint(const CPlayBoardView& pView, CPoint point) const { - point = pView->AdjustPoint(point); + point = pView.AdjustPoint(point); if (point == c_ptLast) - return FALSE; + return point; if (m_eSelMode == smodeMove) { - CRect rct = pView->GetSelectList().GetEnclosingRect(); - CPoint pnt = pView->GetWorkspaceDim(); + CRect rct = pView.GetSelectList().GetEnclosingRect(); + CPoint pnt = pView.GetWorkspaceDim(); if (rct.left + point.x - c_ptLast.x < 0) // Clamp point.x = c_ptLast.x - rct.left; if (rct.top + point.y - c_ptLast.y < 0) // Clamp @@ -536,34 +536,34 @@ BOOL CPSelectTool::AdjustPoint(CPlayBoardView* pView, CPoint& point) if (rct.bottom + point.y - c_ptLast.y > pnt.y) // Clamp point.y = pnt.y - (rct.bottom - c_ptLast.y); } - return TRUE; + return point; } -void CPSelectTool::StartDragTimer(CPlayBoardView* pView) +void CPSelectTool::StartDragTimer(CPlayBoardView& pView) { - m_nTimerID = pView->SetTimer(timerIDSelectDelay, + m_nTimerID = pView.SetTimer(timerIDSelectDelay, timerSelDelay, NULL); } -void CPSelectTool::KillDragTimer(CPlayBoardView* pView) +void CPSelectTool::KillDragTimer(CPlayBoardView& pView) { if (m_nTimerID != uintptr_t(0)) { - pView->KillTimer(m_nTimerID); + pView.KillTimer(m_nTimerID); m_nTimerID = uintptr_t(0); } } -void CPSelectTool::StartScrollTimer(CPlayBoardView* pView) +void CPSelectTool::StartScrollTimer(CPlayBoardView& pView) { - m_nTimerID = pView->SetTimer(timerIDAutoScroll, timerAutoScroll, NULL); + m_nTimerID = pView.SetTimer(timerIDAutoScroll, timerAutoScroll, NULL); } -void CPSelectTool::KillScrollTimer(CPlayBoardView* pView) +void CPSelectTool::KillScrollTimer(CPlayBoardView& pView) { if (m_nTimerID != uintptr_t(0)) { - pView->KillTimer(m_nTimerID); + pView.KillTimer(m_nTimerID); m_nTimerID = uintptr_t(0); } } @@ -571,20 +571,20 @@ void CPSelectTool::KillScrollTimer(CPlayBoardView* pView) //////////////////////////////////////////////////////////////////////// // Note: The CSelList should have had the mouse offset value set at // this time. -void CPSelectTool::DoDragDropStart(CPlayBoardView* pView) +void CPSelectTool::DoDragDropStart(CPlayBoardView& pView) { m_di.SetDragType(DRAG_SELECTLIST); - m_di.GetSubInfo().m_selectList = &pView->GetSelectList(); - m_di.GetSubInfo().m_gamDoc = &pView->GetDocument(); + m_di.GetSubInfo().m_selectList = &pView.GetSelectList(); + m_di.GetSubInfo().m_gamDoc = &pView.GetDocument(); m_di.m_hcsrSuggest = g_res.hcrDragTile; m_hLastWnd = NULL; } -void CPSelectTool::DoDragDrop(CPlayBoardView* pView, CPoint pntClient) +void CPSelectTool::DoDragDrop(CPlayBoardView& pView, const CPoint& pntClient) { CPoint pnt = pntClient; - pView->ClientToScreen(&pnt); + pView.ClientToScreen(&pnt); CWnd* pWnd = GetWindowFromPoint(pnt); HWND hWnd = pWnd ? pWnd->m_hWnd : NULL; // Get actual window handle @@ -593,9 +593,9 @@ void CPSelectTool::DoDragDrop(CPlayBoardView* pView, CPoint pntClient) if (m_hLastWnd != NULL) { // Signal previous window we are leaving them - CWnd* pLstWnd = CWnd::FromHandle(m_hLastWnd); + CWnd& pLstWnd = CheckedDeref(CWnd::FromHandle(m_hLastWnd)); m_di.m_phase = PhaseDrag::Exit; - pLstWnd->SendMessage(WM_DRAGDROP, GetProcessId(GetCurrentProcess()), + pLstWnd.SendMessage(WM_DRAGDROP, GetProcessId(GetCurrentProcess()), (LPARAM)(LPVOID)&m_di); } // Signal new window we have entered it. @@ -610,7 +610,7 @@ void CPSelectTool::DoDragDrop(CPlayBoardView* pView, CPoint pntClient) if (hWnd != NULL) { m_di.m_point = pntClient; - pView->ClientToScreen(&m_di.m_point); // Move point into new coord system + pView.ClientToScreen(&m_di.m_point); // Move point into new coord system pWnd->ScreenToClient(&m_di.m_point); m_di.m_phase = PhaseDrag::Over; hCursor = (HCURSOR)pWnd->SendMessage(WM_DRAGDROP, GetProcessId(GetCurrentProcess()), @@ -624,17 +624,17 @@ void CPSelectTool::DoDragDrop(CPlayBoardView* pView, CPoint pntClient) SetCursor(g_res.hcrNoDrop); } -bool CPSelectTool::DoDragDropEnd(CPlayBoardView* pView, CPoint pntClient) +bool CPSelectTool::DoDragDropEnd(CPlayBoardView& pView, const CPoint& pntClient) { SetCursor(LoadCursor(NULL, IDC_ARROW)); CPoint pnt = pntClient; - pView->ClientToScreen(&pnt); + pView.ClientToScreen(&pnt); CWnd* pWnd = GetWindowFromPoint(pnt); if (pWnd == NULL) return false; m_di.m_point = pntClient; - pView->ClientToScreen(&m_di.m_point); + pView.ClientToScreen(&m_di.m_point); pWnd->ScreenToClient(&m_di.m_point); m_di.m_phase = PhaseDrag::Drop; @@ -644,46 +644,45 @@ bool CPSelectTool::DoDragDropEnd(CPlayBoardView* pView, CPoint pntClient) //////////////////////////////////////////////////////////////////////// // CPShapeTool - tool used to create rectangles. -void CPShapeTool::OnLButtonDown(CPlayBoardView* pView, UINT nFlags, CPoint point) +void CPShapeTool::OnLButtonDown(CPlayBoardView& pView, UINT nFlags, CPoint point) { - CSelList& pSLst = pView->GetSelectList(); + CSelList& pSLst = pView.GetSelectList(); pSLst.PurgeList(TRUE); // Clear current select list int nDragHandle; - point = pView->AdjustPoint(point); + point = pView.AdjustPoint(point); m_pObj = CreateDrawObj(pView, point, nDragHandle); pSLst.AddObject(*m_pObj, TRUE); s_plySelectTool.StartSizingOperation(pView, nFlags, point, nDragHandle); } -bool CPShapeTool::OnLButtonUp(CPlayBoardView* pView, UINT nFlags, CPoint point) +bool CPShapeTool::OnLButtonUp(CPlayBoardView& pView, UINT nFlags, CPoint point) { - if (CWnd::GetCapture() != pView) + if (CWnd::GetCapture() != &pView) return false; bool retval = true; retval = s_plySelectTool.OnLButtonUp(pView, nFlags, point) && retval; - pView->GetSelectList().PurgeList(TRUE); // Clear current select list + pView.GetSelectList().PurgeList(TRUE); // Clear current select list if (!IsEmptyObject()) - pView->AddDrawObject(m_pObj); + pView.AddDrawObject(std::move(m_pObj)); else { - delete m_pObj; m_pObj = NULL; } return true; } -void CPShapeTool::OnMouseMove(CPlayBoardView* pView, UINT nFlags, CPoint point) +void CPShapeTool::OnMouseMove(CPlayBoardView& pView, UINT nFlags, CPoint point) { - if (CWnd::GetCapture() == pView) + if (CWnd::GetCapture() == &pView) s_plySelectTool.OnMouseMove(pView, nFlags, point); } -void CPShapeTool::OnTimer(CPlayBoardView* pView, uintptr_t nIDEvent) +void CPShapeTool::OnTimer(CPlayBoardView& pView, uintptr_t nIDEvent) { s_plySelectTool.OnTimer(pView, nIDEvent); } -BOOL CPShapeTool::OnSetCursor(CPlayBoardView* pView, UINT nHitTest) +BOOL CPShapeTool::OnSetCursor(const CPlayBoardView& pView, UINT nHitTest) const { if (nHitTest != HTCLIENT) return FALSE; @@ -694,33 +693,34 @@ BOOL CPShapeTool::OnSetCursor(CPlayBoardView* pView, UINT nHitTest) //////////////////////////////////////////////////////////////////////// // CPLineTool - tool used to create lines -CDrawObj* CPLineTool::CreateDrawObj(CPlayBoardView* pView, CPoint point, - int& nHandle) +OwnerPtr CPLineTool::CreateDrawObj(CPlayBoardView& pView, const CPoint& point, + int& nHandle) const { - CLine* pObj = new CLine; + OwnerPtr pObj = MakeOwner(); pObj->SetLine(point.x, point.y, point.x, point.y); - pObj->SetForeColor(pView->GetLineColor()); - pObj->SetLineWidth(pView->GetLineWidth()); + pObj->SetForeColor(pView.GetLineColor()); + pObj->SetLineWidth(pView.GetLineWidth()); nHandle = hitPtB; return pObj; } -BOOL CPLineTool::IsEmptyObject() +BOOL CPLineTool::IsEmptyObject() const { - CRect rct = ((CLine*)m_pObj)->GetRect(); + wxASSERT(dynamic_cast(&*m_pObj)); + CRect rct = static_cast(*m_pObj).GetRect(); return rct.Width() < 3 && rct.Height() < 3; } //////////////////////////////////////////////////////////////////////// // CPTextBoxTool - Text box drawing object tool -void CPTextBoxTool::OnLButtonDown(CPlayBoardView* pView, UINT nFlags, +void CPTextBoxTool::OnLButtonDown(CPlayBoardView& pView, UINT nFlags, CPoint point) { // pView->DoCreateTextDrawingObject(point); } -BOOL CPTextBoxTool::OnSetCursor(CPlayBoardView* pView, UINT nHitTest) +BOOL CPTextBoxTool::OnSetCursor(const CPlayBoardView& pView, UINT nHitTest) const { if (nHitTest != HTCLIENT) return FALSE; @@ -731,15 +731,15 @@ BOOL CPTextBoxTool::OnSetCursor(CPlayBoardView* pView, UINT nHitTest) //////////////////////////////////////////////////////////////////////// // CPPlotTool - move plot tool -void CPPlotTool::OnLButtonDown(CPlayBoardView* pView, UINT nFlags, +void CPPlotTool::OnLButtonDown(CPlayBoardView& pView, UINT nFlags, CPoint point) { - CGamDoc& pDoc = pView->GetDocument(); - CPlayBoard& pPBrd = pView->GetPlayBoard(); + CGamDoc& pDoc = pView.GetDocument(); + CPlayBoard& pPBrd = pView.GetPlayBoard(); ASSERT(pPBrd.GetPlotMoveMode()); if (pPBrd.m_bSnapMovePlot) - point = pView->AdjustPoint(point); // Keep on the grid (if enabled) + point = pView.AdjustPoint(point); // Keep on the grid (if enabled) CPoint pntPrev = pPBrd.GetPrevPlotPoint(); @@ -747,7 +747,7 @@ void CPPlotTool::OnLButtonDown(CPlayBoardView* pView, UINT nFlags, { // Draw a line for each piece to the opening location std::vector> listObjs; - pView->GetSelectList().LoadTableWithObjectPtrs(listObjs, CSelList::otAll, FALSE); + pView.GetSelectList().LoadTableWithObjectPtrs(listObjs, CSelList::otAll, FALSE); for (auto pos = listObjs.begin() ; pos != listObjs.end() ; ++pos) { CDrawObj& pObj = **pos; @@ -763,7 +763,7 @@ void CPPlotTool::OnLButtonDown(CPlayBoardView* pView, UINT nFlags, pPBrd.SetPrevPlotPoint(point); } -BOOL CPPlotTool::OnSetCursor(CPlayBoardView* pView, UINT nHitTest) +BOOL CPPlotTool::OnSetCursor(const CPlayBoardView& pView, UINT nHitTest) const { if (nHitTest != HTCLIENT) return FALSE; diff --git a/GP/ToolPlay.h b/GP/ToolPlay.h index 54e25497..8ddfed84 100644 --- a/GP/ToolPlay.h +++ b/GP/ToolPlay.h @@ -1,6 +1,6 @@ // ToolPlay.h // -// Copyright (c) 1994-2020 By Dale L. Larson, All Rights Reserved. +// Copyright (c) 1994-2025 By Dale L. Larson & William Su, All Rights Reserved. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the @@ -55,12 +55,12 @@ class CPlayTool public: static CPlayTool& GetTool(PToolType eType); // ----------- // - virtual void OnLButtonDown(CPlayBoardView* pView, UINT nFlags, CPoint point); - virtual void OnLButtonDblClk(CPlayBoardView* pView, UINT nFlags, CPoint point) {} - virtual bool OnLButtonUp(CPlayBoardView* pView, UINT nFlags, CPoint point) /* override */; - virtual void OnMouseMove(CPlayBoardView* pView, UINT nFlags, CPoint point); - virtual void OnTimer(CPlayBoardView* pView, uintptr_t nIDEvent) /*override*/ {} - virtual BOOL OnSetCursor(CPlayBoardView* pView, UINT nHitTest) + virtual void OnLButtonDown(CPlayBoardView& pView, UINT nFlags, CPoint point) /* override */; + virtual void OnLButtonDblClk(CPlayBoardView& /*pView*/, UINT /*nFlags*/, CPoint /*point*/) /* override */ {} + virtual bool OnLButtonUp(CPlayBoardView& pView, UINT nFlags, CPoint point) /* override */; + virtual void OnMouseMove(CPlayBoardView& pView, UINT nFlags, CPoint point) /* override */; + virtual void OnTimer(CPlayBoardView& /*pView*/, uintptr_t /*nIDEvent*/) /*override*/ {} + virtual BOOL OnSetCursor(const CPlayBoardView& /*pView*/, UINT /*nHitTest*/) const /*override*/ { return FALSE; } // Implementation @@ -95,34 +95,34 @@ class CPSelectTool : public CPlayTool // Operations public: - virtual void OnLButtonDown(CPlayBoardView* pView, UINT nFlags, CPoint point); - virtual void OnLButtonDblClk(CPlayBoardView* pView, UINT nFlags, CPoint point); - virtual bool OnLButtonUp(CPlayBoardView* pView, UINT nFlags, CPoint point) override; - virtual void OnMouseMove(CPlayBoardView* pView, UINT nFlags, CPoint point); - virtual void OnTimer(CPlayBoardView* pView, uintptr_t nIDEvent) override; - virtual BOOL OnSetCursor(CPlayBoardView* pView, UINT nHitTest); + void OnLButtonDown(CPlayBoardView& pView, UINT nFlags, CPoint point) override; + void OnLButtonDblClk(CPlayBoardView& pView, UINT nFlags, CPoint point) override; + bool OnLButtonUp(CPlayBoardView& pView, UINT nFlags, CPoint point) override; + void OnMouseMove(CPlayBoardView& pView, UINT nFlags, CPoint point) override; + void OnTimer(CPlayBoardView& pView, uintptr_t nIDEvent) override; + BOOL OnSetCursor(const CPlayBoardView& pView, UINT nHitTest) const override; // Implementation public: uintptr_t m_nTimerID; CRect m_rectMultiBorder; // ------- // - BOOL ProcessAutoScroll(CPlayBoardView* pView); - void DrawSelectionRect(CDC* pDC, CRect* pRct); - void DrawNetRect(CDC* pDC, CPlayBoardView* pView); - BOOL AdjustPoint(CPlayBoardView* pView, CPoint& point); - void MoveSelections(CSelList *pSLst, CPoint point); - void StartDragTimer(CPlayBoardView* pView); - void KillDragTimer(CPlayBoardView* pView); - void StartScrollTimer(CPlayBoardView* pView); - void KillScrollTimer(CPlayBoardView* pView); + BOOL ProcessAutoScroll(CPlayBoardView& pView); + void DrawSelectionRect(CDC& pDC, const CRect& pRct) const; + void DrawNetRect(CDC& pDC, const CPlayBoardView& pView) const; + [[nodiscard]] CPoint AdjustPoint(const CPlayBoardView& pView, CPoint point) const; + void MoveSelections(CSelList &pSLst, const CPoint& point); + void StartDragTimer(CPlayBoardView& pView); + void KillDragTimer(CPlayBoardView& pView); + void StartScrollTimer(CPlayBoardView& pView); + void KillScrollTimer(CPlayBoardView& pView); // ------- // - void DoDragDropStart(CPlayBoardView* pView); - void DoDragDrop(CPlayBoardView* pView, CPoint pntClient); - bool DoDragDropEnd(CPlayBoardView* pView, CPoint pntClient); + void DoDragDropStart(CPlayBoardView& pView); + void DoDragDrop(CPlayBoardView& pView, const CPoint& pntClient); + bool DoDragDropEnd(CPlayBoardView& pView, const CPoint& pntClient); // ------- // - void StartSizingOperation(CPlayBoardView* pView, UINT nFlags, - CPoint point, int nHandleID = -1); + void StartSizingOperation(CPlayBoardView& pView, UINT nFlags, + const CPoint& point, int nHandleID = -1); }; //////////////////////////////////////////////////////////////////////// @@ -136,20 +136,20 @@ class CPShapeTool : public CPlayTool // Operations public: - virtual void OnLButtonDown(CPlayBoardView* pView, UINT nFlags, CPoint point); - virtual void OnLButtonDblClk(CPlayBoardView* pView, UINT nFlags, CPoint point) {} - virtual bool OnLButtonUp(CPlayBoardView* pView, UINT nFlags, CPoint point) override; - virtual void OnMouseMove(CPlayBoardView* pView, UINT nFlags, CPoint point); - virtual void OnTimer(CPlayBoardView* pView, uintptr_t nIDEvent) override; - virtual BOOL OnSetCursor(CPlayBoardView* pView, UINT nHitTest); + void OnLButtonDown(CPlayBoardView& pView, UINT nFlags, CPoint point) override; + void OnLButtonDblClk(CPlayBoardView& /*pView*/, UINT /*nFlags*/, CPoint /*point*/) override {} + bool OnLButtonUp(CPlayBoardView& pView, UINT nFlags, CPoint point) override; + void OnMouseMove(CPlayBoardView& pView, UINT nFlags, CPoint point) override; + void OnTimer(CPlayBoardView& pView, uintptr_t nIDEvent) override; + BOOL OnSetCursor(const CPlayBoardView& pView, UINT nHitTest) const override; // Implementation public: - virtual CDrawObj* CreateDrawObj(CPlayBoardView* pView, CPoint point, - int& nHandle) = 0; - virtual BOOL IsEmptyObject() = 0; + virtual OwnerPtr CreateDrawObj(CPlayBoardView& pView, const CPoint& point, + int& nHandle) const = 0; + virtual BOOL IsEmptyObject() const = 0; // --------- // - CDrawObj* m_pObj; + OwnerOrNullPtr m_pObj; }; //////////////////////////////////////////////////////////////////////// @@ -163,9 +163,9 @@ class CPLineTool : public CPShapeTool // Implementation public: - virtual CDrawObj* CreateDrawObj(CPlayBoardView* pView, CPoint point, - int& nHandle); - virtual BOOL IsEmptyObject(); + OwnerPtr CreateDrawObj(CPlayBoardView& pView, const CPoint& point, + int& nHandle) const override; + BOOL IsEmptyObject() const override; }; //////////////////////////////////////////////////////////////////////// @@ -179,12 +179,12 @@ class CPTextBoxTool : public CPlayTool // Operations public: - virtual void OnLButtonDown(CPlayBoardView* pView, UINT nFlags, CPoint point); - virtual void OnLButtonDblClk(CPlayBoardView* pView, UINT nFlags, CPoint point) {} - virtual bool OnLButtonUp(CPlayBoardView* pView, UINT nFlags, CPoint point) override { return true; } - virtual void OnMouseMove(CPlayBoardView* pView, UINT nFlags, CPoint point) {} - virtual void OnTimer(CPlayBoardView* pView, uintptr_t nIDEvent) override {} - virtual BOOL OnSetCursor(CPlayBoardView* pView, UINT nHitTest); + void OnLButtonDown(CPlayBoardView& pView, UINT nFlags, CPoint point) override; + void OnLButtonDblClk(CPlayBoardView& /*pView*/, UINT /*nFlags*/, CPoint /*point*/) override {} + bool OnLButtonUp(CPlayBoardView& /*pView*/, UINT /*nFlags*/, CPoint /*point*/) override { return true; } + void OnMouseMove(CPlayBoardView& /*pView*/, UINT /*nFlags*/, CPoint /*point*/) override {} + void OnTimer(CPlayBoardView& /*pView*/, uintptr_t /*nIDEvent*/) override {} + BOOL OnSetCursor(const CPlayBoardView& pView, UINT nHitTest) const override; // Implementation public: @@ -202,12 +202,12 @@ class CPPlotTool : public CPlayTool // Operations public: - virtual void OnLButtonDown(CPlayBoardView* pView, UINT nFlags, CPoint point); - virtual void OnLButtonDblClk(CPlayBoardView* pView, UINT nFlags, CPoint point) {} - virtual bool OnLButtonUp(CPlayBoardView* pView, UINT nFlags, CPoint point) override { return true; } - virtual void OnMouseMove(CPlayBoardView* pView, UINT nFlags, CPoint point) {} - virtual void OnTimer(CPlayBoardView* pView, uintptr_t nIDEvent) override {} - virtual BOOL OnSetCursor(CPlayBoardView* pView, UINT nHitTest); + void OnLButtonDown(CPlayBoardView& pView, UINT nFlags, CPoint point) override; + void OnLButtonDblClk(CPlayBoardView& /*pView*/, UINT /*nFlags*/, CPoint /*point*/) override {} + bool OnLButtonUp(CPlayBoardView& /*pView*/, UINT /*nFlags*/, CPoint /*point*/) override { return true; } + void OnMouseMove(CPlayBoardView& /*pView*/, UINT /*nFlags*/, CPoint /*point*/) override {} + void OnTimer(CPlayBoardView& /*pView*/, uintptr_t /*nIDEvent*/) override {} + BOOL OnSetCursor(const CPlayBoardView& pView, UINT nHitTest) const override; // Implementation public: diff --git a/GP/VwPbrd.cpp b/GP/VwPbrd.cpp index 58a0621d..d8ef3caf 100644 --- a/GP/VwPbrd.cpp +++ b/GP/VwPbrd.cpp @@ -1065,7 +1065,7 @@ void CPlayBoardView::OnLButtonDown(UINT nFlags, CPoint point) CPlayTool& pTool = CPlayTool::GetTool(eToolType); // Allow pieces to be selected even during playback point = ClientToWorkspace(point); - pTool.OnLButtonDown(this, nFlags, point); + pTool.OnLButtonDown(*this, nFlags, point); } void CPlayBoardView::OnMouseMove(UINT nFlags, CPoint point) @@ -1083,7 +1083,7 @@ void CPlayBoardView::OnMouseMove(UINT nFlags, CPoint point) PToolType eToolType = MapToolType(m_nCurToolID); CPlayTool& pTool = CPlayTool::GetTool(eToolType); point = ClientToWorkspace(point); - pTool.OnMouseMove(this, nFlags, point); + pTool.OnMouseMove(*this, nFlags, point); } else CScrollView::OnMouseMove(nFlags, point); @@ -1101,7 +1101,7 @@ void CPlayBoardView::OnLButtonUp(UINT nFlags, CPoint point) CPlayTool& pTool = CPlayTool::GetTool(eToolType); // Allow pieces to be selected even during playback point = ClientToWorkspace(point); - bool rc = pTool.OnLButtonUp(this, nFlags, point); + bool rc = pTool.OnLButtonUp(*this, nFlags, point); ASSERT(rc || pTool.m_eToolType == ptypeSelect); if (!rc && pTool.m_eToolType == ptypeSelect) { @@ -1126,7 +1126,7 @@ void CPlayBoardView::OnLButtonDblClk(UINT nFlags, CPoint point) PToolType eToolType = MapToolType(m_nCurToolID); CPlayTool& pTool = CPlayTool::GetTool(eToolType); point = ClientToWorkspace(point); - pTool.OnLButtonDblClk(this, nFlags, point); + pTool.OnLButtonDblClk(*this, nFlags, point); } else CScrollView::OnLButtonDblClk(nFlags, point); @@ -1153,7 +1153,7 @@ void CPlayBoardView::OnTimer(uintptr_t nIDEvent) { PToolType eToolType = MapToolType(m_nCurToolID); CPlayTool& pTool = CPlayTool::GetTool(eToolType); - pTool.OnTimer(this, nIDEvent); + pTool.OnTimer(*this, nIDEvent); } else CScrollView::OnTimer(nIDEvent); @@ -1169,7 +1169,7 @@ BOOL CPlayBoardView::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) if (pWnd == this && eToolType != ptypeUnknown) { CPlayTool& pTool = CPlayTool::GetTool(eToolType); - if (pTool.OnSetCursor(this, nHitTest)) + if (pTool.OnSetCursor(*this, nHitTest)) return TRUE; } if (GetDocument().IsRecordingCompoundMove()) From 943647a399fcfde5689225a7ede7b911617bf218 Mon Sep 17 00:00:00 2001 From: Bill Su Date: Mon, 6 Oct 2025 23:09:40 -0400 Subject: [PATCH 42/80] VwPbrd: start converting from MFC to wx --- GP/FrmPbrd.cpp | 31 +++- GP/GamDoc.cpp | 13 +- GP/GamDoc.h | 20 ++- GP/GamDoc4.cpp | 11 +- GP/GamDoc5.cpp | 11 +- GP/SelOPlay.cpp | 84 ++++++---- GP/SelOPlay.h | 20 +-- GP/ToolPlay.cpp | 116 +++++++++---- GP/VwPbrd.cpp | 420 +++++++++++++++++++++++++++++------------------- GP/VwPbrd.h | 181 +++++++++++++-------- GP/VwPbrd1.cpp | 208 +++++++++++++----------- GP/VwPrjga1.cpp | 3 +- GP/VwPrjgs1.cpp | 3 +- GP/WStateGp.cpp | 3 +- GShr/LibMfc.cpp | 10 ++ 15 files changed, 703 insertions(+), 431 deletions(-) diff --git a/GP/FrmPbrd.cpp b/GP/FrmPbrd.cpp index 5d22e464..fa620d83 100644 --- a/GP/FrmPbrd.cpp +++ b/GP/FrmPbrd.cpp @@ -1,6 +1,6 @@ // FrmPbrd.cpp : implementation file // -// Copyright (c) 1994-2023 By Dale L. Larson & William Su, All Rights Reserved. +// Copyright (c) 1994-2025 By Dale L. Larson & William Su, All Rights Reserved. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the @@ -48,11 +48,14 @@ IMPLEMENT_DYNCREATE(CPlayBoardFrame, CMDIChildWndEx) BEGIN_MESSAGE_MAP(CPlayBoardFrame, CMDIChildWndEx) //{{AFX_MSG_MAP(CPlayBoardFrame) +#if 0 ON_COMMAND(ID_VIEW_HALFSCALEBRD, OnViewHalfScaleBrd) ON_UPDATE_COMMAND_UI(ID_VIEW_HALFSCALEBRD, OnUpdateViewHalfScaleBrd) ON_COMMAND(ID_VIEW_FULLSCALEBRD, OnViewFullScaleBrd) ON_UPDATE_COMMAND_UI(ID_VIEW_FULLSCALEBRD, OnUpdateViewFullScaleBrd) +#endif ON_WM_CLOSE() +#if 0 ON_COMMAND(ID_VIEW_SNAPGRID, OnViewSnapGrid) ON_UPDATE_COMMAND_UI(ID_VIEW_SNAPGRID, OnUpdateViewSnapGrid) ON_COMMAND(ID_EDIT_SELALLMARKERS, OnEditSelAllMarkers) @@ -80,13 +83,16 @@ BEGIN_MESSAGE_MAP(CPlayBoardFrame, CMDIChildWndEx) ON_UPDATE_COMMAND_UI(ID_ACT_PLOTDONE, OnUpdateActPlotDone) ON_COMMAND(ID_ACT_PLOTDISCARD, OnActPlotDiscard) ON_UPDATE_COMMAND_UI(ID_ACT_PLOTDISCARD, OnUpdateActPlotDiscard) +#endif ON_COMMAND(ID_VIEW_SPLITBOARDROWS, OnViewSplitBoardRows) ON_UPDATE_COMMAND_UI(ID_VIEW_SPLITBOARDROWS, OnUpdateViewSplitBoardRows) ON_COMMAND(ID_VIEW_SPLITBOARDCOLS, OnViewSplitBoardCols) ON_UPDATE_COMMAND_UI(ID_VIEW_SPLITBOARDCOLS, OnUpdateViewSplitBoardCols) //}}AFX_MSG_MAP +#if 0 ON_COMMAND_RANGE(ID_MRKGROUP_FIRST, ID_MRKGROUP_FIRST + 64, OnSelectGroupMarkers) ON_UPDATE_COMMAND_UI_RANGE(ID_MRKGROUP_FIRST, ID_MRKGROUP_FIRST + 64, OnUpdateSelectGroupMarkers) +#endif // Other messages ON_MESSAGE(WM_CENTERBOARDONPOINT, OnMessageCenterBoardOnPoint) ON_MESSAGE(WM_WINSTATE, OnMessageWindowState) @@ -413,8 +419,13 @@ LRESULT CPlayBoardFrame::OnMessageWindowState(WPARAM wParam, LPARAM lParam) LRESULT CPlayBoardFrame::SendMessageToActiveBoardPane(UINT nMsg, WPARAM wParam, LPARAM lParam) { - CWnd& pWnd = GetActiveBoardView(); - return pWnd.SendMessage(nMsg, wParam, lParam); + CPlayBoardView& pWnd = GetActiveBoardView(); + wxASSERT(nMsg == WM_SELECT_BOARD_OBJLIST); + const CPlayBoard* board = reinterpret_cast(wParam); + const std::vector>* objList = reinterpret_cast>*>(lParam); + SelectBoardObjListEvent event(CheckedDeref(board), CheckedDeref(objList)); + pWnd.ProcessWindowEvent(event); + return 1; } ///////////////////////////////////////////////////////////////////////////// @@ -424,7 +435,10 @@ LRESULT CPlayBoardFrame::OnMessageCenterBoardOnPoint(WPARAM wParam, LPARAM lPara { // Route the message to the active board view. CPlayBoardView& pView = GetActiveBoardView(); - return pView.SendMessage(WM_CENTERBOARDONPOINT, wParam, lParam); + const POINT* point = reinterpret_cast(wParam); + CenterBoardOnPointEvent event(CB::Convert(CheckedDeref(point))); + pView.ProcessWindowEvent(event); + return 0; } // Send these on to the main view so they can be process no @@ -445,16 +459,18 @@ const CPlayBoardView& CPlayBoardFrame::GetActiveBoardView() const CCbSplitterWnd& pSplitWnd = CheckedDeref((CCbSplitterWnd*)m_wndSplitter1.GetPane(0, 0)); const CWnd* view = GetActiveView(); if (view && - view->IsKindOf(RUNTIME_CLASS(CPlayBoardView)) && - view->GetParent()->GetParent() == &pSplitWnd) + view->IsKindOf(RUNTIME_CLASS(CPlayBoardViewContainer)) && + view->GetParent() == &pSplitWnd) { - return static_cast(*view); + return static_cast(*view); } + wxASSERT(!"dead code?"); const CWnd& wnd = CheckedDeref(pSplitWnd.GetActivePane()); const CPlayBoardViewContainer& container = dynamic_cast(wnd); return static_cast(container); } +#if 0 void CPlayBoardFrame::OnViewHalfScaleBrd() { GetActiveBoardView().OnViewHalfScaleBrd(); @@ -599,6 +615,7 @@ void CPlayBoardFrame::OnUpdateActPlotDiscard(CCmdUI* pCmdUI) { GetActiveBoardView().OnUpdateActPlotDiscard(pCmdUI); } +#endif void CPlayBoardFrame::OnViewSplitBoardRows() { diff --git a/GP/GamDoc.cpp b/GP/GamDoc.cpp index 8e39b292..9eadfdbf 100644 --- a/GP/GamDoc.cpp +++ b/GP/GamDoc.cpp @@ -535,7 +535,7 @@ CGamProjView& CGamDoc::FindProjectView() const AfxThrowNotSupportedException(); } -CView* CGamDoc::FindPBoardView(const CPlayBoard& pPBoard) const +CPlayBoardView* CGamDoc::FindPBoardView(const CPlayBoard& pPBoard) const { if (!IsScenario() && pPBoard.IsPrivate() && @@ -548,11 +548,12 @@ CView* CGamDoc::FindPBoardView(const CPlayBoard& pPBoard) const POSITION pos = GetFirstViewPosition(); while (pos != NULL) { - CPlayBoardView* pView = (CPlayBoardView*)GetNextView(pos); - if (pView->IsKindOf(RUNTIME_CLASS(CPlayBoardView))) + CPlayBoardViewContainer* pCont = static_cast(GetNextView(pos)); + if (pCont->IsKindOf(RUNTIME_CLASS(CPlayBoardViewContainer))) { - if (&pView->GetPlayBoard() == &pPBoard) - return pView; + CPlayBoardView& pView = *pCont; + if (&pView.GetPlayBoard() == &pPBoard) + return &pView; } } return NULL; @@ -1631,7 +1632,7 @@ void CGamDoc::OnEditSelectBoards() pPBMgr.FindPBoardsNotInList(dlg.m_tblBrds, tblNotInList); for (size_t i = size_t(0); i < tblNotInList.size(); i++) { - CView* pView = FindPBoardView(*tblNotInList.at(i)); + CPlayBoardView* pView = FindPBoardView(*tblNotInList.at(i)); if (pView != NULL) { CFrameWnd* pFrame = pView->GetParentFrame(); diff --git a/GP/GamDoc.h b/GP/GamDoc.h index 35298db0..8b015ead 100644 --- a/GP/GamDoc.h +++ b/GP/GamDoc.h @@ -127,6 +127,13 @@ class CGamDocHint : public CObject DECLARE_DYNCREATE(CGamDocHint); public: CGamDocHint() : hint(HINT_INVALID) {} + ~CGamDocHint() + { + if (hint == HINT_POINTINVIEW) + { + args.m_pointInView.~Args(); + } + } template struct Args @@ -177,7 +184,7 @@ class CGamDocHint : public CObject struct Args { CPlayBoard* m_pPBoard; - POINT m_point; + wxPoint m_point; }; template<> @@ -200,6 +207,10 @@ class CGamDocHint : public CObject if (hint == HINT_INVALID) { hint = HINT; + if (hint == HINT_POINTINVIEW) + { + new (&args.m_pointInView) Args; + } } else if (HINT != hint) { @@ -210,7 +221,7 @@ class CGamDocHint : public CObject private: EGamDocHint hint; - union { + union U { Args m_trayChange; Args m_updateObject; Args m_updateObjList; @@ -220,6 +231,7 @@ class CGamDocHint : public CObject Args m_pointInView; Args m_selectObj; Args m_selectObjList; + U() {} } args; }; @@ -351,8 +363,8 @@ class CGamDoc : public CDocument BOOL CreateNewFrame(CDocTemplate* pTemplate, const CB::string& pszTitle, LPVOID lpvCreateParam); CGamProjView& FindProjectView() const; - CView* FindPBoardView(const CPlayBoard& pPBoard) const; - CView* MakeSurePBoardVisible(CPlayBoard& pPBoard); + CPlayBoardView* FindPBoardView(const CPlayBoard& pPBoard) const; + CPlayBoardView* MakeSurePBoardVisible(CPlayBoard& pPBoard); void GetDocumentFrameList(std::vector>& tblFrames) const; BOOL IsWindowStateAvailable() const { return m_pWinState != NULL; } diff --git a/GP/GamDoc4.cpp b/GP/GamDoc4.cpp index 5e7d6c8d..65c1d0d8 100644 --- a/GP/GamDoc4.cpp +++ b/GP/GamDoc4.cpp @@ -468,7 +468,7 @@ void CGamDoc::EnsureBoardLocationVisible(CPlayBoard& pPBoard, CPoint point) // near the center of the view. CGamDocHint hint; hint.GetArgs().m_pPBoard = &pPBoard; - hint.GetArgs().m_point = point; + hint.GetArgs().m_point = CB::Convert(point); UpdateAllViews(NULL, HINT_POINTINVIEW, &hint); } @@ -561,7 +561,7 @@ void CGamDoc::SelectMarkerPaletteItem(MarkID mid) ///////////////////////////////////////////////////////////////////////////// -CView* CGamDoc::MakeSurePBoardVisible(CPlayBoard& pPBoard) +CPlayBoardView* CGamDoc::MakeSurePBoardVisible(CPlayBoard& pPBoard) { if (IsQuietPlayback()) return NULL; if (pPBoard.IsPrivate() && @@ -577,7 +577,7 @@ CView* CGamDoc::MakeSurePBoardVisible(CPlayBoard& pPBoard) return nullptr; } - CView* pView = FindPBoardView(pPBoard); + CPlayBoardView* pView = FindPBoardView(pPBoard); if (pView != NULL) { // This board already has a view. Activate that view. @@ -664,10 +664,11 @@ void CGamDoc::IndicateTextTipOnBoard(const CPlayBoard& pPBoard, // Shows a balloon tip so person knows what happened. void CGamDoc::IndicateTextTipOnBoard(const CPlayBoard& pPBoard, - CPoint pointWorkspace, const CB::string& pszStr) + CPoint pointWorkspaceMfc, const CB::string& pszStr) { + wxPoint pointWorkspace = CB::Convert(pointWorkspaceMfc); if (IsQuietPlayback()) return; - CPlayBoardView* pView = (CPlayBoardView*)FindPBoardView(pPBoard); + CPlayBoardView* pView = FindPBoardView(pPBoard); ASSERT(pView != NULL); pointWorkspace = pView->WorkspaceToClient(pointWorkspace); pView->SetNotificationTip(pointWorkspace, &pszStr); diff --git a/GP/GamDoc5.cpp b/GP/GamDoc5.cpp index ea46f6cd..b3754501 100644 --- a/GP/GamDoc5.cpp +++ b/GP/GamDoc5.cpp @@ -321,18 +321,17 @@ void CGamDoc::EventShowBoardNotification(BoardID nBrdSerNum, CPoint pntTipLoc, c if (pntTipLoc.x == -1 || pntTipLoc.y == -1) { EnsureBoardVisible(*pPBoard); - pView = (CPlayBoardView*)FindPBoardView(*pPBoard); - CRect rct; - pView->GetClientRect(rct); + pView = FindPBoardView(*pPBoard); + CRect rct = CB::Convert(pView->GetClientRect()); pntTipLoc = rct.CenterPoint(); } else { EnsureBoardLocationVisible(*pPBoard, pntTipLoc); - pView = (CPlayBoardView*)FindPBoardView(*pPBoard); - pntTipLoc = pView->WorkspaceToClient(pntTipLoc); + pView = FindPBoardView(*pPBoard); + pntTipLoc = CB::Convert(pView->WorkspaceToClient(CB::Convert(pntTipLoc))); } - pView->SetNotificationTip(pntTipLoc, &strMsg); + pView->SetNotificationTip(CB::Convert(pntTipLoc), &strMsg); } //////////////////////////////////////////////////////////////////////////// diff --git a/GP/SelOPlay.cpp b/GP/SelOPlay.cpp index 8a560ca3..159e9e3e 100644 --- a/GP/SelOPlay.cpp +++ b/GP/SelOPlay.cpp @@ -83,7 +83,7 @@ void CHandleList::AddHandle(POINT pntNew) ///////////////////////////////////////////////////////////////////// -void CSelection::DrawTracker(CDC& pDC, TrackMode eMode) const +void CSelection::DrawTracker(wxDC& pDC, TrackMode eMode) const { if (eMode == trkSelected) DrawHandles(pDC); @@ -91,13 +91,16 @@ void CSelection::DrawTracker(CDC& pDC, TrackMode eMode) const DrawTrackingImage(pDC, eMode); } -void CSelection::DrawHandles(CDC& pDC) const +void CSelection::DrawHandles(wxDC& pDC) const { int n = GetHandleCount(); + CB::DCLogicalFunctionChanger setLogFunc(pDC, wxXOR); + wxDCPenChanger setPen(pDC, *wxWHITE_PEN); + wxDCBrushChanger setBrush(pDC, *wxWHITE_BRUSH); for (int i = 0; i < n; i++) { - CRect rect = GetHandleRect(i); - pDC.PatBlt(rect.left, rect.top, rect.Width(), rect.Height(), DSTINVERT); + wxRect rect = CB::Convert(GetHandleRect(i)); + pDC.DrawRectangle(rect); } } @@ -118,7 +121,7 @@ void CSelection::InvalidateHandles() for (int i = 0; i < n; i++) { CRect rct = GetHandleRect(i); - m_pView->InvalidateWorkspaceRect(&rct, FALSE); + m_pView->InvalidateWorkspaceRect(CB::Convert(rct), FALSE); } } @@ -126,24 +129,24 @@ void CSelection::InvalidateHandles() CRect CSelection::GetHandleRect(int nHandleID) const { // Get the center of the handle in logical coords - CPoint point = GetHandleLoc(nHandleID); + wxPoint point = CB::Convert(GetHandleLoc(nHandleID)); // Convert point to client coords point = m_pView->WorkspaceToClient(point); // Calc CRect of handle in device coords - CRect rect(point.x-3, point.y-3, point.x+3, point.y+3); + wxRect rect(wxPoint(point.x-3, point.y-3), wxSize(6, 6)); rect = m_pView->ClientToWorkspace(rect); - return rect; + return CB::Convert(rect); } void CSelection::Invalidate() { CRect rct = m_rect; rct = m_pObj->GetEnclosingRect(); - m_pView->InvalidateWorkspaceRect(&rct, FALSE); + m_pView->InvalidateWorkspaceRect(CB::Convert(rct), FALSE); } void CSelection::Open() @@ -151,26 +154,29 @@ void CSelection::Open() if (m_pObj->GetType() == CDrawObj::drawMarkObj || m_pObj->GetType() == CDrawObj::drawPieceObj) { - m_pView->SendMessage(WM_COMMAND, MAKEWPARAM(uint16_t(ID_EDIT_ELEMENT_TEXT), uint16_t(0))); + wxCommandEvent event(wxEVT_MENU, XRCID("ID_EDIT_ELEMENT_TEXT")); + m_pView->ProcessWindowEvent(event); } } +#if 0 //=---------------------------------------------------=// // Static methods... -void CSelection::SetupTrackingDraw(CDC& pDC) +void CSelection::SetupTrackingDraw(wxDC& pDC) { c_nPrvROP2 = pDC.SetROP2(R2_XORPEN); c_pPrvPen = pDC.SelectObject(&c_penDot); c_pPrvBrush = (CBrush*)pDC.SelectStockObject(NULL_BRUSH); } -void CSelection::CleanUpTrackingDraw(CDC& pDC) +void CSelection::CleanUpTrackingDraw(wxDC& pDC) { pDC.SetROP2(c_nPrvROP2); pDC.SelectObject(c_pPrvPen); pDC.SelectObject(c_pPrvBrush); } +#endif ///////////////////////////////////////////////////////////////////// // Line Selection Processing @@ -181,12 +187,16 @@ void CSelLine::AddHandles(CHandleList& listHandles) listHandles.AddHandle(GetHandleLoc(hitPtB)); } -void CSelLine::DrawTrackingImage(CDC& pDC, TrackMode eMode) const +void CSelLine::DrawTrackingImage(wxDC& pDC, TrackMode eMode) const { +#if 0 SetupTrackingDraw(pDC); pDC.MoveTo(m_rect.left, m_rect.top); pDC.LineTo(m_rect.right, m_rect.bottom); CleanUpTrackingDraw(pDC); +#else + wxASSERT(!"TODO:"); +#endif } HCURSOR CSelLine::GetHandleCursor(int nHandleID) const @@ -245,15 +255,16 @@ void CSelLine::UpdateObject(BOOL bInvalidate, CLine& pObj = static_cast(*m_pObj); if (bInvalidate) { - CRect rctA = pObj.GetEnclosingRect(); - CRect rctB; - pObj.GetLine(rctB); - rctB.NormalizeRect(); + wxRect rctA = CB::Convert(pObj.GetEnclosingRect()); + CRect rctBMfc; + pObj.GetLine(rctBMfc); + rctBMfc.NormalizeRect(); + wxRect rctB = CB::Convert(rctBMfc); rctB = m_pView->WorkspaceToClient(rctB); - rctB.InflateRect(handleHalfWidth, handleHalfWidth); + rctB.Inflate(handleHalfWidth, handleHalfWidth); rctB = m_pView->ClientToWorkspace(rctB); - rctA |= rctB; // Make sure we erase the handles - m_pView->InvalidateWorkspaceRect(&rctA, FALSE); + rctA.Union(rctB); // Make sure we erase the handles + m_pView->InvalidateWorkspaceRect(rctA, FALSE); } pObj.SetLine(m_rect.left, m_rect.top, m_rect.right, m_rect.bottom); if (bUpdateObjectExtent) @@ -270,7 +281,7 @@ void CSelLine::UpdateObject(BOOL bInvalidate, if (bInvalidate) { CRect rct = pObj.GetEnclosingRect(); - m_pView->InvalidateWorkspaceRect(&rct); + m_pView->InvalidateWorkspaceRect(CB::Convert(rct)); } } @@ -285,11 +296,15 @@ void CSelGeneric::AddHandles(CHandleList& listHandles) listHandles.AddHandle(GetHandleLoc(hitBottomLeft)); } -void CSelGeneric::DrawTrackingImage(CDC& pDC, TrackMode eMode) const +void CSelGeneric::DrawTrackingImage(wxDC& pDC, TrackMode eMode) const { +#if 0 SetupTrackingDraw(pDC); - pDC.Rectangle(m_rect); + pDC.DrawRectangle(CB::Convert(m_rect)); CleanUpTrackingDraw(pDC); +#else + wxASSERT(!"TODO:"); +#endif } // Returns handle location in logical coords. @@ -314,11 +329,11 @@ void CSelGeneric::UpdateObject(BOOL bInvalidate, { if (bInvalidate) { - CRect rct = m_pObj->GetRect(); + wxRect rct = CB::Convert(m_pObj->GetRect()); rct = m_pView->WorkspaceToClient(rct); - rct.InflateRect(handleHalfWidth, handleHalfWidth); + rct.Inflate(handleHalfWidth, handleHalfWidth); rct = m_pView->ClientToWorkspace(rct); - m_pView->InvalidateWorkspaceRect(&rct); + m_pView->InvalidateWorkspaceRect(rct); } if (bUpdateObjectExtent) { @@ -335,7 +350,7 @@ void CSelGeneric::UpdateObject(BOOL bInvalidate, if (bInvalidate) { CRect rct = m_pObj->GetEnclosingRect(); - m_pView->InvalidateWorkspaceRect(&rct); + m_pView->InvalidateWorkspaceRect(CB::Convert(rct)); } } @@ -475,13 +490,13 @@ void CSelList::Offset(CPoint ptDelta) // Called by view OnDraw(). This entry makes it possible // to turn off handles during a drag operation. -void CSelList::OnDraw(CDC& pDC) +void CSelList::OnDraw(wxDC& pDC) { if (m_eTrkMode == trkSelected) DrawTracker(pDC); } -void CSelList::DrawTracker(CDC& pDC, TrackMode eTrkMode) +void CSelList::DrawTracker(wxDC& pDC, TrackMode eTrkMode) { if (eTrkMode != trkCurrent) m_eTrkMode = eTrkMode; @@ -491,11 +506,16 @@ void CSelList::DrawTracker(CDC& pDC, TrackMode eTrkMode) // Drawing selection handles. Draw them using the // handle list so when an even number of identical // points don't XOR themselves out of existance. + CB::DCLogicalFunctionChanger setLogFunc(pDC, wxXOR); + wxDCPenChanger setPen(pDC, *wxWHITE_PEN); + wxDCBrushChanger setBrush(pDC, *wxWHITE_BRUSH); POSITION pos = m_listHandles.GetHeadPosition(); while (pos != NULL) { POINT pnt = m_listHandles.GetNext(pos); - pDC.PatBlt(pnt.x-3, pnt.y-3, 6, 6, DSTINVERT); + wxRect rect(wxPoint(pnt.x - 3, pnt.y - 3), + wxSize(6, 6)); + pDC.DrawRectangle(rect); } } else @@ -520,7 +540,7 @@ void CSelList::InvalidateListHandles(BOOL bUpdate) bFoundOne = TRUE; } if (bFoundOne && bUpdate) - m_pView->UpdateWindow(); + m_pView->Update(); } void CSelList::InvalidateList(BOOL bUpdate) @@ -534,7 +554,7 @@ void CSelList::InvalidateList(BOOL bUpdate) bFoundOne = TRUE; } if (bFoundOne && bUpdate) - m_pView->UpdateWindow(); + m_pView->Update(); } void CSelList::PurgeList(BOOL bInvalidate) diff --git a/GP/SelOPlay.h b/GP/SelOPlay.h index 33c6f4be..4c9ce56a 100644 --- a/GP/SelOPlay.h +++ b/GP/SelOPlay.h @@ -1,7 +1,7 @@ // SelOPlay.h -- contains class definitions for selection proxies. Used // in concert with the selection tool. // -// Copyright (c) 1994-2020 By Dale L. Larson, All Rights Reserved. +// Copyright (c) 1994-2025 By Dale L. Larson & William Su, All Rights Reserved. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the @@ -95,7 +95,7 @@ class CSelection virtual void MoveHandle(int m_nHandle, CPoint point) /* override */ {} virtual void Offset(CPoint ptDelta) /* override */ { m_rect += ptDelta; } // ------- // - virtual void DrawTracker(CDC& pDC, TrackMode eMode) const /* override */; + virtual void DrawTracker(wxDC& pDC, TrackMode eMode) const /* override */; virtual void InvalidateHandles() /* override */; virtual void Invalidate() /* override */; virtual void UpdateObject(BOOL bInvalidate = TRUE, @@ -109,15 +109,15 @@ class CSelection virtual CRect GetHandleRect(int nHandleID) const /* override */; virtual CPoint GetHandleLoc(int nHandleID) const /* override */ = 0; virtual int GetHandleCount() const /* override */ = 0; - virtual void DrawHandles(CDC& pDC) const /* override */; - virtual void DrawTrackingImage(CDC& pDC, TrackMode eMode) const /* override */ = 0; + virtual void DrawHandles(wxDC& pDC) const /* override */; + virtual void DrawTrackingImage(wxDC& pDC, TrackMode eMode) const /* override */ = 0; // Implementation protected: RefPtr m_pView; // Selection's view // -- Class level support methods -- // - static void SetupTrackingDraw(CDC& pDC); - static void CleanUpTrackingDraw(CDC& pDC); + static void SetupTrackingDraw(wxDC& pDC); + static void CleanUpTrackingDraw(wxDC& pDC); // -- Class variables -- // static CPen NEAR c_penDot; static int NEAR c_nPrvROP2; @@ -146,7 +146,7 @@ class CSelLine : public CSelection protected: virtual void AddHandles(CHandleList& listHandles) override; - virtual void DrawTrackingImage(CDC& pDC, TrackMode eMode) const override; + virtual void DrawTrackingImage(wxDC& pDC, TrackMode eMode) const override; virtual CPoint GetHandleLoc(int nHandleID) const override; virtual int GetHandleCount() const override { return 2; } virtual void UpdateObject(BOOL bInvalidate = TRUE, @@ -173,7 +173,7 @@ class CSelGeneric : public CSelection protected: virtual void AddHandles(CHandleList& listHandles) override; - virtual void DrawTrackingImage(CDC& pDC, TrackMode eMode) const override; + virtual void DrawTrackingImage(wxDC& pDC, TrackMode eMode) const override; virtual CPoint GetHandleLoc(int nHandleID) const override; virtual int GetHandleCount() const override { return 4; } virtual void UpdateObject(BOOL bInvalidate = TRUE, @@ -258,8 +258,8 @@ class CSelList : private std::list> void Offset(CPoint ptDelta); void MoveHandle(int m_nHandle, CPoint point); // -------- // - void OnDraw(CDC& pDC); // Called by view OnDraw() - void DrawTracker(CDC& pDC, TrackMode eTrkMode = trkCurrent); + void OnDraw(wxDC& pDC); // Called by view OnDraw() + void DrawTracker(wxDC& pDC, TrackMode eTrkMode = trkCurrent); // -------- // void UpdateObjects(BOOL bInvalidate = TRUE, BOOL bUpdateObjectExtent = TRUE ); diff --git a/GP/ToolPlay.cpp b/GP/ToolPlay.cpp index 59d2e4d6..2756a91d 100644 --- a/GP/ToolPlay.cpp +++ b/GP/ToolPlay.cpp @@ -84,7 +84,7 @@ CPlayTool& CPlayTool::GetTool(PToolType eToolType) void CPlayTool::OnLButtonDown(CPlayBoardView& pView, UINT nFlags, CPoint point) { - pView.SetCapture(); + pView.CaptureMouse(); c_ptDown = point; c_ptLast = point; @@ -92,16 +92,16 @@ void CPlayTool::OnLButtonDown(CPlayBoardView& pView, UINT nFlags, CPoint point) void CPlayTool::OnMouseMove(CPlayBoardView& pView, UINT nFlags, CPoint point) { - if (CWnd::GetCapture() == &pView) + if (pView.HasCapture()) c_ptLast = point; SetCursor(AfxGetApp()->LoadStandardCursor(IDC_ARROW)); } bool CPlayTool::OnLButtonUp(CPlayBoardView& pView, UINT nFlags, CPoint point) { - if (CWnd::GetCapture() != &pView) + if (!pView.HasCapture()) return false; - ReleaseCapture(); + pView.ReleaseMouse(); return true; } @@ -121,7 +121,7 @@ void CPSelectTool::OnLButtonDown(CPlayBoardView& pView, UINT nFlags, StartSizingOperation(pView, nFlags, point); return; } - CDrawObj* pObj = pView.ObjectHitTest(point); + CDrawObj* pObj = pView.ObjectHitTest(CB::Convert(point)); BOOL bOwnedButNotOkToSelect = FALSE; if (pObj != NULL && pObj->GetType() == CDrawObj::drawPieceObj) @@ -145,9 +145,13 @@ void CPSelectTool::OnLButtonDown(CPlayBoardView& pView, UINT nFlags, // No objects were under the mouse click. m_eSelMode = smodeNet; // Net type selection CPlayTool::OnLButtonDown(pView, nFlags, point); +#if 0 CClientDC dc(&pView); pView.OnPrepareScaledDC(dc, TRUE); DrawNetRect(dc, pView); +#else + wxASSERT(!"TODO: overlay"); +#endif return; } // Object is under mouse. See if also selected. If not, @@ -157,7 +161,7 @@ void CPSelectTool::OnLButtonDown(CPlayBoardView& pView, UINT nFlags, if ((nFlags & MK_SHIFT) == 0) // Shift click adds to list pSLst.PurgeList(TRUE); // Clear current select list if ((nFlags & MK_CONTROL) != 0) // Control click drills down - pView.SelectAllUnderPoint(point); + pView.SelectAllUnderPoint(CB::Convert(point)); else { pSLst.AddObject(*pObj, TRUE); @@ -196,7 +200,7 @@ void CPSelectTool::OnMouseMove(CPlayBoardView& pView, UINT nFlags, CPoint point) { CSelList& pSLst = pView.GetSelectList(); - if (CWnd::GetCapture() != &pView) + if (!pView.HasCapture()) return; if (m_eSelMode != smodeNormal && m_eSelMode != smodeMove) @@ -207,8 +211,9 @@ void CPSelectTool::OnMouseMove(CPlayBoardView& pView, UINT nFlags, CPoint point) CRect rct; CPoint pt; GetCursorPos(&pt); - pView.ScreenToClient(&pt); - pView.GetClientRect(rct); + pt = CB::Convert(pView.ScreenToClient(CB::Convert(pt))); + rct = CB::Convert(pView.GetClientRect()); +#if 0 if (rct.PtInRect(pt)) // In client area { rct.InflateRect(-scrollZone, -scrollZone); @@ -224,17 +229,24 @@ void CPSelectTool::OnMouseMove(CPlayBoardView& pView, UINT nFlags, CPoint point) } else KillScrollTimer(pView); +#else + wxASSERT(!"TODO: autoscroll"); +#endif } // If we get here, the mouse has been captured. Check if // we are doing a "net select". if (m_eSelMode == smodeNet) { +#if 0 CClientDC dc(&pView); pView.OnPrepareScaledDC(dc, TRUE); DrawNetRect(dc, pView); // Erase previous position CPlayTool::OnMouseMove(pView, nFlags, point); // Update position DrawNetRect(dc, pView); // Draw new position rect +#else + wxASSERT(!"TODO: overlay"); +#endif return; } // If object(s) are being moved or sized, removed last tracking @@ -242,16 +254,17 @@ void CPSelectTool::OnMouseMove(CPlayBoardView& pView, UINT nFlags, CPoint point) // tracking image. if (m_eSelMode == smodeMove) { - point = pView.WorkspaceToClient(point); + point = CB::Convert(pView.WorkspaceToClient(CB::Convert(point))); DoDragDrop(pView, point); return; } else if (m_eSelMode == smodeSizing) { - point = pView.AdjustPoint(point); + point = CB::Convert(pView.AdjustPoint(CB::Convert(point))); if (point == c_ptLast) return; +#if 0 CClientDC dc(&pView); pView.OnPrepareScaledDC(dc, TRUE); @@ -260,6 +273,9 @@ void CPSelectTool::OnMouseMove(CPlayBoardView& pView, UINT nFlags, CPoint point) MoveSelections(pSLst, point); pSLst.DrawTracker(dc, trkSizing); // Erase previous tracker +#else +wxASSERT(!"TODO: overlay"); +#endif } c_ptLast = point; // Save new 'last' position } @@ -267,10 +283,11 @@ void CPSelectTool::OnMouseMove(CPlayBoardView& pView, UINT nFlags, CPoint point) bool CPSelectTool::OnLButtonUp(CPlayBoardView& pView, UINT nFlags, CPoint point) { bool retval = true; - if (CWnd::GetCapture() == &pView) + if (pView.HasCapture()) { if (m_eSelMode == smodeNet) { +#if 0 CClientDC dc(&pView); pView.OnPrepareScaledDC(dc, TRUE); DrawNetRect(dc, pView); // Erase previous position @@ -283,6 +300,9 @@ bool CPSelectTool::OnLButtonUp(CPlayBoardView& pView, UINT nFlags, CPoint point) pView.SelectWithinRect(rect, (nFlags & MK_CONTROL) != 0); CSelList& pSLst = pView.GetSelectList(); pSLst.InvalidateListHandles(); +#else +wxASSERT(!"TODO: overlay"); +#endif } else if (m_eSelMode != smodeNormal) { @@ -291,7 +311,7 @@ bool CPSelectTool::OnLButtonUp(CPlayBoardView& pView, UINT nFlags, CPoint point) { CPoint pnt = point; pSLst.SetTrackingMode(trkSelected); - pnt = pView.WorkspaceToClient(pnt); + pnt = CB::Convert(pView.WorkspaceToClient(CB::Convert(pnt))); retval = DoDragDropEnd(pView, pnt) && retval; } else @@ -314,7 +334,7 @@ bool CPSelectTool::OnLButtonUp(CPlayBoardView& pView, UINT nFlags, CPoint point) void CPSelectTool::OnTimer(CPlayBoardView& pView, uintptr_t nIDEvent) { - if (CWnd::GetCapture() != &pView) + if (!pView.HasCapture()) { m_eSelMode = smodeNormal; KillDragTimer(pView); @@ -331,18 +351,22 @@ void CPSelectTool::OnTimer(CPlayBoardView& pView, uintptr_t nIDEvent) m_eSelMode = smodeMove; KillDragTimer(pView); +#if 0 CClientDC dc(&pView); pView.OnPrepareScaledDC(dc, TRUE); pSLst.DrawTracker(dc, trkSelected); // Turn off handles +#else + wxASSERT(!"TODO: overlay"); +#endif CPoint point; GetCursorPos(&point); - pView.ScreenToClient(&point); - point = pView.ClientToWorkspace(point); + point = CB::Convert(pView.ScreenToClient(CB::Convert(point))); + point = CB::Convert(pView.ClientToWorkspace(CB::Convert(point))); pSLst.SetTrackingMode(trkMoving); DoDragDropStart(pView); - point = pView.WorkspaceToClient(point); + point = CB::Convert(pView.WorkspaceToClient(CB::Convert(point))); DoDragDrop(pView, point); } else if (m_eSelMode != smodeMove) @@ -370,8 +394,8 @@ BOOL CPSelectTool::OnSetCursor(const CPlayBoardView& pView, UINT nHitTest) const // Convert cursor position to document coordinates CPoint point; GetCursorPos(&point); - pView.ScreenToClient(&point); - point = pView.ClientToWorkspace(point); + point = CB::Convert(pView.ScreenToClient(CB::Convert(point))); + point = CB::Convert(pView.ClientToWorkspace(CB::Convert(point))); // Check for movement through handle areas. Set the // cursor to the appropriate shape. @@ -399,9 +423,13 @@ void CPSelectTool::StartSizingOperation(CPlayBoardView& pView, UINT nFlags, m_nHandleID = nHandleID; m_eSelMode = smodeSizing; CPlayTool::OnLButtonDown(pView, nFlags, point); +#if 0 CClientDC dc(&pView); pView.OnPrepareScaledDC(dc, TRUE); pSLst.DrawTracker(dc, trkSizing); +#else + wxASSERT(!"TODO: overlay"); +#endif } void CPSelectTool::DrawSelectionRect(CDC& pDC, const CRect& pRct) const @@ -435,8 +463,8 @@ BOOL CPSelectTool::ProcessAutoScroll(CPlayBoardView& pView) CRect rect; GetCursorPos(&point); - pView.ScreenToClient(&point); - pView.GetClientRect(&rectClient); + point = CB::Convert(pView.ScreenToClient(CB::Convert(point))); + rectClient = CB::Convert(pView.GetClientRect()); rect = rectClient; rect.InflateRect(-scrollZone, -scrollZone); rect.NormalizeRect(); @@ -444,6 +472,7 @@ BOOL CPSelectTool::ProcessAutoScroll(CPlayBoardView& pView) UINT nScrollID = MAKEWORD(-1, -1); if (rectClient.PtInRect(point) && !rect.PtInRect(point)) { +#if 0 // Mouse is in the scroll zone.... // Determine which way to scroll along both X & Y axis if (point.x < rect.left) @@ -503,6 +532,9 @@ BOOL CPSelectTool::ProcessAutoScroll(CPlayBoardView& pView) } return TRUE; } +#else + wxASSERT(!"TODO: autoscroll, overlay"); +#endif } return FALSE; } @@ -520,13 +552,13 @@ void CPSelectTool::MoveSelections(CSelList &pSLst, const CPoint& point) CPoint CPSelectTool::AdjustPoint(const CPlayBoardView& pView, CPoint point) const { - point = pView.AdjustPoint(point); + point = CB::Convert(pView.AdjustPoint(CB::Convert(point))); if (point == c_ptLast) return point; if (m_eSelMode == smodeMove) { CRect rct = pView.GetSelectList().GetEnclosingRect(); - CPoint pnt = pView.GetWorkspaceDim(); + CPoint pnt = CB::Convert(pView.GetWorkspaceDim()); if (rct.left + point.x - c_ptLast.x < 0) // Clamp point.x = c_ptLast.x - rct.left; if (rct.top + point.y - c_ptLast.y < 0) // Clamp @@ -541,31 +573,47 @@ CPoint CPSelectTool::AdjustPoint(const CPlayBoardView& pView, CPoint point) cons void CPSelectTool::StartDragTimer(CPlayBoardView& pView) { +#if 0 m_nTimerID = pView.SetTimer(timerIDSelectDelay, timerSelDelay, NULL); +#else + wxASSERT(!"TODO: autoscroll"); +#endif } void CPSelectTool::KillDragTimer(CPlayBoardView& pView) { +#if 0 if (m_nTimerID != uintptr_t(0)) { pView.KillTimer(m_nTimerID); m_nTimerID = uintptr_t(0); } +#else +wxASSERT(!"TODO: autoscroll"); +#endif } void CPSelectTool::StartScrollTimer(CPlayBoardView& pView) { +#if 0 m_nTimerID = pView.SetTimer(timerIDAutoScroll, timerAutoScroll, NULL); +#else + wxASSERT(!"TODO: autoscroll"); +#endif } void CPSelectTool::KillScrollTimer(CPlayBoardView& pView) { +#if 0 if (m_nTimerID != uintptr_t(0)) { pView.KillTimer(m_nTimerID); m_nTimerID = uintptr_t(0); } +#else + wxASSERT(!"TODO: autoscroll"); +#endif } //////////////////////////////////////////////////////////////////////// @@ -584,7 +632,7 @@ void CPSelectTool::DoDragDropStart(CPlayBoardView& pView) void CPSelectTool::DoDragDrop(CPlayBoardView& pView, const CPoint& pntClient) { CPoint pnt = pntClient; - pView.ClientToScreen(&pnt); + pnt = CB::Convert(pView.ClientToScreen(CB::Convert(pnt))); CWnd* pWnd = GetWindowFromPoint(pnt); HWND hWnd = pWnd ? pWnd->m_hWnd : NULL; // Get actual window handle @@ -610,7 +658,7 @@ void CPSelectTool::DoDragDrop(CPlayBoardView& pView, const CPoint& pntClient) if (hWnd != NULL) { m_di.m_point = pntClient; - pView.ClientToScreen(&m_di.m_point); // Move point into new coord system + m_di.m_point = CB::Convert(pView.ClientToScreen(CB::Convert(m_di.m_point))); // Move point into new coord system pWnd->ScreenToClient(&m_di.m_point); m_di.m_phase = PhaseDrag::Over; hCursor = (HCURSOR)pWnd->SendMessage(WM_DRAGDROP, GetProcessId(GetCurrentProcess()), @@ -628,13 +676,13 @@ bool CPSelectTool::DoDragDropEnd(CPlayBoardView& pView, const CPoint& pntClient) { SetCursor(LoadCursor(NULL, IDC_ARROW)); - CPoint pnt = pntClient; - pView.ClientToScreen(&pnt); - CWnd* pWnd = GetWindowFromPoint(pnt); + wxPoint pnt = CB::Convert(pntClient); + pView.ClientToScreen(pnt); + CWnd* pWnd = GetWindowFromPoint(CB::Convert(pnt)); if (pWnd == NULL) return false; m_di.m_point = pntClient; - pView.ClientToScreen(&m_di.m_point); + m_di.m_point = CB::Convert(pView.ClientToScreen(CB::Convert(m_di.m_point))); pWnd->ScreenToClient(&m_di.m_point); m_di.m_phase = PhaseDrag::Drop; @@ -649,7 +697,7 @@ void CPShapeTool::OnLButtonDown(CPlayBoardView& pView, UINT nFlags, CPoint point CSelList& pSLst = pView.GetSelectList(); pSLst.PurgeList(TRUE); // Clear current select list int nDragHandle; - point = pView.AdjustPoint(point); + point = CB::Convert(pView.AdjustPoint(CB::Convert(point))); m_pObj = CreateDrawObj(pView, point, nDragHandle); pSLst.AddObject(*m_pObj, TRUE); s_plySelectTool.StartSizingOperation(pView, nFlags, point, nDragHandle); @@ -657,7 +705,7 @@ void CPShapeTool::OnLButtonDown(CPlayBoardView& pView, UINT nFlags, CPoint point bool CPShapeTool::OnLButtonUp(CPlayBoardView& pView, UINT nFlags, CPoint point) { - if (CWnd::GetCapture() != &pView) + if (!pView.HasCapture()) return false; bool retval = true; retval = s_plySelectTool.OnLButtonUp(pView, nFlags, point) && retval; @@ -673,7 +721,7 @@ bool CPShapeTool::OnLButtonUp(CPlayBoardView& pView, UINT nFlags, CPoint point) void CPShapeTool::OnMouseMove(CPlayBoardView& pView, UINT nFlags, CPoint point) { - if (CWnd::GetCapture() == &pView) + if (pView.HasCapture()) s_plySelectTool.OnMouseMove(pView, nFlags, point); } @@ -698,7 +746,7 @@ OwnerPtr CPLineTool::CreateDrawObj(CPlayBoardView& pView, const CPoint { OwnerPtr pObj = MakeOwner(); pObj->SetLine(point.x, point.y, point.x, point.y); - pObj->SetForeColor(pView.GetLineColor()); + pObj->SetForeColor(CB::Convert(pView.GetLineColor())); pObj->SetLineWidth(pView.GetLineWidth()); nHandle = hitPtB; return pObj; @@ -739,7 +787,7 @@ void CPPlotTool::OnLButtonDown(CPlayBoardView& pView, UINT nFlags, ASSERT(pPBrd.GetPlotMoveMode()); if (pPBrd.m_bSnapMovePlot) - point = pView.AdjustPoint(point); // Keep on the grid (if enabled) + point = CB::Convert(pView.AdjustPoint(CB::Convert(point))); // Keep on the grid (if enabled) CPoint pntPrev = pPBrd.GetPrevPlotPoint(); diff --git a/GP/VwPbrd.cpp b/GP/VwPbrd.cpp index d8ef3caf..e42ac976 100644 --- a/GP/VwPbrd.cpp +++ b/GP/VwPbrd.cpp @@ -49,7 +49,6 @@ static char THIS_FILE[] = __FILE__; #endif -IMPLEMENT_DYNAMIC(CPlayBoardView, CScrollView) IMPLEMENT_DYNCREATE(CPlayBoardViewContainer, CView) #ifdef _DEBUG @@ -58,12 +57,12 @@ IMPLEMENT_DYNCREATE(CPlayBoardViewContainer, CView) ///////////////////////////////////////////////////////////////////////////// -BEGIN_MESSAGE_MAP(CPlayBoardView, CScrollView) - //{{AFX_MSG_MAP(CPlayBoardView) - ON_COMMAND(ID_VIEW_FULLSCALEBRD, OnViewFullScaleBrd) - ON_UPDATE_COMMAND_UI(ID_VIEW_FULLSCALEBRD, OnUpdateViewFullScaleBrd) - ON_COMMAND(ID_VIEW_HALFSCALEBRD, OnViewHalfScaleBrd) - ON_UPDATE_COMMAND_UI(ID_VIEW_HALFSCALEBRD, OnUpdateViewHalfScaleBrd) +wxBEGIN_EVENT_TABLE(CPlayBoardView, CPlayBoardView::BASE) + EVT_MENU(XRCID("ID_VIEW_FULLSCALEBRD"), OnViewFullScaleBrd) + EVT_UPDATE_UI(XRCID("ID_VIEW_FULLSCALEBRD"), OnUpdateViewFullScaleBrd) + EVT_MENU(XRCID("ID_VIEW_HALFSCALEBRD"), OnViewHalfScaleBrd) + EVT_UPDATE_UI(XRCID("ID_VIEW_HALFSCALEBRD"), OnUpdateViewHalfScaleBrd) +#if 0 ON_REGISTERED_MESSAGE(WM_DRAGDROP, OnDragItem) ON_MESSAGE(WM_ROTATEPIECE_DELTA, OnMessageRotateRelative) ON_MESSAGE(WM_CENTERBOARDONPOINT, OnMessageCenterBoardOnPoint) @@ -102,8 +101,10 @@ BEGIN_MESSAGE_MAP(CPlayBoardView, CScrollView) ON_UPDATE_COMMAND_UI(ID_EDIT_SELALLMARKERS, OnUpdateEditSelAllMarkers) ON_COMMAND(ID_ACT_ROTATE, OnActRotate) ON_UPDATE_COMMAND_UI(ID_ACT_ROTATE, OnUpdateActRotate) - ON_COMMAND(ID_VIEW_TOGGLESCALE, OnViewToggleScale) - ON_UPDATE_COMMAND_UI(ID_VIEW_TOGGLESCALE, OnUpdateViewToggleScale) +#endif + EVT_MENU(XRCID("ID_VIEW_TOGGLESCALE"), OnViewToggleScale) + EVT_UPDATE_UI(XRCID("ID_VIEW_TOGGLESCALE"), OnUpdateViewToggleScale) +#if 0 ON_COMMAND(ID_VIEW_PIECES, OnViewPieces) ON_UPDATE_COMMAND_UI(ID_VIEW_PIECES, OnUpdateViewPieces) ON_COMMAND(ID_EDIT_COPY, OnEditCopy) @@ -132,27 +133,35 @@ BEGIN_MESSAGE_MAP(CPlayBoardView, CScrollView) ON_UPDATE_COMMAND_UI(ID_ACT_RELEASE_OWNERSHIP, OnUpdateActReleaseOwnership) ON_COMMAND(ID_ACT_SET_OWNER, OnActSetOwner) ON_UPDATE_COMMAND_UI(ID_ACT_SET_OWNER, OnUpdateActSetOwner) - ON_COMMAND(ID_VIEW_SMALLSCALEBRD, OnViewSmallScaleBoard) - ON_UPDATE_COMMAND_UI(ID_VIEW_SMALLSCALEBRD, OnUpdateViewSmallScaleBoard) +#endif + EVT_MENU(XRCID("ID_VIEW_SMALLSCALEBRD"), OnViewSmallScaleBoard) + EVT_UPDATE_UI(XRCID("ID_VIEW_SMALLSCALEBRD"), OnUpdateViewSmallScaleBoard) +#if 0 ON_COMMAND_EX(ID_PTOOL_LINE, OnPlayTool) ON_COMMAND_EX(ID_PTOOL_TEXTBOX, OnPlayTool) ON_UPDATE_COMMAND_UI(ID_PTOOL_LINE, OnUpdatePlayTool) ON_UPDATE_COMMAND_UI(ID_PTOOL_TEXTBOX, OnUpdatePlayTool) ON_WM_MOUSEWHEEL() - ON_COMMAND(ID_VIEW_BOARD_ROTATE180, OnViewBoardRotate180) - ON_UPDATE_COMMAND_UI(ID_VIEW_BOARD_ROTATE180, OnUpdateViewBoardRotate180) +#endif + EVT_MENU(XRCID("ID_VIEW_BOARD_ROTATE180"), OnViewBoardRotate180) + EVT_UPDATE_UI(XRCID("ID_VIEW_BOARD_ROTATE180"), OnUpdateViewBoardRotate180) +#if 0 ON_COMMAND(ID_ACT_ROTATEGROUP, OnActRotateGroupRelative) ON_UPDATE_COMMAND_UI(ID_ACT_ROTATEGROUP, OnUpdateActRotateGroupRelative) - //}}AFX_MSG_MAP ON_COMMAND_RANGE(ID_ACT_ROTATE_0, (ID_ACT_ROTATE_0 + 360 / 5), OnRotatePiece) ON_UPDATE_COMMAND_UI_RANGE(ID_ACT_ROTATE_0, (ID_ACT_ROTATE_0 + 360 / 5), OnUpdateRotatePiece) ON_COMMAND_RANGE(ID_MRKGROUP_FIRST, ID_MRKGROUP_FIRST + 64, OnSelectGroupMarkers) ON_UPDATE_COMMAND_UI_RANGE(ID_MRKGROUP_FIRST, ID_MRKGROUP_FIRST + 64, OnUpdateSelectGroupMarkers) - ON_MESSAGE(WM_WINSTATE, OnMessageWindowState) +#endif + EVT_WINSTATE(OnMessageWindowState) +#if 0 ON_MESSAGE(WM_SELECT_BOARD_OBJLIST, OnMessageSelectBoardObjectList) -END_MESSAGE_MAP() +#endif + EVT_SCROLLWIN_LINEDOWN(OnScrollWinLine) + EVT_SCROLLWIN_LINEUP(OnScrollWinLine) +wxEND_EVENT_TABLE() -BEGIN_MESSAGE_MAP(CPlayBoardViewContainer, CView) +BEGIN_MESSAGE_MAP(CPlayBoardViewContainer, CPlayBoardViewContainer::BASE) ON_WM_CREATE() ON_WM_SIZE() ON_MESSAGE(WM_WINSTATE, OnMessageWindowState) @@ -161,21 +170,33 @@ END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CPlayBoardView construction/destruction -CPlayBoardView::CPlayBoardView() : - m_selList(*this) +CPlayBoardView::CPlayBoardView(CPlayBoardViewContainer& p) : + m_selList(*this), + parent(&p), + document(dynamic_cast(parent->GetDocument())), + m_pPBoard(static_cast(document->GetNewViewParameter())) { - m_pPBoard = NULL; m_nZoom = fullScale; m_nCurToolID = ID_PTOOL_SELECT; m_bInDrag = FALSE; m_pDragSelList = NULL; +#if 0 m_nTimerID = uintptr_t(0); +#endif + + // use sizers for scrolling + wxSizer* sizer = new wxBoxSizer(wxVERTICAL); + SetSizer(sizer); + sizer->Add(0, 0); + BASE::Create(*parent, 0); + OnInitialUpdate(); } CPlayBoardView::~CPlayBoardView() { } +#if 0 BOOL CPlayBoardView::PreCreateWindow(CREATESTRUCT& cs) { if (!CScrollView::PreCreateWindow(cs)) @@ -187,17 +208,19 @@ BOOL CPlayBoardView::PreCreateWindow(CREATESTRUCT& cs) return TRUE; } +#endif ///////////////////////////////////////////////////////////////////////////// void CPlayBoardView::OnInitialUpdate() { - m_toolMsgTip.Create(this, TTS_ALWAYSTIP | TTS_BALLOON | TTS_NOPREFIX); - m_toolMsgTip.SetMaxTipWidth(MAX_PLAYBOARD_TIP_WIDTH); - m_toolHitTip.Create(this, TTS_ALWAYSTIP | TTS_BALLOON | TTS_NOPREFIX); - m_toolHitTip.SetMaxTipWidth(MAX_PLAYBOARD_TIP_WIDTH); + m_toolMsgTip.SetBalloonMode(true); + m_toolMsgTip.SetMaxWidth(MAX_PLAYBOARD_TIP_WIDTH); + m_toolHitTip.SetBalloonMode(true); + m_toolHitTip.SetMaxWidth(MAX_PLAYBOARD_TIP_WIDTH); m_pCurTipObj = NULL; +#if 0 m_pPBoard = (CPlayBoard*)GetDocument().GetNewViewParameter(); if (m_pPBoard == NULL) @@ -209,8 +232,8 @@ void CPlayBoardView::OnInitialUpdate() } ASSERT(m_pPBoard != NULL); +#endif SetOurScrollSizes(m_nZoom); - CScrollView::OnInitialUpdate(); } void CPlayBoardView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint) @@ -223,18 +246,18 @@ void CPlayBoardView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint) else if (lHint == HINT_BOARDCHANGE) { // Make sure we still exist! - if (GetDocument().GetPBoardManager().FindPBoardByRef(CheckedDeref(m_pPBoard)) == Invalid_v) + if (GetDocument().GetPBoardManager().FindPBoardByRef(*m_pPBoard) == Invalid_v) { - CFrameWnd* pFrm = GetParentFrame(); - ASSERT(pFrm != NULL); + CFrameWnd* pFrm = parent->GetParentFrame(); + wxASSERT(pFrm != NULL); pFrm->PostMessage(WM_CLOSE, 0, 0L); } } else if (lHint == HINT_UPDATEOBJECT && ph->GetArgs().m_pPBoard == m_pPBoard) { - CRect rct; - rct = ph->GetArgs().m_pDrawObj->GetEnclosingRect(); // In board coords. - InvalidateWorkspaceRect(&rct); + wxRect rct; + rct = CB::Convert(ph->GetArgs().m_pDrawObj->GetEnclosingRect()); // In board coords. + InvalidateWorkspaceRect(rct); } else if (lHint == HINT_UPDATEOBJLIST && ph->GetArgs().m_pPBoard == m_pPBoard) { @@ -242,8 +265,8 @@ void CPlayBoardView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint) for (size_t i = size_t(0); i < pPtrList.size(); ++i) { const CDrawObj& pDObj = *pPtrList[i]; - CRect rct = pDObj.GetEnclosingRect(); // In board coords. - InvalidateWorkspaceRect(&rct); + wxRect rct = CB::Convert(pDObj.GetEnclosingRect()); // In board coords. + InvalidateWorkspaceRect(rct); } } else if (lHint == HINT_SELECTOBJ) @@ -272,7 +295,7 @@ void CPlayBoardView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint) NotifySelectListChange(); } } - else if (lHint == HINT_UPDATESELECTLIST && pSender != this) + else if (lHint == HINT_UPDATESELECTLIST && pSender != &*parent) { // Resync the select list to ensure that all objects still exist // and that the handles track objct movements for those that still @@ -291,23 +314,21 @@ void CPlayBoardView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint) else if (lHint == HINT_INVALIDATERECT && ph->GetArgs().m_pPBoard == m_pPBoard) { const CRect& rect = CheckedDeref(ph->GetArgs().m_pRect); - InvalidateWorkspaceRect(rect, true); + InvalidateWorkspaceRect(CB::Convert(rect), true); } else if (lHint == HINT_GAMESTATEUSED) { m_selList.PurgeList(TRUE); - Invalidate(FALSE); - BeginWaitCursor(); - UpdateWindow(); - EndWaitCursor(); + Refresh(FALSE); + wxBusyCursor busyCursor; + Update(); } else if (lHint == HINT_ALWAYSUPDATE || (lHint == HINT_UPDATEBOARD && ph->GetArgs().m_pPBoard == m_pPBoard)) { - Invalidate(FALSE); - BeginWaitCursor(); - UpdateWindow(); - EndWaitCursor(); + Refresh(FALSE); + wxBusyCursor busyCursor; + Update(); } else if (lHint == HINT_CLEARINDTIP) { @@ -322,18 +343,18 @@ void CPlayBoardView::NotifySelectListChange() CGamDocHint hint; hint.GetArgs().m_pPBoard = m_pPBoard.get(); hint.GetArgs().m_pSelList = &m_selList; - GetDocument().UpdateAllViews(this, HINT_UPDATESELECT, &hint); + GetDocument().UpdateAllViews(&*parent, HINT_UPDATESELECT, &hint); } /////////////////////////////////////////////////////////////////////// void CPlayBoardView::OnActivateView(BOOL bActivate, CView* pActivateView, CView* pDeactiveView) { - CScrollView::OnActivateView(bActivate, pActivateView, pDeactiveView); if (bActivate && pActivateView != pDeactiveView) NotifySelectListChange(); } +#if 0 /////////////////////////////////////////////////////////////////////// // This message is sent when a document is being saved. // WPARAM = CPlayBoard*, LPARAM = const std::vector>* @@ -347,53 +368,53 @@ LRESULT CPlayBoardView::OnMessageSelectBoardObjectList(WPARAM wParam, LPARAM lPa SelectAllObjectsInList(pList); // Select the new set return (LRESULT)1; } +#endif /////////////////////////////////////////////////////////////////////// // This message is sent when a document is being saved. // WPARAM = CArchive*, LPARAM = 0 if save, 1 if restore -LRESULT CPlayBoardView::OnMessageWindowState(WPARAM wParam, LPARAM lParam) +void CPlayBoardView::OnMessageWindowState(WinStateEvent& event) { - ASSERT(wParam != NULL); - CArchive& ar = *((CArchive*)wParam); + CArchive& ar = event.GetArchive(); if (ar.IsStoring()) { - ar << (WORD)m_nZoom; + ar << static_cast(m_nZoom); - CPoint pnt = GetScrollPosition(); - ar << (DWORD)pnt.x; - ar << (DWORD)pnt.y; + wxPoint pnt = GetViewStart(); + ar << value_preserving_cast(pnt.x); + ar << value_preserving_cast(pnt.y); // Save the select list if (!m_selList.empty()) { std::vector> tblObjPtrs; m_selList.LoadTableWithObjectPtrs(tblObjPtrs, CSelList::otPiecesMarks, TRUE); - ar << value_preserving_cast(tblObjPtrs.size()); - for (size_t i = 0; i < tblObjPtrs.size(); i++) + ar << value_preserving_cast(tblObjPtrs.size()); + for (size_t i = size_t(0); i < tblObjPtrs.size(); i++) { CDrawObj& pObj = *tblObjPtrs.at(i); ar << GetDocument().GetGameElementCodeForObject(pObj); } } else - ar << (DWORD)0; + ar << uint32_t(0); } else { - CPoint pnt; - WORD wTmp; - DWORD dwTmp; + wxPoint pnt; + uint16_t wTmp; + uint32_t dwTmp; - ar >> wTmp; DoViewScaleBrd((TileScale)wTmp); + ar >> wTmp; DoViewScaleBrd(static_cast(wTmp)); - ar >> dwTmp; pnt.x = (LONG)dwTmp; - ar >> dwTmp; pnt.y = (LONG)dwTmp; + ar >> dwTmp; pnt.x = value_preserving_cast(dwTmp); + ar >> dwTmp; pnt.y = value_preserving_cast(dwTmp); - ScrollToPosition(pnt); + Scroll(pnt); // Restore the select list. m_selList.PurgeList(); - DWORD dwSelCount; + uint32_t dwSelCount; ar >> dwSelCount; while (dwSelCount--) { @@ -408,11 +429,45 @@ LRESULT CPlayBoardView::OnMessageWindowState(WPARAM wParam, LPARAM lParam) m_selList.AddObject(*pObj, TRUE); } } - return (LRESULT)1; +} + +/* This view should support scrolling by individual pixels, + but don't make the line-up and line-down scrolling that + slow. */ +void CPlayBoardView::OnScrollWinLine(wxScrollWinEvent& event) +{ + int type = event.GetEventType(); + wxASSERT(type == static_cast(wxEVT_SCROLLWIN_LINEDOWN) || + type == static_cast(wxEVT_SCROLLWIN_LINEUP)); + + int orient = event.GetOrientation(); + wxASSERT(orient == static_cast(wxHORIZONTAL) || + orient == static_cast(wxVERTICAL)); + + int oldPos; + int offset; + if (orient == static_cast(wxHORIZONTAL)) + { + oldPos = GetViewStart().x; + offset = m_xScrollPixelsPerLine; + } + else + { + oldPos = GetViewStart().y; + offset = m_yScrollPixelsPerLine; + } + if (type == static_cast(wxEVT_SCROLLWIN_LINEUP)) + { + offset = -offset; + } + + wxScrollWinEvent thumbEvent(wxEVT_SCROLLWIN_THUMBTRACK, oldPos + offset, orient); + ProcessWindowEvent(thumbEvent); } ///////////////////////////////////////////////////////////////////////////// +#if 0 BOOL CPlayBoardView::PreTranslateMessage(MSG* pMsg) { // RelayEvent is required for CToolTipCtrl objects - @@ -423,52 +478,68 @@ BOOL CPlayBoardView::PreTranslateMessage(MSG* pMsg) return CScrollView::PreTranslateMessage(pMsg); } +#endif ///////////////////////////////////////////////////////////////////////////// void CPlayBoardView::SetOurScrollSizes(TileScale nZoom) { CBoard* pBoard = m_pPBoard->GetBoard(); - HDC hDC = ::GetDC(NULL); - int xWidth = GetDeviceCaps(hDC, HORZRES); - int yHeight = GetDeviceCaps(hDC, VERTRES); - CSize sizeCell = pBoard->GetCellSize(nZoom); - int nPageX = sizeCell.cx > xWidth / 8 ? xWidth / 32 : sizeCell.cx; - int nPageY = sizeCell.cy > yHeight / 8 ? yHeight / 32 : sizeCell.cy; + wxSizer& sizer = CheckedDeref(GetSizer()); + wxSizerItemList& items = sizer.GetChildren(); + wxASSERT(items.size() == 1); + wxSizerItem& item = CheckedDeref(items[0]); + wxASSERT(item.IsSpacer()); - SetScrollSizes(MM_TEXT, pBoard->GetSize(m_nZoom), sizeDefault, - CSize(nPageX, nPageY)); + item.AssignSpacer(CB::Convert(pBoard->GetSize(m_nZoom))); + SetScrollRate(1, 1); + sizer.FitInside(this); + + // use size of cell as line increment + const CCellForm& cf = pBoard->GetBoardArray().GetCellForm(m_nZoom); + wxSize cellSize = CB::Convert(cf.GetCellSize()); + switch (cf.GetCellType()) + { + case cformHexFlat: + (cellSize.x *= 3) /= 4; + break; + case cformHexPnt: + (cellSize.y *= 3) /= 4; + break; + default: + ; // do nothing + } + m_xScrollPixelsPerLine = cellSize.x; + m_yScrollPixelsPerLine = cellSize.y; } ///////////////////////////////////////////////////////////////////////////// // CPlayBoardView drawing -void CPlayBoardView::OnDraw(CDC* pDC) +void CPlayBoardView::OnDraw(wxDC& pDC) { CBoard* pBoard = m_pPBoard->GetBoard(); - CDC dcMem; - CRect oRct; - CRect oRctSave; - CBitmap* pPrvBMap; + wxMemoryDC dcMem; + wxRect oRct; + wxRect oRctSave; - pDC->GetClipBox(&oRct); + pDC.GetClippingBox(oRct); - if (oRct.IsRectEmpty()) + if (oRct.IsEmpty()) return; // Nothing to do - OwnerPtr bmMem = CDib::CreateDIBSection( - oRct.Width(), oRct.Height()); - dcMem.CreateCompatibleDC(pDC); - pPrvBMap = dcMem.SelectObject(&*bmMem); + wxBitmap bmMem( + oRct.GetWidth(), oRct.GetHeight(), pDC); + dcMem.SelectObject(bmMem); if (m_pPBoard->IsBoardRotated180()) { oRctSave = oRct; - CSize sizeBrd = pBoard->GetSize(m_nZoom); - oRct = CRect(CPoint(sizeBrd.cx - oRct.left - oRct.Width(), - sizeBrd.cy - oRct.top - oRct.Height()), oRct.Size()); + wxSize sizeBrd = CB::Convert(pBoard->GetSize(m_nZoom)); + oRct = wxRect(wxPoint(sizeBrd.x - oRct.GetLeft() - oRct.GetWidth(), + sizeBrd.y - oRct.GetTop() - oRct.GetHeight()), oRct.GetSize()); } - dcMem.SetViewportOrg(-oRct.left, -oRct.top); + dcMem.SetDeviceOrigin(-oRct.GetLeft(), -oRct.GetTop()); // Draw base board image... pBoard->SetMaxDrawLayer(); // Make sure all layers are drawn @@ -477,37 +548,37 @@ void CPlayBoardView::OnDraw(CDC* pDC) // Draw pieces etc..... - CRect rct(&oRct); - SetupDrawListDC(dcMem, rct); + wxRect rct(oRct); + { + DCSetupDrawListDC setupDrawListDC(*this, dcMem, rct); - m_pPBoard->Draw(dcMem, &rct, m_nZoom); + m_pPBoard->Draw(dcMem, rct, m_nZoom); - wxASSERT(!pDC->IsPrinting()); - if (!pDC->IsPrinting() && GetPlayBoard().GetPiecesVisible()) + wxASSERT(!dynamic_cast(&pDC)); + if (!dynamic_cast(&pDC) && GetPlayBoard().GetPiecesVisible()) m_selList.OnDraw(dcMem); // Handle selections. - RestoreDrawListDC(dcMem); + } if (m_pPBoard->IsBoardRotated180()) { // Xfer to output - dcMem.SetViewportOrg(0, 0); - pDC->StretchBlt(oRctSave.left, oRctSave.top, oRctSave.Width(), oRctSave.Height(), - &dcMem, oRctSave.Width() - 1, oRctSave.Height() - 1, - -oRctSave.Width(), -oRctSave.Height(), SRCCOPY); + dcMem.SetDeviceOrigin(0, 0); + pDC.StretchBlit(oRctSave.GetLeft(), oRctSave.GetTop(), oRctSave.GetWidth(), oRctSave.GetHeight(), + &dcMem, oRctSave.GetWidth() - 1, oRctSave.GetHeight() - 1, + -oRctSave.GetWidth(), -oRctSave.GetHeight()); } else { // Xfer to output - pDC->BitBlt(oRct.left, oRct.top, oRct.Width(), oRct.Height(), - &dcMem, oRct.left, oRct.top, SRCCOPY); + pDC.Blit(oRct.GetLeft(), oRct.GetTop(), oRct.GetWidth(), oRct.GetHeight(), + &dcMem, oRct.GetLeft(), oRct.GetTop()); } - - dcMem.SelectObject(pPrvBMap); } ///////////////////////////////////////////////////////////////////////////// +#if 0 LRESULT CPlayBoardView::OnDragItem(WPARAM wParam, LPARAM lParam) { if (wParam != GetProcessId(GetCurrentProcess())) @@ -944,69 +1015,71 @@ void CPlayBoardView::DragKillAutoScroll() KillTimer(m_nTimerID); m_nTimerID = uintptr_t(0); } +#endif ///////////////////////////////////////////////////////////////////////////// -void CPlayBoardView::AddPiece(CPoint pnt, PieceID pid) +void CPlayBoardView::AddPiece(wxPoint pnt, PieceID pid) { - ASSERT(FALSE); //!!!!NO LONGER USED?!!!!! - GetDocument().PlacePieceOnBoard(pnt, pid, m_pPBoard.get()); + wxASSERT(FALSE); //!!!!NO LONGER USED?!!!!! + GetDocument().PlacePieceOnBoard(CB::Convert(pnt), pid, m_pPBoard.get()); } ///////////////////////////////////////////////////////////////////////////// -void CPlayBoardView::OnPrepareScaledDC(CDC& pDC, BOOL bHonor180Flip) +void CPlayBoardView::OnPrepareScaledDC(wxDC& pDC, BOOL bHonor180Flip) { - OnPrepareDC(&pDC, NULL); + PrepareDC(pDC); PrepareScaledDC(pDC, NULL, bHonor180Flip); } -void CPlayBoardView::SetupDrawListDC(CDC& pDC, CRect& pRct) const +CPlayBoardView::DCSetupDrawListDC::DCSetupDrawListDC(const CPlayBoardView& rThis, wxDC& pDC, wxRect& pRct) { - if (m_nZoom == fullScale) + if (rThis.m_nZoom == fullScale) return; - pDC.SaveDC(); - PrepareScaledDC(pDC, &pRct); + double xScale, yScale; + pDC.GetUserScale(&xScale, &yScale); + scaleChanger = CB::DCUserScaleChanger(pDC, xScale, yScale); + logOrgChanger = CB::DCLogicalOriginChanger(pDC, pDC.GetLogicalOrigin()); + + rThis.PrepareScaledDC(pDC, &pRct); } -void CPlayBoardView::PrepareScaledDC(CDC& pDC, CRect* pRct, BOOL bHonor180Flip) const +void CPlayBoardView::PrepareScaledDC(wxDC& pDC, wxRect* pRct, BOOL bHonor180Flip) const { - CSize wsize, vsize; + wxSize wsize, vsize; m_pPBoard->GetBoard()->GetBoardArray(). GetBoardScaling(m_nZoom, wsize, vsize); - pDC.SetMapMode(MM_ANISOTROPIC); if (bHonor180Flip && m_pPBoard->IsBoardRotated180()) { - pDC.SetWindowExt(-wsize); - pDC.SetWindowOrg(wsize.cx, wsize.cy); + pDC.SetLogicalOrigin(wsize.x, wsize.y); + pDC.SetAxisOrientation(false, true); } - else - pDC.SetWindowExt(wsize); - pDC.SetViewportExt(vsize); + pDC.SetUserScale(double(vsize.x)/wsize.x, double(vsize.y)/wsize.y); if (pRct != NULL) ScaleRect(*pRct, wsize, vsize); } -void CPlayBoardView::RestoreDrawListDC(CDC& pDC) const -{ - if (m_nZoom != fullScale) - pDC.RestoreDC(-1); -} - ///////////////////////////////////////////////////////////////////////////// #ifdef _DEBUG const CGamDoc& CPlayBoardView::GetDocument() const // non-debug version is inline { - const CGamDoc& retval = CheckedDeref(CB::ToCGamDoc(m_pDocument)); + const CGamDoc& retval = *document; return retval; } #endif //_DEBUG +CFrameWnd* CPlayBoardView::GetParentFrame() +{ + return parent->GetParentFrame(); +} + +#if 0 ///////////////////////////////////////////////////////////////////////////// // Right mouse button handler @@ -1040,6 +1113,7 @@ void CPlayBoardView::OnContextMenu(CWnd* pWnd, CPoint point) END_TRY } } +#endif ///////////////////////////////////////////////////////////////////////////// // Handlers associated with tools. @@ -1053,6 +1127,7 @@ BOOL CPlayBoardView::IsBoardContentsAvailableToCurrentPlayer() const return m_pPBoard->IsOwnedBy(GetDocument().GetCurrentPlayerMask()); } +#if 0 void CPlayBoardView::OnLButtonDown(UINT nFlags, CPoint point) { if (!IsBoardContentsAvailableToCurrentPlayer()) @@ -1245,6 +1320,7 @@ void CPlayBoardView::OnUpdateEditClear(CCmdUI* pCmdUI) { pCmdUI->Enable(!GetDocument().IsPlaying() && m_selList.HasMarkers()); } +#endif ////////////////////////////////////////////////////////////////////// @@ -1264,6 +1340,7 @@ PToolType CPlayBoardView::MapToolType(UINT nToolResID) const ///////////////////////////////////////////////////////////////////////////// // CPlayBoardView message handlers +#if 0 void CPlayBoardView::OnUpdateIndicatorCellNum(CCmdUI* pCmdUI) { CBoardArray& pba = m_pPBoard->GetBoard()->GetBoardArray(); @@ -1283,71 +1360,69 @@ void CPlayBoardView::OnUpdateIndicatorCellNum(CCmdUI* pCmdUI) } } } +#endif void CPlayBoardView::DoViewScaleBrd(TileScale nZoom) { - ASSERT(m_pPBoard != NULL); CBoard* pBoard = m_pPBoard->GetBoard(); - ASSERT(pBoard != NULL); + wxASSERT(pBoard != NULL); - CPoint pntMid; + wxPoint pntMid; if (m_selList.IsAnySelects()) { CRect rctSelection = m_selList.GetEnclosingRect(); - pntMid = rctSelection.CenterPoint(); + pntMid = CB::Convert(rctSelection.CenterPoint()); } else { - CRect rctClient; - GetClientRect(&rctClient); - pntMid = rctClient.CenterPoint(); + wxRect rctClient = GetClientRect(); + pntMid = GetMidRect(rctClient); pntMid = ClientToWorkspace(pntMid); } m_nZoom = nZoom; SetOurScrollSizes(m_nZoom); - BeginWaitCursor(); - Invalidate(FALSE); + wxBusyCursor busyCursor; + Refresh(FALSE); CenterViewOnWorkspacePoint(pntMid); - UpdateWindow(); - EndWaitCursor(); + Update(); } -void CPlayBoardView::OnViewFullScaleBrd() +void CPlayBoardView::OnViewFullScaleBrd(wxCommandEvent& /*event*/) { DoViewScaleBrd(fullScale); } -void CPlayBoardView::OnUpdateViewFullScaleBrd(CCmdUI* pCmdUI) +void CPlayBoardView::OnUpdateViewFullScaleBrd(wxUpdateUIEvent& pCmdUI) { - pCmdUI->SetCheck(m_nZoom == fullScale); + pCmdUI.Check(m_nZoom == fullScale); } -void CPlayBoardView::OnViewHalfScaleBrd() +void CPlayBoardView::OnViewHalfScaleBrd(wxCommandEvent& /*event*/) { DoViewScaleBrd(halfScale); } -void CPlayBoardView::OnUpdateViewHalfScaleBrd(CCmdUI* pCmdUI) +void CPlayBoardView::OnUpdateViewHalfScaleBrd(wxUpdateUIEvent& pCmdUI) { - pCmdUI->SetCheck(m_nZoom == halfScale); + pCmdUI.Check(m_nZoom == halfScale); } -void CPlayBoardView::OnViewSmallScaleBoard() +void CPlayBoardView::OnViewSmallScaleBoard(wxCommandEvent& /*event*/) { DoViewScaleBrd(smallScale); } -void CPlayBoardView::OnUpdateViewSmallScaleBoard(CCmdUI* pCmdUI) +void CPlayBoardView::OnUpdateViewSmallScaleBoard(wxUpdateUIEvent& pCmdUI) { - pCmdUI->SetCheck(m_nZoom == smallScale); + pCmdUI.Check(m_nZoom == smallScale); } -void CPlayBoardView::OnViewToggleScale() +void CPlayBoardView::OnViewToggleScale(wxCommandEvent& /*event*/) { - if (GetKeyState(VK_CONTROL) < 0) + if (wxGetKeyState(WXK_CONTROL)) { // Zoom out and around if (m_nZoom == fullScale) @@ -1369,12 +1444,12 @@ void CPlayBoardView::OnViewToggleScale() } } -void CPlayBoardView::OnUpdateViewToggleScale(CCmdUI* pCmdUI) +void CPlayBoardView::OnUpdateViewToggleScale(wxUpdateUIEvent& pCmdUI) { - pCmdUI->Enable(TRUE); + pCmdUI.Enable(TRUE); } -void CPlayBoardView::OnViewBoardRotate180() +void CPlayBoardView::OnViewBoardRotate180(wxCommandEvent& /*event*/) { m_pPBoard->SetRotateBoard180(!m_pPBoard->IsBoardRotated180()); CGamDocHint hint; @@ -1382,11 +1457,12 @@ void CPlayBoardView::OnViewBoardRotate180() GetDocument().UpdateAllViews(NULL, HINT_UPDATEBOARD, &hint); } -void CPlayBoardView::OnUpdateViewBoardRotate180(CCmdUI* pCmdUI) +void CPlayBoardView::OnUpdateViewBoardRotate180(wxUpdateUIEvent& pCmdUI) { - pCmdUI->SetCheck(m_pPBoard->IsBoardRotated180()); + pCmdUI.Check(m_pPBoard->IsBoardRotated180()); } +#if 0 BOOL CPlayBoardView::OnPlayTool(UINT id) { if (id !=ID_PTOOL_SELECT) @@ -2417,7 +2493,9 @@ void CPlayBoardView::OnUpdateActSetOwner(CCmdUI* pCmdUI) (m_selList.HasPieces() && pDoc.GetCurrentPlayerMask() != OWNER_MASK_SPECTATOR)); } } +#endif +#if 0 ///////////////////////////////////////////////////////////////////////////// // Fix MFC problems with mouse wheel handling in Win98 and WinME systems @@ -2567,47 +2645,53 @@ BOOL CPlayBoardView::DoMouseWheelFix(UINT fFlags, short zDelta, CPoint point) return bResult; } } +#endif void CPlayBoardViewContainer::OnDraw(CDC* pDC) { // do nothing because child covers entire client rect } +void CPlayBoardViewContainer::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint) +{ + child->OnUpdate(pSender, lHint, pHint); + + BASE::OnUpdate(pSender, lHint, pHint); +} + +void CPlayBoardViewContainer::OnActivateView(BOOL bActivate, CView* pActivateView, + CView* pDeactiveView) +{ + BASE::OnActivateView(bActivate, pActivateView, pDeactiveView); + child->OnActivateView(bActivate, pActivateView, pDeactiveView); +} + CPlayBoardViewContainer::CPlayBoardViewContainer() : - child(new CPlayBoardView) + CB::wxNativeContainerWindowMixin(static_cast(*this)) { } int CPlayBoardViewContainer::OnCreate(LPCREATESTRUCT lpCreateStruct) { - if (CView::OnCreate(lpCreateStruct) == -1) + if (BASE::OnCreate(lpCreateStruct) == -1) { return -1; } - DWORD dwStyle = AFX_WS_DEFAULT_VIEW & ~WS_BORDER; - // Create with the right size (wrong position) - CRect rect; - GetClientRect(rect); - CCreateContext context; - context.m_pCurrentDoc = GetDocument(); - if (!child->Create(NULL, NULL, dwStyle, - rect, this, 0, &context)) - { - return -1; - } + child = new CPlayBoardView(*this); return 0; } void CPlayBoardViewContainer::OnSize(UINT nType, int cx, int cy) { - child->MoveWindow(0, 0, cx, cy); - return CView::OnSize(nType, cx, cy); + child->SetSize(0, 0, cx, cy); + return BASE::OnSize(nType, cx, cy); } LRESULT CPlayBoardViewContainer::OnMessageWindowState(WPARAM wParam, LPARAM lParam) { - child->SendMessage(WM_WINSTATE, wParam, lParam); + WinStateEvent event(*reinterpret_cast(wParam), bool(lParam)); + child->ProcessWindowEvent(event); return (LRESULT)1; } diff --git a/GP/VwPbrd.h b/GP/VwPbrd.h index a29c1f63..857a3485 100644 --- a/GP/VwPbrd.h +++ b/GP/VwPbrd.h @@ -41,21 +41,21 @@ class CPlayBoard; enum TileScale; -class CPlayBoardView : public CScrollView +class CPlayBoardView : public CB::ProcessEventOverride { +private: friend class CPlayBoardFrame; - -public: - CPlayBoardView(); -protected: - DECLARE_DYNAMIC(CPlayBoardView) + friend class CPlayBoardViewContainer; + typedef CB::ProcessEventOverride BASE; + CPlayBoardView(CPlayBoardViewContainer& parent); // Attributes public: const CGamDoc& GetDocument() const; CGamDoc& GetDocument() { return const_cast(std::as_const(*this).GetDocument()); } - const CPlayBoard& GetPlayBoard() const { return CheckedDeref(m_pPBoard); } + const CPlayBoard& GetPlayBoard() const { return *m_pPBoard; } CPlayBoard& GetPlayBoard() { return const_cast(std::as_const(*this).GetPlayBoard()); } + CFrameWnd* GetParentFrame(); // Operations public: @@ -63,7 +63,7 @@ class CPlayBoardView : public CScrollView // Implementation public: ~CPlayBoardView() override; - void OnDraw(CDC* pDC) override; // Overridden to draw this view + void OnDraw(wxDC& pDC) override; // Overridden to draw this view // Tools and selection support public: @@ -72,56 +72,58 @@ class CPlayBoardView : public CScrollView void NotifySelectListChange(); const CSelList& GetSelectList() const { return m_selList; } CSelList& GetSelectList() { return const_cast(std::as_const(*this).GetSelectList()); } - CPoint GetWorkspaceDim() const; + wxPoint GetWorkspaceDim() const; void AddDrawObject(CDrawObj::OwnerPtr pObj); void MoveObjsInSelectList(BOOL bToFront, BOOL bInvalidate = TRUE); - void PrepareScaledDC(CDC& pDC, CRect* pRct = NULL, BOOL bHonor180Flip = FALSE) const; - void OnPrepareScaledDC(CDC& pDC, BOOL bHonor180Flip = FALSE); + void PrepareScaledDC(wxDC& pDC, wxRect* pRct = NULL, BOOL bHonor180Flip = FALSE) const; + void OnPrepareScaledDC(wxDC& pDC, BOOL bHonor180Flip = FALSE); - [[nodiscard]] CPoint AdjustPoint(CPoint pnt) const; // Limit and grid processing - [[nodiscard]] CRect AdjustRect(CRect rct) const; + [[nodiscard]] wxPoint AdjustPoint(wxPoint pnt) const; // Limit and grid processing + [[nodiscard]] wxRect AdjustRect(wxRect rct) const; - void SelectWithinRect(CRect rctNet, BOOL bInclIntersects = FALSE); - void SelectAllUnderPoint(CPoint point); - CDrawObj* ObjectHitTest(CPoint point); + void SelectWithinRect(wxRect rctNet, BOOL bInclIntersects = FALSE); + void SelectAllUnderPoint(wxPoint point); + CDrawObj* ObjectHitTest(wxPoint point); void SelectAllObjectsInList(const std::vector>& pLst); void SelectAllObjectsInTable(const std::vector>& pTbl); void SelectMarkersInGroup(size_t nGroup); void SelectAllMarkers(); // TEMP FOR NOW! - COLORREF GetTextColor() const { return RGB(255, 0, 0); } - COLORREF GetLineColor() const { return RGB(0, 255, 0); } + wxColour GetTextColor() const { return wxColour(255, 0, 0); } + wxColour GetLineColor() const { return wxColour(0, 255, 0); } UINT GetLineWidth() const { return 3; } // Coordinate scaling... public: - [[nodiscard]] CPoint WorkspaceToClient(CPoint point) const; - [[nodiscard]] CRect WorkspaceToClient(CRect rect) const; - [[nodiscard]] CPoint ClientToWorkspace(CPoint point) const; - [[nodiscard]] CRect ClientToWorkspace(CRect rect) const; - void InvalidateWorkspaceRect(const CRect& pRect, BOOL bErase = FALSE); + [[nodiscard]] wxPoint WorkspaceToClient(wxPoint point) const; + [[nodiscard]] wxRect WorkspaceToClient(wxRect rect) const; + [[nodiscard]] wxPoint ClientToWorkspace(wxPoint point) const; + [[nodiscard]] wxRect ClientToWorkspace(wxRect rect) const; + void InvalidateWorkspaceRect(const wxRect& pRect, BOOL bErase = FALSE); // View support public: - void ScrollWorkspacePointIntoView(CPoint point); - void CenterViewOnWorkspacePoint(CPoint point); - BOOL CheckAutoScroll(CPoint point); - BOOL ProcessAutoScroll(CPoint point); + void ScrollWorkspacePointIntoView(wxPoint point); + void CenterViewOnWorkspacePoint(wxPoint point); + BOOL CheckAutoScroll(wxPoint point); + BOOL ProcessAutoScroll(wxPoint point); void SetOurScrollSizes(TileScale nZoom); void DoViewScaleBrd(TileScale nZoom); // Tooltip Support public: - void SetNotificationTip(CPoint pointClient, UINT nResID); - void SetNotificationTip(CPoint pointClient, const CB::string* pszTip); + void SetNotificationTip(wxPoint pointClient, UINT nResID); + void SetNotificationTip(wxPoint pointClient, const CB::string* pszTip); void ClearNotificationTip(); void ClearToolTip(); +#if 0 static void CALLBACK NotificationTipTimeoutHandler(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime); - void DoToolTipHitProcessing(CPoint pointClient); +#endif + void DoToolTipHitProcessing(wxPoint pointClient); // Grid and limiting support protected: @@ -133,42 +135,55 @@ class CPlayBoardView : public CScrollView void GridizeX(int& xPos) const; void GridizeY(int& yPos) const; #endif - [[nodiscard]] POINT LimitPoint(POINT pPnt) const; - [[nodiscard]] RECT LimitRect(RECT pRct) const; - BOOL IsRectFullyOnBoard(const RECT& pRct, BOOL* pbXOK = NULL, BOOL* pbYOK = NULL) const; + [[nodiscard]] wxPoint LimitPoint(wxPoint pPnt) const; + [[nodiscard]] wxRect LimitRect(wxRect pRct) const; + BOOL IsRectFullyOnBoard(const wxRect& pRct, BOOL* pbXOK = NULL, BOOL* pbYOK = NULL) const; // Implementation +private: + // member declaration order determines construction order + RefPtr parent; + RefPtr document; protected: - CB::propagate_const m_pPBoard; // Board that contains selections etc... + RefPtr m_pPBoard; // Board that contains selections etc... TileScale m_nZoom; // Current zoom level of view // -------- // BOOL m_bInDrag; // Currently being dragged over CB::propagate_const m_pDragSelList; // Pointer the select list being dragged +#if 0 uintptr_t m_nTimerID; // Used to control autoscrolls +#endif // -------- // UINT m_nCurToolID; // Current tool ID // -------- // - CToolTipCtrl m_toolMsgTip; // Tooltip for notifications - CToolTipCtrl m_toolHitTip; // Tooltip hit support for view + CB::ToolTip m_toolMsgTip; // Tooltip for notifications + CB::ToolTip m_toolHitTip; // Tooltip hit support for view + wxRect m_toolHitTipRect = wxRect(); CB::propagate_const m_pCurTipObj; // Currently hit tip object // Tables used to process relative piece rotations. DON'T Serialize! BOOL m_bWheelRotation; // Indicates the type of rotation being done - CPoint m_pntWheelMid; // The wheel rotation point + wxPoint m_pntWheelMid; // The wheel rotation point std::vector m_tblCurAngles; // Original angles of pieces std::vector> m_tblCurPieces; // Pieces being rotated - std::vector m_tblMidPnt; // X coord of piece midpoint + std::vector m_tblMidPnt; // X coord of piece midpoint // Implementation protected: BOOL IsBoardContentsAvailableToCurrentPlayer() const; - void AddPiece(CPoint pnt, PieceID pid); + void AddPiece(wxPoint pnt, PieceID pid); PToolType MapToolType(UINT nToolResID) const; - void SetupDrawListDC(CDC& pDC, CRect& pRct) const; - void RestoreDrawListDC(CDC& pDC) const; + class DCSetupDrawListDC + { + public: + DCSetupDrawListDC(const CPlayBoardView& rThis, wxDC& dc, wxRect& pRct); + private: + CB::DCUserScaleChanger scaleChanger; + CB::DCLogicalOriginChanger logOrgChanger; + }; LRESULT DoDragPiece(const DragInfo& pdi); LRESULT DoDragMarker(const DragInfo& pdi); @@ -182,23 +197,26 @@ class CPlayBoardView : public CScrollView void DoAutostackOfSelectedObjects(int xStagger, int yStagger); void DoRotateRelative(BOOL bWheelRotation); +#if 0 BOOL DoMouseWheelFix(UINT fFlags, short zDelta, CPoint point); +#endif protected: - void OnInitialUpdate() override; - void OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint) override; + void OnInitialUpdate(); + void OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint); +#if 0 BOOL PreCreateWindow(CREATESTRUCT& cs) override; BOOL PreTranslateMessage(MSG* pMsg) override; +#endif void OnActivateView(BOOL bActivate, CView* pActivateView, - CView* pDeactiveView) override; + CView* pDeactiveView); -// Generated message map functions protected: - //{{AFX_MSG(CPlayBoardView) - afx_msg void OnViewFullScaleBrd(); - afx_msg void OnUpdateViewFullScaleBrd(CCmdUI* pCmdUI); - afx_msg void OnViewHalfScaleBrd(); - afx_msg void OnUpdateViewHalfScaleBrd(CCmdUI* pCmdUI); + void OnViewFullScaleBrd(wxCommandEvent& event); + void OnUpdateViewFullScaleBrd(wxUpdateUIEvent& pCmdUI); + void OnViewHalfScaleBrd(wxCommandEvent& event); + void OnUpdateViewHalfScaleBrd(wxUpdateUIEvent& pCmdUI); +#if 0 afx_msg LRESULT OnDragItem(WPARAM wParam, LPARAM lParam); afx_msg LRESULT OnMessageRotateRelative(WPARAM wParam, LPARAM lParam); afx_msg LRESULT OnMessageCenterBoardOnPoint(WPARAM wParam, LPARAM lParam); @@ -233,8 +251,10 @@ class CPlayBoardView : public CScrollView afx_msg void OnUpdateEditSelAllMarkers(CCmdUI* pCmdUI); afx_msg void OnActRotate(); afx_msg void OnUpdateActRotate(CCmdUI* pCmdUI); - afx_msg void OnViewToggleScale(); - afx_msg void OnUpdateViewToggleScale(CCmdUI* pCmdUI); +#endif + void OnViewToggleScale(wxCommandEvent& event); + void OnUpdateViewToggleScale(wxUpdateUIEvent& pCmdUI); +#if 0 afx_msg void OnViewPieces(); afx_msg void OnUpdateViewPieces(CCmdUI* pCmdUI); afx_msg void OnEditCopy(); @@ -263,30 +283,48 @@ class CPlayBoardView : public CScrollView afx_msg void OnUpdateActReleaseOwnership(CCmdUI* pCmdUI); afx_msg void OnActSetOwner(); afx_msg void OnUpdateActSetOwner(CCmdUI* pCmdUI); - afx_msg void OnViewSmallScaleBoard(); - afx_msg void OnUpdateViewSmallScaleBoard(CCmdUI* pCmdUI); - afx_msg void OnViewBoardRotate180(); - afx_msg void OnUpdateViewBoardRotate180(CCmdUI* pCmdUI); +#endif + void OnViewSmallScaleBoard(wxCommandEvent& event); + void OnUpdateViewSmallScaleBoard(wxUpdateUIEvent& pCmdUI); + void OnViewBoardRotate180(wxCommandEvent& event); + void OnUpdateViewBoardRotate180(wxUpdateUIEvent& pCmdUI); +#if 0 afx_msg BOOL OnMouseWheel(UINT nFlags, short zDelta, CPoint pt); - //}}AFX_MSG afx_msg void OnSelectGroupMarkers(UINT nID); afx_msg void OnUpdateSelectGroupMarkers(CCmdUI* pCmdUI, UINT nID); afx_msg void OnRotatePiece(UINT nID); afx_msg void OnUpdateRotatePiece(CCmdUI* pCmdUI, UINT nID); - afx_msg LRESULT OnMessageWindowState(WPARAM wParam, LPARAM lParam); +#endif + void OnMessageWindowState(WinStateEvent& event); +#if 0 afx_msg LRESULT OnMessageSelectBoardObjectList(WPARAM wParam, LPARAM lParam); - DECLARE_MESSAGE_MAP() +#endif + void OnScrollWinLine(wxScrollWinEvent& event); + wxDECLARE_EVENT_TABLE(); +#if 0 public: afx_msg void OnActRotateGroupRelative(); afx_msg void OnUpdateActRotateGroupRelative(CCmdUI *pCmdUI); +#endif + +private: + // IGetCmdTarget + CCmdTarget& Get() override; + + /* This view should support scrolling by individual pixels, + but don't make the line-up and line-down scrolling that + slow. */ + int m_xScrollPixelsPerLine; + int m_yScrollPixelsPerLine; }; #ifndef _DEBUG // debug version in vwmbrd.cpp inline const CGamDoc& CPlayBoardView::GetDocument() const - { return *CB::ToCGamDoc(m_pDocument); } + { return *document; } #endif -class CPlayBoardViewContainer : public CView +class CPlayBoardViewContainer : public CB::OnCmdMsgOverride, + public CB::wxNativeContainerWindowMixin { public: void OnDraw(CDC* pDC) override; @@ -296,6 +334,10 @@ class CPlayBoardViewContainer : public CView return const_cast(static_cast(std::as_const(*this))); } + void OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint) override; + void OnActivateView(BOOL bActivate, CView* pActivateView, + CView* pDeactiveView) override; + private: CPlayBoardViewContainer(); // used by dynamic creation DECLARE_DYNCREATE(CPlayBoardViewContainer) @@ -305,9 +347,22 @@ class CPlayBoardViewContainer : public CView afx_msg LRESULT OnMessageWindowState(WPARAM wParam, LPARAM lParam); DECLARE_MESSAGE_MAP() - // owned by MFC - RefPtr child; + // IGetEvtHandler + wxEvtHandler& Get() override + { + return CheckedDeref(CheckedDeref(child).GetEventHandler()); + } + + // owned by wx + CB::propagate_const child = nullptr; + + typedef CB::OnCmdMsgOverride BASE; }; +inline CCmdTarget& CPlayBoardView::Get() +{ + return *parent; +} + ///////////////////////////////////////////////////////////////////////////// diff --git a/GP/VwPbrd1.cpp b/GP/VwPbrd1.cpp index 9cd9957d..b1d2bd2a 100644 --- a/GP/VwPbrd1.cpp +++ b/GP/VwPbrd1.cpp @@ -50,18 +50,22 @@ const int scrollZone = 16; ////////////////////////////////////////////////////////////////////// -void CPlayBoardView::DoToolTipHitProcessing(CPoint pointClient) +void CPlayBoardView::DoToolTipHitProcessing(wxPoint pointClient) { CGamDoc& pDoc = GetDocument(); if (!pDoc.IsShowingObjectTips() && pDoc.IsOwnerTipsDisabled()) { // Delete previous tool definition - m_toolHitTip.DelTool(this, ID_TIP_PLAYBOARD_HIT); + if (!m_toolHitTipRect.IsEmpty()) + { + m_toolHitTip.Delete(*this, m_toolHitTipRect); + m_toolHitTipRect = wxRect(); + } m_pCurTipObj = NULL; return; } - CPoint pnt(pointClient); + wxPoint pnt(pointClient); pnt = ClientToWorkspace(pnt); CDrawObj* pDObj = ObjectHitTest(pnt); @@ -87,12 +91,16 @@ void CPlayBoardView::DoToolTipHitProcessing(CPoint pointClient) if (pDObj != m_pCurTipObj) { // Object changed so delete previous tool definition - m_toolHitTip.DelTool(this, ID_TIP_PLAYBOARD_HIT); + if (!m_toolHitTipRect.IsEmpty()) + { + m_toolHitTip.Delete(*this, m_toolHitTipRect); + m_toolHitTipRect = wxRect(); + } m_pCurTipObj = pDObj; if (pDObj != NULL) { // New object found so create a new tip - CRect rct = pDObj->GetRect(); + wxRect rct = CB::Convert(pDObj->GetRect()); rct = WorkspaceToClient(rct); CB::string strTip; @@ -134,43 +142,53 @@ void CPlayBoardView::DoToolTipHitProcessing(CPoint pointClient) } if (!strTip.empty()) { - m_toolHitTip.AddTool(this, strTip, rct, ID_TIP_PLAYBOARD_HIT); + m_toolHitTip.Add(*this, rct, strTip); + m_toolHitTipRect = rct; - m_toolHitTip.Activate(TRUE); + m_toolHitTip.Enable(TRUE); } else { // Delete previous tool definition - m_toolHitTip.DelTool(this, ID_TIP_PLAYBOARD_HIT); + if (!m_toolHitTipRect.IsEmpty()) + { + m_toolHitTip.Delete(*this, m_toolHitTipRect); + m_toolHitTipRect = wxRect(); + } m_pCurTipObj = NULL; return; } } else - m_toolHitTip.Activate(FALSE); + m_toolHitTip.Enable(FALSE); } } void CPlayBoardView::ClearToolTip() { // Object changed so delete previous tool definition - m_toolHitTip.DelTool(this, ID_TIP_PLAYBOARD_HIT); + if (!m_toolHitTipRect.IsEmpty()) + { + m_toolHitTip.Delete(*this, m_toolHitTipRect); + m_toolHitTipRect = wxRect(); + } m_pCurTipObj = NULL; - m_toolHitTip.Activate(FALSE); + m_toolHitTip.Enable(FALSE); } ////////////////////////////////////////////////////////////////////// -void CPlayBoardView::SetNotificationTip(CPoint pointClient, UINT nResID) +void CPlayBoardView::SetNotificationTip(wxPoint pointClient, UINT nResID) { CB::string str = CB::string::LoadString(nResID); SetNotificationTip(pointClient, &str); } -void CPlayBoardView::SetNotificationTip(CPoint pointClient, const CB::string* pszTip) +void CPlayBoardView::SetNotificationTip(wxPoint pointClient, const CB::string* pszTip) { ClearNotificationTip(); +#if 0 TOOLINFO ti; m_toolMsgTip.FillInToolInfo(ti, this, ID_TIP_PLAYBOARD_MSG); ti.uFlags |= TTF_TRACK; @@ -187,10 +205,14 @@ void CPlayBoardView::SetNotificationTip(CPoint pointClient, const CB::string* ps (LPARAM)MAKELONG(static_cast(pointScreen.x), static_cast(pointScreen.y))); SetTimer(ID_TIP_MSG_TIMER, MAX_TIP_MSG_TIME, NotificationTipTimeoutHandler); +#else + wxASSERT(!"TODO:"); +#endif } void CPlayBoardView::ClearNotificationTip() { +#if 0 KillTimer(ID_TIP_MSG_TIMER); // Kill it in case it's still running CToolInfo ti; @@ -198,8 +220,12 @@ void CPlayBoardView::ClearNotificationTip() m_toolMsgTip.SendMessage(TTM_TRACKACTIVATE, (WPARAM)FALSE, (LPARAM)&ti); m_toolMsgTip.DelTool(this, ID_TIP_PLAYBOARD_MSG); m_toolMsgTip.Activate(FALSE); +#else + wxASSERT(!"TODO:"); +#endif } +#if 0 void CALLBACK CPlayBoardView::NotificationTipTimeoutHandler(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime) { @@ -207,18 +233,19 @@ void CALLBACK CPlayBoardView::NotificationTipTimeoutHandler(HWND hwnd, ASSERT(pView != NULL); pView->ClearNotificationTip(); } +#endif ////////////////////////////////////////////////////////////////////// -CDrawObj* CPlayBoardView::ObjectHitTest(CPoint point) +CDrawObj* CPlayBoardView::ObjectHitTest(wxPoint point) { CDrawList& pDwg = CheckedDeref(m_pPBoard->GetPieceList()); - return pDwg.HitTest(point); + return pDwg.HitTest(CB::Convert(point)); } ////////////////////////////////////////////////////////////////////// -void CPlayBoardView::SelectWithinRect(CRect rctNet, BOOL bInclIntersects) +void CPlayBoardView::SelectWithinRect(wxRect rctNet, BOOL bInclIntersects) { CGamDoc& pDoc = GetDocument(); CDrawList& pDwg = CheckedDeref(m_pPBoard->GetPieceList()); @@ -230,9 +257,9 @@ void CPlayBoardView::SelectWithinRect(CRect rctNet, BOOL bInclIntersects) if (!m_selList.IsObjectSelected(pObj)) { if ((!bInclIntersects && - ((pObj.GetEnclosingRect() | rctNet) == rctNet)) || + ((CB::Convert(pObj.GetEnclosingRect()).Union(rctNet)) == rctNet)) || (bInclIntersects && - (!(pObj.GetEnclosingRect() & rctNet).IsRectEmpty()))) + (!(CB::Convert(pObj.GetEnclosingRect()).Intersect(rctNet)).IsEmpty()))) { BOOL bOwnedByCurrentPlayer = TRUE; if (pObj.GetType() == CDrawObj::drawPieceObj) @@ -270,15 +297,15 @@ void CPlayBoardView::SelectWithinRect(CRect rctNet, BOOL bInclIntersects) NotifySelectListChange(); } -void CPlayBoardView::SelectAllUnderPoint(CPoint point) +void CPlayBoardView::SelectAllUnderPoint(wxPoint point) { CDrawList* pDwg = m_pPBoard->GetPieceList(); - ASSERT(pDwg); + wxASSERT(pDwg); BOOL bPieceSelected = FALSE; std::vector> selLst; - pDwg->DrillDownHitTest(point, selLst); + pDwg->DrillDownHitTest(CB::Convert(point), selLst); for (size_t i = size_t(0) ; i < selLst.size() ; ++i) { @@ -446,83 +473,80 @@ void CPlayBoardView::MoveObjsInSelectList(BOOL bToFront, BOOL bInvalidate) ///////////////////////////////////////////////////////////////////////////// -CPoint CPlayBoardView::GetWorkspaceDim() const +wxPoint CPlayBoardView::GetWorkspaceDim() const { // First get MM_TEXT size of board for this scaling mode. - CPoint pnt = (CPoint)m_pPBoard->GetBoard()->GetSize(m_nZoom); + wxSize size = CB::Convert(m_pPBoard->GetBoard()->GetSize(m_nZoom)); + wxPoint pnt(size.x, size.y); // Translate to current scaling mode. - pnt -= (CSize)GetDeviceScrollPosition(); + pnt = CalcScrolledPosition(pnt); pnt = ClientToWorkspace(pnt); return pnt; } ///////////////////////////////////////////////////////////////////////////// -CPoint CPlayBoardView::WorkspaceToClient(CPoint point) const +wxPoint CPlayBoardView::WorkspaceToClient(wxPoint point) const { - CPoint dpnt = GetDeviceScrollPosition(); - CSize wsize, vsize; + wxSize wsize, vsize; m_pPBoard->GetBoard()->GetBoardArray(). GetBoardScaling(m_nZoom, wsize, vsize); if (m_pPBoard->IsBoardRotated180()) - point = CPoint(wsize.cx - point.x, wsize.cy - point.y); + point = wxPoint(wsize.x - point.x, wsize.y - point.y); ScalePoint(point, vsize, wsize); - point -= (CSize)dpnt; + point = CalcScrolledPosition(point); return point; } -CRect CPlayBoardView::WorkspaceToClient(CRect rect) const +wxRect CPlayBoardView::WorkspaceToClient(wxRect rect) const { - CPoint dpnt = GetDeviceScrollPosition(); - CSize wsize, vsize; + wxSize wsize, vsize; m_pPBoard->GetBoard()->GetBoardArray(). GetBoardScaling(m_nZoom, wsize, vsize); if (m_pPBoard->IsBoardRotated180()) { - rect = CRect(wsize.cx - rect.left, wsize.cy - rect.top, - wsize.cx - rect.right, wsize.cy - rect.bottom); - rect.NormalizeRect(); + rect = wxRect(wxPoint(wsize.x - rect.GetLeft(), wsize.y - rect.GetTop()), + wxSize(-rect.GetWidth(), -rect.GetHeight())); + CB::Normalize(rect); } ScaleRect(rect, vsize, wsize); - rect -= dpnt; + rect.SetLeftTop(CalcScrolledPosition(rect.GetTopLeft())); return rect; } -void CPlayBoardView::InvalidateWorkspaceRect(const CRect& pRect, BOOL bErase) +void CPlayBoardView::InvalidateWorkspaceRect(const wxRect& pRect, BOOL bErase) { - CRect rct(pRect); + wxRect rct(pRect); rct = WorkspaceToClient(rct); - rct.InflateRect(1, 1); - InvalidateRect(&rct, bErase); + rct.Inflate(1, 1); + RefreshRect(rct, bErase); } -CPoint CPlayBoardView::ClientToWorkspace(CPoint point) const +wxPoint CPlayBoardView::ClientToWorkspace(wxPoint point) const { - CPoint dpnt = GetDeviceScrollPosition(); - point += (CSize)dpnt; - CSize wsize, vsize; + point = CalcUnscrolledPosition(point); + wxSize wsize, vsize; m_pPBoard->GetBoard()->GetBoardArray(). GetBoardScaling(m_nZoom, wsize, vsize); ScalePoint(point, wsize, vsize); if (m_pPBoard->IsBoardRotated180()) - point = CPoint(wsize.cx - point.x, wsize.cy - point.y); + point = wxPoint(wsize.x - point.x, wsize.y - point.y); return point; } -CRect CPlayBoardView::ClientToWorkspace(CRect rect) const +wxRect CPlayBoardView::ClientToWorkspace(wxRect rect) const { - CPoint dpnt = GetDeviceScrollPosition(); - rect += dpnt; - CSize wsize, vsize; + rect.SetLeftTop(CalcUnscrolledPosition(rect.GetLeftTop())); + wxSize wsize, vsize; m_pPBoard->GetBoard()->GetBoardArray(). GetBoardScaling(m_nZoom, wsize, vsize); ScaleRect(rect, wsize, vsize); if (m_pPBoard->IsBoardRotated180()) { - rect = CRect(wsize.cx - rect.left, wsize.cy - rect.top, - wsize.cx - rect.right, wsize.cy - rect.bottom); - rect.NormalizeRect(); + rect = wxRect(wxPoint(wsize.x - rect.GetLeft(), wsize.y - rect.GetTop()), + wxSize(-rect.GetWidth(), -rect.GetHeight())); + CB::Normalize(rect); } return rect; } @@ -556,7 +580,7 @@ long CPlayBoardView::GridizeY(long yPos) const return yPos; } -POINT CPlayBoardView::LimitPoint(POINT pPnt) const +wxPoint CPlayBoardView::LimitPoint(wxPoint pPnt) const { const CBoard* pBoard = m_pPBoard->GetBoard(); if (pPnt.x < 0) pPnt.x = 0; @@ -568,37 +592,35 @@ POINT CPlayBoardView::LimitPoint(POINT pPnt) const return pPnt; } -RECT CPlayBoardView::LimitRect(RECT pRct) const +wxRect CPlayBoardView::LimitRect(wxRect rct) const { - CRect rct(pRct); const CBoard* pBoard = m_pPBoard->GetBoard(); - if (rct.left < 0) - rct.OffsetRect(-rct.left, 0); - if (rct.top < 0) - rct.OffsetRect(0, -rct.top); - if (rct.right > pBoard->GetWidth(fullScale)) - rct.OffsetRect(pBoard->GetWidth(fullScale) - rct.right, 0); - if (rct.bottom > pBoard->GetHeight(fullScale)) - rct.OffsetRect(0, pBoard->GetHeight(fullScale) - rct.bottom); - pRct = rct; - return pRct; + if (rct.GetLeft() < 0) + rct.Offset(-rct.GetLeft(), 0); + if (rct.GetTop() < 0) + rct.Offset(0, -rct.GetTop()); + if (rct.GetRight() > pBoard->GetWidth(fullScale)) + rct.Offset(pBoard->GetWidth(fullScale) - rct.GetRight(), 0); + if (rct.GetBottom() > pBoard->GetHeight(fullScale)) + rct.Offset(0, pBoard->GetHeight(fullScale) - rct.GetBottom()); + return rct; } -BOOL CPlayBoardView::IsRectFullyOnBoard(const RECT& pRct, BOOL* pbXOK, BOOL* pbYOK) const +BOOL CPlayBoardView::IsRectFullyOnBoard(const wxRect& pRct, BOOL* pbXOK, BOOL* pbYOK) const { - CRect rct(pRct); + wxRect rct(pRct); const CBoard* pBoard = m_pPBoard->GetBoard(); BOOL bXOK = TRUE; BOOL bYOK = TRUE; BOOL bOK = TRUE; - if (rct.left < 0 || rct.right > pBoard->GetWidth(fullScale)) + if (rct.GetLeft() < 0 || rct.GetRight() > pBoard->GetWidth(fullScale)) { bXOK = FALSE; bOK = FALSE; } - if (rct.top < 0 || rct.bottom > pBoard->GetHeight(fullScale)) + if (rct.GetTop() < 0 || rct.GetBottom() > pBoard->GetHeight(fullScale)) { bYOK = FALSE; bOK = FALSE; @@ -608,7 +630,7 @@ BOOL CPlayBoardView::IsRectFullyOnBoard(const RECT& pRct, BOOL* pbXOK, BOOL* pbY return bOK; } -CPoint CPlayBoardView::AdjustPoint(CPoint pnt) const +wxPoint CPlayBoardView::AdjustPoint(wxPoint pnt) const { pnt.x = GridizeX(pnt.x); pnt.y = GridizeY(pnt.y); @@ -616,13 +638,13 @@ CPoint CPlayBoardView::AdjustPoint(CPoint pnt) const return pnt; } -CRect CPlayBoardView::AdjustRect(CRect rct) const +wxRect CPlayBoardView::AdjustRect(wxRect rct) const { - CPoint pnt; + wxPoint pnt; if (m_pPBoard->m_bGridRectCenters) pnt = GetMidRect(rct); else - pnt = rct.TopLeft(); + pnt = rct.GetLeftTop(); pnt.x = GridizeX(pnt.x); pnt.y = GridizeY(pnt.y); @@ -631,12 +653,12 @@ CRect CPlayBoardView::AdjustRect(CRect rct) const if (m_pPBoard->m_bGridRectCenters) { if (pnt != GetMidRect(rct)) - rct.OffsetRect(pnt - GetMidRect(rct)); + rct.Offset(pnt - GetMidRect(rct)); } else { - if (pnt != rct.TopLeft()) - rct.OffsetRect(pnt - rct.TopLeft()); + if (pnt != rct.GetLeftTop()) + rct.Offset(pnt - rct.GetLeftTop()); } rct = LimitRect(rct); return rct; @@ -644,44 +666,43 @@ CRect CPlayBoardView::AdjustRect(CRect rct) const ////////////////////////////////////////////////////////////////////// -void CPlayBoardView::ScrollWorkspacePointIntoView(CPoint point) +void CPlayBoardView::ScrollWorkspacePointIntoView(wxPoint point) { - CRect rct; - GetClientRect(&rct); - if ((rct.Height() < 2 * viewZone) || (rct.Width() < 2 * viewZone)) + wxRect rct = GetClientRect(); + if ((rct.GetHeight() < 2 * viewZone) || (rct.GetWidth() < 2 * viewZone)) { // Attempt to center point. CenterViewOnWorkspacePoint(point); return; } - rct.InflateRect(-viewZone, -viewZone); + rct.Inflate(-viewZone, -viewZone); rct = ClientToWorkspace(rct); - if (rct.PtInRect(point)) + if (rct.Contains(point)) return; // Everthing is ok CenterViewOnWorkspacePoint(point); } -void CPlayBoardView::CenterViewOnWorkspacePoint(CPoint point) +void CPlayBoardView::CenterViewOnWorkspacePoint(wxPoint point) { point = WorkspaceToClient(point); - CRect rct; - GetClientRect(&rct); - CPoint pt = GetMidRect(rct); - CSize size = point - pt; - CPoint newUpLeft = GetDeviceScrollPosition() + size; + wxRect rct = GetClientRect(); + wxPoint pt = GetMidRect(rct); + wxPoint size = point - pt; + wxPoint newUpLeft = CalcUnscrolledPosition(size); // If the axis being scrolled is entirely visible then set // that scroll position to zero. - CSize sizeTotal = GetTotalSize(); // Logical is in device units for us - if (rct.Width() >= sizeTotal.cx) + wxSize sizeTotal = GetVirtualSize(); // Logical is in device units for us + if (rct.GetWidth() >= sizeTotal.x) newUpLeft.x = 0; - if (rct.Height() >= sizeTotal.cy) + if (rct.GetHeight() >= sizeTotal.y) newUpLeft.y = 0; - ScrollToPosition(newUpLeft); - UpdateWindow(); + Scroll(newUpLeft); + Update(); } +#if 0 ////////////////////////////////////////////////////////////////////////// // point is in client coords @@ -734,5 +755,6 @@ BOOL CPlayBoardView::ProcessAutoScroll(CPoint point) } return FALSE; } +#endif diff --git a/GP/VwPrjga1.cpp b/GP/VwPrjga1.cpp index 6ba3dcc9..cf881eef 100644 --- a/GP/VwPrjga1.cpp +++ b/GP/VwPrjga1.cpp @@ -31,6 +31,7 @@ #include "Trays.h" #include "MoveHist.h" +#include "VwPbrd.h" #include "VwPrjgam.h" #ifdef _DEBUG @@ -105,7 +106,7 @@ void CGamProjView::DoBoardView() AfxMessageBox(IDS_ERR_PRIVATE_BOARD_PERM, MB_OK | MB_ICONEXCLAMATION); return; } - CView* pView = pDoc->FindPBoardView(pPBoard); + CPlayBoardView* pView = pDoc->FindPBoardView(pPBoard); if (pView != NULL) { // This board already has an editor. Activate that view. diff --git a/GP/VwPrjgs1.cpp b/GP/VwPrjgs1.cpp index 5edadb3f..b83e8d56 100644 --- a/GP/VwPrjgs1.cpp +++ b/GP/VwPrjgs1.cpp @@ -32,6 +32,7 @@ #include "Trays.h" #include "Player.h" +#include "VwPbrd.h" #include "VwPrjgsn.h" #include "DlgScnp.h" @@ -96,7 +97,7 @@ void CGsnProjView::DoBoardView() size_t nBrd = m_listProj->GetItemSourceCode(value_preserving_cast(nSel)); CPlayBoard& pPBoard = pDoc.GetPBoardManager().GetPBoard(nBrd); - CView* pView = pDoc.FindPBoardView(pPBoard); + CPlayBoardView* pView = pDoc.FindPBoardView(pPBoard); if (pView != NULL) { // This board already has an editor. Activate that view. diff --git a/GP/WStateGp.cpp b/GP/WStateGp.cpp index ea376447..56fae8a0 100644 --- a/GP/WStateGp.cpp +++ b/GP/WStateGp.cpp @@ -29,6 +29,7 @@ #include "FrmProj.h" #include "Board.h" #include "PBoard.h" +#include "VwPbrd.h" #include "WStateGp.h" enum { gpFrmProject = 0, gpFrmPlayBoard = 1 }; @@ -48,7 +49,7 @@ CWnd* CGpWinStateMgr::OnGetFrameForWinStateElement(const CWinStateElement& pWse) { // The second user code is the board's serial number. CPlayBoard& pPBoard = CheckedDeref(pDoc->GetPBoardManager().GetPBoardBySerial(pWse.m_boardID)); - CView* pView = pDoc->FindPBoardView(pPBoard); + CPlayBoardView* pView = pDoc->FindPBoardView(pPBoard); if (pView == NULL) { // No frame open for board. Create it. diff --git a/GShr/LibMfc.cpp b/GShr/LibMfc.cpp index 26723077..2593e8bf 100644 --- a/GShr/LibMfc.cpp +++ b/GShr/LibMfc.cpp @@ -1336,6 +1336,16 @@ namespace CB return XRCID("ID_PPROJITEM_PROPERTIES"); case ID_PPROJITEM_VIEW: return XRCID("ID_PPROJITEM_VIEW"); + case ID_VIEW_BOARD_ROTATE180: + return XRCID("ID_VIEW_BOARD_ROTATE180"); + case ID_VIEW_FULLSCALEBRD: + return XRCID("ID_VIEW_FULLSCALEBRD"); + case ID_VIEW_HALFSCALEBRD: + return XRCID("ID_VIEW_HALFSCALEBRD"); + case ID_VIEW_SMALLSCALEBRD: + return XRCID("ID_VIEW_SMALLSCALEBRD"); + case ID_VIEW_TOGGLESCALE: + return XRCID("ID_VIEW_TOGGLESCALE"); default: return wxID_NONE; } From 967b66b561649e700b90cd14b3561da5631d49b5 Mon Sep 17 00:00:00 2001 From: Bill Su Date: Mon, 20 Oct 2025 00:51:10 -0400 Subject: [PATCH 43/80] VwPbrd: wxOverlay demo --- GP/ToolPlay.cpp | 80 ++++++++++++++++--------------------------------- GP/ToolPlay.h | 4 +-- GP/VwPbrd.cpp | 37 +++++++++++++++++++++-- GP/VwPbrd.h | 7 ++++- 4 files changed, 68 insertions(+), 60 deletions(-) diff --git a/GP/ToolPlay.cpp b/GP/ToolPlay.cpp index 2756a91d..7cfe7120 100644 --- a/GP/ToolPlay.cpp +++ b/GP/ToolPlay.cpp @@ -145,13 +145,10 @@ void CPSelectTool::OnLButtonDown(CPlayBoardView& pView, UINT nFlags, // No objects were under the mouse click. m_eSelMode = smodeNet; // Net type selection CPlayTool::OnLButtonDown(pView, nFlags, point); -#if 0 - CClientDC dc(&pView); - pView.OnPrepareScaledDC(dc, TRUE); + wxOverlayDC dc(pView.GetOverlay(), &pView); + pView.OnPrepareScaledDC(dc, true); + dc.Clear(); DrawNetRect(dc, pView); -#else - wxASSERT(!"TODO: overlay"); -#endif return; } // Object is under mouse. See if also selected. If not, @@ -238,15 +235,11 @@ void CPSelectTool::OnMouseMove(CPlayBoardView& pView, UINT nFlags, CPoint point) // we are doing a "net select". if (m_eSelMode == smodeNet) { -#if 0 - CClientDC dc(&pView); - pView.OnPrepareScaledDC(dc, TRUE); - DrawNetRect(dc, pView); // Erase previous position + wxOverlayDC dc(pView.GetOverlay(), &pView); + pView.OnPrepareScaledDC(dc, true); + dc.Clear(); CPlayTool::OnMouseMove(pView, nFlags, point); // Update position DrawNetRect(dc, pView); // Draw new position rect -#else - wxASSERT(!"TODO: overlay"); -#endif return; } // If object(s) are being moved or sized, removed last tracking @@ -264,18 +257,13 @@ void CPSelectTool::OnMouseMove(CPlayBoardView& pView, UINT nFlags, CPoint point) if (point == c_ptLast) return; -#if 0 - CClientDC dc(&pView); - pView.OnPrepareScaledDC(dc, TRUE); - - pSLst.DrawTracker(dc, trkSizing); // Erase previous tracker + wxOverlayDC dc(pView.GetOverlay(), &pView); + pView.OnPrepareScaledDC(dc, true); + dc.Clear(); MoveSelections(pSLst, point); - pSLst.DrawTracker(dc, trkSizing); // Erase previous tracker -#else -wxASSERT(!"TODO: overlay"); -#endif + pSLst.DrawTracker(dc, trkSizing); // Draw tracker } c_ptLast = point; // Save new 'last' position } @@ -287,22 +275,16 @@ bool CPSelectTool::OnLButtonUp(CPlayBoardView& pView, UINT nFlags, CPoint point) { if (m_eSelMode == smodeNet) { -#if 0 - CClientDC dc(&pView); - pView.OnPrepareScaledDC(dc, TRUE); - DrawNetRect(dc, pView); // Erase previous position + pView.GetOverlay().Reset(); // If the control key is down when button was released, fields // that intersect the select rect will selected. Otherwise only // those fields that are entirely within the select rect // will be selected. - CRect rect(c_ptDown.x, c_ptDown.y, c_ptLast.x, c_ptLast.y); - rect.NormalizeRect(); + wxRect rect(wxPoint(std::min(c_ptDown.x, c_ptLast.x), std::min(c_ptDown.y, c_ptLast.y)), + wxSize(std::abs(c_ptLast.x - c_ptDown.x), std::abs(c_ptLast.y - c_ptDown.y))); pView.SelectWithinRect(rect, (nFlags & MK_CONTROL) != 0); CSelList& pSLst = pView.GetSelectList(); pSLst.InvalidateListHandles(); -#else -wxASSERT(!"TODO: overlay"); -#endif } else if (m_eSelMode != smodeNormal) { @@ -356,7 +338,7 @@ void CPSelectTool::OnTimer(CPlayBoardView& pView, uintptr_t nIDEvent) pView.OnPrepareScaledDC(dc, TRUE); pSLst.DrawTracker(dc, trkSelected); // Turn off handles #else - wxASSERT(!"TODO: overlay"); + wxASSERT(!"TODO:"); #endif CPoint point; @@ -423,37 +405,25 @@ void CPSelectTool::StartSizingOperation(CPlayBoardView& pView, UINT nFlags, m_nHandleID = nHandleID; m_eSelMode = smodeSizing; CPlayTool::OnLButtonDown(pView, nFlags, point); -#if 0 - CClientDC dc(&pView); - pView.OnPrepareScaledDC(dc, TRUE); + wxOverlayDC dc(pView.GetOverlay(), &pView); + pView.OnPrepareScaledDC(dc, true); + dc.Clear(); pSLst.DrawTracker(dc, trkSizing); -#else - wxASSERT(!"TODO: overlay"); -#endif } -void CPSelectTool::DrawSelectionRect(CDC& pDC, const CRect& pRct) const +void CPSelectTool::DrawSelectionRect(wxDC& pDC, const wxRect& pRct) const { - CPen pen; - pen.CreateStockObject(WHITE_PEN); - CPen* pPrvPen = pDC.SelectObject(&pen); - int nPrvROP2 = pDC.SetROP2(R2_XORPEN); - - pDC.MoveTo(pRct.TopLeft()); - pDC.LineTo(pRct.right, pRct.top); - pDC.LineTo(pRct.BottomRight()); - pDC.LineTo(pRct.left, pRct.bottom); - pDC.LineTo(pRct.TopLeft()); + wxDCPenChanger setPen(pDC, *wxLIGHT_GREY); + wxDCBrushChanger setBrush(pDC, *wxTRANSPARENT_BRUSH); - pDC.SetROP2(nPrvROP2); - pDC.SelectObject(pPrvPen); + pDC.DrawRectangle(pRct); } -void CPSelectTool::DrawNetRect(CDC& pDC, const CPlayBoardView& /*pView*/) const +void CPSelectTool::DrawNetRect(wxDC& pDC, const CPlayBoardView& /*pView*/) const { - CRect rect(c_ptDown.x, c_ptDown.y, c_ptLast.x, c_ptLast.y); - rect.NormalizeRect(); - DrawSelectionRect(pDC, &rect); + wxRect rect(wxPoint(std::min(c_ptDown.x, c_ptLast.x), std::min(c_ptDown.y, c_ptLast.y)), + wxSize(std::abs(c_ptLast.x - c_ptDown.x), std::abs(c_ptLast.y - c_ptDown.y))); + DrawSelectionRect(pDC, rect); } BOOL CPSelectTool::ProcessAutoScroll(CPlayBoardView& pView) diff --git a/GP/ToolPlay.h b/GP/ToolPlay.h index 8ddfed84..6d5ffdda 100644 --- a/GP/ToolPlay.h +++ b/GP/ToolPlay.h @@ -108,8 +108,8 @@ class CPSelectTool : public CPlayTool CRect m_rectMultiBorder; // ------- // BOOL ProcessAutoScroll(CPlayBoardView& pView); - void DrawSelectionRect(CDC& pDC, const CRect& pRct) const; - void DrawNetRect(CDC& pDC, const CPlayBoardView& pView) const; + void DrawSelectionRect(wxDC& pDC, const wxRect& pRct) const; + void DrawNetRect(wxDC& pDC, const CPlayBoardView& pView) const; [[nodiscard]] CPoint AdjustPoint(const CPlayBoardView& pView, CPoint point) const; void MoveSelections(CSelList &pSLst, const CPoint& point); void StartDragTimer(CPlayBoardView& pView); diff --git a/GP/VwPbrd.cpp b/GP/VwPbrd.cpp index e42ac976..d17245c1 100644 --- a/GP/VwPbrd.cpp +++ b/GP/VwPbrd.cpp @@ -67,7 +67,9 @@ wxBEGIN_EVENT_TABLE(CPlayBoardView, CPlayBoardView::BASE) ON_MESSAGE(WM_ROTATEPIECE_DELTA, OnMessageRotateRelative) ON_MESSAGE(WM_CENTERBOARDONPOINT, OnMessageCenterBoardOnPoint) ON_WM_LBUTTONDOWN() - ON_WM_MOUSEMOVE() +#endif + EVT_MOTION(OnMouseMove) +#if 0 ON_WM_LBUTTONUP() ON_WM_TIMER() ON_WM_LBUTTONDBLCLK() @@ -484,6 +486,14 @@ BOOL CPlayBoardView::PreTranslateMessage(MSG* pMsg) void CPlayBoardView::SetOurScrollSizes(TileScale nZoom) { + if (nZoom == fullScale) + { + /* KLUDGE: without this, the optimization in + wxDC::SetUserScale() that returns immediately if + the new scale equals the old scale sometimes + leaves the wxDC with wrong scale behavior */ + overlay = MakeOwner(); + } CBoard* pBoard = m_pPBoard->GetBoard(); wxSizer& sizer = CheckedDeref(GetSizer()); @@ -519,6 +529,7 @@ void CPlayBoardView::SetOurScrollSizes(TileScale nZoom) void CPlayBoardView::OnDraw(wxDC& pDC) { + GetOverlay().Reset(); CBoard* pBoard = m_pPBoard->GetBoard(); wxMemoryDC dcMem; wxRect oRct; @@ -1142,9 +1153,11 @@ void CPlayBoardView::OnLButtonDown(UINT nFlags, CPoint point) point = ClientToWorkspace(point); pTool.OnLButtonDown(*this, nFlags, point); } +#endif -void CPlayBoardView::OnMouseMove(UINT nFlags, CPoint point) +void CPlayBoardView::OnMouseMove(wxMouseEvent& event) { +#if 0 if (!IsBoardContentsAvailableToCurrentPlayer()) { CScrollView::OnMouseMove(nFlags, point); @@ -1162,8 +1175,22 @@ void CPlayBoardView::OnMouseMove(UINT nFlags, CPoint point) } else CScrollView::OnMouseMove(nFlags, point); +#else + wxPoint client = event.GetPosition(); + wxPoint workspace = ClientToWorkspace(client); + CPP20_TRACE("client {}, wkspc {}\n", client, workspace); + wxOverlayDC dc(GetOverlay(), this); + OnPrepareScaledDC(dc, true); + dc.Clear(); + wxDCPenChanger setPen(dc, *wxBLACK_PEN); + wxDCBrushChanger setBrush(dc, *wxBLACK_BRUSH); + CB::DrawEllipse(dc, wxRect(wxPoint(workspace.x - 20, workspace.y - 20), + wxPoint(workspace.x + 20, workspace.y + 20))); + event.Skip(); +#endif } +#if 0 void CPlayBoardView::OnLButtonUp(UINT nFlags, CPoint point) { if (!IsBoardContentsAvailableToCurrentPlayer()) @@ -1452,6 +1479,12 @@ void CPlayBoardView::OnUpdateViewToggleScale(wxUpdateUIEvent& pCmdUI) void CPlayBoardView::OnViewBoardRotate180(wxCommandEvent& /*event*/) { m_pPBoard->SetRotateBoard180(!m_pPBoard->IsBoardRotated180()); + if (m_nZoom == fullScale) + { + /* KLUDGE: without this, the wxDC soemtimes has the + wrong axis behavior */ + overlay = MakeOwner(); + } CGamDocHint hint; hint.GetArgs().m_pPBoard = m_pPBoard.get(); GetDocument().UpdateAllViews(NULL, HINT_UPDATEBOARD, &hint); diff --git a/GP/VwPbrd.h b/GP/VwPbrd.h index 857a3485..e929876f 100644 --- a/GP/VwPbrd.h +++ b/GP/VwPbrd.h @@ -55,6 +55,7 @@ class CPlayBoardView : public CB::ProcessEventOverride CGamDoc& GetDocument() { return const_cast(std::as_const(*this).GetDocument()); } const CPlayBoard& GetPlayBoard() const { return *m_pPBoard; } CPlayBoard& GetPlayBoard() { return const_cast(std::as_const(*this).GetPlayBoard()); } + wxOverlay& GetOverlay() { return *overlay; } CFrameWnd* GetParentFrame(); // Operations @@ -221,7 +222,9 @@ class CPlayBoardView : public CB::ProcessEventOverride afx_msg LRESULT OnMessageRotateRelative(WPARAM wParam, LPARAM lParam); afx_msg LRESULT OnMessageCenterBoardOnPoint(WPARAM wParam, LPARAM lParam); afx_msg void OnLButtonDown(UINT nFlags, CPoint point); - afx_msg void OnMouseMove(UINT nFlags, CPoint point); +#endif + void OnMouseMove(wxMouseEvent& event); +#if 0 afx_msg void OnLButtonUp(UINT nFlags, CPoint point); afx_msg void OnTimer(uintptr_t nIDEvent); afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point); @@ -316,6 +319,8 @@ class CPlayBoardView : public CB::ProcessEventOverride slow. */ int m_xScrollPixelsPerLine; int m_yScrollPixelsPerLine; + + OwnerPtr overlay = MakeOwner(); }; #ifndef _DEBUG // debug version in vwmbrd.cpp From 5721c7c0febf93e57b23857b7cd35c772258271b Mon Sep 17 00:00:00 2001 From: Bill Su Date: Sat, 18 Oct 2025 02:21:47 -0400 Subject: [PATCH 44/80] VwPbrd: basic mouse handling TODO: drag support --- GP/FrmPbrd.cpp | 25 +++-- GP/SelOPlay.cpp | 10 +- GP/SelOPlay.h | 10 +- GP/ToolPlay.cpp | 236 ++++++++++++++++++++++++------------------------ GP/ToolPlay.h | 92 +++++++++++-------- GP/VwPbrd.cpp | 137 +++++++++++++++++----------- GP/VwPbrd.h | 24 +++-- GP/VwPbrd1.cpp | 2 +- GShr/LibMfc.cpp | 6 ++ GShr/ResTbl.cpp | 4 +- GShr/ResTbl.h | 2 +- 11 files changed, 306 insertions(+), 242 deletions(-) diff --git a/GP/FrmPbrd.cpp b/GP/FrmPbrd.cpp index fa620d83..3fcbbe98 100644 --- a/GP/FrmPbrd.cpp +++ b/GP/FrmPbrd.cpp @@ -77,13 +77,13 @@ BEGIN_MESSAGE_MAP(CPlayBoardFrame, CMDIChildWndEx) ON_UPDATE_COMMAND_UI(ID_ACT_TURNOVER, OnUpdateActTurnOver) ON_UPDATE_COMMAND_UI(ID_ACT_TURNOVER_PREV, OnUpdateActTurnOver) ON_UPDATE_COMMAND_UI(ID_ACT_TURNOVER_RANDOM, OnUpdateActTurnOver) +#endif ON_COMMAND(ID_PTOOL_PLOTMOVE, OnActPlotMove) ON_UPDATE_COMMAND_UI(ID_PTOOL_PLOTMOVE, OnUpdateActPlotMove) ON_COMMAND(ID_ACT_PLOTDONE, OnActPlotDone) ON_UPDATE_COMMAND_UI(ID_ACT_PLOTDONE, OnUpdateActPlotDone) ON_COMMAND(ID_ACT_PLOTDISCARD, OnActPlotDiscard) ON_UPDATE_COMMAND_UI(ID_ACT_PLOTDISCARD, OnUpdateActPlotDiscard) -#endif ON_COMMAND(ID_VIEW_SPLITBOARDROWS, OnViewSplitBoardRows) ON_UPDATE_COMMAND_UI(ID_VIEW_SPLITBOARDROWS, OnUpdateViewSplitBoardRows) ON_COMMAND(ID_VIEW_SPLITBOARDCOLS, OnViewSplitBoardCols) @@ -585,37 +585,46 @@ void CPlayBoardFrame::OnUpdateActTurnOver(CCmdUI* pCmdUI) { GetActiveBoardView().OnUpdateActTurnOver(pCmdUI); } +#endif void CPlayBoardFrame::OnActPlotMove() { - GetActiveBoardView().OnActPlotMove(); + wxASSERT(!"dead code?"); + wxCommandEvent dummy; + GetActiveBoardView().OnActPlotMove(dummy); } void CPlayBoardFrame::OnUpdateActPlotMove(CCmdUI* pCmdUI) { - GetActiveBoardView().OnUpdateActPlotMove(pCmdUI); + wxASSERT(!"dead code?"); + CB_VERIFY(CB::RelayOnCmdMsg(GetActiveBoardView(), ID_PTOOL_PLOTMOVE, CN_UPDATE_COMMAND_UI, pCmdUI, nullptr)); } void CPlayBoardFrame::OnActPlotDone() { - GetActiveBoardView().OnActPlotDone(); + wxASSERT(!"dead code?"); + wxCommandEvent dummy; + GetActiveBoardView().OnActPlotDone(dummy); } void CPlayBoardFrame::OnUpdateActPlotDone(CCmdUI* pCmdUI) { - GetActiveBoardView().OnUpdateActPlotDone(pCmdUI); + wxASSERT(!"dead code?"); + CB_VERIFY(CB::RelayOnCmdMsg(GetActiveBoardView(), ID_ACT_PLOTDONE, CN_UPDATE_COMMAND_UI, pCmdUI, nullptr)); } void CPlayBoardFrame::OnActPlotDiscard() { - GetActiveBoardView().OnActPlotDiscard(); + wxASSERT(!"dead code?"); + wxCommandEvent dummy; + GetActiveBoardView().OnActPlotDiscard(dummy); } void CPlayBoardFrame::OnUpdateActPlotDiscard(CCmdUI* pCmdUI) { - GetActiveBoardView().OnUpdateActPlotDiscard(pCmdUI); + wxASSERT(!"dead code?"); + CB_VERIFY(CB::RelayOnCmdMsg(GetActiveBoardView(), ID_ACT_PLOTDISCARD, CN_UPDATE_COMMAND_UI, pCmdUI, nullptr)); } -#endif void CPlayBoardFrame::OnViewSplitBoardRows() { diff --git a/GP/SelOPlay.cpp b/GP/SelOPlay.cpp index 159e9e3e..ec55797d 100644 --- a/GP/SelOPlay.cpp +++ b/GP/SelOPlay.cpp @@ -199,20 +199,20 @@ void CSelLine::DrawTrackingImage(wxDC& pDC, TrackMode eMode) const #endif } -HCURSOR CSelLine::GetHandleCursor(int nHandleID) const +wxCursor CSelLine::GetHandleCursor(int nHandleID) const { - const CB::string::value_type* id; + wxStockCursor id; switch (nHandleID) { case hitPtA: case hitPtB: - id = IDC_CROSS; + id = wxCURSOR_CROSS; break; default: ASSERT(FALSE); - id = nullptr; + id = wxCURSOR_NONE; } - return AfxGetApp()->LoadStandardCursor(id); + return wxCursor(id); } // Returns handle location in logical coords. diff --git a/GP/SelOPlay.h b/GP/SelOPlay.h index 4c9ce56a..02668971 100644 --- a/GP/SelOPlay.h +++ b/GP/SelOPlay.h @@ -84,8 +84,8 @@ class CSelection RefPtr m_pObj; // Associated object that is selected CRect m_rect; // Enclosing rect for selected object - virtual HCURSOR GetHandleCursor(int nHandle) const /* override */ - { return AfxGetApp()->LoadStandardCursor(IDC_ARROW); } + virtual wxCursor GetHandleCursor(int nHandle) const /* override */ + { return wxCursor(wxCURSOR_ARROW); } virtual CRect GetRect() const /* override */ { return m_rect; } // Operations @@ -141,7 +141,7 @@ class CSelLine : public CSelection // Overrides public: - virtual HCURSOR GetHandleCursor(int nHandleID) const override; + wxCursor GetHandleCursor(int nHandleID) const override; virtual void MoveHandle(int m_nHandle, CPoint point) override; protected: @@ -167,8 +167,8 @@ class CSelGeneric : public CSelection // Overrides public: - virtual HCURSOR GetHandleCursor(int nHandleID) const override - { return AfxGetApp()->LoadStandardCursor(IDC_ARROW); } + wxCursor GetHandleCursor(int nHandleID) const override + { return wxCursor(wxCURSOR_ARROW); } virtual void MoveHandle(int m_nHandle, CPoint point) override {} protected: diff --git a/GP/ToolPlay.cpp b/GP/ToolPlay.cpp index 7cfe7120..7b3ba276 100644 --- a/GP/ToolPlay.cpp +++ b/GP/ToolPlay.cpp @@ -51,8 +51,8 @@ const int scrollZone = 16; // From INI? std::vector CPlayTool::c_toolLib; // Tool library -CPoint CPlayTool::c_ptDown; // Mouse down location -CPoint CPlayTool::c_ptLast; // Last mouse location +wxPoint CPlayTool::c_ptDown; // Mouse down location +wxPoint CPlayTool::c_ptLast; // Last mouse location // The playing board tool objects... @@ -82,7 +82,7 @@ CPlayTool& CPlayTool::GetTool(PToolType eToolType) return retval; } -void CPlayTool::OnLButtonDown(CPlayBoardView& pView, UINT nFlags, CPoint point) +void CPlayTool::OnLButtonDown(CPlayBoardView& pView, int /*nMods*/, wxPoint point) { pView.CaptureMouse(); @@ -90,14 +90,14 @@ void CPlayTool::OnLButtonDown(CPlayBoardView& pView, UINT nFlags, CPoint point) c_ptLast = point; } -void CPlayTool::OnMouseMove(CPlayBoardView& pView, UINT nFlags, CPoint point) +void CPlayTool::OnMouseMove(CPlayBoardView& pView, int /*nMods*/, wxPoint point) { if (pView.HasCapture()) c_ptLast = point; - SetCursor(AfxGetApp()->LoadStandardCursor(IDC_ARROW)); + pView.SetCursor(wxCursor(wxCURSOR_ARROW)); } -bool CPlayTool::OnLButtonUp(CPlayBoardView& pView, UINT nFlags, CPoint point) +bool CPlayTool::OnLButtonUp(CPlayBoardView& pView, int /*nMods*/, wxPoint /*point*/) { if (!pView.HasCapture()) return false; @@ -108,20 +108,20 @@ bool CPlayTool::OnLButtonUp(CPlayBoardView& pView, UINT nFlags, CPoint point) //////////////////////////////////////////////////////////////////////// // CPSelectTool - Object Selection/Manipulation tool -void CPSelectTool::OnLButtonDown(CPlayBoardView& pView, UINT nFlags, - CPoint point) +void CPSelectTool::OnLButtonDown(CPlayBoardView& pView, int nMods, + wxPoint point) { CSelList& pSLst = pView.GetSelectList(); CPlayBoard& pPBoard = pView.GetPlayBoard(); // If a a handle is clicked on, immediately start tracking the // resize. - if ((m_nHandleID = pSLst.HitTestHandles(point)) >= 0) + if ((m_nHandleID = pSLst.HitTestHandles(CB::Convert(point))) >= 0) { - StartSizingOperation(pView, nFlags, point); + StartSizingOperation(pView, nMods, point); return; } - CDrawObj* pObj = pView.ObjectHitTest(CB::Convert(point)); + CDrawObj* pObj = pView.ObjectHitTest(point); BOOL bOwnedButNotOkToSelect = FALSE; if (pObj != NULL && pObj->GetType() == CDrawObj::drawPieceObj) @@ -140,11 +140,11 @@ void CPSelectTool::OnLButtonDown(CPlayBoardView& pView, UINT nFlags, if (pObj == NULL || bOwnedButNotOkToSelect || (pPBoard.GetLocksEnforced() && (pObj->GetDObjFlags() & dobjFlgLockDown))) { - if ((nFlags & MK_SHIFT) == 0) // Shift click adds to list + if ((nMods & wxMOD_SHIFT) == 0) // Shift click adds to list pSLst.PurgeList(TRUE); // Clear current select list // No objects were under the mouse click. m_eSelMode = smodeNet; // Net type selection - CPlayTool::OnLButtonDown(pView, nFlags, point); + CPlayTool::OnLButtonDown(pView, nMods, point); wxOverlayDC dc(pView.GetOverlay(), &pView); pView.OnPrepareScaledDC(dc, true); dc.Clear(); @@ -155,10 +155,10 @@ void CPSelectTool::OnLButtonDown(CPlayBoardView& pView, UINT nFlags, // add to list. if (!pSLst.IsObjectSelected(*pObj)) { - if ((nFlags & MK_SHIFT) == 0) // Shift click adds to list + if ((nMods & wxMOD_SHIFT) == 0) // Shift click adds to list pSLst.PurgeList(TRUE); // Clear current select list - if ((nFlags & MK_CONTROL) != 0) // Control click drills down - pView.SelectAllUnderPoint(CB::Convert(point)); + if ((nMods & wxMOD_CONTROL) != 0) // Control click drills down + pView.SelectAllUnderPoint(point); else { pSLst.AddObject(*pObj, TRUE); @@ -166,34 +166,34 @@ void CPSelectTool::OnLButtonDown(CPlayBoardView& pView, UINT nFlags, pObj->GetType() == CDrawObj::drawMarkObj) pView.NotifySelectListChange(); } - CPlayTool::OnLButtonDown(pView, nFlags, point); + CPlayTool::OnLButtonDown(pView, nMods, point); StartDragTimer(pView); - CRect rct = pSLst.GetEnclosingRect(); - CSize sizeOff = point - rct.TopLeft(); - pSLst.SetMouseOffset(sizeOff); + wxRect rct = CB::Convert(pSLst.GetEnclosingRect()); + wxPoint sizeOff = point - rct.GetTopLeft(); + pSLst.SetMouseOffset(CSize(sizeOff.x, sizeOff.y)); return; } // At this point we know s/he clicked on an object that was // already selected. If SHIFT is held we'll remove it from // the list. Otherwise, a timer is started and drag tracking // wont start until it expires. - if ((nFlags & MK_SHIFT) != 0) + if ((nMods & wxMOD_SHIFT) != 0) { pSLst.RemoveObject(*pObj, TRUE); return; } - CPlayTool::OnLButtonDown(pView, nFlags, point); + CPlayTool::OnLButtonDown(pView, nMods, point); pSLst.SetSnapReferenceObject(pObj); - CRect rct = pSLst.GetSnapReferenceRect(); - CSize sizeOff = point - rct.TopLeft(); - pSLst.SetMouseOffset(sizeOff); + wxRect rct = CB::Convert(pSLst.GetSnapReferenceRect()); + wxPoint sizeOff = point - rct.GetTopLeft(); + pSLst.SetMouseOffset(CSize(sizeOff.x, sizeOff.y)); StartDragTimer(pView); } -void CPSelectTool::OnMouseMove(CPlayBoardView& pView, UINT nFlags, CPoint point) +void CPSelectTool::OnMouseMove(CPlayBoardView& pView, int nMods, wxPoint point) { CSelList& pSLst = pView.GetSelectList(); @@ -227,7 +227,7 @@ void CPSelectTool::OnMouseMove(CPlayBoardView& pView, UINT nFlags, CPoint point) else KillScrollTimer(pView); #else - wxASSERT(!"TODO: autoscroll"); + CPP20_TRACE("{}->{}: TODO:\n", *this, __func__); #endif } @@ -238,7 +238,7 @@ void CPSelectTool::OnMouseMove(CPlayBoardView& pView, UINT nFlags, CPoint point) wxOverlayDC dc(pView.GetOverlay(), &pView); pView.OnPrepareScaledDC(dc, true); dc.Clear(); - CPlayTool::OnMouseMove(pView, nFlags, point); // Update position + CPlayTool::OnMouseMove(pView, nMods, point); // Update position DrawNetRect(dc, pView); // Draw new position rect return; } @@ -247,13 +247,13 @@ void CPSelectTool::OnMouseMove(CPlayBoardView& pView, UINT nFlags, CPoint point) // tracking image. if (m_eSelMode == smodeMove) { - point = CB::Convert(pView.WorkspaceToClient(CB::Convert(point))); + point = pView.WorkspaceToClient(point); DoDragDrop(pView, point); return; } else if (m_eSelMode == smodeSizing) { - point = CB::Convert(pView.AdjustPoint(CB::Convert(point))); + point = pView.AdjustPoint(point); if (point == c_ptLast) return; @@ -268,7 +268,7 @@ void CPSelectTool::OnMouseMove(CPlayBoardView& pView, UINT nFlags, CPoint point) c_ptLast = point; // Save new 'last' position } -bool CPSelectTool::OnLButtonUp(CPlayBoardView& pView, UINT nFlags, CPoint point) +bool CPSelectTool::OnLButtonUp(CPlayBoardView& pView, int nMods, wxPoint point) { bool retval = true; if (pView.HasCapture()) @@ -282,7 +282,7 @@ bool CPSelectTool::OnLButtonUp(CPlayBoardView& pView, UINT nFlags, CPoint point) // will be selected. wxRect rect(wxPoint(std::min(c_ptDown.x, c_ptLast.x), std::min(c_ptDown.y, c_ptLast.y)), wxSize(std::abs(c_ptLast.x - c_ptDown.x), std::abs(c_ptLast.y - c_ptDown.y))); - pView.SelectWithinRect(rect, (nFlags & MK_CONTROL) != 0); + pView.SelectWithinRect(rect, (nMods & wxMOD_CONTROL) != 0); CSelList& pSLst = pView.GetSelectList(); pSLst.InvalidateListHandles(); } @@ -291,9 +291,9 @@ bool CPSelectTool::OnLButtonUp(CPlayBoardView& pView, UINT nFlags, CPoint point) CSelList& pSLst = pView.GetSelectList(); if (m_eSelMode == smodeMove) { - CPoint pnt = point; + wxPoint pnt = point; pSLst.SetTrackingMode(trkSelected); - pnt = CB::Convert(pView.WorkspaceToClient(CB::Convert(pnt))); + pnt = pView.WorkspaceToClient(pnt); retval = DoDragDropEnd(pView, pnt) && retval; } else @@ -311,7 +311,7 @@ bool CPSelectTool::OnLButtonUp(CPlayBoardView& pView, UINT nFlags, CPoint point) m_eSelMode = smodeNormal; KillDragTimer(pView); // Make sure timers are released KillScrollTimer(pView); - return CPlayTool::OnLButtonUp(pView, nFlags, point) && retval; + return CPlayTool::OnLButtonUp(pView, nMods, point) && retval; } void CPSelectTool::OnTimer(CPlayBoardView& pView, uintptr_t nIDEvent) @@ -337,9 +337,6 @@ void CPSelectTool::OnTimer(CPlayBoardView& pView, uintptr_t nIDEvent) CClientDC dc(&pView); pView.OnPrepareScaledDC(dc, TRUE); pSLst.DrawTracker(dc, trkSelected); // Turn off handles -#else - wxASSERT(!"TODO:"); -#endif CPoint point; GetCursorPos(&point); @@ -350,6 +347,9 @@ void CPSelectTool::OnTimer(CPlayBoardView& pView, uintptr_t nIDEvent) DoDragDropStart(pView); point = CB::Convert(pView.WorkspaceToClient(CB::Convert(point))); DoDragDrop(pView, point); +#else + wxASSERT(!"TODO:"); +#endif } else if (m_eSelMode != smodeMove) { @@ -358,27 +358,17 @@ void CPSelectTool::OnTimer(CPlayBoardView& pView, uintptr_t nIDEvent) } } -void CPSelectTool::OnLButtonDblClk(CPlayBoardView& pView, UINT nFlags, - CPoint point) +void CPSelectTool::OnLButtonDblClk(CPlayBoardView& pView, int nMods, + wxPoint point) { // Normal DblClk opens some property view of the selected // object. Only recognized if only one selection is active. - CPlayTool::OnLButtonDblClk(pView, nFlags, point); + CPlayTool::OnLButtonDblClk(pView, nMods, point); pView.GetSelectList().Open(); } -BOOL CPSelectTool::OnSetCursor(const CPlayBoardView& pView, UINT nHitTest) const +wxCursor CPSelectTool::OnSetCursor(const CPlayBoardView& pView, const wxPoint& point) const { - // Process only within the client area - if (nHitTest != HTCLIENT) - return FALSE; - - // Convert cursor position to document coordinates - CPoint point; - GetCursorPos(&point); - point = CB::Convert(pView.ScreenToClient(CB::Convert(point))); - point = CB::Convert(pView.ClientToWorkspace(CB::Convert(point))); - // Check for movement through handle areas. Set the // cursor to the appropriate shape. const CSelList& pSLst = pView.GetSelectList(); @@ -387,24 +377,23 @@ BOOL CPSelectTool::OnSetCursor(const CPlayBoardView& pView, UINT nHitTest) const // Check if cursor is over a handle. If it is, // get handle cursor. const CSelection& pSelObj = *pSLst.front(); - int nHandle = pSelObj.HitTestHandles(point); + int nHandle = pSelObj.HitTestHandles(CB::Convert(point)); if (nHandle >= 0) { - SetCursor(pSelObj.GetHandleCursor(nHandle)); - return TRUE; + return pSelObj.GetHandleCursor(nHandle); } } - return FALSE; // Show default cursor + return wxCursor(); // Show default cursor } -void CPSelectTool::StartSizingOperation(CPlayBoardView& pView, UINT nFlags, - const CPoint& point, int nHandleID) +void CPSelectTool::StartSizingOperation(CPlayBoardView& pView, int nMods, + const wxPoint& point, int nHandleID) { CSelList& pSLst = pView.GetSelectList(); if (nHandleID != -1) m_nHandleID = nHandleID; m_eSelMode = smodeSizing; - CPlayTool::OnLButtonDown(pView, nFlags, point); + CPlayTool::OnLButtonDown(pView, nMods, point); wxOverlayDC dc(pView.GetOverlay(), &pView); pView.OnPrepareScaledDC(dc, true); dc.Clear(); @@ -509,34 +498,34 @@ BOOL CPSelectTool::ProcessAutoScroll(CPlayBoardView& pView) return FALSE; } -void CPSelectTool::MoveSelections(CSelList &pSLst, const CPoint& point) +void CPSelectTool::MoveSelections(CSelList &pSLst, const wxPoint& point) { if (m_eSelMode == smodeMove) { - CPoint ptDelta = (CPoint)(point - c_ptLast); - pSLst.Offset(ptDelta); + wxPoint ptDelta = point - c_ptLast; + pSLst.Offset(CB::Convert(ptDelta)); } else - pSLst.MoveHandle(m_nHandleID, point); + pSLst.MoveHandle(m_nHandleID, CB::Convert(point)); } -CPoint CPSelectTool::AdjustPoint(const CPlayBoardView& pView, CPoint point) const +wxPoint CPSelectTool::AdjustPoint(const CPlayBoardView& pView, wxPoint point) const { - point = CB::Convert(pView.AdjustPoint(CB::Convert(point))); + point = pView.AdjustPoint(point); if (point == c_ptLast) return point; if (m_eSelMode == smodeMove) { - CRect rct = pView.GetSelectList().GetEnclosingRect(); - CPoint pnt = CB::Convert(pView.GetWorkspaceDim()); - if (rct.left + point.x - c_ptLast.x < 0) // Clamp - point.x = c_ptLast.x - rct.left; - if (rct.top + point.y - c_ptLast.y < 0) // Clamp - point.y = c_ptLast.y - rct.top; - if (rct.right + point.x - c_ptLast.x > pnt.x) // Clamp - point.x = pnt.x - (rct.right - c_ptLast.x); - if (rct.bottom + point.y - c_ptLast.y > pnt.y) // Clamp - point.y = pnt.y - (rct.bottom - c_ptLast.y); + wxRect rct = CB::Convert(pView.GetSelectList().GetEnclosingRect()); + wxPoint pnt = pView.GetWorkspaceDim(); + if (rct.GetLeft() + point.x - c_ptLast.x < 0) // Clamp + point.x = c_ptLast.x - rct.GetLeft(); + if (rct.GetTop() + point.y - c_ptLast.y < 0) // Clamp + point.y = c_ptLast.y - rct.GetTop(); + if (rct.GetRight() + point.x - c_ptLast.x > pnt.x) // Clamp + point.x = pnt.x - (rct.GetRight() - c_ptLast.x); + if (rct.GetBottom() + point.y - c_ptLast.y > pnt.y) // Clamp + point.y = pnt.y - (rct.GetBottom() - c_ptLast.y); } return point; } @@ -547,7 +536,7 @@ void CPSelectTool::StartDragTimer(CPlayBoardView& pView) m_nTimerID = pView.SetTimer(timerIDSelectDelay, timerSelDelay, NULL); #else - wxASSERT(!"TODO: autoscroll"); + CPP20_TRACE("{}->{}: TODO:\n", *this, __func__); #endif } @@ -560,7 +549,7 @@ void CPSelectTool::KillDragTimer(CPlayBoardView& pView) m_nTimerID = uintptr_t(0); } #else -wxASSERT(!"TODO: autoscroll"); + CPP20_TRACE("{}->{}: TODO:\n", *this, __func__); #endif } @@ -569,7 +558,7 @@ void CPSelectTool::StartScrollTimer(CPlayBoardView& pView) #if 0 m_nTimerID = pView.SetTimer(timerIDAutoScroll, timerAutoScroll, NULL); #else - wxASSERT(!"TODO: autoscroll"); + CPP20_TRACE("{}->{}: TODO:\n", *this, __func__); #endif } @@ -582,7 +571,7 @@ void CPSelectTool::KillScrollTimer(CPlayBoardView& pView) m_nTimerID = uintptr_t(0); } #else - wxASSERT(!"TODO: autoscroll"); + CPP20_TRACE("{}->{}: TODO:\n", *this, __func__); #endif } @@ -591,6 +580,7 @@ void CPSelectTool::KillScrollTimer(CPlayBoardView& pView) // this time. void CPSelectTool::DoDragDropStart(CPlayBoardView& pView) { + wxASSERT(!"TODO:"); m_di.SetDragType(DRAG_SELECTLIST); m_di.GetSubInfo().m_selectList = &pView.GetSelectList(); m_di.GetSubInfo().m_gamDoc = &pView.GetDocument(); @@ -599,8 +589,10 @@ void CPSelectTool::DoDragDropStart(CPlayBoardView& pView) m_hLastWnd = NULL; } -void CPSelectTool::DoDragDrop(CPlayBoardView& pView, const CPoint& pntClient) +void CPSelectTool::DoDragDrop(CPlayBoardView& pView, const wxPoint& pntClient) { + wxASSERT(!"TODO:"); +#if 0 CPoint pnt = pntClient; pnt = CB::Convert(pView.ClientToScreen(CB::Convert(pnt))); CWnd* pWnd = GetWindowFromPoint(pnt); @@ -640,13 +632,18 @@ void CPSelectTool::DoDragDrop(CPlayBoardView& pView, const CPoint& pntClient) SetCursor(hCursor); else SetCursor(g_res.hcrNoDrop); +#endif } -bool CPSelectTool::DoDragDropEnd(CPlayBoardView& pView, const CPoint& pntClient) +bool CPSelectTool::DoDragDropEnd(CPlayBoardView& pView, const wxPoint& pntClient) { +#if 1 + wxASSERT(!"TODO:"); + return false; +#else SetCursor(LoadCursor(NULL, IDC_ARROW)); - wxPoint pnt = CB::Convert(pntClient); + wxPoint pnt = pntClient; pView.ClientToScreen(pnt); CWnd* pWnd = GetWindowFromPoint(CB::Convert(pnt)); if (pWnd == NULL) @@ -657,28 +654,31 @@ bool CPSelectTool::DoDragDropEnd(CPlayBoardView& pView, const CPoint& pntClient) m_di.m_phase = PhaseDrag::Drop; return pWnd->SendMessage(WM_DRAGDROP, GetProcessId(GetCurrentProcess()), (LPARAM)(LPVOID)&m_di) == 1; +#endif } //////////////////////////////////////////////////////////////////////// // CPShapeTool - tool used to create rectangles. -void CPShapeTool::OnLButtonDown(CPlayBoardView& pView, UINT nFlags, CPoint point) +void CPShapeTool::OnLButtonDown(CPlayBoardView& pView, int nMods, wxPoint point) { + wxASSERT(!"dead code"); CSelList& pSLst = pView.GetSelectList(); pSLst.PurgeList(TRUE); // Clear current select list int nDragHandle; - point = CB::Convert(pView.AdjustPoint(CB::Convert(point))); + point = pView.AdjustPoint(point); m_pObj = CreateDrawObj(pView, point, nDragHandle); pSLst.AddObject(*m_pObj, TRUE); - s_plySelectTool.StartSizingOperation(pView, nFlags, point, nDragHandle); + s_plySelectTool.StartSizingOperation(pView, nMods, point, nDragHandle); } -bool CPShapeTool::OnLButtonUp(CPlayBoardView& pView, UINT nFlags, CPoint point) +bool CPShapeTool::OnLButtonUp(CPlayBoardView& pView, int nMods, wxPoint point) { + wxASSERT(!"dead code"); if (!pView.HasCapture()) return false; bool retval = true; - retval = s_plySelectTool.OnLButtonUp(pView, nFlags, point) && retval; + retval = s_plySelectTool.OnLButtonUp(pView, nMods, point) && retval; pView.GetSelectList().PurgeList(TRUE); // Clear current select list if (!IsEmptyObject()) pView.AddDrawObject(std::move(m_pObj)); @@ -689,31 +689,32 @@ bool CPShapeTool::OnLButtonUp(CPlayBoardView& pView, UINT nFlags, CPoint point) return true; } -void CPShapeTool::OnMouseMove(CPlayBoardView& pView, UINT nFlags, CPoint point) +void CPShapeTool::OnMouseMove(CPlayBoardView& pView, int nMods, wxPoint point) { + wxASSERT(!"dead code"); if (pView.HasCapture()) - s_plySelectTool.OnMouseMove(pView, nFlags, point); + s_plySelectTool.OnMouseMove(pView, nMods, point); } void CPShapeTool::OnTimer(CPlayBoardView& pView, uintptr_t nIDEvent) { + wxASSERT(!"dead code"); s_plySelectTool.OnTimer(pView, nIDEvent); } -BOOL CPShapeTool::OnSetCursor(const CPlayBoardView& pView, UINT nHitTest) const +wxCursor CPShapeTool::OnSetCursor(const CPlayBoardView& /*pView*/, const wxPoint& /*point*/) const { - if (nHitTest != HTCLIENT) - return FALSE; - SetCursor(g_res.hcrCrossHair); - return TRUE; + wxASSERT(!"dead code"); + return g_res.hcrCrossHairWx; } //////////////////////////////////////////////////////////////////////// // CPLineTool - tool used to create lines -OwnerPtr CPLineTool::CreateDrawObj(CPlayBoardView& pView, const CPoint& point, +OwnerPtr CPLineTool::CreateDrawObj(CPlayBoardView& pView, const wxPoint& point, int& nHandle) const { + wxASSERT(!"dead code"); OwnerPtr pObj = MakeOwner(); pObj->SetLine(point.x, point.y, point.x, point.y); pObj->SetForeColor(CB::Convert(pView.GetLineColor())); @@ -724,6 +725,7 @@ OwnerPtr CPLineTool::CreateDrawObj(CPlayBoardView& pView, const CPoint BOOL CPLineTool::IsEmptyObject() const { + wxASSERT(!"dead code"); wxASSERT(dynamic_cast(&*m_pObj)); CRect rct = static_cast(*m_pObj).GetRect(); return rct.Width() < 3 && rct.Height() < 3; @@ -732,36 +734,35 @@ BOOL CPLineTool::IsEmptyObject() const //////////////////////////////////////////////////////////////////////// // CPTextBoxTool - Text box drawing object tool -void CPTextBoxTool::OnLButtonDown(CPlayBoardView& pView, UINT nFlags, - CPoint point) +void CPTextBoxTool::OnLButtonDown(CPlayBoardView& pView, int nMods, + wxPoint poin) { + wxASSERT(!"dead code"); // pView->DoCreateTextDrawingObject(point); } -BOOL CPTextBoxTool::OnSetCursor(const CPlayBoardView& pView, UINT nHitTest) const +wxCursor CPTextBoxTool::OnSetCursor(const CPlayBoardView& /*pView*/, const wxPoint& /*point*/) const { - if (nHitTest != HTCLIENT) - return FALSE; - SetCursor(g_res.hcrCrossHair); - return TRUE; + wxASSERT(!"dead code"); + return g_res.hcrCrossHairWx; } //////////////////////////////////////////////////////////////////////// // CPPlotTool - move plot tool -void CPPlotTool::OnLButtonDown(CPlayBoardView& pView, UINT nFlags, - CPoint point) +void CPPlotTool::OnLButtonDown(CPlayBoardView& pView, int nMods, + wxPoint point) { CGamDoc& pDoc = pView.GetDocument(); CPlayBoard& pPBrd = pView.GetPlayBoard(); - ASSERT(pPBrd.GetPlotMoveMode()); + wxASSERT(pPBrd.GetPlotMoveMode()); if (pPBrd.m_bSnapMovePlot) - point = CB::Convert(pView.AdjustPoint(CB::Convert(point))); // Keep on the grid (if enabled) + point = pView.AdjustPoint(point); // Keep on the grid (if enabled) - CPoint pntPrev = pPBrd.GetPrevPlotPoint(); + wxPoint pntPrev = CB::Convert(pPBrd.GetPrevPlotPoint()); - if (pntPrev == CPoint(-1, -1)) + if (pntPrev == wxPoint(-1, -1)) { // Draw a line for each piece to the opening location std::vector> listObjs; @@ -769,23 +770,20 @@ void CPPlotTool::OnLButtonDown(CPlayBoardView& pView, UINT nFlags, for (auto pos = listObjs.begin() ; pos != listObjs.end() ; ++pos) { CDrawObj& pObj = **pos; - ASSERT(pObj.GetType() == CDrawObj::drawPieceObj || + wxASSERT(pObj.GetType() == CDrawObj::drawPieceObj || pObj.GetType() == CDrawObj::drawMarkObj); - CRect rct = pObj.GetRect(); - CPoint pnt = GetMidRect(rct); - pDoc.IndicateBoardPlotLine(pPBrd, pnt, point); + wxRect rct = CB::Convert(pObj.GetRect()); + wxPoint pnt = GetMidRect(rct); + pDoc.IndicateBoardPlotLine(pPBrd, CB::Convert(pnt), CB::Convert(point)); } } else - pDoc.IndicateBoardPlotLine(pPBrd, pntPrev, point); - pPBrd.SetPrevPlotPoint(point); + pDoc.IndicateBoardPlotLine(pPBrd, CB::Convert(pntPrev), CB::Convert(point)); + pPBrd.SetPrevPlotPoint(CB::Convert(point)); } -BOOL CPPlotTool::OnSetCursor(const CPlayBoardView& pView, UINT nHitTest) const +wxCursor CPPlotTool::OnSetCursor(const CPlayBoardView& /*pView*/, const wxPoint& /*point*/) const { - if (nHitTest != HTCLIENT) - return FALSE; - SetCursor(g_res.hcrCrossHair); - return TRUE; + return g_res.hcrCrossHairWx; } diff --git a/GP/ToolPlay.h b/GP/ToolPlay.h index 6d5ffdda..f08cf536 100644 --- a/GP/ToolPlay.h +++ b/GP/ToolPlay.h @@ -55,13 +55,13 @@ class CPlayTool public: static CPlayTool& GetTool(PToolType eType); // ----------- // - virtual void OnLButtonDown(CPlayBoardView& pView, UINT nFlags, CPoint point) /* override */; - virtual void OnLButtonDblClk(CPlayBoardView& /*pView*/, UINT /*nFlags*/, CPoint /*point*/) /* override */ {} - virtual bool OnLButtonUp(CPlayBoardView& pView, UINT nFlags, CPoint point) /* override */; - virtual void OnMouseMove(CPlayBoardView& pView, UINT nFlags, CPoint point) /* override */; + virtual void OnLButtonDown(CPlayBoardView& pView, int nMods, wxPoint point) /* override */; + virtual void OnLButtonDblClk(CPlayBoardView& /*pView*/, int /*nMods*/, wxPoint /*point*/) /* override */ {} + virtual bool OnLButtonUp(CPlayBoardView& pView, int nMods, wxPoint point) /* override */; + virtual void OnMouseMove(CPlayBoardView& pView, int nMods, wxPoint point) /* override */; virtual void OnTimer(CPlayBoardView& /*pView*/, uintptr_t /*nIDEvent*/) /*override*/ {} - virtual BOOL OnSetCursor(const CPlayBoardView& /*pView*/, UINT /*nHitTest*/) const /*override*/ - { return FALSE; } + virtual wxCursor OnSetCursor(const CPlayBoardView& /*pView*/, const wxPoint& /*point*/) const /*override*/ + { return wxCursor(); } // Implementation private: @@ -69,8 +69,26 @@ class CPlayTool static std::vector c_toolLib; protected: // Drag related vars.... - static CPoint c_ptDown; // Document coords. - static CPoint c_ptLast; + static wxPoint c_ptDown; // Document coords. + static wxPoint c_ptLast; +}; + +template T, typename CharT> +struct std::formatter : private std::formatter +{ +private: + using BASE = formatter; +public: + using BASE::parse; + + template + FormatContext::iterator format(const CPlayTool& o, FormatContext& ctx) const + { + return std::format_to(ctx.out(), + "{}({})", + typeid(o).name(), + static_cast(&o)); + } }; //////////////////////////////////////////////////////////////////////// @@ -95,34 +113,34 @@ class CPSelectTool : public CPlayTool // Operations public: - void OnLButtonDown(CPlayBoardView& pView, UINT nFlags, CPoint point) override; - void OnLButtonDblClk(CPlayBoardView& pView, UINT nFlags, CPoint point) override; - bool OnLButtonUp(CPlayBoardView& pView, UINT nFlags, CPoint point) override; - void OnMouseMove(CPlayBoardView& pView, UINT nFlags, CPoint point) override; + void OnLButtonDown(CPlayBoardView& pView, int nMods, wxPoint point) override; + void OnLButtonDblClk(CPlayBoardView& pView, int nMods, wxPoint point) override; + bool OnLButtonUp(CPlayBoardView& pView, int nMods, wxPoint point) override; + void OnMouseMove(CPlayBoardView& pView, int nMods, wxPoint point) override; void OnTimer(CPlayBoardView& pView, uintptr_t nIDEvent) override; - BOOL OnSetCursor(const CPlayBoardView& pView, UINT nHitTest) const override; + wxCursor OnSetCursor(const CPlayBoardView& pView, const wxPoint& point) const override; // Implementation public: uintptr_t m_nTimerID; - CRect m_rectMultiBorder; + wxRect m_rectMultiBorder; // ------- // BOOL ProcessAutoScroll(CPlayBoardView& pView); void DrawSelectionRect(wxDC& pDC, const wxRect& pRct) const; void DrawNetRect(wxDC& pDC, const CPlayBoardView& pView) const; - [[nodiscard]] CPoint AdjustPoint(const CPlayBoardView& pView, CPoint point) const; - void MoveSelections(CSelList &pSLst, const CPoint& point); + [[nodiscard]] wxPoint AdjustPoint(const CPlayBoardView& pView, wxPoint point) const; + void MoveSelections(CSelList &pSLst, const wxPoint& point); void StartDragTimer(CPlayBoardView& pView); void KillDragTimer(CPlayBoardView& pView); void StartScrollTimer(CPlayBoardView& pView); void KillScrollTimer(CPlayBoardView& pView); // ------- // void DoDragDropStart(CPlayBoardView& pView); - void DoDragDrop(CPlayBoardView& pView, const CPoint& pntClient); - bool DoDragDropEnd(CPlayBoardView& pView, const CPoint& pntClient); + void DoDragDrop(CPlayBoardView& pView, const wxPoint& pntClient); + bool DoDragDropEnd(CPlayBoardView& pView, const wxPoint& pntClient); // ------- // - void StartSizingOperation(CPlayBoardView& pView, UINT nFlags, - const CPoint& point, int nHandleID = -1); + void StartSizingOperation(CPlayBoardView& pView, int nMods, + const wxPoint& point, int nHandleID = -1); }; //////////////////////////////////////////////////////////////////////// @@ -136,16 +154,16 @@ class CPShapeTool : public CPlayTool // Operations public: - void OnLButtonDown(CPlayBoardView& pView, UINT nFlags, CPoint point) override; - void OnLButtonDblClk(CPlayBoardView& /*pView*/, UINT /*nFlags*/, CPoint /*point*/) override {} - bool OnLButtonUp(CPlayBoardView& pView, UINT nFlags, CPoint point) override; - void OnMouseMove(CPlayBoardView& pView, UINT nFlags, CPoint point) override; + void OnLButtonDown(CPlayBoardView& pView, int nMods, wxPoint point) override; + void OnLButtonDblClk(CPlayBoardView& /*pView*/, int /*nMods*/, wxPoint /*point*/) override {} + bool OnLButtonUp(CPlayBoardView& pView, int nMods, wxPoint point) override; + void OnMouseMove(CPlayBoardView& pView, int nMods, wxPoint point) override; void OnTimer(CPlayBoardView& pView, uintptr_t nIDEvent) override; - BOOL OnSetCursor(const CPlayBoardView& pView, UINT nHitTest) const override; + wxCursor OnSetCursor(const CPlayBoardView& pView, const wxPoint& point) const override; // Implementation public: - virtual OwnerPtr CreateDrawObj(CPlayBoardView& pView, const CPoint& point, + virtual OwnerPtr CreateDrawObj(CPlayBoardView& pView, const wxPoint& point, int& nHandle) const = 0; virtual BOOL IsEmptyObject() const = 0; // --------- // @@ -163,7 +181,7 @@ class CPLineTool : public CPShapeTool // Implementation public: - OwnerPtr CreateDrawObj(CPlayBoardView& pView, const CPoint& point, + OwnerPtr CreateDrawObj(CPlayBoardView& pView, const wxPoint& point, int& nHandle) const override; BOOL IsEmptyObject() const override; }; @@ -179,12 +197,12 @@ class CPTextBoxTool : public CPlayTool // Operations public: - void OnLButtonDown(CPlayBoardView& pView, UINT nFlags, CPoint point) override; - void OnLButtonDblClk(CPlayBoardView& /*pView*/, UINT /*nFlags*/, CPoint /*point*/) override {} - bool OnLButtonUp(CPlayBoardView& /*pView*/, UINT /*nFlags*/, CPoint /*point*/) override { return true; } - void OnMouseMove(CPlayBoardView& /*pView*/, UINT /*nFlags*/, CPoint /*point*/) override {} + void OnLButtonDown(CPlayBoardView& pView, int nMods, wxPoint point) override; + void OnLButtonDblClk(CPlayBoardView& /*pView*/, int /*nMods*/, wxPoint /*point*/) override {} + bool OnLButtonUp(CPlayBoardView& /*pView*/, int /*nMods*/, wxPoint /*point*/) override { return true; } + void OnMouseMove(CPlayBoardView& /*pView*/, int /*nMods*/, wxPoint /*point*/) override {} void OnTimer(CPlayBoardView& /*pView*/, uintptr_t /*nIDEvent*/) override {} - BOOL OnSetCursor(const CPlayBoardView& pView, UINT nHitTest) const override; + wxCursor OnSetCursor(const CPlayBoardView& pView, const wxPoint& point) const override; // Implementation public: @@ -202,12 +220,12 @@ class CPPlotTool : public CPlayTool // Operations public: - void OnLButtonDown(CPlayBoardView& pView, UINT nFlags, CPoint point) override; - void OnLButtonDblClk(CPlayBoardView& /*pView*/, UINT /*nFlags*/, CPoint /*point*/) override {} - bool OnLButtonUp(CPlayBoardView& /*pView*/, UINT /*nFlags*/, CPoint /*point*/) override { return true; } - void OnMouseMove(CPlayBoardView& /*pView*/, UINT /*nFlags*/, CPoint /*point*/) override {} + void OnLButtonDown(CPlayBoardView& pView, int nMods, wxPoint point) override; + void OnLButtonDblClk(CPlayBoardView& /*pView*/, int /*nMods*/, wxPoint /*point*/) override {} + bool OnLButtonUp(CPlayBoardView& /*pView*/, int /*nMods*/, wxPoint /*point*/) override { return true; } + void OnMouseMove(CPlayBoardView& /*pView*/, int /*nMods*/, wxPoint /*point*/) override {} void OnTimer(CPlayBoardView& /*pView*/, uintptr_t /*nIDEvent*/) override {} - BOOL OnSetCursor(const CPlayBoardView& pView, UINT nHitTest) const override; + wxCursor OnSetCursor(const CPlayBoardView& pView, const wxPoint& point) const override; // Implementation public: diff --git a/GP/VwPbrd.cpp b/GP/VwPbrd.cpp index d17245c1..7820a9ff 100644 --- a/GP/VwPbrd.cpp +++ b/GP/VwPbrd.cpp @@ -66,14 +66,16 @@ wxBEGIN_EVENT_TABLE(CPlayBoardView, CPlayBoardView::BASE) ON_REGISTERED_MESSAGE(WM_DRAGDROP, OnDragItem) ON_MESSAGE(WM_ROTATEPIECE_DELTA, OnMessageRotateRelative) ON_MESSAGE(WM_CENTERBOARDONPOINT, OnMessageCenterBoardOnPoint) - ON_WM_LBUTTONDOWN() #endif + EVT_LEFT_DOWN(OnLButtonDown) EVT_MOTION(OnMouseMove) + EVT_LEFT_UP(OnLButtonUp) #if 0 - ON_WM_LBUTTONUP() ON_WM_TIMER() - ON_WM_LBUTTONDBLCLK() - ON_WM_SETCURSOR() +#endif + EVT_LEFT_DCLICK(OnLButtonDblClk) + EVT_SET_CURSOR(OnSetCursor) +#if 0 ON_WM_KEYDOWN() ON_WM_CHAR() ON_COMMAND_EX(ID_PTOOL_SELECT, OnPlayTool) @@ -90,12 +92,14 @@ wxBEGIN_EVENT_TABLE(CPlayBoardView, CPlayBoardView::BASE) ON_UPDATE_COMMAND_UI(ID_ACT_TURNOVER, OnUpdateActTurnOver) ON_UPDATE_COMMAND_UI(ID_ACT_TURNOVER_PREV, OnUpdateActTurnOver) ON_UPDATE_COMMAND_UI(ID_ACT_TURNOVER_RANDOM, OnUpdateActTurnOver) - ON_COMMAND(ID_PTOOL_PLOTMOVE, OnActPlotMove) - ON_UPDATE_COMMAND_UI(ID_PTOOL_PLOTMOVE, OnUpdateActPlotMove) - ON_COMMAND(ID_ACT_PLOTDONE, OnActPlotDone) - ON_UPDATE_COMMAND_UI(ID_ACT_PLOTDONE, OnUpdateActPlotDone) - ON_COMMAND(ID_ACT_PLOTDISCARD, OnActPlotDiscard) - ON_UPDATE_COMMAND_UI(ID_ACT_PLOTDISCARD, OnUpdateActPlotDiscard) +#endif + EVT_MENU(XRCID("ID_PTOOL_PLOTMOVE"), OnActPlotMove) + EVT_UPDATE_UI(XRCID("ID_PTOOL_PLOTMOVE"), OnUpdateActPlotMove) + EVT_MENU(XRCID("ID_ACT_PLOTDONE"), OnActPlotDone) + EVT_UPDATE_UI(XRCID("ID_ACT_PLOTDONE"), OnUpdateActPlotDone) + EVT_MENU(XRCID("ID_ACT_PLOTDISCARD"), OnActPlotDiscard) + EVT_UPDATE_UI(XRCID("ID_ACT_PLOTDISCARD"), OnUpdateActPlotDiscard) +#if 0 ON_UPDATE_COMMAND_UI(ID_INDICATOR_CELLNUM, OnUpdateIndicatorCellNum) ON_COMMAND(ID_VIEW_SNAPGRID, OnViewSnapGrid) ON_UPDATE_COMMAND_UI(ID_VIEW_SNAPGRID, OnUpdateViewSnapGrid) @@ -1138,29 +1142,29 @@ BOOL CPlayBoardView::IsBoardContentsAvailableToCurrentPlayer() const return m_pPBoard->IsOwnedBy(GetDocument().GetCurrentPlayerMask()); } -#if 0 -void CPlayBoardView::OnLButtonDown(UINT nFlags, CPoint point) +void CPlayBoardView::OnLButtonDown(wxMouseEvent& event) { if (!IsBoardContentsAvailableToCurrentPlayer()) { - CScrollView::OnLButtonDown(nFlags, point); + event.Skip(); return; } PToolType eToolType = MapToolType(m_nCurToolID); CPlayTool& pTool = CPlayTool::GetTool(eToolType); // Allow pieces to be selected even during playback - point = ClientToWorkspace(point); - pTool.OnLButtonDown(*this, nFlags, point); + wxPoint point = ClientToWorkspace(event.GetPosition()); + pTool.OnLButtonDown(*this, event.GetModifiers(), point); } -#endif void CPlayBoardView::OnMouseMove(wxMouseEvent& event) { -#if 0 +#if 1 + int nMods = event.GetModifiers(); + wxPoint point = event.GetPosition(); if (!IsBoardContentsAvailableToCurrentPlayer()) { - CScrollView::OnMouseMove(nFlags, point); + event.Skip(); return; } @@ -1171,10 +1175,10 @@ void CPlayBoardView::OnMouseMove(wxMouseEvent& event) PToolType eToolType = MapToolType(m_nCurToolID); CPlayTool& pTool = CPlayTool::GetTool(eToolType); point = ClientToWorkspace(point); - pTool.OnMouseMove(*this, nFlags, point); + pTool.OnMouseMove(*this, nMods, point); } else - CScrollView::OnMouseMove(nFlags, point); + event.Skip(); #else wxPoint client = event.GetPosition(); wxPoint workspace = ClientToWorkspace(client); @@ -1190,12 +1194,13 @@ void CPlayBoardView::OnMouseMove(wxMouseEvent& event) #endif } -#if 0 -void CPlayBoardView::OnLButtonUp(UINT nFlags, CPoint point) +void CPlayBoardView::OnLButtonUp(wxMouseEvent& event) { + int nMods = event.GetModifiers(); + wxPoint point = event.GetPosition(); if (!IsBoardContentsAvailableToCurrentPlayer()) { - CScrollView::OnLButtonUp(nFlags, point); + event.Skip(); return; } @@ -1203,8 +1208,8 @@ void CPlayBoardView::OnLButtonUp(UINT nFlags, CPoint point) CPlayTool& pTool = CPlayTool::GetTool(eToolType); // Allow pieces to be selected even during playback point = ClientToWorkspace(point); - bool rc = pTool.OnLButtonUp(*this, nFlags, point); - ASSERT(rc || pTool.m_eToolType == ptypeSelect); + bool rc = pTool.OnLButtonUp(*this, nMods, point); + wxASSERT(rc || pTool.m_eToolType == ptypeSelect); if (!rc && pTool.m_eToolType == ptypeSelect) { // failed drop messed up selection list, so rebuild it @@ -1215,11 +1220,13 @@ void CPlayBoardView::OnLButtonUp(UINT nFlags, CPoint point) } } -void CPlayBoardView::OnLButtonDblClk(UINT nFlags, CPoint point) +void CPlayBoardView::OnLButtonDblClk(wxMouseEvent& event) { + int nMods = event.GetModifiers(); + wxPoint point = event.GetPosition(); if (!IsBoardContentsAvailableToCurrentPlayer()) { - CScrollView::OnLButtonDblClk(nFlags, point); + event.Skip(); return; } @@ -1228,12 +1235,13 @@ void CPlayBoardView::OnLButtonDblClk(UINT nFlags, CPoint point) PToolType eToolType = MapToolType(m_nCurToolID); CPlayTool& pTool = CPlayTool::GetTool(eToolType); point = ClientToWorkspace(point); - pTool.OnLButtonDblClk(*this, nFlags, point); + pTool.OnLButtonDblClk(*this, nMods, point); } else - CScrollView::OnLButtonDblClk(nFlags, point); + event.Skip(); } +#if 0 void CPlayBoardView::OnTimer(uintptr_t nIDEvent) { if (m_nTimerID == nIDEvent) @@ -1261,30 +1269,45 @@ void CPlayBoardView::OnTimer(uintptr_t nIDEvent) CScrollView::OnTimer(nIDEvent); } } +#endif -BOOL CPlayBoardView::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) +void CPlayBoardView::OnSetCursor(wxSetCursorEvent& event) { if (GetDocument().IsPlaying()) - return CScrollView::OnSetCursor(pWnd, nHitTest, message); + { + event.Skip(); + return; + } PToolType eToolType = MapToolType(m_nCurToolID); - if (pWnd == this && eToolType != ptypeUnknown) + if (event.GetEventObject() == this && eToolType != ptypeUnknown) { CPlayTool& pTool = CPlayTool::GetTool(eToolType); - if (pTool.OnSetCursor(*this, nHitTest)) - return TRUE; + wxPoint point(event.GetX(), event.GetY()); + wxASSERT(GetClientRect().Contains(point)); + point = ClientToWorkspace(point); + wxCursor rc = pTool.OnSetCursor(*this, point); + if (rc.IsOk()) + { + event.SetCursor(rc); + return; + } } if (GetDocument().IsRecordingCompoundMove()) { - ::SetCursor(g_res.hcrCompMoveActive); - return TRUE; + event.SetCursor(g_res.hcrCompMoveActive); + return; } else - return CScrollView::OnSetCursor(pWnd, nHitTest, message); + { + event.Skip(); + return; + } } ////////////////////////////////////////////////////////////////////// +#if 0 void CPlayBoardView::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) { CGamDoc& pDoc = GetDocument(); @@ -1734,8 +1757,9 @@ void CPlayBoardView::OnUpdateActTurnOver(CCmdUI* pCmdUI) MF_BYPOSITION | (bEnabled ? MF_ENABLED : (MF_DISABLED | MF_GRAYED))); } } +#endif -void CPlayBoardView::OnActPlotMove() +void CPlayBoardView::OnActPlotMove(wxCommandEvent& /*event*/) { // Do this call so we don't record the plot list in the // restoration record. @@ -1746,11 +1770,12 @@ void CPlayBoardView::OnActPlotMove() m_nCurToolID = ID_PTOOL_PLOTMOVE; } -void CPlayBoardView::OnUpdateActPlotMove(CCmdUI* pCmdUI) +void CPlayBoardView::OnUpdateActPlotMove(wxUpdateUIEvent& pCmdUI) { if (GetDocument().IsPlaying() || (!m_selList.HasPieces() && !m_selList.HasMarkers()) || GetDocument().IsScenario()) { +#if 0 if (pCmdUI->m_pSubMenu != NULL) { pCmdUI->m_pMenu->EnableMenuItem(pCmdUI->m_nIndex, @@ -1758,25 +1783,30 @@ void CPlayBoardView::OnUpdateActPlotMove(CCmdUI* pCmdUI) } else pCmdUI->Enable(FALSE); +#else + pCmdUI.Enable(FALSE); +#endif return; } +#if 0 else if (pCmdUI->m_pSubMenu != NULL) { pCmdUI->m_pMenu->EnableMenuItem(pCmdUI->m_nIndex, MF_BYPOSITION | MF_ENABLED); } +#endif - pCmdUI->Enable(!m_pPBoard->GetPlotMoveMode()); - pCmdUI->SetCheck(m_pPBoard->GetPlotMoveMode()); + pCmdUI.Enable(!m_pPBoard->GetPlotMoveMode()); + pCmdUI.Check(m_pPBoard->GetPlotMoveMode()); } -void CPlayBoardView::OnActPlotDone() +void CPlayBoardView::OnActPlotDone(wxCommandEvent& /*event*/) { if (m_pPBoard->GetPrevPlotPoint() != CPoint(-1, -1)) { - CRect rct = m_selList.GetPiecesEnclosingRect(); - CPoint ptPrev = m_pPBoard->GetPrevPlotPoint(); - ptPrev -= CSize(rct.Width() / 2, rct.Height() / 2); + wxRect rct = CB::Convert(m_selList.GetPiecesEnclosingRect()); + wxPoint ptPrev = CB::Convert(m_pPBoard->GetPrevPlotPoint()); + ptPrev -= wxSize(rct.GetWidth() / 2, rct.GetHeight() / 2); ptPrev = AdjustPoint(ptPrev); std::vector> listObjs; @@ -1787,7 +1817,7 @@ void CPlayBoardView::OnActPlotDone() // Note that PlaceObjectListOnBoard() automatically detects the // plotted move case and records that fact. - GetDocument().PlaceObjectTableOnBoard(listObjs, ptPrev, m_pPBoard.get()); + GetDocument().PlaceObjectTableOnBoard(listObjs, CB::Convert(ptPrev), m_pPBoard.get()); m_selList.PurgeList(TRUE); // Purge former selections SelectAllObjectsInTable(listObjs); // Select on this board. } @@ -1797,17 +1827,17 @@ void CPlayBoardView::OnActPlotDone() m_nCurToolID = ID_PTOOL_SELECT; } -void CPlayBoardView::OnUpdateActPlotDone(CCmdUI* pCmdUI) +void CPlayBoardView::OnUpdateActPlotDone(wxUpdateUIEvent& pCmdUI) { if (GetDocument().IsPlaying() || GetDocument().IsScenario()) { - pCmdUI->Enable(FALSE); + pCmdUI.Enable(FALSE); return; } - pCmdUI->Enable(m_pPBoard->GetPlotMoveMode()); + pCmdUI.Enable(m_pPBoard->GetPlotMoveMode()); } -void CPlayBoardView::OnActPlotDiscard() +void CPlayBoardView::OnActPlotDiscard(wxCommandEvent& /*event*/) { m_pPBoard->SetPlotMoveMode(FALSE); GetDocument().UpdateAllBoardIndicators(*m_pPBoard); @@ -1815,16 +1845,17 @@ void CPlayBoardView::OnActPlotDiscard() m_nCurToolID = ID_PTOOL_SELECT; } -void CPlayBoardView::OnUpdateActPlotDiscard(CCmdUI* pCmdUI) +void CPlayBoardView::OnUpdateActPlotDiscard(wxUpdateUIEvent& pCmdUI) { if (GetDocument().IsPlaying() || GetDocument().IsScenario()) { - pCmdUI->Enable(FALSE); + pCmdUI.Enable(FALSE); return; } - pCmdUI->Enable(m_pPBoard->GetPlotMoveMode()); + pCmdUI.Enable(m_pPBoard->GetPlotMoveMode()); } +#if 0 void CPlayBoardView::OnViewSnapGrid() { m_pPBoard->m_bGridSnap = !m_pPBoard->m_bGridSnap; diff --git a/GP/VwPbrd.h b/GP/VwPbrd.h index e929876f..f3e3a11a 100644 --- a/GP/VwPbrd.h +++ b/GP/VwPbrd.h @@ -221,14 +221,16 @@ class CPlayBoardView : public CB::ProcessEventOverride afx_msg LRESULT OnDragItem(WPARAM wParam, LPARAM lParam); afx_msg LRESULT OnMessageRotateRelative(WPARAM wParam, LPARAM lParam); afx_msg LRESULT OnMessageCenterBoardOnPoint(WPARAM wParam, LPARAM lParam); - afx_msg void OnLButtonDown(UINT nFlags, CPoint point); #endif + void OnLButtonDown(wxMouseEvent& event); void OnMouseMove(wxMouseEvent& event); + void OnLButtonUp(wxMouseEvent& event); #if 0 - afx_msg void OnLButtonUp(UINT nFlags, CPoint point); afx_msg void OnTimer(uintptr_t nIDEvent); - afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point); - afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message); +#endif + void OnLButtonDblClk(wxMouseEvent& event); + void OnSetCursor(wxSetCursorEvent& event); +#if 0 afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags); afx_msg void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags); afx_msg BOOL OnPlayTool(UINT id); @@ -241,12 +243,14 @@ class CPlayBoardView : public CB::ProcessEventOverride afx_msg void OnUpdateActToFront(CCmdUI* pCmdUI); afx_msg BOOL OnActTurnOver(UINT id); afx_msg void OnUpdateActTurnOver(CCmdUI* pCmdUI); - afx_msg void OnActPlotMove(); - afx_msg void OnUpdateActPlotMove(CCmdUI* pCmdUI); - afx_msg void OnActPlotDone(); - afx_msg void OnUpdateActPlotDone(CCmdUI* pCmdUI); - afx_msg void OnActPlotDiscard(); - afx_msg void OnUpdateActPlotDiscard(CCmdUI* pCmdUI); +#endif + void OnActPlotMove(wxCommandEvent& event); + void OnUpdateActPlotMove(wxUpdateUIEvent& pCmdUI); + void OnActPlotDone(wxCommandEvent& event); + void OnUpdateActPlotDone(wxUpdateUIEvent& pCmdUI); + void OnActPlotDiscard(wxCommandEvent& event); + void OnUpdateActPlotDiscard(wxUpdateUIEvent& pCmdUI); +#if 0 afx_msg void OnUpdateIndicatorCellNum(CCmdUI* pCmdUI); afx_msg void OnViewSnapGrid(); afx_msg void OnUpdateViewSnapGrid(CCmdUI* pCmdUI); diff --git a/GP/VwPbrd1.cpp b/GP/VwPbrd1.cpp index b1d2bd2a..1a7afa39 100644 --- a/GP/VwPbrd1.cpp +++ b/GP/VwPbrd1.cpp @@ -221,7 +221,7 @@ void CPlayBoardView::ClearNotificationTip() m_toolMsgTip.DelTool(this, ID_TIP_PLAYBOARD_MSG); m_toolMsgTip.Activate(FALSE); #else - wxASSERT(!"TODO:"); + CPP20_TRACE("{}->{}: TODO:\n", *this, __func__); #endif } diff --git a/GShr/LibMfc.cpp b/GShr/LibMfc.cpp index 2593e8bf..ed134a17 100644 --- a/GShr/LibMfc.cpp +++ b/GShr/LibMfc.cpp @@ -1318,6 +1318,10 @@ namespace CB #if defined(GPLAY) switch (id) { + case ID_ACT_PLOTDISCARD: + return XRCID("ID_ACT_PLOTDISCARD"); + case ID_ACT_PLOTDONE: + return XRCID("ID_ACT_PLOTDONE"); case ID_ACT_TURNOVER: return XRCID("ID_ACT_TURNOVER"); case ID_ACT_TURNOVER_PREV: @@ -1336,6 +1340,8 @@ namespace CB return XRCID("ID_PPROJITEM_PROPERTIES"); case ID_PPROJITEM_VIEW: return XRCID("ID_PPROJITEM_VIEW"); + case ID_PTOOL_PLOTMOVE: + return XRCID("ID_PTOOL_PLOTMOVE"); case ID_VIEW_BOARD_ROTATE180: return XRCID("ID_VIEW_BOARD_ROTATE180"); case ID_VIEW_FULLSCALEBRD: diff --git a/GShr/ResTbl.cpp b/GShr/ResTbl.cpp index e9ca7843..ef3c94d3 100644 --- a/GShr/ResTbl.cpp +++ b/GShr/ResTbl.cpp @@ -85,7 +85,7 @@ void ResourceTable::LoadCursors(HINSTANCE hInst) hcrColorChange = LoadCursor(hInst, MAKEINTRESOURCE(IDC_COLORCHANGE)); hcrColorChangeWx.SetHCURSOR(reinterpret_cast(LoadCursor(hInst, MAKEINTRESOURCE(IDC_COLORCHANGE)))); #else - hcrCompMoveActive = LoadCursor(hInst, MAKEINTRESOURCE(IDC_CMOVMODE)); + hcrCompMoveActive.SetHCURSOR(reinterpret_cast(LoadCursor(hInst, MAKEINTRESOURCE(IDC_CMOVMODE)))); #endif } @@ -106,8 +106,6 @@ void ResourceTable::FreeCursors(void) DestroyCursor(hcrPencil); DestroyCursor(hcrBrush); DestroyCursor(hcrColorChange); -#else - DestroyCursor(hcrCompMoveActive); #endif } diff --git a/GShr/ResTbl.h b/GShr/ResTbl.h index 74df90ce..b2de3fc6 100644 --- a/GShr/ResTbl.h +++ b/GShr/ResTbl.h @@ -63,7 +63,7 @@ struct ResourceTable HCURSOR hcrColorChange; wxCursor hcrColorChangeWx; #else - HCURSOR hcrCompMoveActive; + wxCursor hcrCompMoveActive; #endif #ifndef GPLAY // ======== Brushes ========= // From 857aa8ca79b0abe64d9e350048f97bbe66d9e533 Mon Sep 17 00:00:00 2001 From: Bill Su Date: Mon, 1 Dec 2025 22:31:33 -0500 Subject: [PATCH 45/80] VwPbrd: use wxScrolledCanvas prepare for dragging between boards --- GP/ToolPlay.cpp | 15 +++++++++++---- GP/ToolPlay.h | 1 + GP/VwPbrd.cpp | 27 +++++++++++++++++++++------ GP/VwPbrd.h | 6 ++++++ GP/VwPbrd1.cpp | 17 +++++++++++++++++ 5 files changed, 56 insertions(+), 10 deletions(-) diff --git a/GP/ToolPlay.cpp b/GP/ToolPlay.cpp index 7b3ba276..26d1395b 100644 --- a/GP/ToolPlay.cpp +++ b/GP/ToolPlay.cpp @@ -42,10 +42,6 @@ static char THIS_FILE[] = __FILE__; #define new DEBUG_NEW #endif -///////////////////////////////////////////////////////////////// - -const int scrollZone = 16; // From INI? - ///////////////////////////////////////////////////////////////// // Class variables @@ -105,6 +101,11 @@ bool CPlayTool::OnLButtonUp(CPlayBoardView& pView, int /*nMods*/, wxPoint /*poin return true; } +void CPlayTool::OnMouseCaptureLost(CPlayBoardView& pView) +{ + // mouse already released +} + //////////////////////////////////////////////////////////////////////// // CPSelectTool - Object Selection/Manipulation tool @@ -200,6 +201,7 @@ void CPSelectTool::OnMouseMove(CPlayBoardView& pView, int nMods, wxPoint point) if (!pView.HasCapture()) return; +#if 0 if (m_eSelMode != smodeNormal && m_eSelMode != smodeMove) { // Autoscroll initiate possibility processing (sounds like a @@ -230,6 +232,7 @@ void CPSelectTool::OnMouseMove(CPlayBoardView& pView, int nMods, wxPoint point) CPP20_TRACE("{}->{}: TODO:\n", *this, __func__); #endif } +#endif // If we get here, the mouse has been captured. Check if // we are doing a "net select". @@ -353,8 +356,10 @@ void CPSelectTool::OnTimer(CPlayBoardView& pView, uintptr_t nIDEvent) } else if (m_eSelMode != smodeMove) { +#if 0 if (!ProcessAutoScroll(pView)) KillScrollTimer(pView); +#endif } } @@ -415,6 +420,7 @@ void CPSelectTool::DrawNetRect(wxDC& pDC, const CPlayBoardView& /*pView*/) const DrawSelectionRect(pDC, rect); } +#if 0 BOOL CPSelectTool::ProcessAutoScroll(CPlayBoardView& pView) { CPoint point; @@ -497,6 +503,7 @@ BOOL CPSelectTool::ProcessAutoScroll(CPlayBoardView& pView) } return FALSE; } +#endif void CPSelectTool::MoveSelections(CSelList &pSLst, const wxPoint& point) { diff --git a/GP/ToolPlay.h b/GP/ToolPlay.h index f08cf536..8db762af 100644 --- a/GP/ToolPlay.h +++ b/GP/ToolPlay.h @@ -59,6 +59,7 @@ class CPlayTool virtual void OnLButtonDblClk(CPlayBoardView& /*pView*/, int /*nMods*/, wxPoint /*point*/) /* override */ {} virtual bool OnLButtonUp(CPlayBoardView& pView, int nMods, wxPoint point) /* override */; virtual void OnMouseMove(CPlayBoardView& pView, int nMods, wxPoint point) /* override */; + virtual void OnMouseCaptureLost(CPlayBoardView& pView) /* override */; virtual void OnTimer(CPlayBoardView& /*pView*/, uintptr_t /*nIDEvent*/) /*override*/ {} virtual wxCursor OnSetCursor(const CPlayBoardView& /*pView*/, const wxPoint& /*point*/) const /*override*/ { return wxCursor(); } diff --git a/GP/VwPbrd.cpp b/GP/VwPbrd.cpp index 7820a9ff..e8448073 100644 --- a/GP/VwPbrd.cpp +++ b/GP/VwPbrd.cpp @@ -57,6 +57,8 @@ IMPLEMENT_DYNCREATE(CPlayBoardViewContainer, CView) ///////////////////////////////////////////////////////////////////////////// +const int scrollZone = 16; // From INI? + wxBEGIN_EVENT_TABLE(CPlayBoardView, CPlayBoardView::BASE) EVT_MENU(XRCID("ID_VIEW_FULLSCALEBRD"), OnViewFullScaleBrd) EVT_UPDATE_UI(XRCID("ID_VIEW_FULLSCALEBRD"), OnUpdateViewFullScaleBrd) @@ -70,6 +72,7 @@ wxBEGIN_EVENT_TABLE(CPlayBoardView, CPlayBoardView::BASE) EVT_LEFT_DOWN(OnLButtonDown) EVT_MOTION(OnMouseMove) EVT_LEFT_UP(OnLButtonUp) + EVT_MOUSE_CAPTURE_LOST(OnMouseCaptureLost) #if 0 ON_WM_TIMER() #endif @@ -182,6 +185,9 @@ CPlayBoardView::CPlayBoardView(CPlayBoardViewContainer& p) : document(dynamic_cast(parent->GetDocument())), m_pPBoard(static_cast(document->GetNewViewParameter())) { + EnableAutoScrollInside(scrollZone); + DisableAutoScrollOutside(); + m_nZoom = fullScale; m_nCurToolID = ID_PTOOL_SELECT; m_bInDrag = FALSE; @@ -1220,6 +1226,13 @@ void CPlayBoardView::OnLButtonUp(wxMouseEvent& event) } } +void CPlayBoardView::OnMouseCaptureLost(wxMouseCaptureLostEvent& event) +{ + PToolType eToolType = MapToolType(m_nCurToolID); + CPlayTool& pTool = CPlayTool::GetTool(eToolType); + pTool.OnMouseCaptureLost(*this); +} + void CPlayBoardView::OnLButtonDblClk(wxMouseEvent& event) { int nMods = event.GetModifiers(); @@ -1284,13 +1297,15 @@ void CPlayBoardView::OnSetCursor(wxSetCursorEvent& event) { CPlayTool& pTool = CPlayTool::GetTool(eToolType); wxPoint point(event.GetX(), event.GetY()); - wxASSERT(GetClientRect().Contains(point)); - point = ClientToWorkspace(point); - wxCursor rc = pTool.OnSetCursor(*this, point); - if (rc.IsOk()) + if (GetClientRect().Contains(point)) { - event.SetCursor(rc); - return; + point = ClientToWorkspace(point); + wxCursor rc = pTool.OnSetCursor(*this, point); + if (rc.IsOk()) + { + event.SetCursor(rc); + return; + } } } if (GetDocument().IsRecordingCompoundMove()) diff --git a/GP/VwPbrd.h b/GP/VwPbrd.h index f3e3a11a..4474a294 100644 --- a/GP/VwPbrd.h +++ b/GP/VwPbrd.h @@ -111,6 +111,11 @@ class CPlayBoardView : public CB::ProcessEventOverride void CenterViewOnWorkspacePoint(wxPoint point); BOOL CheckAutoScroll(wxPoint point); BOOL ProcessAutoScroll(wxPoint point); + // this method can be overridden in a derived class to forbid sending the + // auto scroll events - note that unlike StopAutoScrolling() it doesn't + // stop the timer, so it will be called repeatedly and will typically + // return different values depending on the current mouse position + bool SendAutoScrollEvents(wxScrollWinEvent& event) const override; void SetOurScrollSizes(TileScale nZoom); void DoViewScaleBrd(TileScale nZoom); @@ -225,6 +230,7 @@ class CPlayBoardView : public CB::ProcessEventOverride void OnLButtonDown(wxMouseEvent& event); void OnMouseMove(wxMouseEvent& event); void OnLButtonUp(wxMouseEvent& event); + void OnMouseCaptureLost(wxMouseCaptureLostEvent& event); #if 0 afx_msg void OnTimer(uintptr_t nIDEvent); #endif diff --git a/GP/VwPbrd1.cpp b/GP/VwPbrd1.cpp index 1a7afa39..7f509fd6 100644 --- a/GP/VwPbrd1.cpp +++ b/GP/VwPbrd1.cpp @@ -757,4 +757,21 @@ BOOL CPlayBoardView::ProcessAutoScroll(CPoint point) } #endif +// this method can be overridden in a derived class to forbid sending the +// auto scroll events - note that unlike StopAutoScrolling() it doesn't +// stop the timer, so it will be called repeatedly and will typically +// return different values depending on the current mouse position +bool CPlayBoardView::SendAutoScrollEvents(wxScrollWinEvent& event) const +{ + // scroll if this is the capturing window (net select) + wxASSERT(event.GetEventObject() == this); + if (HasCapture()) + { + return true; + } + // scroll if drag-move + CPlayTool& tool = CPlayTool::GetTool(ptypeSelect); + CPSelectTool& select = dynamic_cast(tool); + return select.m_eSelMode == CPSelectTool::smodeMove; +} From 9793cb43ad3ccdd7c3d7e1310d1967462ad30da6 Mon Sep 17 00:00:00 2001 From: Bill Su Date: Tue, 9 Dec 2025 01:38:54 -0500 Subject: [PATCH 46/80] VwPbrd: implement drag-move --- GP/SelOPlay.cpp | 27 ++------ GP/SelOPlay.h | 15 ++++- GP/ToolPlay.cpp | 141 ++++++++++++++++++++++----------------- GP/ToolPlay.h | 27 ++++---- GP/VwPbrd.cpp | 164 ++++++++++++++++++++++++++++++---------------- GP/VwPbrd.h | 23 ++++--- GP/VwPbrd1.cpp | 16 ++++- GShr/DragDrop.cpp | 4 ++ GShr/DragDrop.h | 12 ++-- 9 files changed, 265 insertions(+), 164 deletions(-) diff --git a/GP/SelOPlay.cpp b/GP/SelOPlay.cpp index ec55797d..72fd8787 100644 --- a/GP/SelOPlay.cpp +++ b/GP/SelOPlay.cpp @@ -49,10 +49,12 @@ const int handleHalfWidth = 3; ///////////////////////////////////////////////////////////////////// // Class level variables -CPen NEAR CSelection::c_penDot(PS_DOT, 1, RGB(0,0,0)); +const wxPen CSelection::c_penDot(*wxLIGHT_GREY, 1, wxPENSTYLE_SHORT_DASH); +#if 0 int NEAR CSelection::c_nPrvROP2; CPen* NEAR CSelection::c_pPrvPen = NULL; CBrush* NEAR CSelection::c_pPrvBrush = NULL; +#endif ///////////////////////////////////////////////////////////////////// @@ -159,25 +161,15 @@ void CSelection::Open() } } -#if 0 //=---------------------------------------------------=// // Static methods... -void CSelection::SetupTrackingDraw(wxDC& pDC) +CSelection::DCSetupTrackingDraw::DCSetupTrackingDraw(wxDC& pDC) : + setPen(pDC, c_penDot), + setBrush(pDC, *wxTRANSPARENT_BRUSH) { - c_nPrvROP2 = pDC.SetROP2(R2_XORPEN); - c_pPrvPen = pDC.SelectObject(&c_penDot); - c_pPrvBrush = (CBrush*)pDC.SelectStockObject(NULL_BRUSH); } -void CSelection::CleanUpTrackingDraw(wxDC& pDC) -{ - pDC.SetROP2(c_nPrvROP2); - pDC.SelectObject(c_pPrvPen); - pDC.SelectObject(c_pPrvBrush); -} -#endif - ///////////////////////////////////////////////////////////////////// // Line Selection Processing @@ -298,13 +290,8 @@ void CSelGeneric::AddHandles(CHandleList& listHandles) void CSelGeneric::DrawTrackingImage(wxDC& pDC, TrackMode eMode) const { -#if 0 - SetupTrackingDraw(pDC); + DCSetupTrackingDraw setupTrackingDraw(pDC); pDC.DrawRectangle(CB::Convert(m_rect)); - CleanUpTrackingDraw(pDC); -#else - wxASSERT(!"TODO:"); -#endif } // Returns handle location in logical coords. diff --git a/GP/SelOPlay.h b/GP/SelOPlay.h index 02668971..ac1ae8d7 100644 --- a/GP/SelOPlay.h +++ b/GP/SelOPlay.h @@ -116,13 +116,26 @@ class CSelection protected: RefPtr m_pView; // Selection's view // -- Class level support methods -- // +#if 0 static void SetupTrackingDraw(wxDC& pDC); static void CleanUpTrackingDraw(wxDC& pDC); +#else + class DCSetupTrackingDraw + { + public: + DCSetupTrackingDraw(wxDC& pDC); + private: + wxDCPenChanger setPen; + wxDCBrushChanger setBrush; + }; +#endif // -- Class variables -- // - static CPen NEAR c_penDot; + static const wxPen c_penDot; +#if 0 static int NEAR c_nPrvROP2; static CPen* NEAR c_pPrvPen; static CBrush* NEAR c_pPrvBrush; +#endif }; ///////////////////////////////////////////////////////////////////// diff --git a/GP/ToolPlay.cpp b/GP/ToolPlay.cpp index 26d1395b..62826ea4 100644 --- a/GP/ToolPlay.cpp +++ b/GP/ToolPlay.cpp @@ -229,7 +229,7 @@ void CPSelectTool::OnMouseMove(CPlayBoardView& pView, int nMods, wxPoint point) else KillScrollTimer(pView); #else - CPP20_TRACE("{}->{}: TODO:\n", *this, __func__); + CPP20_TRACE("{}->{}: TODO: wxProvides autoscroll?\n", *this, __func__); #endif } #endif @@ -313,17 +313,35 @@ bool CPSelectTool::OnLButtonUp(CPlayBoardView& pView, int nMods, wxPoint point) } m_eSelMode = smodeNormal; KillDragTimer(pView); // Make sure timers are released +#if 0 KillScrollTimer(pView); +#endif return CPlayTool::OnLButtonUp(pView, nMods, point) && retval; } -void CPSelectTool::OnTimer(CPlayBoardView& pView, uintptr_t nIDEvent) +void CPSelectTool::OnMouseCaptureLost(CPlayBoardView& pView) +{ + pView.GetOverlay().Reset(); + pView.SetCursor(wxCursor(wxCURSOR_ARROW)); + m_eSelMode = smodeNormal; + KillDragTimer(pView); // Make sure timers are released +#if 0 + KillScrollTimer(pView); +#endif + CPlayTool::OnMouseCaptureLost(pView); +} + +void CPSelectTool::OnTimer(CPlayBoardView& pView, int nIDEvent) { + wxASSERT(nIDEvent == XRCID("timerIDSelectDelay") && + nIDEvent == m_nTimerID); if (!pView.HasCapture()) { m_eSelMode = smodeNormal; KillDragTimer(pView); +#if 0 KillScrollTimer(pView); +#endif return; } if (m_eSelMode == smodeNormal) @@ -340,27 +358,28 @@ void CPSelectTool::OnTimer(CPlayBoardView& pView, uintptr_t nIDEvent) CClientDC dc(&pView); pView.OnPrepareScaledDC(dc, TRUE); pSLst.DrawTracker(dc, trkSelected); // Turn off handles +#else + wxOverlayDC dc(pView.GetOverlay(), &pView); + pView.OnPrepareScaledDC(dc); + dc.Clear(); +#endif - CPoint point; - GetCursorPos(&point); - point = CB::Convert(pView.ScreenToClient(CB::Convert(point))); - point = CB::Convert(pView.ClientToWorkspace(CB::Convert(point))); + wxPoint point = wxGetMouseState().GetPosition(); + point = pView.ScreenToClient(point); + point = pView.ClientToWorkspace(point); pSLst.SetTrackingMode(trkMoving); DoDragDropStart(pView); - point = CB::Convert(pView.WorkspaceToClient(CB::Convert(point))); + point = pView.WorkspaceToClient(point); DoDragDrop(pView, point); -#else - wxASSERT(!"TODO:"); -#endif } +#if 0 else if (m_eSelMode != smodeMove) { -#if 0 if (!ProcessAutoScroll(pView)) KillScrollTimer(pView); -#endif } +#endif } void CPSelectTool::OnLButtonDblClk(CPlayBoardView& pView, int nMods, @@ -539,27 +558,21 @@ wxPoint CPSelectTool::AdjustPoint(const CPlayBoardView& pView, wxPoint point) co void CPSelectTool::StartDragTimer(CPlayBoardView& pView) { -#if 0 - m_nTimerID = pView.SetTimer(timerIDSelectDelay, - timerSelDelay, NULL); -#else - CPP20_TRACE("{}->{}: TODO:\n", *this, __func__); -#endif + pView.SetTimer(XRCID("timerIDSelectDelay"), + timerSelDelay); + m_nTimerID = XRCID("timerIDSelectDelay"); } void CPSelectTool::KillDragTimer(CPlayBoardView& pView) { -#if 0 - if (m_nTimerID != uintptr_t(0)) + if (m_nTimerID != static_cast(wxID_NONE)) { pView.KillTimer(m_nTimerID); - m_nTimerID = uintptr_t(0); + m_nTimerID = static_cast(wxID_NONE); } -#else - CPP20_TRACE("{}->{}: TODO:\n", *this, __func__); -#endif } +#if 0 void CPSelectTool::StartScrollTimer(CPlayBoardView& pView) { #if 0 @@ -581,87 +594,93 @@ void CPSelectTool::KillScrollTimer(CPlayBoardView& pView) CPP20_TRACE("{}->{}: TODO:\n", *this, __func__); #endif } +#endif //////////////////////////////////////////////////////////////////////// // Note: The CSelList should have had the mouse offset value set at // this time. void CPSelectTool::DoDragDropStart(CPlayBoardView& pView) { - wxASSERT(!"TODO:"); m_di.SetDragType(DRAG_SELECTLIST); m_di.GetSubInfo().m_selectList = &pView.GetSelectList(); m_di.GetSubInfo().m_gamDoc = &pView.GetDocument(); - m_di.m_hcsrSuggest = g_res.hcrDragTile; + m_di.m_hcsrSuggest = g_res.hcrDragTileWx; m_hLastWnd = NULL; } void CPSelectTool::DoDragDrop(CPlayBoardView& pView, const wxPoint& pntClient) { - wxASSERT(!"TODO:"); -#if 0 - CPoint pnt = pntClient; - pnt = CB::Convert(pView.ClientToScreen(CB::Convert(pnt))); - CWnd* pWnd = GetWindowFromPoint(pnt); + wxPoint pnt = pntClient; + pnt = pView.ClientToScreen(pnt); + wxWindow* pWnd = wxFindWindowAtPoint(pnt); - HWND hWnd = pWnd ? pWnd->m_hWnd : NULL; // Get actual window handle - if (hWnd != m_hLastWnd) + if (pWnd != m_hLastWnd) { if (m_hLastWnd != NULL) { // Signal previous window we are leaving them - CWnd& pLstWnd = CheckedDeref(CWnd::FromHandle(m_hLastWnd)); + wxWindow& pLstWnd = CheckedDeref(m_hLastWnd); m_di.m_phase = PhaseDrag::Exit; - pLstWnd.SendMessage(WM_DRAGDROP, GetProcessId(GetCurrentProcess()), - (LPARAM)(LPVOID)&m_di); + DragDropEvent dragDropEvent(wxGetProcessId(), m_di); + pLstWnd.ProcessWindowEvent(dragDropEvent); } // Signal new window we have entered it. if (pWnd != NULL) { m_di.m_phase = PhaseDrag::Enter; - pWnd->SendMessage(WM_DRAGDROP, GetProcessId(GetCurrentProcess()), - (LPARAM)(LPVOID)&m_di); + DragDropEvent dragDropEvent(wxGetProcessId(), m_di); + pWnd->ProcessWindowEvent(dragDropEvent); } } - HCURSOR hCursor = NULL; - if (hWnd != NULL) + wxCursor hCursor; + if (pWnd != NULL) { m_di.m_point = pntClient; - m_di.m_point = CB::Convert(pView.ClientToScreen(CB::Convert(m_di.m_point))); // Move point into new coord system - pWnd->ScreenToClient(&m_di.m_point); + m_di.m_point = pView.ClientToScreen(m_di.m_point); // Move point into new coord system + m_di.m_point = pWnd->ScreenToClient(m_di.m_point); m_di.m_phase = PhaseDrag::Over; - hCursor = (HCURSOR)pWnd->SendMessage(WM_DRAGDROP, GetProcessId(GetCurrentProcess()), - (LPARAM)(LPVOID)&m_di); + DragDropEvent dragDropEvent(wxGetProcessId(), m_di); + pWnd->ProcessWindowEvent(dragDropEvent); + hCursor = dragDropEvent.GetCursor(); } - m_hLastWnd = hWnd; + m_hLastWnd = pWnd; - if (hCursor) - SetCursor(hCursor); + wxWindow& capture = CheckedDeref(wxWindow::GetCapture()); + if (hCursor.IsOk()) + { + wxASSERT(&capture == &pView); + capture.SetCursor(hCursor); + } else - SetCursor(g_res.hcrNoDrop); -#endif + { + wxASSERT(&capture == &pView); + capture.SetCursor(g_res.hcrNoDropWx); + } } bool CPSelectTool::DoDragDropEnd(CPlayBoardView& pView, const wxPoint& pntClient) { -#if 1 - wxASSERT(!"TODO:"); - return false; -#else - SetCursor(LoadCursor(NULL, IDC_ARROW)); + pView.SetCursor(wxCursor(wxCURSOR_ARROW)); wxPoint pnt = pntClient; - pView.ClientToScreen(pnt); - CWnd* pWnd = GetWindowFromPoint(CB::Convert(pnt)); + pnt = pView.ClientToScreen(pnt); + wxWindow* pWnd = wxFindWindowAtPoint(pnt); if (pWnd == NULL) return false; + if (pWnd != &pView) + { + pWnd->SetCursor(wxCursor(wxCURSOR_ARROW)); + } m_di.m_point = pntClient; - m_di.m_point = CB::Convert(pView.ClientToScreen(CB::Convert(m_di.m_point))); - pWnd->ScreenToClient(&m_di.m_point); + m_di.m_point = pView.ClientToScreen(m_di.m_point); + m_di.m_point = pWnd->ScreenToClient(m_di.m_point); m_di.m_phase = PhaseDrag::Drop; - return pWnd->SendMessage(WM_DRAGDROP, GetProcessId(GetCurrentProcess()), (LPARAM)(LPVOID)&m_di) == 1; -#endif + DragDropEvent dragDropEvent(wxGetProcessId(), m_di); + pWnd->ProcessWindowEvent(dragDropEvent); + return dragDropEvent.GetResult() && + *dragDropEvent.GetResult(); } //////////////////////////////////////////////////////////////////////// @@ -703,7 +722,7 @@ void CPShapeTool::OnMouseMove(CPlayBoardView& pView, int nMods, wxPoint point) s_plySelectTool.OnMouseMove(pView, nMods, point); } -void CPShapeTool::OnTimer(CPlayBoardView& pView, uintptr_t nIDEvent) +void CPShapeTool::OnTimer(CPlayBoardView& pView, int nIDEvent) { wxASSERT(!"dead code"); s_plySelectTool.OnTimer(pView, nIDEvent); diff --git a/GP/ToolPlay.h b/GP/ToolPlay.h index 8db762af..504a9cf0 100644 --- a/GP/ToolPlay.h +++ b/GP/ToolPlay.h @@ -31,9 +31,9 @@ class CPlayBoardView; -const UINT timerIDSelectDelay = 666; // Select timer ID +// XRCID("timerIDSelectDelay"); // Select timer ID const UINT timerIDAutoScroll = 999; // Autoscroll timer ID -const int timerSelDelay = 250; // Delay until select +const unsigned timerSelDelay = 250; // Delay until select const int timerAutoScroll = 80; // Interval of autoscrolls enum PToolType { ptypeUnknown, ptypeSelect, ptypeLine, ptypeTextBox, @@ -60,7 +60,7 @@ class CPlayTool virtual bool OnLButtonUp(CPlayBoardView& pView, int nMods, wxPoint point) /* override */; virtual void OnMouseMove(CPlayBoardView& pView, int nMods, wxPoint point) /* override */; virtual void OnMouseCaptureLost(CPlayBoardView& pView) /* override */; - virtual void OnTimer(CPlayBoardView& /*pView*/, uintptr_t /*nIDEvent*/) /*override*/ {} + virtual void OnTimer(CPlayBoardView& /*pView*/, int /*nIDEvent*/) /*override*/ {} virtual wxCursor OnSetCursor(const CPlayBoardView& /*pView*/, const wxPoint& /*point*/) const /*override*/ { return wxCursor(); } @@ -99,7 +99,7 @@ class CPSelectTool : public CPlayTool { // Constructors public: - CPSelectTool() : CPlayTool(ptypeSelect) { m_nTimerID = uintptr_t(0); } + CPSelectTool() : CPlayTool(ptypeSelect) { m_nTimerID = static_cast(wxID_NONE); } // Attributes public: @@ -109,8 +109,8 @@ class CPSelectTool : public CPlayTool SelectMode m_eSelMode; int m_nHandleID; // Inter-view Drag/Drop processing support - DragInfo m_di; - HWND m_hLastWnd; + DragInfoWx m_di; + wxWindow* m_hLastWnd; // Operations public: @@ -118,23 +118,28 @@ class CPSelectTool : public CPlayTool void OnLButtonDblClk(CPlayBoardView& pView, int nMods, wxPoint point) override; bool OnLButtonUp(CPlayBoardView& pView, int nMods, wxPoint point) override; void OnMouseMove(CPlayBoardView& pView, int nMods, wxPoint point) override; - void OnTimer(CPlayBoardView& pView, uintptr_t nIDEvent) override; + void OnMouseCaptureLost(CPlayBoardView& pView) override; + void OnTimer(CPlayBoardView& pView, int nIDEvent) override; wxCursor OnSetCursor(const CPlayBoardView& pView, const wxPoint& point) const override; // Implementation public: - uintptr_t m_nTimerID; + int m_nTimerID; wxRect m_rectMultiBorder; // ------- // +#if 0 BOOL ProcessAutoScroll(CPlayBoardView& pView); +#endif void DrawSelectionRect(wxDC& pDC, const wxRect& pRct) const; void DrawNetRect(wxDC& pDC, const CPlayBoardView& pView) const; [[nodiscard]] wxPoint AdjustPoint(const CPlayBoardView& pView, wxPoint point) const; void MoveSelections(CSelList &pSLst, const wxPoint& point); void StartDragTimer(CPlayBoardView& pView); void KillDragTimer(CPlayBoardView& pView); +#if 0 void StartScrollTimer(CPlayBoardView& pView); void KillScrollTimer(CPlayBoardView& pView); +#endif // ------- // void DoDragDropStart(CPlayBoardView& pView); void DoDragDrop(CPlayBoardView& pView, const wxPoint& pntClient); @@ -159,7 +164,7 @@ class CPShapeTool : public CPlayTool void OnLButtonDblClk(CPlayBoardView& /*pView*/, int /*nMods*/, wxPoint /*point*/) override {} bool OnLButtonUp(CPlayBoardView& pView, int nMods, wxPoint point) override; void OnMouseMove(CPlayBoardView& pView, int nMods, wxPoint point) override; - void OnTimer(CPlayBoardView& pView, uintptr_t nIDEvent) override; + void OnTimer(CPlayBoardView& pView, int nIDEvent) override; wxCursor OnSetCursor(const CPlayBoardView& pView, const wxPoint& point) const override; // Implementation @@ -202,7 +207,7 @@ class CPTextBoxTool : public CPlayTool void OnLButtonDblClk(CPlayBoardView& /*pView*/, int /*nMods*/, wxPoint /*point*/) override {} bool OnLButtonUp(CPlayBoardView& /*pView*/, int /*nMods*/, wxPoint /*point*/) override { return true; } void OnMouseMove(CPlayBoardView& /*pView*/, int /*nMods*/, wxPoint /*point*/) override {} - void OnTimer(CPlayBoardView& /*pView*/, uintptr_t /*nIDEvent*/) override {} + void OnTimer(CPlayBoardView& /*pView*/, int /*nIDEvent*/) override {} wxCursor OnSetCursor(const CPlayBoardView& pView, const wxPoint& point) const override; // Implementation @@ -225,7 +230,7 @@ class CPPlotTool : public CPlayTool void OnLButtonDblClk(CPlayBoardView& /*pView*/, int /*nMods*/, wxPoint /*point*/) override {} bool OnLButtonUp(CPlayBoardView& /*pView*/, int /*nMods*/, wxPoint /*point*/) override { return true; } void OnMouseMove(CPlayBoardView& /*pView*/, int /*nMods*/, wxPoint /*point*/) override {} - void OnTimer(CPlayBoardView& /*pView*/, uintptr_t /*nIDEvent*/) override {} + void OnTimer(CPlayBoardView& /*pView*/, int /*nIDEvent*/) override {} wxCursor OnSetCursor(const CPlayBoardView& pView, const wxPoint& point) const override; // Implementation diff --git a/GP/VwPbrd.cpp b/GP/VwPbrd.cpp index e8448073..9bbee33e 100644 --- a/GP/VwPbrd.cpp +++ b/GP/VwPbrd.cpp @@ -64,8 +64,8 @@ wxBEGIN_EVENT_TABLE(CPlayBoardView, CPlayBoardView::BASE) EVT_UPDATE_UI(XRCID("ID_VIEW_FULLSCALEBRD"), OnUpdateViewFullScaleBrd) EVT_MENU(XRCID("ID_VIEW_HALFSCALEBRD"), OnViewHalfScaleBrd) EVT_UPDATE_UI(XRCID("ID_VIEW_HALFSCALEBRD"), OnUpdateViewHalfScaleBrd) + EVT_DRAGDROP(OnDragItem) #if 0 - ON_REGISTERED_MESSAGE(WM_DRAGDROP, OnDragItem) ON_MESSAGE(WM_ROTATEPIECE_DELTA, OnMessageRotateRelative) ON_MESSAGE(WM_CENTERBOARDONPOINT, OnMessageCenterBoardOnPoint) #endif @@ -73,9 +73,7 @@ wxBEGIN_EVENT_TABLE(CPlayBoardView, CPlayBoardView::BASE) EVT_MOTION(OnMouseMove) EVT_LEFT_UP(OnLButtonUp) EVT_MOUSE_CAPTURE_LOST(OnMouseCaptureLost) -#if 0 - ON_WM_TIMER() -#endif + EVT_TIMER(wxID_ANY, OnTimer) EVT_LEFT_DCLICK(OnLButtonDblClk) EVT_SET_CURSOR(OnSetCursor) #if 0 @@ -599,36 +597,46 @@ void CPlayBoardView::OnDraw(wxDC& pDC) ///////////////////////////////////////////////////////////////////////////// -#if 0 -LRESULT CPlayBoardView::OnDragItem(WPARAM wParam, LPARAM lParam) +void CPlayBoardView::OnDragItem(DragDropEvent& event) { - if (wParam != GetProcessId(GetCurrentProcess())) + if (event.GetProcessId() != wxGetProcessId()) { - return -1; + return; } if (GetDocument().IsPlaying()) - return -1; // Drags not supported during play + return; // Drags not supported during play - const DragInfo& pdi = CheckedDeref(reinterpret_cast(lParam)); + const DragInfoWx& pdi = event.GetDragInfo(); if (pdi.GetDragType() == DRAG_PIECE) - return DoDragPiece(pdi); + { + DoDragPiece(pdi); + return; + } if (pdi.GetDragType() == DRAG_PIECELIST) - return DoDragPieceList(pdi); + { + DoDragPieceList(pdi); + return; + } if (pdi.GetDragType() == DRAG_MARKER) - return DoDragMarker(pdi); + { + DoDragMarker(pdi); + return; + } if (pdi.GetDragType() == DRAG_SELECTLIST) - return DoDragSelectList(pdi); - - return 0; + { + DoDragSelectList(event); + return; + } } -LRESULT CPlayBoardView::DoDragPiece(const DragInfo& pdi) +void CPlayBoardView::DoDragPiece(const DragInfoWx& pdi) { - ASSERT(FALSE); //!!!NOT USED???? //TODO: WHAT'S GOING ON HERE? 20200618 + wxASSERT(FALSE); //!!!NOT USED???? //TODO: WHAT'S GOING ON HERE? 20200618 +#if 0 if (pdi.GetSubInfo().m_gamDoc != &GetDocument()) return -1; // Only pieces from our document. @@ -658,13 +666,15 @@ LRESULT CPlayBoardView::DoDragPiece(const DragInfo& pdi) DragKillAutoScroll(); } return 1; +#endif } -LRESULT CPlayBoardView::DoDragPieceList(const DragInfo& pdi) +void CPlayBoardView::DoDragPieceList(const DragInfoWx& pdi) { if (pdi.GetSubInfo().m_gamDoc != &GetDocument()) - return -1; // Only pieces from our document. + return; // Only pieces from our document. +#if 0 // if piece can't fit on board, reject drop CSize limit = m_pPBoard->GetBoard()->GetSize(fullScale); if (pdi.GetSubInfo().m_size.cx > limit.cx || @@ -718,17 +728,21 @@ LRESULT CPlayBoardView::DoDragPieceList(const DragInfo& pdi) DragKillAutoScroll(); } return 1; +#else + wxASSERT(!"TODO:"); +#endif } #define MARKER_DROP_GAP_X 8 -LRESULT CPlayBoardView::DoDragMarker(const DragInfo& pdi) +void CPlayBoardView::DoDragMarker(const DragInfoWx& pdi) { - ASSERT(pdi.GetDragType() == DRAG_MARKER); + wxASSERT(pdi.GetDragType() == DRAG_MARKER); CGamDoc& pDoc = GetDocument(); if (pdi.GetSubInfo().m_gamDoc != &pDoc) - return -1; // Only markers from our document. + return; // Only markers from our document. +#if 0 // if marker can't fit on board, reject drop CSize limit = m_pPBoard->GetBoard()->GetSize(fullScale); if (pdi.GetSubInfo().m_size.cx > limit.cx || @@ -853,65 +867,89 @@ LRESULT CPlayBoardView::DoDragMarker(const DragInfo& pdi) } } return 1; +#else + wxASSERT(!"TODO:"); +#endif } -LRESULT CPlayBoardView::DoDragSelectList(const DragInfo& pdi) +void CPlayBoardView::DoDragSelectList(DragDropEvent& event) { + const DragInfoWx& pdi = event.GetDragInfo(); if (pdi.GetSubInfo().m_gamDoc != &GetDocument()) - return -1; // Only pieces from our document. + return; // Only pieces from our document. - CPoint pdi_m_point = ClientToWorkspace(pdi.m_point); + // allow autoscroll while this is drag destination + switch (pdi.m_phase) + { + case PhaseDrag::Enter: + EnableAutoscrollWithoutCapture(); + break; + case PhaseDrag::Exit: + case PhaseDrag::Drop: + DisableAutoscrollWithoutCapture(); + break; + } + + wxPoint pdi_m_point = ClientToWorkspace(pdi.m_point); CSelList *pSLst = pdi.GetSubInfo().m_selectList; - CDC& pDC = CheckedDeref(GetDC()); + wxOverlayDC pDC(GetOverlay(), this); OnPrepareScaledDC(pDC, TRUE); + pDC.Clear(); if (pdi.m_phase == PhaseDrag::Exit || pdi.m_phase == PhaseDrag::Drop || pdi.m_phase == PhaseDrag::Over) { // Remove previous drag image. +#if 0 pSLst->DrawTracker(pDC, trkMoving); +#elif 0 + GetOverlay().Reset(); +#endif } +#if 0 if (pdi.m_phase == PhaseDrag::Exit) DragKillAutoScroll(); +#endif - CRect rctSnapRef = pSLst->GetSnapReferenceRect(); - CPoint pntSnapRefTopLeft = rctSnapRef.TopLeft(); + wxRect rctSnapRef = CB::Convert(pSLst->GetSnapReferenceRect()); + wxPoint pntSnapRefTopLeft = rctSnapRef.GetTopLeft(); - CPoint pntMseOff = pntSnapRefTopLeft + pSLst->GetMouseOffset(); - CSize sizeDelta = pdi_m_point - pntMseOff; // Trial delta + wxPoint pntMseOff = pntSnapRefTopLeft + CB::Convert(pSLst->GetMouseOffset()); + wxPoint sizeDelta = pdi_m_point - pntMseOff; // Trial delta - rctSnapRef += (CPoint)sizeDelta; // Calc trial new position + rctSnapRef.Offset(sizeDelta); // Calc trial new position rctSnapRef = AdjustRect(rctSnapRef); // Force onto grid. - sizeDelta = rctSnapRef.TopLeft() - pntSnapRefTopLeft; // Calc actual offset + sizeDelta = rctSnapRef.GetTopLeft() - pntSnapRefTopLeft; // Calc actual offset - if (sizeDelta.cx != 0 || sizeDelta.cy != 0) + if (sizeDelta.x != 0 || sizeDelta.y != 0) { // We still have to make sure the larger rect hasn't left the // playing area. - CRect rctObjs = pSLst->GetEnclosingRect(); - rctObjs += (CPoint)sizeDelta; // Calc trial new position + wxRect rctObjs = CB::Convert(pSLst->GetEnclosingRect()); + rctObjs.Offset(sizeDelta); // Calc trial new position BOOL bXOK, bYOK; if (!IsRectFullyOnBoard(rctObjs, &bXOK, &bYOK)) { - CRect temp = rctObjs; + wxRect temp = rctObjs; temp = LimitRect(temp); // if enclosing rect can't fit on board, reject drop if (!IsRectFullyOnBoard(temp, &bXOK, &bYOK)) { - return pdi.m_phase == PhaseDrag::Over ? - reinterpret_cast(g_res.hcrNoDropTooBig) - : - -1; + if (pdi.m_phase == PhaseDrag::Over) + { + event.SetCursor(g_res.hcrNoDropTooBigWx); + } + return; } - sizeDelta += temp.TopLeft() - rctObjs.TopLeft(); + sizeDelta += temp.GetTopLeft() - rctObjs.GetTopLeft(); } - if (sizeDelta.cx != 0 || sizeDelta.cy != 0) // Check 'em again (what a pain!) - pSLst->Offset((CPoint)sizeDelta); + if (sizeDelta.x != 0 || sizeDelta.y != 0) // Check 'em again (what a pain!) + pSLst->Offset(CB::Convert(sizeDelta)); } - CRect rctObjs = pSLst->GetEnclosingRect(); - CPoint pntTopLeft = rctObjs.TopLeft(); + wxRect rctObjs = CB::Convert(pSLst->GetEnclosingRect()); + wxPoint pntTopLeft = rctObjs.GetTopLeft(); if (pdi.m_phase == PhaseDrag::Over || pdi.m_phase == PhaseDrag::Enter) { @@ -919,25 +957,29 @@ LRESULT CPlayBoardView::DoDragSelectList(const DragInfo& pdi) // Draw new drag image. pSLst->DrawTracker(pDC, trkMoving); } - ReleaseDC(&pDC); if (pdi.m_phase == PhaseDrag::Over) { +#if 0 DragCheckAutoScroll(); - return (LRESULT)(LPVOID)pdi.m_hcsrSuggest; +#endif + event.SetCursor(pdi.m_hcsrSuggest); + return; } else if (pdi.m_phase == PhaseDrag::Drop) { CGamDoc& pDoc = GetDocument(); // Whoooopppp...Whoooopppp!!! Drop occurred here.... +#if 0 DragKillAutoScroll(); +#endif std::vector> listObjs; pSLst->LoadTableWithObjectPtrs(listObjs, CSelList::otAll, FALSE); pSLst->PurgeList(FALSE); // Purge source list pDoc.AssignNewMoveGroup(); - pDoc.PlaceObjectTableOnBoard(listObjs, rctObjs.TopLeft(), m_pPBoard.get()); + pDoc.PlaceObjectTableOnBoard(listObjs, CB::Convert(rctObjs.GetTopLeft()), m_pPBoard.get()); m_selList.PurgeList(TRUE); // Purge former selections @@ -948,16 +990,18 @@ LRESULT CPlayBoardView::DoDragSelectList(const DragInfo& pdi) SelectAllObjectsInTable(listObjs); // Reselect on this board. } - CFrameWnd* pFrame = GetParentFrame(); - pFrame->SetActiveView(this); + CFrameWnd* pFrame = parent->GetParentFrame(); + pFrame->SetActiveView(&*parent); - pDoc.UpdateAllViews(this, HINT_UPDATESELECTLIST); + pDoc.UpdateAllViews(&*parent, HINT_UPDATESELECTLIST); NotifySelectListChange(); } - return 1; + event.SetResult(true); + return; } +#if 0 void CPlayBoardView::DragDoAutoScroll() { CPoint ptBefore(0, 0); @@ -1254,9 +1298,9 @@ void CPlayBoardView::OnLButtonDblClk(wxMouseEvent& event) event.Skip(); } -#if 0 -void CPlayBoardView::OnTimer(uintptr_t nIDEvent) +void CPlayBoardView::OnTimer(wxTimerEvent& event) { +#if 0 if (m_nTimerID == nIDEvent) { CPoint point; @@ -1272,17 +1316,21 @@ void CPlayBoardView::OnTimer(uintptr_t nIDEvent) } else { +#endif if (!GetDocument().IsPlaying()) { PToolType eToolType = MapToolType(m_nCurToolID); CPlayTool& pTool = CPlayTool::GetTool(eToolType); - pTool.OnTimer(*this, nIDEvent); + pTool.OnTimer(*this, event.GetId()); } else - CScrollView::OnTimer(nIDEvent); + { + event.Skip(); + } +#if 0 } -} #endif +} void CPlayBoardView::OnSetCursor(wxSetCursorEvent& event) { diff --git a/GP/VwPbrd.h b/GP/VwPbrd.h index 4474a294..78ca1334 100644 --- a/GP/VwPbrd.h +++ b/GP/VwPbrd.h @@ -158,6 +158,13 @@ class CPlayBoardView : public CB::ProcessEventOverride CB::propagate_const m_pDragSelList; // Pointer the select list being dragged #if 0 uintptr_t m_nTimerID; // Used to control autoscrolls +#else +public: + void SetTimer(int id, unsigned milliseconds); + void KillTimer(int id); +private: + OwnerOrNullPtr timer; +protected: #endif // -------- // UINT m_nCurToolID; // Current tool ID @@ -191,14 +198,16 @@ class CPlayBoardView : public CB::ProcessEventOverride CB::DCLogicalOriginChanger logOrgChanger; }; - LRESULT DoDragPiece(const DragInfo& pdi); - LRESULT DoDragMarker(const DragInfo& pdi); - LRESULT DoDragPieceList(const DragInfo& pdi); - LRESULT DoDragSelectList(const DragInfo& pdi); + void DoDragPiece(const DragInfoWx& pdi); + void DoDragMarker(const DragInfoWx& pdi); + void DoDragPieceList(const DragInfoWx& pdi); + void DoDragSelectList(DragDropEvent& event); +#if 0 void DragDoAutoScroll(); void DragCheckAutoScroll(); void DragKillAutoScroll(); +#endif void DoAutostackOfSelectedObjects(int xStagger, int yStagger); void DoRotateRelative(BOOL bWheelRotation); @@ -222,8 +231,8 @@ class CPlayBoardView : public CB::ProcessEventOverride void OnUpdateViewFullScaleBrd(wxUpdateUIEvent& pCmdUI); void OnViewHalfScaleBrd(wxCommandEvent& event); void OnUpdateViewHalfScaleBrd(wxUpdateUIEvent& pCmdUI); + void OnDragItem(DragDropEvent& event); #if 0 - afx_msg LRESULT OnDragItem(WPARAM wParam, LPARAM lParam); afx_msg LRESULT OnMessageRotateRelative(WPARAM wParam, LPARAM lParam); afx_msg LRESULT OnMessageCenterBoardOnPoint(WPARAM wParam, LPARAM lParam); #endif @@ -231,9 +240,7 @@ class CPlayBoardView : public CB::ProcessEventOverride void OnMouseMove(wxMouseEvent& event); void OnLButtonUp(wxMouseEvent& event); void OnMouseCaptureLost(wxMouseCaptureLostEvent& event); -#if 0 - afx_msg void OnTimer(uintptr_t nIDEvent); -#endif + void OnTimer(wxTimerEvent& event); void OnLButtonDblClk(wxMouseEvent& event); void OnSetCursor(wxSetCursorEvent& event); #if 0 diff --git a/GP/VwPbrd1.cpp b/GP/VwPbrd1.cpp index 7f509fd6..a5a3f250 100644 --- a/GP/VwPbrd1.cpp +++ b/GP/VwPbrd1.cpp @@ -630,6 +630,19 @@ BOOL CPlayBoardView::IsRectFullyOnBoard(const wxRect& pRct, BOOL* pbXOK, BOOL* p return bOK; } +void CPlayBoardView::SetTimer(int id, unsigned milliseconds) +{ + wxASSERT(!timer); + timer = MakeOwner(this, id); + CB_VERIFY(timer->Start(value_preserving_cast(milliseconds))); +} + +void CPlayBoardView::KillTimer(int id) +{ + wxASSERT(timer && timer->GetId() == id); + timer = nullptr; +} + wxPoint CPlayBoardView::AdjustPoint(wxPoint pnt) const { pnt.x = GridizeX(pnt.x); @@ -764,8 +777,9 @@ BOOL CPlayBoardView::ProcessAutoScroll(CPoint point) bool CPlayBoardView::SendAutoScrollEvents(wxScrollWinEvent& event) const { // scroll if this is the capturing window (net select) + // or this is drag destination wxASSERT(event.GetEventObject() == this); - if (HasCapture()) + if (HasCapture() || GetAutoscrollWithoutCapture()) { return true; } diff --git a/GShr/DragDrop.cpp b/GShr/DragDrop.cpp index b1be7f60..e17d1d05 100644 --- a/GShr/DragDrop.cpp +++ b/GShr/DragDrop.cpp @@ -103,12 +103,14 @@ void DragInfoWx::SetDragType(DragType dt) case DRAG_PIECELIST: subInfos.m_pieceList.~SubInfo(); break; +#endif case DRAG_MARKER: subInfos.m_marker.~SubInfo(); break; case DRAG_SELECTLIST: subInfos.m_selectList.~SubInfo(); break; +#if 0 case DRAG_SELECTVIEW: subInfos.m_selectView.~SubInfo(); break; @@ -137,12 +139,14 @@ void DragInfoWx::SetDragType(DragType dt) case DRAG_PIECELIST: new (&subInfos.m_pieceList) SubInfo; break; +#endif case DRAG_MARKER: new (&subInfos.m_marker) SubInfo; break; case DRAG_SELECTLIST: new (&subInfos.m_selectList) SubInfo; break; +#if 0 case DRAG_SELECTVIEW: new (&subInfos.m_selectView) SubInfo; break; diff --git a/GShr/DragDrop.h b/GShr/DragDrop.h index 5a5b3807..9724ba65 100644 --- a/GShr/DragDrop.h +++ b/GShr/DragDrop.h @@ -1,6 +1,6 @@ // DragDrop.h // -// Copyright (c) 1994-2024 By Dale L. Larson & William Su, All Rights Reserved. +// Copyright (c) 1994-2025 By Dale L. Larson & William Su, All Rights Reserved. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the @@ -70,6 +70,9 @@ class DragDropEvent : public wxEvent wxCursor GetCursor() const { return cursor; } void SetCursor(wxCursor c) { cursor = c; } + const std::optional& GetResult() const { return result; } + void SetResult(bool b) { wxASSERT(!result); result = b; } + wxEvent* Clone() const override { return new DragDropEvent(*this); } private: @@ -77,6 +80,7 @@ class DragDropEvent : public wxEvent const DragInfoWx& dragInfo; bool allowScroll = true; wxCursor cursor; + std::optional result; }; typedef void (wxEvtHandler::*DragDropEventFunction)(DragDropEvent&); #define DragDropEventHandler(func) wxEVENT_HANDLER_CAST(DragDropEventFunction, func) @@ -263,7 +267,6 @@ struct DragInfoWx wxSize m_size; const CGamDoc* m_gamDoc; }; -#if 0 template<> struct SubInfo { @@ -277,6 +280,7 @@ struct DragInfoWx CSelList* m_selectList; CGamDoc* m_gamDoc; }; +#if 0 template<> struct SubInfo { @@ -292,9 +296,9 @@ struct DragInfoWx SubInfo m_tileList; SubInfo m_piece; SubInfo m_pieceList; -#if 0 SubInfo m_marker; SubInfo m_selectList; +#if 0 SubInfo m_selectView; #endif @@ -305,7 +309,7 @@ struct DragInfoWx template const SubInfo
& GetSubInfo() const { - ASSERT(m_dragType == DT); + wxASSERT(m_dragType == DT); /* TODO: This check could be removed to improve release build performance if we trust ourselves to always catch any m_dragType mistakes in testing. Also, From f3e007e12ac399827d0be758ed3481d70b8e70c5 Mon Sep 17 00:00:00 2001 From: Bill Su Date: Tue, 9 Dec 2025 12:35:22 -0500 Subject: [PATCH 47/80] VwPbrd: implement some event handlers --- GP/DlgRotpc.cpp | 10 +-- GP/DlgRotpc.h | 8 +-- GP/VwPbrd.cpp | 182 +++++++++++++++++++++++++---------------------- GP/VwPbrd.h | 42 +++++------ GShr/CalcLib.cpp | 6 +- GShr/GMisc.h | 2 +- GShr/LibMfc.cpp | 10 +++ 7 files changed, 139 insertions(+), 121 deletions(-) diff --git a/GP/DlgRotpc.cpp b/GP/DlgRotpc.cpp index 04397174..5ce6ea3a 100644 --- a/GP/DlgRotpc.cpp +++ b/GP/DlgRotpc.cpp @@ -35,11 +35,10 @@ static char THIS_FILE[] = __FILE__; ///////////////////////////////////////////////////////////////////////////// // CRotatePieceDialog dialog -CRotatePieceDialog::CRotatePieceDialog(CWnd& v, wxWindow* pParent /*= &CB::GetMainWndWx()*/) : - CB_XRC_BEGIN_CTRLS_DEFN(pParent, CRotatePieceDialog) +CRotatePieceDialog::CRotatePieceDialog(wxWindow& pParent) : + CB_XRC_BEGIN_CTRLS_DEFN(&pParent, CRotatePieceDialog) CB_XRC_CTRL_VAL(m_editCurVal, m_nRelativeRotation, -359, 359, wxNUM_VAL_SIGN_PLUS) - CB_XRC_END_CTRLS_DEFN(), - view(&v) + CB_XRC_END_CTRLS_DEFN() { // KLUDGE: don't see a way to use GetSizeFromText() in .xrc wxSize size = m_editCurVal->GetSizeFromText("+999"_cbstring); @@ -104,7 +103,8 @@ void CRotatePieceDialog::OnContextMenu(CWnd* pWnd, CPoint point) void CRotatePieceDialog::ApplyOffset(int nOffset) { m_nRelativeRotation = (m_nRelativeRotation + nOffset) % 360; - view->SendMessage(WM_ROTATEPIECE_DELTA, (WPARAM)m_nRelativeRotation); + RotatePieceDeltaEvent event(m_nRelativeRotation); + GetParent()->ProcessWindowEvent(event); TransferDataToWindow(); } diff --git a/GP/DlgRotpc.h b/GP/DlgRotpc.h index 7bc339bf..e817ea64 100644 --- a/GP/DlgRotpc.h +++ b/GP/DlgRotpc.h @@ -36,10 +36,7 @@ class CRotatePieceDialog : public wxDialog { // Construction public: - /* TEMPORARY: this needs to send msgs to the view, but that - hasn't been converted to wx yet, so can't be passed as - parent */ - CRotatePieceDialog(CWnd& v, wxWindow* pParent = &CB::GetMainWndWx()); // standard constructor + CRotatePieceDialog(wxWindow& pParent); // standard constructor // Dialog Data int m_nRelativeRotation; @@ -68,9 +65,6 @@ class CRotatePieceDialog : public wxDialog afx_msg void OnContextMenu(CWnd* pWnd, CPoint point); #endif wxDECLARE_EVENT_TABLE(); - -private: - RefPtr view; }; #endif diff --git a/GP/VwPbrd.cpp b/GP/VwPbrd.cpp index 9bbee33e..81d08dee 100644 --- a/GP/VwPbrd.cpp +++ b/GP/VwPbrd.cpp @@ -65,10 +65,8 @@ wxBEGIN_EVENT_TABLE(CPlayBoardView, CPlayBoardView::BASE) EVT_MENU(XRCID("ID_VIEW_HALFSCALEBRD"), OnViewHalfScaleBrd) EVT_UPDATE_UI(XRCID("ID_VIEW_HALFSCALEBRD"), OnUpdateViewHalfScaleBrd) EVT_DRAGDROP(OnDragItem) -#if 0 - ON_MESSAGE(WM_ROTATEPIECE_DELTA, OnMessageRotateRelative) - ON_MESSAGE(WM_CENTERBOARDONPOINT, OnMessageCenterBoardOnPoint) -#endif + EVT_ROTATEPIECE_DELTA(OnMessageRotateRelative) + EVT_CENTERBOARDONPOINT(OnMessageCenterBoardOnPoint) EVT_LEFT_DOWN(OnLButtonDown) EVT_MOTION(OnMouseMove) EVT_LEFT_UP(OnLButtonUp) @@ -76,11 +74,11 @@ wxBEGIN_EVENT_TABLE(CPlayBoardView, CPlayBoardView::BASE) EVT_TIMER(wxID_ANY, OnTimer) EVT_LEFT_DCLICK(OnLButtonDblClk) EVT_SET_CURSOR(OnSetCursor) + EVT_KEY_DOWN(OnKeyDown) + EVT_CHAR(OnChar) + EVT_MENU(XRCID("ID_PTOOL_SELECT"), OnPlayTool) + EVT_UPDATE_UI(XRCID("ID_PTOOL_SELECT"), OnUpdatePlayTool) #if 0 - ON_WM_KEYDOWN() - ON_WM_CHAR() - ON_COMMAND_EX(ID_PTOOL_SELECT, OnPlayTool) - ON_UPDATE_COMMAND_UI(ID_PTOOL_SELECT, OnUpdatePlayTool) ON_COMMAND(ID_ACT_STACK, OnActStack) ON_UPDATE_COMMAND_UI(ID_ACT_STACK, OnUpdateActStack) ON_COMMAND(ID_ACT_TOBACK, OnActToBack) @@ -117,10 +115,12 @@ wxBEGIN_EVENT_TABLE(CPlayBoardView, CPlayBoardView::BASE) ON_COMMAND(ID_EDIT_COPY, OnEditCopy) ON_COMMAND(ID_EDIT_BRD2FILE, OnEditBoardToFile) ON_COMMAND(ID_EDIT_BRDPROP, OnEditBoardProperties) - ON_COMMAND(ID_ACT_ROTATEREL, OnActRotateRelative) - ON_UPDATE_COMMAND_UI(ID_ACT_ROTATEREL, OnUpdateActRotateRelative) - ON_COMMAND(ID_EDIT_CLEAR, OnEditClear) - ON_UPDATE_COMMAND_UI(ID_EDIT_CLEAR, OnUpdateEditClear) +#endif + EVT_MENU(XRCID("ID_ACT_ROTATEREL"), OnActRotateRelative) + EVT_UPDATE_UI(XRCID("ID_ACT_ROTATEREL"), OnUpdateActRotateRelative) + EVT_MENU(wxID_CLEAR, OnEditClear) + EVT_UPDATE_UI(wxID_CLEAR, OnUpdateEditClear) +#if 0 ON_WM_CONTEXTMENU() ON_COMMAND(ID_VIEW_DRAW_IND_ON_TOP, OnViewDrawIndOnTop) ON_UPDATE_COMMAND_UI(ID_VIEW_DRAW_IND_ON_TOP, OnUpdateViewDrawIndOnTop) @@ -143,18 +143,18 @@ wxBEGIN_EVENT_TABLE(CPlayBoardView, CPlayBoardView::BASE) #endif EVT_MENU(XRCID("ID_VIEW_SMALLSCALEBRD"), OnViewSmallScaleBoard) EVT_UPDATE_UI(XRCID("ID_VIEW_SMALLSCALEBRD"), OnUpdateViewSmallScaleBoard) + EVT_MENU(XRCID("ID_PTOOL_LINE"), OnPlayTool) + EVT_MENU(XRCID("ID_PTOOL_TEXTBOX"), OnPlayTool) + EVT_UPDATE_UI(XRCID("ID_PTOOL_LINE"), OnUpdatePlayTool) + EVT_UPDATE_UI(XRCID("ID_PTOOL_TEXTBOX"), OnUpdatePlayTool) #if 0 - ON_COMMAND_EX(ID_PTOOL_LINE, OnPlayTool) - ON_COMMAND_EX(ID_PTOOL_TEXTBOX, OnPlayTool) - ON_UPDATE_COMMAND_UI(ID_PTOOL_LINE, OnUpdatePlayTool) - ON_UPDATE_COMMAND_UI(ID_PTOOL_TEXTBOX, OnUpdatePlayTool) ON_WM_MOUSEWHEEL() #endif EVT_MENU(XRCID("ID_VIEW_BOARD_ROTATE180"), OnViewBoardRotate180) EVT_UPDATE_UI(XRCID("ID_VIEW_BOARD_ROTATE180"), OnUpdateViewBoardRotate180) + EVT_MENU(XRCID("ID_ACT_ROTATEGROUP"), OnActRotateGroupRelative) + EVT_UPDATE_UI(XRCID("ID_ACT_ROTATEGROUP"), OnUpdateActRotateGroupRelative) #if 0 - ON_COMMAND(ID_ACT_ROTATEGROUP, OnActRotateGroupRelative) - ON_UPDATE_COMMAND_UI(ID_ACT_ROTATEGROUP, OnUpdateActRotateGroupRelative) ON_COMMAND_RANGE(ID_ACT_ROTATE_0, (ID_ACT_ROTATE_0 + 360 / 5), OnRotatePiece) ON_UPDATE_COMMAND_UI_RANGE(ID_ACT_ROTATE_0, (ID_ACT_ROTATE_0 + 360 / 5), OnUpdateRotatePiece) ON_COMMAND_RANGE(ID_MRKGROUP_FIRST, ID_MRKGROUP_FIRST + 64, OnSelectGroupMarkers) @@ -170,6 +170,7 @@ wxEND_EVENT_TABLE() BEGIN_MESSAGE_MAP(CPlayBoardViewContainer, CPlayBoardViewContainer::BASE) ON_WM_CREATE() + ON_WM_SETFOCUS() ON_WM_SIZE() ON_MESSAGE(WM_WINSTATE, OnMessageWindowState) END_MESSAGE_MAP() @@ -187,7 +188,7 @@ CPlayBoardView::CPlayBoardView(CPlayBoardViewContainer& p) : DisableAutoScrollOutside(); m_nZoom = fullScale; - m_nCurToolID = ID_PTOOL_SELECT; + m_nCurToolID = XRCID("ID_PTOOL_SELECT"); m_bInDrag = FALSE; m_pDragSelList = NULL; #if 0 @@ -1370,13 +1371,13 @@ void CPlayBoardView::OnSetCursor(wxSetCursorEvent& event) ////////////////////////////////////////////////////////////////////// -#if 0 -void CPlayBoardView::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) +void CPlayBoardView::OnChar(wxKeyEvent& event) { + int nChar = event.GetKeyCode(); CGamDoc& pDoc = GetDocument(); if (!pDoc.IsPlaying()) { - if (nChar == VK_ESCAPE) + if (nChar == static_cast(WXK_ESCAPE)) { if (pDoc.IsRecordingCompoundMove()) pDoc.RecordCompoundMoveDiscard(); @@ -1385,7 +1386,7 @@ void CPlayBoardView::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) else m_selList.PurgeList(TRUE); } - else if (nChar == VK_RETURN) + else if (nChar == static_cast(WXK_RETURN)) { if (pDoc.IsRecordingCompoundMove()) pDoc.RecordCompoundMoveEnd(); @@ -1393,19 +1394,28 @@ void CPlayBoardView::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) OnActPlotDone(); } } - CScrollView::OnChar(nChar, nRepCnt, nFlags); + event.Skip(); } -void CPlayBoardView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) +void CPlayBoardView::OnKeyDown(wxKeyEvent& event) { + int nChar = event.GetKeyCode(); if (!IsBoardContentsAvailableToCurrentPlayer()) return; if (GetDocument().IsPlaying()) return; - if (nChar == VK_DELETE) + if (nChar == WXK_DELETE || + nChar == WXK_NUMPAD_DELETE) OnEditClear(); + + /* so other keys get to EVT_CHAR + (see https://docs.wxwidgets.org/stable/classwx_key_event.html) */ + else + { + event.Skip(); + } } ////////////////////////////////////////////////////////////////////// @@ -1415,7 +1425,7 @@ void CPlayBoardView::OnEditClear() if (!m_selList.HasMarkers()) return; // Nothing to do - ASSERT(!GetDocument().IsPlaying() && m_selList.HasMarkers()); + wxASSERT(!GetDocument().IsPlaying() && m_selList.HasMarkers()); if (m_pPBoard->GetPlotMoveMode()) OnActPlotDiscard(); @@ -1429,25 +1439,23 @@ void CPlayBoardView::OnEditClear() GetDocument().DeleteObjectsInTable(listPtr); } -void CPlayBoardView::OnUpdateEditClear(CCmdUI* pCmdUI) +void CPlayBoardView::OnUpdateEditClear(wxUpdateUIEvent& pCmdUI) { - pCmdUI->Enable(!GetDocument().IsPlaying() && m_selList.HasMarkers()); + pCmdUI.Enable(!GetDocument().IsPlaying() && m_selList.HasMarkers()); } -#endif ////////////////////////////////////////////////////////////////////// -static PToolType tblTools[] = -{ - ptypeSelect, // ID_PTOOL_SELECT - ptypeLine, // ID_PTOOL_LINE - ptypeTextBox, // ID_PTOOL_TEXTBOX - ptypeMPlot, // ID_PTOOL_PLOTMOVE -}; - -PToolType CPlayBoardView::MapToolType(UINT nToolResID) const +PToolType CPlayBoardView::MapToolType(int nToolResID) const { - return tblTools[nToolResID - ID_PTOOL_SELECT]; + // wx doesn't guarantee XRCID() value order + static const std::unordered_map map { + { XRCID("ID_PTOOL_SELECT"), ptypeSelect }, + { XRCID("ID_PTOOL_LINE"), ptypeLine }, + { XRCID("ID_PTOOL_TEXTBOX"), ptypeTextBox }, + { XRCID("ID_PTOOL_PLOTMOVE"), ptypeMPlot }, + }; + return map.at(nToolResID); } ///////////////////////////////////////////////////////////////////////////// @@ -1581,29 +1589,27 @@ void CPlayBoardView::OnUpdateViewBoardRotate180(wxUpdateUIEvent& pCmdUI) pCmdUI.Check(m_pPBoard->IsBoardRotated180()); } -#if 0 -BOOL CPlayBoardView::OnPlayTool(UINT id) +void CPlayBoardView::OnPlayTool(wxCommandEvent& event) { - if (id !=ID_PTOOL_SELECT) + int id = event.GetId(); + if (id !=XRCID("ID_PTOOL_SELECT")) m_selList.PurgeList(TRUE); if (id != m_nCurToolID) { m_nCurToolID = id; } - return TRUE; } -void CPlayBoardView::OnUpdatePlayTool(CCmdUI* pCmdUI) +void CPlayBoardView::OnUpdatePlayTool(wxUpdateUIEvent& pCmdUI) { - // NOTE!!: The control ID's are assumed to be consecutive and - // in the same order as the tool codes defined in MAINFRM.C if (GetDocument().IsPlaying()) - pCmdUI->Enable(FALSE); + pCmdUI.Enable(FALSE); else - pCmdUI->Enable(pCmdUI->m_nID == m_nCurToolID); - pCmdUI->SetCheck(pCmdUI->m_nID == m_nCurToolID); + pCmdUI.Enable(pCmdUI.GetId() == m_nCurToolID); + pCmdUI.Check(pCmdUI.GetId() == m_nCurToolID); } +#if 0 void CPlayBoardView::OnActStack() { DoAutostackOfSelectedObjects(m_pPBoard->m_xStackStagger, @@ -1830,7 +1836,7 @@ void CPlayBoardView::OnActPlotMove(wxCommandEvent& /*event*/) // Ok...finish plot setup m_pPBoard->SetPlotMoveMode(TRUE); m_pPBoard->InitPlotStartPoint(); - m_nCurToolID = ID_PTOOL_PLOTMOVE; + m_nCurToolID = XRCID("ID_PTOOL_PLOTMOVE"); } void CPlayBoardView::OnUpdateActPlotMove(wxUpdateUIEvent& pCmdUI) @@ -1863,7 +1869,7 @@ void CPlayBoardView::OnUpdateActPlotMove(wxUpdateUIEvent& pCmdUI) pCmdUI.Check(m_pPBoard->GetPlotMoveMode()); } -void CPlayBoardView::OnActPlotDone(wxCommandEvent& /*event*/) +void CPlayBoardView::OnActPlotDone() { if (m_pPBoard->GetPrevPlotPoint() != CPoint(-1, -1)) { @@ -1887,7 +1893,7 @@ void CPlayBoardView::OnActPlotDone(wxCommandEvent& /*event*/) m_pPBoard->SetPlotMoveMode(FALSE); GetDocument().UpdateAllBoardIndicators(*m_pPBoard); m_pPBoard->FlushAllIndicators(); - m_nCurToolID = ID_PTOOL_SELECT; + m_nCurToolID = XRCID("ID_PTOOL_SELECT"); } void CPlayBoardView::OnUpdateActPlotDone(wxUpdateUIEvent& pCmdUI) @@ -1900,12 +1906,12 @@ void CPlayBoardView::OnUpdateActPlotDone(wxUpdateUIEvent& pCmdUI) pCmdUI.Enable(m_pPBoard->GetPlotMoveMode()); } -void CPlayBoardView::OnActPlotDiscard(wxCommandEvent& /*event*/) +void CPlayBoardView::OnActPlotDiscard() { m_pPBoard->SetPlotMoveMode(FALSE); GetDocument().UpdateAllBoardIndicators(*m_pPBoard); m_pPBoard->FlushAllIndicators(); - m_nCurToolID = ID_PTOOL_SELECT; + m_nCurToolID = XRCID("ID_PTOOL_SELECT"); } void CPlayBoardView::OnUpdateActPlotDiscard(wxUpdateUIEvent& pCmdUI) @@ -2008,28 +2014,27 @@ void CPlayBoardView::OnUpdateRotatePiece(CCmdUI* pCmdUI, UINT nID) } pCmdUI->Enable(bEnabled); } +#endif /////////////////////////////////////////////////////////////////////// // This method handles messages typically sent by the tiny map view. // WPARAM = POINT* -LRESULT CPlayBoardView::OnMessageCenterBoardOnPoint(WPARAM wParam, LPARAM lParam) +void CPlayBoardView::OnMessageCenterBoardOnPoint(CenterBoardOnPointEvent& event) { - CPoint pnt = *((POINT*)wParam); - CenterViewOnWorkspacePoint(pnt); - return (LRESULT)0; + CenterViewOnWorkspacePoint(event.GetPoint()); } /////////////////////////////////////////////////////////////////////// // This method handles notifications of changes of relative piece // rotation sent from the CRotatePieceDialog dialog. -LRESULT CPlayBoardView::OnMessageRotateRelative(WPARAM wParam, LPARAM lParam) +void CPlayBoardView::OnMessageRotateRelative(RotatePieceDeltaEvent& event) { CGamDoc& pDoc = GetDocument(); - int nRelativeRotation = (int)wParam; - ASSERT(!m_tblCurPieces.empty()); - ASSERT(m_tblCurAngles.size() == m_tblCurPieces.size()); + int nRelativeRotation = event.GetDelta(); + wxASSERT(!m_tblCurPieces.empty()); + wxASSERT(m_tblCurAngles.size() == m_tblCurPieces.size()); for (size_t i = size_t(0) ; i < m_tblCurPieces.size() ; ++i) { @@ -2046,21 +2051,20 @@ LRESULT CPlayBoardView::OnMessageRotateRelative(WPARAM wParam, LPARAM lParam) (pDObj.GetType() == CDrawObj::drawPieceObj || pDObj.GetType() == CDrawObj::drawMarkObj)) { // Calculate new rotated mid-point for object. - CPoint pntRotate = RotatePointAroundPoint(m_pntWheelMid, + wxPoint pntRotate = RotatePointAroundPoint(m_pntWheelMid, m_tblMidPnt[i], nRelativeRotation); - CSize sizeDelta = pntRotate - GetMidRect(pDObj.GetEnclosingRect()); - pDoc.PlaceObjectOnBoard(m_pPBoard.get(), &pDObj, sizeDelta); + wxPoint sizeDelta = pntRotate - GetMidRect(CB::Convert(pDObj.GetEnclosingRect())); + pDoc.PlaceObjectOnBoard(m_pPBoard.get(), &pDObj, CB::Convert(sizeDelta)); } } - return (LRESULT)0; } -void CPlayBoardView::OnActRotateRelative() +void CPlayBoardView::OnActRotateRelative(wxCommandEvent& /*event*/) { DoRotateRelative(FALSE); } -void CPlayBoardView::OnActRotateGroupRelative() +void CPlayBoardView::OnActRotateGroupRelative(wxCommandEvent& /*event*/) { DoRotateRelative(TRUE); } @@ -2081,7 +2085,7 @@ void CPlayBoardView::DoRotateRelative(BOOL bWheelRotation) m_selList.LoadTableWithObjectPtrs(m_tblCurPieces, CSelList::otAll, FALSE); - CRect rctGroupRect = m_selList.GetPiecesEnclosingRect(); + wxRect rctGroupRect = CB::Convert(m_selList.GetPiecesEnclosingRect()); m_pntWheelMid = GetMidRect(rctGroupRect); for (size_t i = size_t(0) ; i < m_tblCurPieces.size() ; ++i) @@ -2100,7 +2104,7 @@ void CPlayBoardView::DoRotateRelative(BOOL bWheelRotation) if (m_bWheelRotation && (pDObj.GetType() == CDrawObj::drawPieceObj || pDObj.GetType() == CDrawObj::drawMarkObj)) { - CPoint midPoint = GetMidRect(pDObj.GetEnclosingRect()); + wxPoint midPoint = GetMidRect(CB::Convert(pDObj.GetEnclosingRect())); m_tblMidPnt.push_back(midPoint); } } @@ -2150,9 +2154,9 @@ void CPlayBoardView::DoRotateRelative(BOOL bWheelRotation) (pDObj.GetType() == CDrawObj::drawPieceObj || pDObj.GetType() == CDrawObj::drawMarkObj)) { // Restore original position - CSize sizeDelta = m_tblMidPnt[i] - - GetMidRect(pDObj.GetEnclosingRect()); - pDoc.PlaceObjectOnBoard(m_pPBoard.get(), &pDObj, sizeDelta); + wxPoint sizeDelta = m_tblMidPnt[i] - + GetMidRect(CB::Convert(pDObj.GetEnclosingRect())); + pDoc.PlaceObjectOnBoard(m_pPBoard.get(), &pDObj, CB::Convert(sizeDelta)); } } // Restore recording mode if it was active. @@ -2181,47 +2185,48 @@ void CPlayBoardView::DoRotateRelative(BOOL bWheelRotation) (pDObj.GetType() == CDrawObj::drawPieceObj || pDObj.GetType() == CDrawObj::drawMarkObj)) { // Calculate new rotated mid-point for object. - CPoint pntRotate = RotatePointAroundPoint(m_pntWheelMid, + wxPoint pntRotate = RotatePointAroundPoint(m_pntWheelMid, m_tblMidPnt[i], dlg.m_nRelativeRotation); - CSize sizeDelta = pntRotate - GetMidRect(pDObj.GetEnclosingRect()); - pDoc.PlaceObjectOnBoard(m_pPBoard.get(), &pDObj, sizeDelta); + wxPoint sizeDelta = pntRotate - GetMidRect(CB::Convert(pDObj.GetEnclosingRect())); + pDoc.PlaceObjectOnBoard(m_pPBoard.get(), &pDObj, CB::Convert(sizeDelta)); } } m_selList.UpdateObjects(TRUE, FALSE); // Make sure we erase old handles. - rctGroupRect.InflateRect(16, 16); - InvalidateRect(rctGroupRect, FALSE); + rctGroupRect.Inflate(16, 16); + RefreshRect(rctGroupRect, FALSE); } m_tblCurAngles.clear(); m_tblCurPieces.clear(); m_tblMidPnt.clear(); } -void CPlayBoardView::OnUpdateActRotateRelative(CCmdUI* pCmdUI) +void CPlayBoardView::OnUpdateActRotateRelative(wxUpdateUIEvent& pCmdUI) { CGamDoc& pDoc = GetDocument(); if (pDoc.IsPlaying() || !pDoc.IsScenario() && m_selList.HasOwnedPiecesNotMatching(pDoc.GetCurrentPlayerMask())) - pCmdUI->Enable(FALSE); + pCmdUI.Enable(FALSE); else - pCmdUI->Enable(m_selList.HasPieces() || m_selList.HasMarkers()); + pCmdUI.Enable(m_selList.HasPieces() || m_selList.HasMarkers()); } -void CPlayBoardView::OnUpdateActRotateGroupRelative(CCmdUI *pCmdUI) +void CPlayBoardView::OnUpdateActRotateGroupRelative(wxUpdateUIEvent& pCmdUI) { CGamDoc& pDoc = GetDocument(); if (pDoc.IsPlaying() || !pDoc.IsScenario() && m_selList.HasOwnedPiecesNotMatching(pDoc.GetCurrentPlayerMask())) - pCmdUI->Enable(FALSE); + pCmdUI.Enable(FALSE); else { - pCmdUI->Enable(m_selList.IsMultipleSelects() && + pCmdUI.Enable(m_selList.IsMultipleSelects() && (m_selList.HasPieces() || m_selList.HasMarkers())); } } /////////////////////////////////////////////////////////////////////// +#if 0 void CPlayBoardView::OnViewPieces() { GetPlayBoard().SetPiecesVisible(!GetPlayBoard().GetPiecesVisible()); @@ -2810,6 +2815,13 @@ int CPlayBoardViewContainer::OnCreate(LPCREATESTRUCT lpCreateStruct) return 0; } +// MFC puts the focus here, so move it to the useful window +void CPlayBoardViewContainer::OnSetFocus(CWnd* pOldWnd) +{ + BASE::OnSetFocus(pOldWnd); + child->SetFocus(); +} + void CPlayBoardViewContainer::OnSize(UINT nType, int cx, int cy) { child->SetSize(0, 0, cx, cy); diff --git a/GP/VwPbrd.h b/GP/VwPbrd.h index 78ca1334..eaae0f2a 100644 --- a/GP/VwPbrd.h +++ b/GP/VwPbrd.h @@ -167,7 +167,7 @@ class CPlayBoardView : public CB::ProcessEventOverride protected: #endif // -------- // - UINT m_nCurToolID; // Current tool ID + int m_nCurToolID; // Current tool ID // -------- // CB::ToolTip m_toolMsgTip; // Tooltip for notifications CB::ToolTip m_toolHitTip; // Tooltip hit support for view @@ -187,7 +187,7 @@ class CPlayBoardView : public CB::ProcessEventOverride void AddPiece(wxPoint pnt, PieceID pid); - PToolType MapToolType(UINT nToolResID) const; + PToolType MapToolType(int nToolResID) const; class DCSetupDrawListDC { @@ -232,10 +232,8 @@ class CPlayBoardView : public CB::ProcessEventOverride void OnViewHalfScaleBrd(wxCommandEvent& event); void OnUpdateViewHalfScaleBrd(wxUpdateUIEvent& pCmdUI); void OnDragItem(DragDropEvent& event); -#if 0 - afx_msg LRESULT OnMessageRotateRelative(WPARAM wParam, LPARAM lParam); - afx_msg LRESULT OnMessageCenterBoardOnPoint(WPARAM wParam, LPARAM lParam); -#endif + void OnMessageRotateRelative(RotatePieceDeltaEvent& event); + void OnMessageCenterBoardOnPoint(CenterBoardOnPointEvent& event); void OnLButtonDown(wxMouseEvent& event); void OnMouseMove(wxMouseEvent& event); void OnLButtonUp(wxMouseEvent& event); @@ -243,11 +241,11 @@ class CPlayBoardView : public CB::ProcessEventOverride void OnTimer(wxTimerEvent& event); void OnLButtonDblClk(wxMouseEvent& event); void OnSetCursor(wxSetCursorEvent& event); + void OnKeyDown(wxKeyEvent& event); + void OnChar(wxKeyEvent& event); + void OnPlayTool(wxCommandEvent& event); + void OnUpdatePlayTool(wxUpdateUIEvent& pCmdUI); #if 0 - afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags); - afx_msg void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags); - afx_msg BOOL OnPlayTool(UINT id); - afx_msg void OnUpdatePlayTool(CCmdUI* pCmdUI); afx_msg void OnActStack(); afx_msg void OnUpdateActStack(CCmdUI* pCmdUI); afx_msg void OnActToBack(); @@ -259,9 +257,11 @@ class CPlayBoardView : public CB::ProcessEventOverride #endif void OnActPlotMove(wxCommandEvent& event); void OnUpdateActPlotMove(wxUpdateUIEvent& pCmdUI); - void OnActPlotDone(wxCommandEvent& event); + void OnActPlotDone(); + void OnActPlotDone(wxCommandEvent& /*event*/) { OnActPlotDone(); } void OnUpdateActPlotDone(wxUpdateUIEvent& pCmdUI); - void OnActPlotDiscard(wxCommandEvent& event); + void OnActPlotDiscard(); + void OnActPlotDiscard(wxCommandEvent& /*event*/) { OnActPlotDiscard(); } void OnUpdateActPlotDiscard(wxUpdateUIEvent& pCmdUI); #if 0 afx_msg void OnUpdateIndicatorCellNum(CCmdUI* pCmdUI); @@ -280,10 +280,13 @@ class CPlayBoardView : public CB::ProcessEventOverride afx_msg void OnEditCopy(); afx_msg void OnEditBoardToFile(); afx_msg void OnEditBoardProperties(); - afx_msg void OnActRotateRelative(); - afx_msg void OnUpdateActRotateRelative(CCmdUI* pCmdUI); - afx_msg void OnEditClear(); - afx_msg void OnUpdateEditClear(CCmdUI* pCmdUI); +#endif + void OnActRotateRelative(wxCommandEvent& event); + void OnUpdateActRotateRelative(wxUpdateUIEvent& pCmdUI); + void OnEditClear(); + void OnEditClear(wxCommandEvent& /*event*/) { OnEditClear(); } + void OnUpdateEditClear(wxUpdateUIEvent& pCmdUI); +#if 0 afx_msg void OnContextMenu(CWnd* pWnd, CPoint point); afx_msg void OnViewDrawIndOnTop(); afx_msg void OnUpdateViewDrawIndOnTop(CCmdUI* pCmdUI); @@ -321,11 +324,9 @@ class CPlayBoardView : public CB::ProcessEventOverride #endif void OnScrollWinLine(wxScrollWinEvent& event); wxDECLARE_EVENT_TABLE(); -#if 0 public: - afx_msg void OnActRotateGroupRelative(); - afx_msg void OnUpdateActRotateGroupRelative(CCmdUI *pCmdUI); -#endif + void OnActRotateGroupRelative(wxCommandEvent& event); + void OnUpdateActRotateGroupRelative(wxUpdateUIEvent& pCmdUI); private: // IGetCmdTarget @@ -365,6 +366,7 @@ class CPlayBoardViewContainer : public CB::OnCmdMsgOverride, DECLARE_DYNCREATE(CPlayBoardViewContainer) afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); + afx_msg void OnSetFocus(CWnd* pOldWnd); afx_msg void OnSize(UINT nType, int cx, int cy); afx_msg LRESULT OnMessageWindowState(WPARAM wParam, LPARAM lParam); DECLARE_MESSAGE_MAP() diff --git a/GShr/CalcLib.cpp b/GShr/CalcLib.cpp index af71a937..91c96143 100644 --- a/GShr/CalcLib.cpp +++ b/GShr/CalcLib.cpp @@ -250,14 +250,14 @@ CPoint GetMidRect(const CRect& rct) /////////////////////////////////////////////////////////////////////// // Rotate point around specified origin point. -CPoint RotatePointAroundPoint(CPoint pntOrigin, CPoint pntXlate, int nAngleDeg) +wxPoint RotatePointAroundPoint(wxPoint pntOrigin, wxPoint pntXlate, int nAngleDeg) { - CPoint pntRelative = pntXlate - pntOrigin; + wxPoint pntRelative = pntXlate - pntOrigin; int nCosA = Cos10K(nAngleDeg); int nSinA = Sin10K(nAngleDeg); int xRotated = (pntRelative.x * nCosA - pntRelative.y * nSinA) / 10000; int yRotated = (pntRelative.x * nSinA + pntRelative.y * nCosA) / 10000; - CPoint pntFinal = CPoint(xRotated, yRotated) + pntOrigin; + wxPoint pntFinal = wxPoint(xRotated, yRotated) + pntOrigin; return pntFinal; } diff --git a/GShr/GMisc.h b/GShr/GMisc.h index 40e2fdb7..09f03d5a 100644 --- a/GShr/GMisc.h +++ b/GShr/GMisc.h @@ -67,7 +67,7 @@ inline wxPoint GetMidRect(const wxRect& rct) { return CB::Convert(GetMidRect(CB::Convert(rct))); } -CPoint RotatePointAroundPoint(CPoint pntOrigin, CPoint pntXlate, int nAngleDeg); +wxPoint RotatePointAroundPoint(wxPoint pntOrigin, wxPoint pntXlate, int nAngleDeg); int32_t GridizeClosest1000(int32_t nVal, int32_t nMultiple, int32_t nOffset); int32_t GridizeClosest(int32_t nVal, int32_t nMultiple, int32_t nOffset); diff --git a/GShr/LibMfc.cpp b/GShr/LibMfc.cpp index ed134a17..3676fc45 100644 --- a/GShr/LibMfc.cpp +++ b/GShr/LibMfc.cpp @@ -1322,6 +1322,10 @@ namespace CB return XRCID("ID_ACT_PLOTDISCARD"); case ID_ACT_PLOTDONE: return XRCID("ID_ACT_PLOTDONE"); + case ID_ACT_ROTATEGROUP: + return XRCID("ID_ACT_ROTATEGROUP"); + case ID_ACT_ROTATEREL: + return XRCID("ID_ACT_ROTATEREL"); case ID_ACT_TURNOVER: return XRCID("ID_ACT_TURNOVER"); case ID_ACT_TURNOVER_PREV: @@ -1340,8 +1344,14 @@ namespace CB return XRCID("ID_PPROJITEM_PROPERTIES"); case ID_PPROJITEM_VIEW: return XRCID("ID_PPROJITEM_VIEW"); + case ID_PTOOL_LINE: + return XRCID("ID_PTOOL_LINE"); case ID_PTOOL_PLOTMOVE: return XRCID("ID_PTOOL_PLOTMOVE"); + case ID_PTOOL_SELECT: + return XRCID("ID_PTOOL_SELECT"); + case ID_PTOOL_TEXTBOX: + return XRCID("ID_PTOOL_TEXTBOX"); case ID_VIEW_BOARD_ROTATE180: return XRCID("ID_VIEW_BOARD_ROTATE180"); case ID_VIEW_FULLSCALEBRD: From 4f1a97a3c4f8067de3953cc921d65db212fe29fe Mon Sep 17 00:00:00 2001 From: Bill Su Date: Wed, 10 Dec 2025 18:02:01 -0500 Subject: [PATCH 48/80] VwPbrd: implement some more event handlers --- GP/VwPbrd.cpp | 270 +++++++++++++++++++++++------------------------- GP/VwPbrd.h | 42 ++++---- GShr/LibMfc.cpp | 16 +++ 3 files changed, 167 insertions(+), 161 deletions(-) diff --git a/GP/VwPbrd.cpp b/GP/VwPbrd.cpp index 81d08dee..739e9411 100644 --- a/GP/VwPbrd.cpp +++ b/GP/VwPbrd.cpp @@ -78,44 +78,43 @@ wxBEGIN_EVENT_TABLE(CPlayBoardView, CPlayBoardView::BASE) EVT_CHAR(OnChar) EVT_MENU(XRCID("ID_PTOOL_SELECT"), OnPlayTool) EVT_UPDATE_UI(XRCID("ID_PTOOL_SELECT"), OnUpdatePlayTool) -#if 0 - ON_COMMAND(ID_ACT_STACK, OnActStack) - ON_UPDATE_COMMAND_UI(ID_ACT_STACK, OnUpdateActStack) - ON_COMMAND(ID_ACT_TOBACK, OnActToBack) - ON_UPDATE_COMMAND_UI(ID_ACT_TOBACK, OnUpdateActToBack) - ON_COMMAND(ID_ACT_TOFRONT, OnActToFront) - ON_UPDATE_COMMAND_UI(ID_ACT_TOFRONT, OnUpdateActToFront) - ON_COMMAND_EX(ID_ACT_TURNOVER, OnActTurnOver) - ON_COMMAND_EX(ID_ACT_TURNOVER_PREV, OnActTurnOver) - ON_COMMAND_EX(ID_ACT_TURNOVER_RANDOM, OnActTurnOver) - ON_UPDATE_COMMAND_UI(ID_ACT_TURNOVER, OnUpdateActTurnOver) - ON_UPDATE_COMMAND_UI(ID_ACT_TURNOVER_PREV, OnUpdateActTurnOver) - ON_UPDATE_COMMAND_UI(ID_ACT_TURNOVER_RANDOM, OnUpdateActTurnOver) -#endif + EVT_MENU(XRCID("ID_ACT_STACK"), OnActStack) + EVT_UPDATE_UI(XRCID("ID_ACT_STACK"), OnUpdateActStack) + EVT_MENU(XRCID("ID_ACT_TOBACK"), OnActToBack) + EVT_UPDATE_UI(XRCID("ID_ACT_TOBACK"), OnUpdateActToBack) + EVT_MENU(XRCID("ID_ACT_TOFRONT"), OnActToFront) + EVT_UPDATE_UI(XRCID("ID_ACT_TOFRONT"), OnUpdateActToFront) + EVT_MENU(XRCID("ID_ACT_TURNOVER"), OnActTurnOver) + EVT_MENU(XRCID("ID_ACT_TURNOVER_PREV"), OnActTurnOver) + EVT_MENU(XRCID("ID_ACT_TURNOVER_RANDOM"), OnActTurnOver) + EVT_UPDATE_UI(XRCID("ID_ACT_TURNOVER"), OnUpdateActTurnOver) + EVT_UPDATE_UI(XRCID("ID_ACT_TURNOVER_PREV"), OnUpdateActTurnOver) + EVT_UPDATE_UI(XRCID("ID_ACT_TURNOVER_RANDOM"), OnUpdateActTurnOver) EVT_MENU(XRCID("ID_PTOOL_PLOTMOVE"), OnActPlotMove) EVT_UPDATE_UI(XRCID("ID_PTOOL_PLOTMOVE"), OnUpdateActPlotMove) EVT_MENU(XRCID("ID_ACT_PLOTDONE"), OnActPlotDone) EVT_UPDATE_UI(XRCID("ID_ACT_PLOTDONE"), OnUpdateActPlotDone) EVT_MENU(XRCID("ID_ACT_PLOTDISCARD"), OnActPlotDiscard) EVT_UPDATE_UI(XRCID("ID_ACT_PLOTDISCARD"), OnUpdateActPlotDiscard) + EVT_UPDATE_UI(XRCID("ID_INDICATOR_CELLNUM"), OnUpdateIndicatorCellNum) + EVT_MENU(XRCID("ID_VIEW_SNAPGRID"), OnViewSnapGrid) + EVT_UPDATE_UI(XRCID("ID_VIEW_SNAPGRID"), OnUpdateViewSnapGrid) + EVT_MENU(XRCID("ID_EDIT_SELALLMARKERS"), OnEditSelAllMarkers) + EVT_UPDATE_UI(XRCID("ID_EDIT_SELALLMARKERS"), OnUpdateEditSelAllMarkers) #if 0 - ON_UPDATE_COMMAND_UI(ID_INDICATOR_CELLNUM, OnUpdateIndicatorCellNum) - ON_COMMAND(ID_VIEW_SNAPGRID, OnViewSnapGrid) - ON_UPDATE_COMMAND_UI(ID_VIEW_SNAPGRID, OnUpdateViewSnapGrid) - ON_COMMAND(ID_EDIT_SELALLMARKERS, OnEditSelAllMarkers) - ON_UPDATE_COMMAND_UI(ID_EDIT_SELALLMARKERS, OnUpdateEditSelAllMarkers) ON_COMMAND(ID_ACT_ROTATE, OnActRotate) ON_UPDATE_COMMAND_UI(ID_ACT_ROTATE, OnUpdateActRotate) #endif EVT_MENU(XRCID("ID_VIEW_TOGGLESCALE"), OnViewToggleScale) EVT_UPDATE_UI(XRCID("ID_VIEW_TOGGLESCALE"), OnUpdateViewToggleScale) -#if 0 - ON_COMMAND(ID_VIEW_PIECES, OnViewPieces) - ON_UPDATE_COMMAND_UI(ID_VIEW_PIECES, OnUpdateViewPieces) - ON_COMMAND(ID_EDIT_COPY, OnEditCopy) - ON_COMMAND(ID_EDIT_BRD2FILE, OnEditBoardToFile) - ON_COMMAND(ID_EDIT_BRDPROP, OnEditBoardProperties) -#endif + EVT_MENU(XRCID("ID_VIEW_PIECES"), OnViewPieces) + EVT_UPDATE_UI(XRCID("ID_VIEW_PIECES"), OnUpdateViewPieces) + EVT_MENU(wxID_COPY, OnEditCopy) + EVT_UPDATE_UI(wxID_COPY, OnUpdateEnable) + EVT_MENU(XRCID("ID_EDIT_BRD2FILE"), OnEditBoardToFile) + EVT_UPDATE_UI(XRCID("ID_EDIT_BRD2FILE"), OnUpdateEnable) + EVT_MENU(XRCID("ID_EDIT_BRDPROP"), OnEditBoardProperties) + EVT_UPDATE_UI(XRCID("ID_EDIT_BRDPROP"), OnUpdateEnable) EVT_MENU(XRCID("ID_ACT_ROTATEREL"), OnActRotateRelative) EVT_UPDATE_UI(XRCID("ID_ACT_ROTATEREL"), OnUpdateActRotateRelative) EVT_MENU(wxID_CLEAR, OnEditClear) @@ -1461,27 +1460,23 @@ PToolType CPlayBoardView::MapToolType(int nToolResID) const ///////////////////////////////////////////////////////////////////////////// // CPlayBoardView message handlers -#if 0 -void CPlayBoardView::OnUpdateIndicatorCellNum(CCmdUI* pCmdUI) +void CPlayBoardView::OnUpdateIndicatorCellNum(wxUpdateUIEvent& pCmdUI) { CBoardArray& pba = m_pPBoard->GetBoard()->GetBoardArray(); if (pba.GetCellNumTracking()) { - CPoint point; - GetCursorPos(&point); - ScreenToClient(&point); - CRect rct; - GetClientRect(&rct); - if (rct.PtInRect(point)) + wxPoint point = wxGetMouseState().GetPosition(); + point = ScreenToClient(point); + wxRect rct = GetClientRect(); + if (rct.Contains(point)) { - point += (CSize)GetDeviceScrollPosition(); - CB::string str = m_pPBoard->GetCellNumberStr(point, m_nZoom); - pCmdUI->Enable(); - pCmdUI->SetText(str); + point = CalcUnscrolledPosition(point); + CB::string str = m_pPBoard->GetCellNumberStr(CB::Convert(point), m_nZoom); + pCmdUI.Enable(true); + pCmdUI.SetText(str); } } } -#endif void CPlayBoardView::DoViewScaleBrd(TileScale nZoom) { @@ -1609,8 +1604,7 @@ void CPlayBoardView::OnUpdatePlayTool(wxUpdateUIEvent& pCmdUI) pCmdUI.Check(pCmdUI.GetId() == m_nCurToolID); } -#if 0 -void CPlayBoardView::OnActStack() +void CPlayBoardView::OnActStack(wxCommandEvent& /*event*/) { DoAutostackOfSelectedObjects(m_pPBoard->m_xStackStagger, m_pPBoard->m_yStackStagger); @@ -1618,11 +1612,11 @@ void CPlayBoardView::OnActStack() void CPlayBoardView::DoAutostackOfSelectedObjects(int xStagger, int yStagger) { - CRect rct = m_selList.GetPiecesEnclosingRect(); - if (rct.IsRectEmpty()) + wxRect rct = CB::Convert(m_selList.GetPiecesEnclosingRect()); + if (rct.IsEmpty()) return; - CPoint pntCenter(MidPnt(rct.left, rct.right), MidPnt(rct.top, rct.bottom)); + wxPoint pntCenter(MidPnt(rct.GetLeft(), rct.GetRight()), MidPnt(rct.GetTop(), rct.GetBottom())); std::vector> tblObjs; m_selList.LoadTableWithObjectPtrs(tblObjs, CSelList::otPiecesMarks, TRUE); @@ -1630,21 +1624,22 @@ void CPlayBoardView::DoAutostackOfSelectedObjects(int xStagger, int yStagger) m_selList.PurgeList(TRUE); // Purge former selections GetDocument().AssignNewMoveGroup(); - GetDocument().PlaceObjectTableOnBoard(pntCenter, tblObjs, + GetDocument().PlaceObjectTableOnBoard(CB::Convert(pntCenter), tblObjs, xStagger, yStagger, m_pPBoard.get()); // Reselect the pieces. SelectAllObjectsInTable(tblObjs); // Reselect objects } -void CPlayBoardView::OnUpdateActStack(CCmdUI* pCmdUI) +void CPlayBoardView::OnUpdateActStack(wxUpdateUIEvent& pCmdUI) { if (GetDocument().IsPlaying()) - pCmdUI->Enable(FALSE); + pCmdUI.Enable(FALSE); else - pCmdUI->Enable(m_selList.IsMultipleSelects()); + pCmdUI.Enable(m_selList.IsMultipleSelects()); } +#if 0 void CPlayBoardView::OnActAutostackDeck() { DoAutostackOfSelectedObjects(0, 0); @@ -1707,8 +1702,9 @@ void CPlayBoardView::OnUpdateActShuffleSelectedObjects(CCmdUI* pCmdUI) else pCmdUI->Enable(m_selList.IsMultipleSelects()); } +#endif -void CPlayBoardView::OnActToFront() +void CPlayBoardView::OnActToFront(wxCommandEvent& /*event*/) { CRect rct = m_selList.GetEnclosingRect(); if (rct.IsRectEmpty()) @@ -1726,15 +1722,15 @@ void CPlayBoardView::OnActToFront() SelectAllObjectsInTable(listObjs); // Reselect pieces } -void CPlayBoardView::OnUpdateActToFront(CCmdUI* pCmdUI) +void CPlayBoardView::OnUpdateActToFront(wxUpdateUIEvent& pCmdUI) { if (GetDocument().IsPlaying()) - pCmdUI->Enable(FALSE); + pCmdUI.Enable(FALSE); else - pCmdUI->Enable(m_selList.IsAnySelects()); + pCmdUI.Enable(m_selList.IsAnySelects()); } -void CPlayBoardView::OnActToBack() +void CPlayBoardView::OnActToBack(wxCommandEvent& /*event*/) { CRect rct = m_selList.GetEnclosingRect(); if (rct.IsRectEmpty()) @@ -1752,40 +1748,42 @@ void CPlayBoardView::OnActToBack() SelectAllObjectsInTable(listObjs); // Reselect pieces } -void CPlayBoardView::OnUpdateActToBack(CCmdUI* pCmdUI) +void CPlayBoardView::OnUpdateActToBack(wxUpdateUIEvent& pCmdUI) { if (GetDocument().IsPlaying()) - pCmdUI->Enable(FALSE); + pCmdUI.Enable(FALSE); else - pCmdUI->Enable(m_selList.IsAnySelects()); + pCmdUI.Enable(m_selList.IsAnySelects()); } -BOOL CPlayBoardView::OnActTurnOver(UINT id) +void CPlayBoardView::OnActTurnOver(wxCommandEvent& event) { CPieceTable::Flip flip; - switch (id) + if (event.GetId() == XRCID("ID_ACT_TURNOVER")) { - case ID_ACT_TURNOVER: - flip = CPieceTable::fNext; - break; - case ID_ACT_TURNOVER_PREV: - flip = CPieceTable::fPrev; - break; - case ID_ACT_TURNOVER_RANDOM: - flip = CPieceTable::fRandom; - break; - default: - AfxThrowInvalidArgException(); + flip = CPieceTable::fNext; + } + else if (event.GetId() == XRCID("ID_ACT_TURNOVER_PREV")) + { + flip = CPieceTable::fPrev; + } + else if (event.GetId() == XRCID("ID_ACT_TURNOVER_RANDOM")) + { + flip = CPieceTable::fRandom; + } + else + { + throw std::invalid_argument("unknown command id"); } std::vector> listObjs; m_selList.LoadTableWithObjectPtrs(listObjs, CSelList::otAll, FALSE); - CPoint pntCenter; + wxPoint pntCenter; if (flip == CPieceTable::fRandom) { - CRect rct = m_selList.GetPiecesEnclosingRect(FALSE); - ASSERT(!rct.IsRectEmpty()); - pntCenter = CPoint(MidPnt(rct.left, rct.right), MidPnt(rct.top, rct.bottom)); + wxRect rct = CB::Convert(m_selList.GetPiecesEnclosingRect(FALSE)); + wxASSERT(!rct.IsEmpty()); + pntCenter = GetMidRect(rct); } m_selList.PurgeList(TRUE); // Purge former selections @@ -1799,17 +1797,15 @@ BOOL CPlayBoardView::OnActTurnOver(UINT id) // feedback during playback. CB::string strMsg = CB::string::LoadString(IDS_TIP_FLIP_RANDOM); pDoc.RecordEventMessage(strMsg, m_pPBoard->GetSerialNumber(), - value_preserving_cast(pntCenter.x), value_preserving_cast(pntCenter.y)); + pntCenter.x, pntCenter.y); } pDoc.InvertPlayingPieceTableOnBoard(listObjs, *m_pPBoard, flip); SelectAllObjectsInTable(listObjs); // Reselect pieces - - return true; } -void CPlayBoardView::OnUpdateActTurnOver(CCmdUI* pCmdUI) +void CPlayBoardView::OnUpdateActTurnOver(wxUpdateUIEvent& pCmdUI) { bool bEnabled = false; CGamDoc& pDoc = GetDocument(); @@ -1818,15 +1814,16 @@ void CPlayBoardView::OnUpdateActTurnOver(CCmdUI* pCmdUI) bEnabled = false; else bEnabled = m_selList.HasFlippablePieces(); - pCmdUI->Enable(bEnabled); + pCmdUI.Enable(bEnabled); +#if 0 if (pCmdUI->m_pSubMenu != NULL) { // Need to handle menu that the submenu is connected to. pCmdUI->m_pMenu->EnableMenuItem(pCmdUI->m_nIndex, MF_BYPOSITION | (bEnabled ? MF_ENABLED : (MF_DISABLED | MF_GRAYED))); } -} #endif +} void CPlayBoardView::OnActPlotMove(wxCommandEvent& /*event*/) { @@ -1924,30 +1921,30 @@ void CPlayBoardView::OnUpdateActPlotDiscard(wxUpdateUIEvent& pCmdUI) pCmdUI.Enable(m_pPBoard->GetPlotMoveMode()); } -#if 0 -void CPlayBoardView::OnViewSnapGrid() +void CPlayBoardView::OnViewSnapGrid(wxCommandEvent& /*event*/) { m_pPBoard->m_bGridSnap = !m_pPBoard->m_bGridSnap; } -void CPlayBoardView::OnUpdateViewSnapGrid(CCmdUI* pCmdUI) +void CPlayBoardView::OnUpdateViewSnapGrid(wxUpdateUIEvent& pCmdUI) { - pCmdUI->Enable(!GetDocument().IsPlaying()); - pCmdUI->SetCheck(m_pPBoard->m_bGridSnap); + pCmdUI.Enable(!GetDocument().IsPlaying()); + pCmdUI.Check(m_pPBoard->m_bGridSnap); } -void CPlayBoardView::OnEditSelAllMarkers() +void CPlayBoardView::OnEditSelAllMarkers(wxCommandEvent& /*event*/) { SelectAllMarkers(); } -void CPlayBoardView::OnUpdateEditSelAllMarkers(CCmdUI* pCmdUI) +void CPlayBoardView::OnUpdateEditSelAllMarkers(wxUpdateUIEvent& pCmdUI) { CDrawList* pDwg = m_pPBoard->GetPieceList(); - ASSERT(pDwg); - pCmdUI->Enable(!GetDocument().IsPlaying() && pDwg->HasMarker()); + wxASSERT(pDwg); + pCmdUI.Enable(!GetDocument().IsPlaying() && pDwg->HasMarker()); } +#if 0 void CPlayBoardView::OnActRotate() // ** TEST CODE ** // { std::vector tbl; @@ -2226,8 +2223,7 @@ void CPlayBoardView::OnUpdateActRotateGroupRelative(wxUpdateUIEvent& pCmdUI) /////////////////////////////////////////////////////////////////////// -#if 0 -void CPlayBoardView::OnViewPieces() +void CPlayBoardView::OnViewPieces(wxCommandEvent& /*event*/) { GetPlayBoard().SetPiecesVisible(!GetPlayBoard().GetPiecesVisible()); CGamDocHint hint; @@ -2235,113 +2231,104 @@ void CPlayBoardView::OnViewPieces() GetDocument().UpdateAllViews(NULL, HINT_UPDATEBOARD, &hint); } -void CPlayBoardView::OnUpdateViewPieces(CCmdUI* pCmdUI) +void CPlayBoardView::OnUpdateViewPieces(wxUpdateUIEvent& pCmdUI) { - pCmdUI->SetCheck(!GetPlayBoard().GetPiecesVisible()); + pCmdUI.Check(!GetPlayBoard().GetPiecesVisible()); } /////////////////////////////////////////////////////////////////////// -void CPlayBoardView::OnEditCopy() +void CPlayBoardView::OnEditCopy(wxCommandEvent& event) { CBoard* pBoard = m_pPBoard->GetBoard(); - CWindowDC scrnDC(this); - CSize size = pBoard->GetSize(m_nZoom); + wxSize size = CB::Convert(pBoard->GetSize(m_nZoom)); - OwnerPtr bmap = CDib::CreateDIBSection(size.cx, size.cy); - CDC dcMem; - dcMem.CreateCompatibleDC(&scrnDC); - CBitmap* pPrvBMap = (CBitmap*)dcMem.SelectObject(&*bmap); + wxBitmap bmap(size.x, size.y); + { + wxMemoryDC dcMem; + dcMem.SelectObject(bmap); - CRect rct(0, 0, size.cx, size.cy); + wxRect rct(wxPoint(0, 0), size); // Draw base board image... pBoard->Draw(dcMem, rct, m_nZoom, m_pPBoard->m_bCellBorders); // Draw pieces etc..... - SetupDrawListDC(dcMem, rct); - m_pPBoard->Draw(dcMem, &rct, m_nZoom); - RestoreDrawListDC(dcMem); + DCSetupDrawListDC setupDrawListDC(*this, dcMem, rct); + m_pPBoard->Draw(dcMem, rct, m_nZoom); - GdiFlush(); - dcMem.SelectObject(pPrvBMap); + } LockWxClipboard lockClipbd(std::try_to_lock); if (lockClipbd) { wxBusyCursor busyCursor; - wxImage img = ToImage(*bmap); - wxBitmap wxbmp(img); - wxTheClipboard->SetData(new wxBitmapDataObject(wxbmp)); + wxTheClipboard->SetData(new wxBitmapDataObject(bmap)); } } -void CPlayBoardView::OnEditBoardToFile() +void CPlayBoardView::OnEditBoardToFile(wxCommandEvent& event) { CB::string strFilter = CB::string::LoadString(IDS_BMP_FILTER); CB::string strTitle = CB::string::LoadString(IDS_SEL_BITMAPFILE); - CFileDialog dlg(FALSE, "bmp"_cbstring, NULL, OFN_HIDEREADONLY | - OFN_OVERWRITEPROMPT, strFilter, NULL, 0); - dlg.m_ofn.lpstrTitle = strTitle; + wxFileDialog dlg(this, strTitle, + wxEmptyString, wxEmptyString, + strFilter, + wxFD_SAVE | wxFD_OVERWRITE_PROMPT); - if (dlg.DoModal() != IDOK) + if (dlg.ShowModal() != wxID_OK) return; - BeginWaitCursor(); - TRY + wxBusyCursor busyCursor; + try { CBoard* pBoard = m_pPBoard->GetBoard(); - CWindowDC scrnDC(this); - CSize size = pBoard->GetSize(m_nZoom); + wxSize size = CB::Convert(pBoard->GetSize(m_nZoom)); - OwnerPtr bmap = CDib::CreateDIBSection( - size.cx, size.cy); - CDC dcMem; - dcMem.CreateCompatibleDC(&scrnDC); - CBitmap* pPrvBMap = (CBitmap*)dcMem.SelectObject(&*bmap); + wxBitmap bmap(size.x, size.y); + { + wxMemoryDC dcMem; + dcMem.SelectObject(bmap); - CRect rct(0, 0, size.cx, size.cy); + wxRect rct(wxPoint(0, 0), size); // Draw base board image... pBoard->Draw(dcMem, rct, m_nZoom, m_pPBoard->m_bCellBorders); // Draw pieces etc..... - SetupDrawListDC(dcMem, rct); + DCSetupDrawListDC setupDrawListDC(*this, dcMem, rct); m_pPBoard->Draw(dcMem, rct, m_nZoom); - RestoreDrawListDC(dcMem); - GdiFlush(); - dcMem.SelectObject(pPrvBMap); + } - wxImage img = ToImage(*bmap); + wxImage img = bmap.ConvertToImage(); - if (!img.SaveFile(CB::string(dlg.GetPathName()))) + if (!img.SaveFile(dlg.GetPath())) { - EndWaitCursor(); - AfxMessageBox(IDP_ERR_BMPCREATE, MB_ICONEXCLAMATION); - EndWaitCursor(); + wxMessageBox(CB::string::LoadString(IDP_ERR_BMPCREATE), + CB::GetAppName(), + wxICON_EXCLAMATION); return; } - - EndWaitCursor(); } - CATCH_ALL (e) + catch (...) { - EndWaitCursor(); - AfxMessageBox(IDP_ERR_BMPWRITE, MB_ICONEXCLAMATION); + wxMessageBox(CB::string::LoadString(IDP_ERR_BMPWRITE), + CB::GetAppName(), + wxICON_EXCLAMATION); } - END_CATCH_ALL } -void CPlayBoardView::OnEditBoardProperties() +void CPlayBoardView::OnEditBoardProperties(wxCommandEvent& event) { GetDocument().DoBoardProperties(GetPlayBoard()); } +#if 0 void CPlayBoardView::OnSelectGroupMarkers(UINT nID) { SelectMarkersInGroup(nID - ID_MRKGROUP_FIRST); @@ -2779,6 +2766,11 @@ BOOL CPlayBoardView::DoMouseWheelFix(UINT fFlags, short zDelta, CPoint point) } #endif +void CPlayBoardView::OnUpdateEnable(wxUpdateUIEvent& pCmdUI) +{ + pCmdUI.Enable(true); +} + void CPlayBoardViewContainer::OnDraw(CDC* pDC) { // do nothing because child covers entire client rect diff --git a/GP/VwPbrd.h b/GP/VwPbrd.h index eaae0f2a..6cc01074 100644 --- a/GP/VwPbrd.h +++ b/GP/VwPbrd.h @@ -245,16 +245,14 @@ class CPlayBoardView : public CB::ProcessEventOverride void OnChar(wxKeyEvent& event); void OnPlayTool(wxCommandEvent& event); void OnUpdatePlayTool(wxUpdateUIEvent& pCmdUI); -#if 0 - afx_msg void OnActStack(); - afx_msg void OnUpdateActStack(CCmdUI* pCmdUI); - afx_msg void OnActToBack(); - afx_msg void OnUpdateActToBack(CCmdUI* pCmdUI); - afx_msg void OnActToFront(); - afx_msg void OnUpdateActToFront(CCmdUI* pCmdUI); - afx_msg BOOL OnActTurnOver(UINT id); - afx_msg void OnUpdateActTurnOver(CCmdUI* pCmdUI); -#endif + void OnActStack(wxCommandEvent& event); + void OnUpdateActStack(wxUpdateUIEvent& pCmdUI); + void OnActToBack(wxCommandEvent& event); + void OnUpdateActToBack(wxUpdateUIEvent& pCmdUI); + void OnActToFront(wxCommandEvent& event); + void OnUpdateActToFront(wxUpdateUIEvent& pCmdUI); + void OnActTurnOver(wxCommandEvent& event); + void OnUpdateActTurnOver(wxUpdateUIEvent& pCmdUI); void OnActPlotMove(wxCommandEvent& event); void OnUpdateActPlotMove(wxUpdateUIEvent& pCmdUI); void OnActPlotDone(); @@ -263,24 +261,22 @@ class CPlayBoardView : public CB::ProcessEventOverride void OnActPlotDiscard(); void OnActPlotDiscard(wxCommandEvent& /*event*/) { OnActPlotDiscard(); } void OnUpdateActPlotDiscard(wxUpdateUIEvent& pCmdUI); + void OnUpdateIndicatorCellNum(wxUpdateUIEvent& pCmdUI); + void OnViewSnapGrid(wxCommandEvent& event); + void OnUpdateViewSnapGrid(wxUpdateUIEvent& pCmdUI); + void OnEditSelAllMarkers(wxCommandEvent& event); + void OnUpdateEditSelAllMarkers(wxUpdateUIEvent& pCmdUI); #if 0 - afx_msg void OnUpdateIndicatorCellNum(CCmdUI* pCmdUI); - afx_msg void OnViewSnapGrid(); - afx_msg void OnUpdateViewSnapGrid(CCmdUI* pCmdUI); - afx_msg void OnEditSelAllMarkers(); - afx_msg void OnUpdateEditSelAllMarkers(CCmdUI* pCmdUI); afx_msg void OnActRotate(); afx_msg void OnUpdateActRotate(CCmdUI* pCmdUI); #endif void OnViewToggleScale(wxCommandEvent& event); void OnUpdateViewToggleScale(wxUpdateUIEvent& pCmdUI); -#if 0 - afx_msg void OnViewPieces(); - afx_msg void OnUpdateViewPieces(CCmdUI* pCmdUI); - afx_msg void OnEditCopy(); - afx_msg void OnEditBoardToFile(); - afx_msg void OnEditBoardProperties(); -#endif + void OnViewPieces(wxCommandEvent& event); + void OnUpdateViewPieces(wxUpdateUIEvent& pCmdUI); + void OnEditCopy(wxCommandEvent& event); + void OnEditBoardToFile(wxCommandEvent& event); + void OnEditBoardProperties(wxCommandEvent& event); void OnActRotateRelative(wxCommandEvent& event); void OnUpdateActRotateRelative(wxUpdateUIEvent& pCmdUI); void OnEditClear(); @@ -327,6 +323,8 @@ class CPlayBoardView : public CB::ProcessEventOverride public: void OnActRotateGroupRelative(wxCommandEvent& event); void OnUpdateActRotateGroupRelative(wxUpdateUIEvent& pCmdUI); +private: + void OnUpdateEnable(wxUpdateUIEvent& pCmdUI); private: // IGetCmdTarget diff --git a/GShr/LibMfc.cpp b/GShr/LibMfc.cpp index 3676fc45..919ddb1f 100644 --- a/GShr/LibMfc.cpp +++ b/GShr/LibMfc.cpp @@ -1326,6 +1326,12 @@ namespace CB return XRCID("ID_ACT_ROTATEGROUP"); case ID_ACT_ROTATEREL: return XRCID("ID_ACT_ROTATEREL"); + case ID_ACT_STACK: + return XRCID("ID_ACT_STACK"); + case ID_ACT_TOBACK: + return XRCID("ID_ACT_TOBACK"); + case ID_ACT_TOFRONT: + return XRCID("ID_ACT_TOFRONT"); case ID_ACT_TURNOVER: return XRCID("ID_ACT_TURNOVER"); case ID_ACT_TURNOVER_PREV: @@ -1334,8 +1340,14 @@ namespace CB return XRCID("ID_ACT_TURNOVER_RANDOM"); case ID_ACT_TURNOVER_SELECT: return XRCID("ID_ACT_TURNOVER_SELECT"); + case ID_EDIT_BRD2FILE: + return XRCID("ID_EDIT_BRD2FILE"); case ID_EDIT_BRDPROP: return XRCID("ID_EDIT_BRDPROP"); + case ID_EDIT_SELALLMARKERS: + return XRCID("ID_EDIT_SELALLMARKERS"); + case ID_INDICATOR_CELLNUM: + return XRCID("ID_INDICATOR_CELLNUM"); case ID_PPROJITEM_DELETE: return XRCID("ID_PPROJITEM_DELETE"); case ID_PPROJITEM_EDIT: @@ -1358,8 +1370,12 @@ namespace CB return XRCID("ID_VIEW_FULLSCALEBRD"); case ID_VIEW_HALFSCALEBRD: return XRCID("ID_VIEW_HALFSCALEBRD"); + case ID_VIEW_PIECES: + return XRCID("ID_VIEW_PIECES"); case ID_VIEW_SMALLSCALEBRD: return XRCID("ID_VIEW_SMALLSCALEBRD"); + case ID_VIEW_SNAPGRID: + return XRCID("ID_VIEW_SNAPGRID"); case ID_VIEW_TOGGLESCALE: return XRCID("ID_VIEW_TOGGLESCALE"); default: From 140933b84b0357d8c43ee7cab51be7f16d71f093 Mon Sep 17 00:00:00 2001 From: Bill Su Date: Fri, 12 Dec 2025 02:00:46 -0500 Subject: [PATCH 49/80] VwPbrd: implement event handlers, part 3 --- GP/VwPbrd.cpp | 145 ++++++++++++++++++++++++------------------------ GP/VwPbrd.h | 40 +++++++------ GShr/LibMfc.cpp | 18 ++++++ 3 files changed, 108 insertions(+), 95 deletions(-) diff --git a/GP/VwPbrd.cpp b/GP/VwPbrd.cpp index 739e9411..05f667b8 100644 --- a/GP/VwPbrd.cpp +++ b/GP/VwPbrd.cpp @@ -121,25 +121,25 @@ wxBEGIN_EVENT_TABLE(CPlayBoardView, CPlayBoardView::BASE) EVT_UPDATE_UI(wxID_CLEAR, OnUpdateEditClear) #if 0 ON_WM_CONTEXTMENU() - ON_COMMAND(ID_VIEW_DRAW_IND_ON_TOP, OnViewDrawIndOnTop) - ON_UPDATE_COMMAND_UI(ID_VIEW_DRAW_IND_ON_TOP, OnUpdateViewDrawIndOnTop) - ON_COMMAND(ID_EDIT_ELEMENT_TEXT, OnEditElementText) - ON_UPDATE_COMMAND_UI(ID_EDIT_ELEMENT_TEXT, OnUpdateEditElementText) - ON_COMMAND(ID_ACT_LOCKOBJECT, OnActLockObject) - ON_UPDATE_COMMAND_UI(ID_ACT_LOCKOBJECT, OnUpdateActLockObject) - ON_COMMAND(ID_ACT_LOCK_SUSPEND, OnActLockSuspend) - ON_UPDATE_COMMAND_UI(ID_ACT_LOCK_SUSPEND, OnUpdateActLockSuspend) - ON_COMMAND(ID_ACT_SHUFFLE_SELECTED, OnActShuffleSelectedObjects) - ON_UPDATE_COMMAND_UI(ID_ACT_SHUFFLE_SELECTED, OnUpdateActShuffleSelectedObjects) - ON_COMMAND(ID_ACT_AUTOSTACK_DECK, OnActAutostackDeck) - ON_UPDATE_COMMAND_UI(ID_ACT_AUTOSTACK_DECK, OnUpdateActAutostackDeck) - ON_COMMAND(ID_ACT_TAKE_OWNERSHIP, OnActTakeOwnership) - ON_UPDATE_COMMAND_UI(ID_ACT_TAKE_OWNERSHIP, OnUpdateActTakeOwnership) - ON_COMMAND(ID_ACT_RELEASE_OWNERSHIP, OnActReleaseOwnership) - ON_UPDATE_COMMAND_UI(ID_ACT_RELEASE_OWNERSHIP, OnUpdateActReleaseOwnership) - ON_COMMAND(ID_ACT_SET_OWNER, OnActSetOwner) - ON_UPDATE_COMMAND_UI(ID_ACT_SET_OWNER, OnUpdateActSetOwner) #endif + EVT_MENU(XRCID("ID_VIEW_DRAW_IND_ON_TOP"), OnViewDrawIndOnTop) + EVT_UPDATE_UI(XRCID("ID_VIEW_DRAW_IND_ON_TOP"), OnUpdateViewDrawIndOnTop) + EVT_MENU(XRCID("ID_EDIT_ELEMENT_TEXT"), OnEditElementText) + EVT_UPDATE_UI(XRCID("ID_EDIT_ELEMENT_TEXT"), OnUpdateEditElementText) + EVT_MENU(XRCID("ID_ACT_LOCKOBJECT"), OnActLockObject) + EVT_UPDATE_UI(XRCID("ID_ACT_LOCKOBJECT"), OnUpdateActLockObject) + EVT_MENU(XRCID("ID_ACT_LOCK_SUSPEND"), OnActLockSuspend) + EVT_UPDATE_UI(XRCID("ID_ACT_LOCK_SUSPEND"), OnUpdateActLockSuspend) + EVT_MENU(XRCID("ID_ACT_SHUFFLE_SELECTED"), OnActShuffleSelectedObjects) + EVT_UPDATE_UI(XRCID("ID_ACT_SHUFFLE_SELECTED"), OnUpdateActShuffleSelectedObjects) + EVT_MENU(XRCID("ID_ACT_AUTOSTACK_DECK"), OnActAutostackDeck) + EVT_UPDATE_UI(XRCID("ID_ACT_AUTOSTACK_DECK"), OnUpdateActAutostackDeck) + EVT_MENU(XRCID("ID_ACT_TAKE_OWNERSHIP"), OnActTakeOwnership) + EVT_UPDATE_UI(XRCID("ID_ACT_TAKE_OWNERSHIP"), OnUpdateActTakeOwnership) + EVT_MENU(XRCID("ID_ACT_RELEASE_OWNERSHIP"), OnActReleaseOwnership) + EVT_UPDATE_UI(XRCID("ID_ACT_RELEASE_OWNERSHIP"), OnUpdateActReleaseOwnership) + EVT_MENU(XRCID("ID_ACT_SET_OWNER"), OnActSetOwner) + EVT_UPDATE_UI(XRCID("ID_ACT_SET_OWNER"), OnUpdateActSetOwner) EVT_MENU(XRCID("ID_VIEW_SMALLSCALEBRD"), OnViewSmallScaleBoard) EVT_UPDATE_UI(XRCID("ID_VIEW_SMALLSCALEBRD"), OnUpdateViewSmallScaleBoard) EVT_MENU(XRCID("ID_PTOOL_LINE"), OnPlayTool) @@ -160,9 +160,7 @@ wxBEGIN_EVENT_TABLE(CPlayBoardView, CPlayBoardView::BASE) ON_UPDATE_COMMAND_UI_RANGE(ID_MRKGROUP_FIRST, ID_MRKGROUP_FIRST + 64, OnUpdateSelectGroupMarkers) #endif EVT_WINSTATE(OnMessageWindowState) -#if 0 - ON_MESSAGE(WM_SELECT_BOARD_OBJLIST, OnMessageSelectBoardObjectList) -#endif + EVT_SELECT_BOARD_OBJLIST(OnMessageSelectBoardObjectList) EVT_SCROLLWIN_LINEDOWN(OnScrollWinLine) EVT_SCROLLWIN_LINEUP(OnScrollWinLine) wxEND_EVENT_TABLE() @@ -364,21 +362,21 @@ void CPlayBoardView::OnActivateView(BOOL bActivate, CView* pActivateView, CView* NotifySelectListChange(); } -#if 0 /////////////////////////////////////////////////////////////////////// // This message is sent when a document is being saved. // WPARAM = CPlayBoard*, LPARAM = const std::vector>* -LRESULT CPlayBoardView::OnMessageSelectBoardObjectList(WPARAM wParam, LPARAM lParam) +void CPlayBoardView::OnMessageSelectBoardObjectList(SelectBoardObjListEvent& event) { - if ((CPlayBoard*)wParam != m_pPBoard) - return (LRESULT)0; - const std::vector>& pList = *(const std::vector>*)lParam; + if (&event.GetBoard() != m_pPBoard) + { + event.Skip(); + return; + } + const std::vector>& pList = event.GetObjList(); m_selList.PurgeList(); // Deselect current set of selections SelectAllObjectsInList(pList); // Select the new set - return (LRESULT)1; } -#endif /////////////////////////////////////////////////////////////////////// // This message is sent when a document is being saved. @@ -1639,18 +1637,17 @@ void CPlayBoardView::OnUpdateActStack(wxUpdateUIEvent& pCmdUI) pCmdUI.Enable(m_selList.IsMultipleSelects()); } -#if 0 -void CPlayBoardView::OnActAutostackDeck() +void CPlayBoardView::OnActAutostackDeck(wxCommandEvent& /*event*/) { DoAutostackOfSelectedObjects(0, 0); } -void CPlayBoardView::OnUpdateActAutostackDeck(CCmdUI* pCmdUI) +void CPlayBoardView::OnUpdateActAutostackDeck(wxUpdateUIEvent& pCmdUI) { OnUpdateActStack(pCmdUI); } -void CPlayBoardView::OnActShuffleSelectedObjects() +void CPlayBoardView::OnActShuffleSelectedObjects(wxCommandEvent& /*event*/) { CRect rct = m_selList.GetPiecesEnclosingRect(); if (rct.IsRectEmpty()) @@ -1695,14 +1692,13 @@ void CPlayBoardView::OnActShuffleSelectedObjects() SelectAllObjectsInTable(tblRandObjs); // Reselect objects } -void CPlayBoardView::OnUpdateActShuffleSelectedObjects(CCmdUI* pCmdUI) +void CPlayBoardView::OnUpdateActShuffleSelectedObjects(wxUpdateUIEvent& pCmdUI) { if (GetDocument().IsPlaying()) - pCmdUI->Enable(FALSE); + pCmdUI.Enable(FALSE); else - pCmdUI->Enable(m_selList.IsMultipleSelects()); + pCmdUI.Enable(m_selList.IsMultipleSelects()); } -#endif void CPlayBoardView::OnActToFront(wxCommandEvent& /*event*/) { @@ -2238,7 +2234,7 @@ void CPlayBoardView::OnUpdateViewPieces(wxUpdateUIEvent& pCmdUI) /////////////////////////////////////////////////////////////////////// -void CPlayBoardView::OnEditCopy(wxCommandEvent& event) +void CPlayBoardView::OnEditCopy(wxCommandEvent& /*event*/) { CBoard* pBoard = m_pPBoard->GetBoard(); @@ -2269,7 +2265,7 @@ void CPlayBoardView::OnEditCopy(wxCommandEvent& event) } } -void CPlayBoardView::OnEditBoardToFile(wxCommandEvent& event) +void CPlayBoardView::OnEditBoardToFile(wxCommandEvent& /*event*/) { CB::string strFilter = CB::string::LoadString(IDS_BMP_FILTER); CB::string strTitle = CB::string::LoadString(IDS_SEL_BITMAPFILE); @@ -2323,7 +2319,7 @@ void CPlayBoardView::OnEditBoardToFile(wxCommandEvent& event) } } -void CPlayBoardView::OnEditBoardProperties(wxCommandEvent& event) +void CPlayBoardView::OnEditBoardProperties(wxCommandEvent& /*event*/) { GetDocument().DoBoardProperties(GetPlayBoard()); } @@ -2361,8 +2357,9 @@ void CPlayBoardView::OnUpdateSelectGroupMarkers(CCmdUI* pCmdUI, UINT nID) else pCmdUI->Enable(); } +#endif -void CPlayBoardView::OnViewDrawIndOnTop() +void CPlayBoardView::OnViewDrawIndOnTop(wxCommandEvent& /*event*/) { GetPlayBoard().SetIndicatorsOnTop(!GetPlayBoard().GetIndicatorsOnTop()); CGamDocHint hint; @@ -2370,12 +2367,13 @@ void CPlayBoardView::OnViewDrawIndOnTop() GetDocument().UpdateAllViews(NULL, HINT_UPDATEBOARD, &hint); } -void CPlayBoardView::OnUpdateViewDrawIndOnTop(CCmdUI* pCmdUI) +void CPlayBoardView::OnUpdateViewDrawIndOnTop(wxUpdateUIEvent& pCmdUI) { - pCmdUI->SetCheck(GetPlayBoard().GetIndicatorsOnTop()); + pCmdUI.Enable(true); + pCmdUI.Check(GetPlayBoard().GetIndicatorsOnTop()); } -void CPlayBoardView::OnEditElementText() +void CPlayBoardView::OnEditElementText(wxCommandEvent& /*event*/) { ASSERT(m_selList.IsSingleSelect() && (m_selList.HasMarkers() || m_selList.HasPieces())); @@ -2384,20 +2382,20 @@ void CPlayBoardView::OnEditElementText() NotifySelectListChange(); // Make sure indicators are updated } -void CPlayBoardView::OnUpdateEditElementText(CCmdUI* pCmdUI) +void CPlayBoardView::OnUpdateEditElementText(wxUpdateUIEvent& pCmdUI) { CGamDoc& pDoc = GetDocument(); if (pDoc.IsPlaying() || !pDoc.IsScenario() && m_selList.HasOwnedPiecesNotMatching(pDoc.GetCurrentPlayerMask())) - pCmdUI->Enable(FALSE); + pCmdUI.Enable(FALSE); else { - pCmdUI->Enable(m_selList.IsSingleSelect() && + pCmdUI.Enable(m_selList.IsSingleSelect() && (m_selList.HasMarkers() || m_selList.HasPieces())); } } -void CPlayBoardView::OnActLockObject() +void CPlayBoardView::OnActLockObject(wxCommandEvent& /*event*/) { int nSet; int nClear; @@ -2417,11 +2415,11 @@ void CPlayBoardView::OnActLockObject() m_selList.PurgeList(TRUE); // Purge former selections } -void CPlayBoardView::OnUpdateActLockObject(CCmdUI* pCmdUI) +void CPlayBoardView::OnUpdateActLockObject(wxUpdateUIEvent& pCmdUI) { if (GetDocument().IsPlaying()) { - pCmdUI->Enable(FALSE); + pCmdUI.Enable(FALSE); return; } @@ -2431,15 +2429,15 @@ void CPlayBoardView::OnUpdateActLockObject(CCmdUI* pCmdUI) m_selList.CountDObjFlags(dobjFlgLockDown, nSet, nClear); if (nSet != 0 && nClear != 0) - pCmdUI->SetCheck(2); + pCmdUI.Set3StateValue(wxCHK_UNDETERMINED); else if (nSet != 0 && nClear == 0) - pCmdUI->SetCheck(1); + pCmdUI.Set3StateValue(wxCHK_CHECKED); else - pCmdUI->SetCheck(0); - pCmdUI->Enable(!m_selList.empty()); + pCmdUI.Set3StateValue(wxCHK_UNCHECKED); + pCmdUI.Enable(!m_selList.empty()); } -void CPlayBoardView::OnActLockSuspend() +void CPlayBoardView::OnActLockSuspend(wxCommandEvent& /*event*/) { m_pPBoard->SetLocksEnforced(!m_pPBoard->GetLocksEnforced()); // If enforcement is on and objects are locked, deselect them @@ -2447,19 +2445,19 @@ void CPlayBoardView::OnActLockSuspend() m_selList.DeselectIfDObjFlagsSet(dobjFlgLockDown); } -void CPlayBoardView::OnUpdateActLockSuspend(CCmdUI* pCmdUI) +void CPlayBoardView::OnUpdateActLockSuspend(wxUpdateUIEvent& pCmdUI) { if (GetDocument().IsPlaying()) - pCmdUI->Enable(FALSE); + pCmdUI.Enable(FALSE); else { - pCmdUI->Enable(TRUE); - pCmdUI->SetCheck(!m_pPBoard->GetLocksEnforced()); + pCmdUI.Enable(TRUE); + pCmdUI.Check(!m_pPBoard->GetLocksEnforced()); } } -void CPlayBoardView::OnActTakeOwnership() +void CPlayBoardView::OnActTakeOwnership(wxCommandEvent& /*event*/) { CRect rct = m_selList.GetPiecesEnclosingRect(FALSE); if (rct.IsRectEmpty()) @@ -2493,22 +2491,22 @@ void CPlayBoardView::OnActTakeOwnership() NotifySelectListChange(); } -void CPlayBoardView::OnUpdateActTakeOwnership(CCmdUI* pCmdUI) +void CPlayBoardView::OnUpdateActTakeOwnership(wxUpdateUIEvent& pCmdUI) { CGamDoc& pDoc = GetDocument(); // Can't take ownership while residing on an owned board. if (pDoc.IsPlaying() || m_pPBoard->IsOwned()) - pCmdUI->Enable(FALSE); + pCmdUI.Enable(FALSE); else if (pDoc.IsCurrentPlayerReferee()) - pCmdUI->Enable(FALSE); // No owner to acquire. He's the Referee! + pCmdUI.Enable(FALSE); // No owner to acquire. He's the Referee! else { - pCmdUI->Enable(pDoc.HasPlayers() && m_selList.HasNonOwnedPieces() && + pCmdUI.Enable(pDoc.HasPlayers() && m_selList.HasNonOwnedPieces() && pDoc.GetCurrentPlayerMask() != OWNER_MASK_SPECTATOR); } } -void CPlayBoardView::OnActReleaseOwnership() +void CPlayBoardView::OnActReleaseOwnership(wxCommandEvent& /*event*/) { CRect rct = m_selList.GetPiecesEnclosingRect(FALSE); if (rct.IsRectEmpty()) @@ -2542,22 +2540,22 @@ void CPlayBoardView::OnActReleaseOwnership() NotifySelectListChange(); } -void CPlayBoardView::OnUpdateActReleaseOwnership(CCmdUI* pCmdUI) +void CPlayBoardView::OnUpdateActReleaseOwnership(wxUpdateUIEvent& pCmdUI) { CGamDoc& pDoc = GetDocument(); // Can't release ownership while residing on an owned board. if (pDoc.IsPlaying() || m_pPBoard->IsOwned()) - pCmdUI->Enable(FALSE); + pCmdUI.Enable(FALSE); else if (pDoc.IsCurrentPlayerReferee() && m_selList.HasPieces()) - pCmdUI->Enable(TRUE); + pCmdUI.Enable(TRUE); else { - pCmdUI->Enable(pDoc.HasPlayers() && m_selList.HasOwnedPieces() && + pCmdUI.Enable(pDoc.HasPlayers() && m_selList.HasOwnedPieces() && pDoc.GetCurrentPlayerMask() != OWNER_MASK_SPECTATOR); } } -void CPlayBoardView::OnActSetOwner() +void CPlayBoardView::OnActSetOwner(wxCommandEvent& /*event*/) { CGamDoc& pDoc = GetDocument(); CRect rct = m_selList.GetPiecesEnclosingRect(FALSE); @@ -2598,21 +2596,20 @@ void CPlayBoardView::OnActSetOwner() NotifySelectListChange(); } -void CPlayBoardView::OnUpdateActSetOwner(CCmdUI* pCmdUI) +void CPlayBoardView::OnUpdateActSetOwner(wxUpdateUIEvent& pCmdUI) { CGamDoc& pDoc = GetDocument(); // Can't take ownership while residing on an owned board. if (pDoc.IsPlaying() || m_pPBoard->IsOwned()) - pCmdUI->Enable(FALSE); + pCmdUI.Enable(FALSE); else if (pDoc.IsCurrentPlayerReferee() && m_selList.HasPieces()) - pCmdUI->Enable(TRUE); + pCmdUI.Enable(TRUE); else { - pCmdUI->Enable(pDoc.HasPlayers() && + pCmdUI.Enable(pDoc.HasPlayers() && (m_selList.HasPieces() && pDoc.GetCurrentPlayerMask() != OWNER_MASK_SPECTATOR)); } } -#endif #if 0 ///////////////////////////////////////////////////////////////////////////// diff --git a/GP/VwPbrd.h b/GP/VwPbrd.h index 6cc01074..b1d376e7 100644 --- a/GP/VwPbrd.h +++ b/GP/VwPbrd.h @@ -284,25 +284,25 @@ class CPlayBoardView : public CB::ProcessEventOverride void OnUpdateEditClear(wxUpdateUIEvent& pCmdUI); #if 0 afx_msg void OnContextMenu(CWnd* pWnd, CPoint point); - afx_msg void OnViewDrawIndOnTop(); - afx_msg void OnUpdateViewDrawIndOnTop(CCmdUI* pCmdUI); - afx_msg void OnEditElementText(); - afx_msg void OnUpdateEditElementText(CCmdUI* pCmdUI); - afx_msg void OnActLockObject(); - afx_msg void OnUpdateActLockObject(CCmdUI* pCmdUI); - afx_msg void OnActLockSuspend(); - afx_msg void OnUpdateActLockSuspend(CCmdUI* pCmdUI); - afx_msg void OnActShuffleSelectedObjects(); - afx_msg void OnUpdateActShuffleSelectedObjects(CCmdUI* pCmdUI); - afx_msg void OnActAutostackDeck(); - afx_msg void OnUpdateActAutostackDeck(CCmdUI* pCmdUI); - afx_msg void OnActTakeOwnership(); - afx_msg void OnUpdateActTakeOwnership(CCmdUI* pCmdUI); - afx_msg void OnActReleaseOwnership(); - afx_msg void OnUpdateActReleaseOwnership(CCmdUI* pCmdUI); - afx_msg void OnActSetOwner(); - afx_msg void OnUpdateActSetOwner(CCmdUI* pCmdUI); #endif + void OnViewDrawIndOnTop(wxCommandEvent& event); + void OnUpdateViewDrawIndOnTop(wxUpdateUIEvent& pCmdUI); + void OnEditElementText(wxCommandEvent& event); + void OnUpdateEditElementText(wxUpdateUIEvent& pCmdUI); + void OnActLockObject(wxCommandEvent& event); + void OnUpdateActLockObject(wxUpdateUIEvent& pCmdUI); + void OnActLockSuspend(wxCommandEvent& event); + void OnUpdateActLockSuspend(wxUpdateUIEvent& pCmdUI); + void OnActShuffleSelectedObjects(wxCommandEvent& event); + void OnUpdateActShuffleSelectedObjects(wxUpdateUIEvent& pCmdUI); + void OnActAutostackDeck(wxCommandEvent& event); + void OnUpdateActAutostackDeck(wxUpdateUIEvent& pCmdUI); + void OnActTakeOwnership(wxCommandEvent& event); + void OnUpdateActTakeOwnership(wxUpdateUIEvent& pCmdUI); + void OnActReleaseOwnership(wxCommandEvent& event); + void OnUpdateActReleaseOwnership(wxUpdateUIEvent& pCmdUI); + void OnActSetOwner(wxCommandEvent& event); + void OnUpdateActSetOwner(wxUpdateUIEvent& pCmdUI); void OnViewSmallScaleBoard(wxCommandEvent& event); void OnUpdateViewSmallScaleBoard(wxUpdateUIEvent& pCmdUI); void OnViewBoardRotate180(wxCommandEvent& event); @@ -315,9 +315,7 @@ class CPlayBoardView : public CB::ProcessEventOverride afx_msg void OnUpdateRotatePiece(CCmdUI* pCmdUI, UINT nID); #endif void OnMessageWindowState(WinStateEvent& event); -#if 0 - afx_msg LRESULT OnMessageSelectBoardObjectList(WPARAM wParam, LPARAM lParam); -#endif + void OnMessageSelectBoardObjectList(SelectBoardObjListEvent& event); void OnScrollWinLine(wxScrollWinEvent& event); wxDECLARE_EVENT_TABLE(); public: diff --git a/GShr/LibMfc.cpp b/GShr/LibMfc.cpp index 919ddb1f..7513f6f1 100644 --- a/GShr/LibMfc.cpp +++ b/GShr/LibMfc.cpp @@ -1318,16 +1318,30 @@ namespace CB #if defined(GPLAY) switch (id) { + case ID_ACT_AUTOSTACK_DECK: + return XRCID("ID_ACT_AUTOSTACK_DECK"); + case ID_ACT_LOCK_SUSPEND: + return XRCID("ID_ACT_LOCK_SUSPEND"); + case ID_ACT_LOCKOBJECT: + return XRCID("ID_ACT_LOCKOBJECT"); case ID_ACT_PLOTDISCARD: return XRCID("ID_ACT_PLOTDISCARD"); case ID_ACT_PLOTDONE: return XRCID("ID_ACT_PLOTDONE"); + case ID_ACT_RELEASE_OWNERSHIP: + return XRCID("ID_ACT_RELEASE_OWNERSHIP"); case ID_ACT_ROTATEGROUP: return XRCID("ID_ACT_ROTATEGROUP"); case ID_ACT_ROTATEREL: return XRCID("ID_ACT_ROTATEREL"); + case ID_ACT_SET_OWNER: + return XRCID("ID_ACT_SET_OWNER"); + case ID_ACT_SHUFFLE_SELECTED: + return XRCID("ID_ACT_SHUFFLE_SELECTED"); case ID_ACT_STACK: return XRCID("ID_ACT_STACK"); + case ID_ACT_TAKE_OWNERSHIP: + return XRCID("ID_ACT_TAKE_OWNERSHIP"); case ID_ACT_TOBACK: return XRCID("ID_ACT_TOBACK"); case ID_ACT_TOFRONT: @@ -1344,6 +1358,8 @@ namespace CB return XRCID("ID_EDIT_BRD2FILE"); case ID_EDIT_BRDPROP: return XRCID("ID_EDIT_BRDPROP"); + case ID_EDIT_ELEMENT_TEXT: + return XRCID("ID_EDIT_ELEMENT_TEXT"); case ID_EDIT_SELALLMARKERS: return XRCID("ID_EDIT_SELALLMARKERS"); case ID_INDICATOR_CELLNUM: @@ -1366,6 +1382,8 @@ namespace CB return XRCID("ID_PTOOL_TEXTBOX"); case ID_VIEW_BOARD_ROTATE180: return XRCID("ID_VIEW_BOARD_ROTATE180"); + case ID_VIEW_DRAW_IND_ON_TOP: + return XRCID("ID_VIEW_DRAW_IND_ON_TOP"); case ID_VIEW_FULLSCALEBRD: return XRCID("ID_VIEW_FULLSCALEBRD"); case ID_VIEW_HALFSCALEBRD: From 6641386d219ef5ef75ce3f5a6dd8c7abec28f49e Mon Sep 17 00:00:00 2001 From: Bill Su Date: Sat, 21 Feb 2026 19:42:50 -0500 Subject: [PATCH 50/80] VwPbrd: implement context menu --- GP/CBPlay.fbp | 1685 +++++++++++++++++++++++++++++++++++++++++++++++++ GP/CBPlay.xrc | 658 +++++++++++++++++++ GP/VwPbrd.cpp | 37 +- GP/VwPbrd.h | 4 +- 4 files changed, 2361 insertions(+), 23 deletions(-) diff --git a/GP/CBPlay.fbp b/GP/CBPlay.fbp index df491de3..d7c53048 100644 --- a/GP/CBPlay.fbp +++ b/GP/CBPlay.fbp @@ -15629,16 +15629,1701 @@ 0=PV_MOVEMODE MENU_PV_MOVEMODE protected + + + 0 + 1 + Erase the selection + wxID_ANY + wxITEM_NORMAL + Delete Marker + wxID_CLEAR + none + + + + + + 0 + 1 + Select all markers in the current board view + wxID_ANY + wxITEM_NORMAL + Select All Markers + ID_EDIT_SELALLMARKERS + none + + + + + + Select All Markers From + m_menu3 + protected + + + 0 + 1 + + wxID_ANY + wxITEM_NORMAL + No Markers + ID_MRKGROUP_FIRST + none + + + + + + m_separator8 + none + + + + 0 + 1 + Automatically stack selected pieces. + wxID_ANY + wxITEM_NORMAL + Auto Stack + ID_ACT_STACK + none + + + + + + 0 + 1 + Autostack selected objects using a offset of zero. + wxID_ANY + wxITEM_NORMAL + Auto Stack Deck + ID_ACT_AUTOSTACK_DECK + none + + + + + + 0 + 1 + Randomize the stacking order of the selected objects + wxID_ANY + wxITEM_NORMAL + Shuffle Objects + ID_ACT_SHUFFLE_SELECTED + none + + + + + m_separator9 + none + + + + 0 + 1 + Move selected piece(s) in front of other pieces + wxID_ANY + wxITEM_NORMAL + Move To Front + ID_ACT_TOFRONT + none + + + + + + 0 + 1 + Move selected pieces(s) behind other pieces + wxID_ANY + wxITEM_NORMAL + Move To Back + ID_ACT_TOBACK + none + + + + + + 0 + 1 + Turn the selected piece over to the next side + wxID_ANY + wxITEM_NORMAL + Turn Piece Over + ID_ACT_TURNOVER + none + + + + + m_separator10 + none + + + + 0 + 1 + Rotate (or wheel) group of pieces or markers by incremental amounts + wxID_ANY + wxITEM_NORMAL + &Rotate Group - Incremental... + ID_ACT_ROTATEGROUP + none + + + + + + 0 + 1 + Rotate piece or marker using incremental amounts + wxID_ANY + wxITEM_NORMAL + Rotate Object - Incremental... + ID_ACT_ROTATEREL + none + + + + + + Rotate Object - Absolute + m_menu4 + protected + + + 0 + 1 + Set all selection piece rotations to zero. + wxID_ANY + wxITEM_NORMAL + Reset Rotation + ID_ACT_ROTATE_0 + none + + + + + m_separator11 + none + + + + Square Faces + m_menu5 + protected + + + 0 + 1 + Set all selection piece rotations to zero. + wxID_ANY + wxITEM_NORMAL + 0° + ID_ACT_ROTATE_0 + none + + + + + + 0 + 1 + + wxID_ANY + wxITEM_NORMAL + 90° + ID_ACT_ROTATE_90 + none + + + + + + 0 + 1 + + wxID_ANY + wxITEM_NORMAL + 180° + ID_ACT_ROTATE_180 + none + + + + + + 0 + 1 + + wxID_ANY + wxITEM_NORMAL + 270° + ID_ACT_ROTATE_270 + none + + + + + + + Hex Faces (Flat Up) + m_menu6 + protected + + + 0 + 1 + Set all selection piece rotations to zero. + wxID_ANY + wxITEM_NORMAL + 0° + ID_ACT_ROTATE_0 + none + + + + + + 0 + 1 + + wxID_ANY + wxITEM_NORMAL + 60° + ID_ACT_ROTATE_60 + none + + + + + + 0 + 1 + + wxID_ANY + wxITEM_NORMAL + 120° + ID_ACT_ROTATE_120 + none + + + + + + 0 + 1 + + wxID_ANY + wxITEM_NORMAL + 180° + ID_ACT_ROTATE_180 + none + + + + + + 0 + 1 + + wxID_ANY + wxITEM_NORMAL + 240° + ID_ACT_ROTATE_240 + none + + + + + + 0 + 1 + + wxID_ANY + wxITEM_NORMAL + 300° + ID_ACT_ROTATE_300 + none + + + + + + + Hex Faces (Point Up) + m_menu7 + protected + + + 0 + 1 + + wxID_ANY + wxITEM_NORMAL + 30° + ID_ACT_ROTATE_30 + none + + + + + + 0 + 1 + + wxID_ANY + wxITEM_NORMAL + 90° + ID_ACT_ROTATE_90 + none + + + + + + 0 + 1 + + wxID_ANY + wxITEM_NORMAL + 150° + ID_ACT_ROTATE_150 + none + + + + + + 0 + 1 + + wxID_ANY + wxITEM_NORMAL + 210° + ID_ACT_ROTATE_210 + none + + + + + + 0 + 1 + + wxID_ANY + wxITEM_NORMAL + 270° + ID_ACT_ROTATE_270 + none + + + + + + 0 + 1 + + wxID_ANY + wxITEM_NORMAL + 330° + ID_ACT_ROTATE_330 + none + + + + + + + Diamond Faces + m_menu8 + protected + + + 0 + 1 + + wxID_ANY + wxITEM_NORMAL + 45° + ID_ACT_ROTATE_45 + none + + + + + + 0 + 1 + + wxID_ANY + wxITEM_NORMAL + 135° + ID_ACT_ROTATE_135 + none + + + + + + 0 + 1 + + wxID_ANY + wxITEM_NORMAL + 225° + ID_ACT_ROTATE_225 + none + + + + + + 0 + 1 + + wxID_ANY + wxITEM_NORMAL + 315° + ID_ACT_ROTATE_315 + none + + + + + + + m_separator20 + none + + + + 0 + 1 + Take ownership of selected pieces. + wxID_ANY + wxITEM_NORMAL + Take Ownership + ID_ACT_TAKE_OWNERSHIP + none + + + + + + 0 + 1 + Release ownership of selected pieces + wxID_ANY + wxITEM_NORMAL + Release Ownership + ID_ACT_RELEASE_OWNERSHIP + none + + + + + + 0 + 1 + Explicitly set piece ownership. + wxID_ANY + wxITEM_NORMAL + Set Ownership... + ID_ACT_SET_OWNER + none + + + + + m_separator13 + none + + + + 0 + 1 + Lock or unlock pieces and markers from selection. + wxID_ANY + wxITEM_CHECK + Lock Objects + ID_ACT_LOCKOBJECT + none + + + + + + 0 + 1 + Temporarily suspend piece and marker locks + wxID_ANY + wxITEM_CHECK + Suspend Object Locks + ID_ACT_LOCK_SUSPEND + none + + + + + m_separator14 + none + + + + 0 + 1 + Roll Dice + wxID_ANY + wxITEM_NORMAL + Roll Dice... + ID_ACTIONS_ROLLDICE + none + + + + + + 0 + 1 + Enter message for opponent + wxID_ANY + wxITEM_NORMAL + Enter Message... + ID_ACT_DOMESSAGE + none + + + + + + 0 + 1 + Edit text associated with a piece or marker + wxID_ANY + wxITEM_NORMAL + Edit Object Text... + ID_EDIT_ELEMENT_TEXT + none + + + + + m_separator15 + none + + + + Compound Move + m_menu9 + protected + + + 0 + 1 + Begin compound move + wxID_ANY + wxITEM_NORMAL + Begin a Compound Move + ID_ACT_COMPOUNDMOVE_BEGIN + none + + + + + + 0 + 1 + End active compound move + wxID_ANY + wxITEM_NORMAL + Accept Compound Move + ID_ACT_COMPOUNDMOVE_END + none + + + + + + 0 + 1 + Discard current compound move + wxID_ANY + wxITEM_NORMAL + Discard Compound Move + ID_ACT_COMPOUNDMOVE_DISCARD + none + + + + + + + Plotted Move + m_menu11 + protected + + + 0 + 1 + Begin a plotted move. + wxID_ANY + wxITEM_CHECK + Begin a Plotted Move + ID_PTOOL_PLOTMOVE + none + + + + + + 0 + 1 + Record the plotted move + wxID_ANY + wxITEM_NORMAL + Accept Plotted Move + ID_ACT_PLOTDONE + none + + + + + + 0 + 1 + Discard the plotted move + wxID_ANY + wxITEM_NORMAL + Discard Plotted Move + ID_ACT_PLOTDISCARD + none + + + + + + m_separator16 + none + + + + 0 + 1 + Show full scale board + wxID_ANY + wxITEM_RADIO + Full Scale Board + ID_VIEW_FULLSCALEBRD + none + + + + + + 0 + 1 + Show half scale board + wxID_ANY + wxITEM_RADIO + Half Scale Board + ID_VIEW_HALFSCALEBRD + none + + + + + + 0 + 1 + Show small scale board + wxID_ANY + wxITEM_RADIO + Small Scale Board + ID_VIEW_SMALLSCALEBRD + none + + + + + m_separator17 + none + + + + 0 + 1 + Split board view horizontally into two rows. + wxID_ANY + wxITEM_NORMAL + Horizontal Split + ID_VIEW_SPLITBOARDROWS + none + + + + + + 0 + 1 + Split board view vertically into two columns. + wxID_ANY + wxITEM_NORMAL + Vertical Split + ID_VIEW_SPLITBOARDCOLS + none + + + + + m_separator18 + none + + + + 0 + 1 + Hide or show pieces on board + wxID_ANY + wxITEM_CHECK + Hide Pieces + ID_VIEW_PIECES + none + + + + + + 0 + 1 + View the board and trays as if the current player was a spectator. + wxID_ANY + wxITEM_NORMAL + Simulate Spectator Player + ID_ACT_SIMULATE_SPECTATOR + none + + + 1=PV_PLAYMODE MENU_PV_PLAYMODE protected + + + 0 + 1 + Jump to start of moves + wxID_ANY + wxITEM_NORMAL + Start of Moves + ID_PBCK_START + none + + + + + + 0 + 1 + Do the next move + wxID_ANY + wxITEM_NORMAL + Next Move + ID_PBCK_NEXT + none + + + + + + 0 + 1 + Step back to previous move + wxID_ANY + wxITEM_NORMAL + Previous Move + ID_PBCK_PREVIOUS + none + + + + + + 0 + 1 + Jump to end of move + wxID_ANY + wxITEM_NORMAL + End of Moves + ID_PBCK_END + none + + + + + m_separator29 + none + + + + 0 + 1 + Toggles automatic playback feature. + wxID_ANY + wxITEM_NORMAL + Automatic Playback + ID_PBCK_AUTO_STEP + none + + + + + m_separator30 + none + + + + 0 + 1 + If checked, compound moves are single stepped. + wxID_ANY + wxITEM_NORMAL + Single Step Compound Moves + ID_PBCK_STEP_CMOVES + none + + + + + + 0 + 1 + Next move automatically steps to next history entry on last move. + wxID_ANY + wxITEM_NORMAL + Automatically Step to Next History + ID_PBCK_STEP_TO_NEXT_HIST + none + + + + + + 0 + 1 + Keep graphical move indications when skipping moves. + wxID_ANY + wxITEM_NORMAL + Keep Skipped Move Indications + ID_PBCK_SKIP_KEEP_IND + none + + + + + m_separator31 + none + + + + 0 + 1 + Display current message text + wxID_ANY + wxITEM_NORMAL + Show Current Message... + ID_PBCK_READMESSAGE + none + + + + + m_separator32 + none + + + + 0 + 1 + Close current history playback and open the next + wxID_ANY + wxITEM_NORMAL + Next History Entry + ID_PBCK_NEXTHIST + none + + + + + + 0 + 1 + Close history playback mode. + wxID_ANY + wxITEM_NORMAL + Close History Playback + ID_PBCK_CLOSEHIST + none + + + + + m_separator33 + none + + + + 0 + 1 + Show full scale board + wxID_ANY + wxITEM_RADIO + Full Scale Board + ID_VIEW_FULLSCALEBRD + none + + + + + + 0 + 1 + Show half scale board + wxID_ANY + wxITEM_RADIO + Half Scale Board + ID_VIEW_HALFSCALEBRD + none + + + + + + 0 + 1 + Show small scale board + wxID_ANY + wxITEM_RADIO + Small Scale Board + ID_VIEW_SMALLSCALEBRD + none + + + + + m_separator34 + none + + + + 0 + 1 + Split board view horizontally into two rows. + wxID_ANY + wxITEM_NORMAL + Horizontal Split + ID_VIEW_SPLITBOARDROWS + none + + + + + + 0 + 1 + Split board view vertically into two columns. + wxID_ANY + wxITEM_NORMAL + Vertical Split + ID_VIEW_SPLITBOARDCOLS + none + + + + + m_separator35 + none + + + + 0 + 1 + Hide or show pieces on board + wxID_ANY + wxITEM_NORMAL + Hide Pieces + ID_VIEW_PIECES + none + + + + + + 0 + 1 + Draw movement playback indicators on top of pieces. + wxID_ANY + wxITEM_NORMAL + Indicators On Top + ID_VIEW_DRAW_IND_ON_TOP + none + + + + + + 0 + 1 + View the board and trays as if the current player was a spectator. + wxID_ANY + wxITEM_NORMAL + Simulate Spectator Player + ID_ACT_SIMULATE_SPECTATOR + none + + + + + m_separator36 + none + + + + 0 + 1 + Finishes and accepts the move file being played back. Adds to game history. + wxID_ANY + wxITEM_NORMAL + Accept Move File Playback... + ID_PBCK_FINISH + none + + + + + + 0 + 1 + Discard the current move recording. + wxID_ANY + wxITEM_NORMAL + Discard Move File Playback... + ID_PBCK_DISCARD + none + + + 2=PV_SCNMODE MENU_PV_SCNMODE protected + + + 0 + 1 + Erase the selection + wxID_ANY + wxITEM_NORMAL + Delete Marker + wxID_CLEAR + none + + + + + + 0 + 1 + Select all markers in the current board view + wxID_ANY + wxITEM_NORMAL + Select All Markers + ID_EDIT_SELALLMARKERS + none + + + + + m_separator37 + none + + + + 0 + 1 + Automatically stack selected pieces. + wxID_ANY + wxITEM_NORMAL + Auto Stack + ID_ACT_STACK + none + + + + + + 0 + 1 + Autostack selected objects using a offset of zero. + wxID_ANY + wxITEM_NORMAL + Auto Stack Deck + ID_ACT_AUTOSTACK_DECK + none + + + + + + 0 + 1 + Randomize the stacking order of the selected objects + wxID_ANY + wxITEM_NORMAL + Shuffle Objects + ID_ACT_SHUFFLE_SELECTED + none + + + + + m_separator38 + none + + + + 0 + 1 + Move selected piece(s) in front of other pieces + wxID_ANY + wxITEM_NORMAL + Move To Front + ID_ACT_TOFRONT + none + + + + + + 0 + 1 + Move selected piece(s) in front of other pieces + wxID_ANY + wxITEM_NORMAL + Move To Back + ID_ACT_TOBACK + none + + + + + + 0 + 1 + Turn the selected piece over to the next side + wxID_ANY + wxITEM_NORMAL + Turn Piece Over + ID_ACT_TURNOVER + none + + + + + m_separator39 + none + + + + 0 + 1 + Rotate (or wheel) group of pieces or markers by incremental amounts + wxID_ANY + wxITEM_NORMAL + &Rotate Group - Incremental... + ID_ACT_ROTATEGROUP + none + + + + + + 0 + 1 + Rotate piece or marker using incremental amounts + wxID_ANY + wxITEM_NORMAL + Rotate Object - Incremental... + ID_ACT_ROTATEREL + none + + + + + + Rotate Object - Absolute + m_menu41 + protected + + + 0 + 1 + Set all selection piece rotations to zero. + wxID_ANY + wxITEM_NORMAL + Reset Rotation + ID_ACT_ROTATE_0 + none + + + + + m_separator111 + none + + + + Square Faces + m_menu51 + protected + + + 0 + 1 + + wxID_ANY + wxITEM_NORMAL + 0° + ID_ACT_ROTATE_0 + none + + + + + + 0 + 1 + + wxID_ANY + wxITEM_NORMAL + 90° + ID_ACT_ROTATE_90 + none + + + + + + 0 + 1 + + wxID_ANY + wxITEM_NORMAL + 180° + ID_ACT_ROTATE_180 + none + + + + + + 0 + 1 + + wxID_ANY + wxITEM_NORMAL + 270° + ID_ACT_ROTATE_270 + none + + + + + + + Hex Faces (Flat Up) + m_menu61 + protected + + + 0 + 1 + Set all selection piece rotations to zero. + wxID_ANY + wxITEM_NORMAL + 0° + ID_ACT_ROTATE_0 + none + + + + + + 0 + 1 + + wxID_ANY + wxITEM_NORMAL + 60° + ID_ACT_ROTATE_60 + none + + + + + + 0 + 1 + + wxID_ANY + wxITEM_NORMAL + 120° + ID_ACT_ROTATE_120 + none + + + + + + 0 + 1 + + wxID_ANY + wxITEM_NORMAL + 180° + ID_ACT_ROTATE_180 + none + + + + + + 0 + 1 + + wxID_ANY + wxITEM_NORMAL + 240° + ID_ACT_ROTATE_240 + none + + + + + + 0 + 1 + + wxID_ANY + wxITEM_NORMAL + 300° + ID_ACT_ROTATE_300 + none + + + + + + + Hex Faces (Point Up) + m_menu71 + protected + + + 0 + 1 + + wxID_ANY + wxITEM_NORMAL + 30° + ID_ACT_ROTATE_30 + none + + + + + + 0 + 1 + + wxID_ANY + wxITEM_NORMAL + 90° + ID_ACT_ROTATE_90 + none + + + + + + 0 + 1 + + wxID_ANY + wxITEM_NORMAL + 150° + ID_ACT_ROTATE_150 + none + + + + + + 0 + 1 + + wxID_ANY + wxITEM_NORMAL + 210° + ID_ACT_ROTATE_210 + none + + + + + + 0 + 1 + + wxID_ANY + wxITEM_NORMAL + 270° + ID_ACT_ROTATE_270 + none + + + + + + 0 + 1 + + wxID_ANY + wxITEM_NORMAL + 330° + ID_ACT_ROTATE_330 + none + + + + + + + Diamond Faces + m_menu81 + protected + + + 0 + 1 + + wxID_ANY + wxITEM_NORMAL + 45° + ID_ACT_ROTATE_45 + none + + + + + + 0 + 1 + + wxID_ANY + wxITEM_NORMAL + 135° + ID_ACT_ROTATE_135 + none + + + + + + 0 + 1 + + wxID_ANY + wxITEM_NORMAL + 225° + ID_ACT_ROTATE_225 + none + + + + + + 0 + 1 + + wxID_ANY + wxITEM_NORMAL + 315° + ID_ACT_ROTATE_315 + none + + + + + + + m_separator42 + none + + + + 0 + 1 + Lock or unlock pieces and markers from selection. + wxID_ANY + wxITEM_CHECK + Lock Objects + ID_ACT_LOCKOBJECT + none + + + + + + 0 + 1 + Temporarily suspend piece and marker locks + wxID_ANY + wxITEM_CHECK + Suspend Object Locks + ID_ACT_LOCK_SUSPEND + none + + + + + m_separator43 + none + + + + 0 + 1 + Edit text associated with a piece or marker + wxID_ANY + wxITEM_NORMAL + Edit Object Text... + ID_EDIT_ELEMENT_TEXT + none + + + + + m_separator44 + none + + + + 0 + 1 + Show full scale board + wxID_ANY + wxITEM_RADIO + Full Scale Board + ID_VIEW_FULLSCALEBRD + none + + + + + + 0 + 1 + Show half scale board + wxID_ANY + wxITEM_RADIO + Half Scale Board + ID_VIEW_HALFSCALEBRD + none + + + + + + 0 + 1 + Show small scale board + wxID_ANY + wxITEM_RADIO + Small Scale Board + ID_VIEW_SMALLSCALEBRD + none + + + + + m_separator45 + none + + + + 0 + 1 + Split board view horizontally into two rows. + wxID_ANY + wxITEM_NORMAL + Horizontal Split + ID_VIEW_SPLITBOARDROWS + none + + + + + + 0 + 1 + Split board view vertically into two columns. + wxID_ANY + wxITEM_NORMAL + Vertical Split + ID_VIEW_SPLITBOARDCOLS + none + + + + + m_separator47 + none + + + + 0 + 1 + Hide or show pieces on board + wxID_ANY + wxITEM_CHECK + Hide Pieces + ID_VIEW_PIECES + none + + + + + + 0 + 1 + Enable or disable current board's snap grid + wxID_ANY + wxITEM_NORMAL + Snap Grid + ID_VIEW_SNAPGRID + none + + + 3=PJ_GSN_DEFAULT diff --git a/GP/CBPlay.xrc b/GP/CBPlay.xrc index 3e0e8724..16866e0b 100644 --- a/GP/CBPlay.xrc +++ b/GP/CBPlay.xrc @@ -2960,12 +2960,670 @@ + + + + Erase the selection + + + + + Select all markers in the current board view + + + + + + + + + + + + + + Automatically stack selected pieces. + + + + + Autostack selected objects using a offset of zero. + + + + + Randomize the stacking order of the selected objects + + + + + + Move selected piece(s) in front of other pieces + + + + + Move selected pieces(s) behind other pieces + + + + + Turn the selected piece over to the next side + + + + + + Rotate (or wheel) group of pieces or markers by incremental amounts + + + + + Rotate piece or marker using incremental amounts + + + + + + + Set all selection piece rotations to zero. + + + + + + + + Set all selection piece rotations to zero. + + + + + + + + + + + + + + + + + + + + + + + Set all selection piece rotations to zero. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Take ownership of selected pieces. + + + + + Release ownership of selected pieces + + + + + Explicitly set piece ownership. + + + + + + Lock or unlock pieces and markers from selection. + 1 + + + + + Temporarily suspend piece and marker locks + 1 + + + + + + Roll Dice + + + + + Enter message for opponent + + + + + Edit text associated with a piece or marker + + + + + + + + Begin compound move + + + + + End active compound move + + + + + Discard current compound move + + + + + + + + Begin a plotted move. + 1 + + + + + Record the plotted move + + + + + Discard the plotted move + + + + + + + Show full scale board + 1 + + + + + Show half scale board + 1 + + + + + Show small scale board + 1 + + + + + + Split board view horizontally into two rows. + + + + + Split board view vertically into two columns. + + + + + + Hide or show pieces on board + 1 + + + + + View the board and trays as if the current player was a spectator. + + + + + Jump to start of moves + + + + + Do the next move + + + + + Step back to previous move + + + + + Jump to end of move + + + + + + Toggles automatic playback feature. + + + + + + If checked, compound moves are single stepped. + + + + + Next move automatically steps to next history entry on last move. + + + + + Keep graphical move indications when skipping moves. + + + + + + Display current message text + + + + + + Close current history playback and open the next + + + + + Close history playback mode. + + + + + + Show full scale board + 1 + + + + + Show half scale board + 1 + + + + + Show small scale board + 1 + + + + + + Split board view horizontally into two rows. + + + + + Split board view vertically into two columns. + + + + + + Hide or show pieces on board + + + + + Draw movement playback indicators on top of pieces. + + + + + View the board and trays as if the current player was a spectator. + + + + + + Finishes and accepts the move file being played back. Adds to game history. + + + + + Discard the current move recording. + + + + + Erase the selection + + + + + Select all markers in the current board view + + + + + + Automatically stack selected pieces. + + + + + Autostack selected objects using a offset of zero. + + + + + Randomize the stacking order of the selected objects + + + + + + Move selected piece(s) in front of other pieces + + + + + Move selected piece(s) in front of other pieces + + + + + Turn the selected piece over to the next side + + + + + + Rotate (or wheel) group of pieces or markers by incremental amounts + + + + + Rotate piece or marker using incremental amounts + + + + + + + Set all selection piece rotations to zero. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Set all selection piece rotations to zero. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Lock or unlock pieces and markers from selection. + 1 + + + + + Temporarily suspend piece and marker locks + 1 + + + + + + Edit text associated with a piece or marker + + + + + + Show full scale board + 1 + + + + + Show half scale board + 1 + + + + + Show small scale board + 1 + + + + + + Split board view horizontally into two rows. + + + + + Split board view vertically into two columns. + + + + + + Hide or show pieces on board + 1 + + + + + Enable or disable current board's snap grid + diff --git a/GP/VwPbrd.cpp b/GP/VwPbrd.cpp index 05f667b8..d009d62e 100644 --- a/GP/VwPbrd.cpp +++ b/GP/VwPbrd.cpp @@ -119,9 +119,7 @@ wxBEGIN_EVENT_TABLE(CPlayBoardView, CPlayBoardView::BASE) EVT_UPDATE_UI(XRCID("ID_ACT_ROTATEREL"), OnUpdateActRotateRelative) EVT_MENU(wxID_CLEAR, OnEditClear) EVT_UPDATE_UI(wxID_CLEAR, OnUpdateEditClear) -#if 0 - ON_WM_CONTEXTMENU() -#endif + EVT_CONTEXT_MENU(OnContextMenu) EVT_MENU(XRCID("ID_VIEW_DRAW_IND_ON_TOP"), OnViewDrawIndOnTop) EVT_UPDATE_UI(XRCID("ID_VIEW_DRAW_IND_ON_TOP"), OnUpdateViewDrawIndOnTop) EVT_MENU(XRCID("ID_EDIT_ELEMENT_TEXT"), OnEditElementText) @@ -1142,41 +1140,40 @@ CFrameWnd* CPlayBoardView::GetParentFrame() return parent->GetParentFrame(); } -#if 0 ///////////////////////////////////////////////////////////////////////////// // Right mouse button handler -void CPlayBoardView::OnContextMenu(CWnd* pWnd, CPoint point) +void CPlayBoardView::OnContextMenu(wxContextMenuEvent& event) { // Make sure window is active. GetParentFrame()->ActivateFrame(); - CMenu bar; - if (bar.LoadMenuW(IDR_MENU_PLAYER_POPUPS)) + std::unique_ptr bar(wxXmlResource::Get()->LoadMenuBar("IDR_MENU_PLAYER_POPUPS")); + if (bar) { - UINT nMenuNum; + CB::string nMenuNum; if (GetDocument().IsPlaying()) - nMenuNum = MENU_PV_PLAYMODE; + nMenuNum = "1=PV_PLAYMODE"; else if (GetDocument().IsScenario()) - nMenuNum = MENU_PV_SCNMODE; + nMenuNum = "2=PV_SCNMODE"; else - nMenuNum = MENU_PV_MOVEMODE; + nMenuNum = "0=PV_MOVEMODE"; - CMenu& popup = *bar.GetSubMenu(nMenuNum); - ASSERT(popup.m_hMenu != NULL); + int index = bar->FindMenu(nMenuNum); + wxASSERT(index != wxNOT_FOUND); + std::unique_ptr popup(bar->Remove(value_preserving_cast(index))); // Make sure we clean up even if exception is tossed. - TRY + try { - popup.TrackPopupMenu(TPM_RIGHTBUTTON, point.x, point.y, - AfxGetMainWnd()); // Route commands through main window - // Make sure command is dispatched BEFORE we clear m_bInRightMouse. - GetApp()->DispatchMessages(); + PopupMenu(&*popup, ScreenToClient(event.GetPosition())); + } + catch (...) + { + wxASSERT(!"exception"); } - END_TRY } } -#endif ///////////////////////////////////////////////////////////////////////////// // Handlers associated with tools. diff --git a/GP/VwPbrd.h b/GP/VwPbrd.h index b1d376e7..7a746b9b 100644 --- a/GP/VwPbrd.h +++ b/GP/VwPbrd.h @@ -282,9 +282,7 @@ class CPlayBoardView : public CB::ProcessEventOverride void OnEditClear(); void OnEditClear(wxCommandEvent& /*event*/) { OnEditClear(); } void OnUpdateEditClear(wxUpdateUIEvent& pCmdUI); -#if 0 - afx_msg void OnContextMenu(CWnd* pWnd, CPoint point); -#endif + void OnContextMenu(wxContextMenuEvent& event); void OnViewDrawIndOnTop(wxCommandEvent& event); void OnUpdateViewDrawIndOnTop(wxUpdateUIEvent& pCmdUI); void OnEditElementText(wxCommandEvent& event); From 2ee007b79fb9ac71d9b40477e9d7d7e9177eedc5 Mon Sep 17 00:00:00 2001 From: Bill Su Date: Sat, 13 Dec 2025 01:35:08 -0500 Subject: [PATCH 51/80] VwPbrd: handle object rotation menu options TODO: can't handle selecting marker groups until wx controls the menus --- GP/VwPbrd.cpp | 64 ++++++++++++++++++++++++++++++++++++++++++------- GP/VwPbrd.h | 4 ++-- GShr/LibMfc.cpp | 32 +++++++++++++++++++++++++ 3 files changed, 90 insertions(+), 10 deletions(-) diff --git a/GP/VwPbrd.cpp b/GP/VwPbrd.cpp index d009d62e..706aad27 100644 --- a/GP/VwPbrd.cpp +++ b/GP/VwPbrd.cpp @@ -151,9 +151,12 @@ wxBEGIN_EVENT_TABLE(CPlayBoardView, CPlayBoardView::BASE) EVT_UPDATE_UI(XRCID("ID_VIEW_BOARD_ROTATE180"), OnUpdateViewBoardRotate180) EVT_MENU(XRCID("ID_ACT_ROTATEGROUP"), OnActRotateGroupRelative) EVT_UPDATE_UI(XRCID("ID_ACT_ROTATEGROUP"), OnUpdateActRotateGroupRelative) + /* ID_ACT_ROTATE_0: can't use wx event tables with range + because XRCID doesn't allow controlling values, so use + wxEvtHandler::Bind */ #if 0 - ON_COMMAND_RANGE(ID_ACT_ROTATE_0, (ID_ACT_ROTATE_0 + 360 / 5), OnRotatePiece) - ON_UPDATE_COMMAND_UI_RANGE(ID_ACT_ROTATE_0, (ID_ACT_ROTATE_0 + 360 / 5), OnUpdateRotatePiece) + /* ID_MRKGROUP_FIRST involves modifying the menu item count, + but the menus aren't ported to wx yet */ ON_COMMAND_RANGE(ID_MRKGROUP_FIRST, ID_MRKGROUP_FIRST + 64, OnSelectGroupMarkers) ON_UPDATE_COMMAND_UI_RANGE(ID_MRKGROUP_FIRST, ID_MRKGROUP_FIRST + 64, OnUpdateSelectGroupMarkers) #endif @@ -163,6 +166,42 @@ wxBEGIN_EVENT_TABLE(CPlayBoardView, CPlayBoardView::BASE) EVT_SCROLLWIN_LINEUP(OnScrollWinLine) wxEND_EVENT_TABLE() +// helper for wxEvtHandler::Bind for ID_ACT_ROTATE_0 +namespace { + // avoid trying to use XRC before wxApp initialized + const std::map& GetRotateMap() + { + static const std::map retval = []{ + std::map retval; + for (int degrees : { + 0, + 30, + 45, + 60, + 90, + 120, + 135, + 150, + 180, + 210, + 225, + 240, + 270, + 300, + 315, + 330, + }) + { + wxString name = wxString::Format("ID_ACT_ROTATE_%d", degrees); + retval[XRCID(name)] = degrees; + } + return retval; + }(); + return retval; + } +} + + BEGIN_MESSAGE_MAP(CPlayBoardViewContainer, CPlayBoardViewContainer::BASE) ON_WM_CREATE() ON_WM_SETFOCUS() @@ -182,6 +221,13 @@ CPlayBoardView::CPlayBoardView(CPlayBoardViewContainer& p) : EnableAutoScrollInside(scrollZone); DisableAutoScrollOutside(); + // use wxEvtHandler::Bind for ID_ACT_ROTATE_0 + for (auto pair : GetRotateMap()) + { + Bind(wxEVT_MENU, &CPlayBoardView::OnRotatePiece, this, pair.first); + Bind(wxEVT_UPDATE_UI, &CPlayBoardView::OnUpdateRotatePiece, this, pair.first); + } + m_nZoom = fullScale; m_nCurToolID = XRCID("ID_PTOOL_SELECT"); m_bInDrag = FALSE; @@ -1964,6 +2010,7 @@ void CPlayBoardView::OnUpdateActRotate(CCmdUI* pCmdUI) // ** TEST CODE ** // else pCmdUI->Enable(m_selList.HasPieces()); } +#endif /////////////////////////////////////////////////////////////////////// // Handle rotation requests. The ID's for tile rotations @@ -1971,9 +2018,9 @@ void CPlayBoardView::OnUpdateActRotate(CCmdUI* pCmdUI) // ** TEST CODE ** // // five degree increments. For example: if ID_ACT_ROTATE_0 is 42000, then // ID_ACT_ROTATE_90 must be 42009. This makes the angle easy to compute. -void CPlayBoardView::OnRotatePiece(UINT nID) +void CPlayBoardView::OnRotatePiece(wxCommandEvent& event) { - uint16_t nFacing5DegCW = value_preserving_cast(nID - ID_ACT_ROTATE_0); + int nFacingDegCW = GetRotateMap().at(event.GetId()); std::vector> listObjs; m_selList.LoadTableWithObjectPtrs(listObjs, CSelList::otAll, FALSE); @@ -1981,12 +2028,12 @@ void CPlayBoardView::OnRotatePiece(UINT nID) GetDocument().AssignNewMoveGroup(); GetDocument().ChangePlayingPieceFacingTableOnBoard(listObjs, m_pPBoard.get(), - uint16_t(5) * nFacing5DegCW); // Convert to degrees + value_preserving_cast(nFacingDegCW)); SelectAllObjectsInTable(listObjs); // Reselect pieces } -void CPlayBoardView::OnUpdateRotatePiece(CCmdUI* pCmdUI, UINT nID) +void CPlayBoardView::OnUpdateRotatePiece(wxUpdateUIEvent& pCmdUI) { CGamDoc& pDoc = GetDocument(); BOOL bEnabled = (m_selList.HasPieces() || m_selList.HasMarkers()) && !pDoc.IsPlaying(); @@ -1996,15 +2043,16 @@ void CPlayBoardView::OnUpdateRotatePiece(CCmdUI* pCmdUI, UINT nID) bEnabled = FALSE; } +#if 0 if (pCmdUI->m_pSubMenu != NULL) { // Need to handle menu that the submenu is connected to. pCmdUI->m_pMenu->EnableMenuItem(pCmdUI->m_nIndex, MF_BYPOSITION | (bEnabled ? MF_ENABLED : (MF_DISABLED | MF_GRAYED))); } - pCmdUI->Enable(bEnabled); -} #endif + pCmdUI.Enable(bEnabled); +} /////////////////////////////////////////////////////////////////////// // This method handles messages typically sent by the tiny map view. diff --git a/GP/VwPbrd.h b/GP/VwPbrd.h index 7a746b9b..a85a5e94 100644 --- a/GP/VwPbrd.h +++ b/GP/VwPbrd.h @@ -309,9 +309,9 @@ class CPlayBoardView : public CB::ProcessEventOverride afx_msg BOOL OnMouseWheel(UINT nFlags, short zDelta, CPoint pt); afx_msg void OnSelectGroupMarkers(UINT nID); afx_msg void OnUpdateSelectGroupMarkers(CCmdUI* pCmdUI, UINT nID); - afx_msg void OnRotatePiece(UINT nID); - afx_msg void OnUpdateRotatePiece(CCmdUI* pCmdUI, UINT nID); #endif + void OnRotatePiece(wxCommandEvent& event); + void OnUpdateRotatePiece(wxUpdateUIEvent& pCmdUI); void OnMessageWindowState(WinStateEvent& event); void OnMessageSelectBoardObjectList(SelectBoardObjListEvent& event); void OnScrollWinLine(wxScrollWinEvent& event); diff --git a/GShr/LibMfc.cpp b/GShr/LibMfc.cpp index 7513f6f1..66a4fef7 100644 --- a/GShr/LibMfc.cpp +++ b/GShr/LibMfc.cpp @@ -1330,6 +1330,38 @@ namespace CB return XRCID("ID_ACT_PLOTDONE"); case ID_ACT_RELEASE_OWNERSHIP: return XRCID("ID_ACT_RELEASE_OWNERSHIP"); + case ID_ACT_ROTATE_0: + return XRCID("ID_ACT_ROTATE_0"); + case ID_ACT_ROTATE_30: + return XRCID("ID_ACT_ROTATE_30"); + case ID_ACT_ROTATE_45: + return XRCID("ID_ACT_ROTATE_45"); + case ID_ACT_ROTATE_60: + return XRCID("ID_ACT_ROTATE_60"); + case ID_ACT_ROTATE_90: + return XRCID("ID_ACT_ROTATE_90"); + case ID_ACT_ROTATE_120: + return XRCID("ID_ACT_ROTATE_120"); + case ID_ACT_ROTATE_135: + return XRCID("ID_ACT_ROTATE_135"); + case ID_ACT_ROTATE_150: + return XRCID("ID_ACT_ROTATE_150"); + case ID_ACT_ROTATE_180: + return XRCID("ID_ACT_ROTATE_180"); + case ID_ACT_ROTATE_210: + return XRCID("ID_ACT_ROTATE_210"); + case ID_ACT_ROTATE_225: + return XRCID("ID_ACT_ROTATE_225"); + case ID_ACT_ROTATE_240: + return XRCID("ID_ACT_ROTATE_240"); + case ID_ACT_ROTATE_270: + return XRCID("ID_ACT_ROTATE_270"); + case ID_ACT_ROTATE_300: + return XRCID("ID_ACT_ROTATE_300"); + case ID_ACT_ROTATE_315: + return XRCID("ID_ACT_ROTATE_315"); + case ID_ACT_ROTATE_330: + return XRCID("ID_ACT_ROTATE_330"); case ID_ACT_ROTATEGROUP: return XRCID("ID_ACT_ROTATEGROUP"); case ID_ACT_ROTATEREL: From 307b70bbfd7c33755e66f4e9df83be91f78837e2 Mon Sep 17 00:00:00 2001 From: Bill Su Date: Tue, 24 Feb 2026 21:47:14 -0500 Subject: [PATCH 52/80] VwPbrd: convert MFC ID_MRKGROUP_FIRST to wx --- GP/CBPlay.fbp | 2 +- GP/CBPlay.xrc | 2 +- GP/VwPbrd.cpp | 89 ++++++++++++++++++++++++++++++++++++++------------- GP/VwPbrd.h | 6 ++-- 4 files changed, 72 insertions(+), 27 deletions(-) diff --git a/GP/CBPlay.fbp b/GP/CBPlay.fbp index d7c53048..8012cb15 100644 --- a/GP/CBPlay.fbp +++ b/GP/CBPlay.fbp @@ -15668,7 +15668,7 @@ wxID_ANY wxITEM_NORMAL No Markers - ID_MRKGROUP_FIRST + ID_MRKGROUP_FIRST_0 none diff --git a/GP/CBPlay.xrc b/GP/CBPlay.xrc index 16866e0b..a385bf4a 100644 --- a/GP/CBPlay.xrc +++ b/GP/CBPlay.xrc @@ -2972,7 +2972,7 @@ - + diff --git a/GP/VwPbrd.cpp b/GP/VwPbrd.cpp index 706aad27..5d2a98af 100644 --- a/GP/VwPbrd.cpp +++ b/GP/VwPbrd.cpp @@ -159,6 +159,13 @@ wxBEGIN_EVENT_TABLE(CPlayBoardView, CPlayBoardView::BASE) but the menus aren't ported to wx yet */ ON_COMMAND_RANGE(ID_MRKGROUP_FIRST, ID_MRKGROUP_FIRST + 64, OnSelectGroupMarkers) ON_UPDATE_COMMAND_UI_RANGE(ID_MRKGROUP_FIRST, ID_MRKGROUP_FIRST + 64, OnUpdateSelectGroupMarkers) +#else + /* ID_MRKGROUP_FIRST_0: can't use wx event tables with range + because XRCID doesn't allow controlling values, so use + wxEvtHandler::Bind */ + /* wxUpdateEventUI doesn't support modifying menu, + so use EVT_MENU_OPEN */ + EVT_MENU_OPEN(OnMenuOpen) #endif EVT_WINSTATE(OnMessageWindowState) EVT_SELECT_BOARD_OBJLIST(OnMessageSelectBoardObjectList) @@ -201,6 +208,29 @@ namespace { } } +// helpers for wxEvtHandler::Bind for ID_MRKGROUP_FIRST_0 +namespace { + std::map ids; + std::map indices; + int MarkerIndexToXrcid(int index) + { + auto it = ids.lower_bound(index); + if (it != ids.end() && it->first == index) + { + return it->second; + } + wxString name = wxString::Format("ID_MRKGROUP_FIRST_%d", index); + int id = XRCID(name); + ids.insert(it, std::make_pair(index, id)); + indices.insert(std::make_pair(id, index)); + return id; + } + int MarkerXrcidToIndex(int id) + { + return indices.at(id); + } +} + BEGIN_MESSAGE_MAP(CPlayBoardViewContainer, CPlayBoardViewContainer::BASE) ON_WM_CREATE() @@ -2369,40 +2399,53 @@ void CPlayBoardView::OnEditBoardProperties(wxCommandEvent& /*event*/) GetDocument().DoBoardProperties(GetPlayBoard()); } -#if 0 -void CPlayBoardView::OnSelectGroupMarkers(UINT nID) +void CPlayBoardView::OnSelectGroupMarkers(wxCommandEvent& event) { - SelectMarkersInGroup(nID - ID_MRKGROUP_FIRST); + SelectMarkersInGroup(value_preserving_cast(MarkerXrcidToIndex(event.GetId()))); } -void CPlayBoardView::OnUpdateSelectGroupMarkers(CCmdUI* pCmdUI, UINT nID) +void CPlayBoardView::OnMenuOpen(wxMenuEvent& event) { - if (pCmdUI->m_pSubMenu != NULL) + if (event.GetMenu()) { - CMarkManager& pMgr = GetDocument().GetMarkManager(); - if (pMgr.IsEmpty()) - return; - std::vector tbl; - tbl.reserve(pMgr.GetNumMarkSets()); - for (size_t i = size_t(0) ; i < pMgr.GetNumMarkSets() ; ++i) + wxMenu* menu; + wxMenuItem* markers = event.GetMenu()->FindItem(XRCID("ID_MRKGROUP_FIRST_0"), &menu); + if (markers) { - tbl.push_back(pMgr.GetMarkSet(i).GetName()); + OnUpdateSelectGroupMarkers(CheckedDeref(menu)); + return; } - CMenu menu; - VERIFY(menu.CreatePopupMenu()); + } + event.Skip(); +} - CreateSequentialSubMenuIDs(menu, ID_MRKGROUP_FIRST, tbl); +void CPlayBoardView::OnUpdateSelectGroupMarkers(wxMenu& menu) +{ + CMarkManager& pMgr = GetDocument().GetMarkManager(); + if (pMgr.IsEmpty()) + return; + std::vector tbl; + tbl.reserve(pMgr.GetNumMarkSets()); + for (size_t i = size_t(0) ; i < pMgr.GetNumMarkSets() ; ++i) + { + tbl.push_back(pMgr.GetMarkSet(i).GetName()); + } + wxASSERT(menu.GetMenuItemCount() == 1); + menu.Delete(XRCID("ID_MRKGROUP_FIRST_0")); + wxASSERT(menu.GetMenuItemCount() == 0); - CB::string str = CB::string::GetMenuString(*pCmdUI->m_pMenu, pCmdUI->m_nIndex, - MF_BYPOSITION); - VERIFY(pCmdUI->m_pMenu->ModifyMenu(pCmdUI->m_nIndex, - MF_BYPOSITION | MF_ENABLED | MF_POPUP | MF_STRING, - reinterpret_cast(menu.Detach()), str)); + for (size_t i = size_t(0) ; i < tbl.size() ; ++i) + { + int intI = value_preserving_cast(i); + int xrcid = MarkerIndexToXrcid(intI); + menu.Append(xrcid, tbl[i]); + if (intI >= m_bindEnd) + { + Bind(wxEVT_MENU, &CPlayBoardView::OnSelectGroupMarkers, this, xrcid); + ++m_bindEnd; + } } - else - pCmdUI->Enable(); } -#endif void CPlayBoardView::OnViewDrawIndOnTop(wxCommandEvent& /*event*/) { diff --git a/GP/VwPbrd.h b/GP/VwPbrd.h index a85a5e94..06a3a5eb 100644 --- a/GP/VwPbrd.h +++ b/GP/VwPbrd.h @@ -307,9 +307,10 @@ class CPlayBoardView : public CB::ProcessEventOverride void OnUpdateViewBoardRotate180(wxUpdateUIEvent& pCmdUI); #if 0 afx_msg BOOL OnMouseWheel(UINT nFlags, short zDelta, CPoint pt); - afx_msg void OnSelectGroupMarkers(UINT nID); - afx_msg void OnUpdateSelectGroupMarkers(CCmdUI* pCmdUI, UINT nID); #endif + void OnSelectGroupMarkers(wxCommandEvent& event); + void OnMenuOpen(wxMenuEvent& event); + void OnUpdateSelectGroupMarkers(wxMenu& menu); void OnRotatePiece(wxCommandEvent& event); void OnUpdateRotatePiece(wxUpdateUIEvent& pCmdUI); void OnMessageWindowState(WinStateEvent& event); @@ -333,6 +334,7 @@ class CPlayBoardView : public CB::ProcessEventOverride int m_yScrollPixelsPerLine; OwnerPtr overlay = MakeOwner(); + int m_bindEnd = 0; }; #ifndef _DEBUG // debug version in vwmbrd.cpp From 14ae10b129273f4a7a365170d509c649b5213d06 Mon Sep 17 00:00:00 2001 From: Bill Su Date: Sat, 17 Jan 2026 16:03:41 -0500 Subject: [PATCH 53/80] VwPbrd: implement tooltips --- GP/GamDoc4.cpp | 2 +- GP/GamDoc5.cpp | 2 +- GP/VwPbrd.cpp | 4 +++- GP/VwPbrd.h | 12 +++++------ GP/VwPbrd1.cpp | 31 +++++++++++++++++---------- GShr/CyberBoard.h | 8 +++---- GShr/LibMfc.cpp | 54 +++++++++++++++++++++++++++++++++++++++++++---- 7 files changed, 85 insertions(+), 28 deletions(-) diff --git a/GP/GamDoc4.cpp b/GP/GamDoc4.cpp index 65c1d0d8..d444b0dd 100644 --- a/GP/GamDoc4.cpp +++ b/GP/GamDoc4.cpp @@ -671,7 +671,7 @@ void CGamDoc::IndicateTextTipOnBoard(const CPlayBoard& pPBoard, CPlayBoardView* pView = FindPBoardView(pPBoard); ASSERT(pView != NULL); pointWorkspace = pView->WorkspaceToClient(pointWorkspace); - pView->SetNotificationTip(pointWorkspace, &pszStr); + pView->SetNotificationTip(pointWorkspace, pszStr); } void CGamDoc::FlushAllSelections() diff --git a/GP/GamDoc5.cpp b/GP/GamDoc5.cpp index b3754501..c89b0b69 100644 --- a/GP/GamDoc5.cpp +++ b/GP/GamDoc5.cpp @@ -331,7 +331,7 @@ void CGamDoc::EventShowBoardNotification(BoardID nBrdSerNum, CPoint pntTipLoc, c pView = FindPBoardView(*pPBoard); pntTipLoc = CB::Convert(pView->WorkspaceToClient(CB::Convert(pntTipLoc))); } - pView->SetNotificationTip(CB::Convert(pntTipLoc), &strMsg); + pView->SetNotificationTip(CB::Convert(pntTipLoc), strMsg); } //////////////////////////////////////////////////////////////////////////// diff --git a/GP/VwPbrd.cpp b/GP/VwPbrd.cpp index 5d2a98af..c6e1744b 100644 --- a/GP/VwPbrd.cpp +++ b/GP/VwPbrd.cpp @@ -171,6 +171,7 @@ wxBEGIN_EVENT_TABLE(CPlayBoardView, CPlayBoardView::BASE) EVT_SELECT_BOARD_OBJLIST(OnMessageSelectBoardObjectList) EVT_SCROLLWIN_LINEDOWN(OnScrollWinLine) EVT_SCROLLWIN_LINEUP(OnScrollWinLine) + EVT_TIMER(XRCID("ID_TIP_MSG_TIMER"), NotificationTipTimeoutHandler) wxEND_EVENT_TABLE() // helper for wxEvtHandler::Bind for ID_ACT_ROTATE_0 @@ -246,7 +247,8 @@ CPlayBoardView::CPlayBoardView(CPlayBoardViewContainer& p) : m_selList(*this), parent(&p), document(dynamic_cast(parent->GetDocument())), - m_pPBoard(static_cast(document->GetNewViewParameter())) + m_pPBoard(static_cast(document->GetNewViewParameter())), + m_toolMsgTipTimer(this, XRCID("ID_TIP_MSG_TIMER")) { EnableAutoScrollInside(scrollZone); DisableAutoScrollOutside(); diff --git a/GP/VwPbrd.h b/GP/VwPbrd.h index 06a3a5eb..719624ba 100644 --- a/GP/VwPbrd.h +++ b/GP/VwPbrd.h @@ -1,6 +1,6 @@ // VwPbrd.h : interface of the CPlayBoardView class // -// Copyright (c) 1994-2025 By Dale L. Larson & William Su, All Rights Reserved. +// Copyright (c) 1994-2026 By Dale L. Larson & William Su, All Rights Reserved. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the @@ -121,14 +121,13 @@ class CPlayBoardView : public CB::ProcessEventOverride // Tooltip Support public: +#if 0 void SetNotificationTip(wxPoint pointClient, UINT nResID); - void SetNotificationTip(wxPoint pointClient, const CB::string* pszTip); +#endif + void SetNotificationTip(wxPoint pointClient, const CB::string& pszTip); void ClearNotificationTip(); void ClearToolTip(); -#if 0 - static void CALLBACK NotificationTipTimeoutHandler(HWND hwnd, UINT uMsg, - UINT_PTR idEvent, DWORD dwTime); -#endif + void NotificationTipTimeoutHandler(wxTimerEvent& event); void DoToolTipHitProcessing(wxPoint pointClient); // Grid and limiting support @@ -170,6 +169,7 @@ class CPlayBoardView : public CB::ProcessEventOverride int m_nCurToolID; // Current tool ID // -------- // CB::ToolTip m_toolMsgTip; // Tooltip for notifications + wxTimer m_toolMsgTipTimer; CB::ToolTip m_toolHitTip; // Tooltip hit support for view wxRect m_toolHitTipRect = wxRect(); CB::propagate_const m_pCurTipObj; // Currently hit tip object diff --git a/GP/VwPbrd1.cpp b/GP/VwPbrd1.cpp index a5a3f250..a1615529 100644 --- a/GP/VwPbrd1.cpp +++ b/GP/VwPbrd1.cpp @@ -1,6 +1,6 @@ // VwPbrd1.cpp : implementation of the CPlayBoardView class // -// Copyright (c) 1994-2025 By Dale L. Larson & William Su, All Rights Reserved. +// Copyright (c) 1994-2026 By Dale L. Larson & William Su, All Rights Reserved. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the @@ -178,13 +178,15 @@ void CPlayBoardView::ClearToolTip() ////////////////////////////////////////////////////////////////////// +#if 0 void CPlayBoardView::SetNotificationTip(wxPoint pointClient, UINT nResID) { CB::string str = CB::string::LoadString(nResID); SetNotificationTip(pointClient, &str); } +#endif -void CPlayBoardView::SetNotificationTip(wxPoint pointClient, const CB::string* pszTip) +void CPlayBoardView::SetNotificationTip(wxPoint pointClient, const CB::string& pszTip) { ClearNotificationTip(); @@ -206,7 +208,15 @@ void CPlayBoardView::SetNotificationTip(wxPoint pointClient, const CB::string* p SetTimer(ID_TIP_MSG_TIMER, MAX_TIP_MSG_TIME, NotificationTipTimeoutHandler); #else - wxASSERT(!"TODO:"); + m_toolMsgTip.Add(*this, pszTip, CB::ToolTip::TRACK); + + wxPoint pointScreen = ClientToScreen(pointClient); + + m_toolMsgTip.Enable(true); + m_toolMsgTip.TrackActivate(*this, true); + m_toolMsgTip.TrackPosition(pointScreen); + + m_toolMsgTipTimer.Start(MAX_TIP_MSG_TIME, wxTIMER_ONE_SHOT); #endif } @@ -221,19 +231,18 @@ void CPlayBoardView::ClearNotificationTip() m_toolMsgTip.DelTool(this, ID_TIP_PLAYBOARD_MSG); m_toolMsgTip.Activate(FALSE); #else - CPP20_TRACE("{}->{}: TODO:\n", *this, __func__); + m_toolMsgTipTimer.Stop(); + + m_toolMsgTip.TrackActivate(*this, false); + m_toolMsgTip.Delete(*this); + m_toolMsgTip.Enable(false); #endif } -#if 0 -void CALLBACK CPlayBoardView::NotificationTipTimeoutHandler(HWND hwnd, - UINT uMsg, UINT_PTR idEvent, DWORD dwTime) +void CPlayBoardView::NotificationTipTimeoutHandler(wxTimerEvent& /*event*/) { - CPlayBoardView* pView = (CPlayBoardView*)CWnd::FromHandle(hwnd); - ASSERT(pView != NULL); - pView->ClearNotificationTip(); + ClearNotificationTip(); } -#endif ////////////////////////////////////////////////////////////////////// diff --git a/GShr/CyberBoard.h b/GShr/CyberBoard.h index acfc75cb..7c54971b 100644 --- a/GShr/CyberBoard.h +++ b/GShr/CyberBoard.h @@ -2242,7 +2242,7 @@ namespace CB { public: // flags may be or'ed together - enum Flags { NONE = 0, CENTER = 1, TRACK = 2 }; + enum Flags { NONE = 0, CENTER = 1, TRACK = 2, /*TRACK_ON = 4*/ }; ToolTip() = default; ~ToolTip(); @@ -2269,8 +2269,8 @@ namespace CB really want the balloon shape, we will have to implement the paint ourselves. */ void SetBalloonMode(bool b) { balloon = b; } - void TrackActivate(bool b); - void TrackPosition(wxPoint p); + void TrackActivate(wxWindow& wnd, bool b); + void TrackPosition(wxPoint screenPt); void Add(wxWindow& wnd, const wxRect& rect, wxString tip, Flags flags = NONE) @@ -2292,6 +2292,7 @@ namespace CB } private: + enum /*Flags*/ { TRACK_ON = 4 }; void Add(wxWindow& wnd, std::optional&& rect, wxString&& tip, Flags flags); void Delete(wxWindow& wnd, std::optional rect); @@ -2328,7 +2329,6 @@ namespace CB sDisplay, }; State state = sNoTool; - }; /* emulate CRect::Inflate() and CRect::Normalize() sequence diff --git a/GShr/LibMfc.cpp b/GShr/LibMfc.cpp index 66a4fef7..db3a3976 100644 --- a/GShr/LibMfc.cpp +++ b/GShr/LibMfc.cpp @@ -1,6 +1,6 @@ // LibMfc.cpp - Miscellaneous MFC Support Functions // -// Copyright (c) 1994-2025 By Dale L. Larson & William Su, All Rights Reserved. +// Copyright (c) 1994-2026 By Dale L. Larson & William Su, All Rights Reserved. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the @@ -1070,10 +1070,51 @@ void CB::ToolTip::SetMaxWidth(int width) maxWidth = width; } +void CB::ToolTip::TrackActivate(wxWindow& wnd, bool b) +{ + wxASSERT(!b || (!IsRunning() && state == sNoTool)); + auto it = std::find_if(toolInfos.begin(), toolInfos.end(), + [&wnd](const ToolInfo& ti) + { + return &ti.wnd.get() == &wnd && + !ti.rect; + }); + if (it == toolInfos.end() && !b) + { + return; + } + wxASSERT(it != toolInfos.end()); + + it->flags = Flags(it->flags & (~TRACK_ON) | (b ? TRACK_ON : 0)); + + // show/hide the tooltip immediately + if (b && !tipWindow) + { + wxASSERT(tipTool == toolInfos.end()); + tipTool = it; + state = sDisplayWait; + Notify(); + } + else if (!b && tipWindow) + { + CloseTipWindow(); + } +} + +void CB::ToolTip::TrackPosition(wxPoint screenPt) +{ + wxASSERT(tipTool != toolInfos.end() && + (tipTool->flags & Flags(TRACK_ON))); + + if (tipWindow) + { + tipWindow->SetPosition(screenPt); + } +} + void CB::ToolTip::Add(wxWindow& wnd, std::optional&& rect, wxString&& tip, Flags flags) { - wxASSERT(!(flags & TRACK) || !"TRACK not implemented"); // center shouldn't move, track should move wxASSERT((flags & (CENTER | TRACK)) != (CENTER | TRACK)); wxASSERT(!rect || !rect->IsEmpty()); @@ -1107,11 +1148,16 @@ void CB::ToolTip::Delete(wxWindow& wnd, std::optional rect) return &ti.wnd.get() == &wnd && ti.rect == rect; }); - wxASSERT(it != toolInfos.end()); + if (it == toolInfos.end()) + { + return; + } if (it == tipTool) { CloseTipWindow(); + Stop(); + state = sNoTool; } toolInfos.erase(it); @@ -1155,7 +1201,7 @@ void CB::ToolTip::Notify() wxCoord left = center - tipWindow->GetRect().GetWidth() / 2; tipWindow->Move(left, screenRect.GetBottom() + 1); } - Start(autopopMs); + StartOnce(autopopMs); state = sDisplay; break; } From cb320c0bda537f31d8f1426b164ed3fd5ab073a2 Mon Sep 17 00:00:00 2001 From: Bill Su Date: Tue, 27 Jan 2026 00:41:34 -0500 Subject: [PATCH 54/80] PalMark: const/NULL/override/deadcode cleanup --- GP/FrmMain.h | 2 +- GP/GamDoc.cpp | 12 ++++++------ GP/PalMark.cpp | 29 +++++++++-------------------- GP/PalMark.h | 24 ++++++++++-------------- 4 files changed, 26 insertions(+), 41 deletions(-) diff --git a/GP/FrmMain.h b/GP/FrmMain.h index ee8894e6..7021ec1f 100644 --- a/GP/FrmMain.h +++ b/GP/FrmMain.h @@ -51,7 +51,7 @@ class CMainFrame : public CMDIFrameWndExCb, public: CDocument* GetCurrentDocument(); - CDockMarkPalette* GetDockingMarkerWindow() { return &m_wndMarkPal; } + CDockMarkPalette& GetDockingMarkerWindow() { return m_wndMarkPal; } CDockTrayPalette* GetDockingTrayAWindow() { return &m_wndTrayPalA; } CDockTrayPalette* GetDockingTrayBWindow() { return &m_wndTrayPalB; } diff --git a/GP/GamDoc.cpp b/GP/GamDoc.cpp index 9eadfdbf..a07ea096 100644 --- a/GP/GamDoc.cpp +++ b/GP/GamDoc.cpp @@ -1,6 +1,6 @@ // GamDoc.cpp // -// Copyright (c) 1994-2025 By Dale L. Larson & William Su, All Rights Reserved. +// Copyright (c) 1994-2026 By Dale L. Larson & William Su, All Rights Reserved. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the @@ -197,7 +197,8 @@ END_MESSAGE_MAP() CGamDoc::CGamDoc() : m_palTrayA(*this), - m_palTrayB(*this) + m_palTrayB(*this), + m_palMark(*this) { m_nSeedCarryOver = (UINT)GetTickCount(); @@ -230,7 +231,6 @@ CGamDoc::CGamDoc() : m_bVrfySaveState = TRUE; m_palTrayA.SetPaletteID(0); m_palTrayB.SetPaletteID(1); - m_palMark.SetDocument(this); m_wDocRand = GetTimeBasedRandomNumber(FALSE); // Non zero random number m_nMoveInterlock = 0; m_bQuietPlayback = FALSE; @@ -451,9 +451,9 @@ void CGamDoc::OnIdle(BOOL bActive) { CMainFrame* pMFrame = GetMainFrame(); - CDockMarkPalette* pDockMark = pMFrame->GetDockingMarkerWindow(); - pDockMark->SetChild(&m_palMark); - pMFrame->UpdatePaletteWindow(pDockMark, m_bMarkPalVisible); + CDockMarkPalette& pDockMark = pMFrame->GetDockingMarkerWindow(); + pDockMark.SetChild(&m_palMark); + pMFrame->UpdatePaletteWindow(&pDockMark, m_bMarkPalVisible); CDockTrayPalette* pDockTrayA = pMFrame->GetDockingTrayAWindow(); pDockTrayA->SetChild(&m_palTrayA); diff --git a/GP/PalMark.cpp b/GP/PalMark.cpp index 05ad2bac..ea26ecb6 100644 --- a/GP/PalMark.cpp +++ b/GP/PalMark.cpp @@ -1,6 +1,6 @@ // PalMark.cpp : implementation file // -// Copyright (c) 1994-2024 By Dale L. Larson & William Su, All Rights Reserved. +// Copyright (c) 1994-2026 By Dale L. Larson & William Su, All Rights Reserved. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the @@ -36,7 +36,7 @@ static char THIS_FILE[] = __FILE__; #endif -IMPLEMENT_DYNCREATE(CMarkerPalette, CMiniFrameWnd) +IMPLEMENT_DYNAMIC(CMarkerPalette, CMiniFrameWnd) #ifdef _DEBUG #define new DEBUG_NEW @@ -63,22 +63,22 @@ END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CMarkerPalette -CMarkerPalette::CMarkerPalette() +CMarkerPalette::CMarkerPalette(CGamDoc& pDoc) : + m_pDoc(&pDoc) { - m_pDoc = NULL; - m_listMark.EnableDrag(TRUE); + m_listMark.SetDocument(&*m_pDoc); m_dummyArray.push_back(MarkID(0)); m_bStateVarsArmed = FALSE; m_nComboHeight = 0; m_pDockingFrame = NULL; } -BOOL CMarkerPalette::Create(CWnd* pOwnerWnd, DWORD dwStyle, UINT nID) +BOOL CMarkerPalette::Create(CWnd& pOwnerWnd, DWORD dwStyle, UINT nID) { dwStyle |= WS_CHILD | WS_VISIBLE; if (!CWnd::Create(AfxRegisterWndClass(0), NULL, dwStyle, - CRect(0, 0, 200, 100), pOwnerWnd, nID)) + CRect(0, 0, 200, 100), &pOwnerWnd, nID)) { TRACE("Failed to create Tray palette window.\n"); return FALSE; @@ -163,7 +163,7 @@ LRESULT CMarkerPalette::OnPaletteHide(WPARAM, LPARAM) ///////////////////////////////////////////////////////////////////////////// -size_t CMarkerPalette::GetSelectedMarkerGroup() +size_t CMarkerPalette::GetSelectedMarkerGroup() const { int nSel = m_comboMGrp.GetCurSel(); if (nSel < 0) @@ -171,7 +171,7 @@ size_t CMarkerPalette::GetSelectedMarkerGroup() return value_preserving_cast(m_comboMGrp.GetItemData(nSel)); } -int CMarkerPalette::FindMarkerGroupIndex(size_t nGroupNum) +int CMarkerPalette::FindMarkerGroupIndex(size_t nGroupNum) const { if (m_comboMGrp.GetCount() <= 0) return -1; @@ -310,18 +310,8 @@ void CMarkerPalette::Serialize(CArchive& ar) ///////////////////////////////////////////////////////////////////////////// -void CMarkerPalette::SetDocument(CGamDoc *pDoc) -{ - ASSERT(pDoc->IsKindOf(RUNTIME_CLASS(CGamDoc))); - m_pDoc = pDoc; - m_listMark.SetDocument(pDoc); -} - -///////////////////////////////////////////////////////////////////////////// - void CMarkerPalette::LoadMarkerNameList() { - ASSERT(m_pDoc); CMarkManager& pMMgr = m_pDoc->GetMarkManager(); m_comboMGrp.ResetContent(); @@ -351,7 +341,6 @@ void CMarkerPalette::UpdatePaletteContents() void CMarkerPalette::UpdateMarkerList() { - ASSERT(m_pDoc); CMarkManager& pMMgr = m_pDoc->GetMarkManager(); size_t nSel = GetSelectedMarkerGroup(); diff --git a/GP/PalMark.h b/GP/PalMark.h index 8e982f49..8a7f95b0 100644 --- a/GP/PalMark.h +++ b/GP/PalMark.h @@ -1,6 +1,6 @@ // PalMark.h : header file // -// Copyright (c) 1994-2020 By Dale L. Larson, All Rights Reserved. +// Copyright (c) 1994-2026 By Dale L. Larson & William Su, All Rights Reserved. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the @@ -42,20 +42,19 @@ class CGamDoc; class CMarkerPalette : public CWnd { - DECLARE_DYNCREATE(CMarkerPalette) + DECLARE_DYNAMIC(CMarkerPalette) // Construction public: - CMarkerPalette(); - BOOL Create(CWnd* pOwnerWnd, DWORD dwStyle = 0, UINT nID = 0); + CMarkerPalette(CGamDoc& pDoc); + BOOL Create(CWnd& pOwnerWnd, DWORD dwStyle = 0, UINT nID = 0); // Attributes public: - void SetDocument(CGamDoc *pDoc); // Operations public: - size_t GetSelectedMarkerGroup(); + size_t GetSelectedMarkerGroup() const; void UpdatePaletteContents(); @@ -63,7 +62,7 @@ class CMarkerPalette : public CWnd void Serialize(CArchive &ar); - CDockablePane* GetDockingFrame() { return m_pDockingFrame; } + const CDockablePane* GetDockingFrame() const { return &*m_pDockingFrame; } void SetDockingFrame(CDockablePane* pDockingFrame) { m_pDockingFrame = pDockingFrame; @@ -72,9 +71,8 @@ class CMarkerPalette : public CWnd // Implementation protected: - CGamDoc* m_pDoc; - CRect m_rctPos; - CDockablePane* m_pDockingFrame; + RefPtr m_pDoc; + CB::propagate_const m_pDockingFrame; // This dummy area only contains a single entry. It is used // when only single entry should be shown in the Tray listbox. @@ -89,7 +87,7 @@ class CMarkerPalette : public CWnd void LoadMarkerNameList(); void UpdateMarkerList(); - int FindMarkerGroupIndex(size_t nGroupNum); + int FindMarkerGroupIndex(size_t nGroupNum) const; // Some temporary vars used during windows position restoration. // They are loaded during the de-serialization process. @@ -99,11 +97,9 @@ class CMarkerPalette : public CWnd int m_nListCurSel; int m_nComboHeight; - CWinPlacement m_wndPlace; - // Implementation public: - virtual void PostNcDestroy(); + void PostNcDestroy() override; // Generated message map functions protected: From f04f6798b670e2a3c7deec00aaf26ed6daa7b1ed Mon Sep 17 00:00:00 2001 From: Bill Su Date: Tue, 27 Jan 2026 23:29:05 -0500 Subject: [PATCH 55/80] FrmDockMark: const/null/override/access correctness --- GP/FrmDockMark.cpp | 1 + GP/FrmDockMark.h | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/GP/FrmDockMark.cpp b/GP/FrmDockMark.cpp index 15adceac..15d3dc72 100644 --- a/GP/FrmDockMark.cpp +++ b/GP/FrmDockMark.cpp @@ -98,6 +98,7 @@ void CDockMarkPalette::OnSize(UINT nType, int cx, int cy) void CDockMarkPalette::OnDestroy() { + wxASSERT(!m_pChildWnd); m_pChildWnd = NULL; CDockablePane::OnDestroy(); } diff --git a/GP/FrmDockMark.h b/GP/FrmDockMark.h index 848933a7..39ad452e 100644 --- a/GP/FrmDockMark.h +++ b/GP/FrmDockMark.h @@ -37,8 +37,8 @@ class CDockMarkPalette : public CDockablePane CDockMarkPalette(); // Attributes -public: - CMarkerPalette* m_pChildWnd; +private: + CB::propagate_const m_pChildWnd; // Operations public: @@ -46,7 +46,7 @@ class CDockMarkPalette : public CDockablePane // Implementation public: - virtual ~CDockMarkPalette(); + ~CDockMarkPalette() override; // Generated message map functions protected: From a24fdd89620e43b71dd4f31eb07be000e93f5788 Mon Sep 17 00:00:00 2001 From: Bill Su Date: Wed, 28 Jan 2026 23:07:43 -0500 Subject: [PATCH 56/80] PalMark/PalTray: tie palette lifetime to HWND lifetime wxWidgets expects wxWindow to be deleted on destroying HWND Also, make CTrayPalette id behavior more explicit --- GP/GamDoc.cpp | 55 +++++++++++++++++++++++++------------------------- GP/GamDoc.h | 19 +++++++++++++---- GP/GamDoc3.cpp | 26 +++++++++++++++--------- GP/GamDoc4.cpp | 16 +++++++-------- GP/PalMark.h | 4 ++++ GP/PalTray.cpp | 5 +++-- GP/PalTray.h | 5 +++-- 7 files changed, 77 insertions(+), 53 deletions(-) diff --git a/GP/GamDoc.cpp b/GP/GamDoc.cpp index a07ea096..1a32657f 100644 --- a/GP/GamDoc.cpp +++ b/GP/GamDoc.cpp @@ -195,10 +195,7 @@ END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CGamDoc construction/destruction -CGamDoc::CGamDoc() : - m_palTrayA(*this), - m_palTrayB(*this), - m_palMark(*this) +CGamDoc::CGamDoc() { m_nSeedCarryOver = (UINT)GetTickCount(); @@ -229,8 +226,6 @@ CGamDoc::CGamDoc() : m_bKeepMoveHist = TRUE; m_bVrfyGameState = TRUE; m_bVrfySaveState = TRUE; - m_palTrayA.SetPaletteID(0); - m_palTrayB.SetPaletteID(1); m_wDocRand = GetTimeBasedRandomNumber(FALSE); // Non zero random number m_nMoveInterlock = 0; m_bQuietPlayback = FALSE; @@ -357,35 +352,35 @@ void CGamDoc::DeleteContents() { /* close may trigger paint of other windows, so close before delete */ - if (m_palTrayA.m_hWnd != NULL) + if (m_palTrayA) { - CDockTrayPalette* pFrame = (CDockTrayPalette*)m_palTrayA.GetDockingFrame(); + CDockTrayPalette* pFrame = static_cast(m_palTrayA->GetDockingFrame()); if (pFrame) { ASSERT_KINDOF(CDockTrayPalette, pFrame); pFrame->SetChild(NULL); // Need to remove pointer from Tray's UI Frame. } - m_palTrayA.DestroyWindow(); + m_palTrayA = nullptr; } - if (m_palTrayB.m_hWnd != NULL) + if (m_palTrayB) { - CDockTrayPalette* pFrame = (CDockTrayPalette*)m_palTrayB.GetDockingFrame(); + CDockTrayPalette* pFrame = static_cast(m_palTrayB->GetDockingFrame()); if (pFrame) { ASSERT_KINDOF(CDockTrayPalette, pFrame); pFrame->SetChild(NULL); // Need to remove pointer from Tray's UI Frame. } - m_palTrayB.DestroyWindow(); + m_palTrayB = nullptr; } - if (m_palMark.m_hWnd != NULL) + if (m_palMark) { - CDockMarkPalette* pFrame = (CDockMarkPalette*)m_palMark.GetDockingFrame(); + CDockMarkPalette* pFrame = static_cast(m_palMark->GetDockingFrame()); if (pFrame) { ASSERT_KINDOF(CDockMarkPalette, pFrame); pFrame->SetChild(NULL); // Need to remove pointer from Marker's UI Frame. } - m_palMark.DestroyWindow(); + m_palMark = nullptr; } // m_wReserved1 = 0; @@ -452,15 +447,15 @@ void CGamDoc::OnIdle(BOOL bActive) CMainFrame* pMFrame = GetMainFrame(); CDockMarkPalette& pDockMark = pMFrame->GetDockingMarkerWindow(); - pDockMark.SetChild(&m_palMark); + pDockMark.SetChild(&*m_palMark); pMFrame->UpdatePaletteWindow(&pDockMark, m_bMarkPalVisible); CDockTrayPalette* pDockTrayA = pMFrame->GetDockingTrayAWindow(); - pDockTrayA->SetChild(&m_palTrayA); + pDockTrayA->SetChild(&*m_palTrayA); pMFrame->UpdatePaletteWindow(pDockTrayA, m_bTrayAVisible); CDockTrayPalette* pDockTrayB = pMFrame->GetDockingTrayBWindow(); - pDockTrayB->SetChild(&m_palTrayB); + pDockTrayB->SetChild(&*m_palTrayB); pMFrame->UpdatePaletteWindow(pDockTrayB, m_bTrayBVisible); CReadMsgWnd* pDocMsg = pMFrame->GetMessageWindow(); @@ -477,8 +472,8 @@ void CGamDoc::OnIdle(BOOL bActive) void CGamDoc::DoInitialUpdate() { - m_palTrayA.UpdatePaletteContents(NULL); - m_palTrayB.UpdatePaletteContents(NULL); + m_palTrayA->UpdatePaletteContents(NULL); + m_palTrayB->UpdatePaletteContents(NULL); } void CGamDoc::UpdateAllViews(CView* pSender, LPARAM lHint, CObject* pHint) @@ -486,13 +481,13 @@ void CGamDoc::UpdateAllViews(CView* pSender, LPARAM lHint, CObject* pHint) CGamDocHint* ph = static_cast(pHint); if (lHint == HINT_TRAYCHANGE) { - m_palTrayA.UpdatePaletteContents(ph->GetArgs().m_pTray); - m_palTrayB.UpdatePaletteContents(ph->GetArgs().m_pTray); + m_palTrayA->UpdatePaletteContents(ph->GetArgs().m_pTray); + m_palTrayB->UpdatePaletteContents(ph->GetArgs().m_pTray); } else if (lHint == HINT_GAMESTATEUSED) { - m_palTrayA.UpdatePaletteContents(); - m_palTrayB.UpdatePaletteContents(); + m_palTrayA->UpdatePaletteContents(); + m_palTrayB->UpdatePaletteContents(); } CDocument::UpdateAllViews(pSender, lHint, pHint); } @@ -640,9 +635,15 @@ BOOL CGamDoc::OnNewScenario() m_pYMgr->SetTileManager(m_pGbx->GetTileManager()); // Finally set up the tray palettes - m_palTrayA.Create(GetMainFrame()->GetDockingTrayAWindow()); - m_palTrayB.Create(GetMainFrame()->GetDockingTrayBWindow()); - m_palMark.Create(GetMainFrame()->GetDockingMarkerWindow()); + wxASSERT(!m_palTrayA); + m_palTrayA = new CTrayPalette(*this, ID_VIEW_TRAYA); + m_palTrayA->Create(GetMainFrame()->GetDockingTrayAWindow()); + wxASSERT(!m_palTrayB); + m_palTrayB = new CTrayPalette(*this, ID_VIEW_TRAYB); + m_palTrayB->Create(GetMainFrame()->GetDockingTrayBWindow()); + wxASSERT(!m_palMark); + m_palMark = new CMarkerPalette(*this); + m_palMark->Create(GetMainFrame()->GetDockingMarkerWindow()); return TRUE; } diff --git a/GP/GamDoc.h b/GP/GamDoc.h index 8b015ead..fdf24ac7 100644 --- a/GP/GamDoc.h +++ b/GP/GamDoc.h @@ -1,6 +1,6 @@ // GamDoc.h // -// Copyright (c) 1994-2025 By Dale L. Larson & William Su, All Rights Reserved. +// Copyright (c) 1994-2026 By Dale L. Larson & William Su, All Rights Reserved. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the @@ -694,13 +694,24 @@ class CGamDoc : public CDocument CTileFacingMap* m_pTileFacingMap; // Map of temp tile rotations (NOT SERIALIZED) +private: + class WindowDestroy + { + public: + void operator()(CWnd* p) const + { + p->DestroyWindow(); + delete p; + } + }; + // Some document related windows... public: // Tray Palettes... - CTrayPalette m_palTrayA; - CTrayPalette m_palTrayB; + CB::propagate_const> m_palTrayA; + CB::propagate_const> m_palTrayB; // Marker Palette... - CMarkerPalette m_palMark; + CB::propagate_const> m_palMark; // Implementation protected: diff --git a/GP/GamDoc3.cpp b/GP/GamDoc3.cpp index 10194e4d..a482231f 100644 --- a/GP/GamDoc3.cpp +++ b/GP/GamDoc3.cpp @@ -1,6 +1,6 @@ // GamDoc3.cpp -- serialization support for the document. // -// Copyright (c) 1994-2025 By Dale L. Larson & William Su, All Rights Reserved. +// Copyright (c) 1994-2026 By Dale L. Larson & William Su, All Rights Reserved. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the @@ -688,11 +688,11 @@ void CGamDoc::SerializeScenarioOrGame(CArchive& ar, uint64_t& offsetOffsetFeatur ar << (BYTE)0; // 0 -> no win state serialize // V2.0 ar << (WORD)m_bTrayAVisible; - m_palTrayA.Serialize(ar); // Save tray position on screen + m_palTrayA->Serialize(ar); // Save tray position on screen ar << (WORD)m_bTrayBVisible; - m_palTrayB.Serialize(ar); // Save tray position on screen + m_palTrayB->Serialize(ar); // Save tray position on screen ar << (WORD)m_bMarkPalVisible; - m_palMark.Serialize(ar); // Save tray position on screen + m_palMark->Serialize(ar); // Save tray position on screen // Main content serialization.... @@ -848,11 +848,17 @@ void CGamDoc::SerializeScenarioOrGame(CArchive& ar, uint64_t& offsetOffsetFeatur } ar >> wTmp; m_bTrayAVisible = (BOOL)wTmp; - m_palTrayA.Serialize(ar); // Restore tray position on screen + wxASSERT(!m_palTrayA); + m_palTrayA = new CTrayPalette(*this, ID_VIEW_TRAYA); + m_palTrayA->Serialize(ar); // Restore tray position on screen ar >> wTmp; m_bTrayBVisible = (BOOL)wTmp; - m_palTrayB.Serialize(ar); // Restore tray position on screen + wxASSERT(!m_palTrayB); + m_palTrayB = new CTrayPalette(*this, ID_VIEW_TRAYB); + m_palTrayB->Serialize(ar); // Restore tray position on screen ar >> wTmp; m_bMarkPalVisible = (BOOL)wTmp; - m_palMark.Serialize(ar); // Restore tray position on screen + wxASSERT(!m_palMark); + m_palMark = new CMarkerPalette(*this); + m_palMark->Serialize(ar); // Restore tray position on screen // OK....retrieve the file offset of the game data... if (NumVersion(verMajor, verMinor) < NumVersion(2, 90)) @@ -877,9 +883,9 @@ void CGamDoc::SerializeScenarioOrGame(CArchive& ar, uint64_t& offsetOffsetFeatur m_pYMgr->SetTileManager(m_pGbx->GetTileManager()); // Finally set up the tray palettes - m_palTrayA.Create(GetMainFrame()->GetDockingTrayAWindow()); - m_palTrayB.Create(GetMainFrame()->GetDockingTrayBWindow()); - m_palMark.Create(GetMainFrame()->GetDockingMarkerWindow()); + m_palTrayA->Create(GetMainFrame()->GetDockingTrayAWindow()); + m_palTrayB->Create(GetMainFrame()->GetDockingTrayBWindow()); + m_palMark->Create(GetMainFrame()->GetDockingMarkerWindow()); // Main content serialization.... m_pPBMgr->Serialize(ar); // Board contents diff --git a/GP/GamDoc4.cpp b/GP/GamDoc4.cpp index d444b0dd..c08da4d7 100644 --- a/GP/GamDoc4.cpp +++ b/GP/GamDoc4.cpp @@ -1,6 +1,6 @@ // GamDoc4.cpp - various game playback support routines // -// Copyright (c) 1994-2025 By Dale L. Larson & William Su, All Rights Reserved. +// Copyright (c) 1994-2026 By Dale L. Larson & William Su, All Rights Reserved. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the @@ -493,7 +493,7 @@ void CGamDoc::EnsureTrayIndexVisible(const CTraySet& pYSet, int nPos) // Make sure item nPos is visible. size_t nGroup = GetTrayManager().FindTrayByRef(pYSet); ASSERT(nGroup != Invalid_v); - m_palTrayA.ShowTrayIndex(nGroup, nPos); + m_palTrayA->ShowTrayIndex(nGroup, nPos); } ///////////////////////////////////////////////////////////////////////////// @@ -546,7 +546,7 @@ void CGamDoc::SelectTrayItem(const CTraySet& pYSet, PieceID pid, // Select the piece in the appropriate trayset. size_t nGroup = GetTrayManager().FindTrayByRef(pYSet); ASSERT(nGroup != Invalid_v); - m_palTrayA.SelectTrayPiece(nGroup, pid, pszNotificationTip ? pszNotificationTip : nullptr); + m_palTrayA->SelectTrayPiece(nGroup, pid, pszNotificationTip ? pszNotificationTip : nullptr); } void CGamDoc::SelectMarkerPaletteItem(MarkID mid) @@ -556,7 +556,7 @@ void CGamDoc::SelectMarkerPaletteItem(MarkID mid) if (!m_bMarkPalVisible) OnViewMarkPalette(); // Select the marker in the appropriate group. - m_palMark.SelectMarker(mid); + m_palMark->SelectMarker(mid); } ///////////////////////////////////////////////////////////////////////////// @@ -676,8 +676,8 @@ void CGamDoc::IndicateTextTipOnBoard(const CPlayBoard& pPBoard, void CGamDoc::FlushAllSelections() { - m_palTrayA.DeselectAll(); - m_palTrayB.DeselectAll(); + m_palTrayA->DeselectAll(); + m_palTrayB->DeselectAll(); // Use hint to flush select lists. CGamDocHint hint; @@ -688,8 +688,8 @@ void CGamDoc::FlushAllSelections() void CGamDoc::FlushAllIndicators() { - m_palTrayA.DeselectAll(); - m_palTrayB.DeselectAll(); + m_palTrayA->DeselectAll(); + m_palTrayB->DeselectAll(); for (size_t i = 0; i < m_pPBMgr->GetNumPBoards(); i++) { diff --git a/GP/PalMark.h b/GP/PalMark.h index 8a7f95b0..0700afd2 100644 --- a/GP/PalMark.h +++ b/GP/PalMark.h @@ -63,6 +63,10 @@ class CMarkerPalette : public CWnd void Serialize(CArchive &ar); const CDockablePane* GetDockingFrame() const { return &*m_pDockingFrame; } + CDockablePane* GetDockingFrame() + { + return const_cast(std::as_const(*this).GetDockingFrame()); + } void SetDockingFrame(CDockablePane* pDockingFrame) { m_pDockingFrame = pDockingFrame; diff --git a/GP/PalTray.cpp b/GP/PalTray.cpp index 2068060a..61f0a8b9 100644 --- a/GP/PalTray.cpp +++ b/GP/PalTray.cpp @@ -99,7 +99,7 @@ END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CTrayPalette -CTrayPalette::CTrayPalette(CGamDoc& pDoc) : +CTrayPalette::CTrayPalette(CGamDoc& pDoc, UINT palID) : m_pDoc(&pDoc), m_listTray(*m_pDoc) { @@ -114,6 +114,7 @@ CTrayPalette::CTrayPalette(CGamDoc& pDoc) : m_bStateVarsArmed = FALSE; m_nComboHeight = 0; m_pDockingFrame = NULL; + SetPaletteID(palID); } BOOL CTrayPalette::Create(CWnd* pOwnerWnd, DWORD dwStyle, UINT nID) @@ -265,7 +266,7 @@ LRESULT CTrayPalette::OnMessageRestoreWinState(WPARAM, LPARAM) LRESULT CTrayPalette::OnPaletteHide(WPARAM, LPARAM) { GetMainFrame()->SendMessage(WM_COMMAND, - (WPARAM)(m_nID == 0 ? ID_VIEW_TRAYA : ID_VIEW_TRAYB)); + (WPARAM)(m_nID)); return (LRESULT)0; } diff --git a/GP/PalTray.h b/GP/PalTray.h index 1b725266..7bb19053 100644 --- a/GP/PalTray.h +++ b/GP/PalTray.h @@ -48,13 +48,14 @@ class CTrayPalette : public CWnd // Construction public: - CTrayPalette(CGamDoc& pDoc); + CTrayPalette(CGamDoc& pDoc, UINT palID); BOOL Create(CWnd* pOwnerWnd, DWORD dwStyle = 0, UINT nID = 0); // Attributes -public: +private: void SetPaletteID(UINT nID) { m_nID = nID; } +public: CDockablePane* GetDockingFrame() { return m_pDockingFrame; } void SetDockingFrame(CDockablePane* pDockingFrame) From d65731fa3a0be913195966847e39df2ebf17e4d6 Mon Sep 17 00:00:00 2001 From: Bill Su Date: Fri, 30 Jan 2026 00:28:44 -0500 Subject: [PATCH 57/80] provide wx variant of WM_PALETTE_HIDE message --- GP/FrmMain.cpp | 26 ++++++++++++++++++++------ GP/Gp.cpp | 1 + GP/Gp.h | 1 + 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/GP/FrmMain.cpp b/GP/FrmMain.cpp index f7b0cdae..b04e844e 100644 --- a/GP/FrmMain.cpp +++ b/GP/FrmMain.cpp @@ -399,18 +399,32 @@ void CMainFrame::OnIdle() } } +namespace { + /* CB is currently a mix of MFC and wx, + so need to send both kinds of msg */ + BOOL OnClosePalette(CWnd& pWnd) + { + pWnd.SendMessage(WM_PALETTE_HIDE); + pWnd.SendMessageToDescendants(WM_PALETTE_HIDE, true, true); + wxWindow* wxWnd = CB::FindWxWindow(pWnd); + if (wxWnd) + { + wxCommandEvent event(WM_PALETTE_HIDE_WX); + wxWnd->GetEventHandler()->ProcessEventLocally(event); + CB::SendEventToDescendants(*wxWnd, event, true); + } + return true; + } +} + BOOL CMainFrame::OnCloseMiniFrame(CPaneFrameWnd* pWnd) { - pWnd->SendMessage(WM_PALETTE_HIDE); - pWnd->SendMessageToDescendants(WM_PALETTE_HIDE, true, true); - return true; + return OnClosePalette(CheckedDeref(pWnd)); } BOOL CMainFrame::OnCloseDockingPane(CDockablePane* pWnd) { - pWnd->SendMessage(WM_PALETTE_HIDE); - pWnd->SendMessageToDescendants(WM_PALETTE_HIDE, true, true); - return true; + return OnClosePalette(CheckedDeref(pWnd)); } void CMainFrame::ShowPalettePanes(BOOL bShow) diff --git a/GP/Gp.cpp b/GP/Gp.cpp index 15469f33..ec8af054 100644 --- a/GP/Gp.cpp +++ b/GP/Gp.cpp @@ -53,6 +53,7 @@ wxDEFINE_EVENT(WM_CENTERBOARDONPOINT_WX, CenterBoardOnPointEvent); wxDEFINE_EVENT(WM_SHOWPLAYINGBOARD_WX, ShowPlayingBoardEvent); wxDEFINE_EVENT(WM_WINSTATE_RESTORE_WX, WinStateRestoreEvent); wxDEFINE_EVENT(WM_SELECT_BOARD_OBJLIST_WX, SelectBoardObjListEvent); +wxDEFINE_EVENT(WM_PALETTE_HIDE_WX, wxCommandEvent); ///////////////////////////////////////////////////////////////////////////// // Registry keys... diff --git a/GP/Gp.h b/GP/Gp.h index 905e53b8..cb7053fa 100644 --- a/GP/Gp.h +++ b/GP/Gp.h @@ -181,6 +181,7 @@ enum }; #define WM_PALETTE_HIDE (WM_USER + 216) +wxDECLARE_EVENT(WM_PALETTE_HIDE_WX, wxCommandEvent); ///////////////////////////////////////////////////////////////////////////// // Context menu offset definitions. From 2b544d2ab646e2653810d6c279409c4b10543cfd Mon Sep 17 00:00:00 2001 From: Bill Su Date: Sat, 31 Jan 2026 21:39:21 -0500 Subject: [PATCH 58/80] LibMfc: avoid an ASSERT from inside MFC --- GShr/LibMfc.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/GShr/LibMfc.cpp b/GShr/LibMfc.cpp index db3a3976..b0205d0b 100644 --- a/GShr/LibMfc.cpp +++ b/GShr/LibMfc.cpp @@ -1630,6 +1630,7 @@ BOOL CB::RelayOnCmdMsg(wxEvtHandler& dest, so approximate this way */ class CDummyCmdUI : public CCmdUI { + void Enable(BOOL) override {} void SetCheck(int nCheck = 1) override {} // 0, 1 or 2 (indeterminate) }; CDummyCmdUI dummy; From 6582d1e7dc828b575d1b0fdd10097d8e10edff48 Mon Sep 17 00:00:00 2001 From: Bill Su Date: Sun, 15 Feb 2026 02:42:39 -0500 Subject: [PATCH 59/80] PalMark: create an extra window to simplify wx conversion --- GP/FrmDockMark.cpp | 2 +- GP/FrmDockMark.h | 8 +++--- GP/GamDoc.cpp | 2 +- GP/GamDoc.h | 2 +- GP/GamDoc3.cpp | 6 ++--- GP/GamDoc4.cpp | 2 +- GP/PalMark.cpp | 67 +++++++++++++++++++++++++++++++++++++++++----- GP/PalMark.h | 65 +++++++++++++++++++++++++++++++------------- 8 files changed, 119 insertions(+), 35 deletions(-) diff --git a/GP/FrmDockMark.cpp b/GP/FrmDockMark.cpp index 15d3dc72..28bdbed1 100644 --- a/GP/FrmDockMark.cpp +++ b/GP/FrmDockMark.cpp @@ -56,7 +56,7 @@ CDockMarkPalette::~CDockMarkPalette() ///////////////////////////////////////////////////////////////////////////// -void CDockMarkPalette::SetChild(CMarkerPalette* pChildWnd) +void CDockMarkPalette::SetChild(CMarkerPaletteContainer* pChildWnd) { if (m_pChildWnd == pChildWnd) return; diff --git a/GP/FrmDockMark.h b/GP/FrmDockMark.h index 39ad452e..6213157b 100644 --- a/GP/FrmDockMark.h +++ b/GP/FrmDockMark.h @@ -1,6 +1,6 @@ // FrmDockMark.h - container window for the marker palette. // -// Copyright (c) 1994-2020 By Dale L. Larson, All Rights Reserved. +// Copyright (c) 1994-2026 By Dale L. Larson & William Su, All Rights Reserved. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the @@ -27,7 +27,7 @@ ///////////////////////////////////////////////////////////////////////////// // CDockMarkPalette window -class CMarkerPalette; +class CMarkerPaletteContainer; class CDockMarkPalette : public CDockablePane { @@ -38,11 +38,11 @@ class CDockMarkPalette : public CDockablePane // Attributes private: - CB::propagate_const m_pChildWnd; + CB::propagate_const m_pChildWnd; // Operations public: - void SetChild(CMarkerPalette* pChildWnd); + void SetChild(CMarkerPaletteContainer* pChildWnd); // Implementation public: diff --git a/GP/GamDoc.cpp b/GP/GamDoc.cpp index 1a32657f..1078f42f 100644 --- a/GP/GamDoc.cpp +++ b/GP/GamDoc.cpp @@ -642,7 +642,7 @@ BOOL CGamDoc::OnNewScenario() m_palTrayB = new CTrayPalette(*this, ID_VIEW_TRAYB); m_palTrayB->Create(GetMainFrame()->GetDockingTrayBWindow()); wxASSERT(!m_palMark); - m_palMark = new CMarkerPalette(*this); + m_palMark = new CMarkerPaletteContainer(*this); m_palMark->Create(GetMainFrame()->GetDockingMarkerWindow()); return TRUE; diff --git a/GP/GamDoc.h b/GP/GamDoc.h index fdf24ac7..016bbd20 100644 --- a/GP/GamDoc.h +++ b/GP/GamDoc.h @@ -711,7 +711,7 @@ class CGamDoc : public CDocument CB::propagate_const> m_palTrayA; CB::propagate_const> m_palTrayB; // Marker Palette... - CB::propagate_const> m_palMark; + CB::propagate_const> m_palMark; // Implementation protected: diff --git a/GP/GamDoc3.cpp b/GP/GamDoc3.cpp index a482231f..c7548023 100644 --- a/GP/GamDoc3.cpp +++ b/GP/GamDoc3.cpp @@ -692,7 +692,7 @@ void CGamDoc::SerializeScenarioOrGame(CArchive& ar, uint64_t& offsetOffsetFeatur ar << (WORD)m_bTrayBVisible; m_palTrayB->Serialize(ar); // Save tray position on screen ar << (WORD)m_bMarkPalVisible; - m_palMark->Serialize(ar); // Save tray position on screen + (*m_palMark)->Serialize(ar); // Save tray position on screen // Main content serialization.... @@ -857,8 +857,8 @@ void CGamDoc::SerializeScenarioOrGame(CArchive& ar, uint64_t& offsetOffsetFeatur m_palTrayB->Serialize(ar); // Restore tray position on screen ar >> wTmp; m_bMarkPalVisible = (BOOL)wTmp; wxASSERT(!m_palMark); - m_palMark = new CMarkerPalette(*this); - m_palMark->Serialize(ar); // Restore tray position on screen + m_palMark = new CMarkerPaletteContainer(*this); + (*m_palMark)->Serialize(ar); // Restore tray position on screen // OK....retrieve the file offset of the game data... if (NumVersion(verMajor, verMinor) < NumVersion(2, 90)) diff --git a/GP/GamDoc4.cpp b/GP/GamDoc4.cpp index c08da4d7..2b9525c0 100644 --- a/GP/GamDoc4.cpp +++ b/GP/GamDoc4.cpp @@ -556,7 +556,7 @@ void CGamDoc::SelectMarkerPaletteItem(MarkID mid) if (!m_bMarkPalVisible) OnViewMarkPalette(); // Select the marker in the appropriate group. - m_palMark->SelectMarker(mid); + (*m_palMark)->SelectMarker(mid); } ///////////////////////////////////////////////////////////////////////////// diff --git a/GP/PalMark.cpp b/GP/PalMark.cpp index ea26ecb6..6d701711 100644 --- a/GP/PalMark.cpp +++ b/GP/PalMark.cpp @@ -36,7 +36,9 @@ static char THIS_FILE[] = __FILE__; #endif +#if 0 IMPLEMENT_DYNAMIC(CMarkerPalette, CMiniFrameWnd) +#endif #ifdef _DEBUG #define new DEBUG_NEW @@ -60,10 +62,17 @@ BEGIN_MESSAGE_MAP(CMarkerPalette, CWnd) ON_MESSAGE(WM_WINSTATE_RESTORE, OnMessageRestoreWinState) END_MESSAGE_MAP() +BEGIN_MESSAGE_MAP(CMarkerPaletteContainer, CWnd) + ON_WM_CREATE() + ON_WM_SETFOCUS() + ON_WM_SIZE() +END_MESSAGE_MAP() + ///////////////////////////////////////////////////////////////////////////// // CMarkerPalette -CMarkerPalette::CMarkerPalette(CGamDoc& pDoc) : +CMarkerPalette::CMarkerPalette(CMarkerPaletteContainer& container, CGamDoc& pDoc) : + m_pContainer(&container), m_pDoc(&pDoc) { m_listMark.EnableDrag(TRUE); @@ -71,14 +80,13 @@ CMarkerPalette::CMarkerPalette(CGamDoc& pDoc) : m_dummyArray.push_back(MarkID(0)); m_bStateVarsArmed = FALSE; m_nComboHeight = 0; - m_pDockingFrame = NULL; } -BOOL CMarkerPalette::Create(CWnd& pOwnerWnd, DWORD dwStyle, UINT nID) +BOOL CMarkerPalette::Create(/*CWnd& pOwnerWnd, DWORD dwStyle, UINT nID*/) { - dwStyle |= WS_CHILD | WS_VISIBLE; + DWORD dwStyle = WS_CHILD | WS_VISIBLE; if (!CWnd::Create(AfxRegisterWndClass(0), NULL, dwStyle, - CRect(0, 0, 200, 100), &pOwnerWnd, nID)) + CRect(0, 0, 200, 100), &*m_pContainer, 0)) { TRACE("Failed to create Tray palette window.\n"); return FALSE; @@ -394,7 +402,7 @@ void CMarkerPalette::OnSize(UINT nType, int cx, int cy) } } -void CMarkerPalette::PostNcDestroy() +void CMarkerPaletteContainer::PostNcDestroy() { /* DO NOTHING - FRAME CLASS WOULD DELETE SELF! */ } @@ -418,3 +426,50 @@ BOOL CMarkerPalette::OnHelpInfo(HELPINFO* pHelpInfo) GetApp()->DoHelpTopic("gp-ref-pal-markers.htm"); return TRUE; } + +CMarkerPaletteContainer::CMarkerPaletteContainer(CGamDoc& pDoc) : + child(new CMarkerPalette(*this, pDoc)) +{ +} + +BOOL CMarkerPaletteContainer::Create(CWnd& pOwnerWnd/*, DWORD dwStyle = 0, UINT nID = 0*/) +{ + DWORD dwStyle = WS_CHILD | WS_VISIBLE; + if (!CWnd::Create(AfxRegisterWndClass(0), NULL, dwStyle, + CRect(0, 0, 200, 100), &pOwnerWnd, 0)) + { + TRACE("Failed to create Tray palette container window.\n"); + return FALSE; + } + + return TRUE; +} + +int CMarkerPaletteContainer::OnCreate(LPCREATESTRUCT lpCreateStruct) +{ + if (CWnd::OnCreate(lpCreateStruct) == -1) + { + return -1; + } + + if (!child->Create()) + { + TRACE("Failed to create Tray palette window.\n"); + return -1; + } + + return 0; +} + +// MFC puts the focus here, so move it to the useful window +void CMarkerPaletteContainer::OnSetFocus(CWnd* pOldWnd) +{ + CWnd::OnSetFocus(pOldWnd); + child->SetFocus(); +} + +void CMarkerPaletteContainer::OnSize(UINT nType, int cx, int cy) +{ + child->MoveWindow(0, 0, cx, cy); + return CWnd::OnSize(nType, cx, cy); +} diff --git a/GP/PalMark.h b/GP/PalMark.h index 0700afd2..d9818af4 100644 --- a/GP/PalMark.h +++ b/GP/PalMark.h @@ -36,18 +36,17 @@ ///////////////////////////////////////////////////////////////////////////// class CGamDoc; +class CMarkerPaletteContainer; ///////////////////////////////////////////////////////////////////////////// // CMarkerPalette window - Marker palette's are part of the document object. class CMarkerPalette : public CWnd { - DECLARE_DYNAMIC(CMarkerPalette) - // Construction public: - CMarkerPalette(CGamDoc& pDoc); - BOOL Create(CWnd& pOwnerWnd, DWORD dwStyle = 0, UINT nID = 0); + CMarkerPalette(CMarkerPaletteContainer& container, CGamDoc& pDoc); + BOOL Create(); // Attributes public: @@ -60,23 +59,12 @@ class CMarkerPalette : public CWnd void SelectMarker(MarkID mid); - void Serialize(CArchive &ar); - - const CDockablePane* GetDockingFrame() const { return &*m_pDockingFrame; } - CDockablePane* GetDockingFrame() - { - return const_cast(std::as_const(*this).GetDockingFrame()); - } - void SetDockingFrame(CDockablePane* pDockingFrame) - { - m_pDockingFrame = pDockingFrame; - SetParent(pDockingFrame); - } + void Serialize(CArchive &ar) override; // Implementation protected: + RefPtr m_pContainer; RefPtr m_pDoc; - CB::propagate_const m_pDockingFrame; // This dummy area only contains a single entry. It is used // when only single entry should be shown in the Tray listbox. @@ -103,7 +91,6 @@ class CMarkerPalette : public CWnd // Implementation public: - void PostNcDestroy() override; // Generated message map functions protected: @@ -124,6 +111,48 @@ class CMarkerPalette : public CWnd DECLARE_MESSAGE_MAP() }; +class CMarkerPaletteContainer : public CWnd +{ +public: + CMarkerPaletteContainer(CGamDoc& pDoc); + BOOL Create(CWnd& pOwnerWnd/*, DWORD dwStyle = 0, UINT nID = 0*/); + + void PostNcDestroy() override; + + operator const CMarkerPalette&() const { return *child; } + operator CMarkerPalette&() + { + return const_cast(static_cast(std::as_const(*this))); + } + const CMarkerPalette* operator->() const { return &static_cast(*this); } + CMarkerPalette* operator->() + { + return const_cast(std::as_const(*this).operator->()); + } + + const CDockablePane* GetDockingFrame() const { return m_pDockingFrame.get(); } + CDockablePane* GetDockingFrame() + { + return const_cast(std::as_const(*this).GetDockingFrame()); + } + void SetDockingFrame(CDockablePane* pDockingFrame) + { + m_pDockingFrame = pDockingFrame; + SetParent(pDockingFrame); + } + + void Serialize(CArchive& ar) override { wxASSERT(false); AfxThrowNotSupportedException(); } + +private: + afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); + afx_msg void OnSetFocus(CWnd* pOldWnd); + afx_msg void OnSize(UINT nType, int cx, int cy); + DECLARE_MESSAGE_MAP() + + CB::propagate_const m_pDockingFrame = nullptr; + OwnerPtr child; +}; + ///////////////////////////////////////////////////////////////////////////// #endif From 17e0cf5013d60f200eaab0b87d551939e59855af Mon Sep 17 00:00:00 2001 From: Bill Su Date: Sun, 1 Feb 2026 20:27:20 -0500 Subject: [PATCH 60/80] PalMark: convert to wx TODO: autoscroll VwPbrd --- GP/CBPlay.fbp | 167 ++++++++++++++++++++++++++++++++++++++-- GP/CBPlay.xrc | 24 ++++++ GP/PalMark.cpp | 188 ++++++++++++++++++++++++++-------------------- GP/PalMark.h | 57 +++++++------- GP/VwPbrd.cpp | 89 +++++++++++++--------- GP/VwPbrd.h | 2 +- GShr/LBoxGrfx.h | 20 ++--- GShr/LBoxMark.cpp | 32 ++++---- GShr/LBoxMark.h | 8 +- 9 files changed, 398 insertions(+), 189 deletions(-) diff --git a/GP/CBPlay.fbp b/GP/CBPlay.fbp index 8012cb15..98cf2779 100644 --- a/GP/CBPlay.fbp +++ b/GP/CBPlay.fbp @@ -1,6 +1,6 @@ - + C++ ; @@ -5665,6 +5665,161 @@ + + 0 + wxAUI_MGR_DEFAULT + + + 1 + 0 + 1 + impl_virtual + + + 0 + wxID_ANY + + + CMarkerPalette + + -1,-1 + ; ; forward_declare + + 0 + + + wxTAB_TRAVERSAL + + + bSizer84 + wxVERTICAL + none + + 5 + wxEXPAND + 0 + + 1 + 1 + 1 + 1 + 0 + + 0 + 0 + + + + 1 + 0 + + 1 + + 1 + 0 + Dock + 0 + Left + 0 + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + 0 + + 1 + m_comboMGrp + 1 + + + protected + 1 + + Resizable + 0 + 1 + + wxCB_SORT + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + 5 + wxEXPAND + 1 + + 1 + 1 + 1 + 1 + 0 + + 0 + 0 + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 0 + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + 0 + + 1 + m_listMark + 1 + + + protected + 1 + + Resizable + 1 + + + CMarkListBoxWx; forward_declare; forward_declare + 0 + + + + wxBORDER_SIMPLE|wxWANTS_CHARS + + + + 0 wxAUI_MGR_DEFAULT @@ -7934,13 +8089,13 @@ wxALL 0 - wxID_ANY Snap Grid sbSizer2 wxVERTICAL 1 none + 5 wxEXPAND @@ -8669,13 +8824,13 @@ wxALL 0 - wxID_ANY Cells sbSizer3 wxVERTICAL 1 none + 5 wxTOP|wxRIGHT|wxLEFT @@ -8822,13 +8977,13 @@ wxEXPAND|wxALL 0 - wxID_ANY Auto Stack sbSizer4 wxVERTICAL 1 none + 5 wxEXPAND @@ -9232,13 +9387,13 @@ wxEXPAND|wxALL 0 - wxID_ANY Plotted Moves sbSizer5 wxVERTICAL 1 none + 5 wxEXPAND @@ -14870,13 +15025,13 @@ wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT 0 - wxID_ANY Tray content visibility sbSizer5 wxVERTICAL 1 none + 5 wxALL diff --git a/GP/CBPlay.xrc b/GP/CBPlay.xrc index a385bf4a..6bc80ad4 100644 --- a/GP/CBPlay.xrc +++ b/GP/CBPlay.xrc @@ -1074,6 +1074,30 @@ + + + + wxVERTICAL + + wxEXPAND + 5 + + + + 0 + + + + + wxEXPAND + 5 + + + + + + + Enter Move Description diff --git a/GP/PalMark.cpp b/GP/PalMark.cpp index 6d701711..db4ffb14 100644 --- a/GP/PalMark.cpp +++ b/GP/PalMark.cpp @@ -37,7 +37,7 @@ static char THIS_FILE[] = __FILE__; #endif #if 0 -IMPLEMENT_DYNAMIC(CMarkerPalette, CMiniFrameWnd) +wxIMPLEMENT_CLASS(CMarkerPalette, wxPanel) #endif #ifdef _DEBUG @@ -46,21 +46,23 @@ IMPLEMENT_DYNAMIC(CMarkerPalette, CMiniFrameWnd) ///////////////////////////////////////////////////////////////////////////// -BEGIN_MESSAGE_MAP(CMarkerPalette, CWnd) - //{{AFX_MSG_MAP(CMarkerPalette) +wxBEGIN_EVENT_TABLE(CMarkerPalette, wxPanel) +#if 0 ON_WM_ERASEBKGND() ON_WM_SIZE() ON_WM_CREATE() ON_WM_WINDOWPOSCHANGING() - ON_CBN_SELCHANGE(IDC_W_MARKLIST, OnMarkerNameCbnSelchange) - ON_MESSAGE(WM_OVERRIDE_SELECTED_ITEM, OnOverrideSelectedItem) - ON_MESSAGE(WM_GET_DRAG_SIZE, OnGetDragSize) +#endif + EVT_CHOICE(XRCID("m_comboMGrp"), OnMarkerNameCbnSelchange) + EVT_OVERRIDE_SELECTED_ITEM(OnOverrideSelectedItem) + EVT_GET_DRAG_SIZE(OnGetDragSize) +#if 0 ON_WM_HELPINFO() ON_WM_CREATE() - //}}AFX_MSG_MAP - ON_MESSAGE(WM_PALETTE_HIDE, OnPaletteHide) - ON_MESSAGE(WM_WINSTATE_RESTORE, OnMessageRestoreWinState) -END_MESSAGE_MAP() +#endif + EVT_COMMAND(wxID_ANY, WM_PALETTE_HIDE_WX, OnPaletteHide) + EVT_WINSTATE_RESTORE(OnMessageRestoreWinState) +wxEND_EVENT_TABLE() BEGIN_MESSAGE_MAP(CMarkerPaletteContainer, CWnd) ON_WM_CREATE() @@ -73,10 +75,10 @@ END_MESSAGE_MAP() CMarkerPalette::CMarkerPalette(CMarkerPaletteContainer& container, CGamDoc& pDoc) : m_pContainer(&container), - m_pDoc(&pDoc) + m_pDoc(&pDoc), + m_comboMGrp(nullptr), + m_listMark(nullptr) { - m_listMark.EnableDrag(TRUE); - m_listMark.SetDocument(&*m_pDoc); m_dummyArray.push_back(MarkID(0)); m_bStateVarsArmed = FALSE; m_nComboHeight = 0; @@ -84,21 +86,25 @@ CMarkerPalette::CMarkerPalette(CMarkerPaletteContainer& container, CGamDoc& pDoc BOOL CMarkerPalette::Create(/*CWnd& pOwnerWnd, DWORD dwStyle, UINT nID*/) { - DWORD dwStyle = WS_CHILD | WS_VISIBLE; - if (!CWnd::Create(AfxRegisterWndClass(0), NULL, dwStyle, - CRect(0, 0, 200, 100), &*m_pContainer, 0)) + if (!CB::XrcLoad(*this, *m_pContainer, "CMarkerPalette")) { - TRACE("Failed to create Tray palette window.\n"); - return FALSE; + return false; } + m_comboMGrp = XRCCTRL(*this, "m_comboMGrp", wxChoice); + m_listMark = XRCCTRL(*this, "m_listMark", CMarkListBoxWx); + (*m_pContainer)->Layout(); + + m_listMark->EnableDrag(TRUE); + m_listMark->SetDocument(&*m_pDoc); UpdatePaletteContents(); // Queue up a message to finish up state restore. - PostMessage(WM_WINSTATE_RESTORE); + QueueEvent(WinStateRestoreEvent().Clone()); return TRUE; } +#if 0 int CMarkerPalette::OnCreate(LPCREATESTRUCT lpCreateStruct) { CRect rctCombo; @@ -136,74 +142,81 @@ int CMarkerPalette::OnCreate(LPCREATESTRUCT lpCreateStruct) return 0; } +#endif /////////////////////////////////////////////////////////////////////// // This method handles the custom message WM_WINSTATE_RESTORE. The // message is posted during view initial update if the state of // the windows should be restored. -LRESULT CMarkerPalette::OnMessageRestoreWinState(WPARAM, LPARAM) +void CMarkerPalette::OnMessageRestoreWinState(WinStateRestoreEvent& /*event*/) { UpdatePaletteContents(); if (!m_bStateVarsArmed) - return (LRESULT)0; + return; - m_comboMGrp.SetCurSel(m_nComboIndex); + m_comboMGrp->SetSelection(m_nComboIndex == uint32_t(wxNOT_FOUND) ? + wxNOT_FOUND + : + value_preserving_cast(m_nComboIndex)); UpdateMarkerList(); - m_listMark.SetCurSel(m_nListCurSel); - m_listMark.SetTopIndex(m_nListTopindex); + m_listMark->SetSelection(m_nListCurSel == uint32_t(wxNOT_FOUND) ? + wxNOT_FOUND + : + value_preserving_cast(m_nListCurSel)); + m_listMark->ScrollToRow(value_preserving_cast(m_nListTopindex)); m_bStateVarsArmed = FALSE; - - return (LRESULT)0; } ///////////////////////////////////////////////////////////////////////////// -LRESULT CMarkerPalette::OnPaletteHide(WPARAM, LPARAM) +void CMarkerPalette::OnPaletteHide(wxCommandEvent& /*event*/) { GetMainFrame()->SendMessage(WM_COMMAND, ID_VIEW_MARKERPAL); - return (LRESULT)0; } ///////////////////////////////////////////////////////////////////////////// size_t CMarkerPalette::GetSelectedMarkerGroup() const { - int nSel = m_comboMGrp.GetCurSel(); - if (nSel < 0) + int nSel = m_comboMGrp->GetSelection(); + if (nSel == wxNOT_FOUND) return Invalid_v; - return value_preserving_cast(m_comboMGrp.GetItemData(nSel)); + return value_preserving_cast(reinterpret_cast(m_comboMGrp->GetClientData(value_preserving_cast(nSel)))); } int CMarkerPalette::FindMarkerGroupIndex(size_t nGroupNum) const { - if (m_comboMGrp.GetCount() <= 0) - return -1; - for (int nIdx = 0; nIdx < m_comboMGrp.GetCount(); nIdx++) + if (m_comboMGrp->IsEmpty()) + return wxNOT_FOUND; + for (size_t nIdx = size_t(0) ; nIdx < m_comboMGrp->GetCount() ; ++nIdx) { - if (value_preserving_cast(m_comboMGrp.GetItemData(nIdx)) == nGroupNum) - return nIdx; + if (reinterpret_cast(m_comboMGrp->GetClientData(value_preserving_cast(nIdx))) == nGroupNum) + return value_preserving_cast(nIdx); } - return -1; + return wxNOT_FOUND; } ///////////////////////////////////////////////////////////////////////////// -LRESULT CMarkerPalette::OnOverrideSelectedItem(WPARAM wParam, LPARAM lParam) +void CMarkerPalette::OnOverrideSelectedItem(OverrideSelectedItemEvent& event) { size_t nSel = GetSelectedMarkerGroup(); if (nSel == Invalid_v) - return (LRESULT)0; + { + event.Skip(); + return; + } CMarkManager& pMMgr = m_pDoc->GetMarkManager(); CMarkSet& pMSet = pMMgr.GetMarkSet(nSel); if (pMSet.IsRandomMarkerPull()) { - OverrideSelectedItemEvent& oi = *reinterpret_cast(wParam); + OverrideSelectedItemEvent& oi = event; uint32_t nRandSeed = m_pDoc->GetRandomNumberSeed(); @@ -214,17 +227,16 @@ LRESULT CMarkerPalette::OnOverrideSelectedItem(WPARAM wParam, LPARAM lParam) m_pDoc->SetRandomNumberSeed(nRandSeed); } - - return (LRESULT)1; } -LRESULT CMarkerPalette::OnGetDragSize(WPARAM wParam, LPARAM /*lParam*/) +void CMarkerPalette::OnGetDragSize(GetDragSizeEvent& event) { size_t nSel = GetSelectedMarkerGroup(); if (nSel == Invalid_v) { - ASSERT(!"bad tray"); - return 0; + wxASSERT(!"bad tray"); + event.Skip(); + return; } CMarkManager& pMMgr = m_pDoc->GetMarkManager(); CMarkSet& pMSet = pMMgr.GetMarkSet(nSel); @@ -232,31 +244,30 @@ LRESULT CMarkerPalette::OnGetDragSize(WPARAM wParam, LPARAM /*lParam*/) std::vector items; if (pMSet.IsRandomMarkerPull()) { - items.reserve(value_preserving_cast(m_listMark.GetCount())); - for (int i = 0; i < m_listMark.GetCount(); ++i) + items.reserve(m_listMark->GetItemCount()); + for (size_t i = size_t(0) ; i < m_listMark->GetItemCount() ; ++i) { - items.push_back(i); + items.push_back(value_preserving_cast(i)); } } else { - items.push_back(m_listMark.GetCurSel()); + items.push_back(m_listMark->GetSelection()); } CTileManager& tileMgr = m_pDoc->GetTileManager(); - CSize retval(0, 0); + wxSize retval(0, 0); for (int item : items) { - MarkID mid = m_listMark.MapIndexToItem(value_preserving_cast(item)); + MarkID mid = m_listMark->MapIndexToItem(value_preserving_cast(item)); MarkDef& pMark = pMMgr.GetMark(mid); - ASSERT(pMark.m_tid != nullTid); - CSize size = tileMgr.GetTile(pMark.m_tid).GetSize(); - retval.cx = std::max(retval.cx, size.cx); - retval.cy = std::max(retval.cy, size.cy); + wxASSERT(pMark.m_tid != nullTid); + wxSize size = CB::Convert(tileMgr.GetTile(pMark.m_tid).GetSize()); + retval.x = std::max(retval.x, size.x); + retval.y = std::max(retval.y, size.y); } - CheckedDeref(reinterpret_cast(wParam)) = retval; - return 1; + event.SetSize(retval); } ///////////////////////////////////////////////////////////////////////////// @@ -264,14 +275,14 @@ LRESULT CMarkerPalette::OnGetDragSize(WPARAM wParam, LPARAM /*lParam*/) void CMarkerPalette::SelectMarker(MarkID mid) { size_t nGrp = m_pDoc->GetMarkManager().FindMarkInMarkSet(mid); - ASSERT(nGrp != Invalid_v); + wxASSERT(nGrp != Invalid_v); size_t nSel = GetSelectedMarkerGroup(); if (nSel != nGrp) { - m_comboMGrp.SetCurSel(FindMarkerGroupIndex(nGrp)); + m_comboMGrp->SetSelection(FindMarkerGroupIndex(nGrp)); UpdateMarkerList(); } - m_listMark.SelectMarker(mid); + m_listMark->SelectMarker(mid); } ///////////////////////////////////////////////////////////////////////////// @@ -280,26 +291,26 @@ void CMarkerPalette::Serialize(CArchive& ar) { if (ar.IsStoring()) { - ar << (DWORD)m_comboMGrp.GetCurSel(); - ar << (DWORD)m_listMark.GetTopIndex(); - ar << (DWORD)m_listMark.GetCurSel(); + ar << static_cast(value_preserving_cast(m_comboMGrp->GetSelection())); + ar << static_cast(value_preserving_cast(m_listMark->GetVisibleRowsBegin())); + ar << static_cast(value_preserving_cast(m_listMark->GetSelection())); } else { if (CGamDoc::GetLoadingVersion() >= NumVersion(2, 90)) // V2.90 { - DWORD dwTmp; - ar >> dwTmp; m_nComboIndex = (int)dwTmp; - ar >> dwTmp; m_nListTopindex = (int)dwTmp; - ar >> dwTmp; m_nListCurSel = (int)dwTmp; + uint32_t dwTmp; + ar >> dwTmp; m_nComboIndex = dwTmp; + ar >> dwTmp; m_nListTopindex = dwTmp; + ar >> dwTmp; m_nListCurSel = dwTmp; m_bStateVarsArmed = TRUE; // Inform Create() data is good } else if (CGamDoc::GetLoadingVersion() >= NumVersion(2, 0)) // V2.0 { - DWORD dwTmp; - ar >> dwTmp; m_nComboIndex = (int)dwTmp; - ar >> dwTmp; m_nListTopindex = (int)dwTmp; - ar >> dwTmp; m_nListCurSel = (int)dwTmp; + uint32_t dwTmp; + ar >> dwTmp; m_nComboIndex = dwTmp; + ar >> dwTmp; m_nListTopindex = dwTmp; + ar >> dwTmp; m_nListCurSel = dwTmp; CWinPlacement wndSink; ar >> wndSink; // Eat this puppy m_bStateVarsArmed = TRUE; // Inform Create() data is good @@ -307,7 +318,7 @@ void CMarkerPalette::Serialize(CArchive& ar) else // Pre V2.0 data { // Just eat the old data and go with the defaults - short sTmp; + uint16_t sTmp; ar >> sTmp; ar >> sTmp; ar >> sTmp; @@ -322,13 +333,13 @@ void CMarkerPalette::LoadMarkerNameList() { CMarkManager& pMMgr = m_pDoc->GetMarkManager(); - m_comboMGrp.ResetContent(); + m_comboMGrp->Clear(); for (size_t i = size_t(0); i < pMMgr.GetNumMarkSets(); i++) { - int nIdx = m_comboMGrp.AddString(pMMgr.GetMarkSet(i).GetName()); - m_comboMGrp.SetItemData(nIdx, value_preserving_cast(i)); // Store the marker index in the data item + int nIdx = m_comboMGrp->Append(pMMgr.GetMarkSet(i).GetName()); + m_comboMGrp->SetClientData(value_preserving_cast(nIdx), reinterpret_cast(value_preserving_cast(i))); // Store the marker index in the data item } - m_comboMGrp.SetCurSel(0); + m_comboMGrp->SetSelection(0); UpdateMarkerList(); } @@ -340,8 +351,8 @@ void CMarkerPalette::UpdatePaletteContents() if (nSel == Invalid_v) nSel = 0; // Force first entry (if any) LoadMarkerNameList(); - if (value_preserving_cast(nSel) < m_comboMGrp.GetCount()) - m_comboMGrp.SetCurSel(FindMarkerGroupIndex(nSel)); + if (nSel < m_comboMGrp->GetCount()) + m_comboMGrp->SetSelection(FindMarkerGroupIndex(nSel)); UpdateMarkerList(); } @@ -354,7 +365,7 @@ void CMarkerPalette::UpdateMarkerList() size_t nSel = GetSelectedMarkerGroup(); if (nSel == Invalid_v) { - m_listMark.SetItemMap(NULL); + m_listMark->SetItemMap(NULL); return; } @@ -374,13 +385,14 @@ void CMarkerPalette::UpdateMarkerList() m_dummyArray.push_back(pMarkTbl->front()); pMarkTbl = &m_dummyArray; } - m_listMark.SetTrayContentVisibility(pMSet.GetMarkerTrayContentVisibility(), str); - m_listMark.SetItemMap(pMarkTbl); + m_listMark->SetTrayContentVisibility(pMSet.GetMarkerTrayContentVisibility(), str); + m_listMark->SetItemMap(pMarkTbl); } ///////////////////////////////////////////////////////////////////////////// // CMarkerPalette message handlers +#if 0 BOOL CMarkerPalette::OnEraseBkgnd(CDC* pDC) { return TRUE; // controls take care of erase @@ -415,23 +427,33 @@ void CMarkerPalette::OnWindowPosChanging(WINDOWPOS FAR* lpwndpos) if (m_comboMGrp.m_hWnd != NULL) m_comboMGrp.ShowDropDown(FALSE); } +#endif -void CMarkerPalette::OnMarkerNameCbnSelchange() +void CMarkerPalette::OnMarkerNameCbnSelchange(wxCommandEvent& /*event*/) { UpdateMarkerList(); } +#if 0 BOOL CMarkerPalette::OnHelpInfo(HELPINFO* pHelpInfo) { GetApp()->DoHelpTopic("gp-ref-pal-markers.htm"); return TRUE; } +#endif CMarkerPaletteContainer::CMarkerPaletteContainer(CGamDoc& pDoc) : + CB::wxNativeContainerWindowMixin(static_cast(*this)), child(new CMarkerPalette(*this, pDoc)) { } +void CMarkerPaletteContainer::SetDockingFrame(CDockMarkPalette* pDockingFrame) +{ + m_pDockingFrame = pDockingFrame; + SetParent(pDockingFrame); +} + BOOL CMarkerPaletteContainer::Create(CWnd& pOwnerWnd/*, DWORD dwStyle = 0, UINT nID = 0*/) { DWORD dwStyle = WS_CHILD | WS_VISIBLE; @@ -470,6 +492,6 @@ void CMarkerPaletteContainer::OnSetFocus(CWnd* pOldWnd) void CMarkerPaletteContainer::OnSize(UINT nType, int cx, int cy) { - child->MoveWindow(0, 0, cx, cy); + child->SetSize(0, 0, cx, cy); return CWnd::OnSize(nType, cx, cy); } diff --git a/GP/PalMark.h b/GP/PalMark.h index d9818af4..e1e92c35 100644 --- a/GP/PalMark.h +++ b/GP/PalMark.h @@ -37,11 +37,13 @@ class CGamDoc; class CMarkerPaletteContainer; +class CDockMarkPalette; +class WinStateRestoreEvent; ///////////////////////////////////////////////////////////////////////////// // CMarkerPalette window - Marker palette's are part of the document object. -class CMarkerPalette : public CWnd +class CMarkerPalette : public wxPanel { // Construction public: @@ -59,7 +61,7 @@ class CMarkerPalette : public CWnd void SelectMarker(MarkID mid); - void Serialize(CArchive &ar) override; + void Serialize(CArchive &ar); // Implementation protected: @@ -73,8 +75,8 @@ class CMarkerPalette : public CWnd std::vector m_dummyArray; // Enclosed controls.... - CComboBox m_comboMGrp; - CMarkListBox m_listMark; + CB::propagate_const m_comboMGrp; + CB::propagate_const m_listMark; void LoadMarkerNameList(); void UpdateMarkerList(); @@ -84,40 +86,44 @@ class CMarkerPalette : public CWnd // Some temporary vars used during windows position restoration. // They are loaded during the de-serialization process. BOOL m_bStateVarsArmed; // Set so state restore is one-shot process - int m_nComboIndex; - int m_nListTopindex; - int m_nListCurSel; + uint32_t m_nComboIndex; + uint32_t m_nListTopindex; + uint32_t m_nListCurSel; int m_nComboHeight; // Implementation public: - // Generated message map functions protected: - //{{AFX_MSG(CMarkerPalette) +#if 0 afx_msg BOOL OnEraseBkgnd(CDC* pDC); afx_msg void OnSize(UINT nType, int cx, int cy); afx_msg void OnDestroy(); afx_msg void OnWindowPosChanging(WINDOWPOS FAR* lpwndpos); - afx_msg void OnMarkerNameCbnSelchange(); - afx_msg LRESULT OnOverrideSelectedItem(WPARAM wParam, LPARAM lParam); - afx_msg LRESULT OnGetDragSize(WPARAM wParam, LPARAM lParam); +#endif + void OnMarkerNameCbnSelchange(wxCommandEvent& /*event*/); + void OnOverrideSelectedItem(OverrideSelectedItemEvent& event); + void OnGetDragSize(GetDragSizeEvent& event); +#if 0 afx_msg BOOL OnHelpInfo(HELPINFO* pHelpInfo); afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); - //}}AFX_MSG - afx_msg LRESULT OnPaletteHide(WPARAM, LPARAM); - afx_msg LRESULT OnMessageRestoreWinState(WPARAM, LPARAM); +#endif + void OnPaletteHide(wxCommandEvent& event); + void OnMessageRestoreWinState(WinStateRestoreEvent& event); - DECLARE_MESSAGE_MAP() + wxDECLARE_EVENT_TABLE(); }; -class CMarkerPaletteContainer : public CWnd +class CMarkerPaletteContainer : public CWnd, + public CB::wxNativeContainerWindowMixin { public: CMarkerPaletteContainer(CGamDoc& pDoc); BOOL Create(CWnd& pOwnerWnd/*, DWORD dwStyle = 0, UINT nID = 0*/); +#if 0 void PostNcDestroy() override; +#endif operator const CMarkerPalette&() const { return *child; } operator CMarkerPalette&() @@ -130,16 +136,12 @@ class CMarkerPaletteContainer : public CWnd return const_cast(std::as_const(*this).operator->()); } - const CDockablePane* GetDockingFrame() const { return m_pDockingFrame.get(); } - CDockablePane* GetDockingFrame() - { - return const_cast(std::as_const(*this).GetDockingFrame()); - } - void SetDockingFrame(CDockablePane* pDockingFrame) + const CDockMarkPalette* GetDockingFrame() const { return m_pDockingFrame.get(); } + CDockMarkPalette* GetDockingFrame() { - m_pDockingFrame = pDockingFrame; - SetParent(pDockingFrame); + return const_cast(std::as_const(*this).GetDockingFrame()); } + void SetDockingFrame(CDockMarkPalette* pDockingFrame); void Serialize(CArchive& ar) override { wxASSERT(false); AfxThrowNotSupportedException(); } @@ -149,8 +151,9 @@ class CMarkerPaletteContainer : public CWnd afx_msg void OnSize(UINT nType, int cx, int cy); DECLARE_MESSAGE_MAP() - CB::propagate_const m_pDockingFrame = nullptr; - OwnerPtr child; + CB::propagate_const m_pDockingFrame = nullptr; + // owned by wx + CB::propagate_const child = nullptr; }; ///////////////////////////////////////////////////////////////////////////// diff --git a/GP/VwPbrd.cpp b/GP/VwPbrd.cpp index c6e1744b..e1a77015 100644 --- a/GP/VwPbrd.cpp +++ b/GP/VwPbrd.cpp @@ -1,6 +1,6 @@ // VwPbrd.cpp : implementation of the CPlayBoardView class // -// Copyright (c) 1994-2025 By Dale L. Larson & William Su, All Rights Reserved. +// Copyright (c) 1994-2026 By Dale L. Larson & William Su, All Rights Reserved. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the @@ -696,7 +696,7 @@ void CPlayBoardView::OnDragItem(DragDropEvent& event) if (pdi.GetDragType() == DRAG_MARKER) { - DoDragMarker(pdi); + DoDragMarker(event); return; } @@ -809,36 +809,56 @@ void CPlayBoardView::DoDragPieceList(const DragInfoWx& pdi) #define MARKER_DROP_GAP_X 8 -void CPlayBoardView::DoDragMarker(const DragInfoWx& pdi) +void CPlayBoardView::DoDragMarker(DragDropEvent& event) { + const DragInfoWx& pdi = event.GetDragInfo(); wxASSERT(pdi.GetDragType() == DRAG_MARKER); CGamDoc& pDoc = GetDocument(); if (pdi.GetSubInfo().m_gamDoc != &pDoc) return; // Only markers from our document. -#if 0 + // allow autoscroll while this is drag destination + switch (pdi.m_phase) + { + case PhaseDrag::Enter: + EnableAutoscrollWithoutCapture(); + break; + case PhaseDrag::Exit: + case PhaseDrag::Drop: + DisableAutoscrollWithoutCapture(); + break; + } + // if marker can't fit on board, reject drop - CSize limit = m_pPBoard->GetBoard()->GetSize(fullScale); - if (pdi.GetSubInfo().m_size.cx > limit.cx || - pdi.GetSubInfo().m_size.cy > limit.cy) + wxSize limit = CB::Convert(m_pPBoard->GetBoard()->GetSize(fullScale)); + if (pdi.GetSubInfo().m_size.x > limit.x || + pdi.GetSubInfo().m_size.y > limit.y) { - return pdi.m_phase == PhaseDrag::Over ? - reinterpret_cast(g_res.hcrNoDropTooBig) - : - -1; + if (pdi.m_phase == PhaseDrag::Over) + { + event.SetCursor(g_res.hcrNoDropTooBigWx); + } + return; } +#if 0 if (pdi.m_phase == PhaseDrag::Exit) DragKillAutoScroll(); else if (pdi.m_phase == PhaseDrag::Over) +#else + if (pdi.m_phase == PhaseDrag::Over) +#endif { +#if 0 DragCheckAutoScroll(); - return (LRESULT)(LPVOID)pdi.m_hcsrSuggest; +#endif + event.SetCursor(pdi.m_hcsrSuggest); + return; } else if (pdi.m_phase == PhaseDrag::Drop) { CMarkManager& pMMgr = pDoc.GetMarkManager(); - CPoint pnt = pdi.m_point; + wxPoint pnt = pdi.m_point; MarkID mid = pdi.GetSubInfo().m_markID; pnt = ClientToWorkspace(pnt); @@ -846,13 +866,13 @@ void CPlayBoardView::DoDragMarker(const DragInfoWx& pdi) // deliver random markers, prompt for a count of markers // and randomly select that many of them. The snap grid is // ignored for this sort of placement. - if (GetKeyState(VK_CONTROL) < 0) + if (wxGetKeyState(WXK_CONTROL)) { // I'm going to cheat. I happen to know that marker drops // can only originate at the marker palette. I can find out // the current marker set this way. - size_t nMrkGrp = pDoc.m_palMark.GetSelectedMarkerGroup(); - ASSERT(nMrkGrp != Invalid_v); + size_t nMrkGrp = (*pDoc.m_palMark)->GetSelectedMarkerGroup(); + wxASSERT(nMrkGrp != Invalid_v); if (nMrkGrp == Invalid_v) goto NASTY_GOTO_TARGET; CMarkSet& pMSet = pMMgr.GetMarkSet(nMrkGrp); @@ -881,48 +901,48 @@ void CPlayBoardView::DoDragMarker(const DragInfoWx& pdi) tblMarks.push_back(mid); // Add the first one that was dropped } // First figure out the minimum size required. - CSize sizeMin(0, 0); + wxSize sizeMin(0, 0); int i; for (i = 0; i < dlg.m_nMarkerCount; i++) { - CSize size = pMMgr.GetMarkSize(tblMarks[value_preserving_cast(i)]); - sizeMin.cx += size.cx; - sizeMin.cy = CB::max(sizeMin.cy, size.cy); + wxSize size = CB::Convert(pMMgr.GetMarkSize(tblMarks[value_preserving_cast(i)])); + sizeMin.x += size.x; + sizeMin.y = CB::max(sizeMin.y, size.y); if (i < dlg.m_nMarkerCount - 1) - sizeMin += CSize(MARKER_DROP_GAP_X, 0); + sizeMin += wxSize(MARKER_DROP_GAP_X, 0); } - CRect rct(CPoint(pnt.x - sizeMin.cx/2, pnt.y - sizeMin.cy), sizeMin); + wxRect rct(wxPoint(pnt.x - sizeMin.x/2, pnt.y - sizeMin.y), sizeMin); rct = LimitRect(rct); // Make sure stays on board. pDoc.AssignNewMoveGroup(); - int x = rct.right; - int y = (rct.top + rct.bottom) / 2; + int x = rct.GetRight(); + int y = (rct.GetTop() + rct.GetBottom()) / 2; // Load the list from right ot left so the objects // show up in the select list in top to bottom // corresponding to left to right. for (i = dlg.m_nMarkerCount - 1; i >= 0; i--) { - CSize size = pMMgr.GetMarkSize(tblMarks[value_preserving_cast(i)]); + wxSize size = CB::Convert(pMMgr.GetMarkSize(tblMarks[value_preserving_cast(i)])); CDrawObj& pObj = pDoc.CreateMarkerObject(m_pPBoard.get(), tblMarks[value_preserving_cast(i)], - CPoint(x - size.cx / 2, y), ObjectID()); - x -= size.cx + MARKER_DROP_GAP_X; + CB::Convert(wxPoint(x - size.x / 2, y)), ObjectID()); + x -= size.x + MARKER_DROP_GAP_X; m_selList.AddObject(pObj, TRUE); } NotifySelectListChange(); - return 1; + return; } NASTY_GOTO_TARGET: m_selList.PurgeList(); // If the snap grid is on, adjust the point. - CSize sz = pMMgr.GetMarkSize(mid); - ASSERT(sz.cx != 0 && sz.cy != 0); - CRect rct(CPoint(pnt.x - sz.cx/2, pnt.y - sz.cy/2), sz); + wxSize sz = CB::Convert(pMMgr.GetMarkSize(mid)); + wxASSERT(sz.x != 0 && sz.y != 0); + wxRect rct(wxPoint(pnt.x - sz.x/2, pnt.y - sz.y/2), sz); rct = AdjustRect(rct); pnt = GetMidRect(rct); pDoc.AssignNewMoveGroup(); - CDrawObj& pObj = pDoc.CreateMarkerObject(m_pPBoard.get(), mid, pnt, ObjectID()); + CDrawObj& pObj = pDoc.CreateMarkerObject(m_pPBoard.get(), mid, CB::Convert(pnt), ObjectID()); // If marker is set to prompt for text on drop, show the // dialog. @@ -940,10 +960,7 @@ void CPlayBoardView::DoDragMarker(const DragInfoWx& pdi) } } } - return 1; -#else - wxASSERT(!"TODO:"); -#endif + return; } void CPlayBoardView::DoDragSelectList(DragDropEvent& event) diff --git a/GP/VwPbrd.h b/GP/VwPbrd.h index 719624ba..f07e0038 100644 --- a/GP/VwPbrd.h +++ b/GP/VwPbrd.h @@ -199,7 +199,7 @@ class CPlayBoardView : public CB::ProcessEventOverride }; void DoDragPiece(const DragInfoWx& pdi); - void DoDragMarker(const DragInfoWx& pdi); + void DoDragMarker(DragDropEvent& event); void DoDragPieceList(const DragInfoWx& pdi); void DoDragSelectList(DragDropEvent& event); diff --git a/GShr/LBoxGrfx.h b/GShr/LBoxGrfx.h index 38b20fbe..c644a6eb 100644 --- a/GShr/LBoxGrfx.h +++ b/GShr/LBoxGrfx.h @@ -803,25 +803,17 @@ class CGrafixListBoxDataWx : public BASE_WND // The parent may want to override the value. if (BASE_WND::di.GetDragType() == DRAG_MARKER) { - wxASSERT(!"TODO:"); -#if 0 OverrideSelectedItemEvent oi(BASE_WND::di.GetSubInfo().m_markID); - CWnd* pWnd = this->GetParent(); - ASSERT(pWnd != NULL); - pWnd->SendMessage(WM_OVERRIDE_SELECTED_ITEM, reinterpret_cast(&oi)); -#endif + wxWindow* pWnd = this->GetParent(); + wxASSERT(pWnd != NULL); + pWnd->ProcessWindowEvent(oi); } else if (BASE_WND::di.GetDragType() == DRAG_TILE) { -#if defined(GPLAY) - wxASSERT(!"TODO:"); -#if 0 OverrideSelectedItemEvent oi(BASE_WND::di.GetSubInfo().m_tileID); - CWnd* pWnd = this->GetParent(); - ASSERT(pWnd != NULL); - pWnd->SendMessage(WM_OVERRIDE_SELECTED_ITEM, reinterpret_cast(&oi)); -#endif -#endif + wxWindow* pWnd = this->GetParent(); + wxASSERT(pWnd != NULL); + pWnd->ProcessWindowEvent(oi); } else { diff --git a/GShr/LBoxMark.cpp b/GShr/LBoxMark.cpp index 30b9b615..64b2cbc2 100644 --- a/GShr/LBoxMark.cpp +++ b/GShr/LBoxMark.cpp @@ -1,6 +1,6 @@ // LBoxMark.cpp // -// Copyright (c) 1994-2024 By Dale L. Larson & William Su, All Rights Reserved. +// Copyright (c) 1994-2026 By Dale L. Larson & William Su, All Rights Reserved. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the @@ -333,42 +333,44 @@ BOOL CMarkListBoxWx::OnDoesItemHaveTipText(size_t nItem) const ///////////////////////////////////////////////////////////////////////////// -#if 0 -void CMarkListBox::SelectMarker(MarkID mid) +void CMarkListBoxWx::SelectMarker(MarkID mid) { size_t nIndex = MapItemToIndex(mid); // NO LONGER IMPOSSIBLE SINCE HIDE ALL MARKERS. ASSERT(nIndex != -1); if (nIndex == Invalid_v) { - if (GetCount() >= 1) - SetCurSel(0); // Just select the first one. + if (GetItemCount() >= 1) + SetSelection(0); // Just select the first one. } else { - ShowListIndex(value_preserving_cast(nIndex)); - SetCurSel(value_preserving_cast(nIndex)); + ShowListIndex(nIndex); + SetSelection(value_preserving_cast(nIndex)); } } ///////////////////////////////////////////////////////////////////////////// -void CMarkListBox::ShowListIndex(int nPos) +void CMarkListBoxWx::ShowListIndex(size_t nPos) { - if (nPos < GetTopIndex()) + if (nPos < GetVisibleRowsBegin()) { - SetTopIndex(nPos); + ScrollToRow(nPos); return; } +#if 0 CRect rct; GetItemRect(nPos, &rct); CRect rctClient; GetClientRect(&rctClient); if (rct.IntersectRect(&rct, &rctClient)) +#else + if (IsRowVisible(nPos)) +#endif return; - SetTopIndex(nPos); + ScrollToRow(nPos); } -#endif ///////////////////////////////////////////////////////////////////////////// @@ -424,8 +426,7 @@ void CMarkListBoxWx::OnDrawItem(wxDC& pDC, const wxRect& rctItem, size_t nIndex) } } -#if 0 -BOOL CMarkListBox::OnDragSetup(DragInfo& pDI) const +BOOL CMarkListBoxWx::OnDragSetup(DragInfoWx& pDI) const { #ifdef GPLAY if (m_pDoc->IsPlaying()) @@ -438,8 +439,7 @@ BOOL CMarkListBox::OnDragSetup(DragInfo& pDI) const pDI.GetSubInfo().m_markID = GetCurMapItem(); pDI.GetSubInfo().m_size = GetDragSize(); pDI.GetSubInfo().m_gamDoc = m_pDoc; - pDI.m_hcsrSuggest = g_res.hcrDragTile; + pDI.m_hcsrSuggest = g_res.hcrDragTileWx; return TRUE; } -#endif diff --git a/GShr/LBoxMark.h b/GShr/LBoxMark.h index a40e83bf..addde736 100644 --- a/GShr/LBoxMark.h +++ b/GShr/LBoxMark.h @@ -127,10 +127,8 @@ class CMarkListBoxWx : public CGrafixListBoxDataWx m_pDoc = pDoc; } -#if 0 void SelectMarker(MarkID mid); - void ShowListIndex(int nPos); -#endif + void ShowListIndex(size_t nPos); // Implementation protected: @@ -141,9 +139,7 @@ class CMarkListBoxWx : public CGrafixListBoxDataWx // Overrides wxSize GetItemSize(size_t nIndex) const override; void OnDrawItem(wxDC& pDC, const wxRect& rctItem, size_t nIndex) const override; -#if 0 - virtual BOOL OnDragSetup(DragInfo& pDI) const override; -#endif + BOOL OnDragSetup(DragInfoWx& pDI) const override; // Tool tip processing virtual BOOL OnIsToolTipsEnabled() const override; From 9ca45bb3c627e9cb7ad4e5ebfc7ec81bb1d5ee83 Mon Sep 17 00:00:00 2001 From: Bill Su Date: Thu, 5 Feb 2026 22:41:57 -0500 Subject: [PATCH 61/80] Versions: templatize CArchive& << and CArchive& >> --- GShr/Versions.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/GShr/Versions.h b/GShr/Versions.h index 148e8823..0e258eab 100644 --- a/GShr/Versions.h +++ b/GShr/Versions.h @@ -865,7 +865,8 @@ inline CArchive& operator>>(CArchive& ar, T& v) return ar; } -inline CArchive& operator<<(CArchive& ar, const std::vector& v) +template +CArchive& operator<<(CArchive& ar, const std::vector& v) { CB::WriteCount(ar, v.size()); for (size_t i = size_t(0) ; i < v.size() ; ++i) @@ -875,7 +876,8 @@ inline CArchive& operator<<(CArchive& ar, const std::vector& v) return ar; } -inline CArchive& operator>>(CArchive& ar, std::vector& v) +template +CArchive& operator>>(CArchive& ar, std::vector& v) { size_t size = CB::ReadCount(ar); v.resize(size); From bb2740763b6b65e80dea2f243f53d89150a8a7b3 Mon Sep 17 00:00:00 2001 From: Bill Su Date: Wed, 4 Feb 2026 23:44:02 -0500 Subject: [PATCH 62/80] PalTray: code cleanup improve type/const/null/override/CArray/deadcode correctness --- GP/FrmMain.cpp | 22 ++++++++++---------- GP/FrmMain.h | 10 ++++----- GP/GamDoc.cpp | 20 +++++++++--------- GP/GamDoc2.cpp | 2 +- GP/GamDoc3.cpp | 2 +- GP/GamDoc5.cpp | 2 +- GP/PalTray.cpp | 55 +++++++++++++++++++++++++++++--------------------- GP/PalTray.h | 30 +++++++++++++-------------- 8 files changed, 75 insertions(+), 68 deletions(-) diff --git a/GP/FrmMain.cpp b/GP/FrmMain.cpp index b04e844e..8b4e9cdc 100644 --- a/GP/FrmMain.cpp +++ b/GP/FrmMain.cpp @@ -1,6 +1,6 @@ // FrmMain.cpp : implementation of the CMainFrame class // -// Copyright (c) 1994-2024 By Dale L. Larson & William Su, All Rights Reserved. +// Copyright (c) 1994-2026 By Dale L. Larson & William Su, All Rights Reserved. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the @@ -437,36 +437,36 @@ void CMainFrame::ShowPalettePanes(BOOL bShow) /////////////////////////////////////////////////////////////////////// -void CMainFrame::UpdatePaletteWindow(CWnd* pWnd, BOOL bIsOn) +void CMainFrame::UpdatePaletteWindow(CWnd& pWnd, BOOL bIsOn) { - if (pWnd->m_hWnd != NULL) // Handle exists if palette allowed + if (pWnd.m_hWnd != NULL) // Handle exists if palette allowed { - BOOL bIsControlBar = pWnd->IsKindOf(RUNTIME_CLASS(CBasePane)); - BOOL bVisible = ((pWnd->GetStyle() & WS_VISIBLE) != 0); + BOOL bIsControlBar = pWnd.IsKindOf(RUNTIME_CLASS(CBasePane)); + BOOL bVisible = ((pWnd.GetStyle() & WS_VISIBLE) != 0); CMDIChildWndEx* pMDIChild = (CMDIChildWndEx*)MDIGetActive(); if (pMDIChild == NULL || pMDIChild->IsIconic()) { if (!bIsControlBar && bVisible) - pWnd->ShowWindow(SW_HIDE); + pWnd.ShowWindow(SW_HIDE); else if (bIsControlBar && bVisible) - ShowPane((CBasePane*)pWnd, FALSE, FALSE, FALSE); + ShowPane(&dynamic_cast(pWnd), FALSE, FALSE, FALSE); } else { if (bIsOn && !bVisible) { if (!bIsControlBar) - pWnd->ShowWindow(SW_SHOW); + pWnd.ShowWindow(SW_SHOW); else - ShowPane((CBasePane*)pWnd, TRUE, FALSE, FALSE); + ShowPane(&dynamic_cast(pWnd), TRUE, FALSE, FALSE); } else if (!bIsOn && bVisible) { if (!bIsControlBar) - pWnd->ShowWindow(SW_HIDE); + pWnd.ShowWindow(SW_HIDE); else - ShowPane((CBasePane*)pWnd, FALSE, FALSE, FALSE); + ShowPane(&dynamic_cast(pWnd), FALSE, FALSE, FALSE); } } } diff --git a/GP/FrmMain.h b/GP/FrmMain.h index 7021ec1f..b1326a35 100644 --- a/GP/FrmMain.h +++ b/GP/FrmMain.h @@ -1,6 +1,6 @@ // FrmMain.h : interface of the CMainFrame class // -// Copyright (c) 1994-2020 By Dale L. Larson, All Rights Reserved. +// Copyright (c) 1994-2026 By Dale L. Larson & William Su, All Rights Reserved. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the @@ -52,16 +52,16 @@ class CMainFrame : public CMDIFrameWndExCb, CDocument* GetCurrentDocument(); CDockMarkPalette& GetDockingMarkerWindow() { return m_wndMarkPal; } - CDockTrayPalette* GetDockingTrayAWindow() { return &m_wndTrayPalA; } - CDockTrayPalette* GetDockingTrayBWindow() { return &m_wndTrayPalB; } + CDockTrayPalette& GetDockingTrayAWindow() { return m_wndTrayPalA; } + CDockTrayPalette& GetDockingTrayBWindow() { return m_wndTrayPalB; } - CReadMsgWnd* GetMessageWindow() { return &m_wndMessage; } + CReadMsgWnd& GetMessageWindow() { return m_wndMessage; } CMFCStatusBar* GetStatusBar() { return &m_wndStatusBar; } // Operations public: - void UpdatePaletteWindow(CWnd* pWnd, BOOL bIsOn); + void UpdatePaletteWindow(CWnd& pWnd, BOOL bIsOn); void ShowPalettePanes(BOOL bShow); void OnIdle(); BOOL OnCloseMiniFrame(CPaneFrameWnd* pWnd) override; diff --git a/GP/GamDoc.cpp b/GP/GamDoc.cpp index 1078f42f..37ea6ac8 100644 --- a/GP/GamDoc.cpp +++ b/GP/GamDoc.cpp @@ -354,20 +354,18 @@ void CGamDoc::DeleteContents() so close before delete */ if (m_palTrayA) { - CDockTrayPalette* pFrame = static_cast(m_palTrayA->GetDockingFrame()); + CDockTrayPalette* pFrame = m_palTrayA->GetDockingFrame(); if (pFrame) { - ASSERT_KINDOF(CDockTrayPalette, pFrame); pFrame->SetChild(NULL); // Need to remove pointer from Tray's UI Frame. } m_palTrayA = nullptr; } if (m_palTrayB) { - CDockTrayPalette* pFrame = static_cast(m_palTrayB->GetDockingFrame()); + CDockTrayPalette* pFrame = m_palTrayB->GetDockingFrame(); if (pFrame) { - ASSERT_KINDOF(CDockTrayPalette, pFrame); pFrame->SetChild(NULL); // Need to remove pointer from Tray's UI Frame. } m_palTrayB = nullptr; @@ -448,19 +446,19 @@ void CGamDoc::OnIdle(BOOL bActive) CDockMarkPalette& pDockMark = pMFrame->GetDockingMarkerWindow(); pDockMark.SetChild(&*m_palMark); - pMFrame->UpdatePaletteWindow(&pDockMark, m_bMarkPalVisible); + pMFrame->UpdatePaletteWindow(pDockMark, m_bMarkPalVisible); - CDockTrayPalette* pDockTrayA = pMFrame->GetDockingTrayAWindow(); - pDockTrayA->SetChild(&*m_palTrayA); + CDockTrayPalette& pDockTrayA = pMFrame->GetDockingTrayAWindow(); + pDockTrayA.SetChild(&*m_palTrayA); pMFrame->UpdatePaletteWindow(pDockTrayA, m_bTrayAVisible); - CDockTrayPalette* pDockTrayB = pMFrame->GetDockingTrayBWindow(); - pDockTrayB->SetChild(&*m_palTrayB); + CDockTrayPalette& pDockTrayB = pMFrame->GetDockingTrayBWindow(); + pDockTrayB.SetChild(&*m_palTrayB); pMFrame->UpdatePaletteWindow(pDockTrayB, m_bTrayBVisible); - CReadMsgWnd* pDocMsg = pMFrame->GetMessageWindow(); + CReadMsgWnd& pDocMsg = pMFrame->GetMessageWindow(); pMFrame->UpdatePaletteWindow(pDocMsg, m_bMsgWinVisible && !IsScenario()); - pDocMsg->SetText(this); + pDocMsg.SetText(this); } } diff --git a/GP/GamDoc2.cpp b/GP/GamDoc2.cpp index 20d93cad..1944f792 100644 --- a/GP/GamDoc2.cpp +++ b/GP/GamDoc2.cpp @@ -184,7 +184,7 @@ void CGamDoc::SaveRecordedMoves() m_strCurMsg.clear(); m_astrMsgHist.clear(); - GetMainFrame()->GetMessageWindow()->SetText(NULL); + GetMainFrame()->GetMessageWindow().SetText(NULL); // Save was ok..add to game history AddMovesToGameHistoryTable(pHist); diff --git a/GP/GamDoc3.cpp b/GP/GamDoc3.cpp index c7548023..97002dee 100644 --- a/GP/GamDoc3.cpp +++ b/GP/GamDoc3.cpp @@ -526,7 +526,7 @@ void CGamDoc::SerializeGame(CArchive& ar) } GetTrayManager().PropagateOwnerMaskToAllPieces(this); GetPBoardManager().PropagateOwnerMaskToAllPieces(); - GetMainFrame()->GetMessageWindow()->SetText(this); + GetMainFrame()->GetMessageWindow().SetText(this); } } diff --git a/GP/GamDoc5.cpp b/GP/GamDoc5.cpp index c89b0b69..e94e9e7d 100644 --- a/GP/GamDoc5.cpp +++ b/GP/GamDoc5.cpp @@ -364,7 +364,7 @@ void CGamDoc::MsgSetMessageText(const CB::string& str) else m_strCurMsg = str; - GetMainFrame()->GetMessageWindow()->SetText(this); + GetMainFrame()->GetMessageWindow().SetText(this); if (!IsQuietPlayback() && !m_bMsgWinVisible) m_bMsgWinVisible = TRUE; } diff --git a/GP/PalTray.cpp b/GP/PalTray.cpp index 61f0a8b9..c1bac800 100644 --- a/GP/PalTray.cpp +++ b/GP/PalTray.cpp @@ -1,6 +1,6 @@ // PalTray.cpp : implementation file // -// Copyright (c) 1994-2025 By Dale L. Larson & William Su, All Rights Reserved. +// Copyright (c) 1994-2026 By Dale L. Larson & William Su, All Rights Reserved. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the @@ -117,13 +117,13 @@ CTrayPalette::CTrayPalette(CGamDoc& pDoc, UINT palID) : SetPaletteID(palID); } -BOOL CTrayPalette::Create(CWnd* pOwnerWnd, DWORD dwStyle, UINT nID) +BOOL CTrayPalette::Create(CWnd& pOwnerWnd/*, DWORD dwStyle, UINT nID*/) { LoadMenuButtonBitmap(); - dwStyle |= WS_CHILD | WS_VISIBLE; + DWORD dwStyle = WS_CHILD | WS_VISIBLE; if (!CWnd::Create(AfxRegisterWndClass(0), NULL, dwStyle, - CRect(0, 0, 200, 100), pOwnerWnd, nID)) + CRect(0, 0, 200, 100), &pOwnerWnd, 0)) { TRACE("Failed to create Tray palette window.\n"); return FALSE; @@ -135,6 +135,12 @@ BOOL CTrayPalette::Create(CWnd* pOwnerWnd, DWORD dwStyle, UINT nID) return TRUE; } +void CTrayPalette::SetDockingFrame(CDockTrayPalette* pDockingFrame) +{ + m_pDockingFrame = pDockingFrame; + SetParent(pDockingFrame); +} + int CTrayPalette::OnCreate(LPCREATESTRUCT lpCreateStruct) { m_rctMenuBtn.left = 0; @@ -215,7 +221,7 @@ void CTrayPalette::DoEditSelectedPieceText() ///////////////////////////////////////////////////////////////////////////// -size_t CTrayPalette::GetSelectedTray() +size_t CTrayPalette::GetSelectedTray() const { int nSel = m_comboYGrp.GetCurSel(); if (nSel < 0) @@ -223,7 +229,7 @@ size_t CTrayPalette::GetSelectedTray() return value_preserving_cast(m_comboYGrp.GetItemData(nSel)); } -int CTrayPalette::FindTrayIndex(size_t nTrayNum) +int CTrayPalette::FindTrayIndex(size_t nTrayNum) const { if (m_comboYGrp.GetCount() <= 0) return -1; @@ -253,7 +259,7 @@ LRESULT CTrayPalette::OnMessageRestoreWinState(WPARAM, LPARAM) UpdateTrayList(); - for (int i = 0; i < m_tblListBoxSel.GetSize(); i++) + for (size_t i = size_t(0) ; i < m_tblListBoxSel.size() ; ++i) m_listTray.SetSel(m_tblListBoxSel[i]); m_listTray.SetTopIndex(m_nListTopindex); @@ -455,11 +461,11 @@ void CTrayPalette::Serialize(CArchive& ar) ar << (DWORD)m_listTray.GetTopIndex(); // Save the indexes of all the selected items. - m_tblListBoxSel.RemoveAll(); + m_tblListBoxSel.clear(); int nNumSelected = m_listTray.GetSelCount(); - m_tblListBoxSel.SetSize(nNumSelected); - m_listTray.GetSelItems(nNumSelected, m_tblListBoxSel.GetData()); + m_tblListBoxSel.resize(value_preserving_cast(nNumSelected)); + m_listTray.GetSelItems(nNumSelected, m_tblListBoxSel.data()); ar << m_tblListBoxSel; } else @@ -563,7 +569,7 @@ void CTrayPalette::DeselectAll() } void CTrayPalette::SelectTrayPiece(size_t nGroup, PieceID pid, - const CB::string* pszNotificationTip /* = NULL */) + const CB::string* pszNotificationTip) { size_t nSel = GetSelectedTray(); if (nSel != nGroup) @@ -1020,13 +1026,16 @@ void CTrayPalette::OnUpdateEditElementText(CCmdUI* pCmdUI) BOOL CTrayPalette::OnActTurnOver(UINT id) { - CArray tblListSel; + std::vector tblListSel; int nNumSelected = m_listTray.GetSelCount(); - tblListSel.SetSize(nNumSelected); - m_listTray.GetSelItems(nNumSelected, tblListSel.GetData()); + if (nNumSelected) + { + tblListSel.resize(value_preserving_cast(nNumSelected)); + m_listTray.GetSelItems(nNumSelected, &tblListSel.front()); + } - CArray tblListSubjects; - CArray* chosen; + std::vector tblListSubjects; + std::vector* chosen; switch (id) { @@ -1040,16 +1049,16 @@ BOOL CTrayPalette::OnActTurnOver(UINT id) case ID_ACT_TURNOVER_ALL_PREV: case ID_ACT_TURNOVER_ALL_RANDOM: // operate on all pieces - tblListSubjects.SetSize(m_listTray.GetCount()); + tblListSubjects.resize(value_preserving_cast(m_listTray.GetCount())); for (int i = 0; i < m_listTray.GetCount(); i++) { - tblListSubjects[i] = i; + tblListSubjects[value_preserving_cast(i)] = i; } chosen = &tblListSubjects; break; case ID_ACT_TURNOVER_SELECT: // operate on clicked side - tblListSubjects.Add(value_preserving_cast(m_listTray.MapItemToIndex(static_cast(menuGameElement)))); + tblListSubjects.push_back(value_preserving_cast(m_listTray.MapItemToIndex(static_cast(menuGameElement)))); chosen = &tblListSubjects; break; default: @@ -1083,11 +1092,11 @@ BOOL CTrayPalette::OnActTurnOver(UINT id) size_t nSel = GetSelectedTray(); if (m_pDoc->IsRecording() && flip == CPieceTable::fRandom) { - CB::string strMsg = CB::string::Format(IDS_TIP_TRAY_FLIPPED_RANDOM, chosen->GetCount()); - m_pDoc->RecordEventMessage(strMsg, nSel, m_listTray.MapIndexToItem(value_preserving_cast((*chosen)[0]))); + CB::string strMsg = CB::string::Format(IDS_TIP_TRAY_FLIPPED_RANDOM, chosen->size()); + m_pDoc->RecordEventMessage(strMsg, nSel, m_listTray.MapIndexToItem(value_preserving_cast(chosen->front()))); } - for (int i = 0; i < chosen->GetSize(); i++) + for (size_t i = size_t(0) ; i < chosen->size() ; ++i) { PieceID pid = m_listTray.MapIndexToItem(value_preserving_cast((*chosen)[i])); size_t side; @@ -1108,7 +1117,7 @@ BOOL CTrayPalette::OnActTurnOver(UINT id) /* flipping pieces shouldn't change tray content, so restore selections */ - for (int i = 0; i < tblListSel.GetSize(); i++) + for (size_t i = size_t(0) ; i < tblListSel.size() ; ++i) { m_listTray.SetSel(tblListSel[i], true); } diff --git a/GP/PalTray.h b/GP/PalTray.h index 7bb19053..760ccc8e 100644 --- a/GP/PalTray.h +++ b/GP/PalTray.h @@ -1,6 +1,6 @@ // PalTray.h : header file // -// Copyright (c) 1994-2020 By Dale L. Larson, All Rights Reserved. +// Copyright (c) 1994-2026 By Dale L. Larson & William Su, All Rights Reserved. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the @@ -35,6 +35,7 @@ ///////////////////////////////////////////////////////////////////////////// +class CDockTrayPalette; class CGamDoc; class CTraySet; @@ -50,34 +51,34 @@ class CTrayPalette : public CWnd public: CTrayPalette(CGamDoc& pDoc, UINT palID); - BOOL Create(CWnd* pOwnerWnd, DWORD dwStyle = 0, UINT nID = 0); + BOOL Create(CWnd& pOwnerWnd/*, DWORD dwStyle = 0, UINT nID = 0*/); // Attributes private: void SetPaletteID(UINT nID) { m_nID = nID; } public: - CDockablePane* GetDockingFrame() { return m_pDockingFrame; } - void SetDockingFrame(CDockablePane* pDockingFrame) + const CDockTrayPalette* GetDockingFrame() const { return m_pDockingFrame.get(); } + CDockTrayPalette* GetDockingFrame() { - m_pDockingFrame = pDockingFrame; - SetParent(pDockingFrame); + return const_cast(std::as_const(*this).GetDockingFrame()); } + void SetDockingFrame(CDockTrayPalette* pDockingFrame); // Operations public: void DeselectAll(); - void SelectTrayPiece(size_t nGroup, PieceID pid, const CB::string* pszNotificationTip = NULL); + void SelectTrayPiece(size_t nGroup, PieceID pid, const CB::string* pszNotificationTip); void ShowTrayIndex(size_t nGroup, int nPos); void UpdatePaletteContents(const CTraySet* pTray = NULL); - void Serialize(CArchive &ar); + void Serialize(CArchive &ar) override; // Implementation - vars protected: RefPtr m_pDoc; UINT m_nID; - CDockablePane* m_pDockingFrame; + CB::propagate_const m_pDockingFrame; CBitmap m_bmpMenuBtn; CSize m_sizeMenuBtn; @@ -98,8 +99,8 @@ class CTrayPalette : public CWnd void LoadTrayNameList(); void UpdateTrayList(); - size_t GetSelectedTray(); - int FindTrayIndex(size_t nTrayNum); + size_t GetSelectedTray() const; + int FindTrayIndex(size_t nTrayNum) const; // Some temporary vars used during windows position restoration. // They are loaded during the de-serialization process. @@ -107,13 +108,12 @@ class CTrayPalette : public CWnd int m_nComboIndex; int m_nListTopindex; - CWinPlacement m_wndPlace; - CArray m_tblListBoxSel; + std::vector m_tblListBoxSel; // Overrides public: - virtual void PostNcDestroy(); - virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam); + void PostNcDestroy() override; + LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam) override; // Implementation - methods protected: From 9f60409d1acc78811c9896818282c80ed0aadde5 Mon Sep 17 00:00:00 2001 From: Bill Su Date: Sun, 15 Feb 2026 22:53:10 -0500 Subject: [PATCH 63/80] PalTray: create an extra window to simplify wx conversion --- GP/FrmDockTray.cpp | 2 +- GP/FrmDockTray.h | 6 ++--- GP/GamDoc.cpp | 16 +++++------ GP/GamDoc.h | 4 +-- GP/GamDoc3.cpp | 12 ++++----- GP/GamDoc4.cpp | 12 ++++----- GP/PalTray.cpp | 66 ++++++++++++++++++++++++++++++++++++++++++---- GP/PalTray.h | 54 ++++++++++++++++++++++++++++++------- 8 files changed, 131 insertions(+), 41 deletions(-) diff --git a/GP/FrmDockTray.cpp b/GP/FrmDockTray.cpp index a661b633..ca10475f 100644 --- a/GP/FrmDockTray.cpp +++ b/GP/FrmDockTray.cpp @@ -56,7 +56,7 @@ CDockTrayPalette::~CDockTrayPalette() ///////////////////////////////////////////////////////////////////////////// -void CDockTrayPalette::SetChild(CTrayPalette* pChildWnd) +void CDockTrayPalette::SetChild(CTrayPaletteContainer* pChildWnd) { if (m_pChildWnd == pChildWnd) return; diff --git a/GP/FrmDockTray.h b/GP/FrmDockTray.h index 4a84f5aa..ac37c9b2 100644 --- a/GP/FrmDockTray.h +++ b/GP/FrmDockTray.h @@ -27,7 +27,7 @@ ///////////////////////////////////////////////////////////////////////////// // CDockTrayPalette window -class CTrayPalette; +class CTrayPaletteContainer; class CDockTrayPalette : public CDockablePane { @@ -38,11 +38,11 @@ class CDockTrayPalette : public CDockablePane // Attributes public: - CTrayPalette* m_pChildWnd; + CTrayPaletteContainer* m_pChildWnd; // Operations public: - void SetChild(CTrayPalette* pChildWnd); + void SetChild(CTrayPaletteContainer* pChildWnd); // Overrides // ClassWizard generated virtual function overrides diff --git a/GP/GamDoc.cpp b/GP/GamDoc.cpp index 37ea6ac8..c1a36264 100644 --- a/GP/GamDoc.cpp +++ b/GP/GamDoc.cpp @@ -470,8 +470,8 @@ void CGamDoc::OnIdle(BOOL bActive) void CGamDoc::DoInitialUpdate() { - m_palTrayA->UpdatePaletteContents(NULL); - m_palTrayB->UpdatePaletteContents(NULL); + (*m_palTrayA)->UpdatePaletteContents(NULL); + (*m_palTrayB)->UpdatePaletteContents(NULL); } void CGamDoc::UpdateAllViews(CView* pSender, LPARAM lHint, CObject* pHint) @@ -479,13 +479,13 @@ void CGamDoc::UpdateAllViews(CView* pSender, LPARAM lHint, CObject* pHint) CGamDocHint* ph = static_cast(pHint); if (lHint == HINT_TRAYCHANGE) { - m_palTrayA->UpdatePaletteContents(ph->GetArgs().m_pTray); - m_palTrayB->UpdatePaletteContents(ph->GetArgs().m_pTray); + (*m_palTrayA)->UpdatePaletteContents(ph->GetArgs().m_pTray); + (*m_palTrayB)->UpdatePaletteContents(ph->GetArgs().m_pTray); } else if (lHint == HINT_GAMESTATEUSED) { - m_palTrayA->UpdatePaletteContents(); - m_palTrayB->UpdatePaletteContents(); + (*m_palTrayA)->UpdatePaletteContents(); + (*m_palTrayB)->UpdatePaletteContents(); } CDocument::UpdateAllViews(pSender, lHint, pHint); } @@ -634,10 +634,10 @@ BOOL CGamDoc::OnNewScenario() // Finally set up the tray palettes wxASSERT(!m_palTrayA); - m_palTrayA = new CTrayPalette(*this, ID_VIEW_TRAYA); + m_palTrayA = new CTrayPaletteContainer(*this, ID_VIEW_TRAYA); m_palTrayA->Create(GetMainFrame()->GetDockingTrayAWindow()); wxASSERT(!m_palTrayB); - m_palTrayB = new CTrayPalette(*this, ID_VIEW_TRAYB); + m_palTrayB = new CTrayPaletteContainer(*this, ID_VIEW_TRAYB); m_palTrayB->Create(GetMainFrame()->GetDockingTrayBWindow()); wxASSERT(!m_palMark); m_palMark = new CMarkerPaletteContainer(*this); diff --git a/GP/GamDoc.h b/GP/GamDoc.h index 016bbd20..da04c1ff 100644 --- a/GP/GamDoc.h +++ b/GP/GamDoc.h @@ -708,8 +708,8 @@ class CGamDoc : public CDocument // Some document related windows... public: // Tray Palettes... - CB::propagate_const> m_palTrayA; - CB::propagate_const> m_palTrayB; + CB::propagate_const> m_palTrayA; + CB::propagate_const> m_palTrayB; // Marker Palette... CB::propagate_const> m_palMark; diff --git a/GP/GamDoc3.cpp b/GP/GamDoc3.cpp index 97002dee..9c51dba9 100644 --- a/GP/GamDoc3.cpp +++ b/GP/GamDoc3.cpp @@ -688,9 +688,9 @@ void CGamDoc::SerializeScenarioOrGame(CArchive& ar, uint64_t& offsetOffsetFeatur ar << (BYTE)0; // 0 -> no win state serialize // V2.0 ar << (WORD)m_bTrayAVisible; - m_palTrayA->Serialize(ar); // Save tray position on screen + (*m_palTrayA)->Serialize(ar); // Save tray position on screen ar << (WORD)m_bTrayBVisible; - m_palTrayB->Serialize(ar); // Save tray position on screen + (*m_palTrayB)->Serialize(ar); // Save tray position on screen ar << (WORD)m_bMarkPalVisible; (*m_palMark)->Serialize(ar); // Save tray position on screen @@ -849,12 +849,12 @@ void CGamDoc::SerializeScenarioOrGame(CArchive& ar, uint64_t& offsetOffsetFeatur ar >> wTmp; m_bTrayAVisible = (BOOL)wTmp; wxASSERT(!m_palTrayA); - m_palTrayA = new CTrayPalette(*this, ID_VIEW_TRAYA); - m_palTrayA->Serialize(ar); // Restore tray position on screen + m_palTrayA = new CTrayPaletteContainer(*this, ID_VIEW_TRAYA); + (*m_palTrayA)->Serialize(ar); // Restore tray position on screen ar >> wTmp; m_bTrayBVisible = (BOOL)wTmp; wxASSERT(!m_palTrayB); - m_palTrayB = new CTrayPalette(*this, ID_VIEW_TRAYB); - m_palTrayB->Serialize(ar); // Restore tray position on screen + m_palTrayB = new CTrayPaletteContainer(*this, ID_VIEW_TRAYB); + (*m_palTrayB)->Serialize(ar); // Restore tray position on screen ar >> wTmp; m_bMarkPalVisible = (BOOL)wTmp; wxASSERT(!m_palMark); m_palMark = new CMarkerPaletteContainer(*this); diff --git a/GP/GamDoc4.cpp b/GP/GamDoc4.cpp index 2b9525c0..5c157030 100644 --- a/GP/GamDoc4.cpp +++ b/GP/GamDoc4.cpp @@ -493,7 +493,7 @@ void CGamDoc::EnsureTrayIndexVisible(const CTraySet& pYSet, int nPos) // Make sure item nPos is visible. size_t nGroup = GetTrayManager().FindTrayByRef(pYSet); ASSERT(nGroup != Invalid_v); - m_palTrayA->ShowTrayIndex(nGroup, nPos); + (*m_palTrayA)->ShowTrayIndex(nGroup, nPos); } ///////////////////////////////////////////////////////////////////////////// @@ -546,7 +546,7 @@ void CGamDoc::SelectTrayItem(const CTraySet& pYSet, PieceID pid, // Select the piece in the appropriate trayset. size_t nGroup = GetTrayManager().FindTrayByRef(pYSet); ASSERT(nGroup != Invalid_v); - m_palTrayA->SelectTrayPiece(nGroup, pid, pszNotificationTip ? pszNotificationTip : nullptr); + (*m_palTrayA)->SelectTrayPiece(nGroup, pid, pszNotificationTip ? pszNotificationTip : nullptr); } void CGamDoc::SelectMarkerPaletteItem(MarkID mid) @@ -676,8 +676,8 @@ void CGamDoc::IndicateTextTipOnBoard(const CPlayBoard& pPBoard, void CGamDoc::FlushAllSelections() { - m_palTrayA->DeselectAll(); - m_palTrayB->DeselectAll(); + (*m_palTrayA)->DeselectAll(); + (*m_palTrayB)->DeselectAll(); // Use hint to flush select lists. CGamDocHint hint; @@ -688,8 +688,8 @@ void CGamDoc::FlushAllSelections() void CGamDoc::FlushAllIndicators() { - m_palTrayA->DeselectAll(); - m_palTrayB->DeselectAll(); + (*m_palTrayA)->DeselectAll(); + (*m_palTrayB)->DeselectAll(); for (size_t i = 0; i < m_pPBMgr->GetNumPBoards(); i++) { diff --git a/GP/PalTray.cpp b/GP/PalTray.cpp index c1bac800..073c4d82 100644 --- a/GP/PalTray.cpp +++ b/GP/PalTray.cpp @@ -41,7 +41,9 @@ static char THIS_FILE[] = __FILE__; #endif +#if 0 IMPLEMENT_DYNAMIC(CTrayPalette, CWnd) +#endif #ifdef _DEBUG #define new DEBUG_NEW @@ -96,10 +98,17 @@ BEGIN_MESSAGE_MAP(CTrayPalette, CWnd) ON_WM_INITMENUPOPUP() END_MESSAGE_MAP() +BEGIN_MESSAGE_MAP(CTrayPaletteContainer, CWnd) + ON_WM_CREATE() + ON_WM_SETFOCUS() + ON_WM_SIZE() +END_MESSAGE_MAP() + ///////////////////////////////////////////////////////////////////////////// // CTrayPalette -CTrayPalette::CTrayPalette(CGamDoc& pDoc, UINT palID) : +CTrayPalette::CTrayPalette(CTrayPaletteContainer& container, CGamDoc& pDoc, UINT palID) : + m_pContainer(&container), m_pDoc(&pDoc), m_listTray(*m_pDoc) { @@ -117,13 +126,13 @@ CTrayPalette::CTrayPalette(CGamDoc& pDoc, UINT palID) : SetPaletteID(palID); } -BOOL CTrayPalette::Create(CWnd& pOwnerWnd/*, DWORD dwStyle, UINT nID*/) +BOOL CTrayPalette::Create(/*CWnd* pOwnerWnd, DWORD dwStyle, UINT nID*/) { LoadMenuButtonBitmap(); DWORD dwStyle = WS_CHILD | WS_VISIBLE; if (!CWnd::Create(AfxRegisterWndClass(0), NULL, dwStyle, - CRect(0, 0, 200, 100), &pOwnerWnd, 0)) + CRect(0, 0, 200, 100), &*m_pContainer, 0)) { TRACE("Failed to create Tray palette window.\n"); return FALSE; @@ -135,7 +144,7 @@ BOOL CTrayPalette::Create(CWnd& pOwnerWnd/*, DWORD dwStyle, UINT nID*/) return TRUE; } -void CTrayPalette::SetDockingFrame(CDockTrayPalette* pDockingFrame) +void CTrayPaletteContainer::SetDockingFrame(CDockTrayPalette* pDockingFrame) { m_pDockingFrame = pDockingFrame; SetParent(pDockingFrame); @@ -866,7 +875,7 @@ void CTrayPalette::OnSize(UINT nType, int cx, int cy) } } -void CTrayPalette::PostNcDestroy() +void CTrayPaletteContainer::PostNcDestroy() { /* DO NOTHING - FRAME CLASS WOULD DELETE SELF! */ } @@ -1312,3 +1321,50 @@ void CTrayPalette::OnInitMenuPopup(CMenu* pMenu, UINT nIndex, BOOL bSysMenu) state.m_nIndexMax = nCount; } } + +CTrayPaletteContainer::CTrayPaletteContainer(CGamDoc& pDoc, UINT palID) : + child(new CTrayPalette(*this, pDoc, palID)) +{ +} + +BOOL CTrayPaletteContainer::Create(CWnd& pOwnerWnd/*, DWORD dwStyle = 0, UINT nID = 0*/) +{ + DWORD dwStyle = WS_CHILD | WS_VISIBLE; + if (!CWnd::Create(AfxRegisterWndClass(0), NULL, dwStyle, + CRect(0, 0, 200, 100), &pOwnerWnd, 0)) + { + TRACE("Failed to create Tray palette container window.\n"); + return FALSE; + } + + return TRUE; +} + +int CTrayPaletteContainer::OnCreate(LPCREATESTRUCT lpCreateStruct) +{ + if (CWnd::OnCreate(lpCreateStruct) == -1) + { + return -1; + } + + if (!child->Create()) + { + TRACE("Failed to create Tray palette window.\n"); + return -1; + } + + return 0; +} + +// MFC puts the focus here, so move it to the useful window +void CTrayPaletteContainer::OnSetFocus(CWnd* pOldWnd) +{ + CWnd::OnSetFocus(pOldWnd); + child->SetFocus(); +} + +void CTrayPaletteContainer::OnSize(UINT nType, int cx, int cy) +{ + child->MoveWindow(0, 0, cx, cy); + return CWnd::OnSize(nType, cx, cy); +} diff --git a/GP/PalTray.h b/GP/PalTray.h index 760ccc8e..6327c8ef 100644 --- a/GP/PalTray.h +++ b/GP/PalTray.h @@ -37,6 +37,7 @@ class CDockTrayPalette; class CGamDoc; +class CTrayPaletteContainer; class CTraySet; ///////////////////////////////////////////////////////////////////////////// @@ -45,26 +46,21 @@ class CTraySet; class CTrayPalette : public CWnd { +#if 0 DECLARE_DYNAMIC(CTrayPalette) +#endif // Construction public: - CTrayPalette(CGamDoc& pDoc, UINT palID); + CTrayPalette(CTrayPaletteContainer& container, CGamDoc& pDoc, UINT palID); - BOOL Create(CWnd& pOwnerWnd/*, DWORD dwStyle = 0, UINT nID = 0*/); + BOOL Create(/*CWnd* pOwnerWnd, DWORD dwStyle = 0, UINT nID = 0*/); // Attributes private: void SetPaletteID(UINT nID) { m_nID = nID; } public: - const CDockTrayPalette* GetDockingFrame() const { return m_pDockingFrame.get(); } - CDockTrayPalette* GetDockingFrame() - { - return const_cast(std::as_const(*this).GetDockingFrame()); - } - void SetDockingFrame(CDockTrayPalette* pDockingFrame); - // Operations public: void DeselectAll(); @@ -76,6 +72,7 @@ class CTrayPalette : public CWnd // Implementation - vars protected: + RefPtr m_pContainer; RefPtr m_pDoc; UINT m_nID; CB::propagate_const m_pDockingFrame; @@ -112,7 +109,6 @@ class CTrayPalette : public CWnd // Overrides public: - void PostNcDestroy() override; LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam) override; // Implementation - methods @@ -161,6 +157,44 @@ class CTrayPalette : public CWnd DECLARE_MESSAGE_MAP() }; +class CTrayPaletteContainer : public CWnd +{ +public: + CTrayPaletteContainer(CGamDoc& pDoc, UINT palID); + BOOL Create(CWnd& pOwnerWnd/*, DWORD dwStyle = 0, UINT nID = 0*/); + + void PostNcDestroy() override; + + operator const CTrayPalette& () const { return *child; } + operator CTrayPalette& () + { + return const_cast(static_cast(std::as_const(*this))); + } + const CTrayPalette* operator->() const { return &static_cast(*this); } + CTrayPalette* operator->() + { + return const_cast(std::as_const(*this).operator->()); + } + + const CDockTrayPalette* GetDockingFrame() const { return m_pDockingFrame.get(); } + CDockTrayPalette* GetDockingFrame() + { + return const_cast(std::as_const(*this).GetDockingFrame()); + } + void SetDockingFrame(CDockTrayPalette* pDockingFrame); + + void Serialize(CArchive& ar) override { wxASSERT(false); AfxThrowNotSupportedException(); } + +private: + afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); + afx_msg void OnSetFocus(CWnd* pOldWnd); + afx_msg void OnSize(UINT nType, int cx, int cy); + DECLARE_MESSAGE_MAP() + + CB::propagate_const m_pDockingFrame = nullptr; + OwnerPtr child; +}; + ///////////////////////////////////////////////////////////////////////////// #endif From 42b650686f874770d84c720ed94ba36bc386f5f7 Mon Sep 17 00:00:00 2001 From: Bill Su Date: Sun, 8 Feb 2026 01:38:54 -0500 Subject: [PATCH 64/80] LBoxGrfx: implement support for PalTray --- GShr/LBoxGrfx.cpp | 95 +++++++++++++++++++---------------------------- GShr/LBoxGrfx.h | 18 ++++----- 2 files changed, 46 insertions(+), 67 deletions(-) diff --git a/GShr/LBoxGrfx.cpp b/GShr/LBoxGrfx.cpp index 205d93bd..4acfcbcd 100644 --- a/GShr/LBoxGrfx.cpp +++ b/GShr/LBoxGrfx.cpp @@ -1,6 +1,6 @@ // LBoxGrfx.cpp // -// Copyright (c) 1994-2024 By Dale L. Larson & William Su, All Rights Reserved. +// Copyright (c) 1994-2026 By Dale L. Larson & William Su, All Rights Reserved. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the @@ -675,11 +675,13 @@ wxBEGIN_EVENT_TABLE(CGrafixListBoxWx, CB::VListBoxHScroll) ON_WM_CREATE() #endif EVT_DRAGDROP(OnDragItem) + EVT_TIMER(XRCID("ID_TIP_LISTITEM_MSG_TIMER"), NotificationTipTimeoutHandler) wxEND_EVENT_TABLE() ///////////////////////////////////////////////////////////////////////////// CGrafixListBoxWx::CGrafixListBoxWx() : + m_toolMsgTipTimer(this, XRCID("ID_TIP_LISTITEM_MSG_TIMER")), m_nCurItemCode(Invalid_v), m_nTimerID(this) { @@ -687,6 +689,9 @@ CGrafixListBoxWx::CGrafixListBoxWx() : m_bAllowDrag = FALSE; m_bAllowSelfDrop = FALSE; m_bAllowDropScroll = FALSE; + + m_toolMsgTip.SetBalloonMode(true); + m_toolMsgTip.SetMaxWidth(MAX_LISTITEM_TIP_WIDTH); } CGrafixListBoxWx::~CGrafixListBoxWx() @@ -706,65 +711,46 @@ void CGrafixListBoxWx::SetNotificationTip(int nItem, UINT nResID) CB::string str = CB::string::LoadString(nResID); SetNotificationTip(nItem, str); } +#endif // Shows a notification tip over a specified item. If the item // doesn't exist, the center of the listbox receives the tip. -void CGrafixListBoxWx::SetNotificationTip(int nItem, const CB::string& pszTip) +void CGrafixListBoxWx::SetNotificationTip(size_t nItem, const CB::string& pszTip) { - if (m_toolMsgTip.m_hWnd == NULL) - { - m_toolMsgTip.Create(this, TTS_ALWAYSTIP | TTS_BALLOON | TTS_NOPREFIX); - m_toolMsgTip.SetMaxTipWidth(MAX_LISTITEM_TIP_WIDTH); - } - ClearNotificationTip(); - TOOLINFO ti; - m_toolMsgTip.FillInToolInfo(ti, this, ID_TIP_LISTITEM_MSG); - ti.uFlags |= TTF_TRACK; - ti.lpszText = const_cast(pszTip.v_str()); - - m_toolMsgTip.SendMessage(TTM_ADDTOOL, 0, (LPARAM)&ti); + m_toolMsgTip.Add(*this, pszTip, CB::ToolTip::TRACK); MakeItemVisible(nItem); - CRect rctItem; - if (!GetItemRect(nItem, rctItem)) - GetClientRect(rctItem); + wxRect rctItem = GetItemRect(nItem); + if (rctItem.IsEmpty()) + rctItem = GetClientRect(); - CPoint pntClient = rctItem.CenterPoint(); + wxPoint pntClient = GetMidRect(rctItem); - CPoint pntScreen(pntClient); - ClientToScreen(&pntScreen); + wxPoint pntScreen = ClientToScreen(pntClient); - m_toolMsgTip.Activate(TRUE); - m_toolMsgTip.SendMessage(TTM_TRACKACTIVATE, (WPARAM)TRUE, (LPARAM)&ti); - m_toolMsgTip.SendMessage(TTM_TRACKPOSITION, 0, - (LPARAM)MAKELONG(static_cast(pntScreen.x), static_cast(pntScreen.y))); + m_toolMsgTip.Enable(TRUE); + m_toolMsgTip.TrackActivate(*this, true); + m_toolMsgTip.TrackPosition(pntScreen); - SetTimer(ID_TIP_LISTITEM_MSG_TIMER, MAX_TIP_LISTITEM_MSG_TIME, - NotificationTipTimeoutHandler); + m_toolMsgTipTimer.Start(MAX_TIP_LISTITEM_MSG_TIME, wxTIMER_ONE_SHOT); } void CGrafixListBoxWx::ClearNotificationTip() { - KillTimer(ID_TIP_LISTITEM_MSG_TIMER); // Kill it in case it's still running + m_toolMsgTipTimer.Stop(); - CToolInfo ti; - m_toolMsgTip.GetToolInfo(ti, this, ID_TIP_LISTITEM_MSG); - m_toolMsgTip.SendMessage(TTM_TRACKACTIVATE, (WPARAM)FALSE, (LPARAM)&ti); - m_toolMsgTip.DelTool(this, ID_TIP_LISTITEM_MSG); - m_toolMsgTip.Activate(FALSE); + m_toolMsgTip.TrackActivate(*this, false); + m_toolMsgTip.Delete(*this); + m_toolMsgTip.Enable(FALSE); } -void CALLBACK CGrafixListBoxWx::NotificationTipTimeoutHandler(HWND hwnd, - UINT uMsg, UINT_PTR idEvent, DWORD dwTime) +void CGrafixListBoxWx::NotificationTipTimeoutHandler(wxTimerEvent& /*event*/) { - CGrafixListBox* pWnd = (CGrafixListBox*)CWnd::FromHandle(hwnd); - ASSERT(pWnd != NULL); - pWnd->ClearNotificationTip(); + ClearNotificationTip(); } -#endif ///////////////////////////////////////////////////////////////////////////// @@ -808,33 +794,28 @@ int CGrafixListBoxWx::GetTopSelectedItem() const ///////////////////////////////////////////////////////////////////////////// // If the selection is out of view, force it into view. -#if 0 -void CGrafixListBoxWx::MakeItemVisible(int nItem) +void CGrafixListBoxWx::MakeItemVisible(size_t nItem) { - CRect rctLBoxClient; - GetClientRect(&rctLBoxClient); - CRect rct; - GetItemRect(nItem, &rct); - if (!rct.IntersectRect(rct, rctLBoxClient)) - SetTopIndex(nItem); + wxRect rctLBoxClient = GetClientRect(); + wxRect rct = GetItemRect(nItem); + if (!rct.Intersects(rctLBoxClient)) + ScrollToRow(nItem); } -#endif ///////////////////////////////////////////////////////////////////////////// void CGrafixListBoxWx::SetSelFromPoint(wxPoint point) { wxASSERT(postProcessEvents.empty()); - // Short circuit drag processing - m_bAllowDrag = FALSE; - wxMouseEvent down(wxEVT_LEFT_DOWN); - down.SetPosition(point); - ProcessWindowEvent(down); - wxMouseEvent up(wxEVT_LEFT_UP); - up.SetPosition(point); - ProcessWindowEvent(up); - m_bAllowDrag = TRUE; - wxASSERT(postProcessEvents.empty()); + if (GetItemCount() == size_t(0)) + { + return; + } + int itemFromPoint = VirtualHitTest(point.y); + if (itemFromPoint != wxNOT_FOUND) + { + SetSelection(itemFromPoint); + } } ///////////////////////////////////////////////////////////////////////////// diff --git a/GShr/LBoxGrfx.h b/GShr/LBoxGrfx.h index c644a6eb..904b9dfd 100644 --- a/GShr/LBoxGrfx.h +++ b/GShr/LBoxGrfx.h @@ -1,6 +1,6 @@ // LBoxGrfx.h // -// Copyright (c) 1994-2024 By Dale L. Larson & William Su, All Rights Reserved. +// Copyright (c) 1994-2026 By Dale L. Larson & William Su, All Rights Reserved. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the @@ -525,16 +525,15 @@ class CGrafixListBoxWx : public CB::VListBoxHScroll public: void SetSelFromPoint(wxPoint point); void ShowFirstSelection(); -#if 0 - void MakeItemVisible(int nItem); + void MakeItemVisible(size_t nItem); // Notification Tooltip Support +#if 0 void SetNotificationTip(int nItem, UINT nResID); - void SetNotificationTip(int nItem, const CB::string& pszTip); - void ClearNotificationTip(); - static void CALLBACK NotificationTipTimeoutHandler(HWND hwnd, UINT uMsg, - UINT_PTR idEvent, DWORD dwTime); #endif + void SetNotificationTip(size_t nItem, const CB::string& pszTip); + void ClearNotificationTip(); + void NotificationTipTimeoutHandler(wxTimerEvent& event); // Overrides - the subclass of this class must override these public: @@ -564,9 +563,8 @@ class CGrafixListBoxWx : public CB::VListBoxHScroll // Implementation protected: // Tool tip support -#if 0 - CToolTipCtrl m_toolMsgTip; // Tooltip for notifications -#endif + CB::ToolTip m_toolMsgTip; // Tooltip for notifications + wxTimer m_toolMsgTipTimer; wxTipWindow::Ref m_toolTip; // Tooltip of tile text popups GameElement m_nCurItemCode; // current active tip item code From 1f568979a2d3da00ac4f4a279f235601bb9f471a Mon Sep 17 00:00:00 2001 From: Bill Su Date: Sun, 8 Feb 2026 01:55:44 -0500 Subject: [PATCH 65/80] LBoxTray: implement support for PalTray --- GP/LBoxTray.cpp | 39 +++++++++++++++++---------------------- GP/LBoxTray.h | 4 +++- 2 files changed, 20 insertions(+), 23 deletions(-) diff --git a/GP/LBoxTray.cpp b/GP/LBoxTray.cpp index 9ba9c8bb..30ac0696 100644 --- a/GP/LBoxTray.cpp +++ b/GP/LBoxTray.cpp @@ -1,6 +1,6 @@ // LBoxTray.cpp // -// Copyright (c) 1994-2025 By Dale L. Larson & William Su, All Rights Reserved. +// Copyright (c) 1994-2026 By Dale L. Larson & William Su, All Rights Reserved. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the @@ -459,7 +459,6 @@ BOOL CTrayListBoxWx::OnDoesItemHaveTipText(size_t nItem) const PieceID pid = MapIndexToItem(nItem); if (m_eTrayViz != trayVizAllSides) { - wxASSERT(!"untested code"); uint8_t side = m_pDoc->GetPieceTable().GetSide(pid); return m_pDoc->HasGameElementString(MakePieceElement(pid, side)); } @@ -480,50 +479,46 @@ BOOL CTrayListBoxWx::OnDoesItemHaveTipText(size_t nItem) const ///////////////////////////////////////////////////////////////////////////// -#if 0 -void CTrayListBox::DeselectAll() +void CTrayListBoxWx::DeselectAll() { - ASSERT(IsMultiSelect()); - if (GetCount() < 1) + wxASSERT(IsMultiSelect()); + if (GetItemCount() < 1) return; - SelItemRange(FALSE, 0, GetCount()-1); + BASE::DeselectAll(); } -size_t CTrayListBox::SelectTrayPiece(PieceID pid) +size_t CTrayListBoxWx::SelectTrayPiece(PieceID pid) { size_t nIndex = MapItemToIndex(pid); if (nIndex != Invalid_v) { - ShowListIndex(value_preserving_cast(nIndex)); - SetSel(value_preserving_cast(nIndex), TRUE); + ShowListIndex(nIndex); + Select(nIndex, TRUE); } else { - if (GetCount() > 0) - SetSel(0, TRUE); + if (GetItemCount() > 0) + Select(0, TRUE); } return nIndex; } ///////////////////////////////////////////////////////////////////////////// -void CTrayListBox::ShowListIndex(int nPos) +void CTrayListBoxWx::ShowListIndex(size_t nPos) { - if (nPos < GetTopIndex()) + if (nPos < this->GetVisibleRowsBegin()) { - SetTopIndex(nPos); + ScrollToRow(nPos); return; } - CRect rct; - GetItemRect(nPos, &rct); - CRect rctClient; - GetClientRect(&rctClient); - if (rct.IntersectRect(&rct, &rctClient)) + wxRect rct = GetItemRect(nPos); + wxRect rctClient = GetClientRect(); + if (rct.Intersects(rctClient)) return; - SetTopIndex(nPos); + ScrollToRow(nPos); } -#endif ///////////////////////////////////////////////////////////////////////////// diff --git a/GP/LBoxTray.h b/GP/LBoxTray.h index 245cde16..f70c06fd 100644 --- a/GP/LBoxTray.h +++ b/GP/LBoxTray.h @@ -126,7 +126,7 @@ class CTrayListBoxWx : public CGrafixListBoxDataWx public: void DeselectAll(); size_t SelectTrayPiece(PieceID pid); - void ShowListIndex(int nPos); + void ShowListIndex(size_t nPos); void SetTrayContentVisibility(TrayViz eTrayViz, CB::string pszHiddenString = CB::string()); void SetTipsAllowed(BOOL bTipsAllowed) @@ -164,6 +164,8 @@ class CTrayListBoxWx : public CGrafixListBoxDataWx wxDECLARE_DYNAMIC_CLASS(CTrayListBoxWx); private: + typedef CGrafixListBoxDataWx BASE; + bool IsShowAllSides(PieceID pid) const; }; From a7f5fbb2319a1ecd8d21558625ad694cb015fe52 Mon Sep 17 00:00:00 2001 From: Bill Su Date: Sun, 8 Feb 2026 01:59:29 -0500 Subject: [PATCH 66/80] PalTray: start converting from MFC to wx --- GP/CBPlay.fbp | 407 +++++++++++++++++++++++++++++++++++++++++++++++++ GP/CBPlay.xrc | 106 +++++++++++++ GP/GamDoc.h | 2 +- GP/GamDoc4.cpp | 4 +- GP/PalTray.cpp | 215 +++++++++++++------------- GP/PalTray.h | 50 +++--- 6 files changed, 654 insertions(+), 130 deletions(-) diff --git a/GP/CBPlay.fbp b/GP/CBPlay.fbp index 98cf2779..2cbbf966 100644 --- a/GP/CBPlay.fbp +++ b/GP/CBPlay.fbp @@ -14357,6 +14357,246 @@ + + 0 + wxAUI_MGR_DEFAULT + + + 1 + 0 + 1 + impl_virtual + + + 0 + wxID_ANY + + + CTrayPalette + + 500,300 + ; ; forward_declare + + 0 + + + wxTAB_TRAVERSAL + + + bSizer85 + wxVERTICAL + none + + 5 + wxEXPAND + 0 + + + bSizer86 + wxHORIZONTAL + none + + 5 + wxEXPAND + 0 + + 1 + 1 + 1 + 1 + 0 + + 0 + 0 + 0 + + + + + 1 + 0 + 1 + + 1 + + 0 + 0 + + Dock + 0 + Left + 0 + 1 + + 1 + + + 0 + 0 + wxID_ANY + MyButton + + 0 + + 0 + + + 0 + + 1 + m_bpMenuBtn + 1 + + + protected + 1 + + + + Resizable + 1 + + + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL + 1 + + 1 + 1 + 1 + 1 + 0 + + 0 + 0 + + + + 1 + 0 + + 1 + + 1 + 0 + Dock + 0 + Left + 0 + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + 0 + + 1 + m_comboYGrp + 1 + + + protected + 1 + + Resizable + 0 + 1 + + + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + + 5 + wxEXPAND + 1 + + 1 + 1 + 1 + 1 + 0 + + 0 + 0 + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 0 + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + 0 + + 1 + m_listTray + 1 + + + protected + 1 + + Resizable + 1 + + wxLB_MULTIPLE + CTrayListBoxWx; forward_declare + 0 + + + + + + + + 0 wxAUI_MGR_DEFAULT @@ -17614,6 +17854,173 @@ 5=PV_PIECE_TRAY MENU_PV_PIECE_TRAY protected + + + Turn Selected Pieces Over + m_menu1 + protected + + + 0 + 1 + + wxID_ANY + wxITEM_NORMAL + &Next + ID_ACT_TURNOVER + none + + + + + + 0 + 1 + + wxID_ANY + wxITEM_NORMAL + &Prev + ID_ACT_TURNOVER_PREV + none + + + + + + 0 + 1 + + wxID_ANY + wxITEM_NORMAL + &Random + ID_ACT_TURNOVER_RANDOM + none + + + + + + + Turn All Pieces Over + m_menu2 + protected + + + 0 + 1 + + wxID_ANY + wxITEM_NORMAL + &Next + ID_ACT_TURNOVER_ALL + none + + + + + + 0 + 1 + + wxID_ANY + wxITEM_NORMAL + &Prev + ID_ACT_TURNOVER_ALL_PREV + none + + + + + + 0 + 1 + + wxID_ANY + wxITEM_NORMAL + &Random + ID_ACT_TURNOVER_ALL_RANDOM + none + + + + + + + 0 + 1 + + wxID_ANY + wxITEM_NORMAL + Turn Over to Clicked Side + ID_ACT_TURNOVER_SELECT + none + + + + + m_separator5 + none + + + + 0 + 1 + + wxID_ANY + wxITEM_NORMAL + Shuffle Selected Items + ID_PTRAY_SHUFFLE_SELECTED + none + + + + + + 0 + 1 + + wxID_ANY + wxITEM_NORMAL + Shuffle All Pieces + ID_PTRAY_SHUFFLE + none + + + + + m_separator6 + none + + + + 0 + 1 + + wxID_ANY + wxITEM_NORMAL + Edit Object Text... + ID_EDIT_ELEMENT_TEXT + none + + + + + m_separator7 + none + + + + 0 + 1 + + wxID_ANY + wxITEM_NORMAL + About the Selected Tray... + ID_PTRAY_ABOUT + none + + + 6=MV_RICHEDIT diff --git a/GP/CBPlay.xrc b/GP/CBPlay.xrc index 6bc80ad4..78a60270 100644 --- a/GP/CBPlay.xrc +++ b/GP/CBPlay.xrc @@ -2732,6 +2732,48 @@ + + 500,300 + + + wxVERTICAL + + wxEXPAND + 5 + + + wxHORIZONTAL + + wxEXPAND + 5 + + + 0 + 0 + + + + + wxALIGN_CENTER_VERTICAL + 5 + + + 0 + + + + + + + wxEXPAND + 5 + + + + + + + Tray Properties @@ -3701,6 +3743,70 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/GP/GamDoc.h b/GP/GamDoc.h index da04c1ff..908c0668 100644 --- a/GP/GamDoc.h +++ b/GP/GamDoc.h @@ -517,7 +517,7 @@ class CGamDoc : public CDocument // Support for playback... void EnsureBoardVisible(CPlayBoard& pPBoard); void EnsureBoardLocationVisible(CPlayBoard& pPBoard, CPoint point); - void EnsureTrayIndexVisible(const CTraySet& pYSet, int nPos); + void EnsureTrayIndexVisible(const CTraySet& pYSet, size_t nPos); void SelectObjectOnBoard(CPlayBoard& pPBoard, CDrawObj* pObj); void SelectObjectListOnBoard(CPlayBoard& pPBoard, const std::vector>& pList); void SelectTrayItem(const CTraySet& pYSet, PieceID pid, UINT nResourceID); diff --git a/GP/GamDoc4.cpp b/GP/GamDoc4.cpp index 5c157030..f8a03190 100644 --- a/GP/GamDoc4.cpp +++ b/GP/GamDoc4.cpp @@ -484,7 +484,7 @@ void CGamDoc::EnsureBoardVisible(CPlayBoard& pPBoard) ///////////////////////////////////////////////////////////////////////////// -void CGamDoc::EnsureTrayIndexVisible(const CTraySet& pYSet, int nPos) +void CGamDoc::EnsureTrayIndexVisible(const CTraySet& pYSet, size_t nPos) { if (IsQuietPlayback()) return; if (!m_bTrayAVisible) @@ -492,7 +492,7 @@ void CGamDoc::EnsureTrayIndexVisible(const CTraySet& pYSet, int nPos) // Make sure item nPos is visible. size_t nGroup = GetTrayManager().FindTrayByRef(pYSet); - ASSERT(nGroup != Invalid_v); + wxASSERT(nGroup != Invalid_v); (*m_palTrayA)->ShowTrayIndex(nGroup, nPos); } diff --git a/GP/PalTray.cpp b/GP/PalTray.cpp index 073c4d82..cc5d25b2 100644 --- a/GP/PalTray.cpp +++ b/GP/PalTray.cpp @@ -41,9 +41,7 @@ static char THIS_FILE[] = __FILE__; #endif -#if 0 -IMPLEMENT_DYNAMIC(CTrayPalette, CWnd) -#endif +wxIMPLEMENT_CLASS(CTrayPalette, wxPanel) #ifdef _DEBUG #define new DEBUG_NEW @@ -55,8 +53,8 @@ IMPLEMENT_DYNAMIC(CTrayPalette, CWnd) ///////////////////////////////////////////////////////////////////////////// -BEGIN_MESSAGE_MAP(CTrayPalette, CWnd) - //{{AFX_MSG_MAP(CTrayPalette) +wxBEGIN_EVENT_TABLE(CTrayPalette, wxPanel) +#if 0 ON_WM_ERASEBKGND() ON_WM_SIZE() ON_WM_CREATE() @@ -92,11 +90,11 @@ BEGIN_MESSAGE_MAP(CTrayPalette, CWnd) ON_UPDATE_COMMAND_UI(ID_PTRAY_ABOUT, OnUpdatePieceTrayAbout) ON_WM_HELPINFO() ON_WM_MOUSEMOVE() - //}}AFX_MSG_MAP ON_MESSAGE(WM_WINSTATE_RESTORE, OnMessageRestoreWinState) ON_MESSAGE(WM_PALETTE_HIDE, OnPaletteHide) ON_WM_INITMENUPOPUP() -END_MESSAGE_MAP() +#endif +wxEND_EVENT_TABLE() BEGIN_MESSAGE_MAP(CTrayPaletteContainer, CWnd) ON_WM_CREATE() @@ -110,14 +108,10 @@ END_MESSAGE_MAP() CTrayPalette::CTrayPalette(CTrayPaletteContainer& container, CGamDoc& pDoc, UINT palID) : m_pContainer(&container), m_pDoc(&pDoc), - m_listTray(*m_pDoc) + m_bpMenuBtn(nullptr), + m_comboYGrp(nullptr), + m_listTray(nullptr) { - ASSERT(m_pDoc->IsKindOf(RUNTIME_CLASS(CGamDoc))); - m_listTray.EnableDrag(); - m_listTray.EnableSelfDrop(); - m_listTray.EnableDropScroll(); - m_listTray.SetTrayContentVisibility(trayVizAllSides); - m_dummyArray.push_back(PieceID(0)); m_bStateVarsArmed = FALSE; @@ -126,21 +120,31 @@ CTrayPalette::CTrayPalette(CTrayPaletteContainer& container, CGamDoc& pDoc, UINT SetPaletteID(palID); } -BOOL CTrayPalette::Create(/*CWnd* pOwnerWnd, DWORD dwStyle, UINT nID*/) +BOOL CTrayPalette::Create(/*wxWindow & pOwnerWnd, DWORD dwStyle, UINT nID*/) { LoadMenuButtonBitmap(); - DWORD dwStyle = WS_CHILD | WS_VISIBLE; - if (!CWnd::Create(AfxRegisterWndClass(0), NULL, dwStyle, - CRect(0, 0, 200, 100), &*m_pContainer, 0)) + if (!CB::XrcLoad(*this, *m_pContainer, "CTrayPalette")) { - TRACE("Failed to create Tray palette window.\n"); - return FALSE; + return false; } + m_bpMenuBtn = XRCCTRL(*this, "m_bpMenuBtn", wxBitmapButton); + m_bpMenuBtn->SetBitmap(m_bmpMenuBtn); + m_comboYGrp = XRCCTRL(*this, "m_comboYGrp", wxChoice); + m_listTray = XRCCTRL(*this, "m_listTray", CTrayListBoxWx); + (*m_pContainer)->Layout(); + + m_listTray->Init(*m_pDoc); + m_listTray->EnableDrag(); + m_listTray->EnableSelfDrop(); + m_listTray->EnableDropScroll(); + m_listTray->SetTrayContentVisibility(trayVizAllSides); + + EnsureTooltipExistance(); UpdatePaletteContents(); // Queue up a message to finish up state restore. - PostMessage(WM_WINSTATE_RESTORE); + QueueEvent(WinStateRestoreEvent().Clone()); return TRUE; } @@ -150,6 +154,7 @@ void CTrayPaletteContainer::SetDockingFrame(CDockTrayPalette* pDockingFrame) SetParent(pDockingFrame); } +#if 0 int CTrayPalette::OnCreate(LPCREATESTRUCT lpCreateStruct) { m_rctMenuBtn.left = 0; @@ -194,6 +199,7 @@ int CTrayPalette::OnCreate(LPCREATESTRUCT lpCreateStruct) return 0; } +#endif ///////////////////////////////////////////////////////////////////////////// // Because of the way MFC and Windows re-parents the tooltip control they @@ -203,15 +209,12 @@ int CTrayPalette::OnCreate(LPCREATESTRUCT lpCreateStruct) BOOL CTrayPalette::EnsureTooltipExistance() { - if (m_toolTipMenu.m_hWnd == NULL) - { - // Add a tip to the menu icon click area. - m_toolTipMenu.Create(this, TTS_ALWAYSTIP | TTS_BALLOON | TTS_NOPREFIX); - m_toolTipMenu.AddTool(this, IDS_TIP_CLICK_MENU, m_rctMenuBtn, ID_TIP_MENU); + // Add a tip to the menu button. + m_toolTipMenu.SetBalloonMode(true); + m_toolTipMenu.Enable(true); + m_toolTipMenu.Add(*m_bpMenuBtn, CB::string::LoadString(IDS_TIP_CLICK_MENU)); - m_toolTipCombo.Create(this, TTS_ALWAYSTIP | TTS_NOPREFIX); - return TRUE; - } + m_toolTipCombo.Enable(true); return FALSE; } @@ -219,11 +222,10 @@ BOOL CTrayPalette::EnsureTooltipExistance() void CTrayPalette::DoEditSelectedPieceText() { - ASSERT(m_listTray.GetSelCount() == 1); - int nSelItem; - m_listTray.GetSelItems(1, &nSelItem); + std::vector nSelItem = m_listTray->GetSelections(); + wxASSERT(nSelItem.size() == size_t(1)); - PieceID pid = m_listTray.MapIndexToItem(value_preserving_cast(nSelItem)); + PieceID pid = m_listTray->MapIndexToItem(nSelItem.front()); m_pDoc->DoEditPieceText(pid); } @@ -232,26 +234,27 @@ void CTrayPalette::DoEditSelectedPieceText() size_t CTrayPalette::GetSelectedTray() const { - int nSel = m_comboYGrp.GetCurSel(); - if (nSel < 0) + int nSel = m_comboYGrp->GetSelection(); + if (nSel == wxNOT_FOUND) return Invalid_v; - return value_preserving_cast(m_comboYGrp.GetItemData(nSel)); + return value_preserving_cast(reinterpret_cast(m_comboYGrp->GetClientData(value_preserving_cast(nSel)))); } int CTrayPalette::FindTrayIndex(size_t nTrayNum) const { - if (m_comboYGrp.GetCount() <= 0) - return -1; + if (m_comboYGrp->GetCount() <= 0) + return wxNOT_FOUND; // @@@@@ TRACE1("m_comboYGrp.GetCount() = %d\n", m_comboYGrp.GetCount()); - for (int nIdx = 0; nIdx < m_comboYGrp.GetCount(); nIdx++) + for (unsigned nIdx = unsigned(0) ; nIdx < m_comboYGrp->GetCount() ; ++nIdx) { - if (value_preserving_cast(m_comboYGrp.GetItemData(nIdx)) == nTrayNum) - return nIdx; + if (value_preserving_cast(reinterpret_cast(m_comboYGrp->GetClientData(nIdx))) == nTrayNum) + return value_preserving_cast(nIdx); } // CAN HAPPEN! ASSERT(nIdx < m_comboYGrp.GetCount()); - return -1; + return wxNOT_FOUND; } +#if 0 /////////////////////////////////////////////////////////////////////// // This method handles the custom message WM_WINSTATE_RESTORE. The // message is posted during view initial update if the state of @@ -459,6 +462,7 @@ LRESULT CTrayPalette::OnGetDragSize(WPARAM wParam, LPARAM /*lParam*/) CheckedDeref(reinterpret_cast(wParam)) = retval; return 1; } +#endif ///////////////////////////////////////////////////////////////////////////// @@ -466,32 +470,35 @@ void CTrayPalette::Serialize(CArchive& ar) { if (ar.IsStoring()) { - ar << (DWORD)m_comboYGrp.GetCurSel(); - ar << (DWORD)m_listTray.GetTopIndex(); + ar << static_cast(value_preserving_cast(m_comboYGrp->GetSelection())); + ar << static_cast(value_preserving_cast(m_listTray->GetVisibleRowsBegin())); // Save the indexes of all the selected items. m_tblListBoxSel.clear(); - int nNumSelected = m_listTray.GetSelCount(); - m_tblListBoxSel.resize(value_preserving_cast(nNumSelected)); - m_listTray.GetSelItems(nNumSelected, m_tblListBoxSel.data()); + std::vector selections = m_listTray->GetSelections(); + m_tblListBoxSel.reserve(selections.size()); + for (size_t i = size_t(0); i < selections.size(); ++i) + { + m_tblListBoxSel.push_back(value_preserving_cast(selections[i])); + } ar << m_tblListBoxSel; } else { if (CGamDoc::GetLoadingVersion() >= NumVersion(2, 90)) // V2.90 { - DWORD dwTmp; - ar >> dwTmp; m_nComboIndex = (int)dwTmp; - ar >> dwTmp; m_nListTopindex = (int)dwTmp; + uint32_t dwTmp; + ar >> dwTmp; m_nComboIndex = dwTmp; + ar >> dwTmp; m_nListTopindex = dwTmp; ar >> m_tblListBoxSel; m_bStateVarsArmed = TRUE; // Inform Create() data is good } else if (CGamDoc::GetLoadingVersion() >= NumVersion(2, 0)) // V2.0 { - DWORD dwTmp; - ar >> dwTmp; m_nComboIndex = (int)dwTmp; - ar >> dwTmp; m_nListTopindex = (int)dwTmp; + uint32_t dwTmp; + ar >> dwTmp; m_nComboIndex = dwTmp; + ar >> dwTmp; m_nListTopindex = dwTmp; ar >> m_tblListBoxSel; CWinPlacement wndSink; ar >> wndSink; // Eat this puppy @@ -499,7 +506,7 @@ void CTrayPalette::Serialize(CArchive& ar) } else // Pre 2.0 { - short sTmp; // Eat the old data and go with the default values + uint16_t sTmp; // Eat the old data and go with the default values ar >> sTmp; ar >> sTmp; ar >> sTmp; @@ -514,7 +521,7 @@ void CTrayPalette::LoadTrayNameList() { CTrayManager& pYMgr = m_pDoc->GetTrayManager(); - m_comboYGrp.ResetContent(); + m_comboYGrp->Clear(); for (size_t i = size_t(0); i < pYMgr.GetNumTraySets(); i++) { CTraySet& pYSet = pYMgr.GetTraySet(i); @@ -525,10 +532,10 @@ void CTrayPalette::LoadTrayNameList() pYSet.GetOwnerMask()).m_strName; strTrayName += " - " + strOwner; } - int nIdx = m_comboYGrp.AddString(strTrayName); - m_comboYGrp.SetItemData(nIdx, value_preserving_cast(i)); // Store the tray index in the data item + int nIdx = m_comboYGrp->Append(strTrayName); + m_comboYGrp->SetClientData(value_preserving_cast(nIdx), reinterpret_cast(value_preserving_cast(i))); // Store the tray index in the data item } - m_comboYGrp.SetCurSel(0); + m_comboYGrp->SetSelection(0); UpdateTrayList(); } @@ -549,32 +556,33 @@ void CTrayPalette::UpdatePaletteContents(const CTraySet* pTray) { LoadTrayNameList(); int nComboIndex = FindTrayIndex(nSel); - if (nComboIndex < 0) + if (nComboIndex == wxNOT_FOUND) nComboIndex = 0; - m_comboYGrp.SetCurSel(nComboIndex); + m_comboYGrp->SetSelection(nComboIndex); } UpdateTrayList(); } ///////////////////////////////////////////////////////////////////////////// -void CTrayPalette::ShowTrayIndex(size_t nGroup, int nPos) +void CTrayPalette::ShowTrayIndex(size_t nGroup, size_t nPos) { size_t nSel = GetSelectedTray(); if (nSel != nGroup) { - m_comboYGrp.SetCurSel(FindTrayIndex(nGroup)); + m_comboYGrp->SetSelection(FindTrayIndex(nGroup)); UpdateTrayList(); } - m_listTray.ShowListIndex(nPos); + m_listTray->ShowListIndex(nPos); } ///////////////////////////////////////////////////////////////////////////// void CTrayPalette::DeselectAll() { - if (m_hWnd != NULL) - m_listTray.DeselectAll(); + wxASSERT(m_listTray); + if (m_listTray) + m_listTray->DeselectAll(); } void CTrayPalette::SelectTrayPiece(size_t nGroup, PieceID pid, @@ -583,13 +591,13 @@ void CTrayPalette::SelectTrayPiece(size_t nGroup, PieceID pid, size_t nSel = GetSelectedTray(); if (nSel != nGroup) { - m_comboYGrp.SetCurSel(FindTrayIndex(nGroup)); + m_comboYGrp->SetSelection(FindTrayIndex(nGroup)); UpdateTrayList(); } - size_t nItem = m_listTray.SelectTrayPiece(pid); + size_t nItem = m_listTray->SelectTrayPiece(pid); if (pszNotificationTip != NULL) { - m_listTray.SetNotificationTip(value_preserving_cast(nItem), *pszNotificationTip); + m_listTray->SetNotificationTip(nItem, *pszNotificationTip); } } @@ -599,7 +607,7 @@ void CTrayPalette::UpdateTrayList() { CTrayManager& pYMgr = m_pDoc->GetTrayManager(); - m_toolTipCombo.DelTool(&m_comboYGrp); // Always delete current tool + m_toolTipCombo.Delete(*m_comboYGrp); // Always delete current tool size_t nSel = GetSelectedTray(); if (nSel == Invalid_v) @@ -607,21 +615,17 @@ void CTrayPalette::UpdateTrayList() // Get the name from the combo box since it has all the ownership // information added. - CB::string strTrayName = CB::string::GetLBText(m_comboYGrp, m_comboYGrp.GetCurSel()); + CB::string strTrayName = m_comboYGrp->GetString(m_comboYGrp->GetSelection()); - TOOLINFO ti; - m_toolTipCombo.FillInToolInfo(ti, &m_comboYGrp, 0); - ti.uFlags |= TTF_SUBCLASS | TTF_CENTERTIP; - ti.lpszText = const_cast(strTrayName.v_str()); - m_toolTipCombo.SendMessage(TTM_ADDTOOL, 0, (LPARAM)&ti); + m_toolTipCombo.Add(*m_comboYGrp, strTrayName, CB::ToolTip::CENTER); CTraySet& pYSet = pYMgr.GetTraySet(nSel); const std::vector* pPieceTbl = &pYSet.GetPieceIDTable(); CB::string str = ""; - m_listTray.EnableDrag(TRUE); - m_listTray.EnableSelfDrop(TRUE); - m_listTray.SetTipsAllowed(TRUE); + m_listTray->EnableDrag(TRUE); + m_listTray->EnableSelfDrop(TRUE); + m_listTray->SetTipsAllowed(TRUE); TrayViz eViz = pYSet.GetTrayContentVisibility(); @@ -641,7 +645,7 @@ void CTrayPalette::UpdateTrayList() if (pYSet.IsRandomPiecePull()) { str = CB::string::LoadString(IDS_TRAY_RANDHIDDEN); - m_listTray.EnableSelfDrop(FALSE); + m_listTray->EnableSelfDrop(FALSE); } else str = CB::string::LoadString(IDS_TRAY_HIDDEN); @@ -651,7 +655,7 @@ void CTrayPalette::UpdateTrayList() if (pYSet.IsRandomPiecePull()) { str = CB::string::LoadString(IDS_TRAY_ALLRANDHIDDEN); - m_listTray.EnableSelfDrop(FALSE); + m_listTray->EnableSelfDrop(FALSE); } else str = CB::string::LoadString(IDS_TRAY_ALLHIDDEN); @@ -663,22 +667,23 @@ void CTrayPalette::UpdateTrayList() pPieceTbl = &m_dummyArray; } if (!m_pDoc->IsScenario() && pYSet.IsOwnedButNotByCurrentPlayer(*m_pDoc)) - m_listTray.SetTipsAllowed(FALSE); + m_listTray->SetTipsAllowed(FALSE); if (!m_pDoc->IsScenario() && pYSet.IsOwned() && !pYSet.IsOwnedBy(m_pDoc->GetCurrentPlayerMask()) && !pYSet.IsNonOwnerAccessAllowed()) { - m_listTray.EnableDrag(FALSE); - m_listTray.EnableSelfDrop(FALSE); + m_listTray->EnableDrag(FALSE); + m_listTray->EnableSelfDrop(FALSE); } - m_listTray.SetTrayContentVisibility(eViz, str); + m_listTray->SetTrayContentVisibility(eViz, str); - m_listTray.SetItemMap(pPieceTbl); + m_listTray->SetItemMap(pPieceTbl); } ///////////////////////////////////////////////////////////////////////////// +#if 0 LRESULT CTrayPalette::OnDragItem(WPARAM wParam, LPARAM lParam) { if (wParam != GetProcessId(GetCurrentProcess())) @@ -788,6 +793,7 @@ LRESULT CTrayPalette::OnDragItem(WPARAM wParam, LPARAM lParam) } return 1; } +#endif ///////////////////////////////////////////////////////////////////////////// // Load the menu icon image and fill upper-right transparent area with @@ -795,30 +801,25 @@ LRESULT CTrayPalette::OnDragItem(WPARAM wParam, LPARAM lParam) void CTrayPalette::LoadMenuButtonBitmap() { - HBITMAP hBMap = (HBITMAP)LoadImage(AfxGetResourceHandle(), - MAKEINTRESOURCE(IDB_MENU_ICON), IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR); - ASSERT(hBMap != NULL); - m_bmpMenuBtn.Attach(hBMap); - - BITMAP bmap; - m_bmpMenuBtn.GetBitmap(&bmap); - m_sizeMenuBtn.cx = bmap.bmWidth; - m_sizeMenuBtn.cy = bmap.bmHeight; - - CDC dc; - dc.CreateCompatibleDC(NULL); - CBitmap* prvBMap = dc.SelectObject(&m_bmpMenuBtn); - CBrush brush; - brush.CreateSolidBrush(GetSysColor(COLOR_BTNFACE)); - CBrush* prvBrush = dc.SelectObject(&brush); - dc.ExtFloodFill(m_sizeMenuBtn.cx - 1, 0, RGB(0, 255, 255), FLOODFILLSURFACE); - dc.SelectObject(prvBrush); - dc.SelectObject(prvBMap); + wxBitmap hBMap(std::format("#{}", IDB_MENU_ICON), + wxBITMAP_TYPE_BMP_RESOURCE); + wxASSERT(hBMap.IsOk()); + m_bmpMenuBtn = hBMap; + + m_sizeMenuBtn.x = m_bmpMenuBtn.GetWidth(); + m_sizeMenuBtn.y = m_bmpMenuBtn.GetHeight(); + + wxMemoryDC dc; + dc.SelectObject(m_bmpMenuBtn); + wxBrush brush(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE), wxBRUSHSTYLE_SOLID); + wxDCBrushChanger setBrush(dc, brush); + dc.FloodFill(m_sizeMenuBtn.x - 1, 0, wxColour(0, 255, 255), wxFLOOD_SURFACE); } ///////////////////////////////////////////////////////////////////////////// // CTrayPalette message handlers +#if 0 BOOL CTrayPalette::OnEraseBkgnd(CDC* pDC) { // Erase behind menu button only... @@ -839,6 +840,7 @@ BOOL CTrayPalette::OnEraseBkgnd(CDC* pDC) return TRUE; // controls take care of erase } +#if 0 LRESULT CTrayPalette::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) { if (message >= WM_MOUSEFIRST && message <= WM_MOUSELAST) @@ -856,6 +858,7 @@ LRESULT CTrayPalette::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) } return CWnd::WindowProc(message, wParam, lParam); } +#endif void CTrayPalette::OnSize(UINT nType, int cx, int cy) { @@ -1321,8 +1324,10 @@ void CTrayPalette::OnInitMenuPopup(CMenu* pMenu, UINT nIndex, BOOL bSysMenu) state.m_nIndexMax = nCount; } } +#endif CTrayPaletteContainer::CTrayPaletteContainer(CGamDoc& pDoc, UINT palID) : + CB::wxNativeContainerWindowMixin(static_cast(*this)), child(new CTrayPalette(*this, pDoc, palID)) { } @@ -1365,6 +1370,6 @@ void CTrayPaletteContainer::OnSetFocus(CWnd* pOldWnd) void CTrayPaletteContainer::OnSize(UINT nType, int cx, int cy) { - child->MoveWindow(0, 0, cx, cy); + child->SetSize(0, 0, cx, cy); return CWnd::OnSize(nType, cx, cy); } diff --git a/GP/PalTray.h b/GP/PalTray.h index 6327c8ef..a7d13b52 100644 --- a/GP/PalTray.h +++ b/GP/PalTray.h @@ -44,17 +44,15 @@ class CTraySet; // CTrayPalette window - Tray palette's are owned and reside in // the document object. -class CTrayPalette : public CWnd +class CTrayPalette : public wxPanel { -#if 0 - DECLARE_DYNAMIC(CTrayPalette) -#endif + wxDECLARE_CLASS(CTrayPalette); // Construction public: CTrayPalette(CTrayPaletteContainer& container, CGamDoc& pDoc, UINT palID); - BOOL Create(/*CWnd* pOwnerWnd, DWORD dwStyle = 0, UINT nID = 0*/); + BOOL Create(/*wxWindow& pOwnerWnd, DWORD dwStyle = 0, UINT nID = 0*/); // Attributes private: @@ -65,10 +63,10 @@ class CTrayPalette : public CWnd public: void DeselectAll(); void SelectTrayPiece(size_t nGroup, PieceID pid, const CB::string* pszNotificationTip); - void ShowTrayIndex(size_t nGroup, int nPos); + void ShowTrayIndex(size_t nGroup, size_t nPos); void UpdatePaletteContents(const CTraySet* pTray = NULL); - void Serialize(CArchive &ar) override; + void Serialize(CArchive &ar); // Implementation - vars protected: @@ -77,10 +75,10 @@ class CTrayPalette : public CWnd UINT m_nID; CB::propagate_const m_pDockingFrame; - CBitmap m_bmpMenuBtn; - CSize m_sizeMenuBtn; - CToolTipCtrl m_toolTipMenu; - CToolTipCtrl m_toolTipCombo; // For combobox overlay + wxBitmap m_bmpMenuBtn; + wxSize m_sizeMenuBtn; + CB::ToolTip m_toolTipMenu; + CB::ToolTip m_toolTipCombo; // For combobox overlay // This dummy area only contains a single entry. It is used // when only single entry should be shown in the Tray listbox. @@ -89,9 +87,12 @@ class CTrayPalette : public CWnd std::vector m_dummyArray; // Enclosed controls.... - CComboBox m_comboYGrp; - CTrayListBox m_listTray; + CB::propagate_const m_bpMenuBtn; + CB::propagate_const m_comboYGrp; + CB::propagate_const m_listTray; +#if 0 CRect m_rctMenuBtn; // phony menu button dims +#endif int m_nComboHeight; void LoadTrayNameList(); @@ -102,14 +103,16 @@ class CTrayPalette : public CWnd // Some temporary vars used during windows position restoration. // They are loaded during the de-serialization process. BOOL m_bStateVarsArmed; // Set so state restore is one-shot process - int m_nComboIndex; - int m_nListTopindex; + uint32_t m_nComboIndex; + uint32_t m_nListTopindex; std::vector m_tblListBoxSel; // Overrides public: +#if 0 LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam) override; +#endif // Implementation - methods protected: @@ -117,14 +120,13 @@ class CTrayPalette : public CWnd void DoEditSelectedPieceText(); BOOL EnsureTooltipExistance(); - void DoMenu(CPoint point, bool rightButton); + void DoMenu(wxPoint point, bool rightButton); private: GameElement menuGameElement = Invalid_v; -// Generated message map functions protected: - //{{AFX_MSG(CTrayPalette) +#if 0 afx_msg BOOL OnEraseBkgnd(CDC* pDC); afx_msg void OnSize(UINT nType, int cx, int cy); afx_msg void OnWindowPosChanging(WINDOWPOS FAR* lpwndpos); @@ -148,22 +150,25 @@ class CTrayPalette : public CWnd afx_msg BOOL OnHelpInfo(HELPINFO* pHelpInfo); afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); afx_msg void OnMouseMove(UINT nFlags, CPoint point); - //}}AFX_MSG afx_msg BOOL OnToolTipShow(UINT id, NMHDR *pNMH, LRESULT *pResult); afx_msg LRESULT OnMessageRestoreWinState(WPARAM, LPARAM); afx_msg LRESULT OnPaletteHide(WPARAM, LPARAM); afx_msg void OnInitMenuPopup(CMenu* pPopupMenu, UINT nIndex, BOOL bSysMenu); +#endif - DECLARE_MESSAGE_MAP() + wxDECLARE_EVENT_TABLE(); }; -class CTrayPaletteContainer : public CWnd +class CTrayPaletteContainer : public CWnd, + public CB::wxNativeContainerWindowMixin { public: CTrayPaletteContainer(CGamDoc& pDoc, UINT palID); BOOL Create(CWnd& pOwnerWnd/*, DWORD dwStyle = 0, UINT nID = 0*/); +#if 0 void PostNcDestroy() override; +#endif operator const CTrayPalette& () const { return *child; } operator CTrayPalette& () @@ -192,7 +197,8 @@ class CTrayPaletteContainer : public CWnd DECLARE_MESSAGE_MAP() CB::propagate_const m_pDockingFrame = nullptr; - OwnerPtr child; + // owned by wx + CB::propagate_const child = nullptr; }; ///////////////////////////////////////////////////////////////////////////// From 4058496fb719069c8b08044fa290bcdd03d80468 Mon Sep 17 00:00:00 2001 From: Bill Su Date: Sun, 8 Feb 2026 19:12:17 -0500 Subject: [PATCH 67/80] Gp.h: #include guard --- GP/Gp.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/GP/Gp.h b/GP/Gp.h index cb7053fa..1b21571f 100644 --- a/GP/Gp.h +++ b/GP/Gp.h @@ -22,6 +22,9 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +#if !defined(GP_H_) +#define GP_H_ + #ifndef __AFXWIN_H__ #error include 'stdafx.h' before including this file for PCH #endif @@ -259,3 +262,4 @@ inline CMainFrame* GetMainFrame() { return (CMainFrame*)(GetApp()->m_pMainWnd); ///////////////////////////////////////////////////////////////////////////// +#endif From 192ee3e82be3f25bcc4ed9e500d1cb62070170b9 Mon Sep 17 00:00:00 2001 From: Bill Su Date: Tue, 17 Feb 2026 23:52:03 -0500 Subject: [PATCH 68/80] GamDoc: DoEditPieceText() default all-sides off when no text to match CB3.1 --- GP/GamDoc5.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GP/GamDoc5.cpp b/GP/GamDoc5.cpp index e94e9e7d..b3ba37b5 100644 --- a/GP/GamDoc5.cpp +++ b/GP/GamDoc5.cpp @@ -234,7 +234,7 @@ void CGamDoc::DoEditPieceText(PieceID pid) { GameElement elemDown = MakePieceElement(pid, value_preserving_cast(i)); CB::string strDown = GetGameElementString(elemDown); - if (strDown != dlg.m_strText) + if (strDown.empty() || strDown != dlg.m_strText) { dlg.m_bSetAllSides = FALSE; break; From 7a9c44aaa763fda3bf2aafb7d65ad5c37dbbf304 Mon Sep 17 00:00:00 2001 From: Bill Su Date: Wed, 18 Feb 2026 00:50:07 -0500 Subject: [PATCH 69/80] LBoxVHScrl: fix GetSelections() to handle single selection list boxes --- GShr/LBoxVHScrl.cpp | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/GShr/LBoxVHScrl.cpp b/GShr/LBoxVHScrl.cpp index 5d922b5a..0941c97e 100644 --- a/GShr/LBoxVHScrl.cpp +++ b/GShr/LBoxVHScrl.cpp @@ -1,6 +1,6 @@ // LBoxVHScrl.cpp // -// Copyright (c) 2024-2025 By William Su, All Rights Reserved. +// Copyright (c) 2024-2026 By William Su, All Rights Reserved. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the @@ -61,13 +61,24 @@ namespace CB std::vector VListBoxHScroll::GetSelections() const { std::vector retval; - retval.reserve(GetSelectedCount()); - unsigned long cookie; - for (int sel = GetFirstSelected(cookie) ; - sel != wxNOT_FOUND ; - sel = GetNextSelected(cookie)) + if (HasMultipleSelection()) { - retval.push_back(value_preserving_cast(sel)); + retval.reserve(GetSelectedCount()); + unsigned long cookie; + for (int sel = GetFirstSelected(cookie) ; + sel != wxNOT_FOUND ; + sel = GetNextSelected(cookie)) + { + retval.push_back(value_preserving_cast(sel)); + } + } + else + { + int sel = GetSelection(); + if (sel != wxNOT_FOUND) + { + retval.push_back(value_preserving_cast(sel)); + } } return retval; } From 18c258517b30d3f31c66c88b423100c187baf645 Mon Sep 17 00:00:00 2001 From: Bill Su Date: Wed, 18 Feb 2026 01:06:18 -0500 Subject: [PATCH 70/80] LBoxGrfx: fix UpdateList() to handle change from non-empty ... to empty list box --- GShr/LBoxGrfx.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/GShr/LBoxGrfx.h b/GShr/LBoxGrfx.h index 904b9dfd..77925417 100644 --- a/GShr/LBoxGrfx.h +++ b/GShr/LBoxGrfx.h @@ -714,9 +714,11 @@ class CGrafixListBoxDataWx : public BASE_WND if (bKeepPosition) { this->ScrollToRow(CB::min(nTopIdx, nItem - size_t(1))); - if (nFcsIdx != wxNOT_FOUND) + if (nFcsIdx != wxNOT_FOUND && + this->GetItemCount() >= size_t(1)) this->SetCurrent(CB::min(nFcsIdx, value_preserving_cast(nItem - size_t(1)))); - if (nCurSel != wxNOT_FOUND) + if (nCurSel != wxNOT_FOUND && + this->GetItemCount() >= size_t(1)) this->SetSelection(CB::min(nCurSel, value_preserving_cast(nItem - size_t(1)))); } } From cbcbdf4d9b1b2566f164846d73ac19c91a94c9c4 Mon Sep 17 00:00:00 2001 From: Bill Su Date: Wed, 18 Feb 2026 23:58:19 -0500 Subject: [PATCH 71/80] PalTray: convert some event handlers from MFC to wx --- GP/LBoxTray.cpp | 20 +------ GP/PalTray.cpp | 146 +++++++++++++++++++++++++----------------------- GP/PalTray.h | 15 +++-- 3 files changed, 86 insertions(+), 95 deletions(-) diff --git a/GP/LBoxTray.cpp b/GP/LBoxTray.cpp index 30ac0696..09acbfc4 100644 --- a/GP/LBoxTray.cpp +++ b/GP/LBoxTray.cpp @@ -374,12 +374,10 @@ const CTileManager& CTrayListBoxWx::GetTileManager() const return m_pDoc->GetTileManager(); } -#if 0 -BOOL CTrayListBox::IsShowingTileImages() const +BOOL CTrayListBoxWx::IsShowingTileImages() const { return m_eTrayViz == trayVizAllSides || m_eTrayViz == trayVizOneSide; } -#endif void CTrayListBoxWx::SetTrayContentVisibility(TrayViz eTrayViz, CB::string pszHiddenString) { @@ -469,7 +467,6 @@ BOOL CTrayListBoxWx::OnDoesItemHaveTipText(size_t nItem) const { if (m_pDoc->HasGameElementString(MakePieceElement(pid, i))) { - wxASSERT(!"untested code"); return true; } } @@ -552,26 +549,11 @@ void CTrayListBoxWx::OnDrawItem(wxDC& pDC, const wxRect& rctItem, size_t nIndex) else { // Hidden pieces. Draw the supplied text. -#if 0 - pDC.SetTextAlign(TA_TOP | TA_LEFT); - CBrush brBack(GetSysColor(nState & ODS_SELECTED ? - COLOR_HIGHLIGHT : COLOR_WINDOW)); - pDC.FillRect(&rctItem, &brBack); // Fill background color - pDC.SetBkMode(TRANSPARENT); - CFont* pPrvFont = pDC.SelectObject(CFont::FromHandle(g_res.h8ss)); - pDC.SetTextColor(GetSysColor(nState & ODS_SELECTED ? - COLOR_HIGHLIGHTTEXT : COLOR_WINDOWTEXT)); - pDC.TextOut(rctItem.left, rctItem.top, m_strHiddenString); - pDC.SelectObject(pPrvFont); -#else - wxASSERT(!"needs testing"); - // TODO: is bkg automatic? pDC.SetBackgroundMode(wxBRUSHSTYLE_TRANSPARENT); pDC.SetFont(g_res.h8ssWx); pDC.SetTextForeground(wxSystemSettings::GetColour(IsSelected(nIndex) ? wxSYS_COLOUR_HIGHLIGHTTEXT : wxSYS_COLOUR_WINDOWTEXT)); pDC.DrawLabel(m_strHiddenString, rctItem, wxALIGN_TOP | wxALIGN_LEFT); -#endif #if 0 if (nAction & ODA_FOCUS) pDC.DrawFocusRect(&rctItem); diff --git a/GP/PalTray.cpp b/GP/PalTray.cpp index cc5d25b2..6f384c29 100644 --- a/GP/PalTray.cpp +++ b/GP/PalTray.cpp @@ -59,9 +59,11 @@ wxBEGIN_EVENT_TABLE(CTrayPalette, wxPanel) ON_WM_SIZE() ON_WM_CREATE() ON_WM_WINDOWPOSCHANGING() - ON_CBN_SELCHANGE(IDC_W_TRAYNAMECOMBO, OnTrayNameCbnSelchange) - ON_LBN_DBLCLK(IDC_W_TRAYLIST, OnTrayListDoubleClick) - ON_REGISTERED_MESSAGE(WM_DRAGDROP, OnDragItem) +#endif + EVT_CHOICE(XRCID("m_comboYGrp"), OnTrayNameCbnSelchange) + EVT_LISTBOX_DCLICK(XRCID("m_listTray"), OnTrayListDoubleClick) + EVT_DRAGDROP(OnDragItem) +#if 0 ON_MESSAGE(WM_OVERRIDE_SELECTED_ITEM_LIST, OnOverrideSelectedItemList) ON_MESSAGE(WM_GET_DRAG_SIZE, OnGetDragSize) ON_WM_CONTEXTMENU() @@ -90,8 +92,10 @@ wxBEGIN_EVENT_TABLE(CTrayPalette, wxPanel) ON_UPDATE_COMMAND_UI(ID_PTRAY_ABOUT, OnUpdatePieceTrayAbout) ON_WM_HELPINFO() ON_WM_MOUSEMOVE() - ON_MESSAGE(WM_WINSTATE_RESTORE, OnMessageRestoreWinState) - ON_MESSAGE(WM_PALETTE_HIDE, OnPaletteHide) +#endif + EVT_WINSTATE_RESTORE(OnMessageRestoreWinState) + EVT_COMMAND(wxID_ANY, WM_PALETTE_HIDE_WX, OnPaletteHide) +#if 0 ON_WM_INITMENUPOPUP() #endif wxEND_EVENT_TABLE() @@ -254,42 +258,40 @@ int CTrayPalette::FindTrayIndex(size_t nTrayNum) const return wxNOT_FOUND; } -#if 0 /////////////////////////////////////////////////////////////////////// // This method handles the custom message WM_WINSTATE_RESTORE. The // message is posted during view initial update if the state of // the windows should be restored. -LRESULT CTrayPalette::OnMessageRestoreWinState(WPARAM, LPARAM) +void CTrayPalette::OnMessageRestoreWinState(WinStateRestoreEvent& /*event*/) { UpdatePaletteContents(); if (!m_bStateVarsArmed) - return (LRESULT)0; + return; - m_comboYGrp.SetCurSel(m_nComboIndex); + m_comboYGrp->SetSelection(value_preserving_cast(m_nComboIndex)); UpdateTrayList(); for (size_t i = size_t(0) ; i < m_tblListBoxSel.size() ; ++i) - m_listTray.SetSel(m_tblListBoxSel[i]); - m_listTray.SetTopIndex(m_nListTopindex); + m_listTray->SetSelection(m_tblListBoxSel[i]); + m_listTray->ScrollToRow(m_nListTopindex); m_bStateVarsArmed = FALSE; - return (LRESULT)0; } ///////////////////////////////////////////////////////////////////////////// -LRESULT CTrayPalette::OnPaletteHide(WPARAM, LPARAM) +void CTrayPalette::OnPaletteHide(wxCommandEvent& /*event*/) { GetMainFrame()->SendMessage(WM_COMMAND, (WPARAM)(m_nID)); - return (LRESULT)0; } ///////////////////////////////////////////////////////////////////////////// +#if 0 void CTrayPalette::DoMenu(CPoint point, bool rightButton) { // remember clicked side in case of ID_ACT_TURNOVER_SELECT @@ -683,117 +685,117 @@ void CTrayPalette::UpdateTrayList() ///////////////////////////////////////////////////////////////////////////// -#if 0 -LRESULT CTrayPalette::OnDragItem(WPARAM wParam, LPARAM lParam) +void CTrayPalette::OnDragItem(DragDropEvent& event) { - if (wParam != GetProcessId(GetCurrentProcess())) + if (event.GetProcessId() != wxGetProcessId()) { - return -1; + return; } if (m_pDoc->IsPlaying()) - return -1; // Drags not supported during play + return; // Drags not supported during play - DragInfo* pdi = (DragInfo*)lParam; + const DragInfoWx& pdi = event.GetDragInfo(); - if (pdi->GetDragType() != DRAG_PIECE && pdi->GetDragType() != DRAG_SELECTLIST && - pdi->GetDragType() != DRAG_PIECELIST) - return -1; // Only piece drops allowed + if (pdi.GetDragType() != DRAG_PIECE && pdi.GetDragType() != DRAG_SELECTLIST && + pdi.GetDragType() != DRAG_PIECELIST) + return; // Only piece drops allowed - if (pdi->GetDragType() == DRAG_PIECE && pdi->GetSubInfo().m_gamDoc != &*m_pDoc || - pdi->GetDragType() == DRAG_SELECTLIST && pdi->GetSubInfo().m_gamDoc != &*m_pDoc || - pdi->GetDragType() == DRAG_PIECELIST && pdi->GetSubInfo().m_gamDoc != &*m_pDoc) - return -1; // Only pieces from our document. + if (pdi.GetDragType() == DRAG_PIECE && pdi.GetSubInfo().m_gamDoc != &*m_pDoc || + pdi.GetDragType() == DRAG_SELECTLIST && pdi.GetSubInfo().m_gamDoc != &*m_pDoc || + pdi.GetDragType() == DRAG_PIECELIST && pdi.GetSubInfo().m_gamDoc != &*m_pDoc) + return; // Only pieces from our document. - if (pdi->GetDragType() == DRAG_SELECTLIST) + if (pdi.GetDragType() == DRAG_SELECTLIST) { - if (!pdi->GetSubInfo().m_selectList->HasPieces()) - return -1; // Only piece drops allowed + if (!pdi.GetSubInfo().m_selectList->HasPieces()) + return; // Only piece drops allowed } // no size restriction size_t nGrpSel = GetSelectedTray(); if (nGrpSel == Invalid_v) - return -1; // No tray to drop on + return; // No tray to drop on - if (pdi->m_phase == PhaseDrag::Over) - return (LRESULT)(LPVOID)pdi->m_hcsrSuggest; - else if (pdi->m_phase == PhaseDrag::Drop) + if (pdi.m_phase == PhaseDrag::Over) + { + event.SetCursor(pdi.m_hcsrSuggest); + return; + } + else if (pdi.m_phase == PhaseDrag::Drop) { CTrayManager& pYMgr = m_pDoc->GetTrayManager(); CTraySet& pYGrp = pYMgr.GetTraySet(nGrpSel); // Force selection of item under the mouse - m_listTray.SetSelFromPoint(pdi->m_point); - int nSel = m_listTray.GetCount() <= 0 ? -1 : m_listTray.GetCurSel(); + m_listTray->SetSelFromPoint(pdi.m_point); + int nSel = m_listTray->GetSelectedCount() == size_t(0) ? wxNOT_FOUND : value_preserving_cast(m_listTray->GetSelections().front()); if (!m_pDoc->IsScenario() && pYGrp.IsOwnedButNotByCurrentPlayer(*m_pDoc) && pYGrp.GetTrayContentVisibility() == trayVizNone) - nSel = -1; // Always append pieces when dropping on single line view + nSel = wxNOT_FOUND; // Always append pieces when dropping on single line view - if (nSel >= 0) + if (nSel != wxNOT_FOUND) { // Check if the mouse is above or below the half point. // If above, insert before. If below, insert after. - CRect rct; - m_listTray.GetItemRect(nSel, &rct); - if (pdi->m_point.y > (rct.top + rct.bottom) / 2) + wxRect rct = m_listTray->GetItemRect(value_preserving_cast(nSel)); + if (pdi.m_point.y > GetMidRect(rct).y) nSel++; } size_t dropCount; - if (pdi->GetDragType() == DRAG_PIECE) + if (pdi.GetDragType() == DRAG_PIECE) { - ASSERT(!"untested code"); + wxASSERT(!"untested code"); dropCount = size_t(1); m_pDoc->AssignNewMoveGroup(); - m_pDoc->PlacePieceInTray(pdi->GetSubInfo().m_pieceID, pYGrp, nSel < 0 ? Invalid_v : value_preserving_cast(nSel)); + m_pDoc->PlacePieceInTray(pdi.GetSubInfo().m_pieceID, pYGrp, nSel == wxNOT_FOUND ? Invalid_v : value_preserving_cast(nSel)); // Select the last piece that was inserted - nSel = value_preserving_cast(pYGrp.GetPieceIDIndex(pdi->GetSubInfo().m_pieceID)); + nSel = value_preserving_cast(pYGrp.GetPieceIDIndex(pdi.GetSubInfo().m_pieceID)); } - else if (pdi->GetDragType() == DRAG_PIECELIST) + else if (pdi.GetDragType() == DRAG_PIECELIST) { m_pDoc->AssignNewMoveGroup(); - const std::vector& pieceIDList = CheckedDeref(pdi->GetSubInfo().m_pieceIDList); + const std::vector& pieceIDList = CheckedDeref(pdi.GetSubInfo().m_pieceIDList); dropCount = pieceIDList.size(); size_t temp = m_pDoc->PlacePieceListInTray(pieceIDList, - pYGrp, nSel < 0 ? Invalid_v : value_preserving_cast(nSel)); - nSel = temp == Invalid_v ? -1 : value_preserving_cast(temp); + pYGrp, nSel == wxNOT_FOUND ? Invalid_v : value_preserving_cast(nSel)); + nSel = temp == Invalid_v ? wxNOT_FOUND : value_preserving_cast(temp); } else // DRAG_SELECTLIST { - ASSERT(pdi->GetDragType() == DRAG_SELECTLIST); + wxASSERT(pdi.GetDragType() == DRAG_SELECTLIST); std::vector> m_listPtr; - CSelList* pSLst = pdi->GetSubInfo().m_selectList; + CSelList* pSLst = pdi.GetSubInfo().m_selectList; pSLst->LoadTableWithObjectPtrs(m_listPtr, CSelList::otAll, FALSE); pSLst->PurgeList(FALSE); dropCount = m_listPtr.size(); m_pDoc->AssignNewMoveGroup(); size_t temp = m_pDoc->PlaceObjectTableInTray(m_listPtr, - pYGrp, nSel < 0 ? Invalid_v : value_preserving_cast(nSel)); - nSel = temp == Invalid_v ? -1 : value_preserving_cast(temp); + pYGrp, nSel == wxNOT_FOUND ? Invalid_v : value_preserving_cast(nSel)); + nSel = temp == Invalid_v ? wxNOT_FOUND : value_preserving_cast(temp); m_pDoc->UpdateAllViews(NULL, HINT_UPDATESELECTLIST); } - if (nSel >= 0) + if (nSel != wxNOT_FOUND) { for (size_t i = size_t(0) ; i < dropCount ; ++i) { - m_listTray.SetSel(nSel - value_preserving_cast(i)); + m_listTray->SetSelection(nSel - value_preserving_cast(i)); } } - m_listTray.SetCurSel(nSel); + m_listTray->SetSelection(nSel); - // If the selection is out of view, force it into view. - CRect rctLBoxClient; - m_listTray.GetClientRect(&rctLBoxClient); - CRect rct; - m_listTray.GetItemRect(nSel, &rct); - if (!rct.IntersectRect(rct, rctLBoxClient)) - m_listTray.SetTopIndex(nSel); + if (nSel != wxNOT_FOUND) + { + // If the selection is out of view, force it into view. + wxRect rctLBoxClient = m_listTray->GetClientRect(); + wxRect rct = m_listTray->GetItemRect(value_preserving_cast(nSel)); + if (!rct.Intersects(rctLBoxClient)) + m_listTray->ScrollToRow(value_preserving_cast(nSel)); + } } - return 1; } -#endif ///////////////////////////////////////////////////////////////////////////// // Load the menu icon image and fill upper-right transparent area with @@ -891,21 +893,22 @@ void CTrayPalette::OnWindowPosChanging(WINDOWPOS FAR* lpwndpos) if (m_comboYGrp.m_hWnd != NULL) m_comboYGrp.ShowDropDown(FALSE); } +#endif ///////////////////////////////////////////////////////////////////////////// -void CTrayPalette::OnTrayNameCbnSelchange() +void CTrayPalette::OnTrayNameCbnSelchange(wxCommandEvent& /*event*/) { UpdateTrayList(); } -void CTrayPalette::OnTrayListDoubleClick() +void CTrayPalette::OnTrayListDoubleClick(wxCommandEvent& /*event*/) { - if (!m_listTray.IsShowingTileImages()) + if (!m_listTray->IsShowingTileImages()) return; - int nIndex = m_listTray.GetCaretIndex(); - if (nIndex < 0 || nIndex > 65535) + int nIndex = m_listTray->GetCurrent(); + if (nIndex == wxNOT_FOUND) return; size_t nSel = GetSelectedTray(); @@ -918,10 +921,11 @@ void CTrayPalette::OnTrayListDoubleClick() return; } - PieceID pid = m_listTray.MapIndexToItem(value_preserving_cast(nIndex)); + PieceID pid = m_listTray->MapIndexToItem(value_preserving_cast(nIndex)); m_pDoc->DoEditPieceText(pid); } +#if 0 void CTrayPalette::OnPieceTrayShuffle() { // Generate a shuffled index vector diff --git a/GP/PalTray.h b/GP/PalTray.h index a7d13b52..328d8137 100644 --- a/GP/PalTray.h +++ b/GP/PalTray.h @@ -25,6 +25,7 @@ #ifndef _PALTRAY_H #define _PALTRAY_H +#include "Gp.h" #ifndef _LBOXTRAY_H #include "LBoxTray.h" #endif @@ -130,9 +131,11 @@ class CTrayPalette : public wxPanel afx_msg BOOL OnEraseBkgnd(CDC* pDC); afx_msg void OnSize(UINT nType, int cx, int cy); afx_msg void OnWindowPosChanging(WINDOWPOS FAR* lpwndpos); - afx_msg void OnTrayNameCbnSelchange(); - afx_msg void OnTrayListDoubleClick(); - afx_msg LRESULT OnDragItem(WPARAM wParam, LPARAM lParam); +#endif + void OnTrayNameCbnSelchange(wxCommandEvent& event); + void OnTrayListDoubleClick(wxCommandEvent& event); + void OnDragItem(DragDropEvent& event); +#if 0 afx_msg LRESULT OnOverrideSelectedItemList(WPARAM wParam, LPARAM lParam); afx_msg LRESULT OnGetDragSize(WPARAM wParam, LPARAM lParam); afx_msg void OnContextMenu(CWnd* pWnd, CPoint point); @@ -151,8 +154,10 @@ class CTrayPalette : public wxPanel afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); afx_msg void OnMouseMove(UINT nFlags, CPoint point); afx_msg BOOL OnToolTipShow(UINT id, NMHDR *pNMH, LRESULT *pResult); - afx_msg LRESULT OnMessageRestoreWinState(WPARAM, LPARAM); - afx_msg LRESULT OnPaletteHide(WPARAM, LPARAM); +#endif + void OnMessageRestoreWinState(WinStateRestoreEvent& event); + void OnPaletteHide(wxCommandEvent& event); +#if 0 afx_msg void OnInitMenuPopup(CMenu* pPopupMenu, UINT nIndex, BOOL bSysMenu); #endif From fddc4437127ea7c2fd6c9abe7e9edb0a79b6f0d8 Mon Sep 17 00:00:00 2001 From: Bill Su Date: Fri, 20 Feb 2026 00:36:27 -0500 Subject: [PATCH 72/80] PalTray: convert MFC drag-from to wx --- GP/LBoxTray.cpp | 4 +--- GP/LBoxTray.h | 9 +++++++-- GP/PalTray.cpp | 49 +++++++++++++++++++++++------------------------ GP/PalTray.h | 4 ++-- GP/VwPbrd.cpp | 49 ++++++++++++++++++++++++----------------------- GP/VwPbrd.h | 2 +- GShr/DragDrop.cpp | 4 ++-- GShr/LBoxGrfx.h | 10 ++-------- 8 files changed, 64 insertions(+), 67 deletions(-) diff --git a/GP/LBoxTray.cpp b/GP/LBoxTray.cpp index 09acbfc4..0d6b2b2c 100644 --- a/GP/LBoxTray.cpp +++ b/GP/LBoxTray.cpp @@ -364,7 +364,6 @@ CTrayListBoxWx::CTrayListBoxWx(CGamDoc& pDoc) : CTrayListBoxWx() { Init(pDoc); - CGrafixListBoxDataWx::SetDocument(pDoc); } ///////////////////////////////////////////////////////////////////////////// @@ -596,7 +595,6 @@ std::vector CTrayListBoxWx::GetPieceTileIDs(size_t nIndex) const BOOL CTrayListBoxWx::OnDragSetup(DragInfoWx& pDI) const { - wxASSERT(!"needs testing"); if (m_pDoc->IsPlaying()) { pDI.SetDragType(DRAG_INVALID); @@ -613,7 +611,7 @@ BOOL CTrayListBoxWx::OnDragSetup(DragInfoWx& pDI) const } else { - ASSERT(!"untested code"); + wxASSERT(!"untested code"); pDI.SetDragType(DRAG_PIECE); pDI.GetSubInfo().m_pieceID = GetCurMapItem(); pDI.GetSubInfo().m_size = GetDragSize(); diff --git a/GP/LBoxTray.h b/GP/LBoxTray.h index f70c06fd..2006e5b9 100644 --- a/GP/LBoxTray.h +++ b/GP/LBoxTray.h @@ -1,6 +1,6 @@ // LBoxTray.cpp // -// Copyright (c) 1994-2025 By Dale L. Larson & William Su, All Rights Reserved. +// Copyright (c) 1994-2026 By Dale L. Larson & William Su, All Rights Reserved. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the @@ -112,7 +112,12 @@ class CTrayListBoxWx : public CGrafixListBoxDataWx public: CTrayListBoxWx(); CTrayListBoxWx(CGamDoc& pDoc); - void Init(const CGamDoc& pDoc) { wxASSERT(!m_pDoc); m_pDoc = &pDoc; } + void Init(CGamDoc& pDoc) + { + wxASSERT(!m_pDoc); + BASE::SetDocument(pDoc); + m_pDoc = &pDoc; + } // Attributes public: diff --git a/GP/PalTray.cpp b/GP/PalTray.cpp index 6f384c29..aeb63101 100644 --- a/GP/PalTray.cpp +++ b/GP/PalTray.cpp @@ -63,9 +63,9 @@ wxBEGIN_EVENT_TABLE(CTrayPalette, wxPanel) EVT_CHOICE(XRCID("m_comboYGrp"), OnTrayNameCbnSelchange) EVT_LISTBOX_DCLICK(XRCID("m_listTray"), OnTrayListDoubleClick) EVT_DRAGDROP(OnDragItem) + EVT_OVERRIDE_SELECTED_ITEM_LIST(OnOverrideSelectedItemList) + EVT_GET_DRAG_SIZE(OnGetDragSize) #if 0 - ON_MESSAGE(WM_OVERRIDE_SELECTED_ITEM_LIST, OnOverrideSelectedItemList) - ON_MESSAGE(WM_GET_DRAG_SIZE, OnGetDragSize) ON_WM_CONTEXTMENU() ON_COMMAND(ID_PTRAY_SHUFFLE, OnPieceTrayShuffle) ON_UPDATE_COMMAND_UI(ID_PTRAY_SHUFFLE, OnUpdatePieceTrayShuffle) @@ -350,19 +350,19 @@ void CTrayPalette::OnLButtonUp(UINT nFlags, CPoint point) m_listTray.GetWindowRect(rct); DoMenu(rct.TopLeft(), false); } +#endif ///////////////////////////////////////////////////////////////////////////// // This is called when this tray is dragging and dropping a list // of items. It gives the tray the chance to mess with the list's // contents prior to commiting it. -LRESULT CTrayPalette::OnOverrideSelectedItemList(WPARAM wParam, LPARAM /*lParam*/) +void CTrayPalette::OnOverrideSelectedItemList(OverrideSelectedItemListEvent& event) { - wxASSERT(dynamic_cast(reinterpret_cast(wParam))); - OverrideSelectedItemListEvent& oil = *reinterpret_cast(wParam); + OverrideSelectedItemListEvent& oil = event; size_t nSel = GetSelectedTray(); if (nSel == Invalid_v) - return (LRESULT)0; + return; CTrayManager& pYMgr = m_pDoc->GetTrayManager(); CTraySet& pYSet = pYMgr.GetTraySet(nSel); @@ -412,59 +412,58 @@ LRESULT CTrayPalette::OnOverrideSelectedItemList(WPARAM wParam, LPARAM /*lParam* m_pDoc->SetRandomNumberSeed(nRandSeed); } - return (LRESULT)1; + return; } -LRESULT CTrayPalette::OnGetDragSize(WPARAM wParam, LPARAM /*lParam*/) +void CTrayPalette::OnGetDragSize(GetDragSizeEvent& event) { size_t nSel = GetSelectedTray(); if (nSel == Invalid_v) { - ASSERT(!"bad tray"); - return 0; + wxASSERT(!"bad tray"); + event.Skip(); + return; } CTrayManager& pYMgr = m_pDoc->GetTrayManager(); CTraySet& pYSet = pYMgr.GetTraySet(nSel); - std::vector items; + std::vector items; if (pYSet.IsRandomPiecePull() || pYSet.IsRandomSidePull()) { - items.reserve(value_preserving_cast(m_listTray.GetCount())); - for (int i = 0 ; i < m_listTray.GetCount() ; ++i) + items.reserve(m_listTray->GetItemCount()); + for (size_t i = size_t(0) ; i < m_listTray->GetItemCount() ; ++i) { items.push_back(i); } } else { - items.resize(value_preserving_cast(m_listTray.GetSelCount())); - m_listTray.GetSelItems(value_preserving_cast(items.size()), items.data()); + items = m_listTray->GetSelections(); } // check all sides of all items CPieceTable& pieceTable = m_pDoc->GetPieceTable(); CTileManager& tileMgr = m_pDoc->GetTileManager(); PlayerMask player = m_pDoc->GetCurrentPlayerMask(); - CSize retval(0, 0); - for (int item : items) + wxSize retval(0, 0); + for (size_t item : items) { - PieceID pid = m_listTray.MapIndexToItem(value_preserving_cast(item)); + PieceID pid = m_listTray->MapIndexToItem(item); std::vector tids = pieceTable.GetInactiveTileIDs(pid, TRUE); tids.push_back(pieceTable.GetActiveTileID(pid, TRUE)); for (TileID tid : tids) { - ASSERT(tid != nullTid); - CSize size = tileMgr.GetTile(tid).GetSize(); - retval.cx = std::max(retval.cx, size.cx); - retval.cy = std::max(retval.cy, size.cy); + wxASSERT(tid != nullTid); + wxSize size = CB::Convert(tileMgr.GetTile(tid).GetSize()); + retval.x = CB::max(retval.x, size.x); + retval.y = CB::max(retval.y, size.y); } } - CheckedDeref(reinterpret_cast(wParam)) = retval; - return 1; + event.SetSize(retval); + return; } -#endif ///////////////////////////////////////////////////////////////////////////// diff --git a/GP/PalTray.h b/GP/PalTray.h index 328d8137..a3b21a87 100644 --- a/GP/PalTray.h +++ b/GP/PalTray.h @@ -135,9 +135,9 @@ class CTrayPalette : public wxPanel void OnTrayNameCbnSelchange(wxCommandEvent& event); void OnTrayListDoubleClick(wxCommandEvent& event); void OnDragItem(DragDropEvent& event); + void OnOverrideSelectedItemList(OverrideSelectedItemListEvent& event); + void OnGetDragSize(GetDragSizeEvent& event); #if 0 - afx_msg LRESULT OnOverrideSelectedItemList(WPARAM wParam, LPARAM lParam); - afx_msg LRESULT OnGetDragSize(WPARAM wParam, LPARAM lParam); afx_msg void OnContextMenu(CWnd* pWnd, CPoint point); afx_msg void OnLButtonUp(UINT nFlags, CPoint point); afx_msg void OnPieceTrayShuffle(); diff --git a/GP/VwPbrd.cpp b/GP/VwPbrd.cpp index e1a77015..21b3a7d8 100644 --- a/GP/VwPbrd.cpp +++ b/GP/VwPbrd.cpp @@ -690,7 +690,7 @@ void CPlayBoardView::OnDragItem(DragDropEvent& event) if (pdi.GetDragType() == DRAG_PIECELIST) { - DoDragPieceList(pdi); + DoDragPieceList(event); return; } @@ -743,48 +743,52 @@ void CPlayBoardView::DoDragPiece(const DragInfoWx& pdi) #endif } -void CPlayBoardView::DoDragPieceList(const DragInfoWx& pdi) +void CPlayBoardView::DoDragPieceList(DragDropEvent& event) { + const DragInfoWx& pdi = event.GetDragInfo(); if (pdi.GetSubInfo().m_gamDoc != &GetDocument()) return; // Only pieces from our document. -#if 0 // if piece can't fit on board, reject drop - CSize limit = m_pPBoard->GetBoard()->GetSize(fullScale); - if (pdi.GetSubInfo().m_size.cx > limit.cx || - pdi.GetSubInfo().m_size.cy > limit.cy) + wxSize limit = CB::Convert(m_pPBoard->GetBoard()->GetSize(fullScale)); + if (pdi.GetSubInfo().m_size.x > limit.x || + pdi.GetSubInfo().m_size.y > limit.y) { - return pdi.m_phase == PhaseDrag::Over ? - reinterpret_cast(g_res.hcrNoDropTooBig) - : - -1; + if (pdi.m_phase == PhaseDrag::Over) + { + event.SetCursor(g_res.hcrNoDropTooBigWx); + } + return; } if (pdi.m_phase == PhaseDrag::Exit) - DragKillAutoScroll(); + DisableAutoscrollWithoutCapture(); + else if (pdi.m_phase == PhaseDrag::Enter) + { + EnableAutoscrollWithoutCapture(); + } else if (pdi.m_phase == PhaseDrag::Over) { - DragCheckAutoScroll(); - return (LRESULT)(LPVOID)pdi.m_hcsrSuggest; + event.SetCursor(pdi.m_hcsrSuggest); } else if (pdi.m_phase == PhaseDrag::Drop) { CGamDoc& pDoc = GetDocument(); - CPoint pnt = pdi.m_point; + wxPoint pnt = pdi.m_point; const std::vector& pTbl = CheckedDeref(pdi.GetSubInfo().m_pieceIDList); pnt = ClientToWorkspace(pnt); // If the snap grid is on, adjust the point. - CSize sz = GetDocument().GetPieceTable().GetStackedSize(pTbl, - m_pPBoard->m_xStackStagger, m_pPBoard->m_yStackStagger); - ASSERT(sz.cx != 0 && sz.cy != 0); - CRect rct(CPoint(pnt.x - sz.cx/2, pnt.y - sz.cy/2), sz); + wxSize sz = CB::Convert(GetDocument().GetPieceTable().GetStackedSize(pTbl, + m_pPBoard->m_xStackStagger, m_pPBoard->m_yStackStagger)); + wxASSERT(sz.x != 0 && sz.y != 0); + wxRect rct(wxPoint(pnt.x - sz.x/2, pnt.y - sz.y/2), sz); rct = AdjustRect(rct); pnt = GetMidRect(rct); m_selList.PurgeList(TRUE); // Purge former selections GetDocument().AssignNewMoveGroup(); - GetDocument().PlacePieceListOnBoard(pnt, pTbl, + GetDocument().PlacePieceListOnBoard(CB::Convert(pnt), pTbl, m_pPBoard->m_xStackStagger, m_pPBoard->m_yStackStagger, m_pPBoard.get()); if (!pDoc.HasPlayers() || !m_pPBoard->IsOwned() || @@ -799,12 +803,9 @@ void CPlayBoardView::DoDragPieceList(const DragInfoWx& pdi) SelectAllObjectsInList(temp); // Reselect pieces dropped on board } - DragKillAutoScroll(); + DisableAutoscrollWithoutCapture(); } - return 1; -#else - wxASSERT(!"TODO:"); -#endif + return; } #define MARKER_DROP_GAP_X 8 diff --git a/GP/VwPbrd.h b/GP/VwPbrd.h index f07e0038..83868269 100644 --- a/GP/VwPbrd.h +++ b/GP/VwPbrd.h @@ -200,7 +200,7 @@ class CPlayBoardView : public CB::ProcessEventOverride void DoDragPiece(const DragInfoWx& pdi); void DoDragMarker(DragDropEvent& event); - void DoDragPieceList(const DragInfoWx& pdi); + void DoDragPieceList(DragDropEvent& event); void DoDragSelectList(DragDropEvent& event); #if 0 diff --git a/GShr/DragDrop.cpp b/GShr/DragDrop.cpp index e17d1d05..444cd1a7 100644 --- a/GShr/DragDrop.cpp +++ b/GShr/DragDrop.cpp @@ -100,10 +100,10 @@ void DragInfoWx::SetDragType(DragType dt) case DRAG_PIECE: subInfos.m_piece.~SubInfo(); break; +#endif case DRAG_PIECELIST: subInfos.m_pieceList.~SubInfo(); break; -#endif case DRAG_MARKER: subInfos.m_marker.~SubInfo(); break; @@ -136,10 +136,10 @@ void DragInfoWx::SetDragType(DragType dt) case DRAG_PIECE: new (&subInfos.m_piece) SubInfo; break; +#endif case DRAG_PIECELIST: new (&subInfos.m_pieceList) SubInfo; break; -#endif case DRAG_MARKER: new (&subInfos.m_marker) SubInfo; break; diff --git a/GShr/LBoxGrfx.h b/GShr/LBoxGrfx.h index 77925417..fadc2020 100644 --- a/GShr/LBoxGrfx.h +++ b/GShr/LBoxGrfx.h @@ -788,15 +788,9 @@ class CGrafixListBoxDataWx : public BASE_WND m_multiSelList = GetCurMappedItemList(); // this is only needed for PalTray, so don't implement now -#if defined(GPLAY) - wxASSERT(!"TODO:"); -#if 0 - CWnd* pWnd = this->GetParent(); - ASSERT(pWnd != NULL); + wxWindow& pWnd = CheckedDeref(this->GetParent()); OverrideSelectedItemListEvent oil(m_multiSelList); - pWnd->SendMessage(WM_OVERRIDE_SELECTED_ITEM_LIST, reinterpret_cast(&oil)); -#endif -#endif + pWnd.ProcessWindowEvent(oil); } else { From b3b531397d4580acde8a1429c6b896a6eda7881b Mon Sep 17 00:00:00 2001 From: Bill Su Date: Sun, 22 Feb 2026 16:44:49 -0500 Subject: [PATCH 73/80] PalTray: convert context menu from MFC to wx --- GP/CBPlay.fbp | 22 +++++++------- GP/CBPlay.xrc | 22 +++++++------- GP/PalTray.cpp | 78 ++++++++++++++++++++++---------------------------- GP/PalTray.h | 10 +++---- 4 files changed, 62 insertions(+), 70 deletions(-) diff --git a/GP/CBPlay.fbp b/GP/CBPlay.fbp index 2cbbf966..1ddd6548 100644 --- a/GP/CBPlay.fbp +++ b/GP/CBPlay.fbp @@ -17863,7 +17863,7 @@ 0 1 - + Turn the selected piece over to the next side wxID_ANY wxITEM_NORMAL &Next @@ -17876,7 +17876,7 @@ 0 1 - + Turn the selected piece over to the prev side wxID_ANY wxITEM_NORMAL &Prev @@ -17889,7 +17889,7 @@ 0 1 - + Turn the selected piece over to a random side wxID_ANY wxITEM_NORMAL &Random @@ -17908,7 +17908,7 @@ 0 1 - + Turn over all pieces in the Tray to the next side. wxID_ANY wxITEM_NORMAL &Next @@ -17921,7 +17921,7 @@ 0 1 - + Turn over all pieces in the Tray to the previous side. wxID_ANY wxITEM_NORMAL &Prev @@ -17934,7 +17934,7 @@ 0 1 - + Turn over all pieces in the Tray to a random side. wxID_ANY wxITEM_NORMAL &Random @@ -17948,7 +17948,7 @@ 0 1 - + Turn the clicked piece over to the clicked side wxID_ANY wxITEM_NORMAL Turn Over to Clicked Side @@ -17965,7 +17965,7 @@ 0 1 - + Shuffle (randomize) only the tray's selected items. wxID_ANY wxITEM_NORMAL Shuffle Selected Items @@ -17978,7 +17978,7 @@ 0 1 - + Shuffle (randomize) the tray's contents wxID_ANY wxITEM_NORMAL Shuffle All Pieces @@ -17995,7 +17995,7 @@ 0 1 - + Edit text associated with a piece or marker wxID_ANY wxITEM_NORMAL Edit Object Text... @@ -18012,7 +18012,7 @@ 0 1 - + Show information about the currently selected tray. wxID_ANY wxITEM_NORMAL About the Selected Tray... diff --git a/GP/CBPlay.xrc b/GP/CBPlay.xrc index 78a60270..f49e421f 100644 --- a/GP/CBPlay.xrc +++ b/GP/CBPlay.xrc @@ -3748,17 +3748,17 @@ - + Turn the selected piece over to the next side - + Turn the selected piece over to the prev side - + Turn the selected piece over to a random side @@ -3766,46 +3766,46 @@ - + Turn over all pieces in the Tray to the next side. - + Turn over all pieces in the Tray to the previous side. - + Turn over all pieces in the Tray to a random side. - + Turn the clicked piece over to the clicked side - + Shuffle (randomize) only the tray's selected items. - + Shuffle (randomize) the tray's contents - + Edit text associated with a piece or marker - + Show information about the currently selected tray. diff --git a/GP/PalTray.cpp b/GP/PalTray.cpp index aeb63101..b537b824 100644 --- a/GP/PalTray.cpp +++ b/GP/PalTray.cpp @@ -65,11 +65,11 @@ wxBEGIN_EVENT_TABLE(CTrayPalette, wxPanel) EVT_DRAGDROP(OnDragItem) EVT_OVERRIDE_SELECTED_ITEM_LIST(OnOverrideSelectedItemList) EVT_GET_DRAG_SIZE(OnGetDragSize) + EVT_CONTEXT_MENU(OnContextMenu) + EVT_MENU(XRCID("ID_PTRAY_SHUFFLE"), OnPieceTrayShuffle) + EVT_UPDATE_UI(XRCID("ID_PTRAY_SHUFFLE"), OnUpdatePieceTrayShuffle) + EVT_BUTTON(XRCID("m_bpMenuBtn"), OnMenuButton) #if 0 - ON_WM_CONTEXTMENU() - ON_COMMAND(ID_PTRAY_SHUFFLE, OnPieceTrayShuffle) - ON_UPDATE_COMMAND_UI(ID_PTRAY_SHUFFLE, OnUpdatePieceTrayShuffle) - ON_WM_LBUTTONUP() ON_COMMAND(ID_PTRAY_SHUFFLE_SELECTED, OnPieceTrayShuffleSelected) ON_UPDATE_COMMAND_UI(ID_PTRAY_SHUFFLE_SELECTED, OnUpdatePieceTrayShuffleSelected) ON_COMMAND(ID_EDIT_ELEMENT_TEXT, OnEditElementText) @@ -291,24 +291,21 @@ void CTrayPalette::OnPaletteHide(wxCommandEvent& /*event*/) ///////////////////////////////////////////////////////////////////////////// -#if 0 -void CTrayPalette::DoMenu(CPoint point, bool rightButton) +void CTrayPalette::DoMenu(wxPoint point) { // remember clicked side in case of ID_ACT_TURNOVER_SELECT - CPoint clientPoint(point); - ScreenToClient(&clientPoint); - CWnd* child = ChildWindowFromPoint(clientPoint); - ASSERT(child == this || child == &m_listTray); - if (child == &m_listTray) + wxWindow* child = wxFindWindowAtPoint(point); + wxASSERT(child == &*m_bpMenuBtn || child == &*m_listTray); + if (child == &*m_listTray) { - CRect rect; - MapWindowPoints(&m_listTray, &clientPoint, 1); + wxRect rect; + wxPoint clientPoint = m_listTray->ScreenToClient(point); /* KLUDGE: OnGetHitItemCodeAtPoint is public in base CGrafixListBox, but protected in derived CTrayListBox. Why? */ - menuGameElement = static_cast(m_listTray).OnGetHitItemCodeAtPoint(clientPoint, rect); + menuGameElement = static_cast(*m_listTray).OnGetHitItemCodeAtPoint(clientPoint, rect); // ASSERT(menuGameElement != Invalid_v --> menuGameElement.IsAPiece() - ASSERT(menuGameElement == Invalid_v || + wxASSERT(menuGameElement == Invalid_v || menuGameElement.IsAPiece()); } else @@ -316,41 +313,36 @@ void CTrayPalette::DoMenu(CPoint point, bool rightButton) menuGameElement = Invalid_v; } - CMenu bar; - if (bar.LoadMenuW(IDR_MENU_PLAYER_POPUPS)) + std::unique_ptr bar(wxXmlResource::Get()->LoadMenuBar("IDR_MENU_PLAYER_POPUPS")); + if (bar) { - CMenu& popup = *bar.GetSubMenu(MENU_PV_PIECE_TRAY); - ASSERT(popup.m_hMenu != NULL); + int index = bar->FindMenu("5=PV_PIECE_TRAY"); + wxASSERT(index != wxNOT_FOUND); + std::unique_ptr popup(bar->Remove(value_preserving_cast(index))); // Make sure we clean up even if exception is tossed. - TRY + try { - popup.TrackPopupMenu(TPM_LEFTBUTTON | - TPM_LEFTALIGN | - (rightButton ? TPM_RIGHTBUTTON : 0), - point.x, point.y, this); // Route commands through tray window + PopupMenu(&*popup, ScreenToClient(point)); + } + catch (...) + { + wxASSERT(!"exception"); } - END_TRY - } - else - { - ASSERT(!"LoadMenu error"); } } -void CTrayPalette::OnContextMenu(CWnd* pWnd, CPoint point) +void CTrayPalette::OnContextMenu(wxContextMenuEvent& event) { - DoMenu(point, true); + DoMenu(event.GetPosition()); } -void CTrayPalette::OnLButtonUp(UINT nFlags, CPoint point) +void CTrayPalette::OnMenuButton(wxCommandEvent& /*event*/) { - CRect rct; // Use the list box as a guide of where to place the menu - m_listTray.GetWindowRect(rct); - DoMenu(rct.TopLeft(), false); + wxRect rct = m_listTray->GetScreenRect(); + DoMenu(rct.GetTopLeft()); } -#endif ///////////////////////////////////////////////////////////////////////////// // This is called when this tray is dragging and dropping a list @@ -924,12 +916,11 @@ void CTrayPalette::OnTrayListDoubleClick(wxCommandEvent& /*event*/) m_pDoc->DoEditPieceText(pid); } -#if 0 -void CTrayPalette::OnPieceTrayShuffle() +void CTrayPalette::OnPieceTrayShuffle(wxCommandEvent& /*event*/) { // Generate a shuffled index vector uint32_t nRandSeed = m_pDoc->GetRandomNumberSeed(); - size_t nNumIndices = value_preserving_cast(m_listTray.GetCount()); + size_t nNumIndices = m_listTray->GetItemCount(); std::vector pnIndices = AllocateAndCalcRandomIndexVector(nNumIndices, nNumIndices, nRandSeed, &nRandSeed); m_pDoc->SetRandomNumberSeed(nRandSeed); @@ -938,7 +929,7 @@ void CTrayPalette::OnPieceTrayShuffle() std::vector tblPids; tblPids.reserve(value_preserving_cast(nNumIndices)); for (size_t i = size_t(0) ; i < nNumIndices ; ++i) - tblPids.push_back(m_listTray.MapIndexToItem(pnIndices[i])); + tblPids.push_back(m_listTray->MapIndexToItem(pnIndices[i])); m_pDoc->AssignNewMoveGroup(); @@ -954,7 +945,7 @@ void CTrayPalette::OnPieceTrayShuffle() m_pDoc->PlacePieceListInTray(tblPids, pYMgr.GetTraySet(nSel), 0); } -void CTrayPalette::OnUpdatePieceTrayShuffle(CCmdUI* pCmdUI) +void CTrayPalette::OnUpdatePieceTrayShuffle(wxUpdateUIEvent& pCmdUI) { BOOL bNoOwnerRestrictions = TRUE; size_t nSel = GetSelectedTray(); @@ -965,10 +956,11 @@ void CTrayPalette::OnUpdatePieceTrayShuffle(CCmdUI* pCmdUI) bNoOwnerRestrictions = !(pYSet.IsOwnedButNotByCurrentPlayer(*m_pDoc) && !pYSet.IsNonOwnerAccessAllowed()); } - pCmdUI->Enable((m_pDoc->IsScenario() || bNoOwnerRestrictions) && - m_listTray.GetCount() > 1); + pCmdUI.Enable((m_pDoc->IsScenario() || bNoOwnerRestrictions) && + m_listTray->GetItemCount() > 1); } +#if 0 void CTrayPalette::OnPieceTrayShuffleSelected() { size_t nNumSelected = value_preserving_cast(m_listTray.GetSelCount()); diff --git a/GP/PalTray.h b/GP/PalTray.h index a3b21a87..3672f3a2 100644 --- a/GP/PalTray.h +++ b/GP/PalTray.h @@ -121,7 +121,7 @@ class CTrayPalette : public wxPanel void DoEditSelectedPieceText(); BOOL EnsureTooltipExistance(); - void DoMenu(wxPoint point, bool rightButton); + void DoMenu(wxPoint point); private: GameElement menuGameElement = Invalid_v; @@ -137,11 +137,11 @@ class CTrayPalette : public wxPanel void OnDragItem(DragDropEvent& event); void OnOverrideSelectedItemList(OverrideSelectedItemListEvent& event); void OnGetDragSize(GetDragSizeEvent& event); + void OnContextMenu(wxContextMenuEvent& event); + void OnMenuButton(wxCommandEvent& event); + void OnPieceTrayShuffle(wxCommandEvent& event); + void OnUpdatePieceTrayShuffle(wxUpdateUIEvent& pCmdUI); #if 0 - afx_msg void OnContextMenu(CWnd* pWnd, CPoint point); - afx_msg void OnLButtonUp(UINT nFlags, CPoint point); - afx_msg void OnPieceTrayShuffle(); - afx_msg void OnUpdatePieceTrayShuffle(CCmdUI* pCmdUI); afx_msg void OnPieceTrayShuffleSelected(); afx_msg void OnUpdatePieceTrayShuffleSelected(CCmdUI* pCmdUI); afx_msg void OnEditElementText(); From 6296b076b20225cb515c845ba6556685c417fd9d Mon Sep 17 00:00:00 2001 From: Bill Su Date: Thu, 26 Feb 2026 22:50:13 -0500 Subject: [PATCH 74/80] PalTray: convert MFC message handlers to wx --- GP/PalTray.cpp | 240 +++++++++++++++++++++++++------------------------ GP/PalTray.h | 16 ++-- 2 files changed, 129 insertions(+), 127 deletions(-) diff --git a/GP/PalTray.cpp b/GP/PalTray.cpp index b537b824..054c60df 100644 --- a/GP/PalTray.cpp +++ b/GP/PalTray.cpp @@ -69,27 +69,27 @@ wxBEGIN_EVENT_TABLE(CTrayPalette, wxPanel) EVT_MENU(XRCID("ID_PTRAY_SHUFFLE"), OnPieceTrayShuffle) EVT_UPDATE_UI(XRCID("ID_PTRAY_SHUFFLE"), OnUpdatePieceTrayShuffle) EVT_BUTTON(XRCID("m_bpMenuBtn"), OnMenuButton) + EVT_MENU(XRCID("ID_PTRAY_SHUFFLE_SELECTED"), OnPieceTrayShuffleSelected) + EVT_UPDATE_UI(XRCID("ID_PTRAY_SHUFFLE_SELECTED"), OnUpdatePieceTrayShuffleSelected) + EVT_MENU(XRCID("ID_EDIT_ELEMENT_TEXT"), OnEditElementText) + EVT_UPDATE_UI(XRCID("ID_EDIT_ELEMENT_TEXT"), OnUpdateEditElementText) + EVT_MENU(XRCID("ID_ACT_TURNOVER"), OnActTurnOver) + EVT_MENU(XRCID("ID_ACT_TURNOVER_PREV"), OnActTurnOver) + EVT_MENU(XRCID("ID_ACT_TURNOVER_RANDOM"), OnActTurnOver) + EVT_UPDATE_UI(XRCID("ID_ACT_TURNOVER"), OnUpdateActTurnOver) + EVT_UPDATE_UI(XRCID("ID_ACT_TURNOVER_PREV"), OnUpdateActTurnOver) + EVT_UPDATE_UI(XRCID("ID_ACT_TURNOVER_RANDOM"), OnUpdateActTurnOver) + EVT_MENU(XRCID("ID_ACT_TURNOVER_ALL"), OnActTurnOver) + EVT_MENU(XRCID("ID_ACT_TURNOVER_ALL_PREV"), OnActTurnOver) + EVT_MENU(XRCID("ID_ACT_TURNOVER_ALL_RANDOM"), OnActTurnOver) + EVT_UPDATE_UI(XRCID("ID_ACT_TURNOVER_ALL"), OnUpdateActTurnOver) + EVT_UPDATE_UI(XRCID("ID_ACT_TURNOVER_ALL_PREV"), OnUpdateActTurnOver) + EVT_UPDATE_UI(XRCID("ID_ACT_TURNOVER_ALL_RANDOM"), OnUpdateActTurnOver) + EVT_MENU(XRCID("ID_ACT_TURNOVER_SELECT"), OnActTurnOver) + EVT_UPDATE_UI(XRCID("ID_ACT_TURNOVER_SELECT"), OnUpdateActTurnOver) + EVT_MENU(XRCID("ID_PTRAY_ABOUT"), OnPieceTrayAbout) + EVT_UPDATE_UI(XRCID("ID_PTRAY_ABOUT"), OnUpdatePieceTrayAbout) #if 0 - ON_COMMAND(ID_PTRAY_SHUFFLE_SELECTED, OnPieceTrayShuffleSelected) - ON_UPDATE_COMMAND_UI(ID_PTRAY_SHUFFLE_SELECTED, OnUpdatePieceTrayShuffleSelected) - ON_COMMAND(ID_EDIT_ELEMENT_TEXT, OnEditElementText) - ON_UPDATE_COMMAND_UI(ID_EDIT_ELEMENT_TEXT, OnUpdateEditElementText) - ON_COMMAND_EX(ID_ACT_TURNOVER, OnActTurnOver) - ON_COMMAND_EX(ID_ACT_TURNOVER_PREV, OnActTurnOver) - ON_COMMAND_EX(ID_ACT_TURNOVER_RANDOM, OnActTurnOver) - ON_UPDATE_COMMAND_UI(ID_ACT_TURNOVER, OnUpdateActTurnOver) - ON_UPDATE_COMMAND_UI(ID_ACT_TURNOVER_PREV, OnUpdateActTurnOver) - ON_UPDATE_COMMAND_UI(ID_ACT_TURNOVER_RANDOM, OnUpdateActTurnOver) - ON_COMMAND_EX(ID_ACT_TURNOVER_ALL, OnActTurnOver) - ON_COMMAND_EX(ID_ACT_TURNOVER_ALL_PREV, OnActTurnOver) - ON_COMMAND_EX(ID_ACT_TURNOVER_ALL_RANDOM, OnActTurnOver) - ON_UPDATE_COMMAND_UI(ID_ACT_TURNOVER_ALL, OnUpdateActTurnOver) - ON_UPDATE_COMMAND_UI(ID_ACT_TURNOVER_ALL_PREV, OnUpdateActTurnOver) - ON_UPDATE_COMMAND_UI(ID_ACT_TURNOVER_ALL_RANDOM, OnUpdateActTurnOver) - ON_COMMAND_EX(ID_ACT_TURNOVER_SELECT, OnActTurnOver) - ON_UPDATE_COMMAND_UI(ID_ACT_TURNOVER_SELECT, OnUpdateActTurnOver) - ON_COMMAND(ID_PTRAY_ABOUT, OnPieceTrayAbout) - ON_UPDATE_COMMAND_UI(ID_PTRAY_ABOUT, OnUpdatePieceTrayAbout) ON_WM_HELPINFO() ON_WM_MOUSEMOVE() #endif @@ -960,27 +960,24 @@ void CTrayPalette::OnUpdatePieceTrayShuffle(wxUpdateUIEvent& pCmdUI) m_listTray->GetItemCount() > 1); } -#if 0 -void CTrayPalette::OnPieceTrayShuffleSelected() +void CTrayPalette::OnPieceTrayShuffleSelected(wxCommandEvent& /*event*/) { - size_t nNumSelected = value_preserving_cast(m_listTray.GetSelCount()); - std::vector tblListSel(nNumSelected); - m_listTray.GetSelItems(value_preserving_cast(nNumSelected), tblListSel.data()); + std::vector tblListSel = m_listTray->GetSelections(); + size_t nNumSelected = tblListSel.size(); - INT nTopSel = tblListSel[size_t(0)]; // This is where the shuffle is inserted + size_t nTopSel = tblListSel[size_t(0)]; // This is where the shuffle is inserted // Generate a shuffled index vector for the number of selected items uint32_t nRandSeed = m_pDoc->GetRandomNumberSeed(); - ASSERT(nNumSelected == tblListSel.size()); std::vector pnIndices = AllocateAndCalcRandomIndexVector(nNumSelected, nNumSelected, nRandSeed, &nRandSeed); m_pDoc->SetRandomNumberSeed(nRandSeed); // Build table of shuffled pieces std::vector tblPids; - tblPids.reserve(value_preserving_cast(nNumSelected)); + tblPids.reserve(nNumSelected); for (size_t i = size_t(0) ; i < nNumSelected ; ++i) - tblPids.push_back(m_listTray.MapIndexToItem(value_preserving_cast(tblListSel[pnIndices[i]]))); + tblPids.push_back(m_listTray->MapIndexToItem(tblListSel[pnIndices[i]])); m_pDoc->AssignNewMoveGroup(); @@ -996,7 +993,7 @@ void CTrayPalette::OnPieceTrayShuffleSelected() m_pDoc->PlacePieceListInTray(tblPids, pYMgr.GetTraySet(nSel), value_preserving_cast(nTopSel)); } -void CTrayPalette::OnUpdatePieceTrayShuffleSelected(CCmdUI* pCmdUI) +void CTrayPalette::OnUpdatePieceTrayShuffleSelected(wxUpdateUIEvent& pCmdUI) { BOOL bNoOwnerRestrictions = TRUE; size_t nSel = GetSelectedTray(); @@ -1008,16 +1005,16 @@ void CTrayPalette::OnUpdatePieceTrayShuffleSelected(CCmdUI* pCmdUI) !pYSet.IsNonOwnerAccessAllowed()); } - pCmdUI->Enable((m_pDoc->IsScenario() || bNoOwnerRestrictions) && - m_listTray.GetSelCount() > 1 && m_listTray.IsShowingTileImages()); + pCmdUI.Enable((m_pDoc->IsScenario() || bNoOwnerRestrictions) && + m_listTray->GetSelectedCount() > size_t(1) && m_listTray->IsShowingTileImages()); } -void CTrayPalette::OnEditElementText() +void CTrayPalette::OnEditElementText(wxCommandEvent& event) { DoEditSelectedPieceText(); } -void CTrayPalette::OnUpdateEditElementText(CCmdUI* pCmdUI) +void CTrayPalette::OnUpdateEditElementText(wxUpdateUIEvent& pCmdUI) { BOOL bNoOwnerRestrictions = TRUE; size_t nSel = GetSelectedTray(); @@ -1027,71 +1024,71 @@ void CTrayPalette::OnUpdateEditElementText(CCmdUI* pCmdUI) CTraySet& pYSet = pYMgr.GetTraySet(nSel); bNoOwnerRestrictions = !pYSet.IsOwnedButNotByCurrentPlayer(*m_pDoc); } - pCmdUI->Enable((m_pDoc->IsScenario() || bNoOwnerRestrictions) && - m_listTray.GetSelCount() == 1 && m_listTray.IsShowingTileImages()); + pCmdUI.Enable((m_pDoc->IsScenario() || bNoOwnerRestrictions) && + m_listTray->GetSelectedCount() == size_t(1) && m_listTray->IsShowingTileImages()); } -BOOL CTrayPalette::OnActTurnOver(UINT id) +void CTrayPalette::OnActTurnOver(wxCommandEvent& event) { - std::vector tblListSel; - int nNumSelected = m_listTray.GetSelCount(); - if (nNumSelected) - { - tblListSel.resize(value_preserving_cast(nNumSelected)); - m_listTray.GetSelItems(nNumSelected, &tblListSel.front()); - } + int id = event.GetId(); + std::vector tblListSel = m_listTray->GetSelections(); - std::vector tblListSubjects; - std::vector* chosen; + std::vector tblListSubjects; + std::vector* chosen; - switch (id) + if (id == XRCID("ID_ACT_TURNOVER") || + id == XRCID("ID_ACT_TURNOVER_PREV") || + id == XRCID("ID_ACT_TURNOVER_RANDOM")) { - case ID_ACT_TURNOVER: - case ID_ACT_TURNOVER_PREV: - case ID_ACT_TURNOVER_RANDOM: - // operate on selected pieces - chosen = &tblListSel; - break; - case ID_ACT_TURNOVER_ALL: - case ID_ACT_TURNOVER_ALL_PREV: - case ID_ACT_TURNOVER_ALL_RANDOM: - // operate on all pieces - tblListSubjects.resize(value_preserving_cast(m_listTray.GetCount())); - for (int i = 0; i < m_listTray.GetCount(); i++) - { - tblListSubjects[value_preserving_cast(i)] = i; - } - chosen = &tblListSubjects; - break; - case ID_ACT_TURNOVER_SELECT: - // operate on clicked side - tblListSubjects.push_back(value_preserving_cast(m_listTray.MapItemToIndex(static_cast(menuGameElement)))); - chosen = &tblListSubjects; - break; - default: - AfxThrowInvalidArgException(); + // operate on selected pieces + chosen = &tblListSel; + } + else if (id == XRCID("ID_ACT_TURNOVER_ALL") || + id == XRCID("ID_ACT_TURNOVER_ALL_PREV") || + id == XRCID("ID_ACT_TURNOVER_ALL_RANDOM")) + { + // operate on all pieces + tblListSubjects.resize(m_listTray->GetItemCount()); + for (size_t i = size_t(0) ; i < m_listTray->GetItemCount() ; ++i) + { + tblListSubjects[i] = i; + } + chosen = &tblListSubjects; + } + else if (id == XRCID("ID_ACT_TURNOVER_SELECT")) + { + // operate on clicked side + tblListSubjects.push_back(m_listTray->MapItemToIndex(static_cast(menuGameElement))); + chosen = &tblListSubjects; + } + else + { + AfxThrowInvalidArgException(); } CPieceTable::Flip flip; - switch (id) + if (id == XRCID("ID_ACT_TURNOVER") || + id == XRCID("ID_ACT_TURNOVER_ALL")) { - case ID_ACT_TURNOVER: - case ID_ACT_TURNOVER_ALL: - flip = CPieceTable::fNext; - break; - case ID_ACT_TURNOVER_PREV: - case ID_ACT_TURNOVER_ALL_PREV: - flip = CPieceTable::fPrev; - break; - case ID_ACT_TURNOVER_RANDOM: - case ID_ACT_TURNOVER_ALL_RANDOM: - flip = CPieceTable::fRandom; - break; - case ID_ACT_TURNOVER_SELECT: - flip = CPieceTable::fSelect; - break; - default: - AfxThrowInvalidArgException(); + flip = CPieceTable::fNext; + } + else if (id == XRCID("ID_ACT_TURNOVER_PREV") || + id == XRCID("ID_ACT_TURNOVER_ALL_PREV")) + { + flip = CPieceTable::fPrev; + } + else if (id == XRCID("ID_ACT_TURNOVER_RANDOM") || + id == XRCID("ID_ACT_TURNOVER_ALL_RANDOM")) + { + flip = CPieceTable::fRandom; + } + else if (id == XRCID("ID_ACT_TURNOVER_SELECT")) + { + flip = CPieceTable::fSelect; + } + else + { + AfxThrowInvalidArgException(); } m_pDoc->AssignNewMoveGroup(); @@ -1100,12 +1097,12 @@ BOOL CTrayPalette::OnActTurnOver(UINT id) if (m_pDoc->IsRecording() && flip == CPieceTable::fRandom) { CB::string strMsg = CB::string::Format(IDS_TIP_TRAY_FLIPPED_RANDOM, chosen->size()); - m_pDoc->RecordEventMessage(strMsg, nSel, m_listTray.MapIndexToItem(value_preserving_cast(chosen->front()))); + m_pDoc->RecordEventMessage(strMsg, nSel, m_listTray->MapIndexToItem(chosen->front())); } for (size_t i = size_t(0) ; i < chosen->size() ; ++i) { - PieceID pid = m_listTray.MapIndexToItem(value_preserving_cast((*chosen)[i])); + PieceID pid = m_listTray->MapIndexToItem((*chosen)[i]); size_t side; if (flip == CPieceTable::fSelect) { @@ -1124,34 +1121,36 @@ BOOL CTrayPalette::OnActTurnOver(UINT id) /* flipping pieces shouldn't change tray content, so restore selections */ + wxASSERT(m_listTray->GetSelectedCount() == size_t(0)); for (size_t i = size_t(0) ; i < tblListSel.size() ; ++i) { - m_listTray.SetSel(tblListSel[i], true); + m_listTray->Select(tblListSel[i], true); } - - return true; } -void CTrayPalette::OnUpdateActTurnOver(CCmdUI* pCmdUI) +void CTrayPalette::OnUpdateActTurnOver(wxUpdateUIEvent& pCmdUI) { + int id = pCmdUI.GetId(); bool eligible; - switch (pCmdUI->m_nID) + if (id == XRCID("ID_ACT_TURNOVER") || + id == XRCID("ID_ACT_TURNOVER_PREV") || + id == XRCID("ID_ACT_TURNOVER_RANDOM")) { - case ID_ACT_TURNOVER: - case ID_ACT_TURNOVER_PREV: - case ID_ACT_TURNOVER_RANDOM: - eligible = m_listTray.GetSelCount() > 0; - break; - case ID_ACT_TURNOVER_ALL: - case ID_ACT_TURNOVER_ALL_PREV: - case ID_ACT_TURNOVER_ALL_RANDOM: - eligible = m_listTray.GetCount() > 0; - break; - case ID_ACT_TURNOVER_SELECT: - eligible = menuGameElement != Invalid_v; - break; - default: - AfxThrowInvalidArgException(); + eligible = m_listTray->GetSelectedCount() > size_t(0); + } + else if (id == XRCID("ID_ACT_TURNOVER_ALL") || + id == XRCID("ID_ACT_TURNOVER_ALL_PREV") || + id == XRCID("ID_ACT_TURNOVER_ALL_RANDOM")) + { + eligible = m_listTray->GetItemCount() > size_t(0); + } + else if (id == XRCID("ID_ACT_TURNOVER_SELECT")) + { + eligible = menuGameElement != Invalid_v; + } + else + { + AfxThrowInvalidArgException(); } BOOL bNoOwnerRestrictions = TRUE; @@ -1165,17 +1164,19 @@ void CTrayPalette::OnUpdateActTurnOver(CCmdUI* pCmdUI) bool enable = (m_pDoc->IsScenario() || bNoOwnerRestrictions) && eligible && - m_listTray.IsShowingTileImages(); - pCmdUI->Enable(enable); + m_listTray->IsShowingTileImages(); + pCmdUI.Enable(enable); +#if 0 if (pCmdUI->m_pSubMenu != NULL) { // Need to handle menu that the submenu is connected to. pCmdUI->m_pMenu->EnableMenuItem(pCmdUI->m_nIndex, MF_BYPOSITION | (enable ? MF_ENABLED : (MF_DISABLED | MF_GRAYED))); } +#endif } -void CTrayPalette::OnPieceTrayAbout() +void CTrayPalette::OnPieceTrayAbout(wxCommandEvent& event) { size_t nSel = GetSelectedTray(); if (nSel == Invalid_v) @@ -1200,7 +1201,7 @@ void CTrayPalette::OnPieceTrayAbout() strTmp = CB::string::LoadString(IDS_MSG_TVIZ_ALL_HIDDEN); break; default: - ASSERT(FALSE); + wxASSERT(FALSE); strTmp = CB::string::LoadString(IDS_ERR_TRAY_VIZ); } @@ -1241,15 +1242,16 @@ void CTrayPalette::OnPieceTrayAbout() strTmp = CB::string::LoadString(IDS_MSG_TVIZ_OWNER_FULL); strMsg += '\n' + strTmp; } - AfxMessageBox(strMsg, MB_ICONINFORMATION); + wxMessageBox(strMsg, CB::GetAppName(), wxICON_INFORMATION); } -void CTrayPalette::OnUpdatePieceTrayAbout(CCmdUI* pCmdUI) +void CTrayPalette::OnUpdatePieceTrayAbout(wxUpdateUIEvent& pCmdUI) { - int nSel = m_comboYGrp.GetCurSel(); - pCmdUI->Enable(nSel >= 0); + int nSel = m_comboYGrp->GetSelection(); + pCmdUI.Enable(nSel != wxNOT_FOUND); } +#if 0 BOOL CTrayPalette::OnHelpInfo(HELPINFO* pHelpInfo) { GetApp()->DoHelpTopic("gp-ref-pal-tray.htm"); diff --git a/GP/PalTray.h b/GP/PalTray.h index 3672f3a2..4a2da8c7 100644 --- a/GP/PalTray.h +++ b/GP/PalTray.h @@ -141,15 +141,15 @@ class CTrayPalette : public wxPanel void OnMenuButton(wxCommandEvent& event); void OnPieceTrayShuffle(wxCommandEvent& event); void OnUpdatePieceTrayShuffle(wxUpdateUIEvent& pCmdUI); + void OnPieceTrayShuffleSelected(wxCommandEvent& event); + void OnUpdatePieceTrayShuffleSelected(wxUpdateUIEvent& pCmdUI); + void OnEditElementText(wxCommandEvent& event); + void OnUpdateEditElementText(wxUpdateUIEvent& pCmdUI); + void OnActTurnOver(wxCommandEvent& event); + void OnUpdateActTurnOver(wxUpdateUIEvent& pCmdUI); + void OnPieceTrayAbout(wxCommandEvent& event); + void OnUpdatePieceTrayAbout(wxUpdateUIEvent& pCmdUI); #if 0 - afx_msg void OnPieceTrayShuffleSelected(); - afx_msg void OnUpdatePieceTrayShuffleSelected(CCmdUI* pCmdUI); - afx_msg void OnEditElementText(); - afx_msg void OnUpdateEditElementText(CCmdUI* pCmdUI); - afx_msg BOOL OnActTurnOver(UINT id); - afx_msg void OnUpdateActTurnOver(CCmdUI* pCmdUI); - afx_msg void OnPieceTrayAbout(); - afx_msg void OnUpdatePieceTrayAbout(CCmdUI* pCmdUI); afx_msg BOOL OnHelpInfo(HELPINFO* pHelpInfo); afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); afx_msg void OnMouseMove(UINT nFlags, CPoint point); From 8dd25092c2280b98ed32536de172a5f2b1f43cef Mon Sep 17 00:00:00 2001 From: Bill Su Date: Fri, 20 Mar 2026 00:07:05 -0400 Subject: [PATCH 75/80] VwPbrd: remove old code whose replacement code has been validated --- GP/PalTray.h | 3 - GP/SelOPlay.h | 5 -- GP/ToolPlay.cpp | 166 +----------------------------------------------- GP/ToolPlay.h | 7 -- GP/VwPbrd.cpp | 133 ++------------------------------------ GP/VwPbrd.h | 10 --- GP/VwPbrd1.cpp | 92 --------------------------- 7 files changed, 6 insertions(+), 410 deletions(-) diff --git a/GP/PalTray.h b/GP/PalTray.h index 4a2da8c7..cd456303 100644 --- a/GP/PalTray.h +++ b/GP/PalTray.h @@ -91,9 +91,6 @@ class CTrayPalette : public wxPanel CB::propagate_const m_bpMenuBtn; CB::propagate_const m_comboYGrp; CB::propagate_const m_listTray; -#if 0 - CRect m_rctMenuBtn; // phony menu button dims -#endif int m_nComboHeight; void LoadTrayNameList(); diff --git a/GP/SelOPlay.h b/GP/SelOPlay.h index ac1ae8d7..133b6826 100644 --- a/GP/SelOPlay.h +++ b/GP/SelOPlay.h @@ -116,10 +116,6 @@ class CSelection protected: RefPtr m_pView; // Selection's view // -- Class level support methods -- // -#if 0 - static void SetupTrackingDraw(wxDC& pDC); - static void CleanUpTrackingDraw(wxDC& pDC); -#else class DCSetupTrackingDraw { public: @@ -128,7 +124,6 @@ class CSelection wxDCPenChanger setPen; wxDCBrushChanger setBrush; }; -#endif // -- Class variables -- // static const wxPen c_penDot; #if 0 diff --git a/GP/ToolPlay.cpp b/GP/ToolPlay.cpp index 62826ea4..96dae2f9 100644 --- a/GP/ToolPlay.cpp +++ b/GP/ToolPlay.cpp @@ -1,6 +1,6 @@ // ToolPlay.cpp // -// Copyright (c) 1994-2025 By Dale L. Larson & William Su, All Rights Reserved. +// Copyright (c) 1994-2026 By Dale L. Larson & William Su, All Rights Reserved. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the @@ -201,39 +201,6 @@ void CPSelectTool::OnMouseMove(CPlayBoardView& pView, int nMods, wxPoint point) if (!pView.HasCapture()) return; -#if 0 - if (m_eSelMode != smodeNormal && m_eSelMode != smodeMove) - { - // Autoscroll initiate possibility processing (sounds like a - // scifi flic). Autoscroll is enabled when the mouse is captured - // and the mouse is outside of the client area. - CRect rct; - CPoint pt; - GetCursorPos(&pt); - pt = CB::Convert(pView.ScreenToClient(CB::Convert(pt))); - rct = CB::Convert(pView.GetClientRect()); -#if 0 - if (rct.PtInRect(pt)) // In client area - { - rct.InflateRect(-scrollZone, -scrollZone); - rct.NormalizeRect(); // Just in case client is too small - if (!rct.PtInRect(pt)) - { - // It's in the scroll zone - if (m_nTimerID == uintptr_t(0)) // Only start if not scrolling - StartScrollTimer(pView); - } - else - KillScrollTimer(pView); - } - else - KillScrollTimer(pView); -#else - CPP20_TRACE("{}->{}: TODO: wxProvides autoscroll?\n", *this, __func__); -#endif - } -#endif - // If we get here, the mouse has been captured. Check if // we are doing a "net select". if (m_eSelMode == smodeNet) @@ -313,9 +280,6 @@ bool CPSelectTool::OnLButtonUp(CPlayBoardView& pView, int nMods, wxPoint point) } m_eSelMode = smodeNormal; KillDragTimer(pView); // Make sure timers are released -#if 0 - KillScrollTimer(pView); -#endif return CPlayTool::OnLButtonUp(pView, nMods, point) && retval; } @@ -325,9 +289,6 @@ void CPSelectTool::OnMouseCaptureLost(CPlayBoardView& pView) pView.SetCursor(wxCursor(wxCURSOR_ARROW)); m_eSelMode = smodeNormal; KillDragTimer(pView); // Make sure timers are released -#if 0 - KillScrollTimer(pView); -#endif CPlayTool::OnMouseCaptureLost(pView); } @@ -339,9 +300,6 @@ void CPSelectTool::OnTimer(CPlayBoardView& pView, int nIDEvent) { m_eSelMode = smodeNormal; KillDragTimer(pView); -#if 0 - KillScrollTimer(pView); -#endif return; } if (m_eSelMode == smodeNormal) @@ -354,15 +312,9 @@ void CPSelectTool::OnTimer(CPlayBoardView& pView, int nIDEvent) m_eSelMode = smodeMove; KillDragTimer(pView); -#if 0 - CClientDC dc(&pView); - pView.OnPrepareScaledDC(dc, TRUE); - pSLst.DrawTracker(dc, trkSelected); // Turn off handles -#else wxOverlayDC dc(pView.GetOverlay(), &pView); pView.OnPrepareScaledDC(dc); dc.Clear(); -#endif wxPoint point = wxGetMouseState().GetPosition(); point = pView.ScreenToClient(point); @@ -373,13 +325,6 @@ void CPSelectTool::OnTimer(CPlayBoardView& pView, int nIDEvent) point = pView.WorkspaceToClient(point); DoDragDrop(pView, point); } -#if 0 - else if (m_eSelMode != smodeMove) - { - if (!ProcessAutoScroll(pView)) - KillScrollTimer(pView); - } -#endif } void CPSelectTool::OnLButtonDblClk(CPlayBoardView& pView, int nMods, @@ -439,91 +384,6 @@ void CPSelectTool::DrawNetRect(wxDC& pDC, const CPlayBoardView& /*pView*/) const DrawSelectionRect(pDC, rect); } -#if 0 -BOOL CPSelectTool::ProcessAutoScroll(CPlayBoardView& pView) -{ - CPoint point; - CRect rectClient; - CRect rect; - - GetCursorPos(&point); - point = CB::Convert(pView.ScreenToClient(CB::Convert(point))); - rectClient = CB::Convert(pView.GetClientRect()); - rect = rectClient; - rect.InflateRect(-scrollZone, -scrollZone); - rect.NormalizeRect(); - - UINT nScrollID = MAKEWORD(-1, -1); - if (rectClient.PtInRect(point) && !rect.PtInRect(point)) - { -#if 0 - // Mouse is in the scroll zone.... - // Determine which way to scroll along both X & Y axis - if (point.x < rect.left) - nScrollID = MAKEWORD(SB_LINEUP, HIBYTE(nScrollID)); - else if (point.x >= rect.right) - nScrollID = MAKEWORD(SB_LINEDOWN, HIBYTE(nScrollID)); - if (point.y < rect.top) - nScrollID = MAKEWORD(LOBYTE(nScrollID), SB_LINEUP); - else if (point.y >= rect.bottom) - nScrollID = MAKEWORD(LOBYTE(nScrollID), SB_LINEDOWN); - ASSERT(nScrollID != MAKEWORD(-1, -1)); - // First check if scroll can happen. - BOOL bValidScroll = pView.OnScroll(nScrollID, 0, FALSE); - if (bValidScroll) - { - CSelList& pSLst = pView.GetSelectList(); - point = pView.ClientToWorkspace(point); - - CClientDC dc(&pView); - pView.OnPrepareScaledDC(dc, TRUE); - - if (m_eSelMode == smodeNet) - { - // Erase previous position - CRect rect(c_ptDown.x, c_ptDown.y, c_ptLast.x, c_ptLast.y); - rect.NormalizeRect(); - DrawSelectionRect(dc, rect); - } - else - pSLst.DrawTracker(dc); // Turn off tracker - - pView.OnScroll(nScrollID, 0, TRUE); - pView.UpdateWindow(); // Redraw image content. - - point = AdjustPoint(pView, point); - - MoveSelections(pSLst, point); // Offset the tracking data - c_ptLast = point; // Save new 'last' position - - pView.OnPrepareScaledDC(dc, TRUE); - if (m_eSelMode == smodeNet) - { - GetCursorPos(&point); - pView.ScreenToClient(&point); - point = pView.ClientToWorkspace(point); - c_ptLast = point; // Set new 'last' position - // Draw updated net rect - CRect rect(c_ptDown.x, c_ptDown.y, c_ptLast.x, c_ptLast.y); - rect.NormalizeRect(); - DrawSelectionRect(dc, rect); - } - else - { - MoveSelections(pSLst, point);// Offset the tracking data - c_ptLast = point; // Save new 'last' position - pSLst.DrawTracker(dc); // Turn off tracker - } - return TRUE; - } -#else - wxASSERT(!"TODO: autoscroll, overlay"); -#endif - } - return FALSE; -} -#endif - void CPSelectTool::MoveSelections(CSelList &pSLst, const wxPoint& point) { if (m_eSelMode == smodeMove) @@ -572,30 +432,6 @@ void CPSelectTool::KillDragTimer(CPlayBoardView& pView) } } -#if 0 -void CPSelectTool::StartScrollTimer(CPlayBoardView& pView) -{ -#if 0 - m_nTimerID = pView.SetTimer(timerIDAutoScroll, timerAutoScroll, NULL); -#else - CPP20_TRACE("{}->{}: TODO:\n", *this, __func__); -#endif -} - -void CPSelectTool::KillScrollTimer(CPlayBoardView& pView) -{ -#if 0 - if (m_nTimerID != uintptr_t(0)) - { - pView.KillTimer(m_nTimerID); - m_nTimerID = uintptr_t(0); - } -#else - CPP20_TRACE("{}->{}: TODO:\n", *this, __func__); -#endif -} -#endif - //////////////////////////////////////////////////////////////////////// // Note: The CSelList should have had the mouse offset value set at // this time. diff --git a/GP/ToolPlay.h b/GP/ToolPlay.h index 504a9cf0..00c373c2 100644 --- a/GP/ToolPlay.h +++ b/GP/ToolPlay.h @@ -127,19 +127,12 @@ class CPSelectTool : public CPlayTool int m_nTimerID; wxRect m_rectMultiBorder; // ------- // -#if 0 - BOOL ProcessAutoScroll(CPlayBoardView& pView); -#endif void DrawSelectionRect(wxDC& pDC, const wxRect& pRct) const; void DrawNetRect(wxDC& pDC, const CPlayBoardView& pView) const; [[nodiscard]] wxPoint AdjustPoint(const CPlayBoardView& pView, wxPoint point) const; void MoveSelections(CSelList &pSLst, const wxPoint& point); void StartDragTimer(CPlayBoardView& pView); void KillDragTimer(CPlayBoardView& pView); -#if 0 - void StartScrollTimer(CPlayBoardView& pView); - void KillScrollTimer(CPlayBoardView& pView); -#endif // ------- // void DoDragDropStart(CPlayBoardView& pView); void DoDragDrop(CPlayBoardView& pView, const wxPoint& pntClient); diff --git a/GP/VwPbrd.cpp b/GP/VwPbrd.cpp index 21b3a7d8..75326868 100644 --- a/GP/VwPbrd.cpp +++ b/GP/VwPbrd.cpp @@ -264,9 +264,6 @@ CPlayBoardView::CPlayBoardView(CPlayBoardViewContainer& p) : m_nCurToolID = XRCID("ID_PTOOL_SELECT"); m_bInDrag = FALSE; m_pDragSelList = NULL; -#if 0 - m_nTimerID = uintptr_t(0); -#endif // use sizers for scrolling wxSizer* sizer = new wxBoxSizer(wxVERTICAL); @@ -842,17 +839,8 @@ void CPlayBoardView::DoDragMarker(DragDropEvent& event) return; } -#if 0 - if (pdi.m_phase == PhaseDrag::Exit) - DragKillAutoScroll(); - else if (pdi.m_phase == PhaseDrag::Over) -#else if (pdi.m_phase == PhaseDrag::Over) -#endif { -#if 0 - DragCheckAutoScroll(); -#endif event.SetCursor(pdi.m_hcsrSuggest); return; } @@ -999,10 +987,6 @@ void CPlayBoardView::DoDragSelectList(DragDropEvent& event) GetOverlay().Reset(); #endif } -#if 0 - if (pdi.m_phase == PhaseDrag::Exit) - DragKillAutoScroll(); -#endif wxRect rctSnapRef = CB::Convert(pSLst->GetSnapReferenceRect()); wxPoint pntSnapRefTopLeft = rctSnapRef.GetTopLeft(); @@ -1052,9 +1036,6 @@ void CPlayBoardView::DoDragSelectList(DragDropEvent& event) if (pdi.m_phase == PhaseDrag::Over) { -#if 0 - DragCheckAutoScroll(); -#endif event.SetCursor(pdi.m_hcsrSuggest); return; } @@ -1063,9 +1044,6 @@ void CPlayBoardView::DoDragSelectList(DragDropEvent& event) CGamDoc& pDoc = GetDocument(); // Whoooopppp...Whoooopppp!!! Drop occurred here.... -#if 0 - DragKillAutoScroll(); -#endif std::vector> listObjs; pSLst->LoadTableWithObjectPtrs(listObjs, CSelList::otAll, FALSE); pSLst->PurgeList(FALSE); // Purge source list @@ -1093,87 +1071,6 @@ void CPlayBoardView::DoDragSelectList(DragDropEvent& event) return; } -#if 0 -void CPlayBoardView::DragDoAutoScroll() -{ - CPoint ptBefore(0, 0); - ptBefore = ClientToWorkspace(ptBefore); - CDC *pDC = NULL; - - if (m_pDragSelList != NULL) - { - // Remove previous drag image. - pDC = GetDC(); - pDC->SaveDC(); - OnPrepareScaledDC(*pDC, TRUE); - m_pDragSelList->DrawTracker(*pDC, trkMoving); - pDC->RestoreDC(-1); - } - CPoint point; - GetCursorPos(&point); - ScreenToClient(&point); - BOOL bScrolled = ProcessAutoScroll(point); - if (m_pDragSelList != NULL && bScrolled) - { - CPoint ptAfter(0, 0); - ptAfter = ClientToWorkspace(ptAfter); - CSize sizeDelta = ptAfter - ptBefore; - if (sizeDelta.cx != 0 || sizeDelta.cy != 0) - { - // We still have to make sure the larger rect hasn't left the - // playing area. - CRect rctObjs = m_pDragSelList->GetEnclosingRect(); - rctObjs += (CPoint)sizeDelta; // Calc trial new position - BOOL bXOK, bYOK; - if (!IsRectFullyOnBoard(rctObjs, &bXOK, &bYOK)) - { - sizeDelta.cx = bXOK ? sizeDelta.cx : 0; - sizeDelta.cy = bYOK ? sizeDelta.cy : 0; - } - } - m_pDragSelList->Offset((CPoint)sizeDelta); - } - if (m_pDragSelList != NULL) - { - pDC->SaveDC(); - OnPrepareScaledDC(*pDC, TRUE); - // Restore drag image. - m_pDragSelList->DrawTracker(*pDC, trkMoving); - pDC->RestoreDC(-1); - } - if (pDC != NULL) - ReleaseDC(pDC); -} - -void CPlayBoardView::DragCheckAutoScroll() -{ - m_bInDrag = TRUE; - CPoint point; - GetCursorPos(&point); - ScreenToClient(&point); - if (CheckAutoScroll(point)) - { - if (m_nTimerID == uintptr_t(0)) - m_nTimerID = SetTimer(timerIDAutoScroll, timerAutoScroll, NULL); - } - else if (m_nTimerID != uintptr_t(0)) - { - if (m_nTimerID != uintptr_t(0)) - KillTimer(m_nTimerID); - m_nTimerID = uintptr_t(0); - } -} - -void CPlayBoardView::DragKillAutoScroll() -{ - m_bInDrag = FALSE; - m_pDragSelList = NULL; - if (m_nTimerID != uintptr_t(0)) - KillTimer(m_nTimerID); - m_nTimerID = uintptr_t(0); -} -#endif - ///////////////////////////////////////////////////////////////////////////// void CPlayBoardView::AddPiece(wxPoint pnt, PieceID pid) @@ -1391,36 +1288,16 @@ void CPlayBoardView::OnLButtonDblClk(wxMouseEvent& event) void CPlayBoardView::OnTimer(wxTimerEvent& event) { -#if 0 - if (m_nTimerID == nIDEvent) + if (!GetDocument().IsPlaying()) { - CPoint point; - GetCursorPos(&point); - ScreenToClient(&point); - if (!m_bInDrag || !CheckAutoScroll(point)) - { - KillTimer(m_nTimerID); - return; - } - DragDoAutoScroll(); - return; + PToolType eToolType = MapToolType(m_nCurToolID); + CPlayTool& pTool = CPlayTool::GetTool(eToolType); + pTool.OnTimer(*this, event.GetId()); } else { -#endif - if (!GetDocument().IsPlaying()) - { - PToolType eToolType = MapToolType(m_nCurToolID); - CPlayTool& pTool = CPlayTool::GetTool(eToolType); - pTool.OnTimer(*this, event.GetId()); - } - else - { - event.Skip(); - } -#if 0 + event.Skip(); } -#endif } void CPlayBoardView::OnSetCursor(wxSetCursorEvent& event) diff --git a/GP/VwPbrd.h b/GP/VwPbrd.h index 83868269..ac5cfb42 100644 --- a/GP/VwPbrd.h +++ b/GP/VwPbrd.h @@ -155,16 +155,12 @@ class CPlayBoardView : public CB::ProcessEventOverride // -------- // BOOL m_bInDrag; // Currently being dragged over CB::propagate_const m_pDragSelList; // Pointer the select list being dragged -#if 0 - uintptr_t m_nTimerID; // Used to control autoscrolls -#else public: void SetTimer(int id, unsigned milliseconds); void KillTimer(int id); private: OwnerOrNullPtr timer; protected: -#endif // -------- // int m_nCurToolID; // Current tool ID // -------- // @@ -203,12 +199,6 @@ class CPlayBoardView : public CB::ProcessEventOverride void DoDragPieceList(DragDropEvent& event); void DoDragSelectList(DragDropEvent& event); -#if 0 - void DragDoAutoScroll(); - void DragCheckAutoScroll(); - void DragKillAutoScroll(); -#endif - void DoAutostackOfSelectedObjects(int xStagger, int yStagger); void DoRotateRelative(BOOL bWheelRotation); diff --git a/GP/VwPbrd1.cpp b/GP/VwPbrd1.cpp index a1615529..1194fa00 100644 --- a/GP/VwPbrd1.cpp +++ b/GP/VwPbrd1.cpp @@ -178,36 +178,10 @@ void CPlayBoardView::ClearToolTip() ////////////////////////////////////////////////////////////////////// -#if 0 -void CPlayBoardView::SetNotificationTip(wxPoint pointClient, UINT nResID) -{ - CB::string str = CB::string::LoadString(nResID); - SetNotificationTip(pointClient, &str); -} -#endif - void CPlayBoardView::SetNotificationTip(wxPoint pointClient, const CB::string& pszTip) { ClearNotificationTip(); -#if 0 - TOOLINFO ti; - m_toolMsgTip.FillInToolInfo(ti, this, ID_TIP_PLAYBOARD_MSG); - ti.uFlags |= TTF_TRACK; - ti.lpszText = pszTip ? const_cast(pszTip->v_str()) : nullptr; - - m_toolMsgTip.SendMessage(TTM_ADDTOOL, 0, (LPARAM)&ti); - - CPoint pointScreen(pointClient); - ClientToScreen(&pointScreen); - - m_toolMsgTip.Activate(TRUE); - m_toolMsgTip.SendMessage(TTM_TRACKACTIVATE, (WPARAM)TRUE, (LPARAM)&ti); - m_toolMsgTip.SendMessage(TTM_TRACKPOSITION, 0, - (LPARAM)MAKELONG(static_cast(pointScreen.x), static_cast(pointScreen.y))); - - SetTimer(ID_TIP_MSG_TIMER, MAX_TIP_MSG_TIME, NotificationTipTimeoutHandler); -#else m_toolMsgTip.Add(*this, pszTip, CB::ToolTip::TRACK); wxPoint pointScreen = ClientToScreen(pointClient); @@ -217,26 +191,15 @@ void CPlayBoardView::SetNotificationTip(wxPoint pointClient, const CB::string& p m_toolMsgTip.TrackPosition(pointScreen); m_toolMsgTipTimer.Start(MAX_TIP_MSG_TIME, wxTIMER_ONE_SHOT); -#endif } void CPlayBoardView::ClearNotificationTip() { -#if 0 - KillTimer(ID_TIP_MSG_TIMER); // Kill it in case it's still running - - CToolInfo ti; - m_toolMsgTip.GetToolInfo(ti, this, ID_TIP_PLAYBOARD_MSG); - m_toolMsgTip.SendMessage(TTM_TRACKACTIVATE, (WPARAM)FALSE, (LPARAM)&ti); - m_toolMsgTip.DelTool(this, ID_TIP_PLAYBOARD_MSG); - m_toolMsgTip.Activate(FALSE); -#else m_toolMsgTipTimer.Stop(); m_toolMsgTip.TrackActivate(*this, false); m_toolMsgTip.Delete(*this); m_toolMsgTip.Enable(false); -#endif } void CPlayBoardView::NotificationTipTimeoutHandler(wxTimerEvent& /*event*/) @@ -724,61 +687,6 @@ void CPlayBoardView::CenterViewOnWorkspacePoint(wxPoint point) Update(); } -#if 0 -////////////////////////////////////////////////////////////////////////// -// point is in client coords - -BOOL CPlayBoardView::CheckAutoScroll(CPoint point) -{ - CRect rctClient; - CRect rct; - - GetClientRect(&rctClient); - rct = rctClient; - rct.InflateRect(-scrollZone, -scrollZone); - rct.NormalizeRect(); - - return rctClient.PtInRect(point) && !rct.PtInRect(point); -} - -// Returns TRUE if scroll happened -BOOL CPlayBoardView::ProcessAutoScroll(CPoint point) -{ - CRect rectClient; - CRect rect; - - GetClientRect(&rectClient); - rect = rectClient; - rect.InflateRect(-scrollZone, -scrollZone); - rect.NormalizeRect(); - - UINT nScrollID = MAKEWORD(-1, -1); - if (rectClient.PtInRect(point) && !rect.PtInRect(point)) - { - // Mouse is in the scroll zone.... - // Determine which way to scroll along both X & Y axis - if (point.x < rect.left) - nScrollID = MAKEWORD(SB_LINEUP, HIBYTE(nScrollID)); - else if (point.x >= rect.right) - nScrollID = MAKEWORD(SB_LINEDOWN, HIBYTE(nScrollID)); - if (point.y < rect.top) - nScrollID = MAKEWORD(LOBYTE(nScrollID), SB_LINEUP); - else if (point.y >= rect.bottom) - nScrollID = MAKEWORD(LOBYTE(nScrollID), SB_LINEDOWN); - ASSERT(nScrollID != MAKEWORD(-1, -1)); - // First check if scroll can happen. - BOOL bValidScroll = OnScroll(nScrollID, 0, FALSE); - if (bValidScroll) - { - OnScroll(nScrollID, 0, TRUE); - UpdateWindow(); // Redraw image content. - return TRUE; - } - } - return FALSE; -} -#endif - // this method can be overridden in a derived class to forbid sending the // auto scroll events - note that unlike StopAutoScrolling() it doesn't // stop the timer, so it will be called repeatedly and will typically From fbf1fdec7eb4fed99535e671c8ee7e70f68765bd Mon Sep 17 00:00:00 2001 From: Bill Su Date: Sun, 22 Mar 2026 20:21:53 -0400 Subject: [PATCH 76/80] update cmake for MSVS 2026 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4f8c5104..5fd7ff50 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ # Copyright (c) 2023 By William Su, All Rights Reserved. -cmake_minimum_required(VERSION 2.8.12) +cmake_minimum_required(VERSION 3.10...4.1) # set VERSION variables cmake_policy(SET CMP0048 NEW) # provide CMAKE_MSVC_RUNTIME_LIBRARY From 1ccab7454e3eb00dd47e49631ade0049edef29f6 Mon Sep 17 00:00:00 2001 From: Bill Su Date: Mon, 23 Mar 2026 21:32:02 -0400 Subject: [PATCH 77/80] more MS VS 2026 support --- build-all-configs.bat | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/build-all-configs.bat b/build-all-configs.bat index 5e4ebdee..ecb57422 100644 --- a/build-all-configs.bat +++ b/build-all-configs.bat @@ -7,7 +7,11 @@ rem execute in bat's directory pushd %~dp0 call %VSROOTDIR%"\2022\Community\VC\Auxiliary\Build\vcvars64.bat" -if errorlevel 1 goto fail_vc_x64 +if errorlevel 1 ( + rem MSVS 2026 + call %VSROOTDIR%"\18\Community\VC\Auxiliary\Build\vcvars64.bat" + if errorlevel 1 goto fail_vc_x64 +) echo on cmake -G Ninja -B out/build/x64-Debug -DCMAKE_BUILD_TYPE=Debug @@ -25,7 +29,11 @@ if errorlevel 1 cmake --build out/build/x64-Release if errorlevel 1 goto fail_build call %VSROOTDIR%"\2022\Community\VC\Auxiliary\Build\vcvars32.bat" -if errorlevel 1 goto fail_vc_x86 +if errorlevel 1 ( + rem MSVS 2026 + call %VSROOTDIR%"\18\Community\VC\Auxiliary\Build\vcvars32.bat" + if errorlevel 1 goto fail_vc_x86 +) echo on cmake -G Ninja -B out/build/x86-Debug -DCMAKE_BUILD_TYPE=Debug From ba64557aca09d5ceb03dcbba2a6a2e90ea31e115 Mon Sep 17 00:00:00 2001 From: Bill Su Date: Mon, 23 Mar 2026 21:36:40 -0400 Subject: [PATCH 78/80] try to fix missing GHelp/CBoard.chm error --- GHelp/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/GHelp/CMakeLists.txt b/GHelp/CMakeLists.txt index 6983893a..4636daca 100644 --- a/GHelp/CMakeLists.txt +++ b/GHelp/CMakeLists.txt @@ -46,7 +46,7 @@ file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/fixhhc.bat "if errorlevel 1 exit /b 0\n" file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/fixhhc.bat "exit /b 1\n") add_custom_command( - OUTPUT CBoard.chm + OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/CBoard.chm COMMENT "Make CBoard.chm" DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/gmhelp.h ${CMAKE_CURRENT_SOURCE_DIR}/gmhelpidmap.h @@ -57,4 +57,4 @@ add_custom_command( WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} ) -add_custom_target(CBHelp ALL DEPENDS cboard.chm) +add_custom_target(CBHelp ALL DEPENDS CBoard.chm) From 11f6fc32e2f9b11ede71f02b5c6393ea4ce059c0 Mon Sep 17 00:00:00 2001 From: Bill Su Date: Mon, 23 Mar 2026 22:10:12 -0400 Subject: [PATCH 79/80] VwPrjgsn: fix signed/unsigned warning --- GP/VwPrjgsn.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GP/VwPrjgsn.cpp b/GP/VwPrjgsn.cpp index 6e8f279b..9be23f59 100644 --- a/GP/VwPrjgsn.cpp +++ b/GP/VwPrjgsn.cpp @@ -499,7 +499,7 @@ void CGsnProjView::DoUpdateProjectList(BOOL bUpdateItem /* = TRUE */) m_listProj->ScrollToRow(nTopIdx); if (nCurSel != wxNOT_FOUND) { - if (nCurSel >= m_listProj->GetItemCount()) + if (nCurSel >= value_preserving_cast(m_listProj->GetItemCount())) nCurSel = value_preserving_cast(m_listProj->GetItemCount() - size_t(1)); m_listProj->SetSelection(nCurSel); } From 000662f0ca2467773764efc7e89d985dd3ad7c5d Mon Sep 17 00:00:00 2001 From: Bill Su Date: Thu, 26 Mar 2026 18:56:40 -0400 Subject: [PATCH 80/80] update some copyright strings --- GP/DlgRotpc.cpp | 2 +- GP/FrmPbrd.cpp | 2 +- GP/GamDoc1.cpp | 2 +- GP/GamDoc5.cpp | 2 +- GP/Gp.cpp | 2 +- GP/Gp.h | 2 +- GP/LBoxSlct.cpp | 2 +- GP/LBoxSlct.h | 2 +- GP/PBoard.cpp | 2 +- GP/SelOPlay.cpp | 2 +- GP/SelOPlay.h | 2 +- GP/ToolPlay.h | 2 +- GP/VwSelpce.cpp | 2 +- GP/VwSelpce.h | 2 +- GP/VwTbrd.cpp | 2 +- GP/VwTbrd.h | 2 +- GP/WinPoptb.cpp | 2 +- GP/WinPoptb.h | 2 +- GShr/CyberBoard.h | 2 +- GShr/DragDrop.h | 2 +- GShr/DrawObj.cpp | 2 +- GShr/LBoxGfx2.cpp | 2 +- GShr/LBoxGfx2.h | 2 +- GShr/WinState.h | 2 +- 24 files changed, 24 insertions(+), 24 deletions(-) diff --git a/GP/DlgRotpc.cpp b/GP/DlgRotpc.cpp index 5ce6ea3a..0e039ad7 100644 --- a/GP/DlgRotpc.cpp +++ b/GP/DlgRotpc.cpp @@ -1,6 +1,6 @@ // DlgRotpc.cpp : implementation file // -// Copyright (c) 1994-2025 By Dale L. Larson & William Su, All Rights Reserved. +// Copyright (c) 1994-2026 By Dale L. Larson & William Su, All Rights Reserved. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the diff --git a/GP/FrmPbrd.cpp b/GP/FrmPbrd.cpp index 3fcbbe98..676523ef 100644 --- a/GP/FrmPbrd.cpp +++ b/GP/FrmPbrd.cpp @@ -1,6 +1,6 @@ // FrmPbrd.cpp : implementation file // -// Copyright (c) 1994-2025 By Dale L. Larson & William Su, All Rights Reserved. +// Copyright (c) 1994-2026 By Dale L. Larson & William Su, All Rights Reserved. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the diff --git a/GP/GamDoc1.cpp b/GP/GamDoc1.cpp index 223c9849..e07af438 100644 --- a/GP/GamDoc1.cpp +++ b/GP/GamDoc1.cpp @@ -1,6 +1,6 @@ // GamDoc1.cpp - Command and Control for document wide operations // -// Copyright (c) 1994-2025 By Dale L. Larson & William Su, All Rights Reserved. +// Copyright (c) 1994-2026 By Dale L. Larson & William Su, All Rights Reserved. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the diff --git a/GP/GamDoc5.cpp b/GP/GamDoc5.cpp index b3ba37b5..c7bb8a97 100644 --- a/GP/GamDoc5.cpp +++ b/GP/GamDoc5.cpp @@ -1,6 +1,6 @@ // GamDoc5.cpp : just plain miscellaneous stuff // -// Copyright (c) 1994-2025 By Dale L. Larson & William Su, All Rights Reserved. +// Copyright (c) 1994-2026 By Dale L. Larson & William Su, All Rights Reserved. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the diff --git a/GP/Gp.cpp b/GP/Gp.cpp index ec8af054..11a1c469 100644 --- a/GP/Gp.cpp +++ b/GP/Gp.cpp @@ -1,6 +1,6 @@ // Gp.cpp : Defines the class behaviors for the application. // -// Copyright (c) 1994-2025 By Dale L. Larson & William Su, All Rights Reserved. +// Copyright (c) 1994-2026 By Dale L. Larson & William Su, All Rights Reserved. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the diff --git a/GP/Gp.h b/GP/Gp.h index 1b21571f..f9d01ec0 100644 --- a/GP/Gp.h +++ b/GP/Gp.h @@ -1,6 +1,6 @@ // Gp.h : main header file for the GP application // -// Copyright (c) 1994-2025 By Dale L. Larson & William Su, All Rights Reserved. +// Copyright (c) 1994-2026 By Dale L. Larson & William Su, All Rights Reserved. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the diff --git a/GP/LBoxSlct.cpp b/GP/LBoxSlct.cpp index 8038a71b..60e145cd 100644 --- a/GP/LBoxSlct.cpp +++ b/GP/LBoxSlct.cpp @@ -1,6 +1,6 @@ // LBoxSlct.cpp // -// Copyright (c) 1994-2025 By Dale L. Larson & William Su, All Rights Reserved. +// Copyright (c) 1994-2026 By Dale L. Larson & William Su, All Rights Reserved. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the diff --git a/GP/LBoxSlct.h b/GP/LBoxSlct.h index 0b1495fd..8c3fb409 100644 --- a/GP/LBoxSlct.h +++ b/GP/LBoxSlct.h @@ -1,6 +1,6 @@ // LBoxSlct.h // -// Copyright (c) 1994-2025 By Dale L. Larson & William Su, All Rights Reserved. +// Copyright (c) 1994-2026 By Dale L. Larson & William Su, All Rights Reserved. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the diff --git a/GP/PBoard.cpp b/GP/PBoard.cpp index 68195e35..0f52389e 100644 --- a/GP/PBoard.cpp +++ b/GP/PBoard.cpp @@ -1,6 +1,6 @@ // PBoard.cpp // -// Copyright (c) 1994-2025 By Dale L. Larson & William Su, All Rights Reserved. +// Copyright (c) 1994-2026 By Dale L. Larson & William Su, All Rights Reserved. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the diff --git a/GP/SelOPlay.cpp b/GP/SelOPlay.cpp index 72fd8787..abaf3e9d 100644 --- a/GP/SelOPlay.cpp +++ b/GP/SelOPlay.cpp @@ -1,6 +1,6 @@ // SelOPlay.cpp // -// Copyright (c) 1994-2025 By Dale L. Larson & William Su, All Rights Reserved. +// Copyright (c) 1994-2026 By Dale L. Larson & William Su, All Rights Reserved. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the diff --git a/GP/SelOPlay.h b/GP/SelOPlay.h index 133b6826..f92584a6 100644 --- a/GP/SelOPlay.h +++ b/GP/SelOPlay.h @@ -1,7 +1,7 @@ // SelOPlay.h -- contains class definitions for selection proxies. Used // in concert with the selection tool. // -// Copyright (c) 1994-2025 By Dale L. Larson & William Su, All Rights Reserved. +// Copyright (c) 1994-2026 By Dale L. Larson & William Su, All Rights Reserved. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the diff --git a/GP/ToolPlay.h b/GP/ToolPlay.h index 00c373c2..5aceab6e 100644 --- a/GP/ToolPlay.h +++ b/GP/ToolPlay.h @@ -1,6 +1,6 @@ // ToolPlay.h // -// Copyright (c) 1994-2025 By Dale L. Larson & William Su, All Rights Reserved. +// Copyright (c) 1994-2026 By Dale L. Larson & William Su, All Rights Reserved. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the diff --git a/GP/VwSelpce.cpp b/GP/VwSelpce.cpp index fc4528c6..c2fa39ff 100644 --- a/GP/VwSelpce.cpp +++ b/GP/VwSelpce.cpp @@ -1,6 +1,6 @@ // VwSelpce.cpp : Selected Piece List View // -// Copyright (c) 1994-2025 By Dale L. Larson & William Su, All Rights Reserved. +// Copyright (c) 1994-2026 By Dale L. Larson & William Su, All Rights Reserved. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the diff --git a/GP/VwSelpce.h b/GP/VwSelpce.h index 2c7e91e4..d2730057 100644 --- a/GP/VwSelpce.h +++ b/GP/VwSelpce.h @@ -1,6 +1,6 @@ // VwSelpce.h : header file // -// Copyright (c) 1994-2025 By Dale L. Larson & William Su, All Rights Reserved. +// Copyright (c) 1994-2026 By Dale L. Larson & William Su, All Rights Reserved. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the diff --git a/GP/VwTbrd.cpp b/GP/VwTbrd.cpp index ba54a880..b74f20d1 100644 --- a/GP/VwTbrd.cpp +++ b/GP/VwTbrd.cpp @@ -1,6 +1,6 @@ // VwTbrd.cpp : Small scale playing board view. // -// Copyright (c) 1994-2025 By Dale L. Larson & William Su, All Rights Reserved. +// Copyright (c) 1994-2026 By Dale L. Larson & William Su, All Rights Reserved. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the diff --git a/GP/VwTbrd.h b/GP/VwTbrd.h index cbfbf43f..dc84f1b3 100644 --- a/GP/VwTbrd.h +++ b/GP/VwTbrd.h @@ -1,6 +1,6 @@ // VwTbrd.h : header file // -// Copyright (c) 1994-2025 By Dale L. Larson & William Su, All Rights Reserved. +// Copyright (c) 1994-2026 By Dale L. Larson & William Su, All Rights Reserved. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the diff --git a/GP/WinPoptb.cpp b/GP/WinPoptb.cpp index 58848505..7c140635 100644 --- a/GP/WinPoptb.cpp +++ b/GP/WinPoptb.cpp @@ -1,6 +1,6 @@ // WinPoptb.cpp : implementation file // -// Copyright (c) 1994-2025 By Dale L. Larson & William Su, All Rights Reserved. +// Copyright (c) 1994-2026 By Dale L. Larson & William Su, All Rights Reserved. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the diff --git a/GP/WinPoptb.h b/GP/WinPoptb.h index 35493130..b66541dd 100644 --- a/GP/WinPoptb.h +++ b/GP/WinPoptb.h @@ -1,6 +1,6 @@ // WinPoptb.h : header file // -// Copyright (c) 1994-2025 By Dale L. Larson & William Su, All Rights Reserved. +// Copyright (c) 1994-2026 By Dale L. Larson & William Su, All Rights Reserved. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the diff --git a/GShr/CyberBoard.h b/GShr/CyberBoard.h index 7c54971b..1e761ff2 100644 --- a/GShr/CyberBoard.h +++ b/GShr/CyberBoard.h @@ -1,6 +1,6 @@ // CyberBoard.h // -// Copyright (c) 2020-2025 By William Su, All Rights Reserved. +// Copyright (c) 2020-2026 By William Su, All Rights Reserved. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the diff --git a/GShr/DragDrop.h b/GShr/DragDrop.h index 9724ba65..27fc951b 100644 --- a/GShr/DragDrop.h +++ b/GShr/DragDrop.h @@ -1,6 +1,6 @@ // DragDrop.h // -// Copyright (c) 1994-2025 By Dale L. Larson & William Su, All Rights Reserved. +// Copyright (c) 1994-2026 By Dale L. Larson & William Su, All Rights Reserved. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the diff --git a/GShr/DrawObj.cpp b/GShr/DrawObj.cpp index 8f36b592..10705ace 100644 --- a/GShr/DrawObj.cpp +++ b/GShr/DrawObj.cpp @@ -1,6 +1,6 @@ // DrawObj.cpp // -// Copyright (c) 1994-2025 By Dale L. Larson & William Su, All Rights Reserved. +// Copyright (c) 1994-2026 By Dale L. Larson & William Su, All Rights Reserved. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the diff --git a/GShr/LBoxGfx2.cpp b/GShr/LBoxGfx2.cpp index 937dd65f..64daa3da 100644 --- a/GShr/LBoxGfx2.cpp +++ b/GShr/LBoxGfx2.cpp @@ -1,6 +1,6 @@ // LBoxGfx2.cpp // -// Copyright (c) 1994-2025 By Dale L. Larson & William Su, All Rights Reserved. +// Copyright (c) 1994-2026 By Dale L. Larson & William Su, All Rights Reserved. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the diff --git a/GShr/LBoxGfx2.h b/GShr/LBoxGfx2.h index cd9b8cbd..85b1ede2 100644 --- a/GShr/LBoxGfx2.h +++ b/GShr/LBoxGfx2.h @@ -1,6 +1,6 @@ // LBoxGfx2.h // -// Copyright (c) 1994-2025 By Dale L. Larson & William Su, All Rights Reserved. +// Copyright (c) 1994-2026 By Dale L. Larson & William Su, All Rights Reserved. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the diff --git a/GShr/WinState.h b/GShr/WinState.h index 86558d53..a90079c4 100644 --- a/GShr/WinState.h +++ b/GShr/WinState.h @@ -1,6 +1,6 @@ // WinState.h - classes used to manage window state. // -// Copyright (c) 1994-2025 By Dale L. Larson & William Su, All Rights Reserved. +// Copyright (c) 1994-2026 By Dale L. Larson & William Su, All Rights Reserved. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the