aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gui/ListWidget.cpp27
-rw-r--r--gui/ListWidget.h7
-rw-r--r--gui/ScrollBarWidget.cpp14
-rw-r--r--gui/dialog.cpp34
-rw-r--r--gui/dialog.h5
-rw-r--r--gui/widget.cpp2
-rw-r--r--gui/widget.h3
7 files changed, 68 insertions, 24 deletions
diff --git a/gui/ListWidget.cpp b/gui/ListWidget.cpp
index 4607698447..b3b6e0c977 100644
--- a/gui/ListWidget.cpp
+++ b/gui/ListWidget.cpp
@@ -25,17 +25,13 @@
#include "newgui.h"
-// Height of one entry
-#define LINE_HEIGHT 10
-
-
ListWidget::ListWidget(Dialog *boss, int x, int y, int w, int h)
: Widget(boss, x, y, w - kScrollBarWidth, h), CommandSender(boss)
{
_flags = WIDGET_ENABLED | WIDGET_CLEARBG | WIDGET_RETAIN_FOCUS | WIDGET_WANT_TICKLE;
_type = kListWidget;
_numberingMode = kListNumberingOne;
- _entriesPerPage = (_h - 4) / LINE_HEIGHT;
+ _entriesPerPage = (_h - 2) / kLineHeight;
_currentPos = 0;
_selectedItem = -1;
_scrollBar = new ScrollBarWidget(boss, _x + _w, _y, kScrollBarWidth, _h);
@@ -65,7 +61,7 @@ void ListWidget::handleMouseDown(int x, int y, int button, int clickCount)
int oldSelectedItem = _selectedItem;
if (_flags & WIDGET_ENABLED) {
- _selectedItem = (y - 2) / LINE_HEIGHT + _currentPos;
+ _selectedItem = (y - 1) / kLineHeight + _currentPos;
if (_editMode && oldSelectedItem != _selectedItem) {
// undo any changes made
@@ -80,7 +76,7 @@ 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,
// send the double click command
- if (clickCount > 1 && (_selectedItem == (y - 2) / LINE_HEIGHT + _currentPos)) {
+ if (clickCount > 1 && (_selectedItem == (y - 1) / kLineHeight + _currentPos)) {
sendCommand(kListItemDoubleClickedCmd, _selectedItem);
}
}
@@ -220,6 +216,11 @@ void ListWidget::drawWidget(bool hilite)
int i, pos, len = _list.size();
ScummVM::String buffer;
+ // Draw a thin frame around the list.
+ gui->hline(_x, _y, _x+_w-1, gui->_color);
+ gui->hline(_x, _y+_h-1, _x+_w-1, gui->_shadowcolor);
+ gui->vline(_x, _y, _y+_h-1, gui->_color);
+
// Draw the list items
for (i = 0, pos = _currentPos; i < _entriesPerPage && pos < len; i++, pos++) {
if (_numberingMode == kListNumberingZero || _numberingMode == kListNumberingOne) {
@@ -230,9 +231,15 @@ void ListWidget::drawWidget(bool hilite)
buffer = "";
buffer += _list[pos];
-
- gui->drawString(buffer.c_str(), _x+5, _y+2 + LINE_HEIGHT * i, _w - 10,
- (_selectedItem == pos && _hasFocus) ? gui->_textcolorhi : gui->_textcolor);
+
+ if (_selectedItem == pos) {
+ if (_hasFocus)
+ gui->fillRect(_x+1, _y+1 + kLineHeight * i, _w - 1, kLineHeight, gui->_textcolorhi);
+ else
+ gui->frameRect(_x+1, _y+1 + kLineHeight * i, _w - 1, kLineHeight, gui->_textcolorhi);
+ }
+ gui->drawString(buffer.c_str(), _x+2, _y+3 + kLineHeight * i, _w - 4,
+ (_selectedItem == pos && _hasFocus) ? gui->_bgcolor : gui->_textcolor);
}
}
diff --git a/gui/ListWidget.h b/gui/ListWidget.h
index d275e32a07..c778b2e807 100644
--- a/gui/ListWidget.h
+++ b/gui/ListWidget.h
@@ -32,6 +32,11 @@ enum {
kListNumberingOne = 1
};
+// Height of a signle entry line
+enum {
+ kLineHeight = 11
+};
+
// Some special commands
enum {
kListItemDoubleClickedCmd = 'LIdb', // 'data' will be item index
@@ -69,6 +74,8 @@ public:
virtual bool handleKeyUp(char key, int modifiers);
virtual void handleCommand(CommandSender *sender, uint32 cmd, uint32 data);
+ virtual bool wantsFocus() { return true; };
+
void scrollBarRecalc();
protected:
diff --git a/gui/ScrollBarWidget.cpp b/gui/ScrollBarWidget.cpp
index a9af686215..98496ae891 100644
--- a/gui/ScrollBarWidget.cpp
+++ b/gui/ScrollBarWidget.cpp
@@ -110,12 +110,11 @@ void ScrollBarWidget::handleMouseMoved(int x, int y, int button)
if (_sliderPos < UP_DOWN_BOX_HEIGHT)
_sliderPos = UP_DOWN_BOX_HEIGHT;
- if (_sliderPos > _h - UP_DOWN_BOX_HEIGHT - _sliderHeight + 1)
- _sliderPos = _h - UP_DOWN_BOX_HEIGHT - _sliderHeight + 1;
+ if (_sliderPos > _h - UP_DOWN_BOX_HEIGHT - _sliderHeight)
+ _sliderPos = _h - UP_DOWN_BOX_HEIGHT - _sliderHeight;
_currentPos =
- (_sliderPos - UP_DOWN_BOX_HEIGHT) * (_numEntries - _entriesPerPage) / (_h - _sliderHeight -
- 2 * UP_DOWN_BOX_HEIGHT);
+ (_sliderPos - UP_DOWN_BOX_HEIGHT) * (_numEntries - _entriesPerPage) / (_h - 2 * UP_DOWN_BOX_HEIGHT - _sliderHeight);
checkBounds(old_pos);
} else {
int old_part = _part;
@@ -178,8 +177,7 @@ void ScrollBarWidget::recalc()
_sliderHeight = UP_DOWN_BOX_HEIGHT;
_sliderPos =
- UP_DOWN_BOX_HEIGHT + (_h - 2 * UP_DOWN_BOX_HEIGHT - _sliderHeight + 1) * _currentPos / (_numEntries -
- _entriesPerPage);
+ UP_DOWN_BOX_HEIGHT + (_h - 2 * UP_DOWN_BOX_HEIGHT - _sliderHeight) * _currentPos / (_numEntries - _entriesPerPage);
if (_sliderPos < 0)
_sliderPos = 0;
}
@@ -201,8 +199,8 @@ void ScrollBarWidget::drawWidget(bool hilite)
(hilite && _part == kUpArrowPart) ? gui->_textcolorhi : gui->_textcolor);
// Down arrow
- gui->frameRect(_x, bottomY - UP_DOWN_BOX_HEIGHT + 1, _w, UP_DOWN_BOX_HEIGHT, gui->_color);
- gui->drawBitmap(down_arrow, _x, bottomY - UP_DOWN_BOX_HEIGHT + 1,
+ gui->frameRect(_x, bottomY - UP_DOWN_BOX_HEIGHT, _w, UP_DOWN_BOX_HEIGHT, gui->_color);
+ gui->drawBitmap(down_arrow, _x, bottomY - UP_DOWN_BOX_HEIGHT,
(hilite && _part == kDownArrowPart) ? gui->_textcolorhi : gui->_textcolor);
// Slider
diff --git a/gui/dialog.cpp b/gui/dialog.cpp
index 7504539eb6..dff03934f2 100644
--- a/gui/dialog.cpp
+++ b/gui/dialog.cpp
@@ -74,11 +74,28 @@ void Dialog::teardownScreenBuf()
void Dialog::open()
{
+ Widget *w = _firstWidget;
+
+ _visible = true;
_gui->openDialog(this);
+
+ // Search for the first objects that wantsFocus() (if any) and give it the focus
+ while (w && !w->wantsFocus()) {
+ w = w->_next;
+ }
+
+ if (w) {
+ printf("Setting default focus\n");
+ w->receivedFocus();
+ _focusedWidget = w;
+ }
}
void Dialog::close()
{
+ _visible = false;
+ _gui->closeTopDialog();
+
if (_mouseWidget) {
_mouseWidget->handleMouseLeft(0);
_mouseWidget = 0;
@@ -87,12 +104,14 @@ void Dialog::close()
_focusedWidget->lostFocus();
_focusedWidget = 0;
}
- _gui->closeTopDialog();
}
void Dialog::draw()
{
Widget *w = _firstWidget;
+
+ if (!isVisible())
+ return;
if (_screenBuf) {
_gui->blitFrom(_screenBuf, _x, _y, _w, _h);
@@ -113,7 +132,14 @@ void Dialog::handleMouseDown(int x, int y, int button, int clickCount)
Widget *w;
w = findWidget(x, y);
- if (w != _focusedWidget) {
+ // If the click occured inside a widget which is not the currently
+ // focused one, change the focus to that widget.
+ // TODO: use the wantsFocus() method to objects, so that only fields
+ // that want it get the focus (like edit fields, list field...)
+ // However, right now we "abuse" the focus also for the click&drag
+ // behaviour of buttons. This should probably be changed by adding
+ // a nother field, e.g. _clickedWidget or _dragWidget.
+ if (w && w != _focusedWidget) {
// The focus will change. Tell the old focused widget (if any)
// that it lost the focus.
if (_focusedWidget)
@@ -126,7 +152,7 @@ void Dialog::handleMouseDown(int x, int y, int button, int clickCount)
_focusedWidget = w;
}
- if (_focusedWidget)
+ if (w == _focusedWidget)
_focusedWidget->handleMouseDown(x - _focusedWidget->_x, y - _focusedWidget->_y, button, clickCount);
}
@@ -302,7 +328,7 @@ SaveLoadDialog::SaveLoadDialog(NewGui *gui)
addButton(200, 80, 54, 16, CUSTOM_STRING(17), kOptionsCmd, 'O'); // Options
addButton(200, 100, 54, 16, RES_STRING(8), kQuitCmd, 'Q'); // Quit
- _savegameList = new ListWidget(this, 10, 20, 180, 94);
+ _savegameList = new ListWidget(this, 10, 20, 180, 90);
_savegameList->setNumberingMode(kListNumberingZero);
// Get savegame names
diff --git a/gui/dialog.h b/gui/dialog.h
index 0e9b46222a..4d5dd82d0b 100644
--- a/gui/dialog.h
+++ b/gui/dialog.h
@@ -46,11 +46,12 @@ protected:
Widget *_mouseWidget;
Widget *_focusedWidget;
byte *_screenBuf;
+ bool _visible;
public:
Dialog(NewGui *gui, int x, int y, int w, int h)
: _gui(gui), _x(x), _y(y), _w(w), _h(h), _firstWidget(0),
- _mouseWidget(0), _focusedWidget(0), _screenBuf(0)
+ _mouseWidget(0), _focusedWidget(0), _screenBuf(0), _visible(false)
{}
virtual ~Dialog();
@@ -72,6 +73,8 @@ public:
virtual void setupScreenBuf();
virtual void teardownScreenBuf();
+ bool isVisible() const { return _visible; }
+
protected:
Widget* findWidget(int x, int y); // Find the widget at pos x,y if any
diff --git a/gui/widget.cpp b/gui/widget.cpp
index 90b972663a..e822617460 100644
--- a/gui/widget.cpp
+++ b/gui/widget.cpp
@@ -37,7 +37,7 @@ void Widget::draw()
{
NewGui *gui = _boss->getGui();
- if (_flags & WIDGET_INVISIBLE)
+ if (!isVisible() || !_boss->isVisible())
return;
// Account for our relative position in the dialog
diff --git a/gui/widget.h b/gui/widget.h
index 3a39b35ae0..3a544da61d 100644
--- a/gui/widget.h
+++ b/gui/widget.h
@@ -102,10 +102,13 @@ public:
void draw();
void receivedFocus() { _hasFocus = true; receivedFocusWidget(); }
void lostFocus() { _hasFocus = false; lostFocusWidget(); }
+ virtual bool wantsFocus() { return false; };
void setFlags(int flags) { _flags |= flags; }
void clearFlags(int flags) { _flags &= ~flags; }
int getFlags() const { return _flags; }
+
+ bool isVisible() const { return !(_flags & WIDGET_INVISIBLE); }
protected:
virtual void drawWidget(bool hilite) {}