diff options
Diffstat (limited to 'editor/plugins')
-rw-r--r-- | editor/plugins/control_editor_plugin.cpp | 848 | ||||
-rw-r--r-- | editor/plugins/control_editor_plugin.h | 168 | ||||
-rw-r--r-- | editor/plugins/debugger_editor_plugin.cpp | 73 | ||||
-rw-r--r-- | editor/plugins/debugger_editor_plugin.h | 4 | ||||
-rw-r--r-- | editor/plugins/font_config_plugin.cpp | 14 | ||||
-rw-r--r-- | editor/plugins/font_config_plugin.h | 6 | ||||
-rw-r--r-- | editor/plugins/visual_shader_editor_plugin.cpp | 20 | ||||
-rw-r--r-- | editor/plugins/visual_shader_editor_plugin.h | 10 |
8 files changed, 595 insertions, 548 deletions
diff --git a/editor/plugins/control_editor_plugin.cpp b/editor/plugins/control_editor_plugin.cpp index 2756e45cf4..ff5d112956 100644 --- a/editor/plugins/control_editor_plugin.cpp +++ b/editor/plugins/control_editor_plugin.cpp @@ -31,10 +31,13 @@ #include "control_editor_plugin.h" #include "editor/editor_node.h" +#include "editor/editor_scale.h" #include "editor/editor_settings.h" #include "editor/plugins/canvas_item_editor_plugin.h" #include "scene/gui/separator.h" +// Inspector controls. + void ControlPositioningWarning::_update_warning() { if (!control_node) { title_icon->set_texture(nullptr); @@ -49,7 +52,7 @@ void ControlPositioningWarning::_update_warning() { title_label->set_text(TTR("This node doesn't have a control parent.")); hint_label->set_text(TTR("Use the appropriate layout properties depending on where you are going to put it.")); } else if (Object::cast_to<Container>(parent_node)) { - title_icon->set_texture(get_theme_icon(SNAME("Container"), SNAME("EditorIcons"))); + title_icon->set_texture(get_theme_icon(SNAME("ContainerLayout"), SNAME("EditorIcons"))); title_label->set_text(TTR("This node is a child of a container.")); hint_label->set_text(TTR("Use container properties for positioning.")); } else { @@ -448,37 +451,280 @@ bool EditorInspectorPluginControl::parse_property(Object *p_object, const Varian return false; } -void ControlEditorToolbar::_set_anchors_and_offsets_preset(Control::LayoutPreset p_preset) { +// Toolbars controls. + +Size2 ControlEditorPopupButton::get_minimum_size() const { + Vector2 base_size = Vector2(26, 26) * EDSCALE; + + if (arrow_icon.is_null()) { + return base_size; + } + + Vector2 final_size; + final_size.x = base_size.x + arrow_icon->get_width(); + final_size.y = MAX(base_size.y, arrow_icon->get_height()); + + return final_size; +} + +void ControlEditorPopupButton::toggled(bool p_pressed) { + if (!p_pressed) { + return; + } + + Size2 size = get_size() * get_viewport()->get_canvas_transform().get_scale(); + + popup_panel->set_size(Size2(size.width, 0)); + Point2 gp = get_screen_position(); + gp.y += size.y; + if (is_layout_rtl()) { + gp.x += size.width - popup_panel->get_size().width; + } + popup_panel->set_position(gp); + + popup_panel->popup(); +} + +void ControlEditorPopupButton::_popup_visibility_changed(bool p_visible) { + set_pressed(p_visible); +} + +void ControlEditorPopupButton::_notification(int p_what) { + switch (p_what) { + case NOTIFICATION_ENTER_TREE: + case NOTIFICATION_THEME_CHANGED: { + arrow_icon = get_theme_icon("select_arrow", "Tree"); + } break; + + case NOTIFICATION_DRAW: { + if (arrow_icon.is_valid()) { + Vector2 arrow_pos = Point2(26, 0) * EDSCALE; + arrow_pos.y = get_size().y / 2 - arrow_icon->get_height() / 2; + draw_texture(arrow_icon, arrow_pos); + } + } break; + + case NOTIFICATION_LAYOUT_DIRECTION_CHANGED: { + popup_panel->set_layout_direction((Window::LayoutDirection)get_layout_direction()); + } break; + + case NOTIFICATION_VISIBILITY_CHANGED: { + if (!is_visible_in_tree()) { + popup_panel->hide(); + } + } break; + } +} + +ControlEditorPopupButton::ControlEditorPopupButton() { + set_flat(true); + set_toggle_mode(true); + set_focus_mode(FOCUS_NONE); + + popup_panel = memnew(PopupPanel); + popup_panel->set_theme_type_variation("ControlEditorPopupButton"); + add_child(popup_panel); + popup_panel->connect("about_to_popup", callable_mp(this, &ControlEditorPopupButton::_popup_visibility_changed).bind(true)); + popup_panel->connect("popup_hide", callable_mp(this, &ControlEditorPopupButton::_popup_visibility_changed).bind(false)); + + popup_vbox = memnew(VBoxContainer); + popup_panel->add_child(popup_vbox); +} + +void ControlEditorPresetPicker::_add_row_button(HBoxContainer *p_row, const int p_preset, const String &p_name) { + ERR_FAIL_COND(preset_buttons.has(p_preset)); + + Button *b = memnew(Button); + b->set_custom_minimum_size(Size2i(36, 36) * EDSCALE); + b->set_icon_alignment(HORIZONTAL_ALIGNMENT_CENTER); + b->set_tooltip(p_name); + b->set_flat(true); + p_row->add_child(b); + b->connect("pressed", callable_mp(this, &ControlEditorPresetPicker::_preset_button_pressed).bind(p_preset)); + + preset_buttons[p_preset] = b; +} + +void ControlEditorPresetPicker::_add_separator(BoxContainer *p_box, Separator *p_separator) { + p_separator->add_theme_constant_override("separation", grid_separation); + p_separator->set_custom_minimum_size(Size2i(1, 1)); + p_box->add_child(p_separator); +} + +void AnchorPresetPicker::_preset_button_pressed(const int p_preset) { + emit_signal("anchors_preset_selected", p_preset); +} + +void AnchorPresetPicker::_notification(int p_notification) { + switch (p_notification) { + case NOTIFICATION_ENTER_TREE: + case NOTIFICATION_THEME_CHANGED: { + preset_buttons[PRESET_TOP_LEFT]->set_icon(get_theme_icon(SNAME("ControlAlignTopLeft"), SNAME("EditorIcons"))); + preset_buttons[PRESET_CENTER_TOP]->set_icon(get_theme_icon(SNAME("ControlAlignCenterTop"), SNAME("EditorIcons"))); + preset_buttons[PRESET_TOP_RIGHT]->set_icon(get_theme_icon(SNAME("ControlAlignTopRight"), SNAME("EditorIcons"))); + + preset_buttons[PRESET_CENTER_LEFT]->set_icon(get_theme_icon(SNAME("ControlAlignCenterLeft"), SNAME("EditorIcons"))); + preset_buttons[PRESET_CENTER]->set_icon(get_theme_icon(SNAME("ControlAlignCenter"), SNAME("EditorIcons"))); + preset_buttons[PRESET_CENTER_RIGHT]->set_icon(get_theme_icon(SNAME("ControlAlignCenterRight"), SNAME("EditorIcons"))); + + preset_buttons[PRESET_BOTTOM_LEFT]->set_icon(get_theme_icon(SNAME("ControlAlignBottomLeft"), SNAME("EditorIcons"))); + preset_buttons[PRESET_CENTER_BOTTOM]->set_icon(get_theme_icon(SNAME("ControlAlignCenterBottom"), SNAME("EditorIcons"))); + preset_buttons[PRESET_BOTTOM_RIGHT]->set_icon(get_theme_icon(SNAME("ControlAlignBottomRight"), SNAME("EditorIcons"))); + + preset_buttons[PRESET_TOP_WIDE]->set_icon(get_theme_icon(SNAME("ControlAlignTopWide"), SNAME("EditorIcons"))); + preset_buttons[PRESET_HCENTER_WIDE]->set_icon(get_theme_icon(SNAME("ControlAlignHCenterWide"), SNAME("EditorIcons"))); + preset_buttons[PRESET_BOTTOM_WIDE]->set_icon(get_theme_icon(SNAME("ControlAlignBottomWide"), SNAME("EditorIcons"))); + + preset_buttons[PRESET_LEFT_WIDE]->set_icon(get_theme_icon(SNAME("ControlAlignLeftWide"), SNAME("EditorIcons"))); + preset_buttons[PRESET_VCENTER_WIDE]->set_icon(get_theme_icon(SNAME("ControlAlignVCenterWide"), SNAME("EditorIcons"))); + preset_buttons[PRESET_RIGHT_WIDE]->set_icon(get_theme_icon(SNAME("ControlAlignRightWide"), SNAME("EditorIcons"))); + + preset_buttons[PRESET_FULL_RECT]->set_icon(get_theme_icon(SNAME("ControlAlignFullRect"), SNAME("EditorIcons"))); + } break; + } +} + +void AnchorPresetPicker::_bind_methods() { + ADD_SIGNAL(MethodInfo("anchors_preset_selected", PropertyInfo(Variant::INT, "preset"))); +} + +AnchorPresetPicker::AnchorPresetPicker() { + VBoxContainer *main_vb = memnew(VBoxContainer); + main_vb->add_theme_constant_override("separation", grid_separation); + add_child(main_vb); + + HBoxContainer *top_row = memnew(HBoxContainer); + top_row->set_alignment(BoxContainer::ALIGNMENT_CENTER); + top_row->add_theme_constant_override("separation", grid_separation); + main_vb->add_child(top_row); + + _add_row_button(top_row, PRESET_TOP_LEFT, TTR("Top Left")); + _add_row_button(top_row, PRESET_CENTER_TOP, TTR("Center Top")); + _add_row_button(top_row, PRESET_TOP_RIGHT, TTR("Top Right")); + _add_separator(top_row, memnew(VSeparator)); + _add_row_button(top_row, PRESET_TOP_WIDE, TTR("Top Wide")); + + HBoxContainer *mid_row = memnew(HBoxContainer); + mid_row->set_alignment(BoxContainer::ALIGNMENT_CENTER); + mid_row->add_theme_constant_override("separation", grid_separation); + main_vb->add_child(mid_row); + + _add_row_button(mid_row, PRESET_CENTER_LEFT, TTR("Center Left")); + _add_row_button(mid_row, PRESET_CENTER, TTR("Center")); + _add_row_button(mid_row, PRESET_CENTER_RIGHT, TTR("Center Right")); + _add_separator(mid_row, memnew(VSeparator)); + _add_row_button(mid_row, PRESET_HCENTER_WIDE, TTR("HCenter Wide")); + + HBoxContainer *bot_row = memnew(HBoxContainer); + bot_row->set_alignment(BoxContainer::ALIGNMENT_CENTER); + bot_row->add_theme_constant_override("separation", grid_separation); + main_vb->add_child(bot_row); + + _add_row_button(bot_row, PRESET_BOTTOM_LEFT, TTR("Bottom Left")); + _add_row_button(bot_row, PRESET_CENTER_BOTTOM, TTR("Center Bottom")); + _add_row_button(bot_row, PRESET_BOTTOM_RIGHT, TTR("Bottom Right")); + _add_separator(bot_row, memnew(VSeparator)); + _add_row_button(bot_row, PRESET_BOTTOM_WIDE, TTR("Bottom Wide")); + + _add_separator(main_vb, memnew(HSeparator)); + + HBoxContainer *extra_row = memnew(HBoxContainer); + extra_row->set_alignment(BoxContainer::ALIGNMENT_CENTER); + extra_row->add_theme_constant_override("separation", grid_separation); + main_vb->add_child(extra_row); + + _add_row_button(extra_row, PRESET_LEFT_WIDE, TTR("Left Wide")); + _add_row_button(extra_row, PRESET_VCENTER_WIDE, TTR("VCenter Wide")); + _add_row_button(extra_row, PRESET_RIGHT_WIDE, TTR("Right Wide")); + _add_separator(extra_row, memnew(VSeparator)); + _add_row_button(extra_row, PRESET_FULL_RECT, TTR("Full Rect")); +} + +void SizeFlagPresetPicker::_preset_button_pressed(const int p_preset) { + int flags = (SizeFlags)p_preset; + if (expand_button->is_pressed()) { + flags |= SIZE_EXPAND; + } + + emit_signal("size_flags_selected", flags); +} + +void SizeFlagPresetPicker::set_allowed_flags(Vector<SizeFlags> &p_flags) { + preset_buttons[SIZE_SHRINK_BEGIN]->set_disabled(!p_flags.has(SIZE_SHRINK_BEGIN)); + preset_buttons[SIZE_SHRINK_CENTER]->set_disabled(!p_flags.has(SIZE_SHRINK_CENTER)); + preset_buttons[SIZE_SHRINK_END]->set_disabled(!p_flags.has(SIZE_SHRINK_END)); + preset_buttons[SIZE_FILL]->set_disabled(!p_flags.has(SIZE_FILL)); + + expand_button->set_disabled(!p_flags.has(SIZE_EXPAND)); + if (p_flags.has(SIZE_EXPAND)) { + expand_button->set_tooltip(TTR("Enable to also set the Expand flag.\nDisable to only set Shrink/Fill flags.")); + } else { + expand_button->set_pressed(false); + expand_button->set_tooltip(TTR("Some parents of the selected nodes do not support the Expand flag.")); + } +} + +void SizeFlagPresetPicker::_notification(int p_notification) { + switch (p_notification) { + case NOTIFICATION_ENTER_TREE: + case NOTIFICATION_THEME_CHANGED: { + if (vertical) { + preset_buttons[SIZE_SHRINK_BEGIN]->set_icon(get_theme_icon(SNAME("ControlAlignCenterTop"), SNAME("EditorIcons"))); + preset_buttons[SIZE_SHRINK_CENTER]->set_icon(get_theme_icon(SNAME("ControlAlignCenter"), SNAME("EditorIcons"))); + preset_buttons[SIZE_SHRINK_END]->set_icon(get_theme_icon(SNAME("ControlAlignCenterBottom"), SNAME("EditorIcons"))); + + preset_buttons[SIZE_FILL]->set_icon(get_theme_icon(SNAME("ControlAlignVCenterWide"), SNAME("EditorIcons"))); + } else { + preset_buttons[SIZE_SHRINK_BEGIN]->set_icon(get_theme_icon(SNAME("ControlAlignCenterLeft"), SNAME("EditorIcons"))); + preset_buttons[SIZE_SHRINK_CENTER]->set_icon(get_theme_icon(SNAME("ControlAlignCenter"), SNAME("EditorIcons"))); + preset_buttons[SIZE_SHRINK_END]->set_icon(get_theme_icon(SNAME("ControlAlignCenterRight"), SNAME("EditorIcons"))); + + preset_buttons[SIZE_FILL]->set_icon(get_theme_icon(SNAME("ControlAlignHCenterWide"), SNAME("EditorIcons"))); + } + } break; + } +} + +void SizeFlagPresetPicker::_bind_methods() { + ADD_SIGNAL(MethodInfo("size_flags_selected", PropertyInfo(Variant::INT, "size_flags"))); +} + +SizeFlagPresetPicker::SizeFlagPresetPicker(bool p_vertical) { + vertical = p_vertical; + + VBoxContainer *main_vb = memnew(VBoxContainer); + add_child(main_vb); + + HBoxContainer *main_row = memnew(HBoxContainer); + main_row->set_alignment(BoxContainer::ALIGNMENT_CENTER); + main_row->add_theme_constant_override("separation", grid_separation); + main_vb->add_child(main_row); + + _add_row_button(main_row, SIZE_SHRINK_BEGIN, TTR("Shrink Begin")); + _add_row_button(main_row, SIZE_SHRINK_CENTER, TTR("Shrink Center")); + _add_row_button(main_row, SIZE_SHRINK_END, TTR("Shrink End")); + _add_separator(main_row, memnew(VSeparator)); + _add_row_button(main_row, SIZE_FILL, TTR("Fill")); + + expand_button = memnew(CheckBox); + expand_button->set_flat(true); + expand_button->set_text(TTR("Align with Expand")); + expand_button->set_tooltip(TTR("Enable to also set the Expand flag.\nDisable to only set Shrink/Fill flags.")); + main_vb->add_child(expand_button); +} + +// Toolbar. + +void ControlEditorToolbar::_anchors_preset_selected(int p_preset) { + LayoutPreset preset = (LayoutPreset)p_preset; List<Node *> selection = editor_selection->get_selected_node_list(); - undo_redo->create_action(TTR("Change Anchors and Offsets")); + undo_redo->create_action(TTR("Change Anchors, Offsets, Grow Direction")); for (Node *E : selection) { Control *control = Object::cast_to<Control>(E); if (control) { - undo_redo->add_do_method(control, "set_anchors_preset", p_preset); - switch (p_preset) { - case PRESET_TOP_LEFT: - case PRESET_TOP_RIGHT: - case PRESET_BOTTOM_LEFT: - case PRESET_BOTTOM_RIGHT: - case PRESET_CENTER_LEFT: - case PRESET_CENTER_TOP: - case PRESET_CENTER_RIGHT: - case PRESET_CENTER_BOTTOM: - case PRESET_CENTER: - undo_redo->add_do_method(control, "set_offsets_preset", p_preset, Control::PRESET_MODE_KEEP_SIZE); - break; - case PRESET_LEFT_WIDE: - case PRESET_TOP_WIDE: - case PRESET_RIGHT_WIDE: - case PRESET_BOTTOM_WIDE: - case PRESET_VCENTER_WIDE: - case PRESET_HCENTER_WIDE: - case PRESET_FULL_RECT: - undo_redo->add_do_method(control, "set_offsets_preset", p_preset, Control::PRESET_MODE_MINSIZE); - break; - } + undo_redo->add_do_property(control, "anchors_preset", preset); undo_redo->add_undo_method(control, "_edit_set_state", control->_edit_get_state()); } } @@ -489,10 +735,10 @@ void ControlEditorToolbar::_set_anchors_and_offsets_preset(Control::LayoutPreset anchor_mode_button->set_pressed(anchors_mode); } -void ControlEditorToolbar::_set_anchors_and_offsets_to_keep_ratio() { +void ControlEditorToolbar::_anchors_to_current_ratio() { List<Node *> selection = editor_selection->get_selected_node_list(); - undo_redo->create_action(TTR("Change Anchors and Offsets")); + undo_redo->create_action(TTR("Change Anchors, Offsets (Keep Ratio)")); for (Node *E : selection) { Control *control = Object::cast_to<Control>(E); @@ -521,44 +767,41 @@ void ControlEditorToolbar::_set_anchors_and_offsets_to_keep_ratio() { undo_redo->commit_action(); } -void ControlEditorToolbar::_set_anchors_preset(Control::LayoutPreset p_preset) { - List<Node *> selection = editor_selection->get_selected_node_list(); +void ControlEditorToolbar::_anchor_mode_toggled(bool p_status) { + List<Control *> selection = _get_edited_controls(); + for (Control *E : selection) { + if (Object::cast_to<Container>(E->get_parent())) { + continue; + } - undo_redo->create_action(TTR("Change Anchors")); - for (Node *E : selection) { - Control *control = Object::cast_to<Control>(E); - if (control) { - undo_redo->add_do_method(control, "set_anchors_preset", p_preset); - undo_redo->add_undo_method(control, "_edit_set_state", control->_edit_get_state()); + if (p_status) { + E->set_meta("_edit_use_anchors_", true); + } else { + E->remove_meta("_edit_use_anchors_"); } } - undo_redo->commit_action(); + anchors_mode = p_status; + CanvasItemEditor::get_singleton()->update_viewport(); } -void ControlEditorToolbar::_set_container_h_preset(Control::SizeFlags p_preset) { +void ControlEditorToolbar::_container_flags_selected(int p_flags, bool p_vertical) { List<Node *> selection = editor_selection->get_selected_node_list(); - undo_redo->create_action(TTR("Change Horizontal Size Flags")); - for (Node *E : selection) { - Control *control = Object::cast_to<Control>(E); - if (control) { - undo_redo->add_do_method(control, "set_h_size_flags", p_preset); - undo_redo->add_undo_method(control, "_edit_set_state", control->_edit_get_state()); - } + if (p_vertical) { + undo_redo->create_action(TTR("Change Vertical Size Flags")); + } else { + undo_redo->create_action(TTR("Change Horizontal Size Flags")); } - undo_redo->commit_action(); -} - -void ControlEditorToolbar::_set_container_v_preset(Control::SizeFlags p_preset) { - List<Node *> selection = editor_selection->get_selected_node_list(); - - undo_redo->create_action(TTR("Change Horizontal Size Flags")); for (Node *E : selection) { Control *control = Object::cast_to<Control>(E); if (control) { - undo_redo->add_do_method(control, "set_v_size_flags", p_preset); + if (p_vertical) { + undo_redo->add_do_method(control, "set_v_size_flags", p_flags); + } else { + undo_redo->add_do_method(control, "set_h_size_flags", p_flags); + } undo_redo->add_undo_method(control, "_edit_set_state", control->_edit_get_state()); } } @@ -594,400 +837,205 @@ Vector2 ControlEditorToolbar::_position_to_anchor(const Control *p_control, Vect return output; } -void ControlEditorToolbar::_button_toggle_anchor_mode(bool p_status) { - List<Control *> selection = _get_edited_controls(false, false); - for (Control *E : selection) { - if (Object::cast_to<Container>(E->get_parent())) { - continue; - } - - if (p_status) { - E->set_meta("_edit_use_anchors_", true); - } else { - E->remove_meta("_edit_use_anchors_"); - } - } - - anchors_mode = p_status; - CanvasItemEditor::get_singleton()->update_viewport(); -} - bool ControlEditorToolbar::_is_node_locked(const Node *p_node) { return p_node->get_meta("_edit_lock_", false); } -List<Control *> ControlEditorToolbar::_get_edited_controls(bool retrieve_locked, bool remove_controls_if_parent_in_selection) { +List<Control *> ControlEditorToolbar::_get_edited_controls() { List<Control *> selection; for (const KeyValue<Node *, Object *> &E : editor_selection->get_selection()) { Control *control = Object::cast_to<Control>(E.key); - if (control && control->is_visible_in_tree() && control->get_viewport() == EditorNode::get_singleton()->get_scene_root() && (retrieve_locked || !_is_node_locked(control))) { + if (control && control->is_visible_in_tree() && control->get_viewport() == EditorNode::get_singleton()->get_scene_root() && !_is_node_locked(control)) { selection.push_back(control); } } - if (remove_controls_if_parent_in_selection) { - List<Control *> filtered_selection; - for (Control *E : selection) { - if (!selection.find(E->get_parent())) { - filtered_selection.push_back(E); - } - } - return filtered_selection; - } - return selection; } -void ControlEditorToolbar::_popup_callback(int p_op) { - switch (p_op) { - case ANCHORS_AND_OFFSETS_PRESET_TOP_LEFT: { - _set_anchors_and_offsets_preset(PRESET_TOP_LEFT); - } break; - case ANCHORS_AND_OFFSETS_PRESET_TOP_RIGHT: { - _set_anchors_and_offsets_preset(PRESET_TOP_RIGHT); - } break; - case ANCHORS_AND_OFFSETS_PRESET_BOTTOM_LEFT: { - _set_anchors_and_offsets_preset(PRESET_BOTTOM_LEFT); - } break; - case ANCHORS_AND_OFFSETS_PRESET_BOTTOM_RIGHT: { - _set_anchors_and_offsets_preset(PRESET_BOTTOM_RIGHT); - } break; - case ANCHORS_AND_OFFSETS_PRESET_CENTER_LEFT: { - _set_anchors_and_offsets_preset(PRESET_CENTER_LEFT); - } break; - case ANCHORS_AND_OFFSETS_PRESET_CENTER_RIGHT: { - _set_anchors_and_offsets_preset(PRESET_CENTER_RIGHT); - } break; - case ANCHORS_AND_OFFSETS_PRESET_CENTER_TOP: { - _set_anchors_and_offsets_preset(PRESET_CENTER_TOP); - } break; - case ANCHORS_AND_OFFSETS_PRESET_CENTER_BOTTOM: { - _set_anchors_and_offsets_preset(PRESET_CENTER_BOTTOM); - } break; - case ANCHORS_AND_OFFSETS_PRESET_CENTER: { - _set_anchors_and_offsets_preset(PRESET_CENTER); - } break; - case ANCHORS_AND_OFFSETS_PRESET_TOP_WIDE: { - _set_anchors_and_offsets_preset(PRESET_TOP_WIDE); - } break; - case ANCHORS_AND_OFFSETS_PRESET_LEFT_WIDE: { - _set_anchors_and_offsets_preset(PRESET_LEFT_WIDE); - } break; - case ANCHORS_AND_OFFSETS_PRESET_RIGHT_WIDE: { - _set_anchors_and_offsets_preset(PRESET_RIGHT_WIDE); - } break; - case ANCHORS_AND_OFFSETS_PRESET_BOTTOM_WIDE: { - _set_anchors_and_offsets_preset(PRESET_BOTTOM_WIDE); - } break; - case ANCHORS_AND_OFFSETS_PRESET_VCENTER_WIDE: { - _set_anchors_and_offsets_preset(PRESET_VCENTER_WIDE); - } break; - case ANCHORS_AND_OFFSETS_PRESET_HCENTER_WIDE: { - _set_anchors_and_offsets_preset(PRESET_HCENTER_WIDE); - } break; - case ANCHORS_AND_OFFSETS_PRESET_FULL_RECT: { - _set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT); - } break; - case ANCHORS_AND_OFFSETS_PRESET_KEEP_RATIO: { - _set_anchors_and_offsets_to_keep_ratio(); - } break; - - case ANCHORS_PRESET_TOP_LEFT: { - _set_anchors_preset(PRESET_TOP_LEFT); - } break; - case ANCHORS_PRESET_TOP_RIGHT: { - _set_anchors_preset(PRESET_TOP_RIGHT); - } break; - case ANCHORS_PRESET_BOTTOM_LEFT: { - _set_anchors_preset(PRESET_BOTTOM_LEFT); - } break; - case ANCHORS_PRESET_BOTTOM_RIGHT: { - _set_anchors_preset(PRESET_BOTTOM_RIGHT); - } break; - case ANCHORS_PRESET_CENTER_LEFT: { - _set_anchors_preset(PRESET_CENTER_LEFT); - } break; - case ANCHORS_PRESET_CENTER_RIGHT: { - _set_anchors_preset(PRESET_CENTER_RIGHT); - } break; - case ANCHORS_PRESET_CENTER_TOP: { - _set_anchors_preset(PRESET_CENTER_TOP); - } break; - case ANCHORS_PRESET_CENTER_BOTTOM: { - _set_anchors_preset(PRESET_CENTER_BOTTOM); - } break; - case ANCHORS_PRESET_CENTER: { - _set_anchors_preset(PRESET_CENTER); - } break; - case ANCHORS_PRESET_TOP_WIDE: { - _set_anchors_preset(PRESET_TOP_WIDE); - } break; - case ANCHORS_PRESET_LEFT_WIDE: { - _set_anchors_preset(PRESET_LEFT_WIDE); - } break; - case ANCHORS_PRESET_RIGHT_WIDE: { - _set_anchors_preset(PRESET_RIGHT_WIDE); - } break; - case ANCHORS_PRESET_BOTTOM_WIDE: { - _set_anchors_preset(PRESET_BOTTOM_WIDE); - } break; - case ANCHORS_PRESET_VCENTER_WIDE: { - _set_anchors_preset(PRESET_VCENTER_WIDE); - } break; - case ANCHORS_PRESET_HCENTER_WIDE: { - _set_anchors_preset(PRESET_HCENTER_WIDE); - } break; - case ANCHORS_PRESET_FULL_RECT: { - _set_anchors_preset(Control::PRESET_FULL_RECT); - } break; - - case CONTAINERS_H_PRESET_FILL: { - _set_container_h_preset(Control::SIZE_FILL); - } break; - case CONTAINERS_H_PRESET_FILL_EXPAND: { - _set_container_h_preset(Control::SIZE_EXPAND_FILL); - } break; - case CONTAINERS_H_PRESET_SHRINK_BEGIN: { - _set_container_h_preset(Control::SIZE_SHRINK_BEGIN); - } break; - case CONTAINERS_H_PRESET_SHRINK_CENTER: { - _set_container_h_preset(Control::SIZE_SHRINK_CENTER); - } break; - case CONTAINERS_H_PRESET_SHRINK_END: { - _set_container_h_preset(Control::SIZE_SHRINK_END); - } break; - - case CONTAINERS_V_PRESET_FILL: { - _set_container_v_preset(Control::SIZE_FILL); - } break; - case CONTAINERS_V_PRESET_FILL_EXPAND: { - _set_container_v_preset(Control::SIZE_EXPAND_FILL); - } break; - case CONTAINERS_V_PRESET_SHRINK_BEGIN: { - _set_container_v_preset(Control::SIZE_SHRINK_BEGIN); - } break; - case CONTAINERS_V_PRESET_SHRINK_CENTER: { - _set_container_v_preset(Control::SIZE_SHRINK_CENTER); - } break; - case CONTAINERS_V_PRESET_SHRINK_END: { - _set_container_v_preset(Control::SIZE_SHRINK_END); - } break; - } -} - void ControlEditorToolbar::_selection_changed() { - // Update the anchors_mode. - int nb_controls = 0; - int nb_valid_controls = 0; - int nb_anchors_mode = 0; + // Update toolbar visibility. + bool has_controls = false; + bool has_control_parents = false; + bool has_container_parents = false; + + // Also update which size flags can be configured for the selected nodes. + Vector<SizeFlags> allowed_h_flags = { + SIZE_SHRINK_BEGIN, + SIZE_SHRINK_CENTER, + SIZE_SHRINK_END, + SIZE_FILL, + SIZE_EXPAND, + }; + Vector<SizeFlags> allowed_v_flags = { + SIZE_SHRINK_BEGIN, + SIZE_SHRINK_CENTER, + SIZE_SHRINK_END, + SIZE_FILL, + SIZE_EXPAND, + }; - List<Node *> selection = editor_selection->get_selected_node_list(); - for (Node *E : selection) { - Control *control = Object::cast_to<Control>(E); + for (const KeyValue<Node *, Object *> &E : editor_selection->get_selection()) { + Control *control = Object::cast_to<Control>(E.key); if (!control) { continue; } + has_controls = true; - nb_controls++; + if (Object::cast_to<Control>(control->get_parent())) { + has_control_parents = true; + } if (Object::cast_to<Container>(control->get_parent())) { - continue; + has_container_parents = true; + + Container *parent_container = Object::cast_to<Container>(control->get_parent()); + + Vector<int> container_h_flags = parent_container->get_allowed_size_flags_horizontal(); + Vector<SizeFlags> tmp_flags = allowed_h_flags.duplicate(); + for (int i = 0; i < allowed_h_flags.size(); i++) { + if (!container_h_flags.has((int)allowed_h_flags[i])) { + tmp_flags.erase(allowed_h_flags[i]); + } + } + allowed_h_flags = tmp_flags; + + Vector<int> container_v_flags = parent_container->get_allowed_size_flags_vertical(); + tmp_flags = allowed_v_flags.duplicate(); + for (int i = 0; i < allowed_v_flags.size(); i++) { + if (!container_v_flags.has((int)allowed_v_flags[i])) { + tmp_flags.erase(allowed_v_flags[i]); + } + } + allowed_v_flags = tmp_flags; } + } + + // Set general toolbar visibility. + set_visible(has_controls); + + // Set anchor tools visibility. + if (has_controls && (!has_control_parents || !has_container_parents)) { + anchors_button->set_visible(true); + anchor_mode_button->set_visible(true); + + // Update anchor mode. + int nb_valid_controls = 0; + int nb_anchors_mode = 0; - nb_valid_controls++; - if (control->get_meta("_edit_use_anchors_", false)) { - nb_anchors_mode++; + List<Node *> selection = editor_selection->get_selected_node_list(); + for (Node *E : selection) { + Control *control = Object::cast_to<Control>(E); + if (!control) { + continue; + } + if (Object::cast_to<Container>(control->get_parent())) { + continue; + } + + nb_valid_controls++; + if (control->get_meta("_edit_use_anchors_", false)) { + nb_anchors_mode++; + } } + + anchors_mode = (nb_valid_controls == nb_anchors_mode); + anchor_mode_button->set_pressed(anchors_mode); + } else { + anchors_button->set_visible(false); + anchor_mode_button->set_visible(false); + anchor_mode_button->set_pressed(false); } - anchors_mode = (nb_valid_controls == nb_anchors_mode); - anchor_mode_button->set_pressed(anchors_mode); + // Set container tools visibility. + if (has_controls && (!has_control_parents || has_container_parents)) { + containers_button->set_visible(true); - if (nb_controls > 0) { - set_physics_process(true); + // Update allowed size flags. + if (has_container_parents) { + container_h_picker->set_allowed_flags(allowed_h_flags); + container_v_picker->set_allowed_flags(allowed_v_flags); + } else { + Vector<SizeFlags> allowed_all_flags = { + SIZE_SHRINK_BEGIN, + SIZE_SHRINK_CENTER, + SIZE_SHRINK_END, + SIZE_FILL, + SIZE_EXPAND, + }; + + container_h_picker->set_allowed_flags(allowed_all_flags); + container_v_picker->set_allowed_flags(allowed_all_flags); + } } else { - set_physics_process(false); - set_visible(false); + containers_button->set_visible(false); } } void ControlEditorToolbar::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: - case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: { - anchor_presets_menu->set_icon(get_theme_icon(SNAME("ControlLayout"), SNAME("EditorIcons"))); - - PopupMenu *p = anchor_presets_menu->get_popup(); - p->clear(); - p->add_icon_item(get_theme_icon(SNAME("ControlAlignTopLeft"), SNAME("EditorIcons")), TTR("Top Left"), ANCHORS_AND_OFFSETS_PRESET_TOP_LEFT); - p->add_icon_item(get_theme_icon(SNAME("ControlAlignTopRight"), SNAME("EditorIcons")), TTR("Top Right"), ANCHORS_AND_OFFSETS_PRESET_TOP_RIGHT); - p->add_icon_item(get_theme_icon(SNAME("ControlAlignBottomRight"), SNAME("EditorIcons")), TTR("Bottom Right"), ANCHORS_AND_OFFSETS_PRESET_BOTTOM_RIGHT); - p->add_icon_item(get_theme_icon(SNAME("ControlAlignBottomLeft"), SNAME("EditorIcons")), TTR("Bottom Left"), ANCHORS_AND_OFFSETS_PRESET_BOTTOM_LEFT); - p->add_separator(); - p->add_icon_item(get_theme_icon(SNAME("ControlAlignCenterLeft"), SNAME("EditorIcons")), TTR("Center Left"), ANCHORS_AND_OFFSETS_PRESET_CENTER_LEFT); - p->add_icon_item(get_theme_icon(SNAME("ControlAlignCenterTop"), SNAME("EditorIcons")), TTR("Center Top"), ANCHORS_AND_OFFSETS_PRESET_CENTER_TOP); - p->add_icon_item(get_theme_icon(SNAME("ControlAlignCenterRight"), SNAME("EditorIcons")), TTR("Center Right"), ANCHORS_AND_OFFSETS_PRESET_CENTER_RIGHT); - p->add_icon_item(get_theme_icon(SNAME("ControlAlignCenterBottom"), SNAME("EditorIcons")), TTR("Center Bottom"), ANCHORS_AND_OFFSETS_PRESET_CENTER_BOTTOM); - p->add_icon_item(get_theme_icon(SNAME("ControlAlignCenter"), SNAME("EditorIcons")), TTR("Center"), ANCHORS_AND_OFFSETS_PRESET_CENTER); - p->add_separator(); - p->add_icon_item(get_theme_icon(SNAME("ControlAlignLeftWide"), SNAME("EditorIcons")), TTR("Left Wide"), ANCHORS_AND_OFFSETS_PRESET_LEFT_WIDE); - p->add_icon_item(get_theme_icon(SNAME("ControlAlignTopWide"), SNAME("EditorIcons")), TTR("Top Wide"), ANCHORS_AND_OFFSETS_PRESET_TOP_WIDE); - p->add_icon_item(get_theme_icon(SNAME("ControlAlignRightWide"), SNAME("EditorIcons")), TTR("Right Wide"), ANCHORS_AND_OFFSETS_PRESET_RIGHT_WIDE); - p->add_icon_item(get_theme_icon(SNAME("ControlAlignBottomWide"), SNAME("EditorIcons")), TTR("Bottom Wide"), ANCHORS_AND_OFFSETS_PRESET_BOTTOM_WIDE); - p->add_icon_item(get_theme_icon(SNAME("ControlAlignVCenterWide"), SNAME("EditorIcons")), TTR("VCenter Wide"), ANCHORS_AND_OFFSETS_PRESET_VCENTER_WIDE); - p->add_icon_item(get_theme_icon(SNAME("ControlAlignHCenterWide"), SNAME("EditorIcons")), TTR("HCenter Wide"), ANCHORS_AND_OFFSETS_PRESET_HCENTER_WIDE); - p->add_separator(); - p->add_icon_item(get_theme_icon(SNAME("ControlAlignFullRect"), SNAME("EditorIcons")), TTR("Full Rect"), ANCHORS_AND_OFFSETS_PRESET_FULL_RECT); - p->add_icon_item(get_theme_icon(SNAME("Anchor"), SNAME("EditorIcons")), TTR("Keep Current Ratio"), ANCHORS_AND_OFFSETS_PRESET_KEEP_RATIO); - p->set_item_tooltip(19, TTR("Adjust anchors and offsets to match the current rect size.")); - - p->add_separator(); - p->add_submenu_item(TTR("Anchors only"), "Anchors"); - p->set_item_icon(21, get_theme_icon(SNAME("Anchor"), SNAME("EditorIcons"))); - - anchors_popup->clear(); - anchors_popup->add_icon_item(get_theme_icon(SNAME("ControlAlignTopLeft"), SNAME("EditorIcons")), TTR("Top Left"), ANCHORS_PRESET_TOP_LEFT); - anchors_popup->add_icon_item(get_theme_icon(SNAME("ControlAlignTopRight"), SNAME("EditorIcons")), TTR("Top Right"), ANCHORS_PRESET_TOP_RIGHT); - anchors_popup->add_icon_item(get_theme_icon(SNAME("ControlAlignBottomRight"), SNAME("EditorIcons")), TTR("Bottom Right"), ANCHORS_PRESET_BOTTOM_RIGHT); - anchors_popup->add_icon_item(get_theme_icon(SNAME("ControlAlignBottomLeft"), SNAME("EditorIcons")), TTR("Bottom Left"), ANCHORS_PRESET_BOTTOM_LEFT); - anchors_popup->add_separator(); - anchors_popup->add_icon_item(get_theme_icon(SNAME("ControlAlignCenterLeft"), SNAME("EditorIcons")), TTR("Center Left"), ANCHORS_PRESET_CENTER_LEFT); - anchors_popup->add_icon_item(get_theme_icon(SNAME("ControlAlignCenterTop"), SNAME("EditorIcons")), TTR("Center Top"), ANCHORS_PRESET_CENTER_TOP); - anchors_popup->add_icon_item(get_theme_icon(SNAME("ControlAlignCenterRight"), SNAME("EditorIcons")), TTR("Center Right"), ANCHORS_PRESET_CENTER_RIGHT); - anchors_popup->add_icon_item(get_theme_icon(SNAME("ControlAlignCenterBottom"), SNAME("EditorIcons")), TTR("Center Bottom"), ANCHORS_PRESET_CENTER_BOTTOM); - anchors_popup->add_icon_item(get_theme_icon(SNAME("ControlAlignCenter"), SNAME("EditorIcons")), TTR("Center"), ANCHORS_PRESET_CENTER); - anchors_popup->add_separator(); - anchors_popup->add_icon_item(get_theme_icon(SNAME("ControlAlignLeftWide"), SNAME("EditorIcons")), TTR("Left Wide"), ANCHORS_PRESET_LEFT_WIDE); - anchors_popup->add_icon_item(get_theme_icon(SNAME("ControlAlignTopWide"), SNAME("EditorIcons")), TTR("Top Wide"), ANCHORS_PRESET_TOP_WIDE); - anchors_popup->add_icon_item(get_theme_icon(SNAME("ControlAlignRightWide"), SNAME("EditorIcons")), TTR("Right Wide"), ANCHORS_PRESET_RIGHT_WIDE); - anchors_popup->add_icon_item(get_theme_icon(SNAME("ControlAlignBottomWide"), SNAME("EditorIcons")), TTR("Bottom Wide"), ANCHORS_PRESET_BOTTOM_WIDE); - anchors_popup->add_icon_item(get_theme_icon(SNAME("ControlAlignVCenterWide"), SNAME("EditorIcons")), TTR("VCenter Wide"), ANCHORS_PRESET_VCENTER_WIDE); - anchors_popup->add_icon_item(get_theme_icon(SNAME("ControlAlignHCenterWide"), SNAME("EditorIcons")), TTR("HCenter Wide"), ANCHORS_PRESET_HCENTER_WIDE); - anchors_popup->add_separator(); - anchors_popup->add_icon_item(get_theme_icon(SNAME("ControlAlignFullRect"), SNAME("EditorIcons")), TTR("Full Rect"), ANCHORS_PRESET_FULL_RECT); - + case NOTIFICATION_THEME_CHANGED: { + anchors_button->set_icon(get_theme_icon(SNAME("ControlLayout"), SNAME("EditorIcons"))); anchor_mode_button->set_icon(get_theme_icon(SNAME("Anchor"), SNAME("EditorIcons"))); - - container_h_presets_menu->set_icon(get_theme_icon(SNAME("Container"), SNAME("EditorIcons"))); - container_v_presets_menu->set_icon(get_theme_icon(SNAME("Container"), SNAME("EditorIcons"))); - - p = container_h_presets_menu->get_popup(); - p->clear(); - p->add_icon_item(get_theme_icon(SNAME("ControlAlignHCenterWide"), SNAME("EditorIcons")), TTR("Fill"), CONTAINERS_H_PRESET_FILL); - p->add_icon_item(get_theme_icon(SNAME("ControlAlignHCenterWide"), SNAME("EditorIcons")), TTR("Fill & Expand"), CONTAINERS_H_PRESET_FILL_EXPAND); - p->add_icon_item(get_theme_icon(SNAME("ControlAlignCenterLeft"), SNAME("EditorIcons")), TTR("Shrink Begin"), CONTAINERS_H_PRESET_SHRINK_BEGIN); - p->add_icon_item(get_theme_icon(SNAME("ControlAlignCenter"), SNAME("EditorIcons")), TTR("Shrink Center"), CONTAINERS_H_PRESET_SHRINK_CENTER); - p->add_icon_item(get_theme_icon(SNAME("ControlAlignCenterRight"), SNAME("EditorIcons")), TTR("Shrink End"), CONTAINERS_H_PRESET_SHRINK_END); - - p = container_v_presets_menu->get_popup(); - p->clear(); - p->add_icon_item(get_theme_icon(SNAME("ControlAlignVCenterWide"), SNAME("EditorIcons")), TTR("Fill"), CONTAINERS_V_PRESET_FILL); - p->add_icon_item(get_theme_icon(SNAME("ControlAlignVCenterWide"), SNAME("EditorIcons")), TTR("Fill & Expand"), CONTAINERS_V_PRESET_FILL_EXPAND); - p->add_icon_item(get_theme_icon(SNAME("ControlAlignCenterTop"), SNAME("EditorIcons")), TTR("Shrink Begin"), CONTAINERS_V_PRESET_SHRINK_BEGIN); - p->add_icon_item(get_theme_icon(SNAME("ControlAlignCenter"), SNAME("EditorIcons")), TTR("Shrink Center"), CONTAINERS_V_PRESET_SHRINK_CENTER); - p->add_icon_item(get_theme_icon(SNAME("ControlAlignCenterBottom"), SNAME("EditorIcons")), TTR("Shrink End"), CONTAINERS_V_PRESET_SHRINK_END); - } break; - - case NOTIFICATION_PHYSICS_PROCESS: { - bool has_control_parents = false; - bool has_container_parents = false; - - // Update the viewport if the canvas_item changes - List<Control *> selection = _get_edited_controls(true); - for (Control *control : selection) { - if (Object::cast_to<Control>(control->get_parent())) { - has_control_parents = true; - } - if (Object::cast_to<Container>(control->get_parent())) { - has_container_parents = true; - } - } - - // Show / Hide the control layout buttons. - if (selection.size() > 0) { - set_visible(true); - - // Toggle anchor and container layout buttons depending on parents of the selected nodes. - // - If there are no control parents, enable everything. - // - If there are container parents, then enable only container buttons. - // - If there are NO container parents, then enable only anchor buttons. - bool enable_anchors = false; - bool enable_containers = false; - if (!has_control_parents) { - enable_anchors = true; - enable_containers = true; - } else if (has_container_parents) { - enable_containers = true; - } else { - enable_anchors = true; - } - - if (enable_anchors) { - anchor_presets_menu->set_visible(true); - anchor_mode_button->set_visible(true); - } else { - anchor_presets_menu->set_visible(false); - anchor_mode_button->set_visible(false); - } - - if (enable_containers) { - container_h_presets_menu->set_visible(true); - container_v_presets_menu->set_visible(true); - } else { - container_h_presets_menu->set_visible(false); - container_v_presets_menu->set_visible(false); - } - } else { - set_visible(false); - } + containers_button->set_icon(get_theme_icon(SNAME("ContainerLayout"), SNAME("EditorIcons"))); } break; } } ControlEditorToolbar::ControlEditorToolbar() { - anchor_presets_menu = memnew(MenuButton); - anchor_presets_menu->set_shortcut_context(this); - anchor_presets_menu->set_text(TTR("Anchors")); - anchor_presets_menu->set_tooltip(TTR("Presets for the anchor and offset values of a Control node.")); - add_child(anchor_presets_menu); - anchor_presets_menu->set_switch_on_hover(true); + add_child(memnew(VSeparator)); - PopupMenu *p = anchor_presets_menu->get_popup(); - p->connect("id_pressed", callable_mp(this, &ControlEditorToolbar::_popup_callback)); + // Anchor and offset tools. + anchors_button = memnew(ControlEditorPopupButton); + anchors_button->set_tooltip(TTR("Presets for the anchor and offset values of a Control node.")); + add_child(anchors_button); - anchors_popup = memnew(PopupMenu); - p->add_child(anchors_popup); - anchors_popup->set_name("Anchors"); - anchors_popup->connect("id_pressed", callable_mp(this, &ControlEditorToolbar::_popup_callback)); + Label *anchors_label = memnew(Label); + anchors_label->set_text(TTR("Anchor preset")); + anchors_button->get_popup_hbox()->add_child(anchors_label); + AnchorPresetPicker *anchors_picker = memnew(AnchorPresetPicker); + anchors_picker->set_h_size_flags(SIZE_SHRINK_CENTER); + anchors_button->get_popup_hbox()->add_child(anchors_picker); + anchors_picker->connect("anchors_preset_selected", callable_mp(this, &ControlEditorToolbar::_anchors_preset_selected)); + + anchors_button->get_popup_hbox()->add_child(memnew(HSeparator)); + + Button *keep_ratio_button = memnew(Button); + keep_ratio_button->set_text_alignment(HORIZONTAL_ALIGNMENT_LEFT); + keep_ratio_button->set_text(TTR("Set to Current Ratio")); + keep_ratio_button->set_tooltip(TTR("Adjust anchors and offsets to match the current rect size.")); + anchors_button->get_popup_hbox()->add_child(keep_ratio_button); + keep_ratio_button->connect("pressed", callable_mp(this, &ControlEditorToolbar::_anchors_to_current_ratio)); anchor_mode_button = memnew(Button); anchor_mode_button->set_flat(true); anchor_mode_button->set_toggle_mode(true); anchor_mode_button->set_tooltip(TTR("When active, moving Control nodes changes their anchors instead of their offsets.")); add_child(anchor_mode_button); - anchor_mode_button->connect("toggled", callable_mp(this, &ControlEditorToolbar::_button_toggle_anchor_mode)); - - add_child(memnew(VSeparator)); - - container_h_presets_menu = memnew(MenuButton); - container_h_presets_menu->set_shortcut_context(this); - container_h_presets_menu->set_text(TTR("Horizontal")); - container_h_presets_menu->set_tooltip(TTR("Horizontal sizing setting for children of a Container node.")); - add_child(container_h_presets_menu); - container_h_presets_menu->set_switch_on_hover(true); - - p = container_h_presets_menu->get_popup(); - p->connect("id_pressed", callable_mp(this, &ControlEditorToolbar::_popup_callback)); - - container_v_presets_menu = memnew(MenuButton); - container_v_presets_menu->set_shortcut_context(this); - container_v_presets_menu->set_text(TTR("Vertical")); - container_v_presets_menu->set_tooltip(TTR("Vertical sizing setting for children of a Container node.")); - add_child(container_v_presets_menu); - container_v_presets_menu->set_switch_on_hover(true); - - p = container_v_presets_menu->get_popup(); - p->connect("id_pressed", callable_mp(this, &ControlEditorToolbar::_popup_callback)); - + anchor_mode_button->connect("toggled", callable_mp(this, &ControlEditorToolbar::_anchor_mode_toggled)); + + // Container tools. + containers_button = memnew(ControlEditorPopupButton); + containers_button->set_tooltip(TTR("Sizing settings for children of a Container node.")); + add_child(containers_button); + + Label *container_h_label = memnew(Label); + container_h_label->set_text(TTR("Horizontal alignment")); + containers_button->get_popup_hbox()->add_child(container_h_label); + container_h_picker = memnew(SizeFlagPresetPicker(false)); + containers_button->get_popup_hbox()->add_child(container_h_picker); + container_h_picker->connect("size_flags_selected", callable_mp(this, &ControlEditorToolbar::_container_flags_selected).bind(false)); + + containers_button->get_popup_hbox()->add_child(memnew(HSeparator)); + + Label *container_v_label = memnew(Label); + container_v_label->set_text(TTR("Vertical alignment")); + containers_button->get_popup_hbox()->add_child(container_v_label); + container_v_picker = memnew(SizeFlagPresetPicker(true)); + containers_button->get_popup_hbox()->add_child(container_v_picker); + container_v_picker->connect("size_flags_selected", callable_mp(this, &ControlEditorToolbar::_container_flags_selected).bind(true)); + + // Editor connections. undo_redo = EditorNode::get_singleton()->get_undo_redo(); editor_selection = EditorNode::get_singleton()->get_editor_selection(); editor_selection->add_editor_plugin(this); @@ -998,6 +1046,8 @@ ControlEditorToolbar::ControlEditorToolbar() { ControlEditorToolbar *ControlEditorToolbar::singleton = nullptr; +// Editor plugin. + ControlEditorPlugin::ControlEditorPlugin() { toolbar = memnew(ControlEditorToolbar); toolbar->hide(); diff --git a/editor/plugins/control_editor_plugin.h b/editor/plugins/control_editor_plugin.h index 11389bc095..f1b9190a0b 100644 --- a/editor/plugins/control_editor_plugin.h +++ b/editor/plugins/control_editor_plugin.h @@ -33,14 +33,18 @@ #include "editor/editor_plugin.h" #include "scene/gui/box_container.h" +#include "scene/gui/button.h" #include "scene/gui/check_box.h" #include "scene/gui/control.h" #include "scene/gui/label.h" #include "scene/gui/margin_container.h" #include "scene/gui/option_button.h" #include "scene/gui/panel_container.h" +#include "scene/gui/popup.h" +#include "scene/gui/separator.h" #include "scene/gui/texture_rect.h" +// Inspector controls. class ControlPositioningWarning : public MarginContainer { GDCLASS(ControlPositioningWarning, MarginContainer); @@ -125,102 +129,101 @@ public: virtual bool parse_property(Object *p_object, const Variant::Type p_type, const String &p_path, const PropertyHint p_hint, const String &p_hint_text, const uint32_t p_usage, const bool p_wide = false) override; }; +// Toolbar controls. +class ControlEditorPopupButton : public Button { + GDCLASS(ControlEditorPopupButton, Button); + + Ref<Texture2D> arrow_icon; + + PopupPanel *popup_panel = nullptr; + VBoxContainer *popup_vbox = nullptr; + + void _popup_visibility_changed(bool p_visible); + +protected: + void _notification(int p_what); + +public: + virtual Size2 get_minimum_size() const override; + virtual void toggled(bool p_pressed) override; + + VBoxContainer *get_popup_hbox() const { return popup_vbox; } + + ControlEditorPopupButton(); +}; + +class ControlEditorPresetPicker : public MarginContainer { + GDCLASS(ControlEditorPresetPicker, MarginContainer); + + virtual void _preset_button_pressed(const int p_preset) {} + +protected: + static constexpr int grid_separation = 0; + HashMap<int, Button *> preset_buttons; + + void _add_row_button(HBoxContainer *p_row, const int p_preset, const String &p_name); + void _add_separator(BoxContainer *p_box, Separator *p_separator); + +public: + ControlEditorPresetPicker() {} +}; + +class AnchorPresetPicker : public ControlEditorPresetPicker { + GDCLASS(AnchorPresetPicker, ControlEditorPresetPicker); + + virtual void _preset_button_pressed(const int p_preset) override; + +protected: + void _notification(int p_notification); + static void _bind_methods(); + +public: + AnchorPresetPicker(); +}; + +class SizeFlagPresetPicker : public ControlEditorPresetPicker { + GDCLASS(SizeFlagPresetPicker, ControlEditorPresetPicker); + + CheckBox *expand_button; + + bool vertical = false; + + virtual void _preset_button_pressed(const int p_preset) override; + +protected: + void _notification(int p_notification); + static void _bind_methods(); + +public: + void set_allowed_flags(Vector<SizeFlags> &p_flags); + + SizeFlagPresetPicker(bool p_vertical); +}; + class ControlEditorToolbar : public HBoxContainer { GDCLASS(ControlEditorToolbar, HBoxContainer); UndoRedo *undo_redo = nullptr; EditorSelection *editor_selection = nullptr; - enum MenuOption { - ANCHORS_AND_OFFSETS_PRESET_TOP_LEFT, - ANCHORS_AND_OFFSETS_PRESET_TOP_RIGHT, - ANCHORS_AND_OFFSETS_PRESET_BOTTOM_LEFT, - ANCHORS_AND_OFFSETS_PRESET_BOTTOM_RIGHT, - ANCHORS_AND_OFFSETS_PRESET_CENTER_LEFT, - ANCHORS_AND_OFFSETS_PRESET_CENTER_RIGHT, - ANCHORS_AND_OFFSETS_PRESET_CENTER_TOP, - ANCHORS_AND_OFFSETS_PRESET_CENTER_BOTTOM, - ANCHORS_AND_OFFSETS_PRESET_CENTER, - ANCHORS_AND_OFFSETS_PRESET_TOP_WIDE, - ANCHORS_AND_OFFSETS_PRESET_LEFT_WIDE, - ANCHORS_AND_OFFSETS_PRESET_RIGHT_WIDE, - ANCHORS_AND_OFFSETS_PRESET_BOTTOM_WIDE, - ANCHORS_AND_OFFSETS_PRESET_VCENTER_WIDE, - ANCHORS_AND_OFFSETS_PRESET_HCENTER_WIDE, - ANCHORS_AND_OFFSETS_PRESET_FULL_RECT, - - ANCHORS_AND_OFFSETS_PRESET_KEEP_RATIO, - - ANCHORS_PRESET_TOP_LEFT, - ANCHORS_PRESET_TOP_RIGHT, - ANCHORS_PRESET_BOTTOM_LEFT, - ANCHORS_PRESET_BOTTOM_RIGHT, - ANCHORS_PRESET_CENTER_LEFT, - ANCHORS_PRESET_CENTER_RIGHT, - ANCHORS_PRESET_CENTER_TOP, - ANCHORS_PRESET_CENTER_BOTTOM, - ANCHORS_PRESET_CENTER, - ANCHORS_PRESET_TOP_WIDE, - ANCHORS_PRESET_LEFT_WIDE, - ANCHORS_PRESET_RIGHT_WIDE, - ANCHORS_PRESET_BOTTOM_WIDE, - ANCHORS_PRESET_VCENTER_WIDE, - ANCHORS_PRESET_HCENTER_WIDE, - ANCHORS_PRESET_FULL_RECT, - - // Offsets Presets are not currently in use. - OFFSETS_PRESET_TOP_LEFT, - OFFSETS_PRESET_TOP_RIGHT, - OFFSETS_PRESET_BOTTOM_LEFT, - OFFSETS_PRESET_BOTTOM_RIGHT, - OFFSETS_PRESET_CENTER_LEFT, - OFFSETS_PRESET_CENTER_RIGHT, - OFFSETS_PRESET_CENTER_TOP, - OFFSETS_PRESET_CENTER_BOTTOM, - OFFSETS_PRESET_CENTER, - OFFSETS_PRESET_TOP_WIDE, - OFFSETS_PRESET_LEFT_WIDE, - OFFSETS_PRESET_RIGHT_WIDE, - OFFSETS_PRESET_BOTTOM_WIDE, - OFFSETS_PRESET_VCENTER_WIDE, - OFFSETS_PRESET_HCENTER_WIDE, - OFFSETS_PRESET_FULL_RECT, - - CONTAINERS_H_PRESET_FILL, - CONTAINERS_H_PRESET_FILL_EXPAND, - CONTAINERS_H_PRESET_SHRINK_BEGIN, - CONTAINERS_H_PRESET_SHRINK_CENTER, - CONTAINERS_H_PRESET_SHRINK_END, - CONTAINERS_V_PRESET_FILL, - CONTAINERS_V_PRESET_FILL_EXPAND, - CONTAINERS_V_PRESET_SHRINK_BEGIN, - CONTAINERS_V_PRESET_SHRINK_CENTER, - CONTAINERS_V_PRESET_SHRINK_END, - }; - - MenuButton *anchor_presets_menu = nullptr; - PopupMenu *anchors_popup = nullptr; - MenuButton *container_h_presets_menu = nullptr; - MenuButton *container_v_presets_menu = nullptr; - + ControlEditorPopupButton *anchors_button = nullptr; + ControlEditorPopupButton *containers_button = nullptr; Button *anchor_mode_button = nullptr; + SizeFlagPresetPicker *container_h_picker = nullptr; + SizeFlagPresetPicker *container_v_picker = nullptr; + bool anchors_mode = false; - void _set_anchors_preset(Control::LayoutPreset p_preset); - void _set_anchors_and_offsets_preset(Control::LayoutPreset p_preset); - void _set_anchors_and_offsets_to_keep_ratio(); - void _set_container_h_preset(Control::SizeFlags p_preset); - void _set_container_v_preset(Control::SizeFlags p_preset); + void _anchors_preset_selected(int p_preset); + void _anchors_to_current_ratio(); + void _anchor_mode_toggled(bool p_status); + void _container_flags_selected(int p_flags, bool p_vertical); Vector2 _anchor_to_position(const Control *p_control, Vector2 anchor); Vector2 _position_to_anchor(const Control *p_control, Vector2 position); - - void _button_toggle_anchor_mode(bool p_status); - bool _is_node_locked(const Node *p_node); - List<Control *> _get_edited_controls(bool retrieve_locked = false, bool remove_controls_if_parent_in_selection = true); - void _popup_callback(int p_op); + List<Control *> _get_edited_controls(); void _selection_changed(); protected: @@ -236,6 +239,7 @@ public: ControlEditorToolbar(); }; +// Editor plugin. class ControlEditorPlugin : public EditorPlugin { GDCLASS(ControlEditorPlugin, EditorPlugin); diff --git a/editor/plugins/debugger_editor_plugin.cpp b/editor/plugins/debugger_editor_plugin.cpp index c572b5b7fe..40e7dfead2 100644 --- a/editor/plugins/debugger_editor_plugin.cpp +++ b/editor/plugins/debugger_editor_plugin.cpp @@ -40,7 +40,7 @@ #include "editor/plugins/script_editor_plugin.h" #include "scene/gui/menu_button.h" -DebuggerEditorPlugin::DebuggerEditorPlugin(MenuButton *p_debug_menu) { +DebuggerEditorPlugin::DebuggerEditorPlugin(PopupMenu *p_debug_menu) { EditorDebuggerServer::initialize(); ED_SHORTCUT("debugger/step_into", TTR("Step Into"), Key::F11); @@ -61,30 +61,29 @@ DebuggerEditorPlugin::DebuggerEditorPlugin(MenuButton *p_debug_menu) { // Main editor debug menu. debug_menu = p_debug_menu; - PopupMenu *p = debug_menu->get_popup(); - p->set_hide_on_checkable_item_selection(false); - p->add_check_shortcut(ED_SHORTCUT("editor/deploy_with_remote_debug", TTR("Deploy with Remote Debug")), RUN_DEPLOY_REMOTE_DEBUG); - p->set_item_tooltip(-1, + debug_menu->set_hide_on_checkable_item_selection(false); + debug_menu->add_check_shortcut(ED_SHORTCUT("editor/deploy_with_remote_debug", TTR("Deploy with Remote Debug")), RUN_DEPLOY_REMOTE_DEBUG); + debug_menu->set_item_tooltip(-1, TTR("When this option is enabled, using one-click deploy will make the executable attempt to connect to this computer's IP so the running project can be debugged.\nThis option is intended to be used for remote debugging (typically with a mobile device).\nYou don't need to enable it to use the GDScript debugger locally.")); - p->add_check_shortcut(ED_SHORTCUT("editor/small_deploy_with_network_fs", TTR("Small Deploy with Network Filesystem")), RUN_FILE_SERVER); - p->set_item_tooltip(-1, + debug_menu->add_check_shortcut(ED_SHORTCUT("editor/small_deploy_with_network_fs", TTR("Small Deploy with Network Filesystem")), RUN_FILE_SERVER); + debug_menu->set_item_tooltip(-1, TTR("When this option is enabled, using one-click deploy for Android will only export an executable without the project data.\nThe filesystem will be provided from the project by the editor over the network.\nOn Android, deploying will use the USB cable for faster performance. This option speeds up testing for projects with large assets.")); - p->add_separator(); - p->add_check_shortcut(ED_SHORTCUT("editor/visible_collision_shapes", TTR("Visible Collision Shapes")), RUN_DEBUG_COLLISONS); - p->set_item_tooltip(-1, + debug_menu->add_separator(); + debug_menu->add_check_shortcut(ED_SHORTCUT("editor/visible_collision_shapes", TTR("Visible Collision Shapes")), RUN_DEBUG_COLLISONS); + debug_menu->set_item_tooltip(-1, TTR("When this option is enabled, collision shapes and raycast nodes (for 2D and 3D) will be visible in the running project.")); - p->add_check_shortcut(ED_SHORTCUT("editor/visible_paths", TTR("Visible Paths")), RUN_DEBUG_PATHS); - p->set_item_tooltip(-1, + debug_menu->add_check_shortcut(ED_SHORTCUT("editor/visible_paths", TTR("Visible Paths")), RUN_DEBUG_PATHS); + debug_menu->set_item_tooltip(-1, TTR("When this option is enabled, curve resources used by path nodes will be visible in the running project.")); - p->add_check_shortcut(ED_SHORTCUT("editor/visible_navigation", TTR("Visible Navigation")), RUN_DEBUG_NAVIGATION); - p->set_item_tooltip(-1, + debug_menu->add_check_shortcut(ED_SHORTCUT("editor/visible_navigation", TTR("Visible Navigation")), RUN_DEBUG_NAVIGATION); + debug_menu->set_item_tooltip(-1, TTR("When this option is enabled, navigation meshes and polygons will be visible in the running project.")); - p->add_separator(); - p->add_check_shortcut(ED_SHORTCUT("editor/sync_scene_changes", TTR("Synchronize Scene Changes")), RUN_LIVE_DEBUG); - p->set_item_tooltip(-1, + debug_menu->add_separator(); + debug_menu->add_check_shortcut(ED_SHORTCUT("editor/sync_scene_changes", TTR("Synchronize Scene Changes")), RUN_LIVE_DEBUG); + debug_menu->set_item_tooltip(-1, TTR("When this option is enabled, any changes made to the scene in the editor will be replicated in the running project.\nWhen used remotely on a device, this is more efficient when the network filesystem option is enabled.")); - p->add_check_shortcut(ED_SHORTCUT("editor/sync_script_changes", TTR("Synchronize Script Changes")), RUN_RELOAD_SCRIPTS); - p->set_item_tooltip(-1, + debug_menu->add_check_shortcut(ED_SHORTCUT("editor/sync_script_changes", TTR("Synchronize Script Changes")), RUN_RELOAD_SCRIPTS); + debug_menu->set_item_tooltip(-1, TTR("When this option is enabled, any script that is saved will be reloaded in the running project.\nWhen used remotely on a device, this is more efficient when the network filesystem option is enabled.")); // Multi-instance, start/stop @@ -92,9 +91,9 @@ DebuggerEditorPlugin::DebuggerEditorPlugin(MenuButton *p_debug_menu) { instances_menu->set_name("run_instances"); instances_menu->set_hide_on_checkable_item_selection(false); - p->add_child(instances_menu); - p->add_separator(); - p->add_submenu_item(TTR("Run Multiple Instances"), "run_instances"); + debug_menu->add_child(instances_menu); + debug_menu->add_separator(); + debug_menu->add_submenu_item(TTR("Run Multiple Instances"), "run_instances"); instances_menu->add_radio_check_item(TTR("Run 1 Instance")); instances_menu->set_item_metadata(0, 1); @@ -106,7 +105,7 @@ DebuggerEditorPlugin::DebuggerEditorPlugin(MenuButton *p_debug_menu) { instances_menu->set_item_metadata(3, 4); instances_menu->set_item_checked(0, true); instances_menu->connect("index_pressed", callable_mp(this, &DebuggerEditorPlugin::_select_run_count)); - p->connect("id_pressed", callable_mp(this, &DebuggerEditorPlugin::_menu_option)); + debug_menu->connect("id_pressed", callable_mp(this, &DebuggerEditorPlugin::_menu_option)); } DebuggerEditorPlugin::~DebuggerEditorPlugin() { @@ -125,7 +124,7 @@ void DebuggerEditorPlugin::_select_run_count(int p_index) { void DebuggerEditorPlugin::_menu_option(int p_option) { switch (p_option) { case RUN_FILE_SERVER: { - bool ischecked = debug_menu->get_popup()->is_item_checked(debug_menu->get_popup()->get_item_index(RUN_FILE_SERVER)); + bool ischecked = debug_menu->is_item_checked(debug_menu->get_item_index(RUN_FILE_SERVER)); if (ischecked) { file_server->stop(); @@ -133,45 +132,45 @@ void DebuggerEditorPlugin::_menu_option(int p_option) { file_server->start(); } - debug_menu->get_popup()->set_item_checked(debug_menu->get_popup()->get_item_index(RUN_FILE_SERVER), !ischecked); + debug_menu->set_item_checked(debug_menu->get_item_index(RUN_FILE_SERVER), !ischecked); EditorSettings::get_singleton()->set_project_metadata("debug_options", "run_file_server", !ischecked); } break; case RUN_LIVE_DEBUG: { - bool ischecked = debug_menu->get_popup()->is_item_checked(debug_menu->get_popup()->get_item_index(RUN_LIVE_DEBUG)); + bool ischecked = debug_menu->is_item_checked(debug_menu->get_item_index(RUN_LIVE_DEBUG)); - debug_menu->get_popup()->set_item_checked(debug_menu->get_popup()->get_item_index(RUN_LIVE_DEBUG), !ischecked); + debug_menu->set_item_checked(debug_menu->get_item_index(RUN_LIVE_DEBUG), !ischecked); EditorDebuggerNode::get_singleton()->set_live_debugging(!ischecked); EditorSettings::get_singleton()->set_project_metadata("debug_options", "run_live_debug", !ischecked); } break; case RUN_DEPLOY_REMOTE_DEBUG: { - bool ischecked = debug_menu->get_popup()->is_item_checked(debug_menu->get_popup()->get_item_index(RUN_DEPLOY_REMOTE_DEBUG)); - debug_menu->get_popup()->set_item_checked(debug_menu->get_popup()->get_item_index(RUN_DEPLOY_REMOTE_DEBUG), !ischecked); + bool ischecked = debug_menu->is_item_checked(debug_menu->get_item_index(RUN_DEPLOY_REMOTE_DEBUG)); + debug_menu->set_item_checked(debug_menu->get_item_index(RUN_DEPLOY_REMOTE_DEBUG), !ischecked); EditorSettings::get_singleton()->set_project_metadata("debug_options", "run_deploy_remote_debug", !ischecked); } break; case RUN_DEBUG_COLLISONS: { - bool ischecked = debug_menu->get_popup()->is_item_checked(debug_menu->get_popup()->get_item_index(RUN_DEBUG_COLLISONS)); - debug_menu->get_popup()->set_item_checked(debug_menu->get_popup()->get_item_index(RUN_DEBUG_COLLISONS), !ischecked); + bool ischecked = debug_menu->is_item_checked(debug_menu->get_item_index(RUN_DEBUG_COLLISONS)); + debug_menu->set_item_checked(debug_menu->get_item_index(RUN_DEBUG_COLLISONS), !ischecked); EditorSettings::get_singleton()->set_project_metadata("debug_options", "run_debug_collisons", !ischecked); } break; case RUN_DEBUG_PATHS: { - bool ischecked = debug_menu->get_popup()->is_item_checked(debug_menu->get_popup()->get_item_index(RUN_DEBUG_PATHS)); - debug_menu->get_popup()->set_item_checked(debug_menu->get_popup()->get_item_index(RUN_DEBUG_PATHS), !ischecked); + bool ischecked = debug_menu->is_item_checked(debug_menu->get_item_index(RUN_DEBUG_PATHS)); + debug_menu->set_item_checked(debug_menu->get_item_index(RUN_DEBUG_PATHS), !ischecked); EditorSettings::get_singleton()->set_project_metadata("debug_options", "run_debug_paths", !ischecked); } break; case RUN_DEBUG_NAVIGATION: { - bool ischecked = debug_menu->get_popup()->is_item_checked(debug_menu->get_popup()->get_item_index(RUN_DEBUG_NAVIGATION)); - debug_menu->get_popup()->set_item_checked(debug_menu->get_popup()->get_item_index(RUN_DEBUG_NAVIGATION), !ischecked); + bool ischecked = debug_menu->is_item_checked(debug_menu->get_item_index(RUN_DEBUG_NAVIGATION)); + debug_menu->set_item_checked(debug_menu->get_item_index(RUN_DEBUG_NAVIGATION), !ischecked); EditorSettings::get_singleton()->set_project_metadata("debug_options", "run_debug_navigation", !ischecked); } break; case RUN_RELOAD_SCRIPTS: { - bool ischecked = debug_menu->get_popup()->is_item_checked(debug_menu->get_popup()->get_item_index(RUN_RELOAD_SCRIPTS)); - debug_menu->get_popup()->set_item_checked(debug_menu->get_popup()->get_item_index(RUN_RELOAD_SCRIPTS), !ischecked); + bool ischecked = debug_menu->is_item_checked(debug_menu->get_item_index(RUN_RELOAD_SCRIPTS)); + debug_menu->set_item_checked(debug_menu->get_item_index(RUN_RELOAD_SCRIPTS), !ischecked); ScriptEditor::get_singleton()->set_live_auto_reload_running_scripts(!ischecked); EditorSettings::get_singleton()->set_project_metadata("debug_options", "run_reload_scripts", !ischecked); diff --git a/editor/plugins/debugger_editor_plugin.h b/editor/plugins/debugger_editor_plugin.h index fb963385cd..d8871128c3 100644 --- a/editor/plugins/debugger_editor_plugin.h +++ b/editor/plugins/debugger_editor_plugin.h @@ -41,7 +41,7 @@ class DebuggerEditorPlugin : public EditorPlugin { GDCLASS(DebuggerEditorPlugin, EditorPlugin); private: - MenuButton *debug_menu = nullptr; + PopupMenu *debug_menu = nullptr; EditorFileServer *file_server = nullptr; PopupMenu *instances_menu = nullptr; @@ -64,7 +64,7 @@ public: virtual String get_name() const override { return "Debugger"; } bool has_main_screen() const override { return false; } - DebuggerEditorPlugin(MenuButton *p_menu); + DebuggerEditorPlugin(PopupMenu *p_menu); ~DebuggerEditorPlugin(); }; diff --git a/editor/plugins/font_config_plugin.cpp b/editor/plugins/font_config_plugin.cpp index cadb974345..c7d3e92802 100644 --- a/editor/plugins/font_config_plugin.cpp +++ b/editor/plugins/font_config_plugin.cpp @@ -100,11 +100,6 @@ bool EditorPropertyFontOTObject::_get(const StringName &p_name, Variant &r_ret) return false; } -void EditorPropertyFontOTObject::_bind_methods() { - ClassDB::bind_method(D_METHOD("property_can_revert", "name"), &EditorPropertyFontOTObject::property_can_revert); - ClassDB::bind_method(D_METHOD("property_get_revert", "name"), &EditorPropertyFontOTObject::property_get_revert); -} - void EditorPropertyFontOTObject::set_dict(const Dictionary &p_dict) { dict = p_dict; } @@ -121,7 +116,7 @@ Dictionary EditorPropertyFontOTObject::get_defaults() { return defaults_dict; } -bool EditorPropertyFontOTObject::property_can_revert(const String &p_name) { +bool EditorPropertyFontOTObject::_property_can_revert(const StringName &p_name) const { String name = p_name; if (name.begins_with("keys")) { @@ -136,18 +131,19 @@ bool EditorPropertyFontOTObject::property_can_revert(const String &p_name) { return false; } -Variant EditorPropertyFontOTObject::property_get_revert(const String &p_name) { +bool EditorPropertyFontOTObject::_property_get_revert(const StringName &p_name, Variant &r_property) const { String name = p_name; if (name.begins_with("keys")) { int key = name.get_slicec('/', 1).to_int(); if (defaults_dict.has(key)) { Vector3i range = defaults_dict[key]; - return range.z; + r_property = range.z; + return true; } } - return Variant(); + return false; } /*************************************************************************/ diff --git a/editor/plugins/font_config_plugin.h b/editor/plugins/font_config_plugin.h index 3eaa2fdc17..41dde3cc59 100644 --- a/editor/plugins/font_config_plugin.h +++ b/editor/plugins/font_config_plugin.h @@ -66,7 +66,8 @@ class EditorPropertyFontOTObject : public RefCounted { protected: bool _set(const StringName &p_name, const Variant &p_value); bool _get(const StringName &p_name, Variant &r_ret) const; - static void _bind_methods(); + bool _property_can_revert(const StringName &p_name) const; + bool _property_get_revert(const StringName &p_name, Variant &r_property) const; public: void set_dict(const Dictionary &p_dict); @@ -75,9 +76,6 @@ public: void set_defaults(const Dictionary &p_dict); Dictionary get_defaults(); - bool property_can_revert(const String &p_name); - Variant property_get_revert(const String &p_name); - EditorPropertyFontOTObject(){}; }; diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp index 4a144bc391..cf24095582 100644 --- a/editor/plugins/visual_shader_editor_plugin.cpp +++ b/editor/plugins/visual_shader_editor_plugin.cpp @@ -6063,7 +6063,7 @@ Control *VisualShaderNodePluginDefault::create_editor(const Ref<Resource> &p_par return editor; } -void EditorPropertyShaderMode::_option_selected(int p_which) { +void EditorPropertyVisualShaderMode::_option_selected(int p_which) { Ref<VisualShader> visual_shader(Object::cast_to<VisualShader>(get_edited_object())); if (visual_shader->get_mode() == p_which) { return; @@ -6149,39 +6149,39 @@ void EditorPropertyShaderMode::_option_selected(int p_which) { undo_redo->commit_action(); } -void EditorPropertyShaderMode::update_property() { +void EditorPropertyVisualShaderMode::update_property() { int which = get_edited_object()->get(get_edited_property()); options->select(which); } -void EditorPropertyShaderMode::setup(const Vector<String> &p_options) { +void EditorPropertyVisualShaderMode::setup(const Vector<String> &p_options) { for (int i = 0; i < p_options.size(); i++) { options->add_item(p_options[i], i); } } -void EditorPropertyShaderMode::set_option_button_clip(bool p_enable) { +void EditorPropertyVisualShaderMode::set_option_button_clip(bool p_enable) { options->set_clip_text(p_enable); } -void EditorPropertyShaderMode::_bind_methods() { +void EditorPropertyVisualShaderMode::_bind_methods() { } -EditorPropertyShaderMode::EditorPropertyShaderMode() { +EditorPropertyVisualShaderMode::EditorPropertyVisualShaderMode() { options = memnew(OptionButton); options->set_clip_text(true); add_child(options); add_focusable(options); - options->connect("item_selected", callable_mp(this, &EditorPropertyShaderMode::_option_selected)); + options->connect("item_selected", callable_mp(this, &EditorPropertyVisualShaderMode::_option_selected)); } -bool EditorInspectorShaderModePlugin::can_handle(Object *p_object) { +bool EditorInspectorVisualShaderModePlugin::can_handle(Object *p_object) { return true; // Can handle everything. } -bool EditorInspectorShaderModePlugin::parse_property(Object *p_object, const Variant::Type p_type, const String &p_path, const PropertyHint p_hint, const String &p_hint_text, const uint32_t p_usage, const bool p_wide) { +bool EditorInspectorVisualShaderModePlugin::parse_property(Object *p_object, const Variant::Type p_type, const String &p_path, const PropertyHint p_hint, const String &p_hint_text, const uint32_t p_usage, const bool p_wide) { if (p_path == "mode" && p_object->is_class("VisualShader") && p_type == Variant::INT) { - EditorPropertyShaderMode *mode_editor = memnew(EditorPropertyShaderMode); + EditorPropertyVisualShaderMode *mode_editor = memnew(EditorPropertyVisualShaderMode); Vector<String> options = p_hint_text.split(","); mode_editor->setup(options); add_property_editor(p_path, mode_editor); diff --git a/editor/plugins/visual_shader_editor_plugin.h b/editor/plugins/visual_shader_editor_plugin.h index b846c34f9e..b6a3b43754 100644 --- a/editor/plugins/visual_shader_editor_plugin.h +++ b/editor/plugins/visual_shader_editor_plugin.h @@ -529,8 +529,8 @@ public: virtual Control *create_editor(const Ref<Resource> &p_parent_resource, const Ref<VisualShaderNode> &p_node) override; }; -class EditorPropertyShaderMode : public EditorProperty { - GDCLASS(EditorPropertyShaderMode, EditorProperty); +class EditorPropertyVisualShaderMode : public EditorProperty { + GDCLASS(EditorPropertyVisualShaderMode, EditorProperty); OptionButton *options = nullptr; void _option_selected(int p_which); @@ -542,11 +542,11 @@ public: void setup(const Vector<String> &p_options); virtual void update_property() override; void set_option_button_clip(bool p_enable); - EditorPropertyShaderMode(); + EditorPropertyVisualShaderMode(); }; -class EditorInspectorShaderModePlugin : public EditorInspectorPlugin { - GDCLASS(EditorInspectorShaderModePlugin, EditorInspectorPlugin); +class EditorInspectorVisualShaderModePlugin : public EditorInspectorPlugin { + GDCLASS(EditorInspectorVisualShaderModePlugin, EditorInspectorPlugin); public: virtual bool can_handle(Object *p_object) override; |