diff options
author | Paul Gilbert | 2015-06-20 17:29:40 -0400 |
---|---|---|
committer | Paul Gilbert | 2015-06-20 17:29:40 -0400 |
commit | 4a88c69b5dedc4acac8bcb9609c1cf44c497c4ff (patch) | |
tree | efbf1c7a7382145b5cb5217a08260f787ba3f2ac | |
parent | 4318e0072b9f4dc8df25a5dce40ed0094bd20cf6 (diff) | |
download | scummvm-rg350-4a88c69b5dedc4acac8bcb9609c1cf44c497c4ff.tar.gz scummvm-rg350-4a88c69b5dedc4acac8bcb9609c1cf44c497c4ff.tar.bz2 scummvm-rg350-4a88c69b5dedc4acac8bcb9609c1cf44c497c4ff.zip |
SHERLOCK: RT: Refactored map to use the tooltip widget
-rw-r--r-- | engines/sherlock/tattoo/tattoo_map.cpp | 158 | ||||
-rw-r--r-- | engines/sherlock/tattoo/tattoo_map.h | 13 | ||||
-rw-r--r-- | engines/sherlock/tattoo/widget_base.cpp | 27 | ||||
-rw-r--r-- | engines/sherlock/tattoo/widget_base.h | 5 | ||||
-rw-r--r-- | engines/sherlock/tattoo/widget_tooltip.cpp | 10 | ||||
-rw-r--r-- | engines/sherlock/tattoo/widget_tooltip.h | 10 |
6 files changed, 66 insertions, 157 deletions
diff --git a/engines/sherlock/tattoo/tattoo_map.cpp b/engines/sherlock/tattoo/tattoo_map.cpp index b4ce767976..b8f1b6c55d 100644 --- a/engines/sherlock/tattoo/tattoo_map.cpp +++ b/engines/sherlock/tattoo/tattoo_map.cpp @@ -41,10 +41,9 @@ void MapEntry::clear() { /*-------------------------------------------------------------------------*/ -TattooMap::TattooMap(SherlockEngine *vm) : Map(vm) { +TattooMap::TattooMap(SherlockEngine *vm) : Map(vm), _mapTooltip(vm) { _iconImages = nullptr; _bgFound = _oldBgFound = 0; - _textBuffer = nullptr; loadData(); } @@ -120,9 +119,7 @@ int TattooMap::show() { // Display the built map to the screen screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT); - // Set text display positioning and scroll position - _oldTextBounds.left = _oldTextBounds.top = _oldTextBounds.right = _oldTextBounds.bottom = 0; - _textBounds.left = _textBounds.top = _textBounds.right = _textBounds.bottom = 0; + // Set initial scroll position _targetScroll = _bigPos; _currentScroll = Common::Point(-1, -1); @@ -197,9 +194,7 @@ int TattooMap::show() { // Handle any scrolling of the map if (_currentScroll != _targetScroll) { // If there is a Text description being displayed, restore the area under it - if (_oldTextBounds.width() > 0) - screen._backBuffer1.blitFrom(screen._backBuffer2, Common::Point(_oldTextBounds.left, - _oldTextBounds.top), _oldTextBounds); + _mapTooltip.erase(); _currentScroll = _targetScroll; @@ -211,11 +206,7 @@ int TattooMap::show() { // Handling if a location has been clicked on if (events._released && _bgFound != -1) { // If there is a Text description being displayed, restore the area under it - if (_oldTextBounds.width() > 0) { - screen._backBuffer1.blitFrom(screen._backBuffer2, Common::Point(_oldTextBounds.left, - _oldTextBounds.top), _oldTextBounds); - screen.slamRect(_oldTextBounds); - } + _mapTooltip.erase(); // Save the current scroll position on the map _bigPos = _currentScroll; @@ -227,8 +218,7 @@ int TattooMap::show() { music.stopMusic(); events.clearEvents(); - delete _textBuffer; - _textBuffer = nullptr; + _mapTooltip.banishWindow(); // Reset the back buffers back to standard size screen._backBuffer1.create(SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT); @@ -336,141 +326,21 @@ void TattooMap::checkMapNames(bool slamIt) { } } - // Store the previous bounds that were drawn - _oldTextBounds = _textBounds; - - // See if thay are pointing at a different location and we need to change the display - if (_bgFound != _oldBgFound || (_bgFound != -1 && _textBuffer == nullptr)) { - // See if there is a new image to be displayed - if (_bgFound != -1 && (_bgFound != _oldBgFound || _textBuffer == nullptr)) { + // Handle updating the tooltip + if (_bgFound != _oldBgFound) { + if (_bgFound == -1) { + _mapTooltip.setText(""); + } else { const Common::String &desc = _data[_bgFound]._description; - const char *space = nullptr; - int width = screen.stringWidth(desc) + 2; - int height = 0; - - // See if we need to split it into two lines - if (width > 150) { - const char *s = desc.c_str(); - - int dif = 10000; - for (;;) { - // Move to end of next word - s = strchr(s, ' '); - - if (s == nullptr) { - // Reached end of description - if (space == nullptr) { - height = screen.stringHeight(desc) + 2; - } else { - Common::String line1(desc.c_str(), space); - Common::String line2(space + 1); - - height = screen.stringHeight(line1) + screen.stringHeight(line2); - } - break; - } else { - // Reached space separating words within the description - // Get width before and after word - int width1 = screen.stringWidth(Common::String(desc.c_str(), s)); - int width2 = screen.stringWidth(Common::String(s + 1)); - - if (ABS(width1 - width2) < dif) { - space = s; - dif = ABS(width1 - width2); - width = MAX(width1, width) + 2; - } - - ++s; - } - } - } else { - height = screen.stringHeight(desc) + 2; - } - - // Delete any previous saved area - delete _textBuffer; - - // Allocate a new surface - _textBuffer = new Surface(width, height); - - _textBuffer->fillRect(Common::Rect(0, 0, width, height), TRANSPARENCY); - if (space == nullptr) { - // The whole text can be drawn on a single line - _textBuffer->writeFancyString(desc, Common::Point(0, 0), BLACK, MAP_NAME_COLOR); - } else { - // The text needs to be split up over two lines - Common::String line1(desc.c_str(), space); - Common::String line2(space + 1); - - // Draw the first line - int xp = (width - screen.stringWidth(desc)) / 2; - _textBuffer->writeFancyString(line1, Common::Point(xp, 0), BLACK, MAP_NAME_COLOR); - - int yp = screen.stringHeight(line2); - xp = (width - screen.stringWidth(line2)) / 2; - // CHECKME: Shouldn't we use yp for drawing line2? - _textBuffer->writeFancyString(line2, Common::Point(xp, yp), BLACK, MAP_NAME_COLOR); - } - - // Set the text display position - setTextBounds(); - } else if (_bgFound == -1 && _oldBgFound != -1) { - // We need to clear a currently displayed name - delete _textBuffer; - _textBuffer = nullptr; + _mapTooltip.setText(desc); } _oldBgFound = _bgFound; - } else { - // Set the new text position - setTextBounds(); } - // If the location name was displayed, restore the graphics underneath where it previously was - if (_oldTextBounds.width() > 0) - screen._backBuffer1.blitFrom(screen._backBuffer2, Common::Point(_oldTextBounds.left, _oldTextBounds.top), _oldTextBounds); - - // See if we need to draw the currently highlighted location name - if (_textBuffer != nullptr) - screen._backBuffer1.transBlitFrom(*_textBuffer, Common::Point(_textBounds.left, _textBounds.top)); - - // See if we need to flush the areas associated with the text - if (_oldTextBounds.width() > 0) { - if (slamIt) - slamRect(_oldTextBounds); - - // If there's no text to display, reset the display bounds - if (_textBuffer == nullptr) { - _textBounds.left = _textBounds.top = _textBounds.right = _textBounds.bottom = 0; - _oldTextBounds.left = _oldTextBounds.top = _oldTextBounds.right = _oldTextBounds.bottom = 0; - } - } - - // If there's text to display, then copy the drawn area to the screen - if (_textBuffer != nullptr && slamIt) - slamRect(_textBounds); -} - -void TattooMap::setTextBounds() { - Events &events = *_vm->_events; - Common::Point mousePos = events.mousePos(); - - if (_textBuffer == nullptr) { - _textBounds = Common::Rect(0, 0, 0, 0); - } else { - int xp = (mousePos.x - _textBounds.width() / 2) + _currentScroll.x; - int yp = (mousePos.y - _textBounds.height() / 2) + _currentScroll.y; - if (xp < _currentScroll.x) - xp = _currentScroll.x; - if ((xp + _textBounds.width()) >(_currentScroll.x + SHERLOCK_SCREEN_WIDTH)) - xp = _currentScroll.x + SHERLOCK_SCREEN_WIDTH - _textBounds.width(); - if (yp < _currentScroll.y) - yp = _currentScroll.y; - if ((yp + _textBounds.height()) >(_currentScroll.y + SHERLOCK_SCREEN_HEIGHT)) - yp = _currentScroll.y + SHERLOCK_SCREEN_HEIGHT - _textBounds.height(); - - _textBounds = Common::Rect(xp, yp, xp + _textBuffer->w(), yp + _textBuffer->h()); - } + _mapTooltip.handleEvents(); + if (slamIt) + _mapTooltip.draw(); } void TattooMap::restoreArea(const Common::Rect &bounds) { diff --git a/engines/sherlock/tattoo/tattoo_map.h b/engines/sherlock/tattoo/tattoo_map.h index a9753e7587..86db7b04d3 100644 --- a/engines/sherlock/tattoo/tattoo_map.h +++ b/engines/sherlock/tattoo/tattoo_map.h @@ -27,6 +27,7 @@ #include "sherlock/map.h" #include "sherlock/resources.h" #include "sherlock/surface.h" +#include "sherlock/tattoo/widget_tooltip.h" namespace Sherlock { @@ -48,9 +49,8 @@ private: Common::Array<MapEntry> _data; ImageFile *_iconImages; int _bgFound, _oldBgFound; - Surface *_textBuffer; - Common::Rect _textBounds, _oldTextBounds; - Common::Point _currentScroll, _targetScroll; + WidgetMapTooltip _mapTooltip; + Common::Point _targetScroll; /** * Load data needed for the map @@ -78,15 +78,12 @@ private: void showCloseUp(int closeUpNum); /** - * Set the display bounds for the textual description of a location - */ - void setTextBounds(); - - /** * Copies an area of the map to the screen, taking into account scrolling */ void slamRect(const Common::Rect &bounds); public: + Common::Point _currentScroll; +public: TattooMap(SherlockEngine *vm); virtual ~TattooMap() {} diff --git a/engines/sherlock/tattoo/widget_base.cpp b/engines/sherlock/tattoo/widget_base.cpp index adb09d5404..a9422de998 100644 --- a/engines/sherlock/tattoo/widget_base.cpp +++ b/engines/sherlock/tattoo/widget_base.cpp @@ -46,27 +46,39 @@ void WidgetBase::banishWindow() { void WidgetBase::erase() { Screen &screen = *_vm->_screen; + const Common::Point ¤tScroll = getCurrentScroll(); if (_oldBounds.width() > 0) { - screen._backBuffer1.blitFrom(screen._backBuffer2, Common::Point(_oldBounds.left, _oldBounds.top), _oldBounds); - screen.slamRect(_oldBounds); + // Get the bounds to copy from the back buffers, adjusted for scroll position + Common::Rect oldBounds = _oldBounds; + oldBounds.translate(currentScroll.x, currentScroll.y); + // Restore the affected area from the secondary back buffer into the first one, and then copy to screen + screen._backBuffer1.blitFrom(screen._backBuffer2, Common::Point(oldBounds.left, oldBounds.top), oldBounds); + screen.blitFrom(screen._backBuffer1, Common::Point(_oldBounds.left, _oldBounds.top), oldBounds); + + // Reset the old bounds so _oldBounds = Common::Rect(0, 0, 0, 0); } } void WidgetBase::draw() { Screen &screen = *_vm->_screen; + const Common::Point ¤tScroll = getCurrentScroll(); // If there was a previously drawn frame in a different position that hasn't yet been erased, then erase it if (_oldBounds.width() > 0 && _oldBounds != _bounds) erase(); if (_bounds.width() > 0 && !_surface.empty()) { + // Get the area to draw, adjusted for scroll position + Common::Rect bounds = _bounds; + bounds.translate(currentScroll.x, currentScroll.y); + // Copy any area to be drawn on from the secondary back buffer, and then draw surface on top - screen._backBuffer1.blitFrom(screen._backBuffer2, Common::Point(_bounds.left, _bounds.top), _bounds); - screen._backBuffer1.transBlitFrom(_surface, Common::Point(_bounds.left, _bounds.top)); - screen.slamRect(_bounds); + screen._backBuffer1.blitFrom(screen._backBuffer2, Common::Point(bounds.left, bounds.top), bounds); + screen._backBuffer1.transBlitFrom(_surface, Common::Point(bounds.left, bounds.top)); + screen.blitFrom(screen._backBuffer1, Common::Point(_bounds.left, _bounds.top), bounds); // Store a copy of the drawn area for later erasing _oldBounds = _bounds; @@ -151,6 +163,11 @@ void WidgetBase::makeInfoArea() { _surface.vLine(_bounds.width() - 1, (*_images)[0]._height, _bounds.height()- (*_images)[2]._height, INFO_BOTTOM); } +const Common::Point &WidgetBase::getCurrentScroll() const { + TattooUserInterface &ui = *(TattooUserInterface *)_vm->_ui; + return ui._currentScroll; +} + } // End of namespace Tattoo } // End of namespace Sherlock diff --git a/engines/sherlock/tattoo/widget_base.h b/engines/sherlock/tattoo/widget_base.h index 5eacad610b..7e546db248 100644 --- a/engines/sherlock/tattoo/widget_base.h +++ b/engines/sherlock/tattoo/widget_base.h @@ -56,6 +56,11 @@ protected: void checkMenuPosition(); void makeInfoArea(); + + /** + * Returns the current scroll position + */ + virtual const Common::Point &getCurrentScroll() const; public: WidgetBase(SherlockEngine *vm); virtual ~WidgetBase() {} diff --git a/engines/sherlock/tattoo/widget_tooltip.cpp b/engines/sherlock/tattoo/widget_tooltip.cpp index 69a9300b34..69df7e0ede 100644 --- a/engines/sherlock/tattoo/widget_tooltip.cpp +++ b/engines/sherlock/tattoo/widget_tooltip.cpp @@ -21,6 +21,7 @@ */ #include "sherlock/tattoo/widget_tooltip.h" +#include "sherlock/tattoo/tattoo_map.h" #include "sherlock/tattoo/tattoo_user_interface.h" #include "sherlock/tattoo/tattoo.h" @@ -173,6 +174,15 @@ void WidgetSceneTooltip::handleEvents() { } ui._oldArrowZone = ui._arrowZone; + + WidgetTooltip::handleEvents(); +} + +/*----------------------------------------------------------------*/ + +const Common::Point &WidgetMapTooltip::getCurrentScroll() const { + TattooMap &map = *(TattooMap *)_vm->_map; + return map._currentScroll; } } // End of namespace Tattoo diff --git a/engines/sherlock/tattoo/widget_tooltip.h b/engines/sherlock/tattoo/widget_tooltip.h index a44faac875..3003831882 100644 --- a/engines/sherlock/tattoo/widget_tooltip.h +++ b/engines/sherlock/tattoo/widget_tooltip.h @@ -59,6 +59,16 @@ public: virtual void handleEvents(); }; +class WidgetMapTooltip : public WidgetTooltip { +protected: + /** + * Returns the current scroll position + */ + virtual const Common::Point &getCurrentScroll() const; +public: + WidgetMapTooltip(SherlockEngine *vm) : WidgetTooltip(vm) {} +}; + } // End of namespace Tattoo } // End of namespace Sherlock |