mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2024-12-26 20:26:02 +00:00
272 lines
9.4 KiB
C++
272 lines
9.4 KiB
C++
/*
|
|
* Copyright (c) Adubbz
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify it
|
|
* under the terms and conditions of the GNU General Public License,
|
|
* version 2, as published by the Free Software Foundation.
|
|
*
|
|
* This program is distributed in the hope 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 <http://www.gnu.org/licenses/>.
|
|
*/
|
|
#pragma once
|
|
|
|
#include <array>
|
|
#include <memory>
|
|
#include <vector>
|
|
#include <optional>
|
|
#include <nanovg.h>
|
|
#include <switch.h>
|
|
#include "ams_su.h"
|
|
|
|
namespace dbk {
|
|
|
|
struct Button {
|
|
static constexpr u32 InvalidButtonId = -1;
|
|
|
|
u32 id;
|
|
bool selected;
|
|
bool enabled;
|
|
char text[256];
|
|
float x;
|
|
float y;
|
|
float w;
|
|
float h;
|
|
|
|
inline bool IsPositionInBounds(float x, float y) {
|
|
return x >= this->x && y >= this->y && x < (this->x + this->w) && y < (this->y + this->h);
|
|
}
|
|
};
|
|
|
|
enum class Direction {
|
|
Up,
|
|
Down,
|
|
Left,
|
|
Right,
|
|
Invalid,
|
|
};
|
|
|
|
class Menu {
|
|
protected:
|
|
static constexpr size_t MaxButtons = 32;
|
|
static constexpr size_t LogBufferSize = 0x1000;
|
|
protected:
|
|
std::array<std::optional<Button>, MaxButtons> m_buttons;
|
|
const std::shared_ptr<Menu> m_prev_menu;
|
|
char m_log_buffer[LogBufferSize];
|
|
protected:
|
|
void AddButton(u32 id, const char *text, float x, float y, float w, float h);
|
|
void SetButtonSelected(u32 id, bool selected);
|
|
void DeselectAllButtons();
|
|
void SetButtonEnabled(u32 id, bool enabled);
|
|
|
|
Button *GetButton(u32 id);
|
|
Button *GetSelectedButton();
|
|
Button *GetClosestButtonToSelection(Direction direction);
|
|
Button *GetTouchedButton();
|
|
Button *GetActivatedButton();
|
|
|
|
void UpdateButtons();
|
|
void DrawButtons(NVGcontext *vg, u64 ns);
|
|
|
|
void LogText(const char *format, ...);
|
|
public:
|
|
Menu(std::shared_ptr<Menu> prev_menu) : m_buttons({}), m_prev_menu(prev_menu), m_log_buffer{} { /* ... */ }
|
|
|
|
std::shared_ptr<Menu> GetPrevMenu();
|
|
virtual void Update(u64 ns) = 0;
|
|
virtual void Draw(NVGcontext *vg, u64 ns) = 0;
|
|
};
|
|
|
|
class AlertMenu : public Menu {
|
|
protected:
|
|
static constexpr float WindowWidth = 600.0f;
|
|
static constexpr float WindowHeight = 214.0f;
|
|
static constexpr float TitleGap = 90.0f;
|
|
static constexpr float SubTextHeight = 24.0f;
|
|
protected:
|
|
char m_text[0x100];
|
|
char m_subtext[0x100];
|
|
char m_result_text[0x20];
|
|
Result m_rc;
|
|
public:
|
|
AlertMenu(std::shared_ptr<Menu> prev_menu, const char *text, const char *subtext, Result rc = 0);
|
|
|
|
virtual void Draw(NVGcontext *vg, u64 ns) override;
|
|
};
|
|
|
|
class ErrorMenu : public AlertMenu {
|
|
private:
|
|
static constexpr u32 ExitButtonId = 0;
|
|
public:
|
|
ErrorMenu(const char *text, const char *subtext, Result rc = 0);
|
|
|
|
virtual void Update(u64 ns) override;
|
|
};
|
|
|
|
class WarningMenu : public AlertMenu {
|
|
private:
|
|
static constexpr u32 BackButtonId = 0;
|
|
static constexpr u32 ContinueButtonId = 1;
|
|
private:
|
|
const std::shared_ptr<Menu> m_next_menu;
|
|
public:
|
|
WarningMenu(std::shared_ptr<Menu> prev_menu, std::shared_ptr<Menu> next_menu, const char *text, const char *subtext, Result rc = 0);
|
|
|
|
virtual void Update(u64 ns) override;
|
|
};
|
|
|
|
class MainMenu : public Menu {
|
|
private:
|
|
static constexpr u32 InstallButtonId = 0;
|
|
static constexpr u32 ExitButtonId = 1;
|
|
|
|
static constexpr float WindowWidth = 400.0f;
|
|
static constexpr float WindowHeight = 240.0f;
|
|
static constexpr float TitleGap = 90.0f;
|
|
public:
|
|
MainMenu();
|
|
|
|
virtual void Update(u64 ns) override;
|
|
virtual void Draw(NVGcontext *vg, u64 ns) override;
|
|
};
|
|
|
|
class FileMenu : public Menu {
|
|
private:
|
|
struct FileEntry {
|
|
char name[FS_MAX_PATH];
|
|
};
|
|
private:
|
|
static constexpr size_t MaxFileRows = 11;
|
|
|
|
static constexpr float WindowWidth = 1200.0f;
|
|
static constexpr float WindowHeight = 680.0f;
|
|
static constexpr float TitleGap = 90.0f;
|
|
static constexpr float TextBackgroundOffset = 20.0f;
|
|
static constexpr float FileRowHeight = 40.0f;
|
|
static constexpr float FileRowGap = 10.0f;
|
|
static constexpr float FileRowHorizontalInset = 10.0f;
|
|
static constexpr float FileListHeight = MaxFileRows * (FileRowHeight + FileRowGap);
|
|
private:
|
|
char m_root[FS_MAX_PATH];
|
|
std::vector<FileEntry> m_file_entries;
|
|
u32 m_current_index;
|
|
float m_scroll_offset;
|
|
float m_touch_start_scroll_offset;
|
|
bool m_touch_finalize_selection;
|
|
|
|
Result PopulateFileEntries();
|
|
bool IsSelectionVisible();
|
|
void ScrollToSelection();
|
|
bool IsEntryTouched(u32 i);
|
|
void UpdateTouches();
|
|
void FinalizeSelection();
|
|
public:
|
|
FileMenu(std::shared_ptr<Menu> prev_menu, const char *root);
|
|
|
|
virtual void Update(u64 ns) override;
|
|
virtual void Draw(NVGcontext *vg, u64 ns) override;
|
|
};
|
|
|
|
class ValidateUpdateMenu : public Menu {
|
|
private:
|
|
static constexpr u32 BackButtonId = 0;
|
|
static constexpr u32 ContinueButtonId = 1;
|
|
|
|
static constexpr float WindowWidth = 600.0f;
|
|
static constexpr float WindowHeight = 600.0f;
|
|
static constexpr float TitleGap = 90.0f;
|
|
static constexpr float TextAreaHeight = 410.0f;
|
|
private:
|
|
AmsSuUpdateInformation m_update_info;
|
|
AmsSuUpdateValidationInfo m_validation_info;
|
|
bool m_has_drawn;
|
|
bool m_has_info;
|
|
bool m_has_validated;
|
|
|
|
Result GetUpdateInformation();
|
|
void ValidateUpdate();
|
|
public:
|
|
ValidateUpdateMenu(std::shared_ptr<Menu> prev_menu);
|
|
|
|
virtual void Update(u64 ns) override;
|
|
virtual void Draw(NVGcontext *vg, u64 ns) override;
|
|
};
|
|
|
|
class ChooseResetMenu : public Menu {
|
|
private:
|
|
static constexpr u32 ResetToFactorySettingsButtonId = 0;
|
|
static constexpr u32 PreserveSettingsButtonId = 1;
|
|
|
|
static constexpr float WindowWidth = 600.0f;
|
|
static constexpr float WindowHeight = 170.0f;
|
|
static constexpr float TitleGap = 90.0f;
|
|
public:
|
|
ChooseResetMenu(std::shared_ptr<Menu> prev_menu);
|
|
|
|
virtual void Update(u64 ns) override;
|
|
virtual void Draw(NVGcontext *vg, u64 ns) override;
|
|
};
|
|
|
|
class ChooseExfatMenu : public Menu {
|
|
private:
|
|
static constexpr u32 Fat32ButtonId = 0;
|
|
static constexpr u32 ExFatButtonId = 1;
|
|
|
|
static constexpr float WindowWidth = 600.0f;
|
|
static constexpr float WindowHeight = 170.0f;
|
|
static constexpr float TitleGap = 90.0f;
|
|
public:
|
|
ChooseExfatMenu(std::shared_ptr<Menu> prev_menu);
|
|
|
|
virtual void Update(u64 ns) override;
|
|
virtual void Draw(NVGcontext *vg, u64 ns) override;
|
|
};
|
|
|
|
class InstallUpdateMenu : public Menu {
|
|
private:
|
|
enum class InstallState {
|
|
NeedsDraw,
|
|
NeedsSetup,
|
|
NeedsPrepare,
|
|
AwaitingPrepare,
|
|
NeedsApply,
|
|
AwaitingReboot,
|
|
};
|
|
private:
|
|
static constexpr u32 ShutdownButtonId = 0;
|
|
static constexpr u32 RebootButtonId = 1;
|
|
|
|
static constexpr float WindowWidth = 600.0f;
|
|
static constexpr float WindowHeight = 600.0f;
|
|
static constexpr float TitleGap = 120.0f;
|
|
static constexpr float ProgressTextHeight = 20.0f;
|
|
static constexpr float ProgressBarHeight = 30.0f;
|
|
static constexpr float TextAreaHeight = 320.0f;
|
|
|
|
static constexpr size_t UpdateTaskBufferSize = 0x100000;
|
|
private:
|
|
InstallState m_install_state;
|
|
AsyncResult m_prepare_result;
|
|
float m_progress_percent;
|
|
|
|
void MarkForReboot();
|
|
Result TransitionUpdateState();
|
|
public:
|
|
InstallUpdateMenu(std::shared_ptr<Menu> prev_menu);
|
|
|
|
virtual void Update(u64 ns) override;
|
|
virtual void Draw(NVGcontext *vg, u64 ns) override;
|
|
};
|
|
|
|
bool InitializeMenu(u32 screen_width, u32 screen_height);
|
|
bool InitializeMenu(u32 screen_width, u32 screen_height, const char *update_path);
|
|
void UpdateMenu(u64 ns);
|
|
void RenderMenu(NVGcontext *vg, u64 ns);
|
|
bool IsExitRequested();
|
|
|
|
}
|