Merge branch '652-allow-system-placeholders-to-be-a-combination-of-text-and-image-make-text-and-image-customizable'

This commit is contained in:
Leon Styhre 2021-11-05 11:47:37 +01:00
commit 9472f607cc
4 changed files with 125 additions and 31 deletions

View file

@ -362,8 +362,10 @@ Below are the default zIndex values per element type:
* `text name="md_description"` * `text name="md_description"`
* `text name="md_name"` * `text name="md_name"`
* System Logo/Text - 50 * System Logo/Text - 50
* `text name="logoText"`
* `image name="logo"` * `image name="logo"`
* `text name="logoText"`
* `image name="logoPlaceholderImage"`
* `text name="logoPlaceholderText"`
* Gamelist information - 50 * Gamelist information - 50
* `text name="gamelistInfo"` * `text name="gamelistInfo"`
* Badges - 50 * Badges - 50
@ -409,17 +411,26 @@ or to specify only a portion of the value of a theme property:
### Views, their elements, and themeable properties ### Views, their elements, and themeable properties
#### system #### system
* `helpsystem name="help"` - ALL * `helpsystem name="help"` - ALL
- The help system style for this view. - The help system style for this view.
* `carousel name="systemcarousel"` - ALL * `carousel name="systemcarousel"` - ALL
- The system logo carousel - The system logo carousel
* `image name="logo"` - PATH | COLOR * `image name="logo"` - PATH | COLOR
- A logo image, to be displayed in the system logo carousel. - A logo image, to be displayed in the system logo carousel.
* `image name="logoPlaceholderImage"` - ALL
- A logo image, to be displayed system name in the system logo carousel when no logo is available. Set the position
to `0.5 0.5` to center the image.
* `text name="logoPlaceholderText"` - ALL
- Logo text, to be displayed system name in the system logo carousel when no logo is available. The logo text is
displayed on top of `logoPlaceholderImage`. Set the position to `0.5 0.5` to center the text.
* `text name="logoText"` - FONT_PATH | COLOR | FORCE_UPPERCASE | LINE_SPACING | TEXT * `text name="logoText"` - FONT_PATH | COLOR | FORCE_UPPERCASE | LINE_SPACING | TEXT
- A logo text, to be displayed system name in the system logo carousel when no logo is available. - **Deprecated:** A logo text, to be displayed system name in the system logo carousel when no logo is available.
Ignored when `logoPlaceholderImage` or `logoPlaceholderText` are set.
* `text name="systemInfo"` - ALL * `text name="systemInfo"` - ALL
- Displays details of the system currently selected in the carousel. - Displays details of the system currently selected in the carousel.
* You can use extra elements (elements with `extra="true"`) to add your own backgrounds, etc. They will be displayed behind the carousel, and scroll relative to the carousel. * You can use extra elements (elements with `extra="true"`) to add your own backgrounds, etc. They will be displayed
behind the carousel, and scroll relative to the carousel.
#### basic #### basic

View file

