diff options
Diffstat (limited to 'editor/plugins')
82 files changed, 2195 insertions, 1019 deletions
diff --git a/editor/plugins/abstract_polygon_2d_editor.cpp b/editor/plugins/abstract_polygon_2d_editor.cpp index 804f9c607e..990b8df49d 100644 --- a/editor/plugins/abstract_polygon_2d_editor.cpp +++ b/editor/plugins/abstract_polygon_2d_editor.cpp @@ -158,9 +158,9 @@ void AbstractPolygon2DEditor::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: case NOTIFICATION_THEME_CHANGED: { - button_create->set_icon(get_editor_theme_icon(SNAME("CurveCreate"))); - button_edit->set_icon(get_editor_theme_icon(SNAME("CurveEdit"))); - button_delete->set_icon(get_editor_theme_icon(SNAME("CurveDelete"))); + button_create->set_button_icon(get_editor_theme_icon(SNAME("CurveCreate"))); + button_edit->set_button_icon(get_editor_theme_icon(SNAME("CurveEdit"))); + button_delete->set_button_icon(get_editor_theme_icon(SNAME("CurveDelete"))); } break; case NOTIFICATION_READY: { diff --git a/editor/plugins/animation_blend_space_1d_editor.cpp b/editor/plugins/animation_blend_space_1d_editor.cpp index cbf8b27b32..3f534eebc5 100644 --- a/editor/plugins/animation_blend_space_1d_editor.cpp +++ b/editor/plugins/animation_blend_space_1d_editor.cpp @@ -576,12 +576,12 @@ void AnimationNodeBlendSpace1DEditor::_notification(int p_what) { error_panel->add_theme_style_override(SceneStringName(panel), get_theme_stylebox(SceneStringName(panel), SNAME("Tree"))); error_label->add_theme_color_override(SceneStringName(font_color), get_theme_color(SNAME("error_color"), EditorStringName(Editor))); panel->add_theme_style_override(SceneStringName(panel), get_theme_stylebox(SceneStringName(panel), SNAME("Tree"))); - tool_blend->set_icon(get_editor_theme_icon(SNAME("EditPivot"))); - tool_select->set_icon(get_editor_theme_icon(SNAME("ToolSelect"))); - tool_create->set_icon(get_editor_theme_icon(SNAME("EditKey"))); - tool_erase->set_icon(get_editor_theme_icon(SNAME("Remove"))); - snap->set_icon(get_editor_theme_icon(SNAME("SnapGrid"))); - open_editor->set_icon(get_editor_theme_icon(SNAME("Edit"))); + tool_blend->set_button_icon(get_editor_theme_icon(SNAME("EditPivot"))); + tool_select->set_button_icon(get_editor_theme_icon(SNAME("ToolSelect"))); + tool_create->set_button_icon(get_editor_theme_icon(SNAME("EditKey"))); + tool_erase->set_button_icon(get_editor_theme_icon(SNAME("Remove"))); + snap->set_button_icon(get_editor_theme_icon(SNAME("SnapGrid"))); + open_editor->set_button_icon(get_editor_theme_icon(SNAME("Edit"))); interpolation->clear(); interpolation->add_icon_item(get_editor_theme_icon(SNAME("TrackContinuous")), TTR("Continuous"), 0); interpolation->add_icon_item(get_editor_theme_icon(SNAME("TrackDiscrete")), TTR("Discrete"), 1); diff --git a/editor/plugins/animation_blend_space_2d_editor.cpp b/editor/plugins/animation_blend_space_2d_editor.cpp index 934f26415a..ba2dad5880 100644 --- a/editor/plugins/animation_blend_space_2d_editor.cpp +++ b/editor/plugins/animation_blend_space_2d_editor.cpp @@ -798,14 +798,14 @@ void AnimationNodeBlendSpace2DEditor::_notification(int p_what) { error_panel->add_theme_style_override(SceneStringName(panel), get_theme_stylebox(SceneStringName(panel), SNAME("Tree"))); error_label->add_theme_color_override(SceneStringName(font_color), get_theme_color(SNAME("error_color"), EditorStringName(Editor))); panel->add_theme_style_override(SceneStringName(panel), get_theme_stylebox(SceneStringName(panel), SNAME("Tree"))); - tool_blend->set_icon(get_editor_theme_icon(SNAME("EditPivot"))); - tool_select->set_icon(get_editor_theme_icon(SNAME("ToolSelect"))); - tool_create->set_icon(get_editor_theme_icon(SNAME("EditKey"))); - tool_triangle->set_icon(get_editor_theme_icon(SNAME("ToolTriangle"))); - tool_erase->set_icon(get_editor_theme_icon(SNAME("Remove"))); - snap->set_icon(get_editor_theme_icon(SNAME("SnapGrid"))); - open_editor->set_icon(get_editor_theme_icon(SNAME("Edit"))); - auto_triangles->set_icon(get_editor_theme_icon(SNAME("AutoTriangle"))); + tool_blend->set_button_icon(get_editor_theme_icon(SNAME("EditPivot"))); + tool_select->set_button_icon(get_editor_theme_icon(SNAME("ToolSelect"))); + tool_create->set_button_icon(get_editor_theme_icon(SNAME("EditKey"))); + tool_triangle->set_button_icon(get_editor_theme_icon(SNAME("ToolTriangle"))); + tool_erase->set_button_icon(get_editor_theme_icon(SNAME("Remove"))); + snap->set_button_icon(get_editor_theme_icon(SNAME("SnapGrid"))); + open_editor->set_button_icon(get_editor_theme_icon(SNAME("Edit"))); + auto_triangles->set_button_icon(get_editor_theme_icon(SNAME("AutoTriangle"))); interpolation->clear(); interpolation->add_icon_item(get_editor_theme_icon(SNAME("TrackContinuous")), TTR("Continuous"), 0); interpolation->add_icon_item(get_editor_theme_icon(SNAME("TrackDiscrete")), TTR("Discrete"), 1); diff --git a/editor/plugins/animation_blend_tree_editor_plugin.cpp b/editor/plugins/animation_blend_tree_editor_plugin.cpp index 9e282cb3fa..096e92e235 100644 --- a/editor/plugins/animation_blend_tree_editor_plugin.cpp +++ b/editor/plugins/animation_blend_tree_editor_plugin.cpp @@ -45,6 +45,7 @@ #include "scene/3d/skeleton_3d.h" #include "scene/animation/animation_player.h" #include "scene/gui/check_box.h" +#include "scene/gui/grid_container.h" #include "scene/gui/menu_button.h" #include "scene/gui/option_button.h" #include "scene/gui/panel.h" @@ -178,7 +179,7 @@ void AnimationNodeBlendTreeEditor::update_graph() { Button *delete_button = memnew(Button); delete_button->set_flat(true); delete_button->set_focus_mode(FOCUS_NONE); - delete_button->set_icon(get_editor_theme_icon(SNAME("Close"))); + delete_button->set_button_icon(get_editor_theme_icon(SNAME("Close"))); delete_button->connect(SceneStringName(pressed), callable_mp(this, &AnimationNodeBlendTreeEditor::_delete_node_request).bind(E), CONNECT_DEFERRED); node->get_titlebar_hbox()->add_child(delete_button); } @@ -216,7 +217,7 @@ void AnimationNodeBlendTreeEditor::update_graph() { node->add_child(memnew(HSeparator)); Button *open_in_editor = memnew(Button); open_in_editor->set_text(TTR("Open Editor")); - open_in_editor->set_icon(get_editor_theme_icon(SNAME("Edit"))); + open_in_editor->set_button_icon(get_editor_theme_icon(SNAME("Edit"))); node->add_child(open_in_editor); open_in_editor->connect(SceneStringName(pressed), callable_mp(this, &AnimationNodeBlendTreeEditor::_open_in_editor).bind(E), CONNECT_DEFERRED); open_in_editor->set_h_size_flags(SIZE_SHRINK_CENTER); @@ -230,7 +231,7 @@ void AnimationNodeBlendTreeEditor::update_graph() { } else { inspect_filters->set_text(TTR("Edit Filters")); } - inspect_filters->set_icon(get_editor_theme_icon(SNAME("AnimationFilter"))); + inspect_filters->set_button_icon(get_editor_theme_icon(SNAME("AnimationFilter"))); node->add_child(inspect_filters); inspect_filters->connect(SceneStringName(pressed), callable_mp(this, &AnimationNodeBlendTreeEditor::_inspect_filters).bind(E), CONNECT_DEFERRED); inspect_filters->set_h_size_flags(SIZE_SHRINK_CENTER); @@ -240,7 +241,7 @@ void AnimationNodeBlendTreeEditor::update_graph() { if (anim.is_valid()) { MenuButton *mb = memnew(MenuButton); mb->set_text(anim->get_animation()); - mb->set_icon(get_editor_theme_icon(SNAME("Animation"))); + mb->set_button_icon(get_editor_theme_icon(SNAME("Animation"))); mb->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED); mb->set_disabled(read_only); Array options; @@ -1265,7 +1266,7 @@ AnimationNodeBlendTreeEditor::AnimationNodeBlendTreeEditor() { open_file->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_FILE); open_file->connect("file_selected", callable_mp(this, &AnimationNodeBlendTreeEditor::_file_opened)); - animation_node_inspector_plugin = Ref<EditorInspectorPluginAnimationNodeAnimation>(memnew(EditorInspectorPluginAnimationNodeAnimation)); + animation_node_inspector_plugin.instantiate(); EditorInspector::add_inspector_plugin(animation_node_inspector_plugin); } @@ -1375,7 +1376,7 @@ void AnimationNodeAnimationEditor::_notification(int p_what) { switch (p_what) { case NOTIFICATION_THEME_CHANGED: { button->set_theme_type_variation(SNAME("InspectorActionButton")); - button->set_icon(get_editor_theme_icon(SNAME("Edit"))); + button->set_button_icon(get_editor_theme_icon(SNAME("Edit"))); } break; } } @@ -1397,32 +1398,30 @@ bool EditorInspectorPluginAnimationNodeAnimation::parse_property(Object *p_objec } AnimationNodeAnimationEditorDialog::AnimationNodeAnimationEditorDialog() { - set_title(TTR("Select Markers...")); - VBoxContainer *vbox = memnew(VBoxContainer); - add_child(vbox); - vbox->set_offsets_preset(Control::PRESET_FULL_RECT); - - HBoxContainer *container_start = memnew(HBoxContainer); - vbox->add_child(container_start); - Label *label_start = memnew(Label); - container_start->add_child(label_start); + set_title(TTR("Select Markers")); + + GridContainer *grid = memnew(GridContainer); + grid->set_columns(2); + grid->set_offsets_preset(Control::PRESET_FULL_RECT); + add_child(grid); + + Label *label_start = memnew(Label(TTR("Start Marker"))); + grid->add_child(label_start); label_start->set_h_size_flags(Control::SIZE_EXPAND_FILL); label_start->set_stretch_ratio(1); - label_start->set_text(TTR("Start Marker")); select_start = memnew(OptionButton); - container_start->add_child(select_start); + select_start->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED); + grid->add_child(select_start); select_start->set_h_size_flags(Control::SIZE_EXPAND_FILL); select_start->set_stretch_ratio(2); - HBoxContainer *container_end = memnew(HBoxContainer); - vbox->add_child(container_end); - Label *label_end = memnew(Label); - container_end->add_child(label_end); + Label *label_end = memnew(Label(TTR("End Marker"))); + grid->add_child(label_end); label_end->set_h_size_flags(Control::SIZE_EXPAND_FILL); label_end->set_stretch_ratio(1); - label_end->set_text(TTR("End Marker")); select_end = memnew(OptionButton); - container_end->add_child(select_end); + select_end->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED); + grid->add_child(select_end); select_end->set_h_size_flags(Control::SIZE_EXPAND_FILL); select_end->set_stretch_ratio(2); } diff --git a/editor/plugins/animation_library_editor.cpp b/editor/plugins/animation_library_editor.cpp index 147b92c094..4e8a1bd89b 100644 --- a/editor/plugins/animation_library_editor.cpp +++ b/editor/plugins/animation_library_editor.cpp @@ -773,8 +773,8 @@ void AnimationLibraryEditor::show_dialog() { void AnimationLibraryEditor::_notification(int p_what) { switch (p_what) { case NOTIFICATION_THEME_CHANGED: { - new_library_button->set_icon(get_editor_theme_icon(SNAME("Add"))); - load_library_button->set_icon(get_editor_theme_icon(SNAME("Load"))); + new_library_button->set_button_icon(get_editor_theme_icon(SNAME("Add"))); + load_library_button->set_button_icon(get_editor_theme_icon(SNAME("Load"))); } } } diff --git a/editor/plugins/animation_player_editor_plugin.cpp b/editor/plugins/animation_player_editor_plugin.cpp index 1581e7cc66..4edd021b4d 100644 --- a/editor/plugins/animation_player_editor_plugin.cpp +++ b/editor/plugins/animation_player_editor_plugin.cpp @@ -113,7 +113,7 @@ void AnimationPlayerEditor::_notification(int p_what) { // Need the last frame after it stopped. frame->set_value(player->get_current_animation_position()); track_editor->set_anim_pos(player->get_current_animation_position()); - stop->set_icon(stop_icon); + stop->set_button_icon(stop_icon); } last_active = player->is_playing(); @@ -145,16 +145,16 @@ void AnimationPlayerEditor::_notification(int p_what) { stop_icon = get_editor_theme_icon(SNAME("Stop")); pause_icon = get_editor_theme_icon(SNAME("Pause")); if (player && player->is_playing()) { - stop->set_icon(pause_icon); + stop->set_button_icon(pause_icon); } else { - stop->set_icon(stop_icon); + stop->set_button_icon(stop_icon); } - autoplay->set_icon(get_editor_theme_icon(SNAME("AutoPlay"))); - play->set_icon(get_editor_theme_icon(SNAME("PlayStart"))); - play_from->set_icon(get_editor_theme_icon(SNAME("Play"))); - play_bw->set_icon(get_editor_theme_icon(SNAME("PlayStartBackwards"))); - play_bw_from->set_icon(get_editor_theme_icon(SNAME("PlayBackwards"))); + autoplay->set_button_icon(get_editor_theme_icon(SNAME("AutoPlay"))); + play->set_button_icon(get_editor_theme_icon(SNAME("PlayStart"))); + play_from->set_button_icon(get_editor_theme_icon(SNAME("Play"))); + play_bw->set_button_icon(get_editor_theme_icon(SNAME("PlayStartBackwards"))); + play_bw_from->set_button_icon(get_editor_theme_icon(SNAME("PlayBackwards"))); autoplay_icon = get_editor_theme_icon(SNAME("AutoPlay")); reset_icon = get_editor_theme_icon(SNAME("Reload")); @@ -168,10 +168,10 @@ void AnimationPlayerEditor::_notification(int p_what) { autoplay_reset_icon = ImageTexture::create_from_image(autoplay_reset_img); } - onion_toggle->set_icon(get_editor_theme_icon(SNAME("Onion"))); - onion_skinning->set_icon(get_editor_theme_icon(SNAME("GuiTabMenuHl"))); + onion_toggle->set_button_icon(get_editor_theme_icon(SNAME("Onion"))); + onion_skinning->set_button_icon(get_editor_theme_icon(SNAME("GuiTabMenuHl"))); - pin->set_icon(get_editor_theme_icon(SNAME("Pin"))); + pin->set_button_icon(get_editor_theme_icon(SNAME("Pin"))); tool_anim->add_theme_style_override(CoreStringName(normal), get_theme_stylebox(CoreStringName(normal), SNAME("Button"))); track_editor->get_edit_menu()->add_theme_style_override(CoreStringName(normal), get_theme_stylebox(CoreStringName(normal), SNAME("Button"))); @@ -307,7 +307,7 @@ void AnimationPlayerEditor::_play_pressed() { } //unstop - stop->set_icon(pause_icon); + stop->set_button_icon(pause_icon); } void AnimationPlayerEditor::_play_from_pressed() { @@ -331,7 +331,7 @@ void AnimationPlayerEditor::_play_from_pressed() { } //unstop - stop->set_icon(pause_icon); + stop->set_button_icon(pause_icon); } String AnimationPlayerEditor::_get_current() const { @@ -359,7 +359,7 @@ void AnimationPlayerEditor::_play_bw_pressed() { } //unstop - stop->set_icon(pause_icon); + stop->set_button_icon(pause_icon); } void AnimationPlayerEditor::_play_bw_from_pressed() { @@ -383,7 +383,7 @@ void AnimationPlayerEditor::_play_bw_from_pressed() { } //unstop - stop->set_icon(pause_icon); + stop->set_button_icon(pause_icon); } void AnimationPlayerEditor::_stop_pressed() { @@ -400,7 +400,7 @@ void AnimationPlayerEditor::_stop_pressed() { frame->set_value(0); track_editor->set_anim_pos(0); } - stop->set_icon(stop_icon); + stop->set_button_icon(stop_icon); } void AnimationPlayerEditor::_animation_selected(int p_which) { @@ -580,8 +580,10 @@ float AnimationPlayerEditor::_get_editor_step() const { const Ref<Animation> anim = player->get_animation(current); ERR_FAIL_COND_V(anim.is_null(), 0.0); + float step = track_editor->get_snap_unit(); + // Use more precise snapping when holding Shift - return Input::get_singleton()->is_key_pressed(Key::SHIFT) ? anim->get_step() * 0.25 : anim->get_step(); + return Input::get_singleton()->is_key_pressed(Key::SHIFT) ? step * 0.25 : step; } void AnimationPlayerEditor::_animation_name_edited() { @@ -959,9 +961,9 @@ void AnimationPlayerEditor::_update_animation() { updating = true; if (player->is_playing()) { - stop->set_icon(pause_icon); + stop->set_button_icon(pause_icon); } else { - stop->set_icon(stop_icon); + stop->set_button_icon(stop_icon); } scale->set_text(String::num(player->get_speed_scale(), 2)); @@ -1397,7 +1399,7 @@ void AnimationPlayerEditor::_seek_value_changed(float p_value, bool p_timeline_o } track_editor->set_anim_pos(pos); -}; +} void AnimationPlayerEditor::_animation_player_changed(Object *p_pl) { _update_player(); diff --git a/editor/plugins/animation_state_machine_editor.cpp b/editor/plugins/animation_state_machine_editor.cpp index e9dd54f73b..d10daa2bfc 100644 --- a/editor/plugins/animation_state_machine_editor.cpp +++ b/editor/plugins/animation_state_machine_editor.cpp @@ -1271,18 +1271,18 @@ void AnimationNodeStateMachineEditor::_notification(int p_what) { error_panel->add_theme_style_override(SceneStringName(panel), theme_cache.error_panel_style); error_label->add_theme_color_override(SceneStringName(font_color), theme_cache.error_color); - tool_select->set_icon(theme_cache.tool_icon_select); - tool_create->set_icon(theme_cache.tool_icon_create); - tool_connect->set_icon(theme_cache.tool_icon_connect); + tool_select->set_button_icon(theme_cache.tool_icon_select); + tool_create->set_button_icon(theme_cache.tool_icon_create); + tool_connect->set_button_icon(theme_cache.tool_icon_connect); switch_mode->clear(); switch_mode->add_icon_item(theme_cache.transition_icon_immediate, TTR("Immediate")); switch_mode->add_icon_item(theme_cache.transition_icon_sync, TTR("Sync")); switch_mode->add_icon_item(theme_cache.transition_icon_end, TTR("At End")); - auto_advance->set_icon(theme_cache.play_icon_auto); + auto_advance->set_button_icon(theme_cache.play_icon_auto); - tool_erase->set_icon(theme_cache.tool_icon_erase); + tool_erase->set_button_icon(theme_cache.tool_icon_erase); play_mode->clear(); play_mode->add_icon_item(theme_cache.play_icon_travel, TTR("Travel")); diff --git a/editor/plugins/asset_library_editor_plugin.cpp b/editor/plugins/asset_library_editor_plugin.cpp index fec8d4b897..8db106da07 100644 --- a/editor/plugins/asset_library_editor_plugin.cpp +++ b/editor/plugins/asset_library_editor_plugin.cpp @@ -212,12 +212,12 @@ void EditorAssetLibraryItemDescription::set_image(int p_type, int p_index, const // Overlay and thumbnail need the same format for `blend_rect` to work. thumbnail->convert(Image::FORMAT_RGBA8); thumbnail->blend_rect(overlay, overlay->get_used_rect(), overlay_pos); - preview_images[i].button->set_icon(ImageTexture::create_from_image(thumbnail)); + preview_images[i].button->set_button_icon(ImageTexture::create_from_image(thumbnail)); // Make it clearer that clicking it will open an external link preview_images[i].button->set_default_cursor_shape(Control::CURSOR_POINTING_HAND); } else { - preview_images[i].button->set_icon(p_image); + preview_images[i].button->set_button_icon(p_image); } break; } @@ -302,7 +302,7 @@ void EditorAssetLibraryItemDescription::add_preview(int p_id, bool p_video, cons new_preview.video_link = p_url; new_preview.is_video = p_video; new_preview.button = memnew(Button); - new_preview.button->set_icon(previews->get_editor_theme_icon(SNAME("ThumbnailWait"))); + new_preview.button->set_button_icon(previews->get_editor_theme_icon(SNAME("ThumbnailWait"))); new_preview.button->set_toggle_mode(true); new_preview.button->connect(SceneStringName(pressed), callable_mp(this, &EditorAssetLibraryItemDescription::_preview_click).bind(p_id)); preview_hb->add_child(new_preview.button); diff --git a/editor/plugins/audio_stream_editor_plugin.cpp b/editor/plugins/audio_stream_editor_plugin.cpp index f691bad3c3..23eeedea93 100644 --- a/editor/plugins/audio_stream_editor_plugin.cpp +++ b/editor/plugins/audio_stream_editor_plugin.cpp @@ -50,8 +50,8 @@ void AudioStreamEditor::_notification(int p_what) { _current_label->add_theme_font_override(SceneStringName(font), font); _duration_label->add_theme_font_override(SceneStringName(font), font); - _play_button->set_icon(get_editor_theme_icon(SNAME("MainPlay"))); - _stop_button->set_icon(get_editor_theme_icon(SNAME("Stop"))); + _play_button->set_button_icon(get_editor_theme_icon(SNAME("MainPlay"))); + _stop_button->set_button_icon(get_editor_theme_icon(SNAME("Stop"))); _preview->set_color(get_theme_color(SNAME("dark_color_2"), EditorStringName(Editor))); set_color(get_theme_color(SNAME("dark_color_1"), EditorStringName(Editor))); @@ -121,26 +121,26 @@ void AudioStreamEditor::_play() { if (_player->is_playing()) { _pausing = true; _player->stop(); - _play_button->set_icon(get_editor_theme_icon(SNAME("MainPlay"))); + _play_button->set_button_icon(get_editor_theme_icon(SNAME("MainPlay"))); set_process(false); } else { _pausing = false; _player->play(_current); - _play_button->set_icon(get_editor_theme_icon(SNAME("Pause"))); + _play_button->set_button_icon(get_editor_theme_icon(SNAME("Pause"))); set_process(true); } } void AudioStreamEditor::_stop() { _player->stop(); - _play_button->set_icon(get_editor_theme_icon(SNAME("MainPlay"))); + _play_button->set_button_icon(get_editor_theme_icon(SNAME("MainPlay"))); _current = 0; _indicator->queue_redraw(); set_process(false); } void AudioStreamEditor::_on_finished() { - _play_button->set_icon(get_editor_theme_icon(SNAME("MainPlay"))); + _play_button->set_button_icon(get_editor_theme_icon(SNAME("MainPlay"))); if (!_pausing) { _current = 0; _indicator->queue_redraw(); diff --git a/editor/plugins/bone_map_editor_plugin.cpp b/editor/plugins/bone_map_editor_plugin.cpp index d81ec21705..8b105955e7 100644 --- a/editor/plugins/bone_map_editor_plugin.cpp +++ b/editor/plugins/bone_map_editor_plugin.cpp @@ -119,7 +119,7 @@ void BoneMapperItem::create_editor() { hbox->add_child(skeleton_bone_selector); picker_button = memnew(Button); - picker_button->set_icon(get_editor_theme_icon(SNAME("ClassList"))); + picker_button->set_button_icon(get_editor_theme_icon(SNAME("ClassList"))); picker_button->connect(SceneStringName(pressed), callable_mp(this, &BoneMapperItem::_open_picker)); hbox->add_child(picker_button); @@ -296,7 +296,7 @@ void BoneMapper::create_editor() { group_hbox->add_child(profile_group_selector); clear_mapping_button = memnew(Button); - clear_mapping_button->set_icon(get_editor_theme_icon(SNAME("Clear"))); + clear_mapping_button->set_button_icon(get_editor_theme_icon(SNAME("Clear"))); clear_mapping_button->set_tooltip_text(TTR("Clear mappings in current group.")); clear_mapping_button->connect(SceneStringName(pressed), callable_mp(this, &BoneMapper::_clear_mapping_current_group)); group_hbox->add_child(clear_mapping_button); @@ -859,7 +859,7 @@ void BoneMapper::auto_mapping_process(Ref<BoneMap> &p_bone_map) { // 4-1. Guess Finger int tips_index = -1; - bool thumb_tips_size = 0; + bool thumb_tips_size = false; bool named_finger_is_found = false; LocalVector<String> fingers; fingers.push_back("thumb|pollex"); @@ -994,7 +994,7 @@ void BoneMapper::auto_mapping_process(Ref<BoneMap> &p_bone_map) { } tips_index = -1; - thumb_tips_size = 0; + thumb_tips_size = false; named_finger_is_found = false; if (right_hand_or_palm != -1) { LocalVector<LocalVector<String>> right_fingers_map; diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index e9a796dae7..62793fbcb5 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -1464,10 +1464,12 @@ bool CanvasItemEditor::_gui_input_rotate(const Ref<InputEvent> &p_event) { List<CanvasItem *> selection = _get_edited_canvas_items(false, true, &has_locked_items); // Remove not movable nodes - for (CanvasItem *E : selection) { - if (!_is_node_movable(E, true)) { + for (List<CanvasItem *>::Element *E = selection.front(); E;) { + List<CanvasItem *>::Element *N = E->next(); + if (!_is_node_movable(E->get(), true)) { selection.erase(E); } + E = N; } drag_selection = selection; @@ -3964,39 +3966,38 @@ void CanvasItemEditor::set_current_tool(Tool p_tool) { } void CanvasItemEditor::_update_editor_settings() { - button_center_view->set_icon(get_editor_theme_icon(SNAME("CenterView"))); - select_button->set_icon(get_editor_theme_icon(SNAME("ToolSelect"))); + button_center_view->set_button_icon(get_editor_theme_icon(SNAME("CenterView"))); + select_button->set_button_icon(get_editor_theme_icon(SNAME("ToolSelect"))); select_sb->set_texture(get_editor_theme_icon(SNAME("EditorRect2D"))); - list_select_button->set_icon(get_editor_theme_icon(SNAME("ListSelect"))); - move_button->set_icon(get_editor_theme_icon(SNAME("ToolMove"))); - scale_button->set_icon(get_editor_theme_icon(SNAME("ToolScale"))); - rotate_button->set_icon(get_editor_theme_icon(SNAME("ToolRotate"))); - smart_snap_button->set_icon(get_editor_theme_icon(SNAME("Snap"))); - grid_snap_button->set_icon(get_editor_theme_icon(SNAME("SnapGrid"))); - snap_config_menu->set_icon(get_editor_theme_icon(SNAME("GuiTabMenuHl"))); - skeleton_menu->set_icon(get_editor_theme_icon(SNAME("Bone"))); - override_camera_button->set_icon(get_editor_theme_icon(SNAME("Camera2D"))); - pan_button->set_icon(get_editor_theme_icon(SNAME("ToolPan"))); - ruler_button->set_icon(get_editor_theme_icon(SNAME("Ruler"))); - pivot_button->set_icon(get_editor_theme_icon(SNAME("EditPivot"))); + list_select_button->set_button_icon(get_editor_theme_icon(SNAME("ListSelect"))); + move_button->set_button_icon(get_editor_theme_icon(SNAME("ToolMove"))); + scale_button->set_button_icon(get_editor_theme_icon(SNAME("ToolScale"))); + rotate_button->set_button_icon(get_editor_theme_icon(SNAME("ToolRotate"))); + smart_snap_button->set_button_icon(get_editor_theme_icon(SNAME("Snap"))); + grid_snap_button->set_button_icon(get_editor_theme_icon(SNAME("SnapGrid"))); + snap_config_menu->set_button_icon(get_editor_theme_icon(SNAME("GuiTabMenuHl"))); + skeleton_menu->set_button_icon(get_editor_theme_icon(SNAME("Bone"))); + pan_button->set_button_icon(get_editor_theme_icon(SNAME("ToolPan"))); + ruler_button->set_button_icon(get_editor_theme_icon(SNAME("Ruler"))); + pivot_button->set_button_icon(get_editor_theme_icon(SNAME("EditPivot"))); select_handle = get_editor_theme_icon(SNAME("EditorHandle")); anchor_handle = get_editor_theme_icon(SNAME("EditorControlAnchor")); - lock_button->set_icon(get_editor_theme_icon(SNAME("Lock"))); - unlock_button->set_icon(get_editor_theme_icon(SNAME("Unlock"))); - group_button->set_icon(get_editor_theme_icon(SNAME("Group"))); - ungroup_button->set_icon(get_editor_theme_icon(SNAME("Ungroup"))); - key_loc_button->set_icon(get_editor_theme_icon(SNAME("KeyPosition"))); - key_rot_button->set_icon(get_editor_theme_icon(SNAME("KeyRotation"))); - key_scale_button->set_icon(get_editor_theme_icon(SNAME("KeyScale"))); - key_insert_button->set_icon(get_editor_theme_icon(SNAME("Key"))); - key_auto_insert_button->set_icon(get_editor_theme_icon(SNAME("AutoKey"))); + lock_button->set_button_icon(get_editor_theme_icon(SNAME("Lock"))); + unlock_button->set_button_icon(get_editor_theme_icon(SNAME("Unlock"))); + group_button->set_button_icon(get_editor_theme_icon(SNAME("Group"))); + ungroup_button->set_button_icon(get_editor_theme_icon(SNAME("Ungroup"))); + key_loc_button->set_button_icon(get_editor_theme_icon(SNAME("KeyPosition"))); + key_rot_button->set_button_icon(get_editor_theme_icon(SNAME("KeyRotation"))); + key_scale_button->set_button_icon(get_editor_theme_icon(SNAME("KeyScale"))); + key_insert_button->set_button_icon(get_editor_theme_icon(SNAME("Key"))); + key_auto_insert_button->set_button_icon(get_editor_theme_icon(SNAME("AutoKey"))); // Use a different color for the active autokey icon to make them easier // to distinguish from the other key icons at the top. On a light theme, // the icon will be dark, so we need to lighten it before blending it // with the red color. const Color key_auto_color = EditorThemeManager::is_dark_theme() ? Color(1, 1, 1) : Color(4.25, 4.25, 4.25); key_auto_insert_button->add_theme_color_override("icon_pressed_color", key_auto_color.lerp(Color(1, 0, 0), 0.55)); - animation_menu->set_icon(get_editor_theme_icon(SNAME("GuiTabMenuHl"))); + animation_menu->set_button_icon(get_editor_theme_icon(SNAME("GuiTabMenuHl"))); context_toolbar_panel->add_theme_style_override(SceneStringName(panel), get_theme_stylebox(SNAME("ContextualToolbar"), EditorStringName(EditorStyles))); @@ -4014,8 +4015,6 @@ void CanvasItemEditor::_notification(int p_what) { case NOTIFICATION_READY: { _update_lock_and_group_button(); - EditorRunBar::get_singleton()->connect("play_pressed", callable_mp(this, &CanvasItemEditor::_update_override_camera_button).bind(true)); - EditorRunBar::get_singleton()->connect("stop_pressed", callable_mp(this, &CanvasItemEditor::_update_override_camera_button).bind(false)); ProjectSettings::get_singleton()->connect("settings_changed", callable_mp(this, &CanvasItemEditor::_project_settings_changed)); } break; @@ -4114,15 +4113,6 @@ void CanvasItemEditor::_notification(int p_what) { _update_editor_settings(); } break; - case NOTIFICATION_VISIBILITY_CHANGED: { - if (!is_visible() && override_camera_button->is_pressed()) { - EditorDebuggerNode *debugger = EditorDebuggerNode::get_singleton(); - - debugger->set_camera_override(EditorDebuggerNode::OVERRIDE_NONE); - override_camera_button->set_pressed(false); - } - } break; - case NOTIFICATION_APPLICATION_FOCUS_OUT: case NOTIFICATION_WM_WINDOW_FOCUS_OUT: { if (drag_type != DRAG_NONE) { @@ -4280,16 +4270,6 @@ void CanvasItemEditor::_button_toggle_grid_snap(bool p_status) { viewport->queue_redraw(); } -void CanvasItemEditor::_button_override_camera(bool p_pressed) { - EditorDebuggerNode *debugger = EditorDebuggerNode::get_singleton(); - - if (p_pressed) { - debugger->set_camera_override(EditorDebuggerNode::OVERRIDE_2D); - } else { - debugger->set_camera_override(EditorDebuggerNode::OVERRIDE_NONE); - } -} - void CanvasItemEditor::_button_tool_select(int p_index) { Button *tb[TOOL_MAX] = { select_button, list_select_button, move_button, scale_button, rotate_button, pivot_button, pan_button, ruler_button }; for (int i = 0; i < TOOL_MAX; i++) { @@ -4396,17 +4376,6 @@ void CanvasItemEditor::_insert_animation_keys(bool p_location, bool p_rotation, te->commit_insert_queue(); } -void CanvasItemEditor::_update_override_camera_button(bool p_game_running) { - if (p_game_running) { - override_camera_button->set_disabled(false); - override_camera_button->set_tooltip_text(TTR("Project Camera Override\nOverrides the running project's camera with the editor viewport camera.")); - } else { - override_camera_button->set_disabled(true); - override_camera_button->set_pressed(false); - override_camera_button->set_tooltip_text(TTR("Project Camera Override\nNo project instance running. Run the project from the editor to use this feature.")); - } -} - void CanvasItemEditor::_popup_callback(int p_op) { EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton(); last_option = MenuOption(p_op); @@ -5512,16 +5481,6 @@ CanvasItemEditor::CanvasItemEditor() { main_menu_hbox->add_child(memnew(VSeparator)); - override_camera_button = memnew(Button); - override_camera_button->set_theme_type_variation("FlatButton"); - main_menu_hbox->add_child(override_camera_button); - override_camera_button->connect(SceneStringName(toggled), callable_mp(this, &CanvasItemEditor::_button_override_camera)); - override_camera_button->set_toggle_mode(true); - override_camera_button->set_disabled(true); - _update_override_camera_button(false); - - main_menu_hbox->add_child(memnew(VSeparator)); - view_menu = memnew(MenuButton); view_menu->set_flat(false); view_menu->set_theme_type_variation("FlatMenuButton"); @@ -5661,7 +5620,7 @@ CanvasItemEditor::CanvasItemEditor() { snap_dialog->connect(SceneStringName(confirmed), callable_mp(this, &CanvasItemEditor::_snap_changed)); add_child(snap_dialog); - select_sb = Ref<StyleBoxTexture>(memnew(StyleBoxTexture)); + select_sb.instantiate(); selection_menu = memnew(PopupMenu); add_child(selection_menu); @@ -6264,7 +6223,7 @@ void CanvasItemEditorViewport::_update_theme() { for (BaseButton *btn : btn_list) { CheckBox *check = Object::cast_to<CheckBox>(btn); - check->set_icon(get_editor_theme_icon(check->get_text())); + check->set_button_icon(get_editor_theme_icon(check->get_text())); } label->add_theme_color_override(SceneStringName(font_color), get_theme_color(SNAME("warning_color"), EditorStringName(Editor))); diff --git a/editor/plugins/canvas_item_editor_plugin.h b/editor/plugins/canvas_item_editor_plugin.h index bae9efebc9..c5335bf9c1 100644 --- a/editor/plugins/canvas_item_editor_plugin.h +++ b/editor/plugins/canvas_item_editor_plugin.h @@ -335,7 +335,6 @@ private: Button *group_button = nullptr; Button *ungroup_button = nullptr; - Button *override_camera_button = nullptr; MenuButton *view_menu = nullptr; PopupMenu *grid_menu = nullptr; PopupMenu *theme_menu = nullptr; @@ -518,11 +517,8 @@ private: void _zoom_on_position(real_t p_zoom, Point2 p_position = Point2()); void _button_toggle_smart_snap(bool p_status); void _button_toggle_grid_snap(bool p_status); - void _button_override_camera(bool p_pressed); void _button_tool_select(int p_index); - void _update_override_camera_button(bool p_game_running); - HSplitContainer *left_panel_split = nullptr; HSplitContainer *right_panel_split = nullptr; VSplitContainer *bottom_split = nullptr; diff --git a/editor/plugins/control_editor_plugin.cpp b/editor/plugins/control_editor_plugin.cpp index cd13deb3e9..a52d949819 100644 --- a/editor/plugins/control_editor_plugin.cpp +++ b/editor/plugins/control_editor_plugin.cpp @@ -157,7 +157,7 @@ ControlPositioningWarning::ControlPositioningWarning() { void EditorPropertyAnchorsPreset::_set_read_only(bool p_read_only) { options->set_disabled(p_read_only); -}; +} void EditorPropertyAnchorsPreset::_option_selected(int p_which) { int64_t val = options->get_item_metadata(p_which); @@ -221,7 +221,7 @@ void EditorPropertySizeFlags::_set_read_only(bool p_read_only) { check->set_disabled(p_read_only); } flag_presets->set_disabled(p_read_only); -}; +} void EditorPropertySizeFlags::_preset_selected(int p_which) { int preset = flag_presets->get_item_id(p_which); @@ -536,7 +536,6 @@ ControlEditorPopupButton::ControlEditorPopupButton() { set_focus_mode(FOCUS_NONE); popup_panel = memnew(PopupPanel); - popup_panel->set_theme_type_variation("ControlEditorPopupPanel"); 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)); @@ -573,27 +572,27 @@ 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_editor_theme_icon(SNAME("ControlAlignTopLeft"))); - preset_buttons[PRESET_CENTER_TOP]->set_icon(get_editor_theme_icon(SNAME("ControlAlignCenterTop"))); - preset_buttons[PRESET_TOP_RIGHT]->set_icon(get_editor_theme_icon(SNAME("ControlAlignTopRight"))); + preset_buttons[PRESET_TOP_LEFT]->set_button_icon(get_editor_theme_icon(SNAME("ControlAlignTopLeft"))); + preset_buttons[PRESET_CENTER_TOP]->set_button_icon(get_editor_theme_icon(SNAME("ControlAlignCenterTop"))); + preset_buttons[PRESET_TOP_RIGHT]->set_button_icon(get_editor_theme_icon(SNAME("ControlAlignTopRight"))); - preset_buttons[PRESET_CENTER_LEFT]->set_icon(get_editor_theme_icon(SNAME("ControlAlignCenterLeft"))); - preset_buttons[PRESET_CENTER]->set_icon(get_editor_theme_icon(SNAME("ControlAlignCenter"))); - preset_buttons[PRESET_CENTER_RIGHT]->set_icon(get_editor_theme_icon(SNAME("ControlAlignCenterRight"))); + preset_buttons[PRESET_CENTER_LEFT]->set_button_icon(get_editor_theme_icon(SNAME("ControlAlignCenterLeft"))); + preset_buttons[PRESET_CENTER]->set_button_icon(get_editor_theme_icon(SNAME("ControlAlignCenter"))); + preset_buttons[PRESET_CENTER_RIGHT]->set_button_icon(get_editor_theme_icon(SNAME("ControlAlignCenterRight"))); - preset_buttons[PRESET_BOTTOM_LEFT]->set_icon(get_editor_theme_icon(SNAME("ControlAlignBottomLeft"))); - preset_buttons[PRESET_CENTER_BOTTOM]->set_icon(get_editor_theme_icon(SNAME("ControlAlignCenterBottom"))); - preset_buttons[PRESET_BOTTOM_RIGHT]->set_icon(get_editor_theme_icon(SNAME("ControlAlignBottomRight"))); + preset_buttons[PRESET_BOTTOM_LEFT]->set_button_icon(get_editor_theme_icon(SNAME("ControlAlignBottomLeft"))); + preset_buttons[PRESET_CENTER_BOTTOM]->set_button_icon(get_editor_theme_icon(SNAME("ControlAlignCenterBottom"))); + preset_buttons[PRESET_BOTTOM_RIGHT]->set_button_icon(get_editor_theme_icon(SNAME("ControlAlignBottomRight"))); - preset_buttons[PRESET_TOP_WIDE]->set_icon(get_editor_theme_icon(SNAME("ControlAlignTopWide"))); - preset_buttons[PRESET_HCENTER_WIDE]->set_icon(get_editor_theme_icon(SNAME("ControlAlignHCenterWide"))); - preset_buttons[PRESET_BOTTOM_WIDE]->set_icon(get_editor_theme_icon(SNAME("ControlAlignBottomWide"))); + preset_buttons[PRESET_TOP_WIDE]->set_button_icon(get_editor_theme_icon(SNAME("ControlAlignTopWide"))); + preset_buttons[PRESET_HCENTER_WIDE]->set_button_icon(get_editor_theme_icon(SNAME("ControlAlignHCenterWide"))); + preset_buttons[PRESET_BOTTOM_WIDE]->set_button_icon(get_editor_theme_icon(SNAME("ControlAlignBottomWide"))); - preset_buttons[PRESET_LEFT_WIDE]->set_icon(get_editor_theme_icon(SNAME("ControlAlignLeftWide"))); - preset_buttons[PRESET_VCENTER_WIDE]->set_icon(get_editor_theme_icon(SNAME("ControlAlignVCenterWide"))); - preset_buttons[PRESET_RIGHT_WIDE]->set_icon(get_editor_theme_icon(SNAME("ControlAlignRightWide"))); + preset_buttons[PRESET_LEFT_WIDE]->set_button_icon(get_editor_theme_icon(SNAME("ControlAlignLeftWide"))); + preset_buttons[PRESET_VCENTER_WIDE]->set_button_icon(get_editor_theme_icon(SNAME("ControlAlignVCenterWide"))); + preset_buttons[PRESET_RIGHT_WIDE]->set_button_icon(get_editor_theme_icon(SNAME("ControlAlignRightWide"))); - preset_buttons[PRESET_FULL_RECT]->set_icon(get_editor_theme_icon(SNAME("ControlAlignFullRect"))); + preset_buttons[PRESET_FULL_RECT]->set_button_icon(get_editor_theme_icon(SNAME("ControlAlignFullRect"))); } break; } } @@ -691,17 +690,17 @@ void SizeFlagPresetPicker::_notification(int p_notification) { case NOTIFICATION_ENTER_TREE: case NOTIFICATION_THEME_CHANGED: { if (vertical) { - preset_buttons[SIZE_SHRINK_BEGIN]->set_icon(get_editor_theme_icon(SNAME("ControlAlignCenterTop"))); - preset_buttons[SIZE_SHRINK_CENTER]->set_icon(get_editor_theme_icon(SNAME("ControlAlignCenter"))); - preset_buttons[SIZE_SHRINK_END]->set_icon(get_editor_theme_icon(SNAME("ControlAlignCenterBottom"))); + preset_buttons[SIZE_SHRINK_BEGIN]->set_button_icon(get_editor_theme_icon(SNAME("ControlAlignCenterTop"))); + preset_buttons[SIZE_SHRINK_CENTER]->set_button_icon(get_editor_theme_icon(SNAME("ControlAlignCenter"))); + preset_buttons[SIZE_SHRINK_END]->set_button_icon(get_editor_theme_icon(SNAME("ControlAlignCenterBottom"))); - preset_buttons[SIZE_FILL]->set_icon(get_editor_theme_icon(SNAME("ControlAlignVCenterWide"))); + preset_buttons[SIZE_FILL]->set_button_icon(get_editor_theme_icon(SNAME("ControlAlignVCenterWide"))); } else { - preset_buttons[SIZE_SHRINK_BEGIN]->set_icon(get_editor_theme_icon(SNAME("ControlAlignCenterLeft"))); - preset_buttons[SIZE_SHRINK_CENTER]->set_icon(get_editor_theme_icon(SNAME("ControlAlignCenter"))); - preset_buttons[SIZE_SHRINK_END]->set_icon(get_editor_theme_icon(SNAME("ControlAlignCenterRight"))); + preset_buttons[SIZE_SHRINK_BEGIN]->set_button_icon(get_editor_theme_icon(SNAME("ControlAlignCenterLeft"))); + preset_buttons[SIZE_SHRINK_CENTER]->set_button_icon(get_editor_theme_icon(SNAME("ControlAlignCenter"))); + preset_buttons[SIZE_SHRINK_END]->set_button_icon(get_editor_theme_icon(SNAME("ControlAlignCenterRight"))); - preset_buttons[SIZE_FILL]->set_icon(get_editor_theme_icon(SNAME("ControlAlignHCenterWide"))); + preset_buttons[SIZE_FILL]->set_button_icon(get_editor_theme_icon(SNAME("ControlAlignHCenterWide"))); } } break; } @@ -1051,9 +1050,9 @@ void ControlEditorToolbar::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: case NOTIFICATION_THEME_CHANGED: { - anchors_button->set_icon(get_editor_theme_icon(SNAME("ControlLayout"))); - anchor_mode_button->set_icon(get_editor_theme_icon(SNAME("Anchor"))); - containers_button->set_icon(get_editor_theme_icon(SNAME("ContainerLayout"))); + anchors_button->set_button_icon(get_editor_theme_icon(SNAME("ControlLayout"))); + anchor_mode_button->set_button_icon(get_editor_theme_icon(SNAME("Anchor"))); + containers_button->set_button_icon(get_editor_theme_icon(SNAME("ContainerLayout"))); } break; } } diff --git a/editor/plugins/control_editor_plugin.h b/editor/plugins/control_editor_plugin.h index 2672e8ef97..56e9f6ced4 100644 --- a/editor/plugins/control_editor_plugin.h +++ b/editor/plugins/control_editor_plugin.h @@ -241,7 +241,7 @@ protected: static ControlEditorToolbar *singleton; public: - bool is_anchors_mode_enabled() { return anchors_mode; }; + bool is_anchors_mode_enabled() { return anchors_mode; } static ControlEditorToolbar *get_singleton() { return singleton; } diff --git a/editor/plugins/curve_editor_plugin.cpp b/editor/plugins/curve_editor_plugin.cpp index e518cf7815..67006af44b 100644 --- a/editor/plugins/curve_editor_plugin.cpp +++ b/editor/plugins/curve_editor_plugin.cpp @@ -972,7 +972,7 @@ void CurveEditor::_notification(int p_what) { switch (p_what) { case NOTIFICATION_THEME_CHANGED: { spacing = Math::round(BASE_SPACING * get_theme_default_base_scale()); - snap_button->set_icon(get_editor_theme_icon(SNAME("SnapGrid"))); + snap_button->set_button_icon(get_editor_theme_icon(SNAME("SnapGrid"))); PopupMenu *p = presets_button->get_popup(); p->clear(); p->add_icon_item(get_editor_theme_icon(SNAME("CurveConstant")), TTR("Constant"), CurveEdit::PRESET_CONSTANT); diff --git a/editor/plugins/font_config_plugin.cpp b/editor/plugins/font_config_plugin.cpp index 6366d20539..7cf0b2d2ac 100644 --- a/editor/plugins/font_config_plugin.cpp +++ b/editor/plugins/font_config_plugin.cpp @@ -149,7 +149,7 @@ void EditorPropertyFontMetaOverride::_notification(int p_what) { case NOTIFICATION_ENTER_TREE: case NOTIFICATION_THEME_CHANGED: { if (button_add) { - button_add->set_icon(get_editor_theme_icon(SNAME("Add"))); + button_add->set_button_icon(get_editor_theme_icon(SNAME("Add"))); } } break; } @@ -295,7 +295,7 @@ void EditorPropertyFontMetaOverride::update_property() { hbox->add_child(prop); prop->set_h_size_flags(SIZE_EXPAND_FILL); Button *remove = memnew(Button); - remove->set_icon(get_editor_theme_icon(SNAME("Remove"))); + remove->set_button_icon(get_editor_theme_icon(SNAME("Remove"))); hbox->add_child(remove); remove->connect(SceneStringName(pressed), callable_mp(this, &EditorPropertyFontMetaOverride::_remove).bind(remove, name)); @@ -470,7 +470,7 @@ void EditorPropertyOTVariation::update_property() { Vector3i range = supported.get_value_at_index(i); EditorPropertyInteger *prop = memnew(EditorPropertyInteger); - prop->setup(range.x, range.y, false, 1, false, false); + prop->setup(range.x, range.y, false, true, false, false); prop->set_object_and_property(object.ptr(), "keys/" + itos(name_tag)); String name = TS->tag_to_name(name_tag); @@ -552,7 +552,7 @@ void EditorPropertyOTFeatures::_notification(int p_what) { case NOTIFICATION_ENTER_TREE: case NOTIFICATION_THEME_CHANGED: { if (button_add) { - button_add->set_icon(get_editor_theme_icon(SNAME("Add"))); + button_add->set_button_icon(get_editor_theme_icon(SNAME("Add"))); } } break; } @@ -789,7 +789,7 @@ void EditorPropertyOTFeatures::update_property() { hbox->add_child(prop); prop->set_h_size_flags(SIZE_EXPAND_FILL); Button *remove = memnew(Button); - remove->set_icon(get_editor_theme_icon(SNAME("Remove"))); + remove->set_button_icon(get_editor_theme_icon(SNAME("Remove"))); hbox->add_child(remove); remove->connect(SceneStringName(pressed), callable_mp(this, &EditorPropertyOTFeatures::_remove).bind(remove, name_tag)); @@ -798,7 +798,7 @@ void EditorPropertyOTFeatures::update_property() { } button_add = EditorInspector::create_inspector_action_button(TTR("Add Feature")); - button_add->set_icon(get_editor_theme_icon(SNAME("Add"))); + button_add->set_button_icon(get_editor_theme_icon(SNAME("Add"))); button_add->connect(SceneStringName(pressed), callable_mp(this, &EditorPropertyOTFeatures::_add_menu)); property_vbox->add_child(button_add); diff --git a/editor/plugins/game_view_plugin.cpp b/editor/plugins/game_view_plugin.cpp new file mode 100644 index 0000000000..5c1f81ee94 --- /dev/null +++ b/editor/plugins/game_view_plugin.cpp @@ -0,0 +1,487 @@ +/**************************************************************************/ +/* game_view_plugin.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/**************************************************************************/ + +#include "game_view_plugin.h" + +#include "core/debugger/debugger_marshalls.h" +#include "editor/editor_main_screen.h" +#include "editor/editor_node.h" +#include "editor/editor_settings.h" +#include "editor/themes/editor_scale.h" +#include "scene/gui/button.h" +#include "scene/gui/menu_button.h" +#include "scene/gui/panel.h" +#include "scene/gui/separator.h" + +void GameViewDebugger::_session_started(Ref<EditorDebuggerSession> p_session) { + Array setup_data; + Dictionary settings; + settings["editors/panning/2d_editor_panning_scheme"] = EDITOR_GET("editors/panning/2d_editor_panning_scheme"); + settings["editors/panning/simple_panning"] = EDITOR_GET("editors/panning/simple_panning"); + settings["editors/panning/warped_mouse_panning"] = EDITOR_GET("editors/panning/warped_mouse_panning"); + settings["editors/panning/2d_editor_pan_speed"] = EDITOR_GET("editors/panning/2d_editor_pan_speed"); + settings["canvas_item_editor/pan_view"] = DebuggerMarshalls::serialize_key_shortcut(ED_GET_SHORTCUT("canvas_item_editor/pan_view")); + setup_data.append(settings); + p_session->send_message("scene:runtime_node_select_setup", setup_data); + + Array type; + type.append(node_type); + p_session->send_message("scene:runtime_node_select_set_type", type); + Array visible; + visible.append(selection_visible); + p_session->send_message("scene:runtime_node_select_set_visible", visible); + Array mode; + mode.append(select_mode); + p_session->send_message("scene:runtime_node_select_set_mode", mode); + + emit_signal(SNAME("session_started")); +} + +void GameViewDebugger::_session_stopped() { + emit_signal(SNAME("session_stopped")); +} + +void GameViewDebugger::set_suspend(bool p_enabled) { + Array message; + message.append(p_enabled); + + for (Ref<EditorDebuggerSession> &I : sessions) { + if (I->is_active()) { + I->send_message("scene:suspend_changed", message); + } + } +} + +void GameViewDebugger::next_frame() { + for (Ref<EditorDebuggerSession> &I : sessions) { + if (I->is_active()) { + I->send_message("scene:next_frame", Array()); + } + } +} + +void GameViewDebugger::set_node_type(int p_type) { + node_type = p_type; + + Array message; + message.append(p_type); + + for (Ref<EditorDebuggerSession> &I : sessions) { + if (I->is_active()) { + I->send_message("scene:runtime_node_select_set_type", message); + } + } +} + +void GameViewDebugger::set_selection_visible(bool p_visible) { + selection_visible = p_visible; + + Array message; + message.append(p_visible); + + for (Ref<EditorDebuggerSession> &I : sessions) { + if (I->is_active()) { + I->send_message("scene:runtime_node_select_set_visible", message); + } + } +} + +void GameViewDebugger::set_select_mode(int p_mode) { + select_mode = p_mode; + + Array message; + message.append(p_mode); + + for (Ref<EditorDebuggerSession> &I : sessions) { + if (I->is_active()) { + I->send_message("scene:runtime_node_select_set_mode", message); + } + } +} + +void GameViewDebugger::set_camera_override(bool p_enabled) { + EditorDebuggerNode::get_singleton()->set_camera_override(p_enabled ? camera_override_mode : EditorDebuggerNode::OVERRIDE_NONE); +} + +void GameViewDebugger::set_camera_manipulate_mode(EditorDebuggerNode::CameraOverride p_mode) { + camera_override_mode = p_mode; + + if (EditorDebuggerNode::get_singleton()->get_camera_override() != EditorDebuggerNode::OVERRIDE_NONE) { + set_camera_override(true); + } +} + +void GameViewDebugger::reset_camera_2d_position() { + for (Ref<EditorDebuggerSession> &I : sessions) { + if (I->is_active()) { + I->send_message("scene:runtime_node_select_reset_camera_2d", Array()); + } + } +} + +void GameViewDebugger::reset_camera_3d_position() { + for (Ref<EditorDebuggerSession> &I : sessions) { + if (I->is_active()) { + I->send_message("scene:runtime_node_select_reset_camera_3d", Array()); + } + } +} + +void GameViewDebugger::setup_session(int p_session_id) { + Ref<EditorDebuggerSession> session = get_session(p_session_id); + ERR_FAIL_COND(session.is_null()); + + sessions.append(session); + + session->connect("started", callable_mp(this, &GameViewDebugger::_session_started).bind(session)); + session->connect("stopped", callable_mp(this, &GameViewDebugger::_session_stopped)); +} + +void GameViewDebugger::_bind_methods() { + ADD_SIGNAL(MethodInfo("session_started")); + ADD_SIGNAL(MethodInfo("session_stopped")); +} + +/////// + +void GameView::_sessions_changed() { + // The debugger session's `session_started/stopped` signal can be unreliable, so count it manually. + active_sessions = 0; + Array sessions = debugger->get_sessions(); + for (int i = 0; i < sessions.size(); i++) { + if (Object::cast_to<EditorDebuggerSession>(sessions[i])->is_active()) { + active_sessions++; + } + } + + _update_debugger_buttons(); +} + +void GameView::_update_debugger_buttons() { + bool empty = active_sessions == 0; + + suspend_button->set_disabled(empty); + camera_override_button->set_disabled(empty); + + PopupMenu *menu = camera_override_menu->get_popup(); + + bool disable_camera_reset = empty || !camera_override_button->is_pressed() || !menu->is_item_checked(menu->get_item_index(CAMERA_MODE_INGAME)); + menu->set_item_disabled(CAMERA_RESET_2D, disable_camera_reset); + menu->set_item_disabled(CAMERA_RESET_3D, disable_camera_reset); + + if (empty) { + suspend_button->set_pressed(false); + camera_override_button->set_pressed(false); + } + next_frame_button->set_disabled(!suspend_button->is_pressed()); +} + +void GameView::_suspend_button_toggled(bool p_pressed) { + _update_debugger_buttons(); + + debugger->set_suspend(p_pressed); +} + +void GameView::_node_type_pressed(int p_option) { + RuntimeNodeSelect::NodeType type = (RuntimeNodeSelect::NodeType)p_option; + for (int i = 0; i < RuntimeNodeSelect::NODE_TYPE_MAX; i++) { + node_type_button[i]->set_pressed_no_signal(i == type); + } + + _update_debugger_buttons(); + + debugger->set_node_type(type); +} + +void GameView::_select_mode_pressed(int p_option) { + RuntimeNodeSelect::SelectMode mode = (RuntimeNodeSelect::SelectMode)p_option; + for (int i = 0; i < RuntimeNodeSelect::SELECT_MODE_MAX; i++) { + select_mode_button[i]->set_pressed_no_signal(i == mode); + } + + debugger->set_select_mode(mode); +} + +void GameView::_hide_selection_toggled(bool p_pressed) { + hide_selection->set_button_icon(get_editor_theme_icon(p_pressed ? SNAME("GuiVisibilityHidden") : SNAME("GuiVisibilityVisible"))); + + debugger->set_selection_visible(!p_pressed); +} + +void GameView::_camera_override_button_toggled(bool p_pressed) { + _update_debugger_buttons(); + + debugger->set_camera_override(p_pressed); +} + +void GameView::_camera_override_menu_id_pressed(int p_id) { + PopupMenu *menu = camera_override_menu->get_popup(); + if (p_id != CAMERA_RESET_2D && p_id != CAMERA_RESET_3D) { + for (int i = 0; i < menu->get_item_count(); i++) { + menu->set_item_checked(i, false); + } + } + + switch (p_id) { + case CAMERA_RESET_2D: { + debugger->reset_camera_2d_position(); + } break; + case CAMERA_RESET_3D: { + debugger->reset_camera_3d_position(); + } break; + case CAMERA_MODE_INGAME: { + debugger->set_camera_manipulate_mode(EditorDebuggerNode::OVERRIDE_INGAME); + menu->set_item_checked(menu->get_item_index(p_id), true); + + _update_debugger_buttons(); + } break; + case CAMERA_MODE_EDITORS: { + debugger->set_camera_manipulate_mode(EditorDebuggerNode::OVERRIDE_EDITORS); + menu->set_item_checked(menu->get_item_index(p_id), true); + + _update_debugger_buttons(); + } break; + } +} + +void GameView::_notification(int p_what) { + switch (p_what) { + case NOTIFICATION_THEME_CHANGED: { + suspend_button->set_button_icon(get_editor_theme_icon(SNAME("Pause"))); + next_frame_button->set_button_icon(get_editor_theme_icon(SNAME("NextFrame"))); + + node_type_button[RuntimeNodeSelect::NODE_TYPE_NONE]->set_button_icon(get_editor_theme_icon(SNAME("InputEventJoypadMotion"))); + node_type_button[RuntimeNodeSelect::NODE_TYPE_2D]->set_button_icon(get_editor_theme_icon(SNAME("2DNodes"))); +#ifndef _3D_DISABLED + node_type_button[RuntimeNodeSelect::NODE_TYPE_3D]->set_button_icon(get_editor_theme_icon(SNAME("Node3D"))); +#endif // _3D_DISABLED + + select_mode_button[RuntimeNodeSelect::SELECT_MODE_SINGLE]->set_button_icon(get_editor_theme_icon(SNAME("ToolSelect"))); + select_mode_button[RuntimeNodeSelect::SELECT_MODE_LIST]->set_button_icon(get_editor_theme_icon(SNAME("ListSelect"))); + + hide_selection->set_button_icon(get_editor_theme_icon(hide_selection->is_pressed() ? SNAME("GuiVisibilityHidden") : SNAME("GuiVisibilityVisible"))); + + camera_override_button->set_button_icon(get_editor_theme_icon(SNAME("Camera"))); + camera_override_menu->set_button_icon(get_editor_theme_icon(SNAME("GuiTabMenuHl"))); + } break; + } +} + +void GameView::set_state(const Dictionary &p_state) { + if (p_state.has("hide_selection")) { + hide_selection->set_pressed(p_state["hide_selection"]); + _hide_selection_toggled(hide_selection->is_pressed()); + } + if (p_state.has("select_mode")) { + _select_mode_pressed(p_state["select_mode"]); + } + if (p_state.has("camera_override_mode")) { + _camera_override_menu_id_pressed(p_state["camera_override_mode"]); + } +} + +Dictionary GameView::get_state() const { + Dictionary d; + d["hide_selection"] = hide_selection->is_pressed(); + + for (int i = 0; i < RuntimeNodeSelect::SELECT_MODE_MAX; i++) { + if (select_mode_button[i]->is_pressed()) { + d["select_mode"] = i; + break; + } + } + + PopupMenu *menu = camera_override_menu->get_popup(); + for (int i = CAMERA_MODE_INGAME; i < CAMERA_MODE_EDITORS + 1; i++) { + if (menu->is_item_checked(menu->get_item_index(i))) { + d["camera_override_mode"] = i; + break; + } + } + + return d; +} + +GameView::GameView(Ref<GameViewDebugger> p_debugger) { + debugger = p_debugger; + + // Add some margin to the sides for better aesthetics. + // This prevents the first button's hover/pressed effect from "touching" the panel's border, + // which looks ugly. + MarginContainer *toolbar_margin = memnew(MarginContainer); + toolbar_margin->add_theme_constant_override("margin_left", 4 * EDSCALE); + toolbar_margin->add_theme_constant_override("margin_right", 4 * EDSCALE); + add_child(toolbar_margin); + + HBoxContainer *main_menu_hbox = memnew(HBoxContainer); + toolbar_margin->add_child(main_menu_hbox); + + suspend_button = memnew(Button); + main_menu_hbox->add_child(suspend_button); + suspend_button->set_toggle_mode(true); + suspend_button->set_theme_type_variation("FlatButton"); + suspend_button->connect(SceneStringName(toggled), callable_mp(this, &GameView::_suspend_button_toggled)); + suspend_button->set_tooltip_text(TTR("Suspend")); + + next_frame_button = memnew(Button); + main_menu_hbox->add_child(next_frame_button); + next_frame_button->set_theme_type_variation("FlatButton"); + next_frame_button->connect(SceneStringName(pressed), callable_mp(*debugger, &GameViewDebugger::next_frame)); + next_frame_button->set_tooltip_text(TTR("Next Frame")); + + main_menu_hbox->add_child(memnew(VSeparator)); + + node_type_button[RuntimeNodeSelect::NODE_TYPE_NONE] = memnew(Button); + main_menu_hbox->add_child(node_type_button[RuntimeNodeSelect::NODE_TYPE_NONE]); + node_type_button[RuntimeNodeSelect::NODE_TYPE_NONE]->set_text(TTR("Input")); + node_type_button[RuntimeNodeSelect::NODE_TYPE_NONE]->set_toggle_mode(true); + node_type_button[RuntimeNodeSelect::NODE_TYPE_NONE]->set_pressed(true); + node_type_button[RuntimeNodeSelect::NODE_TYPE_NONE]->set_theme_type_variation("FlatButton"); + node_type_button[RuntimeNodeSelect::NODE_TYPE_NONE]->connect(SceneStringName(pressed), callable_mp(this, &GameView::_node_type_pressed).bind(RuntimeNodeSelect::NODE_TYPE_NONE)); + node_type_button[RuntimeNodeSelect::NODE_TYPE_NONE]->set_tooltip_text(TTR("Allow game input.")); + + node_type_button[RuntimeNodeSelect::NODE_TYPE_2D] = memnew(Button); + main_menu_hbox->add_child(node_type_button[RuntimeNodeSelect::NODE_TYPE_2D]); + node_type_button[RuntimeNodeSelect::NODE_TYPE_2D]->set_text(TTR("2D")); + node_type_button[RuntimeNodeSelect::NODE_TYPE_2D]->set_toggle_mode(true); + node_type_button[RuntimeNodeSelect::NODE_TYPE_2D]->set_theme_type_variation("FlatButton"); + node_type_button[RuntimeNodeSelect::NODE_TYPE_2D]->connect(SceneStringName(pressed), callable_mp(this, &GameView::_node_type_pressed).bind(RuntimeNodeSelect::NODE_TYPE_2D)); + node_type_button[RuntimeNodeSelect::NODE_TYPE_2D]->set_tooltip_text(TTR("Disable game input and allow to select Node2Ds, Controls, and manipulate the 2D camera.")); + +#ifndef _3D_DISABLED + node_type_button[RuntimeNodeSelect::NODE_TYPE_3D] = memnew(Button); + main_menu_hbox->add_child(node_type_button[RuntimeNodeSelect::NODE_TYPE_3D]); + node_type_button[RuntimeNodeSelect::NODE_TYPE_3D]->set_text(TTR("3D")); + node_type_button[RuntimeNodeSelect::NODE_TYPE_3D]->set_toggle_mode(true); + node_type_button[RuntimeNodeSelect::NODE_TYPE_3D]->set_theme_type_variation("FlatButton"); + node_type_button[RuntimeNodeSelect::NODE_TYPE_3D]->connect(SceneStringName(pressed), callable_mp(this, &GameView::_node_type_pressed).bind(RuntimeNodeSelect::NODE_TYPE_3D)); + node_type_button[RuntimeNodeSelect::NODE_TYPE_3D]->set_tooltip_text(TTR("Disable game input and allow to select Node3Ds and manipulate the 3D camera.")); +#endif // _3D_DISABLED + + main_menu_hbox->add_child(memnew(VSeparator)); + + hide_selection = memnew(Button); + main_menu_hbox->add_child(hide_selection); + hide_selection->set_toggle_mode(true); + hide_selection->set_theme_type_variation("FlatButton"); + hide_selection->connect(SceneStringName(toggled), callable_mp(this, &GameView::_hide_selection_toggled)); + hide_selection->set_tooltip_text(TTR("Toggle Selection Visibility")); + + main_menu_hbox->add_child(memnew(VSeparator)); + + select_mode_button[RuntimeNodeSelect::SELECT_MODE_SINGLE] = memnew(Button); + main_menu_hbox->add_child(select_mode_button[RuntimeNodeSelect::SELECT_MODE_SINGLE]); + select_mode_button[RuntimeNodeSelect::SELECT_MODE_SINGLE]->set_toggle_mode(true); + select_mode_button[RuntimeNodeSelect::SELECT_MODE_SINGLE]->set_pressed(true); + select_mode_button[RuntimeNodeSelect::SELECT_MODE_SINGLE]->set_theme_type_variation("FlatButton"); + select_mode_button[RuntimeNodeSelect::SELECT_MODE_SINGLE]->connect(SceneStringName(pressed), callable_mp(this, &GameView::_select_mode_pressed).bind(RuntimeNodeSelect::SELECT_MODE_SINGLE)); + select_mode_button[RuntimeNodeSelect::SELECT_MODE_SINGLE]->set_shortcut(ED_SHORTCUT("spatial_editor/tool_select", TTR("Select Mode"), Key::Q)); + select_mode_button[RuntimeNodeSelect::SELECT_MODE_SINGLE]->set_shortcut_context(this); + select_mode_button[RuntimeNodeSelect::SELECT_MODE_SINGLE]->set_tooltip_text(keycode_get_string((Key)KeyModifierMask::CMD_OR_CTRL) + TTR("Alt+RMB: Show list of all nodes at position clicked.")); + + select_mode_button[RuntimeNodeSelect::SELECT_MODE_LIST] = memnew(Button); + main_menu_hbox->add_child(select_mode_button[RuntimeNodeSelect::SELECT_MODE_LIST]); + select_mode_button[RuntimeNodeSelect::SELECT_MODE_LIST]->set_toggle_mode(true); + select_mode_button[RuntimeNodeSelect::SELECT_MODE_LIST]->set_theme_type_variation("FlatButton"); + select_mode_button[RuntimeNodeSelect::SELECT_MODE_LIST]->connect(SceneStringName(pressed), callable_mp(this, &GameView::_select_mode_pressed).bind(RuntimeNodeSelect::SELECT_MODE_LIST)); + select_mode_button[RuntimeNodeSelect::SELECT_MODE_LIST]->set_tooltip_text(TTR("Show list of selectable nodes at position clicked.")); + + main_menu_hbox->add_child(memnew(VSeparator)); + + camera_override_button = memnew(Button); + main_menu_hbox->add_child(camera_override_button); + camera_override_button->set_toggle_mode(true); + camera_override_button->set_theme_type_variation("FlatButton"); + camera_override_button->connect(SceneStringName(toggled), callable_mp(this, &GameView::_camera_override_button_toggled)); + camera_override_button->set_tooltip_text(TTR("Override the in-game camera.")); + + camera_override_menu = memnew(MenuButton); + main_menu_hbox->add_child(camera_override_menu); + camera_override_menu->set_flat(false); + camera_override_menu->set_theme_type_variation("FlatMenuButton"); + camera_override_menu->set_h_size_flags(SIZE_SHRINK_END); + camera_override_menu->set_tooltip_text(TTR("Camera Override Options")); + + PopupMenu *menu = camera_override_menu->get_popup(); + menu->connect(SceneStringName(id_pressed), callable_mp(this, &GameView::_camera_override_menu_id_pressed)); + menu->add_item(TTR("Reset 2D Camera"), CAMERA_RESET_2D); + menu->add_item(TTR("Reset 3D Camera"), CAMERA_RESET_3D); + menu->add_separator(); + menu->add_radio_check_item(TTR("Manipulate In-Game"), CAMERA_MODE_INGAME); + menu->set_item_checked(menu->get_item_index(CAMERA_MODE_INGAME), true); + menu->add_radio_check_item(TTR("Manipulate From Editors"), CAMERA_MODE_EDITORS); + + _update_debugger_buttons(); + + panel = memnew(Panel); + add_child(panel); + panel->set_theme_type_variation("GamePanel"); + panel->set_v_size_flags(SIZE_EXPAND_FILL); + + p_debugger->connect("session_started", callable_mp(this, &GameView::_sessions_changed)); + p_debugger->connect("session_stopped", callable_mp(this, &GameView::_sessions_changed)); +} + +/////// + +void GameViewPlugin::make_visible(bool p_visible) { + game_view->set_visible(p_visible); +} + +void GameViewPlugin::set_state(const Dictionary &p_state) { + game_view->set_state(p_state); +} + +Dictionary GameViewPlugin::get_state() const { + return game_view->get_state(); +} + +void GameViewPlugin::_notification(int p_what) { + switch (p_what) { + case NOTIFICATION_ENTER_TREE: { + add_debugger_plugin(debugger); + } break; + case NOTIFICATION_EXIT_TREE: { + remove_debugger_plugin(debugger); + } break; + } +} + +GameViewPlugin::GameViewPlugin() { + debugger.instantiate(); + + game_view = memnew(GameView(debugger)); + game_view->set_v_size_flags(Control::SIZE_EXPAND_FILL); + EditorNode::get_singleton()->get_editor_main_screen()->get_control()->add_child(game_view); + game_view->hide(); +} + +GameViewPlugin::~GameViewPlugin() { +} diff --git a/editor/plugins/game_view_plugin.h b/editor/plugins/game_view_plugin.h new file mode 100644 index 0000000000..f8701c3e76 --- /dev/null +++ b/editor/plugins/game_view_plugin.h @@ -0,0 +1,152 @@ +/**************************************************************************/ +/* game_view_plugin.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/**************************************************************************/ + +#ifndef GAME_VIEW_PLUGIN_H +#define GAME_VIEW_PLUGIN_H + +#include "editor/debugger/editor_debugger_node.h" +#include "editor/plugins/editor_debugger_plugin.h" +#include "editor/plugins/editor_plugin.h" +#include "scene/debugger/scene_debugger.h" +#include "scene/gui/box_container.h" + +class GameViewDebugger : public EditorDebuggerPlugin { + GDCLASS(GameViewDebugger, EditorDebuggerPlugin); + +private: + Vector<Ref<EditorDebuggerSession>> sessions; + + int node_type = RuntimeNodeSelect::NODE_TYPE_NONE; + bool selection_visible = true; + int select_mode = RuntimeNodeSelect::SELECT_MODE_SINGLE; + EditorDebuggerNode::CameraOverride camera_override_mode = EditorDebuggerNode::OVERRIDE_INGAME; + + void _session_started(Ref<EditorDebuggerSession> p_session); + void _session_stopped(); + +protected: + static void _bind_methods(); + +public: + void set_suspend(bool p_enabled); + void next_frame(); + + void set_node_type(int p_type); + void set_select_mode(int p_mode); + + void set_selection_visible(bool p_visible); + + void set_camera_override(bool p_enabled); + void set_camera_manipulate_mode(EditorDebuggerNode::CameraOverride p_mode); + + void reset_camera_2d_position(); + void reset_camera_3d_position(); + + virtual void setup_session(int p_session_id) override; + + GameViewDebugger() {} +}; + +class GameView : public VBoxContainer { + GDCLASS(GameView, VBoxContainer); + + enum { + CAMERA_RESET_2D, + CAMERA_RESET_3D, + CAMERA_MODE_INGAME, + CAMERA_MODE_EDITORS, + }; + + Ref<GameViewDebugger> debugger; + + int active_sessions = 0; + + Button *suspend_button = nullptr; + Button *next_frame_button = nullptr; + + Button *node_type_button[RuntimeNodeSelect::NODE_TYPE_MAX]; + Button *select_mode_button[RuntimeNodeSelect::SELECT_MODE_MAX]; + + Button *hide_selection = nullptr; + + Button *camera_override_button = nullptr; + MenuButton *camera_override_menu = nullptr; + + Panel *panel = nullptr; + + void _sessions_changed(); + + void _update_debugger_buttons(); + + void _suspend_button_toggled(bool p_pressed); + + void _node_type_pressed(int p_option); + void _select_mode_pressed(int p_option); + + void _hide_selection_toggled(bool p_pressed); + + void _camera_override_button_toggled(bool p_pressed); + void _camera_override_menu_id_pressed(int p_id); + +protected: + void _notification(int p_what); + +public: + void set_state(const Dictionary &p_state); + Dictionary get_state() const; + + GameView(Ref<GameViewDebugger> p_debugger); +}; + +class GameViewPlugin : public EditorPlugin { + GDCLASS(GameViewPlugin, EditorPlugin); + + GameView *game_view = nullptr; + + Ref<GameViewDebugger> debugger; + +protected: + void _notification(int p_what); + +public: + virtual String get_name() const override { return "Game"; } + bool has_main_screen() const override { return true; } + virtual void edit(Object *p_object) override {} + virtual bool handles(Object *p_object) const override { return false; } + virtual void make_visible(bool p_visible) override; + + virtual void set_state(const Dictionary &p_state) override; + virtual Dictionary get_state() const override; + + GameViewPlugin(); + ~GameViewPlugin(); +}; + +#endif // GAME_VIEW_PLUGIN_H diff --git a/editor/plugins/gdextension_export_plugin.h b/editor/plugins/gdextension_export_plugin.h index ad6b534235..c8ed05c6b7 100644 --- a/editor/plugins/gdextension_export_plugin.h +++ b/editor/plugins/gdextension_export_plugin.h @@ -77,12 +77,14 @@ void GDExtensionExportPlugin::_export_file(const String &p_path, const String &p HashSet<String> archs; HashSet<String> features_wo_arch; + Vector<String> features_vector; for (const String &tag : p_features) { if (all_archs.has(tag)) { archs.insert(tag); } else { features_wo_arch.insert(tag); } + features_vector.append(tag); } if (archs.is_empty()) { @@ -90,11 +92,22 @@ void GDExtensionExportPlugin::_export_file(const String &p_path, const String &p } HashSet<String> libs_added; + struct FoundLibInfo { + int count = 0; + Vector<String> libs; + }; + HashMap<String, FoundLibInfo> libs_found; + for (const String &arch_tag : archs) { + if (arch_tag != "universal") { + libs_found[arch_tag] = FoundLibInfo(); + } + } for (const String &arch_tag : archs) { PackedStringArray tags; String library_path = GDExtensionLibraryLoader::find_extension_library( p_path, config, [features_wo_arch, arch_tag](const String &p_feature) { return features_wo_arch.has(p_feature) || (p_feature == arch_tag); }, &tags); + if (libs_added.has(library_path)) { continue; // Universal library, already added for another arch, do not duplicate. } @@ -122,15 +135,19 @@ void GDExtensionExportPlugin::_export_file(const String &p_path, const String &p String linker_flags = "-Wl,-U,_" + entry_symbol; add_ios_linker_flags(linker_flags); } - } else { - Vector<String> features_vector; - for (const String &E : p_features) { - features_vector.append(E); - } - if (get_export_platform().is_valid()) { - get_export_platform()->add_message(EditorExportPlatform::EXPORT_MESSAGE_WARNING, TTR("GDExtension"), vformat(TTR("No suitable library found for GDExtension: \"%s\". Possible feature flags for your platform: %s"), p_path, String(", ").join(features_vector))); + + // Update found library info. + if (arch_tag == "universal") { + for (const String &sub_arch_tag : archs) { + if (sub_arch_tag != "universal") { + libs_found[sub_arch_tag].count++; + libs_found[sub_arch_tag].libs.push_back(library_path); + } + } + } else { + libs_found[arch_tag].count++; + libs_found[arch_tag].libs.push_back(library_path); } - return; } Vector<SharedObject> dependencies_shared_objects = GDExtensionLibraryLoader::find_extension_dependencies(p_path, config, [p_features](String p_feature) { return p_features.has(p_feature); }); @@ -138,6 +155,18 @@ void GDExtensionExportPlugin::_export_file(const String &p_path, const String &p _add_shared_object(shared_object); } } + + for (const KeyValue<String, FoundLibInfo> &E : libs_found) { + if (E.value.count == 0) { + if (get_export_platform().is_valid()) { + get_export_platform()->add_message(EditorExportPlatform::EXPORT_MESSAGE_WARNING, TTR("GDExtension"), vformat(TTR("No \"%s\" library found for GDExtension: \"%s\". Possible feature flags for your platform: %s"), E.key, p_path, String(", ").join(features_vector))); + } + } else if (E.value.count > 1) { + if (get_export_platform().is_valid()) { + get_export_platform()->add_message(EditorExportPlatform::EXPORT_MESSAGE_WARNING, TTR("GDExtension"), vformat(TTR("Multiple \"%s\" libraries found for GDExtension: \"%s\": \"%s\"."), E.key, p_path, String(", ").join(E.value.libs))); + } + } + } } #endif // GDEXTENSION_EXPORT_PLUGIN_H diff --git a/editor/plugins/gizmos/collision_shape_3d_gizmo_plugin.cpp b/editor/plugins/gizmos/collision_shape_3d_gizmo_plugin.cpp index 01492c1dd0..573c686d57 100644 --- a/editor/plugins/gizmos/collision_shape_3d_gizmo_plugin.cpp +++ b/editor/plugins/gizmos/collision_shape_3d_gizmo_plugin.cpp @@ -93,7 +93,7 @@ String CollisionShape3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_g } if (Object::cast_to<CylinderShape3D>(*s)) { - return p_id == 0 ? "Radius" : "Height"; + return helper->cylinder_get_handle_name(p_id); } if (Object::cast_to<SeparationRayShape3D>(*s)) { @@ -219,25 +219,15 @@ void CollisionShape3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, i } if (Object::cast_to<CylinderShape3D>(*s)) { - Vector3 axis; - axis[p_id == 0 ? 0 : 1] = 1.0; Ref<CylinderShape3D> cs2 = s; - Vector3 ra, rb; - Geometry3D::get_closest_points_between_segments(Vector3(), axis * 4096, sg[0], sg[1], ra, rb); - float d = axis.dot(ra); - if (Node3DEditor::get_singleton()->is_snap_enabled()) { - d = Math::snapped(d, Node3DEditor::get_singleton()->get_translate_snap()); - } - - if (d < 0.001) { - d = 0.001; - } - if (p_id == 0) { - cs2->set_radius(d); - } else if (p_id == 1) { - cs2->set_height(d * 2.0); - } + real_t height = cs2->get_height(); + real_t radius = cs2->get_radius(); + Vector3 position; + helper->cylinder_set_handle(sg, p_id, height, radius, position); + cs2->set_height(height); + cs2->set_radius(radius); + cs->set_global_position(position); } } @@ -293,31 +283,7 @@ void CollisionShape3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo if (Object::cast_to<CylinderShape3D>(*s)) { Ref<CylinderShape3D> ss = s; - if (p_cancel) { - if (p_id == 0) { - ss->set_radius(p_restore); - } else { - ss->set_height(p_restore); - } - return; - } - - EditorUndoRedoManager *ur = EditorUndoRedoManager::get_singleton(); - if (p_id == 0) { - ur->create_action(TTR("Change Cylinder Shape Radius")); - ur->add_do_method(ss.ptr(), "set_radius", ss->get_radius()); - ur->add_undo_method(ss.ptr(), "set_radius", p_restore); - } else { - ur->create_action( - /// - - //////// - TTR("Change Cylinder Shape Height")); - ur->add_do_method(ss.ptr(), "set_height", ss->get_height()); - ur->add_undo_method(ss.ptr(), "set_height", p_restore); - } - - ur->commit_action(); + helper->cylinder_commit_handle(p_id, TTR("Change Cylinder Shape Radius"), TTR("Change Cylinder Shape Height"), p_cancel, cs, *ss, *ss); } if (Object::cast_to<SeparationRayShape3D>(*s)) { @@ -534,10 +500,7 @@ void CollisionShape3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { p_gizmo->add_collision_segments(collision_segments); - Vector<Vector3> handles = { - Vector3(cs2->get_radius(), 0, 0), - Vector3(0, cs2->get_height() * 0.5, 0) - }; + Vector<Vector3> handles = helper->cylinder_get_handles(cs2->get_height(), cs2->get_radius()); p_gizmo->add_handles(handles, handles_material); } @@ -575,20 +538,19 @@ void CollisionShape3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { if (Object::cast_to<ConvexPolygonShape3D>(*s)) { Vector<Vector3> points = Object::cast_to<ConvexPolygonShape3D>(*s)->get_points(); - if (points.size() > 3) { + if (points.size() > 1) { // Need at least 2 points for a line. Vector<Vector3> varr = Variant(points); Geometry3D::MeshData md; Error err = ConvexHullComputer::convex_hull(varr, md); if (err == OK) { - Vector<Vector3> points2; - points2.resize(md.edges.size() * 2); + Vector<Vector3> lines; + lines.resize(md.edges.size() * 2); for (uint32_t i = 0; i < md.edges.size(); i++) { - points2.write[i * 2 + 0] = md.vertices[md.edges[i].vertex_a]; - points2.write[i * 2 + 1] = md.vertices[md.edges[i].vertex_b]; + lines.write[i * 2 + 0] = md.vertices[md.edges[i].vertex_a]; + lines.write[i * 2 + 1] = md.vertices[md.edges[i].vertex_b]; } - - p_gizmo->add_lines(points2, material); - p_gizmo->add_collision_segments(points2); + p_gizmo->add_lines(lines, material); + p_gizmo->add_collision_segments(lines); } } } diff --git a/editor/plugins/gizmos/gizmo_3d_helper.cpp b/editor/plugins/gizmos/gizmo_3d_helper.cpp index 1226be90cb..ff1b67aa4a 100644 --- a/editor/plugins/gizmos/gizmo_3d_helper.cpp +++ b/editor/plugins/gizmos/gizmo_3d_helper.cpp @@ -139,3 +139,98 @@ void Gizmo3DHelper::box_commit_handle(const String &p_action_name, bool p_cancel ur->add_undo_property(p_position_object, p_position_property, initial_transform.get_origin()); ur->commit_action(); } + +Vector<Vector3> Gizmo3DHelper::cylinder_get_handles(real_t p_height, real_t p_radius) { + Vector<Vector3> handles; + handles.push_back(Vector3(p_radius, 0, 0)); + handles.push_back(Vector3(0, p_height * 0.5, 0)); + handles.push_back(Vector3(0, p_height * -0.5, 0)); + return handles; +} + +String Gizmo3DHelper::cylinder_get_handle_name(int p_id) const { + if (p_id == 0) { + return "Radius"; + } else { + return "Height"; + } +} + +void Gizmo3DHelper::cylinder_set_handle(const Vector3 p_segment[2], int p_id, real_t &r_height, real_t &r_radius, Vector3 &r_cylinder_position) { + int sign = p_id == 2 ? -1 : 1; + int axis = p_id == 0 ? 0 : 1; + + Vector3 axis_vector; + axis_vector[axis] = sign; + Vector3 ra, rb; + Geometry3D::get_closest_points_between_segments(axis_vector * -4096, axis_vector * 4096, p_segment[0], p_segment[1], ra, rb); + float d = axis_vector.dot(ra); + + // Snap to grid. + if (Node3DEditor::get_singleton()->is_snap_enabled()) { + d = Math::snapped(d, Node3DEditor::get_singleton()->get_translate_snap()); + } + + if (p_id == 0) { + // Adjust radius. + if (d < 0.001) { + d = 0.001; + } + r_radius = d; + r_cylinder_position = initial_transform.get_origin(); + } else if (p_id == 1 || p_id == 2) { + real_t initial_height = initial_value; + + // Adjust height. + if (Input::get_singleton()->is_key_pressed(Key::ALT)) { + r_height = d * 2.0; + } else { + r_height = (initial_height * 0.5) + d; + } + + if (r_height < 0.001) { + r_height = 0.001; + } + + // Adjust position. + if (Input::get_singleton()->is_key_pressed(Key::ALT)) { + r_cylinder_position = initial_transform.get_origin(); + } else { + Vector3 offset; + offset[axis] = (r_height - initial_height) * 0.5 * sign; + r_cylinder_position = initial_transform.xform(offset); + } + } +} + +void Gizmo3DHelper::cylinder_commit_handle(int p_id, const String &p_radius_action_name, const String &p_height_action_name, bool p_cancel, Object *p_position_object, Object *p_height_object, Object *p_radius_object, const StringName &p_position_property, const StringName &p_height_property, const StringName &p_radius_property) { + if (!p_height_object) { + p_height_object = p_position_object; + } + if (!p_radius_object) { + p_radius_object = p_position_object; + } + + if (p_cancel) { + if (p_id == 0) { + p_radius_object->set(p_radius_property, initial_value); + } else { + p_height_object->set(p_height_property, initial_value); + } + p_position_object->set(p_position_property, initial_transform.get_origin()); + return; + } + + EditorUndoRedoManager *ur = EditorUndoRedoManager::get_singleton(); + ur->create_action(p_id == 0 ? p_radius_action_name : p_height_action_name); + if (p_id == 0) { + ur->add_do_property(p_radius_object, p_radius_property, p_radius_object->get(p_radius_property)); + ur->add_undo_property(p_radius_object, p_radius_property, initial_value); + } else { + ur->add_do_property(p_height_object, p_height_property, p_height_object->get(p_height_property)); + ur->add_do_property(p_position_object, p_position_property, p_position_object->get(p_position_property)); + ur->add_undo_property(p_height_object, p_height_property, initial_value); + ur->add_undo_property(p_position_object, p_position_property, initial_transform.get_origin()); + } + ur->commit_action(); +} diff --git a/editor/plugins/gizmos/gizmo_3d_helper.h b/editor/plugins/gizmos/gizmo_3d_helper.h index 387ea020b8..6d27e54770 100644 --- a/editor/plugins/gizmos/gizmo_3d_helper.h +++ b/editor/plugins/gizmos/gizmo_3d_helper.h @@ -50,6 +50,11 @@ public: String box_get_handle_name(int p_id) const; void box_set_handle(const Vector3 p_segment[2], int p_id, Vector3 &r_box_size, Vector3 &r_box_position); void box_commit_handle(const String &p_action_name, bool p_cancel, Object *p_position_object, Object *p_size_object = nullptr, const StringName &p_position_property = "global_position", const StringName &p_size_property = "size"); + + Vector<Vector3> cylinder_get_handles(real_t p_height, real_t p_radius); + String cylinder_get_handle_name(int p_id) const; + void cylinder_set_handle(const Vector3 p_segment[2], int p_id, real_t &r_height, real_t &r_radius, Vector3 &r_cylinder_position); + void cylinder_commit_handle(int p_id, const String &p_radius_action_name, const String &p_height_action_name, bool p_cancel, Object *p_position_object, Object *p_height_object = nullptr, Object *p_radius_object = nullptr, const StringName &p_position_property = "global_position", const StringName &p_height_property = "height", const StringName &p_radius_property = "radius"); }; #endif // GIZMO_3D_HELPER_H diff --git a/editor/plugins/gizmos/marker_3d_gizmo_plugin.cpp b/editor/plugins/gizmos/marker_3d_gizmo_plugin.cpp index 39ae020d53..5a6527f876 100644 --- a/editor/plugins/gizmos/marker_3d_gizmo_plugin.cpp +++ b/editor/plugins/gizmos/marker_3d_gizmo_plugin.cpp @@ -36,7 +36,7 @@ #include "scene/3d/marker_3d.h" Marker3DGizmoPlugin::Marker3DGizmoPlugin() { - pos3d_mesh = Ref<ArrayMesh>(memnew(ArrayMesh)); + pos3d_mesh.instantiate(); Vector<Vector3> cursor_points; Vector<Color> cursor_colors; diff --git a/editor/plugins/gpu_particles_collision_sdf_editor_plugin.cpp b/editor/plugins/gpu_particles_collision_sdf_editor_plugin.cpp index c21a1b5dd6..4c2a3b60f8 100644 --- a/editor/plugins/gpu_particles_collision_sdf_editor_plugin.cpp +++ b/editor/plugins/gpu_particles_collision_sdf_editor_plugin.cpp @@ -181,7 +181,7 @@ GPUParticlesCollisionSDF3DEditorPlugin::GPUParticlesCollisionSDF3DEditorPlugin() bake_hb->hide(); bake = memnew(Button); bake->set_theme_type_variation("FlatButton"); - bake->set_icon(EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("Bake"), EditorStringName(EditorIcons))); + bake->set_button_icon(EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("Bake"), EditorStringName(EditorIcons))); bake->set_text(TTR("Bake SDF")); bake->connect(SceneStringName(pressed), callable_mp(this, &GPUParticlesCollisionSDF3DEditorPlugin::_bake)); bake_hb->add_child(bake); diff --git a/editor/plugins/gradient_editor_plugin.cpp b/editor/plugins/gradient_editor_plugin.cpp index 1300394ca3..291ffc24d2 100644 --- a/editor/plugins/gradient_editor_plugin.cpp +++ b/editor/plugins/gradient_editor_plugin.cpp @@ -604,8 +604,8 @@ void GradientEditor::set_gradient(const Ref<Gradient> &p_gradient) { void GradientEditor::_notification(int p_what) { switch (p_what) { case NOTIFICATION_THEME_CHANGED: { - reverse_button->set_icon(get_editor_theme_icon(SNAME("ReverseGradient"))); - snap_button->set_icon(get_editor_theme_icon(SNAME("SnapGrid"))); + reverse_button->set_button_icon(get_editor_theme_icon(SNAME("ReverseGradient"))); + snap_button->set_button_icon(get_editor_theme_icon(SNAME("SnapGrid"))); } break; case NOTIFICATION_READY: { Ref<Gradient> gradient = gradient_editor_rect->get_gradient(); diff --git a/editor/plugins/gradient_texture_2d_editor_plugin.cpp b/editor/plugins/gradient_texture_2d_editor_plugin.cpp index 5bf1422780..46c9f4501b 100644 --- a/editor/plugins/gradient_texture_2d_editor_plugin.cpp +++ b/editor/plugins/gradient_texture_2d_editor_plugin.cpp @@ -262,8 +262,8 @@ void GradientTexture2DEditor::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: case NOTIFICATION_THEME_CHANGED: { - reverse_button->set_icon(get_editor_theme_icon(SNAME("ReverseGradient"))); - snap_button->set_icon(get_editor_theme_icon(SNAME("SnapGrid"))); + reverse_button->set_button_icon(get_editor_theme_icon(SNAME("ReverseGradient"))); + snap_button->set_button_icon(get_editor_theme_icon(SNAME("SnapGrid"))); } break; case NOTIFICATION_READY: { if (texture.is_valid()) { diff --git a/editor/plugins/input_event_editor_plugin.cpp b/editor/plugins/input_event_editor_plugin.cpp index 30debfc14f..0c3ceff977 100644 --- a/editor/plugins/input_event_editor_plugin.cpp +++ b/editor/plugins/input_event_editor_plugin.cpp @@ -37,7 +37,7 @@ void InputEventConfigContainer::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: case NOTIFICATION_THEME_CHANGED: { - open_config_button->set_icon(get_editor_theme_icon(SNAME("Edit"))); + open_config_button->set_button_icon(get_editor_theme_icon(SNAME("Edit"))); } break; } } diff --git a/editor/plugins/light_occluder_2d_editor_plugin.cpp b/editor/plugins/light_occluder_2d_editor_plugin.cpp index 429add4540..e3b59f9bfb 100644 --- a/editor/plugins/light_occluder_2d_editor_plugin.cpp +++ b/editor/plugins/light_occluder_2d_editor_plugin.cpp @@ -35,8 +35,8 @@ Ref<OccluderPolygon2D> LightOccluder2DEditor::_ensure_occluder() const { Ref<OccluderPolygon2D> occluder = node->get_occluder_polygon(); - if (!occluder.is_valid()) { - occluder = Ref<OccluderPolygon2D>(memnew(OccluderPolygon2D)); + if (occluder.is_null()) { + occluder.instantiate(); node->set_occluder_polygon(occluder); } return occluder; diff --git a/editor/plugins/lightmap_gi_editor_plugin.cpp b/editor/plugins/lightmap_gi_editor_plugin.cpp index 854ab7de8f..6e5dfd44d4 100644 --- a/editor/plugins/lightmap_gi_editor_plugin.cpp +++ b/editor/plugins/lightmap_gi_editor_plugin.cpp @@ -177,7 +177,7 @@ LightmapGIEditorPlugin::LightmapGIEditorPlugin() { bake->set_theme_type_variation("FlatButton"); // TODO: Rework this as a dedicated toolbar control so we can hook into theme changes and update it // when the editor theme updates. - bake->set_icon(EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("Bake"), EditorStringName(EditorIcons))); + bake->set_button_icon(EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("Bake"), EditorStringName(EditorIcons))); bake->set_text(TTR("Bake Lightmaps")); #ifdef MODULE_LIGHTMAPPER_RD_ENABLED diff --git a/editor/plugins/material_editor_plugin.cpp b/editor/plugins/material_editor_plugin.cpp index 2702b6c909..8bdc763ebe 100644 --- a/editor/plugins/material_editor_plugin.cpp +++ b/editor/plugins/material_editor_plugin.cpp @@ -56,9 +56,15 @@ void MaterialEditor::gui_input(const Ref<InputEvent> &p_event) { if (mm.is_valid() && (mm->get_button_mask().has_flag(MouseButtonMask::LEFT))) { rot.x -= mm->get_relative().y * 0.01; rot.y -= mm->get_relative().x * 0.01; - - rot.x = CLAMP(rot.x, -Math_PI / 2, Math_PI / 2); + if (quad_instance->is_visible()) { + // Clamp rotation so the quad is always visible. + const real_t limit = Math::deg_to_rad(80.0); + rot = rot.clampf(-limit, limit); + } else { + rot.x = CLAMP(rot.x, -Math_PI / 2, Math_PI / 2); + } _update_rotation(); + _store_rotation_metadata(); } } @@ -70,6 +76,7 @@ void MaterialEditor::_update_theme_item_cache() { theme_cache.sphere_icon = get_editor_theme_icon(SNAME("MaterialPreviewSphere")); theme_cache.box_icon = get_editor_theme_icon(SNAME("MaterialPreviewCube")); + theme_cache.quad_icon = get_editor_theme_icon(SNAME("MaterialPreviewQuad")); theme_cache.checkerboard = get_editor_theme_icon(SNAME("Checkerboard")); } @@ -77,11 +84,12 @@ void MaterialEditor::_update_theme_item_cache() { void MaterialEditor::_notification(int p_what) { switch (p_what) { case NOTIFICATION_THEME_CHANGED: { - light_1_switch->set_icon(theme_cache.light_1_icon); - light_2_switch->set_icon(theme_cache.light_2_icon); + light_1_switch->set_button_icon(theme_cache.light_1_icon); + light_2_switch->set_button_icon(theme_cache.light_2_icon); - sphere_switch->set_icon(theme_cache.sphere_icon); - box_switch->set_icon(theme_cache.box_icon); + sphere_switch->set_button_icon(theme_cache.sphere_icon); + box_switch->set_button_icon(theme_cache.box_icon); + quad_switch->set_button_icon(theme_cache.quad_icon); error_label->add_theme_color_override(SceneStringName(font_color), get_theme_color(SNAME("error_color"), EditorStringName(Editor))); } break; @@ -95,6 +103,18 @@ void MaterialEditor::_notification(int p_what) { } } +void MaterialEditor::_set_rotation(real_t p_x_degrees, real_t p_y_degrees) { + rot.x = Math::deg_to_rad(p_x_degrees); + rot.y = Math::deg_to_rad(p_y_degrees); + _update_rotation(); +} + +// Store the rotation so it can persist when switching between materials. +void MaterialEditor::_store_rotation_metadata() { + Vector2 rotation_degrees = Vector2(Math::rad_to_deg(rot.x), Math::rad_to_deg(rot.y)); + EditorSettings::get_singleton()->set_project_metadata("inspector_options", "material_preview_rotation", rotation_degrees); +} + void MaterialEditor::_update_rotation() { Transform3D t; t.basis.rotate(Vector3(0, 1, 0), -rot.y); @@ -124,6 +144,7 @@ void MaterialEditor::edit(Ref<Material> p_material, const Ref<Environment> &p_en vc->show(); sphere_instance->set_material_override(material); box_instance->set_material_override(material); + quad_instance->set_material_override(material); break; default: layout_error->show(); @@ -136,10 +157,6 @@ void MaterialEditor::edit(Ref<Material> p_material, const Ref<Environment> &p_en } else { hide(); } - - rot.x = Math::deg_to_rad(-15.0); - rot.y = Math::deg_to_rad(30.0); - _update_rotation(); } void MaterialEditor::_on_light_1_switch_pressed() { @@ -151,19 +168,36 @@ void MaterialEditor::_on_light_2_switch_pressed() { } void MaterialEditor::_on_sphere_switch_pressed() { - box_instance->hide(); sphere_instance->show(); + box_instance->hide(); + quad_instance->hide(); box_switch->set_pressed(false); - sphere_switch->set_pressed(true); - EditorSettings::get_singleton()->set_project_metadata("inspector_options", "material_preview_on_sphere", true); + quad_switch->set_pressed(false); + _set_rotation(-15.0, 30.0); + _store_rotation_metadata(); + EditorSettings::get_singleton()->set_project_metadata("inspector_options", "material_preview_mesh", "sphere"); } void MaterialEditor::_on_box_switch_pressed() { + sphere_instance->hide(); box_instance->show(); + quad_instance->hide(); + sphere_switch->set_pressed(false); + quad_switch->set_pressed(false); + _set_rotation(-15.0, 30.0); + _store_rotation_metadata(); + EditorSettings::get_singleton()->set_project_metadata("inspector_options", "material_preview_mesh", "box"); +} + +void MaterialEditor::_on_quad_switch_pressed() { sphere_instance->hide(); - box_switch->set_pressed(true); + box_instance->hide(); + quad_instance->show(); sphere_switch->set_pressed(false); - EditorSettings::get_singleton()->set_project_metadata("inspector_options", "material_preview_on_sphere", false); + box_switch->set_pressed(false); + _set_rotation(0.0, 0.0); + _store_rotation_metadata(); + EditorSettings::get_singleton()->set_project_metadata("inspector_options", "material_preview_mesh", "quad"); } MaterialEditor::MaterialEditor() { @@ -213,7 +247,7 @@ MaterialEditor::MaterialEditor() { viewport = memnew(SubViewport); Ref<World3D> world_3d; world_3d.instantiate(); - viewport->set_world_3d(world_3d); //use own world + viewport->set_world_3d(world_3d); // Use own world. vc->add_child(viewport); viewport->set_disable_input(true); viewport->set_transparent_background(true); @@ -221,7 +255,7 @@ MaterialEditor::MaterialEditor() { camera = memnew(Camera3D); camera->set_transform(Transform3D(Basis(), Vector3(0, 0, 1.1))); - // Use low field of view so the sphere/box is fully encompassed within the preview, + // Use low field of view so the sphere/box/quad is fully encompassed within the preview, // without much distortion. camera->set_perspective(20, 0.1, 10); camera->make_current(); @@ -249,13 +283,19 @@ MaterialEditor::MaterialEditor() { box_instance = memnew(MeshInstance3D); rotation->add_child(box_instance); - box_instance->set_transform(Transform3D() * 0.25); + quad_instance = memnew(MeshInstance3D); + rotation->add_child(quad_instance); + sphere_instance->set_transform(Transform3D() * 0.375); + box_instance->set_transform(Transform3D() * 0.25); + quad_instance->set_transform(Transform3D() * 0.375); sphere_mesh.instantiate(); sphere_instance->set_mesh(sphere_mesh); box_mesh.instantiate(); box_instance->set_mesh(box_mesh); + quad_mesh.instantiate(); + quad_instance->set_mesh(quad_mesh); set_custom_minimum_size(Size2(1, 150) * EDSCALE); @@ -269,17 +309,21 @@ MaterialEditor::MaterialEditor() { sphere_switch = memnew(Button); sphere_switch->set_theme_type_variation("PreviewLightButton"); sphere_switch->set_toggle_mode(true); - sphere_switch->set_pressed(true); vb_shape->add_child(sphere_switch); sphere_switch->connect(SceneStringName(pressed), callable_mp(this, &MaterialEditor::_on_sphere_switch_pressed)); box_switch = memnew(Button); box_switch->set_theme_type_variation("PreviewLightButton"); box_switch->set_toggle_mode(true); - box_switch->set_pressed(false); vb_shape->add_child(box_switch); box_switch->connect(SceneStringName(pressed), callable_mp(this, &MaterialEditor::_on_box_switch_pressed)); + quad_switch = memnew(Button); + quad_switch->set_theme_type_variation("PreviewLightButton"); + quad_switch->set_toggle_mode(true); + vb_shape->add_child(quad_switch); + quad_switch->connect(SceneStringName(pressed), callable_mp(this, &MaterialEditor::_on_quad_switch_pressed)); + layout_3d->add_spacer(); VBoxContainer *vb_light = memnew(VBoxContainer); @@ -299,14 +343,23 @@ MaterialEditor::MaterialEditor() { vb_light->add_child(light_2_switch); light_2_switch->connect(SceneStringName(pressed), callable_mp(this, &MaterialEditor::_on_light_2_switch_pressed)); - if (EditorSettings::get_singleton()->get_project_metadata("inspector_options", "material_preview_on_sphere", true)) { + String shape = EditorSettings::get_singleton()->get_project_metadata("inspector_options", "material_preview_mesh", "sphere"); + if (shape == "sphere") { box_instance->hide(); + quad_instance->hide(); + sphere_switch->set_pressed_no_signal(true); + } else if (shape == "box") { + sphere_instance->hide(); + quad_instance->hide(); + box_switch->set_pressed_no_signal(true); } else { - box_instance->show(); sphere_instance->hide(); - box_switch->set_pressed(true); - sphere_switch->set_pressed(false); + box_instance->hide(); + quad_switch->set_pressed_no_signal(true); } + + Vector2 stored_rot = EditorSettings::get_singleton()->get_project_metadata("inspector_options", "material_preview_rotation", Vector2()); + _set_rotation(stored_rot.x, stored_rot.y); } /////////////////////// diff --git a/editor/plugins/material_editor_plugin.h b/editor/plugins/material_editor_plugin.h index 28c59d27db..c1b37a5831 100644 --- a/editor/plugins/material_editor_plugin.h +++ b/editor/plugins/material_editor_plugin.h @@ -62,6 +62,7 @@ class MaterialEditor : public Control { Node3D *rotation = nullptr; MeshInstance3D *sphere_instance = nullptr; MeshInstance3D *box_instance = nullptr; + MeshInstance3D *quad_instance = nullptr; DirectionalLight3D *light1 = nullptr; DirectionalLight3D *light2 = nullptr; Camera3D *camera = nullptr; @@ -69,6 +70,7 @@ class MaterialEditor : public Control { Ref<SphereMesh> sphere_mesh; Ref<BoxMesh> box_mesh; + Ref<QuadMesh> quad_mesh; VBoxContainer *layout_error = nullptr; Label *error_label = nullptr; @@ -80,6 +82,7 @@ class MaterialEditor : public Control { Button *sphere_switch = nullptr; Button *box_switch = nullptr; + Button *quad_switch = nullptr; Button *light_1_switch = nullptr; Button *light_2_switch = nullptr; @@ -88,6 +91,7 @@ class MaterialEditor : public Control { Ref<Texture2D> light_2_icon; Ref<Texture2D> sphere_icon; Ref<Texture2D> box_icon; + Ref<Texture2D> quad_icon; Ref<Texture2D> checkerboard; } theme_cache; @@ -95,11 +99,14 @@ class MaterialEditor : public Control { void _on_light_2_switch_pressed(); void _on_sphere_switch_pressed(); void _on_box_switch_pressed(); + void _on_quad_switch_pressed(); protected: virtual void _update_theme_item_cache() override; void _notification(int p_what); void gui_input(const Ref<InputEvent> &p_event) override; + void _set_rotation(real_t p_x_degrees, real_t p_y_degrees); + void _store_rotation_metadata(); void _update_rotation(); public: diff --git a/editor/plugins/mesh_editor_plugin.cpp b/editor/plugins/mesh_editor_plugin.cpp index c8eda600b8..645dd1784e 100644 --- a/editor/plugins/mesh_editor_plugin.cpp +++ b/editor/plugins/mesh_editor_plugin.cpp @@ -58,8 +58,8 @@ void MeshEditor::_update_theme_item_cache() { void MeshEditor::_notification(int p_what) { switch (p_what) { case NOTIFICATION_THEME_CHANGED: { - light_1_switch->set_icon(theme_cache.light_1_icon); - light_2_switch->set_icon(theme_cache.light_2_icon); + light_1_switch->set_button_icon(theme_cache.light_1_icon); + light_2_switch->set_button_icon(theme_cache.light_2_icon); } break; } } diff --git a/editor/plugins/mesh_instance_3d_editor_plugin.cpp b/editor/plugins/mesh_instance_3d_editor_plugin.cpp index eda6cdffb1..fdc222e64f 100644 --- a/editor/plugins/mesh_instance_3d_editor_plugin.cpp +++ b/editor/plugins/mesh_instance_3d_editor_plugin.cpp @@ -40,6 +40,7 @@ #include "scene/3d/physics/collision_shape_3d.h" #include "scene/3d/physics/physics_body_3d.h" #include "scene/3d/physics/static_body_3d.h" +#include "scene/gui/aspect_ratio_container.h" #include "scene/gui/box_container.h" #include "scene/gui/dialogs.h" #include "scene/gui/menu_button.h" @@ -445,10 +446,43 @@ void MeshInstance3DEditor::_debug_uv_draw() { } debug_uv->set_clip_contents(true); - debug_uv->draw_rect(Rect2(Vector2(), debug_uv->get_size()), get_theme_color(SNAME("dark_color_3"), EditorStringName(Editor))); + debug_uv->draw_rect( + Rect2(Vector2(), debug_uv->get_size()), + get_theme_color(SNAME("dark_color_3"), EditorStringName(Editor))); + + // Draw an outline to represent the UV2's beginning and end area (useful on Black OLED theme). + // Top-left coordinate needs to be `(1, 1)` to prevent `clip_contents` from clipping the top and left lines. + debug_uv->draw_rect( + Rect2(Vector2(1, 1), debug_uv->get_size() - Vector2(1, 1)), + get_theme_color(SNAME("mono_color"), EditorStringName(Editor)) * Color(1, 1, 1, 0.125), + false, + Math::round(EDSCALE)); + + for (int x = 1; x <= 7; x++) { + debug_uv->draw_line( + Vector2(debug_uv->get_size().x * 0.125 * x, 0), + Vector2(debug_uv->get_size().x * 0.125 * x, debug_uv->get_size().y), + get_theme_color(SNAME("mono_color"), EditorStringName(Editor)) * Color(1, 1, 1, 0.125), + Math::round(EDSCALE)); + } + + for (int y = 1; y <= 7; y++) { + debug_uv->draw_line( + Vector2(0, debug_uv->get_size().y * 0.125 * y), + Vector2(debug_uv->get_size().x, debug_uv->get_size().y * 0.125 * y), + get_theme_color(SNAME("mono_color"), EditorStringName(Editor)) * Color(1, 1, 1, 0.125), + Math::round(EDSCALE)); + } + debug_uv->draw_set_transform(Vector2(), 0, debug_uv->get_size()); + // Use a translucent color to allow overlapping triangles to be visible. - debug_uv->draw_multiline(uv_lines, get_theme_color(SNAME("mono_color"), EditorStringName(Editor)) * Color(1, 1, 1, 0.5)); + // Divide line width by the drawing scale set above, so that line width is consistent regardless of dialog size. + // Aspect ratio is preserved by the parent AspectRatioContainer, so we only need to check the X size which is always equal to Y. + debug_uv->draw_multiline( + uv_lines, + get_theme_color(SNAME("mono_color"), EditorStringName(Editor)) * Color(1, 1, 1, 0.5), + Math::round(EDSCALE) / debug_uv->get_size().x); } void MeshInstance3DEditor::_create_navigation_mesh() { @@ -527,7 +561,7 @@ void MeshInstance3DEditor::_create_outline_mesh() { void MeshInstance3DEditor::_notification(int p_what) { switch (p_what) { case NOTIFICATION_THEME_CHANGED: { - options->set_icon(get_editor_theme_icon(SNAME("MeshInstance3D"))); + options->set_button_icon(get_editor_theme_icon(SNAME("MeshInstance3D"))); } break; } } @@ -613,10 +647,14 @@ MeshInstance3DEditor::MeshInstance3DEditor() { debug_uv_dialog = memnew(AcceptDialog); debug_uv_dialog->set_title(TTR("UV Channel Debug")); add_child(debug_uv_dialog); + + debug_uv_arc = memnew(AspectRatioContainer); + debug_uv_dialog->add_child(debug_uv_arc); + debug_uv = memnew(Control); debug_uv->set_custom_minimum_size(Size2(600, 600) * EDSCALE); debug_uv->connect(SceneStringName(draw), callable_mp(this, &MeshInstance3DEditor::_debug_uv_draw)); - debug_uv_dialog->add_child(debug_uv); + debug_uv_arc->add_child(debug_uv); navigation_mesh_dialog = memnew(ConfirmationDialog); navigation_mesh_dialog->set_title(TTR("Create NavigationMesh")); diff --git a/editor/plugins/mesh_instance_3d_editor_plugin.h b/editor/plugins/mesh_instance_3d_editor_plugin.h index c982df9c5f..569ecd4fff 100644 --- a/editor/plugins/mesh_instance_3d_editor_plugin.h +++ b/editor/plugins/mesh_instance_3d_editor_plugin.h @@ -36,6 +36,7 @@ #include "scene/gui/option_button.h" class AcceptDialog; +class AspectRatioContainer; class ConfirmationDialog; class MenuButton; class SpinBox; @@ -79,6 +80,7 @@ class MeshInstance3DEditor : public Control { AcceptDialog *err_dialog = nullptr; AcceptDialog *debug_uv_dialog = nullptr; + AspectRatioContainer *debug_uv_arc = nullptr; Control *debug_uv = nullptr; Vector<Vector2> uv_lines; diff --git a/editor/plugins/mesh_library_editor_plugin.cpp b/editor/plugins/mesh_library_editor_plugin.cpp index d6650bd08f..6f79ab0529 100644 --- a/editor/plugins/mesh_library_editor_plugin.cpp +++ b/editor/plugins/mesh_library_editor_plugin.cpp @@ -260,7 +260,7 @@ MeshLibraryEditor::MeshLibraryEditor() { Node3DEditor::get_singleton()->add_control_to_menu_panel(menu); menu->set_position(Point2(1, 1)); menu->set_text(TTR("MeshLibrary")); - menu->set_icon(EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("MeshLibrary"), EditorStringName(EditorIcons))); + menu->set_button_icon(EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("MeshLibrary"), EditorStringName(EditorIcons))); menu->get_popup()->add_item(TTR("Add Item"), MENU_OPTION_ADD_ITEM); menu->get_popup()->add_item(TTR("Remove Selected Item"), MENU_OPTION_REMOVE_ITEM); menu->get_popup()->add_separator(); diff --git a/editor/plugins/multimesh_editor_plugin.cpp b/editor/plugins/multimesh_editor_plugin.cpp index 729ceccd25..9e686dd689 100644 --- a/editor/plugins/multimesh_editor_plugin.cpp +++ b/editor/plugins/multimesh_editor_plugin.cpp @@ -272,7 +272,7 @@ MultiMeshEditor::MultiMeshEditor() { Node3DEditor::get_singleton()->add_control_to_menu_panel(options); options->set_text("MultiMesh"); - options->set_icon(EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("MultiMeshInstance3D"), EditorStringName(EditorIcons))); + options->set_button_icon(EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("MultiMeshInstance3D"), EditorStringName(EditorIcons))); options->get_popup()->add_item(TTR("Populate Surface")); options->get_popup()->connect(SceneStringName(id_pressed), callable_mp(this, &MultiMeshEditor::_menu_option)); diff --git a/editor/plugins/navigation_obstacle_3d_editor_plugin.cpp b/editor/plugins/navigation_obstacle_3d_editor_plugin.cpp index 9629a673e9..94ad20f05a 100644 --- a/editor/plugins/navigation_obstacle_3d_editor_plugin.cpp +++ b/editor/plugins/navigation_obstacle_3d_editor_plugin.cpp @@ -30,144 +30,502 @@ #include "navigation_obstacle_3d_editor_plugin.h" -#include "canvas_item_editor_plugin.h" -#include "core/input/input.h" -#include "core/io/file_access.h" +#include "core/config/project_settings.h" #include "core/math/geometry_2d.h" -#include "core/os/keyboard.h" #include "editor/editor_node.h" #include "editor/editor_settings.h" #include "editor/editor_string_names.h" #include "editor/editor_undo_redo_manager.h" -#include "node_3d_editor_plugin.h" -#include "scene/3d/camera_3d.h" -#include "scene/gui/separator.h" +#include "editor/plugins/node_3d_editor_plugin.h" +#include "scene/3d/navigation_obstacle_3d.h" +#include "scene/gui/button.h" +#include "scene/gui/dialogs.h" +#include "servers/navigation_server_3d.h" + +bool NavigationObstacle3DGizmoPlugin::has_gizmo(Node3D *p_spatial) { + return Object::cast_to<NavigationObstacle3D>(p_spatial) != nullptr; +} + +String NavigationObstacle3DGizmoPlugin::get_gizmo_name() const { + return "NavigationObstacle3D"; +} + +void NavigationObstacle3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { + p_gizmo->clear(); + + if (!p_gizmo->is_selected() && get_state() == HIDDEN) { + return; + } + + NavigationObstacle3D *obstacle = Object::cast_to<NavigationObstacle3D>(p_gizmo->get_node_3d()); + + if (!obstacle) { + return; + } + + const Vector<Vector3> &vertices = obstacle->get_vertices(); + if (vertices.is_empty()) { + return; + } + + float height = obstacle->get_height(); + Basis gbi = obstacle->get_global_basis().inverse(); + + const int vertex_count = vertices.size(); + + Vector<Vector3> lines_mesh_vertices; + lines_mesh_vertices.resize(vertex_count * 8); + Vector3 *lines_mesh_vertices_ptrw = lines_mesh_vertices.ptrw(); + + int vertex_index = 0; + + for (int i = 0; i < vertex_count; i++) { + Vector3 point = vertices[i]; + Vector3 next_point = vertices[(i + 1) % vertex_count]; + + Vector3 direction = next_point.direction_to(point); + Vector3 arrow_dir = direction.cross(Vector3(0.0, 1.0, 0.0)); + Vector3 edge_middle = point + ((next_point - point) * 0.5); + + lines_mesh_vertices_ptrw[vertex_index++] = gbi.xform(edge_middle); + lines_mesh_vertices_ptrw[vertex_index++] = gbi.xform(edge_middle + (arrow_dir * 0.5)); + + lines_mesh_vertices_ptrw[vertex_index++] = gbi.xform(point); + lines_mesh_vertices_ptrw[vertex_index++] = gbi.xform(next_point); + + lines_mesh_vertices_ptrw[vertex_index++] = gbi.xform(Vector3(point.x, height, point.z)); + lines_mesh_vertices_ptrw[vertex_index++] = gbi.xform(Vector3(next_point.x, height, next_point.z)); + + lines_mesh_vertices_ptrw[vertex_index++] = gbi.xform(point); + lines_mesh_vertices_ptrw[vertex_index++] = gbi.xform(Vector3(point.x, height, point.z)); + } + + Vector<Vector2> polygon_2d_vertices; + polygon_2d_vertices.resize(vertex_count); + for (int i = 0; i < vertex_count; i++) { + const Vector3 &vert = vertices[i]; + polygon_2d_vertices.write[i] = Vector2(vert.x, vert.z); + } + Vector<int> triangulated_polygon_2d_indices = Geometry2D::triangulate_polygon(polygon_2d_vertices); + + NavigationServer3D *ns3d = NavigationServer3D::get_singleton(); + + if (triangulated_polygon_2d_indices.is_empty()) { + p_gizmo->add_lines(lines_mesh_vertices, ns3d->get_debug_navigation_avoidance_static_obstacle_pushin_edge_material()); + } else { + p_gizmo->add_lines(lines_mesh_vertices, ns3d->get_debug_navigation_avoidance_static_obstacle_pushout_edge_material()); + } + p_gizmo->add_collision_segments(lines_mesh_vertices); + + if (p_gizmo->is_selected()) { + NavigationObstacle3DEditorPlugin::singleton->redraw(); + } +} + +bool NavigationObstacle3DGizmoPlugin::can_be_hidden() const { + return true; +} + +int NavigationObstacle3DGizmoPlugin::get_priority() const { + return -1; +} + +int NavigationObstacle3DGizmoPlugin::subgizmos_intersect_ray(const EditorNode3DGizmo *p_gizmo, Camera3D *p_camera, const Vector2 &p_point) const { + if (NavigationObstacle3DEditorPlugin::singleton->get_mode() != 1) { // MODE_EDIT + return -1; + } + + NavigationObstacle3D *obstacle_node = Object::cast_to<NavigationObstacle3D>(p_gizmo->get_node_3d()); + ERR_FAIL_NULL_V(obstacle_node, -1); + + Transform3D gt = Transform3D(Basis(), obstacle_node->get_global_position()); + const Vector<Vector3> &vertices = obstacle_node->get_vertices(); + + for (int idx = 0; idx < vertices.size(); ++idx) { + Vector3 pos = gt.xform(vertices[idx]); + if (p_camera->unproject_position(pos).distance_to(p_point) < 20) { + return idx; + } + } + + return -1; +} + +Vector<int> NavigationObstacle3DGizmoPlugin::subgizmos_intersect_frustum(const EditorNode3DGizmo *p_gizmo, const Camera3D *p_camera, const Vector<Plane> &p_frustum) const { + Vector<int> contained_points; + if (NavigationObstacle3DEditorPlugin::singleton->get_mode() != 1) { // MODE_EDIT + return contained_points; + } + + NavigationObstacle3D *obstacle_node = Object::cast_to<NavigationObstacle3D>(p_gizmo->get_node_3d()); + ERR_FAIL_NULL_V(obstacle_node, contained_points); + + Transform3D gt = Transform3D(Basis(), obstacle_node->get_global_position()); + const Vector<Vector3> &vertices = obstacle_node->get_vertices(); + + for (int idx = 0; idx < vertices.size(); ++idx) { + Vector3 pos = gt.xform(vertices[idx]); + bool is_contained_in_frustum = true; + for (int i = 0; i < p_frustum.size(); ++i) { + if (p_frustum[i].distance_to(pos) > 0) { + is_contained_in_frustum = false; + break; + } + } + + if (is_contained_in_frustum) { + contained_points.push_back(idx); + } + } + + return contained_points; +} + +Transform3D NavigationObstacle3DGizmoPlugin::get_subgizmo_transform(const EditorNode3DGizmo *p_gizmo, int p_id) const { + NavigationObstacle3D *obstacle_node = Object::cast_to<NavigationObstacle3D>(p_gizmo->get_node_3d()); + ERR_FAIL_NULL_V(obstacle_node, Transform3D()); + + const Vector<Vector3> &vertices = obstacle_node->get_vertices(); + ERR_FAIL_INDEX_V(p_id, vertices.size(), Transform3D()); + + Basis gbi = obstacle_node->get_global_basis().inverse(); + + Transform3D subgizmo_transform = Transform3D(Basis(), gbi.xform(vertices[p_id])); + return subgizmo_transform; +} + +void NavigationObstacle3DGizmoPlugin::set_subgizmo_transform(const EditorNode3DGizmo *p_gizmo, int p_id, Transform3D p_transform) { + NavigationObstacle3D *obstacle_node = Object::cast_to<NavigationObstacle3D>(p_gizmo->get_node_3d()); + ERR_FAIL_NULL(obstacle_node); + + Basis gb = obstacle_node->get_global_basis(); + + Vector3 new_vertex_pos = p_transform.origin; + + Vector<Vector3> vertices = obstacle_node->get_vertices(); + ERR_FAIL_INDEX(p_id, vertices.size()); -void NavigationObstacle3DEditor::_notification(int p_what) { + Vector3 vertex = gb.xform(new_vertex_pos); + vertex.y = 0.0; + vertices.write[p_id] = vertex; + + obstacle_node->set_vertices(vertices); +} + +void NavigationObstacle3DGizmoPlugin::commit_subgizmos(const EditorNode3DGizmo *p_gizmo, const Vector<int> &p_ids, const Vector<Transform3D> &p_restore, bool p_cancel) { + NavigationObstacle3D *obstacle_node = Object::cast_to<NavigationObstacle3D>(p_gizmo->get_node_3d()); + ERR_FAIL_NULL(obstacle_node); + + Basis gb = obstacle_node->get_global_basis(); + + Vector<Vector3> vertices = obstacle_node->get_vertices(); + Vector<Vector3> restore_vertices = vertices; + + for (int i = 0; i < p_ids.size(); ++i) { + const int idx = p_ids[i]; + Vector3 vertex = gb.xform(p_restore[i].origin); + vertex.y = 0.0; + restore_vertices.write[idx] = vertex; + } + + if (p_cancel) { + obstacle_node->set_vertices(restore_vertices); + return; + } + + EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton(); + undo_redo->create_action(TTR("Set Obstacle Vertices")); + undo_redo->add_do_method(obstacle_node, "set_vertices", vertices); + undo_redo->add_undo_method(obstacle_node, "set_vertices", restore_vertices); + undo_redo->commit_action(); +} + +NavigationObstacle3DGizmoPlugin::NavigationObstacle3DGizmoPlugin() { + current_state = VISIBLE; +} + +void NavigationObstacle3DEditorPlugin::_notification(int p_what) { switch (p_what) { + case NOTIFICATION_ENTER_TREE: { + _update_theme(); + } break; + case NOTIFICATION_READY: { - button_create->set_icon(get_editor_theme_icon(SNAME("Edit"))); - button_edit->set_icon(get_editor_theme_icon(SNAME("MovePoint"))); + _update_theme(); button_edit->set_pressed(true); - get_tree()->connect("node_removed", callable_mp(this, &NavigationObstacle3DEditor::_node_removed)); + get_tree()->connect("node_removed", callable_mp(this, &NavigationObstacle3DEditorPlugin::_node_removed)); + EditorNode::get_singleton()->get_gui_base()->connect(SceneStringName(theme_changed), callable_mp(this, &NavigationObstacle3DEditorPlugin::_update_theme)); + } break; + case NOTIFICATION_EXIT_TREE: { + get_tree()->disconnect("node_removed", callable_mp(this, &NavigationObstacle3DEditorPlugin::_node_removed)); + EditorNode::get_singleton()->get_gui_base()->disconnect(SceneStringName(theme_changed), callable_mp(this, &NavigationObstacle3DEditorPlugin::_update_theme)); } break; } } -void NavigationObstacle3DEditor::_node_removed(Node *p_node) { - if (p_node == obstacle_node) { - obstacle_node = nullptr; - if (point_lines_meshinstance->get_parent() == p_node) { - p_node->remove_child(point_lines_meshinstance); +void NavigationObstacle3DEditorPlugin::edit(Object *p_object) { + obstacle_node = Object::cast_to<NavigationObstacle3D>(p_object); + + RenderingServer *rs = RenderingServer::get_singleton(); + + if (obstacle_node) { + if (obstacle_node->get_vertices().is_empty()) { + set_mode(MODE_CREATE); + } else { + set_mode(MODE_EDIT); } - hide(); + wip_vertices.clear(); + wip_active = false; + edited_point = -1; + + rs->instance_set_scenario(point_lines_instance_rid, obstacle_node->get_world_3d()->get_scenario()); + rs->instance_set_scenario(point_handles_instance_rid, obstacle_node->get_world_3d()->get_scenario()); + + redraw(); + + } else { + obstacle_node = nullptr; + + rs->mesh_clear(point_lines_mesh_rid); + rs->mesh_clear(point_handle_mesh_rid); + rs->instance_set_scenario(point_lines_instance_rid, RID()); + rs->instance_set_scenario(point_handles_instance_rid, RID()); } } -void NavigationObstacle3DEditor::_menu_option(int p_option) { - switch (p_option) { - case MODE_CREATE: { - mode = MODE_CREATE; - button_create->set_pressed(true); - button_edit->set_pressed(false); - } break; - case MODE_EDIT: { - mode = MODE_EDIT; - button_create->set_pressed(false); - button_edit->set_pressed(true); - } break; +bool NavigationObstacle3DEditorPlugin::handles(Object *p_object) const { + return Object::cast_to<NavigationObstacle3D>(p_object); +} + +void NavigationObstacle3DEditorPlugin::make_visible(bool p_visible) { + if (p_visible) { + obstacle_editor->show(); + } else { + obstacle_editor->hide(); + edit(nullptr); } } -void NavigationObstacle3DEditor::_wip_close() { - ERR_FAIL_NULL_MSG(obstacle_node, "Edited NavigationObstacle3D is not valid."); +void NavigationObstacle3DEditorPlugin::action_flip_vertices() { + if (!obstacle_node) { + return; + } + + Vector<Vector3> flipped_vertices = obstacle_node->get_vertices(); + flipped_vertices.reverse(); + EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton(); - undo_redo->create_action(TTR("Set NavigationObstacle3D Vertices")); + undo_redo->create_action(TTR("Edit Obstacle (Flip Winding)")); + undo_redo->add_do_method(obstacle_node, "set_vertices", flipped_vertices); undo_redo->add_undo_method(obstacle_node, "set_vertices", obstacle_node->get_vertices()); + undo_redo->commit_action(); - PackedVector3Array polygon_3d_vertices; - Vector<int> triangulated_polygon_2d_indices = Geometry2D::triangulate_polygon(wip); + obstacle_node->update_gizmos(); +} - if (!triangulated_polygon_2d_indices.is_empty()) { - polygon_3d_vertices.resize(wip.size()); - Vector3 *polygon_3d_vertices_ptr = polygon_3d_vertices.ptrw(); - for (int i = 0; i < wip.size(); i++) { - const Vector2 &vert = wip[i]; - polygon_3d_vertices_ptr[i] = Vector3(vert.x, 0.0, vert.y); - } +void NavigationObstacle3DEditorPlugin::action_clear_vertices() { + if (!obstacle_node) { + return; } - undo_redo->add_do_method(obstacle_node, "set_vertices", polygon_3d_vertices); - undo_redo->add_do_method(this, "_polygon_draw"); - undo_redo->add_undo_method(this, "_polygon_draw"); - wip.clear(); + EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton(); + undo_redo->create_action(TTR("Edit Obstacle (Clear Vertices)")); + undo_redo->add_do_method(obstacle_node, "set_vertices", Vector<Vector3>()); + undo_redo->add_undo_method(obstacle_node, "set_vertices", obstacle_node->get_vertices()); + undo_redo->commit_action(); + + obstacle_node->update_gizmos(); + edit(obstacle_node); +} + +void NavigationObstacle3DEditorPlugin::_update_theme() { + button_create->set_tooltip_text(TTR("Add Vertex")); + button_edit->set_tooltip_text(TTR("Edit Vertex")); + button_delete->set_tooltip_text(TTR("Delete Vertex")); + button_flip->set_tooltip_text(TTR("Flip Winding")); + button_clear->set_tooltip_text(TTR("Clear Vertices")); + button_create->set_button_icon(button_create->get_editor_theme_icon(SNAME("CurveCreate"))); + button_edit->set_button_icon(button_edit->get_editor_theme_icon(SNAME("CurveEdit"))); + button_delete->set_button_icon(button_delete->get_editor_theme_icon(SNAME("CurveDelete"))); + button_flip->set_button_icon(button_flip->get_editor_theme_icon(SNAME("FlipWinding"))); + button_clear->set_button_icon(button_clear->get_editor_theme_icon(SNAME("Clear"))); +} + +void NavigationObstacle3DEditorPlugin::_node_removed(Node *p_node) { + if (obstacle_node == p_node) { + obstacle_node = nullptr; + + RenderingServer *rs = RenderingServer::get_singleton(); + rs->mesh_clear(point_lines_mesh_rid); + rs->mesh_clear(point_handle_mesh_rid); + + obstacle_editor->hide(); + } +} + +void NavigationObstacle3DEditorPlugin::set_mode(int p_option) { + if (p_option == NavigationObstacle3DEditorPlugin::ACTION_FLIP) { + button_flip->set_pressed(false); + action_flip_vertices(); + return; + } + + if (p_option == NavigationObstacle3DEditorPlugin::ACTION_CLEAR) { + button_clear->set_pressed(false); + button_clear_dialog->reset_size(); + button_clear_dialog->popup_centered(); + return; + } + + mode = p_option; + + button_create->set_pressed(p_option == NavigationObstacle3DEditorPlugin::MODE_CREATE); + button_edit->set_pressed(p_option == NavigationObstacle3DEditorPlugin::MODE_EDIT); + button_delete->set_pressed(p_option == NavigationObstacle3DEditorPlugin::MODE_DELETE); + button_flip->set_pressed(false); + button_clear->set_pressed(false); +} + +void NavigationObstacle3DEditorPlugin::_wip_cancel() { + wip_vertices.clear(); wip_active = false; - mode = MODE_EDIT; - button_edit->set_pressed(true); - button_create->set_pressed(false); + edited_point = -1; - undo_redo->commit_action(); + + redraw(); } -EditorPlugin::AfterGUIInput NavigationObstacle3DEditor::forward_3d_gui_input(Camera3D *p_camera, const Ref<InputEvent> &p_event) { +void NavigationObstacle3DEditorPlugin::_wip_close() { + ERR_FAIL_NULL_MSG(obstacle_node, "Edited NavigationObstacle3D is not valid."); + + Vector<Vector2> wip_2d_vertices; + wip_2d_vertices.resize(wip_vertices.size()); + for (int i = 0; i < wip_vertices.size(); i++) { + const Vector3 &vert = wip_vertices[i]; + wip_2d_vertices.write[i] = Vector2(vert.x, vert.z); + } + Vector<int> triangulated_polygon_2d_indices = Geometry2D::triangulate_polygon(wip_2d_vertices); + + if (!triangulated_polygon_2d_indices.is_empty()) { + EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton(); + undo_redo->create_action(TTR("Set Obstacle Vertices")); + undo_redo->add_do_method(obstacle_node, "set_vertices", wip_vertices); + undo_redo->add_undo_method(obstacle_node, "set_vertices", obstacle_node->get_vertices()); + undo_redo->commit_action(); + + wip_vertices.clear(); + wip_active = false; + //mode = MODE_EDIT; + NavigationObstacle3DEditorPlugin::singleton->set_mode(NavigationObstacle3DEditorPlugin::MODE_EDIT); + button_edit->set_pressed(true); + button_create->set_pressed(false); + edited_point = -1; + } +} + +EditorPlugin::AfterGUIInput NavigationObstacle3DEditorPlugin::forward_3d_gui_input(Camera3D *p_camera, const Ref<InputEvent> &p_event) { if (!obstacle_node) { return EditorPlugin::AFTER_GUI_INPUT_PASS; } - Transform3D gt = obstacle_node->get_global_transform(); - Transform3D gi = gt.affine_inverse(); - Plane p(Vector3(0.0, 1.0, 0.0), gt.origin); + if (!obstacle_node->is_visible_in_tree()) { + return EditorPlugin::AFTER_GUI_INPUT_PASS; + } + + Ref<InputEventMouse> mouse_event = p_event; + + if (mouse_event.is_null()) { + return EditorPlugin::AFTER_GUI_INPUT_PASS; + } Ref<InputEventMouseButton> mb = p_event; if (mb.is_valid()) { - Vector2 gpoint = mb->get_position(); - Vector3 ray_from = p_camera->project_ray_origin(gpoint); - Vector3 ray_dir = p_camera->project_ray_normal(gpoint); + Vector2 mouse_position = mb->get_position(); + Vector3 ray_from = p_camera->project_ray_origin(mouse_position); + Vector3 ray_dir = p_camera->project_ray_normal(mouse_position); + + Transform3D gt = Transform3D(Basis(), obstacle_node->get_global_position()); + Transform3D gi = gt.affine_inverse(); + Plane projection_plane(Vector3(0.0, 1.0, 0.0), gt.origin); Vector3 spoint; - if (!p.intersects_ray(ray_from, ray_dir, &spoint)) { + if (!projection_plane.intersects_ray(ray_from, ray_dir, &spoint)) { return EditorPlugin::AFTER_GUI_INPUT_PASS; } spoint = gi.xform(spoint); - Vector2 cpoint(spoint.x, spoint.z); - - //DO NOT snap here, it's confusing in 3D for adding points. - //Let the snap happen when the point is being moved, instead. - //cpoint = CanvasItemEditor::get_singleton()->snap_point(cpoint); + Vector3 cpoint = Vector3(spoint.x, 0.0, spoint.z); + Vector<Vector3> obstacle_vertices = obstacle_node->get_vertices(); - PackedVector2Array poly = _get_polygon(); - - //first check if a point is to be added (segment split) real_t grab_threshold = EDITOR_GET("editors/polygon_editor/point_grab_radius"); switch (mode) { case MODE_CREATE: { if (mb->get_button_index() == MouseButton::LEFT && mb->is_pressed()) { + if (obstacle_vertices.size() >= 3) { + int closest_idx = -1; + Vector2 closest_edge_point; + real_t closest_dist = 1e10; + for (int i = 0; i < obstacle_vertices.size(); i++) { + Vector2 points[2] = { + p_camera->unproject_position(gt.xform(obstacle_vertices[i])), + p_camera->unproject_position(gt.xform(obstacle_vertices[(i + 1) % obstacle_vertices.size()])) + }; + + Vector2 cp = Geometry2D::get_closest_point_to_segment(mouse_position, points); + if (cp.distance_squared_to(points[0]) < grab_threshold || cp.distance_squared_to(points[1]) < grab_threshold) { + continue; // Skip edge as clicked point is too close to existing vertex. + } + + real_t d = cp.distance_to(mouse_position); + if (d < closest_dist && d < grab_threshold) { + closest_dist = d; + closest_edge_point = cp; + closest_idx = i; + } + } + if (closest_idx >= 0) { + edited_point = -1; + Vector3 _ray_from = p_camera->project_ray_origin(closest_edge_point); + Vector3 _ray_dir = p_camera->project_ray_normal(closest_edge_point); + Vector3 edge_intersection_point; + if (projection_plane.intersects_ray(_ray_from, _ray_dir, &edge_intersection_point)) { + edge_intersection_point = gi.xform(edge_intersection_point); + + EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton(); + undo_redo->create_action(TTR("Edit Obstacle (Add Vertex)")); + undo_redo->add_undo_method(obstacle_node, "set_vertices", obstacle_vertices); + obstacle_vertices.insert(closest_idx + 1, edge_intersection_point); + undo_redo->add_do_method(obstacle_node, "set_vertices", obstacle_vertices); + undo_redo->commit_action(); + redraw(); + return EditorPlugin::AFTER_GUI_INPUT_STOP; + } + } + } if (!wip_active) { - wip.clear(); - wip.push_back(cpoint); + wip_vertices.clear(); + wip_vertices.push_back(cpoint); wip_active = true; edited_point_pos = cpoint; snap_ignore = false; - _polygon_draw(); + redraw(); edited_point = 1; return EditorPlugin::AFTER_GUI_INPUT_STOP; } else { - if (wip.size() > 1 && p_camera->unproject_position(gt.xform(Vector3(wip[0].x, 0.0, wip[0].y))).distance_to(gpoint) < grab_threshold) { - //wip closed + if (wip_vertices.size() > 1 && p_camera->unproject_position(gt.xform(wip_vertices[0])).distance_to(mouse_position) < grab_threshold) { _wip_close(); return EditorPlugin::AFTER_GUI_INPUT_STOP; } else { - wip.push_back(cpoint); - edited_point = wip.size(); + wip_vertices.push_back(cpoint); + edited_point = wip_vertices.size(); snap_ignore = false; - _polygon_draw(); + redraw(); return EditorPlugin::AFTER_GUI_INPUT_STOP; } } @@ -181,13 +539,11 @@ EditorPlugin::AfterGUIInput NavigationObstacle3DEditor::forward_3d_gui_input(Cam if (mb->get_button_index() == MouseButton::LEFT) { if (mb->is_pressed()) { if (mb->is_ctrl_pressed()) { - if (poly.size() < 3) { + if (obstacle_vertices.size() < 3) { EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton(); - undo_redo->create_action(TTR("Edit Vertices")); + undo_redo->create_action(TTR("Edit Obstacle (Add Vertex)")); undo_redo->add_undo_method(obstacle_node, "set_vertices", obstacle_node->get_vertices()); - poly.push_back(cpoint); - undo_redo->add_do_method(this, "_polygon_draw"); - undo_redo->add_undo_method(this, "_polygon_draw"); + obstacle_vertices.push_back(cpoint); undo_redo->commit_action(); return EditorPlugin::AFTER_GUI_INPUT_STOP; } @@ -196,18 +552,18 @@ EditorPlugin::AfterGUIInput NavigationObstacle3DEditor::forward_3d_gui_input(Cam int closest_idx = -1; Vector2 closest_pos; real_t closest_dist = 1e10; - for (int i = 0; i < poly.size(); i++) { + for (int i = 0; i < obstacle_vertices.size(); i++) { Vector2 points[2] = { - p_camera->unproject_position(gt.xform(Vector3(poly[i].x, 0.0, poly[i].y))), - p_camera->unproject_position(gt.xform(Vector3(poly[(i + 1) % poly.size()].x, 0.0, poly[(i + 1) % poly.size()].y))) + p_camera->unproject_position(gt.xform(obstacle_vertices[i])), + p_camera->unproject_position(gt.xform(obstacle_vertices[(i + 1) % obstacle_vertices.size()])) }; - Vector2 cp = Geometry2D::get_closest_point_to_segment(gpoint, points); + Vector2 cp = Geometry2D::get_closest_point_to_segment(mouse_position, points); if (cp.distance_squared_to(points[0]) < CMP_EPSILON2 || cp.distance_squared_to(points[1]) < CMP_EPSILON2) { continue; //not valid to reuse point } - real_t d = cp.distance_to(gpoint); + real_t d = cp.distance_to(mouse_position); if (d < closest_dist && d < grab_threshold) { closest_dist = d; closest_pos = cp; @@ -216,26 +572,24 @@ EditorPlugin::AfterGUIInput NavigationObstacle3DEditor::forward_3d_gui_input(Cam } if (closest_idx >= 0) { - pre_move_edit = poly; - poly.insert(closest_idx + 1, cpoint); + pre_move_edit = obstacle_vertices; + obstacle_vertices.insert(closest_idx + 1, cpoint); edited_point = closest_idx + 1; edited_point_pos = cpoint; - _set_polygon(poly); - _polygon_draw(); + obstacle_node->set_vertices(obstacle_vertices); + redraw(); snap_ignore = true; return EditorPlugin::AFTER_GUI_INPUT_STOP; } } else { - //look for points to move - int closest_idx = -1; Vector2 closest_pos; real_t closest_dist = 1e10; - for (int i = 0; i < poly.size(); i++) { - Vector2 cp = p_camera->unproject_position(gt.xform(Vector3(poly[i].x, 0.0, poly[i].y))); + for (int i = 0; i < obstacle_vertices.size(); i++) { + Vector2 cp = p_camera->unproject_position(gt.xform(obstacle_vertices[i])); - real_t d = cp.distance_to(gpoint); + real_t d = cp.distance_to(mouse_position); if (d < closest_dist && d < grab_threshold) { closest_dist = d; closest_pos = cp; @@ -244,10 +598,10 @@ EditorPlugin::AfterGUIInput NavigationObstacle3DEditor::forward_3d_gui_input(Cam } if (closest_idx >= 0) { - pre_move_edit = poly; + pre_move_edit = obstacle_vertices; edited_point = closest_idx; - edited_point_pos = poly[closest_idx]; - _polygon_draw(); + edited_point_pos = obstacle_vertices[closest_idx]; + redraw(); snap_ignore = false; return EditorPlugin::AFTER_GUI_INPUT_STOP; } @@ -256,16 +610,13 @@ EditorPlugin::AfterGUIInput NavigationObstacle3DEditor::forward_3d_gui_input(Cam snap_ignore = false; if (edited_point != -1) { - //apply + ERR_FAIL_INDEX_V(edited_point, obstacle_vertices.size(), EditorPlugin::AFTER_GUI_INPUT_PASS); + obstacle_vertices.write[edited_point] = edited_point_pos; - ERR_FAIL_INDEX_V(edited_point, poly.size(), EditorPlugin::AFTER_GUI_INPUT_PASS); - poly.write[edited_point] = edited_point_pos; EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton(); - undo_redo->create_action(TTR("Edit Poly")); - //undo_redo->add_do_method(obj, "set_polygon", poly); - //undo_redo->add_undo_method(obj, "set_polygon", pre_move_edit); - undo_redo->add_do_method(this, "_polygon_draw"); - undo_redo->add_undo_method(this, "_polygon_draw"); + undo_redo->create_action(TTR("Edit Obstacle (Move Vertex)")); + undo_redo->add_undo_method(obstacle_node, "set_vertices", obstacle_node->get_vertices()); + undo_redo->add_do_method(obstacle_node, "set_vertices", obstacle_vertices); undo_redo->commit_action(); edited_point = -1; @@ -273,30 +624,31 @@ EditorPlugin::AfterGUIInput NavigationObstacle3DEditor::forward_3d_gui_input(Cam } } } - if (mb->get_button_index() == MouseButton::RIGHT && mb->is_pressed() && edited_point == -1) { + + } break; + + case MODE_DELETE: { + if (mb->get_button_index() == MouseButton::LEFT && mb->is_pressed()) { int closest_idx = -1; - Vector2 closest_pos; real_t closest_dist = 1e10; - for (int i = 0; i < poly.size(); i++) { - Vector2 cp = p_camera->unproject_position(gt.xform(Vector3(poly[i].x, 0.0, poly[i].y))); - - real_t d = cp.distance_to(gpoint); + for (int i = 0; i < obstacle_vertices.size(); i++) { + Vector2 point = p_camera->unproject_position(gt.xform(obstacle_vertices[i])); + real_t d = point.distance_to(mouse_position); if (d < closest_dist && d < grab_threshold) { closest_dist = d; - closest_pos = cp; closest_idx = i; } } if (closest_idx >= 0) { + edited_point = -1; EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton(); - undo_redo->create_action(TTR("Edit Poly (Remove Point)")); - //undo_redo->add_undo_method(obj, "set_polygon", poly); - poly.remove_at(closest_idx); - //undo_redo->add_do_method(obj, "set_polygon", poly); - undo_redo->add_do_method(this, "_polygon_draw"); - undo_redo->add_undo_method(this, "_polygon_draw"); + undo_redo->create_action(TTR("Edit Obstacle (Remove Vertex)")); + undo_redo->add_undo_method(obstacle_node, "set_vertices", obstacle_vertices); + obstacle_vertices.remove_at(closest_idx); + undo_redo->add_do_method(obstacle_node, "set_vertices", obstacle_vertices); undo_redo->commit_action(); + redraw(); return EditorPlugin::AFTER_GUI_INPUT_STOP; } } @@ -309,20 +661,24 @@ EditorPlugin::AfterGUIInput NavigationObstacle3DEditor::forward_3d_gui_input(Cam if (mm.is_valid()) { if (edited_point != -1 && (wip_active || mm->get_button_mask().has_flag(MouseButtonMask::LEFT))) { - Vector2 gpoint = mm->get_position(); + Vector2 mouse_position = mm->get_position(); + + Vector3 ray_from = p_camera->project_ray_origin(mouse_position); + Vector3 ray_dir = p_camera->project_ray_normal(mouse_position); - Vector3 ray_from = p_camera->project_ray_origin(gpoint); - Vector3 ray_dir = p_camera->project_ray_normal(gpoint); + Transform3D gt = Transform3D(Basis(), obstacle_node->get_global_position()); + Transform3D gi = gt.affine_inverse(); + Plane projection_plane(Vector3(0.0, 1.0, 0.0), gt.origin); - Vector3 spoint; + Vector3 intersection_point; - if (!p.intersects_ray(ray_from, ray_dir, &spoint)) { + if (!projection_plane.intersects_ray(ray_from, ray_dir, &intersection_point)) { return EditorPlugin::AFTER_GUI_INPUT_PASS; } - spoint = gi.xform(spoint); + intersection_point = gi.xform(intersection_point); - Vector2 cpoint(spoint.x, spoint.z); + Vector2 cpoint(intersection_point.x, intersection_point.z); if (snap_ignore && !Input::get_singleton()->is_key_pressed(Key::CTRL)) { snap_ignore = false; @@ -331,272 +687,217 @@ EditorPlugin::AfterGUIInput NavigationObstacle3DEditor::forward_3d_gui_input(Cam if (!snap_ignore && Node3DEditor::get_singleton()->is_snap_enabled()) { cpoint = cpoint.snappedf(Node3DEditor::get_singleton()->get_translate_snap()); } - edited_point_pos = cpoint; + edited_point_pos = Vector3(cpoint.x, 0.0, cpoint.y); - _polygon_draw(); + redraw(); } } - return EditorPlugin::AFTER_GUI_INPUT_PASS; -} + Ref<InputEventKey> k = p_event; -PackedVector2Array NavigationObstacle3DEditor::_get_polygon() { - ERR_FAIL_NULL_V_MSG(obstacle_node, PackedVector2Array(), "Edited object is not valid."); - return PackedVector2Array(obstacle_node->call("get_polygon")); -} + if (k.is_valid() && k->is_pressed()) { + if (wip_active && k->get_keycode() == Key::ENTER) { + _wip_close(); + } else if (wip_active && k->get_keycode() == Key::ESCAPE) { + _wip_cancel(); + } + } -void NavigationObstacle3DEditor::_set_polygon(const PackedVector2Array &p_poly) { - ERR_FAIL_NULL_MSG(obstacle_node, "Edited object is not valid."); - obstacle_node->call("set_polygon", p_poly); + return EditorPlugin::AFTER_GUI_INPUT_PASS; } -void NavigationObstacle3DEditor::_polygon_draw() { +void NavigationObstacle3DEditorPlugin::redraw() { if (!obstacle_node) { return; } + RenderingServer *rs = RenderingServer::get_singleton(); + + rs->mesh_clear(point_lines_mesh_rid); + rs->mesh_clear(point_handle_mesh_rid); + + if (!obstacle_node->is_visible_in_tree()) { + return; + } - PackedVector2Array poly; - PackedVector3Array polygon_3d_vertices; + Vector<Vector3> edited_vertices; if (wip_active) { - poly = wip; + edited_vertices = wip_vertices; } else { - poly = _get_polygon(); + edited_vertices = obstacle_node->get_vertices(); } - polygon_3d_vertices.resize(poly.size()); - Vector3 *polygon_3d_vertices_ptr = polygon_3d_vertices.ptrw(); - for (int i = 0; i < poly.size(); i++) { - const Vector2 &vert = poly[i]; - polygon_3d_vertices_ptr[i] = Vector3(vert.x, 0.0, vert.y); + if (edited_vertices.is_empty()) { + return; } - point_handle_mesh->clear_surfaces(); - point_lines_mesh->clear_surfaces(); - point_lines_meshinstance->set_material_override(line_material); - point_lines_mesh->surface_begin(Mesh::PRIMITIVE_LINES); + Array point_lines_mesh_array; + point_lines_mesh_array.resize(Mesh::ARRAY_MAX); - Rect2 rect; + Vector<Vector3> point_lines_mesh_vertices; + point_lines_mesh_vertices.resize(edited_vertices.size() * 2); + Vector3 *point_lines_mesh_vertices_ptr = point_lines_mesh_vertices.ptrw(); - for (int i = 0; i < poly.size(); i++) { - Vector2 p, p2; - if (i == edited_point) { - p = edited_point_pos; - } else { - p = poly[i]; - } + int vertex_index = 0; - if ((wip_active && i == poly.size() - 1) || (((i + 1) % poly.size()) == edited_point)) { - p2 = edited_point_pos; + for (int i = 0; i < edited_vertices.size(); i++) { + Vector3 point, next_point; + if (i == edited_point) { + point = edited_point_pos; } else { - p2 = poly[(i + 1) % poly.size()]; + point = edited_vertices[i]; } - if (i == 0) { - rect.position = p; + if ((wip_active && i == edited_vertices.size() - 1) || (((i + 1) % edited_vertices.size()) == edited_point)) { + next_point = edited_point_pos; } else { - rect.expand_to(p); + next_point = edited_vertices[(i + 1) % edited_vertices.size()]; } - Vector3 point = Vector3(p.x, 0.0, p.y); - Vector3 next_point = Vector3(p2.x, 0.0, p2.y); - - point_lines_mesh->surface_set_color(Color(1, 0.3, 0.1, 0.8)); - point_lines_mesh->surface_add_vertex(point); - point_lines_mesh->surface_set_color(Color(1, 0.3, 0.1, 0.8)); - point_lines_mesh->surface_add_vertex(next_point); - - //Color col=Color(1,0.3,0.1,0.8); - //vpc->draw_line(point,next_point,col,2); - //vpc->draw_texture(handle,point-handle->get_size()*0.5); - } - - rect = rect.grow(1); - - AABB r; - r.position.x = rect.position.x; - r.position.y = 0.0; - r.position.z = rect.position.y; - r.size.x = rect.size.x; - r.size.y = 0; - r.size.z = rect.size.y; - - point_lines_mesh->surface_set_color(Color(0.8, 0.8, 0.8, 0.2)); - point_lines_mesh->surface_add_vertex(r.position); - point_lines_mesh->surface_set_color(Color(0.8, 0.8, 0.8, 0.2)); - point_lines_mesh->surface_add_vertex(r.position + Vector3(0.3, 0, 0)); - point_lines_mesh->surface_set_color(Color(0.8, 0.8, 0.8, 0.2)); - point_lines_mesh->surface_add_vertex(r.position); - point_lines_mesh->surface_set_color(Color(0.8, 0.8, 0.8, 0.2)); - point_lines_mesh->surface_add_vertex(r.position + Vector3(0.0, 0.3, 0)); - - point_lines_mesh->surface_set_color(Color(0.8, 0.8, 0.8, 0.2)); - point_lines_mesh->surface_add_vertex(r.position + Vector3(r.size.x, 0, 0)); - point_lines_mesh->surface_set_color(Color(0.8, 0.8, 0.8, 0.2)); - point_lines_mesh->surface_add_vertex(r.position + Vector3(r.size.x, 0, 0) - Vector3(0.3, 0, 0)); - point_lines_mesh->surface_set_color(Color(0.8, 0.8, 0.8, 0.2)); - point_lines_mesh->surface_add_vertex(r.position + Vector3(r.size.x, 0, 0)); - point_lines_mesh->surface_set_color(Color(0.8, 0.8, 0.8, 0.2)); - point_lines_mesh->surface_add_vertex(r.position + Vector3(r.size.x, 0, 0) + Vector3(0, 0.3, 0)); - - point_lines_mesh->surface_set_color(Color(0.8, 0.8, 0.8, 0.2)); - point_lines_mesh->surface_add_vertex(r.position + Vector3(0, r.size.y, 0)); - point_lines_mesh->surface_set_color(Color(0.8, 0.8, 0.8, 0.2)); - point_lines_mesh->surface_add_vertex(r.position + Vector3(0, r.size.y, 0) - Vector3(0, 0.3, 0)); - point_lines_mesh->surface_set_color(Color(0.8, 0.8, 0.8, 0.2)); - point_lines_mesh->surface_add_vertex(r.position + Vector3(0, r.size.y, 0)); - point_lines_mesh->surface_set_color(Color(0.8, 0.8, 0.8, 0.2)); - point_lines_mesh->surface_add_vertex(r.position + Vector3(0, r.size.y, 0) + Vector3(0.3, 0, 0)); - - point_lines_mesh->surface_set_color(Color(0.8, 0.8, 0.8, 0.2)); - point_lines_mesh->surface_add_vertex(r.position + r.size); - point_lines_mesh->surface_set_color(Color(0.8, 0.8, 0.8, 0.2)); - point_lines_mesh->surface_add_vertex(r.position + r.size - Vector3(0.3, 0, 0)); - point_lines_mesh->surface_set_color(Color(0.8, 0.8, 0.8, 0.2)); - point_lines_mesh->surface_add_vertex(r.position + r.size); - point_lines_mesh->surface_set_color(Color(0.8, 0.8, 0.8, 0.2)); - point_lines_mesh->surface_add_vertex(r.position + r.size - Vector3(0.0, 0.3, 0)); - - point_lines_mesh->surface_end(); - - if (poly.size() == 0) { - return; + point_lines_mesh_vertices_ptr[vertex_index++] = point; + point_lines_mesh_vertices_ptr[vertex_index++] = next_point; } + point_lines_mesh_array[Mesh::ARRAY_VERTEX] = point_lines_mesh_vertices; + + rs->mesh_add_surface_from_arrays(point_lines_mesh_rid, RS::PRIMITIVE_LINES, point_lines_mesh_array); + rs->instance_set_surface_override_material(point_lines_instance_rid, 0, line_material->get_rid()); + rs->instance_set_transform(point_lines_instance_rid, Transform3D(Basis(), obstacle_node->get_global_position())); + Array point_handle_mesh_array; point_handle_mesh_array.resize(Mesh::ARRAY_MAX); Vector<Vector3> point_handle_mesh_vertices; - point_handle_mesh_vertices.resize(poly.size()); + point_handle_mesh_vertices.resize(edited_vertices.size()); Vector3 *point_handle_mesh_vertices_ptr = point_handle_mesh_vertices.ptrw(); - for (int i = 0; i < poly.size(); i++) { - Vector2 point_2d; - Vector2 p2; + for (int i = 0; i < edited_vertices.size(); i++) { + Vector3 point_handle_3d; if (i == edited_point) { - point_2d = edited_point_pos; + point_handle_3d = edited_point_pos; } else { - point_2d = poly[i]; + point_handle_3d = edited_vertices[i]; } - Vector3 point_handle_3d = Vector3(point_2d.x, 0.0, point_2d.y); point_handle_mesh_vertices_ptr[i] = point_handle_3d; } point_handle_mesh_array[Mesh::ARRAY_VERTEX] = point_handle_mesh_vertices; - point_handle_mesh->add_surface_from_arrays(Mesh::PRIMITIVE_POINTS, point_handle_mesh_array); - point_handle_mesh->surface_set_material(0, handle_material); -} - -void NavigationObstacle3DEditor::edit(Node *p_node) { - obstacle_node = Object::cast_to<NavigationObstacle3D>(p_node); - - if (obstacle_node) { - //Enable the pencil tool if the polygon is empty - if (_get_polygon().is_empty()) { - _menu_option(MODE_CREATE); - } - wip.clear(); - wip_active = false; - edited_point = -1; - if (point_lines_meshinstance->get_parent()) { - point_lines_meshinstance->reparent(p_node, false); - } else { - p_node->add_child(point_lines_meshinstance); - } - _polygon_draw(); - } else { - obstacle_node = nullptr; - - if (point_lines_meshinstance->get_parent()) { - point_lines_meshinstance->get_parent()->remove_child(point_lines_meshinstance); - } - } + rs->mesh_add_surface_from_arrays(point_handle_mesh_rid, RS::PRIMITIVE_POINTS, point_handle_mesh_array); + rs->instance_set_surface_override_material(point_handles_instance_rid, 0, handle_material->get_rid()); + rs->instance_set_transform(point_handles_instance_rid, Transform3D(Basis(), obstacle_node->get_global_position())); } -void NavigationObstacle3DEditor::_bind_methods() { - ClassDB::bind_method(D_METHOD("_polygon_draw"), &NavigationObstacle3DEditor::_polygon_draw); -} - -NavigationObstacle3DEditor::NavigationObstacle3DEditor() { - obstacle_node = nullptr; +NavigationObstacle3DEditorPlugin *NavigationObstacle3DEditorPlugin::singleton = nullptr; - button_create = memnew(Button); - button_create->set_theme_type_variation("FlatButton"); - add_child(button_create); - button_create->connect(SceneStringName(pressed), callable_mp(this, &NavigationObstacle3DEditor::_menu_option).bind(MODE_CREATE)); - button_create->set_toggle_mode(true); - - button_edit = memnew(Button); - button_edit->set_theme_type_variation("FlatButton"); - add_child(button_edit); - button_edit->connect(SceneStringName(pressed), callable_mp(this, &NavigationObstacle3DEditor::_menu_option).bind(MODE_EDIT)); - button_edit->set_toggle_mode(true); - - mode = MODE_EDIT; - wip_active = false; - point_lines_meshinstance = memnew(MeshInstance3D); - point_lines_mesh.instantiate(); - point_lines_meshinstance->set_mesh(point_lines_mesh); - point_lines_meshinstance->set_transform(Transform3D(Basis(), Vector3(0, 0, 0.00001))); +NavigationObstacle3DEditorPlugin::NavigationObstacle3DEditorPlugin() { + singleton = this; line_material = Ref<StandardMaterial3D>(memnew(StandardMaterial3D)); line_material->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED); - line_material->set_transparency(StandardMaterial3D::TRANSPARENCY_ALPHA); line_material->set_flag(StandardMaterial3D::FLAG_ALBEDO_FROM_VERTEX_COLOR, true); line_material->set_flag(StandardMaterial3D::FLAG_SRGB_VERTEX_COLOR, true); line_material->set_flag(StandardMaterial3D::FLAG_DISABLE_FOG, true); - line_material->set_albedo(Color(1, 1, 1)); + line_material->set_albedo(Color(1, 0.3, 0.1, 0.8)); + line_material->set_flag(StandardMaterial3D::FLAG_DISABLE_DEPTH_TEST, true); handle_material = Ref<StandardMaterial3D>(memnew(StandardMaterial3D)); handle_material->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED); - handle_material->set_flag(StandardMaterial3D::FLAG_USE_POINT_SIZE, true); handle_material->set_transparency(StandardMaterial3D::TRANSPARENCY_ALPHA); + handle_material->set_flag(StandardMaterial3D::FLAG_USE_POINT_SIZE, true); handle_material->set_flag(StandardMaterial3D::FLAG_ALBEDO_FROM_VERTEX_COLOR, true); handle_material->set_flag(StandardMaterial3D::FLAG_SRGB_VERTEX_COLOR, true); handle_material->set_flag(StandardMaterial3D::FLAG_DISABLE_FOG, true); Ref<Texture2D> handle = EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("Editor3DHandle"), EditorStringName(EditorIcons)); handle_material->set_point_size(handle->get_width()); handle_material->set_texture(StandardMaterial3D::TEXTURE_ALBEDO, handle); + handle_material->set_flag(StandardMaterial3D::FLAG_DISABLE_DEPTH_TEST, true); - point_handles_meshinstance = memnew(MeshInstance3D); - point_lines_meshinstance->add_child(point_handles_meshinstance); - point_handle_mesh.instantiate(); - point_handles_meshinstance->set_mesh(point_handle_mesh); - point_handles_meshinstance->set_transform(Transform3D(Basis(), Vector3(0, 0, 0.00001))); + RenderingServer *rs = RenderingServer::get_singleton(); - snap_ignore = false; -} + point_lines_mesh_rid = rs->mesh_create(); + point_handle_mesh_rid = rs->mesh_create(); -NavigationObstacle3DEditor::~NavigationObstacle3DEditor() { - memdelete(point_lines_meshinstance); -} + point_lines_instance_rid = rs->instance_create(); + point_handles_instance_rid = rs->instance_create(); -void NavigationObstacle3DEditorPlugin::edit(Object *p_object) { - obstacle_editor->edit(Object::cast_to<Node>(p_object)); -} + rs->instance_set_base(point_lines_instance_rid, point_lines_mesh_rid); + rs->instance_set_base(point_handles_instance_rid, point_handle_mesh_rid); -bool NavigationObstacle3DEditorPlugin::handles(Object *p_object) const { - return Object::cast_to<NavigationObstacle3D>(p_object); -} + obstacle_editor = memnew(HBoxContainer); + obstacle_editor->hide(); -void NavigationObstacle3DEditorPlugin::make_visible(bool p_visible) { - if (p_visible) { - obstacle_editor->show(); - } else { - obstacle_editor->hide(); - obstacle_editor->edit(nullptr); - } -} + Ref<ButtonGroup> bg; + bg.instantiate(); + + button_create = memnew(Button); + button_create->set_theme_type_variation("FlatButton"); + obstacle_editor->add_child(button_create); + button_create->set_tooltip_text(TTR("Add Vertex")); + button_create->connect(SceneStringName(pressed), callable_mp(this, &NavigationObstacle3DEditorPlugin::set_mode).bind(NavigationObstacle3DEditorPlugin::MODE_CREATE)); + button_create->set_toggle_mode(true); + button_create->set_button_group(bg); + + button_edit = memnew(Button); + button_edit->set_theme_type_variation("FlatButton"); + obstacle_editor->add_child(button_edit); + button_edit->connect(SceneStringName(pressed), callable_mp(this, &NavigationObstacle3DEditorPlugin::set_mode).bind(NavigationObstacle3DEditorPlugin::MODE_EDIT)); + button_edit->set_toggle_mode(true); + button_edit->set_button_group(bg); + + button_delete = memnew(Button); + button_delete->set_theme_type_variation("FlatButton"); + obstacle_editor->add_child(button_delete); + button_delete->connect(SceneStringName(pressed), callable_mp(this, &NavigationObstacle3DEditorPlugin::set_mode).bind(NavigationObstacle3DEditorPlugin::MODE_DELETE)); + button_delete->set_toggle_mode(true); + button_delete->set_button_group(bg); + + button_flip = memnew(Button); + button_flip->set_theme_type_variation("FlatButton"); + obstacle_editor->add_child(button_flip); + button_flip->connect(SceneStringName(pressed), callable_mp(this, &NavigationObstacle3DEditorPlugin::set_mode).bind(NavigationObstacle3DEditorPlugin::ACTION_FLIP)); + button_flip->set_toggle_mode(true); + + button_clear = memnew(Button); + button_clear->set_theme_type_variation("FlatButton"); + obstacle_editor->add_child(button_clear); + button_clear->connect(SceneStringName(pressed), callable_mp(this, &NavigationObstacle3DEditorPlugin::set_mode).bind(NavigationObstacle3DEditorPlugin::ACTION_CLEAR)); + button_clear->set_toggle_mode(true); + + button_clear_dialog = memnew(ConfirmationDialog); + button_clear_dialog->set_title(TTR("Please Confirm...")); + button_clear_dialog->set_text(TTR("Remove all vertices?")); + button_clear_dialog->connect(SceneStringName(confirmed), callable_mp(NavigationObstacle3DEditorPlugin::singleton, &NavigationObstacle3DEditorPlugin::action_clear_vertices)); + obstacle_editor->add_child(button_clear_dialog); -NavigationObstacle3DEditorPlugin::NavigationObstacle3DEditorPlugin() { - obstacle_editor = memnew(NavigationObstacle3DEditor); Node3DEditor::get_singleton()->add_control_to_menu_panel(obstacle_editor); - obstacle_editor->hide(); + Ref<NavigationObstacle3DGizmoPlugin> gizmo_plugin = memnew(NavigationObstacle3DGizmoPlugin()); + obstacle_3d_gizmo_plugin = gizmo_plugin; + Node3DEditor::get_singleton()->add_gizmo_plugin(gizmo_plugin); } NavigationObstacle3DEditorPlugin::~NavigationObstacle3DEditorPlugin() { + RenderingServer *rs = RenderingServer::get_singleton(); + ERR_FAIL_NULL(rs); + + if (point_lines_instance_rid.is_valid()) { + rs->free(point_lines_instance_rid); + point_lines_instance_rid = RID(); + } + if (point_lines_mesh_rid.is_valid()) { + rs->free(point_lines_mesh_rid); + point_lines_mesh_rid = RID(); + } + + if (point_handles_instance_rid.is_valid()) { + rs->free(point_handles_instance_rid); + point_handles_instance_rid = RID(); + } + if (point_handle_mesh_rid.is_valid()) { + rs->free(point_handle_mesh_rid); + point_handle_mesh_rid = RID(); + } } diff --git a/editor/plugins/navigation_obstacle_3d_editor_plugin.h b/editor/plugins/navigation_obstacle_3d_editor_plugin.h index c62a5a281b..b6f3a11cf6 100644 --- a/editor/plugins/navigation_obstacle_3d_editor_plugin.h +++ b/editor/plugins/navigation_obstacle_3d_editor_plugin.h @@ -32,79 +32,99 @@ #define NAVIGATION_OBSTACLE_3D_EDITOR_PLUGIN_H #include "editor/plugins/editor_plugin.h" -#include "scene/3d/mesh_instance_3d.h" -#include "scene/3d/physics/collision_polygon_3d.h" +#include "editor/plugins/node_3d_editor_gizmos.h" #include "scene/gui/box_container.h" -#include "scene/resources/immediate_mesh.h" -#include "scene/3d/navigation_obstacle_3d.h" +class Button; +class ConfirmationDialog; +class NavigationObstacle3D; -class CanvasItemEditor; -class MenuButton; +class NavigationObstacle3DGizmoPlugin : public EditorNode3DGizmoPlugin { + GDCLASS(NavigationObstacle3DGizmoPlugin, EditorNode3DGizmoPlugin); -class NavigationObstacle3DEditor : public HBoxContainer { - GDCLASS(NavigationObstacle3DEditor, HBoxContainer); +public: + virtual bool has_gizmo(Node3D *p_spatial) override; + virtual String get_gizmo_name() const override; - enum Mode { - MODE_CREATE, - MODE_EDIT, + virtual void redraw(EditorNode3DGizmo *p_gizmo) override; - }; + bool can_be_hidden() const override; + int get_priority() const override; - Mode mode; + virtual int subgizmos_intersect_ray(const EditorNode3DGizmo *p_gizmo, Camera3D *p_camera, const Vector2 &p_point) const override; + virtual Vector<int> subgizmos_intersect_frustum(const EditorNode3DGizmo *p_gizmo, const Camera3D *p_camera, const Vector<Plane> &p_frustum) const override; + virtual Transform3D get_subgizmo_transform(const EditorNode3DGizmo *p_gizmo, int p_id) const override; + virtual void set_subgizmo_transform(const EditorNode3DGizmo *p_gizmo, int p_id, Transform3D p_transform) override; + virtual void commit_subgizmos(const EditorNode3DGizmo *p_gizmo, const Vector<int> &p_ids, const Vector<Transform3D> &p_restore, bool p_cancel = false) override; - Button *button_create = nullptr; - Button *button_edit = nullptr; + NavigationObstacle3DGizmoPlugin(); +}; + +class NavigationObstacle3DEditorPlugin : public EditorPlugin { + GDCLASS(NavigationObstacle3DEditorPlugin, EditorPlugin); + + Ref<NavigationObstacle3DGizmoPlugin> obstacle_3d_gizmo_plugin; + + NavigationObstacle3D *obstacle_node = nullptr; Ref<StandardMaterial3D> line_material; Ref<StandardMaterial3D> handle_material; - Panel *panel = nullptr; - NavigationObstacle3D *obstacle_node = nullptr; - Ref<ImmediateMesh> point_lines_mesh; - MeshInstance3D *point_lines_meshinstance = nullptr; - MeshInstance3D *point_handles_meshinstance = nullptr; - Ref<ArrayMesh> point_handle_mesh; + RID point_lines_mesh_rid; + RID point_lines_instance_rid; + RID point_handle_mesh_rid; + RID point_handles_instance_rid; - MenuButton *options = nullptr; +public: + enum Mode { + MODE_CREATE = 0, + MODE_EDIT, + MODE_DELETE, + ACTION_FLIP, + ACTION_CLEAR, + }; - int edited_point = 0; - Vector2 edited_point_pos; - PackedVector2Array pre_move_edit; - PackedVector2Array wip; - bool wip_active; - bool snap_ignore; +private: + int mode = MODE_EDIT; - float prev_depth = 0.0f; + int edited_point = 0; + Vector3 edited_point_pos; + Vector<Vector3> pre_move_edit; + Vector<Vector3> wip_vertices; + bool wip_active = false; + bool snap_ignore = false; void _wip_close(); - void _polygon_draw(); - void _menu_option(int p_option); + void _wip_cancel(); + void _update_theme(); + + Button *button_create = nullptr; + Button *button_edit = nullptr; + Button *button_delete = nullptr; + Button *button_flip = nullptr; + Button *button_clear = nullptr; - PackedVector2Array _get_polygon(); - void _set_polygon(const PackedVector2Array &p_poly); + ConfirmationDialog *button_clear_dialog = nullptr; protected: void _notification(int p_what); void _node_removed(Node *p_node); - static void _bind_methods(); public: - virtual EditorPlugin::AfterGUIInput forward_3d_gui_input(Camera3D *p_camera, const Ref<InputEvent> &p_event); - void edit(Node *p_node); - NavigationObstacle3DEditor(); - ~NavigationObstacle3DEditor(); -}; + HBoxContainer *obstacle_editor = nullptr; + static NavigationObstacle3DEditorPlugin *singleton; -class NavigationObstacle3DEditorPlugin : public EditorPlugin { - GDCLASS(NavigationObstacle3DEditorPlugin, EditorPlugin); + void redraw(); - NavigationObstacle3DEditor *obstacle_editor = nullptr; + void set_mode(int p_mode); + int get_mode() { return mode; } -public: - virtual EditorPlugin::AfterGUIInput forward_3d_gui_input(Camera3D *p_camera, const Ref<InputEvent> &p_event) override { return obstacle_editor->forward_3d_gui_input(p_camera, p_event); } + void action_flip_vertices(); + void action_clear_vertices(); + + virtual EditorPlugin::AfterGUIInput forward_3d_gui_input(Camera3D *p_camera, const Ref<InputEvent> &p_event) override; - virtual String get_name() const override { return "NavigationObstacle3DEditor"; } + virtual String get_name() const override { return "NavigationObstacle3D"; } bool has_main_screen() const override { return false; } virtual void edit(Object *p_object) override; virtual bool handles(Object *p_object) const override; diff --git a/editor/plugins/navigation_polygon_editor_plugin.cpp b/editor/plugins/navigation_polygon_editor_plugin.cpp index ec59bbb543..c11a7cf20e 100644 --- a/editor/plugins/navigation_polygon_editor_plugin.cpp +++ b/editor/plugins/navigation_polygon_editor_plugin.cpp @@ -38,8 +38,8 @@ Ref<NavigationPolygon> NavigationPolygonEditor::_ensure_navpoly() const { Ref<NavigationPolygon> navpoly = node->get_navigation_polygon(); - if (!navpoly.is_valid()) { - navpoly = Ref<NavigationPolygon>(memnew(NavigationPolygon)); + if (navpoly.is_null()) { + navpoly.instantiate(); node->set_navigation_polygon(navpoly); } return navpoly; @@ -177,8 +177,8 @@ NavigationPolygonEditor::NavigationPolygonEditor() { void NavigationPolygonEditor::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: { - button_bake->set_icon(get_editor_theme_icon(SNAME("Bake"))); - button_reset->set_icon(get_editor_theme_icon(SNAME("Reload"))); + button_bake->set_button_icon(get_editor_theme_icon(SNAME("Bake"))); + button_reset->set_button_icon(get_editor_theme_icon(SNAME("Reload"))); } break; case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: { if (rebake_timer) { diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp index 0df0274495..810d1674ca 100644 --- a/editor/plugins/node_3d_editor_plugin.cpp +++ b/editor/plugins/node_3d_editor_plugin.cpp @@ -1692,7 +1692,7 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) { Ref<InputEventMouseButton> b = p_event; if (b.is_valid()) { - emit_signal(SNAME("clicked"), this); + emit_signal(SNAME("clicked")); ViewportNavMouseButton orbit_mouse_preference = (ViewportNavMouseButton)EDITOR_GET("editors/3d/navigation/orbit_mouse_button").operator int(); ViewportNavMouseButton pan_mouse_preference = (ViewportNavMouseButton)EDITOR_GET("editors/3d/navigation/pan_mouse_button").operator int(); @@ -3139,8 +3139,8 @@ void Node3DEditorViewport::_notification(int p_what) { } break; case NOTIFICATION_THEME_CHANGED: { - view_menu->set_icon(get_editor_theme_icon(SNAME("GuiTabMenuHl"))); - preview_camera->set_icon(get_editor_theme_icon(SNAME("Camera3D"))); + view_menu->set_button_icon(get_editor_theme_icon(SNAME("GuiTabMenuHl"))); + preview_camera->set_button_icon(get_editor_theme_icon(SNAME("Camera3D"))); Control *gui_base = EditorNode::get_singleton()->get_gui_base(); const Ref<StyleBox> &information_3d_stylebox = gui_base->get_theme_stylebox(SNAME("Information3dViewport"), EditorStringName(EditorStyles)); @@ -4210,7 +4210,7 @@ Dictionary Node3DEditorViewport::get_state() const { void Node3DEditorViewport::_bind_methods() { ADD_SIGNAL(MethodInfo("toggle_maximize_view", PropertyInfo(Variant::OBJECT, "viewport"))); - ADD_SIGNAL(MethodInfo("clicked", PropertyInfo(Variant::OBJECT, "viewport"))); + ADD_SIGNAL(MethodInfo("clicked")); } void Node3DEditorViewport::reset() { @@ -6572,18 +6572,6 @@ void Node3DEditor::_menu_item_toggled(bool pressed, int p_option) { tool_option_button[TOOL_OPT_USE_SNAP]->set_pressed(pressed); snap_enabled = pressed; } break; - - case MENU_TOOL_OVERRIDE_CAMERA: { - EditorDebuggerNode *const debugger = EditorDebuggerNode::get_singleton(); - - using Override = EditorDebuggerNode::CameraOverride; - if (pressed) { - debugger->set_camera_override((Override)(Override::OVERRIDE_3D_1 + camera_override_viewport_id)); - } else { - debugger->set_camera_override(Override::OVERRIDE_NONE); - } - - } break; } } @@ -6610,36 +6598,6 @@ void Node3DEditor::_menu_gizmo_toggled(int p_option) { update_all_gizmos(); } -void Node3DEditor::_update_camera_override_button(bool p_game_running) { - Button *const button = tool_option_button[TOOL_OPT_OVERRIDE_CAMERA]; - - if (p_game_running) { - button->set_disabled(false); - button->set_tooltip_text(TTR("Project Camera Override\nOverrides the running project's camera with the editor viewport camera.")); - } else { - button->set_disabled(true); - button->set_pressed(false); - button->set_tooltip_text(TTR("Project Camera Override\nNo project instance running. Run the project from the editor to use this feature.")); - } -} - -void Node3DEditor::_update_camera_override_viewport(Object *p_viewport) { - Node3DEditorViewport *current_viewport = Object::cast_to<Node3DEditorViewport>(p_viewport); - - if (!current_viewport) { - return; - } - - EditorDebuggerNode *const debugger = EditorDebuggerNode::get_singleton(); - - camera_override_viewport_id = current_viewport->index; - if (debugger->get_camera_override() >= EditorDebuggerNode::OVERRIDE_3D_1) { - using Override = EditorDebuggerNode::CameraOverride; - - debugger->set_camera_override((Override)(Override::OVERRIDE_3D_1 + camera_override_viewport_id)); - } -} - void Node3DEditor::_menu_item_pressed(int p_option) { EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton(); switch (p_option) { @@ -6670,6 +6628,9 @@ void Node3DEditor::_menu_item_pressed(int p_option) { } break; case MENU_VIEW_USE_1_VIEWPORT: { viewport_base->set_view(Node3DEditorViewportContainer::VIEW_USE_1_VIEWPORT); + if (last_used_viewport > 0) { + last_used_viewport = 0; + } view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_1_VIEWPORT), true); view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_2_VIEWPORTS), false); @@ -6681,6 +6642,9 @@ void Node3DEditor::_menu_item_pressed(int p_option) { } break; case MENU_VIEW_USE_2_VIEWPORTS: { viewport_base->set_view(Node3DEditorViewportContainer::VIEW_USE_2_VIEWPORTS); + if (last_used_viewport > 1) { + last_used_viewport = 0; + } view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_1_VIEWPORT), false); view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_2_VIEWPORTS), true); @@ -6692,6 +6656,9 @@ void Node3DEditor::_menu_item_pressed(int p_option) { } break; case MENU_VIEW_USE_2_VIEWPORTS_ALT: { viewport_base->set_view(Node3DEditorViewportContainer::VIEW_USE_2_VIEWPORTS_ALT); + if (last_used_viewport > 1) { + last_used_viewport = 0; + } view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_1_VIEWPORT), false); view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_2_VIEWPORTS), false); @@ -6703,6 +6670,9 @@ void Node3DEditor::_menu_item_pressed(int p_option) { } break; case MENU_VIEW_USE_3_VIEWPORTS: { viewport_base->set_view(Node3DEditorViewportContainer::VIEW_USE_3_VIEWPORTS); + if (last_used_viewport > 2) { + last_used_viewport = 0; + } view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_1_VIEWPORT), false); view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_2_VIEWPORTS), false); @@ -6714,6 +6684,9 @@ void Node3DEditor::_menu_item_pressed(int p_option) { } break; case MENU_VIEW_USE_3_VIEWPORTS_ALT: { viewport_base->set_view(Node3DEditorViewportContainer::VIEW_USE_3_VIEWPORTS_ALT); + if (last_used_viewport > 2) { + last_used_viewport = 0; + } view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_1_VIEWPORT), false); view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_2_VIEWPORTS), false); @@ -7077,12 +7050,12 @@ void fragment() { col.a = EDITOR_GET("editors/3d/manipulator_gizmo_opacity"); - move_gizmo[i] = Ref<ArrayMesh>(memnew(ArrayMesh)); - move_plane_gizmo[i] = Ref<ArrayMesh>(memnew(ArrayMesh)); - rotate_gizmo[i] = Ref<ArrayMesh>(memnew(ArrayMesh)); - scale_gizmo[i] = Ref<ArrayMesh>(memnew(ArrayMesh)); - scale_plane_gizmo[i] = Ref<ArrayMesh>(memnew(ArrayMesh)); - axis_gizmo[i] = Ref<ArrayMesh>(memnew(ArrayMesh)); + move_gizmo[i].instantiate(); + move_plane_gizmo[i].instantiate(); + rotate_gizmo[i].instantiate(); + scale_gizmo[i].instantiate(); + scale_plane_gizmo[i].instantiate(); + axis_gizmo[i].instantiate(); Ref<StandardMaterial3D> mat = memnew(StandardMaterial3D); mat->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED); @@ -7313,7 +7286,7 @@ void fragment() { border_mat->set_shader(border_shader); border_mat->set_shader_parameter("albedo", Color(0.75, 0.75, 0.75, col.a / 3.0)); - rotate_gizmo[3] = Ref<ArrayMesh>(memnew(ArrayMesh)); + rotate_gizmo[3].instantiate(); rotate_gizmo[3]->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLES, arrays); rotate_gizmo[3]->surface_set_material(0, border_mat); } @@ -8021,19 +7994,18 @@ void Node3DEditor::_add_environment_to_scene(bool p_already_added_sun) { } void Node3DEditor::_update_theme() { - tool_button[TOOL_MODE_SELECT]->set_icon(get_editor_theme_icon(SNAME("ToolSelect"))); - tool_button[TOOL_MODE_MOVE]->set_icon(get_editor_theme_icon(SNAME("ToolMove"))); - tool_button[TOOL_MODE_ROTATE]->set_icon(get_editor_theme_icon(SNAME("ToolRotate"))); - tool_button[TOOL_MODE_SCALE]->set_icon(get_editor_theme_icon(SNAME("ToolScale"))); - tool_button[TOOL_MODE_LIST_SELECT]->set_icon(get_editor_theme_icon(SNAME("ListSelect"))); - tool_button[TOOL_LOCK_SELECTED]->set_icon(get_editor_theme_icon(SNAME("Lock"))); - tool_button[TOOL_UNLOCK_SELECTED]->set_icon(get_editor_theme_icon(SNAME("Unlock"))); - tool_button[TOOL_GROUP_SELECTED]->set_icon(get_editor_theme_icon(SNAME("Group"))); - tool_button[TOOL_UNGROUP_SELECTED]->set_icon(get_editor_theme_icon(SNAME("Ungroup"))); - - tool_option_button[TOOL_OPT_LOCAL_COORDS]->set_icon(get_editor_theme_icon(SNAME("Object"))); - tool_option_button[TOOL_OPT_USE_SNAP]->set_icon(get_editor_theme_icon(SNAME("Snap"))); - tool_option_button[TOOL_OPT_OVERRIDE_CAMERA]->set_icon(get_editor_theme_icon(SNAME("Camera3D"))); + tool_button[TOOL_MODE_SELECT]->set_button_icon(get_editor_theme_icon(SNAME("ToolSelect"))); + tool_button[TOOL_MODE_MOVE]->set_button_icon(get_editor_theme_icon(SNAME("ToolMove"))); + tool_button[TOOL_MODE_ROTATE]->set_button_icon(get_editor_theme_icon(SNAME("ToolRotate"))); + tool_button[TOOL_MODE_SCALE]->set_button_icon(get_editor_theme_icon(SNAME("ToolScale"))); + tool_button[TOOL_MODE_LIST_SELECT]->set_button_icon(get_editor_theme_icon(SNAME("ListSelect"))); + tool_button[TOOL_LOCK_SELECTED]->set_button_icon(get_editor_theme_icon(SNAME("Lock"))); + tool_button[TOOL_UNLOCK_SELECTED]->set_button_icon(get_editor_theme_icon(SNAME("Unlock"))); + tool_button[TOOL_GROUP_SELECTED]->set_button_icon(get_editor_theme_icon(SNAME("Group"))); + tool_button[TOOL_UNGROUP_SELECTED]->set_button_icon(get_editor_theme_icon(SNAME("Ungroup"))); + + tool_option_button[TOOL_OPT_LOCAL_COORDS]->set_button_icon(get_editor_theme_icon(SNAME("Object"))); + tool_option_button[TOOL_OPT_USE_SNAP]->set_button_icon(get_editor_theme_icon(SNAME("Snap"))); view_menu->get_popup()->set_item_icon(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_1_VIEWPORT), get_editor_theme_icon(SNAME("Panels1"))); view_menu->get_popup()->set_item_icon(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_2_VIEWPORTS), get_editor_theme_icon(SNAME("Panels2"))); @@ -8042,9 +8014,9 @@ void Node3DEditor::_update_theme() { view_menu->get_popup()->set_item_icon(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_3_VIEWPORTS_ALT), get_editor_theme_icon(SNAME("Panels3Alt"))); view_menu->get_popup()->set_item_icon(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_4_VIEWPORTS), get_editor_theme_icon(SNAME("Panels4"))); - sun_button->set_icon(get_editor_theme_icon(SNAME("PreviewSun"))); - environ_button->set_icon(get_editor_theme_icon(SNAME("PreviewEnvironment"))); - sun_environ_settings->set_icon(get_editor_theme_icon(SNAME("GuiTabMenuHl"))); + sun_button->set_button_icon(get_editor_theme_icon(SNAME("PreviewSun"))); + environ_button->set_button_icon(get_editor_theme_icon(SNAME("PreviewEnvironment"))); + sun_environ_settings->set_button_icon(get_editor_theme_icon(SNAME("GuiTabMenuHl"))); sun_title->add_theme_font_override(SceneStringName(font), get_theme_font(SNAME("title_font"), SNAME("Window"))); environ_title->add_theme_font_override(SceneStringName(font), get_theme_font(SNAME("title_font"), SNAME("Window"))); @@ -8068,9 +8040,6 @@ void Node3DEditor::_notification(int p_what) { SceneTreeDock::get_singleton()->get_tree_editor()->connect("node_changed", callable_mp(this, &Node3DEditor::_refresh_menu_icons)); editor_selection->connect("selection_changed", callable_mp(this, &Node3DEditor::_selection_changed)); - EditorRunBar::get_singleton()->connect("stop_pressed", callable_mp(this, &Node3DEditor::_update_camera_override_button).bind(false)); - EditorRunBar::get_singleton()->connect("play_pressed", callable_mp(this, &Node3DEditor::_update_camera_override_button).bind(true)); - _update_preview_environment(); sun_state->set_custom_minimum_size(sun_vb->get_combined_minimum_size()); @@ -8106,15 +8075,6 @@ void Node3DEditor::_notification(int p_what) { } } break; - case NOTIFICATION_VISIBILITY_CHANGED: { - if (!is_visible() && tool_option_button[TOOL_OPT_OVERRIDE_CAMERA]->is_pressed()) { - EditorDebuggerNode *debugger = EditorDebuggerNode::get_singleton(); - - debugger->set_camera_override(EditorDebuggerNode::OVERRIDE_NONE); - tool_option_button[TOOL_OPT_OVERRIDE_CAMERA]->set_pressed(false); - } - } break; - case NOTIFICATION_PHYSICS_PROCESS: { if (do_snap_selected_nodes_to_floor) { _snap_selected_nodes_to_floor(); @@ -8216,6 +8176,10 @@ VSplitContainer *Node3DEditor::get_shader_split() { return shader_split; } +Node3DEditorViewport *Node3DEditor::get_last_used_viewport() { + return viewports[last_used_viewport]; +} + void Node3DEditor::add_control_to_left_panel(Control *p_control) { left_panel_split->add_child(p_control); left_panel_split->move_child(p_control, 0); @@ -8393,6 +8357,10 @@ void Node3DEditor::_toggle_maximize_view(Object *p_viewport) { } } +void Node3DEditor::_viewport_clicked(int p_viewport_idx) { + last_used_viewport = p_viewport_idx; +} + void Node3DEditor::_node_added(Node *p_node) { if (EditorNode::get_singleton()->get_scene_root()->is_ancestor_of(p_node)) { if (Object::cast_to<WorldEnvironment>(p_node)) { @@ -8512,7 +8480,7 @@ void Node3DEditor::clear() { } for (uint32_t i = 0; i < VIEWPORTS_COUNT; i++) { - viewports[i]->view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(Node3DEditorViewport::VIEW_AUDIO_LISTENER), i == 0); + viewports[i]->view_menu->get_popup()->set_item_checked(viewports[i]->view_menu->get_popup()->get_item_index(Node3DEditorViewport::VIEW_AUDIO_LISTENER), i == 0); viewports[i]->viewport->set_as_audio_listener_3d(i == 0); } @@ -8671,7 +8639,7 @@ Node3DEditor::Node3DEditor() { gizmo.visible = true; gizmo.scale = 1.0; - viewport_environment = Ref<Environment>(memnew(Environment)); + viewport_environment.instantiate(); VBoxContainer *vbc = this; custom_camera = nullptr; @@ -8684,8 +8652,6 @@ Node3DEditor::Node3DEditor() { snap_key_enabled = false; tool_mode = TOOL_MODE_SELECT; - camera_override_viewport_id = 0; - // Add some margin to the sides for better aesthetics. // This prevents the first button's hover/pressed effect from "touching" the panel's border, // which looks ugly. @@ -8803,16 +8769,6 @@ Node3DEditor::Node3DEditor() { tool_option_button[TOOL_OPT_USE_SNAP]->set_shortcut_context(this); main_menu_hbox->add_child(memnew(VSeparator)); - - tool_option_button[TOOL_OPT_OVERRIDE_CAMERA] = memnew(Button); - main_menu_hbox->add_child(tool_option_button[TOOL_OPT_OVERRIDE_CAMERA]); - tool_option_button[TOOL_OPT_OVERRIDE_CAMERA]->set_toggle_mode(true); - tool_option_button[TOOL_OPT_OVERRIDE_CAMERA]->set_theme_type_variation("FlatButton"); - tool_option_button[TOOL_OPT_OVERRIDE_CAMERA]->set_disabled(true); - tool_option_button[TOOL_OPT_OVERRIDE_CAMERA]->connect(SceneStringName(toggled), callable_mp(this, &Node3DEditor::_menu_item_toggled).bind(MENU_TOOL_OVERRIDE_CAMERA)); - _update_camera_override_button(false); - - main_menu_hbox->add_child(memnew(VSeparator)); sun_button = memnew(Button); sun_button->set_tooltip_text(TTR("Toggle preview sunlight.\nIf a DirectionalLight3D node is added to the scene, preview sunlight is disabled.")); sun_button->set_toggle_mode(true); @@ -8955,7 +8911,7 @@ Node3DEditor::Node3DEditor() { for (uint32_t i = 0; i < VIEWPORTS_COUNT; i++) { viewports[i] = memnew(Node3DEditorViewport(this, i)); viewports[i]->connect("toggle_maximize_view", callable_mp(this, &Node3DEditor::_toggle_maximize_view)); - viewports[i]->connect("clicked", callable_mp(this, &Node3DEditor::_update_camera_override_viewport)); + viewports[i]->connect("clicked", callable_mp(this, &Node3DEditor::_viewport_clicked).bind(i)); viewports[i]->assign_pending_data_pointers(preview_node, &preview_bounds, accept); viewport_base->add_child(viewports[i]); } diff --git a/editor/plugins/node_3d_editor_plugin.h b/editor/plugins/node_3d_editor_plugin.h index 1b03362606..d35fcb7653 100644 --- a/editor/plugins/node_3d_editor_plugin.h +++ b/editor/plugins/node_3d_editor_plugin.h @@ -622,7 +622,6 @@ public: enum ToolOptions { TOOL_OPT_LOCAL_COORDS, TOOL_OPT_USE_SNAP, - TOOL_OPT_OVERRIDE_CAMERA, TOOL_OPT_MAX }; @@ -632,6 +631,8 @@ private: Node3DEditorViewportContainer *viewport_base = nullptr; Node3DEditorViewport *viewports[VIEWPORTS_COUNT]; + int last_used_viewport = 0; + VSplitContainer *shader_split = nullptr; HSplitContainer *left_panel_split = nullptr; HSplitContainer *right_panel_split = nullptr; @@ -704,7 +705,6 @@ private: MENU_TOOL_LIST_SELECT, MENU_TOOL_LOCAL_COORDS, MENU_TOOL_USE_SNAP, - MENU_TOOL_OVERRIDE_CAMERA, MENU_TRANSFORM_CONFIGURE_SNAP, MENU_TRANSFORM_DIALOG, MENU_VIEW_USE_1_VIEWPORT, @@ -759,8 +759,6 @@ private: void _menu_item_pressed(int p_option); void _menu_item_toggled(bool pressed, int p_option); void _menu_gizmo_toggled(int p_option); - void _update_camera_override_button(bool p_game_running); - void _update_camera_override_viewport(Object *p_viewport); // Used for secondary menu items which are displayed depending on the currently selected node // (such as MeshInstance's "Mesh" menu). PanelContainer *context_toolbar_panel = nullptr; @@ -771,8 +769,6 @@ private: void _generate_selection_boxes(); - int camera_override_viewport_id; - void _init_indicators(); void _update_gizmos_menu(); void _update_gizmos_menu_theme(); @@ -781,6 +777,7 @@ private: void _finish_grid(); void _toggle_maximize_view(Object *p_viewport); + void _viewport_clicked(int p_viewport_idx); Node *custom_camera = nullptr; @@ -967,6 +964,7 @@ public: ERR_FAIL_INDEX_V(p_idx, static_cast<int>(VIEWPORTS_COUNT), nullptr); return viewports[p_idx]; } + Node3DEditorViewport *get_last_used_viewport(); void add_gizmo_plugin(Ref<EditorNode3DGizmoPlugin> p_plugin); void remove_gizmo_plugin(Ref<EditorNode3DGizmoPlugin> p_plugin); diff --git a/editor/plugins/occluder_instance_3d_editor_plugin.cpp b/editor/plugins/occluder_instance_3d_editor_plugin.cpp index c14d9e02aa..b9c884178f 100644 --- a/editor/plugins/occluder_instance_3d_editor_plugin.cpp +++ b/editor/plugins/occluder_instance_3d_editor_plugin.cpp @@ -105,7 +105,7 @@ void OccluderInstance3DEditorPlugin::_bind_methods() { OccluderInstance3DEditorPlugin::OccluderInstance3DEditorPlugin() { bake = memnew(Button); bake->set_theme_type_variation("FlatButton"); - bake->set_icon(EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("Bake"), EditorStringName(EditorIcons))); + bake->set_button_icon(EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("Bake"), EditorStringName(EditorIcons))); bake->set_text(TTR("Bake Occluders")); bake->hide(); bake->connect(SceneStringName(pressed), Callable(this, "_bake")); diff --git a/editor/plugins/packed_scene_editor_plugin.cpp b/editor/plugins/packed_scene_editor_plugin.cpp index c2d9851c17..4684c5a456 100644 --- a/editor/plugins/packed_scene_editor_plugin.cpp +++ b/editor/plugins/packed_scene_editor_plugin.cpp @@ -43,7 +43,7 @@ void PackedSceneEditor::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: case NOTIFICATION_THEME_CHANGED: { - open_scene_button->set_icon(get_editor_theme_icon(SNAME("PackedScene"))); + open_scene_button->set_button_icon(get_editor_theme_icon(SNAME("PackedScene"))); } break; } } diff --git a/editor/plugins/parallax_background_editor_plugin.cpp b/editor/plugins/parallax_background_editor_plugin.cpp index 6c55fd2753..e802f42596 100644 --- a/editor/plugins/parallax_background_editor_plugin.cpp +++ b/editor/plugins/parallax_background_editor_plugin.cpp @@ -119,7 +119,7 @@ void ParallaxBackgroundEditorPlugin::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: { menu->get_popup()->connect(SceneStringName(id_pressed), callable_mp(this, &ParallaxBackgroundEditorPlugin::_menu_callback)); - menu->set_icon(menu->get_editor_theme_icon(SNAME("ParallaxBackground"))); + menu->set_button_icon(menu->get_editor_theme_icon(SNAME("ParallaxBackground"))); } break; } } diff --git a/editor/plugins/particle_process_material_editor_plugin.cpp b/editor/plugins/particle_process_material_editor_plugin.cpp index 67c9403aaf..7b46653ac7 100644 --- a/editor/plugins/particle_process_material_editor_plugin.cpp +++ b/editor/plugins/particle_process_material_editor_plugin.cpp @@ -346,7 +346,7 @@ float ParticleProcessMaterialMinMaxPropertyEditor::_get_max_spread() const { void ParticleProcessMaterialMinMaxPropertyEditor::_notification(int p_what) { switch (p_what) { case NOTIFICATION_THEME_CHANGED: { - toggle_mode_button->set_icon(get_editor_theme_icon(SNAME("Anchor"))); + toggle_mode_button->set_button_icon(get_editor_theme_icon(SNAME("Anchor"))); range_slider_left_icon = get_editor_theme_icon(SNAME("RangeSliderLeft")); range_slider_right_icon = get_editor_theme_icon(SNAME("RangeSliderRight")); diff --git a/editor/plugins/particles_editor_plugin.cpp b/editor/plugins/particles_editor_plugin.cpp index 34f5dcf963..36a2d7acad 100644 --- a/editor/plugins/particles_editor_plugin.cpp +++ b/editor/plugins/particles_editor_plugin.cpp @@ -60,7 +60,7 @@ void ParticlesEditorPlugin::_notification(int p_what) { DEV_ASSERT(false); } - menu->set_icon(menu->get_editor_theme_icon(handled_type)); + menu->set_button_icon(menu->get_editor_theme_icon(handled_type)); menu->set_text(handled_type); PopupMenu *popup = menu->get_popup(); diff --git a/editor/plugins/path_2d_editor_plugin.cpp b/editor/plugins/path_2d_editor_plugin.cpp index c96f23869e..96e022e230 100644 --- a/editor/plugins/path_2d_editor_plugin.cpp +++ b/editor/plugins/path_2d_editor_plugin.cpp @@ -43,14 +43,14 @@ void Path2DEditor::_notification(int p_what) { switch (p_what) { case NOTIFICATION_THEME_CHANGED: { - curve_edit->set_icon(get_editor_theme_icon(SNAME("CurveEdit"))); - curve_edit_curve->set_icon(get_editor_theme_icon(SNAME("CurveCurve"))); - curve_create->set_icon(get_editor_theme_icon(SNAME("CurveCreate"))); - curve_del->set_icon(get_editor_theme_icon(SNAME("CurveDelete"))); - curve_close->set_icon(get_editor_theme_icon(SNAME("CurveClose"))); - curve_clear_points->set_icon(get_editor_theme_icon(SNAME("Clear"))); - - create_curve_button->set_icon(get_editor_theme_icon(SNAME("Curve2D"))); + curve_edit->set_button_icon(get_editor_theme_icon(SNAME("CurveEdit"))); + curve_edit_curve->set_button_icon(get_editor_theme_icon(SNAME("CurveCurve"))); + curve_create->set_button_icon(get_editor_theme_icon(SNAME("CurveCreate"))); + curve_del->set_button_icon(get_editor_theme_icon(SNAME("CurveDelete"))); + curve_close->set_button_icon(get_editor_theme_icon(SNAME("CurveClose"))); + curve_clear_points->set_button_icon(get_editor_theme_icon(SNAME("Clear"))); + + create_curve_button->set_button_icon(get_editor_theme_icon(SNAME("Curve2D"))); } break; } } diff --git a/editor/plugins/path_3d_editor_plugin.cpp b/editor/plugins/path_3d_editor_plugin.cpp index 4fdcb79696..3a4b3a0ea2 100644 --- a/editor/plugins/path_3d_editor_plugin.cpp +++ b/editor/plugins/path_3d_editor_plugin.cpp @@ -790,14 +790,14 @@ void Path3DEditorPlugin::_restore_curve_points(const PackedVector3Array &p_point } void Path3DEditorPlugin::_update_theme() { - curve_edit->set_icon(topmenu_bar->get_editor_theme_icon(SNAME("CurveEdit"))); - curve_edit_curve->set_icon(topmenu_bar->get_editor_theme_icon(SNAME("CurveCurve"))); - curve_edit_tilt->set_icon(topmenu_bar->get_editor_theme_icon(SNAME("CurveTilt"))); - curve_create->set_icon(topmenu_bar->get_editor_theme_icon(SNAME("CurveCreate"))); - curve_del->set_icon(topmenu_bar->get_editor_theme_icon(SNAME("CurveDelete"))); - curve_close->set_icon(topmenu_bar->get_editor_theme_icon(SNAME("CurveClose"))); - curve_clear_points->set_icon(topmenu_bar->get_editor_theme_icon(SNAME("Clear"))); - create_curve_button->set_icon(topmenu_bar->get_editor_theme_icon(SNAME("Curve3D"))); + curve_edit->set_button_icon(topmenu_bar->get_editor_theme_icon(SNAME("CurveEdit"))); + curve_edit_curve->set_button_icon(topmenu_bar->get_editor_theme_icon(SNAME("CurveCurve"))); + curve_edit_tilt->set_button_icon(topmenu_bar->get_editor_theme_icon(SNAME("CurveTilt"))); + curve_create->set_button_icon(topmenu_bar->get_editor_theme_icon(SNAME("CurveCreate"))); + curve_del->set_button_icon(topmenu_bar->get_editor_theme_icon(SNAME("CurveDelete"))); + curve_close->set_button_icon(topmenu_bar->get_editor_theme_icon(SNAME("CurveClose"))); + curve_clear_points->set_button_icon(topmenu_bar->get_editor_theme_icon(SNAME("Clear"))); + create_curve_button->set_button_icon(topmenu_bar->get_editor_theme_icon(SNAME("Curve3D"))); } void Path3DEditorPlugin::_update_toolbar() { @@ -922,7 +922,7 @@ Ref<EditorNode3DGizmo> Path3DGizmoPlugin::create_gizmo(Node3D *p_spatial) { Path3D *path = Object::cast_to<Path3D>(p_spatial); if (path) { - ref = Ref<Path3DGizmo>(memnew(Path3DGizmo(path, disk_size))); + ref.instantiate(path, disk_size); } return ref; diff --git a/editor/plugins/physical_bone_3d_editor_plugin.cpp b/editor/plugins/physical_bone_3d_editor_plugin.cpp index c858fa8606..15a957d5c4 100644 --- a/editor/plugins/physical_bone_3d_editor_plugin.cpp +++ b/editor/plugins/physical_bone_3d_editor_plugin.cpp @@ -60,7 +60,7 @@ PhysicalBone3DEditor::PhysicalBone3DEditor() { button_transform_joint->set_text(TTR("Move Joint")); // TODO: Rework this as a dedicated toolbar control so we can hook into theme changes and update it // when the editor theme updates. - button_transform_joint->set_icon(EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("PhysicalBone3D"), EditorStringName(EditorIcons))); + button_transform_joint->set_button_icon(EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("PhysicalBone3D"), EditorStringName(EditorIcons))); button_transform_joint->set_toggle_mode(true); button_transform_joint->connect(SceneStringName(toggled), callable_mp(this, &PhysicalBone3DEditor::_on_toggle_button_transform_joint)); diff --git a/editor/plugins/polygon_2d_editor_plugin.cpp b/editor/plugins/polygon_2d_editor_plugin.cpp index 842142db79..8ab08ff28f 100644 --- a/editor/plugins/polygon_2d_editor_plugin.cpp +++ b/editor/plugins/polygon_2d_editor_plugin.cpp @@ -111,22 +111,22 @@ void Polygon2DEditor::_notification(int p_what) { } break; case NOTIFICATION_READY: { - button_uv->set_icon(get_editor_theme_icon(SNAME("Uv"))); - - uv_button[UV_MODE_CREATE]->set_icon(get_editor_theme_icon(SNAME("Edit"))); - uv_button[UV_MODE_CREATE_INTERNAL]->set_icon(get_editor_theme_icon(SNAME("EditInternal"))); - uv_button[UV_MODE_REMOVE_INTERNAL]->set_icon(get_editor_theme_icon(SNAME("RemoveInternal"))); - uv_button[UV_MODE_EDIT_POINT]->set_icon(get_editor_theme_icon(SNAME("ToolSelect"))); - uv_button[UV_MODE_MOVE]->set_icon(get_editor_theme_icon(SNAME("ToolMove"))); - uv_button[UV_MODE_ROTATE]->set_icon(get_editor_theme_icon(SNAME("ToolRotate"))); - uv_button[UV_MODE_SCALE]->set_icon(get_editor_theme_icon(SNAME("ToolScale"))); - uv_button[UV_MODE_ADD_POLYGON]->set_icon(get_editor_theme_icon(SNAME("Edit"))); - uv_button[UV_MODE_REMOVE_POLYGON]->set_icon(get_editor_theme_icon(SNAME("Close"))); - uv_button[UV_MODE_PAINT_WEIGHT]->set_icon(get_editor_theme_icon(SNAME("Bucket"))); - uv_button[UV_MODE_CLEAR_WEIGHT]->set_icon(get_editor_theme_icon(SNAME("Clear"))); - - b_snap_grid->set_icon(get_editor_theme_icon(SNAME("Grid"))); - b_snap_enable->set_icon(get_editor_theme_icon(SNAME("SnapGrid"))); + button_uv->set_button_icon(get_editor_theme_icon(SNAME("Uv"))); + + uv_button[UV_MODE_CREATE]->set_button_icon(get_editor_theme_icon(SNAME("Edit"))); + uv_button[UV_MODE_CREATE_INTERNAL]->set_button_icon(get_editor_theme_icon(SNAME("EditInternal"))); + uv_button[UV_MODE_REMOVE_INTERNAL]->set_button_icon(get_editor_theme_icon(SNAME("RemoveInternal"))); + uv_button[UV_MODE_EDIT_POINT]->set_button_icon(get_editor_theme_icon(SNAME("ToolSelect"))); + uv_button[UV_MODE_MOVE]->set_button_icon(get_editor_theme_icon(SNAME("ToolMove"))); + uv_button[UV_MODE_ROTATE]->set_button_icon(get_editor_theme_icon(SNAME("ToolRotate"))); + uv_button[UV_MODE_SCALE]->set_button_icon(get_editor_theme_icon(SNAME("ToolScale"))); + uv_button[UV_MODE_ADD_POLYGON]->set_button_icon(get_editor_theme_icon(SNAME("Edit"))); + uv_button[UV_MODE_REMOVE_POLYGON]->set_button_icon(get_editor_theme_icon(SNAME("Close"))); + uv_button[UV_MODE_PAINT_WEIGHT]->set_button_icon(get_editor_theme_icon(SNAME("Bucket"))); + uv_button[UV_MODE_CLEAR_WEIGHT]->set_button_icon(get_editor_theme_icon(SNAME("Clear"))); + + b_snap_grid->set_button_icon(get_editor_theme_icon(SNAME("Grid"))); + b_snap_enable->set_button_icon(get_editor_theme_icon(SNAME("SnapGrid"))); uv_vscroll->set_anchors_and_offsets_preset(PRESET_RIGHT_WIDE); uv_hscroll->set_anchors_and_offsets_preset(PRESET_BOTTOM_WIDE); @@ -275,7 +275,11 @@ void Polygon2DEditor::_uv_edit_mode_select(int p_mode) { uv_button[UV_MODE_REMOVE_POLYGON]->hide(); uv_button[UV_MODE_PAINT_WEIGHT]->hide(); uv_button[UV_MODE_CLEAR_WEIGHT]->hide(); - _uv_mode(UV_MODE_EDIT_POINT); + if (node->get_polygon().is_empty()) { + _uv_mode(UV_MODE_CREATE); + } else { + _uv_mode(UV_MODE_EDIT_POINT); + } bone_scroll_main_vb->hide(); bone_paint_strength->hide(); @@ -317,9 +321,16 @@ void Polygon2DEditor::_uv_edit_mode_select(int p_mode) { uv_edit_draw->queue_redraw(); } +void Polygon2DEditor::_uv_edit_popup_show() { + EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton(); + undo_redo->connect("version_changed", callable_mp(this, &Polygon2DEditor::_update_available_modes)); +} + void Polygon2DEditor::_uv_edit_popup_hide() { EditorSettings::get_singleton()->set_project_metadata("dialog_bounds", "uv_editor", Rect2(uv_edit->get_position(), uv_edit->get_size())); _cancel_editing(); + EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton(); + undo_redo->disconnect("version_changed", callable_mp(this, &Polygon2DEditor::_update_available_modes)); } void Polygon2DEditor::_menu_option(int p_option) { @@ -346,6 +357,7 @@ void Polygon2DEditor::_menu_option(int p_option) { uv_edit->popup_centered_ratio(0.85); } _update_bone_list(); + _update_available_modes(); get_tree()->connect("process_frame", callable_mp(this, &Polygon2DEditor::_center_view), CONNECT_ONE_SHOT); } break; case UVEDIT_POLYGON_TO_UV: { @@ -408,6 +420,7 @@ void Polygon2DEditor::_cancel_editing() { node->set_polygons(polygons_prev); _update_polygon_editing_state(); + _update_available_modes(); } else if (uv_drag) { uv_drag = false; if (uv_edit_mode[0]->is_pressed()) { // Edit UV. @@ -566,6 +579,7 @@ void Polygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) { uv_drag = false; uv_create = false; + _update_available_modes(); _uv_mode(UV_MODE_EDIT_POINT); _menu_option(MODE_EDIT); } else { @@ -973,6 +987,23 @@ void Polygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) { } } +void Polygon2DEditor::_update_available_modes() { + // Force point editing mode if there's no polygon yet. + if (node->get_polygon().is_empty()) { + if (!uv_edit_mode[1]->is_pressed()) { + uv_edit_mode[1]->set_pressed(true); + _uv_edit_mode_select(1); + } + uv_edit_mode[0]->set_disabled(true); + uv_edit_mode[2]->set_disabled(true); + uv_edit_mode[3]->set_disabled(true); + } else { + uv_edit_mode[0]->set_disabled(false); + uv_edit_mode[2]->set_disabled(false); + uv_edit_mode[3]->set_disabled(false); + } +} + void Polygon2DEditor::_center_view() { Size2 texture_size; if (node->get_texture().is_valid()) { @@ -1324,6 +1355,7 @@ Polygon2DEditor::Polygon2DEditor() { add_child(uv_edit); uv_edit->connect(SceneStringName(confirmed), callable_mp(this, &Polygon2DEditor::_uv_edit_popup_hide)); uv_edit->connect("canceled", callable_mp(this, &Polygon2DEditor::_uv_edit_popup_hide)); + uv_edit->connect("about_to_popup", callable_mp(this, &Polygon2DEditor::_uv_edit_popup_show)); VBoxContainer *uv_main_vb = memnew(VBoxContainer); uv_edit->add_child(uv_main_vb); diff --git a/editor/plugins/polygon_2d_editor_plugin.h b/editor/plugins/polygon_2d_editor_plugin.h index 164aa3eccc..4e1cd7172e 100644 --- a/editor/plugins/polygon_2d_editor_plugin.h +++ b/editor/plugins/polygon_2d_editor_plugin.h @@ -142,6 +142,7 @@ class Polygon2DEditor : public AbstractPolygon2DEditor { void _cancel_editing(); void _update_polygon_editing_state(); + void _update_available_modes(); void _center_view(); void _update_zoom_and_pan(bool p_zoom_at_center); @@ -157,6 +158,7 @@ class Polygon2DEditor : public AbstractPolygon2DEditor { void _set_snap_step_y(real_t p_val); void _uv_edit_mode_select(int p_mode); + void _uv_edit_popup_show(); void _uv_edit_popup_hide(); void _bone_paint_selected(int p_index); @@ -168,7 +170,7 @@ protected: virtual Vector2 _get_offset(int p_idx) const override; - virtual bool _has_uv() const override { return true; }; + virtual bool _has_uv() const override { return true; } virtual void _commit_action() override; void _notification(int p_what); diff --git a/editor/plugins/polygon_3d_editor_plugin.cpp b/editor/plugins/polygon_3d_editor_plugin.cpp index 56baa4a839..017504f0d6 100644 --- a/editor/plugins/polygon_3d_editor_plugin.cpp +++ b/editor/plugins/polygon_3d_editor_plugin.cpp @@ -46,8 +46,8 @@ void Polygon3DEditor::_notification(int p_what) { switch (p_what) { case NOTIFICATION_READY: { - button_create->set_icon(get_editor_theme_icon(SNAME("Edit"))); - button_edit->set_icon(get_editor_theme_icon(SNAME("MovePoint"))); + button_create->set_button_icon(get_editor_theme_icon(SNAME("Edit"))); + button_edit->set_button_icon(get_editor_theme_icon(SNAME("MovePoint"))); button_edit->set_pressed(true); get_tree()->connect("node_removed", callable_mp(this, &Polygon3DEditor::_node_removed)); @@ -554,7 +554,7 @@ Polygon3DEditor::Polygon3DEditor() { imgeom->set_mesh(imesh); imgeom->set_transform(Transform3D(Basis(), Vector3(0, 0, 0.00001))); - line_material = Ref<StandardMaterial3D>(memnew(StandardMaterial3D)); + line_material.instantiate(); line_material->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED); line_material->set_transparency(StandardMaterial3D::TRANSPARENCY_ALPHA); line_material->set_flag(StandardMaterial3D::FLAG_ALBEDO_FROM_VERTEX_COLOR, true); @@ -562,7 +562,7 @@ Polygon3DEditor::Polygon3DEditor() { line_material->set_flag(StandardMaterial3D::FLAG_DISABLE_FOG, true); line_material->set_albedo(Color(1, 1, 1)); - handle_material = Ref<StandardMaterial3D>(memnew(StandardMaterial3D)); + handle_material.instantiate(); handle_material->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED); handle_material->set_flag(StandardMaterial3D::FLAG_USE_POINT_SIZE, true); handle_material->set_transparency(StandardMaterial3D::TRANSPARENCY_ALPHA); diff --git a/editor/plugins/resource_preloader_editor_plugin.cpp b/editor/plugins/resource_preloader_editor_plugin.cpp index ba6699fcc4..bb0607a3c6 100644 --- a/editor/plugins/resource_preloader_editor_plugin.cpp +++ b/editor/plugins/resource_preloader_editor_plugin.cpp @@ -45,7 +45,7 @@ void ResourcePreloaderEditor::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: case NOTIFICATION_THEME_CHANGED: { - load->set_icon(get_editor_theme_icon(SNAME("Folder"))); + load->set_button_icon(get_editor_theme_icon(SNAME("Folder"))); } break; } } diff --git a/editor/plugins/root_motion_editor_plugin.cpp b/editor/plugins/root_motion_editor_plugin.cpp index cd422fc291..0a4e3d78c8 100644 --- a/editor/plugins/root_motion_editor_plugin.cpp +++ b/editor/plugins/root_motion_editor_plugin.cpp @@ -169,13 +169,13 @@ void EditorPropertyRootMotion::update_property() { NodePath p = get_edited_property_value(); assign->set_tooltip_text(p); if (p == NodePath()) { - assign->set_icon(Ref<Texture2D>()); + assign->set_button_icon(Ref<Texture2D>()); assign->set_text(TTR("Assign...")); assign->set_flat(false); return; } - assign->set_icon(Ref<Texture2D>()); + assign->set_button_icon(Ref<Texture2D>()); assign->set_text(p); } @@ -188,7 +188,7 @@ void EditorPropertyRootMotion::_notification(int p_what) { case NOTIFICATION_ENTER_TREE: case NOTIFICATION_THEME_CHANGED: { Ref<Texture2D> t = get_editor_theme_icon(SNAME("Clear")); - clear->set_icon(t); + clear->set_button_icon(t); } break; } } diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp index 7e0331d15c..8c3979918d 100644 --- a/editor/plugins/script_editor_plugin.cpp +++ b/editor/plugins/script_editor_plugin.cpp @@ -261,6 +261,52 @@ Ref<EditorSyntaxHighlighter> EditorJSONSyntaxHighlighter::_create() const { return syntax_highlighter; } +//// + +void EditorMarkdownSyntaxHighlighter::_update_cache() { + highlighter->set_text_edit(text_edit); + highlighter->clear_keyword_colors(); + highlighter->clear_member_keyword_colors(); + highlighter->clear_color_regions(); + + // Disable automatic symbolic highlights, as these don't make sense for prose. + highlighter->set_symbol_color(EDITOR_GET("text_editor/theme/highlighting/text_color")); + highlighter->set_number_color(EDITOR_GET("text_editor/theme/highlighting/text_color")); + highlighter->set_member_variable_color(EDITOR_GET("text_editor/theme/highlighting/text_color")); + highlighter->set_function_color(EDITOR_GET("text_editor/theme/highlighting/text_color")); + + // Headings (any level). + const Color function_color = EDITOR_GET("text_editor/theme/highlighting/function_color"); + highlighter->add_color_region("#", "", function_color); + + // Bold. + highlighter->add_color_region("**", "**", function_color); + // `__bold__` syntax is not supported as color regions must begin with a symbol, + // not a character that is valid in an identifier. + + // Code (both inline code and triple-backticks code blocks). + const Color code_color = EDITOR_GET("text_editor/theme/highlighting/engine_type_color"); + highlighter->add_color_region("`", "`", code_color); + + // Link (both references and inline links with URLs). The URL is not highlighted. + const Color link_color = EDITOR_GET("text_editor/theme/highlighting/keyword_color"); + highlighter->add_color_region("[", "]", link_color); + + // Quote. + const Color quote_color = EDITOR_GET("text_editor/theme/highlighting/string_color"); + highlighter->add_color_region(">", "", quote_color, true); + + // HTML comment, which is also supported in Markdown. + const Color comment_color = EDITOR_GET("text_editor/theme/highlighting/comment_color"); + highlighter->add_color_region("<!--", "-->", comment_color); +} + +Ref<EditorSyntaxHighlighter> EditorMarkdownSyntaxHighlighter::_create() const { + Ref<EditorMarkdownSyntaxHighlighter> syntax_highlighter; + syntax_highlighter.instantiate(); + return syntax_highlighter; +} + //////////////////////////////////////////////////////////////////////////////// /*** SCRIPT EDITOR ****/ @@ -1734,18 +1780,18 @@ void ScriptEditor::_notification(int p_what) { case NOTIFICATION_THEME_CHANGED: { tab_container->add_theme_style_override(SceneStringName(panel), get_theme_stylebox(SNAME("ScriptEditor"), EditorStringName(EditorStyles))); - help_search->set_icon(get_editor_theme_icon(SNAME("HelpSearch"))); - site_search->set_icon(get_editor_theme_icon(SNAME("ExternalLink"))); + help_search->set_button_icon(get_editor_theme_icon(SNAME("HelpSearch"))); + site_search->set_button_icon(get_editor_theme_icon(SNAME("ExternalLink"))); if (is_layout_rtl()) { - script_forward->set_icon(get_editor_theme_icon(SNAME("Back"))); - script_back->set_icon(get_editor_theme_icon(SNAME("Forward"))); + script_forward->set_button_icon(get_editor_theme_icon(SNAME("Back"))); + script_back->set_button_icon(get_editor_theme_icon(SNAME("Forward"))); } else { - script_forward->set_icon(get_editor_theme_icon(SNAME("Forward"))); - script_back->set_icon(get_editor_theme_icon(SNAME("Back"))); + script_forward->set_button_icon(get_editor_theme_icon(SNAME("Forward"))); + script_back->set_button_icon(get_editor_theme_icon(SNAME("Back"))); } - members_overview_alphabeta_sort_button->set_icon(get_editor_theme_icon(SNAME("Sort"))); + members_overview_alphabeta_sort_button->set_button_icon(get_editor_theme_icon(SNAME("Sort"))); filter_scripts->set_right_icon(get_editor_theme_icon(SNAME("Search"))); filter_methods->set_right_icon(get_editor_theme_icon(SNAME("Search"))); @@ -2139,8 +2185,6 @@ void ScriptEditor::_update_script_colors() { continue; } - script_list->set_item_custom_bg_color(i, Color(0, 0, 0, 0)); - if (script_temperature_enabled) { int pass = n->get_meta("__editor_pass", -1); if (pass < 0) { @@ -2166,7 +2210,7 @@ void ScriptEditor::_update_script_names() { HashSet<Ref<Script>> used; Node *edited = EditorNode::get_singleton()->get_edited_scene(); - if (edited) { + if (edited && EDITOR_GET("text_editor/script_list/highlight_scene_scripts")) { _find_scripts(edited, edited, used); } @@ -2336,7 +2380,7 @@ void ScriptEditor::_update_script_names() { script_list->set_item_tooltip(index, sedata_filtered[i].tooltip); script_list->set_item_metadata(index, sedata_filtered[i].index); /* Saving as metadata the script's index in the tab container and not the filtered one */ if (sedata_filtered[i].used) { - script_list->set_item_custom_bg_color(index, Color(88 / 255.0, 88 / 255.0, 60 / 255.0)); + script_list->set_item_custom_bg_color(index, Color(.5, .5, .5, .125)); } if (tab_container->get_current_tab() == sedata_filtered[i].index) { script_list->select(index); @@ -4414,6 +4458,10 @@ ScriptEditor::ScriptEditor(WindowWrapper *p_wrapper) { json_syntax_highlighter.instantiate(); register_syntax_highlighter(json_syntax_highlighter); + Ref<EditorMarkdownSyntaxHighlighter> markdown_syntax_highlighter; + markdown_syntax_highlighter.instantiate(); + register_syntax_highlighter(markdown_syntax_highlighter); + _update_online_doc(); } diff --git a/editor/plugins/script_editor_plugin.h b/editor/plugins/script_editor_plugin.h index 8e82d60605..5de0aaa1e9 100644 --- a/editor/plugins/script_editor_plugin.h +++ b/editor/plugins/script_editor_plugin.h @@ -120,6 +120,24 @@ public: EditorJSONSyntaxHighlighter() { highlighter.instantiate(); } }; +class EditorMarkdownSyntaxHighlighter : public EditorSyntaxHighlighter { + GDCLASS(EditorMarkdownSyntaxHighlighter, EditorSyntaxHighlighter) + +private: + Ref<CodeHighlighter> highlighter; + +public: + virtual void _update_cache() override; + virtual Dictionary _get_line_syntax_highlighting_impl(int p_line) override { return highlighter->get_line_syntax_highlighting(p_line); } + + virtual PackedStringArray _get_supported_languages() const override { return PackedStringArray{ "md", "markdown" }; } + virtual String _get_name() const override { return TTR("Markdown"); } + + virtual Ref<EditorSyntaxHighlighter> _create() const override; + + EditorMarkdownSyntaxHighlighter() { highlighter.instantiate(); } +}; + /////////////////////////////////////////////////////////////////////////////// class ScriptEditorQuickOpen : public ConfirmationDialog { diff --git a/editor/plugins/shader_file_editor_plugin.cpp b/editor/plugins/shader_file_editor_plugin.cpp index d732d51f69..d2fd9b1cc0 100644 --- a/editor/plugins/shader_file_editor_plugin.cpp +++ b/editor/plugins/shader_file_editor_plugin.cpp @@ -63,7 +63,7 @@ void ShaderFileEditor::_version_selected(int p_option) { for (int i = 0; i < RD::SHADER_STAGE_MAX; i++) { if (bytecode->get_stage_bytecode(RD::ShaderStage(i)).is_empty() && bytecode->get_stage_compile_error(RD::ShaderStage(i)) == String()) { - stages[i]->set_icon(Ref<Texture2D>()); + stages[i]->set_button_icon(Ref<Texture2D>()); continue; } @@ -73,7 +73,7 @@ void ShaderFileEditor::_version_selected(int p_option) { } else { icon = get_editor_theme_icon(SNAME("ImportCheck")); } - stages[i]->set_icon(icon); + stages[i]->set_button_icon(icon); if (first_found == -1) { first_found = i; diff --git a/editor/plugins/skeleton_2d_editor_plugin.cpp b/editor/plugins/skeleton_2d_editor_plugin.cpp index 8f54641dcb..97ad0ff640 100644 --- a/editor/plugins/skeleton_2d_editor_plugin.cpp +++ b/editor/plugins/skeleton_2d_editor_plugin.cpp @@ -96,7 +96,7 @@ Skeleton2DEditor::Skeleton2DEditor() { CanvasItemEditor::get_singleton()->add_control_to_menu_panel(options); options->set_text(TTR("Skeleton2D")); - options->set_icon(EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("Skeleton2D"), EditorStringName(EditorIcons))); + options->set_button_icon(EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("Skeleton2D"), EditorStringName(EditorIcons))); options->get_popup()->add_item(TTR("Reset to Rest Pose"), MENU_OPTION_SET_REST); options->get_popup()->add_separator(); diff --git a/editor/plugins/skeleton_3d_editor_plugin.cpp b/editor/plugins/skeleton_3d_editor_plugin.cpp index 81beaf6f91..369a1fc864 100644 --- a/editor/plugins/skeleton_3d_editor_plugin.cpp +++ b/editor/plugins/skeleton_3d_editor_plugin.cpp @@ -123,7 +123,7 @@ void BonePropertiesEditor::_notification(int p_what) { const Color section_color = get_theme_color(SNAME("prop_subsection"), EditorStringName(Editor)); section->set_bg_color(section_color); rest_section->set_bg_color(section_color); - add_metadata_button->set_icon(get_editor_theme_icon(SNAME("Add"))); + add_metadata_button->set_button_icon(get_editor_theme_icon(SNAME("Add"))); } break; } } @@ -351,12 +351,12 @@ void Skeleton3DEditor::set_keyable(const bool p_keyable) { } else { animation_hb->hide(); } -}; +} void Skeleton3DEditor::set_bone_options_enabled(const bool p_bone_options_enabled) { skeleton_options->get_popup()->set_item_disabled(SKELETON_OPTION_RESET_SELECTED_POSES, !p_bone_options_enabled); skeleton_options->get_popup()->set_item_disabled(SKELETON_OPTION_SELECTED_POSES_TO_RESTS, !p_bone_options_enabled); -}; +} void Skeleton3DEditor::_bind_methods() { ClassDB::bind_method(D_METHOD("update_all"), &Skeleton3DEditor::update_all); @@ -1136,13 +1136,13 @@ void Skeleton3DEditor::_notification(int p_what) { add_theme_constant_override("separation", 0); } break; case NOTIFICATION_THEME_CHANGED: { - skeleton_options->set_icon(get_editor_theme_icon(SNAME("Skeleton3D"))); - edit_mode_button->set_icon(get_editor_theme_icon(SNAME("ToolBoneSelect"))); - key_loc_button->set_icon(get_editor_theme_icon(SNAME("KeyPosition"))); - key_rot_button->set_icon(get_editor_theme_icon(SNAME("KeyRotation"))); - key_scale_button->set_icon(get_editor_theme_icon(SNAME("KeyScale"))); - key_insert_button->set_icon(get_editor_theme_icon(SNAME("Key"))); - key_insert_all_button->set_icon(get_editor_theme_icon(SNAME("NewKey"))); + skeleton_options->set_button_icon(get_editor_theme_icon(SNAME("Skeleton3D"))); + edit_mode_button->set_button_icon(get_editor_theme_icon(SNAME("ToolBoneSelect"))); + key_loc_button->set_button_icon(get_editor_theme_icon(SNAME("KeyPosition"))); + key_rot_button->set_button_icon(get_editor_theme_icon(SNAME("KeyRotation"))); + key_scale_button->set_button_icon(get_editor_theme_icon(SNAME("KeyScale"))); + key_insert_button->set_button_icon(get_editor_theme_icon(SNAME("Key"))); + key_insert_all_button->set_button_icon(get_editor_theme_icon(SNAME("NewKey"))); bones_section->set_bg_color(get_theme_color(SNAME("prop_subsection"), EditorStringName(Editor))); update_joint_tree(); @@ -1186,8 +1186,8 @@ Skeleton3DEditor::Skeleton3DEditor(EditorInspectorPluginSkeleton *e_plugin, Skel singleton = this; // Handle. - handle_material = Ref<ShaderMaterial>(memnew(ShaderMaterial)); - handle_shader = Ref<Shader>(memnew(Shader)); + handle_material.instantiate(); + handle_shader.instantiate(); handle_shader->set_code(R"( // Skeleton 3D gizmo handle shader. diff --git a/editor/plugins/skeleton_3d_editor_plugin.h b/editor/plugins/skeleton_3d_editor_plugin.h index 0265183dfa..c6f8c5d357 100644 --- a/editor/plugins/skeleton_3d_editor_plugin.h +++ b/editor/plugins/skeleton_3d_editor_plugin.h @@ -228,14 +228,14 @@ public: void move_skeleton_bone(NodePath p_skeleton_path, int32_t p_selected_boneidx, int32_t p_target_boneidx); - Skeleton3D *get_skeleton() const { return skeleton; }; + Skeleton3D *get_skeleton() const { return skeleton; } bool is_edit_mode() const { return edit_mode; } void update_bone_original(); - Vector3 get_bone_original_position() const { return bone_original_position; }; - Quaternion get_bone_original_rotation() const { return bone_original_rotation; }; - Vector3 get_bone_original_scale() const { return bone_original_scale; }; + Vector3 get_bone_original_position() const { return bone_original_position; } + Quaternion get_bone_original_rotation() const { return bone_original_rotation; } + Vector3 get_bone_original_scale() const { return bone_original_scale; } Skeleton3DEditor(EditorInspectorPluginSkeleton *e_plugin, Skeleton3D *skeleton); ~Skeleton3DEditor(); diff --git a/editor/plugins/skeleton_ik_3d_editor_plugin.cpp b/editor/plugins/skeleton_ik_3d_editor_plugin.cpp index 9b98b6ffa2..d0c8744dc2 100644 --- a/editor/plugins/skeleton_ik_3d_editor_plugin.cpp +++ b/editor/plugins/skeleton_ik_3d_editor_plugin.cpp @@ -75,7 +75,7 @@ void SkeletonIK3DEditorPlugin::make_visible(bool p_visible) { SkeletonIK3DEditorPlugin::SkeletonIK3DEditorPlugin() { play_btn = memnew(Button); - play_btn->set_icon(EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("Play"), EditorStringName(EditorIcons))); + play_btn->set_button_icon(EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("Play"), EditorStringName(EditorIcons))); play_btn->set_text(TTR("Play IK")); play_btn->set_toggle_mode(true); play_btn->hide(); diff --git a/editor/plugins/sprite_2d_editor_plugin.cpp b/editor/plugins/sprite_2d_editor_plugin.cpp index c7db243662..c365ad6133 100644 --- a/editor/plugins/sprite_2d_editor_plugin.cpp +++ b/editor/plugins/sprite_2d_editor_plugin.cpp @@ -560,7 +560,7 @@ void Sprite2DEditor::_notification(int p_what) { } break; case NOTIFICATION_ENTER_TREE: case NOTIFICATION_THEME_CHANGED: { - options->set_icon(get_editor_theme_icon(SNAME("Sprite2D"))); + options->set_button_icon(get_editor_theme_icon(SNAME("Sprite2D"))); options->get_popup()->set_item_icon(MENU_OPTION_CONVERT_TO_MESH_2D, get_editor_theme_icon(SNAME("MeshInstance2D"))); options->get_popup()->set_item_icon(MENU_OPTION_CONVERT_TO_POLYGON_2D, get_editor_theme_icon(SNAME("Polygon2D"))); @@ -593,12 +593,12 @@ Sprite2DEditor::Sprite2DEditor() { add_child(err_dialog); debug_uv_dialog = memnew(ConfirmationDialog); + debug_uv_dialog->set_size(Size2(960, 540) * EDSCALE); VBoxContainer *vb = memnew(VBoxContainer); debug_uv_dialog->add_child(vb); debug_uv = memnew(Panel); debug_uv->connect(SceneStringName(gui_input), callable_mp(this, &Sprite2DEditor::_debug_uv_input)); debug_uv->connect(SceneStringName(draw), callable_mp(this, &Sprite2DEditor::_debug_uv_draw)); - debug_uv->set_custom_minimum_size(Size2(800, 500) * EDSCALE); debug_uv->set_clip_contents(true); vb->add_margin_child(TTR("Preview:"), debug_uv, true); diff --git a/editor/plugins/sprite_frames_editor_plugin.cpp b/editor/plugins/sprite_frames_editor_plugin.cpp index 168a3b3ac2..f29ace1d15 100644 --- a/editor/plugins/sprite_frames_editor_plugin.cpp +++ b/editor/plugins/sprite_frames_editor_plugin.cpp @@ -498,9 +498,9 @@ void SpriteFramesEditor::_toggle_show_settings() { void SpriteFramesEditor::_update_show_settings() { if (is_layout_rtl()) { - toggle_settings_button->set_icon(get_editor_theme_icon(split_sheet_settings_vb->is_visible() ? SNAME("Back") : SNAME("Forward"))); + toggle_settings_button->set_button_icon(get_editor_theme_icon(split_sheet_settings_vb->is_visible() ? SNAME("Back") : SNAME("Forward"))); } else { - toggle_settings_button->set_icon(get_editor_theme_icon(split_sheet_settings_vb->is_visible() ? SNAME("Forward") : SNAME("Back"))); + toggle_settings_button->set_button_icon(get_editor_theme_icon(split_sheet_settings_vb->is_visible() ? SNAME("Forward") : SNAME("Back"))); } } @@ -639,32 +639,32 @@ void SpriteFramesEditor::_notification(int p_what) { pause_icon = get_editor_theme_icon(SNAME("Pause")); _update_stop_icon(); - autoplay->set_icon(get_editor_theme_icon(SNAME("AutoPlay"))); - anim_loop->set_icon(get_editor_theme_icon(SNAME("Loop"))); - play->set_icon(get_editor_theme_icon(SNAME("PlayStart"))); - play_from->set_icon(get_editor_theme_icon(SNAME("Play"))); - play_bw->set_icon(get_editor_theme_icon(SNAME("PlayStartBackwards"))); - play_bw_from->set_icon(get_editor_theme_icon(SNAME("PlayBackwards"))); - - load->set_icon(get_editor_theme_icon(SNAME("Load"))); - load_sheet->set_icon(get_editor_theme_icon(SNAME("SpriteSheet"))); - copy->set_icon(get_editor_theme_icon(SNAME("ActionCopy"))); - paste->set_icon(get_editor_theme_icon(SNAME("ActionPaste"))); - empty_before->set_icon(get_editor_theme_icon(SNAME("InsertBefore"))); - empty_after->set_icon(get_editor_theme_icon(SNAME("InsertAfter"))); - move_up->set_icon(get_editor_theme_icon(SNAME("MoveLeft"))); - move_down->set_icon(get_editor_theme_icon(SNAME("MoveRight"))); - delete_frame->set_icon(get_editor_theme_icon(SNAME("Remove"))); - zoom_out->set_icon(get_editor_theme_icon(SNAME("ZoomLess"))); - zoom_reset->set_icon(get_editor_theme_icon(SNAME("ZoomReset"))); - zoom_in->set_icon(get_editor_theme_icon(SNAME("ZoomMore"))); - add_anim->set_icon(get_editor_theme_icon(SNAME("New"))); - duplicate_anim->set_icon(get_editor_theme_icon(SNAME("Duplicate"))); - delete_anim->set_icon(get_editor_theme_icon(SNAME("Remove"))); + autoplay->set_button_icon(get_editor_theme_icon(SNAME("AutoPlay"))); + anim_loop->set_button_icon(get_editor_theme_icon(SNAME("Loop"))); + play->set_button_icon(get_editor_theme_icon(SNAME("PlayStart"))); + play_from->set_button_icon(get_editor_theme_icon(SNAME("Play"))); + play_bw->set_button_icon(get_editor_theme_icon(SNAME("PlayStartBackwards"))); + play_bw_from->set_button_icon(get_editor_theme_icon(SNAME("PlayBackwards"))); + + load->set_button_icon(get_editor_theme_icon(SNAME("Load"))); + load_sheet->set_button_icon(get_editor_theme_icon(SNAME("SpriteSheet"))); + copy->set_button_icon(get_editor_theme_icon(SNAME("ActionCopy"))); + paste->set_button_icon(get_editor_theme_icon(SNAME("ActionPaste"))); + empty_before->set_button_icon(get_editor_theme_icon(SNAME("InsertBefore"))); + empty_after->set_button_icon(get_editor_theme_icon(SNAME("InsertAfter"))); + move_up->set_button_icon(get_editor_theme_icon(SNAME("MoveLeft"))); + move_down->set_button_icon(get_editor_theme_icon(SNAME("MoveRight"))); + delete_frame->set_button_icon(get_editor_theme_icon(SNAME("Remove"))); + zoom_out->set_button_icon(get_editor_theme_icon(SNAME("ZoomLess"))); + zoom_reset->set_button_icon(get_editor_theme_icon(SNAME("ZoomReset"))); + zoom_in->set_button_icon(get_editor_theme_icon(SNAME("ZoomMore"))); + add_anim->set_button_icon(get_editor_theme_icon(SNAME("New"))); + duplicate_anim->set_button_icon(get_editor_theme_icon(SNAME("Duplicate"))); + delete_anim->set_button_icon(get_editor_theme_icon(SNAME("Remove"))); anim_search_box->set_right_icon(get_editor_theme_icon(SNAME("Search"))); - split_sheet_zoom_out->set_icon(get_editor_theme_icon(SNAME("ZoomLess"))); - split_sheet_zoom_reset->set_icon(get_editor_theme_icon(SNAME("ZoomReset"))); - split_sheet_zoom_in->set_icon(get_editor_theme_icon(SNAME("ZoomMore"))); + split_sheet_zoom_out->set_button_icon(get_editor_theme_icon(SNAME("ZoomLess"))); + split_sheet_zoom_reset->set_button_icon(get_editor_theme_icon(SNAME("ZoomReset"))); + split_sheet_zoom_in->set_button_icon(get_editor_theme_icon(SNAME("ZoomMore"))); split_sheet_scroll->add_theme_style_override(SceneStringName(panel), get_theme_stylebox(SceneStringName(panel), SNAME("Tree"))); _update_show_settings(); @@ -1740,9 +1740,9 @@ void SpriteFramesEditor::_update_stop_icon() { is_playing = animated_sprite->call("is_playing"); } if (is_playing) { - stop->set_icon(pause_icon); + stop->set_button_icon(pause_icon); } else { - stop->set_icon(stop_icon); + stop->set_button_icon(stop_icon); } } diff --git a/editor/plugins/style_box_editor_plugin.cpp b/editor/plugins/style_box_editor_plugin.cpp index 0b53c10fab..2d71c617de 100644 --- a/editor/plugins/style_box_editor_plugin.cpp +++ b/editor/plugins/style_box_editor_plugin.cpp @@ -58,7 +58,7 @@ void StyleBoxPreview::_notification(int p_what) { switch (p_what) { case NOTIFICATION_THEME_CHANGED: { set_texture(get_editor_theme_icon(SNAME("Checkerboard"))); - grid_preview->set_icon(get_editor_theme_icon(SNAME("StyleBoxGrid"))); + grid_preview->set_button_icon(get_editor_theme_icon(SNAME("StyleBoxGrid"))); } break; case NOTIFICATION_DRAW: { _redraw(); diff --git a/editor/plugins/texture_region_editor_plugin.cpp b/editor/plugins/texture_region_editor_plugin.cpp index a812633480..bd653e4eed 100644 --- a/editor/plugins/texture_region_editor_plugin.cpp +++ b/editor/plugins/texture_region_editor_plugin.cpp @@ -845,9 +845,9 @@ void TextureRegionEditor::_notification(int p_what) { texture_preview->add_theme_style_override(SceneStringName(panel), get_theme_stylebox(SNAME("TextureRegionPreviewBG"), EditorStringName(EditorStyles))); texture_overlay->add_theme_style_override(SceneStringName(panel), get_theme_stylebox(SNAME("TextureRegionPreviewFG"), EditorStringName(EditorStyles))); - zoom_out->set_icon(get_editor_theme_icon(SNAME("ZoomLess"))); - zoom_reset->set_icon(get_editor_theme_icon(SNAME("ZoomReset"))); - zoom_in->set_icon(get_editor_theme_icon(SNAME("ZoomMore"))); + zoom_out->set_button_icon(get_editor_theme_icon(SNAME("ZoomLess"))); + zoom_reset->set_button_icon(get_editor_theme_icon(SNAME("ZoomReset"))); + zoom_in->set_button_icon(get_editor_theme_icon(SNAME("ZoomMore"))); } break; case NOTIFICATION_VISIBILITY_CHANGED: { @@ -1270,7 +1270,7 @@ bool EditorInspectorPluginTextureRegion::parse_property(Object *p_object, const if ((p_type == Variant::RECT2 || p_type == Variant::RECT2I)) { if (((Object::cast_to<Sprite2D>(p_object) || Object::cast_to<Sprite3D>(p_object) || Object::cast_to<NinePatchRect>(p_object) || Object::cast_to<StyleBoxTexture>(p_object)) && p_path == "region_rect") || (Object::cast_to<AtlasTexture>(p_object) && p_path == "region")) { Button *button = EditorInspector::create_inspector_action_button(TTR("Edit Region")); - button->set_icon(texture_region_editor->get_editor_theme_icon(SNAME("RegionEdit"))); + button->set_button_icon(texture_region_editor->get_editor_theme_icon(SNAME("RegionEdit"))); button->connect(SceneStringName(pressed), callable_mp(this, &EditorInspectorPluginTextureRegion::_region_edit).bind(p_object)); add_property_editor(p_path, button, true); } diff --git a/editor/plugins/theme_editor_plugin.cpp b/editor/plugins/theme_editor_plugin.cpp index cc488ff340..de75ed8c12 100644 --- a/editor/plugins/theme_editor_plugin.cpp +++ b/editor/plugins/theme_editor_plugin.cpp @@ -861,43 +861,43 @@ void ThemeItemImportTree::_notification(int p_what) { import_items_filter->set_right_icon(get_editor_theme_icon(SNAME("Search"))); // Bottom panel buttons. - import_collapse_types_button->set_icon(get_editor_theme_icon(SNAME("CollapseTree"))); - import_expand_types_button->set_icon(get_editor_theme_icon(SNAME("ExpandTree"))); + import_collapse_types_button->set_button_icon(get_editor_theme_icon(SNAME("CollapseTree"))); + import_expand_types_button->set_button_icon(get_editor_theme_icon(SNAME("ExpandTree"))); - import_select_all_button->set_icon(get_editor_theme_icon(SNAME("ThemeSelectAll"))); - import_select_full_button->set_icon(get_editor_theme_icon(SNAME("ThemeSelectFull"))); - import_deselect_all_button->set_icon(get_editor_theme_icon(SNAME("ThemeDeselectAll"))); + import_select_all_button->set_button_icon(get_editor_theme_icon(SNAME("ThemeSelectAll"))); + import_select_full_button->set_button_icon(get_editor_theme_icon(SNAME("ThemeSelectFull"))); + import_deselect_all_button->set_button_icon(get_editor_theme_icon(SNAME("ThemeDeselectAll"))); // Side panel buttons. select_colors_icon->set_texture(get_editor_theme_icon(SNAME("Color"))); - deselect_all_colors_button->set_icon(get_editor_theme_icon(SNAME("ThemeDeselectAll"))); - select_all_colors_button->set_icon(get_editor_theme_icon(SNAME("ThemeSelectAll"))); - select_full_colors_button->set_icon(get_editor_theme_icon(SNAME("ThemeSelectFull"))); + deselect_all_colors_button->set_button_icon(get_editor_theme_icon(SNAME("ThemeDeselectAll"))); + select_all_colors_button->set_button_icon(get_editor_theme_icon(SNAME("ThemeSelectAll"))); + select_full_colors_button->set_button_icon(get_editor_theme_icon(SNAME("ThemeSelectFull"))); select_constants_icon->set_texture(get_editor_theme_icon(SNAME("MemberConstant"))); - deselect_all_constants_button->set_icon(get_editor_theme_icon(SNAME("ThemeDeselectAll"))); - select_all_constants_button->set_icon(get_editor_theme_icon(SNAME("ThemeSelectAll"))); - select_full_constants_button->set_icon(get_editor_theme_icon(SNAME("ThemeSelectFull"))); + deselect_all_constants_button->set_button_icon(get_editor_theme_icon(SNAME("ThemeDeselectAll"))); + select_all_constants_button->set_button_icon(get_editor_theme_icon(SNAME("ThemeSelectAll"))); + select_full_constants_button->set_button_icon(get_editor_theme_icon(SNAME("ThemeSelectFull"))); select_fonts_icon->set_texture(get_editor_theme_icon(SNAME("FontItem"))); - deselect_all_fonts_button->set_icon(get_editor_theme_icon(SNAME("ThemeDeselectAll"))); - select_all_fonts_button->set_icon(get_editor_theme_icon(SNAME("ThemeSelectAll"))); - select_full_fonts_button->set_icon(get_editor_theme_icon(SNAME("ThemeSelectFull"))); + deselect_all_fonts_button->set_button_icon(get_editor_theme_icon(SNAME("ThemeDeselectAll"))); + select_all_fonts_button->set_button_icon(get_editor_theme_icon(SNAME("ThemeSelectAll"))); + select_full_fonts_button->set_button_icon(get_editor_theme_icon(SNAME("ThemeSelectFull"))); select_font_sizes_icon->set_texture(get_editor_theme_icon(SNAME("FontSize"))); - deselect_all_font_sizes_button->set_icon(get_editor_theme_icon(SNAME("ThemeDeselectAll"))); - select_all_font_sizes_button->set_icon(get_editor_theme_icon(SNAME("ThemeSelectAll"))); - select_full_font_sizes_button->set_icon(get_editor_theme_icon(SNAME("ThemeSelectFull"))); + deselect_all_font_sizes_button->set_button_icon(get_editor_theme_icon(SNAME("ThemeDeselectAll"))); + select_all_font_sizes_button->set_button_icon(get_editor_theme_icon(SNAME("ThemeSelectAll"))); + select_full_font_sizes_button->set_button_icon(get_editor_theme_icon(SNAME("ThemeSelectFull"))); select_icons_icon->set_texture(get_editor_theme_icon(SNAME("ImageTexture"))); - deselect_all_icons_button->set_icon(get_editor_theme_icon(SNAME("ThemeDeselectAll"))); - select_all_icons_button->set_icon(get_editor_theme_icon(SNAME("ThemeSelectAll"))); - select_full_icons_button->set_icon(get_editor_theme_icon(SNAME("ThemeSelectFull"))); + deselect_all_icons_button->set_button_icon(get_editor_theme_icon(SNAME("ThemeDeselectAll"))); + select_all_icons_button->set_button_icon(get_editor_theme_icon(SNAME("ThemeSelectAll"))); + select_full_icons_button->set_button_icon(get_editor_theme_icon(SNAME("ThemeSelectFull"))); select_styleboxes_icon->set_texture(get_editor_theme_icon(SNAME("StyleBoxFlat"))); - deselect_all_styleboxes_button->set_icon(get_editor_theme_icon(SNAME("ThemeDeselectAll"))); - select_all_styleboxes_button->set_icon(get_editor_theme_icon(SNAME("ThemeSelectAll"))); - select_full_styleboxes_button->set_icon(get_editor_theme_icon(SNAME("ThemeSelectFull"))); + deselect_all_styleboxes_button->set_button_icon(get_editor_theme_icon(SNAME("ThemeDeselectAll"))); + select_all_styleboxes_button->set_button_icon(get_editor_theme_icon(SNAME("ThemeSelectAll"))); + select_full_styleboxes_button->set_button_icon(get_editor_theme_icon(SNAME("ThemeSelectFull"))); } break; } } @@ -1877,20 +1877,20 @@ void ThemeItemEditorDialog::_notification(int p_what) { [[fallthrough]]; } case NOTIFICATION_THEME_CHANGED: { - edit_items_add_color->set_icon(get_editor_theme_icon(SNAME("Color"))); - edit_items_add_constant->set_icon(get_editor_theme_icon(SNAME("MemberConstant"))); - edit_items_add_font->set_icon(get_editor_theme_icon(SNAME("FontItem"))); - edit_items_add_font_size->set_icon(get_editor_theme_icon(SNAME("FontSize"))); - edit_items_add_icon->set_icon(get_editor_theme_icon(SNAME("ImageTexture"))); - edit_items_add_stylebox->set_icon(get_editor_theme_icon(SNAME("StyleBoxFlat"))); + edit_items_add_color->set_button_icon(get_editor_theme_icon(SNAME("Color"))); + edit_items_add_constant->set_button_icon(get_editor_theme_icon(SNAME("MemberConstant"))); + edit_items_add_font->set_button_icon(get_editor_theme_icon(SNAME("FontItem"))); + edit_items_add_font_size->set_button_icon(get_editor_theme_icon(SNAME("FontSize"))); + edit_items_add_icon->set_button_icon(get_editor_theme_icon(SNAME("ImageTexture"))); + edit_items_add_stylebox->set_button_icon(get_editor_theme_icon(SNAME("StyleBoxFlat"))); - edit_items_remove_class->set_icon(get_editor_theme_icon(SNAME("Control"))); - edit_items_remove_custom->set_icon(get_editor_theme_icon(SNAME("ThemeRemoveCustomItems"))); - edit_items_remove_all->set_icon(get_editor_theme_icon(SNAME("ThemeRemoveAllItems"))); + edit_items_remove_class->set_button_icon(get_editor_theme_icon(SNAME("Control"))); + edit_items_remove_custom->set_button_icon(get_editor_theme_icon(SNAME("ThemeRemoveCustomItems"))); + edit_items_remove_all->set_button_icon(get_editor_theme_icon(SNAME("ThemeRemoveAllItems"))); - edit_add_type_button->set_icon(get_editor_theme_icon(SNAME("Add"))); + edit_add_type_button->set_button_icon(get_editor_theme_icon(SNAME("Add"))); - import_another_theme_button->set_icon(get_editor_theme_icon(SNAME("Folder"))); + import_another_theme_button->set_button_icon(get_editor_theme_icon(SNAME("Folder"))); } break; } } @@ -2481,21 +2481,21 @@ HBoxContainer *ThemeTypeEditor::_create_property_control(Theme::DataType p_data_ item_name_edit->hide(); Button *item_rename_button = memnew(Button); - item_rename_button->set_icon(get_editor_theme_icon(SNAME("Edit"))); + item_rename_button->set_button_icon(get_editor_theme_icon(SNAME("Edit"))); item_rename_button->set_tooltip_text(TTR("Rename Item")); item_rename_button->set_flat(true); item_name_container->add_child(item_rename_button); item_rename_button->connect(SceneStringName(pressed), callable_mp(this, &ThemeTypeEditor::_item_rename_cbk).bind(p_data_type, p_item_name, item_name_container)); Button *item_remove_button = memnew(Button); - item_remove_button->set_icon(get_editor_theme_icon(SNAME("Remove"))); + item_remove_button->set_button_icon(get_editor_theme_icon(SNAME("Remove"))); item_remove_button->set_tooltip_text(TTR("Remove Item")); item_remove_button->set_flat(true); item_name_container->add_child(item_remove_button); item_remove_button->connect(SceneStringName(pressed), callable_mp(this, &ThemeTypeEditor::_item_remove_cbk).bind(p_data_type, p_item_name)); Button *item_rename_confirm_button = memnew(Button); - item_rename_confirm_button->set_icon(get_editor_theme_icon(SNAME("ImportCheck"))); + item_rename_confirm_button->set_button_icon(get_editor_theme_icon(SNAME("ImportCheck"))); item_rename_confirm_button->set_tooltip_text(TTR("Confirm Item Rename")); item_rename_confirm_button->set_flat(true); item_name_container->add_child(item_rename_confirm_button); @@ -2503,7 +2503,7 @@ HBoxContainer *ThemeTypeEditor::_create_property_control(Theme::DataType p_data_ item_rename_confirm_button->hide(); Button *item_rename_cancel_button = memnew(Button); - item_rename_cancel_button->set_icon(get_editor_theme_icon(SNAME("ImportFail"))); + item_rename_cancel_button->set_button_icon(get_editor_theme_icon(SNAME("ImportFail"))); item_rename_cancel_button->set_tooltip_text(TTR("Cancel Item Rename")); item_rename_cancel_button->set_flat(true); item_name_container->add_child(item_rename_cancel_button); @@ -2513,7 +2513,7 @@ HBoxContainer *ThemeTypeEditor::_create_property_control(Theme::DataType p_data_ item_name->add_theme_color_override(SceneStringName(font_color), get_theme_color(SNAME("font_disabled_color"), EditorStringName(Editor))); Button *item_override_button = memnew(Button); - item_override_button->set_icon(get_editor_theme_icon(SNAME("Add"))); + item_override_button->set_button_icon(get_editor_theme_icon(SNAME("Add"))); item_override_button->set_tooltip_text(TTR("Override Item")); item_override_button->set_flat(true); item_name_container->add_child(item_override_button); @@ -2722,7 +2722,7 @@ void ThemeTypeEditor::_update_type_items() { pin_leader_button->set_flat(true); pin_leader_button->set_toggle_mode(true); pin_leader_button->set_pressed(true); - pin_leader_button->set_icon(get_editor_theme_icon(SNAME("Pin"))); + pin_leader_button->set_button_icon(get_editor_theme_icon(SNAME("Pin"))); pin_leader_button->set_tooltip_text(TTR("Unpin this StyleBox as a main style.")); item_control->add_child(pin_leader_button); pin_leader_button->connect(SceneStringName(pressed), callable_mp(this, &ThemeTypeEditor::_on_unpin_leader_button_pressed)); @@ -2765,7 +2765,7 @@ void ThemeTypeEditor::_update_type_items() { Button *pin_leader_button = memnew(Button); pin_leader_button->set_flat(true); pin_leader_button->set_toggle_mode(true); - pin_leader_button->set_icon(get_editor_theme_icon(SNAME("Pin"))); + pin_leader_button->set_button_icon(get_editor_theme_icon(SNAME("Pin"))); pin_leader_button->set_tooltip_text(TTR("Pin this StyleBox as a main style. Editing its properties will update the same properties in all other StyleBoxes of this type.")); item_control->add_child(pin_leader_button); pin_leader_button->connect(SceneStringName(pressed), callable_mp(this, &ThemeTypeEditor::_on_pin_leader_button_pressed).bind(item_editor, E.key)); @@ -3371,7 +3371,7 @@ void ThemeTypeEditor::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: case NOTIFICATION_THEME_CHANGED: { - add_type_button->set_icon(get_editor_theme_icon(SNAME("Add"))); + add_type_button->set_button_icon(get_editor_theme_icon(SNAME("Add"))); data_type_tabs->set_tab_icon(0, get_editor_theme_icon(SNAME("Color"))); data_type_tabs->set_tab_icon(1, get_editor_theme_icon(SNAME("MemberConstant"))); @@ -3381,7 +3381,7 @@ void ThemeTypeEditor::_notification(int p_what) { data_type_tabs->set_tab_icon(5, get_editor_theme_icon(SNAME("StyleBoxFlat"))); data_type_tabs->set_tab_icon(6, get_editor_theme_icon(SNAME("Tools"))); - type_variation_button->set_icon(get_editor_theme_icon(SNAME("Add"))); + type_variation_button->set_button_icon(get_editor_theme_icon(SNAME("Add"))); } break; } } @@ -3695,7 +3695,7 @@ void ThemeEditor::_notification(int p_what) { preview_tabs->add_theme_style_override("tab_unselected", get_theme_stylebox(SNAME("ThemeEditorPreviewBG"), EditorStringName(EditorStyles))); preview_tabs_content->add_theme_style_override(SceneStringName(panel), get_theme_stylebox(SceneStringName(panel), SNAME("TabContainerOdd"))); - add_preview_button->set_icon(get_editor_theme_icon(SNAME("Add"))); + add_preview_button->set_button_icon(get_editor_theme_icon(SNAME("Add"))); } break; } } diff --git a/editor/plugins/theme_editor_preview.cpp b/editor/plugins/theme_editor_preview.cpp index 2426cec521..ea5e8a8ad7 100644 --- a/editor/plugins/theme_editor_preview.cpp +++ b/editor/plugins/theme_editor_preview.cpp @@ -211,7 +211,7 @@ void ThemeEditorPreview::_notification(int p_what) { } break; case NOTIFICATION_THEME_CHANGED: { - picker_button->set_icon(get_editor_theme_icon(SNAME("ColorPick"))); + picker_button->set_button_icon(get_editor_theme_icon(SNAME("ColorPick"))); theme_cache.preview_picker_overlay = get_theme_stylebox(SNAME("preview_picker_overlay"), SNAME("ThemeEditor")); theme_cache.preview_picker_overlay_color = get_theme_color(SNAME("preview_picker_overlay_color"), SNAME("ThemeEditor")); @@ -489,7 +489,7 @@ void SceneThemeEditorPreview::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: case NOTIFICATION_THEME_CHANGED: { - reload_scene_button->set_icon(get_editor_theme_icon(SNAME("Reload"))); + reload_scene_button->set_button_icon(get_editor_theme_icon(SNAME("Reload"))); } break; } } diff --git a/editor/plugins/tiles/tile_atlas_view.cpp b/editor/plugins/tiles/tile_atlas_view.cpp index b806d1e042..bafacf8e36 100644 --- a/editor/plugins/tiles/tile_atlas_view.cpp +++ b/editor/plugins/tiles/tile_atlas_view.cpp @@ -496,13 +496,13 @@ void TileAtlasView::set_atlas_source(TileSet *p_tile_set, TileSetAtlasSource *p_ float TileAtlasView::get_zoom() const { return zoom_widget->get_zoom(); -}; +} void TileAtlasView::set_transform(float p_zoom, Vector2i p_panning) { zoom_widget->set_zoom(p_zoom); panning = p_panning; _update_zoom_and_panning(); -}; +} void TileAtlasView::set_padding(Side p_side, int p_padding) { ERR_FAIL_COND(p_padding < 0); @@ -618,7 +618,7 @@ void TileAtlasView::_notification(int p_what) { } break; case NOTIFICATION_THEME_CHANGED: { - button_center_view->set_icon(theme_cache.center_view_icon); + button_center_view->set_button_icon(theme_cache.center_view_icon); } break; } } diff --git a/editor/plugins/tiles/tile_atlas_view.h b/editor/plugins/tiles/tile_atlas_view.h index 8fcf942056..025df4fda0 100644 --- a/editor/plugins/tiles/tile_atlas_view.h +++ b/editor/plugins/tiles/tile_atlas_view.h @@ -135,8 +135,8 @@ public: void set_padding(Side p_side, int p_padding); // Left side. - void set_texture_grid_visible(bool p_visible) { base_tiles_texture_grid->set_visible(p_visible); }; - void set_tile_shape_grid_visible(bool p_visible) { base_tiles_shape_grid->set_visible(p_visible); }; + void set_texture_grid_visible(bool p_visible) { base_tiles_texture_grid->set_visible(p_visible); } + void set_tile_shape_grid_visible(bool p_visible) { base_tiles_shape_grid->set_visible(p_visible); } Vector2i get_atlas_tile_coords_at_pos(const Vector2 p_pos, bool p_clamp = false) const; @@ -148,7 +148,7 @@ public: } p_control->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT); p_control->set_mouse_filter(Control::MOUSE_FILTER_PASS); - }; + } // Right side. Vector3i get_alternative_tile_at_pos(const Vector2 p_pos) const; @@ -162,7 +162,7 @@ public: } p_control->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT); p_control->set_mouse_filter(Control::MOUSE_FILTER_PASS); - }; + } // Redraw everything. void queue_redraw(); diff --git a/editor/plugins/tiles/tile_data_editors.cpp b/editor/plugins/tiles/tile_data_editors.cpp index c6921699a4..bf53a9dfba 100644 --- a/editor/plugins/tiles/tile_data_editors.cpp +++ b/editor/plugins/tiles/tile_data_editors.cpp @@ -722,7 +722,7 @@ void GenericTilePolygonEditor::_base_control_gui_input(Ref<InputEvent> p_event) void GenericTilePolygonEditor::_set_snap_option(int p_index) { current_snap_option = p_index; - button_pixel_snap->set_icon(button_pixel_snap->get_popup()->get_item_icon(p_index)); + button_pixel_snap->set_button_icon(button_pixel_snap->get_popup()->get_item_icon(p_index)); snap_subdivision->set_visible(p_index == SNAP_GRID); if (initializing) { @@ -880,16 +880,16 @@ void GenericTilePolygonEditor::_notification(int p_what) { } break; case NOTIFICATION_THEME_CHANGED: { - button_expand->set_icon(get_editor_theme_icon(SNAME("DistractionFree"))); - button_create->set_icon(get_editor_theme_icon(SNAME("CurveCreate"))); - button_edit->set_icon(get_editor_theme_icon(SNAME("CurveEdit"))); - button_delete->set_icon(get_editor_theme_icon(SNAME("CurveDelete"))); - button_center_view->set_icon(get_editor_theme_icon(SNAME("CenterView"))); - button_advanced_menu->set_icon(get_editor_theme_icon(SNAME("GuiTabMenuHl"))); + button_expand->set_button_icon(get_editor_theme_icon(SNAME("DistractionFree"))); + button_create->set_button_icon(get_editor_theme_icon(SNAME("CurveCreate"))); + button_edit->set_button_icon(get_editor_theme_icon(SNAME("CurveEdit"))); + button_delete->set_button_icon(get_editor_theme_icon(SNAME("CurveDelete"))); + button_center_view->set_button_icon(get_editor_theme_icon(SNAME("CenterView"))); + button_advanced_menu->set_button_icon(get_editor_theme_icon(SNAME("GuiTabMenuHl"))); button_pixel_snap->get_popup()->set_item_icon(0, get_editor_theme_icon(SNAME("SnapDisable"))); button_pixel_snap->get_popup()->set_item_icon(1, get_editor_theme_icon(SNAME("Snap"))); button_pixel_snap->get_popup()->set_item_icon(2, get_editor_theme_icon(SNAME("SnapGrid"))); - button_pixel_snap->set_icon(button_pixel_snap->get_popup()->get_item_icon(current_snap_option)); + button_pixel_snap->set_button_icon(button_pixel_snap->get_popup()->get_item_icon(current_snap_option)); PopupMenu *p = button_advanced_menu->get_popup(); p->set_item_icon(p->get_item_index(ROTATE_RIGHT), get_editor_theme_icon(SNAME("RotateRight"))); @@ -1100,11 +1100,10 @@ void TileDataDefaultEditor::forward_draw_over_atlas(TileAtlasView *p_tile_atlas_ } p_canvas_item->draw_set_transform_matrix(Transform2D()); } -}; +} void TileDataDefaultEditor::forward_draw_over_alternatives(TileAtlasView *p_tile_atlas_view, TileSetAtlasSource *p_tile_set_atlas_source, CanvasItem *p_canvas_item, Transform2D p_transform) { - -}; +} void TileDataDefaultEditor::forward_painting_atlas_gui_input(TileAtlasView *p_tile_atlas_view, TileSetAtlasSource *p_tile_set_atlas_source, const Ref<InputEvent> &p_event) { Ref<InputEventMouseMotion> mm = p_event; @@ -1362,7 +1361,7 @@ void TileDataDefaultEditor::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: case NOTIFICATION_THEME_CHANGED: { - picker_button->set_icon(get_editor_theme_icon(SNAME("ColorPick"))); + picker_button->set_button_icon(get_editor_theme_icon(SNAME("ColorPick"))); tile_bool_checked = get_editor_theme_icon(SNAME("TileChecked")); tile_bool_unchecked = get_editor_theme_icon(SNAME("TileUnchecked")); } break; @@ -2868,7 +2867,7 @@ void TileDataTerrainsEditor::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: case NOTIFICATION_THEME_CHANGED: { - picker_button->set_icon(get_editor_theme_icon(SNAME("ColorPick"))); + picker_button->set_button_icon(get_editor_theme_icon(SNAME("ColorPick"))); } break; } } diff --git a/editor/plugins/tiles/tile_data_editors.h b/editor/plugins/tiles/tile_data_editors.h index 1426bb4c2f..312eb724ed 100644 --- a/editor/plugins/tiles/tile_data_editors.h +++ b/editor/plugins/tiles/tile_data_editors.h @@ -62,7 +62,7 @@ public: void set_tile_set(Ref<TileSet> p_tile_set); // Input to handle painting. - virtual Control *get_toolbar() { return nullptr; }; + virtual Control *get_toolbar() { return nullptr; } virtual void forward_draw_over_atlas(TileAtlasView *p_tile_atlas_view, TileSetAtlasSource *p_tile_atlas_source, CanvasItem *p_canvas_item, Transform2D p_transform) {} virtual void forward_draw_over_alternatives(TileAtlasView *p_tile_atlas_view, TileSetAtlasSource *p_tile_atlas_source, CanvasItem *p_canvas_item, Transform2D p_transform) {} virtual void forward_painting_atlas_gui_input(TileAtlasView *p_tile_atlas_view, TileSetAtlasSource *p_tile_atlas_source, const Ref<InputEvent> &p_event) {} @@ -238,7 +238,7 @@ protected: virtual void _setup_undo_redo_action(TileSetAtlasSource *p_tile_set_atlas_source, const HashMap<TileMapCell, Variant, TileMapCell> &p_previous_values, const Variant &p_new_value); public: - virtual Control *get_toolbar() override { return toolbar; }; + virtual Control *get_toolbar() override { return toolbar; } virtual void forward_draw_over_atlas(TileAtlasView *p_tile_atlas_view, TileSetAtlasSource *p_tile_atlas_source, CanvasItem *p_canvas_item, Transform2D p_transform) override; virtual void forward_draw_over_alternatives(TileAtlasView *p_tile_atlas_view, TileSetAtlasSource *p_tile_atlas_source, CanvasItem *p_canvas_item, Transform2D p_transform) override; virtual void forward_painting_atlas_gui_input(TileAtlasView *p_tile_atlas_view, TileSetAtlasSource *p_tile_atlas_source, const Ref<InputEvent> &p_event) override; @@ -375,7 +375,7 @@ protected: void _notification(int p_what); public: - virtual Control *get_toolbar() override { return toolbar; }; + virtual Control *get_toolbar() override { return toolbar; } virtual void forward_draw_over_atlas(TileAtlasView *p_tile_atlas_view, TileSetAtlasSource *p_tile_atlas_source, CanvasItem *p_canvas_item, Transform2D p_transform) override; virtual void forward_draw_over_alternatives(TileAtlasView *p_tile_atlas_view, TileSetAtlasSource *p_tile_atlas_source, CanvasItem *p_canvas_item, Transform2D p_transform) override; virtual void forward_painting_atlas_gui_input(TileAtlasView *p_tile_atlas_view, TileSetAtlasSource *p_tile_atlas_source, const Ref<InputEvent> &p_event) override; diff --git a/editor/plugins/tiles/tile_map_layer_editor.cpp b/editor/plugins/tiles/tile_map_layer_editor.cpp index dcfd92f6f9..16d4ee6f68 100644 --- a/editor/plugins/tiles/tile_map_layer_editor.cpp +++ b/editor/plugins/tiles/tile_map_layer_editor.cpp @@ -503,21 +503,21 @@ void TileMapLayerEditorTilesPlugin::_scenes_list_lmb_empty_clicked(const Vector2 } void TileMapLayerEditorTilesPlugin::_update_theme() { - source_sort_button->set_icon(tiles_bottom_panel->get_editor_theme_icon(SNAME("Sort"))); - select_tool_button->set_icon(tiles_bottom_panel->get_editor_theme_icon(SNAME("ToolSelect"))); - paint_tool_button->set_icon(tiles_bottom_panel->get_editor_theme_icon(SNAME("Edit"))); - line_tool_button->set_icon(tiles_bottom_panel->get_editor_theme_icon(SNAME("Line"))); - rect_tool_button->set_icon(tiles_bottom_panel->get_editor_theme_icon(SNAME("Rectangle"))); - bucket_tool_button->set_icon(tiles_bottom_panel->get_editor_theme_icon(SNAME("Bucket"))); - - picker_button->set_icon(tiles_bottom_panel->get_editor_theme_icon(SNAME("ColorPick"))); - erase_button->set_icon(tiles_bottom_panel->get_editor_theme_icon(SNAME("Eraser"))); - random_tile_toggle->set_icon(tiles_bottom_panel->get_editor_theme_icon(SNAME("RandomNumberGenerator"))); - - transform_button_rotate_left->set_icon(tiles_bottom_panel->get_editor_theme_icon("RotateLeft")); - transform_button_rotate_right->set_icon(tiles_bottom_panel->get_editor_theme_icon("RotateRight")); - transform_button_flip_h->set_icon(tiles_bottom_panel->get_editor_theme_icon("MirrorX")); - transform_button_flip_v->set_icon(tiles_bottom_panel->get_editor_theme_icon("MirrorY")); + source_sort_button->set_button_icon(tiles_bottom_panel->get_editor_theme_icon(SNAME("Sort"))); + select_tool_button->set_button_icon(tiles_bottom_panel->get_editor_theme_icon(SNAME("ToolSelect"))); + paint_tool_button->set_button_icon(tiles_bottom_panel->get_editor_theme_icon(SNAME("Edit"))); + line_tool_button->set_button_icon(tiles_bottom_panel->get_editor_theme_icon(SNAME("Line"))); + rect_tool_button->set_button_icon(tiles_bottom_panel->get_editor_theme_icon(SNAME("Rectangle"))); + bucket_tool_button->set_button_icon(tiles_bottom_panel->get_editor_theme_icon(SNAME("Bucket"))); + + picker_button->set_button_icon(tiles_bottom_panel->get_editor_theme_icon(SNAME("ColorPick"))); + erase_button->set_button_icon(tiles_bottom_panel->get_editor_theme_icon(SNAME("Eraser"))); + random_tile_toggle->set_button_icon(tiles_bottom_panel->get_editor_theme_icon(SNAME("RandomNumberGenerator"))); + + transform_button_rotate_left->set_button_icon(tiles_bottom_panel->get_editor_theme_icon("RotateLeft")); + transform_button_rotate_right->set_button_icon(tiles_bottom_panel->get_editor_theme_icon("RotateRight")); + transform_button_flip_h->set_button_icon(tiles_bottom_panel->get_editor_theme_icon("MirrorX")); + transform_button_flip_v->set_button_icon(tiles_bottom_panel->get_editor_theme_icon("MirrorY")); missing_atlas_texture_icon = tiles_bottom_panel->get_editor_theme_icon(SNAME("TileSet")); _update_tile_set_sources_list(); @@ -1550,6 +1550,7 @@ int TileMapLayerEditorTilesPlugin::_get_transformed_alternative(int p_alternativ case TRANSFORM_ROTATE_RIGHT: { // A matrix with every possible flip/transpose combination, sorted by what comes next when you rotate. const LocalVector<bool> rotation_matrix = { + // NOLINTBEGIN(modernize-use-bool-literals) 0, 0, 0, 0, 1, 1, 1, 1, 0, @@ -1558,6 +1559,7 @@ int TileMapLayerEditorTilesPlugin::_get_transformed_alternative(int p_alternativ 0, 0, 1, 0, 1, 0, 1, 1, 1 + // NOLINTEND(modernize-use-bool-literals) }; for (int i = 0; i < 8; i++) { @@ -3486,13 +3488,13 @@ void TileMapLayerEditorTerrainsPlugin::_update_tiles_list() { } void TileMapLayerEditorTerrainsPlugin::_update_theme() { - paint_tool_button->set_icon(main_vbox_container->get_editor_theme_icon(SNAME("Edit"))); - line_tool_button->set_icon(main_vbox_container->get_editor_theme_icon(SNAME("Line"))); - rect_tool_button->set_icon(main_vbox_container->get_editor_theme_icon(SNAME("Rectangle"))); - bucket_tool_button->set_icon(main_vbox_container->get_editor_theme_icon(SNAME("Bucket"))); + paint_tool_button->set_button_icon(main_vbox_container->get_editor_theme_icon(SNAME("Edit"))); + line_tool_button->set_button_icon(main_vbox_container->get_editor_theme_icon(SNAME("Line"))); + rect_tool_button->set_button_icon(main_vbox_container->get_editor_theme_icon(SNAME("Rectangle"))); + bucket_tool_button->set_button_icon(main_vbox_container->get_editor_theme_icon(SNAME("Bucket"))); - picker_button->set_icon(main_vbox_container->get_editor_theme_icon(SNAME("ColorPick"))); - erase_button->set_icon(main_vbox_container->get_editor_theme_icon(SNAME("Eraser"))); + picker_button->set_button_icon(main_vbox_container->get_editor_theme_icon(SNAME("ColorPick"))); + erase_button->set_button_icon(main_vbox_container->get_editor_theme_icon(SNAME("Eraser"))); _update_tiles_list(); } @@ -3689,12 +3691,12 @@ void TileMapLayerEditor::_notification(int p_what) { case NOTIFICATION_THEME_CHANGED: { missing_tile_texture = get_editor_theme_icon(SNAME("StatusWarning")); warning_pattern_texture = get_editor_theme_icon(SNAME("WarningPattern")); - advanced_menu_button->set_icon(get_editor_theme_icon(SNAME("Tools"))); - select_previous_layer->set_icon(get_editor_theme_icon(SNAME("MoveUp"))); - select_next_layer->set_icon(get_editor_theme_icon(SNAME("MoveDown"))); - select_all_layers->set_icon(get_editor_theme_icon(SNAME("FileList"))); - toggle_grid_button->set_icon(get_editor_theme_icon(SNAME("Grid"))); - toggle_highlight_selected_layer_button->set_icon(get_editor_theme_icon(SNAME("TileMapHighlightSelected"))); + advanced_menu_button->set_button_icon(get_editor_theme_icon(SNAME("Tools"))); + select_previous_layer->set_button_icon(get_editor_theme_icon(SNAME("MoveUp"))); + select_next_layer->set_button_icon(get_editor_theme_icon(SNAME("MoveDown"))); + select_all_layers->set_button_icon(get_editor_theme_icon(SNAME("FileList"))); + toggle_grid_button->set_button_icon(get_editor_theme_icon(SNAME("Grid"))); + toggle_highlight_selected_layer_button->set_button_icon(get_editor_theme_icon(SNAME("TileMapHighlightSelected"))); } break; case NOTIFICATION_INTERNAL_PROCESS: { diff --git a/editor/plugins/tiles/tile_map_layer_editor.h b/editor/plugins/tiles/tile_map_layer_editor.h index 805af7b58e..bcba34299d 100644 --- a/editor/plugins/tiles/tile_map_layer_editor.h +++ b/editor/plugins/tiles/tile_map_layer_editor.h @@ -63,9 +63,9 @@ public: virtual Vector<TabData> get_tabs() const { return Vector<TabData>(); - }; + } - virtual bool forward_canvas_gui_input(const Ref<InputEvent> &p_event) { return false; }; + virtual bool forward_canvas_gui_input(const Ref<InputEvent> &p_event) { return false; } virtual void forward_canvas_draw_over_viewport(Control *p_overlay) {} virtual void tile_set_changed() {} virtual void edit(ObjectID p_tile_map_layer_id) {} diff --git a/editor/plugins/tiles/tile_set_atlas_source_editor.cpp b/editor/plugins/tiles/tile_set_atlas_source_editor.cpp index b1417b2878..941d44c85e 100644 --- a/editor/plugins/tiles/tile_set_atlas_source_editor.cpp +++ b/editor/plugins/tiles/tile_set_atlas_source_editor.cpp @@ -996,7 +996,7 @@ void TileSetAtlasSourceEditor::_update_atlas_view() { // Create and position the button. Button *button = memnew(Button); button->set_flat(true); - button->set_icon(get_editor_theme_icon(SNAME("Add"))); + button->set_button_icon(get_editor_theme_icon(SNAME("Add"))); button->add_theme_style_override(CoreStringName(normal), memnew(StyleBoxEmpty)); button->add_theme_style_override("hover", memnew(StyleBoxEmpty)); button->add_theme_style_override("focus", memnew(StyleBoxEmpty)); @@ -1699,7 +1699,7 @@ void TileSetAtlasSourceEditor::_menu_option(int p_option) { void TileSetAtlasSourceEditor::shortcut_input(const Ref<InputEvent> &p_event) { // Check for shortcuts. - if (ED_IS_SHORTCUT("tiles_editor/delete_tile", p_event)) { + if (ED_IS_SHORTCUT("tiles_editor/delete", p_event)) { if (tools_button_group->get_pressed_button() == tool_select_button && !selection.is_empty()) { _menu_option(TILE_DELETE); accept_event(); @@ -2441,12 +2441,12 @@ void TileSetAtlasSourceEditor::_notification(int p_what) { } break; case NOTIFICATION_THEME_CHANGED: { - tool_setup_atlas_source_button->set_icon(get_editor_theme_icon(SNAME("Tools"))); - tool_select_button->set_icon(get_editor_theme_icon(SNAME("ToolSelect"))); - tool_paint_button->set_icon(get_editor_theme_icon(SNAME("Paint"))); + tool_setup_atlas_source_button->set_button_icon(get_editor_theme_icon(SNAME("Tools"))); + tool_select_button->set_button_icon(get_editor_theme_icon(SNAME("ToolSelect"))); + tool_paint_button->set_button_icon(get_editor_theme_icon(SNAME("Paint"))); - tools_settings_erase_button->set_icon(get_editor_theme_icon(SNAME("Eraser"))); - tool_advanced_menu_button->set_icon(get_editor_theme_icon(SNAME("GuiTabMenuHl"))); + tools_settings_erase_button->set_button_icon(get_editor_theme_icon(SNAME("Eraser"))); + tool_advanced_menu_button->set_button_icon(get_editor_theme_icon(SNAME("GuiTabMenuHl"))); outside_tiles_warning->set_texture(get_editor_theme_icon(SNAME("StatusWarning"))); resize_handle = get_editor_theme_icon(SNAME("EditorHandle")); @@ -2711,7 +2711,7 @@ TileSetAtlasSourceEditor::TileSetAtlasSourceEditor() { tile_atlas_control_unscaled->set_mouse_filter(Control::MOUSE_FILTER_IGNORE); alternative_tile_popup_menu = memnew(PopupMenu); - alternative_tile_popup_menu->add_shortcut(ED_SHORTCUT("tiles_editor/delete_tile", TTR("Delete"), Key::KEY_DELETE), TILE_DELETE); + alternative_tile_popup_menu->add_shortcut(ED_GET_SHORTCUT("tiles_editor/delete"), TILE_DELETE); alternative_tile_popup_menu->connect(SceneStringName(id_pressed), callable_mp(this, &TileSetAtlasSourceEditor::_menu_option)); tile_atlas_view->add_child(alternative_tile_popup_menu); diff --git a/editor/plugins/tiles/tile_set_atlas_source_editor.h b/editor/plugins/tiles/tile_set_atlas_source_editor.h index c1a8338f81..f8b65bd675 100644 --- a/editor/plugins/tiles/tile_set_atlas_source_editor.h +++ b/editor/plugins/tiles/tile_set_atlas_source_editor.h @@ -80,7 +80,7 @@ public: int get_id() const; void edit(Ref<TileSet> p_tile_set, Ref<TileSetAtlasSource> p_tile_set_atlas_source, int p_source_id); - Ref<TileSetAtlasSource> get_edited() { return tile_set_atlas_source; }; + Ref<TileSetAtlasSource> get_edited() { return tile_set_atlas_source; } }; // -- Proxy object for a tile, needed by the inspector -- @@ -91,7 +91,7 @@ public: TileSetAtlasSourceEditor *tiles_set_atlas_source_editor = nullptr; Ref<TileSetAtlasSource> tile_set_atlas_source; - RBSet<TileSelection> tiles = RBSet<TileSelection>(); + RBSet<TileSelection> tiles; protected: bool _set(const StringName &p_name, const Variant &p_value); @@ -101,8 +101,8 @@ public: static void _bind_methods(); public: - Ref<TileSetAtlasSource> get_edited_tile_set_atlas_source() const { return tile_set_atlas_source; }; - RBSet<TileSelection> get_edited_tiles() const { return tiles; }; + Ref<TileSetAtlasSource> get_edited_tile_set_atlas_source() const { return tile_set_atlas_source; } + RBSet<TileSelection> get_edited_tiles() const { return tiles; } // Update the proxyed object. void edit(Ref<TileSetAtlasSource> p_tile_set_atlas_source, const RBSet<TileSelection> &p_tiles = RBSet<TileSelection>()); diff --git a/editor/plugins/tiles/tile_set_editor.cpp b/editor/plugins/tiles/tile_set_editor.cpp index 7e5336ce06..6f473d1b60 100644 --- a/editor/plugins/tiles/tile_set_editor.cpp +++ b/editor/plugins/tiles/tile_set_editor.cpp @@ -366,10 +366,10 @@ void TileSetEditor::_set_source_sort(int p_sort) { void TileSetEditor::_notification(int p_what) { switch (p_what) { case NOTIFICATION_THEME_CHANGED: { - sources_delete_button->set_icon(get_editor_theme_icon(SNAME("Remove"))); - sources_add_button->set_icon(get_editor_theme_icon(SNAME("Add"))); - source_sort_button->set_icon(get_editor_theme_icon(SNAME("Sort"))); - sources_advanced_menu_button->set_icon(get_editor_theme_icon(SNAME("GuiTabMenuHl"))); + sources_delete_button->set_button_icon(get_editor_theme_icon(SNAME("Remove"))); + sources_add_button->set_button_icon(get_editor_theme_icon(SNAME("Add"))); + source_sort_button->set_button_icon(get_editor_theme_icon(SNAME("Sort"))); + sources_advanced_menu_button->set_button_icon(get_editor_theme_icon(SNAME("GuiTabMenuHl"))); missing_texture_texture = get_editor_theme_icon(SNAME("TileSet")); expanded_area->add_theme_style_override(SceneStringName(panel), get_theme_stylebox(SceneStringName(panel), "Tree")); _update_sources_list(); diff --git a/editor/plugins/tiles/tile_set_scenes_collection_source_editor.cpp b/editor/plugins/tiles/tile_set_scenes_collection_source_editor.cpp index 305407efdb..e2b3c451b0 100644 --- a/editor/plugins/tiles/tile_set_scenes_collection_source_editor.cpp +++ b/editor/plugins/tiles/tile_set_scenes_collection_source_editor.cpp @@ -367,8 +367,8 @@ void TileSetScenesCollectionSourceEditor::_notification(int p_what) { } break; case NOTIFICATION_THEME_CHANGED: { - scene_tile_add_button->set_icon(get_editor_theme_icon(SNAME("Add"))); - scene_tile_delete_button->set_icon(get_editor_theme_icon(SNAME("Remove"))); + scene_tile_add_button->set_button_icon(get_editor_theme_icon(SNAME("Add"))); + scene_tile_delete_button->set_button_icon(get_editor_theme_icon(SNAME("Remove"))); _update_scenes_list(); } break; diff --git a/editor/plugins/tool_button_editor_plugin.cpp b/editor/plugins/tool_button_editor_plugin.cpp index d9852c8694..d9a15d9a23 100644 --- a/editor/plugins/tool_button_editor_plugin.cpp +++ b/editor/plugins/tool_button_editor_plugin.cpp @@ -33,7 +33,7 @@ #include "scene/gui/button.h" void EditorInspectorToolButtonPlugin::_update_action_icon(Button *p_action_button, const String &p_action_icon) { - p_action_button->set_icon(p_action_button->get_editor_theme_icon(p_action_icon)); + p_action_button->set_button_icon(p_action_button->get_editor_theme_icon(p_action_icon)); } void EditorInspectorToolButtonPlugin::_call_action(const Variant &p_object, const StringName &p_property) { diff --git a/editor/plugins/version_control_editor_plugin.cpp b/editor/plugins/version_control_editor_plugin.cpp index 4f0df1d5fc..815664c608 100644 --- a/editor/plugins/version_control_editor_plugin.cpp +++ b/editor/plugins/version_control_editor_plugin.cpp @@ -1081,7 +1081,7 @@ VersionControlEditorPlugin::VersionControlEditorPlugin() { set_up_ssh_public_key_input_hbc->add_child(set_up_ssh_public_key_file_dialog); Button *select_public_path_button = memnew(Button); - select_public_path_button->set_icon(EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon("Folder")); + select_public_path_button->set_button_icon(EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon("Folder")); select_public_path_button->connect(SceneStringName(pressed), callable_mp(this, &VersionControlEditorPlugin::_popup_file_dialog).bind(set_up_ssh_public_key_file_dialog)); select_public_path_button->set_tooltip_text(TTR("Select SSH public key path")); set_up_ssh_public_key_input_hbc->add_child(select_public_path_button); @@ -1114,7 +1114,7 @@ VersionControlEditorPlugin::VersionControlEditorPlugin() { set_up_ssh_private_key_input_hbc->add_child(set_up_ssh_private_key_file_dialog); Button *select_private_path_button = memnew(Button); - select_private_path_button->set_icon(EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon("Folder")); + select_private_path_button->set_button_icon(EditorNode::get_singleton()->get_gui_base()->get_editor_theme_icon("Folder")); select_private_path_button->connect(SceneStringName(pressed), callable_mp(this, &VersionControlEditorPlugin::_popup_file_dialog).bind(set_up_ssh_private_key_file_dialog)); select_private_path_button->set_tooltip_text(TTR("Select SSH private key path")); set_up_ssh_private_key_input_hbc->add_child(select_private_path_button); @@ -1159,7 +1159,7 @@ VersionControlEditorPlugin::VersionControlEditorPlugin() { refresh_button = memnew(Button); refresh_button->set_tooltip_text(TTR("Detect new changes")); refresh_button->set_theme_type_variation("FlatButton"); - refresh_button->set_icon(EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("Reload"), EditorStringName(EditorIcons))); + refresh_button->set_button_icon(EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("Reload"), EditorStringName(EditorIcons))); refresh_button->connect(SceneStringName(pressed), callable_mp(this, &VersionControlEditorPlugin::_refresh_stage_area)); refresh_button->connect(SceneStringName(pressed), callable_mp(this, &VersionControlEditorPlugin::_refresh_commit_list)); refresh_button->connect(SceneStringName(pressed), callable_mp(this, &VersionControlEditorPlugin::_refresh_branch_list)); @@ -1179,14 +1179,14 @@ VersionControlEditorPlugin::VersionControlEditorPlugin() { discard_all_button = memnew(Button); discard_all_button->set_tooltip_text(TTR("Discard all changes")); - discard_all_button->set_icon(EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("Close"), EditorStringName(EditorIcons))); + discard_all_button->set_button_icon(EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("Close"), EditorStringName(EditorIcons))); discard_all_button->connect(SceneStringName(pressed), callable_mp(this, &VersionControlEditorPlugin::_confirm_discard_all)); discard_all_button->set_theme_type_variation("FlatButton"); unstage_title->add_child(discard_all_button); stage_all_button = memnew(Button); stage_all_button->set_theme_type_variation("FlatButton"); - stage_all_button->set_icon(EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("MoveDown"), EditorStringName(EditorIcons))); + stage_all_button->set_button_icon(EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("MoveDown"), EditorStringName(EditorIcons))); stage_all_button->set_tooltip_text(TTR("Stage all changes")); unstage_title->add_child(stage_all_button); @@ -1216,7 +1216,7 @@ VersionControlEditorPlugin::VersionControlEditorPlugin() { unstage_all_button = memnew(Button); unstage_all_button->set_theme_type_variation("FlatButton"); - unstage_all_button->set_icon(EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("MoveUp"), EditorStringName(EditorIcons))); + unstage_all_button->set_button_icon(EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("MoveUp"), EditorStringName(EditorIcons))); unstage_all_button->set_tooltip_text(TTR("Unstage all changes")); stage_title->add_child(unstage_all_button); @@ -1411,26 +1411,26 @@ VersionControlEditorPlugin::VersionControlEditorPlugin() { fetch_button = memnew(Button); fetch_button->set_theme_type_variation("FlatButton"); fetch_button->set_tooltip_text(TTR("Fetch")); - fetch_button->set_icon(EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("Reload"), EditorStringName(EditorIcons))); + fetch_button->set_button_icon(EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("Reload"), EditorStringName(EditorIcons))); fetch_button->connect(SceneStringName(pressed), callable_mp(this, &VersionControlEditorPlugin::_fetch)); menu_bar->add_child(fetch_button); pull_button = memnew(Button); pull_button->set_theme_type_variation("FlatButton"); pull_button->set_tooltip_text(TTR("Pull")); - pull_button->set_icon(EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("MoveDown"), EditorStringName(EditorIcons))); + pull_button->set_button_icon(EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("MoveDown"), EditorStringName(EditorIcons))); pull_button->connect(SceneStringName(pressed), callable_mp(this, &VersionControlEditorPlugin::_pull)); menu_bar->add_child(pull_button); push_button = memnew(Button); push_button->set_theme_type_variation("FlatButton"); push_button->set_tooltip_text(TTR("Push")); - push_button->set_icon(EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("MoveUp"), EditorStringName(EditorIcons))); + push_button->set_button_icon(EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("MoveUp"), EditorStringName(EditorIcons))); push_button->connect(SceneStringName(pressed), callable_mp(this, &VersionControlEditorPlugin::_push)); menu_bar->add_child(push_button); extra_options = memnew(MenuButton); - extra_options->set_icon(EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("GuiTabMenuHl"), EditorStringName(EditorIcons))); + extra_options->set_button_icon(EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("GuiTabMenuHl"), EditorStringName(EditorIcons))); extra_options->get_popup()->connect(SNAME("about_to_popup"), callable_mp(this, &VersionControlEditorPlugin::_update_extra_options)); extra_options->get_popup()->connect(SceneStringName(id_pressed), callable_mp(this, &VersionControlEditorPlugin::_extra_option_selected)); menu_bar->add_child(extra_options); diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp index a5df9edcf0..9c1befa144 100644 --- a/editor/plugins/visual_shader_editor_plugin.cpp +++ b/editor/plugins/visual_shader_editor_plugin.cpp @@ -258,7 +258,7 @@ void VisualShaderGraphPlugin::show_port_preview(VisualShader::Type p_type, int p vbox->add_child(offset); VisualShaderNodePortPreview *port_preview = memnew(VisualShaderNodePortPreview); - port_preview->setup(visual_shader, editor->preview_material, visual_shader->get_shader_type(), p_node_id, p_port_id, p_is_valid); + port_preview->setup(visual_shader, editor->preview_material, visual_shader->get_shader_type(), links[p_node_id].output_ports[p_port_id].type == VisualShaderNode::PORT_TYPE_VECTOR_4D, p_node_id, p_port_id, p_is_valid); port_preview->set_h_size_flags(Control::SIZE_SHRINK_CENTER); vbox->add_child(port_preview); link.preview_visible = true; @@ -554,8 +554,8 @@ void VisualShaderGraphPlugin::register_link(VisualShader::Type p_type, int p_id, links.insert(p_id, { p_type, p_visual_node, p_graph_element, p_visual_node->get_output_port_for_preview() != -1, -1, HashMap<int, InputPort>(), HashMap<int, Port>(), nullptr, nullptr, nullptr, { nullptr, nullptr, nullptr } }); } -void VisualShaderGraphPlugin::register_output_port(int p_node_id, int p_port, TextureButton *p_button) { - links[p_node_id].output_ports.insert(p_port, { p_button }); +void VisualShaderGraphPlugin::register_output_port(int p_node_id, int p_port, VisualShaderNode::PortType p_port_type, TextureButton *p_button) { + links[p_node_id].output_ports.insert(p_port, { p_port_type, p_button }); } void VisualShaderGraphPlugin::register_parameter_name(int p_node_id, LineEdit *p_parameter_name) { @@ -1138,7 +1138,7 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id, bool name_box->connect(SceneStringName(focus_exited), callable_mp(editor, &VisualShaderEditor::_port_name_focus_out).bind(name_box, p_id, j, false), CONNECT_DEFERRED); Button *remove_btn = memnew(Button); - remove_btn->set_icon(EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("Remove"), EditorStringName(EditorIcons))); + remove_btn->set_button_icon(EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("Remove"), EditorStringName(EditorIcons))); remove_btn->set_tooltip_text(TTR("Remove") + " " + name_left); remove_btn->connect(SceneStringName(pressed), callable_mp(editor, &VisualShaderEditor::_remove_input_port).bind(p_id, j), CONNECT_DEFERRED); hb->add_child(remove_btn); @@ -1166,7 +1166,7 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id, bool if (valid_right) { if (is_group) { Button *remove_btn = memnew(Button); - remove_btn->set_icon(EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("Remove"), EditorStringName(EditorIcons))); + remove_btn->set_button_icon(EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("Remove"), EditorStringName(EditorIcons))); remove_btn->set_tooltip_text(TTR("Remove") + " " + name_left); remove_btn->connect(SceneStringName(pressed), callable_mp(editor, &VisualShaderEditor::_remove_output_port).bind(p_id, i), CONNECT_DEFERRED); hb->add_child(remove_btn); @@ -1220,7 +1220,7 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id, bool preview->set_texture_pressed(editor->get_editor_theme_icon(SNAME("GuiVisibilityVisible"))); preview->set_v_size_flags(Control::SIZE_SHRINK_CENTER); - register_output_port(p_id, j, preview); + register_output_port(p_id, j, port_right, preview); preview->connect(SceneStringName(pressed), callable_mp(editor, &VisualShaderEditor::_preview_select_port).bind(p_id, j), CONNECT_DEFERRED); hb->add_child(preview); @@ -1472,7 +1472,7 @@ void VisualShaderGraphPlugin::disconnect_nodes(VisualShader::Type p_type, int p_ if (visual_shader.is_valid() && visual_shader->get_shader_type() == p_type) { graph->disconnect_node(itos(p_from_node), p_from_port, itos(p_to_node), p_to_port); - for (const List<VisualShader::Connection>::Element *E = connections.front(); E; E = E->next()) { + for (List<VisualShader::Connection>::Element *E = connections.front(); E; E = E->next()) { if (E->get().from_node == p_from_node && E->get().from_port == p_from_port && E->get().to_node == p_to_node && E->get().to_port == p_to_port) { connections.erase(E); break; @@ -5106,8 +5106,8 @@ void VisualShaderEditor::_notification(int p_what) { param_filter->set_right_icon(Control::get_editor_theme_icon(SNAME("Search"))); node_filter->set_right_icon(Control::get_editor_theme_icon(SNAME("Search"))); - code_preview_button->set_icon(Control::get_editor_theme_icon(SNAME("Shader"))); - shader_preview_button->set_icon(Control::get_editor_theme_icon(SNAME("SubViewport"))); + code_preview_button->set_button_icon(Control::get_editor_theme_icon(SNAME("Shader"))); + shader_preview_button->set_button_icon(Control::get_editor_theme_icon(SNAME("SubViewport"))); { Color background_color = EDITOR_GET("text_editor/theme/highlighting/background_color"); @@ -5158,7 +5158,7 @@ void VisualShaderEditor::_notification(int p_what) { error_label->end_bulk_theme_override(); } - tools->set_icon(get_editor_theme_icon(SNAME("Tools"))); + tools->set_button_icon(get_editor_theme_icon(SNAME("Tools"))); if (is_visible_in_tree()) { _update_graph(); @@ -8031,7 +8031,15 @@ void VisualShaderNodePortPreview::_shader_changed() { set_material(mat); } -void VisualShaderNodePortPreview::setup(const Ref<VisualShader> &p_shader, Ref<ShaderMaterial> &p_preview_material, VisualShader::Type p_type, int p_node, int p_port, bool p_is_valid) { +void VisualShaderNodePortPreview::setup(const Ref<VisualShader> &p_shader, Ref<ShaderMaterial> &p_preview_material, VisualShader::Type p_type, bool p_has_transparency, int p_node, int p_port, bool p_is_valid) { + if (p_has_transparency) { + checkerboard = memnew(TextureRect); + checkerboard->set_stretch_mode(TextureRect::STRETCH_TILE); + checkerboard->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT); + checkerboard->set_draw_behind_parent(true); + add_child(checkerboard); + } + shader = p_shader; shader->connect_changed(callable_mp(this, &VisualShaderNodePortPreview::_shader_changed), CONNECT_DEFERRED); preview_mat = p_preview_material; @@ -8050,6 +8058,11 @@ Size2 VisualShaderNodePortPreview::get_minimum_size() const { void VisualShaderNodePortPreview::_notification(int p_what) { switch (p_what) { + case NOTIFICATION_THEME_CHANGED: { + if (checkerboard != nullptr) { + checkerboard->set_texture(get_theme_icon(SNAME("GuiMiniCheckerboard"), EditorStringName(EditorIcons))); + } + } break; case NOTIFICATION_DRAW: { Vector<Vector2> points = { Vector2(), diff --git a/editor/plugins/visual_shader_editor_plugin.h b/editor/plugins/visual_shader_editor_plugin.h index 3b2ad33304..d3dc2e7564 100644 --- a/editor/plugins/visual_shader_editor_plugin.h +++ b/editor/plugins/visual_shader_editor_plugin.h @@ -107,6 +107,7 @@ private: }; struct Port { + VisualShaderNode::PortType type = VisualShaderNode::PORT_TYPE_SCALAR; TextureButton *preview_button = nullptr; }; @@ -141,7 +142,7 @@ public: void register_shader(VisualShader *p_visual_shader); void set_connections(const List<VisualShader::Connection> &p_connections); void register_link(VisualShader::Type p_type, int p_id, VisualShaderNode *p_visual_node, GraphElement *p_graph_element); - void register_output_port(int p_id, int p_port, TextureButton *p_button); + void register_output_port(int p_id, int p_port, VisualShaderNode::PortType p_port_type, TextureButton *p_button); void register_parameter_name(int p_id, LineEdit *p_parameter_name); void register_default_input_button(int p_node_id, int p_port_id, Button *p_button); void register_expression_edit(int p_node_id, CodeEdit *p_expression_edit); @@ -680,6 +681,7 @@ public: class VisualShaderNodePortPreview : public Control { GDCLASS(VisualShaderNodePortPreview, Control); + TextureRect *checkerboard = nullptr; Ref<VisualShader> shader; Ref<ShaderMaterial> preview_mat; VisualShader::Type type = VisualShader::Type::TYPE_MAX; @@ -692,7 +694,7 @@ protected: public: virtual Size2 get_minimum_size() const override; - void setup(const Ref<VisualShader> &p_shader, Ref<ShaderMaterial> &p_preview_material, VisualShader::Type p_type, int p_node, int p_port, bool p_is_valid); + void setup(const Ref<VisualShader> &p_shader, Ref<ShaderMaterial> &p_preview_material, VisualShader::Type p_type, bool p_has_transparency, int p_node, int p_port, bool p_is_valid); }; class VisualShaderConversionPlugin : public EditorResourceConversionPlugin { diff --git a/editor/plugins/voxel_gi_editor_plugin.cpp b/editor/plugins/voxel_gi_editor_plugin.cpp index 3e835d5cb6..68fe013c08 100644 --- a/editor/plugins/voxel_gi_editor_plugin.cpp +++ b/editor/plugins/voxel_gi_editor_plugin.cpp @@ -185,7 +185,7 @@ VoxelGIEditorPlugin::VoxelGIEditorPlugin() { bake->set_theme_type_variation("FlatButton"); // TODO: Rework this as a dedicated toolbar control so we can hook into theme changes and update it // when the editor theme updates. - bake->set_icon(EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("Bake"), EditorStringName(EditorIcons))); + bake->set_button_icon(EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("Bake"), EditorStringName(EditorIcons))); bake->set_text(TTR("Bake VoxelGI")); bake->connect(SceneStringName(pressed), callable_mp(this, &VoxelGIEditorPlugin::_bake)); bake_hb->add_child(bake); |