mirror of
https://github.com/godotengine/godot
synced 2024-09-05 18:19:34 +00:00
Improve the anchors and margin workflow
This commit is contained in:
parent
86a74e2cb3
commit
e875f05c3b
|
@ -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);
|
||||
|
|
|
@ -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]);
|
||||
|
@ -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");
|
||||
|
@ -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 && show_helpers && !Object::cast_to<Container>(control->get_parent())) {
|
||||
// Draw the helpers
|
||||
Color color_base = Color(0.8, 0.8, 0.8, 0.5);
|
||||
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++) {
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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));
|
||||
|
|
|
@ -129,6 +129,7 @@ private:
|
|||
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,
|
||||
|
@ -240,6 +241,8 @@ private:
|
|||
Point2 view_offset;
|
||||
Point2 previous_update_view_offset;
|
||||
|
||||
bool anchors_mode;
|
||||
|
||||
Point2 grid_offset;
|
||||
Point2 grid_step;
|
||||
int grid_step_multiplier;
|
||||
|
@ -347,6 +350,8 @@ private:
|
|||
PopupMenu *anchors_and_margins_popup;
|
||||
PopupMenu *anchors_popup;
|
||||
|
||||
ToolButton *anchor_mode_button;
|
||||
|
||||
Button *key_loc_button;
|
||||
Button *key_rot_button;
|
||||
Button *key_scale_button;
|
||||
|
@ -438,6 +443,7 @@ private:
|
|||
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();
|
||||
|
@ -462,6 +468,8 @@ private:
|
|||
|
||||
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);
|
||||
|
@ -473,6 +481,9 @@ private:
|
|||
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());
|
||||
|
@ -575,6 +586,8 @@ public:
|
|||
|
||||
void focus_selection();
|
||||
|
||||
bool is_anchors_mode_enabled() { return anchors_mode; };
|
||||
|
||||
CanvasItemEditor(EditorNode *p_editor);
|
||||
};
|
||||
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
#include "scene/scene_string_names.h"
|
||||
#ifdef TOOLS_ENABLED
|
||||
#include "editor/editor_settings.h"
|
||||
#include "editor/plugins/canvas_item_editor_plugin.h"
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
|
||||
|
@ -66,6 +67,7 @@ Dictionary Control::_edit_get_state() const {
|
|||
s["margins"] = margins;
|
||||
return s;
|
||||
}
|
||||
|
||||
void Control::_edit_set_state(const Dictionary &p_state) {
|
||||
|
||||
Dictionary state = p_state;
|
||||
|
@ -87,7 +89,12 @@ void Control::_edit_set_state(const Dictionary &p_state) {
|
|||
}
|
||||
|
||||
void Control::_edit_set_position(const Point2 &p_position) {
|
||||
#ifdef TOOLS_ENABLED
|
||||
set_position(p_position, CanvasItemEditor::get_singleton()->is_anchors_mode_enabled());
|
||||
#else
|
||||
// Unlikely to happen. TODO: enclose all _edit_ functions into TOOLS_ENABLED
|
||||
set_position(p_position);
|
||||
#endif
|
||||
};
|
||||
|
||||
Point2 Control::_edit_get_position() const {
|
||||
|
@ -103,8 +110,14 @@ Size2 Control::_edit_get_scale() const {
|
|||
}
|
||||
|
||||
void Control::_edit_set_rect(const Rect2 &p_edit_rect) {
|
||||
#ifdef TOOLS_ENABLED
|
||||
set_position((get_position() + get_transform().basis_xform(p_edit_rect.position)).snapped(Vector2(1, 1)), CanvasItemEditor::get_singleton()->is_anchors_mode_enabled());
|
||||
set_size(p_edit_rect.size.snapped(Vector2(1, 1)), CanvasItemEditor::get_singleton()->is_anchors_mode_enabled());
|
||||
#else
|
||||
// Unlikely to happen. TODO: enclose all _edit_ functions into TOOLS_ENABLED
|
||||
set_position((get_position() + get_transform().basis_xform(p_edit_rect.position)).snapped(Vector2(1, 1)));
|
||||
set_size(p_edit_rect.size.snapped(Vector2(1, 1)));
|
||||
#endif
|
||||
}
|
||||
|
||||
Rect2 Control::_edit_get_rect() const {
|
||||
|
@ -1366,7 +1379,7 @@ void Control::set_anchor(Margin p_margin, float p_anchor, bool p_keep_margin, bo
|
|||
float previous_margin_pos = data.margin[p_margin] + data.anchor[p_margin] * parent_range;
|
||||
float previous_opposite_margin_pos = data.margin[(p_margin + 2) % 4] + data.anchor[(p_margin + 2) % 4] * parent_range;
|
||||
|
||||
data.anchor[p_margin] = CLAMP(p_anchor, 0.0, 1.0);
|
||||
data.anchor[p_margin] = p_anchor;
|
||||
|
||||
if (((p_margin == MARGIN_LEFT || p_margin == MARGIN_TOP) && data.anchor[p_margin] > data.anchor[(p_margin + 2) % 4]) ||
|
||||
((p_margin == MARGIN_RIGHT || p_margin == MARGIN_BOTTOM) && data.anchor[p_margin] < data.anchor[(p_margin + 2) % 4])) {
|
||||
|
@ -1395,15 +1408,7 @@ void Control::set_anchor(Margin p_margin, float p_anchor, bool p_keep_margin, bo
|
|||
}
|
||||
|
||||
void Control::_set_anchor(Margin p_margin, float p_anchor) {
|
||||
#ifdef TOOLS_ENABLED
|
||||
if (is_inside_tree() && Engine::get_singleton()->is_editor_hint()) {
|
||||
set_anchor(p_margin, p_anchor, EDITOR_DEF("editors/2d/keep_margins_when_changing_anchors", false));
|
||||
} else {
|
||||
set_anchor(p_margin, p_anchor, false);
|
||||
}
|
||||
#else
|
||||
set_anchor(p_margin, p_anchor, false);
|
||||
#endif
|
||||
set_anchor(p_margin, p_anchor);
|
||||
}
|
||||
|
||||
void Control::set_anchor_and_margin(Margin p_margin, float p_anchor, float p_pos, bool p_push_opposite_anchor) {
|
||||
|
@ -1412,7 +1417,7 @@ void Control::set_anchor_and_margin(Margin p_margin, float p_anchor, float p_pos
|
|||
set_margin(p_margin, p_pos);
|
||||
}
|
||||
|
||||
void Control::set_anchors_preset(LayoutPreset p_preset, bool p_keep_margin) {
|
||||
void Control::set_anchors_preset(LayoutPreset p_preset, bool p_keep_margins) {
|
||||
//Left
|
||||
switch (p_preset) {
|
||||
case PRESET_TOP_LEFT:
|
||||
|
@ -1423,21 +1428,21 @@ void Control::set_anchors_preset(LayoutPreset p_preset, bool p_keep_margin) {
|
|||
case PRESET_LEFT_WIDE:
|
||||
case PRESET_HCENTER_WIDE:
|
||||
case PRESET_WIDE:
|
||||
set_anchor(MARGIN_LEFT, ANCHOR_BEGIN, p_keep_margin);
|
||||
set_anchor(MARGIN_LEFT, ANCHOR_BEGIN, p_keep_margins);
|
||||
break;
|
||||
|
||||
case PRESET_CENTER_TOP:
|
||||
case PRESET_CENTER_BOTTOM:
|
||||
case PRESET_CENTER:
|
||||
case PRESET_VCENTER_WIDE:
|
||||
set_anchor(MARGIN_LEFT, 0.5, p_keep_margin);
|
||||
set_anchor(MARGIN_LEFT, 0.5, p_keep_margins);
|
||||
break;
|
||||
|
||||
case PRESET_TOP_RIGHT:
|
||||
case PRESET_BOTTOM_RIGHT:
|
||||
case PRESET_CENTER_RIGHT:
|
||||
case PRESET_RIGHT_WIDE:
|
||||
set_anchor(MARGIN_LEFT, ANCHOR_END, p_keep_margin);
|
||||
set_anchor(MARGIN_LEFT, ANCHOR_END, p_keep_margins);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1451,21 +1456,21 @@ void Control::set_anchors_preset(LayoutPreset p_preset, bool p_keep_margin) {
|
|||
case PRESET_TOP_WIDE:
|
||||
case PRESET_VCENTER_WIDE:
|
||||
case PRESET_WIDE:
|
||||
set_anchor(MARGIN_TOP, ANCHOR_BEGIN, p_keep_margin);
|
||||
set_anchor(MARGIN_TOP, ANCHOR_BEGIN, p_keep_margins);
|
||||
break;
|
||||
|
||||
case PRESET_CENTER_LEFT:
|
||||
case PRESET_CENTER_RIGHT:
|
||||
case PRESET_CENTER:
|
||||
case PRESET_HCENTER_WIDE:
|
||||
set_anchor(MARGIN_TOP, 0.5, p_keep_margin);
|
||||
set_anchor(MARGIN_TOP, 0.5, p_keep_margins);
|
||||
break;
|
||||
|
||||
case PRESET_BOTTOM_LEFT:
|
||||
case PRESET_BOTTOM_RIGHT:
|
||||
case PRESET_CENTER_BOTTOM:
|
||||
case PRESET_BOTTOM_WIDE:
|
||||
set_anchor(MARGIN_TOP, ANCHOR_END, p_keep_margin);
|
||||
set_anchor(MARGIN_TOP, ANCHOR_END, p_keep_margins);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1475,14 +1480,14 @@ void Control::set_anchors_preset(LayoutPreset p_preset, bool p_keep_margin) {
|
|||
case PRESET_BOTTOM_LEFT:
|
||||
case PRESET_CENTER_LEFT:
|
||||
case PRESET_LEFT_WIDE:
|
||||
set_anchor(MARGIN_RIGHT, ANCHOR_BEGIN, p_keep_margin);
|
||||
set_anchor(MARGIN_RIGHT, ANCHOR_BEGIN, p_keep_margins);
|
||||
break;
|
||||
|
||||
case PRESET_CENTER_TOP:
|
||||
case PRESET_CENTER_BOTTOM:
|
||||
case PRESET_CENTER:
|
||||
case PRESET_VCENTER_WIDE:
|
||||
set_anchor(MARGIN_RIGHT, 0.5, p_keep_margin);
|
||||
set_anchor(MARGIN_RIGHT, 0.5, p_keep_margins);
|
||||
break;
|
||||
|
||||
case PRESET_TOP_RIGHT:
|
||||
|
@ -1493,7 +1498,7 @@ void Control::set_anchors_preset(LayoutPreset p_preset, bool p_keep_margin) {
|
|||
case PRESET_BOTTOM_WIDE:
|
||||
case PRESET_HCENTER_WIDE:
|
||||
case PRESET_WIDE:
|
||||
set_anchor(MARGIN_RIGHT, ANCHOR_END, p_keep_margin);
|
||||
set_anchor(MARGIN_RIGHT, ANCHOR_END, p_keep_margins);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1503,14 +1508,14 @@ void Control::set_anchors_preset(LayoutPreset p_preset, bool p_keep_margin) {
|
|||
case PRESET_TOP_RIGHT:
|
||||
case PRESET_CENTER_TOP:
|
||||
case PRESET_TOP_WIDE:
|
||||
set_anchor(MARGIN_BOTTOM, ANCHOR_BEGIN, p_keep_margin);
|
||||
set_anchor(MARGIN_BOTTOM, ANCHOR_BEGIN, p_keep_margins);
|
||||
break;
|
||||
|
||||
case PRESET_CENTER_LEFT:
|
||||
case PRESET_CENTER_RIGHT:
|
||||
case PRESET_CENTER:
|
||||
case PRESET_HCENTER_WIDE:
|
||||
set_anchor(MARGIN_BOTTOM, 0.5, p_keep_margin);
|
||||
set_anchor(MARGIN_BOTTOM, 0.5, p_keep_margins);
|
||||
break;
|
||||
|
||||
case PRESET_BOTTOM_LEFT:
|
||||
|
@ -1521,7 +1526,7 @@ void Control::set_anchors_preset(LayoutPreset p_preset, bool p_keep_margin) {
|
|||
case PRESET_BOTTOM_WIDE:
|
||||
case PRESET_VCENTER_WIDE:
|
||||
case PRESET_WIDE:
|
||||
set_anchor(MARGIN_BOTTOM, ANCHOR_END, p_keep_margin);
|
||||
set_anchor(MARGIN_BOTTOM, ANCHOR_END, p_keep_margins);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1714,7 +1719,11 @@ Point2 Control::get_global_position() const {
|
|||
return get_global_transform().get_origin();
|
||||
}
|
||||
|
||||
void Control::set_global_position(const Point2 &p_point) {
|
||||
void Control::_set_global_position(const Point2 &p_point) {
|
||||
set_global_position(p_point);
|
||||
}
|
||||
|
||||
void Control::set_global_position(const Point2 &p_point, bool p_keep_margins) {
|
||||
|
||||
Transform2D inv;
|
||||
|
||||
|
@ -1723,7 +1732,7 @@ void Control::set_global_position(const Point2 &p_point) {
|
|||
inv = data.parent_canvas_item->get_global_transform().affine_inverse();
|
||||
}
|
||||
|
||||
set_position(inv.xform(p_point));
|
||||
set_position(inv.xform(p_point), p_keep_margins);
|
||||
}
|
||||
|
||||
Rect2 Control::_compute_child_rect(const float p_anchors[4], const float p_margins[4]) const {
|
||||
|
@ -1737,6 +1746,15 @@ Rect2 Control::_compute_child_rect(const float p_anchors[4], const float p_margi
|
|||
return result;
|
||||
}
|
||||
|
||||
void Control::_compute_anchors(Rect2 p_rect, const float p_margins[4], float (&r_anchors)[4]) {
|
||||
|
||||
Size2 parent_rect_size = get_parent_anchorable_rect().size;
|
||||
r_anchors[0] = (p_rect.position.x - p_margins[0]) / parent_rect_size.x;
|
||||
r_anchors[1] = (p_rect.position.y - p_margins[1]) / parent_rect_size.y;
|
||||
r_anchors[2] = (p_rect.position.x + p_rect.size.x - p_margins[2]) / parent_rect_size.x;
|
||||
r_anchors[3] = (p_rect.position.y + p_rect.size.y - p_margins[3]) / parent_rect_size.y;
|
||||
}
|
||||
|
||||
void Control::_compute_margins(Rect2 p_rect, const float p_anchors[4], float (&r_margins)[4]) {
|
||||
|
||||
Size2 parent_rect_size = get_parent_anchorable_rect().size;
|
||||
|
@ -1746,13 +1764,28 @@ void Control::_compute_margins(Rect2 p_rect, const float p_anchors[4], float (&r
|
|||
r_margins[3] = p_rect.position.y + p_rect.size.y - (p_anchors[3] * parent_rect_size.y);
|
||||
}
|
||||
|
||||
void Control::set_position(const Size2 &p_point) {
|
||||
void Control::_set_position(const Size2 &p_point) {
|
||||
set_position(p_point);
|
||||
}
|
||||
|
||||
_compute_margins(Rect2(p_point, data.size_cache), data.anchor, data.margin);
|
||||
void Control::set_position(const Size2 &p_point, bool p_keep_margins) {
|
||||
if (p_keep_margins) {
|
||||
_compute_anchors(Rect2(p_point, data.size_cache), data.margin, data.anchor);
|
||||
_change_notify("anchor_left");
|
||||
_change_notify("anchor_right");
|
||||
_change_notify("anchor_top");
|
||||
_change_notify("anchor_bottom");
|
||||
} else {
|
||||
_compute_margins(Rect2(p_point, data.size_cache), data.anchor, data.margin);
|
||||
}
|
||||
_size_changed();
|
||||
}
|
||||
|
||||
void Control::set_size(const Size2 &p_size) {
|
||||
void Control::_set_size(const Size2 &p_size) {
|
||||
set_size(p_size);
|
||||
}
|
||||
|
||||
void Control::set_size(const Size2 &p_size, bool p_keep_margins) {
|
||||
|
||||
Size2 new_size = p_size;
|
||||
Size2 min = get_combined_minimum_size();
|
||||
|
@ -1761,7 +1794,15 @@ void Control::set_size(const Size2 &p_size) {
|
|||
if (new_size.y < min.y)
|
||||
new_size.y = min.y;
|
||||
|
||||
_compute_margins(Rect2(data.pos_cache, new_size), data.anchor, data.margin);
|
||||
if (p_keep_margins) {
|
||||
_compute_anchors(Rect2(data.pos_cache, new_size), data.margin, data.anchor);
|
||||
_change_notify("anchor_left");
|
||||
_change_notify("anchor_right");
|
||||
_change_notify("anchor_top");
|
||||
_change_notify("anchor_bottom");
|
||||
} else {
|
||||
_compute_margins(Rect2(data.pos_cache, new_size), data.anchor, data.margin);
|
||||
}
|
||||
_size_changed();
|
||||
}
|
||||
|
||||
|
@ -2702,20 +2743,23 @@ void Control::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("accept_event"), &Control::accept_event);
|
||||
ClassDB::bind_method(D_METHOD("get_minimum_size"), &Control::get_minimum_size);
|
||||
ClassDB::bind_method(D_METHOD("get_combined_minimum_size"), &Control::get_combined_minimum_size);
|
||||
ClassDB::bind_method(D_METHOD("set_anchors_preset", "preset", "keep_margin"), &Control::set_anchors_preset, DEFVAL(false));
|
||||
ClassDB::bind_method(D_METHOD("set_anchors_preset", "preset", "keep_margins"), &Control::set_anchors_preset, DEFVAL(false));
|
||||
ClassDB::bind_method(D_METHOD("set_margins_preset", "preset", "resize_mode", "margin"), &Control::set_margins_preset, DEFVAL(PRESET_MODE_MINSIZE), DEFVAL(0));
|
||||
ClassDB::bind_method(D_METHOD("set_anchors_and_margins_preset", "preset", "resize_mode", "margin"), &Control::set_anchors_and_margins_preset, DEFVAL(PRESET_MODE_MINSIZE), DEFVAL(0));
|
||||
ClassDB::bind_method(D_METHOD("set_anchor", "margin", "anchor", "keep_margin", "push_opposite_anchor"), &Control::set_anchor, DEFVAL(false), DEFVAL(true));
|
||||
ClassDB::bind_method(D_METHOD("_set_anchor", "margin", "anchor"), &Control::_set_anchor);
|
||||
ClassDB::bind_method(D_METHOD("set_anchor", "margin", "anchor", "keep_margin", "push_opposite_anchor"), &Control::set_anchor, DEFVAL(false), DEFVAL(true));
|
||||
ClassDB::bind_method(D_METHOD("get_anchor", "margin"), &Control::get_anchor);
|
||||
ClassDB::bind_method(D_METHOD("set_margin", "margin", "offset"), &Control::set_margin);
|
||||
ClassDB::bind_method(D_METHOD("set_anchor_and_margin", "margin", "anchor", "offset", "push_opposite_anchor"), &Control::set_anchor_and_margin, DEFVAL(false));
|
||||
ClassDB::bind_method(D_METHOD("set_begin", "position"), &Control::set_begin);
|
||||
ClassDB::bind_method(D_METHOD("set_end", "position"), &Control::set_end);
|
||||
ClassDB::bind_method(D_METHOD("set_position", "position"), &Control::set_position);
|
||||
ClassDB::bind_method(D_METHOD("set_size", "size"), &Control::set_size);
|
||||
ClassDB::bind_method(D_METHOD("set_position", "position", "keep_margins"), &Control::set_position, DEFVAL(false));
|
||||
ClassDB::bind_method(D_METHOD("_set_position", "margin"), &Control::_set_position);
|
||||
ClassDB::bind_method(D_METHOD("set_size", "size", "keep_margins"), &Control::set_size, DEFVAL(false));
|
||||
ClassDB::bind_method(D_METHOD("_set_size", "size"), &Control::_set_size);
|
||||
ClassDB::bind_method(D_METHOD("set_custom_minimum_size", "size"), &Control::set_custom_minimum_size);
|
||||
ClassDB::bind_method(D_METHOD("set_global_position", "position"), &Control::set_global_position);
|
||||
ClassDB::bind_method(D_METHOD("set_global_position", "position", "keep_margins"), &Control::set_global_position, DEFVAL(false));
|
||||
ClassDB::bind_method(D_METHOD("_set_global_position", "position"), &Control::_set_global_position);
|
||||
ClassDB::bind_method(D_METHOD("set_rotation", "radians"), &Control::set_rotation);
|
||||
ClassDB::bind_method(D_METHOD("set_rotation_degrees", "degrees"), &Control::set_rotation_degrees);
|
||||
ClassDB::bind_method(D_METHOD("set_scale", "scale"), &Control::set_scale);
|
||||
|
@ -2835,10 +2879,10 @@ void Control::_bind_methods() {
|
|||
BIND_VMETHOD(MethodInfo(Variant::BOOL, "_clips_input"));
|
||||
|
||||
ADD_GROUP("Anchor", "anchor_");
|
||||
ADD_PROPERTYI(PropertyInfo(Variant::REAL, "anchor_left", PROPERTY_HINT_RANGE, "0,1,0.01"), "_set_anchor", "get_anchor", MARGIN_LEFT);
|
||||
ADD_PROPERTYI(PropertyInfo(Variant::REAL, "anchor_top", PROPERTY_HINT_RANGE, "0,1,0.01"), "_set_anchor", "get_anchor", MARGIN_TOP);
|
||||
ADD_PROPERTYI(PropertyInfo(Variant::REAL, "anchor_right", PROPERTY_HINT_RANGE, "0,1,0.01"), "_set_anchor", "get_anchor", MARGIN_RIGHT);
|
||||
ADD_PROPERTYI(PropertyInfo(Variant::REAL, "anchor_bottom", PROPERTY_HINT_RANGE, "0,1,0.01"), "_set_anchor", "get_anchor", MARGIN_BOTTOM);
|
||||
ADD_PROPERTYI(PropertyInfo(Variant::REAL, "anchor_left", PROPERTY_HINT_RANGE, "0,1,0.01,or_lesser,or_greater"), "_set_anchor", "get_anchor", MARGIN_LEFT);
|
||||
ADD_PROPERTYI(PropertyInfo(Variant::REAL, "anchor_top", PROPERTY_HINT_RANGE, "0,1,0.01,or_lesser,or_greater"), "_set_anchor", "get_anchor", MARGIN_TOP);
|
||||
ADD_PROPERTYI(PropertyInfo(Variant::REAL, "anchor_right", PROPERTY_HINT_RANGE, "0,1,0.01,or_lesser,or_greater"), "_set_anchor", "get_anchor", MARGIN_RIGHT);
|
||||
ADD_PROPERTYI(PropertyInfo(Variant::REAL, "anchor_bottom", PROPERTY_HINT_RANGE, "0,1,0.01,or_lesser,or_greater"), "_set_anchor", "get_anchor", MARGIN_BOTTOM);
|
||||
|
||||
ADD_GROUP("Margin", "margin_");
|
||||
ADD_PROPERTYI(PropertyInfo(Variant::INT, "margin_left", PROPERTY_HINT_RANGE, "-4096,4096"), "set_margin", "get_margin", MARGIN_LEFT);
|
||||
|
@ -2851,9 +2895,9 @@ void Control::_bind_methods() {
|
|||
ADD_PROPERTY(PropertyInfo(Variant::INT, "grow_vertical", PROPERTY_HINT_ENUM, "Begin,End,Both"), "set_v_grow_direction", "get_v_grow_direction");
|
||||
|
||||
ADD_GROUP("Rect", "rect_");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "rect_position", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "set_position", "get_position");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "rect_global_position", PROPERTY_HINT_NONE, "", 0), "set_global_position", "get_global_position");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "rect_size", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "set_size", "get_size");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "rect_position", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "_set_position", "get_position");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "rect_global_position", PROPERTY_HINT_NONE, "", 0), "_set_global_position", "get_global_position");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "rect_size", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "_set_size", "get_size");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "rect_min_size"), "set_custom_minimum_size", "get_custom_minimum_size");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "rect_rotation", PROPERTY_HINT_RANGE, "-1080,1080,0.01"), "set_rotation_degrees", "get_rotation_degrees");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "rect_scale"), "set_scale", "get_scale");
|
||||
|
|
|
@ -217,6 +217,9 @@ private:
|
|||
Control *_get_focus_neighbour(Margin p_margin, int p_count = 0);
|
||||
|
||||
void _set_anchor(Margin p_margin, float p_anchor);
|
||||
void _set_position(const Point2 &p_point);
|
||||
void _set_global_position(const Point2 &p_point);
|
||||
void _set_size(const Size2 &p_size);
|
||||
|
||||
void _propagate_theme_changed(CanvasItem *p_at, Control *p_owner, bool p_assign = true);
|
||||
void _theme_changed();
|
||||
|
@ -229,6 +232,7 @@ private:
|
|||
|
||||
Rect2 _compute_child_rect(const float p_anchors[4], const float p_margins[4]) const;
|
||||
void _compute_margins(Rect2 p_rect, const float p_anchors[4], float (&r_margins)[4]);
|
||||
void _compute_anchors(Rect2 p_rect, const float p_margins[4], float (&r_anchors)[4]);
|
||||
|
||||
void _size_changed();
|
||||
String _get_tooltip() const;
|
||||
|
@ -325,7 +329,7 @@ public:
|
|||
|
||||
/* POSITIONING */
|
||||
|
||||
void set_anchors_preset(LayoutPreset p_preset, bool p_keep_margin = true);
|
||||
void set_anchors_preset(LayoutPreset p_preset, bool p_keep_margins = true);
|
||||
void set_margins_preset(LayoutPreset p_preset, LayoutPresetMode p_resize_mode = PRESET_MODE_MINSIZE, int p_margin = 0);
|
||||
void set_anchors_and_margins_preset(LayoutPreset p_preset, LayoutPresetMode p_resize_mode = PRESET_MODE_MINSIZE, int p_margin = 0);
|
||||
|
||||
|
@ -343,12 +347,12 @@ public:
|
|||
Point2 get_begin() const;
|
||||
Point2 get_end() const;
|
||||
|
||||
void set_position(const Point2 &p_point);
|
||||
void set_global_position(const Point2 &p_point);
|
||||
void set_position(const Point2 &p_point, bool p_keep_margins = false);
|
||||
void set_global_position(const Point2 &p_point, bool p_keep_margins = false);
|
||||
Point2 get_position() const;
|
||||
Point2 get_global_position() const;
|
||||
|
||||
void set_size(const Size2 &p_size);
|
||||
void set_size(const Size2 &p_size, bool p_keep_margins = false);
|
||||
Size2 get_size() const;
|
||||
|
||||
Rect2 get_rect() const;
|
||||
|
|
Loading…
Reference in a new issue