GUI: Implement dirty-checking for widget redraws

This commit is contained in:
Bastien Bouclet 2018-01-06 14:40:02 +01:00
parent 3b50b57f54
commit 0496ede62f
34 changed files with 245 additions and 199 deletions

View file

@ -267,7 +267,7 @@ void RemapDialog::startRemapping(uint i) {
_remapTimeout = g_system->getMillis() + kRemapTimeoutDelay; _remapTimeout = g_system->getMillis() + kRemapTimeoutDelay;
Action *activeRemapAction = _currentActions[_topAction + i].action; Action *activeRemapAction = _currentActions[_topAction + i].action;
_keymapWidgets[i].keyButton->setLabel("..."); _keymapWidgets[i].keyButton->setLabel("...");
_keymapWidgets[i].keyButton->draw(); _keymapWidgets[i].keyButton->markAsDirty();
_keymapper->startRemappingMode(activeRemapAction); _keymapper->startRemappingMode(activeRemapAction);
} }
@ -414,8 +414,8 @@ void RemapDialog::refreshKeymap() {
_topAction = newTopAction; _topAction = newTopAction;
//_container->draw(); //_container->markAsDirty();
_scrollBar->draw(); _scrollBar->markAsDirty();
uint actionI = _topAction; uint actionI = _topAction;
@ -446,12 +446,12 @@ void RemapDialog::refreshKeymap() {
widg.keyButton->setVisible(false); widg.keyButton->setVisible(false);
widg.clearButton->setVisible(false); widg.clearButton->setVisible(false);
} }
//widg.actionText->draw(); //widg.actionText->markAsDirty();
//widg.keyButton->draw(); //widg.keyButton->markAsDirty();
} }
// need to redraw entire Dialog so that invisible // need to redraw entire Dialog so that invisible
// widgets disappear // widgets disappear
draw(); markAsDirty();
} }

View file

@ -82,7 +82,7 @@ void KeysDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) {
selection = Common::String::format(_("Associated key : none")); selection = Common::String::format(_("Associated key : none"));
_keyMapping->setLabel(selection); _keyMapping->setLabel(selection);
_keyMapping->draw(); _keyMapping->markAsDirty();
} }
break; break;
case kMapCmd: case kMapCmd:
@ -105,11 +105,11 @@ void KeysDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) {
_actionTitle->setLabel(_("Press the key to associate")); _actionTitle->setLabel(_("Press the key to associate"));
_keyMapping->setLabel(selection); _keyMapping->setLabel(selection);
_keyMapping->draw(); _keyMapping->markAsDirty();
Actions::Instance()->beginMapping(true); Actions::Instance()->beginMapping(true);
_actionsList->setEnabled(false); _actionsList->setEnabled(false);
} }
_actionTitle->draw(); _actionTitle->markAsDirty();
break; break;
case kOKCmd: case kOKCmd:
Actions::Instance()->saveMapping(); Actions::Instance()->saveMapping();
@ -144,8 +144,8 @@ void KeysDialog::handleKeyUp(Common::KeyState state) {
_actionTitle->setLabel(_("Choose an action to map")); _actionTitle->setLabel(_("Choose an action to map"));
_keyMapping->setLabel(selection); _keyMapping->setLabel(selection);
_keyMapping->draw(); _keyMapping->markAsDirty();
_actionTitle->draw(); _actionTitle->markAsDirty();
_actionSelected = -1; _actionSelected = -1;
_actionsList->setEnabled(true); _actionsList->setEnabled(true);
Actions::Instance()->beginMapping(false); Actions::Instance()->beginMapping(false);

View file

@ -191,7 +191,7 @@ void BrowserDialog::updateListing() {
_fileList->scrollTo(0); _fileList->scrollTo(0);
// Finally, redraw // Finally, redraw
draw(); markAsDirty();
} }
} // End of namespace GUI } // End of namespace GUI

View file

@ -64,7 +64,7 @@ void ChooserDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data
break; break;
case kListSelectionChangedCmd: case kListSelectionChangedCmd:
_chooseButton->setEnabled(item >= 0); _chooseButton->setEnabled(item >= 0);
_chooseButton->draw(); _chooseButton->markAsDirty();
break; break;
case kCloseCmd: case kCloseCmd:
setResult(-1); setResult(-1);

View file

@ -173,6 +173,7 @@ void ConsoleDialog::drawDialog() {
drawLine(line, false); drawLine(line, false);
// Draw the scrollbar // Draw the scrollbar
_scrollBar->markAsDirty();
_scrollBar->draw(); _scrollBar->draw();
} }
@ -213,7 +214,7 @@ void ConsoleDialog::reflowLayout() {
updateScrollBuffer(); updateScrollBuffer();
Dialog::reflowLayout(); Dialog::reflowLayout();
draw(); markAsDirty();
} }
void ConsoleDialog::handleTickle() { void ConsoleDialog::handleTickle() {
@ -236,13 +237,13 @@ void ConsoleDialog::handleTickle() {
// End the slide // End the slide
_slideMode = kNoSlideMode; _slideMode = kNoSlideMode;
_y = 0; _y = 0;
draw(); markAsDirty();
} else if (_slideMode == kUpSlideMode && _y <= -_h) { } else if (_slideMode == kUpSlideMode && _y <= -_h) {
// End the slide // End the slide
//_slideMode = kNoSlideMode; //_slideMode = kNoSlideMode;
close(); close();
} else } else
draw(); markAsDirty();
} }
_scrollBar->handleTickle(); _scrollBar->handleTickle();
@ -291,7 +292,7 @@ void ConsoleDialog::handleKeyDown(Common::KeyState state) {
print(PROMPT); print(PROMPT);
_promptStartPos = _promptEndPos = _currentPos; _promptStartPos = _promptEndPos = _currentPos;
draw(); markAsDirty();
if (!keepRunning) if (!keepRunning)
slideUpAndClose(); slideUpAndClose();
break; break;
@ -376,7 +377,7 @@ void ConsoleDialog::handleKeyDown(Common::KeyState state) {
} else { } else {
_currentPos = _promptEndPos; _currentPos = _promptEndPos;
} }
draw(); markAsDirty();
break; break;
case Common::KEYCODE_KP2: case Common::KEYCODE_KP2:
@ -404,7 +405,7 @@ void ConsoleDialog::handleKeyDown(Common::KeyState state) {
_scrollLine = _firstLineInBuffer + _linesPerPage - 1; _scrollLine = _firstLineInBuffer + _linesPerPage - 1;
} }
updateScrollBuffer(); updateScrollBuffer();
draw(); markAsDirty();
} }
break; break;
@ -445,7 +446,7 @@ void ConsoleDialog::handleKeyDown(Common::KeyState state) {
} else { } else {
_currentPos = _promptStartPos; _currentPos = _promptStartPos;
} }
draw(); markAsDirty();
break; break;
case Common::KEYCODE_KP8: case Common::KEYCODE_KP8:
@ -470,7 +471,7 @@ void ConsoleDialog::handleKeyDown(Common::KeyState state) {
if (_scrollLine < _firstLineInBuffer + _linesPerPage - 1) if (_scrollLine < _firstLineInBuffer + _linesPerPage - 1)
_scrollLine = _firstLineInBuffer + _linesPerPage - 1; _scrollLine = _firstLineInBuffer + _linesPerPage - 1;
updateScrollBuffer(); updateScrollBuffer();
draw(); markAsDirty();
} }
break; break;
@ -507,7 +508,7 @@ void ConsoleDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data
int newPos = (int)data + _linesPerPage - 1 + _firstLineInBuffer; int newPos = (int)data + _linesPerPage - 1 + _firstLineInBuffer;
if (newPos != _scrollLine) { if (newPos != _scrollLine) {
_scrollLine = newPos; _scrollLine = newPos;
draw(); markAsDirty();
} }
break; break;
} }
@ -517,25 +518,25 @@ void ConsoleDialog::specialKeys(int keycode) {
switch (keycode) { switch (keycode) {
case Common::KEYCODE_a: case Common::KEYCODE_a:
_currentPos = _promptStartPos; _currentPos = _promptStartPos;
draw(); markAsDirty();
break; break;
case Common::KEYCODE_d: case Common::KEYCODE_d:
if (_currentPos < _promptEndPos) { if (_currentPos < _promptEndPos) {
killChar(); killChar();
draw(); markAsDirty();
} }
break; break;
case Common::KEYCODE_e: case Common::KEYCODE_e:
_currentPos = _promptEndPos; _currentPos = _promptEndPos;
draw(); markAsDirty();
break; break;
case Common::KEYCODE_k: case Common::KEYCODE_k:
killLine(); killLine();
draw(); markAsDirty();
break; break;
case Common::KEYCODE_w: case Common::KEYCODE_w:
killLastWord(); killLastWord();
draw(); markAsDirty();
break; break;
} }
} }
@ -625,7 +626,7 @@ void ConsoleDialog::historyScroll(int direction) {
// Ensure once more the caret is visible (in case of very long history entries) // Ensure once more the caret is visible (in case of very long history entries)
scrollToCurrent(); scrollToCurrent();
draw(); markAsDirty();
} }
void ConsoleDialog::nextLine() { void ConsoleDialog::nextLine() {
@ -703,7 +704,7 @@ void ConsoleDialog::print(const char *str) {
while (*str) while (*str)
printCharIntern(*str++); printCharIntern(*str++);
draw(); markAsDirty();
} }
void ConsoleDialog::drawCaret(bool erase) { void ConsoleDialog::drawCaret(bool erase) {
@ -732,7 +733,7 @@ void ConsoleDialog::scrollToCurrent() {
} else if (line > _scrollLine) { } else if (line > _scrollLine) {
_scrollLine = line; _scrollLine = line;
updateScrollBuffer(); updateScrollBuffer();
draw(); markAsDirty();
} }
} }

