mirror of
https://github.com/Mr-Wiseguy/Zelda64Recomp.git
synced 2025-03-12 06:48:49 +01:00
Cleanup.
This commit is contained in:
parent
b9eeb57d99
commit
6ca41f37c9
@ -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
|
||||
|
@ -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
|
||||
|
@ -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>
|
@ -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;
|
||||
|
@ -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()}
|
||||
));
|
||||
}
|
||||
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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),
|
||||
};
|
||||
|
@ -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"
|
||||
|
||||
|
@ -1,6 +1,5 @@
|
||||
#include "ui_mod_menu.h"
|
||||
|
||||
#include "elements/presets.h"
|
||||
#include "librecomp/mods.hpp"
|
||||
|
||||
#include <string>
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user