diff options
author | George L. Albany <Megacake1234@gmail.com> | 2024-05-07 01:15:50 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-05-07 01:15:50 +0200 |
commit | c29cc0dabe3e3c7d03280e74d2d10fc3cc479c7f (patch) | |
tree | 059fe3b320d6ed41416aee3853c5eb8e8ca36583 | |
parent | 8c8ee1524f51d44acd1d1894eda5984956cba9a6 (diff) | |
parent | 7def4dd2e7987c20163c6a419bcc0506b5a670d9 (diff) |
Merge pull request #226 from Spartan322/click-mask-guinodes
Improve map view and game panel user experience
-rw-r--r-- | extension/src/openvic-extension/classes/GUINode.cpp | 159 | ||||
-rw-r--r-- | extension/src/openvic-extension/classes/GUINode.hpp | 30 | ||||
-rw-r--r-- | game/src/Game/GameSession/GameSession.tscn | 70 | ||||
-rw-r--r-- | game/src/Game/GameSession/GameSessionMenu.tscn | 1 | ||||
-rw-r--r-- | game/src/Game/GameSession/MapControlPanel/MapControlPanel.tscn | 2 | ||||
-rw-r--r-- | game/src/Game/GameSession/MapView.gd | 85 | ||||
-rw-r--r-- | game/src/Game/GameSession/ProvinceOverviewPanel.gd | 6 | ||||
-rw-r--r-- | game/src/Game/GameSession/Topbar.gd | 6 | ||||
-rw-r--r-- | game/src/Game/Menu/SaveLoadMenu/SaveLoadMenu.tscn | 1 | ||||
-rw-r--r-- | game/src/Game/MusicConductor/MusicPlayer.tscn | 1 |
10 files changed, 282 insertions, 79 deletions
diff --git a/extension/src/openvic-extension/classes/GUINode.cpp b/extension/src/openvic-extension/classes/GUINode.cpp index 73ebb0c..c9af7e2 100644 --- a/extension/src/openvic-extension/classes/GUINode.cpp +++ b/extension/src/openvic-extension/classes/GUINode.cpp @@ -1,7 +1,35 @@ #include "GUINode.hpp" +#include <limits> + +#include <godot_cpp/classes/bit_map.hpp> +#include <godot_cpp/classes/button.hpp> +#include <godot_cpp/classes/canvas_item.hpp> +#include <godot_cpp/classes/check_box.hpp> +#include <godot_cpp/classes/control.hpp> +#include <godot_cpp/classes/image.hpp> +#include <godot_cpp/classes/label.hpp> +#include <godot_cpp/classes/node.hpp> +#include <godot_cpp/classes/object.hpp> +#include <godot_cpp/classes/panel.hpp> +#include <godot_cpp/classes/ref.hpp> +#include <godot_cpp/classes/style_box.hpp> #include <godot_cpp/classes/style_box_texture.hpp> +#include <godot_cpp/classes/texture2d.hpp> +#include <godot_cpp/classes/texture_progress_bar.hpp> +#include <godot_cpp/classes/texture_rect.hpp> +#include <godot_cpp/core/defs.hpp> +#include <godot_cpp/core/error_macros.hpp> +#include <godot_cpp/core/object.hpp> +#include <godot_cpp/core/property_info.hpp> +#include <godot_cpp/variant/node_path.hpp> +#include <godot_cpp/variant/rect2.hpp> +#include <godot_cpp/variant/string.hpp> +#include <godot_cpp/variant/string_name.hpp> #include <godot_cpp/variant/utility_functions.hpp> +#include <godot_cpp/variant/variant.hpp> +#include <godot_cpp/variant/vector2.hpp> +#include <godot_cpp/variant/vector2i.hpp> #include "openvic-extension/utility/ClassBindings.hpp" #include "openvic-extension/utility/UITools.hpp" @@ -31,6 +59,15 @@ void GUINode::_bind_methods() { OV_BIND_METHOD(GUINode::add_gui_element, { "gui_scene", "gui_element", "name" }, DEFVAL(String {})); OV_BIND_SMETHOD(get_gui_position, { "gui_scene", "gui_position" }); + OV_BIND_METHOD(GUINode::get_click_mask); + OV_BIND_METHOD(GUINode::set_click_mask, { "mask" }); + ADD_PROPERTY( + PropertyInfo(Variant::OBJECT, "click_mask", PROPERTY_HINT_RESOURCE_TYPE, "BitMap"), "set_click_mask", "get_click_mask" + ); + + OV_BIND_METHOD(GUINode::set_click_mask_from_nodepaths, { "paths" }); + OV_BIND_METHOD(GUINode::update_click_mask); + #define GET_BINDINGS(type, name) \ OV_BIND_SMETHOD(get_##name##_from_node, { "node" }); \ OV_BIND_METHOD(GUINode::get_##name##_from_nodepath, { "path" }); @@ -56,7 +93,7 @@ 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); + set_mouse_filter(MOUSE_FILTER_STOP); } Control* GUINode::generate_gui_element(String const& gui_scene, String const& gui_element, String const& name) { @@ -196,3 +233,123 @@ String GUINode::format_province_name(String const& province_identifier) { static const String province_prefix = "PROV"; return province_prefix + province_identifier; } + +Ref<BitMap> GUINode::get_click_mask() const { + return _click_mask; +} + +void GUINode::set_click_mask(Ref<BitMap> const& mask) { + if (_click_mask == mask) { + return; + } + _click_mask = mask; + queue_redraw(); + update_minimum_size(); +} + +bool GUINode::_update_click_mask_for(Ref<Image> const& img, int index) { + ERR_FAIL_INDEX_V(index, _mask_controls.size(), false); + Control* control = _mask_controls[index]; + if (!UtilityFunctions::is_instance_valid(control) && !control->is_inside_tree()) { + _mask_controls.remove_at(index); + return false; + } + ERR_FAIL_COND_V(img.is_null(), false); + Ref<Texture2D> texture = get_texture_from_node(control); + ERR_FAIL_COND_V(texture.is_null(), false); + Ref<Image> texture_img = texture->get_image(); + if (img->is_empty()) { + img->copy_from(texture_img); + } else { + if (img->get_format() != texture_img->get_format()) { + img->convert(texture_img->get_format()); + } + Vector2i img_size = img->get_size(); + Vector2i total_size = control->get_screen_position() + texture_img->get_size(); + Vector2i new_img_size = img_size.max(total_size); + if (new_img_size != img_size) { + img->crop(new_img_size.x, new_img_size.y); + } + img->blend_rect(texture_img, texture_img->get_used_rect(), control->get_position()); + } + ERR_FAIL_COND_V(img->is_empty(), false); + return true; +} + +void GUINode::update_click_mask() { + static constexpr real_t max_real = std::numeric_limits<real_t>::max(); + static const Point2 max_point { max_real, max_real }; + if (_mask_controls.size() == 0) { + return; + } + + if (_click_mask.is_null()) { + _click_mask.instantiate(); + } + Ref<Image> img; + img.instantiate(); + Vector2 size = get_size(); + img->create(size.x, size.y, false, Image::Format::FORMAT_RGBA8); + Point2 highest_position = { max_real, max_real }; + for (int index = 0; index < _mask_controls.size(); index++) { + if (!_update_click_mask_for(img, index)) { + continue; + } + Vector2 screen_pos = _mask_controls[index]->get_screen_position(); + highest_position = highest_position.min(screen_pos); + } + ERR_FAIL_COND(img.is_null()); + ERR_FAIL_COND(highest_position == max_point); + _texture_region = Rect2(Point2(), img->get_size()); + _position_rect = Rect2(highest_position, _texture_region.get_size()); + _click_mask->create_from_image_alpha(img); + queue_redraw(); + update_minimum_size(); +} + +void GUINode::set_click_mask_from_nodepaths(TypedArray<NodePath> const& paths) { + // TODO: Update to use https://github.com/godotengine/godot/pull/90916 + // for(godot::Control* control : _mask_controls) { + // control->set_mouse_filter(Control::MouseFilter::MOUSE_FILTER_STOP); + // } + _mask_controls.clear(); + for (int index = 0; index < paths.size(); index++) { + Control* control = _cast_node<Control>(get_node_internal(paths[index])); + ERR_CONTINUE(control == nullptr); + control->set_mouse_filter(Control::MouseFilter::MOUSE_FILTER_IGNORE); + _mask_controls.push_back(control); + } + update_click_mask(); +} + +bool GUINode::_has_point(godot::Vector2 const& p_point) const { + if (!_click_mask.is_valid()) { + return Control::_has_point(p_point); + } + + Point2 point = p_point; + Rect2 rect; + Size2 mask_size = _click_mask->get_size(); + + if (!_position_rect.has_area()) { + rect.size = mask_size; + } else { + // we need to transform the point from our scaled / translated image back to our mask image + Point2 ofs = _position_rect.position; + Size2 scale = mask_size / _position_rect.size; + + // offset and scale the new point position to adjust it to the bitmask size + point -= ofs; + point *= scale; + + // finally, we need to check if the point is inside a rectangle with a position >= 0,0 and a size <= mask_size + rect.position = _texture_region.position.min(Point2 {}); + rect.size = mask_size.min(_texture_region.size); + } + + if (!rect.has_point(point)) { + return false; + } + + return _click_mask->get_bitv(point); +} diff --git a/extension/src/openvic-extension/classes/GUINode.hpp b/extension/src/openvic-extension/classes/GUINode.hpp index 3dbe403..8d926cc 100644 --- a/extension/src/openvic-extension/classes/GUINode.hpp +++ b/extension/src/openvic-extension/classes/GUINode.hpp @@ -1,17 +1,27 @@ #pragma once +#include <godot_cpp/classes/bit_map.hpp> #include <godot_cpp/classes/button.hpp> #include <godot_cpp/classes/check_box.hpp> +#include <godot_cpp/classes/control.hpp> +#include <godot_cpp/classes/image.hpp> +#include <godot_cpp/classes/input_event.hpp> #include <godot_cpp/classes/label.hpp> +#include <godot_cpp/classes/node.hpp> #include <godot_cpp/classes/panel.hpp> +#include <godot_cpp/classes/ref.hpp> +#include <godot_cpp/classes/texture2d.hpp> #include <godot_cpp/classes/texture_progress_bar.hpp> #include <godot_cpp/classes/texture_rect.hpp> +#include <godot_cpp/templates/vector.hpp> +#include <godot_cpp/variant/node_path.hpp> +#include <godot_cpp/variant/rect2.hpp> +#include <godot_cpp/variant/string.hpp> +#include <godot_cpp/variant/vector2.hpp> -#include <openvic-simulation/interface/GUI.hpp> - -#include "openvic-extension/classes/GFXSpriteTexture.hpp" #include "openvic-extension/classes/GFXMaskedFlagTexture.hpp" #include "openvic-extension/classes/GFXPieChartTexture.hpp" +#include "openvic-extension/classes/GFXSpriteTexture.hpp" #include "openvic-extension/classes/GUIListBox.hpp" #include "openvic-extension/classes/GUIOverlappingElementsBox.hpp" #include "openvic-extension/classes/GUIScrollbar.hpp" @@ -20,6 +30,11 @@ namespace OpenVic { class GUINode : public godot::Control { GDCLASS(GUINode, godot::Control) + godot::Ref<godot::BitMap> _click_mask; + godot::Vector<Control*> _mask_controls; + godot::Rect2 _texture_region; + godot::Rect2 _position_rect; + protected: static void _bind_methods(); @@ -73,5 +88,14 @@ namespace OpenVic { static godot::String int_to_formatted_string(int64_t val); static godot::String float_to_formatted_string(float val, int32_t decimal_places); static godot::String format_province_name(godot::String const& province_identifier); + + godot::Ref<godot::BitMap> get_click_mask() const; + void set_click_mask(godot::Ref<godot::BitMap> const& mask); + + void set_click_mask_from_nodepaths(godot::TypedArray<godot::NodePath> const& paths); + bool _update_click_mask_for(godot::Ref<godot::Image> const& img, int index); + void update_click_mask(); + + bool _has_point(godot::Vector2 const& point) const override; }; } diff --git a/game/src/Game/GameSession/GameSession.tscn b/game/src/Game/GameSession/GameSession.tscn index d2fc3a3..343ddfe 100644 --- a/game/src/Game/GameSession/GameSession.tscn +++ b/game/src/Game/GameSession/GameSession.tscn @@ -28,63 +28,76 @@ grow_horizontal = 2 grow_vertical = 2 mouse_filter = 2 script = ExtResource("1_eklvp") -_game_session_menu = NodePath("GameSessionMenu") +_game_session_menu = NodePath("UICanvasLayer/UI/GameSessionMenu") [node name="MapView" parent="." instance=ExtResource("4_xkg5j")] -[node name="ProvinceOverviewPanel" type="GUINode" parent="."] +[node name="UICanvasLayer" type="CanvasLayer" parent="."] + +[node name="UI" type="Control" parent="UICanvasLayer"] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +mouse_filter = 2 + +[node name="ProvinceOverviewPanel" type="GUINode" parent="UICanvasLayer/UI"] layout_mode = 1 anchors_preset = 15 +mouse_force_pass_scroll_events = false script = ExtResource("5_lfv8l") -[node name="Topbar" type="GUINode" parent="."] +[node name="Topbar" type="GUINode" parent="UICanvasLayer/UI"] layout_mode = 1 anchors_preset = 15 +mouse_force_pass_scroll_events = false script = ExtResource("4_2kbih") -[node name="ProductionMenu" type="GUINode" parent="Topbar"] +[node name="ProductionMenu" type="GUINode" parent="UICanvasLayer/UI/Topbar"] layout_mode = 1 anchors_preset = 15 script = ExtResource("5_16755") -[node name="BudgetMenu" type="GUINode" parent="Topbar"] +[node name="BudgetMenu" type="GUINode" parent="UICanvasLayer/UI/Topbar"] layout_mode = 1 anchors_preset = 15 script = ExtResource("6_vninv") -[node name="TechnologyMenu" type="GUINode" parent="Topbar"] +[node name="TechnologyMenu" type="GUINode" parent="UICanvasLayer/UI/Topbar"] layout_mode = 1 anchors_preset = 15 script = ExtResource("7_r712c") -[node name="PoliticsMenu" type="GUINode" parent="Topbar"] +[node name="PoliticsMenu" type="GUINode" parent="UICanvasLayer/UI/Topbar"] layout_mode = 1 anchors_preset = 15 script = ExtResource("8_ppdek") -[node name="PopulationMenu" type="GUINode" parent="Topbar"] +[node name="PopulationMenu" type="GUINode" parent="UICanvasLayer/UI/Topbar"] layout_mode = 1 anchors_preset = 15 script = ExtResource("10_laee7") -[node name="TradeMenu" type="GUINode" parent="Topbar"] +[node name="TradeMenu" type="GUINode" parent="UICanvasLayer/UI/Topbar"] layout_mode = 1 anchors_preset = 15 script = ExtResource("10_mv1r6") -[node name="DiplomacyMenu" type="GUINode" parent="Topbar"] +[node name="DiplomacyMenu" type="GUINode" parent="UICanvasLayer/UI/Topbar"] layout_mode = 1 anchors_preset = 15 script = ExtResource("11_fu7ys") -[node name="MilitaryMenu" type="GUINode" parent="Topbar"] +[node name="MilitaryMenu" type="GUINode" parent="UICanvasLayer/UI/Topbar"] layout_mode = 1 anchors_preset = 15 script = ExtResource("12_6h6nc") -[node name="MapControlPanel" parent="." instance=ExtResource("3_afh6d")] +[node name="MapControlPanel" parent="UICanvasLayer/UI" instance=ExtResource("3_afh6d")] layout_mode = 1 -anchors_preset = 3 +anchors_preset = -1 anchor_left = 1.0 anchor_top = 1.0 anchor_right = 1.0 @@ -92,7 +105,7 @@ anchor_bottom = 1.0 grow_horizontal = 0 grow_vertical = 0 -[node name="GameSessionMenu" parent="." instance=ExtResource("3_bvmqh")] +[node name="GameSessionMenu" parent="UICanvasLayer/UI" instance=ExtResource("3_bvmqh")] visible = false layout_mode = 1 anchors_preset = 8 @@ -107,11 +120,12 @@ offset_bottom = 165.0 grow_horizontal = 2 grow_vertical = 2 -[node name="OptionsMenu" parent="." instance=ExtResource("6_p5mnx")] +[node name="OptionsMenu" parent="UICanvasLayer/UI" instance=ExtResource("6_p5mnx")] visible = false layout_mode = 1 +mouse_force_pass_scroll_events = false -[node name="SaveLoadMenu" parent="." instance=ExtResource("8_4g7ko")] +[node name="SaveLoadMenu" parent="UICanvasLayer/UI" instance=ExtResource("8_4g7ko")] visible = false layout_mode = 1 anchors_preset = -1 @@ -120,7 +134,7 @@ anchor_right = 0.5 offset_left = -640.0 offset_right = 640.0 -[node name="MusicPlayer" parent="." instance=ExtResource("2_kt6aa")] +[node name="MusicPlayer" parent="UICanvasLayer/UI" instance=ExtResource("2_kt6aa")] layout_mode = 1 anchors_preset = 1 anchor_left = 1.0 @@ -129,15 +143,13 @@ offset_left = -150.0 offset_right = 0.0 grow_horizontal = 0 -[connection signal="map_view_camera_changed" from="MapView" to="MapControlPanel" method="_on_map_view_camera_changed"] -[connection signal="game_session_menu_button_pressed" from="MapControlPanel" to="." method="_on_game_session_menu_button_pressed"] -[connection signal="minimap_clicked" from="MapControlPanel" to="MapView" method="_on_minimap_clicked"] -[connection signal="mouse_entered" from="MapControlPanel" to="MapView" method="_on_mouse_exited_viewport"] -[connection signal="mouse_exited" from="MapControlPanel" to="MapView" method="_on_mouse_entered_viewport"] -[connection signal="zoom_in_button_pressed" from="MapControlPanel" to="MapView" method="zoom_in"] -[connection signal="zoom_out_button_pressed" from="MapControlPanel" to="MapView" method="zoom_out"] -[connection signal="load_button_pressed" from="GameSessionMenu" to="SaveLoadMenu" method="show_for_load"] -[connection signal="options_button_pressed" from="GameSessionMenu" to="OptionsMenu" method="show"] -[connection signal="save_button_pressed" from="GameSessionMenu" to="SaveLoadMenu" method="show_for_save"] -[connection signal="back_button_pressed" from="OptionsMenu" to="MapView" method="enable_processing"] -[connection signal="back_button_pressed" from="OptionsMenu" to="OptionsMenu" method="hide"] +[connection signal="map_view_camera_changed" from="MapView" to="UICanvasLayer/UI/MapControlPanel" method="_on_map_view_camera_changed"] +[connection signal="game_session_menu_button_pressed" from="UICanvasLayer/UI/MapControlPanel" to="." method="_on_game_session_menu_button_pressed"] +[connection signal="minimap_clicked" from="UICanvasLayer/UI/MapControlPanel" to="MapView" method="_on_minimap_clicked"] +[connection signal="zoom_in_button_pressed" from="UICanvasLayer/UI/MapControlPanel" to="MapView" method="zoom_in"] +[connection signal="zoom_out_button_pressed" from="UICanvasLayer/UI/MapControlPanel" to="MapView" method="zoom_out"] +[connection signal="load_button_pressed" from="UICanvasLayer/UI/GameSessionMenu" to="UICanvasLayer/UI/SaveLoadMenu" method="show_for_load"] +[connection signal="options_button_pressed" from="UICanvasLayer/UI/GameSessionMenu" to="UICanvasLayer/UI/OptionsMenu" method="show"] +[connection signal="save_button_pressed" from="UICanvasLayer/UI/GameSessionMenu" to="UICanvasLayer/UI/SaveLoadMenu" method="show_for_save"] +[connection signal="back_button_pressed" from="UICanvasLayer/UI/OptionsMenu" to="MapView" method="enable_processing"] +[connection signal="back_button_pressed" from="UICanvasLayer/UI/OptionsMenu" to="UICanvasLayer/UI/OptionsMenu" method="hide"] diff --git a/game/src/Game/GameSession/GameSessionMenu.tscn b/game/src/Game/GameSession/GameSessionMenu.tscn index af81f09..9885c7b 100644 --- a/game/src/Game/GameSession/GameSessionMenu.tscn +++ b/game/src/Game/GameSession/GameSessionMenu.tscn @@ -7,6 +7,7 @@ [node name="GameSessionMenu" type="PanelContainer" node_paths=PackedStringArray("_main_menu_dialog", "_quit_dialog")] process_mode = 3 editor_description = "UI-68" +mouse_force_pass_scroll_events = false theme = ExtResource("1_2onog") theme_type_variation = &"SessionPanel" script = ExtResource("1_usq6o") diff --git a/game/src/Game/GameSession/MapControlPanel/MapControlPanel.tscn b/game/src/Game/GameSession/MapControlPanel/MapControlPanel.tscn index 6731358..7578c82 100644 --- a/game/src/Game/GameSession/MapControlPanel/MapControlPanel.tscn +++ b/game/src/Game/GameSession/MapControlPanel/MapControlPanel.tscn @@ -17,7 +17,7 @@ events = [SubResource("InputEventAction_5nck3")] [node name="MapControlPanel" type="PanelContainer" node_paths=PackedStringArray("_mapmodes_grid")] editor_description = "SS-103, UI-548" -mouse_filter = 1 +mouse_force_pass_scroll_events = false script = ExtResource("1_ign64") _mapmodes_grid = NodePath("MapPanelMargin/MapPanelList/MapDisplayList/MapmodesGrid") diff --git a/game/src/Game/GameSession/MapView.gd b/game/src/Game/GameSession/MapView.gd index 2ab7c34..a83c790 100644 --- a/game/src/Game/GameSession/MapView.gd +++ b/game/src/Game/GameSession/MapView.gd @@ -16,14 +16,13 @@ const _action_click : StringName = &"map_click" @export var _camera : Camera3D -@export var _cardinal_move_speed : float = 1.0 +@export var _cardinal_move_speed : float = 2.5 @export var _edge_move_threshold: float = 0.01 @export var _edge_move_speed: float = 2.5 var _drag_anchor : Vector2 var _drag_active : bool = false var _mouse_over_viewport : bool = true -var _window_in_focus : bool = true @export var _zoom_target_min : float = 0.10 @export var _zoom_target_max : float = 5.0 @@ -122,17 +121,6 @@ func _ready() -> void: _map_text.generate_map_names() -func _notification(what : int) -> void: - match what: - NOTIFICATION_WM_MOUSE_ENTER: # Mouse inside window - _on_mouse_entered_viewport() - NOTIFICATION_WM_MOUSE_EXIT: # Mouse out of window - _on_mouse_exited_viewport() - NOTIFICATION_WM_WINDOW_FOCUS_IN: # Window comes into focus - _on_window_entered_focus() - NOTIFICATION_WM_WINDOW_FOCUS_OUT: # Window goes out of focus - _on_window_exited_focus() - func _world_to_map_coords(pos : Vector3) -> Vector2: return (Vector2(pos.x, pos.z) - _map_mesh_corner) / _map_mesh_dims @@ -163,14 +151,34 @@ func zoom_out() -> void: # cursor location. I'm not sure if we want to preserve this behavior. _zoom_position = Vector2() +func set_hovered_province_index(hover_index : int) -> void: + _map_shader_material.set_shader_parameter(GameLoader.ShaderManager.param_hover_index, hover_index) + +func set_hovered_province_at(pos : Vector2) -> void: + var hover_index := GameSingleton.get_province_index_from_uv_coords(pos) + set_hovered_province_index(hover_index) + +func unset_hovered_province() -> void: + set_hovered_province_index(0) + func _on_province_selected(index : int) -> void: _map_shader_material.set_shader_parameter(GameLoader.ShaderManager.param_selected_index, index) print("Province selected with index: ", index) +func _input(event : InputEvent) -> void: + if event is InputEventMouseMotion: + _mouse_pos_viewport = get_window().get_mouse_position() + elif _drag_active and event.is_action_released(_action_drag): + _drag_active = false + # REQUIREMENTS # * SS-31 func _unhandled_input(event : InputEvent) -> void: - if event.is_action_pressed(_action_click): + if event is InputEventMouseMotion: + _mouse_over_viewport = true + set_hovered_province_at(_viewport_to_map_coords(_mouse_pos_viewport)) + + elif event.is_action_pressed(_action_click): if _mouse_over_viewport: # Check if the mouse is outside of bounds if _map_mesh.is_valid_uv_coord(_mouse_pos_map): @@ -182,17 +190,16 @@ func _unhandled_input(event : InputEvent) -> void: push_warning("Drag being activated while already active!") _drag_active = true _drag_anchor = _mouse_pos_map - elif event.is_action_released(_action_drag): - if not _drag_active: - push_warning("Drag being deactivated while already not active!") - _drag_active = false elif event.is_action_pressed(_action_zoom_in, true): zoom_in() elif event.is_action_pressed(_action_zoom_out, true): zoom_out() -func _physics_process(delta : float) -> void: - _mouse_pos_viewport = get_viewport().get_mouse_position() +func _process(delta : float) -> void: + if _is_viewport_inactive(): + _mouse_over_viewport = false + unset_hovered_province() + _viewport_dims = Vector2(Resolution.get_current_resolution()) # Process movement _movement_process(delta) @@ -222,7 +229,7 @@ func _movement_process(delta : float) -> void: # REQUIREMENTS # * UIFUN-125 func _edge_scrolling_vector() -> Vector2: - if not _window_in_focus: + if _is_viewport_inactive(): return Vector2() var mouse_vector := _mouse_pos_viewport * GuiScale.get_current_guiscale() / _viewport_dims - Vector2(0.5, 0.5) # Only scroll if outside the move threshold. @@ -233,11 +240,12 @@ func _edge_scrolling_vector() -> Vector2: # REQUIREMENTS # * SS-75 func _cardinal_movement_vector() -> Vector2: - var move := Vector2( - float(Input.is_action_pressed(_action_east)) - float(Input.is_action_pressed(_action_west)), - float(Input.is_action_pressed(_action_south)) - float(Input.is_action_pressed(_action_north)) - ) - return move * _cardinal_move_speed + return Input.get_vector( + _action_west, + _action_east, + _action_north, + _action_south + ) * _cardinal_move_speed func _clamp_over_map() -> void: _camera.position.x = _map_mesh_corner.x + fposmod(_camera.position.x - _map_mesh_corner.x, _map_mesh_dims.x) @@ -291,23 +299,7 @@ func _update_minimap_viewport() -> void: map_view_camera_changed.emit(near_left, far_left, far_right, near_right) func _update_mouse_map_position() -> void: - if _mouse_over_viewport: - _mouse_pos_map = _viewport_to_map_coords(_mouse_pos_viewport) - var hover_index := GameSingleton.get_province_index_from_uv_coords(_mouse_pos_map) - _map_shader_material.set_shader_parameter(GameLoader.ShaderManager.param_hover_index, hover_index) - -func _on_mouse_entered_viewport() -> void: - _mouse_over_viewport = true - -func _on_mouse_exited_viewport() -> void: - _mouse_over_viewport = false - _map_shader_material.set_shader_parameter(GameLoader.ShaderManager.param_hover_index, 0) - -func _on_window_entered_focus() -> void: - _window_in_focus = true - -func _on_window_exited_focus() -> void: - _window_in_focus = false + _mouse_pos_map = _viewport_to_map_coords(_mouse_pos_viewport) func _on_minimap_clicked(pos_clicked : Vector2) -> void: pos_clicked *= _map_mesh_dims @@ -315,10 +307,13 @@ func _on_minimap_clicked(pos_clicked : Vector2) -> void: _camera.position.z = pos_clicked.y _clamp_over_map() +func _is_viewport_inactive() -> bool: + return not get_window().has_focus() or get_window().is_input_handled() + func enable_processing() -> void: set_process_unhandled_input(true) - set_physics_process(true) + set_process(true) func disable_processing() -> void: set_process_unhandled_input(false) - set_physics_process(false) + set_process(false) diff --git a/game/src/Game/GameSession/ProvinceOverviewPanel.gd b/game/src/Game/GameSession/ProvinceOverviewPanel.gd index 13e7111..42f6765 100644 --- a/game/src/Game/GameSession/ProvinceOverviewPanel.gd +++ b/game/src/Game/GameSession/ProvinceOverviewPanel.gd @@ -125,6 +125,12 @@ func _ready() -> void: push_error("Failed to generate province overview panel!") return + # Disables all consuming invisible panel + var prov_view := get_panel_from_nodepath(^"./province_view") + if prov_view: + prov_view.mouse_filter = Control.MOUSE_FILTER_IGNORE + set_click_mask_from_nodepaths([^"./province_view/background"]) + var close_button : Button = get_button_from_nodepath(^"./province_view/close_button") if close_button: close_button.pressed.connect(_on_close_button_pressed) diff --git a/game/src/Game/GameSession/Topbar.gd b/game/src/Game/GameSession/Topbar.gd index 92ee75a..8da15e0 100644 --- a/game/src/Game/GameSession/Topbar.gd +++ b/game/src/Game/GameSession/Topbar.gd @@ -27,6 +27,12 @@ func _ready() -> void: const player_country : String = "SLV" + # Disables all consuming invisible panel + var topbar := get_panel_from_nodepath(^"./topbar") + if topbar: + topbar.mouse_filter = Control.MOUSE_FILTER_IGNORE + set_click_mask_from_nodepaths([^"./topbar/topbar_bg", ^"./topbar/topbar_paper"]) + # Player country info var player_flag_texture : GFXMaskedFlagTexture = get_gfx_masked_flag_texture_from_nodepath(^"./topbar/player_flag") if player_flag_texture: diff --git a/game/src/Game/Menu/SaveLoadMenu/SaveLoadMenu.tscn b/game/src/Game/Menu/SaveLoadMenu/SaveLoadMenu.tscn index adc9bdc..38b915c 100644 --- a/game/src/Game/Menu/SaveLoadMenu/SaveLoadMenu.tscn +++ b/game/src/Game/Menu/SaveLoadMenu/SaveLoadMenu.tscn @@ -33,6 +33,7 @@ _overwrite_dialog = NodePath("OverwriteDialog") [node name="SaveLoadPanel" type="PanelContainer" parent="."] layout_mode = 2 +mouse_force_pass_scroll_events = false [node name="SaveLoadList" type="VBoxContainer" parent="SaveLoadPanel"] layout_mode = 2 diff --git a/game/src/Game/MusicConductor/MusicPlayer.tscn b/game/src/Game/MusicConductor/MusicPlayer.tscn index 27bb476..ef57eac 100644 --- a/game/src/Game/MusicConductor/MusicPlayer.tscn +++ b/game/src/Game/MusicConductor/MusicPlayer.tscn @@ -21,6 +21,7 @@ editor_description = "UI-105, UI-107, UI-110, UIFUN-92" custom_minimum_size = Vector2(150, 0) layout_mode = 2 focus_mode = 0 +mouse_force_pass_scroll_events = false alignment = 1 text_overrun_behavior = 3 fit_to_longest_item = false |