Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add viewport override to 2D editor #74573

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
175 changes: 152 additions & 23 deletions editor/plugins/canvas_item_editor_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
#include "scene/gui/separator.h"
#include "scene/gui/split_container.h"
#include "scene/gui/subviewport_container.h"
#include "scene/gui/texture_rect.h"
#include "scene/gui/view_panner.h"
#include "scene/main/canvas_layer.h"
#include "scene/main/window.h"
Expand Down Expand Up @@ -606,6 +607,21 @@ Rect2 CanvasItemEditor::_get_encompassing_rect(const Node *p_node) {
return rect;
}

Vector2 CanvasItemEditor::_get_screen_size() const {
if (!_is_viewport_overridden()) {
return Vector2(GLOBAL_GET("display/window/size/viewport_width"), GLOBAL_GET("display/window/size/viewport_height"));
}
SubViewport *svp = Object::cast_to<SubViewport>(current_viewport);
if (svp) {
return svp->get_size();
}
Window *w = Object::cast_to<Window>(current_viewport);
if (w) {
return w->get_size();
}
return Vector2();
}

void CanvasItemEditor::_find_canvas_items_at_pos(const Point2 &p_pos, Node *p_node, Vector<_SelectResult> &r_items, const Transform2D &p_parent_xform, const Transform2D &p_canvas_xform) {
if (!p_node) {
return;
Expand All @@ -618,7 +634,7 @@ void CanvasItemEditor::_find_canvas_items_at_pos(const Point2 &p_pos, Node *p_no
if (CanvasLayer *cl = Object::cast_to<CanvasLayer>(p_node)) {
xform = cl->get_transform();
} else if (Viewport *vp = Object::cast_to<Viewport>(p_node)) {
if (!vp->is_visible_subviewport()) {
if (!_is_usable_viewport(vp)) {
return;
}
xform = vp->get_popup_base_transform();
Expand All @@ -639,6 +655,10 @@ void CanvasItemEditor::_find_canvas_items_at_pos(const Point2 &p_pos, Node *p_no
}
}

if (_is_viewport_overridden() && p_node->get_viewport() != current_viewport) {
return;
}

if (ci && ci->is_visible_in_tree()) {
if (!ci->is_set_as_top_level()) {
xform *= p_parent_xform;
Expand Down Expand Up @@ -721,7 +741,7 @@ void CanvasItemEditor::_find_canvas_items_in_rect(const Rect2 &p_rect, Node *p_n
if (CanvasLayer *cl = Object::cast_to<CanvasLayer>(p_node)) {
xform = cl->get_transform();
} else if (Viewport *vp = Object::cast_to<Viewport>(p_node)) {
if (!vp->is_visible_subviewport()) {
if (!_is_usable_viewport(vp)) {
return;
}
xform = vp->get_popup_base_transform();
Expand Down Expand Up @@ -804,7 +824,7 @@ List<CanvasItem *> CanvasItemEditor::_get_edited_canvas_items(bool p_retrieve_lo
if (ci) {
if (ci->is_visible_in_tree() && (p_retrieve_locked || !_is_node_locked(ci))) {
Viewport *vp = ci->get_viewport();
if (vp && !vp->is_visible_subviewport()) {
if (!_is_usable_viewport(vp)) {
continue;
}
CanvasItemEditorSelectedItem *se = editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(ci);
Expand Down Expand Up @@ -1066,6 +1086,47 @@ void CanvasItemEditor::_on_grid_menu_id_pressed(int p_id) {
viewport->queue_redraw();
}

void CanvasItemEditor::_set_viewport_override(Viewport *p_viewport) {
if (p_viewport && p_viewport == current_viewport) {
return;
}

const Callable update_size = callable_mp(this, &CanvasItemEditor::_update_viewport_size);
const Callable redraw = callable_mp((CanvasItem *)viewport, &CanvasItem::queue_redraw);

if (current_viewport && _is_viewport_overridden()) {
current_viewport->disconnect("size_changed", update_size);
current_viewport->disconnect("size_changed", redraw);
}

if (p_viewport) {
p_viewport->connect("size_changed", update_size);
p_viewport->connect("size_changed", redraw);
scene_view_display->set_global_canvas_transform(EditorNode::get_singleton()->get_scene_root()->get_global_canvas_transform());
} else {
p_viewport = EditorNode::get_singleton()->get_scene_root();
p_viewport->set_global_canvas_transform(scene_view_display->get_global_canvas_transform());
scene_view_display->set_global_canvas_transform(Transform2D());
}

current_viewport = p_viewport;
scene_view->set_texture(p_viewport->get_texture());
_update_viewport_size();
viewport->queue_redraw();
}

void CanvasItemEditor::_update_viewport_size() {
EditorNode::get_singleton()->get_scene_root()->set_size(scene_tree->get_size());
}

bool CanvasItemEditor::_is_usable_viewport(const Viewport *p_viewport) const {
return p_viewport && p_viewport == current_viewport && p_viewport->is_visible_subviewport();
}

bool CanvasItemEditor::_is_viewport_overridden() const {
return current_viewport != EditorNode::get_singleton()->get_scene_root();
}

void CanvasItemEditor::_switch_theme_preview(int p_mode) {
view_menu->get_popup()->hide();

Expand Down Expand Up @@ -3793,13 +3854,13 @@ void CanvasItemEditor::_draw_axis() {

Color area_axis_color = EDITOR_GET("editors/2d/viewport_border_color");

Size2 screen_size = Size2(GLOBAL_GET("display/window/size/viewport_width"), GLOBAL_GET("display/window/size/viewport_height"));
Size2 viewport_size = _get_screen_size();

Vector2 screen_endpoints[4] = {
transform.xform(Vector2(0, 0)),
transform.xform(Vector2(screen_size.width, 0)),
transform.xform(Vector2(screen_size.width, screen_size.height)),
transform.xform(Vector2(0, screen_size.height))
transform.xform(Vector2(viewport_size.width, 0)),
transform.xform(Vector2(viewport_size.width, viewport_size.height)),
transform.xform(Vector2(0, viewport_size.height))
};

for (int i = 0; i < 4; i++) {
Expand Down Expand Up @@ -3829,7 +3890,7 @@ void CanvasItemEditor::_draw_invisible_nodes_positions(Node *p_node, const Trans
parent_xform = Transform2D();
canvas_xform = cl->get_transform();
} else if (Viewport *vp = Object::cast_to<Viewport>(p_node)) {
if (!vp->is_visible_subviewport()) {
if (_is_usable_viewport(vp)) {
return;
}
parent_xform = Transform2D();
Expand Down Expand Up @@ -3964,7 +4025,7 @@ void CanvasItemEditor::_draw_locks_and_groups(Node *p_node, const Transform2D &p
parent_xform = Transform2D();
canvas_xform = cl->get_transform();
} else if (Viewport *vp = Object::cast_to<Viewport>(p_node)) {
if (!vp->is_visible_subviewport()) {
if (!_is_usable_viewport(vp)) {
return;
}
parent_xform = Transform2D();
Expand Down Expand Up @@ -3998,7 +4059,11 @@ void CanvasItemEditor::_draw_viewport() {
transform = Transform2D();
transform.scale_basis(Size2(zoom, zoom));
transform.columns[2] = -view_offset * zoom;
EditorNode::get_singleton()->get_scene_root()->set_global_canvas_transform(transform);
if (_is_viewport_overridden()) {
scene_view_display->set_global_canvas_transform(transform);
} else {
current_viewport->set_global_canvas_transform(transform);
}

_draw_grid();
_draw_ruler_tool();
Expand Down Expand Up @@ -4054,6 +4119,7 @@ void CanvasItemEditor::_update_editor_settings() {
grid_snap_button->set_button_icon(get_editor_theme_icon(SNAME("SnapGrid")));
snap_config_menu->set_button_icon(get_editor_theme_icon(SNAME("GuiTabMenuHl")));
skeleton_menu->set_button_icon(get_editor_theme_icon(SNAME("Bone")));
override_viewport_button->set_button_icon(get_editor_theme_icon(SNAME("Viewport")));
pan_button->set_button_icon(get_editor_theme_icon(SNAME("ToolPan")));
ruler_button->set_button_icon(get_editor_theme_icon(SNAME("Ruler")));
pivot_button->set_button_icon(get_editor_theme_icon(SNAME("EditPivot")));
Expand Down Expand Up @@ -4084,7 +4150,7 @@ void CanvasItemEditor::_update_editor_settings() {
}

void CanvasItemEditor::_project_settings_changed() {
EditorNode::get_singleton()->get_scene_root()->set_snap_controls_to_pixels(GLOBAL_GET("gui/common/snap_controls_to_pixels"));
current_viewport->set_snap_controls_to_pixels(GLOBAL_GET("gui/common/snap_controls_to_pixels"));
}

void CanvasItemEditor::_notification(int p_what) {
Expand Down Expand Up @@ -4224,6 +4290,10 @@ void CanvasItemEditor::edit(CanvasItem *p_canvas_item) {
}
}

void CanvasItemEditor::edit_viewport(Viewport *p_viewport) {
_update_override_viewport_button(p_viewport);
}

void CanvasItemEditor::_update_scrollbars() {
updating_scroll = true;

Expand All @@ -4236,7 +4306,7 @@ void CanvasItemEditor::_update_scrollbars() {
Size2 vmin = v_scroll->get_minimum_size();

// Get the visible frame.
Size2 screen_rect = Size2(GLOBAL_GET("display/window/size/viewport_width"), GLOBAL_GET("display/window/size/viewport_height"));
Size2 screen_rect = _get_screen_size();
Rect2 local_rect = Rect2(Point2(), viewport->get_size() - Size2(vmin.width, hmin.height));

// Calculate scrollable area.
Expand Down Expand Up @@ -4347,6 +4417,17 @@ void CanvasItemEditor::_button_toggle_grid_snap(bool p_status) {
viewport->queue_redraw();
}

void CanvasItemEditor::_button_override_viewport(bool p_pressed) {
if (p_pressed) {
Viewport *vp = Object::cast_to<Viewport>(override_viewport_button->get_meta("viewport"));
_set_viewport_override(vp);
override_viewport_button->set_tooltip_text(TTR("Editor Viewport Override\nEditor viewport is overridden. Press to disable override."));
} else {
_set_viewport_override(nullptr);
override_viewport_button->set_tooltip_text(TTR("Editor Viewport Override\nMakes editor use selected SubViewport instead of the main viewport, allowing to edit nodes inside it."));
}
}

void CanvasItemEditor::_button_tool_select(int p_index) {
Button *tb[TOOL_MAX] = { select_button, list_select_button, move_button, scale_button, rotate_button, pivot_button, pan_button, ruler_button };
for (int i = 0; i < TOOL_MAX; i++) {
Expand Down Expand Up @@ -4384,7 +4465,7 @@ void CanvasItemEditor::_insert_animation_keys(bool p_location, bool p_rotation,
continue;
}

if (ci->get_viewport() != EditorNode::get_singleton()->get_scene_root()) {
if (ci->get_viewport() != current_viewport) {
continue;
}

Expand Down Expand Up @@ -4461,6 +4542,32 @@ void CanvasItemEditor::_prepare_view_menu() {
popup->set_item_disabled(popup->get_item_index(CLEAR_GUIDES), !has_guides);
}

void CanvasItemEditor::_update_override_viewport_button(Viewport *p_viewport) {
if (p_viewport) {
override_viewport_button->set_disabled(false);
if (p_viewport == current_viewport) {
override_viewport_button->set_pressed_no_signal(true);
override_viewport_button->set_tooltip_text(TTR("Editor Viewport Override\nEditor viewport is overridden. Press to disable override."));
} else {
override_viewport_button->set_pressed_no_signal(false);
override_viewport_button->set_meta(SNAME("viewport"), p_viewport);
override_viewport_button->set_tooltip_text(TTR("Editor Viewport Override\nMakes editor use selected SubViewport instead of the main viewport, allowing to edit nodes inside it."));
}

} else {
if (_is_viewport_overridden()) {
override_viewport_button->set_disabled(false);
override_viewport_button->set_pressed_no_signal(true);
override_viewport_button->set_tooltip_text(TTR("Editor Viewport Override\nEditor viewport is overridden. Press to disable override."));
} else {
override_viewport_button->set_disabled(true);
override_viewport_button->set_pressed_no_signal(false);
override_viewport_button->set_tooltip_text(TTR("Editor Viewport Override\nNo SubViewport node selected. Select one to allow overriding editor viewport."));
}
override_viewport_button->set_meta(SNAME("viewport"), Variant());
}
}

void CanvasItemEditor::_popup_callback(int p_op) {
EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
last_option = MenuOption(p_op);
Expand Down Expand Up @@ -4598,7 +4705,7 @@ void CanvasItemEditor::_popup_callback(int p_op) {
if (!ci || !ci->is_inside_tree()) {
continue;
}
if (ci->get_viewport() != EditorNode::get_singleton()->get_scene_root()) {
if (ci->get_viewport() != current_viewport) {
continue;
}

Expand All @@ -4620,7 +4727,7 @@ void CanvasItemEditor::_popup_callback(int p_op) {
if (!ci || !ci->is_inside_tree()) {
continue;
}
if (ci->get_viewport() != EditorNode::get_singleton()->get_scene_root()) {
if (ci->get_viewport() != current_viewport) {
continue;
}

Expand All @@ -4642,7 +4749,7 @@ void CanvasItemEditor::_popup_callback(int p_op) {
if (!ci || !ci->is_inside_tree()) {
continue;
}
if (ci->get_viewport() != EditorNode::get_singleton()->get_scene_root()) {
if (ci->get_viewport() != current_viewport) {
continue;
}

Expand All @@ -4664,7 +4771,7 @@ void CanvasItemEditor::_popup_callback(int p_op) {
if (!ci || !ci->is_inside_tree()) {
continue;
}
if (ci->get_viewport() != EditorNode::get_singleton()->get_scene_root()) {
if (ci->get_viewport() != current_viewport) {
continue;
}

Expand Down Expand Up @@ -4705,7 +4812,7 @@ void CanvasItemEditor::_popup_callback(int p_op) {
continue;
}

if (ci->get_viewport() != EditorNode::get_singleton()->get_scene_root()) {
if (ci->get_viewport() != current_viewport) {
continue;
}

Expand Down Expand Up @@ -4751,7 +4858,7 @@ void CanvasItemEditor::_popup_callback(int p_op) {
continue;
}

if (ci->get_viewport() != EditorNode::get_singleton()->get_scene_root()) {
if (ci->get_viewport() != current_viewport) {
continue;
}

Expand Down Expand Up @@ -5170,6 +5277,8 @@ void CanvasItemEditor::clear() {
snap_rotation_step = EditorSettings::get_singleton()->get_project_metadata("2d_editor", "snap_rotation_step", Math::deg_to_rad(15.0));
snap_rotation_offset = EditorSettings::get_singleton()->get_project_metadata("2d_editor", "snap_rotation_offset", 0.0);
snap_scale_step = EditorSettings::get_singleton()->get_project_metadata("2d_editor", "snap_scale_step", 0.1);

edit_viewport(nullptr);
}

void CanvasItemEditor::add_control_to_menu_panel(Control *p_control) {
Expand Down Expand Up @@ -5249,7 +5358,7 @@ void CanvasItemEditor::focus_selection() {
}

void CanvasItemEditor::center_at(const Point2 &p_pos) {
Vector2 offset = viewport->get_size() / 2 - EditorNode::get_singleton()->get_scene_root()->get_global_canvas_transform().xform(p_pos);
Vector2 offset = viewport->get_size() / 2 - current_viewport->get_global_canvas_transform().xform(p_pos);
view_offset -= (offset / zoom).round();
update_viewport();
}
Expand Down Expand Up @@ -5303,11 +5412,19 @@ CanvasItemEditor::CanvasItemEditor() {
viewport_scrollable->set_h_size_flags(Control::SIZE_EXPAND_FILL);
viewport_scrollable->connect(SceneStringName(draw), callable_mp(this, &CanvasItemEditor::_update_scrollbars));

SubViewportContainer *scene_tree = memnew(SubViewportContainer);
scene_tree = memnew(SubViewportContainer);
viewport_scrollable->add_child(scene_tree);
scene_tree->set_stretch(true);
scene_tree->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT);
scene_tree->add_child(EditorNode::get_singleton()->get_scene_root());
scene_tree->connect("item_rect_changed", callable_mp(this, &CanvasItemEditor::_update_viewport_size));

scene_view_display = memnew(SubViewport);
scene_tree->add_child(scene_view_display);

scene_view = memnew(TextureRect);
scene_view_display->add_child(scene_view);
scene_view->set_clip_contents(true);
scene_view->add_child(EditorNode::get_singleton()->get_scene_root());

controls_vb = memnew(VBoxContainer);
controls_vb->set_begin(Point2(5, 5));
Expand Down Expand Up @@ -5373,6 +5490,7 @@ CanvasItemEditor::CanvasItemEditor() {
viewport->connect(SceneStringName(draw), callable_mp(this, &CanvasItemEditor::_draw_viewport));
viewport->connect(SceneStringName(gui_input), callable_mp(this, &CanvasItemEditor::_gui_input_viewport));
viewport->connect(SceneStringName(focus_exited), callable_mp(panner.ptr(), &ViewPanner::release_pan_key));
_set_viewport_override(nullptr);

h_scroll = memnew(HScrollBar);
viewport->add_child(h_scroll);
Expand Down Expand Up @@ -5564,6 +5682,16 @@ CanvasItemEditor::CanvasItemEditor() {

main_menu_hbox->add_child(memnew(VSeparator));

override_viewport_button = memnew(Button);
override_viewport_button->set_theme_type_variation("FlatButton");
override_viewport_button->set_toggle_mode(true);
override_viewport_button->set_disabled(true);
main_menu_hbox->add_child(override_viewport_button);
override_viewport_button->connect(SceneStringName(toggled), callable_mp(this, &CanvasItemEditor::_button_override_viewport));
_update_override_viewport_button(nullptr);

main_menu_hbox->add_child(memnew(VSeparator));

view_menu = memnew(MenuButton);
view_menu->set_flat(false);
view_menu->set_theme_type_variation("FlatMenuButton");
Expand Down Expand Up @@ -5736,10 +5864,11 @@ CanvasItemEditor *CanvasItemEditor::singleton = nullptr;

void CanvasItemEditorPlugin::edit(Object *p_object) {
canvas_item_editor->edit(Object::cast_to<CanvasItem>(p_object));
canvas_item_editor->edit_viewport(Object::cast_to<Viewport>(p_object));
}

bool CanvasItemEditorPlugin::handles(Object *p_object) const {
return p_object->is_class("CanvasItem");
return Object::cast_to<CanvasItem>(p_object) || Object::cast_to<SubViewport>(p_object) || Object::cast_to<Window>(p_object);
}

void CanvasItemEditorPlugin::make_visible(bool p_visible) {
Expand Down
Loading