program.cpp 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. #include "../higan-ui.hpp"
  2. #include "../panel-items/home.cpp"
  3. #include "../panel-items/system-creation.cpp"
  4. #include "../panel-items/system-overview.cpp"
  5. #include "../panel-items/port-connector.cpp"
  6. #include "../panel-items/peripheral-overview.cpp"
  7. #include "../panel-items/input-mapper.cpp"
  8. #include "../panel-items/setting-editor.cpp"
  9. #include "../panel-items/video.cpp"
  10. #include "../panel-items/audio.cpp"
  11. #include "../panel-items/input.cpp"
  12. #include "../panel-items/hotkeys.cpp"
  13. #include "../panel-lists/settings-manager.cpp"
  14. #include "../panel-lists/system-manager.cpp"
  15. #include "../panel-lists/node-manager.cpp"
  16. #include "../panel-lists/port-manager.cpp"
  17. #include "../panel-lists/event-manager.cpp"
  18. namespace Instances { Instance<Program> program; }
  19. Program& program = Instances::program();
  20. ActionMenu& actionMenu = program.actionMenu;
  21. SystemMenu& systemMenu = program.systemMenu;
  22. SettingsMenu& settingsMenu = program.settingsMenu;
  23. ToolsMenu& toolsMenu = program.toolsMenu;
  24. HelpMenu& helpMenu = program.helpMenu;
  25. SettingsManager& settingsManager = program.settingsManager;
  26. SystemManager& systemManager = program.systemManager;
  27. NodeManager& nodeManager = program.nodeManager;
  28. PortManager& portManager = program.portManager;
  29. EventManager& eventManager = program.eventManager;
  30. Home& home = program.home;
  31. SystemCreation& systemCreation = program.systemCreation;
  32. SystemOverview& systemOverview = program.systemOverview;
  33. PortConnector& portConnector = program.portConnector;
  34. PeripheralOverview& peripheralOverview = program.peripheralOverview;
  35. InputMapper& inputMapper = program.inputMapper;
  36. SettingEditor& settingEditor = program.settingEditor;
  37. VideoSettings& videoSettings = program.videoSettings;
  38. AudioSettings& audioSettings = program.audioSettings;
  39. InputSettings& inputSettings = program.inputSettings;
  40. HotkeySettings& hotkeySettings = program.hotkeySettings;
  41. Program::Program() {
  42. viewport.setCollapsible().setFocusable();
  43. statusHeight = Font().size(" ").height() + 8_sy;
  44. layout.cell(statusLayout).setSize({~0, statusHeight});
  45. statusLayout.setCollapsible().setVisible(settings.interface.showStatusBar);
  46. statusMessage.setFont(Font().setBold());
  47. statusCaption.setFont(Font().setBold()).setAlignment(1.0);
  48. Color foreground{255, 255, 255};
  49. Color background{ 48, 48, 48};
  50. statusBefore.setForegroundColor(foreground).setBackgroundColor(background);
  51. statusMessage.setForegroundColor(foreground).setBackgroundColor(background);
  52. statusCaption.setForegroundColor(foreground).setBackgroundColor(background);
  53. statusAfter.setForegroundColor(foreground).setBackgroundColor(background);
  54. panelGroup.onChange([&] {
  55. if(auto item = panelGroup.selected()) {
  56. if(auto list = item.attribute<PanelList*>("panelList")) {
  57. setPanelList(*list);
  58. }
  59. }
  60. });
  61. panelHeight = 7 + 250_sy;
  62. verticalResizeGrip.setCollapsible().setVisible(settings.interface.showSystemPanels);
  63. panelLayout.setCollapsible().setVisible(settings.interface.showSystemPanels);
  64. panelLayout.setPadding({5_sx, 0_sy, 5_sx, 5_sy});
  65. for(auto& cell : panelLayout.cells()) cell.setSpacing(0);
  66. verticalResizeGrip.onActivate([&] {
  67. verticalResizeHeight = layout.cell(panelLayout).size().height();
  68. }).onResize([&](auto offset) {
  69. float min = 128_sy, max = geometry().height() - 128_sy;
  70. float height = verticalResizeHeight - offset;
  71. height = height < min ? min : height > max ? max : height;
  72. if(layout.cell(panelLayout).size().height() != height) {
  73. layout.cell(panelLayout).setSize({~0, height});
  74. layout.resize();
  75. }
  76. });
  77. horizontalResizeGrip.onActivate([&] {
  78. horizontalResizeWidth = panelLayout.cell(panelBlock).size().width();
  79. }).onResize([&](auto offset) {
  80. float min = 128_sx, max = panelLayout.geometry().width() - 128_sx;
  81. float width = horizontalResizeWidth + offset;
  82. width = width < min ? min : width > max ? max : width;
  83. if(panelLayout.cell(panelBlock).size().width() != width) {
  84. panelLayout.cell(panelBlock).setSize({width, ~0});
  85. panelLayout.resize();
  86. }
  87. });
  88. onClose([&] { emulator.quit(); });
  89. setOverviewMode();
  90. resize();
  91. setTitle({"higan v", higan::Version});
  92. setVisible();
  93. #if defined(PLATFORM_MACOS)
  94. Application::Cocoa::onQuit([&] { emulator.quit(); });
  95. #endif
  96. emulator.inputUpdate();
  97. videoSettings.eventChange();
  98. audioSettings.eventChange();
  99. inputSettings.eventChange();
  100. }
  101. auto Program::resize() -> void {
  102. uint scale = max(2, min(4, settings.video.scale));
  103. uint width = 320_sx * scale;
  104. uint height = 240_sx * scale;
  105. if(settings.interface.showStatusBar) height += statusHeight;
  106. if(settings.interface.showSystemPanels) height += panelHeight;
  107. setGeometry(Alignment::Center, {width, height});
  108. }
  109. auto Program::setOverviewMode() -> void {
  110. if(panelGroup.attribute("mode") == "overview") return;
  111. panelGroup.setAttribute("mode", "overview");
  112. panelGroup.reset();
  113. panelGroup.append(ComboButtonItem().setText("Systems").setAttribute<PanelList*>("panelList", &systemManager));
  114. panelGroup.append(ComboButtonItem().setText("Settings").setAttribute<PanelList*>("panelList", &settingsManager));
  115. setPanelList(systemManager);
  116. setPanelItem(home);
  117. systemMenu.setVisible(false);
  118. toolsMenu.setVisible(false);
  119. //todo: if test shouldn't be necessary ... works around a hiro/GTK bug ...
  120. if(!actionMenu.visible()) actionMenu.setVisible(true);
  121. }
  122. auto Program::setEmulatorMode() -> void {
  123. if(panelGroup.attribute("mode") == "emulator") return;
  124. panelGroup.setAttribute("mode", "emulator");
  125. panelGroup.reset();
  126. panelGroup.append(ComboButtonItem().setText(emulator.system.name).setAttribute<PanelList*>("panelList", &nodeManager));
  127. panelGroup.append(ComboButtonItem().setText("Ports").setAttribute<PanelList*>("panelList", &portManager));
  128. panelGroup.append(ComboButtonItem().setText("Events").setAttribute<PanelList*>("panelList", &eventManager));
  129. panelGroup.append(ComboButtonItem().setText("Settings").setAttribute<PanelList*>("panelList", &settingsManager));
  130. setPanelList(nodeManager);
  131. setPanelItem(home);
  132. actionMenu.setVisible(false);
  133. systemMenu.setVisible(true);
  134. toolsMenu.setVisible(true);
  135. }
  136. auto Program::setPanelList(PanelList& panelList) -> void {
  137. if(activePanelList && activePanelList() == panelList) return;
  138. if(activePanelList) activePanelList().hide();
  139. setPanelItem(home);
  140. activePanelList = panelList;
  141. activePanelList().show();
  142. panelBlock.resize();
  143. //update the panel group selection as well
  144. for(auto item : panelGroup.items()) {
  145. if(item.attribute<PanelList*>("panelList") == &panelList) {
  146. item.setSelected();
  147. }
  148. }
  149. }
  150. auto Program::setPanelItem(PanelItem& panelItem) -> void {
  151. if(activePanelItem && activePanelItem() == panelItem) return;
  152. if(activePanelItem) activePanelItem().hide();
  153. activePanelItem = panelItem;
  154. activePanelItem().show();
  155. panelLayout.resize();
  156. //todo: this works around a Windows rendering issue on the audio settings panel, but should not be needed:
  157. Application::processEvents();
  158. panelLayout.resize();
  159. }
  160. auto Program::refreshPanelList() -> void {
  161. if(activePanelList) activePanelList().refresh();
  162. }
  163. auto Program::showStatus() -> void {
  164. if(statusLayout.visible()) return;
  165. statusLayout.setVisible(true);
  166. if(!maximized()) setSize({geometry().width(), geometry().height() + statusHeight});
  167. layout.resize();
  168. settingsMenu.showStatusBar.setChecked(true);
  169. }
  170. auto Program::hideStatus() -> void {
  171. if(!statusLayout.visible()) return;
  172. statusLayout.setVisible(false);
  173. if(!maximized()) setSize({geometry().width(), geometry().height() - statusHeight});
  174. layout.resize();
  175. settingsMenu.showStatusBar.setChecked(false);
  176. }
  177. auto Program::showPanels() -> void {
  178. if(panelLayout.visible()) return;
  179. verticalResizeGrip.setVisible(true);
  180. panelLayout.setVisible(true);
  181. if(!maximized()) setSize({geometry().width(), geometry().height() + panelHeight});
  182. layout.resize();
  183. settingsMenu.showSystemPanels.setChecked(true);
  184. }
  185. auto Program::hidePanels() -> void {
  186. if(!panelLayout.visible()) return;
  187. panelHeight = 7 + panelLayout.geometry().height();
  188. verticalResizeGrip.setVisible(false);
  189. panelLayout.setVisible(false);
  190. if(!maximized()) setSize({geometry().width(), geometry().height() - panelHeight});
  191. layout.resize();
  192. settingsMenu.showSystemPanels.setChecked(false);
  193. }