View file

@ -153,7 +153,7 @@ void Dialog::releaseFocus() {
} }
} }
void Dialog::draw() { void Dialog::markAsDirty() {
//TANOKU - FIXME when is this enabled? what does this do? //TANOKU - FIXME when is this enabled? what does this do?
// Update: called on tab drawing, mainly... // Update: called on tab drawing, mainly...
// we can pass this as open a new dialog or something // we can pass this as open a new dialog or something
@ -161,6 +161,14 @@ void Dialog::draw() {
g_gui._redrawStatus = GUI::GuiManager::kRedrawTopDialog; g_gui._redrawStatus = GUI::GuiManager::kRedrawTopDialog;
} }
void Dialog::markWidgetsAsDirty() {
Widget *w = _firstWidget;
while (w) {
w->markAsDirty();
w = w->_next;
}
}
void Dialog::drawDialog() { void Dialog::drawDialog() {
if (!isVisible()) if (!isVisible())
@ -168,6 +176,15 @@ void Dialog::drawDialog() {
g_gui.theme()->drawDialogBackground(Common::Rect(_x, _y, _x+_w, _y+_h), _backgroundType); g_gui.theme()->drawDialogBackground(Common::Rect(_x, _y, _x+_w, _y+_h), _backgroundType);
markWidgetsAsDirty();
drawWidgets();
}
void Dialog::drawWidgets() {
if (!isVisible())
return;
// Draw all children // Draw all children
Widget *w = _firstWidget; Widget *w = _firstWidget;
while (w) { while (w) {

View file

@ -88,9 +88,16 @@ protected:
virtual void open(); virtual void open();
virtual void close(); virtual void close();
virtual void draw(); void markAsDirty() override;
/** Recursively mark all the widgets in this dialog as dirty so they are redrawn */
void markWidgetsAsDirty();
/** Draw the dialog in its entirety (background and widgets) */
virtual void drawDialog(); virtual void drawDialog();
/** Draw only the dialog's widgets */
void drawWidgets();
virtual void handleTickle(); // Called periodically (in every guiloop() ) virtual void handleTickle(); // Called periodically (in every guiloop() )
virtual void handleMouseDown(int x, int y, int button, int clickCount); virtual void handleMouseDown(int x, int y, int button, int clickCount);
virtual void handleMouseUp(int x, int y, int button, int clickCount); virtual void handleMouseUp(int x, int y, int button, int clickCount);

View file

@ -81,7 +81,7 @@ void DownloadDialog::open() {
if (!selectDirectories()) if (!selectDirectories())
close(); close();
reflowLayout(); reflowLayout();
draw(); markAsDirty();
} }
void DownloadDialog::close() { void DownloadDialog::close() {
@ -101,7 +101,7 @@ void DownloadDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 dat
case kDownloadProgressCmd: case kDownloadProgressCmd:
if (!_close) { if (!_close) {
refreshWidgets(); refreshWidgets();
draw(); markAsDirty();
} }
break; break;
case kDownloadEndedCmd: case kDownloadEndedCmd:
@ -196,7 +196,7 @@ void DownloadDialog::handleTickle() {
int32 progress = (int32)(100 * CloudMan.getDownloadingProgress()); int32 progress = (int32)(100 * CloudMan.getDownloadingProgress());
if (_progressBar->getValue() != progress) { if (_progressBar->getValue() != progress) {
refreshWidgets(); refreshWidgets();
draw(); markAsDirty();
} }
Dialog::handleTickle(); Dialog::handleTickle();

View file

@ -424,26 +424,26 @@ void EditGameDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 dat
switch (cmd) { switch (cmd) {
case kCmdGlobalGraphicsOverride: case kCmdGlobalGraphicsOverride:
setGraphicSettingsState(data != 0); setGraphicSettingsState(data != 0);
draw(); markAsDirty();
break; break;
case kCmdGlobalAudioOverride: case kCmdGlobalAudioOverride:
setAudioSettingsState(data != 0); setAudioSettingsState(data != 0);
setSubtitleSettingsState(data != 0); setSubtitleSettingsState(data != 0);
if (_globalVolumeOverride == NULL) if (_globalVolumeOverride == NULL)
setVolumeSettingsState(data != 0); setVolumeSettingsState(data != 0);
draw(); markAsDirty();
break; break;
case kCmdGlobalMIDIOverride: case kCmdGlobalMIDIOverride:
setMIDISettingsState(data != 0); setMIDISettingsState(data != 0);
draw(); markAsDirty();
break; break;
case kCmdGlobalMT32Override: case kCmdGlobalMT32Override:
setMT32SettingsState(data != 0); setMT32SettingsState(data != 0);
draw(); markAsDirty();
break; break;
case kCmdGlobalVolumeOverride: case kCmdGlobalVolumeOverride:
setVolumeSettingsState(data != 0); setVolumeSettingsState(data != 0);
draw(); markAsDirty();
break; break;
case kCmdChooseSoundFontCmd: case kCmdChooseSoundFontCmd:
{ {
@ -459,7 +459,7 @@ void EditGameDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 dat
else else
_soundFontClearButton->setEnabled(false); _soundFontClearButton->setEnabled(false);
draw(); markAsDirty();
} }
break; break;
} }
@ -477,9 +477,9 @@ void EditGameDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 dat
// FSList files = dir.listDir(FSNode::kListFilesOnly); // FSList files = dir.listDir(FSNode::kListFilesOnly);
_gamePathWidget->setLabel(dir.getPath()); _gamePathWidget->setLabel(dir.getPath());
draw(); markAsDirty();
} }
draw(); markAsDirty();
break; break;
} }
@ -491,9 +491,9 @@ void EditGameDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 dat
// User made his choice... // User made his choice...
Common::FSNode dir(browser.getResult()); Common::FSNode dir(browser.getResult());
_extraPathWidget->setLabel(dir.getPath()); _extraPathWidget->setLabel(dir.getPath());
draw(); markAsDirty();
} }
draw(); markAsDirty();
break; break;
} }
// Change path for stored save game (perm and temp) data // Change path for stored save game (perm and temp) data
@ -508,9 +508,9 @@ void EditGameDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 dat
MessageDialog warningMessage(_("Saved games sync feature doesn't work with non-default directories. If you want your saved games to sync, use default directory.")); MessageDialog warningMessage(_("Saved games sync feature doesn't work with non-default directories. If you want your saved games to sync, use default directory."));
warningMessage.runModal(); warningMessage.runModal();
#endif #endif
draw(); markAsDirty();
} }
draw(); markAsDirty();
break; break;
} }

View file

