diff --git a/src/gui/LauncherDialog.cxx b/src/gui/LauncherDialog.cxx index 1f2233319..10c36d4e1 100644 --- a/src/gui/LauncherDialog.cxx +++ b/src/gui/LauncherDialog.cxx @@ -879,6 +879,14 @@ void LauncherDialog::handleKeyDown(StellaKey key, StellaMod mod, bool repeated) reload(); break; + case KBDK_LEFT: + myRomImageWidget->changeImage(-1); + break; + + case KBDK_RIGHT: + myRomImageWidget->changeImage(1); + break; + default: handled = false; break; diff --git a/src/gui/RomImageWidget.cxx b/src/gui/RomImageWidget.cxx index a9dce62bc..ea8e5a4a4 100644 --- a/src/gui/RomImageWidget.cxx +++ b/src/gui/RomImageWidget.cxx @@ -33,7 +33,7 @@ RomImageWidget::RomImageWidget(GuiObject* boss, const GUI::Font& font, : Widget(boss, font, x, y, w, h), CommandSender(boss) { - _flags = Widget::FLAG_ENABLED; + _flags = Widget::FLAG_ENABLED | Widget::FLAG_TRACK_MOUSE; _bgcolor = kDlgColor; _bgcolorlo = kBGColorLo; myImageHeight = _h - labelHeight(font); @@ -80,6 +80,19 @@ void RomImageWidget::reloadProperties(const FSNode& node) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void RomImageWidget::parseProperties(const FSNode& node) { + if(myNavSurface == nullptr) + { + // Create navigation surface + myNavSurface = instance().frameBuffer().allocateSurface( + _w, myImageHeight); + + FBSurface::Attributes& attr = myNavSurface->attributes(); + + attr.blending = true; + attr.blendalpha = 60; + myNavSurface->applyAttributes(); + } + // Check if a surface has ever been created; if so, we use it // The surface will always be the maximum size, but sometimes we'll // only draw certain parts of it @@ -91,9 +104,12 @@ void RomImageWidget::parseProperties(const FSNode& node) dialog().addRenderCallback([this]() { if(mySurfaceIsValid) + { mySurface->render(); + if(isHighlighted()) + myNavSurface->render(); } - ); + }); } // Initialize to empty properties entry @@ -131,6 +147,17 @@ void RomImageWidget::parseProperties(const FSNode& node) setDirty(); } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool RomImageWidget::changeImage(int direction) +{ + if(direction == -1 && myImageIdx) + return loadPng(myImageList[--myImageIdx].getPath()); + else if(direction == 1 && myImageIdx < myImageList.size() - 1) + return loadPng(myImageList[++myImageIdx].getPath()); + + return false; +} + #ifdef PNG_SUPPORT // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool RomImageWidget::getImageList(const string& filename) @@ -184,31 +211,19 @@ bool RomImageWidget::loadPng(const string& filename) } return false; } -#endif -#ifdef PNG_SUPPORT // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void RomImageWidget::handleMouseUp(int x, int y, MouseButton b, int clickCount) { if(isEnabled() && x >= 0 && x < _w && y >= 0 && y < myImageHeight) - { - if(x < _w/2) - { - if(myImageIdx) - { - loadPng(myImageList[--myImageIdx].getPath()); - } - } - else if(myImageIdx < myImageList.size() - 1) - { - loadPng(myImageList[++myImageIdx].getPath()); - } - } + changeImage(x < _w / 2 ? 1 : -1); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void RomImageWidget::handleMouseMoved(int x, int y) { + if(x < _w / 2 != myMouseX < _w / 2) + setDirty(); myMouseX = x; } #endif @@ -239,6 +254,48 @@ void RomImageWidget::drawWidget(bool hilite) // the dialog surface position into account const Common::Rect& s_dst = s.dstRect(); mySurface->setDstPos(x + s_dst.x(), y + s_dst.y()); + + // Draw the image label and counter + ostringstream buf; + buf << myImageIdx + 1 << "/" << myImageList.size(); + const int yText = _y + myImageHeight + _font.getFontHeight() / 8; + const int wText = _font.getStringWidth(buf.str()); + + if(myLabel.length()) + s.drawString(_font, myLabel, _x, yText, _w - wText - _font.getMaxCharWidth() * 2, _textcolor); + if(myImageList.size()) + s.drawString(_font, buf.str(), _x + _w - wText, yText, wText, _textcolor); + + // Draw the navigation arrows + const bool leftArrow = myMouseX < _w / 2; + + myNavSurface->invalidate(); + if(isHighlighted() && + ((leftArrow && myImageIdx) || (!leftArrow && myImageIdx < myImageList.size() - 1)) || true) + { + const int w = _w / 64; + const int w2 = 1; // w / 2; + const int ax = leftArrow ? _w / 12 - w / 2 : _w - _w / 12 - w / 2; + const int ay = myImageHeight >> 1; + const int dx = (_w / 32) * (leftArrow ? 1 : -1); + const int dy = myImageHeight / 16; + + for(int i = 0; i < w; ++i) + { + myNavSurface->line(ax + dx + i + w2, ay - dy, ax + i + w2, ay, kBGColor); + myNavSurface->line(ax + dx + i + w2, ay + dy, ax + i + w2, ay, kBGColor); + myNavSurface->line(ax + dx + i, ay - dy + w2, ax + i, ay + w2, kBGColor); + myNavSurface->line(ax + dx + i, ay + dy + w2, ax + i, ay + w2, kBGColor); + myNavSurface->line(ax + dx + i + w2, ay - dy + w2, ax + i + w2, ay + w2, kBGColor); + myNavSurface->line(ax + dx + i + w2, ay + dy + w2, ax + i + w2, ay + w2, kBGColor); + } + for(int i = 0; i < w; ++i) + { + myNavSurface->line(ax + dx + i, ay - dy, ax + i, ay, kColorInfo); + myNavSurface->line(ax + dx + i, ay + dy, ax + i, ay, kColorInfo); + } + myNavSurface->setDstRect(mySurface->dstRect()); + } } else if(mySurfaceErrorMsg != "") { @@ -246,25 +303,5 @@ void RomImageWidget::drawWidget(bool hilite) const uInt32 y = _y + ((yoff - _font.getLineHeight()) >> 1); s.drawString(_font, mySurfaceErrorMsg, x, y, _w - 10, _textcolor); } - ostringstream buf; - buf << myImageIdx + 1 << "/" << myImageList.size(); - const int yText = _y + myImageHeight + _font.getFontHeight() / 8; - const int wText = _font.getStringWidth(buf.str()); - - if(myLabel.length()) - s.drawString(_font, myLabel, _x, yText, _w - wText - _font.getMaxCharWidth() * 2, _textcolor); - if(myImageList.size()) - s.drawString(_font, buf.str(), _x + _w - wText, yText, wText, _textcolor); - -#ifdef PNG_SUPPORT - if(isHighlighted()) - { - // TODO: need another surface - const int xOfs = myMouseX < _w / 2 ? 10 : _w - 50; - - s.line(xOfs, _h / 2 - 10, xOfs + 20, _h / 2, kBtnTextColorHi); - } -#endif - clearDirty(); } diff --git a/src/gui/RomImageWidget.hxx b/src/gui/RomImageWidget.hxx index aca0d7004..0d5b9e4dd 100644 --- a/src/gui/RomImageWidget.hxx +++ b/src/gui/RomImageWidget.hxx @@ -39,6 +39,7 @@ class RomImageWidget : public Widget, public CommandSender void setProperties(const FSNode& node, const string& md5); void clearProperties(); void reloadProperties(const FSNode& node); + bool changeImage(int direction = 1); protected: void drawWidget(bool hilite) override; @@ -58,6 +59,9 @@ class RomImageWidget : public Widget, public CommandSender // Surface pointer holding the PNG image shared_ptr mySurface; + // Surface pointer holding the navigation elements + shared_ptr myNavSurface; + // Whether the surface should be redrawn by drawWidget() bool mySurfaceIsValid{false}; @@ -70,7 +74,7 @@ class RomImageWidget : public Widget, public CommandSender // Indicates if an error occurred in creating/displaying the surface string mySurfaceErrorMsg; -#ifdef PNG_SUPPORT + // Height of the image area int myImageHeight{0}; // Contains the list of image names for the current ROM @@ -84,7 +88,6 @@ class RomImageWidget : public Widget, public CommandSender // Label for the loaded image string myLabel; -#endif private: // Following constructors and assignment operators not supported