mirror of https://github.com/stella-emu/stella.git
197 lines
6.1 KiB
C++
197 lines
6.1 KiB
C++
//============================================================================
|
|
//
|
|
// SSSS tt lll lll
|
|
// SS SS tt ll ll
|
|
// SS tttttt eeee ll ll aaaa
|
|
// SSSS tt ee ee ll ll aa
|
|
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
|
// SS SS tt ee ll ll aa aa
|
|
// SSSS ttt eeeee llll llll aaaaa
|
|
//
|
|
// Copyright (c) 1995-2019 by Bradford W. Mott, Stephen Anthony
|
|
// and the Stella Team
|
|
//
|
|
// See the file "License.txt" for information on usage and redistribution of
|
|
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
|
//============================================================================
|
|
|
|
#include "Dialog.hxx"
|
|
#include "FBSurface.hxx"
|
|
#include "ScrollBarWidget.hxx"
|
|
#include "CheckListWidget.hxx"
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
CheckListWidget::CheckListWidget(GuiObject* boss, const GUI::Font& font,
|
|
int x, int y, int w, int h)
|
|
: ListWidget(boss, font, x, y, w, h)
|
|
{
|
|
int ypos = _y + 2;
|
|
|
|
// rowheight is determined by largest item on a line,
|
|
// possibly meaning that number of rows will change
|
|
_fontHeight = std::max(_fontHeight, CheckboxWidget::boxSize());
|
|
_rows = h / _fontHeight;
|
|
|
|
// Create a CheckboxWidget for each row in the list
|
|
for(int i = 0; i < _rows; ++i)
|
|
{
|
|
CheckboxWidget* t = new CheckboxWidget(boss, font, _x + 2, ypos, "",
|
|
CheckboxWidget::kCheckActionCmd);
|
|
t->setTextColor(kTextColor);
|
|
t->setTarget(this);
|
|
t->setID(i);
|
|
ypos += _fontHeight;
|
|
|
|
_checkList.push_back(t);
|
|
}
|
|
}
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
void CheckListWidget::handleMouseEntered()
|
|
{
|
|
setFlags(Widget::FLAG_HILITED);
|
|
setDirty();
|
|
}
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
void CheckListWidget::handleMouseLeft()
|
|
{
|
|
clearFlags(Widget::FLAG_HILITED);
|
|
setDirty();
|
|
}
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
void CheckListWidget::setList(const StringList& list, const BoolArray& state)
|
|
{
|
|
_list = list;
|
|
_stateList = state;
|
|
|
|
assert(_list.size() == _stateList.size());
|
|
|
|
// Enable all checkboxes
|
|
for(int i = 0; i < _rows; ++i)
|
|
_checkList[i]->setFlags(Widget::FLAG_ENABLED);
|
|
|
|
// Then turn off any extras
|
|
if(int(_stateList.size()) < _rows)
|
|
for(int i = int(_stateList.size()); i < _rows; ++i)
|
|
_checkList[i]->clearFlags(Widget::FLAG_ENABLED);
|
|
|
|
ListWidget::recalc();
|
|
}
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
void CheckListWidget::setLine(int line, const string& str, const bool& state)
|
|
{
|
|
if(line >= int(_list.size()))
|
|
return;
|
|
|
|
_list[line] = str;
|
|
_stateList[line] = state;
|
|
}
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
void CheckListWidget::drawWidget(bool hilite)
|
|
{
|
|
//cerr << "CheckListWidget::drawWidget\n";
|
|
FBSurface& s = _boss->dialog().surface();
|
|
bool onTop = _boss->dialog().isOnTop();
|
|
int i, pos, len = int(_list.size());
|
|
|
|
// Draw a thin frame around the list and to separate columns
|
|
s.frameRect(_x, _y, _w, _h, hilite ? kWidColorHi : kColor);
|
|
s.vLine(_x + CheckboxWidget::boxSize() + 5, _y, _y + _h - 1, kColor);
|
|
|
|
// Draw the list items
|
|
for (i = 0, pos = _currentPos; i < _rows && pos < len; i++, pos++)
|
|
{
|
|
// Draw checkboxes for correct lines (takes scrolling into account)
|
|
_checkList[i]->setState(_stateList[pos]);
|
|
_checkList[i]->setDirty();
|
|
_checkList[i]->draw();
|
|
|
|
const int y = _y + 2 + _fontHeight * i + 2;
|
|
ColorId textColor = kTextColor;
|
|
|
|
Common::Rect r(getEditRect());
|
|
|
|
// Draw the selected item inverted, on a highlighted background.
|
|
if (_selectedItem == pos)
|
|
{
|
|
if(_hasFocus && !_editMode)
|
|
{
|
|
s.fillRect(_x + r.x() - 3, _y + 1 + _fontHeight * i,
|
|
_w - r.x(), _fontHeight, kTextColorHi);
|
|
textColor = kTextColorInv;
|
|
}
|
|
else
|
|
s.frameRect(_x + r.x() - 3, _y + 1 + _fontHeight * i,
|
|
_w - r.x(), _fontHeight, onTop ? kTextColorHi : kColor);
|
|
}
|
|
|
|
if (_selectedItem == pos && _editMode)
|
|
{
|
|
adjustOffset();
|
|
s.drawString(_font, editString(), _x + r.x(), y, r.w(), onTop ? kTextColor : kColor,
|
|
TextAlign::Left, -_editScrollOffset, false);
|
|
}
|
|
else
|
|
s.drawString(_font, _list[pos], _x + r.x(), y, r.w(),
|
|
onTop ? textColor : kColor);
|
|
}
|
|
|
|
// Only draw the caret while editing, and if it's in the current viewport
|
|
if(_editMode && (_selectedItem >= _scrollBar->_currentPos) &&
|
|
(_selectedItem < _scrollBar->_currentPos + _rows))
|
|
drawCaret();
|
|
}
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
Common::Rect CheckListWidget::getEditRect() const
|
|
{
|
|
const int yoffset = (_selectedItem - _currentPos) * _fontHeight,
|
|
xoffset = CheckboxWidget::boxSize() + 10;
|
|
|
|
return Common::Rect(2 + xoffset, 1 + yoffset,
|
|
_w - (xoffset - 15), _fontHeight + yoffset);
|
|
}
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
bool CheckListWidget::getState(int line)
|
|
{
|
|
if(line >= 0 && line < int(_stateList.size()))
|
|
return _stateList[line];
|
|
else
|
|
return false;
|
|
}
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
bool CheckListWidget::handleEvent(Event::Type e)
|
|
{
|
|
if(e == Event::UISelect)
|
|
{
|
|
// Simulate a mouse button click
|
|
_checkList[ListWidget::getSelected()]->handleMouseUp(0, 0, MouseButton::LEFT, 0);
|
|
return true;
|
|
}
|
|
else
|
|
return ListWidget::handleEvent(e);
|
|
}
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
void CheckListWidget::handleCommand(CommandSender* sender, int cmd,
|
|
int data, int id)
|
|
{
|
|
if(cmd == CheckboxWidget::kCheckActionCmd)
|
|
{
|
|
// Figure out which line has been checked
|
|
int line = _currentPos + id;
|
|
_stateList[line] = bool(data);
|
|
|
|
// Let the boss know about it
|
|
sendCommand(CheckListWidget::kListItemChecked, line, _id);
|
|
}
|
|
else
|
|
ListWidget::handleCommand(sender, cmd, data, id);
|
|
}
|