aboutsummaryrefslogtreecommitdiff
path: root/gui
diff options
context:
space:
mode:
authorMatthew Hoops2012-03-20 14:18:57 -0400
committerMatthew Hoops2012-03-20 14:49:16 -0400
commit71756bdf4eae5ba9cc3f329b85e894f04640aaef (patch)
tree40d464262da107ab5eed82f198685209161ebac1 /gui
parent03eba05b09e5c9e5a351f8111185934b92a3fed3 (diff)
parent3c3576a224b92c703b4e8ea20008ac8a069980dd (diff)
downloadscummvm-rg350-71756bdf4eae5ba9cc3f329b85e894f04640aaef.tar.gz
scummvm-rg350-71756bdf4eae5ba9cc3f329b85e894f04640aaef.tar.bz2
scummvm-rg350-71756bdf4eae5ba9cc3f329b85e894f04640aaef.zip
Merge remote branch 'upstream/master' into pegasus
Diffstat (limited to 'gui')
-rw-r--r--gui/ThemeEngine.cpp195
-rw-r--r--gui/ThemeEngine.h19
-rw-r--r--gui/ThemeParser.cpp9
-rw-r--r--gui/ThemeParser.h2
-rw-r--r--gui/about.cpp2
-rw-r--r--gui/browser_osx.mm6
-rw-r--r--gui/credits.h16
-rw-r--r--gui/debugger.cpp5
-rw-r--r--gui/dialog.cpp27
-rw-r--r--gui/dialog.h9
-rw-r--r--gui/gui-manager.cpp71
-rw-r--r--gui/gui-manager.h1
-rw-r--r--gui/launcher.cpp7
-rw-r--r--gui/object.cpp20
-rw-r--r--gui/object.h2
-rw-r--r--gui/options.cpp74
-rw-r--r--gui/options.h6
-rw-r--r--gui/themes/default.inc40
-rw-r--r--gui/themes/fonts/FreeMonoBold.ttfbin0 -> 173608 bytes
-rw-r--r--gui/themes/fonts/FreeSans.ttfbin0 -> 714456 bytes
-rw-r--r--gui/themes/fonts/FreeSansBold.ttfbin0 -> 359272 bytes
-rw-r--r--gui/themes/fonts/README2
-rw-r--r--gui/themes/scummclassic.zipbin96043 -> 86033 bytes
-rw-r--r--gui/themes/scummclassic/THEMERC2
-rw-r--r--gui/themes/scummclassic/clR6x12-iso-8859-2.fccbin6403 -> 3724 bytes
-rw-r--r--gui/themes/scummclassic/clR6x12-iso-8859-5.fccbin6403 -> 3724 bytes
-rw-r--r--gui/themes/scummclassic/classic_layout.stx21
-rw-r--r--gui/themes/scummclassic/classic_layout_lowres.stx21
-rw-r--r--gui/themes/scummclassic/fixed5x8-iso-8859-2.fccbin4619 -> 2832 bytes
-rw-r--r--gui/themes/scummclassic/fixed5x8-iso-8859-5.fccbin3985 -> 3011 bytes
-rw-r--r--gui/themes/scummclassic/helvb12-iso-8859-2.fccbin5727 -> 4104 bytes
-rw-r--r--gui/themes/scummclassic/helvb12-iso-8859-5.fccbin5234 -> 3968 bytes
-rw-r--r--gui/themes/scummmodern.zipbin204887 -> 1441312 bytes
-rw-r--r--gui/themes/scummmodern/FreeMonoBold.ttfbin0 -> 173608 bytes
-rw-r--r--gui/themes/scummmodern/FreeSans.ttfbin0 -> 714456 bytes
-rw-r--r--gui/themes/scummmodern/FreeSansBold.ttfbin0 -> 359272 bytes
-rw-r--r--gui/themes/scummmodern/THEMERC2
-rw-r--r--gui/themes/scummmodern/clR6x12-iso-8859-2.fccbin6403 -> 3724 bytes
-rw-r--r--gui/themes/scummmodern/clR6x12-iso-8859-5.fccbin6403 -> 3724 bytes
-rw-r--r--gui/themes/scummmodern/eraser.bmpbin890 -> 824 bytes
-rw-r--r--gui/themes/scummmodern/fixed5x8-iso-8859-2.fccbin4619 -> 2832 bytes
-rw-r--r--gui/themes/scummmodern/fixed5x8-iso-8859-5.fccbin3985 -> 3011 bytes
-rw-r--r--gui/themes/scummmodern/helvb12-iso-8859-1.fccbin5615 -> 4102 bytes
-rw-r--r--gui/themes/scummmodern/helvb12-iso-8859-2.fccbin5727 -> 4104 bytes
-rw-r--r--gui/themes/scummmodern/helvb12-iso-8859-5.fccbin5234 -> 3968 bytes
-rw-r--r--gui/themes/scummmodern/scummmodern_gfx.stx14
-rw-r--r--gui/themes/scummmodern/scummmodern_layout.stx21
-rw-r--r--gui/themes/scummmodern/scummmodern_layout_lowres.stx21
-rwxr-xr-xgui/themes/scummtheme.py2
-rw-r--r--gui/themes/translations.datbin285530 -> 309938 bytes
-rw-r--r--gui/widget.cpp40
-rw-r--r--gui/widget.h2
-rw-r--r--gui/widgets/editable.cpp11
-rw-r--r--gui/widgets/edittext.cpp7
54 files changed, 481 insertions, 196 deletions
diff --git a/gui/ThemeEngine.cpp b/gui/ThemeEngine.cpp
index 6d95cab526..bcfd41e05b 100644
--- a/gui/ThemeEngine.cpp
+++ b/gui/ThemeEngine.cpp
@@ -30,10 +30,11 @@
#include "graphics/cursorman.h"
#include "graphics/fontman.h"
-#include "graphics/imagedec.h"
#include "graphics/surface.h"
#include "graphics/VectorRenderer.h"
#include "graphics/fonts/bdf.h"
+#include "graphics/fonts/ttf.h"
+#include "graphics/decoders/bmp.h"
#include "gui/widget.h"
#include "gui/ThemeEngine.h"
@@ -261,7 +262,8 @@ void ThemeItemBitmap::drawSelf(bool draw, bool restore) {
ThemeEngine::ThemeEngine(Common::String id, GraphicsMode mode) :
_system(0), _vectorRenderer(0),
_buffering(false), _bytesPerPixel(0), _graphicsMode(kGfxDisabled),
- _font(0), _initOk(false), _themeOk(false), _enabled(false), _cursor(0) {
+ _font(0), _initOk(false), _themeOk(false), _enabled(false), _themeFiles(),
+ _cursor(0) {
_system = g_system;
_parser = new ThemeParser(this);
@@ -294,6 +296,9 @@ ThemeEngine::ThemeEngine(Common::String id, GraphicsMode mode) :
_graphicsMode = mode;
_themeArchive = 0;
_initOk = false;
+
+ // We prefer files in archive bundles over the common search paths.
+ _themeFiles.add("default", &SearchMan, 0, false);
}
ThemeEngine::~ThemeEngine() {
@@ -317,7 +322,6 @@ ThemeEngine::~ThemeEngine() {
delete _parser;
delete _themeEval;
delete[] _cursor;
- delete _themeArchive;
}
@@ -406,6 +410,9 @@ bool ThemeEngine::init() {
}
}
}
+
+ if (_themeArchive)
+ _themeFiles.add("theme_archive", _themeArchive, 1, true);
}
// Load the theme
@@ -551,7 +558,7 @@ bool ThemeEngine::addTextData(const Common::String &drawDataId, TextData textId,
return true;
}
-bool ThemeEngine::addFont(TextData textId, const Common::String &file) {
+bool ThemeEngine::addFont(TextData textId, const Common::String &file, const Common::String &scalableFile, const int pointsize) {
if (textId == -1)
return false;
@@ -564,35 +571,26 @@ bool ThemeEngine::addFont(TextData textId, const Common::String &file) {
_texts[textId]->_fontPtr = _font;
} else {
Common::String localized = FontMan.genLocalizedFontFilename(file);
- // Try built-in fonts
- _texts[textId]->_fontPtr = FontMan.getFontByName(localized);
-
- if (!_texts[textId]->_fontPtr) {
- // First try to load localized font
- _texts[textId]->_fontPtr = loadFont(localized);
-
- if (_texts[textId]->_fontPtr)
- FontMan.assignFontToName(localized, _texts[textId]->_fontPtr);
+ const Common::String charset
+#ifdef USE_TRANSLATION
+ (TransMan.getCurrentCharset())
+#endif
+ ;
- // Fallback to non-localized font and default translation
- else {
- // Try built-in fonts
- _texts[textId]->_fontPtr = FontMan.getFontByName(file);
+ // Try localized fonts
+ _texts[textId]->_fontPtr = loadFont(localized, scalableFile, charset, pointsize, textId == kTextDataDefault);
- // Try to load it
- if (!_texts[textId]->_fontPtr) {
- _texts[textId]->_fontPtr = loadFont(file);
+ if (!_texts[textId]->_fontPtr) {
+ // Try standard fonts
+ _texts[textId]->_fontPtr = loadFont(file, scalableFile, Common::String(), pointsize, textId == kTextDataDefault);
- if (!_texts[textId]->_fontPtr)
- error("Couldn't load font '%s'", file.c_str());
+ if (!_texts[textId]->_fontPtr)
+ error("Couldn't load font '%s'/'%s'", file.c_str(), scalableFile.c_str());
- FontMan.assignFontToName(file, _texts[textId]->_fontPtr);
- }
#ifdef USE_TRANSLATION
- TransMan.setLanguage("C");
+ TransMan.setLanguage("C");
#endif
- warning("Failed to load localized font '%s'. Using non-localized font and default GUI language instead", localized.c_str());
- }
+ warning("Failed to load localized font '%s'. Using non-localized font and default GUI language instead", localized.c_str());
}
}
@@ -622,16 +620,25 @@ bool ThemeEngine::addBitmap(const Common::String &filename) {
if (surf)
return true;
- // If not, try to load the bitmap via the ImageDecoder class.
- surf = Graphics::ImageDecoder::loadFile(filename, _overlayFormat);
- if (!surf && _themeArchive) {
- Common::SeekableReadStream *stream = _themeArchive->createReadStreamForMember(filename);
+ // If not, try to load the bitmap via the BitmapDecoder class.
+ Graphics::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) {
- surf = Graphics::ImageDecoder::loadFile(*stream, _overlayFormat);
+ 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;
@@ -845,7 +852,7 @@ void ThemeEngine::queueBitmap(const Graphics::Surface *bitmap, const Common::Rec
ThemeItemBitmap *q = new ThemeItemBitmap(this, area, bitmap, alpha);
if (_buffering) {
- _bufferQueue.push_back(q);
+ _screenQueue.push_back(q);
} else {
q->drawSelf(true, false);
delete q;
@@ -904,7 +911,7 @@ void ThemeEngine::drawCheckbox(const Common::Rect &r, const Common::String &str,
r2.left = r2.right + checkBoxSize;
r2.right = r.right;
- queueDDText(getTextData(dd), getTextColor(dd), r2, str, false, false, _widgets[kDDCheckboxDefault]->_textAlignH, _widgets[dd]->_textAlignV);
+ queueDDText(getTextData(dd), getTextColor(dd), r2, str, true, false, _widgets[kDDCheckboxDefault]->_textAlignH, _widgets[dd]->_textAlignV);
}
void ThemeEngine::drawRadiobutton(const Common::Rect &r, const Common::String &str, bool checked, WidgetStateInfo state) {
@@ -930,7 +937,7 @@ void ThemeEngine::drawRadiobutton(const Common::Rect &r, const Common::String &s
r2.left = r2.right + checkBoxSize;
r2.right = r.right;
- queueDDText(getTextData(dd), getTextColor(dd), r2, str, false, false, _widgets[kDDRadiobuttonDefault]->_textAlignH, _widgets[dd]->_textAlignV);
+ queueDDText(getTextData(dd), getTextColor(dd), r2, str, true, false, _widgets[kDDRadiobuttonDefault]->_textAlignH, _widgets[dd]->_textAlignV);
}
void ThemeEngine::drawSlider(const Common::Rect &r, int width, WidgetStateInfo state) {
@@ -1371,6 +1378,10 @@ int ThemeEngine::getCharWidth(byte c, FontStyle font) const {
return ready() ? _texts[fontStyleToData(font)]->_fontPtr->getCharWidth(c) : 0;
}
+int ThemeEngine::getKerningOffset(byte left, byte right, FontStyle font) const {
+ return ready() ? _texts[fontStyleToData(font)]->_fontPtr->getKerningOffset(left, right) : 0;
+}
+
TextData ThemeEngine::getTextData(DrawData ddId) const {
return _widgets[ddId] ? (TextData)_widgets[ddId]->_textDataId : kTextDataNone;
}
@@ -1391,66 +1402,90 @@ DrawData ThemeEngine::parseDrawDataId(const Common::String &name) const {
* External data loading
*********************************************************/
-const Graphics::Font *ThemeEngine::loadFontFromArchive(const Common::String &filename) {
- Common::SeekableReadStream *stream = 0;
- const Graphics::Font *font = 0;
+const Graphics::Font *ThemeEngine::loadScalableFont(const Common::String &filename, const Common::String &charset, const int pointsize, Common::String &name) {
+#ifdef USE_FREETYPE2
+ name = Common::String::format("%s-%s@%d", filename.c_str(), charset.c_str(), pointsize);
- if (_themeArchive)
- stream = _themeArchive->createReadStreamForMember(filename);
- if (stream) {
- font = Graphics::BdfFont::loadFont(*stream);
- delete stream;
- }
+ // Try already loaded fonts.
+ const Graphics::Font *font = FontMan.getFontByName(name);
+ if (font)
+ return font;
- return font;
-}
+ Common::ArchiveMemberList members;
+ _themeFiles.listMatchingMembers(members, filename);
-const Graphics::Font *ThemeEngine::loadCachedFontFromArchive(const Common::String &filename) {
- Common::SeekableReadStream *stream = 0;
- const Graphics::Font *font = 0;
+ for (Common::ArchiveMemberList::const_iterator i = members.begin(), end = members.end(); i != end; ++i) {
+ Common::SeekableReadStream *stream = (*i)->createReadStream();
+ if (stream) {
+ font = Graphics::loadTTFFont(*stream, pointsize, false,
+#ifdef USE_TRANSLATION
+ TransMan.getCharsetMapping()
+#else
+ 0
+#endif
+ );
+ delete stream;
- if (_themeArchive)
- stream = _themeArchive->createReadStreamForMember(filename);
- if (stream) {
- font = Graphics::BdfFont::loadFromCache(*stream);
- delete stream;
+ if (font)
+ return font;
+ }
}
-
- return font;
+#endif
+ return 0;
}
-const Graphics::Font *ThemeEngine::loadFont(const Common::String &filename) {
- const Graphics::Font *font = 0;
- Common::String cacheFilename = genCacheFilename(filename);
- Common::File fontFile;
+const Graphics::Font *ThemeEngine::loadFont(const Common::String &filename, Common::String &name) {
+ name = filename;
- if (!cacheFilename.empty()) {
- if (fontFile.open(cacheFilename)) {
- font = Graphics::BdfFont::loadFromCache(fontFile);
- }
+ // Try already loaded fonts.
+ const Graphics::Font *font = FontMan.getFontByName(name);
+ if (font)
+ return font;
- if (font)
- return font;
+ Common::ArchiveMemberList members;
+ const Common::String cacheFilename(genCacheFilename(filename));
+ _themeFiles.listMatchingMembers(members, cacheFilename);
+ _themeFiles.listMatchingMembers(members, filename);
- if ((font = loadCachedFontFromArchive(cacheFilename)))
- return font;
- }
+ for (Common::ArchiveMemberList::const_iterator i = members.begin(), end = members.end(); i != end; ++i) {
+ Common::SeekableReadStream *stream = (*i)->createReadStream();
+ if (stream) {
+ if ((*i)->getName().equalsIgnoreCase(cacheFilename)) {
+ font = Graphics::BdfFont::loadFromCache(*stream);
+ } else {
+ font = Graphics::BdfFont::loadFont(*stream);
+ if (font && !cacheFilename.empty()) {
+ if (!Graphics::BdfFont::cacheFontData(*(const Graphics::BdfFont *)font, cacheFilename))
+ warning("Couldn't create cache file for font '%s'", filename.c_str());
+ }
+ }
+ delete stream;
- // normal open
- if (fontFile.open(filename)) {
- font = Graphics::BdfFont::loadFont(fontFile);
+ if (font)
+ return font;
+ }
}
- if (!font) {
- font = loadFontFromArchive(filename);
- }
+ return 0;
+}
+const Graphics::Font *ThemeEngine::loadFont(const Common::String &filename, const Common::String &scalableFilename, const Common::String &charset, const int pointsize, const bool makeLocalizedFont) {
+ Common::String fontName;
+
+ const Graphics::Font *font = 0;
+
+ // Prefer scalable fonts over non-scalable fonts
+ font = loadScalableFont(scalableFilename, charset, pointsize, fontName);
+ if (!font)
+ font = loadFont(filename, fontName);
+
+ // If the font is successfully loaded store it in the font manager.
if (font) {
- if (!cacheFilename.empty()) {
- if (!Graphics::BdfFont::cacheFontData(*(const Graphics::BdfFont *)font, cacheFilename)) {
- warning("Couldn't create cache file for font '%s'", filename.c_str());
- }
- }
+ FontMan.assignFontToName(fontName, font);
+ // If this font should be the new default localized font, we set it up
+ // for that.
+ if (makeLocalizedFont)
+ FontMan.setLocalizedFont(fontName);
}
return font;
diff --git a/gui/ThemeEngine.h b/gui/ThemeEngine.h
index 0029886de5..f041f85ab9 100644
--- a/gui/ThemeEngine.h
+++ b/gui/ThemeEngine.h
@@ -35,7 +35,7 @@
#include "graphics/pixelformat.h"
-#define SCUMMVM_THEME_VERSION_STR "SCUMMVM_STX0.8.5"
+#define SCUMMVM_THEME_VERSION_STR "SCUMMVM_STX0.8.8"
class OSystem;
@@ -310,6 +310,8 @@ public:
int getCharWidth(byte c, FontStyle font = kFontStyleBold) const;
+ int getKerningOffset(byte left, byte right, FontStyle font = kFontStyleBold) const;
+
//@}
@@ -411,10 +413,12 @@ public:
* Interface for the ThemeParser class: Loads a font to use on the GUI from the given
* filename.
*
- * @param fontName Identifier name for the font.
- * @param file Name of the font file.
+ * @param fextId Identifier name for the font.
+ * @param file Filename of the non-scalable font version.
+ * @param scalableFile Filename of the scalable version. (Optional)
+ * @param pointsize Point size for the scalable font. (Optional)
*/
- bool addFont(TextData textId, const Common::String &file);
+ bool addFont(TextData textId, const Common::String &file, const Common::String &scalableFile, const int pointsize);
/**
* Interface for the ThemeParser class: adds a text color value.
@@ -536,10 +540,10 @@ protected:
*/
void unloadTheme();
- const Graphics::Font *loadFont(const Common::String &filename);
- const Graphics::Font *loadFontFromArchive(const Common::String &filename);
- const Graphics::Font *loadCachedFontFromArchive(const Common::String &filename);
+ const Graphics::Font *loadScalableFont(const Common::String &filename, const Common::String &charset, const int pointsize, Common::String &name);
+ const Graphics::Font *loadFont(const Common::String &filename, Common::String &name);
Common::String genCacheFilename(const Common::String &filename) const;
+ const Graphics::Font *loadFont(const Common::String &filename, const Common::String &scalableFilename, const Common::String &charset, const int pointsize, const bool makeLocalizedFont);
/**
* Actual Dirty Screen handling function.
@@ -658,6 +662,7 @@ protected:
Common::String _themeId;
Common::String _themeFile;
Common::Archive *_themeArchive;
+ Common::SearchSet _themeFiles;
bool _useCursor;
int _cursorHotspotX, _cursorHotspotY;
diff --git a/gui/ThemeParser.cpp b/gui/ThemeParser.cpp
index ea50dcc061..9ccdedd564 100644
--- a/gui/ThemeParser.cpp
+++ b/gui/ThemeParser.cpp
@@ -176,8 +176,15 @@ bool ThemeParser::parserCallback_font(ParserNode *node) {
return true;
}
+ // Default to a point size of 12.
+ int pointsize = 12;
+ if (node->values.contains("point_size")) {
+ if (sscanf(node->values["point_size"].c_str(), "%d", &pointsize) != 1 || pointsize <= 0)
+ return parserError(Common::String::format("Font \"%s\" has invalid point size \"%s\"", node->values["id"].c_str(), node->values["point_size"].c_str()));
+ }
+
TextData textDataId = parseTextDataId(node->values["id"]);
- if (!_theme->addFont(textDataId, node->values["file"]))
+ if (!_theme->addFont(textDataId, node->values["file"], node->values["scalable_file"], pointsize))
return parserError("Error loading Font in theme engine.");
return true;
diff --git a/gui/ThemeParser.h b/gui/ThemeParser.h
index 1999850643..4b7e88cbf3 100644
--- a/gui/ThemeParser.h
+++ b/gui/ThemeParser.h
@@ -65,6 +65,8 @@ protected:
XML_PROP(id, true)
XML_PROP(file, true)
XML_PROP(resolution, false)
+ XML_PROP(scalable_file, false)
+ XML_PROP(point_size, false)
KEY_END()
XML_KEY(text_color)
diff --git a/gui/about.cpp b/gui/about.cpp
index 00dbc5fe0b..03be1f8992 100644
--- a/gui/about.cpp
+++ b/gui/about.cpp
@@ -54,7 +54,7 @@ enum {
static const char *copyright_text[] = {
"",
-"C0""Copyright (C) 2001-2011 The ScummVM project",
+"C0""Copyright (C) 2001-2012 The ScummVM project",
"C0""http://www.scummvm.org",
"",
"C0""ScummVM is the legal property of its developers, whose names are too numerous to list here. Please refer to the COPYRIGHT file distributed with this binary.",
diff --git a/gui/browser_osx.mm b/gui/browser_osx.mm
index 017b31b9a8..b8aa7c50ee 100644
--- a/gui/browser_osx.mm
+++ b/gui/browser_osx.mm
@@ -62,11 +62,7 @@ int BrowserDialog::runModal() {
NSOpenPanel * panel = [NSOpenPanel openPanel];
[panel setCanChooseDirectories:YES];
if ([panel runModalForTypes:nil] == NSOKButton) {
-#ifdef __POWERPC__
- const char *filename = [[panel filename] cString];
-#else
- const char *filename = [[panel filename] cStringUsingEncoding:NSUTF8StringEncoding];
-#endif
+ const char *filename = [[panel filename] UTF8String];
_choice = Common::FSNode(filename);
choiceMade = true;
}
diff --git a/gui/credits.h b/gui/credits.h
index 08be2e0534..ecfe280d20 100644
--- a/gui/credits.h
+++ b/gui/credits.h
@@ -39,6 +39,7 @@ static const char *credits[] = {
"C0""Pawel Kolodziejski",
"C2""Codecs, iMUSE, Smush, etc.",
"C0""Gregory Montoir",
+"C2""(retired)",
"C0""Eugene Sandulenko",
"C2""FT INSANE, MM NES, MM C64, game detection, Herc/CGA",
"C0""Ludvig Strigeus",
@@ -49,6 +50,7 @@ static const char *credits[] = {
"C2""(retired)",
"C0""Travis Howell",
"C0""Gregory Montoir",
+"C2""(retired)",
"C0""Eugene Sandulenko",
"",
"C1""AGI",
@@ -81,6 +83,7 @@ static const char *credits[] = {
"C2""(retired)",
"C0""Pawel Kolodziejski",
"C0""Gregory Montoir",
+"C2""(retired)",
"C0""Kari Salminen",
"C0""Eugene Sandulenko",
"",
@@ -128,6 +131,7 @@ static const char *credits[] = {
"C0""Oystein Eftevaag",
"C0""Florian Kagerer",
"C0""Gregory Montoir",
+"C2""(retired)",
"C0""Johannes Schickel",
"",
"C1""Lastexpress",
@@ -157,10 +161,13 @@ static const char *credits[] = {
"C0""David Eriksson",
"C2""(retired)",
"C0""Gregory Montoir",
+"C2""(retired)",
"C0""Joost Peters",
"",
"C1""SAGA",
"C0""Torbj\366rn Andersson",
+"C0""Daniel Balsom",
+"C2""Original engine reimplementation author (retired)",
"C0""Filippos Karapetis",
"C0""Andrew Kurushin",
"C0""Eugene Sandulenko",
@@ -230,6 +237,7 @@ static const char *credits[] = {
"",
"C1""Touch\351",
"C0""Gregory Montoir",
+"C2""(retired)",
"",
"C1""TsAGE",
"C0""Arnaud Boutonn\351",
@@ -237,6 +245,7 @@ static const char *credits[] = {
"",
"C1""Tucker",
"C0""Gregory Montoir",
+"C2""(retired)",
"",
"",
"C1""Backend Teams",
@@ -450,6 +459,9 @@ static const char *credits[] = {
"C1""Translations",
"C0""Thierry Crozat",
"C2""Translation Lead",
+"C1""Basque",
+"C0""Mikel Iturbe Urretxa",
+"",
"C1""Catalan",
"C0""Jordi Vilalta Prat",
"",
@@ -560,6 +572,8 @@ static const char *credits[] = {
"C2""Final MI1 CD music support, initial Ogg Vorbis support",
"C0""Andr\351 Souza",
"C2""SDL-based OpenGL renderer",
+"C0""Tom Frost",
+"C2""WebOS port contributions",
"",
"C1""FreeSCI Contributors",
"C0""Francois-R Boyer",
@@ -642,6 +656,8 @@ static const char *credits[] = {
"",
"C1""Special thanks to",
"",
+"C0""Daniel Balsom",
+"C2""For the original Reinherit (SAGA) code",
"C0""Sander Buskens",
"C2""For his work on the initial reversing of Monkey2",
"C0""Canadacow",
diff --git a/gui/debugger.cpp b/gui/debugger.cpp
index 26e62dc1d9..972163df6f 100644
--- a/gui/debugger.cpp
+++ b/gui/debugger.cpp
@@ -200,9 +200,8 @@ void Debugger::enter() {
bool Debugger::handleCommand(int argc, const char **argv, bool &result) {
if (_cmds.contains(argv[0])) {
- Debuglet *debuglet = _cmds[argv[0]].get();
- assert(debuglet);
- result = (*debuglet)(argc, argv);
+ assert(_cmds[argv[0]]);
+ result = (*_cmds[argv[0]])(argc, argv);
return true;
}
diff --git a/gui/dialog.cpp b/gui/dialog.cpp
index 0522b40b46..2201e83ca5 100644
--- a/gui/dialog.cpp
+++ b/gui/dialog.cpp
@@ -21,6 +21,10 @@
#include "common/rect.h"
+#ifdef ENABLE_KEYMAPPER
+#include "common/events.h"
+#endif
+
#include "gui/gui-manager.h"
#include "gui/dialog.h"
#include "gui/widget.h"
@@ -314,6 +318,9 @@ void Dialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) {
}
}
+#ifdef ENABLE_KEYMAPPER
+void Dialog::handleOtherEvent(Common::Event evt) { }
+#endif
/*
* Determine the widget at location (x,y) if any. Assumes the coordinates are
* in the local coordinate system, i.e. relative to the top left of the dialog.
@@ -334,25 +341,7 @@ void Dialog::removeWidget(Widget *del) {
if (del == _dragWidget)
_dragWidget = NULL;
- Widget *w = _firstWidget;
-
- if (del == _firstWidget) {
- Widget *del_next = del->_next;
- del->_next = 0;
- _firstWidget = del_next;
- return;
- }
-
- w = _firstWidget;
- while (w) {
- if (w->_next == del) {
- Widget *del_next = del->_next;
- del->_next = 0;
- w->_next = del_next;
- return;
- }
- w = w->_next;
- }
+ GuiObject::removeWidget(del);
}
} // End of namespace GUI
diff --git a/gui/dialog.h b/gui/dialog.h
index a324450996..f5a5f94a68 100644
--- a/gui/dialog.h
+++ b/gui/dialog.h
@@ -29,6 +29,12 @@
#include "gui/object.h"
#include "gui/ThemeEngine.h"
+#ifdef ENABLE_KEYMAPPER
+namespace Common {
+struct Event;
+}
+#endif
+
namespace GUI {
class Widget;
@@ -82,6 +88,9 @@ protected:
virtual void handleKeyUp(Common::KeyState state);
virtual void handleMouseMoved(int x, int y, int button);
virtual void handleCommand(CommandSender *sender, uint32 cmd, uint32 data);
+#ifdef ENABLE_KEYMAPPER
+ virtual void handleOtherEvent(Common::Event evt);
+#endif
Widget *findWidget(int x, int y); // Find the widget at pos x,y if any
Widget *findWidget(const char *name);
diff --git a/gui/gui-manager.cpp b/gui/gui-manager.cpp
index 98840e6daf..ffecd928bc 100644
--- a/gui/gui-manager.cpp
+++ b/gui/gui-manager.cpp
@@ -103,27 +103,31 @@ GuiManager::~GuiManager() {
void GuiManager::initKeymap() {
using namespace Common;
- bool tmp;
Keymapper *mapper = _system->getEventManager()->getKeymapper();
// Do not try to recreate same keymap over again
- if (mapper->getKeymap(kGuiKeymapName, tmp) != 0)
+ if (mapper->getKeymap(kGuiKeymapName) != 0)
return;
Action *act;
Keymap *guiMap = new Keymap(kGuiKeymapName);
- act = new Action(guiMap, "CLOS", _("Close"), kGenericActionType, kStartKeyType);
+ act = new Action(guiMap, "CLOS", _("Close"));
act->addKeyEvent(KeyState(KEYCODE_ESCAPE, ASCII_ESCAPE, 0));
act = new Action(guiMap, "CLIK", _("Mouse click"));
act->addLeftClickEvent();
- act = new Action(guiMap, "VIRT", _("Display keyboard"), kVirtualKeyboardActionType);
- act->addKeyEvent(KeyState(KEYCODE_F7, ASCII_F7, 0));
+#ifdef ENABLE_VKEYBD
+ act = new Action(guiMap, "VIRT", _("Display keyboard"));
+ act->addEvent(EVENT_VIRTUAL_KEYBOARD);
+#endif
+
+ act = new Action(guiMap, "REMP", _("Remap keys"));
+ act->addEvent(EVENT_KEYMAPPER_REMAP);
- act = new Action(guiMap, "REMP", _("Remap keys"), kKeyRemapActionType);
- act->addKeyEvent(KeyState(KEYCODE_F8, ASCII_F8, 0));
+ act = new Action(guiMap, "FULS", _("Toggle FullScreen"));
+ act->addKeyEvent(KeyState(KEYCODE_RETURN, ASCII_RETURN, KBD_ALT));
mapper->addGlobalKeymap(guiMap);
}
@@ -133,15 +137,7 @@ void GuiManager::pushKeymap() {
}
void GuiManager::popKeymap() {
- Common::Keymapper *keymapper = _system->getEventManager()->getKeymapper();
- if (!keymapper->getActiveStack().empty()) {
- Common::Keymapper::MapRecord topKeymap = keymapper->getActiveStack().top();
- // TODO: Don't use the keymap name as a way to discriminate GUI maps
- if(topKeymap.keymap->getName().equals(Common::kGuiKeymapName))
- keymapper->popKeymap();
- else
- warning("An attempt to pop non-gui keymap %s was blocked", topKeymap.keymap->getName().c_str());
- }
+ _system->getEventManager()->getKeymapper()->popKeymap(Common::kGuiKeymapName);
}
#endif
@@ -192,7 +188,7 @@ bool GuiManager::loadNewTheme(Common::String id, ThemeEngine::GraphicsMode gfx,
}
// refresh all dialogs
- for (int i = 0; i < _dialogStack.size(); ++i)
+ for (DialogStack::size_type i = 0; i < _dialogStack.size(); ++i)
_dialogStack[i]->reflowLayout();
// We need to redraw immediately. Otherwise
@@ -206,7 +202,6 @@ bool GuiManager::loadNewTheme(Common::String id, ThemeEngine::GraphicsMode gfx,
}
void GuiManager::redraw() {
- int i;
ThemeEngine::ShadingStyle shading;
if (_redrawStatus == kRedrawDisabled || _dialogStack.empty())
@@ -227,7 +222,7 @@ void GuiManager::redraw() {
_theme->clearAll();
_theme->openDialog(true, ThemeEngine::kShadingNone);
- for (i = 0; i < _dialogStack.size() - 1; i++)
+ for (DialogStack::size_type i = 0; i < _dialogStack.size() - 1; i++)
_dialogStack[i]->drawDialog();
_theme->finishBuffering();
@@ -286,18 +281,9 @@ void GuiManager::runLoop() {
uint32 lastRedraw = 0;
const uint32 waitTime = 1000 / 45;
-#ifdef ENABLE_KEYMAPPER
- // Due to circular reference with event manager and GUI
- // we cannot init keymap on the GUI creation. Thus, let's
- // try to do it on every launch, checking whether the
- // map is already existing
- initKeymap();
- pushKeymap();
-#endif
-
bool tooltipCheck = false;
- while (!_dialogStack.empty() && activeDialog == getTopDialog()) {
+ while (!_dialogStack.empty() && activeDialog == getTopDialog() && !eventMan->shouldQuit()) {
redraw();
// Don't "tickle" the dialog until the theme has had a chance
@@ -376,12 +362,13 @@ void GuiManager::runLoop() {
case Common::EVENT_WHEELDOWN:
activeDialog->handleMouseWheel(mouse.x, mouse.y, 1);
break;
- case Common::EVENT_QUIT:
- return;
case Common::EVENT_SCREEN_CHANGED:
screenChange();
break;
default:
+#ifdef ENABLE_KEYMAPPER
+ activeDialog->handleOtherEvent(event);
+#endif
break;
}
@@ -406,9 +393,16 @@ void GuiManager::runLoop() {
_system->delayMillis(10);
}
-#ifdef ENABLE_KEYMAPPER
- popKeymap();
-#endif
+ // WORKAROUND: When quitting we might not properly close the dialogs on
+ // the dialog stack, thus we do this here to avoid any problems.
+ // This is most noticable in bug #3481395 "LAUNCHER: Can't quit from unsupported game dialog".
+ // It seems that Dialog::runModal never removes the dialog from the dialog
+ // stack, thus if the dialog does not call Dialog::close to close itself
+ // it will never be removed. Since we can have multiple run loops being
+ // called we cannot rely on catching EVENT_QUIT in the event loop above,
+ // since it would only catch it for the top run loop.
+ if (eventMan->shouldQuit() && activeDialog == getTopDialog())
+ getTopDialog()->close();
if (didSaveState) {
_theme->disable();
@@ -420,6 +414,10 @@ void GuiManager::runLoop() {
#pragma mark -
void GuiManager::saveState() {
+#ifdef ENABLE_KEYMAPPER
+ initKeymap();
+ pushKeymap();
+#endif
// Backup old cursor
_lastClick.x = _lastClick.y = 0;
_lastClick.time = 0;
@@ -429,6 +427,9 @@ void GuiManager::saveState() {
}
void GuiManager::restoreState() {
+#ifdef ENABLE_KEYMAPPER
+ popKeymap();
+#endif
if (_useStdCursor) {
CursorMan.popCursor();
CursorMan.popCursorPalette();
@@ -516,7 +517,7 @@ void GuiManager::screenChange() {
_theme->refresh();
// refresh all dialogs
- for (int i = 0; i < _dialogStack.size(); ++i) {
+ for (DialogStack::size_type i = 0; i < _dialogStack.size(); ++i) {
_dialogStack[i]->reflowLayout();
}
// We need to redraw immediately. Otherwise
diff --git a/gui/gui-manager.h b/gui/gui-manager.h
index addd2e6611..49542fd001 100644
--- a/gui/gui-manager.h
+++ b/gui/gui-manager.h
@@ -81,6 +81,7 @@ public:
int getFontHeight(ThemeEngine::FontStyle style = ThemeEngine::kFontStyleBold) const { return _theme->getFontHeight(style); }
int getStringWidth(const Common::String &str, ThemeEngine::FontStyle style = ThemeEngine::kFontStyleBold) const { return _theme->getStringWidth(str, style); }
int getCharWidth(byte c, ThemeEngine::FontStyle style = ThemeEngine::kFontStyleBold) const { return _theme->getCharWidth(c, style); }
+ int getKerningOffset(byte left, byte right, ThemeEngine::FontStyle font = ThemeEngine::kFontStyleBold) const { return _theme->getKerningOffset(left, right, font); }
/**
* Tell the GuiManager to check whether the screen resolution has changed.
diff --git a/gui/launcher.cpp b/gui/launcher.cpp
index c737b81b33..a3e4925848 100644
--- a/gui/launcher.cpp
+++ b/gui/launcher.cpp
@@ -24,6 +24,7 @@
#include "common/config-manager.h"
#include "common/events.h"
#include "common/fs.h"
+#include "common/gui_options.h"
#include "common/util.h"
#include "common/system.h"
#include "common/translation.h"
@@ -90,7 +91,7 @@ public:
protected:
bool tryInsertChar(byte c, int pos) {
- if (isalnum(c) || c == '-' || c == '_') {
+ if (Common::isAlnum(c) || c == '-' || c == '_') {
_editString.insertChar(c, pos);
return true;
}
@@ -1084,7 +1085,7 @@ void LauncherDialog::updateButtons() {
void LauncherDialog::reflowLayout() {
#ifndef DISABLE_FANCY_THEMES
if (g_gui.xmlEval()->getVar("Globals.ShowLauncherLogo") == 1 && g_gui.theme()->supportsImages()) {
- StaticTextWidget *ver = (StaticTextWidget*)findWidget("Launcher.Version");
+ StaticTextWidget *ver = (StaticTextWidget *)findWidget("Launcher.Version");
if (ver) {
ver->setAlign((Graphics::TextAlign)g_gui.xmlEval()->getVar("Launcher.Version.Align", Graphics::kTextAlignCenter));
ver->setLabel(gScummVMVersionDate);
@@ -1095,7 +1096,7 @@ void LauncherDialog::reflowLayout() {
_logo->useThemeTransparency(true);
_logo->setGfx(g_gui.theme()->getImageSurface(ThemeEngine::kImageLogo));
} else {
- StaticTextWidget *ver = (StaticTextWidget*)findWidget("Launcher.Version");
+ StaticTextWidget *ver = (StaticTextWidget *)findWidget("Launcher.Version");
if (ver) {
ver->setAlign((Graphics::TextAlign)g_gui.xmlEval()->getVar("Launcher.Version.Align", Graphics::kTextAlignCenter));
ver->setLabel(gScummVMFullVersion);
diff --git a/gui/object.cpp b/gui/object.cpp
index 2ec42df9d7..73c4f74d6c 100644
--- a/gui/object.cpp
+++ b/gui/object.cpp
@@ -59,4 +59,24 @@ void GuiObject::reflowLayout() {
}
}
+void GuiObject::removeWidget(Widget *del) {
+ if (del == _firstWidget) {
+ Widget *del_next = del->next();
+ del->setNext(0);
+ _firstWidget = del_next;
+ return;
+ }
+
+ Widget *w = _firstWidget;
+ while (w) {
+ if (w->next() == del) {
+ Widget *del_next = del->next();
+ del->setNext(0);
+ w->setNext(del_next);
+ return;
+ }
+ w = w->next();
+ }
+}
+
} // End of namespace GUI
diff --git a/gui/object.h b/gui/object.h
index 34ff0d47f2..bce3cd7846 100644
--- a/gui/object.h
+++ b/gui/object.h
@@ -83,6 +83,8 @@ public:
virtual void reflowLayout();
+ virtual void removeWidget(Widget *widget);
+
protected:
virtual void releaseFocus() = 0;
};
diff --git a/gui/options.cpp b/gui/options.cpp
index dfa30d1e3e..6747195a1b 100644
--- a/gui/options.cpp
+++ b/gui/options.cpp
@@ -30,6 +30,8 @@
#include "common/fs.h"
#include "common/config-manager.h"
+#include "common/gui_options.h"
+#include "common/rendermode.h"
#include "common/system.h"
#include "common/textconsole.h"
#include "common/translation.h"
@@ -79,7 +81,7 @@ static const char *outputRateLabels[] = { _s("<default>"), _s("8 kHz"), _s("11kH
static const int outputRateValues[] = { 0, 8000, 11025, 22050, 44100, 48000, -1 };
OptionsDialog::OptionsDialog(const Common::String &domain, int x, int y, int w, int h)
- : Dialog(x, y, w, h), _domain(domain), _graphicsTabId(-1), _tabWidget(0) {
+ : Dialog(x, y, w, h), _domain(domain), _graphicsTabId(-1), _midiTabId(-1), _pathsTabId(-1), _tabWidget(0) {
init();
}
@@ -191,9 +193,9 @@ void OptionsDialog::open() {
int sel = 0;
for (int i = 0; p->code; ++p, ++i) {
if (renderMode == p->id)
- sel = i + 2;
+ sel = p->id;
}
- _renderModePopUp->setSelected(sel);
+ _renderModePopUp->setSelectedTag(sel);
}
#ifdef SMALL_SCREEN_DEVICE
@@ -748,13 +750,18 @@ void OptionsDialog::addGraphicControls(GuiObject *boss, const Common::String &pr
}
// RenderMode popup
+ const Common::String allFlags = Common::allRenderModesGUIOs();
+ bool renderingTypeDefined = (strpbrk(_guioptions.c_str(), allFlags.c_str()) != NULL);
+
_renderModePopUpDesc = new StaticTextWidget(boss, prefix + "grRenderPopupDesc", _("Render mode:"), _("Special dithering modes supported by some games"));
_renderModePopUp = new PopUpWidget(boss, prefix + "grRenderPopup", _("Special dithering modes supported by some games"));
_renderModePopUp->appendEntry(_("<default>"), Common::kRenderDefault);
_renderModePopUp->appendEntry("");
const Common::RenderModeDescription *rm = Common::g_renderModes;
for (; rm->code; ++rm) {
- _renderModePopUp->appendEntry(_c(rm->description, context), rm->id);
+ Common::String renderGuiOption = Common::renderMode2GUIO(rm->id);
+ if ((_domain == Common::ConfigManager::kApplicationDomain) || (_domain != Common::ConfigManager::kApplicationDomain && !renderingTypeDefined) || (_guioptions.contains(renderGuiOption)))
+ _renderModePopUp->appendEntry(_c(rm->description, context), rm->id);
}
// Fullscreen checkbox
@@ -1003,7 +1010,7 @@ bool OptionsDialog::loadMusicDeviceSetting(PopUpWidget *popup, Common::String se
for (MusicDevices::iterator d = i.begin(); d != i.end(); ++d) {
if (setting.empty() ? (preferredType == d->getMusicType()) : (drv == d->getCompleteId())) {
popup->setSelectedTag(d->getHandle());
- return popup->getSelected() == -1 ? false : true;
+ return popup->getSelected() != -1;
}
}
}
@@ -1033,22 +1040,6 @@ void OptionsDialog::saveMusicDeviceSetting(PopUpWidget *popup, Common::String se
ConfMan.removeKey(setting, _domain);
}
-ButtonWidget *addClearButton(GuiObject *boss, const Common::String &name, uint32 cmd) {
- ButtonWidget *button;
-
-#ifndef DISABLE_FANCY_THEMES
- if (g_gui.xmlEval()->getVar("Globals.ShowSearchPic") == 1 && g_gui.theme()->supportsImages()) {
- button = new PicButtonWidget(boss, name, _("Clear value"), cmd);
- ((PicButtonWidget *)button)->useThemeTransparency(true);
- ((PicButtonWidget *)button)->setGfx(g_gui.theme()->getImageSurface(ThemeEngine::kImageEraser));
- } else
-#endif
- button = new ButtonWidget(boss, name, "C", _("Clear value"), cmd);
-
- return button;
-}
-
-
int OptionsDialog::getSubtitleMode(bool subtitles, bool speech_mute) {
if (_guioptions.contains(GUIO_NOSUBTITLES))
return kSubtitlesSpeech; // Speech only
@@ -1106,7 +1097,7 @@ GlobalOptionsDialog::GlobalOptionsDialog()
//
// 3) The MIDI tab
//
- tab->addTab(_("MIDI"));
+ _midiTabId = tab->addTab(_("MIDI"));
addMIDIControls(tab, "GlobalOptions_MIDI.");
//
@@ -1119,9 +1110,9 @@ GlobalOptionsDialog::GlobalOptionsDialog()
// 5) The Paths tab
//
if (g_system->getOverlayWidth() > 320)
- tab->addTab(_("Paths"));
+ _pathsTabId = tab->addTab(_("Paths"));
else
- tab->addTab(_c("Paths", "lowres"));
+ _pathsTabId = tab->addTab(_c("Paths", "lowres"));
#if !( defined(__DC__) || defined(__GP32__) )
// These two buttons have to be extra wide, or the text will be
@@ -1480,4 +1471,39 @@ void GlobalOptionsDialog::handleCommand(CommandSender *sender, uint32 cmd, uint3
}
}
+void GlobalOptionsDialog::reflowLayout() {
+ int activeTab = _tabWidget->getActiveTab();
+
+ if (_midiTabId != -1) {
+ _tabWidget->setActiveTab(_midiTabId);
+
+ _tabWidget->removeWidget(_soundFontClearButton);
+ _soundFontClearButton->setNext(0);
+ delete _soundFontClearButton;
+ _soundFontClearButton = addClearButton(_tabWidget, "GlobalOptions_MIDI.mcFontClearButton", kClearSoundFontCmd);
+ }
+
+ if (_pathsTabId != -1) {
+ _tabWidget->setActiveTab(_pathsTabId);
+
+ _tabWidget->removeWidget(_savePathClearButton);
+ _savePathClearButton->setNext(0);
+ delete _savePathClearButton;
+ _savePathClearButton = addClearButton(_tabWidget, "GlobalOptions_Paths.SavePathClearButton", kSavePathClearCmd);
+
+ _tabWidget->removeWidget(_themePathClearButton);
+ _themePathClearButton->setNext(0);
+ delete _themePathClearButton;
+ _themePathClearButton = addClearButton(_tabWidget, "GlobalOptions_Paths.ThemePathClearButton", kThemePathClearCmd);
+
+ _tabWidget->removeWidget(_extraPathClearButton);
+ _extraPathClearButton->setNext(0);
+ delete _extraPathClearButton;
+ _extraPathClearButton = addClearButton(_tabWidget, "GlobalOptions_Paths.ExtraPathClearButton", kExtraPathClearCmd);
+ }
+
+ _tabWidget->setActiveTab(activeTab);
+ OptionsDialog::reflowLayout();
+}
+
} // End of namespace GUI
diff --git a/gui/options.h b/gui/options.h
index 479f836ec0..05b3cac617 100644
--- a/gui/options.h
+++ b/gui/options.h
@@ -43,8 +43,6 @@ class GuiObject;
class RadiobuttonGroup;
class RadiobuttonWidget;
-ButtonWidget *addClearButton(GuiObject *boss, const Common::String &name, uint32 cmd);
-
class OptionsDialog : public Dialog {
public:
OptionsDialog(const Common::String &domain, int x, int y, int w, int h);
@@ -89,6 +87,8 @@ protected:
TabWidget *_tabWidget;
int _graphicsTabId;
+ int _midiTabId;
+ int _pathsTabId;
private:
//
@@ -193,6 +193,8 @@ public:
void close();
void handleCommand(CommandSender *sender, uint32 cmd, uint32 data);
+ virtual void reflowLayout();
+
protected:
#ifdef SMALL_SCREEN_DEVICE
KeysDialog *_keysDialog;
diff --git a/gui/themes/default.inc b/gui/themes/default.inc
index ce670b55f0..bd28c2e85d 100644
--- a/gui/themes/default.inc
+++ b/gui/themes/default.inc
@@ -1364,6 +1364,26 @@
"</layout> "
"</layout> "
"</dialog> "
+"<dialog name='LoomTownsDifficultyDialog' overlays='screen_center'> "
+"<layout type='vertical' padding='8,8,8,8' center='true'> "
+"<widget name='Description1' "
+"width='280' "
+"height='Globals.Line.Height' "
+"/> "
+"<widget name='Description2' "
+"height='Globals.Line.Height' "
+"/> "
+"<widget name='Standard' "
+"type='Button' "
+"/> "
+"<widget name='Practice' "
+"type='Button' "
+"/> "
+"<widget name='Expert' "
+"type='Button' "
+"/> "
+"</layout> "
+"</dialog> "
"<dialog name='MassAdd' overlays='screen_center' shading='dim'> "
"<layout type='vertical' padding='4,4,16,4' center='true'> "
"<widget name='DirProgressText' "
@@ -2174,6 +2194,26 @@
"</layout> "
"</layout> "
"</dialog> "
+"<dialog name='LoomTownsDifficultyDialog' overlays='screen_center'> "
+"<layout type='vertical' padding='8,8,8,8' center='true'> "
+"<widget name='Description1' "
+"width='320' "
+"height='Globals.Line.Height' "
+"/> "
+"<widget name='Description2' "
+"height='Globals.Line.Height' "
+"/> "
+"<widget name='Standard' "
+"type='Button' "
+"/> "
+"<widget name='Practice' "
+"type='Button' "
+"/> "
+"<widget name='Expert' "
+"type='Button' "
+"/> "
+"</layout> "
+"</dialog> "
"<dialog name='MassAdd' overlays='screen_center' shading='dim'> "
"<layout type='vertical' padding='8,8,32,8' center='true'> "
"<widget name='DirProgressText' "
diff --git a/gui/themes/fonts/FreeMonoBold.ttf b/gui/themes/fonts/FreeMonoBold.ttf
new file mode 100644
index 0000000000..3bce6129ae
--- /dev/null
+++ b/gui/themes/fonts/FreeMonoBold.ttf
Binary files differ
diff --git a/gui/themes/fonts/FreeSans.ttf b/gui/themes/fonts/FreeSans.ttf
new file mode 100644
index 0000000000..9db958532c
--- /dev/null
+++ b/gui/themes/fonts/FreeSans.ttf
Binary files differ
diff --git a/gui/themes/fonts/FreeSansBold.ttf b/gui/themes/fonts/FreeSansBold.ttf
new file mode 100644
index 0000000000..63644e7437
--- /dev/null
+++ b/gui/themes/fonts/FreeSansBold.ttf
Binary files differ
diff --git a/gui/themes/fonts/README b/gui/themes/fonts/README
index 594bfc3ea4..b36d89889c 100644
--- a/gui/themes/fonts/README
+++ b/gui/themes/fonts/README
@@ -1,3 +1,5 @@
These are fonts used in ScummVM. Most of them come from Xorg.
+The GNU FreeFont files are distributed under the license in COPYING.FREEFONT.
+
Also other potentially usable fonts are stored here as well.
diff --git a/gui/themes/scummclassic.zip b/gui/themes/scummclassic.zip
index 54d1fc92b0..d4cfd0cba3 100644
--- a/gui/themes/scummclassic.zip
+++ b/gui/themes/scummclassic.zip
Binary files differ
diff --git a/gui/themes/scummclassic/THEMERC b/gui/themes/scummclassic/THEMERC
index f6a46692a0..f3904cbb6d 100644
--- a/gui/themes/scummclassic/THEMERC
+++ b/gui/themes/scummclassic/THEMERC
@@ -1 +1 @@
-[SCUMMVM_STX0.8.5:ScummVM Classic Theme:No Author]
+[SCUMMVM_STX0.8.8:ScummVM Classic Theme:No Author]
diff --git a/gui/themes/scummclassic/clR6x12-iso-8859-2.fcc b/gui/themes/scummclassic/clR6x12-iso-8859-2.fcc
index 042bc5b24d..4d225ddc23 100644
--- a/gui/themes/scummclassic/clR6x12-iso-8859-2.fcc
+++ b/gui/themes/scummclassic/clR6x12-iso-8859-2.fcc
Binary files differ
diff --git a/gui/themes/scummclassic/clR6x12-iso-8859-5.fcc b/gui/themes/scummclassic/clR6x12-iso-8859-5.fcc
index d8e614211d..37d4615ea0 100644
--- a/gui/themes/scummclassic/clR6x12-iso-8859-5.fcc
+++ b/gui/themes/scummclassic/clR6x12-iso-8859-5.fcc
Binary files differ
diff --git a/gui/themes/scummclassic/classic_layout.stx b/gui/themes/scummclassic/classic_layout.stx
index 3d916e28e9..9da42635a7 100644
--- a/gui/themes/scummclassic/classic_layout.stx
+++ b/gui/themes/scummclassic/classic_layout.stx
@@ -818,6 +818,27 @@
</layout>
</dialog>
+ <dialog name = 'LoomTownsDifficultyDialog' overlays = 'screen_center'>
+ <layout type = 'vertical' padding = '8, 8, 8, 8' center = 'true'>
+ <widget name = 'Description1'
+ width = '320'
+ height = 'Globals.Line.Height'
+ />
+ <widget name = 'Description2'
+ height = 'Globals.Line.Height'
+ />
+ <widget name = 'Standard'
+ type = 'Button'
+ />
+ <widget name = 'Practice'
+ type = 'Button'
+ />
+ <widget name = 'Expert'
+ type = 'Button'
+ />
+ </layout>
+ </dialog>
+
<dialog name = 'MassAdd' overlays = 'screen_center' shading = 'dim'>
<layout type = 'vertical' padding = '8, 8, 32, 8' center = 'true'>
<widget name = 'DirProgressText'
diff --git a/gui/themes/scummclassic/classic_layout_lowres.stx b/gui/themes/scummclassic/classic_layout_lowres.stx
index 7d4077dbe2..dc528a4c00 100644
--- a/gui/themes/scummclassic/classic_layout_lowres.stx
+++ b/gui/themes/scummclassic/classic_layout_lowres.stx
@@ -820,6 +820,27 @@
</layout>
</dialog>
+ <dialog name = 'LoomTownsDifficultyDialog' overlays = 'screen_center'>
+ <layout type = 'vertical' padding = '8, 8, 8, 8' center = 'true'>
+ <widget name = 'Description1'
+ width = '280'
+ height = 'Globals.Line.Height'
+ />
+ <widget name = 'Description2'
+ height = 'Globals.Line.Height'
+ />
+ <widget name = 'Standard'
+ type = 'Button'
+ />
+ <widget name = 'Practice'
+ type = 'Button'
+ />
+ <widget name = 'Expert'
+ type = 'Button'
+ />
+ </layout>
+ </dialog>
+
<dialog name = 'MassAdd' overlays = 'screen_center' shading = 'dim'>
<layout type = 'vertical' padding = '4, 4, 16, 4' center = 'true'>
<widget name = 'DirProgressText'
diff --git a/gui/themes/scummclassic/fixed5x8-iso-8859-2.fcc b/gui/themes/scummclassic/fixed5x8-iso-8859-2.fcc
index 73bb5fff2d..37da61be00 100644
--- a/gui/themes/scummclassic/fixed5x8-iso-8859-2.fcc
+++ b/gui/themes/scummclassic/fixed5x8-iso-8859-2.fcc
Binary files differ
diff --git a/gui/themes/scummclassic/fixed5x8-iso-8859-5.fcc b/gui/themes/scummclassic/fixed5x8-iso-8859-5.fcc
index e70388dd93..ee32a2041b 100644
--- a/gui/themes/scummclassic/fixed5x8-iso-8859-5.fcc
+++ b/gui/themes/scummclassic/fixed5x8-iso-8859-5.fcc
Binary files differ
diff --git a/gui/themes/scummclassic/helvb12-iso-8859-2.fcc b/gui/themes/scummclassic/helvb12-iso-8859-2.fcc
index 2117b6b9e6..540d8c4f4c 100644
--- a/gui/themes/scummclassic/helvb12-iso-8859-2.fcc
+++ b/gui/themes/scummclassic/helvb12-iso-8859-2.fcc
Binary files differ
diff --git a/gui/themes/scummclassic/helvb12-iso-8859-5.fcc b/gui/themes/scummclassic/helvb12-iso-8859-5.fcc
index 8ad8f0eb22..90df2b0df4 100644
--- a/gui/themes/scummclassic/helvb12-iso-8859-5.fcc
+++ b/gui/themes/scummclassic/helvb12-iso-8859-5.fcc
Binary files differ
diff --git a/gui/themes/scummmodern.zip b/gui/themes/scummmodern.zip
index 83229184ba..fc4c89cbcc 100644
--- a/gui/themes/scummmodern.zip
+++ b/gui/themes/scummmodern.zip
Binary files differ
diff --git a/gui/themes/scummmodern/FreeMonoBold.ttf b/gui/themes/scummmodern/FreeMonoBold.ttf
new file mode 100644
index 0000000000..3bce6129ae
--- /dev/null
+++ b/gui/themes/scummmodern/FreeMonoBold.ttf
Binary files differ
diff --git a/gui/themes/scummmodern/FreeSans.ttf b/gui/themes/scummmodern/FreeSans.ttf
new file mode 100644
index 0000000000..9db958532c
--- /dev/null
+++ b/gui/themes/scummmodern/FreeSans.ttf
Binary files differ
diff --git a/gui/themes/scummmodern/FreeSansBold.ttf b/gui/themes/scummmodern/FreeSansBold.ttf
new file mode 100644
index 0000000000..63644e7437
--- /dev/null
+++ b/gui/themes/scummmodern/FreeSansBold.ttf
Binary files differ
diff --git a/gui/themes/scummmodern/THEMERC b/gui/themes/scummmodern/THEMERC
index 1d288adffd..32bd36241e 100644
--- a/gui/themes/scummmodern/THEMERC
+++ b/gui/themes/scummmodern/THEMERC
@@ -1 +1 @@
-[SCUMMVM_STX0.8.5:ScummVM Modern Theme:No Author]
+[SCUMMVM_STX0.8.8:ScummVM Modern Theme:No Author]
diff --git a/gui/themes/scummmodern/clR6x12-iso-8859-2.fcc b/gui/themes/scummmodern/clR6x12-iso-8859-2.fcc
index 042bc5b24d..4d225ddc23 100644
--- a/gui/themes/scummmodern/clR6x12-iso-8859-2.fcc
+++ b/gui/themes/scummmodern/clR6x12-iso-8859-2.fcc
Binary files differ
diff --git a/gui/themes/scummmodern/clR6x12-iso-8859-5.fcc b/gui/themes/scummmodern/clR6x12-iso-8859-5.fcc
index d8e614211d..37d4615ea0 100644
--- a/gui/themes/scummmodern/clR6x12-iso-8859-5.fcc
+++ b/gui/themes/scummmodern/clR6x12-iso-8859-5.fcc
Binary files differ
diff --git a/gui/themes/scummmodern/eraser.bmp b/gui/themes/scummmodern/eraser.bmp
index 782b13dc62..b927a6384f 100644
--- a/gui/themes/scummmodern/eraser.bmp
+++ b/gui/themes/scummmodern/eraser.bmp
Binary files differ
diff --git a/gui/themes/scummmodern/fixed5x8-iso-8859-2.fcc b/gui/themes/scummmodern/fixed5x8-iso-8859-2.fcc
index 73bb5fff2d..37da61be00 100644
--- a/gui/themes/scummmodern/fixed5x8-iso-8859-2.fcc
+++ b/gui/themes/scummmodern/fixed5x8-iso-8859-2.fcc
Binary files differ
diff --git a/gui/themes/scummmodern/fixed5x8-iso-8859-5.fcc b/gui/themes/scummmodern/fixed5x8-iso-8859-5.fcc
index e70388dd93..ee32a2041b 100644
--- a/gui/themes/scummmodern/fixed5x8-iso-8859-5.fcc
+++ b/gui/themes/scummmodern/fixed5x8-iso-8859-5.fcc
Binary files differ
diff --git a/gui/themes/scummmodern/helvb12-iso-8859-1.fcc b/gui/themes/scummmodern/helvb12-iso-8859-1.fcc
index 651a25934a..18af0bf870 100644
--- a/gui/themes/scummmodern/helvb12-iso-8859-1.fcc
+++ b/gui/themes/scummmodern/helvb12-iso-8859-1.fcc
Binary files differ
diff --git a/gui/themes/scummmodern/helvb12-iso-8859-2.fcc b/gui/themes/scummmodern/helvb12-iso-8859-2.fcc
index 2117b6b9e6..540d8c4f4c 100644
--- a/gui/themes/scummmodern/helvb12-iso-8859-2.fcc
+++ b/gui/themes/scummmodern/helvb12-iso-8859-2.fcc
Binary files differ
diff --git a/gui/themes/scummmodern/helvb12-iso-8859-5.fcc b/gui/themes/scummmodern/helvb12-iso-8859-5.fcc
index 8ad8f0eb22..90df2b0df4 100644
--- a/gui/themes/scummmodern/helvb12-iso-8859-5.fcc
+++ b/gui/themes/scummmodern/helvb12-iso-8859-5.fcc
Binary files differ
diff --git a/gui/themes/scummmodern/scummmodern_gfx.stx b/gui/themes/scummmodern/scummmodern_gfx.stx
index cb9f9fd2a3..5f7cc69acd 100644
--- a/gui/themes/scummmodern/scummmodern_gfx.stx
+++ b/gui/themes/scummmodern/scummmodern_gfx.stx
@@ -105,27 +105,38 @@
<fonts>
<font id = 'text_default'
file = 'helvb12.bdf'
+ scalable_file = 'FreeSansBold.ttf'
/>
<font resolution = 'y<400'
id = 'text_default'
file = 'clR6x12.bdf'
+ scalable_file = 'FreeSans.ttf'
+ point_size = '11'
/>
<font id = 'text_button'
file = 'helvb12.bdf'
+ scalable_file = 'FreeSansBold.ttf'
/>
<font resolution = 'y<400'
id = 'text_button'
file = 'clR6x12.bdf'
+ scalable_file = 'FreeSans.ttf'
+ point_size = '11'
/>
<font id = 'text_normal'
file = 'helvb12.bdf'
+ scalable_file = 'FreeSans.ttf'
/>
<font resolution = 'y<400'
id = 'text_normal'
file = 'clR6x12.bdf'
+ scalable_file = 'FreeSans.ttf'
+ point_size = '11'
/>
<font id = 'tooltip_normal'
file = 'fixed5x8.bdf'
+ scalable_file = 'FreeMonoBold.ttf'
+ point_size = '8'
/>
<text_color id = 'color_normal'
@@ -387,7 +398,7 @@
<!-- Background of the slider widget -->
<drawdata id = 'widget_slider' cache = 'false'>
<drawstep func = 'roundedsq'
- stroke = '0'
+ stroke = '1'
radius = '5'
fill = 'foreground'
fg_color = 'paleyellow'
@@ -676,6 +687,7 @@
radius = '5'
fg_color = 'paleyellow'
shadow = '0'
+ stroke = '1'
bevel = '1'
bevel_color = 'shadowcolor'
/>
diff --git a/gui/themes/scummmodern/scummmodern_layout.stx b/gui/themes/scummmodern/scummmodern_layout.stx
index a3fc013a08..69ad9c79fa 100644
--- a/gui/themes/scummmodern/scummmodern_layout.stx
+++ b/gui/themes/scummmodern/scummmodern_layout.stx
@@ -833,6 +833,27 @@
</layout>
</dialog>
+ <dialog name = 'LoomTownsDifficultyDialog' overlays = 'screen_center'>
+ <layout type = 'vertical' padding = '8, 8, 8, 8' center = 'true'>
+ <widget name = 'Description1'
+ width = '320'
+ height = 'Globals.Line.Height'
+ />
+ <widget name = 'Description2'
+ height = 'Globals.Line.Height'
+ />
+ <widget name = 'Standard'
+ type = 'Button'
+ />
+ <widget name = 'Practice'
+ type = 'Button'
+ />
+ <widget name = 'Expert'
+ type = 'Button'
+ />
+ </layout>
+ </dialog>
+
<dialog name = 'MassAdd' overlays = 'screen_center' shading = 'dim'>
<layout type = 'vertical' padding = '8, 8, 32, 8' center = 'true'>
<widget name = 'DirProgressText'
diff --git a/gui/themes/scummmodern/scummmodern_layout_lowres.stx b/gui/themes/scummmodern/scummmodern_layout_lowres.stx
index 67a02dc2d5..0bfd16c1d9 100644
--- a/gui/themes/scummmodern/scummmodern_layout_lowres.stx
+++ b/gui/themes/scummmodern/scummmodern_layout_lowres.stx
@@ -819,6 +819,27 @@
</layout>
</dialog>
+ <dialog name = 'LoomTownsDifficultyDialog' overlays = 'screen_center'>
+ <layout type = 'vertical' padding = '8, 8, 8, 8' center = 'true'>
+ <widget name = 'Description1'
+ width = '280'
+ height = 'Globals.Line.Height'
+ />
+ <widget name = 'Description2'
+ height = 'Globals.Line.Height'
+ />
+ <widget name = 'Standard'
+ type = 'Button'
+ />
+ <widget name = 'Practice'
+ type = 'Button'
+ />
+ <widget name = 'Expert'
+ type = 'Button'
+ />
+ </layout>
+ </dialog>
+
<dialog name = 'MassAdd' overlays = 'screen_center' shading = 'dim'>
<layout type = 'vertical' padding = '4, 4, 16, 4' center = 'true'>
<widget name = 'DirProgressText'
diff --git a/gui/themes/scummtheme.py b/gui/themes/scummtheme.py
index e4e9549265..4c55fd79de 100755
--- a/gui/themes/scummtheme.py
+++ b/gui/themes/scummtheme.py
@@ -5,7 +5,7 @@ import re
import os
import zipfile
-THEME_FILE_EXTENSIONS = ('.stx', '.bmp', '.fcc')
+THEME_FILE_EXTENSIONS = ('.stx', '.bmp', '.fcc', '.ttf')
def buildTheme(themeName):
if not os.path.isdir(themeName) or not os.path.isfile(os.path.join(themeName, "THEMERC")):
diff --git a/gui/themes/translations.dat b/gui/themes/translations.dat
index 567df59b43..d3a384ef77 100644
--- a/gui/themes/translations.dat
+++ b/gui/themes/translations.dat
Binary files differ
diff --git a/gui/widget.cpp b/gui/widget.cpp
index d11ebda821..0e2fd248b1 100644
--- a/gui/widget.cpp
+++ b/gui/widget.cpp
@@ -23,6 +23,7 @@
#include "common/system.h"
#include "common/rect.h"
#include "common/textconsole.h"
+#include "common/translation.h"
#include "graphics/pixelformat.h"
#include "gui/widget.h"
#include "gui/gui-manager.h"
@@ -244,16 +245,16 @@ void StaticTextWidget::setValue(int value) {
}
void StaticTextWidget::setLabel(const Common::String &label) {
- if (_label != label) {
- _label = label;
+ if (_label != label) {
+ _label = label;
- // when changing the label, add the CLEARBG flag
- // so the widget is completely redrawn, otherwise
- // the new text is drawn on top of the old one.
- setFlags(WIDGET_CLEARBG);
- draw();
- clearFlags(WIDGET_CLEARBG);
- }
+ // when changing the label, add the CLEARBG flag
+ // so the widget is completely redrawn, otherwise
+ // the new text is drawn on top of the old one.
+ setFlags(WIDGET_CLEARBG);
+ draw();
+ clearFlags(WIDGET_CLEARBG);
+ }
}
void StaticTextWidget::setAlign(Graphics::TextAlign align) {
@@ -302,6 +303,27 @@ void ButtonWidget::setLabel(const Common::String &label) {
StaticTextWidget::setLabel(cleanupHotkey(label));
}
+ButtonWidget *addClearButton(GuiObject *boss, const Common::String &name, uint32 cmd, int x, int y, int w, int h) {
+ ButtonWidget *button;
+
+#ifndef DISABLE_FANCY_THEMES
+ if (g_gui.xmlEval()->getVar("Globals.ShowSearchPic") == 1 && g_gui.theme()->supportsImages()) {
+ if (!name.empty())
+ button = new PicButtonWidget(boss, name, _("Clear value"), cmd);
+ else
+ button = new PicButtonWidget(boss, x, y, w, h, _("Clear value"), cmd);
+ ((PicButtonWidget *)button)->useThemeTransparency(true);
+ ((PicButtonWidget *)button)->setGfx(g_gui.theme()->getImageSurface(ThemeEngine::kImageEraser));
+ } else
+#endif
+ if (!name.empty())
+ button = new ButtonWidget(boss, name, "C", _("Clear value"), cmd);
+ else
+ button = new ButtonWidget(boss, x, y, w, h, "C", _("Clear value"), cmd);
+
+ return button;
+}
+
#pragma mark -
PicButtonWidget::PicButtonWidget(GuiObject *boss, int x, int y, int w, int h, const char *tooltip, uint32 cmd, uint8 hotkey)
diff --git a/gui/widget.h b/gui/widget.h
index 428ab7981e..789fc09231 100644
--- a/gui/widget.h
+++ b/gui/widget.h
@@ -354,6 +354,8 @@ protected:
void drawWidget();
};
+ButtonWidget *addClearButton(GuiObject *boss, const Common::String &name, uint32 cmd, int x=0, int y=0, int w=0, int h=0);
+
} // End of namespace GUI
#endif
diff --git a/gui/widgets/editable.cpp b/gui/widgets/editable.cpp
index 4a0ee54828..6fae9346b2 100644
--- a/gui/widgets/editable.cpp
+++ b/gui/widgets/editable.cpp
@@ -238,8 +238,13 @@ void EditableWidget::defaultKeyDownHandler(Common::KeyState &state, bool &dirty,
int EditableWidget::getCaretOffset() const {
int caretpos = 0;
- for (int i = 0; i < _caretPos; i++)
- caretpos += g_gui.getCharWidth(_editString[i], _font);
+
+ uint last = 0;
+ for (int i = 0; i < _caretPos; ++i) {
+ const uint cur = _editString[i];
+ caretpos += g_gui.getCharWidth(cur, _font) + g_gui.getKerningOffset(last, cur, _font);
+ last = cur;
+ }
caretpos -= _editScrollOffset;
@@ -270,6 +275,8 @@ void EditableWidget::drawCaret(bool erase) {
if ((uint)_caretPos < _editString.size()) {
GUI::EditableWidget::String chr(_editString[_caretPos]);
int chrWidth = g_gui.getCharWidth(_editString[_caretPos], _font);
+ const uint last = (_caretPos > 0) ? _editString[_caretPos - 1] : 0;
+ x += g_gui.getKerningOffset(last, _editString[_caretPos], _font);
g_gui.theme()->drawText(Common::Rect(x, y, x + chrWidth, y + editRect.height() - 2), chr, _state, Graphics::kTextAlignLeft, _inversion, 0, false, _font);
}
}
diff --git a/gui/widgets/edittext.cpp b/gui/widgets/edittext.cpp
index 0337fe1e87..4b266e8194 100644
--- a/gui/widgets/edittext.cpp
+++ b/gui/widgets/edittext.cpp
@@ -33,6 +33,7 @@ EditTextWidget::EditTextWidget(GuiObject *boss, int x, int y, int w, int h, cons
_finishCmd = finishCmd;
setEditString(text);
+ setFontStyle(ThemeEngine::kFontStyleNormal);
}
EditTextWidget::EditTextWidget(GuiObject *boss, const String &name, const String &text, const char *tooltip, uint32 cmd, uint32 finishCmd)
@@ -42,6 +43,7 @@ EditTextWidget::EditTextWidget(GuiObject *boss, const String &name, const String
_finishCmd = finishCmd;
setEditString(text);
+ setFontStyle(ThemeEngine::kFontStyleNormal);
}
void EditTextWidget::setEditString(const String &str) {
@@ -67,10 +69,13 @@ void EditTextWidget::handleMouseDown(int x, int y, int button, int clickCount) {
int width = 0;
uint i;
+ uint last = 0;
for (i = 0; i < _editString.size(); ++i) {
- width += g_gui.theme()->getCharWidth(_editString[i], _font);
+ const uint cur = _editString[i];
+ width += g_gui.getCharWidth(cur, _font) + g_gui.getKerningOffset(last, cur, _font);
if (width >= x)
break;
+ last = cur;
}
if (setCaretPos(i))
draw();