mirror of
https://github.com/RetroDECK/ES-DE.git
synced 2024-11-22 22:25:38 +00:00
Merge branch '63-add-badges-decals-e-g-for-favorites-completed-games-non-working-games-collections-and-folders' into 575-theme-add-a-modern-clean-switch-like-theme-as-an-official-theme-in-es-de-to-choose-from
This commit is contained in:
commit
1c6a80fcc7
|
@ -404,17 +404,19 @@ void DetailedGameListView::updateInfoPanel()
|
|||
mGenre.setValue(file->metadata.get("genre"));
|
||||
mPlayers.setValue(file->metadata.get("players"));
|
||||
|
||||
// Generate badges slots value based on the game metadata.
|
||||
std::stringstream ss;
|
||||
ss << (file->metadata.get("favorite").compare("true") ? "" : "favorite ");
|
||||
ss << (file->metadata.get("completed").compare("true") ? "" : "completed ");
|
||||
ss << (file->metadata.get("kidgame").compare("true") ? "" : "kidgame ");
|
||||
ss << (file->metadata.get("broken").compare("true") ? "" : "broken ");
|
||||
ss << (file->metadata.get("altemulator").compare("") ? "altemulator " : "");
|
||||
std::string slots = ss.str();
|
||||
if (!slots.empty())
|
||||
slots.pop_back();
|
||||
mBadges.setValue(slots);
|
||||
// Populate the badge slots based on game metadata.
|
||||
std::vector<std::string> badgeSlots;
|
||||
for (auto badge : mBadges.getBadgeTypes()) {
|
||||
if (badge == "altemulator") {
|
||||
if (file->metadata.get(badge).compare("") != 0)
|
||||
badgeSlots.push_back(badge);
|
||||
}
|
||||
else {
|
||||
if (file->metadata.get(badge).compare("true") == 0)
|
||||
badgeSlots.push_back(badge);
|
||||
}
|
||||
}
|
||||
mBadges.setBadges(badgeSlots);
|
||||
|
||||
mName.setValue(file->metadata.get("name"));
|
||||
|
||||
|
|
|
@ -445,17 +445,19 @@ void VideoGameListView::updateInfoPanel()
|
|||
mGenre.setValue(file->metadata.get("genre"));
|
||||
mPlayers.setValue(file->metadata.get("players"));
|
||||
|
||||
// Generate badges slots value based on the game metadata.
|
||||
std::stringstream ss;
|
||||
ss << (file->metadata.get("favorite").compare("true") ? "" : "favorite ");
|
||||
ss << (file->metadata.get("completed").compare("true") ? "" : "completed ");
|
||||
ss << (file->metadata.get("kidgame").compare("true") ? "" : "kidgame ");
|
||||
ss << (file->metadata.get("broken").compare("true") ? "" : "broken ");
|
||||
ss << (file->metadata.get("altemulator").compare("") ? "altemulator " : "");
|
||||
std::string slots = ss.str();
|
||||
if (!slots.empty())
|
||||
slots.pop_back();
|
||||
mBadges.setValue(slots);
|
||||
// Populate the badge slots based on game metadata.
|
||||
std::vector<std::string> badgeSlots;
|
||||
for (auto badge : mBadges.getBadgeTypes()) {
|
||||
if (badge == "altemulator") {
|
||||
if (file->metadata.get(badge).compare("") != 0)
|
||||
badgeSlots.push_back(badge);
|
||||
}
|
||||
else {
|
||||
if (file->metadata.get(badge).compare("true") == 0)
|
||||
badgeSlots.push_back(badge);
|
||||
}
|
||||
}
|
||||
mBadges.setBadges(badgeSlots);
|
||||
|
||||
mName.setValue(file->metadata.get("name"));
|
||||
|
||||
|
|
|
@ -7,72 +7,55 @@
|
|||
// Used by gamelist views.
|
||||
//
|
||||
|
||||
#define SLOT_FAVORITE "favorite"
|
||||
#define SLOT_COMPLETED "completed"
|
||||
#define SLOT_KIDGAME "kidgame"
|
||||
#define SLOT_BROKEN "broken"
|
||||
#define SLOT_ALTERNATIVE_EMULATOR "altemulator"
|
||||
|
||||
#include "components/BadgesComponent.h"
|
||||
|
||||
#include "Settings.h"
|
||||
#include "ThemeData.h"
|
||||
#include "resources/TextureResource.h"
|
||||
|
||||
// Available slot definitions.
|
||||
std::vector<std::string> BadgesComponent::mSlots = {SLOT_FAVORITE, SLOT_COMPLETED, SLOT_KIDS,
|
||||
SLOT_BROKEN, SLOT_ALTERNATIVE_EMULATOR};
|
||||
#include "utils/StringUtil.h"
|
||||
|
||||
BadgesComponent::BadgesComponent(Window* window)
|
||||
: FlexboxComponent(window)
|
||||
: FlexboxComponent{window, mBadgeImages}
|
||||
, mBadgeTypes{
|
||||
{SLOT_FAVORITE, SLOT_COMPLETED, SLOT_KIDGAME, SLOT_BROKEN, SLOT_ALTERNATIVE_EMULATOR}}
|
||||
{
|
||||
mBadgeIcons[SLOT_FAVORITE] = ":/graphics/badge_favorite.svg";
|
||||
mBadgeIcons[SLOT_COMPLETED] = ":/graphics/badge_completed.svg";
|
||||
mBadgeIcons[SLOT_KIDS] = ":/graphics/badge_kidgame.svg";
|
||||
mBadgeIcons[SLOT_KIDGAME] = ":/graphics/badge_kidgame.svg";
|
||||
mBadgeIcons[SLOT_BROKEN] = ":/graphics/badge_broken.svg";
|
||||
mBadgeIcons[SLOT_ALTERNATIVE_EMULATOR] = ":/graphics/badge_altemulator.svg";
|
||||
|
||||
ImageComponent mImageFavorite = ImageComponent(window);
|
||||
mImageComponents.insert({SLOT_FAVORITE, mImageFavorite});
|
||||
ImageComponent mImageCompleted = ImageComponent(window);
|
||||
mImageComponents.insert({SLOT_COMPLETED, mImageCompleted});
|
||||
ImageComponent mImageKids = ImageComponent(window);
|
||||
mImageComponents.insert({SLOT_KIDS, mImageKids});
|
||||
ImageComponent mImageBroken = ImageComponent(window);
|
||||
mImageComponents.insert({SLOT_BROKEN, mImageBroken});
|
||||
ImageComponent mImageAltEmulator = ImageComponent(window);
|
||||
mImageComponents.insert({SLOT_ALTERNATIVE_EMULATOR, mImageAltEmulator});
|
||||
}
|
||||
|
||||
BadgesComponent::~BadgesComponent()
|
||||
void BadgesComponent::setBadges(const std::vector<std::string>& badges)
|
||||
{
|
||||
for (GuiComponent* c : mChildren)
|
||||
c->clearChildren();
|
||||
clearChildren();
|
||||
mBadgeIcons.clear();
|
||||
mImageComponents.clear();
|
||||
std::map<std::string, bool> prevVisibility;
|
||||
|
||||
// Save the visibility status to know whether any badges changed.
|
||||
for (auto& image : mBadgeImages) {
|
||||
prevVisibility[image.first] = image.second.isVisible();
|
||||
image.second.setVisible(false);
|
||||
}
|
||||
|
||||
void BadgesComponent::setValue(const std::string& value)
|
||||
{
|
||||
mChildren.clear();
|
||||
if (!value.empty()) {
|
||||
std::string temp;
|
||||
std::istringstream ss(value);
|
||||
while (std::getline(ss, temp, ' ')) {
|
||||
if (!(temp == SLOT_FAVORITE || temp == SLOT_COMPLETED || temp == SLOT_KIDS ||
|
||||
temp == SLOT_BROKEN || temp == SLOT_ALTERNATIVE_EMULATOR))
|
||||
LOG(LogError) << "Badge slot '" << temp << "' is invalid.";
|
||||
else if (std::find(mSlots.begin(), mSlots.end(), temp) != mSlots.end())
|
||||
mChildren.push_back(&mImageComponents.find(temp)->second);
|
||||
}
|
||||
for (auto& badge : badges) {
|
||||
auto it = std::find_if(
|
||||
mBadgeImages.begin(), mBadgeImages.end(),
|
||||
[badge](std::pair<std::string, ImageComponent> image) { return image.first == badge; });
|
||||
|
||||
if (it != mBadgeImages.cend())
|
||||
it->second.setVisible(true);
|
||||
}
|
||||
|
||||
// Only recalculate the flexbox if any badges changed.
|
||||
for (auto& image : mBadgeImages) {
|
||||
if (prevVisibility[image.first] != image.second.isVisible()) {
|
||||
onSizeChanged();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
std::string BadgesComponent::getValue() const
|
||||
{
|
||||
std::stringstream ss;
|
||||
for (auto& slot : mSlots)
|
||||
ss << slot << ' ';
|
||||
std::string r = ss.str();
|
||||
r.pop_back();
|
||||
return r;
|
||||
}
|
||||
|
||||
void BadgesComponent::applyTheme(const std::shared_ptr<ThemeData>& theme,
|
||||
|
@ -82,39 +65,31 @@ void BadgesComponent::applyTheme(const std::shared_ptr<ThemeData>& theme,
|
|||
{
|
||||
using namespace ThemeFlags;
|
||||
|
||||
const ThemeData::ThemeElement* elem = theme->getElement(view, element, "badges");
|
||||
const ThemeData::ThemeElement* elem{theme->getElement(view, element, "badges")};
|
||||
if (!elem)
|
||||
return;
|
||||
|
||||
for (auto& slot : mSlots) {
|
||||
if (properties & PATH && elem->has(slot)) {
|
||||
if (elem->has("slots")) {
|
||||
std::vector<std::string> slots = Utils::String::delimitedStringToVector(
|
||||
Utils::String::toLower(elem->get<std::string>("slots")), " ");
|
||||
|
||||
for (auto slot : slots) {
|
||||
if (std::find(mBadgeTypes.cbegin(), mBadgeTypes.cend(), slot) != mBadgeTypes.end()) {
|
||||
if (properties & PATH && elem->has(slot))
|
||||
mBadgeIcons[slot] = elem->get<std::string>(slot);
|
||||
mImageComponents.find(slot)->second.setImage(mBadgeIcons[slot]);
|
||||
|
||||
ImageComponent badgeImage{mWindow};
|
||||
|
||||
badgeImage.setImage(mBadgeIcons[slot]);
|
||||
badgeImage.setVisible(false);
|
||||
mBadgeImages.push_back(std::make_pair(slot, badgeImage));
|
||||
}
|
||||
else {
|
||||
mImageComponents.find(slot)->second.setImage(mBadgeIcons[slot]);
|
||||
std::string teststring;
|
||||
}
|
||||
}
|
||||
|
||||
if (elem->has("slots")) {
|
||||
auto value = elem->get<std::string>("slots");
|
||||
mSlots = {};
|
||||
if (!value.empty()) {
|
||||
std::string temp;
|
||||
std::istringstream ss(value);
|
||||
while (std::getline(ss, temp, ' ')) {
|
||||
if (!(temp == SLOT_FAVORITE || temp == SLOT_COMPLETED || temp == SLOT_KIDS ||
|
||||
temp == SLOT_BROKEN || temp == SLOT_ALTERNATIVE_EMULATOR))
|
||||
LOG(LogError) << "Badge slot '" << temp << "' is invalid.";
|
||||
else
|
||||
mSlots.push_back(temp);
|
||||
}
|
||||
LOG(LogError) << "Invalid badge slot \"" << slot << "\" defined";
|
||||
}
|
||||
}
|
||||
|
||||
// Apply theme on the flexbox component parent.
|
||||
FlexboxComponent::applyTheme(theme, view, element, properties);
|
||||
|
||||
onSizeChanged();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,30 +11,14 @@
|
|||
#define ES_CORE_COMPONENTS_BADGES_COMPONENT_H
|
||||
|
||||
#include "FlexboxComponent.h"
|
||||
#include "GuiComponent.h"
|
||||
#include "ImageComponent.h"
|
||||
#include "renderers/Renderer.h"
|
||||
|
||||
#define NUM_SLOTS 4
|
||||
#define SLOT_FAVORITE "favorite"
|
||||
#define SLOT_COMPLETED "completed"
|
||||
#define SLOT_KIDS "kidgame"
|
||||
#define SLOT_BROKEN "broken"
|
||||
#define SLOT_ALTERNATIVE_EMULATOR "altemulator"
|
||||
|
||||
class TextureResource;
|
||||
|
||||
class BadgesComponent : public FlexboxComponent
|
||||
{
|
||||
public:
|
||||
BadgesComponent(Window* window);
|
||||
~BadgesComponent();
|
||||
|
||||
static std::shared_ptr<BadgesComponent>& getInstance();
|
||||
|
||||
std::string getValue() const override;
|
||||
// Should be a list of strings.
|
||||
void setValue(const std::string& value) override;
|
||||
std::vector<std::string> getBadgeTypes() { return mBadgeTypes; }
|
||||
void setBadges(const std::vector<std::string>& badges);
|
||||
|
||||
virtual void applyTheme(const std::shared_ptr<ThemeData>& theme,
|
||||
const std::string& view,
|
||||
|
@ -42,9 +26,9 @@ public:
|
|||
unsigned int properties) override;
|
||||
|
||||
private:
|
||||
static std::vector<std::string> mSlots;
|
||||
std::vector<std::string> mBadgeTypes;
|
||||
std::map<std::string, std::string> mBadgeIcons;
|
||||
std::map<std::string, ImageComponent> mImageComponents;
|
||||
std::vector<std::pair<std::string, ImageComponent>> mBadgeImages;
|
||||
};
|
||||
|
||||
#endif // ES_CORE_COMPONENTS_BADGES_COMPONENT_H
|
||||
|
|
|
@ -7,35 +7,41 @@
|
|||
// Used by gamelist views.
|
||||
//
|
||||
|
||||
#include "components/FlexboxComponent.h"
|
||||
#include "Settings.h"
|
||||
#include "ThemeData.h"
|
||||
#include "resources/TextureResource.h"
|
||||
#define DEFAULT_DIRECTION Direction::row
|
||||
#define DEFAULT_ALIGN Align::center
|
||||
#define DEFAULT_ITEMS_PER_LINE 4
|
||||
#define DEFAULT_LINES 1
|
||||
#define DEFAULT_MARGIN_X 10.0f
|
||||
#define DEFAULT_MARGIN_Y 10.0f
|
||||
|
||||
FlexboxComponent::FlexboxComponent(Window* window)
|
||||
: GuiComponent(window)
|
||||
, mDirection(DEFAULT_DIRECTION)
|
||||
, mAlign(DEFAULT_ALIGN)
|
||||
, mItemsPerLine(DEFAULT_ITEMS_PER_LINE)
|
||||
, mLines(DEFAULT_LINES)
|
||||
, mItemMargin({DEFAULT_MARGIN_X, DEFAULT_MARGIN_Y})
|
||||
, mLayoutValid(false)
|
||||
#include "components/FlexboxComponent.h"
|
||||
|
||||
#include "ThemeData.h"
|
||||
|
||||
FlexboxComponent::FlexboxComponent(Window* window,
|
||||
std::vector<std::pair<std::string, ImageComponent>>& images)
|
||||
: GuiComponent{window}
|
||||
, mDirection{DEFAULT_DIRECTION}
|
||||
, mAlign{DEFAULT_ALIGN}
|
||||
, mImages(images)
|
||||
, mItemsPerLine{DEFAULT_ITEMS_PER_LINE}
|
||||
, mLines{DEFAULT_LINES}
|
||||
, mItemMargin{glm::vec2{DEFAULT_MARGIN_X, DEFAULT_MARGIN_Y}}
|
||||
, mLayoutValid{false}
|
||||
{
|
||||
}
|
||||
|
||||
void FlexboxComponent::onSizeChanged() { mLayoutValid = false; }
|
||||
|
||||
void FlexboxComponent::computeLayout()
|
||||
{
|
||||
// Start placing items in the top-left.
|
||||
float anchorX = 0;
|
||||
float anchorY = 0;
|
||||
float anchorOriginX = 0;
|
||||
float anchorOriginY = 0;
|
||||
float anchorX{0.0f};
|
||||
float anchorY{0.0f};
|
||||
float anchorOriginX{0.0f};
|
||||
float anchorOriginY{0.0f};
|
||||
|
||||
// Translation directions when placing items.
|
||||
glm::ivec2 directionLine = {1, 0};
|
||||
glm::ivec2 directionRow = {0, 1};
|
||||
glm::ivec2 directionLine{1, 0};
|
||||
glm::ivec2 directionRow{0, 1};
|
||||
|
||||
// Change direction.
|
||||
if (mDirection == Direction::column) {
|
||||
|
@ -43,21 +49,23 @@ void FlexboxComponent::computeLayout()
|
|||
directionRow = {1, 0};
|
||||
}
|
||||
|
||||
// Compute children maximal dimensions.
|
||||
// Compute maximum image dimensions.
|
||||
glm::vec2 grid;
|
||||
if (mDirection == Direction::row)
|
||||
grid = {mItemsPerLine, mLines};
|
||||
else
|
||||
grid = {mLines, mItemsPerLine};
|
||||
glm::vec2 maxItemSize = (mSize + mItemMargin - grid * mItemMargin) / grid;
|
||||
glm::vec2 maxItemSize{(mSize + mItemMargin - grid * mItemMargin) / grid};
|
||||
|
||||
// Set final children dimensions.
|
||||
for (auto i : mChildren) {
|
||||
auto oldSize = i->getSize();
|
||||
// Set final image dimensions.
|
||||
for (auto& image : mImages) {
|
||||
if (!image.second.isVisible())
|
||||
continue;
|
||||
auto oldSize{image.second.getSize()};
|
||||
if (oldSize.x == 0)
|
||||
oldSize.x = maxItemSize.x;
|
||||
glm::vec2 sizeMaxX = {maxItemSize.x, oldSize.y * (maxItemSize.x / oldSize.x)};
|
||||
glm::vec2 sizeMaxY = {oldSize.x * (maxItemSize.y / oldSize.y), maxItemSize.y};
|
||||
glm::vec2 sizeMaxX{maxItemSize.x, oldSize.y * (maxItemSize.x / oldSize.x)};
|
||||
glm::vec2 sizeMaxY{oldSize.x * (maxItemSize.y / oldSize.y), maxItemSize.y};
|
||||
glm::vec2 newSize;
|
||||
if (sizeMaxX.y > maxItemSize.y)
|
||||
newSize = sizeMaxY;
|
||||
|
@ -65,23 +73,27 @@ void FlexboxComponent::computeLayout()
|
|||
newSize = sizeMaxX;
|
||||
else
|
||||
newSize = sizeMaxX.x * sizeMaxX.y >= sizeMaxY.x * sizeMaxY.y ? sizeMaxX : sizeMaxY;
|
||||
i->setSize(newSize);
|
||||
image.second.setResize(newSize.x, newSize.y);
|
||||
}
|
||||
|
||||
// Pre-compute layout parameters.
|
||||
float lineWidth = (mDirection == Direction::row ? (maxItemSize.y + mItemMargin.y) :
|
||||
(maxItemSize.x + mItemMargin.x));
|
||||
float anchorXStart = anchorX;
|
||||
float anchorYStart = anchorY;
|
||||
float anchorXStart{anchorX};
|
||||
float anchorYStart{anchorY};
|
||||
|
||||
// Iterate through the children.
|
||||
for (int i = 0; i < static_cast<int>(mChildren.size()); i++) {
|
||||
GuiComponent* child = mChildren[i];
|
||||
auto size = child->getSize();
|
||||
int i = 0;
|
||||
|
||||
// Iterate through the images.
|
||||
for (auto& image : mImages) {
|
||||
if (!image.second.isVisible())
|
||||
continue;
|
||||
|
||||
auto size{image.second.getSize()};
|
||||
|
||||
// Top-left anchor position.
|
||||
float x = anchorX - anchorOriginX * size.x;
|
||||
float y = anchorY - anchorOriginY * size.y;
|
||||
float x{anchorX - anchorOriginX * size.x};
|
||||
float y{anchorY - anchorOriginY * size.y};
|
||||
|
||||
// Apply alignment
|
||||
if (mAlign == Align::end) {
|
||||
|
@ -93,7 +105,7 @@ void FlexboxComponent::computeLayout()
|
|||
y += directionLine.y == 0 ? (maxItemSize.y - size.y) / 2 : 0;
|
||||
}
|
||||
else if (mAlign == Align::stretch && mDirection == Direction::row) {
|
||||
child->setSize(child->getSize().x, maxItemSize.y);
|
||||
image.second.setSize(image.second.getSize().x, maxItemSize.y);
|
||||
}
|
||||
|
||||
// Apply origin.
|
||||
|
@ -103,10 +115,10 @@ void FlexboxComponent::computeLayout()
|
|||
y -= mOrigin.y * mSize.y;
|
||||
|
||||
// Store final item position.
|
||||
child->setPosition(getPosition().x + x, getPosition().y + y);
|
||||
image.second.setPosition(getPosition().x + x, getPosition().y + y);
|
||||
|
||||
// Translate anchor.
|
||||
if ((i + 1) % std::max(1, static_cast<int>(mItemsPerLine)) != 0) {
|
||||
if ((i++ + 1) % std::max(1, static_cast<int>(mItemsPerLine)) != 0) {
|
||||
// Translate on same line.
|
||||
anchorX += (size.x + mItemMargin.x) * static_cast<float>(directionLine.x);
|
||||
anchorY += (size.y + mItemMargin.y) * static_cast<float>(directionLine.y);
|
||||
|
@ -135,7 +147,8 @@ void FlexboxComponent::render(const glm::mat4& parentTrans)
|
|||
if (!mLayoutValid)
|
||||
computeLayout();
|
||||
|
||||
renderChildren(parentTrans);
|
||||
for (auto& image : mImages)
|
||||
image.second.render(parentTrans);
|
||||
}
|
||||
|
||||
void FlexboxComponent::applyTheme(const std::shared_ptr<ThemeData>& theme,
|
||||
|
@ -149,7 +162,6 @@ void FlexboxComponent::applyTheme(const std::shared_ptr<ThemeData>& theme,
|
|||
glm::vec2{static_cast<float>(Renderer::getScreenWidth()),
|
||||
static_cast<float>(Renderer::getScreenHeight())}};
|
||||
|
||||
// TODO: How to do this without explicit 'badges' property?
|
||||
const ThemeData::ThemeElement* elem = theme->getElement(view, element, "badges");
|
||||
if (!elem)
|
||||
return;
|
||||
|
@ -179,9 +191,3 @@ void FlexboxComponent::applyTheme(const std::shared_ptr<ThemeData>& theme,
|
|||
// Layout no longer valid.
|
||||
mLayoutValid = false;
|
||||
}
|
||||
|
||||
std::vector<HelpPrompt> FlexboxComponent::getHelpPrompts()
|
||||
{
|
||||
std::vector<HelpPrompt> prompts;
|
||||
return prompts;
|
||||
}
|
||||
|
|
|
@ -11,67 +11,75 @@
|
|||
#define ES_CORE_COMPONENTS_FLEXBOX_COMPONENT_H
|
||||
|
||||
#include "GuiComponent.h"
|
||||
#include "renderers/Renderer.h"
|
||||
|
||||
// Default values.
|
||||
#define DEFAULT_DIRECTION Direction::row
|
||||
#define DEFAULT_ALIGN Align::center
|
||||
#define DEFAULT_ITEMS_PER_LINE 4
|
||||
#define DEFAULT_LINES 1
|
||||
#define DEFAULT_MARGIN_X 10.0f
|
||||
#define DEFAULT_MARGIN_Y 10.0f
|
||||
#include "components/ImageComponent.h"
|
||||
|
||||
class FlexboxComponent : public GuiComponent
|
||||
{
|
||||
public:
|
||||
enum class Direction : char { row, column };
|
||||
enum class Align : char { start, end, center, stretch };
|
||||
enum class Direction : char {
|
||||
row, // Replace with AllowShortEnumsOnASingleLine: false (clang-format >=11.0).
|
||||
column
|
||||
};
|
||||
|
||||
explicit FlexboxComponent(Window* window);
|
||||
enum class Align : char {
|
||||
start, // Replace with AllowShortEnumsOnASingleLine: false (clang-format >=11.0).
|
||||
end,
|
||||
center,
|
||||
stretch
|
||||
};
|
||||
|
||||
explicit FlexboxComponent(Window* window,
|
||||
std::vector<std::pair<std::string, ImageComponent>>& images);
|
||||
|
||||
// Getters/Setters for rendering options.
|
||||
[[nodiscard]] Align getAlign() const { return mAlign; };
|
||||
Align getAlign() const { return mAlign; }
|
||||
void setAlign(Align value)
|
||||
{
|
||||
mAlign = value;
|
||||
mLayoutValid = false;
|
||||
};
|
||||
[[nodiscard]] unsigned int getItemsPerLine() const { return mItemsPerLine; };
|
||||
}
|
||||
|
||||
unsigned int getItemsPerLine() const { return mItemsPerLine; }
|
||||
void setItemsPerLine(unsigned int value)
|
||||
{
|
||||
mItemsPerLine = value;
|
||||
mLayoutValid = false;
|
||||
};
|
||||
[[nodiscard]] unsigned int getLines() const { return mLines; };
|
||||
}
|
||||
|
||||
unsigned int getLines() const { return mLines; }
|
||||
void setLines(unsigned int value)
|
||||
{
|
||||
mLines = value;
|
||||
mLayoutValid = false;
|
||||
};
|
||||
[[nodiscard]] glm::vec2 getItemMargin() const { return mItemMargin; };
|
||||
}
|
||||
|
||||
glm::vec2 getItemMargin() const { return mItemMargin; }
|
||||
void setItemMargin(glm::vec2 value)
|
||||
{
|
||||
mItemMargin = value;
|
||||
mLayoutValid = false;
|
||||
};
|
||||
}
|
||||
|
||||
void onSizeChanged() override;
|
||||
void onSizeChanged() override { mLayoutValid = false; }
|
||||
void render(const glm::mat4& parentTrans) override;
|
||||
void applyTheme(const std::shared_ptr<ThemeData>& theme,
|
||||
const std::string& view,
|
||||
const std::string& element,
|
||||
unsigned int properties) override;
|
||||
std::vector<HelpPrompt> getHelpPrompts() override;
|
||||
|
||||
private:
|
||||
// Calculate flexbox layout.
|
||||
void computeLayout();
|
||||
|
||||
// Rendering options.
|
||||
// Layout options.
|
||||
Direction mDirection;
|
||||
Align mAlign;
|
||||
|
||||
std::vector<std::pair<std::string, ImageComponent>>& mImages;
|
||||
|
||||
unsigned int mItemsPerLine;
|
||||
unsigned int mLines;
|
||||
|
||||
glm::vec2 mItemMargin;
|
||||
bool mLayoutValid;
|
||||
};
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
viewBox="0 0 21.166666 29.633334"
|
||||
version="1.1"
|
||||
id="svg4842"
|
||||
inkscape:version="1.0.2 (e86c870879, 2021-01-15)"
|
||||
inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)"
|
||||
sodipodi:docname="badge_altemulator.svg">
|
||||
<defs
|
||||
id="defs4836" />
|
||||
|
@ -23,15 +23,15 @@
|
|||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="7.0546875"
|
||||
inkscape:cx="29.041584"
|
||||
inkscape:cy="62.825107"
|
||||
inkscape:zoom="12.442154"
|
||||
inkscape:cx="-18.41824"
|
||||
inkscape:cy="59.681612"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:current-layer="layer1"
|
||||
inkscape:current-layer="layer2"
|
||||
showgrid="false"
|
||||
inkscape:window-width="3440"
|
||||
inkscape:window-height="1355"
|
||||
inkscape:window-x="2560"
|
||||
inkscape:window-width="3840"
|
||||
inkscape:window-height="2065"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1"
|
||||
fit-margin-top="0"
|
||||
|
@ -51,7 +51,7 @@
|
|||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
|
@ -401,30 +401,30 @@
|
|||
aria-label="ALT EMU"
|
||||
transform="scale(1.0680187,0.93631321)"
|
||||
id="text41"
|
||||
style="font-size:4.97619px;line-height:1.25;font-family:'Bebas Neue';-inkscape-font-specification:'Bebas Neue';display:inline;stroke-width:0.0339285">
|
||||
style="font-size:4.97619px;line-height:1.25;font-family:'Bebas Neue';-inkscape-font-specification:'Bebas Neue';display:inline;stroke-width:0.0339285;fill:#f0f0f0;fill-opacity:1">
|
||||
<path
|
||||
d="m 1.7229501,4.7457954 c 0,0.024881 0.019905,0.03981 0.044786,0.03981 0.1642143,0.00995 0.3383809,0.014928 0.5075714,0.014928 0.1642142,0 0.2537857,-0.00498 0.4130238,-0.014928 0.034833,-0.1791429 0.06469,-0.3632619 0.094548,-0.547381 h 0.4627856 c 0.024881,0.1691905 0.054738,0.338381 0.089571,0.4976191 0.00498,0.029857 0.029857,0.049762 0.054738,0.049762 0.1741666,0.014928 0.3184761,0.014928 0.4876666,0.014928 0.1691904,0 0.2786666,-0.00498 0.4329285,-0.014928 C 4.1662594,3.8202241 3.9323785,2.8050813 3.7432833,1.8496528 3.7383071,1.8247719 3.7134261,1.7998909 3.6885452,1.7998909 3.449688,1.7949147 3.2158071,1.7899385 2.97695,1.7899385 c -0.233881,0 -0.4627857,0 -0.6867143,0.00995 -0.184119,0.9205952 -0.393119,1.8809999 -0.5424047,2.7916426 -0.00995,0.049762 -0.024881,0.1443096 -0.024881,0.1542619 z M 2.8674738,3.5913193 c 0.03981,-0.3732142 0.079619,-0.7464285 0.1244047,-1.1146665 0.049762,0.3732142 0.099524,0.7464285 0.1542619,1.1146665 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.97619px;font-family:Digitalt;-inkscape-font-specification:Digitalt;fill:#ffffff;stroke-width:0.0339285"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.97619px;font-family:Digitalt;-inkscape-font-specification:Digitalt;fill:#f0f0f0;stroke-width:0.0339285;fill-opacity:1"
|
||||
id="path975" />
|
||||
<path
|
||||
d="m 4.4946808,3.2927479 c 0,0.497619 0.00995,0.9753333 0.019905,1.4430952 0,0.029857 0.019905,0.049762 0.049762,0.049762 0.1642143,0.00995 0.8857619,0.024881 1.0549523,0.024881 0.1642143,0 0.5772381,-0.00498 0.7364762,-0.014929 0,-0.1244047 0,-0.2438333 0,-0.3632618 0,-0.1393334 0,-0.2786667 0,-0.4329286 C 6.3507997,3.974486 6.3308949,3.949605 6.306014,3.949605 6.1368235,3.9446288 5.7138474,3.9396526 5.5446569,3.9396526 h -0.019905 c 0,-0.2089999 0.00498,-0.4229761 0.00498,-0.6469047 0,-0.497619 -0.00995,-0.9753332 -0.019905,-1.4430951 0,-0.024881 -0.024881,-0.049762 -0.049762,-0.049762 -0.1691905,-0.00498 -0.3433572,-0.00995 -0.5125476,-0.00995 -0.1642143,0 -0.2786667,0.00498 -0.4329286,0.00995 -0.014928,0.497619 -0.019905,0.995238 -0.019905,1.492857 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.97619px;font-family:Digitalt;-inkscape-font-specification:Digitalt;fill:#ffffff;stroke-width:0.0339285"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.97619px;font-family:Digitalt;-inkscape-font-specification:Digitalt;fill:#f0f0f0;stroke-width:0.0339285;fill-opacity:1"
|
||||
id="path977" />
|
||||
<path
|
||||
d="m 6.1318408,2.1780813 c 0,0.1343572 0,0.2687143 0.00498,0.4080476 0,0.029857 0.019905,0.049762 0.049762,0.049762 0.084595,0.00498 0.3234523,0.00995 0.5473809,0.014929 0,0.209 0,0.4130238 0,0.6419285 0,0.497619 0.00995,0.9753333 0.019905,1.4430952 0,0.029857 0.019905,0.049762 0.049762,0.049762 0.1642143,0.00995 0.338381,0.014928 0.5075714,0.014928 0.1642143,0 0.2786667,-0.00498 0.4379048,-0.014928 0.00995,-0.4976191 0.019905,-0.9952381 0.019905,-1.4928571 0,-0.2289047 -0.00498,-0.4329285 -0.00995,-0.6369523 0.2587619,0 0.5225,-0.00498 0.6070952,-0.00995 0,-0.1244047 0,-0.2488095 0,-0.3682381 0,-0.1443095 0,-0.2836428 0,-0.4279523 -0.00498,-0.024881 -0.024881,-0.049762 -0.049762,-0.049762 -0.1691904,-0.00498 -0.8608809,-0.00995 -1.0300713,-0.00995 -0.1642143,0 -0.995238,0.00498 -1.1494999,0.00995 -0.00498,0.1343571 -0.00498,0.2587619 -0.00498,0.3781904 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.97619px;font-family:Digitalt;-inkscape-font-specification:Digitalt;fill:#ffffff;stroke-width:0.0339285"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.97619px;font-family:Digitalt;-inkscape-font-specification:Digitalt;fill:#f0f0f0;stroke-width:0.0339285;fill-opacity:1"
|
||||
id="path979" />
|
||||
<path
|
||||
d="m 10.067999,3.2927479 c 0,0.497619 0.01,0.9753333 0.0199,1.4430952 0,0.029857 0.0199,0.049762 0.04976,0.049762 0.164215,0.00995 0.885762,0.024881 1.054953,0.024881 0.164214,0 0.696666,-0.00498 0.855904,-0.014929 0,-0.1244047 0,-0.2438333 0,-0.3632618 0,-0.1393334 0,-0.2786667 0,-0.4329286 -0.005,-0.024881 -0.02488,-0.049762 -0.04976,-0.049762 -0.169191,-0.00498 -0.711596,-0.00995 -0.880786,-0.00995 h -0.06469 c 0,-0.084595 0,-0.1691904 0,-0.2587618 h 0.646905 c 0,-0.1194286 0,-0.2239286 0,-0.3284286 0,-0.1194286 0,-0.2388571 0,-0.3781904 -0.005,-0.024881 -0.02488,-0.049762 -0.04976,-0.049762 -0.129381,0 -0.398095,-0.00498 -0.597143,-0.00498 0,-0.089571 0,-0.1791429 0,-0.2637381 0.0846,0 0.154262,0 0.194072,0 0.164214,0 0.631976,0 0.791214,-0.00995 0,-0.1244047 0,-0.2438333 0,-0.3632619 0,-0.1393333 0,-0.2786666 0,-0.4329285 -0.005,-0.024881 -0.02488,-0.049762 -0.04976,-0.049762 -0.16919,-0.00498 -0.701643,-0.00995 -0.870833,-0.00995 -0.164214,0 -0.87581,0.00498 -1.030071,0.00995 -0.01493,0.497619 -0.0199,0.995238 -0.0199,1.492857 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.97619px;font-family:Digitalt;-inkscape-font-specification:Digitalt;fill:#ffffff;stroke-width:0.0339285"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.97619px;font-family:Digitalt;-inkscape-font-specification:Digitalt;fill:#f0f0f0;stroke-width:0.0339285;fill-opacity:1"
|
||||
id="path981" />
|
||||
<path
|
||||
d="m 12.327182,3.2927479 c 0,0.497619 0.01,0.9753333 0.0199,1.4430952 0,0.029857 0.01991,0.049762 0.04976,0.049762 0.164215,0.00995 0.363262,0.014928 0.482691,0.014928 0.164214,0 0.253786,-0.00498 0.413024,-0.014928 l -0.0199,-1.3485476 0.542405,1.099738 0.04976,0.00995 0.05474,-0.00995 0.567285,-1.1544761 c 0,0.4677619 0.0199,0.915619 0.02986,1.3535238 0,0.029857 0.0199,0.049762 0.04976,0.049762 0.164215,0.00995 0.338381,0.014928 0.45781,0.014928 0.164214,0 0.243833,-0.00498 0.388143,-0.014928 0.01,-0.4976191 0.0199,-0.9952381 0.0199,-1.4928571 0,-0.497619 -0.01,-0.9753332 -0.0199,-1.4430951 0,-0.024881 -0.02488,-0.044786 -0.04976,-0.049762 -0.139334,-0.00498 -0.293596,-0.00995 -0.462786,-0.00995 -0.139333,0 -0.258762,0.00498 -0.348333,0.014929 -0.02488,0 -0.04479,0.024881 -0.05972,0.044786 l -0.627,1.2788809 -0.622023,-1.2788809 c -0.01,-0.019905 -0.02986,-0.044786 -0.05474,-0.049762 -0.149286,-0.00498 -0.263738,-0.00995 -0.432929,-0.00995 -0.164214,0 -0.253786,0.00498 -0.408048,0.00995 -0.01493,0.497619 -0.0199,0.995238 -0.0199,1.492857 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.97619px;font-family:Digitalt;-inkscape-font-specification:Digitalt;fill:#ffffff;stroke-width:0.0339285"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.97619px;font-family:Digitalt;-inkscape-font-specification:Digitalt;fill:#f0f0f0;stroke-width:0.0339285;fill-opacity:1"
|
||||
id="path983" />
|
||||
<path
|
||||
d="m 15.696059,3.3126527 c 0,1.2539999 0.447857,1.5227142 1.348547,1.5227142 0.701643,-0.034833 1.109691,-0.442881 1.109691,-1.5227142 0,-0.497619 -0.01,-0.995238 -0.01991,-1.4629999 0,-0.024881 -0.02488,-0.049762 -0.04976,-0.049762 -0.16919,-0.00498 -0.343357,-0.00995 -0.512548,-0.00995 -0.164214,0 -0.278666,0.00498 -0.432928,0.00995 -0.01493,0.497619 -0.01991,1.1644285 -0.01991,1.6620475 0,0.4428809 -0.05474,0.5075714 -0.189095,0.5075714 -0.134357,0 -0.199048,-0.06469 -0.199048,-0.5075714 0,-0.497619 -0.01,-1.1445237 -0.0199,-1.6122856 0,-0.024881 -0.02488,-0.049762 -0.04976,-0.049762 -0.169191,-0.00498 -0.343357,-0.00995 -0.512548,-0.00995 -0.164214,0 -0.278667,0.00498 -0.432928,0.00995 -0.01493,0.497619 -0.0199,1.0151428 -0.0199,1.5127618 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.97619px;font-family:Digitalt;-inkscape-font-specification:Digitalt;fill:#ffffff;stroke-width:0.0339285"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.97619px;font-family:Digitalt;-inkscape-font-specification:Digitalt;fill:#f0f0f0;stroke-width:0.0339285;fill-opacity:1"
|
||||
id="path985" />
|
||||
</g>
|
||||
</g>
|
||||
|
|
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 51 KiB |
Loading…
Reference in a new issue