@ -88,7 +88,7 @@ void FileBrowserDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32
break; break;
case kListSelectionChangedCmd: case kListSelectionChangedCmd:
_fileName->setEditString(_fileList->getList().operator[](_fileList->getSelected()).c_str()); _fileName->setEditString(_fileList->getList().operator[](_fileList->getSelected()).c_str());
_fileName->draw(); _fileName->markAsDirty();
break; break;
case kListItemActivatedCmd: case kListItemActivatedCmd:
case kListItemDoubleClickedCmd: case kListItemDoubleClickedCmd:
@ -154,7 +154,7 @@ void FileBrowserDialog::updateListing() {
_fileList->scrollTo(0); _fileList->scrollTo(0);
// Finally, redraw // Finally, redraw
draw(); markAsDirty();
} }
} // End of namespace GUI } // End of namespace GUI

View file

@ -180,45 +180,45 @@ void FluidSynthSettingsDialog::handleCommand(CommandSender *sender, uint32 cmd,
break; break;
case kChorusVoiceCountChangedCmd: case kChorusVoiceCountChangedCmd:
_chorusVoiceCountLabel->setLabel(Common::String::format("%d", _chorusVoiceCountSlider->getValue())); _chorusVoiceCountLabel->setLabel(Common::String::format("%d", _chorusVoiceCountSlider->getValue()));
_chorusVoiceCountLabel->draw(); _chorusVoiceCountLabel->markAsDirty();
break; break;
case kChorusLevelChangedCmd: case kChorusLevelChangedCmd:
_chorusLevelLabel->setLabel(Common::String::format("%d", _chorusLevelSlider->getValue())); _chorusLevelLabel->setLabel(Common::String::format("%d", _chorusLevelSlider->getValue()));
_chorusLevelLabel->draw(); _chorusLevelLabel->markAsDirty();
break; break;
case kChorusSpeedChangedCmd: case kChorusSpeedChangedCmd:
_chorusSpeedLabel->setLabel(Common::String::format("%d", _chorusSpeedSlider->getValue())); _chorusSpeedLabel->setLabel(Common::String::format("%d", _chorusSpeedSlider->getValue()));
_chorusSpeedLabel->draw(); _chorusSpeedLabel->markAsDirty();
break; break;
case kChorusDepthChangedCmd: case kChorusDepthChangedCmd:
_chorusDepthLabel->setLabel(Common::String::format("%d", _chorusDepthSlider->getValue())); _chorusDepthLabel->setLabel(Common::String::format("%d", _chorusDepthSlider->getValue()));
_chorusDepthLabel->draw(); _chorusDepthLabel->markAsDirty();
break; break;
case kActivateReverbCmd: case kActivateReverbCmd:
setReverbSettingsState(data); setReverbSettingsState(data);
break; break;
case kReverbRoomSizeChangedCmd: case kReverbRoomSizeChangedCmd:
_reverbRoomSizeLabel->setLabel(Common::String::format("%d", _reverbRoomSizeSlider->getValue())); _reverbRoomSizeLabel->setLabel(Common::String::format("%d", _reverbRoomSizeSlider->getValue()));
_reverbRoomSizeLabel->draw(); _reverbRoomSizeLabel->markAsDirty();
break; break;
case kReverbDampingChangedCmd: case kReverbDampingChangedCmd:
_reverbDampingLabel->setLabel(Common::String::format("%d", _reverbDampingSlider->getValue())); _reverbDampingLabel->setLabel(Common::String::format("%d", _reverbDampingSlider->getValue()));
_reverbDampingLabel->draw(); _reverbDampingLabel->markAsDirty();
break; break;
case kReverbWidthChangedCmd: case kReverbWidthChangedCmd:
_reverbWidthLabel->setLabel(Common::String::format("%d", _reverbWidthSlider->getValue())); _reverbWidthLabel->setLabel(Common::String::format("%d", _reverbWidthSlider->getValue()));
_reverbWidthLabel->draw(); _reverbWidthLabel->markAsDirty();
break; break;
case kReverbLevelChangedCmd: case kReverbLevelChangedCmd:
_reverbLevelLabel->setLabel(Common::String::format("%d", _reverbLevelSlider->getValue())); _reverbLevelLabel->setLabel(Common::String::format("%d", _reverbLevelSlider->getValue()));
_reverbLevelLabel->draw(); _reverbLevelLabel->markAsDirty();
break; break;
case kResetSettingsCmd: { case kResetSettingsCmd: {
MessageDialog alert(_("Do you really want to reset all FluidSynth settings to their default values?"), _("Yes"), _("No")); MessageDialog alert(_("Do you really want to reset all FluidSynth settings to their default values?"), _("Yes"), _("No"));
if (alert.runModal() == GUI::kMessageOK) { if (alert.runModal() == GUI::kMessageOK) {
resetSettings(); resetSettings();
readSettings(); readSettings();
draw(); markAsDirty();
} }
break; break;
} }

View file

@ -208,7 +208,7 @@ bool GuiManager::loadNewTheme(Common::String id, ThemeEngine::GraphicsMode gfx,
void GuiManager::redraw() { void GuiManager::redraw() {
ThemeEngine::ShadingStyle shading; ThemeEngine::ShadingStyle shading;
if (_redrawStatus == kRedrawDisabled || _dialogStack.empty()) if (_dialogStack.empty())
return; return;
shading = (ThemeEngine::ShadingStyle)xmlEval()->getVar("Dialog." + _dialogStack.top()->_name + ".Shading", 0); shading = (ThemeEngine::ShadingStyle)xmlEval()->getVar("Dialog." + _dialogStack.top()->_name + ".Shading", 0);
@ -241,9 +241,12 @@ void GuiManager::redraw() {
break; break;
default: default:
return; break;
} }
// Redraw the widgets that are marked as dirty
_dialogStack.top()->drawWidgets();
_theme->updateScreen(); _theme->updateScreen();
_redrawStatus = kRedrawDisabled; _redrawStatus = kRedrawDisabled;
} }
@ -304,8 +307,6 @@ void GuiManager::runLoop() {
while (!_dialogStack.empty() && activeDialog == getTopDialog() && !eventMan->shouldQuit()) { while (!_dialogStack.empty() && activeDialog == getTopDialog() && !eventMan->shouldQuit()) {
uint32 frameStartTime = _system->getMillis(true); uint32 frameStartTime = _system->getMillis(true);
redraw();
// Don't "tickle" the dialog until the theme has had a chance // Don't "tickle" the dialog until the theme has had a chance
// to re-allocate buffers in case of a scaler change. // to re-allocate buffers in case of a scaler change.
@ -365,7 +366,7 @@ void GuiManager::runLoop() {
} }
} }
_theme->updateScreen(); redraw();
// Delay until the allocated frame time is elapsed to match the target frame rate // Delay until the allocated frame time is elapsed to match the target frame rate
uint32 actualFrameDuration = _system->getMillis(true) - frameStartTime; uint32 actualFrameDuration = _system->getMillis(true) - frameStartTime;

View file

@ -323,7 +323,7 @@ void LauncherDialog::addGame() {
selectTarget(newTarget); selectTarget(newTarget);
} }
draw(); markAsDirty();
} }
// We need to update the buttons here, so "Mass add" will revert to "Add game" // We need to update the buttons here, so "Mass add" will revert to "Add game"
@ -427,7 +427,7 @@ void LauncherDialog::removeGame(int item) {
// Update the ListWidget and force a redraw // Update the ListWidget and force a redraw
updateListing(); updateListing();
draw(); markAsDirty();
} }
} }
@ -452,7 +452,7 @@ void LauncherDialog::editGame(int item) {
// Update the ListWidget, reselect the edited game and force a redraw // Update the ListWidget, reselect the edited game and force a redraw
updateListing(); updateListing();
selectTarget(editDialog.getDomain()); selectTarget(editDialog.getDomain());
draw(); markAsDirty();
} }
} }
@ -614,7 +614,7 @@ bool LauncherDialog::doGameDetection(const Common::String &path) {
// Update the ListWidget, select the new item, and force a redraw // Update the ListWidget, select the new item, and force a redraw
updateListing(); updateListing();
selectTarget(editDialog.getDomain()); selectTarget(editDialog.getDomain());
draw(); markAsDirty();
} else { } else {
// User aborted, remove the the new domain again // User aborted, remove the the new domain again
ConfMan.removeGameDomain(domain); ConfMan.removeGameDomain(domain);
@ -688,15 +688,15 @@ void LauncherDialog::updateButtons() {
bool enable = (_list->getSelected() >= 0); bool enable = (_list->getSelected() >= 0);
if (enable != _startButton->isEnabled()) { if (enable != _startButton->isEnabled()) {
_startButton->setEnabled(enable); _startButton->setEnabled(enable);
_startButton->draw(); _startButton->markAsDirty();
} }
if (enable != _editButton->isEnabled()) { if (enable != _editButton->isEnabled()) {
_editButton->setEnabled(enable); _editButton->setEnabled(enable);
_editButton->draw(); _editButton->markAsDirty();
} }
if (enable != _removeButton->isEnabled()) { if (enable != _removeButton->isEnabled()) {
_removeButton->setEnabled(enable); _removeButton->setEnabled(enable);
_removeButton->draw(); _removeButton->markAsDirty();
} }
int item = _list->getSelected(); int item = _list->getSelected();
@ -707,7 +707,7 @@ void LauncherDialog::updateButtons() {
if (en != _loadButton->isEnabled()) { if (en != _loadButton->isEnabled()) {
_loadButton->setEnabled(en); _loadButton->setEnabled(en);
_loadButton->draw(); _loadButton->markAsDirty();
} }
switchButtonsText(_addButton, "~A~dd Game...", _s("Mass Add...")); switchButtonsText(_addButton, "~A~dd Game...", _s("Mass Add..."));
#ifdef ENABLE_EVENTRECORDER #ifdef ENABLE_EVENTRECORDER

View file

@ -30,7 +30,7 @@
namespace GUI { namespace GUI {
GuiObject::GuiObject(const Common::String &name) GuiObject::GuiObject(const Common::String &name)
: _x(-1000), _y(-1000), _w(0), _h(0), _name(name), _firstWidget(0), _textDrawableArea(Common::Rect(0, 0, 0, 0)) { : _x(-1000), _y(-1000), _w(0), _h(0), _name(name), _firstWidget(nullptr) {
reflowLayout(); reflowLayout();
} }

View file

@ -70,7 +70,7 @@ protected:
Widget *_firstWidget; Widget *_firstWidget;
public: public:
GuiObject(int x, int y, int w, int h) : _x(x), _y(y), _w(w), _h(h), _firstWidget(0), _textDrawableArea(Common::Rect(0, 0, 0, 0)) { } GuiObject(int x, int y, int w, int h) : _x(x), _y(y), _w(w), _h(h), _firstWidget(nullptr) { }
GuiObject(const Common::String &name); GuiObject(const Common::String &name);
~GuiObject(); ~GuiObject();
@ -87,7 +87,7 @@ public:
virtual bool isVisible() const = 0; virtual bool isVisible() const = 0;
virtual void draw() = 0; virtual void markAsDirty() = 0;
virtual void reflowLayout(); virtual void reflowLayout();

View file

@ -709,12 +709,12 @@ void OptionsDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data
switch (cmd) { switch (cmd) {
case kMidiGainChanged: case kMidiGainChanged:
_midiGainLabel->setLabel(Common::String::format("%.2f", (double)_midiGainSlider->getValue() / 100.0)); _midiGainLabel->setLabel(Common::String::format("%.2f", (double)_midiGainSlider->getValue() / 100.0));
_midiGainLabel->draw(); _midiGainLabel->markAsDirty();
break; break;
case kMusicVolumeChanged: { case kMusicVolumeChanged: {
const int newValue = _musicVolumeSlider->getValue(); const int newValue = _musicVolumeSlider->getValue();
_musicVolumeLabel->setValue(newValue); _musicVolumeLabel->setValue(newValue);
_musicVolumeLabel->draw(); _musicVolumeLabel->markAsDirty();
if (_guioptions.contains(GUIO_LINKMUSICTOSFX)) { if (_guioptions.contains(GUIO_LINKMUSICTOSFX)) {
updateSfxVolume(newValue); updateSfxVolume(newValue);
@ -729,7 +729,7 @@ void OptionsDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data
case kSfxVolumeChanged: { case kSfxVolumeChanged: {
const int newValue = _sfxVolumeSlider->getValue(); const int newValue = _sfxVolumeSlider->getValue();
_sfxVolumeLabel->setValue(_sfxVolumeSlider->getValue()); _sfxVolumeLabel->setValue(_sfxVolumeSlider->getValue());
_sfxVolumeLabel->draw(); _sfxVolumeLabel->markAsDirty();
if (_guioptions.contains(GUIO_LINKMUSICTOSFX)) { if (_guioptions.contains(GUIO_LINKMUSICTOSFX)) {
updateMusicVolume(newValue); updateMusicVolume(newValue);
@ -744,7 +744,7 @@ void OptionsDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data
case kSpeechVolumeChanged: { case kSpeechVolumeChanged: {
const int newValue = _speechVolumeSlider->getValue(); const int newValue = _speechVolumeSlider->getValue();
_speechVolumeLabel->setValue(newValue); _speechVolumeLabel->setValue(newValue);
_speechVolumeLabel->draw(); _speechVolumeLabel->markAsDirty();
if (_guioptions.contains(GUIO_LINKSPEECHTOSFX)) { if (_guioptions.contains(GUIO_LINKSPEECHTOSFX)) {
updateSfxVolume(newValue); updateSfxVolume(newValue);
@ -768,20 +768,20 @@ void OptionsDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data
break; break;
case kSubtitleSpeedChanged: case kSubtitleSpeedChanged:
_subSpeedLabel->setValue(_subSpeedSlider->getValue()); _subSpeedLabel->setValue(_subSpeedSlider->getValue());
_subSpeedLabel->draw(); _subSpeedLabel->markAsDirty();
break; break;
case kClearSoundFontCmd: case kClearSoundFontCmd:
_soundFont->setLabel(_c("None", "soundfont")); _soundFont->setLabel(_c("None", "soundfont"));
_soundFontClearButton->setEnabled(false); _soundFontClearButton->setEnabled(false);
draw(); markAsDirty();
break; break;
case kKbdMouseSpeedChanged: case kKbdMouseSpeedChanged:
_kbdMouseSpeedLabel->setLabel(_(kbdMouseSpeedLabels[_kbdMouseSpeedSlider->getValue()])); _kbdMouseSpeedLabel->setLabel(_(kbdMouseSpeedLabels[_kbdMouseSpeedSlider->getValue()]));
_kbdMouseSpeedLabel->draw(); _kbdMouseSpeedLabel->markAsDirty();
break; break;
case kJoystickDeadzoneChanged: case kJoystickDeadzoneChanged:
_joystickDeadzoneLabel->setValue(_joystickDeadzoneSlider->getValue()); _joystickDeadzoneLabel->setValue(_joystickDeadzoneSlider->getValue());
_joystickDeadzoneLabel->draw(); _joystickDeadzoneLabel->markAsDirty();
break; break;
case kApplyCmd: case kApplyCmd:
apply(); apply();
@ -1320,22 +1320,22 @@ int OptionsDialog::getSubtitleMode(bool subtitles, bool speech_mute) {
void OptionsDialog::updateMusicVolume(const int newValue) const { void OptionsDialog::updateMusicVolume(const int newValue) const {
_musicVolumeLabel->setValue(newValue); _musicVolumeLabel->setValue(newValue);
_musicVolumeSlider->setValue(newValue); _musicVolumeSlider->setValue(newValue);
_musicVolumeLabel->draw(); _musicVolumeLabel->markAsDirty();
_musicVolumeSlider->draw(); _musicVolumeSlider->markAsDirty();
} }
void OptionsDialog::updateSfxVolume(const int newValue) const { void OptionsDialog::updateSfxVolume(const int newValue) const {
_sfxVolumeLabel->setValue(newValue); _sfxVolumeLabel->setValue(newValue);
_sfxVolumeSlider->setValue(newValue); _sfxVolumeSlider->setValue(newValue);
_sfxVolumeLabel->draw(); _sfxVolumeLabel->markAsDirty();
_sfxVolumeSlider->draw(); _sfxVolumeSlider->markAsDirty();
} }
void OptionsDialog::updateSpeechVolume(const int newValue) const { void OptionsDialog::updateSpeechVolume(const int newValue) const {
_speechVolumeLabel->setValue(newValue); _speechVolumeLabel->setValue(newValue);
_speechVolumeSlider->setValue(newValue); _speechVolumeSlider->setValue(newValue);
_speechVolumeLabel->draw(); _speechVolumeLabel->markAsDirty();
_speechVolumeSlider->draw(); _speechVolumeSlider->markAsDirty();
} }
void OptionsDialog::reflowLayout() { void OptionsDialog::reflowLayout() {
@ -1936,7 +1936,7 @@ void GlobalOptionsDialog::handleCommand(CommandSender *sender, uint32 cmd, uint3
error.runModal(); error.runModal();
return; return;
} }
draw(); markAsDirty();
} }
break; break;
} }
@ -1946,7 +1946,7 @@ void GlobalOptionsDialog::handleCommand(CommandSender *sender, uint32 cmd, uint3
// User made his choice... // User made his choice...
Common::FSNode dir(browser.getResult()); Common::FSNode dir(browser.getResult());
_themePath->setLabel(dir.getPath()); _themePath->setLabel(dir.getPath());
draw(); markAsDirty();
} }
break; break;
} }
@ -1956,7 +1956,7 @@ void GlobalOptionsDialog::handleCommand(CommandSender *sender, uint32 cmd, uint3
// User made his choice... // User made his choice...
Common::FSNode dir(browser.getResult()); Common::FSNode dir(browser.getResult());
_extraPath->setLabel(dir.getPath()); _extraPath->setLabel(dir.getPath());
draw(); markAsDirty();
} }
break; break;
} }
@ -1967,7 +1967,7 @@ void GlobalOptionsDialog::handleCommand(CommandSender *sender, uint32 cmd, uint3
// User made his choice... // User made his choice...
Common::FSNode dir(browser.getResult()); Common::FSNode dir(browser.getResult());
_pluginsPath->setLabel(dir.getPath()); _pluginsPath->setLabel(dir.getPath());
draw(); markAsDirty();
} }
break; break;
} }
@ -1982,7 +1982,7 @@ void GlobalOptionsDialog::handleCommand(CommandSender *sender, uint32 cmd, uint3
if (path.empty()) if (path.empty())
path = "/"; // absolute root path = "/"; // absolute root
_rootPath->setLabel(path); _rootPath->setLabel(path);
draw(); markAsDirty();
} }
break; break;
} }
@ -2013,7 +2013,7 @@ void GlobalOptionsDialog::handleCommand(CommandSender *sender, uint32 cmd, uint3
else else
_soundFontClearButton->setEnabled(false); _soundFontClearButton->setEnabled(false);
draw(); markAsDirty();
} }
break; break;
} }
@ -2107,7 +2107,7 @@ void GlobalOptionsDialog::handleCommand(CommandSender *sender, uint32 cmd, uint3
if (_serverPort) { if (_serverPort) {
_serverPort->setEditString(Common::String::format("%u", Networking::LocalWebserver::DEFAULT_SERVER_PORT)); _serverPort->setEditString(Common::String::format("%u", Networking::LocalWebserver::DEFAULT_SERVER_PORT));
} }
draw(); markAsDirty();
break; break;
} }
#endif // USE_SDL_NET #endif // USE_SDL_NET
@ -2144,7 +2144,7 @@ void GlobalOptionsDialog::handleTickle() {
#endif #endif
if (_redrawCloudTab) { if (_redrawCloudTab) {
setupCloudTab(); setupCloudTab();
draw(); markAsDirty();
_redrawCloudTab = false; _redrawCloudTab = false;
} }
#endif #endif

View file

@ -995,7 +995,7 @@ void PredictiveDialog::pressEditText() {
Common::strlcat(_predictiveResult, _currentWord.c_str(), sizeof(_predictiveResult)); Common::strlcat(_predictiveResult, _currentWord.c_str(), sizeof(_predictiveResult));
_editText->setEditString(_predictiveResult); _editText->setEditString(_predictiveResult);
//_editText->setCaretPos(_prefix.size() + _currentWord.size()); //_editText->setCaretPos(_prefix.size() + _currentWord.size());
_editText->draw(); _editText->markAsDirty();
} }
} // namespace GUI } // namespace GUI

