Skip to content

Commit

Permalink
Big UI commit - GUINode, MaskedFlag, PieChart, etc
Browse files Browse the repository at this point in the history
  • Loading branch information
Hop311 committed Dec 7, 2023
1 parent a6952ef commit 89c3e1b
Show file tree
Hide file tree
Showing 23 changed files with 1,240 additions and 318 deletions.
2 changes: 1 addition & 1 deletion extension/deps/openvic-simulation
Submodule openvic-simulation updated 42 files
+2 −1 src/openvic-simulation/GameManager.cpp
+7 −4 src/openvic-simulation/GameManager.hpp
+57 −326 src/openvic-simulation/dataloader/Dataloader.cpp
+2 −11 src/openvic-simulation/dataloader/Dataloader.hpp
+1 −11 src/openvic-simulation/dataloader/NodeTools.cpp
+30 −0 src/openvic-simulation/dataloader/NodeTools.hpp
+342 −0 src/openvic-simulation/dataloader/Vic2PathSearch.cpp
+0 −0 src/openvic-simulation/dataloader/Vic2PathSearch_Windows.hpp
+4 −9 src/openvic-simulation/economy/BuildingType.cpp
+4 −4 src/openvic-simulation/economy/BuildingType.hpp
+2 −2 src/openvic-simulation/economy/EconomyManager.hpp
+8 −5 src/openvic-simulation/economy/Good.cpp
+3 −8 src/openvic-simulation/economy/ProductionType.cpp
+3 −4 src/openvic-simulation/history/Bookmark.cpp
+1 −4 src/openvic-simulation/history/CountryHistory.cpp
+14 −14 src/openvic-simulation/history/DiplomaticHistory.cpp
+2 −2 src/openvic-simulation/history/DiplomaticHistory.hpp
+7 −15 src/openvic-simulation/history/ProvinceHistory.cpp
+40 −0 src/openvic-simulation/map/Crime.cpp
+32 −0 src/openvic-simulation/map/Crime.hpp
+6 −10 src/openvic-simulation/map/Map.cpp
+5 −2 src/openvic-simulation/map/Map.hpp
+13 −13 src/openvic-simulation/map/Province.cpp
+8 −9 src/openvic-simulation/map/Province.hpp
+83 −0 src/openvic-simulation/map/State.cpp
+54 −0 src/openvic-simulation/map/State.hpp
+1 −1 src/openvic-simulation/map/TerrainType.cpp
+4 −3 src/openvic-simulation/military/Unit.cpp
+0 −1 src/openvic-simulation/misc/Define.cpp
+42 −53 src/openvic-simulation/misc/Modifier.cpp
+1 −20 src/openvic-simulation/misc/Modifier.hpp
+1 −1 src/openvic-simulation/politics/Government.cpp
+1 −1 src/openvic-simulation/politics/NationalFocus.hpp
+6 −3 src/openvic-simulation/politics/PoliticsManager.hpp
+14 −0 src/openvic-simulation/politics/Rebel.cpp
+3 −3 src/openvic-simulation/politics/Rebel.hpp
+1 −3 src/openvic-simulation/pop/Culture.cpp
+83 −0 src/openvic-simulation/research/Invention.cpp
+59 −0 src/openvic-simulation/research/Invention.hpp
+12 −0 src/openvic-simulation/research/ResearchManager.hpp
+21 −21 src/openvic-simulation/research/Technology.cpp
+6 −7 src/openvic-simulation/research/Technology.hpp
169 changes: 92 additions & 77 deletions extension/src/openvic-extension/UIAdapter.cpp

Large diffs are not rendered by default.

27 changes: 18 additions & 9 deletions extension/src/openvic-extension/UIAdapter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,22 @@
#include "openvic-extension/singletons/AssetManager.hpp"

namespace OpenVic::GodotGUIBuilder {
bool generate_element(GUI::Element const* element, AssetManager& asset_manager, godot::Control*& result);

bool generate_icon(GUI::Element const& element, AssetManager& asset_manager, godot::Control*& result);
bool generate_button(GUI::Element const& element, AssetManager& asset_manager, godot::Control*& result);
bool generate_checkbox(GUI::Element const& element, AssetManager& asset_manager, godot::Control*& result);
bool generate_text(GUI::Element const& element, AssetManager& asset_manager, godot::Control*& result);
bool generate_overlapping_elements(GUI::Element const& element, AssetManager& asset_manager, godot::Control*& result);
bool generate_listbox(GUI::Element const& element, AssetManager& asset_manager, godot::Control*& result);
bool generate_window(GUI::Element const& element, AssetManager& asset_manager, godot::Control*& result);

bool generate_element(
GUI::Element const* element, godot::String const& name, AssetManager& asset_manager, godot::Control*& result
);

#define GEN_GUI_ARGS \
GUI::Element const& element, godot::String const& name, AssetManager& asset_manager, godot::Control*& result

bool generate_icon(GEN_GUI_ARGS);
bool generate_button(GEN_GUI_ARGS);
bool generate_checkbox(GEN_GUI_ARGS);
bool generate_text(GEN_GUI_ARGS);
bool generate_overlapping_elements(GEN_GUI_ARGS);
bool generate_listbox(GEN_GUI_ARGS);
bool generate_window(GEN_GUI_ARGS);

#undef GEN_GUI_ARGS

}
183 changes: 183 additions & 0 deletions extension/src/openvic-extension/classes/GFXMaskedFlagTexture.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
#include "GFXMaskedFlagTexture.hpp"

