|
@@ -31,8 +31,61 @@
|
|
|
#include "camera_2d.h"
|
|
|
|
|
|
#include "core/config/project_settings.h"
|
|
|
+#include "core/input/input.h"
|
|
|
#include "scene/main/viewport.h"
|
|
|
|
|
|
+#ifdef TOOLS_ENABLED
|
|
|
+Dictionary Camera2D::_edit_get_state() const {
|
|
|
+ Dictionary state = Node2D::_edit_get_state();
|
|
|
+ state["limit_rect"] = get_limit_rect();
|
|
|
+ return state;
|
|
|
+}
|
|
|
+
|
|
|
+void Camera2D::_edit_set_state(const Dictionary &p_state) {
|
|
|
+ if (p_state.has("limit_rect")) {
|
|
|
+ _set_limit_rect(p_state["limit_rect"]);
|
|
|
+ }
|
|
|
+ Node2D::_edit_set_state(p_state);
|
|
|
+}
|
|
|
+
|
|
|
+void Camera2D::_edit_set_position(const Point2 &p_position) {
|
|
|
+ if (_is_dragging_limit_rect()) {
|
|
|
+ Rect2 rect = get_limit_rect();
|
|
|
+ rect.position = p_position;
|
|
|
+ _set_limit_rect(rect);
|
|
|
+ } else {
|
|
|
+ Node2D::_edit_set_position(p_position);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+Point2 Camera2D::_edit_get_position() const {
|
|
|
+ return _is_dragging_limit_rect() ? get_limit_rect().position : Node2D::_edit_get_position();
|
|
|
+}
|
|
|
+
|
|
|
+void Camera2D::_edit_set_rect(const Rect2 &p_rect) {
|
|
|
+ ERR_FAIL_COND(limit_enabled && !_edit_use_rect());
|
|
|
+ Rect2 rect = p_rect;
|
|
|
+ Vector2 scl = get_global_scale().abs();
|
|
|
+ rect.size *= scl;
|
|
|
+ rect.position = (rect.position + get_global_position()) * scl;
|
|
|
+ _set_limit_rect(rect);
|
|
|
+}
|
|
|
+#endif // TOOLS_ENABLED
|
|
|
+
|
|
|
+#ifdef DEBUG_ENABLED
|
|
|
+Rect2 Camera2D::_edit_get_rect() const {
|
|
|
+ Rect2 rect = get_limit_rect();
|
|
|
+ Vector2 scl = get_global_scale().abs();
|
|
|
+ rect.size /= scl;
|
|
|
+ rect.position = (rect.position - get_global_position()) / scl;
|
|
|
+ return rect;
|
|
|
+}
|
|
|
+
|
|
|
+bool Camera2D::_edit_use_rect() const {
|
|
|
+ return limit_enabled;
|
|
|
+}
|
|
|
+#endif // DEBUG_ENABLED
|
|
|
+
|
|
|
bool Camera2D::_is_editing_in_editor() const {
|
|
|
#ifdef TOOLS_ENABLED
|
|
|
return is_part_of_edited_scene();
|
|
@@ -75,6 +128,10 @@ void Camera2D::_update_scroll() {
|
|
|
}
|
|
|
|
|
|
#ifdef TOOLS_ENABLED
|
|
|
+bool Camera2D::_is_dragging_limit_rect() const {
|
|
|
+ return _edit_use_rect() && Input::get_singleton()->is_key_pressed(Key::CTRL);
|
|
|
+}
|
|
|
+
|
|
|
void Camera2D::_project_settings_changed() {
|
|
|
if (screen_drawing_enabled) {
|
|
|
queue_redraw();
|
|
@@ -169,7 +226,7 @@ Transform2D Camera2D::get_camera_transform() {
|
|
|
Point2 screen_offset = (anchor_mode == ANCHOR_MODE_DRAG_CENTER ? (screen_size * 0.5 * zoom_scale) : Point2());
|
|
|
Rect2 screen_rect(-screen_offset + camera_pos, screen_size * zoom_scale);
|
|
|
|
|
|
- if (limit_smoothing_enabled) {
|
|
|
+ if (limit_enabled && limit_smoothing_enabled) {
|
|
|
if (screen_rect.position.x < limit[SIDE_LEFT]) {
|
|
|
camera_pos.x -= screen_rect.position.x - limit[SIDE_LEFT];
|
|
|
}
|
|
@@ -222,7 +279,7 @@ Transform2D Camera2D::get_camera_transform() {
|
|
|
|
|
|
Rect2 screen_rect(-screen_offset + ret_camera_pos, screen_size * zoom_scale);
|
|
|
|
|
|
- if (!position_smoothing_enabled || !limit_smoothing_enabled) {
|
|
|
+ if (limit_enabled && (!position_smoothing_enabled || !limit_smoothing_enabled)) {
|
|
|
if (screen_rect.position.x < limit[SIDE_LEFT]) {
|
|
|
screen_rect.position.x = limit[SIDE_LEFT];
|
|
|
}
|
|
@@ -398,8 +455,7 @@ void Camera2D::_notification(int p_what) {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- if (limit_drawing_enabled) {
|
|
|
- Color limit_drawing_color(1, 1, 0.25, 0.63);
|
|
|
+ if (limit_enabled && limit_drawing_enabled) {
|
|
|
real_t limit_drawing_width = -1;
|
|
|
if (is_current()) {
|
|
|
limit_drawing_width = 3;
|
|
@@ -415,7 +471,7 @@ void Camera2D::_notification(int p_what) {
|
|
|
};
|
|
|
|
|
|
for (int i = 0; i < 4; i++) {
|
|
|
- draw_line(limit_points[i], limit_points[(i + 1) % 4], limit_drawing_color, limit_drawing_width);
|
|
|
+ draw_line(limit_points[i], limit_points[(i + 1) % 4], Color(1, 1, 0.25, 0.63), limit_drawing_width);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -484,6 +540,22 @@ bool Camera2D::is_ignoring_rotation() const {
|
|
|
return ignore_rotation;
|
|
|
}
|
|
|
|
|
|
+void Camera2D::set_limit_enabled(bool p_limit_enabled) {
|
|
|
+ if (p_limit_enabled == limit_enabled) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ limit_enabled = p_limit_enabled;
|
|
|
+ _update_scroll();
|
|
|
+#ifdef TOOLS_ENABLED
|
|
|
+ emit_signal("_camera_limit_enabled_updated"); // Used for Camera2DEditorPlugin
|
|
|
+#endif
|
|
|
+ notify_property_list_changed();
|
|
|
+}
|
|
|
+
|
|
|
+bool Camera2D::is_limit_enabled() const {
|
|
|
+ return limit_enabled;
|
|
|
+}
|
|
|
+
|
|
|
void Camera2D::set_process_callback(Camera2DProcessCallback p_mode) {
|
|
|
if (process_callback == p_mode) {
|
|
|
return;
|
|
@@ -548,6 +620,18 @@ void Camera2D::_update_process_internal_for_smoothing() {
|
|
|
set_process_internal(enable);
|
|
|
}
|
|
|
|
|
|
+void Camera2D::_set_limit_rect(const Rect2 &p_limit_rect) {
|
|
|
+ Point2 limit_rect_end = p_limit_rect.get_end();
|
|
|
+ set_limit(SIDE_LEFT, p_limit_rect.position.x);
|
|
|
+ set_limit(SIDE_TOP, p_limit_rect.position.y);
|
|
|
+ set_limit(SIDE_RIGHT, limit_rect_end.x);
|
|
|
+ set_limit(SIDE_BOTTOM, limit_rect_end.y);
|
|
|
+}
|
|
|
+
|
|
|
+Rect2 Camera2D::get_limit_rect() const {
|
|
|
+ return Rect2(limit[SIDE_LEFT], limit[SIDE_TOP], limit[SIDE_RIGHT] - limit[SIDE_LEFT], limit[SIDE_BOTTOM] - limit[SIDE_TOP]);
|
|
|
+}
|
|
|
+
|
|
|
void Camera2D::make_current() {
|
|
|
ERR_FAIL_COND(!enabled || !is_inside_tree());
|
|
|
get_tree()->call_group(group_name, "_make_current", this);
|
|
@@ -817,6 +901,9 @@ bool Camera2D::is_margin_drawing_enabled() const {
|
|
|
}
|
|
|
|
|
|
void Camera2D::_validate_property(PropertyInfo &p_property) const {
|
|
|
+ if (!limit_enabled && (p_property.name == "limit_smoothed" || p_property.name == "limit_left" || p_property.name == "limit_top" || p_property.name == "limit_right" || p_property.name == "limit_bottom")) {
|
|
|
+ p_property.usage = PROPERTY_USAGE_NO_EDITOR;
|
|
|
+ }
|
|
|
if (!position_smoothing_enabled && p_property.name == "position_smoothing_speed") {
|
|
|
p_property.usage = PROPERTY_USAGE_NO_EDITOR;
|
|
|
}
|
|
@@ -847,6 +934,9 @@ void Camera2D::_bind_methods() {
|
|
|
ClassDB::bind_method(D_METHOD("is_current"), &Camera2D::is_current);
|
|
|
ClassDB::bind_method(D_METHOD("_make_current"), &Camera2D::_make_current);
|
|
|
|
|
|
+ ClassDB::bind_method(D_METHOD("set_limit_enabled", "limit_enabled"), &Camera2D::set_limit_enabled);
|
|
|
+ ClassDB::bind_method(D_METHOD("is_limit_enabled"), &Camera2D::is_limit_enabled);
|
|
|
+
|
|
|
ClassDB::bind_method(D_METHOD("set_limit", "margin", "limit"), &Camera2D::set_limit);
|
|
|
ClassDB::bind_method(D_METHOD("get_limit", "margin"), &Camera2D::get_limit);
|
|
|
|
|
@@ -913,6 +1003,7 @@ void Camera2D::_bind_methods() {
|
|
|
ADD_PROPERTY(PropertyInfo(Variant::INT, "process_callback", PROPERTY_HINT_ENUM, "Physics,Idle"), "set_process_callback", "get_process_callback");
|
|
|
|
|
|
ADD_GROUP("Limit", "limit_");
|
|
|
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "limit_enabled"), "set_limit_enabled", "is_limit_enabled");
|
|
|
ADD_PROPERTYI(PropertyInfo(Variant::INT, "limit_left", PROPERTY_HINT_NONE, "suffix:px"), "set_limit", "get_limit", SIDE_LEFT);
|
|
|
ADD_PROPERTYI(PropertyInfo(Variant::INT, "limit_top", PROPERTY_HINT_NONE, "suffix:px"), "set_limit", "get_limit", SIDE_TOP);
|
|
|
ADD_PROPERTYI(PropertyInfo(Variant::INT, "limit_right", PROPERTY_HINT_NONE, "suffix:px"), "set_limit", "get_limit", SIDE_RIGHT);
|
|
@@ -961,4 +1052,8 @@ Camera2D::Camera2D() {
|
|
|
|
|
|
set_notify_transform(true);
|
|
|
set_hide_clip_children(true);
|
|
|
+
|
|
|
+#ifdef TOOLS_ENABLED
|
|
|
+ add_user_signal(MethodInfo("_camera_limit_enabled_updated")); // Camera2DEditorPlugin listens to this
|
|
|
+#endif
|
|
|
}
|