GUI: Testing grid view with constraints

This commit is contained in:
av-dx 2021-05-24 21:12:24 +05:30 committed by Eugene Sandulenko
parent 549b9cf10d
commit 999c5d2bc6
17 changed files with 232 additions and 12 deletions

View file

@ -121,6 +121,7 @@ static const DrawDataInfo kDrawDataDefaults[] = {
{kDDDefaultBackground, "default_bg", kDrawLayerBackground, kDDNone}, {kDDDefaultBackground, "default_bg", kDrawLayerBackground, kDDNone},
{kDDTextSelectionBackground, "text_selection", kDrawLayerForeground, kDDNone}, {kDDTextSelectionBackground, "text_selection", kDrawLayerForeground, kDDNone},
{kDDTextSelectionFocusBackground, "text_selection_focus", kDrawLayerForeground, kDDNone}, {kDDTextSelectionFocusBackground, "text_selection_focus", kDrawLayerForeground, kDDNone},
{kDDThumbnailBackground, "thumb_bg", kDrawLayerBackground, kDDNone},
{kDDWidgetBackgroundDefault, "widget_default", kDrawLayerBackground, kDDNone}, {kDDWidgetBackgroundDefault, "widget_default", kDrawLayerBackground, kDDNone},
{kDDWidgetBackgroundSmall, "widget_small", kDrawLayerBackground, kDDNone}, {kDDWidgetBackgroundSmall, "widget_small", kDrawLayerBackground, kDDNone},
@ -1271,6 +1272,10 @@ void ThemeEngine::drawWidgetBackground(const Common::Rect &r, WidgetBackground b
drawDD(kDDWidgetBackgroundSlider, r); drawDD(kDDWidgetBackgroundSlider, r);
break; break;
case kThumbnailBackground:
drawDD(kDDThumbnailBackground, r);
break;
default: default:
drawDD(kDDWidgetBackgroundDefault, r); drawDD(kDDWidgetBackgroundDefault, r);
break; break;

View file

@ -69,7 +69,7 @@ enum DrawData {
kDDDefaultBackground, kDDDefaultBackground,
kDDTextSelectionBackground, kDDTextSelectionBackground,
kDDTextSelectionFocusBackground, kDDTextSelectionFocusBackground,
kDDThumbnailBackground,
kDDWidgetBackgroundDefault, kDDWidgetBackgroundDefault,
kDDWidgetBackgroundSmall, kDDWidgetBackgroundSmall,
kDDWidgetBackgroundEditText, kDDWidgetBackgroundEditText,
@ -221,7 +221,8 @@ public:
kWidgetBackgroundBorder, ///< Same as kWidgetBackgroundPlain just with a border kWidgetBackgroundBorder, ///< Same as kWidgetBackgroundPlain just with a border
kWidgetBackgroundBorderSmall, ///< Same as kWidgetBackgroundPlain just with a small border kWidgetBackgroundBorderSmall, ///< Same as kWidgetBackgroundPlain just with a small border
kWidgetBackgroundEditText, ///< Background used for edit text fields kWidgetBackgroundEditText, ///< Background used for edit text fields
kWidgetBackgroundSlider ///< Background used for sliders kWidgetBackgroundSlider, ///< Background used for sliders
kThumbnailBackground ///< Background used for thumbnails
}; };
/// Dialog background type /// Dialog background type

View file

@ -236,6 +236,7 @@ void LauncherDialog::build() {
// Add list with game titles // Add list with game titles
_list = new ListWidget(this, "Launcher.GameList", Common::U32String(), kListSearchCmd); _list = new ListWidget(this, "Launcher.GameList", Common::U32String(), kListSearchCmd);
_grid = new GridContainerWidget(this, "Launcher.IconArea");
_list->setEditable(false); _list->setEditable(false);
_list->enableDictionarySelect(true); _list->enableDictionarySelect(true);
_list->setNumberingMode(kListNumberingOff); _list->setNumberingMode(kListNumberingOff);
@ -243,7 +244,7 @@ void LauncherDialog::build() {
// Populate the list // Populate the list
updateListing(); updateListing();
// Restore last selection // Restore last selection
String last(ConfMan.get("lastselectedgame", ConfigManager::kApplicationDomain)); String last(ConfMan.get("lastselectedgame", ConfigManager::kApplicationDomain));
selectTarget(last); selectTarget(last);
@ -317,6 +318,27 @@ struct LauncherEntryComparator {
} }
}; };
void LauncherDialog::destroyButtons() {
for (EntryArray::iterator i = _entries.begin(), end = _entries.end(); i != end; ++i) {
removeWidget(i->container);
delete i->container;
}
_entries.clear();
}
void LauncherDialog::hideButtons() {
for (EntryArray::iterator i = _entries.begin(), end = _entries.end(); i != end; ++i) {
i->button->setGfx((Graphics::ManagedSurface *)nullptr);
i->setVisible(false);
}
}
void LauncherDialog::GameEntry::setVisible(bool state) {
container->setVisible(state);
}
void LauncherDialog::updateListing() { void LauncherDialog::updateListing() {
U32StringArray l; U32StringArray l;
ListWidget::ColorList colors; ListWidget::ColorList colors;
@ -351,13 +373,82 @@ void LauncherDialog::updateListing() {
description = Common::String::format("Unknown (target %s, gameid %s)", iter->_key.c_str(), gameid.c_str()); description = Common::String::format("Unknown (target %s, gameid %s)", iter->_key.c_str(), gameid.c_str());
} }
// Strip platform language from the title.
int extraPos = description.rfind("(");
description.replace((char *)(description.c_str())+extraPos, description.end(), Common::String(""));
if (!description.empty()) if (!description.empty())
domainList.push_back(LauncherEntry(iter->_key, description, &iter->_value)); domainList.push_back(LauncherEntry(iter->_key, description, &iter->_value));
} }
destroyButtons();
_entries.reserve(domainList.size());
for (int i = 0; i < domainList.size(); ++i) {
GameContainerWidget *container = new GameContainerWidget(_grid, 50 + i*(192+40), 50, 192, 160);
GameThumbButton *button = new GameThumbButton(container, 0,0, 192, 128);
StaticTextWidget *title = new StaticTextWidget(container, 0, 128, 192, 160-128, Common::U32String("Title") , Graphics::kTextAlignLeft);
StaticTextWidget *language = new StaticTextWidget(button, container->getWidth()-32, 0, 32, 32, Common::U32String("UNK") , Graphics::kTextAlignRight);
GraphicsWidget *platform = new GraphicsWidget(button, container->getWidth()-32, 128-32, 32, 32);
container->setVisible(false);
_entries.push_back(GameEntry(container, button, title, language, platform));
}
hideButtons();
// Now sort the list in dictionary order // Now sort the list in dictionary order
Common::sort(domainList.begin(), domainList.end(), LauncherEntryComparator()); Common::sort(domainList.begin(), domainList.end(), LauncherEntryComparator());
// Populate Grid
int row = 0, col = 0, i = 0;
int entriesPerRow = 6;
for (Common::List<LauncherEntry>::const_iterator iter = domainList.begin(); iter != domainList.end(); ++iter) {
i = entriesPerRow*row + col;
String language = iter->domain->getValOrDefault("language");
language.toUppercase();
String platform = iter->domain->getValOrDefault("platform");
platform.toLowercase();
String engineid(iter->domain->getVal("engineid"));
String gameid(iter->domain->getVal("gameid"));
if (language.empty())
language = "UNK";
if (platform.empty())
platform = "UNK";
if (engineid.empty())
engineid = iter->key;
if (gameid.empty())
gameid = iter->key;
warning("%s %s %s %s", engineid.c_str(), gameid.c_str(), language.c_str(), platform.c_str());
GameEntry &curEntry = _entries[i];
curEntry.setVisible(true);
Common::String thumbName = engineid + "-" + gameid + ".png";
warning(thumbName.c_str());
curEntry.container->setPos(50 + col*(192+40), 50 + row*(160+20));
curEntry.button->setGfxFromTheme(thumbName.c_str(), kPicButtonStateEnabled, true);
curEntry.language->setLabel(language);
// char *newTit = (char *)iter->description.c_str();
// newTit[5] = '\n';
// curEntry.title->setLabel(Common::String(newTit));
curEntry.title->setLabel(iter->description);
if (platform == "pc")
curEntry.platform->setGfxFromTheme("dos.png");
else if (platform == "amiga")
curEntry.platform->setGfxFromTheme("amiga.png");
else if (platform == "apple2")
curEntry.platform->setGfxFromTheme("apple2.png");
else
{}
col++;
if (col >= entriesPerRow) { row ++; col = 0;}
// if (i > 4) { break; }
}
// And fill out our structures // And fill out our structures
for (Common::List<LauncherEntry>::const_iterator iter = domainList.begin(); iter != domainList.end(); ++iter) { for (Common::List<LauncherEntry>::const_iterator iter = domainList.begin(); iter != domainList.end(); ++iter) {
color = ThemeEngine::kFontColorNormal; color = ThemeEngine::kFontColorNormal;
@ -853,7 +944,7 @@ void LauncherDialog::reflowLayout() {
_w = g_system->getOverlayWidth(); _w = g_system->getOverlayWidth();
_h = g_system->getOverlayHeight(); _h = g_system->getOverlayHeight();
Dialog::reflowLayout(); Dialog::reflowLayout();
} }

View file

@ -31,8 +31,12 @@ namespace GUI {
class BrowserDialog; class BrowserDialog;
class CommandSender; class CommandSender;
class ListWidget; class ListWidget;
class ContainerWidget;
class GameContainerWidget;
class GridContainerWidget;
class ButtonWidget; class ButtonWidget;
class PicButtonWidget; class PicButtonWidget;
class GameThumbButton;
class GraphicsWidget; class GraphicsWidget;
class StaticTextWidget; class StaticTextWidget;
class EditTextWidget; class EditTextWidget;
@ -59,6 +63,7 @@ public:
Common::String getGameConfig(int item, Common::String key); Common::String getGameConfig(int item, Common::String key);
protected: protected:
EditTextWidget *_searchWidget; EditTextWidget *_searchWidget;
GridContainerWidget *_grid;
ListWidget *_list; ListWidget *_list;
Widget *_startButton; Widget *_startButton;
ButtonWidget *_loadButton; ButtonWidget *_loadButton;
@ -126,6 +131,24 @@ protected:
*/ */
void selectTarget(const String &target); void selectTarget(const String &target);
private: private:
struct GameEntry {
GameEntry() : container(nullptr), button(nullptr), title(nullptr), language(nullptr), platform(nullptr) {}
GameEntry(GameContainerWidget *c, GameThumbButton *b, StaticTextWidget *t, StaticTextWidget *l, GraphicsWidget *p) : container(c), button(b), title(t), language(l), platform(p) {}
GameContainerWidget *container;
GameThumbButton *button;
StaticTextWidget *title;
StaticTextWidget *language;
GraphicsWidget *platform;
void setVisible(bool state);
};
typedef Common::Array<GameEntry> EntryArray;
EntryArray _entries;
void destroyButtons();
void hideButtons();
bool checkModifier(int modifier); bool checkModifier(int modifier);
}; };

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 225 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 192 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 73 KiB

