mirror of
https://github.com/Mr-Wiseguy/Zelda64Recomp.git
synced 2025-02-13 18:29:13 +01:00
Text input.
This commit is contained in:
parent
743f048826
commit
4967d31125
@ -186,6 +186,7 @@ set (SOURCES
|
||||
${CMAKE_SOURCE_DIR}/src/ui/elements/ui_scroll_container.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/ui/elements/ui_slider.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/ui/elements/ui_style.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/ui/elements/ui_text_input.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/ui/elements/ui_toggle.cpp
|
||||
|
||||
${CMAKE_SOURCE_DIR}/rsp/aspMain.cpp
|
||||
|
@ -68,10 +68,10 @@ namespace recompui {
|
||||
}
|
||||
break;
|
||||
case EventType::Hover:
|
||||
set_style_enabled(hover_state, e.hover.active);
|
||||
set_style_enabled(hover_state, std::get<EventHover>(e.variant).active);
|
||||
break;
|
||||
case EventType::Enable:
|
||||
set_style_enabled(disabled_state, !e.enable.enable);
|
||||
set_style_enabled(disabled_state, !std::get<EventEnable>(e.variant).active);
|
||||
break;
|
||||
default:
|
||||
assert(false && "Unknown event type.");
|
||||
|
@ -13,22 +13,26 @@ namespace recompui {
|
||||
|
||||
void Clickable::process_event(const Event &e) {
|
||||
switch (e.type) {
|
||||
case EventType::Click:
|
||||
case EventType::Click: {
|
||||
const EventClick &click = std::get<EventClick>(e.variant);
|
||||
for (const auto &function : pressed_callbacks) {
|
||||
function(e.click.mouse.x, e.click.mouse.y);
|
||||
function(click.x, click.y);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case EventType::Hover:
|
||||
set_style_enabled(hover_state, e.hover.active);
|
||||
set_style_enabled(hover_state, std::get<EventHover>(e.variant).active);
|
||||
break;
|
||||
case EventType::Enable:
|
||||
set_style_enabled(disabled_state, !e.enable.enable);
|
||||
set_style_enabled(disabled_state, !std::get<EventEnable>(e.variant).active);
|
||||
break;
|
||||
case EventType::Drag:
|
||||
case EventType::Drag: {
|
||||
const EventDrag &drag = std::get<EventDrag>(e.variant);
|
||||
for (const auto &function : dragged_callbacks) {
|
||||
function(e.drag.mouse.x, e.drag.mouse.y, e.drag.phase);
|
||||
function(drag.x, drag.y, drag.phase);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -89,6 +89,10 @@ void Element::register_event_listeners(uint32_t events_enabled) {
|
||||
base->AddEventListener(Rml::EventId::Dragstart, this);
|
||||
base->AddEventListener(Rml::EventId::Dragend, this);
|
||||
}
|
||||
|
||||
if (events_enabled & Events(EventType::Text)) {
|
||||
base->AddEventListener(Rml::EventId::Change, this);
|
||||
}
|
||||
}
|
||||
|
||||
void Element::apply_style(Style *style) {
|
||||
@ -170,6 +174,16 @@ void Element::ProcessEvent(Rml::Event &event) {
|
||||
case Rml::EventId::Dragend:
|
||||
process_event(Event::drag_event(event.GetParameter("mouse_x", 0.0f), event.GetParameter("mouse_y", 0.0f), DragPhase::End));
|
||||
break;
|
||||
case Rml::EventId::Change: {
|
||||
if (events_enabled & Events(EventType::Text)) {
|
||||
Rml::Variant *value_variant = base->GetAttribute("value");
|
||||
if (value_variant != nullptr) {
|
||||
process_event(Event::text_event(value_variant->Get<std::string>()));
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -180,6 +194,10 @@ void Element::ProcessEvent(Rml::Event &event) {
|
||||
}
|
||||
}
|
||||
|
||||
void Element::set_attribute(const Rml::String &attribute_key, const Rml::String &attribute_value) {
|
||||
base->SetAttribute(attribute_key, attribute_value);
|
||||
}
|
||||
|
||||
void Element::process_event(const Event &) {
|
||||
// Does nothing by default.
|
||||
}
|
||||
|
@ -34,6 +34,8 @@ private:
|
||||
// Rml::EventListener overrides.
|
||||
void ProcessEvent(Rml::Event &event) override final;
|
||||
protected:
|
||||
// Use of this method in inherited classes is discouraged unless it's necessary.
|
||||
void set_attribute(const Rml::String &attribute_key, const Rml::String &attribute_value);
|
||||
virtual void process_event(const Event &e);
|
||||
public:
|
||||
// Used for backwards compatibility with legacy UI elements.
|
||||
|
40
src/ui/elements/ui_text_input.cpp
Normal file
40
src/ui/elements/ui_text_input.cpp
Normal file
@ -0,0 +1,40 @@
|
||||
#include "ui_text_input.h"
|
||||
|
||||
#include <cassert>
|
||||
|
||||
namespace recompui {
|
||||
|
||||
void TextInput::process_event(const Event &e) {
|
||||
switch (e.type) {
|
||||
case EventType::Text: {
|
||||
const EventText &event = std::get<EventText>(e.variant);
|
||||
text = event.text;
|
||||
|
||||
for (const auto &function : text_changed_callbacks) {
|
||||
function(text);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
TextInput::TextInput(Element *parent) : Element(parent, Events(EventType::Text), "input") {
|
||||
}
|
||||
|
||||
void TextInput::set_text(std::string_view text) {
|
||||
this->text = std::string(text);
|
||||
set_attribute("value", this->text);
|
||||
}
|
||||
|
||||
const std::string &TextInput::get_text() {
|
||||
return text;
|
||||
}
|
||||
|
||||
void TextInput::add_text_changed_callback(std::function<void(const std::string &)> callback) {
|
||||
text_changed_callbacks.emplace_back(callback);
|
||||
}
|
||||
|
||||
};
|
20
src/ui/elements/ui_text_input.h
Normal file
20
src/ui/elements/ui_text_input.h
Normal file
@ -0,0 +1,20 @@
|
||||
#pragma once
|
||||
|
||||
#include "ui_element.h"
|
||||
|
||||
namespace recompui {
|
||||
|
||||
class TextInput : public Element {
|
||||
private:
|
||||
std::string text;
|
||||
std::vector<std::function<void(const std::string &)>> text_changed_callbacks;
|
||||
protected:
|
||||
virtual void process_event(const Event &e) override;
|
||||
public:
|
||||
TextInput(Element *parent);
|
||||
void set_text(std::string_view text);
|
||||
const std::string &get_text();
|
||||
void add_text_changed_callback(std::function<void(const std::string &)> callback);
|
||||
};
|
||||
|
||||
} // namespace recompui
|
@ -78,14 +78,18 @@ namespace recompui {
|
||||
}
|
||||
|
||||
break;
|
||||
case EventType::Hover:
|
||||
set_style_enabled(hover_state, e.hover.active);
|
||||
floater->set_style_enabled(hover_state, e.hover.active);
|
||||
case EventType::Hover: {
|
||||
bool hover_active = std::get<EventHover>(e.variant).active;
|
||||
set_style_enabled(hover_state, hover_active);
|
||||
floater->set_style_enabled(hover_state, hover_active);
|
||||
break;
|
||||
case EventType::Enable:
|
||||
set_style_enabled(disabled_state, !e.enable.enable);
|
||||
floater->set_style_enabled(disabled_state, !e.enable.enable);
|
||||
}
|
||||
case EventType::Enable: {
|
||||
bool enable_active = std::get<EventEnable>(e.variant).active;
|
||||
set_style_enabled(disabled_state, !enable_active);
|
||||
floater->set_style_enabled(disabled_state, !enable_active);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
assert(false && "Unknown event type.");
|
||||
break;
|
||||
|
@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <variant>
|
||||
|
||||
namespace recompui {
|
||||
|
||||
@ -23,6 +24,7 @@ namespace recompui {
|
||||
Hover,
|
||||
Enable,
|
||||
Drag,
|
||||
Text,
|
||||
Count
|
||||
};
|
||||
|
||||
@ -43,74 +45,79 @@ namespace recompui {
|
||||
return Events(first) | Events(rest...);
|
||||
}
|
||||
|
||||
struct EventClick {
|
||||
float x;
|
||||
float y;
|
||||
};
|
||||
|
||||
struct EventFocus {
|
||||
bool active;
|
||||
};
|
||||
|
||||
struct EventHover {
|
||||
bool active;
|
||||
};
|
||||
|
||||
struct EventEnable {
|
||||
bool active;
|
||||
};
|
||||
|
||||
struct EventDrag {
|
||||
float x;
|
||||
float y;
|
||||
DragPhase phase;
|
||||
};
|
||||
|
||||
struct EventText {
|
||||
std::string text;
|
||||
};
|
||||
|
||||
using EventVariant = std::variant<EventClick, EventFocus, EventHover, EventEnable, EventDrag, EventText>;
|
||||
|
||||
struct Event {
|
||||
struct Mouse {
|
||||
float x;
|
||||
float y;
|
||||
};
|
||||
|
||||
EventType type;
|
||||
EventVariant variant;
|
||||
|
||||
union {
|
||||
uint64_t raw;
|
||||
|
||||
struct {
|
||||
Mouse mouse;
|
||||
} click;
|
||||
|
||||
struct {
|
||||
bool active;
|
||||
} focus;
|
||||
|
||||
struct {
|
||||
bool active;
|
||||
} hover;
|
||||
|
||||
struct {
|
||||
bool enable;
|
||||
} enable;
|
||||
|
||||
struct {
|
||||
Mouse mouse;
|
||||
DragPhase phase;
|
||||
} drag;
|
||||
};
|
||||
|
||||
// Factory methods for creating specific events
|
||||
static Event click_event(float x, float y) {
|
||||
Event e = {};
|
||||
Event e;
|
||||
e.type = EventType::Click;
|
||||
e.click.mouse.x = x;
|
||||
e.click.mouse.y = y;
|
||||
e.variant = EventClick{ x, y };
|
||||
return e;
|
||||
}
|
||||
|
||||
static Event focus_event(bool active) {
|
||||
Event e = {};
|
||||
Event e;
|
||||
e.type = EventType::Focus;
|
||||
e.focus.active = active;
|
||||
e.variant = EventFocus{ active };
|
||||
return e;
|
||||
}
|
||||
|
||||
static Event hover_event(bool active) {
|
||||
Event e = {};
|
||||
Event e;
|
||||
e.type = EventType::Hover;
|
||||
e.focus.active = active;
|
||||
e.variant = EventHover{ active };
|
||||
return e;
|
||||
}
|
||||
|
||||
static Event enable_event(bool enable) {
|
||||
Event e = {};
|
||||
Event e;
|
||||
e.type = EventType::Enable;
|
||||
e.enable.enable = enable;
|
||||
e.variant = EventEnable{ enable };
|
||||
return e;
|
||||
}
|
||||
|
||||
static Event drag_event(float x, float y, DragPhase phase) {
|
||||
Event e = {};
|
||||
Event e;
|
||||
e.type = EventType::Drag;
|
||||
e.drag.mouse.x = x;
|
||||
e.drag.mouse.y = y;
|
||||
e.drag.phase = phase;
|
||||
e.variant = EventDrag{ x, y, phase };
|
||||
return e;
|
||||
}
|
||||
|
||||
static Event text_event(const std::string &text) {
|
||||
Event e;
|
||||
e.type = EventType::Text;
|
||||
e.variant = EventText{ text };
|
||||
return e;
|
||||
}
|
||||
};
|
||||
|
@ -10,7 +10,7 @@ namespace recompui {
|
||||
void ConfigOptionElement::process_event(const Event &e) {
|
||||
switch (e.type) {
|
||||
case EventType::Hover:
|
||||
hover_callback(this, e.hover.active);
|
||||
hover_callback(this, std::get<EventHover>(e.variant).active);
|
||||
break;
|
||||
default:
|
||||
assert(false && "Unknown event type.");
|
||||
@ -73,6 +73,22 @@ void ConfigOptionSlider::set_max_value(double v) {
|
||||
slider->set_max_value(v);
|
||||
}
|
||||
|
||||
// ConfigOptionTextInput
|
||||
|
||||
void ConfigOptionTextInput::text_changed(const std::string &text) {
|
||||
// TODO: Hook up to whatever API Recomp exposes to set the value of the persisent configuration in mods.
|
||||
printf("%s changed to %s.\n", name.c_str(), text.c_str());
|
||||
}
|
||||
|
||||
ConfigOptionTextInput::ConfigOptionTextInput(Element *parent) : ConfigOptionElement(parent) {
|
||||
text_input = get_current_context().create_element<TextInput>(this);
|
||||
text_input->add_text_changed_callback(std::bind(&ConfigOptionTextInput::text_changed, this, std::placeholders::_1));
|
||||
}
|
||||
|
||||
ConfigOptionTextInput::~ConfigOptionTextInput() {
|
||||
|
||||
}
|
||||
|
||||
// ConfigSubMenu
|
||||
|
||||
void ConfigSubMenu::back_button_pressed() {
|
||||
@ -159,6 +175,11 @@ void ConfigSubMenu::add_slider_option(std::string_view name, std::string_view de
|
||||
add_option(option_slider, name, description);
|
||||
}
|
||||
|
||||
void ConfigSubMenu::add_text_option(std::string_view name, std::string_view description) {
|
||||
ConfigOptionTextInput *option_text_input = get_current_context().create_element<ConfigOptionTextInput>(config_scroll_container);
|
||||
add_option(option_text_input, name, description);
|
||||
}
|
||||
|
||||
void ConfigSubMenu::set_enter_sub_menu_callback(std::function<void()> callback) {
|
||||
enter_sub_menu_callback = callback;
|
||||
}
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "elements/ui_label.h"
|
||||
#include "elements/ui_scroll_container.h"
|
||||
#include "elements/ui_slider.h"
|
||||
#include "elements/ui_text_input.h"
|
||||
|
||||
namespace recompui {
|
||||
|
||||
@ -41,6 +42,16 @@ public:
|
||||
void set_max_value(double v);
|
||||
};
|
||||
|
||||
class ConfigOptionTextInput : public ConfigOptionElement {
|
||||
protected:
|
||||
TextInput *text_input = nullptr;
|
||||
|
||||
void text_changed(const std::string &text);
|
||||
public:
|
||||
ConfigOptionTextInput(Element *parent);
|
||||
virtual ~ConfigOptionTextInput();
|
||||
};
|
||||
|
||||
class ConfigSubMenu : public Element {
|
||||
private:
|
||||
Container *header_container = nullptr;
|
||||
@ -65,6 +76,7 @@ public:
|
||||
void enter(std::string_view title);
|
||||
void clear_options();
|
||||
void add_slider_option(std::string_view name, std::string_view description, double min, double max);
|
||||
void add_text_option(std::string_view name, std::string_view description);
|
||||
void set_enter_sub_menu_callback(std::function<void()> callback);
|
||||
void set_quit_sub_menu_callback(std::function<void()> callback);
|
||||
};
|
||||
|
@ -100,17 +100,8 @@ void ModMenu::mod_toggled(bool enabled) {
|
||||
void ModMenu::mod_configure_requested() {
|
||||
if (active_mod_index >= 0) {
|
||||
ext_config_sub_menu->clear_options();
|
||||
ext_config_sub_menu->add_slider_option("Simple Option", "Description for simple option.", 0.0, 100.0);
|
||||
ext_config_sub_menu->add_slider_option("Slider Option", "Description for slider option.", 0.0, 100.0);
|
||||
ext_config_sub_menu->add_slider_option("Option B", "Description for option B.", 0.0, 100.0);
|
||||
ext_config_sub_menu->add_slider_option("Option C", "Description for option C.", 0.0, 100.0);
|
||||
ext_config_sub_menu->add_slider_option("Option D", "Description for option D.", 0.0, 100.0);
|
||||
ext_config_sub_menu->add_slider_option("Option E", "Description for option E.", 0.0, 100.0);
|
||||
ext_config_sub_menu->add_slider_option("Option F", "Description for option F.", 0.0, 100.0);
|
||||
ext_config_sub_menu->add_slider_option("Option G", "Description for option G.", 0.0, 100.0);
|
||||
ext_config_sub_menu->add_slider_option("Option H", "Description for option H.", 0.0, 100.0);
|
||||
ext_config_sub_menu->add_slider_option("Option J", "Description for option J.", 0.0, 100.0);
|
||||
ext_config_sub_menu->add_slider_option("Option K", "Description for option K.", 0.0, 100.0);
|
||||
ext_config_sub_menu->add_text_option("Text Option", "Description for simple option.");
|
||||
ext_config_sub_menu->enter(mod_details[active_mod_index].mod_id);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user