Add touch input support, add fast scrolling support for coverflow display mode, fix use after free bug in banner list mode

This commit is contained in:
Gericom
2026-04-04 19:24:39 +02:00
parent 21a8790ebc
commit 97762b14d3
119 changed files with 2251 additions and 762 deletions

View File

@@ -1,21 +1,26 @@
#include "common.h"
#include "gui/IVramManager.h"
#include "gui/GraphicsContext.h"
#include "gui/input/InputProvider.h"
#include "BannerListItemView.h"
BannerListItemView::BannerListItemView(std::unique_ptr<LabelView> firstLine,
std::unique_ptr<LabelView> secondLine, std::unique_ptr<LabelView> thirdLine)
: _firstLine(std::move(firstLine))
BannerListItemView::BannerListItemView(std::unique_ptr<RomBrowserItemViewModel> viewModel,
SharedPtr<LabelView> firstLine, SharedPtr<LabelView> secondLine, SharedPtr<LabelView> thirdLine)
: _viewModel(std::move(viewModel))
, _firstLine(std::move(firstLine))
, _secondLine(std::move(secondLine))
, _thirdLine(std::move(thirdLine))
, _inputHandler(this, _viewModel.get())
{
AddChildTail(_firstLine.get());
AddChildTail(_secondLine.get());
AddChildTail(_thirdLine.get());
AddChildTail(_firstLine.GetPointer());
AddChildTail(_secondLine.GetPointer());
AddChildTail(_thirdLine.GetPointer());
}
void BannerListItemView::Update()
{
_viewModel->DisposeQueueTaskWhenComplete();
ViewContainer::Update();
if (_icon)
@@ -23,3 +28,24 @@ void BannerListItemView::Update()
_icon->Update();
}
}
bool BannerListItemView::HandleInput(const InputProvider& inputProvider, FocusManager& focusManager)
{
return _inputHandler.HandleInput(inputProvider, focusManager)
|| View::HandleInput(inputProvider, focusManager);
}
void BannerListItemView::HandlePenDown(const Point& touchPoint, FocusManager& focusManager)
{
_inputHandler.HandlePenDown(touchPoint, focusManager);
}
void BannerListItemView::HandlePenMove(const Point& touchPoint, FocusManager& focusManager)
{
_inputHandler.HandlePenMove(touchPoint, focusManager);
}
void BannerListItemView::HandlePenUp(const Point& lastTouchPoint, FocusManager& focusManager)
{
_inputHandler.HandlePenUp(lastTouchPoint, focusManager);
}

View File

@@ -2,6 +2,8 @@
#include "BannerView.h"
#include "gui/views/LabelView.h"
#include "../FileType/FileIcon.h"
#include "romBrowser/viewModels/RomBrowserItemViewModel.h"
#include "RomBrowserItemInputHandler.h"
class BannerListItemView : public BannerView
{
@@ -19,11 +21,13 @@ public:
constexpr u32 GetVramOffset() const { return _vramOffset; }
};
BannerListItemView(std::unique_ptr<LabelView> firstLine,
std::unique_ptr<LabelView> secondLine, std::unique_ptr<LabelView> thirdLine);
void Update() override;
bool HandleInput(const InputProvider& inputProvider, FocusManager& focusManager) override;
void HandlePenDown(const Point& touchPoint, FocusManager& focusManager) override;
void HandlePenMove(const Point& touchPoint, FocusManager& focusManager) override;
void HandlePenUp(const Point& lastTouchPoint, FocusManager& focusManager) override;
virtual void SetGraphics(const VramToken& vramToken) { }
void SetFirstLineAsync(TaskQueueBase* taskQueue, const char* firstLine, bool ellipsis) override
@@ -60,8 +64,18 @@ public:
_thirdLine->SetText(thirdLine, length);
}
RomBrowserItemViewModel& GetViewModel() const
{
return *_viewModel;
}
protected:
std::unique_ptr<LabelView> _firstLine;
std::unique_ptr<LabelView> _secondLine;
std::unique_ptr<LabelView> _thirdLine;
std::unique_ptr<RomBrowserItemViewModel> _viewModel;
SharedPtr<LabelView> _firstLine;
SharedPtr<LabelView> _secondLine;
SharedPtr<LabelView> _thirdLine;
RomBrowserItemInputHandler _inputHandler;
BannerListItemView(std::unique_ptr<RomBrowserItemViewModel> viewModel, SharedPtr<LabelView> firstLine,
SharedPtr<LabelView> secondLine, SharedPtr<LabelView> thirdLine);
};

View File

@@ -0,0 +1,34 @@
#include "common.h"
#include "BottomSheetView.h"
void BottomSheetView::HandlePenDown(const Point& touchPoint, FocusManager& focusManager)
{
DialogView::HandlePenDown(touchPoint, focusManager);
if (!GetBounds().Contains(touchPoint))
{
_oobPenDown = true;
}
}
void BottomSheetView::HandlePenMove(const Point& touchPoint, FocusManager& focusManager)
{
DialogView::HandlePenMove(touchPoint, focusManager);
if (GetBounds().Contains(touchPoint))
{
_oobPenDown = false;
}
}
void BottomSheetView::HandlePenUp(const Point& lastTouchPoint, FocusManager& focusManager)
{
DialogView::HandlePenUp(lastTouchPoint, focusManager);
if (_oobPenDown && !GetBounds().Contains(lastTouchPoint))
{
Close();
}
_oobPenDown = false;
}

View File

@@ -5,6 +5,10 @@
class BottomSheetView : public DialogView
{
public:
void HandlePenDown(const Point& touchPoint, FocusManager& focusManager) override;
void HandlePenMove(const Point& touchPoint, FocusManager& focusManager) override;
void HandlePenUp(const Point& lastTouchPoint, FocusManager& focusManager) override;
Rectangle GetBounds() const override
{
return Rectangle(_position.x, _position.y, 256 - _position.x, 192 - _position.y);
@@ -16,4 +20,10 @@ public:
}
constexpr DialogType GetDialogType() const override { return DialogType::BottomSheet; }
protected:
virtual void Close() = 0;
private:
bool _oobPenDown = false;
};

View File

@@ -40,13 +40,13 @@ void ChipView::Draw(GraphicsContext& graphicsContext)
DirectPalette(chipPltt), _position.y, _position.y + 20);
if (!_isFocused)
{
_label.SetBackgroundColor(_materialColorScheme->secondaryContainer);
_label.SetForegroundColor(_materialColorScheme->onSecondaryContainer);
_label->SetBackgroundColor(_materialColorScheme->secondaryContainer);
_label->SetForegroundColor(_materialColorScheme->onSecondaryContainer);
}
else
{
_label.SetBackgroundColor(fgColor);
_label.SetForegroundColor(_materialColorScheme->onSecondaryContainer);
_label->SetBackgroundColor(fgColor);
_label->SetForegroundColor(_materialColorScheme->onSecondaryContainer);
}
}
else
@@ -70,13 +70,13 @@ void ChipView::Draw(GraphicsContext& graphicsContext)
if (!_isFocused)
{
_label.SetBackgroundColor(_materialColorScheme->GetColor(_backgroundColor));
_label.SetForegroundColor(_materialColorScheme->onSurfaceVariant);
_label->SetBackgroundColor(_materialColorScheme->GetColor(_backgroundColor));
_label->SetForegroundColor(_materialColorScheme->onSurfaceVariant);
}
else
{
_label.SetBackgroundColor(fgColor);
_label.SetForegroundColor(_materialColorScheme->onSurfaceVariant);
_label->SetBackgroundColor(fgColor);
_label->SetForegroundColor(_materialColorScheme->onSurfaceVariant);
}
}
@@ -88,7 +88,7 @@ void ChipView::Draw(GraphicsContext& graphicsContext)
.WithPriority(graphicsContext.GetPriority())
.Build(oams[0]);
OamBuilder::OamWithSize<64, 32>(
_position.x + width - 48 - 16,
_position.x + width - 48 - 16,
_position.y, _vramOffset >> 7)
.WithPalette16(paletteRow)
.WithPriority(graphicsContext.GetPriority())
@@ -97,8 +97,8 @@ void ChipView::Draw(GraphicsContext& graphicsContext)
DrawIcon(graphicsContext, fgColor);
_label.SetPosition(_position.x + (_iconVramOffset == 0xFFFFFFFF ? 10 : 22), _position.y + 3);
_label.Draw(graphicsContext);
_label->SetPosition(_position.x + (_iconVramOffset == 0xFFFFFFFF ? 10 : 22), _position.y + 3);
_label->Draw(graphicsContext);
}
void ChipView::DrawIcon(GraphicsContext& graphicsContext, const Rgb<8, 8, 8>& fgColor)
@@ -135,4 +135,4 @@ ChipView::VramToken ChipView::UploadGraphics(IVramManager& vramManager)
u32 vramOffset = vramManager.Alloc(chipFilledTilesLen);
dma_ntrCopy32(3, chipFilledTiles, vramManager.GetVramAddress(vramOffset), chipFilledTilesLen);
return ChipView::VramToken(vramOffset);
}
}

View File

