mirror of
https://github.com/LNH-team/pico-launcher.git
synced 2026-06-02 00:56:55 +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:
@@ -4,6 +4,11 @@
|
|||||||
|
|
||||||
### Added
|
### Added
|
||||||
- Ability to set the position of the top screen cover image in custom themes
|
- Ability to set the position of the top screen cover image in custom themes
|
||||||
|
- Support for fast scrolling with the L and R buttons in coverflow display mode
|
||||||
|
- Support for touch input
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- Use after free bug with the texture load request in Label3DView. This occurred for example when spamming B in banner list mode.
|
||||||
|
|
||||||
## [v1.2.0] - 29 Mar 2026
|
## [v1.2.0] - 29 Mar 2026
|
||||||
|
|
||||||
|
|||||||
@@ -30,6 +30,7 @@
|
|||||||
#include "ExitMode.h"
|
#include "ExitMode.h"
|
||||||
#include "Arm7State.h"
|
#include "Arm7State.h"
|
||||||
#include "mmc/tmio.h"
|
#include "mmc/tmio.h"
|
||||||
|
#include "touchScreen.h"
|
||||||
|
|
||||||
static NocashOutputStream sNocashOutputStream;
|
static NocashOutputStream sNocashOutputStream;
|
||||||
static PlainLogger sPlainLogger = PlainLogger(LogLevel::All, std::unique_ptr<IOutputStream>(&sNocashOutputStream));
|
static PlainLogger sPlainLogger = PlainLogger(LogLevel::All, std::unique_ptr<IOutputStream>(&sNocashOutputStream));
|
||||||
@@ -42,19 +43,14 @@ static RtcIpcService sRtcIpcService;
|
|||||||
|
|
||||||
ILogger* gLogger = &sThreadSafeLogger;
|
ILogger* gLogger = &sThreadSafeLogger;
|
||||||
|
|
||||||
static rtos_event_t sVBlankEvent;
|
static rtos_event_t sVCountEvent;
|
||||||
static ExitMode sExitMode;
|
static ExitMode sExitMode;
|
||||||
static Arm7State sState;
|
static Arm7State sState;
|
||||||
static volatile u8 sMcuIrqFlag = false;
|
static volatile u8 sMcuIrqFlag = false;
|
||||||
|
|
||||||
static void vblankIrq(u32 irqMask)
|
|
||||||
{
|
|
||||||
rtos_signalEvent(&sVBlankEvent);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void vcountIrq(u32 irqMask)
|
static void vcountIrq(u32 irqMask)
|
||||||
{
|
{
|
||||||
SHARED_KEY_XY = REG_RCNT0_H;
|
rtos_signalEvent(&sVCountEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mcuIrq(u32 irq2Mask)
|
static void mcuIrq(u32 irq2Mask)
|
||||||
@@ -88,12 +84,13 @@ static void checkMcuIrq(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void initializeVBlankIrq()
|
static void initializeVCountIrq()
|
||||||
{
|
{
|
||||||
rtos_createEvent(&sVBlankEvent);
|
rtos_createEvent(&sVCountEvent);
|
||||||
rtos_setIrqFunc(RTOS_IRQ_VBLANK, vblankIrq);
|
gfx_setVCountMatchLine(96);
|
||||||
rtos_enableIrqMask(RTOS_IRQ_VBLANK);
|
rtos_setIrqFunc(RTOS_IRQ_VCOUNT, vcountIrq);
|
||||||
gfx_setVBlankIrqEnabled(true);
|
rtos_enableIrqMask(RTOS_IRQ_VCOUNT);
|
||||||
|
gfx_setVCountMatchIrqEnabled(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void clearSoundRegisters()
|
static void clearSoundRegisters()
|
||||||
@@ -145,12 +142,7 @@ static void initializeArm7()
|
|||||||
sSoundIpcService.Start();
|
sSoundIpcService.Start();
|
||||||
sRtcIpcService.Start();
|
sRtcIpcService.Start();
|
||||||
|
|
||||||
gfx_setVCountMatchLine(96);
|
initializeVCountIrq();
|
||||||
rtos_setIrqFunc(RTOS_IRQ_VCOUNT, vcountIrq);
|
|
||||||
rtos_enableIrqMask(RTOS_IRQ_VCOUNT);
|
|
||||||
gfx_setVCountMatchIrqEnabled(true);
|
|
||||||
|
|
||||||
initializeVBlankIrq();
|
|
||||||
|
|
||||||
if (isDSiMode())
|
if (isDSiMode())
|
||||||
{
|
{
|
||||||
@@ -158,6 +150,8 @@ static void initializeArm7()
|
|||||||
rtos_enableIrq2Mask(RTOS_IRQ2_MCU);
|
rtos_enableIrq2Mask(RTOS_IRQ2_MCU);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
touch_init();
|
||||||
|
|
||||||
ipc_setArm7SyncBits(7);
|
ipc_setArm7SyncBits(7);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -233,7 +227,16 @@ int main()
|
|||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
rtos_waitEvent(&sVBlankEvent, true, true);
|
rtos_waitEvent(&sVCountEvent, true, true);
|
||||||
|
u16 keys = REG_RCNT0_H | RCNT0_H_DATA_PEN;
|
||||||
|
touchPosition touchPos;
|
||||||
|
if (touch_update(touchPos))
|
||||||
|
{
|
||||||
|
keys &= ~RCNT0_H_DATA_PEN; // pen down
|
||||||
|
SHARED_TOUCH_X = touchPos.px;
|
||||||
|
SHARED_TOUCH_Y = touchPos.py;
|
||||||
|
}
|
||||||
|
SHARED_KEY_XY = keys;
|
||||||
updateArm7();
|
updateArm7();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
146
arm7/source/touchScreen.cpp
Normal file
146
arm7/source/touchScreen.cpp
Normal file
@@ -0,0 +1,146 @@
|
|||||||
|
#include "common.h"
|
||||||
|
#include <nds/input.h>
|
||||||
|
#include <nds/arm7/touch.h>
|
||||||
|
|
||||||
|
// See: https://github.com/blocksds/libnds/blob/master/source/arm7/input.c
|
||||||
|
|
||||||
|
// === Touchscreen filter configuration ===
|
||||||
|
|
||||||
|
// Replace Z1/Z2 values with X/Y noisiness measurements.
|
||||||
|
// #define TOUCH_DEBUG_NOISINESS
|
||||||
|
|
||||||
|
// The number of frames to debounce/hold pen presses for.
|
||||||
|
// Set to 0 to disable.
|
||||||
|
#define PEN_DOWN_DEBOUNCE 1
|
||||||
|
// The shift (1 << N) used for the IIR filter to average noisy samples across
|
||||||
|
// time. Set to 0 to disable.
|
||||||
|
#define TOUCH_MAX_NOISE_PEN_UP_IIR_SHIFT 5
|
||||||
|
|
||||||
|
// The maximum value of noisiness for pressing a pen down (measurement now valid).
|
||||||
|
#define TOUCH_MAX_NOISE_PEN_DOWN 38
|
||||||
|
// The minimum value of noisiness for lifting a pen up (measurement no longer valid).
|
||||||
|
#define TOUCH_MAX_NOISE_PEN_UP 50
|
||||||
|
|
||||||
|
// === Touchscreen filter ===
|
||||||
|
|
||||||
|
// IIR filter constants.
|
||||||
|
#define TOUCH_MAX_NOISE_PEN_UP_IIR_RATIO (1 << TOUCH_MAX_NOISE_PEN_UP_IIR_SHIFT)
|
||||||
|
#define TOUCH_MAX_NOISE_PEN_UP_IIR_MIN (TOUCH_MAX_NOISE_PEN_UP - TOUCH_MAX_NOISE_PEN_UP_IIR_RATIO)
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
u16 value; // 1..4095, 0 if invalid
|
||||||
|
u16 noisiness; // 0..4095, ~15-16 = 1 pixel
|
||||||
|
} libnds_touchMeasurementFilterResult;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Perform filtering on the raw touch samples provided to return one
|
||||||
|
* averaged sample and an estimate of how noisy it is, while skipping outliers.
|
||||||
|
*
|
||||||
|
* Internal. See touchFilter.c for more information.
|
||||||
|
*/
|
||||||
|
extern "C" libnds_touchMeasurementFilterResult libnds_touchMeasurementFilter(u16 values[5]);
|
||||||
|
|
||||||
|
void touch_init()
|
||||||
|
{
|
||||||
|
touchInit();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool touch_update(touchPosition& touchPos)
|
||||||
|
{
|
||||||
|
#if PEN_DOWN_DEBOUNCE > 0
|
||||||
|
static touchPosition lastTouchPosition;
|
||||||
|
static bool lastPenDown = false;
|
||||||
|
static u8 penDownDebounce = 0;
|
||||||
|
#else
|
||||||
|
touchPosition lastTouchPosition;
|
||||||
|
bool lastPenDown = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
bool penDown = touchPenDown();
|
||||||
|
if (penDown)
|
||||||
|
{
|
||||||
|
// Set penDown to false for later fallthroughs to noPenDown.
|
||||||
|
// It will be set to true if all the touch filtering ensures the readout is valid.
|
||||||
|
penDown = false;
|
||||||
|
|
||||||
|
// Measure new touch position.
|
||||||
|
touchRawArray data;
|
||||||
|
if (!touchReadData(&data))
|
||||||
|
goto noPenDown;
|
||||||
|
|
||||||
|
libnds_touchMeasurementFilterResult rawXresult = libnds_touchMeasurementFilter(data.rawX);
|
||||||
|
if (!rawXresult.value)
|
||||||
|
goto noPenDown;
|
||||||
|
libnds_touchMeasurementFilterResult rawYresult = libnds_touchMeasurementFilter(data.rawY);
|
||||||
|
if (!rawYresult.value)
|
||||||
|
goto noPenDown;
|
||||||
|
|
||||||
|
// Valid sample read.
|
||||||
|
u16 noisiness = rawXresult.noisiness > rawYresult.noisiness ? rawXresult.noisiness : rawYresult.noisiness;
|
||||||
|
if (noisiness <= (lastPenDown ? TOUCH_MAX_NOISE_PEN_UP : TOUCH_MAX_NOISE_PEN_DOWN))
|
||||||
|
{
|
||||||
|
lastTouchPosition.z1 = libnds_touchMeasurementFilter(data.z1).value;
|
||||||
|
lastTouchPosition.z2 = libnds_touchMeasurementFilter(data.z2).value;
|
||||||
|
|
||||||
|
#if TOUCH_MAX_NOISE_PEN_UP_IIR_SHIFT > 0
|
||||||
|
// Apply an IIR filter on noisy X/Y samples.
|
||||||
|
// Skip the IIR filter if the pen was just pressed.
|
||||||
|
int n = (noisiness - TOUCH_MAX_NOISE_PEN_UP_IIR_MIN);
|
||||||
|
if (noisiness <= 0 || !lastPenDown)
|
||||||
|
{
|
||||||
|
lastTouchPosition.rawx = rawXresult.value;
|
||||||
|
lastTouchPosition.rawy = rawYresult.value;
|
||||||
|
}
|
||||||
|
else if (noisiness <= TOUCH_MAX_NOISE_PEN_UP_IIR_RATIO)
|
||||||
|
{
|
||||||
|
lastTouchPosition.rawx =
|
||||||
|
((rawXresult.value * (TOUCH_MAX_NOISE_PEN_UP_IIR_RATIO - n))
|
||||||
|
+ (lastTouchPosition.rawx * n)) >> TOUCH_MAX_NOISE_PEN_UP_IIR_SHIFT;
|
||||||
|
lastTouchPosition.rawy =
|
||||||
|
((rawYresult.value * (TOUCH_MAX_NOISE_PEN_UP_IIR_RATIO - n))
|
||||||
|
+ (lastTouchPosition.rawy * n)) >> TOUCH_MAX_NOISE_PEN_UP_IIR_SHIFT;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
lastTouchPosition.rawx = rawXresult.value;
|
||||||
|
lastTouchPosition.rawy = rawYresult.value;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
touchApplyCalibration(lastTouchPosition.rawx, lastTouchPosition.rawy, &lastTouchPosition.px, &lastTouchPosition.py);
|
||||||
|
penDown = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef TOUCH_DEBUG_NOISINESS
|
||||||
|
lastTouchPosition.z1 = rawXresult.noisiness;
|
||||||
|
lastTouchPosition.z2 = rawYresult.noisiness;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
noPenDown:
|
||||||
|
#if PEN_DOWN_DEBOUNCE > 0
|
||||||
|
// Perform simple debouncing.
|
||||||
|
// Hold new presses for PEN_DOWN_DEBOUNCE frames.
|
||||||
|
if (!penDownDebounce)
|
||||||
|
{
|
||||||
|
if (lastPenDown != penDown)
|
||||||
|
{
|
||||||
|
lastPenDown = penDown;
|
||||||
|
if (penDown)
|
||||||
|
penDownDebounce = PEN_DOWN_DEBOUNCE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
penDownDebounce--;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
lastPenDown = penDown;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Return the touch position and pen down.
|
||||||
|
if (lastPenDown)
|
||||||
|
{
|
||||||
|
touchPos = lastTouchPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
return lastPenDown;
|
||||||
|
}
|
||||||
5
arm7/source/touchScreen.h
Normal file
5
arm7/source/touchScreen.h
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <nds/touch.h>
|
||||||
|
|
||||||
|
void touch_init();
|
||||||
|
bool touch_update(touchPosition& touchPos);
|
||||||
7
arm9/gfx/upIcon.grit
Normal file
7
arm9/gfx/upIcon.grit
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
# tile format
|
||||||
|
-gt
|
||||||
|
|
||||||
|
# graphics bit depth is 4 (16 color)
|
||||||
|
-gB4
|
||||||
|
|
||||||
|
-p!
|
||||||
BIN
arm9/gfx/upIcon.png
Normal file
BIN
arm9/gfx/upIcon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 179 B |
@@ -43,7 +43,7 @@ App::App(IAppSettingsService& appSettingsService, IBgmService& bgmService)
|
|||||||
, _subVramContext(nullptr, &_subObjVram, nullptr, nullptr)
|
, _subVramContext(nullptr, &_subObjVram, nullptr, nullptr)
|
||||||
, _appSettingsService(appSettingsService)
|
, _appSettingsService(appSettingsService)
|
||||||
, _bgmService(bgmService)
|
, _bgmService(bgmService)
|
||||||
, _inputProvider(&_inputSource)
|
, _inputProvider(&_keyInputSource, &_touchInputSource)
|
||||||
, _inputRepeater(&_inputProvider,
|
, _inputRepeater(&_inputProvider,
|
||||||
InputKey::DpadLeft | InputKey::DpadRight | InputKey::DpadUp | InputKey::DpadDown | InputKey::L | InputKey::R,
|
InputKey::DpadLeft | InputKey::DpadRight | InputKey::DpadUp | InputKey::DpadDown | InputKey::L | InputKey::R,
|
||||||
25, 8)
|
25, 8)
|
||||||
@@ -134,7 +134,7 @@ void App::Run()
|
|||||||
|
|
||||||
StoreVramState(_vramStateBeforeMakeBottomScreenView);
|
StoreVramState(_vramStateBeforeMakeBottomScreenView);
|
||||||
|
|
||||||
_romBrowserBottomScreenView = std::make_unique<RomBrowserBottomScreenView>(
|
_romBrowserBottomScreenView = RomBrowserBottomScreenView::CreateShared(
|
||||||
&_romBrowserBottomScreenViewModel,
|
&_romBrowserBottomScreenViewModel,
|
||||||
RomBrowserDisplayModeFactory().GetRomBrowserDisplayMode(
|
RomBrowserDisplayModeFactory().GetRomBrowserDisplayMode(
|
||||||
_romBrowserController.GetRomBrowserDisplaySettings().layout),
|
_romBrowserController.GetRomBrowserDisplaySettings().layout),
|
||||||
@@ -301,8 +301,8 @@ void App::HandleShowGameInfoTrigger()
|
|||||||
// gameInfoDialog->SetGraphics(_chipViewVram);
|
// gameInfoDialog->SetGraphics(_chipViewVram);
|
||||||
// _dialogPresenter.ShowDialog(std::move(gameInfoDialog));
|
// _dialogPresenter.ShowDialog(std::move(gameInfoDialog));
|
||||||
|
|
||||||
auto cheatsViewModel = std::make_unique<CheatsViewModel>(_romBrowserController.GetTriggerFileInfo(), &_romBrowserController);
|
auto cheatsViewModel = SharedPtr<CheatsViewModel>::MakeShared(_romBrowserController.GetTriggerFileInfo(), &_romBrowserController);
|
||||||
auto cheatsDialog = std::make_unique<CheatsBottomSheetView>(
|
auto cheatsDialog = CheatsBottomSheetView::CreateShared(
|
||||||
std::move(cheatsViewModel), &_theme->GetMaterialColorScheme(), _theme->GetFontRepository(), &_focusManager);
|
std::move(cheatsViewModel), &_theme->GetMaterialColorScheme(), _theme->GetFontRepository(), &_focusManager);
|
||||||
_dialogPresenter.ShowDialog(std::move(cheatsDialog));
|
_dialogPresenter.ShowDialog(std::move(cheatsDialog));
|
||||||
}
|
}
|
||||||
@@ -316,7 +316,7 @@ void App::HandleHideGameInfoTrigger()
|
|||||||
|
|
||||||
void App::HandleShowDisplaySettingsTrigger()
|
void App::HandleShowDisplaySettingsTrigger()
|
||||||
{
|
{
|
||||||
auto displaySettingsDialog = std::make_unique<DisplaySettingsBottomSheetView>(
|
auto displaySettingsDialog = DisplaySettingsBottomSheetView::CreateShared(
|
||||||
&_displaySettingsBottomSheetViewModel, &_theme->GetMaterialColorScheme(), _theme->GetFontRepository());
|
&_displaySettingsBottomSheetViewModel, &_theme->GetMaterialColorScheme(), _theme->GetFontRepository());
|
||||||
displaySettingsDialog->SetGraphics(_iconButtonViewVram);
|
displaySettingsDialog->SetGraphics(_iconButtonViewVram);
|
||||||
_dialogPresenter.ShowDialog(std::move(displaySettingsDialog));
|
_dialogPresenter.ShowDialog(std::move(displaySettingsDialog));
|
||||||
@@ -337,11 +337,11 @@ void App::HandleNavigateTrigger()
|
|||||||
|
|
||||||
void App::HandleFolderLoadDoneTrigger()
|
void App::HandleFolderLoadDoneTrigger()
|
||||||
{
|
{
|
||||||
_romBrowserTopScreenView.reset();
|
_romBrowserTopScreenView.Reset();
|
||||||
RestoreVramState(_vramStateAfterMakeBottomScreenView);
|
RestoreVramState(_vramStateAfterMakeBottomScreenView);
|
||||||
auto displayMode = RomBrowserDisplayModeFactory().GetRomBrowserDisplayMode(
|
auto displayMode = RomBrowserDisplayModeFactory().GetRomBrowserDisplayMode(
|
||||||
_romBrowserController.GetRomBrowserDisplaySettings().layout);
|
_romBrowserController.GetRomBrowserDisplaySettings().layout);
|
||||||
_romBrowserTopScreenView = std::make_unique<RomBrowserTopScreenView>(
|
_romBrowserTopScreenView = RomBrowserTopScreenView::CreateShared(
|
||||||
_romBrowserController.GetRomBrowserViewModel(),
|
_romBrowserController.GetRomBrowserViewModel(),
|
||||||
displayMode,
|
displayMode,
|
||||||
_materialThemeFileIconFactory.get(),
|
_materialThemeFileIconFactory.get(),
|
||||||
@@ -358,7 +358,7 @@ void App::HandleChangeDisplayModeTrigger(RomBrowserState newState)
|
|||||||
RestoreVramState(_vramStateBeforeMakeBottomScreenView);
|
RestoreVramState(_vramStateBeforeMakeBottomScreenView);
|
||||||
auto displayMode = RomBrowserDisplayModeFactory().GetRomBrowserDisplayMode(
|
auto displayMode = RomBrowserDisplayModeFactory().GetRomBrowserDisplayMode(
|
||||||
_romBrowserController.GetRomBrowserDisplaySettings().layout);
|
_romBrowserController.GetRomBrowserDisplaySettings().layout);
|
||||||
_romBrowserBottomScreenView = std::make_unique<RomBrowserBottomScreenView>(
|
_romBrowserBottomScreenView = RomBrowserBottomScreenView::CreateShared(
|
||||||
&_romBrowserBottomScreenViewModel,
|
&_romBrowserBottomScreenViewModel,
|
||||||
displayMode,
|
displayMode,
|
||||||
_materialThemeFileIconFactory.get(),
|
_materialThemeFileIconFactory.get(),
|
||||||
@@ -366,7 +366,7 @@ void App::HandleChangeDisplayModeTrigger(RomBrowserState newState)
|
|||||||
&_vblankTextureLoader);
|
&_vblankTextureLoader);
|
||||||
_romBrowserBottomScreenView->InitVram(_mainVramContext);
|
_romBrowserBottomScreenView->InitVram(_mainVramContext);
|
||||||
StoreVramState(_vramStateAfterMakeBottomScreenView);
|
StoreVramState(_vramStateAfterMakeBottomScreenView);
|
||||||
_romBrowserTopScreenView = std::make_unique<RomBrowserTopScreenView>(
|
_romBrowserTopScreenView = RomBrowserTopScreenView::CreateShared(
|
||||||
_romBrowserController.GetRomBrowserViewModel(),
|
_romBrowserController.GetRomBrowserViewModel(),
|
||||||
displayMode,
|
displayMode,
|
||||||
_materialThemeFileIconFactory.get(),
|
_materialThemeFileIconFactory.get(),
|
||||||
@@ -405,7 +405,7 @@ void App::Update()
|
|||||||
bool isRomBrowserVisible = IsRomBrowserVisible();
|
bool isRomBrowserVisible = IsRomBrowserVisible();
|
||||||
if (isRomBrowserVisible && !_exit && curState != RomBrowserState::Launching)
|
if (isRomBrowserVisible && !_exit && curState != RomBrowserState::Launching)
|
||||||
{
|
{
|
||||||
_focusManager.Update(_inputRepeater);
|
HandleInput();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_topBackground)
|
if (_topBackground)
|
||||||
@@ -523,3 +523,49 @@ void App::RestoreVramState(const VramState& vramState)
|
|||||||
_texturePaletteVram.SetState(vramState._texPlttVramState);
|
_texturePaletteVram.SetState(vramState._texPlttVramState);
|
||||||
_subObjVram.SetState(vramState._subObjVramState);
|
_subObjVram.SetState(vramState._subObjVramState);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void App::HandleInput()
|
||||||
|
{
|
||||||
|
_focusManager.Update(_inputRepeater);
|
||||||
|
Point touchPoint;
|
||||||
|
if (_inputRepeater.Triggered(InputKey::Touch) &&
|
||||||
|
_inputRepeater.GetCurrentTouchPoint(touchPoint))
|
||||||
|
{
|
||||||
|
// pen down
|
||||||
|
if (_dialogPresenter.IsBottomSheetVisible())
|
||||||
|
{
|
||||||
|
_dialogPresenter.HandlePenDown(touchPoint, _focusManager);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_romBrowserBottomScreenView->HandlePenDown(touchPoint, _focusManager);
|
||||||
|
}
|
||||||
|
_lastTouchPoint = touchPoint;
|
||||||
|
}
|
||||||
|
else if (_inputRepeater.Released(InputKey::Touch))
|
||||||
|
{
|
||||||
|
// pen up
|
||||||
|
if (_dialogPresenter.IsBottomSheetVisible())
|
||||||
|
{
|
||||||
|
_dialogPresenter.HandlePenUp(_lastTouchPoint, _focusManager);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_romBrowserBottomScreenView->HandlePenUp(_lastTouchPoint, _focusManager);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (_inputRepeater.Current(InputKey::Touch)
|
||||||
|
&& _inputRepeater.GetCurrentTouchPoint(touchPoint))
|
||||||
|
{
|
||||||
|
// pen move
|
||||||
|
if (_dialogPresenter.IsBottomSheetVisible())
|
||||||
|
{
|
||||||
|
_dialogPresenter.HandlePenMove(touchPoint, _focusManager);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_romBrowserBottomScreenView->HandlePenMove(touchPoint, _focusManager);
|
||||||
|
}
|
||||||
|
_lastTouchPoint = touchPoint;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
#include "gui/DescendingStackVramManager.h"
|
#include "gui/DescendingStackVramManager.h"
|
||||||
#include "material/scheme/scheme.h"
|
#include "material/scheme/scheme.h"
|
||||||
#include "gui/input/PadInputSource.h"
|
#include "gui/input/PadInputSource.h"
|
||||||
|
#include "gui/input/TouchInputSource.h"
|
||||||
#include "gui/input/SampledInputProvider.h"
|
#include "gui/input/SampledInputProvider.h"
|
||||||
#include "gui/input/InputRepeater.h"
|
#include "gui/input/InputRepeater.h"
|
||||||
#include "gui/VBlankTextureLoader.h"
|
#include "gui/VBlankTextureLoader.h"
|
||||||
@@ -62,9 +63,9 @@ private:
|
|||||||
Rgb6Palette _rgb6Palette;
|
Rgb6Palette _rgb6Palette;
|
||||||
Animator<int> _fadeAnimator;
|
Animator<int> _fadeAnimator;
|
||||||
|
|
||||||
TaskQueue<32, 32> _ioTaskQueue;
|
TaskQueue<32, sizeof(TaskBase) + 32> _ioTaskQueue;
|
||||||
u32 _ioTaskThreadStack[2048 / 4];
|
u32 _ioTaskThreadStack[2048 / 4];
|
||||||
TaskQueue<32, 32> _bgTaskQueue;
|
TaskQueue<32, sizeof(TaskBase) + 32> _bgTaskQueue;
|
||||||
u32 _bgTaskThreadStack[2048 / 4];
|
u32 _bgTaskThreadStack[2048 / 4];
|
||||||
|
|
||||||
std::unique_ptr<ITheme> _theme;
|
std::unique_ptr<ITheme> _theme;
|
||||||
@@ -75,12 +76,13 @@ private:
|
|||||||
IBgmService& _bgmService;
|
IBgmService& _bgmService;
|
||||||
volatile bool _exit = false;
|
volatile bool _exit = false;
|
||||||
|
|
||||||
PadInputSource _inputSource;
|
PadInputSource _keyInputSource;
|
||||||
|
TouchInputSource _touchInputSource;
|
||||||
SampledInputProvider _inputProvider;
|
SampledInputProvider _inputProvider;
|
||||||
InputRepeater _inputRepeater;
|
InputRepeater _inputRepeater;
|
||||||
|
|
||||||
std::unique_ptr<RomBrowserBottomScreenView> _romBrowserBottomScreenView;
|
SharedPtr<RomBrowserBottomScreenView> _romBrowserBottomScreenView;
|
||||||
std::unique_ptr<RomBrowserTopScreenView> _romBrowserTopScreenView;
|
SharedPtr<RomBrowserTopScreenView> _romBrowserTopScreenView;
|
||||||
|
|
||||||
RomBrowserController _romBrowserController;
|
RomBrowserController _romBrowserController;
|
||||||
|
|
||||||
@@ -103,10 +105,13 @@ private:
|
|||||||
|
|
||||||
bool _vcountIrqStarted = false;
|
bool _vcountIrqStarted = false;
|
||||||
|
|
||||||
|
Point _lastTouchPoint = Point(0, 0);
|
||||||
|
|
||||||
void InitVramMapping() const;
|
void InitVramMapping() const;
|
||||||
void DisplaySplashScreen() const;
|
void DisplaySplashScreen() const;
|
||||||
void LoadTheme();
|
void LoadTheme();
|
||||||
void VCountIrq();
|
void VCountIrq();
|
||||||
|
void HandleInput();
|
||||||
void HandleTrigger(RomBrowserStateTrigger trigger, RomBrowserState newState);
|
void HandleTrigger(RomBrowserStateTrigger trigger, RomBrowserState newState);
|
||||||
void HandleShowGameInfoTrigger();
|
void HandleShowGameInfoTrigger();
|
||||||
void HandleHideGameInfoTrigger();
|
void HandleHideGameInfoTrigger();
|
||||||
|
|||||||
@@ -16,10 +16,12 @@ DialogPresenter::DialogPresenter(FocusManager* focusManager, StackVramManager* v
|
|||||||
_baseVramState = _vramManager->GetState();
|
_baseVramState = _vramManager->GetState();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DialogPresenter::ShowDialog(std::unique_ptr<DialogView> dialog)
|
void DialogPresenter::ShowDialog(SharedPtr<DialogView> dialog)
|
||||||
{
|
{
|
||||||
if (!_nextDialog)
|
if (!_nextDialog)
|
||||||
|
{
|
||||||
_nextDialog = std::move(dialog);
|
_nextDialog = std::move(dialog);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DialogPresenter::CloseDialog()
|
void DialogPresenter::CloseDialog()
|
||||||
@@ -93,7 +95,7 @@ void DialogPresenter::Update()
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
_newState = State::Idle;
|
_newState = State::Idle;
|
||||||
_currentDialog.reset();
|
_currentDialog.Reset();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -153,3 +155,27 @@ void DialogPresenter::InitVram()
|
|||||||
REG_BLDCNT = 0x3944;
|
REG_BLDCNT = 0x3944;
|
||||||
REG_BLDALPHA = (16 << 8) | 0;
|
REG_BLDALPHA = (16 << 8) | 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DialogPresenter::HandlePenDown(const Point& touchPoint, FocusManager& focusManager)
|
||||||
|
{
|
||||||
|
if (_curState == State::BottomSheetVisible && _currentDialog)
|
||||||
|
{
|
||||||
|
_currentDialog->HandlePenDown(touchPoint, focusManager);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DialogPresenter::HandlePenMove(const Point& touchPoint, FocusManager& focusManager)
|
||||||
|
{
|
||||||
|
if (_curState == State::BottomSheetVisible && _currentDialog)
|
||||||
|
{
|
||||||
|
_currentDialog->HandlePenMove(touchPoint, focusManager);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DialogPresenter::HandlePenUp(const Point& lastTouchPoint, FocusManager& focusManager)
|
||||||
|
{
|
||||||
|
if (_curState == State::BottomSheetVisible && _currentDialog)
|
||||||
|
{
|
||||||
|
_currentDialog->HandlePenUp(lastTouchPoint, focusManager);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ public:
|
|||||||
|
|
||||||
/// @brief Requests to show the given dialog.
|
/// @brief Requests to show the given dialog.
|
||||||
/// @param dialog The dialog to show.
|
/// @param dialog The dialog to show.
|
||||||
void ShowDialog(std::unique_ptr<DialogView> dialog);
|
void ShowDialog(SharedPtr<DialogView> dialog);
|
||||||
|
|
||||||
/// @brief Closes the current dialog.
|
/// @brief Closes the current dialog.
|
||||||
void CloseDialog();
|
void CloseDialog();
|
||||||
@@ -42,6 +42,21 @@ public:
|
|||||||
/// @brief Initializes vram that is needed for showing dialogs.
|
/// @brief Initializes vram that is needed for showing dialogs.
|
||||||
void InitVram();
|
void InitVram();
|
||||||
|
|
||||||
|
/// @brief Handles a pen down event.
|
||||||
|
/// @param touchPoint The touch point.
|
||||||
|
/// @param focusManager The focus manager.
|
||||||
|
void HandlePenDown(const Point& touchPoint, FocusManager& focusManager);
|
||||||
|
|
||||||
|
/// @brief Handles a pen move event.
|
||||||
|
/// @param touchPoint The touch point.
|
||||||
|
/// @param focusManager The focus manager.
|
||||||
|
void HandlePenMove(const Point& touchPoint, FocusManager& focusManager);
|
||||||
|
|
||||||
|
/// @brief Handles a pen up event.
|
||||||
|
/// @param lastTouchPoint The last touch point.
|
||||||
|
/// @param focusManager The focus manager.
|
||||||
|
void HandlePenUp(const Point& lastTouchPoint, FocusManager& focusManager);
|
||||||
|
|
||||||
/// @brief Clears the focus that was stored when a dialog was opened.
|
/// @brief Clears the focus that was stored when a dialog was opened.
|
||||||
void ClearOldFocus()
|
void ClearOldFocus()
|
||||||
{
|
{
|
||||||
@@ -55,6 +70,11 @@ public:
|
|||||||
return _oldFocus;
|
return _oldFocus;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IsBottomSheetVisible() const
|
||||||
|
{
|
||||||
|
return _curState != State::Idle;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum class State
|
enum class State
|
||||||
{
|
{
|
||||||
@@ -66,8 +86,8 @@ private:
|
|||||||
FocusManager* _focusManager;
|
FocusManager* _focusManager;
|
||||||
StackVramManager* _vramManager;
|
StackVramManager* _vramManager;
|
||||||
u32 _baseVramState;
|
u32 _baseVramState;
|
||||||
std::unique_ptr<DialogView> _currentDialog;
|
SharedPtr<DialogView> _currentDialog;
|
||||||
std::unique_ptr<DialogView> _nextDialog;
|
SharedPtr<DialogView> _nextDialog;
|
||||||
bool _initVram = false;
|
bool _initVram = false;
|
||||||
SharedPtr<View> _oldFocus = nullptr;
|
SharedPtr<View> _oldFocus = nullptr;
|
||||||
Animator<int> _scrimAnimator;
|
Animator<int> _scrimAnimator;
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ class EnableSharedFromThis : public EnableSharedFromThisBase
|
|||||||
template <class Y>
|
template <class Y>
|
||||||
friend class SharedPtr;
|
friend class SharedPtr;
|
||||||
|
|
||||||
protected:
|
public:
|
||||||
SharedPtr<T> SharedFromThis()
|
SharedPtr<T> SharedFromThis()
|
||||||
{
|
{
|
||||||
return __sharedFromThisWeakPtr.Lock();
|
return __sharedFromThisWeakPtr.Lock();
|
||||||
|
|||||||
@@ -207,3 +207,10 @@ private:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define SHARED_ONLY(className) \
|
||||||
|
friend class MakeSharedRefCount<className>; \
|
||||||
|
public: \
|
||||||
|
static SharedPtr<className> CreateShared(auto&&... args) \
|
||||||
|
{ return SharedPtr<className>::MakeShared(std::forward<decltype(args)>(args)...); } \
|
||||||
|
private:
|
||||||
|
|||||||
@@ -161,11 +161,27 @@ public:
|
|||||||
return FromRawValue(this->_value >> rhs);
|
return FromRawValue(this->_value >> rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr fix16 abs() const
|
constexpr fix16 Abs() const
|
||||||
{
|
{
|
||||||
return FromRawValue(std::abs(this->_value));
|
return FromRawValue(std::abs(this->_value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
constexpr fix16 Clamp(fix16 min, fix16 max) const
|
||||||
|
{
|
||||||
|
if (this->_value < min._value)
|
||||||
|
{
|
||||||
|
return min;
|
||||||
|
}
|
||||||
|
else if (this->_value > max._value)
|
||||||
|
{
|
||||||
|
return max;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
template <u32 OtherFractionBits>
|
template <u32 OtherFractionBits>
|
||||||
constexpr fix32<FractionBits + OtherFractionBits> LongMul(const fix16<OtherFractionBits>& other) const
|
constexpr fix32<FractionBits + OtherFractionBits> LongMul(const fix16<OtherFractionBits>& other) const
|
||||||
{
|
{
|
||||||
@@ -265,21 +281,45 @@ public:
|
|||||||
return this->_value < other._value;
|
return this->_value < other._value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename TLhs>
|
||||||
|
constexpr friend bool operator<(TLhs lhs, const fix32& rhs)
|
||||||
|
{
|
||||||
|
return fix32(lhs)._value < rhs._value;
|
||||||
|
}
|
||||||
|
|
||||||
constexpr bool operator<=(const fix32& other) const
|
constexpr bool operator<=(const fix32& other) const
|
||||||
{
|
{
|
||||||
return this->_value <= other._value;
|
return this->_value <= other._value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename TLhs>
|
||||||
|
constexpr friend bool operator<=(TLhs lhs, const fix32& rhs)
|
||||||
|
{
|
||||||
|
return fix32(lhs)._value <= rhs._value;
|
||||||
|
}
|
||||||
|
|
||||||
constexpr bool operator>(const fix32& other) const
|
constexpr bool operator>(const fix32& other) const
|
||||||
{
|
{
|
||||||
return this->_value > other._value;
|
return this->_value > other._value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename TLhs>
|
||||||
|
constexpr friend bool operator>(TLhs lhs, const fix32& rhs)
|
||||||
|
{
|
||||||
|
return fix32(lhs)._value > rhs._value;
|
||||||
|
}
|
||||||
|
|
||||||
constexpr bool operator>=(const fix32& other) const
|
constexpr bool operator>=(const fix32& other) const
|
||||||
{
|
{
|
||||||
return this->_value >= other._value;
|
return this->_value >= other._value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename TLhs>
|
||||||
|
constexpr friend bool operator>=(TLhs lhs, const fix32& rhs)
|
||||||
|
{
|
||||||
|
return fix32(lhs)._value >= rhs._value;
|
||||||
|
}
|
||||||
|
|
||||||
constexpr fix32 operator-() const
|
constexpr fix32 operator-() const
|
||||||
{
|
{
|
||||||
return FromRawValue(-this->_value);
|
return FromRawValue(-this->_value);
|
||||||
@@ -337,6 +377,22 @@ public:
|
|||||||
return FromRawValue(std::abs(this->_value));
|
return FromRawValue(std::abs(this->_value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
constexpr fix32 Clamp(fix32 min, fix32 max) const
|
||||||
|
{
|
||||||
|
if (this->_value < min._value)
|
||||||
|
{
|
||||||
|
return min;
|
||||||
|
}
|
||||||
|
else if (this->_value > max._value)
|
||||||
|
{
|
||||||
|
return max;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
template <u32 OtherFractionBits>
|
template <u32 OtherFractionBits>
|
||||||
constexpr fix64<FractionBits + OtherFractionBits> LongMul(const fix16<OtherFractionBits>& other) const
|
constexpr fix64<FractionBits + OtherFractionBits> LongMul(const fix16<OtherFractionBits>& other) const
|
||||||
{
|
{
|
||||||
@@ -354,6 +410,11 @@ public:
|
|||||||
return fix64<FractionBits>::FromRawValue((s64)this->_value * other);
|
return fix64<FractionBits>::FromRawValue((s64)this->_value * other);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
constexpr fix64<FractionBits> LongMul(double other) const
|
||||||
|
{
|
||||||
|
return LongMul(fix32(other));
|
||||||
|
}
|
||||||
|
|
||||||
template <u32 OtherFractionBits>
|
template <u32 OtherFractionBits>
|
||||||
constexpr fix32 operator*(const fix16<OtherFractionBits>& other) const
|
constexpr fix32 operator*(const fix16<OtherFractionBits>& other) const
|
||||||
{
|
{
|
||||||
@@ -371,6 +432,11 @@ public:
|
|||||||
return FromRawValue(this->_value * other);
|
return FromRawValue(this->_value * other);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
constexpr fix32 operator*(double other) const
|
||||||
|
{
|
||||||
|
return fix32(LongMul(fix32(other)));
|
||||||
|
}
|
||||||
|
|
||||||
constexpr friend fix32 operator*(int lhs, const fix32& rhs)
|
constexpr friend fix32 operator*(int lhs, const fix32& rhs)
|
||||||
{
|
{
|
||||||
return FromRawValue(lhs * rhs.GetRawValue());
|
return FromRawValue(lhs * rhs.GetRawValue());
|
||||||
|
|||||||
@@ -1,9 +1,20 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "Task.h"
|
#include "Task.h"
|
||||||
|
|
||||||
void TaskBase::Execute()
|
void TaskBase::RequestCancel()
|
||||||
{
|
{
|
||||||
u32 irqs = rtos_disableIrqs();
|
u32 irqs = rtos_disableIrqs();
|
||||||
|
_cancelRequested = true;
|
||||||
|
if (_state == TaskState::NotStarted)
|
||||||
|
{
|
||||||
|
_state = TaskState::Canceled;
|
||||||
|
rtos_wakeupQueue(&_threadQueue);
|
||||||
|
}
|
||||||
|
rtos_restoreIrqs(irqs);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TaskBase::Execute(u32 irqs)
|
||||||
|
{
|
||||||
if (_state == TaskState::NotStarted)
|
if (_state == TaskState::NotStarted)
|
||||||
{
|
{
|
||||||
_state = TaskState::Running;
|
_state = TaskState::Running;
|
||||||
@@ -12,7 +23,9 @@ void TaskBase::Execute()
|
|||||||
SetFinalState(finalState);
|
SetFinalState(finalState);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
rtos_restoreIrqs(irqs);
|
rtos_restoreIrqs(irqs);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TaskBase::SetFinalState(TaskState finalState)
|
void TaskBase::SetFinalState(TaskState finalState)
|
||||||
|
|||||||
@@ -3,14 +3,17 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <libtwl/rtos/rtosIrq.h>
|
#include <libtwl/rtos/rtosIrq.h>
|
||||||
#include <libtwl/rtos/rtosThread.h>
|
#include <libtwl/rtos/rtosThread.h>
|
||||||
|
#include "core/LinkedListLink.h"
|
||||||
#include "TaskResult.h"
|
#include "TaskResult.h"
|
||||||
|
|
||||||
class TaskBase
|
class TaskBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
LinkedListLink link;
|
||||||
|
|
||||||
virtual ~TaskBase() { }
|
virtual ~TaskBase() { }
|
||||||
|
|
||||||
void Execute();
|
void Execute(u32 irqs);
|
||||||
|
|
||||||
TaskState GetState() const { return _state; }
|
TaskState GetState() const { return _state; }
|
||||||
|
|
||||||
@@ -24,7 +27,7 @@ public:
|
|||||||
bool GetDestroyWhenComplete() const { return _destroyWhenComplete; }
|
bool GetDestroyWhenComplete() const { return _destroyWhenComplete; }
|
||||||
void SetDestroyWhenComplete() { _destroyWhenComplete = true; }
|
void SetDestroyWhenComplete() { _destroyWhenComplete = true; }
|
||||||
|
|
||||||
void RequestCancel() { _cancelRequested = true; }
|
void RequestCancel();
|
||||||
bool IsCancelRequested() const { return _cancelRequested; }
|
bool IsCancelRequested() const { return _cancelRequested; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|||||||
@@ -1,23 +1,22 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "TaskQueue.h"
|
#include "TaskQueue.h"
|
||||||
|
|
||||||
void TaskQueueBase::ThreadMain(TaskBase** queue, u32 queueLength)
|
void TaskQueueBase::ThreadMain()
|
||||||
{
|
{
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
_idle = false;
|
_idle = false;
|
||||||
u32 readPtr = _queueReadPtr;
|
while (true)
|
||||||
while (readPtr != _queueWritePtr)
|
|
||||||
{
|
{
|
||||||
TaskBase* task = queue[readPtr];
|
u32 irqs = rtos_disableIrqs();
|
||||||
if (readPtr == queueLength - 1)
|
auto task = _taskList.GetHead();
|
||||||
readPtr = 0;
|
|
||||||
else
|
|
||||||
readPtr++;
|
|
||||||
_queueReadPtr = readPtr;
|
|
||||||
if (!task)
|
if (!task)
|
||||||
continue;
|
{
|
||||||
task->Execute();
|
rtos_restoreIrqs(irqs);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
_taskList.Remove(task);
|
||||||
|
task->Execute(irqs);
|
||||||
if (task->GetDestroyWhenComplete())
|
if (task->GetDestroyWhenComplete())
|
||||||
{
|
{
|
||||||
// this will destroy the task
|
// this will destroy the task
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#include <libtwl/rtos/rtosEvent.h>
|
#include <libtwl/rtos/rtosEvent.h>
|
||||||
#include <libtwl/rtos/rtosThread.h>
|
#include <libtwl/rtos/rtosThread.h>
|
||||||
#include "core/BitVector.h"
|
#include "core/BitVector.h"
|
||||||
|
#include "core/LinkedList.h"
|
||||||
#include "Task.h"
|
#include "Task.h"
|
||||||
|
|
||||||
class TaskQueueBase;
|
class TaskQueueBase;
|
||||||
@@ -11,25 +12,13 @@ class TaskQueueBase;
|
|||||||
class QueueTaskBase
|
class QueueTaskBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// forbid copies
|
|
||||||
QueueTaskBase(const QueueTaskBase&) = delete;
|
|
||||||
QueueTaskBase& operator=(const QueueTaskBase&) = delete;
|
|
||||||
|
|
||||||
// move assignment
|
|
||||||
QueueTaskBase& operator=(QueueTaskBase&& other)
|
|
||||||
{
|
|
||||||
_taskQueue = other._taskQueue;
|
|
||||||
_task = other._task;
|
|
||||||
other._taskQueue = nullptr;
|
|
||||||
other._task = nullptr;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
~QueueTaskBase()
|
~QueueTaskBase()
|
||||||
{
|
{
|
||||||
// extra check here for optimizing out the dispose call after move assignment
|
// extra check here for optimizing out the dispose call after move assignment
|
||||||
if (_task)
|
if (_task)
|
||||||
|
{
|
||||||
Dispose();
|
Dispose();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Dispose();
|
void Dispose();
|
||||||
@@ -47,12 +36,10 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
TaskBase* _task;
|
TaskBase* _task;
|
||||||
|
TaskQueueBase* _taskQueue;
|
||||||
|
|
||||||
QueueTaskBase(TaskBase* task, TaskQueueBase* taskQueue)
|
QueueTaskBase(TaskBase* task, TaskQueueBase* taskQueue)
|
||||||
: _task(task), _taskQueue(taskQueue) { }
|
: _task(task), _taskQueue(taskQueue) { }
|
||||||
|
|
||||||
private:
|
|
||||||
TaskQueueBase* _taskQueue;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@@ -62,6 +49,26 @@ public:
|
|||||||
QueueTask()
|
QueueTask()
|
||||||
: QueueTaskBase(nullptr, nullptr) { }
|
: QueueTaskBase(nullptr, nullptr) { }
|
||||||
|
|
||||||
|
QueueTask(const QueueTask&) = delete;
|
||||||
|
QueueTask& operator=(const QueueTask&) = delete;
|
||||||
|
|
||||||
|
QueueTask(QueueTask&& other)
|
||||||
|
: QueueTaskBase(other._task, other._taskQueue)
|
||||||
|
{
|
||||||
|
other._task = nullptr;
|
||||||
|
other._taskQueue = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
QueueTask& operator=(QueueTask&& other)
|
||||||
|
{
|
||||||
|
Dispose();
|
||||||
|
_taskQueue = other._taskQueue;
|
||||||
|
_task = other._task;
|
||||||
|
other._taskQueue = nullptr;
|
||||||
|
other._task = nullptr;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
QueueTask(Task<T>* task, TaskQueueBase* taskQueue)
|
QueueTask(Task<T>* task, TaskQueueBase* taskQueue)
|
||||||
: QueueTaskBase(task, taskQueue) { }
|
: QueueTaskBase(task, taskQueue) { }
|
||||||
|
|
||||||
@@ -91,12 +98,11 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
rtos_event_t _event;
|
rtos_event_t _event;
|
||||||
vu32 _queueReadPtr = 0;
|
LinkedList<TaskBase, &TaskBase::link> _taskList;
|
||||||
vu32 _queueWritePtr = 0;
|
|
||||||
volatile bool _endThreadWhenDone = false;
|
volatile bool _endThreadWhenDone = false;
|
||||||
volatile bool _idle = true;
|
volatile bool _idle = true;
|
||||||
|
|
||||||
void ThreadMain(TaskBase** queue, u32 queueLength);
|
void ThreadMain();
|
||||||
|
|
||||||
TaskQueueBase()
|
TaskQueueBase()
|
||||||
{
|
{
|
||||||
@@ -124,6 +130,10 @@ public:
|
|||||||
u32 irqs = rtos_disableIrqs();
|
u32 irqs = rtos_disableIrqs();
|
||||||
if (task->IsCompleted())
|
if (task->IsCompleted())
|
||||||
{
|
{
|
||||||
|
if (task->link.prev != nullptr || task->link.next != nullptr)
|
||||||
|
{
|
||||||
|
_taskList.Remove(task);
|
||||||
|
}
|
||||||
task->~TaskBase();
|
task->~TaskBase();
|
||||||
u32 slot = ((u32)task - (u32)_taskPool) / ((MaxTaskSize + 3) & ~3);
|
u32 slot = ((u32)task - (u32)_taskPool) / ((MaxTaskSize + 3) & ~3);
|
||||||
_poolOccupation.Set(slot, 0);
|
_poolOccupation.Set(slot, 0);
|
||||||
@@ -159,13 +169,12 @@ public:
|
|||||||
|
|
||||||
bool IsIdle() const
|
bool IsIdle() const
|
||||||
{
|
{
|
||||||
return _queueReadPtr == _queueWritePtr && _idle;
|
return _taskList.GetHead() == nullptr && _idle;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
u32 _taskPool[QueueLength][(MaxTaskSize + 3) / 4];
|
u32 _taskPool[QueueLength][(MaxTaskSize + 3) / 4];
|
||||||
BitVector<QueueLength> _poolOccupation;
|
BitVector<QueueLength> _poolOccupation;
|
||||||
TaskBase* _queue[QueueLength];
|
|
||||||
rtos_thread_t _thread;
|
rtos_thread_t _thread;
|
||||||
bool _threadStarted = false;
|
bool _threadStarted = false;
|
||||||
|
|
||||||
@@ -191,12 +200,11 @@ private:
|
|||||||
[[gnu::noinline]]
|
[[gnu::noinline]]
|
||||||
void Enqueue(TaskBase* task) override
|
void Enqueue(TaskBase* task) override
|
||||||
{
|
{
|
||||||
u32 writePtr = _queueWritePtr;
|
u32 irqs = rtos_disableIrqs();
|
||||||
_queue[writePtr] = task;
|
{
|
||||||
if (writePtr == QueueLength - 1)
|
_taskList.InsertTail(task);
|
||||||
_queueWritePtr = 0;
|
}
|
||||||
else
|
rtos_restoreIrqs(irqs);
|
||||||
_queueWritePtr = writePtr + 1;
|
|
||||||
rtos_signalEvent(&_event);
|
rtos_signalEvent(&_event);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -207,6 +215,6 @@ private:
|
|||||||
|
|
||||||
void ThreadMain()
|
void ThreadMain()
|
||||||
{
|
{
|
||||||
TaskQueueBase::ThreadMain(&_queue[0], QueueLength);
|
TaskQueueBase::ThreadMain();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -2,10 +2,10 @@
|
|||||||
#include "InputKey.h"
|
#include "InputKey.h"
|
||||||
|
|
||||||
/// @brief Interface for a source of key input.
|
/// @brief Interface for a source of key input.
|
||||||
class IInputSource
|
class IKeyInputSource
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual ~IInputSource() { }
|
virtual ~IKeyInputSource() { }
|
||||||
|
|
||||||
virtual InputKey Sample() const = 0;
|
virtual InputKey Sample() const = 0;
|
||||||
};
|
};
|
||||||
14
arm9/source/gui/input/ITouchInputSource.h
Normal file
14
arm9/source/gui/input/ITouchInputSource.h
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "core/math/Point.h"
|
||||||
|
|
||||||
|
/// @brief Interface for a source of touch input.
|
||||||
|
class ITouchInputSource
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~ITouchInputSource() { }
|
||||||
|
|
||||||
|
/// @brief Samples the touch input.
|
||||||
|
/// @param touchPosition When the pen is down, the current touch position.
|
||||||
|
/// @return \c true when the pen is down, or \c false otherwise.
|
||||||
|
virtual bool Sample(Point& touchPosition) const = 0;
|
||||||
|
};
|
||||||
@@ -15,7 +15,9 @@ enum class InputKey : u16
|
|||||||
L = 1 << 9,
|
L = 1 << 9,
|
||||||
X = 1 << 10,
|
X = 1 << 10,
|
||||||
Y = 1 << 11,
|
Y = 1 << 11,
|
||||||
Debug = 1 << 13
|
Debug = 1 << 13,
|
||||||
|
Touch = 1 << 14,
|
||||||
|
Lid = 1 << 15
|
||||||
};
|
};
|
||||||
|
|
||||||
inline InputKey operator&(InputKey lhs, InputKey rhs)
|
inline InputKey operator&(InputKey lhs, InputKey rhs)
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include "core/math/Point.h"
|
||||||
#include "InputKey.h"
|
#include "InputKey.h"
|
||||||
|
|
||||||
class InputProvider
|
class InputProvider
|
||||||
@@ -14,6 +14,23 @@ public:
|
|||||||
/// @return \c true if any of the keys in the \p mask is being held, or \c false otherwise.
|
/// @return \c true if any of the keys in the \p mask is being held, or \c false otherwise.
|
||||||
bool Current(InputKey mask) const { return static_cast<bool>(_currentKeys & mask); }
|
bool Current(InputKey mask) const { return static_cast<bool>(_currentKeys & mask); }
|
||||||
|
|
||||||
|
/// @brief Returns the current touch point if the screen is being touched.
|
||||||
|
/// @param touchPoint The current touch point if the screen is being touched.
|
||||||
|
/// @return \c true if the screen is being touched, or \c false otherwise.
|
||||||
|
bool GetCurrentTouchPoint(Point& touchPoint)
|
||||||
|
{
|
||||||
|
if (Current(InputKey::Touch))
|
||||||
|
{
|
||||||
|
touchPoint = _currentTouchPoint;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
touchPoint = Point(0, 0);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// @brief Returns a bitmask of the keys that went from unpressed to pressed in the latest update.
|
/// @brief Returns a bitmask of the keys that went from unpressed to pressed in the latest update.
|
||||||
/// @return A bitmask of the keys that went from unpressed to pressed in the latest update.
|
/// @return A bitmask of the keys that went from unpressed to pressed in the latest update.
|
||||||
InputKey GetTriggeredKeys() const
|
InputKey GetTriggeredKeys() const
|
||||||
@@ -46,13 +63,16 @@ public:
|
|||||||
_currentKeys = InputKey::None;
|
_currentKeys = InputKey::None;
|
||||||
_triggeredKeys = InputKey::None;
|
_triggeredKeys = InputKey::None;
|
||||||
_releasedKeys = InputKey::None;
|
_releasedKeys = InputKey::None;
|
||||||
|
_currentTouchPoint = Point(0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
InputKey _currentKeys;
|
InputKey _currentKeys;
|
||||||
InputKey _triggeredKeys;
|
InputKey _triggeredKeys;
|
||||||
InputKey _releasedKeys;
|
InputKey _releasedKeys;
|
||||||
|
Point _currentTouchPoint;
|
||||||
|
|
||||||
InputProvider()
|
InputProvider()
|
||||||
: _currentKeys(InputKey::None), _triggeredKeys(InputKey::None), _releasedKeys(InputKey::None) { }
|
: _currentKeys(InputKey::None), _triggeredKeys(InputKey::None), _releasedKeys(InputKey::None)
|
||||||
|
, _currentTouchPoint(0, 0) { }
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -27,7 +27,9 @@ void InputRepeater::Update()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
_state = State::Idle;
|
_state = State::Idle;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (_state == State::NextRepeat)
|
else if (_state == State::NextRepeat)
|
||||||
{
|
{
|
||||||
@@ -40,13 +42,24 @@ void InputRepeater::Update()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
_state = State::Idle;
|
_state = State::Idle;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
InputKey lastRepKeys = _currentKeys & _repeatMask;
|
InputKey lastRepKeys = _currentKeys & _repeatMask;
|
||||||
_currentKeys = curKeys | repKeys;
|
_currentKeys = curKeys | repKeys;
|
||||||
_triggeredKeys = _inputProvider->GetTriggeredKeys() | repKeys;
|
_triggeredKeys = _inputProvider->GetTriggeredKeys() | repKeys;
|
||||||
_releasedKeys = _inputProvider->GetReleasedKeys() | (lastRepKeys & (lastRepKeys ^ repKeys));
|
_releasedKeys = _inputProvider->GetReleasedKeys() | (lastRepKeys & (lastRepKeys ^ repKeys));
|
||||||
|
Point touchPoint;
|
||||||
|
if (_inputProvider->GetCurrentTouchPoint(touchPoint))
|
||||||
|
{
|
||||||
|
_currentTouchPoint = touchPoint;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_currentTouchPoint = Point(0, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void InputRepeater::Reset()
|
void InputRepeater::Reset()
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ class InputRepeater : public InputProvider
|
|||||||
public:
|
public:
|
||||||
InputRepeater(InputProvider* inputProvider, InputKey repeatMask, u16 firstRepeatDelay, u16 nextRepeatDelay)
|
InputRepeater(InputProvider* inputProvider, InputKey repeatMask, u16 firstRepeatDelay, u16 nextRepeatDelay)
|
||||||
: _inputProvider(inputProvider), _state(State::Idle)
|
: _inputProvider(inputProvider), _state(State::Idle)
|
||||||
, _frameCounter(0), _repeatMask(repeatMask)
|
, _frameCounter(0), _repeatMask(repeatMask & ~InputKey::Touch)
|
||||||
, _firstRepeatDelayFrames(firstRepeatDelay)
|
, _firstRepeatDelayFrames(firstRepeatDelay)
|
||||||
, _nextRepeatDelayFrames(nextRepeatDelay) { }
|
, _nextRepeatDelayFrames(nextRepeatDelay) { }
|
||||||
|
|
||||||
|
|||||||
@@ -1,17 +1,18 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include <nds/input.h>
|
#include <nds/input.h>
|
||||||
#include "IInputSource.h"
|
#include "IKeyInputSource.h"
|
||||||
#include "sharedMemory.h"
|
#include "sharedMemory.h"
|
||||||
|
|
||||||
/// @brief Input source from the physical DS buttons.
|
/// @brief Input source from the physical DS buttons.
|
||||||
class PadInputSource : public IInputSource
|
class PadInputSource : public IKeyInputSource
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
InputKey Sample() const override
|
InputKey Sample() const override
|
||||||
{
|
{
|
||||||
u16 arm9Mask = (~REG_KEYINPUT & 0x3FF);
|
u16 arm9Mask = (~REG_KEYINPUT & 0x3FF);
|
||||||
u16 arm7Mask = (~SHARED_KEY_XY & 0xB);
|
u16 arm7Mask = (~SHARED_KEY_XY & 0xCB);
|
||||||
|
arm7Mask = (arm7Mask & 0xB) | ((arm7Mask & 0xC0) >> 2);
|
||||||
return static_cast<InputKey>((arm9Mask | (arm7Mask << 10)));
|
return static_cast<InputKey>((arm9Mask | (arm7Mask << 10)));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -7,16 +7,44 @@ void SampledInputProvider::Update()
|
|||||||
InputKey trig = InputKey::None;
|
InputKey trig = InputKey::None;
|
||||||
InputKey rel = InputKey::None;
|
InputKey rel = InputKey::None;
|
||||||
|
|
||||||
|
Point touchPoint(0, 0);
|
||||||
|
int touchPointCount = 0;
|
||||||
while (_inputBufferReadPtr != _inputBufferWritePtr)
|
while (_inputBufferReadPtr != _inputBufferWritePtr)
|
||||||
{
|
{
|
||||||
InputKey nextKeys = _inputBuffer[_inputBufferReadPtr];
|
InputKey nextKeys = _keyInputBuffer[_inputBufferReadPtr];
|
||||||
trig |= (nextKeys ^ curKeys) & nextKeys;
|
trig |= (nextKeys ^ curKeys) & nextKeys;
|
||||||
rel |= (nextKeys ^ curKeys) & curKeys;
|
rel |= (nextKeys ^ curKeys) & curKeys;
|
||||||
curKeys = nextKeys;
|
curKeys = nextKeys;
|
||||||
|
if ((nextKeys & InputKey::Touch) != InputKey::None)
|
||||||
|
{
|
||||||
|
touchPoint.x += _touchInputBuffer[_inputBufferReadPtr].x;
|
||||||
|
touchPoint.y += _touchInputBuffer[_inputBufferReadPtr].y;
|
||||||
|
touchPointCount++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
touchPoint = Point(0, 0);
|
||||||
|
touchPointCount = 0;
|
||||||
|
}
|
||||||
_inputBufferReadPtr = (_inputBufferReadPtr + 1) & 3;
|
_inputBufferReadPtr = (_inputBufferReadPtr + 1) & 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
_triggeredKeys = trig;
|
_triggeredKeys = trig;
|
||||||
_releasedKeys = rel;
|
_releasedKeys = rel;
|
||||||
_currentKeys = curKeys;
|
_currentKeys = curKeys;
|
||||||
|
if (touchPointCount == 0)
|
||||||
|
{
|
||||||
|
if ((_triggeredKeys & InputKey::Touch) != InputKey::None ||
|
||||||
|
(_currentKeys & InputKey::Touch) != InputKey::None)
|
||||||
|
{
|
||||||
|
_releasedKeys = _releasedKeys | InputKey::Touch;
|
||||||
|
}
|
||||||
|
_triggeredKeys = _triggeredKeys & ~InputKey::Touch;
|
||||||
|
_currentKeys = _currentKeys & ~InputKey::Touch;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_currentTouchPoint.x = touchPoint.x / touchPointCount;
|
||||||
|
_currentTouchPoint.y = touchPoint.y / touchPointCount;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,20 +1,23 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "InputProvider.h"
|
#include "InputProvider.h"
|
||||||
#include "IInputSource.h"
|
#include "IKeyInputSource.h"
|
||||||
|
#include "ITouchInputSource.h"
|
||||||
|
|
||||||
/// @brief Input provider providing input from an \see IInputSource.
|
/// @brief Input provider providing input from an \see IKeyInputSource.
|
||||||
class SampledInputProvider : public InputProvider
|
class SampledInputProvider : public InputProvider
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit SampledInputProvider(const IInputSource* inputSource)
|
explicit SampledInputProvider(const IKeyInputSource* keyInputSource, const ITouchInputSource* touchInputSource)
|
||||||
: _inputSource(inputSource), _inputBufferReadPtr(0), _inputBufferWritePtr(0) { }
|
: _keyInputSource(keyInputSource), _touchInputSource(touchInputSource)
|
||||||
|
, _inputBufferReadPtr(0), _inputBufferWritePtr(0) { }
|
||||||
|
|
||||||
void Update() override;
|
void Update() override;
|
||||||
|
|
||||||
/// @brief Samples the input source.
|
/// @brief Samples the input source.
|
||||||
void Sample()
|
void Sample()
|
||||||
{
|
{
|
||||||
_inputBuffer[_inputBufferWritePtr] = _inputSource->Sample();
|
_keyInputBuffer[_inputBufferWritePtr] = _keyInputSource->Sample();
|
||||||
|
_touchInputSource->Sample(_touchInputBuffer[_inputBufferWritePtr]);
|
||||||
_inputBufferWritePtr = (_inputBufferWritePtr + 1) & 3;
|
_inputBufferWritePtr = (_inputBufferWritePtr + 1) & 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -26,9 +29,11 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const IInputSource* _inputSource;
|
const IKeyInputSource* _keyInputSource;
|
||||||
|
const ITouchInputSource* _touchInputSource;
|
||||||
|
|
||||||
InputKey _inputBuffer[4];
|
InputKey _keyInputBuffer[4];
|
||||||
|
Point _touchInputBuffer[4];
|
||||||
u8 _inputBufferReadPtr;
|
u8 _inputBufferReadPtr;
|
||||||
u8 _inputBufferWritePtr;
|
u8 _inputBufferWritePtr;
|
||||||
};
|
};
|
||||||
|
|||||||
24
arm9/source/gui/input/TouchInputSource.h
Normal file
24
arm9/source/gui/input/TouchInputSource.h
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "common.h"
|
||||||
|
#include <nds/input.h>
|
||||||
|
#include "ITouchInputSource.h"
|
||||||
|
#include "sharedMemory.h"
|
||||||
|
|
||||||
|
/// @brief Input source from the physical DS touch screen.
|
||||||
|
class TouchInputSource : public ITouchInputSource
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
bool Sample(Point& touchPosition) const override
|
||||||
|
{
|
||||||
|
if (SHARED_KEY_XY & (1 << 6))
|
||||||
|
{
|
||||||
|
touchPosition = Point(0, 0);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
touchPosition = Point(SHARED_TOUCH_X, SHARED_TOUCH_Y);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -3,15 +3,17 @@
|
|||||||
|
|
||||||
class Label2DView : public LabelView
|
class Label2DView : public LabelView
|
||||||
{
|
{
|
||||||
public:
|
SHARED_ONLY(Label2DView)
|
||||||
Label2DView(u32 width, u32 height, u32 maxStringLength, const nft2_header_t* font)
|
|
||||||
: LabelView(width, height, maxStringLength, font, false) { }
|
|
||||||
|
|
||||||
|
public:
|
||||||
void InitVram(const VramContext& vramContext) override;
|
void InitVram(const VramContext& vramContext) override;
|
||||||
void Draw(GraphicsContext& graphicsContext) override;
|
void Draw(GraphicsContext& graphicsContext) override;
|
||||||
void VBlank() override;
|
void VBlank() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
Label2DView(u32 width, u32 height, u32 maxStringLength, const nft2_header_t* font)
|
||||||
|
: LabelView(width, height, maxStringLength, font, false) { }
|
||||||
|
|
||||||
void UpdateTileBuffer() override;
|
void UpdateTileBuffer() override;
|
||||||
|
|
||||||
bool _tileBufferUpdated = false;
|
bool _tileBufferUpdated = false;
|
||||||
|
|||||||
@@ -12,6 +12,11 @@ Label3DView::Label3DView(u32 width, u32 height, u32 maxStringLength, const nft2_
|
|||||||
: LabelView(width, height, maxStringLength, font, true)
|
: LabelView(width, height, maxStringLength, font, true)
|
||||||
, _vblankTextureLoader(vblankTextureLoader) { }
|
, _vblankTextureLoader(vblankTextureLoader) { }
|
||||||
|
|
||||||
|
Label3DView::~Label3DView()
|
||||||
|
{
|
||||||
|
_vblankTextureLoader->CancelLoad(_textureLoadRequest);
|
||||||
|
}
|
||||||
|
|
||||||
void Label3DView::InitVram(const VramContext& vramContext)
|
void Label3DView::InitVram(const VramContext& vramContext)
|
||||||
{
|
{
|
||||||
const auto texVramManager = vramContext.GetTexVramManager();
|
const auto texVramManager = vramContext.GetTexVramManager();
|
||||||
|
|||||||
@@ -4,14 +4,18 @@
|
|||||||
|
|
||||||
class alignas(32) Label3DView : public LabelView
|
class alignas(32) Label3DView : public LabelView
|
||||||
{
|
{
|
||||||
|
SHARED_ONLY(Label3DView)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Label3DView(u32 width, u32 height, u32 maxStringLength, const nft2_header_t* font,
|
~Label3DView() override;
|
||||||
VBlankTextureLoader* vblankTextureLoader);
|
|
||||||
|
|
||||||
void InitVram(const VramContext& vramContext) override;
|
void InitVram(const VramContext& vramContext) override;
|
||||||
void Draw(GraphicsContext& graphicsContext) override;
|
void Draw(GraphicsContext& graphicsContext) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
Label3DView(u32 width, u32 height, u32 maxStringLength, const nft2_header_t* font,
|
||||||
|
VBlankTextureLoader* vblankTextureLoader);
|
||||||
|
|
||||||
void UpdateTileBuffer() override;
|
void UpdateTileBuffer() override;
|
||||||
|
|
||||||
u32 _texVramOffset = 0;
|
u32 _texVramOffset = 0;
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
#include "gui/input/InputProvider.h"
|
#include "gui/input/InputProvider.h"
|
||||||
#include "RecyclerView.h"
|
#include "RecyclerView.h"
|
||||||
|
|
||||||
RecyclerView::RecyclerView(Private, int x, int y, int width, int height, Mode mode)
|
RecyclerView::RecyclerView(int x, int y, int width, int height, Mode mode)
|
||||||
: _width(width), _height(height), _mode(mode), _rows(0), _columns(0)
|
: _width(width), _height(height), _mode(mode), _rows(0), _columns(0)
|
||||||
, _viewPoolFreeCount(0), _viewPoolTotalCount(0)
|
, _viewPoolFreeCount(0), _viewPoolTotalCount(0)
|
||||||
, _xOffset(0), _yOffset(0), _xPadding(0), _yPadding(0)
|
, _xOffset(0), _yOffset(0), _xPadding(0), _yPadding(0)
|
||||||
@@ -341,6 +341,117 @@ bool RecyclerView::HandleInput(const InputProvider& inputProvider, FocusManager&
|
|||||||
return View::HandleInput(inputProvider, focusManager);
|
return View::HandleInput(inputProvider, focusManager);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RecyclerView::HandlePenDown(const Point& touchPoint, FocusManager& focusManager)
|
||||||
|
{
|
||||||
|
if (GetBounds().Contains(touchPoint))
|
||||||
|
{
|
||||||
|
_penDown = true;
|
||||||
|
_penDownPosition = touchPoint;
|
||||||
|
_hasScrollStarted = false;
|
||||||
|
_penDownScrollOffset = _scrollOffsetAnimator.GetValue();
|
||||||
|
|
||||||
|
for (u32 i = _viewPoolFreeCount; i < _viewPoolTotalCount; i++)
|
||||||
|
{
|
||||||
|
_viewPool[i].view->HandlePenDown(touchPoint, focusManager);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RecyclerView::HandlePenMove(const Point& touchPoint, FocusManager& focusManager)
|
||||||
|
{
|
||||||
|
if (!_penDown)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_hasScrollStarted)
|
||||||
|
{
|
||||||
|
for (u32 i = _viewPoolFreeCount; i < _viewPoolTotalCount; i++)
|
||||||
|
{
|
||||||
|
_viewPool[i].view->HandlePenMove(touchPoint, focusManager);
|
||||||
|
if (focusManager.GetCurrentFocus().GetPointer() == _viewPool[i].view.GetPointer())
|
||||||
|
{
|
||||||
|
SetSelectedItem(_viewPool[i].itemIdx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int dx = touchPoint.x - _penDownPosition.x;
|
||||||
|
int dy = touchPoint.y - _penDownPosition.y;
|
||||||
|
if (dx * dx + dy * dy > 7 * 7)
|
||||||
|
{
|
||||||
|
bool shouldScrollStart = (_mode == Mode::HorizontalGrid || _mode == Mode::HorizontalList)
|
||||||
|
? (std::abs(touchPoint.x - _penDownPosition.x) > std::abs(touchPoint.y - _penDownPosition.y))
|
||||||
|
: (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 < _viewPoolTotalCount; i++)
|
||||||
|
{
|
||||||
|
_viewPool[i].view->HandlePenUp(Point(-1, -1), focusManager);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int newScrollOffset;
|
||||||
|
if (_mode == Mode::HorizontalGrid || _mode == Mode::HorizontalList)
|
||||||
|
{
|
||||||
|
newScrollOffset = _penDownScrollOffset + touchPoint.x - _penDownPosition.x;
|
||||||
|
if (-newScrollOffset < 0)
|
||||||
|
{
|
||||||
|
newScrollOffset = 0;
|
||||||
|
_penDownScrollOffset = 0;
|
||||||
|
_penDownPosition.x = touchPoint.x;
|
||||||
|
}
|
||||||
|
else if (newScrollOffset < GetMaxScrollOffset())
|
||||||
|
{
|
||||||
|
newScrollOffset = GetMaxScrollOffset();
|
||||||
|
_penDownScrollOffset = newScrollOffset;
|
||||||
|
_penDownPosition.x = touchPoint.x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
newScrollOffset = _penDownScrollOffset + touchPoint.y - _penDownPosition.y;
|
||||||
|
if (-newScrollOffset < 0)
|
||||||
|
{
|
||||||
|
newScrollOffset = 0;
|
||||||
|
_penDownScrollOffset = 0;
|
||||||
|
_penDownPosition.y = touchPoint.y;
|
||||||
|
}
|
||||||
|
else if (newScrollOffset < GetMaxScrollOffset())
|
||||||
|
{
|
||||||
|
newScrollOffset = GetMaxScrollOffset();
|
||||||
|
_penDownScrollOffset = newScrollOffset;
|
||||||
|
_penDownPosition.y = touchPoint.y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SetScrollOffset(newScrollOffset, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RecyclerView::HandlePenUp(const Point& lastTouchPoint, FocusManager& focusManager)
|
||||||
|
{
|
||||||
|
for (u32 i = _viewPoolFreeCount; i < _viewPoolTotalCount; i++)
|
||||||
|
{
|
||||||
|
_viewPool[i].view->HandlePenUp(lastTouchPoint, focusManager);
|
||||||
|
if (focusManager.GetCurrentFocus().GetPointer() == _viewPool[i].view.GetPointer())
|
||||||
|
{
|
||||||
|
SetSelectedItem(_viewPool[i].itemIdx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_penDown = false;
|
||||||
|
}
|
||||||
|
|
||||||
Point RecyclerView::GetItemPosition(int itemIdx)
|
Point RecyclerView::GetItemPosition(int itemIdx)
|
||||||
{
|
{
|
||||||
int x = 0;
|
int x = 0;
|
||||||
|
|||||||
@@ -1,15 +1,14 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include "core/EnableSharedFromThis.h"
|
|
||||||
#include "View.h"
|
#include "View.h"
|
||||||
#include "RecyclerAdapter.h"
|
#include "RecyclerAdapter.h"
|
||||||
#include "gui/FocusManager.h"
|
#include "gui/FocusManager.h"
|
||||||
#include "animation/Animator.h"
|
#include "animation/Animator.h"
|
||||||
#include "RecyclerViewBase.h"
|
#include "RecyclerViewBase.h"
|
||||||
|
|
||||||
class RecyclerView : public RecyclerViewBase, public EnableSharedFromThis<RecyclerView>
|
class RecyclerView : public RecyclerViewBase
|
||||||
{
|
{
|
||||||
struct Private { explicit Private() = default; };
|
SHARED_ONLY(RecyclerView)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum class Mode
|
enum class Mode
|
||||||
@@ -24,13 +23,6 @@ public:
|
|||||||
VerticalGrid
|
VerticalGrid
|
||||||
};
|
};
|
||||||
|
|
||||||
RecyclerView(Private, int x, int y, int width, int height, Mode mode);
|
|
||||||
|
|
||||||
static SharedPtr<RecyclerView> CreateShared(int x, int y, int width, int height, Mode mode)
|
|
||||||
{
|
|
||||||
return SharedPtr<RecyclerView>::MakeShared(Private(), x, y, width, height, mode);
|
|
||||||
}
|
|
||||||
|
|
||||||
~RecyclerView();
|
~RecyclerView();
|
||||||
|
|
||||||
void SetAdapter(SharedPtr<const RecyclerAdapter> adapter, int initialSelectedIndex = 0) override;
|
void SetAdapter(SharedPtr<const RecyclerAdapter> adapter, int initialSelectedIndex = 0) override;
|
||||||
@@ -47,6 +39,9 @@ public:
|
|||||||
SharedPtr<View> MoveFocus(const SharedPtr<View>& currentFocus, FocusMoveDirection direction, View* source) override;
|
SharedPtr<View> MoveFocus(const SharedPtr<View>& currentFocus, FocusMoveDirection direction, View* source) override;
|
||||||
|
|
||||||
bool HandleInput(const InputProvider& inputProvider, FocusManager& focusManager) 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 Focus(FocusManager& focusManager) override
|
void Focus(FocusManager& focusManager) override
|
||||||
{
|
{
|
||||||
@@ -107,6 +102,12 @@ private:
|
|||||||
int _curRangeStart;
|
int _curRangeStart;
|
||||||
int _curRangeLength;
|
int _curRangeLength;
|
||||||
Animator<int> _scrollOffsetAnimator;
|
Animator<int> _scrollOffsetAnimator;
|
||||||
|
bool _penDown = false;
|
||||||
|
Point _penDownPosition = Point(0, 0);
|
||||||
|
bool _hasScrollStarted = false;
|
||||||
|
int _penDownScrollOffset = 0;
|
||||||
|
|
||||||
|
RecyclerView(int x, int y, int width, int height, Mode mode);
|
||||||
|
|
||||||
void UpdatePosition(ViewPoolEntry& viewPoolEntry);
|
void UpdatePosition(ViewPoolEntry& viewPoolEntry);
|
||||||
ViewPoolEntry* GetViewPoolEntryByItemIndex(int itemIdx);
|
ViewPoolEntry* GetViewPoolEntryByItemIndex(int itemIdx);
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#include "core/math/Point.h"
|
#include "core/math/Point.h"
|
||||||
#include "core/math/Rectangle.h"
|
#include "core/math/Rectangle.h"
|
||||||
#include "core/SharedPtr.h"
|
#include "core/SharedPtr.h"
|
||||||
|
#include "core/EnableSharedFromThis.h"
|
||||||
#include "../FocusManager.h"
|
#include "../FocusManager.h"
|
||||||
#include "../FocusMoveDirection.h"
|
#include "../FocusMoveDirection.h"
|
||||||
|
|
||||||
@@ -11,7 +12,7 @@ class VramContext;
|
|||||||
class InputProvider;
|
class InputProvider;
|
||||||
|
|
||||||
/// @brief Base class for views.
|
/// @brief Base class for views.
|
||||||
class View
|
class View : public EnableSharedFromThis<View>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/// @brief Link used for views that contain other views.
|
/// @brief Link used for views that contain other views.
|
||||||
@@ -58,6 +59,21 @@ public:
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @brief Handles a pen down event.
|
||||||
|
/// @param touchPoint The touch point.
|
||||||
|
/// @param focusManager The focus manager.
|
||||||
|
virtual void HandlePenDown(const Point& touchPoint, FocusManager& focusManager) { }
|
||||||
|
|
||||||
|
/// @brief Handles a pen move event.
|
||||||
|
/// @param touchPoint The touch point.
|
||||||
|
/// @param focusManager The focus manager.
|
||||||
|
virtual void HandlePenMove(const Point& touchPoint, FocusManager& focusManager) { }
|
||||||
|
|
||||||
|
/// @brief Handles a pen up event.
|
||||||
|
/// @param lastTouchPoint The last touch point.
|
||||||
|
/// @param focusManager The focus manager.
|
||||||
|
virtual void HandlePenUp(const Point& lastTouchPoint, FocusManager& focusManager) { }
|
||||||
|
|
||||||
/// @brief Gets the bounds of the view.
|
/// @brief Gets the bounds of the view.
|
||||||
/// @return The bounds of the view.
|
/// @return The bounds of the view.
|
||||||
virtual Rectangle GetBounds() const = 0;
|
virtual Rectangle GetBounds() const = 0;
|
||||||
|
|||||||
58
arm9/source/gui/views/ViewContainer.cpp
Normal file
58
arm9/source/gui/views/ViewContainer.cpp
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
#include "common.h"
|
||||||
|
#include "ViewContainer.h"
|
||||||
|
|
||||||
|
void ViewContainer::InitVram(const VramContext& vramContext)
|
||||||
|
{
|
||||||
|
for (auto& view : _children)
|
||||||
|
{
|
||||||
|
view.InitVram(vramContext);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ViewContainer::Update()
|
||||||
|
{
|
||||||
|
for (auto& view : _children)
|
||||||
|
{
|
||||||
|
view.Update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ViewContainer::Draw(GraphicsContext& graphicsContext)
|
||||||
|
{
|
||||||
|
for (auto& view : _children)
|
||||||
|
{
|
||||||
|
view.Draw(graphicsContext);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ViewContainer::VBlank()
|
||||||
|
{
|
||||||
|
for (auto& view : _children)
|
||||||
|
{
|
||||||
|
view.VBlank();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ViewContainer::HandlePenDown(const Point& touchPoint, FocusManager& focusManager)
|
||||||
|
{
|
||||||
|
for (auto& view : _children)
|
||||||
|
{
|
||||||
|
view.HandlePenDown(touchPoint, focusManager);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ViewContainer::HandlePenMove(const Point& touchPoint, FocusManager& focusManager)
|
||||||
|
{
|
||||||
|
for (auto& view : _children)
|
||||||
|
{
|
||||||
|
view.HandlePenMove(touchPoint, focusManager);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ViewContainer::HandlePenUp(const Point& lastTouchPoint, FocusManager& focusManager)
|
||||||
|
{
|
||||||
|
for (auto& view : _children)
|
||||||
|
{
|
||||||
|
view.HandlePenUp(lastTouchPoint, focusManager);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,37 +6,13 @@
|
|||||||
class ViewContainer : public View
|
class ViewContainer : public View
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void InitVram(const VramContext& vramContext) override
|
void InitVram(const VramContext& vramContext) override;
|
||||||
{
|
void Update() override;
|
||||||
for (auto& view : _children)
|
void Draw(GraphicsContext& graphicsContext) override;
|
||||||
{
|
void VBlank() override;
|
||||||
view.InitVram(vramContext);
|
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 Update() override
|
|
||||||
{
|
|
||||||
for (auto& view : _children)
|
|
||||||
{
|
|
||||||
view.Update();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Draw(GraphicsContext& graphicsContext) override
|
|
||||||
{
|
|
||||||
for (auto& view : _children)
|
|
||||||
{
|
|
||||||
view.Draw(graphicsContext);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void VBlank() override
|
|
||||||
{
|
|
||||||
for (auto& view : _children)
|
|
||||||
{
|
|
||||||
view.VBlank();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/// @brief Adds a child to the head of the list.
|
/// @brief Adds a child to the head of the list.
|
||||||
@@ -55,6 +31,14 @@ protected:
|
|||||||
view->SetParent(this);
|
view->SetParent(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @brief Removes a child from the list.
|
||||||
|
/// @param view The child to remove.
|
||||||
|
void RemoveChild(View* view)
|
||||||
|
{
|
||||||
|
_children.Remove(view);
|
||||||
|
view->SetParent(nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
LinkedList<View, &View::listLink> _children;
|
LinkedList<View, &View::listLink> _children;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#include "core/task/TaskQueue.h"
|
#include "core/task/TaskQueue.h"
|
||||||
#include "../views/BannerListItemView.h"
|
#include "../views/BannerListItemView.h"
|
||||||
#include "../Theme/IRomBrowserViewFactory.h"
|
#include "../Theme/IRomBrowserViewFactory.h"
|
||||||
|
#include "romBrowser/viewModels/RomBrowserItemViewModel.h"
|
||||||
#include "BannerListFileRecyclerAdapter.h"
|
#include "BannerListFileRecyclerAdapter.h"
|
||||||
|
|
||||||
void BannerListFileRecyclerAdapter::GetViewSize(int& width, int& height) const
|
void BannerListFileRecyclerAdapter::GetViewSize(int& width, int& height) const
|
||||||
@@ -13,7 +14,8 @@ void BannerListFileRecyclerAdapter::GetViewSize(int& width, int& height) const
|
|||||||
|
|
||||||
SharedPtr<View> BannerListFileRecyclerAdapter::CreateView() const
|
SharedPtr<View> BannerListFileRecyclerAdapter::CreateView() const
|
||||||
{
|
{
|
||||||
return _romBrowserViewFactory->CreateBannerListItemView(_vblankTextureLoader);
|
return _romBrowserViewFactory->CreateBannerListItemView(
|
||||||
|
std::make_unique<RomBrowserItemViewModel>(_romBrowserController), _vblankTextureLoader);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BannerListFileRecyclerAdapter::BindView(SharedPtr<View> view, int index) const
|
void BannerListFileRecyclerAdapter::BindView(SharedPtr<View> view, int index) const
|
||||||
@@ -27,6 +29,7 @@ TaskResult<void> BannerListFileRecyclerAdapter::BindView(SharedPtr<View> view, i
|
|||||||
const InternalFileInfo* internalFileInfo, const vu8& cancelRequested) const
|
const InternalFileInfo* internalFileInfo, const vu8& cancelRequested) const
|
||||||
{
|
{
|
||||||
auto listItemView = static_cast<BannerListItemView*>(view.GetPointer());
|
auto listItemView = static_cast<BannerListItemView*>(view.GetPointer());
|
||||||
|
listItemView->GetViewModel().SetIndex(index);
|
||||||
const auto& fileInfo = _fileInfoManager->GetItem(index);
|
const auto& fileInfo = _fileInfoManager->GetItem(index);
|
||||||
bool fileNameAsTitle = true;
|
bool fileNameAsTitle = true;
|
||||||
if (internalFileInfo)
|
if (internalFileInfo)
|
||||||
@@ -65,12 +68,20 @@ TaskResult<void> BannerListFileRecyclerAdapter::BindView(SharedPtr<View> view, i
|
|||||||
return TaskResult<void>::Completed();
|
return TaskResult<void>::Completed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BannerListFileRecyclerAdapter::SetQueueTask(const SharedPtr<View>& view, QueueTask<void> queueTask) const
|
||||||
|
{
|
||||||
|
auto listItemView = static_cast<BannerListItemView*>(view.GetPointer());
|
||||||
|
listItemView->GetViewModel().SetQueueTask(std::move(queueTask));
|
||||||
|
}
|
||||||
|
|
||||||
void BannerListFileRecyclerAdapter::ReleaseView(SharedPtr<View> view, int index) const
|
void BannerListFileRecyclerAdapter::ReleaseView(SharedPtr<View> view, int index) const
|
||||||
{
|
{
|
||||||
LOG_DEBUG("Releasing %d\n", index);
|
LOG_DEBUG("Releasing %d\n", index);
|
||||||
auto listItemView = static_cast<BannerListItemView*>(view.GetPointer());
|
auto listItemView = static_cast<BannerListItemView*>(view.GetPointer());
|
||||||
listItemView->SetIcon(nullptr);
|
listItemView->SetIcon(nullptr);
|
||||||
listItemView->SetGameTitle(u"");
|
listItemView->SetGameTitle(u"");
|
||||||
|
listItemView->GetViewModel().SetIndex(-1);
|
||||||
|
listItemView->GetViewModel().CancelQueueTask();
|
||||||
_fileInfoManager->ReleaseFileInfo(index);
|
_fileInfoManager->ReleaseFileInfo(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,11 +8,11 @@ class IRomBrowserViewFactory;
|
|||||||
class BannerListFileRecyclerAdapter : public FileRecyclerAdapter
|
class BannerListFileRecyclerAdapter : public FileRecyclerAdapter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
BannerListFileRecyclerAdapter(FileInfoManager* fileInfoManager,
|
BannerListFileRecyclerAdapter(IRomBrowserController* romBrowserController, FileInfoManager* fileInfoManager,
|
||||||
TaskQueueBase* taskQueue, const IThemeFileIconFactory* themeFileIconFactory,
|
TaskQueueBase* taskQueue, const IThemeFileIconFactory* themeFileIconFactory,
|
||||||
const IRomBrowserViewFactory* romBrowserViewFactory,
|
const IRomBrowserViewFactory* romBrowserViewFactory,
|
||||||
VBlankTextureLoader* vblankTextureLoader)
|
VBlankTextureLoader* vblankTextureLoader)
|
||||||
: FileRecyclerAdapter(fileInfoManager, taskQueue, themeFileIconFactory)
|
: FileRecyclerAdapter(romBrowserController, fileInfoManager, taskQueue, themeFileIconFactory)
|
||||||
, _romBrowserViewFactory(romBrowserViewFactory)
|
, _romBrowserViewFactory(romBrowserViewFactory)
|
||||||
, _vblankTextureLoader(vblankTextureLoader) { }
|
, _vblankTextureLoader(vblankTextureLoader) { }
|
||||||
|
|
||||||
@@ -30,4 +30,5 @@ private:
|
|||||||
|
|
||||||
TaskResult<void> BindView(SharedPtr<View> view, int index,
|
TaskResult<void> BindView(SharedPtr<View> view, int index,
|
||||||
const InternalFileInfo* internalFileInfo, const vu8& cancelRequested) const override;
|
const InternalFileInfo* internalFileInfo, const vu8& cancelRequested) const override;
|
||||||
|
void SetQueueTask(const SharedPtr<View>& view, QueueTask<void> queueTask) const override;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -15,13 +15,15 @@ void CoverFlowFileRecyclerAdapter::GetViewSize(int& width, int& height) const
|
|||||||
|
|
||||||
SharedPtr<View> CoverFlowFileRecyclerAdapter::CreateView() const
|
SharedPtr<View> CoverFlowFileRecyclerAdapter::CreateView() const
|
||||||
{
|
{
|
||||||
return SharedPtr<CoverView>::MakeShared(_vblankTextureLoader);
|
return CoverView::CreateShared(
|
||||||
|
std::make_unique<RomBrowserItemViewModel>(_romBrowserController), _vblankTextureLoader);
|
||||||
}
|
}
|
||||||
|
|
||||||
TaskResult<void> CoverFlowFileRecyclerAdapter::BindView(SharedPtr<View> view, int index,
|
TaskResult<void> CoverFlowFileRecyclerAdapter::BindView(SharedPtr<View> view, int index,
|
||||||
const InternalFileInfo* internalFileInfo, const vu8& cancelRequested) const
|
const InternalFileInfo* internalFileInfo, const vu8& cancelRequested) const
|
||||||
{
|
{
|
||||||
auto coverView = static_cast<CoverView*>(view.GetPointer());
|
auto coverView = static_cast<CoverView*>(view.GetPointer());
|
||||||
|
coverView->GetViewModel().SetIndex(index);
|
||||||
auto cover = _fileInfoManager->GetFileCover(index);
|
auto cover = _fileInfoManager->GetFileCover(index);
|
||||||
if (cancelRequested)
|
if (cancelRequested)
|
||||||
{
|
{
|
||||||
@@ -39,11 +41,19 @@ TaskResult<void> CoverFlowFileRecyclerAdapter::BindView(SharedPtr<View> view, in
|
|||||||
return TaskResult<void>::Completed();
|
return TaskResult<void>::Completed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CoverFlowFileRecyclerAdapter::SetQueueTask(const SharedPtr<View>& view, QueueTask<void> queueTask) const
|
||||||
|
{
|
||||||
|
auto coverView = static_cast<CoverView*>(view.GetPointer());
|
||||||
|
coverView->GetViewModel().SetQueueTask(std::move(queueTask));
|
||||||
|
}
|
||||||
|
|
||||||
void CoverFlowFileRecyclerAdapter::ReleaseView(SharedPtr<View> view, int index) const
|
void CoverFlowFileRecyclerAdapter::ReleaseView(SharedPtr<View> view, int index) const
|
||||||
{
|
{
|
||||||
LOG_DEBUG("Releasing %d\n", index);
|
LOG_DEBUG("Releasing %d\n", index);
|
||||||
auto coverView = static_cast<CoverView*>(view.GetPointer());
|
auto coverView = static_cast<CoverView*>(view.GetPointer());
|
||||||
coverView->ClearCover();
|
coverView->ClearCover();
|
||||||
|
coverView->GetViewModel().SetIndex(-1);
|
||||||
|
coverView->GetViewModel().CancelQueueTask();
|
||||||
_fileInfoManager->ReleaseFileInfo(index);
|
_fileInfoManager->ReleaseFileInfo(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,12 +8,12 @@ class ICoverRepository;
|
|||||||
class CoverFlowFileRecyclerAdapter : public FileRecyclerAdapter
|
class CoverFlowFileRecyclerAdapter : public FileRecyclerAdapter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CoverFlowFileRecyclerAdapter(FileInfoManager* fileInfoManager,
|
CoverFlowFileRecyclerAdapter(IRomBrowserController* romBrowserController, FileInfoManager* fileInfoManager,
|
||||||
TaskQueueBase* taskQueue, const IThemeFileIconFactory* themeFileIconFactory,
|
TaskQueueBase* taskQueue, const IThemeFileIconFactory* themeFileIconFactory,
|
||||||
const IRomBrowserViewFactory* romBrowserViewFactory,
|
const IRomBrowserViewFactory* romBrowserViewFactory,
|
||||||
VBlankTextureLoader* vblankTextureLoader,
|
VBlankTextureLoader* vblankTextureLoader,
|
||||||
const ICoverRepository* coverRepository)
|
const ICoverRepository* coverRepository)
|
||||||
: FileRecyclerAdapter(fileInfoManager, taskQueue, themeFileIconFactory)
|
: FileRecyclerAdapter(romBrowserController, fileInfoManager, taskQueue, themeFileIconFactory)
|
||||||
, _romBrowserViewFactory(romBrowserViewFactory)
|
, _romBrowserViewFactory(romBrowserViewFactory)
|
||||||
, _vblankTextureLoader(vblankTextureLoader)
|
, _vblankTextureLoader(vblankTextureLoader)
|
||||||
, _coverRepository(coverRepository) { }
|
, _coverRepository(coverRepository) { }
|
||||||
@@ -31,4 +31,5 @@ private:
|
|||||||
|
|
||||||
TaskResult<void> BindView(SharedPtr<View> view, int index,
|
TaskResult<void> BindView(SharedPtr<View> view, int index,
|
||||||
const InternalFileInfo* internalFileInfo, const vu8& cancelRequested) const override;
|
const InternalFileInfo* internalFileInfo, const vu8& cancelRequested) const override;
|
||||||
|
void SetQueueTask(const SharedPtr<View>& view, QueueTask<void> queueTask) const override;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#include "core/task/TaskQueue.h"
|
#include "core/task/TaskQueue.h"
|
||||||
#include "../views/IconGridItemView.h"
|
#include "../views/IconGridItemView.h"
|
||||||
#include "../Theme/IRomBrowserViewFactory.h"
|
#include "../Theme/IRomBrowserViewFactory.h"
|
||||||
|
#include "romBrowser/viewModels/RomBrowserItemViewModel.h"
|
||||||
#include "IconGridFileRecyclerAdapter.h"
|
#include "IconGridFileRecyclerAdapter.h"
|
||||||
|
|
||||||
void IconGridFileRecyclerAdapter::GetViewSize(int& width, int& height) const
|
void IconGridFileRecyclerAdapter::GetViewSize(int& width, int& height) const
|
||||||
@@ -13,7 +14,7 @@ void IconGridFileRecyclerAdapter::GetViewSize(int& width, int& height) const
|
|||||||
|
|
||||||
SharedPtr<View> IconGridFileRecyclerAdapter::CreateView() const
|
SharedPtr<View> IconGridFileRecyclerAdapter::CreateView() const
|
||||||
{
|
{
|
||||||
return _romBrowserViewFactory->CreateIconGridItemView();
|
return _romBrowserViewFactory->CreateIconGridItemView(std::make_unique<RomBrowserItemViewModel>(_romBrowserController));
|
||||||
}
|
}
|
||||||
|
|
||||||
void IconGridFileRecyclerAdapter::BindView(SharedPtr<View> view, int index) const
|
void IconGridFileRecyclerAdapter::BindView(SharedPtr<View> view, int index) const
|
||||||
@@ -27,6 +28,7 @@ TaskResult<void> IconGridFileRecyclerAdapter::BindView(SharedPtr<View> view, int
|
|||||||
const InternalFileInfo* internalFileInfo, const vu8& cancelRequested) const
|
const InternalFileInfo* internalFileInfo, const vu8& cancelRequested) const
|
||||||
{
|
{
|
||||||
auto iconGridItemView = static_cast<IconGridItemView*>(view.GetPointer());
|
auto iconGridItemView = static_cast<IconGridItemView*>(view.GetPointer());
|
||||||
|
iconGridItemView->GetViewModel().SetIndex(index);
|
||||||
auto icon = internalFileInfo ? internalFileInfo->CreateGameIcon() : nullptr;
|
auto icon = internalFileInfo ? internalFileInfo->CreateGameIcon() : nullptr;
|
||||||
if (!icon)
|
if (!icon)
|
||||||
{
|
{
|
||||||
@@ -54,11 +56,19 @@ TaskResult<void> IconGridFileRecyclerAdapter::BindView(SharedPtr<View> view, int
|
|||||||
return TaskResult<void>::Completed();
|
return TaskResult<void>::Completed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IconGridFileRecyclerAdapter::SetQueueTask(const SharedPtr<View>& view, QueueTask<void> queueTask) const
|
||||||
|
{
|
||||||
|
auto iconGridItemView = static_cast<IconGridItemView*>(view.GetPointer());
|
||||||
|
iconGridItemView->GetViewModel().SetQueueTask(std::move(queueTask));
|
||||||
|
}
|
||||||
|
|
||||||
void IconGridFileRecyclerAdapter::ReleaseView(SharedPtr<View> view, int index) const
|
void IconGridFileRecyclerAdapter::ReleaseView(SharedPtr<View> view, int index) const
|
||||||
{
|
{
|
||||||
LOG_DEBUG("Releasing %d\n", index);
|
LOG_DEBUG("Releasing %d\n", index);
|
||||||
auto iconGridItemView = static_cast<IconGridItemView*>(view.GetPointer());
|
auto iconGridItemView = static_cast<IconGridItemView*>(view.GetPointer());
|
||||||
iconGridItemView->SetIcon(nullptr);
|
iconGridItemView->SetIcon(nullptr);
|
||||||
|
iconGridItemView->GetViewModel().SetIndex(-1);
|
||||||
|
iconGridItemView->GetViewModel().CancelQueueTask();
|
||||||
_fileInfoManager->ReleaseFileInfo(index);
|
_fileInfoManager->ReleaseFileInfo(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,10 +7,10 @@ class IRomBrowserViewFactory;
|
|||||||
class IconGridFileRecyclerAdapter : public FileRecyclerAdapter
|
class IconGridFileRecyclerAdapter : public FileRecyclerAdapter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
IconGridFileRecyclerAdapter(FileInfoManager* fileInfoManager,
|
IconGridFileRecyclerAdapter(IRomBrowserController* romBrowserController, FileInfoManager* fileInfoManager,
|
||||||
TaskQueueBase* taskQueue, const IThemeFileIconFactory* themeFileIconFactory,
|
TaskQueueBase* taskQueue, const IThemeFileIconFactory* themeFileIconFactory,
|
||||||
const IRomBrowserViewFactory* romBrowserViewFactory)
|
const IRomBrowserViewFactory* romBrowserViewFactory)
|
||||||
: FileRecyclerAdapter(fileInfoManager, taskQueue, themeFileIconFactory)
|
: FileRecyclerAdapter(romBrowserController, fileInfoManager, taskQueue, themeFileIconFactory)
|
||||||
, _romBrowserViewFactory(romBrowserViewFactory) { }
|
, _romBrowserViewFactory(romBrowserViewFactory) { }
|
||||||
|
|
||||||
void GetViewSize(int& width, int& height) const override;
|
void GetViewSize(int& width, int& height) const override;
|
||||||
@@ -26,4 +26,5 @@ private:
|
|||||||
|
|
||||||
TaskResult<void> BindView(SharedPtr<View> view, int index,
|
TaskResult<void> BindView(SharedPtr<View> view, int index,
|
||||||
const InternalFileInfo* internalFileInfo, const vu8& cancelRequested) const override;
|
const InternalFileInfo* internalFileInfo, const vu8& cancelRequested) const override;
|
||||||
|
void SetQueueTask(const SharedPtr<View>& view, QueueTask<void> queueTask) const override;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ public:
|
|||||||
|
|
||||||
bool IsVertical() const override { return true; }
|
bool IsVertical() const override { return true; }
|
||||||
|
|
||||||
std::unique_ptr<AppBarView> CreateAppBarView(const IRomBrowserViewFactory* romBrowserViewFactory,
|
SharedPtr<AppBarView> CreateAppBarView(const IRomBrowserViewFactory* romBrowserViewFactory,
|
||||||
int startButtonCount, int endButtonCount) const override
|
int startButtonCount, int endButtonCount) const override
|
||||||
{
|
{
|
||||||
return romBrowserViewFactory->CreateAppBarView(0, 0,
|
return romBrowserViewFactory->CreateAppBarView(0, 0,
|
||||||
@@ -29,7 +29,7 @@ public:
|
|||||||
RomBrowserViewModel* viewModel, const IThemeFileIconFactory* themeFileIconFactory,
|
RomBrowserViewModel* viewModel, const IThemeFileIconFactory* themeFileIconFactory,
|
||||||
const IRomBrowserViewFactory* romBrowserViewFactory, VBlankTextureLoader* vblankTextureLoader) const override
|
const IRomBrowserViewFactory* romBrowserViewFactory, VBlankTextureLoader* vblankTextureLoader) const override
|
||||||
{
|
{
|
||||||
return SharedPtr<BannerListFileRecyclerAdapter>::MakeShared(
|
return SharedPtr<BannerListFileRecyclerAdapter>::MakeShared(viewModel->GetRomBrowserController(),
|
||||||
&viewModel->GetFileInfoManager(), viewModel->GetIoTaskQueue(), themeFileIconFactory,
|
&viewModel->GetFileInfoManager(), viewModel->GetIoTaskQueue(), themeFileIconFactory,
|
||||||
romBrowserViewFactory, vblankTextureLoader);
|
romBrowserViewFactory, vblankTextureLoader);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ class RomBrowserDisplayMode
|
|||||||
public:
|
public:
|
||||||
virtual bool IsVertical() const = 0;
|
virtual bool IsVertical() const = 0;
|
||||||
virtual bool ShowCoverOnTopScreen() const { return true; }
|
virtual bool ShowCoverOnTopScreen() const { return true; }
|
||||||
virtual std::unique_ptr<AppBarView> CreateAppBarView(const IRomBrowserViewFactory* romBrowserViewFactory,
|
virtual SharedPtr<AppBarView> CreateAppBarView(const IRomBrowserViewFactory* romBrowserViewFactory,
|
||||||
int startButtonCount, int endButtonCount) const = 0;
|
int startButtonCount, int endButtonCount) const = 0;
|
||||||
virtual SharedPtr<RecyclerViewBase> CreateRecyclerView(const IRomBrowserViewFactory* romBrowserViewFactory) const = 0;
|
virtual SharedPtr<RecyclerViewBase> CreateRecyclerView(const IRomBrowserViewFactory* romBrowserViewFactory) const = 0;
|
||||||
virtual SharedPtr<FileRecyclerAdapter> CreateRecyclerAdapter(
|
virtual SharedPtr<FileRecyclerAdapter> CreateRecyclerAdapter(
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ public:
|
|||||||
bool IsVertical() const override { return false; }
|
bool IsVertical() const override { return false; }
|
||||||
bool ShowCoverOnTopScreen() const override { return false; }
|
bool ShowCoverOnTopScreen() const override { return false; }
|
||||||
|
|
||||||
std::unique_ptr<AppBarView> CreateAppBarView(const IRomBrowserViewFactory* romBrowserViewFactory,
|
SharedPtr<AppBarView> CreateAppBarView(const IRomBrowserViewFactory* romBrowserViewFactory,
|
||||||
int startButtonCount, int endButtonCount) const override
|
int startButtonCount, int endButtonCount) const override
|
||||||
{
|
{
|
||||||
return romBrowserViewFactory->CreateAppBarView(0, 0,
|
return romBrowserViewFactory->CreateAppBarView(0, 0,
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ public:
|
|||||||
|
|
||||||
bool IsVertical() const override { return false; }
|
bool IsVertical() const override { return false; }
|
||||||
|
|
||||||
std::unique_ptr<AppBarView> CreateAppBarView(const IRomBrowserViewFactory* romBrowserViewFactory,
|
SharedPtr<AppBarView> CreateAppBarView(const IRomBrowserViewFactory* romBrowserViewFactory,
|
||||||
int startButtonCount, int endButtonCount) const override
|
int startButtonCount, int endButtonCount) const override
|
||||||
{
|
{
|
||||||
return romBrowserViewFactory->CreateAppBarView(0, 0,
|
return romBrowserViewFactory->CreateAppBarView(0, 0,
|
||||||
@@ -29,7 +29,7 @@ public:
|
|||||||
RomBrowserViewModel* viewModel, const IThemeFileIconFactory* themeFileIconFactory,
|
RomBrowserViewModel* viewModel, const IThemeFileIconFactory* themeFileIconFactory,
|
||||||
const IRomBrowserViewFactory* romBrowserViewFactory, VBlankTextureLoader* vblankTextureLoader) const override
|
const IRomBrowserViewFactory* romBrowserViewFactory, VBlankTextureLoader* vblankTextureLoader) const override
|
||||||
{
|
{
|
||||||
return SharedPtr<IconGridFileRecyclerAdapter>::MakeShared(
|
return SharedPtr<IconGridFileRecyclerAdapter>::MakeShared(viewModel->GetRomBrowserController(),
|
||||||
&viewModel->GetFileInfoManager(), viewModel->GetIoTaskQueue(),
|
&viewModel->GetFileInfoManager(), viewModel->GetIoTaskQueue(),
|
||||||
themeFileIconFactory, romBrowserViewFactory);
|
themeFileIconFactory, romBrowserViewFactory);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ public:
|
|||||||
|
|
||||||
bool IsVertical() const override { return true; }
|
bool IsVertical() const override { return true; }
|
||||||
|
|
||||||
std::unique_ptr<AppBarView> CreateAppBarView(const IRomBrowserViewFactory* romBrowserViewFactory,
|
SharedPtr<AppBarView> CreateAppBarView(const IRomBrowserViewFactory* romBrowserViewFactory,
|
||||||
int startButtonCount, int endButtonCount) const override
|
int startButtonCount, int endButtonCount) const override
|
||||||
{
|
{
|
||||||
return romBrowserViewFactory->CreateAppBarView(0, 0,
|
return romBrowserViewFactory->CreateAppBarView(0, 0,
|
||||||
@@ -29,7 +29,7 @@ public:
|
|||||||
RomBrowserViewModel* viewModel, const IThemeFileIconFactory* themeFileIconFactory,
|
RomBrowserViewModel* viewModel, const IThemeFileIconFactory* themeFileIconFactory,
|
||||||
const IRomBrowserViewFactory* romBrowserViewFactory, VBlankTextureLoader* vblankTextureLoader) const override
|
const IRomBrowserViewFactory* romBrowserViewFactory, VBlankTextureLoader* vblankTextureLoader) const override
|
||||||
{
|
{
|
||||||
return SharedPtr<IconGridFileRecyclerAdapter>::MakeShared(
|
return SharedPtr<IconGridFileRecyclerAdapter>::MakeShared(viewModel->GetRomBrowserController(),
|
||||||
&viewModel->GetFileInfoManager(), viewModel->GetIoTaskQueue(),
|
&viewModel->GetFileInfoManager(), viewModel->GetIoTaskQueue(),
|
||||||
themeFileIconFactory, romBrowserViewFactory);
|
themeFileIconFactory, romBrowserViewFactory);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,8 +11,14 @@ u32 FileRecyclerAdapter::GetItemCount() const
|
|||||||
void FileRecyclerAdapter::BindView(SharedPtr<View> view, int index) const
|
void FileRecyclerAdapter::BindView(SharedPtr<View> view, int index) const
|
||||||
{
|
{
|
||||||
LOG_DEBUG("Binding %d\n", index);
|
LOG_DEBUG("Binding %d\n", index);
|
||||||
_taskQueue->Enqueue([=, this] (const vu8& cancelRequested)
|
auto queueTask = _taskQueue->Enqueue([=, this] (const vu8& cancelRequested)
|
||||||
{
|
{
|
||||||
|
if (cancelRequested)
|
||||||
|
{
|
||||||
|
LOG_DEBUG("Task to load %d was canceled\n", index);
|
||||||
|
return TaskResult<void>::Canceled();
|
||||||
|
}
|
||||||
|
|
||||||
LOG_DEBUG("Started task to load %d\n", index);
|
LOG_DEBUG("Started task to load %d\n", index);
|
||||||
_fileInfoManager->LoadFileInfo(index);
|
_fileInfoManager->LoadFileInfo(index);
|
||||||
auto internalFileInfo = _fileInfoManager->GetInternalFileInfo(index);
|
auto internalFileInfo = _fileInfoManager->GetInternalFileInfo(index);
|
||||||
@@ -23,4 +29,5 @@ void FileRecyclerAdapter::BindView(SharedPtr<View> view, int index) const
|
|||||||
}
|
}
|
||||||
return BindView(view, index, internalFileInfo, cancelRequested);
|
return BindView(view, index, internalFileInfo, cancelRequested);
|
||||||
});
|
});
|
||||||
|
SetQueueTask(view, std::move(queueTask));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ class IVramManager;
|
|||||||
class InternalFileInfo;
|
class InternalFileInfo;
|
||||||
class IThemeFileIconFactory;
|
class IThemeFileIconFactory;
|
||||||
class VramContext;
|
class VramContext;
|
||||||
|
class IRomBrowserController;
|
||||||
|
|
||||||
class FileRecyclerAdapter : public RecyclerAdapter
|
class FileRecyclerAdapter : public RecyclerAdapter
|
||||||
{
|
{
|
||||||
@@ -22,16 +23,18 @@ public:
|
|||||||
virtual void InitVram(const VramContext& vramContext) { }
|
virtual void InitVram(const VramContext& vramContext) { }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
IRomBrowserController* _romBrowserController;
|
||||||
FileInfoManager* _fileInfoManager;
|
FileInfoManager* _fileInfoManager;
|
||||||
TaskQueueBase* _taskQueue;
|
TaskQueueBase* _taskQueue;
|
||||||
u32 _iconFrameCounter;
|
u32 _iconFrameCounter;
|
||||||
const IThemeFileIconFactory* _themeFileIconFactory;
|
const IThemeFileIconFactory* _themeFileIconFactory;
|
||||||
|
|
||||||
FileRecyclerAdapter(FileInfoManager* fileInfoManager, TaskQueueBase* taskQueue,
|
FileRecyclerAdapter(IRomBrowserController* romBrowserController, FileInfoManager* fileInfoManager,
|
||||||
const IThemeFileIconFactory* themeFileIconFactory)
|
TaskQueueBase* taskQueue, const IThemeFileIconFactory* themeFileIconFactory)
|
||||||
: _fileInfoManager(fileInfoManager), _taskQueue(taskQueue)
|
: _romBrowserController(romBrowserController), _fileInfoManager(fileInfoManager), _taskQueue(taskQueue)
|
||||||
, _iconFrameCounter(0), _themeFileIconFactory(themeFileIconFactory) { }
|
, _iconFrameCounter(0), _themeFileIconFactory(themeFileIconFactory) { }
|
||||||
|
|
||||||
virtual TaskResult<void> BindView(SharedPtr<View> view, int index,
|
virtual TaskResult<void> BindView(SharedPtr<View> view, int index,
|
||||||
const InternalFileInfo* internalFileInfo, const vu8& cancelRequested) const = 0;
|
const InternalFileInfo* internalFileInfo, const vu8& cancelRequested) const = 0;
|
||||||
|
virtual void SetQueueTask(const SharedPtr<View>& view, QueueTask<void> queueTask) const = 0;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -12,24 +12,26 @@ class VBlankTextureLoader;
|
|||||||
class RomBrowserViewModel;
|
class RomBrowserViewModel;
|
||||||
class IThemeFileIconFactory;
|
class IThemeFileIconFactory;
|
||||||
class FileRecyclerAdapter;
|
class FileRecyclerAdapter;
|
||||||
|
class RomBrowserItemViewModel;
|
||||||
|
|
||||||
class IRomBrowserViewFactory
|
class IRomBrowserViewFactory
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual ~IRomBrowserViewFactory() = 0;
|
virtual ~IRomBrowserViewFactory() = 0;
|
||||||
|
|
||||||
virtual SharedPtr<IconGridItemView> CreateIconGridItemView() const = 0;
|
virtual SharedPtr<IconGridItemView> CreateIconGridItemView(std::unique_ptr<RomBrowserItemViewModel> viewModel) const = 0;
|
||||||
virtual IconGridItemView::VramToken UploadIconGridItemViewGraphics(
|
virtual IconGridItemView::VramToken UploadIconGridItemViewGraphics(
|
||||||
const VramContext& vramContext) const { return IconGridItemView::VramToken(0); }
|
const VramContext& vramContext) const { return IconGridItemView::VramToken(0); }
|
||||||
|
|
||||||
virtual SharedPtr<BannerListItemView> CreateBannerListItemView(VBlankTextureLoader* vblankTextureLoader) const = 0;
|
virtual SharedPtr<BannerListItemView> CreateBannerListItemView(std::unique_ptr<RomBrowserItemViewModel> viewModel,
|
||||||
|
VBlankTextureLoader* vblankTextureLoader) const = 0;
|
||||||
virtual BannerListItemView::VramToken UploadBannerListItemViewGraphics(
|
virtual BannerListItemView::VramToken UploadBannerListItemViewGraphics(
|
||||||
const VramContext& vramContext) const { return BannerListItemView::VramToken(0); }
|
const VramContext& vramContext) const { return BannerListItemView::VramToken(0); }
|
||||||
|
|
||||||
virtual std::unique_ptr<AppBarView> CreateAppBarView(int x, int y, AppBarView::Orientation orientation,
|
virtual SharedPtr<AppBarView> CreateAppBarView(int x, int y, AppBarView::Orientation orientation,
|
||||||
int startButtonCount, int endButtonCount) const = 0;
|
int startButtonCount, int endButtonCount) const = 0;
|
||||||
|
|
||||||
virtual std::unique_ptr<BannerView> CreateFileInfoView() const = 0;
|
virtual SharedPtr<BannerView> CreateFileInfoView() const = 0;
|
||||||
|
|
||||||
virtual SharedPtr<RecyclerViewBase> CreateCoverFlowRecyclerView() const = 0;
|
virtual SharedPtr<RecyclerViewBase> CreateCoverFlowRecyclerView() const = 0;
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,8 @@
|
|||||||
#include "romBrowser/FileType/FileCover.h"
|
#include "romBrowser/FileType/FileCover.h"
|
||||||
#include "core/math/SinTable.h"
|
#include "core/math/SinTable.h"
|
||||||
#include "carouselMask.h"
|
#include "carouselMask.h"
|
||||||
|
#include "animation/Interpolator.h"
|
||||||
|
#include "gui/input/InputProvider.h"
|
||||||
#include "CarouselRecyclerView.h"
|
#include "CarouselRecyclerView.h"
|
||||||
|
|
||||||
#define COVER_SPACING 4
|
#define COVER_SPACING 4
|
||||||
@@ -41,8 +43,10 @@ void CarouselRecyclerView::Update()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int rangeStartIndex = GetSelectedItem() - 4;
|
_scrollAnimator.Update();
|
||||||
int rangeEndIndex = GetSelectedItem() + 1 + 4;
|
|
||||||
|
int rangeStartIndex = _scrollAnimator.GetValue().Int() - 4;
|
||||||
|
int rangeEndIndex = _scrollAnimator.GetValue().Int() + 1 + 4;
|
||||||
rangeStartIndex = std::clamp(rangeStartIndex, 0, (int)_itemCount - 1);
|
rangeStartIndex = std::clamp(rangeStartIndex, 0, (int)_itemCount - 1);
|
||||||
rangeEndIndex = std::clamp(rangeEndIndex, 0, (int)_itemCount);
|
rangeEndIndex = std::clamp(rangeEndIndex, 0, (int)_itemCount);
|
||||||
|
|
||||||
@@ -66,8 +70,7 @@ void CarouselRecyclerView::Update()
|
|||||||
|
|
||||||
for (u32 i = _viewPoolFreeCount; i < _viewPool.size(); i++)
|
for (u32 i = _viewPoolFreeCount; i < _viewPool.size(); i++)
|
||||||
{
|
{
|
||||||
_viewPoolEx[i].xPositionAnimator.Update();
|
UpdateItemPosition(i);
|
||||||
_viewPoolEx[i].widthAnimator.Update();
|
|
||||||
_viewPool[i].view->Update();
|
_viewPool[i].view->Update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -76,8 +79,8 @@ void CarouselRecyclerView::Draw(GraphicsContext& graphicsContext)
|
|||||||
{
|
{
|
||||||
for (u32 i = _viewPoolFreeCount; i < _viewPool.size(); i++)
|
for (u32 i = _viewPoolFreeCount; i < _viewPool.size(); i++)
|
||||||
{
|
{
|
||||||
fix32<12> x = (_viewPoolEx[i].xPositionAnimator.GetValue() + 0.5).Int();
|
fix32<12> x = (_viewPoolEx[i].xPosition + 0.5).Int();
|
||||||
fix32<12> width = (_viewPoolEx[i].widthAnimator.GetValue() + 0.5).Int();
|
fix32<12> width = (_viewPoolEx[i].width + 0.5).Int();
|
||||||
fix32<12> left = x;
|
fix32<12> left = x;
|
||||||
if (left < HORIZONTAL_PADDING)
|
if (left < HORIZONTAL_PADDING)
|
||||||
{
|
{
|
||||||
@@ -180,48 +183,179 @@ void CarouselRecyclerView::RenderRoundedCorners(GraphicsContext& graphicsContext
|
|||||||
Gx::End();
|
Gx::End();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CarouselRecyclerView::UpdateItemPosition(int viewPoolIndex, bool initial)
|
bool CarouselRecyclerView::HandleInput(const InputProvider& inputProvider, FocusManager& focusManager)
|
||||||
{
|
{
|
||||||
ViewPoolEntry* item = &_viewPool[viewPoolIndex];
|
if (_itemCount != 0 && inputProvider.Triggered(InputKey::L | InputKey::R))
|
||||||
ViewPoolEntryEx* itemEx = &_viewPoolEx[viewPoolIndex];
|
|
||||||
int selectedIndex = GetSelectedItem();
|
|
||||||
if (selectedIndex == -1)
|
|
||||||
{
|
{
|
||||||
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;
|
return View::HandleInput(inputProvider, focusManager);
|
||||||
fix32<12> width;
|
}
|
||||||
if (itemIndex < selectedIndex)
|
|
||||||
|
void CarouselRecyclerView::HandlePenDown(const Point& touchPoint, FocusManager& focusManager)
|
||||||
|
{
|
||||||
|
if (GetBounds().Contains(touchPoint))
|
||||||
{
|
{
|
||||||
x = SELECTED_COVER_X + (SMALL_COVER_WIDTH + COVER_SPACING) * (itemIndex - selectedIndex);
|
_penDown = true;
|
||||||
width = SMALL_COVER_WIDTH;
|
_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;
|
return;
|
||||||
width = NEXT_COVER_WIDTH;
|
|
||||||
}
|
}
|
||||||
else if (itemIndex > selectedIndex + 1)
|
|
||||||
|
if (!_hasScrollStarted)
|
||||||
{
|
{
|
||||||
x = NEXT_COVER_X + NEXT_COVER_WIDTH + COVER_SPACING
|
for (u32 i = _viewPoolFreeCount; i < _viewPool.size(); i++)
|
||||||
+ (SMALL_COVER_WIDTH + COVER_SPACING) * (itemIndex - selectedIndex - 2);
|
{
|
||||||
width = SMALL_COVER_WIDTH;
|
_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
|
else
|
||||||
{
|
{
|
||||||
x = SELECTED_COVER_X;
|
fix32<12> newScrollOffset = _penDownScrollOffset + fix32<12>(_penDownPosition.x - touchPoint.x) * (2.5 / COVER_WIDTH);
|
||||||
width = SELECTED_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)
|
if (initial)
|
||||||
{
|
{
|
||||||
itemEx->xPositionAnimator = Animator(x);
|
_scrollAnimator = Animator<fix32<12>>(itemIdx);
|
||||||
itemEx->widthAnimator = Animator(width);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
itemEx->xPositionAnimator.Goto(x, md::sys::motion::duration::medium4, &md::sys::motion::easing::standard);
|
_scrollAnimator.Goto(itemIdx, md::sys::motion::duration::medium4, &md::sys::motion::easing::standard);
|
||||||
itemEx->widthAnimator.Goto(width, 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
|
class CarouselRecyclerView : public CoverFlowRecyclerViewBase
|
||||||
{
|
{
|
||||||
struct Private { explicit Private() = default; };
|
SHARED_ONLY(CarouselRecyclerView)
|
||||||
|
|
||||||
public:
|
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);
|
static void UploadGraphics(const VramContext& vramContext);
|
||||||
|
|
||||||
void Update() override;
|
void Update() override;
|
||||||
void Draw(GraphicsContext &graphicsContext) 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:
|
private:
|
||||||
struct ViewPoolEntryEx
|
struct ViewPoolEntryEx
|
||||||
{
|
{
|
||||||
Animator<fix32<12>> xPositionAnimator;
|
fix32<12> xPosition;
|
||||||
Animator<fix32<12>> widthAnimator;
|
fix32<12> width;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::array<ViewPoolEntryEx, 10> _viewPoolEx;
|
std::array<ViewPoolEntryEx, 10> _viewPoolEx;
|
||||||
const MaterialColorScheme* _materialColorScheme;
|
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;
|
static u32 sMaskTextureVramOffset;
|
||||||
|
|
||||||
|
CarouselRecyclerView(const MaterialColorScheme* materialColorScheme)
|
||||||
|
: _materialColorScheme(materialColorScheme) { }
|
||||||
|
|
||||||
void RenderCoverMask(GraphicsContext& graphicsContext, fix32<12> left, fix32<12> right) const;
|
void RenderCoverMask(GraphicsContext& graphicsContext, fix32<12> left, fix32<12> right) const;
|
||||||
void RenderRoundedCorners(GraphicsContext& graphicsContext, fix32<12> x, fix32<12> width) 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
|
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++)
|
for (int i = 0; i < _startButtonCount + _endButtonCount; i++)
|
||||||
{
|
{
|
||||||
_buttons[i] = SharedPtr<IconButton2DView>::MakeShared(
|
_buttons[i] = IconButton2DView::CreateShared(
|
||||||
IconButtonView::Type::Standard,
|
IconButtonView::Type::Standard,
|
||||||
IconButtonView::State::NoToggle,
|
IconButtonView::State::NoToggle,
|
||||||
md::sys::color::inverseOnSurface,
|
md::sys::color::inverseOnSurface,
|
||||||
|
|||||||
@@ -3,9 +3,12 @@
|
|||||||
|
|
||||||
class MaterialAppBarView : public AppBarView
|
class MaterialAppBarView : public AppBarView
|
||||||
{
|
{
|
||||||
|
SHARED_ONLY(MaterialAppBarView)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
void InitVram(const VramContext& vramContext) override;
|
||||||
|
|
||||||
|
private:
|
||||||
MaterialAppBarView(int x, int y, Orientation orientation,
|
MaterialAppBarView(int x, int y, Orientation orientation,
|
||||||
int startButtonCount, int endButtonCount, const MaterialColorScheme* materialColorScheme);
|
int startButtonCount, int endButtonCount, const MaterialColorScheme* materialColorScheme);
|
||||||
|
|
||||||
void InitVram(const VramContext& vramContext) override;
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -18,12 +18,12 @@
|
|||||||
#include "gui/views/Label2DView.h"
|
#include "gui/views/Label2DView.h"
|
||||||
#include "MaterialBannerListItemView.h"
|
#include "MaterialBannerListItemView.h"
|
||||||
|
|
||||||
MaterialBannerListItemView::MaterialBannerListItemView(const MaterialColorScheme* materialColorScheme,
|
MaterialBannerListItemView::MaterialBannerListItemView(std::unique_ptr<RomBrowserItemViewModel> viewModel,
|
||||||
const IFontRepository* fontRepository)
|
const MaterialColorScheme* materialColorScheme, const IFontRepository* fontRepository)
|
||||||
: BannerListItemView(
|
: BannerListItemView(std::move(viewModel),
|
||||||
std::make_unique<Label2DView>(160, 16, 50, fontRepository->GetFont(FontType::Medium10)),
|
Label2DView::CreateShared(160, 16, 50, fontRepository->GetFont(FontType::Medium10)),
|
||||||
std::make_unique<Label2DView>(160, 16, 50, fontRepository->GetFont(FontType::Regular10)),
|
Label2DView::CreateShared(160, 16, 50, fontRepository->GetFont(FontType::Regular10)),
|
||||||
std::make_unique<Label2DView>(160, 16, 50, fontRepository->GetFont(FontType::Regular10)))
|
Label2DView::CreateShared(160, 16, 50, fontRepository->GetFont(FontType::Regular10)))
|
||||||
, _materialColorScheme(materialColorScheme) { }
|
, _materialColorScheme(materialColorScheme) { }
|
||||||
|
|
||||||
void MaterialBannerListItemView::Draw(GraphicsContext& graphicsContext)
|
void MaterialBannerListItemView::Draw(GraphicsContext& graphicsContext)
|
||||||
|
|||||||
@@ -7,10 +7,9 @@ class IFontRepository;
|
|||||||
|
|
||||||
class MaterialBannerListItemView : public BannerListItemView
|
class MaterialBannerListItemView : public BannerListItemView
|
||||||
{
|
{
|
||||||
public:
|
SHARED_ONLY(MaterialBannerListItemView)
|
||||||
MaterialBannerListItemView(const MaterialColorScheme* materialColorScheme,
|
|
||||||
const IFontRepository* fontRepository);
|
|
||||||
|
|
||||||
|
public:
|
||||||
void Draw(GraphicsContext& graphicsContext) override;
|
void Draw(GraphicsContext& graphicsContext) override;
|
||||||
|
|
||||||
Rectangle GetBounds() const override
|
Rectangle GetBounds() const override
|
||||||
@@ -28,4 +27,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
const MaterialColorScheme* _materialColorScheme;
|
const MaterialColorScheme* _materialColorScheme;
|
||||||
u32 _bgVramOffset;
|
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
|
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,
|
TaskResult<void> MaterialCoverFlowFileRecyclerAdapter::BindView(SharedPtr<View> view, int index,
|
||||||
const InternalFileInfo* internalFileInfo, const vu8& cancelRequested) const
|
const InternalFileInfo* internalFileInfo, const vu8& cancelRequested) const
|
||||||
{
|
{
|
||||||
auto coverView = static_cast<MaterialCoverView*>(view.GetPointer());
|
auto coverView = static_cast<MaterialCoverView*>(view.GetPointer());
|
||||||
|
coverView->GetViewModel().SetIndex(index);
|
||||||
auto cover = _fileInfoManager->GetFileCover(index);
|
auto cover = _fileInfoManager->GetFileCover(index);
|
||||||
if (cancelRequested)
|
if (cancelRequested)
|
||||||
{
|
{
|
||||||
@@ -39,10 +41,18 @@ TaskResult<void> MaterialCoverFlowFileRecyclerAdapter::BindView(SharedPtr<View>
|
|||||||
return TaskResult<void>::Completed();
|
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
|
void MaterialCoverFlowFileRecyclerAdapter::ReleaseView(SharedPtr<View> view, int index) const
|
||||||
{
|
{
|
||||||
LOG_DEBUG("Releasing %d\n", index);
|
LOG_DEBUG("Releasing %d\n", index);
|
||||||
auto coverView = static_cast<MaterialCoverView*>(view.GetPointer());
|
auto coverView = static_cast<MaterialCoverView*>(view.GetPointer());
|
||||||
coverView->ClearCover();
|
coverView->ClearCover();
|
||||||
|
coverView->GetViewModel().SetIndex(-1);
|
||||||
|
coverView->GetViewModel().CancelQueueTask();
|
||||||
_fileInfoManager->ReleaseFileInfo(index);
|
_fileInfoManager->ReleaseFileInfo(index);
|
||||||
}
|
}
|
||||||
@@ -8,12 +8,12 @@ class ICoverRepository;
|
|||||||
class MaterialCoverFlowFileRecyclerAdapter : public FileRecyclerAdapter
|
class MaterialCoverFlowFileRecyclerAdapter : public FileRecyclerAdapter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
MaterialCoverFlowFileRecyclerAdapter(FileInfoManager* fileInfoManager,
|
MaterialCoverFlowFileRecyclerAdapter(IRomBrowserController* romBrowserController, FileInfoManager* fileInfoManager,
|
||||||
TaskQueueBase* taskQueue, const IThemeFileIconFactory* themeFileIconFactory,
|
TaskQueueBase* taskQueue, const IThemeFileIconFactory* themeFileIconFactory,
|
||||||
const IRomBrowserViewFactory* romBrowserViewFactory,
|
const IRomBrowserViewFactory* romBrowserViewFactory,
|
||||||
VBlankTextureLoader* vblankTextureLoader,
|
VBlankTextureLoader* vblankTextureLoader,
|
||||||
const ICoverRepository* coverRepository)
|
const ICoverRepository* coverRepository)
|
||||||
: FileRecyclerAdapter(fileInfoManager, taskQueue, themeFileIconFactory)
|
: FileRecyclerAdapter(romBrowserController, fileInfoManager, taskQueue, themeFileIconFactory)
|
||||||
, _romBrowserViewFactory(romBrowserViewFactory)
|
, _romBrowserViewFactory(romBrowserViewFactory)
|
||||||
, _vblankTextureLoader(vblankTextureLoader)
|
, _vblankTextureLoader(vblankTextureLoader)
|
||||||
, _coverRepository(coverRepository) { }
|
, _coverRepository(coverRepository) { }
|
||||||
@@ -29,4 +29,5 @@ private:
|
|||||||
|
|
||||||
TaskResult<void> BindView(SharedPtr<View> view, int index,
|
TaskResult<void> BindView(SharedPtr<View> view, int index,
|
||||||
const InternalFileInfo* internalFileInfo, const vu8& cancelRequested) const override;
|
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/Gx.h"
|
||||||
#include "gui/materialDesign.h"
|
#include "gui/materialDesign.h"
|
||||||
#include "gui/GraphicsContext.h"
|
#include "gui/GraphicsContext.h"
|
||||||
|
#include "gui/input/InputProvider.h"
|
||||||
#include "MaterialCoverView.h"
|
#include "MaterialCoverView.h"
|
||||||
|
|
||||||
void MaterialCoverView::InitVram(const VramContext& vramContext)
|
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)
|
void MaterialCoverView::Draw(GraphicsContext& graphicsContext)
|
||||||
{
|
{
|
||||||
if (_cover.Lock() && _textureLoadRequest.GetState() == VBlankTextureLoadRequestState::LoadComplete)
|
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()
|
void MaterialCoverView::UploadCoverGraphics()
|
||||||
{
|
{
|
||||||
if (auto cover = _cover.Lock())
|
if (auto cover = _cover.Lock())
|
||||||
|
|||||||
@@ -3,13 +3,14 @@
|
|||||||
#include "gui/views/View.h"
|
#include "gui/views/View.h"
|
||||||
#include "romBrowser/FileType/FileCover.h"
|
#include "romBrowser/FileType/FileCover.h"
|
||||||
#include "gui/VBlankTextureLoader.h"
|
#include "gui/VBlankTextureLoader.h"
|
||||||
|
#include "romBrowser/viewModels/RomBrowserItemViewModel.h"
|
||||||
|
#include "romBrowser/views/RomBrowserItemInputHandler.h"
|
||||||
|
|
||||||
class MaterialCoverView : public View
|
class MaterialCoverView : public View
|
||||||
{
|
{
|
||||||
public:
|
SHARED_ONLY(MaterialCoverView)
|
||||||
explicit MaterialCoverView(VBlankTextureLoader* vblankTextureLoader)
|
|
||||||
: _vblankTextureLoader(vblankTextureLoader) { }
|
|
||||||
|
|
||||||
|
public:
|
||||||
~MaterialCoverView() override
|
~MaterialCoverView() override
|
||||||
{
|
{
|
||||||
_vblankTextureLoader->CancelLoad(_textureLoadRequest);
|
_vblankTextureLoader->CancelLoad(_textureLoadRequest);
|
||||||
@@ -17,11 +18,17 @@ public:
|
|||||||
|
|
||||||
void InitVram(const VramContext& vramContext) override;
|
void InitVram(const VramContext& vramContext) override;
|
||||||
|
|
||||||
|
void Update() override;
|
||||||
void Draw(GraphicsContext& graphicsContext) 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
|
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)
|
void SetCover(SharedPtr<FileCover> cover)
|
||||||
@@ -38,10 +45,21 @@ public:
|
|||||||
|
|
||||||
void UploadCoverGraphics();
|
void UploadCoverGraphics();
|
||||||
|
|
||||||
|
RomBrowserItemViewModel& GetViewModel() const
|
||||||
|
{
|
||||||
|
return *_viewModel;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
std::unique_ptr<RomBrowserItemViewModel> _viewModel;
|
||||||
VBlankTextureLoader* _vblankTextureLoader;
|
VBlankTextureLoader* _vblankTextureLoader;
|
||||||
AtomicSharedPtr<FileCover> _cover;
|
AtomicSharedPtr<FileCover> _cover;
|
||||||
VBlankTextureLoadRequest _textureLoadRequest;
|
VBlankTextureLoadRequest _textureLoadRequest;
|
||||||
u32 _texVramOffset = 0;
|
u32 _texVramOffset = 0;
|
||||||
u32 _plttVramOffset = 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,
|
MaterialFileInfoCardView::MaterialFileInfoCardView(const MaterialColorScheme* materialColorScheme,
|
||||||
const IFontRepository* fontRepository)
|
const IFontRepository* fontRepository)
|
||||||
: _firstLine(176, 16, 50, fontRepository->GetFont(FontType::Medium11))
|
: _firstLine(Label2DView::CreateShared(176, 16, 50, fontRepository->GetFont(FontType::Medium11)))
|
||||||
, _secondLine(176, 16, 50, fontRepository->GetFont(FontType::Regular10))
|
, _secondLine(Label2DView::CreateShared(176, 16, 50, fontRepository->GetFont(FontType::Regular10)))
|
||||||
, _thirdLine(176, 16, 50, fontRepository->GetFont(FontType::Regular10))
|
, _thirdLine(Label2DView::CreateShared(176, 16, 50, fontRepository->GetFont(FontType::Regular10)))
|
||||||
, _filenameLabelView(220, 16, 200, fontRepository->GetFont(FontType::Medium7_5))
|
, _filenameLabelView(Label2DView::CreateShared(220, 16, 200, fontRepository->GetFont(FontType::Medium7_5)))
|
||||||
, _materialColorScheme(materialColorScheme)
|
, _materialColorScheme(materialColorScheme)
|
||||||
{
|
{
|
||||||
AddChildTail(&_firstLine);
|
AddChildTail(_firstLine.GetPointer());
|
||||||
AddChildTail(&_secondLine);
|
AddChildTail(_secondLine.GetPointer());
|
||||||
AddChildTail(&_thirdLine);
|
AddChildTail(_thirdLine.GetPointer());
|
||||||
_filenameLabelView.SetEllipsisStyle(LabelView::EllipsisStyle::Marquee);
|
_filenameLabelView->SetEllipsisStyle(LabelView::EllipsisStyle::Marquee);
|
||||||
AddChildTail(&_filenameLabelView);
|
AddChildTail(_filenameLabelView.GetPointer());
|
||||||
}
|
}
|
||||||
|
|
||||||
void MaterialFileInfoCardView::InitVram(const VramContext& vramContext)
|
void MaterialFileInfoCardView::InitVram(const VramContext& vramContext)
|
||||||
@@ -41,10 +41,10 @@ void MaterialFileInfoCardView::InitVram(const VramContext& vramContext)
|
|||||||
void MaterialFileInfoCardView::Update()
|
void MaterialFileInfoCardView::Update()
|
||||||
{
|
{
|
||||||
BannerView::Update();
|
BannerView::Update();
|
||||||
_firstLine.SetPosition(_position.x + 70, _position.y + 130 - 8);
|
_firstLine->SetPosition(_position.x + 70, _position.y + 130 - 8);
|
||||||
_secondLine.SetPosition(_position.x + 70, _position.y + 145 - 8);
|
_secondLine->SetPosition(_position.x + 70, _position.y + 145 - 8);
|
||||||
_thirdLine.SetPosition(_position.x + 70, _position.y + 159 - 8);
|
_thirdLine->SetPosition(_position.x + 70, _position.y + 159 - 8);
|
||||||
_filenameLabelView.SetPosition(_position.x + 18, _position.y + 168);
|
_filenameLabelView->SetPosition(_position.x + 18, _position.y + 168);
|
||||||
if (_icon)
|
if (_icon)
|
||||||
{
|
{
|
||||||
_icon->SetPosition(_position.x + 24, _position.y + 136 - 8);
|
_icon->SetPosition(_position.x + 24, _position.y + 136 - 8);
|
||||||
@@ -54,14 +54,14 @@ void MaterialFileInfoCardView::Update()
|
|||||||
|
|
||||||
void MaterialFileInfoCardView::Draw(GraphicsContext& graphicsContext)
|
void MaterialFileInfoCardView::Draw(GraphicsContext& graphicsContext)
|
||||||
{
|
{
|
||||||
_firstLine.SetBackgroundColor(_materialColorScheme->secondaryContainer);
|
_firstLine->SetBackgroundColor(_materialColorScheme->secondaryContainer);
|
||||||
_firstLine.SetForegroundColor(_materialColorScheme->onSecondaryContainer);
|
_firstLine->SetForegroundColor(_materialColorScheme->onSecondaryContainer);
|
||||||
_secondLine.SetBackgroundColor(_materialColorScheme->secondaryContainer);
|
_secondLine->SetBackgroundColor(_materialColorScheme->secondaryContainer);
|
||||||
_secondLine.SetForegroundColor(_materialColorScheme->onSecondaryContainer);
|
_secondLine->SetForegroundColor(_materialColorScheme->onSecondaryContainer);
|
||||||
_thirdLine.SetBackgroundColor(_materialColorScheme->secondaryContainer);
|
_thirdLine->SetBackgroundColor(_materialColorScheme->secondaryContainer);
|
||||||
_thirdLine.SetForegroundColor(_materialColorScheme->onSecondaryContainer);
|
_thirdLine->SetForegroundColor(_materialColorScheme->onSecondaryContainer);
|
||||||
_filenameLabelView.SetBackgroundColor(_materialColorScheme->secondaryContainer);
|
_filenameLabelView->SetBackgroundColor(_materialColorScheme->secondaryContainer);
|
||||||
_filenameLabelView.SetForegroundColor(_materialColorScheme->onSurfaceVariant);
|
_filenameLabelView->SetForegroundColor(_materialColorScheme->onSurfaceVariant);
|
||||||
|
|
||||||
BannerView::Draw(graphicsContext);
|
BannerView::Draw(graphicsContext);
|
||||||
|
|
||||||
|
|||||||
@@ -9,55 +9,54 @@ class IFontRepository;
|
|||||||
|
|
||||||
class MaterialFileInfoCardView : public BannerView
|
class MaterialFileInfoCardView : public BannerView
|
||||||
{
|
{
|
||||||
public:
|
SHARED_ONLY(MaterialFileInfoCardView)
|
||||||
MaterialFileInfoCardView(const MaterialColorScheme* materialColorScheme,
|
|
||||||
const IFontRepository* fontRepository);
|
|
||||||
|
|
||||||
|
public:
|
||||||
void InitVram(const VramContext& vramContext) override;
|
void InitVram(const VramContext& vramContext) override;
|
||||||
void Update() override;
|
void Update() override;
|
||||||
void Draw(GraphicsContext& graphicsContext) override;
|
void Draw(GraphicsContext& graphicsContext) override;
|
||||||
|
|
||||||
void SetFirstLineAsync(TaskQueueBase* taskQueue, const char* firstLine, bool ellipsis) 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)
|
if (taskQueue)
|
||||||
_firstLine.SetTextAsync(taskQueue, firstLine);
|
_firstLine->SetTextAsync(taskQueue, firstLine);
|
||||||
else
|
else
|
||||||
_firstLine.SetText(firstLine);
|
_firstLine->SetText(firstLine);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetFirstLineAsync(TaskQueueBase* taskQueue, const char16_t* firstLine, u32 length, bool ellipsis) override
|
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)
|
if (taskQueue)
|
||||||
_firstLine.SetTextAsync(taskQueue, firstLine, length);
|
_firstLine->SetTextAsync(taskQueue, firstLine, length);
|
||||||
else
|
else
|
||||||
_firstLine.SetText(firstLine, length);
|
_firstLine->SetText(firstLine, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetSecondLineAsync(TaskQueueBase* taskQueue, const char16_t* secondLine, u32 length) override
|
void SetSecondLineAsync(TaskQueueBase* taskQueue, const char16_t* secondLine, u32 length) override
|
||||||
{
|
{
|
||||||
if (taskQueue)
|
if (taskQueue)
|
||||||
_secondLine.SetTextAsync(taskQueue, secondLine, length);
|
_secondLine->SetTextAsync(taskQueue, secondLine, length);
|
||||||
else
|
else
|
||||||
_secondLine.SetText(secondLine, length);
|
_secondLine->SetText(secondLine, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetThirdLineAsync(TaskQueueBase* taskQueue, const char16_t* thirdLine, u32 length) override
|
void SetThirdLineAsync(TaskQueueBase* taskQueue, const char16_t* thirdLine, u32 length) override
|
||||||
{
|
{
|
||||||
if (taskQueue)
|
if (taskQueue)
|
||||||
_thirdLine.SetTextAsync(taskQueue, thirdLine, length);
|
_thirdLine->SetTextAsync(taskQueue, thirdLine, length);
|
||||||
else
|
else
|
||||||
_thirdLine.SetText(thirdLine, length);
|
_thirdLine->SetText(thirdLine, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetFileNameAsync(TaskQueueBase* taskQueue, const TCHAR* fileName, bool useAsTitle) override
|
void SetFileNameAsync(TaskQueueBase* taskQueue, const TCHAR* fileName, bool useAsTitle) override
|
||||||
{
|
{
|
||||||
BannerView::SetFileNameAsync(taskQueue, fileName, useAsTitle);
|
BannerView::SetFileNameAsync(taskQueue, fileName, useAsTitle);
|
||||||
if (taskQueue)
|
if (taskQueue)
|
||||||
_filenameLabelView.SetTextAsync(taskQueue, fileName);
|
_filenameLabelView->SetTextAsync(taskQueue, fileName);
|
||||||
else
|
else
|
||||||
_filenameLabelView.SetText(fileName);
|
_filenameLabelView->SetText(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle GetBounds() const override
|
Rectangle GetBounds() const override
|
||||||
@@ -66,10 +65,13 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Label2DView _firstLine;
|
SharedPtr<Label2DView> _firstLine;
|
||||||
Label2DView _secondLine;
|
SharedPtr<Label2DView> _secondLine;
|
||||||
Label2DView _thirdLine;
|
SharedPtr<Label2DView> _thirdLine;
|
||||||
Label2DView _filenameLabelView;
|
SharedPtr<Label2DView> _filenameLabelView;
|
||||||
u32 _iconCellVramOffset;
|
u32 _iconCellVramOffset;
|
||||||
const MaterialColorScheme* _materialColorScheme;
|
const MaterialColorScheme* _materialColorScheme;
|
||||||
|
|
||||||
|
MaterialFileInfoCardView(const MaterialColorScheme* materialColorScheme,
|
||||||
|
const IFontRepository* fontRepository);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ void MaterialIconGridItemView::Draw(GraphicsContext& graphicsContext)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
auto backColor = _materialColorScheme->inverseOnSurface;
|
auto backColor = _materialColorScheme->inverseOnSurface;
|
||||||
auto frontColor = _isFocused
|
auto frontColor = (_isFocused || _inputHandler.IsPenDown())
|
||||||
? _materialColorScheme->mainIconBg
|
? _materialColorScheme->mainIconBg
|
||||||
: _materialColorScheme->surfaceBright;
|
: _materialColorScheme->surfaceBright;
|
||||||
u16 selectedIconCellPltt[16];
|
u16 selectedIconCellPltt[16];
|
||||||
|
|||||||
@@ -5,10 +5,9 @@ class MaterialColorScheme;
|
|||||||
|
|
||||||
class MaterialIconGridItemView : public IconGridItemView
|
class MaterialIconGridItemView : public IconGridItemView
|
||||||
{
|
{
|
||||||
public:
|
SHARED_ONLY(MaterialIconGridItemView)
|
||||||
explicit MaterialIconGridItemView(const MaterialColorScheme* materialColorScheme)
|
|
||||||
: _materialColorScheme(materialColorScheme) { }
|
|
||||||
|
|
||||||
|
public:
|
||||||
void Draw(GraphicsContext& graphicsContext) override;
|
void Draw(GraphicsContext& graphicsContext) override;
|
||||||
|
|
||||||
Rectangle GetBounds() const override
|
Rectangle GetBounds() const override
|
||||||
@@ -26,4 +25,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
const MaterialColorScheme* _materialColorScheme;
|
const MaterialColorScheme* _materialColorScheme;
|
||||||
u32 _bgVramOffset;
|
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)
|
const IFontRepository* fontRepository)
|
||||||
: _materialColorScheme(materialColorScheme), _fontRepository(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(
|
IconGridItemView::VramToken UploadIconGridItemViewGraphics(
|
||||||
@@ -29,9 +29,10 @@ public:
|
|||||||
return MaterialIconGridItemView::UploadGraphics(vramContext);
|
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(
|
BannerListItemView::VramToken UploadBannerListItemViewGraphics(
|
||||||
@@ -40,15 +41,15 @@ public:
|
|||||||
return MaterialBannerListItemView::UploadGraphics(vramContext);
|
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
|
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
|
SharedPtr<RecyclerViewBase> CreateCoverFlowRecyclerView() const override
|
||||||
@@ -60,7 +61,7 @@ public:
|
|||||||
RomBrowserViewModel* viewModel, const IThemeFileIconFactory* themeFileIconFactory,
|
RomBrowserViewModel* viewModel, const IThemeFileIconFactory* themeFileIconFactory,
|
||||||
VBlankTextureLoader* vblankTextureLoader) const override
|
VBlankTextureLoader* vblankTextureLoader) const override
|
||||||
{
|
{
|
||||||
return SharedPtr<MaterialCoverFlowFileRecyclerAdapter>::MakeShared(
|
return SharedPtr<MaterialCoverFlowFileRecyclerAdapter>::MakeShared(viewModel->GetRomBrowserController(),
|
||||||
&viewModel->GetFileInfoManager(), viewModel->GetIoTaskQueue(),
|
&viewModel->GetFileInfoManager(), viewModel->GetIoTaskQueue(),
|
||||||
themeFileIconFactory, this, vblankTextureLoader, &viewModel->GetCoverRepository());
|
themeFileIconFactory, this, vblankTextureLoader, &viewModel->GetCoverRepository());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ CustomAppBarView::CustomAppBarView(int x, int y, Orientation orientation,
|
|||||||
{
|
{
|
||||||
for (int i = 0; i < _startButtonCount + _endButtonCount; i++)
|
for (int i = 0; i < _startButtonCount + _endButtonCount; i++)
|
||||||
{
|
{
|
||||||
_buttons[i] = SharedPtr<IconButton3DView>::MakeShared(
|
_buttons[i] = IconButton3DView::CreateShared(
|
||||||
IconButtonView::Type::Tonal,
|
IconButtonView::Type::Tonal,
|
||||||
IconButtonView::State::NoToggle,
|
IconButtonView::State::NoToggle,
|
||||||
md::sys::color::inverseOnSurface,
|
md::sys::color::inverseOnSurface,
|
||||||
|
|||||||
@@ -3,14 +3,16 @@
|
|||||||
|
|
||||||
class CustomAppBarView : public AppBarView
|
class CustomAppBarView : public AppBarView
|
||||||
{
|
{
|
||||||
public:
|
SHARED_ONLY(CustomAppBarView)
|
||||||
CustomAppBarView(int x, int y, Orientation orientation,
|
|
||||||
int startButtonCount, int endButtonCount, const MaterialColorScheme* materialColorScheme,
|
|
||||||
u32 scrimTexVramOffset, u32 scrimPlttVramOffset);
|
|
||||||
|
|
||||||
|
public:
|
||||||
void Draw(GraphicsContext& graphicsContext) override;
|
void Draw(GraphicsContext& graphicsContext) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
u32 _scrimTexVramOffset = 0;
|
u32 _scrimTexVramOffset = 0;
|
||||||
u32 _scrimPlttVramOffset = 0;
|
u32 _scrimPlttVramOffset = 0;
|
||||||
|
|
||||||
|
CustomAppBarView(int x, int y, Orientation orientation,
|
||||||
|
int startButtonCount, int endButtonCount, const MaterialColorScheme* materialColorScheme,
|
||||||
|
u32 scrimTexVramOffset, u32 scrimPlttVramOffset);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -31,16 +31,17 @@
|
|||||||
#define LINE_HEIGHT 16
|
#define LINE_HEIGHT 16
|
||||||
#define MAX_LINE_STRING_LENGTH 50
|
#define MAX_LINE_STRING_LENGTH 50
|
||||||
|
|
||||||
CustomBannerListItemView::CustomBannerListItemView(const CustomThemeInfo* customThemeInfo,
|
CustomBannerListItemView::CustomBannerListItemView(std::unique_ptr<RomBrowserItemViewModel> viewModel,
|
||||||
const MaterialColorScheme* materialColorScheme, const IFontRepository* fontRepository,
|
const CustomThemeInfo* customThemeInfo, const MaterialColorScheme* materialColorScheme,
|
||||||
u32 texVramOffset, u32 plttVramOffset, u32 selectedTexVramOffset, u32 selectedPlttVramOffset,
|
const IFontRepository* fontRepository, u32 texVramOffset, u32 plttVramOffset,
|
||||||
|
u32 selectedTexVramOffset, u32 selectedPlttVramOffset,
|
||||||
VBlankTextureLoader* vblankTextureLoader)
|
VBlankTextureLoader* vblankTextureLoader)
|
||||||
: BannerListItemView(
|
: BannerListItemView(std::move(viewModel),
|
||||||
std::make_unique<Label3DView>(LINE_WIDTH, LINE_HEIGHT, MAX_LINE_STRING_LENGTH,
|
Label3DView::CreateShared(LINE_WIDTH, LINE_HEIGHT, MAX_LINE_STRING_LENGTH,
|
||||||
fontRepository->GetFont(FontType::Medium10), vblankTextureLoader),
|
fontRepository->GetFont(FontType::Medium10), vblankTextureLoader),
|
||||||
std::make_unique<Label3DView>(LINE_WIDTH, LINE_HEIGHT, MAX_LINE_STRING_LENGTH,
|
Label3DView::CreateShared(LINE_WIDTH, LINE_HEIGHT, MAX_LINE_STRING_LENGTH,
|
||||||
fontRepository->GetFont(FontType::Regular10), vblankTextureLoader),
|
fontRepository->GetFont(FontType::Regular10), vblankTextureLoader),
|
||||||
std::make_unique<Label3DView>(LINE_WIDTH, LINE_HEIGHT, MAX_LINE_STRING_LENGTH,
|
Label3DView::CreateShared(LINE_WIDTH, LINE_HEIGHT, MAX_LINE_STRING_LENGTH,
|
||||||
fontRepository->GetFont(FontType::Regular10), vblankTextureLoader))
|
fontRepository->GetFont(FontType::Regular10), vblankTextureLoader))
|
||||||
, _customThemeInfo(customThemeInfo)
|
, _customThemeInfo(customThemeInfo)
|
||||||
, _materialColorScheme(materialColorScheme)
|
, _materialColorScheme(materialColorScheme)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "gui/views/LabelView.h"
|
#include "gui/views/LabelView.h"
|
||||||
#include "../../views/BannerListItemView.h"
|
#include "romBrowser/views/BannerListItemView.h"
|
||||||
|
|
||||||
class MaterialColorScheme;
|
class MaterialColorScheme;
|
||||||
class IFontRepository;
|
class IFontRepository;
|
||||||
@@ -8,11 +8,9 @@ class CustomThemeInfo;
|
|||||||
|
|
||||||
class CustomBannerListItemView : public BannerListItemView
|
class CustomBannerListItemView : public BannerListItemView
|
||||||
{
|
{
|
||||||
public:
|
SHARED_ONLY(CustomBannerListItemView)
|
||||||
CustomBannerListItemView(const CustomThemeInfo* customThemeInfo, const MaterialColorScheme* materialColorScheme,
|
|
||||||
const IFontRepository* fontRepository, u32 texVramOffset, u32 plttVramOffset,
|
|
||||||
u32 selectedTexVramOffset, u32 selectedPlttVramOffset, VBlankTextureLoader* vblankTextureLoader);
|
|
||||||
|
|
||||||
|
public:
|
||||||
void Draw(GraphicsContext& graphicsContext) override;
|
void Draw(GraphicsContext& graphicsContext) override;
|
||||||
|
|
||||||
Rectangle GetBounds() const override
|
Rectangle GetBounds() const override
|
||||||
@@ -27,4 +25,9 @@ private:
|
|||||||
u32 _plttVramOffset = 0;
|
u32 _plttVramOffset = 0;
|
||||||
u32 _selectedTexVramOffset = 0;
|
u32 _selectedTexVramOffset = 0;
|
||||||
u32 _selectedPlttVramOffset = 0;
|
u32 _selectedPlttVramOffset = 0;
|
||||||
|
|
||||||
|
CustomBannerListItemView(std::unique_ptr<RomBrowserItemViewModel> viewModel, const CustomThemeInfo* customThemeInfo,
|
||||||
|
const MaterialColorScheme* materialColorScheme, const IFontRepository* fontRepository,
|
||||||
|
u32 texVramOffset, u32 plttVramOffset, u32 selectedTexVramOffset, u32 selectedPlttVramOffset,
|
||||||
|
VBlankTextureLoader* vblankTextureLoader);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -6,26 +6,30 @@
|
|||||||
#include "CustomFileInfoView.h"
|
#include "CustomFileInfoView.h"
|
||||||
|
|
||||||
CustomFileInfoView::CustomFileInfoView(const CustomThemeInfo* customThemeInfo, const IFontRepository* fontRepository)
|
CustomFileInfoView::CustomFileInfoView(const CustomThemeInfo* customThemeInfo, const IFontRepository* fontRepository)
|
||||||
: _firstLine(customThemeInfo->topBannerTextLine0Info.GetWidth(), 16, 50, fontRepository->GetFont(FontType::Medium11))
|
: _firstLine(Label2DView::CreateShared(
|
||||||
, _secondLine(customThemeInfo->topBannerTextLine1Info.GetWidth(), 16, 50, fontRepository->GetFont(FontType::Regular10))
|
customThemeInfo->topBannerTextLine0Info.GetWidth(), 16, 50, fontRepository->GetFont(FontType::Medium11)))
|
||||||
, _thirdLine(customThemeInfo->topBannerTextLine2Info.GetWidth(), 16, 50, fontRepository->GetFont(FontType::Regular10))
|
, _secondLine(Label2DView::CreateShared(
|
||||||
, _filenameLabelView(customThemeInfo->topFileNameTextInfo.GetWidth(), 16, 256, fontRepository->GetFont(FontType::Medium7_5))
|
customThemeInfo->topBannerTextLine1Info.GetWidth(), 16, 50, fontRepository->GetFont(FontType::Regular10)))
|
||||||
|
, _thirdLine(Label2DView::CreateShared(
|
||||||
|
customThemeInfo->topBannerTextLine2Info.GetWidth(), 16, 50, fontRepository->GetFont(FontType::Regular10)))
|
||||||
|
, _filenameLabelView(Label2DView::CreateShared(
|
||||||
|
customThemeInfo->topFileNameTextInfo.GetWidth(), 16, 256, fontRepository->GetFont(FontType::Medium7_5)))
|
||||||
, _customThemeInfo(customThemeInfo)
|
, _customThemeInfo(customThemeInfo)
|
||||||
{
|
{
|
||||||
AddChildTail(&_firstLine);
|
AddChildTail(_firstLine.GetPointer());
|
||||||
AddChildTail(&_secondLine);
|
AddChildTail(_secondLine.GetPointer());
|
||||||
AddChildTail(&_thirdLine);
|
AddChildTail(_thirdLine.GetPointer());
|
||||||
_filenameLabelView.SetEllipsisStyle(LabelView::EllipsisStyle::Marquee);
|
_filenameLabelView->SetEllipsisStyle(LabelView::EllipsisStyle::Marquee);
|
||||||
AddChildTail(&_filenameLabelView);
|
AddChildTail(_filenameLabelView.GetPointer());
|
||||||
}
|
}
|
||||||
|
|
||||||
void CustomFileInfoView::Update()
|
void CustomFileInfoView::Update()
|
||||||
{
|
{
|
||||||
BannerView::Update();
|
BannerView::Update();
|
||||||
_firstLine.SetPosition(_customThemeInfo->topBannerTextLine0Info.GetPosition());
|
_firstLine->SetPosition(_customThemeInfo->topBannerTextLine0Info.GetPosition());
|
||||||
_secondLine.SetPosition(_customThemeInfo->topBannerTextLine1Info.GetPosition());
|
_secondLine->SetPosition(_customThemeInfo->topBannerTextLine1Info.GetPosition());
|
||||||
_thirdLine.SetPosition(_customThemeInfo->topBannerTextLine2Info.GetPosition());
|
_thirdLine->SetPosition(_customThemeInfo->topBannerTextLine2Info.GetPosition());
|
||||||
_filenameLabelView.SetPosition(_customThemeInfo->topFileNameTextInfo.GetPosition());
|
_filenameLabelView->SetPosition(_customThemeInfo->topFileNameTextInfo.GetPosition());
|
||||||
if (_icon)
|
if (_icon)
|
||||||
{
|
{
|
||||||
_icon->SetPosition(_customThemeInfo->topIconInfo.GetPosition());
|
_icon->SetPosition(_customThemeInfo->topIconInfo.GetPosition());
|
||||||
@@ -35,14 +39,14 @@ void CustomFileInfoView::Update()
|
|||||||
|
|
||||||
void CustomFileInfoView::Draw(GraphicsContext& graphicsContext)
|
void CustomFileInfoView::Draw(GraphicsContext& graphicsContext)
|
||||||
{
|
{
|
||||||
_firstLine.SetBackgroundColor(_customThemeInfo->topBannerTextLine0Info.GetBlendColor());
|
_firstLine->SetBackgroundColor(_customThemeInfo->topBannerTextLine0Info.GetBlendColor());
|
||||||
_firstLine.SetForegroundColor(_customThemeInfo->topBannerTextLine0Info.GetTextColor());
|
_firstLine->SetForegroundColor(_customThemeInfo->topBannerTextLine0Info.GetTextColor());
|
||||||
_secondLine.SetBackgroundColor(_customThemeInfo->topBannerTextLine1Info.GetBlendColor());
|
_secondLine->SetBackgroundColor(_customThemeInfo->topBannerTextLine1Info.GetBlendColor());
|
||||||
_secondLine.SetForegroundColor(_customThemeInfo->topBannerTextLine1Info.GetTextColor());
|
_secondLine->SetForegroundColor(_customThemeInfo->topBannerTextLine1Info.GetTextColor());
|
||||||
_thirdLine.SetBackgroundColor(_customThemeInfo->topBannerTextLine2Info.GetBlendColor());
|
_thirdLine->SetBackgroundColor(_customThemeInfo->topBannerTextLine2Info.GetBlendColor());
|
||||||
_thirdLine.SetForegroundColor(_customThemeInfo->topBannerTextLine2Info.GetTextColor());
|
_thirdLine->SetForegroundColor(_customThemeInfo->topBannerTextLine2Info.GetTextColor());
|
||||||
_filenameLabelView.SetBackgroundColor(_customThemeInfo->topFileNameTextInfo.GetBlendColor());
|
_filenameLabelView->SetBackgroundColor(_customThemeInfo->topFileNameTextInfo.GetBlendColor());
|
||||||
_filenameLabelView.SetForegroundColor(_customThemeInfo->topFileNameTextInfo.GetTextColor());
|
_filenameLabelView->SetForegroundColor(_customThemeInfo->topFileNameTextInfo.GetTextColor());
|
||||||
|
|
||||||
BannerView::Draw(graphicsContext);
|
BannerView::Draw(graphicsContext);
|
||||||
|
|
||||||
|
|||||||
@@ -9,53 +9,53 @@ class CustomThemeInfo;
|
|||||||
|
|
||||||
class CustomFileInfoView : public BannerView
|
class CustomFileInfoView : public BannerView
|
||||||
{
|
{
|
||||||
public:
|
SHARED_ONLY(CustomFileInfoView)
|
||||||
CustomFileInfoView(const CustomThemeInfo* customThemeInfo, const IFontRepository* fontRepository);
|
|
||||||
|
|
||||||
|
public:
|
||||||
void Update() override;
|
void Update() override;
|
||||||
void Draw(GraphicsContext& graphicsContext) override;
|
void Draw(GraphicsContext& graphicsContext) override;
|
||||||
|
|
||||||
void SetFirstLineAsync(TaskQueueBase* taskQueue, const char* firstLine, bool ellipsis) 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)
|
if (taskQueue)
|
||||||
_firstLine.SetTextAsync(taskQueue, firstLine);
|
_firstLine->SetTextAsync(taskQueue, firstLine);
|
||||||
else
|
else
|
||||||
_firstLine.SetText(firstLine);
|
_firstLine->SetText(firstLine);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetFirstLineAsync(TaskQueueBase* taskQueue, const char16_t* firstLine, u32 length, bool ellipsis) override
|
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)
|
if (taskQueue)
|
||||||
_firstLine.SetTextAsync(taskQueue, firstLine, length);
|
_firstLine->SetTextAsync(taskQueue, firstLine, length);
|
||||||
else
|
else
|
||||||
_firstLine.SetText(firstLine, length);
|
_firstLine->SetText(firstLine, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetSecondLineAsync(TaskQueueBase* taskQueue, const char16_t* secondLine, u32 length) override
|
void SetSecondLineAsync(TaskQueueBase* taskQueue, const char16_t* secondLine, u32 length) override
|
||||||
{
|
{
|
||||||
if (taskQueue)
|
if (taskQueue)
|
||||||
_secondLine.SetTextAsync(taskQueue, secondLine, length);
|
_secondLine->SetTextAsync(taskQueue, secondLine, length);
|
||||||
else
|
else
|
||||||
_secondLine.SetText(secondLine, length);
|
_secondLine->SetText(secondLine, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetThirdLineAsync(TaskQueueBase* taskQueue, const char16_t* thirdLine, u32 length) override
|
void SetThirdLineAsync(TaskQueueBase* taskQueue, const char16_t* thirdLine, u32 length) override
|
||||||
{
|
{
|
||||||
if (taskQueue)
|
if (taskQueue)
|
||||||
_thirdLine.SetTextAsync(taskQueue, thirdLine, length);
|
_thirdLine->SetTextAsync(taskQueue, thirdLine, length);
|
||||||
else
|
else
|
||||||
_thirdLine.SetText(thirdLine, length);
|
_thirdLine->SetText(thirdLine, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetFileNameAsync(TaskQueueBase* taskQueue, const TCHAR* fileName, bool useAsTitle) override
|
void SetFileNameAsync(TaskQueueBase* taskQueue, const TCHAR* fileName, bool useAsTitle) override
|
||||||
{
|
{
|
||||||
BannerView::SetFileNameAsync(taskQueue, fileName, useAsTitle);
|
BannerView::SetFileNameAsync(taskQueue, fileName, useAsTitle);
|
||||||
if (taskQueue)
|
if (taskQueue)
|
||||||
_filenameLabelView.SetTextAsync(taskQueue, fileName);
|
_filenameLabelView->SetTextAsync(taskQueue, fileName);
|
||||||
else
|
else
|
||||||
_filenameLabelView.SetText(fileName);
|
_filenameLabelView->SetText(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle GetBounds() const override
|
Rectangle GetBounds() const override
|
||||||
@@ -64,9 +64,11 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Label2DView _firstLine;
|
SharedPtr<Label2DView> _firstLine;
|
||||||
Label2DView _secondLine;
|
SharedPtr<Label2DView> _secondLine;
|
||||||
Label2DView _thirdLine;
|
SharedPtr<Label2DView> _thirdLine;
|
||||||
Label2DView _filenameLabelView;
|
SharedPtr<Label2DView> _filenameLabelView;
|
||||||
const CustomThemeInfo* _customThemeInfo;
|
const CustomThemeInfo* _customThemeInfo;
|
||||||
|
|
||||||
|
CustomFileInfoView(const CustomThemeInfo* customThemeInfo, const IFontRepository* fontRepository);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -26,8 +26,8 @@ void CustomIconGridItemView::Draw(GraphicsContext& graphicsContext)
|
|||||||
false, false, false, GX_DEPTH_FUNC_LESS, false, 31, 0);
|
false, false, false, GX_DEPTH_FUNC_LESS, false, 31, 0);
|
||||||
Gx::Color(0x7FFF);
|
Gx::Color(0x7FFF);
|
||||||
|
|
||||||
u32 tex = _isFocused ? _selectedTexVramOffset : _texVramOffset;
|
u32 tex = (_isFocused || _inputHandler.IsPenDown()) ? _selectedTexVramOffset : _texVramOffset;
|
||||||
u32 pltt = _isFocused ? _selectedPlttVramOffset : _plttVramOffset;
|
u32 pltt = (_isFocused || _inputHandler.IsPenDown()) ? _selectedPlttVramOffset : _plttVramOffset;
|
||||||
Gx::TexImageParam(tex >> 3, false, false, false, false, GX_TEXSIZE_64,
|
Gx::TexImageParam(tex >> 3, false, false, false, false, GX_TEXSIZE_64,
|
||||||
GX_TEXSIZE_64, GX_TEXFMT_A3I5, false, GX_TEXGEN_NONE);
|
GX_TEXSIZE_64, GX_TEXFMT_A3I5, false, GX_TEXGEN_NONE);
|
||||||
Gx::TexPlttBase(pltt >> 4);
|
Gx::TexPlttBase(pltt >> 4);
|
||||||
|
|||||||
@@ -5,12 +5,9 @@ class CustomThemeInfo;
|
|||||||
|
|
||||||
class CustomIconGridItemView : public IconGridItemView
|
class CustomIconGridItemView : public IconGridItemView
|
||||||
{
|
{
|
||||||
public:
|
SHARED_ONLY(CustomIconGridItemView)
|
||||||
CustomIconGridItemView(const CustomThemeInfo* customThemeInfo, u32 texVramOffset, u32 plttVramOffset,
|
|
||||||
u32 selectedTexVramOffset, u32 selectedPlttVramOffset)
|
|
||||||
: _customThemeInfo(customThemeInfo), _texVramOffset(texVramOffset), _plttVramOffset(plttVramOffset)
|
|
||||||
, _selectedTexVramOffset(selectedTexVramOffset), _selectedPlttVramOffset(selectedPlttVramOffset) { }
|
|
||||||
|
|
||||||
|
public:
|
||||||
void Draw(GraphicsContext& graphicsContext) override;
|
void Draw(GraphicsContext& graphicsContext) override;
|
||||||
|
|
||||||
Rectangle GetBounds() const override
|
Rectangle GetBounds() const override
|
||||||
@@ -24,4 +21,9 @@ private:
|
|||||||
u32 _plttVramOffset;
|
u32 _plttVramOffset;
|
||||||
u32 _selectedTexVramOffset;
|
u32 _selectedTexVramOffset;
|
||||||
u32 _selectedPlttVramOffset;
|
u32 _selectedPlttVramOffset;
|
||||||
|
|
||||||
|
CustomIconGridItemView(std::unique_ptr<RomBrowserItemViewModel> viewModel, const CustomThemeInfo* customThemeInfo,
|
||||||
|
u32 texVramOffset, u32 plttVramOffset, u32 selectedTexVramOffset, u32 selectedPlttVramOffset)
|
||||||
|
: IconGridItemView(std::move(viewModel)), _customThemeInfo(customThemeInfo), _texVramOffset(texVramOffset), _plttVramOffset(plttVramOffset)
|
||||||
|
, _selectedTexVramOffset(selectedTexVramOffset), _selectedPlttVramOffset(selectedPlttVramOffset) { }
|
||||||
};
|
};
|
||||||
@@ -21,15 +21,16 @@ public:
|
|||||||
const IFontRepository* fontRepository)
|
const IFontRepository* fontRepository)
|
||||||
: _customThemeInfo(customThemeInfo), _materialColorScheme(materialColorScheme), _fontRepository(fontRepository) { }
|
: _customThemeInfo(customThemeInfo), _materialColorScheme(materialColorScheme), _fontRepository(fontRepository) { }
|
||||||
|
|
||||||
SharedPtr<IconGridItemView> CreateIconGridItemView() const override
|
SharedPtr<IconGridItemView> CreateIconGridItemView(std::unique_ptr<RomBrowserItemViewModel> viewModel) const override
|
||||||
{
|
{
|
||||||
return SharedPtr<CustomIconGridItemView>::MakeShared(_customThemeInfo, _gridCellTexVramOffset, _gridCellPlttVramOffset,
|
return CustomIconGridItemView::CreateShared(std::move(viewModel), _customThemeInfo, _gridCellTexVramOffset, _gridCellPlttVramOffset,
|
||||||
_gridCellSelectedTexVramOffset, _gridCellSelectedPlttVramOffset);
|
_gridCellSelectedTexVramOffset, _gridCellSelectedPlttVramOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
SharedPtr<BannerListItemView> CreateBannerListItemView(VBlankTextureLoader* vblankTextureLoader) const override
|
SharedPtr<BannerListItemView> CreateBannerListItemView(std::unique_ptr<RomBrowserItemViewModel> viewModel,
|
||||||
|
VBlankTextureLoader* vblankTextureLoader) const override
|
||||||
{
|
{
|
||||||
return SharedPtr<CustomBannerListItemView>::MakeShared(_customThemeInfo, _materialColorScheme, _fontRepository,
|
return CustomBannerListItemView::CreateShared(std::move(viewModel), _customThemeInfo, _materialColorScheme, _fontRepository,
|
||||||
_bannerListCellTexVramOffset, _bannerListCellPlttVramOffset,
|
_bannerListCellTexVramOffset, _bannerListCellPlttVramOffset,
|
||||||
_bannerListCellSelectedTexVramOffset, _bannerListCellSelectedPlttVramOffset, vblankTextureLoader);
|
_bannerListCellSelectedTexVramOffset, _bannerListCellSelectedPlttVramOffset, vblankTextureLoader);
|
||||||
}
|
}
|
||||||
@@ -39,16 +40,16 @@ public:
|
|||||||
return BannerListItemView::VramToken(0);
|
return BannerListItemView::VramToken(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
int startButtonCount, int endButtonCount) const override
|
||||||
{
|
{
|
||||||
return std::make_unique<CustomAppBarView>(x, y, orientation, startButtonCount, endButtonCount, _materialColorScheme,
|
return CustomAppBarView::CreateShared(x, y, orientation, startButtonCount, endButtonCount, _materialColorScheme,
|
||||||
_scrimTexVramOffset, _scrimPlttVramOffset);
|
_scrimTexVramOffset, _scrimPlttVramOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<BannerView> CreateFileInfoView() const override
|
SharedPtr<BannerView> CreateFileInfoView() const override
|
||||||
{
|
{
|
||||||
return std::make_unique<CustomFileInfoView>(_customThemeInfo, _fontRepository);
|
return CustomFileInfoView::CreateShared(_customThemeInfo, _fontRepository);
|
||||||
}
|
}
|
||||||
|
|
||||||
SharedPtr<RecyclerViewBase> CreateCoverFlowRecyclerView() const override
|
SharedPtr<RecyclerViewBase> CreateCoverFlowRecyclerView() const override
|
||||||
@@ -60,7 +61,7 @@ public:
|
|||||||
RomBrowserViewModel* viewModel, const IThemeFileIconFactory* themeFileIconFactory,
|
RomBrowserViewModel* viewModel, const IThemeFileIconFactory* themeFileIconFactory,
|
||||||
VBlankTextureLoader* vblankTextureLoader) const override
|
VBlankTextureLoader* vblankTextureLoader) const override
|
||||||
{
|
{
|
||||||
return SharedPtr<CoverFlowFileRecyclerAdapter>::MakeShared(
|
return SharedPtr<CoverFlowFileRecyclerAdapter>::MakeShared(viewModel->GetRomBrowserController(),
|
||||||
&viewModel->GetFileInfoManager(), viewModel->GetIoTaskQueue(),
|
&viewModel->GetFileInfoManager(), viewModel->GetIoTaskQueue(),
|
||||||
themeFileIconFactory, this, vblankTextureLoader, &viewModel->GetCoverRepository());
|
themeFileIconFactory, this, vblankTextureLoader, &viewModel->GetCoverRepository());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ CheatsViewModel::CheatsViewModel(const FileInfo& romFileInfo, IRomBrowserControl
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void CheatsViewModel::ActivateSelectedItem()
|
void CheatsViewModel::ActivateItem(int index)
|
||||||
{
|
{
|
||||||
if (_state != State::DisplayCheats)
|
if (_state != State::DisplayCheats)
|
||||||
{
|
{
|
||||||
@@ -36,19 +36,19 @@ void CheatsViewModel::ActivateSelectedItem()
|
|||||||
u32 numberOfSubEntries = 0;
|
u32 numberOfSubEntries = 0;
|
||||||
auto subEntries = cheatCategory->GetSubEntries(numberOfSubEntries);
|
auto subEntries = cheatCategory->GetSubEntries(numberOfSubEntries);
|
||||||
|
|
||||||
if (numberOfSubEntries == 0)
|
if (numberOfSubEntries == 0 || index < 0 || index >= (int)numberOfSubEntries)
|
||||||
{
|
{
|
||||||
// There is nothing to activate
|
// There is nothing to activate
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto& entry = subEntries[_selectedItem];
|
auto& entry = subEntries[index];
|
||||||
if (entry.IsCheatCategory())
|
if (entry.IsCheatCategory())
|
||||||
{
|
{
|
||||||
// Category activated
|
// Category activated
|
||||||
if (_categoryStackLevel + 1 != _categoryStack.size())
|
if (_categoryStackLevel + 1 != _categoryStack.size())
|
||||||
{
|
{
|
||||||
_categoryStack[++_categoryStackLevel] = { &entry, (u32)_selectedItem };
|
_categoryStack[++_categoryStackLevel] = { &entry, (u32)index };
|
||||||
_selectedItem = 0;
|
_selectedItem = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,8 +25,8 @@ public:
|
|||||||
|
|
||||||
CheatsViewModel(const FileInfo& romFileInfo, IRomBrowserController* romBrowserController);
|
CheatsViewModel(const FileInfo& romFileInfo, IRomBrowserController* romBrowserController);
|
||||||
|
|
||||||
/// @brief Activates the selected cheat or category.
|
/// @brief Activates the cheat or category at the specified \p index.
|
||||||
void ActivateSelectedItem();
|
void ActivateItem(int index);
|
||||||
|
|
||||||
/// @brief Navigates up in the cheat hierachy, or closes the cheats panel when at the root.
|
/// @brief Navigates up in the cheat hierachy, or closes the cheats panel when at the root.
|
||||||
/// @return \c true when navigation happened in the cheats tree, or \c false when the cheats panel was closed.
|
/// @return \c true when navigation happened in the cheats tree, or \c false when the cheats panel was closed.
|
||||||
@@ -54,9 +54,9 @@ public:
|
|||||||
/// @param selectedItem The index of the selected item to set.
|
/// @param selectedItem The index of the selected item to set.
|
||||||
void SetSelectedItem(int selectedItem) { _selectedItem = selectedItem; }
|
void SetSelectedItem(int selectedItem) { _selectedItem = selectedItem; }
|
||||||
|
|
||||||
/// @brief Returns whether the category name should be displayed.
|
/// @brief Returns whether the current displayed category is a sub-category.
|
||||||
/// @return \c true when the category name should be displayed, or \c false otherwise.
|
/// @return \c true when the current displayed category is a sub-category, or \c false otherwise.
|
||||||
bool ShouldShowCategoryName() const
|
bool IsInSubCategory() const
|
||||||
{
|
{
|
||||||
return _categoryStackLevel > 0;
|
return _categoryStackLevel > 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
#include "common.h"
|
||||||
|
#include "romBrowser/IRomBrowserController.h"
|
||||||
|
#include "RomBrowserViewModel.h"
|
||||||
|
#include "romBrowser/FileType/Nds/NdsFileType.h"
|
||||||
|
#include "RomBrowserItemViewModel.h"
|
||||||
|
|
||||||
|
void RomBrowserItemViewModel::Activate()
|
||||||
|
{
|
||||||
|
if (_index >= 0)
|
||||||
|
{
|
||||||
|
const auto& item = _romBrowserController->GetRomBrowserViewModel()->GetFileInfoManager().GetItem(_index);
|
||||||
|
if (item.GetFileType()->GetClassification() == FileTypeClassification::Folder)
|
||||||
|
{
|
||||||
|
_romBrowserController->NavigateToPath(item.GetFileName());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_romBrowserController->LaunchFile(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RomBrowserItemViewModel::ShowGameInfo()
|
||||||
|
{
|
||||||
|
if (_index >= 0)
|
||||||
|
{
|
||||||
|
const auto& item = _romBrowserController->GetRomBrowserViewModel()->GetFileInfoManager().GetItem(_index);
|
||||||
|
if (item.GetFileType() == &NdsFileType::sInstance)
|
||||||
|
{
|
||||||
|
_romBrowserController->ShowGameInfo(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
43
arm9/source/romBrowser/viewModels/RomBrowserItemViewModel.h
Normal file
43
arm9/source/romBrowser/viewModels/RomBrowserItemViewModel.h
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "core/task/TaskQueue.h"
|
||||||
|
|
||||||
|
class IRomBrowserController;
|
||||||
|
|
||||||
|
class RomBrowserItemViewModel
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit RomBrowserItemViewModel(IRomBrowserController* romBrowserController)
|
||||||
|
: _romBrowserController(romBrowserController) { }
|
||||||
|
|
||||||
|
void Activate();
|
||||||
|
void ShowGameInfo();
|
||||||
|
|
||||||
|
void SetIndex(int index)
|
||||||
|
{
|
||||||
|
_index = index;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetQueueTask(QueueTask<void> queueTask)
|
||||||
|
{
|
||||||
|
_queueTask = std::move(queueTask);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CancelQueueTask()
|
||||||
|
{
|
||||||
|
_queueTask.CancelTask();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DisposeQueueTaskWhenComplete()
|
||||||
|
{
|
||||||
|
if (_queueTask.GetTask().IsCompleted())
|
||||||
|
{
|
||||||
|
_queueTask.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
int _index = -1;
|
||||||
|
QueueTask<void> _queueTask;
|
||||||
|
|
||||||
|
IRomBrowserController* _romBrowserController;
|
||||||
|
};
|
||||||
@@ -40,29 +40,7 @@ RomBrowserViewModel::RomBrowserViewModel(IRomBrowserController* romBrowserContro
|
|||||||
_selectedItem = _fileInfoManager->GetItemIndex(initialSelectedFileName);
|
_selectedItem = _fileInfoManager->GetItemIndex(initialSelectedFileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RomBrowserViewModel::ItemActivated()
|
|
||||||
{
|
|
||||||
const auto& item = _fileInfoManager->GetItem(_selectedItem);
|
|
||||||
if (item.GetFileType()->GetClassification() == FileTypeClassification::Folder)
|
|
||||||
{
|
|
||||||
_romBrowserController->NavigateToPath(item.GetFileName());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_romBrowserController->LaunchFile(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void RomBrowserViewModel::NavigateUp()
|
void RomBrowserViewModel::NavigateUp()
|
||||||
{
|
{
|
||||||
_romBrowserController->NavigateUp();
|
_romBrowserController->NavigateUp();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RomBrowserViewModel::ShowGameInfo()
|
|
||||||
{
|
|
||||||
const auto& item = _fileInfoManager->GetItem(_selectedItem);
|
|
||||||
if (item.GetFileType() == &NdsFileType::sInstance)
|
|
||||||
{
|
|
||||||
_romBrowserController->ShowGameInfo(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -13,6 +13,7 @@ class RomBrowserViewModel
|
|||||||
public:
|
public:
|
||||||
RomBrowserViewModel(IRomBrowserController* romBrowserController, const char* initialSelectedFileName = nullptr);
|
RomBrowserViewModel(IRomBrowserController* romBrowserController, const char* initialSelectedFileName = nullptr);
|
||||||
|
|
||||||
|
IRomBrowserController* GetRomBrowserController() const { return _romBrowserController; }
|
||||||
FileInfoManager& GetFileInfoManager() const { return *_fileInfoManager; }
|
FileInfoManager& GetFileInfoManager() const { return *_fileInfoManager; }
|
||||||
TaskQueueBase* GetIoTaskQueue() const { return _romBrowserController->GetIoTaskQueue(); }
|
TaskQueueBase* GetIoTaskQueue() const { return _romBrowserController->GetIoTaskQueue(); }
|
||||||
TaskQueueBase* GetBgTaskQueue() const { return _romBrowserController->GetBgTaskQueue(); }
|
TaskQueueBase* GetBgTaskQueue() const { return _romBrowserController->GetBgTaskQueue(); }
|
||||||
@@ -24,9 +25,7 @@ public:
|
|||||||
constexpr u32 GetIconFrameCounter() const { return _iconFrameCounter; }
|
constexpr u32 GetIconFrameCounter() const { return _iconFrameCounter; }
|
||||||
void SetIconFrameCounter(u32 iconFrameCounter) { _iconFrameCounter = iconFrameCounter; }
|
void SetIconFrameCounter(u32 iconFrameCounter) { _iconFrameCounter = iconFrameCounter; }
|
||||||
|
|
||||||
void ItemActivated();
|
|
||||||
void NavigateUp();
|
void NavigateUp();
|
||||||
void ShowGameInfo();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
IRomBrowserController* _romBrowserController;
|
IRomBrowserController* _romBrowserController;
|
||||||
|
|||||||
@@ -1,21 +1,26 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "gui/IVramManager.h"
|
#include "gui/IVramManager.h"
|
||||||
#include "gui/GraphicsContext.h"
|
#include "gui/GraphicsContext.h"
|
||||||
|
#include "gui/input/InputProvider.h"
|
||||||
#include "BannerListItemView.h"
|
#include "BannerListItemView.h"
|
||||||
|
|
||||||
BannerListItemView::BannerListItemView(std::unique_ptr<LabelView> firstLine,
|
BannerListItemView::BannerListItemView(std::unique_ptr<RomBrowserItemViewModel> viewModel,
|
||||||
std::unique_ptr<LabelView> secondLine, std::unique_ptr<LabelView> thirdLine)
|
SharedPtr<LabelView> firstLine, SharedPtr<LabelView> secondLine, SharedPtr<LabelView> thirdLine)
|
||||||
: _firstLine(std::move(firstLine))
|
: _viewModel(std::move(viewModel))
|
||||||
|
, _firstLine(std::move(firstLine))
|
||||||
, _secondLine(std::move(secondLine))
|
, _secondLine(std::move(secondLine))
|
||||||
, _thirdLine(std::move(thirdLine))
|
, _thirdLine(std::move(thirdLine))
|
||||||
|
, _inputHandler(this, _viewModel.get())
|
||||||
{
|
{
|
||||||
AddChildTail(_firstLine.get());
|
AddChildTail(_firstLine.GetPointer());
|
||||||
AddChildTail(_secondLine.get());
|
AddChildTail(_secondLine.GetPointer());
|
||||||
AddChildTail(_thirdLine.get());
|
AddChildTail(_thirdLine.GetPointer());
|
||||||
}
|
}
|
||||||
|
|
||||||
void BannerListItemView::Update()
|
void BannerListItemView::Update()
|
||||||
{
|
{
|
||||||
|
_viewModel->DisposeQueueTaskWhenComplete();
|
||||||
|
|
||||||
ViewContainer::Update();
|
ViewContainer::Update();
|
||||||
|
|
||||||
if (_icon)
|
if (_icon)
|
||||||
@@ -23,3 +28,24 @@ void BannerListItemView::Update()
|
|||||||
_icon->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);
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
#include "BannerView.h"
|
#include "BannerView.h"
|
||||||
#include "gui/views/LabelView.h"
|
#include "gui/views/LabelView.h"
|
||||||
#include "../FileType/FileIcon.h"
|
#include "../FileType/FileIcon.h"
|
||||||
|
#include "romBrowser/viewModels/RomBrowserItemViewModel.h"
|
||||||
|
#include "RomBrowserItemInputHandler.h"
|
||||||
|
|
||||||
class BannerListItemView : public BannerView
|
class BannerListItemView : public BannerView
|
||||||
{
|
{
|
||||||
@@ -19,11 +21,13 @@ public:
|
|||||||
constexpr u32 GetVramOffset() const { return _vramOffset; }
|
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;
|
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) { }
|
virtual void SetGraphics(const VramToken& vramToken) { }
|
||||||
|
|
||||||
void SetFirstLineAsync(TaskQueueBase* taskQueue, const char* firstLine, bool ellipsis) override
|
void SetFirstLineAsync(TaskQueueBase* taskQueue, const char* firstLine, bool ellipsis) override
|
||||||
@@ -60,8 +64,18 @@ public:
|
|||||||
_thirdLine->SetText(thirdLine, length);
|
_thirdLine->SetText(thirdLine, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RomBrowserItemViewModel& GetViewModel() const
|
||||||
|
{
|
||||||
|
return *_viewModel;
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::unique_ptr<LabelView> _firstLine;
|
std::unique_ptr<RomBrowserItemViewModel> _viewModel;
|
||||||
std::unique_ptr<LabelView> _secondLine;
|
SharedPtr<LabelView> _firstLine;
|
||||||
std::unique_ptr<LabelView> _thirdLine;
|
SharedPtr<LabelView> _secondLine;
|
||||||
|
SharedPtr<LabelView> _thirdLine;
|
||||||
|
RomBrowserItemInputHandler _inputHandler;
|
||||||
|
|
||||||
|
BannerListItemView(std::unique_ptr<RomBrowserItemViewModel> viewModel, SharedPtr<LabelView> firstLine,
|
||||||
|
SharedPtr<LabelView> secondLine, SharedPtr<LabelView> thirdLine);
|
||||||
};
|
};
|
||||||
|
|||||||
34
arm9/source/romBrowser/views/BottomSheetView.cpp
Normal file
34
arm9/source/romBrowser/views/BottomSheetView.cpp
Normal 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;
|
||||||
|
}
|
||||||
@@ -5,6 +5,10 @@
|
|||||||
class BottomSheetView : public DialogView
|
class BottomSheetView : public DialogView
|
||||||
{
|
{
|
||||||
public:
|
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
|
Rectangle GetBounds() const override
|
||||||
{
|
{
|
||||||
return Rectangle(_position.x, _position.y, 256 - _position.x, 192 - _position.y);
|
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; }
|
constexpr DialogType GetDialogType() const override { return DialogType::BottomSheet; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void Close() = 0;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool _oobPenDown = false;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -40,13 +40,13 @@ void ChipView::Draw(GraphicsContext& graphicsContext)
|
|||||||
DirectPalette(chipPltt), _position.y, _position.y + 20);
|
DirectPalette(chipPltt), _position.y, _position.y + 20);
|
||||||
if (!_isFocused)
|
if (!_isFocused)
|
||||||
{
|
{
|
||||||
_label.SetBackgroundColor(_materialColorScheme->secondaryContainer);
|
_label->SetBackgroundColor(_materialColorScheme->secondaryContainer);
|
||||||
_label.SetForegroundColor(_materialColorScheme->onSecondaryContainer);
|
_label->SetForegroundColor(_materialColorScheme->onSecondaryContainer);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_label.SetBackgroundColor(fgColor);
|
_label->SetBackgroundColor(fgColor);
|
||||||
_label.SetForegroundColor(_materialColorScheme->onSecondaryContainer);
|
_label->SetForegroundColor(_materialColorScheme->onSecondaryContainer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -70,13 +70,13 @@ void ChipView::Draw(GraphicsContext& graphicsContext)
|
|||||||
|
|
||||||
if (!_isFocused)
|
if (!_isFocused)
|
||||||
{
|
{
|
||||||
_label.SetBackgroundColor(_materialColorScheme->GetColor(_backgroundColor));
|
_label->SetBackgroundColor(_materialColorScheme->GetColor(_backgroundColor));
|
||||||
_label.SetForegroundColor(_materialColorScheme->onSurfaceVariant);
|
_label->SetForegroundColor(_materialColorScheme->onSurfaceVariant);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_label.SetBackgroundColor(fgColor);
|
_label->SetBackgroundColor(fgColor);
|
||||||
_label.SetForegroundColor(_materialColorScheme->onSurfaceVariant);
|
_label->SetForegroundColor(_materialColorScheme->onSurfaceVariant);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -97,8 +97,8 @@ void ChipView::Draw(GraphicsContext& graphicsContext)
|
|||||||
|
|
||||||
DrawIcon(graphicsContext, fgColor);
|
DrawIcon(graphicsContext, fgColor);
|
||||||
|
|
||||||
_label.SetPosition(_position.x + (_iconVramOffset == 0xFFFFFFFF ? 10 : 22), _position.y + 3);
|
_label->SetPosition(_position.x + (_iconVramOffset == 0xFFFFFFFF ? 10 : 22), _position.y + 3);
|
||||||
_label.Draw(graphicsContext);
|
_label->Draw(graphicsContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChipView::DrawIcon(GraphicsContext& graphicsContext, const Rgb<8, 8, 8>& fgColor)
|
void ChipView::DrawIcon(GraphicsContext& graphicsContext, const Rgb<8, 8, 8>& fgColor)
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ class IVramManager;
|
|||||||
|
|
||||||
class ChipView : public View
|
class ChipView : public View
|
||||||
{
|
{
|
||||||
|
SHARED_ONLY(ChipView)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
class VramToken
|
class VramToken
|
||||||
{
|
{
|
||||||
@@ -27,22 +29,16 @@ public:
|
|||||||
constexpr u32 GetVramOffset() const { return _vramOffset; }
|
constexpr u32 GetVramOffset() const { return _vramOffset; }
|
||||||
};
|
};
|
||||||
|
|
||||||
explicit ChipView(md::sys::color backgroundColor, const MaterialColorScheme* materialColorScheme,
|
void InitVram(const VramContext& vramContext) override { _label->InitVram(vramContext); }
|
||||||
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 SetText(const char16_t* text) { _label->SetText(text); }
|
||||||
|
void SetText(const char16_t* text, u32 length) { _label->SetText(text, length); }
|
||||||
void SetText(const char16_t* text) { _label.SetText(text); }
|
QueueTask<void> SetTextAsync(TaskQueueBase* taskQueue, const char16_t* text) { return _label->SetTextAsync(taskQueue, text); }
|
||||||
void SetText(const char16_t* text, u32 length) { _label.SetText(text, length); }
|
QueueTask<void> SetTextAsync(TaskQueueBase* taskQueue, const char16_t* text, u32 length) { return _label->SetTextAsync(taskQueue, 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 Draw(GraphicsContext& graphicsContext) override;
|
||||||
|
|
||||||
void VBlank() override { _label.VBlank(); }
|
void VBlank() override { _label->VBlank(); }
|
||||||
|
|
||||||
void SetGraphics(const VramToken& vramToken)
|
void SetGraphics(const VramToken& vramToken)
|
||||||
{
|
{
|
||||||
@@ -63,9 +59,13 @@ public:
|
|||||||
{
|
{
|
||||||
int width;
|
int width;
|
||||||
if (_iconVramOffset == 0xFFFFFFFF)
|
if (_iconVramOffset == 0xFFFFFFFF)
|
||||||
width = 10 + _label.GetStringWidth() + 10;
|
{
|
||||||
|
width = 10 + _label->GetStringWidth() + 10;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
width = 22 + _label.GetStringWidth() + 10;
|
{
|
||||||
|
width = 22 + _label->GetStringWidth() + 10;
|
||||||
|
}
|
||||||
width = std::clamp(width, CHIP_VIEW_MIN_WIDTH, CHIP_VIEW_MAX_WIDTH);
|
width = std::clamp(width, CHIP_VIEW_MIN_WIDTH, CHIP_VIEW_MAX_WIDTH);
|
||||||
return width;
|
return width;
|
||||||
}
|
}
|
||||||
@@ -83,9 +83,15 @@ private:
|
|||||||
u32 _vramOffset;
|
u32 _vramOffset;
|
||||||
bool _isSelected;
|
bool _isSelected;
|
||||||
md::sys::color _backgroundColor;
|
md::sys::color _backgroundColor;
|
||||||
Label2DView _label;
|
SharedPtr<Label2DView> _label;
|
||||||
u32 _iconVramOffset;
|
u32 _iconVramOffset;
|
||||||
const MaterialColorScheme* _materialColorScheme;
|
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);
|
void DrawIcon(GraphicsContext& graphicsContext, const Rgb<8, 8, 8>& fgColor);
|
||||||
};
|
};
|
||||||
@@ -5,6 +5,7 @@
|
|||||||
#include "gui/Gx.h"
|
#include "gui/Gx.h"
|
||||||
#include "gui/GraphicsContext.h"
|
#include "gui/GraphicsContext.h"
|
||||||
#include "gui/materialDesign.h"
|
#include "gui/materialDesign.h"
|
||||||
|
#include "gui/input/InputProvider.h"
|
||||||
#include "core/math/SinTable.h"
|
#include "core/math/SinTable.h"
|
||||||
#include "romBrowser/FileType/FileCover.h"
|
#include "romBrowser/FileType/FileCover.h"
|
||||||
#include "CoverFlowRecyclerView.h"
|
#include "CoverFlowRecyclerView.h"
|
||||||
@@ -18,8 +19,10 @@ void CoverFlowRecyclerView::Update()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int rangeStartIndex = GetSelectedItem() - 4;
|
_scrollAnimator.Update();
|
||||||
int rangeEndIndex = GetSelectedItem() + 1 + 4;
|
|
||||||
|
int rangeStartIndex = _scrollAnimator.GetValue().Int() - 4;
|
||||||
|
int rangeEndIndex = _scrollAnimator.GetValue().Int() + 1 + 4;
|
||||||
rangeStartIndex = std::clamp(rangeStartIndex, 0, (int)_itemCount - 1);
|
rangeStartIndex = std::clamp(rangeStartIndex, 0, (int)_itemCount - 1);
|
||||||
rangeEndIndex = std::clamp(rangeEndIndex, 0, (int)_itemCount);
|
rangeEndIndex = std::clamp(rangeEndIndex, 0, (int)_itemCount);
|
||||||
|
|
||||||
@@ -43,10 +46,8 @@ void CoverFlowRecyclerView::Update()
|
|||||||
|
|
||||||
for (u32 i = _viewPoolFreeCount; i < _viewPool.size(); i++)
|
for (u32 i = _viewPoolFreeCount; i < _viewPool.size(); i++)
|
||||||
{
|
{
|
||||||
_viewPoolEx[i].yAngleAnimator.Update();
|
UpdateItemPosition(i);
|
||||||
_viewPoolEx[i].xPositionAnimator.Update();
|
_viewPool[i].view->SetPosition(_viewPoolEx[i].xPosition.Int(), 32 + 80);
|
||||||
_viewPoolEx[i].zPositionAnimator.Update();
|
|
||||||
_viewPool[i].view->SetPosition(_viewPoolEx[i].xPositionAnimator.GetValue().Int(), 32 + 80);
|
|
||||||
_viewPool[i].view->Update();
|
_viewPool[i].view->Update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -86,9 +87,9 @@ void CoverFlowRecyclerView::Draw(GraphicsContext& graphicsContext)
|
|||||||
graphicsContext.SetPolygonId(i);
|
graphicsContext.SetPolygonId(i);
|
||||||
Gx::MtxPush();
|
Gx::MtxPush();
|
||||||
{
|
{
|
||||||
fix32<12> x = _viewPoolEx[i].xPositionAnimator.GetValue();
|
fix32<12> x = _viewPoolEx[i].xPosition;
|
||||||
u32 angle = _viewPoolEx[i].yAngleAnimator.GetValue();
|
u32 angle = _viewPoolEx[i].yAngle;
|
||||||
fix32<12> z = _viewPoolEx[i].zPositionAnimator.GetValue();
|
fix32<12> z = _viewPoolEx[i].zPosition;
|
||||||
auto sinCos = gSinTable.SinCos(angle);
|
auto sinCos = gSinTable.SinCos(angle);
|
||||||
mtx43_t rotMtx =
|
mtx43_t rotMtx =
|
||||||
{
|
{
|
||||||
@@ -110,47 +111,144 @@ void CoverFlowRecyclerView::Draw(GraphicsContext& graphicsContext)
|
|||||||
Gx::MtxMode(GX_MTX_MODE_POSITION_VECTOR);
|
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];
|
if (_itemCount != 0 && inputProvider.Triggered(InputKey::L | InputKey::R))
|
||||||
ViewPoolEntryEx* itemEx = &_viewPoolEx[viewPoolIndex];
|
|
||||||
int selectedIndex = GetSelectedItem();
|
|
||||||
if (selectedIndex == -1)
|
|
||||||
{
|
{
|
||||||
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;
|
return View::HandleInput(inputProvider, focusManager);
|
||||||
fix32<12> z = 0;
|
}
|
||||||
u32 angle;
|
|
||||||
if (itemIndex < selectedIndex)
|
void CoverFlowRecyclerView::HandlePenDown(const Point& touchPoint, FocusManager& focusManager)
|
||||||
|
{
|
||||||
|
if (GetBounds().Contains(touchPoint))
|
||||||
{
|
{
|
||||||
x = 256 / 2 - (COVER_HEIGHT / 4) + COVER_SPACING * (itemIndex - selectedIndex);
|
_penDown = true;
|
||||||
angle = std::clamp((selectedIndex - itemIndex) * 10 + 45, -90, 90) * (1 << 16) / 360;
|
_penDownPosition = touchPoint;
|
||||||
z = -(selectedIndex - itemIndex) * 30 - 20;
|
_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);
|
return;
|
||||||
angle = std::clamp((selectedIndex - itemIndex) * 10 - 45, -90, 90) * (1 << 16) / 360;
|
}
|
||||||
z = (selectedIndex - itemIndex) * 30 - 20;
|
|
||||||
|
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
|
else
|
||||||
{
|
{
|
||||||
x = 256 / 2;
|
fix32<12> newScrollOffset = _penDownScrollOffset + fix32<12>(_penDownPosition.x - touchPoint.x) * (2.5 / COVER_WIDTH);
|
||||||
angle = 0;
|
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)
|
if (initial)
|
||||||
{
|
{
|
||||||
itemEx->yAngleAnimator = Animator<int>(angle);
|
_scrollAnimator = Animator<fix32<12>>(itemIdx);
|
||||||
itemEx->xPositionAnimator = Animator(x);
|
|
||||||
itemEx->zPositionAnimator = Animator(z);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
itemEx->yAngleAnimator.Goto(angle, md::sys::motion::duration::medium4, &md::sys::motion::easing::standard);
|
_scrollAnimator.Goto(itemIdx, 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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|||||||
@@ -5,30 +5,37 @@
|
|||||||
|
|
||||||
class CoverFlowRecyclerView : public CoverFlowRecyclerViewBase
|
class CoverFlowRecyclerView : public CoverFlowRecyclerViewBase
|
||||||
{
|
{
|
||||||
struct Private { explicit Private() = default; };
|
SHARED_ONLY(CoverFlowRecyclerView)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit CoverFlowRecyclerView(Private) { }
|
|
||||||
|
|
||||||
static SharedPtr<CoverFlowRecyclerView> CreateShared()
|
|
||||||
{
|
|
||||||
return SharedPtr<CoverFlowRecyclerView>::MakeShared(Private());
|
|
||||||
}
|
|
||||||
|
|
||||||
void Update() override;
|
void Update() override;
|
||||||
void Draw(GraphicsContext& graphicsContext) 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:
|
private:
|
||||||
struct ViewPoolEntryEx
|
struct ViewPoolEntryEx
|
||||||
{
|
{
|
||||||
Animator<int> yAngleAnimator;
|
int yAngle;
|
||||||
Animator<fix32<12>> xPositionAnimator;
|
fix32<12> xPosition;
|
||||||
Animator<fix32<12>> zPositionAnimator;
|
fix32<12> zPosition;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::array<ViewPoolEntryEx, 10> _viewPoolEx;
|
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
|
void SwapViewPoolEntry(int indexA, int indexB) override
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -115,7 +115,6 @@ CoverFlowRecyclerViewBase::ViewPoolEntry* CoverFlowRecyclerViewBase::BindViewPoo
|
|||||||
_viewPoolFreeCount--;
|
_viewPoolFreeCount--;
|
||||||
entry.itemIdx = itemIdx;
|
entry.itemIdx = itemIdx;
|
||||||
_adapter->BindView(entry.view, itemIdx);
|
_adapter->BindView(entry.view, itemIdx);
|
||||||
UpdateItemPosition(viewPoolIndex, true);
|
|
||||||
return &entry;
|
return &entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -185,9 +184,4 @@ void CoverFlowRecyclerViewBase::SetSelectedItem(int itemIdx, bool initial)
|
|||||||
{
|
{
|
||||||
_selectedItem = BindViewPoolEntry(itemIdx);
|
_selectedItem = BindViewPoolEntry(itemIdx);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (u32 i = _viewPoolFreeCount; i < _viewPool.size(); i++)
|
|
||||||
{
|
|
||||||
UpdateItemPosition(i, initial);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <array>
|
#include <array>
|
||||||
#include "core/EnableSharedFromThis.h"
|
|
||||||
#include "gui/views/RecyclerViewBase.h"
|
#include "gui/views/RecyclerViewBase.h"
|
||||||
|
|
||||||
class CoverFlowRecyclerViewBase : public RecyclerViewBase, public EnableSharedFromThis<CoverFlowRecyclerViewBase>
|
class CoverFlowRecyclerViewBase : public RecyclerViewBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
~CoverFlowRecyclerViewBase() override;
|
~CoverFlowRecyclerViewBase() override;
|
||||||
@@ -53,8 +52,7 @@ protected:
|
|||||||
void BindRange(int start, int end);
|
void BindRange(int start, int end);
|
||||||
void ReleaseViewPoolEntry(int itemIdx);
|
void ReleaseViewPoolEntry(int itemIdx);
|
||||||
void ReleaseRange(int start, int end);
|
void ReleaseRange(int start, int end);
|
||||||
void SetSelectedItem(int itemIdx, bool initial);
|
virtual void SetSelectedItem(int itemIdx, bool initial);
|
||||||
virtual void UpdateItemPosition(int viewPoolIndex, bool initial) = 0;
|
|
||||||
|
|
||||||
virtual void SwapViewPoolEntry(int indexA, int indexB)
|
virtual void SwapViewPoolEntry(int indexA, int indexB)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#include "gui/Gx.h"
|
#include "gui/Gx.h"
|
||||||
#include "gui/materialDesign.h"
|
#include "gui/materialDesign.h"
|
||||||
#include "gui/GraphicsContext.h"
|
#include "gui/GraphicsContext.h"
|
||||||
|
#include "gui/input/InputProvider.h"
|
||||||
#include "CoverView.h"
|
#include "CoverView.h"
|
||||||
|
|
||||||
void CoverView::InitVram(const VramContext& vramContext)
|
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)
|
void CoverView::Draw(GraphicsContext& graphicsContext)
|
||||||
{
|
{
|
||||||
if (_cover.Lock() && _textureLoadRequest.GetState() == VBlankTextureLoadRequestState::LoadComplete)
|
if (_cover.Lock() && _textureLoadRequest.GetState() == VBlankTextureLoadRequestState::LoadComplete)
|
||||||
@@ -93,3 +99,24 @@ void CoverView::UploadCoverGraphics()
|
|||||||
_vblankTextureLoader->RequestLoad(_textureLoadRequest);
|
_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);
|
||||||
|
}
|
||||||
|
|||||||
@@ -4,15 +4,14 @@
|
|||||||
#include "gui/views/View.h"
|
#include "gui/views/View.h"
|
||||||
#include "../FileType/FileCover.h"
|
#include "../FileType/FileCover.h"
|
||||||
#include "gui/VBlankTextureLoader.h"
|
#include "gui/VBlankTextureLoader.h"
|
||||||
|
#include "romBrowser/viewModels/RomBrowserItemViewModel.h"
|
||||||
#define COVER_THICKNESS (fix32<12>(0.23).GetRawValue())
|
#include "RomBrowserItemInputHandler.h"
|
||||||
|
|
||||||
class CoverView : public View
|
class CoverView : public View
|
||||||
{
|
{
|
||||||
public:
|
SHARED_ONLY(CoverView)
|
||||||
explicit CoverView(VBlankTextureLoader* vblankTextureLoader)
|
|
||||||
: _vblankTextureLoader(vblankTextureLoader) { }
|
|
||||||
|
|
||||||
|
public:
|
||||||
~CoverView() override
|
~CoverView() override
|
||||||
{
|
{
|
||||||
_vblankTextureLoader->CancelLoad(_textureLoadRequest);
|
_vblankTextureLoader->CancelLoad(_textureLoadRequest);
|
||||||
@@ -20,8 +19,14 @@ public:
|
|||||||
|
|
||||||
void InitVram(const VramContext& vramContext) override;
|
void InitVram(const VramContext& vramContext) override;
|
||||||
|
|
||||||
|
void Update() override;
|
||||||
void Draw(GraphicsContext& graphicsContext) 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
|
Rectangle GetBounds() const override
|
||||||
{
|
{
|
||||||
return Rectangle(_position.x - (COVER_WIDTH / 2), _position.y - (COVER_HEIGHT / 2), COVER_WIDTH, COVER_HEIGHT);
|
return Rectangle(_position.x - (COVER_WIDTH / 2), _position.y - (COVER_HEIGHT / 2), COVER_WIDTH, COVER_HEIGHT);
|
||||||
@@ -41,10 +46,21 @@ public:
|
|||||||
|
|
||||||
void UploadCoverGraphics();
|
void UploadCoverGraphics();
|
||||||
|
|
||||||
|
RomBrowserItemViewModel& GetViewModel() const
|
||||||
|
{
|
||||||
|
return *_viewModel;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
std::unique_ptr<RomBrowserItemViewModel> _viewModel;
|
||||||
VBlankTextureLoader* _vblankTextureLoader;
|
VBlankTextureLoader* _vblankTextureLoader;
|
||||||
AtomicSharedPtr<FileCover> _cover;
|
AtomicSharedPtr<FileCover> _cover;
|
||||||
VBlankTextureLoadRequest _textureLoadRequest;
|
VBlankTextureLoadRequest _textureLoadRequest;
|
||||||
u32 _texVramOffset = 0;
|
u32 _texVramOffset = 0;
|
||||||
u32 _plttVramOffset = 0;
|
u32 _plttVramOffset = 0;
|
||||||
|
RomBrowserItemInputHandler _inputHandler;
|
||||||
|
|
||||||
|
CoverView(std::unique_ptr<RomBrowserItemViewModel> viewModel, VBlankTextureLoader* vblankTextureLoader)
|
||||||
|
: _viewModel(std::move(viewModel)), _vblankTextureLoader(vblankTextureLoader)
|
||||||
|
, _inputHandler(this, _viewModel.get()) { }
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -52,18 +52,18 @@ DisplaySettingsBottomSheetView::DisplaySettingsBottomSheetView(
|
|||||||
DisplaySettingsViewModel* viewModel, const MaterialColorScheme* materialColorScheme,
|
DisplaySettingsViewModel* viewModel, const MaterialColorScheme* materialColorScheme,
|
||||||
const IFontRepository* fontRepository)
|
const IFontRepository* fontRepository)
|
||||||
: _viewModel(viewModel)
|
: _viewModel(viewModel)
|
||||||
, _titleLabel(128, 16, 25, fontRepository->GetFont(FontType::Medium11))
|
, _titleLabel(Label2DView::CreateShared(128, 16, 25, fontRepository->GetFont(FontType::Medium11)))
|
||||||
, _layoutLabel(64, 16, 25, fontRepository->GetFont(FontType::Regular10))
|
, _layoutLabel(Label2DView::CreateShared(64, 16, 25, fontRepository->GetFont(FontType::Regular10)))
|
||||||
, _sortingLabel(64, 16, 25, fontRepository->GetFont(FontType::Regular10))
|
, _sortingLabel(Label2DView::CreateShared(64, 16, 25, fontRepository->GetFont(FontType::Regular10)))
|
||||||
, _materialColorScheme(materialColorScheme)
|
, _materialColorScheme(materialColorScheme)
|
||||||
// , _filtersLabel(64, 16, 25, fontRepository->GetFont(FontType::Regular10))
|
// , _filtersLabel(64, 16, 25, fontRepository->GetFont(FontType::Regular10))
|
||||||
{
|
{
|
||||||
_titleLabel.SetText(u"Display Settings");
|
_titleLabel->SetText(u"Display Settings");
|
||||||
AddChildTail(&_titleLabel);
|
AddChildTail(_titleLabel.GetPointer());
|
||||||
_layoutLabel.SetText(u"Layout");
|
_layoutLabel->SetText(u"Layout");
|
||||||
AddChildTail(&_layoutLabel);
|
AddChildTail(_layoutLabel.GetPointer());
|
||||||
_sortingLabel.SetText(u"Sorting");
|
_sortingLabel->SetText(u"Sorting");
|
||||||
AddChildTail(&_sortingLabel);
|
AddChildTail(_sortingLabel.GetPointer());
|
||||||
// _filtersLabel.SetText(u"Filters");
|
// _filtersLabel.SetText(u"Filters");
|
||||||
// AddChildTail(&_filtersLabel);
|
// AddChildTail(&_filtersLabel);
|
||||||
|
|
||||||
@@ -90,7 +90,7 @@ DisplaySettingsBottomSheetView::DisplaySettingsBottomSheetView(
|
|||||||
|
|
||||||
SharedPtr<IconButton2DView> DisplaySettingsBottomSheetView::CreateLayoutOptionIconButton()
|
SharedPtr<IconButton2DView> DisplaySettingsBottomSheetView::CreateLayoutOptionIconButton()
|
||||||
{
|
{
|
||||||
auto layoutOption = SharedPtr<IconButton2DView>::MakeShared(
|
auto layoutOption = IconButton2DView::CreateShared(
|
||||||
IconButtonView::Type::Tonal,
|
IconButtonView::Type::Tonal,
|
||||||
IconButtonView::State::ToggleUnselected,
|
IconButtonView::State::ToggleUnselected,
|
||||||
md::sys::color::surfaceContainerLow,
|
md::sys::color::surfaceContainerLow,
|
||||||
@@ -113,7 +113,7 @@ SharedPtr<IconButton2DView> DisplaySettingsBottomSheetView::CreateLayoutOptionIc
|
|||||||
|
|
||||||
SharedPtr<IconButton2DView> DisplaySettingsBottomSheetView::CreateSortOptionIconButton()
|
SharedPtr<IconButton2DView> DisplaySettingsBottomSheetView::CreateSortOptionIconButton()
|
||||||
{
|
{
|
||||||
auto sortOption = SharedPtr<IconButton2DView>::MakeShared(
|
auto sortOption = IconButton2DView::CreateShared(
|
||||||
IconButtonView::Type::Tonal,
|
IconButtonView::Type::Tonal,
|
||||||
IconButtonView::State::ToggleUnselected,
|
IconButtonView::State::ToggleUnselected,
|
||||||
md::sys::color::surfaceContainerLow,
|
md::sys::color::surfaceContainerLow,
|
||||||
@@ -175,9 +175,9 @@ void DisplaySettingsBottomSheetView::InitVram(const VramContext& vramContext)
|
|||||||
|
|
||||||
void DisplaySettingsBottomSheetView::UpdateLabels()
|
void DisplaySettingsBottomSheetView::UpdateLabels()
|
||||||
{
|
{
|
||||||
_titleLabel.SetPosition(TITLE_LABEL_X, _position.y + TITLE_LABEL_Y);
|
_titleLabel->SetPosition(TITLE_LABEL_X, _position.y + TITLE_LABEL_Y);
|
||||||
_layoutLabel.SetPosition(LAYOUT_LABEL_X, _position.y + LAYOUT_LABEL_Y);
|
_layoutLabel->SetPosition(LAYOUT_LABEL_X, _position.y + LAYOUT_LABEL_Y);
|
||||||
_sortingLabel.SetPosition(SORTING_LABEL_X, _position.y + SORTING_LABEL_Y);
|
_sortingLabel->SetPosition(SORTING_LABEL_X, _position.y + SORTING_LABEL_Y);
|
||||||
// _filtersLabel.SetPosition(FILTERS_LABEL_X, _position.y + FILTERS_LABEL_Y);
|
// _filtersLabel.SetPosition(FILTERS_LABEL_X, _position.y + FILTERS_LABEL_Y);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -222,12 +222,12 @@ void DisplaySettingsBottomSheetView::Draw(GraphicsContext& graphicsContext)
|
|||||||
graphicsContext.SetClipArea(GetBounds());
|
graphicsContext.SetClipArea(GetBounds());
|
||||||
u32 oldPrio = graphicsContext.SetPriority(1);
|
u32 oldPrio = graphicsContext.SetPriority(1);
|
||||||
{
|
{
|
||||||
_titleLabel.SetBackgroundColor(_materialColorScheme->GetColor(md::sys::color::surfaceContainerLow));
|
_titleLabel->SetBackgroundColor(_materialColorScheme->GetColor(md::sys::color::surfaceContainerLow));
|
||||||
_titleLabel.SetForegroundColor(_materialColorScheme->onSurface);
|
_titleLabel->SetForegroundColor(_materialColorScheme->onSurface);
|
||||||
_layoutLabel.SetBackgroundColor(_materialColorScheme->GetColor(md::sys::color::surfaceContainerLow));
|
_layoutLabel->SetBackgroundColor(_materialColorScheme->GetColor(md::sys::color::surfaceContainerLow));
|
||||||
_layoutLabel.SetForegroundColor(_materialColorScheme->onSurfaceVariant);
|
_layoutLabel->SetForegroundColor(_materialColorScheme->onSurfaceVariant);
|
||||||
_sortingLabel.SetBackgroundColor(_materialColorScheme->GetColor(md::sys::color::surfaceContainerLow));
|
_sortingLabel->SetBackgroundColor(_materialColorScheme->GetColor(md::sys::color::surfaceContainerLow));
|
||||||
_sortingLabel.SetForegroundColor(_materialColorScheme->onSurfaceVariant);
|
_sortingLabel->SetForegroundColor(_materialColorScheme->onSurfaceVariant);
|
||||||
// _filtersLabel.SetBackgroundColor(_materialColorScheme->GetColor(md::sys::color::surfaceContainerLow));
|
// _filtersLabel.SetBackgroundColor(_materialColorScheme->GetColor(md::sys::color::surfaceContainerLow));
|
||||||
// _filtersLabel.SetForegroundColor(_materialColorScheme->onSurfaceVariant);
|
// _filtersLabel.SetForegroundColor(_materialColorScheme->onSurfaceVariant);
|
||||||
BottomSheetView::Draw(graphicsContext);
|
BottomSheetView::Draw(graphicsContext);
|
||||||
@@ -364,6 +364,11 @@ void DisplaySettingsBottomSheetView::SetGraphics(
|
|||||||
// filterOption.SetGraphics(iconButtonVramToken);
|
// filterOption.SetGraphics(iconButtonVramToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DisplaySettingsBottomSheetView::Close()
|
||||||
|
{
|
||||||
|
_viewModel->Close();
|
||||||
|
}
|
||||||
|
|
||||||
u32 DisplaySettingsBottomSheetView::LoadIcon(IVramManager& vramManager,
|
u32 DisplaySettingsBottomSheetView::LoadIcon(IVramManager& vramManager,
|
||||||
const unsigned int* tiles, u32 tilesLength) const
|
const unsigned int* tiles, u32 tilesLength) const
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -11,10 +11,9 @@ class IFontRepository;
|
|||||||
|
|
||||||
class DisplaySettingsBottomSheetView : public BottomSheetView
|
class DisplaySettingsBottomSheetView : public BottomSheetView
|
||||||
{
|
{
|
||||||
public:
|
SHARED_ONLY(DisplaySettingsBottomSheetView)
|
||||||
DisplaySettingsBottomSheetView(DisplaySettingsViewModel* viewModel,
|
|
||||||
const MaterialColorScheme* materialColorScheme, const IFontRepository* fontRepository);
|
|
||||||
|
|
||||||
|
public:
|
||||||
void InitVram(const VramContext& vramContext) override;
|
void InitVram(const VramContext& vramContext) override;
|
||||||
void Update() override;
|
void Update() override;
|
||||||
void Draw(GraphicsContext& graphicsContext) override;
|
void Draw(GraphicsContext& graphicsContext) override;
|
||||||
@@ -29,12 +28,15 @@ public:
|
|||||||
focusManager.Focus(_layoutOptions[0]);
|
focusManager.Focus(_layoutOptions[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void Close() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DisplaySettingsViewModel* _viewModel;
|
DisplaySettingsViewModel* _viewModel;
|
||||||
|
|
||||||
Label2DView _titleLabel;
|
SharedPtr<Label2DView> _titleLabel;
|
||||||
Label2DView _layoutLabel;
|
SharedPtr<Label2DView> _layoutLabel;
|
||||||
Label2DView _sortingLabel;
|
SharedPtr<Label2DView> _sortingLabel;
|
||||||
// LabelView _filtersLabel;
|
// LabelView _filtersLabel;
|
||||||
|
|
||||||
std::array<SharedPtr<IconButton2DView>, 4> _layoutOptions;
|
std::array<SharedPtr<IconButton2DView>, 4> _layoutOptions;
|
||||||
@@ -47,6 +49,9 @@ private:
|
|||||||
SharedPtr<IconButton2DView> CreateSortOptionIconButton();
|
SharedPtr<IconButton2DView> CreateSortOptionIconButton();
|
||||||
// IconButton2DView CreateFilterOptionIconButton();
|
// IconButton2DView CreateFilterOptionIconButton();
|
||||||
|
|
||||||
|
DisplaySettingsBottomSheetView(DisplaySettingsViewModel* viewModel,
|
||||||
|
const MaterialColorScheme* materialColorScheme, const IFontRepository* fontRepository);
|
||||||
|
|
||||||
void UpdateLabels();
|
void UpdateLabels();
|
||||||
|
|
||||||
u32 LoadIcon(IVramManager& vramManager, const unsigned int* tiles, u32 tilesLength) const;
|
u32 LoadIcon(IVramManager& vramManager, const unsigned int* tiles, u32 tilesLength) const;
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ void IconButton2DView::Draw(GraphicsContext& graphicsContext)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
u32 iconPaletteRow;
|
u32 iconPaletteRow;
|
||||||
if (_isFocused)
|
if (_isFocused || _penDown)
|
||||||
{
|
{
|
||||||
const auto& bgColor = _materialColorScheme->GetColor(_backgroundColor);
|
const auto& bgColor = _materialColorScheme->GetColor(_backgroundColor);
|
||||||
const auto& selectorBaseColor = _materialColorScheme->GetColor(GetCircleBackgroundColor());
|
const auto& selectorBaseColor = _materialColorScheme->GetColor(GetCircleBackgroundColor());
|
||||||
|
|||||||
@@ -3,6 +3,8 @@
|
|||||||
|
|
||||||
class IconButton2DView : public IconButtonView
|
class IconButton2DView : public IconButtonView
|
||||||
{
|
{
|
||||||
|
SHARED_ONLY(IconButton2DView)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
class VramToken
|
class VramToken
|
||||||
{
|
{
|
||||||
@@ -17,12 +19,6 @@ public:
|
|||||||
constexpr u32 GetVramOffset() const { return _vramOffset; }
|
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 Draw(GraphicsContext& graphicsContext) override;
|
||||||
|
|
||||||
void SetGraphics(const VramToken& vramToken)
|
void SetGraphics(const VramToken& vramToken)
|
||||||
@@ -34,4 +30,8 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
u32 _selectorVramOffset;
|
u32 _selectorVramOffset;
|
||||||
|
|
||||||
|
IconButton2DView(Type type, State state,
|
||||||
|
md::sys::color backgroundColor, const MaterialColorScheme* materialColorScheme)
|
||||||
|
: IconButtonView(type, state, backgroundColor, materialColorScheme) { }
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ void IconButton3DView::Draw(GraphicsContext& graphicsContext)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
u32 iconPaletteRow;
|
u32 iconPaletteRow;
|
||||||
if (_isFocused)
|
if (_isFocused || _penDown)
|
||||||
{
|
{
|
||||||
const auto& selectorBaseColor = _materialColorScheme->GetColor(GetCircleBackgroundColor());
|
const auto& selectorBaseColor = _materialColorScheme->GetColor(GetCircleBackgroundColor());
|
||||||
const auto& fgColor = _materialColorScheme->GetColor(GetForegroundColor());
|
const auto& fgColor = _materialColorScheme->GetColor(GetForegroundColor());
|
||||||
|
|||||||
@@ -5,13 +5,9 @@
|
|||||||
|
|
||||||
class IconButton3DView : public IconButtonView
|
class IconButton3DView : public IconButtonView
|
||||||
{
|
{
|
||||||
|
SHARED_ONLY(IconButton3DView)
|
||||||
|
|
||||||
public:
|
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;
|
void Draw(GraphicsContext& graphicsContext) override;
|
||||||
|
|
||||||
static void UploadGraphics(const VramContext& vramContext);
|
static void UploadGraphics(const VramContext& vramContext);
|
||||||
@@ -19,5 +15,9 @@ public:
|
|||||||
private:
|
private:
|
||||||
static u32 sSelectorTextureVramOffset;
|
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);
|
void DrawSelector(GraphicsContext& graphicsContext, const Rgb<8, 8, 8>& color);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -7,12 +7,46 @@ bool IconButtonView::HandleInput(const InputProvider& inputProvider, FocusManage
|
|||||||
if (inputProvider.Triggered(InputKey::A))
|
if (inputProvider.Triggered(InputKey::A))
|
||||||
{
|
{
|
||||||
if (_action)
|
if (_action)
|
||||||
|
{
|
||||||
_action(this, _actionArg);
|
_action(this, _actionArg);
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return View::HandleInput(inputProvider, focusManager);
|
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
|
bool IconButtonView::IsCircleBackgroundVisible() const
|
||||||
{
|
{
|
||||||
switch (_type)
|
switch (_type)
|
||||||
|
|||||||
@@ -24,16 +24,6 @@ public:
|
|||||||
ToggleSelected
|
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; }
|
void SetIconVramOffset(u32 vramOffset) { _iconVramOffset = vramOffset; }
|
||||||
|
|
||||||
Rectangle GetBounds() const override
|
Rectangle GetBounds() const override
|
||||||
@@ -53,6 +43,9 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool HandleInput(const InputProvider& inputProvider, FocusManager& focusManager) 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;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
u32 _iconVramOffset;
|
u32 _iconVramOffset;
|
||||||
@@ -62,6 +55,13 @@ protected:
|
|||||||
Type _type;
|
Type _type;
|
||||||
State _state;
|
State _state;
|
||||||
const MaterialColorScheme* _materialColorScheme;
|
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;
|
bool IsCircleBackgroundVisible() const;
|
||||||
md::sys::color GetCircleBackgroundColor() const;
|
md::sys::color GetCircleBackgroundColor() const;
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "gui/IVramManager.h"
|
#include "gui/IVramManager.h"
|
||||||
#include "gui/VramContext.h"
|
#include "gui/VramContext.h"
|
||||||
|
#include "gui/input/InputProvider.h"
|
||||||
#include "IconGridItemView.h"
|
#include "IconGridItemView.h"
|
||||||
|
|
||||||
void IconGridItemView::InitVram(const VramContext& vramContext)
|
void IconGridItemView::InitVram(const VramContext& vramContext)
|
||||||
@@ -15,8 +16,31 @@ void IconGridItemView::InitVram(const VramContext& vramContext)
|
|||||||
|
|
||||||
void IconGridItemView::Update()
|
void IconGridItemView::Update()
|
||||||
{
|
{
|
||||||
|
_viewModel->DisposeQueueTaskWhenComplete();
|
||||||
|
|
||||||
if (_icon)
|
if (_icon)
|
||||||
{
|
{
|
||||||
_icon->Update();
|
_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);
|
||||||
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user