View file

@ -128,7 +128,14 @@
<bitmap filename = 'editbtn_small.bmp' scalable_file = 'editbtn.svg' width = '16' height = '16'/> <bitmap filename = 'editbtn_small.bmp' scalable_file = 'editbtn.svg' width = '16' height = '16'/>
<bitmap filename = 'switchbtn_small.bmp' scalable_file = 'switchbtn.svg' width = '16' height = '16'/> <bitmap filename = 'switchbtn_small.bmp' scalable_file = 'switchbtn.svg' width = '16' height = '16'/>
<bitmap filename = 'fastreplay_small.bmp' scalable_file = 'fastreplay.svg' width = '16' height = '16'/> <bitmap filename = 'fastreplay_small.bmp' scalable_file = 'fastreplay.svg' width = '16' height = '16'/>
<bitmap filename = 'agi-kq3.bmp' width = '256' height = '256'/> <bitmap filename = 'adl-hires1.png' width = '512' height = '512'/>
<bitmap filename = 'sky-sky.png' width = '512' height = '512'/>
<bitmap filename = 'lure-lure.png' width = '512' height = '512'/>
<bitmap filename = 'queen-queen.png' width = '512' height = '512'/>
<bitmap filename = 'dos.png' width = '419' height = '443'/>
<bitmap filename = 'amiga.png' width = '256' height = '256'/>
<bitmap filename = 'apple2.png' width = '845' height = '1024'/>
<bitmap filename = 'win.png' width = '277' height = '240'/>
</bitmaps> </bitmaps>
<fonts> <fonts>

