From adc6354943780d9e0cba51b0540f78321cffe46a Mon Sep 17 00:00:00 2001 From: stephena Date: Wed, 4 Jan 2006 01:24:17 +0000 Subject: [PATCH] Added more complete support for in-GUI navigation with a joystick for those dialogs that don't emulate the mouse (currently the Launcher and Command dialogs). Moving a joystick axis in such dialogs now repeats the event until the axis is released (similar to key repeat). Also, the number of events is based on how long the axis is held. So the longer the axis is pressed, the faster events will be generated. The LauncherDialog now handles its own joystick axis events, which are described as follows: - Axis up/down (on any stick) move up and down through the game list. - Axis left/right moves between the 4 buttons on the bottom (play, options, reload, quit). - The buttons are now highlighted to indicate that they're focusable. So the cursor keys can also be used to move between them. Still TODO is deal with analog joystick axis events. The analog nature of these types of joysticks should really be ignored by the GUI. git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@935 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba --- stella/src/emucore/EventHandler.cxx | 4 +- stella/src/emucore/EventStreamer.cxx | 23 +++++--- stella/src/emucore/EventStreamer.hxx | 9 ++- stella/src/gui/CommandDialog.cxx | 47 +++------------ stella/src/gui/CommandDialog.hxx | 26 ++++++++- stella/src/gui/DialogContainer.cxx | 62 +++++++++++++++++--- stella/src/gui/DialogContainer.hxx | 23 ++++++-- stella/src/gui/GuiObject.hxx | 15 ++++- stella/src/gui/LauncherDialog.cxx | 86 ++++++++++++++++++++++++++-- stella/src/gui/LauncherDialog.hxx | 22 +++++-- stella/src/gui/ListWidget.cxx | 14 ++--- stella/src/gui/ListWidget.hxx | 4 +- stella/src/gui/StringListWidget.cxx | 4 +- stella/src/gui/Widget.hxx | 10 ++-- 14 files changed, 258 insertions(+), 91 deletions(-) diff --git a/stella/src/emucore/EventHandler.cxx b/stella/src/emucore/EventHandler.cxx index 870d11cc7..53e53f898 100644 --- a/stella/src/emucore/EventHandler.cxx +++ b/stella/src/emucore/EventHandler.cxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: EventHandler.cxx,v 1.138 2005-12-29 21:16:26 stephena Exp $ +// $Id: EventHandler.cxx,v 1.139 2006-01-04 01:24:17 stephena Exp $ //============================================================================ #include @@ -175,6 +175,8 @@ void EventHandler::reset(State state) setPaddleSpeed(1, myOSystem->settings().getInt("p2speed")); setPaddleSpeed(2, myOSystem->settings().getInt("p3speed")); setPaddleSpeed(3, myOSystem->settings().getInt("p4speed")); + + myEventStreamer->reset(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/stella/src/emucore/EventStreamer.cxx b/stella/src/emucore/EventStreamer.cxx index 23b2b4881..d354b5a11 100644 --- a/stella/src/emucore/EventStreamer.cxx +++ b/stella/src/emucore/EventStreamer.cxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: EventStreamer.cxx,v 1.3 2005-12-29 21:16:28 stephena Exp $ +// $Id: EventStreamer.cxx,v 1.4 2006-01-04 01:24:17 stephena Exp $ //============================================================================ #include "bspf.hxx" @@ -44,6 +44,16 @@ EventStreamer::~EventStreamer() myStreamWriter.close(); } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void EventStreamer::reset() +{ +cerr << "EventStreamer::reset()\n"; + myEventWriteFlag = false; + myEventReadFlag = false; + myFrameCounter = -1; + myEventPos = 0; +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool EventStreamer::startRecording() { @@ -57,10 +67,8 @@ bool EventStreamer::startRecording() return false; myEventHistory.clear(); - myEventWriteFlag = true; - myEventReadFlag = false; - - return myEventWriteFlag; + reset(); + return myEventWriteFlag = true; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -97,6 +105,7 @@ bool EventStreamer::stopRecording() // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool EventStreamer::loadRecording() { +cerr << "EventStreamer::loadRecording()\n"; string eventfile = /*myOSystem->baseDir() + BSPF_PATH_SEPARATOR +*/ "test.inp"; if(!myStreamReader.open(eventfile)) return false; @@ -128,10 +137,8 @@ bool EventStreamer::loadRecording() return false; } - myEventWriteFlag = false; + reset(); myEventReadFlag = myEventHistory.size() > 0; - myFrameCounter = -1; - myEventPos = 0; return true; } diff --git a/stella/src/emucore/EventStreamer.hxx b/stella/src/emucore/EventStreamer.hxx index 6fd9c6c1c..365fcb84e 100644 --- a/stella/src/emucore/EventStreamer.hxx +++ b/stella/src/emucore/EventStreamer.hxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: EventStreamer.hxx,v 1.2 2005-12-29 01:25:07 stephena Exp $ +// $Id: EventStreamer.hxx,v 1.3 2006-01-04 01:24:17 stephena Exp $ //============================================================================ #ifndef EVENTSTREAMER_HXX @@ -48,7 +48,7 @@ class OSystem; the correct order at the correct time. @author Stephen Anthony - @version $Id: EventStreamer.hxx,v 1.2 2005-12-29 01:25:07 stephena Exp $ + @version $Id: EventStreamer.hxx,v 1.3 2006-01-04 01:24:17 stephena Exp $ */ class EventStreamer { @@ -99,6 +99,11 @@ class EventStreamer */ void nextFrame(); + /** + Reset to base state (not saving or loading an eventstream) + */ + void reset(); + private: private: diff --git a/stella/src/gui/CommandDialog.cxx b/stella/src/gui/CommandDialog.cxx index 919d6e2d5..cc9833178 100644 --- a/stella/src/gui/CommandDialog.cxx +++ b/stella/src/gui/CommandDialog.cxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: CommandDialog.cxx,v 1.5 2005-12-19 02:19:49 stephena Exp $ +// $Id: CommandDialog.cxx,v 1.6 2006-01-04 01:24:17 stephena Exp $ // // Based on code from ScummVM - Scumm Interpreter // Copyright (C) 2002-2004 The ScummVM project @@ -26,35 +26,6 @@ #include "CommandDialog.hxx" #include "EventHandler.hxx" -enum { - kSelectCmd = 'Csel', - kResetCmd = 'Cres', - kColorCmd = 'Ccol', - kBWCmd = 'Cbwt', - kLeftDiffACmd = 'Clda', - kLeftDiffBCmd = 'Cldb', - kRightDiffACmd = 'Crda', - kRightDiffBCmd = 'Crdb', - kSaveStateCmd = 'Csst', - kStateSlotCmd = 'Ccst', - kLoadStateCmd = 'Clst', - kSnapshotCmd = 'Csnp', - kFormatCmd = 'Cfmt', - kPaletteCmd = 'Cpal', - kReloadRomCmd = 'Crom', - kExitCmd = 'Clex' -}; - -enum { - kUpArrow = 256+17, - kDownArrow = 256+18, - kLeftArrow = 256+20, - kRightArrow = 256+19, - - kNumRows = 4, - kNumCols = 4 -}; - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CommandDialog::CommandDialog(OSystem* osystem, DialogContainer* parent) : Dialog(osystem, parent, 0, 0, 16, 16), @@ -180,7 +151,7 @@ void CommandDialog::handleKeyDown(int ascii, int keycode, int modifiers) // Only detect the cursor keys, otherwise pass to base class switch(ascii) { - case kUpArrow: + case kCursorUp: if (row > 0) --row; else if(col > 0) @@ -190,7 +161,7 @@ void CommandDialog::handleKeyDown(int ascii, int keycode, int modifiers) } break; - case kDownArrow: + case kCursorDown: if (row < kNumRows - 1) ++row; else if(col < kNumCols - 1) @@ -200,7 +171,7 @@ void CommandDialog::handleKeyDown(int ascii, int keycode, int modifiers) } break; - case kLeftArrow: + case kCursorLeft: if (col > 0) --col; else if(row > 0) @@ -210,7 +181,7 @@ void CommandDialog::handleKeyDown(int ascii, int keycode, int modifiers) } break; - case kRightArrow: + case kCursorRight: if (col < kNumCols - 1) ++col; else if(row < kNumRows - 1) @@ -245,16 +216,16 @@ void CommandDialog::handleJoyAxis(int stick, int axis, int value) if(axis % 2 == 0) // x-direction { if(value < 0) - key = kLeftArrow; + key = kCursorLeft; else if(value > 0) - key = kRightArrow; + key = kCursorRight; } else // y-direction { if(value < 0) - key = kUpArrow; + key = kCursorUp; else if(value > 0) - key = kDownArrow; + key = kCursorDown; } if(key != -1) diff --git a/stella/src/gui/CommandDialog.hxx b/stella/src/gui/CommandDialog.hxx index 783d213dd..b13bbb709 100644 --- a/stella/src/gui/CommandDialog.hxx +++ b/stella/src/gui/CommandDialog.hxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: CommandDialog.hxx,v 1.3 2005-12-24 22:09:36 stephena Exp $ +// $Id: CommandDialog.hxx,v 1.4 2006-01-04 01:24:17 stephena Exp $ // // Based on code from ScummVM - Scumm Interpreter // Copyright (C) 2002-2004 The ScummVM project @@ -44,6 +44,30 @@ class CommandDialog : public Dialog private: int mySelectedItem; + + enum { + kSelectCmd = 'Csel', + kResetCmd = 'Cres', + kColorCmd = 'Ccol', + kBWCmd = 'Cbwt', + kLeftDiffACmd = 'Clda', + kLeftDiffBCmd = 'Cldb', + kRightDiffACmd = 'Crda', + kRightDiffBCmd = 'Crdb', + kSaveStateCmd = 'Csst', + kStateSlotCmd = 'Ccst', + kLoadStateCmd = 'Clst', + kSnapshotCmd = 'Csnp', + kFormatCmd = 'Cfmt', + kPaletteCmd = 'Cpal', + kReloadRomCmd = 'Crom', + kExitCmd = 'Clex' + }; + + enum { + kNumRows = 4, + kNumCols = 4 + }; }; #endif diff --git a/stella/src/gui/DialogContainer.cxx b/stella/src/gui/DialogContainer.cxx index d9892db46..522b2dd13 100644 --- a/stella/src/gui/DialogContainer.cxx +++ b/stella/src/gui/DialogContainer.cxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: DialogContainer.cxx,v 1.22 2005-12-24 22:50:53 stephena Exp $ +// $Id: DialogContainer.cxx,v 1.23 2006-01-04 01:24:17 stephena Exp $ //============================================================================ #include "OSystem.hxx" @@ -72,6 +72,31 @@ void DialogContainer::updateTime(uInt32 time) myClickRepeatTime = myTime + kClickRepeatSustainDelay; } + if(myCurrentAxisDown.stick != -1 && myAxisRepeatTime < myTime) + { + // The longer an axis event is enabled, the faster it should change + // We do this by decreasing the amount of time between consecutive axis events + // After a certain threshold, send 10 events at a time (this is necessary + // since at some point, we'd like to process more eventss than the + // current framerate allows) + myCurrentAxisDown.count++; + int interval = myCurrentAxisDown.count / 40 + 1; + myAxisRepeatTime = myTime + kAxisRepeatSustainDelay / interval; + if(interval > 3) + { + for(int i = 0; i < 10; ++i) + activeDialog->handleJoyAxis(myCurrentAxisDown.stick, myCurrentAxisDown.axis, + myCurrentAxisDown.value); + myAxisRepeatTime = myTime + kAxisRepeatSustainDelay / 3; + } + else + { + activeDialog->handleJoyAxis(myCurrentAxisDown.stick, myCurrentAxisDown.axis, + myCurrentAxisDown.value); + myAxisRepeatTime = myTime + kAxisRepeatSustainDelay / interval; + } + } + // Update joy to mouse events handleJoyMouse(time); } @@ -270,17 +295,33 @@ void DialogContainer::handleJoyAxisEvent(int stick, int axis, int value) // Send the event to the dialog box on the top of the stack Dialog* activeDialog = myDialogStack.top(); + if(value > JOY_DEADZONE) + value -= JOY_DEADZONE; + else if(value < -JOY_DEADZONE ) + value += JOY_DEADZONE; + else + value = 0; + if(activeDialog->wantsEvents()) + { + // Only stop firing events if it's the current key + if(myCurrentAxisDown.stick == stick && value == 0) + { + myCurrentAxisDown.stick = myCurrentAxisDown.axis = -1; + myCurrentAxisDown.count = 0; + } + else + { + // Now account for repeated axis events (press and hold) + myCurrentAxisDown.stick = stick; + myCurrentAxisDown.axis = axis; + myCurrentAxisDown.value = value; + myAxisRepeatTime = myTime + kAxisRepeatInitialDelay; + } activeDialog->handleJoyAxis(stick, axis, value); + } else { - if(value > JOY_DEADZONE) - value -= JOY_DEADZONE; - else if(value < -JOY_DEADZONE ) - value += JOY_DEADZONE; - else - value = 0; - if(axis % 2 == 0) // x-direction { if(value != 0) @@ -309,6 +350,8 @@ void DialogContainer::handleJoyAxisEvent(int stick, int axis, int value) ourJoyMouse.y_down_count = 0; } } + myCurrentAxisDown.stick = myCurrentAxisDown.axis = -1; + myCurrentAxisDown.count = 0; } } @@ -413,6 +456,9 @@ void DialogContainer::reset() myLastClick.time = 0; myLastClick.count = 0; + myCurrentAxisDown.stick = myCurrentAxisDown.axis = -1; + myCurrentAxisDown.count = 0; + int oldX = ourJoyMouse.x, oldY = ourJoyMouse.y; if(ourJoyMouse.x > ourJoyMouse.x_max) ourJoyMouse.x = ourJoyMouse.x_max; diff --git a/stella/src/gui/DialogContainer.hxx b/stella/src/gui/DialogContainer.hxx index d6bd7a90b..ebc3c8756 100644 --- a/stella/src/gui/DialogContainer.hxx +++ b/stella/src/gui/DialogContainer.hxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: DialogContainer.hxx,v 1.12 2005-12-24 22:50:53 stephena Exp $ +// $Id: DialogContainer.hxx,v 1.13 2006-01-04 01:24:17 stephena Exp $ //============================================================================ #ifndef DIALOG_CONTAINER_HXX @@ -37,7 +37,7 @@ typedef FixedStack DialogStack; a stack, and handles their events. @author Stephen Anthony - @version $Id: DialogContainer.hxx,v 1.12 2005-12-24 22:50:53 stephena Exp $ + @version $Id: DialogContainer.hxx,v 1.13 2006-01-04 01:24:17 stephena Exp $ */ class DialogContainer { @@ -154,11 +154,13 @@ class DialogContainer DialogStack myDialogStack; enum { - kDoubleClickDelay = 500, - kKeyRepeatInitialDelay = 400, - kKeyRepeatSustainDelay = 50, + kDoubleClickDelay = 500, + kKeyRepeatInitialDelay = 400, + kKeyRepeatSustainDelay = 50, kClickRepeatInitialDelay = kKeyRepeatInitialDelay, - kClickRepeatSustainDelay = kKeyRepeatSustainDelay + kClickRepeatSustainDelay = kKeyRepeatSustainDelay, + kAxisRepeatInitialDelay = kKeyRepeatInitialDelay, + kAxisRepeatSustainDelay = kKeyRepeatSustainDelay }; // Indicates the most current time (in milliseconds) as set by updateTime() @@ -183,6 +185,15 @@ class DialogContainer } myCurrentMouseDown; uInt32 myClickRepeatTime; + // For continuous events (joyaxisDown) + struct { + int stick; + int axis; + int value; + int count; + } myCurrentAxisDown; + uInt32 myAxisRepeatTime; + // Position and time of last mouse click (used to detect double clicks) struct { int x, y; // Position of mouse when the click occured diff --git a/stella/src/gui/GuiObject.hxx b/stella/src/gui/GuiObject.hxx index eccd20985..6076e6477 100644 --- a/stella/src/gui/GuiObject.hxx +++ b/stella/src/gui/GuiObject.hxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: GuiObject.hxx,v 1.16 2005-12-09 01:16:13 stephena Exp $ +// $Id: GuiObject.hxx,v 1.17 2006-01-04 01:24:17 stephena Exp $ // // Based on code from ScummVM - Scumm Interpreter // Copyright (C) 2002-2004 The ScummVM project @@ -32,11 +32,22 @@ class Widget; typedef Common::Array WidgetArray; +enum { + kCursorUp = 256+17, + kCursorDown = 256+18, + kCursorRight = 256+19, + kCursorLeft = 256+20, + kCursorHome = 256+22, + kCursorEnd = 256+23, + kCursorPgUp = 256+24, + kCursorPgDn = 256+25 +}; + /** This is the base class for all GUI objects/widgets. @author Stephen Anthony - @version $Id: GuiObject.hxx,v 1.16 2005-12-09 01:16:13 stephena Exp $ + @version $Id: GuiObject.hxx,v 1.17 2006-01-04 01:24:17 stephena Exp $ */ class GuiObject : public CommandReceiver { diff --git a/stella/src/gui/LauncherDialog.cxx b/stella/src/gui/LauncherDialog.cxx index 811e656e3..97578ef45 100644 --- a/stella/src/gui/LauncherDialog.cxx +++ b/stella/src/gui/LauncherDialog.cxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: LauncherDialog.cxx,v 1.34 2005-12-18 18:37:03 stephena Exp $ +// $Id: LauncherDialog.cxx,v 1.35 2006-01-04 01:24:17 stephena Exp $ // // Based on code from ScummVM - Scumm Interpreter // Copyright (C) 2002-2004 The ScummVM project @@ -53,10 +53,12 @@ LauncherDialog::LauncherDialog(OSystem* osystem, DialogContainer* parent, myQuitButton(NULL), myList(NULL), myGameList(NULL), - myProgressBar(NULL) + myProgressBar(NULL), + mySelectedItem(0) { const GUI::Font& font = instance()->font(); const int fontHeight = font.getFontHeight(); + WidgetArray wid; // Show game name new StaticTextWidget(this, 10, 8, 200, fontHeight, @@ -74,31 +76,49 @@ LauncherDialog::LauncherDialog(OSystem* osystem, DialogContainer* parent, #ifndef MAC_OSX myStartButton = new ButtonWidget(this, xpos, _h - 24, width, 16, "Play", kStartCmd, 'S'); + myStartButton->setEditable(true); + wid.push_back(myStartButton); xpos += space + width; myOptionsButton = new ButtonWidget(this, xpos, _h - 24, width, 16, "Options", kOptionsCmd, 'O'); + myOptionsButton->setEditable(true); + wid.push_back(myOptionsButton); xpos += space + width; myReloadButton = new ButtonWidget(this, xpos, _h - 24, width, 16, "Reload", kReloadCmd, 'R'); + myReloadButton->setEditable(true); + wid.push_back(myReloadButton); xpos += space + width; myQuitButton = new ButtonWidget(this, xpos, _h - 24, width, 16, "Quit", kQuitCmd, 'Q'); + myQuitButton->setEditable(true); + wid.push_back(myQuitButton); xpos += space + width; #else myQuitButton = new ButtonWidget(this, xpos, _h - 24, width, 16, "Quit", kQuitCmd, 'Q'); + myQuitButton->setEditable(true); + wid.push_back(myQuitButton); xpos += space + width; myOptionsButton = new ButtonWidget(this, xpos, _h - 24, width, 16, "Options", kOptionsCmd, 'O'); + myOptionsButton->setEditable(true); + wid.push_back(myOptionsButton); xpos += space + width; myReloadButton = new ButtonWidget(this, xpos, _h - 24, width, 16, "Reload", kReloadCmd, 'R'); + myReloadButton->setEditable(true); + wid.push_back(myReloadButton); xpos += space + width; myStartButton = new ButtonWidget(this, xpos, _h - 24, width, 16, "Start", kStartCmd, 'Q'); + myStartButton->setEditable(true); + wid.push_back(myStartButton); xpos += space + width; #endif // Add list with game titles + // The list isn't added to focus objects, but is instead made 'sticky' + // This means it will act as if it were focused (wrt how it's drawn), but + // won't actually be able to lose focus myList = new StringListWidget(this, instance()->font(), 10, 24, _w - 20, _h - 24 - 26 - 10 - 10); myList->setNumberingMode(kListNumberingOff); myList->setEditable(false); - myList->setFlags(WIDGET_NODRAW_FOCUS); - addFocusWidget(myList); + myList->setFlags(WIDGET_STICKY_FOCUS); // Add note textwidget to show any notes for the currently selected ROM new StaticTextWidget(this, 20, _h - 43, 30, fontHeight, "Note:", kTextAlignLeft); @@ -113,6 +133,8 @@ LauncherDialog::LauncherDialog(OSystem* osystem, DialogContainer* parent, // Create a game list, which contains all the information about a ROM that // the launcher needs myGameList = new GameList(); + + addToFocusList(wid); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -336,6 +358,62 @@ string LauncherDialog::MD5FromFile(const string& path) return md5; } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void LauncherDialog::handleKeyDown(int ascii, int keycode, int modifiers) +{ + // Only detect the cursor keys, otherwise pass to base class + switch(ascii) + { + case kCursorLeft: + mySelectedItem--; + if(mySelectedItem < 0) mySelectedItem = 3; + Dialog::setFocus(getFocusList()[mySelectedItem]); + break; + + case kCursorRight: + mySelectedItem++; + if(mySelectedItem > 3) mySelectedItem = 0; + Dialog::setFocus(getFocusList()[mySelectedItem]); + break; + + case ' ': // Used to activate currently focused button + Dialog::handleKeyDown(ascii, keycode, modifiers); + break; + + default: + if(!myList->handleKeyDown(ascii, keycode, modifiers)) + Dialog::handleKeyDown(ascii, keycode, modifiers); + break; + } +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void LauncherDialog::handleJoyAxis(int stick, int axis, int value) +{ + // We make the (hopefully) valid assumption that all joysticks + // treat axis the same way. Eventually, we may need to remap + // these actions of this assumption is invalid. + // TODO - make this work better with analog axes ... + int key = -1; + if(axis % 2 == 0) // x-direction + { + if(value < 0) + key = kCursorLeft; + else if(value > 0) + key = kCursorRight; + } + else // y-direction + { + if(value < 0) + key = kCursorUp; + else if(value > 0) + key = kCursorDown; + } + + if(key != -1) + handleKeyDown(key, 0, 0); +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void LauncherDialog::handleCommand(CommandSender* sender, int cmd, int data, int id) diff --git a/stella/src/gui/LauncherDialog.hxx b/stella/src/gui/LauncherDialog.hxx index 685d59809..ec42deb5e 100644 --- a/stella/src/gui/LauncherDialog.hxx +++ b/stella/src/gui/LauncherDialog.hxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: LauncherDialog.hxx,v 1.13 2005-08-22 18:17:10 stephena Exp $ +// $Id: LauncherDialog.hxx,v 1.14 2006-01-04 01:24:17 stephena Exp $ // // Based on code from ScummVM - Scumm Interpreter // Copyright (C) 2002-2004 The ScummVM project @@ -36,10 +36,6 @@ class OSystem; #include "bspf.hxx" enum { - kStartCmd = 'STRT', - kOptionsCmd = 'OPTI', - kReloadCmd = 'RELO', - kQuitCmd = 'QUIT', kChooseRomDirCmd = 'roms', // rom select kChooseSnapDirCmd = 'snps', // snap select kRomDirChosenCmd = 'romc', // rom chosen @@ -53,12 +49,16 @@ class LauncherDialog : public Dialog int x, int y, int w, int h); ~LauncherDialog(); + protected: + virtual void handleKeyDown(int ascii, int keycode, int modifiers); + virtual void handleJoyAxis(int stick, int axis, int value); virtual void handleCommand(CommandSender* sender, int cmd, int data, int id); - protected: void updateListing(bool fullReload = false); void loadConfig(); + virtual bool wantsEvents() { return true; } + protected: ButtonWidget* myStartButton; ButtonWidget* myOptionsButton; @@ -79,6 +79,16 @@ class LauncherDialog : public Dialog void loadListFromCache(); void createListCache(); string MD5FromFile(const string& path); + + private: + int mySelectedItem; + + enum { + kStartCmd = 'STRT', + kOptionsCmd = 'OPTI', + kReloadCmd = 'RELO', + kQuitCmd = 'QUIT' + }; }; #endif diff --git a/stella/src/gui/ListWidget.cxx b/stella/src/gui/ListWidget.cxx index 26186b323..f860b677b 100644 --- a/stella/src/gui/ListWidget.cxx +++ b/stella/src/gui/ListWidget.cxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: ListWidget.cxx,v 1.37 2005-12-21 19:31:18 stephena Exp $ +// $Id: ListWidget.cxx,v 1.38 2006-01-04 01:24:17 stephena Exp $ // // Based on code from ScummVM - Scumm Interpreter // Copyright (C) 2002-2004 The ScummVM project @@ -287,33 +287,33 @@ bool ListWidget::handleKeyDown(int ascii, int keycode, int modifiers) } break; - case 256+17: // up arrow + case kCursorUp: if (_selectedItem > 0) _selectedItem--; break; - case 256+18: // down arrow + case kCursorDown: if (_selectedItem < (int)_list.size() - 1) _selectedItem++; break; - case 256+24: // pageup + case kCursorPgUp: _selectedItem -= _rows - 1; if (_selectedItem < 0) _selectedItem = 0; break; - case 256+25: // pagedown + case kCursorPgDn: _selectedItem += _rows - 1; if (_selectedItem >= (int)_list.size() ) _selectedItem = _list.size() - 1; break; - case 256+22: // home + case kCursorHome: _selectedItem = 0; break; - case 256+23: // end + case kCursorEnd: _selectedItem = _list.size() - 1; break; diff --git a/stella/src/gui/ListWidget.hxx b/stella/src/gui/ListWidget.hxx index 87dccd5aa..14384b625 100644 --- a/stella/src/gui/ListWidget.hxx +++ b/stella/src/gui/ListWidget.hxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: ListWidget.hxx,v 1.14 2005-09-30 18:17:29 stephena Exp $ +// $Id: ListWidget.hxx,v 1.15 2006-01-04 01:24:17 stephena Exp $ // // Based on code from ScummVM - Scumm Interpreter // Copyright (C) 2002-2004 The ScummVM project @@ -70,7 +70,7 @@ class ListWidget : public EditableWidget virtual void handleCommand(CommandSender* sender, int cmd, int data, int id); virtual GUI::Rect getRect() const; - virtual bool wantsFocus() { return true; } + virtual bool wantsFocus() { return !isSticky(); } void startEditMode(); void endEditMode(); diff --git a/stella/src/gui/StringListWidget.cxx b/stella/src/gui/StringListWidget.cxx index 6a7cb9465..8c3fd1abf 100644 --- a/stella/src/gui/StringListWidget.cxx +++ b/stella/src/gui/StringListWidget.cxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: StringListWidget.cxx,v 1.2 2005-08-23 18:32:51 stephena Exp $ +// $Id: StringListWidget.cxx,v 1.3 2006-01-04 01:24:17 stephena Exp $ // // Based on code from ScummVM - Scumm Interpreter // Copyright (C) 2002-2004 The ScummVM project @@ -67,7 +67,7 @@ void StringListWidget::drawWidget(bool hilite) // Draw the selected item inverted, on a highlighted background. if (_selectedItem == pos) { - if (_hasFocus && !_editMode) + if ((_hasFocus && !_editMode) || isSticky()) fb.fillRect(_x + 1, _y + 1 + kLineHeight * i, _w - 1, kLineHeight, kTextColorHi); else fb.frameRect(_x + 1, _y + 1 + kLineHeight * i, _w - 1, kLineHeight, kTextColorHi); diff --git a/stella/src/gui/Widget.hxx b/stella/src/gui/Widget.hxx index 4e95cfcfb..7b387b2c7 100644 --- a/stella/src/gui/Widget.hxx +++ b/stella/src/gui/Widget.hxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: Widget.hxx,v 1.43 2005-12-24 22:09:36 stephena Exp $ +// $Id: Widget.hxx,v 1.44 2006-01-04 01:24:17 stephena Exp $ // // Based on code from ScummVM - Scumm Interpreter // Copyright (C) 2002-2004 The ScummVM project @@ -44,8 +44,9 @@ enum { WIDGET_TRACK_MOUSE = 1 << 6, WIDGET_RETAIN_FOCUS = 1 << 7, WIDGET_NODRAW_FOCUS = 1 << 8, - WIDGET_WANTS_TAB = 1 << 9, - WIDGET_WANTS_EVENTS = 1 << 10 + WIDGET_STICKY_FOCUS = 1 << 9, + WIDGET_WANTS_TAB = 1 << 10, + WIDGET_WANTS_EVENTS = 1 << 11 }; enum { @@ -73,7 +74,7 @@ enum { This is the base class for all widgets. @author Stephen Anthony - @version $Id: Widget.hxx,v 1.43 2005-12-24 22:09:36 stephena Exp $ + @version $Id: Widget.hxx,v 1.44 2006-01-04 01:24:17 stephena Exp $ */ class Widget : public GuiObject { @@ -115,6 +116,7 @@ class Widget : public GuiObject bool isEnabled() const { return _flags & WIDGET_ENABLED; } bool isVisible() const { return !(_flags & WIDGET_INVISIBLE); } + bool isSticky() const { return _flags & WIDGET_STICKY_FOCUS; } bool wantsEvents() const { return _flags & WIDGET_WANTS_EVENTS; } void setID(int id) { _id = id; }