This commit is contained in:
Dario 2025-01-19 17:15:07 -03:00 committed by Mr-Wiseguy
parent b9eeb57d99
commit 6ca41f37c9
34 changed files with 0 additions and 1453 deletions

View File

@ -164,18 +164,6 @@ set (SOURCES
${CMAKE_SOURCE_DIR}/src/ui/ui_mod_menu.cpp
${CMAKE_SOURCE_DIR}/src/ui/util/hsv.cpp
${CMAKE_SOURCE_DIR}/src/ui/core/ui_context.cpp
${CMAKE_SOURCE_DIR}/src/ui/elements/ElementConfigGroup.cpp
${CMAKE_SOURCE_DIR}/src/ui/elements/ElementConfigOption.cpp
${CMAKE_SOURCE_DIR}/src/ui/elements/ElementDescription.cpp
${CMAKE_SOURCE_DIR}/src/ui/elements/ElementOptionType.cpp
${CMAKE_SOURCE_DIR}/src/ui/elements/ElementOptionTypeButton.cpp
${CMAKE_SOURCE_DIR}/src/ui/elements/ElementOptionTypeCheckbox.cpp
${CMAKE_SOURCE_DIR}/src/ui/elements/ElementOptionTypeColor.cpp
${CMAKE_SOURCE_DIR}/src/ui/elements/ElementOptionTypeDropdown.cpp
${CMAKE_SOURCE_DIR}/src/ui/elements/ElementOptionTypeRadioTabs.cpp
${CMAKE_SOURCE_DIR}/src/ui/elements/ElementOptionTypeRange.cpp
${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

View File

@ -29,7 +29,6 @@
<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" />
</head>
<body class="window">
@ -80,13 +79,6 @@
<panel class="config" data-model="debug_model">
<template src="config-menu__debug" />
</panel>
<tab class="tab" id="tab_cheats">
<div>Cheats</div>
<div class="tab__indicator"></div>
</tab>
<panel class="config">
<template src="config-menu__cheats" />
</panel>
</tabset>
<div class="config__icon-buttons">
<button

View File

@ -1,12 +0,0 @@
<template name="config-menu__cheats">
<head>
</head>
<body>
<form class="config__form" id="conf-cheats__form">
<div class="config__hz-wrapper" id="conf-cheats__hz-wrapper">
<recomp-config-group recomp-data="cheats" />
<recomp-description />
</div>
</form>
</body>
</template>

View File

@ -44,4 +44,3 @@ recomp_get_inverted_axes = 0x8F0000A4;
recomp_high_precision_fb_enabled = 0x8F0000A8;
recomp_get_resolution_scale = 0x8F0000AC;
recomp_get_analog_inverted_axes = 0x8F0000B0;
recomp_get_config_store_int = 0x8F0000B4;

View File

@ -167,20 +167,3 @@ extern "C" void recomp_set_right_analog_suppressed(uint8_t* rdram, recomp_contex
recomp::set_right_analog_suppressed(suppressed);
}
extern "C" void recomp_get_config_store_int(uint8_t* rdram, recomp_context* ctx) {
thread_local std::vector<char> key_buffer{};
key_buffer.clear();
char c;
PTR(char) cur_char = _arg<0, PTR(char)>(rdram, ctx);
size_t i = 0;
while ((c = MEM_B(cur_char, i)) != '\0') {
key_buffer.push_back(c);
i++;
}
_return(ctx, recomp::config::get_config_store_value<int>(
std::string_view{key_buffer.data(), key_buffer.size()}
));
}

View File

@ -1,134 +0,0 @@
#include "ElementConfigGroup.h"
#include "ElementConfigOption.h"
#include <string>
#include <cassert>
using json = nlohmann::json;
using ConfigOptionType = recomp::config::ConfigOptionType;
using ConfigOption = recomp::config::ConfigOption;
namespace recompui {
static const std::string config_group_base_class = "config-group";
static const std::string config_group_base_class_scrollable = config_group_base_class + "--scrollable";
static const std::string config_group_title_class = config_group_base_class + "__title";
static const std::string config_group_title_class_hidden = config_group_title_class + "--hidden";
static const std::string config_group_wrapper_class = config_group_base_class + "__wrapper";
ElementConfigGroup::ElementConfigGroup(const Rml::String& tag) : Rml::Element(tag)
{
SetAttribute("recomp-store-element", true);
SetClass(config_group_base_class, true);
Rml::ElementDocument *doc = GetOwnerDocument();
{
Rml::Element *title_el = AppendChild(doc->CreateElement("div"));
title_el->SetClass(config_group_title_class, true);
{
Rml::Element *text_el = title_el->AppendChild(doc->CreateTextNode("replace me"));
text_el->SetId("config-group-label");
} // title_el
Rml::Element *div_el = AppendChild(doc->CreateElement("div"));
div_el->SetClass(config_group_wrapper_class, true);
}
}
ElementConfigGroup::~ElementConfigGroup()
{
}
void ElementConfigGroup::SetTextLabel(const std::string& s) {
Rml::Element *title_container = GetChild(0);
Rml::ElementText *label = (Rml::ElementText *)title_container->GetElementById("config-group-label");
label->SetText(s);
DirtyLayout();
}
void ElementConfigGroup::ToggleTextLabelVisibility(bool show) {
Rml::Element *title_container = GetChild(0);
title_container->SetClass(config_group_title_class_hidden, !show);
}
void ElementConfigGroup::AddConfigOptionElement(const json& option_json) {
ConfigOptionType el_option_type = ConfigOptionType::Label;
from_json(option_json["type"], el_option_type);
const std::string key = recomp::config::get_string_in_json(option_json, ConfigOption::schema::key);
Rml::Element *option_container = GetChild(1);
Rml::Element *child_opt = nullptr;
if (config_option_is_group(el_option_type)) {
child_opt = (ElementConfigGroup *)option_container->AppendChild(
recompui::create_custom_element(GetOwnerDocument(), "recomp-config-group")
);
// TODO: Base class with option type + config_key
((ElementConfigGroup *)child_opt)->option_type = el_option_type;
} else {
child_opt = (ElementConfigOption *)option_container->AppendChild(
recompui::create_custom_element(GetOwnerDocument(), "recomp-config-option")
);
// TODO: Base class with option type + config_key
ElementConfigOption *opt_as_conf_opt = (ElementConfigOption *)child_opt;
opt_as_conf_opt->option_type = el_option_type;
opt_as_conf_opt->in_checkbox_group = option_type == ConfigOptionType::CheckboxGroup;
}
std::string full_key = config_key + "/" + key;
child_opt->SetAttribute("recomp-data", full_key);
}
static nlohmann::json get_options(std::string& config_key) {
if (recomp::config::config_key_is_base_group(config_key)) {
return recomp::config::get_group_json(config_key);
}
const json& group_json = recomp::config::get_json_from_key(config_key);
return group_json["options"];
}
void ElementConfigGroup::OnAttributeChange(const Rml::ElementAttributes& changed_attributes)
{
// Call through to the base element's OnAttributeChange().
Rml::Element::OnAttributeChange(changed_attributes);
auto config_store_key_attr = changed_attributes.find("recomp-data");
if (config_store_key_attr != changed_attributes.end() && config_store_key_attr->second.GetType() == Rml::Variant::STRING) {
config_key = config_store_key_attr->second.Get<Rml::String>();
bool is_base_group = recomp::config::config_key_is_base_group(config_key);
option_type = ConfigOptionType::Label;
if (is_base_group) {
SetClass(config_group_base_class_scrollable, true);
option_type = ConfigOptionType::Group;
ToggleTextLabelVisibility(false);
} else {
try {
auto value = recomp::config::get_config_store_value<std::string>("translations/" + config_key);
SetTextLabel(value);
} catch (const std::runtime_error& e) {
SetTextLabel(e.what());
}
const json& group_json = recomp::config::get_json_from_key(config_key);
from_json(group_json["type"], option_type);
assert(
option_type == ConfigOptionType::Group || option_type == ConfigOptionType::CheckboxGroup);
}
const nlohmann::json& options = get_options(config_key);
for (size_t i = 0; i < options.size(); i++) {
const auto &el = options[i];
AddConfigOptionElement(el);
}
DirtyLayout();
}
}
} // namespace Rml

View File

@ -1,28 +0,0 @@
#ifndef RECOMPUI_ELEMENTS_CONFIG_GROUP_H
#define RECOMPUI_ELEMENTS_CONFIG_GROUP_H
#include "common.h"
namespace recompui {
/**
Base custom element representing a single config option.
Maps to other custom elements.
*/
class ElementConfigGroup : public Rml::Element {
public:
ElementConfigGroup(const Rml::String& tag);
virtual ~ElementConfigGroup();
recomp::config::ConfigOptionType option_type;
std::string config_key;
protected:
void OnAttributeChange(const Rml::ElementAttributes& changed_attributes);
void AddConfigOptionElement(const nlohmann::json& option_json);
void SetTextLabel(const std::string& s);
void ToggleTextLabelVisibility(bool show);
};
}
#endif

View File

@ -1,166 +0,0 @@
#include "ElementConfigOption.h"
#include "../ui_elements.h"
#include <string>
using json = nlohmann::json;
using ConfigOptionType = recomp::config::ConfigOptionType;
namespace recompui {
static const std::string option_type_wrapper_id = "checkbox__input";
static const std::string config_option_base_class = "config-option";
static const std::string config_option_base_class_hz = config_option_base_class + "--hz";
static const std::string config_option_title_class = config_option_base_class + "__title";
static const std::string config_option_wrapper = config_option_base_class + "__list"; // TODO: move hz listing to radio tabs, make this container dumber
ElementConfigOption::ElementConfigOption(const Rml::String& tag) : Rml::Element(tag)
{
Rml::ElementDocument *doc = GetOwnerDocument();
SetAttribute("recomp-store-element", true);
SetClass(config_option_base_class, true);
{
Rml::Element *label_el = AppendChild(doc->CreateElement("label"));
label_el->SetClass(config_option_title_class, true);
{
Rml::Element *label_text_el = label_el->AppendChild(doc->CreateTextNode("Unknown"));
label_text_el->SetAttribute("id", "config-opt-label");
} // label_el
Rml::Element *option_type_wrapper = AppendChild(doc->CreateElement("div"));
option_type_wrapper->SetId(option_type_wrapper_id);
option_type_wrapper->SetClass(config_option_wrapper, true);
} // base element
AddEventListener(Rml::EventId::Mouseover, this, true);
}
ElementConfigOption::~ElementConfigOption()
{
RemoveEventListener(Rml::EventId::Mouseover, this, true);
}
Rml::Element *ElementConfigOption::GetLabel() {
Rml::ElementText *text_label = (Rml::ElementText *)GetElementById("config-opt-label");
return text_label->GetParentNode();
}
void ElementConfigOption::SetTextLabel(const std::string& s) {
Rml::ElementText *text_label = (Rml::ElementText *)GetElementById("config-opt-label");
text_label->SetText(s);
DirtyLayout();
}
Rml::Element *ElementConfigOption::GetOptionTypeWrapper() {
return GetElementById(option_type_wrapper_id);
}
template <typename T>
static void add_option_el(Rml::ElementDocument *doc, Rml::Element *wrapper, const std::string& tag, std::string& config_key) {
T *opt = (T *)wrapper->AppendChild(recompui::create_custom_element(doc, tag));
opt->init_option(config_key);
}
void ElementConfigOption::AddOptionTypeElement() {
ConfigOptionType el_option_type = ConfigOptionType::Label;
const json& option_json = recomp::config::get_json_from_key(config_key);
recomp::config::from_json(option_json["type"], el_option_type);
Rml::Element *wrapper = GetOptionTypeWrapper();
Rml::ElementDocument *doc = GetOwnerDocument();
switch (el_option_type) {
default:
printf("No option type element exists for type '%u'\n", static_cast<uint32_t>(el_option_type));
return;
case ConfigOptionType::Button: {
add_option_el<ElementOptionTypeButton>(doc, wrapper, "recomp-option-type-button", config_key);
// Button contains label text, so hide the label
auto label = GetLabel();
label->SetProperty("display", "none");
break;
}
case ConfigOptionType::Checkbox: {
add_option_el<ElementOptionTypeCheckbox>(doc, wrapper, "recomp-option-type-checkbox", config_key);
break;
}
case ConfigOptionType::Color: {
add_option_el<ElementOptionTypeColor>(doc, wrapper, "recomp-option-type-color", config_key);
break;
}
case ConfigOptionType::Dropdown: {
add_option_el<ElementOptionTypeDropdown>(doc, wrapper, "recomp-option-type-dropdown", config_key);
break;
}
case ConfigOptionType::TextField: {
add_option_el<ElementOptionTypeTextField>(doc, wrapper, "recomp-option-type-textfield", config_key);
break;
}
case ConfigOptionType::RadioTabs: {
add_option_el<ElementOptionTypeRadioTabs>(doc, wrapper, "recomp-option-type-radio-tabs", config_key);
break;
}
case ConfigOptionType::Range: {
add_option_el<ElementOptionTypeRange>(doc, wrapper, "recomp-option-type-range", config_key);
break;
}
}
}
void ElementConfigOption::OnAttributeChange(const Rml::ElementAttributes& changed_attributes)
{
// Call through to the base element's OnAttributeChange().
Rml::Element::OnAttributeChange(changed_attributes);
bool dirty_layout = false;
auto config_store_key_attr = changed_attributes.find("recomp-data");
if (config_store_key_attr != changed_attributes.end() && config_store_key_attr->second.GetType() == Rml::Variant::STRING) {
config_key = config_store_key_attr->second.Get<Rml::String>();
if (in_checkbox_group) {
SetClass(config_option_base_class_hz, true);
}
Rml::Element *label = GetLabel();
label->SetAttribute("for", "input__" + config_key);
try {
auto value = recomp::config::get_config_store_value<std::string>("translations/" + config_key);
SetTextLabel(value);
AddOptionTypeElement();
} catch (const std::runtime_error& e) {
SetTextLabel(e.what());
}
dirty_layout = true;
}
if (dirty_layout) {
DirtyLayout();
}
}
void ElementConfigOption::ProcessEvent(Rml::Event& event)
{
// Set description key
if (event == Rml::EventId::Mouseover)
{
if (event.GetPhase() == Rml::EventPhase::Capture || event.GetPhase() == Rml::EventPhase::Target)
{
Rml::ElementList elements;
Rml::ElementDocument *doc = GetOwnerDocument();
GetElementsByTagName(elements, "input");
doc->GetElementsByTagName(elements, "recomp-description");
for (size_t i = 0; i < elements.size(); i++) {
Rml::Element *el = elements[i];
el->SetAttribute("recomp-data", config_key);
}
}
}
}
} // namespace Rml

View File

@ -1,32 +0,0 @@
#ifndef RECOMPUI_ELEMENTS_CONFIG_OPTION_H
#define RECOMPUI_ELEMENTS_CONFIG_OPTION_H
#include "common.h"
namespace recompui {
/**
Base custom element representing a single config option.
Maps to other custom elements.
*/
class ElementConfigOption : public Rml::Element, public Rml::EventListener {
public:
ElementConfigOption(const Rml::String& tag);
virtual ~ElementConfigOption();
recomp::config::ConfigOptionType option_type;
std::string config_key;
bool in_checkbox_group = false;
protected:
void OnAttributeChange(const Rml::ElementAttributes& changed_attributes);
Rml::Element *GetLabel(void);
void SetTextLabel(const std::string& s);
void AddOptionTypeElement();
Rml::Element *GetOptionTypeWrapper();
void ProcessEvent(Rml::Event& event) override;
};
}
#endif

View File

@ -1,57 +0,0 @@
#include "ElementDescription.h"
#include <string>
using json = nlohmann::json;
namespace recompui {
static const std::string cls_base = "config-description";
static const std::string cls_contents = cls_base + "__contents";
static const std::string contents_id = cls_base + "__contents-text";
static const std::string default_contents = "";
ElementDescription::ElementDescription(const Rml::String& tag) : Rml::Element(tag)
{
SetAttribute("recomp-store-element", true);
Rml::ElementDocument *doc = GetOwnerDocument();
SetClass(cls_base, true);
{
Rml::Element *p_el = AppendChild(doc->CreateElement("p"));
p_el->SetClass(cls_contents, true);
p_el->SetId(contents_id);
}
}
ElementDescription::~ElementDescription()
{
}
void ElementDescription::update_text(const std::string& text) {
auto *p_el = GetElementById(contents_id);
p_el->SetInnerRML(text);
DirtyLayout();
}
void ElementDescription::OnAttributeChange(const Rml::ElementAttributes& changed_attributes)
{
// Call through to the base element's OnAttributeChange().
Rml::Element::OnAttributeChange(changed_attributes);
auto config_store_key_attr = changed_attributes.find("recomp-data");
if (config_store_key_attr != changed_attributes.end() && config_store_key_attr->second.GetType() == Rml::Variant::STRING) {
config_key = config_store_key_attr->second.Get<Rml::String>();
try {
auto value = recomp::config::get_config_store_value<std::string>("translations/" + config_key + ":description");
update_text(value);
} catch (const std::runtime_error& e) {
update_text(default_contents);
}
}
}
} // namespace Rml

View File

@ -1,21 +0,0 @@
#ifndef RECOMPUI_ELEMENT_DESCRIPTION_H
#define RECOMPUI_ELEMENT_DESCRIPTION_H
#include "common.h"
namespace recompui {
class ElementDescription : public Rml::Element {
public:
ElementDescription(const Rml::String& tag);
virtual ~ElementDescription();
std::string config_key;
protected:
void update_text(const std::string& text_rml);
private:
void OnAttributeChange(const Rml::ElementAttributes& changed_attributes);
};
} // namespace recompui
#endif

View File

@ -1,16 +0,0 @@
#include "ElementOptionType.h"
namespace recompui {
ElementOptionType::ElementOptionType(const Rml::String& tag, const std::string& base_class) : Rml::Element(tag)
{
SetAttribute("recomp-store-element", true);
SetClass(base_class, true);
}
ElementOptionType::~ElementOptionType()
{
}
} // namespace Rml

View File

@ -1,20 +0,0 @@
#ifndef RECOMPUI_ELEMENT_OPTION_TYPE_H
#define RECOMPUI_ELEMENT_OPTION_TYPE_H
#include "common.h"
// base class for ElementOptionTypes. Already set up as an event listener,
// and contains required data. Initialization sets an important flag.
namespace recompui {
class ElementOptionType : public Rml::Element, public Rml::EventListener {
public:
ElementOptionType(const Rml::String& tag, const std::string& base_class);
virtual ~ElementOptionType();
std::string config_key;
};
} // namespace recompui
#endif

View File

@ -1,61 +0,0 @@
#include "ElementOptionTypeButton.h"
#include <string>
using json = nlohmann::json;
namespace recompui {
static const std::string button_id = "recomp-button";
static const std::string cls_base = "config-option-button";
static const std::string cls_button = "button";
ElementOptionTypeButton::ElementOptionTypeButton(const Rml::String& tag) : ElementOptionType(tag, cls_base)
{
Rml::Element *button = AppendChild(GetOwnerDocument()->CreateElement("button"));
button->SetClass(cls_button, true);
button->SetId(button_id);
button->AddEventListener(Rml::EventId::Click, this, false);
}
ElementOptionTypeButton::~ElementOptionTypeButton()
{
auto button_el = get_button();
button_el->RemoveEventListener(Rml::EventId::Click, this, false);
}
Rml::Element *ElementOptionTypeButton::get_button()
{
return GetElementById(button_id);
}
void ElementOptionTypeButton::init_option(std::string& _config_key) {
config_key = _config_key;
const json& option_json = recomp::config::get_json_from_key(config_key);
auto button_el = get_button();
button_el->SetInnerRML(
recomp::config::get_config_store_value<std::string>("translations/" + config_key)
);
std::string variantClass = recomp::config::get_value_in_json_with_default<std::string>(option_json, "variant", "primary");
button_el->SetClass(cls_button + "--" + variantClass, true);
}
void ElementOptionTypeButton::ProcessEvent(Rml::Event& event)
{
if (event == Rml::EventId::Click)
{
if (event.GetPhase() == Rml::EventPhase::Bubble || event.GetPhase() == Rml::EventPhase::Target)
{
printf("Button clicked\n");
}
}
}
} // namespace Rml

View File

@ -1,22 +0,0 @@
#ifndef RECOMPUI_ELEMENT_OPTION_TYPE_BUTTON_H
#define RECOMPUI_ELEMENT_OPTION_TYPE_BUTTON_H
#include "common.h"
#include "ElementOptionType.h"
namespace recompui {
class ElementOptionTypeButton : public ElementOptionType {
public:
ElementOptionTypeButton(const Rml::String& tag);
virtual ~ElementOptionTypeButton();
void init_option(std::string& _config_key);
protected:
void ProcessEvent(Rml::Event& event) override;
private:
Rml::Element* get_button();
};
} // namespace recompui
#endif

View File

@ -1,75 +0,0 @@
#include "ElementOptionTypeCheckbox.h"
#include <string>
using json = nlohmann::json;
namespace recompui {
static const std::string checkbox_input_id = "checkbox__input";
ElementOptionTypeCheckbox::ElementOptionTypeCheckbox(const Rml::String& tag) : Rml::Element(tag)
{
SetAttribute("recomp-store-element", true);
Rml::ElementDocument *doc = GetOwnerDocument();
SetClass("config-option__checkbox-wrapper", true);
{
Rml::Element *checkbox_el = AppendChild(doc->CreateElement("input"));
checkbox_el->SetId(checkbox_input_id);
checkbox_el->SetClass("config-option__checkbox", true);
checkbox_el->SetAttribute("type", "checkbox");
}
AddEventListener(Rml::EventId::Click, this, true);
}
ElementOptionTypeCheckbox::~ElementOptionTypeCheckbox()
{
RemoveEventListener(Rml::EventId::Click, this, true);
}
Rml::ElementFormControlInput *ElementOptionTypeCheckbox::get_input() {
return (Rml::ElementFormControlInput *)GetElementById(checkbox_input_id);
}
void ElementOptionTypeCheckbox::set_checked(bool checked) {
auto *input_el = get_input();
if (checked) {
SetAttribute("checked", true);
input_el->SetAttribute("checked", true);
} else {
RemoveAttribute("checked");
input_el->RemoveAttribute("checked");
}
DirtyLayout();
}
void ElementOptionTypeCheckbox::init_option(std::string& _config_key) {
config_key = _config_key;
const json& option_json = recomp::config::get_json_from_key(config_key);
int value = recomp::config::get_config_store_value<int>(config_key);
set_checked(value);
}
void ElementOptionTypeCheckbox::ProcessEvent(Rml::Event& event)
{
// Forward clicks to the target.
if (event == Rml::EventId::Click && !disable_click)
{
if (event.GetPhase() == Rml::EventPhase::Capture || event.GetPhase() == Rml::EventPhase::Target)
{
bool new_value = !recomp::config::get_config_store_value<int>(config_key);
recomp::config::set_config_store_value(config_key, new_value);
set_checked(new_value);
}
}
}
Rml::Element* ElementOptionTypeCheckbox::GetTarget()
{
return get_input();
}
} // namespace Rml

View File

@ -1,31 +0,0 @@
#ifndef RECOMPUI_ELEMENT_OPTION_TYPE_CHECKBOX_H
#define RECOMPUI_ELEMENT_OPTION_TYPE_CHECKBOX_H
#include "common.h"
namespace recompui {
class ElementOptionTypeCheckbox : public Rml::Element, public Rml::EventListener {
public:
ElementOptionTypeCheckbox(const Rml::String& tag);
virtual ~ElementOptionTypeCheckbox();
void init_option(std::string& _config_key);
std::string config_key;
const recomp::config::ConfigOptionType option_type = recomp::config::ConfigOptionType::Checkbox;
protected:
Rml::ElementFormControlInput *get_input();
void ProcessEvent(Rml::Event& event) override;
private:
Element* GetTarget();
void set_checked(bool checked);
bool disable_click = false;
};
} // namespace recompui
#endif

View File

@ -1,183 +0,0 @@
#include "ElementOptionTypeColor.h"
#include <string>
#include <math.h>
using json = nlohmann::json;
namespace recompui {
static const std::string range_input_id = "recomp-color-range:"; // + H/S/V
static const std::string range_label_id = "recomp-color-range-label:"; // + H/S/V
static const std::string hsv_label[] = {"H", "S", "V"};
static const std::string preview_block_id = "recomp-color-block";
static const std::string cls_base = "config-option-color";
static const std::string cls_color_preview_wrapper = cls_base + "__preview-wrapper";
static const std::string cls_color_preview_block = cls_base + "__preview-block";
static const std::string cls_color_hsv_wrapper = cls_base + "__hsv-wrapper";
// TODO: use these 3 directly from ElementOptionTypeRange
static const std::string range_cls_base = "config-option-range";
static const std::string range_cls_label = cls_base + "__label";
static const std::string range_cls_range_input = cls_base + "__range-input";
ElementOptionTypeColor::ElementOptionTypeColor(const Rml::String& tag) : Rml::Element(tag)
{
SetAttribute("recomp-store-element", true);
SetClass(cls_base, true);
hsv.h = 0;
hsv.s = 0;
hsv.v = 0;
Rml::ElementDocument *doc = GetOwnerDocument();
{
Rml::Element *preview_wrapper = AppendChild(doc->CreateElement("div"));
preview_wrapper->SetClass(cls_color_preview_wrapper, true);
{
Rml::Element *preview_block = preview_wrapper->AppendChild(doc->CreateElement("div"));
preview_block->SetClass(cls_color_preview_block, true);
preview_block->SetId(preview_block_id);
Rml::Element *hsv_wrapper = preview_wrapper->AppendChild(doc->CreateElement("div"));
hsv_wrapper->SetClass(cls_color_hsv_wrapper, true);
for (size_t i = 0; i < 3; i++) {
const auto &label = hsv_label[i];
Rml::Element *range_wrapper = hsv_wrapper->AppendChild(doc->CreateElement("div"));
range_wrapper->SetClass(range_cls_base, true);
{
Rml::Element *label_el = range_wrapper->AppendChild(doc->CreateElement("label"));
label_el->SetClass(range_cls_label, true);
label_el->SetId(range_label_id);
{
Rml::Element *text_node = label_el->AppendChild(doc->CreateTextNode(""));
text_node->SetId(range_label_id + label);
}
Rml::ElementFormControlInput *range_el = (Rml::ElementFormControlInput *)range_wrapper->AppendChild(doc->CreateElement("input"));
range_el->SetClass(range_cls_range_input, true);
range_el->SetId(range_input_id + label);
range_el->SetAttribute("type", "range");
range_el->SetAttribute("min", 0);
range_el->SetAttribute("hsv-index", i);
if (i == 0) {
range_el->SetValue(std::to_string((int)round(hsv[i])));
range_el->SetAttribute("max", 360);
} else {
range_el->SetValue(std::to_string((int)round(hsv[i] * 100.0f)));
range_el->SetAttribute("max", 100);
}
range_el->AddEventListener(Rml::EventId::Change, this, false);
}
}
}
// TODO: RGB hex input
}
}
ElementOptionTypeColor::~ElementOptionTypeColor()
{
Rml::ElementList elements;
GetElementsByTagName(elements, "input");
for (size_t i = 0; i < elements.size(); i++) {
Rml::Element *el = elements[i];
el->RemoveEventListener(Rml::EventId::Click, this, false);
}
}
void ElementOptionTypeColor::set_value_label(int hsvIndex) {
const auto value = hsv[hsvIndex];
const auto& which = hsv_label[hsvIndex];
Rml::ElementText *text_label = (Rml::ElementText *)GetElementById(range_label_id + which);
if (hsvIndex == 0) {
text_label->SetText(which + ": " + std::to_string((int)round(value)));
} else {
text_label->SetText(which + ": " + std::to_string((int)round(value * 100.0f)));
}
DirtyLayout();
}
void ElementOptionTypeColor::set_preview_block_rgb(RgbColor rgb) {
Rml::Element *color_block = GetElementById(preview_block_id);
char hex_buf[8]; // Enough to hold "#RRGGBB\0"
sprintf(hex_buf, "#%02x%02x%02x", rgb.r, rgb.g, rgb.b);
const std::string hex_val = std::string(hex_buf);
color_block->SetProperty("background-color", hex_val);
}
void ElementOptionTypeColor::set_config_store_rgb() {
RgbColor rgb;
HsvFToRgb(hsv, rgb);
recomp::config::set_config_store_value(config_key + ":r", rgb.r);
recomp::config::set_config_store_value(config_key + ":g", rgb.g);
recomp::config::set_config_store_value(config_key + ":b", rgb.b);
set_preview_block_rgb(rgb);
}
void ElementOptionTypeColor::init_option(std::string& _config_key) {
config_key = _config_key;
const json& option_json = recomp::config::get_json_from_key(config_key);
RgbColor col;
HsvColor hsv_uc;
col.r = recomp::config::get_config_store_value<int>(config_key + ":r");
col.g = recomp::config::get_config_store_value<int>(config_key + ":g");
col.b = recomp::config::get_config_store_value<int>(config_key + ":b");
RgbToHsv(col, hsv_uc);
hsv.h = std::clamp(hsv_uc.h * 360.0f, 0.0f, 360.0f);
hsv.s = std::clamp((float)hsv_uc.s / 255.0f, 0.0f, 1.0f);
hsv.v = std::clamp((float)hsv_uc.v / 255.0f, 0.0f, 1.0f);
set_preview_block_rgb(col);
for (size_t i = 0; i < 3; i++) {
const auto &label = hsv_label[i];
Rml::ElementFormControlInput *range = (Rml::ElementFormControlInput *)GetElementById(range_input_id + label);
if (i == 0) {
range->SetValue(std::to_string((int)round(hsv[i])));
} else {
range->SetValue(std::to_string((int)round(hsv[i] * 100.0f)));
}
set_value_label(i);
}
}
void ElementOptionTypeColor::ProcessEvent(Rml::Event& event)
{
if (event == Rml::EventId::Change)
{
if (event.GetPhase() == Rml::EventPhase::Bubble || event.GetPhase() == Rml::EventPhase::Target)
{
Rml::Element *target = event.GetTargetElement();
auto val_variant = target->GetAttribute("value");
int new_value = val_variant->Get<int>();
auto idx_variant = target->GetAttribute("hsv-index");
auto hsv_index = idx_variant->Get<int>();
if (hsv_index == 0) {
hsv[hsv_index] = (float)new_value;
} else {
hsv[hsv_index] = (float)new_value / 100.0f;
}
set_value_label(hsv_index);
set_config_store_rgb();
}
}
}
} // namespace Rml

View File

@ -1,26 +0,0 @@
#ifndef RECOMPUI_ELEMENT_OPTION_TYPE_COLOR_H
#define RECOMPUI_ELEMENT_OPTION_TYPE_COLOR_H
#include "common.h"
namespace recompui {
class ElementOptionTypeColor : public Rml::Element, public Rml::EventListener {
public:
ElementOptionTypeColor(const Rml::String& tag);
virtual ~ElementOptionTypeColor();
std::string config_key;
HsvColorF hsv;
void init_option(std::string& _config_key);
protected:
void set_value_label(int hsvIndex);
void set_config_store_rgb();
void set_preview_block_rgb(RgbColor rgb);
void ProcessEvent(Rml::Event& event) override;
};
} // namespace recompui
#endif

View File

@ -1,79 +0,0 @@
#include "ElementOptionTypeDropdown.h"
#include <string>
using json = nlohmann::json;
namespace recompui {
static const std::string select_id = "recomp-select";
static const std::string select_option_id = "recomp-select-option__";
static const std::string cls_base = "config-option-dropdown";
static const std::string cls_select = cls_base + "__select";
ElementOptionTypeDropdown::ElementOptionTypeDropdown(const Rml::String& tag) : ElementOptionType(tag, cls_base)
{
Rml::ElementFormControlSelect *select_el = (Rml::ElementFormControlSelect *)AppendChild(GetOwnerDocument()->CreateElement("select"));
select_el->SetId(select_id);
select_el->SetValue("0");
select_el->AddEventListener(Rml::EventId::Change, this, false);
select_el->SetClass(cls_select, true);
}
ElementOptionTypeDropdown::~ElementOptionTypeDropdown()
{
auto select_el = get_select();
RemoveEventListener(Rml::EventId::Change, this, false);
}
Rml::ElementFormControlSelect *ElementOptionTypeDropdown::get_select()
{
return (Rml::ElementFormControlSelect *)GetElementById(select_id);
}
void ElementOptionTypeDropdown::set_cur_option(int opt) {
auto select_el = get_select();
select_el->SetValue(std::to_string(opt));
DirtyLayout();
}
void ElementOptionTypeDropdown::init_option(std::string& _config_key) {
config_key = _config_key;
const json& option_json = recomp::config::get_json_from_key(config_key);;
int opt = recomp::config::get_config_store_value<int>(config_key);
const json& opt_array = option_json["values"];
auto select_el = get_select();
for (size_t i = 0; i < opt_array.size(); i++) {
const auto &j_opt = opt_array[i];
const std::string opt_val = j_opt.get<std::string>();
const std::string opt_id = select_option_id + config_key + "--" + opt_val;
const std::string translation_key = "translations/" + config_key + "/values/" + opt_val;
const std::string& opt_text = recomp::config::get_config_store_value<std::string>(translation_key);
select_el->Add(opt_text, std::to_string(i));
}
set_cur_option(opt);
}
void ElementOptionTypeDropdown::ProcessEvent(Rml::Event& event)
{
if (event == Rml::EventId::Change)
{
if (event.GetPhase() == Rml::EventPhase::Bubble || event.GetPhase() == Rml::EventPhase::Target)
{
Rml::Element *target = event.GetTargetElement();
auto val_variant = target->GetAttribute("value");
int new_value = val_variant->Get<int>();
recomp::config::set_config_store_value(config_key, new_value);
}
}
}
} // namespace Rml

View File

@ -1,24 +0,0 @@
#ifndef RECOMPUI_ELEMENT_OPTION_TYPE_DROPDOWN_H
#define RECOMPUI_ELEMENT_OPTION_TYPE_DROPDOWN_H
#include "common.h"
#include "ElementOptionType.h"
namespace recompui {
class ElementOptionTypeDropdown : public ElementOptionType {
public:
ElementOptionTypeDropdown(const Rml::String& tag);
virtual ~ElementOptionTypeDropdown();
void init_option(std::string& _config_key);
protected:
void ProcessEvent(Rml::Event& event) override;
private:
void set_cur_option(int opt);
Rml::ElementFormControlSelect *get_select();
};
} // namespace recompui
#endif

View File

@ -1,94 +0,0 @@
#include "ElementOptionTypeRadioTabs.h"
#include <string>
using json = nlohmann::json;
namespace recompui {
static const std::string radio_input_id = "recomp-radio__";
ElementOptionTypeRadioTabs::ElementOptionTypeRadioTabs(const Rml::String& tag) : Rml::Element(tag)
{
SetAttribute("recomp-store-element", true);
SetClass("config-option__radio-tabs", true);
}
ElementOptionTypeRadioTabs::~ElementOptionTypeRadioTabs()
{
Rml::ElementList elements;
GetElementsByTagName(elements, "input");
for (size_t i = 0; i < elements.size(); i++) {
Rml::Element *el = elements[i];
el->RemoveEventListener(Rml::EventId::Click, this, false);
}
}
void ElementOptionTypeRadioTabs::set_cur_option(int opt) {
Rml::ElementList elements;
GetElementsByTagName(elements, "input");
for (size_t i = 0; i < elements.size(); i++) {
Rml::Element *el = elements[i];
if (static_cast<int>(i) == opt) {
SetAttribute("checked", true);
el->SetAttribute("checked", true);
} else {
RemoveAttribute("checked");
el->RemoveAttribute("checked");
}
}
DirtyLayout();
}
void ElementOptionTypeRadioTabs::init_option(std::string& _config_key) {
config_key = _config_key;
const json& option_json = recomp::config::get_json_from_key(config_key);
int opt = recomp::config::get_config_store_value<int>(config_key);
const json& opt_array = option_json["values"];
for (size_t i = 0; i < opt_array.size(); i++) {
const auto &j_opt = opt_array[i];
const std::string opt_val = j_opt.get<std::string>();
const std::string opt_id = radio_input_id + config_key + "--" + opt_val;
const std::string translation_key = "translations/" + config_key + "/values/" + opt_val;
const std::string& opt_text = recomp::config::get_config_store_value<std::string>(translation_key);
Rml::Element *radio_el = AppendChild(GetOwnerDocument()->CreateElement("input"));
radio_el->SetId(opt_id);
radio_el->SetAttribute("type", "radio");
radio_el->SetAttribute("value", i);
radio_el->AddEventListener(Rml::EventId::Click, this, false);
// TODO: focus event set description
// TODO: blur event clear description
Rml::Element *label_el = AppendChild(GetOwnerDocument()->CreateElement("label"));
label_el->SetAttribute("for", opt_id);
label_el->SetClass("config-option__tab-label", true);
{
label_el->AppendChild(GetOwnerDocument()->CreateTextNode(opt_text));
}
}
set_cur_option(opt);
}
void ElementOptionTypeRadioTabs::ProcessEvent(Rml::Event& event)
{
// Forward clicks to the target.
if (event == Rml::EventId::Click)
{
if (event.GetPhase() == Rml::EventPhase::Bubble || event.GetPhase() == Rml::EventPhase::Target)
{
Rml::Element *target = event.GetTargetElement();
auto val_variant = target->GetAttribute("value");
int new_value = val_variant->Get<int>();
recomp::config::set_config_store_value(config_key, new_value);
set_cur_option(new_value);
}
}
}
} // namespace Rml

View File

@ -1,23 +0,0 @@
#ifndef RECOMPUI_ELEMENT_OPTION_TYPE_RADIO_TABS_H
#define RECOMPUI_ELEMENT_OPTION_TYPE_RADIO_TABS_H
#include "common.h"
namespace recompui {
class ElementOptionTypeRadioTabs : public Rml::Element, public Rml::EventListener {
public:
ElementOptionTypeRadioTabs(const Rml::String& tag);
virtual ~ElementOptionTypeRadioTabs();
std::string config_key;
void init_option(std::string& _config_key);
protected:
void ProcessEvent(Rml::Event& event) override;
private:
void set_cur_option(int opt);
};
} // namespace recompui
#endif

View File

@ -1,92 +0,0 @@
#include "ElementOptionTypeRange.h"
#include <string>
#include <RmlUi/Core/ElementDocument.h>
#include <RmlUi/Core/ElementText.h>
using json = nlohmann::json;
namespace recompui {
static const std::string range_label_id = "recomp-range__label";
static const std::string range_label_text_id = "recomp-range__label-text";
static const std::string range_input_id = "recomp-range__input";
static const std::string cls_base = "config-option-range";
static const std::string cls_label = cls_base + "__label";
static const std::string cls_range_input = cls_base + "__range-input";
ElementOptionTypeRange::ElementOptionTypeRange(const Rml::String& tag) : Rml::Element(tag)
{
SetAttribute("recomp-store-element", true);
SetClass(cls_base, true);
Rml::ElementDocument *doc = GetOwnerDocument();
{
Rml::Element *label_el = AppendChild(doc->CreateElement("label"));
label_el->SetClass(cls_label, true);
label_el->SetId(range_label_id);
{
Rml::Element *text_node = label_el->AppendChild(doc->CreateTextNode(""));
text_node->SetId(range_label_text_id);
}
Rml::Element *range_el = AppendChild(doc->CreateElement("input"));
range_el->SetClass(cls_range_input, true);
range_el->SetId(range_input_id);
range_el->SetAttribute("type", "range");
range_el->AddEventListener(Rml::EventId::Change, this, false);
// TODO: focus event set description
// TODO: blur event clear description
}
}
ElementOptionTypeRange::~ElementOptionTypeRange()
{
Rml::Element *range = GetElementById(range_input_id);
range->RemoveEventListener(Rml::EventId::Change, this, false);
}
void ElementOptionTypeRange::set_value_label(int value) {
Rml::ElementText *text_label = (Rml::ElementText *)GetElementById(range_label_text_id);
text_label->SetText(std::to_string(value) + suffix);
DirtyLayout();
}
void ElementOptionTypeRange::init_option(std::string& _config_key) {
config_key = _config_key;
const json& option_json = recomp::config::get_json_from_key(config_key);
const int value = recomp::config::get_config_store_value<int>(config_key);
suffix = recomp::config::get_string_in_json_with_default(option_json, "suffix", "");
const int min = recomp::config::get_value_in_json<int>(option_json, "min");
const int max = recomp::config::get_value_in_json<int>(option_json, "max");
const int step = recomp::config::get_value_in_json_with_default<int>(option_json, "step", 1);
Rml::ElementFormControlInput *range = (Rml::ElementFormControlInput *)GetElementById(range_input_id);
range->SetAttribute("min", min);
range->SetAttribute("max", max);
range->SetAttribute("step", step);
range->SetValue(std::to_string(value));
set_value_label(value);
}
void ElementOptionTypeRange::ProcessEvent(Rml::Event& event)
{
if (event == Rml::EventId::Change)
{
if (event.GetPhase() == Rml::EventPhase::Bubble || event.GetPhase() == Rml::EventPhase::Target)
{
Rml::ElementFormControlInput *target = (Rml::ElementFormControlInput *)event.GetTargetElement();
auto val_s = target->GetValue();
int new_value = std::stoi(val_s);
recomp::config::set_config_store_value(config_key, new_value);
set_value_label(new_value);
}
}
}
} // namespace Rml

View File

@ -1,26 +0,0 @@
#ifndef RECOMPUI_ELEMENT_OPTION_TYPE_RANGE_H
#define RECOMPUI_ELEMENT_OPTION_TYPE_RANGE_H
#include "common.h"
namespace recompui {
class ElementOptionTypeRange : public Rml::Element, public Rml::EventListener {
public:
ElementOptionTypeRange(const Rml::String& tag);
virtual ~ElementOptionTypeRange();
std::string config_key;
std::string suffix;
void init_option(std::string& _config_key);
protected:
void ProcessEvent(Rml::Event& event) override;
private:
void set_cur_option(int opt);
void set_value_label(int value);
};
} // namespace recompui
#endif

View File

@ -1,67 +0,0 @@
#include "ElementOptionTypeTextField.h"
#include <string>
using json = nlohmann::json;
namespace recompui {
static const std::string input_id = "recomp-textfield";
static const std::string cls_base = "config-option-textfield";
static const std::string cls_wrapper = cls_base + "__wrapper";
static const std::string cls_input = cls_base + "__input";
ElementOptionTypeTextField::ElementOptionTypeTextField(const Rml::String& tag) : ElementOptionType(tag, cls_base)
{
Rml::Element *wrapper = AppendChild(GetOwnerDocument()->CreateElement("label"));
wrapper->SetClass(cls_wrapper, true);
Rml::ElementFormControlSelect *input_el = (Rml::ElementFormControlSelect *)wrapper->AppendChild(GetOwnerDocument()->CreateElement("input"));
input_el->SetId(input_id);
input_el->SetValue("");
input_el->AddEventListener(Rml::EventId::Change, this, false);
input_el->SetClass(cls_input, true);
}
Rml::ElementFormControlInput *ElementOptionTypeTextField::get_input()
{
return (Rml::ElementFormControlInput *)GetElementById(input_id);
}
ElementOptionTypeTextField::~ElementOptionTypeTextField()
{
auto input_el = get_input();
input_el->RemoveEventListener(Rml::EventId::Change, this, false);
}
void ElementOptionTypeTextField::init_option(std::string& _config_key) {
config_key = _config_key;
const json& option_json = recomp::config::get_json_from_key(config_key);;
auto val = recomp::config::get_config_store_value<std::string>(config_key);
auto input_el = get_input();
input_el->SetValue(val);
const auto maxlength = recomp::config::get_value_in_json<int>(option_json, "maxlength");
input_el->SetAttribute("maxlength", std::to_string(maxlength));
// RMLUI sadly doesn't support placeholders yet, so this will be a _placeholder_ until thats ready.
input_el->SetAttribute("placeholder", recomp::config::get_config_store_value_with_default<std::string>("translations/" + config_key + ":placeholder", ""));
}
void ElementOptionTypeTextField::ProcessEvent(Rml::Event& event)
{
if (event == Rml::EventId::Change)
{
if (event.GetPhase() == Rml::EventPhase::Bubble || event.GetPhase() == Rml::EventPhase::Target)
{
Rml::Element *target = event.GetTargetElement();
auto val_variant = target->GetAttribute("value");
recomp::config::set_config_store_value(config_key, val_variant->Get<std::string>());
}
}
}
} // namespace Rml

View File

@ -1,22 +0,0 @@
#ifndef RECOMPUI_ELEMENT_OPTION_TYPE_TEXTFIELD_H
#define RECOMPUI_ELEMENT_OPTION_TYPE_TEXTFIELD_H
#include "common.h"
#include "ElementOptionType.h"
namespace recompui {
class ElementOptionTypeTextField : public ElementOptionType {
public:
ElementOptionTypeTextField(const Rml::String& tag);
virtual ~ElementOptionTypeTextField();
void init_option(std::string& _config_key);
protected:
void ProcessEvent(Rml::Event& event) override;
private:
Rml::ElementFormControlInput* get_input();
};
} // namespace recompui
#endif

View File

@ -1,10 +0,0 @@
#ifndef RECOMPUI_ELEMENTS_COMMON
#define RECOMPUI_ELEMENTS_COMMON
// Common includes for custom recomp elements
#include "recomp_ui.h"
#include "librecomp/config.hpp"
#include "json/json.hpp"
#include "RmlUi/Core.h"
#endif

View File

@ -1,40 +0,0 @@
#include "presets.h"
#define BUTTON_BEM "button"
#define ICON_BUTTON_BEM "icon-button"
namespace recompui {
Rml::Element *add_button(Rml::ElementDocument *doc, Rml::Element *parent_el, const Rml::String contents, ButtonVariant variant, bool isLarge) {
Rml::Element *button = parent_el->AppendChild(doc->CreateElement("button"));
button->SetClass(BLOCK(BUTTON_BEM), true);
button->SetClass(MOD_DYN(BUTTON_BEM, button_variants.at(variant)), true);
if (isLarge) {
button->SetClass(MOD(BUTTON_BEM, "large"), true);
}
if (contents != "") {
button->SetInnerRML(contents);
}
return button;
}
Rml::Element *add_icon_button(Rml::ElementDocument *doc, Rml::Element *parent_el, const std::string &svg_src, ButtonVariant variant) {
Rml::Element *button = parent_el->AppendChild(doc->CreateElement("button"));
button->SetClass(BLOCK(ICON_BUTTON_BEM), true);
button->SetClass(MOD_DYN(ICON_BUTTON_BEM, button_variants.at(variant)), true);
{
Rml::Element *icon = button->AppendChild(doc->CreateElement("svg"));
icon->SetClass(EL(ICON_BUTTON_BEM, "icon"), true);
icon->SetAttribute("src", svg_src);
}
return button;
}
} // namespace recompui

View File

@ -1,17 +0,0 @@
#ifndef RECOMPUI_ELEMENTS_PRESETS
#define RECOMPUI_ELEMENTS_PRESETS
#include "common.h"
namespace recompui {
Rml::Element *add_button(Rml::ElementDocument *doc, Rml::Element *parent_el, const Rml::String contents = "", ButtonVariant variant = ButtonVariant::Primary, bool isLarge = false);
Rml::Element *add_icon_button(Rml::ElementDocument *doc, Rml::Element *parent_el, const std::string &svg_src, ButtonVariant variant = ButtonVariant::Tertiary);
inline Rml::Element *add_div_with_class(Rml::ElementDocument *doc, Rml::Element *parent_el, const std::string& cls) {
Rml::Element *el = parent_el->AppendChild(doc->CreateElement("div"));
el->SetClass(cls, true);
return el;
}
} // namespace recompui
#endif

View File

@ -9,16 +9,6 @@ struct RecompElementConfig {
#define CUSTOM_ELEMENT(s, e) { s, std::make_unique< Rml::ElementInstancerGeneric< e > >() }
static RecompElementConfig custom_elements[] = {
CUSTOM_ELEMENT("recomp-description", recompui::ElementDescription),
CUSTOM_ELEMENT("recomp-config-group", recompui::ElementConfigGroup),
CUSTOM_ELEMENT("recomp-config-option", recompui::ElementConfigOption),
CUSTOM_ELEMENT("recomp-option-type-button", recompui::ElementOptionTypeButton),
CUSTOM_ELEMENT("recomp-option-type-checkbox", recompui::ElementOptionTypeCheckbox),
CUSTOM_ELEMENT("recomp-option-type-color", recompui::ElementOptionTypeColor),
CUSTOM_ELEMENT("recomp-option-type-dropdown", recompui::ElementOptionTypeDropdown),
CUSTOM_ELEMENT("recomp-option-type-textfield", recompui::ElementOptionTypeTextField),
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),
};

View File

@ -4,16 +4,6 @@
#include "recomp_ui.h"
#include "RmlUi/Core/Element.h"
#include "elements/ElementConfigOption.h"
#include "elements/ElementConfigGroup.h"
#include "elements/ElementOptionTypeButton.h"
#include "elements/ElementOptionTypeCheckbox.h"
#include "elements/ElementOptionTypeColor.h"
#include "elements/ElementOptionTypeDropdown.h"
#include "elements/ElementOptionTypeRadioTabs.h"
#include "elements/ElementOptionTypeRange.h"
#include "elements/ElementOptionTypeTextField.h"
#include "elements/ElementDescription.h"
#include "ui_mod_menu.h"
#include "ui_config_sub_menu.h"

View File

@ -1,6 +1,5 @@
#include "ui_mod_menu.h"
#include "elements/presets.h"
#include "librecomp/mods.hpp"
#include <string>

View File

@ -1175,22 +1175,6 @@ void init_hook(RT64::RenderInterface* interface, RT64::RenderDevice* device) {
recompui::register_custom_elements();
// TODO: Remove hardcoded config register
// std::filesystem::path recomp_dir = zelda64::get_app_folder_path();
// std::filesystem::path test_conf_path = zelda64::get_app_folder_path() / "config_example.json";
std::filesystem::path test_conf_path = "config_example.cheats.json";
std::filesystem::path test_conf_trans_path = "config_example.cheats.en_us.json";
if (std::filesystem::exists(test_conf_path)) {
const std::string s = read_file_to_string(test_conf_path);
recomp::config::register_config(read_file_to_string(test_conf_path), "cheats");
if (std::filesystem::exists(test_conf_trans_path)) {
recomp::config::register_translation(read_file_to_string("config_example.cheats.en_us.json"), "cheats");
}
} else {
printf("FAIL ALL\n");
}
Rml::Initialise();
// Apply the hack to replace RmlUi's default color parser with one that conforms to HTML5 alpha parsing for SASS compatibility