mirror of
https://github.com/zhenyan121/Cubed.git
synced 2026-08-08 17:57:02 +08:00
feat(ui): add ComboButton widget and integrate into settings
Introduce ComboButton, a button that cycles through options on click. Used in SettingsUI for fullscreen, V-Sync, and anisotropic filtering. Adds texture reload support in SettingsScene and makes Button methods virtual to allow overriding. Also fixes default mouse_enable to true.
This commit is contained in:
@@ -29,11 +29,13 @@ public:
|
|||||||
void on_re_enter() override;
|
void on_re_enter() override;
|
||||||
SceneManager& scene_manager();
|
SceneManager& scene_manager();
|
||||||
SliderVariable& slider_variable();
|
SliderVariable& slider_variable();
|
||||||
|
void set_texture_reload(bool reload);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void save_and_apply();
|
void save_and_apply();
|
||||||
SceneManager& m_scene_manager;
|
SceneManager& m_scene_manager;
|
||||||
SliderVariable m_slider_variable;
|
SliderVariable m_slider_variable;
|
||||||
SettingsUI m_settings_ui;
|
SettingsUI m_settings_ui;
|
||||||
|
bool m_need_texture_reload = false;
|
||||||
};
|
};
|
||||||
} // namespace Cubed
|
} // namespace Cubed
|
||||||
@@ -17,7 +17,7 @@ public:
|
|||||||
Button& operator=(Button&&) = delete;
|
Button& operator=(Button&&) = delete;
|
||||||
|
|
||||||
bool handle_mouse_move_event(const MouseMoveEvent& e) override;
|
bool handle_mouse_move_event(const MouseMoveEvent& e) override;
|
||||||
bool handle_mouse_button_event(const MouseButtonEvent& e) override;
|
virtual bool handle_mouse_button_event(const MouseButtonEvent& e) override;
|
||||||
Button& set_scale(float scale);
|
Button& set_scale(float scale);
|
||||||
|
|
||||||
float width() const override;
|
float width() const override;
|
||||||
@@ -28,7 +28,7 @@ public:
|
|||||||
Button& set_background_image(const std::string& path,
|
Button& set_background_image(const std::string& path,
|
||||||
TextureManager& texture_manager);
|
TextureManager& texture_manager);
|
||||||
Button& set_default_image(TextureManager& texture_manager);
|
Button& set_default_image(TextureManager& texture_manager);
|
||||||
Button& set_text(const std::string& text);
|
virtual Button& set_text(const std::string& text);
|
||||||
|
|
||||||
Button& set_auto_scale(bool auto_scale);
|
Button& set_auto_scale(bool auto_scale);
|
||||||
Button& set_enable(bool enable);
|
Button& set_enable(bool enable);
|
||||||
@@ -38,6 +38,13 @@ public:
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::unique_ptr<Image> m_background;
|
||||||
|
std::unique_ptr<Label> m_foreground;
|
||||||
|
bool m_hovered = false;
|
||||||
|
bool m_enable = true;
|
||||||
|
void update_text_scale();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static constexpr float PADDING = 5.0f;
|
static constexpr float PADDING = 5.0f;
|
||||||
static constexpr float DEFAULT_SCALE = 3.0f;
|
static constexpr float DEFAULT_SCALE = 3.0f;
|
||||||
@@ -46,16 +53,12 @@ private:
|
|||||||
static constexpr const char* DEFAULT_BUTTON_IMAGE =
|
static constexpr const char* DEFAULT_BUTTON_IMAGE =
|
||||||
"texture/ui/button001.png";
|
"texture/ui/button001.png";
|
||||||
std::function<void()> m_clicked;
|
std::function<void()> m_clicked;
|
||||||
std::unique_ptr<Image> m_background;
|
|
||||||
std::unique_ptr<Label> m_foreground;
|
|
||||||
bool m_hovered = false;
|
|
||||||
bool m_enable = true;
|
|
||||||
float m_width = NORMAL_BUTTON_WIDTH;
|
float m_width = NORMAL_BUTTON_WIDTH;
|
||||||
float m_height = NORMAL_BUTTON_HEIGHT;
|
float m_height = NORMAL_BUTTON_HEIGHT;
|
||||||
float m_scale = DEFAULT_SCALE;
|
float m_scale = DEFAULT_SCALE;
|
||||||
bool m_auto_scale = false;
|
bool m_auto_scale = false;
|
||||||
void on_render(Renderer& renderer) override;
|
void on_render(Renderer& renderer) override;
|
||||||
void on_update(float dt) override;
|
void on_update(float dt) override;
|
||||||
void update_text_scale();
|
|
||||||
};
|
};
|
||||||
} // namespace Cubed
|
} // namespace Cubed
|
||||||
30
include/Cubed/ui/combo_button.hpp
Normal file
30
include/Cubed/ui/combo_button.hpp
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "Cubed/ui/button.hpp"
|
||||||
|
|
||||||
|
#include <span>
|
||||||
|
namespace Cubed {
|
||||||
|
using ComboPair = std::pair<std::string, std::function<void()>>;
|
||||||
|
class ComboButton : public Button {
|
||||||
|
|
||||||
|
public:
|
||||||
|
ComboButton(const ComboButton&) = delete;
|
||||||
|
ComboButton(ComboButton&&) = delete;
|
||||||
|
ComboButton& operator=(const ComboButton&) = delete;
|
||||||
|
ComboButton& operator=(ComboButton&&) = delete;
|
||||||
|
|
||||||
|
ComboButton(Widget* parent);
|
||||||
|
Button& set_text(const std::string& text) override;
|
||||||
|
bool handle_mouse_button_event(const MouseButtonEvent& e) override;
|
||||||
|
ComboButton& set_combos(std::span<ComboPair> combos);
|
||||||
|
ComboButton& set_index(int index);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void update_text();
|
||||||
|
|
||||||
|
std::vector<std::string> m_suffix;
|
||||||
|
std::vector<std::function<void()>> m_funs;
|
||||||
|
std::string m_text;
|
||||||
|
int m_index = 0;
|
||||||
|
int m_sum = 0;
|
||||||
|
};
|
||||||
|
} // namespace Cubed
|
||||||
@@ -41,7 +41,7 @@ public:
|
|||||||
void set_imgui_enabled(bool enable);
|
void set_imgui_enabled(bool enable);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool m_mouse_enable = false;
|
bool m_mouse_enable = true;
|
||||||
bool m_imgui_init = false;
|
bool m_imgui_init = false;
|
||||||
bool m_game_running = false;
|
bool m_game_running = false;
|
||||||
GLFWwindow* m_window;
|
GLFWwindow* m_window;
|
||||||
|
|||||||
@@ -76,4 +76,5 @@ target_sources(${PROJECT_NAME}
|
|||||||
ui/slider.cpp
|
ui/slider.cpp
|
||||||
ui/settings_ui.cpp
|
ui/settings_ui.cpp
|
||||||
scene/settings_scene.cpp
|
scene/settings_scene.cpp
|
||||||
|
ui/combo_button.cpp
|
||||||
)
|
)
|
||||||
@@ -30,7 +30,13 @@ void SettingsScene::on_enter() {
|
|||||||
m_slider_variable.rendering_distance = config.get(
|
m_slider_variable.rendering_distance = config.get(
|
||||||
"world.rendering_distance", m_slider_variable.rendering_distance);
|
"world.rendering_distance", m_slider_variable.rendering_distance);
|
||||||
}
|
}
|
||||||
void SettingsScene::on_leave() { save_and_apply(); }
|
void SettingsScene::on_leave() {
|
||||||
|
save_and_apply();
|
||||||
|
|
||||||
|
if (m_need_texture_reload) {
|
||||||
|
m_scene_manager.app().texture_manager().need_reload();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void SettingsScene::on_re_enter() {
|
void SettingsScene::on_re_enter() {
|
||||||
auto width = m_scene_manager.app().renderer().window_width();
|
auto width = m_scene_manager.app().renderer().window_width();
|
||||||
@@ -56,4 +62,7 @@ void SettingsScene::save_and_apply() {
|
|||||||
|
|
||||||
SceneManager& SettingsScene::scene_manager() { return m_scene_manager; }
|
SceneManager& SettingsScene::scene_manager() { return m_scene_manager; }
|
||||||
SliderVariable& SettingsScene::slider_variable() { return m_slider_variable; }
|
SliderVariable& SettingsScene::slider_variable() { return m_slider_variable; }
|
||||||
|
void SettingsScene::set_texture_reload(bool reload) {
|
||||||
|
m_need_texture_reload = reload;
|
||||||
|
}
|
||||||
} // namespace Cubed
|
} // namespace Cubed
|
||||||
55
src/ui/combo_button.cpp
Normal file
55
src/ui/combo_button.cpp
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
#include "Cubed/ui/combo_button.hpp"
|
||||||
|
|
||||||
|
namespace Cubed {
|
||||||
|
ComboButton::ComboButton(Widget* parent) : Button(parent) {}
|
||||||
|
|
||||||
|
Button& ComboButton::set_text(const std::string& text) {
|
||||||
|
m_text = text;
|
||||||
|
update_text();
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
bool ComboButton::handle_mouse_button_event(const MouseButtonEvent& e) {
|
||||||
|
if (e.action == KeyAction::PRESS && e.key == MouseKey::LEFT_BUTTON) {
|
||||||
|
if (m_hovered && m_enable) {
|
||||||
|
m_index = (m_index + 1) % m_sum;
|
||||||
|
update_text();
|
||||||
|
if (m_funs[m_index]) {
|
||||||
|
m_funs[m_index]();
|
||||||
|
} else {
|
||||||
|
Logger::error("Function {} is null", m_index);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Widget::handle_mouse_button_event(e);
|
||||||
|
}
|
||||||
|
ComboButton& ComboButton::set_combos(
|
||||||
|
std::span<std::pair<std::string, std::function<void()>>> combos) {
|
||||||
|
m_funs.clear();
|
||||||
|
m_suffix.clear();
|
||||||
|
m_sum = combos.size();
|
||||||
|
for (auto& pair : combos) {
|
||||||
|
m_suffix.push_back(pair.first);
|
||||||
|
m_funs.push_back(pair.second);
|
||||||
|
}
|
||||||
|
update_text();
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
ComboButton& ComboButton::set_index(int index) {
|
||||||
|
m_index = index;
|
||||||
|
update_text();
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ComboButton::update_text() {
|
||||||
|
if (m_suffix.empty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto text = m_text + ": " + m_suffix[m_index];
|
||||||
|
m_foreground->set_text(text);
|
||||||
|
update_text_scale();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Cubed
|
||||||
@@ -6,6 +6,7 @@
|
|||||||
#include "Cubed/scene/settings_scene.hpp"
|
#include "Cubed/scene/settings_scene.hpp"
|
||||||
#include "Cubed/ui/button.hpp"
|
#include "Cubed/ui/button.hpp"
|
||||||
#include "Cubed/ui/column_layout.hpp"
|
#include "Cubed/ui/column_layout.hpp"
|
||||||
|
#include "Cubed/ui/combo_button.hpp"
|
||||||
#include "Cubed/ui/image.hpp"
|
#include "Cubed/ui/image.hpp"
|
||||||
#include "Cubed/ui/slider.hpp"
|
#include "Cubed/ui/slider.hpp"
|
||||||
namespace Cubed {
|
namespace Cubed {
|
||||||
@@ -63,7 +64,86 @@ void SettingsUI::init() {
|
|||||||
set_default_slider_image(sfx);
|
set_default_slider_image(sfx);
|
||||||
sfx.set_text("SFX");
|
sfx.set_text("SFX");
|
||||||
}
|
}
|
||||||
|
auto& config = m_scene.scene_manager().app().config();
|
||||||
|
{
|
||||||
|
|
||||||
|
bool full = config.get("window.fullscreen", false);
|
||||||
|
auto& fullscreen = layout.add_child<ComboButton>();
|
||||||
|
fullscreen.set_index(!full ? 0 : 1);
|
||||||
|
fullscreen.set_text("Fullscreen");
|
||||||
|
std::vector<std::pair<std::string, std::function<void()>>> comb;
|
||||||
|
comb.emplace_back("off", [&config, this]() {
|
||||||
|
config.set("window.fullscreen", false);
|
||||||
|
m_scene.scene_manager().app().window().reload_config();
|
||||||
|
});
|
||||||
|
comb.emplace_back("on", [&config, this]() {
|
||||||
|
config.set("window.fullscreen", true);
|
||||||
|
m_scene.scene_manager().app().window().reload_config();
|
||||||
|
});
|
||||||
|
fullscreen.set_default_image(texture_manager);
|
||||||
|
fullscreen.set_combos(comb);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
bool enable_vsync = config.get("window.V-Sync", true);
|
||||||
|
auto& vsync = layout.add_child<ComboButton>();
|
||||||
|
vsync.set_default_image(texture_manager);
|
||||||
|
vsync.set_text("V-Sync");
|
||||||
|
std::vector<ComboPair> combos;
|
||||||
|
combos.emplace_back("off", [this, &config]() {
|
||||||
|
config.set("window.V-Sync", false);
|
||||||
|
m_scene.scene_manager().app().window().reload_config();
|
||||||
|
});
|
||||||
|
combos.emplace_back("on", [this, &config]() {
|
||||||
|
config.set("window.V-Sync", true);
|
||||||
|
m_scene.scene_manager().app().window().reload_config();
|
||||||
|
});
|
||||||
|
|
||||||
|
vsync.set_combos(combos);
|
||||||
|
vsync.set_index(!enable_vsync ? 0 : 1);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
int max_aniso = texture_manager.max_aniso();
|
||||||
|
int config_aniso = config.get("texture.aniso", 1);
|
||||||
|
int aniso = (config_aniso > max_aniso) ? max_aniso : config_aniso;
|
||||||
|
int max_sum = 1;
|
||||||
|
for (int temp = max_aniso; temp > 1; temp /= 2) {
|
||||||
|
++max_sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
int cur_index = 0;
|
||||||
|
for (int i = 0, temp = 1; i < max_sum; i++) {
|
||||||
|
if (temp == aniso) {
|
||||||
|
cur_index = i;
|
||||||
|
}
|
||||||
|
temp *= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto& aniso_button = layout.add_child<ComboButton>();
|
||||||
|
aniso_button.set_default_image(texture_manager);
|
||||||
|
aniso_button.set_text("Aniso");
|
||||||
|
aniso_button.set_index(cur_index);
|
||||||
|
std::vector<ComboPair> combos;
|
||||||
|
auto get_suffix = [](int i) -> std::pair<std::string, int> {
|
||||||
|
if (i == 0) {
|
||||||
|
return {"off", 1};
|
||||||
|
}
|
||||||
|
int n = 1;
|
||||||
|
for (int j = 0; j < i; j++) {
|
||||||
|
n *= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {std::to_string(n) + "x", n};
|
||||||
|
};
|
||||||
|
for (int i = 0; i < max_sum; i++) {
|
||||||
|
auto [str, n] = get_suffix(i);
|
||||||
|
combos.emplace_back(str, [&config, this, n]() {
|
||||||
|
config.set("texture.aniso", n);
|
||||||
|
m_scene.set_texture_reload(true);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
aniso_button.set_combos(combos);
|
||||||
|
}
|
||||||
auto& return_button = layout.add_child<Button>();
|
auto& return_button = layout.add_child<Button>();
|
||||||
return_button.set_background_image("texture/ui/button001.png",
|
return_button.set_background_image("texture/ui/button001.png",
|
||||||
texture_manager);
|
texture_manager);
|
||||||
|
|||||||
Reference in New Issue
Block a user