mirror of
https://github.com/Mr-Wiseguy/Zelda64Recomp.git
synced 2025-02-10 17:08:49 +01:00
Convert to spaces, hook up mod enabled to toggle.
This commit is contained in:
parent
eeb935a5fe
commit
2ab4d7dfac
@ -53,8 +53,8 @@ namespace recompui {
|
|||||||
hover_disabled_style.set_border_color({ 196, 196, 196, border_hover_opacity });
|
hover_disabled_style.set_border_color({ 196, 196, 196, border_hover_opacity });
|
||||||
hover_disabled_style.set_background_color({ 196, 196, 196, background_hover_opacity });
|
hover_disabled_style.set_background_color({ 196, 196, 196, background_hover_opacity });
|
||||||
|
|
||||||
add_style(&hover_style, { hover_state });
|
add_style(&hover_style, hover_state);
|
||||||
add_style(&disabled_style, { disabled_state });
|
add_style(&disabled_style, disabled_state);
|
||||||
add_style(&hover_disabled_style, { hover_state, disabled_state });
|
add_style(&hover_disabled_style, { hover_state, disabled_state });
|
||||||
|
|
||||||
// transition: color 0.05s linear-in-out, background-color 0.05s linear-in-out;
|
// transition: color 0.05s linear-in-out, background-color 0.05s linear-in-out;
|
||||||
|
@ -157,6 +157,10 @@ void Element::clear_children() {
|
|||||||
children.clear();
|
children.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Element::add_style(Style *style, const std::string_view style_name) {
|
||||||
|
add_style(style, { style_name });
|
||||||
|
}
|
||||||
|
|
||||||
void Element::add_style(Style *style, const std::initializer_list<std::string_view> &style_names) {
|
void Element::add_style(Style *style, const std::initializer_list<std::string_view> &style_names) {
|
||||||
for (const std::string_view &style_name : style_names) {
|
for (const std::string_view &style_name : style_names) {
|
||||||
style_name_index_map.emplace(style_name, styles.size());
|
style_name_index_map.emplace(style_name, styles.size());
|
||||||
|
@ -44,6 +44,7 @@ public:
|
|||||||
Element(Element *parent, uint32_t events_enabled = 0, Rml::String base_class = "div");
|
Element(Element *parent, uint32_t events_enabled = 0, Rml::String base_class = "div");
|
||||||
virtual ~Element();
|
virtual ~Element();
|
||||||
void clear_children();
|
void clear_children();
|
||||||
|
void add_style(Style *style, const std::string_view style_name);
|
||||||
void add_style(Style *style, const std::initializer_list<std::string_view> &style_names);
|
void add_style(Style *style, const std::initializer_list<std::string_view> &style_names);
|
||||||
void set_enabled(bool enabled);
|
void set_enabled(bool enabled);
|
||||||
void set_text(const std::string &text);
|
void set_text(const std::string &text);
|
||||||
|
@ -7,166 +7,166 @@
|
|||||||
using ColourMap = Rml::UnorderedMap<Rml::String, Rml::Colourb>;
|
using ColourMap = Rml::UnorderedMap<Rml::String, Rml::Colourb>;
|
||||||
|
|
||||||
namespace recompui {
|
namespace recompui {
|
||||||
class PropertyParserColorHack : public Rml::PropertyParser {
|
class PropertyParserColorHack : public Rml::PropertyParser {
|
||||||
public:
|
public:
|
||||||
PropertyParserColorHack();
|
PropertyParserColorHack();
|
||||||
virtual ~PropertyParserColorHack();
|
virtual ~PropertyParserColorHack();
|
||||||
bool ParseValue(Rml::Property& property, const Rml::String& value, const Rml::ParameterMap& /*parameters*/) const override;
|
bool ParseValue(Rml::Property& property, const Rml::String& value, const Rml::ParameterMap& /*parameters*/) const override;
|
||||||
private:
|
private:
|
||||||
static ColourMap html_colours;
|
static ColourMap html_colours;
|
||||||
};
|
};
|
||||||
static_assert(sizeof(PropertyParserColorHack) == sizeof(Rml::PropertyParserColour));
|
static_assert(sizeof(PropertyParserColorHack) == sizeof(Rml::PropertyParserColour));
|
||||||
PropertyParserColorHack::PropertyParserColorHack() {
|
PropertyParserColorHack::PropertyParserColorHack() {
|
||||||
html_colours["black"] = Rml::Colourb(0, 0, 0);
|
html_colours["black"] = Rml::Colourb(0, 0, 0);
|
||||||
html_colours["silver"] = Rml::Colourb(192, 192, 192);
|
html_colours["silver"] = Rml::Colourb(192, 192, 192);
|
||||||
html_colours["gray"] = Rml::Colourb(128, 128, 128);
|
html_colours["gray"] = Rml::Colourb(128, 128, 128);
|
||||||
html_colours["grey"] = Rml::Colourb(128, 128, 128);
|
html_colours["grey"] = Rml::Colourb(128, 128, 128);
|
||||||
html_colours["white"] = Rml::Colourb(255, 255, 255);
|
html_colours["white"] = Rml::Colourb(255, 255, 255);
|
||||||
html_colours["maroon"] = Rml::Colourb(128, 0, 0);
|
html_colours["maroon"] = Rml::Colourb(128, 0, 0);
|
||||||
html_colours["red"] = Rml::Colourb(255, 0, 0);
|
html_colours["red"] = Rml::Colourb(255, 0, 0);
|
||||||
html_colours["orange"] = Rml::Colourb(255, 165, 0);
|
html_colours["orange"] = Rml::Colourb(255, 165, 0);
|
||||||
html_colours["purple"] = Rml::Colourb(128, 0, 128);
|
html_colours["purple"] = Rml::Colourb(128, 0, 128);
|
||||||
html_colours["fuchsia"] = Rml::Colourb(255, 0, 255);
|
html_colours["fuchsia"] = Rml::Colourb(255, 0, 255);
|
||||||
html_colours["green"] = Rml::Colourb(0, 128, 0);
|
html_colours["green"] = Rml::Colourb(0, 128, 0);
|
||||||
html_colours["lime"] = Rml::Colourb(0, 255, 0);
|
html_colours["lime"] = Rml::Colourb(0, 255, 0);
|
||||||
html_colours["olive"] = Rml::Colourb(128, 128, 0);
|
html_colours["olive"] = Rml::Colourb(128, 128, 0);
|
||||||
html_colours["yellow"] = Rml::Colourb(255, 255, 0);
|
html_colours["yellow"] = Rml::Colourb(255, 255, 0);
|
||||||
html_colours["navy"] = Rml::Colourb(0, 0, 128);
|
html_colours["navy"] = Rml::Colourb(0, 0, 128);
|
||||||
html_colours["blue"] = Rml::Colourb(0, 0, 255);
|
html_colours["blue"] = Rml::Colourb(0, 0, 255);
|
||||||
html_colours["teal"] = Rml::Colourb(0, 128, 128);
|
html_colours["teal"] = Rml::Colourb(0, 128, 128);
|
||||||
html_colours["aqua"] = Rml::Colourb(0, 255, 255);
|
html_colours["aqua"] = Rml::Colourb(0, 255, 255);
|
||||||
html_colours["transparent"] = Rml::Colourb(0, 0, 0, 0);
|
html_colours["transparent"] = Rml::Colourb(0, 0, 0, 0);
|
||||||
html_colours["whitesmoke"] = Rml::Colourb(245, 245, 245);
|
html_colours["whitesmoke"] = Rml::Colourb(245, 245, 245);
|
||||||
}
|
}
|
||||||
|
|
||||||
PropertyParserColorHack::~PropertyParserColorHack() {}
|
PropertyParserColorHack::~PropertyParserColorHack() {}
|
||||||
|
|
||||||
bool PropertyParserColorHack::ParseValue(Rml::Property& property, const Rml::String& value, const Rml::ParameterMap& /*parameters*/) const {
|
bool PropertyParserColorHack::ParseValue(Rml::Property& property, const Rml::String& value, const Rml::ParameterMap& /*parameters*/) const {
|
||||||
if (value.empty())
|
if (value.empty())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
Rml::Colourb colour;
|
Rml::Colourb colour;
|
||||||
|
|
||||||
// Check for a hex colour.
|
// Check for a hex colour.
|
||||||
if (value[0] == '#')
|
if (value[0] == '#')
|
||||||
{
|
{
|
||||||
char hex_values[4][2] = { {'f', 'f'}, {'f', 'f'}, {'f', 'f'}, {'f', 'f'} };
|
char hex_values[4][2] = { {'f', 'f'}, {'f', 'f'}, {'f', 'f'}, {'f', 'f'} };
|
||||||
|
|
||||||
switch (value.size())
|
switch (value.size())
|
||||||
{
|
{
|
||||||
// Single hex digit per channel, RGB and alpha.
|
// Single hex digit per channel, RGB and alpha.
|
||||||
case 5:
|
case 5:
|
||||||
hex_values[3][0] = hex_values[3][1] = value[4];
|
hex_values[3][0] = hex_values[3][1] = value[4];
|
||||||
//-fallthrough
|
//-fallthrough
|
||||||
// Single hex digit per channel, RGB only.
|
// Single hex digit per channel, RGB only.
|
||||||
case 4:
|
case 4:
|
||||||
hex_values[0][0] = hex_values[0][1] = value[1];
|
hex_values[0][0] = hex_values[0][1] = value[1];
|
||||||
hex_values[1][0] = hex_values[1][1] = value[2];
|
hex_values[1][0] = hex_values[1][1] = value[2];
|
||||||
hex_values[2][0] = hex_values[2][1] = value[3];
|
hex_values[2][0] = hex_values[2][1] = value[3];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Two hex digits per channel, RGB and alpha.
|
// Two hex digits per channel, RGB and alpha.
|
||||||
case 9:
|
case 9:
|
||||||
hex_values[3][0] = value[7];
|
hex_values[3][0] = value[7];
|
||||||
hex_values[3][1] = value[8];
|
hex_values[3][1] = value[8];
|
||||||
//-fallthrough
|
//-fallthrough
|
||||||
// Two hex digits per channel, RGB only.
|
// Two hex digits per channel, RGB only.
|
||||||
case 7: memcpy(hex_values, &value.c_str()[1], sizeof(char) * 6); break;
|
case 7: memcpy(hex_values, &value.c_str()[1], sizeof(char) * 6); break;
|
||||||
|
|
||||||
default: return false;
|
default: return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse each of the colour elements.
|
// Parse each of the colour elements.
|
||||||
for (size_t i = 0; i < 4; i++)
|
for (size_t i = 0; i < 4; i++)
|
||||||
{
|
{
|
||||||
int tens = Rml::Math::HexToDecimal(hex_values[i][0]);
|
int tens = Rml::Math::HexToDecimal(hex_values[i][0]);
|
||||||
int ones = Rml::Math::HexToDecimal(hex_values[i][1]);
|
int ones = Rml::Math::HexToDecimal(hex_values[i][1]);
|
||||||
if (tens == -1 || ones == -1)
|
if (tens == -1 || ones == -1)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
colour[i] = (Rml::byte)(tens * 16 + ones);
|
colour[i] = (Rml::byte)(tens * 16 + ones);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (value.substr(0, 3) == "rgb")
|
else if (value.substr(0, 3) == "rgb")
|
||||||
{
|
{
|
||||||
Rml::StringList values;
|
Rml::StringList values;
|
||||||
values.reserve(4);
|
values.reserve(4);
|
||||||
|
|
||||||
size_t find = value.find('(');
|
size_t find = value.find('(');
|
||||||
if (find == Rml::String::npos)
|
if (find == Rml::String::npos)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
size_t begin_values = find + 1;
|
size_t begin_values = find + 1;
|
||||||
|
|
||||||
Rml::StringUtilities::ExpandString(values, value.substr(begin_values, value.rfind(')') - begin_values), ',');
|
Rml::StringUtilities::ExpandString(values, value.substr(begin_values, value.rfind(')') - begin_values), ',');
|
||||||
|
|
||||||
// Check if we're parsing an 'rgba' or 'rgb' colour declaration.
|
// Check if we're parsing an 'rgba' or 'rgb' colour declaration.
|
||||||
if (value.size() > 3 && value[3] == 'a')
|
if (value.size() > 3 && value[3] == 'a')
|
||||||
{
|
{
|
||||||
if (values.size() != 4)
|
if (values.size() != 4)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (values.size() != 3)
|
if (values.size() != 3)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
values.push_back("255");
|
values.push_back("255");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse the three RGB values.
|
// Parse the three RGB values.
|
||||||
for (size_t i = 0; i < 3; ++i)
|
for (size_t i = 0; i < 3; ++i)
|
||||||
{
|
{
|
||||||
int component;
|
int component;
|
||||||
|
|
||||||
// We're parsing a percentage value.
|
// We're parsing a percentage value.
|
||||||
if (values[i].size() > 0 && values[i][values[i].size() - 1] == '%')
|
if (values[i].size() > 0 && values[i][values[i].size() - 1] == '%')
|
||||||
component = int((float)atof(values[i].substr(0, values[i].size() - 1).c_str()) * (255.0f / 100.0f));
|
component = int((float)atof(values[i].substr(0, values[i].size() - 1).c_str()) * (255.0f / 100.0f));
|
||||||
// We're parsing a 0 -> 255 integer value.
|
// We're parsing a 0 -> 255 integer value.
|
||||||
else
|
else
|
||||||
component = atoi(values[i].c_str());
|
component = atoi(values[i].c_str());
|
||||||
|
|
||||||
colour[i] = (Rml::byte)(Rml::Math::Clamp(component, 0, 255));
|
colour[i] = (Rml::byte)(Rml::Math::Clamp(component, 0, 255));
|
||||||
}
|
}
|
||||||
// Parse the alpha value. Modified from the original RmlUi implementation to use 0-1 instead of 0-255.
|
// Parse the alpha value. Modified from the original RmlUi implementation to use 0-1 instead of 0-255.
|
||||||
{
|
{
|
||||||
int component;
|
int component;
|
||||||
|
|
||||||
// We're parsing a percentage value.
|
// We're parsing a percentage value.
|
||||||
if (values[3].size() > 0 && values[3][values[3].size() - 1] == '%')
|
if (values[3].size() > 0 && values[3][values[3].size() - 1] == '%')
|
||||||
component = ((float)atof(values[3].substr(0, values[3].size() - 1).c_str()) * (255.0f / 100.0f));
|
component = ((float)atof(values[3].substr(0, values[3].size() - 1).c_str()) * (255.0f / 100.0f));
|
||||||
// We're parsing a 0 -> 1 float value.
|
// We're parsing a 0 -> 1 float value.
|
||||||
else
|
else
|
||||||
component = atof(values[3].c_str()) * 255.0f;
|
component = atof(values[3].c_str()) * 255.0f;
|
||||||
|
|
||||||
colour[3] = (Rml::byte)(Rml::Math::Clamp(component, 0, 255));
|
colour[3] = (Rml::byte)(Rml::Math::Clamp(component, 0, 255));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Check for the specification of an HTML colour.
|
// Check for the specification of an HTML colour.
|
||||||
ColourMap::const_iterator iterator = html_colours.find(Rml::StringUtilities::ToLower(value));
|
ColourMap::const_iterator iterator = html_colours.find(Rml::StringUtilities::ToLower(value));
|
||||||
if (iterator == html_colours.end())
|
if (iterator == html_colours.end())
|
||||||
return false;
|
return false;
|
||||||
else
|
else
|
||||||
colour = (*iterator).second;
|
colour = (*iterator).second;
|
||||||
}
|
}
|
||||||
|
|
||||||
property.value = Rml::Variant(colour);
|
property.value = Rml::Variant(colour);
|
||||||
property.unit = Rml::Unit::COLOUR;
|
property.unit = Rml::Unit::COLOUR;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This hack overwrites the contents of a property parser pointer for "color" (which is known to point to a valid Rml::PropertyParserColour) with the contents of a PropertyParserColorHack.
|
// This hack overwrites the contents of a property parser pointer for "color" (which is known to point to a valid Rml::PropertyParserColour) with the contents of a PropertyParserColorHack.
|
||||||
// This overwrites the object's vtable, allowing us to override color parsing behavior to use 0-1 alpha instead of 0-255.
|
// This overwrites the object's vtable, allowing us to override color parsing behavior to use 0-1 alpha instead of 0-255.
|
||||||
// Ideally we'd just replace the pointer itself, but RmlUi doesn't provide a way to do that currently.
|
// Ideally we'd just replace the pointer itself, but RmlUi doesn't provide a way to do that currently.
|
||||||
void apply_color_hack() {
|
void apply_color_hack() {
|
||||||
// Allocate and leak a parser to act as a vtable source.
|
// Allocate and leak a parser to act as a vtable source.
|
||||||
PropertyParserColorHack* new_parser = new PropertyParserColorHack();
|
PropertyParserColorHack* new_parser = new PropertyParserColorHack();
|
||||||
// Copy the allocated object into the color parser pointer to overwrite its vtable.
|
// Copy the allocated object into the color parser pointer to overwrite its vtable.
|
||||||
memcpy((void*)Rml::StyleSheetSpecification::GetParser("color"), (void*)new_parser, sizeof(*new_parser));
|
memcpy((void*)Rml::StyleSheetSpecification::GetParser("color"), (void*)new_parser, sizeof(*new_parser));
|
||||||
}
|
}
|
||||||
|
|
||||||
ColourMap PropertyParserColorHack::html_colours{};
|
ColourMap PropertyParserColorHack::html_colours{};
|
||||||
}
|
}
|
||||||
|
1474
src/ui/ui_config.cpp
1474
src/ui/ui_config.cpp
File diff suppressed because it is too large
Load Diff
@ -14,16 +14,16 @@ bool mm_rom_valid = false;
|
|||||||
extern std::vector<recomp::GameEntry> supported_games;
|
extern std::vector<recomp::GameEntry> supported_games;
|
||||||
|
|
||||||
void select_rom() {
|
void select_rom() {
|
||||||
nfdnchar_t* native_path = nullptr;
|
nfdnchar_t* native_path = nullptr;
|
||||||
nfdresult_t result = NFD_OpenDialogN(&native_path, nullptr, 0, nullptr);
|
nfdresult_t result = NFD_OpenDialogN(&native_path, nullptr, 0, nullptr);
|
||||||
|
|
||||||
if (result == NFD_OKAY) {
|
if (result == NFD_OKAY) {
|
||||||
std::filesystem::path path{native_path};
|
std::filesystem::path path{native_path};
|
||||||
|
|
||||||
NFD_FreePathN(native_path);
|
NFD_FreePathN(native_path);
|
||||||
native_path = nullptr;
|
native_path = nullptr;
|
||||||
|
|
||||||
recomp::RomValidationError rom_error = recomp::select_rom(path, supported_games[0].game_id);
|
recomp::RomValidationError rom_error = recomp::select_rom(path, supported_games[0].game_id);
|
||||||
switch (rom_error) {
|
switch (rom_error) {
|
||||||
case recomp::RomValidationError::Good:
|
case recomp::RomValidationError::Good:
|
||||||
mm_rom_valid = true;
|
mm_rom_valid = true;
|
||||||
@ -55,44 +55,44 @@ void select_rom() {
|
|||||||
class LauncherMenu : public recompui::MenuController {
|
class LauncherMenu : public recompui::MenuController {
|
||||||
public:
|
public:
|
||||||
LauncherMenu() {
|
LauncherMenu() {
|
||||||
mm_rom_valid = recomp::is_rom_valid(supported_games[0].game_id);
|
mm_rom_valid = recomp::is_rom_valid(supported_games[0].game_id);
|
||||||
}
|
}
|
||||||
~LauncherMenu() override {
|
~LauncherMenu() override {
|
||||||
|
|
||||||
}
|
}
|
||||||
Rml::ElementDocument* load_document(Rml::Context* context) override {
|
Rml::ElementDocument* load_document(Rml::Context* context) override {
|
||||||
return context->LoadDocument("assets/launcher.rml");
|
return context->LoadDocument("assets/launcher.rml");
|
||||||
}
|
}
|
||||||
void register_events(recompui::UiEventListenerInstancer& listener) override {
|
void register_events(recompui::UiEventListenerInstancer& listener) override {
|
||||||
recompui::register_event(listener, "select_rom",
|
recompui::register_event(listener, "select_rom",
|
||||||
[](const std::string& param, Rml::Event& event) {
|
[](const std::string& param, Rml::Event& event) {
|
||||||
select_rom();
|
select_rom();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
recompui::register_event(listener, "rom_selected",
|
recompui::register_event(listener, "rom_selected",
|
||||||
[](const std::string& param, Rml::Event& event) {
|
[](const std::string& param, Rml::Event& event) {
|
||||||
mm_rom_valid = true;
|
mm_rom_valid = true;
|
||||||
model_handle.DirtyVariable("mm_rom_valid");
|
model_handle.DirtyVariable("mm_rom_valid");
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
recompui::register_event(listener, "start_game",
|
recompui::register_event(listener, "start_game",
|
||||||
[](const std::string& param, Rml::Event& event) {
|
[](const std::string& param, Rml::Event& event) {
|
||||||
recomp::start_game(supported_games[0].game_id);
|
recomp::start_game(supported_games[0].game_id);
|
||||||
recompui::set_current_menu(recompui::Menu::None);
|
recompui::set_current_menu(recompui::Menu::None);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
recompui::register_event(listener, "open_controls",
|
recompui::register_event(listener, "open_controls",
|
||||||
[](const std::string& param, Rml::Event& event) {
|
[](const std::string& param, Rml::Event& event) {
|
||||||
recompui::set_current_menu(recompui::Menu::Config);
|
recompui::set_current_menu(recompui::Menu::Config);
|
||||||
recompui::set_config_submenu(recompui::ConfigSubmenu::Controls);
|
recompui::set_config_submenu(recompui::ConfigSubmenu::Controls);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
recompui::register_event(listener, "open_settings",
|
recompui::register_event(listener, "open_settings",
|
||||||
[](const std::string& param, Rml::Event& event) {
|
[](const std::string& param, Rml::Event& event) {
|
||||||
recompui::set_current_menu(recompui::Menu::Config);
|
recompui::set_current_menu(recompui::Menu::Config);
|
||||||
recompui::set_config_submenu(recompui::ConfigSubmenu::General);
|
recompui::set_config_submenu(recompui::ConfigSubmenu::General);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
recompui::register_event(listener, "open_mods",
|
recompui::register_event(listener, "open_mods",
|
||||||
[](const std::string ¶m, Rml::Event &event) {
|
[](const std::string ¶m, Rml::Event &event) {
|
||||||
recompui::set_current_menu(recompui::Menu::Config);
|
recompui::set_current_menu(recompui::Menu::Config);
|
||||||
@ -100,21 +100,21 @@ public:
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
recompui::register_event(listener, "exit_game",
|
recompui::register_event(listener, "exit_game",
|
||||||
[](const std::string& param, Rml::Event& event) {
|
[](const std::string& param, Rml::Event& event) {
|
||||||
ultramodern::quit();
|
ultramodern::quit();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
void make_bindings(Rml::Context* context) override {
|
void make_bindings(Rml::Context* context) override {
|
||||||
Rml::DataModelConstructor constructor = context->CreateDataModel("launcher_model");
|
Rml::DataModelConstructor constructor = context->CreateDataModel("launcher_model");
|
||||||
|
|
||||||
constructor.Bind("mm_rom_valid", &mm_rom_valid);
|
constructor.Bind("mm_rom_valid", &mm_rom_valid);
|
||||||
|
|
||||||
version_string = recomp::get_project_version().to_string();
|
version_string = recomp::get_project_version().to_string();
|
||||||
constructor.Bind("version_number", &version_string);
|
constructor.Bind("version_number", &version_string);
|
||||||
|
|
||||||
model_handle = constructor.GetModelHandle();
|
model_handle = constructor.GetModelHandle();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
std::unique_ptr<recompui::MenuController> recompui::create_launcher_menu() {
|
std::unique_ptr<recompui::MenuController> recompui::create_launcher_menu() {
|
||||||
|
@ -43,6 +43,7 @@ ModDetailsPanel::ModDetailsPanel(Element *parent) : Element(parent) {
|
|||||||
buttons_container->set_padding_left(16.0f);
|
buttons_container->set_padding_left(16.0f);
|
||||||
{
|
{
|
||||||
enable_toggle = new Toggle(buttons_container);
|
enable_toggle = new Toggle(buttons_container);
|
||||||
|
enable_toggle->add_checked_callback(std::bind(&ModDetailsPanel::enable_toggle_checked, this, std::placeholders::_1));
|
||||||
configure_button = new Button("Configure", recompui::ButtonStyle::Secondary, buttons_container);
|
configure_button = new Button("Configure", recompui::ButtonStyle::Secondary, buttons_container);
|
||||||
erase_button = new Button("Erase", recompui::ButtonStyle::Secondary, buttons_container);
|
erase_button = new Button("Erase", recompui::ButtonStyle::Secondary, buttons_container);
|
||||||
}
|
}
|
||||||
@ -52,7 +53,7 @@ ModDetailsPanel::ModDetailsPanel(Element *parent) : Element(parent) {
|
|||||||
ModDetailsPanel::~ModDetailsPanel() {
|
ModDetailsPanel::~ModDetailsPanel() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModDetailsPanel::set_mod_details(const recomp::mods::ModDetails& details) {
|
void ModDetailsPanel::set_mod_details(const recomp::mods::ModDetails& details, bool enabled) {
|
||||||
cur_details = details;
|
cur_details = details;
|
||||||
|
|
||||||
title_label->set_text(cur_details.mod_id);
|
title_label->set_text(cur_details.mod_id);
|
||||||
@ -67,6 +68,17 @@ void ModDetailsPanel::set_mod_details(const recomp::mods::ModDetails& details) {
|
|||||||
|
|
||||||
authors_label->set_text(authors_str);
|
authors_label->set_text(authors_str);
|
||||||
description_label->set_text("Placeholder description. Some long text to make sure that wrapping is working correctly. Yet more text and so on.");
|
description_label->set_text("Placeholder description. Some long text to make sure that wrapping is working correctly. Yet more text and so on.");
|
||||||
|
enable_toggle->set_checked(enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModDetailsPanel::set_mod_toggled_callback(std::function<void(bool)> callback) {
|
||||||
|
mod_toggled_callback = callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModDetailsPanel::enable_toggle_checked(bool checked) {
|
||||||
|
if (mod_toggled_callback != nullptr) {
|
||||||
|
mod_toggled_callback(checked);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace recompui
|
} // namespace recompui
|
||||||
|
@ -12,24 +12,28 @@ namespace recompui {
|
|||||||
|
|
||||||
class ModDetailsPanel : public Element {
|
class ModDetailsPanel : public Element {
|
||||||
public:
|
public:
|
||||||
ModDetailsPanel(Element *parent);
|
ModDetailsPanel(Element *parent);
|
||||||
virtual ~ModDetailsPanel();
|
virtual ~ModDetailsPanel();
|
||||||
void set_mod_details(const recomp::mods::ModDetails& details);
|
void set_mod_details(const recomp::mods::ModDetails& details, bool enabled);
|
||||||
|
void set_mod_toggled_callback(std::function<void(bool)> callback);
|
||||||
private:
|
private:
|
||||||
recomp::mods::ModDetails cur_details;
|
recomp::mods::ModDetails cur_details;
|
||||||
Container *thumbnail_container = nullptr;
|
Container *thumbnail_container = nullptr;
|
||||||
Image *thumbnail_image = nullptr;
|
Image *thumbnail_image = nullptr;
|
||||||
Container *header_container = nullptr;
|
Container *header_container = nullptr;
|
||||||
Container *header_details_container = nullptr;
|
Container *header_details_container = nullptr;
|
||||||
Label *title_label = nullptr;
|
Label *title_label = nullptr;
|
||||||
Label *version_label = nullptr;
|
Label *version_label = nullptr;
|
||||||
Container *body_container = nullptr;
|
Container *body_container = nullptr;
|
||||||
Label *description_label = nullptr;
|
Label *description_label = nullptr;
|
||||||
Label *authors_label = nullptr;
|
Label *authors_label = nullptr;
|
||||||
Container *buttons_container = nullptr;
|
Container *buttons_container = nullptr;
|
||||||
Toggle *enable_toggle = nullptr;
|
Toggle *enable_toggle = nullptr;
|
||||||
Button *configure_button = nullptr;
|
Button *configure_button = nullptr;
|
||||||
Button *erase_button = nullptr;
|
Button *erase_button = nullptr;
|
||||||
|
std::function<void(bool)> mod_toggled_callback = {};
|
||||||
|
|
||||||
|
void enable_toggle_checked(bool checked);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace recompui
|
} // namespace recompui
|
||||||
|
@ -69,8 +69,12 @@ void ModEntry::process_event(const Event& e) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModMenu::set_active_mod(uint32_t mod_index) {
|
void ModMenu::set_active_mod(int32_t mod_index) {
|
||||||
mod_details_panel->set_mod_details(mod_details[mod_index]);
|
active_mod_index = mod_index;
|
||||||
|
if (active_mod_index >= 0) {
|
||||||
|
bool mod_enabled = recomp::mods::is_mod_enabled(mod_details[mod_index].mod_id);
|
||||||
|
mod_details_panel->set_mod_details(mod_details[mod_index], mod_enabled);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModMenu::refresh_mods() {
|
void ModMenu::refresh_mods() {
|
||||||
@ -79,6 +83,12 @@ void ModMenu::refresh_mods() {
|
|||||||
create_mod_list();
|
create_mod_list();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ModMenu::mod_toggled(bool enabled) {
|
||||||
|
if (active_mod_index >= 0) {
|
||||||
|
recomp::mods::enable_mod(mod_details[active_mod_index].mod_id, enabled);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ModMenu::create_mod_list() {
|
void ModMenu::create_mod_list() {
|
||||||
// Clear the contents of the list scroll.
|
// Clear the contents of the list scroll.
|
||||||
list_scroll_container->clear_children();
|
list_scroll_container->clear_children();
|
||||||
@ -121,6 +131,7 @@ ModMenu::ModMenu(Element *parent) : Element(parent) {
|
|||||||
} // list_container
|
} // list_container
|
||||||
|
|
||||||
mod_details_panel = new ModDetailsPanel(body_container);
|
mod_details_panel = new ModDetailsPanel(body_container);
|
||||||
|
mod_details_panel->set_mod_toggled_callback(std::bind(&ModMenu::mod_toggled, this, std::placeholders::_1));
|
||||||
} // body_container
|
} // body_container
|
||||||
|
|
||||||
|
|
||||||
|
@ -11,45 +11,47 @@ class ModMenu;
|
|||||||
|
|
||||||
class ModEntry : public Element {
|
class ModEntry : public Element {
|
||||||
public:
|
public:
|
||||||
ModEntry(Element *parent, const recomp::mods::ModDetails &details, uint32_t mod_index, ModMenu *mod_menu);
|
ModEntry(Element *parent, const recomp::mods::ModDetails &details, uint32_t mod_index, ModMenu *mod_menu);
|
||||||
virtual ~ModEntry();
|
virtual ~ModEntry();
|
||||||
protected:
|
protected:
|
||||||
virtual void process_event(const Event &e);
|
virtual void process_event(const Event &e);
|
||||||
private:
|
private:
|
||||||
uint32_t mod_index = 0;
|
uint32_t mod_index = 0;
|
||||||
ModMenu *mod_menu = nullptr;
|
ModMenu *mod_menu = nullptr;
|
||||||
Image *thumbnail_image = nullptr;
|
Image *thumbnail_image = nullptr;
|
||||||
Container *body_container = nullptr;
|
Container *body_container = nullptr;
|
||||||
Label *name_label = nullptr;
|
Label *name_label = nullptr;
|
||||||
Label *description_label = nullptr;
|
Label *description_label = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ModMenu : public Element {
|
class ModMenu : public Element {
|
||||||
public:
|
public:
|
||||||
ModMenu(Element *parent);
|
ModMenu(Element *parent);
|
||||||
virtual ~ModMenu();
|
virtual ~ModMenu();
|
||||||
void set_active_mod(uint32_t mod_index);
|
void set_active_mod(int32_t mod_index);
|
||||||
private:
|
private:
|
||||||
void refresh_mods();
|
void refresh_mods();
|
||||||
void create_mod_list();
|
void mod_toggled(bool enabled);
|
||||||
|
void create_mod_list();
|
||||||
Container *body_container = nullptr;
|
|
||||||
Container *list_container = nullptr;
|
Container *body_container = nullptr;
|
||||||
ScrollContainer *list_scroll_container = nullptr;
|
Container *list_container = nullptr;
|
||||||
ModDetailsPanel *mod_details_panel = nullptr;
|
ScrollContainer *list_scroll_container = nullptr;
|
||||||
Container *footer_container = nullptr;
|
ModDetailsPanel *mod_details_panel = nullptr;
|
||||||
Button *refresh_button = nullptr;
|
Container *footer_container = nullptr;
|
||||||
std::vector<ModEntry *> mod_entries;
|
Button *refresh_button = nullptr;
|
||||||
std::vector<recomp::mods::ModDetails> mod_details{};
|
int32_t active_mod_index = -1;
|
||||||
std::string game_mod_id;
|
std::vector<ModEntry *> mod_entries;
|
||||||
|
std::vector<recomp::mods::ModDetails> mod_details{};
|
||||||
|
std::string game_mod_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ElementModMenu : public Rml::Element {
|
class ElementModMenu : public Rml::Element {
|
||||||
public:
|
public:
|
||||||
ElementModMenu(const Rml::String& tag);
|
ElementModMenu(const Rml::String& tag);
|
||||||
virtual ~ElementModMenu();
|
virtual ~ElementModMenu();
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<ModMenu> mod_menu;
|
std::unique_ptr<ModMenu> mod_menu;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace recompui
|
} // namespace recompui
|
||||||
|
Loading…
x
Reference in New Issue
Block a user