mirror of https://github.com/stella-emu/stella.git
added editable PopupWidget
made AtariVox serial port editable
This commit is contained in:
parent
858e79e7d3
commit
1e68194576
|
@ -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!
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -112,6 +116,8 @@ const Variant& PopUpWidget::getSelectedTag() const
|
|||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void PopUpWidget::handleMouseDown(int x, int y, MouseButton b, int clickCount)
|
||||
{
|
||||
if(!isEditable() || x > _w - dropDownWidth(_font))
|
||||
{
|
||||
if(isEnabled() && !myMenu->isVisible())
|
||||
{
|
||||
|
@ -120,6 +126,24 @@ void PopUpWidget::handleMouseDown(int x, int y, MouseButton b, int clickCount)
|
|||
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();
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void PopUpWidget::handleMouseWheel(int x, int y, int direction)
|
||||
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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};
|
||||
|
|
Loading…
Reference in New Issue