Added continuous key event support to the DialogContainer. That means

one can hold down a key, and after a small delay, the key event will be
repeated.  This is much better than having to push the 'down arrow' 100
times in a large scroll box.  Still TODO is handle mouse clicks in the same
way.  The code is there, but it's commented out.  This will be much harder,
since the GUI code from ScummVM wasn't designed to work that way.

Removed x,y items when sending joystick events, since that information
isn't available in SDL joystick motion.


git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@439 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
stephena 2005-05-26 15:43:44 +00:00
parent 46f3e463d9
commit 9722d7f554
10 changed files with 153 additions and 51 deletions

View File

@ -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.61 2005-05-25 23:22:11 stephena Exp $
// $Id: EventHandler.cxx,v 1.62 2005-05-26 15:43:43 stephena Exp $
//============================================================================
#include <algorithm>
@ -222,7 +222,7 @@ void EventHandler::setupJoysticks()
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void EventHandler::poll()
void EventHandler::poll(uInt32 time)
{
SDL_Event event;
@ -450,6 +450,22 @@ void EventHandler::poll()
}
#endif
}
// Update the current dialog container at regular intervals
// Used to implement continuous events
switch(myState)
{
case S_MENU:
myOSystem->menu().updateTime(time);
break;
case S_LAUNCHER:
myOSystem->launcher().updateTime(time);
break;
default:
break;
}
}
@ -622,11 +638,11 @@ void EventHandler::handleKeyEvent(SDLKey key, SDLMod mod, uInt8 state)
myEvent->clear();
return;
}
myOSystem->menu().handleKeyEvent((uInt16) key, (Int32) mod, state);
myOSystem->menu().handleKeyEvent(key, mod, state);
break;
case S_LAUNCHER:
myOSystem->launcher().handleKeyEvent((uInt16) key, (Int32) mod, state);
myOSystem->launcher().handleKeyEvent(key, mod, state);
break;
case S_DEBUGGER:
@ -762,11 +778,11 @@ void EventHandler::handleJoyEvent(uInt8 stick, uInt32 code, uInt8 state)
break;
case S_MENU:
myOSystem->menu().handleJoyEvent(0, 0, stick, code, state); // FIXME - get x,y
myOSystem->menu().handleJoyEvent(stick, code, state);
break;
case S_LAUNCHER:
myOSystem->launcher().handleJoyEvent(0, 0, stick, code, state); // FIXME - get x,y
myOSystem->launcher().handleJoyEvent(stick, code, state);
break;
case S_DEBUGGER:

View File

