Files
pico-launcher/arm9/source/romBrowser/Theme/Material/MaterialBannerListItemView.cpp
2025-11-25 17:41:31 +01:00

147 lines
6.0 KiB
C++

#include "common.h"
#include <libtwl/gfx/gfx.h>
#include "gui/PaletteManager.h"
#include "gui/OamManager.h"
#include "gui/OamBuilder.h"
#include "gui/IVramManager.h"
#include "gui/VramContext.h"
#include "gui/GraphicsContext.h"
#include "core/math/ColorConverter.h"
#include "core/math/RgbMixer.h"
#include "themes/material/MaterialColorScheme.h"
#include "themes/IFontRepository.h"
#include "bannerListItemBg0.h"
#include "bannerListItemBg1.h"
#include "bannerListItemBg2.h"
#include "gui/palette/GradientPalette.h"
#include "gui/palette/DirectPalette.h"
#include "gui/views/Label2DView.h"
#include "MaterialBannerListItemView.h"
MaterialBannerListItemView::MaterialBannerListItemView(const MaterialColorScheme* materialColorScheme,
const IFontRepository* fontRepository)
: BannerListItemView(
std::make_unique<Label2DView>(160, 16, 50, fontRepository->GetFont(FontType::Medium10)),
std::make_unique<Label2DView>(160, 16, 50, fontRepository->GetFont(FontType::Regular10)),
std::make_unique<Label2DView>(160, 16, 50, fontRepository->GetFont(FontType::Regular10)))
, _materialColorScheme(materialColorScheme) { }
void MaterialBannerListItemView::Draw(GraphicsContext& graphicsContext)
{
if (!graphicsContext.IsVisible(Rectangle(_position.x - 2, _position.y - 2, 207, 48)))
return;
auto backColor = _materialColorScheme->inverseOnSurface;
auto frontColor = _isFocused
? _materialColorScheme->mainIconBg
: _materialColorScheme->surfaceBright;
u16 bgPltt[16];
for (int i = 0; i < 16; i++)
{
auto blendFactors = ColorConverter::FromXBGR555(bannerListItemBg0Pal[i]);
auto palColor = Rgb<8, 8, 8>(
(backColor.r * blendFactors.r + frontColor.r * blendFactors.g + 16) / 31,
(backColor.g * blendFactors.r + frontColor.g * blendFactors.g + 16) / 31,
(backColor.b * blendFactors.r + frontColor.b * blendFactors.g + 16) / 31);
palColor = palColor.Clamped();
bgPltt[i] = ColorConverter::ToGBGR565(palColor);
}
u32 bgPaletteRow = graphicsContext.GetPaletteManager().AllocRow(
DirectPalette(bgPltt), _position.y - 2, _position.y - 2 + 48);
gfx_oam_entry_t* oam = graphicsContext.GetOamManager().AllocOams(4);
OamBuilder::OamWithSize<64, 64>(
_position.x - 2,
_position.y - 2, _bgVramOffset >> 7)
.WithPalette16(bgPaletteRow)
.WithPriority(graphicsContext.GetPriority())
.Build(oam[0]);
OamBuilder::OamWithSize<64, 64>(
_position.x - 2 + 64,
_position.y - 2, (_bgVramOffset + bannerListItemBg0TilesLen) >> 7)
.WithPalette16(bgPaletteRow)
.WithPriority(graphicsContext.GetPriority())
.Build(oam[1]);
OamBuilder::OamWithSize<64, 64>(
_position.x - 2 + 64 + 64,
_position.y - 2, (_bgVramOffset + bannerListItemBg0TilesLen) >> 7)
.WithPalette16(bgPaletteRow)
.WithPriority(graphicsContext.GetPriority())
.Build(oam[2]);
OamBuilder::OamWithSize<32, 64>(
_position.x - 2 + 64 + 64 + 64,
_position.y - 2, (_bgVramOffset + bannerListItemBg0TilesLen + bannerListItemBg1TilesLen) >> 7)
.WithPalette16(bgPaletteRow)
.WithPriority(graphicsContext.GetPriority())
.Build(oam[3]);
if (_isFocused)
{
_firstLine->SetBackgroundColor(frontColor);
_firstLine->SetForegroundColor(_materialColorScheme->onSecondaryContainer);
_secondLine->SetBackgroundColor(frontColor);
_secondLine->SetForegroundColor(_materialColorScheme->onSecondaryContainer);
_thirdLine->SetBackgroundColor(frontColor);
_thirdLine->SetForegroundColor(_materialColorScheme->onSecondaryContainer);
}
else
{
_firstLine->SetForegroundColor(_materialColorScheme->onSurface);
_firstLine->SetBackgroundColor(_materialColorScheme->surfaceBright);
_secondLine->SetForegroundColor(_materialColorScheme->onSurfaceVariant);
_secondLine->SetBackgroundColor(_materialColorScheme->surfaceBright);
_thirdLine->SetForegroundColor(_materialColorScheme->onSurfaceVariant);
_thirdLine->SetBackgroundColor(_materialColorScheme->surfaceBright);
}
if (_lines == 1)
{
_firstLine->SetPosition(_position.x + 6 + 32 + 6, _position.y + 14);
}
else if (_lines == 2)
{
_firstLine->SetPosition(_position.x + 6 + 32 + 6, _position.y + 8);
_secondLine->SetPosition(_position.x + 6 + 32 + 6, _position.y + 20);
}
else
{
_firstLine->SetPosition(_position.x + 6 + 32 + 6, _position.y + 2);
_secondLine->SetPosition(_position.x + 6 + 32 + 6, _position.y + 14);
_thirdLine->SetPosition(_position.x + 6 + 32 + 6, _position.y + 26);
}
if (_lines >= 1)
_firstLine->Draw(graphicsContext);
if (_lines >= 2)
_secondLine->Draw(graphicsContext);
if (_lines >= 3)
_thirdLine->Draw(graphicsContext);
if (_icon)
{
_icon->SetObjVramOffset(_iconVramOffset);
_icon->SetPosition(6 + _position.x, 6 + _position.y);
_icon->Draw(graphicsContext, frontColor);
}
}
BannerListItemView::VramToken MaterialBannerListItemView::UploadGraphics(const VramContext& vramContext)
{
const auto objVramManager = vramContext.GetObjVramManager();
u32 vramOffset = 0;
if (objVramManager)
{
vramOffset = objVramManager->Alloc(
bannerListItemBg0TilesLen + bannerListItemBg1TilesLen + bannerListItemBg2TilesLen);
dma_ntrCopy32(3, bannerListItemBg0Tiles,
objVramManager->GetVramAddress(vramOffset),
bannerListItemBg0TilesLen);
dma_ntrCopy32(3, bannerListItemBg1Tiles,
objVramManager->GetVramAddress(vramOffset + bannerListItemBg0TilesLen),
bannerListItemBg1TilesLen);
dma_ntrCopy32(3, bannerListItemBg2Tiles,
objVramManager->GetVramAddress(vramOffset + bannerListItemBg0TilesLen + bannerListItemBg1TilesLen),
bannerListItemBg2TilesLen);
}
return BannerListItemView::VramToken(vramOffset);
}