Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion include/gui/gfx.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ namespace GFX {
void DrawTop(void);
void DrawBottom();
void DrawSprite(int img, int x, int y, float ScaleX = 1, float ScaleY = 1);
void DrawBox(float xPos, float yPos, float width = 50, float height = 50, bool selected = false, uint32_t clr = UIThemes->BoxInside());
void DrawBox(float xPos, float yPos, float width = 50, float height = 50, bool selected = false, uint32_t clr = 0, uint32_t borderClr = 0);
void DrawCheckbox(float xPos, float yPos, bool selected);
void DrawToggle(float xPos, float yPos, bool toggled);
void DrawTime();
Expand Down
1 change: 1 addition & 0 deletions include/store/store.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ class Store {
std::vector<std::string> GetScreenshotList(int index) const;
std::vector<std::string> GetScreenshotNames(int index) const;
std::string GetReleaseNotes(int index) const;
uint32_t GetAccentColorEntry(int index) const;

std::vector<std::string> GetDownloadList(int index) const;

Expand Down
3 changes: 3 additions & 0 deletions include/store/storeEntry.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ class StoreEntry {
int GetSheetIndex() const { return this->SheetIndex; };
int GetEntryIndex() const { return this->EntryIndex; };

uint32_t GetAccentColor() const { return this->AccentColor; };

std::vector<std::string> GetCategoryFull() const { return this->FullCategory; };
std::vector<std::string> GetConsoleFull() const { return this->FullConsole; };
std::vector<std::string> GetSizes() const { return this->Sizes; };
Expand All @@ -73,6 +75,7 @@ class StoreEntry {
int Stars;
C2D_Image Icon;
int SheetIndex, EntryIndex, Marks;
uint32_t AccentColor;
std::vector<std::string> FullCategory, FullConsole, Sizes, Types, Screenshots, ScreenshotNames;
bool UpdateAvailable;
};
Expand Down
7 changes: 6 additions & 1 deletion include/utils/config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,10 @@ class Config {
std::string theme() const { return this->v_theme; };
void theme(const std::string &v) { this->v_theme = v; if (!this->changesMade) this->changesMade = true; };

/* If accent color should be used. */
bool useAccentColor() const { return this->v_useAccentColor; };
void useAccentColor(bool v) { this->v_useAccentColor = v; };

/* If showing prompt if action failed / succeeded. */
bool prompt() const { return this->v_prompt; };
void prompt(bool v) { this->v_prompt = v; if (!this->changesMade) this->changesMade = true; };
Expand All @@ -122,7 +126,8 @@ class Config {
v_shortcutPath = "sdmc:/3ds/Universal-Updater/shortcuts", v_firmPath = "sdmc:/luma/payloads", v_theme = "Default";

bool v_list = false, v_autoUpdate = true, v_metadata = true, v_updateCheck = true, v_updateNightly = false,
v_showBg = false, v_customFont = false, v_changelog = true, v_prompt = true, v_3dsxInFolder = false;
v_showBg = false, v_customFont = false, v_changelog = true, v_prompt = true, v_3dsxInFolder = false,
v_useAccentColor = true;
};

#endif
1 change: 1 addition & 0 deletions include/utils/stringutils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ namespace StringUtils {
std::string GetMarkString(int marks);
std::vector<std::string> GetMarks(int marks);
std::string format(const char *fmt_str, ...);
uint32_t ParseColorHexString(std::string_view str);
};

#endif
1 change: 1 addition & 0 deletions romfs/lang/en/app.json
Original file line number Diff line number Diff line change
Expand Up @@ -155,5 +155,6 @@
"UPDATING_SPRITE_SHEET": "Updating Spritesheet...",
"UPDATING_SPRITE_SHEET2": "Updating Spritesheet %i of %i...",
"UPDATING_UNISTORE": "Updating UniStore...",
"USE_ACCENT_COLOR": "Use Accent Color of Entries",
"VERSION": "Version"
}
17 changes: 11 additions & 6 deletions source/gui/gfx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,17 +52,22 @@ void GFX::DrawBottom() {
float height: The Height of the button.
bool selected: If selected, or not.
uint32_t clr: (Optional) The color of the inside of the box.
uint32_t borderClr: (Optional) The color of the border if selected.
*/
void GFX::DrawBox(float xPos, float yPos, float width, float height, bool selected, uint32_t clr) {
Gui::Draw_Rect(xPos, yPos, width, height, UIThemes->BoxInside()); // Draw middle BG.
void GFX::DrawBox(float xPos, float yPos, float width, float height, bool selected, uint32_t clr, uint32_t borderClr) {
if (!clr) clr = UIThemes->BoxInside();

Gui::Draw_Rect(xPos, yPos, width, height, clr); // Draw middle BG.

if (selected) {
static constexpr int depth = 3;

Gui::Draw_Rect(xPos - depth, yPos - depth, width + depth * 2, depth, UIThemes->BoxSelected()); // Top.
Gui::Draw_Rect(xPos - depth, yPos - depth, depth, height + depth * 2, UIThemes->BoxSelected()); // Left.
Gui::Draw_Rect(xPos + width, yPos - depth, depth, height + depth * 2, UIThemes->BoxSelected()); // Right.
Gui::Draw_Rect(xPos - depth, yPos + height, width + depth * 2, depth, UIThemes->BoxSelected()); // Bottom.
if (!borderClr) borderClr = UIThemes->BoxSelected();

Gui::Draw_Rect(xPos - depth, yPos - depth, width + depth * 2, depth, borderClr); // Top.
Gui::Draw_Rect(xPos - depth, yPos - depth, depth, height + depth * 2, borderClr); // Left.
Gui::Draw_Rect(xPos + width, yPos - depth, depth, height + depth * 2, borderClr); // Right.
Gui::Draw_Rect(xPos - depth, yPos + height, width + depth * 2, depth, borderClr); // Bottom.
}
}

Expand Down
15 changes: 10 additions & 5 deletions source/menu/downList.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,20 +108,25 @@ static bool CreateShortcut(const std::string &entryName, int index, const std::s
const std::vector<std::string> &sizes: Const Reference to the download sizes as a vector of strings.
*/
void StoreUtils::DrawDownList(const std::vector<std::string> &entries, bool fetch, const std::unique_ptr<StoreEntry> &entry, const std::vector<std::string> &sizes, const std::vector<bool> &installs) {
uint32_t accentColor = 0;

/* For the Top Screen. */
if (StoreUtils::store && StoreUtils::store->GetValid() && !fetch && entry) {
if (entries.size() > 0) {
Gui::Draw_Rect(0, 174, 400, 66, UIThemes->DownListPrev());
accentColor = config->useAccentColor() ? entry->GetAccentColor() : 0;

if (accentColor) Gui::Draw_Rect(0, 173, 400, 1, UIThemes->EntryOutline());
Gui::Draw_Rect(0, 174, 400, 66, accentColor ? accentColor : UIThemes->DownListPrev());
const C2D_Image tempImg = entry->GetIcon();
const uint8_t offsetW = (48 - tempImg.subtex->width) / 2; // Center W.
const uint8_t offsetH = (48 - tempImg.subtex->height) / 2; // Center H.
C2D_DrawImageAt(tempImg, 9 + offsetW, 174 + 9 + offsetH, 0.5);

Gui::DrawString(70, 174 + 15, 0.45f, UIThemes->TextColor(), entries[StoreUtils::store->GetDownloadIndex()], 310, 0, font);
Gui::DrawString(70, 174 + 15, 0.45f, accentColor ? WHITE : UIThemes->TextColor(), entries[StoreUtils::store->GetDownloadIndex()], 310, 0, font);

if (!sizes.empty()) {
if (sizes[StoreUtils::store->GetDownloadIndex()] != "") {
Gui::DrawString(70, 174 + 30, 0.45f, UIThemes->TextColor(), Lang::get("SIZE") + ": " + sizes[StoreUtils::store->GetDownloadIndex()], 310, 0, font);
Gui::DrawString(70, 174 + 30, 0.45f, accentColor ? WHITE : UIThemes->TextColor(), Lang::get("SIZE") + ": " + sizes[StoreUtils::store->GetDownloadIndex()], 310, 0, font);
}
}
}
Expand All @@ -133,9 +138,9 @@ void StoreUtils::DrawDownList(const std::vector<std::string> &entries, bool fetc
Animation::QueueEntryDone();

GFX::DrawBottom();
Gui::Draw_Rect(40, 0, 280, 25, UIThemes->EntryBar());
Gui::Draw_Rect(40, 0, 280, 25, accentColor ? accentColor : UIThemes->EntryBar());
Gui::Draw_Rect(40, 25, 280, 1, UIThemes->EntryOutline());
Gui::DrawStringCentered(17, 2, 0.6, UIThemes->TextColor(), Lang::get("AVAILABLE_DOWNLOADS"), 273, 0, font);
Gui::DrawStringCentered(17, 2, 0.6, accentColor ? WHITE : UIThemes->TextColor(), Lang::get("AVAILABLE_DOWNLOADS"), 273, 0, font);

if (StoreUtils::store && StoreUtils::store->GetValid() && !fetch && entry) {
if (entries.size() > 0) {
Expand Down
8 changes: 5 additions & 3 deletions source/menu/entryInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,13 @@ extern bool exiting, QueueRuns;
*/
void StoreUtils::DrawEntryInfo(const std::unique_ptr<StoreEntry> &entry) {
if (StoreUtils::store && entry) { // Ensure, store & entry is not a nullptr.
Gui::Draw_Rect(40, 0, 280, 36, UIThemes->EntryBar());
uint32_t accentColor = config->useAccentColor() ? entry->GetAccentColor() : 0;

Gui::Draw_Rect(40, 0, 280, 36, accentColor ? accentColor : UIThemes->EntryBar());
Gui::Draw_Rect(40, 36, 280, 1, UIThemes->EntryOutline());

Gui::DrawStringCentered(17, 0, 0.6, UIThemes->TextColor(), entry->GetTitle(), 273, 0, font);
Gui::DrawStringCentered(17, 20, 0.4, UIThemes->TextColor(), entry->GetAuthor(), 273, 0, font);
Gui::DrawStringCentered(17, 0, 0.6, accentColor ? WHITE : UIThemes->TextColor(), entry->GetTitle(), 273, 0, font);
Gui::DrawStringCentered(17, 20, 0.4, accentColor ? WHITE : UIThemes->TextColor(), entry->GetAuthor(), 273, 0, font);
Gui::DrawStringCentered(17, 50, 0.4, UIThemes->TextColor(), entry->GetDescription(), 248, 0, font, C2D_WordWrap);

Gui::DrawString(53, 115, 0.45, UIThemes->TextColor(), Lang::get("VERSION") + ": " + entry->GetVersion(), 248, 0, font);
Expand Down
7 changes: 6 additions & 1 deletion source/menu/grid.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,13 @@ void StoreUtils::DrawGrid() {
}

for (int i = 0, i2 = -5 + (StoreUtils::store->GetScreenIndx() * 5); i2 < 20 + (StoreUtils::store->GetScreenIndx() * 5) && i2 < (int)StoreUtils::entries.size(); i2++, i++) {
uint32_t accentColor = 0;
if (config->useAccentColor() && (int)StoreUtils::entries.size() > i + StoreUtils::store->GetScreenIndx()) {
accentColor = StoreUtils::entries[i + StoreUtils::store->GetScreenIndx()]->GetAccentColor();
}

/* Boxes. */
if (i == StoreUtils::store->GetBox()) GFX::DrawBox(GridBoxes[i + 5].x, GridBoxes[i + 5].y + StoreUtils::store->GetAnimOffset(), 50, 50, true);
if (i == StoreUtils::store->GetBox()) GFX::DrawBox(GridBoxes[i + 5].x, GridBoxes[i + 5].y + StoreUtils::store->GetAnimOffset(), 50, 50, true, accentColor);

/* Ensure, entries is larger than the index. */
if ((int)StoreUtils::entries.size() > i2) {
Expand Down
11 changes: 8 additions & 3 deletions source/menu/list.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,14 @@ void StoreUtils::DrawList() {

if (StoreUtils::entries.size() > 0) {
for (int i = 0; i < 5 && i < (int)StoreUtils::entries.size(); i++) {
uint32_t accentColor = 0;

if (i + StoreUtils::store->GetScreenIndx() == StoreUtils::store->GetEntry()) {
GFX::DrawBox(StoreBoxesList[i + 1].x, StoreBoxesList[i + 1].y + StoreUtils::store->GetAnimOffset(), StoreBoxesList[i + 1].w, StoreBoxesList[i + 1].h, false);
if (config->useAccentColor() && (int)StoreUtils::entries.size() > i + StoreUtils::store->GetScreenIndx()) {
accentColor = StoreUtils::entries[i + StoreUtils::store->GetScreenIndx()]->GetAccentColor();
}

GFX::DrawBox(StoreBoxesList[i + 1].x, StoreBoxesList[i + 1].y + StoreUtils::store->GetAnimOffset(), StoreBoxesList[i + 1].w, StoreBoxesList[i + 1].h, true, accentColor);
}

/* Ensure, entries is larger than the index. */
Expand All @@ -72,8 +77,8 @@ void StoreUtils::DrawList() {
}

if (StoreUtils::entries[i - 1 + StoreUtils::store->GetScreenIndx()]->GetUpdateAvl()) GFX::DrawSprite(sprites_update_app_idx, StoreBoxesList[i].x + 32, StoreBoxesList[i].y + 32 + StoreUtils::store->GetAnimOffset());
Gui::DrawStringCentered(29, StoreBoxesList[i].y + 5 + StoreUtils::store->GetAnimOffset(), 0.6f, UIThemes->TextColor(), StoreUtils::entries[i - 1 + StoreUtils::store->GetScreenIndx()]->GetTitle(), 300, 0, font);
Gui::DrawStringCentered(29, StoreBoxesList[i].y + 24 + StoreUtils::store->GetAnimOffset(), 0.6f, UIThemes->TextColor(), StoreUtils::entries[i - 1 + StoreUtils::store->GetScreenIndx()]->GetAuthor(), 300, 0, font);
Gui::DrawStringCentered(29, StoreBoxesList[i].y + 5 + StoreUtils::store->GetAnimOffset(), 0.6f, accentColor ? WHITE : UIThemes->TextColor(), StoreUtils::entries[i - 1 + StoreUtils::store->GetScreenIndx()]->GetTitle(), 300, 0, font);
Gui::DrawStringCentered(29, StoreBoxesList[i].y + 24 + StoreUtils::store->GetAnimOffset(), 0.6f, accentColor ? WHITE : UIThemes->TextColor(), StoreUtils::entries[i - 1 + StoreUtils::store->GetScreenIndx()]->GetAuthor(), 300, 0, font);
}
}
}
Expand Down
45 changes: 31 additions & 14 deletions source/menu/settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,12 @@ static const std::vector<Structs::ButtonPos> toggleAbles = {
{ 288, 180, 24, 24 }
};

static const std::vector<Structs::ButtonPos> toggleAblesGui = {
{ 288, 30, 24, 24 },
{ 288, 108, 24, 24 },
{ 288, 136, 24, 24 },
};

static const std::vector<Structs::ButtonPos> dirButtons = {
{ 41, 34, 280, 24 },
{ 41, 64, 280, 24 },
Expand Down Expand Up @@ -191,19 +197,23 @@ static void DrawGUISettings(int selection) {

Gui::DrawStringCentered(20, 2, 0.6, UIThemes->TextColor(), Lang::get("GUI_SETTINGS"), 248, 0, font);

Gui::Draw_Rect(40, 44, 280, 24, (selection == 0 ? UIThemes->MarkSelected() : UIThemes->MarkUnselected()));
Gui::DrawString(47, 48, 0.5f, UIThemes->TextColor(), Lang::get("UNISTORE_BG"), 210, 0, font);
GFX::DrawToggle(toggleAbles[0].x, toggleAbles[0].y, config->usebg());
Gui::DrawString(47, 75, 0.4f, UIThemes->TextColor(), Lang::get("UNISTORE_BG_DESC"), 265, 0, font, C2D_WordWrap);
Gui::Draw_Rect(40, 30, 280, 24, (selection == 0 ? UIThemes->MarkSelected() : UIThemes->MarkUnselected()));
Gui::DrawString(47, 34, 0.5f, UIThemes->TextColor(), Lang::get("UNISTORE_BG"), 210, 0, font);
GFX::DrawToggle(toggleAblesGui[0].x, toggleAblesGui[0].y, config->usebg());
Gui::DrawString(47, 61, 0.4f, UIThemes->TextColor(), Lang::get("UNISTORE_BG_DESC"), 265, 0, font, C2D_WordWrap);

Gui::Draw_Rect(40, 120, 280, 24, (selection == 1 ? UIThemes->MarkSelected() : UIThemes->MarkUnselected()));
Gui::DrawString(47, 124, 0.5f, UIThemes->TextColor(), Lang::get("CUSTOM_FONT"), 210, 0, font);
GFX::DrawToggle(toggleAbles[1].x, toggleAbles[1].y, config->customfont());
Gui::DrawString(47, 151, 0.4f, UIThemes->TextColor(), Lang::get("CUSTOM_FONT_DESC"), 265, 0, font, C2D_WordWrap);
Gui::Draw_Rect(40, 108, 280, 24, (selection == 1 ? UIThemes->MarkSelected() : UIThemes->MarkUnselected()));
Gui::DrawString(47, 112, 0.5f, UIThemes->TextColor(), Lang::get("USE_ACCENT_COLOR"), 210, 0, font);
GFX::DrawToggle(toggleAblesGui[1].x, toggleAblesGui[1].y, config->useAccentColor());

Gui::Draw_Rect(40, 136, 280, 24, (selection == 2 ? UIThemes->MarkSelected() : UIThemes->MarkUnselected()));
Gui::DrawString(47, 140, 0.5f, UIThemes->TextColor(), Lang::get("CUSTOM_FONT"), 210, 0, font);
GFX::DrawToggle(toggleAblesGui[2].x, toggleAblesGui[2].y, config->customfont());
Gui::DrawString(47, 167, 0.4f, UIThemes->TextColor(), Lang::get("CUSTOM_FONT_DESC"), 265, 0, font, C2D_WordWrap);

if (!Themes.empty()) {
Gui::Draw_Rect(40, 196, 280, 24, (selection == 2 ? UIThemes->MarkSelected() : UIThemes->MarkUnselected()));
Gui::DrawString(47, 200, 0.5f, UIThemes->TextColor(), Lang::get("ACTIVE_THEME") + ": " + config->theme(), 270, 0, font);
Gui::Draw_Rect(40, 212, 280, 24, (selection == 3 ? UIThemes->MarkSelected() : UIThemes->MarkUnselected()));
Gui::DrawString(47, 216, 0.5f, UIThemes->TextColor(), Lang::get("ACTIVE_THEME") + ": " + config->theme(), 270, 0, font);
}
}

Expand Down Expand Up @@ -505,7 +515,7 @@ static void GUISettingsLogic(int &page, int &selection) {
}

if (hRepeat & KEY_DOWN) {
if (selection < (Themes.empty() ? 1 : 2)) selection++;
if (selection < (Themes.empty() ? 2 : 3)) selection++;
}

if (hRepeat & KEY_UP) {
Expand All @@ -517,10 +527,13 @@ static void GUISettingsLogic(int &page, int &selection) {
page = 0;
selection = 3;

} else if (touching(touch, toggleAbles[0])) {
} else if (touching(touch, toggleAblesGui[0])) {
config->usebg(!config->usebg());

} else if (touching(touch, toggleAbles[1])) {
} else if (touching(touch, toggleAblesGui[1])) {
config->useAccentColor(!config->useAccentColor());

} else if (touching(touch, toggleAblesGui[2])) {
config->customfont(!config->customfont());

(config->customfont() ? Init::LoadFont() : Init::UnloadFont());
Expand All @@ -537,12 +550,16 @@ static void GUISettingsLogic(int &page, int &selection) {
break;

case 1:
config->useAccentColor(!config->useAccentColor());
break;

case 2:
config->customfont(!config->customfont());

(config->customfont() ? Init::LoadFont() : Init::UnloadFont());
break;

case 2:
case 3:
if (!Themes.empty()) Overlays::SelectTheme();
break;
}
Expand Down
18 changes: 18 additions & 0 deletions source/store/store.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include "download.hpp"
#include "gui.hpp"
#include "scriptUtils.hpp"
#include "stringutils.hpp"
#include "store.hpp"
#include <unistd.h>

Expand Down Expand Up @@ -634,4 +635,21 @@ std::string Store::GetReleaseNotes(int index) const {
}

return "";
}

/*
Get the accent color of an entry.

int index: The Entry Index.
*/
u32 Store::GetAccentColorEntry(int index) const {
if (!this->valid) return 0;
if (index > (int)this->storeJson["storeContent"].size() - 1) return 0; // Empty.

if (this->storeJson["storeContent"][index]["info"].contains("color") && this->storeJson["storeContent"][index]["info"]["color"].is_string()) {
const std::string color = this->storeJson["storeContent"][index]["info"]["color"];
return StringUtils::ParseColorHexString(color);
}

return 0;
}
2 changes: 2 additions & 0 deletions source/store/storeEntry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ StoreEntry::StoreEntry(const std::unique_ptr<Store> &store, const std::unique_pt
this->SheetIndex = 0;
this->EntryIndex = index;

this->AccentColor = store->GetAccentColorEntry(index);

this->FullCategory = store->GetCategoryIndex(index);
this->FullConsole = store->GetConsoleEntry(index);

Expand Down
2 changes: 2 additions & 0 deletions source/utils/config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ Config::Config() {
if (this->json.contains("UpdateCheck")) this->updatecheck(this->getBool("UpdateCheck"));
if (this->json.contains("UpdateNightly")) this->updatenightly(this->getBool("UpdateNightly"));
if (this->json.contains("UseBG")) this->usebg(this->getBool("UseBG"));
if (this->json.contains("UseAccentColor")) this->useAccentColor(this->getBool("UseAccentColor"));
if (this->json.contains("CustomFont")) this->customfont(this->getBool("CustomFont"));
if (this->json.contains("Shortcut_Path")) this->shortcut(this->getString("Shortcut_Path"));
if (this->json.contains("Display_Changelog")) this->changelog(this->getBool("Display_Changelog"));
Expand Down Expand Up @@ -176,6 +177,7 @@ void Config::save() {
this->setBool("UpdateCheck", this->updatecheck());
this->setBool("UpdateNightly", this->updatenightly());
this->setBool("UseBG", this->usebg());
this->setBool("UseAccentColor", this->useAccentColor());
this->setBool("CustomFont", this->customfont());
this->setString("Shortcut_Path", this->shortcut());
this->setBool("Display_Changelog", this->changelog());
Expand Down
20 changes: 20 additions & 0 deletions source/utils/stringutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

#include "common.hpp"
#include "stringutils.hpp"
#include <charconv>
#include <stdarg.h>

/*
Expand Down Expand Up @@ -117,4 +118,23 @@ std::string StringUtils::format(const char *fmt_str, ...) {

std::unique_ptr<char, decltype(free) *> formatted(fp, free);
return std::string(formatted.get());
}

/*
Parse a color hex string (`#RRGGBB`) and return a C2D color.
Return 0 if parsing failed.
*/
uint32_t StringUtils::ParseColorHexString(std::string_view str) {
if (str.size() != 7) return 0;
if (str[0] != '#') return 0;

uint8_t colorVal[3];
for (int i = 0; i < 3; i++) {
const char *colorValStart = str.data() + 1 + i * 2;
auto result = std::from_chars(colorValStart, colorValStart + 2, colorVal[i], 16);
if (result.ec != std::errc()) return 0;
if (result.ptr != colorValStart + 2) return 0;
}

return C2D_Color32(colorVal[0], colorVal[1], colorVal[2], 255);
}
Loading