Updated ListWidget to extend EditableWidget class (new code from ScummVM

CVS).  This means you can now edit the contents of a ListWidget, and
do something with those new contents based on the signal that's emitted.


git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@499 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
stephena 2005-06-15 15:34:35 +00:00
parent ab9e047d49
commit eb792b159a
3 changed files with 163 additions and 174 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: CheatWidget.cxx,v 1.3 2005-06-14 18:55:36 stephena Exp $ // $Id: CheatWidget.cxx,v 1.4 2005-06-15 15:34:35 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
@ -122,6 +122,18 @@ void CheatWidget::handleCommand(CommandSender* sender, int cmd, int data)
case kRestartCmd: case kRestartCmd:
doRestart(); doRestart();
break; break;
case kListItemDataChangedCmd:
cerr << "data changed\n";
break;
case kListItemDoubleClickedCmd:
cerr << "kListItemDoubleClickedCmd\n";
break;
case kListItemActivatedCmd:
cerr << "kListItemActivatedCmd\n";
break;
} }
} }

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.15 2005-06-14 01:11:48 stephena Exp $ // $Id: ListWidget.cxx,v 1.16 2005-06-15 15:34:35 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
@ -30,15 +30,17 @@
#include "ListWidget.hxx" #include "ListWidget.hxx"
#include "bspf.hxx" #include "bspf.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ListWidget::ListWidget(GuiObject* boss, int x, int y, int w, int h) ListWidget::ListWidget(GuiObject* boss, int x, int y, int w, int h)
: Widget(boss, x, y, w - kScrollBarWidth, h), : EditableWidget(boss, x, y, w, h),
CommandSender(boss) CommandSender(boss)
{ {
_w = w - kScrollBarWidth;
_flags = WIDGET_ENABLED | WIDGET_CLEARBG | WIDGET_RETAIN_FOCUS | _flags = WIDGET_ENABLED | WIDGET_CLEARBG | WIDGET_RETAIN_FOCUS |
WIDGET_TAB_NAVIGATE; WIDGET_TAB_NAVIGATE;
_type = kListWidget; _type = kListWidget;
_editMode = false;
_numberingMode = kListNumberingOne; _numberingMode = kListNumberingOne;
_entriesPerPage = (_h - 2) / kLineHeight; _entriesPerPage = (_h - 2) / kLineHeight;
_currentPos = 0; _currentPos = 0;
@ -47,15 +49,14 @@ ListWidget::ListWidget(GuiObject* boss, int x, int y, int w, int h)
_scrollBar->setTarget(this); _scrollBar->setTarget(this);
_currentKeyDown = 0; _currentKeyDown = 0;
_caretVisible = false;
_caretTime = 0;
_quickSelectTime = 0; _quickSelectTime = 0;
// The item is selected, thus _bgcolor is used to draw the caret and
// _textcolorhi to erase it
_caretInverse = true;
// FIXME: This flag should come from widget definition // FIXME: This flag should come from widget definition
_editable = true; _editable = true;
_editMode = false;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -68,38 +69,26 @@ void ListWidget::setSelected(int item)
{ {
assert(item >= -1 && item < (int)_list.size()); assert(item >= -1 && item < (int)_list.size());
if(isEnabled() && _selectedItem != item) if (isEnabled() && _selectedItem != item)
{ {
int oldSelectedItem = _selectedItem;
_selectedItem = item;
if (_editMode) if (_editMode)
{ abortEditMode();
// undo any changes made
_list[oldSelectedItem] = _backupString;
_editMode = false;
drawCaret(true);
}
_selectedItem = item;
sendCommand(kListSelectionChangedCmd, _selectedItem); sendCommand(kListSelectionChangedCmd, _selectedItem);
_currentPos = _selectedItem - _entriesPerPage / 2; _currentPos = _selectedItem - _entriesPerPage / 2;
scrollToCurrent(); scrollToCurrent();
draw(); draw();
instance()->frameBuffer().refresh();
_boss->instance()->frameBuffer().refresh();
} }
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void ListWidget::setList(const StringList& list) void ListWidget::setList(const StringList& list)
{ {
if (_editMode && _caretVisible)
drawCaret(true);
int size = list.size(); int size = list.size();
_list = list; _list = list;
if (_currentPos >= size) if (_currentPos >= size)
_currentPos = size - 1; _currentPos = size - 1;
if (_currentPos < 0) if (_currentPos < 0)
@ -137,31 +126,31 @@ void ListWidget::scrollBarRecalc()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void ListWidget::handleMouseDown(int x, int y, int button, int clickCount) void ListWidget::handleMouseDown(int x, int y, int button, int clickCount)
{ {
if (isEnabled()) if (!isEnabled())
return;
// A click indicates this widget has been selected
// It should receive focus (because it has the WIDGET_TAB_NAVIGATE property)
receivedFocus();
// First check whether the selection changed
int newSelectedItem;
newSelectedItem = findItem(x, y);
if (newSelectedItem > (int)_list.size() - 1)
newSelectedItem = -1;
if (_selectedItem != newSelectedItem)
{ {
// A click indicated this widget has been selected if (_editMode)
// It should receive focus (because it has the WIDGET_TAB_NAVIGATE property) abortEditMode();
receivedFocus(); _selectedItem = newSelectedItem;
sendCommand(kListSelectionChangedCmd, _selectedItem);
int oldSelectedItem = _selectedItem; instance()->frameBuffer().refresh();
_selectedItem = (y - 1) / kLineHeight + _currentPos;
if (_selectedItem > (int)_list.size() - 1)
_selectedItem = -1;
if (oldSelectedItem != _selectedItem)
{
if (_editMode)
{
// undo any changes made
_list[oldSelectedItem] = _backupString;
_editMode = false;
drawCaret(true);
}
sendCommand(kListSelectionChangedCmd, _selectedItem);
_boss->instance()->frameBuffer().refresh();
}
draw();
} }
// TODO: Determine where inside the string the user clicked and place the
// caret accordingly. See _editScrollOffset and EditTextWidget::handleMouseDown.
draw();
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -169,8 +158,14 @@ void ListWidget::handleMouseUp(int x, int y, int button, int clickCount)
{ {
// If this was a double click and the mouse is still over the selected item, // If this was a double click and the mouse is still over the selected item,
// send the double click command // send the double click command
if (clickCount == 2 && (_selectedItem == (y - 1) / kLineHeight + _currentPos)) if (clickCount == 2 && (_selectedItem == findItem(x, y)))
{
sendCommand(kListItemDoubleClickedCmd, _selectedItem); sendCommand(kListItemDoubleClickedCmd, _selectedItem);
// Start edit mode
if(_editable && !_editMode)
startEditMode();
}
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -179,6 +174,12 @@ void ListWidget::handleMouseWheel(int x, int y, int direction)
_scrollBar->handleMouseWheel(x, y, direction); _scrollBar->handleMouseWheel(x, y, direction);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
int ListWidget::findItem(int x, int y) const
{
return (y - 1) / kLineHeight + _currentPos;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
static bool matchingCharsIgnoringCase(string s, string pattern) static bool matchingCharsIgnoringCase(string s, string pattern)
{ {
@ -202,7 +203,7 @@ bool ListWidget::handleKeyDown(int ascii, int keycode, int modifiers)
bool dirty = false; bool dirty = false;
int oldSelectedItem = _selectedItem; int oldSelectedItem = _selectedItem;
if (!_editMode && isalnum((char)ascii)) if (!_editMode && isalpha((char)ascii))
{ {
// Quick selection mode: Go to first list item starting with this key // Quick selection mode: Go to first list item starting with this key
// (or a substring accumulated from the last couple key presses). // (or a substring accumulated from the last couple key presses).
@ -215,8 +216,6 @@ bool ListWidget::handleKeyDown(int ascii, int keycode, int modifiers)
else else
_quickSelectStr += (char)ascii; _quickSelectStr += (char)ascii;
_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
// key is pressed); it could be much faster. Only of importance if we have // key is pressed); it could be much faster. Only of importance if we have
// quite big lists to deal with -- so for now we can live with this lazy // quite big lists to deal with -- so for now we can live with this lazy
@ -232,48 +231,19 @@ bool ListWidget::handleKeyDown(int ascii, int keycode, int modifiers)
} }
newSelectedItem++; newSelectedItem++;
} }
scrollToCurrent(); scrollToCurrent();
} }
else if (_editMode) else if (_editMode)
{ {
if (_caretVisible) // Class EditableWidget handles all text editing related key presses for us
drawCaret(true); handled = EditableWidget::handleKeyDown(ascii, keycode, modifiers);
switch (keycode)
{
case '\n': // enter/return
case '\r':
// confirm edit and exit editmode
_editMode = false;
dirty = true;
sendCommand(kListItemActivatedCmd, _selectedItem);
break;
case 27: // escape
// abort edit and exit editmode
_editMode = false;
dirty = true;
_list[_selectedItem] = _backupString;
break;
case 8: // backspace
_list[_selectedItem].erase(_list[_selectedItem].length()-1);
dirty = true;
break;
default:
if (isprint(ascii))
{
_list[_selectedItem] += (char)ascii;
dirty = true;
}
else
handled = false;
}
} }
else // not editmode else
{ {
// not editmode
switch (keycode) switch (keycode)
{ {
case '\n': // enter/return case '\n': // enter/return
case '\r': case '\r':
if (_selectedItem >= 0) if (_selectedItem >= 0)
{ {
@ -281,47 +251,47 @@ bool ListWidget::handleKeyDown(int ascii, int keycode, int modifiers)
if (_editable && (_currentKeyDown != '\n' && _currentKeyDown != '\r')) if (_editable && (_currentKeyDown != '\n' && _currentKeyDown != '\r'))
{ {
dirty = true; dirty = true;
_editMode = true; startEditMode();
_backupString = _list[_selectedItem];
} }
else else
sendCommand(kListItemActivatedCmd, _selectedItem); sendCommand(kListItemActivatedCmd, _selectedItem);
} }
break; break;
case 256+17: // up arrow case 256+17: // up arrow
if (_selectedItem > 0) if (_selectedItem > 0)
_selectedItem--; _selectedItem--;
break; break;
case 256+18: // down arrow case 256+18: // down arrow
if (_selectedItem < (int)_list.size() - 1) if (_selectedItem < (int)_list.size() - 1)
_selectedItem++; _selectedItem++;
break; break;
case 256+24: // pageup case 256+24: // pageup
_selectedItem -= _entriesPerPage - 1; _selectedItem -= _entriesPerPage - 1;
if (_selectedItem < 0) if (_selectedItem < 0)
_selectedItem = 0; _selectedItem = 0;
break; break;
case 256+25: // pagedown case 256+25: // pagedown
_selectedItem += _entriesPerPage - 1; _selectedItem += _entriesPerPage - 1;
if (_selectedItem >= (int)_list.size() ) if (_selectedItem >= (int)_list.size() )
_selectedItem = _list.size() - 1; _selectedItem = _list.size() - 1;
break; break;
case 256+22: // home case 256+22: // home
_selectedItem = 0; _selectedItem = 0;
break; break;
case 256+23: // end case 256+23: // end
_selectedItem = _list.size() - 1; _selectedItem = _list.size() - 1;
break; break;
default: default:
handled = false; handled = false;
} }
scrollToCurrent(); scrollToCurrent();
} }
@ -334,9 +304,10 @@ bool ListWidget::handleKeyDown(int ascii, int keycode, int modifiers)
// also draw scrollbar // also draw scrollbar
_scrollBar->draw(); _scrollBar->draw();
_boss->instance()->frameBuffer().refresh(); instance()->frameBuffer().refresh();
} }
_currentKeyDown = keycode;
return handled; return handled;
} }
@ -352,7 +323,6 @@ bool ListWidget::handleKeyUp(int ascii, int keycode, int modifiers)
void ListWidget::lostFocusWidget() void ListWidget::lostFocusWidget()
{ {
_editMode = false; _editMode = false;
drawCaret(true);
draw(); draw();
} }
@ -377,6 +347,7 @@ void ListWidget::drawWidget(bool hilite)
FrameBuffer& fb = _boss->instance()->frameBuffer(); FrameBuffer& fb = _boss->instance()->frameBuffer();
int i, pos, len = _list.size(); int i, pos, len = _list.size();
string buffer; string buffer;
int deltax;
// Draw a thin frame around the list. // Draw a thin frame around the list.
fb.hLine(_x, _y, _x + _w - 1, kColor); fb.hLine(_x, _y, _x + _w - 1, kColor);
@ -386,67 +357,69 @@ void ListWidget::drawWidget(bool hilite)
// Draw the list items // Draw the list items
for (i = 0, pos = _currentPos; i < _entriesPerPage && pos < len; i++, pos++) for (i = 0, pos = _currentPos; i < _entriesPerPage && pos < len; i++, pos++)
{ {
if (_numberingMode == kListNumberingZero || _numberingMode == kListNumberingOne) const OverlayColor textColor = (_selectedItem == pos && _hasFocus)
{ ? kBGColor : kTextColor;
char temp[10]; const int y = _y + 2 + kLineHeight * i;
sprintf(temp, "%2d. ", (pos + _numberingMode));
buffer = temp;
buffer += _list[pos];
}
else
buffer = _list[pos];
// Draw the selected item inverted, on a highlighted background.
if (_selectedItem == pos) if (_selectedItem == pos)
{ {
if (_hasFocus) if (_hasFocus && !_editMode)
fb.fillRect(_x + 1, _y + 1 + kLineHeight * i, _w - 1, kLineHeight, kTextColorHi); fb.fillRect(_x + 1, _y + 1 + kLineHeight * i, _w - 1, kLineHeight, kTextColorHi);
else else
fb.frameRect(_x + 1, _y + 1 + kLineHeight * i, _w - 1, kLineHeight, kTextColorHi); fb.frameRect(_x + 1, _y + 1 + kLineHeight * i, _w - 1, kLineHeight, kTextColorHi);
} }
fb.drawString(_font, buffer, _x + 2, _y + 2 + kLineHeight * i, _w - 4,
(_selectedItem == pos && _hasFocus) ? kBGColor : kTextColor); // If in numbering mode, we first print a number prefix
if (_numberingMode != kListNumberingOff)
{
char temp[10];
sprintf(temp, "%2d. ", (pos + _numberingMode));
buffer = temp;
fb.drawString(_font, buffer, _x + 2, y, _w - 4, textColor);
}
GUI::Rect r(getEditRect());
if (_selectedItem == pos && _editMode)
{
buffer = _editString;
adjustOffset();
deltax = -_editScrollOffset;
fb.drawString(_font, buffer, _x + r.left, y, r.width(), kTextColor,
kTextAlignLeft, deltax, false);
}
else
{
buffer = _list[pos];
deltax = 0;
fb.drawString(_font, buffer, _x + r.left, y, r.width(), kTextColor);
}
} }
// Only draw the caret while editing, and if it's in the current viewport
if(_editMode && (_selectedItem >= _scrollBar->_currentPos) &&
(_selectedItem < _scrollBar->_currentPos + _entriesPerPage))
drawCaret();
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
int ListWidget::getCaretPos() const GUI::Rect ListWidget::getEditRect() const
{ {
int caretpos = 0; GUI::Rect r(2, 1, _w - 2 , kLineHeight);
const int offset = (_selectedItem - _currentPos) * kLineHeight;
r.top += offset;
r.bottom += offset;
if (_numberingMode == kListNumberingZero || _numberingMode == kListNumberingOne) if (_numberingMode != kListNumberingOff)
{ {
char temp[10]; char temp[10];
sprintf(temp, "%2d. ", (_selectedItem + _numberingMode)); // FIXME: Assumes that all digits have the same width.
caretpos += _font->getStringWidth(temp); sprintf(temp, "%2d. ", (_list.size() - 1 + _numberingMode));
r.left += _font->getStringWidth(temp);
} }
caretpos += _font->getStringWidth(_list[_selectedItem]); return r;
return caretpos;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void ListWidget::drawCaret(bool erase)
{
// Only draw if item is visible
if (_selectedItem < _currentPos || _selectedItem >= _currentPos + _entriesPerPage)
return;
if (!isVisible() || !_boss->isVisible())
return;
FrameBuffer& fb = _boss->instance()->frameBuffer();
// The item is selected, thus _bgcolor is used to draw the caret and _textcolorhi to erase it
OverlayColor color = erase ? kTextColorHi : kBGColor;
int x = getAbsX() + 3;
int y = getAbsY() + 1;
y += (_selectedItem - _currentPos) * kLineHeight;
x += getCaretPos();
fb.vLine(x, y, y+kLineHeight, color);
_caretVisible = !erase;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -473,30 +446,35 @@ void ListWidget::scrollToCurrent()
_scrollBar->recalc(); _scrollBar->recalc();
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void ListWidget::startEditMode() void ListWidget::startEditMode()
{ {
cerr << "ListWidget::startEditMode()\n"; cerr << "ListWidget::startEditMode()\n";
if (_editable && !_editMode && _selectedItem >= 0) if (_editable && !_editMode && _selectedItem >= 0)
{ {
_editMode = true; _editMode = true;
_backupString = _list[_selectedItem]; setEditString(_list[_selectedItem]);
draw(); draw();
} }
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void ListWidget::endEditMode()
{
if (!_editMode)
return;
// send a message that editing finished with a return/enter key press
_editMode = false;
_list[_selectedItem] = _editString;
sendCommand(kListItemDataChangedCmd, _selectedItem);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void ListWidget::abortEditMode() void ListWidget::abortEditMode()
{ {
cerr << "ListWidget::abortEditMode()\n"; cerr << "ListWidget::abortEditMode()\n";
// undo any changes made
if (_editMode) assert(_selectedItem >= 0);
{ _editMode = false;
_editMode = false;
_list[_selectedItem] = _backupString;
drawCaret(true);
draw();
}
} }

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.hxx,v 1.4 2005-06-07 01:14:39 stephena Exp $ // $Id: ListWidget.hxx,v 1.5 2005-06-15 15:34:35 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
@ -24,10 +24,12 @@
#include "GuiObject.hxx" #include "GuiObject.hxx"
#include "Widget.hxx" #include "Widget.hxx"
#include "ScrollBarWidget.hxx"
#include "Command.hxx" #include "Command.hxx"
#include "StringList.hxx" #include "StringList.hxx"
#include "bspf.hxx" #include "EditableWidget.hxx"
#include "Rect.hxx"
class ScrollBarWidget;
enum NumberingMode { enum NumberingMode {
kListNumberingOff = -1, kListNumberingOff = -1,
@ -39,12 +41,12 @@ enum NumberingMode {
enum { enum {
kListItemDoubleClickedCmd = 'LIdb', // double click on item - 'data' will be item index kListItemDoubleClickedCmd = 'LIdb', // double click on item - 'data' will be item index
kListItemActivatedCmd = 'LIac', // item activated by return/enter - 'data' will be item index kListItemActivatedCmd = 'LIac', // item activated by return/enter - 'data' will be item index
kListItemDataChangedCmd = 'LIch', // item data changed - 'data' will be item index
kListSelectionChangedCmd = 'Lsch' // selection changed - 'data' will be item index kListSelectionChangedCmd = 'Lsch' // selection changed - 'data' will be item index
}; };
/* ListWidget */ /* ListWidget */
class ListWidget : public Widget, public CommandSender class ListWidget : public EditableWidget, public CommandSender
{ {
public: public:
ListWidget(GuiObject* boss, int x, int y, int w, int h); ListWidget(GuiObject* boss, int x, int y, int w, int h);
@ -57,35 +59,35 @@ class ListWidget : public Widget, public CommandSender
const string& getSelectedString() const { return _list[_selectedItem]; } const string& getSelectedString() const { return _list[_selectedItem]; }
bool isEditable() const { return _editable; } bool isEditable() const { return _editable; }
void setEditable(bool editable) { _editable = editable; } void setEditable(bool editable) { _editable = editable; }
void setNumberingMode(NumberingMode numberingMode) { _numberingMode = numberingMode; } void setNumberingMode(NumberingMode numberingMode) { _numberingMode = numberingMode; }
void scrollTo(int item); void scrollTo(int item);
virtual void handleMouseDown(int x, int y, int button, int clickCount); virtual void handleMouseDown(int x, int y, int button, int clickCount);
virtual void handleMouseUp(int x, int y, int button, int clickCount); virtual void handleMouseUp(int x, int y, int button, int clickCount);
virtual void handleMouseWheel(int x, int y, int direction); virtual void handleMouseWheel(int x, int y, int direction);
virtual void handleMouseEntered(int button) {};
virtual void handleMouseLeft(int button) {};
virtual bool handleKeyDown(int ascii, int keycode, int modifiers); virtual bool handleKeyDown(int ascii, int keycode, int modifiers);
virtual bool handleKeyUp(int ascii, int keycode, int modifiers); virtual bool handleKeyUp(int ascii, int keycode, int modifiers);
virtual void handleCommand(CommandSender* sender, int cmd, int data); virtual void handleCommand(CommandSender* sender, int cmd, int data);
virtual bool wantsFocus() { return true; }; virtual bool wantsFocus() { return true; }
void scrollBarRecalc();
void startEditMode(); void startEditMode();
void abortEditMode(); void endEditMode();
protected: protected:
void drawWidget(bool hilite); void drawWidget(bool hilite);
int getCaretPos() const; int findItem(int x, int y) const;
void drawCaret(bool erase); void scrollBarRecalc();
void abortEditMode();
GUI::Rect getEditRect() const;
void lostFocusWidget(); void lostFocusWidget();
void scrollToCurrent(); void scrollToCurrent();
protected: protected:
StringList _list; StringList _list;
bool _editable; bool _editable;
bool _editMode; bool _editMode;
@ -97,9 +99,6 @@ class ListWidget : public Widget, public CommandSender
int _currentKeyDown; int _currentKeyDown;
string _backupString; string _backupString;
bool _caretVisible;
int _caretTime;
string _quickSelectStr; string _quickSelectStr;
int _quickSelectTime; int _quickSelectTime;
}; };