added editable PopupWidget

made AtariVox serial port editable
This commit is contained in:
thrust26 2020-10-22 12:09:49 +02:00
parent 858e79e7d3
commit 1e68194576
6 changed files with 104 additions and 42 deletions

View File

@ -19,6 +19,8 @@
* Fixed bug with aspect correction and fullscreen mode; snapshots from
such a mode are now pixel-exact.
* Made serial port used for an AtariVox-USB adaptor editable. (TODO: Doc)
-Have fun!

View File

@ -186,11 +186,12 @@ bool OSystem::create()
myPropSet->load(myPropertiesFile);
// Detect serial port for AtariVox-USB
// If a previously set port is available, use it;
// If a previously set port is defined, use it;
// otherwise use the first one found (if any)
StringList ports = MediaFactory::createSerialPort()->portNames();
bool oldPortFound = BSPF::contains(ports, mySettings->getString("avoxport"));
if(!oldPortFound && ports.size() > 0)
const string& avoxport = mySettings->getString("avoxport");
const StringList ports = MediaFactory::createSerialPort()->portNames();
if(avoxport.empty() && ports.size() > 0)
mySettings->setValue("avoxport", ports[0]);
return true;

View File

@ -93,7 +93,7 @@ GameInfoDialog::GameInfoDialog(
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() + fontWidth, ypos,
pwidth, lineHeight, items, "");
pwidth, lineHeight, items);
wid.push_back(myBSType);
ypos += lineHeight + VGAP;
@ -105,7 +105,7 @@ GameInfoDialog::GameInfoDialog(
myStartBankLabel = new StaticTextWidget(myTab, font, HBORDER, ypos + 1, "Start bank (*) ");
items.clear();
myStartBank = new PopUpWidget(myTab, font, myStartBankLabel->getRight(), ypos,
font.getStringWidth("AUTO"), lineHeight, items, "", 0, 0);
font.getStringWidth("AUTO"), lineHeight, items);
wid.push_back(myStartBank);
ypos += lineHeight + VGAP * 4;
@ -120,7 +120,7 @@ GameInfoDialog::GameInfoDialog(
VarList::push_back(items, "PAL60", "PAL60");
VarList::push_back(items, "SECAM60", "SECAM60");
myFormat = new PopUpWidget(myTab, font, t->getRight(), ypos,
pwidth, lineHeight, items, "", 0, 0);
pwidth, lineHeight, items);
wid.push_back(myFormat);
myFormatDetected = new StaticTextWidget(myTab, ifont, myFormat->getRight() + fontWidth, ypos + 4,

View File

@ -224,10 +224,9 @@ void InputDialog::addDevicePortTab()
ypos += lineHeight + VGAP * 3;
lwidth = _font.getStringWidth("AtariVox serial port ");
fwidth = _w - HBORDER * 2 - 2 - lwidth - PopUpWidget::dropDownWidth(_font);
VariantList items;
VarList::push_back(items, "None detected", "");
myAVoxPort = new PopUpWidget(myTab, _font, HBORDER, ypos, fwidth, lineHeight, items,
myAVoxPort = new PopUpWidget(myTab, _font, HBORDER, ypos, fwidth, lineHeight, EmptyVarList,
"AtariVox serial port ", lwidth, kCursorStateChanged);
myAVoxPort->setEditable(true);
wid.push_back(myAVoxPort);
// Add items for virtual device ports
@ -362,13 +361,16 @@ void InputDialog::loadConfig()
// AtariVox serial port
const string& avoxport = settings.getString("avoxport");
StringList ports = MediaFactory::createSerialPort()->portNames();
if(avoxport != EmptyString && !BSPF::contains(ports, avoxport))
ports.push_back(avoxport);
const StringList ports = MediaFactory::createSerialPort()->portNames();
VariantList items;
VarList::push_back(items, "None detected", "");
for(const auto& port: ports)
VarList::push_back(items, port, port);
VarList::push_back(items, port);
if(avoxport != EmptyString && !BSPF::contains(ports, avoxport))
VarList::push_back(items, avoxport, avoxport);
if(items.size() == 0)
VarList::push_back(items, "None detected");
myAVoxPort->addItems(items);
myAVoxPort->setSelected(avoxport);
@ -451,7 +453,7 @@ void InputDialog::saveConfig()
Controller::setAutoFireRate(rate);
// AtariVox serial port
settings.setValue("avoxport", myAVoxPort->getSelectedTag().toString());
settings.setValue("avoxport", myAVoxPort->getText());
// Allow all 4 joystick directions
bool allowall4 = myAllowAll4->getState();
@ -490,17 +492,11 @@ void InputDialog::setDefaults()
break;
case 2: // Devices & Ports
// Left & right ports
mySAPort->setState(false);
// Joystick deadzone
myDeadzone->setValue(0);
// Paddle speed (analog)
myPaddleSpeed->setValue(20);
// Paddle speed (digital)
myDPaddleSpeed->setValue(10);
#if defined(RETRON77)
myDejitterBase->setValue(2);
myDejitterDiff->setValue(6);
@ -508,10 +504,12 @@ void InputDialog::setDefaults()
myDejitterBase->setValue(0);
myDejitterDiff->setValue(0);
#endif
// Paddle speed (digital)
myDPaddleSpeed->setValue(10);
// Autofire rate
myAutoFireRate->setValue(0);
// AtariVox serial port
myAVoxPort->setSelectedMax();
// Allow all 4 joystick directions
myAllowAll4->setState(false);
@ -519,6 +517,11 @@ void InputDialog::setDefaults()
// Enable/disable modifier key-combos
myModCombo->setState(true);
// Left & right ports
mySAPort->setState(false);
// AtariVox serial port
myAVoxPort->setSelectedIndex(0);
break;
case 3: // Mouse

View File

@ -27,8 +27,7 @@
PopUpWidget::PopUpWidget(GuiObject* boss, const GUI::Font& font,
int x, int y, int w, int h, const VariantList& list,
const string& label, int labelWidth, int cmd)
: Widget(boss, font, x, y - 1, w, h + 2),
CommandSender(boss),
: EditableWidget(boss, font, x, y - 1, w, h + 2),
_label(label),
_labelWidth(labelWidth)
{
@ -38,6 +37,8 @@ PopUpWidget::PopUpWidget(GuiObject* boss, const GUI::Font& font,
_textcolor = kTextColor;
_textcolorhi = kTextColor; // do not highlight the label
setEditable(false);
if(!_label.empty() && _labelWidth == 0)
_labelWidth = _font.getStringWidth(_label);
@ -70,6 +71,7 @@ void PopUpWidget::addItems(const VariantList& items)
void PopUpWidget::setSelected(const Variant& tag, const Variant& def)
{
myMenu->setSelected(tag, def);
setText(myMenu->getSelectedName());
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -77,6 +79,7 @@ void PopUpWidget::setSelectedIndex(int idx, bool changed)
{
_changed = changed;
myMenu->setSelectedIndex(idx);
setText(myMenu->getSelectedName());
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -84,6 +87,7 @@ void PopUpWidget::setSelectedMax(bool changed)
{
_changed = changed;
myMenu->setSelectedMax();
setText(myMenu->getSelectedName());
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -113,11 +117,31 @@ const Variant& PopUpWidget::getSelectedTag() const
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void PopUpWidget::handleMouseDown(int x, int y, MouseButton b, int clickCount)
{
if(isEnabled() && !myMenu->isVisible())
if(!isEditable() || x > _w - dropDownWidth(_font))
{
// Add menu just underneath parent widget
myMenu->show(getAbsX() + _labelWidth, getAbsY() + getHeight(),
dialog().surface().dstRect(), myMenu->getSelected());
if(isEnabled() && !myMenu->isVisible())
{
// Add menu just underneath parent widget
myMenu->show(getAbsX() + _labelWidth, getAbsY() + getHeight(),
dialog().surface().dstRect(), myMenu->getSelected());
}
}
else
{
x += _editScrollOffset - _labelWidth;
int width = 0;
uInt32 i;
for(i = 0; i < editString().size(); ++i)
{
width += _font.getCharWidth(editString()[i]);
if(width >= x)
break;
}
if(setCaretPos(i))
setDirty();
}
}
@ -180,6 +204,7 @@ void PopUpWidget::handleCommand(CommandSender* sender, int cmd, int data, int id
{
// Intercept all events sent through the PromptWidget
// They're likely from our ContextMenu, indicating a redraw is required
setText(myMenu->getSelectedName());
dialog().setDirty();
// Pass the cmd on to our parent
@ -246,23 +271,49 @@ void PopUpWidget::drawWidget(bool hilite)
// Draw a thin frame around us.
s.frameRect(x, _y, w, _h, isEnabled() && hilite ? kWidColorHi : kColor);
s.frameRect(x + w - (_arrowWidth * 2 - 2), _y + 1, (_arrowWidth * 2 - 3), _h - 2,
isEnabled() && hilite ? kWidColorHi : kBGColorLo);
if(isEnabled() && hilite)
s.frameRect(x + w - (_arrowWidth * 2 - 1), _y, (_arrowWidth * 2 - 1), _h, kWidColorHi);
// Fill the background
s.fillRect(x + 1, _y + 1, w - (_arrowWidth * 2 - 1), _h - 2,
onTop ? _changed ? kDbgChangedColor : kWidColor : kDlgColor);
s.fillRect(x + w - (_arrowWidth * 2 - 3), _y + 2, (_arrowWidth * 2 - 5), _h - 4,
onTop ? isEnabled() && hilite ? kWidColor : kBGColorHi : kBGColorLo);
ColorId bgCol = isEditable() ? kWidColor : kDlgColor;
s.fillRect(x + 1, _y + 1, w - (_arrowWidth * 2 - 0), _h - 2,
onTop ? _changed ? kDbgChangedColor : bgCol : kDlgColor);
s.fillRect(x + w - (_arrowWidth * 2 - 2), _y + 1, (_arrowWidth * 2 - 3), _h - 2,
onTop ? isEnabled() && hilite ? kBtnColorHi : bgCol : kBGColorLo);
// Draw an arrow pointing down at the right end to signal this is a dropdown/popup
s.drawBitmap(_arrowImg, x + w - (_arrowWidth * 1.5 - 1), _y + myArrowsY + 1,
!(isEnabled() && onTop) ? kColor : kTextColor, _arrowWidth, _arrowHeight);
// Draw the selected entry, if any
const string& name = myMenu->getSelectedName();
const string& name = editString();
bool editable = isEditable();
w -= dropDownWidth(_font);
TextAlign align = (_font.getStringWidth(name) > w) ?
TextAlign align = (_font.getStringWidth(name) > w && !editable) ?
TextAlign::Right : TextAlign::Left;
adjustOffset();
s.drawString(_font, name, x + _textOfs, _y + myTextY, w,
!(isEnabled() && onTop) ? kColor : _changed ? kDbgChangedTextColor : kTextColor, align);
!(isEnabled() && onTop) ? kColor : _changed ? kDbgChangedTextColor : kTextColor,
align, editable ? -_editScrollOffset : 0, !editable);
if(editable)
drawCaret();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Common::Rect PopUpWidget::getEditRect() const
{
return Common::Rect(_labelWidth + _textOfs, 1, _w - _textOfs - dropDownWidth(_font), _h);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void PopUpWidget::endEditMode()
{
// Editing is always enabled
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void PopUpWidget::abortEditMode()
{
// Editing is always enabled
}

View File

@ -24,7 +24,7 @@ class ContextMenu;
#include "bspf.hxx"
#include "Variant.hxx"
#include "Command.hxx"
#include "Widget.hxx"
#include "EditableWidget.hxx"
/**
* Popup or dropdown widget which, when clicked, "pop up" a list of items and
@ -33,12 +33,12 @@ class ContextMenu;
* Implementation wise, when the user selects an item, then a kPopUpItemSelectedCmd
* is broadcast, with data being equal to the tag value of the selected entry.
*/
class PopUpWidget : public Widget, public CommandSender
class PopUpWidget : public EditableWidget
{
public:
PopUpWidget(GuiObject* boss, const GUI::Font& font,
int x, int y, int w, int h, const VariantList& items,
const string& label, int labelWidth = 0, int cmd = 0);
const string& label = "", int labelWidth = 0, int cmd = 0);
~PopUpWidget() override = default;
void setID(uInt32 id);
@ -78,6 +78,11 @@ class PopUpWidget : public Widget, public CommandSender
void setArrow();
void drawWidget(bool hilite) override;
void endEditMode() override;
void abortEditMode() override;
Common::Rect getEditRect() const override;
private:
unique_ptr<ContextMenu> myMenu;
int myArrowsY{0};