Part 1 of the changes for #600 (UI fonts)

This commit is contained in:
thrust26 2020-04-29 14:25:54 +02:00
parent bbbf4ed2e0
commit b9ec835ef5
37 changed files with 922 additions and 430 deletions

View File

@ -24,6 +24,8 @@
* Added 'Turbo' mode, runs the game as fast as the computer allows.
* Added selectable dialog fonts (TODO: Doc)
* Added option which lets default ROM path follow launcher navigation (TODO: Doc)
* Added displaying last write address in the debugger.

View File

@ -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);

View File

@ -65,7 +65,7 @@ int CartDebugWidget::addBaseInformation(size_t bytes, const string& manufacturer
w->setEditable(false);
y += myLineHeight + 4;
StringParser bs(desc, (fwidth - kScrollBarWidth) / myFontWidth - 4);
StringParser bs(desc, (fwidth - ScrollBarWidget::scrollBarWidth(_font)) / myFontWidth - 4);
const StringList& sl = bs.stringList();
uInt32 lines = uInt32(sl.size());
if(lines < 3) lines = 3;

View File

@ -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 < 3) lines = 3;

View File

@ -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);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -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);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -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::Font>(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::Font>(GUI::stella12x24tDesc); // 12x24
// The info font used in all UI elements
// This is determined by the size of the framebuffer
myInfoFont = make_unique<GUI::Font>(GUI::stellaLargeDesc); // 10x20
}
else
{
myFont = make_unique<GUI::Font>(GUI::stellaMediumDesc); // 9x18
// The info font used in all UI elements
// This is determined by the size of the framebuffer
myInfoFont = make_unique<GUI::Font>(GUI::consoleDesc); // 8x13
}
// The font used by the ROM launcher
const string& lf = myOSystem.settings().getString("launcherfont");
if(lf == "small")
myLauncherFont = make_unique<GUI::Font>(GUI::consoleBDesc); // 8x13
else if(lf == "low_medium")
myLauncherFont = make_unique<GUI::Font>(GUI::consoleMediumBDesc); // 9x15
else if(lf == "medium")
myLauncherFont = make_unique<GUI::Font>(GUI::stellaMediumDesc); // 9x18
else if(lf == "large" || lf == "large10")
myLauncherFont = make_unique<GUI::Font>(GUI::stellaLargeDesc); // 10x20
else if(lf == "large12")
myLauncherFont = make_unique<GUI::Font>(GUI::stella12x24tDesc); // 12x24
else if(lf == "large14")
myLauncherFont = make_unique<GUI::Font>(GUI::stella14x28tDesc); // 14x28
else // "large16"
myLauncherFont = make_unique<GUI::Font>(GUI::stella16x32tDesc); // 16x32
setupFonts();
#endif
// Determine possible TIA windowed zoom levels
@ -164,6 +116,93 @@ 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::Font>(GUI::stellaDesc); // 6x10
if(myOSystem.settings().getBool("minimal_ui"))
{
// The general font used in all UI elements
myFont = make_unique<GUI::Font>(GUI::stella12x24tDesc); // 12x24
// The info font used in all UI elements
myInfoFont = make_unique<GUI::Font>(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<GUI::Font>(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<GUI::Font>(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;
int zoom = std::max(zoom_w, zoom_h);
myTIAMinZoom = std::max(2 * 4, zoom) / 4.F; // round to 25% steps
}
// The font used by the ROM launcher
const string& lf = myOSystem.settings().getString("launcherfont");
myLauncherFont = make_unique<GUI::Font>(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,
@ -965,7 +1004,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

View File

@ -35,6 +35,7 @@ namespace GUI {
#include "TIAConstants.hxx"
#include "FrameBufferConstants.hxx"
#include "EventHandlerConstants.hxx"
#include "Font.hxx"
#include "bspf.hxx"
/**
@ -223,7 +224,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; }
/**
@ -480,6 +481,16 @@ class FrameBuffer
*/
void resetSurfaces();
#ifdef GUI_SUPPORT
/**
Setup the UI fonts
*/
void setupFonts();
FontDesc getFontDesc(const string& name) const;
#endif
/**
Calculate the maximum level by which the base window can be zoomed and
still fit in the given screen dimensions.
@ -619,6 +630,8 @@ class FrameBuffer
VideoModeList myWindowedModeList;
vector<VideoModeList> 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};

View File

@ -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 <standard| Selects GUI theme\n"
<< " classic|light>\n"
<< " -hidpi <0|1> Enable HiDPI mode\n"
<< " -dialogfont <small| Use the specified font in the dialogs\n"
<< " low_medium|\n"
<< " medium|large|\n"
<< " large12|large14|\n"
<< " large16>\n"
<< " -dialogpos <0..4> Display all dialogs at given positions\n"
<< " -confirmexit <0|1> Display a confirm dialog when exiting emulation\n"
<< " -listdelay <delay> Time to wait between keypresses in list widgets\n"

View File

@ -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,

View File

@ -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,

View File

@ -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);

View File

@ -33,16 +33,20 @@
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.5,
buttonWidth = _font.getStringWidth("Time Machine On") + fontWidth * 2;
const int VBORDER = fontHeight / 2;
const int HBORDER = fontWidth * 1.25;
const int INDENT = fontWidth * 2;
const int VGAP = fontHeight / 4;
const int HGAP = VGAP * 2;
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;

View File

@ -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,7 +615,7 @@ 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;
ypos = myTab->getHeight() - fontHeight - infofont.getFontHeight() - VGAP - VBORDER;
new StaticTextWidget(myTab, infofont, HBORDER, ypos, "(*) Changes require a ROM reload");
#if defined(DEBUGGER_SUPPORT) && defined(WINDOWED_SUPPORT)

View File

@ -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));

View File

@ -44,10 +44,12 @@ EventMappingWidget::EventMappingWidget(GuiObject* boss, const GUI::Font& font,
{
const int fontHeight = font.getFontHeight(),
lineHeight = font.getLineHeight(),
fontWidth = font.getMaxCharWidth(),
buttonWidth = font.getStringWidth("Defaults") + 10,
buttonHeight = font.getLineHeight() + 4;
const int HBORDER = 8;
const int VBORDER = 8;
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;
@ -74,8 +76,8 @@ EventMappingWidget::EventMappingWidget(GuiObject* boss, const GUI::Font& font,
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,
lineHeight + font.getFontHeight() * (ACTION_LINES - 1), "");
myKeyMapping->setEditable(false, true);
myKeyMapping->clearFlags(Widget::FLAG_RETAIN_FOCUS);

View File

@ -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,7 +154,7 @@ 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");
@ -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<uInt32>(MouseControl::Type::MindLink0));
VarList::push_back(items, "MindLink 1", static_cast<uInt32>(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 ");

View File

@ -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");

View File

@ -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);

View File

@ -61,14 +61,14 @@ LauncherDialog::LauncherDialog(OSystem& osystem, DialogContainer& parent,
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;
LBL_GAP = fontWidth,
HBORDER = 10,//fontWidth * 1.25,
BUTTON_GAP = fontWidth,
bwidth = (_w - 2 * HBORDER - BUTTON_GAP * (4 - 1));
int xpos = 0, ypos = 0, lwidth = 0, lwidth2 = 0;
WidgetArray wid;

View File

@ -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);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -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);

View File

@ -49,15 +49,19 @@
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,
const int lineHeight = _font.getLineHeight(),
fontWidth = _font.getMaxCharWidth(),
fontHeight = _font.getFontHeight(),
buttonHeight = _font.getLineHeight() * 1.25,
GAP = fontWidth / 2,
rowHeight = buttonHeight + GAP;
const int VBORDER = GAP * 2 + 2;
const int HBORDER = GAP * 2 + 2;
const int VBORDER = fontHeight / 2;
const int HBORDER = fontWidth * 1.25;
int buttonWidth = _font.getStringWidth("Game Properties" + ELLIPSIS) + GAP * 5;
_w = 2 * buttonWidth + HBORDER * 3;
@ -243,8 +247,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<UIDialog>(instance(), parent(),
instance().frameBuffer().font(), myBoss, w, h);
}
myUIDialog->open();
break;
}
case kSnapCmd:
{

View File

@ -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};

View File

@ -187,7 +187,7 @@ void PopUpWidget::handleCommand(CommandSender* sender, int cmd, int data, int id
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void PopUpWidget::drawWidget(bool hilite)
{
// Little down arrow
// Small down arrow
static constexpr std::array<uInt32, 8> down_arrow = {
0b100000001,
0b110000011,
@ -198,6 +198,21 @@ void PopUpWidget::drawWidget(bool hilite)
0b000010000,
0b000000000
};
// Large down arrow
static constexpr std::array<uInt32, 11> down_arrow_large = {
0b00000000000,
0b10000000001,
0b11000000011,
0b11100000111,
0b11110001111,
0b01111011110,
0b00111111100,
0b00011111000,
0b00001110000,
0b00000100000,
0b00000000000
};
//cerr << "PopUpWidget::drawWidget\n";
FBSurface& s = dialog().surface();

View File

@ -21,6 +21,7 @@
#include "RadioButtonWidget.hxx"
/* Radiobutton bitmaps */
// small versions
static constexpr std::array<uInt32, 14> radio_img_outercircle = {
0b00001111110000, 0b00110000001100, 0b01000000000010,
0b01000000000010, 0b10000000000001, 0b10000000000001,
@ -33,16 +34,188 @@ static constexpr std::array<uInt32, 12> radio_img_innercircle = {
0b111111111111, 0b111111111111, 0b111111111111, 0b111111111111,
0b111111111111, 0b011111111110, 0b011111111110, 0b000111111000
};
static constexpr uInt32 RADIO_IMG_FILL_SIZE = 10;
static constexpr std::array<uInt32, RADIO_IMG_FILL_SIZE> radio_img_active = {
static constexpr std::array<uInt32, 10> radio_img_active = {
0b0011111100, 0b0111111110, 0b1111111111, 0b1111111111, 0b1111111111,
0b1111111111, 0b1111111111, 0b1111111111, 0b0111111110, 0b0011111100,
};
static constexpr std::array<uInt32, RADIO_IMG_FILL_SIZE> radio_img_inactive = {
static constexpr std::array<uInt32, 10> radio_img_inactive = {
0b0011111100, 0b0111111110, 0b1111001111, 0b1110000111, 0b1100000011,
0b1100000011, 0b1110000111, 0b1111001111, 0b0111111110, 0b0011111100
};
// large versions
static constexpr std::array<uInt32, 22> 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<uInt32, 20> 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<uInt32, 18> 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<uInt32, 18> 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<uInt32>(radio_img_outercircle.size()),
static_cast<uInt32>(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<uInt32>(radio_img_innercircle.size()),
static_cast<uInt32>(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);
}

View File

@ -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

View File

@ -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");

View File

@ -205,14 +205,21 @@ void RomInfoWidget::drawWidget(bool hilite)
int xpos = _x + 8, ypos = _y + yoff + 5;
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);
ypos += _font.getLineHeight() + (lines - 1) * _font.getFontHeight();
// assume 2 lines for next entry
if(ypos >= _h + _y - _font.getLineHeight() - _font.getFontHeight())
break;
}
}

View File

@ -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<uInt32, 6> up_arrow = {
0b0001000,
0b0011100,
0b0111110,
0b1110111,
0b1100011,
0b1000001,
};
// Small down arrow
static constexpr std::array<uInt32, 6> down_arrow = {
0b1000001,
0b1100011,
0b1110111,
0b0111110,
0b0011100,
0b0001000
};
// Large up arrow
static constexpr std::array<uInt32, 9> up_arrow_large = {
0b00000100000,
0b00001110000,
0b00011111000,
0b00111111100,
0b01111011110,
0b11110001111,
0b11100000111,
0b11000000011,
0b10000000001,
};
// Large down arrow
static constexpr std::array<uInt32, 9> 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<uInt32, 8> up_arrow = {
0b00000000,
0b00010000,
0b00111000,
0b01111100,
0b11101110,
0b11000110,
0b10000010,
0b00000000
};
// Down arrow
static constexpr std::array<uInt32, 8> 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;

View File

@ -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 ((int(font.getMaxCharWidth() * 1.67) >> 1) << 1) + 1;
}
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;

View File

@ -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);

View File

@ -48,12 +48,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 +60,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 +87,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);
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 +117,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 +136,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 +146,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 +157,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 +168,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 +181,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("(*) Changes require application restart");
new StaticTextWidget(myTab, ifont, xpos, ypos,
std::min(lwidth, _w - HBORDER * 2), ifont.getFontHeight(),
"(*) Changes require application restart");
// Add items for tab 0
addToFocusList(wid, myTab, tabID);
@ -185,18 +203,18 @@ 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);
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 ",
@ -207,7 +225,7 @@ UIDialog::UIDialog(OSystem& osystem, DialogContainer& parent,
// 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");
@ -217,7 +235,7 @@ UIDialog::UIDialog(OSystem& osystem, DialogContainer& parent,
// 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 +251,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 +263,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,9 +285,10 @@ UIDialog::UIDialog(OSystem& osystem, DialogContainer& parent,
// Add message concerning usage
xpos = HBORDER;
ypos = myTab->getHeight() - 5 - fontHeight - ifont.getFontHeight() - 10;
ypos = myTab->getHeight() - fontHeight - ifont.getFontHeight() - VGAP - VBORDER;
lwidth = ifont.getStringWidth("(*) Changes require application restart");
new StaticTextWidget(myTab, ifont, xpos, ypos, std::min(lwidth, _w - 20), fontHeight,
new StaticTextWidget(myTab, ifont, xpos, ypos,
std::min(lwidth, _w - HBORDER * 2), ifont.getFontHeight(),
"(*) Changes require application restart");
// Add items for tab 1
@ -319,8 +339,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 +372,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");
@ -398,7 +422,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 +443,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 +486,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);

View File

@ -66,6 +66,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};

View File

@ -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")

View File

@ -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<uInt32, 10> 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<uInt32, 18> 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<uInt32, 18> 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,7 +829,7 @@ 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;

View File

@ -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;