View file

@ -211,7 +211,7 @@ void RecorderDialog::updateList() {
file.close(); file.close();
} }
_list->setList(namesList); _list->setList(namesList);
_list->draw(); _list->markAsDirty();
} }
int RecorderDialog::runModal(Common::String &target) { int RecorderDialog::runModal(Common::String &target) {
@ -253,7 +253,7 @@ void RecorderDialog::updateSelection(bool redraw) {
_screenShotsCount = -1; _screenShotsCount = -1;
_currentScreenshot = 0; _currentScreenshot = 0;
_gfxWidget->setGfx(-1, -1, 0, 0, 0); _gfxWidget->setGfx(-1, -1, 0, 0, 0);
_gfxWidget->draw(); _gfxWidget->markAsDirty();
updateScreenShotsText(); updateScreenShotsText();
} }
} }
@ -283,7 +283,7 @@ void RecorderDialog::updateScreenshot() {
} else { } else {
_gfxWidget->setGfx(-1, -1, 0, 0, 0); _gfxWidget->setGfx(-1, -1, 0, 0, 0);
} }
_gfxWidget->draw(); _gfxWidget->markAsDirty();
} }
void RecorderDialog::updateScreenShotsText() { void RecorderDialog::updateScreenShotsText() {

View file

@ -162,7 +162,7 @@ void RemoteBrowserDialog::updateListing() {
_fileList->setEnabled(!_navigationLocked); _fileList->setEnabled(!_navigationLocked);
// Finally, redraw // Finally, redraw
draw(); markAsDirty();
} }
void RemoteBrowserDialog::goUp() { void RemoteBrowserDialog::goUp() {

View file

@ -60,7 +60,7 @@ SaveLoadCloudSyncProgressDialog::SaveLoadCloudSyncProgressDialog(bool canRunInBa
new ButtonWidget(this, "SaveLoadCloudSyncProgress.Cancel", "Cancel", 0, kCancelSyncCmd, Common::ASCII_ESCAPE); // Cancel dialog new ButtonWidget(this, "SaveLoadCloudSyncProgress.Cancel", "Cancel", 0, kCancelSyncCmd, Common::ASCII_ESCAPE); // Cancel dialog
ButtonWidget *backgroundButton = new ButtonWidget(this, "SaveLoadCloudSyncProgress.Background", "Run in background", 0, kBackgroundSyncCmd, Common::ASCII_RETURN); // Confirm dialog ButtonWidget *backgroundButton = new ButtonWidget(this, "SaveLoadCloudSyncProgress.Background", "Run in background", 0, kBackgroundSyncCmd, Common::ASCII_RETURN); // Confirm dialog
backgroundButton->setEnabled(canRunInBackground); backgroundButton->setEnabled(canRunInBackground);
draw(); markAsDirty();
} }
SaveLoadCloudSyncProgressDialog::~SaveLoadCloudSyncProgressDialog() { SaveLoadCloudSyncProgressDialog::~SaveLoadCloudSyncProgressDialog() {
@ -72,7 +72,7 @@ void SaveLoadCloudSyncProgressDialog::handleCommand(CommandSender *sender, uint3
case kSavesSyncProgressCmd: case kSavesSyncProgressCmd:
_percentLabel->setLabel(Common::String::format("%u%%", data)); _percentLabel->setLabel(Common::String::format("%u%%", data));
_progressBar->setValue(data); _progressBar->setValue(data);
_progressBar->draw(); _progressBar->markAsDirty();
break; break;
case kCancelSyncCmd: case kCancelSyncCmd:
@ -594,14 +594,14 @@ void SaveLoadChooserSimple::updateSelection(bool redraw) {
_deleteButton->setEnabled(isDeletable && !isLocked && (selItem >= 0) && (!_list->getSelectedString().empty())); _deleteButton->setEnabled(isDeletable && !isLocked && (selItem >= 0) && (!_list->getSelectedString().empty()));
if (redraw) { if (redraw) {
_gfxWidget->draw(); _gfxWidget->markAsDirty();
_date->draw(); _date->markAsDirty();
_time->draw(); _time->markAsDirty();
_playtime->draw(); _playtime->markAsDirty();
_chooseButton->draw(); _chooseButton->markAsDirty();
_deleteButton->draw(); _deleteButton->markAsDirty();
draw(); markAsDirty();
} }
} }
@ -703,7 +703,7 @@ void SaveLoadChooserSimple::updateSaveList() {
else else
_chooseButton->setEnabled(false); _chooseButton->setEnabled(false);
draw(); markAsDirty();
} }
// SaveLoadChooserGrid implementation // SaveLoadChooserGrid implementation
@ -761,13 +761,13 @@ void SaveLoadChooserGrid::handleCommand(CommandSender *sender, uint32 cmd, uint3
case kNextCmd: case kNextCmd:
++_curPage; ++_curPage;
updateSaves(); updateSaves();
draw(); markAsDirty();
break; break;
case kPrevCmd: case kPrevCmd:
--_curPage; --_curPage;
updateSaves(); updateSaves();
draw(); markAsDirty();
break; break;
case kNewSaveCmd: case kNewSaveCmd:
@ -788,13 +788,13 @@ void SaveLoadChooserGrid::handleMouseWheel(int x, int y, int direction) {
if (_nextButton->isEnabled()) { if (_nextButton->isEnabled()) {
++_curPage; ++_curPage;
updateSaves(); updateSaves();
draw(); markAsDirty();
} }
} else { } else {
if (_prevButton->isEnabled()) { if (_prevButton->isEnabled()) {
--_curPage; --_curPage;
updateSaves(); updateSaves();
draw(); markAsDirty();
} }
} }
} }
@ -802,7 +802,7 @@ void SaveLoadChooserGrid::handleMouseWheel(int x, int y, int direction) {
void SaveLoadChooserGrid::updateSaveList() { void SaveLoadChooserGrid::updateSaveList() {
SaveLoadChooserDialog::updateSaveList(); SaveLoadChooserDialog::updateSaveList();
updateSaves(); updateSaves();
draw(); markAsDirty();
} }
void SaveLoadChooserGrid::open() { void SaveLoadChooserGrid::open() {

View file

@ -231,7 +231,7 @@ void StorageWizardDialog::handleCommand(CommandSender *sender, uint32 cmd, uint3
_codeWidget[i]->setEditString(subcode); _codeWidget[i]->setEditString(subcode);
} }
handleCommand(sender, kCodeBoxCmd, data); handleCommand(sender, kCodeBoxCmd, data);
draw(); markAsDirty();
} }
break; break;
} }

