aboutsummaryrefslogtreecommitdiff
path: root/extension/src/openvic-extension/classes/GUILabel.hpp
diff options
context:
space:
mode:
author Hop311 <Hop3114@gmail.com>2024-08-30 23:29:57 +0200
committer GitHub <noreply@github.com>2024-08-30 23:29:57 +0200
commitf54e454afb90f8868e7c62529e2a388fdaadf20b (patch)
treef19dbcdfe613397e86dc52cc34e0a443bd0f3e96 /extension/src/openvic-extension/classes/GUILabel.hpp
parent855e5b087459da19caf230cf22d99462680b268e (diff)
parentd7672f406406eea46625bc725690651f28211e19 (diff)
Merge pull request #251 from OpenVicProject/gui-text-label
Add GUILabel (colour code + currency icon support)
Diffstat (limited to 'extension/src/openvic-extension/classes/GUILabel.hpp')
-rw-r--r--extension/src/openvic-extension/classes/GUILabel.hpp116
1 files changed, 116 insertions, 0 deletions
diff --git a/extension/src/openvic-extension/classes/GUILabel.hpp b/extension/src/openvic-extension/classes/GUILabel.hpp
new file mode 100644
index 0000000..e0982b2
--- /dev/null
+++ b/extension/src/openvic-extension/classes/GUILabel.hpp
@@ -0,0 +1,116 @@
+#pragma once
+
+#include <godot_cpp/classes/control.hpp>
+#include <godot_cpp/classes/font.hpp>
+#include <godot_cpp/classes/font_file.hpp>
+#include <godot_cpp/classes/style_box_texture.hpp>
+
+#include <openvic-simulation/interface/GUI.hpp>
+
+#include "openvic-extension/classes/GFXSpriteTexture.hpp"
+
+namespace OpenVic {
+ class GUILabel : public godot::Control {
+ GDCLASS(GUILabel, godot::Control)
+
+ using colour_instructions_t = std::vector<std::pair<int64_t, char>>;
+
+ GUI::Text const* PROPERTY(gui_text);
+
+ godot::String PROPERTY(text);
+ godot::Dictionary PROPERTY(substitution_dict);
+ godot::HorizontalAlignment PROPERTY(horizontal_alignment);
+ godot::Size2 PROPERTY(max_size); // Actual max size is max_size - 2 * border_size
+ godot::Size2 PROPERTY(border_size); // The padding between the Nodes bounding box and the text within it
+ godot::Rect2 PROPERTY(adjusted_rect); // Offset + size after adjustment to fit content size
+ bool PROPERTY_CUSTOM_PREFIX(auto_adjust_to_content_size, will);
+
+ godot::Ref<godot::Font> font;
+ int32_t PROPERTY(font_size);
+ godot::Color PROPERTY(default_colour);
+ GFX::Font::colour_codes_t const* colour_codes;
+ godot::Ref<GFXSpriteTexture> currency_texture;
+
+ godot::Ref<godot::StyleBoxTexture> background;
+
+ struct string_segment_t {
+ godot::String text;
+ godot::Color colour;
+ real_t width;
+ };
+ using currency_segment_t = std::monostate;
+ using segment_t = std::variant<string_segment_t, currency_segment_t>;
+ struct line_t {
+ std::vector<segment_t> segments;
+ real_t width {};
+ };
+
+ std::vector<line_t> lines;
+
+ bool line_update_queued;
+
+ protected:
+ static void _bind_methods();
+
+ void _notification(int what);
+
+ public:
+ GUILabel();
+
+ /* Reset gui_text to nullptr and reset current text. */
+ void clear();
+ /* Return the name of the GUI::Text, or an empty String if it's null. */
+ godot::String get_gui_text_name() const;
+ /* Set the GUI::Text. */
+ godot::Error set_gui_text(
+ GUI::Text const* new_gui_text, GFX::Font::colour_codes_t const* override_colour_codes = nullptr
+ );
+
+ void set_text(godot::String const& new_text);
+
+ void add_substitution(godot::String const& key, godot::String const& value);
+ void set_substitution_dict(godot::Dictionary const& new_substitution_dict);
+ void clear_substitutions();
+
+ void set_horizontal_alignment(godot::HorizontalAlignment new_horizontal_alignment);
+ void set_max_size(godot::Size2 new_max_size);
+ void set_border_size(godot::Size2 new_border_size);
+ void set_auto_adjust_to_content_size(bool new_auto_adjust_to_content_size);
+
+ godot::Ref<godot::Font> get_font() const;
+ void set_font(godot::Ref<godot::Font> const& new_font);
+ godot::Error set_font_file(godot::Ref<godot::FontFile> const& new_font_file);
+ godot::Error set_font_size(int32_t new_font_size);
+ void set_default_colour(godot::Color const& new_default_colour);
+
+ godot::Ref<GFXSpriteTexture> get_currency_texture() const;
+
+ godot::Ref<godot::StyleBoxTexture> get_background() const;
+ void set_background_texture(godot::Ref<godot::Texture2D> const& new_texture);
+ void set_background_stylebox(godot::Ref<godot::StyleBoxTexture> const& new_stylebox_texture);
+
+ private:
+ void update_stylebox_border_size();
+ real_t get_string_width(godot::String const& string) const;
+ real_t get_segment_width(segment_t const& segment) const;
+
+ void _queue_line_update();
+ void _update_lines();
+
+ godot::String generate_substituted_text(godot::String const& base_text) const;
+ std::pair<godot::String, colour_instructions_t> generate_display_text_and_colour_instructions(
+ godot::String const& substituted_text
+ ) const;
+ std::vector<line_t> generate_lines_and_segments(
+ godot::String const& display_text, colour_instructions_t const& colour_instructions
+ ) const;
+ void separate_lines(
+ godot::String const& string, godot::Color const& colour, std::vector<line_t>& lines
+ ) const;
+ void separate_currency_segments(
+ godot::String const& string, godot::Color const& colour, line_t& line
+ ) const;
+ std::vector<line_t> wrap_lines(std::vector<line_t>& unwrapped_lines) const;
+ void adjust_to_content_size();
+ };
+}