mirror of https://github.com/stella-emu/stella.git
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
This commit is contained in:
parent
2f16788aaa
commit
adc6354943
|
@ -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 <sstream>
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,10 +295,6 @@ 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(activeDialog->wantsEvents())
|
||||
activeDialog->handleJoyAxis(stick, axis, value);
|
||||
else
|
||||
{
|
||||
if(value > JOY_DEADZONE)
|
||||
value -= JOY_DEADZONE;
|
||||
else if(value < -JOY_DEADZONE )
|
||||
|
@ -281,6 +302,26 @@ void DialogContainer::handleJoyAxisEvent(int stick, int axis, int value)
|
|||
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(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;
|
||||
|
|
|
@ -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<Dialog *> 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
|
||||
{
|
||||
|
@ -158,7 +158,9 @@ class DialogContainer
|
|||
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
|
||||
|
|
|
@ -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<Widget*> 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
|
||||
{
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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; }
|
||||
|
|
Loading…
Reference in New Issue