View file

@ -115,7 +115,7 @@ void ThemeBrowser::updateListing() {
_fileList->setSelected(currentThemeIndex); _fileList->setSelected(currentThemeIndex);
// Finally, redraw // Finally, redraw
draw(); markAsDirty();
} }
} // End of namespace GUI } // End of namespace GUI

View file

@ -51,6 +51,7 @@ void Widget::init() {
// Insert into the widget list of the boss // Insert into the widget list of the boss
_next = _boss->_firstWidget; _next = _boss->_firstWidget;
_boss->_firstWidget = this; _boss->_firstWidget = this;
_needsRedraw = true;
} }
Common::Rect Widget::getBossClipRect() const { Common::Rect Widget::getBossClipRect() const {
@ -112,10 +113,21 @@ void Widget::updateState(int oldFlags, int newFlags) {
} }
} }
void Widget::markAsDirty() {
_needsRedraw = true;
Widget *w = _firstWidget;
while (w) {
w->markAsDirty();
w = w->next();
}
}
void Widget::draw() { void Widget::draw() {
if (!isVisible() || !_boss->isVisible()) if (!isVisible() || !_boss->isVisible())
return; return;
if (_needsRedraw) {
int oldX = _x, oldY = _y; int oldX = _x, oldY = _y;
// Account for our relative position in the dialog // Account for our relative position in the dialog
@ -145,6 +157,9 @@ void Widget::draw() {
_x = oldX; _x = oldX;
_y = oldY; _y = oldY;
_needsRedraw = false;
}
// Draw all children // Draw all children
Widget *w = _firstWidget; Widget *w = _firstWidget;
while (w) { while (w) {
@ -191,7 +206,7 @@ void Widget::setEnabled(bool e) {
else else
clearFlags(WIDGET_ENABLED); clearFlags(WIDGET_ENABLED);
_boss->draw(); _boss->markAsDirty();
} }
} }
@ -273,7 +288,7 @@ StaticTextWidget::StaticTextWidget(GuiObject *boss, int x, int y, int w, int h,
StaticTextWidget::StaticTextWidget(GuiObject *boss, const Common::String &name, const Common::String &text, const char *tooltip, ThemeEngine::FontStyle font) StaticTextWidget::StaticTextWidget(GuiObject *boss, const Common::String &name, const Common::String &text, const char *tooltip, ThemeEngine::FontStyle font)
: Widget(boss, name, tooltip) { : Widget(boss, name, tooltip) {
setFlags(WIDGET_ENABLED); setFlags(WIDGET_ENABLED | WIDGET_CLEARBG);
_type = kStaticTextWidget; _type = kStaticTextWidget;
_label = text; _label = text;
@ -289,12 +304,7 @@ void StaticTextWidget::setLabel(const Common::String &label) {
if (_label != label) { if (_label != label) {
_label = label; _label = label;
// when changing the label, add the CLEARBG flag markAsDirty();
// so the widget is completely redrawn, otherwise
// the new text is drawn on top of the old one.
setFlags(WIDGET_CLEARBG);
draw();
clearFlags(WIDGET_CLEARBG);
} }
} }
@ -302,14 +312,8 @@ void StaticTextWidget::setAlign(Graphics::TextAlign align) {
if (_align != align){ if (_align != align){
_align = align; _align = align;
// same as setLabel() actually, the text markAsDirty();
// would be redrawn on top of the old one so
// we add the CLEARBG flag
setFlags(WIDGET_CLEARBG);
draw();
clearFlags(WIDGET_CLEARBG);
} }
} }
@ -389,18 +393,18 @@ ButtonWidget *addClearButton(GuiObject *boss, const Common::String &name, uint32
void ButtonWidget::setHighLighted(bool enable) { void ButtonWidget::setHighLighted(bool enable) {
(enable) ? setFlags(WIDGET_HILITED) : clearFlags(WIDGET_HILITED); (enable) ? setFlags(WIDGET_HILITED) : clearFlags(WIDGET_HILITED);
draw(); markAsDirty();
} }
void ButtonWidget::setPressedState() { void ButtonWidget::setPressedState() {
setFlags(WIDGET_PRESSED); setFlags(WIDGET_PRESSED);
clearFlags(WIDGET_HILITED); clearFlags(WIDGET_HILITED);
draw(); markAsDirty();
} }
void ButtonWidget::setUnpressedState() { void ButtonWidget::setUnpressedState() {
clearFlags(WIDGET_PRESSED); clearFlags(WIDGET_PRESSED);
draw(); markAsDirty();
} }
#pragma mark - #pragma mark -
@ -563,7 +567,7 @@ void CheckboxWidget::setState(bool state) {
if (_state != state) { if (_state != state) {
_state = state; _state = state;
//_flags ^= WIDGET_INV_BORDER; //_flags ^= WIDGET_INV_BORDER;
draw(); markAsDirty();
} }
sendCommand(_cmd, _state); sendCommand(_cmd, _state);
} }
@ -632,7 +636,7 @@ void RadiobuttonWidget::setState(bool state, bool setGroup) {
if (_state != state) { if (_state != state) {
_state = state; _state = state;
//_flags ^= WIDGET_INV_BORDER; //_flags ^= WIDGET_INV_BORDER;
draw(); markAsDirty();
} }
sendCommand(_cmd, _state); sendCommand(_cmd, _state);
} }
@ -667,7 +671,7 @@ void SliderWidget::handleMouseMoved(int x, int y, int button) {
if (newValue != _value) { if (newValue != _value) {
_value = newValue; _value = newValue;
draw(); markAsDirty();
sendCommand(_cmd, _value); // FIXME - hack to allow for "live update" in sound dialog sendCommand(_cmd, _value); // FIXME - hack to allow for "live update" in sound dialog
} }
} }
@ -699,7 +703,7 @@ void SliderWidget::handleMouseWheel(int x, int y, int direction) {
if (newValue != _value) { if (newValue != _value) {
_value = newValue; _value = newValue;
draw(); markAsDirty();
sendCommand(_cmd, _value); // FIXME - hack to allow for "live update" in sound dialog sendCommand(_cmd, _value); // FIXME - hack to allow for "live update" in sound dialog
} }
} }

