diff --git a/CMakeLists.txt b/CMakeLists.txt
index bd719b2..af69dbe 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -172,6 +172,7 @@ set (SOURCES
${CMAKE_SOURCE_DIR}/src/ui/ui_state.cpp
${CMAKE_SOURCE_DIR}/src/ui/ui_launcher.cpp
${CMAKE_SOURCE_DIR}/src/ui/ui_config.cpp
+ ${CMAKE_SOURCE_DIR}/src/ui/ui_prompt.cpp
${CMAKE_SOURCE_DIR}/src/ui/ui_config_sub_menu.cpp
${CMAKE_SOURCE_DIR}/src/ui/ui_color_hack.cpp
${CMAKE_SOURCE_DIR}/src/ui/ui_rml_hacks.cpp
diff --git a/assets/components/prompt.rml b/assets/components/prompt.rml
deleted file mode 100644
index 3de53ea..0000000
--- a/assets/components/prompt.rml
+++ /dev/null
@@ -1,30 +0,0 @@
-
-
-
-
-
-
-
-
{{ promptHeader }}
-
{{ promptContent }}
-
-
-
-
-
-
-
-
diff --git a/assets/config_menu.rml b/assets/config_menu.rml
index 0666d77..3865510 100644
--- a/assets/config_menu.rml
+++ b/assets/config_menu.rml
@@ -29,7 +29,6 @@
-
@@ -117,19 +116,6 @@
-->
-
diff --git a/include/recomp_ui.h b/include/recomp_ui.h
index acae932..3982a86 100644
--- a/include/recomp_ui.h
+++ b/include/recomp_ui.h
@@ -29,7 +29,7 @@ namespace recompui {
class MenuController {
public:
virtual ~MenuController() {}
- virtual Rml::ElementDocument* load_document(Rml::Context* context) = 0;
+ virtual void load_document() = 0;
virtual void register_events(UiEventListenerInstancer& listener) = 0;
virtual void make_bindings(Rml::Context* context) = 0;
};
@@ -56,7 +56,6 @@ namespace recompui {
ContextId get_launcher_context_id();
ContextId get_config_context_id();
ContextId get_config_sub_menu_context_id();
- ContextId get_close_prompt_context_id();
enum class ConfigTab {
General,
@@ -79,6 +78,7 @@ namespace recompui {
NumVariants,
};
+ void init_prompt_context();
void open_prompt(
const std::string& headerText,
const std::string& contentText,
diff --git a/src/game/input.cpp b/src/game/input.cpp
index 7384e37..45a6f9f 100644
--- a/src/game/input.cpp
+++ b/src/game/input.cpp
@@ -156,11 +156,6 @@ bool sdl_event_filter(void* userdata, SDL_Event* event) {
return true;
}
- recompui::ContextId config_context_id = recompui::get_config_context_id();
- if (!recompui::is_context_shown(config_context_id)) {
- recompui::show_context(config_context_id, "");
- }
-
zelda64::open_quit_game_prompt();
recompui::activate_mouse();
break;
diff --git a/src/ui/core/ui_context.cpp b/src/ui/core/ui_context.cpp
index 69214e8..397d6d8 100644
--- a/src/ui/core/ui_context.cpp
+++ b/src/ui/core/ui_context.cpp
@@ -206,6 +206,7 @@ recompui::ContextId recompui::create_context() {
root->set_height(100.0f, Unit::Percent);
root->set_display(Display::Flex);
root->set_opacity(1.0f);
+ root->set_color(Color{ 242, 242, 242, 255 });
root->set_font_family("chiaro");
root->set_font_style(FontStyle::Normal);
root->set_font_weight(400);
@@ -218,6 +219,8 @@ recompui::ContextId recompui::create_context() {
root->set_line_height(sz_add, Unit::Dp);
ret.close();
+ doc->Hide();
+
return ret;
}
diff --git a/src/ui/elements/ui_button.h b/src/ui/elements/ui_button.h
index a133b24..b5ff114 100644
--- a/src/ui/elements/ui_button.h
+++ b/src/ui/elements/ui_button.h
@@ -22,6 +22,9 @@ namespace recompui {
public:
Button(Element *parent, const std::string &text, ButtonStyle style);
void add_pressed_callback(std::function callback);
+ Style* get_hover_style() { return &hover_style; }
+ Style* get_disabled_style() { return &disabled_style; }
+ Style* get_hover_disabled_style() { return &hover_disabled_style; }
};
} // namespace recompui
\ No newline at end of file
diff --git a/src/ui/ui_config.cpp b/src/ui/ui_config.cpp
index 8258739..5d20c7e 100644
--- a/src/ui/ui_config.cpp
+++ b/src/ui/ui_config.cpp
@@ -442,11 +442,8 @@ public:
~ConfigMenu() override {
}
- Rml::ElementDocument* load_document(Rml::Context* context) override {
- (void)context;
+ void load_document() override {
config_context = recompui::create_context(zelda64::get_asset_path("config_menu.rml"));
- Rml::ElementDocument* ret = config_context.get_document();
- return ret;
}
void register_events(recompui::UiEventListenerInstancer& listener) override {
recompui::register_event(listener, "apply_options",
@@ -959,27 +956,6 @@ void recompui::toggle_fullscreen() {
graphics_model_handle.DirtyVariable("wm_option");
}
-void recompui::open_prompt(
- const std::string& headerText,
- const std::string& contentText,
- const std::string& confirmLabelText,
- const std::string& cancelLabelText,
- std::function confirmCb,
- std::function cancelCb,
- ButtonVariant _confirmVariant,
- ButtonVariant _cancelVariant,
- bool _focusOnCancel,
- const std::string& _returnElementId
-) {
- printf("Prompt opened\n %s (%s): %s %s\n", contentText.c_str(), headerText.c_str(), confirmLabelText.c_str(), cancelLabelText.c_str());
- printf(" Autoselected %s\n", confirmLabelText.c_str());
- confirmCb();
-}
-
-bool recompui::is_prompt_open() {
- return false;
-}
-
void recompui::set_config_tab(ConfigTab tab) {
ContextId config_context = recompui::get_config_context_id();
diff --git a/src/ui/ui_launcher.cpp b/src/ui/ui_launcher.cpp
index fd0ee8e..67149c1 100644
--- a/src/ui/ui_launcher.cpp
+++ b/src/ui/ui_launcher.cpp
@@ -62,11 +62,8 @@ public:
~LauncherMenu() override {
}
- Rml::ElementDocument* load_document(Rml::Context* context) override {
- (void)context;
+ void load_document() override {
launcher_context = recompui::create_context(zelda64::get_asset_path("launcher.rml"));
- Rml::ElementDocument* ret = launcher_context.get_document();
- return ret;
}
void register_events(recompui::UiEventListenerInstancer& listener) override {
recompui::register_event(listener, "select_rom",
diff --git a/src/ui/ui_prompt.cpp b/src/ui/ui_prompt.cpp
new file mode 100644
index 0000000..7e79f42
--- /dev/null
+++ b/src/ui/ui_prompt.cpp
@@ -0,0 +1,243 @@
+#include
+
+#include "recomp_ui.h"
+
+#include "elements/ui_element.h"
+#include "elements/ui_label.h"
+#include "elements/ui_button.h"
+
+struct {
+ recompui::ContextId ui_context;
+ recompui::Label* prompt_header;
+ recompui::Label* prompt_label;
+ recompui::Button* confirm_button;
+ recompui::Button* cancel_button;
+ std::function confirm_action;
+ std::function cancel_action;
+ std::string return_element_id;
+ std::mutex mutex;
+} prompt_state;
+
+void run_confirm_callback() {
+ std::function confirm_action;
+ {
+ std::lock_guard lock{ prompt_state.mutex };
+ confirm_action = std::move(prompt_state.confirm_action);
+ }
+ if (confirm_action) {
+ confirm_action();
+ }
+ recompui::hide_context(prompt_state.ui_context);
+
+ // TODO nav: focus on return_element_id
+ // or just remove it as the usage of the prompt can change now
+}
+
+void run_cancel_callback() {
+ std::function cancel_action;
+ {
+ std::lock_guard lock{ prompt_state.mutex };
+ cancel_action = std::move(prompt_state.cancel_action);
+ }
+ if (cancel_action) {
+ cancel_action();
+ }
+ recompui::hide_context(prompt_state.ui_context);
+
+ // TODO nav: focus on return_element_id
+ // or just remove it as the usage of the prompt can change now
+}
+
+void recompui::init_prompt_context() {
+ ContextId context = create_context();
+
+ std::lock_guard lock{ prompt_state.mutex };
+
+ context.open();
+
+ prompt_state.ui_context = context;
+
+ Element* window = context.create_element(context.get_root_element());
+ window->set_display(Display::Flex);
+ window->set_flex_direction(FlexDirection::Column);
+ window->set_background_color({0, 0, 0, 0});
+
+ Element* prompt_overlay = context.create_element(window);
+ prompt_overlay->set_background_color(Color{ 190, 184, 219, 25 });
+ prompt_overlay->set_position(Position::Absolute);
+ prompt_overlay->set_top(0);
+ prompt_overlay->set_right(0);
+ prompt_overlay->set_bottom(0);
+ prompt_overlay->set_left(0);
+
+ Element* prompt_content_wrapper = context.create_element(window);
+ prompt_content_wrapper->set_display(Display::Flex);
+ prompt_content_wrapper->set_position(Position::Absolute);
+ prompt_content_wrapper->set_top(0);
+ prompt_content_wrapper->set_right(0);
+ prompt_content_wrapper->set_bottom(0);
+ prompt_content_wrapper->set_left(0);
+ prompt_content_wrapper->set_align_items(AlignItems::Center);
+ prompt_content_wrapper->set_justify_content(JustifyContent::Center);
+
+ Element* prompt_content = context.create_element(prompt_content_wrapper);
+ prompt_content->set_display(Display::Flex);
+ prompt_content->set_position(Position::Relative);
+ prompt_content->set_flex(1.0f, 1.0f);
+ prompt_content->set_flex_basis(100, Unit::Percent);
+ prompt_content->set_flex_direction(FlexDirection::Column);
+ prompt_content->set_width(100, Unit::Percent);
+ prompt_content->set_max_width(700, Unit::Dp);
+ prompt_content->set_height_auto();
+ prompt_content->set_margin_auto();
+ prompt_content->set_border_width(1.1, Unit::Dp);
+ prompt_content->set_border_radius(16, Unit::Dp);
+ prompt_content->set_border_color(Color{ 255, 255, 255, 51 });
+ prompt_content->set_background_color(Color{ 8, 7, 13, 229 });
+
+ prompt_state.prompt_header = context.create_element