GUI: Fix thumbnails for event recorder dialogue
Also prevent segmentation fault cases related to low-res or switching from low-res to hi-res And fix memory leak related to loading and scaling of the thumbnail image A lot of the updated logic is borrowed from the saveload-dialog.cpp for the simple list view (with the thumbnail to the right of the list).
This commit is contained in:
parent
d7b18666fe
commit
07c1e5cc2a
3 changed files with 116 additions and 35 deletions
|
@ -696,7 +696,7 @@ Graphics::Surface *PlaybackFile::getScreenShot(int number) {
|
||||||
if (screenCount == number) {
|
if (screenCount == number) {
|
||||||
screenCount++;
|
screenCount++;
|
||||||
_readStream->seek(-4, SEEK_CUR);
|
_readStream->seek(-4, SEEK_CUR);
|
||||||
Graphics::Surface *thumbnail;
|
Graphics::Surface *thumbnail = nullptr;
|
||||||
return Graphics::loadThumbnail(*_readStream, thumbnail) ? thumbnail : NULL;
|
return Graphics::loadThumbnail(*_readStream, thumbnail) ? thumbnail : NULL;
|
||||||
} else {
|
} else {
|
||||||
uint32 size = _readStream->readUint32BE();
|
uint32 size = _readStream->readUint32BE();
|
||||||
|
|
|
@ -40,6 +40,8 @@
|
||||||
|
|
||||||
namespace GUI {
|
namespace GUI {
|
||||||
|
|
||||||
|
#define SCALEVALUE(val) ((val) * g_gui.getScaleFactor())
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
kRecordCmd = 'RCRD',
|
kRecordCmd = 'RCRD',
|
||||||
kPlaybackCmd = 'PBCK',
|
kPlaybackCmd = 'PBCK',
|
||||||
|
@ -55,6 +57,10 @@ RecorderDialog::RecorderDialog() : Dialog("RecorderDialog"), _list(nullptr), _cu
|
||||||
_currentScreenshotText = nullptr;
|
_currentScreenshotText = nullptr;
|
||||||
_authorText = nullptr;
|
_authorText = nullptr;
|
||||||
_notesText = nullptr;
|
_notesText = nullptr;
|
||||||
|
_container = nullptr;
|
||||||
|
_gfxWidget = nullptr;
|
||||||
|
_nextScreenshotBtn = nullptr;
|
||||||
|
_prevScreenshotBtn = nullptr;
|
||||||
|
|
||||||
_backgroundType = ThemeEngine::kDialogBackgroundSpecial;
|
_backgroundType = ThemeEngine::kDialogBackgroundSpecial;
|
||||||
|
|
||||||
|
@ -75,20 +81,15 @@ RecorderDialog::RecorderDialog() : Dialog("RecorderDialog"), _list(nullptr), _cu
|
||||||
_playbackButton->setEnabled(false);
|
_playbackButton->setEnabled(false);
|
||||||
|
|
||||||
_gfxWidget = new GUI::GraphicsWidget(this, 0, 0, 10, 10);
|
_gfxWidget = new GUI::GraphicsWidget(this, 0, 0, 10, 10);
|
||||||
_container = new GUI::ContainerWidget(this, "RecorderDialog.Thumbnail");
|
_gfxWidget->useThemeTransparency(false);
|
||||||
if (g_gui.xmlEval()->getVar("Globals.RecorderDialog.ExtInfo.Visible") == 1) {
|
|
||||||
new GUI::ButtonWidget(this,"RecorderDialog.NextScreenShotButton", Common::U32String("<"), Common::U32String(), kPrevScreenshotCmd);
|
addThumbnailContainerButtonsAndText();
|
||||||
new GUI::ButtonWidget(this, "RecorderDialog.PreviousScreenShotButton", Common::U32String(">"), Common::U32String(), kNextScreenshotCmd);
|
|
||||||
_currentScreenshotText = new StaticTextWidget(this, "RecorderDialog.currentScreenshot", Common::U32String("0/0"));
|
|
||||||
_authorText = new StaticTextWidget(this, "RecorderDialog.Author", _("Author: "));
|
|
||||||
_notesText = new StaticTextWidget(this, "RecorderDialog.Notes", _("Notes: "));
|
|
||||||
}
|
|
||||||
if (_gfxWidget)
|
|
||||||
_gfxWidget->setGfx((Graphics::Surface *)nullptr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void RecorderDialog::reflowLayout() {
|
void RecorderDialog::reflowLayout() {
|
||||||
|
addThumbnailContainerButtonsAndText();
|
||||||
|
|
||||||
Dialog::reflowLayout();
|
Dialog::reflowLayout();
|
||||||
|
|
||||||
if (g_gui.xmlEval()->getVar("Globals.RecorderDialog.ExtInfo.Visible") == 1) {
|
if (g_gui.xmlEval()->getVar("Globals.RecorderDialog.ExtInfo.Visible") == 1) {
|
||||||
|
@ -99,24 +100,82 @@ void RecorderDialog::reflowLayout() {
|
||||||
error("Error when loading position data for Recorder Thumbnails");
|
error("Error when loading position data for Recorder Thumbnails");
|
||||||
}
|
}
|
||||||
|
|
||||||
int thumbW = kThumbnailWidth;
|
int thumbW = SCALEVALUE(kThumbnailWidth);
|
||||||
int thumbH = kThumbnailHeight2;
|
int thumbH = SCALEVALUE(kThumbnailHeight2);
|
||||||
int thumbX = x + (w >> 1) - (thumbW >> 1);
|
int thumbX = x + (w >> 1) - (thumbW >> 1);
|
||||||
int thumbY = y + kLineHeight;
|
int thumbY = y + kLineHeight;
|
||||||
|
|
||||||
_container->resize(x, y, w, h);
|
_gfxWidget->resize(thumbX, thumbY, thumbW, thumbH, false);
|
||||||
_gfxWidget->resize(thumbX, thumbY, thumbW, thumbH);
|
|
||||||
|
|
||||||
_container->setVisible(true);
|
|
||||||
_gfxWidget->setVisible(true);
|
_gfxWidget->setVisible(true);
|
||||||
|
|
||||||
|
_container->resize(x, y, w, h, false);
|
||||||
|
_container->setVisible(true);
|
||||||
|
|
||||||
|
_notesText->setVisible(true);
|
||||||
|
_authorText->setVisible(true);
|
||||||
|
|
||||||
|
_nextScreenshotBtn->setVisible(true);
|
||||||
|
_prevScreenshotBtn->setVisible(true);
|
||||||
|
|
||||||
updateSelection(false);
|
updateSelection(false);
|
||||||
} else {
|
} else {
|
||||||
_container->setVisible(false);
|
if (_container) _container->setVisible(false);
|
||||||
_gfxWidget->setVisible(false);
|
_gfxWidget->setVisible(false);
|
||||||
|
if (_notesText) _notesText->setVisible(false);
|
||||||
|
if (_authorText) _authorText->setVisible(false);
|
||||||
|
if (_nextScreenshotBtn) _nextScreenshotBtn->setVisible(false);
|
||||||
|
if (_prevScreenshotBtn) _prevScreenshotBtn->setVisible(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RecorderDialog::addThumbnailContainerButtonsAndText() {
|
||||||
|
// When switching layouts, create / remove the thumbnail container as needed
|
||||||
|
if (g_gui.xmlEval()->getVar("Globals.RecorderDialog.ExtInfo.Visible") == 1) {
|
||||||
|
if (!_container)
|
||||||
|
_container = new ContainerWidget(this, "RecorderDialog.Thumbnail");
|
||||||
|
if (!_nextScreenshotBtn)
|
||||||
|
_nextScreenshotBtn = new GUI::ButtonWidget(this,"RecorderDialog.NextScreenShotButton", Common::U32String("<"), Common::U32String(), kPrevScreenshotCmd);
|
||||||
|
if (!_prevScreenshotBtn)
|
||||||
|
_prevScreenshotBtn = new GUI::ButtonWidget(this, "RecorderDialog.PreviousScreenShotButton", Common::U32String(">"), Common::U32String(), kNextScreenshotCmd);
|
||||||
|
if (!_currentScreenshotText)
|
||||||
|
_currentScreenshotText = new StaticTextWidget(this, "RecorderDialog.currentScreenshot", Common::U32String("0/0"));
|
||||||
|
if (!_authorText)
|
||||||
|
_authorText = new StaticTextWidget(this, "RecorderDialog.Author", _("Author: "));
|
||||||
|
if (!_notesText)
|
||||||
|
_notesText = new StaticTextWidget(this, "RecorderDialog.Notes", _("Notes: "));
|
||||||
|
} else if (g_gui.xmlEval()->getVar("Globals.RecorderDialog.ExtInfo.Visible") == 0) {
|
||||||
|
if (_container) {
|
||||||
|
removeWidget(_container);
|
||||||
|
delete _container;
|
||||||
|
_container = nullptr;
|
||||||
|
}
|
||||||
|
if (_nextScreenshotBtn) {
|
||||||
|
removeWidget(_nextScreenshotBtn);
|
||||||
|
delete _nextScreenshotBtn;
|
||||||
|
_nextScreenshotBtn = nullptr;
|
||||||
|
}
|
||||||
|
if (_prevScreenshotBtn) {
|
||||||
|
removeWidget(_prevScreenshotBtn);
|
||||||
|
delete _prevScreenshotBtn;
|
||||||
|
_prevScreenshotBtn = nullptr;
|
||||||
|
}
|
||||||
|
if (_currentScreenshotText) {
|
||||||
|
removeWidget(_currentScreenshotText);
|
||||||
|
delete _currentScreenshotText;
|
||||||
|
_currentScreenshotText = nullptr;
|
||||||
|
}
|
||||||
|
if (_authorText) {
|
||||||
|
removeWidget(_authorText);
|
||||||
|
delete _authorText;
|
||||||
|
_authorText = nullptr;
|
||||||
|
}
|
||||||
|
if (_notesText) {
|
||||||
|
removeWidget(_notesText);
|
||||||
|
delete _notesText;
|
||||||
|
_notesText = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void RecorderDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) {
|
void RecorderDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) {
|
||||||
switch(cmd) {
|
switch(cmd) {
|
||||||
|
@ -215,6 +274,10 @@ void RecorderDialog::updateList() {
|
||||||
|
|
||||||
int RecorderDialog::runModal(Common::String &target) {
|
int RecorderDialog::runModal(Common::String &target) {
|
||||||
_target = target;
|
_target = target;
|
||||||
|
if (_gfxWidget)
|
||||||
|
_gfxWidget->setGfx((Graphics::ManagedSurface *)nullptr);
|
||||||
|
|
||||||
|
reflowLayout();
|
||||||
updateList();
|
updateList();
|
||||||
return Dialog::runModal();
|
return Dialog::runModal();
|
||||||
}
|
}
|
||||||
|
@ -235,17 +298,13 @@ void RecorderDialog::updateSelection(bool redraw) {
|
||||||
_gfxWidget->setGfx(-1, -1, 0, 0, 0);
|
_gfxWidget->setGfx(-1, -1, 0, 0, 0);
|
||||||
_screenShotsCount = 0;
|
_screenShotsCount = 0;
|
||||||
_currentScreenshot = 0;
|
_currentScreenshot = 0;
|
||||||
updateScreenShotsText();
|
|
||||||
if (_list->getSelected() >= 0) {
|
if (_list->getSelected() >= 0) {
|
||||||
_authorText->setLabel(_("Author: ") + Common::U32String(_fileHeaders[_list->getSelected()].author));
|
_authorText->setLabel(_("Author: ") + Common::U32String(_fileHeaders[_list->getSelected()].author));
|
||||||
_notesText->setLabel(_("Notes: ") + Common::U32String(_fileHeaders[_list->getSelected()].notes));
|
_notesText->setLabel(_("Notes: ") + Common::U32String(_fileHeaders[_list->getSelected()].notes));
|
||||||
|
|
||||||
_firstScreenshotUpdate = true;
|
_firstScreenshotUpdate = true;
|
||||||
updateScreenshot();
|
updateScreenshot();
|
||||||
if ((_screenShotsCount) > 0) {
|
updateScreenShotsText();
|
||||||
_currentScreenshot = 1;
|
|
||||||
}
|
|
||||||
updateScreenshot();
|
|
||||||
} else {
|
} else {
|
||||||
_authorText->setLabel(_("Author: "));
|
_authorText->setLabel(_("Author: "));
|
||||||
_notesText->setLabel(_("Notes: "));
|
_notesText->setLabel(_("Notes: "));
|
||||||
|
@ -255,33 +314,51 @@ void RecorderDialog::updateSelection(bool redraw) {
|
||||||
_gfxWidget->markAsDirty();
|
_gfxWidget->markAsDirty();
|
||||||
updateScreenShotsText();
|
updateScreenShotsText();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (redraw) {
|
||||||
|
_gfxWidget->markAsDirty();
|
||||||
|
_authorText->markAsDirty();
|
||||||
|
_notesText->markAsDirty();
|
||||||
|
updateScreenShotsText();
|
||||||
|
|
||||||
|
g_gui.scheduleTopDialogRedraw();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RecorderDialog::updateScreenshot() {
|
void RecorderDialog::updateScreenshot() {
|
||||||
if (_list->getSelected() == -1) {
|
if (_list->getSelected() == -1) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (_firstScreenshotUpdate) {
|
||||||
|
_playbackFile.openRead(_fileHeaders[_list->getSelected()].fileName);
|
||||||
|
_screenShotsCount = _playbackFile.getScreensCount();
|
||||||
|
_currentScreenshot = _screenShotsCount > 0 ? 1 : 0;
|
||||||
|
_firstScreenshotUpdate = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_screenShotsCount == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (_currentScreenshot < 1) {
|
if (_currentScreenshot < 1) {
|
||||||
_currentScreenshot = _screenShotsCount;
|
_currentScreenshot = _screenShotsCount;
|
||||||
}
|
}
|
||||||
if (_currentScreenshot > _screenShotsCount) {
|
if (_currentScreenshot > _screenShotsCount) {
|
||||||
_currentScreenshot = 1;
|
_currentScreenshot = 1;
|
||||||
}
|
}
|
||||||
if (_firstScreenshotUpdate) {
|
|
||||||
_playbackFile.openRead(_fileHeaders[_list->getSelected()].fileName);
|
|
||||||
_screenShotsCount = _playbackFile.getScreensCount();
|
|
||||||
_firstScreenshotUpdate = false;
|
|
||||||
}
|
|
||||||
Graphics::Surface *srcsf = _playbackFile.getScreenShot(_currentScreenshot);
|
Graphics::Surface *srcsf = _playbackFile.getScreenShot(_currentScreenshot);
|
||||||
if (srcsf != nullptr) {
|
Common::SharedPtr<Graphics::Surface> srcsfSptr = Common::SharedPtr<Graphics::Surface>(srcsf, Graphics::SurfaceDeleter());
|
||||||
Graphics::Surface *destsf = Graphics::scale(*srcsf, _gfxWidget->getWidth(), _gfxWidget->getHeight());
|
if (srcsfSptr) {
|
||||||
_gfxWidget->setGfx(destsf);
|
Graphics::Surface *destsf = Graphics::scale(*srcsfSptr, _gfxWidget->getWidth(), _gfxWidget->getHeight());
|
||||||
updateScreenShotsText();
|
Common::SharedPtr<Graphics::Surface> destsfSptr = Common::SharedPtr<Graphics::Surface>(destsf, Graphics::SurfaceDeleter());
|
||||||
delete destsf;
|
if (destsfSptr && _gfxWidget->isVisible())
|
||||||
delete srcsf;
|
_gfxWidget->setGfx(destsf, false);
|
||||||
} else {
|
} else {
|
||||||
_gfxWidget->setGfx(-1, -1, 0, 0, 0);
|
_gfxWidget->setGfx(-1, -1, 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateScreenShotsText();
|
||||||
_gfxWidget->markAsDirty();
|
_gfxWidget->markAsDirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -291,6 +368,7 @@ void RecorderDialog::updateScreenShotsText() {
|
||||||
} else {
|
} else {
|
||||||
_currentScreenshotText->setLabel(Common::String::format("%d / %d", _currentScreenshot, _screenShotsCount));
|
_currentScreenshotText->setLabel(Common::String::format("%d / %d", _currentScreenshot, _screenShotsCount));
|
||||||
}
|
}
|
||||||
|
_currentScreenshotText->markAsDirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // End of namespace GUI
|
} // End of namespace GUI
|
||||||
|
|
|
@ -53,11 +53,14 @@ private:
|
||||||
GUI::ButtonWidget *_editButton;
|
GUI::ButtonWidget *_editButton;
|
||||||
GUI::ButtonWidget *_deleteButton;
|
GUI::ButtonWidget *_deleteButton;
|
||||||
GUI::ButtonWidget *_playbackButton;
|
GUI::ButtonWidget *_playbackButton;
|
||||||
|
GUI::ButtonWidget *_nextScreenshotBtn;
|
||||||
|
GUI::ButtonWidget *_prevScreenshotBtn;
|
||||||
|
|
||||||
void updateList();
|
void updateList();
|
||||||
void updateScreenShotsText();
|
void updateScreenShotsText();
|
||||||
void updateSelection(bool redraw);
|
void updateSelection(bool redraw);
|
||||||
void updateScreenshot();
|
void updateScreenshot();
|
||||||
|
void addThumbnailContainerButtonsAndText();
|
||||||
public:
|
public:
|
||||||
Common::U32String _author;
|
Common::U32String _author;
|
||||||
Common::String _name;
|
Common::String _name;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue