Add various extra customization options for custom themes. Fixes #40

This commit is contained in:
Gericom
2026-03-29 14:48:12 +02:00
parent 53727e5fdd
commit cf9ce63db5
17 changed files with 494 additions and 56 deletions

View File

@@ -8,5 +8,119 @@
"g": 217,
"b": 255
},
"darkTheme": false
"darkTheme": false,
"topIcon": {
"position": {
"x": 24,
"y": 132
},
"blendColor": {
"r": 200,
"g": 200,
"b": 200
}
},
"topBannerTextLine0": {
"position": {
"x": 70,
"y": 126
},
"width": 176,
"textColor": {
"r": 30,
"g": 30,
"b": 30
},
"blendColor": {
"r": 200,
"g": 200,
"b": 200
}
},
"topBannerTextLine1": {
"position": {
"x": 70,
"y": 141
},
"width": 176,
"textColor": {
"r": 30,
"g": 30,
"b": 30
},
"blendColor": {
"r": 200,
"g": 200,
"b": 200
}
},
"topBannerTextLine2": {
"position": {
"x": 70,
"y": 155
},
"width": 176,
"textColor": {
"r": 30,
"g": 30,
"b": 30
},
"blendColor": {
"r": 200,
"g": 200,
"b": 200
}
},
"topFileNameText": {
"position": {
"x": 18,
"y": 170
},
"width": 220,
"textColor": {
"r": 30,
"g": 30,
"b": 30
},
"blendColor": {
"r": 200,
"g": 200,
"b": 200
}
},
"gridIcon": {
"blendColor": {
"r": 200,
"g": 200,
"b": 200
}
},
"bannerListIcon": {
"blendColor": {
"r": 200,
"g": 200,
"b": 200
}
},
"bannerListTextLine0": {
"textColor": {
"r": 30,
"g": 30,
"b": 30
}
},
"bannerListTextLine1": {
"textColor": {
"r": 30,
"g": 30,
"b": 30
}
},
"bannerListTextLine2": {
"textColor": {
"r": 30,
"g": 30,
"b": 30
}
}
}

View File

@@ -75,3 +75,5 @@ public:
return Rgb(r + other.r, g + other.g, b + other.b);
}
};
using Rgb8 = Rgb<8, 8, 8>;

View File

