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

@@ -10,6 +10,8 @@
#include "romBrowser/FileType/FileCover.h"
#include "core/math/SinTable.h"
#include "carouselMask.h"
#include "animation/Interpolator.h"
#include "gui/input/InputProvider.h"
#include "CarouselRecyclerView.h"
#define COVER_SPACING 4
@@ -41,8 +43,10 @@ void CarouselRecyclerView::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);
@@ -66,8 +70,7 @@ void CarouselRecyclerView::Update()
for (u32 i = _viewPoolFreeCount; i < _viewPool.size(); i++)
{
_viewPoolEx[i].xPositionAnimator.Update();
_viewPoolEx[i].widthAnimator.Update();
UpdateItemPosition(i);
_viewPool[i].view->Update();
}
}
@@ -76,8 +79,8 @@ void CarouselRecyclerView::Draw(GraphicsContext& graphicsContext)
{
for (u32 i = _viewPoolFreeCount; i < _viewPool.size(); i++)
{
fix32<12> x = (_viewPoolEx[i].xPositionAnimator.GetValue() + 0.5).Int();
fix32<12> width = (_viewPoolEx[i].widthAnimator.GetValue() + 0.5).Int();
fix32<12> x = (_viewPoolEx[i].xPosition + 0.5).Int();
fix32<12> width = (_viewPoolEx[i].width + 0.5).Int();
fix32<12> left = x;
if (left < HORIZONTAL_PADDING)
{
@@ -180,48 +183,179 @@ void CarouselRecyclerView::RenderRoundedCorners(GraphicsContext& graphicsContext
Gx::End();
}
void CarouselRecyclerView::UpdateItemPosition(int viewPoolIndex, bool initial)
bool CarouselRecyclerView::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> width;
if (itemIndex < selectedIndex)
return View::HandleInput(inputProvider, focusManager);
}
void CarouselRecyclerView::HandlePenDown(const Point& touchPoint, FocusManager& focusManager)
{
if (GetBounds().Contains(touchPoint))
{
x = SELECTED_COVER_X + (SMALL_COVER_WIDTH + COVER_SPACING) * (itemIndex - selectedIndex);
width = SMALL_COVER_WIDTH;
_penDown = true;
_penDownPosition = touchPoint;
_hasScrollStarted = false;
_penDownScrollOffset = _scrollAnimator.GetValue();
if (_itemCount > 0)
{
_selectedItem->view->HandlePenDown(touchPoint, focusManager);
}
for (u32 i = _viewPoolFreeCount; i < _viewPool.size(); i++)
{
auto bounds = _viewPool[i].view->GetBounds();
bounds = Rectangle(_viewPoolEx[i].xPosition.Int(), bounds.GetTop(), _viewPoolEx[i].width.Int(), bounds.GetHeight());
if (bounds.Contains(touchPoint))
{
_viewPool[i].view->HandlePenDown(touchPoint, focusManager);
}
}
}
else if (itemIndex == selectedIndex + 1)
}
void CarouselRecyclerView::HandlePenMove(const Point& touchPoint, FocusManager& focusManager)
{
if (!_penDown)
{
x = NEXT_COVER_X;
width = NEXT_COVER_WIDTH;
return;
}
else if (itemIndex > selectedIndex + 1)
if (!_hasScrollStarted)
{
x = NEXT_COVER_X + NEXT_COVER_WIDTH + COVER_SPACING
+ (SMALL_COVER_WIDTH + COVER_SPACING) * (itemIndex - selectedIndex - 2);
width = SMALL_COVER_WIDTH;
for (u32 i = _viewPoolFreeCount; i < _viewPool.size(); i++)
{
_viewPool[i].view->HandlePenMove(touchPoint, focusManager);
if (focusManager.GetCurrentFocus().GetPointer() == _viewPool[i].view.GetPointer())
{
SetSelectedItem(_viewPool[i].itemIdx, false);
}
}
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
}
for (u32 i = _viewPoolFreeCount; i < _viewPool.size(); i++)
{
_viewPool[i].view->HandlePenUp(Point(-1, -1), focusManager);
}
}
}
else
{
x = SELECTED_COVER_X;
width = SELECTED_COVER_WIDTH;
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 CarouselRecyclerView::HandlePenUp(const Point& lastTouchPoint, FocusManager& focusManager)
{
if (_hasScrollStarted)
{
SetSelectedItem((_scrollAnimator.GetValue() + 0.5).Int(), false);
focusManager.Focus(_selectedItem->view);
}
for (u32 i = _viewPoolFreeCount; i < _viewPool.size(); i++)
{
_viewPool[i].view->HandlePenUp(lastTouchPoint, focusManager);
if (focusManager.GetCurrentFocus().GetPointer() == _viewPool[i].view.GetPointer())
{
SetSelectedItem(_viewPool[i].itemIdx, false);
}
}
_penDown = false;
}
void CarouselRecyclerView::SetSelectedItem(int itemIdx, bool initial)
{
CoverFlowRecyclerViewBase::SetSelectedItem(itemIdx, initial);
if (itemIdx < 0 || itemIdx >= (int)_itemCount)
{
return;
}
if (initial)
{
itemEx->xPositionAnimator = Animator(x);
itemEx->widthAnimator = Animator(width);
_scrollAnimator = Animator<fix32<12>>(itemIdx);
}
else
{
itemEx->xPositionAnimator.Goto(x, md::sys::motion::duration::medium4, &md::sys::motion::easing::standard);
itemEx->widthAnimator.Goto(width, md::sys::motion::duration::medium4, &md::sys::motion::easing::standard);
_scrollAnimator.Goto(itemIdx, md::sys::motion::duration::medium4, &md::sys::motion::easing::standard);
}
}
void CarouselRecyclerView::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> initialOffsetFromNext = (absOffsetFromCenter - 1).Clamp(0, 1);
fix32<12> x;
fix32<12> width;
if (itemIndex < _scrollAnimator.GetValue())
{
// everything before selected
x = SELECTED_COVER_X - (SMALL_COVER_WIDTH + COVER_SPACING) * absOffsetFromCenter;
width = Interpolator::InterpolateLinear<fix32<12>>(SELECTED_COVER_WIDTH, SMALL_COVER_WIDTH, initialOffsetFromCenter);
}
else if (initialOffsetFromCenter < 1)
{
// from selected to next
x = Interpolator::InterpolateLinear<fix32<12>>(SELECTED_COVER_X, NEXT_COVER_X, initialOffsetFromCenter);
width = Interpolator::InterpolateLinear<fix32<12>>(SELECTED_COVER_WIDTH, NEXT_COVER_WIDTH, initialOffsetFromCenter);
}
else
{
// everything after next
x = NEXT_COVER_X
+ Interpolator::InterpolateLinear<fix32<12>>(0, NEXT_COVER_WIDTH + COVER_SPACING, initialOffsetFromNext);
if (absOffsetFromCenter - 2 > 0)
{
x = x + (SMALL_COVER_WIDTH + COVER_SPACING) * (absOffsetFromCenter - 2);
}
width = Interpolator::InterpolateLinear<fix32<12>>(NEXT_COVER_WIDTH, SMALL_COVER_WIDTH, initialOffsetFromNext);
}
itemEx.xPosition = x;
itemEx.width = width;
}

View File

@@ -7,38 +7,44 @@ class MaterialColorScheme;
class CarouselRecyclerView : public CoverFlowRecyclerViewBase
{
struct Private { explicit Private() = default; };
SHARED_ONLY(CarouselRecyclerView)
public:
CarouselRecyclerView(Private, const MaterialColorScheme* materialColorScheme)
: _materialColorScheme(materialColorScheme) { }
static SharedPtr<CarouselRecyclerView> CreateShared(const MaterialColorScheme* materialColorScheme)
{
return SharedPtr<CarouselRecyclerView>::MakeShared(Private(), materialColorScheme);
}
static void UploadGraphics(const VramContext& vramContext);
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<fix32<12>> xPositionAnimator;
Animator<fix32<12>> widthAnimator;
fix32<12> xPosition;
fix32<12> width;
};
std::array<ViewPoolEntryEx, 10> _viewPoolEx;
const MaterialColorScheme* _materialColorScheme;
Animator<fix32<12>> _scrollAnimator = Animator<fix32<12>>(0);
bool _penDown = false;
Point _penDownPosition = Point(0, 0);
bool _hasScrollStarted = false;
fix32<12> _penDownScrollOffset = 0;
static u32 sMaskTextureVramOffset;
CarouselRecyclerView(const MaterialColorScheme* materialColorScheme)
: _materialColorScheme(materialColorScheme) { }
void RenderCoverMask(GraphicsContext& graphicsContext, fix32<12> left, fix32<12> right) const;
void RenderRoundedCorners(GraphicsContext& graphicsContext, fix32<12> x, fix32<12> width) const;
void UpdateItemPosition(int viewPoolIndex, bool initial) override;
void SetSelectedItem(int itemIdx, bool initial) override;
void UpdateItemPosition(int viewPoolIndex);
void SwapViewPoolEntry(int indexA, int indexB) override
{

View File

@@ -9,7 +9,7 @@ MaterialAppBarView::MaterialAppBarView(int x, int y, Orientation orientation,
{
for (int i = 0; i < _startButtonCount + _endButtonCount; i++)
{
_buttons[i] = SharedPtr<IconButton2DView>::MakeShared(
_buttons[i] = IconButton2DView::CreateShared(
IconButtonView::Type::Standard,
IconButtonView::State::NoToggle,
md::sys::color::inverseOnSurface,

View File

@@ -3,9 +3,12 @@
class MaterialAppBarView : public AppBarView
{
SHARED_ONLY(MaterialAppBarView)
public:
void InitVram(const VramContext& vramContext) override;
private:
MaterialAppBarView(int x, int y, Orientation orientation,
int startButtonCount, int endButtonCount, const MaterialColorScheme* materialColorScheme);
void InitVram(const VramContext& vramContext) override;
};

View File

@@ -18,12 +18,12 @@
#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)))
MaterialBannerListItemView::MaterialBannerListItemView(std::unique_ptr<RomBrowserItemViewModel> viewModel,
const MaterialColorScheme* materialColorScheme, const IFontRepository* fontRepository)
: BannerListItemView(std::move(viewModel),
Label2DView::CreateShared(160, 16, 50, fontRepository->GetFont(FontType::Medium10)),
Label2DView::CreateShared(160, 16, 50, fontRepository->GetFont(FontType::Regular10)),
Label2DView::CreateShared(160, 16, 50, fontRepository->GetFont(FontType::Regular10)))
, _materialColorScheme(materialColorScheme) { }
void MaterialBannerListItemView::Draw(GraphicsContext& graphicsContext)

View File

@@ -7,10 +7,9 @@ class IFontRepository;
class MaterialBannerListItemView : public BannerListItemView
{
public:
MaterialBannerListItemView(const MaterialColorScheme* materialColorScheme,
const IFontRepository* fontRepository);
SHARED_ONLY(MaterialBannerListItemView)
public:
void Draw(GraphicsContext& graphicsContext) override;
Rectangle GetBounds() const override
@@ -28,4 +27,7 @@ public:
private:
const MaterialColorScheme* _materialColorScheme;
u32 _bgVramOffset;
MaterialBannerListItemView(std::unique_ptr<RomBrowserItemViewModel> viewModel,
const MaterialColorScheme* materialColorScheme, const IFontRepository* fontRepository);
};

View File

@@ -15,13 +15,15 @@ void MaterialCoverFlowFileRecyclerAdapter::GetViewSize(int& width, int& height)
SharedPtr<View> MaterialCoverFlowFileRecyclerAdapter::CreateView() const
{
return SharedPtr<MaterialCoverView>::MakeShared(_vblankTextureLoader);
return MaterialCoverView::CreateShared(
std::make_unique<RomBrowserItemViewModel>(_romBrowserController), _vblankTextureLoader);
}
TaskResult<void> MaterialCoverFlowFileRecyclerAdapter::BindView(SharedPtr<View> view, int index,
const InternalFileInfo* internalFileInfo, const vu8& cancelRequested) const
{
auto coverView = static_cast<MaterialCoverView*>(view.GetPointer());
coverView->GetViewModel().SetIndex(index);
auto cover = _fileInfoManager->GetFileCover(index);
if (cancelRequested)
{
@@ -39,10 +41,18 @@ TaskResult<void> MaterialCoverFlowFileRecyclerAdapter::BindView(SharedPtr<View>
return TaskResult<void>::Completed();
}
void MaterialCoverFlowFileRecyclerAdapter::SetQueueTask(const SharedPtr<View>& view, QueueTask<void> queueTask) const
{
auto coverView = static_cast<MaterialCoverView*>(view.GetPointer());
coverView->GetViewModel().SetQueueTask(std::move(queueTask));
}
void MaterialCoverFlowFileRecyclerAdapter::ReleaseView(SharedPtr<View> view, int index) const
{
LOG_DEBUG("Releasing %d\n", index);
auto coverView = static_cast<MaterialCoverView*>(view.GetPointer());
coverView->ClearCover();
coverView->GetViewModel().SetIndex(-1);
coverView->GetViewModel().CancelQueueTask();
_fileInfoManager->ReleaseFileInfo(index);
}

View File

@@ -8,12 +8,12 @@ class ICoverRepository;
class MaterialCoverFlowFileRecyclerAdapter : public FileRecyclerAdapter
{
public:
MaterialCoverFlowFileRecyclerAdapter(FileInfoManager* fileInfoManager,
MaterialCoverFlowFileRecyclerAdapter(IRomBrowserController* romBrowserController, FileInfoManager* fileInfoManager,
TaskQueueBase* taskQueue, const IThemeFileIconFactory* themeFileIconFactory,
const IRomBrowserViewFactory* romBrowserViewFactory,
VBlankTextureLoader* vblankTextureLoader,
const ICoverRepository* coverRepository)
: FileRecyclerAdapter(fileInfoManager, taskQueue, themeFileIconFactory)
: FileRecyclerAdapter(romBrowserController, fileInfoManager, taskQueue, themeFileIconFactory)
, _romBrowserViewFactory(romBrowserViewFactory)
, _vblankTextureLoader(vblankTextureLoader)
, _coverRepository(coverRepository) { }
@@ -29,4 +29,5 @@ private:
TaskResult<void> BindView(SharedPtr<View> view, int index,
const InternalFileInfo* internalFileInfo, const vu8& cancelRequested) const override;
void SetQueueTask(const SharedPtr<View>& view, QueueTask<void> queueTask) const override;
};

View File

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

View File

@@ -3,13 +3,14 @@
#include "gui/views/View.h"
#include "romBrowser/FileType/FileCover.h"
#include "gui/VBlankTextureLoader.h"
#include "romBrowser/viewModels/RomBrowserItemViewModel.h"
#include "romBrowser/views/RomBrowserItemInputHandler.h"
class MaterialCoverView : public View
{
public:
explicit MaterialCoverView(VBlankTextureLoader* vblankTextureLoader)
: _vblankTextureLoader(vblankTextureLoader) { }
SHARED_ONLY(MaterialCoverView)
public:
~MaterialCoverView() override
{
_vblankTextureLoader->CancelLoad(_textureLoadRequest);
@@ -17,11 +18,17 @@ 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);
return Rectangle(_position.x, _position.y, COVER_WIDTH, COVER_HEIGHT);
}
void SetCover(SharedPtr<FileCover> cover)
@@ -38,10 +45,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;
MaterialCoverView(std::unique_ptr<RomBrowserItemViewModel> viewModel, VBlankTextureLoader* vblankTextureLoader)
: _viewModel(std::move(viewModel)), _vblankTextureLoader(vblankTextureLoader)
, _inputHandler(this, _viewModel.get()) { }
};

View File

@@ -13,17 +13,17 @@
MaterialFileInfoCardView::MaterialFileInfoCardView(const MaterialColorScheme* materialColorScheme,
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))
: _firstLine(Label2DView::CreateShared(176, 16, 50, fontRepository->GetFont(FontType::Medium11)))
, _secondLine(Label2DView::CreateShared(176, 16, 50, fontRepository->GetFont(FontType::Regular10)))
, _thirdLine(Label2DView::CreateShared(176, 16, 50, fontRepository->GetFont(FontType::Regular10)))
, _filenameLabelView(Label2DView::CreateShared(220, 16, 200, fontRepository->GetFont(FontType::Medium7_5)))
, _materialColorScheme(materialColorScheme)
{
AddChildTail(&_firstLine);
AddChildTail(&_secondLine);
AddChildTail(&_thirdLine);
_filenameLabelView.SetEllipsisStyle(LabelView::EllipsisStyle::Marquee);
AddChildTail(&_filenameLabelView);
AddChildTail(_firstLine.GetPointer());
AddChildTail(_secondLine.GetPointer());
AddChildTail(_thirdLine.GetPointer());
_filenameLabelView->SetEllipsisStyle(LabelView::EllipsisStyle::Marquee);
AddChildTail(_filenameLabelView.GetPointer());
}
void MaterialFileInfoCardView::InitVram(const VramContext& vramContext)
@@ -41,10 +41,10 @@ void MaterialFileInfoCardView::InitVram(const VramContext& vramContext)
void MaterialFileInfoCardView::Update()
{
BannerView::Update();
_firstLine.SetPosition(_position.x + 70, _position.y + 130 - 8);
_secondLine.SetPosition(_position.x + 70, _position.y + 145 - 8);
_thirdLine.SetPosition(_position.x + 70, _position.y + 159 - 8);
_filenameLabelView.SetPosition(_position.x + 18, _position.y + 168);
_firstLine->SetPosition(_position.x + 70, _position.y + 130 - 8);
_secondLine->SetPosition(_position.x + 70, _position.y + 145 - 8);
_thirdLine->SetPosition(_position.x + 70, _position.y + 159 - 8);
_filenameLabelView->SetPosition(_position.x + 18, _position.y + 168);
if (_icon)
{
_icon->SetPosition(_position.x + 24, _position.y + 136 - 8);
@@ -54,14 +54,14 @@ void MaterialFileInfoCardView::Update()
void MaterialFileInfoCardView::Draw(GraphicsContext& graphicsContext)
{
_firstLine.SetBackgroundColor(_materialColorScheme->secondaryContainer);
_firstLine.SetForegroundColor(_materialColorScheme->onSecondaryContainer);
_secondLine.SetBackgroundColor(_materialColorScheme->secondaryContainer);
_secondLine.SetForegroundColor(_materialColorScheme->onSecondaryContainer);
_thirdLine.SetBackgroundColor(_materialColorScheme->secondaryContainer);
_thirdLine.SetForegroundColor(_materialColorScheme->onSecondaryContainer);
_filenameLabelView.SetBackgroundColor(_materialColorScheme->secondaryContainer);
_filenameLabelView.SetForegroundColor(_materialColorScheme->onSurfaceVariant);
_firstLine->SetBackgroundColor(_materialColorScheme->secondaryContainer);
_firstLine->SetForegroundColor(_materialColorScheme->onSecondaryContainer);
_secondLine->SetBackgroundColor(_materialColorScheme->secondaryContainer);
_secondLine->SetForegroundColor(_materialColorScheme->onSecondaryContainer);
_thirdLine->SetBackgroundColor(_materialColorScheme->secondaryContainer);
_thirdLine->SetForegroundColor(_materialColorScheme->onSecondaryContainer);
_filenameLabelView->SetBackgroundColor(_materialColorScheme->secondaryContainer);
_filenameLabelView->SetForegroundColor(_materialColorScheme->onSurfaceVariant);
BannerView::Draw(graphicsContext);

View File

@@ -9,55 +9,54 @@ class IFontRepository;
class MaterialFileInfoCardView : public BannerView
{
public:
MaterialFileInfoCardView(const MaterialColorScheme* materialColorScheme,
const IFontRepository* fontRepository);
SHARED_ONLY(MaterialFileInfoCardView)
public:
void InitVram(const VramContext& vramContext) override;
void Update() override;
void Draw(GraphicsContext& graphicsContext) override;
void SetFirstLineAsync(TaskQueueBase* taskQueue, const char* firstLine, bool ellipsis) override
{
_firstLine.SetEllipsisStyle(ellipsis ? LabelView::EllipsisStyle::Ellipsis : LabelView::EllipsisStyle::None);
_firstLine->SetEllipsisStyle(ellipsis ? LabelView::EllipsisStyle::Ellipsis : LabelView::EllipsisStyle::None);
if (taskQueue)
_firstLine.SetTextAsync(taskQueue, firstLine);
_firstLine->SetTextAsync(taskQueue, firstLine);
else
_firstLine.SetText(firstLine);
_firstLine->SetText(firstLine);
}
void SetFirstLineAsync(TaskQueueBase* taskQueue, const char16_t* firstLine, u32 length, bool ellipsis) override
{
_firstLine.SetEllipsisStyle(ellipsis ? LabelView::EllipsisStyle::Ellipsis : LabelView::EllipsisStyle::None);
_firstLine->SetEllipsisStyle(ellipsis ? LabelView::EllipsisStyle::Ellipsis : LabelView::EllipsisStyle::None);
if (taskQueue)
_firstLine.SetTextAsync(taskQueue, firstLine, length);
_firstLine->SetTextAsync(taskQueue, firstLine, length);
else
_firstLine.SetText(firstLine, length);
_firstLine->SetText(firstLine, length);
}
void SetSecondLineAsync(TaskQueueBase* taskQueue, const char16_t* secondLine, u32 length) override
{
if (taskQueue)
_secondLine.SetTextAsync(taskQueue, secondLine, length);
_secondLine->SetTextAsync(taskQueue, secondLine, length);
else
_secondLine.SetText(secondLine, length);
_secondLine->SetText(secondLine, length);
}
void SetThirdLineAsync(TaskQueueBase* taskQueue, const char16_t* thirdLine, u32 length) override
{
if (taskQueue)
_thirdLine.SetTextAsync(taskQueue, thirdLine, length);
_thirdLine->SetTextAsync(taskQueue, thirdLine, length);
else
_thirdLine.SetText(thirdLine, length);
_thirdLine->SetText(thirdLine, length);
}
void SetFileNameAsync(TaskQueueBase* taskQueue, const TCHAR* fileName, bool useAsTitle) override
{
BannerView::SetFileNameAsync(taskQueue, fileName, useAsTitle);
if (taskQueue)
_filenameLabelView.SetTextAsync(taskQueue, fileName);
_filenameLabelView->SetTextAsync(taskQueue, fileName);
else
_filenameLabelView.SetText(fileName);
_filenameLabelView->SetText(fileName);
}
Rectangle GetBounds() const override
@@ -66,10 +65,13 @@ public:
}
private:
Label2DView _firstLine;
Label2DView _secondLine;
Label2DView _thirdLine;
Label2DView _filenameLabelView;
SharedPtr<Label2DView> _firstLine;
SharedPtr<Label2DView> _secondLine;
SharedPtr<Label2DView> _thirdLine;
SharedPtr<Label2DView> _filenameLabelView;
u32 _iconCellVramOffset;
const MaterialColorScheme* _materialColorScheme;
MaterialFileInfoCardView(const MaterialColorScheme* materialColorScheme,
const IFontRepository* fontRepository);
};

View File

@@ -20,7 +20,7 @@ void MaterialIconGridItemView::Draw(GraphicsContext& graphicsContext)
return;
auto backColor = _materialColorScheme->inverseOnSurface;
auto frontColor = _isFocused
auto frontColor = (_isFocused || _inputHandler.IsPenDown())
? _materialColorScheme->mainIconBg
: _materialColorScheme->surfaceBright;
u16 selectedIconCellPltt[16];

View File

@@ -5,10 +5,9 @@ class MaterialColorScheme;
class MaterialIconGridItemView : public IconGridItemView
{
public:
explicit MaterialIconGridItemView(const MaterialColorScheme* materialColorScheme)
: _materialColorScheme(materialColorScheme) { }
SHARED_ONLY(MaterialIconGridItemView)
public:
void Draw(GraphicsContext& graphicsContext) override;
Rectangle GetBounds() const override
@@ -26,4 +25,7 @@ public:
private:
const MaterialColorScheme* _materialColorScheme;
u32 _bgVramOffset;
};
MaterialIconGridItemView(std::unique_ptr<RomBrowserItemViewModel> viewModel, const MaterialColorScheme* materialColorScheme)
: IconGridItemView(std::move(viewModel)), _materialColorScheme(materialColorScheme) { }
};

View File

@@ -18,9 +18,9 @@ public:
const IFontRepository* fontRepository)
: _materialColorScheme(materialColorScheme), _fontRepository(fontRepository) { }
SharedPtr<IconGridItemView> CreateIconGridItemView() const override
SharedPtr<IconGridItemView> CreateIconGridItemView(std::unique_ptr<RomBrowserItemViewModel> viewModel) const override
{
return SharedPtr<MaterialIconGridItemView>::MakeShared(_materialColorScheme);
return MaterialIconGridItemView::CreateShared(std::move(viewModel), _materialColorScheme);
}
IconGridItemView::VramToken UploadIconGridItemViewGraphics(
@@ -29,9 +29,10 @@ public:
return MaterialIconGridItemView::UploadGraphics(vramContext);
}
SharedPtr<BannerListItemView> CreateBannerListItemView(VBlankTextureLoader* vblankTextureLoader) const override
SharedPtr<BannerListItemView> CreateBannerListItemView(std::unique_ptr<RomBrowserItemViewModel> viewModel,
VBlankTextureLoader* vblankTextureLoader) const override
{
return SharedPtr<MaterialBannerListItemView>::MakeShared(_materialColorScheme, _fontRepository);
return MaterialBannerListItemView::CreateShared(std::move(viewModel), _materialColorScheme, _fontRepository);
}
BannerListItemView::VramToken UploadBannerListItemViewGraphics(
@@ -40,15 +41,15 @@ public:
return MaterialBannerListItemView::UploadGraphics(vramContext);
}
std::unique_ptr<AppBarView> CreateAppBarView(int x, int y, AppBarView::Orientation orientation,
SharedPtr<AppBarView> CreateAppBarView(int x, int y, AppBarView::Orientation orientation,
int startButtonCount, int endButtonCount) const override
{
return std::make_unique<MaterialAppBarView>(x, y, orientation, startButtonCount, endButtonCount, _materialColorScheme);
return MaterialAppBarView::CreateShared(x, y, orientation, startButtonCount, endButtonCount, _materialColorScheme);
}
std::unique_ptr<BannerView> CreateFileInfoView() const override
SharedPtr<BannerView> CreateFileInfoView() const override
{
return std::make_unique<MaterialFileInfoCardView>(_materialColorScheme, _fontRepository);
return MaterialFileInfoCardView::CreateShared(_materialColorScheme, _fontRepository);
}
SharedPtr<RecyclerViewBase> CreateCoverFlowRecyclerView() const override
@@ -60,7 +61,7 @@ public:
RomBrowserViewModel* viewModel, const IThemeFileIconFactory* themeFileIconFactory,
VBlankTextureLoader* vblankTextureLoader) const override
{
return SharedPtr<MaterialCoverFlowFileRecyclerAdapter>::MakeShared(
return SharedPtr<MaterialCoverFlowFileRecyclerAdapter>::MakeShared(viewModel->GetRomBrowserController(),
&viewModel->GetFileInfoManager(), viewModel->GetIoTaskQueue(),
themeFileIconFactory, this, vblankTextureLoader, &viewModel->GetCoverRepository());
}