diff --git a/src/gui/AboutDialog.cxx b/src/gui/AboutDialog.cxx index 62e69253f..1855d8904 100644 --- a/src/gui/AboutDialog.cxx +++ b/src/gui/AboutDialog.cxx @@ -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"); diff --git a/src/gui/ContextMenu.cxx b/src/gui/ContextMenu.cxx index c26609508..373bad0b9 100644 --- a/src/gui/ContextMenu.cxx +++ b/src/gui/ContextMenu.cxx @@ -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; } diff --git a/src/gui/ContextMenu.hxx b/src/gui/ContextMenu.hxx index d8770d9d3..0732ac355 100644 --- a/src/gui/ContextMenu.hxx +++ b/src/gui/ContextMenu.hxx @@ -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; diff --git a/src/gui/DialogContainer.cxx b/src/gui/DialogContainer.cxx index d2df73c2e..3509245a2 100644 --- a/src/gui/DialogContainer.cxx +++ b/src/gui/DialogContainer.cxx @@ -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();