diff --git a/GM/CBDesign.fbp b/GM/CBDesign.fbp index d0451dcd..52d892b7 100644 --- a/GM/CBDesign.fbp +++ b/GM/CBDesign.fbp @@ -48,12 +48,12 @@ wxID_ANY - CBoardMaskDialog + CAboutDlg wxDEFAULT_DIALOG_STYLE ; ; forward_declare - Select Board + About CyberBoard Designer 0 @@ -61,23 +61,23 @@ - bSizer9 - wxHORIZONTAL + bSizer110 + wxVERTICAL none 5 wxEXPAND - 1 + 0 - bSizer10 - wxVERTICAL + bSizer111 + wxHORIZONTAL none 5 - wxTOP|wxRIGHT|wxLEFT + wxALL|wxALIGN_BOTTOM 0 - + 1 1 1 @@ -88,6 +88,7 @@ 0 + Load From Icon Resource; #IDR_MAINFRAME; [-1; -1] 1 0 @@ -106,8 +107,6 @@ 0 0 wxID_ANY - Select mask from board: - 0 0 @@ -115,7 +114,7 @@ 0 1 - m_staticText7 + m_bitmap1 1 @@ -125,21 +124,216 @@ Resizable 1 - ; ; forward_declare 0 - -1 5 - wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT + wxEXPAND + 1 + + + bSizer112 + wxVERTICAL + none + + 5 + wxALIGN_CENTER_HORIZONTAL|wxTOP|wxRIGHT|wxLEFT + 0 + + 1 + 1 + 1 + 1 + 0 + + 0 + 0 + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 0 + 1 + + 1 + + 0 + 0 + wxID_ANY + CyberBoard Designer Program + 0 + + 0 + + + 0 + + 1 + m_staticText91 + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + + + -1 + + + + 5 + wxALIGN_CENTER_HORIZONTAL|wxRIGHT|wxLEFT + 0 + + 1 + 1 + 1 + 1 + 0 + + 0 + 0 + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 0 + 1 + + 1 + + 0 + 0 + wxID_ANY + Program Version - ??????? + 0 + + 0 + + + 0 + + 1 + m_staticProgVer + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + + + -1 + + + + 5 + wxALIGN_CENTER_HORIZONTAL|wxBOTTOM|wxLEFT|wxRESERVE_SPACE_EVEN_IF_HIDDEN|wxRIGHT + 0 + + 1 + 1 + 1 + 1 + 0 + + 0 + 0 + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 0 + 1 + + 1 + + 0 + 1 + wxID_ANY + File Version - ??????? + 0 + + 0 + + + 0 + + 1 + m_staticFileVer + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + + + -1 + + + + + + 5 + wxALL|wxALIGN_BOTTOM 0 - + 1 1 1 @@ -150,10 +344,10 @@ 0 + Load From Icon Resource; #IDR_MAINFRAME; [-1; -1] 1 0 - "1" "2" "3" "4" "5" 1 1 @@ -176,7 +370,7 @@ 0 1 - m_lboxBoard + m_bitmap2 1 @@ -186,14 +380,9 @@ Resizable 1 - ; ; forward_declare 0 - - wxFILTER_NONE - wxDefaultValidator - @@ -203,18 +392,266 @@ 5 - wxEXPAND + wxALIGN_CENTER_HORIZONTAL|wxTOP|wxRIGHT|wxLEFT 0 - + + 1 + 1 + 1 + 1 + 0 + + 0 + 0 + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 0 + 1 + + 1 + + 0 + 0 + wxID_ANY + Copyright © 1994-2025 by Dale L. Larson and William Su + 0 + + 0 + + + 0 - bSizer11 - wxVERTICAL - none - - 5 - wxALL - 0 - + 1 + m_staticText94 + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + + + -1 + + + + 5 + wxALIGN_CENTER_HORIZONTAL|wxRIGHT|wxLEFT + 0 + + 1 + 1 + 1 + 1 + 0 + + 0 + 0 + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 0 + 1 + + 1 + + 0 + 0 + wxID_ANY + All Rights Reserved + 0 + + 0 + + + 0 + + 1 + m_staticText95 + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + + + -1 + + + + 5 + wxALIGN_CENTER_HORIZONTAL|wxBOTTOM|wxRIGHT|wxLEFT + 0 + + 1 + 1 + 1 + 1 + 0 + + 0 + 0 + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 0 + 1 + + 1 + + 0 + 0 + wxID_ANY + dlarson42@gmail.com + 0 + + 0 + + + 0 + + 1 + m_staticText96 + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + + + -1 + + + + 5 + wxALIGN_CENTER_HORIZONTAL|wxALL|wxRESERVE_SPACE_EVEN_IF_HIDDEN + 0 + + 1 + 1 + 1 + 1 + 0 + + 0 + 0 + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 0 + 1 + + 1 + + 0 + 1 + wxID_ANY + NOTE: Program ceases to function on: October 1, 2005 + 0 + + 0 + + + 0 + + 1 + m_staticText97 + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + + + -1 + + + + 5 + wxEXPAND + 0 + + + bSizer113 + wxHORIZONTAL + none + + 5 + wxALIGN_CENTER_VERTICAL|wxALL|wxRESERVE_SPACE_EVEN_IF_HIDDEN + 1 + 1 1 1 @@ -223,20 +660,15 @@ 0 0 - 0 - 1 0 1 1 - - 1 0 - Dock 0 Left @@ -244,13 +676,11 @@ 1 1 - 0 - 0 + 1 wxID_ANY - OK - + GenDate: ???? 0 0 @@ -259,34 +689,29 @@ 0 1 - wxID_OK + m_staticGenDate 1 protected 1 - - Resizable 1 - + wxALIGN_LEFT ; ; forward_declare 0 - - wxFILTER_NONE - wxDefaultValidator - + -1 5 - wxALL + wxALIGN_CENTER_VERTICAL|wxALL 0 1 @@ -323,7 +748,7 @@ 0 0 wxID_ANY - Cancel + OK 0 @@ -333,7 +758,7 @@ 0 1 - wxID_CANCEL + wxID_OK 1 @@ -358,33 +783,95 @@ - - - - - - 0 - wxAUI_MGR_DEFAULT - - wxBOTH - - 1 - 0 - 1 - impl_virtual - - - - 0 - wxID_ANY - - - CBoardPropDialog - + + 5 + wxALIGN_CENTER_VERTICAL|wxALL|wxRESERVE_SPACE_EVEN_IF_HIDDEN + 1 + + 1 + 1 + 1 + 1 + 0 + + 0 + 0 + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 0 + 1 + + 1 + + 0 + 1 + wxID_ANY + Beta XX + 0 + + 0 + + + 0 + + 1 + IDC_D_ABOUT_GENDATE2 + 1 + + + protected + 1 + + Resizable + 1 + + wxALIGN_RIGHT + ; ; forward_declare + 0 + + + + + -1 + + + + + + + + 0 + wxAUI_MGR_DEFAULT + + wxBOTH + + 1 + 0 + 1 + impl_virtual + + + + 0 + wxID_ANY + + + CBoardMaskDialog + wxDEFAULT_DIALOG_STYLE ; ; forward_declare - Board Properties + Select Board 0 @@ -392,16 +879,16 @@ - bSizer12 + bSizer9 wxHORIZONTAL none 5 - - 0 + wxEXPAND + 1 - bSizer13 + bSizer10 wxVERTICAL none @@ -437,7 +924,7 @@ 0 0 wxID_ANY - Board Name: + Select mask from board: 0 0 @@ -446,7 +933,7 @@ 0 1 - m_staticText31 + m_staticText7 1 @@ -470,7 +957,7 @@ 5 wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT 0 - + 1 1 1 @@ -484,6 +971,7 @@ 1 0 + "1" "2" "3" "4" "5" 1 1 @@ -502,12 +990,11 @@ 0 - 0 0 1 - m_editBrdName + m_lboxBoard 1 @@ -525,117 +1012,448 @@ wxFILTER_NONE wxDefaultValidator - + + + + 5 + wxEXPAND + 0 + + + bSizer11 + wxVERTICAL + none 5 - wxALL|wxEXPAND + wxALL 0 - + + 1 + 1 + 1 + 1 + 0 + + 0 + 0 + 0 + + + + + 1 + 0 + 1 + + 1 + + 1 + 0 + + Dock + 0 + Left + 0 + 1 + + 1 + + + 0 + 0 wxID_ANY - Snap Grid + OK + + 0 + + 0 + + + 0 - sbSizer1 - wxVERTICAL - 1 - none - - 5 - - 0 - - 4 - wxBOTH - - - 0 - - fgSizer3 - wxFLEX_GROWMODE_SPECIFIED - none - 2 - 0 - - 5 - wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL - 0 - - 1 - 1 - 1 - 1 - 0 - - 0 - 0 - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 0 - 1 - - 1 - - 0 - 0 - wxID_ANY - X Pixels: - 0 - - 0 - - - 0 - - 1 - m_staticText32 - 1 - - - protected - 1 - - Resizable - 1 - - - ; ; forward_declare - 0 - - - - - -1 - - - - 5 - wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxRIGHT - 0 - - 1 - 1 - 1 - 1 - 0 - - 0 - 0 - - + 1 + wxID_OK + 1 + + + protected + 1 + + + + Resizable + 1 + + + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + 5 + wxALL + 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 + Cancel + + 0 + + 0 + + + 0 + + 1 + wxID_CANCEL + 1 + + + protected + 1 + + + + Resizable + 1 + + + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + + + + 0 + wxAUI_MGR_DEFAULT + + wxBOTH + + 1 + 0 + 1 + impl_virtual + + + + 0 + wxID_ANY + + + CBoardPropDialog + + + wxDEFAULT_DIALOG_STYLE + ; ; forward_declare + Board Properties + + 0 + + + + + + bSizer12 + wxHORIZONTAL + none + + 5 + + 0 + + + bSizer13 + wxVERTICAL + none + + 5 + wxTOP|wxRIGHT|wxLEFT + 0 + + 1 + 1 + 1 + 1 + 0 + + 0 + 0 + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 0 + 1 + + 1 + + 0 + 0 + wxID_ANY + Board Name: + 0 + + 0 + + + 0 + + 1 + m_staticText31 + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + + + -1 + + + + 5 + wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT + 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 + + 0 + + 1 + m_editBrdName + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + 5 + wxALL|wxEXPAND + 0 + + wxID_ANY + Snap Grid + + sbSizer1 + wxVERTICAL + 1 + none + + 5 + + 0 + + 4 + wxBOTH + + + 0 + + fgSizer3 + wxFLEX_GROWMODE_SPECIFIED + none + 2 + 0 + + 5 + wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL + 0 + + 1 + 1 + 1 + 1 + 0 + + 0 + 0 + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 0 + 1 + + 1 + + 0 + 0 + wxID_ANY + X Pixels: + 0 + + 0 + + + 0 + + 1 + m_staticText32 + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + + + -1 + + + + 5 + wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxRIGHT + 0 + + 1 + 1 + 1 + 1 + 0 + + 0 + 0 + + 1 0 @@ -18890,7 +19708,7 @@ CTilePalette - 500,300 + -1,-1 CTilePalette; forward_declare 0 @@ -19371,146 +20189,1409 @@ - - 5 - wxEXPAND - 0 - + + 5 + wxEXPAND + 0 + + wxID_ANY + For This Tile Group + + sbSizer7 + wxVERTICAL + 1 + none + + 5 + wxALL + 0 + + 1 + 1 + 1 + 1 + 0 + + 0 + 0 + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 0 + 1 + + 1 + + 0 + 0 + wxID_ANY + Group Name: + 0 + + 0 + + + 0 + + 1 + m_staticText90 + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + + + -1 + + + + 5 + wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT + 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 + + 0 + + 1 + m_editName + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + + + + + + + 1 + 0 + 1 + + + 0 + wxID_ANY + + + + IDR_GAMEBOX + + + + ; ; forward_declare + + + + + + &File + m_menu11 + protected + + + 0 + 1 + Create a new GameBox New GameBox + wxID_ANY + wxITEM_NORMAL + New + wxID_NEW + none + Ctrl+N + + + + + 0 + 1 + Open an existing GameBox Open GameBox + wxID_ANY + wxITEM_NORMAL + Open + wxID_OPEN + none + Ctrl+O + + + + + 0 + 1 + Close the active document + wxID_ANY + wxITEM_NORMAL + &Close + wxID_CLOSE + none + + + + + + 0 + 1 + Save the active GameBox Save Active GameBox + wxID_ANY + wxITEM_NORMAL + &Save + wxID_SAVE + none + Ctrl+S + + + + + 0 + 1 + Save the active document with a new name + wxID_ANY + wxITEM_NORMAL + Save &As... + wxID_SAVEAS + none + + + + + m_separator23 + none + + + + 0 + 1 + Quit the application; prompts to save documents + wxID_ANY + wxITEM_NORMAL + E&xit + wxID_EXIT + none + Alt+F4 + + + + + &Edit + m_menu12 + protected + + + 0 + 1 + Undo the last action Undo + wxID_ANY + wxITEM_NORMAL + &Undo + wxID_UNDO + none + Ctrl+Z + + + + m_separator24 + none + + + + 0 + 1 + Copy the selection and put it on the Clipboard Copy + wxID_ANY + wxITEM_NORMAL + &Copy + wxID_COPY + none + Ctrl+C + + + + + 0 + 1 + Insert Clipboard contents Paste + wxID_ANY + wxITEM_NORMAL + &Paste + wxID_PASTE + none + Ctrl+V + + + + + 0 + 1 + Move clipboard objects to new locations Move + wxID_ANY + wxITEM_NORMAL + &Move + ID_EDIT_MOVE + none + Ctrl+M + + + + + 0 + 1 + Erase the current selection Delete (Del) + wxID_ANY + wxITEM_NORMAL + &Delete + wxID_DELETE + none + Del + + + + m_separator25 + none + + + + 0 + 1 + + wxID_ANY + wxITEM_NORMAL + Paste &Bitmap From File... + ID_EDIT_PASTEBITMAPFROMFILE + none + + + + + m_separator26 + none + + + + 0 + 1 + Edit the board's base drawing layer Base Drawing Layer + wxID_ANY + wxITEM_CHECK + B&ase Board Layer + ID_EDIT_LAYER_BASE + none + Ctrl+1 + + + + + 0 + 1 + Edit the board's cell layer Board Cell Layer + wxID_ANY + wxITEM_CHECK + C&ell Board Layer + ID_EDIT_LAYER_TILE + none + Ctrl+2 + + + + + 0 + 1 + Edit the board's top drawing layer Top Drawing Layer + wxID_ANY + wxITEM_CHECK + &Top Board Layer + ID_EDIT_LAYER_TOP + none + Ctrl+3 + + + + m_separator27 + none + + + + 0 + 1 + Change the board properties + wxID_ANY + wxITEM_NORMAL + Board Properties... + ID_TOOLS_BRDPROPS + none + + + + + + &View + m_menu13 + protected + + + 0 + 1 + Show or hide the status bar + wxID_ANY + wxITEM_CHECK + Status Bar + ID_VIEW_STATUS_BAR + none + + + + + m_separator28 + none + + + + 0 + 1 + Zoom the tile image in Zoom Tile Image In + wxID_ANY + wxITEM_NORMAL + Zoom Tile Image &In + wxID_ZOOM_IN + none + + + + + + 0 + 1 + Zoom the tile image out Zoom Tile Image Out + wxID_ANY + wxITEM_NORMAL + Zoom Tile Image &Out + wxID_ZOOM_OUT + none + + + + + m_separator29 + none + + + + 0 + 1 + Shows or hides tile editor grid lines Tile Grid Lines + wxID_ANY + wxITEM_CHECK + Tile Image &Grid Lines + ID_IMAGE_GRIDLINES + none + + + + + m_separator30 + none + + + + 0 + 1 + Show full scale board view + wxID_ANY + wxITEM_CHECK + &Full Scale Board + ID_VIEW_FULLSCALE + none + + + + + + 0 + 1 + Show half scale board view + wxID_ANY + wxITEM_CHECK + &Half Scale Board + ID_VIEW_HALFSCALE + none + + + + + + 0 + 1 + Show small scale board view + wxID_ANY + wxITEM_CHECK + S&mall Scale Board + ID_VIEW_SMALLSCALE + none + + + + + m_separator31 + none + + + + 0 + 1 + Hides or shows cell layer border lines Cell Border Lines + wxID_ANY + wxITEM_CHECK + &Cell Border Lines + ID_VIEW_GRIDLINES + none + + + + + + &Project + m_menu14 + protected + + + 0 + 1 + Create game play board. + wxID_ANY + wxITEM_NORMAL + Create Playing &Board... + ID_EDIT_CREATEBOARD + none + + + + + + 0 + 1 + Create tile image grouping + wxID_ANY + wxITEM_NORMAL + Create Tile &Image Group... + ID_EDIT_CREATETILEGROUP + none + + + + + + 0 + 1 + Create a grouping for playing pieces + wxID_ANY + wxITEM_NORMAL + Create Playing &Piece Group... + ID_EDIT_CREATEPIECEGROUP + none + + + + + + 0 + 1 + Create a grouping for markers + wxID_ANY + wxITEM_NORMAL + Create &Marker Group... + ID_EDIT_CREATEMARKGROUP + none + + + + + m_separator32 + none + + + + 0 + 1 + Edit the game box properties + wxID_ANY + wxITEM_NORMAL + &GameBox Properties... + ID_EDIT_GBOXPROPERTIES + none + + + + + + 0 + 1 + Change GameBox Fingerprint. + wxID_ANY + wxITEM_NORMAL + Change GameBox &Fingerprint... + ID_PROJECT_CHGID + none + + + + + m_separator33 + none + + + + 0 + 1 + Save tiles in a tile library file Save Tile File + wxID_ANY + wxITEM_NORMAL + &Save Tile Library File... + ID_PROJECT_SAVETILEFILE + none + + + + + + 0 + 1 + Load tiles from a tile library file Load Tile File + wxID_ANY + wxITEM_NORMAL + &Load Tile Library File... + ID_PROJECT_LOADTILEFILE + none + + + + + + &Tools + m_menu15 + protected + + + 0 + 1 + Set default drawing font. + wxID_ANY + wxITEM_NORMAL + Fo&nt... + ID_DWG_FONT + none + + + + + m_separator34 + none + + + + 0 + 1 + Brings the selected drawing objects to the front of the drawing Move Object to Front + wxID_ANY + wxITEM_NORMAL + Bring Objects to &Front + ID_DWG_TOFRONT + none + + + + + + 0 + 1 + Sends the selected drawing objects to the back of the drawing Move Object to Back + wxID_ANY + wxITEM_NORMAL + Send Objects to &Back + ID_DWG_TOBACK + none + + + + + + 0 + 1 + Draw selected objects above the grid lines Draw Above Grid + wxID_ANY + wxITEM_CHECK + Draw Objects Above Grid + ID_DWG_DRAWABOVEGRID + none + + + + + m_separator35 + none + + + + 0 + 1 + Select which scales the objects are visible + wxID_ANY + wxITEM_NORMAL + Set Scale &Visibility... + ID_TOOL_SETVISIBLESCALE + none + + + + + + 0 + 1 + Turn off scaled visibility for drawn objects + wxID_ANY + wxITEM_CHECK + &Suspend Scale Visibility + ID_TOOL_SUSPENDSCALEVISIBILITY + none + + + + + m_separator36 + none + + + + 0 + 1 + Enable or disables the board editor snap grid Board Snap Grid + wxID_ANY + wxITEM_CHECK + Snap &Grid + ID_TOOLS_BRDSNAPGRID + none + + + + + + 0 + 1 + Change the board properties + wxID_ANY + wxITEM_NORMAL + Bo&ard Properties... + ID_TOOLS_BRDPROPS + none + + + + + m_separator37 + none + + + + 0 + 1 + Toggle automatic selection of Select tool after drawing. + wxID_ANY + wxITEM_CHECK + Drawing Tools Are Sticky + ID_STICKY_DRAWTOOLS + none + + + + + + Board Drawing Tools + m_menu5 + protected + + + 0 + 1 + Selects objects Select Objects + wxID_ANY + wxITEM_CHECK + &Selector + ID_TOOL_ARROW + none + + + + + + 0 + 1 + Extract a color from the screen Pickup Color + wxID_ANY + wxITEM_CHECK + Pick&up Color + ID_TOOL_DROPPER + none + + + + + + 0 + 1 + Places tiles on the board Tile + wxID_ANY + wxITEM_CHECK + Draw &Tile + ID_TOOL_TILE + none + + + + + + 0 + 1 + Places text on the board Text + wxID_ANY + wxITEM_CHECK + Draw Te&xt + ID_TOOL_TEXT + none + + + + + + 0 + 1 + Draw a line on the board Line + wxID_ANY + wxITEM_CHECK + Draw &Line + ID_TOOL_LINE + none + + + + + + 0 + 1 + Draw a rectangle on the board Rectangle + wxID_ANY + wxITEM_CHECK + Draw &Rectangle + ID_TOOL_RECT + none + + + + + + 0 + 1 + Draw a polygon or polyline on board Polygon or Polyline + wxID_ANY + wxITEM_CHECK + Draw &Polygon + ID_TOOL_POLYGON + none + + + + + + 0 + 1 + Draw an oval on the board Oval + wxID_ANY + wxITEM_CHECK + Draw &Oval + ID_TOOL_OVAL + none + + + + + + 0 + 1 + Fills board cell with a single color Color Cell + wxID_ANY + wxITEM_CHECK + &Color Cell + ID_TOOL_FILL + none + + + + + + 0 + 1 + Erases contents of board cell Erase Cell + wxID_ANY + wxITEM_CHECK + &Erase Cell + ID_TOOL_ERASER + none + + + + + + m_separator39 + none + + + + 0 + 1 + Update original tile with changes + wxID_ANY + wxITEM_NORMAL + &Update Tile Changes + ID_IMAGE_UPDATE + none + Ctrl+U + + + + + 0 + 1 + Discard changes to tile image + wxID_ANY + wxITEM_NORMAL + &Discard Tile Changes + ID_IMAGE_DISCARD + none + + + + + + Rotate Tile + m_menu6 + protected + + + 0 + 1 + Rotate the tile image clockwise 90 degrees + wxID_ANY + wxITEM_NORMAL + 90° + ID_TOOLS_ROT90 + none + + + + + + 0 + 1 + Rotate the tile image clockwise 180 degrees + wxID_ANY + wxITEM_NORMAL + 180° + ID_TOOLS_ROT180 + none + + + + + + 0 + 1 + Rotate the tile image clockwise 270 degrees + wxID_ANY + wxITEM_NORMAL + 270° + ID_TOOLS_ROT270 + none + + + + + + + 0 + 1 + Resize the tile's bitmaps + wxID_ANY + wxITEM_NORMAL + R&esize Tile... + ID_TOOLS_RESIZETILE + none + + + + + + 0 + 1 + Apply the cell mask from a board + wxID_ANY + wxITEM_NORMAL + Apply Cell &Mask to Tile... + ID_IMAGE_BOARDMASK + none + + + + + m_separator40 + none + + + + Tile Image Tools + m_menu7 + protected + + + 0 + 1 + Draws using a singe-pixel pencil Pixel Pencil wxID_ANY - For This Tile Group - - sbSizer7 - wxVERTICAL - 1 + wxITEM_CHECK + &Pencil + ID_ITOOL_PENCIL none - - 5 - wxALL - 0 - - 1 - 1 - 1 - 1 - 0 - - 0 - 0 - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 0 - 1 - - 1 - - 0 - 0 - wxID_ANY - Group Name: - 0 - - 0 - - - 0 - - 1 - m_staticText90 - 1 - - - protected - 1 - - Resizable - 1 - - - ; ; forward_declare - 0 - - - - - -1 - - - - 5 - wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT - 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 - - 0 - - 1 - m_editName - 1 - - - protected - 1 - - Resizable - 1 - - - ; ; forward_declare - 0 - - - wxFILTER_NONE - wxDefaultValidator - - - - - - - + + + + + + 0 + 1 + Selects a portion the image for move, cut or copy Select + wxID_ANY + wxITEM_CHECK + &Selector + ID_ITOOL_SELECT + none + + + + + + 0 + 1 + Draw using a brush having the selected size Brush + wxID_ANY + wxITEM_CHECK + &Brush + ID_ITOOL_BRUSH + none + + + + + + 0 + 1 + Fill a portion of the image with the selected color Fill + wxID_ANY + wxITEM_CHECK + &Fill + ID_ITOOL_FILL + none + + + + + + 0 + 1 + Change clicked color to current color. Change Color + wxID_ANY + wxITEM_CHECK + &Change Color + ID_ITOOL_COLORCHANGE + none + + + + + + 0 + 1 + Draw text on the image using the current font Text + wxID_ANY + wxITEM_CHECK + &Text + ID_ITOOL_TEXT + none + + + + + + 0 + 1 + Draw lines on the the image using the current size Line + wxID_ANY + wxITEM_CHECK + &Line + ID_ITOOL_LINE + none + + + + + + 0 + 1 + Draw a rectagle using the selected color and border width Rectangle + wxID_ANY + wxITEM_CHECK + &Rect + ID_ITOOL_RECT + none + + + + + + 0 + 1 + Draw an oval using the selected color and border width Oval + wxID_ANY + wxITEM_CHECK + &Oval + ID_ITOOL_OVAL + none + + + + + + 0 + 1 + Draw a filled rectagle using the selected color and border width Filled Rectangle + wxID_ANY + wxITEM_CHECK + Filled R&ect + ID_ITOOL_FILLRECT + none + + + + + 0 + 1 + Draw an filled oval using the selected colors and border width Filled Oval + wxID_ANY + wxITEM_CHECK + Filled O&val + ID_ITOOL_FILLOVAL + none + + + + + + 0 + 1 + Extract a color from the screen Pickup Color + wxID_ANY + wxITEM_CHECK + P&ickup Color + ID_ITOOL_DROPPER + none + + + + + + + Help + m_menu17 + protected + + + 0 + 1 + List Help topics + wxID_ANY + wxITEM_NORMAL + Contents + ID_HELP_INDEX + none + + + + + m_separator21 + none + + + + 0 + 1 + Opens a web browser and takes you to the CyberBoard web site. + wxID_ANY + wxITEM_NORMAL + Visit the CyberBoard Web Site... + ID_HELP_WEBSITE + none + + + + + + 0 + 1 + + wxID_ANY + wxITEM_NORMAL + Latest CyberBoard Releases... + ID_HELP_RELEASES + none + + + + + m_separator22 + none + + + + 0 + 1 + Display program information, version number and copyright Program Information + wxID_ANY + wxITEM_NORMAL + &About CyberBoard... + wxID_ABOUT + none + + + + + + + + + 1 + 0 + 1 + + + 0 + wxID_ANY + + + + IDR_MAINFRAME + + + + ; ; forward_declare + + + + + + File + m_menu7 + protected + + + 0 + 1 + Create a new GameBox New GameBox + wxID_ANY + wxITEM_NORMAL + New + wxID_NEW + none + Ctrl+N + + + + + 0 + 1 + Open an existing GameBox Open GameBox + wxID_ANY + wxITEM_NORMAL + Open + wxID_OPEN + none + Ctrl+O + + + + m_separator20 + none + + + + 0 + 1 + Quit the application; prompts to save documents + wxID_ANY + wxITEM_NORMAL + Exit + wxID_EXIT + none + Alt+F4 + + + + + View + m_menu8 + protected + + + 0 + 1 + Show or hide the status bar + wxID_ANY + wxITEM_CHECK + Status Bar + ID_VIEW_STATUS_BAR + none + + + + + + Help + m_menu9 + protected + + + 0 + 1 + List Help topics + wxID_ANY + wxITEM_NORMAL + Contents + ID_HELP_INDEX + none + + + + + m_separator21 + none + + + + 0 + 1 + Opens a web browser and takes you to the CyberBoard web site. + wxID_ANY + wxITEM_NORMAL + Visit the CyberBoard Web Site... + ID_HELP_WEBSITE + none + + + + + + 0 + 1 + + wxID_ANY + wxITEM_NORMAL + Latest CyberBoard Releases... + ID_HELP_RELEASES + none + + + + + m_separator22 + none + + + + 0 + 1 + Display program information, version number and copyright Program Information + wxID_ANY + wxITEM_NORMAL + &About CyberBoard... + wxID_ABOUT + none + + diff --git a/GM/CBDesign.xrc b/GM/CBDesign.xrc index 7bd63ae0..fee67575 100644 --- a/GM/CBDesign.xrc +++ b/GM/CBDesign.xrc @@ -1,5 +1,152 @@ + + + About CyberBoard Designer + 1 + + wxVERTICAL + + wxEXPAND + 5 + + + wxHORIZONTAL + + wxALL|wxALIGN_BOTTOM + 5 + + + + + + + wxEXPAND + 5 + + + wxVERTICAL + + wxALIGN_CENTER_HORIZONTAL|wxTOP|wxRIGHT|wxLEFT + 5 + + + + -1 + + + + wxALIGN_CENTER_HORIZONTAL|wxRIGHT|wxLEFT + 5 + + + + -1 + + + + wxALIGN_CENTER_HORIZONTAL|wxBOTTOM|wxLEFT|wxRESERVE_SPACE_EVEN_IF_HIDDEN|wxRIGHT + 5 + + + 1 + + -1 + + + + + + wxALL|wxALIGN_BOTTOM + 5 + + + + + + + + + wxALIGN_CENTER_HORIZONTAL|wxTOP|wxRIGHT|wxLEFT + 5 + + + + -1 + + + + wxALIGN_CENTER_HORIZONTAL|wxRIGHT|wxLEFT + 5 + + + + -1 + + + + wxALIGN_CENTER_HORIZONTAL|wxBOTTOM|wxRIGHT|wxLEFT + 5 + + + + -1 + + + + wxALIGN_CENTER_HORIZONTAL|wxALL|wxRESERVE_SPACE_EVEN_IF_HIDDEN + 5 + + + 1 + + -1 + + + + wxEXPAND + 5 + + + wxHORIZONTAL + + wxALIGN_CENTER_VERTICAL|wxALL|wxRESERVE_SPACE_EVEN_IF_HIDDEN + 5 + + + + 1 + + -1 + + + + wxALIGN_CENTER_VERTICAL|wxALL + 5 + + + + 0 + 0 + 0 + + + + + wxALIGN_CENTER_VERTICAL|wxALL|wxRESERVE_SPACE_EVEN_IF_HIDDEN + 5 + + + + 1 + + -1 + + + + + + Select Board @@ -3565,7 +3712,6 @@ - 500,300 wxVERTICAL @@ -3690,6 +3836,514 @@ + + + + + + Ctrl+N + Create a new GameBox\nNew GameBox + + + + Ctrl+O + Open an existing GameBox\nOpen GameBox + + + + + Close the active document + + + + Ctrl+S + Save the active GameBox\nSave Active GameBox + + + + + Save the active document with a new name + + + + + Alt+F4 + Quit the application; prompts to save documents + + + + + + + Ctrl+Z + Undo the last action\nUndo + + + + + Ctrl+C + Copy the selection and put it on the Clipboard\nCopy + + + + Ctrl+V + Insert Clipboard contents\nPaste + + + + Ctrl+M + Move clipboard objects to new locations\nMove + + + + Del + Erase the current selection\nDelete (Del) + + + + + + + + + + + Ctrl+1 + Edit the board's base drawing layer\nBase Drawing Layer + 1 + + + + Ctrl+2 + Edit the board's cell layer\nBoard Cell Layer + 1 + + + + Ctrl+3 + Edit the board's top drawing layer\nTop Drawing Layer + 1 + + + + + + Change the board properties + + + + + + + + Show or hide the status bar + 1 + + + + + + Zoom the tile image in\nZoom Tile Image In + + + + + Zoom the tile image out\nZoom Tile Image Out + + + + + + Shows or hides tile editor grid lines\nTile Grid Lines + 1 + + + + + + Show full scale board view + 1 + + + + + Show half scale board view + 1 + + + + + Show small scale board view + 1 + + + + + + Hides or shows cell layer border lines\nCell Border Lines + 1 + + + + + + + + Create game play board. + + + + + Create tile image grouping + + + + + Create a grouping for playing pieces + + + + + Create a grouping for markers + + + + + + Edit the game box properties + + + + + Change GameBox Fingerprint. + + + + + + Save tiles in a tile library file\nSave Tile File + + + + + Load tiles from a tile library file\nLoad Tile File + + + + + + + + Set default drawing font. + + + + + + Brings the selected drawing objects to the front of the drawing\nMove Object to Front + + + + + Sends the selected drawing objects to the back of the drawing\nMove Object to Back + + + + + Draw selected objects above the grid lines\nDraw Above Grid + 1 + + + + + + Select which scales the objects are visible + + + + + Turn off scaled visibility for drawn objects + 1 + + + + + + Enable or disables the board editor snap grid\nBoard Snap Grid + 1 + + + + + Change the board properties + + + + + + Toggle automatic selection of Select tool after drawing. + 1 + + + + + + + Selects objects\nSelect Objects + 1 + + + + + Extract a color from the screen\nPickup Color + 1 + + + + + Places tiles on the board\nTile + 1 + + + + + Places text on the board\nText + 1 + + + + + Draw a line on the board\nLine + 1 + + + + + Draw a rectangle on the board\nRectangle + 1 + + + + + Draw a polygon or polyline on board\nPolygon or Polyline + 1 + + + + + Draw an oval on the board\nOval + 1 + + + + + Fills board cell with a single color\nColor Cell + 1 + + + + + Erases contents of board cell\nErase Cell + 1 + + + + + + Ctrl+U + Update original tile with changes + + + + + Discard changes to tile image + + + + + + + Rotate the tile image clockwise 90 degrees + + + + + Rotate the tile image clockwise 180 degrees + + + + + Rotate the tile image clockwise 270 degrees + + + + + + Resize the tile's bitmaps + + + + + Apply the cell mask from a board + + + + + + + + Draws using a singe-pixel pencil\nPixel Pencil + 1 + + + + + Selects a portion the image for move, cut or copy\nSelect + 1 + + + + + Draw using a brush having the selected size\nBrush + 1 + + + + + Fill a portion of the image with the selected color\nFill + 1 + + + + + Change clicked color to current color.\nChange Color + 1 + + + + + Draw text on the image using the current font\nText + 1 + + + + + Draw lines on the the image using the current size\nLine + 1 + + + + + Draw a rectagle using the selected color and border width\nRectangle + 1 + + + + + Draw an oval using the selected color and border width\nOval + 1 + + + + + Draw a filled rectagle using the selected color and border width\nFilled Rectangle + 1 + + + + + Draw an filled oval using the selected colors and border width\nFilled Oval + 1 + + + + + Extract a color from the screen\nPickup Color + 1 + + + + + + + + + List Help topics + + + + + + Opens a web browser and takes you to the CyberBoard web site. + + + + + + + + + + + Display program information, version number and copyright\nProgram Information + + + + + + + + + Ctrl+N + Create a new GameBox\nNew GameBox + + + + Ctrl+O + Open an existing GameBox\nOpen GameBox + + + + + Alt+F4 + Quit the application; prompts to save documents + + + + + + + + Show or hide the status bar + 1 + + + + + + + + List Help topics + + + + + + Opens a web browser and takes you to the CyberBoard web site. + + + + + + + + + + + Display program information, version number and copyright\nProgram Information + + + diff --git a/GM/CBDsgn32.vcxproj b/GM/CBDsgn32.vcxproj index 50948410..d7118fb5 100644 --- a/GM/CBDsgn32.vcxproj +++ b/GM/CBDsgn32.vcxproj @@ -134,7 +134,7 @@ echo off false - wxbase33ud.lib;wxbase33ud_xml.lib;wxexpatd.lib;wxmsw33ud_core.lib;wxmsw33ud_html.lib;wxmsw33ud_xrc.lib;wxpngd.lib;wxzlibd.lib;htmlhelp.lib;rpcrt4.lib;%(AdditionalDependencies) + wxbase33ud.lib;wxbase33ud_xml.lib;wxexpatd.lib;wxmsw33ud_aui.lib;wxmsw33ud_core.lib;wxmsw33ud_html.lib;wxmsw33ud_xrc.lib;wxpngd.lib;wxzlibd.lib;htmlhelp.lib;rpcrt4.lib;%(AdditionalDependencies) true true Windows @@ -186,7 +186,7 @@ echo off false - wxbase33ud.lib;wxbase33ud_xml.lib;wxexpatd.lib;wxmsw33ud_core.lib;wxmsw33ud_html.lib;wxmsw33ud_xrc.lib;wxpngd.lib;wxzlibd.lib;htmlhelp.lib;rpcrt4.lib;%(AdditionalDependencies) + wxbase33ud.lib;wxbase33ud_xml.lib;wxexpatd.lib;wxmsw33ud_aui.lib;wxmsw33ud_core.lib;wxmsw33ud_html.lib;wxmsw33ud_xrc.lib;wxpngd.lib;wxzlibd.lib;htmlhelp.lib;rpcrt4.lib;%(AdditionalDependencies) true true Windows @@ -237,7 +237,7 @@ echo off $(SolutionDir)deps\wxWidgets\include - wxbase33u.lib;wxbase33u_xml.lib;wxexpat.lib;wxmsw33u_core.lib;wxmsw33u_html.lib;wxmsw33u_xrc.lib;wxpng.lib;wxzlib.lib;htmlhelp.lib;rpcrt4.lib;%(AdditionalDependencies) + wxbase33u.lib;wxbase33u_xml.lib;wxexpat.lib;wxmsw33u_aui.lib;wxmsw33u_core.lib;wxmsw33u_html.lib;wxmsw33u_xrc.lib;wxpng.lib;wxzlib.lib;htmlhelp.lib;rpcrt4.lib;%(AdditionalDependencies) true Windows false @@ -292,7 +292,7 @@ echo off ..\out\build\x64-Release\deps\wxWidgets\lib\vc_x64_lib - wxbase33u.lib;wxbase33u_xml.lib;wxexpat.lib;wxmsw33u_core.lib;wxmsw33u_html.lib;wxmsw33u_xrc.lib;wxpng.lib;wxzlib.lib;htmlhelp.lib;rpcrt4.lib;%(AdditionalDependencies) + wxbase33u.lib;wxbase33u_xml.lib;wxexpat.lib;wxmsw33u_aui.lib;wxmsw33u_core.lib;wxmsw33u_html.lib;wxmsw33u_xrc.lib;wxpng.lib;wxzlib.lib;htmlhelp.lib;rpcrt4.lib;%(AdditionalDependencies) @@ -333,10 +333,8 @@ echo off - - @@ -421,10 +419,8 @@ echo off - - diff --git a/GM/CBDsgn32.vcxproj.filters b/GM/CBDsgn32.vcxproj.filters index 5e72042b..a391a48b 100644 --- a/GM/CBDsgn32.vcxproj.filters +++ b/GM/CBDsgn32.vcxproj.filters @@ -120,18 +120,12 @@ Source Files - - Source Files - Source Files Source Files - - Source Files - Source Files @@ -361,18 +355,12 @@ Header Files - - Header Files - Header Files Header Files - - Header Files - Header Files diff --git a/GM/CMakeLists.txt b/GM/CMakeLists.txt index f6e972a7..75a8f2c6 100644 --- a/GM/CMakeLists.txt +++ b/GM/CMakeLists.txt @@ -29,10 +29,8 @@ set(SRCS DlgTilsz.cpp DlgTsetp.cpp FrmBited.cpp - FrmBxdoc.cpp FrmDockTile.cpp FrmMain.cpp - FrmView.cpp Gm.cpp GmDoc.cpp LBoxTile.cpp @@ -108,7 +106,7 @@ endif() target_include_directories(CBDesign PRIVATE . ../GShr) target_precompile_headers(CBDesign PRIVATE StdAfx.h) -target_link_libraries(CBDesign wx::core wx::xrc) +target_link_libraries(CBDesign wx::aui wx::core wx::xrc) add_custom_command( OUTPUT "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/CBDesign.xrc" diff --git a/GM/FrmBited.cpp b/GM/FrmBited.cpp index 0fc1dc8b..34f02092 100644 --- a/GM/FrmBited.cpp +++ b/GM/FrmBited.cpp @@ -1,6 +1,6 @@ // FrmBited.cpp // -// 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 @@ -26,6 +26,7 @@ #include "Gm.h" #include "GmDoc.h" #include "FrmBited.h" +#include "FrmMain.h" #include "VwBitedt.h" #include "VwTilesl.h" @@ -34,41 +35,86 @@ static char THIS_FILE[] = __FILE__; #endif +wxIMPLEMENT_DYNAMIC_CLASS(wxBitEditView, wxView); + +namespace { + TileID createParam = nullTid; +} + ///////////////////////////////////////////////////////////////////////////// // CBitEditFrame -IMPLEMENT_DYNCREATE(CBitEditFrame, CMDIChildWndEx) - -CBitEditFrame::CBitEditFrame() : - CB::wxNativeContainerWindowMixin(static_cast(*this)) +CBitEditFrame::CBitEditFrame(wxDocument& doc, + wxBitEditView& view, + wxAuiMDIParentFrame& parent) : + BASE(&doc, &view, &parent, wxID_ANY, + doc.GetUserReadableName() + " - Tile Editor"), + m_wndSplitter([this, &view]{ + wxSplitterWindow* retval = new wxSplitterWindow(this, + wxID_ANY, + wxDefaultPosition, + wxDefaultSize, + /* this seems to be the only combo of flags + that creates a visible sash */ + wxSP_3D | wxSP_NO_XP_THEME); + retval->SetMinimumPaneSize(20); + retval->SetSashGravity(0.0); + CTileSelView* pSelView = new CTileSelView(*retval, view, createParam); + CBitEditView* pBitView = new CBitEditView(*retval, view); + if (!retval->SplitVertically(pSelView, pBitView, 90)) + { + AfxThrowMemoryException(); + } + // Link the biteditor view to the tile selector and vice versa + pSelView->SetBitEditor(*pBitView); + pBitView->SetTileSelectView(*pSelView); + pSelView->OnInitialUpdate(); + pBitView->OnInitialUpdate(); + return retval; + }()) { + SetIcon(wxIcon(std::format("#{}", IDR_BITEDITOR), + wxBITMAP_TYPE_ICO_RESOURCE, + 16, 16)); + /* KLUDGE: giving each frame its own menu + seems to avoid crashes on process close */ + wxXmlResource::Get()->LoadMenuBar(this, "IDR_GAMEBOX"_cbstring); + Layout(); } +#if 0 CBitEditFrame::~CBitEditFrame() { } +#endif -BEGIN_MESSAGE_MAP(CBitEditFrame, CMDIChildWndEx) - //{{AFX_MSG_MAP(CBitEditFrame) +wxBEGIN_EVENT_TABLE(CBitEditFrame, CBitEditFrame::BASE) +#if 0 ON_WM_CLOSE() - ON_COMMAND(ID_IMAGE_DISCARD, OnImageDiscard) - ON_COMMAND(ID_IMAGE_UPDATE, OnImageUpdate) - ON_COMMAND(ID_TOOLS_RESIZETILE, OnToolsResizeTile) +#endif + EVT_MENU(XRCID("ID_IMAGE_DISCARD"), OnImageDiscard) + EVT_MENU(XRCID("ID_IMAGE_UPDATE"), OnImageUpdate) + EVT_MENU(XRCID("ID_TOOLS_RESIZETILE"), OnToolsResizeTile) + EVT_UPDATE_UI(XRCID("ID_IMAGE_DISCARD"), OnUpdateEnable) + EVT_UPDATE_UI(XRCID("ID_IMAGE_UPDATE"), OnUpdateEnable) + EVT_UPDATE_UI(XRCID("ID_TOOLS_RESIZETILE"), OnUpdateEnable) +#if 0 ON_COMMAND(ID_EDIT_UNDO, OnEditUndo) ON_UPDATE_COMMAND_UI(ID_EDIT_UNDO, OnUpdateEditUndo) - ON_COMMAND_EX(ID_TOOLS_ROT90, OnRotateTile) - ON_COMMAND_EX(ID_TOOLS_ROT180, OnRotateTile) - ON_COMMAND_EX(ID_TOOLS_ROT270, OnRotateTile) - ON_UPDATE_COMMAND_UI(ID_TOOLS_ROT90, OnUpdateRotateTile) - ON_UPDATE_COMMAND_UI(ID_TOOLS_ROT180, OnUpdateRotateTile) - ON_UPDATE_COMMAND_UI(ID_TOOLS_ROT270, OnUpdateRotateTile) - //}}AFX_MSG_MAP -END_MESSAGE_MAP() +#endif + EVT_MENU(XRCID("ID_TOOLS_ROT90"), OnRotateTile) + EVT_MENU(XRCID("ID_TOOLS_ROT180"), OnRotateTile) + EVT_MENU(XRCID("ID_TOOLS_ROT270"), OnRotateTile) + EVT_UPDATE_UI(XRCID("ID_TOOLS_ROT90"), OnUpdateRotateTile) + EVT_UPDATE_UI(XRCID("ID_TOOLS_ROT180"), OnUpdateRotateTile) + EVT_UPDATE_UI(XRCID("ID_TOOLS_ROT270"), OnUpdateRotateTile) +wxEND_EVENT_TABLE() ///////////////////////////////////////////////////////////////////////////// +#if 0 BOOL CBitEditFrame::PreCreateWindow(CREATESTRUCT& cs) { if (!CMDIChildWndEx::PreCreateWindow(cs)) @@ -134,23 +180,25 @@ void CBitEditFrame::OnClose() { CWnd::OnClose(); // Short circuit frame's doc close code } +#endif -void CBitEditFrame::OnImageDiscard() +void CBitEditFrame::OnImageDiscard(wxCommandEvent& WXUNUSED(event)) { GetTileSelView().SetNoUpdate(); - PostMessage(WM_CLOSE, 0, 0L); + Close(); } -void CBitEditFrame::OnImageUpdate() +void CBitEditFrame::OnImageUpdate(wxCommandEvent& WXUNUSED(event)) { GetTileSelView().UpdateDocumentTiles(); } -void CBitEditFrame::OnToolsResizeTile() +void CBitEditFrame::OnToolsResizeTile(wxCommandEvent& WXUNUSED(event)) { GetTileSelView().DoTileResizeDialog(); } +#if 0 void CBitEditFrame::OnEditUndo() { wxASSERT(!"unreachable code?"); @@ -168,30 +216,121 @@ void CBitEditFrame::OnUpdateEditUndo(CCmdUI* pCmdUI) GetTileSelView().OnUpdateEditUndo(pCmdUI); #endif } +#endif -BOOL CBitEditFrame::OnRotateTile(UINT id) +void CBitEditFrame::OnRotateTile(wxCommandEvent& event) { - int nAngle = (id == ID_TOOLS_ROT90) ? 90 : - ((id == ID_TOOLS_ROT180) ? 180 : 270); + int id = event.GetId(); + int nAngle = (id == XRCID("ID_TOOLS_ROT90")) ? 90 : + ((id == XRCID("ID_TOOLS_ROT180")) ? 180 : 270); GetTileSelView().DoTileRotation(nAngle); - return TRUE; } -void CBitEditFrame::OnUpdateRotateTile(CCmdUI* pCmdUI) +void CBitEditFrame::OnUpdateRotateTile(wxUpdateUIEvent& pCmdUI) { - if (pCmdUI->m_pSubMenu != NULL && pCmdUI->m_nID == ID_TOOLS_ROT90) + pCmdUI.Enable(TRUE); +} + +void CBitEditFrame::OnUpdateEnable(wxUpdateUIEvent& pCmdUI) +{ + pCmdUI.Enable(true); +} + +wxBitEditView* wxBitEditView::New(CGamDoc& doc, TileID tid) +{ + wxDocManager& docMgr = CheckedDeref(wxDocManager::GetDocumentManager()); + wxDocTemplate& templ = CB::FindDocTemplateByView(*CLASSINFO(wxBitEditView)); + + class CreateParamManager { - // Need to enable menu that the submenu is connected to. - pCmdUI->m_pMenu->EnableMenuItem(pCmdUI->m_nIndex, - MF_BYPOSITION | MF_ENABLED); - } + public: + CreateParamManager(TileID tid) + { + wxASSERT(createParam == nullTid); + createParam = tid; + } + ~CreateParamManager() + { + createParam = nullTid; + } + } createParamMgr(tid); + ::wxView* retval = templ.CreateView(&doc); + wxASSERT(dynamic_cast(retval)); + return static_cast(retval); +} + +CGamDoc& wxBitEditView::GetDocument() +{ + wxDocument& doc = CheckedDeref(wxView::GetDocument()); + wxASSERT(dynamic_cast(&doc)); + return static_cast(doc); +} - pCmdUI->Enable(TRUE); +CBitEditFrame& wxBitEditView::GetFrame() +{ + wxWindow& frame = CheckedDeref(GetDocChildFrame()->GetWindow()); + wxASSERT(dynamic_cast(&frame)); + return static_cast(frame); +} + +CBitEditView& CBitEditFrame::GetBitEditView() +{ + wxWindow& wnd = CheckedDeref(m_wndSplitter->GetWindow2()); + CBitEditView& bev = dynamic_cast(wnd); + return bev; } CTileSelView& CBitEditFrame::GetTileSelView() { - CWnd& wnd = CheckedDeref(m_wndSplitter.GetPane(0, 0)); - CTileSelViewContainer& tsvc = dynamic_cast(wnd); - return tsvc.GetChild(); + wxWindow& wnd = CheckedDeref(m_wndSplitter->GetWindow1()); + CTileSelView& tsvc = dynamic_cast(wnd); + return tsvc; +} + +void wxBitEditView::OnActivateView(bool activate, ::wxView* activeView, ::wxView* deactiveView) +{ + wxASSERT(activeView == this); + if (!activate) + { + return; + } + // wx tries to activate this before it's ready + if (ready) + { + GetBitEditView().SetFocus(); + } +} + +bool wxBitEditView::OnClose(bool /*deleteWindow*/) +{ + /* doc's life determined by wxGbxProjView, not this, + so bypass wxView::OnClose() */ + return true; +} + +bool wxBitEditView::OnCreate(wxDocument* doc, long flags) +{ + if (!wxView::OnCreate(doc, flags)) + { + return false; + } + + new CBitEditFrame(CheckedDeref(doc), + *this, + CheckedDeref(GetMainFrame())); + /* wx tried to activate this before it was ready, + so do it now */ + ready = true; + Activate(true); + + return true; +} + +void wxBitEditView::OnUpdate(::wxView* sender, wxObject* hint /*= nullptr*/) +{ + CB::wxView::OnUpdate(sender, hint); + + CGmBoxHintWx& hint2 = dynamic_cast(CheckedDeref(hint)); + GetTileSelView().OnUpdate(nullptr, hint2.hint, hint2.hintObj); + GetBitEditView().OnUpdate(nullptr, hint2.hint, hint2.hintObj); } diff --git a/GM/FrmBited.h b/GM/FrmBited.h index 454ba83f..67075ef7 100644 --- a/GM/FrmBited.h +++ b/GM/FrmBited.h @@ -1,6 +1,6 @@ // FrmBited.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 @@ -22,22 +22,26 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +#include "VwBitedt.h" + class CTileSelView; +class wxBitEditView; ///////////////////////////////////////////////////////////////////////////// // CBitEditFrame frame -class CBitEditFrame : public CMDIChildWndEx, - public CB::wxNativeContainerWindowMixin +class CBitEditFrame : public wxDocChildFrameAny { - DECLARE_DYNCREATE(CBitEditFrame) protected: - CBitEditFrame(); // protected constructor used by dynamic creation + CBitEditFrame(wxDocument& doc, + wxBitEditView& view, + wxAuiMDIParentFrame& parent); // Attributes protected: - CSplitterWndEx m_wndSplitter; + RefPtr m_wndSplitter; +#if 0 // Operations public: @@ -51,18 +55,50 @@ class CBitEditFrame : public CMDIChildWndEx, // Generated message map functions //{{AFX_MSG(CBitEditFrame) afx_msg void OnClose(); - afx_msg void OnImageDiscard(); - afx_msg void OnImageUpdate(); - afx_msg void OnToolsResizeTile(); +#endif + void OnImageDiscard(wxCommandEvent& event); + void OnImageUpdate(wxCommandEvent& event); + void OnToolsResizeTile(wxCommandEvent& event); +#if 0 afx_msg void OnEditUndo(); afx_msg void OnUpdateEditUndo(CCmdUI* pCmdUI); - afx_msg BOOL OnRotateTile(UINT id); - afx_msg void OnUpdateRotateTile(CCmdUI* pCmdUI); - //}}AFX_MSG - DECLARE_MESSAGE_MAP() +#endif + void OnRotateTile(wxCommandEvent& event); + void OnUpdateRotateTile(wxUpdateUIEvent& pCmdUI); + void OnUpdateEnable(wxUpdateUIEvent& pCmdUI); + wxDECLARE_EVENT_TABLE(); private: + using BASE = wxDocChildFrameAny; + + CBitEditView& GetBitEditView(); CTileSelView& GetTileSelView(); + + friend class wxBitEditView; +}; + +class wxBitEditView : public CB::wxView +{ +public: + static wxBitEditView* New(CGamDoc& doc, TileID tid); + + CGamDoc& GetDocument(); + CBitEditFrame& GetFrame(); + CBitEditView& GetWindow() override { return GetBitEditView(); } + CBitEditView& GetBitEditView() { return GetFrame().GetBitEditView(); } + CTileSelView& GetTileSelView() { return GetFrame().GetTileSelView(); } + + void OnActivateView(bool activate, ::wxView* activeView, ::wxView* deactiveView) override; + bool OnClose(bool deleteWindow) override; + bool OnCreate(wxDocument* doc, long flags) override; + void OnUpdate(::wxView* sender, wxObject* hint = nullptr) override; + +private: + wxBitEditView() = default; + wxDECLARE_DYNAMIC_CLASS(wxBitEditView); + + // wx tries to activate this before it is ready + bool ready = false; }; ///////////////////////////////////////////////////////////////////////////// diff --git a/GM/FrmBxdoc.cpp b/GM/FrmBxdoc.cpp deleted file mode 100644 index 8363b744..00000000 --- a/GM/FrmBxdoc.cpp +++ /dev/null @@ -1,83 +0,0 @@ -// FrmBxdoc.cpp -// -// Copyright (c) 1994-2020 By Dale L. Larson, All Rights Reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -#include "stdafx.h" -#include "Gm.h" -#include "GmDoc.h" -#include "FrmBxdoc.h" -#include "VwPrjgbx.h" - -#ifdef _DEBUG -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#endif - -///////////////////////////////////////////////////////////////////////////// -// CDocFrame - -IMPLEMENT_DYNCREATE(CDocFrame, CMDIChildWndEx) - -CDocFrame::CDocFrame() : - CB::wxNativeContainerWindowMixin(static_cast(*this)) -{ -} - -CDocFrame::~CDocFrame() -{ -} - -BEGIN_MESSAGE_MAP(CDocFrame, CMDIChildWndEx) - //{{AFX_MSG_MAP(CDocFrame) - //}}AFX_MSG_MAP - ON_WM_CLOSE() -END_MESSAGE_MAP() - -///////////////////////////////////////////////////////////////////////////// -// CDocFrame message handlers - -BOOL CDocFrame::PreCreateWindow(CREATESTRUCT& cs) -{ - if (!CMDIChildWndEx::PreCreateWindow(cs)) - return FALSE; - - cs.style |= WS_CLIPCHILDREN; - cs.style &= ~(DWORD)FWS_ADDTOTITLE; - return TRUE; -} - -void CDocFrame::OnUpdateFrameTitle(BOOL bAddToTitle) -{ - CDocument* pDoc = GetActiveDocument(); - CB::string str = pDoc->GetTitle(); - str += " - "; - CB::string strType = CB::string::LoadString(IDS_PROJTYPE_GAMEBOX); - str += strType; - SetWindowText(str); -} - -void CDocFrame::OnClose() -{ - // Close the document when the main document window is closed. - GetActiveDocument()->OnCmdMsg(ID_FILE_CLOSE, CN_COMMAND, nullptr, nullptr); -} diff --git a/GM/FrmBxdoc.h b/GM/FrmBxdoc.h deleted file mode 100644 index e2cdbf6c..00000000 --- a/GM/FrmBxdoc.h +++ /dev/null @@ -1,61 +0,0 @@ -// FrmBxdoc.h -// -// Copyright (c) 1994-2020 By Dale L. Larson, All Rights Reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -#ifndef _FRMBXDOC_H -#define _FRMBXDOC_H - -///////////////////////////////////////////////////////////////////////////// -// CDocFrame frame - -class CDocFrame : public CMDIChildWndEx, - public CB::wxNativeContainerWindowMixin -{ - DECLARE_DYNCREATE(CDocFrame) -protected: - CDocFrame(); // protected constructor used by dynamic creation - BOOL PreCreateWindow(CREATESTRUCT& cs); - -// Attributes -public: - -// Operations -public: - -// Implementation -protected: - virtual ~CDocFrame(); - virtual void OnUpdateFrameTitle(BOOL bAddToTitle); - - // Generated message map functions - //{{AFX_MSG(CDocFrame) - afx_msg void OnSysCommand(UINT nID, LPARAM lParam); - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -public: - afx_msg void OnClose(); -}; - -#endif -///////////////////////////////////////////////////////////////////////////// - diff --git a/GM/FrmDockTile.cpp b/GM/FrmDockTile.cpp index 9446578b..65699a94 100644 --- a/GM/FrmDockTile.cpp +++ b/GM/FrmDockTile.cpp @@ -1,6 +1,6 @@ // FrmDockTile.cpp - container window for the tile palette. // -// 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 @@ -35,10 +35,10 @@ static char THIS_FILE[] = __FILE__; ///////////////////////////////////////////////////////////////////////////// -CDockTilePalette::CDockTilePalette() : - CB::wxNativeContainerWindowMixin(static_cast(*this)) +CDockTilePalette::CDockTilePalette() { m_pChildWnd = NULL; + SetSizer(new wxBoxSizer(wxVERTICAL)); } CDockTilePalette::~CDockTilePalette() @@ -52,11 +52,15 @@ void CDockTilePalette::SetChild(CTilePalette* pChildWnd) if (m_pChildWnd == pChildWnd) return; + InvalidateBestSize(); + wxAuiManager& auiMgr = CheckedDeref(wxAuiManager::GetManager(this)); + wxAuiPaneInfo& pane = auiMgr.GetPane(this); if (m_pChildWnd != NULL) { m_pChildWnd->Hide(); + GetSizer()->Detach(m_pChildWnd); m_pChildWnd->SetDockingFrame(NULL); - Invalidate(TRUE); + Refresh(TRUE); } // We need to set this field explicitly rather than // using CDockablePane::SetChild() since this function @@ -67,7 +71,23 @@ void CDockTilePalette::SetChild(CTilePalette* pChildWnd) { pChildWnd->SetDockingFrame(this); m_pChildWnd->Show(); + GetSizer()->Add(m_pChildWnd, 1, wxEXPAND); + Layout(); + SetMinClientSize(m_pChildWnd->GetMinSize()); + pane.BestSize(GetBestSize()). + MinSize(GetMinSize()); } else - GetMainFrame()->ShowPane(this, FALSE, TRUE, FALSE); + { + pane.Show(false); + } + auiMgr.Update(); +} + +wxSize CDockTilePalette::DoGetBestClientSize() const +{ + return m_pChildWnd ? + m_pChildWnd->GetBestSize() + : + wxPanel::DoGetBestClientSize(); } diff --git a/GM/FrmDockTile.h b/GM/FrmDockTile.h index 85012a53..c5156898 100644 --- a/GM/FrmDockTile.h +++ b/GM/FrmDockTile.h @@ -32,8 +32,7 @@ class CTilePalette; ///////////////////////////////////////////////////////////////////////////// // CDockTilePalette window -class CDockTilePalette : public CDockablePane, - public CB::wxNativeContainerWindowMixin +class CDockTilePalette : public wxPanel { // Construction public: @@ -49,6 +48,9 @@ class CDockTilePalette : public CDockablePane, // Implementation public: virtual ~CDockTilePalette(); + +protected: + wxSize DoGetBestClientSize() const override; }; #endif diff --git a/GM/FrmMain.cpp b/GM/FrmMain.cpp index 18b5efcd..47114e0e 100644 --- a/GM/FrmMain.cpp +++ b/GM/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-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 @@ -25,17 +25,16 @@ #include "stdafx.h" #include "Gm.h" #include "GmDoc.h" +#include "FrmBited.h" #include "FrmMain.h" #include "VwEdtbrd.h" -#include "VwBitedt.h" +#include "VwPrjgbx.h" #include "VwTilesl.h" #include "PalColor.h" #include "LibMfc.h" #include "HtmlHelp.h" -#include "afxpriv.h" // For WM_IDLEUPDATECMDUI - #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[] = __FILE__; @@ -44,39 +43,54 @@ static char THIS_FILE[] = __FILE__; /////////////////////////////////////////////////////////////////////// // CMainFrame -IMPLEMENT_DYNAMIC(CMainFrame, CMDIFrameWndExCb) - -BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWndExCb) +wxBEGIN_EVENT_TABLE(CMainFrame, wxDocParentFrameAny) +#if 0 ON_WM_CREATE() ON_WM_CLOSE() - ON_COMMAND(ID_WINDOW_TOOLPAL, OnWindowToolPal) - ON_COMMAND(ID_WINDOW_ITOOLPAL, OnWindowIToolPal) - ON_COMMAND(ID_WINDOW_COLORPAL, OnWindowColorPal) - ON_UPDATE_COMMAND_UI(ID_WINDOW_TOOLPAL, OnUpdateWindowToolPal) - ON_UPDATE_COMMAND_UI(ID_WINDOW_ITOOLPAL, OnUpdateWindowIToolPal) - ON_UPDATE_COMMAND_UI(ID_WINDOW_COLORPAL, OnUpdateWindowColorPal) - ON_UPDATE_COMMAND_UI(ID_EDIT_LAYER_BASE, OnUpdateDisable) +#endif + EVT_MENU(XRCID("ID_WINDOW_TOOLPAL"), OnWindowToolPal) + EVT_MENU(XRCID("ID_WINDOW_ITOOLPAL"), OnWindowIToolPal) + EVT_MENU(XRCID("ID_WINDOW_COLORPAL"), OnWindowColorPal) + EVT_UPDATE_UI(XRCID("ID_WINDOW_TOOLPAL"), OnUpdateWindowToolPal) + EVT_UPDATE_UI(XRCID("ID_WINDOW_ITOOLPAL"), OnUpdateWindowIToolPal) + EVT_UPDATE_UI(XRCID("ID_WINDOW_COLORPAL"), OnUpdateWindowColorPal) + EVT_UPDATE_UI(XRCID("ID_EDIT_LAYER_BASE"), OnUpdateDisable) +#if 0 ON_WM_HELPINFO() ON_COMMAND(ID_HELP_INDEX, OnHelpIndex) - ON_UPDATE_COMMAND_UI(ID_EDIT_LAYER_TILE, OnUpdateDisable) - ON_UPDATE_COMMAND_UI(ID_EDIT_LAYER_TOP, OnUpdateDisable) - ON_UPDATE_COMMAND_UI(ID_VIEW_GRIDLINES, OnUpdateDisable) - ON_UPDATE_COMMAND_UI(ID_TOOLS_BRDSNAPGRID, OnUpdateDisable) - ON_UPDATE_COMMAND_UI(ID_TOOLS_ROT90, OnUpdateDisable) - ON_UPDATE_COMMAND_UI(ID_ITOOL_PENCIL, OnUpdateDisable) - ON_UPDATE_COMMAND_UI(ID_TOOL_ARROW, OnUpdateDisable) - ON_COMMAND(ID_WINDOW_TILEPAL, OnWindowTilePalette) - ON_UPDATE_COMMAND_UI(ID_WINDOW_TILEPAL, OnUpdateWindowTilePalette) - ON_COMMAND(IDW_COLOR_PALETTE, OnToggleColorPalette) - ON_COMMAND(IDW_TILE_PALETTE, OnToggleTilePalette) +#endif + EVT_UPDATE_UI(XRCID("ID_EDIT_LAYER_TILE"), OnUpdateDisable) + EVT_UPDATE_UI(XRCID("ID_EDIT_LAYER_TOP"), OnUpdateDisable) + EVT_UPDATE_UI(XRCID("ID_VIEW_GRIDLINES"), OnUpdateDisable) + EVT_UPDATE_UI(XRCID("ID_TOOLS_BRDSNAPGRID"), OnUpdateDisable) + EVT_UPDATE_UI(XRCID("ID_TOOLS_ROT90"), OnUpdateDisable) + EVT_UPDATE_UI(XRCID("ID_ITOOL_PENCIL"), OnUpdateDisable) + EVT_UPDATE_UI(XRCID("ID_TOOL_ARROW"), OnUpdateDisable) + EVT_MENU(XRCID("ID_WINDOW_TILEPAL"), OnWindowTilePalette) + EVT_UPDATE_UI(XRCID("ID_WINDOW_TILEPAL"), OnUpdateWindowTilePalette) + EVT_MENU(XRCID("IDW_COLOR_PALETTE"), OnToggleColorPalette) + EVT_MENU(XRCID("IDW_TILE_PALETTE"), OnToggleTilePalette) +#if 0 ON_COMMAND(ID_HELP_FINDER, CMDIFrameWndEx::OnHelpFinder) ON_COMMAND(ID_HELP, CMDIFrameWndEx::OnHelp) ON_COMMAND(ID_CONTEXT_HELP, CMDIFrameWndEx::OnContextHelp) -END_MESSAGE_MAP() - -static UINT indicators[] = +#endif + EVT_MENU(XRCID("ID_WINDOW_TILE_HORZ"), OnTile) + EVT_MENU(XRCID("ID_WINDOW_TILE_VERT"), OnTile) + EVT_UPDATE_UI(XRCID("ID_WINDOW_TILE_HORZ"), OnUpdateTile) + EVT_UPDATE_UI(XRCID("ID_WINDOW_TILE_VERT"), OnUpdateTile) + EVT_AUI_PANE_CLOSE(OnPaneClose) + EVT_UPDATE_UI(wxID_EXIT, OnUpdateEnable) + EVT_UPDATE_UI_RANGE(wxID_FILE1, wxID_FILE9, OnUpdateEnable) + EVT_MENU(XRCID("ID_VIEW_STATUS_BAR"), OnViewStatusBar) + EVT_UPDATE_UI(XRCID("ID_VIEW_STATUS_BAR"), OnUpdateViewStatusBar) +wxEND_EVENT_TABLE() + +static const int indicators[] = { - ID_SEPARATOR, // status line indicator + value_preserving_cast(wxID_SEPARATOR), // status line indicator + /* N.B.: do not use XRCID with these because they are + also string identifiers in .rc */ ID_INDICATOR_CAPS, ID_INDICATOR_NUM, ID_INDICATOR_CELLNUM, @@ -92,13 +106,13 @@ static UINT toolbars[] = /////////////////////////////////////////////////////////////////////// // These are used to qualify palette visiblility... -static const CRuntimeClass *tblColor[] = { - RUNTIME_CLASS(CBrdEditViewContainer), - RUNTIME_CLASS(CBitEditViewContainer), - RUNTIME_CLASS(CTileSelViewContainer), NULL }; +static const wxClassInfo *tblColor[] = { + wxCLASSINFO(wxBrdEditView), + wxCLASSINFO(wxBitEditView), + NULL }; -static const CRuntimeClass *tblBrd[] = { - RUNTIME_CLASS(CBrdEditViewContainer), +static const wxClassInfo *tblBrd[] = { + wxCLASSINFO(wxBrdEditView), NULL }; @@ -106,16 +120,142 @@ static const CRuntimeClass *tblBrd[] = { // CMainFrame construction/destruction CMainFrame::CMainFrame() : - CB::wxNativeContainerWindowMixin(static_cast(*this)) + wxDocParentFrameAny(wxDocManager::GetDocumentManager(), + nullptr, wxID_ANY, + wxTheApp->GetAppDisplayName()) { + auiManager.SetManagedWindow(this); + SetIcon(wxIcon(std::format("#{}", IDR_MAINFRAME))); + GetClientWindow()->SetWindowStyleFlag( + GetClientWindow()->GetWindowStyleFlag() | + wxAUI_NB_WINDOWLIST_BUTTON); m_bColorPalOn = TRUE; m_bTilePalOn = TRUE; + + wxMenuBar& menubar = CheckedDeref(wxXmlResource::Get()->LoadMenuBar(this, "IDR_MAINFRAME"_cbstring)); + // mru File menu + wxMenu& menuFile = CheckedDeref(menubar.GetMenu(size_t(0))); + wxDocManager& docMgr = CheckedDeref(wxDocManager::GetDocumentManager()); + docMgr.FileHistoryUseMenu(&menuFile); + docMgr.FileHistoryAddFilesToMenu(&menuFile); + + /* KLUDGE: wx wants to construct Window menu itself, so we + can't put Split commands in .xrc */ + wxMenu& wndMenu = CheckedDeref(GetWindowMenu()); + static const struct + { + int xrcId; + CB::string menuString; + int helpId; + wxItemKind kind; + } windowMenuArgs[] = { + { wxID_SEPARATOR }, + { XRCID("ID_WINDOW_TILE_HORZ"), "Split Tabs &Horizontally"_cbstring, ID_WINDOW_TILE_HORZ, wxITEM_NORMAL }, + { XRCID("ID_WINDOW_TILE_VERT"), "Split Tabs &Vertically"_cbstring, ID_WINDOW_TILE_VERT, wxITEM_NORMAL }, + { wxID_SEPARATOR }, + { XRCID("ID_WINDOW_TOOLPAL"), "T&ool Palette"_cbstring, ID_WINDOW_TOOLPAL, wxITEM_CHECK }, + { XRCID("ID_WINDOW_COLORPAL"), "Co&lor Palette"_cbstring, ID_WINDOW_TOOLPAL, wxITEM_CHECK }, + { XRCID("ID_WINDOW_TILEPAL"), "T&ile Palette"_cbstring, ID_WINDOW_TOOLPAL, wxITEM_CHECK }, + { XRCID("ID_WINDOW_ITOOLPAL"), "I&mage Palette"_cbstring, ID_WINDOW_TOOLPAL, wxITEM_CHECK }, + }; + for (const auto& arg : windowMenuArgs) + { + if (arg.xrcId != wxID_SEPARATOR) + { + CB::string str = CB::string::LoadString(arg.helpId); + std::vector tokens; + wxStringTokenizer tokenizer(str, "\n"); + while (tokenizer.HasMoreTokens()) + { + tokens.push_back(tokenizer.GetNextToken()); + } + wxASSERT(!tokens.empty()); + wndMenu.Append(arg.xrcId, arg.menuString, tokens.front(), arg.kind); + } + else + { + wndMenu.AppendSeparator(); + } + } + + // Build the main window tool bar. + static const CB::ToolArgs standardArgs[] = { + { wxID_NEW, ID_FILE_NEW }, + { wxID_OPEN, ID_FILE_OPEN }, + { wxID_SAVE, ID_FILE_SAVE }, + { wxID_SEPARATOR }, + { wxID_CUT, ID_EDIT_CUT }, + { wxID_COPY, ID_EDIT_COPY }, + { wxID_PASTE, ID_EDIT_PASTE }, + { wxID_SEPARATOR }, + { XRCID("ID_WINDOW_TILEPAL"), ID_WINDOW_TILEPAL, wxITEM_CHECK }, + { XRCID("ID_WINDOW_TOOLPAL"), ID_WINDOW_TOOLPAL, wxITEM_CHECK }, + { XRCID("ID_WINDOW_COLORPAL"), ID_WINDOW_COLORPAL, wxITEM_CHECK }, + { XRCID("ID_WINDOW_ITOOLPAL"), ID_WINDOW_ITOOLPAL, wxITEM_CHECK }, + { wxID_SEPARATOR }, + { XRCID("ID_VIEW_TOGGLE_SCALE"), ID_VIEW_TOGGLE_SCALE }, + { wxID_SEPARATOR }, + { XRCID("ID_EDIT_LAYER_BASE"), ID_EDIT_LAYER_BASE, wxITEM_CHECK }, + { XRCID("ID_EDIT_LAYER_TILE"), ID_EDIT_LAYER_TILE, wxITEM_CHECK }, + { XRCID("ID_EDIT_LAYER_TOP"), ID_EDIT_LAYER_TOP, wxITEM_CHECK }, + { wxID_SEPARATOR }, + { XRCID("ID_VIEW_GRIDLINES"), ID_VIEW_GRIDLINES, wxITEM_CHECK }, + { XRCID("ID_TOOLS_BRDSNAPGRID"), ID_TOOLS_BRDSNAPGRID, wxITEM_CHECK }, + { wxID_SEPARATOR }, + { XRCID("ID_DWG_TOFRONT"), ID_DWG_TOFRONT }, + { XRCID("ID_DWG_TOBACK"), ID_DWG_TOBACK }, + { wxID_SEPARATOR }, + { wxID_HELP_CONTEXT, ID_CONTEXT_HELP }, + }; + m_wndToolBar = &CB::CreateToolbar(*this, + standardArgs, + IDR_MAINFRAME); + auiManager.AddPane(m_wndToolBar, wxAuiPaneInfo(). + Name("IDR_MAINFRAME"_cbstring).Caption("Standard"_cbstring). + ToolbarPane().Top().Layer(0)); + + m_wndToolPal = &CBrdEditView::CreateToolbar(*this); + auiManager.AddPane(m_wndToolPal, wxAuiPaneInfo(). + Name("IDB_DRAWLAYERTOOLS"_cbstring).Caption("Board Tools"_cbstring). + ToolbarPane().Right().Layer(1)); + + m_wndIToolPal = &CBitEditView::CreateToolbar(*this); + auiManager.AddPane(m_wndIToolPal, wxAuiPaneInfo(). + Name("IDB_IMAGETOOLS").Caption("Tile Tools"_cbstring). + ToolbarPane().Right().Layer(2)); + + m_wndStatusBar = nullptr; + wxCommandEvent dummy; + OnViewStatusBar(dummy); + + m_wndColorPal = new CColorPalette; + m_wndColorPal->Create(this); + auiManager.AddPane(m_wndColorPal, wxAuiPaneInfo(). + Name("CColorPalette").Caption("Colors"_cbstring). + MinSize(m_wndColorPal->GetBestSize()). + BestSize(m_wndColorPal->GetBestSize()). + MaxSize(m_wndColorPal->GetBestSize()). + Right().Layer(0).Position(0). + Hide()); + + m_wndTilePal = new CDockTilePalette; + m_wndTilePal->Create(this); + auiManager.AddPane(m_wndTilePal, wxAuiPaneInfo(). + Name("CTilePalette").Caption("Tiles"_cbstring). + BestSize(m_wndTilePal->GetBestSize()). + Right().Layer(0).Position(1). + Hide()); + + // default width doesn't leave enough space for color palette + SetClientSize(4*m_wndColorPal->GetBestSize().x, GetClientSize().y); + auiManager.Update(); } CMainFrame::~CMainFrame() { } +#if 0 int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CMDIFrameWndEx::OnCreate(lpCreateStruct) == -1) @@ -246,28 +386,18 @@ void CMainFrame::OnHelpIndex() { GetApp()->DoHelpContents(); } +#endif /////////////////////////////////////////////////////////////////////// -CDocument* CMainFrame::GetCurrentDocument() +wxDocument* CMainFrame::GetCurrentDocument() { - CMDIChildWndEx* pMDIChild = (CMDIChildWndEx*)MDIGetActive(); - if (pMDIChild != NULL) - { - CView *pView = pMDIChild->GetActiveView(); - ASSERT(pView != NULL); - ASSERT(pView->IsKindOf(RUNTIME_CLASS(CView))); - return pView->GetDocument(); - } - return NULL; + return GetDocumentManager()->GetCurrentDocument(); } -CView* CMainFrame::GetActiveView() const +wxView* CMainFrame::GetActiveView() const { - CMDIChildWndEx* pMDIChild = (CMDIChildWndEx*)MDIGetActive(); - if (pMDIChild != NULL) - return pMDIChild->GetActiveView(); - return NULL; + return GetDocumentManager()->GetCurrentView(); } /////////////////////////////////////////////////////////////////////// @@ -283,6 +413,7 @@ static const CB::string szEntryStatusBar = "StatusBar"; void CMainFrame::SaveProfileSettings() { +#if 0 SaveBarState(szSectControlBars); GetApp()->WriteProfileInt(szSectSettings, szEntryColorPal, m_bColorPalOn); @@ -290,10 +421,14 @@ void CMainFrame::SaveProfileSettings() GetApp()->WriteProfileInt(szSectSettings, szEntryStatusBar, (m_wndStatusBar.GetStyle() & WS_VISIBLE) ? 1 : 0); +#else + AfxThrowNotSupportedException(); +#endif } void CMainFrame::RestoreProfileSettings() { +#if 0 // Note: I only send a message to turn off the tool and status bars // since MFC sets them on by default. if (!GetApp()->GetProfileInt(szSectSettings, szEntryStatusBar, 1)) @@ -301,6 +436,14 @@ void CMainFrame::RestoreProfileSettings() m_bColorPalOn = GetApp()->GetProfileInt(szSectSettings, szEntryColorPal, TRUE); m_bTilePalOn = GetApp()->GetProfileInt(szSectSettings, szEntryTilePal, TRUE); +#else + AfxThrowNotSupportedException(); +#endif +} + +void CMainFrame::OnUpdateEnable(wxUpdateUIEvent& pCmdUI) +{ + pCmdUI.Enable(true); } /////////////////////////////////////////////////////////////////////// @@ -309,21 +452,19 @@ void CMainFrame::RestoreProfileSettings() // do you mean 'we'? Is there anyone else here?) simply disable // the 'items'. -void CMainFrame::OnUpdateDisable(CCmdUI* pCmdUI) +void CMainFrame::OnUpdateDisable(wxUpdateUIEvent& pCmdUI) { - if (pCmdUI->m_pSubMenu != NULL) + if (pCmdUI.IsCheckable()) { - // Need to handle menu that the submenu is connected to. - pCmdUI->m_pMenu->EnableMenuItem(pCmdUI->m_nIndex, - MF_BYPOSITION | MF_DISABLED | MF_GRAYED); + pCmdUI.Check(false); } - pCmdUI->SetCheck(0); - pCmdUI->Enable(0); + pCmdUI.Enable(false); } /////////////////////////////////////////////////////////////////////// // CMainFrame diagnostics +#if 0 #ifdef _DEBUG void CMainFrame::AssertValid() const { @@ -335,46 +476,78 @@ void CMainFrame::Dump(CDumpContext& dc) const CMDIFrameWndEx::Dump(dc); } #endif //_DEBUG +#endif /////////////////////////////////////////////////////////////////////// // System color palette message handlers -void CMainFrame::OnToggleColorPalette() +void CMainFrame::OnToggleColorPalette(wxCommandEvent& /*event*/) { - SendMessage(WM_COMMAND, ID_WINDOW_COLORPAL); + wxCommandEvent event(wxEVT_MENU, XRCID("ID_WINDOW_COLORPAL")); + ProcessWindowEvent(event); } -void CMainFrame::OnToggleTilePalette() +void CMainFrame::OnToggleTilePalette(wxCommandEvent& /*event*/) { - SendMessage(WM_COMMAND, ID_WINDOW_TILEPAL); + wxCommandEvent event(wxEVT_MENU, XRCID("ID_WINDOW_TILEPAL")); + ProcessWindowEvent(event); +} + +void CMainFrame::OnTile(wxCommandEvent& event) +{ + Tile(event.GetId() == XRCID("ID_WINDOW_TILE_HORZ") ? wxHORIZONTAL : wxVERTICAL); +} + +void CMainFrame::OnUpdateTile(wxUpdateUIEvent& pCmdUI) +{ + pCmdUI.Enable(GetClientWindow()->GetPageCount() >= 2); +} + +void CMainFrame::OnViewStatusBar(wxCommandEvent& event) +{ + if (!m_wndStatusBar) + { + m_wndStatusBar = &CreateStatusBar(indicators); + } + else + { + SetStatusBar(nullptr); + delete m_wndStatusBar; + m_wndStatusBar = nullptr; + } +} + +void CMainFrame::OnUpdateViewStatusBar(wxUpdateUIEvent& pCmdUI) +{ + pCmdUI.Enable(true); + pCmdUI.Check(m_wndStatusBar); } /////////////////////////////////////////////////////////////////////// // pRtc points to a NULL terminated list of CRuntimeClass pointers // specifying qualifying active views for the specified palette. -void CMainFrame::UpdatePaletteWindow(CWnd& pWnd, const CRuntimeClass** pRtc, BOOL bIsOn) +void CMainFrame::UpdatePaletteWindow(wxWindow& pWnd, const wxClassInfo** pRtc, BOOL bIsOn) { - if (pWnd.m_hWnd != NULL) // Handle exists if palette allowed + if (pWnd.GetHandle()) // Handle exists if palette allowed { - BOOL bIsControlBar = pWnd.IsKindOf(RUNTIME_CLASS(CBasePane)); - BOOL bVisible = ((pWnd.GetStyle() & WS_VISIBLE) != 0); + wxAuiPaneInfo& pane = auiManager.GetPane(&pWnd); + BOOL bVisible = pane.IsShown(); - CMDIChildWndEx* pMDIChild = (CMDIChildWndEx*)MDIGetActive(); - if (pMDIChild == NULL || pMDIChild->IsIconic()) + wxView* pView = GetDocumentManager()->GetCurrentView(); + if (!pView) { - if (!bIsControlBar && bVisible) - pWnd.ShowWindow(SW_HIDE); - else if (bIsControlBar && bVisible) - ShowPane((CBasePane*)&pWnd, FALSE, FALSE, FALSE); + if (bVisible) + { + pane.Show(false); + auiMgrScheduleUpdate = true; + } } else { - CView *pView = pMDIChild->GetActiveView(); - ASSERT(pView != NULL); - wxASSERT(typeid(*pView) != typeid(CTileSelView) && - typeid(*pView) != typeid(CTileSelViewContainer) && - typeid(*pView) != typeid(CBitEditView)); + wxASSERT(typeid(*pView) == typeid(wxBitEditView) || + typeid(*pView) == typeid(wxBrdEditView) || + typeid(*pView) == typeid(wxGbxProjView)); while (*pRtc != NULL) { @@ -382,44 +555,39 @@ void CMainFrame::UpdatePaletteWindow(CWnd& pWnd, const CRuntimeClass** pRtc, BOO { if (bIsOn && !bVisible) { - if (!bIsControlBar) - pWnd.ShowWindow(SW_SHOW); - else - ShowPane((CBasePane*)&pWnd, TRUE, FALSE, FALSE); + pane.Show(true); + auiMgrScheduleUpdate = true; } else if (!bIsOn && bVisible) { - if (!bIsControlBar) - pWnd.ShowWindow(SW_HIDE); - else - ShowPane((CBasePane*)&pWnd, FALSE, FALSE, FALSE); + pane.Show(false); + auiMgrScheduleUpdate = true; } return; } pRtc++; } - if (!bIsControlBar && bVisible) - pWnd.ShowWindow(SW_HIDE); - else if (bIsControlBar && bVisible) - ShowPane((CBasePane*)&pWnd, FALSE, FALSE, FALSE); + if (bVisible) + { + pane.Show(false); + auiMgrScheduleUpdate = true; + } } } } /////////////////////////////////////////////////////////////////////// -BOOL CMainFrame::IsQualifyingView(CWnd& pWnd, const CRuntimeClass** pRtc) +BOOL CMainFrame::IsQualifyingView(wxWindow& pWnd, const wxClassInfo** pRtc) { - if (pWnd.m_hWnd != NULL) // Handle exists if palette allowed + if (pWnd.GetHandle()) // Handle exists if palette allowed { - CMDIChildWndEx* pMDIChild = (CMDIChildWndEx*)MDIGetActive(); - if (pMDIChild != NULL) + wxView* pView = GetDocumentManager()->GetCurrentView(); + if (pView) { - CView *pView = pMDIChild->GetActiveView(); - ASSERT(pView != NULL); - wxASSERT(typeid(*pView) != typeid(CTileSelView) && - typeid(*pView) != typeid(CTileSelViewContainer) && - typeid(*pView) != typeid(CBitEditView)); + wxASSERT(typeid(*pView) == typeid(wxBitEditView) || + typeid(*pView) == typeid(wxBrdEditView) || + typeid(*pView) == typeid(wxGbxProjView)); while (*pRtc != NULL) { @@ -436,92 +604,115 @@ BOOL CMainFrame::IsQualifyingView(CWnd& pWnd, const CRuntimeClass** pRtc) void CMainFrame::OnIdle() { - if (IsIconic()) // No window palette processing if app minimized + if (IsIconized()) // No window palette processing if app minimized return; - UpdatePaletteWindow(m_wndColorPal, tblColor, m_bColorPalOn); + UpdatePaletteWindow(*m_wndColorPal, tblColor, m_bColorPalOn); + wxAuiPaneInfo& pane = auiManager.GetPane(m_wndTilePal); if (GetCurrentDocument() == NULL) - ShowPane(&m_wndTilePal, FALSE, FALSE, TRUE); - - if (m_wndColorPal.m_hWnd != NULL && m_wndColorPal.IsWindowVisible()) - m_wndColorPal.SendMessage(WM_IDLEUPDATECMDUI, (WPARAM)TRUE); -} - -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) + pane.Show(false); + auiMgrScheduleUpdate = true; + } + else + { + wxSize newSize = m_wndTilePal->GetBestSize(); + if (pane.best_size != newSize) { - wxCommandEvent event(WM_PALETTE_HIDE_WX); - wxWnd->GetEventHandler()->ProcessEventLocally(event); - CB::SendEventToDescendants(*wxWnd, event, true); + pane.BestSize(newSize); + auiMgrScheduleUpdate = true; } - return true; + } + + if (m_wndColorPal->GetHandle() && m_wndColorPal->IsShownOnScreen()) + { + wxCommandEvent event(wxEVT_MENU, XRCID("WM_IDLEUPDATECMDUI")); + m_wndColorPal->ProcessWindowEvent(event); + } + + if (auiMgrScheduleUpdate) + { + auiMgrScheduleUpdate = false; + auiManager.Update(); } } -BOOL CMainFrame::OnCloseMiniFrame(CPaneFrameWnd* pWnd) -{ - return OnClosePalette(CheckedDeref(pWnd)); +namespace { + void OnClosePalette(wxWindow& wxWnd) + { + wxCommandEvent event(WM_PALETTE_HIDE_WX); + // for color palette + wxWnd.GetEventHandler()->ProcessEventLocally(event); + // for tile palette + CB::SendEventToDescendants(wxWnd, event, true); + } } -BOOL CMainFrame::OnCloseDockingPane(CDockablePane* pWnd) +void CMainFrame::OnPaneClose(wxAuiManagerEvent& event) { - return OnClosePalette(CheckedDeref(pWnd)); + wxAuiPaneInfo& pane = CheckedDeref(event.GetPane()); + if (pane.name == "CColorPalette" || + pane.name == "CTilePalette") + { + OnClosePalette(CheckedDeref(pane.window)); + } + else + { + event.Skip(); + } } ///////////////////////////////////////////////////////////////// -void CMainFrame::OnWindowToolPal() +void CMainFrame::OnWindowToolPal(wxCommandEvent& /*event*/) { - ShowPane(&m_wndToolPal, (m_wndToolPal.GetStyle() & WS_VISIBLE) == 0, FALSE, TRUE); + wxAuiPaneInfo& pane = auiManager.GetPane(m_wndToolPal); + pane.Show(!pane.IsShown()); + auiManager.Update(); } -void CMainFrame::OnUpdateWindowToolPal(CCmdUI* pCmdUI) +void CMainFrame::OnUpdateWindowToolPal(wxUpdateUIEvent& pCmdUI) { - pCmdUI->SetCheck((m_wndToolPal.GetStyle() & WS_VISIBLE) != 0); + pCmdUI.Check(m_wndToolPal->IsShownOnScreen()); } ///////////////////////////////////////////////////////////////// -void CMainFrame::OnWindowIToolPal() +void CMainFrame::OnWindowIToolPal(wxCommandEvent& /*event*/) { - ShowPane(&m_wndIToolPal, (m_wndIToolPal.GetStyle() & WS_VISIBLE) == 0, FALSE, TRUE); + wxAuiPaneInfo& pane = auiManager.GetPane(m_wndIToolPal); + pane.Show(!pane.IsShown()); + auiManager.Update(); } -void CMainFrame::OnUpdateWindowIToolPal(CCmdUI* pCmdUI) +void CMainFrame::OnUpdateWindowIToolPal(wxUpdateUIEvent& pCmdUI) { - pCmdUI->SetCheck((m_wndIToolPal.GetStyle() & WS_VISIBLE) != 0); + pCmdUI.Check(m_wndIToolPal->IsShownOnScreen()); } ///////////////////////////////////////////////////////////////// -void CMainFrame::OnWindowColorPal() +void CMainFrame::OnWindowColorPal(wxCommandEvent& /*event*/) { m_bColorPalOn = !m_bColorPalOn; } -void CMainFrame::OnUpdateWindowColorPal(CCmdUI* pCmdUI) +void CMainFrame::OnUpdateWindowColorPal(wxUpdateUIEvent& pCmdUI) { - pCmdUI->SetCheck(m_bColorPalOn); - pCmdUI->Enable(IsQualifyingView(m_wndColorPal, tblColor)); + pCmdUI.Check(m_bColorPalOn); + pCmdUI.Enable(IsQualifyingView(*m_wndColorPal, tblColor)); } ///////////////////////////////////////////////////////////////// -void CMainFrame::OnWindowTilePalette() +void CMainFrame::OnWindowTilePalette(wxCommandEvent& /*event*/) { m_bTilePalOn = !m_bTilePalOn; } -void CMainFrame::OnUpdateWindowTilePalette(CCmdUI* pCmdUI) +void CMainFrame::OnUpdateWindowTilePalette(wxUpdateUIEvent& pCmdUI) { - pCmdUI->SetCheck(m_bTilePalOn); - pCmdUI->Enable(IsQualifyingView(m_wndTilePal, tblBrd)); + pCmdUI.Check(m_bTilePalOn); + pCmdUI.Enable(IsQualifyingView(*m_wndTilePal, tblBrd)); } diff --git a/GM/FrmMain.h b/GM/FrmMain.h index 0a14c20f..7d3c5035 100644 --- a/GM/FrmMain.h +++ b/GM/FrmMain.h @@ -1,6 +1,6 @@ // FrmMain.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 @@ -42,20 +42,18 @@ #include "frmdocktile.h" #endif -class CMainFrame : public CMDIFrameWndExCb, - public CB::wxNativeContainerWindowMixin +class CMainFrame : public wxDocParentFrameAny { - DECLARE_DYNAMIC(CMainFrame) public: CMainFrame(); // Attributes public: - CDocument* GetCurrentDocument(); + wxDocument* GetCurrentDocument(); - CView* GetActiveView() const; + wxView* GetActiveView() const; - CDockTilePalette& GetDockingTileWindow() { return m_wndTilePal; } + CDockTilePalette& GetDockingTileWindow() { return CheckedDeref(m_wndTilePal); } BOOL IsTilePaletteOn() { return m_bTilePalOn; } @@ -67,51 +65,78 @@ class CMainFrame : public CMDIFrameWndExCb, // Implementation public: void OnIdle(); - BOOL OnCloseMiniFrame(CPaneFrameWnd* pWnd) override; - BOOL OnCloseDockingPane(CDockablePane* pWnd) override; + void OnPaneClose(wxAuiManagerEvent& event); virtual ~CMainFrame(); +#if 0 #ifdef _DEBUG - virtual void AssertValid() const; - virtual void Dump(CDumpContext& dc) const; + void AssertValid() const override; + void Dump(CDumpContext& dc) const override; #endif - void UpdatePaletteWindow(CWnd& pWnd, const CRuntimeClass** pRtc, BOOL IsOn); - BOOL IsQualifyingView(CWnd& pWnd, const CRuntimeClass** pRtc); +#endif + void UpdatePaletteWindow(wxWindow& pWnd, const wxClassInfo** pRtc, BOOL IsOn); + BOOL IsQualifyingView(wxWindow& pWnd, const wxClassInfo** pRtc); protected: // control bar embedded members +#if 0 CMFCMenuBar m_wndMenuBar; // Main menu - CMFCToolBar m_wndToolBar; // Main toolbar - CMFCToolBar m_wndToolPal; // Button tool palette for board draw - CMFCToolBar m_wndIToolPal; // Button tool palette for image edit - CDockColorPalette m_wndColorPal; // Color tool palette window - CDockTilePalette m_wndTilePal; // Container window for tile palette - CMFCStatusBar m_wndStatusBar; // Status bar at window bottom +#endif + wxAuiToolBar* m_wndToolBar; // Main toolbar + wxAuiToolBar* m_wndToolPal; // Button tool palette for board draw + wxAuiToolBar* m_wndIToolPal; // Button tool palette for image edit + CColorPalette* m_wndColorPal; // Color tool palette window + CDockTilePalette* m_wndTilePal; // Container window for tile palette + CB::wxStatusBar* m_wndStatusBar; // Status bar at window bottom BOOL m_bColorPalOn; BOOL m_bTilePalOn; // Generated message map functions protected: +#if 0 void WinHelp(DWORD_PTR dwData, UINT nCmd) override; +#endif +#if 0 afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); afx_msg void OnClose(); - afx_msg void OnWindowToolPal(); - afx_msg void OnWindowIToolPal(); - afx_msg void OnWindowColorPal(); - afx_msg void OnUpdateWindowToolPal(CCmdUI* pCmdUI); - afx_msg void OnUpdateWindowIToolPal(CCmdUI* pCmdUI); - afx_msg void OnUpdateWindowColorPal(CCmdUI* pCmdUI); - afx_msg void OnUpdateDisable(CCmdUI* pCmdUI); +#endif + void OnWindowToolPal(wxCommandEvent& event); + void OnWindowIToolPal(wxCommandEvent& event); + void OnWindowColorPal(wxCommandEvent& event); + void OnUpdateWindowToolPal(wxUpdateUIEvent& pCmdUI); + void OnUpdateWindowIToolPal(wxUpdateUIEvent& pCmdUI); + void OnUpdateWindowColorPal(wxUpdateUIEvent& pCmdUI); + void OnUpdateEnable(wxUpdateUIEvent& pCmdUI); + void OnUpdateDisable(wxUpdateUIEvent& pCmdUI); +#if 0 afx_msg BOOL OnHelpInfo(HELPINFO* pHelpInfo); afx_msg void OnHelpIndex(); - afx_msg void OnWindowTilePalette(); - afx_msg void OnUpdateWindowTilePalette(CCmdUI* pCmdUI); - afx_msg void OnToggleColorPalette(); - afx_msg void OnToggleTilePalette(); - - DECLARE_MESSAGE_MAP() +#endif + void OnWindowTilePalette(wxCommandEvent& event); + void OnUpdateWindowTilePalette(wxUpdateUIEvent& pCmdUI); + void OnToggleColorPalette(wxCommandEvent& event); + void OnToggleTilePalette(wxCommandEvent& event); + void OnTile(wxCommandEvent& event); + void OnUpdateTile(wxUpdateUIEvent& pCmdUI); + void OnViewStatusBar(wxCommandEvent& event); + void OnUpdateViewStatusBar(wxUpdateUIEvent& pCmdUI); + + wxDECLARE_EVENT_TABLE(); + +private: + wxAuiManager auiManager; + /* performing all idle updates as a single transaction + improves AUI's sizing choices */ + bool auiMgrScheduleUpdate = false; }; +inline CMainFrame* GetMainFrame() +{ + // KLUDGE: wx may return non-mainframe during shutdown + wxWindow* w = CB::pGetMainWndWx(); + return w ? dynamic_cast(w) : nullptr; +} + #endif diff --git a/GM/FrmView.cpp b/GM/FrmView.cpp deleted file mode 100644 index 37bb8ff3..00000000 --- a/GM/FrmView.cpp +++ /dev/null @@ -1,77 +0,0 @@ -// FrmView.cpp -// -// Copyright (c) 1994-2020 By Dale L. Larson, All Rights Reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -#include "stdafx.h" -#include "Gm.h" -#include "FrmView.h" - -#ifdef _DEBUG -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#endif - -///////////////////////////////////////////////////////////////////////////// -// CViewFrame - -IMPLEMENT_DYNCREATE(CViewFrame, CMDIChildWndEx) - -CViewFrame::CViewFrame() : - CB::wxNativeContainerWindowMixin(static_cast(*this)) -{ -} - -CViewFrame::~CViewFrame() -{ -} - -BEGIN_MESSAGE_MAP(CViewFrame, CMDIChildWndEx) - //{{AFX_MSG_MAP(CViewFrame) - ON_WM_CLOSE() - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - -///////////////////////////////////////////////////////////////////////////// - -BOOL CViewFrame::PreCreateWindow(CREATESTRUCT& cs) -{ - if (!CMDIChildWndEx::PreCreateWindow(cs)) - return FALSE; - - cs.lpszClass = AfxRegisterWndClass(CS_DBLCLKS, - AfxGetApp()->LoadStandardCursor(IDC_ARROW), - (HBRUSH)GetStockObject(LTGRAY_BRUSH), - AfxGetApp()->LoadIconW(IDR_BOARDVIEW)); - - cs.style |= WS_CLIPCHILDREN; - cs.style &= ~(DWORD)FWS_ADDTOTITLE; - return TRUE; -} - -///////////////////////////////////////////////////////////////////////////// -// CViewFrame message handlers - -void CViewFrame::OnClose() -{ - CWnd::OnClose(); // Short circuit frame's doc close code -} diff --git a/GM/FrmView.h b/GM/FrmView.h deleted file mode 100644 index 97acdd13..00000000 --- a/GM/FrmView.h +++ /dev/null @@ -1,57 +0,0 @@ -// FrmView.h -// -// Copyright (c) 1994-2020 By Dale L. Larson, All Rights Reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -#ifndef _FRMVIEW_H -#define _FRMVIEW_H - -///////////////////////////////////////////////////////////////////////////// -// CViewFrame frame - -class CViewFrame : public CMDIChildWndEx, - public CB::wxNativeContainerWindowMixin -{ - DECLARE_DYNCREATE(CViewFrame) -protected: - CViewFrame(); // protected constructor used by dynamic creation - BOOL PreCreateWindow(CREATESTRUCT& cs); - -// Attributes -public: - -// Operations -public: - -// Implementation -protected: - virtual ~CViewFrame(); - - // Generated message map functions - //{{AFX_MSG(CViewFrame) - afx_msg void OnClose(); - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; -#endif -///////////////////////////////////////////////////////////////////////////// - diff --git a/GM/Gm.cpp b/GM/Gm.cpp index 32dec772..dec67269 100644 --- a/GM/Gm.cpp +++ b/GM/Gm.cpp @@ -1,6 +1,6 @@ // Gm.cpp : Defines the class behaviors for the application. // -// 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 @@ -29,8 +29,6 @@ #include "GmDoc.h" #include "FrmMain.h" -#include "FrmView.h" -#include "FrmBxdoc.h" #include "FrmBited.h" #include "VwEdtbrd.h" #include "VwBitedt.h" @@ -231,16 +229,19 @@ static void DeletePrintKeys(const CB::string& szFileClass); ///////////////////////////////////////////////////////////////////////////// // CGmApp -BEGIN_MESSAGE_MAP(CGmApp, CWinAppEx) - //{{AFX_MSG_MAP(CGmApp) - ON_COMMAND(ID_APP_ABOUT, OnAppAbout) - ON_COMMAND(ID_HELP_WEBSITE, OnHelpWebsite) - ON_COMMAND(ID_HELP_RELEASES, OnHelpReleases) - //}}AFX_MSG_MAP +wxBEGIN_EVENT_TABLE(wxCGmApp, wxAppWithMFC) + EVT_MENU(wxID_ABOUT, OnAppAbout) + EVT_MENU(XRCID("ID_HELP_WEBSITE"), OnHelpWebsite) + EVT_MENU(XRCID("ID_HELP_RELEASES"), OnHelpReleases) + EVT_UPDATE_UI(wxID_ABOUT, OnUpdateEnable) + EVT_UPDATE_UI(XRCID("ID_HELP_WEBSITE"), OnUpdateEnable) + EVT_UPDATE_UI(XRCID("ID_HELP_RELEASES"), OnUpdateEnable) +#if 0 // Standard file based document commands ON_COMMAND(ID_FILE_NEW, CWinAppEx::OnFileNew) ON_COMMAND(ID_FILE_OPEN, CWinAppEx::OnFileOpen) -END_MESSAGE_MAP() +#endif +wxEND_EVENT_TABLE() ///////////////////////////////////////////////////////////////////////////// @@ -268,8 +269,6 @@ CGmApp::CGmApp() m_dwHtmlHelpCookie = 0; m_bDisableHtmlHelp = FALSE; m_hHtmlProcessHandle = NULL; - m_pMapViewTmpl = NULL; - m_pTileEditTmpl = NULL; } ///////////////////////////////////////////////////////////////////////////// @@ -278,6 +277,7 @@ CGmApp::CGmApp() class CGmApp::CwxGmApp : public wxMFCApp { protected: +#if 0 BOOL InitMainWnd() override { // Create main MDI Frame window @@ -304,6 +304,7 @@ class CGmApp::CwxGmApp : public wxMFCApp return TRUE; } +#endif }; CGmApp& CGmApp::Get() @@ -318,23 +319,106 @@ CWinApp& CbGetApp() return CGmApp::Get(); } -namespace { - class wxCGmApp : public wxAppWithMFC - { - public: - virtual bool OnInit() override - { - // handling cmd line w/ MFC, so skip wxCmdLineParser +bool wxCGmApp::OnInit() +{ + // handling cmd line w/ MFC, so skip wxCmdLineParser + + wxXmlResource::Get()->InitAllHandlers(); + wxCHECK(wxXmlResource::Get()->LoadFile(wxStandardPaths::Get().GetDataDir() + "/CBDesign.xrc"), false); + + // Fill in the application information fields before creating wxConfig. + SetVendorName("CyberBoardPBEM"); + SetAppName("CBDesign"); + SetAppDisplayName(CB::GetAppName()); + static OwnerPtr docManager = MakeOwner(); + new wxDocTemplate(&*docManager, "CyberBoard GameBox", "*.gbx", "", "gbx", + "CGamDoc", "wxGbxProjView", + CLASSINFO(CGamDoc), CLASSINFO(wxGbxProjView)); + new wxDocTemplate(&*docManager, "CyberBoard GameBox", "*.gbx", "", "gbx", + "CGamDoc", "wxBrdEditView", + CLASSINFO(CGamDoc), CLASSINFO(wxBrdEditView), + wxTEMPLATE_INVISIBLE); + new wxDocTemplate(&*docManager, "CyberBoard GameBox", "*.gbx", "", "gbx", + "CGamDoc", "wxTileEditView", + CLASSINFO(CGamDoc), CLASSINFO(wxBitEditView), + wxTEMPLATE_INVISIBLE); + wxDocManager& docMgr = CheckedDeref(wxDocManager::GetDocumentManager()); + docMgr.FileHistoryLoad(*wxConfig::Get()); + + CMainFrame& pMainFrame = *new CMainFrame; + wxTheApp->SetTopWindow(&pMainFrame); + pMainFrame.Show(); + + return true; +} - wxXmlResource::Get()->InitAllHandlers(); - wxCHECK(wxXmlResource::Get()->LoadFile(wxStandardPaths::Get().GetDataDir() + "/CBDesign.xrc"), false); +int wxCGmApp::OnExit() +{ + wxDocManager& docMgr = CheckedDeref(wxDocManager::GetDocumentManager()); + docMgr.FileHistorySave(*wxConfig::Get()); - static OwnerPtr docManager = MakeOwner(); + return wxAppWithMFC::OnExit(); +} - return true; +/* for safety, and to approximate MFC, + disable toolbar/menu commands that aren't + explicitly enabled */ +bool wxCGmApp::TryAfter(wxEvent& event) +{ + 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); + wxAuiToolBar* toolbar = dynamic_cast(pCmdUI.GetEventObject()); + wxMenu* menu = dynamic_cast(pCmdUI.GetEventObject()); + wxMenuItem* item = menu ? menu->FindItem(pCmdUI.GetId()) : nullptr; + wxMenu* submenu = item ? item->GetSubMenu() : nullptr; + if ((toolbar && pCmdUI.GetId() != toolbar->GetId()) || + // a submenu isn't a command, so don't disable it + (menu && !submenu)) + { + /* if xrcid is empty, then id is something + wx-internal (e.g., wxAUI_BUTTON_WINDOWLIST), + so don't interfere with it */ + wxString xrcid = wxXmlResource::FindXRCIDById(pCmdUI.GetId()); + if (!xrcid.empty()) + { + if (pCmdUI.IsCheckable()) + { + pCmdUI.Check(false); + } + pCmdUI.Enable(false); + return true; + } + } + // but a submenu with all items disabled should be disabled + else if (menu && submenu) + { + CallAfter([item, submenu]() + { + for (size_t i = size_t(0) ; i < submenu->GetMenuItemCount() ; ++i) + { + wxMenuItem* curr = submenu->FindItemByPosition(i); + if (curr->IsEnabled()) + { + return; + } + } + item->Enable(false); + }); } - }; + } + + return false; } + wxDECLARE_APP(wxCGmApp); // Notice use of wxIMPLEMENT_APP_NO_MAIN() instead of the usual wxIMPLEMENT_APP! wxIMPLEMENT_APP_NO_MAIN(wxCGmApp); @@ -398,26 +482,13 @@ BOOL CGmApp::InitInstance() } } - // Register the application's document templates. Document templates - // serve as the connection between documents, frame windows and views. - AddDocTemplate(new CMultiDocTemplate(IDR_GAMEBOX, - RUNTIME_CLASS(CGamDocMfc), - RUNTIME_CLASS(CDocFrame), - RUNTIME_CLASS(CGbxProjViewContainer))); - - m_pMapViewTmpl = new CMultiDocTemplate(IDR_BOARDVIEW, - RUNTIME_CLASS(CGamDocMfc), RUNTIME_CLASS(CViewFrame), - RUNTIME_CLASS(CBrdEditViewContainer)); - - m_pTileEditTmpl = new CMultiDocTemplate(IDR_BITEDITOR, - RUNTIME_CLASS(CGamDocMfc), RUNTIME_CLASS(CBitEditFrame), - RUNTIME_CLASS(CBitEditViewContainer)); - EnableLoadWindowPlacement(FALSE); +#if 0 // Enable DDE Execute open EnableShellOpen(); RegisterShellFileTypes(TRUE); +#endif // Remove the ShellNew key since we don't support it... AfxRegDeleteKey(HKEY_CLASSES_ROOT, szGbxShellNew); @@ -468,8 +539,6 @@ int CGmApp::ExitInstance() CWinAppEx::ExitInstance(); - if (m_pMapViewTmpl != NULL) delete m_pMapViewTmpl; - if (m_pTileEditTmpl != NULL) delete m_pTileEditTmpl; return 0; } @@ -566,9 +635,13 @@ BOOL CGmApp::DispatchMessages() { if (msg.message == WM_QUIT) { +#if 0 if (GetMainFrame() != NULL && ::IsWindow(GetMainFrame()->GetSafeHwnd())) GetMainFrame()->PostMessage(WM_QUIT, 0, 0); return TRUE; // Inform caller the WM_QUIT was queued +#else + AfxThrowNotSupportedException(); +#endif } if (!PreTranslateMessage(&msg)) { @@ -610,35 +683,30 @@ BOOL CGmApp::OnIdle(LONG lCount) // as when a context menu is visible. Therefore we also // cause the quit message to be reposted so the message // pump will exit. - if (GetMainFrame() == NULL) + CMainFrame* mainWnd = GetMainFrame(); + if (mainWnd == NULL) { PostQuitMessage(0); return TRUE; } // Inform all open documents of idle condition. - CDocument* pCurDoc = GetMainFrame()->GetCurrentDocument(); - - POSITION pos = m_pDocManager->GetFirstDocTemplatePosition(); + wxDocManager& docMgr = CheckedDeref(wxDocManager::GetDocumentManager()); + wxDocument* pCurDoc = docMgr.GetCurrentDocument(); - BOOL bAppVisible = m_pMainWnd->IsWindowVisible() && - !m_pMainWnd->IsIconic(); + BOOL bAppVisible = mainWnd->IsShown() && + !mainWnd->IsIconized(); - while (pos != NULL) + wxList& docs = docMgr.GetDocuments(); + for (auto it = docs.begin() ; it != docs.end() ; ++it) { - CDocTemplate* pTemplate = - (CDocTemplate*)m_pDocManager->GetNextDocTemplate(pos); - POSITION pos2 = pTemplate->GetFirstDocPosition(); - while (pos2) - { - CGamDoc* pDoc = CB::ToCGamDoc(pTemplate->GetNextDoc(pos2)); - wxASSERT(pDoc != NULL); - pDoc->OnIdle(bAppVisible && pDoc == CB::ToCGamDoc(pCurDoc)); + CGamDoc* pDoc = dynamic_cast(*it); + wxASSERT(pDoc != NULL); + pDoc->OnIdle(bAppVisible && pDoc == pCurDoc); - } } // Main idle processing... - ((CMainFrame*)m_pMainWnd)->OnIdle(); + mainWnd->OnIdle(); // Finally MFC idle processing... return CWinAppEx::OnIdle(lCount); } @@ -646,98 +714,89 @@ BOOL CGmApp::OnIdle(LONG lCount) ///////////////////////////////////////////////////////////////////////////// // CAboutDlg dialog used for App About -class CAboutDlg : public CDialog +class CAboutDlg : public wxDialog { public: - CAboutDlg(); + CAboutDlg(wxWindow* parent = &CB::GetMainWndWx()); // Dialog Data - //{{AFX_DATA(CAboutDlg) - enum { IDD = IDD_GM_ABOUTBOX }; - CStatic m_staticGenDate; - CStatic m_staticProgVer; - CStatic m_staticFileVer; - //}}AFX_DATA - -// Implementation -protected: - virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support - //{{AFX_MSG(CAboutDlg) - virtual BOOL OnInitDialog(); - //}}AFX_MSG - DECLARE_MESSAGE_MAP() +private: + CB_XRC_BEGIN_CTRLS_DECL() + RefPtr m_staticGenDate; + RefPtr m_staticProgVer; + RefPtr m_staticFileVer; + RefPtr m_bitmap1; + RefPtr m_bitmap2; + CB_XRC_END_CTRLS_DECL() + + bool TransferDataToWindow() override; }; -CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) -{ - //{{AFX_DATA_INIT(CAboutDlg) - //}}AFX_DATA_INIT -} - -void CAboutDlg::DoDataExchange(CDataExchange* pDX) +CAboutDlg::CAboutDlg(wxWindow* parent /*= &CB::GetMainWndWx()*/) : + CB_XRC_BEGIN_CTRLS_DEFN(parent, CAboutDlg) + CB_XRC_CTRL(m_staticGenDate) + CB_XRC_CTRL(m_staticProgVer) + CB_XRC_CTRL(m_staticFileVer) + CB_XRC_CTRL(m_bitmap1) + CB_XRC_CTRL(m_bitmap2) + CB_XRC_END_CTRLS_DEFN() { - CDialog::DoDataExchange(pDX); - //{{AFX_DATA_MAP(CAboutDlg) - DDX_Control(pDX, IDC_D_ABOUT_GENDATE, m_staticGenDate); - DDX_Control(pDX, IDC_D_ABOUT_VERSION, m_staticProgVer); - DDX_Control(pDX, IDC_D_ABOUT_FILEVER, m_staticFileVer); - //}}AFX_DATA_MAP + m_bitmap1->SetIcon(wxIcon(std::format("#{}", IDR_MAINFRAME))); + m_bitmap2->SetIcon(wxIcon(std::format("#{}", IDR_MAINFRAME))); } -BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) - //{{AFX_MSG_MAP(CAboutDlg) - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - // App command to run the dialog -void CGmApp::OnAppAbout() +void wxCGmApp::OnAppAbout(wxCommandEvent& WXUNUSED(event)) { CAboutDlg aboutDlg; - aboutDlg.DoModal(); + aboutDlg.ShowModal(); } #ifdef _DEBUG static const CB::string szGenDate = __DATE__; #endif -BOOL CAboutDlg::OnInitDialog() +bool CAboutDlg::TransferDataToWindow() { - CDialog::OnInitDialog(); - CB::string str = CB::string::Format(IDP_PROGVER, progVerMajor, progVerMinor); - m_staticProgVer.SetWindowText(str); + m_staticProgVer->SetLabel(str); str = CB::string::Format(IDP_FILEVER, fileGbxVerMajor, fileGbxVerMinor); - m_staticFileVer.SetWindowText(str); + m_staticFileVer->SetLabel(str); #ifdef _DEBUG - m_staticGenDate.SetWindowText(szGenDate); + m_staticGenDate->SetLabel(szGenDate); #else - m_staticGenDate.ShowWindow(SW_HIDE); + m_staticGenDate->Hide(); #endif - CenterWindow(); + Centre(); - return TRUE; // return TRUE unless you set the focus to a control + return wxDialog::TransferDataToWindow(); } ///////////////////////////////////////////////////////////////////////////// // CGmApp commands -void CGmApp::OnHelpWebsite() +void wxCGmApp::OnHelpWebsite(wxCommandEvent& WXUNUSED(event)) { CB::string strUrl = CB::string::LoadString(IDS_URL_CB_WEBSITE); ShellExecute(NULL, "open"_cbstring, strUrl, NULL, NULL, SW_SHOWNORMAL); } -void CGmApp::OnHelpReleases() +void wxCGmApp::OnHelpReleases(wxCommandEvent& WXUNUSED(event)) { CB::string strUrl = CB::string::LoadString(IDS_URL_CB_RELEASES); ShellExecute(NULL, "open"_cbstring, strUrl, NULL, NULL, SW_SHOWNORMAL); } -wxNativeContainerWindow& CB::GetMainWndWx() +void wxCGmApp::OnUpdateEnable(wxUpdateUIEvent& pCmdUI) +{ + pCmdUI.Enable(true); +} + +wxWindow* CB::pGetMainWndWx() { - return *dynamic_cast(AfxGetMainWnd()); + return wxTheApp->GetTopWindow(); } CB::string CB::GetAppName() diff --git a/GM/Gm.h b/GM/Gm.h index 68794d0f..9ef645ab 100644 --- a/GM/Gm.h +++ b/GM/Gm.h @@ -1,6 +1,6 @@ // Gm.h : main header file for the GM 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 @@ -155,9 +155,6 @@ class CGmApp : public CWinAppEx HANDLE m_hHtmlProcessHandle; UINT m_nAppLook; - CMultiDocTemplate* m_pMapViewTmpl; - CMultiDocTemplate* m_pTileEditTmpl; - // Operations public: void DoHelpShellLaunch(); @@ -175,21 +172,31 @@ class CGmApp : public CWinAppEx virtual BOOL InitInstance(); virtual int ExitInstance(); virtual BOOL OnIdle(LONG lCount); +}; + +class wxCGmApp : public wxAppWithMFC +{ +public: + bool OnInit() override; + int OnExit() override; + +protected: + /* for safety, and to approximate MFC, + disable toolbar/menu commands that aren't + explicitly enabled */ + bool TryAfter(wxEvent& event) override; +private: // Implementation - //{{AFX_MSG(CGmApp) - afx_msg void OnAppAbout(); - afx_msg void OnHelpWebsite(); - afx_msg void OnHelpReleases(); - //}}AFX_MSG - DECLARE_MESSAGE_MAP() + void OnAppAbout(wxCommandEvent& event); + void OnHelpWebsite(wxCommandEvent& event); + void OnHelpReleases(wxCommandEvent& event); + void OnUpdateEnable(wxUpdateUIEvent& pCmdUI); + wxDECLARE_EVENT_TABLE(); }; -class CMainFrame; - inline CGmApp* GetApp() { return (CGmApp*)AfxGetApp(); } -inline CMainFrame* GetMainFrame() { return (CMainFrame*)(GetApp()->m_pMainWnd); } ///////////////////////////////////////////////////////////////////////////// diff --git a/GM/GmDoc.cpp b/GM/GmDoc.cpp index 9f9f8b49..7bae56ce 100644 --- a/GM/GmDoc.cpp +++ b/GM/GmDoc.cpp @@ -1,6 +1,6 @@ // GmDoc.cpp : implementation of the CGamDoc class // -// 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 @@ -44,6 +44,7 @@ #include "Marks.h" #include "FrmMain.h" +#include "FrmBited.h" #include "VwTilesl.h" #include "VwEdtbrd.h" @@ -68,7 +69,7 @@ Features CGamDoc::c_fileFeatures; static char THIS_FILE[] = __FILE__; #endif -IMPLEMENT_DYNCREATE(CGamDocMfc, CDocument) +wxIMPLEMENT_DYNAMIC_CLASS(CGamDoc, wxDocument); IMPLEMENT_DYNCREATE(CGmBoxHint, CObject) #ifdef _DEBUG @@ -119,8 +120,8 @@ wxEND_EVENT_TABLE() /////////////////////////////////////////////////////////////////////// -CGamDoc::CGamDoc(CGamDocMfc& md) : - mfcDoc(&md) +CGamDoc::CGamDoc() : + mfcDoc(new CGamDocMfc(*this)) { m_pBMgr = NULL; m_pTMgr = NULL; @@ -152,8 +153,8 @@ CGamDoc::CGamDoc(CGamDocMfc& md) : ///////////////////////////////////////////////////////////////////////////// -static const CRuntimeClass *tblBrd[] = { - RUNTIME_CLASS(CBrdEditViewContainer), +static const wxClassInfo *tblBrd[] = { + wxCLASSINFO(wxBrdEditView), NULL }; @@ -170,10 +171,44 @@ void CGamDoc::OnIdle(BOOL bActive) ///////////////////////////////////////////////////////////////////////////// +/* whichever UpdateAllViews() is used, + pass it also to other version, + but don't infinitely recurse */ void CGamDoc::UpdateAllViews(CView* pSender, LPARAM lHint, CObject* pHint) { - CPP20_TRACE("{}({}, {}, {})\n", __func__, static_cast(pSender), lHint, static_cast(pHint)); - WORD wHint = LOWORD(lHint); + // avoid recursion due to wx and mfc UpdateAllViews() + static wxRecursionGuardFlag s_flag; + wxRecursionGuard guard(s_flag); + if (guard.IsInside()) + { + // don't allow reentrancy + return; + } + + mfcDoc->CDocument::UpdateAllViews(pSender, lHint, pHint); + CGmBoxHint* hint = dynamic_cast(pHint); + wxASSERT(!pHint || hint); // pHint --> hint + UpdateAllViews(nullptr, CGmBoxHintWx(lHint, hint)); +} + +// wxWidgets +void CGamDoc::UpdateAllViews(wxView* sender /*= nullptr*/, wxObject* hint /*= nullptr*/) +{ + // avoid recursion due to wx and mfc UpdateAllViews() + static wxRecursionGuardFlag s_flag; + wxRecursionGuard guard(s_flag); + if (guard.IsInside()) + { + // don't allow reentrancy + return; + } + + wxDocument::UpdateAllViews(sender, hint); + + CGmBoxHintWx* cbhint = dynamic_cast(hint); + wxASSERT(!hint || cbhint); // hint --> cbhint + WORD wHint = static_cast(cbhint ? cbhint->hint : HINT_ALWAYSUPDATE); + CObject* mfcHintObject = cbhint ? cbhint->hintObj : nullptr; if ( ((wHint & HINT_TILEGROUP) && !(wHint & ~HINT_TILEGROUP)) || wHint == HINT_TILESETDELETED || @@ -181,13 +216,27 @@ void CGamDoc::UpdateAllViews(CView* pSender, LPARAM lHint, CObject* pHint) wHint == HINT_ALWAYSUPDATE ) m_palTile->UpdatePaletteContents(); - mfcDoc->CDocument::UpdateAllViews(pSender, lHint, pHint); + UpdateAllViews(nullptr, wHint, mfcHintObject); } -// wxWidgets -void CGamDoc::UpdateAllViews(wxView* sender /*= nullptr*/, wxObject* hint /*= nullptr*/) +// give bit editor chance to update doc before doc closes +bool CGamDoc::OnSaveModified() { - CPP20_TRACE("{}({}, {})\n", __func__, static_cast(sender), static_cast(hint)); + if (++saveMods != 1) + { + // avoid double-query (save/discard) on closing app w/ open bit editor + return true; + } + + // Make sure tile edits are saved. + UpdateAllViews(nullptr, CGmBoxHintWx(HINT_FORCETILEUPDATE)); + + bool retval = wxDocument::OnSaveModified(); + if (!retval) + { + saveMods = 0; + } + return retval; } /////////////////////////////////////////////////////////////////////// @@ -196,12 +245,47 @@ bool CGamDoc::OnNewDocument() { if (!mfcDoc->CDocument::OnNewDocument()) return FALSE; - return SetupBlankBoard(); + if (!wxDocument::OnNewDocument()) + { + return false; + } + bool retval = SetupBlankBoard(); + if (retval) + { + // success, so tell views that doc is ready + UpdateAllViews(nullptr, CGmBoxHintWx(HINT_DOCREADY)); + } + return retval; } bool CGamDoc::OnOpenDocument(const wxString& lpszPathName) { - BOOL bOK = wxDocument::OnOpenDocument(lpszPathName); + // on success, tell views that doc is ready + class Retval + { + public: + Retval(CGamDoc& d) : doc(d) {} + ~Retval() + { + if (retval) + { + doc.UpdateAllViews(nullptr, CGmBoxHintWx(HINT_DOCREADY)); + } + } + operator bool&() { return retval; } + bool& operator=(bool b) + { + bool& rc = *this; + rc = b; + return rc; + } + private: + CGamDoc& doc; + bool retval = false; + }; + + Retval bOK(*this); + bOK = wxDocument::OnOpenDocument(lpszPathName); // If the game loaded OK, check if it's password protected. if (bOK) { @@ -217,12 +301,12 @@ bool CGamDoc::OnOpenDocument(const wxString& lpszPathName) { bfr = ComputeGameboxPasskey(dlg.m_strPassword); if (bfr == m_abytePass) - return TRUE; + return (bOK = TRUE); AfxMessageBox(IDS_ERR_BAD_PASSWORD); } else AfxMessageBox(IDS_ERR_NEED_PASSWORD); - return FALSE; + return (bOK = FALSE); } return bOK; } @@ -253,7 +337,7 @@ bool CGamDoc::OnSaveDocument(const wxString& pszPathName) return wxDocument::OnSaveDocument(pszPathName); } -bool CGamDoc::DeleteContents() +CGamDoc::~CGamDoc() { m_pTMgr = NULL; m_pBMgr = NULL; @@ -273,7 +357,7 @@ bool CGamDoc::DeleteContents() CColorPalette::CustomColorsClear(m_pCustomColors); mfcDoc->CDocument::DeleteContents(); - return wxDocument::DeleteContents(); + wxDocument::DeleteContents(); } // wxDocument @@ -303,29 +387,6 @@ void CGamDoc::SetCustomColors(const std::vector& pCustColors) SetModifiedFlag(); } -/////////////////////////////////////////////////////////////////////// -// Support for new unique views on this document - -BOOL CGamDoc::CreateNewFrame(CDocTemplate& pTemplate, const CB::string& pszTitle, - LPVOID lpvCreateParam) -{ - CMDIChildWndEx* pNewFrame - = static_cast(pTemplate.CreateNewFrame(*this, NULL)); - if (pNewFrame == NULL) - return FALSE; // Not created - wxASSERT(pNewFrame->IsKindOf(RUNTIME_CLASS(CMDIChildWndEx))); - CB::string str = GetUserReadableName(); - str += " - "; - str += pszTitle; - pNewFrame->SetWindowText(str); - m_lpvCreateParam = lpvCreateParam; - pTemplate.InitialUpdateFrame(pNewFrame, *this); - // KLUDGE: work around https://github.com/CyberBoardPBEM/cbwindows/issues/23 - GetMainFrame()->RedrawWindow(NULL, NULL, RDW_ALLCHILDREN | RDW_INVALIDATE); - m_lpvCreateParam = NULL; - return TRUE; -} - /////////////////////////////////////////////////////////////////////// // Returns TRUE if views may have been affected @@ -389,31 +450,35 @@ DWORD CGamDoc::IssueGameBoxID() /////////////////////////////////////////////////////////////////////// -CView* CGamDoc::FindTileEditorView(TileID tid) const +wxBitEditView* CGamDoc::FindTileEditorView(TileID tid) const { - POSITION pos = mfcDoc->GetFirstViewPosition(); - while (pos != NULL) + const wxList& views = GetViews(); + for (auto it = views.begin() ; it != views.end() ; ++it) { - CTileSelViewContainer* pView = static_cast(mfcDoc->GetNextView(pos)); - if (pView->IsKindOf(RUNTIME_CLASS(CTileSelViewContainer))) + wxBitEditView* pView = dynamic_cast(*it); + if (pView) { - if (pView->GetChild().GetTileID() == tid) + if (pView->GetTileSelView().GetTileID() == tid) + { return pView; + } } } return NULL; } -CView* CGamDoc::FindBoardEditorView(const CBoard& pBoard) const +wxBrdEditView* CGamDoc::FindBoardEditorView(const CBoard& pBoard) const { - POSITION pos = mfcDoc->GetFirstViewPosition(); - while (pos != NULL) + const wxList& views = GetViews(); + for (auto it = views.begin() ; it != views.end() ; ++it) { - CBrdEditViewContainer* pView = static_cast(mfcDoc->GetNextView(pos)); - if (pView->IsKindOf(RUNTIME_CLASS(CBrdEditViewContainer))) + wxBrdEditView* pView = dynamic_cast(*it); + if (pView) { - if (&pView->GetChild().GetBoard() == &pBoard) + if (&pView->GetWindow().GetBoard() == &pBoard) + { return pView; + } } } return NULL; diff --git a/GM/GmDoc.h b/GM/GmDoc.h index f93b6e1c..65277318 100644 --- a/GM/GmDoc.h +++ b/GM/GmDoc.h @@ -1,6 +1,6 @@ // GmDoc.h : interface of the CGamDoc class // -// 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 @@ -84,6 +84,7 @@ enum CGamDocHint HINT_MARKERSETPROPCHANGE=0x23, HINT_FORCETILEUPDATE = 0x40, // Used before a save is done + HINT_DOCREADY = 0x80, // Used when safe to create CGbxProjView HINT_UPDATEPROJVIEW = 0x0100, // Used to reload prject window @@ -178,12 +179,31 @@ class CGmBoxHint : public CObject } }; +class CGmBoxHintWx : public wxObject +{ +public: + CGmBoxHintWx(LPARAM h, CGmBoxHint* hObj = nullptr) : + hint(static_cast(h)), + hintObj(hObj) + { + } + /* KLUDGE: Temporary objects are const, but UpdateAllViews() + requires a non-const wxObject. The const_cast + isn't fully safe, but I don't expect + UpdateAllViews() to modify the hint. */ + operator wxObject*() const { return const_cast(this); } + const CGamDocHint hint; + CGmBoxHint* const hintObj; +}; + ////////////////////////////////////////////////////////////////////// class CDib; class CPieceManager; class CMarkManager; class CGamDocMfc; +class wxBitEditView; +class wxBrdEditView; class CGamDoc : public wxDocument { @@ -198,10 +218,8 @@ class CGamDoc : public wxDocument private: friend class CGbxProjView; - CGamDoc(CGamDocMfc& md); -#if 0 - DECLARE_DYNCREATE(CGamDoc) -#endif + CGamDoc(); + wxDECLARE_DYNAMIC_CLASS(CGamDoc); // Class Global Attributes public: @@ -238,26 +256,18 @@ class CGamDoc : public wxDocument void IncrMajorRevLevel(); static DWORD IssueGameBoxID(); - // If you need to pass a pointer to the views to be created, - // bracket the view can call the GetCreateParameter() method. - // It is only valid during the InitialUpdate() method. - LPVOID GetCreateParameter() const { return m_lpvCreateParam; } - // Operations public: BOOL SetupBlankBoard(); - BOOL CreateNewFrame(CDocTemplate& pTemplate, const CB::string& pszTitle, - LPVOID lpvCreateParam = NULL); - BOOL NotifyTileDatabaseChange(BOOL bPurgeScan = TRUE); BOOL PurgeMissingTileIDs(); BOOL QueryTileInUse(TileID tid) const; BOOL QueryAnyOfTheseTilesInUse(const std::vector& tbl) const; TileID CreateTileFromDib(const CDib& pDib, size_t nTSet); - CView* FindTileEditorView(TileID tid) const; - CView* FindBoardEditorView(const CBoard& pBoard) const; + wxBitEditView* FindTileEditorView(TileID tid) const; + wxBrdEditView* FindBoardEditorView(const CBoard& pBoard) const; // Support for strings associated with game elements (pieces, markers) CB::string GetGameElementString(GameElement gelem) const; @@ -292,12 +302,10 @@ class CGamDoc : public wxDocument void UpdateAllViews(CView* pSender, LPARAM lHint = 0L, CObject* pHint = NULL); - // wxWidgets - // lifetime is controlled by MFC (not wx), so override: - // Called after a view is added or removed. The default implementation - // deletes the document if this is there are no more views. - void OnChangedViewList() override {} + // wxDocument void UpdateAllViews(wxView* sender = nullptr, wxObject* hint = nullptr) override; + // give bit editor chance to update doc before doc closes + bool OnSaveModified() override; // Implementation protected: @@ -335,10 +343,8 @@ class CGamDoc : public wxDocument }; CB::propagate_const> m_palTile; // Tile palette child window is in document - LPVOID m_lpvCreateParam; // Used to pass parameters to new views - public: - virtual ~CGamDoc() = default; + ~CGamDoc() override; void Serialize(CArchive& ar); #ifdef _DEBUG void AssertValid() const; @@ -349,7 +355,6 @@ class CGamDoc : public wxDocument bool OnNewDocument() override; bool OnOpenDocument(const wxString& lpszPathName) override; bool OnSaveDocument(const wxString& lpszPathName) override; - bool DeleteContents() override; // wxDocument // Called by OnSaveDocument and OnOpenDocument to implement standard @@ -381,7 +386,8 @@ class CGamDoc : public wxDocument void OnExportGamebox(wxCommandEvent& event); private: - RefPtr mfcDoc; + OwnerPtr mfcDoc; + unsigned saveMods = 0; friend CGamDocMfc; }; @@ -395,9 +401,9 @@ class CGamDocMfc : public CDocument operator CGamDoc*() { return &*wxDoc; } protected: - CGamDocMfc() = default; + CGamDocMfc(CGamDoc& wd) : wxDoc(&wd) {} +public: ~CGamDocMfc() override = default; - DECLARE_DYNCREATE(CGamDocMfc) public: // Forced override of this (note not virtual) @@ -424,7 +430,9 @@ class CGamDocMfc : public CDocument { CB_VERIFY(wxDoc->DeleteContents()); } private: - OwnerPtr wxDoc = new CGamDoc(*this); + RefPtr wxDoc; + + friend CGamDoc; }; inline const CGamDoc* CB::ToCGamDoc(const CDocument* p) diff --git a/GM/PalColor.cpp b/GM/PalColor.cpp index 7fff10ce..4f0888c8 100644 --- a/GM/PalColor.cpp +++ b/GM/PalColor.cpp @@ -1,6 +1,6 @@ // ColorPal.cpp : implementation file // -// 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 @@ -46,6 +46,8 @@ static char THIS_FILE[] = __FILE__; #define new DEBUG_NEW #endif +wxDEFINE_EVENT(cbEVT_UPDATE_UI_COLOR, CColorCmdUI); + ///////////////////////////////////////////////////////////////////////////// static const CB::string szColorPalDefPos = "140 350"; @@ -136,17 +138,12 @@ inline wxColour& CellColor(wxColour* pCref, int nCol, int nRow) ///////////////////////////////////////////////////////////////////////////// -BEGIN_MESSAGE_MAP(CDockColorPalette, CDockablePane) - ON_WM_CREATE() - ON_MESSAGE(WM_IDLEUPDATECMDUI, OnIdleUpdateCmdUI) - ON_WM_SIZE() -END_MESSAGE_MAP() - wxBEGIN_EVENT_TABLE(CColorPalette, wxPanel) EVT_PAINT(OnPaint) EVT_WINDOW_CREATE(OnCreate) EVT_LEFT_DOWN(OnLButtonDown) EVT_RIGHT_DOWN(OnRButtonDown) + EVT_UPDATE_UI(wxID_ANY, OnUpdateCmdUI) EVT_CHOICE(XRCID("IDC_W_COLORPAL_LINEWIDTH"), OnLineWidthCbnSelchange) #if 0 ON_WM_HELPINFO() @@ -159,17 +156,9 @@ wxBEGIN_EVENT_TABLE(CColorPalette, wxPanel) EVT_COMMAND(wxID_ANY, WM_PALETTE_HIDE_WX, OnPaletteHide) wxEND_EVENT_TABLE() -IMPLEMENT_DYNCREATE(CDockColorPalette, CDockablePane); - ///////////////////////////////////////////////////////////////////////////// // CColorPalette -CDockColorPalette::CDockColorPalette() : - CB::wxNativeContainerWindowMixin(static_cast(*this)), - m_child(new CColorPalette) -{ -} - CColorPalette::CColorPalette() : m_comboLine(new wxChoice) { @@ -190,29 +179,6 @@ CColorPalette::CColorPalette() : m_pCustColors = CustomColorsAllocate(); } -void CDockColorPalette::CalculateMinClientSize(CSize& size) -{ - wxSize temp; - m_child->CalculateMinClientSize(temp); - size = CB::Convert(temp); -} - -int CDockColorPalette::OnCreate(LPCREATESTRUCT lpCreateStruct) -{ - if (CDockablePane::OnCreate(lpCreateStruct) == -1) - return -1; - - if (!m_child->Create(*this, - wxID_ANY, - wxPoint(0, 0), wxSize(100, 100))) - { - TRACE0("Failed to create color palette window\n"); - return -1; // fail to create - } - - return 0; -} - void CColorPalette::OnCreate(wxWindowCreateEvent& event) { if (event.GetWindow() != this) @@ -234,15 +200,6 @@ void CColorPalette::OnCreate(wxWindowCreateEvent& event) SetupToolTips(m_sizeClient.x); } -CSize CDockColorPalette::CalcFixedLayout(BOOL bStretch, BOOL bHorz) -{ - CRect rctInside(0, 0, 0, 0); - CalcInsideRect(rctInside, TRUE); - CSize sizeInside(rctInside.Size()); - return CSize(CB::Convert(m_child->GetSize()) - sizeInside); - // return CDockablePane::CalcFixedLayout(bStretch, bHorz); -} - ///////////////////////////////////////////////////////////////////////////// // Tool tip processing... @@ -327,25 +284,6 @@ void CColorPalette::ComputeLayout() ///////////////////////////////////////////////////////////////////////////// -LRESULT CDockColorPalette::OnIdleUpdateCmdUI(WPARAM wParam, LPARAM) -{ - if (IsVisible()) // Ignore if child is invisible - { - CFrameWnd* pTarget = GetMainFrame(); - if (pTarget != NULL) - OnUpdateCmdUI(pTarget, (BOOL)wParam); - } - return 0L; -} - -void CDockColorPalette::OnSize(UINT nType, int cx, int cy) -{ - m_child->SetSize(0, 0, cx, cy); - CDockablePane::OnSize(nType, cx, cy); -} - -///////////////////////////////////////////////////////////////////////////// - BOOL CColorPalette::SetupLineControl() { if (!m_comboLine->Create(this, @@ -374,9 +312,9 @@ BOOL CColorPalette::SetupLineControl() // Command UI Stuff CColorCmdUI::CColorCmdUI(CColorPalette& cp) : + wxCommandEvent(cbEVT_UPDATE_UI_COLOR), colorPalette(&cp) { - m_pOther = nullptr; } // Only used for auto disable @@ -384,13 +322,13 @@ void CColorCmdUI::Enable(BOOL bOn) { m_bEnableChanged = TRUE; if (!bOn) - colorPalette->SetIDColor(m_nID, wxNullColour); + colorPalette->SetIDColor(GetId(), wxNullColour); } void CColorCmdUI::SetColor(wxColour cr) { m_bEnableChanged = TRUE; - colorPalette->SetIDColor(m_nID, cr); + colorPalette->SetIDColor(GetId(), cr); } void CColorCmdUI::SetLineWidth(UINT uiLineWidth) @@ -405,24 +343,34 @@ void CColorCmdUI::SetCustomColors(const std::vector& pCustColors) colorPalette->SetCustomColors(pCustColors); } -void CDockColorPalette::OnUpdateCmdUI(CFrameWnd* pTarget, BOOL bDisableIfNoHndler) +void CColorPalette::OnUpdateCmdUI(wxUpdateUIEvent& /*pCmdUI*/) { - CColorCmdUI state(*m_child); - state.m_nID = ID_COLOR_FOREGROUND; - state.DoUpdate(pTarget, bDisableIfNoHndler); - state.m_nID = ID_COLOR_BACKGROUND; - state.DoUpdate(pTarget, bDisableIfNoHndler); - state.m_nID = ID_COLOR_TRANSPARENT; - state.DoUpdate(pTarget, bDisableIfNoHndler); - state.m_nID = ID_COLOR_CUSTOM; - state.DoUpdate(pTarget, bDisableIfNoHndler); - state.m_nID = ID_LINE_WIDTH; - state.DoUpdate(pTarget, bDisableIfNoHndler); + if (!IsShownOnScreen()) // Ignore if wnd is invisible + { + return; + } + + CColorCmdUI state(*this); + state.SetId(XRCID("ID_COLOR_FOREGROUND")); + state.DoUpdate(); + state.SetId(XRCID("ID_COLOR_BACKGROUND")); + state.DoUpdate(); + state.SetId(XRCID("ID_COLOR_TRANSPARENT")); + state.DoUpdate(); + state.SetId(XRCID("ID_COLOR_CUSTOM")); + state.DoUpdate(); + state.SetId(XRCID("ID_LINE_WIDTH")); + state.DoUpdate(); } -CSize CDockColorPalette::CalcSize() const +void CColorCmdUI::DoUpdate() { - return CB::Convert(m_child->GetSize()); + m_bEnableChanged = false; + CB::GetMainWndWx().ProcessWindowEvent(*this); + if (!m_bEnableChanged) + { + Enable(false); + } } ///////////////////////////////////////////////////////////////////////////// @@ -682,19 +630,19 @@ void CColorPalette::SetLineWidth(UINT nLineWidth) m_comboLine->SetSelection(nLineWidth); } -void CColorPalette::SetIDColor(UINT nID, wxColour cr) +void CColorPalette::SetIDColor(int nID, wxColour cr) { - if (nID == ID_COLOR_FOREGROUND) + if (nID == XRCID("ID_COLOR_FOREGROUND")) { if (cr == m_crFore) return; m_crFore = cr; } - else if (nID == ID_COLOR_BACKGROUND) + else if (nID == XRCID("ID_COLOR_BACKGROUND")) { if (cr == m_crBack) return; m_crBack = cr; } - else if (nID == ID_COLOR_TRANSPARENT) + else if (nID == XRCID("ID_COLOR_TRANSPARENT")) { if (cr == m_crTrans) return; m_crTrans = cr; @@ -865,59 +813,32 @@ BOOL CColorPalette::HandleButtonDown(const wxMouseEvent& event) void CColorPalette::NotifyColorChange(const wxMouseEvent& event, wxColour cref) { - CView* pView = GetMainFrame()->GetActiveView(); + wxView* pView = GetMainFrame()->GetActiveView(); if (pView == NULL) return; - wxASSERT(!dynamic_cast(pView)); - CB::IGetEventHandler* getter = dynamic_cast(pView); - wxEvtHandler* evtHandler = getter ? *getter : nullptr; if (mouseFore(event)) { - if (!evtHandler) - { - pView->SendMessage(WM_SETCOLOR, (WPARAM)ID_COLOR_FOREGROUND, static_cast(CB::Convert(cref))); - } - else - { - SetColorEvent event2(XRCID("ID_COLOR_FOREGROUND"), cref); - evtHandler->ProcessEvent(event2); - } + SetColorEvent event2(XRCID("ID_COLOR_FOREGROUND"), cref); + pView->ProcessEvent(event2); } else if (mouseBack1(event) || mouseBack2(event)) { - if (!evtHandler) - { - pView->SendMessage(WM_SETCOLOR, (WPARAM)ID_COLOR_BACKGROUND, static_cast(CB::Convert(cref))); - } - else - { - SetColorEvent event2(XRCID("ID_COLOR_BACKGROUND"), cref); - evtHandler->ProcessEvent(event2); - } + SetColorEvent event2(XRCID("ID_COLOR_BACKGROUND"), cref); + pView->ProcessEvent(event2); } } void CColorPalette::NotifyCustomColorChange(const std::vector& pcrCustomColors) { - CView* pView = GetMainFrame()->GetActiveView(); + wxView* pView = GetMainFrame()->GetActiveView(); if (pView == NULL) return; - wxASSERT(!dynamic_cast(pView)); - CB::IGetEventHandler* getter = dynamic_cast(pView); - wxEvtHandler* evtHandler = getter ? *getter : nullptr; - if (!evtHandler) - { - pView->SendMessage(WM_SETCUSTOMCOLOR, value_preserving_cast(reinterpret_cast(&pcrCustomColors))); - } - else - { - SetCustomColorEvent event2(pcrCustomColors); - evtHandler->ProcessEvent(event2); - } + SetCustomColorEvent event2(pcrCustomColors); + pView->ProcessEvent(event2); } ///////////////////////////////////////////////////////////////////////////// @@ -1025,20 +946,9 @@ void CColorPalette::OnMouseCaptureLost(wxMouseCaptureLostEvent& /*event*/) void CColorPalette::OnLineWidthCbnSelchange(wxCommandEvent& /*event*/) { - CView* pView = GetMainFrame()->GetActiveView(); - wxASSERT(!dynamic_cast(pView)); - CB::IGetEventHandler* getter = dynamic_cast(pView); - wxEvtHandler* evtHandler = getter ? *getter : nullptr; - if (!evtHandler) - { - pView->SendMessage(WM_SETLINEWIDTH, - (WPARAM)m_comboLine->GetSelection(), (LPARAM)0); - } - else - { - SetLineWidthEvent event2(m_comboLine->GetSelection()); - evtHandler->ProcessEvent(event2); - } + wxView* pView = GetMainFrame()->GetActiveView(); + SetLineWidthEvent event2(m_comboLine->GetSelection()); + pView->ProcessEvent(event2); } #if 0 @@ -1053,6 +963,7 @@ BOOL CColorPalette::OnHelpInfo(HELPINFO* pHelpInfo) void CColorPalette::OnPaletteHide(wxCommandEvent& /*event*/) { - GetMainFrame()->SendMessage(WM_COMMAND, ID_WINDOW_COLORPAL); + wxCommandEvent event(wxEVT_MENU, XRCID("ID_WINDOW_COLORPAL")); + GetMainFrame()->ProcessWindowEvent(event); } diff --git a/GM/PalColor.h b/GM/PalColor.h index b596e25b..7d825eea 100644 --- a/GM/PalColor.h +++ b/GM/PalColor.h @@ -1,6 +1,6 @@ // ColorPal.h : header file // -// 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 @@ -67,71 +67,34 @@ inline bool mouseSetCustomClear(const wxMouseEvent& event) class CColorPalette; -class CColorCmdUI : public CCmdUI +class CColorCmdUI : public wxCommandEvent { public: CColorCmdUI(CColorPalette& colorPalette); - // Not used... - virtual void SetCheck(int nCheck) override {} - virtual void SetText(LPCTSTR lpszText) override {} + // Used... - virtual void Enable(BOOL bOn) override; + void Enable(BOOL bOn); // New for color palette - virtual void SetColor(wxColour cr = wxNullColour) /* override */; - virtual void SetLineWidth(UINT uiLineWidth = 0) /* override */; - virtual void SetCustomColors(const std::vector& pCustColors) /* override */; + void SetColor(wxColour cr = wxNullColour); + void SetLineWidth(UINT uiLineWidth = 0); + void SetCustomColors(const std::vector& pCustColors); + + void DoUpdate(); private: RefPtr colorPalette; + bool m_bEnableChanged; }; +wxDECLARE_EVENT(cbEVT_UPDATE_UI_COLOR, CColorCmdUI); +typedef void (wxEvtHandler::* CColorCmdUIFunction)(CColorCmdUI&); +#define CColorCmdUIHandler(func) wxEVENT_HANDLER_CAST(CColorCmdUIFunction, func) +#define EVT_UPDATE_UI_COLOR(id, func) \ + wx__DECLARE_EVT1(cbEVT_UPDATE_UI_COLOR, id, CColorCmdUIHandler(func)) /////////////////////////////////////////////////////////////////////// class CMainFrame; -class CDockColorPalette : public CDockablePane, - public CB::wxNativeContainerWindowMixin -{ - DECLARE_DYNCREATE(CDockColorPalette); - // Construction -public: - CDockColorPalette(); - -// Operations -public: - void CalculateMinClientSize(CSize& size); - -// Overrides -protected: - virtual CSize CalcFixedLayout(BOOL bStretch, BOOL bHorz) override; - virtual void OnUpdateCmdUI(CFrameWnd* pTarget, BOOL bDisableIfNoHndler) override; - virtual CSize CalcSize(BOOL bVertDock) override - { - return CalcSize(); - } - virtual void GetMinSize(CSize& size) const override - { - // Account for size of caption. - size = CalcSize() + CSize(0, GetCaptionHeight()); - } - virtual void GetPaneName(CString &strName) const override - { - AfxThrowNotSupportedException(); - } - -private: - CSize CalcSize() const; - - // wx owns m_child - RefPtr m_child; - - afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); - afx_msg LRESULT OnIdleUpdateCmdUI(WPARAM wParam, LPARAM lParam); - afx_msg void OnSize(UINT nType, int cx, int cy); - - DECLARE_MESSAGE_MAP() -}; - class CColorPalette : public wxPanel { public: @@ -139,15 +102,15 @@ class CColorPalette : public wxPanel BOOL SetupLineControl(); // Attributes -public: - wxSize GetSize() const +protected: + wxSize DoGetBestClientSize() const override { return m_sizeClient; } // Operations public: - void SetIDColor(UINT nID, wxColour cr); + void SetIDColor(int nID, wxColour cr); void SetLineWidth(UINT nLineWidth); void SetCustomColors(const std::vector& pCustColors); void CalculateMinClientSize(wxSize& size) @@ -241,6 +204,7 @@ class CColorPalette : public wxPanel void OnCreate(wxWindowCreateEvent& event); void OnLButtonDown(wxMouseEvent& event); void OnRButtonDown(wxMouseEvent& event); + void OnUpdateCmdUI(wxUpdateUIEvent& pCmdUI); void OnLineWidthCbnSelchange(wxCommandEvent& event); #if 0 afx_msg BOOL OnHelpInfo(HELPINFO* pHelpInfo); diff --git a/GM/PalTile.cpp b/GM/PalTile.cpp index 4d459ca0..92997578 100644 --- a/GM/PalTile.cpp +++ b/GM/PalTile.cpp @@ -1,6 +1,6 @@ // PalTile.cpp - Tile palette window // -// 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 @@ -59,6 +59,10 @@ CTilePalette::CTilePalette(const CGamDoc& pDoc, wxWindow& pOwnerWnd) : CB_XRC_CTRL(m_listTile) CB_XRC_END_CTRLS_DEFN() { + wxInfoDC dc(&*m_comboTGrp); + int minX = dc.GetTextExtent("MMMMMMMM"_cbstring).x; + int minY = m_comboTGrp->GetBestSize().y * 3; + SetMinClientSize(wxSize(minX, minY)); m_pDockingFrame = NULL; m_listTile->SetDocument(&pDoc); m_listTile->EnableDrag(TRUE); @@ -70,15 +74,19 @@ CTilePalette::CTilePalette(const CGamDoc& pDoc, wxWindow& pOwnerWnd) : void CTilePalette::OnPaletteHide(wxCommandEvent& /*event*/) { - GetMainFrame()->SendMessage(WM_COMMAND, ID_WINDOW_TILEPAL); + wxCommandEvent event(wxEVT_MENU, XRCID("ID_WINDOW_TILEPAL")); + GetMainFrame()->ProcessWindowEvent(event); } ///////////////////////////////////////////////////////////////////////////// TileID CTilePalette::GetCurrentTileID() const { - if (m_hWnd == NULL) + wxASSERT(GetHandle()); + if (!GetHandle()) + { return nullTid; + } if (m_listTile->GetSelection() == wxNOT_FOUND) return nullTid; return m_listTile->GetCurMapItem(); @@ -142,6 +150,18 @@ void CTilePalette::UpdateTileList() m_listTile->SetItemMap(&pPieceTbl); } +wxSize CTilePalette::DoGetBestClientSize() const +{ + wxSize choiceBestSize = m_comboTGrp->GetBestSize(); + wxSize tilesBestSize = m_listTile->GetBestSize(); + wxSize bestClientSize(std::max(choiceBestSize.x, tilesBestSize.x), + m_listTile->GetPosition().y + tilesBestSize.y); + // limit best size to no more than 1/4 of screen dims + bestClientSize.x = std::min(bestClientSize.x, wxSystemSettings::GetMetric(wxSYS_SCREEN_X, this)/4); + bestClientSize.y = std::min(bestClientSize.y, wxSystemSettings::GetMetric(wxSYS_SCREEN_Y, this)/4); + return bestClientSize; +} + ///////////////////////////////////////////////////////////////////////////// // CTilePalette message handlers diff --git a/GM/PalTile.h b/GM/PalTile.h index a7eb4d52..d7ab6adf 100644 --- a/GM/PalTile.h +++ b/GM/PalTile.h @@ -74,10 +74,11 @@ class CTilePalette : public wxPanel void SetDockingFrame(CDockTilePalette* pDockingFrame) { m_pDockingFrame = pDockingFrame; - Reparent(pDockingFrame ? static_cast(*pDockingFrame) : nullptr); + Reparent(pDockingFrame); } protected: + wxSize DoGetBestClientSize() const override; void OnTileNameCbnSelchange(wxCommandEvent& event); void OnGetDragSize(GetDragSizeEvent& event); #if 0 diff --git a/GM/VwBitedt.cpp b/GM/VwBitedt.cpp index 3274ceda..b0148818 100644 --- a/GM/VwBitedt.cpp +++ b/GM/VwBitedt.cpp @@ -1,6 +1,6 @@ // VwBitedt.cpp : implementation file // -// 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 @@ -27,6 +27,7 @@ #include "GmDoc.h" #include "ResTbl.h" #include "CellForm.h" +#include "FrmBited.h" #include "VwBitedt.h" #include "VwTilesl.h" #include "PalColor.h" @@ -50,10 +51,7 @@ const size_t maxUndoLevels = size_t(8); ///////////////////////////////////////////////////////////////////////////// -namespace { - typedef wxDocChildFrameAny>, wxWindow> NoCommas; -} -wxBEGIN_EVENT_TABLE(CBitEditView, NoCommas) +wxBEGIN_EVENT_TABLE(CBitEditView, wxScrolledCanvas) EVT_MENU(XRCID("ID_IMAGE_GRIDLINES"), OnImageGridLines) EVT_MENU(XRCID("ID_ITOOL_PENCIL"), OnToolPalette) EVT_SETCOLOR(OnSetColor) @@ -61,11 +59,11 @@ wxBEGIN_EVENT_TABLE(CBitEditView, NoCommas) EVT_SETLINEWIDTH(OnSetLineWidth) EVT_UPDATE_UI(XRCID("ID_IMAGE_GRIDLINES"), OnUpdateImageGridLines) EVT_UPDATE_UI(XRCID("ID_ITOOL_PENCIL"), OnUpdateToolPalette) - EVT_UPDATE_UI(XRCID("ID_COLOR_FOREGROUND"), OnUpdateColorForeground) - EVT_UPDATE_UI(XRCID("ID_COLOR_BACKGROUND"), OnUpdateColorBackground) - EVT_UPDATE_UI(XRCID("ID_COLOR_TRANSPARENT"), OnUpdateColorTransparent) - EVT_UPDATE_UI(XRCID("ID_COLOR_CUSTOM"), OnUpdateColorCustom) - EVT_UPDATE_UI(XRCID("ID_LINE_WIDTH"), OnUpdateLineWidth) + EVT_UPDATE_UI_COLOR(XRCID("ID_COLOR_FOREGROUND"), OnUpdateColorForeground) + EVT_UPDATE_UI_COLOR(XRCID("ID_COLOR_BACKGROUND"), OnUpdateColorBackground) + EVT_UPDATE_UI_COLOR(XRCID("ID_COLOR_TRANSPARENT"), OnUpdateColorTransparent) + EVT_UPDATE_UI_COLOR(XRCID("ID_COLOR_CUSTOM"), OnUpdateColorCustom) + EVT_UPDATE_UI_COLOR(XRCID("ID_LINE_WIDTH"), OnUpdateLineWidth) EVT_LEFT_DOWN(OnLButtonDown) EVT_LEFT_UP(OnLButtonUp) EVT_MOTION(OnMouseMove) @@ -86,7 +84,7 @@ wxBEGIN_EVENT_TABLE(CBitEditView, NoCommas) EVT_MENU(wxID_PASTE, OnEditPaste) EVT_UPDATE_UI(wxID_PASTE, OnUpdateEditPaste) EVT_UPDATE_UI(wxID_COPY, OnUpdateEditCopy) - EVT_UPDATE_UI(XRCID("ID_INDICATOR_CELLNUM"), OnUpdateIndicatorCellNum) + EVT_UPDATE_UI(ID_INDICATOR_CELLNUM, OnUpdateIndicatorCellNum) EVT_CONTEXT_MENU(OnContextMenu) EVT_MENU(XRCID("ID_ITOOL_SELECT"), OnToolPalette) EVT_MENU(XRCID("ID_ITOOL_BRUSH"), OnToolPalette) @@ -114,19 +112,13 @@ wxBEGIN_EVENT_TABLE(CBitEditView, NoCommas) EVT_UPDATE_UI(XRCID("ID_VIEW_TOGGLE_SCALE"), OnUpdateEnable) wxEND_EVENT_TABLE() -BEGIN_MESSAGE_MAP(CBitEditViewContainer, CView) - ON_WM_CREATE() - ON_WM_SETFOCUS() -END_MESSAGE_MAP() - ///////////////////////////////////////////////////////////////////////////// // CBitEditView -IMPLEMENT_DYNCREATE(CBitEditViewContainer, CView) - -CBitEditView::CBitEditView(CBitEditViewContainer& p) : +CBitEditView::CBitEditView(wxSplitterWindow& p, wxBitEditView& v) : parent(&p), - document(CB::ToCGamDoc(parent->GetDocument())) + document(&v.GetDocument()), + view(&v) { m_pSelView = NULL; m_nZoom = 6; @@ -140,9 +132,28 @@ CBitEditView::CBitEditView(CBitEditViewContainer& p) : m_nCurToolID = XRCID("ID_ITOOL_PENCIL"); m_nLastToolID = XRCID("ID_ITOOL_PENCIL"); m_bSelectCapture = FALSE; - wxScrolledCanvas::Create(*parent, 0); - wxView->SetDocument(&*document); - wxView->SetFrame(this); + wxScrolledCanvas::Create(&*parent, 0); +} + +wxAuiToolBar& CBitEditView::CreateToolbar(wxWindow& parent) +{ + static const CB::ToolArgs toolArgs[] = { + { XRCID("ID_ITOOL_PENCIL"), ID_ITOOL_PENCIL, wxITEM_CHECK }, + { XRCID("ID_ITOOL_SELECT"), ID_ITOOL_SELECT, wxITEM_CHECK }, + { XRCID("ID_ITOOL_BRUSH"), ID_ITOOL_BRUSH, wxITEM_CHECK }, + { XRCID("ID_ITOOL_FILL"), ID_ITOOL_FILL, wxITEM_CHECK }, + { XRCID("ID_ITOOL_COLORCHANGE"), ID_ITOOL_COLORCHANGE, wxITEM_CHECK }, + { XRCID("ID_ITOOL_TEXT"), ID_ITOOL_TEXT, wxITEM_CHECK }, + { XRCID("ID_ITOOL_LINE"), ID_ITOOL_LINE, wxITEM_CHECK }, + { XRCID("ID_ITOOL_RECT"), ID_ITOOL_RECT, wxITEM_CHECK }, + { XRCID("ID_ITOOL_OVAL"), ID_ITOOL_OVAL, wxITEM_CHECK }, + { XRCID("ID_ITOOL_FILLRECT"), ID_ITOOL_FILLRECT, wxITEM_CHECK }, + { XRCID("ID_ITOOL_FILLOVAL"), ID_ITOOL_FILLOVAL, wxITEM_CHECK }, + { XRCID("ID_ITOOL_DROPPER"), ID_ITOOL_DROPPER, wxITEM_CHECK }, + }; + return CB::CreateToolbar(parent, + toolArgs, + IDB_IMAGETOOLS); } CBitEditView::~CBitEditView() @@ -154,8 +165,6 @@ CBitEditView::~CBitEditView() void CBitEditView::OnInitialUpdate() { - CB_VERIFY(Create(&GetDocument(), &*wxView, *GetMainFrame(), wxID_ANY, "dummy")); - wxSizer* sizer = new wxBoxSizer(wxVERTICAL); SetSizer(sizer); sizer->Add(100, 100); @@ -170,7 +179,12 @@ void CBitEditView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint) WORD wHint = LOWORD(lHint); // Update for nonspecific notification only if (wHint == HINT_ALWAYSUPDATE) + { + wxASSERT(!"untested code"); +#if 0 parent->CView::OnUpdate(pSender, lHint, pHint); +#endif + } } ///////////////////////////////////////////////////////////////////////////// @@ -186,7 +200,11 @@ void CBitEditView::OnDraw(wxDC& pDC) if (m_nCurToolID != XRCID("ID_ITOOL_SELECT") || m_rctPaste.IsEmpty()) { // Handle fancy focus rect +#if 0 /* wx frames don't support multiple views. + Fortunately, I don't think CB3 ever let + tile selector be active. */ if (parent->GetParentFrame()->GetActiveView() == parent) +#endif { wxRect rct(0, 0, 2 * xBorder + size.x, 2 * yBorder + size.y); Draw25PctPatBorder(*this, pDC, rct, xBorder); @@ -227,7 +245,11 @@ void CBitEditView::OnDraw(wxDC& pDC) m_bmPaste.IsOk() && !m_rctPaste.IsEmpty()) { // Handle fancy focus rect +#if 0 /* wx frames don't support multiple views. + Fortunately, I don't think CB3 ever let + tile selector be active. */ if (parent->GetParentFrame()->GetActiveView()) +#endif { // Convert paste rect to view coordinates. wxRect rct = GetZoomedSelectBorderRect(); @@ -236,28 +258,6 @@ void CBitEditView::OnDraw(wxDC& pDC) } } -void CBitEditViewContainer::OnActivateView(BOOL bActivate, CView *pActivateView, - CView* pDeactivateView) -{ - CB::OnCmdMsgOverride::OnActivateView(bActivate, pActivateView, pDeactivateView); - - // KLUDGE: often get deactivate w/o activate - if (bActivate) - { - wxActivateEvent event(wxEVT_ACTIVATE, bActivate); - child->ProcessWindowEvent(event); - } - - if (pActivateView == pDeactivateView) - return; -// if (m_nCurToolID == ID_ITOOL_TEXT) -// { -// child->SetFocus(); -// child->SetTextCaretPos(m_ptCaret); -// } - child->Refresh(); // Later only mess with focus rect. -} - ///////////////////////////////////////////////////////////////////////////// void CBitEditView::ClientToWorkspace(wxPoint& pnt) const @@ -927,7 +927,8 @@ void CBitEditView::OnMouseCaptureLost(wxMouseCaptureLostEvent& /*event*/) void CBitEditView::OnSetCursor(wxSetCursorEvent& event) { IToolType eToolType = MapToolType(m_nCurToolID); - if (eToolType != itoolUnknown) +// wxASSERT(event.GetEventObject() == this); + if (event.GetEventObject() == this && eToolType != itoolUnknown) { CImageTool& pTool = CImageTool::GetTool(eToolType); wxPoint point = ClientToWorkspace(wxPoint(event.GetX(), event.GetY())); @@ -1005,7 +1006,11 @@ void CBitEditView::OnToolPalette(wxCommandEvent& event) CommitCurrentText(); SetTextCaretPos(wxPoint(-1, -1)); // Turn off the caret // wx doesn't have precise DestroyCaret() equivalent - GetCaret()->Hide(); + wxCaret* caret = GetCaret(); + if (caret) + { + caret->Hide(); + } } if (m_nLastToolID == XRCID("ID_ITOOL_SELECT") && m_bmPaste.IsOk()) { @@ -1046,38 +1051,28 @@ void CBitEditView::OnSetLineWidth(SetLineWidthEvent& event) m_pTMgr->SetLineWidth(event.GetWidth()); } -void CBitEditView::OnUpdateColorForeground(wxUpdateUIEvent& pCmdUI) +void CBitEditView::OnUpdateColorForeground(CColorCmdUI& colorCmdUI) { - CCmdUI* cmdui = static_cast(pCmdUI.GetClientData()); - CColorCmdUI& colorCmdUI = CheckedDeref(dynamic_cast(cmdui)); colorCmdUI.SetColor(CB::Convert(m_pTMgr->GetForeColor())); } -void CBitEditView::OnUpdateColorBackground(wxUpdateUIEvent& pCmdUI) +void CBitEditView::OnUpdateColorBackground(CColorCmdUI& colorCmdUI) { - CCmdUI* cmdui = static_cast(pCmdUI.GetClientData()); - CColorCmdUI& colorCmdUI = CheckedDeref(dynamic_cast(cmdui)); colorCmdUI.SetColor(CB::Convert(m_pTMgr->GetBackColor())); } -void CBitEditView::OnUpdateColorTransparent(wxUpdateUIEvent& pCmdUI) +void CBitEditView::OnUpdateColorTransparent(CColorCmdUI& colorCmdUI) { - CCmdUI* cmdui = static_cast(pCmdUI.GetClientData()); - CColorCmdUI& colorCmdUI = CheckedDeref(dynamic_cast(cmdui)); colorCmdUI.SetColor(CB::Convert(m_pTMgr->GetTransparentColor())); } -void CBitEditView::OnUpdateColorCustom(wxUpdateUIEvent& pCmdUI) +void CBitEditView::OnUpdateColorCustom(CColorCmdUI& colorCmdUI) { - CCmdUI* cmdui = static_cast(pCmdUI.GetClientData()); - CColorCmdUI& colorCmdUI = CheckedDeref(dynamic_cast(cmdui)); colorCmdUI.SetCustomColors(GetDocument().GetCustomColors()); } -void CBitEditView::OnUpdateLineWidth(wxUpdateUIEvent& pCmdUI) +void CBitEditView::OnUpdateLineWidth(CColorCmdUI& colorCmdUI) { - CCmdUI* cmdui = static_cast(pCmdUI.GetClientData()); - CColorCmdUI& colorCmdUI = CheckedDeref(dynamic_cast(cmdui)); colorCmdUI.SetLineWidth(m_pTMgr->GetLineWidth()); } @@ -1300,45 +1295,3 @@ void CBitEditView::OnUpdateIndicatorCellNum(wxUpdateUIEvent& pCmdUI) } } } - -void CBitEditViewContainer::OnDraw(CDC* pDC) -{ - // do nothing because child covers entire client rect -} - -void CBitEditViewContainer::OnInitialUpdate() -{ - child->OnInitialUpdate(); -} - -void CBitEditViewContainer::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint) -{ - child->OnUpdate(pSender, lHint, pHint); -} - -CBitEditViewContainer::CBitEditViewContainer() : - CB::wxNativeContainerWindowMixin(static_cast(*this)) -{ -} - -int CBitEditViewContainer::OnCreate(LPCREATESTRUCT lpCreateStruct) -{ - if (CView::OnCreate(lpCreateStruct) == -1) - { - return -1; - } - - static_cast(*GetMainFrame()).AddChild(*this); - wxASSERT(static_cast(*this).GetParent() == *GetMainFrame()); - - child = new CBitEditView(*this); - - return 0; -} - -// MFC puts the focus here, so move it to the useful window -void CBitEditViewContainer::OnSetFocus(CWnd* pOldWnd) -{ - CB::OnCmdMsgOverride::OnSetFocus(pOldWnd); - child->SetFocus(); -} diff --git a/GM/VwBitedt.h b/GM/VwBitedt.h index a9066f77..874d997f 100644 --- a/GM/VwBitedt.h +++ b/GM/VwBitedt.h @@ -1,6 +1,6 @@ // VwBitedt.h : implementation file // -// 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 @@ -37,17 +37,20 @@ ///////////////////////////////////////////////////////////////////////////// // CBitEditView view +class wxBitEditView; +class CColorCmdUI; class CTileSelView; -class CBitEditView : public wxDocChildFrameAny>, wxWindow> +class CBitEditView : public wxScrolledCanvas { - friend class CBitEditViewContainer; - friend class CTileSelViewContainer; + friend class CBitEditFrame; protected: - CBitEditView(CBitEditViewContainer& parent); + CBitEditView(wxSplitterWindow& parent, wxBitEditView& view); // Attributes public: + static wxAuiToolBar& CreateToolbar(wxWindow& parent); + const CGamDoc& GetDocument() const { return *document; } CGamDoc& GetDocument() { @@ -188,7 +191,9 @@ class CBitEditView : public wxDocChildFrameAny parent; + RefPtr parent; RefPtr document; - OwnerPtr wxView = MakeOwner(*this); -}; - -class CBitEditViewContainer : public CB::OnCmdMsgOverride, - public CB::wxNativeContainerWindowMixin -{ -public: - const CBitEditView& GetChild() const { return CheckedDeref(child); } - CBitEditView& GetChild() - { - return const_cast(std::as_const(*this).GetChild()); - } - void OnDraw(CDC* pDC) override; - void OnInitialUpdate() override; - void OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint) override; - -protected: - void OnActivateView(BOOL bActivate, CView *pActivateView, - CView* pDeactivateView) override; - -private: - CBitEditViewContainer(); // used by dynamic creation - DECLARE_DYNCREATE(CBitEditViewContainer) - - afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); - afx_msg void OnSetFocus(CWnd* pOldWnd); - DECLARE_MESSAGE_MAP() - - // IGetEventHandler - wxEvtHandler& Get() override - { - return CheckedDeref(CheckedDeref(child).GetEventHandler()); - } - - // owned by wx - CB::propagate_const child = nullptr; - - friend CBitEditView; + RefPtr view; }; ///////////////////////////////////////////////////////////////////////////// diff --git a/GM/VwEdtbrd.cpp b/GM/VwEdtbrd.cpp index 92fd3d93..4097500b 100644 --- a/GM/VwEdtbrd.cpp +++ b/GM/VwEdtbrd.cpp @@ -1,6 +1,6 @@ // VwEdtbrd.cpp : implementation of the CBrdEditView class // -// 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 @@ -49,12 +49,9 @@ static char THIS_FILE[] = __FILE__; ///////////////////////////////////////////////////////////////////////////// // CBrdEditView -IMPLEMENT_DYNCREATE(CBrdEditViewContainer, CView) +wxIMPLEMENT_DYNAMIC_CLASS(wxBrdEditView, wxView); -namespace { - typedef wxDocChildFrameAny>, wxWindow> NoCommas; -} -wxBEGIN_EVENT_TABLE(CBrdEditView, NoCommas) +wxBEGIN_EVENT_TABLE(CBrdEditView, wxScrolledCanvas) #if 0 ON_WM_MOUSEWHEEL() #endif @@ -87,10 +84,10 @@ wxBEGIN_EVENT_TABLE(CBrdEditView, NoCommas) ON_UPDATE_COMMAND_UI(ID_OFFSCREEN, OnUpdateOffscreen) #endif EVT_UPDATE_UI(XRCID("ID_EDIT_LAYER_BASE"), OnUpdateEditLayer) - EVT_UPDATE_UI(XRCID("ID_COLOR_FOREGROUND"), OnUpdateColorForeground) - EVT_UPDATE_UI(XRCID("ID_COLOR_BACKGROUND"), OnUpdateColorBackground) - EVT_UPDATE_UI(XRCID("ID_COLOR_CUSTOM"), OnUpdateColorCustom) - EVT_UPDATE_UI(XRCID("ID_LINE_WIDTH"), OnUpdateLineWidth) + EVT_UPDATE_UI_COLOR(XRCID("ID_COLOR_FOREGROUND"), OnUpdateColorForeground) + EVT_UPDATE_UI_COLOR(XRCID("ID_COLOR_BACKGROUND"), OnUpdateColorBackground) + EVT_UPDATE_UI_COLOR(XRCID("ID_COLOR_CUSTOM"), OnUpdateColorCustom) + EVT_UPDATE_UI_COLOR(XRCID("ID_LINE_WIDTH"), OnUpdateLineWidth) EVT_UPDATE_UI(XRCID("ID_TOOL_ARROW"), OnUpdateToolPalette) EVT_UPDATE_UI(XRCID("ID_DWG_TOFRONT"), OnUpdateDwgToFrontOrBack) EVT_UPDATE_UI(XRCID("ID_VIEW_FULLSCALE"), OnUpdateViewFullScale) @@ -100,7 +97,7 @@ wxBEGIN_EVENT_TABLE(CBrdEditView, NoCommas) EVT_MENU(XRCID("ID_VIEW_HALFSCALE"), OnViewHalfScale) EVT_MENU(XRCID("ID_VIEW_SMALLSCALE"), OnViewSmallScale) EVT_UPDATE_UI(XRCID("ID_VIEW_SMALLSCALE"), OnUpdateViewSmallScale) - EVT_UPDATE_UI(XRCID("ID_INDICATOR_CELLNUM"), OnUpdateIndicatorCellNum) + EVT_UPDATE_UI(ID_INDICATOR_CELLNUM, OnUpdateIndicatorCellNum) EVT_MENU(XRCID("ID_TOOLS_BRDSNAPGRID"), OnToolsBrdSnapGrid) EVT_UPDATE_UI(XRCID("ID_TOOLS_BRDSNAPGRID"), OnUpdateToolsBrdSnapGrid) EVT_MENU(XRCID("ID_TOOLS_BRDPROPS"), OnToolsBrdProps) @@ -153,22 +150,18 @@ wxBEGIN_EVENT_TABLE(CBrdEditView, NoCommas) EVT_SCROLLWIN_LINEUP(OnScrollWinLine) wxEND_EVENT_TABLE() -BEGIN_MESSAGE_MAP(CBrdEditViewContainer, CView) - ON_WM_CREATE() - ON_WM_SETFOCUS() -END_MESSAGE_MAP() - ///////////////////////////////////////////////////////////////////////////// // CBrdEditView construction/destruction -CBrdEditView::CBrdEditView(CBrdEditViewContainer& p) : +CBrdEditView::CBrdEditView(wxView& v, CBoard& b) : m_selList(*this), - parent(&p), - document(CB::ToCGamDoc(parent->GetDocument())), + view(&v), + parent(view->GetFrame()), + document(dynamic_cast(view->GetDocument())), timer(this) { m_bOffScreen = TRUE; - m_pBoard = NULL; + m_pBoard = &b; m_pBMgr = NULL; m_nCurToolID = XRCID("ID_TOOL_ARROW"); // ID_TOOL_ARROW tool (select) m_nLastToolID = XRCID("ID_TOOL_ARROW"); // ID_TOOL_ARROW tool (select) @@ -177,9 +170,27 @@ CBrdEditView::CBrdEditView(CBrdEditViewContainer& p) : wxSizer* sizer = new wxBoxSizer(wxVERTICAL); SetSizer(sizer); sizer->Add(0, 0); - wxScrolledCanvas::Create(*parent, 0); - wxView->SetDocument(&*document); - wxView->SetFrame(this); + wxScrolledCanvas::Create(&*parent, 0); + OnInitialUpdate(); +} + +wxAuiToolBar& CBrdEditView::CreateToolbar(wxWindow& parent) +{ + static const CB::ToolArgs toolArgs[] = { + { XRCID("ID_TOOL_ARROW"), ID_TOOL_ARROW, wxITEM_CHECK }, + { XRCID("ID_TOOL_ERASER"), ID_TOOL_ERASER, wxITEM_CHECK }, + { XRCID("ID_TOOL_TILE"), ID_TOOL_TILE, wxITEM_CHECK }, + { XRCID("ID_TOOL_TEXT"), ID_TOOL_TEXT, wxITEM_CHECK }, + { XRCID("ID_TOOL_FILL"), ID_TOOL_FILL, wxITEM_CHECK }, + { XRCID("ID_TOOL_DROPPER"), ID_TOOL_DROPPER, wxITEM_CHECK }, + { XRCID("ID_TOOL_LINE"), ID_TOOL_LINE, wxITEM_CHECK }, + { XRCID("ID_TOOL_POLYGON"), ID_TOOL_POLYGON, wxITEM_CHECK }, + { XRCID("ID_TOOL_RECT"), ID_TOOL_RECT, wxITEM_CHECK }, + { XRCID("ID_TOOL_OVAL"), ID_TOOL_OVAL, wxITEM_CHECK }, + }; + return CB::CreateToolbar(parent, + toolArgs, + IDB_DRAWLAYERTOOLS); } CBrdEditView::~CBrdEditView() @@ -202,10 +213,7 @@ BOOL CBrdEditView::PreCreateWindow(CREATESTRUCT& cs) void CBrdEditView::OnInitialUpdate() { - CB_VERIFY(Create(&GetDocument(), &*wxView, *GetMainFrame(), wxID_ANY, "dummy")); - m_pBMgr = &GetDocument().GetBoardManager(); - m_pBoard = static_cast(GetDocument().GetCreateParameter()); RecalcScrollLimits(); } @@ -222,9 +230,10 @@ void CBrdEditView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint) { if (static_cast(pHint)->GetArgs().m_pBoard == m_pBoard) { - CFrameWnd* pFrm = parent->GetParentFrame(); - ASSERT(pFrm != NULL); - pFrm->SendMessage(WM_CLOSE, 0, 0L); + // close this view + /* can't delete now + because iterator in caller would be invalidated */ + wxTheApp->ScheduleForDestruction(&*view); } } else if (wHint == HINT_BOARDPROPCHANGE) @@ -238,7 +247,9 @@ void CBrdEditView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint) else if (wHint == HINT_ALWAYSUPDATE) { wxASSERT(!"untested code"); +#if 0 parent->CView::OnUpdate(pSender, lHint, pHint); +#endif } } @@ -535,11 +546,12 @@ void CBrdEditView::OnViewGridLines(wxCommandEvent& event) CGmBoxHint hint; hint.GetArgs().m_pBoard = &*m_pBoard; - GetDocument().UpdateAllViews(&*parent, HINT_BOARDPROPCHANGE, &hint); + GetDocument().UpdateAllViews(&*view, CGmBoxHintWx(HINT_BOARDPROPCHANGE, &hint)); } void CBrdEditView::OnUpdateViewGridLines(wxUpdateUIEvent& pCmdUI) { + pCmdUI.Enable(true); pCmdUI.Check(m_pBoard->GetCellBorder()); } @@ -682,7 +694,7 @@ void CBrdEditView::OnTimer(wxTimerEvent& event) void CBrdEditView::OnSetCursor(wxSetCursorEvent& event) { ToolType eToolType = MapToolType(m_nCurToolID); - wxASSERT(event.GetEventObject() == this); +// wxASSERT(event.GetEventObject() == this); if (event.GetEventObject() == this && eToolType != ttypeUnknown) { CTool& pTool = CTool::GetTool(eToolType); @@ -1240,31 +1252,23 @@ void CBrdEditView::PixelToWorkspace(CPoint& point) const ////////////////////////////////////////////////////////////////////// -void CBrdEditView::OnUpdateColorForeground(wxUpdateUIEvent& pCmdUI) +void CBrdEditView::OnUpdateColorForeground(CColorCmdUI& colorCmdUI) { - CCmdUI* cmdui = static_cast(pCmdUI.GetClientData()); - CColorCmdUI& colorCmdUI = CheckedDeref(dynamic_cast(cmdui)); colorCmdUI.SetColor(CB::Convert(m_pBMgr->GetForeColor())); } -void CBrdEditView::OnUpdateColorBackground(wxUpdateUIEvent& pCmdUI) +void CBrdEditView::OnUpdateColorBackground(CColorCmdUI& colorCmdUI) { - CCmdUI* cmdui = static_cast(pCmdUI.GetClientData()); - CColorCmdUI& colorCmdUI = CheckedDeref(dynamic_cast(cmdui)); colorCmdUI.SetColor(CB::Convert(m_pBMgr->GetBackColor())); } -void CBrdEditView::OnUpdateColorCustom(wxUpdateUIEvent& pCmdUI) +void CBrdEditView::OnUpdateColorCustom(CColorCmdUI& colorCmdUI) { - CCmdUI* cmdui = static_cast(pCmdUI.GetClientData()); - CColorCmdUI& colorCmdUI = CheckedDeref(dynamic_cast(cmdui)); colorCmdUI.SetCustomColors(GetDocument().GetCustomColors()); } -void CBrdEditView::OnUpdateLineWidth(wxUpdateUIEvent& pCmdUI) +void CBrdEditView::OnUpdateLineWidth(CColorCmdUI& colorCmdUI) { - CCmdUI* cmdui = static_cast(pCmdUI.GetClientData()); - CColorCmdUI& colorCmdUI = CheckedDeref(dynamic_cast(cmdui)); colorCmdUI.SetLineWidth(value_preserving_cast(m_pBMgr->GetLineWidth())); } @@ -1385,7 +1389,11 @@ 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")) { @@ -2342,58 +2350,91 @@ void CBrdEditView::RecalcScrollLimits() m_yScrollPixelsPerLine = cellSize.y; } -void CBrdEditViewContainer::OnDraw(CDC* /*pDC*/) -{ - // do nothing because child covers entire client rect +namespace { + CBoard* createParam = nullptr; } -void CBrdEditViewContainer::OnInitialUpdate() +wxBrdEditView* wxBrdEditView::New(CGamDoc& doc, CBoard& board) { - child->OnInitialUpdate(); + wxDocManager& docMgr = CheckedDeref(wxDocManager::GetDocumentManager()); + wxDocTemplate& templ = CB::FindDocTemplateByView(*CLASSINFO(wxBrdEditView)); + + class CreateParamManager + { + public: + CreateParamManager(CBoard& board) + { + wxASSERT(!createParam); + createParam = &board; + } + ~CreateParamManager() + { + createParam = nullptr; + } + } createParamMgr(board); + ::wxView* retval = templ.CreateView(&doc); + wxASSERT(dynamic_cast(retval)); + return static_cast(retval); } -void CBrdEditViewContainer::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint) +CViewFrame& wxBrdEditView::GetFrame() { - child->OnUpdate(pSender, lHint, pHint); + wxWindow& frame = CheckedDeref(GetDocChildFrame()->GetWindow()); + wxASSERT(dynamic_cast(&frame)); + return static_cast(frame); } -void CBrdEditViewContainer::OnActivateView(BOOL bActivate, CView* pActivateView, CView* pDeactiveView) +CBrdEditView& wxBrdEditView::GetWindow() { - CB::OnCmdMsgOverride::OnActivateView(bActivate, pActivateView, pDeactiveView); - - // KLUDGE: often get deactivate w/o activate - if (bActivate) - { - wxActivateEvent event(wxEVT_ACTIVATE, bActivate); - child->ProcessWindowEvent(event); - } + wxWindowList& children = GetFrame().GetChildren(); + wxASSERT(children.size() == size_t(1)); + wxWindow& child = CheckedDeref(children.front()); + wxASSERT(dynamic_cast(&child)); + return static_cast(child); } -CBrdEditViewContainer::CBrdEditViewContainer() : - CB::wxNativeContainerWindowMixin(static_cast(*this)) +bool wxBrdEditView::OnClose(bool /*deleteWindow*/) { + /* doc's life determined by wxGbxProjView, not this, + so bypass wxView::OnClose() */ + return true; } -int CBrdEditViewContainer::OnCreate(LPCREATESTRUCT lpCreateStruct) +bool wxBrdEditView::OnCreate(wxDocument* doc, long flags) { - if (CB::OnCmdMsgOverride::OnCreate(lpCreateStruct) == -1) + if (!wxView::OnCreate(doc, flags)) { - return -1; + return false; } - static_cast(*GetMainFrame()).AddChild(*this); - wxASSERT(static_cast(*this).GetParent() == *GetMainFrame()); + CB::string str = doc->GetUserReadableName(); + str += " - "; + str += CheckedDeref(createParam).GetName(); - child = new CBrdEditView(*this); + CViewFrame* frame = new CViewFrame(doc, + this, + GetMainFrame(), + wxID_ANY, + str); + frame->SetIcon(wxIcon(std::format("#{}", IDR_BOARDVIEW), + wxBITMAP_TYPE_ICO_RESOURCE, + 16, 16)); + /* KLUDGE: giving each frame its own menu + seems to avoid crashes on process close */ + wxXmlResource::Get()->LoadMenuBar(frame, "IDR_GAMEBOX"_cbstring); + new CBrdEditView(*this, *createParam); + frame->Show(); - return 0; + return true; } -// MFC puts the focus here, so move it to the useful window -void CBrdEditViewContainer::OnSetFocus(CWnd* pOldWnd) +void wxBrdEditView::OnUpdate(::wxView* sender, wxObject* hint /*= nullptr*/) { - CB::OnCmdMsgOverride::OnSetFocus(pOldWnd); - child->SetFocus(); + CB::wxView::OnUpdate(sender, hint); + + CGmBoxHintWx& hint2 = dynamic_cast(CheckedDeref(hint)); + GetWindow().OnUpdate(nullptr, hint2.hint, hint2.hintObj); + // WARNING: this might be deleted now! } diff --git a/GM/VwEdtbrd.h b/GM/VwEdtbrd.h index aa1a98b3..657a5746 100644 --- a/GM/VwEdtbrd.h +++ b/GM/VwEdtbrd.h @@ -1,6 +1,6 @@ // VwEdtbrd.h : interface of the CBrdEditView class // -// 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 @@ -32,12 +32,14 @@ #include "ToolObjs.h" #endif -class CBrdEditViewContainer; +class CColorCmdUI; -class CBrdEditView : public wxDocChildFrameAny>, wxWindow> +using CViewFrame = wxDocChildFrameAny; + +class CBrdEditView : public wxScrolledCanvas { -protected: // create from serialization only - CBrdEditView(CBrdEditViewContainer& p); +private: + CBrdEditView(wxView& v, CBoard& b); CB::propagate_const m_pBoard; // Pointer to document's board CB::propagate_const m_pBMgr; @@ -51,6 +53,8 @@ class CBrdEditView : public wxDocChildFrameAny parent; + RefPtr view; + RefPtr parent; RefPtr document; - OwnerPtr wxView = MakeOwner(*this); wxTimer timer; wxOverlay overlay; @@ -317,39 +315,22 @@ class CBrdEditView : public wxDocChildFrameAny, - public CB::wxNativeContainerWindowMixin +class wxBrdEditView : public CB::wxView { public: - const CBrdEditView& GetChild() const { return CheckedDeref(child); } - CBrdEditView& GetChild() - { - return const_cast(std::as_const(*this).GetChild()); - } - void OnDraw(CDC* pDC) override; - void OnInitialUpdate() override; - void OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint) override; - void OnActivateView(BOOL bActivate, CView* pActivateView, CView* pDeactiveView) override; + static wxBrdEditView* New(CGamDoc& doc, CBoard& board); -private: - CBrdEditViewContainer(); // used by dynamic creation - DECLARE_DYNCREATE(CBrdEditViewContainer) + CViewFrame& GetFrame(); + CBrdEditView& GetWindow() override; - afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); - afx_msg void OnSetFocus(CWnd* pOldWnd); - DECLARE_MESSAGE_MAP() + bool OnClose(bool deleteWindow) override; + bool OnCreate(wxDocument* doc, long flags) override; + void OnUpdate(::wxView* sender, wxObject* hint = nullptr) override; - // IGetEvtHandler - wxEvtHandler& Get() override - { - return CheckedDeref(CheckedDeref(child).GetEventHandler()); - } - - // owned by wx - CB::propagate_const child = nullptr; - - friend CBrdEditView; +private: + wxBrdEditView() = default; + wxDECLARE_DYNAMIC_CLASS(wxBrdEditView); }; diff --git a/GM/VwPrjgb1.cpp b/GM/VwPrjgb1.cpp index 97b79e5f..77927e8f 100644 --- a/GM/VwPrjgb1.cpp +++ b/GM/VwPrjgb1.cpp @@ -1,6 +1,6 @@ // VwPrjgb1.cpp : Support file for vwprjgbx.cpp // -// 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 @@ -46,6 +46,8 @@ #include "DlgMedt.h" #include "DlgPEditMulti.h" #include "DlgMEditMulti.h" +#include "FrmBited.h" +#include "VwEdtbrd.h" #include "VwPrjgbx.h" #ifdef _DEBUG @@ -188,18 +190,15 @@ void CGbxProjView::DoBoardEdit() size_t nBrd = m_listProj->GetItemSourceCode(value_preserving_cast(nSel)); CBoard& pBoard = pDoc.GetBoardManager().GetBoard(nBrd); - CView* pView = pDoc.FindBoardEditorView(pBoard); + wxBrdEditView* pView = pDoc.FindBoardEditorView(pBoard); if (pView != NULL) { // This board already has an editor. Activate that view. - CFrameWnd* pFrm = pView->GetParentFrame(); - wxASSERT(pFrm); - pFrm->ActivateFrame(); + pView->GetFrame().Activate(); } else { - CB::string strTitle = m_listProj->GetItemText(value_preserving_cast(nSel)); - pDoc.CreateNewFrame(CheckedDeref(GetApp()->m_pMapViewTmpl), strTitle, &pBoard); + wxBrdEditView::New(pDoc, pBoard); } } @@ -303,8 +302,7 @@ void CGbxProjView::DoTileNew() CGmBoxHint hint; hint.GetArgs().m_tid = tidNew; pDoc.UpdateAllViews(NULL, HINT_TILECREATED, &hint); - pDoc.CreateNewFrame(CheckedDeref(GetApp()->m_pTileEditTmpl), "Tile Editor", - reinterpret_cast(value_preserving_cast(tidNew))); + wxBitEditView::New(pDoc, tidNew); pDoc.SetModifiedFlag(); } } @@ -325,18 +323,15 @@ void CGbxProjView::DoTileEdit() { TileID tid = tidtbl[i]; - CView *pView = pDoc.FindTileEditorView(tid); - if (pView) + wxBitEditView* pView = pDoc.FindTileEditorView(tid); + if (pView != NULL) { // Already has an editor. Activate that view. - CFrameWnd* pFrm = pView->GetParentFrame(); - wxASSERT(pFrm); - pFrm->ActivateFrame(); + pView->GetFrame().Activate(); } else { - pDoc.CreateNewFrame(CheckedDeref(GetApp()->m_pTileEditTmpl), "Tile Editor", - reinterpret_cast(value_preserving_cast(tid))); + wxBitEditView::New(pDoc, tid); } } } @@ -378,8 +373,7 @@ void CGbxProjView::DoTileClone() hint.GetArgs().m_tid = tidNew; pDoc.UpdateAllViews(NULL, HINT_TILECREATED, &hint); - pDoc.CreateNewFrame(CheckedDeref(GetApp()->m_pTileEditTmpl), "Tile Editor", - reinterpret_cast(value_preserving_cast(tidNew))); + wxBitEditView::New(pDoc, tidNew); } pDoc.SetModifiedFlag(); diff --git a/GM/VwPrjgbx.cpp b/GM/VwPrjgbx.cpp index 1f999b2b..deb86b9b 100644 --- a/GM/VwPrjgbx.cpp +++ b/GM/VwPrjgbx.cpp @@ -1,6 +1,6 @@ // VwPrjgbx.cpp : implementation file // -// 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 @@ -41,8 +41,8 @@ static char THIS_FILE[] = __FILE__; #endif -wxIMPLEMENT_DYNAMIC_CLASS(CProjListBoxGm, CGrafixListBoxWx) -IMPLEMENT_DYNCREATE(CGbxProjViewContainer, CView) +wxIMPLEMENT_DYNAMIC_CLASS(CProjListBoxGm, CGrafixListBoxWx); +wxIMPLEMENT_DYNAMIC_CLASS(wxGbxProjView, wxView); #ifdef _DEBUG #define new DEBUG_NEW @@ -103,10 +103,7 @@ static UINT * btnGroupTbl[nNumGroups + 1] = ///////////////////////////////////////////////////////////////////////////// -namespace { - typedef wxDocChildFrameAny, wxWindow> NoCommas; -} -wxBEGIN_EVENT_TABLE(CGbxProjView, NoCommas) +wxBEGIN_EVENT_TABLE(CGbxProjView, wxPanel) #if 0 ON_WM_SIZE() ON_WM_CREATE() @@ -164,16 +161,11 @@ wxBEGIN_EVENT_TABLE(CGbxProjView, NoCommas) EVT_GET_DRAG_SIZE(OnGetDragSize) wxEND_EVENT_TABLE() -BEGIN_MESSAGE_MAP(CGbxProjViewContainer, CView) - ON_WM_CREATE() - ON_WM_SETFOCUS() -END_MESSAGE_MAP() - ///////////////////////////////////////////////////////////////////////////// // CGbxProjView -CGbxProjView::CGbxProjView(CGbxProjViewContainer& p) : - CB_XRC_BEGIN_CTRLS_DEFN(static_cast(p), CGbxProjView) +CGbxProjView::CGbxProjView(wxView& v) : + CB_XRC_BEGIN_CTRLS_DEFN(v.GetFrame(), CGbxProjView) CB_XRC_CTRL(m_listProj) CB_XRC_CTRL(m_editInfo) CB_XRC_CTRL(m_listTiles) @@ -186,8 +178,9 @@ CGbxProjView::CGbxProjView(CGbxProjViewContainer& p) : CB_XRC_CTRL(m_btnItmC) CB_XRC_CTRL(m_btnItmD) CB_XRC_END_CTRLS_DEFN(), - parent(&p), - document(CB::ToCGamDoc(parent->GetDocument())) + view(&v), + parent(view->GetFrame()), + document(dynamic_cast(view->GetDocument())) { m_nLastSel = -1; m_nLastGrp = -1; @@ -196,8 +189,6 @@ CGbxProjView::CGbxProjView(CGbxProjViewContainer& p) : m_listTiles->EnableDrag(); m_listTiles->EnableSelfDrop(); m_listTiles->EnableDropScroll(); - wxView->SetDocument(&*document); - wxView->SetFrame(this); } CGbxProjView::~CGbxProjView() @@ -277,14 +268,12 @@ int CGbxProjView::OnCreate(LPCREATESTRUCT lpCreateStruct) void CGbxProjView::OnInitialUpdate() { - CB_VERIFY(Create(&GetDocument(), &*wxView, *GetMainFrame(), wxID_ANY, "dummy")); - m_listTiles->SetDocument(&GetDocument()); m_listPieces->SetDocument(GetDocument()); m_listMarks->SetDocument(&GetDocument()); } -void CGbxProjView::OnUpdate(CView* /*pSender*/, LPARAM /*lHint*/, CObject* /*pHint*/) +void CGbxProjView::OnUpdate() { DoUpdateProjectList(); } @@ -1421,75 +1410,111 @@ void CGbxProjView::OnUpdateMarkerDelete(wxUpdateUIEvent& pCmdUI) pCmdUI.Enable(m_listMarks->GetSelectedCount() >= 0); } -#if 0 -void CGbxProjViewContainer::OnActivateView(BOOL bActivate, - CView* pActivateView, - CView* /*pDeactiveView*/) -{ - WXUNUSED_UNLESS_DEBUG(pActivateView); - if (bActivate) - { - wxASSERT(pActivateView == this); - GetParentFrame()->SetActiveView(&*child); - } -} -#endif - -void CGbxProjViewContainer::OnDraw(CDC* /*pDC*/) +const CDocFrame& wxGbxProjView::GetFrame() const { - // do nothing because child covers entire client rect + const wxWindow& frame = CheckedDeref(GetDocChildFrame()->GetWindow()); + return dynamic_cast(frame); } -void CGbxProjViewContainer::OnInitialUpdate() +CGbxProjView& wxGbxProjView::GetWindow() { - child->OnInitialUpdate(); - - CB::OnCmdMsgOverride::OnInitialUpdate(); + wxWindowList& children = GetFrame().GetChildren(); + wxASSERT(children.size() == size_t(1)); + wxWindow& child = CheckedDeref(children.front()); + wxASSERT(dynamic_cast(&child)); + return static_cast(child); } -void CGbxProjViewContainer::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint) +bool wxGbxProjView::OnClose(bool deleteWindow) { - child->OnUpdate(pSender, lHint, pHint); - - CB::OnCmdMsgOverride::OnUpdate(pSender, lHint, pHint); -} - -void CGbxProjViewContainer::OnActivateView(BOOL bActivate, CView* pActivateView, CView* pDeactiveView) -{ - CB::OnCmdMsgOverride::OnActivateView(bActivate, pActivateView, pDeactiveView); + if (wxView::OnClose(deleteWindow)) + { + /* can't draw w/ doc gone, + but load failure doesn't create wnd */ + if (HasWindow()) + { + GetWindow().Hide(); + } + wxMenuBar& menubar = CheckedDeref(GetFrame().GetMenuBar()); + wxMenu& menuFile = CheckedDeref(menubar.GetMenu(size_t(0))); + wxDocManager& docMgr = CheckedDeref(wxDocManager::GetDocumentManager()); + docMgr.FileHistoryRemoveMenu(&menuFile); + + /* CB defines doc's life only by proj view, + so delete rest */ + wxViewVector views = GetDocument()->GetViewsVector(); + for (auto it = views.begin() ; it != views.end() ; ++it) + { + ::wxView* view = *it; + if (view != this) + { + delete view; + } + } - // KLUDGE: often get deactivate w/o activate - if (bActivate) + return true; + } + else { - wxActivateEvent event(wxEVT_ACTIVATE, bActivate); - child->ProcessWindowEvent(event); + return false; } } -CGbxProjViewContainer::CGbxProjViewContainer() : - CB::wxNativeContainerWindowMixin(static_cast(*this)) +bool wxGbxProjView::OnCreate(wxDocument* doc, long flags) { -} - -int CGbxProjViewContainer::OnCreate(LPCREATESTRUCT lpCreateStruct) -{ - if (CView::OnCreate(lpCreateStruct) == -1) + if (!wxView::OnCreate(doc, flags)) { - return -1; + return false; } - static_cast(*GetMainFrame()).AddChild(*this); - wxASSERT(static_cast(*this).GetParent() == *GetMainFrame()); + CB::string str = doc->GetUserReadableName(); + str += " - "; + str += CB::string::LoadString(IDS_PROJTYPE_GAMEBOX); + + CDocFrame* frame = new CDocFrame(doc, + this, + GetMainFrame(), + wxID_ANY, + str); + frame->SetIcon(wxIcon(std::format("#{}", IDR_GAMEBOX), + wxBITMAP_TYPE_ICO_RESOURCE, + 16, 16)); + /* KLUDGE: giving each frame its own menu + seems to avoid crashes on process close */ + wxMenuBar& menubar = CheckedDeref(wxXmlResource::Get()->LoadMenuBar(frame, "IDR_GAMEBOX"_cbstring)); + wxMenu& menuFile = CheckedDeref(menubar.GetMenu(size_t(0))); + wxDocManager& docMgr = CheckedDeref(wxDocManager::GetDocumentManager()); + docMgr.FileHistoryUseMenu(&menuFile); + docMgr.FileHistoryAddFilesToMenu(&menuFile); + /* postpone because this gets called before OnOpenDocument() + new CGbxProjView(*this); + frame->Show(); + */ + + return true; +} + +void wxGbxProjView::OnUpdate(::wxView* sender, wxObject* hint /*= nullptr*/) +{ + CGmBoxHintWx* gbxHint = dynamic_cast(hint); + if (gbxHint && gbxHint->hint == HINT_DOCREADY) + { + new CGbxProjView(*this); + GetFrame().Show(); + GetWindow().OnInitialUpdate(); + isDocReady = true; + } - child = new CGbxProjView(*this); + CB::wxView::OnUpdate(sender, hint); - return 0; + if (isDocReady) + { + GetWindow().OnUpdate(); + } } -// MFC puts the focus here, so move it to the useful window -void CGbxProjViewContainer::OnSetFocus(CWnd* pOldWnd) +bool wxGbxProjView::HasWindow() const { - CView::OnSetFocus(pOldWnd); - child->SetFocus(); + return !GetFrame().GetChildren().empty(); } diff --git a/GM/VwPrjgbx.h b/GM/VwPrjgbx.h index c553dacc..5dda2872 100644 --- a/GM/VwPrjgbx.h +++ b/GM/VwPrjgbx.h @@ -1,6 +1,6 @@ // VwPrjgbx.h : header file // -// 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 @@ -43,6 +43,8 @@ #include "LBoxMark.h" #endif +using CDocFrame = wxDocChildFrameAny; + ///////////////////////////////////////////////////////////////////////////// // CGbxProjView view @@ -73,12 +75,10 @@ class CProjListBoxGm : public CProjListBoxWx, wxWindow>, private CB::Impl::CGbxProjViewBase +class CGbxProjView : public wxPanel, private CB::Impl::CGbxProjViewBase { protected: - CGbxProjView(CGbxProjViewContainer& p); + CGbxProjView(wxView& v); // Attributes public: @@ -176,7 +176,7 @@ class CGbxProjView : public wxDocChildFrameAny, wxWindo protected: ~CGbxProjView() override; void OnInitialUpdate(); - void OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint); + void OnUpdate(); #if 0 void OnDraw(CDC* pDC) override; // overridden to draw this view @@ -248,45 +248,33 @@ class CGbxProjView : public wxDocChildFrameAny, wxWindo wxDECLARE_EVENT_TABLE(); private: - RefPtr parent; + RefPtr view; + RefPtr parent; RefPtr document; - OwnerPtr wxView = MakeOwner(*this); - friend class CGbxProjViewContainer; + friend class wxGbxProjView; }; -class CGbxProjViewContainer : public CB::OnCmdMsgOverride, - public CB::wxNativeContainerWindowMixin +class wxGbxProjView : public CB::wxView { public: - const CGbxProjView& GetChild() const { return CheckedDeref(child); } - CGbxProjView& GetChild() + const CDocFrame& GetFrame() const; + CDocFrame& GetFrame() { - return const_cast(std::as_const(*this).GetChild()); + return const_cast(std::as_const(*this).GetFrame()); } - void OnDraw(CDC* pDC) override; - void OnInitialUpdate() override; - void OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint) override; - void OnActivateView(BOOL bActivate, CView* pActivateView, CView* pDeactiveView) override; + CGbxProjView& GetWindow() override; -private: - CGbxProjViewContainer(); // used by dynamic creation - DECLARE_DYNCREATE(CGbxProjViewContainer) - - afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); - afx_msg void OnSetFocus(CWnd* pOldWnd); - DECLARE_MESSAGE_MAP() + bool OnClose(bool deleteWindow) override; + bool OnCreate(wxDocument* doc, long flags) override; + void OnUpdate(::wxView* sender, wxObject* hint = nullptr) override; - // IGetEvtHandler - wxEvtHandler& Get() override - { - return CheckedDeref(CheckedDeref(child).GetEventHandler()); - } - - // owned by wx - CB::propagate_const child = nullptr; +private: + wxGbxProjView() = default; + wxDECLARE_DYNAMIC_CLASS(wxGbxProjView); + bool HasWindow() const; - friend CGbxProjView; + bool isDocReady = false; }; ///////////////////////////////////////////////////////////////////////////// diff --git a/GM/VwTilesl.cpp b/GM/VwTilesl.cpp index bf7dfc19..be142551 100644 --- a/GM/VwTilesl.cpp +++ b/GM/VwTilesl.cpp @@ -1,6 +1,6 @@ // VwTilesl.cpp : implementation file // -// 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 @@ -27,6 +27,7 @@ #include "GmDoc.h" #include "CDib.h" #include "VwTilesl.h" +#include "FrmBited.h" #include "VwBitedt.h" #include "DlgTilsz.h" #include "FrmMain.h" // TODO: remove? @@ -43,77 +44,30 @@ const int nBorderWidth = 5; ///////////////////////////////////////////////////////////////////////////// // CTileSelView -IMPLEMENT_DYNCREATE(CTileSelViewContainer, CView) - -CTileSelView::CTileSelView(CTileSelViewContainer& p) : +CTileSelView::CTileSelView(wxSplitterWindow& p, + wxBitEditView& v, + TileID tid) : + m_tid(tid), parent(&p), - document(CB::ToCGamDoc(parent->GetDocument())) + document(&v.GetDocument()), + view(&v) { m_pTileMgr = NULL; m_pEditView = NULL; - m_tid = nullTid; m_bNoUpdate = FALSE; - wxScrolledCanvas::Create(*parent, 0); - wxView->SetDocument(&*document); - wxView->SetFrame(this); + wxScrolledCanvas::Create(&*parent, 0); } -namespace { - typedef wxDocChildFrameAny, wxWindow> NoCommas; -} -wxBEGIN_EVENT_TABLE(CTileSelView, NoCommas) +wxBEGIN_EVENT_TABLE(CTileSelView, wxScrolledCanvas) EVT_LEFT_DOWN(OnLButtonDown) wxEND_EVENT_TABLE() -BEGIN_MESSAGE_MAP(CTileSelViewContainer, CView) - ON_WM_CREATE() - ON_MESSAGE(WM_SETCOLOR, OnSetColor) - ON_MESSAGE(WM_SETCUSTOMCOLOR, OnSetCustomColors) - ON_MESSAGE(WM_SETLINEWIDTH, OnSetLineWidth) - ON_UPDATE_COMMAND_UI(ID_COLOR_FOREGROUND, OnUpdateColorForeground) - ON_UPDATE_COMMAND_UI(ID_COLOR_BACKGROUND, OnUpdateColorBackground) - ON_UPDATE_COMMAND_UI(ID_COLOR_TRANSPARENT, OnUpdateColorTransparent) - ON_UPDATE_COMMAND_UI(ID_COLOR_CUSTOM, OnUpdateColorCustom) - ON_UPDATE_COMMAND_UI(ID_LINE_WIDTH, OnUpdateLineWidth) - ON_UPDATE_COMMAND_UI(ID_ITOOL_PENCIL, OnUpdateToolPalette) - ON_COMMAND_EX(ID_ITOOL_SELECT, OnToolPalette) - ON_COMMAND(ID_EDIT_PASTE, OnEditPaste) - ON_UPDATE_COMMAND_UI(ID_EDIT_PASTE, OnUpdateEditPaste) - ON_COMMAND(ID_EDIT_UNDO, OnEditUndo) - ON_UPDATE_COMMAND_UI(ID_EDIT_UNDO, OnUpdateEditUndo) - ON_COMMAND(ID_EDIT_COPY, OnEditCopy) - ON_UPDATE_COMMAND_UI(ID_EDIT_COPY, OnUpdateEditCopy) - ON_COMMAND_EX(ID_ITOOL_BRUSH, OnToolPalette) - ON_COMMAND_EX(ID_ITOOL_FILL, OnToolPalette) - ON_COMMAND_EX(ID_ITOOL_TEXT, OnToolPalette) - ON_COMMAND_EX(ID_ITOOL_LINE, OnToolPalette) - ON_COMMAND_EX(ID_ITOOL_RECT, OnToolPalette) - ON_COMMAND_EX(ID_ITOOL_OVAL, OnToolPalette) - ON_COMMAND_EX(ID_ITOOL_FILLRECT, OnToolPalette) - ON_COMMAND_EX(ID_ITOOL_FILLOVAL, OnToolPalette) - ON_COMMAND_EX(ID_ITOOL_DROPPER, OnToolPalette) - ON_UPDATE_COMMAND_UI(ID_ITOOL_SELECT, OnUpdateToolPalette) - ON_UPDATE_COMMAND_UI(ID_ITOOL_BRUSH, OnUpdateToolPalette) - ON_UPDATE_COMMAND_UI(ID_ITOOL_FILL, OnUpdateToolPalette) - ON_UPDATE_COMMAND_UI(ID_ITOOL_TEXT, OnUpdateToolPalette) - ON_UPDATE_COMMAND_UI(ID_ITOOL_LINE, OnUpdateToolPalette) - ON_UPDATE_COMMAND_UI(ID_ITOOL_RECT, OnUpdateToolPalette) - ON_UPDATE_COMMAND_UI(ID_ITOOL_OVAL, OnUpdateToolPalette) - ON_UPDATE_COMMAND_UI(ID_ITOOL_FILLRECT, OnUpdateToolPalette) - ON_UPDATE_COMMAND_UI(ID_ITOOL_FILLOVAL, OnUpdateToolPalette) - ON_UPDATE_COMMAND_UI(ID_ITOOL_DROPPER, OnUpdateToolPalette) - ON_COMMAND(ID_VIEW_TOGGLE_SCALE, OnViewToggleScale) -END_MESSAGE_MAP() - ///////////////////////////////////////////////////////////////////////////// void CTileSelView::OnInitialUpdate() { - CB_VERIFY(Create(&GetDocument(), &*wxView, *GetMainFrame(), wxID_ANY, "dummy")); - m_pTileMgr = &GetDocument().GetTileManager(); - m_tid = static_cast(reinterpret_cast(GetDocument().GetCreateParameter())); - ASSERT(m_tid != nullTid); + wxASSERT(m_tid != nullTid); // Fetch full scale tile CTile tile = m_pTileMgr->GetTile(m_tid, fullScale); @@ -153,24 +107,31 @@ void CTileSelView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint) if (static_cast(pHint)->GetArgs().m_tid == m_tid) { m_bNoUpdate = TRUE; - CFrameWnd* pFrm = parent->GetParentFrame(); - ASSERT(pFrm != NULL); - pFrm->PostMessage(WM_CLOSE, 0, 0L); + // close this view + /* can't delete now + because iterator in caller would be invalidated */ + wxTheApp->ScheduleForDestruction(&*view); } } else if (wHint == HINT_TILESETDELETED && !m_pTileMgr->IsTileIDValid(m_tid)) { m_bNoUpdate = TRUE; - CFrameWnd* pFrm = parent->GetParentFrame(); - ASSERT(pFrm != NULL); - pFrm->PostMessage(WM_CLOSE, 0, 0L); + // close this view + /* can't delete now + because iterator in caller would be invalidated */ + wxTheApp->ScheduleForDestruction(&*view); } else if (wHint == HINT_FORCETILEUPDATE) { UpdateDocumentTiles(); } else if (wHint == HINT_ALWAYSUPDATE) + { + wxASSERT(!"untested code"); +#if 0 parent->CView::OnUpdate(pSender, lHint, pHint); +#endif + } } ///////////////////////////////////////////////////////////////////////////// @@ -271,7 +232,7 @@ void CTileSelView::UpdateDocumentTiles() // Finally handle various notifications CGmBoxHint hint; hint.GetArgs().m_tid = m_tid; - pDoc.UpdateAllViews(&*parent, HINT_TILEMODIFIED, &hint); + pDoc.UpdateAllViews(&*view, CGmBoxHintWx(HINT_TILEMODIFIED, &hint)); pDoc.SetModifiedFlag(); } @@ -508,210 +469,3 @@ CTileSelView::~CTileSelView() UpdateDocumentTiles(); } } - -///////////////////////////////////////////////////////////////////////////// -// CTileSelView command handlers -// Hot potato most of these to the editor view. - -LRESULT CTileSelViewContainer::OnSetColor(WPARAM wParam, LPARAM lParam) -{ - wxASSERT(!"unreachable code?"); -#if 0 - return child->GetBitEditor().OnSetColor(wParam, lParam); -#else - return 0; -#endif -} - -LRESULT CTileSelViewContainer::OnSetCustomColors(WPARAM wParam, LPARAM lParam) -{ - wxASSERT(!"unreachable code?"); -#if 0 - return child->GetBitEditor().OnSetCustomColors(wParam, lParam); -#else - return 0; -#endif -} - -LRESULT CTileSelViewContainer::OnSetLineWidth(WPARAM wParam, LPARAM lParam) -{ - wxASSERT(!"unreachable code?"); -#if 0 - return child->GetBitEditor().OnSetLineWidth(wParam, lParam); -#else - return 0; -#endif -} - -void CTileSelViewContainer::OnUpdateColorForeground(CCmdUI* pCmdUI) -{ - wxASSERT(!"unreachable code?"); -#if 0 - child->GetBitEditor().OnUpdateColorForeground(pCmdUI); -#endif -} - -void CTileSelViewContainer::OnUpdateColorBackground(CCmdUI* pCmdUI) -{ - wxASSERT(!"unreachable code?"); -#if 0 - child->GetBitEditor().OnUpdateColorBackground(pCmdUI); -#endif -} - -void CTileSelViewContainer::OnUpdateColorTransparent(CCmdUI* pCmdUI) -{ - wxASSERT(!"unreachable code?"); -#if 0 - child->GetBitEditor().OnUpdateColorTransparent(pCmdUI); -#endif -} - -void CTileSelViewContainer::OnUpdateColorCustom(CCmdUI* pCmdUI) -{ - wxASSERT(!"unreachable code?"); -#if 0 - child->GetBitEditor().OnUpdateColorCustom(pCmdUI); -#endif -} - -void CTileSelViewContainer::OnUpdateLineWidth(CCmdUI* pCmdUI) -{ - wxASSERT(!"unreachable code?"); -#if 0 - child->GetBitEditor().OnUpdateLineWidth(pCmdUI); -#endif -} - -void CTileSelViewContainer::OnUpdateToolPalette(CCmdUI* pCmdUI) -{ - wxASSERT(!"unreachable code?"); -#if 0 - child->GetBitEditor().OnUpdateToolPalette(pCmdUI); -#endif -} - -BOOL CTileSelViewContainer::OnToolPalette(UINT id) -{ - wxASSERT(!"unreachable code?"); -#if 0 - return child->GetBitEditor().OnToolPalette(id); -#else - return 0; -#endif -} - -void CTileSelViewContainer::OnEditPaste() -{ - wxASSERT(!"unreachable code?"); -#if 0 - child->GetBitEditor().OnEditPaste(); -#endif -} - -void CTileSelViewContainer::OnUpdateEditPaste(CCmdUI* pCmdUI) -{ - wxASSERT(!"unreachable code?"); -#if 0 - child->GetBitEditor().OnUpdateEditPaste(pCmdUI); -#endif -} - -void CTileSelViewContainer::OnEditCopy() -{ - wxASSERT(!"unreachable code?"); -#if 0 - child->GetBitEditor().OnEditCopy(); -#endif -} - -void CTileSelViewContainer::OnUpdateEditCopy(CCmdUI* pCmdUI) -{ - wxASSERT(!"unreachable code?"); -#if 0 - child->GetBitEditor().OnUpdateEditCopy(pCmdUI); -#endif -} - -void CTileSelViewContainer::OnEditUndo() -{ - wxASSERT(!"unreachable code?"); -#if 0 - if (child->IsUndoAvailable()) // Us first. - child->RestoreFromUndo(); - else - child->GetBitEditor().OnEditUndo(); -#endif -} - -void CTileSelViewContainer::OnUpdateEditUndo(CCmdUI* pCmdUI) -{ - wxASSERT(!"unreachable code?"); -#if 0 - if (child->IsUndoAvailable()) // Us first. - pCmdUI->Enable(TRUE); - else - child->GetBitEditor().OnUpdateEditUndo(pCmdUI); -#endif -} - -void CTileSelViewContainer::OnViewToggleScale() -{ - wxASSERT(!"unreachable code?"); -#if 0 - child->GetBitEditor().OnViewToggleScale(); -#endif -} - -void CTileSelViewContainer::OnDraw(CDC* pDC) -{ - // do nothing because child covers entire client rect -} - -void CTileSelViewContainer::OnInitialUpdate() -{ - child->OnInitialUpdate(); -} - -void CTileSelViewContainer::OnActivateView(BOOL bActivate, - CView* pActivateView, - CView* /*pDeactiveView*/) -{ - WXUNUSED_UNLESS_DEBUG(pActivateView); - if (bActivate) - { - wxASSERT(pActivateView == this); - CBitEditView& bitEdit = child->GetBitEditor(); - wxWindow& bitEditParent = CheckedDeref(bitEdit.GetParent()); - CView& view = CheckedDeref(dynamic_cast(CB::ToCWnd(bitEditParent))); - GetParentFrame()->SetActiveView(&view); - - wxActivateEvent event(wxEVT_ACTIVATE, bActivate); - bitEdit.ProcessWindowEvent(event); - } -} - -void CTileSelViewContainer::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint) -{ - child->OnUpdate(pSender, lHint, pHint); -} - -CTileSelViewContainer::CTileSelViewContainer() : - CB::wxNativeContainerWindowMixin(static_cast(*this)) -{ -} - -int CTileSelViewContainer::OnCreate(LPCREATESTRUCT lpCreateStruct) -{ - if (CView::OnCreate(lpCreateStruct) == -1) - { - return -1; - } - - static_cast(*GetMainFrame()).AddChild(*this); - wxASSERT(static_cast(*this).GetParent() == *GetMainFrame()); - - child = new CTileSelView(*this); - - return 0; -} diff --git a/GM/VwTilesl.h b/GM/VwTilesl.h index 20ba3cd8..fe7c19cd 100644 --- a/GM/VwTilesl.h +++ b/GM/VwTilesl.h @@ -1,6 +1,6 @@ // VwTilesl.h : header file // -// 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 @@ -33,15 +33,16 @@ // CTileSelView view class CBitEditView; -class CTileSelViewContainer; +class wxBitEditView; -class CTileSelView : public wxDocChildFrameAny, wxWindow> +class CTileSelView : public wxScrolledCanvas { friend class CBitEditFrame; - friend class CTileSelViewContainer; protected: // single-part construction - CTileSelView(CTileSelViewContainer& parent); + CTileSelView(wxSplitterWindow& parent, + wxBitEditView& view, + TileID tid); // Attributes public: @@ -70,7 +71,7 @@ class CTileSelView : public wxDocChildFrameAny protected: BOOL m_bNoUpdate; // TRUE if should discard changes - TileID m_tid; + const TileID m_tid; wxBitmap m_pBmFullUndo; // Save from previous resize wxBitmap m_pBmHalfUndo; // Save from previous resize @@ -116,57 +117,9 @@ class CTileSelView : public wxDocChildFrameAny wxDECLARE_EVENT_TABLE(); private: - RefPtr parent; + RefPtr parent; RefPtr document; - OwnerPtr wxView = MakeOwner(*this); -}; - -class CTileSelViewContainer : public CView, - public CB::wxNativeContainerWindowMixin -{ -public: - const CTileSelView& GetChild() const { return CheckedDeref(child); } - CTileSelView& GetChild() - { - return const_cast(std::as_const(*this).GetChild()); - } - void OnDraw(CDC* pDC) override; - void OnInitialUpdate() override; - -protected: - void OnActivateView(BOOL bActivate, - CView* pActivateView, - CView* pDeactiveView) override; - void OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint) override; - -private: - CTileSelViewContainer(); // used by dynamic creation - DECLARE_DYNCREATE(CTileSelViewContainer) - - afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); - afx_msg LRESULT OnSetColor(WPARAM wParam, LPARAM lParam); - afx_msg LRESULT OnSetCustomColors(WPARAM wParam, LPARAM lParam); - afx_msg LRESULT OnSetLineWidth(WPARAM wParam, LPARAM lParam); - afx_msg void OnUpdateColorForeground(CCmdUI* pCmdUI); - afx_msg void OnUpdateColorBackground(CCmdUI* pCmdUI); - afx_msg void OnUpdateColorTransparent(CCmdUI* pCmdUI); - afx_msg void OnUpdateColorCustom(CCmdUI* pCmdUI); - afx_msg void OnUpdateLineWidth(CCmdUI* pCmdUI); - afx_msg void OnUpdateToolPalette(CCmdUI* pCmdUI); - afx_msg BOOL OnToolPalette(UINT id); - afx_msg void OnEditPaste(); - afx_msg void OnUpdateEditPaste(CCmdUI* pCmdUI); - afx_msg void OnEditUndo(); - afx_msg void OnUpdateEditUndo(CCmdUI* pCmdUI); - afx_msg void OnEditCopy(); - afx_msg void OnUpdateEditCopy(CCmdUI* pCmdUI); - afx_msg void OnViewToggleScale(); - DECLARE_MESSAGE_MAP() - - // owned by wx - CB::propagate_const child = nullptr; - - friend CTileSelView; + RefPtr view; }; ///////////////////////////////////////////////////////////////////////////// diff --git a/GM/Resource.h b/GM/resource.h similarity index 100% rename from GM/Resource.h rename to GM/resource.h diff --git a/GP/res/manifest.xml b/GP/res/manifest.xml index 2517a6df..b9c10ae2 100644 --- a/GP/res/manifest.xml +++ b/GP/res/manifest.xml @@ -4,7 +4,7 @@ processorArchitecture="x86" version="5.1.0.0" type="win32" - name="CBDesign" + name="CBPlay" /> CyberBoard Player Program diff --git a/GP/Resource.h b/GP/resource.h similarity index 100% rename from GP/Resource.h rename to GP/resource.h diff --git a/GShr/CyberBoard.h b/GShr/CyberBoard.h index 348399e7..7202ede8 100644 --- a/GShr/CyberBoard.h +++ b/GShr/CyberBoard.h @@ -1,6 +1,6 @@ // CyberBoard.h // -// Copyright (c) 2020-2024 By William Su, All Rights Reserved. +// Copyright (c) 2020-2025 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 @@ -63,11 +63,14 @@ #include +#include +#include #include #include #include #include #include +#include #include #include #include @@ -87,12 +90,15 @@ #include #include #include +#include +#include #include #include #include #include #include #include +#include #include #include #include @@ -349,6 +355,24 @@ struct std::formatter : private std::formatter T, typename CharT> +struct std::formatter : private std::formatter +{ +private: + using BASE = formatter; +public: + using BASE::parse; + + template + FormatContext::iterator format(const wxObject& o, FormatContext& ctx) const + { + return std::format_to(ctx.out(), + "{}({})", + typeid(o).name(), + static_cast(&o)); + } +}; + template struct std::formatter : private std::formatter().Red()), CharT> { @@ -1900,6 +1924,7 @@ static_assert(std::is_same_v::iterator::difference_type, ptrdif // adapt between CWnd and wxWindow namespace CB { +#if 0 class wxNativeContainerWindowMixin { public: @@ -1935,20 +1960,24 @@ namespace CB /* if mfcWnd or one of its descendants has wxNativeContainerWindowMixin, return it */ wxWindow* FindWxWindow(CWnd& mfcWnd); +#endif // emulate CWnd::SendMessageToDescendants() void SendEventToDescendants(wxWindow& wnd, wxEvent& event, bool deep = true); +#if 0 const CWnd* ToCWnd(const wxWindow& w); inline CWnd* ToCWnd(wxWindow& w) { return const_cast(ToCWnd(std::as_const(w))); } // MFC if possible, wx otherwise const std::type_info& GetPublicTypeid(const wxWindow& w); +#endif } // helpers for providing wx/docview namespace CB { +#if 0 // satisfy wxDocChildFrameAny<> requirements template class PseudoFrame : public BASE @@ -1973,15 +2002,15 @@ namespace CB /* wxView must be separate from wxWindow (see https://groups.google.com/g/wx-dev/c/xMK4zYT3FFQ/m/kR9JmczbBAAJ) */ - class wxView : public ::wxView + class wxView_deprecated : public ::wxView { public: - wxView(wxWindow& v) : + wxView_deprecated(wxWindow& v) : window(&v) { } - ~wxView() + ~wxView_deprecated() { // wnd dtor deletes this, so avoid wx trying to delete wnd SetDocChildFrame(nullptr); @@ -1996,6 +2025,27 @@ namespace CB private: RefPtr window; }; +#endif + + /* wxView must be separate from wxWindow + (see https://groups.google.com/g/wx-dev/c/xMK4zYT3FFQ/m/kR9JmczbBAAJ) */ + /* wx passes events to wxView, but, for historical reasons, all + of our event handlers are in the corresponding wxWindow, + so use this class as an adapter */ + class wxView : public ::wxView + { + public: + virtual wxWindow& GetWindow() = 0; + + void OnDraw(wxDC* dc) override; + + protected: + // this one is called before trying our own event table to allow plugging + // in the event handlers overriding the default logic, this is used by e.g. + // validators. + // for CB, forward events to window here + bool TryBefore(wxEvent& event) override; + }; } // CGamDoc is currently a wxDoc in GM, CDoc in GP, so need workaround @@ -2015,7 +2065,8 @@ namespace CB CWinApp& CbGetApp(); namespace CB { - wxNativeContainerWindow& GetMainWndWx(); + wxWindow* pGetMainWndWx(); + inline wxWindow& GetMainWndWx() { return CheckedDeref(pGetMainWndWx()); } string GetAppName(); } @@ -2275,6 +2326,7 @@ namespace CB void InflateAndNormalize(wxRect& rect, int dx, int dy); } +#if 0 // use these to translate and relay MFC messages to a wx target namespace CB { @@ -2356,6 +2408,7 @@ namespace CB } }; } +#endif namespace CB { @@ -2458,6 +2511,78 @@ namespace CB int GetMouseButtons(const wxMouseState& event); } +namespace CB +{ + wxDocTemplate& FindDocTemplateByView(const wxClassInfo& classInfo); +} + +namespace CB +{ + struct ToolArgs + { + const int xrcId; + const unsigned stringId = 0; + const wxItemKind kind = wxITEM_NORMAL; + }; + wxAuiToolBar& CreateToolbar(wxWindow& parent, const ToolArgs (&toolArgs)[], size_t count, unsigned bmapID); + + // tell compiler to count array elements + template + wxAuiToolBar& CreateToolbar(wxWindow& parent, const ToolArgs (&toolArgs)[COUNT], unsigned bmapID) + { + return CreateToolbar(parent, toolArgs, COUNT, bmapID); + } +} + +namespace CB +{ + /* emulate MFC support for displaying + CAPS lock and NUM lock indicators */ + class wxStatusBar : public ::wxStatusBar + { + public: + using ::wxStatusBar::wxStatusBar; + + void SetIndicators(const int (&ids)[], + size_t count); + + template + void SetIndicators(const int (&ids)[COUNT]) + { + SetIndicators(ids, COUNT); + } + + private: + void OnIdle(wxIdleEvent& event); + void OnUpdateUI(wxUpdateUIEvent& event); + wxDECLARE_EVENT_TABLE(); + + std::vector indicators; + }; + + // create CB::wxStatusBar instead of ::wxStatusBar + class wxAuiMDIParentFrame : public ::wxAuiMDIParentFrame + { + public: + using ::wxAuiMDIParentFrame::wxAuiMDIParentFrame; + + wxStatusBar& CreateStatusBar(const int (&ids)[], + size_t count); + + template + wxStatusBar& CreateStatusBar(const int (&ids)[COUNT]) + { + return CreateStatusBar(ids, COUNT); + } + + // return a new status bar + wxStatusBar* OnCreateStatusBar(int number, + long style, + wxWindowID winid, + const wxString& name) override; + }; +} + // replacement for wxDC::DrawEllipse() namespace CB { diff --git a/GShr/LBoxVHScrl.cpp b/GShr/LBoxVHScrl.cpp index 562b578e..5d922b5a 100644 --- a/GShr/LBoxVHScrl.cpp +++ b/GShr/LBoxVHScrl.cpp @@ -1,6 +1,6 @@ // LBoxVHScrl.cpp // -// Copyright (c) 2024 By William Su, All Rights Reserved. +// Copyright (c) 2024-2025 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 @@ -40,12 +40,22 @@ namespace CB void VListBoxHScroll::SetItemCount(size_t count) { wxVListBox::SetItemCount(count); - wxCoord width = 0; + wxSize virtSize(0, 0); for (size_t i = 0 ; i < count ; ++i) { - width = std::max(width, GetItemSize(i).GetWidth()); + wxSize itemSize = GetItemSize(i); + virtSize.x = std::max(virtSize.x, itemSize.GetWidth()); + virtSize.y += itemSize.y; } - SetVirtualSize(width, GetVirtualSize().GetHeight()); + SetVirtualSize(virtSize); + + bestClientSize = virtSize; + if (count) + { + bestClientSize.x += wxSystemSettings::GetMetric(wxSYS_VSCROLL_X, this); + bestClientSize.y += wxSystemSettings::GetMetric(wxSYS_HSCROLL_Y, this); + } + InvalidateBestSize(); } std::vector VListBoxHScroll::GetSelections() const diff --git a/GShr/LBoxVHScrl.h b/GShr/LBoxVHScrl.h index b3b54766..c3d6b564 100644 --- a/GShr/LBoxVHScrl.h +++ b/GShr/LBoxVHScrl.h @@ -1,6 +1,6 @@ // LBoxVHScrl.h // -// Copyright (c) 2024 By William Su, All Rights Reserved. +// Copyright (c) 2024-2025 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 @@ -62,6 +62,7 @@ namespace CB } protected: + wxSize DoGetBestClientSize() const override { return bestClientSize; } void DoSetVirtualSize(int x, int y) override; private: @@ -72,6 +73,11 @@ namespace CB void OnSize(wxSizeEvent& event); void OnLButtonDown(wxMouseEvent& event); void OnLButtonUp(wxMouseEvent& event); + + /* GetVirtualSize() never returns less than + GetClientSize(), so need this to preserve + actual bestClientSize */ + wxSize bestClientSize; }; } diff --git a/GShr/LibMfc.cpp b/GShr/LibMfc.cpp index 84a98cb2..42151fb7 100644 --- a/GShr/LibMfc.cpp +++ b/GShr/LibMfc.cpp @@ -1,6 +1,6 @@ // LibMfc.cpp - Miscellaneous MFC Support Functions // -// 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 @@ -773,6 +773,7 @@ void CB::string::Serialize(CArchive& ar) #endif } +#if 0 CB::wxNativeContainerWindowMixin::operator const wxNativeContainerWindow*() const { if (!mfcWnd->m_hWnd) @@ -870,6 +871,7 @@ wxWindow* CB::FindWxWindow(CWnd& mfcWnd) } return wxWnd; } +#endif // emulate CWnd::SendMessageToDescendants() void CB::SendEventToDescendants(wxWindow& wnd, wxEvent& event, bool deep /*= true*/) @@ -885,6 +887,7 @@ void CB::SendEventToDescendants(wxWindow& wnd, wxEvent& event, bool deep /*= tru } } +#if 0 const CWnd* CB::ToCWnd(const wxWindow& w) { const wxNativeContainerWindow* ncw = dynamic_cast(&w); @@ -904,6 +907,87 @@ const std::type_info& CB::GetPublicTypeid(const wxWindow& w) const CWnd* mfcWnd = ToCWnd(w); return mfcWnd ? typeid(*mfcWnd) : typeid(w); } +#endif + +void CB::wxView::OnDraw(wxDC * dc) +{ + CPP20_TRACE("{}({})\n", __func__, *this); + wxASSERT(!"not impl"); +} + +// for CB, forward events to window here +bool CB::wxView::TryBefore(wxEvent& event) +{ + /* wx expects TryBefore() to be checked before the event + handlers specific to the current class, and I think + the wxWindow handlers are equivalent to what wx would + expect to be the wxView handlers, so check them after + base class TryBefore() */ + if (::wxView::TryBefore(event)) + { + return true; + } + + /* KLUDGE: there is time during doc setup where + wxGbxProjView exists, but can't create + corresponding window because the doc + isn't ready yet */ + wxWindowList& children = GetFrame()->GetChildren(); + if (children.empty()) + { + return false; + } + + /* only process wxFocusEvent for setting focus to + view's frame or descendants */ + if (event.GetEventType() == wxEVT_KILL_FOCUS) + { + return false; + } + else + { + wxFocusEvent* fe = dynamic_cast(&event); + if (fe) + { + wxASSERT(fe->GetEventType() == wxEVT_SET_FOCUS && + fe->GetEventObject() && + dynamic_cast(fe->GetEventObject())); + if (!GetFrame()->IsDescendant(static_cast(fe->GetEventObject()))) + { + return false; + } + } + } + + // only process wxChildFocusEvent for frame's (strict) descendants + wxChildFocusEvent* cfe = dynamic_cast(&event); + if (cfe) + { + if (GetFrame() == cfe->GetWindow() || + !GetFrame()->IsDescendant(cfe->GetWindow())) + { + return false; + } + } + + if (dynamic_cast(&event)) + { + /* KLUDGE: passing this to window causes + problems because vwbitedit isn't ready, + and I don't know of a need for this, + so drop it */ + return false; + } + + // view shouldn't process a different window's mouse events + if (dynamic_cast(&event) && + event.GetEventObject() != &GetWindow()) + { + return false; + } + + return GetWindow().ProcessWindowEventLocally(event); +} CB::ToolTip::~ToolTip() { @@ -1183,6 +1267,7 @@ void CB::InflateAndNormalize(wxRect& rect, int dx, int dy) rect.Inflate(dx, dy); } +#if 0 namespace CB { int ToWxID(int id) @@ -1402,6 +1487,7 @@ BOOL CB::RelayOnCmdMsg(wxEvtHandler& dest, return false; } } +#endif namespace CB { @@ -1431,6 +1517,7 @@ namespace CB } } +#if 0 bool CB::RelayProcessEvent(CCmdTarget& dest, wxEvent& event) { @@ -1494,6 +1581,7 @@ bool CB::RelayProcessEvent(CCmdTarget& dest, return false; } +#endif int CB::GetMouseButtons(const wxMouseState& event) { @@ -1505,3 +1593,176 @@ int CB::GetMouseButtons(const wxMouseState& event) retval |= event.Aux2IsDown() ? wxMOUSE_BTN_AUX2 : 0; return retval; } + +wxDocTemplate& CB::FindDocTemplateByView(const wxClassInfo& classInfo) +{ + wxDocManager& docMgr = CheckedDeref(wxDocManager::GetDocumentManager()); + wxList& templates = docMgr.GetTemplates(); + for (auto it = templates.begin() ; it != templates.end() ; ++it) + { + wxDocTemplate& templ = dynamic_cast(**it); + if (templ.GetViewClassInfo() == &classInfo) + { + return templ; + } + } + + AfxThrowInvalidArgException(); +} + +#if !defined(GPLAY) +wxAuiToolBar& CB::CreateToolbar(wxWindow& parent, const ToolArgs(&toolArgs)[], size_t count, unsigned bmapID) +{ + wxBitmap tools(std::format("#{}", bmapID), + wxBITMAP_TYPE_BMP_RESOURCE); + wxAuiToolBar& toolbar = *new wxAuiToolBar(&parent); + int separators = 0; + for (int i = 0 ; i < value_preserving_cast(count) ; ++i) + { + int id = toolArgs[i].xrcId; + if (id != wxID_SEPARATOR) + { + CB::string str = CB::string::LoadString(toolArgs[i].stringId); + std::vector tokens; + wxStringTokenizer tokenizer(str, "\n"); + while (tokenizer.HasMoreTokens()) + { + tokens.push_back(tokenizer.GetNextToken()); + } + if (tokens.size() == size_t(1)) + { + tokens.push_back(wxEmptyString); + } + wxASSERT(tokens.size() == size_t(2)); + wxBitmap tool = tools.GetSubBitmap(wxRect(wxPoint(16*(i - separators), 0), + wxSize(16, 16))); + toolbar.AddTool(id, + wxEmptyString, + tool, + wxNullBitmap, + toolArgs[i].kind, + tokens.back(), + tokens.front(), + nullptr); + } + else + { + ++separators; + toolbar.AddSeparator(); + } + } + wxASSERT(tools.GetSize() == wxSize( + value_preserving_cast(size_t(16) * (count - value_preserving_cast(separators))), 16)); + toolbar.Realize(); + return toolbar; +} +#endif + +wxBEGIN_EVENT_TABLE(CB::wxStatusBar, ::wxStatusBar) + EVT_IDLE(OnIdle) + EVT_UPDATE_UI(wxID_SEPARATOR, OnUpdateUI) + EVT_UPDATE_UI(ID_INDICATOR_CAPS, OnUpdateUI) + EVT_UPDATE_UI(ID_INDICATOR_NUM, OnUpdateUI) +wxEND_EVENT_TABLE() + +void CB::wxStatusBar::SetIndicators( + const int (&ids)[], + size_t count) +{ + wxASSERT(value_preserving_cast(GetFieldsCount()) == count); + indicators.resize(count); + + wxInfoDC dc(this); + std::vector widths(count); + for (size_t i = size_t(0) ; i < count ; ++i) + { + indicators[i] = ids[value_preserving_cast(i)]; + if (indicators[i] != wxID_SEPARATOR) + { + CB::string s = CB::string::LoadString(indicators[i]); + widths[i] = dc.GetTextExtent(s).x; + SetStatusText(s, value_preserving_cast(i)); + } + else + { + widths[i] = -1; + } + } + SetStatusWidths(value_preserving_cast(widths.size()), widths.data()); +} + +void CB::wxStatusBar::OnIdle(wxIdleEvent& WXUNUSED(event)) +{ + // represent disabled fields as "" + // use the status field stacks to remember enabled value + for (int i = 0 ; i < GetFieldsCount() ; ++i) + { + wxUpdateUIEvent uievent(indicators[value_preserving_cast(i)]); + bool rc = ProcessWindowEvent(uievent); + wxASSERT(rc == !uievent.GetSkipped()); + if (rc) + { + bool wasEnabled = !GetStatusText(i).empty(); + if (uievent.GetSetText()) + { + // reserve "" for disabled fields + wxString s = uievent.GetText(); + if (s.empty()) + { + s = wxString("\0", 1); + } + SetStatusText(s, i); + } + if (uievent.GetSetEnabled()) + { + if (wasEnabled && !uievent.GetEnabled()) + { + PushStatusText(wxEmptyString, i); + } + else if (!wasEnabled && uievent.GetEnabled()) + { + PopStatusText(i); + } + } + } + } +} + +void CB::wxStatusBar::OnUpdateUI(wxUpdateUIEvent& event) +{ + if (event.GetId() == ID_INDICATOR_CAPS) + { + event.Enable(wxGetKeyState(WXK_CAPITAL)); + } + else if (event.GetId() == ID_INDICATOR_NUM) + { + event.Enable(wxGetKeyState(WXK_NUMLOCK)); + } + else + { + event.Skip(); + } +} + +CB::wxStatusBar& CB::wxAuiMDIParentFrame::CreateStatusBar( + const int (&ids)[], + size_t count) +{ + ::wxStatusBar* psb = ::wxAuiMDIParentFrame::CreateStatusBar(value_preserving_cast(count)); + ::wxStatusBar& sb = CheckedDeref(psb); + CB::wxStatusBar& retval = dynamic_cast(sb); + retval.SetIndicators(ids, count); + return retval; +} + +CB::wxStatusBar* CB::wxAuiMDIParentFrame::OnCreateStatusBar(int number, + long style, + wxWindowID id, + const wxString& name) +{ + CB::wxStatusBar* statusBar = new CB::wxStatusBar(this, id, style, "CB::" + name); + + statusBar->SetFieldsCount(number); + + return statusBar; +} diff --git a/deps/wxWidgets b/deps/wxWidgets index 12b09a5e..5a51e52e 160000 --- a/deps/wxWidgets +++ b/deps/wxWidgets @@ -1 +1 @@ -Subproject commit 12b09a5e5ea76a1a0c27b769e821b37d803a4cb7 +Subproject commit 5a51e52ef817b513dce0f24fee2dbd0ea5f921ab