View file

@ -103,6 +103,7 @@ protected:
private: private:
uint16 _flags; uint16 _flags;
bool _needsRedraw;
public: public:
static Widget *findWidgetInChain(Widget *start, int x, int y); static Widget *findWidgetInChain(Widget *start, int x, int y);
@ -137,7 +138,12 @@ public:
virtual bool handleKeyUp(Common::KeyState state) { return false; } // Return true if the event was handled virtual bool handleKeyUp(Common::KeyState state) { return false; } // Return true if the event was handled
virtual void handleTickle() {} virtual void handleTickle() {}
void draw(); /** Mark the widget and its children as dirty so they are redrawn on the next screen update */
virtual void markAsDirty();
/** Redraw the widget if it was marked as dirty, and recursively proceed with its children */
virtual void draw();
void receivedFocus() { _hasFocus = true; receivedFocusWidget(); } void receivedFocus() { _hasFocus = true; receivedFocusWidget(); }
void lostFocus() { _hasFocus = false; lostFocusWidget(); } void lostFocus() { _hasFocus = false; lostFocusWidget(); }
virtual bool wantsFocus() { return false; } virtual bool wantsFocus() { return false; }
@ -213,8 +219,8 @@ public:
void handleMouseUp(int x, int y, int button, int clickCount); void handleMouseUp(int x, int y, int button, int clickCount);
void handleMouseDown(int x, int y, int button, int clickCount); void handleMouseDown(int x, int y, int button, int clickCount);
void handleMouseEntered(int button) { if (_duringPress) { setFlags(WIDGET_PRESSED); } else { setFlags(WIDGET_HILITED); } draw(); } void handleMouseEntered(int button) { if (_duringPress) { setFlags(WIDGET_PRESSED); } else { setFlags(WIDGET_HILITED); } markAsDirty(); }
void handleMouseLeft(int button) { clearFlags(WIDGET_HILITED | WIDGET_PRESSED); draw(); } void handleMouseLeft(int button) { clearFlags(WIDGET_HILITED | WIDGET_PRESSED); markAsDirty(); }
void setHighLighted(bool enable); void setHighLighted(bool enable);
void setPressedState(); void setPressedState();
@ -262,8 +268,8 @@ public:
CheckboxWidget(GuiObject *boss, const Common::String &name, const Common::String &label, const char *tooltip = 0, uint32 cmd = 0, uint8 hotkey = 0); CheckboxWidget(GuiObject *boss, const Common::String &name, const Common::String &label, const char *tooltip = 0, uint32 cmd = 0, uint8 hotkey = 0);
void handleMouseUp(int x, int y, int button, int clickCount); void handleMouseUp(int x, int y, int button, int clickCount);
virtual void handleMouseEntered(int button) { setFlags(WIDGET_HILITED); draw(); } virtual void handleMouseEntered(int button) { setFlags(WIDGET_HILITED); markAsDirty(); }
virtual void handleMouseLeft(int button) { clearFlags(WIDGET_HILITED); draw(); } virtual void handleMouseLeft(int button) { clearFlags(WIDGET_HILITED); markAsDirty(); }
void setState(bool state); void setState(bool state);
void toggleState() { setState(!_state); } void toggleState() { setState(!_state); }
@ -308,8 +314,8 @@ public:
RadiobuttonWidget(GuiObject *boss, const Common::String &name, RadiobuttonGroup *group, int value, const Common::String &label, const char *tooltip = 0, uint8 hotkey = 0); RadiobuttonWidget(GuiObject *boss, const Common::String &name, RadiobuttonGroup *group, int value, const Common::String &label, const char *tooltip = 0, uint8 hotkey = 0);
void handleMouseUp(int x, int y, int button, int clickCount); void handleMouseUp(int x, int y, int button, int clickCount);
virtual void handleMouseEntered(int button) { setFlags(WIDGET_HILITED); draw(); } virtual void handleMouseEntered(int button) { setFlags(WIDGET_HILITED); markAsDirty(); }
virtual void handleMouseLeft(int button) { clearFlags(WIDGET_HILITED); draw(); } virtual void handleMouseLeft(int button) { clearFlags(WIDGET_HILITED); markAsDirty(); }
void setState(bool state, bool setGroup = true); void setState(bool state, bool setGroup = true);
void toggleState() { setState(!_state); } void toggleState() { setState(!_state); }
@ -348,8 +354,8 @@ public:
void handleMouseMoved(int x, int y, int button); void handleMouseMoved(int x, int y, int button);
void handleMouseDown(int x, int y, int button, int clickCount); void handleMouseDown(int x, int y, int button, int clickCount);
void handleMouseUp(int x, int y, int button, int clickCount); void handleMouseUp(int x, int y, int button, int clickCount);
void handleMouseEntered(int button) { setFlags(WIDGET_HILITED); draw(); } void handleMouseEntered(int button) { setFlags(WIDGET_HILITED); markAsDirty(); }
void handleMouseLeft(int button) { clearFlags(WIDGET_HILITED); draw(); } void handleMouseLeft(int button) { clearFlags(WIDGET_HILITED); markAsDirty(); }
void handleMouseWheel(int x, int y, int direction); void handleMouseWheel(int x, int y, int direction);
protected: protected:

