diff --git a/Changes.txt b/Changes.txt index 20ed3e411..b01916cbe 100644 --- a/Changes.txt +++ b/Changes.txt @@ -12,7 +12,7 @@ Release History =========================================================================== -6.1 to 6.2: (??? ??, 2020) +6.1.2 to 6.2: (??? ??, 2020) * Added that paddle centering and sensitivity can be adjusted (TODO: Doc) @@ -24,7 +24,9 @@ * Added 'Turbo' mode, runs the game as fast as the computer allows. - * Added option which lets default ROM path follow launcher navigation (TODO: Doc) + * Added selectable dialog fonts + + * Added option which lets default ROM path follow launcher navigation * Added displaying last write address in the debugger. @@ -39,6 +41,16 @@ -Have fun! +6.1.1 to 6.1.2: (April 25, 2020) + + * Fixed bug with remapped events not being reloaded in certain cases. + + * Fixed bug in debugger for 3E scheme when displaying active RAM bank. + + * Fixed bug in "Dragon Defender" ROM being misconfigured for Mindlink + controller. + + 6.1 to 6.1.1: (April 4, 2020) * Fixed crash in 3E bankswitching scheme when writing to ROM addresses. diff --git a/Makefile b/Makefile index b0e41062b..939f0d7cf 100644 --- a/Makefile +++ b/Makefile @@ -8,14 +8,11 @@ ## SS SS tt ee ll ll aa aa ## SSSS ttt eeeee llll llll aaaaa ## -## Copyright (c) 1995-2016 by Bradford W. Mott, Stephen Anthony +## Copyright (c) 1995-2020 by Bradford W. Mott, Stephen Anthony ## and the Stella Team ## ## See the file "License.txt" for information on usage and redistribution of ## this file, and for a DISCLAIMER OF ALL WARRANTIES. -## -## Based on code from ScummVM - Scumm Interpreter -## Copyright (C) 2002-2004 The ScummVM project ##============================================================================ ####################################################################### diff --git a/appveyor.yml b/appveyor.yml index a087f4e42..211b69a24 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -7,15 +7,15 @@ environment: matrix: - Platform: x64 - Platform: Win32 - + Configuration: Release - SDL2_version: 2.0.10 + SDL2_version: 2.0.12 install: - cmd: | - curl -o "C:\SDL2-devel.zip" https://www.libsdl.org/release/SDL2-devel-2.0.10-VC.zip + curl -o "C:\SDL2-devel.zip" "https://www.libsdl.org/release/SDL2-devel-%SDL2_version%-VC.zip" 7z x "C:\SDL2-devel.zip" -o"C:\" xcopy /S "C:\SDL2-%SDL2_version%\include" src\common diff --git a/debian/changelog b/debian/changelog index af319a670..81ab67bce 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,10 @@ +stella (6.1.2-1) stable; urgency=high + + * Version 6.1.2 release + + -- Stephen Anthony Sat, 25 Apr 2020 17:09:59 -0230 + + stella (6.1.1-1) stable; urgency=high * Version 6.1.1 release diff --git a/docs/debugger.html b/docs/debugger.html index 46e38d079..4f0c1cf6f 100644 --- a/docs/debugger.html +++ b/docs/debugger.html @@ -331,7 +331,7 @@ previous rewind operation. The rewind buffer is 100 levels deep by default, the size can be configured e.g. in the Developer Settings - Time Machine dialog.

-

The other operations are Step, Trace, Scan+1, Frame+1 and Exit (debugger).

+

The other operations are Step, Trace, Scan+1, Frame+1 and Run.

You can also use the buttons from anywhere in the GUI via hotkeys.