Binary file not shown.

After

Width:  |  Height:  |  Size: 231 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 122 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

View file

@ -673,6 +673,70 @@ void PicButtonWidget::drawWidget() {
#pragma mark - #pragma mark -
void GameThumbButton::setGfx(const Graphics::ManagedSurface *gfx, int statenum, bool scale) {
_gfx[statenum].free();
if (!gfx || !gfx->getPixels())
return;
if (gfx->format.bytesPerPixel == 1) {
warning("GameThumbButton::setGfx got paletted surface passed");
return;
}
float sf = g_gui.getScaleFactor();
if (scale && sf != 1.0) {
float scalingFactor = (float)gfx->w / _w;
Graphics::Surface *tmp4 = gfx->rawSurface().scale(gfx->w * sf, gfx->h * sf, false);
Graphics::Surface *tmp2 = tmp4->scale(_w, (uint16)(gfx->h / scalingFactor), false);
Graphics::Surface tmp3 = tmp2->getSubArea(Common::Rect(0,(tmp2->h -_h)/2, tmp2->w, (tmp2->h + _h)/2));
_gfx[statenum].copyFrom(tmp3);
tmp4->free();
delete tmp4;
tmp2->free();
delete tmp2;
} else {
_gfx[statenum].copyFrom(*gfx);
}
}
void GameThumbButton::setGfxFromTheme(const char *name, int statenum, bool scale) {
const Graphics::ManagedSurface *gfx = g_gui.theme()->getImageSurface(name);
setGfx(gfx, statenum, scale);
return;
}
void GameThumbButton::drawWidget() {
if (_showButton)
g_gui.theme()->drawButton(Common::Rect(_x, _y, _x + _w, _y + _h), Common::U32String(), _state, getFlags());
Graphics::ManagedSurface *gfx;
if (_state == ThemeEngine::kStateHighlight)
gfx = &_gfx[kPicButtonHighlight];
else if (_state == ThemeEngine::kStateDisabled)
gfx = &_gfx[kPicButtonStateDisabled];
else if (_state == ThemeEngine::kStatePressed)
gfx = &_gfx[kPicButtonStatePressed];
else
gfx = &_gfx[kPicButtonStateEnabled];
if (!gfx->getPixels())
gfx = &_gfx[kPicButtonStateEnabled];
if (gfx->getPixels()) {
const int x = _x + (_w - gfx->w) / 2;
const int y = _y + (_h - gfx->h) / 2;
g_gui.theme()->drawWidgetBackground(Common::Rect(x, y, x+_w, y+_h),ThemeEngine::WidgetBackground::kThumbnailBackground);
g_gui.theme()->drawSurface(Common::Point(x, y), *gfx, _transparency);
}
}
#pragma mark -
CheckboxWidget::CheckboxWidget(GuiObject *boss, int x, int y, int w, int h, const Common::U32String &label, const Common::U32String &tooltip, uint32 cmd, uint8 hotkey) CheckboxWidget::CheckboxWidget(GuiObject *boss, int x, int y, int w, int h, const Common::U32String &label, const Common::U32String &tooltip, uint32 cmd, uint8 hotkey)
: ButtonWidget(boss, x, y, w, h, label, tooltip, cmd, hotkey), _state(false) { : ButtonWidget(boss, x, y, w, h, label, tooltip, cmd, hotkey), _state(false) {
setFlags(WIDGET_ENABLED); setFlags(WIDGET_ENABLED);
@ -898,16 +962,18 @@ void GraphicsWidget::setGfx(const Graphics::ManagedSurface *gfx, bool scale) {
float sf = g_gui.getScaleFactor(); float sf = g_gui.getScaleFactor();
if (scale && sf != 1.0) { if (scale && sf != 1.0) {
_w = gfx->w * sf; // _w = gfx->w * sf;
_h = gfx->h * sf; // _h = gfx->h * sf;
} else { } else {
_w = gfx->w; // _w = gfx->w;
_h = gfx->h; // _h = gfx->h;
} }
if ((_w != gfx->w || _h != gfx->h) && _w && _h) { if ((_w != gfx->w || _h != gfx->h) && _w && _h) {
Graphics::Surface *tmp2 = gfx->rawSurface().scale(_w, _h, false); float scalingFactor = (float)gfx->w / _w;
_gfx.copyFrom(*tmp2); Graphics::Surface *tmp2 = gfx->rawSurface().scale(_w, (uint16)(gfx->h / scalingFactor), false);
Graphics::Surface tmp3 = tmp2->getSubArea(Common::Rect(0,(tmp2->h -_h)/2, tmp2->w, (tmp2->h + _h)/2)); // scale(_w, _h, false);
_gfx.copyFrom(tmp3);
tmp2->free(); tmp2->free();
delete tmp2; delete tmp2;
} else { } else {

View file

@ -303,7 +303,7 @@ public:
protected: protected:
void drawWidget() override; void drawWidget() override;
Graphics::ManagedSurface _gfx[kPicButtonStateMax + 1]; Graphics::ManagedSurface _gfx[kPicButtonStateMax + 1];
int _alpha; int _alpha;
bool _transparency; bool _transparency;
@ -460,6 +460,33 @@ protected:
ThemeEngine::WidgetBackground _backgroundType; ThemeEngine::WidgetBackground _backgroundType;
}; };
/* GameThumbButton */
class GameThumbButton : public PicButtonWidget {
public:
GameThumbButton(GuiObject *boss, int x, int y, int w, int h, const Common::U32String &tooltip = Common::U32String(), uint32 cmd = 0, uint8 hotkey = 0): PicButtonWidget(boss, x, y, w, h, tooltip, cmd, hotkey) {};
GameThumbButton(GuiObject *boss, const Common::String &name, const Common::U32String &tooltip = Common::U32String(), uint32 cmd = 0, uint8 hotkey = 0): PicButtonWidget(boss, name, tooltip, cmd, hotkey) {};
void setGfx(const Graphics::ManagedSurface *gfx, int statenum = kPicButtonStateEnabled, bool scale = true);
void setGfxFromTheme(const char *name, int statenum = kPicButtonStateEnabled, bool scale = true);
void drawWidget(void);
};
/* GameContainerWidget */
class GameContainerWidget : public ContainerWidget {
public:
GameContainerWidget(GuiObject *boss, int x, int y, int w, int h) : ContainerWidget(boss, x, y, w, h) {};
};
/* GridContainerWidget */
class GridContainerWidget : public ContainerWidget {
public:
GridContainerWidget(GuiObject *boss, int x, int y, int w, int h) : ContainerWidget(boss, x, y, w, h) {};
GridContainerWidget(GuiObject *boss, const Common::String &name) : ContainerWidget(boss, name) {};
int selectedGame;
Common::Array<GameContainerWidget> _entries;
};
/* OptionsContainerWidget */ /* OptionsContainerWidget */
class OptionsContainerWidget : public Widget { class OptionsContainerWidget : public Widget {
public: public: