aboutsummaryrefslogtreecommitdiff
path: root/gui
diff options
context:
space:
mode:
authorVicent Marti2008-06-14 14:44:29 +0000
committerVicent Marti2008-06-14 14:44:29 +0000
commitd0b27cf9c66b9281899acf826cb205e19dcb7260 (patch)
tree74e813b1d1f081f35f41ca7a95da5d048951b9e7 /gui
parentd51a0cab3fe494698f001d81d5d86cea7cd0395b (diff)
parent91d3ea31359950b59ee46af8355cc0f5790257e5 (diff)
downloadscummvm-rg350-d0b27cf9c66b9281899acf826cb205e19dcb7260.tar.gz
scummvm-rg350-d0b27cf9c66b9281899acf826cb205e19dcb7260.tar.bz2
scummvm-rg350-d0b27cf9c66b9281899acf826cb205e19dcb7260.zip
Merged trunk into the GUI branch.
Fixed MSVS9 project files. svn-id: r32702
Diffstat (limited to 'gui')
-rw-r--r--gui/ListWidget.cpp2
-rw-r--r--gui/ThemeModern.cpp8
-rw-r--r--gui/about.cpp8
-rw-r--r--gui/console.cpp2
-rw-r--r--gui/credits.h3
-rw-r--r--gui/debugger.cpp6
-rw-r--r--gui/eval.cpp2
-rw-r--r--gui/eval.h6
-rw-r--r--gui/launcher.cpp28
-rw-r--r--gui/launcher.h1
-rw-r--r--gui/massadd.cpp63
-rw-r--r--gui/massadd.h10
-rw-r--r--gui/newgui.cpp3
-rw-r--r--gui/options.cpp35
-rw-r--r--gui/options.h3
-rw-r--r--gui/theme-config.cpp3
-rw-r--r--gui/theme.cpp8
-rw-r--r--gui/themes/classic080.ini3
-rw-r--r--gui/themes/modern.ini3
19 files changed, 153 insertions, 44 deletions
diff --git a/gui/ListWidget.cpp b/gui/ListWidget.cpp
index c43a0f64d7..80898d06c8 100644
--- a/gui/ListWidget.cpp
+++ b/gui/ListWidget.cpp
@@ -495,7 +495,7 @@ void ListWidget::reflowLayout() {
_entriesPerPage = (_h - _topPadding - _bottomPadding) / kLineHeight;
- delete [] _textWidth;
+ delete[] _textWidth;
_textWidth = new int[_entriesPerPage];
for (int i = 0; i < _entriesPerPage; i++)
diff --git a/gui/ThemeModern.cpp b/gui/ThemeModern.cpp
index 69595eb219..177171b40c 100644
--- a/gui/ThemeModern.cpp
+++ b/gui/ThemeModern.cpp
@@ -114,8 +114,8 @@ _forceRedraw(false), _lastUsedBitMask(0), _fonts(), _cursor(0), _imageHandles(),
ThemeModern::~ThemeModern() {
deleteFonts();
deinit();
- delete [] _images;
- delete [] _cursor;
+ delete[] _images;
+ delete[] _cursor;
_images = 0;
for (int i = 0; i < kImageHandlesMax; ++i) {
ImageMan.unregisterSurface(_imageHandles[i]);
@@ -1470,7 +1470,7 @@ void ThemeModern::createCursor() {
_system->colorToRGB(_colors[kColorTransparency], r, g, b);
uint16 transparency = RGBToColor<ColorMasks<565> >(r, g, b);
- delete [] _cursor;
+ delete[] _cursor;
_cursor = new byte[_cursorWidth * _cursorHeight];
assert(_cursor);
@@ -1502,7 +1502,7 @@ void ThemeModern::createCursor() {
}
_useCursor = true;
- delete [] table;
+ delete[] table;
}
#pragma mark -
diff --git a/gui/about.cpp b/gui/about.cpp
index c346d5ad87..758f3ee6a7 100644
--- a/gui/about.cpp
+++ b/gui/about.cpp
@@ -22,7 +22,7 @@
* $Id$
*/
-#include "engines/engine.h"
+#include "engines/metaengine.h"
#include "base/plugins.h"
#include "base/version.h"
#include "common/events.h"
@@ -128,8 +128,8 @@ AboutDialog::AboutDialog()
_lines.push_back("");
addLine("\\C\\c1""Available engines:");
- const PluginList &plugins = PluginManager::instance().getPlugins();
- PluginList::const_iterator iter = plugins.begin();
+ const EnginePlugin::List &plugins = EngineMan.getPlugins();
+ EnginePlugin::List::const_iterator iter = plugins.begin();
for (; iter != plugins.end(); ++iter) {
Common::String str;
str = "\\C";
@@ -137,7 +137,7 @@ AboutDialog::AboutDialog()
addLine(str.c_str());
str = "\\C\\c2";
- str += (**iter).getCopyright();
+ str += (**iter)->getCopyright();
addLine(str.c_str());
//addLine("");
diff --git a/gui/console.cpp b/gui/console.cpp
index b57ccbdaa6..728724d76f 100644
--- a/gui/console.cpp
+++ b/gui/console.cpp
@@ -295,7 +295,7 @@ void ConsoleDialog::handleKeyDown(Common::KeyState state) {
keepRunning = (*_callbackProc)(this, str, _callbackRefCon);
// Get rid of the string buffer
- delete [] str;
+ delete[] str;
}
print(PROMPT);
diff --git a/gui/credits.h b/gui/credits.h
index a84cc53d98..41544a2248 100644
--- a/gui/credits.h
+++ b/gui/credits.h
@@ -144,6 +144,9 @@ static const char *credits[] = {
"\\C\\c0""Jurgen Braam",
"\\C\\c0""Lars Persson",
"\\C\\c0""",
+"\\C\\c1""Wii",
+"\\C\\c0""Andre Heider",
+"\\C\\c0""",
"\\C\\c0""",
"\\C\\c1""Other subsystems",
"\\C\\c1""Infrastructure",
diff --git a/gui/debugger.cpp b/gui/debugger.cpp
index 99aebe9b62..87abe854be 100644
--- a/gui/debugger.cpp
+++ b/gui/debugger.cpp
@@ -406,7 +406,7 @@ bool Debugger::Cmd_Help(int argc, const char **argv) {
}
bool Debugger::Cmd_DebugFlagsList(int argc, const char **argv) {
- const Common::Array<Common::EngineDebugLevel> &debugLevels = Common::listSpecialDebugLevels();
+ const Common::DebugLevelContainer &debugLevels = Common::listSpecialDebugLevels();
DebugPrintf("Engine debug levels:\n");
DebugPrintf("--------------------\n");
@@ -414,8 +414,8 @@ bool Debugger::Cmd_DebugFlagsList(int argc, const char **argv) {
DebugPrintf("No engine debug levels\n");
return true;
}
- for (uint i = 0; i < debugLevels.size(); ++i) {
- DebugPrintf("'%s' - Description: %s\n", debugLevels[i].option.c_str(), debugLevels[i].description.c_str());
+ for (Common::DebugLevelContainer::const_iterator i = debugLevels.begin(); i != debugLevels.end(); ++i) {
+ DebugPrintf("'%s' - Description: %s\n", i->option.c_str(), i->description.c_str());
}
DebugPrintf("\n");
return true;
diff --git a/gui/eval.cpp b/gui/eval.cpp
index a2aec6d0d3..716006c108 100644
--- a/gui/eval.cpp
+++ b/gui/eval.cpp
@@ -102,7 +102,7 @@ void Eval::level4(int *result) {
char op;
op = 0;
- if ((_tokenType == tDelimiter) && *_token == '+' || *_token == '-') {
+ if ((_tokenType == tDelimiter) && (*_token == '+' || *_token == '-')) {
op = *_token;
getToken();
}
diff --git a/gui/eval.h b/gui/eval.h
index 245ab1230b..47c8313903 100644
--- a/gui/eval.h
+++ b/gui/eval.h
@@ -68,9 +68,9 @@ public:
char *lastToken() { return _token; }
- typedef HashMap<String, int, Common::CaseSensitiveString_Hash, Common::CaseSensitiveString_EqualTo> VariablesMap;
- typedef HashMap<String, String, Common::CaseSensitiveString_Hash, Common::CaseSensitiveString_EqualTo> AliasesMap;
- typedef HashMap<String, String, Common::CaseSensitiveString_Hash, Common::CaseSensitiveString_EqualTo> StringsMap;
+ typedef HashMap<String, int> VariablesMap;
+ typedef HashMap<String, String> AliasesMap;
+ typedef HashMap<String, String> StringsMap;
private:
enum TokenTypes {
diff --git a/gui/launcher.cpp b/gui/launcher.cpp
index 2be703a405..2c1212b84a 100644
--- a/gui/launcher.cpp
+++ b/gui/launcher.cpp
@@ -22,9 +22,7 @@
* $Id$
*/
-#include "engines/engine.h"
-#include "base/game.h"
-#include "base/plugins.h"
+#include "engines/metaengine.h"
#include "base/version.h"
#include "common/config-manager.h"
@@ -574,27 +572,27 @@ void LauncherDialog::updateListing() {
// Retrieve a list of all games defined in the config file
_domains.clear();
const ConfigManager::DomainMap &domains = ConfMan.getGameDomains();
- ConfigManager::DomainMap::const_iterator iter = domains.begin();
+ ConfigManager::DomainMap::const_iterator iter;
for (iter = domains.begin(); iter != domains.end(); ++iter) {
+#ifdef __DS__
+ // DS port uses an extra section called 'ds'. This prevents the section from being
+ // detected as a game.
+ if (iter->_key == "ds") {
+ continue;
+ }
+#endif
+
String gameid(iter->_value.get("gameid"));
String description(iter->_value.get("description"));
if (gameid.empty())
gameid = iter->_key;
if (description.empty()) {
- GameDescriptor g = Base::findGame(gameid);
+ GameDescriptor g = EngineMan.findGame(gameid);
if (g.contains("description"))
description = g.description();
}
-#ifdef __DS__
- // DS port uses an extra section called 'ds'. This prevents the section from being
- // detected as a game.
- if (gameid == "ds") {
- continue;
- }
-#endif
-
if (description.empty())
description = "Unknown (target " + iter->_key + ", gameid " + gameid + ")";
@@ -659,7 +657,7 @@ void LauncherDialog::addGame() {
// ...so let's determine a list of candidates, games that
// could be contained in the specified directory.
- GameList candidates(PluginManager::instance().detectGames(files));
+ GameList candidates(EngineMan.detectGames(files));
int idx;
if (candidates.empty()) {
@@ -783,7 +781,7 @@ void LauncherDialog::editGame(int item) {
String gameId(ConfMan.get("gameid", _domains[item]));
if (gameId.empty())
gameId = _domains[item];
- EditGameDialog editDialog(_domains[item], Base::findGame(gameId).description());
+ EditGameDialog editDialog(_domains[item], EngineMan.findGame(gameId).description());
if (editDialog.runModal() > 0) {
// User pressed OK, so make changes permanent
diff --git a/gui/launcher.h b/gui/launcher.h
index 164a7e0707..a9d09bf109 100644
--- a/gui/launcher.h
+++ b/gui/launcher.h
@@ -26,6 +26,7 @@
#define LAUNCHER_DIALOG_H
#include "gui/dialog.h"
+#include "base/game.h"
#include "common/str.h"
namespace GUI {
diff --git a/gui/massadd.cpp b/gui/massadd.cpp
index 934957e80b..687d367516 100644
--- a/gui/massadd.cpp
+++ b/gui/massadd.cpp
@@ -22,10 +22,9 @@
* $Id$
*/
-#include "engines/engine.h"
-#include "base/game.h"
-#include "base/plugins.h"
+#include "engines/metaengine.h"
#include "common/events.h"
+#include "common/config-manager.h"
#include "gui/launcher.h" // For addGameToConf()
#include "gui/massadd.h"
@@ -89,6 +88,29 @@ MassAddDialog::MassAddDialog(const FilesystemNode &startDir)
new ButtonWidget(this, "massadddialog_cancel", "Cancel", kCancelCmd, Common::ASCII_ESCAPE);
+ // Build a map from all configured game paths to the targets using them
+ const Common::ConfigManager::DomainMap &domains = ConfMan.getGameDomains();
+ Common::ConfigManager::DomainMap::const_iterator iter;
+ for (iter = domains.begin(); iter != domains.end(); ++iter) {
+
+#ifdef __DS__
+ // DS port uses an extra section called 'ds'. This prevents the section from being
+ // detected as a game.
+ if (iter->_key == "ds") {
+ continue;
+ }
+#endif
+
+ Common::String path(iter->_value.get("path"));
+ // Remove trailing slash, so that "/foo" and "/foo/" match.
+ // This works around a bug in the POSIX FS code (and others?)
+ // where paths are not normalized (so FSNodes refering to identical
+ // FS objects may return different values in path()).
+ while (path != "/" && path.lastChar() == '/')
+ path.deleteLastChar();
+ if (!path.empty())
+ _pathToTargets[path].push_back(iter->_key);
+ }
}
@@ -132,15 +154,42 @@ void MassAddDialog::handleTickle() {
}
// Run the detector on the dir
- GameList candidates(PluginManager::instance().detectGames(files));
+ GameList candidates(EngineMan.detectGames(files));
// Just add all detected games / game variants. If we get more than one,
// that either means the directory contains multiple games, or the detector
// could not fully determine which game variant it was seeing. In either
// case, let the user choose which entries he wants to keep.
+ //
+ // However, we only add games which are not already in the config file.
for (GameList::const_iterator cand = candidates.begin(); cand != candidates.end(); ++cand) {
GameDescriptor result = *cand;
- result["path"] = dir.getPath();
+ Common::String path = dir.getPath();
+
+ // Remove trailing slashes
+ while (path != "/" && path.lastChar() == '/')
+ path.deleteLastChar();
+
+ // Check for existing config entries for this path/gameid/lang/platform combination
+ if (_pathToTargets.contains(path)) {
+ bool duplicate = false;
+ const Common::StringList &targets = _pathToTargets[path];
+ for (Common::StringList::const_iterator iter = targets.begin(); iter != targets.end(); ++iter) {
+ // If the gameid, platform and language match -> skip it
+ Common::ConfigManager::Domain *dom = ConfMan.getDomain(*iter);
+ assert(dom);
+
+ if ((*dom)["gameid"] == result["gameid"] &&
+ (*dom)["platform"] == result["platform"] &&
+ (*dom)["language"] == result["language"]) {
+ duplicate = true;
+ break;
+ }
+ }
+ if (duplicate)
+ break; // Skip duplicates
+ }
+ result["path"] = path;
_games.push_back(result);
}
@@ -166,14 +215,14 @@ void MassAddDialog::handleTickle() {
snprintf(buf, sizeof(buf), "Scan complete!");
_dirProgressText->setLabel(buf);
- snprintf(buf, sizeof(buf), "Discovered %d games.", _games.size());
+ snprintf(buf, sizeof(buf), "Discovered %d new games.", _games.size());
_gameProgressText->setLabel(buf);
} else {
snprintf(buf, sizeof(buf), "Scanned %d directories ...", _dirsScanned);
_dirProgressText->setLabel(buf);
- snprintf(buf, sizeof(buf), "Discovered %d games ...", _games.size());
+ snprintf(buf, sizeof(buf), "Discovered %d new games ...", _games.size());
_gameProgressText->setLabel(buf);
}
diff --git a/gui/massadd.h b/gui/massadd.h
index 29d24ca9a5..e0eff75c64 100644
--- a/gui/massadd.h
+++ b/gui/massadd.h
@@ -27,7 +27,10 @@
#include "gui/dialog.h"
#include "common/fs.h"
+#include "common/hashmap.h"
#include "common/stack.h"
+#include "common/str.h"
+#include "common/hash-str.h"
namespace GUI {
@@ -45,6 +48,13 @@ private:
Common::Stack<FilesystemNode> _scanStack;
GameList _games;
+ /**
+ * Map each path occuring in the config file to the target(s) using that path.
+ * Used to detect whether a potential new target is already present in the
+ * config manager.
+ */
+ Common::HashMap<Common::String, Common::StringList> _pathToTargets;
+
int _dirsScanned;
Widget *_okButton;
diff --git a/gui/newgui.cpp b/gui/newgui.cpp
index 5e034b726c..0bf61d084f 100644
--- a/gui/newgui.cpp
+++ b/gui/newgui.cpp
@@ -219,6 +219,7 @@ void NewGui::runLoop() {
Dialog *activeDialog = getTopDialog();
bool didSaveState = false;
int button;
+ uint32 time;
if (activeDialog == 0)
return;
@@ -252,7 +253,6 @@ void NewGui::runLoop() {
_system->updateScreen();
Common::Event event;
- uint32 time = _system->getMillis();
while (eventMan->pollEvent(event)) {
if (activeDialog != getTopDialog() && event.type != Common::EVENT_QUIT && event.type != Common::EVENT_SCREEN_CHANGED)
@@ -288,6 +288,7 @@ void NewGui::runLoop() {
case Common::EVENT_LBUTTONDOWN:
case Common::EVENT_RBUTTONDOWN:
button = (event.type == Common::EVENT_LBUTTONDOWN ? 1 : 2);
+ time = _system->getMillis();
if (_lastClick.count && (time < _lastClick.time + kDoubleClickDelay)
&& ABS(_lastClick.x - event.mouse.x) < 3
&& ABS(_lastClick.y - event.mouse.y) < 3) {
diff --git a/gui/options.cpp b/gui/options.cpp
index 7972ceebb2..d6f5306ce2 100644
--- a/gui/options.cpp
+++ b/gui/options.cpp
@@ -55,6 +55,7 @@ enum {
kChooseSaveDirCmd = 'chos',
kChooseThemeDirCmd = 'chth',
kChooseExtraDirCmd = 'chex',
+ kChoosePluginsDirCmd = 'chpl',
kChooseThemeCmd = 'chtf'
};
@@ -706,6 +707,11 @@ GlobalOptionsDialog::GlobalOptionsDialog()
new ButtonWidget(tab, "globaloptions_extrabutton", "Extra Path:", kChooseExtraDirCmd, 0);
_extraPath = new StaticTextWidget(tab, "globaloptions_extrapath", "None");
+
+#ifdef DYNAMIC_MODULES
+ new ButtonWidget(tab, "globaloptions_pluginsbutton", "Plugins Path:", kChoosePluginsDirCmd, 0);
+ _pluginsPath = new StaticTextWidget(tab, "globaloptions_pluginspath", "None");
+#endif
#endif
#ifdef SMALL_SCREEN_DEVICE
@@ -772,6 +778,15 @@ void GlobalOptionsDialog::open() {
} else {
_extraPath->setLabel(extraPath);
}
+
+#ifdef DYNAMIC_MODULES
+ Common::String pluginsPath(ConfMan.get("pluginspath", _domain));
+ if (pluginsPath.empty() || !ConfMan.hasKey("pluginspath", _domain)) {
+ _pluginsPath->setLabel("None");
+ } else {
+ _pluginsPath->setLabel(pluginsPath);
+ }
+#endif
#endif
// Misc Tab
@@ -801,6 +816,14 @@ void GlobalOptionsDialog::close() {
else
ConfMan.removeKey("extrapath", _domain);
+#ifdef DYNAMIC_MODULES
+ String pluginsPath(_pluginsPath->getLabel());
+ if (!pluginsPath.empty() && (pluginsPath != "None"))
+ ConfMan.set("pluginspath", pluginsPath, _domain);
+ else
+ ConfMan.removeKey("pluginspath", _domain);
+#endif
+
ConfMan.setInt("autosave_period", _autosavePeriodPopUp->getSelectedTag(), _domain);
}
OptionsDialog::close();
@@ -844,6 +867,18 @@ void GlobalOptionsDialog::handleCommand(CommandSender *sender, uint32 cmd, uint3
}
break;
}
+#ifdef DYNAMIC_MODULES
+ case kChoosePluginsDirCmd: {
+ BrowserDialog browser("Select directory for plugins", true);
+ if (browser.runModal() > 0) {
+ // User made his choice...
+ FilesystemNode dir(browser.getResult());
+ _pluginsPath->setLabel(dir.getPath());
+ draw();
+ }
+ break;
+ }
+#endif
case kChooseSoundFontCmd: {
BrowserDialog browser("Select SoundFont", false);
if (browser.runModal() > 0) {
diff --git a/gui/options.h b/gui/options.h
index 6f0fccf3cb..8f4496c753 100644
--- a/gui/options.h
+++ b/gui/options.h
@@ -158,6 +158,9 @@ protected:
StaticTextWidget *_savePath;
StaticTextWidget *_themePath;
StaticTextWidget *_extraPath;
+#ifdef DYNAMIC_MODULES
+ StaticTextWidget *_pluginsPath;
+#endif
//
// Misc controls
diff --git a/gui/theme-config.cpp b/gui/theme-config.cpp
index e6d8026edb..47f60d3d7b 100644
--- a/gui/theme-config.cpp
+++ b/gui/theme-config.cpp
@@ -215,6 +215,9 @@ const char *Theme::_defaultConfigINI =
"globaloptions_themebutton=10 yoffset (buttonWidth + 5) buttonHeight\n"
"globaloptions_themepath=(prev.x2 + 20) (yoffset + glOff) (parent.w - (prev.w + 20) - 15) kLineHeight\n"
"yoffset=(yoffset + buttonHeight + 4)\n"
+"globaloptions_pluginsbutton=10 yoffset (buttonWidth + 5) buttonHeight\n"
+"globaloptions_pluginspath=(prev.x2 + 20) (yoffset + glOff) (parent.w - (prev.w + 20) - 15) kLineHeight\n"
+"yoffset=(yoffset + buttonHeight + 4)\n"
"globaloptions_keysbutton=10 yoffset (buttonWidth + 5) buttonHeight\n"
"\n"
"# Misc options\n"
diff --git a/gui/theme.cpp b/gui/theme.cpp
index a044769bfd..c8501c4f91 100644
--- a/gui/theme.cpp
+++ b/gui/theme.cpp
@@ -82,7 +82,7 @@ const Graphics::Font *Theme::loadFont(const char *filename) {
font = Graphics::NewFont::loadFromCache(stream);
- delete [] buffer;
+ delete[] buffer;
buffer = 0;
}
unzClose(zipFile);
@@ -112,7 +112,7 @@ const Graphics::Font *Theme::loadFont(const char *filename) {
font = Graphics::NewFont::loadFont(stream);
- delete [] buffer;
+ delete[] buffer;
buffer = 0;
}
unzClose(zipFile);
@@ -175,7 +175,7 @@ bool Theme::loadConfigFile(const Common::String &stylefile) {
unzClose(zipFile);
return false;
}
- delete [] buffer;
+ delete[] buffer;
buffer = 0;
} else {
unzClose(zipFile);
@@ -225,7 +225,7 @@ bool Theme::themeConfigUseable(const Common::String &stylefile, const Common::St
unzClose(zipFile);
return false;
}
- delete [] buffer;
+ delete[] buffer;
buffer = 0;
}
} else {
diff --git a/gui/themes/classic080.ini b/gui/themes/classic080.ini
index 23d91b701e..b5c911bada 100644
--- a/gui/themes/classic080.ini
+++ b/gui/themes/classic080.ini
@@ -134,6 +134,9 @@ yoffset=(yoffset + buttonHeight + 4)
globaloptions_themebutton=10 yoffset (buttonWidth + 5) buttonHeight
globaloptions_themepath=(prev.x2 + 20) (yoffset + glOff) (parent.w - (prev.w + 20) - 15) kLineHeight
yoffset=(yoffset + buttonHeight + 4)
+globaloptions_pluginsbutton=10 yoffset (buttonWidth + 5) buttonHeight
+globaloptions_pluginspath=(prev.x2 + 20) (yoffset + glOff) (parent.w - (prev.w + 20) - 15) kLineHeight
+yoffset=(yoffset + buttonHeight + 4)
globaloptions_keysbutton=10 yoffset (buttonWidth + 5) buttonHeight
# Misc options
diff --git a/gui/themes/modern.ini b/gui/themes/modern.ini
index b5929511b0..87ef0bcbb9 100644
--- a/gui/themes/modern.ini
+++ b/gui/themes/modern.ini
@@ -295,6 +295,9 @@ yoffset=(yoffset + buttonHeight + ySeparation)
globaloptions_themebutton=xBorder yoffset buttonWidth buttonHeight
globaloptions_themepath=(prev.x2 + xSeparation) (yoffset + glOff) (parent.w - self.x - xBorder) kLineHeight
yoffset=(yoffset + buttonHeight + ySeparation)
+globaloptions_pluginsbutton=xBorder yoffset buttonWidth buttonHeight
+globaloptions_pluginspath=(prev.x2 + xSeparation) (yoffset + glOff) (parent.w - self.x - xBorder) kLineHeight
+yoffset=(yoffset + buttonHeight + ySeparation)
globaloptions_keysbutton=xBorder yoffset buttonWidth buttonHeight
# Misc options