aboutsummaryrefslogtreecommitdiff
path: root/gui/ThemeEngine.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'gui/ThemeEngine.cpp')
-rw-r--r--gui/ThemeEngine.cpp185
1 files changed, 165 insertions, 20 deletions
diff --git a/gui/ThemeEngine.cpp b/gui/ThemeEngine.cpp
index c850a6a02e..96108bccce 100644
--- a/gui/ThemeEngine.cpp
+++ b/gui/ThemeEngine.cpp
@@ -31,11 +31,13 @@
#include "graphics/cursorman.h"
#include "graphics/fontman.h"
#include "graphics/surface.h"
+#include "graphics/transparent_surface.h"
#include "graphics/VectorRenderer.h"
#include "graphics/fonts/bdf.h"
#include "graphics/fonts/ttf.h"
#include "image/bmp.h"
+#include "image/png.h"
#include "gui/widget.h"
#include "gui/ThemeEngine.h"
@@ -59,6 +61,10 @@ const char *const ThemeEngine::kImageStopSmallButton = "stopbtn_small.bmp";
const char *const ThemeEngine::kImageEditSmallButton = "editbtn_small.bmp";
const char *const ThemeEngine::kImageSwitchModeSmallButton = "switchbtn_small.bmp";
const char *const ThemeEngine::kImageFastReplaySmallButton = "fastreplay_small.bmp";
+const char *const ThemeEngine::kImageDropboxLogo = "dropbox.bmp";
+const char *const ThemeEngine::kImageOneDriveLogo = "onedrive.bmp";
+const char *const ThemeEngine::kImageGoogleDriveLogo = "googledrive.bmp";
+const char *const ThemeEngine::kImageBoxLogo = "box.bmp";
struct TextDrawData {
const Graphics::Font *_fontPtr;
@@ -168,11 +174,23 @@ protected:
bool _alpha;
};
+class ThemeItemABitmap : public ThemeItem {
+public:
+ ThemeItemABitmap(ThemeEngine *engine, const Common::Rect &area, Graphics::TransparentSurface *bitmap, ThemeEngine::AutoScaleMode autoscale, int alpha) :
+ ThemeItem(engine, area), _bitmap(bitmap), _autoscale(autoscale), _alpha(alpha) {}
+
+ void drawSelf(bool draw, bool restore);
+
+protected:
+ Graphics::TransparentSurface *_bitmap;
+ ThemeEngine::AutoScaleMode _autoscale;
+ int _alpha;
+};
+
class ThemeItemBitmapClip : public ThemeItem {
public:
ThemeItemBitmapClip(ThemeEngine *engine, const Common::Rect &area, const Common::Rect &clip, const Graphics::Surface *bitmap, bool alpha) :
ThemeItem(engine, area), _bitmap(bitmap), _alpha(alpha), _clip(clip) {}
-
void drawSelf(bool draw, bool restore);
protected:
@@ -308,7 +326,7 @@ void ThemeItemBitmap::drawSelf(bool draw, bool restore) {
if (draw) {
if (_alpha)
- _engine->renderer()->blitAlphaBitmap(_bitmap, _area);
+ _engine->renderer()->blitKeyBitmap(_bitmap, _area);
else
_engine->renderer()->blitSubSurface(_bitmap, _area);
}
@@ -316,13 +334,23 @@ void ThemeItemBitmap::drawSelf(bool draw, bool restore) {
_engine->addDirtyRect(_area);
}
-void ThemeItemBitmapClip::drawSelf(bool draw, bool restore) {
+void ThemeItemABitmap::drawSelf(bool draw, bool restore) {
if (restore)
_engine->restoreBackground(_area);
+ if (draw)
+ _engine->renderer()->blitAlphaBitmap(_bitmap, _area, _autoscale, Graphics::DrawStep::kVectorAlignManual, Graphics::DrawStep::kVectorAlignManual, _alpha);
+
+ _engine->addDirtyRect(_area);
+}
+
+void ThemeItemBitmapClip::drawSelf(bool draw, bool restore) {
+ if (restore)
+ _engine->restoreBackground(_area);
+
if (draw) {
if (_alpha)
- _engine->renderer()->blitAlphaBitmapClip(_bitmap, _area, _clip);
+ _engine->renderer()->blitKeyBitmapClip(_bitmap, _area, _clip);
else
_engine->renderer()->blitSubSurfaceClip(_bitmap, _area, _clip);
}
@@ -401,6 +429,15 @@ ThemeEngine::~ThemeEngine() {
}
_bitmaps.clear();
+ for (AImagesMap::iterator i = _abitmaps.begin(); i != _abitmaps.end(); ++i) {
+ Graphics::TransparentSurface *surf = i->_value;
+ if (surf) {
+ surf->free();
+ delete surf;
+ }
+ }
+ _abitmaps.clear();
+
delete _parser;
delete _themeEval;
delete[] _cursor;
@@ -525,6 +562,15 @@ void ThemeEngine::refresh() {
}
}
_bitmaps.clear();
+
+ for (AImagesMap::iterator i = _abitmaps.begin(); i != _abitmaps.end(); ++i) {
+ Graphics::TransparentSurface *surf = i->_value;
+ if (surf) {
+ surf->free();
+ delete surf;
+ }
+ }
+ _abitmaps.clear();
}
init();
@@ -706,24 +752,51 @@ bool ThemeEngine::addBitmap(const Common::String &filename) {
if (surf)
return true;
- // If not, try to load the bitmap via the BitmapDecoder class.
- Image::BitmapDecoder bitmapDecoder;
const Graphics::Surface *srcSurface = 0;
- Common::ArchiveMemberList members;
- _themeFiles.listMatchingMembers(members, filename);
- for (Common::ArchiveMemberList::const_iterator i = members.begin(), end = members.end(); i != end; ++i) {
- Common::SeekableReadStream *stream = (*i)->createReadStream();
- if (stream) {
- bitmapDecoder.loadStream(*stream);
- srcSurface = bitmapDecoder.getSurface();
- delete stream;
- if (srcSurface)
- break;
+
+ if (filename.hasSuffix(".png")) {
+ // Maybe it is PNG?
+#ifdef USE_PNG
+ Image::PNGDecoder decoder;
+ Common::ArchiveMemberList members;
+ _themeFiles.listMatchingMembers(members, filename);
+ for (Common::ArchiveMemberList::const_iterator i = members.begin(), end = members.end(); i != end; ++i) {
+ Common::SeekableReadStream *stream = (*i)->createReadStream();
+ if (stream) {
+ if (!decoder.loadStream(*stream))
+ error("Error decoding PNG");
+
+ srcSurface = decoder.getSurface();
+ delete stream;
+ if (srcSurface)
+ break;
+ }
}
- }
- if (srcSurface && srcSurface->format.bytesPerPixel != 1)
- surf = srcSurface->convertTo(_overlayFormat);
+ if (srcSurface && srcSurface->format.bytesPerPixel != 1)
+ surf = srcSurface->convertTo(_overlayFormat);
+#else
+ error("No PNG support compiled in");
+#endif
+ } else {
+ // If not, try to load the bitmap via the BitmapDecoder class.
+ Image::BitmapDecoder bitmapDecoder;
+ Common::ArchiveMemberList members;
+ _themeFiles.listMatchingMembers(members, filename);
+ for (Common::ArchiveMemberList::const_iterator i = members.begin(), end = members.end(); i != end; ++i) {
+ Common::SeekableReadStream *stream = (*i)->createReadStream();
+ if (stream) {
+ bitmapDecoder.loadStream(*stream);
+ srcSurface = bitmapDecoder.getSurface();
+ delete stream;
+ if (srcSurface)
+ break;
+ }
+ }
+
+ if (srcSurface && srcSurface->format.bytesPerPixel != 1)
+ surf = srcSurface->convertTo(_overlayFormat);
+ }
// Store the surface into our hashmap (attention, may store NULL entries!)
_bitmaps[filename] = surf;
@@ -731,6 +804,48 @@ bool ThemeEngine::addBitmap(const Common::String &filename) {
return surf != 0;
}
+bool ThemeEngine::addAlphaBitmap(const Common::String &filename) {
+ // Nothing has to be done if the bitmap already has been loaded.
+ Graphics::TransparentSurface *surf = _abitmaps[filename];
+ if (surf)
+ return true;
+
+ const Graphics::TransparentSurface *srcSurface = 0;
+
+ if (filename.hasSuffix(".png")) {
+ // Maybe it is PNG?
+#ifdef USE_PNG
+ Image::PNGDecoder decoder;
+ Common::ArchiveMemberList members;
+ _themeFiles.listMatchingMembers(members, filename);
+ for (Common::ArchiveMemberList::const_iterator i = members.begin(), end = members.end(); i != end; ++i) {
+ Common::SeekableReadStream *stream = (*i)->createReadStream();
+ if (stream) {
+ if (!decoder.loadStream(*stream))
+ error("Error decoding PNG");
+
+ srcSurface = new Graphics::TransparentSurface(*decoder.getSurface(), true);
+ delete stream;
+ if (srcSurface)
+ break;
+ }
+ }
+
+ if (srcSurface && srcSurface->format.bytesPerPixel != 1)
+ surf = srcSurface->convertTo(_overlayFormat);
+#else
+ error("No PNG support compiled in");
+#endif
+ } else {
+ error("Only PNG is supported as alphabitmap");
+ }
+
+ // Store the surface into our hashmap (attention, may store NULL entries!)
+ _abitmaps[filename] = surf;
+
+ return surf != 0;
+}
+
bool ThemeEngine::addDrawData(const Common::String &data, bool cached) {
DrawData id = parseDrawDataId(data);
@@ -977,7 +1092,10 @@ void ThemeEngine::queueDDTextClip(TextData type, TextColor color, const Common::
area.clip(_screen.w, _screen.h);
Common::Rect textArea = drawableTextArea;
if (textArea.isEmpty()) textArea = clippingArea;
- else textArea.clip(clippingArea);
+ else {
+ textArea.clip(clippingArea);
+ if (textArea.isEmpty()) textArea = Common::Rect(0, 0, 1, 1); // one small pixel should be invisible enough
+ }
ThemeItemTextData *q = new ThemeItemTextData(this, _texts[type], _textColors[color], area, textArea, text, alignH, alignV, ellipsis, restoreBg, deltax);
@@ -1004,6 +1122,21 @@ void ThemeEngine::queueBitmap(const Graphics::Surface *bitmap, const Common::Rec
}
}
+void ThemeEngine::queueABitmap(Graphics::TransparentSurface *bitmap, const Common::Rect &r, AutoScaleMode autoscale, int alpha) {
+
+ Common::Rect area = r;
+ area.clip(_screen.w, _screen.h);
+
+ ThemeItemABitmap *q = new ThemeItemABitmap(this, area, bitmap, autoscale, alpha);
+
+ if (_buffering) {
+ _screenQueue.push_back(q);
+ } else {
+ q->drawSelf(true, false);
+ delete q;
+ }
+}
+
void ThemeEngine::queueBitmapClip(const Graphics::Surface *bitmap, const Common::Rect &r, const Common::Rect &clip, bool alpha) {
Common::Rect area = r;
@@ -1291,6 +1424,8 @@ void ThemeEngine::drawDialogBackground(const Common::Rect &r, DialogBackground b
case kDialogBackgroundDefault:
queueDD(kDDDefaultBackground, r);
break;
+ case kDialogBackgroundNone:
+ break;
}
}
@@ -1318,6 +1453,9 @@ void ThemeEngine::drawDialogBackgroundClip(const Common::Rect &r, const Common::
case kDialogBackgroundDefault:
queueDDClip(kDDDefaultBackground, r, clip);
break;
+ case kDialogBackgroundNone:
+ // no op
+ break;
}
}
@@ -1392,6 +1530,13 @@ void ThemeEngine::drawSurface(const Common::Rect &r, const Graphics::Surface &su
queueBitmap(&surface, r, themeTrans);
}
+void ThemeEngine::drawASurface(const Common::Rect &r, Graphics::TransparentSurface &surface, AutoScaleMode autoscale, int alpha) {
+ if (!ready())
+ return;
+
+ queueABitmap(&surface, r, autoscale, alpha);
+}
+
void ThemeEngine::drawSurfaceClip(const Common::Rect &r, const Common::Rect &clip, const Graphics::Surface &surface, WidgetStateInfo state, int alpha, bool themeTrans) {
if (!ready())
return;