@ -56,44 +56,102 @@ void SystemView::populate()
{ {
mEntries.clear(); mEntries.clear();
for (auto it = SystemData::sSystemVector.cbegin(); // Line break. for (auto it : SystemData::sSystemVector) {
it != SystemData::sSystemVector.cend(); it++) { const std::shared_ptr<ThemeData>& theme = it->getTheme();
const std::shared_ptr<ThemeData>& theme = (*it)->getTheme();
if (mViewNeedsReload) if (mViewNeedsReload)
getViewElements(theme); getViewElements(theme);
if ((*it)->isVisible()) { if (it->isVisible()) {
Entry e; Entry e;
e.name = (*it)->getName(); e.name = it->getName();
e.object = *it; e.object = it;
// Component offset. Used for positioning placeholders.
glm::vec3 offsetLogo = {0.0f, 0.0f, 0.0f};
glm::vec3 offsetLogoPlaceholderText = {0.0f, 0.0f, 0.0f};
// Make logo. // Make logo.
const ThemeData::ThemeElement* logoElem = theme->getElement("system", "logo", "image"); const ThemeData::ThemeElement* logoElem = theme->getElement("system", "logo", "image");
if (logoElem) { if (logoElem) {
std::string path = logoElem->get<std::string>("path"); auto path = logoElem->get<std::string>("path");
std::string defaultPath = std::string defaultPath =
logoElem->has("default") ? logoElem->get<std::string>("default") : ""; logoElem->has("default") ? logoElem->get<std::string>("default") : "";
if ((!path.empty() && ResourceManager::getInstance()->fileExists(path)) || if ((!path.empty() && ResourceManager::getInstance()->fileExists(path)) ||
(!defaultPath.empty() && (!defaultPath.empty() &&
ResourceManager::getInstance()->fileExists(defaultPath))) { ResourceManager::getInstance()->fileExists(defaultPath))) {
ImageComponent* logo = new ImageComponent(mWindow, false, false); auto* logo = new ImageComponent(mWindow, false, false);
logo->setMaxSize(mCarousel.logoSize * mCarousel.logoScale); logo->setMaxSize(mCarousel.logoSize * mCarousel.logoScale);
logo->applyTheme(theme, "system", "logo", ThemeFlags::PATH | ThemeFlags::COLOR); logo->applyTheme(theme, "system", "logo", ThemeFlags::PATH | ThemeFlags::COLOR);
logo->setRotateByTargetSize(true); logo->setRotateByTargetSize(true);
e.data.logo = std::shared_ptr<GuiComponent>(logo); e.data.logo = std::shared_ptr<GuiComponent>(logo);
} }
} }
// No logo available? Make placeholder.
if (!e.data.logo) { if (!e.data.logo) {
// No logo in theme; use text.
TextComponent* text = glm::vec2 resolution = glm::vec2{static_cast<float>(Renderer::getScreenWidth()),
new TextComponent(mWindow, (*it)->getName(), Font::get(FONT_SIZE_LARGE), static_cast<float>(Renderer::getScreenHeight())};
glm::vec3 center = {resolution.x / 2.0f, resolution.y / 2.0f, 1.0f};
// Placeholder Image.
logoElem = theme->getElement("system", "logoPlaceholderImage", "image");
if (logoElem) {
auto path = logoElem->get<std::string>("path");
std::string defaultPath =
logoElem->has("default") ? logoElem->get<std::string>("default") : "";
if ((!path.empty() && ResourceManager::getInstance()->fileExists(path)) ||
(!defaultPath.empty() &&
ResourceManager::getInstance()->fileExists(defaultPath))) {
auto* logo = new ImageComponent(mWindow, false, false);
logo->applyTheme(theme, "system", "logoPlaceholderImage", ThemeFlags::ALL);
if (!logoElem->has("size"))
logo->setMaxSize(mCarousel.logoSize * mCarousel.logoScale);
offsetLogo = logo->getPosition() - center;
logo->setRotateByTargetSize(true);
e.data.logo = std::shared_ptr<GuiComponent>(logo);
}
}
// Placeholder Text.
const ThemeData::ThemeElement* logoPlaceholderText =
theme->getElement("system", "logoPlaceholderText", "text");
if (logoPlaceholderText) {
// Element 'logoPlaceholderText' found in theme: place text
auto* text =
new TextComponent(mWindow, it->getName(), Font::get(FONT_SIZE_LARGE),
0x000000FF, ALIGN_CENTER); 0x000000FF, ALIGN_CENTER);
text->setSize(mCarousel.logoSize * mCarousel.logoScale); text->setSize(mCarousel.logoSize * mCarousel.logoScale);
text->applyTheme((*it)->getTheme(), "system", "logoText", if (mCarousel.type == VERTICAL || mCarousel.type == VERTICAL_WHEEL) {
ThemeFlags::FONT_PATH | ThemeFlags::FONT_SIZE | ThemeFlags::COLOR | text->setHorizontalAlignment(mCarousel.logoAlignment);
ThemeFlags::FORCE_UPPERCASE | ThemeFlags::LINE_SPACING | text->setVerticalAlignment(ALIGN_CENTER);
ThemeFlags::TEXT); }
else {
text->setHorizontalAlignment(ALIGN_CENTER);
text->setVerticalAlignment(mCarousel.logoAlignment);
}
text->applyTheme(it->getTheme(), "system", "logoPlaceholderText",
ThemeFlags::ALL);
if (!e.data.logo) {
e.data.logo = std::shared_ptr<GuiComponent>(text);
offsetLogo = text->getPosition() - center;
}
else {
e.data.logoPlaceholderText = std::shared_ptr<GuiComponent>(text);
offsetLogoPlaceholderText = text->getPosition() - center;
}
}
else {
// Fallback to legacy centered placeholder text.
auto* text =
new TextComponent(mWindow, it->getName(), Font::get(FONT_SIZE_LARGE),
0x000000FF, ALIGN_CENTER);
text->setSize(mCarousel.logoSize * mCarousel.logoScale);
text->applyTheme(it->getTheme(), "system", "logoText",
ThemeFlags::FONT_PATH | ThemeFlags::FONT_SIZE |
ThemeFlags::COLOR | ThemeFlags::FORCE_UPPERCASE |
ThemeFlags::LINE_SPACING | ThemeFlags::TEXT);
e.data.logo = std::shared_ptr<GuiComponent>(text); e.data.logo = std::shared_ptr<GuiComponent>(text);
if (mCarousel.type == VERTICAL || mCarousel.type == VERTICAL_WHEEL) { if (mCarousel.type == VERTICAL || mCarousel.type == VERTICAL_WHEEL) {
@ -105,6 +163,7 @@ void SystemView::populate()
text->setVerticalAlignment(mCarousel.logoAlignment); text->setVerticalAlignment(mCarousel.logoAlignment);
} }
} }
}
if (mCarousel.type == VERTICAL || mCarousel.type == VERTICAL_WHEEL) { if (mCarousel.type == VERTICAL || mCarousel.type == VERTICAL_WHEEL) {
if (mCarousel.logoAlignment == ALIGN_LEFT) if (mCarousel.logoAlignment == ALIGN_LEFT)
@ -124,10 +183,14 @@ void SystemView::populate()
} }
glm::vec2 denormalized{mCarousel.logoSize * e.data.logo->getOrigin()}; glm::vec2 denormalized{mCarousel.logoSize * e.data.logo->getOrigin()};
e.data.logo->setPosition(denormalized.x, denormalized.y, 0.0f); glm::vec3 v = {denormalized.x, denormalized.y, 0.0f};
e.data.logo->setPosition(v + offsetLogo);
if (e.data.logoPlaceholderText)
e.data.logoPlaceholderText->setPosition(
v + offsetLogoPlaceholderText);
// Make background extras. // Make background extras.
e.data.backgroundExtras = ThemeData::makeExtras((*it)->getTheme(), "system", mWindow); e.data.backgroundExtras = ThemeData::makeExtras(it->getTheme(), "system", mWindow);
// Sort the extras by z-index. // Sort the extras by z-index.
std::stable_sort( std::stable_sort(
@ -137,7 +200,7 @@ void SystemView::populate()
this->add(e); this->add(e);
} }
} }
if (mEntries.size() == 0) { if (mEntries.empty()) {
// Something is wrong, there is not a single system to show, check if UI mode is not full. // Something is wrong, there is not a single system to show, check if UI mode is not full.
if (!UIModeController::getInstance()->isUIModeFull()) { if (!UIModeController::getInstance()->isUIModeFull()) {
Settings::getInstance()->setString("UIMode", "full"); Settings::getInstance()->setString("UIMode", "full");
@ -615,6 +678,17 @@ void SystemView::renderCarousel(const glm::mat4& trans)
comp->setOpacity(static_cast<unsigned char>(opacity)); comp->setOpacity(static_cast<unsigned char>(opacity));
comp->render(logoTrans); comp->render(logoTrans);
if (mEntries.at(index).data.logoPlaceholderText) {
const std::shared_ptr<GuiComponent>& comp = mEntries.at(index).data.logoPlaceholderText;
if (mCarousel.type == VERTICAL_WHEEL || mCarousel.type == HORIZONTAL_WHEEL) {
comp->setRotationDegrees(mCarousel.logoRotation * distance);
comp->setRotationOrigin(mCarousel.logoRotationOrigin);
}
comp->setScale(scale);
comp->setOpacity(static_cast<unsigned char>(opacity));
comp->render(logoTrans);
}
} }
Renderer::popClipRect(); Renderer::popClipRect();
} }

View file

@ -29,6 +29,7 @@ enum CarouselType : unsigned int {
struct SystemViewData { struct SystemViewData {
std::shared_ptr<GuiComponent> logo; std::shared_ptr<GuiComponent> logo;
std::shared_ptr<GuiComponent> logoPlaceholderText;
std::vector<GuiComponent*> backgroundExtras; std::vector<GuiComponent*> backgroundExtras;
}; };

View file

@ -21,6 +21,14 @@ based on: 'recalbox-multi' by the Recalbox community
<fontPath>./core/fonts/Exo2-RegularCondensed.otf</fontPath> <fontPath>./core/fonts/Exo2-RegularCondensed.otf</fontPath>
<fontSize>0.035</fontSize> <fontSize>0.035</fontSize>
</text> </text>
<text name="logoPlaceholderText">
<pos>0.5 0.5</pos>
<origin>0.5 0.5</origin>
<fontPath>./core/fonts/Exo2-RegularCondensed.otf</fontPath>
<fontSize>0.035</fontSize>
<color>000000FF</color>
<text>${system.fullName}</text>
</text>
</view> </view>
</feature> </feature>