mirror of https://github.com/stella-emu/stella.git
First pass at converting LauncherDialog to use FileListWidget, similar to BrowserDialog.
- FileListWidget is a newer development, and LauncherDialog duplicates some (but not all) of its functionality - Similarly, BrowserDialog has some functionality that LauncherDialog does not - We will implement all required functionality in FileListWidget, and have both classes use it. BrowserDialog is currently slightly broken; not all functionality is reimplemented yet.
This commit is contained in:
parent
d7e9c95fb0
commit
786f3b2a49
|
@ -18,6 +18,8 @@
|
|||
#include "ScrollBarWidget.hxx"
|
||||
#include "FileListWidget.hxx"
|
||||
|
||||
#include "Bankswitch.hxx"
|
||||
#include "MD5.hxx"
|
||||
#include "bspf.hxx"
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -25,7 +27,7 @@ FileListWidget::FileListWidget(GuiObject* boss, const GUI::Font& font,
|
|||
int x, int y, int w, int h)
|
||||
: StringListWidget(boss, font, x, y, w, h),
|
||||
_fsmode(FilesystemNode::ListMode::All),
|
||||
_extension("")
|
||||
_selectedPos(0)
|
||||
{
|
||||
// This widget is special, in that it catches signals and redirects them
|
||||
setTarget(this);
|
||||
|
@ -90,6 +92,26 @@ void FileListWidget::selectParent()
|
|||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FileListWidget::reload()
|
||||
{
|
||||
if(_node.exists())
|
||||
setLocation(_node, _gameList.name(_selectedPos));
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
const string& FileListWidget::selectedMD5()
|
||||
{
|
||||
if(_selected.isDirectory() || !Bankswitch::isValidRomName(_selected))
|
||||
return EmptyString;
|
||||
|
||||
// Make sure we have a valid md5 for this ROM
|
||||
if(_gameList.md5(_selectedPos) == "")
|
||||
_gameList.setMd5(_selectedPos, MD5::hash(_selected));
|
||||
|
||||
return _gameList.md5(_selectedPos);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FileListWidget::handleCommand(CommandSender* sender, int cmd, int data, int id)
|
||||
{
|
||||
|
@ -102,6 +124,7 @@ void FileListWidget::handleCommand(CommandSender* sender, int cmd, int data, int
|
|||
case ListWidget::kSelectionChangedCmd:
|
||||
cmd = ItemChanged;
|
||||
_selected = FilesystemNode(_gameList.path(data));
|
||||
_selectedPos = data;
|
||||
break;
|
||||
|
||||
case ListWidget::kActivatedCmd:
|
||||
|
@ -116,7 +139,6 @@ void FileListWidget::handleCommand(CommandSender* sender, int cmd, int data, int
|
|||
}
|
||||
else
|
||||
cmd = ItemActivated;
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
|
@ -35,7 +35,7 @@ class CommandSender;
|
|||
|
||||
Note that for the current implementation, the ItemActivated signal is
|
||||
not sent when activating a directory (instead the code descends into
|
||||
the directory). This may be changed in a future revision.
|
||||
the directory).
|
||||
*/
|
||||
class FileListWidget : public StringListWidget
|
||||
{
|
||||
|
@ -60,20 +60,31 @@ class FileListWidget : public StringListWidget
|
|||
/** Select parent directory (if applicable) */
|
||||
void selectParent();
|
||||
|
||||
/** Reload current location (file or directory) */
|
||||
void reload();
|
||||
|
||||
/** Gets current node(s) */
|
||||
const FilesystemNode& selected() const { return _selected; }
|
||||
const FilesystemNode& currentDir() const { return _node; }
|
||||
|
||||
protected:
|
||||
/** Gets MD5sum of the current node, if it is a file, and caches the result.
|
||||
Otherwise, does nothing.
|
||||
|
||||
@return MD5sum of selected file, else EmptyString
|
||||
*/
|
||||
const string& selectedMD5();
|
||||
|
||||
private:
|
||||
void handleCommand(CommandSender* sender, int cmd, int data, int id) override;
|
||||
|
||||
private:
|
||||
FilesystemNode::ListMode _fsmode;
|
||||
FilesystemNode _node, _selected;
|
||||
string _extension;
|
||||
|
||||
GameList _gameList;
|
||||
|
||||
string _extension;
|
||||
uInt32 _selectedPos;
|
||||
|
||||
private:
|
||||
// Following constructors and assignment operators not supported
|
||||
FileListWidget() = delete;
|
||||
|
|
|
@ -16,15 +16,14 @@
|
|||
//============================================================================
|
||||
|
||||
#include "bspf.hxx"
|
||||
#include "Bankswitch.hxx"
|
||||
#include "BrowserDialog.hxx"
|
||||
#include "ContextMenu.hxx"
|
||||
#include "DialogContainer.hxx"
|
||||
#include "Dialog.hxx"
|
||||
#include "EditTextWidget.hxx"
|
||||
#include "FileListWidget.hxx"
|
||||
#include "FSNode.hxx"
|
||||
#include "GameList.hxx"
|
||||
#include "MD5.hxx"
|
||||
#include "OptionsDialog.hxx"
|
||||
#include "GlobalPropsDialog.hxx"
|
||||
#include "StellaSettingsDialog.hxx"
|
||||
|
@ -38,12 +37,18 @@
|
|||
#include "PropsSet.hxx"
|
||||
#include "RomInfoWidget.hxx"
|
||||
#include "Settings.hxx"
|
||||
#include "StringListWidget.hxx"
|
||||
#include "Widget.hxx"
|
||||
#include "Font.hxx"
|
||||
#include "Version.hxx"
|
||||
#include "LauncherDialog.hxx"
|
||||
|
||||
/**
|
||||
TODO:
|
||||
- show all files / only ROMs
|
||||
- connect to 'matchPattern'
|
||||
- history of selected folders/files
|
||||
*/
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
LauncherDialog::LauncherDialog(OSystem& osystem, DialogContainer& parent,
|
||||
int x, int y, int w, int h)
|
||||
|
@ -142,9 +147,10 @@ LauncherDialog::LauncherDialog(OSystem& osystem, DialogContainer& parent,
|
|||
romWidth = 365;
|
||||
|
||||
int listWidth = _w - (romWidth > 0 ? romWidth+8 : 0) - 20;
|
||||
myList = new StringListWidget(this, font, xpos, ypos,
|
||||
myList = new FileListWidget(this, font, xpos, ypos,
|
||||
listWidth, _h - 43 - bheight - fontHeight - lineHeight);
|
||||
myList->setEditable(false);
|
||||
myList->setFileListMode(FilesystemNode::ListMode::All);
|
||||
wid.push_back(myList);
|
||||
|
||||
// Add ROM info area (if enabled)
|
||||
|
@ -211,10 +217,6 @@ LauncherDialog::LauncherDialog(OSystem& osystem, DialogContainer& parent,
|
|||
else
|
||||
mySelectedItem = 2;
|
||||
|
||||
// Create a game list, which contains all the information about a ROM that
|
||||
// the launcher needs
|
||||
myGameList = make_unique<GameList>();
|
||||
|
||||
addToFocusList(wid);
|
||||
|
||||
// Create context menu for ROM list options
|
||||
|
@ -236,31 +238,27 @@ LauncherDialog::LauncherDialog(OSystem& osystem, DialogContainer& parent,
|
|||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
const string& LauncherDialog::selectedRom()
|
||||
const string& LauncherDialog::selectedRom() const
|
||||
{
|
||||
int item = myList->getSelected();
|
||||
if(item < 0)
|
||||
return EmptyString;
|
||||
|
||||
return myGameList->path(item);
|
||||
return currentNode().getPath();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
const string& LauncherDialog::selectedRomMD5()
|
||||
{
|
||||
int item = myList->getSelected();
|
||||
if(item < 0)
|
||||
return EmptyString;
|
||||
return myList->selectedMD5();
|
||||
}
|
||||
|
||||
const FilesystemNode node(myGameList->path(item));
|
||||
if(node.isDirectory() || !Bankswitch::isValidRomName(node))
|
||||
return EmptyString;
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
const FilesystemNode& LauncherDialog::currentNode() const
|
||||
{
|
||||
return myList->selected();
|
||||
}
|
||||
|
||||
// Make sure we have a valid md5 for this ROM
|
||||
if(myGameList->md5(item) == "")
|
||||
myGameList->setMd5(item, MD5::hash(node));
|
||||
|
||||
return myGameList->md5(item);
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void LauncherDialog::reload()
|
||||
{
|
||||
myList->reload();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -276,26 +274,43 @@ void LauncherDialog::loadConfig()
|
|||
// has been called (and we should reload the list)
|
||||
if(myList->getList().empty())
|
||||
{
|
||||
if(myPrevDirButton)
|
||||
myPrevDirButton->setEnabled(false);
|
||||
myCurrentNode = FilesystemNode(romdir == "" ? "~" : romdir);
|
||||
if(!(myCurrentNode.exists() && myCurrentNode.isDirectory()))
|
||||
myCurrentNode = FilesystemNode("~");
|
||||
FilesystemNode node(romdir == "" ? "~" : romdir);
|
||||
if(!(node.exists() && node.isDirectory()))
|
||||
node = FilesystemNode("~");
|
||||
|
||||
updateListing();
|
||||
myList->setLocation(node);
|
||||
updateUI(instance().settings().getString("lastrom"));
|
||||
}
|
||||
Dialog::setFocus(getFocusList()[mySelectedItem]);
|
||||
|
||||
if(myRomInfoWidget)
|
||||
myRomInfoWidget->reloadProperties(currentNode());
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void LauncherDialog::updateUI(const string& nameToSelect)
|
||||
{
|
||||
int item = myList->getSelected();
|
||||
if(item < 0) return;
|
||||
const FilesystemNode node(myGameList->path(item));
|
||||
// Only hilite the 'up' button if there's a parent directory
|
||||
if(myPrevDirButton)
|
||||
myPrevDirButton->setEnabled(myList->currentDir().hasParent());
|
||||
|
||||
myRomInfoWidget->reloadProperties(node);
|
||||
}
|
||||
// Show current directory
|
||||
myDir->setText(myList->currentDir().getShortPath());
|
||||
|
||||
// Indicate how many files were found
|
||||
ostringstream buf;
|
||||
buf << (myList->getList().size() - 1) << " items found";
|
||||
myRomCount->setLabel(buf.str());
|
||||
|
||||
// Restore last selection
|
||||
if(nameToSelect != "")
|
||||
myList->setSelected(nameToSelect);
|
||||
|
||||
// Update ROM info UI item
|
||||
loadRomInfo();
|
||||
}
|
||||
|
||||
#if 0
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void LauncherDialog::updateListing(const string& nameToSelect)
|
||||
{
|
||||
|
@ -365,26 +380,22 @@ void LauncherDialog::loadDirListing()
|
|||
// Sort the list by rom name (since that's what we see in the listview)
|
||||
myGameList->sortByName();
|
||||
}
|
||||
#endif
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void LauncherDialog::loadRomInfo()
|
||||
{
|
||||
if(!myRomInfoWidget) return;
|
||||
int item = myList->getSelected();
|
||||
if(item < 0) return;
|
||||
if(!myRomInfoWidget)
|
||||
return;
|
||||
|
||||
const FilesystemNode node(myGameList->path(item));
|
||||
if(!node.isDirectory() && Bankswitch::isValidRomName(node))
|
||||
const string& md5 = selectedRomMD5();
|
||||
if(md5 != EmptyString)
|
||||
{
|
||||
// Make sure we have a valid md5 for this ROM
|
||||
if(myGameList->md5(item) == "")
|
||||
myGameList->setMd5(item, MD5::hash(node));
|
||||
|
||||
// Get the properties for this entry
|
||||
Properties props;
|
||||
instance().propSet().getMD5WithInsert(node, myGameList->md5(item), props);
|
||||
instance().propSet().getMD5WithInsert(currentNode(), md5, props);
|
||||
|
||||
myRomInfoWidget->setProperties(props, node);
|
||||
myRomInfoWidget->setProperties(props, currentNode());
|
||||
}
|
||||
else
|
||||
myRomInfoWidget->clearProperties();
|
||||
|
@ -396,13 +407,9 @@ void LauncherDialog::handleContextMenu()
|
|||
const string& cmd = myMenu->getSelectedTag().toString();
|
||||
|
||||
if(cmd == "override")
|
||||
{
|
||||
myGlobalProps->open();
|
||||
}
|
||||
else if(cmd == "reload")
|
||||
{
|
||||
updateListing();
|
||||
}
|
||||
reload();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -459,7 +466,7 @@ void LauncherDialog::handleKeyDown(StellaKey key, StellaMod mod)
|
|||
// Grab the key before passing it to the actual dialog and check for
|
||||
// Control-R (reload ROM listing)
|
||||
if(StellaModTest::isControl(mod) && key == KBDK_R)
|
||||
updateListing();
|
||||
reload();
|
||||
else
|
||||
#if defined(RETRON77)
|
||||
// handle keys used by R77
|
||||
|
@ -554,14 +561,16 @@ void LauncherDialog::handleCommand(CommandSender* sender, int cmd,
|
|||
{
|
||||
case kAllfilesCmd:
|
||||
showOnlyROMs(myAllFiles ? !myAllFiles->getState() : true);
|
||||
updateListing();
|
||||
reload();
|
||||
break;
|
||||
|
||||
case kLoadROMCmd:
|
||||
case ListWidget::kActivatedCmd:
|
||||
case ListWidget::kDoubleClickedCmd:
|
||||
case FileListWidget::ItemActivated:
|
||||
{
|
||||
startGame();
|
||||
if(currentNode().isDirectory())
|
||||
myList->setLocation(currentNode());
|
||||
else
|
||||
loadRom();
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -570,13 +579,11 @@ void LauncherDialog::handleCommand(CommandSender* sender, int cmd,
|
|||
break;
|
||||
|
||||
case kPrevDirCmd:
|
||||
case ListWidget::kPrevDirCmd:
|
||||
myCurrentNode = myCurrentNode.getParent();
|
||||
updateListing(myNodeNames.empty() ? "" : myNodeNames.pop());
|
||||
myList->selectParent();
|
||||
break;
|
||||
|
||||
case ListWidget::kSelectionChangedCmd:
|
||||
loadRomInfo();
|
||||
case FileListWidget::ItemChanged:
|
||||
updateUI();
|
||||
break;
|
||||
|
||||
case kQuitCmd:
|
||||
|
@ -585,73 +592,38 @@ void LauncherDialog::handleCommand(CommandSender* sender, int cmd,
|
|||
break;
|
||||
|
||||
case kRomDirChosenCmd:
|
||||
myCurrentNode = FilesystemNode(instance().settings().getString("romdir"));
|
||||
if(!(myCurrentNode.exists() && myCurrentNode.isDirectory()))
|
||||
myCurrentNode = FilesystemNode("~");
|
||||
updateListing();
|
||||
break;
|
||||
|
||||
case kReloadRomDirCmd:
|
||||
updateListing();
|
||||
{
|
||||
FilesystemNode node(instance().settings().getString("romdir"));
|
||||
if(!(node.exists() && node.isDirectory()))
|
||||
node = FilesystemNode("~");
|
||||
myList->setLocation(node);
|
||||
break;
|
||||
}
|
||||
|
||||
case ContextMenu::kItemSelectedCmd:
|
||||
handleContextMenu();
|
||||
break;
|
||||
|
||||
case EditableWidget::kAcceptCmd:
|
||||
case EditableWidget::kChangedCmd:
|
||||
// The updateListing() method knows what to do when the text changes
|
||||
updateListing();
|
||||
break;
|
||||
|
||||
default:
|
||||
Dialog::handleCommand(sender, cmd, data, 0);
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void LauncherDialog::startGame()
|
||||
void LauncherDialog::loadRom()
|
||||
{
|
||||
int item = myList->getSelected();
|
||||
if(item >= 0)
|
||||
{
|
||||
const FilesystemNode romnode(myGameList->path(item));
|
||||
|
||||
// Directory's should be selected (ie, enter them and redisplay)
|
||||
if(romnode.isDirectory())
|
||||
{
|
||||
string dirname = "";
|
||||
if(myGameList->name(item) == " [..]")
|
||||
{
|
||||
myCurrentNode = myCurrentNode.getParent();
|
||||
if(!myNodeNames.empty())
|
||||
dirname = myNodeNames.pop();
|
||||
}
|
||||
else
|
||||
{
|
||||
myCurrentNode = romnode;
|
||||
myNodeNames.push(myGameList->name(item));
|
||||
}
|
||||
updateListing(dirname);
|
||||
}
|
||||
else
|
||||
{
|
||||
const string& result =
|
||||
instance().createConsole(romnode, myGameList->md5(item));
|
||||
const string& result = instance().createConsole(currentNode(), myList->selectedMD5());
|
||||
if(result == EmptyString)
|
||||
{
|
||||
instance().settings().setValue("lastrom", myList->getSelectedString());
|
||||
|
||||
// If romdir has never been set, set it now based on the selected rom
|
||||
if(instance().settings().getString("romdir") == EmptyString)
|
||||
instance().settings().setValue("romdir", romnode.getParent().getShortPath());
|
||||
instance().settings().setValue("romdir", currentNode().getParent().getShortPath());
|
||||
}
|
||||
else
|
||||
instance().frameBuffer().showMessage(result, MessagePosition::MiddleCenter, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void LauncherDialog::openSettings()
|
||||
|
|
|
@ -22,7 +22,6 @@ class ButtonWidget;
|
|||
class CommandSender;
|
||||
class ContextMenu;
|
||||
class DialogContainer;
|
||||
class GameList;
|
||||
class BrowserDialog;
|
||||
class OptionsDialog;
|
||||
class GlobalPropsDialog;
|
||||
|
@ -30,9 +29,9 @@ class StellaSettingsDialog;
|
|||
class OSystem;
|
||||
class Properties;
|
||||
class EditTextWidget;
|
||||
class FileListWidget;
|
||||
class RomInfoWidget;
|
||||
class StaticTextWidget;
|
||||
class StringListWidget;
|
||||
namespace GUI {
|
||||
class MessageBox;
|
||||
}
|
||||
|
@ -49,8 +48,7 @@ class LauncherDialog : public Dialog
|
|||
enum {
|
||||
kAllfilesCmd = 'lalf', // show all files (or ROMs only)
|
||||
kLoadROMCmd = 'STRT', // load currently selected ROM
|
||||
kRomDirChosenCmd = 'romc', // rom dir chosen
|
||||
kReloadRomDirCmd = 'rdrl', // reload the current listing
|
||||
kRomDirChosenCmd = 'romc' // rom dir chosen
|
||||
};
|
||||
|
||||
public:
|
||||
|
@ -59,30 +57,32 @@ class LauncherDialog : public Dialog
|
|||
virtual ~LauncherDialog() = default;
|
||||
|
||||
/**
|
||||
Get path for the currently selected file
|
||||
Get path for the currently selected file.
|
||||
|
||||
@return path if a valid ROM file, else the empty string
|
||||
*/
|
||||
const string& selectedRom();
|
||||
const string& selectedRom() const;
|
||||
|
||||
/**
|
||||
Get MD5sum for the currently selected file
|
||||
Get MD5sum for the currently selected file.
|
||||
If the MD5 hasn't already been calculated, it will be
|
||||
calculated (and cached) for future use.
|
||||
|
||||
@return md5sum if a valid ROM file, else the empty string
|
||||
*/
|
||||
const string& selectedRomMD5();
|
||||
|
||||
/**
|
||||
Get node for the currently selected directory
|
||||
Get node for the currently selected directory.
|
||||
|
||||
@return FilesystemNode currently active
|
||||
*/
|
||||
const FilesystemNode& currentNode() const { return myCurrentNode; }
|
||||
const FilesystemNode& currentNode() const;
|
||||
|
||||
/**
|
||||
Reload the current listing
|
||||
*/
|
||||
void reload() { updateListing(); }
|
||||
void reload();
|
||||
|
||||
private:
|
||||
void center() override { positionAt(0); }
|
||||
|
@ -93,20 +93,18 @@ class LauncherDialog : public Dialog
|
|||
Event::Type getJoyAxisEvent(int stick, int axis, int value) override;
|
||||
|
||||
void loadConfig() override;
|
||||
void updateListing(const string& nameToSelect = "");
|
||||
void updateUI(const string& nameToSelect = "");
|
||||
|
||||
void loadDirListing();
|
||||
void loadRom();
|
||||
void loadRomInfo();
|
||||
void handleContextMenu();
|
||||
void showOnlyROMs(bool state);
|
||||
bool matchPattern(const string& s, const string& pattern) const;
|
||||
void startGame();
|
||||
void openSettings();
|
||||
|
||||
private:
|
||||
unique_ptr<OptionsDialog> myOptionsDialog;
|
||||
unique_ptr<StellaSettingsDialog> myStellaSettingsDialog;
|
||||
unique_ptr<GameList> myGameList;
|
||||
unique_ptr<ContextMenu> myMenu;
|
||||
unique_ptr<GlobalPropsDialog> myGlobalProps;
|
||||
unique_ptr<BrowserDialog> myRomDir;
|
||||
|
@ -116,7 +114,7 @@ class LauncherDialog : public Dialog
|
|||
ButtonWidget* myOptionsButton;
|
||||
ButtonWidget* myQuitButton;
|
||||
|
||||
StringListWidget* myList;
|
||||
FileListWidget* myList;
|
||||
StaticTextWidget* myDirLabel;
|
||||
EditTextWidget* myDir;
|
||||
StaticTextWidget* myRomCount;
|
||||
|
@ -126,8 +124,6 @@ class LauncherDialog : public Dialog
|
|||
RomInfoWidget* myRomInfoWidget;
|
||||
|
||||
int mySelectedItem;
|
||||
FilesystemNode myCurrentNode;
|
||||
Common::FixedStack<string> myNodeNames;
|
||||
|
||||
bool myShowOnlyROMs;
|
||||
bool myUseMinimalUI;
|
||||
|
|
Loading…
Reference in New Issue