#include <godot_cpp/variant/utility_functions.hpp>

#include "openvic-extension/singletons/AssetManager.hpp"
#include "openvic-extension/singletons/GameSingleton.hpp"
#include "openvic-extension/utility/ClassBindings.hpp"
#include "openvic-extension/utility/Utilities.hpp"

using namespace godot;
using namespace OpenVic;

using OpenVic::Utilities::godot_to_std_string;
using OpenVic::Utilities::std_view_to_godot_string;
using OpenVic::Utilities::std_view_to_godot_string_name;

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()) {
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()) {
const Vector2i centre_translation = (mask_image->get_size() - combined_image->get_size()) / 2;
for (Vector2i combined_image_point { 0, 0 }; combined_image_point.y < combined_image->get_height(); ++combined_image_point.y) {
for (combined_image_point.x = 0; combined_image_point.x < combined_image->get_width(); ++combined_image_point.x) {
const Color overlay_image_colour = overlay_image->get_pixelv(combined_image_point);
// Translate to mask_image coordinates, keeping the centres of each image aligned.
const Vector2i mask_image_point = combined_image_point + centre_translation;
if (
0 <= mask_image_point.x && mask_image_point.x < mask_image->get_width() &&
0 <= mask_image_point.y && mask_image_point.y < mask_image->get_height()
) {
const Color mask_image_colour = mask_image->get_pixelv(mask_image_point);
// Rescale from mask_image to flag_image coordinates.
const Vector2i flag_image_point = mask_image_point * flag_image->get_size() / mask_image->get_size();
Color flag_image_colour = flag_image->get_pixelv(flag_image_point);
flag_image_colour.a = mask_image_colour.a;
combined_image->set_pixelv(combined_image_point, flag_image_colour.blend(overlay_image_colour));
} else {
combined_image->set_pixelv(combined_image_point, overlay_image_colour);
}
}
}
} else {
combined_image->blit_rect(overlay_image, overlay_image->get_used_rect(), {});
}

if (can_update) {
update(combined_image);
} else {
set_image(combined_image);
}
return OK;
}

void GFXMaskedFlagTexture::_bind_methods() {
OV_BIND_METHOD(GFXMaskedFlagTexture::clear);

OV_BIND_METHOD(GFXMaskedFlagTexture::set_gfx_masked_flag_name, { "gfx_masked_flag_name" });
OV_BIND_METHOD(GFXMaskedFlagTexture::get_gfx_masked_flag_name);

OV_BIND_METHOD(GFXMaskedFlagTexture::set_flag_country_name_and_type, { "new_flag_country_name", "new_flag_type" });
OV_BIND_METHOD(GFXMaskedFlagTexture::get_flag_country_name);
OV_BIND_METHOD(GFXMaskedFlagTexture::get_flag_type);
}

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> masked_flag_texture;
masked_flag_texture.instantiate();
ERR_FAIL_NULL_V(masked_flag_texture, nullptr);
if (masked_flag_texture->set_gfx_masked_flag(gfx_masked_flag) == OK) {
return masked_flag_texture;
} else {
return nullptr;
}
}

void GFXMaskedFlagTexture::clear() {
gfx_masked_flag = nullptr;
flag_country = nullptr;
flag_type = String {};

overlay_image.unref();
mask_image.unref();
flag_image.unref();
}

Error GFXMaskedFlagTexture::set_gfx_masked_flag(GFX::MaskedFlag const* new_gfx_masked_flag) {
if (gfx_masked_flag == new_gfx_masked_flag) {
return OK;
}
if (new_gfx_masked_flag == nullptr) {
clear();
return OK;
}
AssetManager* asset_manager = AssetManager::get_singleton();
ERR_FAIL_NULL_V(asset_manager, FAILED);

const StringName overlay_file = std_view_to_godot_string_name(new_gfx_masked_flag->get_overlay_file());
const Ref<Image> new_overlay_image = asset_manager->get_image(overlay_file);
ERR_FAIL_NULL_V_MSG(new_overlay_image, FAILED, vformat("Failed to load flag overlay image: %s", overlay_file));

const StringName mask_file = std_view_to_godot_string_name(new_gfx_masked_flag->get_mask_file());
const Ref<Image> new_mask_image = asset_manager->get_image(mask_file);
ERR_FAIL_NULL_V_MSG(new_mask_image, FAILED, vformat("Failed to load flag mask image: %s", mask_file));

gfx_masked_flag = new_gfx_masked_flag;
overlay_image = new_overlay_image;
mask_image = new_mask_image;

return _generate_combined_image();
}

