changed the way listbox draw selected items; list box now has a frame & different spacing; clicking outside any widget doesn't cause the focus widget to loose focus; other tweaks

svn-id: r4906
This commit is contained in:
Max Horn 2002-09-08 16:00:13 +00:00
parent 27bfe32f16
commit c0df1c2df2
7 changed files with 68 additions and 24 deletions

View file

@ -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) {
@ -231,8 +232,14 @@ void ListWidget::drawWidget(bool hilite)
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);
}
}

View file

@ -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:

View file

@ -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

View file

@ -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,13 +104,15 @@ 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);
} else {
@ -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

View file

@ -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

View file

@ -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

View file

@ -102,11 +102,14 @@ 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) {}