mirror of
https://github.com/Zelda64Recomp/Zelda64Recomp.git
synced 2026-04-28 05:01:39 +00:00
Begin implementing mod UI API
This commit is contained in:
parent
563e645c85
commit
2f37efa8a5
30 changed files with 366 additions and 57 deletions
|
|
@ -163,6 +163,7 @@ set (SOURCES
|
||||||
${CMAKE_SOURCE_DIR}/src/ui/ui_elements.cpp
|
${CMAKE_SOURCE_DIR}/src/ui/ui_elements.cpp
|
||||||
${CMAKE_SOURCE_DIR}/src/ui/ui_mod_details_panel.cpp
|
${CMAKE_SOURCE_DIR}/src/ui/ui_mod_details_panel.cpp
|
||||||
${CMAKE_SOURCE_DIR}/src/ui/ui_mod_menu.cpp
|
${CMAKE_SOURCE_DIR}/src/ui/ui_mod_menu.cpp
|
||||||
|
${CMAKE_SOURCE_DIR}/src/ui/ui_api.cpp
|
||||||
${CMAKE_SOURCE_DIR}/src/ui/util/hsv.cpp
|
${CMAKE_SOURCE_DIR}/src/ui/util/hsv.cpp
|
||||||
${CMAKE_SOURCE_DIR}/src/ui/core/ui_context.cpp
|
${CMAKE_SOURCE_DIR}/src/ui/core/ui_context.cpp
|
||||||
${CMAKE_SOURCE_DIR}/src/ui/elements/ui_button.cpp
|
${CMAKE_SOURCE_DIR}/src/ui/elements/ui_button.cpp
|
||||||
|
|
|
||||||
|
|
@ -108,6 +108,7 @@ namespace recompui {
|
||||||
|
|
||||||
Rml::ElementPtr create_custom_element(Rml::Element* parent, std::string tag);
|
Rml::ElementPtr create_custom_element(Rml::Element* parent, std::string tag);
|
||||||
Rml::ElementDocument* load_document(const std::filesystem::path& path);
|
Rml::ElementDocument* load_document(const std::filesystem::path& path);
|
||||||
|
Rml::ElementDocument* create_empty_document();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -599,6 +599,8 @@ int main(int argc, char** argv) {
|
||||||
recomp::register_game(game);
|
recomp::register_game(game);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
recompui::register_ui_exports();
|
||||||
|
|
||||||
zelda64::register_overlays();
|
zelda64::register_overlays();
|
||||||
zelda64::register_patches();
|
zelda64::register_patches();
|
||||||
zelda64::load_config();
|
zelda64::load_config();
|
||||||
|
|
|
||||||
|
|
@ -178,6 +178,34 @@ recompui::ContextId recompui::create_context(Rml::ElementDocument* document) {
|
||||||
return create_context_impl(document);
|
return create_context_impl(document);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
recompui::ContextId recompui::create_context() {
|
||||||
|
Rml::ElementDocument* doc = create_empty_document();
|
||||||
|
ContextId ret = create_context_impl(doc);
|
||||||
|
Element* root = ret.get_root_element();
|
||||||
|
// Mark the root element as not being a shim, as that's only needed for elements that were parented to Rml ones manually.
|
||||||
|
root->shim = false;
|
||||||
|
|
||||||
|
// TODO move these defaults elsewhere. Copied from the existing rcss.
|
||||||
|
ret.open();
|
||||||
|
root->set_width(100.0f, Unit::Percent);
|
||||||
|
root->set_height(100.0f, Unit::Percent);
|
||||||
|
root->set_display(Display::Flex);
|
||||||
|
root->set_opacity(1.0f);
|
||||||
|
root->set_font_family("chiaro");
|
||||||
|
root->set_font_style(FontStyle::Normal);
|
||||||
|
root->set_font_weight(400);
|
||||||
|
|
||||||
|
float sz = 16.0f;
|
||||||
|
float spacing = 0.0f;
|
||||||
|
float sz_add = sz + 4;
|
||||||
|
root->set_font_size(sz_add, Unit::Dp);
|
||||||
|
root->set_letter_spacing(sz_add * spacing, Unit::Dp);
|
||||||
|
root->set_line_height(sz_add, Unit::Dp);
|
||||||
|
ret.close();
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
void recompui::destroy_context(ContextId id) {
|
void recompui::destroy_context(ContextId id) {
|
||||||
bool existed = false;
|
bool existed = false;
|
||||||
|
|
||||||
|
|
@ -209,6 +237,8 @@ void recompui::destroy_context(ContextId id) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void recompui::destroy_all_contexts() {
|
void recompui::destroy_all_contexts() {
|
||||||
|
recompui::hide_all_contexts();
|
||||||
|
|
||||||
std::lock_guard lock{ context_state.all_contexts_lock };
|
std::lock_guard lock{ context_state.all_contexts_lock };
|
||||||
|
|
||||||
// TODO prevent deletion of a context while its mutex is in use. Second lock on the context's mutex before popping
|
// TODO prevent deletion of a context while its mutex is in use. Second lock on the context's mutex before popping
|
||||||
|
|
|
||||||
|
|
@ -51,8 +51,11 @@ namespace recompui {
|
||||||
|
|
||||||
ContextId create_context(const std::filesystem::path& path);
|
ContextId create_context(const std::filesystem::path& path);
|
||||||
ContextId create_context(Rml::ElementDocument* document);
|
ContextId create_context(Rml::ElementDocument* document);
|
||||||
|
ContextId create_context();
|
||||||
void destroy_context(ContextId id);
|
void destroy_context(ContextId id);
|
||||||
ContextId get_current_context();
|
ContextId get_current_context();
|
||||||
ContextId get_context_from_document(Rml::ElementDocument* document);
|
ContextId get_context_from_document(Rml::ElementDocument* document);
|
||||||
void destroy_all_contexts();
|
void destroy_all_contexts();
|
||||||
|
|
||||||
|
void register_ui_exports();
|
||||||
} // namespace recompui
|
} // namespace recompui
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,8 @@ namespace recompui {
|
||||||
struct ResourceId {
|
struct ResourceId {
|
||||||
uint32_t slot_id;
|
uint32_t slot_id;
|
||||||
|
|
||||||
|
bool operator==(const ResourceId& rhs) const = default;
|
||||||
|
|
||||||
const Style* operator*() const;
|
const Style* operator*() const;
|
||||||
Style* operator*();
|
Style* operator*();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
namespace recompui {
|
namespace recompui {
|
||||||
|
|
||||||
Button::Button(const std::string &text, ButtonStyle style, Element *parent) : Element(parent, Events(EventType::Click, EventType::Hover, EventType::Enable), "button") {
|
Button::Button(Element *parent, const std::string &text, ButtonStyle style) : Element(parent, Events(EventType::Click, EventType::Hover, EventType::Enable), "button") {
|
||||||
this->style = style;
|
this->style = style;
|
||||||
|
|
||||||
set_text(text);
|
set_text(text);
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ namespace recompui {
|
||||||
// Element overrides.
|
// Element overrides.
|
||||||
virtual void process_event(const Event &e) override;
|
virtual void process_event(const Event &e) override;
|
||||||
public:
|
public:
|
||||||
Button(const std::string &text, ButtonStyle style, Element *parent);
|
Button(Element *parent, const std::string &text, ButtonStyle style);
|
||||||
void add_pressed_callback(std::function<void()> callback);
|
void add_pressed_callback(std::function<void()> callback);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
namespace recompui {
|
namespace recompui {
|
||||||
|
|
||||||
Container::Container(FlexDirection direction, JustifyContent justify_content, Element *parent) : Element(parent) {
|
Container::Container(Element *parent, FlexDirection direction, JustifyContent justify_content) : Element(parent) {
|
||||||
set_display(Display::Flex);
|
set_display(Display::Flex);
|
||||||
set_flex(1.0f, 1.0f);
|
set_flex(1.0f, 1.0f);
|
||||||
set_flex_direction(direction);
|
set_flex_direction(direction);
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ namespace recompui {
|
||||||
|
|
||||||
class Container : public Element {
|
class Container : public Element {
|
||||||
public:
|
public:
|
||||||
Container(FlexDirection direction, JustifyContent justify_content, Element *parent);
|
Container(Element* parent, FlexDirection direction, JustifyContent justify_content);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace recompui
|
} // namespace recompui
|
||||||
|
|
|
||||||
|
|
@ -203,6 +203,9 @@ void Element::process_event(const Event &) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Element::clear_children() {
|
void Element::clear_children() {
|
||||||
|
if (children.empty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
ContextId context = get_current_context();
|
ContextId context = get_current_context();
|
||||||
|
|
||||||
// Remove the children from the context.
|
// Remove the children from the context.
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@
|
||||||
namespace recompui {
|
namespace recompui {
|
||||||
class Element : public Style, public Rml::EventListener {
|
class Element : public Style, public Rml::EventListener {
|
||||||
friend ContextId create_context(const std::filesystem::path& path);
|
friend ContextId create_context(const std::filesystem::path& path);
|
||||||
|
friend ContextId create_context();
|
||||||
private:
|
private:
|
||||||
Rml::Element *base = nullptr;
|
Rml::Element *base = nullptr;
|
||||||
Rml::ElementPtr base_owning = {};
|
Rml::ElementPtr base_owning = {};
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
namespace recompui {
|
namespace recompui {
|
||||||
|
|
||||||
Label::Label(LabelStyle label_style, Element *parent) : Element(parent) {
|
Label::Label(Element *parent, LabelStyle label_style) : Element(parent) {
|
||||||
switch (label_style) {
|
switch (label_style) {
|
||||||
case LabelStyle::Small:
|
case LabelStyle::Small:
|
||||||
set_font_size(20.0f);
|
set_font_size(20.0f);
|
||||||
|
|
@ -29,7 +29,7 @@ namespace recompui {
|
||||||
set_font_style(FontStyle::Normal);
|
set_font_style(FontStyle::Normal);
|
||||||
}
|
}
|
||||||
|
|
||||||
Label::Label(const std::string &text, LabelStyle label_style, Element *parent) : Label(label_style, parent) {
|
Label::Label(Element *parent, const std::string &text, LabelStyle label_style) : Label(parent, label_style) {
|
||||||
set_text(text);
|
set_text(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,8 +12,8 @@ namespace recompui {
|
||||||
|
|
||||||
class Label : public Element {
|
class Label : public Element {
|
||||||
public:
|
public:
|
||||||
Label(LabelStyle label_style, Element *parent);
|
Label(Element *parent, LabelStyle label_style);
|
||||||
Label(const std::string &text, LabelStyle label_style, Element *parent);
|
Label(Element *parent, const std::string &text, LabelStyle label_style);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace recompui
|
} // namespace recompui
|
||||||
|
|
@ -4,7 +4,7 @@ namespace recompui {
|
||||||
|
|
||||||
// RadioOption
|
// RadioOption
|
||||||
|
|
||||||
RadioOption::RadioOption(std::string_view name, uint32_t index, Element *parent) : Element(parent, Events(EventType::Click, EventType::Focus, EventType::Hover, EventType::Enable), "label") {
|
RadioOption::RadioOption(Element *parent, std::string_view name, uint32_t index) : Element(parent, Events(EventType::Click, EventType::Focus, EventType::Hover, EventType::Enable), "label") {
|
||||||
this->index = index;
|
this->index = index;
|
||||||
|
|
||||||
set_text(name);
|
set_text(name);
|
||||||
|
|
@ -68,7 +68,7 @@ namespace recompui {
|
||||||
set_index_internal(index, false, true);
|
set_index_internal(index, false, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
Radio::Radio(Element *parent) : Container(FlexDirection::Row, JustifyContent::FlexStart, parent) {
|
Radio::Radio(Element *parent) : Container(parent, FlexDirection::Row, JustifyContent::FlexStart) {
|
||||||
set_gap(12.0f);
|
set_gap(12.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -77,7 +77,7 @@ namespace recompui {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Radio::add_option(std::string_view name) {
|
void Radio::add_option(std::string_view name) {
|
||||||
RadioOption *option = get_current_context().create_element<RadioOption>(name, uint32_t(options.size()), this);
|
RadioOption *option = get_current_context().create_element<RadioOption>(this, name, uint32_t(options.size()));
|
||||||
option->set_pressed_callback(std::bind(&Radio::option_selected, this, std::placeholders::_1));
|
option->set_pressed_callback(std::bind(&Radio::option_selected, this, std::placeholders::_1));
|
||||||
options.emplace_back(option);
|
options.emplace_back(option);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ namespace recompui {
|
||||||
protected:
|
protected:
|
||||||
virtual void process_event(const Event &e) override;
|
virtual void process_event(const Event &e) override;
|
||||||
public:
|
public:
|
||||||
RadioOption(std::string_view name, uint32_t index, Element *parent);
|
RadioOption(Element *parent, std::string_view name, uint32_t index);
|
||||||
void set_pressed_callback(std::function<void(uint32_t)> callback);
|
void set_pressed_callback(std::function<void(uint32_t)> callback);
|
||||||
void set_selected_state(bool enable);
|
void set_selected_state(bool enable);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
namespace recompui {
|
namespace recompui {
|
||||||
|
|
||||||
ScrollContainer::ScrollContainer(ScrollDirection direction, Element *parent) : Element(parent) {
|
ScrollContainer::ScrollContainer(Element *parent, ScrollDirection direction) : Element(parent) {
|
||||||
set_flex(1.0f, 1.0f, 100.0f);
|
set_flex(1.0f, 1.0f, 100.0f);
|
||||||
set_width(100.0f, Unit::Percent);
|
set_width(100.0f, Unit::Percent);
|
||||||
set_height(100.0f, Unit::Percent);
|
set_height(100.0f, Unit::Percent);
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ namespace recompui {
|
||||||
|
|
||||||
class ScrollContainer : public Element {
|
class ScrollContainer : public Element {
|
||||||
public:
|
public:
|
||||||
ScrollContainer(ScrollDirection direction, Element *parent);
|
ScrollContainer(Element *parent, ScrollDirection direction);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace recompui
|
} // namespace recompui
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,7 @@ namespace recompui {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Slider::Slider(SliderType type, Element *parent) : Element(parent) {
|
Slider::Slider(Element *parent, SliderType type) : Element(parent) {
|
||||||
this->type = type;
|
this->type = type;
|
||||||
|
|
||||||
set_display(Display::Flex);
|
set_display(Display::Flex);
|
||||||
|
|
@ -69,7 +69,7 @@ namespace recompui {
|
||||||
|
|
||||||
ContextId context = get_current_context();
|
ContextId context = get_current_context();
|
||||||
|
|
||||||
value_label = context.create_element<Label>("0", LabelStyle::Small, this);
|
value_label = context.create_element<Label>(this, "0", LabelStyle::Small);
|
||||||
value_label->set_margin_right(20.0f);
|
value_label->set_margin_right(20.0f);
|
||||||
value_label->set_min_width(60.0f);
|
value_label->set_min_width(60.0f);
|
||||||
value_label->set_max_width(60.0f);
|
value_label->set_max_width(60.0f);
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ namespace recompui {
|
||||||
void update_label_text();
|
void update_label_text();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Slider(SliderType type, Element *parent);
|
Slider(Element *parent, SliderType type);
|
||||||
virtual ~Slider();
|
virtual ~Slider();
|
||||||
void set_value(double v);
|
void set_value(double v);
|
||||||
double get_value() const;
|
double get_value() const;
|
||||||
|
|
|
||||||
|
|
@ -475,4 +475,8 @@ namespace recompui {
|
||||||
set_property(Rml::PropertyId::TabIndex, to_rml(tab_index), Animation());
|
set_property(Rml::PropertyId::TabIndex, to_rml(tab_index), Animation());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Style::set_font_family(std::string_view family) {
|
||||||
|
set_property(Rml::PropertyId::FontFamily, Rml::Property(Rml::String{ family }, Rml::Unit::UNKNOWN), Animation());
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace recompui
|
} // namespace recompui
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <string_view>
|
||||||
|
|
||||||
#include "RmlUi/Core.h"
|
#include "RmlUi/Core.h"
|
||||||
|
|
||||||
#include "../core/ui_resource.h"
|
#include "../core/ui_resource.h"
|
||||||
|
|
@ -84,6 +86,7 @@ namespace recompui {
|
||||||
void set_column_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);
|
void set_drag(Drag drag);
|
||||||
void set_tab_index(TabIndex focus);
|
void set_tab_index(TabIndex focus);
|
||||||
|
void set_font_family(std::string_view family);
|
||||||
virtual bool is_element() { return false; }
|
virtual bool is_element() { return false; }
|
||||||
ResourceId get_resource_id() { return resource_id; }
|
ResourceId get_resource_id() { return resource_id; }
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -171,7 +171,7 @@ namespace recompui {
|
||||||
Percent
|
Percent
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class AnimationType {
|
enum class AnimationType : uint32_t {
|
||||||
None,
|
None,
|
||||||
Set,
|
Set,
|
||||||
Tween
|
Tween
|
||||||
|
|
|
||||||
254
src/ui/ui_api.cpp
Normal file
254
src/ui/ui_api.cpp
Normal file
|
|
@ -0,0 +1,254 @@
|
||||||
|
#include "recomp_ui.h"
|
||||||
|
|
||||||
|
#include "core/ui_context.h"
|
||||||
|
#include "core/ui_resource.h"
|
||||||
|
|
||||||
|
#include "elements/ui_element.h"
|
||||||
|
#include "elements/ui_button.h"
|
||||||
|
#include "elements/ui_clickable.h"
|
||||||
|
#include "elements/ui_container.h"
|
||||||
|
#include "elements/ui_image.h"
|
||||||
|
#include "elements/ui_label.h"
|
||||||
|
#include "elements/ui_radio.h"
|
||||||
|
#include "elements/ui_scroll_container.h"
|
||||||
|
#include "elements/ui_slider.h"
|
||||||
|
#include "elements/ui_style.h"
|
||||||
|
#include "elements/ui_text_input.h"
|
||||||
|
#include "elements/ui_toggle.h"
|
||||||
|
#include "elements/ui_types.h"
|
||||||
|
|
||||||
|
#include "librecomp/overlays.hpp"
|
||||||
|
#include "librecomp/helpers.hpp"
|
||||||
|
|
||||||
|
using namespace recompui;
|
||||||
|
|
||||||
|
constexpr ResourceId root_element_id{ 0xFFFFFFFE };
|
||||||
|
|
||||||
|
// Helpers
|
||||||
|
|
||||||
|
ContextId get_context(uint8_t* rdram, recomp_context* ctx) {
|
||||||
|
uint32_t context_id = _arg<0, uint32_t>(rdram, ctx);
|
||||||
|
return ContextId{ .slot_id = context_id };
|
||||||
|
}
|
||||||
|
|
||||||
|
template <int arg_index>
|
||||||
|
std::string arg_string(uint8_t* rdram, recomp_context* ctx) {
|
||||||
|
PTR(char) str = _arg<arg_index, PTR(char)>(rdram, ctx);
|
||||||
|
|
||||||
|
// Get the length of the byteswapped string.
|
||||||
|
size_t len = 0;
|
||||||
|
while (MEM_B(str, len) != 0x00) {
|
||||||
|
len++;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string ret{};
|
||||||
|
ret.reserve(len + 1);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < len; i++) {
|
||||||
|
ret += (char)MEM_B(str, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <int arg_index>
|
||||||
|
ResourceId arg_resource_id(uint8_t* rdram, recomp_context* ctx) {
|
||||||
|
uint32_t slot_id = _arg<arg_index, uint32_t>(rdram, ctx);
|
||||||
|
|
||||||
|
return ResourceId{ .slot_id = slot_id };
|
||||||
|
}
|
||||||
|
|
||||||
|
template <int arg_index>
|
||||||
|
Element* arg_element(uint8_t* rdram, recomp_context* ctx, ContextId ui_context) {
|
||||||
|
ResourceId resource = arg_resource_id<arg_index>(rdram, ctx);
|
||||||
|
|
||||||
|
if (resource == ResourceId::null()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
else if (resource == root_element_id) {
|
||||||
|
return ui_context.get_root_element();
|
||||||
|
}
|
||||||
|
|
||||||
|
return resource.as_element();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <int arg_index>
|
||||||
|
Style* arg_style(uint8_t* rdram, recomp_context* ctx) {
|
||||||
|
ResourceId resource = arg_resource_id<arg_index>(rdram, ctx);
|
||||||
|
|
||||||
|
if (resource == ResourceId::null()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return *resource;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <int arg_index>
|
||||||
|
Animation arg_animation(uint8_t* rdram, recomp_context* ctx) {
|
||||||
|
PTR(Animation) anim_ptr = _arg<arg_index, PTR(Animation)>(rdram, ctx);
|
||||||
|
|
||||||
|
if (anim_ptr == NULLPTR) {
|
||||||
|
return Animation{};
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return *TO_PTR(Animation, anim_ptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void return_resource(recomp_context* ctx, ResourceId resource) {
|
||||||
|
_return<uint32_t>(ctx, resource.slot_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Context functions
|
||||||
|
|
||||||
|
extern "C" void recompui_create_context(uint8_t* rdram, recomp_context* ctx) {
|
||||||
|
(void)rdram;
|
||||||
|
ContextId ui_context = create_context();
|
||||||
|
|
||||||
|
_return<uint32_t>(ctx, ui_context.slot_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" void recompui_open_context(uint8_t* rdram, recomp_context* ctx) {
|
||||||
|
ContextId ui_context = get_context(rdram, ctx);
|
||||||
|
|
||||||
|
ui_context.open();
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" void recompui_close_context(uint8_t* rdram, recomp_context* ctx) {
|
||||||
|
ContextId ui_context = get_context(rdram, ctx);
|
||||||
|
|
||||||
|
ui_context.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" void recompui_context_root(uint8_t* rdram, recomp_context* ctx) {
|
||||||
|
ContextId ui_context = get_context(rdram, ctx);
|
||||||
|
(void)ui_context;
|
||||||
|
|
||||||
|
return_resource(ctx, root_element_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" void recompui_show_context(uint8_t* rdram, recomp_context* ctx) {
|
||||||
|
ContextId ui_context = get_context(rdram, ctx);
|
||||||
|
|
||||||
|
recompui::show_context(ui_context, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" void recompui_hide_context(uint8_t* rdram, recomp_context* ctx) {
|
||||||
|
ContextId ui_context = get_context(rdram, ctx);
|
||||||
|
|
||||||
|
recompui::hide_context(ui_context);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Resource creation functions
|
||||||
|
|
||||||
|
extern "C" void recompui_create_style(uint8_t* rdram, recomp_context* ctx) {
|
||||||
|
ContextId ui_context = get_context(rdram, ctx);
|
||||||
|
|
||||||
|
Style* ret = ui_context.create_style();
|
||||||
|
return_resource(ctx, ret->get_resource_id());
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" void recompui_create_element(uint8_t* rdram, recomp_context* ctx) {
|
||||||
|
ContextId ui_context = get_context(rdram, ctx);
|
||||||
|
Element* parent = arg_element<1>(rdram, ctx, ui_context);
|
||||||
|
|
||||||
|
Element* ret = ui_context.create_element<Element>(parent);
|
||||||
|
return_resource(ctx, ret->get_resource_id());
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" void recompui_create_button(uint8_t* rdram, recomp_context* ctx) {
|
||||||
|
ContextId ui_context = get_context(rdram, ctx);
|
||||||
|
Element* parent = arg_element<1>(rdram, ctx, ui_context);
|
||||||
|
std::string text = arg_string<2>(rdram, ctx);
|
||||||
|
uint32_t style = _arg<3, uint32_t>(rdram, ctx);
|
||||||
|
|
||||||
|
Button* ret = ui_context.create_element<Button>(parent, text, static_cast<ButtonStyle>(style));
|
||||||
|
return_resource(ctx, ret->get_resource_id());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Style functions
|
||||||
|
|
||||||
|
extern "C" void recompui_set_width(uint8_t* rdram, recomp_context* ctx) {
|
||||||
|
Style* resource = arg_style<0>(rdram, ctx);
|
||||||
|
float width = _arg_float_a1(rdram, ctx);
|
||||||
|
uint32_t unit = _arg<2, uint32_t>(rdram, ctx);
|
||||||
|
Animation animation = arg_animation<3>(rdram, ctx);
|
||||||
|
|
||||||
|
resource->set_width(width, static_cast<Unit>(unit), animation);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" void recompui_set_height(uint8_t* rdram, recomp_context* ctx) {
|
||||||
|
Style* resource = arg_style<0>(rdram, ctx);
|
||||||
|
float height = _arg_float_a1(rdram, ctx);
|
||||||
|
uint32_t unit = _arg<2, uint32_t>(rdram, ctx);
|
||||||
|
Animation animation = arg_animation<3>(rdram, ctx);
|
||||||
|
|
||||||
|
resource->set_height(height, static_cast<Unit>(unit), animation);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" void recompui_set_display(uint8_t* rdram, recomp_context* ctx) {
|
||||||
|
Style* resource = arg_style<0>(rdram, ctx);
|
||||||
|
uint32_t display = _arg<1, uint32_t>(rdram, ctx);
|
||||||
|
|
||||||
|
resource->set_display(static_cast<Display>(display));
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" void recompui_set_flex_direction(uint8_t* rdram, recomp_context* ctx) {
|
||||||
|
Style* resource = arg_style<0>(rdram, ctx);
|
||||||
|
uint32_t direction = _arg<1, uint32_t>(rdram, ctx);
|
||||||
|
|
||||||
|
resource->set_flex_direction(static_cast<FlexDirection>(direction));
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" void recompui_set_flex_grow(uint8_t* rdram, recomp_context* ctx) { // float grow, Animation animation = Animation()
|
||||||
|
Style* resource = arg_style<0>(rdram, ctx);
|
||||||
|
float grow = _arg_float_a1(rdram, ctx);
|
||||||
|
Animation animation = arg_animation<2>(rdram, ctx);
|
||||||
|
|
||||||
|
resource->set_flex_grow(grow, animation);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" void recompui_set_flex_shrink(uint8_t* rdram, recomp_context* ctx) { // float shrink, Animation animation = Animation()
|
||||||
|
Style* resource = arg_style<0>(rdram, ctx);
|
||||||
|
float shrink = _arg_float_a1(rdram, ctx);
|
||||||
|
Animation animation = arg_animation<2>(rdram, ctx);
|
||||||
|
|
||||||
|
resource->set_flex_shrink(shrink, animation);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" void recompui_set_flex_basis_auto(uint8_t* rdram, recomp_context* ctx) {
|
||||||
|
Style* resource = arg_style<0>(rdram, ctx);
|
||||||
|
|
||||||
|
resource->set_flex_basis_auto();
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" void recompui_set_flex_basis(uint8_t* rdram, recomp_context* ctx) { // float basis, Unit unit = Unit::Percent, Animation animation = Animation()
|
||||||
|
Style* resource = arg_style<0>(rdram, ctx);
|
||||||
|
float basis = _arg_float_a1(rdram, ctx);
|
||||||
|
uint32_t unit = _arg<2, uint32_t>(rdram, ctx);
|
||||||
|
Animation animation = arg_animation<3>(rdram, ctx);
|
||||||
|
|
||||||
|
resource->set_flex_basis(basis, static_cast<Unit>(unit), animation);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define REGISTER_FUNC(name) recomp::overlays::register_base_export(#name, name)
|
||||||
|
|
||||||
|
void recompui::register_ui_exports() {
|
||||||
|
REGISTER_FUNC(recompui_create_context);
|
||||||
|
REGISTER_FUNC(recompui_open_context);
|
||||||
|
REGISTER_FUNC(recompui_close_context);
|
||||||
|
REGISTER_FUNC(recompui_context_root);
|
||||||
|
REGISTER_FUNC(recompui_show_context);
|
||||||
|
REGISTER_FUNC(recompui_hide_context);
|
||||||
|
REGISTER_FUNC(recompui_create_style);
|
||||||
|
REGISTER_FUNC(recompui_create_element);
|
||||||
|
REGISTER_FUNC(recompui_create_button);
|
||||||
|
REGISTER_FUNC(recompui_set_width);
|
||||||
|
REGISTER_FUNC(recompui_set_height);
|
||||||
|
REGISTER_FUNC(recompui_set_display);
|
||||||
|
REGISTER_FUNC(recompui_set_flex_direction);
|
||||||
|
REGISTER_FUNC(recompui_set_flex_grow);
|
||||||
|
REGISTER_FUNC(recompui_set_flex_shrink);
|
||||||
|
REGISTER_FUNC(recompui_set_flex_basis_auto);
|
||||||
|
REGISTER_FUNC(recompui_set_flex_basis);
|
||||||
|
}
|
||||||
|
|
@ -25,7 +25,7 @@ ConfigOptionElement::ConfigOptionElement(Element *parent) : Element(parent, Even
|
||||||
set_gap(8.0f);
|
set_gap(8.0f);
|
||||||
set_min_height(100.0f);
|
set_min_height(100.0f);
|
||||||
|
|
||||||
name_label = get_current_context().create_element<Label>(LabelStyle::Normal, this);
|
name_label = get_current_context().create_element<Label>(this, LabelStyle::Normal);
|
||||||
}
|
}
|
||||||
|
|
||||||
ConfigOptionElement::~ConfigOptionElement() {
|
ConfigOptionElement::~ConfigOptionElement() {
|
||||||
|
|
@ -56,8 +56,8 @@ void ConfigOptionSlider::slider_value_changed(double v) {
|
||||||
printf("%s changed to %f.\n", name.c_str(), v);
|
printf("%s changed to %f.\n", name.c_str(), v);
|
||||||
}
|
}
|
||||||
|
|
||||||
ConfigOptionSlider::ConfigOptionSlider(double value, double min_value, double max_value, double step_value, bool percent, Element *parent) : ConfigOptionElement(parent) {
|
ConfigOptionSlider::ConfigOptionSlider(Element *parent, double value, double min_value, double max_value, double step_value, bool percent) : ConfigOptionElement(parent) {
|
||||||
slider = get_current_context().create_element<Slider>(percent ? SliderType::Percent : SliderType::Double, this);
|
slider = get_current_context().create_element<Slider>(this, percent ? SliderType::Percent : SliderType::Double);
|
||||||
slider->set_value(value);
|
slider->set_value(value);
|
||||||
slider->set_min_value(min_value);
|
slider->set_min_value(min_value);
|
||||||
slider->set_max_value(max_value);
|
slider->set_max_value(max_value);
|
||||||
|
|
@ -83,7 +83,7 @@ void ConfigOptionRadio::index_changed(uint32_t index) {
|
||||||
printf("%s changed to %d.\n", name.c_str(), index);
|
printf("%s changed to %d.\n", name.c_str(), index);
|
||||||
}
|
}
|
||||||
|
|
||||||
ConfigOptionRadio::ConfigOptionRadio(const std::vector<std::string> &options, Element *parent) : ConfigOptionElement(parent) {
|
ConfigOptionRadio::ConfigOptionRadio(Element *parent, const std::vector<std::string> &options) : ConfigOptionElement(parent) {
|
||||||
radio = get_current_context().create_element<Radio>(this);
|
radio = get_current_context().create_element<Radio>(this);
|
||||||
radio->add_index_changed_callback(std::bind(&ConfigOptionRadio::index_changed, this, std::placeholders::_1));
|
radio->add_index_changed_callback(std::bind(&ConfigOptionRadio::index_changed, this, std::placeholders::_1));
|
||||||
for (std::string_view option : options) {
|
for (std::string_view option : options) {
|
||||||
|
|
@ -127,25 +127,25 @@ ConfigSubMenu::ConfigSubMenu(Element *parent) : Element(parent) {
|
||||||
set_height(100.0f, Unit::Percent);
|
set_height(100.0f, Unit::Percent);
|
||||||
|
|
||||||
recompui::ContextId context = get_current_context();
|
recompui::ContextId context = get_current_context();
|
||||||
header_container = context.create_element<Container>(FlexDirection::Row, JustifyContent::FlexStart, this);
|
header_container = context.create_element<Container>(this, FlexDirection::Row, JustifyContent::FlexStart);
|
||||||
|
|
||||||
{
|
{
|
||||||
back_button = context.create_element<Button>("Back", ButtonStyle::Secondary, header_container);
|
back_button = context.create_element<Button>(header_container, "Back", ButtonStyle::Secondary);
|
||||||
back_button->add_pressed_callback(std::bind(&ConfigSubMenu::back_button_pressed, this));
|
back_button->add_pressed_callback(std::bind(&ConfigSubMenu::back_button_pressed, this));
|
||||||
title_label = context.create_element<Label>("Title", LabelStyle::Large, header_container);
|
title_label = context.create_element<Label>(header_container, "Title", LabelStyle::Large);
|
||||||
}
|
}
|
||||||
|
|
||||||
body_container = context.create_element<Container>(FlexDirection::Row, JustifyContent::SpaceEvenly, this);
|
body_container = context.create_element<Container>(this, FlexDirection::Row, JustifyContent::SpaceEvenly);
|
||||||
{
|
{
|
||||||
config_container = context.create_element<Container>(FlexDirection::Column, JustifyContent::Center, body_container);
|
config_container = context.create_element<Container>(body_container, FlexDirection::Column, JustifyContent::Center);
|
||||||
config_container->set_display(Display::Block);
|
config_container->set_display(Display::Block);
|
||||||
config_container->set_flex_basis(100.0f);
|
config_container->set_flex_basis(100.0f);
|
||||||
config_container->set_align_items(AlignItems::Center);
|
config_container->set_align_items(AlignItems::Center);
|
||||||
{
|
{
|
||||||
config_scroll_container = context.create_element<ScrollContainer>(ScrollDirection::Vertical, config_container);
|
config_scroll_container = context.create_element<ScrollContainer>(config_container, ScrollDirection::Vertical);
|
||||||
}
|
}
|
||||||
|
|
||||||
description_label = context.create_element<Label>("Description", LabelStyle::Small, body_container);
|
description_label = context.create_element<Label>(body_container, "Description", LabelStyle::Small);
|
||||||
description_label->set_min_width(800.0f);
|
description_label->set_min_width(800.0f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -172,7 +172,7 @@ void ConfigSubMenu::add_option(ConfigOptionElement *option, std::string_view nam
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigSubMenu::add_slider_option(std::string_view name, std::string_view description, double min, double max, double step, bool percent) {
|
void ConfigSubMenu::add_slider_option(std::string_view name, std::string_view description, double min, double max, double step, bool percent) {
|
||||||
ConfigOptionSlider *option_slider = get_current_context().create_element<ConfigOptionSlider>((min + max) / 2.0, min, max, step, percent, config_scroll_container);
|
ConfigOptionSlider *option_slider = get_current_context().create_element<ConfigOptionSlider>(config_scroll_container, (min + max) / 2.0, min, max, step, percent);
|
||||||
add_option(option_slider, name, description);
|
add_option(option_slider, name, description);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -182,7 +182,7 @@ void ConfigSubMenu::add_text_option(std::string_view name, std::string_view desc
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigSubMenu::add_radio_option(std::string_view name, std::string_view description, const std::vector<std::string> &options) {
|
void ConfigSubMenu::add_radio_option(std::string_view name, std::string_view description, const std::vector<std::string> &options) {
|
||||||
ConfigOptionRadio *option_radio = get_current_context().create_element<ConfigOptionRadio>(options, config_scroll_container);
|
ConfigOptionRadio *option_radio = get_current_context().create_element<ConfigOptionRadio>(config_scroll_container, options);
|
||||||
add_option(option_radio, name, description);
|
add_option(option_radio, name, description);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ protected:
|
||||||
|
|
||||||
void slider_value_changed(double v);
|
void slider_value_changed(double v);
|
||||||
public:
|
public:
|
||||||
ConfigOptionSlider(double value, double min_value, double max_value, double step_value, bool percent, Element *parent);
|
ConfigOptionSlider(Element *parent, double value, double min_value, double max_value, double step_value, bool percent);
|
||||||
};
|
};
|
||||||
|
|
||||||
class ConfigOptionTextInput : public ConfigOptionElement {
|
class ConfigOptionTextInput : public ConfigOptionElement {
|
||||||
|
|
@ -54,7 +54,7 @@ protected:
|
||||||
|
|
||||||
void index_changed(uint32_t index);
|
void index_changed(uint32_t index);
|
||||||
public:
|
public:
|
||||||
ConfigOptionRadio(const std::vector<std::string> &options, Element *parent);
|
ConfigOptionRadio(Element *parent, const std::vector<std::string> &options);
|
||||||
};
|
};
|
||||||
|
|
||||||
class ConfigSubMenu : public Element {
|
class ConfigSubMenu : public Element {
|
||||||
|
|
|
||||||
|
|
@ -14,13 +14,13 @@ ModDetailsPanel::ModDetailsPanel(Element *parent) : Element(parent) {
|
||||||
|
|
||||||
ContextId context = get_current_context();
|
ContextId context = get_current_context();
|
||||||
|
|
||||||
header_container = context.create_element<Container>(FlexDirection::Row, JustifyContent::FlexStart, this);
|
header_container = context.create_element<Container>(this, FlexDirection::Row, JustifyContent::FlexStart);
|
||||||
header_container->set_flex(0.0f, 0.0f);
|
header_container->set_flex(0.0f, 0.0f);
|
||||||
header_container->set_padding(16.0f);
|
header_container->set_padding(16.0f);
|
||||||
header_container->set_gap(16.0f);
|
header_container->set_gap(16.0f);
|
||||||
header_container->set_background_color(Color{ 0, 0, 0, 89 });
|
header_container->set_background_color(Color{ 0, 0, 0, 89 });
|
||||||
{
|
{
|
||||||
thumbnail_container = context.create_element<Container>(FlexDirection::Column, JustifyContent::SpaceEvenly, header_container);
|
thumbnail_container = context.create_element<Container>(header_container, FlexDirection::Column, JustifyContent::SpaceEvenly);
|
||||||
thumbnail_container->set_flex(0.0f, 0.0f);
|
thumbnail_container->set_flex(0.0f, 0.0f);
|
||||||
{
|
{
|
||||||
thumbnail_image = context.create_element<Image>(thumbnail_container);
|
thumbnail_image = context.create_element<Image>(thumbnail_container);
|
||||||
|
|
@ -29,38 +29,38 @@ ModDetailsPanel::ModDetailsPanel(Element *parent) : Element(parent) {
|
||||||
thumbnail_image->set_background_color(Color{ 190, 184, 219, 25 });
|
thumbnail_image->set_background_color(Color{ 190, 184, 219, 25 });
|
||||||
}
|
}
|
||||||
|
|
||||||
header_details_container = context.create_element<Container>(FlexDirection::Column, JustifyContent::SpaceEvenly, header_container);
|
header_details_container = context.create_element<Container>(header_container, FlexDirection::Column, JustifyContent::SpaceEvenly);
|
||||||
header_details_container->set_flex(1.0f, 1.0f);
|
header_details_container->set_flex(1.0f, 1.0f);
|
||||||
header_details_container->set_flex_basis(100.0f, Unit::Percent);
|
header_details_container->set_flex_basis(100.0f, Unit::Percent);
|
||||||
header_details_container->set_text_align(TextAlign::Left);
|
header_details_container->set_text_align(TextAlign::Left);
|
||||||
{
|
{
|
||||||
title_label = context.create_element<Label>(LabelStyle::Large, header_details_container);
|
title_label = context.create_element<Label>(header_details_container, LabelStyle::Large);
|
||||||
version_label = context.create_element<Label>(LabelStyle::Normal, header_details_container);
|
version_label = context.create_element<Label>(header_details_container, LabelStyle::Normal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
body_container = context.create_element<Container>(FlexDirection::Column, JustifyContent::FlexStart, this);
|
body_container = context.create_element<Container>(this, FlexDirection::Column, JustifyContent::FlexStart);
|
||||||
body_container->set_flex(0.0f, 0.0f);
|
body_container->set_flex(0.0f, 0.0f);
|
||||||
body_container->set_text_align(TextAlign::Left);
|
body_container->set_text_align(TextAlign::Left);
|
||||||
body_container->set_padding(16.0f);
|
body_container->set_padding(16.0f);
|
||||||
body_container->set_gap(16.0f);
|
body_container->set_gap(16.0f);
|
||||||
{
|
{
|
||||||
description_label = context.create_element<Label>(LabelStyle::Normal, body_container);
|
description_label = context.create_element<Label>(body_container, LabelStyle::Normal);
|
||||||
authors_label = context.create_element<Label>(LabelStyle::Normal, body_container);
|
authors_label = context.create_element<Label>(body_container, LabelStyle::Normal);
|
||||||
}
|
}
|
||||||
|
|
||||||
spacer_element = context.create_element<Element>(this);
|
spacer_element = context.create_element<Element>(this);
|
||||||
spacer_element->set_flex(1.0f, 0.0f);
|
spacer_element->set_flex(1.0f, 0.0f);
|
||||||
|
|
||||||
buttons_container = context.create_element<Container>(FlexDirection::Row, JustifyContent::SpaceAround, this);
|
buttons_container = context.create_element<Container>(this, FlexDirection::Row, JustifyContent::SpaceAround);
|
||||||
buttons_container->set_flex(0.0f, 0.0f);
|
buttons_container->set_flex(0.0f, 0.0f);
|
||||||
buttons_container->set_padding(16.0f);
|
buttons_container->set_padding(16.0f);
|
||||||
{
|
{
|
||||||
enable_toggle = context.create_element<Toggle>(buttons_container);
|
enable_toggle = context.create_element<Toggle>(buttons_container);
|
||||||
enable_toggle->add_checked_callback(std::bind(&ModDetailsPanel::enable_toggle_checked, this, std::placeholders::_1));
|
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 = context.create_element<Button>(buttons_container, "Configure", recompui::ButtonStyle::Secondary);
|
||||||
configure_button->add_pressed_callback(std::bind(&ModDetailsPanel::configure_button_pressed, this));
|
configure_button->add_pressed_callback(std::bind(&ModDetailsPanel::configure_button_pressed, this));
|
||||||
erase_button = context.create_element<Button>("Erase", recompui::ButtonStyle::Secondary, buttons_container);
|
erase_button = context.create_element<Button>(buttons_container, "Erase", recompui::ButtonStyle::Secondary);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -40,15 +40,15 @@ ModEntry::ModEntry(Element *parent, const recomp::mods::ModDetails &details, uin
|
||||||
thumbnail_image->set_min_height(100.0f);
|
thumbnail_image->set_min_height(100.0f);
|
||||||
thumbnail_image->set_background_color(Color{ 190, 184, 219, 25 });
|
thumbnail_image->set_background_color(Color{ 190, 184, 219, 25 });
|
||||||
|
|
||||||
body_container = context.create_element<Container>(FlexDirection::Column, JustifyContent::FlexStart, this);
|
body_container = context.create_element<Container>(this, FlexDirection::Column, JustifyContent::FlexStart);
|
||||||
body_container->set_width_auto();
|
body_container->set_width_auto();
|
||||||
body_container->set_height(100.0f);
|
body_container->set_height(100.0f);
|
||||||
body_container->set_margin_left(16.0f);
|
body_container->set_margin_left(16.0f);
|
||||||
body_container->set_overflow(Overflow::Hidden);
|
body_container->set_overflow(Overflow::Hidden);
|
||||||
|
|
||||||
{
|
{
|
||||||
name_label = context.create_element<Label>(details.mod_id, LabelStyle::Normal, body_container);
|
name_label = context.create_element<Label>(body_container, details.mod_id, LabelStyle::Normal);
|
||||||
description_label = context.create_element<Label>("Short description of mod here.", LabelStyle::Small, body_container);
|
description_label = context.create_element<Label>(body_container, "Short description of mod here.", LabelStyle::Small);
|
||||||
} // body_container
|
} // body_container
|
||||||
} // this
|
} // this
|
||||||
}
|
}
|
||||||
|
|
@ -174,12 +174,12 @@ ModMenu::ModMenu(Element *parent) : Element(parent) {
|
||||||
set_height(100.0f, Unit::Percent);
|
set_height(100.0f, Unit::Percent);
|
||||||
|
|
||||||
{
|
{
|
||||||
body_container = context.create_element<Container>(FlexDirection::Row, JustifyContent::FlexStart, this);
|
body_container = context.create_element<Container>(this, FlexDirection::Row, JustifyContent::FlexStart);
|
||||||
body_container->set_flex(1.0f, 1.0f, 100.0f);
|
body_container->set_flex(1.0f, 1.0f, 100.0f);
|
||||||
body_container->set_width(100.0f, Unit::Percent);
|
body_container->set_width(100.0f, Unit::Percent);
|
||||||
body_container->set_height(100.0f, Unit::Percent);
|
body_container->set_height(100.0f, Unit::Percent);
|
||||||
{
|
{
|
||||||
list_container = context.create_element<Container>(FlexDirection::Column, JustifyContent::Center, body_container);
|
list_container = context.create_element<Container>(body_container, FlexDirection::Column, JustifyContent::Center);
|
||||||
list_container->set_display(Display::Block);
|
list_container->set_display(Display::Block);
|
||||||
list_container->set_flex_basis(100.0f);
|
list_container->set_flex_basis(100.0f);
|
||||||
list_container->set_align_items(AlignItems::Center);
|
list_container->set_align_items(AlignItems::Center);
|
||||||
|
|
@ -187,7 +187,7 @@ ModMenu::ModMenu(Element *parent) : Element(parent) {
|
||||||
list_container->set_background_color(Color{ 0, 0, 0, 89 });
|
list_container->set_background_color(Color{ 0, 0, 0, 89 });
|
||||||
list_container->set_border_bottom_left_radius(16.0f);
|
list_container->set_border_bottom_left_radius(16.0f);
|
||||||
{
|
{
|
||||||
list_scroll_container = context.create_element<ScrollContainer>(ScrollDirection::Vertical, list_container);
|
list_scroll_container = context.create_element<ScrollContainer>(list_container, ScrollDirection::Vertical);
|
||||||
} // list_container
|
} // list_container
|
||||||
|
|
||||||
mod_details_panel = context.create_element<ModDetailsPanel>(body_container);
|
mod_details_panel = context.create_element<ModDetailsPanel>(body_container);
|
||||||
|
|
@ -196,7 +196,7 @@ ModMenu::ModMenu(Element *parent) : Element(parent) {
|
||||||
} // body_container
|
} // body_container
|
||||||
|
|
||||||
|
|
||||||
footer_container = context.create_element<Container>(FlexDirection::Row, JustifyContent::SpaceBetween, this);
|
footer_container = context.create_element<Container>(this, FlexDirection::Row, JustifyContent::SpaceBetween);
|
||||||
footer_container->set_width(100.0f, recompui::Unit::Percent);
|
footer_container->set_width(100.0f, recompui::Unit::Percent);
|
||||||
footer_container->set_align_items(recompui::AlignItems::Center);
|
footer_container->set_align_items(recompui::AlignItems::Center);
|
||||||
footer_container->set_background_color(Color{ 0, 0, 0, 89 });
|
footer_container->set_background_color(Color{ 0, 0, 0, 89 });
|
||||||
|
|
@ -206,7 +206,7 @@ ModMenu::ModMenu(Element *parent) : Element(parent) {
|
||||||
footer_container->set_border_bottom_left_radius(16.0f);
|
footer_container->set_border_bottom_left_radius(16.0f);
|
||||||
footer_container->set_border_bottom_right_radius(16.0f);
|
footer_container->set_border_bottom_right_radius(16.0f);
|
||||||
{
|
{
|
||||||
refresh_button = context.create_element<Button>("Refresh", recompui::ButtonStyle::Primary, footer_container);
|
refresh_button = context.create_element<Button>(footer_container, "Refresh", recompui::ButtonStyle::Primary);
|
||||||
refresh_button->add_pressed_callback(std::bind(&ModMenu::refresh_mods, this));
|
refresh_button->add_pressed_callback(std::bind(&ModMenu::refresh_mods, this));
|
||||||
} // footer_container
|
} // footer_container
|
||||||
} // this
|
} // this
|
||||||
|
|
|
||||||
|
|
@ -4,10 +4,10 @@
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
namespace RT64 {
|
namespace RT64 {
|
||||||
class RenderInterface;
|
struct RenderInterface;
|
||||||
class RenderDevice;
|
struct RenderDevice;
|
||||||
class RenderCommandList;
|
struct RenderCommandList;
|
||||||
class RenderFramebuffer;
|
struct RenderFramebuffer;
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace Rml {
|
namespace Rml {
|
||||||
|
|
|
||||||
|
|
@ -650,7 +650,6 @@ void draw_hook(RT64::RenderCommandList* command_list, RT64::RenderFramebuffer* s
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
recompui::hide_all_contexts();
|
|
||||||
if (open_config) {
|
if (open_config) {
|
||||||
recompui::show_context(recompui::get_config_context_id(), "");
|
recompui::show_context(recompui::get_config_context_id(), "");
|
||||||
}
|
}
|
||||||
|
|
@ -770,3 +769,9 @@ Rml::ElementDocument* recompui::load_document(const std::filesystem::path& path)
|
||||||
return ui_state->context->LoadDocument(path.string());
|
return ui_state->context->LoadDocument(path.string());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Rml::ElementDocument* recompui::create_empty_document() {
|
||||||
|
std::lock_guard lock{ui_state_mutex};
|
||||||
|
|
||||||
|
return ui_state->context->CreateDocument();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue