mirror of https://github.com/stella-emu/stella.git
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:
parent
ab9e047d49
commit
eb792b159a
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue