mirror of https://github.com/stella-emu/stella.git
First pass at fixing ContextMenu when list of items is larger
than the enclosing screen. Selecting images with the mouse is working, but the up and down 'buttons' are currently just drawn text/placeholders. Still TODO is get the keyboard actions (cursor up/down, etc) working. git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@1949 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
parent
f096fa1eb7
commit
965787050a
|
@ -108,7 +108,7 @@ void AboutDialog::updateStrings(int page, int lines, string& title)
|
|||
case 1:
|
||||
title = string("Stella ") + STELLA_VERSION;
|
||||
ADD_ATEXT("\\CA multi-platform Atari 2600 VCS emulator");
|
||||
ADD_ATEXT(string("\\C\\c2") + instance().features());
|
||||
ADD_ATEXT(string("\\C\\c2Features: ") + instance().features());
|
||||
ADD_ATEXT(string("\\C\\c2") + instance().buildInfo());
|
||||
ADD_ALINE;
|
||||
ADD_ATEXT("\\CCopyright (C) 1995-2010 The Stella Team");
|
||||
|
|
|
@ -33,7 +33,9 @@ ContextMenu::ContextMenu(GuiObject* boss, const GUI::Font& font,
|
|||
_currentItem(-1),
|
||||
_selectedItem(-1),
|
||||
_rowHeight(font.getLineHeight()),
|
||||
_twoColumns(false),
|
||||
_firstEntry(0),
|
||||
_numEntries(0),
|
||||
_showScroll(false),
|
||||
_font(&font),
|
||||
_cmd(cmd),
|
||||
_xorig(0),
|
||||
|
@ -54,21 +56,6 @@ void ContextMenu::addItems(const StringMap& items)
|
|||
_entries.clear();
|
||||
_entries = items;
|
||||
|
||||
// Create two columns of entries if there are more than 10 items
|
||||
if(_entries.size() > 10)
|
||||
{
|
||||
_twoColumns = true;
|
||||
_entriesPerColumn = _entries.size() / 2;
|
||||
|
||||
if(_entries.size() & 1)
|
||||
_entriesPerColumn++;
|
||||
}
|
||||
else
|
||||
{
|
||||
_twoColumns = false;
|
||||
_entriesPerColumn = _entries.size();
|
||||
}
|
||||
|
||||
// Resize to largest string
|
||||
int maxwidth = 0;
|
||||
for(unsigned int i = 0; i < _entries.size(); ++i)
|
||||
|
@ -79,8 +66,8 @@ void ContextMenu::addItems(const StringMap& items)
|
|||
}
|
||||
|
||||
_x = _y = 0;
|
||||
_w = maxwidth * (_twoColumns ? 2 : 1) + 10;
|
||||
_h = _entriesPerColumn * _rowHeight + 4;
|
||||
_w = maxwidth + 10;
|
||||
_h = 1; // recalculate this in ::recalc()
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -88,6 +75,8 @@ void ContextMenu::show(uInt32 x, uInt32 y, int item)
|
|||
{
|
||||
_xorig = x;
|
||||
_yorig = y;
|
||||
|
||||
recalc(instance().frameBuffer().imageRect());
|
||||
parent().addDialog(this);
|
||||
setSelected(item);
|
||||
}
|
||||
|
@ -98,6 +87,7 @@ void ContextMenu::center()
|
|||
// Make sure the menu is exactly where it should be, in case the image
|
||||
// offset has changed
|
||||
const GUI::Rect& image = instance().frameBuffer().imageRect();
|
||||
recalc(image);
|
||||
uInt32 x = image.x() + _xorig;
|
||||
uInt32 y = image.y() + _yorig;
|
||||
uInt32 tx = image.x() + image.width();
|
||||
|
@ -108,6 +98,27 @@ void ContextMenu::center()
|
|||
surface().setPos(x, y);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void ContextMenu::recalc(const GUI::Rect& image)
|
||||
{
|
||||
// Now is the time to adjust the height
|
||||
// If it's higher than the screen, we need to scroll through
|
||||
int maxentries = (image.height() - 4) / _rowHeight;
|
||||
if((int)_entries.size() > maxentries)
|
||||
{
|
||||
// We show two less than the max, so we have room for two scroll buttons
|
||||
_numEntries = maxentries - 2;
|
||||
_h = maxentries * _rowHeight + 4;
|
||||
_showScroll = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
_numEntries = _entries.size();
|
||||
_h = _entries.size() * _rowHeight + 4;
|
||||
_showScroll = false;
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void ContextMenu::setSelected(int item)
|
||||
{
|
||||
|
@ -184,15 +195,6 @@ void ContextMenu::handleMouseDown(int x, int y, int button, int clickCount)
|
|||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void ContextMenu::handleMouseWheel(int x, int y, int direction)
|
||||
{
|
||||
if(direction < 0)
|
||||
moveUp();
|
||||
else if(direction > 0)
|
||||
moveDown();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void ContextMenu::handleMouseMoved(int x, int y, int button)
|
||||
{
|
||||
|
@ -265,21 +267,8 @@ void ContextMenu::handleEvent(Event::Type e)
|
|||
int ContextMenu::findItem(int x, int y) const
|
||||
{
|
||||
if(x >= 0 && x < _w && y >= 0 && y < _h)
|
||||
{
|
||||
if(_twoColumns)
|
||||
{
|
||||
unsigned int entry = (y - 4) / _rowHeight;
|
||||
if(x > _w / 2)
|
||||
{
|
||||
entry += _entriesPerColumn;
|
||||
|
||||
if(entry >= _entries.size())
|
||||
return -1;
|
||||
}
|
||||
return entry;
|
||||
}
|
||||
return (y - 4) / _rowHeight;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -297,6 +286,19 @@ void ContextMenu::drawCurrentSelection(int item)
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void ContextMenu::sendSelection()
|
||||
{
|
||||
// Select the correct item when scrolling; we have to take into account
|
||||
// that the viewable items are no longer 1-to-1 with the entries
|
||||
int item = _currentItem;
|
||||
if(_showScroll)
|
||||
{
|
||||
if(item == 0) // scroll up
|
||||
return scrollUp();
|
||||
else if(item == _numEntries+1) // scroll down
|
||||
return scrollDown();
|
||||
else
|
||||
item = item + _firstEntry - 1;
|
||||
}
|
||||
|
||||
// We remove the dialog when the user has selected an item
|
||||
// Make sure the dialog is removed before sending any commands,
|
||||
// since one consequence of sending a command may be to add another
|
||||
|
@ -304,7 +306,7 @@ void ContextMenu::sendSelection()
|
|||
close();
|
||||
|
||||
// Send any command associated with the selection
|
||||
_selectedItem = _currentItem;
|
||||
_selectedItem = item;
|
||||
sendCommand(_cmd ? _cmd : kCMenuItemSelectedCmd, _selectedItem, -1);
|
||||
}
|
||||
|
||||
|
@ -312,6 +314,14 @@ void ContextMenu::sendSelection()
|
|||
void ContextMenu::moveUp()
|
||||
{
|
||||
int item = _currentItem;
|
||||
if(_showScroll)
|
||||
{
|
||||
if(item > 0) // scroll up
|
||||
{
|
||||
if(_firstEntry > item)
|
||||
_firstEntry--;
|
||||
}
|
||||
}
|
||||
if(item > 0)
|
||||
drawCurrentSelection(--item);
|
||||
}
|
||||
|
@ -320,10 +330,39 @@ void ContextMenu::moveUp()
|
|||
void ContextMenu::moveDown()
|
||||
{
|
||||
int item = _currentItem;
|
||||
if(_showScroll)
|
||||
{
|
||||
if(item == _numEntries+1) // scroll down
|
||||
{
|
||||
if(_firstEntry + _numEntries < (int)_entries.size())
|
||||
_firstEntry++;
|
||||
}
|
||||
setDirty();
|
||||
}
|
||||
if(item < (int)_entries.size() - 1)
|
||||
drawCurrentSelection(++item);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void ContextMenu::scrollUp()
|
||||
{
|
||||
if(_firstEntry > _currentItem)
|
||||
{
|
||||
_firstEntry--;
|
||||
setDirty();
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void ContextMenu::scrollDown()
|
||||
{
|
||||
if(_firstEntry + _numEntries < (int)_entries.size())
|
||||
{
|
||||
_firstEntry++;
|
||||
setDirty();
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void ContextMenu::drawDialog()
|
||||
{
|
||||
|
@ -338,42 +377,34 @@ void ContextMenu::drawDialog()
|
|||
s.fillRect(_x+1, _y+1, _w-2, _h-2, kWidColor);
|
||||
s.box(_x, _y, _w, _h, kColor, kShadowColor);
|
||||
|
||||
// If necessary, draw dividing line
|
||||
if(_twoColumns)
|
||||
s.vLine(_x + _w / 2, _y, _y + _h - 2, kColor);
|
||||
// Draw the entries, taking scroll buttons into account
|
||||
int x = _x + 2, y = _y + 2, w = _w - 4;
|
||||
cerr << "_firstEntry = " << _firstEntry << ", _numEntries = " << _numEntries << endl;
|
||||
|
||||
// Draw the entries
|
||||
int x, y, w;
|
||||
int count = _entries.size();
|
||||
for(int i = 0; i < count; i++)
|
||||
// Show top scroll area
|
||||
int offset = _firstEntry;
|
||||
if(_showScroll)
|
||||
{
|
||||
bool hilite = i == _currentItem;
|
||||
if(_twoColumns)
|
||||
{
|
||||
int n = _entries.size() / 2;
|
||||
if(_entries.size() & 1) n++;
|
||||
if(i >= n)
|
||||
{
|
||||
x = _x + 1 + _w / 2;
|
||||
y = _y + 2 + _rowHeight * (i - n);
|
||||
}
|
||||
else
|
||||
{
|
||||
x = _x + 2;
|
||||
y = _y + 2 + _rowHeight * i;
|
||||
}
|
||||
w = _w / 2 - 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
x = _x + 2;
|
||||
y = _y + 2 + i * _rowHeight;
|
||||
w = _w - 4;
|
||||
}
|
||||
if(hilite) s.fillRect(x, y, w, _rowHeight, kTextColorHi);
|
||||
s.drawString(_font, _entries[i].first, x + 1, y + 2, w - 2,
|
||||
hilite ? kWidColor : kTextColor);
|
||||
s.drawString(_font, " ^^^^^", x + 1, y + 2, w, kTextColor);
|
||||
y += _rowHeight;
|
||||
offset--;
|
||||
}
|
||||
|
||||
for(int i = _firstEntry; i < _firstEntry + _numEntries; ++i)
|
||||
{
|
||||
bool hilite = (i-offset) == _currentItem;
|
||||
if(hilite) s.fillRect(x, y, w, _rowHeight, kTextColorHi);
|
||||
s.drawString(_font, _entries[i].first, x + 1, y + 2, w,
|
||||
hilite ? kWidColor : kTextColor);
|
||||
y += _rowHeight;
|
||||
}
|
||||
|
||||
// Show bottom scroll area
|
||||
if(_showScroll)
|
||||
{
|
||||
s.drawString(_font, " vvvvv", x + 1, y + 2, w, kTextColor);
|
||||
}
|
||||
|
||||
s.addDirtyRect(_x, _y, _w, _h);
|
||||
_dirty = false;
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@ class ContextMenu : public Dialog, public CommandSender
|
|||
public:
|
||||
ContextMenu(GuiObject* boss, const GUI::Font& font,
|
||||
const StringMap& items, int cmd = 0);
|
||||
virtual ~ContextMenu();
|
||||
virtual ~ContextMenu();
|
||||
|
||||
/** Add the given items to the widget. */
|
||||
void addItems(const StringMap& items);
|
||||
|
@ -74,7 +74,6 @@ class ContextMenu : public Dialog, public CommandSender
|
|||
|
||||
protected:
|
||||
void handleMouseDown(int x, int y, int button, int clickCount);
|
||||
void handleMouseWheel(int x, int y, int direction);
|
||||
void handleMouseMoved(int x, int y, int button);
|
||||
void handleKeyDown(int ascii, int keycode, int modifiers); // Scroll through entries with arrow keys etc
|
||||
void handleJoyDown(int stick, int button);
|
||||
|
@ -85,6 +84,7 @@ class ContextMenu : public Dialog, public CommandSender
|
|||
void drawDialog();
|
||||
|
||||
private:
|
||||
void recalc(const GUI::Rect& image);
|
||||
void drawMenuEntry(int entry, bool hilite);
|
||||
|
||||
int findItem(int x, int y) const;
|
||||
|
@ -92,6 +92,8 @@ class ContextMenu : public Dialog, public CommandSender
|
|||
|
||||
void moveUp();
|
||||
void moveDown();
|
||||
void scrollUp();
|
||||
void scrollDown();
|
||||
|
||||
void sendSelection();
|
||||
|
||||
|
@ -101,9 +103,8 @@ class ContextMenu : public Dialog, public CommandSender
|
|||
int _currentItem;
|
||||
int _selectedItem;
|
||||
int _rowHeight;
|
||||
|
||||
bool _twoColumns;
|
||||
int _entriesPerColumn;
|
||||
int _firstEntry, _numEntries;
|
||||
bool _showScroll;
|
||||
|
||||
const GUI::Font* _font;
|
||||
int _cmd;
|
||||
|
|
|
@ -107,6 +107,9 @@ void DialogContainer::draw(bool full)
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void DialogContainer::addDialog(Dialog* d)
|
||||
{
|
||||
const GUI::Rect& image = myOSystem->frameBuffer().imageRect();
|
||||
assert(d->getWidth() <= image.width() && d->getHeight() <= image.height());
|
||||
|
||||
myDialogStack.push(d);
|
||||
d->open();
|
||||
|
||||
|
|
Loading…
Reference in New Issue