@ -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.31 2005-05-25 23:22:11 stephena Exp $
// $Id: EventHandler.hxx,v 1.32 2005-05-26 15:43:44 stephena Exp $
//============================================================================
#ifndef EVENTHANDLER_HXX
@ -74,7 +74,7 @@ struct Stella_Joystick {
mapping can take place.
@author Stephen Anthony
@version $Id: EventHandler.hxx,v 1.31 2005-05-25 23:22:11 stephena Exp $
@version $Id: EventHandler.hxx,v 1.32 2005-05-26 15:43:44 stephena Exp $
*/
class EventHandler
{
@ -109,8 +109,10 @@ class EventHandler
/**
Collects and dispatches any pending events. This method should be
called regularly (at X times per second, where X is the game framerate).
@param time The current time in milliseconds.
*/
void poll();
void poll(uInt32 time);
/**
Bind a key to an event/action

View File

@ -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.16 2005-05-25 23:22:11 stephena Exp $
// $Id: Dialog.cxx,v 1.17 2005-05-26 15:43:44 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
@ -284,19 +284,19 @@ void Dialog::handleMouseMoved(int x, int y, int button)
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Dialog::handleJoyDown(int x, int y, int stick, int button)
void Dialog::handleJoyDown(int stick, int button)
{
// Focused widget receives joystick events
if(_focusedWidget)
_focusedWidget->handleJoyDown(x, y, stick, button);
_focusedWidget->handleJoyDown(stick, button);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Dialog::handleJoyUp(int x, int y, int stick, int button)
void Dialog::handleJoyUp(int stick, int button)
{
// Focused widget receives joystick events
if(_focusedWidget)
_focusedWidget->handleJoyUp(x, y, stick, button);
_focusedWidget->handleJoyUp(stick, button);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -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.14 2005-05-25 23:22:11 stephena Exp $
// $Id: Dialog.hxx,v 1.15 2005-05-26 15:43:44 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
@ -35,7 +35,7 @@ class DialogContainer;
This is the base class for all dialog boxes.
@author Stephen Anthony
@version $Id: Dialog.hxx,v 1.14 2005-05-25 23:22:11 stephena Exp $
@version $Id: Dialog.hxx,v 1.15 2005-05-26 15:43:44 stephena Exp $
*/
class Dialog : public GuiObject
{
@ -68,8 +68,8 @@ class Dialog : public GuiObject
virtual void handleMouseUp(int x, int y, int button, int clickCount);
virtual void handleMouseWheel(int x, int y, int direction);
virtual void handleMouseMoved(int x, int y, int button);
virtual void handleJoyDown(int x, int y, int stick, int button);
virtual void handleJoyUp(int x, int y, int stick, int button);
virtual void handleJoyDown(int stick, int button);
virtual void handleJoyUp(int stick, int button);
virtual void handleCommand(CommandSender* sender, int cmd, int data);
virtual void handleScreenChanged() {}

View File

@ -13,21 +13,24 @@
// 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.6 2005-05-25 23:22:11 stephena Exp $
// $Id: DialogContainer.cxx,v 1.7 2005-05-26 15:43:44 stephena Exp $
//============================================================================
#include "OSystem.hxx"
#include "Dialog.hxx"
#include "Stack.hxx"
#include "EventHandler.hxx"
#include "bspf.hxx"
#include "DialogContainer.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
DialogContainer::DialogContainer(OSystem* osystem)
: myOSystem(osystem),
myBaseDialog(NULL)
myBaseDialog(NULL),
myTime(0)
{
myCurrentKeyDown.keycode = 0;
myCurrentMouseDown.button = -1;
myLastClick.x = myLastClick.y = 0;
myLastClick.time = 0;
myLastClick.count = 0;
@ -40,6 +43,36 @@ DialogContainer::~DialogContainer()
delete myBaseDialog;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void DialogContainer::updateTime(uInt32 time)
{
// We only need millisecond precision
myTime = time / 1000;
if(myDialogStack.empty())
return;
// Check for pending continuous events and send them to the active dialog box
Dialog* activeDialog = myDialogStack.top();
if(myCurrentKeyDown.keycode != 0 && myKeyRepeatTime < myTime)
{
activeDialog->handleKeyDown(myCurrentKeyDown.ascii, myCurrentKeyDown.keycode,
myCurrentKeyDown.flags);
myKeyRepeatTime = myTime + kKeyRepeatSustainDelay;
}
/* FIXME - there are still some problems with this code
if(myCurrentMouseDown.button != -1 && myClickRepeatTime < myTime)
{
activeDialog->handleMouseDown(myCurrentMouseDown.x - activeDialog->_x,
myCurrentMouseDown.y - activeDialog->_y,
myCurrentMouseDown.button, 1);
myClickRepeatTime = myTime + kClickRepeatSustainDelay;
}
*/
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void DialogContainer::draw()
{
@ -78,6 +111,13 @@ void DialogContainer::reStack()
// Now make sure all dialog boxes are in a known (closed) state
myBaseDialog->reset();
// Reset all continuous events
myCurrentKeyDown.keycode = 0;
myCurrentMouseDown.button = -1;
myLastClick.x = myLastClick.y = 0;
myLastClick.time = 0;
myLastClick.count = 0;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -89,9 +129,22 @@ void DialogContainer::handleKeyEvent(int key, int mod, uInt8 state)
// Send the event to the dialog box on the top of the stack
Dialog* activeDialog = myDialogStack.top();
if(state == 1)
{
myCurrentKeyDown.ascii = key;
myCurrentKeyDown.keycode = key;
myCurrentKeyDown.flags = mod;
myKeyRepeatTime = myTime + kKeyRepeatInitialDelay;
activeDialog->handleKeyDown(key, key, mod);
}
else
{
activeDialog->handleKeyUp(key, key, mod);
// Only stop firing events if it's the current key
if (key == myCurrentKeyDown.keycode)
myCurrentKeyDown.keycode = 0;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -116,9 +169,6 @@ void DialogContainer::handleMouseButtonEvent(MouseButton b, int x, int y, uInt8
// Send the event to the dialog box on the top of the stack
Dialog* activeDialog = myDialogStack.top();
// Get the current time for detecting double clicks
int time = myOSystem->getTicks() / 1000; // we only need millisecond precision
switch(b)
{
case EVENT_LBUTTONDOWN:
@ -131,7 +181,7 @@ void DialogContainer::handleMouseButtonEvent(MouseButton b, int x, int y, uInt8
myLastClick.count = 0;
}
if(myLastClick.count && (time < myLastClick.time + 500) // DoubleClickDelay
if(myLastClick.count && (myTime < myLastClick.time + kDoubleClickDelay)
&& ABS(myLastClick.x - x) < 3
&& ABS(myLastClick.y - y) < 3)
{
@ -143,7 +193,14 @@ void DialogContainer::handleMouseButtonEvent(MouseButton b, int x, int y, uInt8
myLastClick.y = y;
myLastClick.count = 1;
}
myLastClick.time = time;
myLastClick.time = myTime;
// Now account for repeated mouse events (click and hold)
myCurrentMouseDown.x = x;
myCurrentMouseDown.y = y;
myCurrentMouseDown.button = 1; // in the future, we may differentiate buttons
myClickRepeatTime = myTime + kClickRepeatInitialDelay;
activeDialog->handleMouseDown(x - activeDialog->_x, y - activeDialog->_y,
1, myLastClick.count);
break;
@ -152,6 +209,9 @@ void DialogContainer::handleMouseButtonEvent(MouseButton b, int x, int y, uInt8
case EVENT_RBUTTONUP:
activeDialog->handleMouseUp(x - activeDialog->_x, y - activeDialog->_y,
1, myLastClick.count);
// Since all buttons are treated equally, we don't need to check which button
//if (button == myCurrentClickDown.button)
myCurrentMouseDown.button = -1;
break;
case EVENT_WHEELUP:
@ -165,8 +225,7 @@ void DialogContainer::handleMouseButtonEvent(MouseButton b, int x, int y, uInt8
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void DialogContainer::handleJoyEvent(int x, int y, int stick, int button,
uInt8 state)
void DialogContainer::handleJoyEvent(int stick, int button, uInt8 state)
{
if(myDialogStack.empty())
return;
@ -174,7 +233,7 @@ void DialogContainer::handleJoyEvent(int x, int y, int stick, int button,
// Send the event to the dialog box on the top of the stack
Dialog* activeDialog = myDialogStack.top();
if(state == 1)
activeDialog->handleJoyDown(x, y, stick, button);
activeDialog->handleJoyDown(stick, button);
else
activeDialog->handleJoyUp(x, y, stick, button);
activeDialog->handleJoyUp(stick, button);
}

View File

@ -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.3 2005-05-25 23:22:11 stephena Exp $
// $Id: DialogContainer.hxx,v 1.4 2005-05-26 15:43:44 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.3 2005-05-25 23:22:11 stephena Exp $
@version $Id: DialogContainer.hxx,v 1.4 2005-05-26 15:43:44 stephena Exp $
*/
class DialogContainer
{
@ -53,6 +53,14 @@ class DialogContainer
virtual ~DialogContainer();
public:
/**
Update the dialog container with the current time.
This is useful if we want to trigger events at some specified time.
@param time The current time in microseconds
*/
void updateTime(uInt32 time);
/**
Handle a keyboard event.
@ -84,13 +92,11 @@ class DialogContainer
/**
Handle a joystick button event.
@param x The x location
@param y The y location
@param stick The joystick number
@param button The joystick button
@param state The state (pressed or released)
*/
void handleJoyEvent(int x, int y, int stick, int button, uInt8 state);
void handleJoyEvent(int stick, int button, uInt8 state);
/**
Draw the stack of menus.
@ -123,19 +129,38 @@ class DialogContainer
Dialog* myBaseDialog;
DialogStack myDialogStack;
enum {
kDoubleClickDelay = 500,
kKeyRepeatInitialDelay = 400,
kKeyRepeatSustainDelay = 50,
kClickRepeatInitialDelay = kKeyRepeatInitialDelay,
kClickRepeatSustainDelay = kKeyRepeatSustainDelay
};
// Indicates the most current time (in milliseconds) as set by updateTime()
uInt32 myTime;
// For continuous events (keyDown)
struct {
int ascii;
uInt8 flags;
int keycode;
uInt8 flags;
} myCurrentKeyDown;
int myKeyRepeatTime;
uInt32 myKeyRepeatTime;
// For continuous events (mouseDown)
struct {
int x;
int y;
int button;
} myCurrentMouseDown;
uInt32 myClickRepeatTime;
// Position and time of last mouse click (used to detect double clicks)
struct {
int x, y; // Position of mouse when the click occured
int time; // Time
int count; // How often was it already pressed?
int x, y; // Position of mouse when the click occured
uInt32 time; // Time
int count; // How often was it already pressed?
} myLastClick;
};

View File

@ -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: EventMappingDialog.cxx,v 1.11 2005-05-25 23:22:11 stephena Exp $
// $Id: EventMappingDialog.cxx,v 1.12 2005-05-26 15:43:44 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
@ -191,7 +191,7 @@ void EventMappingDialog::handleKeyDown(int ascii, int keycode, int modifiers)
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void EventMappingDialog::handleJoyDown(int x, int y, int stick, int button)
void EventMappingDialog::handleJoyDown(int stick, int button)
{
// Remap joystick buttons in remap mode, otherwise pass to listwidget
if(myRemapStatus && myActionSelected >= 0)
@ -202,7 +202,7 @@ void EventMappingDialog::handleJoyDown(int x, int y, int stick, int button)
stopRemapping();
}
else
myActionsList->handleJoyDown(x, y, stick, button);
myActionsList->handleJoyDown(stick, button);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -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: EventMappingDialog.hxx,v 1.8 2005-05-25 23:22:11 stephena Exp $
// $Id: EventMappingDialog.hxx,v 1.9 2005-05-26 15:43:44 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
@ -40,7 +40,7 @@ class EventMappingDialog : public Dialog
~EventMappingDialog();
virtual void handleKeyDown(int ascii, int keycode, int modifiers);
virtual void handleJoyDown(int x, int y, int stick, int button);
virtual void handleJoyDown(int stick, int button);
protected:
ButtonWidget* myMapButton;

View File

@ -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.12 2005-05-25 23:22:11 stephena Exp $
// $Id: Widget.hxx,v 1.13 2005-05-26 15:43:44 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
@ -65,7 +65,7 @@ enum {
This is the base class for all widgets.
@author Stephen Anthony
@version $Id: Widget.hxx,v 1.12 2005-05-25 23:22:11 stephena Exp $
@version $Id: Widget.hxx,v 1.13 2005-05-26 15:43:44 stephena Exp $
*/
class Widget : public GuiObject
{
@ -86,8 +86,8 @@ class Widget : public GuiObject
virtual void handleMouseWheel(int x, int y, int direction) {}
virtual bool handleKeyDown(int ascii, int keycode, int modifiers) { return false; }
virtual bool handleKeyUp(int ascii, int keycode, int modifiers) { return false; }
virtual void handleJoyDown(int x, int y, int stick, int button) {}
virtual void handleJoyUp(int x, int y, int stick, int button) {}
virtual void handleJoyDown(int stick, int button) {}
virtual void handleJoyUp(int stick, int button) {}
virtual void handleTickle() {}
void draw();

View File

@ -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: OSystemUNIX.cxx,v 1.9 2005-05-25 17:17:38 stephena Exp $
// $Id: OSystemUNIX.cxx,v 1.10 2005-05-26 15:43:44 stephena Exp $
//============================================================================
#include <cstdlib>
@ -96,7 +96,7 @@ void OSystemUNIX::mainLoop()
break;
startTime = getTicks();
myEventHandler->poll();
myEventHandler->poll(startTime);
myFrameBuffer->update();
// Now, waste time if we need to so that we are at the desired frame rate
@ -129,7 +129,7 @@ void OSystemUNIX::mainLoop()
break;
startTime = getTicks();
myEventHandler->poll();
myEventHandler->poll(startTime);
myFrameBuffer->update();
currentTime = getTicks();