View file

@ -235,7 +235,7 @@ bool EditableWidget::handleKeyDown(Common::KeyState state) {
} }
if (dirty) if (dirty)
draw(); markAsDirty();
if (forcecaret) if (forcecaret)
makeCaretVisible(); makeCaretVisible();

View file

@ -87,7 +87,7 @@ void EditTextWidget::handleMouseDown(int x, int y, int button, int clickCount) {
last = cur; last = cur;
} }
if (setCaretPos(i)) if (setCaretPos(i))
draw(); markAsDirty();
#ifdef TIZEN #ifdef TIZEN
// Display the virtual keypad to allow text entry. Samsung app-store testers expected // Display the virtual keypad to allow text entry. Samsung app-store testers expected

View file

@ -145,7 +145,7 @@ void ListWidget::setSelected(int item) {
_currentPos = _selectedItem - _entriesPerPage / 2; _currentPos = _selectedItem - _entriesPerPage / 2;
scrollToCurrent(); scrollToCurrent();
draw(); markAsDirty();
} }
} }
@ -251,7 +251,7 @@ void ListWidget::handleMouseDown(int x, int y, int button, int clickCount) {
// TODO: Determine where inside the string the user clicked and place the // TODO: Determine where inside the string the user clicked and place the
// caret accordingly. // caret accordingly.
// See _editScrollOffset and EditTextWidget::handleMouseDown. // See _editScrollOffset and EditTextWidget::handleMouseDown.
draw(); markAsDirty();
} }
@ -446,12 +446,12 @@ bool ListWidget::handleKeyDown(Common::KeyState state) {
} }
if (dirty || _selectedItem != oldSelectedItem) if (dirty || _selectedItem != oldSelectedItem)
draw(); markAsDirty();
if (_selectedItem != oldSelectedItem) { if (_selectedItem != oldSelectedItem) {
sendCommand(kListSelectionChangedCmd, _selectedItem); sendCommand(kListSelectionChangedCmd, _selectedItem);
// also draw scrollbar // also draw scrollbar
_scrollBar->draw(); _scrollBar->markAsDirty();
} }
return handled; return handled;
@ -467,7 +467,7 @@ void ListWidget::receivedFocusWidget() {
_inversion = ThemeEngine::kTextInversionFocus; _inversion = ThemeEngine::kTextInversionFocus;
// Redraw the widget so the selection color will change // Redraw the widget so the selection color will change
draw(); markAsDirty();
} }
void ListWidget::lostFocusWidget() { void ListWidget::lostFocusWidget() {
@ -477,7 +477,7 @@ void ListWidget::lostFocusWidget() {
_editMode = false; _editMode = false;
g_system->setFeatureState(OSystem::kFeatureVirtualKeyboard, false); g_system->setFeatureState(OSystem::kFeatureVirtualKeyboard, false);
drawCaret(true); drawCaret(true);
draw(); markAsDirty();
} }
void ListWidget::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) { void ListWidget::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) {
@ -486,7 +486,7 @@ void ListWidget::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) {
if (_currentPos != (int)data) { if (_currentPos != (int)data) {
_currentPos = data; _currentPos = data;
checkBounds(); checkBounds();
draw(); markAsDirty();
// Scrollbar actions cause list focus (which triggers a redraw) // Scrollbar actions cause list focus (which triggers a redraw)
// NOTE: ListWidget's boss is always GUI::Dialog // NOTE: ListWidget's boss is always GUI::Dialog
@ -600,7 +600,7 @@ void ListWidget::scrollToEnd() {
_scrollBar->_currentPos = _currentPos; _scrollBar->_currentPos = _currentPos;
_scrollBar->recalc(); _scrollBar->recalc();
_scrollBar->draw(); _scrollBar->markAsDirty();
} }
void ListWidget::startEditMode() { void ListWidget::startEditMode() {
@ -616,7 +616,7 @@ void ListWidget::startEditMode() {
else else
_editColor = _listColors[_listIndex[_selectedItem]]; _editColor = _listColors[_listIndex[_selectedItem]];
} }
draw(); markAsDirty();
g_system->setFeatureState(OSystem::kFeatureVirtualKeyboard, true); g_system->setFeatureState(OSystem::kFeatureVirtualKeyboard, true);
} }
} }
@ -636,7 +636,7 @@ void ListWidget::abortEditMode() {
assert(_selectedItem >= 0); assert(_selectedItem >= 0);
_editMode = false; _editMode = false;
//drawCaret(true); //drawCaret(true);
//draw(); //markAsDirty();
g_system->setFeatureState(OSystem::kFeatureVirtualKeyboard, false); g_system->setFeatureState(OSystem::kFeatureVirtualKeyboard, false);
} }
@ -744,7 +744,7 @@ void ListWidget::setFilter(const String &filter, bool redraw) {
// Such a widget could also (optionally) draw a border (or even different // Such a widget could also (optionally) draw a border (or even different
// kinds of borders) around the objects it groups; and also a 'title' // kinds of borders) around the objects it groups; and also a 'title'
// (I am borrowing these "ideas" from the NSBox class in Cocoa :). // (I am borrowing these "ideas" from the NSBox class in Cocoa :).
_boss->draw(); _boss->markAsDirty();
} }
} }