@@ -12,6 +12,7 @@
#include "core/math/RgbMixer.h"
#include "themes/material/MaterialColorScheme.h"
#include "themes/IFontRepository.h"
#include "themes/custom/CustomThemeInfo.h"
#include "bannerListItemBg0.h"
#include "bannerListItemBg1.h"
#include "bannerListItemBg2.h"
@@ -30,9 +31,10 @@
#define LINE_HEIGHT 16
#define MAX_LINE_STRING_LENGTH 50
CustomBannerListItemView::CustomBannerListItemView(const MaterialColorScheme* materialColorScheme,
const IFontRepository* fontRepository, u32 texVramOffset, u32 plttVramOffset,
u32 selectedTexVramOffset, u32 selectedPlttVramOffset, VBlankTextureLoader* vblankTextureLoader)
CustomBannerListItemView::CustomBannerListItemView(const CustomThemeInfo* customThemeInfo,
const MaterialColorScheme* materialColorScheme, const IFontRepository* fontRepository,
u32 texVramOffset, u32 plttVramOffset, u32 selectedTexVramOffset, u32 selectedPlttVramOffset,
VBlankTextureLoader* vblankTextureLoader)
: BannerListItemView(
std::make_unique<Label3DView>(LINE_WIDTH, LINE_HEIGHT, MAX_LINE_STRING_LENGTH,
fontRepository->GetFont(FontType::Medium10), vblankTextureLoader),
@@ -40,6 +42,7 @@ CustomBannerListItemView::CustomBannerListItemView(const MaterialColorScheme* ma
fontRepository->GetFont(FontType::Regular10), vblankTextureLoader),
std::make_unique<Label3DView>(LINE_WIDTH, LINE_HEIGHT, MAX_LINE_STRING_LENGTH,
fontRepository->GetFont(FontType::Regular10), vblankTextureLoader))
, _customThemeInfo(customThemeInfo)
, _materialColorScheme(materialColorScheme)
, _texVramOffset(texVramOffset)
, _plttVramOffset(plttVramOffset)
@@ -53,8 +56,6 @@ void CustomBannerListItemView::Draw(GraphicsContext& graphicsContext)
return;
}
auto backgroundColor = Rgb<8, 8, 8>(200, 200, 200);
Gx::MtxIdentity();
Gx::PolygonAttr(GX_LIGHTMASK_NONE, GX_POLYGON_MODE_MODULATE, GX_DISPLAY_MODE_FRONT,
false, false, false, GX_DEPTH_FUNC_LESS, false, 31, 0);
@@ -82,9 +83,9 @@ void CustomBannerListItemView::Draw(GraphicsContext& graphicsContext)
graphicsContext.SetPolygonId(1);
_firstLine->SetForegroundColor(Rgb<8, 8, 8>(30, 30, 30));
_secondLine->SetForegroundColor(Rgb<8, 8, 8>(30, 30, 30));
_thirdLine->SetForegroundColor(Rgb<8, 8, 8>(30, 30, 30));
_firstLine->SetForegroundColor(_customThemeInfo->bannerListTextLine0Info.GetTextColor());
_secondLine->SetForegroundColor(_customThemeInfo->bannerListTextLine1Info.GetTextColor());
_thirdLine->SetForegroundColor(_customThemeInfo->bannerListTextLine2Info.GetTextColor());
if (_lines == 1)
{
@@ -118,6 +119,6 @@ void CustomBannerListItemView::Draw(GraphicsContext& graphicsContext)
if (_icon)
{
_icon->SetPosition(6 + _position.x, 6 + _position.y);
_icon->Draw(graphicsContext, backgroundColor);
_icon->Draw(graphicsContext, _customThemeInfo->bannerListIconInfo.GetBlendColor());
}
}

View File