@@ -382,12 +382,12 @@ size can be configured e.g. in the Backquote (`) - Exit + Run

For MacOS use 'Cmd' instead of  'Alt' key. -

To the left of the global buttons, you find the "Options..." button.

+

To the left of the global buttons, you find the 'Options...' button.

@@ -608,7 +608,7 @@ created a symbol file, you can use labels for the expression.

Example: You have got a label called "kernel". To break there, the command is "break kernel". After you've set the breakpoint, -exit the debugger ("quit" or click the Exit button). The emulator +exit the debugger (enter "run" or click the 'Run' button). The emulator will run until it gets to the breakpoint, then it will enter the debugger with the Program Counter pointing to the instruction at the breakpoint.

@@ -1027,8 +1027,8 @@ graphics and positions, and the playfield.

of the displays are editable. You can even toggle individual bits in the GRP0/1 and playfield registers (remember to double-click).

-

The group of buttons labelled "Strobes" allows you to write to any -of the strobe registers at any time.

+

The buttons allow you to write to any of the strobe registers at +any time.

The collision registers are displayed in decoded format, in a table. You can see exactly which objects have hit what. These are read-only @@ -1103,7 +1103,7 @@ or TV effects are enabled, you won't see the effects here; this shows the raw TIA image only.

To e.g. watch the TIA draw the frame one scanline at a time, you can -use the "Scan+1" button, the prompt "scan" command or the Control-L key.

+use the 'Scan+1' button, the prompt "scan" command or the Control-L key.

You can also right-click anywhere in this window to show a context menu, as illustrated:

@@ -1213,7 +1213,7 @@ section for details.

All the registers and flags are displayed, and can be changed by double-clicking on them (to the left). Flags are toggled on double-click. -Selected registers here can also be changed by using the "Data Operations" buttons, +Selected registers here can also be changed by using the 'Data Operations' buttons, further described in (J). All items are shown in hex. Any label defined for the current PC value is shown to the right. Decimal and binary equivalents are shown for SP/A/X/Y to the right (first decimal, then binary).

@@ -1631,7 +1631,7 @@ but it helps to know at least a little about 6502 programming.

  • Enter the debugger by pressing the ` (backquote) key. Don't get killed before you do this, though. You should still have all 5 lives.
  • -
  • In the RAM display, click the "Search" button and enter "5" for input. +
  • In the RAM display, click the 'Search' button and enter "5" for input. This searches RAM for your value and highlights all addresses that match the input. You should see two addresses highlighted: "00a5" and "00ba". These are the only two addresses that currently have the value 5, so they're @@ -1647,7 +1647,7 @@ but it helps to know at least a little about 6502 programming.

  • Get killed! Ram an enemy tank, or let him shoot you. Wait for the explosion to finish. You will now have 4 lives.
  • -
  • Enter the debugger again. Click the "Compare" button in RAM widget and enter +
  • Enter the debugger again. Click the 'Compare...' button in RAM widget and enter a value of 4. Now the RAM widget should only show one highlighted address: "00ba". What we did was search within our previous results (the ones that were 5 before) for the new value 4. Address $00ba used to have the value 5, diff --git a/docs/graphics/options_misc.png b/docs/graphics/options_misc.png index aa382419f..b1930b45d 100644 Binary files a/docs/graphics/options_misc.png and b/docs/graphics/options_misc.png differ diff --git a/docs/graphics/options_misc_classic.png b/docs/graphics/options_misc_classic.png index d4a77dc9f..1eab6039e 100644 Binary files a/docs/graphics/options_misc_classic.png and b/docs/graphics/options_misc_classic.png differ diff --git a/docs/graphics/options_misc_light.png b/docs/graphics/options_misc_light.png index b1113c033..c0cebe477 100644 Binary files a/docs/graphics/options_misc_light.png and b/docs/graphics/options_misc_light.png differ diff --git a/docs/graphics/options_ui.png b/docs/graphics/options_ui.png index 322527cb3..54ed568fc 100644 Binary files a/docs/graphics/options_ui.png and b/docs/graphics/options_ui.png differ diff --git a/docs/index.html b/docs/index.html index 6f9fb85a9..51edf0dbc 100644 --- a/docs/index.html +++ b/docs/index.html @@ -2404,6 +2404,11 @@ Use the specified palette for UI elements. + +
    -dialogfont <small|low_medium|medium|large|large12|large14|large16>
    + Set the size of the font in the dialogs. + +
    -dialogpos <0 - 4>
    Set the position of dialogs within Stella windows (0 = center). @@ -2448,7 +2453,12 @@
    -romdir <dir>
    - Set the directory where the ROM launcher will start. + Set the path where the ROM launcher will start. + + + +
    -followlauncher <0|1>
    + Make the start path follow ROM launcher navigation. @@ -2914,8 +2924,9 @@ - + + diff --git a/src/cheat/CheatCodeDialog.cxx b/src/cheat/CheatCodeDialog.cxx index 780fbea2f..5ce380e0b 100644 --- a/src/cheat/CheatCodeDialog.cxx +++ b/src/cheat/CheatCodeDialog.cxx @@ -35,46 +35,50 @@ CheatCodeDialog::CheatCodeDialog(OSystem& osystem, DialogContainer& parent, const GUI::Font& font) : Dialog(osystem, parent, font, "Cheat codes") { - const int lineHeight = font.getLineHeight(), - fontWidth = font.getMaxCharWidth(), - buttonWidth = font.getStringWidth("Defaults") + 20, - buttonHeight = font.getLineHeight() + 4; - const int HBORDER = 10; - const int VBORDER = 10 + _th; + const int lineHeight = font.getLineHeight(), + fontHeight = font.getFontHeight(), + fontWidth = font.getMaxCharWidth(), + buttonWidth = font.getStringWidth("One shot ") + fontWidth * 2.5, + buttonHeight = font.getLineHeight() * 1.25; + const int VBORDER = fontHeight / 2; + const int HBORDER = fontWidth * 1.25; + const int INDENT = fontWidth * 2; + const int VGAP = fontHeight / 4; + int xpos, ypos; WidgetArray wid; ButtonWidget* b; // Set real dimensions _w = 45 * fontWidth + HBORDER * 2; - _h = 11 * (lineHeight + 4) + VBORDER; + _h = _th + 11 * (lineHeight + 4) + VBORDER * 2; // List of cheats, with checkboxes to enable/disable - xpos = HBORDER; ypos = VBORDER; + xpos = HBORDER; ypos = _th + VBORDER; myCheatList = - new CheckListWidget(this, font, xpos, ypos, _w - buttonWidth - HBORDER * 2 - 8, - _h - 2*buttonHeight - VBORDER); + new CheckListWidget(this, font, xpos, ypos, _w - buttonWidth - HBORDER * 2 - fontWidth, + _h - _th - buttonHeight - VBORDER * 3); myCheatList->setEditable(false); wid.push_back(myCheatList); - xpos += myCheatList->getWidth() + 8; ypos = VBORDER; + xpos += myCheatList->getWidth() + fontWidth; ypos = _th + VBORDER; b = new ButtonWidget(this, font, xpos, ypos, buttonWidth, buttonHeight, "Add" + ELLIPSIS, kAddCheatCmd); wid.push_back(b); - ypos += lineHeight + 8; + ypos += lineHeight + VGAP * 2; myEditButton = new ButtonWidget(this, font, xpos, ypos, buttonWidth, buttonHeight, "Edit" + ELLIPSIS, kEditCheatCmd); wid.push_back(myEditButton); - ypos += lineHeight + 8; + ypos += lineHeight + VGAP * 2; myRemoveButton = new ButtonWidget(this, font, xpos, ypos, buttonWidth, buttonHeight, "Remove", kRemCheatCmd); wid.push_back(myRemoveButton); - ypos += lineHeight + 8 * 3; + ypos += lineHeight + VGAP * 2 * 3; b = new ButtonWidget(this, font, xpos, ypos, buttonWidth, buttonHeight, "One shot" + ELLIPSIS, kAddOneShotCmd); diff --git a/src/common/LinkedObjectPool.hxx b/src/common/LinkedObjectPool.hxx index ab4a2fcbd..7c35439e3 100644 --- a/src/common/LinkedObjectPool.hxx +++ b/src/common/LinkedObjectPool.hxx @@ -49,7 +49,7 @@ */ namespace Common { -template +template class LinkedObjectPool { public: diff --git a/src/common/PKeyboardHandler.cxx b/src/common/PKeyboardHandler.cxx index 57a3bfd4b..fa1139d66 100644 --- a/src/common/PKeyboardHandler.cxx +++ b/src/common/PKeyboardHandler.cxx @@ -66,6 +66,31 @@ PhysicalKeyboardHandler::PhysicalKeyboardHandler(OSystem& system, EventHandler& setDefaultMapping(Event::NoType, EventMode::kMenuMode, true); } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool PhysicalKeyboardHandler::isMappingUsed(EventMode mode, const EventMapping& map) const +{ + // Menu events can only interfere with + // - other menu events + if(mode == EventMode::kMenuMode) + return myKeyMap.check(EventMode::kMenuMode, map.key, map.mod); + + // Controller events can interfere with + // - other events of the same controller + // - and common emulation events + if(mode != EventMode::kCommonMode) + return myKeyMap.check(mode, map.key, map.mod) + || myKeyMap.check(EventMode::kCommonMode, map.key, map.mod); + + // Common emulation events can interfere with + // - other common emulation events + // - and all controller events + return myKeyMap.check(EventMode::kCommonMode, map.key, map.mod) + || myKeyMap.check(EventMode::kJoystickMode, map.key, map.mod) + || myKeyMap.check(EventMode::kPaddlesMode, map.key, map.mod) + || myKeyMap.check(EventMode::kKeypadMode, map.key, map.mod) + || myKeyMap.check(EventMode::kCompuMateMode, map.key, map.mod); +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // Depending on parameters, this method does the following: // 1. update all events with default (event == Event::NoType, updateDefault == true) @@ -83,7 +108,7 @@ void PhysicalKeyboardHandler::setDefaultKey(EventMapping map, Event::Type event, // if there is no existing mapping for the event and // the default mapping for the event is unused, set default key for event if (myKeyMap.getEventMapping(map.event, mode).size() == 0 && - !myKeyMap.check(mode, map.key, map.mod)) + !isMappingUsed(mode, map)) { addMapping(map.event, mode, map.key, StellaMod(map.mod)); } diff --git a/src/common/PKeyboardHandler.hxx b/src/common/PKeyboardHandler.hxx index adb9b5106..ede6aa55a 100644 --- a/src/common/PKeyboardHandler.hxx +++ b/src/common/PKeyboardHandler.hxx @@ -87,6 +87,9 @@ class PhysicalKeyboardHandler }; using EventMappingArray = std::vector; + // Checks if the given mapping is used by any event mode + bool isMappingUsed(EventMode mode, const EventMapping& map) const; + void setDefaultKey(EventMapping map, Event::Type event = Event::NoType, EventMode mode = EventMode::kEmulationMode, bool updateDefaults = false); diff --git a/src/common/Stack.hxx b/src/common/Stack.hxx index aac9c28b2..e3b2afd87 100644 --- a/src/common/Stack.hxx +++ b/src/common/Stack.hxx @@ -27,7 +27,7 @@ */ namespace Common { -template +template class FixedStack { private: diff --git a/src/common/Vec.hxx b/src/common/Vec.hxx index 10e0c492e..7d102a785 100644 --- a/src/common/Vec.hxx +++ b/src/common/Vec.hxx @@ -22,19 +22,19 @@ namespace Vec { -template +template void append(vector& dst, const vector& src) { dst.insert(dst.cend(), src.cbegin(), src.cend()); } -template +template void insertAt(vector& dst, uInt32 idx, const T& element) { dst.insert(dst.cbegin()+idx, element); } -template +template void removeAt(vector& dst, uInt32 idx) { dst.erase(dst.cbegin()+idx); diff --git a/src/common/bspf.hxx b/src/common/bspf.hxx index 7312783b3..1484b21ed 100644 --- a/src/common/bspf.hxx +++ b/src/common/bspf.hxx @@ -120,16 +120,16 @@ namespace BSPF #endif // Make 2D-arrays using std::array less verbose - template + template using array2D = std::array, ROW>; // Combines 'max' and 'min', and clamps value to the upper/lower value // if it is outside the specified range - template inline T clamp(T val, T lower, T upper) + template inline T clamp(T val, T lower, T upper) { return (val < lower) ? lower : (val > upper) ? upper : val; } - template inline void clamp(T& val, T lower, T upper, T setVal) + template inline void clamp(T& val, T lower, T upper, T setVal) { if(val < lower || val > upper) val = setVal; } diff --git a/src/debugger/CartDebug.cxx b/src/debugger/CartDebug.cxx index 5192f84e8..3198eb9ea 100644 --- a/src/debugger/CartDebug.cxx +++ b/src/debugger/CartDebug.cxx @@ -736,7 +736,7 @@ string CartDebug::loadListFile() if(myListFile == "") { - FilesystemNode lst(myOSystem.romFile().getPathWithExt("") + ".lst"); + FilesystemNode lst(myOSystem.romFile().getPathWithExt(".lst")); if(lst.isFile() && lst.isReadable()) myListFile = lst.getPath(); else @@ -796,7 +796,7 @@ string CartDebug::loadSymbolFile() if(mySymbolFile == "") { - FilesystemNode sym(myOSystem.romFile().getPathWithExt("") + ".sym"); + FilesystemNode sym(myOSystem.romFile().getPathWithExt(".sym")); if(sym.isFile() && sym.isReadable()) mySymbolFile = sym.getPath(); else @@ -856,7 +856,7 @@ string CartDebug::loadConfigFile() if(myCfgFile == "") { - FilesystemNode romNode(myOSystem.romFile().getPathWithExt("") + ".cfg"); + FilesystemNode romNode(myOSystem.romFile().getPathWithExt(".cfg")); FilesystemNode cfg(myOSystem.cfgDir() + romNode.getName()); if(cfg.isFile() && cfg.isReadable()) myCfgFile = cfg.getPath(); @@ -978,7 +978,7 @@ string CartDebug::saveConfigFile() if(myCfgFile == "") { - FilesystemNode romNode(myOSystem.romFile().getPathWithExt("") + ".cfg"); + FilesystemNode romNode(myOSystem.romFile().getPathWithExt(".cfg")); FilesystemNode cfg(myOSystem.cfgDir() + romNode.getName()); if(cfg.getParent().isWritable()) myCfgFile = cfg.getPath(); diff --git a/src/debugger/Debugger.cxx b/src/debugger/Debugger.cxx index cfb16a1e5..a96f208ec 100644 --- a/src/debugger/Debugger.cxx +++ b/src/debugger/Debugger.cxx @@ -688,6 +688,7 @@ void Debugger::setStartState() // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void Debugger::setQuitState() { + myDialog->saveConfig(); saveOldState(); // Bus must be unlocked for normal operation when leaving debugger mode diff --git a/src/debugger/gui/CartDebugWidget.cxx b/src/debugger/gui/CartDebugWidget.cxx index 5d0bb5c98..b04000328 100644 --- a/src/debugger/gui/CartDebugWidget.cxx +++ b/src/debugger/gui/CartDebugWidget.cxx @@ -65,7 +65,7 @@ int CartDebugWidget::addBaseInformation(size_t bytes, const string& manufacturer w->setEditable(false); y += myLineHeight + 4; - StringParser bs(desc, (fwidth - kScrollBarWidth - 4) / myFontWidth); + StringParser bs(desc, (fwidth - ScrollBarWidget::scrollBarWidth(_font)) / myFontWidth - 4); const StringList& sl = bs.stringList(); uInt32 lines = uInt32(sl.size()); if(lines < 3) lines = 3; diff --git a/src/debugger/gui/CartRamWidget.cxx b/src/debugger/gui/CartRamWidget.cxx index 10bfb5c23..84cc8b9ab 100644 --- a/src/debugger/gui/CartRamWidget.cxx +++ b/src/debugger/gui/CartRamWidget.cxx @@ -62,7 +62,7 @@ CartRamWidget::CartRamWidget( // Add Description const string& desc = cartDebug.internalRamDescription(); const uInt16 maxlines = 6; - StringParser bs(desc, (fwidth - kScrollBarWidth) / myFontWidth); + StringParser bs(desc, (fwidth - ScrollBarWidget::scrollBarWidth(_font)) / myFontWidth); const StringList& sl = bs.stringList(); uInt32 lines = uInt32(sl.size()); if(lines < 2) lines = 2; diff --git a/src/debugger/gui/DataGridWidget.cxx b/src/debugger/gui/DataGridWidget.cxx index 9d9d25886..6b663609c 100644 --- a/src/debugger/gui/DataGridWidget.cxx +++ b/src/debugger/gui/DataGridWidget.cxx @@ -67,7 +67,8 @@ DataGridWidget::DataGridWidget(GuiObject* boss, const GUI::Font& font, // Add a scrollbar if necessary if(useScrollbar) { - _scrollBar = new ScrollBarWidget(boss, font, _x + _w, _y, kScrollBarWidth, _h); + _scrollBar = new ScrollBarWidget(boss, font, _x + _w, _y, + ScrollBarWidget::scrollBarWidth(_font), _h); _scrollBar->setTarget(this); _scrollBar->_numEntries = 1; _scrollBar->_currentPos = 0; @@ -675,7 +676,7 @@ Common::Rect DataGridWidget::getEditRect() const // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - int DataGridWidget::getWidth() const { - return _w + (_scrollBar ? kScrollBarWidth : 0); + return _w + (_scrollBar ? ScrollBarWidget::scrollBarWidth(_font) : 0); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/debugger/gui/DebuggerDialog.cxx b/src/debugger/gui/DebuggerDialog.cxx index ed98fa879..5d8404d06 100644 --- a/src/debugger/gui/DebuggerDialog.cxx +++ b/src/debugger/gui/DebuggerDialog.cxx @@ -71,12 +71,11 @@ DebuggerDialog::DebuggerDialog(OSystem& osystem, DialogContainer& parent, // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void DebuggerDialog::loadConfig() { - // set initial focus to myPrompt - if (myFirstLoad) - { - setFocus(myPrompt); - myFirstLoad = false; - } + if(myFocusedWidget == nullptr) + // Set initial focus to prompt tab + myFocusedWidget = myPrompt; + // Restore focus + setFocus(myFocusedWidget); myTab->loadConfig(); myTiaInfo->loadConfig(); @@ -89,6 +88,11 @@ void DebuggerDialog::loadConfig() myMessageBox->setText(""); } +void DebuggerDialog::saveConfig() +{ + myFocusedWidget = _focusedWidget; +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void DebuggerDialog::handleKeyDown(StellaKey key, StellaMod mod, bool repeated) { @@ -231,7 +235,7 @@ void DebuggerDialog::handleCommand(CommandSender* sender, int cmd, doUnwind(); break; - case kDDExitCmd: + case kDDRunCmd: doExitDebugger(); break; @@ -541,7 +545,7 @@ void DebuggerDialog::addRomArea() wid2.push_back(b); buttonY += bheight + 4; b = new ButtonWidget(this, *myLFont, buttonX, buttonY, - bwidth, bheight, "Exit", kDDExitCmd); + bwidth, bheight, "Run", kDDRunCmd); wid2.push_back(b); addCancelWidget(b); diff --git a/src/debugger/gui/DebuggerDialog.hxx b/src/debugger/gui/DebuggerDialog.hxx index f9f11e459..2fa007214 100644 --- a/src/debugger/gui/DebuggerDialog.hxx +++ b/src/debugger/gui/DebuggerDialog.hxx @@ -71,6 +71,7 @@ class DebuggerDialog : public Dialog ButtonWidget& unwindButton() const { return *myUnwindButton; } void showFatalMessage(const string& msg); + void saveConfig(); private: void center() override { positionAt(0); } @@ -110,7 +111,7 @@ class DebuggerDialog : public Dialog kDDSAdvCmd = 'DDsv', kDDRewindCmd = 'DDrw', kDDUnwindCmd = 'DDuw', - kDDExitCmd = 'DDex', + kDDRunCmd = 'DDex', kDDExitFatalCmd = 'DDer', kDDOptionsCmd = 'DDop' }; @@ -136,7 +137,8 @@ class DebuggerDialog : public Dialog unique_ptr myLFont; // used for labels unique_ptr myNFont; // used for normal text - bool myFirstLoad{true}; + Widget* myFocusedWidget{nullptr}; + private: // Following constructors and assignment operators not supported diff --git a/src/debugger/gui/FlashWidget.cxx b/src/debugger/gui/FlashWidget.cxx index ace5e30cb..3c2614659 100644 --- a/src/debugger/gui/FlashWidget.cxx +++ b/src/debugger/gui/FlashWidget.cxx @@ -30,7 +30,6 @@ FlashWidget::FlashWidget(GuiObject* boss, const GUI::Font& font, // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void FlashWidget::init(GuiObject* boss, const GUI::Font& font, int x, int y) { - const GUI::Font& ifont = instance().frameBuffer().infoFont(); const int lineHeight = font.getLineHeight(); int xpos = x, ypos = y; @@ -38,14 +37,14 @@ void FlashWidget::init(GuiObject* boss, const GUI::Font& font, int x, int y) ypos += lineHeight + 6; - new StaticTextWidget(boss, ifont, xpos, ypos, "Pages/Ranges used:"); + new StaticTextWidget(boss, font, xpos, ypos, "Pages/Ranges used:"); ypos += lineHeight + 2; xpos += 8; for(uInt32 page = 0; page < MAX_PAGES; ++page) { - myPage[page] = new StaticTextWidget(boss, ifont, xpos, ypos, + myPage[page] = new StaticTextWidget(boss, font, xpos, ypos, page ? " " : "none "); ypos += lineHeight; } diff --git a/src/debugger/gui/PromptWidget.cxx b/src/debugger/gui/PromptWidget.cxx index a7910f8e8..b803adc17 100644 --- a/src/debugger/gui/PromptWidget.cxx +++ b/src/debugger/gui/PromptWidget.cxx @@ -33,7 +33,7 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - PromptWidget::PromptWidget(GuiObject* boss, const GUI::Font& font, int x, int y, int w, int h) - : Widget(boss, font, x, y, w - kScrollBarWidth, h), + : Widget(boss, font, x, y, w - ScrollBarWidget::scrollBarWidth(font), h), CommandSender(boss), _historySize(0), _historyIndex(0), @@ -53,12 +53,13 @@ PromptWidget::PromptWidget(GuiObject* boss, const GUI::Font& font, _kConsoleLineHeight = _kConsoleCharHeight + 2; // Calculate depending values - _lineWidth = (_w - kScrollBarWidth - 2) / _kConsoleCharWidth; + _lineWidth = (_w - ScrollBarWidget::scrollBarWidth(_font) - 2) / _kConsoleCharWidth; _linesPerPage = (_h - 2) / _kConsoleLineHeight; _linesInBuffer = kBufferSize / _lineWidth; // Add scrollbar - _scrollBar = new ScrollBarWidget(boss, font, _x + _w, _y, kScrollBarWidth, _h); + _scrollBar = new ScrollBarWidget(boss, font, _x + _w, _y, + ScrollBarWidget::scrollBarWidth(_font), _h); _scrollBar->setTarget(this); // Init colors @@ -546,7 +547,7 @@ void PromptWidget::loadConfig() // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - int PromptWidget::getWidth() const { - return _w + kScrollBarWidth; + return _w + ScrollBarWidget::scrollBarWidth(_font); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/debugger/gui/RiotWidget.cxx b/src/debugger/gui/RiotWidget.cxx index eef3cce66..43514e072 100644 --- a/src/debugger/gui/RiotWidget.cxx +++ b/src/debugger/gui/RiotWidget.cxx @@ -214,7 +214,7 @@ RiotWidget::RiotWidget(GuiObject* boss, const GUI::Font& lfont, // 2600/7800 mode lwidth = lfont.getStringWidth("Console") + 29; - pwidth = lfont.getStringWidth("Atari 2600") + 4; + pwidth = lfont.getStringWidth("Atari 2600") + 6; new StaticTextWidget(boss, lfont, 10, ypos+1, "Console"); myConsole = new EditTextWidget(boss, lfont, 10 + lwidth, ypos - 1, pwidth, lineHeight); myConsole->setEditable(false, true); diff --git a/src/debugger/gui/RomListWidget.cxx b/src/debugger/gui/RomListWidget.cxx index b4af0daf7..64ca2df9d 100644 --- a/src/debugger/gui/RomListWidget.cxx +++ b/src/debugger/gui/RomListWidget.cxx @@ -42,11 +42,12 @@ RomListWidget::RomListWidget(GuiObject* boss, const GUI::Font& lfont, _rows = h / _fontHeight; // Set real dimensions - _w = w - kScrollBarWidth; + _w = w - ScrollBarWidget::scrollBarWidth(_font); _h = h + 2; // Create scrollbar and attach to the list - myScrollBar = new ScrollBarWidget(boss, lfont, _x + _w, _y, kScrollBarWidth, _h); + myScrollBar = new ScrollBarWidget(boss, lfont, _x + _w, _y, + ScrollBarWidget::scrollBarWidth(_font), _h); myScrollBar->setTarget(this); // Add settings menu @@ -65,7 +66,7 @@ RomListWidget::RomListWidget(GuiObject* boss, const GUI::Font& lfont, // rowheight is determined by largest item on a line, // possibly meaning that number of rows will change - _fontHeight = std::max(_fontHeight, CheckboxWidget::boxSize()); + _fontHeight = std::max(_fontHeight, CheckboxWidget::boxSize(_font)); _rows = h / _fontHeight; // Create a CheckboxWidget for each row in the list @@ -465,7 +466,7 @@ void RomListWidget::drawWidget(bool hilite) // Draw a thin frame around the list and to separate columns s.frameRect(_x, _y, _w + 1, _h, hilite ? kWidColorHi : kColor); - s.vLine(_x + CheckboxWidget::boxSize() + 5, _y, _y + _h - 1, kColor); + s.vLine(_x + CheckboxWidget::boxSize(_font) + 5, _y, _y + _h - 1, kColor); // Draw the list items int cycleCountW = _fontWidth * 8, @@ -476,7 +477,7 @@ void RomListWidget::drawWidget(bool hilite) if(actualWidth < codeDisasmW) codeDisasmW = actualWidth; - xpos = _x + CheckboxWidget::boxSize() + 10; ypos = _y + 2; + xpos = _x + CheckboxWidget::boxSize(_font) + 10; ypos = _y + 2; for (i = 0, pos = _currentPos; i < _rows && pos < len; i++, pos++, ypos += _fontHeight) { ColorId bytesColor = textColor; @@ -566,7 +567,7 @@ void RomListWidget::drawWidget(bool hilite) Common::Rect RomListWidget::getLineRect() const { const int yoffset = std::max(0, (_selectedItem - _currentPos) * _fontHeight), - xoffset = CheckboxWidget::boxSize() + 10; + xoffset = CheckboxWidget::boxSize(_font) + 10; return Common::Rect(2 + xoffset, 1 + yoffset, _w - (xoffset - 15), _fontHeight + yoffset); diff --git a/src/debugger/gui/TiaInfoWidget.cxx b/src/debugger/gui/TiaInfoWidget.cxx index 33ea5c7cf..21681d2c0 100644 --- a/src/debugger/gui/TiaInfoWidget.cxx +++ b/src/debugger/gui/TiaInfoWidget.cxx @@ -34,15 +34,16 @@ TiaInfoWidget::TiaInfoWidget(GuiObject* boss, const GUI::Font& lfont, : Widget(boss, lfont, x, y, 16, 16), CommandSender(boss) { - bool longstr = 34 * lfont.getMaxCharWidth() <= max_w; + bool longstr = 11 + 32 * lfont.getMaxCharWidth() + 9 + + EditTextWidget::calcWidth(lfont) * 3 <= max_w; const int VGAP = 5; x += 11; const int lineHeight = lfont.getLineHeight(); int xpos = x, ypos = y + 10; int lwidth = lfont.getStringWidth(longstr ? "Frame Cycle " : "F. Cycle "); - int fwidth = 5 * lfont.getMaxCharWidth() + 4; - int twidth = 8 * lfont.getMaxCharWidth() + 4; + int fwidth = EditTextWidget::calcWidth(lfont, 5); + int twidth = EditTextWidget::calcWidth(lfont, 8); // Add frame info // 1st column @@ -78,11 +79,9 @@ TiaInfoWidget::TiaInfoWidget(GuiObject* boss, const GUI::Font& lfont, // 2nd column xpos = x + lwidth + myFrameCycles->getWidth() + 9; ypos = y + 10; lwidth = lfont.getStringWidth(longstr ? "Color Clock " : "Pixel Pos "); - fwidth = 3 * lfont.getMaxCharWidth() + 4; + fwidth = EditTextWidget::calcWidth(lfont, 3); - new StaticTextWidget(boss, lfont, xpos, ypos, - lfont.getStringWidth(longstr ? "Scanline" : "Scn Ln"), lineHeight, - longstr ? "Scanline" : "Scn Ln", TextAlign::Left); + new StaticTextWidget(boss, lfont, xpos, ypos, longstr ? "Scanline" : "Scn Ln"); myScanlineCountLast = new EditTextWidget(boss, nfont, xpos+lwidth, ypos-1, fwidth, lineHeight, ""); myScanlineCountLast->setEditable(false, true); diff --git a/src/emucore/DefProps.hxx b/src/emucore/DefProps.hxx index 354f68d30..36db315de 100644 --- a/src/emucore/DefProps.hxx +++ b/src/emucore/DefProps.hxx @@ -2092,7 +2092,7 @@ static const BSPF::array2D DefProps = {{ { "95a69cf8c08ef1522b050529464f0bca", "", "", "Grid Pattern Demo 1 (20-12-2002) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, { "95a89d1bf767d7cc9d0d5093d579ba61", "PlayAround - J.H.M.", "204", "Lady in Wading (1982) (PlayAround)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, { "95e1d834c57cdd525dd0bd6048a57f7b", "Atari, Bill Aspromonte, John Russell, Michael Sierchio, Robert Zdybel", "CX26114", "Pigs in Space (1983) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "95e542a7467c94b1e4ab24a3ebe907f1", "Suntek", "SS-021", "Dragon Defender (1983) (Suntek) (PAL)", "", "", "", "", "", "", "", "", "", "MINDLINK", "", "", "", "", "", "", "", "YES", "" }, + { "95e542a7467c94b1e4ab24a3ebe907f1", "Suntek", "SS-021", "Dragon Defender (1983) (Suntek) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, { "95fd6097dc27c20666f039cfe34f7c69", "", "", "Oh No! (Version 1) (17-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, { "961112b74a920a5242e233480326c356", "Activision, Alan Miller", "AG-007, CAG-007", "Tennis (1981) (Activision) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, { "962ffd3eaf865230a7a312b80e6c5cfd", "Imagic, Wilfredo 'Willy' Aguilar, Michael Becker, Rob Fulop", "13205", "Fathom (1983) (Imagic) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, diff --git a/src/emucore/DispatchResult.hxx b/src/emucore/DispatchResult.hxx index 4ce172aeb..6d76cf5ce 100644 --- a/src/emucore/DispatchResult.hxx +++ b/src/emucore/DispatchResult.hxx @@ -55,7 +55,7 @@ class DispatchResult if (myStatus != status) throw runtime_error("invalid status for operation"); } - template void assertStatus(Status status, Ts... more) const + template void assertStatus(Status status, Ts... more) const { if (myStatus == status) return; diff --git a/src/emucore/EventHandlerConstants.hxx b/src/emucore/EventHandlerConstants.hxx index 7246983eb..8f11ecab6 100644 --- a/src/emucore/EventHandlerConstants.hxx +++ b/src/emucore/EventHandlerConstants.hxx @@ -82,7 +82,8 @@ enum class EventMode { kPaddlesMode, kKeypadMode, kCompuMateMode, // cannot be remapped - kCommonMode // mapping common between controllers + kCommonMode, // mapping common between controllers + kNumModes }; namespace GUI diff --git a/src/emucore/FrameBuffer.cxx b/src/emucore/FrameBuffer.cxx index 3c64c5d8f..eb35cfe5c 100644 --- a/src/emucore/FrameBuffer.cxx +++ b/src/emucore/FrameBuffer.cxx @@ -36,6 +36,7 @@ #ifdef GUI_SUPPORT #include "Font.hxx" #include "StellaFont.hxx" + #include "ConsoleMediumFont.hxx" #include "ConsoleMediumBFont.hxx" #include "StellaMediumFont.hxx" #include "StellaLargeFont.hxx" @@ -97,56 +98,7 @@ bool FrameBuffer::initialize() } #ifdef GUI_SUPPORT - //////////////////////////////////////////////////////////////////// - // Create fonts to draw text - // NOTE: the logic determining appropriate font sizes is done here, - // so that the UI classes can just use the font they expect, - // and not worry about it - // This logic should also take into account the size of the - // framebuffer, and try to be intelligent about font sizes - // We can probably add ifdefs to take care of corner cases, - // but that means we've failed to abstract it enough ... - //////////////////////////////////////////////////////////////////// - - // This font is used in a variety of situations when a really small - // font is needed; we let the specific widget/dialog decide when to - // use it - mySmallFont = make_unique(GUI::stellaDesc); // 6x10 - - // The general font used in all UI elements - // This is determined by the size of the framebuffer - if(myOSystem.settings().getBool("minimal_ui")) - { - myFont = make_unique(GUI::stella12x24tDesc); // 12x24 - // The info font used in all UI elements - // This is determined by the size of the framebuffer - myInfoFont = make_unique(GUI::stellaLargeDesc); // 10x20 - } - else - { - myFont = make_unique(GUI::stellaMediumDesc); // 9x18 - // The info font used in all UI elements - // This is determined by the size of the framebuffer - myInfoFont = make_unique(GUI::consoleDesc); // 8x13 - } - - - // The font used by the ROM launcher - const string& lf = myOSystem.settings().getString("launcherfont"); - if(lf == "small") - myLauncherFont = make_unique(GUI::consoleBDesc); // 8x13 - else if(lf == "low_medium") - myLauncherFont = make_unique(GUI::consoleMediumBDesc); // 9x15 - else if(lf == "medium") - myLauncherFont = make_unique(GUI::stellaMediumDesc); // 9x18 - else if(lf == "large" || lf == "large10") - myLauncherFont = make_unique(GUI::stellaLargeDesc); // 10x20 - else if(lf == "large12") - myLauncherFont = make_unique(GUI::stella12x24tDesc); // 12x24 - else if(lf == "large14") - myLauncherFont = make_unique(GUI::stella14x28tDesc); // 14x28 - else // "large16" - myLauncherFont = make_unique(GUI::stella16x32tDesc); // 16x32 + setupFonts(); #endif // Determine possible TIA windowed zoom levels @@ -164,6 +116,92 @@ bool FrameBuffer::initialize() return true; } +#ifdef GUI_SUPPORT +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void FrameBuffer::setupFonts() +{ + //////////////////////////////////////////////////////////////////// + // Create fonts to draw text + // NOTE: the logic determining appropriate font sizes is done here, + // so that the UI classes can just use the font they expect, + // and not worry about it + // This logic should also take into account the size of the + // framebuffer, and try to be intelligent about font sizes + // We can probably add ifdefs to take care of corner cases, + // but that means we've failed to abstract it enough ... + //////////////////////////////////////////////////////////////////// + + // This font is used in a variety of situations when a really small + // font is needed; we let the specific widget/dialog decide when to + // use it + mySmallFont = make_unique(GUI::stellaDesc); // 6x10 + + if(myOSystem.settings().getBool("minimal_ui")) + { + // The general font used in all UI elements + myFont = make_unique(GUI::stella12x24tDesc); // 12x24 + // The info font used in all UI elements + myInfoFont = make_unique(GUI::stellaLargeDesc); // 10x20 + } + else + { + const int NUM_FONTS = 7; + FontDesc FONT_DESC[NUM_FONTS] = {GUI::consoleDesc, GUI::consoleMediumDesc, GUI::stellaMediumDesc, + GUI::stellaLargeDesc, GUI::stella12x24tDesc, GUI::stella14x28tDesc, GUI::stella16x32tDesc}; + const string& dialogFont = myOSystem.settings().getString("dialogfont"); + FontDesc fd = getFontDesc(dialogFont); + + // The general font used in all UI elements + myFont = make_unique(fd); // default: 9x18 + // The info font used in all UI elements, + // automatically determined aiming for 1 / 1.4 (~= 18 / 13) size + int fontIdx = 0; + for(int i = 0; i < NUM_FONTS; ++i) + { + if(fd.height <= FONT_DESC[i].height * 1.4) + { + fontIdx = i; + break; + } + } + myInfoFont = make_unique(FONT_DESC[fontIdx]); // default 8x13 + + // Determine minimal zoom level based on the default font + // So what fits with default font should fit for any font. + // However, we have to make sure all Dialogs are sized using the fontsize. + int zoom_h = (fd.height * 4 * 2) / GUI::stellaMediumDesc.height; + int zoom_w = (fd.maxwidth * 4 * 2) / GUI::stellaMediumDesc.maxwidth; + myTIAMinZoom = std::max(zoom_w, zoom_h) / 4.F; // round to 25% steps + } + + + // The font used by the ROM launcher + const string& lf = myOSystem.settings().getString("launcherfont"); + + + myLauncherFont = make_unique(getFontDesc(lf)); // 8x13 +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +FontDesc FrameBuffer::getFontDesc(const string& name) const +{ + if(name == "small") + return GUI::consoleBDesc; // 8x13 + else if(name == "low_medium") + return GUI::consoleMediumBDesc; // 9x15 + else if(name == "medium") + return GUI::stellaMediumDesc; // 9x18 + else if(name == "large" || name == "large10") + return GUI::stellaLargeDesc; // 10x20 + else if(name == "large12") + return GUI::stella12x24tDesc; // 12x24 + else if(name == "large14") + return GUI::stella14x28tDesc; // 14x28 + else // "large16" + return GUI::stella16x32tDesc; // 16x32 +} +#endif + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - FBInitStatus FrameBuffer::createDisplay(const string& title, uInt32 width, uInt32 height, @@ -268,7 +306,7 @@ FBInitStatus FrameBuffer::createDisplay(const string& title, } if(!myMsg.surface) - myMsg.surface = allocateSurface(FBMinimum::Width, font().getFontHeight()+10); + myMsg.surface = allocateSurface(FBMinimum::Width, font().getFontHeight() * 1.5); #endif // Print initial usage message, but only print it later if the status has changed @@ -454,14 +492,20 @@ void FrameBuffer::showMessage(const string& message, MessagePosition position, if(myMsg.surface == nullptr || !(force || myOSystem.settings().getBool("uimessages"))) return; + const int fontWidth = font().getMaxCharWidth(), + fontHeight = font().getFontHeight(); + const int VBORDER = fontHeight / 4; + const int HBORDER = fontWidth * 1.25 / 2.0; + // Precompute the message coordinates myMsg.text = message; myMsg.counter = uInt32(myOSystem.frameRate()) << 1; // Show message for 2 seconds if(myMsg.counter == 0) myMsg.counter = 60; myMsg.color = kBtnTextColor; - myMsg.w = font().getStringWidth(myMsg.text) + 10; - myMsg.h = font().getFontHeight() + 8; + myMsg.w = font().getStringWidth(myMsg.text) + HBORDER * 2; + myMsg.h = fontHeight + VBORDER * 2; + myMsg.surface->setSrcSize(myMsg.w, myMsg.h); myMsg.surface->setDstSize(myMsg.w * hidpiScaleFactor(), myMsg.h * hidpiScaleFactor()); myMsg.position = position; @@ -580,6 +624,10 @@ inline bool FrameBuffer::drawMessage() // Draw the bounded box and text const Common::Rect& dst = myMsg.surface->dstRect(); + const int fontWidth = font().getMaxCharWidth(), + fontHeight = font().getFontHeight(); + const int VBORDER = fontHeight / 4; + const int HBORDER = fontWidth * 1.25 / 2.0; switch(myMsg.position) { @@ -630,10 +678,10 @@ inline bool FrameBuffer::drawMessage() } myMsg.surface->setDstPos(myMsg.x + myImageRect.x(), myMsg.y + myImageRect.y()); - myMsg.surface->fillRect(1, 1, myMsg.w-2, myMsg.h-2, kBtnColor); + myMsg.surface->fillRect(1, 1, myMsg.w - 2, myMsg.h - 2, kBtnColor); myMsg.surface->frameRect(0, 0, myMsg.w, myMsg.h, kColor); - myMsg.surface->drawString(font(), myMsg.text, 5, 4, - myMsg.w, myMsg.color, TextAlign::Left); + myMsg.surface->drawString(font(), myMsg.text, HBORDER, VBORDER, + myMsg.w, myMsg.color); myMsg.surface->render(); myMsg.counter--; #endif @@ -965,7 +1013,7 @@ void FrameBuffer::setAvailableVidModes(uInt32 baseWidth, uInt32 baseHeight) if(tiaMode) { // TIA windowed modes - uInt32 minZoom = supportedTIAMinZoom(); + float minZoom = supportedTIAMinZoom(); myTIAMaxZoom = maxZoomForScreen(baseWidth, baseHeight, myAbsDesktopSize.w, myAbsDesktopSize.h); // Determine all zoom levels diff --git a/src/emucore/FrameBuffer.hxx b/src/emucore/FrameBuffer.hxx index 67628ee84..35c656cf0 100644 --- a/src/emucore/FrameBuffer.hxx +++ b/src/emucore/FrameBuffer.hxx @@ -26,9 +26,9 @@ class Settings; class FBSurface; class TIASurface; -namespace GUI { - class Font; -} +#ifdef GUI_SUPPORT + #include "Font.hxx" +#endif #include "Rect.hxx" #include "Variant.hxx" @@ -223,7 +223,7 @@ class FrameBuffer Get the minimum/maximum supported TIA zoom level (windowed mode) for the framebuffer. */ - float supportedTIAMinZoom() const { return 2 * hidpiScaleFactor(); } + float supportedTIAMinZoom() const { return myTIAMinZoom * hidpiScaleFactor(); } float supportedTIAMaxZoom() const { return myTIAMaxZoom; } /** @@ -307,6 +307,15 @@ class FrameBuffer const GUI::Font& infoFont() const { return *myInfoFont; } const GUI::Font& smallFont() const { return *mySmallFont; } const GUI::Font& launcherFont() const { return *myLauncherFont; } + + /** + Get the font description from the font name + + @param name The settings name of the font + + @return The description of the font + */ + FontDesc getFontDesc(const string& name) const; #endif ////////////////////////////////////////////////////////////////////// @@ -480,6 +489,13 @@ class FrameBuffer */ void resetSurfaces(); + #ifdef GUI_SUPPORT + /** + Setup the UI fonts + */ + void setupFonts(); + #endif + /** Calculate the maximum level by which the base window can be zoomed and still fit in the given screen dimensions. @@ -619,6 +635,8 @@ class FrameBuffer VideoModeList myWindowedModeList; vector myFullscreenModeLists; + // Minimum TIA zoom level that can be used for this framebuffer + float myTIAMinZoom{2.F}; // Maximum TIA zoom level that can be used for this framebuffer float myTIAMaxZoom{1.F}; diff --git a/src/emucore/OSystem.cxx b/src/emucore/OSystem.cxx index 832b1ce35..bbaa72aa5 100644 --- a/src/emucore/OSystem.cxx +++ b/src/emucore/OSystem.cxx @@ -646,11 +646,35 @@ ByteBuffer OSystem::openROM(const FilesystemNode& rom, string& md5, size_t& size if(md5 == "") md5 = MD5::hash(image, size); - // Some games may not have a name, since there may not - // be an entry in stella.pro. In that case, we use the rom name - // and reinsert the properties object + // Handle ROM properties, do some error checking + // Only add to the database when necessary + bool toInsert = false; + + // First, does this ROM have a per-ROM properties entry? + // If so, load it into the database + FilesystemNode propsNode(rom.getPathWithExt(".pro")); + if(propsNode.exists() && propsNode.isFile()) + { + Logger::info("Loading per-ROM properties: " + propsNode.getShortPath()); + myPropSet->load(propsNode.getPath(), false); + } + + // Next, make sure we have a valid md5 and name Properties props; - myPropSet->getMD5WithInsert(rom, md5, props); + if(!myPropSet->getMD5(md5, props)) + { + props.set(PropType::Cart_MD5, md5); + toInsert = true; + } + if(toInsert || props.get(PropType::Cart_Name) == EmptyString) + { + props.set(PropType::Cart_Name, rom.getNameWithExt("")); + toInsert = true; + } + + // Finally, insert properties if any info was missing + if(toInsert) + myPropSet->insert(props, false); return image; } diff --git a/src/emucore/PropsSet.cxx b/src/emucore/PropsSet.cxx index 5375a269e..a13a9c759 100644 --- a/src/emucore/PropsSet.cxx +++ b/src/emucore/PropsSet.cxx @@ -24,13 +24,13 @@ #include "PropsSet.hxx" // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void PropertiesSet::load(const string& filename) +void PropertiesSet::load(const string& filename, bool save) { ifstream in(filename); Properties prop; while(in >> prop) - insert(prop); + insert(prop, save); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -117,26 +117,6 @@ bool PropertiesSet::getMD5(const string& md5, Properties& properties, return found; } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void PropertiesSet::getMD5WithInsert(const FilesystemNode& rom, - const string& md5, Properties& properties) -{ - bool toInsert = false; - - if(!getMD5(md5, properties)) - { - properties.set(PropType::Cart_MD5, md5); - toInsert = true; - } - if(toInsert || properties.get(PropType::Cart_Name) == EmptyString) - { - properties.set(PropType::Cart_Name, rom.getNameWithExt("")); - toInsert = true; - } - if(toInsert) - insert(properties, false); -} - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void PropertiesSet::insert(const Properties& properties, bool save) { diff --git a/src/emucore/PropsSet.hxx b/src/emucore/PropsSet.hxx index 684137817..71924749a 100644 --- a/src/emucore/PropsSet.hxx +++ b/src/emucore/PropsSet.hxx @@ -49,8 +49,10 @@ class PropertiesSet searchable list. @param filename Full pathname of input file to use + @param save Indicates whether the properties should be saved + when the program exits */ - void load(const string& filename); + void load(const string& filename, bool save = true); /** Save properties to the specified file. @@ -78,19 +80,6 @@ class PropertiesSet bool getMD5(const string& md5, Properties& properties, bool useDefaults = false) const; - /** - Get the property from the set with the given MD5, at the same time - checking if it exists. If it doesn't, insert a temporary copy into - the set. - - @param rom The ROM file used to calculate the MD5 - @param md5 The md5 of the property to get - @param properties The properties with the given MD5, or the default - properties if not found - */ - void getMD5WithInsert(const FilesystemNode& rom, const string& md5, - Properties& properties); - /** Insert the properties into the set. If a duplicate is inserted the old properties are overwritten with the new ones. diff --git a/src/emucore/Settings.cxx b/src/emucore/Settings.cxx index 50e45cd06..599c8badf 100644 --- a/src/emucore/Settings.cxx +++ b/src/emucore/Settings.cxx @@ -146,6 +146,7 @@ Settings::Settings() setPermanent("ctrldelay", "400"); setPermanent("ctrlrate", "20"); setPermanent("basic_settings", false); + setPermanent("dialogfont", "medium"); setPermanent("dialogpos", 0); setPermanent("confirmexit", false); @@ -510,6 +511,11 @@ void Settings::usage() const << " -uipalette \n" << " -hidpi <0|1> Enable HiDPI mode\n" + << " -dialogfont \n" << " -dialogpos <0..4> Display all dialogs at given positions\n" << " -confirmexit <0|1> Display a confirm dialog when exiting emulation\n" << " -listdelay Time to wait between keypresses in list widgets\n" diff --git a/src/emucore/stella.pro b/src/emucore/stella.pro index ef12c4369..4c589fe72 100644 --- a/src/emucore/stella.pro +++ b/src/emucore/stella.pro @@ -12574,7 +12574,6 @@ "Cart.Manufacturer" "Suntek" "Cart.ModelNo" "SS-021" "Cart.Name" "Dragon Defender (1983) (Suntek) (PAL)" -"Controller.Left" "MINDLINK" "Display.Phosphor" "YES" "" diff --git a/src/emucore/tia/DelayQueue.hxx b/src/emucore/tia/DelayQueue.hxx index d3e7e544b..996bde72e 100644 --- a/src/emucore/tia/DelayQueue.hxx +++ b/src/emucore/tia/DelayQueue.hxx @@ -41,7 +41,7 @@ class DelayQueue : public Serializable void reset(); - template void execute(T executor); + template void execute(T executor); /** Serializable methods (see that class for more information). @@ -103,7 +103,7 @@ void DelayQueue::reset() // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - template -template +template void DelayQueue::execute(T executor) { DelayQueueMember& currentMember = myMembers[myIndex]; diff --git a/src/gui/AboutDialog.cxx b/src/gui/AboutDialog.cxx index 168520138..05db4b695 100644 --- a/src/gui/AboutDialog.cxx +++ b/src/gui/AboutDialog.cxx @@ -28,44 +28,49 @@ AboutDialog::AboutDialog(OSystem& osystem, DialogContainer& parent, : Dialog(osystem, parent, font, "About Stella") { const int lineHeight = font.getLineHeight(), - fontWidth = font.getMaxCharWidth(), - fontHeight = font.getFontHeight(), - buttonWidth = font.getStringWidth("Defaults") + 20, - buttonHeight = font.getLineHeight() + 4; + fontWidth = font.getMaxCharWidth(), + fontHeight = font.getFontHeight(), + buttonWidth = font.getStringWidth("Previous") + fontWidth * 2.5, + buttonHeight = font.getLineHeight() * 1.25; + const int VBORDER = fontHeight / 2; + const int HBORDER = fontWidth * 1.25; + const int INDENT = fontWidth * 2; + const int VGAP = fontHeight / 4; + int xpos, ypos; WidgetArray wid; // Set real dimensions - _w = 55 * fontWidth + 8; - _h = 15 * lineHeight + 20 + _th; + _w = 55 * fontWidth + HBORDER * 2; + _h = _th + 14 * lineHeight + VGAP * 3 + buttonHeight + VBORDER * 2; // Add Previous, Next and Close buttons - xpos = 10; ypos = _h - buttonHeight - 10; + xpos = HBORDER; ypos = _h - buttonHeight - VBORDER; myPrevButton = new ButtonWidget(this, font, xpos, ypos, buttonWidth, buttonHeight, "Previous", GuiObject::kPrevCmd); myPrevButton->clearFlags(Widget::FLAG_ENABLED); wid.push_back(myPrevButton); - xpos += buttonWidth + 8; + xpos += buttonWidth + fontWidth; myNextButton = new ButtonWidget(this, font, xpos, ypos, buttonWidth, buttonHeight, "Next", GuiObject::kNextCmd); wid.push_back(myNextButton); - xpos = _w - buttonWidth - 10; + xpos = _w - buttonWidth - HBORDER; ButtonWidget* b = new ButtonWidget(this, font, xpos, ypos, buttonWidth, buttonHeight, "Close", GuiObject::kCloseCmd); wid.push_back(b); addCancelWidget(b); - xpos = 5; ypos = 5 + _th; + xpos = HBORDER; ypos = _th + VBORDER; myTitle = new StaticTextWidget(this, font, xpos, ypos, _w - xpos * 2, fontHeight, "", TextAlign::Center); myTitle->setTextColor(kTextColorEm); - xpos = 16; ypos += lineHeight + 4; + xpos = HBORDER * 2; ypos += lineHeight + VGAP * 2; for(int i = 0; i < myLinesPerPage; i++) { myDesc.push_back(new StaticTextWidget(this, font, xpos, ypos, _w - xpos * 2, diff --git a/src/gui/AudioDialog.cxx b/src/gui/AudioDialog.cxx index cb73dee42..1f97c2f8b 100644 --- a/src/gui/AudioDialog.cxx +++ b/src/gui/AudioDialog.cxx @@ -40,12 +40,14 @@ AudioDialog::AudioDialog(OSystem& osystem, DialogContainer& parent, const GUI::Font& font) : Dialog(osystem, parent, font, "Audio settings") { - const int VBORDER = 10; - const int HBORDER = 10; - const int INDENT = 20; - const int VGAP = 4; const int lineHeight = font.getLineHeight(), + fontHeight = font.getFontHeight(), fontWidth = font.getMaxCharWidth(); + const int VBORDER = fontHeight / 2; + const int HBORDER = fontWidth * 1.25; + const int INDENT = fontWidth * 2; + const int VGAP = fontHeight / 4; + int xpos, ypos; int lwidth = font.getStringWidth("Volume "), pwidth; @@ -64,7 +66,7 @@ AudioDialog::AudioDialog(OSystem& osystem, DialogContainer& parent, "Enable sound", kSoundEnableChanged); wid.push_back(mySoundEnableCheckbox); ypos += lineHeight + VGAP; - xpos += INDENT; + xpos += CheckboxWidget::prefixSize(font); // Volume myVolumeSlider = new SliderWidget(this, font, xpos, ypos, diff --git a/src/gui/BrowserDialog.cxx b/src/gui/BrowserDialog.cxx index b64edf525..544ff4518 100644 --- a/src/gui/BrowserDialog.cxx +++ b/src/gui/BrowserDialog.cxx @@ -42,13 +42,19 @@ BrowserDialog::BrowserDialog(GuiObject* boss, const GUI::Font& font, _h = max_h; const int lineHeight = font.getLineHeight(), - buttonWidth = font.getStringWidth("Defaults") + 20, - buttonHeight = font.getLineHeight() + 4, - selectHeight = lineHeight + 12; + fontWidth = font.getMaxCharWidth(), + fontHeight = font.getFontHeight(), + buttonHeight = font.getLineHeight() * 1.25, + buttonWidth = font.getStringWidth("Base Dir") + fontWidth * 2.5; + const int VBORDER = fontHeight / 2; + const int HBORDER = fontWidth * 1.25; + const int VGAP = fontHeight / 4; + const int BUTTON_GAP = fontWidth; + const int selectHeight = lineHeight + VGAP * 3; int xpos, ypos; ButtonWidget* b; - xpos = 10; ypos = 4 + _th; + xpos = HBORDER; ypos = VBORDER + _th; // Current path - TODO: handle long paths ? StaticTextWidget* t = new StaticTextWidget(this, font, xpos, ypos + 2, "Path "); @@ -56,14 +62,14 @@ BrowserDialog::BrowserDialog(GuiObject* boss, const GUI::Font& font, _w - t->getWidth() - 2 * xpos, lineHeight); _currentPath->setEditable(false); // Add file list - ypos += lineHeight + 8; + ypos += lineHeight + VGAP * 2; _fileList = new FileListWidget(this, font, xpos, ypos, _w - 2 * xpos, - _h - selectHeight - buttonHeight - ypos - 20); + _h - selectHeight - buttonHeight - ypos - VBORDER * 2); _fileList->setEditable(false); addFocusWidget(_fileList); // Add currently selected item - ypos += _fileList->getHeight() + 8; + ypos += _fileList->getHeight() + VGAP * 2; _type = new StaticTextWidget(this, font, xpos, ypos + 2, "Name "); _selected = new EditTextWidget(this, font, xpos + _type->getWidth(), ypos, @@ -71,30 +77,30 @@ BrowserDialog::BrowserDialog(GuiObject* boss, const GUI::Font& font, _selected->setEditable(false); // Buttons - _goUpButton = new ButtonWidget(this, font, 10, _h - buttonHeight - 10, + _goUpButton = new ButtonWidget(this, font, xpos, _h - buttonHeight - VBORDER, buttonWidth, buttonHeight, "Go up", kGoUpCmd); addFocusWidget(_goUpButton); _basedirButton = - new ButtonWidget(this, font, 15 + buttonWidth, _h - buttonHeight - 10, + new ButtonWidget(this, font, _goUpButton->getRight() + BUTTON_GAP, _h - buttonHeight - VBORDER, buttonWidth, buttonHeight, "Base Dir", kBaseDirCmd); addFocusWidget(_basedirButton); #ifndef BSPF_MACOS - b = new ButtonWidget(this, font, _w - 2 * (buttonWidth + 7), _h - buttonHeight - 10, + b = new ButtonWidget(this, font, _w - (2 * buttonWidth + BUTTON_GAP + HBORDER), _h - buttonHeight - VBORDER, buttonWidth, buttonHeight, "Choose", kChooseCmd); addFocusWidget(b); addOKWidget(b); - b = new ButtonWidget(this, font, _w - (buttonWidth + 10), _h - buttonHeight - 10, + b = new ButtonWidget(this, font, _w - (buttonWidth + HBORDER), _h - buttonHeight - VBORDER, buttonWidth, buttonHeight, "Cancel", GuiObject::kCloseCmd); addFocusWidget(b); addCancelWidget(b); #else - b = new ButtonWidget(this, font, _w - 2 * (buttonWidth + 7), _h - buttonHeight - 10, + b = new ButtonWidget(this, font, _w - (2 * buttonWidth + BUTTON_GAP + HBORDER), _h - buttonHeight - VBORDER, buttonWidth, buttonHeight, "Cancel", GuiObject::kCloseCmd); addFocusWidget(b); addCancelWidget(b); - b = new ButtonWidget(this, font, _w - (buttonWidth + 10), _h - buttonHeight - 10, + b = new ButtonWidget(this, font, _w - (buttonWidth + HBORDER), _h - buttonHeight - VBORDER, buttonWidth, buttonHeight, "Choose", kChooseCmd); addFocusWidget(b); addOKWidget(b); diff --git a/src/gui/CheckListWidget.cxx b/src/gui/CheckListWidget.cxx index f228407d4..0e5a46d82 100644 --- a/src/gui/CheckListWidget.cxx +++ b/src/gui/CheckListWidget.cxx @@ -29,7 +29,7 @@ CheckListWidget::CheckListWidget(GuiObject* boss, const GUI::Font& font, // rowheight is determined by largest item on a line, // possibly meaning that number of rows will change - _fontHeight = std::max(_fontHeight, CheckboxWidget::boxSize()); + _fontHeight = std::max(_fontHeight, CheckboxWidget::boxSize(_font)); _rows = h / _fontHeight; // Create a CheckboxWidget for each row in the list @@ -100,7 +100,7 @@ void CheckListWidget::drawWidget(bool hilite) // Draw a thin frame around the list and to separate columns s.frameRect(_x, _y, _w, _h, hilite ? kWidColorHi : kColor); - s.vLine(_x + CheckboxWidget::boxSize() + 5, _y, _y + _h - 1, kColor); + s.vLine(_x + CheckboxWidget::boxSize(_font) + 5, _y, _y + _h - 1, kColor); // Draw the list items for (i = 0, pos = _currentPos; i < _rows && pos < len; i++, pos++) @@ -150,7 +150,7 @@ void CheckListWidget::drawWidget(bool hilite) Common::Rect CheckListWidget::getEditRect() const { const int yoffset = (_selectedItem - _currentPos) * _fontHeight, - xoffset = CheckboxWidget::boxSize() + 10; + xoffset = CheckboxWidget::boxSize(_font) + 10; return Common::Rect(2 + xoffset, 1 + yoffset, _w - (xoffset - 15), _fontHeight + yoffset); diff --git a/src/gui/ComboDialog.cxx b/src/gui/ComboDialog.cxx index a18e3920b..524a1a3e2 100644 --- a/src/gui/ComboDialog.cxx +++ b/src/gui/ComboDialog.cxx @@ -32,7 +32,14 @@ ComboDialog::ComboDialog(GuiObject* boss, const GUI::Font& font, : Dialog(boss->instance(), boss->parent(), font, "Add...") { const int lineHeight = font.getLineHeight(), - fontWidth = font.getMaxCharWidth(); + fontWidth = font.getMaxCharWidth(), + fontHeight = font.getFontHeight(), + buttonHeight = font.getLineHeight() * 1.25; + const int VBORDER = fontHeight / 2; + const int HBORDER = fontWidth * 1.25; + const int INDENT = fontWidth * 2; + const int VGAP = fontHeight / 4; + int xpos, ypos; WidgetArray wid; @@ -42,10 +49,10 @@ ComboDialog::ComboDialog(GuiObject* boss, const GUI::Font& font, pwidth = std::max(font.getStringWidth(s.first), pwidth); // Set real dimensions - _w = 11 * fontWidth + pwidth-4 + 10 * 2; - _h = 10 * (lineHeight + 4) + 10 + _th; - xpos = 10; - ypos = 10 + _th; + _w = 8 * fontWidth + pwidth + PopUpWidget::dropDownWidth(font) + HBORDER * 2; + _h = 8 * (lineHeight + VGAP) + VGAP + buttonHeight + VBORDER * 2 + _th; + xpos = HBORDER; + ypos = VBORDER + _th; // Add event popup for 8 events myEvents.fill(nullptr); @@ -54,7 +61,7 @@ ComboDialog::ComboDialog(GuiObject* boss, const GUI::Font& font, myEvents[idx] = new PopUpWidget(this, font, xpos, ypos, pwidth, lineHeight, combolist, label); wid.push_back(myEvents[idx]); - ypos += lineHeight + 4; + ypos += lineHeight + VGAP; }; ADD_EVENT_POPUP(0, "Event 1 "); ADD_EVENT_POPUP(1, "Event 2 "); diff --git a/src/gui/CommandDialog.cxx b/src/gui/CommandDialog.cxx index 6eaf714b7..86fc6f8c9 100644 --- a/src/gui/CommandDialog.cxx +++ b/src/gui/CommandDialog.cxx @@ -33,16 +33,19 @@ CommandDialog::CommandDialog(OSystem& osystem, DialogContainer& parent) : Dialog(osystem, parent, osystem.frameBuffer().font(), "Commands") { - const int HBORDER = 10; - const int VBORDER = 10; - const int HGAP = 8; - const int VGAP = 4; - const int buttonWidth = _font.getStringWidth("Time Machine On") + 16, - buttonHeight = _font.getLineHeight() + 6, - rowHeight = buttonHeight + VGAP; + const int lineHeight = _font.getLineHeight(), + fontHeight = _font.getFontHeight(), + fontWidth = _font.getMaxCharWidth(), + buttonHeight = _font.getLineHeight() * 1.25, + buttonWidth = _font.getStringWidth("Time Machine On") + fontWidth * 2; + const int VBORDER = fontHeight / 2; + const int HBORDER = fontWidth * 1.25; + const int VGAP = fontHeight / 4; + const int HGAP = fontWidth; + const int rowHeight = buttonHeight + VGAP; // Set real dimensions - _w = 3 * (buttonWidth + 5) + HBORDER * 2; + _w = 3 * (buttonWidth + HGAP) - HGAP + HBORDER * 2; _h = 6 * rowHeight - VGAP + VBORDER * 2 + _th; ButtonWidget* bw = nullptr; WidgetArray wid; diff --git a/src/gui/ContextMenu.cxx b/src/gui/ContextMenu.cxx index cf142255f..41f049ba2 100644 --- a/src/gui/ContextMenu.cxx +++ b/src/gui/ContextMenu.cxx @@ -23,6 +23,7 @@ #include "Dialog.hxx" #include "DialogContainer.hxx" #include "ScrollBarWidget.hxx" +#include "PopUpWidget.hxx" #include "ContextMenu.hxx" // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -35,6 +36,7 @@ ContextMenu::ContextMenu(GuiObject* boss, const GUI::Font& font, _maxWidth(width) { addItems(items); + setArrows(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -49,7 +51,7 @@ void ContextMenu::addItems(const VariantList& items) maxwidth = std::max(maxwidth, _font.getStringWidth(e.first)); _x = _y = 0; - _w = maxwidth + 23; + _w = maxwidth + PopUpWidget::dropDownWidth(_font); // 23; _h = 1; // recalculate this in ::recalc() _scrollUpColor = _firstEntry > 0 ? kScrollColor : kColor; @@ -509,7 +511,7 @@ void ContextMenu::scrollDown(int distance) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void ContextMenu::drawDialog() +void ContextMenu::setArrows() { static constexpr std::array up_arrow = { 0b00011000, @@ -532,6 +534,55 @@ void ContextMenu::drawDialog() 0b00011000 }; + static constexpr std::array up_arrow_large = { + 0b000001100000, + 0b000001100000, + 0b000011110000, + 0b000011110000, + 0b000111111000, + 0b000111111000, + 0b001111111100, + 0b001111111100, + 0b011111111110, + 0b011111111110, + 0b111111111111, + 0b111111111111 + }; + static constexpr std::array down_arrow_large = { + 0b111111111111, + 0b111111111111, + 0b011111111110, + 0b011111111110, + 0b001111111100, + 0b001111111100, + 0b000111111000, + 0b000111111000, + 0b000011110000, + 0b000011110000, + 0b000001100000, + 0b000001100000 + }; + + if(_font.getFontHeight() < 24) + { + _textOfs = 2; + _arrowSize = 8; + _upImg = up_arrow.data(); + _downImg = down_arrow.data(); + } + else + { + _textOfs = 4; + _arrowSize = 12; + _upImg = up_arrow_large.data(); + _downImg = down_arrow_large.data(); + } +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void ContextMenu::drawDialog() +{ + // Normally we add widgets and let Dialog::draw() take care of this // logic. But for some reason, this Dialog was written differently // by the ScummVM guys, so I'm not going to mess with it. @@ -549,7 +600,7 @@ void ContextMenu::drawDialog() if(_showScroll) { s.hLine(x, y+_rowHeight-1, w+2, kColor); - s.drawBitmap(up_arrow.data(), ((_w-_x)>>1)-4, (_rowHeight>>1)+y-4, _scrollUpColor, 8); + s.drawBitmap(_upImg, ((_w-_x)>>1)-4, (_rowHeight>>1)+y-4, _scrollUpColor, _arrowSize); y += _rowHeight; offset--; } @@ -558,7 +609,7 @@ void ContextMenu::drawDialog() { bool hilite = offset == current; if(hilite) s.fillRect(x, y, w, _rowHeight, kTextColorHi); - s.drawString(_font, _entries[i].first, x + 1, y + 2, w, + s.drawString(_font, _entries[i].first, x + _textOfs, y + 2, w, !hilite ? kTextColor : kTextColorInv); y += _rowHeight; } @@ -567,7 +618,7 @@ void ContextMenu::drawDialog() if(_showScroll) { s.hLine(x, y, w+2, kColor); - s.drawBitmap(down_arrow.data(), ((_w-_x)>>1)-4, (_rowHeight>>1)+y-4, _scrollDnColor, 8); + s.drawBitmap(_downImg, ((_w-_x)>>1)-4, (_rowHeight>>1)+y-4, _scrollDnColor, _arrowSize); } setDirty(); diff --git a/src/gui/ContextMenu.hxx b/src/gui/ContextMenu.hxx index 40858f8b9..221b90a30 100644 --- a/src/gui/ContextMenu.hxx +++ b/src/gui/ContextMenu.hxx @@ -95,6 +95,7 @@ class ContextMenu : public Dialog, public CommandSender bool handleJoyHat(int stick, int hat, JoyHatDir vahdirlue, int button) override; void handleEvent(Event::Type e); + void setArrows(); void drawDialog() override; void recalc(const Common::Rect& image); @@ -129,6 +130,11 @@ class ContextMenu : public Dialog, public CommandSender uInt32 _xorig{0}, _yorig{0}; uInt32 _maxWidth{0}; + int _textOfs{0}; + int _arrowSize{0}; + const uInt32* _upImg{nullptr}; + const uInt32* _downImg{nullptr}; + private: // Following constructors and assignment operators not supported ContextMenu() = delete; diff --git a/src/gui/DeveloperDialog.cxx b/src/gui/DeveloperDialog.cxx index 1d3d59aa5..0bcbe32e6 100644 --- a/src/gui/DeveloperDialog.cxx +++ b/src/gui/DeveloperDialog.cxx @@ -48,18 +48,27 @@ DeveloperDialog::DeveloperDialog(OSystem& osystem, DialogContainer& parent, const GUI::Font& font, int max_w, int max_h) : Dialog(osystem, parent, font, "Developer settings") { - const int VGAP = 4; const int lineHeight = font.getLineHeight(), - fontWidth = font.getMaxCharWidth(), - buttonHeight = font.getLineHeight() + 4; + fontHeight = font.getFontHeight(), + fontWidth = font.getMaxCharWidth(), + buttonHeight = font.getLineHeight() * 1.25; + const int VBORDER = fontHeight / 2; + const int HBORDER = fontWidth * 1.25; + const int INDENT = fontWidth * 2; + const int VGAP = fontHeight / 4; + int xpos, ypos; // Set real dimensions - setSize(54 * fontWidth + 10, 16 * (lineHeight + VGAP) + 14 + _th, max_w, max_h); + setSize(53 * fontWidth + HBORDER * 2, + _th + VGAP * 3 + lineHeight + 13 * (lineHeight + VGAP) + buttonHeight + VBORDER * 3, + max_w, max_h); // The tab widget - xpos = 2; ypos = 4; - myTab = new TabWidget(this, font, xpos, ypos + _th, _w - 2 * xpos, _h - _th - buttonHeight - 16 - ypos); + xpos = 2; ypos = VGAP; + myTab = new TabWidget(this, font, xpos, ypos + _th, + _w - 2 * xpos, + _h - _th - VGAP - buttonHeight - VBORDER * 2); addTabWidget(myTab); addEmulationTab(font); @@ -79,12 +88,16 @@ DeveloperDialog::DeveloperDialog(OSystem& osystem, DialogContainer& parent, // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void DeveloperDialog::addEmulationTab(const GUI::Font& font) { - const int HBORDER = 10; - const int INDENT = 16+4; - const int VBORDER = 8; - const int VGAP = 4; + const int lineHeight = font.getLineHeight(), + fontHeight = font.getFontHeight(), + fontWidth = font.getMaxCharWidth(), + buttonHeight = font.getLineHeight() * 1.25; + const int VBORDER = fontHeight / 2; + const int HBORDER = fontWidth * 1.25; + const int INDENT = fontWidth * 2; + const int VGAP = fontHeight / 4; + int ypos = VBORDER; - int lineHeight = font.getLineHeight(); WidgetArray wid; VariantList items; int tabID = myTab->addTab(" Emulation ", TabWidget::AUTO_WIDTH); @@ -136,13 +149,13 @@ void DeveloperDialog::addEmulationTab(const GUI::Font& font) myRandomizeCPULabel = new StaticTextWidget(myTab, font, HBORDER + INDENT * 2, ypos + 1, "Randomize CPU "); wid.push_back(myRandomizeCPULabel); - int xpos = myRandomizeCPULabel->getRight() + 10; + int xpos = myRandomizeCPULabel->getRight() + fontWidth * 1.25; for(int i = 0; i < 5; ++i) { myRandomizeCPUWidget[i] = new CheckboxWidget(myTab, font, xpos, ypos + 1, ourCPUregs[i], kRandCPUID); wid.push_back(myRandomizeCPUWidget[i]); - xpos += CheckboxWidget::boxSize() + font.getStringWidth("XX") + 20; + xpos += CheckboxWidget::boxSize(font) + font.getStringWidth("XX") + fontWidth * 2.5; } ypos += lineHeight + VGAP; @@ -182,12 +195,16 @@ void DeveloperDialog::addEmulationTab(const GUI::Font& font) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void DeveloperDialog::addTiaTab(const GUI::Font& font) { - const int HBORDER = 10; - const int INDENT = 16 + 4; - const int VBORDER = 8; - const int VGAP = 4; + const int lineHeight = font.getLineHeight(), + fontHeight = font.getFontHeight(), + fontWidth = font.getMaxCharWidth(), + buttonHeight = font.getLineHeight() * 1.25; + const int VBORDER = fontHeight / 2; + const int HBORDER = fontWidth * 1.25; + const int INDENT = fontWidth * 2; + const int VGAP = fontHeight / 4; + int ypos = VBORDER; - int lineHeight = font.getLineHeight(); int pwidth = font.getStringWidth("Faulty Cosmic Ark stars"); WidgetArray wid; VariantList items; @@ -268,13 +285,16 @@ void DeveloperDialog::addTiaTab(const GUI::Font& font) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void DeveloperDialog::addVideoTab(const GUI::Font& font) { - const int HBORDER = 10; - const int INDENT = 16 + 4; - const int VBORDER = 8; - const int VGAP = 4; + const int lineHeight = font.getLineHeight(), + fontHeight = font.getFontHeight(), + fontWidth = font.getMaxCharWidth(), + buttonHeight = font.getLineHeight() * 1.25; + const int VBORDER = fontHeight / 2; + const int HBORDER = fontWidth * 1.25; + const int INDENT = fontWidth * 2; + const int VGAP = fontHeight / 4; + int ypos = VBORDER; - int lineHeight = font.getLineHeight(); - int fontWidth = font.getMaxCharWidth(), fontHeight = font.getFontHeight(); int lwidth = font.getStringWidth("Intensity "); int pwidth = font.getMaxCharWidth() * 6; WidgetArray wid; @@ -340,7 +360,7 @@ void DeveloperDialog::addVideoTab(const GUI::Font& font) myDbgColour[idx] = new PopUpWidget(myTab, font, x, ypos - 1, pwidth, lineHeight, items, desc, lwidth, dbg_cmds[idx]); wid.push_back(myDbgColour[idx]); - x += myDbgColour[idx]->getWidth() + 10; + x += myDbgColour[idx]->getWidth() + fontWidth * 1.25; myDbgColourSwatch[idx] = new ColorWidget(myTab, font, x, ypos - 1, uInt32(2 * lineHeight), lineHeight); ypos += lineHeight + VGAP * 1; @@ -355,8 +375,11 @@ void DeveloperDialog::addVideoTab(const GUI::Font& font) // Add message concerning usage const GUI::Font& infofont = instance().frameBuffer().infoFont(); - ypos = myTab->getHeight() - 5 - fontHeight - infofont.getFontHeight() - 10; - new StaticTextWidget(myTab, infofont, HBORDER, ypos, "(*) Colors identical for player and developer settings"); + ypos = myTab->getHeight() - fontHeight - infofont.getFontHeight() - VGAP - VBORDER; + lwidth = infofont.getStringWidth("(*) Colors identical for player and developer settings"); + new StaticTextWidget(myTab, infofont, HBORDER, ypos, + std::min(lwidth, _w - HBORDER * 2), infofont.getFontHeight(), + "(*) Colors identical for player and developer settings"); // Add items for tab 2 addToFocusList(wid, myTab, tabID); @@ -403,37 +426,42 @@ void DeveloperDialog::addTimeMachineTab(const GUI::Font& font) "30m", "60m" }; - const int HBORDER = 10; - const int INDENT = 16+4; - const int VBORDER = 8; - const int VGAP = 4; - int ypos = VBORDER; - int lineHeight = font.getLineHeight(), - fontHeight = font.getFontHeight(), - fontWidth = font.getMaxCharWidth(), - lwidth = fontWidth * 11; + const int lineHeight = font.getLineHeight(), + fontHeight = font.getFontHeight(), + fontWidth = font.getMaxCharWidth(), + buttonHeight = font.getLineHeight() * 1.25; + const int VBORDER = fontHeight / 2; + const int HBORDER = fontWidth * 1.25; + const int INDENT = fontWidth * 2; + const int VGAP = fontHeight / 4; + + int xpos = HBORDER, + ypos = VBORDER, + lwidth = fontWidth * 11; WidgetArray wid; VariantList items; int tabID = myTab->addTab(" Time Machine ", TabWidget::AUTO_WIDTH); // settings set mySettingsGroupTM = new RadioButtonGroup(); - RadioButtonWidget* r = new RadioButtonWidget(myTab, font, HBORDER, ypos + 1, + RadioButtonWidget* r = new RadioButtonWidget(myTab, font, xpos, ypos + 1, "Player settings", mySettingsGroupTM, kPlrSettings); wid.push_back(r); ypos += lineHeight + VGAP; - r = new RadioButtonWidget(myTab, font, HBORDER, ypos + 1, + r = new RadioButtonWidget(myTab, font, xpos, ypos + 1, "Developer settings", mySettingsGroupTM, kDevSettings); wid.push_back(r); + xpos += INDENT; ypos += lineHeight + VGAP * 1; - myTimeMachineWidget = new CheckboxWidget(myTab, font, HBORDER + INDENT, ypos + 1, + myTimeMachineWidget = new CheckboxWidget(myTab, font, xpos, ypos + 1, "Time Machine", kTimeMachine); wid.push_back(myTimeMachineWidget); + xpos += CheckboxWidget::prefixSize(font); ypos += lineHeight + VGAP; int swidth = fontWidth * 12 + 5; // width of PopUpWidgets below - myStateSizeWidget = new SliderWidget(myTab, font, HBORDER + INDENT * 2, ypos - 1, swidth, lineHeight, + myStateSizeWidget = new SliderWidget(myTab, font, xpos, ypos - 1, swidth, lineHeight, "Buffer size (*) ", 0, kSizeChanged, lwidth, " states"); myStateSizeWidget->setMinValue(20); #ifdef RETRON77 @@ -446,7 +474,7 @@ void DeveloperDialog::addTimeMachineTab(const GUI::Font& font) wid.push_back(myStateSizeWidget); ypos += lineHeight + VGAP; - myUncompressedWidget = new SliderWidget(myTab, font, HBORDER + INDENT * 2, ypos - 1, swidth, lineHeight, + myUncompressedWidget = new SliderWidget(myTab, font, xpos, ypos - 1, swidth, lineHeight, "Uncompressed size ", 0, kUncompressedChanged, lwidth, " states"); myUncompressedWidget->setMinValue(0); #ifdef RETRON77 @@ -463,7 +491,7 @@ void DeveloperDialog::addTimeMachineTab(const GUI::Font& font) for(int i = 0; i < NUM_INTERVALS; ++i) VarList::push_back(items, INTERVALS[i], INT_SETTINGS[i]); int pwidth = font.getStringWidth("10 seconds"); - myStateIntervalWidget = new PopUpWidget(myTab, font, HBORDER + INDENT * 2, ypos, pwidth, + myStateIntervalWidget = new PopUpWidget(myTab, font, xpos, ypos, pwidth, lineHeight, items, "Interval ", 0, kIntervalChanged); wid.push_back(myStateIntervalWidget); ypos += lineHeight + VGAP; @@ -471,37 +499,42 @@ void DeveloperDialog::addTimeMachineTab(const GUI::Font& font) items.clear(); for(int i = 0; i < NUM_HORIZONS; ++i) VarList::push_back(items, HORIZONS[i], HOR_SETTINGS[i]); - myStateHorizonWidget = new PopUpWidget(myTab, font, HBORDER + INDENT * 2, ypos, pwidth, + myStateHorizonWidget = new PopUpWidget(myTab, font, xpos, ypos, pwidth, lineHeight, items, "Horizon ~ ", 0, kHorizonChanged); wid.push_back(myStateHorizonWidget); + xpos = HBORDER + INDENT; ypos += lineHeight + VGAP * 2; new StaticTextWidget(myTab, font, HBORDER, ypos + 1, "When entering/exiting emulation:"); ypos += lineHeight + VGAP; mySaveOnExitGroup = new RadioButtonGroup(); - r = new RadioButtonWidget(myTab, font, HBORDER + INDENT, ypos + 1, + r = new RadioButtonWidget(myTab, font, xpos, ypos + 1, "Do nothing", mySaveOnExitGroup); wid.push_back(r); ypos += lineHeight + VGAP; - r = new RadioButtonWidget(myTab, font, HBORDER + INDENT, ypos + 1, + r = new RadioButtonWidget(myTab, font, xpos, ypos + 1, "Save current state in current slot", mySaveOnExitGroup); wid.push_back(r); ypos += lineHeight + VGAP; - r = new RadioButtonWidget(myTab, font, HBORDER + INDENT, ypos + 1, + r = new RadioButtonWidget(myTab, font, xpos, ypos + 1, "Load/save all Time Machine states", mySaveOnExitGroup); wid.push_back(r); ypos += lineHeight + VGAP; + xpos = HBORDER; - myAutoSlotWidget = new CheckboxWidget(myTab, font, HBORDER, ypos + 1, "Automatically change save state slots"); + myAutoSlotWidget = new CheckboxWidget(myTab, font, xpos, ypos + 1, "Automatically change save state slots"); wid.push_back(myAutoSlotWidget); ypos += lineHeight + VGAP; // Add message concerning usage const GUI::Font& infofont = instance().frameBuffer().infoFont(); - ypos = myTab->getHeight() - 5 - fontHeight - infofont.getFontHeight() - 10; - new StaticTextWidget(myTab, infofont, HBORDER, ypos, "(*) Any size change clears the buffer"); + ypos = myTab->getHeight() - fontHeight - infofont.getFontHeight() - VGAP - VBORDER; + lwidth = infofont.getStringWidth("(*) Any size change clears the buffer"); + new StaticTextWidget(myTab, infofont, HBORDER, ypos, + std::min(lwidth, _w - HBORDER * 2), infofont.getFontHeight(), + "(*) Any size change clears the buffer"); addToFocusList(wid, myTab, tabID); } @@ -513,14 +546,16 @@ void DeveloperDialog::addDebuggerTab(const GUI::Font& font) WidgetArray wid; #ifdef DEBUGGER_SUPPORT - const int HBORDER = 10; - const int VBORDER = 8; - const int VGAP = 4; + const int lineHeight = font.getLineHeight(), + fontHeight = font.getFontHeight(), + fontWidth = font.getMaxCharWidth(), + buttonHeight = font.getLineHeight() * 1.25; + const int VBORDER = fontHeight / 2; + const int HBORDER = fontWidth * 1.25; + const int INDENT = fontWidth * 2; + const int VGAP = fontHeight / 4; VariantList items; - int fontWidth = font.getMaxCharWidth(), - fontHeight = font.getFontHeight(), - lineHeight = font.getLineHeight(); int xpos, ypos, pwidth; const Common::Size& ds = instance().frameBuffer().desktopSize(); @@ -537,7 +572,7 @@ void DeveloperDialog::addDebuggerTab(const GUI::Font& font) new PopUpWidget(myTab, font, HBORDER, ypos + 1, pwidth, lineHeight, items, "Font size (*) ", 0, kDFontSizeChanged); wid.push_back(myDebuggerFontSize); - ypos += lineHeight + 4; + ypos += lineHeight + VGAP; // Font style (bold label vs. text, etc) items.clear(); @@ -580,8 +615,8 @@ void DeveloperDialog::addDebuggerTab(const GUI::Font& font) // Add message concerning usage const GUI::Font& infofont = instance().frameBuffer().infoFont(); - ypos = myTab->getHeight() - 5 - fontHeight - infofont.getFontHeight() - 10; - new StaticTextWidget(myTab, infofont, HBORDER, ypos, "(*) Changes require a ROM reload"); + ypos = myTab->getHeight() - fontHeight - infofont.getFontHeight() - VGAP - VBORDER; + new StaticTextWidget(myTab, infofont, HBORDER, ypos, "(*) Change requires a ROM reload"); #if defined(DEBUGGER_SUPPORT) && defined(WINDOWED_SUPPORT) // Debugger is only realistically available in windowed modes 800x600 or greater diff --git a/src/gui/Dialog.cxx b/src/gui/Dialog.cxx index a9c60f3d1..0195fa8f9 100644 --- a/src/gui/Dialog.cxx +++ b/src/gui/Dialog.cxx @@ -139,7 +139,7 @@ void Dialog::setTitle(const string& title) if(title.empty()) _th = 0; else - _th = _font.getLineHeight() + 4; + _th = _font.getLineHeight() * 1.25; _h += _th; } @@ -383,7 +383,8 @@ void Dialog::drawDialog() if(_th) { s.fillRect(_x, _y, _w, _th, _onTop ? kColorTitleBar : kColorTitleBarLo); - s.drawString(_font, _title, _x + 10, _y + 2 + 1, _font.getStringWidth(_title), + s.drawString(_font, _title, _x + _font.getMaxCharWidth() * 1.25, _y + _font.getFontHeight() / 6, + _font.getStringWidth(_title), _onTop ? kColorTitleText : kColorTitleTextLo); } } @@ -771,15 +772,18 @@ void Dialog::addOKCancelBGroup(WidgetArray& wid, const GUI::Font& font, const string& okText, const string& cancelText, bool focusOKButton, int buttonWidth) { - const int HBORDER = 10; - const int VBORDER = 10; - const int BTN_BORDER = 20; - const int BUTTON_GAP = 8; + const int lineHeight = font.getLineHeight(), + fontWidth = font.getMaxCharWidth(), + fontHeight = font.getFontHeight(), + buttonHeight = font.getLineHeight() * 1.25; + const int VBORDER = fontHeight / 2; + const int HBORDER = fontWidth * 1.25; + const int BTN_BORDER = fontWidth * 2.5; + const int BUTTON_GAP = fontWidth; buttonWidth = std::max(buttonWidth, std::max(font.getStringWidth("Defaults"), std::max(font.getStringWidth(okText), font.getStringWidth(cancelText))) + BTN_BORDER); - int buttonHeight = font.getLineHeight() + 4; _w = std::max(HBORDER * 2 + buttonWidth * 2 + BUTTON_GAP, _w); @@ -817,11 +821,14 @@ void Dialog::addDefaultsOKCancelBGroup(WidgetArray& wid, const GUI::Font& font, const string& defaultsText, bool focusOKButton) { - const int HBORDER = 10; - const int VBORDER = 10; - const int BTN_BORDER = 20; - int buttonWidth = font.getStringWidth(defaultsText) + BTN_BORDER; - int buttonHeight = font.getLineHeight() + 4; + const int lineHeight = font.getLineHeight(), + fontWidth = font.getMaxCharWidth(), + fontHeight = font.getFontHeight(), + buttonHeight = font.getLineHeight() * 1.25; + const int VBORDER = fontHeight / 2; + const int HBORDER = fontWidth * 1.25; + const int BTN_BORDER = fontWidth * 2.5; + const int buttonWidth = font.getStringWidth(defaultsText) + BTN_BORDER; addDefaultWidget(new ButtonWidget(this, font, HBORDER, _h - buttonHeight - VBORDER, buttonWidth, buttonHeight, defaultsText, GuiObject::kDefaultsCmd)); diff --git a/src/gui/EditTextWidget.cxx b/src/gui/EditTextWidget.cxx index 09c9f3106..ff53ced5a 100644 --- a/src/gui/EditTextWidget.cxx +++ b/src/gui/EditTextWidget.cxx @@ -29,6 +29,15 @@ EditTextWidget::EditTextWidget(GuiObject* boss, const GUI::Font& font, _flags = Widget::FLAG_ENABLED | Widget::FLAG_CLEARBG | Widget::FLAG_RETAIN_FOCUS; EditableWidget::startEditMode(); // We're always in edit mode + + if(_font.getFontHeight() < 24) + { + _textOfs = 3; + } + else + { + _textOfs = 5; + } } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -92,7 +101,7 @@ void EditTextWidget::drawWidget(bool hilite) // Draw the text adjustOffset(); - s.drawString(_font, editString(), _x + 2, _y + 2, getEditRect().w(), getEditRect().h(), + s.drawString(_font, editString(), _x + _textOfs, _y + 2, getEditRect().w(), getEditRect().h(), _changed && onTop && isEnabled() ? kDbgChangedTextColor : onTop && isEnabled() ? _textcolor : kColor, @@ -105,7 +114,7 @@ void EditTextWidget::drawWidget(bool hilite) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Common::Rect EditTextWidget::getEditRect() const { - return Common::Rect(2, 1, _w - 2, _h); + return Common::Rect(_textOfs, 1, _w - _textOfs, _h); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/gui/EditTextWidget.hxx b/src/gui/EditTextWidget.hxx index 50f8bfdc8..f752ae385 100644 --- a/src/gui/EditTextWidget.hxx +++ b/src/gui/EditTextWidget.hxx @@ -32,6 +32,18 @@ class EditTextWidget : public EditableWidget void setText(const string& str, bool changed = false) override; + // Get total width of widget + static int calcWidth(const GUI::Font& font, int length = 0) + { + return length * font.getMaxCharWidth() + + (font.getFontHeight() < 24 ? 3 * 2 : 5 * 2); + } + // Get total width of widget + static int calcWidth(const GUI::Font& font, const string& str) + { + return calcWidth(font, int(str.length())); + } + protected: void drawWidget(bool hilite) override; void lostFocusWidget() override; @@ -49,6 +61,7 @@ class EditTextWidget : public EditableWidget protected: string _backupString; bool _changed{false}; + int _textOfs{0}; private: // Following constructors and assignment operators not supported diff --git a/src/gui/EventMappingWidget.cxx b/src/gui/EventMappingWidget.cxx index 3d55dffe7..bb4088173 100644 --- a/src/gui/EventMappingWidget.cxx +++ b/src/gui/EventMappingWidget.cxx @@ -44,13 +44,15 @@ EventMappingWidget::EventMappingWidget(GuiObject* boss, const GUI::Font& font, { const int fontHeight = font.getFontHeight(), lineHeight = font.getLineHeight(), - buttonWidth = font.getStringWidth("Defaults") + 10, - buttonHeight = font.getLineHeight() + 4; - const int HBORDER = 8; - const int VBORDER = 8; + fontWidth = font.getMaxCharWidth(), + buttonWidth = font.getStringWidth("Defaults") + fontWidth * 1.25, + buttonHeight = font.getLineHeight() * 1.25; + const int VBORDER = fontHeight / 2; + const int HBORDER = fontWidth * 1.25; + const int VGAP = fontHeight / 4; const int ACTION_LINES = 2; int xpos = HBORDER, ypos = VBORDER; - const int listWidth = _w - buttonWidth - HBORDER * 2 - 8; + const int listWidth = _w - buttonWidth - HBORDER * 2 - fontWidth; int listHeight = _h - (2 + ACTION_LINES) * lineHeight - VBORDER + 2; if(mode == EventMode::kEmulationMode) @@ -70,12 +72,12 @@ EventMappingWidget::EventMappingWidget(GuiObject* boss, const GUI::Font& font, VarList::push_back(items, "Debug", Event::Group::Debug); myFilterPopup = new PopUpWidget(boss, font, xpos, ypos, - listWidth - font.getStringWidth("Events ") - 23, lineHeight, - items, "Events ", 0, kFilterCmd); + listWidth - font.getStringWidth("Events ") - PopUpWidget::dropDownWidth(font), + lineHeight, items, "Events ", 0, kFilterCmd); myFilterPopup->setTarget(this); addFocusWidget(myFilterPopup); - ypos += lineHeight + 8; - listHeight -= lineHeight + 8; + ypos += lineHeight * 1.5; + listHeight -= lineHeight * 1.5; } myActionsList = new StringListWidget(boss, font, xpos, ypos, listWidth, listHeight); @@ -91,7 +93,7 @@ EventMappingWidget::EventMappingWidget(GuiObject* boss, const GUI::Font& font, myMapButton->setTarget(this); addFocusWidget(myMapButton); - ypos += lineHeight + 10; + ypos += buttonHeight + VGAP; myCancelMapButton = new ButtonWidget(boss, font, xpos, ypos, buttonWidth, buttonHeight, "Cancel", kStopMapCmd); @@ -99,14 +101,14 @@ EventMappingWidget::EventMappingWidget(GuiObject* boss, const GUI::Font& font, myCancelMapButton->clearFlags(Widget::FLAG_ENABLED); addFocusWidget(myCancelMapButton); - ypos += lineHeight + 20; + ypos += buttonHeight + VGAP * 2; myEraseButton = new ButtonWidget(boss, font, xpos, ypos, buttonWidth, buttonHeight, "Erase", kEraseCmd); myEraseButton->setTarget(this); addFocusWidget(myEraseButton); - ypos += lineHeight + 10; + ypos += buttonHeight + VGAP; myResetButton = new ButtonWidget(boss, font, xpos, ypos, buttonWidth, buttonHeight, "Reset", kResetCmd); @@ -115,7 +117,7 @@ EventMappingWidget::EventMappingWidget(GuiObject* boss, const GUI::Font& font, if(mode == EventMode::kEmulationMode) { - ypos += lineHeight + 20; + ypos += buttonHeight + VGAP * 2; myComboButton = new ButtonWidget(boss, font, xpos, ypos, buttonWidth, buttonHeight, "Combo" + ELLIPSIS, kComboCmd); @@ -128,13 +130,13 @@ EventMappingWidget::EventMappingWidget(GuiObject* boss, const GUI::Font& font, // Show message for currently selected event xpos = HBORDER; - ypos = myActionsList->getBottom() + 8; + ypos = myActionsList->getBottom() + VGAP * 2; StaticTextWidget* t; t = new StaticTextWidget(boss, font, xpos, ypos+2, font.getStringWidth("Action"), fontHeight, "Action", TextAlign::Left); - myKeyMapping = new EditTextWidget(boss, font, xpos + t->getWidth() + 8, ypos, - _w - xpos - t->getWidth() - 8 - HBORDER, + myKeyMapping = new EditTextWidget(boss, font, xpos + t->getWidth() + fontWidth, ypos, + _w - xpos - t->getWidth() - fontWidth - HBORDER + 2, lineHeight + font.getFontHeight() * (ACTION_LINES - 1), ""); myKeyMapping->setEditable(false, true); myKeyMapping->clearFlags(Widget::FLAG_RETAIN_FOCUS); diff --git a/src/gui/GameInfoDialog.cxx b/src/gui/GameInfoDialog.cxx index bd5d87402..fd646c6ed 100644 --- a/src/gui/GameInfoDialog.cxx +++ b/src/gui/GameInfoDialog.cxx @@ -52,14 +52,16 @@ GameInfoDialog::GameInfoDialog( CommandSender(boss) { const GUI::Font& ifont = instance().frameBuffer().infoFont(); - const int lineHeight = font.getLineHeight(), - fontWidth = font.getMaxCharWidth(), - fontHeight = font.getFontHeight(), - buttonHeight = font.getLineHeight() + 4, + + const int lineHeight = font.getLineHeight(), + fontHeight = font.getFontHeight(), + fontWidth = font.getMaxCharWidth(), + buttonHeight = font.getLineHeight() * 1.25, infoLineHeight = ifont.getLineHeight(); - const int VBORDER = 8; - const int HBORDER = 10; - const int VGAP = 4; + const int VBORDER = fontHeight / 2; + const int HBORDER = fontWidth * 1.25; + const int INDENT = fontWidth * 2; + const int VGAP = fontHeight / 4; int xpos, ypos, lwidth, fwidth, pwidth, tabID; WidgetArray wid; @@ -67,19 +69,20 @@ GameInfoDialog::GameInfoDialog( StaticTextWidget* t; // Set real dimensions - setSize(55 * fontWidth + 8, - 8 * (lineHeight + VGAP) + 1 * (infoLineHeight + VGAP) + VBORDER * 2 + _th + - buttonHeight + fontHeight + ifont.getLineHeight() + 20, + setSize(54 * fontWidth + HBORDER * 2, + _th + VGAP * 3 + lineHeight + 8 * (lineHeight + VGAP) + 1 * (infoLineHeight + VGAP) + + ifont.getLineHeight() + VGAP + buttonHeight + VBORDER * 2, max_w, max_h); // The tab widget - myTab = new TabWidget(this, font, 2, 4 + _th, _w - 2 * 2, - _h - (_th + buttonHeight + 20)); + myTab = new TabWidget(this, font, 2, 4 + _th, + _w - 2 * 2, + _h - _th - VGAP - buttonHeight - VBORDER * 2); addTabWidget(myTab); ////////////////////////////////////////////////////////////////////////////// // 1) Emulation properties - tabID = myTab->addTab("Emulation"); + tabID = myTab->addTab(" Emulation ", TabWidget::AUTO_WIDTH); ypos = VBORDER; @@ -88,12 +91,12 @@ GameInfoDialog::GameInfoDialog( items.clear(); for(uInt32 i = 0; i < uInt32(Bankswitch::Type::NumSchemes); ++i) VarList::push_back(items, Bankswitch::BSList[i].desc, Bankswitch::BSList[i].name); - myBSType = new PopUpWidget(myTab, font, t->getRight() + 8, ypos, + myBSType = new PopUpWidget(myTab, font, t->getRight() + fontWidth, ypos, pwidth, lineHeight, items, ""); wid.push_back(myBSType); ypos += lineHeight + VGAP; - myTypeDetected = new StaticTextWidget(myTab, ifont, t->getRight() + 8, ypos, + myTypeDetected = new StaticTextWidget(myTab, ifont, t->getRight() + fontWidth, ypos, "CM (SpectraVideo CompuMate) detected"); ypos += ifont.getLineHeight() + VGAP; @@ -119,7 +122,7 @@ GameInfoDialog::GameInfoDialog( pwidth, lineHeight, items, "", 0, 0); wid.push_back(myFormat); - myFormatDetected = new StaticTextWidget(myTab, ifont, myFormat->getRight() + 8, ypos + 4, + myFormatDetected = new StaticTextWidget(myTab, ifont, myFormat->getRight() + fontWidth, ypos + 4, "SECAM60 detected"); // Phosphor @@ -130,7 +133,7 @@ GameInfoDialog::GameInfoDialog( ypos += lineHeight + VGAP * 0; myPPBlend = new SliderWidget(myTab, font, - HBORDER + 20, ypos, + HBORDER + fontWidth * 2, ypos, "Blend ", 0, kPPBlendChanged, 4 * fontWidth, "%"); myPPBlend->setMinValue(0); myPPBlend->setMaxValue(100); myPPBlend->setTickmarkIntervals(2); @@ -138,7 +141,7 @@ GameInfoDialog::GameInfoDialog( ypos += lineHeight + VGAP; t = new StaticTextWidget(myTab, font, HBORDER, ypos + 1, "V-Center "); - myVCenter = new SliderWidget(myTab, font, t->getRight() + 2, ypos, "", + myVCenter = new SliderWidget(myTab, font, t->getRight(), ypos, "", 0, kVCenterChanged, 7 * fontWidth, "px", 0, true); myVCenter->setMinValue(TIAConstants::minVcenter); @@ -151,9 +154,9 @@ GameInfoDialog::GameInfoDialog( wid.push_back(mySound); // Add message concerning usage - ypos = myTab->getHeight() - 5 - fontHeight - ifont.getFontHeight() - 10; + ypos = myTab->getHeight() - fontHeight - ifont.getFontHeight() - VGAP - VBORDER; new StaticTextWidget(myTab, ifont, HBORDER, ypos, - "(*) Changes require a ROM reload"); + "(*) Change requires a ROM reload"); // Add items for tab 0 addToFocusList(wid, myTab, tabID); @@ -161,7 +164,7 @@ GameInfoDialog::GameInfoDialog( ////////////////////////////////////////////////////////////////////////////// // 2) Console properties wid.clear(); - tabID = myTab->addTab("Console"); + tabID = myTab->addTab(" Console ", TabWidget::AUTO_WIDTH); xpos = HBORDER; ypos = VBORDER; lwidth = font.getStringWidth(GUI::RIGHT_DIFFICULTY + " "); @@ -204,7 +207,7 @@ GameInfoDialog::GameInfoDialog( ////////////////////////////////////////////////////////////////////////////// // 3) Controller properties wid.clear(); - tabID = myTab->addTab("Controllers"); + tabID = myTab->addTab(" Controllers ", TabWidget::AUTO_WIDTH); ctrls.clear(); VarList::push_back(ctrls, "Auto-detect", "AUTO"); @@ -271,7 +274,7 @@ GameInfoDialog::GameInfoDialog( myPaddlesCenter = new StaticTextWidget(myTab, font, xpos, ypos, "Paddles center:"); ypos += lineHeight + VGAP; - xpos += 20; + xpos += INDENT; myPaddleXCenter = new SliderWidget(myTab, font, xpos, ypos - 1, "X ", 0, kPXCenterChanged, fontWidth * 6, "px", 0 ,true); myPaddleXCenter->setMinValue(Paddles::MIN_ANALOG_CENTER); @@ -288,7 +291,7 @@ GameInfoDialog::GameInfoDialog( wid.push_back(myPaddleYCenter); // Mouse - xpos = HBORDER + fontWidth * 24 - 20; + xpos = HBORDER + fontWidth * 24 - INDENT; ypos = myPaddlesCenter->getTop(); myMouseControl = new CheckboxWidget(myTab, font, xpos, ypos + 1, "Specific mouse axes", kMCtrlChanged); @@ -307,7 +310,7 @@ GameInfoDialog::GameInfoDialog( VarList::push_back(items, "MindLink 0", static_cast(MouseControl::Type::MindLink0)); VarList::push_back(items, "MindLink 1", static_cast(MouseControl::Type::MindLink1)); - xpos += 20; + xpos += CheckboxWidget::prefixSize(font); ypos += lineHeight + VGAP; myMouseX = new PopUpWidget(myTab, font, xpos, ypos, pwidth, lineHeight, items, "X-Axis is "); @@ -318,7 +321,7 @@ GameInfoDialog::GameInfoDialog( "Y-Axis is "); wid.push_back(myMouseY); - xpos -= 20; ypos += lineHeight + VGAP; + xpos -= CheckboxWidget::prefixSize(font); ypos += lineHeight + VGAP; myMouseRange = new SliderWidget(myTab, font, xpos, ypos, "Mouse axes range ", 0, 0, fontWidth * 4, "%"); myMouseRange->setMinValue(1); myMouseRange->setMaxValue(100); @@ -331,7 +334,7 @@ GameInfoDialog::GameInfoDialog( ////////////////////////////////////////////////////////////////////////////// // 4) Cartridge properties wid.clear(); - tabID = myTab->addTab("Cartridge"); + tabID = myTab->addTab(" Cartridge ", TabWidget::AUTO_WIDTH); xpos = HBORDER; ypos = VBORDER; lwidth = font.getStringWidth("Manufacturer "); diff --git a/src/gui/GlobalPropsDialog.cxx b/src/gui/GlobalPropsDialog.cxx index b4f296596..d8226a2d5 100644 --- a/src/gui/GlobalPropsDialog.cxx +++ b/src/gui/GlobalPropsDialog.cxx @@ -36,20 +36,25 @@ GlobalPropsDialog::GlobalPropsDialog(GuiObject* boss, const GUI::Font& font) const int lineHeight = font.getLineHeight(), fontWidth = font.getMaxCharWidth(), fontHeight = font.getFontHeight(), - buttonHeight = font.getLineHeight() + 4; + buttonHeight = lineHeight * 1.25; + const int VBORDER = fontHeight / 2; + const int HBORDER = fontWidth * 1.25; + const int INDENT = fontWidth * 2; + const int VGAP = fontHeight / 4; + int xpos, ypos; int lwidth = font.getStringWidth("Right difficulty "), pwidth = font.getStringWidth("CM (SpectraVideo CompuMate)"); - const int VGAP = 4; WidgetArray wid; VariantList items; const GUI::Font& infofont = instance().frameBuffer().infoFont(); // Set real dimensions - _w = lwidth + pwidth + fontWidth*3 + 15; - _h = 15 * (lineHeight + 4) + buttonHeight + 16 + _th; + _w = HBORDER * 2 + std::max(lwidth + pwidth + PopUpWidget::dropDownWidth(font), + 49 * infofont.getMaxCharWidth()); + _h = _th + 11 * (lineHeight + VGAP) + 3 * infofont.getLineHeight() + VGAP * 12 + buttonHeight + VBORDER * 2; - xpos = 10; ypos = 10 + _th; + xpos = HBORDER; ypos = VBORDER + _th; // Bankswitch type new StaticTextWidget(this, font, xpos, ypos+1, "Bankswitch type"); @@ -112,12 +117,12 @@ GlobalPropsDialog::GlobalPropsDialog(GuiObject* boss, const GUI::Font& font) "(automatically released shortly after start)"); // Start with console joystick direction/buttons held down - xpos = 32; ypos += infofont.getLineHeight() + VGAP * 2; + xpos = fontWidth * 4; ypos += infofont.getLineHeight() + VGAP * 2; ypos = addHoldWidgets(font, xpos, ypos, wid); // Add message concerning usage - xpos = 10; ypos += 2 * fontHeight; - ypos = _h - fontHeight * 2 - infofont.getLineHeight() - 24; + xpos = HBORDER; + ypos = _h - VBORDER - buttonHeight - VGAP * 3 - infofont.getLineHeight() * 2; new StaticTextWidget(this, infofont, xpos, ypos, "(*) These options are not saved, but apply to all"); ypos += infofont.getLineHeight(); @@ -134,21 +139,24 @@ GlobalPropsDialog::GlobalPropsDialog(GuiObject* boss, const GUI::Font& font) int GlobalPropsDialog::addHoldWidgets(const GUI::Font& font, int x, int y, WidgetArray& wid) { - int xpos = x, ypos = y; - const int VGAP = 4; + const int fontWidth = font.getMaxCharWidth(), + fontHeight = font.getFontHeight(); + const int VGAP = fontHeight / 4; + + int xpos = x, ypos = y, xdiff = CheckboxWidget::boxSize(font) - 9; // Left joystick - StaticTextWidget* t = new StaticTextWidget(this, font, xpos, ypos+2, "Left joy"); - xpos += t->getWidth()/2 - 7; ypos += t->getHeight() + VGAP; + StaticTextWidget* t = new StaticTextWidget(this, font, xpos, ypos + 2, "Left joy"); + xpos += t->getWidth()/2 - xdiff - 2; ypos += t->getHeight() + VGAP; myJoy[kJ0Up] = new CheckboxWidget(this, font, xpos, ypos, "", kJ0Up); ypos += myJoy[kJ0Up]->getHeight() * 2 + VGAP * 2; myJoy[kJ0Down] = new CheckboxWidget(this, font, xpos, ypos, "", kJ0Down); - xpos -= myJoy[kJ0Up]->getWidth() + 5; + xpos -= myJoy[kJ0Up]->getWidth() + xdiff; ypos -= myJoy[kJ0Up]->getHeight() + VGAP; myJoy[kJ0Left] = new CheckboxWidget(this, font, xpos, ypos, "", kJ0Left); - xpos += (myJoy[kJ0Up]->getWidth() + 5) * 2; + xpos += (myJoy[kJ0Up]->getWidth() + xdiff) * 2; myJoy[kJ0Right] = new CheckboxWidget(this, font, xpos, ypos, "", kJ0Right); - xpos -= (myJoy[kJ0Up]->getWidth() + 5) * 2; + xpos -= (myJoy[kJ0Up]->getWidth() + xdiff) * 2; ypos += myJoy[kJ0Down]->getHeight() * 2 + VGAP * 2; myJoy[kJ0Fire] = new CheckboxWidget(this, font, xpos, ypos, "Fire", kJ0Fire); @@ -157,20 +165,20 @@ int GlobalPropsDialog::addHoldWidgets(const GUI::Font& font, int x, int y, // Right joystick t = new StaticTextWidget(this, font, xpos, ypos + 2, "Right joy"); - xpos += t->getWidth()/2 - 7; ypos += t->getHeight() + VGAP; + xpos += t->getWidth()/2 - xdiff - 2; ypos += t->getHeight() + VGAP; myJoy[kJ1Up] = new CheckboxWidget(this, font, xpos, ypos, "", kJ1Up); ypos += myJoy[kJ1Up]->getHeight() * 2 + VGAP * 2; myJoy[kJ1Down] = new CheckboxWidget(this, font, xpos, ypos, "", kJ1Down); - xpos -= myJoy[kJ1Up]->getWidth() + 5; + xpos -= myJoy[kJ1Up]->getWidth() + xdiff; ypos -= myJoy[kJ1Up]->getHeight() + VGAP; myJoy[kJ1Left] = new CheckboxWidget(this, font, xpos, ypos, "", kJ1Left); - xpos += (myJoy[kJ1Up]->getWidth() + 5) * 2; + xpos += (myJoy[kJ1Up]->getWidth() + xdiff) * 2; myJoy[kJ1Right] = new CheckboxWidget(this, font, xpos, ypos, "", kJ1Right); - xpos -= (myJoy[kJ1Up]->getWidth() + 5) * 2; + xpos -= (myJoy[kJ1Up]->getWidth() + xdiff) * 2; ypos += myJoy[kJ1Down]->getHeight() * 2 + VGAP * 2; myJoy[kJ1Fire] = new CheckboxWidget(this, font, xpos, ypos, "Fire", kJ1Fire); - xpos = 2 * _w / 3 + 8; ypos = y; + xpos = 2 * _w / 3 + fontWidth; ypos = y; // Console Select/Reset t = new StaticTextWidget(this, font, xpos, ypos+2, "Console"); diff --git a/src/gui/HelpDialog.cxx b/src/gui/HelpDialog.cxx index bc86026b0..9a0bd2bdd 100644 --- a/src/gui/HelpDialog.cxx +++ b/src/gui/HelpDialog.cxx @@ -31,49 +31,55 @@ HelpDialog::HelpDialog(OSystem& osystem, DialogContainer& parent, const int lineHeight = font.getLineHeight(), fontWidth = font.getMaxCharWidth(), fontHeight = font.getFontHeight(), - buttonWidth = font.getStringWidth("Defaults") + 20, - buttonHeight = font.getLineHeight() + 4; + buttonWidth = font.getStringWidth("Previous") + fontWidth * 2.5, + buttonHeight = font.getLineHeight() * 1.25; + const int VBORDER = fontHeight / 2; + const int HBORDER = fontWidth * 1.25; + const int INDENT = fontWidth * 2; + const int VGAP = fontHeight / 4; + int xpos, ypos; WidgetArray wid; // Set real dimensions - _w = 46 * fontWidth + 10; - _h = 12 * lineHeight + 20 + _th; + _w = 46 * fontWidth + HBORDER * 2; + _h = _th + 11 * lineHeight + VGAP * 3 + buttonHeight + VBORDER * 2; // Add Previous, Next and Close buttons - xpos = 10; ypos = _h - buttonHeight - 10; + xpos = HBORDER; ypos = _h - buttonHeight - VBORDER; myPrevButton = new ButtonWidget(this, font, xpos, ypos, buttonWidth, buttonHeight, "Previous", GuiObject::kPrevCmd); myPrevButton->clearFlags(Widget::FLAG_ENABLED); wid.push_back(myPrevButton); - xpos += buttonWidth + 8; + xpos += buttonWidth + fontWidth; myNextButton = new ButtonWidget(this, font, xpos, ypos, buttonWidth, buttonHeight, "Next", GuiObject::kNextCmd); wid.push_back(myNextButton); - xpos = _w - buttonWidth - 10; + xpos = _w - buttonWidth - HBORDER; ButtonWidget* b = new ButtonWidget(this, font, xpos, ypos, buttonWidth, buttonHeight, "Close", GuiObject::kCloseCmd); wid.push_back(b); addCancelWidget(b); - xpos = 5; ypos = 5 + _th; - myTitle = new StaticTextWidget(this, font, xpos, ypos, _w - 10, fontHeight, + xpos = HBORDER; ypos = VBORDER + _th; + myTitle = new StaticTextWidget(this, font, xpos, ypos, _w - HBORDER * 2, fontHeight, "", TextAlign::Center); + myTitle->setTextColor(kTextColorEm); - int lwidth = 13 * fontWidth; - xpos += 5; ypos += lineHeight + 4; - for(uInt8 i = 0; i < LINES_PER_PAGE; ++i) + int lwidth = 15 * fontWidth; + ypos += lineHeight + VGAP * 2; + for(int i = 0; i < LINES_PER_PAGE; ++i) { myKey[i] = new StaticTextWidget(this, font, xpos, ypos, lwidth, fontHeight, "", TextAlign::Left); myDesc[i] = - new StaticTextWidget(this, font, xpos+lwidth, ypos, _w - xpos - lwidth - 5, + new StaticTextWidget(this, font, xpos+lwidth, ypos, _w - xpos - lwidth - HBORDER, fontHeight, "", TextAlign::Left); ypos += fontHeight; } @@ -158,7 +164,7 @@ void HelpDialog::updateStrings(uInt8 page, uInt8 lines, string& title) case 5: title = "All other commands"; ADD_LINE(); - ADD_BIND("Remapped Even", "ts"); + ADD_BIND("Remapped Events", ""); ADD_TEXT("Most other commands can be"); ADD_TEXT("remapped. Please consult the"); ADD_TEXT("'Options/Input" + ELLIPSIS + "' dialog for"); diff --git a/src/gui/InputDialog.cxx b/src/gui/InputDialog.cxx index e5eaa9057..bfa914c63 100644 --- a/src/gui/InputDialog.cxx +++ b/src/gui/InputDialog.cxx @@ -45,16 +45,23 @@ InputDialog::InputDialog(OSystem& osystem, DialogContainer& parent, { const int lineHeight = _font.getLineHeight(), fontWidth = _font.getMaxCharWidth(), - buttonHeight = _font.getLineHeight() + 4; - const int vBorder = 4; + fontHeight = _font.getFontHeight(), + buttonHeight = _font.getLineHeight() * 1.25; + const int VBORDER = fontHeight / 2; + const int VGAP = fontHeight / 4; + const int HBORDER = fontWidth * 1.25; int xpos, ypos, tabID; // Set real dimensions - setSize(51 * fontWidth + 10, 17 * (lineHeight + 4) + 16 + _th, max_w, max_h); + setSize(50 * fontWidth + HBORDER * 2, + _th + VGAP * 3 + lineHeight + 13 * (lineHeight + VGAP) + VGAP * 7 + buttonHeight + VBORDER * 3, + max_w, max_h); // The tab widget - xpos = 2; ypos = vBorder + _th; - myTab = new TabWidget(this, _font, xpos, ypos, _w - 2*xpos, _h -_th - buttonHeight - 20); + xpos = 2; ypos = VGAP + _th; + myTab = new TabWidget(this, _font, xpos, ypos, + _w - 2*xpos, + _h -_th - VGAP - buttonHeight - VBORDER * 2); addTabWidget(myTab); // 1) Event mapper for emulation actions @@ -102,11 +109,11 @@ void InputDialog::addDevicePortTab() const int lineHeight = _font.getLineHeight(), fontWidth = _font.getMaxCharWidth(), fontHeight = _font.getFontHeight(); + const int VGAP = fontHeight / 4; + const int VBORDER = fontHeight / 2; + const int HBORDER = fontWidth * 1.25; int xpos, ypos, lwidth, tabID; WidgetArray wid; - const int VGAP = 4; - const int VBORDER = 8; - const int HBORDER = 8; // Devices/ports tabID = myTab->addTab("Devices & Ports", TabWidget::AUTO_WIDTH); @@ -239,13 +246,14 @@ void InputDialog::addDevicePortTab() void InputDialog::addMouseTab() { const int lineHeight = _font.getLineHeight(), - fontWidth = _font.getMaxCharWidth(); + fontWidth = _font.getMaxCharWidth(), + fontHeight = _font.getFontHeight(); + const int VGAP = fontHeight / 4; + const int VBORDER = fontHeight / 2; + const int HBORDER = fontWidth * 1.25; int ypos, lwidth, pwidth, tabID; WidgetArray wid; VariantList items; - const int VGAP = 4; - const int VBORDER = 8; - const int HBORDER = 8; // Mouse tabID = myTab->addTab(" Mouse ", TabWidget::AUTO_WIDTH); diff --git a/src/gui/InputTextDialog.cxx b/src/gui/InputTextDialog.cxx index b543d9729..12e7a66d4 100644 --- a/src/gui/InputTextDialog.cxx +++ b/src/gui/InputTextDialog.cxx @@ -50,15 +50,20 @@ InputTextDialog::InputTextDialog(GuiObject* boss, const GUI::Font& lfont, void InputTextDialog::initialize(const GUI::Font& lfont, const GUI::Font& nfont, const StringList& labels) { - const int fontWidth = lfont.getMaxCharWidth(), - fontHeight = lfont.getFontHeight(), - lineHeight = lfont.getLineHeight(); + const int lineHeight = lfont.getLineHeight(), + fontWidth = lfont.getMaxCharWidth(), + fontHeight = lfont.getFontHeight(), + buttonHeight = lfont.getLineHeight() * 1.25; + const int VBORDER = fontHeight / 2; + const int HBORDER = fontWidth * 1.25; + const int VGAP = fontHeight / 4; + uInt32 xpos, ypos, i, lwidth = 0, maxIdx = 0; WidgetArray wid; // Calculate real dimensions - _w = fontWidth * 41; - _h = lineHeight * 4 + int(labels.size()) * (lineHeight + 5) + _th; + _w = HBORDER * 2 + fontWidth * 39; + _h = buttonHeight + lineHeight + VGAP + int(labels.size()) * (lineHeight + VGAP) + _th + VBORDER * 2; // Determine longest label for(i = 0; i < labels.size(); ++i) @@ -72,25 +77,25 @@ void InputTextDialog::initialize(const GUI::Font& lfont, const GUI::Font& nfont, lwidth = lfont.getStringWidth(labels[maxIdx]); // Create editboxes for all labels - ypos = lineHeight + _th; + ypos = VBORDER + _th; for(i = 0; i < labels.size(); ++i) { - xpos = 10; + xpos = HBORDER; new StaticTextWidget(this, lfont, xpos, ypos + 2, lwidth, fontHeight, labels[i], TextAlign::Left); xpos += lwidth + fontWidth; EditTextWidget* w = new EditTextWidget(this, nfont, xpos, ypos, - _w - xpos - 10, lineHeight, ""); + _w - xpos - HBORDER, lineHeight, ""); wid.push_back(w); myInput.push_back(w); - ypos += lineHeight + 5; + ypos += lineHeight + VGAP; } - xpos = 10; - myMessage = new StaticTextWidget(this, lfont, xpos, ypos, _w - 2*xpos, fontHeight, + xpos = HBORDER; ypos += VGAP; + myMessage = new StaticTextWidget(this, lfont, xpos, ypos, _w - 2 * xpos, fontHeight, "", TextAlign::Left); myMessage->setTextColor(kTextColorEm); diff --git a/src/gui/JoystickDialog.cxx b/src/gui/JoystickDialog.cxx index 16f8e84f0..266822eda 100644 --- a/src/gui/JoystickDialog.cxx +++ b/src/gui/JoystickDialog.cxx @@ -32,33 +32,40 @@ JoystickDialog::JoystickDialog(GuiObject* boss, const GUI::Font& font, int xpos, ypos; WidgetArray wid; - int buttonWidth = font.getStringWidth("Remove ") + 20, - buttonHeight = font.getLineHeight() + 4; + const int lineHeight = font.getLineHeight(), + fontWidth = font.getMaxCharWidth(), + fontHeight = font.getFontHeight(), + buttonWidth = font.getStringWidth("Remove") + fontWidth * 2.5, + buttonHeight = font.getLineHeight() * 1.25; + const int VBORDER = fontHeight / 2; + const int HBORDER = fontWidth * 1.25; + const int INDENT = fontWidth * 2; + const int VGAP = fontHeight / 4; // Joystick list - xpos = 10; ypos = 10 + _th; + xpos = HBORDER; ypos = VBORDER + _th; int w = _w - 2 * xpos; - int h = _h - buttonHeight - ypos - 20; + int h = _h - buttonHeight - ypos - VBORDER * 2; myJoyList = new StringListWidget(this, font, xpos, ypos, w, h); myJoyList->setEditable(false); wid.push_back(myJoyList); // Joystick ID - ypos = _h - buttonHeight - 10; + ypos = _h - VBORDER - (buttonHeight + lineHeight) / 2; StaticTextWidget* t = new StaticTextWidget(this, font, xpos, ypos+2, "Joystick ID "); - xpos += t->getWidth() + 4; + xpos += t->getWidth(); myJoyText = new EditTextWidget(this, font, xpos, ypos, - font.getStringWidth("Unplugged")+8, font.getLineHeight(), ""); + font.getStringWidth("Unplugged "), font.getLineHeight(), ""); myJoyText->setEditable(false); // Add buttons at bottom - xpos = _w - buttonWidth - 10; + xpos = _w - buttonWidth - HBORDER; + ypos = _h - VBORDER - buttonHeight; myCloseBtn = new ButtonWidget(this, font, xpos, ypos, buttonWidth, buttonHeight, "Close", GuiObject::kCloseCmd); addOKWidget(myCloseBtn); addCancelWidget(myCloseBtn); - buttonWidth = font.getStringWidth("Remove") + 20; - xpos -= buttonWidth + 8; + xpos -= buttonWidth + fontWidth; myRemoveBtn = new ButtonWidget(this, font, xpos, ypos, buttonWidth, buttonHeight, "Remove", kRemoveCmd); myRemoveBtn->clearFlags(Widget::FLAG_ENABLED); diff --git a/src/gui/LauncherDialog.cxx b/src/gui/LauncherDialog.cxx index fc47f9bbe..3e9936cdf 100644 --- a/src/gui/LauncherDialog.cxx +++ b/src/gui/LauncherDialog.cxx @@ -60,25 +60,26 @@ LauncherDialog::LauncherDialog(OSystem& osystem, DialogContainer& parent, myUseMinimalUI = instance().settings().getBool("minimal_ui"); const GUI::Font& font = instance().frameBuffer().launcherFont(); - - const int HBORDER = 10; - const int BUTTON_GAP = 8; const int fontWidth = font.getMaxCharWidth(), fontHeight = font.getFontHeight(), lineHeight = font.getLineHeight(), - bwidth = (_w - 2 * HBORDER - BUTTON_GAP * (4 - 1)), - bheight = myUseMinimalUI ? lineHeight - 4 : lineHeight + 4, - LBL_GAP = fontWidth; - int xpos = 0, ypos = 0, lwidth = 0, lwidth2 = 0; - WidgetArray wid; + HBORDER = fontWidth * 1.25, + VBORDER = fontHeight / 2, + BUTTON_GAP = fontWidth, + LBL_GAP = fontWidth, + VGAP = fontHeight / 4, + buttonHeight = myUseMinimalUI ? lineHeight - VGAP * 2: lineHeight * 1.25, + buttonWidth = (_w - 2 * HBORDER - BUTTON_GAP * (4 - 1)); + int xpos = HBORDER, ypos = VBORDER, lwidth = 0, lwidth2 = 0; + WidgetArray wid; string lblRom = "Select a ROM from the list" + ELLIPSIS; const string& lblFilter = "Filter"; const string& lblAllFiles = "Show all files"; const string& lblFound = "XXXX items found"; lwidth = font.getStringWidth(lblRom); - lwidth2 = font.getStringWidth(lblAllFiles) + 20; + lwidth2 = font.getStringWidth(lblAllFiles) + CheckboxWidget::boxSize(font); int lwidth3 = font.getStringWidth(lblFilter); int lwidth4 = font.getStringWidth(lblFound); @@ -97,14 +98,12 @@ LauncherDialog::LauncherDialog(OSystem& osystem, DialogContainer& parent, #if defined(RETRON77) ver << " for RetroN 77"; #endif - ypos += 8; - new StaticTextWidget(this, font, xpos, ypos, _w - 20, fontHeight, + new StaticTextWidget(this, font, 0, ypos, _w, fontHeight, ver.str(), TextAlign::Center); - ypos += fontHeight - 4; + ypos += lineHeight; } // Show the header - xpos += HBORDER; ypos += 8; new StaticTextWidget(this, font, xpos, ypos, lblRom); // Shop the files counter xpos = _w - HBORDER - lwidth4; @@ -132,12 +131,12 @@ LauncherDialog::LauncherDialog(OSystem& osystem, DialogContainer& parent, // Add list with game titles // Before we add the list, we need to know the size of the RomInfoWidget - int listHeight = _h - 43 - bheight - fontHeight - lineHeight; + int listHeight = _h - VBORDER * 2 - buttonHeight - lineHeight * 2 - VGAP * 6; float imgZoom = getRomInfoZoom(listHeight); int romWidth = imgZoom * TIAConstants::viewableWidth; - if(romWidth > 0) romWidth += 10; - int listWidth = _w - (romWidth > 0 ? romWidth+8 : 0) - 20; - xpos = HBORDER; ypos += lineHeight + 4; + if(romWidth > 0) romWidth += HBORDER; + int listWidth = _w - (romWidth > 0 ? romWidth + fontWidth : 0) - HBORDER * 2; + xpos = HBORDER; ypos += lineHeight + VGAP; myList = new FileListWidget(this, font, xpos, ypos, listWidth, listHeight); myList->setEditable(false); myList->setListMode(FilesystemNode::ListMode::All); @@ -146,14 +145,14 @@ LauncherDialog::LauncherDialog(OSystem& osystem, DialogContainer& parent, // Add ROM info area (if enabled) if(romWidth > 0) { - xpos += myList->getWidth() + 8; + xpos += myList->getWidth() + fontWidth; // Initial surface size is the same as the viewable area Common::Size imgSize(TIAConstants::viewableWidth*imgZoom, TIAConstants::viewableHeight*imgZoom); // Calculate font area, and in the process the font that can be used - Common::Size fontArea(romWidth - 16, myList->getHeight() - imgSize.h - 12); + Common::Size fontArea(romWidth - fontWidth * 2, myList->getHeight() - imgSize.h - VGAP * 3); setRomInfoFont(fontArea); myRomInfoWidget = new RomInfoWidget(this, *myROMInfoFont, @@ -162,7 +161,7 @@ LauncherDialog::LauncherDialog(OSystem& osystem, DialogContainer& parent, // Add textfield to show current directory xpos = HBORDER; - ypos += myList->getHeight() + 8; + ypos += myList->getHeight() + VGAP * 2; lwidth = font.getStringWidth("Path") + LBL_GAP; myDirLabel = new StaticTextWidget(this, font, xpos, ypos+2, lwidth, fontHeight, "Path", TextAlign::Left); @@ -174,43 +173,43 @@ LauncherDialog::LauncherDialog(OSystem& osystem, DialogContainer& parent, if(!myUseMinimalUI) { // Add four buttons at the bottom - xpos = HBORDER; ypos += myDir->getHeight() + 8; + xpos = HBORDER; ypos = _h - VBORDER - buttonHeight; #ifndef BSPF_MACOS - myStartButton = new ButtonWidget(this, font, xpos, ypos, (bwidth + 0) / 4, bheight, + myStartButton = new ButtonWidget(this, font, xpos, ypos, (buttonWidth + 0) / 4, buttonHeight, "Select", kLoadROMCmd); wid.push_back(myStartButton); - xpos += (bwidth + 0) / 4 + BUTTON_GAP; - myPrevDirButton = new ButtonWidget(this, font, xpos, ypos, (bwidth + 1) / 4, bheight, + xpos += (buttonWidth + 0) / 4 + BUTTON_GAP; + myPrevDirButton = new ButtonWidget(this, font, xpos, ypos, (buttonWidth + 1) / 4, buttonHeight, "Go Up", kPrevDirCmd); wid.push_back(myPrevDirButton); - xpos += (bwidth + 1) / 4 + BUTTON_GAP; - myOptionsButton = new ButtonWidget(this, font, xpos, ypos, (bwidth + 3) / 4, bheight, + xpos += (buttonWidth + 1) / 4 + BUTTON_GAP; + myOptionsButton = new ButtonWidget(this, font, xpos, ypos, (buttonWidth + 3) / 4, buttonHeight, "Options" + ELLIPSIS, kOptionsCmd); wid.push_back(myOptionsButton); - xpos += (bwidth + 2) / 4 + BUTTON_GAP; - myQuitButton = new ButtonWidget(this, font, xpos, ypos, (bwidth + 4) / 4, bheight, + xpos += (buttonWidth + 2) / 4 + BUTTON_GAP; + myQuitButton = new ButtonWidget(this, font, xpos, ypos, (buttonWidth + 4) / 4, buttonHeight, "Quit", kQuitCmd); wid.push_back(myQuitButton); #else - myQuitButton = new ButtonWidget(this, font, xpos, ypos, (bwidth + 0) / 4, bheight, + myQuitButton = new ButtonWidget(this, font, xpos, ypos, (buttonWidth + 0) / 4, buttonHeight, "Quit", kQuitCmd); wid.push_back(myQuitButton); - xpos += (bwidth + 0) / 4 + BUTTON_GAP; - myOptionsButton = new ButtonWidget(this, font, xpos, ypos, (bwidth + 1) / 4, bheight, + xpos += (buttonWidth + 0) / 4 + BUTTON_GAP; + myOptionsButton = new ButtonWidget(this, font, xpos, ypos, (buttonWidth + 1) / 4, buttonHeight, "Options" + ELLIPSIS, kOptionsCmd); wid.push_back(myOptionsButton); - xpos += (bwidth + 1) / 4 + BUTTON_GAP; - myPrevDirButton = new ButtonWidget(this, font, xpos, ypos, (bwidth + 2) / 4, bheight, + xpos += (buttonWidth + 1) / 4 + BUTTON_GAP; + myPrevDirButton = new ButtonWidget(this, font, xpos, ypos, (buttonWidth + 2) / 4, buttonHeight, "Go Up", kPrevDirCmd); wid.push_back(myPrevDirButton); - xpos += (bwidth + 2) / 4 + BUTTON_GAP; - myStartButton = new ButtonWidget(this, font, xpos, ypos, (bwidth + 3) / 4, bheight, + xpos += (buttonWidth + 2) / 4 + BUTTON_GAP; + myStartButton = new ButtonWidget(this, font, xpos, ypos, (buttonWidth + 3) / 4, buttonHeight, "Select", kLoadROMCmd); wid.push_back(myStartButton); #endif @@ -223,7 +222,7 @@ LauncherDialog::LauncherDialog(OSystem& osystem, DialogContainer& parent, addToFocusList(wid); // Create (empty) context menu for ROM list options - myMenu = make_unique(this, osystem.frameBuffer().font(), EmptyVarList); + myMenu = make_unique(this, osystem.frameBuffer().launcherFont(), EmptyVarList); // Create global props dialog, which is used to temporarily override // ROM properties @@ -363,28 +362,33 @@ float LauncherDialog::getRomInfoZoom(int listHeight) const if(zoom > 0.F) { - // upper zoom limit - at least 24 launchers chars/line and 8 ROM info lines - if((_w - 58 - zoom * TIAConstants::viewableWidth) - / instance().frameBuffer().launcherFont().getMaxCharWidth() < MIN_LAUNCHER_CHARS) + const GUI::Font& font = instance().frameBuffer().launcherFont(); + const GUI::Font& smallFont = instance().frameBuffer().smallFont(); + const int fontWidth = font.getMaxCharWidth(), + HBORDER = fontWidth * 1.25; + + // upper zoom limit - at least 24 launchers chars/line and 7 + 4 ROM info lines + if((_w - (HBORDER * 2 + fontWidth + 30) - zoom * TIAConstants::viewableWidth) + / font.getMaxCharWidth() < MIN_LAUNCHER_CHARS) { - zoom = float(_w - 58 - MIN_LAUNCHER_CHARS * instance().frameBuffer().launcherFont().getMaxCharWidth()) + zoom = float(_w - (HBORDER * 2 + fontWidth + 30) - MIN_LAUNCHER_CHARS * font.getMaxCharWidth()) / TIAConstants::viewableWidth; } if((listHeight - 12 - zoom * TIAConstants::viewableHeight) < - MIN_ROMINFO_ROWS * instance().frameBuffer().smallFont().getLineHeight() + - MIN_ROMINFO_LINES * instance().frameBuffer().smallFont().getFontHeight()) + MIN_ROMINFO_ROWS * smallFont.getLineHeight() + + MIN_ROMINFO_LINES * smallFont.getFontHeight()) { zoom = float(listHeight - 12 - - MIN_ROMINFO_ROWS * instance().frameBuffer().smallFont().getLineHeight() - - MIN_ROMINFO_LINES * instance().frameBuffer().smallFont().getFontHeight()) + MIN_ROMINFO_ROWS * smallFont.getLineHeight() - + MIN_ROMINFO_LINES * smallFont.getFontHeight()) / TIAConstants::viewableHeight; } - // lower zoom limit - at least 24 ROM info chars/line + // lower zoom limit - at least 30 ROM info chars/line if((zoom * TIAConstants::viewableWidth) - / instance().frameBuffer().smallFont().getMaxCharWidth() < MIN_ROMINFO_CHARS + 6) + / smallFont.getMaxCharWidth() < MIN_ROMINFO_CHARS + 6) { - zoom = float(MIN_ROMINFO_CHARS * instance().frameBuffer().smallFont().getMaxCharWidth() + 6) + zoom = float(MIN_ROMINFO_CHARS * smallFont.getMaxCharWidth() + 6) / TIAConstants::viewableWidth; } } @@ -428,13 +432,7 @@ void LauncherDialog::loadRomInfo() const string& md5 = selectedRomMD5(); if(md5 != EmptyString) - { - // Get the properties for this entry - Properties props; - instance().propSet().getMD5WithInsert(currentNode(), md5, props); - - myRomInfoWidget->setProperties(props, currentNode()); - } + myRomInfoWidget->setProperties(currentNode(), md5); else myRomInfoWidget->clearProperties(); } diff --git a/src/gui/LauncherDialog.hxx b/src/gui/LauncherDialog.hxx index dc1058356..bfa0cecba 100644 --- a/src/gui/LauncherDialog.hxx +++ b/src/gui/LauncherDialog.hxx @@ -94,9 +94,9 @@ class LauncherDialog : public Dialog private: static constexpr int MIN_LAUNCHER_CHARS = 24; - static constexpr int MIN_ROMINFO_CHARS = 24; + static constexpr int MIN_ROMINFO_CHARS = 30; static constexpr int MIN_ROMINFO_ROWS = 7; // full lines - static constexpr int MIN_ROMINFO_LINES = 2; // extra lines + static constexpr int MIN_ROMINFO_LINES = 4; // extra lines void center() override { positionAt(0); } void handleKeyDown(StellaKey key, StellaMod mod, bool repeated) override; @@ -132,7 +132,7 @@ class LauncherDialog : public Dialog unique_ptr myROMInfoFont; ButtonWidget* myStartButton{nullptr}; - ButtonWidget* myPrevDirButton{nullptr}; + ButtonWidget* myPrevDirButton{nullptr}; ButtonWidget* myOptionsButton{nullptr}; ButtonWidget* myQuitButton{nullptr}; diff --git a/src/gui/ListWidget.cxx b/src/gui/ListWidget.cxx index 850b7710b..aa8ed9455 100644 --- a/src/gui/ListWidget.cxx +++ b/src/gui/ListWidget.cxx @@ -39,11 +39,12 @@ ListWidget::ListWidget(GuiObject* boss, const GUI::Font& font, _rows = h / _fontHeight; // Set real dimensions - _w = w - kScrollBarWidth; + _w = w - ScrollBarWidget::scrollBarWidth(_font); _h = h + 2; // Create scrollbar and attach to the list - _scrollBar = new ScrollBarWidget(boss, font, _x + _w, _y, kScrollBarWidth, _h); + _scrollBar = new ScrollBarWidget(boss, font, _x + _w, _y, + ScrollBarWidget::scrollBarWidth(_font), _h); _scrollBar->setTarget(this); } @@ -144,7 +145,7 @@ void ListWidget::scrollTo(int item) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - int ListWidget::getWidth() const { - return _w + kScrollBarWidth; + return _w + ScrollBarWidget::scrollBarWidth(_font); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/gui/LoggerDialog.cxx b/src/gui/LoggerDialog.cxx index 779cd1868..57a0161fc 100644 --- a/src/gui/LoggerDialog.cxx +++ b/src/gui/LoggerDialog.cxx @@ -37,8 +37,15 @@ LoggerDialog::LoggerDialog(OSystem& osystem, DialogContainer& parent, : Dialog(osystem, parent, font, "System logs") { const int lineHeight = font.getLineHeight(), - buttonWidth = font.getStringWidth("Save log to disk") + 20, - buttonHeight = font.getLineHeight() + 4; + fontWidth = font.getMaxCharWidth(), + fontHeight = font.getFontHeight(), + buttonWidth = font.getStringWidth("Save log to disk") + fontWidth * 2.5, + buttonHeight = font.getLineHeight() * 1.25; + const int VBORDER = fontHeight / 2; + const int HBORDER = fontWidth * 1.25; + const int INDENT = fontWidth * 2; + const int VGAP = fontHeight / 4; + int xpos, ypos; WidgetArray wid; @@ -47,13 +54,13 @@ LoggerDialog::LoggerDialog(OSystem& osystem, DialogContainer& parent, setSize(4000, 4000, max_w, max_h); // Test listing of the log output - xpos = 10; ypos = 10 + _th; + xpos = HBORDER; ypos = VBORDER + _th; myLogInfo = new StringListWidget(this, uselargefont ? font : instance().frameBuffer().infoFont(), xpos, ypos, _w - 2 * xpos, - _h - buttonHeight - ypos - 20 - 2 * lineHeight, false); + _h - buttonHeight - ypos - VBORDER - lineHeight - VGAP * 4, false); myLogInfo->setEditable(false); wid.push_back(myLogInfo); - ypos += myLogInfo->getHeight() + 8; + ypos += myLogInfo->getHeight() + VGAP * 2; // Level of logging (how much info to print) VariantList items; @@ -67,13 +74,13 @@ LoggerDialog::LoggerDialog(OSystem& osystem, DialogContainer& parent, wid.push_back(myLogLevel); // Should log output also be shown on the console? - xpos += myLogLevel->getWidth() + 32; + xpos += myLogLevel->getWidth() + fontWidth * 4; myLogToConsole = new CheckboxWidget(this, font, xpos, ypos + 1, "Print to console"); wid.push_back(myLogToConsole); // Add Save, OK and Cancel buttons ButtonWidget* b; - b = new ButtonWidget(this, font, 10, _h - buttonHeight - 10, + b = new ButtonWidget(this, font, HBORDER, _h - buttonHeight - VBORDER, buttonWidth, buttonHeight, "Save log to disk", GuiObject::kDefaultsCmd); wid.push_back(b); diff --git a/src/gui/MessageBox.cxx b/src/gui/MessageBox.cxx index 30bdc88d0..d5b5cf11b 100644 --- a/src/gui/MessageBox.cxx +++ b/src/gui/MessageBox.cxx @@ -79,21 +79,24 @@ MessageBox::MessageBox(GuiObject* boss, const GUI::Font& font, // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void MessageBox::addText(const GUI::Font& font, const StringList& text) { - const int fontWidth = font.getMaxCharWidth(), - fontHeight = font.getFontHeight(); - int xpos, ypos; + const int fontWidth = font.getMaxCharWidth(), + fontHeight = font.getFontHeight(); + const int VBORDER = fontHeight / 2; + const int HBORDER = fontWidth * 1.25; + int xpos, ypos; // Set real dimensions int str_w = 0; + for(const auto& s: text) str_w = std::max(int(s.length()), str_w); - _w = std::min(str_w * fontWidth + 20, _w); - _h = std::min(uInt32((text.size() + 2) * fontHeight + 20 + _th), uInt32(_h)); + _w = std::min(str_w * fontWidth + HBORDER * 2, _w); + _h = std::min(uInt32((text.size() + 2) * fontHeight + VBORDER * 2 + _th), uInt32(_h)); - xpos = 10; ypos = 10 + _th; + xpos = HBORDER; ypos = VBORDER + _th; for(const auto& s: text) { - new StaticTextWidget(this, font, xpos, ypos, _w - 20, + new StaticTextWidget(this, font, xpos, ypos, _w - HBORDER * 2, fontHeight, s, TextAlign::Left); ypos += fontHeight; } diff --git a/src/gui/OptionsDialog.cxx b/src/gui/OptionsDialog.cxx index 1b03b8cfc..9b8087b34 100644 --- a/src/gui/OptionsDialog.cxx +++ b/src/gui/OptionsDialog.cxx @@ -49,19 +49,24 @@ OptionsDialog::OptionsDialog(OSystem& osystem, DialogContainer& parent, GuiObject* boss, int max_w, int max_h, Menu::AppMode mode) : Dialog(osystem, parent, osystem.frameBuffer().font(), "Options"), + myBoss(boss), myMode(mode) { // do not show basic settings options in debugger bool minSettings = osystem.settings().getBool("minimal_ui") && mode != Menu::AppMode::debugger; - const int buttonHeight = _font.getLineHeight() + 6, - GAP = buttonHeight > 26 ? 5 : 4, - rowHeight = buttonHeight + GAP; - const int VBORDER = GAP * 2 + 2; - const int HBORDER = GAP * 2 + 2; - int buttonWidth = _font.getStringWidth("Game Properties" + ELLIPSIS) + GAP * 5; + const int lineHeight = _font.getLineHeight(), + fontWidth = _font.getMaxCharWidth(), + fontHeight = _font.getFontHeight(), + buttonHeight = _font.getLineHeight() * 1.25, + VGAP = fontHeight / 4, + HGAP = fontWidth, + rowHeight = buttonHeight + VGAP; + const int VBORDER = fontHeight / 2; + const int HBORDER = fontWidth * 1.25; + int buttonWidth = _font.getStringWidth("Game Properties" + ELLIPSIS) + fontWidth * 2.5; - _w = 2 * buttonWidth + HBORDER * 3; - _h = 7 * rowHeight + VBORDER * 2 - GAP + _th; + _w = 2 * buttonWidth + HBORDER * 2 + HGAP; + _h = 7 * rowHeight + VBORDER * 2 - VGAP + _th; int xoffset = HBORDER, yoffset = VBORDER + _th; WidgetArray wid; @@ -72,8 +77,8 @@ OptionsDialog::OptionsDialog(OSystem& osystem, DialogContainer& parent, ButtonWidget* bw = new ButtonWidget(this, _font, xoffset, yoffset, _w - HBORDER * 2, buttonHeight, "Use Basic Settings", kBasSetCmd); wid.push_back(bw); - yoffset += rowHeight + GAP * 2; - _h += rowHeight + GAP * 2; + yoffset += rowHeight + VGAP * 2; + _h += rowHeight + VGAP * 2; } auto ADD_OD_BUTTON = [&](const string& label, int cmd) @@ -107,8 +112,8 @@ OptionsDialog::OptionsDialog(OSystem& osystem, DialogContainer& parent, wid.push_back(b); // Move to second column - xoffset += buttonWidth + HBORDER; - yoffset = minSettings ? VBORDER + _th + rowHeight + GAP * 2 : VBORDER + _th; + xoffset += buttonWidth + HGAP; + yoffset = minSettings ? VBORDER + _th + rowHeight + VGAP * 2 : VBORDER + _th; myGameInfoButton = ADD_OD_BUTTON("Game Properties" + ELLIPSIS, kInfoCmd); wid.push_back(myGameInfoButton); @@ -131,8 +136,8 @@ OptionsDialog::OptionsDialog(OSystem& osystem, DialogContainer& parent, b = ADD_OD_BUTTON("About" + ELLIPSIS, kAboutCmd); wid.push_back(b); - buttonWidth = _font.getStringWidth(" Close ") + GAP * 5; - xoffset -= (buttonWidth + HBORDER) / 2; + buttonWidth = _font.getStringWidth(" Close ") + fontWidth * 2.5; + xoffset -= (buttonWidth + HGAP) / 2; b = ADD_OD_BUTTON("Close", kExitCmd); wid.push_back(b); addCancelWidget(b); @@ -243,8 +248,20 @@ void OptionsDialog::handleCommand(CommandSender* sender, int cmd, } case kUsrIfaceCmd: + { + // This dialog is resizable under certain conditions, so we need + // to re-create it as necessary + uInt32 w = 0, h = 0; + + if(myUIDialog == nullptr || myUIDialog->shouldResize(w, h)) + { + myUIDialog = make_unique(instance(), parent(), + instance().frameBuffer().font(), myBoss, w, h); + } + myUIDialog->open(); break; + } case kSnapCmd: { diff --git a/src/gui/OptionsDialog.hxx b/src/gui/OptionsDialog.hxx index 5842bc482..3b5598693 100644 --- a/src/gui/OptionsDialog.hxx +++ b/src/gui/OptionsDialog.hxx @@ -71,6 +71,7 @@ class OptionsDialog : public Dialog ButtonWidget* myGameInfoButton{nullptr}; ButtonWidget* myCheatCodeButton{nullptr}; + GuiObject* myBoss; // Indicates if this dialog is used for global (vs. in-game) settings Menu::AppMode myMode{Menu::AppMode::emulator}; diff --git a/src/gui/PopUpWidget.cxx b/src/gui/PopUpWidget.cxx index 9cc233060..589c34660 100644 --- a/src/gui/PopUpWidget.cxx +++ b/src/gui/PopUpWidget.cxx @@ -41,11 +41,13 @@ PopUpWidget::PopUpWidget(GuiObject* boss, const GUI::Font& font, if(!_label.empty() && _labelWidth == 0) _labelWidth = _font.getStringWidth(_label); - _w = w + _labelWidth + 23; + setArrow(); + + _w = w + _labelWidth + dropDownWidth(font); // 23 // vertically center the arrows and text myTextY = (_h - _font.getFontHeight()) / 2; - myArrowsY = (_h - 8) / 2; + myArrowsY = (_h - _arrowHeight) / 2; myMenu = make_unique(this, font, list, cmd, w); } @@ -185,10 +187,10 @@ void PopUpWidget::handleCommand(CommandSender* sender, int cmd, int data, int id } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void PopUpWidget::drawWidget(bool hilite) +void PopUpWidget::setArrow() { - // Little down arrow - static constexpr std::array down_arrow = { + // Small down arrow + static constexpr std::array down_arrow = { 0b100000001, 0b110000011, 0b111000111, @@ -196,9 +198,40 @@ void PopUpWidget::drawWidget(bool hilite) 0b001111100, 0b000111000, 0b000010000, - 0b000000000 + }; + // Large down arrow + static constexpr std::array down_arrow_large = { + 0b1000000000001, + 0b1100000000011, + 0b1110000000111, + 0b1111000001111, + 0b0111100011110, + 0b0011110111100, + 0b0001111111000, + 0b0000111110000, + 0b0000011100000, + 0b0000001000000 }; + if(_font.getFontHeight() < 24) + { + _textOfs = 3; + _arrowWidth = 9; + _arrowHeight = 7; + _arrowImg = down_arrow.data(); + } + else + { + _textOfs = 5; + _arrowWidth = 13; + _arrowHeight = 10; + _arrowImg = down_arrow_large.data(); + } +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void PopUpWidget::drawWidget(bool hilite) +{ //cerr << "PopUpWidget::drawWidget\n"; FBSurface& s = dialog().surface(); bool onTop = _boss->dialog().isOnTop(); @@ -213,19 +246,22 @@ void PopUpWidget::drawWidget(bool hilite) // Draw a thin frame around us. s.frameRect(x, _y, w, _h, isEnabled() && hilite ? kWidColorHi : kColor); - s.frameRect(x + w - 16, _y + 1, 15, _h - 2, isEnabled() && hilite ? kWidColorHi : kBGColorLo); + s.frameRect(x + w - (_arrowWidth * 2 - 2), _y + 1, (_arrowWidth * 2 - 3), _h - 2, + isEnabled() && hilite ? kWidColorHi : kBGColorLo); // Fill the background - s.fillRect(x + 1, _y + 1, w - 17, _h - 2, onTop ? _changed ? kDbgChangedColor : kWidColor : kDlgColor); - s.fillRect(x + w - 15, _y + 2, 13, _h - 4, onTop ? isEnabled() && hilite ? kWidColor : kBGColorHi : kBGColorLo); + s.fillRect(x + 1, _y + 1, w - (_arrowWidth * 2 - 1), _h - 2, + onTop ? _changed ? kDbgChangedColor : kWidColor : kDlgColor); + s.fillRect(x + w - (_arrowWidth * 2 - 3), _y + 2, (_arrowWidth * 2 - 5), _h - 4, + onTop ? isEnabled() && hilite ? kWidColor : kBGColorHi : kBGColorLo); // Draw an arrow pointing down at the right end to signal this is a dropdown/popup - s.drawBitmap(down_arrow.data(), x + w - 13, _y + myArrowsY + 1, - !(isEnabled() && onTop) ? kColor : kTextColor, 9U, 8U); + s.drawBitmap(_arrowImg, x + w - (_arrowWidth * 1.5 - 1), _y + myArrowsY + 1, + !(isEnabled() && onTop) ? kColor : kTextColor, _arrowWidth, _arrowHeight); // Draw the selected entry, if any const string& name = myMenu->getSelectedName(); - TextAlign align = (_font.getStringWidth(name) > w-6) ? + TextAlign align = (_font.getStringWidth(name) > w - 6) ? TextAlign::Right : TextAlign::Left; - s.drawString(_font, name, x+2, _y+myTextY, w-6, + s.drawString(_font, name, x + _textOfs, _y + myTextY, w - 6, !(isEnabled() && onTop) ? kColor : _changed ? kDbgChangedTextColor : kTextColor, align); } diff --git a/src/gui/PopUpWidget.hxx b/src/gui/PopUpWidget.hxx index 955263f5f..c9817e6dd 100644 --- a/src/gui/PopUpWidget.hxx +++ b/src/gui/PopUpWidget.hxx @@ -62,6 +62,10 @@ class PopUpWidget : public Widget, public CommandSender const Variant& getSelectedTag() const; bool wantsFocus() const override { return true; } + static int dropDownWidth(const GUI::Font& font) + { + return font.getFontHeight() < 24 ? (9 * 2 + 3) : (13 * 2 + 7); + } protected: void handleMouseDown(int x, int y, MouseButton b, int clickCount) override; @@ -70,6 +74,8 @@ class PopUpWidget : public Widget, public CommandSender void handleMouseLeft() override; bool handleEvent(Event::Type e) override; void handleCommand(CommandSender* sender, int cmd, int data, int id) override; + + void setArrow(); void drawWidget(bool hilite) override; private: @@ -81,6 +87,11 @@ class PopUpWidget : public Widget, public CommandSender int _labelWidth{0}; bool _changed{false}; + int _textOfs{0}; + int _arrowWidth{0}; + int _arrowHeight{0}; + const uInt32* _arrowImg{nullptr}; + private: // Following constructors and assignment operators not supported PopUpWidget() = delete; diff --git a/src/gui/ProgressDialog.cxx b/src/gui/ProgressDialog.cxx index 5ff6f7698..04bc2adae 100644 --- a/src/gui/ProgressDialog.cxx +++ b/src/gui/ProgressDialog.cxx @@ -31,20 +31,23 @@ ProgressDialog::ProgressDialog(GuiObject* boss, const GUI::Font& font, { const int fontWidth = font.getMaxCharWidth(), fontHeight = font.getFontHeight(), - lineHeight = font.getLineHeight(); + lineHeight = font.getLineHeight(), + VBORDER = fontHeight / 2, + HBORDER = fontWidth * 1.25, + VGAP = fontHeight / 4; int xpos, ypos, lwidth; // Calculate real dimensions lwidth = font.getStringWidth(message); - _w = lwidth + 2 * fontWidth; - _h = lineHeight * 5; + _w = HBORDER * 2 + lwidth; + _h = VBORDER * 2 + lineHeight * 2 + VGAP * 2; - xpos = fontWidth; ypos = lineHeight; + xpos = HBORDER; ypos = VBORDER; myMessage = new StaticTextWidget(this, font, xpos, ypos, lwidth, fontHeight, message, TextAlign::Center); myMessage->setTextColor(kTextColorEm); - xpos = fontWidth; ypos += 2 * lineHeight; + xpos = HBORDER; ypos += lineHeight + VGAP * 2; mySlider = new SliderWidget(this, font, xpos, ypos, lwidth, lineHeight, "", 0, 0); mySlider->setMinValue(1); mySlider->setMaxValue(100); diff --git a/src/gui/RadioButtonWidget.cxx b/src/gui/RadioButtonWidget.cxx index 7480122a2..e2b5e34df 100644 --- a/src/gui/RadioButtonWidget.cxx +++ b/src/gui/RadioButtonWidget.cxx @@ -21,6 +21,7 @@ #include "RadioButtonWidget.hxx" /* Radiobutton bitmaps */ +// small versions static constexpr std::array radio_img_outercircle = { 0b00001111110000, 0b00110000001100, 0b01000000000010, 0b01000000000010, 0b10000000000001, 0b10000000000001, @@ -33,16 +34,188 @@ static constexpr std::array radio_img_innercircle = { 0b111111111111, 0b111111111111, 0b111111111111, 0b111111111111, 0b111111111111, 0b011111111110, 0b011111111110, 0b000111111000 }; -static constexpr uInt32 RADIO_IMG_FILL_SIZE = 10; -static constexpr std::array radio_img_active = { +static constexpr std::array radio_img_active = { 0b0011111100, 0b0111111110, 0b1111111111, 0b1111111111, 0b1111111111, 0b1111111111, 0b1111111111, 0b1111111111, 0b0111111110, 0b0011111100, }; -static constexpr std::array radio_img_inactive = { +static constexpr std::array radio_img_inactive = { 0b0011111100, 0b0111111110, 0b1111001111, 0b1110000111, 0b1100000011, 0b1100000011, 0b1110000111, 0b1111001111, 0b0111111110, 0b0011111100 }; +// large versions +static constexpr std::array radio_img_outercircle_large = { + // thinner version + //0b0000000011111100000000, + //0b0000001100000011000000, + //0b0000110000000000110000, + //0b0001000000000000001000, + //0b0010000000000000000100, + //0b0010000000000000000100, + //0b0100000000000000000010, + //0b0100000000000000000010, + //0b1000000000000000000001, + //0b1000000000000000000001, + //0b1000000000000000000001, + //0b1000000000000000000001, + //0b1000000000000000000001, + //0b1000000000000000000001, + //0b0100000000000000000010, + //0b0100000000000000000010, + //0b0010000000000000000100, + //0b0010000000000000000100, + //0b0001000000000000001000, + //0b0000110000000000110000, + //0b0000001100000011000000, + //0b0000000011111100000000 + + 0b0000000011111100000000, + 0b0000001110000111000000, + 0b0000111000000001110000, + 0b0001100000000000011000, + 0b0011000000000000001100, + 0b0010000000000000000100, + 0b0110000000000000000110, + 0b0100000000000000000010, + 0b1100000000000000000011, + 0b1000000000000000000001, + 0b1000000000000000000001, + 0b1000000000000000000001, + 0b1000000000000000000001, + 0b1100000000000000000011, + 0b0100000000000000000010, + 0b0110000000000000000110, + 0b0010000000000000000100, + 0b0011000000000000001100, + 0b0001100000000000011000, + 0b0000111000000001110000, + 0b0000001110000111000000, + 0b0000000011111100000000 + +}; +static constexpr std::array radio_img_innercircle_large = { + //0b00000001111110000000, + //0b00000111111111100000, + //0b00011111111111111000, + //0b00111111111111111100, + //0b00111111111111111100, + //0b01111111111111111110, + //0b01111111111111111110, + //0b11111111111111111111, + //0b11111111111111111111, + //0b11111111111111111111, + //0b11111111111111111111, + //0b11111111111111111111, + //0b11111111111111111111, + //0b01111111111111111110, + //0b01111111111111111110, + //0b00111111111111111100, + //0b00111111111111111100, + //0b00011111111111111000, + //0b00000111111111100000, + //0b00000001111110000000 + + 0b00000000111100000000, + 0b00000011111111000000, + 0b00001111111111110000, + 0b00011111111111111000, + 0b00111111111111111100, + 0b00111111111111111100, + 0b01111111111111111110, + 0b01111111111111111110, + 0b11111111111111111111, + 0b11111111111111111111, + 0b11111111111111111111, + 0b11111111111111111111, + 0b01111111111111111110, + 0b01111111111111111110, + 0b00111111111111111100, + 0b00111111111111111100, + 0b00011111111111111000, + 0b00001111111111110000, + 0b00000011111111000000, + 0b00000000111100000000 + +}; +static constexpr std::array radio_img_active_large = { + //0b000000111111000000, + //0b000011111111110000, + //0b000111111111111000, + //0b001111111111111100, + //0b011111111111111110, + //0b011111111111111110, + //0b111111111111111111, + //0b111111111111111111, + //0b111111111111111111, + //0b111111111111111111, + //0b111111111111111111, + //0b111111111111111111, + //0b011111111111111110, + //0b011111111111111110, + //0b001111111111111100, + //0b000111111111111000, + //0b000011111111110000, + //0b000000111111000000 + + 0b000000000000000000, + 0b000000111111000000, + 0b000011111111110000, + 0b000111111111111000, + 0b001111111111111100, + 0b001111111111111100, + 0b011111111111111110, + 0b011111111111111110, + 0b011111111111111110, + 0b011111111111111110, + 0b011111111111111110, + 0b011111111111111110, + 0b001111111111111100, + 0b001111111111111100, + 0b000111111111111000, + 0b000011111111110000, + 0b000000111111000000, + 0b000000000000000000 +}; +static constexpr std::array radio_img_inactive_large = { + //0b000001111111100000, + //0b000111111111111000, + //0b001111111111111100, + //0b011111100001111110, + //0b011110000000011110, + //0b111100000000001111, + //0b111100000000001111, + //0b111000000000000111, + //0b111000000000000111, + //0b111000000000000111, + //0b111000000000000111, + //0b111100000000001111, + //0b111100000000001111, + //0b011110000000011110, + //0b011111100001111110, + //0b001111111111111100, + //0b010111111111111000, + //0b000001111111100000 + + 0b000000000000000000, + 0b000000111111000000, + 0b000011111111110000, + 0b000111111111111000, + 0b001111100001111100, + 0b001111000000111100, + 0b011110000000011110, + 0b011100000000001110, + 0b011100000000001110, + 0b011100000000001110, + 0b011100000000001110, + 0b011110000000011110, + 0b001111000000111100, + 0b001111100001111100, + 0b000111111111111000, + 0b000011111111110000, + 0b000000111111000000, + 0b000000000000000000 +}; + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - RadioButtonWidget::RadioButtonWidget(GuiObject* boss, const GUI::Font& font, int x, int y, const string& label, @@ -54,19 +227,31 @@ RadioButtonWidget::RadioButtonWidget(GuiObject* boss, const GUI::Font& font, _bgcolor = _bgcolorhi = kWidColor; _editable = true; + _buttonSize = buttonSize(font); // 14 | 22 + + if(_buttonSize == 14) + { + _outerCircle = radio_img_outercircle.data(); + _innerCircle = radio_img_innercircle.data(); + } + else + { + _outerCircle = radio_img_outercircle_large.data(); + _innerCircle = radio_img_innercircle_large.data(); + } if(label == "") - _w = 14; + _w = _buttonSize; else - _w = font.getStringWidth(label) + 20; - _h = font.getFontHeight() < 14 ? 14 : font.getFontHeight(); + _w = font.getStringWidth(label) + _buttonSize + font.getMaxCharWidth() * 0.75; + _h = font.getFontHeight() < int(_buttonSize) ? _buttonSize : font.getFontHeight(); // Depending on font size, either the font or box will need to be // centered vertically - if(_h > 14) // center box - _boxY = (_h - 14) / 2; + if(_h > int(_buttonSize)) // center box + _boxY = (_h - _buttonSize) / 2; else // center text - _textY = (14 - _font.getFontHeight()) / 2; + _textY = (_buttonSize - _font.getFontHeight()) / 2; setFill(CheckboxWidget::FillType::Normal); myGroup->addWidget(this); @@ -102,10 +287,10 @@ void RadioButtonWidget::setFill(FillType type) switch(type) { case CheckboxWidget::FillType::Normal: - _img = radio_img_active.data(); + _img = _buttonSize == 14 ? radio_img_active.data() : radio_img_active_large.data(); break; case CheckboxWidget::FillType::Inactive: - _img = radio_img_inactive.data(); + _img = _buttonSize == 14 ? radio_img_inactive.data(): radio_img_inactive_large.data(); break; default: break; @@ -118,25 +303,23 @@ void RadioButtonWidget::drawWidget(bool hilite) FBSurface& s = _boss->dialog().surface(); // Draw the outer bounding circle - s.drawBitmap(radio_img_outercircle.data(), _x, _y + _boxY, + s.drawBitmap(_outerCircle, _x, _y + _boxY, hilite ? kWidColorHi : kColor, - static_cast(radio_img_outercircle.size()), - static_cast(radio_img_outercircle.size())); + _buttonSize); // Draw the inner bounding circle with enabled color - s.drawBitmap(radio_img_innercircle.data(), _x + 1, _y + _boxY + 1, + s.drawBitmap(_innerCircle, _x + 1, _y + _boxY + 1, isEnabled() ? _bgcolor : kColor, - static_cast(radio_img_innercircle.size()), - static_cast(radio_img_innercircle.size())); + _buttonSize - 2); // draw state if(_state) s.drawBitmap(_img, _x + 2, _y + _boxY + 2, isEnabled() ? hilite ? kWidColorHi : kCheckColor - : kColor, RADIO_IMG_FILL_SIZE); + : kColor, _buttonSize - 4); // Finally draw the label - s.drawString(_font, _label, _x + 20, _y + _textY, _w, + s.drawString(_font, _label, _x + _buttonSize + _font.getMaxCharWidth() * 0.75, _y + _textY, _w, isEnabled() ? kTextColor : kColor); } diff --git a/src/gui/RadioButtonWidget.hxx b/src/gui/RadioButtonWidget.hxx index 840cc2dd2..8003a8627 100644 --- a/src/gui/RadioButtonWidget.hxx +++ b/src/gui/RadioButtonWidget.hxx @@ -40,9 +40,14 @@ class RadioButtonWidget : public CheckboxWidget protected: void setFill(FillType type); void drawWidget(bool hilite) override; + static int buttonSize(const GUI::Font& font) + { + return font.getFontHeight() < 24 ? 14 : 22; // box is square + } private: RadioButtonGroup* myGroup{nullptr}; + uInt32 _buttonSize{14}; private: // Following constructors and assignment operators not supported diff --git a/src/gui/RomAuditDialog.cxx b/src/gui/RomAuditDialog.cxx index f83586d45..580263730 100644 --- a/src/gui/RomAuditDialog.cxx +++ b/src/gui/RomAuditDialog.cxx @@ -40,15 +40,17 @@ RomAuditDialog::RomAuditDialog(OSystem& osystem, DialogContainer& parent, myMaxWidth(max_w), myMaxHeight(max_h) { - const int VBORDER = 10 + _th; - const int HBORDER = 10; - const int lineHeight = font.getLineHeight(), fontWidth = font.getMaxCharWidth(), fontHeight = font.getFontHeight(), - buttonWidth = font.getStringWidth("Audit path" + ELLIPSIS) + 20, - buttonHeight = font.getLineHeight() + 4, + buttonWidth = font.getStringWidth("Audit path" + ELLIPSIS) + fontWidth * 2.5, + buttonHeight = font.getLineHeight() * 1.25, lwidth = font.getStringWidth("ROMs without properties (skipped) "); + const int VBORDER = _th + fontHeight / 2; + const int HBORDER = fontWidth * 1.25; + const int INDENT = fontWidth * 2; + const int VGAP = fontHeight / 4; + int xpos, ypos = VBORDER; WidgetArray wid; @@ -62,28 +64,24 @@ RomAuditDialog::RomAuditDialog(OSystem& osystem, DialogContainer& parent, "Audit path" + ELLIPSIS, kChooseAuditDirCmd); wid.push_back(romButton); xpos = HBORDER + buttonWidth + 8; - myRomPath = new EditTextWidget(this, font, xpos, ypos + 1, + myRomPath = new EditTextWidget(this, font, xpos, ypos + (buttonHeight - lineHeight) / 2 - 1, _w - xpos - HBORDER, lineHeight, ""); wid.push_back(myRomPath); // Show results of ROM audit ypos += buttonHeight + 16; - new StaticTextWidget(this, font, HBORDER, ypos, lwidth, fontHeight, - "ROMs with properties (renamed) ", TextAlign::Left); + new StaticTextWidget(this, font, HBORDER, ypos, "ROMs with properties (renamed) "); myResults1 = new EditTextWidget(this, font, HBORDER + lwidth, ypos - 2, fontWidth * 6, lineHeight, ""); myResults1->setEditable(false, true); ypos += buttonHeight; - new StaticTextWidget(this, font, HBORDER, ypos, lwidth, fontHeight, - "ROMs without properties (skipped) ", TextAlign::Left); + new StaticTextWidget(this, font, HBORDER, ypos, "ROMs without properties (skipped) "); myResults2 = new EditTextWidget(this, font, HBORDER + lwidth, ypos - 2, fontWidth * 6, lineHeight, ""); myResults2->setEditable(false, true); ypos += buttonHeight + 8; - new StaticTextWidget(this, font, HBORDER, ypos, _w - 20, fontHeight, - "(*) WARNING: Operation cannot be undone!", - TextAlign::Left); + new StaticTextWidget(this, font, HBORDER, ypos, "(*) WARNING: Operation cannot be undone!"); // Add OK and Cancel buttons addOKCancelBGroup(wid, font, "Audit", "Close"); diff --git a/src/gui/RomInfoWidget.cxx b/src/gui/RomInfoWidget.cxx index 752876735..c935f54dc 100644 --- a/src/gui/RomInfoWidget.cxx +++ b/src/gui/RomInfoWidget.cxx @@ -27,6 +27,7 @@ #include "Logger.hxx" #include "Props.hxx" #include "PNGLibrary.hxx" +#include "PropsSet.hxx" #include "Rect.hxx" #include "Widget.hxx" #include "RomInfoWidget.hxx" @@ -44,20 +45,10 @@ RomInfoWidget::RomInfoWidget(GuiObject* boss, const GUI::Font& font, } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void RomInfoWidget::reloadProperties(const FilesystemNode& node) -{ - // The ROM may have changed since we were last in the browser, either - // by saving a different image or through a change in video renderer, - // so we reload the properties - if(myHaveProperties) - parseProperties(node); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void RomInfoWidget::setProperties(const Properties& props, const FilesystemNode& node) +void RomInfoWidget::setProperties(const FilesystemNode& node, const string& md5) { myHaveProperties = true; - myProperties = props; + instance().propSet().getMD5(md5, myProperties); // Decide whether the information should be shown immediately if(instance().eventHandler().state() == EventHandlerState::LAUNCHER) @@ -76,6 +67,16 @@ void RomInfoWidget::clearProperties() setDirty(); } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void RomInfoWidget::reloadProperties(const FilesystemNode& node) +{ + // The ROM may have changed since we were last in the browser, either + // by saving a different image or through a change in video renderer, + // so we reload the properties + if(myHaveProperties) + parseProperties(node); +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void RomInfoWidget::parseProperties(const FilesystemNode& node) { @@ -140,8 +141,7 @@ void RomInfoWidget::parseProperties(const FilesystemNode& node) try { ByteBuffer image; - string md5 = myProperties.get(PropType::Cart_MD5); - size_t size = 0; + string md5 = ""; size_t size = 0; if(node.exists() && !node.isDirectory() && (image = instance().openROM(node, md5, size)) != nullptr) @@ -203,11 +203,23 @@ void RomInfoWidget::drawWidget(bool hilite) } int xpos = _x + 8, ypos = _y + yoff + 5; - for(const auto& info: myRomInfo) + for(const auto& info : myRomInfo) { + if(info.length() * _font.getMaxCharWidth() <= _w - 16) + + { + // 1 line for next entry + if(ypos + _font.getFontHeight() > _h + _y) + break; + } + else + { + // assume 2 lines for next entry + if(ypos + _font.getLineHeight() + _font.getFontHeight() > _h + _y ) + break; + } int lines = s.drawString(_font, info, xpos, ypos, _w - 16, _font.getFontHeight() * 3, onTop ? _textcolor : _shadowcolor); - if(ypos >= _h) break; ypos += _font.getLineHeight() + (lines - 1) * _font.getFontHeight(); } } diff --git a/src/gui/RomInfoWidget.hxx b/src/gui/RomInfoWidget.hxx index e1a964263..e2ea566ca 100644 --- a/src/gui/RomInfoWidget.hxx +++ b/src/gui/RomInfoWidget.hxx @@ -35,7 +35,7 @@ class RomInfoWidget : public Widget const Common::Size& imgSize); virtual ~RomInfoWidget() = default; - void setProperties(const Properties& props, const FilesystemNode& node); + void setProperties(const FilesystemNode& node, const string& md5); void clearProperties(); void reloadProperties(const FilesystemNode& node); diff --git a/src/gui/ScrollBarWidget.cxx b/src/gui/ScrollBarWidget.cxx index 4d055a027..335b716de 100644 --- a/src/gui/ScrollBarWidget.cxx +++ b/src/gui/ScrollBarWidget.cxx @@ -28,8 +28,6 @@ * and we thus should not highlight the arrows/slider. */ -#define UP_DOWN_BOX_HEIGHT 18 - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ScrollBarWidget::ScrollBarWidget(GuiObject* boss, const GUI::Font& font, int x, int y, int w, int h) @@ -38,6 +36,76 @@ ScrollBarWidget::ScrollBarWidget(GuiObject* boss, const GUI::Font& font, _flags = Widget::FLAG_ENABLED | Widget::FLAG_TRACK_MOUSE | Widget::FLAG_CLEARBG; _bgcolor = kWidColor; _bgcolorhi = kWidColor; + + _scrollBarWidth = scrollBarWidth(font); + + setArrows(); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void ScrollBarWidget::setArrows() +{ + // Small up arrow + static constexpr std::array up_arrow = { + 0b0001000, + 0b0011100, + 0b0111110, + 0b1110111, + 0b1100011, + 0b1000001, + }; + // Small down arrow + static constexpr std::array down_arrow = { + 0b1000001, + 0b1100011, + 0b1110111, + 0b0111110, + 0b0011100, + 0b0001000 + }; + + // Large up arrow + static constexpr std::array up_arrow_large = { + 0b00000100000, + 0b00001110000, + 0b00011111000, + 0b00111111100, + 0b01111011110, + 0b11110001111, + 0b11100000111, + 0b11000000011, + 0b10000000001, + }; + // Large down arrow + static constexpr std::array down_arrow_large = { + 0b10000000001, + 0b11000000011, + 0b11100000111, + 0b11110001111, + 0b01111011110, + 0b00111111100, + 0b00011111000, + 0b00001110000, + 0b00000100000 + }; + + + if(_font.getFontHeight() < 24) + { + _upDownWidth = 7; + _upDownHeight = 6; + _upDownBoxHeight = 18; + _upImg = up_arrow.data(); + _downImg = down_arrow.data(); + } + else + { + _upDownWidth = 11; + _upDownHeight = 9; + _upDownBoxHeight = 27; + _upImg = up_arrow_large.data(); + _downImg = down_arrow_large.data(); + } } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -54,13 +122,13 @@ void ScrollBarWidget::handleMouseDown(int x, int y, MouseButton b, if(_numEntries <= _entriesPerPage) return; - if (y <= UP_DOWN_BOX_HEIGHT) + if (y <= _upDownBoxHeight) { // Up arrow _currentPos--; _draggingPart = Part::UpArrow; } - else if(y >= _h - UP_DOWN_BOX_HEIGHT) + else if(y >= _h - _upDownBoxHeight) { // Down arrow _currentPos++; @@ -120,23 +188,23 @@ void ScrollBarWidget::handleMouseMoved(int x, int y) int old_pos = _currentPos; _sliderPos = y - _sliderDeltaMouseDownPos; - if(_sliderPos < UP_DOWN_BOX_HEIGHT) - _sliderPos = UP_DOWN_BOX_HEIGHT; + if(_sliderPos < _upDownBoxHeight) + _sliderPos = _upDownBoxHeight; - if(_sliderPos > _h - UP_DOWN_BOX_HEIGHT - _sliderHeight) - _sliderPos = _h - UP_DOWN_BOX_HEIGHT - _sliderHeight; + if(_sliderPos > _h - _upDownBoxHeight - _sliderHeight) + _sliderPos = _h - _upDownBoxHeight - _sliderHeight; - _currentPos = (_sliderPos - UP_DOWN_BOX_HEIGHT) * (_numEntries - _entriesPerPage) / - (_h - 2 * UP_DOWN_BOX_HEIGHT - _sliderHeight); + _currentPos = (_sliderPos - _upDownBoxHeight) * (_numEntries - _entriesPerPage) / + (_h - 2 * _upDownBoxHeight - _sliderHeight); checkBounds(old_pos); } else { Part old_part = _part; - if(y <= UP_DOWN_BOX_HEIGHT) // Up arrow + if(y <= _upDownBoxHeight) // Up arrow _part = Part::UpArrow; - else if(y >= _h - UP_DOWN_BOX_HEIGHT) // Down arrow + else if(y >= _h - _upDownBoxHeight) // Down arrow _part = Part::DownArrow; else if(y < _sliderPos) _part = Part::PageUp; @@ -193,19 +261,19 @@ void ScrollBarWidget::recalc() //cerr << "ScrollBarWidget::recalc()\n"; if(_numEntries > _entriesPerPage) { - _sliderHeight = (_h - 2 * UP_DOWN_BOX_HEIGHT) * _entriesPerPage / _numEntries; - if(_sliderHeight < UP_DOWN_BOX_HEIGHT) - _sliderHeight = UP_DOWN_BOX_HEIGHT; + _sliderHeight = (_h - 2 * _upDownBoxHeight) * _entriesPerPage / _numEntries; + if(_sliderHeight < _upDownBoxHeight) + _sliderHeight = _upDownBoxHeight; - _sliderPos = UP_DOWN_BOX_HEIGHT + (_h - 2 * UP_DOWN_BOX_HEIGHT - _sliderHeight) * + _sliderPos = _upDownBoxHeight + (_h - 2 * _upDownBoxHeight - _sliderHeight) * _currentPos / (_numEntries - _entriesPerPage); if(_sliderPos < 0) _sliderPos = 0; } else { - _sliderHeight = _h - 2 * UP_DOWN_BOX_HEIGHT; - _sliderPos = UP_DOWN_BOX_HEIGHT; + _sliderHeight = _h - 2 * _upDownBoxHeight; + _sliderPos = _upDownBoxHeight; } setDirty(); @@ -214,30 +282,6 @@ void ScrollBarWidget::recalc() // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void ScrollBarWidget::drawWidget(bool hilite) { - // Up arrow - static constexpr std::array up_arrow = { - 0b00000000, - 0b00010000, - 0b00111000, - 0b01111100, - 0b11101110, - 0b11000110, - 0b10000010, - 0b00000000 - }; - - // Down arrow - static constexpr std::array down_arrow = { - 0b00000000, - 0b10000010, - 0b11000110, - 0b11101110, - 0b01111100, - 0b00111000, - 0b00010000, - 0b00000000 - }; - //cerr << "ScrollBarWidget::drawWidget\n"; FBSurface& s = _boss->dialog().surface(); bool onTop = _boss->dialog().isOnTop(); @@ -251,17 +295,19 @@ void ScrollBarWidget::drawWidget(bool hilite) // Up arrow if(hilite && _part == Part::UpArrow) - s.fillRect(_x + 1, _y + 1, _w - 2, UP_DOWN_BOX_HEIGHT - 2, kScrollColor); - s.drawBitmap(up_arrow.data(), _x+4, _y+5, + s.fillRect(_x + 1, _y + 1, _w - 2, _upDownBoxHeight - 2, kScrollColor); + s.drawBitmap(_upImg, _x + (_scrollBarWidth - _upDownWidth) / 2, + _y + (_upDownBoxHeight - _upDownHeight) / 2, onTop ? isSinglePage ? kColor : (hilite && _part == Part::UpArrow) ? kWidColor - : kTextColor : kColor, 8); + : kTextColor : kColor, _upDownWidth, _upDownHeight); // Down arrow if(hilite && _part == Part::DownArrow) - s.fillRect(_x + 1, bottomY - UP_DOWN_BOX_HEIGHT + 1, _w - 2, UP_DOWN_BOX_HEIGHT - 2, kScrollColor); - s.drawBitmap(down_arrow.data(), _x+4, bottomY - UP_DOWN_BOX_HEIGHT + 5, + s.fillRect(_x + 1, bottomY - _upDownBoxHeight + 1, _w - 2, _upDownBoxHeight - 2, kScrollColor); + s.drawBitmap(_downImg, _x + (_scrollBarWidth - _upDownWidth) / 2, + bottomY - _upDownBoxHeight + (_upDownBoxHeight - _upDownHeight) / 2, onTop ? isSinglePage ? kColor : (hilite && _part == Part::DownArrow) ? - kWidColor : kTextColor : kColor, 8); + kWidColor : kTextColor : kColor, _upDownWidth, _upDownHeight); // Slider if(!isSinglePage) @@ -273,3 +319,4 @@ void ScrollBarWidget::drawWidget(bool hilite) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - int ScrollBarWidget::_WHEEL_LINES = 4; + diff --git a/src/gui/ScrollBarWidget.hxx b/src/gui/ScrollBarWidget.hxx index bbe227559..7752e8ab7 100644 --- a/src/gui/ScrollBarWidget.hxx +++ b/src/gui/ScrollBarWidget.hxx @@ -24,10 +24,6 @@ class GuiObject; #include "Command.hxx" #include "bspf.hxx" -enum { - kScrollBarWidth = 15 -}; - class ScrollBarWidget : public Widget, public CommandSender { public: @@ -40,6 +36,10 @@ class ScrollBarWidget : public Widget, public CommandSender static void setWheelLines(int lines) { _WHEEL_LINES = lines; } static int getWheelLines() { return _WHEEL_LINES; } + static int scrollBarWidth(const GUI::Font& font) + { + return font.getFontHeight() < 24 ? 15 : 23; + } private: void drawWidget(bool hilite) override; @@ -51,6 +51,7 @@ class ScrollBarWidget : public Widget, public CommandSender bool handleMouseClicks(int x, int y, MouseButton b) override; void handleMouseEntered() override; void handleMouseLeft() override; + void setArrows(); public: int _numEntries{0}; @@ -66,6 +67,12 @@ class ScrollBarWidget : public Widget, public CommandSender int _sliderHeight{0}; int _sliderPos{0}; int _sliderDeltaMouseDownPos{0}; + int _upDownWidth{0}; + int _upDownHeight{0}; + int _upDownBoxHeight{0}; + int _scrollBarWidth{0}; + const uInt32* _upImg{nullptr}; + const uInt32* _downImg{nullptr}; static int _WHEEL_LINES; diff --git a/src/gui/SnapshotDialog.cxx b/src/gui/SnapshotDialog.cxx index c1f94d52f..2c0534ffa 100644 --- a/src/gui/SnapshotDialog.cxx +++ b/src/gui/SnapshotDialog.cxx @@ -30,20 +30,22 @@ SnapshotDialog::SnapshotDialog(OSystem& osystem, DialogContainer& parent, : Dialog(osystem, parent, font, "Snapshot settings"), myFont(font) { - const int VBORDER = 10; - const int HBORDER = 10; - const int INDENT = 16; - const int V_GAP = 4; const int lineHeight = font.getLineHeight(), + fontHeight = _font.getFontHeight(), fontWidth = font.getMaxCharWidth(), - buttonWidth = font.getStringWidth("Save path" + ELLIPSIS) + 20, - buttonHeight = font.getLineHeight() + 4; + buttonWidth = font.getStringWidth("Save path" + ELLIPSIS) + fontWidth * 2.5, + buttonHeight = font.getLineHeight() * 1.25; + const int HBORDER = fontWidth * 1.25; + const int VBORDER = fontHeight / 4; + const int INDENT = fontWidth * 2; + const int VGAP = fontHeight / 4; + int xpos, ypos, fwidth; WidgetArray wid; ButtonWidget* b; // Set real dimensions - setSize(64 * fontWidth + HBORDER * 2, 9 * (lineHeight + 4) + VBORDER + _th, max_w, max_h); + setSize(64 * fontWidth + HBORDER * 2, 9 * (lineHeight + VGAP) + VBORDER + _th, max_w, max_h); xpos = HBORDER; ypos = VBORDER + _th; @@ -51,13 +53,13 @@ SnapshotDialog::SnapshotDialog(OSystem& osystem, DialogContainer& parent, b = new ButtonWidget(this, font, xpos, ypos, buttonWidth, buttonHeight, "Save path" + ELLIPSIS, kChooseSnapSaveDirCmd); wid.push_back(b); - xpos += buttonWidth + 8; - mySnapSavePath = new EditTextWidget(this, font, xpos, ypos + 1, + xpos += buttonWidth + fontWidth; + mySnapSavePath = new EditTextWidget(this, font, xpos, ypos + (buttonHeight - lineHeight) / 2 - 1, _w - xpos - HBORDER, lineHeight, ""); wid.push_back(mySnapSavePath); // Snapshot naming - xpos = HBORDER; ypos += buttonHeight + V_GAP * 4; + xpos = HBORDER; ypos += buttonHeight + VGAP * 4; // Snapshot interval (continuous mode) mySnapInterval = new SliderWidget(this, font, xpos, ypos, @@ -70,21 +72,21 @@ SnapshotDialog::SnapshotDialog(OSystem& osystem, DialogContainer& parent, // Booleans for saving snapshots fwidth = font.getStringWidth("When saving snapshots:"); - xpos = HBORDER; ypos += lineHeight + V_GAP * 3; + xpos = HBORDER; ypos += lineHeight + VGAP * 3; new StaticTextWidget(this, font, xpos, ypos, fwidth, lineHeight, "When saving snapshots:", TextAlign::Left); // Snapshot single or multiple saves - xpos += INDENT; ypos += lineHeight + V_GAP; + xpos += INDENT; ypos += lineHeight + VGAP; mySnapName = new CheckboxWidget(this, font, xpos, ypos, "Use actual ROM name"); wid.push_back(mySnapName); - ypos += lineHeight + V_GAP; + ypos += lineHeight + VGAP; mySnapSingle = new CheckboxWidget(this, font, xpos, ypos, "Overwrite existing files"); wid.push_back(mySnapSingle); // Snapshot in 1x mode (ignore scaling) - ypos += lineHeight + V_GAP; + ypos += lineHeight + VGAP; mySnap1x = new CheckboxWidget(this, font, xpos, ypos, "Ignore scaling (1x mode)"); wid.push_back(mySnap1x); diff --git a/src/gui/StringListWidget.cxx b/src/gui/StringListWidget.cxx index 8af0fcb80..46aed13ba 100644 --- a/src/gui/StringListWidget.cxx +++ b/src/gui/StringListWidget.cxx @@ -29,6 +29,16 @@ StringListWidget::StringListWidget(GuiObject* boss, const GUI::Font& font, _hilite(hilite) { _bgcolorlo = kDlgColor; + + + if(_font.getFontHeight() < 24) + { + _textOfs = 3; + } + else + { + _textOfs = 5; + } } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -106,5 +116,5 @@ void StringListWidget::drawWidget(bool hilite) Common::Rect StringListWidget::getEditRect() const { const int offset = std::max(0, (_selectedItem - _currentPos) * _fontHeight); - return Common::Rect(2, 1 + offset, _w - 2, _fontHeight + offset); + return Common::Rect(_textOfs, 1 + offset, _w - _textOfs, _fontHeight + offset); } diff --git a/src/gui/StringListWidget.hxx b/src/gui/StringListWidget.hxx index 18080a7c7..10c197509 100644 --- a/src/gui/StringListWidget.hxx +++ b/src/gui/StringListWidget.hxx @@ -39,6 +39,7 @@ class StringListWidget : public ListWidget protected: bool _hilite{false}; + int _textOfs{0}; private: // Following constructors and assignment operators not supported diff --git a/src/gui/TimeMachineDialog.cxx b/src/gui/TimeMachineDialog.cxx index e5881ef01..e84c50223 100644 --- a/src/gui/TimeMachineDialog.cxx +++ b/src/gui/TimeMachineDialog.cxx @@ -196,7 +196,7 @@ TimeMachineDialog::TimeMachineDialog(OSystem& osystem, DialogContainer& parent, // Set real dimensions _w = width; // Parent determines our width (based on window size) - _h = V_BORDER * 2 + rowHeight + buttonHeight + 2; + _h = V_BORDER * 2 + rowHeight + std::max(buttonHeight + 2, rowHeight); this->clearFlags(Widget::FLAG_CLEARBG); // does only work combined with blending (0..100)! this->clearFlags(Widget::FLAG_BORDER); @@ -221,9 +221,10 @@ TimeMachineDialog::TimeMachineDialog(OSystem& osystem, DialogContainer& parent, ypos += rowHeight; // Add time info - myCurrentTimeWidget = new StaticTextWidget(this, font, xpos, ypos + 3, "00:00.00", TextAlign::Left, kBGColor); + int ypos_s = ypos + (buttonHeight - font.getFontHeight() + 1) / 2; // align to button vertical center + myCurrentTimeWidget = new StaticTextWidget(this, font, xpos, ypos_s, "00:00.00", TextAlign::Left, kBGColor); myCurrentTimeWidget->setTextColor(kColorInfo); - myLastTimeWidget = new StaticTextWidget(this, font, _w - H_BORDER - font.getStringWidth("00:00.00"), ypos + 3, + myLastTimeWidget = new StaticTextWidget(this, font, _w - H_BORDER - font.getStringWidth("00:00.00"), ypos_s, "00:00.00", TextAlign::Right, kBGColor); myLastTimeWidget->setTextColor(kColorInfo); xpos = myCurrentTimeWidget->getRight() + BUTTON_GAP * 4; @@ -262,7 +263,7 @@ TimeMachineDialog::TimeMachineDialog(OSystem& osystem, DialogContainer& parent, xpos = myLoadAllWidget->getRight() + BUTTON_GAP * 4; // Add message - myMessageWidget = new StaticTextWidget(this, font, xpos, ypos + 3, + myMessageWidget = new StaticTextWidget(this, font, xpos, ypos_s, " ", TextAlign::Left, kBGColor); myMessageWidget->setTextColor(kColorInfo); } diff --git a/src/gui/UIDialog.cxx b/src/gui/UIDialog.cxx index fd52fa483..099886b9b 100644 --- a/src/gui/UIDialog.cxx +++ b/src/gui/UIDialog.cxx @@ -30,6 +30,7 @@ #include "TabWidget.hxx" #include "Widget.hxx" #include "Font.hxx" +#include "StellaMediumFont.hxx" #include "LauncherDialog.hxx" #ifdef DEBUGGER_SUPPORT #include "DebuggerDialog.hxx" @@ -48,12 +49,11 @@ UIDialog::UIDialog(OSystem& osystem, DialogContainer& parent, const int lineHeight = font.getLineHeight(), fontWidth = font.getMaxCharWidth(), fontHeight = font.getFontHeight(), - buttonHeight = font.getLineHeight() + 4; - - const int VBORDER = 8; - const int HBORDER = 10; - const int INDENT = 16; - const int V_GAP = 4; + buttonHeight = font.getLineHeight() * 1.25; + const int VBORDER = fontHeight / 2; + const int HBORDER = fontWidth * 1.25; + const int INDENT = fontWidth * 2; + const int VGAP = fontHeight / 4; int xpos, ypos, tabID; int lwidth, pwidth, bwidth; WidgetArray wid; @@ -61,11 +61,14 @@ UIDialog::UIDialog(OSystem& osystem, DialogContainer& parent, const Common::Size& ds = instance().frameBuffer().desktopSize(); // Set real dimensions - setSize(64 * fontWidth + HBORDER * 2, 11 * (lineHeight + V_GAP) + V_GAP * 9 + VBORDER + _th, + setSize(64 * fontWidth + HBORDER * 2, + _th + VGAP * 3 + lineHeight + 10 * (lineHeight + VGAP) + VGAP * 2 + buttonHeight + VBORDER * 3, max_w, max_h); // The tab widget - myTab = new TabWidget(this, font, 2, 4 + _th, _w - 2*2, _h - _th - buttonHeight - 20); + myTab = new TabWidget(this, font, 2, VGAP + _th, + _w - 2*2, + _h - _th - VGAP - buttonHeight - VBORDER * 2); addTabWidget(myTab); ////////////////////////////////////////////////////////// @@ -85,12 +88,27 @@ UIDialog::UIDialog(OSystem& osystem, DialogContainer& parent, myPalettePopup = new PopUpWidget(myTab, font, xpos, ypos, pwidth, lineHeight, items, "Theme ", lwidth); wid.push_back(myPalettePopup); + ypos += lineHeight + VGAP; + + + // Dialog font + items.clear(); + VarList::push_back(items, "Small", "small"); // 8x13 + VarList::push_back(items, "Low Medium", "low_medium"); // 9x15 + VarList::push_back(items, "Medium", "medium"); // 9x18 + VarList::push_back(items, "Large (10pt)", "large"); // 10x20 + VarList::push_back(items, "Large (12pt)", "large12"); // 12x24 + VarList::push_back(items, "Large (14pt)", "large14"); // 14x28 + VarList::push_back(items, "Large (16pt)", "large16"); // 16x32 + myDialogFontPopup = new PopUpWidget(myTab, font, xpos, ypos, pwidth, lineHeight, + items, "Dialogs font (*)", lwidth, kDialogFont); + wid.push_back(myDialogFontPopup); // Enable HiDPI mode - myHidpiWidget = new CheckboxWidget(myTab, font, myPalettePopup->getRight() + 40, - ypos, "HiDPI mode (*)"); + myHidpiWidget = new CheckboxWidget(myTab, font, myDialogFontPopup->getRight() + fontWidth * 5, + ypos + 1, "HiDPI mode (*)"); wid.push_back(myHidpiWidget); - ypos += lineHeight + V_GAP; + ypos += lineHeight + VGAP; // Dialog position items.clear(); @@ -100,14 +118,14 @@ UIDialog::UIDialog(OSystem& osystem, DialogContainer& parent, VarList::push_back(items, "Right bottom", 3); VarList::push_back(items, "Left bottom", 4); myPositionPopup = new PopUpWidget(myTab, font, xpos, ypos, pwidth, lineHeight, - items, "Dialogs position ", lwidth); + items, "Dialogs position", lwidth); wid.push_back(myPositionPopup); - ypos += lineHeight + V_GAP * 2; + ypos += lineHeight + VGAP * 2; // Confirm dialog when exiting emulation myConfirmExitWidget = new CheckboxWidget(myTab, font, xpos, ypos, "Confirm exiting emulation"); wid.push_back(myConfirmExitWidget); - ypos += lineHeight + V_GAP * 3; + ypos += lineHeight + VGAP * 3; // Delay between quick-selecting characters in ListWidget int swidth = myPalettePopup->getWidth() - lwidth; @@ -119,7 +137,7 @@ UIDialog::UIDialog(OSystem& osystem, DialogContainer& parent, myListDelaySlider->setStepValue(50); myListDelaySlider->setTickmarkIntervals(5); wid.push_back(myListDelaySlider); - ypos += lineHeight + V_GAP; + ypos += lineHeight + VGAP; // Number of lines a mouse wheel will scroll myWheelLinesSlider = new SliderWidget(myTab, font, xpos, ypos, swidth, lineHeight, @@ -129,7 +147,7 @@ UIDialog::UIDialog(OSystem& osystem, DialogContainer& parent, myWheelLinesSlider->setMaxValue(10); myWheelLinesSlider->setTickmarkIntervals(3); wid.push_back(myWheelLinesSlider); - ypos += lineHeight + V_GAP; + ypos += lineHeight + VGAP; // Mouse double click speed myDoubleClickSlider = new SliderWidget(myTab, font, xpos, ypos, swidth, lineHeight, @@ -140,7 +158,7 @@ UIDialog::UIDialog(OSystem& osystem, DialogContainer& parent, myDoubleClickSlider->setStepValue(50); myDoubleClickSlider->setTickmarkIntervals(8); wid.push_back(myDoubleClickSlider); - ypos += lineHeight + V_GAP; + ypos += lineHeight + VGAP; // Initial delay before controller input will start repeating myControllerDelaySlider = new SliderWidget(myTab, font, xpos, ypos, swidth, lineHeight, @@ -151,7 +169,7 @@ UIDialog::UIDialog(OSystem& osystem, DialogContainer& parent, myControllerDelaySlider->setStepValue(100); myControllerDelaySlider->setTickmarkIntervals(4); wid.push_back(myControllerDelaySlider); - ypos += lineHeight + V_GAP; + ypos += lineHeight + VGAP; // Controller repeat rate myControllerRateSlider = new SliderWidget(myTab, font, xpos, ypos, swidth, lineHeight, @@ -164,10 +182,11 @@ UIDialog::UIDialog(OSystem& osystem, DialogContainer& parent, wid.push_back(myControllerRateSlider); // Add message concerning usage - ypos = myTab->getHeight() - 5 - fontHeight - ifont.getFontHeight() - 10; - lwidth = ifont.getStringWidth("(*) Change requires application restart"); - new StaticTextWidget(myTab, ifont, xpos, ypos, std::min(lwidth, _w - 20), fontHeight, - "(*) Change requires application restart"); + ypos = myTab->getHeight() - fontHeight - ifont.getFontHeight() - VGAP - VBORDER; + lwidth = ifont.getStringWidth("(*) Change requires an application restart"); + new StaticTextWidget(myTab, ifont, xpos, ypos, + std::min(lwidth, _w - HBORDER * 2), ifont.getFontHeight(), + "(*) Change requires an application restart"); // Add items for tab 0 addToFocusList(wid, myTab, tabID); @@ -185,39 +204,33 @@ UIDialog::UIDialog(OSystem& osystem, DialogContainer& parent, new ButtonWidget(myTab, font, xpos, ypos, bwidth, buttonHeight, "ROM path" + ELLIPSIS, kChooseRomDirCmd); wid.push_back(romButton); - xpos = romButton->getRight() + 8; - myRomPath = new EditTextWidget(myTab, font, xpos, ypos + 1, + xpos = romButton->getRight() + fontWidth; + myRomPath = new EditTextWidget(myTab, font, xpos, ypos + (buttonHeight - lineHeight) / 2 - 1, _w - xpos - HBORDER - 2, lineHeight, ""); wid.push_back(myRomPath); - xpos = _w - HBORDER - font.getStringWidth("Follow Launcher path") - 24; - ypos += lineHeight + V_GAP * 2; + xpos = _w - HBORDER - font.getStringWidth("Follow Launcher path") - CheckboxWidget::prefixSize(font) - 1; + ypos += lineHeight + VGAP * 2; myFollowLauncherWidget = new CheckboxWidget(myTab, font, xpos, ypos, "Follow Launcher path"); wid.push_back(myFollowLauncherWidget); xpos = HBORDER; - ypos += V_GAP * 2; + ypos += VGAP * 2; // Launcher width and height myLauncherWidthSlider = new SliderWidget(myTab, font, xpos, ypos, "Launcher width ", lwidth, 0, 6 * fontWidth, "px"); - myLauncherWidthSlider->setMinValue(FBMinimum::Width); myLauncherWidthSlider->setMaxValue(ds.w); myLauncherWidthSlider->setStepValue(10); - // one tickmark every ~100 pixel - myLauncherWidthSlider->setTickmarkIntervals((ds.w - FBMinimum::Width + 50) / 100); wid.push_back(myLauncherWidthSlider); - ypos += lineHeight + V_GAP; + ypos += lineHeight + VGAP; myLauncherHeightSlider = new SliderWidget(myTab, font, xpos, ypos, "Launcher height ", lwidth, 0, 6 * fontWidth, "px"); - myLauncherHeightSlider->setMinValue(FBMinimum::Height); myLauncherHeightSlider->setMaxValue(ds.h); myLauncherHeightSlider->setStepValue(10); - // one tickmark every ~100 pixel - myLauncherHeightSlider->setTickmarkIntervals((ds.h - FBMinimum::Height + 50) / 100); wid.push_back(myLauncherHeightSlider); - ypos += lineHeight + V_GAP; + ypos += lineHeight + VGAP; // Launcher font pwidth = font.getStringWidth("2x (1000x760)"); @@ -233,7 +246,7 @@ UIDialog::UIDialog(OSystem& osystem, DialogContainer& parent, new PopUpWidget(myTab, font, xpos, ypos + 1, pwidth, lineHeight, items, "Launcher font ", lwidth); wid.push_back(myLauncherFontPopup); - ypos += lineHeight + V_GAP * 4; + ypos += lineHeight + VGAP * 4; // ROM launcher info/snapshot viewer myRomViewerSize = new SliderWidget(myTab, font, xpos, ypos, "ROM info width ", @@ -245,19 +258,20 @@ UIDialog::UIDialog(OSystem& osystem, DialogContainer& parent, myRomViewerSize->setTickmarkIntervals((myRomViewerSize->getMaxValue() - myRomViewerSize->getMinValue()) / 20); wid.push_back(myRomViewerSize); - ypos += lineHeight + V_GAP; + ypos += lineHeight + VGAP; // Snapshot path (load files) xpos = HBORDER + INDENT; - bwidth = font.getStringWidth("Image path" + ELLIPSIS) + 20 + 1; + bwidth = font.getStringWidth("Image path" + ELLIPSIS) + fontWidth * 2 + 1; myOpenBrowserButton = new ButtonWidget(myTab, font, xpos, ypos, bwidth, buttonHeight, "Image path" + ELLIPSIS, kChooseSnapLoadDirCmd); wid.push_back(myOpenBrowserButton); - mySnapLoadPath = new EditTextWidget(myTab, font, HBORDER + lwidth, ypos + 1, + mySnapLoadPath = new EditTextWidget(myTab, font, HBORDER + lwidth, + ypos + (buttonHeight - lineHeight) / 2 - 1, _w - lwidth - HBORDER * 2 - 2, lineHeight, ""); wid.push_back(mySnapLoadPath); - ypos += lineHeight + V_GAP * 4; + ypos += lineHeight + VGAP * 4; // Exit to Launcher xpos = HBORDER; @@ -266,10 +280,11 @@ UIDialog::UIDialog(OSystem& osystem, DialogContainer& parent, // Add message concerning usage xpos = HBORDER; - ypos = myTab->getHeight() - 5 - fontHeight - ifont.getFontHeight() - 10; - lwidth = ifont.getStringWidth("(*) Changes require application restart"); - new StaticTextWidget(myTab, ifont, xpos, ypos, std::min(lwidth, _w - 20), fontHeight, - "(*) Changes require application restart"); + ypos = myTab->getHeight() - fontHeight - ifont.getFontHeight() - VGAP - VBORDER; + lwidth = ifont.getStringWidth("(*) Changes require an application restart"); + new StaticTextWidget(myTab, ifont, xpos, ypos, + std::min(lwidth, _w - HBORDER * 2), ifont.getFontHeight(), + "(*) Changes require an application restart"); // Add items for tab 1 addToFocusList(wid, myTab, tabID); @@ -319,8 +334,8 @@ void UIDialog::loadConfig() myFollowLauncherWidget->setState(settings.getBool("followlauncher")); // Launcher font - const string& font = settings.getString("launcherfont"); - myLauncherFontPopup->setSelected(font, "medium"); + const string& launcherFont = settings.getString("launcherfont"); + myLauncherFontPopup->setSelected(launcherFont, "medium"); // ROM launcher info viewer float zoom = instance().settings().getFloat("romviewer"); @@ -352,6 +367,10 @@ void UIDialog::loadConfig() // Confirm dialog when exiting emulation myConfirmExitWidget->setState(settings.getBool("confirmexit")); + // Dialog font + const string& dialogFont = settings.getString("dialogfont"); + myDialogFontPopup->setSelected(dialogFont, "medium"); + // Dialog position myPositionPopup->setSelected(settings.getString("dialogpos"), "0"); @@ -375,6 +394,7 @@ void UIDialog::loadConfig() int cr = settings.getInt("ctrlrate"); myControllerRateSlider->setValue(cr); + handleLauncherSize(); handleRomViewer(); myTab->loadConfig(); @@ -398,7 +418,7 @@ void UIDialog::saveConfig() // Launcher font settings.setValue("launcherfont", - myLauncherFontPopup->getSelectedTag().toString()); + myLauncherFontPopup->getSelectedTag().toString()); // ROM launcher info viewer int w = myLauncherWidthSlider->getValue(); @@ -419,6 +439,10 @@ void UIDialog::saveConfig() // Enable HiDPI mode settings.setValue("hidpi", myHidpiWidget->getState()); + // Dialog font + settings.setValue("dialogfont", + myDialogFontPopup->getSelectedTag().toString()); + // Dialog position settings.setValue("dialogpos", myPositionPopup->getSelectedTag().toString()); @@ -458,6 +482,7 @@ void UIDialog::setDefaults() case 0: // Misc. options myPalettePopup->setSelected("standard"); myHidpiWidget->setState(false); + myDialogFontPopup->setSelected("medium", ""); myPositionPopup->setSelected("0"); myConfirmExitWidget->setState(false); myListDelaySlider->setValue(300); @@ -501,6 +526,10 @@ void UIDialog::handleCommand(CommandSender* sender, int cmd, int data, int id) setDefaults(); break; + case kDialogFont: + handleLauncherSize(); + break; + case kListDelay: if(myListDelaySlider->getValue() == 0) { @@ -571,6 +600,29 @@ void UIDialog::handleCommand(CommandSender* sender, int cmd, int data, int id) } } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void UIDialog::handleLauncherSize() +{ + // Determine minimal launcher sizebased on the default font + // So what fits with default font should fit for any font. + FontDesc fd = instance().frameBuffer().getFontDesc(myDialogFontPopup->getSelectedTag().toString()); + int w = std::max(FBMinimum::Width, FBMinimum::Width * fd.maxwidth / GUI::stellaMediumDesc.maxwidth); + int h = std::max(FBMinimum::Height, FBMinimum::Height * fd.height / GUI::stellaMediumDesc.height); + const Common::Size& ds = instance().frameBuffer().desktopSize(); + + myLauncherWidthSlider->setMinValue(w); + if(myLauncherWidthSlider->getValue() < myLauncherWidthSlider->getMinValue()) + myLauncherWidthSlider->setValue(w); + // one tickmark every ~100 pixel + myLauncherWidthSlider->setTickmarkIntervals((ds.w - w + 67) / 100); + + myLauncherHeightSlider->setMinValue(h); + if(myLauncherHeightSlider->getValue() < myLauncherHeightSlider->getMinValue()) + myLauncherHeightSlider->setValue(h); + // one tickmark every ~100 pixel + myLauncherHeightSlider->setTickmarkIntervals((ds.h - h + 67) / 100); +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /*void UIDialog::handleLauncherSize() // an attempt to limit the minimal and maximal ROM info percentages diff --git a/src/gui/UIDialog.hxx b/src/gui/UIDialog.hxx index 4517396d0..83851e971 100644 --- a/src/gui/UIDialog.hxx +++ b/src/gui/UIDialog.hxx @@ -33,13 +33,14 @@ class UIDialog : public Dialog, public CommandSender void setDefaults() override; void handleCommand(CommandSender* sender, int cmd, int data, int id) override; - //void handleLauncherSize(); + void handleLauncherSize(); void handleRomViewer(); void createBrowser(const string& title); private: enum { + kDialogFont = 'UIDf', kListDelay = 'UILd', kMouseWheel = 'UIMw', kControllerDelay = 'UIcd', @@ -66,6 +67,7 @@ class UIDialog : public Dialog, public CommandSender // Misc options PopUpWidget* myPalettePopup{nullptr}; CheckboxWidget* myHidpiWidget{nullptr}; + PopUpWidget* myDialogFontPopup{nullptr}; PopUpWidget* myPositionPopup{nullptr}; CheckboxWidget* myConfirmExitWidget{nullptr}; SliderWidget* myListDelaySlider{nullptr}; diff --git a/src/gui/VideoDialog.cxx b/src/gui/VideoDialog.cxx index 981e1a4e0..b7aa2a2d5 100644 --- a/src/gui/VideoDialog.cxx +++ b/src/gui/VideoDialog.cxx @@ -78,27 +78,33 @@ VideoDialog::VideoDialog(OSystem& osystem, DialogContainer& parent, const GUI::Font& font, int max_w, int max_h) : Dialog(osystem, parent, font, "Video settings") { - const int VGAP = 4; - const int VBORDER = 8; - const int HBORDER = 10; - const int INDENT = 20; const int lineHeight = font.getLineHeight(), + fontHeight = font.getFontHeight(), fontWidth = font.getMaxCharWidth(), - buttonHeight = font.getLineHeight() + 4; + buttonHeight = font.getLineHeight() * 1.25; + const int VGAP = fontHeight / 4; + const int VBORDER = fontHeight / 2; + const int HBORDER = fontWidth * 1.25; + const int INDENT = fontWidth * 2; + int xpos, ypos, tabID; int lwidth = font.getStringWidth("V-Size adjust "), - pwidth = font.getStringWidth("XXXXxXXXX"), - swidth = font.getMaxCharWidth() * 10 - 2; + pwidth = font.getStringWidth("XXXXxXXXX"), + swidth = font.getMaxCharWidth() * 10 - 2; WidgetArray wid; VariantList items; // Set real dimensions - setSize(60 * fontWidth + HBORDER * 2, 14 * (lineHeight + VGAP) + 14 + _th, max_w, max_h); + setSize(60 * fontWidth + HBORDER * 2, + _th + VGAP * 3 + lineHeight + 11 * (lineHeight + VGAP) + buttonHeight + VBORDER * 3, + max_w, max_h); // The tab widget - xpos = 2; ypos = 4; - myTab = new TabWidget(this, font, xpos, ypos + _th, _w - 2*xpos, _h - _th - buttonHeight - 20); + xpos = 2; ypos = VGAP; + myTab = new TabWidget(this, font, xpos, ypos + _th, + _w - 2*xpos, + _h - _th - VGAP - buttonHeight - VBORDER * 2); addTabWidget(myTab); xpos = HBORDER; ypos = VBORDER; @@ -160,7 +166,7 @@ VideoDialog::VideoDialog(OSystem& osystem, DialogContainer& parent, wid.push_back(myUseVSync); // Move over to the next column - xpos += mySpeed->getWidth() + 44; + xpos = myVSizeAdjust->getRight() + fontWidth * 3; ypos = VBORDER; // Fullscreen @@ -216,7 +222,7 @@ VideoDialog::VideoDialog(OSystem& osystem, DialogContainer& parent, tabID = myTab->addTab(" TV Effects "); xpos = HBORDER; ypos = VBORDER; - swidth = font.getMaxCharWidth() * 8 - 4; + swidth = fontWidth * 8 - fontWidth / 2; // TV Mode items.clear(); @@ -258,7 +264,7 @@ VideoDialog::VideoDialog(OSystem& osystem, DialogContainer& parent, CREATE_CUSTOM_SLIDERS(Fringe, "Fringing ", 0) CREATE_CUSTOM_SLIDERS(Bleed, "Bleeding ", 0) - xpos += myTVContrast->getWidth() + 30; + xpos += myTVContrast->getWidth() + fontWidth * 4; ypos = VBORDER; lwidth = font.getStringWidth("Intensity "); @@ -272,7 +278,7 @@ VideoDialog::VideoDialog(OSystem& osystem, DialogContainer& parent, xpos += INDENT; swidth = font.getMaxCharWidth() * 10; CREATE_CUSTOM_SLIDERS(PhosLevel, "Blend ", kPhosBlendChanged) - ypos += 8; + ypos += VGAP * 2; // Scanline intensity and interpolation xpos -= INDENT; @@ -291,7 +297,7 @@ VideoDialog::VideoDialog(OSystem& osystem, DialogContainer& parent, new ButtonWidget(myTab, font, xpos, ypos, cloneWidth, buttonHeight,\ desc, kClone ## obj ##Cmd); \ wid.push_back(myClone ## obj); \ - ypos += lineHeight + 4 + VGAP; + ypos += buttonHeight + VGAP; ypos += VGAP; CREATE_CLONE_BUTTON(RGB, "Clone RGB") diff --git a/src/gui/Widget.cxx b/src/gui/Widget.cxx index 895f68158..ed6ba2f02 100644 --- a/src/gui/Widget.cxx +++ b/src/gui/Widget.cxx @@ -482,26 +482,28 @@ void ButtonWidget::drawWidget(bool hilite) CheckboxWidget::CheckboxWidget(GuiObject* boss, const GUI::Font& font, int x, int y, const string& label, int cmd) - : ButtonWidget(boss, font, x, y, 16, 16, label, cmd) + : ButtonWidget(boss, font, x, y, font.getFontHeight() < 24 ? 16 : 24, + font.getFontHeight() < 24 ? 16 : 24, label, cmd) { _flags = Widget::FLAG_ENABLED; _bgcolor = _bgcolorhi = kWidColor; _bgcolorlo = kDlgColor; _editable = true; + _boxSize = boxSize(font); if(label == "") - _w = 14; + _w = _boxSize; else - _w = font.getStringWidth(label) + 20; - _h = font.getFontHeight() < 14 ? 14 : font.getFontHeight(); + _w = font.getStringWidth(label) + _boxSize + font.getMaxCharWidth() * 0.75; + _h = font.getFontHeight() < _boxSize ? _boxSize : font.getFontHeight(); // Depending on font size, either the font or box will need to be // centered vertically - if(_h > 14) // center box - _boxY = (_h - 14) / 2; + if(_h > _boxSize) // center box + _boxY = (_h - _boxSize) / 2; else // center text - _textY = (14 - _font.getFontHeight()) / 2; + _textY = (_boxSize - _font.getFontHeight()) / 2; setFill(CheckboxWidget::FillType::Normal); } @@ -549,7 +551,8 @@ void CheckboxWidget::setEditable(bool editable) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void CheckboxWidget::setFill(FillType type) { - /* 8x8 checkbox bitmap */ + /* 10x10 checkbox bitmap */ + // small versions static constexpr std::array checked_img_active = { 0b1111111111, 0b1111111111, 0b1111111111, 0b1111111111, 0b1111111111, 0b1111111111, 0b1111111111, 0b1111111111, 0b1111111111, 0b1111111111 @@ -565,17 +568,36 @@ void CheckboxWidget::setFill(FillType type) 0b1111111111, 0b1111111111, 0b0111111110, 0b0111111110, 0b0001111000 }; + /* 18x18 checkbox bitmap */ + // large versions + static constexpr std::array checked_img_active_large = { + 0b111111111111111111, 0b111111111111111111, 0b111111111111111111, 0b111111111111111111, + 0b111111111111111111, 0b111111111111111111, 0b111111111111111111, 0b111111111111111111, + 0b111111111111111111, 0b111111111111111111, 0b111111111111111111, 0b111111111111111111, + 0b111111111111111111, 0b111111111111111111, 0b111111111111111111, 0b111111111111111111, + 0b111111111111111111, 0b111111111111111111 + }; + + static constexpr std::array checked_img_inactive_large = { + 0b111111111111111111, 0b111111111111111111, 0b111111111111111111, + 0b111111110011111111, 0b111111100001111111, 0b111111000000111111, 0b111110000000011111, + 0b111100000000001111, 0b111000000000000111, 0b111000000000000111, 0b111100000000001111, + 0b111110000000011111, 0b111111000000111111, 0b111111100001111111, 0b111111110011111111, + 0b111111111111111111, 0b111111111111111111, 0b111111111111111111 + }; + switch(type) { case CheckboxWidget::FillType::Normal: - _img = checked_img_active.data(); + _img = _boxSize == 14 ? checked_img_active.data() : checked_img_active_large.data(); _drawBox = true; break; case CheckboxWidget::FillType::Inactive: - _img = checked_img_inactive.data(); + _img = _boxSize == 14 ? checked_img_inactive.data() : checked_img_inactive_large.data(); _drawBox = true; break; case CheckboxWidget::FillType::Circle: + // only used in debugger which only has smaller fonts _img = checked_img_circle.data(); _drawBox = false; break; @@ -601,17 +623,17 @@ void CheckboxWidget::drawWidget(bool hilite) bool onTop = _boss->dialog().isOnTop(); if(_drawBox) - s.frameRect(_x, _y + _boxY, 14, 14, onTop && hilite && isEnabled() && isEditable() ? kWidColorHi : kColor); + s.frameRect(_x, _y + _boxY, _boxSize, _boxSize, onTop && hilite && isEnabled() && isEditable() ? kWidColorHi : kColor); // Do we draw a square or cross? - s.fillRect(_x + 1, _y + _boxY + 1, 12, 12, + s.fillRect(_x + 1, _y + _boxY + 1, _boxSize - 2, _boxSize - 2, _changed ? onTop ? kDbgChangedColor : kDlgColor : isEnabled() && onTop ? _bgcolor : kDlgColor); if(_state) s.drawBitmap(_img, _x + 2, _y + _boxY + 2, onTop && isEnabled() ? hilite && isEditable() ? kWidColorHi : kCheckColor - : kColor, 10); + : kColor, _boxSize - 4); // Finally draw the label - s.drawString(_font, _label, _x + 20, _y + _textY, _w, + s.drawString(_font, _label, _x + prefixSize(_font), _y + _textY, _w, onTop && isEnabled() ? kTextColor : kColor); setDirty(); @@ -640,7 +662,7 @@ SliderWidget::SliderWidget(GuiObject* boss, const GUI::Font& font, if(_valueLabelWidth == 0) _valueLabelGap = 0; if(_valueLabelGap == 0) - _valueLabelGap = DEF_LBL_GAP; + _valueLabelGap = font.getMaxCharWidth() / 2; _w = w + _labelWidth + _valueLabelGap + _valueLabelWidth; } @@ -807,9 +829,9 @@ void SliderWidget::drawWidget(bool hilite) s.drawString(_font, _label, _x, _y + 2, _labelWidth, isEnabled() ? kTextColor : kColor); int p = valueToPos(_value), - h = _h - 10, + h = _h - _font.getFontHeight() / 2 - 1, x = _x + _labelWidth, - y = _y + (_h - h) / 2 + 1; + y = _y + 2 + _font.desc().ascent - (_font.getFontHeight() + 1) / 2 - 1; // align to bottom of font // Fill the box s.fillRect(x, y, _w - _labelWidth - _valueLabelGap - _valueLabelWidth, h, diff --git a/src/gui/Widget.hxx b/src/gui/Widget.hxx index aa45a5420..eb31f7cd4 100644 --- a/src/gui/Widget.hxx +++ b/src/gui/Widget.hxx @@ -285,7 +285,14 @@ class CheckboxWidget : public ButtonWidget void handleMouseEntered() override; void handleMouseLeft() override; - static int boxSize() { return 14; } // box is square + static int boxSize(const GUI::Font& font) + { + return font.getFontHeight() < 24 ? 14 : 22; // box is square + } + static int prefixSize(const GUI::Font& font) + { + return boxSize(font) + font.getMaxCharWidth() * 0.75; + } protected: void drawWidget(bool hilite) override; @@ -296,10 +303,13 @@ class CheckboxWidget : public ButtonWidget bool _drawBox{true}; bool _changed{false}; + const uInt32* _outerCircle{nullptr}; + const uInt32* _innerCircle{nullptr}; const uInt32* _img{nullptr}; ColorId _fillColor{kColor}; int _boxY{0}; int _textY{0}; + int _boxSize{14}; private: // Following constructors and assignment operators not supported @@ -342,9 +352,6 @@ class SliderWidget : public ButtonWidget void setTickmarkIntervals(int numIntervals); - protected: - const int DEF_LBL_GAP = 4; - protected: void handleMouseMoved(int x, int y) override; void handleMouseDown(int x, int y, MouseButton b, int clickCount) override; diff --git a/src/unix/stella.spec b/src/unix/stella.spec index a4236c38f..796217ea6 100644 --- a/src/unix/stella.spec +++ b/src/unix/stella.spec @@ -1,5 +1,5 @@ %define name stella -%define version 6.1 +%define version 6.1.2 %define rel 1 %define enable_sound 1 @@ -100,6 +100,9 @@ rm -rf $RPM_BUILD_DIR/%{name}-%{version} %_datadir/icons/large/%{name}.png %changelog +* Sat Apr 25 2020 Stephen Anthony 6.1.2-1 +- Version 6.1.2 release + * Sat Apr 04 2020 Stephen Anthony 6.1.1-1 - Version 6.1.1 release
    ItemBrief descriptionFor more information,
    see CommandLine
    ThemeTheme to use for UI elements (see examples)-uipalette
    Dialogs positionPosition of dialogs with Stella window-dialogpos
    Dialogs fontThe font used in the dialogs-dialogfont
    HiDPI modeScales the UI by a factor of two when enabled-hidpi
    Dialogs positionPosition of dialogs with Stella window-dialogpos
    Confirm exiting...Display a popup when emulation is exited-confirmexit
    List input delayMaximum delay between keypresses in filelist-widgets before a search string resets. -listdelay
    Mouse wheel scrollNumber of lines a mouse scroll will move in list-widgets-mwheel