Add new quick menu, controller applet...

This commit is contained in:
XorTroll 2019-11-16 18:34:45 +01:00
parent 71b7d03b41
commit 3a9049927c
16 changed files with 377 additions and 17 deletions

29
CurrentChangelog.md Normal file
View 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)

View file

@ -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;

View 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;
};
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6 KiB

View file

@ -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));

View file

@ -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)

View file

@ -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()

View 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

View file

@ -449,9 +449,9 @@ namespace qdaemon
while(true)
{
appletUpdateLastForegroundCaptureImage();
bool flag;
appletGetLastForegroundCaptureImageEx(usbbuf, RawRGBAScreenBufferSize, &flag);
appletUpdateLastForegroundCaptureImage();
usbCommsWrite(usbbuf, RawRGBAScreenBufferSize);
}