From d31a15c315237bd69ee9b3d5bc1351ae5e38b99c Mon Sep 17 00:00:00 2001 From: Gericom Date: Sat, 13 Jun 2026 20:26:14 +0200 Subject: [PATCH] Add theme selector --- CHANGELOG.md | 1 + _pico/themes/raspberry/icon.bmp | Bin 0 -> 630 bytes _pico/themes/raspberry/preview.bin | 20 ++ _pico/themes/raspberry/theme.json | 6 +- arm9/gfx/themeIcon.grit | 7 + arm9/gfx/themeIcon.png | Bin 0 -> 234 bytes arm9/gfx/themeIconLarge.grit | 7 + arm9/gfx/themeIconLarge.png | Bin 0 -> 316 bytes arm9/source/App.cpp | 32 +- arm9/source/App.h | 5 - arm9/source/bgm/AudioStreamPlayer.cpp | 6 +- arm9/source/bgm/AudioStreamPlayer.h | 4 +- arm9/source/bgm/BgmService.cpp | 2 +- arm9/source/gui/views/Label2DView.cpp | 2 +- arm9/source/gui/views/RecyclerAdapter.h | 2 + .../CoverFlowFileRecyclerAdapter.cpp | 1 + .../source/romBrowser/IRomBrowserController.h | 1 + .../romBrowser/RomBrowserController.cpp | 15 + arm9/source/romBrowser/RomBrowserController.h | 2 + arm9/source/romBrowser/RomBrowserState.h | 3 +- .../romBrowser/RomBrowserStateMachine.cpp | 1 + .../romBrowser/RomBrowserStateTrigger.h | 3 +- arm9/source/romBrowser/SdFolder.cpp | 4 +- arm9/source/romBrowser/SdFolder.h | 2 +- .../romBrowser/Theme/IRomBrowserViewFactory.h | 6 +- .../romBrowser/Theme/IThemeFileIconFactory.h | 1 + .../Material/MaterialBannerListItemView.cpp | 8 +- .../Material/MaterialBannerListItemView.h | 2 +- .../MaterialCoverFlowFileRecyclerAdapter.cpp | 1 + .../Theme/Material/MaterialCoverView.h | 8 +- .../Material/MaterialFileInfoCardView.cpp | 8 +- .../Theme/Material/MaterialFileInfoCardView.h | 25 ++ .../Theme/Material/MaterialIconGridItemView.h | 2 +- .../Material/MaterialRomBrowserViewFactory.h | 4 +- .../Theme/Material/MaterialThemeFileIcon.h | 29 ++ .../Material/MaterialThemeFileIconFactory.h | 6 + .../Theme/custom/CustomBannerListItemView.cpp | 6 +- .../Theme/custom/CustomBannerListItemView.h | 2 +- .../Theme/custom/CustomFileInfoView.cpp | 6 +- .../Theme/custom/CustomFileInfoView.h | 25 ++ .../Theme/custom/CustomIconGridItemView.h | 2 +- .../custom/CustomRomBrowserViewFactory.h | 4 +- .../viewModels/DisplaySettingsViewModel.h | 5 + .../viewModels/IRomBrowserItemViewModel.h | 18 + .../RomBrowserBottomScreenViewModel.h | 3 +- .../viewModels/RomBrowserItemViewModel.h | 16 +- .../viewModels/RomBrowserViewModel.cpp | 2 +- .../romBrowser/views/BannerListItemView.cpp | 15 +- .../romBrowser/views/BannerListItemView.h | 33 +- arm9/source/romBrowser/views/BannerView.h | 9 +- arm9/source/romBrowser/views/CoverView.h | 8 +- .../views/DisplaySettingsBottomSheetView.cpp | 124 +++---- .../views/DisplaySettingsBottomSheetView.h | 4 +- .../romBrowser/views/IconGridItemView.h | 8 +- .../views/RomBrowserItemInputHandler.cpp | 2 +- .../views/RomBrowserItemInputHandler.h | 6 +- .../services/process/ProcessFactory.thumb.cpp | 2 + arm9/source/settings/ISettingsController.h | 18 + arm9/source/settings/SettingsController.cpp | 28 ++ arm9/source/settings/SettingsController.h | 26 ++ arm9/source/settings/SettingsProcess.cpp | 307 ++++++++++++++++++ arm9/source/settings/SettingsProcess.h | 86 +++++ arm9/source/settings/ThemeInfoManager.cpp | 81 +++++ arm9/source/settings/ThemeInfoManager.h | 36 ++ .../viewModels/ThemeListItemViewModel.cpp | 11 + .../viewModels/ThemeListItemViewModel.h | 58 ++++ .../viewModels/ThemeListViewModel.cpp | 11 + .../settings/viewModels/ThemeListViewModel.h | 23 ++ .../settings/views/SettingsAppBarView.cpp | 49 +++ .../settings/views/SettingsAppBarView.h | 38 +++ arm9/source/settings/views/ThemeAdapter.cpp | 91 ++++++ arm9/source/settings/views/ThemeAdapter.h | 33 ++ .../settings/views/ThemeListBottomView.cpp | 67 ++++ .../settings/views/ThemeListBottomView.h | 42 +++ .../settings/views/ThemeListTopView.cpp | 42 +++ arm9/source/settings/views/ThemeListTopView.h | 29 ++ arm9/source/themes/ThemeRepository.cpp | 27 ++ arm9/source/themes/ThemeRepository.h | 20 ++ arm9/source/themes/custom/CustomTheme.cpp | 3 +- arm9/source/themes/custom/CustomTheme.h | 4 +- docs/Themes.md | 12 +- libs/libtwl | 2 +- 82 files changed, 1474 insertions(+), 196 deletions(-) create mode 100644 _pico/themes/raspberry/icon.bmp create mode 100644 _pico/themes/raspberry/preview.bin create mode 100644 arm9/gfx/themeIcon.grit create mode 100644 arm9/gfx/themeIcon.png create mode 100644 arm9/gfx/themeIconLarge.grit create mode 100644 arm9/gfx/themeIconLarge.png create mode 100644 arm9/source/romBrowser/Theme/Material/MaterialThemeFileIcon.h create mode 100644 arm9/source/romBrowser/viewModels/IRomBrowserItemViewModel.h create mode 100644 arm9/source/settings/ISettingsController.h create mode 100644 arm9/source/settings/SettingsController.cpp create mode 100644 arm9/source/settings/SettingsController.h create mode 100644 arm9/source/settings/SettingsProcess.cpp create mode 100644 arm9/source/settings/SettingsProcess.h create mode 100644 arm9/source/settings/ThemeInfoManager.cpp create mode 100644 arm9/source/settings/ThemeInfoManager.h create mode 100644 arm9/source/settings/viewModels/ThemeListItemViewModel.cpp create mode 100644 arm9/source/settings/viewModels/ThemeListItemViewModel.h create mode 100644 arm9/source/settings/viewModels/ThemeListViewModel.cpp create mode 100644 arm9/source/settings/viewModels/ThemeListViewModel.h create mode 100644 arm9/source/settings/views/SettingsAppBarView.cpp create mode 100644 arm9/source/settings/views/SettingsAppBarView.h create mode 100644 arm9/source/settings/views/ThemeAdapter.cpp create mode 100644 arm9/source/settings/views/ThemeAdapter.h create mode 100644 arm9/source/settings/views/ThemeListBottomView.cpp create mode 100644 arm9/source/settings/views/ThemeListBottomView.h create mode 100644 arm9/source/settings/views/ThemeListTopView.cpp create mode 100644 arm9/source/settings/views/ThemeListTopView.h create mode 100644 arm9/source/themes/ThemeRepository.cpp create mode 100644 arm9/source/themes/ThemeRepository.h diff --git a/CHANGELOG.md b/CHANGELOG.md index 476adee..b8c04ca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ ### Added - Support for custom BMP icons for games and folders - by @tasken - Support for custom NDS banners (custom titles, subtitles and animated icons) for games and folders - by @tasken +- Theme selector ### Fixed - Top screen cover is now displayed/hidden correctly when placed partially or fully off-screen diff --git a/_pico/themes/raspberry/icon.bmp b/_pico/themes/raspberry/icon.bmp new file mode 100644 index 0000000000000000000000000000000000000000..2da8301f083663a7c364154755a5b3e175c9853d GIT binary patch literal 630 zcmZ?rEn{K;gEAng0mKSW%*en3WB~zG9>PJ8|NsAIIJV_KgDt~thD6oB403z(87Ays z!64e`!?5GcWrnwZ{xE>lU|OEq#Y!03^hOn#)rBA&WBn_h(86UAL?Y7`6e(2LgjI}XC}x3pmX3s zFbODN?1J#$%$bv1V2*|OsZmH#0_MA!GiRhmNHn&Fb;3kiLnB)wT0k)?N=$ks zQwUqi4+hbnjaObUg*LL>m}h9f5Nc>J*X+b@KA{JC33X4ngAS@6n9E=`ZTAMYB*n}7 de0ek&7#v-s{_IRJYzNxN;OXk;vd$@?2>{qPRT=;Q literal 0 HcmV?d00001 diff --git a/arm9/gfx/themeIconLarge.grit b/arm9/gfx/themeIconLarge.grit new file mode 100644 index 0000000..9392dda --- /dev/null +++ b/arm9/gfx/themeIconLarge.grit @@ -0,0 +1,7 @@ +# tile format +-gt + +# graphics bit depth is 4 (16 color) +-gB4 + +-p! \ No newline at end of file diff --git a/arm9/gfx/themeIconLarge.png b/arm9/gfx/themeIconLarge.png new file mode 100644 index 0000000000000000000000000000000000000000..3eb8d0eb8cda30aa59a2e3840b5c0fabd203636f GIT binary patch literal 316 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnF3?v&v(vJfv=3*z$5DpHG+YkL80J#PMJ|V6^ zT0lTRQBl#*(9p@rDJUo?IXStwxVWdMXU?2CYuB#byLa!obLZ~eyZ8S6`~Uy{U#PX1 z3)Hj2)5S5QVoq|x0<{ad4o{8m{_kA&;QxP44X%5dcmFr)Eco8B@W1^eO`q=~4NUd{ zA_hnPyK5v?u}?`^>o8-{_Z9LgEB}kD75FzY0~s7@7vc{vgdFLoadResources(*_theme, _subVramContext); _bottomBackground = _theme->CreateRomBrowserBottomBackground(); _bottomBackground->LoadResources(*_theme, _mainVramContext); - - _materialThemeFileIconFactory = std::make_unique( - &_theme->GetMaterialColorScheme(), _theme->GetFontRepository()); } void App::VCountIrq() @@ -138,7 +135,7 @@ void App::Run() &_romBrowserBottomScreenViewModel, RomBrowserDisplayModeFactory().GetRomBrowserDisplayMode( _romBrowserController.GetRomBrowserDisplaySettings().layout), - _materialThemeFileIconFactory.get(), + _theme->GetThemeFileIconFactory(), _theme->GetRomBrowserViewFactory(), &_vblankTextureLoader); _romBrowserBottomScreenView->InitVram(_mainVramContext); @@ -253,6 +250,7 @@ void App::HandleTrigger(RomBrowserStateTrigger trigger, RomBrowserState newState { case RomBrowserStateTrigger::None: case RomBrowserStateTrigger::Launch: + case RomBrowserStateTrigger::GotoSettingsScreen: { break; } @@ -344,7 +342,7 @@ void App::HandleFolderLoadDoneTrigger() _romBrowserTopScreenView = RomBrowserTopScreenView::CreateShared( _romBrowserController.GetRomBrowserViewModel(), displayMode, - _materialThemeFileIconFactory.get(), + _theme->GetThemeFileIconFactory(), _theme->GetRomBrowserViewFactory()); _romBrowserTopScreenView->InitVram(_subVramContext); _romBrowserBottomScreenView->RomBrowserViewModelInvalidated(_mainVramContext); @@ -361,7 +359,7 @@ void App::HandleChangeDisplayModeTrigger(RomBrowserState newState) _romBrowserBottomScreenView = RomBrowserBottomScreenView::CreateShared( &_romBrowserBottomScreenViewModel, displayMode, - _materialThemeFileIconFactory.get(), + _theme->GetThemeFileIconFactory(), _theme->GetRomBrowserViewFactory(), &_vblankTextureLoader); _romBrowserBottomScreenView->InitVram(_mainVramContext); @@ -369,7 +367,7 @@ void App::HandleChangeDisplayModeTrigger(RomBrowserState newState) _romBrowserTopScreenView = RomBrowserTopScreenView::CreateShared( _romBrowserController.GetRomBrowserViewModel(), displayMode, - _materialThemeFileIconFactory.get(), + _theme->GetThemeFileIconFactory(), _theme->GetRomBrowserViewFactory()); _romBrowserTopScreenView->InitVram(_subVramContext); _romBrowserBottomScreenView->RomBrowserViewModelInvalidated(_mainVramContext); @@ -377,16 +375,6 @@ void App::HandleChangeDisplayModeTrigger(RomBrowserState newState) _romBrowserBottomScreenView->Focus(_focusManager); } -bool App::IsRomBrowserVisible() const -{ - const auto& stateMachine = _romBrowserController.GetStateMachine(); - auto curState = stateMachine.GetCurrentState(); - return curState == RomBrowserState::Browser - || curState == RomBrowserState::GameInfo - || curState == RomBrowserState::DisplaySettings - || curState == RomBrowserState::Launching; -} - void App::Update() { const auto& stateMachine = _romBrowserController.GetStateMachine(); @@ -402,8 +390,10 @@ void App::Update() HandleTrigger(stateMachine.GetLastTrigger(), curState); } - bool isRomBrowserVisible = IsRomBrowserVisible(); - if (isRomBrowserVisible && !_exit && curState != RomBrowserState::Launching) + bool isRomBrowserVisible = _romBrowserBottomScreenViewModel.IsRomBrowserVisible(); + if (isRomBrowserVisible && !_exit && + curState != RomBrowserState::Launching && + curState != RomBrowserState::GoingToSettingsScreen) { HandleInput(); } @@ -456,7 +446,7 @@ void App::Draw() if (_bottomBackground) _bottomBackground->Draw(mainGraphicsContext); - if (!_changeDisplayMode && IsRomBrowserVisible()) + if (!_changeDisplayMode && _romBrowserBottomScreenViewModel.IsRomBrowserVisible()) { _romBrowserTopScreenView->Draw(subGraphicsContext); } @@ -499,7 +489,7 @@ void App::VBlank() _dialogPresenter.VBlank(); - if (IsRomBrowserVisible()) + if (_romBrowserBottomScreenViewModel.IsRomBrowserVisible()) { _romBrowserTopScreenView->VBlank(); } diff --git a/arm9/source/App.h b/arm9/source/App.h index f424e6c..fb74551 100644 --- a/arm9/source/App.h +++ b/arm9/source/App.h @@ -25,7 +25,6 @@ #include "romBrowser/views/RomBrowserTopScreenView.h" #include "romBrowser/views/IconButton2DView.h" #include "romBrowser/views/ChipView.h" -#include "romBrowser/Theme/Material/MaterialThemeFileIconFactory.h" #include "romBrowser/RomBrowserController.h" #include "DialogPresenter.h" #include "themes/ITheme.h" @@ -90,8 +89,6 @@ private: FocusManager _focusManager; - std::unique_ptr _materialThemeFileIconFactory; - RomBrowserBottomScreenViewModel _romBrowserBottomScreenViewModel; DialogPresenter _dialogPresenter; @@ -121,8 +118,6 @@ private: void HandleFolderLoadDoneTrigger(); void HandleChangeDisplayModeTrigger(RomBrowserState newState); - bool IsRomBrowserVisible() const; - void MainLoop(); void Update(); void Draw(); diff --git a/arm9/source/bgm/AudioStreamPlayer.cpp b/arm9/source/bgm/AudioStreamPlayer.cpp index fa8c241..572b040 100644 --- a/arm9/source/bgm/AudioStreamPlayer.cpp +++ b/arm9/source/bgm/AudioStreamPlayer.cpp @@ -32,7 +32,7 @@ bool AudioStreamPlayer::StartPlaybackIntern(std::unique_ptr audioS StopPlaybackIntern(); _audioStream = std::move(audioStream); - + // fill buffer _readBlock = 0; _writeBlock = 0; @@ -83,10 +83,10 @@ void AudioStreamPlayer::StopPlaybackIntern() return; _isPlaying = false; - rtos_wakeupThread(&_thread); ipc_sendFifoMessage(IPC_CHANNEL_SOUND, (u32)&_soundStopCmdList); tmr_stop(AUDIO_STREAM_PLAYER_TIMER); rtos_disableIrqMask(RTOS_IRQ_TIMER(AUDIO_STREAM_PLAYER_TIMER)); + rtos_signalEvent(&_event); rtos_joinThread(&_thread); sCurrentPlayer = nullptr; _audioStream.reset(); @@ -97,7 +97,7 @@ void AudioStreamPlayer::ThreadMain() do { bool doUpdate = true; - while(_isPlaying && doUpdate) + while (_isPlaying && doUpdate) { rtos_lockMutex(&_mutex); { diff --git a/arm9/source/bgm/AudioStreamPlayer.h b/arm9/source/bgm/AudioStreamPlayer.h index 7e9bb93..930254d 100644 --- a/arm9/source/bgm/AudioStreamPlayer.h +++ b/arm9/source/bgm/AudioStreamPlayer.h @@ -93,8 +93,8 @@ private: rtos_thread_t _thread; rtos_event_t _event; volatile bool _isPlaying = false; - volatile u8 _readBlock; - volatile u8 _writeBlock; + volatile u8 _readBlock = 0; + volatile u8 _writeBlock = 0; std::unique_ptr _audioStream; static AudioStreamPlayer* sCurrentPlayer; diff --git a/arm9/source/bgm/BgmService.cpp b/arm9/source/bgm/BgmService.cpp index 54e86af..b79bfef 100644 --- a/arm9/source/bgm/BgmService.cpp +++ b/arm9/source/bgm/BgmService.cpp @@ -12,7 +12,7 @@ bool BgmService::StartBgm(const TCHAR* filePath) auto stream = std::make_unique(); if (!stream->Open(filePath)) return false; - + return _audioStreamPlayer->StartPlayback(std::move(stream)); } diff --git a/arm9/source/gui/views/Label2DView.cpp b/arm9/source/gui/views/Label2DView.cpp index 5b286b0..d147ae8 100644 --- a/arm9/source/gui/views/Label2DView.cpp +++ b/arm9/source/gui/views/Label2DView.cpp @@ -59,7 +59,7 @@ void Label2DView::Draw(GraphicsContext& graphicsContext) void Label2DView::VBlank() { - if (_tileBufferUpdated) + if (_tileBufferUpdated && _vramAddress) { memcpy((void*)_vramAddress, _tileBuffer.get(), _tileBufferSize); _tileBufferUpdated = false; diff --git a/arm9/source/gui/views/RecyclerAdapter.h b/arm9/source/gui/views/RecyclerAdapter.h index fb77b9f..58cfcbc 100644 --- a/arm9/source/gui/views/RecyclerAdapter.h +++ b/arm9/source/gui/views/RecyclerAdapter.h @@ -1,4 +1,6 @@ #pragma once +#include "core/SharedPtr.h" + class View; /// @brief Adapter class providing the content to show in a \see RecyclerView. diff --git a/arm9/source/romBrowser/DisplayMode/CoverFlowFileRecyclerAdapter.cpp b/arm9/source/romBrowser/DisplayMode/CoverFlowFileRecyclerAdapter.cpp index 11ff06d..8805e45 100644 --- a/arm9/source/romBrowser/DisplayMode/CoverFlowFileRecyclerAdapter.cpp +++ b/arm9/source/romBrowser/DisplayMode/CoverFlowFileRecyclerAdapter.cpp @@ -5,6 +5,7 @@ #include "../Theme/IRomBrowserViewFactory.h" #include "../FileType/UnknownFileCover.h" #include "romBrowser/ICoverRepository.h" +#include "romBrowser/viewModels/RomBrowserItemViewModel.h" #include "CoverFlowFileRecyclerAdapter.h" void CoverFlowFileRecyclerAdapter::GetViewSize(int& width, int& height) const diff --git a/arm9/source/romBrowser/IRomBrowserController.h b/arm9/source/romBrowser/IRomBrowserController.h index 343d75a..d88a232 100644 --- a/arm9/source/romBrowser/IRomBrowserController.h +++ b/arm9/source/romBrowser/IRomBrowserController.h @@ -24,6 +24,7 @@ public: virtual void HideGameInfo() = 0; virtual void ShowDisplaySettings() = 0; virtual void HideDisplaySettings() = 0; + virtual void GotoSettingsScreen() = 0; virtual void Update() = 0; diff --git a/arm9/source/romBrowser/RomBrowserController.cpp b/arm9/source/romBrowser/RomBrowserController.cpp index 1a4eabc..e530f87 100644 --- a/arm9/source/romBrowser/RomBrowserController.cpp +++ b/arm9/source/romBrowser/RomBrowserController.cpp @@ -2,6 +2,7 @@ #include #include "picoLoaderBootstrap.h" #include "PicoLoaderProcess.h" +#include "settings/SettingsProcess.h" #include "FileType/ExtensionFileTypeProvider.h" #include "FileType/FileType.h" #include "SdFolderFactory.h" @@ -60,6 +61,11 @@ void RomBrowserController::HideDisplaySettings() _stateMachine.Fire(RomBrowserStateTrigger::HideDisplaySettings); } +void RomBrowserController::GotoSettingsScreen() +{ + _stateMachine.Fire(RomBrowserStateTrigger::GotoSettingsScreen); +} + void RomBrowserController::SetRomBrowserDisplaySettings( const RomBrowserDisplaySettings& romBrowserDisplaySettings) { @@ -128,6 +134,10 @@ void RomBrowserController::HandleTrigger() HandleChangeDisplayModeTrigger(); break; + case RomBrowserStateTrigger::GotoSettingsScreen: + HandleGotoSettingsScreenTrigger(); + break; + default: break; } @@ -213,6 +223,11 @@ void RomBrowserController::HandleChangeDisplayModeTrigger() _romBrowserViewModel = SharedPtr::MakeShared(this); } +void RomBrowserController::HandleGotoSettingsScreenTrigger() +{ + gProcessManager.Goto(); +} + void RomBrowserController::UpdateLastUsedFilepath() { f_getcwd(_navigatePath, sizeof(_navigatePath) / sizeof(_navigatePath[0])); diff --git a/arm9/source/romBrowser/RomBrowserController.h b/arm9/source/romBrowser/RomBrowserController.h index f8ddc7b..7dc3623 100644 --- a/arm9/source/romBrowser/RomBrowserController.h +++ b/arm9/source/romBrowser/RomBrowserController.h @@ -30,6 +30,7 @@ public: void HideGameInfo() override; void ShowDisplaySettings() override; void HideDisplaySettings() override; + void GotoSettingsScreen() override; void Update() override; @@ -80,6 +81,7 @@ private: void HandleFolderLoadDoneTrigger(); void HandleLaunchTrigger(); void HandleChangeDisplayModeTrigger(); + void HandleGotoSettingsScreenTrigger(); void UpdateLastUsedFilepath(); void SetPicoLoaderParams() const; void LoadCheats() const; diff --git a/arm9/source/romBrowser/RomBrowserState.h b/arm9/source/romBrowser/RomBrowserState.h index 9099b03..6c2972a 100644 --- a/arm9/source/romBrowser/RomBrowserState.h +++ b/arm9/source/romBrowser/RomBrowserState.h @@ -7,5 +7,6 @@ enum class RomBrowserState GameInfo, LoadingFolder, Launching, - DisplaySettings + DisplaySettings, + GoingToSettingsScreen }; diff --git a/arm9/source/romBrowser/RomBrowserStateMachine.cpp b/arm9/source/romBrowser/RomBrowserStateMachine.cpp index 11796c4..98b5cdf 100644 --- a/arm9/source/romBrowser/RomBrowserStateMachine.cpp +++ b/arm9/source/romBrowser/RomBrowserStateMachine.cpp @@ -28,6 +28,7 @@ bool RomBrowserStateMachine::FireDirect(RomBrowserStateTrigger trigger) .In(RomBrowserState::DisplaySettings) .Trigger(RomBrowserStateTrigger::ChangeDisplayMode).GoesTo(RomBrowserState::DisplaySettings) .Trigger(RomBrowserStateTrigger::HideDisplaySettings).GoesTo(RomBrowserState::Browser) + .Trigger(RomBrowserStateTrigger::GotoSettingsScreen).GoesTo(RomBrowserState::GoingToSettingsScreen) .Check(newState)) { _prevState = _curState; diff --git a/arm9/source/romBrowser/RomBrowserStateTrigger.h b/arm9/source/romBrowser/RomBrowserStateTrigger.h index 58473d5..cd9be6b 100644 --- a/arm9/source/romBrowser/RomBrowserStateTrigger.h +++ b/arm9/source/romBrowser/RomBrowserStateTrigger.h @@ -10,5 +10,6 @@ enum class RomBrowserStateTrigger FolderLoadDone, Launch, ShowDisplaySettings, - HideDisplaySettings + HideDisplaySettings, + GotoSettingsScreen }; diff --git a/arm9/source/romBrowser/SdFolder.cpp b/arm9/source/romBrowser/SdFolder.cpp index a52dca1..0392593 100644 --- a/arm9/source/romBrowser/SdFolder.cpp +++ b/arm9/source/romBrowser/SdFolder.cpp @@ -14,10 +14,10 @@ SdFolder::~SdFolder() } std::unique_ptr SdFolder::FilterAndSort( - const SdFolderFilterSortParams& filterSortParams, int& resultCount) const + const SdFolderFilterSortParams& filterSortParams, u32& resultCount) const { auto sortedFilteredFiles = std::make_unique(_fileCount); - int filteredCount = 0; + u32 filteredCount = 0; for (int i = 0; i < _fileCount; i++) { const FileInfo* file = _files[i]; diff --git a/arm9/source/romBrowser/SdFolder.h b/arm9/source/romBrowser/SdFolder.h index 49806b7..db2b1e7 100644 --- a/arm9/source/romBrowser/SdFolder.h +++ b/arm9/source/romBrowser/SdFolder.h @@ -26,7 +26,7 @@ public: /// @param resultCount Will contain the number of results. /// @return A unique pointer to an array of FileInfo pointers containing the results. std::unique_ptr FilterAndSort( - const SdFolderFilterSortParams& filterSortParams, int& resultCount) const; + const SdFolderFilterSortParams& filterSortParams, u32& resultCount) const; void SortByNameInPlace(); const FileInfo* BinarySearch(const char* fileName) const; diff --git a/arm9/source/romBrowser/Theme/IRomBrowserViewFactory.h b/arm9/source/romBrowser/Theme/IRomBrowserViewFactory.h index 93a63ea..6658527 100644 --- a/arm9/source/romBrowser/Theme/IRomBrowserViewFactory.h +++ b/arm9/source/romBrowser/Theme/IRomBrowserViewFactory.h @@ -12,18 +12,18 @@ class VBlankTextureLoader; class RomBrowserViewModel; class IThemeFileIconFactory; class FileRecyclerAdapter; -class RomBrowserItemViewModel; +class IRomBrowserItemViewModel; class IRomBrowserViewFactory { public: virtual ~IRomBrowserViewFactory() = 0; - virtual SharedPtr CreateIconGridItemView(std::unique_ptr viewModel) const = 0; + virtual SharedPtr CreateIconGridItemView(std::unique_ptr viewModel) const = 0; virtual IconGridItemView::VramToken UploadIconGridItemViewGraphics( const VramContext& vramContext) const { return IconGridItemView::VramToken(0); } - virtual SharedPtr CreateBannerListItemView(std::unique_ptr viewModel, + virtual SharedPtr CreateBannerListItemView(std::unique_ptr viewModel, VBlankTextureLoader* vblankTextureLoader) const = 0; virtual BannerListItemView::VramToken UploadBannerListItemViewGraphics( const VramContext& vramContext) const { return BannerListItemView::VramToken(0); } diff --git a/arm9/source/romBrowser/Theme/IThemeFileIconFactory.h b/arm9/source/romBrowser/Theme/IThemeFileIconFactory.h index 96158f0..9431f1c 100644 --- a/arm9/source/romBrowser/Theme/IThemeFileIconFactory.h +++ b/arm9/source/romBrowser/Theme/IThemeFileIconFactory.h @@ -9,6 +9,7 @@ public: virtual std::unique_ptr CreateFolderIcon(const TCHAR* name) const = 0; virtual std::unique_ptr CreateGenericFileIcon(const TCHAR* name) const = 0; virtual std::unique_ptr CreateNdsFileIcon(const TCHAR* name) const = 0; + virtual std::unique_ptr CreateThemeFileIcon() const = 0; }; inline IThemeFileIconFactory::~IThemeFileIconFactory() { } diff --git a/arm9/source/romBrowser/Theme/Material/MaterialBannerListItemView.cpp b/arm9/source/romBrowser/Theme/Material/MaterialBannerListItemView.cpp index ac0dd43..c4f1078 100644 --- a/arm9/source/romBrowser/Theme/Material/MaterialBannerListItemView.cpp +++ b/arm9/source/romBrowser/Theme/Material/MaterialBannerListItemView.cpp @@ -18,12 +18,12 @@ #include "gui/views/Label2DView.h" #include "MaterialBannerListItemView.h" -MaterialBannerListItemView::MaterialBannerListItemView(std::unique_ptr viewModel, +MaterialBannerListItemView::MaterialBannerListItemView(std::unique_ptr viewModel, const MaterialColorScheme* materialColorScheme, const IFontRepository* fontRepository) : BannerListItemView(std::move(viewModel), - Label2DView::CreateShared(160, 16, 50, fontRepository->GetFont(FontType::Medium10)), - Label2DView::CreateShared(160, 16, 50, fontRepository->GetFont(FontType::Regular10)), - Label2DView::CreateShared(160, 16, 50, fontRepository->GetFont(FontType::Regular10))) + Label2DView::CreateShared(152, 16, 128, fontRepository->GetFont(FontType::Medium10)), + Label2DView::CreateShared(152, 16, 128, fontRepository->GetFont(FontType::Regular10)), + Label2DView::CreateShared(152, 16, 128, fontRepository->GetFont(FontType::Regular10))) , _materialColorScheme(materialColorScheme) { } void MaterialBannerListItemView::Draw(GraphicsContext& graphicsContext) diff --git a/arm9/source/romBrowser/Theme/Material/MaterialBannerListItemView.h b/arm9/source/romBrowser/Theme/Material/MaterialBannerListItemView.h index bba63bd..16d9344 100644 --- a/arm9/source/romBrowser/Theme/Material/MaterialBannerListItemView.h +++ b/arm9/source/romBrowser/Theme/Material/MaterialBannerListItemView.h @@ -28,6 +28,6 @@ private: const MaterialColorScheme* _materialColorScheme; u32 _bgVramOffset; - MaterialBannerListItemView(std::unique_ptr viewModel, + MaterialBannerListItemView(std::unique_ptr viewModel, const MaterialColorScheme* materialColorScheme, const IFontRepository* fontRepository); }; diff --git a/arm9/source/romBrowser/Theme/Material/MaterialCoverFlowFileRecyclerAdapter.cpp b/arm9/source/romBrowser/Theme/Material/MaterialCoverFlowFileRecyclerAdapter.cpp index e6e41a8..2b67fb0 100644 --- a/arm9/source/romBrowser/Theme/Material/MaterialCoverFlowFileRecyclerAdapter.cpp +++ b/arm9/source/romBrowser/Theme/Material/MaterialCoverFlowFileRecyclerAdapter.cpp @@ -5,6 +5,7 @@ #include "romBrowser/Theme/IRomBrowserViewFactory.h" #include "romBrowser/FileType/UnknownFileCover.h" #include "romBrowser/ICoverRepository.h" +#include "romBrowser/viewModels/RomBrowserItemViewModel.h" #include "MaterialCoverFlowFileRecyclerAdapter.h" void MaterialCoverFlowFileRecyclerAdapter::GetViewSize(int& width, int& height) const diff --git a/arm9/source/romBrowser/Theme/Material/MaterialCoverView.h b/arm9/source/romBrowser/Theme/Material/MaterialCoverView.h index 82cf65d..ab32ced 100644 --- a/arm9/source/romBrowser/Theme/Material/MaterialCoverView.h +++ b/arm9/source/romBrowser/Theme/Material/MaterialCoverView.h @@ -3,7 +3,7 @@ #include "gui/views/View.h" #include "romBrowser/FileType/FileCover.h" #include "gui/VBlankTextureLoader.h" -#include "romBrowser/viewModels/RomBrowserItemViewModel.h" +#include "romBrowser/viewModels/IRomBrowserItemViewModel.h" #include "romBrowser/views/RomBrowserItemInputHandler.h" class MaterialCoverView : public View @@ -45,13 +45,13 @@ public: void UploadCoverGraphics(); - RomBrowserItemViewModel& GetViewModel() const + IRomBrowserItemViewModel& GetViewModel() const { return *_viewModel; } private: - std::unique_ptr _viewModel; + std::unique_ptr _viewModel; VBlankTextureLoader* _vblankTextureLoader; AtomicSharedPtr _cover; VBlankTextureLoadRequest _textureLoadRequest; @@ -59,7 +59,7 @@ private: u32 _plttVramOffset = 0; RomBrowserItemInputHandler _inputHandler; - MaterialCoverView(std::unique_ptr viewModel, VBlankTextureLoader* vblankTextureLoader) + MaterialCoverView(std::unique_ptr viewModel, VBlankTextureLoader* vblankTextureLoader) : _viewModel(std::move(viewModel)), _vblankTextureLoader(vblankTextureLoader) , _inputHandler(this, _viewModel.get()) { } }; diff --git a/arm9/source/romBrowser/Theme/Material/MaterialFileInfoCardView.cpp b/arm9/source/romBrowser/Theme/Material/MaterialFileInfoCardView.cpp index 4cfcd29..153cbcd 100644 --- a/arm9/source/romBrowser/Theme/Material/MaterialFileInfoCardView.cpp +++ b/arm9/source/romBrowser/Theme/Material/MaterialFileInfoCardView.cpp @@ -13,10 +13,10 @@ MaterialFileInfoCardView::MaterialFileInfoCardView(const MaterialColorScheme* materialColorScheme, const IFontRepository* fontRepository) - : _firstLine(Label2DView::CreateShared(176, 16, 50, fontRepository->GetFont(FontType::Medium11))) - , _secondLine(Label2DView::CreateShared(176, 16, 50, fontRepository->GetFont(FontType::Regular10))) - , _thirdLine(Label2DView::CreateShared(176, 16, 50, fontRepository->GetFont(FontType::Regular10))) - , _filenameLabelView(Label2DView::CreateShared(220, 16, 200, fontRepository->GetFont(FontType::Medium7_5))) + : _firstLine(Label2DView::CreateShared(168, 16, 128, fontRepository->GetFont(FontType::Medium11))) + , _secondLine(Label2DView::CreateShared(168, 16, 128, fontRepository->GetFont(FontType::Regular10))) + , _thirdLine(Label2DView::CreateShared(168, 16, 128, fontRepository->GetFont(FontType::Regular10))) + , _filenameLabelView(Label2DView::CreateShared(220, 16, 256, fontRepository->GetFont(FontType::Medium7_5))) , _materialColorScheme(materialColorScheme) { AddChildTail(_firstLine.GetPointer()); diff --git a/arm9/source/romBrowser/Theme/Material/MaterialFileInfoCardView.h b/arm9/source/romBrowser/Theme/Material/MaterialFileInfoCardView.h index 69e9f38..bba692c 100644 --- a/arm9/source/romBrowser/Theme/Material/MaterialFileInfoCardView.h +++ b/arm9/source/romBrowser/Theme/Material/MaterialFileInfoCardView.h @@ -25,6 +25,15 @@ public: _firstLine->SetText(firstLine); } + void SetFirstLineAsync(TaskQueueBase* taskQueue, const char16_t* firstLine, bool ellipsis) override + { + _firstLine->SetEllipsisStyle(ellipsis ? LabelView::EllipsisStyle::Ellipsis : LabelView::EllipsisStyle::None); + if (taskQueue) + _firstLine->SetTextAsync(taskQueue, firstLine); + else + _firstLine->SetText(firstLine); + } + void SetFirstLineAsync(TaskQueueBase* taskQueue, const char16_t* firstLine, u32 length, bool ellipsis) override { _firstLine->SetEllipsisStyle(ellipsis ? LabelView::EllipsisStyle::Ellipsis : LabelView::EllipsisStyle::None); @@ -34,6 +43,14 @@ public: _firstLine->SetText(firstLine, length); } + void SetSecondLineAsync(TaskQueueBase* taskQueue, const char16_t* secondLine) override + { + if (taskQueue) + _secondLine->SetTextAsync(taskQueue, secondLine); + else + _secondLine->SetText(secondLine); + } + void SetSecondLineAsync(TaskQueueBase* taskQueue, const char16_t* secondLine, u32 length) override { if (taskQueue) @@ -42,6 +59,14 @@ public: _secondLine->SetText(secondLine, length); } + void SetThirdLineAsync(TaskQueueBase* taskQueue, const char16_t* thirdLine) override + { + if (taskQueue) + _thirdLine->SetTextAsync(taskQueue, thirdLine); + else + _thirdLine->SetText(thirdLine); + } + void SetThirdLineAsync(TaskQueueBase* taskQueue, const char16_t* thirdLine, u32 length) override { if (taskQueue) diff --git a/arm9/source/romBrowser/Theme/Material/MaterialIconGridItemView.h b/arm9/source/romBrowser/Theme/Material/MaterialIconGridItemView.h index 6f3048e..db0ce87 100644 --- a/arm9/source/romBrowser/Theme/Material/MaterialIconGridItemView.h +++ b/arm9/source/romBrowser/Theme/Material/MaterialIconGridItemView.h @@ -26,6 +26,6 @@ private: const MaterialColorScheme* _materialColorScheme; u32 _bgVramOffset; - MaterialIconGridItemView(std::unique_ptr viewModel, const MaterialColorScheme* materialColorScheme) + MaterialIconGridItemView(std::unique_ptr viewModel, const MaterialColorScheme* materialColorScheme) : IconGridItemView(std::move(viewModel)), _materialColorScheme(materialColorScheme) { } }; diff --git a/arm9/source/romBrowser/Theme/Material/MaterialRomBrowserViewFactory.h b/arm9/source/romBrowser/Theme/Material/MaterialRomBrowserViewFactory.h index 74b0f3e..f7e31c1 100644 --- a/arm9/source/romBrowser/Theme/Material/MaterialRomBrowserViewFactory.h +++ b/arm9/source/romBrowser/Theme/Material/MaterialRomBrowserViewFactory.h @@ -18,7 +18,7 @@ public: const IFontRepository* fontRepository) : _materialColorScheme(materialColorScheme), _fontRepository(fontRepository) { } - SharedPtr CreateIconGridItemView(std::unique_ptr viewModel) const override + SharedPtr CreateIconGridItemView(std::unique_ptr viewModel) const override { return MaterialIconGridItemView::CreateShared(std::move(viewModel), _materialColorScheme); } @@ -29,7 +29,7 @@ public: return MaterialIconGridItemView::UploadGraphics(vramContext); } - SharedPtr CreateBannerListItemView(std::unique_ptr viewModel, + SharedPtr CreateBannerListItemView(std::unique_ptr viewModel, VBlankTextureLoader* vblankTextureLoader) const override { return MaterialBannerListItemView::CreateShared(std::move(viewModel), _materialColorScheme, _fontRepository); diff --git a/arm9/source/romBrowser/Theme/Material/MaterialThemeFileIcon.h b/arm9/source/romBrowser/Theme/Material/MaterialThemeFileIcon.h new file mode 100644 index 0000000..ea8a8aa --- /dev/null +++ b/arm9/source/romBrowser/Theme/Material/MaterialThemeFileIcon.h @@ -0,0 +1,29 @@ +#pragma once +#include "MaterialFileIcon.h" +#include "themeIconLarge.h" +#include "themes/material/MaterialColorScheme.h" + +class MaterialThemeFileIcon : public MaterialFileIcon +{ +public: + MaterialThemeFileIcon(const MaterialColorScheme* materialColorScheme, const IFontRepository* fontRepository) + : MaterialFileIcon("", materialColorScheme, fontRepository) { } + +protected: + const void* GetIconTiles() const override + { + return themeIconLargeTiles; + } + + Rgb<8, 8, 8> GetIconColor() const override + { + return _materialColorScheme->tertiary; + } + + Rgb<8, 8, 8> GetTextColor() const override + { + return _materialColorScheme->onTertiary; + } + + int GetTextYOffset() const override { return 0; } +}; diff --git a/arm9/source/romBrowser/Theme/Material/MaterialThemeFileIconFactory.h b/arm9/source/romBrowser/Theme/Material/MaterialThemeFileIconFactory.h index 01ebf3a..b74fa11 100644 --- a/arm9/source/romBrowser/Theme/Material/MaterialThemeFileIconFactory.h +++ b/arm9/source/romBrowser/Theme/Material/MaterialThemeFileIconFactory.h @@ -3,6 +3,7 @@ #include "MaterialFolderIcon.h" #include "MaterialGenericFileIcon.h" #include "MaterialNdsFileIcon.h" +#include "MaterialThemeFileIcon.h" class MaterialColorScheme; class IFontRepository; @@ -29,6 +30,11 @@ public: return std::make_unique(name, _materialColorScheme, _fontRepository); } + std::unique_ptr CreateThemeFileIcon() const override + { + return std::make_unique(_materialColorScheme, _fontRepository); + } + private: const MaterialColorScheme* _materialColorScheme; const IFontRepository* _fontRepository; diff --git a/arm9/source/romBrowser/Theme/custom/CustomBannerListItemView.cpp b/arm9/source/romBrowser/Theme/custom/CustomBannerListItemView.cpp index ec47070..a2dea5e 100644 --- a/arm9/source/romBrowser/Theme/custom/CustomBannerListItemView.cpp +++ b/arm9/source/romBrowser/Theme/custom/CustomBannerListItemView.cpp @@ -27,11 +27,11 @@ #define WIDTH 209 #define HEIGHT 49 -#define LINE_WIDTH 160 +#define LINE_WIDTH 152 #define LINE_HEIGHT 16 -#define MAX_LINE_STRING_LENGTH 50 +#define MAX_LINE_STRING_LENGTH 128 -CustomBannerListItemView::CustomBannerListItemView(std::unique_ptr viewModel, +CustomBannerListItemView::CustomBannerListItemView(std::unique_ptr viewModel, const CustomThemeInfo* customThemeInfo, const MaterialColorScheme* materialColorScheme, const IFontRepository* fontRepository, u32 texVramOffset, u32 plttVramOffset, u32 selectedTexVramOffset, u32 selectedPlttVramOffset, diff --git a/arm9/source/romBrowser/Theme/custom/CustomBannerListItemView.h b/arm9/source/romBrowser/Theme/custom/CustomBannerListItemView.h index d7814e4..c427c98 100644 --- a/arm9/source/romBrowser/Theme/custom/CustomBannerListItemView.h +++ b/arm9/source/romBrowser/Theme/custom/CustomBannerListItemView.h @@ -26,7 +26,7 @@ private: u32 _selectedTexVramOffset = 0; u32 _selectedPlttVramOffset = 0; - CustomBannerListItemView(std::unique_ptr viewModel, const CustomThemeInfo* customThemeInfo, + CustomBannerListItemView(std::unique_ptr viewModel, const CustomThemeInfo* customThemeInfo, const MaterialColorScheme* materialColorScheme, const IFontRepository* fontRepository, u32 texVramOffset, u32 plttVramOffset, u32 selectedTexVramOffset, u32 selectedPlttVramOffset, VBlankTextureLoader* vblankTextureLoader); diff --git a/arm9/source/romBrowser/Theme/custom/CustomFileInfoView.cpp b/arm9/source/romBrowser/Theme/custom/CustomFileInfoView.cpp index 6a557ff..e9fd2ab 100644 --- a/arm9/source/romBrowser/Theme/custom/CustomFileInfoView.cpp +++ b/arm9/source/romBrowser/Theme/custom/CustomFileInfoView.cpp @@ -7,11 +7,11 @@ CustomFileInfoView::CustomFileInfoView(const CustomThemeInfo* customThemeInfo, const IFontRepository* fontRepository) : _firstLine(Label2DView::CreateShared( - customThemeInfo->topBannerTextLine0Info.GetWidth(), 16, 50, fontRepository->GetFont(FontType::Medium11))) + customThemeInfo->topBannerTextLine0Info.GetWidth(), 16, 128, fontRepository->GetFont(FontType::Medium11))) , _secondLine(Label2DView::CreateShared( - customThemeInfo->topBannerTextLine1Info.GetWidth(), 16, 50, fontRepository->GetFont(FontType::Regular10))) + customThemeInfo->topBannerTextLine1Info.GetWidth(), 16, 128, fontRepository->GetFont(FontType::Regular10))) , _thirdLine(Label2DView::CreateShared( - customThemeInfo->topBannerTextLine2Info.GetWidth(), 16, 50, fontRepository->GetFont(FontType::Regular10))) + customThemeInfo->topBannerTextLine2Info.GetWidth(), 16, 128, fontRepository->GetFont(FontType::Regular10))) , _filenameLabelView(Label2DView::CreateShared( customThemeInfo->topFileNameTextInfo.GetWidth(), 16, 256, fontRepository->GetFont(FontType::Medium7_5))) , _customThemeInfo(customThemeInfo) diff --git a/arm9/source/romBrowser/Theme/custom/CustomFileInfoView.h b/arm9/source/romBrowser/Theme/custom/CustomFileInfoView.h index 8177783..6cce29a 100644 --- a/arm9/source/romBrowser/Theme/custom/CustomFileInfoView.h +++ b/arm9/source/romBrowser/Theme/custom/CustomFileInfoView.h @@ -24,6 +24,15 @@ public: _firstLine->SetText(firstLine); } + void SetFirstLineAsync(TaskQueueBase* taskQueue, const char16_t* firstLine, bool ellipsis) override + { + _firstLine->SetEllipsisStyle(ellipsis ? LabelView::EllipsisStyle::Ellipsis : LabelView::EllipsisStyle::None); + if (taskQueue) + _firstLine->SetTextAsync(taskQueue, firstLine); + else + _firstLine->SetText(firstLine); + } + void SetFirstLineAsync(TaskQueueBase* taskQueue, const char16_t* firstLine, u32 length, bool ellipsis) override { _firstLine->SetEllipsisStyle(ellipsis ? LabelView::EllipsisStyle::Ellipsis : LabelView::EllipsisStyle::None); @@ -33,6 +42,14 @@ public: _firstLine->SetText(firstLine, length); } + void SetSecondLineAsync(TaskQueueBase* taskQueue, const char16_t* secondLine) override + { + if (taskQueue) + _secondLine->SetTextAsync(taskQueue, secondLine); + else + _secondLine->SetText(secondLine); + } + void SetSecondLineAsync(TaskQueueBase* taskQueue, const char16_t* secondLine, u32 length) override { if (taskQueue) @@ -41,6 +58,14 @@ public: _secondLine->SetText(secondLine, length); } + void SetThirdLineAsync(TaskQueueBase* taskQueue, const char16_t* thirdLine) override + { + if (taskQueue) + _thirdLine->SetTextAsync(taskQueue, thirdLine); + else + _thirdLine->SetText(thirdLine); + } + void SetThirdLineAsync(TaskQueueBase* taskQueue, const char16_t* thirdLine, u32 length) override { if (taskQueue) diff --git a/arm9/source/romBrowser/Theme/custom/CustomIconGridItemView.h b/arm9/source/romBrowser/Theme/custom/CustomIconGridItemView.h index eeb34e7..b9b7d74 100644 --- a/arm9/source/romBrowser/Theme/custom/CustomIconGridItemView.h +++ b/arm9/source/romBrowser/Theme/custom/CustomIconGridItemView.h @@ -22,7 +22,7 @@ private: u32 _selectedTexVramOffset; u32 _selectedPlttVramOffset; - CustomIconGridItemView(std::unique_ptr viewModel, const CustomThemeInfo* customThemeInfo, + CustomIconGridItemView(std::unique_ptr 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) { } diff --git a/arm9/source/romBrowser/Theme/custom/CustomRomBrowserViewFactory.h b/arm9/source/romBrowser/Theme/custom/CustomRomBrowserViewFactory.h index 6b32be5..f125cb2 100644 --- a/arm9/source/romBrowser/Theme/custom/CustomRomBrowserViewFactory.h +++ b/arm9/source/romBrowser/Theme/custom/CustomRomBrowserViewFactory.h @@ -21,13 +21,13 @@ public: const IFontRepository* fontRepository) : _customThemeInfo(customThemeInfo), _materialColorScheme(materialColorScheme), _fontRepository(fontRepository) { } - SharedPtr CreateIconGridItemView(std::unique_ptr viewModel) const override + SharedPtr CreateIconGridItemView(std::unique_ptr viewModel) const override { return CustomIconGridItemView::CreateShared(std::move(viewModel), _customThemeInfo, _gridCellTexVramOffset, _gridCellPlttVramOffset, _gridCellSelectedTexVramOffset, _gridCellSelectedPlttVramOffset); } - SharedPtr CreateBannerListItemView(std::unique_ptr viewModel, + SharedPtr CreateBannerListItemView(std::unique_ptr viewModel, VBlankTextureLoader* vblankTextureLoader) const override { return CustomBannerListItemView::CreateShared(std::move(viewModel), _customThemeInfo, _materialColorScheme, _fontRepository, diff --git a/arm9/source/romBrowser/viewModels/DisplaySettingsViewModel.h b/arm9/source/romBrowser/viewModels/DisplaySettingsViewModel.h index cab9854..ba6b10a 100644 --- a/arm9/source/romBrowser/viewModels/DisplaySettingsViewModel.h +++ b/arm9/source/romBrowser/viewModels/DisplaySettingsViewModel.h @@ -43,6 +43,11 @@ public: _romBrowserController->HideDisplaySettings(); } + void GotoSettingsScreen() + { + _romBrowserController->GotoSettingsScreen(); + } + private: IRomBrowserController* _romBrowserController; RomBrowserDisplaySettings _romBrowserDisplaySettings; diff --git a/arm9/source/romBrowser/viewModels/IRomBrowserItemViewModel.h b/arm9/source/romBrowser/viewModels/IRomBrowserItemViewModel.h new file mode 100644 index 0000000..dd9c7bf --- /dev/null +++ b/arm9/source/romBrowser/viewModels/IRomBrowserItemViewModel.h @@ -0,0 +1,18 @@ +#pragma once +#include "core/task/TaskQueue.h" + +class IRomBrowserItemViewModel +{ +public: + virtual ~IRomBrowserItemViewModel() = default; + + virtual void Activate() = 0; + virtual void ShowGameInfo() = 0; + virtual void SetIndex(int index) = 0; + virtual void SetQueueTask(QueueTask queueTask) = 0; + virtual void CancelQueueTask() = 0; + virtual void DisposeQueueTaskWhenComplete() = 0; + +protected: + IRomBrowserItemViewModel() = default; +}; diff --git a/arm9/source/romBrowser/viewModels/RomBrowserBottomScreenViewModel.h b/arm9/source/romBrowser/viewModels/RomBrowserBottomScreenViewModel.h index 38b779f..bcfd982 100644 --- a/arm9/source/romBrowser/viewModels/RomBrowserBottomScreenViewModel.h +++ b/arm9/source/romBrowser/viewModels/RomBrowserBottomScreenViewModel.h @@ -20,7 +20,8 @@ public: return state == RomBrowserState::Browser || state == RomBrowserState::GameInfo || state == RomBrowserState::DisplaySettings - || state == RomBrowserState::Launching; + || state == RomBrowserState::Launching + || state == RomBrowserState::GoingToSettingsScreen; } const SharedPtr& GetRomBrowserViewModel() diff --git a/arm9/source/romBrowser/viewModels/RomBrowserItemViewModel.h b/arm9/source/romBrowser/viewModels/RomBrowserItemViewModel.h index dcdbf72..2f118e0 100644 --- a/arm9/source/romBrowser/viewModels/RomBrowserItemViewModel.h +++ b/arm9/source/romBrowser/viewModels/RomBrowserItemViewModel.h @@ -1,33 +1,33 @@ #pragma once -#include "core/task/TaskQueue.h" +#include "IRomBrowserItemViewModel.h" class IRomBrowserController; -class RomBrowserItemViewModel +class RomBrowserItemViewModel : public IRomBrowserItemViewModel { public: explicit RomBrowserItemViewModel(IRomBrowserController* romBrowserController) : _romBrowserController(romBrowserController) { } - void Activate(); - void ShowGameInfo(); + void Activate() override; + void ShowGameInfo() override; - void SetIndex(int index) + void SetIndex(int index) override { _index = index; } - void SetQueueTask(QueueTask queueTask) + void SetQueueTask(QueueTask queueTask) override { _queueTask = std::move(queueTask); } - void CancelQueueTask() + void CancelQueueTask() override { _queueTask.CancelTask(); } - void DisposeQueueTaskWhenComplete() + void DisposeQueueTaskWhenComplete() override { if (_queueTask.GetTask().IsCompleted()) { diff --git a/arm9/source/romBrowser/viewModels/RomBrowserViewModel.cpp b/arm9/source/romBrowser/viewModels/RomBrowserViewModel.cpp index 8784931..6ea7b25 100644 --- a/arm9/source/romBrowser/viewModels/RomBrowserViewModel.cpp +++ b/arm9/source/romBrowser/viewModels/RomBrowserViewModel.cpp @@ -31,7 +31,7 @@ RomBrowserViewModel::RomBrowserViewModel(IRomBrowserController* romBrowserContro } u64 startTick = gTickCounter.GetValue(); const auto& sdFolder = romBrowserController->GetSdFolder(); - int filteredCount; + u32 filteredCount; auto sortedFilteredFiles = sdFolder.FilterAndSort(filterSortParams, filteredCount); u64 endTick = gTickCounter.GetValue(); LOG_DEBUG("Filter + sort took: %d us\n", (u32)TickCounter::TicksToMicroSeconds(endTick - startTick)); diff --git a/arm9/source/romBrowser/views/BannerListItemView.cpp b/arm9/source/romBrowser/views/BannerListItemView.cpp index b6987e8..0fab37c 100644 --- a/arm9/source/romBrowser/views/BannerListItemView.cpp +++ b/arm9/source/romBrowser/views/BannerListItemView.cpp @@ -4,7 +4,7 @@ #include "gui/input/InputProvider.h" #include "BannerListItemView.h" -BannerListItemView::BannerListItemView(std::unique_ptr viewModel, +BannerListItemView::BannerListItemView(std::unique_ptr viewModel, SharedPtr firstLine, SharedPtr secondLine, SharedPtr thirdLine) : _viewModel(std::move(viewModel)) , _firstLine(std::move(firstLine)) @@ -21,6 +21,19 @@ void BannerListItemView::Update() { _viewModel->DisposeQueueTaskWhenComplete(); + if (IsFocused()) + { + _firstLine->SetEllipsisStyle(LabelView::EllipsisStyle::Marquee); + _secondLine->SetEllipsisStyle(LabelView::EllipsisStyle::Marquee); + _thirdLine->SetEllipsisStyle(LabelView::EllipsisStyle::Marquee); + } + else + { + _firstLine->SetEllipsisStyle(LabelView::EllipsisStyle::Ellipsis); + _secondLine->SetEllipsisStyle(LabelView::EllipsisStyle::Ellipsis); + _thirdLine->SetEllipsisStyle(LabelView::EllipsisStyle::Ellipsis); + } + ViewContainer::Update(); if (_icon) diff --git a/arm9/source/romBrowser/views/BannerListItemView.h b/arm9/source/romBrowser/views/BannerListItemView.h index f7f3993..79df058 100644 --- a/arm9/source/romBrowser/views/BannerListItemView.h +++ b/arm9/source/romBrowser/views/BannerListItemView.h @@ -2,7 +2,7 @@ #include "BannerView.h" #include "gui/views/LabelView.h" #include "../FileType/FileIcon.h" -#include "romBrowser/viewModels/RomBrowserItemViewModel.h" +#include "romBrowser/viewModels/IRomBrowserItemViewModel.h" #include "RomBrowserItemInputHandler.h" class BannerListItemView : public BannerView @@ -39,6 +39,15 @@ public: _firstLine->SetText(firstLine); } + void SetFirstLineAsync(TaskQueueBase* taskQueue, const char16_t* firstLine, bool ellipsis) override + { + _firstLine->SetEllipsisStyle(ellipsis ? LabelView::EllipsisStyle::Ellipsis : LabelView::EllipsisStyle::None); + if (taskQueue) + _firstLine->SetTextAsync(taskQueue, firstLine); + else + _firstLine->SetText(firstLine); + } + void SetFirstLineAsync(TaskQueueBase* taskQueue, const char16_t* firstLine, u32 length, bool ellipsis) override { _firstLine->SetEllipsisStyle(ellipsis ? LabelView::EllipsisStyle::Ellipsis : LabelView::EllipsisStyle::None); @@ -48,6 +57,14 @@ public: _firstLine->SetText(firstLine, length); } + void SetSecondLineAsync(TaskQueueBase* taskQueue, const char16_t* secondLine) override + { + if (taskQueue) + _secondLine->SetTextAsync(taskQueue, secondLine); + else + _secondLine->SetText(secondLine); + } + void SetSecondLineAsync(TaskQueueBase* taskQueue, const char16_t* secondLine, u32 length) override { if (taskQueue) @@ -56,6 +73,14 @@ public: _secondLine->SetText(secondLine, length); } + void SetThirdLineAsync(TaskQueueBase* taskQueue, const char16_t* thirdLine) override + { + if (taskQueue) + _thirdLine->SetTextAsync(taskQueue, thirdLine); + else + _thirdLine->SetText(thirdLine); + } + void SetThirdLineAsync(TaskQueueBase* taskQueue, const char16_t* thirdLine, u32 length) override { if (taskQueue) @@ -64,18 +89,18 @@ public: _thirdLine->SetText(thirdLine, length); } - RomBrowserItemViewModel& GetViewModel() const + IRomBrowserItemViewModel& GetViewModel() const { return *_viewModel; } protected: - std::unique_ptr _viewModel; + std::unique_ptr _viewModel; SharedPtr _firstLine; SharedPtr _secondLine; SharedPtr _thirdLine; RomBrowserItemInputHandler _inputHandler; - BannerListItemView(std::unique_ptr viewModel, SharedPtr firstLine, + BannerListItemView(std::unique_ptr viewModel, SharedPtr firstLine, SharedPtr secondLine, SharedPtr thirdLine); }; diff --git a/arm9/source/romBrowser/views/BannerView.h b/arm9/source/romBrowser/views/BannerView.h index 93bb97f..d7a6356 100644 --- a/arm9/source/romBrowser/views/BannerView.h +++ b/arm9/source/romBrowser/views/BannerView.h @@ -42,12 +42,15 @@ public: protected: std::unique_ptr _icon = nullptr; - vu16* _iconVram; - u32 _iconVramOffset; - u32 _lines; + vu16* _iconVram = nullptr; + u32 _iconVramOffset = 0; + u32 _lines = 3; virtual void SetFirstLineAsync(TaskQueueBase* taskQueue, const char* firstLine, bool ellipsis) = 0; + virtual void SetFirstLineAsync(TaskQueueBase* taskQueue, const char16_t* firstLine, bool ellipsis) = 0; virtual void SetFirstLineAsync(TaskQueueBase* taskQueue, const char16_t* firstLine, u32 length, bool ellipsis) = 0; + virtual void SetSecondLineAsync(TaskQueueBase* taskQueue, const char16_t* secondLine) = 0; virtual void SetSecondLineAsync(TaskQueueBase* taskQueue, const char16_t* secondLine, u32 length) = 0; + virtual void SetThirdLineAsync(TaskQueueBase* taskQueue, const char16_t* thirdLine) = 0; virtual void SetThirdLineAsync(TaskQueueBase* taskQueue, const char16_t* thirdLine, u32 length) = 0; }; diff --git a/arm9/source/romBrowser/views/CoverView.h b/arm9/source/romBrowser/views/CoverView.h index 7213274..1157917 100644 --- a/arm9/source/romBrowser/views/CoverView.h +++ b/arm9/source/romBrowser/views/CoverView.h @@ -4,7 +4,7 @@ #include "gui/views/View.h" #include "../FileType/FileCover.h" #include "gui/VBlankTextureLoader.h" -#include "romBrowser/viewModels/RomBrowserItemViewModel.h" +#include "romBrowser/viewModels/IRomBrowserItemViewModel.h" #include "RomBrowserItemInputHandler.h" class CoverView : public View @@ -46,13 +46,13 @@ public: void UploadCoverGraphics(); - RomBrowserItemViewModel& GetViewModel() const + IRomBrowserItemViewModel& GetViewModel() const { return *_viewModel; } private: - std::unique_ptr _viewModel; + std::unique_ptr _viewModel; VBlankTextureLoader* _vblankTextureLoader; AtomicSharedPtr _cover; VBlankTextureLoadRequest _textureLoadRequest; @@ -60,7 +60,7 @@ private: u32 _plttVramOffset = 0; RomBrowserItemInputHandler _inputHandler; - CoverView(std::unique_ptr viewModel, VBlankTextureLoader* vblankTextureLoader) + CoverView(std::unique_ptr viewModel, VBlankTextureLoader* vblankTextureLoader) : _viewModel(std::move(viewModel)), _vblankTextureLoader(vblankTextureLoader) , _inputHandler(this, _viewModel.get()) { } }; diff --git a/arm9/source/romBrowser/views/DisplaySettingsBottomSheetView.cpp b/arm9/source/romBrowser/views/DisplaySettingsBottomSheetView.cpp index 3de9fab..4d22208 100644 --- a/arm9/source/romBrowser/views/DisplaySettingsBottomSheetView.cpp +++ b/arm9/source/romBrowser/views/DisplaySettingsBottomSheetView.cpp @@ -15,6 +15,7 @@ #include "moviesIcon.h" #include "unknownIcon.h" #include "coverflowIcon.h" +#include "themeIcon.h" #include "../IRomBrowserController.h" #include "gui/input/InputProvider.h" #include "themes/material/MaterialColorScheme.h" @@ -24,6 +25,9 @@ #define TITLE_LABEL_X 20 #define TITLE_LABEL_Y 16 +#define THEME_BUTTON_X 212 +#define THEME_BUTTON_Y (TITLE_LABEL_Y - 7) + #define LAYOUT_LABEL_X 20 #define LAYOUT_LABEL_Y 46 @@ -53,19 +57,28 @@ DisplaySettingsBottomSheetView::DisplaySettingsBottomSheetView( const IFontRepository* fontRepository) : _viewModel(viewModel) , _titleLabel(Label2DView::CreateShared(128, 16, 25, fontRepository->GetFont(FontType::Medium11))) + , _themeButton(IconButton2DView::CreateShared( + IconButtonView::Type::Standard, + IconButtonView::State::NoToggle, + md::sys::color::inverseOnSurface, + materialColorScheme)) , _layoutLabel(Label2DView::CreateShared(64, 16, 25, fontRepository->GetFont(FontType::Regular10))) , _sortingLabel(Label2DView::CreateShared(64, 16, 25, fontRepository->GetFont(FontType::Regular10))) , _materialColorScheme(materialColorScheme) - // , _filtersLabel(64, 16, 25, fontRepository->GetFont(FontType::Regular10)) { _titleLabel->SetText(u"Display Settings"); AddChildTail(_titleLabel.GetPointer()); + + _themeButton->SetAction([] (IconButtonView*, void* arg) + { + ((DisplaySettingsBottomSheetView*)arg)->_viewModel->GotoSettingsScreen(); + }, this); + AddChildTail(_themeButton.GetPointer()); + _layoutLabel->SetText(u"Layout"); AddChildTail(_layoutLabel.GetPointer()); _sortingLabel->SetText(u"Sorting"); AddChildTail(_sortingLabel.GetPointer()); - // _filtersLabel.SetText(u"Filters"); - // AddChildTail(&_filtersLabel); for (auto& layoutOption : _layoutOptions) { @@ -78,14 +91,6 @@ DisplaySettingsBottomSheetView::DisplaySettingsBottomSheetView( sortOption = CreateSortOptionIconButton(); AddChildTail(sortOption.GetPointer()); } - - // for (auto& filterOption : _filterOptions) - // { - // filterOption = CreateFilterOptionIconButton(); - // AddChildTail(&filterOption); - // } - - // _filterOptions[0].SetState(IconButtonView::State::ToggleSelected); } SharedPtr DisplaySettingsBottomSheetView::CreateLayoutOptionIconButton() @@ -134,18 +139,6 @@ SharedPtr DisplaySettingsBottomSheetView::CreateSortOptionIcon return sortOption; } -// IconButtonView DisplaySettingsBottomSheetView::CreateFilterOptionIconButton() -// { -// IconButtonView filterOption -// { -// IconButtonView::Type::Tonal, -// IconButtonView::State::ToggleUnselected, -// md::sys::color::surfaceContainerLow, -// _materialColorScheme -// }; -// return filterOption; -// } - void DisplaySettingsBottomSheetView::InitVram(const VramContext& vramContext) { BottomSheetView::InitVram(vramContext); @@ -153,6 +146,8 @@ void DisplaySettingsBottomSheetView::InitVram(const VramContext& vramContext) const auto objVramManager = vramContext.GetObjVramManager(); if (objVramManager) { + _themeButton->SetIconVramOffset(LoadIcon(*objVramManager, themeIconTiles, themeIconTilesLen)); + // layout options _layoutOptions[0]->SetIconVramOffset(LoadIcon(*objVramManager, hGridIconTiles, hGridIconTilesLen)); _layoutOptions[1]->SetIconVramOffset(LoadIcon(*objVramManager, vGridIconTiles, vGridIconTilesLen)); @@ -162,14 +157,6 @@ void DisplaySettingsBottomSheetView::InitVram(const VramContext& vramContext) // sort options _sortOptions[0]->SetIconVramOffset(LoadIcon(*objVramManager, sortNameAscendingIconTiles, sortNameAscendingIconTilesLen)); _sortOptions[1]->SetIconVramOffset(LoadIcon(*objVramManager, sortNameDescendingIconTiles, sortNameDescendingIconTilesLen)); - // _sortOptions[2].SetIconVramOffset(LoadIcon(objVramManager, recentIconTiles, recentIconTilesLen)); - - // filter options - // _filterOptions[0].SetIconVramOffset(LoadIcon(objVramManager, gamesIconTiles, gamesIconTilesLen)); - // _filterOptions[1].SetIconVramOffset(LoadIcon(objVramManager, picturesIconTiles, picturesIconTilesLen)); - // _filterOptions[2].SetIconVramOffset(LoadIcon(objVramManager, musicIconTiles, musicIconTilesLen)); - // _filterOptions[3].SetIconVramOffset(LoadIcon(objVramManager, moviesIconTiles, moviesIconTilesLen)); - // _filterOptions[4].SetIconVramOffset(LoadIcon(objVramManager, unknownIconTiles, unknownIconTilesLen)); } } @@ -178,12 +165,12 @@ void DisplaySettingsBottomSheetView::UpdateLabels() _titleLabel->SetPosition(TITLE_LABEL_X, _position.y + TITLE_LABEL_Y); _layoutLabel->SetPosition(LAYOUT_LABEL_X, _position.y + LAYOUT_LABEL_Y); _sortingLabel->SetPosition(SORTING_LABEL_X, _position.y + SORTING_LABEL_Y); - // _filtersLabel.SetPosition(FILTERS_LABEL_X, _position.y + FILTERS_LABEL_Y); } void DisplaySettingsBottomSheetView::Update() { BottomSheetView::Update(); + _themeButton->SetPosition(THEME_BUTTON_X, _position.y + THEME_BUTTON_Y); UpdateLabels(); auto selectedDisplayMode = _viewModel->GetRomBrowserDisplayMode(); int x = 70; @@ -209,12 +196,6 @@ void DisplaySettingsBottomSheetView::Update() x += 32; idx++; } - // x = 70; - // for (auto& filterOption : _filterOptions) - // { - // filterOption.SetPosition(x, _position.y + 102); - // x += 32; - // } } void DisplaySettingsBottomSheetView::Draw(GraphicsContext& graphicsContext) @@ -228,8 +209,6 @@ void DisplaySettingsBottomSheetView::Draw(GraphicsContext& graphicsContext) _layoutLabel->SetForegroundColor(_materialColorScheme->onSurfaceVariant); _sortingLabel->SetBackgroundColor(_materialColorScheme->GetColor(md::sys::color::surfaceContainerLow)); _sortingLabel->SetForegroundColor(_materialColorScheme->onSurfaceVariant); - // _filtersLabel.SetBackgroundColor(_materialColorScheme->GetColor(md::sys::color::surfaceContainerLow)); - // _filtersLabel.SetForegroundColor(_materialColorScheme->onSurfaceVariant); BottomSheetView::Draw(graphicsContext); } graphicsContext.SetPriority(oldPrio); @@ -250,6 +229,18 @@ bool DisplaySettingsBottomSheetView::HandleInput( SharedPtr DisplaySettingsBottomSheetView::MoveFocus(const SharedPtr& currentFocus, FocusMoveDirection direction, View* source) { + if (currentFocus.GetPointer() == _themeButton.GetPointer()) + { + if (direction == FocusMoveDirection::Down) + { + return _layoutOptions[0]; + } + else + { + return nullptr; + } + } + int idx = 0; for (auto& layoutOption : _layoutOptions) { @@ -267,12 +258,10 @@ SharedPtr DisplaySettingsBottomSheetView::MoveFocus(const SharedPtr& idx = 0; return _layoutOptions[idx]; } - // else if (direction == FocusMoveDirection::Up) - // { - // if (idx >= (int)_filterOptions.size()) - // idx = _filterOptions.size() - 1; - // return &_filterOptions[idx]; - // } + else if (direction == FocusMoveDirection::Up) + { + return _themeButton; + } else //if (direction == FocusMoveDirection::Down) { if (idx >= (int)_sortOptions.size()) @@ -299,59 +288,22 @@ SharedPtr DisplaySettingsBottomSheetView::MoveFocus(const SharedPtr& idx = 0; return _sortOptions[idx]; } - else //if (direction == FocusMoveDirection::Up) + else if (direction == FocusMoveDirection::Up) { if (idx >= (int)_layoutOptions.size()) idx = _layoutOptions.size() - 1; return _layoutOptions[idx]; } - // else //if (direction == FocusMoveDirection::Down) - // { - // if (idx >= (int)_filterOptions.size()) - // idx = _filterOptions.size() - 1; - // return &_filterOptions[idx]; - // } } idx++; } - // idx = 0; - // for (auto& filterOption : _filterOptions) - // { - // if (currentFocus == &filterOption) - // { - // if (direction == FocusMoveDirection::Left) - // { - // if (--idx < 0) - // idx += _filterOptions.size(); - // return &_filterOptions[idx]; - // } - // else if (direction == FocusMoveDirection::Right) - // { - // if (++idx >= (int)_filterOptions.size()) - // idx = 0; - // return &_filterOptions[idx]; - // } - // else if (direction == FocusMoveDirection::Up) - // { - // if (idx >= (int)_sortOptions.size()) - // idx = _sortOptions.size() - 1; - // return &_sortOptions[idx]; - // } - // else //if (direction == FocusMoveDirection::Down) - // { - // if (idx >= (int)_layoutOptions.size()) - // idx = _layoutOptions.size() - 1; - // return &_layoutOptions[idx]; - // } - // } - // idx++; - // } return nullptr; } void DisplaySettingsBottomSheetView::SetGraphics( const IconButton2DView::VramToken& iconButtonVramToken) { + _themeButton->SetGraphics(iconButtonVramToken); for (auto& layoutOption : _layoutOptions) { layoutOption->SetGraphics(iconButtonVramToken); @@ -360,8 +312,6 @@ void DisplaySettingsBottomSheetView::SetGraphics( { sortOption->SetGraphics(iconButtonVramToken); } - // for (auto& filterOption : _filterOptions) - // filterOption.SetGraphics(iconButtonVramToken); } void DisplaySettingsBottomSheetView::Close() diff --git a/arm9/source/romBrowser/views/DisplaySettingsBottomSheetView.h b/arm9/source/romBrowser/views/DisplaySettingsBottomSheetView.h index f92d7a2..2699620 100644 --- a/arm9/source/romBrowser/views/DisplaySettingsBottomSheetView.h +++ b/arm9/source/romBrowser/views/DisplaySettingsBottomSheetView.h @@ -35,19 +35,17 @@ private: DisplaySettingsViewModel* _viewModel; SharedPtr _titleLabel; + SharedPtr _themeButton; SharedPtr _layoutLabel; SharedPtr _sortingLabel; - // LabelView _filtersLabel; std::array, 4> _layoutOptions; std::array, /*3*/2> _sortOptions; - // std::array _filterOptions; const MaterialColorScheme* _materialColorScheme; SharedPtr CreateLayoutOptionIconButton(); SharedPtr CreateSortOptionIconButton(); - // IconButton2DView CreateFilterOptionIconButton(); DisplaySettingsBottomSheetView(DisplaySettingsViewModel* viewModel, const MaterialColorScheme* materialColorScheme, const IFontRepository* fontRepository); diff --git a/arm9/source/romBrowser/views/IconGridItemView.h b/arm9/source/romBrowser/views/IconGridItemView.h index 7d80a12..66286f3 100644 --- a/arm9/source/romBrowser/views/IconGridItemView.h +++ b/arm9/source/romBrowser/views/IconGridItemView.h @@ -1,6 +1,6 @@ #pragma once #include -#include "romBrowser/viewModels/RomBrowserItemViewModel.h" +#include "romBrowser/viewModels/IRomBrowserItemViewModel.h" #include "gui/views/View.h" #include "../FileType/FileIcon.h" #include "RomBrowserItemInputHandler.h" @@ -50,18 +50,18 @@ public: virtual void SetGraphics(const VramToken& vramToken) { } - RomBrowserItemViewModel& GetViewModel() const + IRomBrowserItemViewModel& GetViewModel() const { return *_viewModel; } protected: - std::unique_ptr _viewModel; + std::unique_ptr _viewModel; std::unique_ptr _icon; vu16* _iconVram; u32 _iconVramOffset; RomBrowserItemInputHandler _inputHandler; - explicit IconGridItemView(std::unique_ptr viewModel) + explicit IconGridItemView(std::unique_ptr viewModel) : _viewModel(std::move(viewModel)), _inputHandler(this, _viewModel.get()) { } }; diff --git a/arm9/source/romBrowser/views/RomBrowserItemInputHandler.cpp b/arm9/source/romBrowser/views/RomBrowserItemInputHandler.cpp index 0a55296..1798efe 100644 --- a/arm9/source/romBrowser/views/RomBrowserItemInputHandler.cpp +++ b/arm9/source/romBrowser/views/RomBrowserItemInputHandler.cpp @@ -2,7 +2,7 @@ #include "gui/FocusManager.h" #include "gui/input/InputProvider.h" #include "gui/views/View.h" -#include "romBrowser/viewModels/RomBrowserItemViewModel.h" +#include "romBrowser/viewModels/IRomBrowserItemViewModel.h" #include "RomBrowserItemInputHandler.h" #define LONG_PRESS_FRAMES 30 diff --git a/arm9/source/romBrowser/views/RomBrowserItemInputHandler.h b/arm9/source/romBrowser/views/RomBrowserItemInputHandler.h index cc3be78..d491383 100644 --- a/arm9/source/romBrowser/views/RomBrowserItemInputHandler.h +++ b/arm9/source/romBrowser/views/RomBrowserItemInputHandler.h @@ -3,13 +3,13 @@ class InputProvider; class FocusManager; -class RomBrowserItemViewModel; +class IRomBrowserItemViewModel; class View; class RomBrowserItemInputHandler { public: - RomBrowserItemInputHandler(View* view, RomBrowserItemViewModel* viewModel) + RomBrowserItemInputHandler(View* view, IRomBrowserItemViewModel* viewModel) : _view(view), _viewModel(viewModel) { } bool HandleInput(const InputProvider& inputProvider, FocusManager& focusManager); @@ -21,7 +21,7 @@ public: private: View* _view; - RomBrowserItemViewModel* _viewModel; + IRomBrowserItemViewModel* _viewModel; bool _penDown = false; int _penDownFrames = 0; }; diff --git a/arm9/source/services/process/ProcessFactory.thumb.cpp b/arm9/source/services/process/ProcessFactory.thumb.cpp index 67ee9bd..cef570f 100644 --- a/arm9/source/services/process/ProcessFactory.thumb.cpp +++ b/arm9/source/services/process/ProcessFactory.thumb.cpp @@ -6,6 +6,7 @@ #include "bgm/BgmService.h" #include "App.h" #include "PicoLoaderProcess.h" +#include "settings/SettingsProcess.h" #include "ProcessFactory.h" namespace di = boost::di; @@ -35,3 +36,4 @@ static auto diConfig = [] { return di::make_injector( REGISTER_PROCESS(App); REGISTER_PROCESS(PicoLoaderProcess); +REGISTER_PROCESS(SettingsProcess); diff --git a/arm9/source/settings/ISettingsController.h b/arm9/source/settings/ISettingsController.h new file mode 100644 index 0000000..d64f067 --- /dev/null +++ b/arm9/source/settings/ISettingsController.h @@ -0,0 +1,18 @@ +#pragma once +class TaskQueueBase; +class ThemeInfoManager; +class ThemeRepository; + +class ISettingsController +{ +public: + virtual ~ISettingsController() = default; + + virtual void Initialize() = 0; + virtual void NavigateUp() = 0; + virtual void SelectTheme(const char* themeFolderName) = 0; + + virtual ThemeInfoManager& GetThemeInfoManager() const = 0; + virtual const ThemeRepository& GetThemeRepository() const = 0; + virtual TaskQueueBase* GetIoTaskQueue() const = 0; +}; diff --git a/arm9/source/settings/SettingsController.cpp b/arm9/source/settings/SettingsController.cpp new file mode 100644 index 0000000..ecfe19c --- /dev/null +++ b/arm9/source/settings/SettingsController.cpp @@ -0,0 +1,28 @@ +#include "common.h" +#include "App.h" +#include "SettingsController.h" + +SettingsController::SettingsController(IAppSettingsService* appSettingsService, TaskQueueBase* ioTaskQueue) + : _appSettingsService(appSettingsService), _ioTaskQueue(ioTaskQueue) { } + +void SettingsController::Initialize() +{ + _themeRepository.Initialize(); + _themeInfoManager = std::make_unique(_themeRepository); +} + +void SettingsController::NavigateUp() +{ + gProcessManager.Goto(); +} + +void SettingsController::SelectTheme(const char* themeFolderName) +{ + _appSettingsService->GetAppSettings().theme = themeFolderName; + _ioTaskQueue->Enqueue([this] (const vu8& cancelRequested) + { + _appSettingsService->Save(); + return TaskResult::Completed(); + }); + gProcessManager.Goto(); +} diff --git a/arm9/source/settings/SettingsController.h b/arm9/source/settings/SettingsController.h new file mode 100644 index 0000000..349bc29 --- /dev/null +++ b/arm9/source/settings/SettingsController.h @@ -0,0 +1,26 @@ +#pragma once +#include "ISettingsController.h" +#include "ThemeInfoManager.h" +#include "themes/ThemeRepository.h" + +class IAppSettingsService; + +class SettingsController : public ISettingsController +{ +public: + SettingsController(IAppSettingsService* appSettingsService, TaskQueueBase* ioTaskQueue); + + void Initialize() override; + void NavigateUp() override; + void SelectTheme(const char* themeFolderName) override; + + ThemeInfoManager& GetThemeInfoManager() const override { return *_themeInfoManager; } + const ThemeRepository& GetThemeRepository() const override { return _themeRepository; } + TaskQueueBase* GetIoTaskQueue() const override { return _ioTaskQueue; } + +private: + IAppSettingsService* _appSettingsService; + TaskQueueBase* _ioTaskQueue; + ThemeRepository _themeRepository; + std::unique_ptr _themeInfoManager; +}; diff --git a/arm9/source/settings/SettingsProcess.cpp b/arm9/source/settings/SettingsProcess.cpp new file mode 100644 index 0000000..64e4e68 --- /dev/null +++ b/arm9/source/settings/SettingsProcess.cpp @@ -0,0 +1,307 @@ +#include "common.h" +#include +#include +#include +#include +#include +#include +#include +#include "core/math/RgbMixer.h" +#include "gui/GraphicsContext.h" +#include "gui/Gx.h" +#include "settings/viewModels/ThemeListViewModel.h" +#include "themes/ThemeInfoFactory.h" +#include "themes/ThemeFactory.h" +#include "SettingsProcess.h" + +SettingsProcess::SettingsProcess(IAppSettingsService& appSettingsService) + : _mainObjPltt(GFX_PLTT_OBJ_MAIN) + , _mainObjVram(GFX_OBJ_MAIN) + , _subObjVram(GFX_OBJ_SUB) + , _textureVram((vu16*)0x06860000) + , _texturePaletteVram((vu16*)0x6880000) + , _mainVramContext(nullptr, &_mainObjVram, &_textureVram, &_texturePaletteVram) + , _subVramContext(nullptr, &_subObjVram, nullptr, nullptr) + , _appSettingsService(appSettingsService) + , _inputProvider(&_keyInputSource, &_touchInputSource) + , _inputRepeater(&_inputProvider, + InputKey::DpadLeft | InputKey::DpadRight | InputKey::DpadUp | InputKey::DpadDown | InputKey::L | InputKey::R, + 25, 8) { } + +void SettingsProcess::Run() +{ + InitVramMapping(); + gx_init(); + + _chipViewVram = ChipView::UploadGraphics(_mainObjVram); + _iconButtonViewVram = IconButton2DView::UploadGraphics(_mainObjVram); + + mem_setVramEMapping(MEM_VRAM_E_LCDC); + _rgb6Palette.UploadGraphics(_mainVramContext); + mem_setVramEMapping(MEM_VRAM_E_TEX_PLTT_SLOT_0123); + + LoadTheme(); + + _settingsController = std::make_unique(&_appSettingsService, &_ioTaskQueue); + _settingsController->Initialize(); + + auto viewModel = SharedPtr::MakeShared(_settingsController.get()); + _themeListBottomView = ThemeListBottomView::CreateShared(viewModel, + &_theme->GetMaterialColorScheme(), _theme->GetRomBrowserViewFactory(), + _theme->GetThemeFileIconFactory(), &_vblankTextureLoader); + _themeListBottomView->InitVram(_mainVramContext); + _themeListBottomView->Focus(_focusManager); + + _themeListTopView = ThemeListTopView::CreateShared(viewModel, &_theme->GetMaterialColorScheme(), _theme->GetFontRepository()); + _themeListTopView->InitVram(_subVramContext); + + _ioTaskQueue.StartThread(1, _ioTaskThreadStack, sizeof(_ioTaskThreadStack)); + + const auto& materialColorScheme = _theme->GetMaterialColorScheme(); + + auto scrimBlendColor = Rgb<8, 8, 8>( + materialColorScheme.inverseOnSurface.r + (materialColorScheme.scrim.r - materialColorScheme.inverseOnSurface.r) * 5 / 16, + materialColorScheme.inverseOnSurface.g + (materialColorScheme.scrim.g - materialColorScheme.inverseOnSurface.g) * 5 / 16, + materialColorScheme.inverseOnSurface.b + (materialColorScheme.scrim.b - materialColorScheme.inverseOnSurface.b) * 5 / 16); + + RgbMixer::MakeGradientPalette((u16*)GFX_PLTT_BG_MAIN, scrimBlendColor, materialColorScheme.GetColor(md::sys::color::surfaceContainerLow)); + + GFX_PLTT_BG_MAIN[0] = ColorConverter::ToGBGR565(materialColorScheme.inverseOnSurface); + GFX_PLTT_BG_MAIN[31] = ColorConverter::ToGBGR565(materialColorScheme.scrim); + REG_DISPCNT = 0x21191B; + REG_BG0HOFS = 0; + REG_BG0VOFS = 0; + REG_BG0CNT = 3; + REG_DISPCNT_SUB = 0x40211015; + GFX_PLTT_BG_SUB[0] = ColorConverter::ToGBGR565(materialColorScheme.inverseOnSurface); + + REG_DMA3FILL = 0; + dma_ntrSetParams(3, (const void*)®_DMA3FILL, GFX_BG_SUB, + DMACNT_ENABLE | DMACNT_MODE_IMMEDIATE | DMACNT_32BIT | + DMACNT_SRC_MODE_FIXED | DMACNT_DST_MODE_INCREMENT | + DMACNT_COUNT((256 * 192 * 2) >> 2)); + dma_ntrWait(3); + + Gx::MtxMode(GX_MTX_MODE_PROJECTION); + mtx43_t orthoMtx = + { + 2048, 0, 0, + 0, -21845, 0, + 0, 0, 4096 >> 5, + -4096, 4096, 0 + }; + Gx::MtxLoad43(&orthoMtx); + + _vcountIrqStarted = false; + rtos_disableIrqMask(RTOS_IRQ_VCOUNT); + rtos_setIrqFunc(RTOS_IRQ_VCOUNT, [] (u32 mask) { ((SettingsProcess*)gProcessManager.GetRunningProcess())->VCountIrq(); }); + + _fadeAnimator = Animator(16, 0, 16, &md::sys::motion::easing::linear); + + MainLoop(); + + rtos_disableIrqMask(RTOS_IRQ_VCOUNT); + rtos_setIrqFunc(RTOS_IRQ_VCOUNT, nullptr); +} + +void SettingsProcess::Exit() +{ + _fadeAnimator.Goto(16, 16, &md::sys::motion::easing::linear); + _exit = true; +} + +void SettingsProcess::InitVramMapping() const +{ + mem_setVramAMapping(MEM_VRAM_AB_TEX_SLOT_1); + mem_setVramBMapping(MEM_VRAM_AB_MAIN_OBJ_00000); + mem_setVramCMapping(MEM_VRAM_C_SUB_BG_00000); + mem_setVramDMapping(MEM_VRAM_D_TEX_SLOT_0); + mem_setVramEMapping(MEM_VRAM_E_TEX_PLTT_SLOT_0123); + mem_setVramFMapping(MEM_VRAM_FG_MAIN_BG_00000); + mem_setVramGMapping(MEM_VRAM_FG_MAIN_BG_04000); + mem_setVramHMapping(MEM_VRAM_H_SUB_BG_EXT_PLTT_SLOT_0123); + mem_setVramIMapping(MEM_VRAM_I_SUB_OBJ_00000); +} + +void SettingsProcess::LoadTheme() +{ + ThemeInfoFactory themeInfoFactory; + auto themeInfo = themeInfoFactory.CreateFromThemeFolder(_appSettingsService.GetAppSettings().theme); + if (!themeInfo) + { + LOG_DEBUG("Failed to load theme '%s'. Using fallback theme.\n", _appSettingsService.GetAppSettings().theme.GetString()); + themeInfo = themeInfoFactory.CreateFallbackTheme(); + } + _theme = ThemeFactory().CreateFromThemeInfo(themeInfo.get()); + themeInfo.reset(); + _theme->LoadRomBrowserResources(_mainVramContext, _subVramContext); + // _topBackground = _theme->CreateRomBrowserTopBackground(); + // _topBackground->LoadResources(*_theme, _subVramContext); + _bottomBackground = _theme->CreateRomBrowserBottomBackground(); + _bottomBackground->LoadResources(*_theme, _mainVramContext); +} + +void SettingsProcess::MainLoop() +{ + bool fadeIn = true; + while (true) + { + Update(); + Draw(); + VBlank::Wait(); + VBlank(); + if (_exit) + { + bool fadeComplete = _fadeAnimator.Update(); + REG_MASTER_BRIGHT = 0x4000 | _fadeAnimator.GetValue(); + REG_MASTER_BRIGHT_SUB = 0x4000 | _fadeAnimator.GetValue(); + if (fadeComplete) + { + break; + } + } + else if (fadeIn) + { + bool fadeComplete = _fadeAnimator.Update(); + if (fadeComplete) + { + fadeIn = false; + REG_BLDCNT_SUB = 0; + REG_MASTER_BRIGHT = 0; + REG_MASTER_BRIGHT_SUB = 0; + } + else + { + int fade = _fadeAnimator.GetValue(); + REG_MASTER_BRIGHT = 0x4000 | fade; + REG_MASTER_BRIGHT_SUB = 0x4000 | fade; + } + } + } +} + +void SettingsProcess::Update() +{ + if (!_exit) + { + HandleInput(); + } + + // if (_topBackground) + // { + // _topBackground->Update(); + // } + if (_bottomBackground) + { + _bottomBackground->Update(); + } + + _themeListBottomView->Update(); + _themeListTopView->Update(); +} + +void SettingsProcess::HandleInput() +{ + _focusManager.Update(_inputRepeater); + Point touchPoint; + if (_inputRepeater.Triggered(InputKey::Touch) && + _inputRepeater.GetCurrentTouchPoint(touchPoint)) + { + // pen down + _themeListBottomView->HandlePenDown(touchPoint, _focusManager); + _lastTouchPoint = touchPoint; + } + else if (_inputRepeater.Released(InputKey::Touch)) + { + // pen up + _themeListBottomView->HandlePenUp(_lastTouchPoint, _focusManager); + } + else if (_inputRepeater.Current(InputKey::Touch) + && _inputRepeater.GetCurrentTouchPoint(touchPoint)) + { + // pen move + _themeListBottomView->HandlePenMove(touchPoint, _focusManager); + _lastTouchPoint = touchPoint; + } +} + +void SettingsProcess::Draw() +{ + gx_reset(); + Gx::Viewport(0, 0, 255, 191); + Gx::MtxMode(GX_MTX_MODE_POSITION_VECTOR); + Gx::MtxIdentity(); + + GraphicsContext mainGraphicsContext + { + &_mainOam, + &_mainObjPltt, + &_rgb6Palette + }; + GraphicsContext subGraphicsContext + { + &_subOam, + &_subObjPltt, + nullptr + }; + + _mainOam.Clear(); + _subOam.Clear(); + _mainObjPltt.Reset(); + _subObjPltt.Reset(); + mainGraphicsContext.SetPriority(3); + subGraphicsContext.SetPriority(2); + + // if (_topBackground) + // { + // _topBackground->Draw(subGraphicsContext); + // } + if (_bottomBackground) + { + _bottomBackground->Draw(mainGraphicsContext); + } + + _themeListBottomView->Draw(mainGraphicsContext); + _themeListTopView->Draw(subGraphicsContext); + + _mainObjPltt.EndOfFrame(); + + Gx::SwapBuffers(GX_XLU_SORT_MANUAL, GX_DEPTH_MODE_Z); +} + +void SettingsProcess::VBlank() +{ + dma_ntrStopDirect(0); // stop hblank dma + _inputProvider.Sample(); + _inputRepeater.Update(); + _mainOam.Apply(GFX_OAM_MAIN); + _subOam.Apply(GFX_OAM_SUB); + _subObjPltt.Apply(GFX_PLTT_OBJ_SUB); + + if (!_vcountIrqStarted) + { + rtos_ackIrqMask(RTOS_IRQ_VCOUNT); + rtos_enableIrqMask(RTOS_IRQ_VCOUNT); + _vcountIrqStarted = true; + } + _mainObjPltt.VBlank(); + + // if (_topBackground) + // { + // _topBackground->VBlank(); + // } + if (_bottomBackground) + { + _bottomBackground->VBlank(); + } + + _themeListBottomView->VBlank(); + _vblankTextureLoader.VBlank(); + + _themeListTopView->VBlank(); +} + +void SettingsProcess::VCountIrq() +{ + _mainObjPltt.VCount(); +} diff --git a/arm9/source/settings/SettingsProcess.h b/arm9/source/settings/SettingsProcess.h new file mode 100644 index 0000000..f51aafa --- /dev/null +++ b/arm9/source/settings/SettingsProcess.h @@ -0,0 +1,86 @@ +#pragma once +#include +#include "SettingsController.h" +#include "animation/Animator.h" +#include "core/task/TaskQueue.h" +#include "gui/AdvancedPaletteManager.h" +#include "gui/AscendingStackVramManager.h" +#include "gui/OamManager.h" +#include "gui/Rgb6Palette.h" +#include "gui/SimplePaletteManager.h" +#include "gui/VBlankTextureLoader.h" +#include "gui/VramContext.h" +#include "gui/input/InputRepeater.h" +#include "gui/input/PadInputSource.h" +#include "gui/input/SampledInputProvider.h" +#include "gui/input/TouchInputSource.h" +#include "romBrowser/views/ChipView.h" +#include "romBrowser/views/IconButton2DView.h" +#include "settings/views/ThemeListTopView.h" +#include "settings/views/ThemeListBottomView.h" +#include "themes/ITheme.h" +#include "services/process/IProcess.h" +#include "services/settings/IAppSettingsService.h" + +class SettingsController; + +class alignas(32) SettingsProcess : public IProcess +{ +public: + SettingsProcess(IAppSettingsService& appSettingsService); + + void Run() override; + void Exit() override; + +private: + AdvancedPaletteManager<64> _mainObjPltt; + OamManager _mainOam; + AscendingStackVramManager _mainObjVram; + OamManager _subOam; + SimplePaletteManager _subObjPltt; + AscendingStackVramManager _subObjVram; + AscendingStackVramManager _textureVram; + AscendingStackVramManager _texturePaletteVram; + VBlankTextureLoader _vblankTextureLoader; + VramContext _mainVramContext; + VramContext _subVramContext; + Rgb6Palette _rgb6Palette; + Animator _fadeAnimator; + + TaskQueue<32, sizeof(TaskBase) + 32> _ioTaskQueue; + u32 _ioTaskThreadStack[2048 / 4]; + + std::unique_ptr _theme; + std::unique_ptr _topBackground; + std::unique_ptr _bottomBackground; + + IAppSettingsService& _appSettingsService; + volatile bool _exit = false; + + PadInputSource _keyInputSource; + TouchInputSource _touchInputSource; + SampledInputProvider _inputProvider; + InputRepeater _inputRepeater; + + FocusManager _focusManager; + + ChipView::VramToken _chipViewVram; + IconButton2DView::VramToken _iconButtonViewVram; + + bool _vcountIrqStarted = false; + + Point _lastTouchPoint = Point(0, 0); + + std::unique_ptr _settingsController; + SharedPtr _themeListTopView; + SharedPtr _themeListBottomView; + + void InitVramMapping() const; + void LoadTheme(); + void MainLoop(); + void Update(); + void HandleInput(); + void Draw(); + void VBlank(); + void VCountIrq(); +}; diff --git a/arm9/source/settings/ThemeInfoManager.cpp b/arm9/source/settings/ThemeInfoManager.cpp new file mode 100644 index 0000000..2516639 --- /dev/null +++ b/arm9/source/settings/ThemeInfoManager.cpp @@ -0,0 +1,81 @@ +#include "common.h" +#include +#include "core/mini-printf.h" +#include "fat/Directory.h" +#include "fat/File.h" +#include "ThemeInfoManager.h" + +ThemeInfoManager::ThemeInfoManager(const ThemeRepository& themeRepository) + : _themeRepository(themeRepository) + , _extraThemeInfo(std::make_unique[]>(themeRepository.GetThemeCount())) { } + +void ThemeInfoManager::LoadThemeInfo(int index) +{ + auto extraThemeInfo = SharedPtr::MakeShared(); + extraThemeInfo->themeInfo = _themeRepository.LoadThemeInfo(index); + if (extraThemeInfo->themeInfo) + { + LoadThemeIcon(extraThemeInfo); + LoadThemePreviewImage(extraThemeInfo); + _extraThemeInfo[index] = std::move(extraThemeInfo); + } +} + +void ThemeInfoManager::ReleaseThemeInfo(int index) +{ + _extraThemeInfo[index].Reset(); +} + +void ThemeInfoManager::LoadThemeIcon(SharedPtr& extraThemeInfo) +{ + char pathBuffer[256]; + mini_snprintf(pathBuffer, sizeof(pathBuffer), "/_pico/themes/%s", extraThemeInfo->themeInfo->GetFolderName()); + auto folderDir = std::make_unique(); + if (folderDir->Open(pathBuffer) == FR_OK) + { + FILINFO folderFileInfo; + while (folderDir->Read(&folderFileInfo) == FR_OK && folderFileInfo.fname[0] != 0) + { + if (!(folderFileInfo.fattrib & AM_DIR) && !strcasecmp(folderFileInfo.fname, "icon.bmp")) + { + extraThemeInfo->iconData = SharedPtr::MakeShared( + FastFileRef(folderDir->GetFatFsDirectory(), &folderFileInfo)); + break; + } + } + } +} + +void ThemeInfoManager::LoadThemePreviewImage(SharedPtr& extraThemeInfo) +{ + bool previewOk = false; + char pathBuffer[256]; + mini_snprintf(pathBuffer, sizeof(pathBuffer), "/_pico/themes/%s/preview.bin", extraThemeInfo->themeInfo->GetFolderName()); + auto file = std::make_unique(); + if (file->Open(pathBuffer, FA_READ) == FR_OK && + file->ReadExact(extraThemeInfo->previewImage, 256 * 192 * 2)) + { + previewOk = true; + } + file->Close(); + + if (!previewOk) + { + if (extraThemeInfo->themeInfo->GetType() == ThemeType::Custom) + { + mini_snprintf(pathBuffer, sizeof(pathBuffer), "/_pico/themes/%s/topbg.bin", extraThemeInfo->themeInfo->GetFolderName()); + if (file->Open(pathBuffer, FA_READ) == FR_OK && + file->ReadExact(extraThemeInfo->previewImage, 256 * 192 * 2)) + { + previewOk = true; + } + } + } + + if (!previewOk) + { + memset(extraThemeInfo->previewImage, 0, 256 * 192 * 2); + } + + DC_FlushRange(extraThemeInfo->previewImage, 256 * 192 * 2); +} diff --git a/arm9/source/settings/ThemeInfoManager.h b/arm9/source/settings/ThemeInfoManager.h new file mode 100644 index 0000000..60b71d7 --- /dev/null +++ b/arm9/source/settings/ThemeInfoManager.h @@ -0,0 +1,36 @@ +#pragma once +#include "common.h" +#include +#include "romBrowser/FileType/BmpFileIconData.h" +#include "themes/ThemeRepository.h" +#include "core/AtomicSharedPtr.h" + +class ThemeInfoManager +{ +public: + struct alignas(32) ExtraThemeInfo + { + u16 previewImage[256 * 192]; + std::unique_ptr themeInfo; + SharedPtr iconData; + }; + + ThemeInfoManager(const ThemeRepository& themeRepository); + + SharedPtr GetExtraThemeInfo(int index) const + { + return _extraThemeInfo[index].Lock(); + } + + void LoadThemeInfo(int index); + void ReleaseThemeInfo(int index); + + u32 GetItemCount() const { return _themeRepository.GetThemeCount(); } + +private: + const ThemeRepository& _themeRepository; + std::unique_ptr[]> _extraThemeInfo; + + void LoadThemeIcon(SharedPtr& extraThemeInfo); + void LoadThemePreviewImage(SharedPtr& extraThemeInfo); +}; \ No newline at end of file diff --git a/arm9/source/settings/viewModels/ThemeListItemViewModel.cpp b/arm9/source/settings/viewModels/ThemeListItemViewModel.cpp new file mode 100644 index 0000000..44ab19f --- /dev/null +++ b/arm9/source/settings/viewModels/ThemeListItemViewModel.cpp @@ -0,0 +1,11 @@ +#include "common.h" +#include "settings/ISettingsController.h" +#include "ThemeListItemViewModel.h" + +void ThemeListItemViewModel::Activate() +{ + if (_extraThemeInfo) + { + _settingsController->SelectTheme(_extraThemeInfo->themeInfo->GetFolderName()); + } +} diff --git a/arm9/source/settings/viewModels/ThemeListItemViewModel.h b/arm9/source/settings/viewModels/ThemeListItemViewModel.h new file mode 100644 index 0000000..f49308f --- /dev/null +++ b/arm9/source/settings/viewModels/ThemeListItemViewModel.h @@ -0,0 +1,58 @@ +#pragma once +#include "core/SharedPtr.h" +#include "romBrowser/viewModels/IRomBrowserItemViewModel.h" +#include "settings/ThemeInfoManager.h" +#include "themes/ThemeInfo.h" + +class ISettingsController; + +class ThemeListItemViewModel : public IRomBrowserItemViewModel +{ +public: + explicit ThemeListItemViewModel(ISettingsController* settingsController) + : _settingsController(settingsController) { } + + void Activate() override; + + void ShowGameInfo() override { } + + void SetIndex(int index) override + { + _index = index; + } + + void SetQueueTask(QueueTask queueTask) override + { + _queueTask = std::move(queueTask); + } + + void CancelQueueTask() override + { + _queueTask.CancelTask(); + } + + void DisposeQueueTaskWhenComplete() override + { + if (_queueTask.GetTask().IsCompleted()) + { + _queueTask.Dispose(); + } + } + + const ThemeInfoManager::ExtraThemeInfo* GetExtraThemeInfo() const + { + return _extraThemeInfo.GetPointer(); + } + + void SetExtraThemeInfo(SharedPtr extraThemeInfo) + { + _extraThemeInfo = std::move(extraThemeInfo); + } + +private: + int _index = -1; + QueueTask _queueTask; + SharedPtr _extraThemeInfo; + + ISettingsController* _settingsController; +}; diff --git a/arm9/source/settings/viewModels/ThemeListViewModel.cpp b/arm9/source/settings/viewModels/ThemeListViewModel.cpp new file mode 100644 index 0000000..02b6ed2 --- /dev/null +++ b/arm9/source/settings/viewModels/ThemeListViewModel.cpp @@ -0,0 +1,11 @@ +#include "common.h" +#include "settings/ISettingsController.h" +#include "ThemeListViewModel.h" + +ThemeListViewModel::ThemeListViewModel(ISettingsController* settingsController) + : _settingsController(settingsController) { } + +void ThemeListViewModel::NavigateUp() const +{ + _settingsController->NavigateUp(); +} diff --git a/arm9/source/settings/viewModels/ThemeListViewModel.h b/arm9/source/settings/viewModels/ThemeListViewModel.h new file mode 100644 index 0000000..6c51e2e --- /dev/null +++ b/arm9/source/settings/viewModels/ThemeListViewModel.h @@ -0,0 +1,23 @@ +#pragma once + +class ISettingsController; + +class ThemeListViewModel +{ +public: + explicit ThemeListViewModel(ISettingsController* settingsController); + + void NavigateUp() const; + + ISettingsController* GetSettingsController() const + { + return _settingsController; + } + + constexpr int GetSelectedItem() const { return _selectedItem; } + void SetSelectedItem(int selectedItem) { _selectedItem = selectedItem; } + +private: + ISettingsController* _settingsController; + int _selectedItem = -1; +}; diff --git a/arm9/source/settings/views/SettingsAppBarView.cpp b/arm9/source/settings/views/SettingsAppBarView.cpp new file mode 100644 index 0000000..8e710d6 --- /dev/null +++ b/arm9/source/settings/views/SettingsAppBarView.cpp @@ -0,0 +1,49 @@ +#include "common.h" +#include "backIcon.h" +#include "gui/GraphicsContext.h" +#include "gui/VramContext.h" +#include "gui/IVramManager.h" +#include "romBrowser/Theme/IRomBrowserViewFactory.h" +#include "SettingsAppBarView.h" + +SettingsAppBarView::SettingsAppBarView(SharedPtr viewModel, const IRomBrowserViewFactory* romBrowserViewFactory) + : _viewModel(std::move(viewModel)) +{ + _appBarView = romBrowserViewFactory->CreateAppBarView(0, 0, AppBarView::Orientation::Vertical, 1, 0); + AddChildTail(_appBarView.GetPointer()); + + _appBarView->SetButtonAction(APP_BAR_BUTTON_BACK, [] (IconButtonView* sender, void* arg) + { + ((ThemeListViewModel*)arg)->NavigateUp(); + }, _viewModel.GetPointer()); +} + +void SettingsAppBarView::InitVram(const VramContext& vramContext) +{ + ViewContainer::InitVram(vramContext); + + const auto objVramManager = vramContext.GetObjVramManager(); + if (objVramManager) + { + u32 backIconVramOffset = objVramManager->Alloc(backIconTilesLen); + dma_ntrCopy32(3, backIconTiles, objVramManager->GetVramAddress(backIconVramOffset), backIconTilesLen); + _appBarView->SetButtonIcon(APP_BAR_BUTTON_BACK, backIconVramOffset); + } +} + +SharedPtr SettingsAppBarView::MoveFocus(const SharedPtr& currentFocus, FocusMoveDirection direction, View* source) +{ + if (!currentFocus) + { + return nullptr; + } + if (source == _appBarView.GetPointer()) + { + return View::MoveFocus(currentFocus, direction, source); + } + else if (source == GetParent()) + { + return _appBarView->MoveFocus(currentFocus, direction, this); + } + return nullptr; +} diff --git a/arm9/source/settings/views/SettingsAppBarView.h b/arm9/source/settings/views/SettingsAppBarView.h new file mode 100644 index 0000000..42d1ead --- /dev/null +++ b/arm9/source/settings/views/SettingsAppBarView.h @@ -0,0 +1,38 @@ +#pragma once +#include "romBrowser/views/AppBarView.h" +#include "gui/views/ViewContainer.h" +#include "settings/viewModels/ThemeListViewModel.h" + +class RomBrowserDisplayMode; +class IRomBrowserViewFactory; + +class SettingsAppBarView : public ViewContainer +{ + SHARED_ONLY(SettingsAppBarView) + +public: + void InitVram(const VramContext& vramContext) override; + + Rectangle GetBounds() const override + { + return Rectangle(0, 0, 256, 192); + } + + SharedPtr MoveFocus(const SharedPtr& currentFocus, FocusMoveDirection direction, View* source) override; + + void Focus(FocusManager& focusManager) + { + _appBarView->Focus(focusManager, 0); + } + +private: + enum AppBarButton + { + APP_BAR_BUTTON_BACK = 0 + }; + + SharedPtr _viewModel; + SharedPtr _appBarView; + + SettingsAppBarView(SharedPtr viewModel, const IRomBrowserViewFactory* romBrowserViewFactory); +}; diff --git a/arm9/source/settings/views/ThemeAdapter.cpp b/arm9/source/settings/views/ThemeAdapter.cpp new file mode 100644 index 0000000..4c67650 --- /dev/null +++ b/arm9/source/settings/views/ThemeAdapter.cpp @@ -0,0 +1,91 @@ +#include "common.h" +#include "romBrowser/FileType/BmpFileIcon.h" +#include "romBrowser/Theme/IRomBrowserViewFactory.h" +#include "romBrowser/Theme/IThemeFileIconFactory.h" +#include "settings/SettingsController.h" +#include "settings/ThemeInfoManager.h" +#include "settings/viewModels/ThemeListItemViewModel.h" +#include "themes/ThemeInfo.h" +#include "ThemeAdapter.h" + +ThemeAdapter::ThemeAdapter(ISettingsController* settingsController, const IRomBrowserViewFactory* romBrowserViewFactory, + const IThemeFileIconFactory* themeFileIconFactory, VBlankTextureLoader* vblankTextureLoader) + : _settingsController(settingsController), _romBrowserViewFactory(romBrowserViewFactory) + , _themeFileIconFactory(themeFileIconFactory), _vblankTextureLoader(vblankTextureLoader) { } + +u32 ThemeAdapter::GetItemCount() const +{ + return _settingsController->GetThemeRepository().GetThemeCount(); +} + +void ThemeAdapter::GetViewSize(int& width, int& height) const +{ + width = 203; + height = 44; +} + +SharedPtr ThemeAdapter::CreateView() const +{ + return _romBrowserViewFactory->CreateBannerListItemView( + std::make_unique(_settingsController), _vblankTextureLoader); +} + +void ThemeAdapter::BindView(SharedPtr view, int index) const +{ + auto listItemView = static_cast(view.GetPointer()); + listItemView->SetGraphics(_listItemVramToken); + LOG_DEBUG("Binding %d\n", index); + auto queueTask = _settingsController->GetIoTaskQueue()->Enqueue([=, this] (const vu8& cancelRequested) + { + if (cancelRequested) + { + LOG_DEBUG("Task to load %d was canceled\n", index); + return TaskResult::Canceled(); + } + + LOG_DEBUG("Started task to load %d\n", index); + auto& themeInfoManager = _settingsController->GetThemeInfoManager(); + themeInfoManager.LoadThemeInfo(index); + if (cancelRequested) + { + return TaskResult::Canceled(); + } + + auto extraThemeInfo = themeInfoManager.GetExtraThemeInfo(index); + auto listItemView = static_cast(view.GetPointer()); + listItemView->GetViewModel().SetIndex(index); + if (extraThemeInfo) + { + listItemView->SetFirstLineAsync(nullptr, extraThemeInfo->themeInfo->GetName(), false); + listItemView->SetSecondLineAsync(nullptr, extraThemeInfo->themeInfo->GetAuthor()); + listItemView->SetThirdLineAsync(nullptr, extraThemeInfo->themeInfo->GetDescription()); + if (extraThemeInfo->iconData) + { + listItemView->SetIcon(std::make_unique(extraThemeInfo->iconData)); + } + else + { + listItemView->SetIcon(_themeFileIconFactory->CreateThemeFileIcon()); + } + listItemView->UploadIconGraphics(); + static_cast(listItemView->GetViewModel()).SetExtraThemeInfo(extraThemeInfo); + } + + return TaskResult::Completed(); + }); + + listItemView->GetViewModel().SetQueueTask(std::move(queueTask)); +} + +void ThemeAdapter::ReleaseView(SharedPtr view, int index) const +{ + auto listItemView = static_cast(view.GetPointer()); + listItemView->SetIcon(nullptr); + listItemView->GetViewModel().SetIndex(-1); + listItemView->GetViewModel().CancelQueueTask(); +} + +void ThemeAdapter::InitVram(const VramContext& vramContext) +{ + _listItemVramToken = _romBrowserViewFactory->UploadBannerListItemViewGraphics(vramContext); +} diff --git a/arm9/source/settings/views/ThemeAdapter.h b/arm9/source/settings/views/ThemeAdapter.h new file mode 100644 index 0000000..3be2b16 --- /dev/null +++ b/arm9/source/settings/views/ThemeAdapter.h @@ -0,0 +1,33 @@ +#pragma once +#include "gui/views/RecyclerAdapter.h" +#include "romBrowser/views/BannerListItemView.h" + +class IFontRepository; +class IRomBrowserViewFactory; +class ISettingsController; +class IThemeFileIconFactory; +class MaterialColorScheme; +class VBlankTextureLoader; +class VramContext; + +class ThemeAdapter : public RecyclerAdapter +{ +public: + ThemeAdapter(ISettingsController* settingsController, const IRomBrowserViewFactory* romBrowserViewFactory, + const IThemeFileIconFactory* themeFileIconFactory, VBlankTextureLoader* vblankTextureLoader); + + u32 GetItemCount() const override; + void GetViewSize(int& width, int& height) const override; + SharedPtr CreateView() const override; + void BindView(SharedPtr view, int index) const override; + void ReleaseView(SharedPtr view, int index) const override; + + void InitVram(const VramContext& vramContext); + +private: + ISettingsController* _settingsController; + const IRomBrowserViewFactory* _romBrowserViewFactory; + const IThemeFileIconFactory* _themeFileIconFactory; + VBlankTextureLoader* _vblankTextureLoader; + BannerListItemView::VramToken _listItemVramToken; +}; diff --git a/arm9/source/settings/views/ThemeListBottomView.cpp b/arm9/source/settings/views/ThemeListBottomView.cpp new file mode 100644 index 0000000..9c362dd --- /dev/null +++ b/arm9/source/settings/views/ThemeListBottomView.cpp @@ -0,0 +1,67 @@ +#include "common.h" +#include "gui/input/InputProvider.h" +#include "ThemeListBottomView.h" + +ThemeListBottomView::ThemeListBottomView(SharedPtr viewModel, const MaterialColorScheme* materialColorScheme, + const IRomBrowserViewFactory* romBrowserViewFactory, const IThemeFileIconFactory* themeFileIconFactory, + VBlankTextureLoader* vblankTextureLoader) + : _appBarView(SettingsAppBarView::CreateShared(viewModel, romBrowserViewFactory)) + , _recyclerView(RecyclerView::CreateShared(42, 0, 256 - 42, 192, RecyclerView::Mode::VerticalList)) + , _viewModel(std::move(viewModel)) +{ + AddChildTail(_appBarView.GetPointer()); + AddChildTail(_recyclerView.GetPointer()); + _recyclerView->SetPadding(0, 3); + _recyclerView->SetItemSpacing(0, 3); + _themeAdapter = SharedPtr::MakeShared( + _viewModel->GetSettingsController(), romBrowserViewFactory, themeFileIconFactory, vblankTextureLoader); +} + +void ThemeListBottomView::InitVram(const VramContext& vramContext) +{ + _appBarView->InitVram(vramContext); + _themeAdapter->InitVram(vramContext); // first initialize the shared vram for the items + _recyclerView->SetAdapter(_themeAdapter, 0); // set the adapter of the recycler + _recyclerView->InitVram(vramContext); // init the vram for the recycler and its items +} + +void ThemeListBottomView::Update() +{ + ViewContainer::Update(); + _viewModel->SetSelectedItem(_recyclerView->GetSelectedItem()); +} + +SharedPtr ThemeListBottomView::MoveFocus(const SharedPtr& currentFocus, FocusMoveDirection direction, View* source) +{ + if (!currentFocus) + { + return nullptr; + } + if (source == _appBarView.GetPointer()) + { + if (direction == FocusMoveDirection::Right) + { + return _recyclerView->MoveFocus(currentFocus, direction, this); + } + return nullptr; + } + else if (source == _recyclerView.GetPointer()) + { + if (direction == FocusMoveDirection::Left) + { + return _appBarView->MoveFocus(currentFocus, direction, this); + } + return nullptr; + } + return nullptr; +} + +bool ThemeListBottomView::HandleInput(const InputProvider& inputProvider, FocusManager& focusManager) +{ + if (inputProvider.Triggered(InputKey::B)) + { + _viewModel->NavigateUp(); + return true; + } + return View::HandleInput(inputProvider, focusManager); +} diff --git a/arm9/source/settings/views/ThemeListBottomView.h b/arm9/source/settings/views/ThemeListBottomView.h new file mode 100644 index 0000000..6296e61 --- /dev/null +++ b/arm9/source/settings/views/ThemeListBottomView.h @@ -0,0 +1,42 @@ +#pragma once +#include +#include "ThemeAdapter.h" +#include "gui/views/RecyclerView.h" +#include "gui/views/ViewContainer.h" +#include "settings/viewModels/ThemeListViewModel.h" +#include "settings/views/SettingsAppBarView.h" + +class IFontRepository; +class ISettingsController; +class MaterialColorScheme; + +class ThemeListBottomView : public ViewContainer +{ + SHARED_ONLY(ThemeListBottomView) + +public: + ThemeListBottomView(SharedPtr viewModel, const MaterialColorScheme* materialColorScheme, + const IRomBrowserViewFactory* romBrowserViewFactory, const IThemeFileIconFactory* themeFileIconFactory, + VBlankTextureLoader* vblankTextureLoader); + + void InitVram(const VramContext& vramContext) override; + void Update() override; + SharedPtr MoveFocus(const SharedPtr& currentFocus, FocusMoveDirection direction, View* source) override; + bool HandleInput(const InputProvider& inputProvider, FocusManager& focusManager) override; + + Rectangle GetBounds() const override + { + return Rectangle(_position, 256, 192); + } + + void Focus(FocusManager& focusManager) + { + _recyclerView->Focus(focusManager); + } + + SharedPtr _appBarView; +private: + SharedPtr _recyclerView; + SharedPtr _themeAdapter; + SharedPtr _viewModel; +}; diff --git a/arm9/source/settings/views/ThemeListTopView.cpp b/arm9/source/settings/views/ThemeListTopView.cpp new file mode 100644 index 0000000..80e9015 --- /dev/null +++ b/arm9/source/settings/views/ThemeListTopView.cpp @@ -0,0 +1,42 @@ +#include "common.h" +#include +#include +#include +#include "settings/SettingsController.h" +#include "themes/IFontRepository.h" +#include "themes/material/MaterialColorScheme.h" +#include "ThemeListTopView.h" + +ThemeListTopView::ThemeListTopView(SharedPtr viewModel, const MaterialColorScheme* materialColorScheme, + const IFontRepository* fontRepository) + : _viewModel(viewModel) + , _noPreviewLabel(Label2DView::CreateShared(64, 16, 25, fontRepository->GetFont(FontType::Medium11))) +{ + _noPreviewLabel->SetHorizontalAlignment(Alignment::Center); + _noPreviewLabel->SetText("No preview"); + _noPreviewLabel->SetPosition(128 - 32, 96 - 8); + _noPreviewLabel->SetBackgroundColor(materialColorScheme->inverseOnSurface); + _noPreviewLabel->SetForegroundColor(materialColorScheme->onSurfaceVariant); + AddChildTail(_noPreviewLabel.GetPointer()); +} + +void ThemeListTopView::VBlank() +{ + ViewContainer::VBlank(); + REG_DISPCNT_SUB = (REG_DISPCNT_SUB & ~0xF) | 5 | (4 << 8); + REG_BG2CNT_SUB = 0x4084; + REG_BG2HOFS_SUB = 0; + REG_BG2VOFS_SUB = 0; + gfx_setSubBg2Affine(256, 0, 0, 256, 0, 0); + + int selectedItem = _viewModel->GetSelectedItem(); + if (selectedItem != _lastSelectedItem) + { + auto extraThemeInfo = _viewModel->GetSettingsController()->GetThemeInfoManager().GetExtraThemeInfo(selectedItem); + if (extraThemeInfo) + { + dma_ntrCopy32(3, extraThemeInfo->previewImage, GFX_BG_SUB, 256 * 192 * 2); + _lastSelectedItem = selectedItem; + } + } +} diff --git a/arm9/source/settings/views/ThemeListTopView.h b/arm9/source/settings/views/ThemeListTopView.h new file mode 100644 index 0000000..56f0d05 --- /dev/null +++ b/arm9/source/settings/views/ThemeListTopView.h @@ -0,0 +1,29 @@ +#pragma once +#include "core/SharedPtr.h" +#include "gui/views/Label2DView.h" +#include "gui/views/ViewContainer.h" +#include "settings/viewModels/ThemeListViewModel.h" + +class IFontRepository; +class MaterialColorScheme; + +class ThemeListTopView : public ViewContainer +{ + SHARED_ONLY(ThemeListTopView) + +public: + ThemeListTopView(SharedPtr viewModel, const MaterialColorScheme* materialColorScheme, + const IFontRepository* fontRepository); + + void VBlank() override; + + Rectangle GetBounds() const override + { + return Rectangle(0, 0, 256, 192); + } + +private: + SharedPtr _viewModel; + int _lastSelectedItem = -1; + SharedPtr _noPreviewLabel; +}; diff --git a/arm9/source/themes/ThemeRepository.cpp b/arm9/source/themes/ThemeRepository.cpp new file mode 100644 index 0000000..699550f --- /dev/null +++ b/arm9/source/themes/ThemeRepository.cpp @@ -0,0 +1,27 @@ +#include "common.h" +#include "romBrowser/FileType/NullFileTypeProvider.h" +#include "romBrowser/SdFolderFactory.h" +#include "ThemeRepository.h" + +void ThemeRepository::Initialize() +{ + NullFileTypeProvider fileTypeProvider; + _themesFolder = SdFolderFactory(&fileTypeProvider).CreateFromPath("/_pico/themes"); + auto filterSortParams = SdFolderFilterSortParams(SdFolderSortType::Name, SdFolderSortDirection::Ascending, false); + _themeFolders = _themesFolder->FilterAndSort(filterSortParams, _numberOfThemes); +} + +u32 ThemeRepository::GetThemeCount() const +{ + return _numberOfThemes; +} + +std::unique_ptr ThemeRepository::LoadThemeInfo(u32 themeIndex) const +{ + if (themeIndex >= _numberOfThemes) + { + return nullptr; + } + + return _themeInfoFactory.CreateFromThemeFolder(_themeFolders[themeIndex]->GetFileName()); +} diff --git a/arm9/source/themes/ThemeRepository.h b/arm9/source/themes/ThemeRepository.h new file mode 100644 index 0000000..770939c --- /dev/null +++ b/arm9/source/themes/ThemeRepository.h @@ -0,0 +1,20 @@ +#pragma once +#include +#include "romBrowser/SdFolder.h" +#include "themes/ThemeInfo.h" +#include "themes/ThemeInfoFactory.h" + +class ThemeRepository +{ +public: + void Initialize(); + + u32 GetThemeCount() const; + std::unique_ptr LoadThemeInfo(u32 themeIndex) const; + +private: + ThemeInfoFactory _themeInfoFactory; + std::unique_ptr _themesFolder; + u32 _numberOfThemes = 0; + std::unique_ptr _themeFolders; +}; diff --git a/arm9/source/themes/custom/CustomTheme.cpp b/arm9/source/themes/custom/CustomTheme.cpp index 3c9da38..7a0ead0 100644 --- a/arm9/source/themes/custom/CustomTheme.cpp +++ b/arm9/source/themes/custom/CustomTheme.cpp @@ -182,7 +182,8 @@ static CustomThemeInfo parseCustomThemeInfo(const JsonDocument& json) CustomTheme::CustomTheme(const TCHAR* folderName, const Rgb<8, 8, 8>& primaryColor, bool darkMode) : Theme(folderName, primaryColor, darkMode) , _customThemeInfo(sDefaultCustomThemeInfo) - , _romBrowserViewFactory(&_customThemeInfo, &_materialColorScheme, &_fontRepository) { } + , _romBrowserViewFactory(&_customThemeInfo, &_materialColorScheme, &_fontRepository) + , _themeFileIconFactory(&_materialColorScheme, &_fontRepository) { } void CustomTheme::LoadRomBrowserResources(const VramContext& mainVramContext, const VramContext& subVramContext) { diff --git a/arm9/source/themes/custom/CustomTheme.h b/arm9/source/themes/custom/CustomTheme.h index 3d7d0f2..c68bb7d 100644 --- a/arm9/source/themes/custom/CustomTheme.h +++ b/arm9/source/themes/custom/CustomTheme.h @@ -5,6 +5,7 @@ #include "CustomMainBackground.h" #include "CustomSubBackground.h" #include "romBrowser/Theme/custom/CustomRomBrowserViewFactory.h" +#include "romBrowser/Theme/Material/MaterialThemeFileIconFactory.h" #include "CustomTopBackgroundType.h" #include "../DefaultFontRepository.h" #include "CustomThemeInfo.h" @@ -22,7 +23,7 @@ public: const IThemeFileIconFactory* GetThemeFileIconFactory() const override { - return nullptr; + return &_themeFileIconFactory; } const IRomBrowserViewFactory* GetRomBrowserViewFactory() const override @@ -48,4 +49,5 @@ private: CustomRomBrowserViewFactory _romBrowserViewFactory; CustomTopBackgroundType _topBackgroundType; DefaultFontRepository _fontRepository; + MaterialThemeFileIconFactory _themeFileIconFactory; }; diff --git a/docs/Themes.md b/docs/Themes.md index 5dc972c..a93c783 100644 --- a/docs/Themes.md +++ b/docs/Themes.md @@ -84,19 +84,19 @@ Blend colors are used to fake translucency. They should be set to an approximati }, "topBannerTextLine0": { "position": { "x": 70, "y": 126 }, - "width": 176, + "width": 168, "textColor": { "r": 30, "g": 30, "b": 30 }, "blendColor": { "r": 200, "g": 200, "b": 200 } }, "topBannerTextLine1": { "position": { "x": 70, "y": 141 }, - "width": 176, + "width": 168, "textColor": { "r": 30, "g": 30, "b": 30 }, "blendColor": { "r": 200, "g": 200, "b": 200 } }, "topBannerTextLine2": { "position": { "x": 70, "y": 155 }, - "width": 176, + "width": 168, "textColor": { "r": 30, "g": 30, "b": 30 }, "blendColor": { "r": 200, "g": 200, "b": 200 } }, @@ -129,3 +129,9 @@ Blend colors are used to fake translucency. They should be set to an approximati ## Background music All themes support background music by placing DSP-ADPCM encoded `.bcstm` files in a `bgm` folder inside the theme folder. Looping is supported. When multiple `.bcstm` files are provided, the background music will be selected at random each time Pico Launcher is started. + +## Theme selector icon +A theme can have an `icon.bmp` file that is shown in the theme list when selecting a theme. It must be **32×32 pixels, 4 bpp (16 colors), uncompressed `.bmp`** file, with the first palette color treated as transparent. + +## Theme selector preview image +A theme can have a `preview.bin` file that is shown on the top screen in the theme selection screen. It must be a 256x192 pixels 15 bpp bitmap (same format as `topbg.bin` and `bottombg.bin`). When it is not provided, `topbg.bin` is displayed instead. If that does not exist either, nothing is shown on the top screen. diff --git a/libs/libtwl b/libs/libtwl index 55ffbc9..aa3b2a2 160000 --- a/libs/libtwl +++ b/libs/libtwl @@ -1 +1 @@ -Subproject commit 55ffbc9e45b27d44cfee4404caac5fda19d4b8cc +Subproject commit aa3b2a23c10185a10449ffa685bb7933d5d5a784