[Scummvm-git-logs] scummvm master -> 02d47a1d45e5f92e914416c5b77b294429ca704d
antoniou79
a.antoniou79 at gmail.com
Wed Jun 10 09:44:19 UTC 2020
This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
02d47a1d45 BLADERUNNER: Scrollable dropdown control for KIA (WIP)
Commit: 02d47a1d45e5f92e914416c5b77b294429ca704d
https://github.com/scummvm/scummvm/commit/02d47a1d45e5f92e914416c5b77b294429ca704d
Author: Thanasis Antoniou (a.antoniou79 at gmail.com)
Date: 2020-06-10T12:33:05+03:00
Commit Message:
BLADERUNNER: Scrollable dropdown control for KIA (WIP)
Current purpose is for text language selection
Drop down list for language selection in KIA (early stage)
Changed paths:
A engines/bladerunner/ui/ui_dropdown.cpp
A engines/bladerunner/ui/ui_dropdown.h
engines/bladerunner/bladerunner.h
engines/bladerunner/module.mk
engines/bladerunner/subtitles.h
engines/bladerunner/ui/kia_section_settings.cpp
engines/bladerunner/ui/kia_section_settings.h
engines/bladerunner/ui/ui_container.cpp
engines/bladerunner/ui/ui_container.h
engines/bladerunner/ui/ui_image_picker.cpp
engines/bladerunner/ui/ui_image_picker.h
engines/bladerunner/ui/ui_scroll_box.cpp
engines/bladerunner/ui/ui_scroll_box.h
engines/bladerunner/ui/ui_slider.cpp
diff --git a/engines/bladerunner/bladerunner.h b/engines/bladerunner/bladerunner.h
index d70b8e1a6b..8631d4e920 100644
--- a/engines/bladerunner/bladerunner.h
+++ b/engines/bladerunner/bladerunner.h
@@ -110,6 +110,7 @@ public:
static const int kArchiveCount = 12; // +2 to original value (10) to accommodate for SUBTITLES.MIX and one extra resource file, to allow for capability of loading all VQAx.MIX and the MODE.MIX file (debug purposes)
static const int kActorCount = 100;
static const int kActorVoiceOver = kActorCount - 1;
+
// Incremental number to keep track of significant revisions of the ScummVM bladerunner engine
// that could potentially introduce incompatibilities with old save files or require special actions to restore compatibility
// This is stored in game global variable "kVariableGameVersion"
diff --git a/engines/bladerunner/module.mk b/engines/bladerunner/module.mk
index f1d935b606..984de0aa27 100644
--- a/engines/bladerunner/module.mk
+++ b/engines/bladerunner/module.mk
@@ -273,6 +273,7 @@ MODULE_OBJS = \
ui/ui_input_box.o \
ui/ui_scroll_box.o \
ui/ui_slider.o \
+ ui/ui_dropdown.o \
ui/vk.o \
view.o \
vqa_decoder.o \
diff --git a/engines/bladerunner/subtitles.h b/engines/bladerunner/subtitles.h
index 713e45efb4..44ed1ea4c1 100644
--- a/engines/bladerunner/subtitles.h
+++ b/engines/bladerunner/subtitles.h
@@ -39,13 +39,16 @@ class TextResource;
class Subtitles {
friend class Debugger;
+ friend class KIASectionSettings;
//
// Subtitles could be in 6 possible languages are EN_ANY, DE_DEU, FR_FRA, IT_ITA, RU_RUS, ES_ESP
// with corresponding _vm->_languageCode values: "E", "G", "F", "I", "E", "S" (Russian version is built on top of English one)
- static const uint kPreferedLine = 2; // Prefer drawing from this line (the bottom-most of available subtitle lines index is 0) by default
- static const int kMarginBottom = 12; // In pixels. This is the bottom margin beneath the subtitles space
- static const int kTextMaxWidth = 610; // In pixels
- static const int kMaxTextResourceEntries = 27; // Support in-game subs (1) and all possible VQAs (26) with spoken dialogue or translatable text
+ static const uint kPreferedLine = 2; // Prefer drawing from this line (the bottom-most of available subtitle lines index is 0) by default
+ static const int kMarginBottom = 12; // In pixels. This is the bottom margin beneath the subtitles space
+ static const int kTextMaxWidth = 610; // In pixels
+ static const int kMaxTextResourceEntries = 27; // Support in-game subs (1) and all possible VQAs (26) with spoken dialogue or translatable text
+ static const int kMaxLanguageSelectionNum = 1024; // Max allowed number of languages to select from (should be available in the MIX file)
+
static const char *SUBTITLES_FILENAME_PREFIXES[kMaxTextResourceEntries];
static const char *SUBTITLES_FONT_FILENAME_EXTERNAL;
static const char *SUBTITLES_VERSION_TRENAME;
diff --git a/engines/bladerunner/ui/kia_section_settings.cpp b/engines/bladerunner/ui/kia_section_settings.cpp
index 001579acaa..5d1e3c2fb0 100644
--- a/engines/bladerunner/ui/kia_section_settings.cpp
+++ b/engines/bladerunner/ui/kia_section_settings.cpp
@@ -40,14 +40,31 @@
#include "bladerunner/ui/ui_container.h"
#include "bladerunner/ui/ui_image_picker.h"
#include "bladerunner/ui/ui_slider.h"
+#include "bladerunner/ui/ui_scroll_box.h"
+#include "bladerunner/ui/ui_dropdown.h"
#include "audio/mixer.h"
#include "common/keyboard.h"
+#include "common/debug.h"
namespace BladeRunner {
const char *KIASectionSettings::kLeary = "LEARY";
+const Color256 KIASectionSettings::kColors[] = {
+ { 0, 0, 0 }, // Black - unpressed (framing rectange)
+ { 16, 8, 8 },
+ { 32, 24, 8 },
+ { 56, 32, 16 },
+ { 72, 48, 16 },
+ { 88, 56, 24 }, // Mouse-over (framing rectange)
+ { 104, 72, 32 },
+ { 128, 80, 40 },
+ { 136, 96, 48 },
+ { 152, 112, 56 },
+ { 168, 128, 72 } // Pressed (framing rectange)
+};
+
KIASectionSettings::KIASectionSettings(BladeRunnerEngine *vm)
: KIASectionBase(vm) {
@@ -64,17 +81,44 @@ KIASectionSettings::KIASectionSettings(BladeRunnerEngine *vm)
_soundEffectVolume = new UISlider(_vm, sliderCallback, this, Common::Rect(180, 185, 460, 195), _vm->_mixer->kMaxMixerVolume, 0);
_speechVolume = new UISlider(_vm, sliderCallback, this, Common::Rect(180, 210, 460, 220), _vm->_mixer->kMaxMixerVolume, 0);
#endif
+ _subtitlesEnable = nullptr;
if (_vm->_language == Common::RU_RUS) {
// expanded click-bounding box x-axis
_directorsCut = new UICheckBox(_vm, checkBoxCallback, this, Common::Rect(180, 364, 436, 374), 0, false);
- // moved to new line
- _subtitlesEnable = new UICheckBox(_vm, checkBoxCallback, this, Common::Rect(276, 376, 345, 386), 0, false);
+ if (_vm->_subtitles->isSystemActive()) {
+ // moved to new line
+ _subtitlesEnable = new UICheckBox(_vm, checkBoxCallback, this, Common::Rect(276, 376, 345, 386), 0, false);
+ }
} else {
_directorsCut = new UICheckBox(_vm, checkBoxCallback, this, Common::Rect(180, 364, 270, 374), 0, false);
- // moved further to the right to avoid overlap with 'Designer's Cut' in some language versions (ESP)
- _subtitlesEnable = new UICheckBox(_vm, checkBoxCallback, this, Common::Rect(311, 364, 380, 374), 0, false);
+ if (_vm->_subtitles->isSystemActive()) {
+ // moved further to the right to avoid overlap with 'Designer's Cut' in some language versions (ESP)
+ _subtitlesEnable = new UICheckBox(_vm, checkBoxCallback, this, Common::Rect(311, 364, 380, 374), 0, false);
+ }
}
+
+ _selectedTextLanguageStr = "";
+ _selectedTextLanguageId = -1;
+ _textLanguageDropdown = nullptr;
+ if (_vm->_subtitles->isSystemActive()) {
+ // TODO initialize with default values or ConfMan() in open()?
+ _selectedTextLanguageStr = "";
+ _selectedTextLanguageId = -1;
+ // Put at height on top of Music setting
+ // This avoids interference and handling the case of when BLADERUNNER_ORIGINAL_SETTINGS is set
+ // (in which case the middle part of the KIA screen is filled with controls)
+ _textLanguageDropdown = new UIDropDown(_vm,
+ dropdownSelectedCallback,
+ dropdownCancelledCallback,
+ dropdownClickedTopFrameCallback,
+ this,
+ "",
+ 0,
+ 136,
+ Subtitles::kMaxLanguageSelectionNum);
+ }
+
_playerAgendaSelector = new UIImagePicker(_vm, 5);
_uiContainer->add(_musicVolume);
@@ -87,8 +131,17 @@ KIASectionSettings::KIASectionSettings(BladeRunnerEngine *vm)
_uiContainer->add(_directorsCut);
if (_vm->_subtitles->isSystemActive()) {
_uiContainer->add(_subtitlesEnable);
+ // Note: Keep _languageSelectorScrollBox last added to _uiContainer
+ // in order to be able to set it as the only active object
+ // when the language selection dropdown is shown.
+ _uiContainer->add(_textLanguageDropdown);
}
+ _state = kStateNormal;
+
+ _mouseX = 0;
+ _mouseY = 0;
+
_learyPos = 0;
}
@@ -102,27 +155,39 @@ KIASectionSettings::~KIASectionSettings() {
delete _gammaCorrection;
#endif
delete _directorsCut;
- delete _subtitlesEnable;
+ if (_vm->_subtitles->isSystemActive()) {
+ delete _textLanguageDropdown;
+ delete _subtitlesEnable;
+ }
delete _playerAgendaSelector;
}
void KIASectionSettings::open() {
+ _state = kStateNormal;
+
_playerAgendaSelector->resetImages();
- _playerAgendaSelector->defineImage(0, Common::Rect(180, 290, 227, 353), nullptr, nullptr, nullptr, _vm->_textOptions->getText(30));
- _playerAgendaSelector->defineImage(1, Common::Rect(238, 290, 285, 353), nullptr, nullptr, nullptr, _vm->_textOptions->getText(31));
- _playerAgendaSelector->defineImage(2, Common::Rect(296, 290, 343, 353), nullptr, nullptr, nullptr, _vm->_textOptions->getText(32));
- _playerAgendaSelector->defineImage(3, Common::Rect(354, 290, 401, 353), nullptr, nullptr, nullptr, _vm->_textOptions->getText(33));
- _playerAgendaSelector->defineImage(4, Common::Rect(412, 290, 459, 353), nullptr, nullptr, nullptr, _vm->_textOptions->getText(34));
+ _playerAgendaSelector->defineImage(kPlayerAgendaPolite, Common::Rect(180, 290, 227, 353), nullptr, nullptr, nullptr, _vm->_textOptions->getText(30));
+ _playerAgendaSelector->defineImage(kPlayerAgendaNormal, Common::Rect(238, 290, 285, 353), nullptr, nullptr, nullptr, _vm->_textOptions->getText(31));
+ _playerAgendaSelector->defineImage(kPlayerAgendaSurly, Common::Rect(296, 290, 343, 353), nullptr, nullptr, nullptr, _vm->_textOptions->getText(32));
+ _playerAgendaSelector->defineImage(kPlayerAgendaErratic, Common::Rect(354, 290, 401, 353), nullptr, nullptr, nullptr, _vm->_textOptions->getText(33));
+ _playerAgendaSelector->defineImage(kPlayerAgendaUserChoice, Common::Rect(412, 290, 459, 353), nullptr, nullptr, nullptr, _vm->_textOptions->getText(34));
initConversationChoices();
_playerAgendaSelector->activate(mouseInCallback, nullptr, nullptr, mouseUpCallback, this);
_directorsCut->enable();
- _subtitlesEnable->enable();
+ if (_vm->_subtitles->isSystemActive()) {
+ _subtitlesEnable->enable();
+ _textLanguageDropdown->activate();
+ populateLanguageSelection();
+ }
}
void KIASectionSettings::close() {
_playerAgendaSelector->deactivate();
+ if (_vm->_subtitles->isSystemActive()) {
+ _textLanguageDropdown->deactivate();
+ }
}
void KIASectionSettings::draw(Graphics::Surface &surface) {
@@ -140,7 +205,9 @@ void KIASectionSettings::draw(Graphics::Surface &surface) {
_directorsCut->setChecked(_vm->_gameFlags->query(kFlagDirectorsCut));
- _subtitlesEnable->setChecked(_vm->isSubtitlesEnabled());
+ if (_vm->_subtitles->isSystemActive()) {
+ _subtitlesEnable->setChecked(_vm->isSubtitlesEnabled());
+ }
const char *textConversationChoices = _vm->_textOptions->getText(0);
const char *textMusic = _vm->_textOptions->getText(2);
@@ -167,7 +234,6 @@ void KIASectionSettings::draw(Graphics::Surface &surface) {
int posDark = 178 - _vm->_mainFont->getStringWidth(textDark);
#endif
- _uiContainer->draw(surface);
_playerAgendaSelector->draw(surface);
_vm->_mainFont->drawString(&surface, textConversationChoices, posConversationChoices, 280, surface.w, surface.format.RGBToColor(232, 208, 136));
@@ -202,38 +268,47 @@ void KIASectionSettings::draw(Graphics::Surface &surface) {
if (_vm->_subtitles->isSystemActive()) {
// Allow this to be loading as an extra text item in the resource for text options
- const char *subtitlesTranslation = nullptr;
+ const char *subtitlesTranslation = nullptr;
+ const char *languageSelectTranslation = nullptr;
switch (_vm->_language) {
- case Common::EN_ANY:
- default:
- subtitlesTranslation = "Subtitles";
- break;
- case Common::DE_DEU:
- subtitlesTranslation = "Untertitel";
- break;
- case Common::FR_FRA:
- subtitlesTranslation = "Sous-titres";
- break;
- case Common::IT_ITA:
- subtitlesTranslation = "Sottotitoli";
- break;
- case Common::ES_ESP:
- // the spanish text must have accented Ã
- subtitlesTranslation = "Subt\xa1tulos";
- break;
- case Common::RU_RUS:
- // ÑÑбÑиÑÑÑ
- if (_vm->_russianCP1251) {
- // Patched translation by Siberian Studio is using Windows-1251 encoding
- subtitlesTranslation = "\xf1\xf3\xe1\xf2\xe8\xf2\xf0\xfb";
- } else {
- // Original release uses custom encoding
- subtitlesTranslation = "CE,NBNHS";
- }
- break;
+ case Common::EN_ANY:
+ default:
+ subtitlesTranslation = "Subtitles";
+ languageSelectTranslation = "Text Language:";
+ break;
+ case Common::DE_DEU:
+ subtitlesTranslation = "Untertitel";
+ languageSelectTranslation = "Text Language:"; // TODO DEUTCH translation
+ break;
+ case Common::FR_FRA:
+ subtitlesTranslation = "Sous-titres";
+ languageSelectTranslation = "Text Language:"; // TODO FRENCH translation
+ break;
+ case Common::IT_ITA:
+ subtitlesTranslation = "Sottotitoli";
+ languageSelectTranslation = "Text Language:"; // TODO ITALIAN translation
+ break;
+ case Common::ES_ESP:
+ // the spanish text must have accented Ã
+ subtitlesTranslation = "Subt\xa1tulos";
+ languageSelectTranslation = "Text Language:"; // TODO SPANISH translation
+ break;
+ case Common::RU_RUS:
+ // ÑÑбÑиÑÑÑ
+ if (_vm->_russianCP1251) {
+ // Patched translation by Siberian Studio is using Windows-1251 encoding
+ subtitlesTranslation = "\xf1\xf3\xe1\xf2\xe8\xf2\xf0\xfb";
+ languageSelectTranslation = "Text Language:"; // TODO RUSSIAN translation + proper characters for encoding
+ } else {
+ // Original release uses custom encoding
+ subtitlesTranslation = "CE,NBNHS";
+ languageSelectTranslation = "Text Language:"; // TODO RUSSIAN translation + proper characters for this encoding
+ }
+ break;
}
- // +1 to the max of original index of textOptions which is 41
+ // +2 to the max of original index of textOptions which is 41
const char *textSubtitles = strcmp(_vm->_textOptions->getText(42), "") == 0 ? subtitlesTranslation : _vm->_textOptions->getText(42);
+ const char *textLanguageSelect = strcmp(_vm->_textOptions->getText(43), "") == 0 ? languageSelectTranslation : _vm->_textOptions->getText(43);
if (_vm->_language == Common::RU_RUS) {
// special case for Russian version, put the option in a new line to avoid overlap
@@ -242,36 +317,48 @@ void KIASectionSettings::draw(Graphics::Surface &surface) {
// moved further to the right to avoid overlap with 'Designer's Cut' in some language versions (ESP)
_vm->_mainFont->drawString(&surface, textSubtitles, 323, 365, surface.w, surface.format.RGBToColor(232, 208, 136));
}
+
+ // Vertical Align with "Soft" label
+ _textLanguageDropdown->setControlLeft(posSoft);
+ _textLanguageDropdown->setLabelStr(textLanguageSelect);
}
+ // Draw uiContainer contained objects after drawing the text on the section for music, sound, speech etc.
+ _uiContainer->draw(surface);
+
_playerAgendaSelector->drawTooltip(surface, _mouseX, _mouseY);
}
void KIASectionSettings::handleKeyDown(const Common::KeyState &kbd) {
- if (toupper(kbd.ascii) != kLeary[_learyPos]) {
- _learyPos = 0;
- }
-
- if (toupper(kbd.ascii) == kLeary[_learyPos]) {
- ++_learyPos;
- if (!kLeary[_learyPos]) {
- _vm->_settings->setLearyMode(!_vm->_settings->getLearyMode());
+ if (_state == kStateNormal) {
+ if (toupper(kbd.ascii) != kLeary[_learyPos]) {
_learyPos = 0;
- initConversationChoices();
+ }
+
+ if (toupper(kbd.ascii) == kLeary[_learyPos]) {
+ ++_learyPos;
+ if (!kLeary[_learyPos]) {
+ _vm->_settings->setLearyMode(!_vm->_settings->getLearyMode());
+ _learyPos = 0;
+ initConversationChoices();
+ }
}
}
}
void KIASectionSettings::handleMouseMove(int mouseX, int mouseY) {
_uiContainer->handleMouseMove(mouseX, mouseY);
+
_mouseX = mouseX;
_mouseY = mouseY;
+
_playerAgendaSelector->handleMouseAction(mouseX, mouseY, false, false, false);
}
void KIASectionSettings::handleMouseDown(bool mainButton) {
if (mainButton) {
_uiContainer->handleMouseDown(false);
+
_playerAgendaSelector->handleMouseAction(_mouseX, _mouseY, true, false, false);
}
}
@@ -279,10 +366,17 @@ void KIASectionSettings::handleMouseDown(bool mainButton) {
void KIASectionSettings::handleMouseUp(bool mainButton) {
if (mainButton) {
_uiContainer->handleMouseUp(false);
+
_playerAgendaSelector->handleMouseAction(_mouseX, _mouseY, false, true, false);
}
}
+void KIASectionSettings::handleMouseScroll(int direction) {
+ if (_vm->_subtitles->isSystemActive() && _state == kStateLanguageSelect) {
+ _uiContainer->handleMouseScroll(direction);
+ }
+}
+
void KIASectionSettings::sliderCallback(void *callbackData, void *source) {
KIASectionSettings *self = (KIASectionSettings *)callbackData;
@@ -333,8 +427,7 @@ void KIASectionSettings::checkBoxCallback(void *callbackData, void *source) {
} else {
self->_vm->_gameFlags->reset(kFlagDirectorsCut);
}
- }
- else if (source == self->_subtitlesEnable) {
+ } else if (self->_vm->_subtitles->isSystemActive() && source == self->_subtitlesEnable) {
self->_vm->setSubtitlesEnabled(self->_subtitlesEnable->_isChecked);
}
}
@@ -351,29 +444,29 @@ void KIASectionSettings::mouseUpCallback(int buttonId, void *callbackData) {
void KIASectionSettings::onButtonPressed(int buttonId) {
switch (buttonId) {
- case 0:
+ case kPlayerAgendaPolite:
_vm->_audioPlayer->playAud(_vm->_gameInfo->getSfxTrack(kSfxELECBP1), 90, -30, -30, 50, 0);
- _vm->_settings->setPlayerAgenda(0);
+ _vm->_settings->setPlayerAgenda(kPlayerAgendaPolite);
initConversationChoices();
break;
- case 1:
+ case kPlayerAgendaNormal:
_vm->_audioPlayer->playAud(_vm->_gameInfo->getSfxTrack(kSfxELECBP1), 90, -15, -15, 50, 0);
- _vm->_settings->setPlayerAgenda(1);
+ _vm->_settings->setPlayerAgenda(kPlayerAgendaNormal);
initConversationChoices();
break;
- case 2:
+ case kPlayerAgendaSurly:
_vm->_audioPlayer->playAud(_vm->_gameInfo->getSfxTrack(kSfxELECBP1), 90, 0, 0, 50, 0);
- _vm->_settings->setPlayerAgenda(2);
+ _vm->_settings->setPlayerAgenda(kPlayerAgendaSurly);
initConversationChoices();
break;
- case 3:
+ case kPlayerAgendaErratic:
_vm->_audioPlayer->playAud(_vm->_gameInfo->getSfxTrack(kSfxELECBP1), 90, 15, 15, 50, 0);
- _vm->_settings->setPlayerAgenda(3);
+ _vm->_settings->setPlayerAgenda(kPlayerAgendaErratic);
initConversationChoices();
break;
- case 4:
+ case kPlayerAgendaUserChoice:
_vm->_audioPlayer->playAud(_vm->_gameInfo->getSfxTrack(kSfxELECBP1), 90, 30, 30, 50, 0);
- _vm->_settings->setPlayerAgenda(4);
+ _vm->_settings->setPlayerAgenda(kPlayerAgendaUserChoice);
initConversationChoices();
break;
default:
@@ -385,7 +478,7 @@ void KIASectionSettings::initConversationChoices() {
for (int i = 0; i < 5; ++i) {
const Shape *shape = nullptr;
if (_vm->_settings->getPlayerAgenda() == i) {
- if (i == 4) {
+ if (i == kPlayerAgendaUserChoice) {
shape = _vm->_kia->_shapes->get(122);
} else if (_vm->_settings->getLearyMode()) {
shape = _vm->_kia->_shapes->get(106 + i);
@@ -393,7 +486,7 @@ void KIASectionSettings::initConversationChoices() {
shape = _vm->_kia->_shapes->get(114 + i);
}
} else {
- if (i == 4) {
+ if (i == kPlayerAgendaUserChoice) {
shape = _vm->_kia->_shapes->get(123);
} else if (_vm->_settings->getLearyMode()) {
shape = _vm->_kia->_shapes->get(110 + i);
@@ -408,4 +501,62 @@ void KIASectionSettings::initConversationChoices() {
}
}
+void KIASectionSettings::populateLanguageSelection() {
+ _textLanguageDropdown->clearLines();
+ _textLanguageDropdown->addLine("English v7 [ENG] (SCUMMVM)", 1);
+ _textLanguageDropdown->addLine("French v7 [FRA] (Kwama57)", 2);
+ _textLanguageDropdown->addLine("Spanish v7 [ESP] (Victor G. Fraile & GeekOb)", 3);
+ _textLanguageDropdown->addLine("Greek v1 [ENG] (Praetorian)", 4);
+ _textLanguageDropdown->addLine("Hebrew v1 [ENG] (Rzil)", 5);
+ _textLanguageDropdown->addLine("Chinese v0 [ENG] (*)", 6);
+ _textLanguageDropdown->addLine("Russian v1 [ENG] (*)", 7);
+ _textLanguageDropdown->addLine("Italian v0 [ITA] (*)", 8);
+ _textLanguageDropdown->addLine("Deutsch v0 [DEU] (*)", 9);
+}
+
+void KIASectionSettings::changeState(State state) {
+ _state = state;
+ if (state != kStateNormal) {
+ _vm->_audioPlayer->playAud(_vm->_gameInfo->getSfxTrack(kSfxSPNBEEP7), 90, 0, 0, 50, 0);
+ }
+}
+
+void KIASectionSettings::dropdownSelectedCallback(void *callbackData, void *source, int lineData, int mouseButton) {
+ KIASectionSettings *self = (KIASectionSettings *)callbackData;
+
+ if (source == self->_textLanguageDropdown && lineData >= 0) {
+ self->_selectedTextLanguageStr = self->_textLanguageDropdown->getLineSelectedStr();
+ self->_selectedTextLanguageId = lineData;
+ self->showTextSelectionDropdown(false);
+ }
+}
+
+void KIASectionSettings::dropdownCancelledCallback(void *callbackData, void *source) {
+ KIASectionSettings *self = (KIASectionSettings *)callbackData;
+ if (source == self->_textLanguageDropdown) {
+ self->showTextSelectionDropdown(false);
+ }
+}
+
+void KIASectionSettings::dropdownClickedTopFrameCallback(void *callbackData, void *source) {
+ KIASectionSettings *self = (KIASectionSettings *)callbackData;
+
+ if (source == self->_textLanguageDropdown) {
+ self->showTextSelectionDropdown(!self->_textLanguageDropdown->isDropDownMenuExpanded());
+ }
+}
+
+void KIASectionSettings::showTextSelectionDropdown(bool showToggle) {
+ if (showToggle) {
+ // scrollable area will be expanded
+ populateLanguageSelection();
+ _uiContainer->setHandleSpecificNumOfTopLayers(1);
+ changeState(kStateLanguageSelect);
+ } else {
+ // scrollable area will be collapsed
+ _uiContainer->setHandleSpecificNumOfTopLayers(0);
+ changeState(kStateNormal);
+ }
+}
+
} // End of namespace BladeRunner
diff --git a/engines/bladerunner/ui/kia_section_settings.h b/engines/bladerunner/ui/kia_section_settings.h
index b6ca8a7eb9..430a3b7972 100644
--- a/engines/bladerunner/ui/kia_section_settings.h
+++ b/engines/bladerunner/ui/kia_section_settings.h
@@ -24,9 +24,11 @@
#define BLADERUNNER_KIA_SECTION_SETTINGS_H
#include "bladerunner/bladerunner.h" // for BLADERUNNER_ORIGINAL_SETTINGS macro
+#include "bladerunner/color.h"
#include "bladerunner/ui/kia_section_base.h"
#include "common/config-manager.h"
+#include "common/rect.h"
namespace BladeRunner {
@@ -35,9 +37,17 @@ class UIContainer;
class UICheckBox;
class UIImagePicker;
class UISlider;
+class UIScrollBox;
+class UIDropDown;
class KIASectionSettings : public KIASectionBase {
+ enum State {
+ kStateNormal = 0,
+ kStateLanguageSelect = 1
+ };
+
static const char *kLeary;
+ static const Color256 kColors[];
UIContainer *_uiContainer;
UISlider *_musicVolume;
@@ -49,6 +59,18 @@ class KIASectionSettings : public KIASectionBase {
#endif
UICheckBox *_directorsCut;
UICheckBox *_subtitlesEnable;
+ Common::String _selectedTextLanguageStr;
+ int _selectedTextLanguageId;
+
+ UIDropDown *_textLanguageDropdown;
+
+// UIScrollBox *_languageSelectorScrollBox;
+// UIImagePicker *_languageDropdownBtn;
+// Common::Rect _languageSelectorFrameRect;
+// int _languageSelectorFrameRectColor;
+// bool _languageSelectorFrameRectHasFocus;
+// int _languageSelectorScrollBoxMaxLineWidth;
+
UIImagePicker *_playerAgendaSelector;
int _mouseX;
@@ -56,6 +78,8 @@ class KIASectionSettings : public KIASectionBase {
int _learyPos;
+ State _state;
+
public:
KIASectionSettings(BladeRunnerEngine *vm);
~KIASectionSettings() override;
@@ -69,16 +93,25 @@ public:
void handleMouseMove(int mouseX, int mouseY) override;
void handleMouseDown(bool mainButton) override;
void handleMouseUp(bool mainButton) override;
+ void handleMouseScroll(int direction) override;
+
+ void showTextSelectionDropdown(bool showToggle);
private:
static void sliderCallback(void *callbackData, void *source);
static void checkBoxCallback(void *callbackData, void *source);
static void mouseInCallback(int buttonId, void *callbackData);
static void mouseUpCallback(int buttonId, void *callbackData);
+ static void dropdownSelectedCallback(void *callbackData, void *source, int lineData, int mouseButton);
+ static void dropdownCancelledCallback(void *callbackData, void *source);
+ static void dropdownClickedTopFrameCallback(void *callbackData, void *source);
void onButtonPressed(int buttonId) override;
void initConversationChoices();
+ void populateLanguageSelection();
+
+ void changeState(State state);
};
} // End of namespace BladeRunner
diff --git a/engines/bladerunner/ui/ui_container.cpp b/engines/bladerunner/ui/ui_container.cpp
index 6b9feb105a..eeff854b04 100644
--- a/engines/bladerunner/ui/ui_container.cpp
+++ b/engines/bladerunner/ui/ui_container.cpp
@@ -33,38 +33,99 @@ void UIContainer::draw(Graphics::Surface &surface) {
}
void UIContainer::handleMouseMove(int mouseX, int mouseY) {
- for (Common::Array<UIComponent*>::iterator component = _components.begin(); component != _components.end(); ++component) {
- (*component)->handleMouseMove(mouseX, mouseY);
+ if (_handleSpecificNumOfTopLayers <= 0) {
+ for (Common::Array<UIComponent*>::iterator component = _components.begin(); component != _components.end(); ++component) {
+ (*component)->handleMouseMove(mouseX, mouseY);
+ }
+ } else {
+ int countOfTopLayersToHandle = _handleSpecificNumOfTopLayers;
+ Common::Array<UIComponent*>::iterator component = _components.end();
+ do {
+ --component;
+ --countOfTopLayersToHandle;
+ (*component)->handleMouseMove(mouseX, mouseY);
+ } while (component != _components.begin() && countOfTopLayersToHandle != 0);
}
}
void UIContainer::handleMouseDown(bool alternateButton) {
- for (Common::Array<UIComponent*>::iterator component = _components.begin(); component != _components.end(); ++component) {
- (*component)->handleMouseDown(alternateButton);
+ if (_handleSpecificNumOfTopLayers <= 0) {
+ for (Common::Array<UIComponent*>::iterator component = _components.begin(); component != _components.end(); ++component) {
+ (*component)->handleMouseDown(alternateButton);
+ }
+ } else {
+ int countOfTopLayersToHandle = _handleSpecificNumOfTopLayers;
+ Common::Array<UIComponent*>::iterator component = _components.end();
+ do {
+ --component;
+ --countOfTopLayersToHandle;
+ (*component)->handleMouseDown(alternateButton);
+ } while (component != _components.begin() && countOfTopLayersToHandle != 0);
}
}
void UIContainer::handleMouseUp(bool alternateButton) {
- for (Common::Array<UIComponent*>::iterator component = _components.begin(); component != _components.end(); ++component) {
- (*component)->handleMouseUp(alternateButton);
+ if (_handleSpecificNumOfTopLayers <= 0) {
+ for (Common::Array<UIComponent*>::iterator component = _components.begin(); component != _components.end(); ++component) {
+ (*component)->handleMouseUp(alternateButton);
+ }
+ } else {
+ int countOfTopLayersToHandle = _handleSpecificNumOfTopLayers;
+ Common::Array<UIComponent*>::iterator component = _components.end();
+ do {
+ --component;
+ --countOfTopLayersToHandle;
+ (*component)->handleMouseUp(alternateButton);
+ } while (component != _components.begin() && countOfTopLayersToHandle != 0);
}
}
void UIContainer::handleMouseScroll(int direction) {
- for (Common::Array<UIComponent*>::iterator component = _components.begin(); component != _components.end(); ++component) {
- (*component)->handleMouseScroll(direction);
+ if (_handleSpecificNumOfTopLayers <= 0) {
+ for (Common::Array<UIComponent*>::iterator component = _components.begin(); component != _components.end(); ++component) {
+ (*component)->handleMouseScroll(direction);
+ }
+ } else {
+ int countOfTopLayersToHandle = _handleSpecificNumOfTopLayers;
+ Common::Array<UIComponent*>::iterator component = _components.end();
+ do {
+ --component;
+ --countOfTopLayersToHandle;
+ (*component)->handleMouseScroll(direction);
+ } while (component != _components.begin() && countOfTopLayersToHandle != 0);
}
}
void UIContainer::handleKeyUp(const Common::KeyState &kbd) {
- for (Common::Array<UIComponent*>::iterator component = _components.begin(); component != _components.end(); ++component) {
- (*component)->handleKeyUp(kbd);
+ if (_handleSpecificNumOfTopLayers <= 0) {
+ for (Common::Array<UIComponent*>::iterator component = _components.begin(); component != _components.end(); ++component) {
+ (*component)->handleKeyUp(kbd);
+ }
+ } else {
+ int countOfTopLayersToHandle = _handleSpecificNumOfTopLayers;
+ Common::Array<UIComponent*>::iterator component = _components.end();
+ do {
+ --component;
+ --countOfTopLayersToHandle;
+ (*component)->handleKeyUp(kbd);
+ } while (component != _components.begin() && countOfTopLayersToHandle != 0);
}
}
void UIContainer::handleKeyDown(const Common::KeyState &kbd) {
- for (Common::Array<UIComponent*>::iterator component = _components.begin(); component != _components.end(); ++component) {
- (*component)->handleKeyDown(kbd);
+ if (_handleSpecificNumOfTopLayers <= 0) {
+ for (Common::Array<UIComponent*>::iterator component = _components.begin(); component != _components.end(); ++component) {
+ (*component)->handleKeyDown(kbd);
+ }
+ } else {
+ int countOfTopLayersToHandle = _handleSpecificNumOfTopLayers;
+ Common::Array<UIComponent*>::iterator component = _components.end();
+ do {
+ --component;
+ --countOfTopLayersToHandle;
+ (*component)->handleKeyDown(kbd);
+ } while (component != _components.begin() && countOfTopLayersToHandle != 0);
+
}
}
@@ -74,6 +135,12 @@ void UIContainer::add(UIComponent *component) {
void UIContainer::clear() {
_components.clear();
+ _handleSpecificNumOfTopLayers = 0;
}
+void UIContainer::setHandleSpecificNumOfTopLayers(int count) {
+ _handleSpecificNumOfTopLayers = count;
+}
+
+
} // End of namespace BladeRunner
diff --git a/engines/bladerunner/ui/ui_container.h b/engines/bladerunner/ui/ui_container.h
index 8d794513dd..214d55ca99 100644
--- a/engines/bladerunner/ui/ui_container.h
+++ b/engines/bladerunner/ui/ui_container.h
@@ -34,8 +34,12 @@ class UIComponent;
class UIContainer : public UIComponent {
Common::Array<UIComponent*> _components;
+ int _handleSpecificNumOfTopLayers;
+
public:
- UIContainer(BladeRunnerEngine *vm) : UIComponent(vm) {}
+ UIContainer(BladeRunnerEngine *vm) : UIComponent(vm) {
+ _handleSpecificNumOfTopLayers = 0;
+ }
void draw(Graphics::Surface &surface) override;
@@ -48,6 +52,8 @@ public:
void add(UIComponent *component);
void clear();
+
+ void setHandleSpecificNumOfTopLayers(int count);
};
diff --git a/engines/bladerunner/ui/ui_dropdown.cpp b/engines/bladerunner/ui/ui_dropdown.cpp
new file mode 100644
index 0000000000..fe2c00de7d
--- /dev/null
+++ b/engines/bladerunner/ui/ui_dropdown.cpp
@@ -0,0 +1,352 @@
+/* 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 "bladerunner/ui/ui_dropdown.h"
+
+#include "bladerunner/audio_player.h"
+#include "bladerunner/bladerunner.h"
+#include "bladerunner/ui/kia.h"
+#include "bladerunner/ui/ui_image_picker.h"
+#include "bladerunner/ui/ui_scroll_box.h"
+#include "bladerunner/subtitles.h"
+#include "bladerunner/font.h"
+#include "bladerunner/game_info.h"
+#include "bladerunner/shape.h"
+#include "bladerunner/game_constants.h"
+
+#include "common/debug.h"
+
+namespace BladeRunner {
+
+const Color256 UIDropDown::kColors[] = {
+ { 0, 0, 0 }, // Black - unpressed (framing rectange)
+ { 16, 8, 8 },
+ { 32, 24, 8 },
+ { 56, 32, 16 },
+ { 72, 48, 16 },
+ { 88, 56, 24 }, // Mouse-over (framing rectange)
+ { 104, 72, 32 },
+ { 128, 80, 40 },
+ { 136, 96, 48 },
+ { 152, 112, 56 },
+ { 168, 128, 72 } // Pressed (framing rectange)
+};
+
+UIDropDown::UIDropDown(BladeRunnerEngine *vm,
+ UIDropDownLineSelectedCallback *ddlLineSelectedCallback,
+ UIDropDownGenericCallback *ddlCancelledCallback,
+ UIDropDownGenericCallback *ddlTopFrameClickCallback,
+ void *callbackData,
+ Common::String labelStr,
+ int controlLeftX,
+ int controlTopY,
+ int scrollBoxMaxLineCount) : UIComponent(vm) {
+
+ _isVisible = false;
+
+ _labelStr = labelStr;
+ _controlLeftX = MAX(controlLeftX, 0);
+ // TODO The id should be used to eg. grab info about the selected subtitles from an engine's subtitles object
+ _lineSelectedId = -1;
+
+ _lineSelectorFrameRectColor = 0;
+ _lineSelectorFrameRectHasFocus = false;
+ // A framing (outlining) rectangle to highlight the selected option field on top of the scrollbox
+ controlTopY = CLIP(controlTopY, 0, 600);
+ _lineSelectorFrameRect = Common::Rect(0, controlTopY, 0, controlTopY + kDropDownButtonShapeHeight);
+
+ // TODO This eventually should be set to a default probably by the outside caller class(kia_section_settings)
+ // Current explicit assignment only serves as placeholder / proof of concept
+ _lineSelectedStr = "English (SCUMMVM) v7 [ENG]";
+ _lineSelectorScrollBox = new UIScrollBox(_vm, scrollBoxLineSelectCallback, this, scrollBoxMaxLineCount, 2, false, Common::Rect(0, 0, 0, 55 + kFrameRectPaddingPx), Common::Rect(0, 0, 0, 55));
+ _lineSelectorScrollBoxMaxLineWidth = 0;
+
+ _lineDropdownBtn = new UIImagePicker(_vm, 2);
+
+ _ddlLineSelectedCallback = ddlLineSelectedCallback;
+ _ddlCancelledCallback = ddlCancelledCallback;
+ _ddlTopFrameClickCallback = ddlTopFrameClickCallback;
+ _callbackData = callbackData;
+
+ _mouseX = 0;
+ _mouseY = 0;
+}
+
+UIDropDown::~UIDropDown() {
+ delete _lineSelectorScrollBox;
+ delete _lineDropdownBtn;
+}
+
+void UIDropDown::activate() {
+ _lineDropdownBtn->resetImages();
+ // Actual button shape
+ // defineImage actually increases internally the bottom and right bounds for the rect to be inclusive (for the contains() method)
+ _lineDropdownBtn->defineImage(0, Common::Rect(0, _lineSelectorFrameRect.top + 1, kDropDownButtonShapeWidth - 1, _lineSelectorFrameRect.bottom - 1), _vm->_kia->_shapes->get(73), _vm->_kia->_shapes->get(74), _vm->_kia->_shapes->get(75), nullptr);
+ // Clickable Selected/Active Line Description area
+ _lineDropdownBtn->defineImage(1, Common::Rect(0, _lineSelectorFrameRect.top, kDropDownButtonShapeWidth - 1, _lineSelectorFrameRect.bottom - 1), nullptr, nullptr, nullptr, nullptr);
+ _lineDropdownBtn->activate(nullptr, nullptr, mouseDownLDBCallback, nullptr, this);
+
+ _lineSelectorScrollBox->setBoxTop(_lineSelectorFrameRect.bottom);
+ _lineSelectorScrollBox->setScrollbarTop(_lineSelectorFrameRect.bottom);
+
+ _lineSelectorScrollBox->hide(); // show upon click on field or dropdown button
+ show();
+}
+
+
+void UIDropDown::deactivate() {
+ _isVisible = false;
+
+ _lineDropdownBtn->deactivate();
+ _lineSelectorScrollBox->hide();
+}
+
+void UIDropDown::draw(Graphics::Surface &surface) {
+ if (!_isVisible) {
+ return;
+ }
+
+ int posStartOfSelectedLineDesc = _controlLeftX + _vm->_mainFont->getStringWidth(_labelStr) + _vm->_mainFont->getCharWidth(' ');
+ _vm->_mainFont->drawString(&surface, _labelStr, _controlLeftX, _lineSelectorFrameRect.top, surface.w, surface.format.RGBToColor(232, 208, 136));
+ _vm->_mainFont->drawString(&surface, _lineSelectedStr,
+ posStartOfSelectedLineDesc,
+ _lineSelectorFrameRect.top, surface.w, surface.format.RGBToColor(240, 232, 192));
+
+ // TODO add a clipping for description field here
+ int posEndOfSelectedLineDesc = posStartOfSelectedLineDesc + _vm->_mainFont->getStringWidth(_lineSelectedStr) + _vm->_mainFont->getCharWidth(' ');
+
+ _lineDropdownBtn->setImageLeft(0, posEndOfSelectedLineDesc );
+
+ _lineDropdownBtn->setImageLeft(1, posStartOfSelectedLineDesc - kFrameRectPaddingPx);
+ _lineDropdownBtn->setImageWidth(1, posEndOfSelectedLineDesc + kFrameRectPaddingPx - posStartOfSelectedLineDesc);
+
+ _lineDropdownBtn->draw(surface);
+// _lineDropdownBtn->drawTooltip(surface, _mouseX, _mouseY);
+
+ _lineSelectorFrameRect.moveTo(posStartOfSelectedLineDesc - kFrameRectPaddingPx, _lineSelectorFrameRect.top);
+ _lineSelectorFrameRect.setWidth(posEndOfSelectedLineDesc + kDropDownButtonShapeWidth + kFrameRectPaddingPx - posStartOfSelectedLineDesc);
+
+ _lineSelectorScrollBox->draw(surface);
+
+ int lineSelectorFrameRectTargetColor;
+ if (_lineSelectorScrollBox->isVisible()) {
+ lineSelectorFrameRectTargetColor = 10;
+ } else if (_lineSelectorFrameRectHasFocus) {
+ lineSelectorFrameRectTargetColor = 5;
+ } else {
+ lineSelectorFrameRectTargetColor = 0;
+ }
+
+ // Ensures animated transition of the frame's (outlining rectangle's) color to the new one
+ if (_lineSelectorFrameRectColor < lineSelectorFrameRectTargetColor) {
+ ++_lineSelectorFrameRectColor;
+ }
+
+ // Ensures animated transition of the frame's (outlining rectangle's) color to the new one
+ if (_lineSelectorFrameRectColor > lineSelectorFrameRectTargetColor) {
+ --_lineSelectorFrameRectColor;
+ }
+ surface.frameRect(_lineSelectorFrameRect,
+ surface.format.RGBToColor(kColors[_lineSelectorFrameRectColor].r,
+ kColors[_lineSelectorFrameRectColor].g,
+ kColors[_lineSelectorFrameRectColor].b));
+}
+
+void UIDropDown::show() {
+ _isVisible = true;
+}
+
+void UIDropDown::hide() {
+ _isVisible = false;
+}
+
+bool UIDropDown::isVisible() {
+ return _isVisible;
+}
+
+bool UIDropDown::isDropDownMenuExpanded() {
+ return _lineSelectorScrollBox->isVisible();
+}
+
+void UIDropDown::clearLines() {
+ _lineSelectorScrollBox->clearLines();
+ _lineSelectorScrollBoxMaxLineWidth = 0;
+}
+
+void UIDropDown::addLine(const Common::String &text, int lineData) {
+ _lineSelectorScrollBox->addLine(text, lineData, 0x08);
+ _lineSelectorScrollBoxMaxLineWidth = MAX(_vm->_mainFont->getStringWidth(text), _lineSelectorScrollBoxMaxLineWidth);
+}
+
+void UIDropDown::addLine(const char *text, int lineData) {
+ _lineSelectorScrollBox->addLine(text, lineData, 0x08);
+ _lineSelectorScrollBoxMaxLineWidth = MAX(_vm->_mainFont->getStringWidth(text), _lineSelectorScrollBoxMaxLineWidth);
+}
+
+void UIDropDown::sortLines() {
+ _lineSelectorScrollBox->sortLines();
+}
+
+void UIDropDown::handleMouseMove(int mouseX, int mouseY) {
+ if (!_isVisible) {
+ return;
+ }
+
+ _mouseX = mouseX;
+ _mouseY = mouseY;
+
+ // contains() does not include right or bottom boundary "line"
+ if (_lineSelectorFrameRect.contains(mouseX, mouseY)) {
+ if (!_lineSelectorFrameRectHasFocus && !_lineSelectorScrollBox->isVisible()) {
+ _vm->_audioPlayer->playAud(_vm->_gameInfo->getSfxTrack(kSfxTEXT3), 100, 0, 0, 50, 0);
+ }
+ _lineSelectorFrameRectHasFocus = true;
+ } else {
+ _lineSelectorFrameRectHasFocus = false;
+ }
+
+ _lineSelectorScrollBox->handleMouseMove(mouseX, mouseY);
+ _lineDropdownBtn->handleMouseAction(mouseX, mouseY, false, false, false);
+}
+
+void UIDropDown::handleMouseDown(bool alternateButton) {
+ if (!_isVisible) {
+ return;
+ }
+
+ if (!alternateButton) {
+ _lineSelectorScrollBox->handleMouseDown(false);
+ _lineDropdownBtn->handleMouseAction(_mouseX, _mouseY, true, false, false);
+ if (!_lineSelectorFrameRectHasFocus
+ && _lineSelectorScrollBox->isVisible()
+ && !_lineSelectorScrollBox->hasFocus()
+ ) {
+ _ddlCancelledCallback(_callbackData, this);
+ showSelectionDropdown(false);
+ }
+ }
+}
+
+void UIDropDown::handleMouseScroll(int direction) {
+ if (!_isVisible) {
+ return;
+ }
+
+ if (_lineSelectorScrollBox->isVisible()) {
+ _lineSelectorScrollBox->handleMouseScroll(direction);
+ }
+}
+
+void UIDropDown::handleMouseUp(bool alternateButton) {
+ if (!_isVisible) {
+ return;
+ }
+
+ if (!alternateButton) {
+ _lineSelectorScrollBox->handleMouseUp(false);
+ _lineDropdownBtn->handleMouseAction(_mouseX, _mouseY, false, true, false);
+ }
+}
+
+void UIDropDown::scrollBoxLineSelectCallback(void *callbackData, void *source, int lineData, int mouseButton) {
+ UIDropDown *self = (UIDropDown *)callbackData;
+
+ if (source == self->_lineSelectorScrollBox && lineData >= 0) {
+ Common::String selectedLangDescStr = self->_lineSelectorScrollBox->getLineText(lineData);
+ self->_lineSelectedId = lineData;
+ self->_lineSelectedStr = selectedLangDescStr;
+ self->_vm->_audioPlayer->playAud(self->_vm->_gameInfo->getSfxTrack(kSfxELECBP1), 90, 0, 0, 50, 0);
+ self->_ddlLineSelectedCallback(self->_callbackData, self, lineData, mouseButton);
+ self->showSelectionDropdown(false);
+ //debug("text selected: %s", selectedLangDescStr.c_str());
+ }
+}
+
+// Callback from _lineDropdownBtn items
+void UIDropDown::mouseDownLDBCallback(int buttonId, void *callbackData) {
+ UIDropDown *self = (UIDropDown *)callbackData;
+ self->onButtonPressed(buttonId);
+}
+
+void UIDropDown::onButtonPressed(int buttonId) {
+ switch (buttonId) {
+ case 0:
+ // Pressed DDL dropdown button (0)
+ // fall through
+ case 1:
+// if (buttonId == 1) {
+// // Pressed DDL clickable area (1)
+// debug("Pressed DDL clickable area (1)");
+// }
+ _ddlTopFrameClickCallback(_callbackData, this);
+ showSelectionDropdown(!_lineSelectorScrollBox->isVisible());
+ break;
+ default:
+ return;
+ }
+}
+
+void UIDropDown::showSelectionDropdown(bool showToggle) {
+ int prevDropdownBtnLeft = _lineDropdownBtn->getImageLeft(0);
+ if (showToggle) {
+ _lineSelectorScrollBox->setBoxTop(_lineSelectorFrameRect.bottom);
+ _lineSelectorScrollBox->setBoxLeft(_lineDropdownBtn->getImageLeft(1));
+ // TODO width should be retrieved from the maximum width of a language description in SUBTITLES.MIX (or a max width to clip to)
+ _lineSelectorScrollBox->setBoxWidth(MAX(_lineDropdownBtn->getImageWidth(1), _lineSelectorScrollBoxMaxLineWidth + _vm->_mainFont->getCharWidth(' ')));
+
+ if (_lineDropdownBtn->getImageLeft(0) < kFurthestLeftForScrollBar) {
+ // CLIP expects the first boundary argument to be the min of the two.
+ _lineSelectorScrollBox->setScrollbarLeft(CLIP( _lineSelectorScrollBox->getBoxLeft() + _lineSelectorScrollBox->getBoxWidth(), _lineDropdownBtn->getImageLeft(0), kFurthestLeftForScrollBar));
+ } else {
+ _lineSelectorScrollBox->setScrollbarLeft(MAX( _lineSelectorScrollBox->getBoxLeft() + _lineSelectorScrollBox->getBoxWidth(), kFurthestLeftForScrollBar));
+ }
+
+ _lineSelectorScrollBox->setScrollbarTop(_lineSelectorFrameRect.bottom);
+ _lineSelectorScrollBox->setScrollbarWidth(kDropDownButtonShapeWidth);
+ _lineSelectorScrollBox->show();
+ // change dropdown button icon too
+ _lineDropdownBtn->resetActiveImage(0);
+ _lineDropdownBtn->defineImage(0, Common::Rect(prevDropdownBtnLeft, _lineSelectorFrameRect.top + 1, prevDropdownBtnLeft + kDropDownButtonShapeWidth - 1, _lineSelectorFrameRect.bottom - 1), _vm->_kia->_shapes->get(70), _vm->_kia->_shapes->get(71), _vm->_kia->_shapes->get(72), nullptr);
+ _lineSelectorFrameRectColor = 10;
+ } else {
+ // hide scrollable area
+ _lineSelectorScrollBox->hide();
+ // change dropdown button icon too
+ _lineDropdownBtn->resetActiveImage(0);
+ _lineDropdownBtn->defineImage(0, Common::Rect(prevDropdownBtnLeft, _lineSelectorFrameRect.top + 1, prevDropdownBtnLeft + kDropDownButtonShapeWidth - 1, _lineSelectorFrameRect.bottom - 1), _vm->_kia->_shapes->get(73), _vm->_kia->_shapes->get(74), _vm->_kia->_shapes->get(75), nullptr);
+ _lineSelectorFrameRectColor = 0;
+ }
+}
+
+void UIDropDown::setLabelStr(Common::String newLabel) {
+ _labelStr = newLabel;
+}
+
+void UIDropDown::setControlLeft(int controlLeftX) {
+ _controlLeftX = controlLeftX;
+}
+
+Common::String UIDropDown::getLineSelectedStr() {
+ return _lineSelectedStr;
+}
+
+}
diff --git a/engines/bladerunner/ui/ui_dropdown.h b/engines/bladerunner/ui/ui_dropdown.h
new file mode 100644
index 0000000000..9a89ebee91
--- /dev/null
+++ b/engines/bladerunner/ui/ui_dropdown.h
@@ -0,0 +1,124 @@
+/* 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 BLADERUNNER_UI_DROPDOWN_H
+#define BLADERUNNER_UI_DROPDOWN_H
+
+#include "bladerunner/color.h"
+#include "bladerunner/ui/ui_component.h"
+
+#include "common/array.h"
+#include "common/rect.h"
+#include "common/str.h"
+
+namespace BladeRunner {
+
+class BladeRunnerEngine;
+class UIImagePicker;
+class UIScrollBox;
+
+typedef void UIDropDownLineSelectedCallback(void *callbackData, void *source, int data, int mouseButton);
+typedef void UIDropDownGenericCallback(void *callbackData, void *source);
+
+class UIDropDown : public UIComponent {
+
+ static const int kDropDownButtonShapeWidth = 15;
+ static const int kDropDownButtonShapeHeight = 10;
+ static const uint8 kFrameRectPaddingPx = 2;
+ static const int kFurthestLeftForScrollBar = 495;
+
+ static const Color256 kColors[];
+
+ int _controlLeftX;
+ Common::String _labelStr;
+
+ bool _isVisible;
+
+ int _lineSelectedId;
+ Common::String _lineSelectedStr;
+ UIScrollBox *_lineSelectorScrollBox;
+ UIImagePicker *_lineDropdownBtn;
+ int _lineDropdownBtnTopY;
+ int _lineDropdownBtnHeight;
+
+ Common::Rect _lineSelectorFrameRect;
+ int _lineSelectorFrameRectColor;
+ bool _lineSelectorFrameRectHasFocus;
+ int _lineSelectorScrollBoxMaxLineWidth;
+
+ UIDropDownLineSelectedCallback *_ddlLineSelectedCallback;
+ UIDropDownGenericCallback *_ddlCancelledCallback;
+ UIDropDownGenericCallback *_ddlTopFrameClickCallback;
+ void *_callbackData;
+
+ int _mouseX;
+ int _mouseY;
+
+public:
+ UIDropDown(BladeRunnerEngine *vm, UIDropDownLineSelectedCallback *ddlLineSelectedCallback,
+ UIDropDownGenericCallback *ddlCancelledCallback,
+ UIDropDownGenericCallback *ddlTopFrameClickCallback,
+ void *callbackData,
+ Common::String labelStr,
+ int controlLeftX,
+ int controlTopY,
+ int scrollBoxMaxLineCount);
+ ~UIDropDown() override;
+
+ void draw(Graphics::Surface &surface) override;
+
+ void handleMouseMove(int mouseX, int mouseY) override;
+ void handleMouseDown(bool alternateButton) override;
+ void handleMouseUp(bool alternateButton) override;
+ void handleMouseScroll(int direction) override;
+
+ void show();
+ void hide();
+ bool isVisible();
+ bool isDropDownMenuExpanded();
+
+ void activate();
+ void deactivate();
+
+ void clearLines();
+ void addLine(const Common::String &text, int lineData);
+ void addLine(const char *text, int lineData);
+
+ void sortLines();
+
+ void setLabelStr(Common::String newLabel);
+ void setControlLeft(int controlLeftX);
+
+ Common::String getLineSelectedStr();
+
+private:
+ static void mouseDownLDBCallback(int buttonId, void *callbackData);
+ static void scrollBoxLineSelectCallback(void *callbackData, void *source, int lineData, int mouseButton);
+
+ void onButtonPressed(int buttonId);
+
+ void showSelectionDropdown(bool showToggle);
+};
+
+} // End of namespace BladeRunner
+
+#endif
diff --git a/engines/bladerunner/ui/ui_image_picker.cpp b/engines/bladerunner/ui/ui_image_picker.cpp
index 7cdd50a62c..d6c01301f1 100644
--- a/engines/bladerunner/ui/ui_image_picker.cpp
+++ b/engines/bladerunner/ui/ui_image_picker.cpp
@@ -103,6 +103,18 @@ bool UIImagePicker::setImageLeft(int i, int left) {
return true;
}
+bool UIImagePicker::setImageWidth(int i, int16 width) {
+ if (i < 0 || i >= _imageCount || !_images[i].active) {
+ return false;
+ }
+
+ Image &img = _images[i];
+
+ img.rect.setWidth(width);
+
+ return true;
+}
+
bool UIImagePicker::setImageShapeUp(int i, const Shape *shapeUp) {
if (i < 0 || i >= _imageCount || !_images[i].active) {
return false;
@@ -147,6 +159,36 @@ bool UIImagePicker::setImageTooltip(int i, const char *tooltip) {
return true;
}
+int UIImagePicker::getImageTop(int i) {
+ if (i < 0 || i >= _imageCount || !_images[i].active) {
+ return false;
+ }
+
+ Image &img = _images[i];
+
+ return img.rect.top;
+}
+
+int UIImagePicker::getImageLeft(int i) {
+ if (i < 0 || i >= _imageCount || !_images[i].active) {
+ return false;
+ }
+
+ Image &img = _images[i];
+
+ return img.rect.left;
+}
+
+int UIImagePicker::getImageWidth(int i) {
+ if (i < 0 || i >= _imageCount || !_images[i].active) {
+ return false;
+ }
+
+ Image &img = _images[i];
+
+ return img.rect.width();
+}
+
bool UIImagePicker::resetActiveImage(int i) {
if (i < 0 || i >= _imageCount || !_images[i].active) {
return false;
diff --git a/engines/bladerunner/ui/ui_image_picker.h b/engines/bladerunner/ui/ui_image_picker.h
index 29d59ba68c..5d7bf5ddad 100644
--- a/engines/bladerunner/ui/ui_image_picker.h
+++ b/engines/bladerunner/ui/ui_image_picker.h
@@ -73,11 +73,16 @@ public:
bool setImageTop(int i, int top);
bool setImageLeft(int i, int left);
+ bool setImageWidth(int i, int16 width);
bool setImageShapeUp(int i, const Shape *shapeUp);
bool setImageShapeHovered(int i, const Shape *shapeHovered);
bool setImageShapeDown(int i, const Shape *shapeDown);
bool setImageTooltip(int i, const char *tooltip);
+ int getImageTop(int i);
+ int getImageLeft(int i);
+ int getImageWidth(int i);
+
bool resetActiveImage(int i);
void activate(UIImagePickerCallback *mouseInCallback,
diff --git a/engines/bladerunner/ui/ui_scroll_box.cpp b/engines/bladerunner/ui/ui_scroll_box.cpp
index b3b861e991..96ff857bf8 100644
--- a/engines/bladerunner/ui/ui_scroll_box.cpp
+++ b/engines/bladerunner/ui/ui_scroll_box.cpp
@@ -80,7 +80,15 @@ const Color256 UIScrollBox::kTextColors4[] = {
{ 248, 224, 144 }
};
-UIScrollBox::UIScrollBox(BladeRunnerEngine *vm, UIScrollBoxCallback *lineSelectedCallback, void *callbackData, int maxLineCount, int style, bool center, Common::Rect rect, Common::Rect scrollBarRect) : UIComponent(vm) {
+UIScrollBox::UIScrollBox(BladeRunnerEngine *vm,
+ UIScrollBoxClickedCallback *lineSelectedCallback,
+ void *callbackData,
+ int maxLineCount,
+ int style,
+ bool center,
+ Common::Rect rect,
+ Common::Rect scrollBarRect) : UIComponent(vm) {
+
_selectedLineState = 0;
_scrollUpButtonState = 0;
_scrollDownButtonState = 0;
@@ -101,7 +109,7 @@ UIScrollBox::UIScrollBox(BladeRunnerEngine *vm, UIScrollBoxCallback *lineSelecte
_callbackData = callbackData;
_isVisible = false;
- _style = style;
+ _style = style; // 0, 1 or (new) 2. "2" is similar to "1" but with solid background for main area and scroll bar
_center = center;
_timeLastScroll = _vm->_time->currentSystem();
_timeLastCheckbox = _vm->_time->currentSystem();
@@ -171,10 +179,52 @@ void UIScrollBox::hide() {
_isVisible = false;
}
+bool UIScrollBox::isVisible() {
+ return _isVisible;
+}
+
+bool UIScrollBox::hasFocus() {
+ return _mouseOver;
+}
+
+void UIScrollBox::setBoxTop(int top) {
+ _rect.moveTo(_rect.left, top);
+
+ _rect.bottom = _rect.top + kLineHeight * _maxLinesVisible - 1;
+}
+
+void UIScrollBox::setBoxLeft(int left) {
+ _rect.moveTo(left, _rect.top);
+}
+
+void UIScrollBox::setBoxWidth(uint16 width) {
+ _rect.setWidth(width);
+}
+
+int UIScrollBox::getBoxLeft() {
+ return _rect.left;
+}
+
+uint16 UIScrollBox::getBoxWidth() {
+ return _rect.width();
+}
+
+void UIScrollBox::setScrollbarTop(int top) {
+ _scrollBarRect.moveTo(_scrollBarRect.left, top);
+}
+
+void UIScrollBox::setScrollbarLeft(int left) {
+ _scrollBarRect.moveTo(left, _scrollBarRect.top);
+}
+
+void UIScrollBox::setScrollbarWidth(uint16 width) {
+ _scrollBarRect.setWidth(width);
+ _scrollBarRect.right += 15; // right side was not used, but it's useful for determining if the control is selected
+}
+
void UIScrollBox::clearLines() {
_lineCount = 0;
_firstLineVisible = 0;
-
}
void UIScrollBox::addLine(const Common::String &text, int lineData, int flags) {
@@ -378,7 +428,26 @@ int UIScrollBox::getSelectedLineData() {
return -1;
}
+Common::String UIScrollBox::getLineText(int lineData) {
+ if (hasLine(lineData)) {
+ return _lines[_hoveredLine]->text;
+ }
+ return "";
+}
+
+int UIScrollBox::getMaxLinesVisible() {
+ return _maxLinesVisible;
+}
+
+int UIScrollBox::getLineCount() {
+ return _lineCount;
+}
+
void UIScrollBox::draw(Graphics::Surface &surface) {
+ if (!_isVisible) {
+ return;
+ }
+
uint32 timeNow = _vm->_time->currentSystem();
// update scrolling
@@ -536,12 +605,22 @@ void UIScrollBox::draw(Graphics::Surface &surface) {
if (_lines[i]->flags & 0x08) { // has background rectangle
int colorBackground = 0;
- if (_style) {
+ if (_style == 2) {
+ colorBackground = surface.format.RGBToColor(kTextBackgroundColors[colorIndex].r / 8, kTextBackgroundColors[colorIndex].g / 8, kTextBackgroundColors[colorIndex].b / 8);
+ } else if (_style > 0) {
colorBackground = surface.format.RGBToColor(kTextBackgroundColors[colorIndex].r, kTextBackgroundColors[colorIndex].g, kTextBackgroundColors[colorIndex].b);
} else {
colorBackground = surface.format.RGBToColor(80, 56, 32);
}
- surface.fillRect(Common::Rect(x, y, _rect.right + 1, y1 + 1), colorBackground);
+
+ if (_style == 2) {
+ // New: style = 2 (original unused)
+ // original behavior -- No padding between the colored background of lines, simulate solid background (gradient)
+ surface.fillRect(Common::Rect(CLIP(x - 1, 0, 639), y, _rect.right + 1, y + kLineHeight), colorBackground);
+ } else {
+ // original behavior -- there is padding between the colored background of lines
+ surface.fillRect(Common::Rect(x, y, _rect.right + 1, y1 + 1), colorBackground);
+ }
}
if (_center) {
@@ -557,68 +636,79 @@ void UIScrollBox::draw(Graphics::Surface &surface) {
} while (i < lastLineVisible);
}
- // draw scroll up button
- int scrollUpButtonShapeId = 0;
- if (_scrollUpButtonState) {
- if (_scrollUpButtonState == 2) {
- if (_scrollUpButtonHover) {
- scrollUpButtonShapeId = 72;
+ if (_style == 2 && getLineCount() >= getMaxLinesVisible()) {
+ // New: style = 2 (original unused)
+ // Solid background color for scrollbar
+ int scrollBarFillColor = surface.format.RGBToColor(k3DFrameColors[0].r / 2, k3DFrameColors[0].g / 2, k3DFrameColors[0].b / 2);
+ surface.fillRect(Common::Rect(_scrollBarRect.left, _scrollBarRect.top, CLIP(_scrollBarRect.left + 15, 0, 639), _scrollBarRect.bottom), scrollBarFillColor);
+ }
+
+ if (_style != 2
+ || (_style == 2 && getLineCount() >= getMaxLinesVisible())
+ ) {
+ // draw scroll up button
+ int scrollUpButtonShapeId = 0;
+ if (_scrollUpButtonState) {
+ if (_scrollUpButtonState == 2) {
+ if (_scrollUpButtonHover) {
+ scrollUpButtonShapeId = 72;
+ } else {
+ scrollUpButtonShapeId = 71;
+ }
} else {
- scrollUpButtonShapeId = 71;
+ scrollUpButtonShapeId = 70;
}
+ } else if (_scrollUpButtonHover) {
+ scrollUpButtonShapeId = 71;
} else {
scrollUpButtonShapeId = 70;
}
- } else if (_scrollUpButtonHover) {
- scrollUpButtonShapeId = 71;
- } else {
- scrollUpButtonShapeId = 70;
- }
- _vm->_kia->_shapes->get(scrollUpButtonShapeId)->draw(surface, _scrollBarRect.left, _scrollBarRect.top);
-
- // draw scroll down button
- int scrollDownButtonShapeId = 0;
- if (_scrollDownButtonState) {
- if (_scrollDownButtonState == 2) {
- if (_scrollDownButtonHover) {
- scrollDownButtonShapeId = 75;
+ _vm->_kia->_shapes->get(scrollUpButtonShapeId)->draw(surface, _scrollBarRect.left, _scrollBarRect.top);
+
+ // draw scroll down button
+ int scrollDownButtonShapeId = 0;
+ if (_scrollDownButtonState) {
+ if (_scrollDownButtonState == 2) {
+ if (_scrollDownButtonHover) {
+ scrollDownButtonShapeId = 75;
+ } else {
+ scrollDownButtonShapeId = 74;
+ }
} else {
- scrollDownButtonShapeId = 74;
+ scrollDownButtonShapeId = 73;
}
+ } else if (_scrollDownButtonHover) {
+ scrollDownButtonShapeId = 74;
} else {
scrollDownButtonShapeId = 73;
}
- } else if (_scrollDownButtonHover) {
- scrollDownButtonShapeId = 74;
- } else {
- scrollDownButtonShapeId = 73;
- }
- _vm->_kia->_shapes->get(scrollDownButtonShapeId)->draw(surface, _scrollBarRect.left, _scrollBarRect.bottom - 7);
+ _vm->_kia->_shapes->get(scrollDownButtonShapeId)->draw(surface, _scrollBarRect.left, _scrollBarRect.bottom - 7);
- int scrollAreaSize = _scrollBarRect.bottom - (_scrollBarRect.top + 15);
- int scrollBarHeight = 0;
- if (_lineCount <= _maxLinesVisible) {
- scrollBarHeight = _scrollBarRect.bottom - (_scrollBarRect.top + 15);
- } else {
- scrollBarHeight = _maxLinesVisible * scrollAreaSize / _lineCount;
- }
- scrollBarHeight = MAX(scrollBarHeight, 16);
+ int scrollAreaSize = _scrollBarRect.bottom - (_scrollBarRect.top + 15);
+ int scrollBarHeight = 0;
+ if (_lineCount <= _maxLinesVisible) {
+ scrollBarHeight = _scrollBarRect.bottom - (_scrollBarRect.top + 15);
+ } else {
+ scrollBarHeight = _maxLinesVisible * scrollAreaSize / _lineCount;
+ }
+ scrollBarHeight = MAX(scrollBarHeight, 16);
- int v56 = 0;
- if (_lineCount <= _maxLinesVisible) {
- v56 = 0;
- } else {
- v56 = _firstLineVisible * (scrollAreaSize - scrollBarHeight) / (_lineCount - _maxLinesVisible);
- }
+ int v56 = 0;
+ if (_lineCount <= _maxLinesVisible) {
+ v56 = 0;
+ } else {
+ v56 = _firstLineVisible * (scrollAreaSize - scrollBarHeight) / (_lineCount - _maxLinesVisible);
+ }
- int v58 = v56 + _scrollBarRect.top + 8;
+ int v58 = v56 + _scrollBarRect.top + 8;
- if (_scrollBarState == 2) {
- draw3DFrame(surface, Common::Rect(_scrollBarRect.left, v58, _scrollBarRect.left + 15, v58 + scrollBarHeight), 1, 1);
- } else if (!_scrollBarState && _scrollBarHover) {
- draw3DFrame(surface, Common::Rect(_scrollBarRect.left, v56 + _scrollBarRect.top + 8, _scrollBarRect.left + 15, v58 + scrollBarHeight), 0, 1);
- } else {
- draw3DFrame(surface, Common::Rect(_scrollBarRect.left, v58, _scrollBarRect.left + 15, v58 + scrollBarHeight), 0, 0);
+ if (_scrollBarState == 2) {
+ draw3DFrame(surface, Common::Rect(_scrollBarRect.left, v58, _scrollBarRect.left + 15, v58 + scrollBarHeight), 1, 1);
+ } else if (!_scrollBarState && _scrollBarHover) {
+ draw3DFrame(surface, Common::Rect(_scrollBarRect.left, v56 + _scrollBarRect.top + 8, _scrollBarRect.left + 15, v58 + scrollBarHeight), 0, 1);
+ } else {
+ draw3DFrame(surface, Common::Rect(_scrollBarRect.left, v58, _scrollBarRect.left + 15, v58 + scrollBarHeight), 0, 0);
+ }
}
}
diff --git a/engines/bladerunner/ui/ui_scroll_box.h b/engines/bladerunner/ui/ui_scroll_box.h
index 1e2d0e5de9..bd32762b99 100644
--- a/engines/bladerunner/ui/ui_scroll_box.h
+++ b/engines/bladerunner/ui/ui_scroll_box.h
@@ -32,7 +32,7 @@
namespace BladeRunner {
-typedef void UIScrollBoxCallback(void *callbackData, void *source, int lineData, int mouseButton);
+typedef void UIScrollBoxClickedCallback(void *callbackData, void *source, int lineData, int mouseButton);
class UIScrollBox : public UIComponent {
static const int kLineHeight = 10;
@@ -68,8 +68,8 @@ class UIScrollBox : public UIComponent {
bool _mouseButton;
- UIScrollBoxCallback *_lineSelectedCallback;
- void *_callbackData;
+ UIScrollBoxClickedCallback *_lineSelectedCallback;
+ void *_callbackData;
bool _isVisible;
int _style;
@@ -93,7 +93,15 @@ class UIScrollBox : public UIComponent {
bool _mouseOver;
public:
- UIScrollBox(BladeRunnerEngine *vm, UIScrollBoxCallback *lineSelectedCallback, void *callbackData, int maxLineCount, int style, bool center, Common::Rect rect,Common::Rect scrollBarRect);
+ UIScrollBox(BladeRunnerEngine *vm,
+ UIScrollBoxClickedCallback *lineSelectedCallback,
+ void *callbackData,
+ int maxLineCount,
+ int style,
+ bool center,
+ Common::Rect rect,
+ Common::Rect scrollBarRect);
+
~UIScrollBox() override;
void draw(Graphics::Surface &surface) override;
@@ -105,6 +113,19 @@ public:
void show();
void hide();
+ bool isVisible();
+ bool hasFocus();
+
+ void setBoxTop(int top);
+ void setBoxLeft(int left);
+ void setBoxWidth(uint16 width);
+ void setScrollbarTop(int top);
+ void setScrollbarLeft(int left);
+ void setScrollbarWidth(uint16 width);
+
+ int getBoxLeft();
+ uint16 getBoxWidth();
+
void clearLines();
void addLine(const Common::String &text, int lineData, int flags);
@@ -112,6 +133,9 @@ public:
void sortLines();
int getSelectedLineData();
+ Common::String getLineText(int lineData);
+ int getMaxLinesVisible();
+ int getLineCount();
void checkAll();
void uncheckAll();
diff --git a/engines/bladerunner/ui/ui_slider.cpp b/engines/bladerunner/ui/ui_slider.cpp
index e8fc73568c..a3eb18d6ec 100644
--- a/engines/bladerunner/ui/ui_slider.cpp
+++ b/engines/bladerunner/ui/ui_slider.cpp
@@ -30,19 +30,19 @@
namespace BladeRunner {
const Color256 UISlider::kColors[] = {
- { 0, 0, 0 },
- { 16, 8, 8 },
- { 32, 24, 8 },
- { 56, 32, 16 },
- { 72, 48, 16 },
- { 88, 56, 24 },
- { 104, 72, 32 },
- { 128, 80, 40 },
- { 136, 96, 48 },
- { 152, 112, 56 },
- { 168, 128, 72 },
- { 184, 144, 88 },
- { 200, 160, 96 },
+ { 0, 0, 0 }, // Black - unpressed (framing rectange)
+ { 16, 8, 8 },
+ { 32, 24, 8 },
+ { 56, 32, 16 },
+ { 72, 48, 16 },
+ { 88, 56, 24 }, // Mouse-over (framing rectange)
+ { 104, 72, 32 },
+ { 128, 80, 40 },
+ { 136, 96, 48 },
+ { 152, 112, 56 },
+ { 168, 128, 72 }, // Pressed (framing rectange)
+ { 184, 144, 88 },
+ { 200, 160, 96 },
{ 216, 184, 112 },
{ 232, 200, 128 },
{ 240, 224, 144 }
@@ -79,10 +79,12 @@ void UISlider::draw(Graphics::Surface &surface) {
frameColor = 0;
}
+ // Ensures animated transition of the frame's (outlining rectangle's) color to the new one
if (_currentFrameColor < frameColor) {
++_currentFrameColor;
}
+ // Ensures animated transition of the frame's (outlining rectangle's) color to the new one
if (_currentFrameColor > frameColor) {
--_currentFrameColor;
}
More information about the Scummvm-git-logs
mailing list