From 96e1b1a092b569e8e96289f7652006709eeb8631 Mon Sep 17 00:00:00 2001 From: Goober5000 Date: Tue, 18 Aug 2026 03:09:49 -0400 Subject: [PATCH] add a toggle to switch FRED2 between the classic and current menu layouts PR #7082 rearranged the FRED2 menu layout to match qtFRED (see issue #6985), but some users preferred the previous Editors/Misc layout. This adds a "Classic menu layout" toggle (under Settings in the current layout, and under Misc in the classic layout) that swaps the whole menu bar on demand. The choice is persisted to the registry and reapplied on startup. Co-Authored-By: Claude Opus 4.8 (1M context) --- fred2/fred.cpp | 6 ++ fred2/fred.rc | 221 +++++++++++++++++++++++++++++++++++++++++++ fred2/fredrender.cpp | 1 + fred2/fredrender.h | 1 + fred2/fredview.cpp | 15 +++ fred2/fredview.h | 2 + fred2/mainfrm.cpp | 20 ++++ fred2/mainfrm.h | 7 ++ fred2/resource.h | 10 +- 9 files changed, 279 insertions(+), 4 deletions(-) diff --git a/fred2/fred.cpp b/fred2/fred.cpp index 6a63c1bc8ee..8dba5bf611f 100644 --- a/fred2/fred.cpp +++ b/fred2/fred.cpp @@ -237,6 +237,7 @@ BOOL CFREDApp::InitInstance() { Outline_lod = GetProfileInt("Preferences", "Outline LOD", 1); Always_save_display_names = GetProfileInt("Preferences", "Always save display names", 0) != 0; Error_checker_checks_potential_issues = GetProfileInt("Preferences", "Error checker checks potential issues", 1) != 0; + Classic_menu_layout = GetProfileInt("Preferences", "Classic menu layout", 0) != 0; read_window("Main window", &Main_wnd_data); read_window("Ship window", &Ship_wnd_data); @@ -334,6 +335,10 @@ BOOL CFREDApp::InitInstance() { if (m_pMainWnd == NULL) return FALSE; + // apply the saved main menu layout preference (the new layout is loaded by default) + if (Classic_menu_layout) + ((CMainFrame *) m_pMainWnd)->apply_menu_layout(true); + // Enable drag/drop open m_pMainWnd->DragAcceptFiles(); @@ -536,6 +541,7 @@ void CFREDApp::write_ini_file(int degree) { WriteProfileInt("Preferences", "Outline LOD", Outline_lod); WriteProfileInt("Preferences", "Always save display names", Always_save_display_names ? 1 : 0); WriteProfileInt("Preferences", "Error checker checks potential issues", Error_checker_checks_potential_issues ? 1 : 0); + WriteProfileInt("Preferences", "Classic menu layout", Classic_menu_layout ? 1 : 0); if (!degree) { record_window_data(&Waypoint_wnd_data, &Waypoint_editor_dialog); diff --git a/fred2/fred.rc b/fred2/fred.rc index bcb9b7ba576..f88f5aa544e 100644 --- a/fred2/fred.rc +++ b/fred2/fred.rc @@ -426,6 +426,8 @@ BEGIN MENUITEM SEPARATOR MENUITEM "Always save Display Names", ID_ALWAYS_SAVE_DISPLAY_NAMES MENUITEM "Error checker checks for potential issues", ID_ERROR_CHECKER_CHECKS_POTENTIAL_ISSUES, CHECKED + MENUITEM SEPARATOR + MENUITEM "Classic menu layout", ID_CLASSIC_MENU_LAYOUT END POPUP "&Help" BEGIN @@ -436,6 +438,224 @@ BEGIN END END +IDR_MAINMENU_CLASSIC MENU +BEGIN + POPUP "&File" + BEGIN + MENUITEM "&New\tCtrl+N", 57600 + MENUITEM "&Open...\tCtrl+O", 57601 + MENUITEM "&Save\tCtrl+S", 57603 + MENUITEM "Save &As...\tCtrl+Shift+S", 57604 + MENUITEM "Re&vert", 33000 + MENUITEM SEPARATOR + POPUP "Save &Format" + BEGIN + MENUITEM "FS2 Open", 33069, CHECKED + MENUITEM "FS2 Retail", 33070 + MENUITEM "Here Be Dragons", 33092 + END + POPUP "&Import" + BEGIN + MENUITEM "&FreeSpace 1 mission...", 33074 + END + MENUITEM SEPARATOR + MENUITEM "&Run FreeSpace", 32985 + MENUITEM SEPARATOR + MENUITEM "Recent File", 57616, GRAYED + MENUITEM SEPARATOR + MENUITEM "E&xit", 57665 + END + POPUP "&Edit" + BEGIN + MENUITEM "Undo\tCtrl+Z", 57643 + MENUITEM "Clone Marked Objects", 33099 + MENUITEM "Delete\tDel", 32789 + MENUITEM "Delete Wing\tCtrl+Del", 33035 + MENUITEM SEPARATOR + MENUITEM "Lock Marked Objects", ID_EDIT_LOCK_MARKED_OBJECTS + MENUITEM "Unlock All Objects", ID_EDIT_UNLOCK_ALL_OBJECTS + MENUITEM "Selection Lock", ID_SELECTION_LOCK + MENUITEM SEPARATOR + MENUITEM "Disable Undo", 33055 + END + POPUP "&View" + BEGIN + MENUITEM "&Toolbar", 59392, CHECKED + MENUITEM "&Status Bar", 59393, CHECKED + MENUITEM SEPARATOR + POPUP "Display Filter" + BEGIN + MENUITEM "Show Ships", 32990 + MENUITEM "Show Player Starts", 32991 + MENUITEM "Show Waypoints", 1075 + MENUITEM SEPARATOR + MENUITEM "Show IFF 0", 33081 + MENUITEM "Show IFF 1", 33082 + MENUITEM "Show IFF 2", 33083 + MENUITEM "Show IFF 3", 33084 + MENUITEM "Show IFF 4", 33085 + MENUITEM "Show IFF 5", 33086 + MENUITEM "Show IFF 6", 33087 + MENUITEM "Show IFF 7", 33088 + MENUITEM "Show IFF 8", 33089 + MENUITEM "Show IFF 9", 32988 + END + POPUP "Outline LOD" + BEGIN + MENUITEM "LOD 0 (highest detail)", 33107 + MENUITEM "LOD 1", 33108, CHECKED + MENUITEM "LOD 2", 33109 + MENUITEM "LOD 3", 33110 + MENUITEM "LOD 4 (lowest detail)", 33111 + END + MENUITEM SEPARATOR + MENUITEM "Hide Marked Objects", 33002 + MENUITEM "Show Hidden Objects", 33003 + MENUITEM SEPARATOR + MENUITEM "Show Ship Models\tShift+Alt+M", 32820, CHECKED + MENUITEM "Show Outlines\tShift+Alt+O", 32980 + MENUITEM "Draw Outlines on Selected Ships", ID_VIEW_OUTLINES_ON_SELECTED, CHECKED + MENUITEM "Draw Outline at Warpin Position", ID_VIEW_OUTLINE_AT_WARPIN, CHECKED + MENUITEM "Show Ship Info\tShift+Alt+I", 32823, CHECKED, HELP + MENUITEM "Show Coordinates\tShift+Alt+C", 32915 + MENUITEM "Show Grid Positions\tShift+Alt+P", 32914 + MENUITEM "Show Distances\tD", 32941 + MENUITEM "Show Model Paths", 33066 + MENUITEM "Show Model Dock Points", 33065 + MENUITEM "Highlight Selectable Subsystems", 33062 + MENUITEM SEPARATOR + MENUITEM "Show &Grid\tShift+Alt+G", 32808 + MENUITEM "Show Horizon\tShift+Alt+H", 32954 + MENUITEM "Double Fine Gridlines", 32939 + MENUITEM "Anti-Aliased Gridlines", 33048 + MENUITEM "Show 3D Compass\tShift+Alt+3", 32832, CHECKED + MENUITEM "Show Background\tShift+Alt+B", 32983 + MENUITEM SEPARATOR + POPUP "Viewpoint\tShift+V" + BEGIN + MENUITEM "Camera", 32835, CHECKED + MENUITEM "Current Ship", 32837 + END + MENUITEM "Save Camera Pos\tCtrl+P", 33008 + MENUITEM "Restore Camera Pos\tCtrl+R", 33009 + MENUITEM SEPARATOR + MENUITEM "Lighting from Suns", 33079 + MENUITEM "Render full detail", 33090 + END + POPUP "&Speed" + BEGIN + POPUP "Movement" + BEGIN + MENUITEM "x1\t1", 32898, CHECKED + MENUITEM "x2\t2", 32899 + MENUITEM "x3\t3", 32902 + MENUITEM "x5\t4", 32900 + MENUITEM "x8\t5", 32908 + MENUITEM "x10\t6", 32901 + MENUITEM "x50\t7", 32917 + MENUITEM "x100\t8", 32918 + MENUITEM "x500", 32920 + MENUITEM "x1000", 32922 + END + POPUP "Rotation" + BEGIN + MENUITEM "x1\tShift+1", 32903, CHECKED + MENUITEM "x5\tShift+2", 32904 + MENUITEM "x12\tShift+3", 32905 + MENUITEM "x25\tShift+4", 32906 + MENUITEM "x50\tShift+5", 32907 + END + END + POPUP "E&ditors" + BEGIN + MENUITEM "&Ships\tShift+S", 32799 + MENUITEM "&Wings\tShift+W", 32955 + MENUITEM "&Objects\tShift+O", 32973 + MENUITEM "Waypoint Paths\tShift+Y", 32979 + MENUITEM "Jump Nodes\tShift+J", ID_EDITORS_JUMPNODE + MENUITEM SEPARATOR + MENUITEM "&Mission Specs\tShift+N", 32771 + MENUITEM "Mission &Goals\tShift+G", 32800 + MENUITEM "Mission &Events\tShift+E", 32974 + MENUITEM "Mission Cutscenes", ID_EDITORS_CUTSCENES + MENUITEM "&Voice Acting Manager", ID_EDITORS_VOICE + MENUITEM SEPARATOR + MENUITEM "&Fiction Viewer\tShift+F", ID_EDITORS_FICTION + MENUITEM "&Command Briefing\tShift+C", 33054 + MENUITEM "Team &Loadout\tShift+P", 32972 + MENUITEM "&Briefing\tShift+B", 33006 + MENUITEM "&Debriefing\tShift+D", 33007 + MENUITEM SEPARATOR + MENUITEM "Background\tShift+I", 32976 + MENUITEM "Asteroid Field\tShift+A", 32984 + MENUITEM "Volumetric Nebula", ID_EDITORS_VOLUMETRICS + MENUITEM SEPARATOR + MENUITEM "Reinforcements\tShift+R", 32977 + MENUITEM "Shield System", 33033 + MENUITEM "Set Global Ship Flags", 33073 + MENUITEM "Reorder Ships and Wings", ID_REORDER + MENUITEM SEPARATOR + MENUITEM "Campaign", 32986 + END + POPUP "&Groups" + BEGIN + MENUITEM "Group 1\tCtrl+1", 33012 + MENUITEM "Group 2\tCtrl+2", 33013 + MENUITEM "Group 3\tCtrl+3", 33014 + MENUITEM "Group 4\tCtrl+4", 33015 + MENUITEM "Group 5\tCtrl+5", 33016 + MENUITEM "Group 6\tCtrl+6", 33017 + MENUITEM "Group 7\tCtrl+7", 33018 + MENUITEM "Group 8\tCtrl+8", 33019 + MENUITEM "Group 9\tCtrl+9", 33020 + POPUP "Set Group" + BEGIN + MENUITEM "Group 1", 33021 + MENUITEM "Group 2", 33022 + MENUITEM "Group 3", 33023 + MENUITEM "Group 4", 33024 + MENUITEM "Group 5", 33025 + MENUITEM "Group 6", 33026 + MENUITEM "Group 7", 33027 + MENUITEM "Group 8", 33028 + MENUITEM "Group 9", 33029 + END + END + POPUP "&Misc" + BEGIN + MENUITEM "Next Object\tTab", 33039 + MENUITEM "Previous Object\tCtrl+Tab", 33040 + MENUITEM "Control Object\tT", 33041 + MENUITEM "Level Object\tL", 33037 + MENUITEM "Align Object\tCtrl+L", 33036 + MENUITEM SEPARATOR + MENUITEM "Next Subsystem\tK", 33059 + MENUITEM "Prev Subsystem\tShift+K", 33060 + MENUITEM "Cancel Subsystem\tAlt+K", 33061 + MENUITEM SEPARATOR + MENUITEM "Mark Wing\tW", 33038 + MENUITEM "Adjust Grid", 33032 + MENUITEM "Calculate Relative Coordinates", 33030 + MENUITEM "Point Ships Using UVec", 33101 + MENUITEM "Move Ships When Undocking", 33098, CHECKED + MENUITEM "Mission Statistics\tCtrl+Shift+D", 33067 + MENUITEM "Music Player", ID_MUSIC_PLAYER + MENUITEM SEPARATOR + MENUITEM "Always save Display Names", ID_ALWAYS_SAVE_DISPLAY_NAMES + MENUITEM "Error checker checks for potential issues", ID_ERROR_CHECKER_CHECKS_POTENTIAL_ISSUES, CHECKED + MENUITEM "Error checker\tShift+H", 32978 + MENUITEM SEPARATOR + MENUITEM "Classic menu layout", ID_CLASSIC_MENU_LAYOUT + END + POPUP "&Help" + BEGIN + MENUITEM "&Help Topics", 57667 + MENUITEM SEPARATOR + MENUITEM "&About FRED2", 57664 + MENUITEM "Show Sexp Help", 33010 + END +END + IDR_MENU_SHIP_POPUP MENU BEGIN POPUP "Properties" @@ -3827,6 +4047,7 @@ BEGIN ID_ALWAYS_SAVE_DISPLAY_NAMES "When saving a mission, always write display names to the mission file even if the display name is not set" ID_ERROR_CHECKER_CHECKS_POTENTIAL_ISSUES "If checked, error checker will check for things that are not necessarily errors but may cause unexpected behavior" ID_ERROR_CHECKER "Checks mission for FRED-detectable errors" + ID_CLASSIC_MENU_LAYOUT "Switch between the QtFRED menu layout and the classic FRED menu layout" END STRINGTABLE diff --git a/fred2/fredrender.cpp b/fred2/fredrender.cpp index e36492c373f..a3c42e60ee4 100644 --- a/fred2/fredrender.cpp +++ b/fred2/fredrender.cpp @@ -118,6 +118,7 @@ int Outline_lod = 1; bool Always_save_display_names = false; bool Error_checker_checks_potential_issues = true; bool Error_checker_checks_potential_issues_once = false; +bool Classic_menu_layout = false; int Show_stars = 1; int Single_axis_constraint = 0; int True_rw, True_rh; diff --git a/fred2/fredrender.h b/fred2/fredrender.h index f03920f96f1..6a89a7b4a1f 100644 --- a/fred2/fredrender.h +++ b/fred2/fredrender.h @@ -28,6 +28,7 @@ extern bool Always_save_display_names; // When saving a mission, always write di // Wings now support display names, or the ship-change-display-name SEXP can be used, to handle that case. extern bool Error_checker_checks_potential_issues; // Error checker checks not only outright errors but also potential issues extern bool Error_checker_checks_potential_issues_once; // Same as above, but only once, and independent of the selected option +extern bool Classic_menu_layout; // Use the classic main menu layout instead of the qtFRED-style layout extern int Show_stars; //!< Bool. If nonzero, draw the starfield, nebulas, and suns. Might also handle skyboxes extern int Single_axis_constraint; //!< Bool. If nonzero, constrain movement to one axis extern int Show_distances; //!< Bool. If nonzero, draw lines between each object and display their distance on the middle of each line diff --git a/fred2/fredview.cpp b/fred2/fredview.cpp index 3898169d687..c332b7deb4f 100644 --- a/fred2/fredview.cpp +++ b/fred2/fredview.cpp @@ -292,6 +292,8 @@ BEGIN_MESSAGE_MAP(CFREDView, CView) ON_UPDATE_COMMAND_UI(ID_ALWAYS_SAVE_DISPLAY_NAMES, OnUpdateAlwaysSaveDisplayNames) ON_COMMAND(ID_ERROR_CHECKER_CHECKS_POTENTIAL_ISSUES, OnErrorCheckerChecksPotentialIssues) ON_UPDATE_COMMAND_UI(ID_ERROR_CHECKER_CHECKS_POTENTIAL_ISSUES, OnUpdateErrorCheckerChecksPotentialIssues) + ON_COMMAND(ID_CLASSIC_MENU_LAYOUT, OnClassicMenuLayout) + ON_UPDATE_COMMAND_UI(ID_CLASSIC_MENU_LAYOUT, OnUpdateClassicMenuLayout) ON_UPDATE_COMMAND_UI(ID_NEW_SHIP_TYPE, OnUpdateNewShipType) ON_COMMAND(ID_SHOW_STARFIELD, OnShowStarfield) ON_UPDATE_COMMAND_UI(ID_SHOW_STARFIELD, OnUpdateShowStarfield) @@ -4050,6 +4052,19 @@ void CFREDView::OnUpdateErrorCheckerChecksPotentialIssues(CCmdUI* pCmdUI) pCmdUI->SetCheck(Error_checker_checks_potential_issues); } +void CFREDView::OnClassicMenuLayout() +{ + Classic_menu_layout = !Classic_menu_layout; + if (Fred_main_wnd != nullptr) + Fred_main_wnd->apply_menu_layout(Classic_menu_layout); + theApp.write_ini_file(); +} + +void CFREDView::OnUpdateClassicMenuLayout(CCmdUI* pCmdUI) +{ + pCmdUI->SetCheck(Classic_menu_layout); +} + void CFREDView::OnUpdateNewShipType(CCmdUI* pCmdUI) { int z; diff --git a/fred2/fredview.h b/fred2/fredview.h index 36520dbf539..4c8d9709812 100644 --- a/fred2/fredview.h +++ b/fred2/fredview.h @@ -250,6 +250,8 @@ class CFREDView : public CView afx_msg void OnUpdateAlwaysSaveDisplayNames(CCmdUI* pCmdUI); afx_msg void OnErrorCheckerChecksPotentialIssues(); afx_msg void OnUpdateErrorCheckerChecksPotentialIssues(CCmdUI* pCmdUI); + afx_msg void OnClassicMenuLayout(); + afx_msg void OnUpdateClassicMenuLayout(CCmdUI* pCmdUI); afx_msg void OnUpdateNewShipType(CCmdUI* pCmdUI); afx_msg void OnShowStarfield(); afx_msg void OnUpdateShowStarfield(CCmdUI* pCmdUI); diff --git a/fred2/mainfrm.cpp b/fred2/mainfrm.cpp index 66ddb39307d..46193b45dde 100644 --- a/fred2/mainfrm.cpp +++ b/fred2/mainfrm.cpp @@ -306,6 +306,26 @@ void CMainFrame::OnDestroy() { CFrameWnd::OnDestroy(); } +void CMainFrame::apply_menu_layout(bool classic) +{ + CMenu menu; + if (!menu.LoadMenu(classic ? IDR_MAINMENU_CLASSIC : IDR_MAINMENU)) + return; + + // grab the menu currently on the frame so we can free it after the swap + CMenu *old_menu = GetMenu(); + + SetMenu(&menu); + m_hMenuDefault = menu.GetSafeHmenu(); // keep MFC's fallback handle in sync so the bar isn't reverted later + menu.Detach(); // the frame now owns the new menu + + // destroy the menu we just replaced to avoid a GDI leak + if (old_menu != nullptr && old_menu->GetSafeHmenu() != nullptr) + old_menu->DestroyMenu(); + + DrawMenuBar(); +} + void CMainFrame::OnFileMissionnotes() { CMissionNotesDlg dlg; diff --git a/fred2/mainfrm.h b/fred2/mainfrm.h index 39cf1eebc2e..d2bcfac6b7c 100644 --- a/fred2/mainfrm.h +++ b/fred2/mainfrm.h @@ -102,6 +102,13 @@ class CMainFrame : public CFrameWnd void init_tools(); + /** + * @brief Swaps the main menu bar between the qtFRED-style and classic layouts + * + * @param[in] classic If true, load the classic menu; otherwise the newer menu + */ + void apply_menu_layout(bool classic); + /** * @breif Standard deconstructor */ diff --git a/fred2/resource.h b/fred2/resource.h index 27c6268578d..e6fbf2d0efb 100644 --- a/fred2/resource.h +++ b/fred2/resource.h @@ -11,9 +11,10 @@ #define IDD_VOICE_MANAGER 102 #define IDR_MAINFRAME 128 #define IDR_MAINMENU 128 -#define IDR_FREDTYPE 129 -#define IDR_CAMPAIGN_VIEW 130 -#define IDR_CAMPAIGN_DLG 131 +#define IDR_MAINMENU_CLASSIC 129 +#define IDR_FREDTYPE 130 +#define IDR_CAMPAIGN_VIEW 131 +#define IDR_CAMPAIGN_DLG 132 #define IDR_TOOLBAR1 150 #define IDD_SHIP_EDITBAR 154 #define IDD_SHIP_CLASS_EDITOR 161 @@ -1614,6 +1615,7 @@ #define ID_OUTLINE_LOD_3 33110 #define ID_OUTLINE_LOD_4 33111 #define ID_REORDER 33112 +#define ID_CLASSIC_MENU_LAYOUT 33113 #define ID_INDICATOR_MODE 59142 #define ID_INDICATOR_LEFT 59143 #define ID_INDICATOR_RIGHT 59144 @@ -1627,7 +1629,7 @@ #define _APS_3D_CONTROLS 1 #define _APS_NEXT_RESOURCE_VALUE 340 #define _APS_NEXT_CONTROL_VALUE 1747 -#define _APS_NEXT_COMMAND_VALUE 33113 +#define _APS_NEXT_COMMAND_VALUE 33114 #define _APS_NEXT_SYMED_VALUE 105 #endif #endif