mirror of
https://github.com/LNH-team/pico-launcher.git
synced 2026-06-02 09:06:54 +02:00
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:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -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()) { }
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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) { }
|
||||
};
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user