summaryrefslogtreecommitdiff
path: root/scene/main
diff options
context:
space:
mode:
Diffstat (limited to 'scene/main')
-rw-r--r--scene/main/canvas_item.cpp2
-rw-r--r--scene/main/canvas_item.h2
-rw-r--r--scene/main/scene_tree.cpp5
-rw-r--r--scene/main/scene_tree.h2
-rw-r--r--scene/main/viewport.cpp50
-rw-r--r--scene/main/viewport.h7
-rw-r--r--scene/main/window.cpp17
-rw-r--r--scene/main/window.h6
8 files changed, 76 insertions, 15 deletions
diff --git a/scene/main/canvas_item.cpp b/scene/main/canvas_item.cpp
index 721f573f39..d1bf038b8d 100644
--- a/scene/main/canvas_item.cpp
+++ b/scene/main/canvas_item.cpp
@@ -1174,7 +1174,7 @@ void CanvasItem::_bind_methods() {
ClassDB::bind_method(D_METHOD("draw_mesh", "mesh", "texture", "normal_map", "specular_map", "specular_shininess", "transform", "modulate", "texture_filter", "texture_repeat"), &CanvasItem::draw_mesh, DEFVAL(Ref<Texture2D>()), DEFVAL(Ref<Texture2D>()), DEFVAL(Color(1, 1, 1, 1)), DEFVAL(Transform2D()), DEFVAL(Color(1, 1, 1, 1)), DEFVAL(TEXTURE_FILTER_PARENT_NODE), DEFVAL(TEXTURE_REPEAT_PARENT_NODE));
ClassDB::bind_method(D_METHOD("draw_multimesh", "multimesh", "texture", "normal_map", "specular_map", "specular_shininess", "texture_filter", "texture_repeat"), &CanvasItem::draw_multimesh, DEFVAL(Ref<Texture2D>()), DEFVAL(Ref<Texture2D>()), DEFVAL(Color(1, 1, 1, 1)), DEFVAL(TEXTURE_FILTER_PARENT_NODE), DEFVAL(TEXTURE_REPEAT_PARENT_NODE));
- ClassDB::bind_method(D_METHOD("draw_set_transform", "position", "rotation", "scale"), &CanvasItem::draw_set_transform);
+ ClassDB::bind_method(D_METHOD("draw_set_transform", "position", "rotation", "scale"), &CanvasItem::draw_set_transform, DEFVAL(0.0), DEFVAL(Size2(1.0, 1.0)));
ClassDB::bind_method(D_METHOD("draw_set_transform_matrix", "xform"), &CanvasItem::draw_set_transform_matrix);
ClassDB::bind_method(D_METHOD("get_transform"), &CanvasItem::get_transform);
ClassDB::bind_method(D_METHOD("get_global_transform"), &CanvasItem::get_global_transform);
diff --git a/scene/main/canvas_item.h b/scene/main/canvas_item.h
index 31edd424a1..918610ac1e 100644
--- a/scene/main/canvas_item.h
+++ b/scene/main/canvas_item.h
@@ -348,7 +348,7 @@ public:
void draw_string(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, const Color &p_modulate = Color(1, 1, 1), int p_clip_w = -1);
float draw_char(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_char, const String &p_next = "", const Color &p_modulate = Color(1, 1, 1));
- void draw_set_transform(const Point2 &p_offset, float p_rot, const Size2 &p_scale);
+ void draw_set_transform(const Point2 &p_offset, float p_rot = 0.0, const Size2 &p_scale = Size2(1.0, 1.0));
void draw_set_transform_matrix(const Transform2D &p_matrix);
static CanvasItem *get_current_item_drawn();
diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp
index a418883506..d6159e089b 100644
--- a/scene/main/scene_tree.cpp
+++ b/scene/main/scene_tree.cpp
@@ -939,10 +939,6 @@ int64_t SceneTree::get_frame() const {
return current_frame;
}
-int64_t SceneTree::get_event_count() const {
- return current_event;
-}
-
Array SceneTree::_get_nodes_in_group(const StringName &p_group) {
Array ret;
Map<StringName, Group>::Element *E = group_map.find(p_group);
@@ -1362,7 +1358,6 @@ SceneTree::SceneTree() {
root = nullptr;
pause = false;
current_frame = 0;
- current_event = 0;
tree_changed_name = "tree_changed";
node_added_name = "node_added";
node_removed_name = "node_removed";
diff --git a/scene/main/scene_tree.h b/scene/main/scene_tree.h
index 57b6b4dcfa..bea29c7605 100644
--- a/scene/main/scene_tree.h
+++ b/scene/main/scene_tree.h
@@ -110,7 +110,6 @@ private:
StringName node_renamed_name;
int64_t current_frame;
- int64_t current_event;
int node_count;
#ifdef TOOLS_ENABLED
@@ -300,7 +299,6 @@ public:
int get_collision_debug_contact_count() { return collision_debug_contacts; }
int64_t get_frame() const;
- int64_t get_event_count() const;
int get_node_count() const;
diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp
index 8042f02fa6..65a72267b1 100644
--- a/scene/main/viewport.cpp
+++ b/scene/main/viewport.cpp
@@ -2450,6 +2450,22 @@ void Viewport::_gui_remove_control(Control *p_control) {
}
}
+Window *Viewport::get_base_window() const {
+ Viewport *v = const_cast<Viewport *>(this);
+ Window *w = Object::cast_to<Window>(v);
+ while (!w) {
+ v = v->get_parent_viewport();
+ w = Object::cast_to<Window>(v);
+ }
+
+ return w;
+}
+void Viewport::_gui_remove_focus_for_window(Node *p_window) {
+ if (get_base_window() == p_window) {
+ _gui_remove_focus();
+ }
+}
+
void Viewport::_gui_remove_focus() {
if (gui.key_focus) {
Node *f = gui.key_focus;
@@ -2467,7 +2483,7 @@ void Viewport::_gui_control_grab_focus(Control *p_control) {
if (gui.key_focus && gui.key_focus == p_control) {
return;
}
- get_tree()->call_group_flags(SceneTree::GROUP_CALL_REALTIME, "_viewports", "_gui_remove_focus");
+ get_tree()->call_group_flags(SceneTree::GROUP_CALL_REALTIME, "_viewports", "_gui_remove_focus_for_window", (Node *)get_base_window());
gui.key_focus = p_control;
emit_signal("gui_focus_changed", p_control);
p_control->notification(Control::NOTIFICATION_FOCUS_ENTER);
@@ -2685,6 +2701,27 @@ bool Viewport::_sub_windows_forward_input(const Ref<InputEvent> &p_event) {
if (gui.subwindow_drag == SUB_WINDOW_DRAG_MOVE) {
Vector2 diff = mm->get_position() - gui.subwindow_drag_from;
Rect2i new_rect(gui.subwindow_drag_pos + diff, gui.subwindow_focused->get_size());
+
+ if (gui.subwindow_focused->is_clamped_to_embedder()) {
+ Size2i limit = get_visible_rect().size;
+ if (new_rect.position.x + new_rect.size.x > limit.x) {
+ new_rect.position.x = limit.x - new_rect.size.x;
+ }
+ if (new_rect.position.y + new_rect.size.y > limit.y) {
+ new_rect.position.y = limit.y - new_rect.size.y;
+ }
+
+ if (new_rect.position.x < 0) {
+ new_rect.position.x = 0;
+ }
+
+ int title_height = gui.subwindow_focused->get_flag(Window::FLAG_BORDERLESS) ? 0 : gui.subwindow_focused->get_theme_constant("title_height");
+
+ if (new_rect.position.y < title_height) {
+ new_rect.position.y = title_height;
+ }
+ }
+
gui.subwindow_focused->_rect_changed_callback(new_rect);
}
if (gui.subwindow_drag == SUB_WINDOW_DRAG_CLOSE) {
@@ -2913,6 +2950,10 @@ void Viewport::input(const Ref<InputEvent> &p_event, bool p_local_coords) {
return;
}
+ if (!_can_consume_input_events()) {
+ return;
+ }
+
if (!is_input_handled()) {
get_tree()->_call_input_pause(input_group, "_input", ev, this); //not a bug, must happen before GUI, order is _input -> gui input -> _unhandled input
}
@@ -2920,13 +2961,15 @@ void Viewport::input(const Ref<InputEvent> &p_event, bool p_local_coords) {
if (!is_input_handled()) {
_gui_input_event(ev);
}
+
+ event_count++;
//get_tree()->call_group(SceneTree::GROUP_CALL_REVERSE|SceneTree::GROUP_CALL_REALTIME|SceneTree::GROUP_CALL_MULIILEVEL,gui_input_group,"_gui_input",ev); //special one for GUI, as controls use their own process check
}
void Viewport::unhandled_input(const Ref<InputEvent> &p_event, bool p_local_coords) {
ERR_FAIL_COND(!is_inside_tree());
- if (disable_input) {
+ if (disable_input || !_can_consume_input_events()) {
return;
}
@@ -3301,8 +3344,7 @@ void Viewport::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_disable_input", "disable"), &Viewport::set_disable_input);
ClassDB::bind_method(D_METHOD("is_input_disabled"), &Viewport::is_input_disabled);
- ClassDB::bind_method(D_METHOD("_gui_show_tooltip"), &Viewport::_gui_show_tooltip);
- ClassDB::bind_method(D_METHOD("_gui_remove_focus"), &Viewport::_gui_remove_focus);
+ ClassDB::bind_method(D_METHOD("_gui_remove_focus_for_window"), &Viewport::_gui_remove_focus_for_window);
ClassDB::bind_method(D_METHOD("_post_gui_grab_click_focus"), &Viewport::_post_gui_grab_click_focus);
ClassDB::bind_method(D_METHOD("set_shadow_atlas_size", "size"), &Viewport::set_shadow_atlas_size);
diff --git a/scene/main/viewport.h b/scene/main/viewport.h
index 11fe4f00d2..09ef4354c5 100644
--- a/scene/main/viewport.h
+++ b/scene/main/viewport.h
@@ -392,6 +392,7 @@ private:
void _gui_force_drag(Control *p_base, const Variant &p_data, Control *p_control);
void _gui_set_drag_preview(Control *p_base, Control *p_control);
+ void _gui_remove_focus_for_window(Node *p_window);
void _gui_remove_focus();
void _gui_unfocus_control(Control *p_control);
bool _gui_control_has_focus(const Control *p_control);
@@ -441,6 +442,9 @@ private:
bool _sub_windows_forward_input(const Ref<InputEvent> &p_event);
SubWindowResize _sub_window_get_resize_margin(Window *p_subwindow, const Point2 &p_point);
+ virtual bool _can_consume_input_events() const { return true; }
+ uint64_t event_count = 0;
+
protected:
void _set_size(const Size2i &p_size, const Size2i &p_size_2d_override, const Rect2i &p_to_screen_rect, const Transform2D &p_stretch_transform, bool p_allocated);
@@ -453,6 +457,8 @@ protected:
virtual void _validate_property(PropertyInfo &property) const;
public:
+ uint64_t get_processed_events_count() const { return event_count; }
+
Listener3D *get_listener() const;
Camera3D *get_camera() const;
@@ -570,6 +576,7 @@ public:
bool is_embedding_subwindows() const;
Viewport *get_parent_viewport() const;
+ Window *get_base_window() const;
void pass_mouse_focus_to(Viewport *p_viewport, Control *p_control);
diff --git a/scene/main/window.cpp b/scene/main/window.cpp
index 7f2160c6a5..0463615d4d 100644
--- a/scene/main/window.cpp
+++ b/scene/main/window.cpp
@@ -874,6 +874,10 @@ void Window::child_controls_changed() {
call_deferred("_update_child_controls");
}
+bool Window::_can_consume_input_events() const {
+ return exclusive_child == nullptr;
+}
+
void Window::_window_input(const Ref<InputEvent> &p_ev) {
if (Engine::get_singleton()->is_editor_hint() && (Object::cast_to<InputEventJoypadButton>(p_ev.ptr()) || Object::cast_to<InputEventJoypadMotion>(*p_ev))) {
return; //avoid joy input on editor
@@ -890,10 +894,13 @@ void Window::_window_input(const Ref<InputEvent> &p_ev) {
if (exclusive_child != nullptr) {
exclusive_child->grab_focus();
- return; //has an exclusive child, can't get events until child is closed
+ if (!is_embedding_subwindows()) { //not embedding, no need for event
+ return;
+ }
}
emit_signal(SceneStringNames::get_singleton()->window_input, p_ev);
+
input(p_ev);
if (!is_input_handled()) {
unhandled_input(p_ev);
@@ -1244,6 +1251,14 @@ Rect2i Window::get_parent_rect() const {
}
}
+void Window::set_clamp_to_embedder(bool p_enable) {
+ clamp_to_embedder = p_enable;
+}
+
+bool Window::is_clamped_to_embedder() const {
+ return clamp_to_embedder;
+}
+
void Window::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_title", "title"), &Window::set_title);
ClassDB::bind_method(D_METHOD("get_title"), &Window::get_title);
diff --git a/scene/main/window.h b/scene/main/window.h
index adaa5ca3be..5fd59e06f5 100644
--- a/scene/main/window.h
+++ b/scene/main/window.h
@@ -92,6 +92,7 @@ private:
bool exclusive = false;
bool wrap_controls = false;
bool updating_child_controls = false;
+ bool clamp_to_embedder = false;
void _update_child_controls();
@@ -130,10 +131,10 @@ private:
void _window_drop_files(const Vector<String> &p_files);
void _rect_changed_callback(const Rect2i &p_callback);
void _event_callback(DisplayServer::WindowEvent p_event);
+ virtual bool _can_consume_input_events() const;
protected:
Viewport *_get_embedder() const;
-
virtual Rect2i _popup_adjust_rect() const { return Rect2i(); }
virtual void _post_popup() {}
@@ -195,6 +196,9 @@ public:
void set_exclusive(bool p_exclusive);
bool is_exclusive() const;
+ void set_clamp_to_embedder(bool p_enable);
+ bool is_clamped_to_embedder() const;
+
bool can_draw() const;
void set_ime_active(bool p_active);