2021-07-23 08:24:00 +01:00
/*
* options_tab . cpp
*
2024-04-12 10:47:36 +01:00
* Copyright ( c ) 2020 - 2024 , DarkMatterCore < pabloacurielz @ gmail . com > .
2021-07-23 08:24:00 +01:00
*
* This file is part of nxdumptool ( https : //github.com/DarkMatterCore/nxdumptool).
*
* nxdumptool is free software : you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation , either version 3 of the License , or
* ( at your option ) any later version .
*
* nxdumptool is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program . If not , see < https : //www.gnu.org/licenses/>.
*/
2021-08-07 09:42:03 +01:00
# include <sstream>
2024-04-30 22:01:42 +01:00
# include <views/options_tab.hpp>
# include <views/focusable_item.hpp>
# include <core/title.h>
2021-07-23 08:24:00 +01:00
2021-08-07 09:42:03 +01:00
namespace i18n = brls : : i18n ; /* For getStr(). */
using namespace i18n : : literals ; /* For _i18n. */
2021-07-23 08:24:00 +01:00
namespace nxdt : : views
{
2024-04-19 11:08:44 +01:00
OptionsTabUpdateApplicationFrame : : OptionsTabUpdateApplicationFrame ( ) : brls : : StagedAppletFrame ( false )
2021-07-29 08:50:17 +01:00
{
2021-08-07 09:42:03 +01:00
/* Set UI properties. */
this - > setTitle ( " options_tab/update_app/label " _i18n ) ;
this - > setIcon ( BOREALIS_ASSET ( " icon/ " APP_TITLE " .jpg " ) ) ;
2022-07-05 02:04:28 +01:00
2021-08-07 09:42:03 +01:00
/* Add first stage. */
this - > wait_lbl = new brls : : Label ( brls : : LabelStyle : : DIALOG , " options_tab/update_app/frame/please_wait " _i18n , false ) ;
this - > wait_lbl - > setHorizontalAlign ( NVG_ALIGN_CENTER ) ;
this - > addStage ( this - > wait_lbl ) ;
2022-07-05 02:04:28 +01:00
2021-08-07 09:42:03 +01:00
/* Add second stage. */
this - > changelog_list = new brls : : List ( ) ;
this - > changelog_list - > setSpacing ( this - > changelog_list - > getSpacing ( ) / 2 ) ;
this - > changelog_list - > setMarginBottom ( 20 ) ;
this - > addStage ( this - > changelog_list ) ;
2022-07-05 02:04:28 +01:00
2021-08-07 09:42:03 +01:00
/* Add third stage. */
2024-04-15 00:53:43 +01:00
this - > update_progress = new DataTransferProgressDisplay ( ) ;
2021-08-07 09:42:03 +01:00
this - > addStage ( this - > update_progress ) ;
2022-07-05 02:04:28 +01:00
2021-08-07 09:42:03 +01:00
/* Subscribe to the JSON task. */
2024-04-15 00:53:43 +01:00
this - > json_task . RegisterListener ( [ & ] ( const nxdt : : tasks : : DataTransferProgress & progress ) {
2024-04-25 00:49:04 +01:00
/* Return immediately if the JSON task hasn't finished yet or if it was cancelled. */
if ( ! this - > json_task . IsFinished ( ) | | this - > json_task . IsCancelled ( ) ) return ;
2022-07-05 02:04:28 +01:00
2021-08-07 10:44:36 +01:00
std : : string notification = " " ;
2022-07-05 02:04:28 +01:00
2021-08-07 09:42:03 +01:00
/* Retrieve task result. */
2024-04-25 00:49:04 +01:00
nxdt : : tasks : : DownloadDataResult json_task_result = this - > json_task . GetResult ( ) ;
2021-08-07 09:42:03 +01:00
this - > json_buf = json_task_result . first ;
this - > json_buf_size = json_task_result . second ;
2022-07-05 02:04:28 +01:00
2021-08-07 09:42:03 +01:00
/* Parse downloaded JSON object. */
if ( utilsParseGitHubReleaseJsonData ( this - > json_buf , this - > json_buf_size , & ( this - > json_data ) ) )
{
2021-08-07 10:44:36 +01:00
/* Check if the application can be updated. */
if ( utilsIsApplicationUpdatable ( this - > json_data . version , this - > json_data . commit_hash ) )
{
/* Display changelog. */
this - > DisplayChangelog ( ) ;
} else {
/* Set notification string. */
notification = " options_tab/notifications/up_to_date " _i18n ;
}
2021-08-07 09:42:03 +01:00
} else {
2021-08-07 10:44:36 +01:00
/* Log downloaded data. */
2022-07-12 17:34:49 +01:00
LOG_DATA_ERROR ( this - > json_buf , this - > json_buf_size , " Failed to parse GitHub release JSON. Downloaded data: " ) ;
2022-07-05 02:04:28 +01:00
2021-08-07 10:44:36 +01:00
/* Set notification string. */
notification = " options_tab/notifications/github_json_failed " _i18n ;
}
2022-07-05 02:04:28 +01:00
2021-08-07 10:44:36 +01:00
/* Pop view (if needed). */
2024-04-15 00:53:43 +01:00
if ( ! notification . empty ( ) )
2021-08-07 10:44:36 +01:00
{
2021-08-07 09:42:03 +01:00
/* Display notification. */
2021-08-07 10:44:36 +01:00
brls : : Application : : notify ( notification ) ;
2022-07-05 02:04:28 +01:00
2021-08-07 10:44:36 +01:00
/* Pop view. */
2021-08-07 09:42:03 +01:00
this - > onCancel ( ) ;
}
} ) ;
2022-07-05 02:04:28 +01:00
2021-08-07 09:42:03 +01:00
/* Start JSON task. */
2024-04-25 00:49:04 +01:00
this - > json_task . Execute ( GITHUB_API_RELEASE_URL , true ) ;
2021-08-07 09:42:03 +01:00
}
2022-07-05 02:04:28 +01:00
2024-04-19 11:08:44 +01:00
OptionsTabUpdateApplicationFrame : : ~ OptionsTabUpdateApplicationFrame ( )
2021-08-07 09:42:03 +01:00
{
/* Free parsed JSON data. */
utilsFreeGitHubReleaseJsonData ( & ( this - > json_data ) ) ;
2022-07-05 02:04:28 +01:00
2021-08-07 09:42:03 +01:00
/* Free JSON buffer. */
if ( this - > json_buf ) free ( this - > json_buf ) ;
}
2022-07-05 02:04:28 +01:00
2021-08-07 09:42:03 +01:00
void OptionsTabUpdateApplicationFrame : : layout ( NVGcontext * vg , brls : : Style * style , brls : : FontStash * stash )
{
brls : : StagedAppletFrame : : layout ( vg , style , stash ) ;
2022-07-05 02:04:28 +01:00
2021-08-07 09:42:03 +01:00
if ( this - > getCurrentStage ( ) = = 0 )
{
/* Center wait label. */
this - > wait_lbl - > setBoundaries ( this - > x + ( this - > width / 2 ) , this - > y , this - > width , this - > height ) ;
this - > wait_lbl - > invalidate ( ) ;
}
}
2022-07-05 02:04:28 +01:00
2021-08-07 09:42:03 +01:00
bool OptionsTabUpdateApplicationFrame : : onCancel ( void )
{
/* Cancel NRO task. */
2024-04-25 00:49:04 +01:00
this - > nro_task . Cancel ( ) ;
2022-07-05 02:04:28 +01:00
2021-08-07 09:42:03 +01:00
/* Cancel JSON task. */
2024-04-25 00:49:04 +01:00
this - > json_task . Cancel ( ) ;
2022-07-05 02:04:28 +01:00
Add DataTransferTaskFrame and GameCardImageDumpTaskFrame classes
DataTransferTaskFrame is a template class that's derived from brls::AppletFrame, which automatically starts a background task using an internal object belonging to a class derived from DataTransferTask. A DataTransferProgressDisplay view is used to show progress updates. If the background task hits an error, the class takes care of switching to an ErrorFrame view with the corresponding error message.
GameCardImageDumpTaskFrame is a derived class of DataTransferTaskFrame that uses a GameCardImageDumpTask object as its background task. In layman's terms, this provides a way to fully dump gamecard images using the new UI.
DataTransferTaskFrame depends on the newly added is_base_template helper from goneskiing to check if the class for the provided task is derived from DataTransferTask.
Other changes include:
* DataTransferProgressDisplay: rename setProgress() method to SetProgress().
* DataTransferTask: move post-task-execution code into its own new private method, PostExecutionCallback(), and update both OnCancelled() and OnPostExecute() callbacks to invoke it.
* DataTransferTask: update OnProgressUpdate() to allow sending a last progress update to all event subscribers even if the background task was cancelled.
* DataTransferTask: update OnProgressUpdate() to allow sending a first progress update if no data has been transferred but the total transfer size is already known.
* DataTransferTask: update OnProgressUpdate() to avoid calculating the ETA if the speed isn't greater than 0.
* DumpOptionsFrame: remove UpdateOutputStorages() method.
* DumpOptionsFrame: update class to use the cached output storage value from our RootView.
* DumpOptionsFrame: add GenerateOutputStoragesVector() method, which is used to avoid setting dummy options while initializing the output storages SelectListItem.
* DumpOptionsFrame: update UMS task callback to add the rest of the leftover logic from UpdateOutputStorages().
* DumpOptionsFrame: update RegisterButtonListener() to use a wrapper callback around the user-provided callback to check if the USB host was selected as the output storage but no USB host connection is available.
* ErrorFrame: use const references for all input string arguments.
* FileWriter: fix a localization stirng name typo.
* FileWriter: fix an exception that was previously being thrown by a fmt::format() call because of a wrong format specifier.
* FocusableItem: add a static assert to check if the provided ViewType is derived from brls::View.
* gamecard: redefine global gamecard status variable as an atomic unsigned 8-bit integer, which fixes a "status-hopping" issue previously experienced by repeating tasks running under other threads that periodically call gamecardGetStatus().
* GameCardImageDumpOptionsFrame: define GAMECARD_TOGGLE_ITEM macro, which is used to initialize all ToggleListItem elements from the view.
* GameCardImageDumpOptionsFrame: update button callback to push a GameCardImageDumpTaskFrame view onto the borealis stack.
* GameCardImageDumpTask: move class into its own header and module files.
* GameCardImageDumpTask: update class to also take in the checksum lookup method (not yet implemented).
* GameCardImageDumpTask: update class to send its first progress update as soon as the gamecard image size is known.
* GameCardImageDumpTask: update class to avoid returning a string if the task was cancelled -- DataTransferTaskFrame offers logic to display the appropiate cancel message on its own.
* GameCardTab: update PopulateList() method to display the new version information available in TitleGameCardApplicationMetadataEntry elements as part of the generated TitlesTabItem objects.
* i18n: add new localization strings.
* OptionsTab: update background task callback logic to handle task cancellation, reflecting the changes made to DataTransferTask.
* OptionsTab: reflect changes made to DataTransferProgressDisplay.
* RootView: cache the currently selected output storage value at all times, which is propagated throughout different parts of the UI. Getter and setter helpers have been added to operate with this value.
* RootView: add GetUsbHostSpeed() helper, which can be used by child views to retrieve the USB host speed on demand.
* RootView: update UMS task callback to automatically reset the cached output storage value back to the SD card if a UMS device was previously selected.
* title: define TitleGameCardApplicationMetadataEntry struct, which also holds version-specific information retrieved from the gamecard titles.
* title: refactor titleGetGameCardApplicationMetadataEntries() to return a dynamically allocated array of TitleGameCardApplicationMetadataEntry elements.
* usb: redefine global endpoint max packet size variable as an atomic unsigned 16-bit integer, which fixes a "status-hopping" issue previously experienced by repeating tasks running under other threads that periodically call usbIsReady().
* UsbHostTask: add GetUsbHostSpeed() method.
2024-04-29 14:26:12 +01:00
/* Pop view. This will invoke this class' destructor. */
2021-08-11 08:17:57 +01:00
brls : : Application : : popView ( brls : : ViewAnimation : : SLIDE_RIGHT ) ;
2022-07-05 02:04:28 +01:00
2021-07-29 08:50:17 +01:00
return true ;
}
2022-07-05 02:04:28 +01:00
2021-08-07 09:42:03 +01:00
void OptionsTabUpdateApplicationFrame : : DisplayChangelog ( void )
{
2022-07-31 00:47:40 +01:00
int line = 0 ;
2024-04-25 00:49:04 +01:00
std : : string item { } ;
std : : stringstream ss ( this - > json_data . changelog ) ;
2022-07-05 02:04:28 +01:00
2021-08-07 09:42:03 +01:00
/* Display version string at the top. */
2024-04-12 22:08:54 +01:00
FocusableLabel * version_lbl = new FocusableLabel ( false , false , brls : : LabelStyle : : CRASH , std : : string ( this - > json_data . version ) , true ) ;
2021-08-07 09:42:03 +01:00
version_lbl - > setHorizontalAlign ( NVG_ALIGN_CENTER ) ;
this - > changelog_list - > addView ( version_lbl ) ;
2022-07-05 02:04:28 +01:00
2021-08-07 09:42:03 +01:00
/* Display release date and commit hash. */
brls : : Label * release_details_lbl = new brls : : Label ( brls : : LabelStyle : : DESCRIPTION , i18n : : getStr ( " options_tab/update_app/frame/release_details " _i18n , \
this - > json_data . commit_hash , RootView : : GetFormattedDateString ( this - > json_data . date ) ) , true ) ;
release_details_lbl - > setHorizontalAlign ( NVG_ALIGN_CENTER ) ;
this - > changelog_list - > addView ( release_details_lbl ) ;
2022-07-05 02:04:28 +01:00
2021-08-07 09:42:03 +01:00
/* Add changelog header. */
this - > changelog_list - > addView ( new brls : : Header ( " options_tab/update_app/frame/changelog_header " _i18n ) ) ;
2022-07-05 02:04:28 +01:00
2021-08-07 09:42:03 +01:00
/* Split changelog string and fill list. */
while ( std : : getline ( ss , item ) )
{
/* Don't proceed if this is an empty line. */
/* Make sure to remove any possible carriage returns. */
size_t item_len = item . length ( ) ;
if ( ! item_len ) continue ;
2022-07-05 02:04:28 +01:00
2021-08-07 09:42:03 +01:00
if ( item . back ( ) = = ' \r ' )
{
if ( item_len > 1 )
{
item . pop_back ( ) ;
} else {
continue ;
}
}
2022-07-05 02:04:28 +01:00
2021-08-07 09:42:03 +01:00
/* Add line to the changelog view. */
2022-07-31 00:47:40 +01:00
if ( ! ( line % 2 ) )
{
2024-04-12 12:40:50 +01:00
this - > changelog_list - > addView ( new FocusableLabel ( false , false , brls : : LabelStyle : : SMALL , item , true ) ) ;
2022-07-31 00:47:40 +01:00
} else {
this - > changelog_list - > addView ( new brls : : Label ( brls : : LabelStyle : : SMALL , item , true ) ) ;
}
line + + ;
2021-08-07 09:42:03 +01:00
}
2022-07-05 02:04:28 +01:00
2021-08-07 09:42:03 +01:00
/* Register update action. */
2021-08-11 08:17:57 +01:00
this - > registerAction ( " options_tab/update_app/frame/update_action " _i18n , brls : : Key : : PLUS , [ this ] ( void ) {
2021-08-07 09:42:03 +01:00
/* Display update progress. */
this - > DisplayUpdateProgress ( ) ;
2022-07-05 02:04:28 +01:00
2021-08-07 09:42:03 +01:00
return true ;
} ) ;
2022-07-05 02:04:28 +01:00
2021-08-07 09:42:03 +01:00
/* Go to the next stage. */
this - > nextStage ( ) ;
}
2022-07-05 02:04:28 +01:00
2021-08-07 09:42:03 +01:00
void OptionsTabUpdateApplicationFrame : : DisplayUpdateProgress ( void )
{
2022-07-30 15:25:41 +01:00
/* Unregister update action. */
this - > unregisterAction ( brls : : Key : : PLUS ) ;
2022-07-05 02:04:28 +01:00
2022-07-30 15:25:41 +01:00
/* Update cancel action label. */
2024-04-25 00:49:04 +01:00
this - > updateActionHint ( brls : : Key : : B , " generic/cancel " _i18n ) ;
2022-07-05 02:04:28 +01:00
2021-08-07 09:42:03 +01:00
/* Subscribe to the NRO task. */
2024-04-15 00:53:43 +01:00
this - > nro_task . RegisterListener ( [ & ] ( const nxdt : : tasks : : DataTransferProgress & progress ) {
2021-08-07 09:42:03 +01:00
/* Update progress. */
Add DataTransferTaskFrame and GameCardImageDumpTaskFrame classes
DataTransferTaskFrame is a template class that's derived from brls::AppletFrame, which automatically starts a background task using an internal object belonging to a class derived from DataTransferTask. A DataTransferProgressDisplay view is used to show progress updates. If the background task hits an error, the class takes care of switching to an ErrorFrame view with the corresponding error message.
GameCardImageDumpTaskFrame is a derived class of DataTransferTaskFrame that uses a GameCardImageDumpTask object as its background task. In layman's terms, this provides a way to fully dump gamecard images using the new UI.
DataTransferTaskFrame depends on the newly added is_base_template helper from goneskiing to check if the class for the provided task is derived from DataTransferTask.
Other changes include:
* DataTransferProgressDisplay: rename setProgress() method to SetProgress().
* DataTransferTask: move post-task-execution code into its own new private method, PostExecutionCallback(), and update both OnCancelled() and OnPostExecute() callbacks to invoke it.
* DataTransferTask: update OnProgressUpdate() to allow sending a last progress update to all event subscribers even if the background task was cancelled.
* DataTransferTask: update OnProgressUpdate() to allow sending a first progress update if no data has been transferred but the total transfer size is already known.
* DataTransferTask: update OnProgressUpdate() to avoid calculating the ETA if the speed isn't greater than 0.
* DumpOptionsFrame: remove UpdateOutputStorages() method.
* DumpOptionsFrame: update class to use the cached output storage value from our RootView.
* DumpOptionsFrame: add GenerateOutputStoragesVector() method, which is used to avoid setting dummy options while initializing the output storages SelectListItem.
* DumpOptionsFrame: update UMS task callback to add the rest of the leftover logic from UpdateOutputStorages().
* DumpOptionsFrame: update RegisterButtonListener() to use a wrapper callback around the user-provided callback to check if the USB host was selected as the output storage but no USB host connection is available.
* ErrorFrame: use const references for all input string arguments.
* FileWriter: fix a localization stirng name typo.
* FileWriter: fix an exception that was previously being thrown by a fmt::format() call because of a wrong format specifier.
* FocusableItem: add a static assert to check if the provided ViewType is derived from brls::View.
* gamecard: redefine global gamecard status variable as an atomic unsigned 8-bit integer, which fixes a "status-hopping" issue previously experienced by repeating tasks running under other threads that periodically call gamecardGetStatus().
* GameCardImageDumpOptionsFrame: define GAMECARD_TOGGLE_ITEM macro, which is used to initialize all ToggleListItem elements from the view.
* GameCardImageDumpOptionsFrame: update button callback to push a GameCardImageDumpTaskFrame view onto the borealis stack.
* GameCardImageDumpTask: move class into its own header and module files.
* GameCardImageDumpTask: update class to also take in the checksum lookup method (not yet implemented).
* GameCardImageDumpTask: update class to send its first progress update as soon as the gamecard image size is known.
* GameCardImageDumpTask: update class to avoid returning a string if the task was cancelled -- DataTransferTaskFrame offers logic to display the appropiate cancel message on its own.
* GameCardTab: update PopulateList() method to display the new version information available in TitleGameCardApplicationMetadataEntry elements as part of the generated TitlesTabItem objects.
* i18n: add new localization strings.
* OptionsTab: update background task callback logic to handle task cancellation, reflecting the changes made to DataTransferTask.
* OptionsTab: reflect changes made to DataTransferProgressDisplay.
* RootView: cache the currently selected output storage value at all times, which is propagated throughout different parts of the UI. Getter and setter helpers have been added to operate with this value.
* RootView: add GetUsbHostSpeed() helper, which can be used by child views to retrieve the USB host speed on demand.
* RootView: update UMS task callback to automatically reset the cached output storage value back to the SD card if a UMS device was previously selected.
* title: define TitleGameCardApplicationMetadataEntry struct, which also holds version-specific information retrieved from the gamecard titles.
* title: refactor titleGetGameCardApplicationMetadataEntries() to return a dynamically allocated array of TitleGameCardApplicationMetadataEntry elements.
* usb: redefine global endpoint max packet size variable as an atomic unsigned 16-bit integer, which fixes a "status-hopping" issue previously experienced by repeating tasks running under other threads that periodically call usbIsReady().
* UsbHostTask: add GetUsbHostSpeed() method.
2024-04-29 14:26:12 +01:00
this - > update_progress - > SetProgress ( progress ) ;
2022-07-05 02:04:28 +01:00
2021-08-07 09:42:03 +01:00
/* Check if the download task has finished. */
2024-04-15 00:53:43 +01:00
if ( this - > nro_task . IsFinished ( ) )
2021-08-07 09:42:03 +01:00
{
Add DataTransferTaskFrame and GameCardImageDumpTaskFrame classes
DataTransferTaskFrame is a template class that's derived from brls::AppletFrame, which automatically starts a background task using an internal object belonging to a class derived from DataTransferTask. A DataTransferProgressDisplay view is used to show progress updates. If the background task hits an error, the class takes care of switching to an ErrorFrame view with the corresponding error message.
GameCardImageDumpTaskFrame is a derived class of DataTransferTaskFrame that uses a GameCardImageDumpTask object as its background task. In layman's terms, this provides a way to fully dump gamecard images using the new UI.
DataTransferTaskFrame depends on the newly added is_base_template helper from goneskiing to check if the class for the provided task is derived from DataTransferTask.
Other changes include:
* DataTransferProgressDisplay: rename setProgress() method to SetProgress().
* DataTransferTask: move post-task-execution code into its own new private method, PostExecutionCallback(), and update both OnCancelled() and OnPostExecute() callbacks to invoke it.
* DataTransferTask: update OnProgressUpdate() to allow sending a last progress update to all event subscribers even if the background task was cancelled.
* DataTransferTask: update OnProgressUpdate() to allow sending a first progress update if no data has been transferred but the total transfer size is already known.
* DataTransferTask: update OnProgressUpdate() to avoid calculating the ETA if the speed isn't greater than 0.
* DumpOptionsFrame: remove UpdateOutputStorages() method.
* DumpOptionsFrame: update class to use the cached output storage value from our RootView.
* DumpOptionsFrame: add GenerateOutputStoragesVector() method, which is used to avoid setting dummy options while initializing the output storages SelectListItem.
* DumpOptionsFrame: update UMS task callback to add the rest of the leftover logic from UpdateOutputStorages().
* DumpOptionsFrame: update RegisterButtonListener() to use a wrapper callback around the user-provided callback to check if the USB host was selected as the output storage but no USB host connection is available.
* ErrorFrame: use const references for all input string arguments.
* FileWriter: fix a localization stirng name typo.
* FileWriter: fix an exception that was previously being thrown by a fmt::format() call because of a wrong format specifier.
* FocusableItem: add a static assert to check if the provided ViewType is derived from brls::View.
* gamecard: redefine global gamecard status variable as an atomic unsigned 8-bit integer, which fixes a "status-hopping" issue previously experienced by repeating tasks running under other threads that periodically call gamecardGetStatus().
* GameCardImageDumpOptionsFrame: define GAMECARD_TOGGLE_ITEM macro, which is used to initialize all ToggleListItem elements from the view.
* GameCardImageDumpOptionsFrame: update button callback to push a GameCardImageDumpTaskFrame view onto the borealis stack.
* GameCardImageDumpTask: move class into its own header and module files.
* GameCardImageDumpTask: update class to also take in the checksum lookup method (not yet implemented).
* GameCardImageDumpTask: update class to send its first progress update as soon as the gamecard image size is known.
* GameCardImageDumpTask: update class to avoid returning a string if the task was cancelled -- DataTransferTaskFrame offers logic to display the appropiate cancel message on its own.
* GameCardTab: update PopulateList() method to display the new version information available in TitleGameCardApplicationMetadataEntry elements as part of the generated TitlesTabItem objects.
* i18n: add new localization strings.
* OptionsTab: update background task callback logic to handle task cancellation, reflecting the changes made to DataTransferTask.
* OptionsTab: reflect changes made to DataTransferProgressDisplay.
* RootView: cache the currently selected output storage value at all times, which is propagated throughout different parts of the UI. Getter and setter helpers have been added to operate with this value.
* RootView: add GetUsbHostSpeed() helper, which can be used by child views to retrieve the USB host speed on demand.
* RootView: update UMS task callback to automatically reset the cached output storage value back to the SD card if a UMS device was previously selected.
* title: define TitleGameCardApplicationMetadataEntry struct, which also holds version-specific information retrieved from the gamecard titles.
* title: refactor titleGetGameCardApplicationMetadataEntries() to return a dynamically allocated array of TitleGameCardApplicationMetadataEntry elements.
* usb: redefine global endpoint max packet size variable as an atomic unsigned 16-bit integer, which fixes a "status-hopping" issue previously experienced by repeating tasks running under other threads that periodically call usbIsReady().
* UsbHostTask: add GetUsbHostSpeed() method.
2024-04-29 14:26:12 +01:00
/* Check if the download task was cancelled. */
if ( ! this - > nro_task . IsCancelled ( ) )
{
/* Get NRO task result and immediately set application updated state if the task succeeded. */
bool ret = this - > nro_task . GetResult ( ) ;
if ( ret ) utilsSetApplicationUpdatedState ( ) ;
2022-07-05 02:04:28 +01:00
Add DataTransferTaskFrame and GameCardImageDumpTaskFrame classes
DataTransferTaskFrame is a template class that's derived from brls::AppletFrame, which automatically starts a background task using an internal object belonging to a class derived from DataTransferTask. A DataTransferProgressDisplay view is used to show progress updates. If the background task hits an error, the class takes care of switching to an ErrorFrame view with the corresponding error message.
GameCardImageDumpTaskFrame is a derived class of DataTransferTaskFrame that uses a GameCardImageDumpTask object as its background task. In layman's terms, this provides a way to fully dump gamecard images using the new UI.
DataTransferTaskFrame depends on the newly added is_base_template helper from goneskiing to check if the class for the provided task is derived from DataTransferTask.
Other changes include:
* DataTransferProgressDisplay: rename setProgress() method to SetProgress().
* DataTransferTask: move post-task-execution code into its own new private method, PostExecutionCallback(), and update both OnCancelled() and OnPostExecute() callbacks to invoke it.
* DataTransferTask: update OnProgressUpdate() to allow sending a last progress update to all event subscribers even if the background task was cancelled.
* DataTransferTask: update OnProgressUpdate() to allow sending a first progress update if no data has been transferred but the total transfer size is already known.
* DataTransferTask: update OnProgressUpdate() to avoid calculating the ETA if the speed isn't greater than 0.
* DumpOptionsFrame: remove UpdateOutputStorages() method.
* DumpOptionsFrame: update class to use the cached output storage value from our RootView.
* DumpOptionsFrame: add GenerateOutputStoragesVector() method, which is used to avoid setting dummy options while initializing the output storages SelectListItem.
* DumpOptionsFrame: update UMS task callback to add the rest of the leftover logic from UpdateOutputStorages().
* DumpOptionsFrame: update RegisterButtonListener() to use a wrapper callback around the user-provided callback to check if the USB host was selected as the output storage but no USB host connection is available.
* ErrorFrame: use const references for all input string arguments.
* FileWriter: fix a localization stirng name typo.
* FileWriter: fix an exception that was previously being thrown by a fmt::format() call because of a wrong format specifier.
* FocusableItem: add a static assert to check if the provided ViewType is derived from brls::View.
* gamecard: redefine global gamecard status variable as an atomic unsigned 8-bit integer, which fixes a "status-hopping" issue previously experienced by repeating tasks running under other threads that periodically call gamecardGetStatus().
* GameCardImageDumpOptionsFrame: define GAMECARD_TOGGLE_ITEM macro, which is used to initialize all ToggleListItem elements from the view.
* GameCardImageDumpOptionsFrame: update button callback to push a GameCardImageDumpTaskFrame view onto the borealis stack.
* GameCardImageDumpTask: move class into its own header and module files.
* GameCardImageDumpTask: update class to also take in the checksum lookup method (not yet implemented).
* GameCardImageDumpTask: update class to send its first progress update as soon as the gamecard image size is known.
* GameCardImageDumpTask: update class to avoid returning a string if the task was cancelled -- DataTransferTaskFrame offers logic to display the appropiate cancel message on its own.
* GameCardTab: update PopulateList() method to display the new version information available in TitleGameCardApplicationMetadataEntry elements as part of the generated TitlesTabItem objects.
* i18n: add new localization strings.
* OptionsTab: update background task callback logic to handle task cancellation, reflecting the changes made to DataTransferTask.
* OptionsTab: reflect changes made to DataTransferProgressDisplay.
* RootView: cache the currently selected output storage value at all times, which is propagated throughout different parts of the UI. Getter and setter helpers have been added to operate with this value.
* RootView: add GetUsbHostSpeed() helper, which can be used by child views to retrieve the USB host speed on demand.
* RootView: update UMS task callback to automatically reset the cached output storage value back to the SD card if a UMS device was previously selected.
* title: define TitleGameCardApplicationMetadataEntry struct, which also holds version-specific information retrieved from the gamecard titles.
* title: refactor titleGetGameCardApplicationMetadataEntries() to return a dynamically allocated array of TitleGameCardApplicationMetadataEntry elements.
* usb: redefine global endpoint max packet size variable as an atomic unsigned 16-bit integer, which fixes a "status-hopping" issue previously experienced by repeating tasks running under other threads that periodically call usbIsReady().
* UsbHostTask: add GetUsbHostSpeed() method.
2024-04-29 14:26:12 +01:00
/* Display notification. */
brls : : Application : : notify ( ret ? " options_tab/notifications/app_updated " _i18n : " options_tab/notifications/update_failed " _i18n ) ;
}
2022-07-05 02:04:28 +01:00
Add DataTransferTaskFrame and GameCardImageDumpTaskFrame classes
DataTransferTaskFrame is a template class that's derived from brls::AppletFrame, which automatically starts a background task using an internal object belonging to a class derived from DataTransferTask. A DataTransferProgressDisplay view is used to show progress updates. If the background task hits an error, the class takes care of switching to an ErrorFrame view with the corresponding error message.
GameCardImageDumpTaskFrame is a derived class of DataTransferTaskFrame that uses a GameCardImageDumpTask object as its background task. In layman's terms, this provides a way to fully dump gamecard images using the new UI.
DataTransferTaskFrame depends on the newly added is_base_template helper from goneskiing to check if the class for the provided task is derived from DataTransferTask.
Other changes include:
* DataTransferProgressDisplay: rename setProgress() method to SetProgress().
* DataTransferTask: move post-task-execution code into its own new private method, PostExecutionCallback(), and update both OnCancelled() and OnPostExecute() callbacks to invoke it.
* DataTransferTask: update OnProgressUpdate() to allow sending a last progress update to all event subscribers even if the background task was cancelled.
* DataTransferTask: update OnProgressUpdate() to allow sending a first progress update if no data has been transferred but the total transfer size is already known.
* DataTransferTask: update OnProgressUpdate() to avoid calculating the ETA if the speed isn't greater than 0.
* DumpOptionsFrame: remove UpdateOutputStorages() method.
* DumpOptionsFrame: update class to use the cached output storage value from our RootView.
* DumpOptionsFrame: add GenerateOutputStoragesVector() method, which is used to avoid setting dummy options while initializing the output storages SelectListItem.
* DumpOptionsFrame: update UMS task callback to add the rest of the leftover logic from UpdateOutputStorages().
* DumpOptionsFrame: update RegisterButtonListener() to use a wrapper callback around the user-provided callback to check if the USB host was selected as the output storage but no USB host connection is available.
* ErrorFrame: use const references for all input string arguments.
* FileWriter: fix a localization stirng name typo.
* FileWriter: fix an exception that was previously being thrown by a fmt::format() call because of a wrong format specifier.
* FocusableItem: add a static assert to check if the provided ViewType is derived from brls::View.
* gamecard: redefine global gamecard status variable as an atomic unsigned 8-bit integer, which fixes a "status-hopping" issue previously experienced by repeating tasks running under other threads that periodically call gamecardGetStatus().
* GameCardImageDumpOptionsFrame: define GAMECARD_TOGGLE_ITEM macro, which is used to initialize all ToggleListItem elements from the view.
* GameCardImageDumpOptionsFrame: update button callback to push a GameCardImageDumpTaskFrame view onto the borealis stack.
* GameCardImageDumpTask: move class into its own header and module files.
* GameCardImageDumpTask: update class to also take in the checksum lookup method (not yet implemented).
* GameCardImageDumpTask: update class to send its first progress update as soon as the gamecard image size is known.
* GameCardImageDumpTask: update class to avoid returning a string if the task was cancelled -- DataTransferTaskFrame offers logic to display the appropiate cancel message on its own.
* GameCardTab: update PopulateList() method to display the new version information available in TitleGameCardApplicationMetadataEntry elements as part of the generated TitlesTabItem objects.
* i18n: add new localization strings.
* OptionsTab: update background task callback logic to handle task cancellation, reflecting the changes made to DataTransferTask.
* OptionsTab: reflect changes made to DataTransferProgressDisplay.
* RootView: cache the currently selected output storage value at all times, which is propagated throughout different parts of the UI. Getter and setter helpers have been added to operate with this value.
* RootView: add GetUsbHostSpeed() helper, which can be used by child views to retrieve the USB host speed on demand.
* RootView: update UMS task callback to automatically reset the cached output storage value back to the SD card if a UMS device was previously selected.
* title: define TitleGameCardApplicationMetadataEntry struct, which also holds version-specific information retrieved from the gamecard titles.
* title: refactor titleGetGameCardApplicationMetadataEntries() to return a dynamically allocated array of TitleGameCardApplicationMetadataEntry elements.
* usb: redefine global endpoint max packet size variable as an atomic unsigned 16-bit integer, which fixes a "status-hopping" issue previously experienced by repeating tasks running under other threads that periodically call usbIsReady().
* UsbHostTask: add GetUsbHostSpeed() method.
2024-04-29 14:26:12 +01:00
/* Pop view. */
2021-08-07 09:42:03 +01:00
this - > onCancel ( ) ;
}
} ) ;
2022-07-05 02:04:28 +01:00
2021-08-07 09:42:03 +01:00
/* Start NRO task. */
2024-04-25 00:49:04 +01:00
this - > nro_task . Execute ( NRO_TMP_PATH , std : : string ( this - > json_data . download_url ) , true ) ;
2022-07-05 02:04:28 +01:00
2021-08-07 09:42:03 +01:00
/* Go to the next stage. */
this - > nextStage ( ) ;
}
2022-07-05 02:04:28 +01:00
2021-08-11 08:17:57 +01:00
OptionsTab : : OptionsTab ( RootView * root_view ) : brls : : List ( ) , root_view ( root_view )
2021-07-23 08:24:00 +01:00
{
/* Set custom spacing. */
this - > setSpacing ( this - > getSpacing ( ) / 2 ) ;
this - > setMarginBottom ( 20 ) ;
2022-07-05 02:04:28 +01:00
2021-07-25 06:37:13 +01:00
/* Information about actual dump options. */
brls : : Label * dump_options_info = new brls : : Label ( brls : : LabelStyle : : DESCRIPTION , " options_tab/dump_options_info " _i18n , true ) ;
dump_options_info - > setHorizontalAlign ( NVG_ALIGN_CENTER ) ;
this - > addView ( dump_options_info ) ;
2022-07-05 02:04:28 +01:00
2021-07-23 08:24:00 +01:00
/* Overclock. */
brls : : ToggleListItem * overclock = new brls : : ToggleListItem ( " options_tab/overclock/label " _i18n , configGetBoolean ( " overclock " ) , \
2022-09-12 19:19:10 +01:00
" options_tab/overclock/description " _i18n , " generic/value_enabled " _i18n , \
" generic/value_disabled " _i18n ) ;
2022-07-05 02:04:28 +01:00
2021-07-23 08:24:00 +01:00
overclock - > getClickEvent ( ) - > subscribe ( [ ] ( brls : : View * view ) {
2021-07-25 06:37:13 +01:00
/* Get current value. */
2022-07-12 01:27:03 +01:00
brls : : ToggleListItem * item = static_cast < brls : : ToggleListItem * > ( view ) ;
2021-07-23 08:24:00 +01:00
bool value = item - > getToggleState ( ) ;
2022-07-05 02:04:28 +01:00
2021-07-25 06:37:13 +01:00
/* Update configuration. */
2021-07-23 08:24:00 +01:00
configSetBoolean ( " overclock " , value ) ;
2022-07-05 02:04:28 +01:00
2022-07-12 02:31:39 +01:00
LOG_MSG_DEBUG ( " Overclock setting changed by user. " ) ;
2021-07-23 08:24:00 +01:00
} ) ;
2022-07-05 02:04:28 +01:00
2021-07-23 08:24:00 +01:00
this - > addView ( overclock ) ;
2022-07-05 02:04:28 +01:00
2021-07-23 08:24:00 +01:00
/* Naming convention. */
brls : : SelectListItem * naming_convention = new brls : : SelectListItem ( " options_tab/naming_convention/label " _i18n , {
" options_tab/naming_convention/value_00 " _i18n ,
" options_tab/naming_convention/value_01 " _i18n
} , static_cast < unsigned > ( configGetInteger ( " naming_convention " ) ) ,
" options_tab/naming_convention/description " _i18n ) ;
2022-07-05 02:04:28 +01:00
2021-08-11 08:17:57 +01:00
naming_convention - > getValueSelectedEvent ( ) - > subscribe ( [ ] ( int selected ) {
2021-07-25 06:37:13 +01:00
/* Make sure the current value isn't out of bounds. */
2021-07-23 08:24:00 +01:00
if ( selected < 0 | | selected > static_cast < int > ( TitleNamingConvention_Count ) ) return ;
2022-07-05 02:04:28 +01:00
2021-07-25 06:37:13 +01:00
/* Update configuration. */
2021-07-23 08:24:00 +01:00
configSetInteger ( " naming_convention " , selected ) ;
2022-07-05 02:04:28 +01:00
2022-07-12 02:31:39 +01:00
LOG_MSG_DEBUG ( " Naming convention setting changed by user. " ) ;
2021-07-23 08:24:00 +01:00
} ) ;
2022-07-05 02:04:28 +01:00
2021-07-23 08:24:00 +01:00
this - > addView ( naming_convention ) ;
2022-07-05 02:04:28 +01:00
2024-04-19 11:08:44 +01:00
/* Unmount USB Mass Storage devices. */
2024-04-18 20:58:47 +01:00
/* We will replace its default click event with a new one that will: */
/* 1. Check if any UMS devices are available before displaying the dropdown and display a notification if there are none. */
/* 2. Generate the string vector required by the dropdown. */
/* 3. Initialize the dropdown and pass a custom callback that will take care of unmounting the selected device. */
2024-04-19 11:08:44 +01:00
brls : : SelectListItem * unmount_ums_device = new brls : : SelectListItem ( " options_tab/unmount_ums_device/label " _i18n , { " dummy " } , 0 ,
i18n : : getStr ( " options_tab/unmount_ums_device/description " _i18n , APP_TITLE ) , false ) ;
2024-04-18 20:58:47 +01:00
2024-04-19 11:08:44 +01:00
unmount_ums_device - > getClickEvent ( ) - > unsubscribeAll ( ) ;
2024-04-18 20:58:47 +01:00
2024-04-19 11:08:44 +01:00
unmount_ums_device - > getClickEvent ( ) - > subscribe ( [ this ] ( brls : : View * view ) {
2024-04-18 20:58:47 +01:00
if ( this - > ums_devices . empty ( ) )
{
/* Display a notification if we haven't mounted any UMS devices at all. */
this - > DisplayNotification ( " options_tab/notifications/no_ums_devices " _i18n ) ;
return ;
}
/* Generate values vector for the dropdown. */
std : : vector < std : : string > values { } ;
for ( nxdt : : tasks : : UmsDeviceVectorEntry ums_device_entry : this - > ums_devices ) values . push_back ( ums_device_entry . second ) ;
/* Display dropdown. */
2024-04-19 11:08:44 +01:00
brls : : SelectListItem * unmount_ums_device = static_cast < brls : : SelectListItem * > ( view ) ;
brls : : Dropdown : : open ( unmount_ums_device - > getLabel ( ) , values , [ this ] ( int idx ) {
2024-04-18 20:58:47 +01:00
/* Make sure the current value isn't out of bounds. */
if ( idx < 0 | | idx > = static_cast < int > ( this - > ums_devices . size ( ) ) ) return ;
/* Unmount UMS device. */
if ( umsUnmountDevice ( this - > ums_devices . at ( idx ) . first ) )
{
this - > DisplayNotification ( " options_tab/notifications/ums_device_unmount_success " _i18n ) ;
} else {
2024-04-25 00:49:04 +01:00
this - > DisplayNotification ( " options_tab/notifications/ums_device_unmount_failed " _i18n ) ;
2024-04-18 20:58:47 +01:00
}
} ) ;
} ) ;
Add DataTransferTaskFrame and GameCardImageDumpTaskFrame classes
DataTransferTaskFrame is a template class that's derived from brls::AppletFrame, which automatically starts a background task using an internal object belonging to a class derived from DataTransferTask. A DataTransferProgressDisplay view is used to show progress updates. If the background task hits an error, the class takes care of switching to an ErrorFrame view with the corresponding error message.
GameCardImageDumpTaskFrame is a derived class of DataTransferTaskFrame that uses a GameCardImageDumpTask object as its background task. In layman's terms, this provides a way to fully dump gamecard images using the new UI.
DataTransferTaskFrame depends on the newly added is_base_template helper from goneskiing to check if the class for the provided task is derived from DataTransferTask.
Other changes include:
* DataTransferProgressDisplay: rename setProgress() method to SetProgress().
* DataTransferTask: move post-task-execution code into its own new private method, PostExecutionCallback(), and update both OnCancelled() and OnPostExecute() callbacks to invoke it.
* DataTransferTask: update OnProgressUpdate() to allow sending a last progress update to all event subscribers even if the background task was cancelled.
* DataTransferTask: update OnProgressUpdate() to allow sending a first progress update if no data has been transferred but the total transfer size is already known.
* DataTransferTask: update OnProgressUpdate() to avoid calculating the ETA if the speed isn't greater than 0.
* DumpOptionsFrame: remove UpdateOutputStorages() method.
* DumpOptionsFrame: update class to use the cached output storage value from our RootView.
* DumpOptionsFrame: add GenerateOutputStoragesVector() method, which is used to avoid setting dummy options while initializing the output storages SelectListItem.
* DumpOptionsFrame: update UMS task callback to add the rest of the leftover logic from UpdateOutputStorages().
* DumpOptionsFrame: update RegisterButtonListener() to use a wrapper callback around the user-provided callback to check if the USB host was selected as the output storage but no USB host connection is available.
* ErrorFrame: use const references for all input string arguments.
* FileWriter: fix a localization stirng name typo.
* FileWriter: fix an exception that was previously being thrown by a fmt::format() call because of a wrong format specifier.
* FocusableItem: add a static assert to check if the provided ViewType is derived from brls::View.
* gamecard: redefine global gamecard status variable as an atomic unsigned 8-bit integer, which fixes a "status-hopping" issue previously experienced by repeating tasks running under other threads that periodically call gamecardGetStatus().
* GameCardImageDumpOptionsFrame: define GAMECARD_TOGGLE_ITEM macro, which is used to initialize all ToggleListItem elements from the view.
* GameCardImageDumpOptionsFrame: update button callback to push a GameCardImageDumpTaskFrame view onto the borealis stack.
* GameCardImageDumpTask: move class into its own header and module files.
* GameCardImageDumpTask: update class to also take in the checksum lookup method (not yet implemented).
* GameCardImageDumpTask: update class to send its first progress update as soon as the gamecard image size is known.
* GameCardImageDumpTask: update class to avoid returning a string if the task was cancelled -- DataTransferTaskFrame offers logic to display the appropiate cancel message on its own.
* GameCardTab: update PopulateList() method to display the new version information available in TitleGameCardApplicationMetadataEntry elements as part of the generated TitlesTabItem objects.
* i18n: add new localization strings.
* OptionsTab: update background task callback logic to handle task cancellation, reflecting the changes made to DataTransferTask.
* OptionsTab: reflect changes made to DataTransferProgressDisplay.
* RootView: cache the currently selected output storage value at all times, which is propagated throughout different parts of the UI. Getter and setter helpers have been added to operate with this value.
* RootView: add GetUsbHostSpeed() helper, which can be used by child views to retrieve the USB host speed on demand.
* RootView: update UMS task callback to automatically reset the cached output storage value back to the SD card if a UMS device was previously selected.
* title: define TitleGameCardApplicationMetadataEntry struct, which also holds version-specific information retrieved from the gamecard titles.
* title: refactor titleGetGameCardApplicationMetadataEntries() to return a dynamically allocated array of TitleGameCardApplicationMetadataEntry elements.
* usb: redefine global endpoint max packet size variable as an atomic unsigned 16-bit integer, which fixes a "status-hopping" issue previously experienced by repeating tasks running under other threads that periodically call usbIsReady().
* UsbHostTask: add GetUsbHostSpeed() method.
2024-04-29 14:26:12 +01:00
/* Manually update UMS devices vector. */
2024-04-18 20:58:47 +01:00
this - > ums_devices = this - > root_view - > GetUmsDevices ( ) ;
/* Subscribe to the UMS device event. */
2024-04-19 11:08:44 +01:00
this - > ums_task_sub = this - > root_view - > RegisterUmsTaskListener ( [ this , unmount_ums_device ] ( const nxdt : : tasks : : UmsDeviceVector & ums_devices ) {
2024-04-18 20:58:47 +01:00
/* Update UMS devices vector. */
Add DataTransferTaskFrame and GameCardImageDumpTaskFrame classes
DataTransferTaskFrame is a template class that's derived from brls::AppletFrame, which automatically starts a background task using an internal object belonging to a class derived from DataTransferTask. A DataTransferProgressDisplay view is used to show progress updates. If the background task hits an error, the class takes care of switching to an ErrorFrame view with the corresponding error message.
GameCardImageDumpTaskFrame is a derived class of DataTransferTaskFrame that uses a GameCardImageDumpTask object as its background task. In layman's terms, this provides a way to fully dump gamecard images using the new UI.
DataTransferTaskFrame depends on the newly added is_base_template helper from goneskiing to check if the class for the provided task is derived from DataTransferTask.
Other changes include:
* DataTransferProgressDisplay: rename setProgress() method to SetProgress().
* DataTransferTask: move post-task-execution code into its own new private method, PostExecutionCallback(), and update both OnCancelled() and OnPostExecute() callbacks to invoke it.
* DataTransferTask: update OnProgressUpdate() to allow sending a last progress update to all event subscribers even if the background task was cancelled.
* DataTransferTask: update OnProgressUpdate() to allow sending a first progress update if no data has been transferred but the total transfer size is already known.
* DataTransferTask: update OnProgressUpdate() to avoid calculating the ETA if the speed isn't greater than 0.
* DumpOptionsFrame: remove UpdateOutputStorages() method.
* DumpOptionsFrame: update class to use the cached output storage value from our RootView.
* DumpOptionsFrame: add GenerateOutputStoragesVector() method, which is used to avoid setting dummy options while initializing the output storages SelectListItem.
* DumpOptionsFrame: update UMS task callback to add the rest of the leftover logic from UpdateOutputStorages().
* DumpOptionsFrame: update RegisterButtonListener() to use a wrapper callback around the user-provided callback to check if the USB host was selected as the output storage but no USB host connection is available.
* ErrorFrame: use const references for all input string arguments.
* FileWriter: fix a localization stirng name typo.
* FileWriter: fix an exception that was previously being thrown by a fmt::format() call because of a wrong format specifier.
* FocusableItem: add a static assert to check if the provided ViewType is derived from brls::View.
* gamecard: redefine global gamecard status variable as an atomic unsigned 8-bit integer, which fixes a "status-hopping" issue previously experienced by repeating tasks running under other threads that periodically call gamecardGetStatus().
* GameCardImageDumpOptionsFrame: define GAMECARD_TOGGLE_ITEM macro, which is used to initialize all ToggleListItem elements from the view.
* GameCardImageDumpOptionsFrame: update button callback to push a GameCardImageDumpTaskFrame view onto the borealis stack.
* GameCardImageDumpTask: move class into its own header and module files.
* GameCardImageDumpTask: update class to also take in the checksum lookup method (not yet implemented).
* GameCardImageDumpTask: update class to send its first progress update as soon as the gamecard image size is known.
* GameCardImageDumpTask: update class to avoid returning a string if the task was cancelled -- DataTransferTaskFrame offers logic to display the appropiate cancel message on its own.
* GameCardTab: update PopulateList() method to display the new version information available in TitleGameCardApplicationMetadataEntry elements as part of the generated TitlesTabItem objects.
* i18n: add new localization strings.
* OptionsTab: update background task callback logic to handle task cancellation, reflecting the changes made to DataTransferTask.
* OptionsTab: reflect changes made to DataTransferProgressDisplay.
* RootView: cache the currently selected output storage value at all times, which is propagated throughout different parts of the UI. Getter and setter helpers have been added to operate with this value.
* RootView: add GetUsbHostSpeed() helper, which can be used by child views to retrieve the USB host speed on demand.
* RootView: update UMS task callback to automatically reset the cached output storage value back to the SD card if a UMS device was previously selected.
* title: define TitleGameCardApplicationMetadataEntry struct, which also holds version-specific information retrieved from the gamecard titles.
* title: refactor titleGetGameCardApplicationMetadataEntries() to return a dynamically allocated array of TitleGameCardApplicationMetadataEntry elements.
* usb: redefine global endpoint max packet size variable as an atomic unsigned 16-bit integer, which fixes a "status-hopping" issue previously experienced by repeating tasks running under other threads that periodically call usbIsReady().
* UsbHostTask: add GetUsbHostSpeed() method.
2024-04-29 14:26:12 +01:00
this - > ums_devices = ums_devices ;
2024-04-18 20:58:47 +01:00
/* Generate values vector for the dropdown. */
std : : vector < std : : string > values { } ;
for ( nxdt : : tasks : : UmsDeviceVectorEntry ums_device_entry : this - > ums_devices ) values . push_back ( ums_device_entry . second ) ;
/* Update SelectListItem values. */
/* If the dropdown menu is already being displayed, it'll be reloaded or popped from the view stack, depending on whether the provided vector is empty or not. */
2024-04-19 11:08:44 +01:00
unmount_ums_device - > updateValues ( values ) ;
2024-04-18 20:58:47 +01:00
} ) ;
this - > addView ( unmount_ums_device ) ;
2021-07-23 08:24:00 +01:00
/* Update application. */
2021-07-25 06:37:13 +01:00
brls : : ListItem * update_app = new brls : : ListItem ( " options_tab/update_app/label " _i18n , " options_tab/update_app/description " _i18n ) ;
2022-07-05 02:04:28 +01:00
2021-07-25 06:37:13 +01:00
update_app - > getClickEvent ( ) - > subscribe ( [ this ] ( brls : : View * view ) {
if ( envIsNso ( ) )
{
/* Display a notification if we're running as a NSO. */
this - > DisplayNotification ( " options_tab/notifications/is_nso " _i18n ) ;
return ;
} else
2021-08-11 08:17:57 +01:00
if ( ! this - > root_view - > IsInternetConnectionAvailable ( ) )
2021-07-29 20:55:31 +01:00
{
/* Display a notification if no Internet connection is available. */
this - > DisplayNotification ( " options_tab/notifications/no_internet_connection " _i18n ) ;
return ;
} else
2021-08-07 09:42:03 +01:00
if ( utilsGetApplicationUpdatedState ( ) )
2021-07-25 06:37:13 +01:00
{
/* Display a notification if the application has already been updated. */
this - > DisplayNotification ( " options_tab/notifications/already_updated " _i18n ) ;
return ;
}
2022-07-05 02:04:28 +01:00
2021-08-07 09:42:03 +01:00
/* Display update frame. */
2021-08-11 08:17:57 +01:00
brls : : Application : : pushView ( new OptionsTabUpdateApplicationFrame ( ) , brls : : ViewAnimation : : SLIDE_LEFT , false ) ;
2021-07-25 06:37:13 +01:00
} ) ;
2022-07-05 02:04:28 +01:00
2021-07-25 06:37:13 +01:00
this - > addView ( update_app ) ;
2024-05-01 11:50:36 +01:00
/* Reset settings. */
brls : : ListItem * reset_settings = new brls : : ListItem ( " options_tab/reset_settings/label " _i18n , " options_tab/reset_settings/description " _i18n ) ;
reset_settings - > getClickEvent ( ) - > subscribe ( [ this ] ( brls : : View * view ) {
if ( ! this - > display_notification ) return ;
2024-05-01 12:56:49 +01:00
/* Reset settings. */
2024-05-01 11:50:36 +01:00
configResetSettings ( ) ;
2024-05-01 12:56:49 +01:00
/* Reset cached output storage value. */
this - > root_view - > SetOutputStorage ( ConfigOutputStorage_SdCard ) ;
2024-05-01 11:50:36 +01:00
this - > DisplayNotification ( " options_tab/notifications/settings_reset " _i18n ) ;
} ) ;
this - > addView ( reset_settings ) ;
2021-07-25 06:37:13 +01:00
}
2022-07-05 02:04:28 +01:00
2024-04-19 11:08:44 +01:00
OptionsTab : : ~ OptionsTab ( )
2021-07-25 06:37:13 +01:00
{
2024-04-18 20:58:47 +01:00
this - > root_view - > UnregisterUmsTaskListener ( this - > ums_task_sub ) ;
this - > ums_devices . clear ( ) ;
2021-07-25 06:37:13 +01:00
brls : : menu_timer_kill ( & ( this - > notification_timer ) ) ;
}
2022-07-05 02:04:28 +01:00
2024-04-15 12:47:50 +01:00
void OptionsTab : : DisplayNotification ( const std : : string & str )
2021-07-25 06:37:13 +01:00
{
2024-04-15 12:47:50 +01:00
if ( str . empty ( ) | | ! this - > display_notification ) return ;
2022-07-05 02:04:28 +01:00
2021-07-25 06:37:13 +01:00
brls : : Application : : notify ( str ) ;
this - > display_notification = false ;
2022-07-05 02:04:28 +01:00
2021-07-25 06:37:13 +01:00
this - > notification_timer_ctx . duration = brls : : Application : : getStyle ( ) - > AnimationDuration . notificationTimeout ;
this - > notification_timer_ctx . cb = [ this ] ( void * userdata ) { this - > display_notification = true ; } ;
this - > notification_timer_ctx . tick = [ ] ( void * ) { } ;
this - > notification_timer_ctx . userdata = nullptr ;
2022-07-05 02:04:28 +01:00
2021-07-25 06:37:13 +01:00
brls : : menu_timer_start ( & ( this - > notification_timer ) , & ( this - > notification_timer_ctx ) ) ;
2021-07-23 08:24:00 +01:00
}
}