aboutsummaryrefslogtreecommitdiff
path: root/extension/src/openvic-extension/classes/GUIHasTooltip.hpp
diff options
context:
space:
mode:
author hop311 <hop3114@gmail.com>2024-08-29 00:16:24 +0200
committer hop311 <hop3114@gmail.com>2024-08-29 23:04:30 +0200
commitbdc2ba527bc02e7cdf977f6040f2ca85aa4f9a94 (patch)
tree4627ad955ac60f5c66b94dfc3106bd8442b58302 /extension/src/openvic-extension/classes/GUIHasTooltip.hpp
parent88acb31bd43f0e163522837bb1d0dd7da2977c4a (diff)
Add tooltips for buttons, labels, icons, pie charts, sliders, and progress barstooltip
Diffstat (limited to 'extension/src/openvic-extension/classes/GUIHasTooltip.hpp')
-rw-r--r--extension/src/openvic-extension/classes/GUIHasTooltip.hpp121
1 files changed, 121 insertions, 0 deletions
diff --git a/extension/src/openvic-extension/classes/GUIHasTooltip.hpp b/extension/src/openvic-extension/classes/GUIHasTooltip.hpp
new file mode 100644
index 0000000..22413ec
--- /dev/null
+++ b/extension/src/openvic-extension/classes/GUIHasTooltip.hpp
@@ -0,0 +1,121 @@
+#pragma once
+
+#include <godot_cpp/classes/control.hpp>
+#include <godot_cpp/variant/string.hpp>
+#include <godot_cpp/variant/utility_functions.hpp>
+#include <godot_cpp/variant/vector2.hpp>
+
+#include <openvic-simulation/utility/Getters.hpp>
+
+#include "openvic-extension/singletons/MenuSingleton.hpp"
+#include "openvic-extension/utility/ClassBindings.hpp"
+#include "openvic-extension/utility/Utilities.hpp"
+
+/* To add tooltip functionality to a class:
+ * - the class must be derived from Control.
+ * - add GUI_TOOLTIP_DEFINITIONS to the class definition, bearing in mind that it leaves visibility as private.
+ * - add GUI_TOOLTIP_IMPLEMENTATIONS(CLASS) to the class' source file.
+ * - add GUI_TOOLTIP_BIND_METHODS(CLASS) to the class' _bind_methods implementation.
+ * - call _tooltip_notification from the class' _notification method.
+ * - initialise tooltip_active to false in the class' constructor. */
+
+#define GUI_TOOLTIP_DEFINITIONS \
+ public: \
+ void set_tooltip_string_and_substitution_dict( \
+ godot::String const& new_tooltip_string, godot::Dictionary const& new_tooltip_substitution_dict \
+ ); \
+ void set_tooltip_string(godot::String const& new_tooltip_string); \
+ void set_tooltip_substitution_dict(godot::Dictionary const& new_tooltip_substitution_dict); \
+ void clear_tooltip(); \
+ private: \
+ godot::String PROPERTY(tooltip_string); \
+ godot::Dictionary PROPERTY(tooltip_substitution_dict); \
+ bool PROPERTY_CUSTOM_PREFIX(tooltip_active, is); \
+ void _tooltip_notification(int what); \
+ void _set_tooltip_active(bool new_tooltip_active); \
+ void _set_tooltip_visibility(bool visible);
+
+#define GUI_TOOLTIP_IMPLEMENTATIONS(CLASS) \
+ void CLASS::set_tooltip_string_and_substitution_dict( \
+ String const& new_tooltip_string, Dictionary const& new_tooltip_substitution_dict \
+ ) { \
+ if (get_mouse_filter() == MOUSE_FILTER_IGNORE) { \
+ UtilityFunctions::push_error("Tooltips won't work for \"", get_name(), "\" as it has MOUSE_FILTER_IGNORE"); \
+ } \
+ if (tooltip_string != new_tooltip_string || tooltip_substitution_dict != new_tooltip_substitution_dict) { \
+ tooltip_string = new_tooltip_string; \
+ tooltip_substitution_dict = new_tooltip_substitution_dict; \
+ if (tooltip_active) { \
+ _set_tooltip_visibility(!tooltip_string.is_empty()); \
+ } \
+ } \
+ } \
+ void CLASS::set_tooltip_string(String const& new_tooltip_string) { \
+ if (get_mouse_filter() == MOUSE_FILTER_IGNORE) { \
+ UtilityFunctions::push_error("Tooltips won't work for \"", get_name(), "\" as it has MOUSE_FILTER_IGNORE"); \
+ } \
+ if (tooltip_string != new_tooltip_string) { \
+ tooltip_string = new_tooltip_string; \
+ if (tooltip_active) { \
+ _set_tooltip_visibility(!tooltip_string.is_empty()); \
+ } \
+ } \
+ } \
+ void CLASS::set_tooltip_substitution_dict(Dictionary const& new_tooltip_substitution_dict) { \
+ if (get_mouse_filter() == MOUSE_FILTER_IGNORE) { \
+ UtilityFunctions::push_error("Tooltips won't work for \"", get_name(), "\" as it has MOUSE_FILTER_IGNORE"); \
+ } \
+ if (tooltip_substitution_dict != new_tooltip_substitution_dict) { \
+ tooltip_substitution_dict = new_tooltip_substitution_dict; \
+ if (tooltip_active) { \
+ _set_tooltip_visibility(!tooltip_string.is_empty()); \
+ } \
+ } \
+ } \
+ void CLASS::clear_tooltip() { \
+ set_tooltip_string_and_substitution_dict({}, {}); \
+ } \
+ void CLASS::_tooltip_notification(int what) { \
+ if (what == NOTIFICATION_MOUSE_ENTER_SELF) { \
+ _set_tooltip_active(true); \
+ } else if (what == NOTIFICATION_MOUSE_EXIT_SELF) { \
+ _set_tooltip_active(false); \
+ } \
+ } \
+ void CLASS::_set_tooltip_active(bool new_tooltip_active) { \
+ if (tooltip_active != new_tooltip_active) { \
+ tooltip_active = new_tooltip_active; \
+ if (!tooltip_string.is_empty()) { \
+ _set_tooltip_visibility(tooltip_active); \
+ } \
+ } \
+ } \
+ void CLASS::_set_tooltip_visibility(bool visible) { \
+ MenuSingleton* menu_singleton = MenuSingleton::get_singleton(); \
+ ERR_FAIL_NULL(menu_singleton); \
+ if (visible) { \
+ menu_singleton->show_control_tooltip(tooltip_string, tooltip_substitution_dict, this); \
+ } else { \
+ menu_singleton->hide_tooltip(); \
+ } \
+ }
+
+#define GUI_TOOLTIP_BIND_METHODS(CLASS) \
+ OV_BIND_METHOD(CLASS::get_tooltip_string); \
+ OV_BIND_METHOD(CLASS::set_tooltip_string, { "new_tooltip_string" }); \
+ OV_BIND_METHOD(CLASS::get_tooltip_substitution_dict); \
+ OV_BIND_METHOD(CLASS::set_tooltip_substitution_dict, { "new_tooltip_substitution_dict" }); \
+ OV_BIND_METHOD( \
+ CLASS::set_tooltip_string_and_substitution_dict, { "new_tooltip_string", "new_tooltip_substitution_dict" } \
+ ); \
+ OV_BIND_METHOD(CLASS::clear_tooltip); \
+ OV_BIND_METHOD(CLASS::is_tooltip_active); \
+ ADD_PROPERTY( \
+ PropertyInfo(Variant::STRING, "tooltip_string", PROPERTY_HINT_MULTILINE_TEXT), \
+ "set_tooltip_string", "get_tooltip_string" \
+ ); \
+ ADD_PROPERTY( \
+ PropertyInfo(Variant::DICTIONARY, "tooltip_substitution_dict"), \
+ "set_tooltip_substitution_dict", "get_tooltip_substitution_dict" \
+ ); \
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "tooltip_active"), "", "is_tooltip_active");