@@ -4,11 +4,12 @@
class MaterialColorScheme;
class IFontRepository;
class CustomThemeInfo;
class CustomBannerListItemView : public BannerListItemView
{
public:
CustomBannerListItemView(const MaterialColorScheme* materialColorScheme,
CustomBannerListItemView(const CustomThemeInfo* customThemeInfo, const MaterialColorScheme* materialColorScheme,
const IFontRepository* fontRepository, u32 texVramOffset, u32 plttVramOffset,
u32 selectedTexVramOffset, u32 selectedPlttVramOffset, VBlankTextureLoader* vblankTextureLoader);
@@ -20,6 +21,7 @@ public:
}
private:
const CustomThemeInfo* _customThemeInfo;
const MaterialColorScheme* _materialColorScheme;
u32 _texVramOffset = 0;
u32 _plttVramOffset = 0;

View File

@@ -2,14 +2,15 @@
#include "gui/GraphicsContext.h"
#include "gui/IVramManager.h"
#include "themes/IFontRepository.h"
#include "themes/custom/CustomThemeInfo.h"
#include "CustomFileInfoView.h"
CustomFileInfoView::CustomFileInfoView(const IFontRepository* fontRepository)
: _firstLine(176, 16, 50, fontRepository->GetFont(FontType::Medium11))
, _secondLine(176, 16, 50, fontRepository->GetFont(FontType::Regular10))
, _thirdLine(176, 16, 50, fontRepository->GetFont(FontType::Regular10))
, _filenameLabelView(220, 16, 200, fontRepository->GetFont(FontType::Medium7_5))
, _backgroundColor(200, 200, 200), _textColor(30, 30, 30)
CustomFileInfoView::CustomFileInfoView(const CustomThemeInfo* customThemeInfo, const IFontRepository* fontRepository)
: _firstLine(customThemeInfo->topBannerTextLine0Info.GetWidth(), 16, 50, fontRepository->GetFont(FontType::Medium11))
, _secondLine(customThemeInfo->topBannerTextLine1Info.GetWidth(), 16, 50, fontRepository->GetFont(FontType::Regular10))
, _thirdLine(customThemeInfo->topBannerTextLine2Info.GetWidth(), 16, 50, fontRepository->GetFont(FontType::Regular10))
, _filenameLabelView(customThemeInfo->topFileNameTextInfo.GetWidth(), 16, 256, fontRepository->GetFont(FontType::Medium7_5))
, _customThemeInfo(customThemeInfo)
{
AddChildTail(&_firstLine);
AddChildTail(&_secondLine);
@@ -21,32 +22,32 @@ CustomFileInfoView::CustomFileInfoView(const IFontRepository* fontRepository)
void CustomFileInfoView::Update()
{
BannerView::Update();
_firstLine.SetPosition(_position.x + 70, _position.y + 130 - 4);
_secondLine.SetPosition(_position.x + 70, _position.y + 145 - 4);
_thirdLine.SetPosition(_position.x + 70, _position.y + 159 - 4);
_filenameLabelView.SetPosition(_position.x + 18, _position.y + 170);
_firstLine.SetPosition(_customThemeInfo->topBannerTextLine0Info.GetPosition());
_secondLine.SetPosition(_customThemeInfo->topBannerTextLine1Info.GetPosition());
_thirdLine.SetPosition(_customThemeInfo->topBannerTextLine2Info.GetPosition());
_filenameLabelView.SetPosition(_customThemeInfo->topFileNameTextInfo.GetPosition());
if (_icon)
{
_icon->SetPosition(_position.x + 24, _position.y + 136 - 4);
_icon->SetPosition(_customThemeInfo->topIconInfo.GetPosition());
_icon->Update();
}
}
void CustomFileInfoView::Draw(GraphicsContext& graphicsContext)
{
_firstLine.SetBackgroundColor(_backgroundColor);
_firstLine.SetForegroundColor(_textColor);
_secondLine.SetBackgroundColor(_backgroundColor);
_secondLine.SetForegroundColor(_textColor);
_thirdLine.SetBackgroundColor(_backgroundColor);
_thirdLine.SetForegroundColor(_textColor);
_filenameLabelView.SetBackgroundColor(_backgroundColor);
_filenameLabelView.SetForegroundColor(_textColor);
_firstLine.SetBackgroundColor(_customThemeInfo->topBannerTextLine0Info.GetBlendColor());
_firstLine.SetForegroundColor(_customThemeInfo->topBannerTextLine0Info.GetTextColor());
_secondLine.SetBackgroundColor(_customThemeInfo->topBannerTextLine1Info.GetBlendColor());
_secondLine.SetForegroundColor(_customThemeInfo->topBannerTextLine1Info.GetTextColor());
_thirdLine.SetBackgroundColor(_customThemeInfo->topBannerTextLine2Info.GetBlendColor());
_thirdLine.SetForegroundColor(_customThemeInfo->topBannerTextLine2Info.GetTextColor());
_filenameLabelView.SetBackgroundColor(_customThemeInfo->topFileNameTextInfo.GetBlendColor());
_filenameLabelView.SetForegroundColor(_customThemeInfo->topFileNameTextInfo.GetTextColor());
BannerView::Draw(graphicsContext);
if (_icon)
{
_icon->Draw(graphicsContext, _backgroundColor);
_icon->Draw(graphicsContext, _customThemeInfo->topIconInfo.GetBlendColor());
}
}

View File

@@ -5,11 +5,12 @@
class FileIcon;
class IFontRepository;
class CustomThemeInfo;
class CustomFileInfoView : public BannerView
{
public:
explicit CustomFileInfoView(const IFontRepository* fontRepository);
CustomFileInfoView(const CustomThemeInfo* customThemeInfo, const IFontRepository* fontRepository);
void Update() override;
void Draw(GraphicsContext& graphicsContext) override;
@@ -67,6 +68,5 @@ private:
Label2DView _secondLine;
Label2DView _thirdLine;
Label2DView _filenameLabelView;
Rgb<8, 8, 8> _backgroundColor;
Rgb<8, 8, 8> _textColor;
const CustomThemeInfo* _customThemeInfo;
};

View File

@@ -5,6 +5,7 @@
#include "gui/OamBuilder.h"
#include "gui/IVramManager.h"
#include "gui/GraphicsContext.h"
#include "themes/custom/CustomThemeInfo.h"
#include "CustomIconGridItemView.h"
#define X_OFFSET (-2)
@@ -48,6 +49,6 @@ void CustomIconGridItemView::Draw(GraphicsContext& graphicsContext)
if (_icon)
{
_icon->SetPosition(6 + _position.x, 6 + _position.y);
_icon->Draw(graphicsContext, Rgb<8, 8, 8>(200, 200, 200));
_icon->Draw(graphicsContext, _customThemeInfo->gridIconInfo.GetBlendColor());
}
}

View File

@@ -1,12 +1,14 @@
#pragma once
#include "../../views/IconGridItemView.h"
class CustomThemeInfo;
class CustomIconGridItemView : public IconGridItemView
{
public:
CustomIconGridItemView(u32 texVramOffset, u32 plttVramOffset,
CustomIconGridItemView(const CustomThemeInfo* customThemeInfo, u32 texVramOffset, u32 plttVramOffset,
u32 selectedTexVramOffset, u32 selectedPlttVramOffset)
: _texVramOffset(texVramOffset), _plttVramOffset(plttVramOffset)
: _customThemeInfo(customThemeInfo), _texVramOffset(texVramOffset), _plttVramOffset(plttVramOffset)
, _selectedTexVramOffset(selectedTexVramOffset), _selectedPlttVramOffset(selectedPlttVramOffset) { }
void Draw(GraphicsContext& graphicsContext) override;
@@ -17,8 +19,9 @@ public:
}
private:
u32 _texVramOffset = 0;
u32 _plttVramOffset = 0;
u32 _selectedTexVramOffset = 0;
u32 _selectedPlttVramOffset = 0;
const CustomThemeInfo* _customThemeInfo;
u32 _texVramOffset;
u32 _plttVramOffset;
u32 _selectedTexVramOffset;
u32 _selectedPlttVramOffset;
};

View File

@@ -12,23 +12,24 @@ class MaterialColorScheme;
class ITheme;
class VramContext;
class IFontRepository;
class CustomThemeInfo;
class CustomRomBrowserViewFactory : public IRomBrowserViewFactory
{
public:
CustomRomBrowserViewFactory(const MaterialColorScheme* materialColorScheme,
CustomRomBrowserViewFactory(const CustomThemeInfo* customThemeInfo, const MaterialColorScheme* materialColorScheme,
const IFontRepository* fontRepository)
: _materialColorScheme(materialColorScheme), _fontRepository(fontRepository) { }
: _customThemeInfo(customThemeInfo), _materialColorScheme(materialColorScheme), _fontRepository(fontRepository) { }
IconGridItemView* CreateIconGridItemView() const override
{
return new CustomIconGridItemView(_gridCellTexVramOffset, _gridCellPlttVramOffset,
return new CustomIconGridItemView(_customThemeInfo, _gridCellTexVramOffset, _gridCellPlttVramOffset,
_gridCellSelectedTexVramOffset, _gridCellSelectedPlttVramOffset);
}
BannerListItemView* CreateBannerListItemView(VBlankTextureLoader* vblankTextureLoader) const override
{
return new CustomBannerListItemView(_materialColorScheme, _fontRepository,
return new CustomBannerListItemView(_customThemeInfo, _materialColorScheme, _fontRepository,
_bannerListCellTexVramOffset, _bannerListCellPlttVramOffset,
_bannerListCellSelectedTexVramOffset, _bannerListCellSelectedPlttVramOffset, vblankTextureLoader);
}
@@ -47,7 +48,7 @@ public:
std::unique_ptr<BannerView> CreateFileInfoView() const override
{
return std::make_unique<CustomFileInfoView>(_fontRepository);
return std::make_unique<CustomFileInfoView>(_customThemeInfo, _fontRepository);
}
std::unique_ptr<RecyclerViewBase> CreateCoverFlowRecyclerView() const override
@@ -77,6 +78,7 @@ private:
u32 _bannerListCellSelectedPlttVramOffset;
u32 _scrimTexVramOffset;
u32 _scrimPlttVramOffset;
const CustomThemeInfo* _customThemeInfo;
const MaterialColorScheme* _materialColorScheme;
const IFontRepository* _fontRepository;
};

View File

@@ -0,0 +1,15 @@
#pragma once
#include "core/math/Point.h"
#include "core/math/Rgb.h"
class CustomBannerListTextElementInfo
{
public:
CustomBannerListTextElementInfo(const Rgb8& textColor)
: _textColor(textColor) { }
const Rgb8& GetTextColor() const { return _textColor; }
private:
Rgb8 _textColor;
};

View File

@@ -0,0 +1,15 @@
#pragma once
#include "core/math/Point.h"
#include "core/math/Rgb.h"
class CustomBottomIconInfo
{
public:
CustomBottomIconInfo(const Rgb8& blendColor)
: _blendColor(blendColor) { }
const Rgb8& GetBlendColor() const { return _blendColor; }
private:
Rgb8 _blendColor;
};

View File

@@ -0,0 +1,21 @@
#pragma once
#include "core/math/Point.h"
#include "core/math/Rgb.h"
class CustomTopTextElementInfo
{
public:
CustomTopTextElementInfo(const Point& position, u32 width, const Rgb8& textColor, const Rgb8& blendColor)
: _position(position), _width(width), _textColor(textColor), _blendColor(blendColor) { }
const Point& GetPosition() const { return _position; }
const u32 GetWidth() const { return _width; }
const Rgb8& GetTextColor() const { return _textColor; }
const Rgb8& GetBlendColor() const { return _blendColor; }
private:
Point _position;
u32 _width;
Rgb8 _textColor;
Rgb8 _blendColor;
};

View File

@@ -11,13 +11,164 @@
#include "romBrowser/views/IconButton3DView.h"
#include "CustomTheme.h"
#define JSON_RESERVED_SIZE 2048
#define JSON_RESERVED_SIZE 4096
#define KEY_COLOR_R "r"
#define KEY_COLOR_G "g"
#define KEY_COLOR_B "b"
#define KEY_POINT_X "x"
#define KEY_POINT_Y "y"
#define KEY_TOP_ICON "topIcon"
#define KEY_TOP_BANNER_TEXT_LINE_0 "topBannerTextLine0"
#define KEY_TOP_BANNER_TEXT_LINE_1 "topBannerTextLine1"
#define KEY_TOP_BANNER_TEXT_LINE_2 "topBannerTextLine2"
#define KEY_TOP_FILE_NAME_TEXT "topFileNameText"
#define KEY_GRID_ICON "gridIcon"
#define KEY_BANNER_LIST_ICON "bannerListIcon"
#define KEY_BANNER_LIST_TEXT_LINE_0 "bannerListTextLine0"
#define KEY_BANNER_LIST_TEXT_LINE_1 "bannerListTextLine1"
#define KEY_BANNER_LIST_TEXT_LINE_2 "bannerListTextLine2"
#define KEY_ELEMENT_POSITION "position"
#define KEY_ELEMENT_WIDTH "width"
#define KEY_ELEMENT_TEXT_COLOR "textColor"
#define KEY_ELEMENT_BLEND_COLOR "blendColor"
static const CustomThemeInfo sDefaultCustomThemeInfo
{
.topIconInfo = CustomTopIconInfo(Point(24, 132), Rgb8(200, 200, 200)),
.topBannerTextLine0Info = CustomTopTextElementInfo(Point(70, 126), 176, Rgb8(30, 30, 30), Rgb8(200, 200, 200)),
.topBannerTextLine1Info = CustomTopTextElementInfo(Point(70, 141), 176, Rgb8(30, 30, 30), Rgb8(200, 200, 200)),
.topBannerTextLine2Info = CustomTopTextElementInfo(Point(70, 155), 176, Rgb8(30, 30, 30), Rgb8(200, 200, 200)),
.topFileNameTextInfo = CustomTopTextElementInfo(Point(18, 170), 220, Rgb8(30, 30, 30), Rgb8(200, 200, 200)),
.gridIconInfo = CustomBottomIconInfo(Rgb8(200, 200, 200)),
.bannerListIconInfo = CustomBottomIconInfo(Rgb8(200, 200, 200)),
.bannerListTextLine0Info = CustomBannerListTextElementInfo(Rgb8(30, 30, 30)),
.bannerListTextLine1Info = CustomBannerListTextElementInfo(Rgb8(30, 30, 30)),
.bannerListTextLine2Info = CustomBannerListTextElementInfo(Rgb8(30, 30, 30))
};
static CustomTopBackgroundType parseTopBackgroundType(const char* topBackgroundTypeString)
{
return CustomTopBackgroundType::Bitmap;
}
static Rgb8 parseColor(const JsonObjectConst& json, const Rgb8& defaultColor)
{
if (json.isNull())
{
return defaultColor;
}
return Rgb8(
json[KEY_COLOR_R] | 0,
json[KEY_COLOR_G] | 0,
json[KEY_COLOR_B] | 0
);
}
static Point parsePoint(const JsonObjectConst& json, const Point& defaultPoint)
{
if (json.isNull())
{
return defaultPoint;
}
return Point(
json[KEY_POINT_X] | 0,
json[KEY_POINT_Y] | 0
);
}
static CustomBannerListTextElementInfo parseCustomBannerListTextElementInfo(
const JsonObjectConst& json, const CustomBannerListTextElementInfo& defaultInfo)
{
if (json.isNull())
{
return defaultInfo;
}
return CustomBannerListTextElementInfo(
parseColor(json[KEY_ELEMENT_TEXT_COLOR], defaultInfo.GetTextColor())
);
}
static CustomBottomIconInfo parseCustomBottomIconInfo(const JsonObjectConst& json, const CustomBottomIconInfo& defaultInfo)
{
if (json.isNull())
{
return defaultInfo;
}
return CustomBottomIconInfo(
parseColor(json[KEY_ELEMENT_BLEND_COLOR], defaultInfo.GetBlendColor())
);
}
static CustomTopIconInfo parseCustomTopIconInfo(const JsonObjectConst& json, const CustomTopIconInfo& defaultInfo)
{
if (json.isNull())
{
return defaultInfo;
}
return CustomTopIconInfo(
parsePoint(json[KEY_ELEMENT_POSITION], defaultInfo.GetPosition()),
parseColor(json[KEY_ELEMENT_BLEND_COLOR], defaultInfo.GetBlendColor())
);
}
static CustomTopTextElementInfo parseCustomTextElementInfo(
const JsonObjectConst& json, const CustomTopTextElementInfo& defaultInfo)
{
if (json.isNull())
{
return defaultInfo;
}
return CustomTopTextElementInfo(
parsePoint(json[KEY_ELEMENT_POSITION], defaultInfo.GetPosition()),
json[KEY_ELEMENT_WIDTH] | defaultInfo.GetWidth(),
parseColor(json[KEY_ELEMENT_TEXT_COLOR], defaultInfo.GetTextColor()),
parseColor(json[KEY_ELEMENT_BLEND_COLOR], defaultInfo.GetBlendColor())
);
}
static CustomThemeInfo parseCustomThemeInfo(const JsonDocument& json)
{
return CustomThemeInfo
{
.topIconInfo = parseCustomTopIconInfo(json[KEY_TOP_ICON], sDefaultCustomThemeInfo.topIconInfo),
.topBannerTextLine0Info = parseCustomTextElementInfo(
json[KEY_TOP_BANNER_TEXT_LINE_0], sDefaultCustomThemeInfo.topBannerTextLine0Info),
.topBannerTextLine1Info = parseCustomTextElementInfo(
json[KEY_TOP_BANNER_TEXT_LINE_1], sDefaultCustomThemeInfo.topBannerTextLine1Info),
.topBannerTextLine2Info = parseCustomTextElementInfo(
json[KEY_TOP_BANNER_TEXT_LINE_2], sDefaultCustomThemeInfo.topBannerTextLine2Info),
.topFileNameTextInfo = parseCustomTextElementInfo(
json[KEY_TOP_FILE_NAME_TEXT], sDefaultCustomThemeInfo.topFileNameTextInfo),
.gridIconInfo = parseCustomBottomIconInfo(json[KEY_GRID_ICON], sDefaultCustomThemeInfo.gridIconInfo),
.bannerListIconInfo = parseCustomBottomIconInfo(json[KEY_BANNER_LIST_ICON], sDefaultCustomThemeInfo.bannerListIconInfo),
.bannerListTextLine0Info = parseCustomBannerListTextElementInfo(
json[KEY_BANNER_LIST_TEXT_LINE_0], sDefaultCustomThemeInfo.bannerListTextLine0Info),
.bannerListTextLine1Info = parseCustomBannerListTextElementInfo(
json[KEY_BANNER_LIST_TEXT_LINE_1], sDefaultCustomThemeInfo.bannerListTextLine1Info),
.bannerListTextLine2Info = parseCustomBannerListTextElementInfo(
json[KEY_BANNER_LIST_TEXT_LINE_2], sDefaultCustomThemeInfo.bannerListTextLine2Info)
};
}
CustomTheme::CustomTheme(const TCHAR* folderName, const Rgb<8, 8, 8>& primaryColor, bool darkMode)
: Theme(folderName, primaryColor, darkMode)
, _customThemeInfo(sDefaultCustomThemeInfo)
, _romBrowserViewFactory(&_customThemeInfo, &_materialColorScheme, &_fontRepository) { }
void CustomTheme::LoadRomBrowserResources(const VramContext& mainVramContext, const VramContext& subVramContext)
{
const auto file = std::make_unique<File>();
@@ -39,6 +190,7 @@ void CustomTheme::LoadRomBrowserResources(const VramContext& mainVramContext, co
return;
_topBackgroundType = parseTopBackgroundType(json["topBackgroundType"].as<const char*>());
_customThemeInfo = parseCustomThemeInfo(json);
mem_setVramDMapping(MEM_VRAM_D_LCDC);
mem_setVramEMapping(MEM_VRAM_E_LCDC);

View File

@@ -7,19 +7,13 @@
#include "romBrowser/Theme/custom/CustomRomBrowserViewFactory.h"
#include "CustomTopBackgroundType.h"
#include "../DefaultFontRepository.h"
#include "CustomThemeInfo.h"
#include "../Theme.h"
class CustomTheme : public Theme
{
String<TCHAR, 64> _folderName;
CustomRomBrowserViewFactory _romBrowserViewFactory;
CustomTopBackgroundType _topBackgroundType;
DefaultFontRepository _fontRepository;
public:
CustomTheme(const TCHAR* folderName, const Rgb<8, 8, 8>& primaryColor, bool darkMode)
: Theme(folderName, primaryColor, darkMode)
, _romBrowserViewFactory(&_materialColorScheme, &_fontRepository) { }
CustomTheme(const TCHAR* folderName, const Rgb<8, 8, 8>& primaryColor, bool darkMode);
const IFontRepository* GetFontRepository() const override
{
@@ -47,4 +41,11 @@ public:
}
void LoadRomBrowserResources(const VramContext& mainVramContext, const VramContext& subVramContext) override;
private:
String<TCHAR, 64> _folderName;
CustomThemeInfo _customThemeInfo;
CustomRomBrowserViewFactory _romBrowserViewFactory;
CustomTopBackgroundType _topBackgroundType;
DefaultFontRepository _fontRepository;
};

View File

@@ -0,0 +1,21 @@
#pragma once
#include "CustomBannerListTextElementInfo.h"
#include "CustomBottomIconInfo.h"
#include "CustomTopIconInfo.h"
#include "CustomTextElementInfo.h"
struct CustomThemeInfo
{
CustomTopIconInfo topIconInfo;
CustomTopTextElementInfo topBannerTextLine0Info;
CustomTopTextElementInfo topBannerTextLine1Info;
CustomTopTextElementInfo topBannerTextLine2Info;
CustomTopTextElementInfo topFileNameTextInfo;
CustomBottomIconInfo gridIconInfo;
CustomBottomIconInfo bannerListIconInfo;
CustomBannerListTextElementInfo bannerListTextLine0Info;
CustomBannerListTextElementInfo bannerListTextLine1Info;
CustomBannerListTextElementInfo bannerListTextLine2Info;
};

View File

@@ -0,0 +1,17 @@
#pragma once
#include "core/math/Point.h"
#include "core/math/Rgb.h"
class CustomTopIconInfo
{
public:
CustomTopIconInfo(const Point& position, const Rgb8& blendColor)
: _position(position), _blendColor(blendColor) { }
const Point& GetPosition() const { return _position; }
const Rgb8& GetBlendColor() const { return _blendColor; }
private:
Point _position;
Rgb8 _blendColor;
};

View File

@@ -53,5 +53,75 @@ These files can be created, for example, using [NitroPaint](https://github.com/G
The top screen background should include a box in which the banner text and icon of the selected item will be shown.
### Additional JSON properties
Custom themes support additional properties in the `theme.json` file to allow for more customization.
- **topIcon** - Properties of the icon displayed on the top screen.
- **topBannerTextLine0** - Properties of the first banner text line displayed on the top screen.
- **topBannerTextLine1** - Properties of the second banner text line displayed on the top screen.
- **topBannerTextLine2** - Properties of the third banner text line displayed on the top screen.
- **topFileNameText** - Properties of the file name text displayed on the top screen.
- **gridIcon** - Properties of the icons displayed on the bottom screen in grid display modes.
- **bannerListIcon** - Properties of the icons displayed on the bottom screen in banner list display mode.
- **bannerListTextLine0** - Properties of the first banner text line displayed on the bottom screen in banner list display mode.
- **bannerListTextLine1** - Properties of the second banner text line displayed on the bottom screen in banner list display mode.
- **bannerListTextLine2** - Properties of the third banner text line displayed on the bottom screen in banner list display mode.
Blend colors are used to fake translucency. They should be set to an approximation of the background color.
```json
{
"type": "custom",
"name": "Raspberry",
"description": "Theme based on raspberries.",
"author": "Gericom",
"primaryColor": { "r": 138, "g": 217, "b": 255 },
"darkTheme": false,
"topIcon": {
"position": { "x": 24, "y": 132 },
"blendColor": { "r": 200, "g": 200, "b": 200 }
},
"topBannerTextLine0": {
"position": { "x": 70, "y": 126 },
"width": 176,
"textColor": { "r": 30, "g": 30, "b": 30 },
"blendColor": { "r": 200, "g": 200, "b": 200 }
},
"topBannerTextLine1": {
"position": { "x": 70, "y": 141 },
"width": 176,
"textColor": { "r": 30, "g": 30, "b": 30 },
"blendColor": { "r": 200, "g": 200, "b": 200 }
},
"topBannerTextLine2": {
"position": { "x": 70, "y": 155 },
"width": 176,
"textColor": { "r": 30, "g": 30, "b": 30 },
"blendColor": { "r": 200, "g": 200, "b": 200 }
},
"topFileNameText": {
"position": { "x": 18, "y": 170 },
"width": 220,
"textColor": { "r": 30, "g": 30, "b": 30 },
"blendColor": { "r": 200, "g": 200, "b": 200 }
},
"gridIcon": {
"blendColor": { "r": 200, "g": 200, "b": 200 }
},
"bannerListIcon": {
"blendColor": { "r": 200, "g": 200, "b": 200 }
},
"bannerListTextLine0": {
"textColor": { "r": 30, "g": 30, "b": 30 }
},
"bannerListTextLine1": {
"textColor": { "r": 30, "g": 30, "b": 30 }
},
"bannerListTextLine2": {
"textColor": { "r": 30, "g": 30, "b": 30 }
}
}
```
## Background music
All themes support background music by placing DSP-ADPCM encoded `.bcstm` files in a `bgm` folder inside the theme folder. Looping is supported. When multiple `.bcstm` files are provided, the background music will be selected at random each time Pico Launcher is started.