mirror of
https://github.com/Mr-Wiseguy/Zelda64Recomp.git
synced 2025-03-12 06:48:49 +01:00
Config submenu.
This commit is contained in:
parent
5c11adda89
commit
f153fd1b8f
@ -156,6 +156,7 @@ set (SOURCES
|
||||
${CMAKE_SOURCE_DIR}/src/ui/ui_renderer.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/ui/ui_launcher.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/ui/ui_config.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/ui/ui_config_sub_menu.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/ui/ui_color_hack.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/ui/ui_rml_hacks.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/ui/ui_elements.cpp
|
||||
@ -176,11 +177,14 @@ set (SOURCES
|
||||
${CMAKE_SOURCE_DIR}/src/ui/elements/ElementOptionTypeTextField.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/ui/elements/presets.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/ui/elements/ui_button.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/ui/elements/ui_clickable.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/ui/elements/ui_container.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/ui/elements/ui_element.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/ui/elements/ui_image.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/ui/elements/ui_label.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/ui/elements/ui_radio.cpp
|
||||
${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_toggle.cpp
|
||||
|
||||
|
@ -20,14 +20,14 @@
|
||||
}
|
||||
.col {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
<link type="text/template" href="config_menu/general.rml" />
|
||||
<link type="text/template" href="config_menu/controls.rml" />
|
||||
<link type="text/template" href="config_menu/graphics.rml" />
|
||||
<link type="text/template" href="config_menu/sound.rml" />
|
||||
<link type="text/template" href="config_menu/mods.rml" />
|
||||
<link type="text/template" href="config_menu/sound.rml" />
|
||||
<link type="text/template" href="config_menu/mods.rml" />
|
||||
<link type="text/template" href="config_menu/debug.rml" />
|
||||
<link type="text/template" href="config_menu/cheats.rml" />
|
||||
<link type="text/template" href="components/prompt.rml" />
|
||||
@ -104,6 +104,7 @@
|
||||
<svg src="icons/X.svg" />
|
||||
</button>
|
||||
</div>
|
||||
<recomp-config-sub-menu id="config_sub_menu" />
|
||||
</div>
|
||||
<div
|
||||
class="centered-page__controls"
|
||||
|
@ -3,7 +3,7 @@
|
||||
</head>
|
||||
<body>
|
||||
<form class="config__form">
|
||||
<recomp-mod-menu />
|
||||
<recomp-mod-menu id="menu_mods" />
|
||||
</form>
|
||||
</body>
|
||||
</template>
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit b5bf23ddde92dc5bdbf3ab949cbab512fe866b31
|
||||
Subproject commit a893ea6386e0c842f90a726a53c9b9e888797519
|
45
src/ui/elements/ui_clickable.cpp
Normal file
45
src/ui/elements/ui_clickable.cpp
Normal file
@ -0,0 +1,45 @@
|
||||
#include "ui_clickable.h"
|
||||
|
||||
namespace recompui {
|
||||
|
||||
static const std::string_view hover_state = "hover";
|
||||
static const std::string_view disabled_state = "disabled";
|
||||
|
||||
Clickable::Clickable(Element *parent, bool draggable) : Element(parent, Events(EventType::Click, EventType::Hover, EventType::Enable, draggable ? EventType::Drag : EventType::None)) {
|
||||
if (draggable) {
|
||||
set_drag(Drag::Drag);
|
||||
}
|
||||
}
|
||||
|
||||
void Clickable::process_event(const Event &e) {
|
||||
switch (e.type) {
|
||||
case EventType::Click:
|
||||
for (const auto &function : pressed_callbacks) {
|
||||
function(e.click.mouse.x, e.click.mouse.y);
|
||||
}
|
||||
break;
|
||||
case EventType::Hover:
|
||||
set_style_enabled(hover_state, e.hover.active);
|
||||
break;
|
||||
case EventType::Enable:
|
||||
set_style_enabled(disabled_state, !e.enable.enable);
|
||||
break;
|
||||
case EventType::Drag:
|
||||
for (const auto &function : dragged_callbacks) {
|
||||
function(e.drag.mouse.x, e.drag.mouse.y, e.drag.phase);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Clickable::add_pressed_callback(std::function<void(float, float)> callback) {
|
||||
pressed_callbacks.emplace_back(callback);
|
||||
}
|
||||
|
||||
void Clickable::add_dragged_callback(std::function<void(float, float, DragPhase)> callback) {
|
||||
dragged_callbacks.emplace_back(callback);
|
||||
}
|
||||
|
||||
};
|
20
src/ui/elements/ui_clickable.h
Normal file
20
src/ui/elements/ui_clickable.h
Normal file
@ -0,0 +1,20 @@
|
||||
#pragma once
|
||||
|
||||
#include "ui_element.h"
|
||||
|
||||
namespace recompui {
|
||||
|
||||
class Clickable : public Element {
|
||||
protected:
|
||||
std::vector<std::function<void(float, float)>> pressed_callbacks;
|
||||
std::vector<std::function<void(float, float, DragPhase)>> dragged_callbacks;
|
||||
|
||||
// Element overrides.
|
||||
virtual void process_event(const Event &e) override;
|
||||
public:
|
||||
Clickable(Element *parent, bool draggable = false);
|
||||
void add_pressed_callback(std::function<void(float, float)> callback);
|
||||
void add_dragged_callback(std::function<void(float, float, DragPhase)> callback);
|
||||
};
|
||||
|
||||
} // namespace recompui
|
@ -16,6 +16,7 @@ Element::Element(Rml::Element *base) {
|
||||
Element::Element(Element* parent, uint32_t events_enabled, Rml::String base_class) {
|
||||
ContextId context = get_current_context();
|
||||
base_owning = context.get_document()->CreateElement(base_class);
|
||||
|
||||
if (parent != nullptr) {
|
||||
base = parent->base->AppendChild(std::move(base_owning));
|
||||
parent->add_child(this);
|
||||
@ -82,6 +83,12 @@ void Element::register_event_listeners(uint32_t events_enabled) {
|
||||
base->AddEventListener(Rml::EventId::Mouseover, this);
|
||||
base->AddEventListener(Rml::EventId::Mouseout, this);
|
||||
}
|
||||
|
||||
if (events_enabled & Events(EventType::Drag)) {
|
||||
base->AddEventListener(Rml::EventId::Drag, this);
|
||||
base->AddEventListener(Rml::EventId::Dragstart, this);
|
||||
base->AddEventListener(Rml::EventId::Dragend, this);
|
||||
}
|
||||
}
|
||||
|
||||
void Element::apply_style(Style *style) {
|
||||
@ -135,6 +142,9 @@ void Element::ProcessEvent(Rml::Event &event) {
|
||||
case Rml::EventId::Mousedown:
|
||||
process_event(Event::click_event(event.GetParameter("mouse_x", 0.0f), event.GetParameter("mouse_y", 0.0f)));
|
||||
break;
|
||||
case Rml::EventId::Drag:
|
||||
process_event(Event::drag_event(event.GetParameter("mouse_x", 0.0f), event.GetParameter("mouse_y", 0.0f), DragPhase::Move));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -154,6 +164,12 @@ void Element::ProcessEvent(Rml::Event &event) {
|
||||
case Rml::EventId::Blur:
|
||||
process_event(Event::focus_event(false));
|
||||
break;
|
||||
case Rml::EventId::Dragstart:
|
||||
process_event(Event::drag_event(event.GetParameter("mouse_x", 0.0f), event.GetParameter("mouse_y", 0.0f), DragPhase::Start));
|
||||
break;
|
||||
case Rml::EventId::Dragend:
|
||||
process_event(Event::drag_event(event.GetParameter("mouse_x", 0.0f), event.GetParameter("mouse_y", 0.0f), DragPhase::End));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -212,10 +228,10 @@ bool Element::is_enabled() const {
|
||||
}
|
||||
|
||||
void Element::set_text(const std::string &text) {
|
||||
base->SetInnerRML(text);
|
||||
base->SetInnerRML(std::string(text));
|
||||
}
|
||||
|
||||
void Element::set_style_enabled(const std::string_view &style_name, bool enable) {
|
||||
void Element::set_style_enabled(std::string_view style_name, bool enable) {
|
||||
if (enable && style_active_set.find(style_name) == style_active_set.end()) {
|
||||
// Style was disabled and will be enabled.
|
||||
style_active_set.emplace(style_name);
|
||||
@ -243,4 +259,28 @@ void Element::set_style_enabled(const std::string_view &style_name, bool enable)
|
||||
apply_styles();
|
||||
}
|
||||
|
||||
};
|
||||
float Element::get_absolute_left() {
|
||||
return base->GetAbsoluteLeft();
|
||||
}
|
||||
|
||||
float Element::get_absolute_top() {
|
||||
return base->GetAbsoluteTop();
|
||||
}
|
||||
|
||||
float Element::get_client_left() {
|
||||
return base->GetClientLeft();
|
||||
}
|
||||
|
||||
float Element::get_client_top() {
|
||||
return base->GetClientTop();
|
||||
}
|
||||
|
||||
float Element::get_client_width() {
|
||||
return base->GetClientWidth();
|
||||
}
|
||||
|
||||
float Element::get_client_height() {
|
||||
return base->GetClientHeight();
|
||||
}
|
||||
|
||||
}
|
@ -43,14 +43,19 @@ public:
|
||||
Element(Element* parent, uint32_t events_enabled = 0, Rml::String base_class = "div");
|
||||
virtual ~Element();
|
||||
void clear_children();
|
||||
void add_style(Style *style, const std::string_view style_name);
|
||||
void add_style(Style *style, std::string_view style_name);
|
||||
void add_style(Style *style, const std::initializer_list<std::string_view> &style_names);
|
||||
void set_enabled(bool enabled);
|
||||
bool is_enabled() const;
|
||||
void set_text(const std::string &text);
|
||||
void set_style_enabled(const std::string_view &style_name, bool enabled);
|
||||
|
||||
void set_style_enabled(std::string_view style_name, bool enabled);
|
||||
bool is_element() override { return true; }
|
||||
float get_absolute_left();
|
||||
float get_absolute_top();
|
||||
float get_client_left();
|
||||
float get_client_top();
|
||||
float get_client_width();
|
||||
float get_client_height();
|
||||
};
|
||||
|
||||
} // namespace recompui
|
5
src/ui/elements/ui_radio.cpp
Normal file
5
src/ui/elements/ui_radio.cpp
Normal file
@ -0,0 +1,5 @@
|
||||
#include "ui_radio.h"
|
||||
|
||||
namespace recompui {
|
||||
|
||||
};
|
7
src/ui/elements/ui_radio.h
Normal file
7
src/ui/elements/ui_radio.h
Normal file
@ -0,0 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "ui_element.h"
|
||||
|
||||
namespace recompui {
|
||||
|
||||
} // namespace recompui
|
142
src/ui/elements/ui_slider.cpp
Normal file
142
src/ui/elements/ui_slider.cpp
Normal file
@ -0,0 +1,142 @@
|
||||
#include "ui_slider.h"
|
||||
|
||||
#include <charconv>
|
||||
|
||||
namespace recompui {
|
||||
|
||||
void Slider::set_value_internal(double v, bool setup, bool trigger_callbacks) {
|
||||
if (step_value != 0.0) {
|
||||
v = std::lround(v / step_value) * step_value;
|
||||
}
|
||||
|
||||
if (value != v || setup) {
|
||||
value = v;
|
||||
update_circle_position();
|
||||
update_label_text();
|
||||
|
||||
if (trigger_callbacks) {
|
||||
for (auto callback : value_changed_callbacks) {
|
||||
callback(v);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Slider::bar_clicked(float x, float) {
|
||||
update_value_from_mouse(x);
|
||||
}
|
||||
|
||||
void Slider::bar_dragged(float x, float, DragPhase) {
|
||||
update_value_from_mouse(x);
|
||||
}
|
||||
|
||||
void Slider::circle_dragged(float x, float, DragPhase) {
|
||||
update_value_from_mouse(x);
|
||||
}
|
||||
|
||||
void Slider::update_value_from_mouse(float x) {
|
||||
double left = slider_element->get_absolute_left();
|
||||
double width = slider_element->get_client_width();
|
||||
double ratio = std::clamp((x - left) / width, 0.0, 1.0);
|
||||
set_value_internal(min_value + ratio * (max_value - min_value), false, true);
|
||||
}
|
||||
|
||||
void Slider::update_circle_position() {
|
||||
double ratio = std::clamp((value - min_value) / (max_value - min_value), 0.0, 1.0);
|
||||
circle_element->set_left(slider_width_dp * ratio);
|
||||
}
|
||||
|
||||
void Slider::update_label_text() {
|
||||
char text_buffer[32];
|
||||
int precision = type == SliderType::Double ? 1 : 0;
|
||||
auto result = std::to_chars(text_buffer, text_buffer + sizeof(text_buffer) - 1, value, std::chars_format::fixed, precision);
|
||||
if (result.ec == std::errc()) {
|
||||
if (type == SliderType::Percent) {
|
||||
*result.ptr = '%';
|
||||
result.ptr++;
|
||||
}
|
||||
|
||||
value_label->set_text(std::string(text_buffer, result.ptr));
|
||||
}
|
||||
}
|
||||
|
||||
Slider::Slider(SliderType type, Element *parent) : Element(parent) {
|
||||
this->type = type;
|
||||
|
||||
set_display(Display::Flex);
|
||||
set_flex(1.0f, 1.0f, 100.0f, Unit::Percent);
|
||||
set_flex_direction(FlexDirection::Row);
|
||||
|
||||
value_label = new Label("0", LabelStyle::Small, this);
|
||||
value_label->set_margin_right(20.0f);
|
||||
value_label->set_min_width(60.0f);
|
||||
value_label->set_max_width(60.0f);
|
||||
|
||||
slider_element = new Element(this);
|
||||
slider_element->set_width(slider_width_dp);
|
||||
|
||||
{
|
||||
bar_element = new Clickable(slider_element, true);
|
||||
bar_element->set_width(100.0f, Unit::Percent);
|
||||
bar_element->set_height(2.0f);
|
||||
bar_element->set_margin_top(8.0f);
|
||||
bar_element->set_background_color(Color{ 255, 255, 255, 50 });
|
||||
bar_element->add_pressed_callback(std::bind(&Slider::bar_clicked, this, std::placeholders::_1, std::placeholders::_2));
|
||||
bar_element->add_dragged_callback(std::bind(&Slider::bar_dragged, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
|
||||
|
||||
circle_element = new Clickable(slider_element, true);
|
||||
circle_element->set_position(Position::Relative);
|
||||
circle_element->set_width(16.0f);
|
||||
circle_element->set_height(16.0f);
|
||||
circle_element->set_margin_top(-8.0f);
|
||||
circle_element->set_margin_right(-8.0f);
|
||||
circle_element->set_margin_left(-8.0f);
|
||||
circle_element->set_background_color(Color{ 204, 204, 204, 255 });
|
||||
circle_element->set_border_radius(8.0f);
|
||||
circle_element->add_dragged_callback(std::bind(&Slider::circle_dragged, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
|
||||
circle_element->set_cursor(Cursor::Pointer);
|
||||
}
|
||||
|
||||
set_value_internal(value, true, false);
|
||||
}
|
||||
|
||||
Slider::~Slider() {
|
||||
|
||||
}
|
||||
|
||||
void Slider::set_value(double v) {
|
||||
set_value_internal(v, false, false);
|
||||
}
|
||||
|
||||
double Slider::get_value() const {
|
||||
return value;
|
||||
}
|
||||
void Slider::set_min_value(double v) {
|
||||
min_value = v;
|
||||
}
|
||||
|
||||
double Slider::get_min_value() const {
|
||||
return min_value;
|
||||
}
|
||||
|
||||
void Slider::set_max_value(double v) {
|
||||
max_value = v;
|
||||
}
|
||||
|
||||
double Slider::get_max_value() const {
|
||||
return max_value;
|
||||
}
|
||||
|
||||
void Slider::set_step_value(double v) {
|
||||
step_value = v;
|
||||
}
|
||||
|
||||
double Slider::get_step_value() const {
|
||||
return step_value;
|
||||
}
|
||||
|
||||
void Slider::add_value_changed_callback(std::function<void(double)> callback) {
|
||||
value_changed_callbacks.emplace_back(callback);
|
||||
}
|
||||
|
||||
} // namespace recompui
|
50
src/ui/elements/ui_slider.h
Normal file
50
src/ui/elements/ui_slider.h
Normal file
@ -0,0 +1,50 @@
|
||||
#pragma once
|
||||
|
||||
#include "ui_clickable.h"
|
||||
#include "ui_label.h"
|
||||
|
||||
namespace recompui {
|
||||
|
||||
enum SliderType {
|
||||
Double,
|
||||
Percent,
|
||||
Integer
|
||||
};
|
||||
|
||||
class Slider : public Element {
|
||||
private:
|
||||
SliderType type = SliderType::Percent;
|
||||
Label *value_label = nullptr;
|
||||
Element *slider_element = nullptr;
|
||||
Clickable *bar_element = nullptr;
|
||||
Clickable *circle_element = nullptr;
|
||||
double value = 50.0;
|
||||
double min_value = 0.0;
|
||||
double max_value = 100.0;
|
||||
double step_value = 1.0;
|
||||
float slider_width_dp = 300.0;
|
||||
std::vector<std::function<void(double)>> value_changed_callbacks;
|
||||
|
||||
void set_value_internal(double v, bool setup, bool trigger_callbacks);
|
||||
void bar_clicked(float x, float y);
|
||||
void bar_dragged(float x, float y, DragPhase phase);
|
||||
void circle_dragged(float x, float y, DragPhase phase);
|
||||
void update_value_from_mouse(float x);
|
||||
void update_circle_position();
|
||||
void update_label_text();
|
||||
|
||||
public:
|
||||
Slider(SliderType type, Element *parent);
|
||||
virtual ~Slider();
|
||||
void set_value(double v);
|
||||
double get_value() const;
|
||||
void set_min_value(double v);
|
||||
double get_min_value() const;
|
||||
void set_max_value(double v);
|
||||
double get_max_value() const;
|
||||
void set_step_value(double v);
|
||||
double get_step_value() const;
|
||||
void add_value_changed_callback(std::function<void(double)> callback);
|
||||
};
|
||||
|
||||
} // namespace recompui
|
@ -67,6 +67,24 @@ namespace recompui {
|
||||
}
|
||||
}
|
||||
|
||||
static Rml::Style::Drag to_rml(Drag drag) {
|
||||
switch (drag) {
|
||||
case Drag::None:
|
||||
return Rml::Style::Drag::None;
|
||||
case Drag::Drag:
|
||||
return Rml::Style::Drag::Drag;
|
||||
case Drag::DragDrop:
|
||||
return Rml::Style::Drag::DragDrop;
|
||||
case Drag::Block:
|
||||
return Rml::Style::Drag::Block;
|
||||
case Drag::Clone:
|
||||
return Rml::Style::Drag::Clone;
|
||||
default:
|
||||
assert(false && "Unknown drag.");
|
||||
return Rml::Style::Drag::None;
|
||||
}
|
||||
}
|
||||
|
||||
void Style::set_property(Rml::PropertyId property_id, const Rml::Property &property, Animation) {
|
||||
property_map[property_id] = property;
|
||||
}
|
||||
@ -437,4 +455,8 @@ namespace recompui {
|
||||
set_property(Rml::PropertyId::ColumnGap, Rml::Property(size, to_rml(unit)), animation);
|
||||
}
|
||||
|
||||
void Style::set_drag(Drag drag) {
|
||||
set_property(Rml::PropertyId::Drag, to_rml(drag), Animation());
|
||||
}
|
||||
|
||||
} // namespace recompui
|
@ -82,7 +82,7 @@ namespace recompui {
|
||||
void set_gap(float size, Unit unit = Unit::Dp, Animation animation = Animation());
|
||||
void set_row_gap(float size, Unit unit = Unit::Dp, Animation animation = Animation());
|
||||
void set_column_gap(float size, Unit unit = Unit::Dp, Animation animation = Animation());
|
||||
|
||||
void set_drag(Drag drag);
|
||||
virtual bool is_element() { return false; }
|
||||
ResourceId get_resource_id() { return resource_id; }
|
||||
};
|
||||
|
@ -46,16 +46,16 @@ namespace recompui {
|
||||
floater->add_style(&floater_disabled_style, disabled_state);
|
||||
floater->add_style(&floater_disabled_checked_style, { checked_state, disabled_state });
|
||||
|
||||
set_checked_internal(false, false, true);
|
||||
set_checked_internal(false, false, true, false);
|
||||
}
|
||||
|
||||
void Toggle::set_checked_internal(bool checked, bool animate, bool setup) {
|
||||
void Toggle::set_checked_internal(bool checked, bool animate, bool setup, bool trigger_callbacks) {
|
||||
if (this->checked != checked || setup) {
|
||||
this->checked = checked;
|
||||
|
||||
floater->set_left(floater_left_target(), Unit::Dp, animate ? Animation::tween(0.1f) : Animation::set());
|
||||
|
||||
if (!setup) {
|
||||
if (trigger_callbacks) {
|
||||
for (const auto &function : checked_callbacks) {
|
||||
function(checked);
|
||||
}
|
||||
@ -74,7 +74,7 @@ namespace recompui {
|
||||
switch (e.type) {
|
||||
case EventType::Click:
|
||||
if (is_enabled()) {
|
||||
set_checked_internal(!checked, true, false);
|
||||
set_checked_internal(!checked, true, false, true);
|
||||
}
|
||||
|
||||
break;
|
||||
@ -93,7 +93,7 @@ namespace recompui {
|
||||
}
|
||||
|
||||
void Toggle::set_checked(bool checked) {
|
||||
set_checked_internal(checked, false, false);
|
||||
set_checked_internal(checked, false, false, false);
|
||||
}
|
||||
|
||||
bool Toggle::is_checked() const {
|
||||
|
@ -18,7 +18,7 @@ namespace recompui {
|
||||
Style floater_disabled_checked_style;
|
||||
bool checked = false;
|
||||
|
||||
void set_checked_internal(bool checked, bool animate, bool setup);
|
||||
void set_checked_internal(bool checked, bool animate, bool setup, bool trigger_callbacks);
|
||||
float floater_left_target() const;
|
||||
|
||||
// Element overrides.
|
||||
|
@ -22,9 +22,17 @@ namespace recompui {
|
||||
Focus,
|
||||
Hover,
|
||||
Enable,
|
||||
Drag,
|
||||
Count
|
||||
};
|
||||
|
||||
enum class DragPhase {
|
||||
None,
|
||||
Start,
|
||||
Move,
|
||||
End
|
||||
};
|
||||
|
||||
template <typename Enum, typename = std::enable_if_t<std::is_enum_v<Enum>>>
|
||||
constexpr uint32_t Events(Enum first) {
|
||||
return 1u << static_cast<uint32_t>(first);
|
||||
@ -44,6 +52,8 @@ namespace recompui {
|
||||
EventType type;
|
||||
|
||||
union {
|
||||
uint64_t raw;
|
||||
|
||||
struct {
|
||||
Mouse mouse;
|
||||
} click;
|
||||
@ -59,6 +69,11 @@ namespace recompui {
|
||||
struct {
|
||||
bool enable;
|
||||
} enable;
|
||||
|
||||
struct {
|
||||
Mouse mouse;
|
||||
DragPhase phase;
|
||||
} drag;
|
||||
};
|
||||
|
||||
static Event click_event(float x, float y) {
|
||||
@ -89,6 +104,15 @@ namespace recompui {
|
||||
e.enable.enable = enable;
|
||||
return e;
|
||||
}
|
||||
|
||||
static Event drag_event(float x, float y, DragPhase phase) {
|
||||
Event e = {};
|
||||
e.type = EventType::Drag;
|
||||
e.drag.mouse.x = x;
|
||||
e.drag.mouse.y = y;
|
||||
e.drag.phase = phase;
|
||||
return e;
|
||||
}
|
||||
};
|
||||
|
||||
enum class Display {
|
||||
@ -154,6 +178,14 @@ namespace recompui {
|
||||
Justify
|
||||
};
|
||||
|
||||
enum class Drag {
|
||||
None,
|
||||
Drag,
|
||||
DragDrop,
|
||||
Block,
|
||||
Clone
|
||||
};
|
||||
|
||||
struct Animation {
|
||||
AnimationType type = AnimationType::None;
|
||||
float duration = 0.0f;
|
||||
|
200
src/ui/ui_config_sub_menu.cpp
Normal file
200
src/ui/ui_config_sub_menu.cpp
Normal file
@ -0,0 +1,200 @@
|
||||
#include "ui_config_sub_menu.h"
|
||||
|
||||
#include <cassert>
|
||||
|
||||
namespace recompui {
|
||||
|
||||
// ConfigOptionElement
|
||||
|
||||
|
||||
void ConfigOptionElement::process_event(const Event &e) {
|
||||
switch (e.type) {
|
||||
case EventType::Hover:
|
||||
hover_callback(this, e.hover.active);
|
||||
break;
|
||||
default:
|
||||
assert(false && "Unknown event type.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ConfigOptionElement::ConfigOptionElement(Element *parent) : Element(parent, Events(EventType::Hover)) {
|
||||
set_min_height(100.0f);
|
||||
|
||||
name_label = new Label(LabelStyle::Normal, this);
|
||||
}
|
||||
|
||||
ConfigOptionElement::~ConfigOptionElement() {
|
||||
|
||||
}
|
||||
|
||||
void ConfigOptionElement::set_name(std::string_view name) {
|
||||
this->name = name;
|
||||
name_label->set_text(name);
|
||||
}
|
||||
|
||||
void ConfigOptionElement::set_description(std::string_view description) {
|
||||
this->description = description;
|
||||
}
|
||||
|
||||
void ConfigOptionElement::set_hover_callback(std::function<void(ConfigOptionElement *, bool)> callback) {
|
||||
hover_callback = callback;
|
||||
}
|
||||
|
||||
const std::string &ConfigOptionElement::get_description() const {
|
||||
return description;
|
||||
}
|
||||
|
||||
// ConfigOptionSlider
|
||||
|
||||
void ConfigOptionSlider::slider_value_changed(double v) {
|
||||
// TODO: Hook up to whatever API Recomp exposes to set the value of the persisent configuration in mods.
|
||||
printf("%s changed to %f.\n", name.c_str(), v);
|
||||
}
|
||||
|
||||
ConfigOptionSlider::ConfigOptionSlider(Element *parent) : ConfigOptionElement(parent) {
|
||||
slider = new Slider(SliderType::Percent, this);
|
||||
slider->add_value_changed_callback(std::bind(&ConfigOptionSlider::slider_value_changed, this, std::placeholders::_1));
|
||||
}
|
||||
|
||||
ConfigOptionSlider::~ConfigOptionSlider() {
|
||||
|
||||
}
|
||||
|
||||
void ConfigOptionSlider::set_value(double v) {
|
||||
slider->set_value(v);
|
||||
}
|
||||
|
||||
void ConfigOptionSlider::set_min_value(double v) {
|
||||
slider->set_min_value(v);
|
||||
}
|
||||
|
||||
void ConfigOptionSlider::set_max_value(double v) {
|
||||
slider->set_max_value(v);
|
||||
}
|
||||
|
||||
// ConfigSubMenu
|
||||
|
||||
void ConfigSubMenu::back_button_pressed() {
|
||||
if (quit_sub_menu_callback != nullptr) {
|
||||
quit_sub_menu_callback();
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigSubMenu::option_hovered(ConfigOptionElement *option, bool active) {
|
||||
if (active) {
|
||||
hover_option_elements.emplace(option);
|
||||
}
|
||||
else {
|
||||
hover_option_elements.erase(option);
|
||||
}
|
||||
|
||||
if (hover_option_elements.empty()) {
|
||||
description_label->set_text("");
|
||||
}
|
||||
else {
|
||||
description_label->set_text((*hover_option_elements.begin())->get_description());
|
||||
}
|
||||
}
|
||||
|
||||
ConfigSubMenu::ConfigSubMenu(Element *parent) : Element(parent) {
|
||||
set_display(Display::Flex);
|
||||
set_flex(1, 1, 100.0f, Unit::Percent);
|
||||
set_flex_direction(FlexDirection::Column);
|
||||
set_height(100.0f, Unit::Percent);
|
||||
|
||||
header_container = new Container(FlexDirection::Row, JustifyContent::FlexStart, this);
|
||||
|
||||
{
|
||||
back_button = new Button("Back", ButtonStyle::Secondary, header_container);
|
||||
back_button->add_pressed_callback(std::bind(&ConfigSubMenu::back_button_pressed, this));
|
||||
title_label = new Label("Title", LabelStyle::Large, header_container);
|
||||
}
|
||||
|
||||
body_container = new Container(FlexDirection::Row, JustifyContent::SpaceEvenly, this);
|
||||
{
|
||||
config_container = new Container(FlexDirection::Column, JustifyContent::Center, body_container);
|
||||
config_container->set_display(Display::Block);
|
||||
config_container->set_flex_basis(100.0f);
|
||||
config_container->set_align_items(AlignItems::Center);
|
||||
{
|
||||
config_scroll_container = new ScrollContainer(ScrollDirection::Vertical, config_container);
|
||||
}
|
||||
|
||||
description_label = new Label("Description", LabelStyle::Small, body_container);
|
||||
description_label->set_min_width(800.0f);
|
||||
}
|
||||
}
|
||||
|
||||
ConfigSubMenu::~ConfigSubMenu() {
|
||||
|
||||
}
|
||||
|
||||
void ConfigSubMenu::enter(std::string_view title) {
|
||||
title_label->set_text(title);
|
||||
|
||||
if (enter_sub_menu_callback != nullptr) {
|
||||
enter_sub_menu_callback();
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigSubMenu::clear_options() {
|
||||
config_scroll_container->clear_children();
|
||||
config_option_elements.clear();
|
||||
hover_option_elements.clear();
|
||||
}
|
||||
|
||||
void ConfigSubMenu::add_option(ConfigOptionElement *option, std::string_view name, std::string_view description) {
|
||||
option->set_name(name);
|
||||
option->set_description(description);
|
||||
option->set_hover_callback(std::bind(&ConfigSubMenu::option_hovered, this, std::placeholders::_1, std::placeholders::_2));
|
||||
config_option_elements.emplace_back(option);
|
||||
}
|
||||
|
||||
void ConfigSubMenu::add_slider_option(std::string_view name, std::string_view description, double min, double max) {
|
||||
ConfigOptionSlider *option_slider = new ConfigOptionSlider(config_scroll_container);
|
||||
option_slider->set_min_value(min);
|
||||
option_slider->set_max_value(max);
|
||||
add_option(option_slider, name, description);
|
||||
}
|
||||
|
||||
void ConfigSubMenu::set_enter_sub_menu_callback(std::function<void()> callback) {
|
||||
enter_sub_menu_callback = callback;
|
||||
}
|
||||
|
||||
void ConfigSubMenu::set_quit_sub_menu_callback(std::function<void()> callback) {
|
||||
quit_sub_menu_callback = callback;
|
||||
}
|
||||
|
||||
// ElementConfigSubMenu
|
||||
|
||||
ElementConfigSubMenu::ElementConfigSubMenu(const Rml::String &tag) : Rml::Element(tag) {
|
||||
SetProperty(Rml::PropertyId::Display, Rml::Style::Display::None);
|
||||
SetProperty("width", "100%");
|
||||
SetProperty("height", "100%");
|
||||
|
||||
recompui::Element this_compat(this);
|
||||
config_sub_menu = std::make_unique<ConfigSubMenu>(&this_compat);
|
||||
}
|
||||
|
||||
ElementConfigSubMenu::~ElementConfigSubMenu() {
|
||||
|
||||
}
|
||||
|
||||
void ElementConfigSubMenu::set_display(bool display) {
|
||||
SetProperty(Rml::PropertyId::Display, display ? Rml::Style::Display::Block : Rml::Style::Display::None);
|
||||
}
|
||||
|
||||
void ElementConfigSubMenu::set_enter_sub_menu_callback(std::function<void()> callback) {
|
||||
config_sub_menu->set_enter_sub_menu_callback(callback);
|
||||
}
|
||||
|
||||
void ElementConfigSubMenu::set_quit_sub_menu_callback(std::function<void()> callback) {
|
||||
config_sub_menu->set_quit_sub_menu_callback(callback);
|
||||
}
|
||||
|
||||
ConfigSubMenu *ElementConfigSubMenu::get_config_sub_menu_element() const {
|
||||
return config_sub_menu.get();
|
||||
}
|
||||
|
||||
}
|
85
src/ui/ui_config_sub_menu.h
Normal file
85
src/ui/ui_config_sub_menu.h
Normal file
@ -0,0 +1,85 @@
|
||||
#ifndef RECOMPUI_CONFIG_SUB_MENU_H
|
||||
#define RECOMPUI_CONFIG_SUB_MENU_H
|
||||
|
||||
#include <span>
|
||||
|
||||
#include "elements/ui_button.h"
|
||||
#include "elements/ui_container.h"
|
||||
#include "elements/ui_label.h"
|
||||
#include "elements/ui_scroll_container.h"
|
||||
#include "elements/ui_slider.h"
|
||||
|
||||
namespace recompui {
|
||||
|
||||
class ConfigOptionElement : public Element {
|
||||
protected:
|
||||
Label *name_label = nullptr;
|
||||
std::string name;
|
||||
std::string description;
|
||||
std::function<void(ConfigOptionElement *, bool)> hover_callback = nullptr;
|
||||
|
||||
virtual void process_event(const Event &e) override;
|
||||
public:
|
||||
ConfigOptionElement(Element *parent);
|
||||
virtual ~ConfigOptionElement();
|
||||
void set_name(std::string_view name);
|
||||
void set_description(std::string_view description);
|
||||
void set_hover_callback(std::function<void(ConfigOptionElement *, bool)> callback);
|
||||
const std::string &get_description() const;
|
||||
};
|
||||
|
||||
class ConfigOptionSlider : public ConfigOptionElement {
|
||||
protected:
|
||||
Slider *slider = nullptr;
|
||||
|
||||
void slider_value_changed(double v);
|
||||
public:
|
||||
ConfigOptionSlider(Element *parent);
|
||||
virtual ~ConfigOptionSlider();
|
||||
void set_value(double v);
|
||||
void set_min_value(double v);
|
||||
void set_max_value(double v);
|
||||
};
|
||||
|
||||
class ConfigSubMenu : public Element {
|
||||
private:
|
||||
Container *header_container = nullptr;
|
||||
Button *back_button = nullptr;
|
||||
Label *title_label = nullptr;
|
||||
Container *body_container = nullptr;
|
||||
Label *description_label = nullptr;
|
||||
Container *config_container = nullptr;
|
||||
ScrollContainer *config_scroll_container = nullptr;
|
||||
std::function<void()> enter_sub_menu_callback = nullptr;
|
||||
std::function<void()> quit_sub_menu_callback = nullptr;
|
||||
std::vector<ConfigOptionElement *> config_option_elements;
|
||||
std::unordered_set<ConfigOptionElement *> hover_option_elements;
|
||||
|
||||
void back_button_pressed();
|
||||
void option_hovered(ConfigOptionElement *option, bool active);
|
||||
void add_option(ConfigOptionElement *option, std::string_view name, std::string_view description);
|
||||
|
||||
public:
|
||||
ConfigSubMenu(Element *parent);
|
||||
virtual ~ConfigSubMenu();
|
||||
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 set_enter_sub_menu_callback(std::function<void()> callback);
|
||||
void set_quit_sub_menu_callback(std::function<void()> callback);
|
||||
};
|
||||
|
||||
class ElementConfigSubMenu : public Rml::Element {
|
||||
public:
|
||||
ElementConfigSubMenu(const Rml::String &tag);
|
||||
virtual ~ElementConfigSubMenu();
|
||||
void set_display(bool display);
|
||||
void set_enter_sub_menu_callback(std::function<void()> callback);
|
||||
void set_quit_sub_menu_callback(std::function<void()> callback);
|
||||
ConfigSubMenu *get_config_sub_menu_element() const;
|
||||
private:
|
||||
std::unique_ptr<ConfigSubMenu> config_sub_menu;
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
@ -20,6 +20,7 @@ static RecompElementConfig custom_elements[] = {
|
||||
CUSTOM_ELEMENT("recomp-option-type-radio-tabs", recompui::ElementOptionTypeRadioTabs),
|
||||
CUSTOM_ELEMENT("recomp-option-type-range", recompui::ElementOptionTypeRange),
|
||||
CUSTOM_ELEMENT("recomp-mod-menu", recompui::ElementModMenu),
|
||||
CUSTOM_ELEMENT("recomp-config-sub-menu", recompui::ElementConfigSubMenu),
|
||||
};
|
||||
|
||||
void recompui::register_custom_elements() {
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "elements/ElementOptionTypeTextField.h"
|
||||
#include "elements/ElementDescription.h"
|
||||
#include "ui_mod_menu.h"
|
||||
#include "ui_config_sub_menu.h"
|
||||
|
||||
namespace recompui {
|
||||
void register_custom_elements();
|
||||
|
@ -59,6 +59,7 @@ ModDetailsPanel::ModDetailsPanel(Element *parent) : Element(parent) {
|
||||
enable_toggle = context.create_element<Toggle>(buttons_container);
|
||||
enable_toggle->add_checked_callback(std::bind(&ModDetailsPanel::enable_toggle_checked, this, std::placeholders::_1));
|
||||
configure_button = context.create_element<Button>("Configure", recompui::ButtonStyle::Secondary, buttons_container);
|
||||
configure_button->add_pressed_callback(std::bind(&ModDetailsPanel::configure_button_pressed, this));
|
||||
erase_button = context.create_element<Button>("Erase", recompui::ButtonStyle::Secondary, buttons_container);
|
||||
}
|
||||
}
|
||||
@ -89,10 +90,20 @@ void ModDetailsPanel::set_mod_toggled_callback(std::function<void(bool)> callbac
|
||||
mod_toggled_callback = callback;
|
||||
}
|
||||
|
||||
void ModDetailsPanel::set_mod_configure_pressed_callback(std::function<void()> callback) {
|
||||
mod_configure_pressed_callback = callback;
|
||||
}
|
||||
|
||||
void ModDetailsPanel::enable_toggle_checked(bool checked) {
|
||||
if (mod_toggled_callback != nullptr) {
|
||||
mod_toggled_callback(checked);
|
||||
}
|
||||
}
|
||||
|
||||
void ModDetailsPanel::configure_button_pressed() {
|
||||
if (mod_configure_pressed_callback != nullptr) {
|
||||
mod_configure_pressed_callback();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace recompui
|
||||
|
@ -16,6 +16,7 @@ public:
|
||||
virtual ~ModDetailsPanel();
|
||||
void set_mod_details(const recomp::mods::ModDetails& details, bool mod_enabled, bool toggle_enabled);
|
||||
void set_mod_toggled_callback(std::function<void(bool)> callback);
|
||||
void set_mod_configure_pressed_callback(std::function<void()> callback);
|
||||
private:
|
||||
recomp::mods::ModDetails cur_details;
|
||||
Container *thumbnail_container = nullptr;
|
||||
@ -32,9 +33,11 @@ private:
|
||||
Toggle *enable_toggle = nullptr;
|
||||
Button *configure_button = nullptr;
|
||||
Button *erase_button = nullptr;
|
||||
std::function<void(bool)> mod_toggled_callback = {};
|
||||
std::function<void(bool)> mod_toggled_callback = nullptr;
|
||||
std::function<void()> mod_configure_pressed_callback = nullptr;
|
||||
|
||||
void enable_toggle_checked(bool checked);
|
||||
void configure_button_pressed();
|
||||
};
|
||||
|
||||
} // namespace recompui
|
||||
|
@ -81,6 +81,10 @@ void ModMenu::set_active_mod(int32_t mod_index) {
|
||||
}
|
||||
}
|
||||
|
||||
void ModMenu::set_config_sub_menu(ConfigSubMenu *config_sub_menu) {
|
||||
ext_config_sub_menu = config_sub_menu;
|
||||
}
|
||||
|
||||
void ModMenu::refresh_mods() {
|
||||
recomp::mods::scan_mods();
|
||||
mod_details = recomp::mods::get_mod_details(game_mod_id);
|
||||
@ -93,6 +97,24 @@ 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->enter(mod_details[active_mod_index].mod_id);
|
||||
}
|
||||
}
|
||||
|
||||
void ModMenu::create_mod_list() {
|
||||
ContextId context = get_current_context();
|
||||
|
||||
@ -140,6 +162,7 @@ ModMenu::ModMenu(Element *parent) : Element(parent) {
|
||||
|
||||
mod_details_panel = context.create_element<ModDetailsPanel>(body_container);
|
||||
mod_details_panel->set_mod_toggled_callback(std::bind(&ModMenu::mod_toggled, this, std::placeholders::_1));
|
||||
mod_details_panel->set_mod_configure_pressed_callback(std::bind(&ModMenu::mod_configure_requested, this));
|
||||
} // body_container
|
||||
|
||||
|
||||
@ -179,4 +202,8 @@ ElementModMenu::~ElementModMenu() {
|
||||
|
||||
}
|
||||
|
||||
void ElementModMenu::set_config_sub_menu(ConfigSubMenu *config_sub_menu) {
|
||||
mod_menu->set_config_sub_menu(config_sub_menu);
|
||||
}
|
||||
|
||||
} // namespace recompui
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
#include "librecomp/mods.hpp"
|
||||
#include "elements/ui_scroll_container.h"
|
||||
#include "ui_config_sub_menu.h"
|
||||
#include "ui_mod_details_panel.h"
|
||||
|
||||
namespace recompui {
|
||||
@ -29,9 +30,11 @@ public:
|
||||
ModMenu(Element *parent);
|
||||
virtual ~ModMenu();
|
||||
void set_active_mod(int32_t mod_index);
|
||||
void set_config_sub_menu(ConfigSubMenu *config_sub_menu);
|
||||
private:
|
||||
void refresh_mods();
|
||||
void mod_toggled(bool enabled);
|
||||
void mod_configure_requested();
|
||||
void create_mod_list();
|
||||
|
||||
Container *body_container = nullptr;
|
||||
@ -40,6 +43,7 @@ private:
|
||||
ModDetailsPanel *mod_details_panel = nullptr;
|
||||
Container *footer_container = nullptr;
|
||||
Button *refresh_button = nullptr;
|
||||
ConfigSubMenu *ext_config_sub_menu = nullptr;
|
||||
int32_t active_mod_index = -1;
|
||||
std::vector<ModEntry *> mod_entries;
|
||||
std::vector<recomp::mods::ModDetails> mod_details{};
|
||||
@ -50,6 +54,7 @@ class ElementModMenu : public Rml::Element {
|
||||
public:
|
||||
ElementModMenu(const Rml::String& tag);
|
||||
virtual ~ElementModMenu();
|
||||
void set_config_sub_menu(ConfigSubMenu *config_sub_menu);
|
||||
private:
|
||||
std::unique_ptr<ModMenu> mod_menu;
|
||||
};
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include "RmlUi_Platform_SDL.h"
|
||||
|
||||
#include "ui_elements.h"
|
||||
#include "ui_mod_menu.h"
|
||||
#include "librecomp/config.hpp"
|
||||
|
||||
#include "InterfaceVS.hlsl.spirv.h"
|
||||
@ -753,7 +754,7 @@ Rml::Element* find_autofocus_element(Rml::Element* start) {
|
||||
|
||||
struct UIContext {
|
||||
struct UIRenderContext render;
|
||||
class {
|
||||
class Context {
|
||||
std::unordered_map<recompui::Menu, std::unique_ptr<recompui::MenuController>> menus;
|
||||
std::unordered_map<recompui::Menu, Rml::ElementDocument*> documents;
|
||||
Rml::ElementDocument* current_document;
|
||||
@ -776,6 +777,10 @@ struct UIContext {
|
||||
}
|
||||
|
||||
void swap_document(recompui::Menu menu) {
|
||||
if (menu != recompui::Menu::Config) {
|
||||
quit_sub_menu();
|
||||
}
|
||||
|
||||
if (current_document != nullptr) {
|
||||
Rml::Element* window_el = current_document->GetElementById("window");
|
||||
if (window_el != nullptr) {
|
||||
@ -804,21 +809,77 @@ struct UIContext {
|
||||
mouse_is_active = false;
|
||||
mouse_is_active_changed = false;
|
||||
mouse_is_active_initialized = false;
|
||||
|
||||
if (menu == recompui::Menu::Config) {
|
||||
recompui::ElementModMenu *mods_menu = get_mods_menu();
|
||||
recompui::ElementConfigSubMenu *config_sub_menu = get_config_sub_menu();
|
||||
if (mods_menu != nullptr && config_sub_menu != nullptr) {
|
||||
mods_menu->set_config_sub_menu(config_sub_menu->get_config_sub_menu_element());
|
||||
config_sub_menu->set_enter_sub_menu_callback(std::bind(&Context::enter_sub_menu, this));
|
||||
config_sub_menu->set_quit_sub_menu_callback(std::bind(&Context::quit_sub_menu, this));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rml::ElementTabSet *get_config_tabset() {
|
||||
if (current_document != nullptr) {
|
||||
Rml::Element *config_tabset_base = current_document->GetElementById("config_tabset");
|
||||
if (config_tabset_base != nullptr) {
|
||||
return rmlui_dynamic_cast<Rml::ElementTabSet *>(config_tabset_base);
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
recompui::ElementModMenu *get_mods_menu() {
|
||||
if (current_document != nullptr) {
|
||||
Rml::Element *menu_mods_base = current_document->GetElementById("menu_mods");
|
||||
if (menu_mods_base != nullptr) {
|
||||
return rmlui_dynamic_cast<recompui::ElementModMenu *>(menu_mods_base);
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
recompui::ElementConfigSubMenu *get_config_sub_menu() {
|
||||
if (current_document != nullptr) {
|
||||
Rml::Element *config_sub_menu_base = current_document->GetElementById("config_sub_menu");
|
||||
if (config_sub_menu_base != nullptr) {
|
||||
return rmlui_dynamic_cast<recompui::ElementConfigSubMenu *>(config_sub_menu_base);
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void swap_config_menu(recompui::ConfigSubmenu submenu) {
|
||||
if (current_document != nullptr) {
|
||||
Rml::Element* config_tabset_base = current_document->GetElementById("config_tabset");
|
||||
if (config_tabset_base != nullptr) {
|
||||
Rml::ElementTabSet* config_tabset = rmlui_dynamic_cast<Rml::ElementTabSet*>(config_tabset_base);
|
||||
if (config_tabset != nullptr) {
|
||||
config_tabset->SetActiveTab(static_cast<int>(submenu));
|
||||
prev_focused = nullptr;
|
||||
mouse_is_active = false;
|
||||
mouse_is_active_changed = false;
|
||||
mouse_is_active_initialized = false;
|
||||
}
|
||||
}
|
||||
Rml::ElementTabSet* config_tabset = get_config_tabset();
|
||||
if (config_tabset != nullptr) {
|
||||
config_tabset->SetActiveTab(static_cast<int>(submenu));
|
||||
prev_focused = nullptr;
|
||||
mouse_is_active = false;
|
||||
mouse_is_active_changed = false;
|
||||
mouse_is_active_initialized = false;
|
||||
}
|
||||
}
|
||||
|
||||
void enter_sub_menu() {
|
||||
Rml::ElementTabSet *config_tabset = get_config_tabset();
|
||||
recompui::ElementConfigSubMenu *config_sub_menu = get_config_sub_menu();
|
||||
if (config_tabset != nullptr && config_sub_menu != nullptr) {
|
||||
config_tabset->SetProperty(Rml::PropertyId::Display, Rml::Style::Display::None);
|
||||
config_sub_menu->set_display(true);
|
||||
}
|
||||
}
|
||||
|
||||
void quit_sub_menu() {
|
||||
Rml::ElementTabSet *config_tabset = get_config_tabset();
|
||||
recompui::ElementConfigSubMenu *config_sub_menu = get_config_sub_menu();
|
||||
if (config_tabset != nullptr && config_sub_menu != nullptr) {
|
||||
config_tabset->SetProperty(Rml::PropertyId::Display, Rml::Style::Display::Flex);
|
||||
config_sub_menu->set_display(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user