@@ -13,6 +13,8 @@ class IVramManager;
class ChipView : public View
{
SHARED_ONLY(ChipView)
public:
class VramToken
{
@@ -27,22 +29,16 @@ public:
constexpr u32 GetVramOffset() const { return _vramOffset; }
};
explicit ChipView(md::sys::color backgroundColor, const MaterialColorScheme* materialColorScheme,
const IFontRepository* fontRepository)
: _vramOffset(0), _isSelected(false), _backgroundColor(backgroundColor)
, _label(CHIP_VIEW_MAX_WIDTH - 20, 16, 30, fontRepository->GetFont(FontType::Medium10))
, _iconVramOffset(0xFFFFFFFF), _materialColorScheme(materialColorScheme) { }
void InitVram(const VramContext& vramContext) override { _label->InitVram(vramContext); }
void InitVram(const VramContext& vramContext) override { _label.InitVram(vramContext); }
void SetText(const char16_t* text) { _label.SetText(text); }
void SetText(const char16_t* text, u32 length) { _label.SetText(text, length); }
QueueTask<void> SetTextAsync(TaskQueueBase* taskQueue, const char16_t* text) { return _label.SetTextAsync(taskQueue, text); }
QueueTask<void> SetTextAsync(TaskQueueBase* taskQueue, const char16_t* text, u32 length) { return _label.SetTextAsync(taskQueue, text, length); }
void SetText(const char16_t* text) { _label->SetText(text); }
void SetText(const char16_t* text, u32 length) { _label->SetText(text, length); }
QueueTask<void> SetTextAsync(TaskQueueBase* taskQueue, const char16_t* text) { return _label->SetTextAsync(taskQueue, text); }
QueueTask<void> SetTextAsync(TaskQueueBase* taskQueue, const char16_t* text, u32 length) { return _label->SetTextAsync(taskQueue, text, length); }
void Draw(GraphicsContext& graphicsContext) override;
void VBlank() override { _label.VBlank(); }
void VBlank() override { _label->VBlank(); }
void SetGraphics(const VramToken& vramToken)
{
@@ -63,9 +59,13 @@ public:
{
int width;
if (_iconVramOffset == 0xFFFFFFFF)
width = 10 + _label.GetStringWidth() + 10;
{
width = 10 + _label->GetStringWidth() + 10;
}
else
width = 22 + _label.GetStringWidth() + 10;
{
width = 22 + _label->GetStringWidth() + 10;
}
width = std::clamp(width, CHIP_VIEW_MIN_WIDTH, CHIP_VIEW_MAX_WIDTH);
return width;
}
@@ -83,9 +83,15 @@ private:
u32 _vramOffset;
bool _isSelected;
md::sys::color _backgroundColor;
Label2DView _label;
SharedPtr<Label2DView> _label;
u32 _iconVramOffset;
const MaterialColorScheme* _materialColorScheme;
ChipView(md::sys::color backgroundColor, const MaterialColorScheme* materialColorScheme,
const IFontRepository* fontRepository)
: _vramOffset(0), _isSelected(false), _backgroundColor(backgroundColor)
, _label(Label2DView::CreateShared(CHIP_VIEW_MAX_WIDTH - 20, 16, 30, fontRepository->GetFont(FontType::Medium10)))
, _iconVramOffset(0xFFFFFFFF), _materialColorScheme(materialColorScheme) { }
void DrawIcon(GraphicsContext& graphicsContext, const Rgb<8, 8, 8>& fgColor);
};

View File

@@ -5,6 +5,7 @@
#include "gui/Gx.h"
#include "gui/GraphicsContext.h"
#include "gui/materialDesign.h"
#include "gui/input/InputProvider.h"
#include "core/math/SinTable.h"
#include "romBrowser/FileType/FileCover.h"
#include "CoverFlowRecyclerView.h"
@@ -18,8 +19,10 @@ void CoverFlowRecyclerView::Update()
return;
}
int rangeStartIndex = GetSelectedItem() - 4;
int rangeEndIndex = GetSelectedItem() + 1 + 4;
_scrollAnimator.Update();
int rangeStartIndex = _scrollAnimator.GetValue().Int() - 4;
int rangeEndIndex = _scrollAnimator.GetValue().Int() + 1 + 4;
rangeStartIndex = std::clamp(rangeStartIndex, 0, (int)_itemCount - 1);
rangeEndIndex = std::clamp(rangeEndIndex, 0, (int)_itemCount);
@@ -43,10 +46,8 @@ void CoverFlowRecyclerView::Update()
for (u32 i = _viewPoolFreeCount; i < _viewPool.size(); i++)
{
_viewPoolEx[i].yAngleAnimator.Update();
_viewPoolEx[i].xPositionAnimator.Update();
_viewPoolEx[i].zPositionAnimator.Update();
_viewPool[i].view->SetPosition(_viewPoolEx[i].xPositionAnimator.GetValue().Int(), 32 + 80);
UpdateItemPosition(i);
_viewPool[i].view->SetPosition(_viewPoolEx[i].xPosition.Int(), 32 + 80);
_viewPool[i].view->Update();
}
}
@@ -86,9 +87,9 @@ void CoverFlowRecyclerView::Draw(GraphicsContext& graphicsContext)
graphicsContext.SetPolygonId(i);
Gx::MtxPush();
{
fix32<12> x = _viewPoolEx[i].xPositionAnimator.GetValue();
u32 angle = _viewPoolEx[i].yAngleAnimator.GetValue();
fix32<12> z = _viewPoolEx[i].zPositionAnimator.GetValue();
fix32<12> x = _viewPoolEx[i].xPosition;
u32 angle = _viewPoolEx[i].yAngle;
fix32<12> z = _viewPoolEx[i].zPosition;
auto sinCos = gSinTable.SinCos(angle);
mtx43_t rotMtx =
{
@@ -110,47 +111,144 @@ void CoverFlowRecyclerView::Draw(GraphicsContext& graphicsContext)
Gx::MtxMode(GX_MTX_MODE_POSITION_VECTOR);
}
void CoverFlowRecyclerView::UpdateItemPosition(int viewPoolIndex, bool initial)
bool CoverFlowRecyclerView::HandleInput(const InputProvider& inputProvider, FocusManager& focusManager)
{
ViewPoolEntry* item = &_viewPool[viewPoolIndex];
ViewPoolEntryEx* itemEx = &_viewPoolEx[viewPoolIndex];
int selectedIndex = GetSelectedItem();
if (selectedIndex == -1)
if (_itemCount != 0 && inputProvider.Triggered(InputKey::L | InputKey::R))
{
selectedIndex = 0;
int direction = inputProvider.Triggered(InputKey::L) ? -1 : 1;
int selected = std::clamp(_selectedItem->itemIdx + 10 * direction, 0, (int)_itemCount - 1);
focusManager.Unfocus();
SetSelectedItem(selected, false);
focusManager.Focus(_selectedItem->view);
return true;
}
int itemIndex = item->itemIdx;
fix32<12> x;
fix32<12> z = 0;
u32 angle;
if (itemIndex < selectedIndex)
return View::HandleInput(inputProvider, focusManager);
}
void CoverFlowRecyclerView::HandlePenDown(const Point& touchPoint, FocusManager& focusManager)
{
if (GetBounds().Contains(touchPoint))
{
x = 256 / 2 - (COVER_HEIGHT / 4) + COVER_SPACING * (itemIndex - selectedIndex);
angle = std::clamp((selectedIndex - itemIndex) * 10 + 45, -90, 90) * (1 << 16) / 360;
z = -(selectedIndex - itemIndex) * 30 - 20;
_penDown = true;
_penDownPosition = touchPoint;
_hasScrollStarted = false;
_penDownScrollOffset = _scrollAnimator.GetValue();
if (_itemCount > 0)
{
_selectedItem->view->HandlePenDown(touchPoint, focusManager);
}
}
else if (itemIndex > selectedIndex)
}
void CoverFlowRecyclerView::HandlePenMove(const Point& touchPoint, FocusManager& focusManager)
{
if (!_penDown)
{
x = 256 / 2 + (COVER_HEIGHT / 4) + COVER_SPACING * (itemIndex - selectedIndex);
angle = std::clamp((selectedIndex - itemIndex) * 10 - 45, -90, 90) * (1 << 16) / 360;
z = (selectedIndex - itemIndex) * 30 - 20;
return;
}
if (!_hasScrollStarted)
{
if (_itemCount > 0)
{
_selectedItem->view->HandlePenMove(touchPoint, focusManager);
}
int dx = touchPoint.x - _penDownPosition.x;
int dy = touchPoint.y - _penDownPosition.y;
if (dx * dx + dy * dy > 7 * 7)
{
bool shouldScrollStart = std::abs(touchPoint.x - _penDownPosition.x) > std::abs(touchPoint.y - _penDownPosition.y);
if (shouldScrollStart)
{
_hasScrollStarted = true;
}
else
{
_penDown = false; //wrong direction drag, so cancel it
}
if (_itemCount > 0)
{
_selectedItem->view->HandlePenUp(Point(-1, -1), focusManager);
}
}
}
else
{
x = 256 / 2;
angle = 0;
fix32<12> newScrollOffset = _penDownScrollOffset + fix32<12>(_penDownPosition.x - touchPoint.x) * (2.5 / COVER_WIDTH);
if (newScrollOffset < 0)
{
newScrollOffset = 0;
_penDownScrollOffset = 0;
_penDownPosition.x = touchPoint.x;
}
else if (newScrollOffset > (int)_itemCount - 1)
{
newScrollOffset = (int)_itemCount - 1;
_penDownScrollOffset = newScrollOffset;
_penDownPosition.x = touchPoint.x;
}
_scrollAnimator = Animator<fix32<12>>(newScrollOffset);
}
}
void CoverFlowRecyclerView::HandlePenUp(const Point& lastTouchPoint, FocusManager& focusManager)
{
if (_hasScrollStarted)
{
SetSelectedItem((_scrollAnimator.GetValue() + 0.5).Int(), false);
}
if (_itemCount > 0)
{
_selectedItem->view->HandlePenUp(lastTouchPoint, focusManager);
focusManager.Focus(_selectedItem->view);
}
_penDown = false;
}
void CoverFlowRecyclerView::SetSelectedItem(int itemIdx, bool initial)
{
CoverFlowRecyclerViewBase::SetSelectedItem(itemIdx, initial);
if (itemIdx < 0 || itemIdx >= (int)_itemCount)
{
return;
}
if (initial)
{
itemEx->yAngleAnimator = Animator<int>(angle);
itemEx->xPositionAnimator = Animator(x);
itemEx->zPositionAnimator = Animator(z);
_scrollAnimator = Animator<fix32<12>>(itemIdx);
}
else
{
itemEx->yAngleAnimator.Goto(angle, md::sys::motion::duration::medium4, &md::sys::motion::easing::standard);
itemEx->xPositionAnimator.Goto(x, md::sys::motion::duration::medium4, &md::sys::motion::easing::standard);
itemEx->zPositionAnimator.Goto(z, md::sys::motion::duration::medium4, &md::sys::motion::easing::standard);
_scrollAnimator.Goto(itemIdx, md::sys::motion::duration::medium4, &md::sys::motion::easing::standard);
}
}
void CoverFlowRecyclerView::UpdateItemPosition(int viewPoolIndex)
{
auto& item = _viewPool[viewPoolIndex];
auto& itemEx = _viewPoolEx[viewPoolIndex];
int itemIndex = item.itemIdx;
fix32<12> absOffsetFromCenter = (itemIndex - _scrollAnimator.GetValue()).Abs();
fix32<12> initialOffsetFromCenter = absOffsetFromCenter.Clamp(0, 1);
fix32<12> x = (COVER_HEIGHT / 4) * initialOffsetFromCenter + COVER_SPACING * absOffsetFromCenter;
int angle = -(fix32<16>((absOffsetFromCenter * 10 + 45 * initialOffsetFromCenter).Clamp(-90, 90)) / 360).GetRawValue();
fix32<12> z = -absOffsetFromCenter * 30 - 20 * initialOffsetFromCenter;
if (itemIndex <= _scrollAnimator.GetValue().Int())
{
x = -x;
angle = -angle;
}
itemEx.yAngle = angle;
itemEx.xPosition = x + 256 / 2;
itemEx.zPosition = z;
}

View File

@@ -5,30 +5,37 @@
class CoverFlowRecyclerView : public CoverFlowRecyclerViewBase
{
struct Private { explicit Private() = default; };
SHARED_ONLY(CoverFlowRecyclerView)
public:
explicit CoverFlowRecyclerView(Private) { }
static SharedPtr<CoverFlowRecyclerView> CreateShared()
{
return SharedPtr<CoverFlowRecyclerView>::MakeShared(Private());
}
void Update() override;
void Draw(GraphicsContext& graphicsContext) override;
bool HandleInput(const InputProvider& inputProvider, FocusManager& focusManager) override;
void HandlePenDown(const Point& touchPoint, FocusManager& focusManager) override;
void HandlePenMove(const Point& touchPoint, FocusManager& focusManager) override;
void HandlePenUp(const Point& lastTouchPoint, FocusManager& focusManager) override;
private:
struct ViewPoolEntryEx
{
Animator<int> yAngleAnimator;
Animator<fix32<12>> xPositionAnimator;
Animator<fix32<12>> zPositionAnimator;
int yAngle;
fix32<12> xPosition;
fix32<12> zPosition;
};
std::array<ViewPoolEntryEx, 10> _viewPoolEx;
Animator<fix32<12>> _scrollAnimator = Animator<fix32<12>>(0);
bool _penDown = false;
Point _penDownPosition = Point(0, 0);
bool _hasScrollStarted = false;
fix32<12> _penDownScrollOffset = 0;
void UpdateItemPosition(int viewPoolIndex, bool initial) override;
explicit CoverFlowRecyclerView() { }
void SetSelectedItem(int itemIdx, bool initial) override;
void UpdateItemPosition(int viewPoolIndex);
void SwapViewPoolEntry(int indexA, int indexB) override
{

View File

@@ -115,7 +115,6 @@ CoverFlowRecyclerViewBase::ViewPoolEntry* CoverFlowRecyclerViewBase::BindViewPoo
_viewPoolFreeCount--;
entry.itemIdx = itemIdx;
_adapter->BindView(entry.view, itemIdx);
UpdateItemPosition(viewPoolIndex, true);
return &entry;
}
@@ -185,9 +184,4 @@ void CoverFlowRecyclerViewBase::SetSelectedItem(int itemIdx, bool initial)
{
_selectedItem = BindViewPoolEntry(itemIdx);
}
for (u32 i = _viewPoolFreeCount; i < _viewPool.size(); i++)
{
UpdateItemPosition(i, initial);
}
}

View File

@@ -1,9 +1,8 @@
#pragma once
#include <array>
#include "core/EnableSharedFromThis.h"
#include "gui/views/RecyclerViewBase.h"
class CoverFlowRecyclerViewBase : public RecyclerViewBase, public EnableSharedFromThis<CoverFlowRecyclerViewBase>
class CoverFlowRecyclerViewBase : public RecyclerViewBase
{
public:
~CoverFlowRecyclerViewBase() override;
@@ -53,8 +52,7 @@ protected:
void BindRange(int start, int end);
void ReleaseViewPoolEntry(int itemIdx);
void ReleaseRange(int start, int end);
void SetSelectedItem(int itemIdx, bool initial);
virtual void UpdateItemPosition(int viewPoolIndex, bool initial) = 0;
virtual void SetSelectedItem(int itemIdx, bool initial);
virtual void SwapViewPoolEntry(int indexA, int indexB)
{

View File

@@ -4,6 +4,7 @@
#include "gui/Gx.h"
#include "gui/materialDesign.h"
#include "gui/GraphicsContext.h"
#include "gui/input/InputProvider.h"
#include "CoverView.h"
void CoverView::InitVram(const VramContext& vramContext)
@@ -17,6 +18,11 @@ void CoverView::InitVram(const VramContext& vramContext)
}
}
void CoverView::Update()
{
_viewModel->DisposeQueueTaskWhenComplete();
}
void CoverView::Draw(GraphicsContext& graphicsContext)
{
if (_cover.Lock() && _textureLoadRequest.GetState() == VBlankTextureLoadRequestState::LoadComplete)
@@ -93,3 +99,24 @@ void CoverView::UploadCoverGraphics()
_vblankTextureLoader->RequestLoad(_textureLoadRequest);
}
}
bool CoverView::HandleInput(const InputProvider& inputProvider, FocusManager& focusManager)
{
return _inputHandler.HandleInput(inputProvider, focusManager)
|| View::HandleInput(inputProvider, focusManager);
}
void CoverView::HandlePenDown(const Point& touchPoint, FocusManager& focusManager)
{
_inputHandler.HandlePenDown(touchPoint, focusManager);
}
void CoverView::HandlePenMove(const Point& touchPoint, FocusManager& focusManager)
{
_inputHandler.HandlePenMove(touchPoint, focusManager);
}
void CoverView::HandlePenUp(const Point& lastTouchPoint, FocusManager& focusManager)
{
_inputHandler.HandlePenUp(lastTouchPoint, focusManager);
}

