diff --git a/docs/graphics/options_gameinfo_cartridge.png b/docs/graphics/options_gameinfo_cartridge.png index da6f4fdc4..772f1334b 100644 Binary files a/docs/graphics/options_gameinfo_cartridge.png and b/docs/graphics/options_gameinfo_cartridge.png differ diff --git a/docs/graphics/options_gameinfo_console.png b/docs/graphics/options_gameinfo_console.png index 83d4b04b1..f7233672b 100644 Binary files a/docs/graphics/options_gameinfo_console.png and b/docs/graphics/options_gameinfo_console.png differ diff --git a/docs/graphics/options_gameinfo_controller.png b/docs/graphics/options_gameinfo_controller.png index 6b8740424..63b5548a3 100644 Binary files a/docs/graphics/options_gameinfo_controller.png and b/docs/graphics/options_gameinfo_controller.png differ diff --git a/docs/graphics/options_gameinfo_emulation.png b/docs/graphics/options_gameinfo_emulation.png index 8da3b8c42..b67ca95f7 100644 Binary files a/docs/graphics/options_gameinfo_emulation.png and b/docs/graphics/options_gameinfo_emulation.png differ diff --git a/docs/graphics/options_gameinfo_highscores.png b/docs/graphics/options_gameinfo_highscores.png index 9a6e7f1d2..572aa252b 100644 Binary files a/docs/graphics/options_gameinfo_highscores.png and b/docs/graphics/options_gameinfo_highscores.png differ diff --git a/docs/index.html b/docs/index.html index d6cfdb001..359a8bfed 100644 --- a/docs/index.html +++ b/docs/index.html @@ -3930,7 +3930,7 @@ Allow all 4 directions ...Allow all 4 joystick directions to be pressed simultaneously-joyallow4 Use modifier key combosEnable using modifier keys in keyboard actions-modcombo Swap Stelladaptor portsSwap the order of the detected Stelladaptors/2600-daptors (see Advanced Configuration - Stelladaptor/2600-daptor Support)-saport - Joystick databaseShow all joysticks that Stella knows about, with the option to remove them  + Joystick DatabaseShow all joysticks that Stella knows about, with the option to remove them  Erase EEPROMErase the whole AtariVox/SaveKey flash memory  AtariVox serial portDescribed in further detail in Advanced Configuration - AtariVox/SaveKey Support -avoxport diff --git a/src/debugger/gui/DataGridOpsWidget.cxx b/src/debugger/gui/DataGridOpsWidget.cxx index 2a62ec60c..e4bf5d247 100644 --- a/src/debugger/gui/DataGridOpsWidget.cxx +++ b/src/debugger/gui/DataGridOpsWidget.cxx @@ -34,7 +34,7 @@ DataGridOpsWidget::DataGridOpsWidget(GuiObject* boss, const GUI::Font& font, _zeroButton = new ButtonWidget(boss, font, xpos, ypos, bwidth, bheight, "0", kDGZeroCmd); _zeroButton->setToolTip("Zero currently selected value"); - + ypos += bheight + space; _invButton = new ButtonWidget(boss, font, xpos, ypos, bwidth, bheight, "Inv", kDGInvertCmd); diff --git a/src/debugger/gui/DebuggerDialog.cxx b/src/debugger/gui/DebuggerDialog.cxx index 87481234c..8abf382d4 100644 --- a/src/debugger/gui/DebuggerDialog.cxx +++ b/src/debugger/gui/DebuggerDialog.cxx @@ -489,6 +489,8 @@ void DebuggerDialog::createBrowser(const string& title) { uInt32 w = 0, h = 0; getDynamicBounds(w, h); + if(w > uInt32(_font.getMaxCharWidth() * 80)) + w = _font.getMaxCharWidth() * 80; // Create file browser dialog if(!myBrowser || uInt32(myBrowser->getWidth()) != w || diff --git a/src/emucore/FSNode.cxx b/src/emucore/FSNode.cxx index d9de7e0a5..212828379 100644 --- a/src/emucore/FSNode.cxx +++ b/src/emucore/FSNode.cxx @@ -59,7 +59,6 @@ FilesystemNode& FilesystemNode::operator/=(const string& path) } return *this; -#undef PATH_SEPARATOR } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/gui/BrowserDialog.cxx b/src/gui/BrowserDialog.cxx index 25b35aee1..3b1ee48a7 100644 --- a/src/gui/BrowserDialog.cxx +++ b/src/gui/BrowserDialog.cxx @@ -81,14 +81,19 @@ BrowserDialog::BrowserDialog(GuiObject* boss, const GUI::Font& font, buttonWidth, buttonHeight, "Go up", kGoUpCmd); addFocusWidget(_goUpButton); - _basedirButton = - new ButtonWidget(this, font, _goUpButton->getRight() + BUTTON_GAP, _h - buttonHeight - VBORDER, - buttonWidth, buttonHeight, "Base Dir", kBaseDirCmd); - addFocusWidget(_basedirButton); + b = new ButtonWidget(this, font, _goUpButton->getRight() + BUTTON_GAP, _h - buttonHeight - VBORDER, + buttonWidth, buttonHeight, "Base Dir", kBaseDirCmd); + b->setToolTip("Go to Stella's base directory."); + addFocusWidget(b); + + b = new ButtonWidget(this, font, b->getRight() + BUTTON_GAP, _h - buttonHeight - VBORDER, + buttonWidth, buttonHeight, "Home Dir", kHomeDirCmd); + b->setToolTip("Go to user's home directory."); + addFocusWidget(b); #ifndef BSPF_MACOS b = new ButtonWidget(this, font, _w - (2 * buttonWidth + BUTTON_GAP + HBORDER), _h - buttonHeight - VBORDER, - buttonWidth, buttonHeight, "Choose", kChooseCmd); + buttonWidth, buttonHeight, "OK", kChooseCmd); addFocusWidget(b); addOKWidget(b); b = new ButtonWidget(this, font, _w - (buttonWidth + HBORDER), _h - buttonHeight - VBORDER, @@ -101,7 +106,7 @@ BrowserDialog::BrowserDialog(GuiObject* boss, const GUI::Font& font, addFocusWidget(b); addCancelWidget(b); b = new ButtonWidget(this, font, _w - (buttonWidth + HBORDER), _h - buttonHeight - VBORDER, - buttonWidth, buttonHeight, "Choose", kChooseCmd); + buttonWidth, buttonHeight, "OK", kChooseCmd); addFocusWidget(b); addOKWidget(b); #endif @@ -115,7 +120,9 @@ void BrowserDialog::show(const string& startpath, _mode = mode; _cmd = cmd; _cancelCmd = cancelCmd; - string fileName; + string directory;// = EmptyString; + string fileName;// = EmptyString; + bool fileSelected = true; // Set start path if(_mode != Directories) @@ -123,13 +130,7 @@ void BrowserDialog::show(const string& startpath, // split startpath into path and filename FilesystemNode fs = FilesystemNode(startpath); fileName = fs.getName(); - string directory = fs.isDirectory() ? "" : fs.getParent().getPath(); - - _fileList->setDirectory(FilesystemNode(directory), fileName); - } - else - { - _fileList->setDirectory(FilesystemNode(startpath)); + directory = fs.isDirectory() ? "" : fs.getParent().getPath(); } switch(_mode) @@ -144,7 +145,6 @@ void BrowserDialog::show(const string& startpath, _selected->clearFlags(Widget::FLAG_INVISIBLE); _type->clearFlags(Widget::FLAG_INVISIBLE); _okWidget->setLabel("Load"); - updateUI(true); break; case FileSave: @@ -158,7 +158,7 @@ void BrowserDialog::show(const string& startpath, _type->clearFlags(Widget::FLAG_INVISIBLE); _okWidget->setLabel("Save"); _selected->setText(fileName); - updateUI(false); + fileSelected = false; break; case Directories: @@ -168,11 +168,17 @@ void BrowserDialog::show(const string& startpath, _selected->setEnabled(false); _selected->setFlags(Widget::FLAG_INVISIBLE); _type->setFlags(Widget::FLAG_INVISIBLE); - _okWidget->setLabel("Choose"); - updateUI(true); + _okWidget->setLabel("OK"); break; } + // Set start path + if(_mode != Directories) + _fileList->setDirectory(FilesystemNode(directory), fileName); + else + _fileList->setDirectory(FilesystemNode(startpath)); + updateUI(fileSelected); + // Finally, open the dialog after it has been fully updated open(); } @@ -182,76 +188,15 @@ const FilesystemNode& BrowserDialog::getResult() const { if(_mode == FileLoad || _mode == FileSave) { - static FilesystemNode node(_fileList->currentDir().getShortPath() + _selected->getText()); + static FilesystemNode node; - return node; + return node + = FilesystemNode(_fileList->currentDir().getShortPath() + _selected->getText()); } else return _fileList->currentDir(); } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void BrowserDialog::updateUI(bool fileSelected) -{ - // Only hilite the 'up' button if there's a parent directory - _goUpButton->setEnabled(_fileList->currentDir().hasParent()); - - // Update the path display - _currentPath->setText(_fileList->currentDir().getShortPath()); - - // Enable/disable OK button based on current mode - //bool enable = true; - //switch(_mode) - //{ - // case Directories: - // enable = true; - // break; - - // case FileLoad: - // if(_fileList->selected().isDirectory()) - // { - // enable = false; - // _selected->setText(""); - // } - // else - // { - // enable = fileSelected && !_selected->getText().empty(); - // _selected->setText(_fileList->getSelectedString()); - // } - // break; - - // case FileSave: - // if(_fileList->selected().isDirectory()) - // { - // enable = false; - // _selected->setText(""); - // } - // else - // { - // enable = fileSelected && !_selected->getText().empty(); // TODO - // _selected->setText(_fileList->getSelectedString()); - // } - // break; - - // default: - // break; - //} - //_okWidget->setEnabled(enable); - - bool enable = _mode == Directories - || (!_fileList->selected().isDirectory() && fileSelected) - || (!_selected->getText().empty() && !fileSelected); - _okWidget->setEnabled(enable); - - if(fileSelected) - { - if(!_fileList->selected().isDirectory()) - _selected->setText(_fileList->getSelectedString()); - else - _selected->setText(""); - } -} - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void BrowserDialog::handleCommand(CommandSender* sender, int cmd, int data, int id) @@ -281,6 +226,10 @@ void BrowserDialog::handleCommand(CommandSender* sender, int cmd, _fileList->setDirectory(FilesystemNode(instance().baseDir())); break; + case kHomeDirCmd: + _fileList->setDirectory(FilesystemNode(instance().defaultSaveDir())); + break; + case EditableWidget::kChangedCmd: Dialog::handleCommand(sender, cmd, data, 0); updateUI(false); @@ -295,3 +244,23 @@ void BrowserDialog::handleCommand(CommandSender* sender, int cmd, break; } } + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void BrowserDialog::updateUI(bool fileSelected) +{ + // Only hilite the 'up' button if there's a parent directory + _goUpButton->setEnabled(_fileList->currentDir().hasParent()); + + // Update the path display + _currentPath->setText(_fileList->currentDir().getShortPath()); + + // Enable/disable OK button based on current mode and status + bool enable = true; + + if(_mode != Directories) + enable = !_selected->getText().empty(); + _okWidget->setEnabled(enable); + + if(fileSelected && !_fileList->selected().isDirectory()) + _selected->setText(_fileList->getSelectedString()); +} diff --git a/src/gui/BrowserDialog.hxx b/src/gui/BrowserDialog.hxx index 9ee401ad6..1038398c0 100644 --- a/src/gui/BrowserDialog.hxx +++ b/src/gui/BrowserDialog.hxx @@ -58,7 +58,8 @@ class BrowserDialog : public Dialog, public CommandSender enum { kChooseCmd = 'CHOS', kGoUpCmd = 'GOUP', - kBaseDirCmd = 'BADR' + kBaseDirCmd = 'BADR', + kHomeDirCmd = 'HODR' }; int _cmd{0}; @@ -69,7 +70,6 @@ class BrowserDialog : public Dialog, public CommandSender StaticTextWidget* _type{nullptr}; EditTextWidget* _selected{nullptr}; ButtonWidget* _goUpButton{nullptr}; - ButtonWidget* _basedirButton{nullptr}; BrowserDialog::ListMode _mode{Directories}; diff --git a/src/gui/GameInfoDialog.cxx b/src/gui/GameInfoDialog.cxx index 3700caf5f..fc2c08c47 100644 --- a/src/gui/GameInfoDialog.cxx +++ b/src/gui/GameInfoDialog.cxx @@ -29,6 +29,7 @@ #include "Paddles.hxx" #include "PopUpWidget.hxx" #include "PropsSet.hxx" +#include "BrowserDialog.hxx" #include "QuadTariDialog.hxx" #include "TabWidget.hxx" #include "TIAConstants.hxx" @@ -92,7 +93,7 @@ GameInfoDialog::GameInfoDialog( myTab->setActiveTab(0); // Add Defaults, OK and Cancel buttons - addDefaultsExtraOKCancelBGroup(wid, font, "Export", kExportPressed); + addDefaultsExtraOKCancelBGroup(wid, font, "Export" + ELLIPSIS, kExportPressed); _extraWidget->setToolTip("Export the current ROM's properties\n" "into the default directory."); addBGroupToFocusList(wid); @@ -660,12 +661,27 @@ void GameInfoDialog::addHighScoresTab() addToFocusList(wid, myTab, tabID); } - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - GameInfoDialog::~GameInfoDialog() { } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void GameInfoDialog::createBrowser(const string& title) +{ + uInt32 w = 0, h = 0; + getDynamicBounds(w, h); + if(w > uInt32(_font.getMaxCharWidth() * 80)) + w = _font.getMaxCharWidth() * 80; + + // Create file browser dialog + if(!myBrowser || uInt32(myBrowser->getWidth()) != w || + uInt32(myBrowser->getHeight()) != h) + myBrowser = make_unique(this, _font, w, h, title); + else + myBrowser->setTitle(title); +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void GameInfoDialog::loadConfig() { @@ -1350,16 +1366,14 @@ void GameInfoDialog::exportCurrentPropertiesToDisk() try { - FilesystemNode propfile = instance().defaultSaveDir(); - propfile /= myGameFile.getNameWithExt(".pro"); + FilesystemNode propfile(myBrowser->getResult().getShortPath()); propfile.write(out); - instance().frameBuffer().showTextMessage("Properties exported to " + - propfile.getShortPath()); + instance().frameBuffer().showTextMessage("ROM properties exported"); } catch(...) { - instance().frameBuffer().showTextMessage("Error exporting properties"); + instance().frameBuffer().showTextMessage("Error exporting ROM properties"); } } @@ -1379,6 +1393,15 @@ void GameInfoDialog::handleCommand(CommandSender* sender, int cmd, break; case kExportPressed: + // This dialog is resizable under certain conditions, so we need + // to re-create it as necessary + createBrowser("Export properties as"); + + myBrowser->show(instance().defaultSaveDir().getPath() + myGameFile.getNameWithExt(".pro"), + BrowserDialog::FileSave, kExportChosen); + break; + + case kExportChosen: exportCurrentPropertiesToDisk(); break; diff --git a/src/gui/GameInfoDialog.hxx b/src/gui/GameInfoDialog.hxx index c217bd689..d3af6775e 100644 --- a/src/gui/GameInfoDialog.hxx +++ b/src/gui/GameInfoDialog.hxx @@ -27,6 +27,7 @@ class RadioButtonGroup; class TabWidget; class SliderWidget; class QuadTariDialog; +class BrowserDialog; #include "Dialog.hxx" #include "Command.hxx" @@ -78,6 +79,7 @@ class GameInfoDialog : public Dialog, public CommandSender void setAddressVal(EditTextWidget* address, EditTextWidget* val, bool isBCD = true, bool zeroBased = false, uInt8 maxVal = 255); void exportCurrentPropertiesToDisk(); + void createBrowser(const string& title); private: TabWidget* myTab{nullptr}; @@ -168,6 +170,8 @@ class GameInfoDialog : public Dialog, public CommandSender StaticTextWidget* myHighScoreNotesLabel{nullptr}; EditTextWidget* myHighScoreNotes{nullptr}; + unique_ptr myBrowser; + enum { kVCenterChanged = 'Vcch', kPhosphorChanged = 'PPch', @@ -180,7 +184,8 @@ class GameInfoDialog : public Dialog, public CommandSender kHiScoresChanged = 'HSch', kPXCenterChanged = 'Pxch', kPYCenterChanged = 'Pych', - kExportPressed = 'GIsp' + kExportPressed = 'Expr', + kExportChosen = 'Exch' }; // Game properties for currently loaded ROM diff --git a/src/gui/RomAuditDialog.cxx b/src/gui/RomAuditDialog.cxx index 65b4d0c33..60b627f8d 100644 --- a/src/gui/RomAuditDialog.cxx +++ b/src/gui/RomAuditDialog.cxx @@ -223,6 +223,8 @@ void RomAuditDialog::createBrowser(const string& title) { uInt32 w = 0, h = 0; getDynamicBounds(w, h); + if(w > uInt32(_font.getMaxCharWidth() * 80)) + w = _font.getMaxCharWidth() * 80; // Create file browser dialog if(!myBrowser || uInt32(myBrowser->getWidth()) != w || diff --git a/src/gui/SnapshotDialog.cxx b/src/gui/SnapshotDialog.cxx index 80af8ec1d..c983c1d5b 100644 --- a/src/gui/SnapshotDialog.cxx +++ b/src/gui/SnapshotDialog.cxx @@ -183,6 +183,8 @@ void SnapshotDialog::createBrowser(const string& title) { uInt32 w = 0, h = 0; getDynamicBounds(w, h); + if(w > uInt32(_font.getMaxCharWidth() * 80)) + w = _font.getMaxCharWidth() * 80; // Create file browser dialog if(!myBrowser || uInt32(myBrowser->getWidth()) != w || diff --git a/src/gui/UIDialog.cxx b/src/gui/UIDialog.cxx index beb6f576d..6ba10d9f8 100644 --- a/src/gui/UIDialog.cxx +++ b/src/gui/UIDialog.cxx @@ -706,6 +706,8 @@ void UIDialog::createBrowser(const string& title) { uInt32 w = 0, h = 0; getDynamicBounds(w, h); + if(w > uInt32(_font.getMaxCharWidth() * 80)) + w = _font.getMaxCharWidth() * 80; // Create file browser dialog if(!myBrowser || uInt32(myBrowser->getWidth()) != w ||