mirror of
https://github.com/Mr-Wiseguy/Zelda64Recomp.git
synced 2025-03-12 06:48:49 +01:00
Refactored mods menu entirely.
This commit is contained in:
parent
425dfeec24
commit
4e582443fb
@ -159,6 +159,8 @@ set (SOURCES
|
||||
${CMAKE_SOURCE_DIR}/src/ui/ui_color_hack.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/ui/ui_rml_hacks.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/ui/ui_elements.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/ui/ui_mod_details_panel.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/ui/ui_mod_menu.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/ui/util/hsv.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/ui/elements/ElementConfigGroup.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/ui/elements/ElementConfigOption.cpp
|
||||
@ -171,14 +173,13 @@ set (SOURCES
|
||||
${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/ElementModMenu.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_container.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/ui/elements/ui_element.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/ui/elements/ui_image.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/ui/elements/ui_label.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/ui/elements/ui_mod_details_panel.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/ui/elements/ui_scroll_container.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/ui/elements/ui_toggle.cpp
|
||||
|
||||
${CMAKE_SOURCE_DIR}/rsp/aspMain.cpp
|
||||
|
@ -1,144 +0,0 @@
|
||||
#include "ElementModMenu.h"
|
||||
#include "presets.h"
|
||||
#include "librecomp/mods.hpp"
|
||||
|
||||
#include <string>
|
||||
|
||||
#define MOD_MENU_BEM "mod-menu"
|
||||
|
||||
namespace recompui {
|
||||
|
||||
static const std::string cls_base = BLOCK(MOD_MENU_BEM);
|
||||
static const std::string cls_list = EL(MOD_MENU_BEM, "list");
|
||||
static const std::string cls_list_scroll = EL(MOD_MENU_BEM, "list-scroll");
|
||||
static const std::string cls_list_entry = EL(MOD_MENU_BEM, "list-entry");
|
||||
static const std::string cls_list_entry_thumbnail = EL(MOD_MENU_BEM, "list-entry-thumbnail");
|
||||
static const std::string cls_list_entry_body = EL(MOD_MENU_BEM, "list-entry-body");
|
||||
static const std::string cls_list_entry_name = EL(MOD_MENU_BEM, "list-entry-name");
|
||||
static const std::string cls_list_entry_description = EL(MOD_MENU_BEM, "list-entry-description");
|
||||
|
||||
void ElementModMenu::ProcessEvent(Rml::Event& event) {
|
||||
Rml::Element* event_element = event.GetCurrentElement();
|
||||
Rml::EventId event_id = event.GetId();
|
||||
switch (event_id) {
|
||||
// Click event handlers.
|
||||
case Rml::EventId::Click:
|
||||
// Refresh
|
||||
if (event_element == refresh_button) {
|
||||
RefreshMods();
|
||||
}
|
||||
break;
|
||||
case Rml::EventId::Focus:
|
||||
{
|
||||
size_t mod_index;
|
||||
Rml::Variant *val = event_element->GetAttribute("mod_index");
|
||||
if (val->GetInto(mod_index) && mod_index < mod_details.size()) {
|
||||
mod_details_panel->set_mod_details(mod_details[mod_index]);
|
||||
}
|
||||
if (active_list_entry_el != nullptr) {
|
||||
active_list_entry_el->RemoveAttribute("is_selected");
|
||||
}
|
||||
event_element->SetAttribute("is_selected", true);
|
||||
active_list_entry_el = event_element;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Rml::ElementPtr ElementModMenu::CreateModListEntry(const recomp::mods::ModDetails& details, size_t index) {
|
||||
Rml::ElementDocument *doc = GetOwnerDocument();
|
||||
|
||||
Rml::ElementPtr mod_el = doc->CreateElement("div");
|
||||
mod_el->SetClass(cls_list_entry, true);
|
||||
mod_el->SetAttribute("mod_index", index);
|
||||
{
|
||||
Rml::Element* thumbnail_el = add_div_with_class(doc, mod_el.get(), cls_list_entry_thumbnail);
|
||||
Rml::Element *body_el = add_div_with_class(doc, mod_el.get(), cls_list_entry_body);
|
||||
{
|
||||
Rml::Element *name_el = add_div_with_class(doc, body_el, cls_list_entry_name);
|
||||
name_el->SetInnerRML(details.mod_id);
|
||||
|
||||
Rml::Element *description_el = add_div_with_class(doc, body_el, cls_list_entry_description);
|
||||
description_el->SetInnerRML("Short description of mod here.");
|
||||
} // body_el
|
||||
} // mod_el
|
||||
|
||||
return mod_el;
|
||||
}
|
||||
|
||||
void ElementModMenu::CreateModList() {
|
||||
Rml::ElementDocument *doc = GetOwnerDocument();
|
||||
|
||||
// Clear the contents of the list scroll.
|
||||
list_el_scroll->SetInnerRML("");
|
||||
Rml::Element* prev_el = refresh_button;
|
||||
active_list_entry_el = nullptr;
|
||||
|
||||
bool first = true;
|
||||
|
||||
// Create the child elements for the list scroll.
|
||||
for (size_t mod_index = 0; mod_index < mod_details.size(); mod_index++) {
|
||||
const recomp::mods::ModDetails& details = mod_details[mod_index];
|
||||
Rml::Element *mod_el = list_el_scroll->AppendChild(CreateModListEntry(details, mod_index));
|
||||
mod_el->SetAttribute("mod_index", mod_index);
|
||||
mod_el->AddEventListener(Rml::EventId::Focus, this, false);
|
||||
mod_el->SetId("mod-list-entry-" + std::to_string(mod_index));
|
||||
|
||||
mod_el->SetProperty("nav-up", "#" + prev_el->GetId());
|
||||
prev_el->SetProperty("nav-down", "#" + mod_el->GetId());
|
||||
|
||||
if (first) {
|
||||
active_list_entry_el = mod_el;
|
||||
}
|
||||
first = false;
|
||||
|
||||
prev_el = mod_el;
|
||||
}
|
||||
|
||||
active_list_entry_el->SetAttribute("is_selected", true);
|
||||
|
||||
DirtyLayout();
|
||||
}
|
||||
|
||||
void ElementModMenu::RefreshMods() {
|
||||
recomp::mods::scan_mods();
|
||||
mod_details = recomp::mods::get_mod_details(game_mod_id);
|
||||
|
||||
mod_details_panel->set_mod_details(mod_details[0]);
|
||||
|
||||
CreateModList();
|
||||
}
|
||||
|
||||
ElementModMenu::ElementModMenu(const Rml::String& tag) : Rml::Element(tag) {
|
||||
game_mod_id = "mm";
|
||||
SetAttribute("recomp-store-element", true);
|
||||
Rml::ElementDocument *doc = GetOwnerDocument();
|
||||
SetClass(cls_base, true);
|
||||
|
||||
Rml::Element *body_el = add_div_with_class(doc, this, "config__hz-wrapper");
|
||||
{
|
||||
list_el = add_div_with_class(doc, body_el, cls_list);
|
||||
{
|
||||
list_el_scroll = add_div_with_class(doc, list_el, cls_list_scroll);
|
||||
} // list_el
|
||||
|
||||
recompui::Element body_el_compat(body_el);
|
||||
mod_details_panel = std::make_unique<ModDetailsPanel>(&body_el_compat);
|
||||
} // body_el
|
||||
|
||||
Rml::Element *footer_el = add_div_with_class(doc, this, "config__footer");
|
||||
{
|
||||
refresh_button = add_button(doc, footer_el, "Refresh", ButtonVariant::Primary);
|
||||
refresh_button->AddEventListener(Rml::EventId::Click, this, false);
|
||||
refresh_button->SetId("refresh-button");
|
||||
} // footer_el
|
||||
|
||||
RefreshMods();
|
||||
}
|
||||
|
||||
ElementModMenu::~ElementModMenu() {
|
||||
}
|
||||
|
||||
|
||||
} // namespace Rml
|
@ -1,29 +0,0 @@
|
||||
#ifndef RECOMPUI_ELEMENT_MOD_MENU_H
|
||||
#define RECOMPUI_ELEMENT_MOD_MENU_H
|
||||
|
||||
#include "common.h"
|
||||
#include "librecomp/mods.hpp"
|
||||
#include "ui_mod_details_panel.h"
|
||||
|
||||
namespace recompui {
|
||||
|
||||
class ElementModMenu : public Rml::Element, public Rml::EventListener {
|
||||
public:
|
||||
ElementModMenu(const Rml::String& tag);
|
||||
virtual ~ElementModMenu();
|
||||
void ProcessEvent(Rml::Event& event) final;
|
||||
private:
|
||||
void RefreshMods();
|
||||
void CreateModList();
|
||||
Rml::ElementPtr CreateModListEntry(const recomp::mods::ModDetails& details, size_t index);
|
||||
Rml::Element *refresh_button;
|
||||
Rml::Element *list_el; // The root mod list element.
|
||||
Rml::Element *list_el_scroll; // The scroll within the root mod list element.
|
||||
std::unique_ptr<ModDetailsPanel> mod_details_panel;
|
||||
Rml::Element *active_list_entry_el = nullptr;
|
||||
std::vector<recomp::mods::ModDetails> mod_details{};
|
||||
std::string game_mod_id;
|
||||
};
|
||||
|
||||
} // namespace recompui
|
||||
#endif
|
@ -17,6 +17,24 @@ static Rml::Unit to_rml(Unit unit) {
|
||||
}
|
||||
}
|
||||
|
||||
static Rml::Style::AlignItems to_rml(AlignItems align_items) {
|
||||
switch (align_items) {
|
||||
case AlignItems::FlexStart:
|
||||
return Rml::Style::AlignItems::FlexStart;
|
||||
case AlignItems::FlexEnd:
|
||||
return Rml::Style::AlignItems::FlexEnd;
|
||||
case AlignItems::Center:
|
||||
return Rml::Style::AlignItems::Center;
|
||||
case AlignItems::Baseline:
|
||||
return Rml::Style::AlignItems::Baseline;
|
||||
case AlignItems::Stretch:
|
||||
return Rml::Style::AlignItems::Stretch;
|
||||
default:
|
||||
assert(false && "Unknown align items.");
|
||||
return Rml::Style::AlignItems::FlexStart;
|
||||
}
|
||||
}
|
||||
|
||||
static Rml::Style::Overflow to_rml(Overflow overflow) {
|
||||
switch (overflow) {
|
||||
case Overflow::Visible:
|
||||
@ -33,18 +51,32 @@ static Rml::Style::Overflow to_rml(Overflow overflow) {
|
||||
}
|
||||
}
|
||||
|
||||
static Rml::Style::TextAlign to_rml(TextAlign text_align) {
|
||||
switch (text_align) {
|
||||
case TextAlign::Left:
|
||||
return Rml::Style::TextAlign::Left;
|
||||
case TextAlign::Right:
|
||||
return Rml::Style::TextAlign::Right;
|
||||
case TextAlign::Center:
|
||||
return Rml::Style::TextAlign::Center;
|
||||
case TextAlign::Justify:
|
||||
return Rml::Style::TextAlign::Justify;
|
||||
default:
|
||||
assert(false && "Unknown text align.");
|
||||
return Rml::Style::TextAlign::Left;
|
||||
}
|
||||
}
|
||||
|
||||
Element::Element(Rml::Element *base) {
|
||||
assert(base != nullptr);
|
||||
|
||||
this->base = base;
|
||||
this->parent = nullptr;
|
||||
this->owner = false;
|
||||
}
|
||||
|
||||
Element::Element(Element *parent, uint32_t events_enabled, Rml::String base_class) {
|
||||
assert(parent != nullptr);
|
||||
|
||||
this->parent = parent;
|
||||
this->owner = true;
|
||||
|
||||
base = parent->base->AppendChild(parent->base->GetOwnerDocument()->CreateElement(base_class));
|
||||
@ -169,6 +201,22 @@ void Element::set_height_auto() {
|
||||
set_property(Rml::PropertyId::Height, Rml::Property(Rml::Style::FlexBasis::Type::Auto, Rml::Unit::KEYWORD));
|
||||
}
|
||||
|
||||
void Element::set_min_width(float width, Unit unit, Animation animation) {
|
||||
set_property(Rml::PropertyId::MinWidth, Rml::Property(width, to_rml(unit)), animation);
|
||||
}
|
||||
|
||||
void Element::set_min_height(float height, Unit unit, Animation animation) {
|
||||
set_property(Rml::PropertyId::MinHeight, Rml::Property(height, to_rml(unit)), animation);
|
||||
}
|
||||
|
||||
void Element::set_max_width(float width, Unit unit, Animation animation) {
|
||||
set_property(Rml::PropertyId::MaxWidth, Rml::Property(width, to_rml(unit)), animation);
|
||||
}
|
||||
|
||||
void Element::set_max_height(float height, Unit unit, Animation animation) {
|
||||
set_property(Rml::PropertyId::MaxHeight, Rml::Property(height, to_rml(unit)), animation);
|
||||
}
|
||||
|
||||
void Element::set_padding(float padding, Unit unit, Animation animation) {
|
||||
set_property(Rml::PropertyId::PaddingLeft, Rml::Property(padding, to_rml(unit)), animation);
|
||||
set_property(Rml::PropertyId::PaddingTop, Rml::Property(padding, to_rml(unit)), animation);
|
||||
@ -223,6 +271,22 @@ void Element::set_border_width(float width, Unit unit, Animation animation) {
|
||||
set_property(Rml::PropertyId::BorderRightWidth, property, animation);
|
||||
}
|
||||
|
||||
void Element::set_border_left_width(float width, Unit unit, Animation animation) {
|
||||
set_property(Rml::PropertyId::BorderLeftWidth, Rml::Property(width, to_rml(unit)), animation);
|
||||
}
|
||||
|
||||
void Element::set_border_top_width(float width, Unit unit, Animation animation) {
|
||||
set_property(Rml::PropertyId::BorderTopWidth, Rml::Property(width, to_rml(unit)), animation);
|
||||
}
|
||||
|
||||
void Element::set_border_right_width(float width, Unit unit, Animation animation) {
|
||||
set_property(Rml::PropertyId::BorderRightWidth, Rml::Property(width, to_rml(unit)), animation);
|
||||
}
|
||||
|
||||
void Element::set_border_bottom_width(float width, Unit unit, Animation animation) {
|
||||
set_property(Rml::PropertyId::BorderBottomWidth, Rml::Property(width, to_rml(unit)), animation);
|
||||
}
|
||||
|
||||
void Element::set_border_radius(float radius, Unit unit, Animation animation) {
|
||||
Rml::Property property(radius, to_rml(unit));
|
||||
set_property(Rml::PropertyId::BorderTopLeftRadius, property, animation);
|
||||
@ -260,6 +324,26 @@ void Element::set_border_color(const Color &color, Animation animation) {
|
||||
set_property(Rml::PropertyId::BorderRightColor, property, animation);
|
||||
}
|
||||
|
||||
void Element::set_border_left_color(const Color &color, Animation animation) {
|
||||
Rml::Property property(Rml::Colourb(color.r, color.g, color.b, color.a), Rml::Unit::COLOUR);
|
||||
set_property(Rml::PropertyId::BorderLeftColor, property, animation);
|
||||
}
|
||||
|
||||
void Element::set_border_top_color(const Color &color, Animation animation) {
|
||||
Rml::Property property(Rml::Colourb(color.r, color.g, color.b, color.a), Rml::Unit::COLOUR);
|
||||
set_property(Rml::PropertyId::BorderTopColor, property, animation);
|
||||
}
|
||||
|
||||
void Element::set_border_right_color(const Color &color, Animation animation) {
|
||||
Rml::Property property(Rml::Colourb(color.r, color.g, color.b, color.a), Rml::Unit::COLOUR);
|
||||
set_property(Rml::PropertyId::BorderRightColor, property, animation);
|
||||
}
|
||||
|
||||
void Element::set_border_bottom_color(const Color &color, Animation animation) {
|
||||
Rml::Property property(Rml::Colourb(color.r, color.g, color.b, color.a), Rml::Unit::COLOUR);
|
||||
set_property(Rml::PropertyId::BorderBottomColor, property, animation);
|
||||
}
|
||||
|
||||
void Element::set_color(const Color &color, Animation animation) {
|
||||
Rml::Property property(Rml::Colourb(color.r, color.g, color.b, color.a), Rml::Unit::COLOUR);
|
||||
set_property(Rml::PropertyId::Color, property, animation);
|
||||
@ -365,6 +449,10 @@ void Element::set_flex_direction(FlexDirection flex_direction) {
|
||||
}
|
||||
}
|
||||
|
||||
void Element::set_align_items(AlignItems align_items) {
|
||||
set_property(Rml::PropertyId::AlignItems, to_rml(align_items));
|
||||
}
|
||||
|
||||
void Element::set_overflow(Overflow overflow) {
|
||||
set_property(Rml::PropertyId::OverflowX, to_rml(overflow));
|
||||
set_property(Rml::PropertyId::OverflowY, to_rml(overflow));
|
||||
@ -412,4 +500,8 @@ void Element::set_text(const std::string &text) {
|
||||
base->SetInnerRML(text);
|
||||
}
|
||||
|
||||
void Element::set_text_align(TextAlign text_align) {
|
||||
set_property(Rml::PropertyId::TextAlign, to_rml(text_align));
|
||||
}
|
||||
|
||||
};
|
@ -103,6 +103,14 @@ enum class FlexDirection {
|
||||
Column
|
||||
};
|
||||
|
||||
enum class AlignItems {
|
||||
FlexStart,
|
||||
FlexEnd,
|
||||
Center,
|
||||
Baseline,
|
||||
Stretch
|
||||
};
|
||||
|
||||
enum class Overflow {
|
||||
Visible,
|
||||
Hidden,
|
||||
@ -126,6 +134,13 @@ enum class FontStyle {
|
||||
Italic
|
||||
};
|
||||
|
||||
enum class TextAlign {
|
||||
Left,
|
||||
Right,
|
||||
Center,
|
||||
Justify
|
||||
};
|
||||
|
||||
struct Animation {
|
||||
AnimationType type = AnimationType::None;
|
||||
float duration = 0.0f;
|
||||
@ -146,7 +161,6 @@ private:
|
||||
// Rml::EventListener overrides.
|
||||
virtual void ProcessEvent(Rml::Event &event) override;
|
||||
protected:
|
||||
Element *parent;
|
||||
Rml::Element *base;
|
||||
bool owner;
|
||||
|
||||
@ -167,6 +181,10 @@ public:
|
||||
void set_width_auto();
|
||||
void set_height(float height, Unit unit = Unit::Dp, Animation animation = Animation());
|
||||
void set_height_auto();
|
||||
void set_min_width(float width, Unit unit = Unit::Dp, Animation animation = Animation());
|
||||
void set_min_height(float height, Unit unit = Unit::Dp, Animation animation = Animation());
|
||||
void set_max_width(float width, Unit unit = Unit::Dp, Animation animation = Animation());
|
||||
void set_max_height(float height, Unit unit = Unit::Dp, Animation animation = Animation());
|
||||
void set_padding(float padding, Unit unit = Unit::Dp, Animation animation = Animation());
|
||||
void set_padding_left(float padding, Unit unit = Unit::Dp, Animation animation = Animation());
|
||||
void set_padding_top(float padding, Unit unit = Unit::Dp, Animation animation = Animation());
|
||||
@ -178,6 +196,10 @@ public:
|
||||
void set_margin_right(float margin, Unit unit = Unit::Dp, Animation animation = Animation());
|
||||
void set_margin_bottom(float margin, Unit unit = Unit::Dp, Animation animation = Animation());
|
||||
void set_border_width(float width, Unit unit = Unit::Dp, Animation animation = Animation());
|
||||
void set_border_left_width(float width, Unit unit = Unit::Dp, Animation animation = Animation());
|
||||
void set_border_top_width(float width, Unit unit = Unit::Dp, Animation animation = Animation());
|
||||
void set_border_right_width(float width, Unit unit = Unit::Dp, Animation animation = Animation());
|
||||
void set_border_bottom_width(float width, Unit unit = Unit::Dp, Animation animation = Animation());
|
||||
void set_border_radius(float radius, Unit unit = Unit::Dp, Animation animation = Animation());
|
||||
void set_border_top_left_radius(float radius, Unit unit = Unit::Dp, Animation animation = Animation());
|
||||
void set_border_top_right_radius(float radius, Unit unit = Unit::Dp, Animation animation = Animation());
|
||||
@ -185,6 +207,10 @@ public:
|
||||
void set_border_bottom_right_radius(float radius, Unit unit = Unit::Dp, Animation animation = Animation());
|
||||
void set_background_color(const Color &color, Animation animation = Animation());
|
||||
void set_border_color(const Color &color, Animation animation = Animation());
|
||||
void set_border_left_color(const Color &color, Animation animation = Animation());
|
||||
void set_border_top_color(const Color &color, Animation animation = Animation());
|
||||
void set_border_right_color(const Color &color, Animation animation = Animation());
|
||||
void set_border_bottom_color(const Color &color, Animation animation = Animation());
|
||||
void set_color(const Color &color, Animation animation = Animation());
|
||||
void set_cursor(Cursor cursor);
|
||||
void set_opacity(float opacity, Animation animation = Animation());
|
||||
@ -197,6 +223,7 @@ public:
|
||||
void set_flex(float grow, float shrink, Animation animation = Animation());
|
||||
void set_flex(float grow, float shrink, float basis_percentage, Animation animation = Animation());
|
||||
void set_flex_direction(FlexDirection flex_direction);
|
||||
void set_align_items(AlignItems align_items);
|
||||
void set_overflow(Overflow overflow);
|
||||
void set_overflow_x(Overflow overflow);
|
||||
void set_overflow_y(Overflow overflow);
|
||||
@ -206,6 +233,7 @@ public:
|
||||
void set_font_style(FontStyle style);
|
||||
void set_font_weight(uint32_t weight, Animation animation = Animation());
|
||||
void set_text(const std::string &text);
|
||||
void set_text_align(TextAlign text_align);
|
||||
};
|
||||
|
||||
} // namespace recompui
|
@ -6,20 +6,27 @@ namespace recompui {
|
||||
|
||||
Label::Label(LabelStyle label_style, Element *parent) : Element(parent) {
|
||||
switch (label_style) {
|
||||
case LabelStyle::Small:
|
||||
set_font_size(20.0f);
|
||||
set_letter_spacing(0.0f);
|
||||
set_line_height(20.0f);
|
||||
set_font_weight(400);
|
||||
break;
|
||||
case LabelStyle::Normal:
|
||||
set_font_size(28.0f);
|
||||
set_letter_spacing(3.08f);
|
||||
set_line_height(28.0f);
|
||||
set_font_weight(700);
|
||||
break;
|
||||
case LabelStyle::Large:
|
||||
set_font_size(36.0f);
|
||||
set_letter_spacing(2.52f);
|
||||
set_line_height(36.0f);
|
||||
set_font_weight(700);
|
||||
break;
|
||||
}
|
||||
|
||||
set_font_style(FontStyle::Normal);
|
||||
set_font_weight(700);
|
||||
}
|
||||
|
||||
Label::Label(const std::string &text, LabelStyle label_style, Element *parent) : Label(label_style, parent) {
|
||||
|
@ -5,6 +5,7 @@
|
||||
namespace recompui {
|
||||
|
||||
enum class LabelStyle {
|
||||
Small,
|
||||
Normal,
|
||||
Large
|
||||
};
|
||||
|
27
src/ui/elements/ui_scroll_container.cpp
Normal file
27
src/ui/elements/ui_scroll_container.cpp
Normal file
@ -0,0 +1,27 @@
|
||||
#include "ui_scroll_container.h"
|
||||
|
||||
#include <cassert>
|
||||
|
||||
namespace recompui {
|
||||
|
||||
ScrollContainer::ScrollContainer(ScrollDirection direction, Element *parent) : Element(parent) {
|
||||
set_flex(1.0f, 1.0f, 100.0f);
|
||||
set_width(100.0f, Unit::Percent);
|
||||
set_height(100.0f, Unit::Percent);
|
||||
|
||||
switch (direction) {
|
||||
case ScrollDirection::Horizontal:
|
||||
set_max_width(100.0f, Unit::Percent);
|
||||
set_overflow_x(Overflow::Auto);
|
||||
break;
|
||||
case ScrollDirection::Vertical:
|
||||
set_max_height(100.0f, Unit::Percent);
|
||||
set_overflow_y(Overflow::Auto);
|
||||
break;
|
||||
default:
|
||||
assert(false && "Unknown scroll direction.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
};
|
17
src/ui/elements/ui_scroll_container.h
Normal file
17
src/ui/elements/ui_scroll_container.h
Normal file
@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#include "ui_element.h"
|
||||
|
||||
namespace recompui {
|
||||
|
||||
enum class ScrollDirection {
|
||||
Horizontal,
|
||||
Vertical
|
||||
};
|
||||
|
||||
class ScrollContainer : public Element {
|
||||
public:
|
||||
ScrollContainer(ScrollDirection direction, Element *parent);
|
||||
};
|
||||
|
||||
} // namespace recompui
|
@ -14,7 +14,7 @@
|
||||
#include "elements/ElementOptionTypeRange.h"
|
||||
#include "elements/ElementOptionTypeTextField.h"
|
||||
#include "elements/ElementDescription.h"
|
||||
#include "elements/ElementModMenu.h"
|
||||
#include "ui_mod_menu.h"
|
||||
|
||||
namespace recompui {
|
||||
void register_custom_elements();
|
||||
|
@ -1,6 +1,5 @@
|
||||
#include "ui_mod_details_panel.h"
|
||||
|
||||
#include "presets.h"
|
||||
#include "librecomp/mods.hpp"
|
||||
|
||||
namespace recompui {
|
@ -1,13 +1,12 @@
|
||||
#ifndef RECOMPUI_ELEMENT_MOD_DETAILS_PANEL_H
|
||||
#define RECOMPUI_ELEMENT_MOD_DETAILS_PANEL_H
|
||||
|
||||
#include "common.h"
|
||||
#include "librecomp/mods.hpp"
|
||||
#include "ui_button.h"
|
||||
#include "ui_container.h"
|
||||
#include "ui_image.h"
|
||||
#include "ui_label.h"
|
||||
#include "ui_toggle.h"
|
||||
#include "elements/ui_button.h"
|
||||
#include "elements/ui_container.h"
|
||||
#include "elements/ui_image.h"
|
||||
#include "elements/ui_label.h"
|
||||
#include "elements/ui_toggle.h"
|
||||
|
||||
namespace recompui {
|
||||
|
161
src/ui/ui_mod_menu.cpp
Normal file
161
src/ui/ui_mod_menu.cpp
Normal file
@ -0,0 +1,161 @@
|
||||
#include "ui_mod_menu.h"
|
||||
|
||||
#include "elements/presets.h"
|
||||
#include "librecomp/mods.hpp"
|
||||
|
||||
#include <string>
|
||||
|
||||
// TODO:
|
||||
// - Set up navigation.
|
||||
// - Add hover and active state for mod entries.
|
||||
|
||||
namespace recompui {
|
||||
|
||||
ModEntry::ModEntry(Element *parent, const recomp::mods::ModDetails &details, uint32_t mod_index, ModMenu *mod_menu) : Element(parent, Events(EventType::Click, EventType::Hover, EventType::Focus)) {
|
||||
assert(mod_menu != nullptr);
|
||||
|
||||
this->mod_index = mod_index;
|
||||
this->mod_menu = mod_menu;
|
||||
|
||||
set_display(Display::Flex);
|
||||
set_flex_direction(FlexDirection::Row);
|
||||
set_width(100.0f, Unit::Percent);
|
||||
set_height_auto();
|
||||
set_padding_top(4.0f);
|
||||
set_padding_right(8.0f);
|
||||
set_padding_bottom(4.0f);
|
||||
set_padding_left(8.0f);
|
||||
set_border_width(1.1f);
|
||||
set_border_color(Color{ 242, 242, 242, 204 });
|
||||
set_background_color(Color{ 242, 242, 242, 12 });
|
||||
set_cursor(Cursor::Pointer);
|
||||
|
||||
{
|
||||
thumbnail_image = std::make_unique<Image>(this);
|
||||
thumbnail_image->set_width(100.0f);
|
||||
thumbnail_image->set_height(100.0f);
|
||||
thumbnail_image->set_min_width(100.0f);
|
||||
thumbnail_image->set_min_height(100.0f);
|
||||
thumbnail_image->set_background_color(Color{ 190, 184, 219, 25 });
|
||||
|
||||
body_container = std::make_unique<Container>(FlexDirection::Column, JustifyContent::FlexStart, this);
|
||||
body_container->set_width_auto();
|
||||
body_container->set_height(100.0f);
|
||||
body_container->set_margin_left(16.0f);
|
||||
body_container->set_overflow(Overflow::Hidden);
|
||||
|
||||
{
|
||||
name_label = std::make_unique<Label>(details.mod_id, LabelStyle::Normal, body_container.get());
|
||||
description_label = std::make_unique<Label>("Short description of mod here.", LabelStyle::Small, body_container.get());
|
||||
} // body_container
|
||||
} // this
|
||||
}
|
||||
|
||||
ModEntry::~ModEntry() {
|
||||
|
||||
}
|
||||
|
||||
void ModEntry::process_event(const Event& e) {
|
||||
switch (e.type) {
|
||||
case EventType::Click:
|
||||
mod_menu->set_active_mod(mod_index);
|
||||
break;
|
||||
case EventType::Hover:
|
||||
break;
|
||||
case EventType::Focus:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ModMenu::set_active_mod(uint32_t mod_index) {
|
||||
mod_details_panel->set_mod_details(mod_details[mod_index]);
|
||||
}
|
||||
|
||||
void ModMenu::refresh_mods() {
|
||||
recomp::mods::scan_mods();
|
||||
mod_details = recomp::mods::get_mod_details(game_mod_id);
|
||||
create_mod_list();
|
||||
}
|
||||
|
||||
void ModMenu::create_mod_list() {
|
||||
// Clear the contents of the list scroll.
|
||||
mod_entries.clear();
|
||||
|
||||
// Create the child elements for the list scroll.
|
||||
for (size_t mod_index = 0; mod_index < mod_details.size(); mod_index++) {
|
||||
mod_entries.emplace_back(std::make_unique<ModEntry>(list_scroll_container.get(), mod_details[mod_index], mod_index, this));
|
||||
}
|
||||
|
||||
set_active_mod(0);
|
||||
}
|
||||
|
||||
ModMenu::ModMenu(Element *parent) : Element(parent) {
|
||||
game_mod_id = "mm";
|
||||
|
||||
set_display(Display::Flex);
|
||||
set_flex(1.0f, 1.0f, 100.0f);
|
||||
set_flex_direction(FlexDirection::Column);
|
||||
set_align_items(AlignItems::Center);
|
||||
set_justify_content(JustifyContent::FlexStart);
|
||||
set_width(100.0f, Unit::Percent);
|
||||
set_height(100.0f, Unit::Percent);
|
||||
|
||||
{
|
||||
body_container = std::make_unique<Container>(FlexDirection::Row, JustifyContent::FlexStart, this);
|
||||
body_container->set_flex(1.0f, 1.0f, 100.0f);
|
||||
body_container->set_width(100.0f, Unit::Percent);
|
||||
body_container->set_height(100.0f, Unit::Percent);
|
||||
{
|
||||
list_container = std::make_unique<Container>(FlexDirection::Column, JustifyContent::Center, body_container.get());
|
||||
list_container->set_display(Display::Block);
|
||||
list_container->set_flex_basis_percentage(100.0f);
|
||||
list_container->set_align_items(AlignItems::Center);
|
||||
list_container->set_height(100.0f, Unit::Percent);
|
||||
list_container->set_background_color(Color{ 0, 0, 0, 89 });
|
||||
list_container->set_border_bottom_left_radius(16.0f);
|
||||
{
|
||||
list_scroll_container = std::make_unique<ScrollContainer>(ScrollDirection::Vertical, list_container.get());
|
||||
} // list_container
|
||||
|
||||
mod_details_panel = std::make_unique<ModDetailsPanel>(body_container.get());
|
||||
} // body_container
|
||||
|
||||
|
||||
footer_container = std::make_unique<recompui::Container>(FlexDirection::Row, JustifyContent::SpaceBetween, this);
|
||||
footer_container->set_width(100.0f, recompui::Unit::Percent);
|
||||
footer_container->set_align_items(recompui::AlignItems::Center);
|
||||
footer_container->set_background_color(Color{ 0, 0, 0, 89 });
|
||||
footer_container->set_border_top_width(1.1f);
|
||||
footer_container->set_border_top_color(Color{ 255, 255, 255, 25 });
|
||||
footer_container->set_padding(20.0f);
|
||||
footer_container->set_border_bottom_left_radius(16.0f);
|
||||
footer_container->set_border_bottom_right_radius(16.0f);
|
||||
{
|
||||
refresh_button = std::make_unique<recompui::Button>("Refresh", recompui::ButtonStyle::Primary, footer_container.get());
|
||||
refresh_button->add_pressed_callback(std::bind(&ModMenu::refresh_mods, this));
|
||||
} // footer_container
|
||||
} // this
|
||||
|
||||
refresh_mods();
|
||||
}
|
||||
|
||||
ModMenu::~ModMenu() {
|
||||
}
|
||||
|
||||
// Placeholder class until the rest of the UI refactor is finished.
|
||||
|
||||
ElementModMenu::ElementModMenu(const Rml::String &tag) : Rml::Element(tag) {
|
||||
SetProperty("width", "100%");
|
||||
SetProperty("height", "100%");
|
||||
|
||||
recompui::Element this_compat(this);
|
||||
mod_menu = std::make_unique<ModMenu>(&this_compat);
|
||||
}
|
||||
|
||||
ElementModMenu::~ElementModMenu() {
|
||||
|
||||
}
|
||||
|
||||
} // namespace recompui
|
56
src/ui/ui_mod_menu.h
Normal file
56
src/ui/ui_mod_menu.h
Normal file
@ -0,0 +1,56 @@
|
||||
#ifndef RECOMPUI_ELEMENT_MOD_MENU_H
|
||||
#define RECOMPUI_ELEMENT_MOD_MENU_H
|
||||
|
||||
#include "librecomp/mods.hpp"
|
||||
#include "elements/ui_scroll_container.h"
|
||||
#include "ui_mod_details_panel.h"
|
||||
|
||||
namespace recompui {
|
||||
|
||||
class ModMenu;
|
||||
|
||||
class ModEntry : public Element {
|
||||
public:
|
||||
ModEntry(Element *parent, const recomp::mods::ModDetails &details, uint32_t mod_index, ModMenu *mod_menu);
|
||||
virtual ~ModEntry();
|
||||
protected:
|
||||
virtual void process_event(const Event &e);
|
||||
private:
|
||||
uint32_t mod_index;
|
||||
ModMenu *mod_menu;
|
||||
std::unique_ptr<Image> thumbnail_image;
|
||||
std::unique_ptr<Container> body_container;
|
||||
std::unique_ptr<Label> name_label;
|
||||
std::unique_ptr<Label> description_label;
|
||||
};
|
||||
|
||||
class ModMenu : public Element {
|
||||
public:
|
||||
ModMenu(Element *parent);
|
||||
virtual ~ModMenu();
|
||||
void set_active_mod(uint32_t mod_index);
|
||||
private:
|
||||
void refresh_mods();
|
||||
void create_mod_list();
|
||||
|
||||
std::unique_ptr<Container> body_container;
|
||||
std::unique_ptr<Container> list_container;
|
||||
std::unique_ptr<ScrollContainer> list_scroll_container;
|
||||
std::unique_ptr<ModDetailsPanel> mod_details_panel;
|
||||
std::unique_ptr<Container> footer_container;
|
||||
std::unique_ptr<Button> refresh_button;
|
||||
std::vector<std::unique_ptr<ModEntry>> mod_entries;
|
||||
std::vector<recomp::mods::ModDetails> mod_details{};
|
||||
std::string game_mod_id;
|
||||
};
|
||||
|
||||
class ElementModMenu : public Rml::Element {
|
||||
public:
|
||||
ElementModMenu(const Rml::String& tag);
|
||||
virtual ~ElementModMenu();
|
||||
private:
|
||||
std::unique_ptr<ModMenu> mod_menu;
|
||||
};
|
||||
|
||||
} // namespace recompui
|
||||
#endif
|
Loading…
x
Reference in New Issue
Block a user