diff options
-rw-r--r-- | engines/agi/agi.cpp | 72 | ||||
-rw-r--r-- | engines/agi/agi.h | 12 | ||||
-rw-r--r-- | engines/agi/keyboard.cpp | 26 | ||||
-rw-r--r-- | engines/agi/module.mk | 1 | ||||
-rw-r--r-- | engines/agi/predictive.cpp | 617 | ||||
-rw-r--r-- | gui/ThemeEngine.cpp | 1 | ||||
-rw-r--r-- | gui/ThemeEngine.h | 3 | ||||
-rw-r--r-- | gui/module.mk | 1 | ||||
-rw-r--r-- | gui/predictivedialog.cpp | 917 | ||||
-rw-r--r-- | gui/predictivedialog.h | 142 | ||||
-rw-r--r-- | gui/themes/default.inc | 920 | ||||
-rw-r--r-- | gui/themes/scummclassic.zip | bin | 16136 -> 93228 bytes | |||
-rw-r--r-- | gui/themes/scummclassic/THEMERC | 2 | ||||
-rw-r--r-- | gui/themes/scummclassic/classic_layout.stx | 96 | ||||
-rw-r--r-- | gui/themes/scummclassic/classic_layout_lowres.stx | 96 | ||||
-rw-r--r-- | gui/themes/scummmodern.zip | bin | 713257 -> 1449506 bytes | |||
-rw-r--r-- | gui/themes/scummmodern/THEMERC | 2 | ||||
-rw-r--r-- | gui/themes/scummmodern/delbtn.bmp | bin | 0 -> 890 bytes | |||
-rw-r--r-- | gui/themes/scummmodern/scummmodern_gfx.stx | 1 | ||||
-rw-r--r-- | gui/themes/scummmodern/scummmodern_layout.stx | 99 | ||||
-rw-r--r-- | gui/themes/scummmodern/scummmodern_layout_lowres.stx | 95 | ||||
-rw-r--r-- | gui/widgets/editable.h | 9 |
22 files changed, 2079 insertions, 1033 deletions
diff --git a/engines/agi/agi.cpp b/engines/agi/agi.cpp index e9c9645768..8218d82a05 100644 --- a/engines/agi/agi.cpp +++ b/engines/agi/agi.cpp @@ -46,6 +46,8 @@ #include "agi/keyboard.h" #include "agi/menu.h" +#include "gui/predictivedialog.h" + namespace Agi { void AgiEngine::allowSynthetic(bool allow) { @@ -58,9 +60,25 @@ void AgiEngine::processEvents() { while (_eventMan->pollEvent(event)) { switch (event.type) { - case Common::EVENT_PREDICTIVE_DIALOG: - if (_predictiveDialogRunning) - break; + case Common::EVENT_PREDICTIVE_DIALOG: { + GUI::PredictiveDialog _predictiveDialog; + _predictiveDialog.runModal(); + strcpy(_predictiveResult, _predictiveDialog.getResult()); + if (strcmp(_predictiveResult, "")) { + if (_game.inputMode == INPUT_NORMAL) { + strcpy((char *)_game.inputBuffer, _predictiveResult); + handleKeys(KEY_ENTER); + } else if (_game.inputMode == INPUT_GETSTRING) { + strcpy(_game.strings[_stringdata.str], _predictiveResult); + newInputMode(INPUT_NORMAL); + _gfx->printCharacter(_stringdata.x + strlen(_game.strings[_stringdata.str]) + 1, + _stringdata.y, ' ', _game.colorFg, _game.colorBg); + } else if (_game.inputMode == INPUT_NONE) { + for (int n = 0; _predictiveResult[n]; n++) + keyEnqueue(_predictiveResult[n]); + } + } + /* if (predictiveDialog()) { if (_game.inputMode == INPUT_NORMAL) { strcpy((char *)_game.inputBuffer, _predictiveResult); @@ -75,6 +93,8 @@ void AgiEngine::processEvents() { keyEnqueue(_predictiveResult[n]); } } + */ + } break; case Common::EVENT_LBUTTONDOWN: key = BUTTON_LEFT; @@ -131,65 +151,46 @@ void AgiEngine::processEvents() { switch (key = event.kbd.keycode) { case Common::KEYCODE_LEFT: case Common::KEYCODE_KP4: - if (_predictiveDialogRunning && key == Common::KEYCODE_KP4) - key = event.kbd.ascii; - else if (_allowSynthetic || !event.synthetic) + if (_allowSynthetic || !event.synthetic) key = KEY_LEFT; break; case Common::KEYCODE_RIGHT: case Common::KEYCODE_KP6: - if (_predictiveDialogRunning && key == Common::KEYCODE_KP6) - key = event.kbd.ascii; - else if (_allowSynthetic || !event.synthetic) + if (_allowSynthetic || !event.synthetic) key = KEY_RIGHT; break; case Common::KEYCODE_UP: case Common::KEYCODE_KP8: - if (_predictiveDialogRunning && key == Common::KEYCODE_KP8) - key = event.kbd.ascii; - else if (_allowSynthetic || !event.synthetic) + if (_allowSynthetic || !event.synthetic) key = KEY_UP; break; case Common::KEYCODE_DOWN: case Common::KEYCODE_KP2: - if (_predictiveDialogRunning && key == Common::KEYCODE_KP2) - key = event.kbd.ascii; - else if (_allowSynthetic || !event.synthetic) + if (_allowSynthetic || !event.synthetic) key = KEY_DOWN; break; case Common::KEYCODE_PAGEUP: case Common::KEYCODE_KP9: - if (_predictiveDialogRunning && key == Common::KEYCODE_KP9) - key = event.kbd.ascii; - else if (_allowSynthetic || !event.synthetic) + if (_allowSynthetic || !event.synthetic) key = KEY_UP_RIGHT; break; case Common::KEYCODE_PAGEDOWN: case Common::KEYCODE_KP3: - if (_predictiveDialogRunning && key == Common::KEYCODE_KP3) - key = event.kbd.ascii; - else if (_allowSynthetic || !event.synthetic) + if (_allowSynthetic || !event.synthetic) key = KEY_DOWN_RIGHT; break; case Common::KEYCODE_HOME: case Common::KEYCODE_KP7: - if (_predictiveDialogRunning && key == Common::KEYCODE_KP7) - key = event.kbd.ascii; - else if (_allowSynthetic || !event.synthetic) + if (_allowSynthetic || !event.synthetic) key = KEY_UP_LEFT; break; case Common::KEYCODE_END: case Common::KEYCODE_KP1: - if (_predictiveDialogRunning && key == Common::KEYCODE_KP1) - key = event.kbd.ascii; - else if (_allowSynthetic || !event.synthetic) + if (_allowSynthetic || !event.synthetic) key = KEY_DOWN_LEFT; break; case Common::KEYCODE_KP5: - if (_predictiveDialogRunning) - key = event.kbd.ascii; - else - key = KEY_STATIONARY; + key = KEY_STATIONARY; break; case Common::KEYCODE_PLUS: key = '+'; @@ -218,7 +219,7 @@ void AgiEngine::processEvents() { case Common::KEYCODE_F6: key = 0x4000; break; - case Common::KEYCODE_F7: + case Common::KEYCODE_F7: key = 0x4100; break; case Common::KEYCODE_F8: @@ -575,10 +576,6 @@ AgiEngine::AgiEngine(OSystem *syst, const AGIGameDescription *gameDesc) : AgiBas _oldMode = INPUT_NONE; - _predictiveDialogRunning = false; - _predictiveDictText = NULL; - _predictiveDictLine = NULL; - _predictiveDictLineCount = 0; _firstSlot = 0; resetControllers(); @@ -684,9 +681,6 @@ AgiEngine::~AgiEngine() { _gfx->deinitMachine(); delete _gfx; delete _console; - - free(_predictiveDictLine); - free(_predictiveDictText); } Common::Error AgiBase::init() { diff --git a/engines/agi/agi.h b/engines/agi/agi.h index 55b4805022..1e2b617040 100644 --- a/engines/agi/agi.h +++ b/engines/agi/agi.h @@ -43,6 +43,7 @@ #include "agi/logic.h" #include "agi/sound.h" +#include "gui/predictivedialog.h" namespace Common { class RandomSource; @@ -1078,7 +1079,6 @@ public: void clearPrompt(bool useBlackBg = false); void clearLines(int, int, int); void flushLines(int, int); - bool predictiveDialog(); private: void printStatus(const char *message, ...) GCC_PRINTF(2, 3); @@ -1088,16 +1088,6 @@ private: void loadDict(); bool matchWord(); - // Predictive dialog - // TODO: Move this to a separate class - char *_predictiveDictText; - char **_predictiveDictLine; - int32 _predictiveDictLineCount; - char *_predictiveDictActLine; - Common::String _currentCode; - Common::String _currentWord; - int _wordNumber; - bool _predictiveDialogRunning; public: char _predictiveResult[40]; diff --git a/engines/agi/keyboard.cpp b/engines/agi/keyboard.cpp index a7f15c16fb..b7e52f4dc3 100644 --- a/engines/agi/keyboard.cpp +++ b/engines/agi/keyboard.cpp @@ -133,6 +133,19 @@ int AgiEngine::handleController(int key) { if (key == BUTTON_LEFT && (int)_mouse.y >= _game.lineUserInput * CHAR_LINES && (int)_mouse.y <= (_game.lineUserInput + 1) * CHAR_LINES) { + GUI::PredictiveDialog _predictiveDialog; + _predictiveDialog.runModal(); + strcpy(_predictiveResult, _predictiveDialog.getResult()); + if (strcmp(_predictiveResult, "")) { + if (_game.inputMode == INPUT_NONE) { + for (int n = 0; _predictiveResult[n]; n++) + keyEnqueue(_predictiveResult[n]); + } else { + strcpy((char *)_game.inputBuffer, _predictiveResult); + handleKeys(KEY_ENTER); + } + } + /* if (predictiveDialog()) { if (_game.inputMode == INPUT_NONE) { for (int n = 0; _predictiveResult[n]; n++) @@ -142,6 +155,7 @@ int AgiEngine::handleController(int key) { handleKeys(KEY_ENTER); } } + */ return true; } @@ -217,6 +231,17 @@ void AgiEngine::handleGetstring(int key) { case BUTTON_LEFT: if ((int)_mouse.y >= _stringdata.y * CHAR_LINES && (int)_mouse.y <= (_stringdata.y + 1) * CHAR_LINES) { + GUI::PredictiveDialog _predictiveDialog; + _predictiveDialog.runModal(); + strcpy(_predictiveResult, _predictiveDialog.getResult()); + if (strcmp(_predictiveResult, "")) { + strcpy(_game.strings[_stringdata.str], _predictiveResult); + newInputMode(INPUT_NORMAL); + _gfx->printCharacter(_stringdata.x + strlen(_game.strings[_stringdata.str]) + 1, + _stringdata.y, ' ', _game.colorFg, _game.colorBg); + return; + } + /* if (predictiveDialog()) { strcpy(_game.strings[_stringdata.str], _predictiveResult); newInputMode(INPUT_NORMAL); @@ -224,6 +249,7 @@ void AgiEngine::handleGetstring(int key) { _stringdata.y, ' ', _game.colorFg, _game.colorBg); return; } + */ } break; case KEY_ENTER: diff --git a/engines/agi/module.mk b/engines/agi/module.mk index 68d86f7b2e..331a10c16e 100644 --- a/engines/agi/module.mk +++ b/engines/agi/module.mk @@ -28,7 +28,6 @@ MODULE_OBJS := \ preagi_mickey.o \ preagi_troll.o \ preagi_winnie.o \ - predictive.o \ saveload.o \ sound.o \ sound_2gs.o \ diff --git a/engines/agi/predictive.cpp b/engines/agi/predictive.cpp deleted file mode 100644 index 4bb378934d..0000000000 --- a/engines/agi/predictive.cpp +++ /dev/null @@ -1,617 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * 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 source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -#include "agi/agi.h" -#include "agi/graphics.h" -#include "agi/keyboard.h" - -#include "common/config-manager.h" -#include "common/textconsole.h" - -#ifdef __DS__ -#include "wordcompletion.h" -#endif - -namespace Agi { - -enum { - kModePre = 0, - kModeNum = 1, - kModeAbc = 2 -}; - -enum { - MAXLINELEN = 80, - MAXWORDLEN = 24 -}; - -uint8 countWordsInString(char *str) { - // Count the number of (space separated) words in the given string. - char *ptr; - - if (!str) - return 0; - - ptr = strchr(str, ' '); - if (!ptr) { - debug("Invalid dictionary line"); - return 0; - } - - uint8 num = 1; - ptr++; - while ((ptr = strchr(ptr, ' '))) { - ptr++; - num++; - } - return num; -} - -void bringWordtoTop(char *str, int wordnum) { - // This function reorders the words on the given pred.dic line - // by moving the word at position 'wordnum' to the front (that is, right behind - // right behind the numerical code word at the start of the line). - Common::Array<Common::String> words; - char buf[MAXLINELEN]; - - if (!str) - return; - strncpy(buf, str, MAXLINELEN); - buf[MAXLINELEN - 1] = 0; - char *word = strtok(buf, " "); - if (!word) { - debug("Invalid dictionary line"); - return; - } - - words.push_back(word); - while ((word = strtok(NULL, " ")) != NULL) - words.push_back(word); - words.insert_at(1, words.remove_at(wordnum + 1)); - - Common::String tmp; - for (uint8 i = 0; i < words.size(); i++) - tmp += words[i] + " "; - tmp.deleteLastChar(); - memcpy(str, tmp.c_str(), strlen(str)); -} - -bool AgiEngine::predictiveDialog() { - uint8 x; - int y; - int bx[17], by[17]; - Common::String prefix; - char temp[MAXWORDLEN + 1], repeatcount[MAXWORDLEN]; - AgiBlock tmpwindow; - bool navigationwithkeys = false; - - const char *buttonStr[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9", "0" }; - const char *buttons[] = { - "(1)'-.&", "(2)abc", "(3)def", - "(4)ghi", "(5)jkl", "(6)mno", - "(7)pqrs", "(8)tuv", "(9)wxyz", - "(#)next", "add", - "<", - "Cancel", "OK", - "(*)Pre", "(0) ", NULL - }; - const int colors[] = { - 15, 0, 15, 0, 15, 0, - 15, 0, 15, 0, 15, 0, - 15, 0, 15, 0, 15, 0, - 15, 12, 15, 12, - 15, 0, - 15, 0, 15, 0, - 14, 0, 15, 0, 0, 0 - }; - const char *modes[] = { "(*)Pre", "(*)123", "(*)Abc" }; - - // FIXME: Move this to a more appropriate place. - if (!_predictiveDictText) { - loadDict(); - if (!_predictiveDictText) - return false; - } - _predictiveDictActLine = NULL; - uint8 numMatchingWords = 0; - - _predictiveDialogRunning = true; - _system->setFeatureState(OSystem::kFeatureDisableKeyFiltering, true); - - memset(repeatcount, 0, sizeof(repeatcount)); - - // show the predictive dialog. - // if another window is already in display, save its state into tmpwindow - memset(&tmpwindow, 0, sizeof(tmpwindow)); - tmpwindow.active = false; - if (_game.window.active) - memcpy(&tmpwindow, &(_game.window), sizeof(AgiBlock)); - drawWindow(50, 40, 269, 159); - _gfx->drawRectangle(62, 54, 249, 66, MSG_BOX_TEXT); - _gfx->flushBlock(62, 54, 249, 66); - - bx[15] = 73; // Zero/space - by[15] = 120; - bx[9] = 110; // next - by[9] = 120; - bx[10] = 172; // add - by[10] = 120; - bx[14] = 200; // Mode - by[14] = 120; - bx[11] = 252; // Backspace - by[11] = 57; - bx[12] = 180; // Cancel - by[12] = 140; - bx[13] = 240; // OK - by[13] = 140; - - x = 73; - y = 75; - for (int i = 0; i < 9; i++) { - bx[i] = x; - by[i] = y; - x += 60; - if (i % 3 == 2) { - y += 15; - x = 73; - } - } - - clearKeyQueue(); - - prefix.clear(); - _currentCode.clear(); - _currentWord.clear(); - _wordNumber = 0; - - int mode = kModePre; - - bool needRefresh = true; - int active = -1, lastactive = 0; - bool rc = false; - bool closeDialog = false; - bool enterPredictiveResult = false; - while (!closeDialog && !shouldQuit()) { - if (needRefresh) { - for (int i = 0; buttons[i]; i++) { - int color1 = colors[i * 2]; - int color2 = colors[i * 2 + 1]; - - if (i == 9 && !((mode != kModeAbc && _predictiveDictActLine && numMatchingWords > 1) - || (mode == kModeAbc && _currentWord.size() && _currentWord.lastChar() != ' '))) { // Next - color2 = 7; - } - - // needs fixing, or remove it! - bool _addIsActive = false; // FIXME: word adding is not implemented - if (i == 10 && !_addIsActive) { // Add - color2 = 7; - } - if (i == 14) { - _gfx->drawDefaultStyleButton(bx[i], by[i], modes[mode], i == active, 0, color1, color2); - } else { - _gfx->drawDefaultStyleButton(bx[i], by[i], buttons[i], i == active, 0, color1, color2); - } - } - - Common::strlcpy(temp, prefix.c_str(), sizeof(temp)); - Common::strlcat(temp, _currentWord.c_str(), sizeof(temp)); - - for (int i = prefix.size() + _currentCode.size(); i < MAXWORDLEN; i++) - temp[i] = ' '; - temp[MAXWORDLEN] = 0; - - printText(temp, 0, 8, 7, MAXWORDLEN, 15, 0); - _gfx->flushBlock(62, 54, 249, 66); - - if (active >= 0 && !navigationwithkeys) { - // provide visual feedback only when not navigating with the arrows - // so that the user can see the active button. - active = -1; - needRefresh = true; - } else - needRefresh = false; - - _gfx->doUpdate(); - } - - bool processkey = false; - - pollTimer(); - int key = doPollKeyboard(); - switch (key) { - case KEY_ENTER: - if (navigationwithkeys) { - // when the user has utilized arrow key navigation, - // interpret enter as 'click' on the active button - active = lastactive; - } else { - // else it is a shortcut for 'Ok' - active = 13; - } - processkey = true; - break; - case KEY_ESCAPE: - rc = false; - closeDialog = true; - break; - case BUTTON_LEFT: - navigationwithkeys = false; - for (int i = 0; buttons[i]; i++) { - if (_gfx->testButton(bx[i], by[i], buttons[i])) { - active = i; - processkey = true; - break; - } - } - break; - case KEY_BACKSPACE: - active = 11; - processkey = true; - break; - case '#': - active = 9; - processkey = true; - break; - case '*': - active = 14; - processkey = true; - break; - case 0x09: // Tab - navigationwithkeys = true; - debugC(3, kDebugLevelText, "Focus change"); - lastactive = active = lastactive + 1; - active %= ARRAYSIZE(buttons) - 1; - needRefresh = true; - break; - case KEY_LEFT: - navigationwithkeys = true; - if (lastactive == 0 || lastactive == 3 || lastactive == 6) - active = lastactive + 2; - else if (lastactive == 9) - active = 15; - else if (lastactive == 11) - active = 11; - else if (lastactive == 12) - active = 13; - else if (lastactive == 14) - active = 10; - else - active = lastactive - 1; - lastactive = active; - needRefresh = true; - break; - case KEY_RIGHT: - navigationwithkeys = true; - if (lastactive == 2 || lastactive == 5 || lastactive == 8) - active = lastactive - 2; - else if (lastactive == 10) - active = 14; - else if (lastactive == 11) - active = 11; - else if (lastactive == 13) - active = 12; - else if (lastactive == 15) - active = 9; - else - active = lastactive + 1; - lastactive = active; - needRefresh = true; - break; - case KEY_UP: - navigationwithkeys = true; - if (lastactive <= 2) - active = 11; - else if (lastactive == 9 || lastactive == 10) - active = lastactive - 2; - else if (lastactive == 11) - active = 13; - else if (lastactive == 14) - active = 8; - else if (lastactive == 15) - active = 6; - else - active = lastactive - 3; - lastactive = active; - needRefresh = true; - break; - case KEY_DOWN: - navigationwithkeys = true; - if (lastactive == 6) - active = 15; - else if (lastactive == 7 || lastactive == 8) - active = lastactive + 2; - else if (lastactive == 11) - active = 0; - else if (lastactive == 12 || lastactive == 13) - active = 11; - else if (lastactive == 14 || lastactive == 15) - active = lastactive - 2; - else - active = lastactive + 3; - lastactive = active; - needRefresh = true; - break; - default: - // handle numeric buttons - if (key >= '1' && key <= '9') { - active = key - '1'; - processkey = true; - } else if (key == '0') { - active = 15; - processkey = true; - } - break; - } - - if (processkey && !closeDialog) { - if (active >= 0) { - needRefresh = true; - lastactive = active; - if (active == 15 && mode != kModeNum) { // Space - // bring MRU word at the top of the list when changing words - if (mode == kModePre && _predictiveDictActLine && numMatchingWords > 1 && _wordNumber != 0) - bringWordtoTop(_predictiveDictActLine, _wordNumber); - strncpy(temp, _currentWord.c_str(), _currentCode.size()); - temp[_currentCode.size()] = 0; - prefix += temp; - prefix += " "; - _currentCode.clear(); - _currentWord.clear(); - numMatchingWords = 0; - memset(repeatcount, 0, sizeof(repeatcount)); - } else if (active < 9 || active == 11 || active == 15) { // number or backspace - if (active == 11) { // backspace - if (_currentCode.size()) { - repeatcount[_currentCode.size() - 1] = 0; - _currentCode.deleteLastChar(); - } else { - if (prefix.size()) - prefix.deleteLastChar(); - } - } else if (prefix.size() + _currentCode.size() < MAXWORDLEN - 1) { // don't overflow the dialog line - if (active == 15) { // zero - _currentCode += buttonStr[9]; - } else { - _currentCode += buttonStr[active]; - } - } - - switch (mode) { - case kModeNum: - _currentWord = _currentCode; - break; - case kModePre: - if (!matchWord() && _currentCode.size()) { - _currentCode.deleteLastChar(); - matchWord(); - } - numMatchingWords = countWordsInString(_predictiveDictActLine); - break; - case kModeAbc: - for (x = 0; x < _currentCode.size(); x++) - if (_currentCode[x] >= '1') - temp[x] = buttons[_currentCode[x] - '1'][3 + repeatcount[x]]; - temp[_currentCode.size()] = 0; - _currentWord = temp; - } - } else if (active == 9) { // next - if (mode == kModePre) { - if (_predictiveDictActLine && numMatchingWords > 1) { - _wordNumber = (_wordNumber + 1) % numMatchingWords; - char tmp[MAXLINELEN]; - strncpy(tmp, _predictiveDictActLine, MAXLINELEN); - tmp[MAXLINELEN - 1] = 0; - char *tok = strtok(tmp, " "); - for (uint8 i = 0; i <= _wordNumber; i++) - tok = strtok(NULL, " "); - _currentWord = Common::String(tok, _currentCode.size()); - } - } else if (mode == kModeAbc){ - x = _currentCode.size(); - if (x) { - if (_currentCode.lastChar() == '1' || _currentCode.lastChar() == '7' || _currentCode.lastChar() == '9') - repeatcount[x - 1] = (repeatcount[x - 1] + 1) % 4; - else - repeatcount[x - 1] = (repeatcount[x - 1] + 1) % 3; - if (_currentCode.lastChar() >= '1') - _currentWord.setChar(buttons[_currentCode[x - 1] - '1'][3 + repeatcount[x - 1]], x-1); - } - } - } else if (active == 10) { // add - debug(0, "add"); - } else if (active == 13) { // Ok - // bring MRU word at the top of the list when ok'ed out of the dialog - if (mode == kModePre && _predictiveDictActLine && numMatchingWords > 1 && _wordNumber != 0) - bringWordtoTop(_predictiveDictActLine, _wordNumber); - rc = true; - enterPredictiveResult = true; - closeDialog = true; - } else if (active == 14) { // Mode - mode++; - if (mode > kModeAbc) - mode = kModePre; - - // truncate current input at mode change - strncpy(temp, _currentWord.c_str(), _currentCode.size()); - temp[_currentCode.size()] = 0; - prefix += temp; - _currentCode.clear(); - _currentWord.clear(); - memset(repeatcount, 0, sizeof(repeatcount)); - _predictiveDictActLine = NULL; - } else { - enterPredictiveResult = true; - closeDialog = true; - } - } - } - } - - if (enterPredictiveResult) { - Common::strlcpy(_predictiveResult, prefix.c_str(), sizeof(_predictiveResult)); - Common::strlcat(_predictiveResult, _currentWord.c_str(), sizeof(_predictiveResult)); - } - - // if another window was shown, bring it up again - if (!tmpwindow.active) - closeWindow(); - else { - _gfx->restoreBlock(_game.window.x1, _game.window.y1, - _game.window.x2, _game.window.y2, _game.window.buffer); - - free(_game.window.buffer); - memcpy(&(_game.window), &tmpwindow, sizeof(AgiBlock)); - _gfx->doUpdate(); - } - - _system->setFeatureState(OSystem::kFeatureDisableKeyFiltering, false); - _predictiveDialogRunning = false; - - return rc; -} - -void AgiEngine::loadDict() { - Common::File inFile; - int lines = 0; - - ConfMan.registerDefault("predictive_dictionary", "pred.dic"); - - uint32 time1 = _system->getMillis(); - Common::String inFileName(ConfMan.get("predictive_dictionary")); - if (!inFile.open(inFileName)) - return; - - char *ptr; - int size = inFile.size(); - - _predictiveDictText = (char *)malloc(size + 1); - if (!_predictiveDictText) { - warning("Not enough memory to load the predictive dictionary"); - return; - } - inFile.read(_predictiveDictText, size); - _predictiveDictText[size] = 0; - uint32 time2 = _system->getMillis(); - debug("Time to read %s: %d bytes, %d ms", inFileName.c_str(), size, time2-time1); - inFile.close(); - - ptr = _predictiveDictText; - lines = 1; - while ((ptr = strchr(ptr, '\n'))) { - lines++; - ptr++; - } - - _predictiveDictLine = (char **)calloc(1, sizeof(char *) * lines); - if (_predictiveDictLine == NULL) { - warning("Cannot allocate memory for line index buffer"); - return; - } - _predictiveDictLine[0] = _predictiveDictText; - ptr = _predictiveDictText; - int i = 1; - while ((ptr = strchr(ptr, '\n'))) { - *ptr = 0; - ptr++; -#ifdef __DS__ - // Pass the line on to the DS word list - DS::addAutoCompleteLine(_predictiveDictLine[i - 1]); -#endif - _predictiveDictLine[i++] = ptr; - } - if (_predictiveDictLine[lines - 1][0] == 0) - lines--; - - _predictiveDictLineCount = lines; - debug("Loaded %d lines", _predictiveDictLineCount); - - // FIXME: We use binary search on _predictiveDictLine, yet we make no attempt - // to ever sort this array (except for the DS port). That seems risky, doesn't it? - -#ifdef __DS__ - // Sort the DS word completion list, to allow for a binary chop later (in the ds backend) - DS::sortAutoCompleteWordList(); -#endif - - uint32 time3 = _system->getMillis(); - debug("Time to parse pred.dic: %d, total: %d", time3-time2, time3-time1); -} - -bool AgiEngine::matchWord() { - // If no text has been entered, then there is no match. - if (_currentCode.empty()) - return false; - - // If the currently entered text is too long, it cannot match anything. - if (_currentCode.size() > MAXWORDLEN) - return false; - - // The entries in the dictionary consist of a code, a space, and then - // a space-separated list of words matching this code. - // To exactly match a code, we therefore match the code plus the trailing - // space in the dictionary. - Common::String code = _currentCode + " "; - - // Perform a binary search on the dictionary. - int hi = _predictiveDictLineCount - 1; - int lo = 0; - int line = 0; - while (lo <= hi) { - line = (lo + hi) / 2; - int cmpVal = strncmp(_predictiveDictLine[line], code.c_str(), code.size()); - if (cmpVal > 0) - hi = line - 1; - else if (cmpVal < 0) - lo = line + 1; - else { - break; - } - } - - bool partial = hi < lo; - if (partial) { - // Didn't find an exact match, but 'lo' now points to the first entry - // lexicographically greater than the current code, so that will - // be the first entry with the current code as a prefix, if it exists. - line = lo; - _predictiveDictActLine = NULL; - } else { - _predictiveDictActLine = _predictiveDictLine[line]; - } - - _currentWord.clear(); - _wordNumber = 0; - if (0 == strncmp(_predictiveDictLine[line], _currentCode.c_str(), _currentCode.size())) { - char tmp[MAXLINELEN]; - strncpy(tmp, _predictiveDictLine[line], MAXLINELEN); - tmp[MAXLINELEN - 1] = 0; - char *tok = strtok(tmp, " "); - tok = strtok(NULL, " "); - _currentWord = Common::String(tok, _currentCode.size()); - return true; - } else { - return false; - } -} - -} // End of namespace Agi diff --git a/gui/ThemeEngine.cpp b/gui/ThemeEngine.cpp index bcfd41e05b..fdd7750af9 100644 --- a/gui/ThemeEngine.cpp +++ b/gui/ThemeEngine.cpp @@ -47,6 +47,7 @@ const char * const ThemeEngine::kImageLogo = "logo.bmp"; const char * const ThemeEngine::kImageLogoSmall = "logo_small.bmp"; const char * const ThemeEngine::kImageSearch = "search.bmp"; const char * const ThemeEngine::kImageEraser = "eraser.bmp"; +const char * const ThemeEngine::kImageDelbtn = "delbtn.bmp"; struct TextDrawData { const Graphics::Font *_fontPtr; diff --git a/gui/ThemeEngine.h b/gui/ThemeEngine.h index 42ccc57ce8..e26a584354 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.9" +#define SCUMMVM_THEME_VERSION_STR "SCUMMVM_STX0.8.10" class OSystem; @@ -229,6 +229,7 @@ public: static const char *const kImageLogoSmall; ///< ScummVM logo used in the GMM static const char *const kImageSearch; ///< Search tool image used in the launcher static const char *const kImageEraser; ///< Clear input image used in the launcher + static const char *const kImageDelbtn; ///< Delete characters in the predictive dialog /** * Graphics mode enumeration. diff --git a/gui/module.mk b/gui/module.mk index df6b76172a..d272bb0313 100644 --- a/gui/module.mk +++ b/gui/module.mk @@ -13,6 +13,7 @@ MODULE_OBJS := \ message.o \ object.o \ options.o \ + predictivedialog.o \ saveload.o \ themebrowser.o \ ThemeEngine.o \ diff --git a/gui/predictivedialog.cpp b/gui/predictivedialog.cpp new file mode 100644 index 0000000000..ac329867d2 --- /dev/null +++ b/gui/predictivedialog.cpp @@ -0,0 +1,917 @@ +/* ScummVM - Graphic Adventure Engine + * + * 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 source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "gui/predictivedialog.h" +#include "gui/widget.h" +#include "gui/widgets/edittext.h" +#include "gui/gui-manager.h" + +#include "common/config-manager.h" +#include "common/translation.h" +#include "common/events.h" +#include "common/debug.h" +#include "common/system.h" +#include "common/keyboard.h" +#include "common/file.h" +#include "common/savefile.h" + +using namespace Common; + +namespace GUI { + +enum { + kCancelCmd = 'CNCL', + kOkCmd = '__OK', + kBut1Cmd = 'BUT1', + kBut2Cmd = 'BUT2', + kBut3Cmd = 'BUT3', + kBut4Cmd = 'BUT4', + kBut5Cmd = 'BUT5', + kBut6Cmd = 'BUT6', + kBut7Cmd = 'BUT7', + kBut8Cmd = 'BUT8', + kBut9Cmd = 'BUT9', + kBut0Cmd = 'BUT0', + kNextCmd = 'NEXT', + kAddCmd = '_ADD', + kModeCmd = 'MODE', + kDelCmd = '_DEL', + kTestCmd = 'TEST' +}; + +enum { + kModePre = 0, + kModeNum = 1, + kModeAbc = 2 +}; + +PredictiveDialog::PredictiveDialog() : Dialog("Predictive") { + new StaticTextWidget(this, "Predictive.Headline", "Enter Text"); + + new ButtonWidget(this, "Predictive.Cancel" , _("Cancel") , 0, kCancelCmd); + new ButtonWidget(this, "Predictive.OK" , _("Ok") , 0, kOkCmd); + new ButtonWidget(this, "Predictive.Button1", "1 `-.&" , 0, kBut1Cmd); + new ButtonWidget(this, "Predictive.Button2", "2 abc" , 0, kBut2Cmd); + new ButtonWidget(this, "Predictive.Button3", "3 def" , 0, kBut3Cmd); + new ButtonWidget(this, "Predictive.Button4", "4 ghi" , 0, kBut4Cmd); + new ButtonWidget(this, "Predictive.Button5", "5 jkl" , 0, kBut5Cmd); + new ButtonWidget(this, "Predictive.Button6", "6 mno" , 0, kBut6Cmd); + new ButtonWidget(this, "Predictive.Button7", "7 pqrs" , 0, kBut7Cmd); + new ButtonWidget(this, "Predictive.Button8", "8 tuv" , 0, kBut8Cmd); + new ButtonWidget(this, "Predictive.Button9", "9 wxyz" , 0, kBut9Cmd); + new ButtonWidget(this, "Predictive.Button0", "0" , 0, kBut0Cmd); + // I18N: You must leave "#" as is, only word 'next' is translatable + new ButtonWidget(this, "Predictive.Next" , _("# next") , 0, kNextCmd); + _addBtn = new ButtonWidget(this, "Predictive.Add", _("add") , 0, kAddCmd); + _addBtn->setEnabled(false); + +#ifndef DISABLE_FANCY_THEMES + _delbtn = new PicButtonWidget(this, "Predictive.Delete", _("Delete char"), kDelCmd); + ((PicButtonWidget *)_delbtn)->useThemeTransparency(true); + ((PicButtonWidget *)_delbtn)->setGfx(g_gui.theme()->getImageSurface(ThemeEngine::kImageDelbtn)); +#endif + _delbtn = new ButtonWidget(this, "Predictive.Delete" , _("<") , 0, kDelCmd); + // I18N: Pre means 'Predictive', leave '*' as is + _modebutton = new ButtonWidget(this, "Predictive.Pre", _("* Pre"), 0, kModeCmd); + _edittext = new EditTextWidget(this, "Predictive.Word", _search, 0, 0, 0); + + _userDictHasChanged = false; + + _predictiveDict.nameDict = "predictive_dictionary"; + _predictiveDict.fnameDict = "pred.dic"; + _predictiveDict.dictActLine = NULL; + + _userDict.nameDict = "user_dictionary"; + _userDict.fnameDict = "user.dic"; + _userDict.dictActLine = NULL; + + _unitedDict.nameDict = ""; + _unitedDict.fnameDict = ""; + + _predictiveDict.dictLine = NULL; + _predictiveDict.dictText = NULL; + _predictiveDict.dictLineCount = 0; + + if (!_predictiveDict.dictText) { + loadAllDictionary(_predictiveDict); + if (!_predictiveDict.dictText) + debug("Predictive Dialog: pred.dic not loaded"); + } + + _userDict.dictLine = NULL; + _userDict.dictText = NULL; + _userDict.dictTextSize = 0; + _userDict.dictLineCount = 0; + + if (!_userDict.dictText) { + loadAllDictionary(_userDict); + if (!_userDict.dictText) + debug("Predictive Dialog: user.dic not loaded"); + } + + mergeDicts(); + + _unitedDict.dictActLine = NULL; + _unitedDict.dictText = NULL; + + memset(_repeatcount, 0, sizeof(_repeatcount)); + + _prefix.clear(); + _currentCode.clear(); + _currentWord.clear(); + _wordNumber = 0; + _numMatchingWords = 0; + + _lastbutton = kNoAct; + _mode = kModePre; + + _lastTime = 0; + _curTime = 0; + _lastPressBtn = kNoAct; + + _memoryList[0] = _predictiveDict.dictText; + _memoryList[1] = _userDict.dictText; + _numMemory = 0; + + _navigationwithkeys = false; +} + +PredictiveDialog::~PredictiveDialog() { + for (int i = 0; i < _numMemory; i++) { + free(_memoryList[i]); + } + free(_userDict.dictLine); + free(_predictiveDict.dictLine); + free(_unitedDict.dictLine); +} + +void PredictiveDialog::saveUserDictToFile() { + if (_userDictHasChanged) { + ConfMan.registerDefault("user_dictionary", "user.dic"); + + Common::OutSaveFile *file = g_system->getSavefileManager()->openForSaving(ConfMan.get("user_dictionary")); + + for (int i = 0; i < _userDict.dictLineCount; i++) { + file->writeString(_userDict.dictLine[i]); + file->writeString("\n"); + } + + file->finalize(); + delete file; + } +} + +void PredictiveDialog::handleKeyDown(Common::KeyState state) { + ButtonId act = kNoAct; + + if (getFocusWidget() == _edittext) { + setFocusWidget(_addBtn); + } + + switch (state.keycode) { + case Common::KEYCODE_ESCAPE: + saveUserDictToFile(); + close(); + return; + case Common::KEYCODE_LEFT: + _navigationwithkeys = true; + if (_lastbutton == kBtn1Act || _lastbutton == kBtn4Act || _lastbutton == kBtn7Act) + act = ButtonId(_lastbutton + 2); + else if (_lastbutton == kNextAct) + act = kBtn0Act; + else if (_lastbutton == kDelAct) + act = kDelAct; + else if (_lastbutton == kCancelAct) + act = kOkAct; + else if (_lastbutton == kModeAct) + act = kAddAct; + else + act = ButtonId(_lastbutton - 1); + _lastbutton = act; + //needRefresh = true; + break; + case Common::KEYCODE_RIGHT: + _navigationwithkeys = true; + if (_lastbutton == kBtn3Act || _lastbutton == kBtn6Act || _lastbutton == kBtn9Act) + act = ButtonId(_lastbutton - 2); + else if (_lastbutton == kAddAct) + act = kModeAct; + else if (_lastbutton == kDelAct) + act = kDelAct; + else if (_lastbutton == kOkAct) + act = kCancelAct; + else if (_lastbutton == kBtn0Act) + act = kNextAct; + else + act = ButtonId(_lastbutton + 1); + _lastbutton = act; + //needRefresh = true; + break; + case Common::KEYCODE_UP: + _navigationwithkeys = true; + if (_lastbutton <= kBtn3Act) + act = kDelAct; + else if (_lastbutton == kNextAct || _lastbutton == kAddAct) + act = ButtonId(_lastbutton - 2); + else if (_lastbutton == kDelAct) + act = kOkAct; + else if (_lastbutton == kModeAct) + act = kBtn9Act; + else if (_lastbutton == kBtn0Act) + act = kBtn7Act; + else + act = ButtonId(_lastbutton - 3); + _lastbutton = act; + //needRefresh = true; + break; + case Common::KEYCODE_DOWN: + _navigationwithkeys = true; + if (_lastbutton == kBtn7Act) + act = kBtn0Act; + else if (_lastbutton == kBtn8Act || _lastbutton == kBtn9Act) + act = ButtonId(_lastbutton + 2); + else if (_lastbutton == kDelAct) + act = kBtn1Act; + else if (_lastbutton == kCancelAct || _lastbutton == kOkAct) + act = kDelAct; + else if (_lastbutton == kModeAct || _lastbutton == kBtn0Act) + act = ButtonId(_lastbutton - 2); + else + act = ButtonId(_lastbutton + 3); + _lastbutton = act; + //needRefresh = true; + break; + case Common::KEYCODE_KP_ENTER: + if (_navigationwithkeys) { + // when the user has utilized arrow key navigation, + // interpret enter as 'click' on the act button + act = _lastbutton; + } else { + // else it is a shortcut for 'Ok' + act = kOkAct; + } + break; + case Common::KEYCODE_KP_PLUS: + act = kAddAct; + break; + case Common::KEYCODE_BACKSPACE: + case Common::KEYCODE_KP_MINUS: + act = kDelAct; + break; + case Common::KEYCODE_KP_DIVIDE: + act = kNextAct; + break; + case Common::KEYCODE_KP_MULTIPLY: + act = kModeAct; + break; + case Common::KEYCODE_KP0: + act = kBtn0Act; + break; + case Common::KEYCODE_KP1: + case Common::KEYCODE_KP2: + case Common::KEYCODE_KP3: + case Common::KEYCODE_KP4: + case Common::KEYCODE_KP5: + case Common::KEYCODE_KP6: + case Common::KEYCODE_KP7: + case Common::KEYCODE_KP8: + case Common::KEYCODE_KP9: + act = ButtonId(state.keycode - Common::KEYCODE_KP1); + break; + default: + Dialog::handleKeyDown(state); + } + + if (act != kNoAct) { + processBtnActive(act); + } +} + +void PredictiveDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) { + ButtonId act = kNoAct; + + _navigationwithkeys = false; + + switch (cmd) { + case kDelCmd: + act = kDelAct; + break; + case kNextCmd: + act = kNextAct; + break; + case kAddCmd: + act = kAddAct; + break; + case kModeCmd: + act = kModeAct; + break; + case kBut1Cmd: + act = kBtn1Act; + break; + case kBut2Cmd: + act = kBtn2Act; + break; + case kBut3Cmd: + act = kBtn3Act; + break; + case kBut4Cmd: + act = kBtn4Act; + break; + case kBut5Cmd: + act = kBtn5Act; + break; + case kBut6Cmd: + act = kBtn6Act; + break; + case kBut7Cmd: + act = kBtn7Act; + break; + case kBut8Cmd: + act = kBtn8Act; + break; + case kBut9Cmd: + act = kBtn9Act; + break; + case kBut0Cmd: + act = kBtn0Act; + break; + case kCancelCmd: + saveUserDictToFile(); + close(); + return; + case kOkCmd: + act = kOkAct; + break; + default: + Dialog::handleCommand(sender, cmd, data); + } + + if (act != kNoAct) { + processBtnActive(act); + } +} + +void PredictiveDialog::processBtnActive(ButtonId button) { + uint8 x; + const char *buttonStr[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9", "0" }; + const char *buttons[] = { + "'-.&", "abc", "def", + "ghi", "jkl", "mno", + "pqrs", "tuv", "wxyz", + "next", "add", + "<", + "Cancel", "OK", + "Pre", "(0) ", NULL + }; + + if (_mode == kModeAbc) { + if (button >= kBtn1Act && button <= kBtn9Act ) { + if (!_lastTime) + _lastTime = g_system->getMillis(); + if (_lastPressBtn == button) { + _curTime = g_system->getMillis(); + if((_curTime - _lastTime) < kRepeatDelay) { + button = kNextAct; + _lastTime = _curTime; + } else { + _lastTime = 0; + } + } else { + _lastPressBtn = button; + _lastTime = g_system->getMillis(); + } + } + } + + if (button >= kBtn1Act) { + _lastbutton = button; + if (button == kBtn0Act && _mode != kModeNum) { // Space + // bring MRU word at the top of the list when changing words + if (_mode == kModePre && _unitedDict.dictActLine && _numMatchingWords > 1 && _wordNumber != 0) + bringWordtoTop(_unitedDict.dictActLine, _wordNumber); + + strncpy(_temp, _currentWord.c_str(), _currentCode.size()); + _temp[_currentCode.size()] = 0; + _prefix += _temp; + _prefix += " "; + _currentCode.clear(); + _currentWord.clear(); + _numMatchingWords = 0; + memset(_repeatcount, 0, sizeof(_repeatcount)); + _lastTime = 0; + _lastPressBtn = kNoAct; + _curTime = 0; + } else if (button < kNextAct || button == kDelAct || button == kBtn0Act) { // number or backspace + if (button == kDelAct) { // backspace + if (_currentCode.size()) { + _repeatcount[_currentCode.size() - 1] = 0; + _currentCode.deleteLastChar(); + if(_currentCode == Common::String("")) + _currentWord.clear(); + } else { + if (_prefix.size()) + _prefix.deleteLastChar(); + } + } else if (_prefix.size() + _currentCode.size() < MAXWORDLEN - 1) { // don't overflow the dialog line + if (button == kBtn0Act) { // zero + _currentCode += buttonStr[9]; + } else { + _currentCode += buttonStr[button]; + } + } + + switch (_mode) { + case kModeNum: + _currentWord = _currentCode; + break; + case kModePre: + if (!matchWord() && _currentCode.size()) { + _currentCode.deleteLastChar(); + matchWord(); + } + _numMatchingWords = countWordsInString(_unitedDict.dictActLine); + break; + case kModeAbc: + for (x = 0; x < _currentCode.size(); x++) + if (_currentCode[x] >= '1') + _temp[x] = buttons[_currentCode[x] - '1'][_repeatcount[x]]; + _temp[_currentCode.size()] = 0; + _currentWord = _temp; + } + } else if (button == kNextAct) { // next + if (_mode == kModePre) { + if (_unitedDict.dictActLine && _numMatchingWords > 1) { + _wordNumber = (_wordNumber + 1) % _numMatchingWords; + char tmp[MAXLINELEN]; + strncpy(tmp, _unitedDict.dictActLine, MAXLINELEN); + tmp[MAXLINELEN - 1] = 0; + char *tok = strtok(tmp, " "); + for (uint8 i = 0; i <= _wordNumber; i++) + tok = strtok(NULL, " "); + _currentWord = Common::String(tok, _currentCode.size()); + } + } else if (_mode == kModeAbc) { + x = _currentCode.size(); + if (x) { + if (_currentCode.lastChar() == '1' || _currentCode.lastChar() == '7' || _currentCode.lastChar() == '9') + _repeatcount[x - 1] = (_repeatcount[x - 1] + 1) % 4; + else + _repeatcount[x - 1] = (_repeatcount[x - 1] + 1) % 3; + + if (_currentCode.lastChar() >= '1') + _currentWord.setChar(buttons[_currentCode[x - 1] - '1'][_repeatcount[x - 1]], x-1); + } + } + } else if (button == kAddAct) { // add + if (_mode == kModeAbc) + addWordToDict(); + else + debug("Predictive Dialog: button Add doesn't work in this mode"); + } else if (button == kOkAct) { // Ok + // bring MRU word at the top of the list when ok'ed out of the dialog + if (_mode == kModePre && _unitedDict.dictActLine && _numMatchingWords > 1 && _wordNumber != 0) + bringWordtoTop(_unitedDict.dictActLine, _wordNumber); + + goto press; + } else if (button == kModeAct) { // Mode + _mode++; + _addBtn->setEnabled(false); + if (_mode > kModeAbc) { + _mode = kModePre; + // I18N: Pre means 'Predictive', leave '*' as is + _modebutton->setLabel("* Pre"); + // I18N: 'Num' means Numbers, 'Abc' means Latin alphabet input + } else (_mode == kModeNum) ? _modebutton->setLabel("* Num") : (_modebutton->setLabel("* Abc"), _addBtn->setEnabled(true)); + + // truncate current input at mode change + strncpy(_temp, _currentWord.c_str(), _currentCode.size()); + _temp[_currentCode.size()] = 0; + _prefix += _temp; + _currentCode.clear(); + _currentWord.clear(); + memset(_repeatcount, 0, sizeof(_repeatcount)); + + _lastTime = 0; + _lastPressBtn = kNoAct; + _curTime = 0; + } else { + goto press; + } + } + +press: + pressEditText(); + + if (button == kOkAct) close(); +} + +void PredictiveDialog::handleTickle() { + if (!_lastTime) + if ((_curTime - _lastTime) > kRepeatDelay) { + _lastTime = 0; + } +} + +void PredictiveDialog::mergeDicts() { + _unitedDict.dictLineCount = _predictiveDict.dictLineCount + _userDict.dictLineCount; + _unitedDict.dictLine = (char **)calloc(1, sizeof(char *) * _unitedDict.dictLineCount); + + if (!_unitedDict.dictLine) { + debug("Predictive Dialog: cannot allocate memory for united dic"); + return; + } + + int lenUserDictCode, lenPredictiveDictCode, lenCode; + int i, j, k; + i = j = k = 0; + + while ((i < _userDict.dictLineCount) && (j < _predictiveDict.dictLineCount)) { + lenUserDictCode = strchr(_userDict.dictLine[i], ' ') - _userDict.dictLine[i]; + lenPredictiveDictCode = strchr(_predictiveDict.dictLine[j], ' ') - _predictiveDict.dictLine[j]; + lenCode = (lenUserDictCode >= lenPredictiveDictCode) ? lenUserDictCode : lenPredictiveDictCode; + if (strncmp(_userDict.dictLine[i], _predictiveDict.dictLine[j], lenCode) >= 0) { + _unitedDict.dictLine[k++] = _predictiveDict.dictLine[j++]; + } else { + _unitedDict.dictLine[k++] = _userDict.dictLine[i++]; + } + } + + while (i < _userDict.dictLineCount) { + _unitedDict.dictLine[k++] = _userDict.dictLine[i++]; + } + + while (j < _predictiveDict.dictLineCount) { + _unitedDict.dictLine[k++] = _predictiveDict.dictLine[j++]; + } +} + +uint8 PredictiveDialog::countWordsInString(char *str) { + // Count the number of (space separated) words in the given string. + char *ptr; + + if (!str) + return 0; + + ptr = strchr(str, ' '); + if (!ptr) { + debug("Predictive Dialog: Invalid dictionary line"); + return 0; + } + + uint8 num = 1; + ptr++; + while ((ptr = strchr(ptr, ' '))) { + ptr++; + num++; + } + return num; +} + +void PredictiveDialog::bringWordtoTop(char *str, int wordnum) { + // This function reorders the words on the given pred.dic line + // by moving the word at position 'wordnum' to the front (that is, right behind + // right behind the numerical code word at the start of the line). + Common::Array<Common::String> words; + char buf[MAXLINELEN]; + + if (!str) + return; + strncpy(buf, str, MAXLINELEN); + buf[MAXLINELEN - 1] = 0; + char *word = strtok(buf, " "); + if (!word) { + debug("Predictive Dialog: Invalid dictionary line"); + return; + } + + words.push_back(word); + while ((word = strtok(NULL, " ")) != NULL) + words.push_back(word); + words.insert_at(1, words.remove_at(wordnum + 1)); + + Common::String tmp; + for (uint8 i = 0; i < words.size(); i++) + tmp += words[i] + " "; + tmp.deleteLastChar(); + memcpy(str, tmp.c_str(), strlen(str)); +} + +int PredictiveDialog::binarySearch(char **dictLine, const String &code, int dictLineCount) { + int hi = dictLineCount - 1; + int lo = 0; + int line = 0; + while (lo <= hi) { + line = (lo + hi) / 2; + int cmpVal = strncmp(dictLine[line], code.c_str(), code.size()); + if (cmpVal > 0) + hi = line - 1; + else if (cmpVal < 0) + lo = line + 1; + else { + break; + } + } + + if (hi < lo) { + return -(lo + 1); + } else { + return line; + } +} + +bool PredictiveDialog::matchWord() { + // If no text has been entered, then there is no match. + if (_currentCode.empty()) + return false; + + // If the currently entered text is too long, it cannot match anything. + if (_currentCode.size() > MAXWORDLEN) + return false; + + // The entries in the dictionary consist of a code, a space, and then + // a space-separated list of words matching this code. + // To exactly match a code, we therefore match the code plus the trailing + // space in the dictionary. + Common::String code = _currentCode + " "; + + int line = binarySearch(_unitedDict.dictLine, code, _unitedDict.dictLineCount); + if (line < 0) { + line = -(line + 1); + _unitedDict.dictActLine = NULL; + } else { + _unitedDict.dictActLine = _unitedDict.dictLine[line]; + } + + _currentWord.clear(); + _wordNumber = 0; + if (0 == strncmp(_unitedDict.dictLine[line], _currentCode.c_str(), _currentCode.size())) { + char tmp[MAXLINELEN]; + strncpy(tmp, _unitedDict.dictLine[line], MAXLINELEN); + tmp[MAXLINELEN - 1] = 0; + char *tok = strtok(tmp, " "); + tok = strtok(NULL, " "); + _currentWord = Common::String(tok, _currentCode.size()); + return true; + } else { + return false; + } +} + +bool PredictiveDialog::searchWord(char *where, const String &whatCode) { + char *ptr = where; + ptr += whatCode.size(); + + char *newPtr; + bool is = false; + while((newPtr = strchr(ptr, ' '))) { + if (0 == strncmp(ptr, _currentWord.c_str(), newPtr - ptr)) { + is = true; + break; + } + ptr = newPtr + 1; + } + if (!is) { + if (0 == strcmp(ptr, _currentWord.c_str())) { + is = true; + } + } + return is; +} + +void PredictiveDialog::addWord(Dict &dict, const String &word, const String &code) { + char *newLine; + Common::String tmpCode = code + ' '; + int line = binarySearch(dict.dictLine, tmpCode, dict.dictLineCount); + if (line >= 0) { + if (searchWord(dict.dictLine[line], tmpCode)) { + // if we found code and word, we should not insert/expands any word + return; + } else { + // if we found the code, but did not find a word, we must + // EXPANDS the currnent line with new word + int oldLineSize = strlen(dict.dictLine[line]); + int newLineSize = oldLineSize + word.size() + 1; + + newLine = (char *)malloc(newLineSize + 1); + + char *ptr = newLine; + strncpy(ptr, dict.dictLine[line], oldLineSize); + ptr += oldLineSize; + Common::String tmp = ' ' + word + '\0'; + strncpy(ptr, tmp.c_str(), tmp.size()); + + dict.dictLine[line] = newLine; + _memoryList[_numMemory++] = newLine; + + if (dict.nameDict == "user_dictionary") + _userDictHasChanged = true; + + return; + } + } else { // if we didn't find the code, we need to INSERT new line with code and word + if (dict.nameDict == "user_dictionary") { + // if we must INSERT new line(code and word) to user_dictionary, we need to + // check if there is a line that we want to INSERT in predictive dictionay + int predictLine = binarySearch(_predictiveDict.dictLine, tmpCode, _predictiveDict.dictLineCount); + if (predictLine >= 0) { + if (searchWord(_predictiveDict.dictLine[predictLine], tmpCode)) { + // if code and word is in predictive dictionary, we need to copy + // this line to user dictionary + int len = (predictLine == _predictiveDict.dictLineCount - 1) ? &_predictiveDict.dictText[_predictiveDict.dictTextSize] - _predictiveDict.dictLine[predictLine] : + _predictiveDict.dictLine[predictLine + 1] - _predictiveDict.dictLine[predictLine]; + newLine = (char *)malloc(len); + strncpy(newLine, _predictiveDict.dictLine[predictLine], len); + } else { + // if there is no word in predictive dictionary, we need to copy to + // user dictionary mathed line + new word. + int len = (predictLine == _predictiveDict.dictLineCount - 1) ? &_predictiveDict.dictText[_predictiveDict.dictTextSize] - _predictiveDict.dictLine[predictLine] : + _predictiveDict.dictLine[predictLine + 1] - _predictiveDict.dictLine[predictLine]; + newLine = (char *)malloc(len + word.size() + 1); + char *ptr = newLine; + strncpy(ptr, _predictiveDict.dictLine[predictLine], len); + ptr[len - 1] = ' '; + ptr += len; + strncpy(ptr, word.c_str(), word.size()); + ptr[len + word.size()] = '\0'; + } + } else { + // if we didnt find line in predictive dialog, we should copy to user dictionary + // code + word + Common::String tmp; + tmp = tmpCode + word + '\0'; + newLine = (char *)malloc(tmp.size()); + strncpy(newLine, tmp.c_str(), tmp.size()); + } + } else { + // if want to insert line to different from user dictionary, we should copy to this + // dictionary code + word + Common::String tmp; + tmp = tmpCode + word + '\0'; + newLine = (char *)malloc(tmp.size()); + strncpy(newLine, tmp.c_str(), tmp.size()); + } + } + + // start from here are INSERTING new line to dictionaty ( dict ) + char **newDictLine = (char **)calloc(1, sizeof(char *) * (dict.dictLineCount + 1)); + if (!newDictLine) { + warning("Predictive Dialog: cannot allocate memory for index buffer"); + return; + } + newDictLine[dict.dictLineCount] = '\0'; + + int k = 0; + bool inserted = false; + for (int i = 0; i < dict.dictLineCount; i++) { + uint lenPredictiveDictCode = strchr(dict.dictLine[i], ' ') - dict.dictLine[i]; + uint lenCode = (lenPredictiveDictCode >= (code.size() - 1)) ? lenPredictiveDictCode : code.size() - 1; + if ((strncmp(dict.dictLine[i], code.c_str(), lenCode) > 0) && !inserted) { + newDictLine[k++] = newLine; + inserted = true; + } + if (k != (dict.dictLineCount + 1)) { + newDictLine[k++] = dict.dictLine[i]; + } + } + if (!inserted) + newDictLine[k] = newLine; + + _memoryList[_numMemory++] = newLine; + + free(dict.dictLine); + dict.dictLineCount += 1; + dict.dictLine = (char **)calloc(1, sizeof(char *) * dict.dictLineCount); + if (!dict.dictLine) { + warning("Predictive Dialog: cannot allocate memory for index buffer"); + free(newDictLine); + return; + } + + for (int i = 0; i < dict.dictLineCount; i++) { + dict.dictLine[i] = newDictLine[i]; + } + + if (dict.nameDict == "user_dictionary") + _userDictHasChanged = true; + + free(newDictLine); +} + +void PredictiveDialog::addWordToDict() { + if (_numMemory < MAXWORD) { + addWord(_unitedDict, _currentWord, _currentCode); + addWord(_userDict, _currentWord, _currentCode); + } else { + warning("Predictive Dialog: You cannot add word to user dictionary..."); + } +} + +void PredictiveDialog::loadDictionary(Common::SeekableReadStream *in, Dict &dict) { + int lines = 0; + + uint32 time1 = g_system->getMillis(); + + dict.dictTextSize = in->size(); + dict.dictText = (char *)malloc(dict.dictTextSize + 1); + + if (!dict.dictText) { + warning("Predictive Dialog: Not enough memory to load the file user.dic"); + return; + } + + in->read(dict.dictText, dict.dictTextSize); + dict.dictText[dict.dictTextSize] = 0; + uint32 time2 = g_system->getMillis(); + debug("Predictive Dialog: Time to read %s: %d bytes, %d ms", ConfMan.get(dict.nameDict).c_str(), dict.dictTextSize, time2-time1); + delete in; + + char *ptr = dict.dictText; + lines = 1; + while ((ptr = strchr(ptr, '\n'))) { + lines++; + ptr++; + } + + dict.dictLine = (char **)calloc(1, sizeof(char *) * lines); + if (dict.dictLine == NULL) { + warning("Predictive Dialog: Cannot allocate memory for line index buffer"); + return; + } + dict.dictLine[0] = dict.dictText; + ptr = dict.dictText; + int i = 1; + while ((ptr = strchr(ptr, '\n'))) { + *ptr = 0; + ptr++; +#ifdef __DS__ + // Pass the line on to the DS word list + DS::addAutoCompleteLine(dict.dictLine[i - 1]); +#endif + dict.dictLine[i++] = ptr; + } + if (dict.dictLine[lines - 1][0] == 0) + lines--; + + dict.dictLineCount = lines; + debug("Predictive Dialog: Loaded %d lines", dict.dictLineCount); + + // FIXME: We use binary search on _predictiveDict.dictLine, yet we make no at_tempt + // to ever sort this array (except for the DS port). That seems risky, doesn't it? + +#ifdef __DS__ + // Sort the DS word completion list, to allow for a binary chop later (in the ds backend) + DS::sortAutoCompleteWordList(); +#endif + + uint32 time3 = g_system->getMillis(); + debug("Predictive Dialog: Time to parse %s: %d, total: %d", ConfMan.get(dict.nameDict).c_str(), time3-time2, time3-time1); +} + +void PredictiveDialog::loadAllDictionary(Dict &dict) { + ConfMan.registerDefault(dict.nameDict, dict.fnameDict); + + if (dict.nameDict == "predictive_dictionary") { + Common::File *inFile = new File(); + if (!inFile->open(ConfMan.get(dict.nameDict))) { + warning("Predictive Dialog: cannot read file: %s", dict.fnameDict.c_str()); + return; + } + loadDictionary(inFile, dict); + } else { + Common::InSaveFile *inFile = g_system->getSavefileManager()->openForLoading(ConfMan.get(dict.nameDict)); + if (!inFile) { + warning("Predictive Dialog: cannot read file: %s", dict.fnameDict.c_str()); + return; + } + loadDictionary(inFile, dict); + } +} + +void PredictiveDialog::pressEditText() { + Common::strlcpy(_predictiveResult, _prefix.c_str(), sizeof(_predictiveResult)); + Common::strlcat(_predictiveResult, _currentWord.c_str(), sizeof(_predictiveResult)); + _edittext->setEditString(_predictiveResult); + //_edittext->setCaretPos(_prefix.size() + _currentWord.size()); + _edittext->draw(); +} + +} // namespace GUI
\ No newline at end of file diff --git a/gui/predictivedialog.h b/gui/predictivedialog.h new file mode 100644 index 0000000000..6d7cd320b7 --- /dev/null +++ b/gui/predictivedialog.h @@ -0,0 +1,142 @@ +/* ScummVM - Graphic Adventure Engine + * + * 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 source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef GLOBAL_DIALOGS_H +#define GLOBAL_DIALOGS_H + +#include "gui/dialog.h" +#include "common/str.h" +#include "common/stream.h" + +namespace GUI { + +class EditTextWidget; +class ButtonWidget; +class PicButtonWidget; + +enum ButtonId { + kBtn1Act = 0, + kBtn2Act = 1, + kBtn3Act = 2, + kBtn4Act = 3, + kBtn5Act = 4, + kBtn6Act = 5, + kBtn7Act = 6, + kBtn8Act = 7, + kBtn9Act = 8, + kNextAct = 9, + kAddAct = 10, + kDelAct = 11, + kCancelAct = 12, + kOkAct = 13, + kModeAct = 14, + kBtn0Act = 15, + kNoAct = -1 +}; + +enum { + kRepeatDelay = 500 +}; + +enum { + MAXLINELEN = 80, + MAXWORDLEN = 24, + MAXWORD = 50 +}; + +class PredictiveDialog : public GUI::Dialog { + typedef Common::String String; + +public: + PredictiveDialog(); + ~PredictiveDialog(); + + virtual void handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 data); + virtual void handleKeyDown(Common::KeyState state); + virtual void handleTickle(); + + char * getResult() { return _predictiveResult; } +private: + struct Dict { + char **dictLine; + char *dictText; + char *dictActLine; // using only for united dict... + int32 dictLineCount; + int32 dictTextSize; + String nameDict; + String fnameDict; + }; + + uint8 countWordsInString(char *str); + void bringWordtoTop(char *str, int wordnum); + void loadDictionary(Common::SeekableReadStream *in, Dict &dict); + void loadAllDictionary(Dict &dict); + void addWordToDict(); + void addWord(Dict &dict, const String &word, const String &code); + bool searchWord(char *where, const String &whatCode); + int binarySearch(char **dictLine, const String &code, int dictLineCount); + bool matchWord(); + void processBtnActive(ButtonId active); + void pressEditText(); + + void saveUserDictToFile(); + + void mergeDicts(); +private: + Dict _unitedDict; + Dict _predictiveDict; + Dict _userDict; + + int _mode; + ButtonId _lastbutton; + + bool _userDictHasChanged; + + int _wordNumber; + uint8 _numMatchingWords; + char _predictiveResult[40]; + + String _currentCode; + String _currentWord; + String _prefix; + + uint32 _curTime, _lastTime; + ButtonId _lastPressBtn; + + char _temp[MAXWORDLEN + 1]; + int _repeatcount[MAXWORDLEN]; + + char *_memoryList[MAXWORD]; + int _numMemory; + + String _search; + + bool _navigationwithkeys; +private: + EditTextWidget *_edittext; + ButtonWidget *_modebutton; + ButtonWidget *_delbtn; + ButtonWidget *_addBtn; +}; + +} // namespace GUI + +#endif diff --git a/gui/themes/default.inc b/gui/themes/default.inc index f6096ce342..c1047c0994 100644 --- a/gui/themes/default.inc +++ b/gui/themes/default.inc @@ -599,46 +599,50 @@ "/> " "</drawdata> " "</render_info> " -"<layout_info resolution='y<400'> " +"<layout_info resolution='y>399'> " "<globals> " -"<def var='Line.Height' value='12' /> " -"<def var='Font.Height' value='10' /> " -"<def var='About.OuterBorder' value='10'/> " -"<def var='Layout.Spacing' value='8'/> " +"<def var='Line.Height' value='16' /> " +"<def var='Font.Height' value='16' /> " +"<def var='About.OuterBorder' value='80'/> " +"<def var='Layout.Spacing' value='8' /> " "<def var='ShowLauncherLogo' value='0'/> " "<def var='ShowGlobalMenuLogo' value='0'/> " "<def var='ShowSearchPic' value='0'/> " -"<def var='SaveLoadChooser.ExtInfo.Visible' value='0'/> " -"<def var='KeyMapper.Spacing' value='5'/> " -"<def var='KeyMapper.LabelWidth' value='80'/> " -"<def var='KeyMapper.ButtonWidth' value='60'/> " -"<def var='Tooltip.MaxWidth' value='70'/> " -"<def var='Tooltip.XDelta' value='8'/> " -"<def var='Tooltip.YDelta' value='8'/> " -"<widget name='Button' " -"size='72,16' " -"/> " -"<widget name='Slider' " -"size='85,12' " -"/> " +"<def var='SaveLoadChooser.ExtInfo.Visible' value='1'/> " +"<def var='KeyMapper.Spacing' value='10'/> " +"<def var='KeyMapper.LabelWidth' value='100'/> " +"<def var='KeyMapper.ButtonWidth' value='80'/> " +"<def var='Tooltip.MaxWidth' value='200'/> " +"<def var='Tooltip.XDelta' value='16'/> " +"<def var='Tooltip.YDelta' value='16'/> " +"<def var='Predictive.Button.Width' value='60' /> " "<widget name='OptionsLabel' " "size='110,Globals.Line.Height' " "textalign='right' " "/> " "<widget name='SmallLabel' " -"size='18,Globals.Line.Height' " +"size='24,Globals.Line.Height' " +"/> " +"<widget name='ShortOptionsLabel' " +"size='60,Globals.Line.Height' " +"/> " +"<widget name='Button' " +"size='108,24' " +"/> " +"<widget name='Slider' " +"size='128,18' " "/> " "<widget name='PopUp' " -"size='-1,15' " +"size='-1,19' " "/> " "<widget name='Checkbox' " -"size='-1,Globals.Line.Height' " +"size='-1,14' " "/> " "<widget name='Radiobutton' " "size='-1,Globals.Line.Height' " "/> " "<widget name='ListWidget' " -"padding='5,0,0,0' " +"padding='5,0,8,0' " "/> " "<widget name='PopUpWidget' " "padding='7,5,0,0' " @@ -650,28 +654,28 @@ "padding='7,5,5,5' " "/> " "<widget name='Scrollbar' " -"size='9,0' " +"size='15,0' " "/> " "<widget name='TabWidget.Tab' " -"size='45,16' " -"padding='0,0,2,0' " +"size='75,27' " +"padding='0,0,8,0' " "/> " "<widget name='TabWidget.Body' " -"padding='0,0,0,-8' " +"padding='0,0,0,0' " "/> " "<widget name='TabWidget.NavButton' " -"size='32,18' " -"padding='0,0,1,0' " +"size='15,18' " +"padding='0,3,4,0' " "/> " "</globals> " "<dialog name='Launcher' overlays='screen'> " -"<layout type='vertical' center='true' padding='6,6,2,2'> " +"<layout type='vertical' center='true' padding='16,16,8,8'> " "<widget name='Version' " "height='Globals.Line.Height' " "/> " -"<layout type='horizontal' spacing='5' padding='0,0,0,0'> " +"<layout type='horizontal' spacing='5' padding='10,0,0,0'> " "<widget name='SearchDesc' " -"width='50' " +"width='60' " "height='Globals.Line.Height' " "textalign='right' " "/> " @@ -686,38 +690,39 @@ "<space /> " "</layout> " "<widget name='GameList'/> " -"<layout type='horizontal' padding='0,0,0,0' spacing='8'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='10'> " "<widget name='LoadGameButton' " -"height='12' " +"height='20' " "/> " "<widget name='AddGameButton' " -"height='12' " +"height='20' " "/> " "<widget name='EditGameButton' " -"height='12' " +"height='20' " "/> " "<widget name='RemoveGameButton' " -"height='12' " +"height='20' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='8'> " +"<space size='4'/> " +"<layout type='horizontal' padding='0,0,0,0' spacing='10'> " "<widget name='QuitButton' " -"height='12' " +"height='20' " "/> " "<widget name='AboutButton' " -"height='12' " +"height='20' " "/> " "<widget name='OptionsButton' " -"height='12' " +"height='20' " "/> " "<widget name='StartButton' " -"height='12' " +"height='20' " "/> " "</layout> " "</layout> " "</dialog> " -"<dialog name='Browser' overlays='screen' inset='8' shading='dim'> " -"<layout type='vertical' padding='8,8,0,4'> " +"<dialog name='Browser' overlays='Dialog.Launcher.GameList' shading='dim'> " +"<layout type='vertical' padding='8,8,8,8'> " "<widget name='Headline' " "height='Globals.Line.Height' " "/> " @@ -725,7 +730,7 @@ "height='Globals.Line.Height' " "/> " "<widget name='List'/> " -"<layout type='horizontal' padding='0,0,8,0'> " +"<layout type='horizontal' padding='0,0,16,0'> " "<widget name='Up' " "type='Button' " "/> " @@ -739,10 +744,10 @@ "</layout> " "</layout> " "</dialog> " -"<dialog name='GlobalOptions' overlays='screen' inset='16' shading='dim'> " +"<dialog name='GlobalOptions' overlays='Dialog.Launcher.GameList' shading='dim'> " "<layout type='vertical' padding='0,0,0,0'> " "<widget name='TabWidget'/> " -"<layout type='horizontal' padding='8,8,8,8'> " +"<layout type='horizontal' padding='16,16,16,16'> " "<space/> " "<widget name='Cancel' " "type='Button' " @@ -755,7 +760,7 @@ "</dialog> " "<dialog name='GlobalOptions_Graphics' overlays='Dialog.GlobalOptions.TabWidget'> " "<layout type='vertical' padding='16,16,16,16' spacing='8'> " -"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " "<widget name='grModePopupDesc' " "type='OptionsLabel' " "/> " @@ -763,7 +768,7 @@ "type='PopUp' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " "<widget name='grRenderPopupDesc' " "type='OptionsLabel' " "/> " @@ -784,7 +789,7 @@ "</dialog> " "<dialog name='GlobalOptions_Audio' overlays='Dialog.GlobalOptions.TabWidget'> " "<layout type='vertical' padding='16,16,16,16' spacing='8'> " -"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " "<widget name='auMidiPopupDesc' " "type='OptionsLabel' " "/> " @@ -792,7 +797,7 @@ "type='PopUp' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " "<widget name='auOPLPopupDesc' " "type='OptionsLabel' " "/> " @@ -800,7 +805,7 @@ "type='PopUp' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " "<widget name='auSampleRatePopupDesc' " "type='OptionsLabel' " "/> " @@ -808,7 +813,7 @@ "type='PopUp' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='3' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='10'> " "<widget name='subToggleDesc' " "type='OptionsLabel' " "/> " @@ -822,7 +827,7 @@ "type='Radiobutton' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='10'> " "<widget name='subSubtitleSpeedDesc' " "type='OptionsLabel' " "/> " @@ -836,8 +841,9 @@ "</layout> " "</dialog> " "<dialog name='GlobalOptions_Volume' overlays='Dialog.GlobalOptions.TabWidget'> " -"<layout type='vertical' padding='16,16,16,16' spacing='8'> " -"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " +"<layout type='horizontal' padding='16,16,16,16' spacing='8'> " +"<layout type='vertical' padding='0,0,0,0' spacing='8'> " +"<layout type='horizontal' padding='0,0,0,0'> " "<widget name='vcMusicText' " "type='OptionsLabel' " "/> " @@ -848,7 +854,7 @@ "type='SmallLabel' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " +"<layout type='horizontal' padding='0,0,0,0'> " "<widget name='vcSfxText' " "type='OptionsLabel' " "/> " @@ -859,7 +865,7 @@ "type='SmallLabel' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " +"<layout type='horizontal' padding='0,0,0,0'> " "<widget name='vcSpeechText' " "type='OptionsLabel' " "/> " @@ -870,8 +876,8 @@ "type='SmallLabel' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " -"<space size='110' /> " +"</layout> " +"<layout type='vertical' padding='24,0,24,0' center='true'> " "<widget name='vcMuteCheckbox' " "type='Checkbox' " "/> " @@ -880,7 +886,7 @@ "</dialog> " "<dialog name='GlobalOptions_MIDI' overlays='Dialog.GlobalOptions.TabWidget'> " "<layout type='vertical' padding='16,16,16,16' spacing='8'> " -"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " "<widget name='auPrefGmPopupDesc' " "type='OptionsLabel' " "/> " @@ -888,7 +894,7 @@ "type='PopUp' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='16' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " "<widget name='mcFontButton' " "type='Button' " "/> " @@ -903,7 +909,7 @@ "<widget name='mcMixedCheckbox' " "type='Checkbox' " "/> " -"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " +"<layout type='horizontal' padding='0,0,0,0'> " "<widget name='mcMidiGainText' " "type='OptionsLabel' " "/> " @@ -919,7 +925,7 @@ "</dialog> " "<dialog name='GlobalOptions_MT32' overlays='Dialog.GlobalOptions.TabWidget'> " "<layout type='vertical' padding='16,16,16,16' spacing='8'> " -"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " "<widget name='auPrefMt32PopupDesc' " "type='OptionsLabel' " "/> " @@ -937,7 +943,7 @@ "</dialog> " "<dialog name='GlobalOptions_Paths' overlays='Dialog.GlobalOptions.TabWidget'> " "<layout type='vertical' padding='16,16,16,16' spacing='8'> " -"<layout type='horizontal' padding='0,0,0,0' spacing='16'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " "<widget name='SaveButton' " "type='Button' " "/> " @@ -949,7 +955,7 @@ "width='Globals.Line.Height' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='16'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " "<widget name='ThemeButton' " "type='Button' " "/> " @@ -961,7 +967,7 @@ "width='Globals.Line.Height' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='16'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " "<widget name='ExtraButton' " "type='Button' " "/> " @@ -985,7 +991,7 @@ "</dialog> " "<dialog name='GlobalOptions_Misc' overlays='Dialog.GlobalOptions.TabWidget'> " "<layout type='vertical' padding='16,16,16,16' spacing='8'> " -"<layout type='horizontal' padding='0,0,0,0' spacing='16'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " "<widget name='ThemeButton' " "type='Button' " "/> " @@ -993,31 +999,25 @@ "height='Globals.Line.Height' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " "<widget name='RendererPopupDesc' " -"width='80' " -"height='Globals.Line.Height' " -"textalign='right' " +"type='OptionsLabel' " "/> " "<widget name='RendererPopup' " "type='PopUp' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " "<widget name='AutosavePeriodPopupDesc' " -"width='80' " -"height='Globals.Line.Height' " -"textalign='right' " +"type='OptionsLabel' " "/> " "<widget name='AutosavePeriodPopup' " "type='PopUp' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " "<widget name='GuiLanguagePopupDesc' " -"width='80' " -"height='Globals.Line.Height' " -"textalign='right' " +"type='OptionsLabel' " "/> " "<widget name='GuiLanguagePopup' " "type='PopUp' " @@ -1052,10 +1052,10 @@ "</layout> " "</layout> " "</dialog> " -"<dialog name='GameOptions' overlays='screen' inset='16' shading='dim'> " +"<dialog name='GameOptions' overlays='Dialog.Launcher.GameList' shading='dim'> " "<layout type='vertical' padding='0,0,0,0' spacing='16'> " "<widget name='TabWidget'/> " -"<layout type='horizontal' padding='8,8,8,8'> " +"<layout type='horizontal' padding='16,16,16,4'> " "<space/> " "<widget name='Cancel' " "type='Button' " @@ -1067,7 +1067,7 @@ "</layout> " "</dialog> " "<dialog name='GameOptions_Graphics' overlays='Dialog.GlobalOptions.TabWidget'> " -"<layout type='vertical' padding='8,8,8,8' spacing='6'> " +"<layout type='vertical' padding='16,16,16,16' spacing='8'> " "<widget name='EnableTabCheckbox' " "type='Checkbox' " "/> " @@ -1075,7 +1075,7 @@ "</layout> " "</dialog> " "<dialog name='GameOptions_Audio' overlays='Dialog.GlobalOptions.TabWidget'> " -"<layout type='vertical' padding='8,8,8,8' spacing='6'> " +"<layout type='vertical' padding='16,16,16,16' spacing='8'> " "<widget name='EnableTabCheckbox' " "type='Checkbox' " "/> " @@ -1083,7 +1083,7 @@ "</layout> " "</dialog> " "<dialog name='GameOptions_MIDI' overlays='Dialog.GlobalOptions.TabWidget'> " -"<layout type='vertical' padding='8,8,8,8' spacing='6'> " +"<layout type='vertical' padding='16,16,16,16' spacing='8'> " "<widget name='EnableTabCheckbox' " "type='Checkbox' " "/> " @@ -1091,7 +1091,7 @@ "</layout> " "</dialog> " "<dialog name='GameOptions_MT32' overlays='Dialog.GlobalOptions.TabWidget'> " -"<layout type='vertical' padding='8,8,8,8' spacing='6'> " +"<layout type='vertical' padding='16,16,16,16' spacing='8'> " "<widget name='EnableTabCheckbox' " "type='Checkbox' " "/> " @@ -1099,7 +1099,7 @@ "</layout> " "</dialog> " "<dialog name='GameOptions_Volume' overlays='Dialog.GlobalOptions.TabWidget'> " -"<layout type='vertical' padding='8,8,8,8' spacing='6'> " +"<layout type='vertical' padding='16,16,16,16' spacing='8'> " "<widget name='EnableTabCheckbox' " "type='Checkbox' " "/> " @@ -1107,43 +1107,34 @@ "</layout> " "</dialog> " "<dialog name='GameOptions_Game' overlays='Dialog.GameOptions.TabWidget' shading='dim'> " -"<layout type='vertical' padding='8,8,8,8'> " -"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " +"<layout type='vertical' padding='16,16,16,16'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " "<widget name='Id' " -"width='35' " -"height='Globals.Line.Height' " -"textalign='right' " +"type='OptionsLabel' " "/> " "<widget name='Domain' " "type='PopUp' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " "<widget name='Name' " -"width='35' " -"height='Globals.Line.Height' " -"textalign='right' " +"type='OptionsLabel' " "/> " "<widget name='Desc' " "type='PopUp' " "/> " "</layout> " -"<space size='8'/> " -"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " "<widget name='LangPopupDesc' " -"width='60' " -"height='Globals.Line.Height' " -"textalign='right' " +"type='OptionsLabel' " "/> " "<widget name='LangPopup' " "type='PopUp' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " "<widget name='PlatformPopupDesc' " -"width='60' " -"height='Globals.Line.Height' " -"textalign='right' " +"type='OptionsLabel' " "/> " "<widget name='PlatformPopup' " "type='PopUp' " @@ -1152,8 +1143,8 @@ "</layout> " "</dialog> " "<dialog name='GameOptions_Paths' overlays='Dialog.GameOptions.TabWidget' shading='dim'> " -"<layout type='vertical' padding='8,8,8,8'> " -"<layout type='horizontal' padding='0,0,0,0' spacing='16' center='true'> " +"<layout type='vertical' padding='16,16,16,16'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " "<widget name='Savepath' " "type='Button' " "/> " @@ -1165,7 +1156,7 @@ "width='Globals.Line.Height' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='16' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " "<widget name='Extrapath' " "type='Button' " "/> " @@ -1177,7 +1168,7 @@ "width='Globals.Line.Height' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='16' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " "<widget name='Gamepath' " "type='Button' " "/> " @@ -1187,81 +1178,83 @@ "</layout> " "</layout> " "</dialog> " -"<dialog name = 'GameOptions_Engine' overlays = 'Dialog.GameOptions.TabWidget' shading = 'dim'> " -"<layout type = 'vertical' padding = '16, 16, 16, 16'> " -"<widget name = 'customOption1Checkbox' " -"type = 'Checkbox' " +"<dialog name='GameOptions_Engine' overlays='Dialog.GameOptions.TabWidget' shading='dim'> " +"<layout type='vertical' padding='16,16,16,16'> " +"<widget name='customOption1Checkbox' " +"type='Checkbox' " "/> " -"<widget name = 'customOption2Checkbox' " -"type = 'Checkbox' " +"<widget name='customOption2Checkbox' " +"type='Checkbox' " "/> " -"<widget name = 'customOption3Checkbox' " -"type = 'Checkbox' " +"<widget name='customOption3Checkbox' " +"type='Checkbox' " "/> " -"<widget name = 'customOption4Checkbox' " -"type = 'Checkbox' " +"<widget name='customOption4Checkbox' " +"type='Checkbox' " "/> " -"<widget name = 'customOption5Checkbox' " -"type = 'Checkbox' " +"<widget name='customOption5Checkbox' " +"type='Checkbox' " "/> " -"<widget name = 'customOption6Checkbox' " -"type = 'Checkbox' " +"<widget name='customOption6Checkbox' " +"type='Checkbox' " "/> " -"<widget name = 'customOption7Checkbox' " -"type = 'Checkbox' " +"<widget name='customOption7Checkbox' " +"type='Checkbox' " "/> " "</layout> " "</dialog> " "<dialog name='GlobalMenu' overlays='screen_center'> " -"<layout type='vertical' padding='2,2,4,6' center='true' spacing='6'> " +"<layout type='vertical' padding='16,16,16,16' center='true'> " "<widget name='Title' " -"width='160' " -"height='4' " +"width='210' " +"height='Globals.Line.Height' " "/> " "<widget name='Version' " -"width='160' " -"height='4' " +"width='210' " +"height='Globals.Line.Height' " "/> " -"<space size='1'/> " +"<widget name='Resume' " +"width='150' " +"height='Globals.Button.Height' " +"/> " +"<space size='10'/> " "<widget name='Load' " -"width='120' " -"height='12' " +"width='150' " +"height='Globals.Button.Height' " "/> " "<widget name='Save' " -"width='120' " -"height='12' " +"width='150' " +"height='Globals.Button.Height' " "/> " -"<space size='1'/> " +"<space size='10'/> " "<widget name='Options' " -"width='120' " -"height='12' " +"width='150' " +"height='Globals.Button.Height' " "/> " "<widget name='Help' " -"width='120' " -"height='12' " +"width='150' " +"height='Globals.Button.Height' " "/> " "<widget name='About' " -"width='120' " -"height='12' " -"/> " -"<space size='1'/> " -"<widget name='Resume' " -"width='120' " -"height='12' " +"width='150' " +"height='Globals.Button.Height' " "/> " +"<space size='10'/> " "<widget name='RTL' " -"width='120' " -"height='12' " +"width='150' " +"height='Globals.Button.Height' " "/> " "<widget name='Quit' " -"width='120' " -"height='12' " +"width='150' " +"height='Globals.Button.Height' " "/> " "</layout> " "</dialog> " "<dialog name='GlobalConfig' overlays='screen_center'> " "<layout type='vertical' padding='8,8,8,8'> " -"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " +"<layout type='horizontal' padding='0,0,0,0'> " +"<layout type='vertical' padding='0,0,0,0' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='8'> " "<widget name='vcMusicText' " "type='OptionsLabel' " "/> " @@ -1272,7 +1265,7 @@ "type='SmallLabel' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='8'> " "<widget name='vcSfxText' " "type='OptionsLabel' " "/> " @@ -1283,7 +1276,7 @@ "type='SmallLabel' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='8'> " "<widget name='vcSpeechText' " "type='OptionsLabel' " "/> " @@ -1294,34 +1287,33 @@ "type='SmallLabel' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " -"<space size='110' /> " +"</layout> " +"<layout type='vertical' padding='24,24,24,24' center='true'> " "<widget name='vcMuteCheckbox' " "type='Checkbox' " -"width='80' " +"width='80' " "/> " "</layout> " -"<layout type='vertical' padding='0,0,0,0' spacing='1' center='true'> " +"</layout> " +"<space size='8' /> " +"<layout type='horizontal' padding='0,0,0,0' spacing='10'> " "<widget name='subToggleDesc' " "type='OptionsLabel' " "/> " -"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " "<widget name='subToggleSpeechOnly' " "type='Radiobutton' " -"width='90' " +"width='100' " "/> " "<widget name='subToggleSubOnly' " "type='Radiobutton' " -"width='90' " +"width='100' " "/> " "<widget name='subToggleSubBoth' " "type='Radiobutton' " -"width='90' " +"width='100' " "/> " "</layout> " -"</layout> " -"<space size='2' /> " -"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='10'> " "<widget name='subSubtitleSpeedDesc' " "type='OptionsLabel' " "/> " @@ -1332,8 +1324,8 @@ "type='SmallLabel' " "/> " "</layout> " -"<space size='16'/> " -"<layout type='horizontal' padding='0,0,0,0' spacing='4'> " +"<space size='60'/> " +"<layout type='horizontal' padding='0,0,0,0' spacing='10'> " "<widget name='Keys' " "type='Button' " "/> " @@ -1348,15 +1340,23 @@ "</layout> " "</dialog> " "<dialog name='SaveLoadChooser' overlays='screen' inset='8' shading='dim'> " -"<layout type='vertical' padding='8,8,8,8' center='true'> " -"<widget name='Title' height='Globals.Line.Height'/> " +"<layout type='vertical' padding='8,8,8,32' center='true'> " +"<widget name='Title' " +"height='Globals.Line.Height' " +"/> " +"<layout type='horizontal' padding='0,0,0,16' spacing='16'> " "<widget name='List' /> " -"<layout type='horizontal' padding='0,0,16,0'> " +"<widget name='Thumbnail' " +"width='180' " +"height='200' " +"/> " +"</layout> " +"<layout type='horizontal' padding='0,0,0,0'> " "<space/> " "<widget name='Delete' " "type='Button' " "/> " -"<space size='16'/> " +"<space size='32'/> " "<widget name='Cancel' " "type='Button' " "/> " @@ -1366,16 +1366,16 @@ "</layout> " "</layout> " "</dialog> " -"<dialog name='ScummHelp' overlays='screen'> " -"<layout type='vertical' padding='8,8,8,8'> " +"<dialog name='ScummHelp' overlays='screen_center'> " +"<layout type='vertical' padding='8,8,8,8' center='true'> " "<widget name='Title' " -"width='180' " +"width='320' " "height='Globals.Line.Height' " "/> " "<widget name='HelpText' " -"height='140' " +"height='200' " "/> " -"<layout type='horizontal' padding='0,0,0,0'> " +"<layout type='horizontal' padding='0,0,16,0'> " "<widget name='Prev' " "type='Button' " "/> " @@ -1392,7 +1392,7 @@ "<dialog name='LoomTownsDifficultyDialog' overlays='screen_center'> " "<layout type='vertical' padding='8,8,8,8' center='true'> " "<widget name='Description1' " -"width='280' " +"width='320' " "height='Globals.Line.Height' " "/> " "<widget name='Description2' " @@ -1410,20 +1410,20 @@ "</layout> " "</dialog> " "<dialog name='MassAdd' overlays='screen_center' shading='dim'> " -"<layout type='vertical' padding='4,4,16,4' center='true'> " +"<layout type='vertical' padding='8,8,32,8' center='true'> " "<widget name='DirProgressText' " -"width='280' " +"width='480' " "height='Globals.Line.Height' " "/> " "<widget name='GameProgressText' " -"width='280' " +"width='480' " "height='Globals.Line.Height' " "/> " "<widget name='GameList' " -"width='280' " -"height='100' " +"width='480' " +"height='250' " "/> " -"<layout type='horizontal' padding='4,4,4,4'> " +"<layout type='horizontal' padding='8,8,8,8'> " "<widget name='Ok' " "type='Button' " "/> " @@ -1434,70 +1434,161 @@ "</layout> " "</dialog> " "<dialog name='KeyMapper' overlays='screen_center' shading='dim'> " -"<layout type='vertical' padding='8,8,8,8' spacing='10' center='true'> " +"<layout type='vertical' padding='8,8,32,8' spacing='10' center='true'> " "<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " "<widget name='PopupDesc' " "type='OptionsLabel' " "/> " "<widget name='Popup' " "type='PopUp' " -"width='150' " +"width='400' " "height='Globals.Line.Height' " "/> " "</layout> " "<widget name='KeymapArea' " -"width='300' " -"height='120' " +"width='600' " +"height='280' " "/> " "<widget name='Close' " "type='Button' " "/> " "</layout> " "</dialog> " +"<dialog name='Predictive' overlays='screen_center'> " +"<layout type='vertical' padding='5,5,5,5' center='true'> " +"<widget name='Headline' " +"height='Globals.Line.Height' " +"width='210' " +"textalign='center' " +"/> " +"<layout type='horizontal' padding='5,5,5,5'> " +"<widget name='Word' " +"width='190' " +"height='Globals.Button.Height' " +"/> " +"<widget name='Delete' " +"width='20' " +"height='Globals.Button.Height' " +"/> " +"</layout> " +"<space size='5' /> " +"<layout type='horizontal' padding='3,3,3,3'> " +"<widget name='Button1' " +"width='Globals.Predictive.Button.Width' " +"height='Globals.Button.Height' " +"/> " +"<widget name='Button2' " +"width='Globals.Predictive.Button.Width' " +"height='Globals.Button.Height' " +"/> " +"<widget name='Button3' " +"width='Globals.Predictive.Button.Width' " +"height='Globals.Button.Height' " +"/> " +"</layout> " +"<layout type='horizontal' padding='3,3,3,3'> " +"<widget name='Button4' " +"width='Globals.Predictive.Button.Width' " +"height='Globals.Button.Height' " +"/> " +"<widget name='Button5' " +"width='Globals.Predictive.Button.Width' " +"height='Globals.Button.Height' " +"/> " +"<widget name='Button6' " +"width='Globals.Predictive.Button.Width' " +"height='Globals.Button.Height' " +"/> " +"</layout> " +"<layout type='horizontal' padding='3,3,3,3'> " +"<widget name='Button7' " +"width='Globals.Predictive.Button.Width' " +"height='Globals.Button.Height' " +"/> " +"<widget name='Button8' " +"width='Globals.Predictive.Button.Width' " +"height='Globals.Button.Height' " +"/> " +"<widget name='Button9' " +"width='Globals.Predictive.Button.Width' " +"height='Globals.Button.Height' " +"/> " +"</layout> " +"<layout type='horizontal' padding='3,3,3,3'> " +"<widget name='Pre' " +"width='Globals.Predictive.Button.Width' " +"height='Globals.Button.Height' " +"/> " +"<widget name='Button0' " +"width='Globals.Predictive.Button.Width' " +"height='Globals.Button.Height' " +"/> " +"<widget name='Next' " +"width='Globals.Predictive.Button.Width' " +"height='Globals.Button.Height' " +"/> " +"</layout> " +"<space size='5' /> " +"<layout type='horizontal' padding='3,3,3,3'> " +"<widget name='Add' " +"width='Globals.Predictive.Button.Width' " +"height='Globals.Button.Height' " +"/> " +"<space size='22'/> " +"<widget name='Cancel' " +"width='Globals.Predictive.Button.Width' " +"height='Globals.Button.Height' " +"/> " +"<widget name='OK' " +"width='Globals.Predictive.Button.Width' " +"height='Globals.Button.Height' " +"/> " +"</layout> " +"</layout> " +"</dialog> " "</layout_info> " -"<layout_info resolution='y>399'> " +"<layout_info resolution='y<400'> " "<globals> " -"<def var='Line.Height' value='16' /> " -"<def var='Font.Height' value='16' /> " -"<def var='About.OuterBorder' value='80'/> " -"<def var='Layout.Spacing' value='8' /> " +"<def var='Line.Height' value='12' /> " +"<def var='Font.Height' value='10' /> " +"<def var='About.OuterBorder' value='10'/> " +"<def var='Layout.Spacing' value='8'/> " "<def var='ShowLauncherLogo' value='0'/> " "<def var='ShowGlobalMenuLogo' value='0'/> " "<def var='ShowSearchPic' value='0'/> " -"<def var='SaveLoadChooser.ExtInfo.Visible' value='1'/> " -"<def var='KeyMapper.Spacing' value='10'/> " -"<def var='KeyMapper.LabelWidth' value='100'/> " -"<def var='KeyMapper.ButtonWidth' value='80'/> " -"<def var='Tooltip.MaxWidth' value='200'/> " -"<def var='Tooltip.XDelta' value='16'/> " -"<def var='Tooltip.YDelta' value='16'/> " +"<def var='SaveLoadChooser.ExtInfo.Visible' value='0'/> " +"<def var='KeyMapper.Spacing' value='5'/> " +"<def var='KeyMapper.LabelWidth' value='80'/> " +"<def var='KeyMapper.ButtonWidth' value='60'/> " +"<def var='Tooltip.MaxWidth' value='70'/> " +"<def var='Tooltip.XDelta' value='8'/> " +"<def var='Tooltip.YDelta' value='8'/> " +"<def var='Predictive.Button.Width' value='45' /> " +"<def var='Predictive.Button.Height' value='15' /> " +"<widget name='Button' " +"size='72,16' " +"/> " +"<widget name='Slider' " +"size='85,12' " +"/> " "<widget name='OptionsLabel' " "size='110,Globals.Line.Height' " "textalign='right' " "/> " "<widget name='SmallLabel' " -"size='24,Globals.Line.Height' " -"/> " -"<widget name='ShortOptionsLabel' " -"size='60,Globals.Line.Height' " -"/> " -"<widget name='Button' " -"size='108,24' " -"/> " -"<widget name='Slider' " -"size='128,18' " +"size='18,Globals.Line.Height' " "/> " "<widget name='PopUp' " -"size='-1,19' " +"size='-1,15' " "/> " "<widget name='Checkbox' " -"size='-1,14' " +"size='-1,Globals.Line.Height' " "/> " "<widget name='Radiobutton' " "size='-1,Globals.Line.Height' " "/> " "<widget name='ListWidget' " -"padding='5,0,8,0' " +"padding='5,0,0,0' " "/> " "<widget name='PopUpWidget' " "padding='7,5,0,0' " @@ -1509,28 +1600,28 @@ "padding='7,5,5,5' " "/> " "<widget name='Scrollbar' " -"size='15,0' " +"size='9,0' " "/> " "<widget name='TabWidget.Tab' " -"size='75,27' " -"padding='0,0,8,0' " +"size='45,16' " +"padding='0,0,2,0' " "/> " "<widget name='TabWidget.Body' " -"padding='0,0,0,0' " +"padding='0,0,0,-8' " "/> " "<widget name='TabWidget.NavButton' " -"size='15,18' " -"padding='0,3,4,0' " +"size='32,18' " +"padding='0,0,1,0' " "/> " "</globals> " "<dialog name='Launcher' overlays='screen'> " -"<layout type='vertical' center='true' padding='16,16,8,8'> " +"<layout type='vertical' center='true' padding='6,6,2,2'> " "<widget name='Version' " "height='Globals.Line.Height' " "/> " -"<layout type='horizontal' spacing='5' padding='10,0,0,0'> " +"<layout type='horizontal' spacing='5' padding='0,0,0,0'> " "<widget name='SearchDesc' " -"width='60' " +"width='50' " "height='Globals.Line.Height' " "textalign='right' " "/> " @@ -1545,39 +1636,38 @@ "<space /> " "</layout> " "<widget name='GameList'/> " -"<layout type='horizontal' padding='0,0,0,0' spacing='10'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='8'> " "<widget name='LoadGameButton' " -"height='20' " +"height='12' " "/> " "<widget name='AddGameButton' " -"height='20' " +"height='12' " "/> " "<widget name='EditGameButton' " -"height='20' " +"height='12' " "/> " "<widget name='RemoveGameButton' " -"height='20' " +"height='12' " "/> " "</layout> " -"<space size='4'/> " -"<layout type='horizontal' padding='0,0,0,0' spacing='10'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='8'> " "<widget name='QuitButton' " -"height='20' " +"height='12' " "/> " "<widget name='AboutButton' " -"height='20' " +"height='12' " "/> " "<widget name='OptionsButton' " -"height='20' " +"height='12' " "/> " "<widget name='StartButton' " -"height='20' " +"height='12' " "/> " "</layout> " "</layout> " "</dialog> " -"<dialog name='Browser' overlays='Dialog.Launcher.GameList' shading='dim'> " -"<layout type='vertical' padding='8,8,8,8'> " +"<dialog name='Browser' overlays='screen' inset='8' shading='dim'> " +"<layout type='vertical' padding='8,8,0,4'> " "<widget name='Headline' " "height='Globals.Line.Height' " "/> " @@ -1585,7 +1675,7 @@ "height='Globals.Line.Height' " "/> " "<widget name='List'/> " -"<layout type='horizontal' padding='0,0,16,0'> " +"<layout type='horizontal' padding='0,0,8,0'> " "<widget name='Up' " "type='Button' " "/> " @@ -1599,10 +1689,10 @@ "</layout> " "</layout> " "</dialog> " -"<dialog name='GlobalOptions' overlays='Dialog.Launcher.GameList' shading='dim'> " +"<dialog name='GlobalOptions' overlays='screen' inset='16' shading='dim'> " "<layout type='vertical' padding='0,0,0,0'> " "<widget name='TabWidget'/> " -"<layout type='horizontal' padding='16,16,16,16'> " +"<layout type='horizontal' padding='8,8,8,8'> " "<space/> " "<widget name='Cancel' " "type='Button' " @@ -1615,7 +1705,7 @@ "</dialog> " "<dialog name='GlobalOptions_Graphics' overlays='Dialog.GlobalOptions.TabWidget'> " "<layout type='vertical' padding='16,16,16,16' spacing='8'> " -"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " "<widget name='grModePopupDesc' " "type='OptionsLabel' " "/> " @@ -1623,7 +1713,7 @@ "type='PopUp' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " "<widget name='grRenderPopupDesc' " "type='OptionsLabel' " "/> " @@ -1644,7 +1734,7 @@ "</dialog> " "<dialog name='GlobalOptions_Audio' overlays='Dialog.GlobalOptions.TabWidget'> " "<layout type='vertical' padding='16,16,16,16' spacing='8'> " -"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " "<widget name='auMidiPopupDesc' " "type='OptionsLabel' " "/> " @@ -1652,7 +1742,7 @@ "type='PopUp' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " "<widget name='auOPLPopupDesc' " "type='OptionsLabel' " "/> " @@ -1660,7 +1750,7 @@ "type='PopUp' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " "<widget name='auSampleRatePopupDesc' " "type='OptionsLabel' " "/> " @@ -1668,7 +1758,7 @@ "type='PopUp' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='10'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='3' center='true'> " "<widget name='subToggleDesc' " "type='OptionsLabel' " "/> " @@ -1682,7 +1772,7 @@ "type='Radiobutton' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='10'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " "<widget name='subSubtitleSpeedDesc' " "type='OptionsLabel' " "/> " @@ -1696,9 +1786,8 @@ "</layout> " "</dialog> " "<dialog name='GlobalOptions_Volume' overlays='Dialog.GlobalOptions.TabWidget'> " -"<layout type='horizontal' padding='16,16,16,16' spacing='8'> " -"<layout type='vertical' padding='0,0,0,0' spacing='8'> " -"<layout type='horizontal' padding='0,0,0,0'> " +"<layout type='vertical' padding='16,16,16,16' spacing='8'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " "<widget name='vcMusicText' " "type='OptionsLabel' " "/> " @@ -1709,7 +1798,7 @@ "type='SmallLabel' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " "<widget name='vcSfxText' " "type='OptionsLabel' " "/> " @@ -1720,7 +1809,7 @@ "type='SmallLabel' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " "<widget name='vcSpeechText' " "type='OptionsLabel' " "/> " @@ -1731,8 +1820,8 @@ "type='SmallLabel' " "/> " "</layout> " -"</layout> " -"<layout type='vertical' padding='24,0,24,0' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " +"<space size='110' /> " "<widget name='vcMuteCheckbox' " "type='Checkbox' " "/> " @@ -1741,7 +1830,7 @@ "</dialog> " "<dialog name='GlobalOptions_MIDI' overlays='Dialog.GlobalOptions.TabWidget'> " "<layout type='vertical' padding='16,16,16,16' spacing='8'> " -"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " "<widget name='auPrefGmPopupDesc' " "type='OptionsLabel' " "/> " @@ -1749,7 +1838,7 @@ "type='PopUp' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='16' center='true'> " "<widget name='mcFontButton' " "type='Button' " "/> " @@ -1764,7 +1853,7 @@ "<widget name='mcMixedCheckbox' " "type='Checkbox' " "/> " -"<layout type='horizontal' padding='0,0,0,0'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " "<widget name='mcMidiGainText' " "type='OptionsLabel' " "/> " @@ -1780,7 +1869,7 @@ "</dialog> " "<dialog name='GlobalOptions_MT32' overlays='Dialog.GlobalOptions.TabWidget'> " "<layout type='vertical' padding='16,16,16,16' spacing='8'> " -"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " "<widget name='auPrefMt32PopupDesc' " "type='OptionsLabel' " "/> " @@ -1798,7 +1887,7 @@ "</dialog> " "<dialog name='GlobalOptions_Paths' overlays='Dialog.GlobalOptions.TabWidget'> " "<layout type='vertical' padding='16,16,16,16' spacing='8'> " -"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='16'> " "<widget name='SaveButton' " "type='Button' " "/> " @@ -1810,7 +1899,7 @@ "width='Globals.Line.Height' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='16'> " "<widget name='ThemeButton' " "type='Button' " "/> " @@ -1822,7 +1911,7 @@ "width='Globals.Line.Height' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='16'> " "<widget name='ExtraButton' " "type='Button' " "/> " @@ -1846,7 +1935,7 @@ "</dialog> " "<dialog name='GlobalOptions_Misc' overlays='Dialog.GlobalOptions.TabWidget'> " "<layout type='vertical' padding='16,16,16,16' spacing='8'> " -"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='16'> " "<widget name='ThemeButton' " "type='Button' " "/> " @@ -1854,25 +1943,31 @@ "height='Globals.Line.Height' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " "<widget name='RendererPopupDesc' " -"type='OptionsLabel' " +"width='80' " +"height='Globals.Line.Height' " +"textalign='right' " "/> " "<widget name='RendererPopup' " "type='PopUp' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " "<widget name='AutosavePeriodPopupDesc' " -"type='OptionsLabel' " +"width='80' " +"height='Globals.Line.Height' " +"textalign='right' " "/> " "<widget name='AutosavePeriodPopup' " "type='PopUp' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " "<widget name='GuiLanguagePopupDesc' " -"type='OptionsLabel' " +"width='80' " +"height='Globals.Line.Height' " +"textalign='right' " "/> " "<widget name='GuiLanguagePopup' " "type='PopUp' " @@ -1907,10 +2002,10 @@ "</layout> " "</layout> " "</dialog> " -"<dialog name='GameOptions' overlays='Dialog.Launcher.GameList' shading='dim'> " +"<dialog name='GameOptions' overlays='screen' inset='16' shading='dim'> " "<layout type='vertical' padding='0,0,0,0' spacing='16'> " "<widget name='TabWidget'/> " -"<layout type='horizontal' padding='16,16,16,4'> " +"<layout type='horizontal' padding='8,8,8,8'> " "<space/> " "<widget name='Cancel' " "type='Button' " @@ -1922,7 +2017,7 @@ "</layout> " "</dialog> " "<dialog name='GameOptions_Graphics' overlays='Dialog.GlobalOptions.TabWidget'> " -"<layout type='vertical' padding='16,16,16,16' spacing='8'> " +"<layout type='vertical' padding='8,8,8,8' spacing='6'> " "<widget name='EnableTabCheckbox' " "type='Checkbox' " "/> " @@ -1930,7 +2025,7 @@ "</layout> " "</dialog> " "<dialog name='GameOptions_Audio' overlays='Dialog.GlobalOptions.TabWidget'> " -"<layout type='vertical' padding='16,16,16,16' spacing='8'> " +"<layout type='vertical' padding='8,8,8,8' spacing='6'> " "<widget name='EnableTabCheckbox' " "type='Checkbox' " "/> " @@ -1938,7 +2033,7 @@ "</layout> " "</dialog> " "<dialog name='GameOptions_MIDI' overlays='Dialog.GlobalOptions.TabWidget'> " -"<layout type='vertical' padding='16,16,16,16' spacing='8'> " +"<layout type='vertical' padding='8,8,8,8' spacing='6'> " "<widget name='EnableTabCheckbox' " "type='Checkbox' " "/> " @@ -1946,7 +2041,7 @@ "</layout> " "</dialog> " "<dialog name='GameOptions_MT32' overlays='Dialog.GlobalOptions.TabWidget'> " -"<layout type='vertical' padding='16,16,16,16' spacing='8'> " +"<layout type='vertical' padding='8,8,8,8' spacing='6'> " "<widget name='EnableTabCheckbox' " "type='Checkbox' " "/> " @@ -1954,7 +2049,7 @@ "</layout> " "</dialog> " "<dialog name='GameOptions_Volume' overlays='Dialog.GlobalOptions.TabWidget'> " -"<layout type='vertical' padding='16,16,16,16' spacing='8'> " +"<layout type='vertical' padding='8,8,8,8' spacing='6'> " "<widget name='EnableTabCheckbox' " "type='Checkbox' " "/> " @@ -1962,34 +2057,43 @@ "</layout> " "</dialog> " "<dialog name='GameOptions_Game' overlays='Dialog.GameOptions.TabWidget' shading='dim'> " -"<layout type='vertical' padding='16,16,16,16'> " -"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " +"<layout type='vertical' padding='8,8,8,8'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " "<widget name='Id' " -"type='OptionsLabel' " +"width='35' " +"height='Globals.Line.Height' " +"textalign='right' " "/> " "<widget name='Domain' " "type='PopUp' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " "<widget name='Name' " -"type='OptionsLabel' " +"width='35' " +"height='Globals.Line.Height' " +"textalign='right' " "/> " "<widget name='Desc' " "type='PopUp' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " +"<space size='8'/> " +"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " "<widget name='LangPopupDesc' " -"type='OptionsLabel' " +"width='60' " +"height='Globals.Line.Height' " +"textalign='right' " "/> " "<widget name='LangPopup' " "type='PopUp' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " "<widget name='PlatformPopupDesc' " -"type='OptionsLabel' " +"width='60' " +"height='Globals.Line.Height' " +"textalign='right' " "/> " "<widget name='PlatformPopup' " "type='PopUp' " @@ -1998,8 +2102,8 @@ "</layout> " "</dialog> " "<dialog name='GameOptions_Paths' overlays='Dialog.GameOptions.TabWidget' shading='dim'> " -"<layout type='vertical' padding='16,16,16,16'> " -"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " +"<layout type='vertical' padding='8,8,8,8'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='16' center='true'> " "<widget name='Savepath' " "type='Button' " "/> " @@ -2011,7 +2115,7 @@ "width='Globals.Line.Height' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='16' center='true'> " "<widget name='Extrapath' " "type='Button' " "/> " @@ -2023,7 +2127,7 @@ "width='Globals.Line.Height' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='16' center='true'> " "<widget name='Gamepath' " "type='Button' " "/> " @@ -2033,58 +2137,81 @@ "</layout> " "</layout> " "</dialog> " +"<dialog name='GameOptions_Engine' overlays='Dialog.GameOptions.TabWidget' shading='dim'> " +"<layout type='vertical' padding='8,8,8,8'> " +"<widget name='customOption1Checkbox' " +"type='Checkbox' " +"/> " +"<widget name='customOption2Checkbox' " +"type='Checkbox' " +"/> " +"<widget name='customOption3Checkbox' " +"type='Checkbox' " +"/> " +"<widget name='customOption4Checkbox' " +"type='Checkbox' " +"/> " +"<widget name='customOption5Checkbox' " +"type='Checkbox' " +"/> " +"<widget name='customOption6Checkbox' " +"type='Checkbox' " +"/> " +"<widget name='customOption7Checkbox' " +"type='Checkbox' " +"/> " +"</layout> " +"</dialog> " "<dialog name='GlobalMenu' overlays='screen_center'> " -"<layout type='vertical' padding='16,16,16,16' center='true'> " +"<layout type='vertical' padding='2,2,4,6' center='true' spacing='6'> " "<widget name='Title' " -"width='210' " -"height='Globals.Line.Height' " +"width='160' " +"height='4' " "/> " "<widget name='Version' " -"width='210' " -"height='Globals.Line.Height' " -"/> " -"<widget name='Resume' " -"width='150' " -"height='Globals.Button.Height' " +"width='160' " +"height='4' " "/> " -"<space size='10'/> " +"<space size='1'/> " "<widget name='Load' " -"width='150' " -"height='Globals.Button.Height' " +"width='120' " +"height='12' " "/> " "<widget name='Save' " -"width='150' " -"height='Globals.Button.Height' " +"width='120' " +"height='12' " "/> " -"<space size='10'/> " +"<space size='1'/> " "<widget name='Options' " -"width='150' " -"height='Globals.Button.Height' " +"width='120' " +"height='12' " "/> " "<widget name='Help' " -"width='150' " -"height='Globals.Button.Height' " +"width='120' " +"height='12' " "/> " "<widget name='About' " -"width='150' " -"height='Globals.Button.Height' " +"width='120' " +"height='12' " +"/> " +"<space size='1'/> " +"<widget name='Resume' " +"width='120' " +"height='12' " "/> " -"<space size='10'/> " "<widget name='RTL' " -"width='150' " -"height='Globals.Button.Height' " +"width='120' " +"height='12' " "/> " "<widget name='Quit' " -"width='150' " -"height='Globals.Button.Height' " +"width='120' " +"height='12' " "/> " "</layout> " "</dialog> " "<dialog name='GlobalConfig' overlays='screen_center'> " "<layout type='vertical' padding='8,8,8,8'> " -"<layout type='horizontal' padding='0,0,0,0'> " -"<layout type='vertical' padding='0,0,0,0' center='true'> " -"<layout type='horizontal' padding='0,0,0,0' spacing='8'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " "<widget name='vcMusicText' " "type='OptionsLabel' " "/> " @@ -2095,7 +2222,7 @@ "type='SmallLabel' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='8'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " "<widget name='vcSfxText' " "type='OptionsLabel' " "/> " @@ -2106,7 +2233,7 @@ "type='SmallLabel' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='8'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " "<widget name='vcSpeechText' " "type='OptionsLabel' " "/> " @@ -2117,33 +2244,34 @@ "type='SmallLabel' " "/> " "</layout> " -"</layout> " -"<layout type='vertical' padding='24,24,24,24' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " +"<space size='110' /> " "<widget name='vcMuteCheckbox' " "type='Checkbox' " -"width='80' " +"width='80' " "/> " "</layout> " -"</layout> " -"<space size='8' /> " -"<layout type='horizontal' padding='0,0,0,0' spacing='10'> " +"<layout type='vertical' padding='0,0,0,0' spacing='1' center='true'> " "<widget name='subToggleDesc' " "type='OptionsLabel' " "/> " +"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " "<widget name='subToggleSpeechOnly' " "type='Radiobutton' " -"width='100' " +"width='90' " "/> " "<widget name='subToggleSubOnly' " "type='Radiobutton' " -"width='100' " +"width='90' " "/> " "<widget name='subToggleSubBoth' " "type='Radiobutton' " -"width='100' " +"width='90' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='10'> " +"</layout> " +"<space size='2' /> " +"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " "<widget name='subSubtitleSpeedDesc' " "type='OptionsLabel' " "/> " @@ -2154,8 +2282,8 @@ "type='SmallLabel' " "/> " "</layout> " -"<space size='60'/> " -"<layout type='horizontal' padding='0,0,0,0' spacing='10'> " +"<space size='16'/> " +"<layout type='horizontal' padding='0,0,0,0' spacing='4'> " "<widget name='Keys' " "type='Button' " "/> " @@ -2170,23 +2298,15 @@ "</layout> " "</dialog> " "<dialog name='SaveLoadChooser' overlays='screen' inset='8' shading='dim'> " -"<layout type='vertical' padding='8,8,8,32' center='true'> " -"<widget name='Title' " -"height='Globals.Line.Height' " -"/> " -"<layout type='horizontal' padding='0,0,0,16' spacing='16'> " +"<layout type='vertical' padding='8,8,8,8' center='true'> " +"<widget name='Title' height='Globals.Line.Height'/> " "<widget name='List' /> " -"<widget name='Thumbnail' " -"width='180' " -"height='200' " -"/> " -"</layout> " -"<layout type='horizontal' padding='0,0,0,0'> " +"<layout type='horizontal' padding='0,0,16,0'> " "<space/> " "<widget name='Delete' " "type='Button' " "/> " -"<space size='32'/> " +"<space size='16'/> " "<widget name='Cancel' " "type='Button' " "/> " @@ -2196,16 +2316,16 @@ "</layout> " "</layout> " "</dialog> " -"<dialog name='ScummHelp' overlays='screen_center'> " -"<layout type='vertical' padding='8,8,8,8' center='true'> " +"<dialog name='ScummHelp' overlays='screen'> " +"<layout type='vertical' padding='8,8,8,8'> " "<widget name='Title' " -"width='320' " +"width='180' " "height='Globals.Line.Height' " "/> " "<widget name='HelpText' " -"height='200' " +"height='140' " "/> " -"<layout type='horizontal' padding='0,0,16,0'> " +"<layout type='horizontal' padding='0,0,0,0'> " "<widget name='Prev' " "type='Button' " "/> " @@ -2222,7 +2342,7 @@ "<dialog name='LoomTownsDifficultyDialog' overlays='screen_center'> " "<layout type='vertical' padding='8,8,8,8' center='true'> " "<widget name='Description1' " -"width='320' " +"width='280' " "height='Globals.Line.Height' " "/> " "<widget name='Description2' " @@ -2240,20 +2360,20 @@ "</layout> " "</dialog> " "<dialog name='MassAdd' overlays='screen_center' shading='dim'> " -"<layout type='vertical' padding='8,8,32,8' center='true'> " +"<layout type='vertical' padding='4,4,16,4' center='true'> " "<widget name='DirProgressText' " -"width='480' " +"width='280' " "height='Globals.Line.Height' " "/> " "<widget name='GameProgressText' " -"width='480' " +"width='280' " "height='Globals.Line.Height' " "/> " "<widget name='GameList' " -"width='480' " -"height='250' " +"width='280' " +"height='100' " "/> " -"<layout type='horizontal' padding='8,8,8,8'> " +"<layout type='horizontal' padding='4,4,4,4'> " "<widget name='Ok' " "type='Button' " "/> " @@ -2264,24 +2384,114 @@ "</layout> " "</dialog> " "<dialog name='KeyMapper' overlays='screen_center' shading='dim'> " -"<layout type='vertical' padding='8,8,32,8' spacing='10' center='true'> " +"<layout type='vertical' padding='8,8,8,8' spacing='10' center='true'> " "<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " "<widget name='PopupDesc' " "type='OptionsLabel' " "/> " "<widget name='Popup' " "type='PopUp' " -"width='400' " +"width='150' " "height='Globals.Line.Height' " "/> " "</layout> " "<widget name='KeymapArea' " -"width='600' " -"height='280' " +"width='300' " +"height='120' " "/> " "<widget name='Close' " "type='Button' " "/> " "</layout> " "</dialog> " +"<dialog name='Predictive' overlays='screen_center'> " +"<layout type='vertical' padding='1,1,1,1' center='true'> " +"<widget name='Headline' " +"height='Globals.Line.Height' " +"width='150' " +"textalign='center' " +"/> " +"<layout type='horizontal' padding='3,3,3,3'> " +"<widget name='Word' " +"width='120' " +"height='Globals.Button.Height' " +"/> " +"<widget name='Delete' " +"width='20' " +"height='Globals.Predictive.Button.Height' " +"/> " +"</layout> " +"<layout type='horizontal' padding='3,3,3,3'> " +"<widget name='Button1' " +"width='Globals.Predictive.Button.Width' " +"height='Globals.Predictive.Button.Height' " +"/> " +"<widget name='Button2' " +"width='Globals.Predictive.Button.Width' " +"height='Globals.Predictive.Button.Height' " +"/> " +"<widget name='Button3' " +"width='Globals.Predictive.Button.Width' " +"height='Globals.Predictive.Button.Height' " +"/> " +"</layout> " +"<layout type='horizontal' padding='3,3,3,3'> " +"<widget name='Button4' " +"width='Globals.Predictive.Button.Width' " +"height='Globals.Predictive.Button.Height' " +"/> " +"<widget name='Button5' " +"width='Globals.Predictive.Button.Width' " +"height='Globals.Predictive.Button.Height' " +"/> " +"<widget name='Button6' " +"width='Globals.Predictive.Button.Width' " +"height='Globals.Predictive.Button.Height' " +"/> " +"</layout> " +"<layout type='horizontal' padding='3,3,3,3'> " +"<widget name='Button7' " +"width='Globals.Predictive.Button.Width' " +"height='Globals.Predictive.Button.Height' " +"/> " +"<widget name='Button8' " +"width='Globals.Predictive.Button.Width' " +"height='Globals.Predictive.Button.Height' " +"/> " +"<widget name='Button9' " +"width='Globals.Predictive.Button.Width' " +"height='Globals.Predictive.Button.Height' " +"/> " +"</layout> " +"<layout type='horizontal' padding='3,3,3,0'> " +"<widget name='Pre' " +"width='Globals.Predictive.Button.Width' " +"height='Globals.Predictive.Button.Height' " +"/> " +"<widget name='Button0' " +"width='Globals.Predictive.Button.Width' " +"height='Globals.Predictive.Button.Height' " +"/> " +"<widget name='Next' " +"width='Globals.Predictive.Button.Width' " +"height='Globals.Predictive.Button.Height' " +"/> " +"</layout> " +"<space size='3' /> " +"<layout type='horizontal' padding='3,3,0,3'> " +"<widget name='Add' " +"width='Globals.Predictive.Button.Width' " +"height='Globals.Predictive.Button.Height' " +"/> " +"<widget name='Cancel' " +"width='Globals.Predictive.Button.Width' " +"height='Globals.Predictive.Button.Height' " +"/> " +"<widget name='OK' " +"width='Globals.Predictive.Button.Width' " +"height='Globals.Predictive.Button.Height' " +"/> " +"</layout> " +"</layout> " +"</dialog> " "</layout_info> " diff --git a/gui/themes/scummclassic.zip b/gui/themes/scummclassic.zip Binary files differindex 9f7e4b5e0e..f60f3cb29e 100644 --- a/gui/themes/scummclassic.zip +++ b/gui/themes/scummclassic.zip diff --git a/gui/themes/scummclassic/THEMERC b/gui/themes/scummclassic/THEMERC index fb8177f329..68bdfde6fd 100644 --- a/gui/themes/scummclassic/THEMERC +++ b/gui/themes/scummclassic/THEMERC @@ -1 +1 @@ -[SCUMMVM_STX0.8.9:ScummVM Classic Theme:No Author] +[SCUMMVM_STX0.8.10:ScummVM Classic Theme:No Author] diff --git a/gui/themes/scummclassic/classic_layout.stx b/gui/themes/scummclassic/classic_layout.stx index bdccea418b..0d8fe3150d 100644 --- a/gui/themes/scummclassic/classic_layout.stx +++ b/gui/themes/scummclassic/classic_layout.stx @@ -42,6 +42,8 @@ <def var = 'Tooltip.XDelta' value = '16'/> <!-- basically cursor size --> <def var = 'Tooltip.YDelta' value = '16'/> + <def var = 'Predictive.Button.Width' value = '60' /> + <widget name = 'OptionsLabel' size = '110, Globals.Line.Height' textalign = 'right' @@ -911,4 +913,98 @@ /> </layout> </dialog> + + <dialog name = 'Predictive' overlays = 'screen_center'> + <layout type = 'vertical' padding = '5, 5, 5, 5' center = 'true'> + <widget name = 'Headline' + height = 'Globals.Line.Height' + width = '210' + textalign = 'center' + /> + + <layout type = 'horizontal' padding = '5, 5, 5, 5'> + <widget name = 'Word' + width = '190' + height = 'Globals.Button.Height' + /> + <widget name = 'Delete' + width = '20' + height = 'Globals.Button.Height' + /> + </layout> + <space size = '5' /> + <layout type = 'horizontal' padding = '3, 3, 3, 3'> + <widget name = 'Button1' + width = 'Globals.Predictive.Button.Width' + height = 'Globals.Button.Height' + /> + <widget name = 'Button2' + width = 'Globals.Predictive.Button.Width' + height = 'Globals.Button.Height' + /> + <widget name = 'Button3' + width = 'Globals.Predictive.Button.Width' + height = 'Globals.Button.Height' + /> + </layout> + <layout type = 'horizontal' padding = '3, 3, 3, 3'> + <widget name = 'Button4' + width = 'Globals.Predictive.Button.Width' + height = 'Globals.Button.Height' + /> + <widget name = 'Button5' + width = 'Globals.Predictive.Button.Width' + height = 'Globals.Button.Height' + /> + <widget name = 'Button6' + width = 'Globals.Predictive.Button.Width' + height = 'Globals.Button.Height' + /> + </layout> + <layout type = 'horizontal' padding = '3, 3, 3, 3'> + <widget name = 'Button7' + width = 'Globals.Predictive.Button.Width' + height = 'Globals.Button.Height' + /> + <widget name = 'Button8' + width = 'Globals.Predictive.Button.Width' + height = 'Globals.Button.Height' + /> + <widget name = 'Button9' + width = 'Globals.Predictive.Button.Width' + height = 'Globals.Button.Height' + /> + </layout> + <layout type = 'horizontal' padding = '3, 3, 3, 3'> + <widget name = 'Pre' + width = 'Globals.Predictive.Button.Width' + height = 'Globals.Button.Height' + /> + <widget name = 'Button0' + width = 'Globals.Predictive.Button.Width' + height = 'Globals.Button.Height' + /> + <widget name = 'Next' + width = 'Globals.Predictive.Button.Width' + height = 'Globals.Button.Height' + /> + </layout> + <space size = '5' /> + <layout type = 'horizontal' padding = '3, 3, 3, 3'> + <widget name = 'Add' + width = 'Globals.Predictive.Button.Width' + height = 'Globals.Button.Height' + /> + <space size = '22'/> + <widget name = 'Cancel' + width = 'Globals.Predictive.Button.Width' + height = 'Globals.Button.Height' + /> + <widget name = 'OK' + width = 'Globals.Predictive.Button.Width' + height = 'Globals.Button.Height' + /> + </layout> + </layout> + </dialog> </layout_info> diff --git a/gui/themes/scummclassic/classic_layout_lowres.stx b/gui/themes/scummclassic/classic_layout_lowres.stx index 87246023c4..4dc04f2705 100644 --- a/gui/themes/scummclassic/classic_layout_lowres.stx +++ b/gui/themes/scummclassic/classic_layout_lowres.stx @@ -43,6 +43,9 @@ <def var = 'Tooltip.XDelta' value = '8'/> <!-- basically cursor size --> <def var = 'Tooltip.YDelta' value = '8'/> + <def var = 'Predictive.Button.Width' value = '45' /> + <def var = 'Predictive.Button.Height' value = '15' /> + <widget name = 'Button' size = '72, 16' /> @@ -913,4 +916,97 @@ /> </layout> </dialog> + + <dialog name = 'Predictive' overlays = 'screen_center'> + <layout type = 'vertical' padding = '1, 1, 1, 1' center = 'true'> + <widget name = 'Headline' + height = 'Globals.Line.Height' + width = '150' + textalign = 'center' + /> + <layout type = 'horizontal' padding = '3, 3, 3, 3'> + <widget name = 'Word' + width = '120' + height = 'Globals.Button.Height' + /> + <widget name = 'Delete' + width = '20' + height = 'Globals.Predictive.Button.Height' + /> + </layout> + <!-- <space size = '3' /> --> + <layout type = 'horizontal' padding = '3, 3, 3, 3'> + <widget name = 'Button1' + width = 'Globals.Predictive.Button.Width' + height = 'Globals.Predictive.Button.Height' + /> + <widget name = 'Button2' + width = 'Globals.Predictive.Button.Width' + height = 'Globals.Predictive.Button.Height' + /> + <widget name = 'Button3' + width = 'Globals.Predictive.Button.Width' + height = 'Globals.Predictive.Button.Height' + /> + </layout> + <layout type = 'horizontal' padding = '3, 3, 3, 3'> + <widget name = 'Button4' + width = 'Globals.Predictive.Button.Width' + height = 'Globals.Predictive.Button.Height' + /> + <widget name = 'Button5' + width = 'Globals.Predictive.Button.Width' + height = 'Globals.Predictive.Button.Height' + /> + <widget name = 'Button6' + width = 'Globals.Predictive.Button.Width' + height = 'Globals.Predictive.Button.Height' + /> + </layout> + <layout type = 'horizontal' padding = '3, 3, 3, 3'> + <widget name = 'Button7' + width = 'Globals.Predictive.Button.Width' + height = 'Globals.Predictive.Button.Height' + /> + <widget name = 'Button8' + width = 'Globals.Predictive.Button.Width' + height = 'Globals.Predictive.Button.Height' + /> + <widget name = 'Button9' + width = 'Globals.Predictive.Button.Width' + height = 'Globals.Predictive.Button.Height' + /> + </layout> + <layout type = 'horizontal' padding = '3, 3, 3, 0'> + <widget name = 'Pre' + width = 'Globals.Predictive.Button.Width' + height = 'Globals.Predictive.Button.Height' + /> + <widget name = 'Button0' + width = 'Globals.Predictive.Button.Width' + height = 'Globals.Predictive.Button.Height' + /> + <widget name = 'Next' + width = 'Globals.Predictive.Button.Width' + height = 'Globals.Predictive.Button.Height' + /> + </layout> + <space size = '3' /> + <layout type = 'horizontal' padding = '3, 3, 0, 3'> + <widget name = 'Add' + width = 'Globals.Predictive.Button.Width' + height = 'Globals.Predictive.Button.Height' + /> + <!-- <space size = '22'/> --> + <widget name = 'Cancel' + width = 'Globals.Predictive.Button.Width' + height = 'Globals.Predictive.Button.Height' + /> + <widget name = 'OK' + width = 'Globals.Predictive.Button.Width' + height = 'Globals.Predictive.Button.Height' + /> + </layout> + </layout> + </dialog> </layout_info> diff --git a/gui/themes/scummmodern.zip b/gui/themes/scummmodern.zip Binary files differindex 56dc162a0a..803a9336c4 100644 --- a/gui/themes/scummmodern.zip +++ b/gui/themes/scummmodern.zip diff --git a/gui/themes/scummmodern/THEMERC b/gui/themes/scummmodern/THEMERC index 628ab67f42..734138998a 100644 --- a/gui/themes/scummmodern/THEMERC +++ b/gui/themes/scummmodern/THEMERC @@ -1 +1 @@ -[SCUMMVM_STX0.8.9:ScummVM Modern Theme:No Author] +[SCUMMVM_STX0.8.10:ScummVM Modern Theme:No Author] diff --git a/gui/themes/scummmodern/delbtn.bmp b/gui/themes/scummmodern/delbtn.bmp Binary files differnew file mode 100644 index 0000000000..aeb3b7f5f5 --- /dev/null +++ b/gui/themes/scummmodern/delbtn.bmp diff --git a/gui/themes/scummmodern/scummmodern_gfx.stx b/gui/themes/scummmodern/scummmodern_gfx.stx index 5f7cc69acd..6c2e4bb873 100644 --- a/gui/themes/scummmodern/scummmodern_gfx.stx +++ b/gui/themes/scummmodern/scummmodern_gfx.stx @@ -100,6 +100,7 @@ <bitmap filename = 'logo_small.bmp'/> <bitmap filename = 'search.bmp'/> <bitmap filename = 'eraser.bmp'/> + <bitmap filename = 'delbtn.bmp'/> </bitmaps> <fonts> diff --git a/gui/themes/scummmodern/scummmodern_layout.stx b/gui/themes/scummmodern/scummmodern_layout.stx index 6acccebccc..676de964e2 100644 --- a/gui/themes/scummmodern/scummmodern_layout.stx +++ b/gui/themes/scummmodern/scummmodern_layout.stx @@ -49,6 +49,8 @@ <def var = 'Tooltip.XDelta' value = '16'/> <!-- basically cursor size --> <def var = 'Tooltip.YDelta' value = '32'/> + <def var = 'Predictive.Button.Width' value = '60' /> + <widget name = 'OptionsLabel' size = '115, Globals.Line.Height' textalign = 'right' @@ -59,8 +61,7 @@ <widget name = 'Button' size = '108, 24' - /> - + /> <widget name = 'Slider' size = '128, 18' @@ -925,5 +926,99 @@ type = 'Button' /> </layout> + </dialog> + <dialog name = 'Predictive' overlays = 'screen_center'> + <layout type = 'vertical' padding = '5, 5, 5, 5' center = 'true'> + <widget name = 'Headline' + height = 'Globals.Line.Height' + width = '210' + textalign = 'center' + /> + + <layout type = 'horizontal' padding = '5, 5, 5, 5'> + <widget name = 'Word' + width = '190' + height = 'Globals.Button.Height' + /> + <widget name = 'Delete' + width = '20' + height = 'Globals.Button.Height' + /> + </layout> + <space size = '5' /> + <layout type = 'horizontal' padding = '3, 3, 3, 3'> + <widget name = 'Button1' + width = 'Globals.Predictive.Button.Width' + height = 'Globals.Button.Height' + /> + <widget name = 'Button2' + width = 'Globals.Predictive.Button.Width' + height = 'Globals.Button.Height' + /> + <widget name = 'Button3' + width = 'Globals.Predictive.Button.Width' + height = 'Globals.Button.Height' + /> + </layout> + <layout type = 'horizontal' padding = '3, 3, 3, 3'> + <widget name = 'Button4' + width = 'Globals.Predictive.Button.Width' + height = 'Globals.Button.Height' + /> + <widget name = 'Button5' + width = 'Globals.Predictive.Button.Width' + height = 'Globals.Button.Height' + /> + <widget name = 'Button6' + width = 'Globals.Predictive.Button.Width' + height = 'Globals.Button.Height' + /> + </layout> + <layout type = 'horizontal' padding = '3, 3, 3, 3'> + <widget name = 'Button7' + width = 'Globals.Predictive.Button.Width' + height = 'Globals.Button.Height' + /> + <widget name = 'Button8' + width = 'Globals.Predictive.Button.Width' + height = 'Globals.Button.Height' + /> + <widget name = 'Button9' + width = 'Globals.Predictive.Button.Width' + height = 'Globals.Button.Height' + /> + </layout> + <layout type = 'horizontal' padding = '3, 3, 3, 3'> + <widget name = 'Pre' + width = 'Globals.Predictive.Button.Width' + height = 'Globals.Button.Height' + /> + <widget name = 'Button0' + width = 'Globals.Predictive.Button.Width' + height = 'Globals.Button.Height' + /> + <widget name = 'Next' + width = 'Globals.Predictive.Button.Width' + height = 'Globals.Button.Height' + /> + </layout> + <space size = '5' /> + <layout type = 'horizontal' padding = '3, 3, 3, 3'> + <widget name = 'Add' + width = 'Globals.Predictive.Button.Width' + height = 'Globals.Button.Height' + /> + <space size = '22'/> + <widget name = 'Cancel' + width = 'Globals.Predictive.Button.Width' + height = 'Globals.Button.Height' + /> + <widget name = 'OK' + width = 'Globals.Predictive.Button.Width' + height = 'Globals.Button.Height' + /> + </layout> + </layout> </dialog> + </layout_info> diff --git a/gui/themes/scummmodern/scummmodern_layout_lowres.stx b/gui/themes/scummmodern/scummmodern_layout_lowres.stx index 49aad1070a..00ff440d44 100644 --- a/gui/themes/scummmodern/scummmodern_layout_lowres.stx +++ b/gui/themes/scummmodern/scummmodern_layout_lowres.stx @@ -33,6 +33,9 @@ <def var = 'SaveLoadChooser.ExtInfo.Visible' value = '0'/> + <def var = 'Predictive.Button.Width' value = '45' /> + <def var = 'Predictive.Button.Height' value = '15' /> + <widget name = 'Button' size = '72, 16' /> @@ -911,4 +914,96 @@ /> </layout> </dialog> + <dialog name = 'Predictive' overlays = 'screen_center'> + <layout type = 'vertical' center = 'true'> + <widget name = 'Headline' + height = 'Globals.Line.Height' + width = '150' + textalign = 'center' + /> + <layout type = 'horizontal' padding = '0, 0, 2, 2'> + <widget name = 'Word' + width = '120' + height = 'Globals.Button.Height' + /> + <widget name = 'Delete' + width = '20' + height = 'Globals.Predictive.Button.Height' + /> + </layout> + <!-- <space size = '3' /> --> + <layout type = 'horizontal' padding = '0, 0, 2, 2'> + <widget name = 'Button1' + width = 'Globals.Predictive.Button.Width' + height = 'Globals.Predictive.Button.Height' + /> + <widget name = 'Button2' + width = 'Globals.Predictive.Button.Width' + height = 'Globals.Predictive.Button.Height' + /> + <widget name = 'Button3' + width = 'Globals.Predictive.Button.Width' + height = 'Globals.Predictive.Button.Height' + /> + </layout> + <layout type = 'horizontal' padding = '0, 0, 2, 2'> + <widget name = 'Button4' + width = 'Globals.Predictive.Button.Width' + height = 'Globals.Predictive.Button.Height' + /> + <widget name = 'Button5' + width = 'Globals.Predictive.Button.Width' + height = 'Globals.Predictive.Button.Height' + /> + <widget name = 'Button6' + width = 'Globals.Predictive.Button.Width' + height = 'Globals.Predictive.Button.Height' + /> + </layout> + <layout type = 'horizontal' padding = '0, 0, 2, 2'> + <widget name = 'Button7' + width = 'Globals.Predictive.Button.Width' + height = 'Globals.Predictive.Button.Height' + /> + <widget name = 'Button8' + width = 'Globals.Predictive.Button.Width' + height = 'Globals.Predictive.Button.Height' + /> + <widget name = 'Button9' + width = 'Globals.Predictive.Button.Width' + height = 'Globals.Predictive.Button.Height' + /> + </layout> + <layout type = 'horizontal' padding = '0, 0, 2, 2'> + <widget name = 'Pre' + width = 'Globals.Predictive.Button.Width' + height = 'Globals.Predictive.Button.Height' + /> + <widget name = 'Button0' + width = 'Globals.Predictive.Button.Width' + height = 'Globals.Predictive.Button.Height' + /> + <widget name = 'Next' + width = 'Globals.Predictive.Button.Width' + height = 'Globals.Predictive.Button.Height' + /> + </layout> + <space size = '2' /> + <layout type = 'horizontal' padding = '0, 0, 2, 2'> + <widget name = 'Add' + width = 'Globals.Predictive.Button.Width' + height = 'Globals.Predictive.Button.Height' + /> + <!-- <space size = '22'/> --> + <widget name = 'Cancel' + width = 'Globals.Predictive.Button.Width' + height = 'Globals.Predictive.Button.Height' + /> + <widget name = 'OK' + width = 'Globals.Predictive.Button.Width' + height = 'Globals.Predictive.Button.Height' + /> + </layout> + </layout> + </dialog> </layout_info> diff --git a/gui/widgets/editable.h b/gui/widgets/editable.h index 4b51ac9145..7e453c1204 100644 --- a/gui/widgets/editable.h +++ b/gui/widgets/editable.h @@ -70,18 +70,17 @@ public: virtual void handleTickle(); virtual bool handleKeyDown(Common::KeyState state); - virtual void reflowLayout(); + bool setCaretPos(int newPos); + protected: virtual void startEditMode() = 0; virtual void endEditMode() = 0; - virtual void abortEditMode() = 0; - + virtual void abortEditMode() = 0; virtual Common::Rect getEditRect() const = 0; virtual int getCaretOffset() const; - void drawCaret(bool erase); - bool setCaretPos(int newPos); + void drawCaret(bool erase); bool adjustOffset(); void makeCaretVisible(); |