Skip to content

Commit

Permalink
Merge pull request #27559 from groud/anchor_mode
Browse files Browse the repository at this point in the history
Improve the anchors and margin workflow
  • Loading branch information
akien-mga authored May 20, 2019
2 parents 9e214ad + e875f05 commit 79cc95c
Show file tree
Hide file tree
Showing 5 changed files with 235 additions and 63 deletions.
1 change: 0 additions & 1 deletion editor/editor_settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -546,7 +546,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

0 comments on commit 79cc95c

Please sign in to comment.