View file

@ -409,7 +409,7 @@ void PopUpWidget::handleMouseDown(int x, int y, int button, int clickCount) {
if (newSel != -1 && _selectedItem != newSel) { if (newSel != -1 && _selectedItem != newSel) {
_selectedItem = newSel; _selectedItem = newSel;
sendCommand(kPopUpItemSelectedCmd, _entries[_selectedItem].tag); sendCommand(kPopUpItemSelectedCmd, _entries[_selectedItem].tag);
draw(); markAsDirty();
} }
} }
} }
@ -429,7 +429,7 @@ void PopUpWidget::handleMouseWheel(int x, int y, int direction) {
(newSelection != _selectedItem)) { (newSelection != _selectedItem)) {
_selectedItem = newSelection; _selectedItem = newSelection;
sendCommand(kPopUpItemSelectedCmd, _entries[_selectedItem].tag); sendCommand(kPopUpItemSelectedCmd, _entries[_selectedItem].tag);
draw(); markAsDirty();
} }
} }
} }

View file

@ -77,8 +77,8 @@ public:
uint32 getSelectedTag() const { return (_selectedItem >= 0) ? _entries[_selectedItem].tag : (uint32)-1; } uint32 getSelectedTag() const { return (_selectedItem >= 0) ? _entries[_selectedItem].tag : (uint32)-1; }
// const String& getSelectedString() const { return (_selectedItem >= 0) ? _entries[_selectedItem].name : String::emptyString; } // const String& getSelectedString() const { return (_selectedItem >= 0) ? _entries[_selectedItem].name : String::emptyString; }
void handleMouseEntered(int button) { setFlags(WIDGET_HILITED); draw(); } void handleMouseEntered(int button) { setFlags(WIDGET_HILITED); markAsDirty(); }
void handleMouseLeft(int button) { clearFlags(WIDGET_HILITED); draw(); } void handleMouseLeft(int button) { clearFlags(WIDGET_HILITED); markAsDirty(); }
virtual void reflowLayout(); virtual void reflowLayout();
protected: protected:

View file

@ -135,7 +135,7 @@ void ScrollBarWidget::handleMouseMoved(int x, int y, int button) {
_part = kSliderPart; _part = kSliderPart;
if (old_part != _part) if (old_part != _part)
draw(); markAsDirty();
} }
} }
@ -165,7 +165,7 @@ void ScrollBarWidget::checkBounds(int old_pos) {
if (old_pos != _currentPos) { if (old_pos != _currentPos) {
recalc(); recalc();
draw(); markAsDirty();
sendCommand(kSetPositionCmd, _currentPos); sendCommand(kSetPositionCmd, _currentPos);
} }
} }

View file

@ -69,7 +69,7 @@ public:
void handleMouseWheel(int x, int y, int direction); void handleMouseWheel(int x, int y, int direction);
void handleMouseMoved(int x, int y, int button); void handleMouseMoved(int x, int y, int button);
void handleMouseEntered(int button) { setFlags(WIDGET_HILITED); } void handleMouseEntered(int button) { setFlags(WIDGET_HILITED); }
void handleMouseLeft(int button) { clearFlags(WIDGET_HILITED); _part = kNoPart; draw(); } void handleMouseLeft(int button) { clearFlags(WIDGET_HILITED); _part = kNoPart; markAsDirty(); }
void handleTickle(); void handleTickle();
// FIXME - this should be private, but then we also have to add accessors // FIXME - this should be private, but then we also have to add accessors

View file

@ -102,7 +102,7 @@ void ScrollContainerWidget::handleCommand(CommandSender *sender, uint32 cmd, uin
case kSetPositionCmd: case kSetPositionCmd:
_scrolledY = _verticalScroll->_currentPos; _scrolledY = _verticalScroll->_currentPos;
reflowLayout(); reflowLayout();
draw(); markAsDirty();
g_gui.doFullRedraw(); g_gui.doFullRedraw();
break; break;
} }

View file

@ -154,7 +154,7 @@ void TabWidget::removeTab(int tabID) {
} }
// Finally trigger a redraw // Finally trigger a redraw
_boss->draw(); _boss->markAsDirty();
} }
void TabWidget::setActiveTab(int tabID) { void TabWidget::setActiveTab(int tabID) {
@ -174,7 +174,7 @@ void TabWidget::setActiveTab(int tabID) {
while (_lastVisibleTab < tabID) while (_lastVisibleTab < tabID)
setFirstVisible(_firstVisibleTab + 1, false); setFirstVisible(_firstVisibleTab + 1, false);
_boss->draw(); _boss->markAsDirty();
} }
} }
@ -246,7 +246,7 @@ void TabWidget::setFirstVisible(int tabID, bool adjustIfRoom) {
computeLastVisibleTab(adjustIfRoom); computeLastVisibleTab(adjustIfRoom);
_boss->draw(); // TODO: Necessary? _boss->markAsDirty(); // TODO: Necessary?
} }
void TabWidget::reflowLayout() { void TabWidget::reflowLayout() {
@ -334,6 +334,15 @@ void TabWidget::draw() {
} }
} }
void TabWidget::markAsDirty() {
Widget::markAsDirty();
if (_navButtonsVisible) {
_navLeft->markAsDirty();
_navRight->markAsDirty();
}
}
bool TabWidget::containsWidget(Widget *w) const { bool TabWidget::containsWidget(Widget *w) const {
if (w == _navLeft || w == _navRight || _navLeft->containsWidget(w) || _navRight->containsWidget(w)) if (w == _navLeft || w == _navRight || _navLeft->containsWidget(w) || _navRight->containsWidget(w))
return true; return true;

View file

@ -111,7 +111,8 @@ public:
virtual void reflowLayout(); virtual void reflowLayout();
virtual void draw(); void draw() override;
void markAsDirty() override;
protected: protected:
// We overload getChildY to make sure child widgets are positioned correctly. // We overload getChildY to make sure child widgets are positioned correctly.