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

Improve the anchors and margin workflow #27559

Merged
merged 1 commit into from
May 20, 2019
Merged
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
1 change: 0 additions & 1 deletion editor/editor_settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -545,7 +545,6 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
_initial_set("editors/2d/bone_ik_color", Color(0.9, 0.9, 0.45, 0.9));
_initial_set("editors/2d/bone_outline_color", Color(0.35, 0.35, 0.35));
_initial_set("editors/2d/bone_outline_size", 2);
_initial_set("editors/2d/keep_margins_when_changing_anchors", false);
_initial_set("editors/2d/viewport_border_color", Color(0.4, 0.4, 1.0, 0.4));
_initial_set("editors/2d/warped_mouse_panning", true);
_initial_set("editors/2d/simple_spacebar_panning", false);
Expand Down
146 changes: 129 additions & 17 deletions editor/plugins/canvas_item_editor_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1387,7 +1387,7 @@ bool CanvasItemEditor::_gui_input_anchors(const Ref<InputEvent> &p_event) {

// Starts anchor dragging if needed
if (drag_type == DRAG_NONE) {
if (b.is_valid() && b->get_button_index() == BUTTON_LEFT && b->is_pressed() && tool == TOOL_SELECT && show_helpers) {
if (b.is_valid() && b->get_button_index() == BUTTON_LEFT && b->is_pressed() && tool == TOOL_SELECT) {
List<CanvasItem *> selection = _get_edited_canvas_items();
if (selection.size() == 1) {
Control *control = Object::cast_to<Control>(selection[0]);
Expand Down Expand Up @@ -2213,6 +2213,7 @@ bool CanvasItemEditor::_gui_input_hover(const Ref<InputEvent> &p_event) {

void CanvasItemEditor::_gui_input_viewport(const Ref<InputEvent> &p_event) {
bool accepted = false;

if (EditorSettings::get_singleton()->get("editors/2d/simple_spacebar_panning") || !Input::get_singleton()->is_key_pressed(KEY_SPACE)) {
if ((accepted = _gui_input_rulers_and_guides(p_event))) {
//printf("Rulers and guides\n");
Expand Down Expand Up @@ -2512,20 +2513,50 @@ void CanvasItemEditor::_draw_grid() {
}
}

void CanvasItemEditor::_draw_control_helpers(Control *control) {
void CanvasItemEditor::_draw_control_anchors(Control *control) {
Transform2D xform = transform * control->get_global_transform_with_canvas();
RID ci = viewport->get_canvas_item();
if (tool == TOOL_SELECT && !Object::cast_to<Container>(control->get_parent())) {

// Compute the anchors
float anchors_values[4];
anchors_values[0] = control->get_anchor(MARGIN_LEFT);
anchors_values[1] = control->get_anchor(MARGIN_TOP);
anchors_values[2] = control->get_anchor(MARGIN_RIGHT);
anchors_values[3] = control->get_anchor(MARGIN_BOTTOM);

Vector2 anchors_pos[4];
for (int i = 0; i < 4; i++) {
Vector2 value = Vector2((i % 2 == 0) ? anchors_values[i] : anchors_values[(i + 1) % 4], (i % 2 == 1) ? anchors_values[i] : anchors_values[(i + 1) % 4]);
anchors_pos[i] = xform.xform(_anchor_to_position(control, value));
}

// Draw the anchors handles
Rect2 anchor_rects[4];
anchor_rects[0] = Rect2(anchors_pos[0] - anchor_handle->get_size(), anchor_handle->get_size());
anchor_rects[1] = Rect2(anchors_pos[1] - Vector2(0.0, anchor_handle->get_size().y), Point2(-anchor_handle->get_size().x, anchor_handle->get_size().y));
anchor_rects[2] = Rect2(anchors_pos[2], -anchor_handle->get_size());
anchor_rects[3] = Rect2(anchors_pos[3] - Vector2(anchor_handle->get_size().x, 0.0), Point2(anchor_handle->get_size().x, -anchor_handle->get_size().y));

for (int i = 0; i < 4; i++) {
anchor_handle->draw_rect(ci, anchor_rects[i]);
}
}
}

void CanvasItemEditor::_draw_control_helpers(Control *control) {
Transform2D xform = transform * control->get_global_transform_with_canvas();
if (tool == TOOL_SELECT && show_helpers && !Object::cast_to<Container>(control->get_parent())) {
// Draw the helpers
Color color_base = Color(0.8, 0.8, 0.8, 0.5);

// Compute the anchors
float anchors_values[4];
anchors_values[0] = control->get_anchor(MARGIN_LEFT);
anchors_values[1] = control->get_anchor(MARGIN_TOP);
anchors_values[2] = control->get_anchor(MARGIN_RIGHT);
anchors_values[3] = control->get_anchor(MARGIN_BOTTOM);

// Draw the anchors
Vector2 anchors[4];
Vector2 anchors_pos[4];
for (int i = 0; i < 4; i++) {
Expand Down Expand Up @@ -2592,16 +2623,6 @@ void CanvasItemEditor::_draw_control_helpers(Control *control) {
_draw_percentage_at_position(percent_val, (line_ends[(dragged_anchor + 1) % 4] + anchors_pos[dragged_anchor]) / 2, (Margin)((dragged_anchor + 1) % 4));
}

Rect2 anchor_rects[4];
anchor_rects[0] = Rect2(anchors_pos[0] - anchor_handle->get_size(), anchor_handle->get_size());
anchor_rects[1] = Rect2(anchors_pos[1] - Vector2(0.0, anchor_handle->get_size().y), Point2(-anchor_handle->get_size().x, anchor_handle->get_size().y));
anchor_rects[2] = Rect2(anchors_pos[2], -anchor_handle->get_size());
anchor_rects[3] = Rect2(anchors_pos[3] - Vector2(anchor_handle->get_size().x, 0.0), Point2(anchor_handle->get_size().x, -anchor_handle->get_size().y));

for (int i = 0; i < 4; i++) {
anchor_handle->draw_rect(ci, anchor_rects[i]);
}

// Draw the margin values and the node width/height when dragging control side
float ratio = 0.33;
Transform2D parent_transform = xform * control->get_transform().affine_inverse();
Expand Down Expand Up @@ -2779,6 +2800,7 @@ void CanvasItemEditor::_draw_selection() {
// Draw control-related helpers
Control *control = Object::cast_to<Control>(canvas_item);
if (control && _is_node_movable(control)) {
_draw_control_anchors(control);
_draw_control_helpers(control);
}

Expand Down Expand Up @@ -3311,24 +3333,32 @@ void CanvasItemEditor::_notification(int p_what) {
// Activate / Deactivate the pivot tool
pivot_button->set_disabled(nb_having_pivot == 0);

// Show / Hide the layout button
// Show / Hide the layout and anchors mode buttons
if (nb_control > 0 && nb_control == selection.size()) {
presets_menu->set_visible(true);
presets_menu->set_tooltip(TTR("Presets for the anchors and margins values of a Control node."));
anchor_mode_button->set_visible(true);
anchor_mode_button->set_tooltip(TTR("When active, moving Control nodes changes their anchors instead of their margins."));

// Set the pressed state of the node
anchor_mode_button->set_pressed(anchors_mode);

// Disable if the selected node is child of a container
presets_menu->set_disabled(false);
anchor_mode_button->set_disabled(false);
for (List<CanvasItem *>::Element *E = selection.front(); E; E = E->next()) {
Control *control = Object::cast_to<Control>(E->get());
if (!control || Object::cast_to<Container>(control->get_parent())) {
presets_menu->set_disabled(true);
presets_menu->set_tooltip(TTR("Children of containers have their anchors and margins values overridden by their parent."));
anchor_mode_button->set_disabled(true);
anchor_mode_button->set_tooltip(TTR("Children of containers have their anchors and margins values overridden by their parent."));
break;
}
}

} else {
presets_menu->set_visible(false);
anchor_mode_button->set_visible(false);
}

// Update the viewport if bones changes
Expand Down Expand Up @@ -3436,9 +3466,10 @@ void CanvasItemEditor::_notification(int p_what) {
p->add_icon_item(get_icon("ControlHcenterWide", "EditorIcons"), "HCenter Wide ", ANCHORS_AND_MARGINS_PRESET_HCENTER_WIDE);
p->add_separator();
p->add_icon_item(get_icon("ControlAlignWide", "EditorIcons"), "Full Rect", ANCHORS_AND_MARGINS_PRESET_WIDE);
p->add_icon_item(get_icon("Anchor", "EditorIcons"), "Keep Ratio", ANCHORS_AND_MARGINS_PRESET_KEEP_RATIO);
p->add_separator();
p->add_submenu_item(TTR("Anchors Only"), "Anchors");
p->set_item_icon(20, get_icon("Anchor", "EditorIcons"));
p->add_submenu_item(TTR("Anchors only"), "Anchors");
p->set_item_icon(21, get_icon("Anchor", "EditorIcons"));

anchors_popup->clear();
anchors_popup->add_icon_item(get_icon("ControlAlignTopLeft", "EditorIcons"), "Top Left", ANCHORS_PRESET_TOP_LEFT);
Expand All @@ -3460,9 +3491,31 @@ void CanvasItemEditor::_notification(int p_what) {
anchors_popup->add_icon_item(get_icon("ControlHcenterWide", "EditorIcons"), "HCenter Wide ", ANCHORS_PRESET_HCENTER_WIDE);
anchors_popup->add_separator();
anchors_popup->add_icon_item(get_icon("ControlAlignWide", "EditorIcons"), "Full Rect", ANCHORS_PRESET_WIDE);

anchor_mode_button->set_icon(get_icon("Anchor", "EditorIcons"));
}
}

void CanvasItemEditor::_selection_changed() {
// Update the anchors_mode
int nbValidControls = 0;
int nbAnchorsMode = 0;
List<Node *> selection = editor_selection->get_selected_node_list();
for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
Control *control = Object::cast_to<Control>(E->get());
if (!control)
continue;
if (Object::cast_to<Container>(control->get_parent()))
continue;

nbValidControls++;
if (control->has_meta("_edit_use_anchors_") && control->get_meta("_edit_use_anchors_")) {
nbAnchorsMode++;
}
}
anchors_mode = (nbValidControls == nbAnchorsMode);
}

void CanvasItemEditor::edit(CanvasItem *p_canvas_item) {

Array selection = editor_selection->get_selected_nodes();
Expand Down Expand Up @@ -3680,6 +3733,36 @@ void CanvasItemEditor::_set_anchors_and_margins_preset(Control::LayoutPreset p_p
}

undo_redo->commit_action();

anchors_mode = false;
}

void CanvasItemEditor::_set_anchors_and_margins_to_keep_ratio() {
List<Node *> selection = editor_selection->get_selected_node_list();

undo_redo->create_action(TTR("Change Anchors and Margins"));

for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {

Control *control = Object::cast_to<Control>(E->get());
if (control) {
Point2 top_left_anchor = _position_to_anchor(control, Point2());
Point2 bottom_right_anchor = _position_to_anchor(control, control->get_size());
undo_redo->add_do_method(control, "set_anchor", MARGIN_LEFT, top_left_anchor.x, false, true);
undo_redo->add_do_method(control, "set_anchor", MARGIN_RIGHT, bottom_right_anchor.x, false, true);
undo_redo->add_do_method(control, "set_anchor", MARGIN_TOP, top_left_anchor.y, false, true);
undo_redo->add_do_method(control, "set_anchor", MARGIN_BOTTOM, bottom_right_anchor.y, false, true);
undo_redo->add_do_method(control, "set_meta", "_edit_use_anchors_", true);

bool use_anchors = control->has_meta("_edit_use_anchors_") && control->get_meta("_edit_use_anchors_");
undo_redo->add_undo_method(control, "_edit_set_state", control->_edit_get_state());
undo_redo->add_undo_method(control, "set_meta", "_edit_use_anchors_", use_anchors);

anchors_mode = true;
}
}

undo_redo->commit_action();
}

void CanvasItemEditor::_set_anchors_preset(Control::LayoutPreset p_preset) {
Expand Down Expand Up @@ -3811,6 +3894,21 @@ void CanvasItemEditor::_insert_animation_keys(bool p_location, bool p_rotation,
}
}

void CanvasItemEditor::_button_toggle_anchor_mode(bool p_status) {
List<CanvasItem *> selection = _get_edited_canvas_items(false, false);
for (List<CanvasItem *>::Element *E = selection.front(); E; E = E->next()) {
Control *control = Object::cast_to<Control>(E->get());
if (!control || Object::cast_to<Container>(control->get_parent()))
continue;

control->set_meta("_edit_use_anchors_", p_status);
}

anchors_mode = p_status;

viewport->update();
}

void CanvasItemEditor::_popup_callback(int p_op) {

last_option = MenuOption(p_op);
Expand Down Expand Up @@ -4047,6 +4145,9 @@ void CanvasItemEditor::_popup_callback(int p_op) {
case ANCHORS_AND_MARGINS_PRESET_WIDE: {
_set_anchors_and_margins_preset(Control::PRESET_WIDE);
} break;
case ANCHORS_AND_MARGINS_PRESET_KEEP_RATIO: {
_set_anchors_and_margins_to_keep_ratio();
} break;

case ANCHORS_PRESET_TOP_LEFT: {
_set_anchors_preset(PRESET_TOP_LEFT);
Expand Down Expand Up @@ -4366,6 +4467,7 @@ void CanvasItemEditor::_bind_methods() {
ClassDB::bind_method("_button_zoom_reset", &CanvasItemEditor::_button_zoom_reset);
ClassDB::bind_method("_button_zoom_plus", &CanvasItemEditor::_button_zoom_plus);
ClassDB::bind_method("_button_toggle_snap", &CanvasItemEditor::_button_toggle_snap);
ClassDB::bind_method("_button_toggle_anchor_mode", &CanvasItemEditor::_button_toggle_anchor_mode);
ClassDB::bind_method("_update_scroll", &CanvasItemEditor::_update_scroll);
ClassDB::bind_method("_update_scrollbars", &CanvasItemEditor::_update_scrollbars);
ClassDB::bind_method("_popup_callback", &CanvasItemEditor::_popup_callback);
Expand All @@ -4378,6 +4480,7 @@ void CanvasItemEditor::_bind_methods() {
ClassDB::bind_method("_snap_changed", &CanvasItemEditor::_snap_changed);
ClassDB::bind_method("_update_bone_list", &CanvasItemEditor::_update_bone_list);
ClassDB::bind_method("_tree_changed", &CanvasItemEditor::_tree_changed);
ClassDB::bind_method("_selection_changed", &CanvasItemEditor::_selection_changed);
ClassDB::bind_method("_popup_warning_depop", &CanvasItemEditor::_popup_warning_depop);
ClassDB::bind_method(D_METHOD("_selection_result_pressed"), &CanvasItemEditor::_selection_result_pressed);
ClassDB::bind_method(D_METHOD("_selection_menu_hide"), &CanvasItemEditor::_selection_menu_hide);
Expand Down Expand Up @@ -4636,6 +4739,8 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
snap_relative = false;
snap_pixel = false;

anchors_mode = false;

skeleton_show_bones = true;

drag_type = DRAG_NONE;
Expand All @@ -4654,6 +4759,7 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
editor_selection = p_editor->get_editor_selection();
editor_selection->add_editor_plugin(this);
editor_selection->connect("selection_changed", this, "update");
editor_selection->connect("selection_changed", this, "_selection_changed");

hb = memnew(HBoxContainer);
add_child(hb);
Expand Down Expand Up @@ -4913,6 +5019,12 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
anchors_popup->set_name("Anchors");
anchors_popup->connect("id_pressed", this, "_popup_callback");

anchor_mode_button = memnew(ToolButton);
hb->add_child(anchor_mode_button);
anchor_mode_button->set_toggle_mode(true);
anchor_mode_button->hide();
anchor_mode_button->connect("toggled", this, "_button_toggle_anchor_mode");

animation_hb = memnew(HBoxContainer);
hb->add_child(animation_hb);
animation_hb->add_child(memnew(VSeparator));
Expand Down
13 changes: 13 additions & 0 deletions editor/plugins/canvas_item_editor_plugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ class CanvasItemEditor : public VBoxContainer {
ANCHORS_AND_MARGINS_PRESET_VCENTER_WIDE,
ANCHORS_AND_MARGINS_PRESET_HCENTER_WIDE,
ANCHORS_AND_MARGINS_PRESET_WIDE,
ANCHORS_AND_MARGINS_PRESET_KEEP_RATIO,
ANCHORS_PRESET_TOP_LEFT,
ANCHORS_PRESET_TOP_RIGHT,
ANCHORS_PRESET_BOTTOM_LEFT,
Expand Down Expand Up @@ -240,6 +241,8 @@ class CanvasItemEditor : public VBoxContainer {
Point2 view_offset;
Point2 previous_update_view_offset;

bool anchors_mode;

Point2 grid_offset;
Point2 grid_step;
int grid_step_multiplier;
Expand Down Expand Up @@ -347,6 +350,8 @@ class CanvasItemEditor : public VBoxContainer {
PopupMenu *anchors_and_margins_popup;
PopupMenu *anchors_popup;

ToolButton *anchor_mode_button;

Button *key_loc_button;
Button *key_rot_button;
Button *key_scale_button;
Expand Down Expand Up @@ -438,6 +443,7 @@ class CanvasItemEditor : public VBoxContainer {
void _draw_guides();
void _draw_focus();
void _draw_grid();
void _draw_control_anchors(Control *control);
void _draw_control_helpers(Control *control);
void _draw_selection();
void _draw_axis();
Expand All @@ -462,6 +468,8 @@ class CanvasItemEditor : public VBoxContainer {

void _gui_input_viewport(const Ref<InputEvent> &p_event);

void _selection_changed();

void _focus_selection(int p_op);

void _solve_IK(Node2D *leaf_node, Point2 target_position);
Expand All @@ -473,6 +481,9 @@ class CanvasItemEditor : public VBoxContainer {
void _set_anchors_preset(Control::LayoutPreset p_preset);
void _set_margins_preset(Control::LayoutPreset p_preset);
void _set_anchors_and_margins_preset(Control::LayoutPreset p_preset);
void _set_anchors_and_margins_to_keep_ratio();

void _button_toggle_anchor_mode(bool p_status);

HBoxContainer *zoom_hb;
void _zoom_on_position(float p_zoom, Point2 p_position = Point2());
Expand Down Expand Up @@ -575,6 +586,8 @@ class CanvasItemEditor : public VBoxContainer {

void focus_selection();

bool is_anchors_mode_enabled() { return anchors_mode; };

CanvasItemEditor(EditorNode *p_editor);
};

Expand Down
Loading