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:
parent
27bfe32f16
commit
c0df1c2df2
7 changed files with 68 additions and 24 deletions
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue