Files
sphaira/sphaira/include/ui/sidebar.hpp

164 lines
5.4 KiB
C++

#pragma once
#include "ui/widget.hpp"
#include "ui/list.hpp"
#include "ui/scrolling_text.hpp"
#include "option.hpp"
#include <memory>
#include <concepts>
#include <utility>
namespace sphaira::ui {
class SidebarEntryBase : public Widget {
public:
using DependsCallback = std::function<bool(void)>;
public:
explicit SidebarEntryBase(const std::string& title, const std::string& info);
using Widget::Draw;
virtual void Draw(NVGcontext* vg, Theme* theme, const Vec4& root_pos, bool left);
void Depends(const DependsCallback& callback, const std::string& depends_info) {
m_depends_callback = callback;
m_depends_info = depends_info;
}
void Depends(bool& value, const std::string& depends_info) {
m_depends_callback = [&value](){ return value; };
m_depends_info = depends_info;
}
void Depends(option::OptionBool& value, const std::string& depends_info) {
m_depends_callback = [&value](){ return value.Get(); };
m_depends_info = depends_info;
}
protected:
auto IsEnabled() -> bool {
if (m_depends_callback) {
return m_depends_callback();
}
return true;
}
protected:
std::string m_title;
private:
std::string m_info{};
std::string m_depends_info{};
DependsCallback m_depends_callback{};
ScrollingText m_scolling_title{};
};
template<typename T>
concept DerivedFromSidebarBase = std::is_base_of_v<SidebarEntryBase, T>;
class SidebarEntryBool final : public SidebarEntryBase {
public:
using Callback = std::function<void(bool&)>;
public:
explicit SidebarEntryBool(const std::string& title, bool option, Callback cb, const std::string& info = "", const std::string& true_str = "On", const std::string& false_str = "Off");
explicit SidebarEntryBool(const std::string& title, bool& option, const std::string& info = "", const std::string& true_str = "On", const std::string& false_str = "Off");
explicit SidebarEntryBool(const std::string& title, option::OptionBool& option, const Callback& cb, const std::string& info = "", const std::string& true_str = "On", const std::string& false_str = "Off");
explicit SidebarEntryBool(const std::string& title, option::OptionBool& option, const std::string& info = "", const std::string& true_str = "On", const std::string& false_str = "Off");
private:
void Draw(NVGcontext* vg, Theme* theme, const Vec4& root_pos, bool left) override;
bool m_option;
Callback m_callback;
std::string m_true_str;
std::string m_false_str;
};
class SidebarEntryCallback final : public SidebarEntryBase {
public:
using Callback = std::function<void()>;
public:
explicit SidebarEntryCallback(const std::string& title, Callback cb, const std::string& info);
explicit SidebarEntryCallback(const std::string& title, Callback cb, bool pop_on_click = false, const std::string& info = "");
void Draw(NVGcontext* vg, Theme* theme, const Vec4& root_pos, bool left) override;
private:
Callback m_callback;
bool m_pop_on_click;
};
class SidebarEntryArray final : public SidebarEntryBase {
public:
using Items = std::vector<std::string>;
using ListCallback = std::function<void()>;
using Callback = std::function<void(s64& index)>;
public:
explicit SidebarEntryArray(const std::string& title, const Items& items, Callback cb, s64 index = 0, const std::string& info = "");
explicit SidebarEntryArray(const std::string& title, const Items& items, Callback cb, const std::string& index, const std::string& info = "");
explicit SidebarEntryArray(const std::string& title, const Items& items, std::string& index, const std::string& info = "");
void Draw(NVGcontext* vg, Theme* theme, const Vec4& root_pos, bool left) override;
auto OnFocusGained() noexcept -> void override;
auto OnFocusLost() noexcept -> void override;
private:
Items m_items;
ListCallback m_list_callback;
Callback m_callback;
s64 m_index;
s64 m_tick{};
float m_text_yoff{};
};
class Sidebar final : public Widget {
public:
enum class Side { LEFT, RIGHT };
using Items = std::vector<std::unique_ptr<SidebarEntryBase>>;
public:
explicit Sidebar(const std::string& title, Side side, Items&& items);
explicit Sidebar(const std::string& title, Side side);
explicit Sidebar(const std::string& title, const std::string& sub, Side side, Items&& items);
explicit Sidebar(const std::string& title, const std::string& sub, Side side);
auto Update(Controller* controller, TouchInfo* touch) -> void override;
auto Draw(NVGcontext* vg, Theme* theme) -> void override;
auto OnFocusGained() noexcept -> void override;
auto OnFocusLost() noexcept -> void override;
auto Add(std::unique_ptr<SidebarEntryBase>&& entry) -> SidebarEntryBase*;
template<DerivedFromSidebarBase T, typename... Args>
auto Add(Args&&... args) -> SidebarEntryBase* {
return Add(std::make_unique<T>(std::forward<Args>(args)...));
}
private:
void SetIndex(s64 index);
void SetupButtons();
private:
std::string m_title;
std::string m_sub;
Side m_side;
Items m_items;
s64 m_index{};
std::unique_ptr<List> m_list;
Vec4 m_top_bar{};
Vec4 m_bottom_bar{};
Vec2 m_title_pos{};
Vec4 m_base_pos{};
static constexpr float m_title_size{28.f};
// static constexpr Vec2 box_size{380.f, 70.f};
static constexpr Vec2 m_box_size{400.f, 70.f};
};
} // namespace sphaira::ui