Error GFXMaskedFlagTexture::set_gfx_masked_flag_name(String const& gfx_masked_flag_name) {
if (gfx_masked_flag_name.is_empty()) {
return set_gfx_masked_flag(nullptr);
}
GameSingleton* game_singleton = GameSingleton::get_singleton();
ERR_FAIL_NULL_V(game_singleton, FAILED);
GFX::Sprite const* sprite = game_singleton->get_game_manager().get_ui_manager().get_sprite_by_identifier(
godot_to_std_string(gfx_masked_flag_name)
);
ERR_FAIL_NULL_V_MSG(sprite, FAILED, vformat("GFX sprite not found: %s", gfx_masked_flag_name));
GFX::MaskedFlag const* new_masked_flag = sprite->cast_to<GFX::MaskedFlag>();
ERR_FAIL_NULL_V_MSG(
new_masked_flag, FAILED, vformat(
"Invalid type for GFX sprite %s: %s (expected %s)", gfx_masked_flag_name,
std_view_to_godot_string(sprite->get_type()), std_view_to_godot_string(GFX::MaskedFlag::get_type_static())
)
);
return set_gfx_masked_flag(new_masked_flag);
}

String GFXMaskedFlagTexture::get_gfx_masked_flag_name() const {
return gfx_masked_flag != nullptr ? std_view_to_godot_string(gfx_masked_flag->get_name()) : String {};
}

Error GFXMaskedFlagTexture::set_flag_country_and_type(Country const* new_flag_country, StringName const& new_flag_type) {
if (flag_country == new_flag_country && flag_type == new_flag_type) {
return OK;
}
if (new_flag_country != nullptr) {
GameSingleton* game_singleton = GameSingleton::get_singleton();
ERR_FAIL_NULL_V(game_singleton, FAILED);

const Ref<Image> new_flag_image = game_singleton->get_flag_image(new_flag_country, new_flag_type);
ERR_FAIL_NULL_V(new_flag_image, FAILED);

flag_country = new_flag_country;
flag_type = new_flag_type;
flag_image = new_flag_image;
} else {
flag_country = nullptr;
flag_type = String {};
flag_image.unref();
}
return _generate_combined_image();
}

Error GFXMaskedFlagTexture::set_flag_country_name_and_type(String const& new_flag_country_name, StringName const& new_flag_type) {
if (new_flag_country_name.is_empty()) {
return set_flag_country_and_type(nullptr, {});
}
GameSingleton* game_singleton = GameSingleton::get_singleton();
ERR_FAIL_NULL_V(game_singleton, FAILED);
Country const* new_flag_country = game_singleton->get_game_manager().get_country_manager().get_country_by_identifier(
godot_to_std_string(new_flag_country_name)
);
ERR_FAIL_NULL_V_MSG(new_flag_country, FAILED, vformat("Country not found: %s", new_flag_country_name));
return set_flag_country_and_type(new_flag_country, new_flag_type);
}

String GFXMaskedFlagTexture::get_flag_country_name() const {
return flag_country != nullptr ? std_view_to_godot_string(flag_country->get_identifier()) : String {};
}
55 changes: 55 additions & 0 deletions extension/src/openvic-extension/classes/GFXMaskedFlagTexture.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#pragma once

#include <godot_cpp/classes/image_texture.hpp>

#include <openvic-simulation/country/Country.hpp>
#include <openvic-simulation/interface/GFX.hpp>

namespace OpenVic {
class GFXMaskedFlagTexture : public godot::ImageTexture {
GDCLASS(GFXMaskedFlagTexture, godot::ImageTexture)

GFX::MaskedFlag const* PROPERTY(gfx_masked_flag);
Country const* PROPERTY(flag_country);
godot::StringName PROPERTY(flag_type);

godot::Ref<godot::Image> overlay_image, mask_image, flag_image, combined_image;

godot::Error _generate_combined_image();

protected:
static void _bind_methods();

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);

/* 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. */
void clear();

/* Set the GFX::MaskedFlag, load its overlay and mask textures, and regenerate the combined image. */
godot::Error set_gfx_masked_flag(GFX::MaskedFlag const* new_gfx_masked_flag);

/* Search for a GFX::MaskedFlag with the specfied name and, if successful, set it using set_gfx_masked_flag. */
godot::Error set_gfx_masked_flag_name(godot::String const& gfx_masked_flag_name);

/* Return the name of the GFX::MaskedFlag, or an empty String if it's null */
godot::String get_gfx_masked_flag_name() const;

/* Set flag_country and flag_type and update the combined image to use that flag, or no flag if it doesn't exist. */
godot::Error set_flag_country_and_type(Country const* new_flag_country, godot::StringName const& new_flag_type);

/* Look up the country with the specified identifier, then call set_flag_country_and_type with the country and
* specified flag_type as arguments. */
godot::Error set_flag_country_name_and_type(
godot::String const& new_flag_country_name, godot::StringName const& new_flag_type
);

/* Return the name of the selected flag's country, or an empty String if it's null */
godot::String get_flag_country_name() const;
};
}
Loading

0 comments on commit 89c3e1b

Please sign in to comment.