mirror of
https://github.com/DarkMatterCore/nxdumptool.git
synced 2024-11-25 11:42:11 +00:00
Rewrote RootView.
This commit is contained in:
parent
1654862198
commit
e2da60646d
30 changed files with 499 additions and 1097 deletions
|
@ -1,34 +0,0 @@
|
|||
/*
|
||||
Copyright 2020-2021 natinusala
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <borealis.hpp>
|
||||
|
||||
class CaptionedImage : public brls::Box
|
||||
{
|
||||
public:
|
||||
CaptionedImage();
|
||||
|
||||
void onChildFocusGained(brls::View* directChild, brls::View* focusedView) override;
|
||||
void onChildFocusLost(brls::View* directChild, brls::View* focusedView) override;
|
||||
|
||||
static brls::View* create();
|
||||
|
||||
private:
|
||||
BRLS_BIND(brls::Image, image, "image");
|
||||
BRLS_BIND(brls::Label, label, "label");
|
||||
};
|
|
@ -1,30 +0,0 @@
|
|||
/*
|
||||
Copyright 2021 natinusala
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <borealis.hpp>
|
||||
|
||||
class ComponentsTab : public brls::Box
|
||||
{
|
||||
public:
|
||||
ComponentsTab();
|
||||
|
||||
static brls::View* create();
|
||||
|
||||
private:
|
||||
bool onPrimaryButtonClicked(brls::View* view);
|
||||
};
|
|
@ -1,26 +0,0 @@
|
|||
/*
|
||||
Copyright 2020-2021 natinusala
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <borealis.hpp>
|
||||
|
||||
class MainActivity : public brls::Activity
|
||||
{
|
||||
public:
|
||||
// Declare that the content of this activity is the given XML file
|
||||
CONTENT_FROM_XML_RES("activity/main.xml");
|
||||
};
|
|
@ -1,27 +0,0 @@
|
|||
/*
|
||||
Copyright 2020-2021 natinusala
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <borealis.hpp>
|
||||
|
||||
class RecyclingListTab : public brls::Box
|
||||
{
|
||||
public:
|
||||
RecyclingListTab();
|
||||
|
||||
static brls::View* create();
|
||||
};
|
|
@ -39,7 +39,7 @@ namespace nxdt::views
|
|||
nxdt::tasks::UmsTask *ums_task = nullptr;
|
||||
nxdt::tasks::UsbHostTask *usb_host_task = nullptr;
|
||||
|
||||
nxdt::tasks::VoidEvent::Subscription status_info_task_sub;
|
||||
nxdt::tasks::StatusInfoEvent::Subscription status_info_task_sub;
|
||||
|
||||
brls::Label *applet_mode_lbl = nullptr;
|
||||
brls::Label *time_lbl = nullptr;
|
||||
|
@ -47,8 +47,8 @@ namespace nxdt::views
|
|||
brls::Label *connection_icon = nullptr, *connection_status_lbl = nullptr;
|
||||
|
||||
protected:
|
||||
void draw(NVGcontext* vg, int x, int y, unsigned width, unsigned height, brls::Style* style, brls::FrameContext* ctx) override;
|
||||
void layout(NVGcontext* vg, brls::Style* style, brls::FontStash* stash) override;
|
||||
void draw(NVGcontext* vg, float x, float y, float width, float height, brls::Style style, brls::FrameContext* ctx) override;
|
||||
void onLayout(void) override;
|
||||
|
||||
public:
|
||||
RootView(void);
|
|
@ -33,66 +33,65 @@
|
|||
|
||||
namespace nxdt::tasks
|
||||
{
|
||||
/* Custom event types used by the tasks defined below. */
|
||||
typedef brls::Event<GameCardStatus> GameCardStatusEvent;
|
||||
typedef brls::VoidEvent VoidEvent;
|
||||
typedef brls::Event<bool> BooleanEvent;
|
||||
/* Used to hold status info data. */
|
||||
typedef struct {
|
||||
struct tm *timeinfo;
|
||||
u32 charge_percentage;
|
||||
PsmChargerType charger_type;
|
||||
NifmInternetConnectionType connection_type;
|
||||
char *ip_addr;
|
||||
} StatusInfoData;
|
||||
|
||||
/* Custom vector type used to hold pointers to application metadata entries. */
|
||||
/* Used to hold pointers to application metadata entries. */
|
||||
typedef std::vector<TitleApplicationMetadata*> TitleApplicationMetadataVector;
|
||||
|
||||
/* Custom vector type used to hold UMS devices. */
|
||||
/* Used to hold UMS devices. */
|
||||
typedef std::vector<UsbHsFsDevice> UmsDeviceVector;
|
||||
|
||||
/* Custom event types. */
|
||||
typedef brls::Event<const StatusInfoData*> StatusInfoEvent;
|
||||
typedef brls::Event<GameCardStatus> GameCardStatusEvent;
|
||||
typedef brls::Event<const TitleApplicationMetadataVector*> TitleEvent;
|
||||
typedef brls::Event<const UmsDeviceVector*> UmsEvent;
|
||||
typedef brls::Event<bool> UsbHostEvent;
|
||||
|
||||
/* Status info task. */
|
||||
/* Its event returns a pointer to a StatusInfoData struct. */
|
||||
class StatusInfoTask: public brls::RepeatingTask
|
||||
{
|
||||
private:
|
||||
VoidEvent status_info_event;
|
||||
|
||||
std::string cur_time = "";
|
||||
|
||||
u32 charge_percentage = 0;
|
||||
PsmChargerType charger_type = PsmChargerType_Unconnected;
|
||||
|
||||
NifmInternetConnectionType connection_type = (NifmInternetConnectionType)0;
|
||||
u32 signal_strength = 0;
|
||||
NifmInternetConnectionStatus connection_status = (NifmInternetConnectionStatus)0;
|
||||
char *ip_addr = NULL;
|
||||
StatusInfoEvent status_info_event;
|
||||
StatusInfoData status_info_data = {0};
|
||||
|
||||
protected:
|
||||
void run(retro_time_t current_time) override;
|
||||
void run(void) override;
|
||||
|
||||
public:
|
||||
StatusInfoTask(void);
|
||||
~StatusInfoTask(void);
|
||||
|
||||
std::string GetCurrentTimeString(void);
|
||||
void GetBatteryStats(u32 *out_charge_percentage, PsmChargerType *out_charger_type);
|
||||
void GetNetworkStats(NifmInternetConnectionType *out_connection_type, u32 *out_signal_strength, NifmInternetConnectionStatus *out_connection_status, char **out_ip_addr);
|
||||
|
||||
ALWAYS_INLINE VoidEvent::Subscription RegisterListener(VoidEvent::Callback cb)
|
||||
ALWAYS_INLINE StatusInfoEvent::Subscription RegisterListener(StatusInfoEvent::Callback cb)
|
||||
{
|
||||
return this->status_info_event.subscribe(cb);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE void UnregisterListener(VoidEvent::Subscription subscription)
|
||||
ALWAYS_INLINE void UnregisterListener(StatusInfoEvent::Subscription subscription)
|
||||
{
|
||||
this->status_info_event.unsubscribe(subscription);
|
||||
}
|
||||
};
|
||||
|
||||
/* Gamecard task. */
|
||||
/* Its event returns a GameCardStatus value. */
|
||||
class GameCardTask: public brls::RepeatingTask
|
||||
{
|
||||
private:
|
||||
GameCardStatusEvent gc_status_event;
|
||||
|
||||
GameCardStatus cur_gc_status = GameCardStatus_NotInserted;
|
||||
GameCardStatus prev_gc_status = GameCardStatus_NotInserted;
|
||||
|
||||
protected:
|
||||
void run(retro_time_t current_time) override;
|
||||
void run(void) override;
|
||||
|
||||
public:
|
||||
GameCardTask(void);
|
||||
|
@ -110,10 +109,11 @@ namespace nxdt::tasks
|
|||
};
|
||||
|
||||
/* Title task. */
|
||||
/* Its event returns a pointer to a TitleApplicationMetadataVector with metadata for user titles (system titles don't change at runtime). */
|
||||
class TitleTask: public brls::RepeatingTask
|
||||
{
|
||||
private:
|
||||
VoidEvent title_event;
|
||||
TitleEvent title_event;
|
||||
|
||||
TitleApplicationMetadataVector system_metadata;
|
||||
TitleApplicationMetadataVector user_metadata;
|
||||
|
@ -121,50 +121,50 @@ namespace nxdt::tasks
|
|||
void PopulateApplicationMetadataVector(bool is_system);
|
||||
|
||||
protected:
|
||||
void run(retro_time_t current_time) override;
|
||||
void run(void) override;
|
||||
|
||||
public:
|
||||
TitleTask(void);
|
||||
~TitleTask(void);
|
||||
|
||||
/* Intentionally left here to let system titles views retrieve metadata. */
|
||||
TitleApplicationMetadataVector* GetApplicationMetadata(bool is_system);
|
||||
|
||||
ALWAYS_INLINE VoidEvent::Subscription RegisterListener(VoidEvent::Callback cb)
|
||||
ALWAYS_INLINE TitleEvent::Subscription RegisterListener(TitleEvent::Callback cb)
|
||||
{
|
||||
return this->title_event.subscribe(cb);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE void UnregisterListener(VoidEvent::Subscription subscription)
|
||||
ALWAYS_INLINE void UnregisterListener(TitleEvent::Subscription subscription)
|
||||
{
|
||||
this->title_event.unsubscribe(subscription);
|
||||
}
|
||||
};
|
||||
|
||||
/* USB Mass Storage task. */
|
||||
/* Its event returns a pointer to a UmsDeviceVector. */
|
||||
class UmsTask: public brls::RepeatingTask
|
||||
{
|
||||
private:
|
||||
VoidEvent ums_event;
|
||||
UmsEvent ums_event;
|
||||
|
||||
UmsDeviceVector ums_devices;
|
||||
|
||||
void PopulateUmsDeviceVector(void);
|
||||
|
||||
protected:
|
||||
void run(retro_time_t current_time) override;
|
||||
void run(void) override;
|
||||
|
||||
public:
|
||||
UmsTask(void);
|
||||
~UmsTask(void);
|
||||
|
||||
UmsDeviceVector* GetUmsDevices(void);
|
||||
|
||||
ALWAYS_INLINE VoidEvent::Subscription RegisterListener(VoidEvent::Callback cb)
|
||||
ALWAYS_INLINE UmsEvent::Subscription RegisterListener(UmsEvent::Callback cb)
|
||||
{
|
||||
return this->ums_event.subscribe(cb);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE void UnregisterListener(VoidEvent::Subscription subscription)
|
||||
ALWAYS_INLINE void UnregisterListener(UmsEvent::Subscription subscription)
|
||||
{
|
||||
this->ums_event.unsubscribe(subscription);
|
||||
}
|
||||
|
@ -174,24 +174,24 @@ namespace nxdt::tasks
|
|||
class UsbHostTask: public brls::RepeatingTask
|
||||
{
|
||||
private:
|
||||
BooleanEvent usb_host_event;
|
||||
UsbHostEvent usb_host_event;
|
||||
|
||||
bool cur_usb_host_status = false;
|
||||
bool prev_usb_host_status = false;
|
||||
|
||||
protected:
|
||||
void run(retro_time_t current_time) override;
|
||||
void run(void) override;
|
||||
|
||||
public:
|
||||
UsbHostTask(void);
|
||||
~UsbHostTask(void);
|
||||
|
||||
ALWAYS_INLINE BooleanEvent::Subscription RegisterListener(BooleanEvent::Callback cb)
|
||||
ALWAYS_INLINE UsbHostEvent::Subscription RegisterListener(UsbHostEvent::Callback cb)
|
||||
{
|
||||
return this->usb_host_event.subscribe(cb);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE void UnregisterListener(BooleanEvent::Subscription subscription)
|
||||
ALWAYS_INLINE void UnregisterListener(UsbHostEvent::Subscription subscription)
|
||||
{
|
||||
this->usb_host_event.unsubscribe(subscription);
|
||||
}
|
34
legacy_borealis/en-US/about_tab.json
Normal file
34
legacy_borealis/en-US/about_tab.json
Normal file
|
@ -0,0 +1,34 @@
|
|||
{
|
||||
"description": "Nintendo Switch Dump Tool",
|
||||
|
||||
"copyright": "Licensed under GPLv3+\n\u00A9 2020 - 2021 {0}\n{1}",
|
||||
|
||||
"dependencies": {
|
||||
"header": "Dependencies",
|
||||
"line_00": "\uE016 {0} is powered by Borealis, a hardware-accelerated UI library: {1}.",
|
||||
"line_01": "\uE016 USB Mass Storage device support is powered by libusbhsfs: {0}.",
|
||||
"line_02": "\uE016 FatFs is used to mount FAT volumes from the eMMC storage: {0}.",
|
||||
"line_03": "\uE016 LZ4 is used to decompress NSO binaries: {0}."
|
||||
},
|
||||
|
||||
"acknowledgments": {
|
||||
"header": "Acknowledgments",
|
||||
"line_00": "\uE016 Switchbrew and libnx contributors.",
|
||||
"line_01": "\uE016 SciresM, for hactool and Atmosphère-NX.",
|
||||
"line_02": "\uE016 shchmue, for Lockpick and its runtime key-collection algorithm, as well as helping in reverse engineering tasks.",
|
||||
"line_03": "\uE016 Adubbz, for Tinfoil and its ES service bindings.",
|
||||
"line_04": "\uE016 RattletraPM, for the awesome icon.",
|
||||
"line_05": "\uE016 Whovian9369, for being a key piece throughout the whole development by providing with lots of testing and cool ideas.",
|
||||
"line_06": "\uE016 0Liam, Shadów and SimonTime, for their tremendous help in understanding Nintendo Switch file and data formats.",
|
||||
"line_07": "\uE016 The folks from NSWDB.COM and No-Intro.org, for being kind enough to put up public APIs to perform online checksum lookups.",
|
||||
"line_08": "\uE016 The folks at the nxdumptool Discord server.",
|
||||
"line_09": "\uE016 The Comfy Boyes, for always being awesome and supportive. You know who you are.",
|
||||
"line_10": "\uE016 My girlfriend, for always being by my side and motivating me to keep working on all my projects. I love you. \uE87D",
|
||||
"line_11": "\uE016 And, at last but not least, you! Thank you for using my work!"
|
||||
},
|
||||
|
||||
"links": {
|
||||
"header": "Additional links and resources",
|
||||
"line_00": "\uE016 Discord server: {0}."
|
||||
}
|
||||
}
|
|
@ -1,8 +1,8 @@
|
|||
{
|
||||
"hints": {
|
||||
"ok": "OK",
|
||||
"back": "Retour",
|
||||
"exit": "Quitter"
|
||||
"back": "Back",
|
||||
"exit": "Exit"
|
||||
},
|
||||
|
||||
"crash_frame": {
|
||||
|
@ -10,6 +10,6 @@
|
|||
},
|
||||
|
||||
"thumbnail_sidebar": {
|
||||
"save": "Sauvegarder"
|
||||
"save": "Save"
|
||||
}
|
||||
}
|
57
legacy_borealis/en-US/gamecard_tab.json
Normal file
57
legacy_borealis/en-US/gamecard_tab.json
Normal file
|
@ -0,0 +1,57 @@
|
|||
{
|
||||
"notification": "Gamecard status change detected!",
|
||||
|
||||
"error_frame": {
|
||||
"not_inserted": "No gamecard inserted.",
|
||||
"processing": "Processing gamecard, please wait...",
|
||||
"nogc_enabled": "A gamecard has been inserted, but the \"nogc\" patch is enabled.\nNothing at all can be done with the inserted gamecard.\nDisabling this patch *will* update the Lotus ASIC firmware if it's outdated.\nConsider disabling this patch if you wish to use gamecard dumping features.",
|
||||
"lafw_update_required": "A gamecard has been inserted, but a Lotus ASIC firmware update is required.\nUpdate your console using the inserted gamecard and try again.",
|
||||
"info_not_loaded": "A gamecard has been inserted, but an unexpected I/O error occurred.\nPlease report this issue at \"{0}\"."
|
||||
},
|
||||
|
||||
"list": {
|
||||
"properties_table": {
|
||||
"header": "Gamecard properties",
|
||||
"capacity": "Capacity",
|
||||
"total_size": "Total size",
|
||||
"trimmed_size": "Trimmed size",
|
||||
"update_version": "Bundled update version",
|
||||
"lafw_version": "Required LAFW version",
|
||||
"lafw_version_value": "%lu or greater (%s)",
|
||||
"sdk_version": "SDK version",
|
||||
"compatibility_type": "Compatibility type"
|
||||
},
|
||||
|
||||
"dump_options": "Dump options",
|
||||
|
||||
"dump_card_image": {
|
||||
"label": "Dump gamecard image (XCI)",
|
||||
"description": "Generates a raw gamecard image. This is the option most people will want to use."
|
||||
},
|
||||
|
||||
"dump_certificate": {
|
||||
"label": "Dump gamecard certificate",
|
||||
"description": "The gamecard certificate is used to unequivocally identify each individual gamecard."
|
||||
},
|
||||
|
||||
"dump_header": {
|
||||
"label": "Dump gamecard header",
|
||||
"description": "The gamecard header holds information such as the location of the root HFS partition and the gamecard capacity.\nOnly useful for developers, preservationists and advanced users."
|
||||
},
|
||||
|
||||
"dump_decrypted_cardinfo": {
|
||||
"label": "Dump decrypted CardInfo area",
|
||||
"description": "The CardInfo area holds information such as the bundled system update version and the Lotus ASIC firmware version required by the gamecard.\nThis area is part of the gamecard header, but it's always encrypted.\nOnly useful for developers, preservationists and advanced users."
|
||||
},
|
||||
|
||||
"dump_initial_data": {
|
||||
"label": "Dump InitialData area",
|
||||
"description": "The InitialData area holds cryptographic information used by the Lotus ASIC to communicate with the gamecard.\nIt can't be dumped through normal means - it's not part of the storage areas from gamecard images.\nOnly useful for developers, preservationists and advanced users."
|
||||
},
|
||||
|
||||
"dump_hfs_partitions": {
|
||||
"label": "Dump Hash File System (HFS) partitions",
|
||||
"description": "Dumps data from the HFS partitions within the gamecard storage areas, in both raw and extracted forms."
|
||||
}
|
||||
}
|
||||
}
|
3
legacy_borealis/en-US/generic.json
Normal file
3
legacy_borealis/en-US/generic.json
Normal file
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"unknown": "Unknown"
|
||||
}
|
4
legacy_borealis/en-US/user_titles_tab.json
Normal file
4
legacy_borealis/en-US/user_titles_tab.json
Normal file
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"no_titles_available": "No user titles available.",
|
||||
"notification": "User titles list updated!"
|
||||
}
|
|
@ -1,211 +0,0 @@
|
|||
/*
|
||||
* root_view.cpp
|
||||
*
|
||||
* Copyright (c) 2020-2021, DarkMatterCore <pabloacurielz@gmail.com>.
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#include <nxdt_utils.h>
|
||||
#include <root_view.hpp>
|
||||
#include <gamecard_tab.hpp>
|
||||
#include <user_titles_tab.hpp>
|
||||
//#include <system_titles_tab.hpp>
|
||||
//#include <options_tab.hpp>
|
||||
#include <about_tab.hpp>
|
||||
|
||||
using namespace brls::i18n::literals; /* For _i18n. */
|
||||
|
||||
namespace nxdt::views
|
||||
{
|
||||
RootView::RootView(void) : brls::TabFrame()
|
||||
{
|
||||
/* Check if we're running under applet mode. */
|
||||
this->applet_mode = utilsAppletModeCheck();
|
||||
|
||||
/* Create labels. */
|
||||
this->applet_mode_lbl = new brls::Label(brls::LabelStyle::HINT, "root_view/applet_mode"_i18n);
|
||||
this->applet_mode_lbl->setColor(nvgRGB(255, 0, 0));
|
||||
this->applet_mode_lbl->setParent(this);
|
||||
|
||||
this->time_lbl = new brls::Label(brls::LabelStyle::SMALL, "");
|
||||
this->time_lbl->setParent(this);
|
||||
|
||||
this->battery_icon = new brls::Label(brls::LabelStyle::SMALL, "");
|
||||
this->battery_icon->setFont(brls::Application::getFontStash()->material);
|
||||
this->battery_icon->setParent(this);
|
||||
|
||||
this->battery_percentage = new brls::Label(brls::LabelStyle::SMALL, "");
|
||||
this->battery_percentage->setParent(this);
|
||||
|
||||
this->connection_icon = new brls::Label(brls::LabelStyle::SMALL, "");
|
||||
this->connection_icon->setFont(brls::Application::getFontStash()->material);
|
||||
this->connection_icon->setParent(this);
|
||||
|
||||
this->connection_status_lbl = new brls::Label(brls::LabelStyle::SMALL, "");
|
||||
this->connection_status_lbl->setParent(this);
|
||||
|
||||
/* Start background tasks. */
|
||||
this->status_info_task = new nxdt::tasks::StatusInfoTask();
|
||||
this->gc_status_task = new nxdt::tasks::GameCardTask();
|
||||
this->title_task = new nxdt::tasks::TitleTask();
|
||||
this->ums_task = new nxdt::tasks::UmsTask();
|
||||
this->usb_host_task = new nxdt::tasks::UsbHostTask();
|
||||
|
||||
/* Set UI properties. */
|
||||
this->setTitle(APP_TITLE);
|
||||
this->setIcon(BOREALIS_ASSET("icon/" APP_TITLE ".jpg"));
|
||||
this->setFooterText("v" APP_VERSION);
|
||||
|
||||
/* Add tabs. */
|
||||
this->addTab("root_view/tabs/gamecard"_i18n, new GameCardTab(this->gc_status_task));
|
||||
this->addSeparator();
|
||||
this->addTab("root_view/tabs/user_titles"_i18n, new UserTitlesTab(this->title_task));
|
||||
this->addTab("root_view/tabs/system_titles"_i18n, new brls::Rectangle(nvgRGB(0, 0, 255)));
|
||||
this->addSeparator();
|
||||
this->addTab("root_view/tabs/options"_i18n, new brls::Rectangle(nvgRGB(255, 255, 0)));
|
||||
this->addSeparator();
|
||||
this->addTab("root_view/tabs/about"_i18n, new AboutTab());
|
||||
|
||||
/* Subscribe to status info event. */
|
||||
this->status_info_task_sub = this->status_info_task->RegisterListener([this](void) {
|
||||
u32 charge_percentage = 0;
|
||||
PsmChargerType charger_type = PsmChargerType_Unconnected;
|
||||
|
||||
NifmInternetConnectionType connection_type = (NifmInternetConnectionType)0;
|
||||
u32 signal_strength = 0;
|
||||
NifmInternetConnectionStatus connection_status = (NifmInternetConnectionStatus)0;
|
||||
char *ip_addr = NULL;
|
||||
|
||||
/* Update time label. */
|
||||
this->time_lbl->setText(this->status_info_task->GetCurrentTimeString());
|
||||
|
||||
/* Update battery labels. */
|
||||
this->status_info_task->GetBatteryStats(&charge_percentage, &charger_type);
|
||||
|
||||
this->battery_icon->setText(charger_type != PsmChargerType_Unconnected ? "\uE1A3" : (charge_percentage <= 15 ? "\uE19C" : "\uE1A4"));
|
||||
this->battery_icon->setColor(charger_type != PsmChargerType_Unconnected ? nvgRGB(0, 255, 0) : (charge_percentage <= 15 ? nvgRGB(255, 0, 0) : brls::Application::getTheme()->textColor));
|
||||
|
||||
this->battery_percentage->setText(fmt::format("{}%", charge_percentage));
|
||||
|
||||
/* Update network label. */
|
||||
this->status_info_task->GetNetworkStats(&connection_type, &signal_strength, &connection_status, &ip_addr);
|
||||
|
||||
this->connection_icon->setText(!connection_type ? "\uE195" : (connection_type == NifmInternetConnectionType_WiFi ? "\uE63E" : "\uE8BE"));
|
||||
this->connection_status_lbl->setText(ip_addr ? std::string(ip_addr) : "root_view/not_connected"_i18n);
|
||||
|
||||
/* Update layout. */
|
||||
this->invalidate(true);
|
||||
});
|
||||
}
|
||||
|
||||
RootView::~RootView(void)
|
||||
{
|
||||
/* Unregister status info task listener. */
|
||||
this->status_info_task->UnregisterListener(this->status_info_task_sub);
|
||||
|
||||
/* Destroy labels. */
|
||||
delete this->applet_mode_lbl;
|
||||
delete this->time_lbl;
|
||||
delete this->battery_icon;
|
||||
delete this->battery_percentage;
|
||||
delete this->connection_icon;
|
||||
delete this->connection_status_lbl;
|
||||
|
||||
/* Stop background tasks. */
|
||||
this->gc_status_task->stop();
|
||||
this->title_task->stop();
|
||||
this->ums_task->stop();
|
||||
this->usb_host_task->stop();
|
||||
}
|
||||
|
||||
void RootView::draw(NVGcontext* vg, int x, int y, unsigned width, unsigned height, brls::Style* style, brls::FrameContext* ctx)
|
||||
{
|
||||
if (this->applet_mode) this->applet_mode_lbl->frame(ctx);
|
||||
|
||||
this->time_lbl->frame(ctx);
|
||||
|
||||
this->battery_icon->frame(ctx);
|
||||
this->battery_percentage->frame(ctx);
|
||||
|
||||
this->connection_icon->frame(ctx);
|
||||
this->connection_status_lbl->frame(ctx);
|
||||
|
||||
brls::AppletFrame::draw(vg, x, y, width, height, style, ctx);
|
||||
}
|
||||
|
||||
void RootView::layout(NVGcontext* vg, brls::Style* style, brls::FontStash* stash)
|
||||
{
|
||||
int y_pos = 0;
|
||||
|
||||
brls::AppletFrame::layout(vg, style, stash);
|
||||
|
||||
if (this->applet_mode)
|
||||
{
|
||||
/* Applet mode label. */
|
||||
this->applet_mode_lbl->invalidate(true);
|
||||
this->applet_mode_lbl->setBoundaries(
|
||||
this->x + (this->width / 4) - (this->applet_mode_lbl->getWidth() / 2),
|
||||
this->y + this->height - (style->AppletFrame.footerHeight / 2),
|
||||
this->applet_mode_lbl->getWidth(),
|
||||
this->applet_mode_lbl->getHeight());
|
||||
}
|
||||
|
||||
/* Time label. */
|
||||
this->time_lbl->invalidate(true);
|
||||
y_pos += this->y + 25 + this->time_lbl->getHeight();
|
||||
|
||||
this->time_lbl->setBoundaries(
|
||||
this->x + this->width - (style->AppletFrame.separatorSpacing * 2) - this->time_lbl->getWidth(),
|
||||
y_pos,
|
||||
this->time_lbl->getWidth(),
|
||||
this->time_lbl->getHeight());
|
||||
|
||||
/* Battery stats labels. */
|
||||
this->battery_icon->invalidate(true);
|
||||
this->battery_percentage->invalidate(true);
|
||||
y_pos += (20 + this->battery_icon->getHeight());
|
||||
|
||||
this->battery_icon->setBoundaries(
|
||||
this->x + this->width - (style->AppletFrame.separatorSpacing * 2) - this->battery_percentage->getWidth() - 5 - this->battery_icon->getWidth(),
|
||||
y_pos,
|
||||
this->battery_icon->getWidth(),
|
||||
this->battery_icon->getHeight());
|
||||
|
||||
this->battery_percentage->setBoundaries(
|
||||
this->x + this->width - (style->AppletFrame.separatorSpacing * 2) - this->battery_percentage->getWidth(),
|
||||
y_pos,
|
||||
this->battery_percentage->getWidth(),
|
||||
this->battery_percentage->getHeight());
|
||||
|
||||
/* Network connection labels. */
|
||||
this->connection_icon->invalidate(true);
|
||||
this->connection_status_lbl->invalidate(true);
|
||||
y_pos += (20 + this->connection_icon->getHeight());
|
||||
|
||||
this->connection_icon->setBoundaries(
|
||||
this->x + this->width - (style->AppletFrame.separatorSpacing * 2) - this->connection_status_lbl->getWidth() - 5 - this->connection_icon->getWidth(),
|
||||
y_pos,
|
||||
this->connection_icon->getWidth(),
|
||||
this->connection_icon->getHeight());
|
||||
|
||||
this->connection_status_lbl->setBoundaries(
|
||||
this->x + this->width - (style->AppletFrame.separatorSpacing * 2) - this->connection_status_lbl->getWidth(),
|
||||
y_pos,
|
||||
this->connection_status_lbl->getWidth(),
|
||||
this->connection_status_lbl->getHeight());
|
||||
}
|
||||
}
|
|
@ -1,48 +0,0 @@
|
|||
{
|
||||
"title": "Borealis Demo App",
|
||||
|
||||
"tabs": {
|
||||
"components": "Basic components",
|
||||
"layout": "Layout and alignment",
|
||||
"recycling": "Recycling lists",
|
||||
"popups": "Popups, notifications and dialogs",
|
||||
"hos_layout": "Horizon layouts",
|
||||
"misc_layouts": "Misc. layouts",
|
||||
"misc_components": "Misc. components",
|
||||
"misc_tools": "Misc. dev tools",
|
||||
"about": "About borealis"
|
||||
},
|
||||
|
||||
"welcome": "Welcome to the borealis demo! Feel free to explore and discover what the library can do.",
|
||||
|
||||
"components": {
|
||||
"buttons_header": "Buttons",
|
||||
"button_primary": "Primary button",
|
||||
"button_highlight": "\uE13C Highlight button",
|
||||
"button_wrapping": "Default button with wrapping text",
|
||||
"button_bordered": "Bordered button",
|
||||
"button_borderless": "Borderless button",
|
||||
|
||||
"labels_header": "Labels",
|
||||
"regular_label": "This is a label. By default, they will automatically wrap and expand their height, should the remaining vertical space allow it. Otherwise, they will be truncated, like some of the tabs of the sidebar.",
|
||||
"label_left": "This label is left-aligned",
|
||||
"label_center": "This label is center-aligned",
|
||||
"label_right": "This label is right-aligned",
|
||||
|
||||
"images_header_title": "Images",
|
||||
"images_header_subtitle": "Focus them to see the scaling method",
|
||||
"images_downscaled": "Downscaled",
|
||||
"images_original": "Original",
|
||||
"images_upscaled": "Upscaled",
|
||||
"images_stretched": "Stretched",
|
||||
"images_cropped": "Cropped"
|
||||
},
|
||||
|
||||
"about": {
|
||||
"title": "borealis",
|
||||
"description": "A hardware accelerated, controller and TV oriented UI library for PC and Nintendo Switch (libnx).",
|
||||
"github": "Find it on github.com/natinusala/borealis",
|
||||
"licence": "Licensed under Apache 2.0",
|
||||
"logo_credit": "Logo by @MeganRoshelle"
|
||||
}
|
||||
}
|
19
resources/i18n/en-US/root_view.json
Normal file
19
resources/i18n/en-US/root_view.json
Normal file
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"applet_mode": "\uE8B2 Applet Mode \uE8B2",
|
||||
|
||||
"time_format": "12",
|
||||
"__time_format_comment__": "Use 12 for a 12-hour clock, or 24 for a 24-hour clock",
|
||||
|
||||
"date": "{1:02d}/{2:02d}/{0} {3:02d}:{4:02d}:{5:02d} {6}",
|
||||
"__date_comment__": "{0} = Year, {1} = Month, {2} = Day, {3} = Hour, {4} = Minute, {5} = Second, {6} = AM/PM (if time_format is set to 12)",
|
||||
|
||||
"not_connected": "Not connected",
|
||||
|
||||
"tabs": {
|
||||
"gamecard": "Gamecard",
|
||||
"user_titles": "User titles",
|
||||
"system_titles": "System titles",
|
||||
"options": "Options",
|
||||
"about": "About"
|
||||
}
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
{}
|
Binary file not shown.
Before Width: | Height: | Size: 24 KiB |
Binary file not shown.
Before Width: | Height: | Size: 6.3 KiB |
Binary file not shown.
Before Width: | Height: | Size: 85 KiB |
|
@ -1,102 +0,0 @@
|
|||
<brls:TabFrame
|
||||
title="@i18n/demo/title"
|
||||
iconInterpolation="linear"
|
||||
icon="@res/img/borealis_96.png">
|
||||
|
||||
<!-- Dynamic tab - required to get references to the views in the code -->
|
||||
<brls:Tab label="@i18n/demo/tabs/components" >
|
||||
<ComponentsTab />
|
||||
</brls:Tab>
|
||||
|
||||
<!-- Static tab linking to another XML -->
|
||||
<brls:Tab label="@i18n/demo/tabs/layout" >
|
||||
<brls:View xml="@res/xml/tabs/layout.xml" />
|
||||
</brls:Tab>
|
||||
|
||||
<brls:Tab label="@i18n/demo/tabs/recycling">
|
||||
<RecyclingListTab />
|
||||
</brls:Tab>
|
||||
|
||||
<brls:Separator />
|
||||
|
||||
<brls:Tab label="@i18n/demo/tabs/popups" />
|
||||
<brls:Tab label="@i18n/demo/tabs/hos_layout" />
|
||||
|
||||
<brls:Separator />
|
||||
|
||||
<brls:Tab label="@i18n/demo/tabs/misc_layouts" />
|
||||
<brls:Tab label="@i18n/demo/tabs/misc_components" />
|
||||
<brls:Tab label="@i18n/demo/tabs/misc_tools" />
|
||||
|
||||
<brls:Separator />
|
||||
|
||||
<!-- Static tab with inline XML -->
|
||||
<brls:Tab label="@i18n/demo/tabs/about" >
|
||||
|
||||
<brls:Box
|
||||
width="auto"
|
||||
height="auto"
|
||||
axis="column"
|
||||
paddingTop="@style/about/padding_top_bottom"
|
||||
paddingBottom="@style/about/padding_top_bottom"
|
||||
paddingLeft="@style/about/padding_sides"
|
||||
paddingRight="@style/about/padding_sides" >
|
||||
|
||||
<brls:Image
|
||||
width="auto"
|
||||
height="33%"
|
||||
image="@res/img/borealis_256.png"
|
||||
marginBottom="@style/about/description_margin"/>
|
||||
|
||||
<brls:Box
|
||||
width="auto"
|
||||
height="auto"
|
||||
axis="row"
|
||||
marginBottom="@style/about/description_margin">
|
||||
|
||||
<brls:Label
|
||||
width="40%"
|
||||
height="auto"
|
||||
text="@i18n/demo/about/title"
|
||||
fontSize="36"
|
||||
horizontalAlign="right"
|
||||
verticalAlign="top" />
|
||||
|
||||
<brls:Label
|
||||
width="auto"
|
||||
height="auto"
|
||||
text="@i18n/demo/about/description"
|
||||
marginLeft="@style/about/description_margin" />
|
||||
|
||||
</brls:Box>
|
||||
|
||||
<brls:Box
|
||||
width="auto"
|
||||
height="auto"
|
||||
axis="column"
|
||||
alignItems="center"
|
||||
justifyContent="spaceEvenly"
|
||||
grow="1.0" >
|
||||
|
||||
<brls:Label
|
||||
width="auto"
|
||||
height="auto"
|
||||
text="@i18n/demo/about/github" />
|
||||
|
||||
<brls:Label
|
||||
width="auto"
|
||||
height="auto"
|
||||
text="@i18n/demo/about/licence" />
|
||||
|
||||
<brls:Label
|
||||
width="auto"
|
||||
height="auto"
|
||||
text="@i18n/demo/about/logo_credit" />
|
||||
|
||||
</brls:Box>
|
||||
|
||||
</brls:Box>
|
||||
|
||||
</brls:Tab>
|
||||
|
||||
</brls:TabFrame>
|
|
@ -1,216 +0,0 @@
|
|||
<brls:Box
|
||||
width="auto"
|
||||
height="auto">
|
||||
|
||||
<brls:ScrollingFrame
|
||||
width="auto"
|
||||
height="auto"
|
||||
grow="1.0" >
|
||||
|
||||
<brls:Box
|
||||
width="auto"
|
||||
height="auto"
|
||||
axis="column"
|
||||
paddingLeft="@style/brls/tab_frame/content_padding_sides"
|
||||
paddingRight="@style/brls/tab_frame/content_padding_sides"
|
||||
paddingTop="@style/brls/tab_frame/content_padding_top_bottom"
|
||||
paddingBottom="@style/brls/tab_frame/content_padding_top_bottom">
|
||||
|
||||
<brls:Label
|
||||
width="auto"
|
||||
height="auto"
|
||||
text="@i18n/demo/welcome"
|
||||
marginBottom="10px" />
|
||||
|
||||
<!-- Buttons -->
|
||||
<brls:Header
|
||||
width="auto"
|
||||
height="auto"
|
||||
title="@i18n/demo/components/buttons_header"
|
||||
marginBottom="30px" />
|
||||
|
||||
<brls:Box
|
||||
width="100%"
|
||||
height="auto"
|
||||
axis="row"
|
||||
marginBottom="30px">
|
||||
|
||||
<brls:Button
|
||||
id="button_primary"
|
||||
width="auto"
|
||||
height="auto"
|
||||
style="primary"
|
||||
grow="1.0"
|
||||
marginRight="30px"
|
||||
text="@i18n/demo/components/button_primary" />
|
||||
|
||||
<brls:Button
|
||||
id="button_highlight"
|
||||
width="auto"
|
||||
height="auto"
|
||||
style="highlight"
|
||||
text="@i18n/demo/components/button_highlight"
|
||||
focusDown="button_bordered" />
|
||||
|
||||
</brls:Box>
|
||||
|
||||
<brls:Box
|
||||
width="100%"
|
||||
height="auto"
|
||||
axis="row"
|
||||
marginBottom="30px">
|
||||
|
||||
<brls:Button
|
||||
width="33%"
|
||||
height="auto"
|
||||
marginRight="30px"
|
||||
text="@i18n/demo/components/button_wrapping" />
|
||||
|
||||
<brls:Box
|
||||
width="auto"
|
||||
height="auto"
|
||||
grow="1.0"
|
||||
axis="column">
|
||||
|
||||
<brls:Button
|
||||
id="button_bordered"
|
||||
width="auto"
|
||||
height="auto"
|
||||
padding="10px"
|
||||
style="bordered"
|
||||
fontSize="16"
|
||||
text="@i18n/demo/components/button_bordered"
|
||||
marginBottom="30px" />
|
||||
|
||||
<brls:Button
|
||||
width="auto"
|
||||
height="auto"
|
||||
padding="10px"
|
||||
style="borderless"
|
||||
fontSize="16"
|
||||
text="@i18n/demo/components/button_borderless" />
|
||||
|
||||
</brls:Box>
|
||||
|
||||
</brls:Box>
|
||||
|
||||
<!-- Labels -->
|
||||
<brls:Header
|
||||
width="auto"
|
||||
height="auto"
|
||||
title="@i18n/demo/components/labels_header"
|
||||
marginBottom="30px" />
|
||||
|
||||
<brls:Label
|
||||
width="auto"
|
||||
height="auto"
|
||||
text="@i18n/demo/components/regular_label"
|
||||
marginBottom="30px" />
|
||||
|
||||
<brls:Box
|
||||
width="auto"
|
||||
height="auto"
|
||||
axis="row"
|
||||
justifyContent="spaceEvenly"
|
||||
marginBottom="30px" >
|
||||
|
||||
<brls:Label
|
||||
width="30%"
|
||||
height="auto"
|
||||
text="@i18n/demo/components/label_left"
|
||||
horizontalAlign="left" />
|
||||
|
||||
<brls:Label
|
||||
width="30%"
|
||||
height="auto"
|
||||
text="@i18n/demo/components/label_center"
|
||||
horizontalAlign="center" />
|
||||
|
||||
<brls:Label
|
||||
width="30%"
|
||||
height="auto"
|
||||
text="@i18n/demo/components/label_right"
|
||||
horizontalAlign="right" />
|
||||
|
||||
</brls:Box>
|
||||
|
||||
<!-- Images -->
|
||||
<brls:Header
|
||||
width="auto"
|
||||
height="auto"
|
||||
title="@i18n/demo/components/images_header_title"
|
||||
subtitle="@i18n/demo/components/images_header_subtitle"
|
||||
marginBottom="30px" />
|
||||
|
||||
<brls:Box
|
||||
width="auto"
|
||||
height="auto"
|
||||
axis="row"
|
||||
alignItems="center"
|
||||
justifyContent="spaceEvenly"
|
||||
marginBottom="30px">
|
||||
|
||||
<CaptionedImage
|
||||
width="auto"
|
||||
height="auto"
|
||||
imageWidth="76px"
|
||||
imageHeight="76px"
|
||||
image="@res/img/tiles.png"
|
||||
caption="@i18n/demo/components/images_downscaled" />
|
||||
|
||||
<CaptionedImage
|
||||
id="image_original"
|
||||
width="auto"
|
||||
height="auto"
|
||||
imageWidth="auto"
|
||||
imageHeight="auto"
|
||||
image="@res/img/tiles.png"
|
||||
caption="@i18n/demo/components/images_original" />
|
||||
|
||||
<CaptionedImage
|
||||
id="image_upscaled"
|
||||
width="auto"
|
||||
height="auto"
|
||||
imageWidth="170px"
|
||||
imageHeight="170px"
|
||||
maxWidth="170px"
|
||||
image="@res/img/tiles.png"
|
||||
caption="@i18n/demo/components/images_upscaled"
|
||||
focusDown="image_cropped" />
|
||||
|
||||
</brls:Box>
|
||||
|
||||
<brls:Box
|
||||
width="auto"
|
||||
height="auto"
|
||||
axis="row"
|
||||
alignItems="center"
|
||||
justifyContent="spaceEvenly">
|
||||
|
||||
<CaptionedImage
|
||||
width="auto"
|
||||
height="auto"
|
||||
imageWidth="400px"
|
||||
imageHeight="75px"
|
||||
image="@res/img/tiles.png"
|
||||
scalingType="stretch"
|
||||
caption="@i18n/demo/components/images_stretched" />
|
||||
|
||||
<CaptionedImage
|
||||
id="image_cropped"
|
||||
width="auto"
|
||||
height="auto"
|
||||
imageWidth="auto"
|
||||
imageHeight="75px"
|
||||
image="@res/img/tiles.png"
|
||||
scalingType="crop"
|
||||
caption="@i18n/demo/components/images_cropped"
|
||||
focusUp="image_upscaled" />
|
||||
|
||||
</brls:Box>
|
||||
|
||||
</brls:Box>
|
||||
|
||||
</brls:ScrollingFrame>
|
||||
|
||||
</brls:Box>
|
|
@ -1,4 +0,0 @@
|
|||
<brls:Rectangle
|
||||
width="auto"
|
||||
height="auto"
|
||||
color="#50FFDD" />
|
|
@ -1,11 +0,0 @@
|
|||
<brls:Box
|
||||
width="auto"
|
||||
height="auto">
|
||||
|
||||
<brls:Rectangle
|
||||
width="auto"
|
||||
height="auto"
|
||||
grow="1.0"
|
||||
color="#0000FF" />
|
||||
|
||||
</brls:Box>
|
|
@ -1,21 +0,0 @@
|
|||
<brls:Box
|
||||
width="auto"
|
||||
height="auto"
|
||||
axis="column"
|
||||
alignItems="center">
|
||||
|
||||
<brls:Image
|
||||
id="image"
|
||||
width="auto"
|
||||
height="auto"
|
||||
focusable="true"
|
||||
marginBottom="20px" />
|
||||
|
||||
<brls:Label
|
||||
id="label"
|
||||
width="auto"
|
||||
height="auto"
|
||||
horizontalAlign="center"
|
||||
textColor="@theme/captioned_image/caption" />
|
||||
|
||||
</brls:Box>
|
|
@ -1,65 +0,0 @@
|
|||
/*
|
||||
Copyright 2020-2021 natinusala
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#include "captioned_image.hpp"
|
||||
|
||||
CaptionedImage::CaptionedImage()
|
||||
{
|
||||
// Load the XML file and inflate ourself with its content
|
||||
// The top-level Box in the XML corresponds to us, and every XML child
|
||||
// is added to our children (and the attributes are applied)
|
||||
// The CaptionedImage instance basically becomes what's written in the XML
|
||||
this->inflateFromXMLRes("xml/views/captioned_image.xml");
|
||||
|
||||
// The label stays hidden until focused, so hide it right away
|
||||
this->label->hide([] {});
|
||||
|
||||
// Forward Image and Label XML attributes
|
||||
this->forwardXMLAttribute("scalingType", this->image);
|
||||
this->forwardXMLAttribute("image", this->image);
|
||||
this->forwardXMLAttribute("focusUp", this->image);
|
||||
this->forwardXMLAttribute("focusRight", this->image);
|
||||
this->forwardXMLAttribute("focusDown", this->image);
|
||||
this->forwardXMLAttribute("focusLeft", this->image);
|
||||
this->forwardXMLAttribute("imageWidth", this->image, "width");
|
||||
this->forwardXMLAttribute("imageHeight", this->image, "height");
|
||||
|
||||
this->forwardXMLAttribute("caption", this->label, "text");
|
||||
}
|
||||
|
||||
void CaptionedImage::onChildFocusGained(brls::View* directChild, brls::View* focusedView)
|
||||
{
|
||||
// Called when a child of ours gets focused, in that case it's the Image
|
||||
|
||||
Box::onChildFocusGained(directChild, focusedView);
|
||||
|
||||
this->label->show([] {});
|
||||
}
|
||||
|
||||
void CaptionedImage::onChildFocusLost(brls::View* directChild, brls::View* focusedView)
|
||||
{
|
||||
// Called when a child of ours losts focused, in that case it's the Image
|
||||
|
||||
Box::onChildFocusLost(directChild, focusedView);
|
||||
|
||||
this->label->hide([] {});
|
||||
}
|
||||
|
||||
brls::View* CaptionedImage::create()
|
||||
{
|
||||
// Called by the XML engine to create a new CaptionedImage
|
||||
return new CaptionedImage();
|
||||
}
|
|
@ -1,43 +0,0 @@
|
|||
/*
|
||||
Copyright 2021 natinusala
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#include "components_tab.hpp"
|
||||
|
||||
ComponentsTab::ComponentsTab()
|
||||
{
|
||||
// Inflate the tab from the XML file
|
||||
this->inflateFromXMLRes("xml/tabs/components.xml");
|
||||
|
||||
// Bind the button click to a method using the macro (just for the sake of showcasing it, it's overkill in this situation)
|
||||
BRLS_REGISTER_CLICK_BY_ID("button_primary", this->onPrimaryButtonClicked);
|
||||
|
||||
// Get a handle to the button and register the action directly
|
||||
brls::Button* highlightButton = (brls::Button*)this->getView("button_highlight");
|
||||
highlightButton->registerAction(
|
||||
"Honk", brls::BUTTON_A, [](brls::View* view) { return true; }, false, brls::SOUND_HONK);
|
||||
}
|
||||
|
||||
bool ComponentsTab::onPrimaryButtonClicked(brls::View* view)
|
||||
{
|
||||
brls::Logger::info("Clicked");
|
||||
return true;
|
||||
}
|
||||
|
||||
brls::View* ComponentsTab::create()
|
||||
{
|
||||
// Called by the XML engine to create a new ComponentsTab
|
||||
return new ComponentsTab();
|
||||
}
|
|
@ -1,59 +1,64 @@
|
|||
/*
|
||||
* main.cpp
|
||||
*
|
||||
* Copyright (c) 2020-2021, DarkMatterCore <pabloacurielz@gmail.com>.
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#include <nxdt_utils.h>
|
||||
#include <scope_guard.hpp>
|
||||
|
||||
#include <borealis.hpp>
|
||||
|
||||
#include "captioned_image.hpp"
|
||||
#include "components_tab.hpp"
|
||||
#include "main_activity.hpp"
|
||||
#include "recycling_list_tab.hpp"
|
||||
|
||||
using namespace brls::literals; // for _i18n
|
||||
#include <root_view.hpp>
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
/* Set scope guard to clean up resources at exit. */
|
||||
ON_SCOPE_EXIT { utilsCloseResources(); };
|
||||
|
||||
|
||||
/* Initialize application resources. */
|
||||
if (!utilsInitializeResources(argc, (const char**)argv)) return EXIT_FAILURE;
|
||||
|
||||
// Set log level
|
||||
// We recommend to use INFO for real apps
|
||||
|
||||
/* Set Borealis log level. */
|
||||
/* TODO: set this to INFO before a proper release. */
|
||||
brls::Logger::setLogLevel(brls::LogLevel::DEBUG);
|
||||
|
||||
// Init the app and i18n
|
||||
if (!brls::Application::init())
|
||||
{
|
||||
brls::Logger::error("Unable to init Borealis application");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
brls::Application::createWindow("demo/title"_i18n);
|
||||
|
||||
// Have the application register an action on every activity that will quit when you press BUTTON_START
|
||||
|
||||
/* Initialize Borealis. */
|
||||
if (!brls::Application::init()) return EXIT_FAILURE;
|
||||
|
||||
/* Create application window. */
|
||||
brls::Application::createWindow(APP_TITLE);
|
||||
|
||||
/* Set common footer. */
|
||||
brls::Application::setCommonFooter("v" APP_VERSION);
|
||||
|
||||
/* Register an action on every activity to quit whenever BUTTON_START is pressed. */
|
||||
brls::Application::setGlobalQuit(true);
|
||||
|
||||
// Register custom views (including tabs, which are views)
|
||||
brls::Application::registerXMLView("CaptionedImage", CaptionedImage::create);
|
||||
brls::Application::registerXMLView("RecyclingListTab", RecyclingListTab::create);
|
||||
brls::Application::registerXMLView("ComponentsTab", ComponentsTab::create);
|
||||
|
||||
// Add custom values to the theme
|
||||
brls::getLightTheme().addColor("captioned_image/caption", nvgRGB(2, 176, 183));
|
||||
brls::getDarkTheme().addColor("captioned_image/caption", nvgRGB(51, 186, 227));
|
||||
|
||||
// Add custom values to the style
|
||||
brls::getStyle().addMetric("about/padding_top_bottom", 50);
|
||||
brls::getStyle().addMetric("about/padding_sides", 75);
|
||||
brls::getStyle().addMetric("about/description_margin", 50);
|
||||
|
||||
// Create and push the main activity to the stack
|
||||
brls::Application::pushActivity(new MainActivity());
|
||||
|
||||
// Run the app
|
||||
while (brls::Application::mainLoop());
|
||||
|
||||
// Exit
|
||||
|
||||
/* Display a FPS counter whenever BUTTON_BACK is pressed. */
|
||||
/* TODO: disable this before a proper release. */
|
||||
brls::Application::setGlobalFPSToggle(true);
|
||||
|
||||
/* Create and push the main activity to the stack. */
|
||||
brls::Activity *main_activity = new brls::Activity();
|
||||
main_activity->setContentView(new nxdt::views::RootView());
|
||||
brls::Application::pushActivity(main_activity);
|
||||
|
||||
/* Run the application. */
|
||||
while(brls::Application::mainLoop());
|
||||
|
||||
/* Exit. */
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -1,17 +0,0 @@
|
|||
/*
|
||||
Copyright 2020-2021 natinusala
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#include "main_activity.hpp"
|
|
@ -1,29 +0,0 @@
|
|||
/*
|
||||
Copyright 2020-2021 natinusala
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#include "recycling_list_tab.hpp"
|
||||
|
||||
RecyclingListTab::RecyclingListTab()
|
||||
{
|
||||
// Inflate the tab from the XML file
|
||||
this->inflateFromXMLRes("xml/tabs/recycling_list.xml");
|
||||
}
|
||||
|
||||
brls::View* RecyclingListTab::create()
|
||||
{
|
||||
// Called by the XML engine to create a new RecyclingListTab
|
||||
return new RecyclingListTab();
|
||||
}
|
219
source/root_view.cpp
Normal file
219
source/root_view.cpp
Normal file
|
@ -0,0 +1,219 @@
|
|||
/*
|
||||
* root_view.cpp
|
||||
*
|
||||
* Copyright (c) 2020-2021, DarkMatterCore <pabloacurielz@gmail.com>.
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#include <nxdt_utils.h>
|
||||
#include <root_view.hpp>
|
||||
//#include <gamecard_tab.hpp>
|
||||
//#include <user_titles_tab.hpp>
|
||||
//#include <system_titles_tab.hpp>
|
||||
//#include <options_tab.hpp>
|
||||
//#include <about_tab.hpp>
|
||||
|
||||
using namespace brls::literals; /* For _i18n. */
|
||||
|
||||
namespace nxdt::views
|
||||
{
|
||||
RootView::RootView(void) : brls::TabFrame()
|
||||
{
|
||||
/* Set UI properties. */
|
||||
this->setTitle(APP_TITLE);
|
||||
this->setIconFromRes("img/" APP_TITLE ".jpg");
|
||||
|
||||
/* Check if we're running under applet mode. */
|
||||
this->applet_mode = utilsAppletModeCheck();
|
||||
|
||||
/* Create labels. */
|
||||
this->applet_mode_lbl = new brls::Label();
|
||||
this->applet_mode_lbl->setText("root_view/applet_mode"_i18n);
|
||||
this->applet_mode_lbl->setFontSize(22.0f);
|
||||
this->applet_mode_lbl->setTextColor(nvgRGB(255, 0, 0));
|
||||
this->applet_mode_lbl->setSingleLine(true);
|
||||
this->applet_mode_lbl->setParent(this);
|
||||
|
||||
this->time_lbl = new brls::Label();
|
||||
this->time_lbl->setFontSize(16.0f);
|
||||
this->time_lbl->setSingleLine(true);
|
||||
this->time_lbl->setParent(this);
|
||||
|
||||
this->battery_icon = new brls::Label();
|
||||
this->battery_icon->setFontSize(16.0f);
|
||||
this->battery_icon->setSingleLine(true);
|
||||
this->battery_icon->setParent(this);
|
||||
|
||||
this->battery_percentage = new brls::Label();
|
||||
this->battery_percentage->setFontSize(16.0f);
|
||||
this->battery_percentage->setSingleLine(true);
|
||||
this->battery_percentage->setParent(this);
|
||||
|
||||
this->connection_icon = new brls::Label();
|
||||
this->connection_icon->setFontSize(16.0f);
|
||||
this->connection_icon->setSingleLine(true);
|
||||
this->connection_icon->setParent(this);
|
||||
|
||||
this->connection_status_lbl = new brls::Label();
|
||||
this->connection_status_lbl->setFontSize(16.0f);
|
||||
this->connection_status_lbl->setSingleLine(true);
|
||||
this->connection_status_lbl->setParent(this);
|
||||
|
||||
/* Add tabs. */
|
||||
this->addTab("root_view/tabs/gamecard"_i18n, [this](void){ return new brls::Rectangle(nvgRGB(255, 0, 0));/*return new GameCardTab(this->gc_status_task);*/ });
|
||||
this->addSeparator();
|
||||
this->addTab("root_view/tabs/user_titles"_i18n, [this](void){ return new brls::Rectangle(nvgRGB(0, 255, 0));/*return new UserTitlesTab(this->title_task);*/ });
|
||||
this->addTab("root_view/tabs/system_titles"_i18n, [this](void){ return new brls::Rectangle(nvgRGB(0, 0, 255)); });
|
||||
this->addSeparator();
|
||||
this->addTab("root_view/tabs/options"_i18n, [this](void){ return new brls::Rectangle(nvgRGB(255, 255, 0)); });
|
||||
this->addSeparator();
|
||||
this->addTab("root_view/tabs/about"_i18n, [this](void){ return new brls::Rectangle(nvgRGB(0, 255, 255));/*return new AboutTab();*/ });
|
||||
|
||||
/* Start background tasks. */
|
||||
this->status_info_task = new nxdt::tasks::StatusInfoTask();
|
||||
this->gc_status_task = new nxdt::tasks::GameCardTask();
|
||||
this->title_task = new nxdt::tasks::TitleTask();
|
||||
this->ums_task = new nxdt::tasks::UmsTask();
|
||||
this->usb_host_task = new nxdt::tasks::UsbHostTask();
|
||||
|
||||
/* Subscribe to status info event. */
|
||||
this->status_info_task_sub = this->status_info_task->RegisterListener([this](const nxdt::tasks::StatusInfoData *status_info_data) {
|
||||
/* Update time label. */
|
||||
bool is_am = true;
|
||||
struct tm *timeinfo = status_info_data->timeinfo;
|
||||
|
||||
timeinfo->tm_mon++;
|
||||
timeinfo->tm_year += 1900;
|
||||
|
||||
if ("root_view/time_format"_i18n.compare("12") == 0)
|
||||
{
|
||||
/* Adjust time for 12-hour clock. */
|
||||
if (timeinfo->tm_hour > 12)
|
||||
{
|
||||
timeinfo->tm_hour -= 12;
|
||||
is_am = false;
|
||||
} else
|
||||
if (!timeinfo->tm_hour)
|
||||
{
|
||||
timeinfo->tm_hour = 12;
|
||||
}
|
||||
}
|
||||
|
||||
this->time_lbl->setText(brls::getStr("root_view/date"_i18n, timeinfo->tm_year, timeinfo->tm_mon, timeinfo->tm_mday, timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec, \
|
||||
is_am ? "AM" : "PM"));
|
||||
|
||||
/* Update battery labels. */
|
||||
u32 charge_percentage = status_info_data->charge_percentage;
|
||||
PsmChargerType charger_type = status_info_data->charger_type;
|
||||
|
||||
this->battery_icon->setText(charger_type != PsmChargerType_Unconnected ? "\uE1A3" : (charge_percentage <= 15 ? "\uE19C" : "\uE1A4"));
|
||||
this->battery_icon->setTextColor(charger_type != PsmChargerType_Unconnected ? nvgRGB(0, 255, 0) : (charge_percentage <= 15 ? nvgRGB(255, 0, 0) : brls::Application::getTheme()["brls/text"]));
|
||||
|
||||
this->battery_percentage->setText(fmt::format("{}%", charge_percentage));
|
||||
|
||||
/* Update network label. */
|
||||
NifmInternetConnectionType connection_type = status_info_data->connection_type;
|
||||
char *ip_addr = status_info_data->ip_addr;
|
||||
|
||||
this->connection_icon->setText(!connection_type ? "\uE195" : (connection_type == NifmInternetConnectionType_WiFi ? "\uE63E" : "\uE8BE"));
|
||||
this->connection_status_lbl->setText(ip_addr ? std::string(ip_addr) : "root_view/not_connected"_i18n);
|
||||
|
||||
/* Update layout. */
|
||||
this->invalidate();
|
||||
});
|
||||
}
|
||||
|
||||
RootView::~RootView(void)
|
||||
{
|
||||
/* Unregister status info task listener. */
|
||||
this->status_info_task->UnregisterListener(this->status_info_task_sub);
|
||||
|
||||
/* Stop background tasks. */
|
||||
this->gc_status_task->stop();
|
||||
this->title_task->stop();
|
||||
this->ums_task->stop();
|
||||
this->usb_host_task->stop();
|
||||
|
||||
/* Destroy labels. */
|
||||
delete this->applet_mode_lbl;
|
||||
delete this->time_lbl;
|
||||
delete this->battery_icon;
|
||||
delete this->battery_percentage;
|
||||
delete this->connection_icon;
|
||||
delete this->connection_status_lbl;
|
||||
}
|
||||
|
||||
void RootView::draw(NVGcontext* vg, float x, float y, float width, float height, brls::Style style, brls::FrameContext* ctx)
|
||||
{
|
||||
brls::AppletFrame::draw(vg, x, y, width, height, style, ctx);
|
||||
|
||||
if (this->applet_mode) this->applet_mode_lbl->frame(ctx);
|
||||
|
||||
this->time_lbl->frame(ctx);
|
||||
|
||||
this->battery_icon->frame(ctx);
|
||||
this->battery_percentage->frame(ctx);
|
||||
|
||||
this->connection_icon->frame(ctx);
|
||||
this->connection_status_lbl->frame(ctx);
|
||||
}
|
||||
|
||||
void RootView::onLayout(void)
|
||||
{
|
||||
brls::AppletFrame::onLayout();
|
||||
|
||||
float y_pos = 0;
|
||||
brls::Style style = brls::Application::getStyle();
|
||||
|
||||
if (this->applet_mode)
|
||||
{
|
||||
/* Applet mode label. */
|
||||
this->applet_mode_lbl->invalidate();
|
||||
this->applet_mode_lbl->setPositionLeft((this->getWidth() / 4.0f) - (this->applet_mode_lbl->getWidth() / 2.0f));
|
||||
this->applet_mode_lbl->setPositionBottom(-(style["brls/applet_frame/footer_height"] / 2.0f));
|
||||
}
|
||||
|
||||
/* Time label. */
|
||||
this->time_lbl->invalidate();
|
||||
y_pos += (this->getY() + 25.0f + this->time_lbl->getLineHeight());
|
||||
|
||||
this->time_lbl->setPositionTop(y_pos);
|
||||
this->time_lbl->setPositionRight(-style["brls/applet_frame/header_padding_sides"]);
|
||||
|
||||
/* Battery stats labels. */
|
||||
this->battery_icon->invalidate();
|
||||
this->battery_percentage->invalidate();
|
||||
y_pos += (20.0f + this->battery_icon->getLineHeight());
|
||||
|
||||
this->battery_percentage->setPositionTop(y_pos);
|
||||
this->battery_percentage->setPositionRight(-style["brls/applet_frame/header_padding_sides"]);
|
||||
|
||||
this->battery_icon->setPositionTop(y_pos);
|
||||
this->battery_icon->setPositionRight(-(style["brls/applet_frame/header_padding_sides"] + this->battery_percentage->getWidth() + 5.0f));
|
||||
|
||||
/* Network connection labels. */
|
||||
this->connection_icon->invalidate();
|
||||
this->connection_status_lbl->invalidate();
|
||||
y_pos += (20.0f + this->connection_icon->getLineHeight());
|
||||
|
||||
this->connection_status_lbl->setPositionTop(y_pos);
|
||||
this->connection_status_lbl->setPositionRight(-style["brls/applet_frame/header_padding_sides"]);
|
||||
|
||||
this->connection_icon->setPositionTop(y_pos);
|
||||
this->connection_icon->setPositionRight(-(style["brls/applet_frame/header_padding_sides"] + this->connection_status_lbl->getWidth() + 5.0f));
|
||||
}
|
||||
}
|
|
@ -23,16 +23,13 @@
|
|||
#include <tasks.hpp>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#define NXDT_TASK_INTERVAL 100 /* 100 ms. */
|
||||
|
||||
namespace i18n = brls::i18n; /* For getStr(). */
|
||||
using namespace i18n::literals; /* For _i18n. */
|
||||
#define NXDT_TASK_INTERVAL 250 /* 250 ms. */
|
||||
|
||||
namespace nxdt::tasks
|
||||
{
|
||||
/* Status info task. */
|
||||
|
||||
StatusInfoTask::StatusInfoTask(void) : brls::RepeatingTask(1000)
|
||||
StatusInfoTask::StatusInfoTask(void) : brls::RepeatingTask(NXDT_TASK_INTERVAL)
|
||||
{
|
||||
brls::RepeatingTask::start();
|
||||
brls::Logger::debug("Status info task started.");
|
||||
|
@ -40,82 +37,42 @@ namespace nxdt::tasks
|
|||
|
||||
StatusInfoTask::~StatusInfoTask(void)
|
||||
{
|
||||
/* Clear current time string. */
|
||||
this->cur_time.clear();
|
||||
|
||||
brls::Logger::debug("Status info task stopped.");
|
||||
}
|
||||
|
||||
void StatusInfoTask::run(retro_time_t current_time)
|
||||
void StatusInfoTask::run(void)
|
||||
{
|
||||
brls::RepeatingTask::run(current_time);
|
||||
StatusInfoData *status_info_data = &(this->status_info_data);
|
||||
|
||||
/* Get current time. */
|
||||
bool is_am = true;
|
||||
time_t unix_time = time(NULL);
|
||||
struct tm *timeinfo = localtime(&unix_time);
|
||||
|
||||
if (timeinfo->tm_hour > 12)
|
||||
{
|
||||
timeinfo->tm_hour -= 12;
|
||||
is_am = false;
|
||||
} else
|
||||
if (!timeinfo->tm_hour)
|
||||
{
|
||||
timeinfo->tm_hour = 12;
|
||||
}
|
||||
|
||||
timeinfo->tm_mon++;
|
||||
timeinfo->tm_year += 1900;
|
||||
|
||||
this->cur_time.clear();
|
||||
this->cur_time = i18n::getStr("root_view/date"_i18n, timeinfo->tm_year, timeinfo->tm_mon, timeinfo->tm_mday, timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec, is_am ? "AM" : "PM");
|
||||
status_info_data->timeinfo = localtime(&unix_time);
|
||||
|
||||
/* Get battery stats. */
|
||||
psmGetBatteryChargePercentage(&(this->charge_percentage));
|
||||
psmGetChargerType(&(this->charger_type));
|
||||
psmGetBatteryChargePercentage(&(status_info_data->charge_percentage));
|
||||
psmGetChargerType(&(status_info_data->charger_type));
|
||||
|
||||
/* Get network connection status. */
|
||||
Result rc = nifmGetInternetConnectionStatus(&(this->connection_type), &(this->signal_strength), &(this->connection_status));
|
||||
u32 signal_strength = 0;
|
||||
NifmInternetConnectionStatus connection_status = (NifmInternetConnectionStatus)0;
|
||||
|
||||
Result rc = nifmGetInternetConnectionStatus(&(status_info_data->connection_type), &signal_strength, &connection_status);
|
||||
if (R_SUCCEEDED(rc))
|
||||
{
|
||||
if (this->connection_type && this->connection_status == NifmInternetConnectionStatus_Connected)
|
||||
if (status_info_data->connection_type && connection_status == NifmInternetConnectionStatus_Connected)
|
||||
{
|
||||
struct in_addr addr = { .s_addr = 0 };
|
||||
nifmGetCurrentIpAddress(&(addr.s_addr));
|
||||
this->ip_addr = inet_ntoa(addr);
|
||||
status_info_data->ip_addr = inet_ntoa(addr);
|
||||
} else {
|
||||
this->ip_addr = NULL;
|
||||
status_info_data->ip_addr = NULL;
|
||||
}
|
||||
} else {
|
||||
this->connection_type = (NifmInternetConnectionType)0;
|
||||
this->signal_strength = 0;
|
||||
this->connection_status = (NifmInternetConnectionStatus)0;
|
||||
this->ip_addr = NULL;
|
||||
status_info_data->connection_type = (NifmInternetConnectionType)0;
|
||||
status_info_data->ip_addr = NULL;
|
||||
}
|
||||
|
||||
this->status_info_event.fire();
|
||||
}
|
||||
|
||||
std::string StatusInfoTask::GetCurrentTimeString(void)
|
||||
{
|
||||
return this->cur_time;
|
||||
}
|
||||
|
||||
void StatusInfoTask::GetBatteryStats(u32 *out_charge_percentage, PsmChargerType *out_charger_type)
|
||||
{
|
||||
if (!out_charge_percentage || !out_charger_type) return;
|
||||
*out_charge_percentage = this->charge_percentage;
|
||||
*out_charger_type = this->charger_type;
|
||||
}
|
||||
|
||||
void StatusInfoTask::GetNetworkStats(NifmInternetConnectionType *out_connection_type, u32 *out_signal_strength, NifmInternetConnectionStatus *out_connection_status, char **out_ip_addr)
|
||||
{
|
||||
if (!out_connection_type || !out_signal_strength || !out_connection_status || !out_ip_addr) return;
|
||||
*out_connection_type = this->connection_type;
|
||||
*out_signal_strength = this->signal_strength;
|
||||
*out_connection_status = this->connection_status;
|
||||
*out_ip_addr = this->ip_addr;
|
||||
this->status_info_event.fire(status_info_data);
|
||||
}
|
||||
|
||||
/* Gamecard task. */
|
||||
|
@ -131,10 +88,8 @@ namespace nxdt::tasks
|
|||
brls::Logger::debug("Gamecard task stopped.");
|
||||
}
|
||||
|
||||
void GameCardTask::run(retro_time_t current_time)
|
||||
void GameCardTask::run(void)
|
||||
{
|
||||
brls::RepeatingTask::run(current_time);
|
||||
|
||||
this->cur_gc_status = (GameCardStatus)gamecardGetStatus();
|
||||
if (this->cur_gc_status != this->prev_gc_status)
|
||||
{
|
||||
|
@ -168,39 +123,15 @@ namespace nxdt::tasks
|
|||
brls::Logger::debug("Title task stopped.");
|
||||
}
|
||||
|
||||
void TitleTask::PopulateApplicationMetadataVector(bool is_system)
|
||||
void TitleTask::run(void)
|
||||
{
|
||||
TitleApplicationMetadata **app_metadata = NULL;
|
||||
u32 app_metadata_count = 0;
|
||||
|
||||
/* Get pointer to output vector. */
|
||||
TitleApplicationMetadataVector *vector = (is_system ? &(this->system_metadata) : &(this->user_metadata));
|
||||
if (vector->size()) vector->clear();
|
||||
|
||||
/* Get application metadata entries. */
|
||||
app_metadata = titleGetApplicationMetadataEntries(is_system, &app_metadata_count);
|
||||
if (!app_metadata) return;
|
||||
|
||||
/* Fill output vector. */
|
||||
for(u32 i = 0; i < app_metadata_count; i++) vector->push_back(app_metadata[i]);
|
||||
|
||||
/* Free application metadata array. */
|
||||
free(app_metadata);
|
||||
|
||||
brls::Logger::debug("Retrieved {} {} metadata {}.", app_metadata_count, is_system ? "system" : "user", app_metadata_count == 1 ? "entry" : "entries");
|
||||
}
|
||||
|
||||
void TitleTask::run(retro_time_t current_time)
|
||||
{
|
||||
brls::RepeatingTask::run(current_time);
|
||||
|
||||
if (titleIsGameCardInfoUpdated())
|
||||
{
|
||||
/* Update user metadata vector. */
|
||||
this->PopulateApplicationMetadataVector(false);
|
||||
|
||||
/* Fire task event. */
|
||||
this->title_event.fire();
|
||||
this->title_event.fire(&(this->user_metadata));
|
||||
brls::Logger::debug("Title info updated.");
|
||||
}
|
||||
}
|
||||
|
@ -210,6 +141,29 @@ namespace nxdt::tasks
|
|||
return (is_system ? &(this->system_metadata) : &(this->user_metadata));
|
||||
}
|
||||
|
||||
void TitleTask::PopulateApplicationMetadataVector(bool is_system)
|
||||
{
|
||||
TitleApplicationMetadata **app_metadata = NULL;
|
||||
u32 app_metadata_count = 0;
|
||||
|
||||
/* Get pointer to output vector. */
|
||||
TitleApplicationMetadataVector *vector = (is_system ? &(this->system_metadata) : &(this->user_metadata));
|
||||
vector->clear();
|
||||
|
||||
/* Get application metadata entries. */
|
||||
app_metadata = titleGetApplicationMetadataEntries(is_system, &app_metadata_count);
|
||||
if (app_metadata)
|
||||
{
|
||||
/* Fill output vector. */
|
||||
for(u32 i = 0; i < app_metadata_count; i++) vector->push_back(app_metadata[i]);
|
||||
|
||||
/* Free application metadata array. */
|
||||
free(app_metadata);
|
||||
}
|
||||
|
||||
brls::Logger::debug("Retrieved {} {} metadata {}.", app_metadata_count, is_system ? "system" : "user", app_metadata_count == 1 ? "entry" : "entries");
|
||||
}
|
||||
|
||||
/* USB Mass Storage task. */
|
||||
|
||||
UmsTask::UmsTask(void) : brls::RepeatingTask(NXDT_TASK_INTERVAL)
|
||||
|
@ -226,45 +180,39 @@ namespace nxdt::tasks
|
|||
brls::Logger::debug("UMS task stopped.");
|
||||
}
|
||||
|
||||
void UmsTask::PopulateUmsDeviceVector(void)
|
||||
void UmsTask::run(void)
|
||||
{
|
||||
UsbHsFsDevice *ums_devices = NULL;
|
||||
u32 ums_device_count = 0;
|
||||
|
||||
/* Clear UMS device vector (if needed). */
|
||||
if (this->ums_devices.size()) this->ums_devices.clear();
|
||||
|
||||
/* Get UMS devices. */
|
||||
ums_devices = umsGetDevices(&ums_device_count);
|
||||
if (!ums_devices) return;
|
||||
|
||||
/* Fill UMS device vector. */
|
||||
for(u32 i = 0; i < ums_device_count; i++) this->ums_devices.push_back(ums_devices[i]);
|
||||
|
||||
/* Free UMS devices array. */
|
||||
free(ums_devices);
|
||||
|
||||
brls::Logger::debug("Retrieved info for {} UMS {}.", ums_device_count, ums_device_count == 1 ? "device" : "devices");
|
||||
}
|
||||
|
||||
void UmsTask::run(retro_time_t current_time)
|
||||
{
|
||||
brls::RepeatingTask::run(current_time);
|
||||
|
||||
if (umsIsDeviceInfoUpdated())
|
||||
{
|
||||
/* Update UMS device vector. */
|
||||
this->PopulateUmsDeviceVector();
|
||||
|
||||
/* Fire task event. */
|
||||
this->ums_event.fire();
|
||||
this->ums_event.fire(&(this->ums_devices));
|
||||
brls::Logger::debug("UMS device info updated.");
|
||||
}
|
||||
}
|
||||
|
||||
UmsDeviceVector* UmsTask::GetUmsDevices(void)
|
||||
void UmsTask::PopulateUmsDeviceVector(void)
|
||||
{
|
||||
return &(this->ums_devices);
|
||||
UsbHsFsDevice *ums_devices = NULL;
|
||||
u32 ums_device_count = 0;
|
||||
|
||||
/* Clear UMS device vector. */
|
||||
this->ums_devices.clear();
|
||||
|
||||
/* Get UMS devices. */
|
||||
ums_devices = umsGetDevices(&ums_device_count);
|
||||
if (ums_devices)
|
||||
{
|
||||
/* Fill UMS device vector. */
|
||||
for(u32 i = 0; i < ums_device_count; i++) this->ums_devices.push_back(ums_devices[i]);
|
||||
|
||||
/* Free UMS devices array. */
|
||||
free(ums_devices);
|
||||
}
|
||||
|
||||
brls::Logger::debug("Retrieved info for {} UMS {}.", ums_device_count, ums_device_count == 1 ? "device" : "devices");
|
||||
}
|
||||
|
||||
/* USB host device connection task. */
|
||||
|
@ -280,15 +228,13 @@ namespace nxdt::tasks
|
|||
brls::Logger::debug("USB host task stopped.");
|
||||
}
|
||||
|
||||
void UsbHostTask::run(retro_time_t current_time)
|
||||
void UsbHostTask::run(void)
|
||||
{
|
||||
brls::RepeatingTask::run(current_time);
|
||||
|
||||
this->cur_usb_host_status = usbIsReady();
|
||||
if (this->cur_usb_host_status != this->prev_usb_host_status)
|
||||
{
|
||||
this->usb_host_event.fire(this->cur_usb_host_status);
|
||||
this->prev_usb_host_status = this->cur_usb_host_status;
|
||||
this->usb_host_event.fire(this->cur_usb_host_status);
|
||||
brls::Logger::debug("USB host status change triggered: {}.", this->cur_usb_host_status);
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue