From 978c97c2d0e5ad7bc6d3b1347c34815f91865be5 Mon Sep 17 00:00:00 2001 From: stephena Date: Mon, 19 Dec 2005 02:19:49 +0000 Subject: [PATCH] Removed the ability to emulate the mouse cursor with the joystick while in GUI menu mode. The code was too troublesome to fix, and navigating a GUI with a joystick simulating a mouse is a broken concept anyway. In place of joy-is-mouse navigation, added the ability to use the cursor keys or joysticks axes to 'tab' between different focused objects in GUI mode. This is much more intuitive, and is how navigation works in a mouse-less, game console based system. Also, any joystick button (or enter/space keys) activate the currently focused item. For now, only the CommandDialog can be accessed this way. It really only makes sense here anyway, since many GUI objects in the other menus really need access to a keyboard and mouse, and if you have those, one can already navigate the menu. Overall, this should make arcade cabinet style access much easier. One can map the CommandDialog to a joystick button, navigate with the joystick axes, and select an item with any joystick button. So Stella can be started, play a game, and then exit, all by just using the joystick. It also solves quite a few usability problems for the WinCE and PSP ports. git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@918 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba --- stella/src/debugger/DebuggerParser.cxx | 4 +- stella/src/debugger/EquateList.cxx | 4 +- stella/src/debugger/WordDerefExpression.cxx | 3 +- stella/src/emucore/EventHandler.cxx | 190 ++---------------- stella/src/emucore/EventHandler.hxx | 30 +-- stella/src/gui/CommandDialog.cxx | 206 ++++++++++++++++---- stella/src/gui/CommandDialog.hxx | 8 +- stella/src/gui/Dialog.cxx | 14 +- stella/src/gui/Dialog.hxx | 5 +- stella/src/gui/DialogContainer.hxx | 8 +- stella/src/gui/Widget.cxx | 51 ++++- stella/src/gui/Widget.hxx | 11 +- 12 files changed, 271 insertions(+), 263 deletions(-) diff --git a/stella/src/debugger/DebuggerParser.cxx b/stella/src/debugger/DebuggerParser.cxx index a242df703..f38c490e8 100644 --- a/stella/src/debugger/DebuggerParser.cxx +++ b/stella/src/debugger/DebuggerParser.cxx @@ -13,12 +13,14 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: DebuggerParser.cxx,v 1.88 2005-11-11 21:44:19 stephena Exp $ +// $Id: DebuggerParser.cxx,v 1.89 2005-12-19 02:19:48 stephena Exp $ //============================================================================ #include "bspf.hxx" #include #include + +#include "Dialog.hxx" #include "Debugger.hxx" #include "CpuDebug.hxx" #include "DebuggerParser.hxx" diff --git a/stella/src/debugger/EquateList.cxx b/stella/src/debugger/EquateList.cxx index 09f399440..0b3718c31 100644 --- a/stella/src/debugger/EquateList.cxx +++ b/stella/src/debugger/EquateList.cxx @@ -13,11 +13,9 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: EquateList.cxx,v 1.20 2005-10-23 15:54:55 urchlay Exp $ +// $Id: EquateList.cxx,v 1.21 2005-12-19 02:19:48 stephena Exp $ //============================================================================ -#include -#include #include #include "bspf.hxx" diff --git a/stella/src/debugger/WordDerefExpression.cxx b/stella/src/debugger/WordDerefExpression.cxx index ebcfc3fbf..375016d94 100644 --- a/stella/src/debugger/WordDerefExpression.cxx +++ b/stella/src/debugger/WordDerefExpression.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: WordDerefExpression.cxx,v 1.1 2005-07-15 01:20:11 urchlay Exp $ +// $Id: WordDerefExpression.cxx,v 1.2 2005-12-19 02:19:49 stephena Exp $ //============================================================================ #include "Expression.hxx" @@ -24,4 +24,3 @@ WordDerefExpression::WordDerefExpression(Expression *left) : Expression(left, 0) { } - diff --git a/stella/src/emucore/EventHandler.cxx b/stella/src/emucore/EventHandler.cxx index 905c6eab3..bafd26cae 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.131 2005-12-18 18:37:03 stephena Exp $ +// $Id: EventHandler.cxx,v 1.132 2005-12-19 02:19:49 stephena Exp $ //============================================================================ #include @@ -56,12 +56,6 @@ #define JOY_DEADZONE 3200 -#ifdef PSP - #define JOYMOUSE_LEFT_BUTTON 2 -#else - #define JOYMOUSE_LEFT_BUTTON 0 -#endif - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - EventHandler::EventHandler(OSystem* osystem) : myOSystem(osystem), @@ -350,10 +344,6 @@ void EventHandler::poll(uInt32 time) { SDL_Event event; - // Handle joystick to mouse emulation FIXME -// if(myEmulateMouseFlag) -// handleJoyMouse(time); - // Check for an event while(SDL_PollEvent(&event)) { @@ -634,11 +624,18 @@ void EventHandler::poll(uInt32 time) if(event.jbutton.button >= kNumJoyButtons-4) return; - int stick = event.jbutton.which; - int code = event.jbutton.button; - int state = event.jbutton.state == SDL_PRESSED ? 1 : 0; + int stick = event.jbutton.which; + int button = event.jbutton.button; + int state = event.jbutton.state == SDL_PRESSED ? 1 : 0; - handleJoyEvent(stick, code, state); + if(state && eventStateChange(myJoyTable[stick][button])) + return; + + // Determine which mode we're in, then send the event to the appropriate place + if(myState == S_EMULATE) + handleEvent(myJoyTable[stick][button], state); + else if(myOverlay != NULL) + myOverlay->handleJoyEvent(stick, button, state); break; // Regular joystick button } @@ -693,10 +690,7 @@ void EventHandler::poll(uInt32 time) if(myState == S_EMULATE) handleJoyAxisEvent(stick, axis, value); else if(myOverlay != NULL) - { - handleMouseWarp(stick, axis, value); myOverlay->handleJoyAxisEvent(stick, axis, value); - } break; // Regular joystick axis } @@ -879,166 +873,6 @@ void EventHandler::handleMouseButtonEvent(SDL_Event& event, int state) } } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void EventHandler::handleJoyMouse(JoyMouse& jm, uInt32 time) -{ - bool mouseAccel = false; // TODO - make this a commandline option - - if (jm.active || (time >= jm.last_time + jm.delay_time)) - { - jm.last_time = time; - if (jm.x_down_count == 1) - { - jm.x_down_time = time; - jm.x_down_count = 2; - } - if (jm.y_down_count == 1) - { - jm.y_down_time = time; - jm.y_down_count = 2; - } - - if (jm.x_vel || jm.y_vel) - { - if (jm.x_down_count) - { - if (mouseAccel && time > jm.x_down_time + jm.delay_time * 12) - { - if (jm.x_vel > 0) - jm.x_vel++; - else - jm.x_vel--; - } - else if (time > jm.x_down_time + jm.delay_time * 8) - { - if (jm.x_vel > 0) - jm.x_vel = jm.x_amt; - else - jm.x_vel = -jm.x_amt; - } - } - if (jm.y_down_count) - { - if (mouseAccel && time > jm.y_down_time + jm.delay_time * 12) - { - if (jm.y_vel > 0) - jm.y_vel++; - else - jm.y_vel--; - } - else if (time > jm.y_down_time + jm.delay_time * 8) - { - if (jm.y_vel > 0) - jm.y_vel = jm.x_amt; - else - jm.y_vel = -jm.x_amt; - } - } - - jm.x += jm.x_vel; - jm.y += jm.y_vel; - - if (jm.x < 0) - { - jm.x = 0; - jm.x_vel = -1; - jm.x_down_count = 1; - } - else if (jm.x > jm.x_max) - { - jm.x = jm.x_max; - jm.x_vel = 1; - jm.x_down_count = 1; - } - - if (jm.y < 0) - { - jm.y = 0; - jm.y_vel = -1; - jm.y_down_count = 1; - } - else if (jm.y > jm.y_max) - { - jm.y = myJoyMouse.y_max; - jm.y_vel = 1; - jm.y_down_count = 1; - } - -//FIXME SDL_WarpMouse(myJoyMouse.x, myJoyMouse.y); - } - } -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void EventHandler::handleMouseWarp(int stick, int axis, int value) -{ - if(value > JOY_DEADZONE) - value -= JOY_DEADZONE; - else if(value < -JOY_DEADZONE ) - value += JOY_DEADZONE; - else - value = 0; - - if(axis == 0) // X axis - { - if (value != 0) - { - myJoyMouse.x_vel = (value > 0) ? 1 : -1; - myJoyMouse.x_down_count = 1; - } - else - { - myJoyMouse.x_vel = 0; - myJoyMouse.x_down_count = 0; - } - } - else if(axis == 1) // Y axis - { - value = -value; - - if (value != 0) - { - myJoyMouse.y_vel = (-value > 0) ? 1 : -1; - myJoyMouse.y_down_count = 1; - } - else - { - myJoyMouse.y_vel = 0; - myJoyMouse.y_down_count = 0; - } - } -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void EventHandler::handleJoyEvent(int stick, int button, int state) -{ - Event::Type event = myJoyTable[stick][button]; - - // Joystick button zero acts as left mouse button and cannot be remapped - if(myState != S_EMULATE && button == JOYMOUSE_LEFT_BUTTON && - myEmulateMouseFlag) - { - // This button acts as mouse button zero, and can never be remapped - SDL_MouseButtonEvent mouseEvent; - mouseEvent.type = state ? SDL_MOUSEBUTTONDOWN : SDL_MOUSEBUTTONUP; - mouseEvent.button = SDL_BUTTON_LEFT; - mouseEvent.state = state ? SDL_PRESSED : SDL_RELEASED; - mouseEvent.x = myJoyMouse.x; - mouseEvent.y = myJoyMouse.y; - - handleMouseButtonEvent((SDL_Event&)mouseEvent, state); - return; - } - else if(state && eventStateChange(event)) - return; - - // Determine which mode we're in, then send the event to the appropriate place - if(myState == S_EMULATE) - handleEvent(event, state); - else if(myOverlay != NULL) - myOverlay->handleJoyEvent(stick, button, state); -} - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void EventHandler::handleJoyAxisEvent(int stick, int axis, int value) { diff --git a/stella/src/emucore/EventHandler.hxx b/stella/src/emucore/EventHandler.hxx index 141d238c3..0f75fdf6b 100644 --- a/stella/src/emucore/EventHandler.hxx +++ b/stella/src/emucore/EventHandler.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: EventHandler.hxx,v 1.67 2005-12-17 22:48:24 stephena Exp $ +// $Id: EventHandler.hxx,v 1.68 2005-12-19 02:19:49 stephena Exp $ //============================================================================ #ifndef EVENTHANDLER_HXX @@ -92,7 +92,7 @@ struct Stella_Joystick { mapping can take place. @author Stephen Anthony - @version $Id: EventHandler.hxx,v 1.67 2005-12-17 22:48:24 stephena Exp $ + @version $Id: EventHandler.hxx,v 1.68 2005-12-19 02:19:49 stephena Exp $ */ class EventHandler { @@ -325,15 +325,6 @@ class EventHandler */ void handleMouseButtonEvent(SDL_Event& event, int state); - /** - Send a joystick button event to the handler - - @param stick The joystick number - @param button The joystick button - @param state State of button (pressed/released) - */ - void handleJoyEvent(int stick, int button, int state); - /** Send a joystick axis event to the handler (directions are encoded as buttons) @@ -343,23 +334,6 @@ class EventHandler */ void handleJoyAxisEvent(int stick, int axis, int value); - /** - Convert joystick motion events to simulated mouse motion events - - @param stick The joystick number - @param axis The joystick axis - @param value The value on the given axis - */ - void handleMouseWarp(int stick, int axis, int value); - - /** - Handle joystick movement emulating mouse motion - - @param jm JoyMouse structure to modify - @param time Current millisecond count - */ - void handleJoyMouse(JoyMouse& jm, uInt32 time); - /** Detects and changes the eventhandler state diff --git a/stella/src/gui/CommandDialog.cxx b/stella/src/gui/CommandDialog.cxx index 1b9861628..919d6e2d5 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.4 2005-10-30 20:29:56 stephena Exp $ +// $Id: CommandDialog.cxx,v 1.5 2005-12-19 02:19:49 stephena Exp $ // // Based on code from ScummVM - Scumm Interpreter // Copyright (C) 2002-2004 The ScummVM project @@ -45,9 +45,20 @@ enum { 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) + : Dialog(osystem, parent, 0, 0, 16, 16), + mySelectedItem(0) { int lineHeight = osystem->font().getLineHeight(), buttonWidth = 60, @@ -62,60 +73,96 @@ CommandDialog::CommandDialog(OSystem* osystem, DialogContainer* parent) _x = (osystem->frameBuffer().baseWidth() - _w) / 2; _y = (osystem->frameBuffer().baseHeight() - _h) / 2; + WidgetArray wid; + ButtonWidget* b; - new ButtonWidget(this, xoffset, yoffset, buttonWidth, buttonHeight, - "Select", kSelectCmd, 0); + b = new ButtonWidget(this, xoffset, yoffset, buttonWidth, buttonHeight, + "Select", kSelectCmd, 0); + b->setEditable(true); + wid.push_back(b); xoffset += lwidth; - new ButtonWidget(this, xoffset, yoffset, buttonWidth, buttonHeight, - "Reset", kResetCmd, 0); + b = new ButtonWidget(this, xoffset, yoffset, buttonWidth, buttonHeight, + "Reset", kResetCmd, 0); + b->setEditable(true); + wid.push_back(b); xoffset += lwidth; - new ButtonWidget(this, xoffset, yoffset, buttonWidth, buttonHeight, - "Color TV", kColorCmd, 0); + b = new ButtonWidget(this, xoffset, yoffset, buttonWidth, buttonHeight, + "Color TV", kColorCmd, 0); + b->setEditable(true); + wid.push_back(b); xoffset += lwidth; - new ButtonWidget(this, xoffset, yoffset, buttonWidth, buttonHeight, - "B/W TV", kBWCmd, 0); + b = new ButtonWidget(this, xoffset, yoffset, buttonWidth, buttonHeight, + "B/W TV", kBWCmd, 0); + b->setEditable(true); + wid.push_back(b); xoffset = 5; yoffset += buttonHeight + 5; - new ButtonWidget(this, xoffset, yoffset, buttonWidth, buttonHeight, - "Left Diff A", kLeftDiffACmd, 0); + b = new ButtonWidget(this, xoffset, yoffset, buttonWidth, buttonHeight, + "Left Diff A", kLeftDiffACmd, 0); + b->setEditable(true); + wid.push_back(b); xoffset += lwidth; - new ButtonWidget(this, xoffset, yoffset, buttonWidth, buttonHeight, - "Left Diff B", kLeftDiffBCmd, 0); + b = new ButtonWidget(this, xoffset, yoffset, buttonWidth, buttonHeight, + "Left Diff B", kLeftDiffBCmd, 0); + b->setEditable(true); + wid.push_back(b); xoffset += lwidth; - new ButtonWidget(this, xoffset, yoffset, buttonWidth, buttonHeight, - "Right Diff A", kRightDiffACmd, 0); + b = new ButtonWidget(this, xoffset, yoffset, buttonWidth, buttonHeight, + "Right Diff A", kRightDiffACmd, 0); + b->setEditable(true); + wid.push_back(b); xoffset += lwidth; - new ButtonWidget(this, xoffset, yoffset, buttonWidth, buttonHeight, - "Right Diff B", kRightDiffBCmd, 0); + b = new ButtonWidget(this, xoffset, yoffset, buttonWidth, buttonHeight, + "Right Diff B", kRightDiffBCmd, 0); + b->setEditable(true); + wid.push_back(b); xoffset = 5; yoffset += buttonHeight + 5; - new ButtonWidget(this, xoffset, yoffset, buttonWidth, buttonHeight, - "Save State", kSaveStateCmd, 0); + b = new ButtonWidget(this, xoffset, yoffset, buttonWidth, buttonHeight, + "Save State", kSaveStateCmd, 0); + b->setEditable(true); + wid.push_back(b); xoffset += lwidth; - new ButtonWidget(this, xoffset, yoffset, buttonWidth, buttonHeight, - "State Slot", kStateSlotCmd, 0); + b = new ButtonWidget(this, xoffset, yoffset, buttonWidth, buttonHeight, + "State Slot", kStateSlotCmd, 0); + b->setEditable(true); + wid.push_back(b); xoffset += lwidth; - new ButtonWidget(this, xoffset, yoffset, buttonWidth, buttonHeight, - "Load State", kLoadStateCmd, 0); + b = new ButtonWidget(this, xoffset, yoffset, buttonWidth, buttonHeight, + "Load State", kLoadStateCmd, 0); + b->setEditable(true); + wid.push_back(b); xoffset += lwidth; - new ButtonWidget(this, xoffset, yoffset, buttonWidth, buttonHeight, - "Snapshot", kSnapshotCmd, 0); + b = new ButtonWidget(this, xoffset, yoffset, buttonWidth, buttonHeight, + "Snapshot", kSnapshotCmd, 0); + b->setEditable(true); + wid.push_back(b); xoffset = 5; yoffset += buttonHeight + 5; - new ButtonWidget(this, xoffset, yoffset, buttonWidth, buttonHeight, - "NTSC/PAL", kFormatCmd, 0); + b = new ButtonWidget(this, xoffset, yoffset, buttonWidth, buttonHeight, + "NTSC/PAL", kFormatCmd, 0); + b->setEditable(true); + wid.push_back(b); xoffset += lwidth; - new ButtonWidget(this, xoffset, yoffset, buttonWidth, buttonHeight, - "Palette", kPaletteCmd, 0); + b = new ButtonWidget(this, xoffset, yoffset, buttonWidth, buttonHeight, + "Palette", kPaletteCmd, 0); + b->setEditable(true); + wid.push_back(b); xoffset += lwidth; - new ButtonWidget(this, xoffset, yoffset, buttonWidth, buttonHeight, - "Reload ROM", kReloadRomCmd, 0); + b = new ButtonWidget(this, xoffset, yoffset, buttonWidth, buttonHeight, + "Reload ROM", kReloadRomCmd, 0); + b->setEditable(true); + wid.push_back(b); xoffset += lwidth; - new ButtonWidget(this, xoffset, yoffset, buttonWidth, buttonHeight, - "Exit Game", kExitCmd, 0); + b = new ButtonWidget(this, xoffset, yoffset, buttonWidth, buttonHeight, + "Exit Game", kExitCmd, 0); + b->setEditable(true); + wid.push_back(b); + + addToFocusList(wid); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -123,6 +170,97 @@ CommandDialog::~CommandDialog() { } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void CommandDialog::handleKeyDown(int ascii, int keycode, int modifiers) +{ + bool handled = true; + int row = mySelectedItem / kNumRows, + col = mySelectedItem - (row * kNumCols); + + // Only detect the cursor keys, otherwise pass to base class + switch(ascii) + { + case kUpArrow: + if (row > 0) + --row; + else if(col > 0) + { + row = kNumRows - 1; + --col; + } + break; + + case kDownArrow: + if (row < kNumRows - 1) + ++row; + else if(col < kNumCols - 1) + { + row = 0; + ++col; + } + break; + + case kLeftArrow: + if (col > 0) + --col; + else if(row > 0) + { + col = kNumCols - 1; + --row; + } + break; + + case kRightArrow: + if (col < kNumCols - 1) + ++col; + else if(row < kNumRows - 1) + { + col = 0; + ++row; + } + break; + + default: + handled = false; + break; + } + + if(handled) + { + mySelectedItem = row * kNumCols + col; + Dialog::setFocus(getFocusList()[mySelectedItem]); + } + else + Dialog::handleKeyDown(ascii, keycode, modifiers); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void CommandDialog::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 = kLeftArrow; + else if(value > 0) + key = kRightArrow; + } + else // y-direction + { + if(value < 0) + key = kUpArrow; + else if(value > 0) + key = kDownArrow; + } + + if(key != -1) + handleKeyDown(key, 0, 0); +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void CommandDialog::handleCommand(CommandSender* sender, int cmd, int data, int id) diff --git a/stella/src/gui/CommandDialog.hxx b/stella/src/gui/CommandDialog.hxx index 6cc1aeeb1..70d2fae05 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.1 2005-08-29 18:36:42 stephena Exp $ +// $Id: CommandDialog.hxx,v 1.2 2005-12-19 02:19:49 stephena Exp $ // // Based on code from ScummVM - Scumm Interpreter // Copyright (C) 2002-2004 The ScummVM project @@ -35,7 +35,13 @@ class CommandDialog : public Dialog CommandDialog(OSystem* osystem, DialogContainer* parent); ~CommandDialog(); + 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); + + private: + int mySelectedItem; }; #endif diff --git a/stella/src/gui/Dialog.cxx b/stella/src/gui/Dialog.cxx index 7f2414b3f..47a38568a 100644 --- a/stella/src/gui/Dialog.cxx +++ b/stella/src/gui/Dialog.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: Dialog.cxx,v 1.34 2005-12-07 20:46:49 stephena Exp $ +// $Id: Dialog.cxx,v 1.35 2005-12-19 02:19:49 stephena Exp $ // // Based on code from ScummVM - Scumm Interpreter // Copyright (C) 2002-2004 The ScummVM project @@ -126,6 +126,18 @@ void Dialog::addToFocusList(WidgetArray& list, int id) _ourFocusList[id].focusedWidget = list[0]; } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void Dialog::setFocus(Widget* w) +{ + // If the click occured inside a widget which is not the currently + // focused one, change the focus to that widget. + if(w && w != _focusedWidget && w->wantsFocus()) + { + // Redraw widgets for new focus + _focusedWidget = Widget::setFocusForChain(this, getFocusList(), w, 0); + } +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void Dialog::buildFocusWidgetList(int id) { diff --git a/stella/src/gui/Dialog.hxx b/stella/src/gui/Dialog.hxx index b493f5149..615eb3274 100644 --- a/stella/src/gui/Dialog.hxx +++ b/stella/src/gui/Dialog.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: Dialog.hxx,v 1.22 2005-12-09 01:16:13 stephena Exp $ +// $Id: Dialog.hxx,v 1.23 2005-12-19 02:19:49 stephena Exp $ // // Based on code from ScummVM - Scumm Interpreter // Copyright (C) 2002-2004 The ScummVM project @@ -36,7 +36,7 @@ class TabWidget; This is the base class for all dialog boxes. @author Stephen Anthony - @version $Id: Dialog.hxx,v 1.22 2005-12-09 01:16:13 stephena Exp $ + @version $Id: Dialog.hxx,v 1.23 2005-12-19 02:19:49 stephena Exp $ */ class Dialog : public GuiObject { @@ -67,6 +67,7 @@ class Dialog : public GuiObject void addToFocusList(WidgetArray& list, int id = -1); void redrawFocus(); void addTabWidget(TabWidget* w) { _ourTab = w; } + void setFocus(Widget* w); protected: virtual void draw(); diff --git a/stella/src/gui/DialogContainer.hxx b/stella/src/gui/DialogContainer.hxx index 36467df9e..7e6037032 100644 --- a/stella/src/gui/DialogContainer.hxx +++ b/stella/src/gui/DialogContainer.hxx @@ -13,17 +13,17 @@ // 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.9 2005-12-07 02:33:56 stephena Exp $ +// $Id: DialogContainer.hxx,v 1.10 2005-12-19 02:19:49 stephena Exp $ //============================================================================ #ifndef DIALOG_CONTAINER_HXX #define DIALOG_CONTAINER_HXX +class Dialog; class OSystem; -#include "Stack.hxx" #include "EventHandler.hxx" -#include "Dialog.hxx" +#include "Stack.hxx" #include "bspf.hxx" typedef FixedStack DialogStack; @@ -37,7 +37,7 @@ typedef FixedStack DialogStack; a stack, and handles their events. @author Stephen Anthony - @version $Id: DialogContainer.hxx,v 1.9 2005-12-07 02:33:56 stephena Exp $ + @version $Id: DialogContainer.hxx,v 1.10 2005-12-19 02:19:49 stephena Exp $ */ class DialogContainer { diff --git a/stella/src/gui/Widget.cxx b/stella/src/gui/Widget.cxx index fa54f07f6..7357f0ec2 100644 --- a/stella/src/gui/Widget.cxx +++ b/stella/src/gui/Widget.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: Widget.cxx,v 1.38 2005-09-30 00:53:30 stephena Exp $ +// $Id: Widget.cxx,v 1.39 2005-12-19 02:19:49 stephena Exp $ // // Based on code from ScummVM - Scumm Interpreter // Copyright (C) 2002-2004 The ScummVM project @@ -356,6 +356,30 @@ void ButtonWidget::handleMouseLeft(int button) setDirty(); draw(); } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool ButtonWidget::handleKeyDown(int ascii, int keycode, int modifiers) +{ + // (De)activate with space or return + switch(ascii) + { + case '\n': // enter/return + case '\r': + case ' ' : // space + // Simulate mouse event + handleMouseUp(0, 0, 1, 0); + return true; + default: + return false; + } +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void ButtonWidget::handleJoyDown(int stick, int button) +{ + // Any button activates the button + handleMouseUp(0, 0, 1, 0); +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void ButtonWidget::handleMouseUp(int x, int y, int button, int clickCount) { @@ -366,6 +390,22 @@ void ButtonWidget::handleMouseUp(int x, int y, int button, int clickCount) } } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool ButtonWidget::wantsFocus() +{ + return _editable; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void ButtonWidget::setEditable(bool editable) +{ + _editable = editable; + if(_editable) + setFlags(WIDGET_RETAIN_FOCUS); + else + clearFlags(WIDGET_RETAIN_FOCUS); +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void ButtonWidget::drawWidget(bool hilite) { @@ -426,8 +466,6 @@ void CheckboxWidget::handleMouseUp(int x, int y, int button, int clickCount) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool CheckboxWidget::handleKeyDown(int ascii, int keycode, int modifiers) { - bool handled = false; - // (De)activate with space or return switch(ascii) { @@ -436,11 +474,10 @@ bool CheckboxWidget::handleKeyDown(int ascii, int keycode, int modifiers) case ' ' : // space // Simulate mouse event handleMouseUp(0, 0, 1, 0); - handled = true; - break; + return true; + default: + return false; } - - return handled; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/stella/src/gui/Widget.hxx b/stella/src/gui/Widget.hxx index c7228174f..c8b04e70b 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.40 2005-12-07 02:33:56 stephena Exp $ +// $Id: Widget.hxx,v 1.41 2005-12-19 02:19:49 stephena Exp $ // // Based on code from ScummVM - Scumm Interpreter // Copyright (C) 2002-2004 The ScummVM project @@ -72,7 +72,7 @@ enum { This is the base class for all widgets. @author Stephen Anthony - @version $Id: Widget.hxx,v 1.40 2005-12-07 02:33:56 stephena Exp $ + @version $Id: Widget.hxx,v 1.41 2005-12-19 02:19:49 stephena Exp $ */ class Widget : public GuiObject { @@ -175,12 +175,14 @@ class StaticTextWidget : public Widget void setLabel(const string& label); void setAlign(TextAlignment align) { _align = align; } const string& getLabel() const { return _label; } + void setEditable(bool editable); protected: void drawWidget(bool hilite); protected: string _label; + bool _editable; TextAlignment _align; }; @@ -199,6 +201,11 @@ class ButtonWidget : public StaticTextWidget, public CommandSender void handleMouseUp(int x, int y, int button, int clickCount); void handleMouseEntered(int button); void handleMouseLeft(int button); + bool handleKeyDown(int ascii, int keycode, int modifiers); + void handleJoyDown(int stick, int button); + + bool wantsFocus(); + void setEditable(bool editable); protected: void drawWidget(bool hilite);