You've already forked pico-launcher
mirror of
https://github.com/LNH-team/pico-launcher.git
synced 2026-01-09 16:28:48 -08:00
105 lines
2.6 KiB
C++
105 lines
2.6 KiB
C++
#include "common.h"
|
|
#include "common.h"
|
|
#include <memory>
|
|
#include "fat/File.h"
|
|
#include "json/ArduinoJson.h"
|
|
#include "core/mini-printf.h"
|
|
#include "core/math/Rgb.h"
|
|
#include "ThemeInfoFactory.h"
|
|
|
|
#pragma GCC optimize("Os")
|
|
|
|
#define JSON_RESERVED_SIZE 2048
|
|
|
|
#define KEY_TYPE "type"
|
|
#define KEY_NAME "name"
|
|
#define KEY_DESCRIPTION "description"
|
|
#define KEY_AUTHOR "author"
|
|
#define KEY_PRIMARY_COLOR "primaryColor"
|
|
#define KEY_COLOR_R "r"
|
|
#define KEY_COLOR_G "g"
|
|
#define KEY_COLOR_B "b"
|
|
#define KEY_DARK_THEME "darkTheme"
|
|
|
|
static bool tryParseThemeType(const char* themeTypeString, ThemeType& themeType)
|
|
{
|
|
if (!themeTypeString)
|
|
return false;
|
|
|
|
if (!strcasecmp(themeTypeString, "Material"))
|
|
themeType = ThemeType::Material;
|
|
else if (!strcasecmp(themeTypeString, "Custom"))
|
|
themeType = ThemeType::Custom;
|
|
else
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
static Rgb<8, 8, 8> parseColor(const JsonObjectConst& json, const Rgb<8, 8, 8>& defaultColor)
|
|
{
|
|
if (json.isNull())
|
|
{
|
|
return defaultColor;
|
|
}
|
|
|
|
return Rgb<8, 8, 8>(
|
|
json[KEY_COLOR_R] | 0,
|
|
json[KEY_COLOR_G] | 0,
|
|
json[KEY_COLOR_B] | 0
|
|
);
|
|
}
|
|
|
|
static std::unique_ptr<ThemeInfo> fromJson(const TCHAR* folderName, const JsonDocument& json)
|
|
{
|
|
ThemeType themeType;
|
|
if (!tryParseThemeType(json[KEY_TYPE].as<const char*>(), themeType))
|
|
{
|
|
themeType = ThemeType::Custom;
|
|
}
|
|
return std::make_unique<ThemeInfo>(
|
|
folderName,
|
|
themeType,
|
|
json[KEY_NAME] | "",
|
|
json[KEY_DESCRIPTION] | "",
|
|
json[KEY_AUTHOR] | "",
|
|
parseColor(json[KEY_PRIMARY_COLOR], Rgb<8, 8, 8>(0xFF, 0xFF, 0xFF)),
|
|
json[KEY_DARK_THEME] | false
|
|
);
|
|
}
|
|
|
|
std::unique_ptr<ThemeInfo> ThemeInfoFactory::CreateFromThemeFolder(const TCHAR* folderName) const
|
|
{
|
|
TCHAR pathBuffer[128];
|
|
mini_snprintf(pathBuffer, sizeof(pathBuffer), "/_pico/themes/%s/theme.json", folderName);
|
|
|
|
const auto file = std::make_unique<File>();
|
|
if (file->Open(pathBuffer, FA_READ | FA_OPEN_EXISTING) != FR_OK)
|
|
{
|
|
return nullptr;
|
|
}
|
|
|
|
u32 fileSize = file->GetSize();
|
|
if (fileSize == 0)
|
|
{
|
|
return nullptr;
|
|
}
|
|
|
|
std::unique_ptr<u8[]> fileData(new(cache_align) u8[fileSize]);
|
|
u8* fileDataPtr = fileData.get();
|
|
|
|
u32 bytesRead = 0;
|
|
if (file->Read(fileDataPtr, fileSize, bytesRead) != FR_OK)
|
|
{
|
|
return nullptr;
|
|
}
|
|
|
|
DynamicJsonDocument json(JSON_RESERVED_SIZE);
|
|
if (deserializeJson(json, fileDataPtr, fileSize) != DeserializationError::Ok)
|
|
{
|
|
return nullptr;
|
|
}
|
|
|
|
return fromJson(folderName, json);
|
|
}
|