Add new quick menu, controller applet...
29
CurrentChangelog.md
Normal file
|
@ -0,0 +1,29 @@
|
|||
# Changelog
|
||||
|
||||
- Settings menu
|
||||
|
||||
- New settings were added:
|
||||
|
||||
- Console information upload (enable/disable)
|
||||
|
||||
- Automatic titles' download (e/d)
|
||||
|
||||
- Console auto-update (e/d)
|
||||
|
||||
- Bluetooth (e/d)
|
||||
|
||||
- 3.0 USB (e/d)
|
||||
|
||||
- NFC (e/d)
|
||||
|
||||
- Wireless LAN (e/d)
|
||||
|
||||
- MAC address
|
||||
|
||||
- Serial number
|
||||
|
||||
- General
|
||||
|
||||
- Custom icons in entry JSONs can now be used with normal titles too, not just homebrew.
|
||||
|
||||
- Certain parts of the code/functionality were slightly improved (speed might be slightly faster in certain laggy moments)
|
|
@ -5,6 +5,7 @@
|
|||
#include <ui/ui_SideMenu.hpp>
|
||||
#include <ui/ui_RawData.hpp>
|
||||
#include <ui/ui_ClickableImage.hpp>
|
||||
#include <ui/ui_QuickMenu.hpp>
|
||||
#include <cfg/cfg_Config.hpp>
|
||||
|
||||
namespace ui
|
||||
|
@ -33,6 +34,8 @@ namespace ui
|
|||
void HandleWebPageOpen();
|
||||
void HandleSettingsMenu();
|
||||
void HandleThemesMenu();
|
||||
void HandleControllerAppletOpen();
|
||||
void HandleShowHelp();
|
||||
void HandleMultiselectMoveToFolder(std::string folder);
|
||||
void StopMultiselect();
|
||||
private:
|
||||
|
@ -58,6 +61,7 @@ namespace ui
|
|||
pu::ui::elm::TextBlock::Ref itemVersion;
|
||||
pu::ui::elm::Image::Ref bannerImage;
|
||||
ClickableImage::Ref menuToggle;
|
||||
QuickMenu::Ref quickMenu;
|
||||
std::string curfolder;
|
||||
std::chrono::steady_clock::time_point tp;
|
||||
bool warnshown;
|
||||
|
|
65
LibraryAppletQMenu/Include/ui/ui_QuickMenu.hpp
Normal file
|
@ -0,0 +1,65 @@
|
|||
|
||||
#pragma once
|
||||
#include <q_Include.hpp>
|
||||
#include <pu/Plutonium>
|
||||
|
||||
namespace ui
|
||||
{
|
||||
enum class QuickMenuDirection
|
||||
{
|
||||
Up,
|
||||
Down,
|
||||
Left,
|
||||
Right,
|
||||
UpLeft,
|
||||
UpRight,
|
||||
DownLeft,
|
||||
DownRight,
|
||||
None
|
||||
};
|
||||
|
||||
struct QuickMenuSubItem
|
||||
{
|
||||
std::function<void()> on_select;
|
||||
pu::ui::render::NativeTexture nicon;
|
||||
};
|
||||
|
||||
class QuickMenu : public pu::ui::elm::Element
|
||||
{
|
||||
static constexpr s32 MainItemSize = 300;
|
||||
static constexpr s32 SubItemsSize = 150;
|
||||
static constexpr s32 CommonAreaSize = 50;
|
||||
|
||||
static constexpr s32 MainItemX = (1280 - MainItemSize) / 2;
|
||||
static constexpr s32 MainItemY = (720 - MainItemSize) / 2;
|
||||
|
||||
public:
|
||||
QuickMenu(std::string main_icon);
|
||||
PU_SMART_CTOR(QuickMenu)
|
||||
~QuickMenu();
|
||||
|
||||
void SetEntry(QuickMenuDirection direction, std::string icon, std::function<void()> on_selected);
|
||||
void RemoveEntry(QuickMenuDirection direction);
|
||||
|
||||
s32 GetX();
|
||||
s32 GetY();
|
||||
s32 GetWidth();
|
||||
s32 GetHeight();
|
||||
|
||||
bool IsOn();
|
||||
|
||||
void OnRender(pu::ui::render::Renderer::Ref &Drawer, s32 X, s32 Y);
|
||||
void OnInput(u64 Down, u64 Up, u64 Held, pu::ui::Touch Pos);
|
||||
|
||||
private:
|
||||
QuickMenuDirection GetCurrentDirection();
|
||||
std::tuple<s32, s32> ComputePositionForDirection(QuickMenuDirection direction);
|
||||
bool on;
|
||||
s64 off_wait;
|
||||
pu::ui::render::NativeTexture nmain;
|
||||
u64 lastheld;
|
||||
s32 bgalpha;
|
||||
s32 fgalpha;
|
||||
std::map<QuickMenuDirection, QuickMenuSubItem> item_map;
|
||||
};
|
||||
}
|
BIN
LibraryAppletQMenu/RomFs/default/ui/QuickMenuControllerItem.png
Normal file
After Width: | Height: | Size: 4.7 KiB |
BIN
LibraryAppletQMenu/RomFs/default/ui/QuickMenuHelpItem.png
Normal file
After Width: | Height: | Size: 3.9 KiB |
BIN
LibraryAppletQMenu/RomFs/default/ui/QuickMenuMain.png
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
LibraryAppletQMenu/RomFs/default/ui/QuickMenuSettingsItem.png
Normal file
After Width: | Height: | Size: 4.4 KiB |
BIN
LibraryAppletQMenu/RomFs/default/ui/QuickMenuThemesItem.png
Normal file
After Width: | Height: | Size: 5.1 KiB |
BIN
LibraryAppletQMenu/RomFs/default/ui/QuickMenuWebItem.png
Normal file
After Width: | Height: | Size: 6 KiB |
|
@ -65,6 +65,7 @@ int main()
|
|||
if(R_SUCCEEDED(rc))
|
||||
{
|
||||
am::QDaemonStatus status = {};
|
||||
|
||||
// Information block sent as an extra storage to QMenu.
|
||||
am::QLibraryAppletReadStorage(&status, sizeof(status));
|
||||
|
||||
|
|
|
@ -122,6 +122,17 @@ namespace ui
|
|||
this->itemsMenu->SetOnSelectionChanged(std::bind(&MenuLayout::menu_OnSelected, this, std::placeholders::_1));
|
||||
qapp->ApplyConfigForElement("main_menu", "items_menu", this->itemsMenu, false); // Main menu must be visible, and only Y is customizable here
|
||||
this->Add(this->itemsMenu);
|
||||
|
||||
this->quickMenu = QuickMenu::New(cfg::ProcessedThemeResource(theme, "ui/QuickMenuMain.png"));
|
||||
|
||||
this->quickMenu->SetEntry(QuickMenuDirection::Down, cfg::ProcessedThemeResource(theme, "ui/QuickMenuSettingsItem.png"), std::bind(&MenuLayout::settings_Click, this));
|
||||
this->quickMenu->SetEntry(QuickMenuDirection::Left, cfg::ProcessedThemeResource(theme, "ui/QuickMenuWebItem.png"), std::bind(&MenuLayout::web_Click, this));
|
||||
this->quickMenu->SetEntry(QuickMenuDirection::Right, cfg::ProcessedThemeResource(theme, "ui/QuickMenuThemesItem.png"), std::bind(&MenuLayout::themes_Click, this));
|
||||
this->quickMenu->SetEntry(QuickMenuDirection::UpLeft, cfg::ProcessedThemeResource(theme, "ui/QuickMenuControllerItem.png"), std::bind(&MenuLayout::HandleControllerAppletOpen, this));
|
||||
this->quickMenu->SetEntry(QuickMenuDirection::DownRight, cfg::ProcessedThemeResource(theme, "ui/QuickMenuHelpItem.png"), std::bind(&MenuLayout::HandleShowHelp, this));
|
||||
|
||||
this->Add(this->quickMenu);
|
||||
|
||||
this->tp = std::chrono::steady_clock::now();
|
||||
|
||||
this->sfxTitleLaunch = pu::audio::Load(cfg::ProcessedThemeResource(theme, "sound/TitleLaunch.wav"));
|
||||
|
@ -711,15 +722,13 @@ namespace ui
|
|||
}
|
||||
else if(down & KEY_PLUS) this->logo_Click();
|
||||
else if(down & KEY_MINUS) this->menuToggle_Click();
|
||||
else if(down & KEY_ZL) this->HandleUserMenu();
|
||||
else if(down & KEY_L) this->HandleWebPageOpen();
|
||||
else if(down & KEY_R) this->HandleSettingsMenu();
|
||||
else if(down & KEY_ZR) this->HandleThemesMenu();
|
||||
}
|
||||
|
||||
void MenuLayout::SetUser(u128 user)
|
||||
{
|
||||
this->users->SetImage(os::GetIconCacheImagePath(user));
|
||||
auto path = os::GetIconCacheImagePath(user);
|
||||
this->users->SetImage(path);
|
||||
this->quickMenu->SetEntry(QuickMenuDirection::Up, path, std::bind(&MenuLayout::users_Click, this));
|
||||
this->users->SetWidth(50);
|
||||
this->users->SetHeight(50);
|
||||
}
|
||||
|
@ -739,7 +748,7 @@ namespace ui
|
|||
void MenuLayout::logo_Click()
|
||||
{
|
||||
qapp->CreateShowDialog(cfg::GetLanguageString(config.main_lang, config.default_lang, "ulaunch_about"), "uLaunch v" + std::string(Q_VERSION) + "\n\n" + cfg::GetLanguageString(config.main_lang, config.default_lang, "ulaunch_desc") + "\n\n" + cfg::GetLanguageString(config.main_lang, config.default_lang, "ulaunch_contribute") + ":\nhttps://github.com/XorTroll/uLaunch", { cfg::GetLanguageString(config.main_lang, config.default_lang, "ok") }, true, "romfs:/LogoLarge.png");
|
||||
qapp->ShowNotification("(-) -> " + cfg::GetLanguageString(config.main_lang, config.default_lang, "control_minus") + " | (X) -> " + cfg::GetLanguageString(config.main_lang, config.default_lang, "control_x") + " | (Y) -> " + cfg::GetLanguageString(config.main_lang, config.default_lang, "control_y") + " | (L), (R), (ZL), (ZR) -> " + cfg::GetLanguageString(config.main_lang, config.default_lang, "control_zlr"), 3500);
|
||||
// qapp->ShowNotification("(-) -> " + cfg::GetLanguageString(config.main_lang, config.default_lang, "control_minus") + " | (X) -> " + cfg::GetLanguageString(config.main_lang, config.default_lang, "control_x") + " | (Y) -> " + cfg::GetLanguageString(config.main_lang, config.default_lang, "control_y") + " | (L), (R), (ZL), (ZR) -> " + cfg::GetLanguageString(config.main_lang, config.default_lang, "control_zlr"), 3500);
|
||||
}
|
||||
|
||||
void MenuLayout::settings_Click()
|
||||
|
@ -1036,6 +1045,42 @@ namespace ui
|
|||
qapp->FadeIn();
|
||||
}
|
||||
|
||||
void MenuLayout::HandleControllerAppletOpen()
|
||||
{
|
||||
am::controller::InitialArg arg1 = {};
|
||||
HidControllerType type;
|
||||
hidGetSupportedNpadStyleSet(&type);
|
||||
arg1.controller_type = (u64)type;
|
||||
arg1.this_size = sizeof(arg1);
|
||||
arg1.unk2 = true;
|
||||
arg1.unk3 = true;
|
||||
|
||||
am::controller::MainArg arg2 = {};
|
||||
arg2.min_player_count = 0;
|
||||
arg2.max_player_count = 4;
|
||||
arg2.take_over_connection = true;
|
||||
arg2.left_justify = true;
|
||||
|
||||
am::LibraryAppletQMenuLaunchWith(AppletId_controller, 0,
|
||||
[&](AppletHolder *h)
|
||||
{
|
||||
libappletPushInData(h, &arg1, sizeof(arg1));
|
||||
libappletPushInData(h, &arg2, sizeof(arg2));
|
||||
},
|
||||
[&](AppletHolder *h)
|
||||
{
|
||||
},
|
||||
[&]() -> bool
|
||||
{
|
||||
return !am::QMenuIsHomePressed();
|
||||
});
|
||||
}
|
||||
|
||||
void MenuLayout::HandleShowHelp()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void MenuLayout::HandleMultiselectMoveToFolder(std::string folder)
|
||||
{
|
||||
if(this->select_on)
|
||||
|
|
|
@ -43,18 +43,13 @@ namespace ui
|
|||
|
||||
switch(this->stmode)
|
||||
{
|
||||
case am::QMenuStartMode::Menu:
|
||||
case am::QMenuStartMode::MenuApplicationSuspended:
|
||||
case am::QMenuStartMode::MenuLaunchFailure:
|
||||
{
|
||||
// Returned from applet/title
|
||||
case am::QMenuStartMode::StartupScreen:
|
||||
this->LoadStartupMenu();
|
||||
break;
|
||||
default:
|
||||
this->StartPlayBGM();
|
||||
this->LoadMenu();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
this->LoadStartupMenu();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -159,7 +154,7 @@ namespace ui
|
|||
writer.Write<u128>(user_id);
|
||||
writer.FinishWrite();
|
||||
|
||||
this->status.selected_user = user_id;
|
||||
memcpy(&this->status.selected_user, &user_id, sizeof(user_id));
|
||||
}
|
||||
|
||||
u128 QMenuApplication::GetSelectedUser()
|
||||
|
|
221
LibraryAppletQMenu/Source/ui/ui_QuickMenu.cpp
Normal file
|
@ -0,0 +1,221 @@
|
|||
#include <ui/ui_QuickMenu.hpp>
|
||||
|
||||
namespace ui
|
||||
{
|
||||
QuickMenu::QuickMenu(std::string main_icon)
|
||||
{
|
||||
this->on = false;
|
||||
this->lastheld = 0;
|
||||
this->nmain = pu::ui::render::LoadImage(main_icon);
|
||||
this->bgalpha = 0;
|
||||
this->fgalpha = 0;
|
||||
this->off_wait = -1;
|
||||
}
|
||||
|
||||
QuickMenu::~QuickMenu()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void QuickMenu::SetEntry(QuickMenuDirection direction, std::string icon, std::function<void()> on_selected)
|
||||
{
|
||||
this->RemoveEntry(direction);
|
||||
|
||||
this->item_map[direction] = { on_selected, pu::ui::render::LoadImage(icon) };
|
||||
}
|
||||
|
||||
void QuickMenu::RemoveEntry(QuickMenuDirection direction)
|
||||
{
|
||||
if(this->item_map.count(direction)) this->item_map.erase(direction);
|
||||
}
|
||||
|
||||
s32 QuickMenu::GetX()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
s32 QuickMenu::GetY()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
s32 QuickMenu::GetWidth()
|
||||
{
|
||||
return 1280;
|
||||
}
|
||||
|
||||
s32 QuickMenu::GetHeight()
|
||||
{
|
||||
return 720;
|
||||
}
|
||||
|
||||
bool QuickMenu::IsOn()
|
||||
{
|
||||
return this->on;
|
||||
}
|
||||
|
||||
void QuickMenu::OnRender(pu::ui::render::Renderer::Ref &Drawer, s32 X, s32 Y)
|
||||
{
|
||||
if(!this->on)
|
||||
{
|
||||
if(this->off_wait >= 0)
|
||||
{
|
||||
if(bgalpha > 0)
|
||||
{
|
||||
bgalpha -= 20;
|
||||
if(bgalpha < 0) bgalpha = 0;
|
||||
}
|
||||
if(fgalpha > 0)
|
||||
{
|
||||
fgalpha -= 20;
|
||||
if(fgalpha < 0) fgalpha = 0;
|
||||
}
|
||||
}
|
||||
else return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(bgalpha < 220)
|
||||
{
|
||||
bgalpha += 20;
|
||||
if(bgalpha > 220) bgalpha = 220;
|
||||
}
|
||||
if(fgalpha < 255)
|
||||
{
|
||||
fgalpha += 20;
|
||||
if(fgalpha > 255) fgalpha = 255;
|
||||
}
|
||||
}
|
||||
|
||||
Drawer->RenderRectangleFill({ 50, 50, 50, bgalpha }, 0, 0, 1280, 720);
|
||||
|
||||
auto dir = this->GetCurrentDirection();
|
||||
Drawer->RenderTexture(this->nmain, MainItemX, MainItemY, { fgalpha, MainItemSize, MainItemSize, -1 });
|
||||
|
||||
for(auto &[direction, subitem]: this->item_map)
|
||||
{
|
||||
auto [x, y] = this->ComputePositionForDirection(direction);
|
||||
|
||||
auto tex = subitem.nicon;
|
||||
if(direction == dir) SDL_SetTextureColorMod(tex, 200, 200, 255);
|
||||
else SDL_SetTextureColorMod(tex, 255, 255, 255);
|
||||
|
||||
Drawer->RenderTexture(tex, x, y, { fgalpha, SubItemsSize, SubItemsSize, -1 });
|
||||
}
|
||||
}
|
||||
|
||||
void QuickMenu::OnInput(u64 Down, u64 Up, u64 Held, pu::ui::Touch Pos)
|
||||
{
|
||||
auto prevheld = this->lastheld;
|
||||
this->lastheld = Held;
|
||||
if(this->off_wait >= 0)
|
||||
{
|
||||
if((this->fgalpha == 0) && (this->bgalpha == 0))
|
||||
{
|
||||
this->lastheld = (u64)this->off_wait;
|
||||
auto dir = this->GetCurrentDirection();
|
||||
this->lastheld = Held;
|
||||
this->off_wait = -1;
|
||||
|
||||
if(this->item_map.count(dir))
|
||||
{
|
||||
auto itm = this->item_map[dir];
|
||||
(itm.on_select)();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
auto prevon = this->on;
|
||||
this->on = false;
|
||||
if(Held & KEY_LSTICK) this->on = true;
|
||||
if(Held & KEY_RSTICK) this->on = true;
|
||||
|
||||
if(prevon && !this->on) this->off_wait = prevheld;
|
||||
}
|
||||
}
|
||||
|
||||
QuickMenuDirection QuickMenu::GetCurrentDirection()
|
||||
{
|
||||
QuickMenuDirection dir = QuickMenuDirection::None;
|
||||
|
||||
if(this->lastheld & KEY_RSTICK)
|
||||
{
|
||||
if(this->lastheld & KEY_RSTICK_UP)
|
||||
{
|
||||
dir = QuickMenuDirection::Up;
|
||||
if(this->lastheld & KEY_RSTICK_LEFT) dir = QuickMenuDirection::UpLeft;
|
||||
else if(this->lastheld & KEY_RSTICK_RIGHT) dir = QuickMenuDirection::UpRight;
|
||||
}
|
||||
else if(this->lastheld & KEY_RSTICK_DOWN)
|
||||
{
|
||||
dir = QuickMenuDirection::Down;
|
||||
if(this->lastheld & KEY_RSTICK_LEFT) dir = QuickMenuDirection::DownLeft;
|
||||
else if(this->lastheld & KEY_RSTICK_RIGHT) dir = QuickMenuDirection::DownRight;
|
||||
}
|
||||
else if(this->lastheld & KEY_RSTICK_LEFT) dir = QuickMenuDirection::Left;
|
||||
else if(this->lastheld & KEY_RSTICK_RIGHT) dir = QuickMenuDirection::Right;
|
||||
}
|
||||
else if(this->lastheld & KEY_LSTICK)
|
||||
{
|
||||
if(this->lastheld & KEY_LSTICK_UP)
|
||||
{
|
||||
dir = QuickMenuDirection::Up;
|
||||
if(this->lastheld & KEY_LSTICK_LEFT) dir = QuickMenuDirection::UpLeft;
|
||||
else if(this->lastheld & KEY_LSTICK_RIGHT) dir = QuickMenuDirection::UpRight;
|
||||
}
|
||||
else if(this->lastheld & KEY_LSTICK_DOWN)
|
||||
{
|
||||
dir = QuickMenuDirection::Down;
|
||||
if(this->lastheld & KEY_LSTICK_LEFT) dir = QuickMenuDirection::DownLeft;
|
||||
else if(this->lastheld & KEY_LSTICK_RIGHT) dir = QuickMenuDirection::DownRight;
|
||||
}
|
||||
else if(this->lastheld & KEY_LSTICK_LEFT) dir = QuickMenuDirection::Left;
|
||||
else if(this->lastheld & KEY_LSTICK_RIGHT) dir = QuickMenuDirection::Right;
|
||||
}
|
||||
|
||||
return dir;
|
||||
}
|
||||
|
||||
std::tuple<s32, s32> QuickMenu::ComputePositionForDirection(QuickMenuDirection direction)
|
||||
{
|
||||
s32 x = MainItemX;
|
||||
s32 y = MainItemY;
|
||||
switch(direction)
|
||||
{
|
||||
case QuickMenuDirection::Up:
|
||||
x += ((MainItemSize - SubItemsSize) / 2);
|
||||
y -= SubItemsSize;
|
||||
break;
|
||||
case QuickMenuDirection::Down:
|
||||
x += ((MainItemSize - SubItemsSize) / 2);
|
||||
y += MainItemSize;
|
||||
break;
|
||||
case QuickMenuDirection::Left:
|
||||
x -= SubItemsSize;
|
||||
y += ((MainItemSize - SubItemsSize) / 2);
|
||||
break;
|
||||
case QuickMenuDirection::Right:
|
||||
x += MainItemSize;
|
||||
y += ((MainItemSize - SubItemsSize) / 2);
|
||||
break;
|
||||
case QuickMenuDirection::UpLeft:
|
||||
x -= (SubItemsSize - CommonAreaSize);
|
||||
y -= (SubItemsSize - CommonAreaSize);
|
||||
break;
|
||||
case QuickMenuDirection::UpRight:
|
||||
x += (MainItemSize - CommonAreaSize);
|
||||
y -= (SubItemsSize - CommonAreaSize);
|
||||
break;
|
||||
case QuickMenuDirection::DownLeft:
|
||||
x -= (SubItemsSize - CommonAreaSize);
|
||||
y += (MainItemSize - CommonAreaSize);
|
||||
break;
|
||||
case QuickMenuDirection::DownRight:
|
||||
x += (MainItemSize - CommonAreaSize);
|
||||
y += (MainItemSize - CommonAreaSize);
|
||||
break;
|
||||
}
|
||||
return std::make_tuple(x, y);
|
||||
}
|
||||
}
|
BIN
QForegroundViewer/Icon.ico
Normal file
After Width: | Height: | Size: 64 KiB |
BIN
QForegroundViewer/QForegroundViewer/Icon.ico
Normal file
After Width: | Height: | Size: 64 KiB |
|
@ -449,9 +449,9 @@ namespace qdaemon
|
|||
|
||||
while(true)
|
||||
{
|
||||
appletUpdateLastForegroundCaptureImage();
|
||||
bool flag;
|
||||
appletGetLastForegroundCaptureImageEx(usbbuf, RawRGBAScreenBufferSize, &flag);
|
||||
appletUpdateLastForegroundCaptureImage();
|
||||
usbCommsWrite(usbbuf, RawRGBAScreenBufferSize);
|
||||
}
|
||||
|
||||
|
|