View File

@@ -4,15 +4,14 @@
#include "gui/views/View.h"
#include "../FileType/FileCover.h"
#include "gui/VBlankTextureLoader.h"
#define COVER_THICKNESS (fix32<12>(0.23).GetRawValue())
#include "romBrowser/viewModels/RomBrowserItemViewModel.h"
#include "RomBrowserItemInputHandler.h"
class CoverView : public View
{
public:
explicit CoverView(VBlankTextureLoader* vblankTextureLoader)
: _vblankTextureLoader(vblankTextureLoader) { }
SHARED_ONLY(CoverView)
public:
~CoverView() override
{
_vblankTextureLoader->CancelLoad(_textureLoadRequest);
@@ -20,8 +19,14 @@ public:
void InitVram(const VramContext& vramContext) override;
void Update() override;
void Draw(GraphicsContext& graphicsContext) override;
bool HandleInput(const InputProvider& inputProvider, FocusManager& focusManager) override;
void HandlePenDown(const Point& touchPoint, FocusManager& focusManager) override;
void HandlePenMove(const Point& touchPoint, FocusManager& focusManager) override;
void HandlePenUp(const Point& lastTouchPoint, FocusManager& focusManager) override;
Rectangle GetBounds() const override
{
return Rectangle(_position.x - (COVER_WIDTH / 2), _position.y - (COVER_HEIGHT / 2), COVER_WIDTH, COVER_HEIGHT);
@@ -41,10 +46,21 @@ public:
void UploadCoverGraphics();
RomBrowserItemViewModel& GetViewModel() const
{
return *_viewModel;
}
private:
std::unique_ptr<RomBrowserItemViewModel> _viewModel;
VBlankTextureLoader* _vblankTextureLoader;
AtomicSharedPtr<FileCover> _cover;
VBlankTextureLoadRequest _textureLoadRequest;
u32 _texVramOffset = 0;
u32 _plttVramOffset = 0;
RomBrowserItemInputHandler _inputHandler;
CoverView(std::unique_ptr<RomBrowserItemViewModel> viewModel, VBlankTextureLoader* vblankTextureLoader)
: _viewModel(std::move(viewModel)), _vblankTextureLoader(vblankTextureLoader)
, _inputHandler(this, _viewModel.get()) { }
};

View File

@@ -52,18 +52,18 @@ DisplaySettingsBottomSheetView::DisplaySettingsBottomSheetView(
DisplaySettingsViewModel* viewModel, const MaterialColorScheme* materialColorScheme,
const IFontRepository* fontRepository)
: _viewModel(viewModel)
, _titleLabel(128, 16, 25, fontRepository->GetFont(FontType::Medium11))
, _layoutLabel(64, 16, 25, fontRepository->GetFont(FontType::Regular10))
, _sortingLabel(64, 16, 25, fontRepository->GetFont(FontType::Regular10))
, _titleLabel(Label2DView::CreateShared(128, 16, 25, fontRepository->GetFont(FontType::Medium11)))
, _layoutLabel(Label2DView::CreateShared(64, 16, 25, fontRepository->GetFont(FontType::Regular10)))
, _sortingLabel(Label2DView::CreateShared(64, 16, 25, fontRepository->GetFont(FontType::Regular10)))
, _materialColorScheme(materialColorScheme)
// , _filtersLabel(64, 16, 25, fontRepository->GetFont(FontType::Regular10))
{
_titleLabel.SetText(u"Display Settings");
AddChildTail(&_titleLabel);
_layoutLabel.SetText(u"Layout");
AddChildTail(&_layoutLabel);
_sortingLabel.SetText(u"Sorting");
AddChildTail(&_sortingLabel);
_titleLabel->SetText(u"Display Settings");
AddChildTail(_titleLabel.GetPointer());
_layoutLabel->SetText(u"Layout");
AddChildTail(_layoutLabel.GetPointer());
_sortingLabel->SetText(u"Sorting");
AddChildTail(_sortingLabel.GetPointer());
// _filtersLabel.SetText(u"Filters");
// AddChildTail(&_filtersLabel);
@@ -90,7 +90,7 @@ DisplaySettingsBottomSheetView::DisplaySettingsBottomSheetView(
SharedPtr<IconButton2DView> DisplaySettingsBottomSheetView::CreateLayoutOptionIconButton()
{
auto layoutOption = SharedPtr<IconButton2DView>::MakeShared(
auto layoutOption = IconButton2DView::CreateShared(
IconButtonView::Type::Tonal,
IconButtonView::State::ToggleUnselected,
md::sys::color::surfaceContainerLow,
@@ -113,7 +113,7 @@ SharedPtr<IconButton2DView> DisplaySettingsBottomSheetView::CreateLayoutOptionIc
SharedPtr<IconButton2DView> DisplaySettingsBottomSheetView::CreateSortOptionIconButton()
{
auto sortOption = SharedPtr<IconButton2DView>::MakeShared(
auto sortOption = IconButton2DView::CreateShared(
IconButtonView::Type::Tonal,
IconButtonView::State::ToggleUnselected,
md::sys::color::surfaceContainerLow,
@@ -175,9 +175,9 @@ void DisplaySettingsBottomSheetView::InitVram(const VramContext& vramContext)
void DisplaySettingsBottomSheetView::UpdateLabels()
{
_titleLabel.SetPosition(TITLE_LABEL_X, _position.y + TITLE_LABEL_Y);
_layoutLabel.SetPosition(LAYOUT_LABEL_X, _position.y + LAYOUT_LABEL_Y);
_sortingLabel.SetPosition(SORTING_LABEL_X, _position.y + SORTING_LABEL_Y);
_titleLabel->SetPosition(TITLE_LABEL_X, _position.y + TITLE_LABEL_Y);
_layoutLabel->SetPosition(LAYOUT_LABEL_X, _position.y + LAYOUT_LABEL_Y);
_sortingLabel->SetPosition(SORTING_LABEL_X, _position.y + SORTING_LABEL_Y);
// _filtersLabel.SetPosition(FILTERS_LABEL_X, _position.y + FILTERS_LABEL_Y);
}
@@ -222,12 +222,12 @@ void DisplaySettingsBottomSheetView::Draw(GraphicsContext& graphicsContext)
graphicsContext.SetClipArea(GetBounds());
u32 oldPrio = graphicsContext.SetPriority(1);
{
_titleLabel.SetBackgroundColor(_materialColorScheme->GetColor(md::sys::color::surfaceContainerLow));
_titleLabel.SetForegroundColor(_materialColorScheme->onSurface);
_layoutLabel.SetBackgroundColor(_materialColorScheme->GetColor(md::sys::color::surfaceContainerLow));
_layoutLabel.SetForegroundColor(_materialColorScheme->onSurfaceVariant);
_sortingLabel.SetBackgroundColor(_materialColorScheme->GetColor(md::sys::color::surfaceContainerLow));
_sortingLabel.SetForegroundColor(_materialColorScheme->onSurfaceVariant);
_titleLabel->SetBackgroundColor(_materialColorScheme->GetColor(md::sys::color::surfaceContainerLow));
_titleLabel->SetForegroundColor(_materialColorScheme->onSurface);
_layoutLabel->SetBackgroundColor(_materialColorScheme->GetColor(md::sys::color::surfaceContainerLow));
_layoutLabel->SetForegroundColor(_materialColorScheme->onSurfaceVariant);
_sortingLabel->SetBackgroundColor(_materialColorScheme->GetColor(md::sys::color::surfaceContainerLow));
_sortingLabel->SetForegroundColor(_materialColorScheme->onSurfaceVariant);
// _filtersLabel.SetBackgroundColor(_materialColorScheme->GetColor(md::sys::color::surfaceContainerLow));
// _filtersLabel.SetForegroundColor(_materialColorScheme->onSurfaceVariant);
BottomSheetView::Draw(graphicsContext);
@@ -364,6 +364,11 @@ void DisplaySettingsBottomSheetView::SetGraphics(
// filterOption.SetGraphics(iconButtonVramToken);
}
void DisplaySettingsBottomSheetView::Close()
{
_viewModel->Close();
}
u32 DisplaySettingsBottomSheetView::LoadIcon(IVramManager& vramManager,
const unsigned int* tiles, u32 tilesLength) const
{

View File

@@ -11,10 +11,9 @@ class IFontRepository;
class DisplaySettingsBottomSheetView : public BottomSheetView
{
public:
DisplaySettingsBottomSheetView(DisplaySettingsViewModel* viewModel,
const MaterialColorScheme* materialColorScheme, const IFontRepository* fontRepository);
SHARED_ONLY(DisplaySettingsBottomSheetView)
public:
void InitVram(const VramContext& vramContext) override;
void Update() override;
void Draw(GraphicsContext& graphicsContext) override;
@@ -29,12 +28,15 @@ public:
focusManager.Focus(_layoutOptions[0]);
}
protected:
void Close() override;
private:
DisplaySettingsViewModel* _viewModel;
Label2DView _titleLabel;
Label2DView _layoutLabel;
Label2DView _sortingLabel;
SharedPtr<Label2DView> _titleLabel;
SharedPtr<Label2DView> _layoutLabel;
SharedPtr<Label2DView> _sortingLabel;
// LabelView _filtersLabel;
std::array<SharedPtr<IconButton2DView>, 4> _layoutOptions;
@@ -47,6 +49,9 @@ private:
SharedPtr<IconButton2DView> CreateSortOptionIconButton();
// IconButton2DView CreateFilterOptionIconButton();
DisplaySettingsBottomSheetView(DisplaySettingsViewModel* viewModel,
const MaterialColorScheme* materialColorScheme, const IFontRepository* fontRepository);
void UpdateLabels();
u32 LoadIcon(IVramManager& vramManager, const unsigned int* tiles, u32 tilesLength) const;

View File

@@ -17,7 +17,7 @@ void IconButton2DView::Draw(GraphicsContext& graphicsContext)
return;
u32 iconPaletteRow;
if (_isFocused)
if (_isFocused || _penDown)
{
const auto& bgColor = _materialColorScheme->GetColor(_backgroundColor);
const auto& selectorBaseColor = _materialColorScheme->GetColor(GetCircleBackgroundColor());

View File

@@ -3,6 +3,8 @@
class IconButton2DView : public IconButtonView
{
SHARED_ONLY(IconButton2DView)
public:
class VramToken
{
@@ -17,12 +19,6 @@ public:
constexpr u32 GetVramOffset() const { return _vramOffset; }
};
IconButton2DView() : IconButtonView() { }
IconButton2DView(Type type, State state,
md::sys::color backgroundColor, const MaterialColorScheme* materialColorScheme)
: IconButtonView(type, state, backgroundColor, materialColorScheme) { }
void Draw(GraphicsContext& graphicsContext) override;
void SetGraphics(const VramToken& vramToken)
@@ -34,4 +30,8 @@ public:
private:
u32 _selectorVramOffset;
IconButton2DView(Type type, State state,
md::sys::color backgroundColor, const MaterialColorScheme* materialColorScheme)
: IconButtonView(type, state, backgroundColor, materialColorScheme) { }
};

View File

@@ -19,7 +19,7 @@ void IconButton3DView::Draw(GraphicsContext& graphicsContext)
return;
u32 iconPaletteRow;
if (_isFocused)
if (_isFocused || _penDown)
{
const auto& selectorBaseColor = _materialColorScheme->GetColor(GetCircleBackgroundColor());
const auto& fgColor = _materialColorScheme->GetColor(GetForegroundColor());

View File

@@ -5,13 +5,9 @@
class IconButton3DView : public IconButtonView
{
SHARED_ONLY(IconButton3DView)
public:
IconButton3DView() : IconButtonView() { }
IconButton3DView(Type type, State state,
md::sys::color backgroundColor, const MaterialColorScheme* materialColorScheme)
: IconButtonView(type, state, backgroundColor, materialColorScheme) { }
void Draw(GraphicsContext& graphicsContext) override;
static void UploadGraphics(const VramContext& vramContext);
@@ -19,5 +15,9 @@ public:
private:
static u32 sSelectorTextureVramOffset;
IconButton3DView(Type type, State state,
md::sys::color backgroundColor, const MaterialColorScheme* materialColorScheme)
: IconButtonView(type, state, backgroundColor, materialColorScheme) { }
void DrawSelector(GraphicsContext& graphicsContext, const Rgb<8, 8, 8>& color);
};

View File

@@ -7,12 +7,46 @@ bool IconButtonView::HandleInput(const InputProvider& inputProvider, FocusManage
if (inputProvider.Triggered(InputKey::A))
{
if (_action)
{
_action(this, _actionArg);
}
return true;
}
return View::HandleInput(inputProvider, focusManager);
}
void IconButtonView::HandlePenDown(const Point& touchPoint, FocusManager& focusManager)
{
if (GetBounds().Contains(touchPoint))
{
_penDown = true;
}
}
void IconButtonView::HandlePenMove(const Point& touchPoint, FocusManager& focusManager)
{
if (!GetBounds().Contains(touchPoint))
{
_penDown = false;
}
}
void IconButtonView::HandlePenUp(const Point& lastTouchPoint, FocusManager& focusManager)
{
if (_penDown && GetBounds().Contains(lastTouchPoint))
{
focusManager.Focus(SharedFromThis());
if (_action)
{
_action(this, _actionArg);
}
}
_penDown = false;
}
bool IconButtonView::IsCircleBackgroundVisible() const
{
switch (_type)

View File

@@ -24,16 +24,6 @@ public:
ToggleSelected
};
IconButtonView()
: _iconVramOffset(0), _action(nullptr), _actionArg(nullptr)
, _type(Type::Standard), _state(State::NoToggle) { }
IconButtonView(Type type, State state,
md::sys::color backgroundColor, const MaterialColorScheme* materialColorScheme)
: _iconVramOffset(0), _backgroundColor(backgroundColor)
, _action(nullptr), _actionArg(nullptr), _type(type), _state(state)
, _materialColorScheme(materialColorScheme) { }
void SetIconVramOffset(u32 vramOffset) { _iconVramOffset = vramOffset; }
Rectangle GetBounds() const override
@@ -53,6 +43,9 @@ public:
}
bool HandleInput(const InputProvider& inputProvider, FocusManager& focusManager) override;
void HandlePenDown(const Point& touchPoint, FocusManager& focusManager) override;
void HandlePenMove(const Point& touchPoint, FocusManager& focusManager) override;
void HandlePenUp(const Point& lastTouchPoint, FocusManager& focusManager) override;
protected:
u32 _iconVramOffset;
@@ -62,6 +55,13 @@ protected:
Type _type;
State _state;
const MaterialColorScheme* _materialColorScheme;
bool _penDown = false;
IconButtonView(Type type, State state,
md::sys::color backgroundColor, const MaterialColorScheme* materialColorScheme)
: _iconVramOffset(0), _backgroundColor(backgroundColor)
, _action(nullptr), _actionArg(nullptr), _type(type), _state(state)
, _materialColorScheme(materialColorScheme) { }
bool IsCircleBackgroundVisible() const;
md::sys::color GetCircleBackgroundColor() const;

View File

@@ -1,6 +1,7 @@
#include "common.h"
#include "gui/IVramManager.h"
#include "gui/VramContext.h"
#include "gui/input/InputProvider.h"
#include "IconGridItemView.h"
void IconGridItemView::InitVram(const VramContext& vramContext)
@@ -15,8 +16,31 @@ void IconGridItemView::InitVram(const VramContext& vramContext)
void IconGridItemView::Update()
{
_viewModel->DisposeQueueTaskWhenComplete();
if (_icon)
{
_icon->Update();
}
}
bool IconGridItemView::HandleInput(const InputProvider& inputProvider, FocusManager& focusManager)
{
return _inputHandler.HandleInput(inputProvider, focusManager)
|| View::HandleInput(inputProvider, focusManager);
}
void IconGridItemView::HandlePenDown(const Point& touchPoint, FocusManager& focusManager)
{
_inputHandler.HandlePenDown(touchPoint, focusManager);
}
void IconGridItemView::HandlePenMove(const Point& touchPoint, FocusManager& focusManager)
{
_inputHandler.HandlePenMove(touchPoint, focusManager);
}
void IconGridItemView::HandlePenUp(const Point& lastTouchPoint, FocusManager& focusManager)
{
_inputHandler.HandlePenUp(lastTouchPoint, focusManager);
}

View File

@@ -1,7 +1,9 @@
#pragma once
#include <memory>
#include "romBrowser/viewModels/RomBrowserItemViewModel.h"
#include "gui/views/View.h"
#include "../FileType/FileIcon.h"
#include "RomBrowserItemInputHandler.h"
class MaterialColorScheme;
@@ -24,6 +26,11 @@ public:
void InitVram(const VramContext& vramContext) override;
void Update() override;
bool HandleInput(const InputProvider& inputProvider, FocusManager& focusManager) override;
void HandlePenDown(const Point& touchPoint, FocusManager& focusManager) override;
void HandlePenMove(const Point& touchPoint, FocusManager& focusManager) override;
void HandlePenUp(const Point& lastTouchPoint, FocusManager& focusManager) override;
void SetIcon(std::unique_ptr<FileIcon> icon)
{
_icon = std::move(icon);
@@ -43,11 +50,18 @@ public:
virtual void SetGraphics(const VramToken& vramToken) { }
RomBrowserItemViewModel& GetViewModel() const
{
return *_viewModel;
}
protected:
std::unique_ptr<RomBrowserItemViewModel> _viewModel;
std::unique_ptr<FileIcon> _icon;
vu16* _iconVram;
u32 _iconVramOffset;
RomBrowserItemInputHandler _inputHandler;
IconGridItemView()
: _icon(nullptr) { }
};
explicit IconGridItemView(std::unique_ptr<RomBrowserItemViewModel> viewModel)
: _viewModel(std::move(viewModel)), _inputHandler(this, _viewModel.get()) { }
};

View File

@@ -13,8 +13,8 @@ NdsGameDetailsBottomSheetView::NdsGameDetailsBottomSheetView(
IRomBrowserController* romBrowserController, const MaterialColorScheme* materialColorScheme,
const IFontRepository* fontRepository)
: _romBrowserController(romBrowserController)
, _cheatsChip(SharedPtr<ChipView>::MakeShared(md::sys::color::surfaceContainerLow, materialColorScheme, fontRepository))
, _favoriteChip(SharedPtr<ChipView>::MakeShared(md::sys::color::surfaceContainerLow, materialColorScheme, fontRepository))
, _cheatsChip(ChipView::CreateShared(md::sys::color::surfaceContainerLow, materialColorScheme, fontRepository))
, _favoriteChip(ChipView::CreateShared(md::sys::color::surfaceContainerLow, materialColorScheme, fontRepository))
{
_cheatsChip->SetText(u"Cheats");
_cheatsChip->SetSelected(false);
@@ -77,4 +77,9 @@ bool NdsGameDetailsBottomSheetView::HandleInput(const InputProvider& inputProvid
return true;
}
return false;
}
}
void NdsGameDetailsBottomSheetView::Close()
{
_romBrowserController->HideGameInfo();
}

View File

@@ -8,12 +8,9 @@ class IFontRepository;
class NdsGameDetailsBottomSheetView : public BottomSheetView
{
public:
NdsGameDetailsBottomSheetView(
IRomBrowserController* romBrowserController,
const MaterialColorScheme* materialColorScheme,
const IFontRepository* fontRepository);
SHARED_ONLY(NdsGameDetailsBottomSheetView)
public:
void SetGraphics(const ChipView::VramToken& chipVramToken)
{
_cheatsChip->SetGraphics(chipVramToken);
@@ -34,10 +31,18 @@ public:
bool HandleInput(const InputProvider& inputProvider, FocusManager& focusManager) override;
protected:
void Close() override;
private:
IRomBrowserController* _romBrowserController;
u32 _smallHeartIconVramOffset;
u32 _smallHeartIconFilledVramOffset;
SharedPtr<ChipView> _cheatsChip;
SharedPtr<ChipView> _favoriteChip;
NdsGameDetailsBottomSheetView(
IRomBrowserController* romBrowserController,
const MaterialColorScheme* materialColorScheme,
const IFontRepository* fontRepository);
};

View File

@@ -21,7 +21,7 @@ RomBrowserAppBarView::RomBrowserAppBarView(
: _viewModel(viewModel)
{
_appBarView = displayMode.CreateAppBarView(romBrowserViewFactory, 1, 1);
_appBarView->SetParent(this);
AddChildTail(_appBarView.GetPointer());
_appBarView->SetButtonAction(APP_BAR_BUTTON_BACK, [] (IconButtonView* sender, void* arg)
{
@@ -35,7 +35,7 @@ RomBrowserAppBarView::RomBrowserAppBarView(
void RomBrowserAppBarView::InitVram(const VramContext& vramContext)
{
_appBarView->InitVram(vramContext);
ViewContainer::InitVram(vramContext);
const auto objVramManager = vramContext.GetObjVramManager();
if (objVramManager)
@@ -99,28 +99,13 @@ void RomBrowserAppBarView::InitVram(const VramContext& vramContext)
}
}
void RomBrowserAppBarView::Update()
{
_appBarView->Update();
}
void RomBrowserAppBarView::Draw(GraphicsContext& graphicsContext)
{
_appBarView->Draw(graphicsContext);
}
void RomBrowserAppBarView::VBlank()
{
_appBarView->VBlank();
}
SharedPtr<View> RomBrowserAppBarView::MoveFocus(const SharedPtr<View>& currentFocus, FocusMoveDirection direction, View* source)
{
if (!currentFocus)
{
return nullptr;
}
if (source == _appBarView.get())
if (source == _appBarView.GetPointer())
{
return View::MoveFocus(currentFocus, direction, source);
}
@@ -130,4 +115,3 @@ SharedPtr<View> RomBrowserAppBarView::MoveFocus(const SharedPtr<View>& currentFo
}
return nullptr;
}

View File

@@ -1,22 +1,17 @@
#pragma once
#include "gui/views/View.h"
#include "gui/views/ViewContainer.h"
#include "AppBarView.h"
#include "../viewModels/RomBrowserAppBarViewModel.h"
class RomBrowserDisplayMode;
class IRomBrowserViewFactory;
class RomBrowserAppBarView : public View
class RomBrowserAppBarView : public ViewContainer
{
public:
RomBrowserAppBarView(
RomBrowserAppBarViewModel* viewModel, const RomBrowserDisplayMode& displayMode,
const IRomBrowserViewFactory* romBrowserViewFactory);
SHARED_ONLY(RomBrowserAppBarView)
public:
void InitVram(const VramContext& vramContext) override;
void Update() override;
void Draw(GraphicsContext& graphicsContext) override;
void VBlank() override;
Rectangle GetBounds() const override
{
@@ -42,5 +37,9 @@ private:
};
RomBrowserAppBarViewModel* _viewModel;
std::unique_ptr<AppBarView> _appBarView;
SharedPtr<AppBarView> _appBarView;
RomBrowserAppBarView(
RomBrowserAppBarViewModel* viewModel, const RomBrowserDisplayMode& displayMode,
const IRomBrowserViewFactory* romBrowserViewFactory);
};

View File

@@ -21,37 +21,43 @@ RomBrowserBottomScreenView::RomBrowserBottomScreenView(
, _romBrowserViewFactory(romBrowserViewFactory)
, _romBrowserDisplayMode(displayMode)
, _themeFileIconFactory(themeFileIconFactory)
, _romBrowserAppBarView(_viewModel->GetRomBrowserAppBarViewModel(),
*displayMode, romBrowserViewFactory)
, _romBrowserAppBarView(RomBrowserAppBarView::CreateShared(_viewModel->GetRomBrowserAppBarViewModel(),
*displayMode, romBrowserViewFactory))
, _vblankTextureLoader(vblankTextureLoader)
{
_romBrowserAppBarView.SetParent(this);
_romBrowserAppBarView->SetParent(this);
}
void RomBrowserBottomScreenView::InitVram(const VramContext& vramContext)
{
_romBrowserAppBarView.InitVram(vramContext);
_romBrowserAppBarView->InitVram(vramContext);
}
void RomBrowserBottomScreenView::Update()
{
_romBrowserAppBarView.Update();
_romBrowserAppBarView->Update();
if (_romBrowserView && _viewModel->IsRomBrowserVisible())
{
_romBrowserView->Update();
}
}
void RomBrowserBottomScreenView::Draw(GraphicsContext& graphicsContext)
{
_romBrowserAppBarView.Draw(graphicsContext);
_romBrowserAppBarView->Draw(graphicsContext);
if (_romBrowserView && _viewModel->IsRomBrowserVisible())
{
_romBrowserView->Draw(graphicsContext);
}
}
void RomBrowserBottomScreenView::VBlank()
{
_romBrowserAppBarView.VBlank();
_romBrowserAppBarView->VBlank();
if (_romBrowserView && _viewModel->IsRomBrowserVisible())
{
_romBrowserView->VBlank();
}
}
SharedPtr<View> RomBrowserBottomScreenView::MoveFocus(const SharedPtr<View>& currentFocus, FocusMoveDirection direction, View* source)
@@ -60,31 +66,39 @@ SharedPtr<View> RomBrowserBottomScreenView::MoveFocus(const SharedPtr<View>& cur
{
return nullptr;
}
if (source == &_romBrowserAppBarView)
if (source == _romBrowserAppBarView.GetPointer())
{
if (_romBrowserDisplayMode->IsVertical())
{
if (direction == FocusMoveDirection::Right)
{
return _romBrowserView->MoveFocus(currentFocus, direction, this);
}
}
else
{
if (direction == FocusMoveDirection::Down)
{
return _romBrowserView->MoveFocus(currentFocus, direction, this);
}
}
return nullptr;
}
else if (source == _romBrowserView.get())
else if (source == _romBrowserView.GetPointer())
{
if (_romBrowserDisplayMode->IsVertical())
{
if (direction == FocusMoveDirection::Left)
return _romBrowserAppBarView.MoveFocus(currentFocus, direction, this);
{
return _romBrowserAppBarView->MoveFocus(currentFocus, direction, this);
}
}
else
{
if (direction == FocusMoveDirection::Up)
return _romBrowserAppBarView.MoveFocus(currentFocus, direction, this);
{
return _romBrowserAppBarView->MoveFocus(currentFocus, direction, this);
}
}
return nullptr;
}
@@ -101,11 +115,38 @@ bool RomBrowserBottomScreenView::HandleInput(const InputProvider& inputProvider,
return View::HandleInput(inputProvider, focusManager);
}
void RomBrowserBottomScreenView::HandlePenDown(const Point& touchPoint, FocusManager& focusManager)
{
_romBrowserAppBarView->HandlePenDown(touchPoint, focusManager);
if (_romBrowserView && _viewModel->IsRomBrowserVisible())
{
_romBrowserView->HandlePenDown(touchPoint, focusManager);
}
}
void RomBrowserBottomScreenView::HandlePenMove(const Point& touchPoint, FocusManager& focusManager)
{
_romBrowserAppBarView->HandlePenMove(touchPoint, focusManager);
if (_romBrowserView && _viewModel->IsRomBrowserVisible())
{
_romBrowserView->HandlePenMove(touchPoint, focusManager);
}
}
void RomBrowserBottomScreenView::HandlePenUp(const Point& lastTouchPoint, FocusManager& focusManager)
{
_romBrowserAppBarView->HandlePenUp(lastTouchPoint, focusManager);
if (_romBrowserView && _viewModel->IsRomBrowserVisible())
{
_romBrowserView->HandlePenUp(lastTouchPoint, focusManager);
}
}
void RomBrowserBottomScreenView::RomBrowserViewModelInvalidated(const VramContext& vramContext)
{
if (_viewModel->GetRomBrowserViewModel().IsValid())
{
_romBrowserView = std::make_unique<RomBrowserView>(
_romBrowserView = RomBrowserView::CreateShared(
_viewModel->GetRomBrowserViewModel(), *_romBrowserDisplayMode,
_themeFileIconFactory, _romBrowserViewFactory, _vblankTextureLoader);
_romBrowserView->SetParent(this);
@@ -113,6 +154,6 @@ void RomBrowserBottomScreenView::RomBrowserViewModelInvalidated(const VramContex
}
else
{
_romBrowserView.reset();
_romBrowserView.Reset();
}
}

View File

@@ -13,14 +13,9 @@ class VBlankTextureLoader;
class RomBrowserBottomScreenView : public View
{
public:
RomBrowserBottomScreenView(
RomBrowserBottomScreenViewModel* viewModel,
const RomBrowserDisplayMode* displayMode,
const IThemeFileIconFactory* themeFileIconFactory,
const IRomBrowserViewFactory* romBrowserViewFactory,
VBlankTextureLoader* vblankTextureLoader);
SHARED_ONLY(RomBrowserBottomScreenView)
public:
void InitVram(const VramContext& vramContext) override;
void Update() override;
void Draw(GraphicsContext& graphicsContext) override;
@@ -36,16 +31,21 @@ public:
void Focus(FocusManager& focusManager)
{
if (!_romBrowserView || !_romBrowserView->Focus(focusManager))
_romBrowserAppBarView.Focus(focusManager);
{
_romBrowserAppBarView->Focus(focusManager);
}
}
bool HandleInput(const InputProvider& inputProvider, FocusManager& focusManager) override;
void HandlePenDown(const Point& touchPoint, FocusManager& focusManager) override;
void HandlePenMove(const Point& touchPoint, FocusManager& focusManager) override;
void HandlePenUp(const Point& lastTouchPoint, FocusManager& focusManager) override;
void RomBrowserViewModelInvalidated(const VramContext& vramContext);
bool IsAppBarFocused(const FocusManager& focusManager) const
{
return focusManager.IsFocusInside(&_romBrowserAppBarView);
return focusManager.IsFocusInside(_romBrowserAppBarView.GetPointer());
}
private:
@@ -54,7 +54,14 @@ private:
const RomBrowserDisplayMode* _romBrowserDisplayMode;
const IThemeFileIconFactory* _themeFileIconFactory;
RomBrowserAppBarView _romBrowserAppBarView;
std::unique_ptr<RomBrowserView> _romBrowserView;
SharedPtr<RomBrowserAppBarView> _romBrowserAppBarView;
SharedPtr<RomBrowserView> _romBrowserView;
VBlankTextureLoader* _vblankTextureLoader;
RomBrowserBottomScreenView(
RomBrowserBottomScreenViewModel* viewModel,
const RomBrowserDisplayMode* displayMode,
const IThemeFileIconFactory* themeFileIconFactory,
const IRomBrowserViewFactory* romBrowserViewFactory,
VBlankTextureLoader* vblankTextureLoader);
};

View File

@@ -0,0 +1,76 @@
#include "common.h"
#include "gui/FocusManager.h"
#include "gui/input/InputProvider.h"
#include "gui/views/View.h"
#include "romBrowser/viewModels/RomBrowserItemViewModel.h"
#include "RomBrowserItemInputHandler.h"
#define LONG_PRESS_FRAMES 30
bool RomBrowserItemInputHandler::HandleInput(const InputProvider& inputProvider, FocusManager& focusManager)
{
if (inputProvider.Triggered(InputKey::A))
{
_viewModel->Activate();
return true;
}
else if (inputProvider.Triggered(InputKey::Y))
{
_viewModel->ShowGameInfo();
return true;
}
else
{
return false;
}
}
void RomBrowserItemInputHandler::HandlePenDown(const Point& touchPoint, FocusManager& focusManager)
{
if (_view->GetBounds().Contains(touchPoint))
{
_penDown = true;
_penDownFrames = 0;
}
}
void RomBrowserItemInputHandler::HandlePenMove(const Point& touchPoint, FocusManager& focusManager)
{
if (_penDown && _view->GetBounds().Contains(touchPoint))
{
if (++_penDownFrames == LONG_PRESS_FRAMES)
{
// Long press
if (focusManager.GetCurrentFocus().GetPointer() != _view)
{
focusManager.Focus(_view->SharedFromThis());
}
_viewModel->ShowGameInfo();
_penDown = false; // pen action is complete
}
}
else
{
_penDown = false;
}
}
void RomBrowserItemInputHandler::HandlePenUp(const Point& lastTouchPoint, FocusManager& focusManager)
{
if (_penDown && _view->GetBounds().Contains(lastTouchPoint))
{
// Short tap
if (focusManager.GetCurrentFocus().GetPointer() == _view)
{
_viewModel->Activate();
}
else
{
focusManager.Focus(_view->SharedFromThis());
}
}
_penDown = false;
}

View File

@@ -0,0 +1,27 @@
#pragma once
#include "core/math/Point.h"
class InputProvider;
class FocusManager;
class RomBrowserItemViewModel;
class View;
class RomBrowserItemInputHandler
{
public:
RomBrowserItemInputHandler(View* view, RomBrowserItemViewModel* viewModel)
: _view(view), _viewModel(viewModel) { }
bool HandleInput(const InputProvider& inputProvider, FocusManager& focusManager);
void HandlePenDown(const Point& touchPoint, FocusManager& focusManager);
void HandlePenMove(const Point& touchPoint, FocusManager& focusManager);
void HandlePenUp(const Point& lastTouchPoint, FocusManager& focusManager);
bool IsPenDown() const { return _penDown; }
private:
View* _view;
RomBrowserItemViewModel* _viewModel;
bool _penDown = false;
int _penDownFrames = 0;
};

View File

@@ -22,7 +22,7 @@ RomBrowserTopScreenView::RomBrowserTopScreenView(
, _showCover(displayMode->ShowCoverOnTopScreen())
, _coverPosition(romBrowserViewFactory->GetTopCoverPosition())
{
AddChildTail(_fileInfoView.get());
AddChildTail(_fileInfoView.GetPointer());
}
void RomBrowserTopScreenView::InitVram(const VramContext& vramContext)

View File

@@ -11,12 +11,9 @@ class IRomBrowserViewFactory;
class RomBrowserTopScreenView : public ViewContainer
{
public:
RomBrowserTopScreenView(SharedPtr<RomBrowserViewModel> viewModel,
const RomBrowserDisplayMode* displayMode,
const IThemeFileIconFactory* themeFileIconFactory,
const IRomBrowserViewFactory* romBrowserViewFactory);
SHARED_ONLY(RomBrowserTopScreenView)
public:
void InitVram(const VramContext& vramContext) override;
void Update() override;
void VBlank() override;
@@ -29,7 +26,7 @@ public:
private:
SharedPtr<RomBrowserViewModel> _viewModel;
const IThemeFileIconFactory* _themeFileIconFactory;
std::unique_ptr<BannerView> _fileInfoView;
SharedPtr<BannerView> _fileInfoView;
std::unique_ptr<FileIcon> _selectedFileIcon;
SharedPtr<FileCover> _selectedFileCover;
int _lastSelectedItem = -1;
@@ -37,4 +34,9 @@ private:
bool _coverGraphicsUploaded = false;
bool _showCover;
Point _coverPosition;
RomBrowserTopScreenView(SharedPtr<RomBrowserViewModel> viewModel,
const RomBrowserDisplayMode* displayMode,
const IThemeFileIconFactory* themeFileIconFactory,
const IRomBrowserViewFactory* romBrowserViewFactory);
};

View File

@@ -13,7 +13,7 @@ RomBrowserView::RomBrowserView(
: _viewModel(std::move(viewModel)), _isVertical(displayMode.IsVertical())
{
_fileGridView = displayMode.CreateRecyclerView(romBrowserViewFactory);
_fileGridView->SetParent(this);
AddChildTail(_fileGridView.GetPointer());
_fileRecyclerAdapter = displayMode.CreateRecyclerAdapter(
_viewModel.GetPointer(), themeFileIconFactory, romBrowserViewFactory, vblankTextureLoader);
}
@@ -32,16 +32,6 @@ void RomBrowserView::Update()
_viewModel->SetSelectedItem(_fileGridView->GetSelectedItem());
}
void RomBrowserView::Draw(GraphicsContext& graphicsContext)
{
_fileGridView->Draw(graphicsContext);
}
void RomBrowserView::VBlank()
{
_fileGridView->VBlank();
}
SharedPtr<View> RomBrowserView::MoveFocus(const SharedPtr<View>& currentFocus, FocusMoveDirection direction, View* source)
{
if (!currentFocus)
@@ -72,24 +62,3 @@ SharedPtr<View> RomBrowserView::MoveFocus(const SharedPtr<View>& currentFocus, F
}
return nullptr;
}
bool RomBrowserView::HandleInput(const InputProvider& inputProvider, FocusManager& focusManager)
{
if (inputProvider.Triggered(InputKey::A))
{
if (focusManager.IsFocusInside(_fileGridView.GetPointer()))
{
_viewModel->ItemActivated();
return true;
}
}
else if (inputProvider.Triggered(InputKey::Y))
{
if (focusManager.IsFocusInside(_fileGridView.GetPointer()))
{
_viewModel->ShowGameInfo();
return true;
}
}
return View::HandleInput(inputProvider, focusManager);
}

View File

@@ -9,20 +9,13 @@
class IRomBrowserViewFactory;
class RomBrowserView : public View
class RomBrowserView : public ViewContainer
{
public:
RomBrowserView(
SharedPtr<RomBrowserViewModel> viewModel,
const RomBrowserDisplayMode& displayMode,
const IThemeFileIconFactory* themeFileIconFactory,
const IRomBrowserViewFactory* romBrowserViewFactory,
VBlankTextureLoader* vblankTextureLoader);
SHARED_ONLY(RomBrowserView)
public:
void InitVram(const VramContext& vramContext) override;
void Update() override;
void Draw(GraphicsContext& graphicsContext) override;
void VBlank() override;
Rectangle GetBounds() const override
{
@@ -41,11 +34,16 @@ public:
SharedPtr<View> MoveFocus(
const SharedPtr<View>& currentFocus, FocusMoveDirection direction, View* source) override;
bool HandleInput(const InputProvider& inputProvider, FocusManager& focusManager) override;
private:
SharedPtr<RomBrowserViewModel> _viewModel;
SharedPtr<RecyclerViewBase> _fileGridView;
SharedPtr<FileRecyclerAdapter> _fileRecyclerAdapter;
bool _isVertical;
RomBrowserView(
SharedPtr<RomBrowserViewModel> viewModel,
const RomBrowserDisplayMode& displayMode,
const IThemeFileIconFactory* themeFileIconFactory,
const IRomBrowserViewFactory* romBrowserViewFactory,
VBlankTextureLoader* vblankTextureLoader);
};

View File

@@ -4,6 +4,7 @@
#include "gui/palette/GradientPalette.h"
#include "gui/GraphicsContext.h"
#include "gui/OamBuilder.h"
#include "gui/input/InputProvider.h"
#include "CheatListItemView.h"
#define ICON_X 4
@@ -12,19 +13,20 @@
#define NAME_LABEL_X 24
#define NAME_LABEL_Y 5
CheatListItemView::CheatListItemView(const VramOffsets& vramOffsets,
CheatListItemView::CheatListItemView(SharedPtr<CheatsViewModel> viewModel, const VramOffsets& vramOffsets,
const MaterialColorScheme* materialColorScheme, const IFontRepository* fontRepository)
: _nameLabel(196, 16, 256, fontRepository->GetFont(FontType::Regular10))
: _viewModel(std::move(viewModel))
, _nameLabel(Label2DView::CreateShared(196, 16, 256, fontRepository->GetFont(FontType::Regular10)))
, _vramOffsets(vramOffsets)
, _materialColorScheme(materialColorScheme)
{
_nameLabel.SetEllipsisStyle(LabelView::EllipsisStyle::Ellipsis);
AddChildTail(&_nameLabel);
_nameLabel->SetEllipsisStyle(LabelView::EllipsisStyle::Ellipsis);
AddChildTail(_nameLabel.GetPointer());
}
void CheatListItemView::Update()
{
_nameLabel.SetPosition(_position.x + NAME_LABEL_X, _position.y + NAME_LABEL_Y);
_nameLabel->SetPosition(_position.x + NAME_LABEL_X, _position.y + NAME_LABEL_Y);
if (_cheatEntry != nullptr && !_cheatEntry->IsCheatCategory())
{
_iconVramOffset = _cheatEntry->GetIsCheatActive()
@@ -33,11 +35,11 @@ void CheatListItemView::Update()
}
if (IsFocused())
{
_nameLabel.SetEllipsisStyle(LabelView::EllipsisStyle::Marquee);
_nameLabel->SetEllipsisStyle(LabelView::EllipsisStyle::Marquee);
}
else
{
_nameLabel.SetEllipsisStyle(LabelView::EllipsisStyle::Ellipsis);
_nameLabel->SetEllipsisStyle(LabelView::EllipsisStyle::Ellipsis);
}
ViewContainer::Update();
}
@@ -56,8 +58,8 @@ void CheatListItemView::Draw(GraphicsContext& graphicsContext)
backColor = RgbMixer::Lerp(backColor, selectorFullColor, 10, 100);
}
_nameLabel.SetBackgroundColor(backColor);
_nameLabel.SetForegroundColor(_materialColorScheme->onSurface);
_nameLabel->SetBackgroundColor(backColor);
_nameLabel->SetForegroundColor(_materialColorScheme->onSurface);
if (IsFocused())
{
@@ -97,3 +99,55 @@ void CheatListItemView::Draw(GraphicsContext& graphicsContext)
.Build(iconOam[0]);
}
}
bool CheatListItemView::HandleInput(const InputProvider& inputProvider, FocusManager& focusManager)
{
if (inputProvider.Triggered(InputKey::A))
{
_viewModel->ActivateItem(_index);
return true;
}
return ViewContainer::HandleInput(inputProvider, focusManager);
}
void CheatListItemView::HandlePenDown(const Point& touchPoint, FocusManager& focusManager)
{
if (GetBounds().Contains(touchPoint))
{
_penDown = true;
}
}
void CheatListItemView::HandlePenMove(const Point& touchPoint, FocusManager& focusManager)
{
if (!GetBounds().Contains(touchPoint))
{
_penDown = false;
}
}
void CheatListItemView::HandlePenUp(const Point& lastTouchPoint, FocusManager& focusManager)
{
if (_penDown && GetBounds().Contains(lastTouchPoint))
{
if (lastTouchPoint.x - _position.x < 24)
{
focusManager.Focus(SharedFromThis());
_viewModel->ActivateItem(_index);
}
else
{
if (focusManager.GetCurrentFocus().GetPointer() == this)
{
_viewModel->ActivateItem(_index);
}
else
{
focusManager.Focus(SharedFromThis());
}
}
}
_penDown = false;
}

View File

@@ -2,6 +2,7 @@
#include "gui/views/ViewContainer.h"
#include "gui/views/Label2DView.h"
#include "cheats/CheatEntry.h"
#include "romBrowser/viewModels/CheatsViewModel.h"
class MaterialColorScheme;
class IFontRepository;
@@ -9,6 +10,8 @@ class IFontRepository;
/// @brief List item view for the cheats panel, representing a single cheat or cheat category.
class CheatListItemView : public ViewContainer
{
SHARED_ONLY(CheatListItemView)
public:
struct VramOffsets
{
@@ -18,10 +21,12 @@ public:
u32 cheatSelectorVramOffset = 0;
};
CheatListItemView(const VramOffsets& vramOffsets, const MaterialColorScheme* materialColorScheme, const IFontRepository* fontRepository);
void Update() override;
void Draw(GraphicsContext& graphicsContext) override;
bool HandleInput(const InputProvider& inputProvider, FocusManager& focusManager) override;
void HandlePenDown(const Point& touchPoint, FocusManager& focusManager) override;
void HandlePenMove(const Point& touchPoint, FocusManager& focusManager) override;
void HandlePenUp(const Point& lastTouchPoint, FocusManager& focusManager) override;
Rectangle GetBounds() const override
{
@@ -30,13 +35,14 @@ public:
void SetName(const char* name)
{
_nameLabel.SetText(name);
_nameLabel->SetText(name);
}
void SetEntry(const CheatEntry* cheatEntry)
void SetEntry(const CheatEntry* cheatEntry, int index)
{
_cheatEntry = cheatEntry;
_nameLabel.SetText(cheatEntry->GetName());
_index = index;
_nameLabel->SetText(cheatEntry->GetName());
if (cheatEntry->IsCheatCategory())
{
_iconVramOffset = _vramOffsets.folderIconVramOffset;
@@ -44,9 +50,15 @@ public:
}
private:
Label2DView _nameLabel;
SharedPtr<CheatsViewModel> _viewModel;
SharedPtr<Label2DView> _nameLabel;
VramOffsets _vramOffsets;
const MaterialColorScheme* _materialColorScheme;
u32 _iconVramOffset = 0;
const CheatEntry* _cheatEntry = nullptr;
int _index = -1;
bool _penDown = false;
CheatListItemView(SharedPtr<CheatsViewModel> viewModel, const VramOffsets& vramOffsets,
const MaterialColorScheme* materialColorScheme, const IFontRepository* fontRepository);
};

View File

@@ -7,9 +7,10 @@
class CheatsAdapter : public RecyclerAdapter
{
public:
CheatsAdapter(const CheatEntry* cheatCategory, const MaterialColorScheme* materialColorScheme,
const IFontRepository* fontRepository, const CheatListItemView::VramOffsets& vramOffsets)
: _cheatCategory(cheatCategory), _materialColorScheme(materialColorScheme)
CheatsAdapter(const CheatEntry* cheatCategory, SharedPtr<CheatsViewModel> cheatsViewModel,
const MaterialColorScheme* materialColorScheme, const IFontRepository* fontRepository,
const CheatListItemView::VramOffsets& vramOffsets)
: _cheatCategory(cheatCategory), _cheatsViewModel(std::move(cheatsViewModel)), _materialColorScheme(materialColorScheme)
, _fontRepository(fontRepository), _vramOffsets(vramOffsets) { }
u32 GetItemCount() const override
@@ -27,7 +28,7 @@ public:
SharedPtr<View> CreateView() const override
{
return SharedPtr<CheatListItemView>::MakeShared(_vramOffsets, _materialColorScheme, _fontRepository);
return CheatListItemView::CreateShared(_cheatsViewModel, _vramOffsets, _materialColorScheme, _fontRepository);
}
void BindView(SharedPtr<View> view, int index) const override
@@ -35,7 +36,7 @@ public:
auto listItemView = static_cast<CheatListItemView*>(view.GetPointer());
u32 numberOfSubEntries = 0;
auto subEntries = _cheatCategory->GetSubEntries(numberOfSubEntries);
listItemView->SetEntry(&subEntries[index]);
listItemView->SetEntry(&subEntries[index], index);
}
void ReleaseView(SharedPtr<View> view, int index) const override
@@ -45,6 +46,7 @@ public:
private:
const CheatEntry* _cheatCategory;
SharedPtr<CheatsViewModel> _cheatsViewModel;
const MaterialColorScheme* _materialColorScheme;
const IFontRepository* _fontRepository;
CheatListItemView::VramOffsets _vramOffsets;

View File

@@ -7,6 +7,7 @@
#include "gui/palette/GradientPalette.h"
#include "gui/OamBuilder.h"
#include "folderIcon.h"
#include "upIcon.h"
#include "checkboxChecked.h"
#include "checkboxUnchecked.h"
#include "cheatSelector.h"
@@ -30,28 +31,37 @@
#define LIST_WIDTH 224
#define LIST_HEIGHT 108
CheatsBottomSheetView::CheatsBottomSheetView(std::unique_ptr<CheatsViewModel> viewModel,
CheatsBottomSheetView::CheatsBottomSheetView(SharedPtr<CheatsViewModel> viewModel,
const MaterialColorScheme* materialColorScheme, const IFontRepository* fontRepository,
FocusManager* focusManager)
: _viewModel(std::move(viewModel))
, _titleLabel(64, 16, 25, fontRepository->GetFont(FontType::Medium11))
, _secondaryLabel(177, 16, 64, fontRepository->GetFont(FontType::Regular10))
, _descriptionLabel(224, 16, 256, fontRepository->GetFont(FontType::Medium7_5))
, _titleLabel(Label2DView::CreateShared(64, 16, 25, fontRepository->GetFont(FontType::Medium11)))
, _secondaryLabel(Label2DView::CreateShared(153, 16, 64, fontRepository->GetFont(FontType::Regular10)))
, _descriptionLabel(Label2DView::CreateShared(224, 16, 256, fontRepository->GetFont(FontType::Medium7_5)))
, _cheatListRecycler(RecyclerView::CreateShared(
LIST_X, LIST_Y, LIST_WIDTH, LIST_HEIGHT, RecyclerView::Mode::VerticalList))
, _upButton(IconButton2DView::CreateShared(
IconButtonView::Type::Standard,
IconButtonView::State::NoToggle,
md::sys::color::inverseOnSurface,
materialColorScheme))
, _materialColorScheme(materialColorScheme)
, _fontRepository(fontRepository)
, _focusManager(focusManager)
{
_titleLabel.SetText(u"Cheats");
_secondaryLabel.SetText(u"No cheats found.");
_secondaryLabel.SetEllipsisStyle(LabelView::EllipsisStyle::Ellipsis);
_descriptionLabel.SetEllipsisStyle(LabelView::EllipsisStyle::Marquee);
_descriptionLabel.SetText("");
AddChildTail(&_titleLabel);
AddChildTail(&_secondaryLabel);
AddChildTail(&_descriptionLabel);
_titleLabel->SetText(u"Cheats");
_secondaryLabel->SetText(u"No cheats found.");
_secondaryLabel->SetEllipsisStyle(LabelView::EllipsisStyle::Ellipsis);
_descriptionLabel->SetEllipsisStyle(LabelView::EllipsisStyle::Marquee);
_descriptionLabel->SetText(u"");
AddChildTail(_titleLabel.GetPointer());
AddChildTail(_secondaryLabel.GetPointer());
AddChildTail(_descriptionLabel.GetPointer());
AddChildTail(_cheatListRecycler.GetPointer());
_upButton->SetAction([] (IconButtonView*, void* arg)
{
((CheatsBottomSheetView*)arg)->_viewModel->NavigateUp();
}, this);
}
void CheatsBottomSheetView::InitVram(const VramContext& vramContext)
@@ -61,21 +71,17 @@ void CheatsBottomSheetView::InitVram(const VramContext& vramContext)
const auto objVramManager = vramContext.GetObjVramManager();
if (objVramManager)
{
_vramOffsets.folderIconVramOffset = objVramManager->Alloc(folderIconTilesLen);
dma_ntrCopy32(3, folderIconTiles,
objVramManager->GetVramAddress(_vramOffsets.folderIconVramOffset), folderIconTilesLen);
_vramOffsets.checkboxUncheckedIconVramOffset = objVramManager->Alloc(checkboxUncheckedTilesLen);
dma_ntrCopy32(3, checkboxUncheckedTiles,
objVramManager->GetVramAddress(_vramOffsets.checkboxUncheckedIconVramOffset), checkboxUncheckedTilesLen);
_vramOffsets.checkboxCheckedIconVramOffset = objVramManager->Alloc(checkboxCheckedTilesLen);
dma_ntrCopy32(3, checkboxCheckedTiles,
objVramManager->GetVramAddress(_vramOffsets.checkboxCheckedIconVramOffset), checkboxCheckedTilesLen);
_vramOffsets.cheatSelectorVramOffset = objVramManager->Alloc(cheatSelectorTilesLen);
dma_ntrCopy32(3, cheatSelectorTiles,
objVramManager->GetVramAddress(_vramOffsets.cheatSelectorVramOffset), cheatSelectorTilesLen);
_vramOffsets.folderIconVramOffset
= LoadSprite(*objVramManager, folderIconTiles, folderIconTilesLen);
_vramOffsets.checkboxUncheckedIconVramOffset
= LoadSprite(*objVramManager, checkboxUncheckedTiles, checkboxUncheckedTilesLen);
_vramOffsets.checkboxCheckedIconVramOffset
= LoadSprite(*objVramManager, checkboxCheckedTiles, checkboxCheckedTilesLen);
_vramOffsets.cheatSelectorVramOffset
= LoadSprite(*objVramManager, cheatSelectorTiles, cheatSelectorTilesLen);
auto iconButtonVramToken = IconButton2DView::UploadGraphics(*objVramManager);
_upButton->SetGraphics(iconButtonVramToken);
_upButton->SetIconVramOffset(LoadSprite(*objVramManager, upIconTiles, upIconTilesLen));
}
_objVramManager = vramContext.GetObjVramManager();
@@ -83,23 +89,34 @@ void CheatsBottomSheetView::InitVram(const VramContext& vramContext)
void CheatsBottomSheetView::Update()
{
_titleLabel.SetPosition(TITLE_LABEL_X, _position.y + TITLE_LABEL_Y);
if (_upButton->GetParent() == nullptr && _viewModel->IsInSubCategory())
{
AddChildTail(_upButton.GetPointer());
}
else if (_upButton->GetParent() != nullptr && !_viewModel->IsInSubCategory())
{
RemoveChild(_upButton.GetPointer());
}
_titleLabel->SetPosition(TITLE_LABEL_X, _position.y + TITLE_LABEL_Y);
if (_viewModel->GetState() == CheatsViewModel::State::DisplayCheats)
{
_secondaryLabel.SetPosition(CATEGORY_NAME_LABEL_X, _position.y + CATEGORY_NAME_LABEL_Y);
_secondaryLabel->SetPosition(CATEGORY_NAME_LABEL_X, _position.y + CATEGORY_NAME_LABEL_Y);
}
else
{
_secondaryLabel.SetPosition(NO_CHEATS_FOUND_LABEL_X, _position.y + NO_CHEATS_FOUND_LABEL_Y);
_secondaryLabel->SetPosition(NO_CHEATS_FOUND_LABEL_X, _position.y + NO_CHEATS_FOUND_LABEL_Y);
}
_descriptionLabel.SetPosition(DESCRIPTION_LABEL_X, _position.y + DESCRIPTION_LABEL_Y);
_descriptionLabel->SetPosition(DESCRIPTION_LABEL_X, _position.y + DESCRIPTION_LABEL_Y);
_cheatListRecycler->SetPosition(LIST_X, _position.y + LIST_Y);
_upButton->SetPosition(212, _position.y + CATEGORY_NAME_LABEL_Y - 8);
if (_viewModel->GetState() == CheatsViewModel::State::DisplayCheats)
{
if (!_cheatsAdapter && _objVramManager != nullptr)
{
_currentCheatCategory = _viewModel->GetCurrentCheatCategory();
_cheatsAdapter = SharedPtr<CheatsAdapter>::MakeShared(
_viewModel->GetCurrentCheatCategory(), _materialColorScheme, _fontRepository, _vramOffsets);
_currentCheatCategory, _viewModel, _materialColorScheme, _fontRepository, _vramOffsets);
_cheatListRecycler->SetAdapter(_cheatsAdapter);
// Ugly hack
@@ -108,6 +125,12 @@ void CheatsBottomSheetView::Update()
_cheatListRecycler->InitVram(VramContext(nullptr, _objVramManager, nullptr, nullptr));
_cheatListRecycler->Focus(*_focusManager);
}
else if (_currentCheatCategory != _viewModel->GetCurrentCheatCategory()
&& _viewModel->GetCurrentCheatCategory() != nullptr)
{
// _secondaryLabel->SetText(_viewModel->GetCurrentCheatCategory()->GetName());
UpdateCheatList();
}
}
BottomSheetView::Update();
int selectedItem = _cheatListRecycler->GetSelectedItem();
@@ -175,21 +198,26 @@ void CheatsBottomSheetView::Draw(GraphicsContext& graphicsContext)
.Build(maskOam[7]);
}
_titleLabel.SetBackgroundColor(backColor);
_titleLabel.SetForegroundColor(_materialColorScheme->onSurface);
_titleLabel.Draw(graphicsContext);
_titleLabel->SetBackgroundColor(backColor);
_titleLabel->SetForegroundColor(_materialColorScheme->onSurface);
_titleLabel->Draw(graphicsContext);
if (_viewModel->GetState() == CheatsViewModel::State::NoCheats ||
_viewModel->ShouldShowCategoryName())
_viewModel->IsInSubCategory())
{
_secondaryLabel.SetBackgroundColor(backColor);
_secondaryLabel.SetForegroundColor(_materialColorScheme->onSurfaceVariant);
_secondaryLabel.Draw(graphicsContext);
_secondaryLabel->SetBackgroundColor(backColor);
_secondaryLabel->SetForegroundColor(_materialColorScheme->onSurfaceVariant);
_secondaryLabel->Draw(graphicsContext);
}
_descriptionLabel.SetBackgroundColor(backColor);
_descriptionLabel.SetForegroundColor(_materialColorScheme->onSurfaceVariant);
_descriptionLabel.Draw(graphicsContext);
_descriptionLabel->SetBackgroundColor(backColor);
_descriptionLabel->SetForegroundColor(_materialColorScheme->onSurfaceVariant);
_descriptionLabel->Draw(graphicsContext);
if (_viewModel->IsInSubCategory())
{
_upButton->Draw(graphicsContext);
}
}
graphicsContext.SetPriority(oldPrio);
graphicsContext.ResetClipArea();
@@ -197,29 +225,9 @@ void CheatsBottomSheetView::Draw(GraphicsContext& graphicsContext)
bool CheatsBottomSheetView::HandleInput(const InputProvider& inputProvider, FocusManager& focusManager)
{
if (inputProvider.Triggered(InputKey::A))
if (inputProvider.Triggered(InputKey::B))
{
if (focusManager.IsFocusInside(_cheatListRecycler.GetPointer()))
{
auto oldCategory = _viewModel->GetCurrentCheatCategory();
_viewModel->ActivateSelectedItem();
if (oldCategory != _viewModel->GetCurrentCheatCategory())
{
_secondaryLabel.SetText(_viewModel->GetCurrentCheatCategory()->GetName());
UpdateCheatList();
}
return true;
}
}
else if (inputProvider.Triggered(InputKey::B))
{
auto oldCategory = _viewModel->GetCurrentCheatCategory();
if (_viewModel->NavigateUp() &&
oldCategory != _viewModel->GetCurrentCheatCategory())
{
UpdateCheatList();
}
_viewModel->NavigateUp();
return true;
}
else if (inputProvider.Triggered(InputKey::Y))
@@ -235,13 +243,16 @@ bool CheatsBottomSheetView::HandleInput(const InputProvider& inputProvider, Focu
return false;
}
void CheatsBottomSheetView::Close()
{
_viewModel->Close();
}
void CheatsBottomSheetView::UpdateCheatList()
{
// Need to unfocus first, otherwise the focus manager still contains a pointer to a view that is going to be destroyed
_focusManager->Unfocus();
_currentCheatCategory = _viewModel->GetCurrentCheatCategory();
_cheatsAdapter = SharedPtr<CheatsAdapter>::MakeShared(
_viewModel->GetCurrentCheatCategory(), _materialColorScheme, _fontRepository, _vramOffsets);
_currentCheatCategory, _viewModel, _materialColorScheme, _fontRepository, _vramOffsets);
_cheatListRecycler->SetAdapter(_cheatsAdapter, _viewModel->GetSelectedItem());
// Ugly hack
@@ -257,13 +268,20 @@ void CheatsBottomSheetView::UpdateDescriptionText()
int selectedItem = _viewModel->GetSelectedItem();
if (selectedItem < 0)
{
_descriptionLabel.SetText("");
_descriptionLabel->SetText("");
}
else
{
auto cheatCategory = _viewModel->GetCurrentCheatCategory();
u32 numberOfSubEntries = 0;
auto subEntries = cheatCategory->GetSubEntries(numberOfSubEntries);
_descriptionLabel.SetText(subEntries[selectedItem].GetDescription());
_descriptionLabel->SetText(subEntries[selectedItem].GetDescription());
}
}
u32 CheatsBottomSheetView::LoadSprite(IVramManager& vramManager, const unsigned int* tiles, u32 tilesLength) const
{
u32 vramOffset = vramManager.Alloc(tilesLength);
dma_ntrCopy32(3, tiles, vramManager.GetVramAddress(vramOffset), tilesLength);
return vramOffset;
}

View File

@@ -7,6 +7,7 @@
#include "romBrowser/viewModels/CheatsViewModel.h"
#include "CheatsAdapter.h"
#include "CheatListItemView.h"
#include "romBrowser/views/IconButton2DView.h"
class MaterialColorScheme;
class IFontRepository;
@@ -15,11 +16,9 @@ class IVramManager;
/// @brief Bottom sheet for browsing and enabling/disabling cheats.
class CheatsBottomSheetView : public BottomSheetView
{
public:
CheatsBottomSheetView(std::unique_ptr<CheatsViewModel> viewModel,
const MaterialColorScheme* materialColorScheme, const IFontRepository* fontRepository,
FocusManager* focusManager);
SHARED_ONLY(CheatsBottomSheetView)
public:
void InitVram(const VramContext& vramContext) override;
void Update() override;
void Draw(GraphicsContext& graphicsContext) override;
@@ -30,20 +29,30 @@ public:
_cheatListRecycler->Focus(focusManager);
}
protected:
void Close() override;
private:
std::unique_ptr<CheatsViewModel> _viewModel;
Label2DView _titleLabel;
Label2DView _secondaryLabel;
Label2DView _descriptionLabel;
SharedPtr<CheatsViewModel> _viewModel;
SharedPtr<Label2DView> _titleLabel;
SharedPtr<Label2DView> _secondaryLabel;
SharedPtr<Label2DView> _descriptionLabel;
SharedPtr<RecyclerView> _cheatListRecycler;
SharedPtr<CheatsAdapter> _cheatsAdapter;
SharedPtr<IconButton2DView> _upButton;
const MaterialColorScheme* _materialColorScheme;
const IFontRepository* _fontRepository;
IVramManager* _objVramManager = nullptr;
FocusManager* _focusManager;
CheatListItemView::VramOffsets _vramOffsets;
u32 _savedVramState = 0;
const CheatEntry* _currentCheatCategory = nullptr;
CheatsBottomSheetView(SharedPtr<CheatsViewModel> viewModel,
const MaterialColorScheme* materialColorScheme, const IFontRepository* fontRepository,
FocusManager* focusManager);
void UpdateCheatList();
void UpdateDescriptionText();
u32 LoadSprite(IVramManager& vramManager, const unsigned int* tiles, u32 tilesLength) const;
};