aboutsummaryrefslogtreecommitdiff
path: root/gui/ListWidget.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'gui/ListWidget.cpp')
-rw-r--r--gui/ListWidget.cpp149
1 files changed, 67 insertions, 82 deletions
diff --git a/gui/ListWidget.cpp b/gui/ListWidget.cpp
index 5bd59827cb..515f2850f5 100644
--- a/gui/ListWidget.cpp
+++ b/gui/ListWidget.cpp
@@ -28,7 +28,7 @@
namespace GUI {
ListWidget::ListWidget(GuiObject *boss, int x, int y, int w, int h)
- : Widget(boss, x, y, w - kScrollBarWidth, h), CommandSender(boss) {
+ : EditableWidget(boss, x, y, w - kScrollBarWidth, h), CommandSender(boss) {
_flags = WIDGET_ENABLED | WIDGET_CLEARBG | WIDGET_RETAIN_FOCUS | WIDGET_WANT_TICKLE;
_type = kListWidget;
_numberingMode = kListNumberingOne;
@@ -38,16 +38,14 @@ ListWidget::ListWidget(GuiObject *boss, int x, int y, int w, int h)
_scrollBar = new ScrollBarWidget(boss, _x + _w, _y, kScrollBarWidth, _h);
_scrollBar->setTarget(this);
_currentKeyDown = 0;
-
- _caretVisible = false;
- _caretTime = 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
_editable = true;
-
- _editMode = false;
}
ListWidget::~ListWidget() {
@@ -57,16 +55,10 @@ void ListWidget::setSelected(int item) {
assert(item >= -1 && item < (int)_list.size());
if (isEnabled() && _selectedItem != item) {
- int oldSelectedItem = _selectedItem;
- _selectedItem = item;
-
- if (_editMode) {
- // undo any changes made
- _list[oldSelectedItem] = _backupString;
- _editMode = false;
- drawCaret(true);
- }
+ if (_editMode)
+ abortEditMode();
+ _selectedItem = item;
sendCommand(kListSelectionChangedCmd, _selectedItem);
_currentPos = _selectedItem - _entriesPerPage / 2;
@@ -110,31 +102,31 @@ void ListWidget::scrollBarRecalc() {
}
void ListWidget::handleTickle() {
- uint32 time = getMillis();
- if (_editMode && _caretTime < time) {
- _caretTime = time + kCaretBlinkTime;
- drawCaret(_caretVisible);
- }
+ if (_editMode)
+ EditableWidget::handleTickle();
}
void ListWidget::handleMouseDown(int x, int y, int button, int clickCount) {
- if (isEnabled()) {
- int oldSelectedItem = _selectedItem;
- _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);
- }
- draw();
+ if (!isEnabled())
+ return;
+
+ // First check whether the selection changed
+ int newSelectedItem;
+ newSelectedItem = (y - 1) / kLineHeight + _currentPos;
+ if (newSelectedItem > (int)_list.size() - 1)
+ newSelectedItem = -1;
+
+ if (_selectedItem != newSelectedItem) {
+ if (_editMode)
+ abortEditMode();
+ _selectedItem = newSelectedItem;
+ sendCommand(kListSelectionChangedCmd, _selectedItem);
}
+
+ // TODO: Determine where inside the string the user clicked and place the
+ // caret accordingly.
+ draw();
+
}
void ListWidget::handleMouseUp(int x, int y, int button, int clickCount) {
@@ -209,23 +201,21 @@ bool ListWidget::handleKeyDown(uint16 ascii, int keycode, int modifiers) {
case '\n': // enter/return
case '\r':
// confirm edit and exit editmode
- _editMode = false;
+ endEditMode();
dirty = true;
- sendCommand(kListItemActivatedCmd, _selectedItem);
break;
case 27: // escape
// abort edit and exit editmode
- _editMode = false;
+ abortEditMode();
dirty = true;
- _list[_selectedItem] = _backupString;
break;
case 8: // backspace
- _list[_selectedItem].deleteLastChar();
+ _editString.deleteLastChar();
dirty = true;
break;
default:
if (isprint((char)ascii)) {
- _list[_selectedItem] += (char)ascii;
+ _editString += (char)ascii;
dirty = true;
} else {
handled = false;
@@ -242,8 +232,7 @@ bool ListWidget::handleKeyDown(uint16 ascii, int keycode, int modifiers) {
// override continuous enter keydown
if (_editable && (_currentKeyDown != '\n' && _currentKeyDown != '\r')) {
dirty = true;
- _editMode = true;
- _backupString = _list[_selectedItem];
+ startEditMode();
} else
sendCommand(kListItemActivatedCmd, _selectedItem);
}
@@ -303,6 +292,7 @@ bool ListWidget::handleKeyUp(uint16 ascii, int keycode, int modifiers) {
}
void ListWidget::lostFocusWidget() {
+ // If we loose focus, we simply forget the user changes
_editMode = false;
drawCaret(true);
draw();
@@ -331,13 +321,17 @@ void ListWidget::drawWidget(bool hilite) {
// Draw the list items
for (i = 0, pos = _currentPos; i < _entriesPerPage && pos < len; i++, pos++) {
- if (_numberingMode == kListNumberingZero || _numberingMode == kListNumberingOne) {
+ if (_numberingMode != kListNumberingOff) {
char temp[10];
sprintf(temp, "%2d. ", (pos + _numberingMode));
buffer = temp;
+ } else {
+ buffer.clear();
+ }
+ if (_selectedItem == pos && _editMode)
+ buffer += _editString;
+ else
buffer += _list[pos];
- } else
- buffer = _list[pos];
if (_selectedItem == pos) {
if (_hasFocus)
@@ -350,43 +344,27 @@ void ListWidget::drawWidget(bool hilite) {
}
}
-int ListWidget::getCaretPos() const {
- int caretpos = 0;
- NewGui *gui = &g_gui;
+Common::Rect ListWidget::getEditRect() const {
+ Common::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];
sprintf(temp, "%2d. ", (_selectedItem + _numberingMode));
- caretpos += gui->getStringWidth(temp);
+ r.left += g_gui.getStringWidth(temp);
}
-
- caretpos += gui->getStringWidth(_list[_selectedItem]);
- return caretpos;
+ return r;
}
-void ListWidget::drawCaret(bool erase) {
- // Only draw if item is visible
- if (_selectedItem < _currentPos || _selectedItem >= _currentPos + _entriesPerPage)
- return;
- if (!isVisible() || !_boss->isVisible())
- return;
-
- NewGui *gui = &g_gui;
-
- // The item is selected, thus _bgcolor is used to draw the caret and _textcolorhi to erase it
- int16 color = erase ? gui->_textcolorhi : gui->_bgcolor;
- int x = getAbsX() + 3;
- int y = getAbsY() + 1;
-
- y += (_selectedItem - _currentPos) * kLineHeight;
-
- x += getCaretPos();
+int ListWidget::getCaretOffset() const {
+ int caretpos = 0;
- gui->vLine(x, y, y+kLineHeight, color);
- gui->addDirtyRect(x, y, 2, kLineHeight);
+ caretpos += g_gui.getStringWidth(_editString);
- _caretVisible = !erase;
+ return caretpos;
}
void ListWidget::scrollToCurrent() {
@@ -411,18 +389,25 @@ void ListWidget::scrollToCurrent() {
void ListWidget::startEditMode() {
if (_editable && !_editMode && _selectedItem >= 0) {
_editMode = true;
- _backupString = _list[_selectedItem];
+ _editString = _list[_selectedItem];
+ _caretPos = _editString.size();
draw();
}
}
+void ListWidget::endEditMode() {
+ // send a message that editing finished with a return/enter key press
+ _editMode = false;
+ _list[_selectedItem] = _editString;
+ sendCommand(kListItemActivatedCmd, _selectedItem);
+}
+
void ListWidget::abortEditMode() {
- if (_editMode) {
- _editMode = false;
- _list[_selectedItem] = _backupString;
- drawCaret(true);
- draw();
- }
+ // undo any changes made
+ assert(_selectedItem >= 0);
+ _editMode = false;
+ //drawCaret(true);
+ //draw();
}
} // End of namespace GUI