From bc0b3c61ae0b742da304cada451fba1df72bb0ad Mon Sep 17 00:00:00 2001 From: hop311 Date: Wed, 8 Nov 2023 22:24:21 +0000 Subject: GUI elements -> Godot UI nodes generator --- extension/src/openvic-extension/UIAdapter.cpp | 404 ++++++++++++++++++++++++++ 1 file changed, 404 insertions(+) create mode 100644 extension/src/openvic-extension/UIAdapter.cpp (limited to 'extension/src/openvic-extension/UIAdapter.cpp') diff --git a/extension/src/openvic-extension/UIAdapter.cpp b/extension/src/openvic-extension/UIAdapter.cpp new file mode 100644 index 0000000..5b889d6 --- /dev/null +++ b/extension/src/openvic-extension/UIAdapter.cpp @@ -0,0 +1,404 @@ +#include "UIAdapter.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "openvic-extension/classes/GFXIconTexture.hpp" +#include "openvic-extension/utility/Utilities.hpp" + +using namespace godot; +using namespace OpenVic; + +using OpenVic::Utilities::std_view_to_godot_string; +using OpenVic::Utilities::std_view_to_godot_string_name; + +bool GodotGUIBuilder::generate_element(GUI::Element const* element, AssetManager& asset_manager, Control*& result) { + if (element == nullptr) { + UtilityFunctions::push_error("Invalid element passed to GodotGUIBuilder - null!"); + return false; + } + static const std::map type_map { + { GUI::Icon::get_type_static(), &generate_icon }, + { GUI::Button::get_type_static(), &generate_button }, + { GUI::Checkbox::get_type_static(), &generate_checkbox }, + { GUI::Text::get_type_static(), &generate_text }, + { GUI::OverlappingElementsBox::get_type_static(), &generate_overlapping_elements }, + { GUI::ListBox::get_type_static(), &generate_listbox }, + { GUI::Window::get_type_static(), &generate_window } + }; + const decltype(type_map)::const_iterator it = type_map.find(element->get_type()); + if (it != type_map.end()) { + return it->second(*element, asset_manager, result); + } else { + UtilityFunctions::push_error("Invalid GUI element type: ", std_view_to_godot_string(element->get_type())); + result = nullptr; + return false; + } +} + +template T> +static T* new_control(GUI::Element const& element) { + T* node = memnew(T); + ERR_FAIL_NULL_V(node, nullptr); + + using enum GUI::Element::orientation_t; + using enum Control::LayoutPreset; + static const std::map orientation_map { + { UPPER_LEFT, PRESET_TOP_LEFT }, { LOWER_LEFT, PRESET_BOTTOM_LEFT }, + { LOWER_RIGHT, PRESET_BOTTOM_RIGHT }, { UPPER_RIGHT, PRESET_TOP_RIGHT }, + { CENTER, PRESET_CENTER } + }; + + node->set_name(std_view_to_godot_string(element.get_name())); + const decltype(orientation_map)::const_iterator it = orientation_map.find(element.get_orientation()); + if (it != orientation_map.end()) { + node->set_anchors_and_offsets_preset(it->second); + } else { + UtilityFunctions::push_error("Invalid orientation for GUI element ", + std_view_to_godot_string(element.get_name())); + } + node->set_position(Utilities::to_godot_ivec2(element.get_position())); + node->set_focus_mode(Control::FOCUS_NONE); + + return node; +} + +bool GodotGUIBuilder::generate_icon(GUI::Element const& element, AssetManager& asset_manager, Control*& result) { + GUI::Icon const& icon = static_cast(element); + + result = nullptr; + const String icon_name = std_view_to_godot_string(icon.get_name()); + + /* Change to use sprite type to choose Godot node type! */ + bool ret = true; + if (icon.get_sprite() != nullptr) { + if (icon.get_sprite()->is_type()) { + TextureRect* godot_texture_rect = new_control(icon); + if (godot_texture_rect == nullptr) { + UtilityFunctions::push_error("Failed to create TextureRect for GUI icon ", icon_name); + return false; + } + + GFX::TextureSprite const* texture_sprite = icon.get_sprite()->cast_to(); + Ref texture = GFXIconTexture::make_gfx_icon_texture(texture_sprite, icon.get_frame()); + if (texture.is_valid()) { + godot_texture_rect->set_texture(texture); + } else { + UtilityFunctions::push_error("Failed to make GFXIconTexture for GUI icon ", icon_name); + ret = false; + } + + result = godot_texture_rect; + } else if (icon.get_sprite()->is_type()) { + TextureRect* godot_texture_rect = new_control(icon); + if (godot_texture_rect == nullptr) { + UtilityFunctions::push_error("Failed to create TextureRect for GUI icon ", icon_name); + return false; + } + + const StringName texture_file = + std_view_to_godot_string_name(icon.get_sprite()->cast_to()->get_texture_file()); + const Ref texture = asset_manager.get_texture(texture_file); + if (texture.is_valid()) { + godot_texture_rect->set_texture(texture); + } else { + UtilityFunctions::push_error("Failed to load masked flag sprite ", texture_file, " for GUI icon ", icon_name); + ret = false; + } + + result = godot_texture_rect; + } else if (icon.get_sprite()->is_type()) { + TextureProgressBar* godot_progress_bar = new_control(icon); + if (godot_progress_bar == nullptr) { + UtilityFunctions::push_error("Failed to create TextureProgressBar for GUI icon ", icon_name); + return false; + } + + const StringName back_texture_file = + std_view_to_godot_string_name(icon.get_sprite()->cast_to()->get_back_texture_file()); + const Ref back_texture = asset_manager.get_texture(back_texture_file); + if (back_texture.is_valid()) { + godot_progress_bar->set_under_texture(back_texture); + } else { + UtilityFunctions::push_error("Failed to load progress bar base sprite ", back_texture_file, " for GUI icon ", icon_name); + ret = false; + } + + const StringName progress_texture_file = + std_view_to_godot_string_name(icon.get_sprite()->cast_to()->get_progress_texture_file()); + const Ref progress_texture = asset_manager.get_texture(progress_texture_file); + if (progress_texture.is_valid()) { + godot_progress_bar->set_progress_texture(progress_texture); + } else { + UtilityFunctions::push_error( + "Failed to load progress bar base sprite ", progress_texture_file, " for GUI icon ", icon_name + ); + ret = false; + } + + result = godot_progress_bar; + } else if (icon.get_sprite()->is_type()) { + + } else if (icon.get_sprite()->is_type()) { + + } else { + UtilityFunctions::push_error("Invalid sprite type ", std_view_to_godot_string(icon.get_sprite()->get_type()), + " for GUI icon ", icon_name); + ret = false; + } + } else { + UtilityFunctions::push_error("Null sprite for GUI icon ", icon_name); + ret = false; + } + return ret; +} + +bool GodotGUIBuilder::generate_button(GUI::Element const& element, AssetManager& asset_manager, Control*& result) { + GUI::Button const& button = static_cast(element); + + // TODO - shortcut, sprite, text + result = nullptr; + const String button_name = std_view_to_godot_string(button.get_name()); + + Button* godot_button = new_control