aboutsummaryrefslogtreecommitdiff
path: root/extension/src/openvic-extension/classes
diff options
context:
space:
mode:
Diffstat (limited to 'extension/src/openvic-extension/classes')
-rw-r--r--extension/src/openvic-extension/classes/GFXButtonStateTexture.cpp106
-rw-r--r--extension/src/openvic-extension/classes/GFXButtonStateTexture.hpp46
-rw-r--r--extension/src/openvic-extension/classes/GFXIconTexture.cpp33
-rw-r--r--extension/src/openvic-extension/classes/GFXIconTexture.hpp12
-rw-r--r--extension/src/openvic-extension/classes/GFXMaskedFlagTexture.cpp31
-rw-r--r--extension/src/openvic-extension/classes/GFXMaskedFlagTexture.hpp13
-rw-r--r--extension/src/openvic-extension/classes/GFXPieChartTexture.cpp31
-rw-r--r--extension/src/openvic-extension/classes/GFXPieChartTexture.hpp23
-rw-r--r--extension/src/openvic-extension/classes/GUINode.cpp3
-rw-r--r--extension/src/openvic-extension/classes/GUIOverlappingElementsBox.cpp9
10 files changed, 275 insertions, 32 deletions
diff --git a/extension/src/openvic-extension/classes/GFXButtonStateTexture.cpp b/extension/src/openvic-extension/classes/GFXButtonStateTexture.cpp
new file mode 100644
index 0000000..e6dff1f
--- /dev/null
+++ b/extension/src/openvic-extension/classes/GFXButtonStateTexture.cpp
@@ -0,0 +1,106 @@
+#include "GFXButtonStateTexture.hpp"
+
+#include "openvic-extension/utility/ClassBindings.hpp"
+
+using namespace OpenVic;
+using namespace godot;
+
+void GFXButtonStateTexture::_bind_methods() {
+ OV_BIND_METHOD(GFXButtonStateTexture::set_button_state, { "new_button_state" });
+ OV_BIND_METHOD(GFXButtonStateTexture::get_button_state);
+
+ OV_BIND_SMETHOD(get_generate_state_image_func_name);
+
+ OV_BIND_SMETHOD(button_state_to_theme_name, { "button_state" });
+ OV_BIND_METHOD(GFXButtonStateTexture::get_button_state_theme);
+
+ OV_BIND_METHOD(GFXButtonStateTexture::generate_state_image, { "source_image" });
+
+ BIND_ENUM_CONSTANT(HOVER);
+ BIND_ENUM_CONSTANT(PRESSED);
+ BIND_ENUM_CONSTANT(DISABLED);
+}
+
+GFXButtonStateTexture::GFXButtonStateTexture() : button_state { HOVER } {}
+
+Ref<GFXButtonStateTexture> GFXButtonStateTexture::make_gfx_button_state_texture(
+ ButtonState button_state, Ref<Image> const& source_image
+) {
+ Ref<GFXButtonStateTexture> button_state_texture;
+ button_state_texture.instantiate();
+ ERR_FAIL_NULL_V(button_state_texture, nullptr);
+ button_state_texture->set_button_state(button_state);
+ if (source_image.is_valid()) {
+ ERR_FAIL_COND_V(button_state_texture->generate_state_image(source_image) != OK, nullptr);
+ }
+ return button_state_texture;
+}
+
+void GFXButtonStateTexture::set_button_state(ButtonState new_button_state) {
+ ERR_FAIL_COND(new_button_state != HOVER && new_button_state != PRESSED && new_button_state != DISABLED);
+ button_state = new_button_state;
+}
+
+Error GFXButtonStateTexture::generate_state_image(Ref<Image> const& source_image) {
+ ERR_FAIL_COND_V(source_image.is_null() || source_image->is_empty(), FAILED);
+ /* Whether we've already set the ImageTexture to an image of the right dimensions and format,
+ * and so can update it without creating and setting a new image, or not. */
+ const bool can_update = state_image.is_valid() && state_image->get_size() == source_image->get_size()
+ && state_image->get_format() == source_image->get_format();
+ if (!can_update) {
+ state_image = Image::create(source_image->get_width(), source_image->get_height(), false, source_image->get_format());
+ ERR_FAIL_NULL_V(state_image, FAILED);
+ }
+
+ static constexpr auto hover_colour = [](Color const& colour) -> Color {
+ return { std::min(colour.r + 0.1f, 1.0f), std::min(colour.g + 0.1f, 1.0f), std::min(colour.b + 0.1f, 1.0f), colour.a };
+ };
+ static constexpr auto pressed_colour = [](Color const& colour) -> Color {
+ return { std::max(colour.r - 0.1f, 0.0f), std::max(colour.g - 0.1f, 0.0f), std::max(colour.b - 0.1f, 0.0f), colour.a };
+ };
+ static constexpr auto disabled_colour = [](Color const& colour) -> Color {
+ const float luma = colour.get_luminance();
+ return { luma, luma, luma, colour.a };
+ };
+
+ const auto colour_func = button_state == HOVER ? hover_colour : button_state == PRESSED ? pressed_colour : disabled_colour;
+
+ for (Vector2i point { 0, 0 }; point.y < state_image->get_height(); ++point.y) {
+ for (point.x = 0; point.x < state_image->get_width(); ++point.x) {
+ state_image->set_pixelv(point, colour_func(source_image->get_pixelv(point)));
+ }
+ }
+
+ if (can_update) {
+ update(state_image);
+ } else {
+ set_image(state_image);
+ }
+ return OK;
+}
+
+StringName const& GFXButtonStateTexture::get_generate_state_image_func_name() {
+ static const StringName generate_state_image_func_name = "generate_state_image";
+ return generate_state_image_func_name;
+}
+
+StringName const& GFXButtonStateTexture::button_state_to_theme_name(ButtonState button_state) {
+ static const StringName theme_name_hover = "hover";
+ static const StringName theme_name_pressed = "pressed";
+ static const StringName theme_name_disabled = "disabled";
+ static const StringName theme_name_error = "";
+ switch (button_state) {
+ case HOVER:
+ return theme_name_hover;
+ case PRESSED:
+ return theme_name_pressed;
+ case DISABLED:
+ return theme_name_disabled;
+ default:
+ return theme_name_error;
+ }
+}
+
+StringName const& GFXButtonStateTexture::get_button_state_theme() const {
+ return button_state_to_theme_name(button_state);
+}
diff --git a/extension/src/openvic-extension/classes/GFXButtonStateTexture.hpp b/extension/src/openvic-extension/classes/GFXButtonStateTexture.hpp
new file mode 100644
index 0000000..32f4087
--- /dev/null
+++ b/extension/src/openvic-extension/classes/GFXButtonStateTexture.hpp
@@ -0,0 +1,46 @@
+#pragma once
+
+#include <godot_cpp/classes/image_texture.hpp>
+
+#include <openvic-simulation/utility/Getters.hpp>
+
+namespace OpenVic {
+ class GFXButtonStateTexture : public godot::ImageTexture {
+ GDCLASS(GFXButtonStateTexture, godot::ImageTexture)
+
+ public:
+ enum ButtonState {
+ HOVER,
+ PRESSED,
+ DISABLED
+ };
+
+ private:
+ ButtonState PROPERTY(button_state);
+ godot::Ref<godot::Image> state_image;
+
+ protected:
+ static void _bind_methods();
+
+ public:
+ GFXButtonStateTexture();
+
+ /* Create a GFXButtonStateTexture using the specified godot::Image. Returns nullptr if generate_state_image fails. */
+ static godot::Ref<GFXButtonStateTexture> make_gfx_button_state_texture(
+ ButtonState button_state, godot::Ref<godot::Image> const& source_image = nullptr
+ );
+
+ /* Set the ButtonState to be generated by this class (calling this does not trigger state image generation). */
+ void set_button_state(ButtonState new_button_state);
+
+ /* Generate a modified version of source_image and update the underlying godot::ImageTexture to use it. */
+ godot::Error generate_state_image(godot::Ref<godot::Image> const& source_image);
+
+ static godot::StringName const& get_generate_state_image_func_name();
+
+ static godot::StringName const& button_state_to_theme_name(ButtonState button_state);
+ godot::StringName const& get_button_state_theme() const;
+ };
+}
+
+VARIANT_ENUM_CAST(OpenVic::GFXButtonStateTexture::ButtonState);
diff --git a/extension/src/openvic-extension/classes/GFXIconTexture.cpp b/extension/src/openvic-extension/classes/GFXIconTexture.cpp
index 895bf6b..5d29c07 100644
--- a/extension/src/openvic-extension/classes/GFXIconTexture.cpp
+++ b/extension/src/openvic-extension/classes/GFXIconTexture.cpp
@@ -15,6 +15,11 @@ using OpenVic::Utilities::godot_to_std_string;
using OpenVic::Utilities::std_view_to_godot_string;
using OpenVic::Utilities::std_view_to_godot_string_name;
+StringName const& GFXIconTexture::_signal_image_updated() {
+ static const StringName signal_image_updated = "image_updated";
+ return signal_image_updated;
+}
+
void GFXIconTexture::_bind_methods() {
OV_BIND_METHOD(GFXIconTexture::clear);
@@ -26,16 +31,32 @@ void GFXIconTexture::_bind_methods() {
OV_BIND_METHOD(GFXIconTexture::get_icon_count);
ADD_PROPERTY(PropertyInfo(Variant::INT, "icon_index"), "set_icon_index", "get_icon_index");
+
+ ADD_SIGNAL(
+ MethodInfo(_signal_image_updated(), PropertyInfo(Variant::OBJECT, "source_image", PROPERTY_HINT_RESOURCE_TYPE, "Image"))
+ );
}
GFXIconTexture::GFXIconTexture()
: gfx_texture_sprite { nullptr }, icon_index { GFX::NO_FRAMES }, icon_count { GFX::NO_FRAMES } {}
-Ref<GFXIconTexture> GFXIconTexture::make_gfx_icon_texture(GFX::TextureSprite const* gfx_texture_sprite, GFX::frame_t icon) {
+Ref<GFXIconTexture> GFXIconTexture::make_gfx_icon_texture(
+ GFX::TextureSprite const* gfx_texture_sprite, GFX::frame_t icon,
+ std::vector<Ref<GFXButtonStateTexture>> const& button_state_textures
+) {
Ref<GFXIconTexture> icon_texture;
icon_texture.instantiate();
ERR_FAIL_NULL_V(icon_texture, nullptr);
- icon_texture->set_gfx_texture_sprite(gfx_texture_sprite, icon);
+
+ for (Ref<GFXButtonStateTexture> const& button_state_texture : button_state_textures) {
+ icon_texture->connect(
+ _signal_image_updated(),
+ Callable { *button_state_texture, GFXButtonStateTexture::get_generate_state_image_func_name() },
+ CONNECT_PERSIST
+ );
+ }
+
+ ERR_FAIL_COND_V(icon_texture->set_gfx_texture_sprite(gfx_texture_sprite, icon) != OK, nullptr);
return icon_texture;
}
@@ -57,9 +78,15 @@ Error GFXIconTexture::set_gfx_texture_sprite(GFX::TextureSprite const* new_gfx_t
ERR_FAIL_NULL_V(asset_manager, FAILED);
const StringName texture_file = std_view_to_godot_string_name(new_gfx_texture_sprite->get_texture_file());
+
+ /* Needed for GFXButtonStateTexture, AssetManager::get_texture will re-use this image from its internal cache. */
+ const Ref<Image> image = asset_manager->get_image(texture_file);
+ ERR_FAIL_NULL_V_MSG(image, FAILED, vformat("Failed to load image: %s", texture_file));
+
const Ref<ImageTexture> texture = asset_manager->get_texture(texture_file);
ERR_FAIL_NULL_V_MSG(texture, FAILED, vformat("Failed to load texture: %s", texture_file));
+ sprite_image = image;
gfx_texture_sprite = new_gfx_texture_sprite;
set_atlas(texture);
icon_index = GFX::NO_FRAMES;
@@ -98,6 +125,7 @@ Error GFXIconTexture::set_icon_index(int32_t new_icon_index) {
}
icon_index = GFX::NO_FRAMES;
set_region({ {}, size });
+ emit_signal(_signal_image_updated(), sprite_image);
return OK;
}
if (GFX::NO_FRAMES < new_icon_index && new_icon_index <= icon_count) {
@@ -111,5 +139,6 @@ Error GFXIconTexture::set_icon_index(int32_t new_icon_index) {
}
}
set_region({ (icon_index - 1) * size.x / icon_count, 0, size.x / icon_count, size.y });
+ emit_signal(_signal_image_updated(), sprite_image->get_region(get_region()));
return OK;
}
diff --git a/extension/src/openvic-extension/classes/GFXIconTexture.hpp b/extension/src/openvic-extension/classes/GFXIconTexture.hpp
index 176d855..06dac34 100644
--- a/extension/src/openvic-extension/classes/GFXIconTexture.hpp
+++ b/extension/src/openvic-extension/classes/GFXIconTexture.hpp
@@ -4,6 +4,8 @@
#include <openvic-simulation/interface/GFX.hpp>
+#include "openvic-extension/classes/GFXButtonStateTexture.hpp"
+
namespace OpenVic {
class GFXIconTexture : public godot::AtlasTexture {
GDCLASS(GFXIconTexture, godot::AtlasTexture)
@@ -16,14 +18,22 @@ namespace OpenVic {
GFX::frame_t PROPERTY(icon_index);
GFX::frame_t PROPERTY(icon_count);
+ godot::Ref<godot::Image> sprite_image;
+
+ static godot::StringName const& _signal_image_updated();
+
protected:
static void _bind_methods();
public:
GFXIconTexture();
+ /* Create a GFXIconTexture using the specified GFX::TextureSprite and icon index. Returns nullptr if
+ * set_gfx_texture_sprite fails. Connects the provided GFXButtonStateTextures (if any) to the
+ * GFXIconTexture's image_updated signal. */
static godot::Ref<GFXIconTexture> make_gfx_icon_texture(
- GFX::TextureSprite const* gfx_texture_sprite, GFX::frame_t icon = GFX::NO_FRAMES
+ GFX::TextureSprite const* gfx_texture_sprite, GFX::frame_t icon = GFX::NO_FRAMES,
+ std::vector<godot::Ref<GFXButtonStateTexture>> const& button_state_textures = {}
);
/* Discard the GFX::TextureSprite, atlas texture and icon index. */
diff --git a/extension/src/openvic-extension/classes/GFXMaskedFlagTexture.cpp b/extension/src/openvic-extension/classes/GFXMaskedFlagTexture.cpp
index 424be33..0a44e56 100644
--- a/extension/src/openvic-extension/classes/GFXMaskedFlagTexture.cpp
+++ b/extension/src/openvic-extension/classes/GFXMaskedFlagTexture.cpp
@@ -13,15 +13,22 @@ using OpenVic::Utilities::godot_to_std_string;
using OpenVic::Utilities::std_view_to_godot_string;
using OpenVic::Utilities::std_view_to_godot_string_name;
+StringName const& GFXMaskedFlagTexture::_signal_image_updated() {
+ static const StringName signal_image_updated = "image_updated";
+ return signal_image_updated;
+}
+
Error GFXMaskedFlagTexture::_generate_combined_image() {
ERR_FAIL_NULL_V(overlay_image, FAILED);
- bool can_update = true;
- if (combined_image.is_null() || combined_image->get_size() != overlay_image->get_size()) {
+ /* Whether we've already set the ImageTexture to an image of the right dimensions and format,
+ * and so can update it without creating and setting a new image, or not. */
+ const bool can_update = combined_image.is_valid() && combined_image->get_size() == overlay_image->get_size()
+ && combined_image->get_format() == overlay_image->get_format();
+ if (!can_update) {
combined_image = Image::create(
overlay_image->get_width(), overlay_image->get_height(), false, overlay_image->get_format()
);
ERR_FAIL_NULL_V(combined_image, FAILED);
- can_update = false;
}
if (mask_image.is_valid() && flag_image.is_valid()) {
@@ -55,6 +62,7 @@ Error GFXMaskedFlagTexture::_generate_combined_image() {
} else {
set_image(combined_image);
}
+ emit_signal(_signal_image_updated(), combined_image);
return OK;
}
@@ -68,14 +76,29 @@ void GFXMaskedFlagTexture::_bind_methods() {
OV_BIND_METHOD(GFXMaskedFlagTexture::set_flag_country_name, { "new_flag_country_name" });
OV_BIND_METHOD(GFXMaskedFlagTexture::get_flag_country_name);
OV_BIND_METHOD(GFXMaskedFlagTexture::get_flag_type);
+
+ ADD_SIGNAL(
+ MethodInfo(_signal_image_updated(), PropertyInfo(Variant::OBJECT, "source_image", PROPERTY_HINT_RESOURCE_TYPE, "Image"))
+ );
}
GFXMaskedFlagTexture::GFXMaskedFlagTexture() : gfx_masked_flag { nullptr }, flag_country { nullptr } {}
-Ref<GFXMaskedFlagTexture> GFXMaskedFlagTexture::make_gfx_masked_flag_texture(GFX::MaskedFlag const* gfx_masked_flag) {
+Ref<GFXMaskedFlagTexture> GFXMaskedFlagTexture::make_gfx_masked_flag_texture(
+ GFX::MaskedFlag const* gfx_masked_flag, std::vector<Ref<GFXButtonStateTexture>> const& button_state_textures
+) {
Ref<GFXMaskedFlagTexture> masked_flag_texture;
masked_flag_texture.instantiate();
ERR_FAIL_NULL_V(masked_flag_texture, nullptr);
+
+ for (Ref<GFXButtonStateTexture> const& button_state_texture : button_state_textures) {
+ masked_flag_texture->connect(
+ _signal_image_updated(),
+ Callable { *button_state_texture, GFXButtonStateTexture::get_generate_state_image_func_name() },
+ CONNECT_PERSIST
+ );
+ }
+
ERR_FAIL_COND_V(masked_flag_texture->set_gfx_masked_flag(gfx_masked_flag) != OK, nullptr);
return masked_flag_texture;
}
diff --git a/extension/src/openvic-extension/classes/GFXMaskedFlagTexture.hpp b/extension/src/openvic-extension/classes/GFXMaskedFlagTexture.hpp
index f71a1d7..294b842 100644
--- a/extension/src/openvic-extension/classes/GFXMaskedFlagTexture.hpp
+++ b/extension/src/openvic-extension/classes/GFXMaskedFlagTexture.hpp
@@ -5,6 +5,8 @@
#include <openvic-simulation/country/Country.hpp>
#include <openvic-simulation/interface/GFX.hpp>
+#include "openvic-extension/classes/GFXButtonStateTexture.hpp"
+
namespace OpenVic {
class GFXMaskedFlagTexture : public godot::ImageTexture {
GDCLASS(GFXMaskedFlagTexture, godot::ImageTexture)
@@ -15,6 +17,8 @@ namespace OpenVic {
godot::Ref<godot::Image> overlay_image, mask_image, flag_image, combined_image;
+ static godot::StringName const& _signal_image_updated();
+
godot::Error _generate_combined_image();
protected:
@@ -23,9 +27,12 @@ namespace OpenVic {
public:
GFXMaskedFlagTexture();
- /* Create a GFXMaskedFlagTexture using the specific GFX::MaskedFlag.
- * Returns nullptr if setting gfx_masked_flag fails. */
- static godot::Ref<GFXMaskedFlagTexture> make_gfx_masked_flag_texture(GFX::MaskedFlag const* gfx_masked_flag);
+ /* Create a GFXMaskedFlagTexture using the specified GFX::MaskedFlag. Returns nullptr if gfx_masked_flag fails.
+ * Connects the provided GFXButtonStateTextures (if any) to the GFXMaskedFlagTexture's image_updated signal. */
+ static godot::Ref<GFXMaskedFlagTexture> make_gfx_masked_flag_texture(
+ GFX::MaskedFlag const* gfx_masked_flag,
+ std::vector<godot::Ref<GFXButtonStateTexture>> const& button_state_textures = {}
+ );
/* Reset gfx_masked_flag, flag_country and flag_type to nullptr/an empty string, and unreference all images.
* This does not affect the godot::ImageTexture, which cannot be reset to a null or empty image. */
diff --git a/extension/src/openvic-extension/classes/GFXPieChartTexture.cpp b/extension/src/openvic-extension/classes/GFXPieChartTexture.cpp
index 63deeda..c9a2a72 100644
--- a/extension/src/openvic-extension/classes/GFXPieChartTexture.cpp
+++ b/extension/src/openvic-extension/classes/GFXPieChartTexture.cpp
@@ -12,6 +12,19 @@ using OpenVic::Utilities::godot_to_std_string;
using OpenVic::Utilities::std_view_to_godot_string;
using OpenVic::Utilities::std_view_to_godot_string_name;
+StringName const& GFXPieChartTexture::_slice_identifier_key() {
+ static StringName const slice_identifier_key = "identifier";
+ return slice_identifier_key;
+}
+StringName const& GFXPieChartTexture::_slice_colour_key() {
+ static StringName const slice_colour_key = "colour";
+ return slice_colour_key;
+}
+StringName const& GFXPieChartTexture::_slice_weight_key() {
+ static StringName const slice_weight_key = "weight";
+ return slice_weight_key;
+}
+
static constexpr float PI = std::numbers::pi_v<float>;
Error GFXPieChartTexture::_generate_pie_chart_image() {
@@ -21,14 +34,13 @@ Error GFXPieChartTexture::_generate_pie_chart_image() {
vformat("Invalid GFX::PieChart size for GFXPieChartTexture - %d", gfx_pie_chart->get_size())
);
const int32_t pie_chart_size = 2 * gfx_pie_chart->get_size();
- bool can_update = true;
- if (
- pie_chart_image.is_null() || pie_chart_image->get_width() != pie_chart_size ||
- pie_chart_image->get_height() != pie_chart_size
- ) {
+ /* Whether we've already set the ImageTexture to an image of the right dimensions,
+ * and so can update it without creating and setting a new image, or not. */
+ const bool can_update = pie_chart_image.is_valid() && pie_chart_image->get_width() == pie_chart_size
+ && pie_chart_image->get_height() == pie_chart_size;
+ if (!can_update) {
pie_chart_image = Image::create(pie_chart_size, pie_chart_size, false, Image::FORMAT_RGBA8);
ERR_FAIL_NULL_V(pie_chart_image, FAILED);
- can_update = false;
}
static const Color background_colour { 0.0f, 0.0f, 0.0f, 0.0f };
@@ -74,17 +86,14 @@ Error GFXPieChartTexture::_generate_pie_chart_image() {
}
Error GFXPieChartTexture::set_slices_array(TypedArray<Dictionary> const& new_slices) {
- static const StringName colour_key = "colour";
- static const StringName weight_key = "weight";
-
slices.clear();
total_weight = 0.0f;
for (int32_t i = 0; i < new_slices.size(); ++i) {
Dictionary const& slice_dict = new_slices[i];
ERR_CONTINUE_MSG(
- !slice_dict.has(colour_key) || !slice_dict.has(weight_key), vformat("Invalid slice keys at index %d", i)
+ !slice_dict.has(_slice_colour_key()) || !slice_dict.has(_slice_weight_key()), vformat("Invalid slice keys at index %d", i)
);
- const slice_t slice = std::make_pair(slice_dict[colour_key], slice_dict[weight_key]);
+ slice_t slice = std::make_pair(slice_dict[_slice_colour_key()], slice_dict[_slice_weight_key()]);
ERR_CONTINUE_MSG(slice.second <= 0.0f, vformat("Invalid slice values at index %d", i));
total_weight += slice.second;
slices.emplace_back(std::move(slice));
diff --git a/extension/src/openvic-extension/classes/GFXPieChartTexture.hpp b/extension/src/openvic-extension/classes/GFXPieChartTexture.hpp
index ad8e751..f8279e4 100644
--- a/extension/src/openvic-extension/classes/GFXPieChartTexture.hpp
+++ b/extension/src/openvic-extension/classes/GFXPieChartTexture.hpp
@@ -17,6 +17,10 @@ namespace OpenVic {
float total_weight;
godot::Ref<godot::Image> pie_chart_image;
+ static godot::StringName const& _slice_identifier_key();
+ static godot::StringName const& _slice_colour_key();
+ static godot::StringName const& _slice_weight_key();
+
godot::Error _generate_pie_chart_image();
protected:
@@ -34,34 +38,31 @@ namespace OpenVic {
* The resulting Array of Dictionaries can be used as an argument for set_slices_array. */
template<std::derived_from<HasIdentifierAndColour> T>
static godot::TypedArray<godot::Dictionary> distribution_to_slices_array(fixed_point_map_t<T const*> const& dist) {
+ using namespace godot;
using entry_t = std::pair<T const*, fixed_point_t>;
std::vector<entry_t> sorted_dist;
sorted_dist.reserve(dist.size());
for (entry_t const& entry : dist) {
ERR_CONTINUE_MSG(
- entry.first == nullptr, godot::vformat("Null distribution key with value %f", entry.second.to_float())
+ entry.first == nullptr, vformat("Null distribution key with value %f", entry.second.to_float())
);
sorted_dist.push_back(entry);
}
std::sort(sorted_dist.begin(), sorted_dist.end(), [](entry_t const& lhs, entry_t const& rhs) -> bool {
return lhs.second < rhs.second;
});
- static const godot::StringName identifier_key = "identifier";
- static const godot::StringName colour_key = "colour";
- static const godot::StringName weight_key = "weight";
- godot::TypedArray<godot::Dictionary> array;
+ TypedArray<Dictionary> array;
for (auto const& [key, val] : sorted_dist) {
- godot::Dictionary sub_dict;
- sub_dict[identifier_key] = Utilities::std_view_to_godot_string(key->get_identifier());
- sub_dict[colour_key] = Utilities::to_godot_color(key->get_colour());
- sub_dict[weight_key] = val.to_float();
+ Dictionary sub_dict;
+ sub_dict[_slice_identifier_key()] = Utilities::std_view_to_godot_string(key->get_identifier());
+ sub_dict[_slice_colour_key()] = Utilities::to_godot_color(key->get_colour());
+ sub_dict[_slice_weight_key()] = val.to_float();
array.push_back(sub_dict);
}
return array;
}
- /* Create a GFXPieChartTexture using the specific GFX::PieChart.
- * Returns nullptr if setting gfx_pie_chart fails. */
+ /* Create a GFXPieChartTexture using the specified GFX::PieChart. Returns nullptr if gfx_pie_chart fails. */
static godot::Ref<GFXPieChartTexture> make_gfx_pie_chart_texture(GFX::PieChart const* gfx_pie_chart);
/* Reset gfx_pie_chart, flag_country and flag_type to nullptr/an empty string, and unreference all images.
diff --git a/extension/src/openvic-extension/classes/GUINode.cpp b/extension/src/openvic-extension/classes/GUINode.cpp
index 043f65d..89701e0 100644
--- a/extension/src/openvic-extension/classes/GUINode.cpp
+++ b/extension/src/openvic-extension/classes/GUINode.cpp
@@ -49,6 +49,9 @@ void GUINode::_bind_methods() {
}
GUINode::GUINode() {
+ set_anchors_and_offsets_preset(PRESET_FULL_RECT);
+ set_h_grow_direction(GROW_DIRECTION_BOTH);
+ set_v_grow_direction(GROW_DIRECTION_BOTH);
set_mouse_filter(MOUSE_FILTER_IGNORE);
}
diff --git a/extension/src/openvic-extension/classes/GUIOverlappingElementsBox.cpp b/extension/src/openvic-extension/classes/GUIOverlappingElementsBox.cpp
index ff88781..921f633 100644
--- a/extension/src/openvic-extension/classes/GUIOverlappingElementsBox.cpp
+++ b/extension/src/openvic-extension/classes/GUIOverlappingElementsBox.cpp
@@ -120,6 +120,15 @@ Error GUIOverlappingElementsBox::set_child_count(int32_t new_count) {
name, child_count, new_count
)
);
+
+ static const StringName set_z_index_func_name = "set_z_index";
+ static const StringName mouse_entered_signal_name = "mouse_entered";
+ static const StringName mouse_exited_signal_name = "mouse_exited";
+
+ /* Move the child element in front of its neighbours when moused-over. */
+ child->connect(mouse_entered_signal_name, Callable { child, set_z_index_func_name }.bind(1), CONNECT_PERSIST);
+ child->connect(mouse_exited_signal_name, Callable { child, set_z_index_func_name }.bind(0), CONNECT_PERSIST);
+
add_child(child);
child_count++;
} while (child_count < new_count);