Re-added double-click support to the list widget. This will be needed when I

add the ROM launcher, as double-clicking on a game will start it.

More cleanups/re-additions for the ListWidget class.  It now supports more
complete navigation with the keyboard (as opposed to just using the mouse).


git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@406 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
stephena 2005-05-03 19:11:27 +00:00
parent 6bc6dedf39
commit 2173b7701b
3 changed files with 120 additions and 68 deletions

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of // See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES. // this file, and for a DISCLAIMER OF ALL WARRANTIES.
// //
// $Id: ListWidget.cxx,v 1.2 2005-04-24 01:57:47 stephena Exp $ // $Id: ListWidget.cxx,v 1.3 2005-05-03 19:11:25 stephena Exp $
// //
// Based on code from ScummVM - Scumm Interpreter // Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project // Copyright (C) 2002-2004 The ScummVM project
@ -201,9 +201,6 @@ static int matchingCharsIgnoringCase(const char* x, const char* y, bool& stop)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool ListWidget::handleKeyDown(uInt16 ascii, Int32 keycode, Int32 modifiers) bool ListWidget::handleKeyDown(uInt16 ascii, Int32 keycode, Int32 modifiers)
{ {
cerr << "ListWidget::handleKeyDown()\n";
return false; // FIXME - do something with this method ...
/*
bool handled = true; bool handled = true;
bool dirty = false; bool dirty = false;
Int32 oldSelectedItem = _selectedItem; Int32 oldSelectedItem = _selectedItem;
@ -215,12 +212,12 @@ return false; // FIXME - do something with this method ...
// Only works in a useful fashion if the list entries are sorted. // Only works in a useful fashion if the list entries are sorted.
// TODO: Maybe this should be off by default, and instead we add a // TODO: Maybe this should be off by default, and instead we add a
// method "enableQuickSelect()" or so ? // method "enableQuickSelect()" or so ?
uInt32 time = g_system->getMillis(); uInt32 time = instance()->getTicks() / 1000;
if (_quickSelectTime < time) if (_quickSelectTime < time)
_quickSelectStr = (char)ascii; _quickSelectStr = (char)ascii;
else else
_quickSelectStr += (char)ascii; _quickSelectStr += (char)ascii;
cerr << "_quickSelectStr = " << _quickSelectStr << endl;
_quickSelectTime = time + 300; // TODO: Turn this into a proper constant (kQuickSelectDelay ?) _quickSelectTime = time + 300; // TODO: Turn this into a proper constant (kQuickSelectDelay ?)
// FIXME: This is bad slow code (it scans the list linearly each time a // FIXME: This is bad slow code (it scans the list linearly each time a
@ -238,7 +235,9 @@ return false; // FIXME - do something with this method ...
_selectedItem = newSelectedItem; _selectedItem = newSelectedItem;
bestMatch = match; bestMatch = match;
if (stop) if (stop)
{cerr << *i << endl;
break; break;
}
} }
newSelectedItem++; newSelectedItem++;
} }
@ -252,21 +251,21 @@ return false; // FIXME - do something with this method ...
switch (keycode) switch (keycode)
{ {
case '\n': // enter/return case '\n': // enter/return
case '\r': case '\r':
// confirm edit and exit editmode // confirm edit and exit editmode
_editMode = false; _editMode = false;
dirty = true; dirty = true;
sendCommand(kListItemActivatedCmd, _selectedItem); sendCommand(kListItemActivatedCmd, _selectedItem);
break; break;
case 27: // escape case 27: // escape
// abort edit and exit editmode // abort edit and exit editmode
_editMode = false; _editMode = false;
dirty = true; dirty = true;
_list[_selectedItem] = _backupString; _list[_selectedItem] = _backupString;
break; break;
case 8: // backspace case 8: // backspace
_list[_selectedItem].deleteLastChar(); _list[_selectedItem].erase(_list[_selectedItem].length()-1);
dirty = true; dirty = true;
break; break;
default: default:
@ -279,65 +278,73 @@ return false; // FIXME - do something with this method ...
handled = false; handled = false;
} }
} }
else else // not editmode
{ {
// not editmode switch (keycode)
{
case '\n': // enter/return
case '\r':
if (_selectedItem >= 0)
{
// override continuous enter keydown
if (_editable && (_currentKeyDown != '\n' && _currentKeyDown != '\r'))
{
dirty = true;
_editMode = true;
_backupString = _list[_selectedItem];
}
else
sendCommand(kListItemActivatedCmd, _selectedItem);
}
break;
switch (keycode) { case 256+17: // up arrow
case '\n': // enter/return if (_selectedItem > 0)
case '\r': _selectedItem--;
if (_selectedItem >= 0) { break;
// override continuous enter keydown
if (_editable && (_currentKeyDown != '\n' && _currentKeyDown != '\r')) {
dirty = true;
_editMode = true;
_backupString = _list[_selectedItem];
} else
sendCommand(kListItemActivatedCmd, _selectedItem);
}
break;
case 256+17: // up arrow
if (_selectedItem > 0)
_selectedItem--;
break;
case 256+18: // down arrow
if (_selectedItem < (int)_list.size() - 1)
_selectedItem++;
break;
case 256+24: // pageup
_selectedItem -= _entriesPerPage - 1;
if (_selectedItem < 0)
_selectedItem = 0;
break;
case 256+25: // pagedown
_selectedItem += _entriesPerPage - 1;
if (_selectedItem >= (int)_list.size() )
_selectedItem = _list.size() - 1;
break;
case 256+22: // home
_selectedItem = 0;
break;
case 256+23: // end
_selectedItem = _list.size() - 1;
break;
default:
handled = false;
}
scrollToCurrent(); case 256+18: // down arrow
} if (_selectedItem < (int)_list.size() - 1)
_selectedItem++;
break;
if (dirty || _selectedItem != oldSelectedItem) case 256+24: // pageup
draw(); _selectedItem -= _entriesPerPage - 1;
if (_selectedItem < 0)
_selectedItem = 0;
break;
if (_selectedItem != oldSelectedItem) { case 256+25: // pagedown
sendCommand(kListSelectionChangedCmd, _selectedItem); _selectedItem += _entriesPerPage - 1;
// also draw scrollbar if (_selectedItem >= (int)_list.size() )
_scrollBar->draw(); _selectedItem = _list.size() - 1;
} break;
return handled; case 256+22: // home
*/ _selectedItem = 0;
break;
case 256+23: // end
_selectedItem = _list.size() - 1;
break;
default:
handled = false;
}
scrollToCurrent();
}
if (dirty || _selectedItem != oldSelectedItem)
draw();
if (_selectedItem != oldSelectedItem)
{
sendCommand(kListSelectionChangedCmd, _selectedItem);
// also draw scrollbar
_scrollBar->draw();
}
return handled;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of // See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES. // this file, and for a DISCLAIMER OF ALL WARRANTIES.
// //
// $Id: Menu.cxx,v 1.5 2005-03-14 04:08:15 stephena Exp $ // $Id: Menu.cxx,v 1.6 2005-05-03 19:11:27 stephena Exp $
//============================================================================ //============================================================================
#include <SDL.h> #include <SDL.h>
@ -31,6 +31,11 @@ Menu::Menu(OSystem* osystem)
myOptionsDialog(NULL) myOptionsDialog(NULL)
{ {
myOSystem->attach(this); myOSystem->attach(this);
myCurrentKeyDown.keycode = 0;
myLastClick.x = myLastClick.y = 0;
myLastClick.time = 0;
myLastClick.count = 0;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -131,17 +136,42 @@ void Menu::handleMouseButtonEvent(MouseButton b, Int32 x, Int32 y, uInt8 state)
// Send the event to the dialog box on the top of the stack // Send the event to the dialog box on the top of the stack
Dialog* activeDialog = myDialogStack.top(); Dialog* activeDialog = myDialogStack.top();
// We don't currently use 'clickCount' // Get the current time for detecting double clicks
uInt32 time = myOSystem->getTicks() / 1000; // we only need millisecond precision
switch(b) switch(b)
{ {
case EVENT_LBUTTONDOWN: case EVENT_LBUTTONDOWN:
case EVENT_RBUTTONDOWN: case EVENT_RBUTTONDOWN:
activeDialog->handleMouseDown(x - activeDialog->_x, y - activeDialog->_y, 1, 1); // If more than two clicks have been recorded, we start over
if(myLastClick.count == 2)
{
myLastClick.x = myLastClick.y = 0;
myLastClick.time = 0;
myLastClick.count = 0;
}
if(myLastClick.count && (time < myLastClick.time + 500) // DoubleClickDelay
&& ABS(myLastClick.x - x) < 3
&& ABS(myLastClick.y - y) < 3)
{
myLastClick.count++;
}
else
{
myLastClick.x = x;
myLastClick.y = y;
myLastClick.count = 1;
}
myLastClick.time = time;
activeDialog->handleMouseDown(x - activeDialog->_x, y - activeDialog->_y,
1, myLastClick.count);
break; break;
case EVENT_LBUTTONUP: case EVENT_LBUTTONUP:
case EVENT_RBUTTONUP: case EVENT_RBUTTONUP:
activeDialog->handleMouseUp(x - activeDialog->_x, y - activeDialog->_y, 1, 1); activeDialog->handleMouseUp(x - activeDialog->_x, y - activeDialog->_y,
1, myLastClick.count);
break; break;
case EVENT_WHEELUP: case EVENT_WHEELUP:

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of // See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES. // this file, and for a DISCLAIMER OF ALL WARRANTIES.
// //
// $Id: Menu.hxx,v 1.5 2005-03-27 03:07:34 stephena Exp $ // $Id: Menu.hxx,v 1.6 2005-05-03 19:11:27 stephena Exp $
//============================================================================ //============================================================================
#ifndef MENU_HXX #ifndef MENU_HXX
@ -39,7 +39,7 @@ typedef FixedStack<Dialog *> DialogStack;
a stack, and handles their events. a stack, and handles their events.
@author Stephen Anthony @author Stephen Anthony
@version $Id: Menu.hxx,v 1.5 2005-03-27 03:07:34 stephena Exp $ @version $Id: Menu.hxx,v 1.6 2005-05-03 19:11:27 stephena Exp $
*/ */
class Menu class Menu
{ {
@ -122,6 +122,21 @@ class Menu
OSystem* myOSystem; OSystem* myOSystem;
OptionsDialog* myOptionsDialog; OptionsDialog* myOptionsDialog;
DialogStack myDialogStack; DialogStack myDialogStack;
// For continuous events (keyDown)
struct {
uInt16 ascii;
uInt8 flags;
uInt32 keycode;
} myCurrentKeyDown;
uInt32 myKeyRepeatTime;
// Position and time of last mouse click (used to detect double clicks)
struct {
Int16 x, y; // Position of mouse when the click occured
uInt32 time; // Time
Int32 count; // How often was it already pressed?
} myLastClick;
}; };
#endif #endif