diff options
Diffstat (limited to 'editor')
95 files changed, 3504 insertions, 1424 deletions
diff --git a/editor/animation_bezier_editor.cpp b/editor/animation_bezier_editor.cpp index 9af8b907c4..0183d08733 100644 --- a/editor/animation_bezier_editor.cpp +++ b/editor/animation_bezier_editor.cpp @@ -648,7 +648,7 @@ void AnimationBezierTrackEdit::set_animation_and_track(const Ref<Animation> &p_a animation = p_animation; read_only = p_read_only; selected_track = p_track; - update(); + queue_redraw(); } Size2 AnimationBezierTrackEdit::get_minimum_size() const { @@ -691,11 +691,11 @@ void AnimationBezierTrackEdit::_play_position_draw() { void AnimationBezierTrackEdit::set_play_position(real_t p_pos) { play_position_pos = p_pos; - play_position->update(); + play_position->queue_redraw(); } void AnimationBezierTrackEdit::update_play_position() { - play_position->update(); + play_position->queue_redraw(); } void AnimationBezierTrackEdit::set_root(Node *p_root) { @@ -734,12 +734,12 @@ void AnimationBezierTrackEdit::set_filtered(bool p_filtered) { } } } - update(); + queue_redraw(); } void AnimationBezierTrackEdit::_zoom_changed() { - update(); - play_position->update(); + queue_redraw(); + play_position->queue_redraw(); } void AnimationBezierTrackEdit::_update_locked_tracks_after(int p_track) { @@ -787,7 +787,7 @@ String AnimationBezierTrackEdit::get_tooltip(const Point2 &p_pos) const { void AnimationBezierTrackEdit::_clear_selection() { selection.clear(); emit_signal(SNAME("clear_selection")); - update(); + queue_redraw(); } void AnimationBezierTrackEdit::_change_selected_keys_handle_mode(Animation::HandleMode p_mode, bool p_auto) { @@ -819,7 +819,7 @@ void AnimationBezierTrackEdit::_select_at_anim(const Ref<Animation> &p_anim, int selection.insert(IntPair(p_track, idx)); emit_signal(SNAME("select_key"), idx, true, p_track); - update(); + queue_redraw(); } void AnimationBezierTrackEdit::gui_input(const Ref<InputEvent> &p_event) { @@ -909,7 +909,7 @@ void AnimationBezierTrackEdit::gui_input(const Ref<InputEvent> &p_event) { v_scroll = (maximum_value + minimum_value) / 2.0; v_zoom = (maximum_value - minimum_value) / ((get_size().height - timeline->get_size().height) * 0.9); - update(); + queue_redraw(); accept_event(); return; } else if (ED_GET_SHORTCUT("animation_bezier_editor/select_all_keys")->matches_event(p_event)) { @@ -917,13 +917,13 @@ void AnimationBezierTrackEdit::gui_input(const Ref<InputEvent> &p_event) { selection.insert(IntPair(edit_points[i].track, edit_points[i].key)); } - update(); + queue_redraw(); accept_event(); return; } else if (ED_GET_SHORTCUT("animation_bezier_editor/deselect_all_keys")->matches_event(p_event)) { selection.clear(); - update(); + queue_redraw(); accept_event(); return; } @@ -1024,7 +1024,7 @@ void AnimationBezierTrackEdit::gui_input(const Ref<InputEvent> &p_event) { } } } - update(); + queue_redraw(); return; } else if (I.key == VISIBILITY_ICON) { if (hidden_tracks.has(track)) { @@ -1054,7 +1054,7 @@ void AnimationBezierTrackEdit::gui_input(const Ref<InputEvent> &p_event) { solo_track = -1; } - update(); + queue_redraw(); return; } else if (I.key == SOLO_ICON) { if (solo_track == track) { @@ -1076,7 +1076,7 @@ void AnimationBezierTrackEdit::gui_input(const Ref<InputEvent> &p_event) { set_animation_and_track(animation, track, read_only); solo_track = track; } - update(); + queue_redraw(); return; } return; @@ -1098,7 +1098,7 @@ void AnimationBezierTrackEdit::gui_input(const Ref<InputEvent> &p_event) { } else { selection.insert(pair); } - update(); + queue_redraw(); select_single_attempt = IntPair(-1, -1); } else if (selection.has(pair)) { moving_selection_attempt = true; @@ -1110,7 +1110,7 @@ void AnimationBezierTrackEdit::gui_input(const Ref<InputEvent> &p_event) { moving_handle_right = animation->bezier_track_get_key_out_handle(pair.first, pair.second); moving_selection_offset = Vector2(); select_single_attempt = pair; - update(); + queue_redraw(); } else { moving_selection_attempt = true; moving_selection = true; @@ -1135,7 +1135,7 @@ void AnimationBezierTrackEdit::gui_input(const Ref<InputEvent> &p_event) { moving_handle_track = edit_points[i].track; moving_handle_left = animation->bezier_track_get_key_in_handle(edit_points[i].track, edit_points[i].key); moving_handle_right = animation->bezier_track_get_key_out_handle(edit_points[i].track, edit_points[i].key); - update(); + queue_redraw(); return; } @@ -1145,7 +1145,7 @@ void AnimationBezierTrackEdit::gui_input(const Ref<InputEvent> &p_event) { moving_handle_track = edit_points[i].track; moving_handle_left = animation->bezier_track_get_key_in_handle(edit_points[i].track, edit_points[i].key); moving_handle_right = animation->bezier_track_get_key_out_handle(edit_points[i].track, edit_points[i].key); - update(); + queue_redraw(); return; } } @@ -1186,7 +1186,7 @@ void AnimationBezierTrackEdit::gui_input(const Ref<InputEvent> &p_event) { moving_selection_from_track = selected_track; moving_selection_offset = Vector2(); select_single_attempt = IntPair(-1, -1); - update(); + queue_redraw(); return; } @@ -1258,7 +1258,7 @@ void AnimationBezierTrackEdit::gui_input(const Ref<InputEvent> &p_event) { box_selecting_attempt = false; box_selecting = false; - update(); + queue_redraw(); } if (moving_selection_attempt && mb.is_valid() && !mb->is_pressed() && mb->get_button_index() == MouseButton::LEFT) { @@ -1376,7 +1376,7 @@ void AnimationBezierTrackEdit::gui_input(const Ref<InputEvent> &p_event) { } moving_selection_attempt = false; - update(); + queue_redraw(); } } @@ -1397,7 +1397,7 @@ void AnimationBezierTrackEdit::gui_input(const Ref<InputEvent> &p_event) { additional_moving_handle_lefts.clear(); additional_moving_handle_rights.clear(); - update(); + queue_redraw(); } if (box_selecting_attempt && mm.is_valid()) { @@ -1412,7 +1412,7 @@ void AnimationBezierTrackEdit::gui_input(const Ref<InputEvent> &p_event) { //avoid cursor from going too above, so it does not lose focus with viewport warp_mouse(Vector2(get_local_mouse_position().x, 0)); } - update(); + queue_redraw(); } if ((moving_handle == 1 || moving_handle == -1) && mm.is_valid()) { @@ -1461,7 +1461,7 @@ void AnimationBezierTrackEdit::gui_input(const Ref<InputEvent> &p_event) { moving_handle_left = -moving_handle_right; } } - update(); + queue_redraw(); } if ((moving_handle == -1 || moving_handle == 1) && mb.is_valid() && !mb->is_pressed() && mb->get_button_index() == MouseButton::LEFT) { @@ -1478,7 +1478,7 @@ void AnimationBezierTrackEdit::gui_input(const Ref<InputEvent> &p_event) { } undo_redo->commit_action(); moving_handle = 0; - update(); + queue_redraw(); } } } @@ -1491,7 +1491,7 @@ void AnimationBezierTrackEdit::_pan_callback(Vector2 p_scroll_vec) { v_scroll += p_scroll_vec.y * v_zoom; v_scroll = CLAMP(v_scroll, -100000, 100000); timeline->set_value(timeline->get_value() - p_scroll_vec.x / timeline->get_zoom_scale()); - update(); + queue_redraw(); } void AnimationBezierTrackEdit::_zoom_callback(Vector2 p_scroll_vec, Vector2 p_origin, bool p_alt) { @@ -1511,7 +1511,7 @@ void AnimationBezierTrackEdit::_zoom_callback(Vector2 p_scroll_vec, Vector2 p_or } } v_scroll = v_scroll + (p_origin.y - get_size().y / 2.0) * (v_zoom - v_zoom_orig); - update(); + queue_redraw(); } void AnimationBezierTrackEdit::_menu_selected(int p_index) { @@ -1541,7 +1541,7 @@ void AnimationBezierTrackEdit::_menu_selected(int p_index) { undo_redo->add_do_method(animation.ptr(), "track_insert_key", selected_track, time, new_point); undo_redo->add_undo_method(animation.ptr(), "track_remove_key_at_time", selected_track, time); undo_redo->commit_action(); - update(); + queue_redraw(); } } break; case MENU_KEY_DUPLICATE: { @@ -1624,7 +1624,7 @@ void AnimationBezierTrackEdit::duplicate_selection() { selection.insert(IntPair(track, existing_idx)); } - update(); + queue_redraw(); } void AnimationBezierTrackEdit::delete_selection() { diff --git a/editor/animation_track_editor.cpp b/editor/animation_track_editor.cpp index aaaf3e6f04..4991b2cfaf 100644 --- a/editor/animation_track_editor.cpp +++ b/editor/animation_track_editor.cpp @@ -1399,8 +1399,8 @@ public: }; void AnimationTimelineEdit::_zoom_changed(double) { - update(); - play_position->update(); + queue_redraw(); + play_position->queue_redraw(); emit_signal(SNAME("zoom_changed")); } @@ -1430,7 +1430,7 @@ void AnimationTimelineEdit::_anim_length_changed(double p_new_len) { undo_redo->add_undo_method(animation.ptr(), "set_length", animation->get_length()); undo_redo->commit_action(); editing = false; - update(); + queue_redraw(); emit_signal(SNAME("length_changed"), p_new_len); } @@ -1703,7 +1703,7 @@ void AnimationTimelineEdit::set_animation(const Ref<Animation> &p_animation, boo add_track->hide(); play_position->hide(); } - update(); + queue_redraw(); update_values(); } @@ -1731,7 +1731,7 @@ void AnimationTimelineEdit::set_track_edit(AnimationTrackEdit *p_track_edit) { void AnimationTimelineEdit::set_play_position(float p_pos) { play_position_pos = p_pos; - play_position->update(); + play_position->queue_redraw(); } float AnimationTimelineEdit::get_play_position() const { @@ -1739,7 +1739,7 @@ float AnimationTimelineEdit::get_play_position() const { } void AnimationTimelineEdit::update_play_position() { - play_position->update(); + play_position->queue_redraw(); } void AnimationTimelineEdit::update_values() { @@ -1853,9 +1853,9 @@ void AnimationTimelineEdit::gui_input(const Ref<InputEvent> &p_event) { if (dragging_hsize) { int ofs = mm->get_position().x - dragging_hsize_from; name_limit = dragging_hsize_at + ofs; - update(); + queue_redraw(); emit_signal(SNAME("name_limit_changed")); - play_position->update(); + play_position->queue_redraw(); } if (dragging_timeline) { int x = mm->get_position().x - get_name_limit(); @@ -1898,7 +1898,7 @@ void AnimationTimelineEdit::_zoom_callback(Vector2 p_scroll_vec, Vector2 p_origi void AnimationTimelineEdit::set_use_fps(bool p_use_fps) { use_fps = p_use_fps; update_values(); - update(); + queue_redraw(); } bool AnimationTimelineEdit::is_using_fps() const { @@ -2292,13 +2292,13 @@ void AnimationTrackEdit::_notification(int p_what) { case NOTIFICATION_MOUSE_ENTER: hovered = true; - update(); + queue_redraw(); break; case NOTIFICATION_MOUSE_EXIT: hovered = false; // When the mouse cursor exits the track, we're no longer hovering any keyframe. hovering_key_idx = -1; - update(); + queue_redraw(); [[fallthrough]]; case NOTIFICATION_DRAG_END: { cancel_drop(); @@ -2491,7 +2491,7 @@ void AnimationTrackEdit::set_animation_and_track(const Ref<Animation> &p_animati read_only = p_read_only; track = p_track; - update(); + queue_redraw(); ERR_FAIL_INDEX(track, animation->get_track_count()); @@ -2553,11 +2553,11 @@ void AnimationTrackEdit::_play_position_draw() { void AnimationTrackEdit::set_play_position(float p_pos) { play_position_pos = p_pos; - play_position->update(); + play_position->queue_redraw(); } void AnimationTrackEdit::update_play_position() { - play_position->update(); + play_position->queue_redraw(); } void AnimationTrackEdit::set_root(Node *p_root) { @@ -2565,8 +2565,8 @@ void AnimationTrackEdit::set_root(Node *p_root) { } void AnimationTrackEdit::_zoom_changed() { - update(); - play_position->update(); + queue_redraw(); + play_position->queue_redraw(); } void AnimationTrackEdit::_path_submitted(const String &p_text) { @@ -2811,7 +2811,7 @@ void AnimationTrackEdit::gui_input(const Ref<InputEvent> &p_event) { undo_redo->add_do_method(animation.ptr(), "track_set_enabled", track, !animation->track_is_enabled(track)); undo_redo->add_undo_method(animation.ptr(), "track_set_enabled", track, animation->track_is_enabled(track)); undo_redo->commit_action(); - update(); + queue_redraw(); accept_event(); } @@ -3090,7 +3090,7 @@ void AnimationTrackEdit::gui_input(const Ref<InputEvent> &p_event) { if (hovering_key_idx != previous_hovering_key_idx) { // Required to draw keyframe hover feedback on the correct keyframe. - update(); + queue_redraw(); } } } @@ -3156,7 +3156,7 @@ bool AnimationTrackEdit::can_drop_data(const Point2 &p_point, const Variant &p_d dropping_at = 1; } - const_cast<AnimationTrackEdit *>(this)->update(); + const_cast<AnimationTrackEdit *>(this)->queue_redraw(); const_cast<AnimationTrackEdit *>(this)->emit_signal(SNAME("drop_attempted"), track); return true; @@ -3202,7 +3202,7 @@ void AnimationTrackEdit::_menu_selected(int p_index) { undo_redo->add_do_method(animation.ptr(), "value_track_set_update_mode", track, update_mode); undo_redo->add_undo_method(animation.ptr(), "value_track_set_update_mode", track, animation->value_track_get_update_mode(track)); undo_redo->commit_action(); - update(); + queue_redraw(); } break; case MENU_INTERPOLATION_NEAREST: @@ -3215,7 +3215,7 @@ void AnimationTrackEdit::_menu_selected(int p_index) { undo_redo->add_do_method(animation.ptr(), "track_set_interpolation_type", track, interp_mode); undo_redo->add_undo_method(animation.ptr(), "track_set_interpolation_type", track, animation->track_get_interpolation_type(track)); undo_redo->commit_action(); - update(); + queue_redraw(); } break; case MENU_LOOP_WRAP: case MENU_LOOP_CLAMP: { @@ -3224,7 +3224,7 @@ void AnimationTrackEdit::_menu_selected(int p_index) { undo_redo->add_do_method(animation.ptr(), "track_set_interpolation_loop_wrap", track, loop_wrap); undo_redo->add_undo_method(animation.ptr(), "track_set_interpolation_loop_wrap", track, animation->track_get_interpolation_loop_wrap(track)); undo_redo->commit_action(); - update(); + queue_redraw(); } break; case MENU_KEY_INSERT: { @@ -3247,13 +3247,13 @@ void AnimationTrackEdit::_menu_selected(int p_index) { void AnimationTrackEdit::cancel_drop() { if (dropping_at != 0) { dropping_at = 0; - update(); + queue_redraw(); } } void AnimationTrackEdit::set_in_group(bool p_enable) { in_group = p_enable; - update(); + queue_redraw(); } void AnimationTrackEdit::append_to_selection(const Rect2 &p_box, bool p_deselection) { @@ -3399,7 +3399,7 @@ void AnimationTrackEditGroup::set_type_and_name(const Ref<Texture2D> &p_type, co icon = p_type; node_name = p_name; node = p_node; - update(); + queue_redraw(); update_minimum_size(); } @@ -3419,11 +3419,11 @@ void AnimationTrackEditGroup::set_timeline(AnimationTimelineEdit *p_timeline) { void AnimationTrackEditGroup::set_root(Node *p_root) { root = p_root; - update(); + queue_redraw(); } void AnimationTrackEditGroup::_zoom_changed() { - update(); + queue_redraw(); } void AnimationTrackEditGroup::_bind_methods() { @@ -4645,18 +4645,18 @@ void AnimationTrackEditor::_update_tracks() { void AnimationTrackEditor::_redraw_tracks() { for (int i = 0; i < track_edits.size(); i++) { - track_edits[i]->update(); + track_edits[i]->queue_redraw(); } } void AnimationTrackEditor::_redraw_groups() { for (int i = 0; i < groups.size(); i++) { - groups[i]->update(); + groups[i]->queue_redraw(); } } void AnimationTrackEditor::_sync_animation_change() { - bezier_edit->update(); + bezier_edit->queue_redraw(); } void AnimationTrackEditor::_animation_changed() { @@ -4669,12 +4669,12 @@ void AnimationTrackEditor::_animation_changed() { } if (key_edit && key_edit->setting) { - // If editing a key, just update the edited track, makes refresh less costly. + // If editing a key, just redraw the edited track, makes refresh less costly. if (key_edit->track < track_edits.size()) { if (animation->track_get_type(key_edit->track) == Animation::TYPE_BEZIER) { - bezier_edit->update(); + bezier_edit->queue_redraw(); } else { - track_edits[key_edit->track]->update(); + track_edits[key_edit->track]->queue_redraw(); } } return; @@ -4713,7 +4713,7 @@ void AnimationTrackEditor::_update_step_spinbox() { } void AnimationTrackEditor::_animation_update() { - timeline->update(); + timeline->queue_redraw(); timeline->update_values(); bool same = true; @@ -4742,7 +4742,7 @@ void AnimationTrackEditor::_animation_update() { _update_tracks(); } - bezier_edit->update(); + bezier_edit->queue_redraw(); _update_step_spinbox(); emit_signal(SNAME("animation_step_changed"), animation->get_step()); @@ -5000,7 +5000,7 @@ void AnimationTrackEditor::_timeline_value_changed(double) { } _redraw_groups(); - bezier_edit->update(); + bezier_edit->queue_redraw(); bezier_edit->update_play_position(); } diff --git a/editor/animation_track_editor_plugins.cpp b/editor/animation_track_editor_plugins.cpp index ab64aaa24d..6499cf8df2 100644 --- a/editor/animation_track_editor_plugins.cpp +++ b/editor/animation_track_editor_plugins.cpp @@ -197,7 +197,7 @@ void AnimationTrackEditAudio::_preview_changed(ObjectID p_which) { Ref<AudioStream> stream = object->call("get_stream"); if (stream.is_valid() && stream->get_instance_id() == p_which) { - update(); + queue_redraw(); } } @@ -799,7 +799,7 @@ void AnimationTrackEditTypeAudio::_preview_changed(ObjectID p_which) { for (int i = 0; i < get_animation()->track_get_key_count(get_track()); i++) { Ref<AudioStream> stream = get_animation()->audio_track_get_key_stream(get_track(), i); if (stream.is_valid() && stream->get_instance_id() == p_which) { - update(); + queue_redraw(); return; } } @@ -1026,7 +1026,7 @@ void AnimationTrackEditTypeAudio::drop_data(const Point2 &p_point, const Variant get_undo_redo()->add_undo_method(get_animation().ptr(), "track_remove_key_at_time", get_track(), ofs); get_undo_redo()->commit_action(); - update(); + queue_redraw(); return; } } @@ -1086,7 +1086,7 @@ void AnimationTrackEditTypeAudio::gui_input(const Ref<InputEvent> &p_event) { if (len_resizing && mm.is_valid()) { len_resizing_rel += mm->get_relative().x; len_resizing_start = mm->is_shift_pressed(); - update(); + queue_redraw(); accept_event(); return; } @@ -1097,7 +1097,7 @@ void AnimationTrackEditTypeAudio::gui_input(const Ref<InputEvent> &p_event) { len_resizing_start = mb->is_shift_pressed(); len_resizing_from_px = mb->get_position().x; len_resizing_rel = 0; - update(); + queue_redraw(); accept_event(); return; } @@ -1120,7 +1120,7 @@ void AnimationTrackEditTypeAudio::gui_input(const Ref<InputEvent> &p_event) { } len_resizing_index = -1; - update(); + queue_redraw(); accept_event(); return; } diff --git a/editor/code_editor.cpp b/editor/code_editor.cpp index 2b1584b20c..2d5e70e1ff 100644 --- a/editor/code_editor.cpp +++ b/editor/code_editor.cpp @@ -1092,7 +1092,7 @@ void CodeTextEditor::trim_trailing_whitespace() { if (trimed_whitespace) { text_editor->end_complex_operation(); - text_editor->update(); + text_editor->queue_redraw(); } } @@ -1110,7 +1110,7 @@ void CodeTextEditor::insert_final_newline() { text_editor->set_line(final_line, line); text_editor->end_complex_operation(); - text_editor->update(); + text_editor->queue_redraw(); } } @@ -1154,7 +1154,7 @@ void CodeTextEditor::convert_indent_to_spaces() { if (changed_indentation) { text_editor->set_caret_column(cursor_column); text_editor->end_complex_operation(); - text_editor->update(); + text_editor->queue_redraw(); } } @@ -1203,7 +1203,7 @@ void CodeTextEditor::convert_indent_to_tabs() { if (changed_indentation) { text_editor->set_caret_column(cursor_column); text_editor->end_complex_operation(); - text_editor->update(); + text_editor->queue_redraw(); } } @@ -1295,7 +1295,7 @@ void CodeTextEditor::move_lines_up() { text_editor->set_caret_line(next_id); } text_editor->end_complex_operation(); - text_editor->update(); + text_editor->queue_redraw(); } void CodeTextEditor::move_lines_down() { @@ -1341,7 +1341,7 @@ void CodeTextEditor::move_lines_down() { text_editor->set_caret_line(next_id); } text_editor->end_complex_operation(); - text_editor->update(); + text_editor->queue_redraw(); } void CodeTextEditor::_delete_line(int p_line) { @@ -1418,7 +1418,7 @@ void CodeTextEditor::duplicate_selection() { } text_editor->end_complex_operation(); - text_editor->update(); + text_editor->queue_redraw(); } void CodeTextEditor::toggle_inline_comment(const String &delimiter) { @@ -1495,7 +1495,7 @@ void CodeTextEditor::toggle_inline_comment(const String &delimiter) { text_editor->set_caret_column(col); } text_editor->end_complex_operation(); - text_editor->update(); + text_editor->queue_redraw(); } void CodeTextEditor::goto_line(int p_line) { diff --git a/editor/connections_dialog.cpp b/editor/connections_dialog.cpp index 587c16c229..dce9ca2b93 100644 --- a/editor/connections_dialog.cpp +++ b/editor/connections_dialog.cpp @@ -753,22 +753,12 @@ void ConnectionsDock::_open_connection_dialog(TreeItem &p_item) { } Dictionary subst; - - String s = node_name.capitalize().replace(" ", ""); - subst["NodeName"] = s; - if (!s.is_empty()) { - s[0] = s.to_lower()[0]; - } - subst["nodeName"] = s; - subst["node_name"] = node_name.capitalize().replace(" ", "_").to_lower(); - - s = signal_name.capitalize().replace(" ", ""); - subst["SignalName"] = s; - if (!s.is_empty()) { - s[0] = s.to_lower()[0]; - } - subst["signalName"] = s; - subst["signal_name"] = signal_name.capitalize().replace(" ", "_").to_lower(); + subst["NodeName"] = node_name.to_pascal_case(); + subst["nodeName"] = node_name.to_camel_case(); + subst["node_name"] = node_name.to_snake_case(); + subst["SignalName"] = signal_name.to_pascal_case(); + subst["signalName"] = signal_name.to_camel_case(); + subst["signal_name"] = signal_name.to_snake_case(); String dst_method = String(EDITOR_GET("interface/editors/default_signal_callback_name")).format(subst); @@ -1070,7 +1060,7 @@ void ConnectionsDock::update_tree() { } // "::" separators used in make_custom_tooltip for formatting. - signal_item->set_tooltip(0, String(signal_name) + "::" + signaldesc + "::" + descr); + signal_item->set_tooltip_text(0, String(signal_name) + "::" + signaldesc + "::" + descr); } // List existing connections. diff --git a/editor/create_dialog.cpp b/editor/create_dialog.cpp index 7e5b818307..8ccfda1145 100644 --- a/editor/create_dialog.cpp +++ b/editor/create_dialog.cpp @@ -313,7 +313,7 @@ void CreateDialog::_configure_search_option_item(TreeItem *r_item, const String } const String &description = DTR(EditorHelp::get_doc_data()->class_list[p_type].brief_description); - r_item->set_tooltip(0, description); + r_item->set_tooltip_text(0, description); if (p_type_category == TypeCategory::OTHER_TYPE && !script_type) { Ref<Texture2D> icon = EditorNode::get_editor_data().get_custom_types()[custom_type_parents[p_type]][custom_type_indices[p_type]].icon; diff --git a/editor/debugger/editor_debugger_tree.cpp b/editor/debugger/editor_debugger_tree.cpp index dbd2c61d44..76efcd7190 100644 --- a/editor/debugger/editor_debugger_tree.cpp +++ b/editor/debugger/editor_debugger_tree.cpp @@ -155,7 +155,7 @@ void EditorDebuggerTree::update_scene_tree(const SceneDebuggerTree *p_tree, int const SceneDebuggerTree::RemoteNode &node = p_tree->nodes[i]; TreeItem *item = create_item(parent); item->set_text(0, node.name); - item->set_tooltip(0, TTR("Type:") + " " + node.type_name); + item->set_tooltip_text(0, TTR("Type:") + " " + node.type_name); Ref<Texture2D> icon = EditorNode::get_singleton()->get_class_icon(node.type_name, ""); if (icon.is_valid()) { item->set_icon(0, icon); diff --git a/editor/debugger/editor_performance_profiler.cpp b/editor/debugger/editor_performance_profiler.cpp index 55d025f675..10b50a81e4 100644 --- a/editor/debugger/editor_performance_profiler.cpp +++ b/editor/debugger/editor_performance_profiler.cpp @@ -61,7 +61,7 @@ void EditorPerformanceProfiler::Monitor::update_value(float p_value) { } break; } item->set_text(1, label); - item->set_tooltip(1, tooltip); + item->set_tooltip_text(1, tooltip); if (p_value > max) { max = p_value; @@ -73,7 +73,7 @@ void EditorPerformanceProfiler::Monitor::reset() { max = 0.0f; if (item) { item->set_text(1, ""); - item->set_tooltip(1, ""); + item->set_tooltip_text(1, ""); } } @@ -92,7 +92,7 @@ String EditorPerformanceProfiler::_create_label(float p_value, Performance::Moni } void EditorPerformanceProfiler::_monitor_select() { - monitor_draw->update(); + monitor_draw->queue_redraw(); } void EditorPerformanceProfiler::_monitor_draw() { @@ -283,12 +283,12 @@ void EditorPerformanceProfiler::_marker_input(const Ref<InputEvent> &p_event) { float spacing = float(point_sep) / float(columns); marker_frame = (rect.size.x - point.x) / spacing; } - monitor_draw->update(); + monitor_draw->queue_redraw(); return; } } marker_key = ""; - monitor_draw->update(); + monitor_draw->queue_redraw(); } } @@ -308,7 +308,7 @@ void EditorPerformanceProfiler::reset() { _build_monitor_tree(); marker_key = ""; marker_frame = 0; - monitor_draw->update(); + monitor_draw->queue_redraw(); } void EditorPerformanceProfiler::update_monitors(const Vector<StringName> &p_names) { @@ -357,7 +357,7 @@ void EditorPerformanceProfiler::add_profile_frame(const Vector<float> &p_values) E.value.update_value(data); } marker_frame++; - monitor_draw->update(); + monitor_draw->queue_redraw(); } List<float> *EditorPerformanceProfiler::get_monitor_data(const StringName &p_name) { diff --git a/editor/debugger/editor_profiler.cpp b/editor/debugger/editor_profiler.cpp index b49cab9df7..cf48366bd3 100644 --- a/editor/debugger/editor_profiler.cpp +++ b/editor/debugger/editor_profiler.cpp @@ -318,7 +318,7 @@ void EditorProfiler::_update_plot() { graph_texture->update(img); graph->set_texture(graph_texture); - graph->update(); + graph->queue_redraw(); } void EditorProfiler::_update_frame() { @@ -356,7 +356,7 @@ void EditorProfiler::_update_frame() { item->set_metadata(1, it.script); item->set_metadata(2, it.line); item->set_text_alignment(2, HORIZONTAL_ALIGNMENT_RIGHT); - item->set_tooltip(0, it.name + "\n" + it.script + ":" + itos(it.line)); + item->set_tooltip_text(0, it.name + "\n" + it.script + ":" + itos(it.line)); float time = dtime == DISPLAY_SELF_TIME ? it.self : it.total; @@ -421,7 +421,7 @@ void EditorProfiler::_graph_tex_draw() { void EditorProfiler::_graph_tex_mouse_exit() { hover_metric = -1; - graph->update(); + graph->queue_redraw(); } void EditorProfiler::_cursor_metric_changed(double) { @@ -429,7 +429,7 @@ void EditorProfiler::_cursor_metric_changed(double) { return; } - graph->update(); + graph->queue_redraw(); _update_frame(); } @@ -480,13 +480,13 @@ void EditorProfiler::_graph_tex_input(const Ref<InputEvent> &p_ev) { } } - graph->update(); + graph->queue_redraw(); } } void EditorProfiler::disable_seeking() { seeking = false; - graph->update(); + graph->queue_redraw(); } void EditorProfiler::_combo_changed(int) { diff --git a/editor/debugger/editor_visual_profiler.cpp b/editor/debugger/editor_visual_profiler.cpp index 6f3dd1793c..8e7135f1c5 100644 --- a/editor/debugger/editor_visual_profiler.cpp +++ b/editor/debugger/editor_visual_profiler.cpp @@ -312,7 +312,7 @@ void EditorVisualProfiler::_update_plot() { graph_texture->update(img); graph->set_texture(graph_texture); - graph->update(); + graph->queue_redraw(); } void EditorVisualProfiler::_update_frame(bool p_focus_selected) { @@ -489,7 +489,7 @@ void EditorVisualProfiler::_graph_tex_draw() { void EditorVisualProfiler::_graph_tex_mouse_exit() { hover_metric = -1; - graph->update(); + graph->queue_redraw(); } void EditorVisualProfiler::_cursor_metric_changed(double) { @@ -497,7 +497,7 @@ void EditorVisualProfiler::_cursor_metric_changed(double) { return; } - graph->update(); + graph->queue_redraw(); _update_frame(); } @@ -613,7 +613,7 @@ void EditorVisualProfiler::_graph_tex_input(const Ref<InputEvent> &p_ev) { } } - graph->update(); + graph->queue_redraw(); } } @@ -637,7 +637,7 @@ int EditorVisualProfiler::_get_cursor_index() const { void EditorVisualProfiler::disable_seeking() { seeking = false; - graph->update(); + graph->queue_redraw(); } void EditorVisualProfiler::_combo_changed(int) { diff --git a/editor/debugger/script_editor_debugger.cpp b/editor/debugger/script_editor_debugger.cpp index fab211f18c..5baa9970af 100644 --- a/editor/debugger/script_editor_debugger.cpp +++ b/editor/debugger/script_editor_debugger.cpp @@ -580,8 +580,8 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da stack_trace->set_text(1, frame_txt); } - error->set_tooltip(0, tooltip); - error->set_tooltip(1, tooltip); + error->set_tooltip_text(0, tooltip); + error->set_tooltip_text(1, tooltip); if (warning_count == 0 && error_count == 0) { expand_all_button->set_disabled(false); diff --git a/editor/editor_asset_installer.cpp b/editor/editor_asset_installer.cpp index 8dc8a0ab6b..aaa5956c17 100644 --- a/editor/editor_asset_installer.cpp +++ b/editor/editor_asset_installer.cpp @@ -215,11 +215,11 @@ void EditorAssetInstaller::open(const String &p_path, int p_depth) { if (FileAccess::exists(res_path)) { num_file_conflicts += 1; ti->set_custom_color(0, tree->get_theme_color(SNAME("error_color"), SNAME("Editor"))); - ti->set_tooltip(0, vformat(TTR("%s (already exists)"), res_path)); + ti->set_tooltip_text(0, vformat(TTR("%s (already exists)"), res_path)); ti->set_checked(0, false); ti->propagate_check(0); } else { - ti->set_tooltip(0, res_path); + ti->set_tooltip_text(0, res_path); } ti->set_metadata(0, res_path); diff --git a/editor/editor_audio_buses.cpp b/editor/editor_audio_buses.cpp index a95cc4981a..b1253ed7cb 100644 --- a/editor/editor_audio_buses.cpp +++ b/editor/editor_audio_buses.cpp @@ -182,7 +182,7 @@ void EditorAudioBus::_notification(int p_what) { case NOTIFICATION_DRAG_END: { if (hovering_drop) { hovering_drop = false; - update(); + queue_redraw(); } } break; } @@ -967,7 +967,7 @@ void EditorAudioBusDrop::_notification(int p_what) { case NOTIFICATION_MOUSE_ENTER: { if (!hovering_drop) { hovering_drop = true; - update(); + queue_redraw(); } } break; @@ -975,7 +975,7 @@ void EditorAudioBusDrop::_notification(int p_what) { case NOTIFICATION_DRAG_END: { if (hovering_drop) { hovering_drop = false; - update(); + queue_redraw(); } } break; } diff --git a/editor/editor_autoload_settings.cpp b/editor/editor_autoload_settings.cpp index 6d44654617..544b6c7141 100644 --- a/editor/editor_autoload_settings.cpp +++ b/editor/editor_autoload_settings.cpp @@ -164,7 +164,7 @@ void EditorAutoloadSettings::_autoload_add() { if (!fpath.ends_with("/")) { fpath = fpath.get_base_dir(); } - dialog->config("Node", fpath.path_join(vformat("%s.gd", autoload_add_name->get_text().camelcase_to_underscore())), false, false); + dialog->config("Node", fpath.path_join(vformat("%s.gd", autoload_add_name->get_text().to_snake_case())), false, false); dialog->popup_centered(); } else { if (autoload_add(autoload_add_name->get_text(), autoload_add_path->get_text())) { @@ -371,7 +371,7 @@ void EditorAutoloadSettings::_autoload_open(const String &fpath) { void EditorAutoloadSettings::_autoload_file_callback(const String &p_path) { // Convert the file name to PascalCase, which is the convention for classes in GDScript. - const String class_name = p_path.get_file().get_basename().capitalize().replace(" ", ""); + const String class_name = p_path.get_file().get_basename().to_pascal_case(); // If the name collides with a built-in class, prefix the name to make it possible to add without having to edit the name. // The prefix is subjective, but it provides better UX than leaving the Add button disabled :) @@ -580,7 +580,7 @@ void EditorAutoloadSettings::_script_created(Ref<Script> p_script) { FileSystemDock::get_singleton()->get_script_create_dialog()->hide(); path = p_script->get_path().get_base_dir(); autoload_add_path->set_text(p_script->get_path()); - autoload_add_name->set_text(p_script->get_path().get_file().get_basename().capitalize().replace(" ", "")); + autoload_add_name->set_text(p_script->get_path().get_file().get_basename().to_pascal_case()); _autoload_add(); } diff --git a/editor/editor_feature_profile.cpp b/editor/editor_feature_profile.cpp index 45d7fa9357..708173ea26 100644 --- a/editor/editor_feature_profile.cpp +++ b/editor/editor_feature_profile.cpp @@ -630,7 +630,7 @@ void EditorFeatureProfileManager::_class_list_item_selected() { property->set_selectable(0, true); property->set_checked(0, !edited->is_class_property_disabled(class_name, name)); property->set_text(0, text); - property->set_tooltip(0, tooltip); + property->set_tooltip_text(0, tooltip); property->set_metadata(0, name); String icon_type = Variant::get_type_name(E.type); property->set_icon(0, EditorNode::get_singleton()->get_class_icon(icon_type)); diff --git a/editor/editor_file_dialog.cpp b/editor/editor_file_dialog.cpp index e24aa995c8..fca9907c20 100644 --- a/editor/editor_file_dialog.cpp +++ b/editor/editor_file_dialog.cpp @@ -37,6 +37,7 @@ #include "core/string/print_string.h" #include "dependency_editor.h" #include "editor/editor_file_system.h" +#include "editor/editor_node.h" #include "editor/editor_resource_preview.h" #include "editor/editor_scale.h" #include "editor/editor_settings.h" @@ -294,11 +295,22 @@ void EditorFileDialog::_post_popup() { bool res = (access == ACCESS_RESOURCES); Vector<String> recentd = EditorSettings::get_singleton()->get_recent_dirs(); + Vector<String> recentd_paths; + Vector<String> recentd_names; + for (int i = 0; i < recentd.size(); i++) { bool cres = recentd[i].begins_with("res://"); if (cres != res) { continue; } + + if (!dir_access->dir_exists(recentd[i])) { + // Remove invalid directory from the list of Recent directories. + recentd.remove_at(i--); + continue; + } + + // Compute recent directory display text. String name = recentd[i]; if (res && name == "res://") { name = "/"; @@ -306,17 +318,18 @@ void EditorFileDialog::_post_popup() { if (name.ends_with("/")) { name = name.substr(0, name.length() - 1); } - name = name.get_file() + "/"; - } - bool exists = dir_access->dir_exists(recentd[i]); - if (!exists) { - // Remove invalid directory from the list of Recent directories. - recentd.remove_at(i--); - } else { - recent->add_item(name, folder); - recent->set_item_metadata(-1, recentd[i]); - recent->set_item_icon_modulate(-1, folder_color); + name = name.get_file(); } + recentd_paths.append(recentd[i]); + recentd_names.append(name); + } + + EditorNode::disambiguate_filenames(recentd_paths, recentd_names); + + for (int i = 0; i < recentd_paths.size(); i++) { + recent->add_item(recentd_names[i], folder); + recent->set_item_metadata(-1, recentd_paths[i]); + recent->set_item_icon_modulate(-1, folder_color); } EditorSettings::get_singleton()->set_recent_dirs(recentd); @@ -1329,49 +1342,58 @@ void EditorFileDialog::_update_favorites() { favorite->set_pressed(false); Vector<String> favorited = EditorSettings::get_singleton()->get_favorites(); + Vector<String> favorited_paths; + Vector<String> favorited_names; bool fav_changed = false; - for (int i = favorited.size() - 1; i >= 0; i--) { - if (!dir_access->dir_exists(favorited[i])) { - favorited.remove_at(i); - fav_changed = true; - } - } - if (fav_changed) { - EditorSettings::get_singleton()->set_favorites(favorited); - } - + int current_favorite = -1; for (int i = 0; i < favorited.size(); i++) { bool cres = favorited[i].begins_with("res://"); if (cres != res) { continue; } - String name = favorited[i]; - bool setthis = false; + if (!dir_access->dir_exists(favorited[i])) { + // Remove invalid directory from the list of Favorited directories. + favorited.remove_at(i--); + fav_changed = true; + continue; + } + + // Compute favorite display text. + String name = favorited[i]; if (res && name == "res://") { if (name == current) { - setthis = true; + current_favorite = favorited_paths.size(); } name = "/"; - - favorites->add_item(name, folder_icon); + favorited_paths.append(favorited[i]); + favorited_names.append(name); } else if (name.ends_with("/")) { if (name == current || name == current + "/") { - setthis = true; + current_favorite = favorited_paths.size(); } name = name.substr(0, name.length() - 1); name = name.get_file(); - - favorites->add_item(name, folder_icon); + favorited_paths.append(favorited[i]); + favorited_names.append(name); } else { - continue; // We don't handle favorite files here. + // Ignore favorited files. } + } + + if (fav_changed) { + EditorSettings::get_singleton()->set_favorites(favorited); + } + + EditorNode::disambiguate_filenames(favorited_paths, favorited_names); - favorites->set_item_metadata(-1, favorited[i]); + for (int i = 0; i < favorited_paths.size(); i++) { + favorites->add_item(favorited_names[i], folder_icon); + favorites->set_item_metadata(-1, favorited_paths[i]); favorites->set_item_icon_modulate(-1, folder_color); - if (setthis) { + if (i == current_favorite) { favorite->set_pressed(true); favorites->set_current(favorites->get_item_count() - 1); recent->deselect_all(); diff --git a/editor/editor_help_search.cpp b/editor/editor_help_search.cpp index b4678d8363..2e35f21e47 100644 --- a/editor/editor_help_search.cpp +++ b/editor/editor_help_search.cpp @@ -562,8 +562,8 @@ TreeItem *EditorHelpSearch::Runner::_create_class_item(TreeItem *p_parent, const item->set_icon(0, icon); item->set_text(0, p_doc->name); item->set_text(1, TTR("Class")); - item->set_tooltip(0, tooltip); - item->set_tooltip(1, tooltip); + item->set_tooltip_text(0, tooltip); + item->set_tooltip_text(1, tooltip); item->set_metadata(0, "class_name:" + p_doc->name); if (p_gray) { item->set_custom_color(0, disabled_color); @@ -639,8 +639,8 @@ TreeItem *EditorHelpSearch::Runner::_create_member_item(TreeItem *p_parent, cons item->set_icon(0, icon); item->set_text(0, text); item->set_text(1, TTRGET(p_type)); - item->set_tooltip(0, p_tooltip); - item->set_tooltip(1, p_tooltip); + item->set_tooltip_text(0, p_tooltip); + item->set_tooltip_text(1, p_tooltip); item->set_metadata(0, "class_" + p_metatype + ":" + p_class_name + ":" + p_name); _match_item(item, p_name); diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp index 5033f842d5..6aa0bd3f99 100644 --- a/editor/editor_inspector.cpp +++ b/editor/editor_inspector.cpp @@ -231,7 +231,7 @@ void EditorProperty::_notification(int p_what) { bottom_child_rect = bottom_rect; } - update(); //need to redraw text + queue_redraw(); //need to redraw text } break; case NOTIFICATION_DRAW: { @@ -398,7 +398,7 @@ void EditorProperty::_notification(int p_what) { void EditorProperty::set_label(const String &p_label) { label = p_label; - update(); + queue_redraw(); } String EditorProperty::get_label() const { @@ -478,7 +478,7 @@ void EditorProperty::update_revert_and_pin_status() { } can_revert = new_can_revert; pinned = new_pinned; - update(); + queue_redraw(); } } @@ -499,7 +499,7 @@ bool EditorProperty::use_keying_next() const { void EditorProperty::set_checkable(bool p_checkable) { checkable = p_checkable; - update(); + queue_redraw(); queue_sort(); } @@ -509,7 +509,7 @@ bool EditorProperty::is_checkable() const { void EditorProperty::set_checked(bool p_checked) { checked = p_checked; - update(); + queue_redraw(); } bool EditorProperty::is_checked() const { @@ -518,18 +518,18 @@ bool EditorProperty::is_checked() const { void EditorProperty::set_draw_warning(bool p_draw_warning) { draw_warning = p_draw_warning; - update(); + queue_redraw(); } void EditorProperty::set_keying(bool p_keying) { keying = p_keying; - update(); + queue_redraw(); queue_sort(); } void EditorProperty::set_deletable(bool p_deletable) { deletable = p_deletable; - update(); + queue_redraw(); queue_sort(); } @@ -552,7 +552,7 @@ void EditorProperty::_focusable_focused(int p_index) { bool already_selected = selected; selected = true; selected_focusable = p_index; - update(); + queue_redraw(); if (!already_selected && selected) { emit_signal(SNAME("selected"), property, selected_focusable); } @@ -571,7 +571,7 @@ void EditorProperty::select(int p_focusable) { focusables[p_focusable]->grab_focus(); } else { selected = true; - update(); + queue_redraw(); } if (!already_selected && selected) { @@ -582,7 +582,7 @@ void EditorProperty::select(int p_focusable) { void EditorProperty::deselect() { selected = false; selected_focusable = -1; - update(); + queue_redraw(); } bool EditorProperty::is_selected() const { @@ -608,25 +608,25 @@ void EditorProperty::gui_input(const Ref<InputEvent> &p_event) { bool new_keying_hover = keying_rect.has_point(mpos) && !button_left; if (new_keying_hover != keying_hover) { keying_hover = new_keying_hover; - update(); + queue_redraw(); } bool new_delete_hover = delete_rect.has_point(mpos) && !button_left; if (new_delete_hover != delete_hover) { delete_hover = new_delete_hover; - update(); + queue_redraw(); } bool new_revert_hover = revert_rect.has_point(mpos) && !button_left; if (new_revert_hover != revert_hover) { revert_hover = new_revert_hover; - update(); + queue_redraw(); } bool new_check_hover = check_rect.has_point(mpos) && !button_left; if (new_check_hover != check_hover) { check_hover = new_check_hover; - update(); + queue_redraw(); } } @@ -641,7 +641,7 @@ void EditorProperty::gui_input(const Ref<InputEvent> &p_event) { if (!selected && selectable) { selected = true; emit_signal(SNAME("selected"), property, -1); - update(); + queue_redraw(); } if (keying_rect.has_point(mpos)) { @@ -681,7 +681,7 @@ void EditorProperty::gui_input(const Ref<InputEvent> &p_event) { if (check_rect.has_point(mpos)) { checked = !checked; - update(); + queue_redraw(); emit_signal(SNAME("property_checked"), property, checked); } } else if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == MouseButton::RIGHT) { @@ -912,7 +912,7 @@ void EditorProperty::menu_option(int p_option) { } break; case MENU_PIN_VALUE: { emit_signal(SNAME("property_pinned"), property, !pinned); - update(); + queue_redraw(); } break; case MENU_OPEN_DOCUMENTATION: { ScriptEditor::get_singleton()->goto_help(doc_path); @@ -1372,26 +1372,26 @@ void EditorInspectorSection::_notification(int p_what) { } dropping = children_can_drop; - update(); + queue_redraw(); } break; case NOTIFICATION_DRAG_END: { dropping = false; - update(); + queue_redraw(); } break; case NOTIFICATION_MOUSE_ENTER: { if (dropping) { dropping_unfold_timer->start(); } - update(); + queue_redraw(); } break; case NOTIFICATION_MOUSE_EXIT: { if (dropping) { dropping_unfold_timer->stop(); } - update(); + queue_redraw(); } break; } } @@ -1477,7 +1477,7 @@ void EditorInspectorSection::gui_input(const Ref<InputEvent> &p_event) { fold(); } } else if (mb.is_valid() && !mb->is_pressed()) { - update(); + queue_redraw(); } } @@ -1494,7 +1494,7 @@ void EditorInspectorSection::unfold() { object->editor_set_section_unfold(section, true); vbox->show(); - update(); + queue_redraw(); } void EditorInspectorSection::fold() { @@ -1508,7 +1508,7 @@ void EditorInspectorSection::fold() { object->editor_set_section_unfold(section, false); vbox->hide(); - update(); + queue_redraw(); } bool EditorInspectorSection::has_revertable_properties() const { @@ -1523,7 +1523,7 @@ void EditorInspectorSection::property_can_revert_changed(const String &p_path, b revertable_properties.erase(p_path); } if (has_revertable_properties() != had_revertable_properties) { - update(); + queue_redraw(); } } @@ -2052,8 +2052,8 @@ void EditorInspectorArray::_setup() { ae.panel->set_drag_forwarding(this); ae.panel->set_meta("index", begin_array_index + i); ae.panel->set_tooltip_text(vformat(TTR("Element %d: %s%d*"), i, array_element_prefix, i)); - ae.panel->connect("focus_entered", callable_mp((CanvasItem *)ae.panel, &PanelContainer::update)); - ae.panel->connect("focus_exited", callable_mp((CanvasItem *)ae.panel, &PanelContainer::update)); + ae.panel->connect("focus_entered", callable_mp((CanvasItem *)ae.panel, &PanelContainer::queue_redraw)); + ae.panel->connect("focus_exited", callable_mp((CanvasItem *)ae.panel, &PanelContainer::queue_redraw)); ae.panel->connect("draw", callable_mp(this, &EditorInspectorArray::_panel_draw).bind(i)); ae.panel->connect("gui_input", callable_mp(this, &EditorInspectorArray::_panel_gui_input).bind(i)); ae.panel->add_theme_style_override(SNAME("panel"), i % 2 ? odd_style : even_style); @@ -2155,7 +2155,7 @@ bool EditorInspectorArray::can_drop_data_fw(const Point2 &p_point, const Variant return false; } // First, update drawing. - control_dropping->update(); + control_dropping->queue_redraw(); if (p_data.get_type() != Variant::DICTIONARY) { return false; @@ -2206,14 +2206,14 @@ void EditorInspectorArray::_notification(int p_what) { Dictionary dict = get_viewport()->gui_get_drag_data(); if (dict.has("type") && dict["type"] == "property_array_element" && String(dict["property_array_prefix"]) == array_element_prefix) { dropping = true; - control_dropping->update(); + control_dropping->queue_redraw(); } } break; case NOTIFICATION_DRAG_END: { if (dropping) { dropping = false; - control_dropping->update(); + control_dropping->queue_redraw(); } } break; } diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 0b0c0a953a..689a13ab5c 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -216,6 +216,8 @@ EditorNode *EditorNode::singleton = nullptr; static const String META_TEXT_TO_COPY = "text_to_copy"; void EditorNode::disambiguate_filenames(const Vector<String> p_full_paths, Vector<String> &r_filenames) { + ERR_FAIL_COND_MSG(p_full_paths.size() != r_filenames.size(), vformat("disambiguate_filenames requires two string vectors of same length (%d != %d).", p_full_paths.size(), r_filenames.size())); + // Keep track of a list of "index sets," i.e. sets of indices // within disambiguated_scene_names which contain the same name. Vector<RBSet<int>> index_sets; @@ -250,6 +252,10 @@ void EditorNode::disambiguate_filenames(const Vector<String> p_full_paths, Vecto full_path = full_path.substr(0, full_path.rfind(".")); } + // Normalize trailing slashes when normalizing directory names. + scene_name = scene_name.trim_suffix("/"); + full_path = full_path.trim_suffix("/"); + int scene_name_size = scene_name.size(); int full_path_size = full_path.size(); int difference = full_path_size - scene_name_size; @@ -292,17 +298,23 @@ void EditorNode::disambiguate_filenames(const Vector<String> p_full_paths, Vecto // and the scene name first to remove extensions so that this // comparison actually works. String path = p_full_paths[E->get()]; + + // Get rid of file extensions and res:// prefixes. + if (scene_name.rfind(".") >= 0) { + scene_name = scene_name.substr(0, scene_name.rfind(".")); + } if (path.begins_with("res://")) { path = path.substr(6); } if (path.rfind(".") >= 0) { path = path.substr(0, path.rfind(".")); } - if (scene_name.rfind(".") >= 0) { - scene_name = scene_name.substr(0, scene_name.rfind(".")); - } - // We can proceed iff the full path is longer than the scene name, + // Normalize trailing slashes when normalizing directory names. + scene_name = scene_name.trim_suffix("/"); + path = path.trim_suffix("/"); + + // We can proceed if the full path is longer than the scene name, // meaning that there is at least one more parent folder we can // tack onto the name. can_proceed = can_proceed || (path.size() - scene_name.size()) >= 1; @@ -354,7 +366,7 @@ void EditorNode::_update_scene_tabs() { scene_tabs->add_tab(disambiguated_scene_names[i] + (unsaved ? "(*)" : ""), icon); if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_GLOBAL_MENU)) { - DisplayServer::get_singleton()->global_menu_add_item("_dock", editor_data.get_scene_title(i) + (unsaved ? "(*)" : ""), callable_mp(this, &EditorNode::_global_menu_scene), i); + DisplayServer::get_singleton()->global_menu_add_item("_dock", editor_data.get_scene_title(i) + (unsaved ? "(*)" : ""), callable_mp(this, &EditorNode::_global_menu_scene), Callable(), i); } if (show_rb && editor_data.get_scene_root_script(i).is_valid()) { @@ -411,9 +423,6 @@ void EditorNode::_version_control_menu_option(int p_idx) { case RUN_VCS_SETTINGS: { VersionControlEditorPlugin::get_singleton()->popup_vcs_set_up_dialog(gui_base); } break; - case RUN_VCS_SHUT_DOWN: { - VersionControlEditorPlugin::get_singleton()->shut_down(); - } break; } } @@ -492,10 +501,10 @@ void EditorNode::_update_from_settings() { } RS::DOFBokehShape dof_shape = RS::DOFBokehShape(int(GLOBAL_GET("rendering/camera/depth_of_field/depth_of_field_bokeh_shape"))); - RS::get_singleton()->camera_effects_set_dof_blur_bokeh_shape(dof_shape); + RS::get_singleton()->camera_attributes_set_dof_blur_bokeh_shape(dof_shape); RS::DOFBlurQuality dof_quality = RS::DOFBlurQuality(int(GLOBAL_GET("rendering/camera/depth_of_field/depth_of_field_bokeh_quality"))); bool dof_jitter = GLOBAL_GET("rendering/camera/depth_of_field/depth_of_field_use_jitter"); - RS::get_singleton()->camera_effects_set_dof_blur_quality(dof_quality, dof_jitter); + RS::get_singleton()->camera_attributes_set_dof_blur_quality(dof_quality, dof_jitter); RS::get_singleton()->environment_set_ssao_quality(RS::EnvironmentSSAOQuality(int(GLOBAL_GET("rendering/environment/ssao/quality"))), GLOBAL_GET("rendering/environment/ssao/half_size"), GLOBAL_GET("rendering/environment/ssao/adaptive_target"), GLOBAL_GET("rendering/environment/ssao/blur_passes"), GLOBAL_GET("rendering/environment/ssao/fadeout_from"), GLOBAL_GET("rendering/environment/ssao/fadeout_to")); RS::get_singleton()->screen_space_roughness_limiter_set_active(GLOBAL_GET("rendering/anti_aliasing/screen_space_roughness_limiter/enabled"), GLOBAL_GET("rendering/anti_aliasing/screen_space_roughness_limiter/amount"), GLOBAL_GET("rendering/anti_aliasing/screen_space_roughness_limiter/limit")); bool glow_bicubic = int(GLOBAL_GET("rendering/environment/glow/upscale_mode")) > 0; @@ -511,13 +520,13 @@ void EditorNode::_update_from_settings() { float sss_depth_scale = GLOBAL_GET("rendering/environment/subsurface_scattering/subsurface_scattering_depth_scale"); RS::get_singleton()->sub_surface_scattering_set_scale(sss_scale, sss_depth_scale); - uint32_t directional_shadow_size = GLOBAL_GET("rendering/shadows/directional_shadow/size"); - uint32_t directional_shadow_16_bits = GLOBAL_GET("rendering/shadows/directional_shadow/16_bits"); + uint32_t directional_shadow_size = GLOBAL_GET("rendering/lights_and_shadows/directional_shadow/size"); + uint32_t directional_shadow_16_bits = GLOBAL_GET("rendering/lights_and_shadows/directional_shadow/16_bits"); RS::get_singleton()->directional_shadow_atlas_set_size(directional_shadow_size, directional_shadow_16_bits); - RS::ShadowQuality shadows_quality = RS::ShadowQuality(int(GLOBAL_GET("rendering/shadows/positional_shadow/soft_shadow_filter_quality"))); + RS::ShadowQuality shadows_quality = RS::ShadowQuality(int(GLOBAL_GET("rendering/lights_and_shadows/positional_shadow/soft_shadow_filter_quality"))); RS::get_singleton()->positional_soft_shadow_filter_set_quality(shadows_quality); - RS::ShadowQuality directional_shadow_quality = RS::ShadowQuality(int(GLOBAL_GET("rendering/shadows/directional_shadow/soft_shadow_filter_quality"))); + RS::ShadowQuality directional_shadow_quality = RS::ShadowQuality(int(GLOBAL_GET("rendering/lights_and_shadows/directional_shadow/soft_shadow_filter_quality"))); RS::get_singleton()->directional_soft_shadow_filter_set_quality(directional_shadow_quality); float probe_update_speed = GLOBAL_GET("rendering/lightmapping/probe_capture/update_speed"); RS::get_singleton()->lightmap_set_probe_capture_update_speed(probe_update_speed); @@ -544,6 +553,9 @@ void EditorNode::_update_from_settings() { Viewport::SDFScale sdf_scale = Viewport::SDFScale(int(GLOBAL_GET("rendering/2d/sdf/scale"))); scene_root->set_sdf_scale(sdf_scale); + Viewport::MSAA msaa = Viewport::MSAA(int(GLOBAL_GET("rendering/anti_aliasing/quality/msaa_2d"))); + scene_root->set_msaa_2d(msaa); + float mesh_lod_threshold = GLOBAL_GET("rendering/mesh_lod/lod_change/threshold_pixels"); scene_root->set_mesh_lod_threshold(mesh_lod_threshold); @@ -750,6 +762,8 @@ void EditorNode::_notification(int p_what) { gui_base->add_theme_style_override("panel", gui_base->get_theme_stylebox(SNAME("Background"), SNAME("EditorStyles"))); scene_root_parent->add_theme_style_override("panel", gui_base->get_theme_stylebox(SNAME("Content"), SNAME("EditorStyles"))); bottom_panel->add_theme_style_override("panel", gui_base->get_theme_stylebox(SNAME("panel"), SNAME("TabContainer"))); + + tabbar_panel->add_theme_style_override("panel", gui_base->get_theme_stylebox(SNAME("tabbar_background"), SNAME("TabContainer"))); scene_tabs->add_theme_style_override("tab_selected", gui_base->get_theme_stylebox(SNAME("SceneTabFG"), SNAME("EditorStyles"))); scene_tabs->add_theme_style_override("tab_unselected", gui_base->get_theme_stylebox(SNAME("SceneTabBG"), SNAME("EditorStyles"))); @@ -781,6 +795,14 @@ void EditorNode::_notification(int p_what) { _build_icon_type_cache(); + if (write_movie_button->is_pressed()) { + launch_pad->add_theme_style_override("panel", gui_base->get_theme_stylebox(SNAME("LaunchPadMovieMode"), SNAME("EditorStyles"))); + write_movie_panel->add_theme_style_override("panel", gui_base->get_theme_stylebox(SNAME("MovieWriterButtonPressed"), SNAME("EditorStyles"))); + } else { + launch_pad->add_theme_style_override("panel", gui_base->get_theme_stylebox(SNAME("LaunchPadNormal"), SNAME("EditorStyles"))); + write_movie_panel->add_theme_style_override("panel", gui_base->get_theme_stylebox(SNAME("MovieWriterButtonNormal"), SNAME("EditorStyles"))); + } + play_button->set_icon(gui_base->get_theme_icon(SNAME("MainPlay"), SNAME("EditorIcons"))); play_scene_button->set_icon(gui_base->get_theme_icon(SNAME("PlayScene"), SNAME("EditorIcons"))); play_custom_scene_button->set_icon(gui_base->get_theme_icon(SNAME("PlayCustom"), SNAME("EditorIcons"))); @@ -1314,7 +1336,7 @@ void EditorNode::save_resource_as(const Ref<Resource> &p_resource, const String file->set_current_file(p_resource->get_path().get_file()); } else { if (extensions.size()) { - String resource_name_snake_case = p_resource->get_class().camelcase_to_underscore(); + String resource_name_snake_case = p_resource->get_class().to_snake_case(); file->set_current_file("new_" + resource_name_snake_case + "." + preferred.front()->get().to_lower()); } else { file->set_current_file(String()); @@ -1331,7 +1353,7 @@ void EditorNode::save_resource_as(const Ref<Resource> &p_resource, const String } else if (preferred.size()) { String existing; if (extensions.size()) { - String resource_name_snake_case = p_resource->get_class().camelcase_to_underscore(); + String resource_name_snake_case = p_resource->get_class().to_snake_case(); existing = "new_" + resource_name_snake_case + "." + preferred.front()->get().to_lower(); } file->set_current_path(existing); @@ -2402,6 +2424,16 @@ void EditorNode::_edit_current(bool p_skip_foreign) { InspectorDock::get_singleton()->update(current_obj); } +void EditorNode::_write_movie_toggled(bool p_enabled) { + if (p_enabled) { + launch_pad->add_theme_style_override("panel", gui_base->get_theme_stylebox(SNAME("LaunchPadMovieMode"), SNAME("EditorStyles"))); + write_movie_panel->add_theme_style_override("panel", gui_base->get_theme_stylebox(SNAME("MovieWriterButtonPressed"), SNAME("EditorStyles"))); + } else { + launch_pad->add_theme_style_override("panel", gui_base->get_theme_stylebox(SNAME("LaunchPadNormal"), SNAME("EditorStyles"))); + write_movie_panel->add_theme_style_override("panel", gui_base->get_theme_stylebox(SNAME("MovieWriterButtonNormal"), SNAME("EditorStyles"))); + } +} + void EditorNode::_run(bool p_current, const String &p_custom) { if (editor_run.get_status() == EditorRun::STATUS_PLAY) { play_button->set_pressed(!_playing_edited); @@ -2730,10 +2762,10 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) { // Use casing of the root node. break; case SCENE_NAME_CASING_PASCAL_CASE: { - root_name = root_name.capitalize().replace(" ", ""); + root_name = root_name.to_pascal_case(); } break; case SCENE_NAME_CASING_SNAKE_CASE: - root_name = root_name.capitalize().replace(" ", "").replace("-", "_").camelcase_to_underscore(); + root_name = root_name.replace("-", "_").to_snake_case(); break; } file->set_current_path(root_name + "." + extensions.front()->get().to_lower()); @@ -4563,7 +4595,7 @@ void EditorNode::_dock_select_input(const Ref<InputEvent> &p_input) { } if (nrect != dock_select_rect_over_idx) { - dock_select->update(); + dock_select->queue_redraw(); dock_select_rect_over_idx = nrect; } @@ -4589,7 +4621,7 @@ void EditorNode::_dock_select_input(const Ref<InputEvent> &p_input) { dock_popup_selected_idx = nrect; dock_slot[nrect]->set_current_tab(dock_slot[nrect]->get_tab_count() - 1); dock_slot[nrect]->show(); - dock_select->update(); + dock_select->queue_redraw(); _update_dock_containers(); @@ -4601,7 +4633,7 @@ void EditorNode::_dock_select_input(const Ref<InputEvent> &p_input) { void EditorNode::_dock_popup_exit() { dock_select_rect_over_idx = -1; - dock_select->update(); + dock_select->queue_redraw(); } void EditorNode::_dock_pre_popup(int p_which) { @@ -4619,7 +4651,7 @@ void EditorNode::_dock_move_left() { } dock_slot[dock_popup_selected_idx]->move_child(current, prev->get_index()); dock_slot[dock_popup_selected_idx]->set_current_tab(dock_slot[dock_popup_selected_idx]->get_current_tab() - 1); - dock_select->update(); + dock_select->queue_redraw(); _edit_current(); _save_docks(); } @@ -4632,7 +4664,7 @@ void EditorNode::_dock_move_right() { } dock_slot[dock_popup_selected_idx]->move_child(next, current->get_index()); dock_slot[dock_popup_selected_idx]->set_current_tab(dock_slot[dock_popup_selected_idx]->get_current_tab() + 1); - dock_select->update(); + dock_select->queue_redraw(); _edit_current(); _save_docks(); } @@ -6487,8 +6519,11 @@ EditorNode::EditorNode() { tab_preview->set_position(Point2(2, 2) * EDSCALE); tab_preview_panel->add_child(tab_preview); + tabbar_panel = memnew(PanelContainer); + tabbar_panel->add_theme_style_override("panel", gui_base->get_theme_stylebox(SNAME("tabbar_background"), SNAME("TabContainer"))); + srt->add_child(tabbar_panel); tabbar_container = memnew(HBoxContainer); - srt->add_child(tabbar_container); + tabbar_panel->add_child(tabbar_container); scene_tabs = memnew(TabBar); scene_tabs->add_theme_style_override("tab_selected", gui_base->get_theme_stylebox(SNAME("SceneTabFG"), SNAME("EditorStyles"))); @@ -6706,8 +6741,7 @@ EditorNode::EditorNode() { project_menu->add_child(vcs_actions_menu); project_menu->add_submenu_item(TTR("Version Control"), "Version Control"); vcs_actions_menu->add_item(TTR("Create Version Control Metadata"), RUN_VCS_METADATA); - vcs_actions_menu->add_item(TTR("Set Up Version Control"), RUN_VCS_SETTINGS); - vcs_actions_menu->add_item(TTR("Shut Down Version Control"), RUN_VCS_SHUT_DOWN); + vcs_actions_menu->add_item(TTR("Version Control Settings"), RUN_VCS_SETTINGS); project_menu->add_separator(); project_menu->add_shortcut(ED_SHORTCUT_AND_COMMAND("editor/export", TTR("Export..."), Key::NONE, TTR("Export")), FILE_EXPORT_PROJECT); @@ -6822,12 +6856,16 @@ EditorNode::EditorNode() { right_spacer->set_mouse_filter(Control::MOUSE_FILTER_PASS); menu_hb->add_child(right_spacer); - HBoxContainer *play_hb = memnew(HBoxContainer); - menu_hb->add_child(play_hb); + launch_pad = memnew(PanelContainer); + launch_pad->add_theme_style_override("panel", gui_base->get_theme_stylebox(SNAME("LaunchPadNormal"), SNAME("EditorStyles"))); + menu_hb->add_child(launch_pad); + + HBoxContainer *launch_pad_hb = memnew(HBoxContainer); + launch_pad->add_child(launch_pad_hb); play_button = memnew(Button); play_button->set_flat(true); - play_hb->add_child(play_button); + launch_pad_hb->add_child(play_button); play_button->set_toggle_mode(true); play_button->set_focus_mode(Control::FOCUS_NONE); play_button->connect("pressed", callable_mp(this, &EditorNode::_menu_option).bind(RUN_PLAY)); @@ -6843,7 +6881,7 @@ EditorNode::EditorNode() { pause_button->set_focus_mode(Control::FOCUS_NONE); pause_button->set_tooltip_text(TTR("Pause the scene execution for debugging.")); pause_button->set_disabled(true); - play_hb->add_child(pause_button); + launch_pad_hb->add_child(pause_button); ED_SHORTCUT("editor/pause_scene", TTR("Pause Scene"), Key::F7); ED_SHORTCUT_OVERRIDE("editor/pause_scene", "macos", KeyModifierMask::CMD | KeyModifierMask::CTRL | Key::Y); @@ -6851,7 +6889,7 @@ EditorNode::EditorNode() { stop_button = memnew(Button); stop_button->set_flat(true); - play_hb->add_child(stop_button); + launch_pad_hb->add_child(stop_button); stop_button->set_focus_mode(Control::FOCUS_NONE); stop_button->set_icon(gui_base->get_theme_icon(SNAME("Stop"), SNAME("EditorIcons"))); stop_button->connect("pressed", callable_mp(this, &EditorNode::_menu_option).bind(RUN_STOP)); @@ -6863,12 +6901,12 @@ EditorNode::EditorNode() { stop_button->set_shortcut(ED_GET_SHORTCUT("editor/stop")); run_native = memnew(EditorRunNative); - play_hb->add_child(run_native); + launch_pad_hb->add_child(run_native); run_native->connect("native_run", callable_mp(this, &EditorNode::_run_native)); play_scene_button = memnew(Button); play_scene_button->set_flat(true); - play_hb->add_child(play_scene_button); + launch_pad_hb->add_child(play_scene_button); play_scene_button->set_toggle_mode(true); play_scene_button->set_focus_mode(Control::FOCUS_NONE); play_scene_button->connect("pressed", callable_mp(this, &EditorNode::_menu_option).bind(RUN_PLAY_SCENE)); @@ -6879,7 +6917,7 @@ EditorNode::EditorNode() { play_custom_scene_button = memnew(Button); play_custom_scene_button->set_flat(true); - play_hb->add_child(play_custom_scene_button); + launch_pad_hb->add_child(play_custom_scene_button); play_custom_scene_button->set_toggle_mode(true); play_custom_scene_button->set_focus_mode(Control::FOCUS_NONE); play_custom_scene_button->connect("pressed", callable_mp(this, &EditorNode::_menu_option).bind(RUN_PLAY_CUSTOM_SCENE)); @@ -6890,18 +6928,23 @@ EditorNode::EditorNode() { ED_SHORTCUT_OVERRIDE("editor/play_custom_scene", "macos", KeyModifierMask::CMD | KeyModifierMask::SHIFT | Key::R); play_custom_scene_button->set_shortcut(ED_GET_SHORTCUT("editor/play_custom_scene")); + write_movie_panel = memnew(PanelContainer); + write_movie_panel->add_theme_style_override("panel", gui_base->get_theme_stylebox(SNAME("MovieWriterButtonNormal"), SNAME("EditorStyles"))); + launch_pad_hb->add_child(write_movie_panel); + write_movie_button = memnew(Button); write_movie_button->set_flat(true); write_movie_button->set_toggle_mode(true); - play_hb->add_child(write_movie_button); + write_movie_panel->add_child(write_movie_button); write_movie_button->set_pressed(false); write_movie_button->set_icon(gui_base->get_theme_icon(SNAME("MainMovieWrite"), SNAME("EditorIcons"))); write_movie_button->set_focus_mode(Control::FOCUS_NONE); + write_movie_button->connect("toggled", callable_mp(this, &EditorNode::_write_movie_toggled)); write_movie_button->set_tooltip_text(TTR("Enable Movie Maker mode.\nThe project will run at stable FPS and the visual and audio output will be recorded to a video file.")); // This button behaves differently, so color it as such. write_movie_button->add_theme_color_override("icon_normal_color", Color(1, 1, 1, 0.7)); - write_movie_button->add_theme_color_override("icon_pressed_color", gui_base->get_theme_color(SNAME("error_color"), SNAME("Editor"))); + write_movie_button->add_theme_color_override("icon_pressed_color", Color(0, 0, 0, 0.84)); write_movie_button->add_theme_color_override("icon_hover_color", Color(1, 1, 1, 0.9)); HBoxContainer *right_menu_hb = memnew(HBoxContainer); @@ -7486,9 +7529,9 @@ EditorNode::EditorNode() { screenshot_timer->set_owner(get_owner()); // Adjust spacers to center 2D / 3D / Script buttons. - int max_w = MAX(play_hb->get_minimum_size().x + right_menu_hb->get_minimum_size().x, main_menu->get_minimum_size().x); + int max_w = MAX(launch_pad_hb->get_minimum_size().x + right_menu_hb->get_minimum_size().x, main_menu->get_minimum_size().x); left_spacer->set_custom_minimum_size(Size2(MAX(0, max_w - main_menu->get_minimum_size().x), 0)); - right_spacer->set_custom_minimum_size(Size2(MAX(0, max_w - play_hb->get_minimum_size().x - right_menu_hb->get_minimum_size().x), 0)); + right_spacer->set_custom_minimum_size(Size2(MAX(0, max_w - launch_pad_hb->get_minimum_size().x - right_menu_hb->get_minimum_size().x), 0)); // Extend menu bar to window title. if (can_expand) { diff --git a/editor/editor_node.h b/editor/editor_node.h index 792d2fc879..c3b4c985cc 100644 --- a/editor/editor_node.h +++ b/editor/editor_node.h @@ -185,7 +185,6 @@ private: RUN_PROJECT_MANAGER, RUN_VCS_METADATA, RUN_VCS_SETTINGS, - RUN_VCS_SHUT_DOWN, SETTINGS_UPDATE_CONTINUOUSLY, SETTINGS_UPDATE_WHEN_CHANGED, SETTINGS_UPDATE_ALWAYS, @@ -335,15 +334,17 @@ private: PopupMenu *export_as_menu = nullptr; Button *export_button = nullptr; Button *prev_scene = nullptr; + Button *search_button = nullptr; + TextureProgressBar *audio_vu = nullptr; + + PanelContainer *launch_pad = nullptr; Button *play_button = nullptr; Button *pause_button = nullptr; Button *stop_button = nullptr; - Button *run_settings_button = nullptr; Button *play_scene_button = nullptr; Button *play_custom_scene_button = nullptr; - Button *search_button = nullptr; + PanelContainer *write_movie_panel = nullptr; Button *write_movie_button = nullptr; - TextureProgressBar *audio_vu = nullptr; Timer *screenshot_timer = nullptr; @@ -426,6 +427,7 @@ private: int dock_popup_selected_idx = -1; int dock_select_rect_over_idx = -1; + PanelContainer *tabbar_panel = nullptr; HBoxContainer *tabbar_container = nullptr; Button *distraction_free = nullptr; Button *scene_tab_add = nullptr; @@ -581,6 +583,8 @@ private: void _quick_run(); void _open_command_palette(); + void _write_movie_toggled(bool p_enabled); + void _run(bool p_current = false, const String &p_custom = ""); void _run_native(const Ref<EditorExportPreset> &p_preset); void _reset_play_buttons(); diff --git a/editor/editor_plugin.cpp b/editor/editor_plugin.cpp index b0bd500ef8..4fc6947636 100644 --- a/editor/editor_plugin.cpp +++ b/editor/editor_plugin.cpp @@ -599,7 +599,7 @@ int EditorPlugin::update_overlays() const { return count; } else { // This will update the normal viewport itself as well - CanvasItemEditor::get_singleton()->get_viewport_control()->update(); + CanvasItemEditor::get_singleton()->get_viewport_control()->queue_redraw(); return 1; } } diff --git a/editor/editor_plugin_settings.cpp b/editor/editor_plugin_settings.cpp index e5a5a372ad..a8df486381 100644 --- a/editor/editor_plugin_settings.cpp +++ b/editor/editor_plugin_settings.cpp @@ -102,7 +102,7 @@ void EditorPluginSettings::update_plugins() { TreeItem *item = plugin_list->create_item(root); item->set_text(0, name); - item->set_tooltip(0, TTR("Name:") + " " + name + "\n" + TTR("Path:") + " " + path + "\n" + TTR("Main Script:") + " " + script + "\n" + TTR("Description:") + " " + description); + item->set_tooltip_text(0, TTR("Name:") + " " + name + "\n" + TTR("Path:") + " " + path + "\n" + TTR("Main Script:") + " " + script + "\n" + TTR("Description:") + " " + description); item->set_metadata(0, path); item->set_text(1, version); item->set_metadata(1, script); diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp index 0e69c0e2f4..d78fee6ad6 100644 --- a/editor/editor_properties.cpp +++ b/editor/editor_properties.cpp @@ -52,7 +52,7 @@ void EditorPropertyNil::update_property() { EditorPropertyNil::EditorPropertyNil() { Label *label = memnew(Label); - label->set_text("[null]"); + label->set_text("<null>"); add_child(label); } @@ -832,26 +832,35 @@ void EditorPropertyFlags::setup(const Vector<String> &p_options) { bool first = true; uint32_t current_val; for (int i = 0; i < p_options.size(); i++) { + // An empty option is not considered a "flag". String option = p_options[i].strip_edges(); - if (!option.is_empty()) { - CheckBox *cb = memnew(CheckBox); - cb->set_text(option); - cb->set_clip_text(true); - cb->connect("pressed", callable_mp(this, &EditorPropertyFlags::_flag_toggled).bind(i)); - add_focusable(cb); - vbox->add_child(cb); - flags.push_back(cb); - Vector<String> text_split = p_options[i].split(":"); - if (text_split.size() != 1) { - current_val = text_split[1].to_int(); - } else { - current_val = 1 << i; - } - flag_values.push_back(current_val); - if (first) { - set_label_reference(cb); - first = false; - } + if (option.is_empty()) { + continue; + } + const int flag_index = flags.size(); // Index of the next element (added by the code below). + + // Value for a flag can be explicitly overridden. + Vector<String> text_split = p_options[i].split(":"); + if (text_split.size() != 1) { + current_val = text_split[1].to_int(); + } else { + current_val = 1 << i; + } + flag_values.push_back(current_val); + + // Create a CheckBox for the current flag. + CheckBox *cb = memnew(CheckBox); + cb->set_text(option); + cb->set_clip_text(true); + cb->connect("pressed", callable_mp(this, &EditorPropertyFlags::_flag_toggled).bind(flag_index)); + add_focusable(cb); + vbox->add_child(cb); + flags.push_back(cb); + + // Can't use `i == 0` because we want to find the first none-empty option. + if (first) { + set_label_reference(cb); + first = false; } } } @@ -951,7 +960,7 @@ void EditorPropertyLayersGrid::gui_input(const Ref<InputEvent> &p_ev) { bool expand_was_hovered = expand_hovered; expand_hovered = expand_rect.has_point(mm->get_position()); if (expand_hovered != expand_was_hovered) { - update(); + queue_redraw(); } if (!expand_hovered) { @@ -959,7 +968,7 @@ void EditorPropertyLayersGrid::gui_input(const Ref<InputEvent> &p_ev) { if (flag_rects[i].has_point(mm->get_position())) { // Used to highlight the hovered flag in the layers grid. hovered_index = i; - update(); + queue_redraw(); return; } } @@ -968,7 +977,7 @@ void EditorPropertyLayersGrid::gui_input(const Ref<InputEvent> &p_ev) { // Remove highlight when no square is hovered. if (hovered_index != -1) { hovered_index = -1; - update(); + queue_redraw(); } return; @@ -986,11 +995,11 @@ void EditorPropertyLayersGrid::gui_input(const Ref<InputEvent> &p_ev) { } emit_signal(SNAME("flag_changed"), value); - update(); + queue_redraw(); } else if (expand_hovered) { expanded = !expanded; update_minimum_size(); - update(); + queue_redraw(); } } if (mb.is_valid() && mb->get_button_index() == MouseButton::RIGHT && mb->is_pressed()) { @@ -1131,11 +1140,11 @@ void EditorPropertyLayersGrid::_notification(int p_what) { case NOTIFICATION_MOUSE_EXIT: { if (expand_hovered) { expand_hovered = false; - update(); + queue_redraw(); } if (hovered_index != -1) { hovered_index = -1; - update(); + queue_redraw(); } } break; } @@ -1143,7 +1152,7 @@ void EditorPropertyLayersGrid::_notification(int p_what) { void EditorPropertyLayersGrid::set_flag(uint32_t p_flag) { value = p_flag; - update(); + queue_redraw(); } void EditorPropertyLayersGrid::_bind_methods() { @@ -1276,7 +1285,7 @@ void EditorPropertyLayers::_menu_pressed(int p_menu) { } else { grid->value |= (1 << p_menu); } - grid->update(); + grid->queue_redraw(); layers->set_item_checked(layers->get_item_index(p_menu), grid->value & (1 << p_menu)); _grid_changed(grid->value); } @@ -1382,7 +1391,7 @@ void EditorPropertyObjectID::update_property() { edit->set_disabled(false); edit->set_icon(EditorNode::get_singleton()->get_class_icon(type)); } else { - edit->set_text(TTR("[Empty]")); + edit->set_text(TTR("<empty>")); edit->set_disabled(true); edit->set_icon(Ref<Texture2D>()); } @@ -1523,13 +1532,13 @@ void EditorPropertyEasing::_drag_easing(const Ref<InputEvent> &p_ev) { // Ensure the easing doesn't appear as being dragged dragging = false; - easing_draw->update(); + easing_draw->queue_redraw(); } if (mb->get_button_index() == MouseButton::LEFT) { dragging = mb->is_pressed(); // Update to display the correct dragging color - easing_draw->update(); + easing_draw->queue_redraw(); } } @@ -1569,7 +1578,7 @@ void EditorPropertyEasing::_drag_easing(const Ref<InputEvent> &p_ev) { val = CLAMP(val, -1'000'000, 1'000'000); emit_changed(get_edited_property(), val); - easing_draw->update(); + easing_draw->queue_redraw(); } } @@ -1621,14 +1630,14 @@ void EditorPropertyEasing::_draw_easing() { } void EditorPropertyEasing::update_property() { - easing_draw->update(); + easing_draw->queue_redraw(); } void EditorPropertyEasing::_set_preset(int p_preset) { static const float preset_value[EASING_MAX] = { 0.0, 1.0, 2.0, 0.5, -2.0, -0.5 }; emit_changed(get_edited_property(), preset_value[p_preset]); - easing_draw->update(); + easing_draw->queue_redraw(); } void EditorPropertyEasing::_setup_spin() { @@ -1667,7 +1676,7 @@ void EditorPropertyEasing::_spin_focus_exited() { spin->hide(); // Ensure the easing doesn't appear as being dragged dragging = false; - easing_draw->update(); + easing_draw->queue_redraw(); } void EditorPropertyEasing::setup(bool p_positive_only, bool p_flip) { @@ -3952,7 +3961,7 @@ void EditorPropertyResource::_update_property_bg() { } updating_theme = false; - update(); + queue_redraw(); } void EditorPropertyResource::_update_preferred_shader() { diff --git a/editor/editor_properties_array_dict.cpp b/editor/editor_properties_array_dict.cpp index f6953e8866..ad84b30689 100644 --- a/editor/editor_properties_array_dict.cpp +++ b/editor/editor_properties_array_dict.cpp @@ -509,7 +509,7 @@ void EditorPropertyArray::_notification(int p_what) { if (is_visible_in_tree()) { if (_is_drop_valid(get_viewport()->gui_get_drag_data())) { dropping = true; - edit->update(); + edit->queue_redraw(); } } } break; @@ -517,7 +517,7 @@ void EditorPropertyArray::_notification(int p_what) { case NOTIFICATION_DRAG_END: { if (dropping) { dropping = false; - edit->update(); + edit->queue_redraw(); } } break; } diff --git a/editor/editor_resource_picker.cpp b/editor/editor_resource_picker.cpp index ce05026696..f717188b3b 100644 --- a/editor/editor_resource_picker.cpp +++ b/editor/editor_resource_picker.cpp @@ -61,7 +61,7 @@ void EditorResourcePicker::_update_resource() { if (edited_resource == Ref<Resource>()) { assign_button->set_icon(Ref<Texture2D>()); - assign_button->set_text(TTR("[empty]")); + assign_button->set_text(TTR("<empty>")); assign_button->set_tooltip_text(""); } else { assign_button->set_icon(EditorNode::get_singleton()->get_object_icon(edited_resource.operator->(), "Object")); @@ -775,14 +775,14 @@ void EditorResourcePicker::_notification(int p_what) { case NOTIFICATION_DRAG_BEGIN: { if (editable && _is_drop_valid(get_viewport()->gui_get_drag_data())) { dropping = true; - assign_button->update(); + assign_button->queue_redraw(); } } break; case NOTIFICATION_DRAG_END: { if (dropping) { dropping = false; - assign_button->update(); + assign_button->queue_redraw(); } } break; } @@ -1049,7 +1049,7 @@ void EditorAudioStreamPicker::_notification(int p_what) { Ref<AudioStreamPreview> preview = AudioStreamPreviewGenerator::get_singleton()->generate_preview(audio_stream); if (preview.is_valid()) { if (preview->get_version() != last_preview_version) { - stream_preview_rect->update(); + stream_preview_rect->queue_redraw(); last_preview_version = preview->get_version(); } } @@ -1083,10 +1083,10 @@ void EditorAudioStreamPicker::_notification(int p_what) { } } - stream_preview_rect->update(); + stream_preview_rect->queue_redraw(); } else { if (tagged_frame_offset_count != 0) { - stream_preview_rect->update(); + stream_preview_rect->queue_redraw(); } tagged_frame_offset_count = 0; } @@ -1107,13 +1107,13 @@ void EditorAudioStreamPicker::_update_resource() { set_assign_button_min_size(Size2(1, font->get_height(font_size) * 1.5)); } - stream_preview_rect->update(); + stream_preview_rect->queue_redraw(); } void EditorAudioStreamPicker::_preview_draw() { Ref<AudioStream> audio_stream = get_edited_resource(); if (!audio_stream.is_valid()) { - get_assign_button()->set_text(TTR("[empty]")); + get_assign_button()->set_text(TTR("<empty>")); return; } diff --git a/editor/editor_run.cpp b/editor/editor_run.cpp index 3b828951e4..b909129b18 100644 --- a/editor/editor_run.cpp +++ b/editor/editor_run.cpp @@ -258,6 +258,11 @@ Error EditorRun::run(const String &p_scene, const String &p_write_movie) { } } + // Pass the debugger stop shortcut to the running instance(s). + String shortcut; + VariantWriter::write_to_string(ED_GET_SHORTCUT("editor/stop"), shortcut); + OS::get_singleton()->set_environment("__GODOT_EDITOR_STOP_SHORTCUT__", shortcut); + printf("Running: %s", exec.utf8().get_data()); for (const String &E : args) { printf(" %s", E.utf8().get_data()); diff --git a/editor/editor_sectioned_inspector.cpp b/editor/editor_sectioned_inspector.cpp index 1faefb5af7..94ee741db5 100644 --- a/editor/editor_sectioned_inspector.cpp +++ b/editor/editor_sectioned_inspector.cpp @@ -283,7 +283,7 @@ void SectionedInspector::update_category_list() { const String tooltip = EditorPropertyNameProcessor::get_singleton()->process_name(sectionarr[i], tooltip_style); ms->set_text(0, text); - ms->set_tooltip(0, tooltip); + ms->set_tooltip_text(0, tooltip); ms->set_metadata(0, metasection); ms->set_selectable(0, false); } diff --git a/editor/editor_settings_dialog.cpp b/editor/editor_settings_dialog.cpp index 67c602ad2d..d190ab57c3 100644 --- a/editor/editor_settings_dialog.cpp +++ b/editor/editor_settings_dialog.cpp @@ -440,7 +440,7 @@ void EditorSettingsDialog::_update_shortcuts() { const String tooltip = EditorPropertyNameProcessor::get_singleton()->process_name(section_name, tooltip_style); section->set_text(0, item_name); - section->set_tooltip(0, tooltip); + section->set_tooltip_text(0, tooltip); section->set_selectable(0, false); section->set_selectable(1, false); section->set_custom_bg_color(0, shortcuts->get_theme_color(SNAME("prop_subsection"), SNAME("Editor"))); diff --git a/editor/editor_spin_slider.cpp b/editor/editor_spin_slider.cpp index b9a3e9decf..33632649c8 100644 --- a/editor/editor_spin_slider.cpp +++ b/editor/editor_spin_slider.cpp @@ -82,7 +82,7 @@ void EditorSpinSlider::gui_input(const Ref<InputEvent> &p_event) { if (grabbing_spinner) { Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_VISIBLE); Input::get_singleton()->warp_mouse(grabbing_spinner_mouse_pos); - update(); + queue_redraw(); } else { _focus_entered(); } @@ -93,7 +93,7 @@ void EditorSpinSlider::gui_input(const Ref<InputEvent> &p_event) { } } else if (mb->get_button_index() == MouseButton::WHEEL_UP || mb->get_button_index() == MouseButton::WHEEL_DOWN) { if (grabber->is_visible()) { - call_deferred(SNAME("update")); + call_deferred(SNAME("queue_redraw")); } } } @@ -137,7 +137,7 @@ void EditorSpinSlider::gui_input(const Ref<InputEvent> &p_event) { bool new_hover = (mm->get_position().x > updown_offset); if (new_hover != hover_updown) { hover_updown = new_hover; - update(); + queue_redraw(); } } } @@ -155,6 +155,10 @@ void EditorSpinSlider::_grabber_gui_input(const Ref<InputEvent> &p_event) { Ref<InputEventMouseButton> mb = p_event; + if (is_read_only()) { + return; + } + if (grabbing_grabber) { if (mb.is_valid()) { if (mb->get_button_index() == MouseButton::WHEEL_UP) { @@ -190,13 +194,13 @@ void EditorSpinSlider::_grabber_gui_input(const Ref<InputEvent> &p_event) { ERR_FAIL_COND(Math::is_zero_approx(scale_x)); float grabbing_ofs = (grabber->get_transform().xform(mm->get_position()).x - grabbing_from) / float(grabber_range) / scale_x; set_as_ratio(grabbing_ratio + grabbing_ofs); - update(); + queue_redraw(); } } void EditorSpinSlider::_value_input_gui_input(const Ref<InputEvent> &p_event) { Ref<InputEventKey> k = p_event; - if (k.is_valid() && k->is_pressed()) { + if (k.is_valid() && k->is_pressed() && !is_read_only()) { double step = get_step(); double real_step = step; if (step < 1) { @@ -463,12 +467,12 @@ void EditorSpinSlider::_notification(int p_what) { case NOTIFICATION_MOUSE_ENTER: { mouse_over_spin = true; - update(); + queue_redraw(); } break; case NOTIFICATION_MOUSE_EXIT: { mouse_over_spin = false; - update(); + queue_redraw(); } break; case NOTIFICATION_FOCUS_ENTER: { @@ -498,7 +502,7 @@ Size2 EditorSpinSlider::get_minimum_size() const { void EditorSpinSlider::set_hide_slider(bool p_hide) { hide_slider = p_hide; - update(); + queue_redraw(); } bool EditorSpinSlider::is_hiding_slider() const { @@ -507,7 +511,7 @@ bool EditorSpinSlider::is_hiding_slider() const { void EditorSpinSlider::set_label(const String &p_label) { label = p_label; - update(); + queue_redraw(); } String EditorSpinSlider::get_label() const { @@ -516,7 +520,7 @@ String EditorSpinSlider::get_label() const { void EditorSpinSlider::set_suffix(const String &p_suffix) { suffix = p_suffix; - update(); + queue_redraw(); } String EditorSpinSlider::get_suffix() const { @@ -583,17 +587,17 @@ void EditorSpinSlider::_value_focus_exited() { void EditorSpinSlider::_grabber_mouse_entered() { mouse_over_grabber = true; - update(); + queue_redraw(); } void EditorSpinSlider::_grabber_mouse_exited() { mouse_over_grabber = false; - update(); + queue_redraw(); } void EditorSpinSlider::set_read_only(bool p_enable) { read_only = p_enable; - update(); + queue_redraw(); } bool EditorSpinSlider::is_read_only() const { @@ -602,7 +606,7 @@ bool EditorSpinSlider::is_read_only() const { void EditorSpinSlider::set_flat(bool p_enable) { flat = p_enable; - update(); + queue_redraw(); } bool EditorSpinSlider::is_flat() const { diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp index d20caef51c..af0e40d1d4 100644 --- a/editor/editor_themes.cpp +++ b/editor/editor_themes.cpp @@ -656,45 +656,46 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { // TabBar - Ref<StyleBoxFlat> style_tab_selected = style_widget->duplicate(); + Ref<StyleBoxFlat> style_tab_base = style_widget->duplicate(); - // Add a highlight line at the top of the selected tab. - style_tab_selected->set_border_width_all(0); - style_tab_selected->set_default_margin(SIDE_LEFT, widget_default_margin.x - border_width); - style_tab_selected->set_border_width(SIDE_TOP, Math::round(2 * EDSCALE)); - // Make the highlight line prominent, but not too prominent as to not be distracting. - Color tab_highlight = dark_color_2.lerp(accent_color, 0.75); - style_tab_selected->set_border_color(tab_highlight); + style_tab_base->set_border_width_all(0); // Don't round the top corners to avoid creating a small blank space between the tabs and the main panel. // This also makes the top highlight look better. - style_tab_selected->set_corner_radius_all(0); + style_tab_base->set_corner_detail(corner_width); + style_tab_base->set_corner_radius_all(0); + style_tab_base->set_corner_radius(CORNER_TOP_LEFT, corner_radius * EDSCALE); + style_tab_base->set_corner_radius(CORNER_TOP_RIGHT, corner_radius * EDSCALE); // Prevent visible artifacts and cover the top-left rounded corner of the panel below the tab if selected // We can't prevent them with both rounded corners and non-zero border width, though - style_tab_selected->set_expand_margin_size(SIDE_BOTTOM, corner_width > 0 ? corner_width : border_width); - + style_tab_base->set_expand_margin_size(SIDE_BOTTOM, corner_width > 0 ? corner_width : border_width); // When using a border width greater than 0, visually line up the left of the selected tab with the underlying panel. - style_tab_selected->set_expand_margin_size(SIDE_LEFT, -border_width); + style_tab_base->set_expand_margin_size(SIDE_LEFT, -border_width); + + style_tab_base->set_default_margin(SIDE_LEFT, widget_default_margin.x + 5 * EDSCALE); + style_tab_base->set_default_margin(SIDE_RIGHT, widget_default_margin.x + 5 * EDSCALE); + style_tab_base->set_default_margin(SIDE_BOTTOM, widget_default_margin.y); + style_tab_base->set_default_margin(SIDE_TOP, widget_default_margin.y); + + Ref<StyleBoxFlat> style_tab_selected = style_tab_base->duplicate(); - style_tab_selected->set_default_margin(SIDE_LEFT, widget_default_margin.x + 2 * EDSCALE); - style_tab_selected->set_default_margin(SIDE_RIGHT, widget_default_margin.x + 2 * EDSCALE); - style_tab_selected->set_default_margin(SIDE_BOTTOM, widget_default_margin.y); - style_tab_selected->set_default_margin(SIDE_TOP, widget_default_margin.y); style_tab_selected->set_bg_color(base_color); + // Add a highlight line at the top of the selected tab. + style_tab_selected->set_border_width(SIDE_TOP, Math::round(2 * EDSCALE)); + // Make the highlight line prominent, but not too prominent as to not be distracting. + Color tab_highlight = dark_color_2.lerp(accent_color, 0.75); + style_tab_selected->set_border_color(tab_highlight); + style_tab_selected->set_corner_radius_all(0); - Ref<StyleBoxFlat> style_tab_unselected = style_tab_selected->duplicate(); - style_tab_unselected->set_bg_color(dark_color_1); + Ref<StyleBoxFlat> style_tab_unselected = style_tab_base->duplicate(); style_tab_unselected->set_expand_margin_size(SIDE_BOTTOM, 0); + style_tab_unselected->set_bg_color(dark_color_1); // Add some spacing between unselected tabs to make them easier to distinguish from each other style_tab_unselected->set_border_color(Color(0, 0, 0, 0)); - style_tab_unselected->set_border_width(SIDE_LEFT, Math::round(1 * EDSCALE)); - style_tab_unselected->set_border_width(SIDE_RIGHT, Math::round(1 * EDSCALE)); - style_tab_unselected->set_default_margin(SIDE_LEFT, widget_default_margin.x + 2 * EDSCALE); - style_tab_unselected->set_default_margin(SIDE_RIGHT, widget_default_margin.x + 2 * EDSCALE); - Ref<StyleBoxFlat> style_tab_disabled = style_tab_selected->duplicate(); - style_tab_disabled->set_bg_color(disabled_bg_color); + Ref<StyleBoxFlat> style_tab_disabled = style_tab_base->duplicate(); style_tab_disabled->set_expand_margin_size(SIDE_BOTTOM, 0); + style_tab_disabled->set_bg_color(disabled_bg_color); style_tab_disabled->set_border_color(disabled_bg_color); // Editor background @@ -740,8 +741,26 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_stylebox("ScriptEditorPanel", "EditorStyles", make_empty_stylebox(default_margin_size, 0, default_margin_size, default_margin_size)); theme->set_stylebox("ScriptEditor", "EditorStyles", make_empty_stylebox(0, 0, 0, 0)); - // Play button group - theme->set_stylebox("PlayButtonPanel", "EditorStyles", style_empty); + // Launch Pad and Play buttons + Ref<StyleBoxFlat> style_launch_pad = make_flat_stylebox(dark_color_1, 2 * EDSCALE, 0, 2 * EDSCALE, 0, corner_width); + style_launch_pad->set_corner_radius_all(corner_radius * EDSCALE); + theme->set_stylebox("LaunchPadNormal", "EditorStyles", style_launch_pad); + Ref<StyleBoxFlat> style_launch_pad_movie = style_launch_pad->duplicate(); + style_launch_pad_movie->set_bg_color(accent_color * Color(1, 1, 1, 0.1)); + style_launch_pad_movie->set_border_color(accent_color); + style_launch_pad_movie->set_border_width_all(Math::round(2 * EDSCALE)); + theme->set_stylebox("LaunchPadMovieMode", "EditorStyles", style_launch_pad_movie); + + theme->set_stylebox("MovieWriterButtonNormal", "EditorStyles", make_empty_stylebox(0, 0, 0, 0)); + Ref<StyleBoxFlat> style_write_movie_button = style_widget_pressed->duplicate(); + style_write_movie_button->set_bg_color(accent_color); + style_write_movie_button->set_corner_radius_all(corner_radius * EDSCALE); + style_write_movie_button->set_default_margin(SIDE_TOP, 0); + style_write_movie_button->set_default_margin(SIDE_BOTTOM, 0); + style_write_movie_button->set_default_margin(SIDE_LEFT, 0); + style_write_movie_button->set_default_margin(SIDE_RIGHT, 0); + style_write_movie_button->set_expand_margin_size(SIDE_RIGHT, 2 * EDSCALE); + theme->set_stylebox("MovieWriterButtonPressed", "EditorStyles", style_write_movie_button); theme->set_stylebox("normal", "MenuButton", style_menu); theme->set_stylebox("hover", "MenuButton", style_widget_hover); @@ -1199,6 +1218,13 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_constant("line_separation", "ItemList", 3 * EDSCALE); // TabBar & TabContainer + Ref<StyleBoxFlat> style_tabbar_background = make_flat_stylebox(dark_color_1, 0, 0, 0, 0); + style_tabbar_background->set_expand_margin_size(SIDE_BOTTOM, corner_width > 0 ? corner_width : border_width); + style_tabbar_background->set_corner_detail(corner_width); + style_tabbar_background->set_corner_radius(CORNER_TOP_LEFT, corner_radius * EDSCALE); + style_tabbar_background->set_corner_radius(CORNER_TOP_RIGHT, corner_radius * EDSCALE); + theme->set_stylebox("tabbar_background", "TabContainer", style_tabbar_background); + theme->set_stylebox("tab_selected", "TabContainer", style_tab_selected); theme->set_stylebox("tab_unselected", "TabContainer", style_tab_unselected); theme->set_stylebox("tab_disabled", "TabContainer", style_tab_disabled); @@ -1234,14 +1260,14 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { Ref<StyleBoxFlat> style_content_panel = style_default->duplicate(); style_content_panel->set_border_color(dark_color_3); style_content_panel->set_border_width_all(border_width); + style_content_panel->set_border_width(Side::SIDE_TOP, 0); + style_content_panel->set_corner_radius(CORNER_TOP_LEFT, 0); + style_content_panel->set_corner_radius(CORNER_TOP_RIGHT, 0); // compensate the border style_content_panel->set_default_margin(SIDE_TOP, (2 + margin_size_extra) * EDSCALE); style_content_panel->set_default_margin(SIDE_RIGHT, margin_size_extra * EDSCALE); style_content_panel->set_default_margin(SIDE_BOTTOM, margin_size_extra * EDSCALE); style_content_panel->set_default_margin(SIDE_LEFT, margin_size_extra * EDSCALE); - // Display border to visually split the body of the container from its possible backgrounds. - style_content_panel->set_border_width(Side::SIDE_TOP, Math::round(2 * EDSCALE)); - style_content_panel->set_border_color(dark_color_2); theme->set_stylebox("panel", "TabContainer", style_content_panel); // TabContainerOdd can be used on tabs against the base color background (e.g. nested tabs). diff --git a/editor/editor_toaster.cpp b/editor/editor_toaster.cpp index bb29b1c171..5b015fc95c 100644 --- a/editor/editor_toaster.cpp +++ b/editor/editor_toaster.cpp @@ -62,7 +62,7 @@ void EditorToaster::_notification(int p_what) { if (toasts[element.key].remaining_time < 0) { close(element.key); } - element.key->update(); + element.key->queue_redraw(); } } else { // Reset the timers when hovered. @@ -71,7 +71,7 @@ void EditorToaster::_notification(int p_what) { continue; } toasts[element.key].remaining_time = element.value.duration; - element.key->update(); + element.key->queue_redraw(); } } @@ -101,7 +101,7 @@ void EditorToaster::_notification(int p_what) { if (needs_update) { _update_vbox_position(); _update_disable_notifications_button(); - main_button->update(); + main_button->queue_redraw(); } } break; @@ -132,8 +132,8 @@ void EditorToaster::_notification(int p_what) { error_panel_style_progress->set_bg_color(get_theme_color(SNAME("base_color"), SNAME("Editor")).lightened(0.03)); error_panel_style_progress->set_border_color(get_theme_color(SNAME("error_color"), SNAME("Editor"))); - main_button->update(); - disable_notifications_button->update(); + main_button->queue_redraw(); + disable_notifications_button->queue_redraw(); } break; case NOTIFICATION_TRANSFORM_CHANGED: { @@ -334,7 +334,7 @@ void EditorToaster::_repop_old() { if (needs_update) { _update_vbox_position(); _update_disable_notifications_button(); - main_button->update(); + main_button->queue_redraw(); } } @@ -389,7 +389,7 @@ Control *EditorToaster::popup(Control *p_control, Severity p_severity, double p_ _auto_hide_or_free_toasts(); _update_vbox_position(); _update_disable_notifications_button(); - main_button->update(); + main_button->queue_redraw(); return panel; } @@ -438,7 +438,7 @@ void EditorToaster::_popup_str(String p_message, Severity p_severity, String p_t _auto_hide_or_free_toasts(); _update_vbox_position(); _update_disable_notifications_button(); - main_button->update(); + main_button->queue_redraw(); } // Retrieve the label back then update the text. diff --git a/editor/editor_vcs_interface.cpp b/editor/editor_vcs_interface.cpp index 53cc8d5b22..0c6c876b2f 100644 --- a/editor/editor_vcs_interface.cpp +++ b/editor/editor_vcs_interface.cpp @@ -30,132 +30,371 @@ #include "editor_vcs_interface.h" +#include "editor_node.h" + +#define UNIMPLEMENTED() ERR_PRINT(vformat("Unimplemented virtual function in EditorVCSInterface based plugin: %s", __func__)) + EditorVCSInterface *EditorVCSInterface::singleton = nullptr; -void EditorVCSInterface::_bind_methods() { - // Proxy end points that act as fallbacks to unavailability of a function in the VCS addon - ClassDB::bind_method(D_METHOD("_initialize", "project_root_path"), &EditorVCSInterface::_initialize); - ClassDB::bind_method(D_METHOD("_is_vcs_initialized"), &EditorVCSInterface::_is_vcs_initialized); - ClassDB::bind_method(D_METHOD("_get_vcs_name"), &EditorVCSInterface::_get_vcs_name); - ClassDB::bind_method(D_METHOD("_shut_down"), &EditorVCSInterface::_shut_down); - ClassDB::bind_method(D_METHOD("_get_project_name"), &EditorVCSInterface::_get_project_name); - ClassDB::bind_method(D_METHOD("_get_modified_files_data"), &EditorVCSInterface::_get_modified_files_data); - ClassDB::bind_method(D_METHOD("_commit", "msg"), &EditorVCSInterface::_commit); - ClassDB::bind_method(D_METHOD("_get_file_diff", "file_path"), &EditorVCSInterface::_get_file_diff); - ClassDB::bind_method(D_METHOD("_stage_file", "file_path"), &EditorVCSInterface::_stage_file); - ClassDB::bind_method(D_METHOD("_unstage_file", "file_path"), &EditorVCSInterface::_unstage_file); +void EditorVCSInterface::popup_error(String p_msg) { + // TRANSLATORS: %s refers to the name of a version control system (e.g. "Git"). + EditorNode::get_singleton()->show_warning(p_msg.strip_edges(), vformat(TTR("%s Error"), get_vcs_name())); +} - ClassDB::bind_method(D_METHOD("is_addon_ready"), &EditorVCSInterface::is_addon_ready); +bool EditorVCSInterface::initialize(String p_project_path) { + bool result = false; + if (!GDVIRTUAL_CALL(_initialize, p_project_path, result)) { + UNIMPLEMENTED(); + return false; + } + return result; +} - // API methods that redirect calls to the proxy end points - ClassDB::bind_method(D_METHOD("initialize", "project_root_path"), &EditorVCSInterface::initialize); - ClassDB::bind_method(D_METHOD("is_vcs_initialized"), &EditorVCSInterface::is_vcs_initialized); - ClassDB::bind_method(D_METHOD("get_modified_files_data"), &EditorVCSInterface::get_modified_files_data); - ClassDB::bind_method(D_METHOD("stage_file", "file_path"), &EditorVCSInterface::stage_file); - ClassDB::bind_method(D_METHOD("unstage_file", "file_path"), &EditorVCSInterface::unstage_file); - ClassDB::bind_method(D_METHOD("commit", "msg"), &EditorVCSInterface::commit); - ClassDB::bind_method(D_METHOD("get_file_diff", "file_path"), &EditorVCSInterface::get_file_diff); - ClassDB::bind_method(D_METHOD("shut_down"), &EditorVCSInterface::shut_down); - ClassDB::bind_method(D_METHOD("get_project_name"), &EditorVCSInterface::get_project_name); - ClassDB::bind_method(D_METHOD("get_vcs_name"), &EditorVCSInterface::get_vcs_name); +void EditorVCSInterface::set_credentials(String p_username, String p_password, String p_ssh_public_key, String p_ssh_private_key, String p_ssh_passphrase) { + if (!GDVIRTUAL_CALL(_set_credentials, p_username, p_password, p_ssh_public_key, p_ssh_private_key, p_ssh_passphrase)) { + UNIMPLEMENTED(); + } } -bool EditorVCSInterface::_initialize(String p_project_root_path) { - WARN_PRINT("Selected VCS addon does not implement an initialization function. This warning will be suppressed."); - return true; +List<String> EditorVCSInterface::get_remotes() { + Array result; + if (!GDVIRTUAL_CALL(_get_remotes, result)) { + UNIMPLEMENTED(); + return {}; + } + + List<String> remotes; + for (int i = 0; i < result.size(); i++) { + remotes.push_back(result[i]); + } + return remotes; } -bool EditorVCSInterface::_is_vcs_initialized() { - return false; +List<EditorVCSInterface::StatusFile> EditorVCSInterface::get_modified_files_data() { + Array result; + if (!GDVIRTUAL_CALL(_get_modified_files_data, result)) { + UNIMPLEMENTED(); + return {}; + } + + List<EditorVCSInterface::StatusFile> status_files; + for (int i = 0; i < result.size(); i++) { + status_files.push_back(_convert_status_file(result[i])); + } + return status_files; } -Dictionary EditorVCSInterface::_get_modified_files_data() { - return Dictionary(); +void EditorVCSInterface::stage_file(String p_file_path) { + if (!GDVIRTUAL_CALL(_stage_file, p_file_path)) { + UNIMPLEMENTED(); + } } -void EditorVCSInterface::_stage_file(String p_file_path) { +void EditorVCSInterface::unstage_file(String p_file_path) { + if (!GDVIRTUAL_CALL(_unstage_file, p_file_path)) { + UNIMPLEMENTED(); + } } -void EditorVCSInterface::_unstage_file(String p_file_path) { +void EditorVCSInterface::discard_file(String p_file_path) { + if (!GDVIRTUAL_CALL(_discard_file, p_file_path)) { + UNIMPLEMENTED(); + } } -void EditorVCSInterface::_commit(String p_msg) { +void EditorVCSInterface::commit(String p_msg) { + if (!GDVIRTUAL_CALL(_commit, p_msg)) { + UNIMPLEMENTED(); + } } -TypedArray<Dictionary> EditorVCSInterface::_get_file_diff(String p_file_path) { - return TypedArray<Dictionary>(); +List<EditorVCSInterface::DiffFile> EditorVCSInterface::get_diff(String p_identifier, TreeArea p_area) { + TypedArray<Dictionary> result; + if (!GDVIRTUAL_CALL(_get_diff, p_identifier, int(p_area), result)) { + UNIMPLEMENTED(); + return {}; + } + + List<DiffFile> diff_files; + for (int i = 0; i < result.size(); i++) { + diff_files.push_back(_convert_diff_file(result[i])); + } + return diff_files; } -bool EditorVCSInterface::_shut_down() { - return false; +List<EditorVCSInterface::Commit> EditorVCSInterface::get_previous_commits(int p_max_commits) { + Array result; + if (!GDVIRTUAL_CALL(_get_previous_commits, p_max_commits, result)) { + UNIMPLEMENTED(); + return {}; + } + + List<EditorVCSInterface::Commit> commits; + for (int i = 0; i < result.size(); i++) { + commits.push_back(_convert_commit(result[i])); + } + return commits; } -String EditorVCSInterface::_get_project_name() { - return String(); +List<String> EditorVCSInterface::get_branch_list() { + Array result; + if (!GDVIRTUAL_CALL(_get_branch_list, result)) { + UNIMPLEMENTED(); + return {}; + } + + List<String> branch_list; + for (int i = 0; i < result.size(); i++) { + branch_list.push_back(result[i]); + } + return branch_list; } -String EditorVCSInterface::_get_vcs_name() { - return ""; +void EditorVCSInterface::create_branch(String p_branch_name) { + if (!GDVIRTUAL_CALL(_create_branch, p_branch_name)) { + UNIMPLEMENTED(); + } } -bool EditorVCSInterface::initialize(String p_project_root_path) { - is_initialized = call("_initialize", p_project_root_path); - return is_initialized; +void EditorVCSInterface::create_remote(String p_remote_name, String p_remote_url) { + if (!GDVIRTUAL_CALL(_create_remote, p_remote_name, p_remote_url)) { + UNIMPLEMENTED(); + } } -bool EditorVCSInterface::is_vcs_initialized() { - return call("_is_vcs_initialized"); +void EditorVCSInterface::remove_branch(String p_branch_name) { + if (!GDVIRTUAL_CALL(_remove_branch, p_branch_name)) { + UNIMPLEMENTED(); + } } -Dictionary EditorVCSInterface::get_modified_files_data() { - return call("_get_modified_files_data"); +void EditorVCSInterface::remove_remote(String p_remote_name) { + if (!GDVIRTUAL_CALL(_remove_remote, p_remote_name)) { + UNIMPLEMENTED(); + } } -void EditorVCSInterface::stage_file(String p_file_path) { - if (is_addon_ready()) { - call("_stage_file", p_file_path); +String EditorVCSInterface::get_current_branch_name() { + String result; + if (!GDVIRTUAL_CALL(_get_current_branch_name, result)) { + UNIMPLEMENTED(); + return ""; } + return result; } -void EditorVCSInterface::unstage_file(String p_file_path) { - if (is_addon_ready()) { - call("_unstage_file", p_file_path); +bool EditorVCSInterface::checkout_branch(String p_branch_name) { + bool result = false; + if (!GDVIRTUAL_CALL(_checkout_branch, p_branch_name, result)) { + UNIMPLEMENTED(); } + return result; } -bool EditorVCSInterface::is_addon_ready() { - return is_initialized; +void EditorVCSInterface::pull(String p_remote) { + if (!GDVIRTUAL_CALL(_pull, p_remote)) { + UNIMPLEMENTED(); + } } -void EditorVCSInterface::commit(String p_msg) { - if (is_addon_ready()) { - call("_commit", p_msg); +void EditorVCSInterface::push(String p_remote, bool p_force) { + if (!GDVIRTUAL_CALL(_push, p_remote, p_force)) { + UNIMPLEMENTED(); } } -TypedArray<Dictionary> EditorVCSInterface::get_file_diff(String p_file_path) { - if (is_addon_ready()) { - return call("_get_file_diff", p_file_path); +void EditorVCSInterface::fetch(String p_remote) { + if (!GDVIRTUAL_CALL(_fetch, p_remote)) { + UNIMPLEMENTED(); } - return TypedArray<Dictionary>(); } -bool EditorVCSInterface::shut_down() { - return call("_shut_down"); +List<EditorVCSInterface::DiffHunk> EditorVCSInterface::get_line_diff(String p_file_path, String p_text) { + Array result; + if (!GDVIRTUAL_CALL(_get_line_diff, p_file_path, p_text, result)) { + UNIMPLEMENTED(); + return {}; + } + + List<DiffHunk> diff_hunks; + for (int i = 0; i < result.size(); i++) { + diff_hunks.push_back(_convert_diff_hunk(result[i])); + } + return diff_hunks; } -String EditorVCSInterface::get_project_name() { - return call("_get_project_name"); +bool EditorVCSInterface::shut_down() { + bool result = false; + if (!GDVIRTUAL_CALL(_shut_down, result)) { + UNIMPLEMENTED(); + return false; + } + return result; } String EditorVCSInterface::get_vcs_name() { - return call("_get_vcs_name"); + String result; + if (!GDVIRTUAL_CALL(_get_vcs_name, result)) { + UNIMPLEMENTED(); + return {}; + } + return result; +} + +Dictionary EditorVCSInterface::create_diff_line(int p_new_line_no, int p_old_line_no, String p_content, String p_status) { + Dictionary diff_line; + diff_line["new_line_no"] = p_new_line_no; + diff_line["old_line_no"] = p_old_line_no; + diff_line["content"] = p_content; + diff_line["status"] = p_status; + + return diff_line; +} + +Dictionary EditorVCSInterface::create_diff_hunk(int p_old_start, int p_new_start, int p_old_lines, int p_new_lines) { + Dictionary diff_hunk; + diff_hunk["new_lines"] = p_new_lines; + diff_hunk["old_lines"] = p_old_lines; + diff_hunk["new_start"] = p_new_start; + diff_hunk["old_start"] = p_old_start; + diff_hunk["diff_lines"] = Array(); + return diff_hunk; +} + +Dictionary EditorVCSInterface::add_line_diffs_into_diff_hunk(Dictionary p_diff_hunk, Array p_line_diffs) { + p_diff_hunk["diff_lines"] = p_line_diffs; + return p_diff_hunk; +} + +Dictionary EditorVCSInterface::create_diff_file(String p_new_file, String p_old_file) { + Dictionary file_diff; + file_diff["new_file"] = p_new_file; + file_diff["old_file"] = p_old_file; + file_diff["diff_hunks"] = Array(); + return file_diff; +} + +Dictionary EditorVCSInterface::create_commit(String p_msg, String p_author, String p_id, int64_t p_unix_timestamp, int64_t p_offset_minutes) { + Dictionary commit_info; + commit_info["message"] = p_msg; + commit_info["author"] = p_author; + commit_info["unix_timestamp"] = p_unix_timestamp; + commit_info["offset_minutes"] = p_offset_minutes; + commit_info["id"] = p_id; + return commit_info; } -EditorVCSInterface::EditorVCSInterface() { +Dictionary EditorVCSInterface::add_diff_hunks_into_diff_file(Dictionary p_diff_file, Array p_diff_hunks) { + p_diff_file["diff_hunks"] = p_diff_hunks; + return p_diff_file; } -EditorVCSInterface::~EditorVCSInterface() { +Dictionary EditorVCSInterface::create_status_file(String p_file_path, ChangeType p_change, TreeArea p_area) { + Dictionary sf; + sf["file_path"] = p_file_path; + sf["change_type"] = p_change; + sf["area"] = p_area; + return sf; +} + +EditorVCSInterface::DiffLine EditorVCSInterface::_convert_diff_line(Dictionary p_diff_line) { + DiffLine d; + d.new_line_no = p_diff_line["new_line_no"]; + d.old_line_no = p_diff_line["old_line_no"]; + d.content = p_diff_line["content"]; + d.status = p_diff_line["status"]; + return d; +} + +EditorVCSInterface::DiffHunk EditorVCSInterface::_convert_diff_hunk(Dictionary p_diff_hunk) { + DiffHunk dh; + dh.new_lines = p_diff_hunk["new_lines"]; + dh.old_lines = p_diff_hunk["old_lines"]; + dh.new_start = p_diff_hunk["new_start"]; + dh.old_start = p_diff_hunk["old_start"]; + Array diff_lines = p_diff_hunk["diff_lines"]; + for (int i = 0; i < diff_lines.size(); i++) { + DiffLine dl = _convert_diff_line(diff_lines[i]); + dh.diff_lines.push_back(dl); + } + return dh; +} + +EditorVCSInterface::DiffFile EditorVCSInterface::_convert_diff_file(Dictionary p_diff_file) { + DiffFile df; + df.new_file = p_diff_file["new_file"]; + df.old_file = p_diff_file["old_file"]; + Array diff_hunks = p_diff_file["diff_hunks"]; + for (int i = 0; i < diff_hunks.size(); i++) { + DiffHunk dh = _convert_diff_hunk(diff_hunks[i]); + df.diff_hunks.push_back(dh); + } + return df; +} + +EditorVCSInterface::Commit EditorVCSInterface::_convert_commit(Dictionary p_commit) { + EditorVCSInterface::Commit c; + c.msg = p_commit["message"]; + c.author = p_commit["author"]; + c.unix_timestamp = p_commit["unix_timestamp"]; + c.offset_minutes = p_commit["offset_minutes"]; + c.id = p_commit["id"]; + return c; +} + +EditorVCSInterface::StatusFile EditorVCSInterface::_convert_status_file(Dictionary p_status_file) { + StatusFile sf; + sf.file_path = p_status_file["file_path"]; + sf.change_type = (ChangeType)(int)p_status_file["change_type"]; + sf.area = (TreeArea)(int)p_status_file["area"]; + return sf; +} + +void EditorVCSInterface::_bind_methods() { + // Proxy end points that implement the VCS specific operations that the editor demands. + GDVIRTUAL_BIND(_initialize, "project_path"); + GDVIRTUAL_BIND(_set_credentials, "username", "password", "ssh_public_key_path", "ssh_private_key_path", "ssh_passphrase"); + GDVIRTUAL_BIND(_get_modified_files_data); + GDVIRTUAL_BIND(_stage_file, "file_path"); + GDVIRTUAL_BIND(_unstage_file, "file_path"); + GDVIRTUAL_BIND(_discard_file, "file_path"); + GDVIRTUAL_BIND(_commit, "msg"); + GDVIRTUAL_BIND(_get_diff, "identifier", "area"); + GDVIRTUAL_BIND(_shut_down); + GDVIRTUAL_BIND(_get_vcs_name); + GDVIRTUAL_BIND(_get_previous_commits, "max_commits"); + GDVIRTUAL_BIND(_get_branch_list); + GDVIRTUAL_BIND(_get_remotes); + GDVIRTUAL_BIND(_create_branch, "branch_name"); + GDVIRTUAL_BIND(_remove_branch, "branch_name"); + GDVIRTUAL_BIND(_create_remote, "remote_name", "remote_url"); + GDVIRTUAL_BIND(_remove_remote, "remote_name"); + GDVIRTUAL_BIND(_get_current_branch_name); + GDVIRTUAL_BIND(_checkout_branch, "branch_name"); + GDVIRTUAL_BIND(_pull, "remote"); + GDVIRTUAL_BIND(_push, "remote", "force"); + GDVIRTUAL_BIND(_fetch, "remote"); + GDVIRTUAL_BIND(_get_line_diff, "file_path", "text"); + + ClassDB::bind_method(D_METHOD("create_diff_line", "new_line_no", "old_line_no", "content", "status"), &EditorVCSInterface::create_diff_line); + ClassDB::bind_method(D_METHOD("create_diff_hunk", "old_start", "new_start", "old_lines", "new_lines"), &EditorVCSInterface::create_diff_hunk); + ClassDB::bind_method(D_METHOD("create_diff_file", "new_file", "old_file"), &EditorVCSInterface::create_diff_file); + ClassDB::bind_method(D_METHOD("create_commit", "msg", "author", "id", "unix_timestamp", "offset_minutes"), &EditorVCSInterface::create_commit); + ClassDB::bind_method(D_METHOD("create_status_file", "file_path", "change_type", "area"), &EditorVCSInterface::create_status_file); + ClassDB::bind_method(D_METHOD("add_diff_hunks_into_diff_file", "diff_file", "diff_hunks"), &EditorVCSInterface::add_diff_hunks_into_diff_file); + ClassDB::bind_method(D_METHOD("add_line_diffs_into_diff_hunk", "diff_hunk", "line_diffs"), &EditorVCSInterface::add_line_diffs_into_diff_hunk); + ClassDB::bind_method(D_METHOD("popup_error", "msg"), &EditorVCSInterface::popup_error); + + BIND_ENUM_CONSTANT(CHANGE_TYPE_NEW); + BIND_ENUM_CONSTANT(CHANGE_TYPE_MODIFIED); + BIND_ENUM_CONSTANT(CHANGE_TYPE_RENAMED); + BIND_ENUM_CONSTANT(CHANGE_TYPE_DELETED); + BIND_ENUM_CONSTANT(CHANGE_TYPE_TYPECHANGE); + BIND_ENUM_CONSTANT(CHANGE_TYPE_UNMERGED); + + BIND_ENUM_CONSTANT(TREE_AREA_COMMIT); + BIND_ENUM_CONSTANT(TREE_AREA_STAGED); + BIND_ENUM_CONSTANT(TREE_AREA_UNSTAGED); } EditorVCSInterface *EditorVCSInterface::get_singleton() { @@ -170,14 +409,14 @@ void EditorVCSInterface::create_vcs_metadata_files(VCSMetadata p_vcs_metadata_ty if (p_vcs_metadata_type == VCSMetadata::GIT) { Ref<FileAccess> f = FileAccess::open(p_dir.path_join(".gitignore"), FileAccess::WRITE); if (f.is_null()) { - ERR_FAIL_MSG(TTR("Couldn't create .gitignore in project path.")); + ERR_FAIL_MSG("Couldn't create .gitignore in project path."); } else { f->store_line("# Godot 4+ specific ignores"); f->store_line(".godot/"); } f = FileAccess::open(p_dir.path_join(".gitattributes"), FileAccess::WRITE); if (f.is_null()) { - ERR_FAIL_MSG(TTR("Couldn't create .gitattributes in project path.")); + ERR_FAIL_MSG("Couldn't create .gitattributes in project path."); } else { f->store_line("# Normalize EOL for all files that Git considers text files."); f->store_line("* text=auto eol=lf"); diff --git a/editor/editor_vcs_interface.h b/editor/editor_vcs_interface.h index d6d7ffa0e9..e23e032ab9 100644 --- a/editor/editor_vcs_interface.h +++ b/editor/editor_vcs_interface.h @@ -32,30 +32,103 @@ #define EDITOR_VCS_INTERFACE_H #include "core/object/class_db.h" +#include "core/object/gdvirtual.gen.inc" +#include "core/object/script_language_extension.h" #include "core/string/ustring.h" -#include "scene/gui/panel_container.h" +#include "core/variant/type_info.h" class EditorVCSInterface : public Object { GDCLASS(EditorVCSInterface, Object) - bool is_initialized = false; +public: + enum ChangeType { + CHANGE_TYPE_NEW = 0, + CHANGE_TYPE_MODIFIED = 1, + CHANGE_TYPE_RENAMED = 2, + CHANGE_TYPE_DELETED = 3, + CHANGE_TYPE_TYPECHANGE = 4, + CHANGE_TYPE_UNMERGED = 5 + }; + + enum TreeArea { + TREE_AREA_COMMIT = 0, + TREE_AREA_STAGED = 1, + TREE_AREA_UNSTAGED = 2 + }; + + struct DiffLine { + int new_line_no; + int old_line_no; + String content; + String status; + + String old_text; + String new_text; + }; + + struct DiffHunk { + int new_start; + int old_start; + int new_lines; + int old_lines; + List<DiffLine> diff_lines; + }; + + struct DiffFile { + String new_file; + String old_file; + List<DiffHunk> diff_hunks; + }; + + struct Commit { + String author; + String msg; + String id; + int64_t unix_timestamp; + int64_t offset_minutes; + }; + + struct StatusFile { + TreeArea area; + ChangeType change_type; + String file_path; + }; protected: static EditorVCSInterface *singleton; static void _bind_methods(); - // Implemented by addons as end points for the proxy functions - virtual bool _initialize(String p_project_root_path); - virtual bool _is_vcs_initialized(); - virtual Dictionary _get_modified_files_data(); - virtual void _stage_file(String p_file_path); - virtual void _unstage_file(String p_file_path); - virtual void _commit(String p_msg); - virtual TypedArray<Dictionary> _get_file_diff(String p_file_path); - virtual bool _shut_down(); - virtual String _get_project_name(); - virtual String _get_vcs_name(); + DiffLine _convert_diff_line(Dictionary p_diff_line); + DiffHunk _convert_diff_hunk(Dictionary p_diff_hunk); + DiffFile _convert_diff_file(Dictionary p_diff_file); + Commit _convert_commit(Dictionary p_commit); + StatusFile _convert_status_file(Dictionary p_status_file); + + // Proxy endpoints for extensions to implement + GDVIRTUAL1R(bool, _initialize, String); + GDVIRTUAL5(_set_credentials, String, String, String, String, String); + GDVIRTUAL0R(Array, _get_modified_files_data); + GDVIRTUAL1(_stage_file, String); + GDVIRTUAL1(_unstage_file, String); + GDVIRTUAL1(_discard_file, String); + GDVIRTUAL1(_commit, String); + GDVIRTUAL2R(TypedArray<Dictionary>, _get_diff, String, int); + GDVIRTUAL0R(bool, _shut_down); + GDVIRTUAL0R(String, _get_vcs_name); + GDVIRTUAL1R(Array, _get_previous_commits, int); + GDVIRTUAL0R(Array, _get_branch_list); + GDVIRTUAL0R(Array, _get_remotes); + GDVIRTUAL1(_create_branch, String); + GDVIRTUAL1(_remove_branch, String); + GDVIRTUAL2(_create_remote, String, String); + GDVIRTUAL1(_remove_remote, String); + GDVIRTUAL0R(String, _get_current_branch_name); + GDVIRTUAL1R(bool, _checkout_branch, String); + GDVIRTUAL1(_pull, String); + GDVIRTUAL2(_push, String, bool); + GDVIRTUAL1(_fetch, String); + GDVIRTUAL2R(Array, _get_line_diff, String, String); public: static EditorVCSInterface *get_singleton(); @@ -67,22 +140,44 @@ public: }; static void create_vcs_metadata_files(VCSMetadata p_vcs_metadata_type, String &p_dir); - bool is_addon_ready(); - - // Proxy functions to the editor for use - bool initialize(String p_project_root_path); - bool is_vcs_initialized(); - Dictionary get_modified_files_data(); + // Proxies to the editor for use + bool initialize(String p_project_path); + void set_credentials(String p_username, String p_password, String p_ssh_public_key_path, String p_ssh_private_key_path, String p_ssh_passphrase); + List<StatusFile> get_modified_files_data(); void stage_file(String p_file_path); void unstage_file(String p_file_path); + void discard_file(String p_file_path); void commit(String p_msg); - TypedArray<Dictionary> get_file_diff(String p_file_path); + List<DiffFile> get_diff(String p_identifier, TreeArea p_area); bool shut_down(); - String get_project_name(); String get_vcs_name(); + List<Commit> get_previous_commits(int p_max_commits); + List<String> get_branch_list(); + List<String> get_remotes(); + void create_branch(String p_branch_name); + void remove_branch(String p_branch_name); + void create_remote(String p_remote_name, String p_remote_url); + void remove_remote(String p_remote_name); + String get_current_branch_name(); + bool checkout_branch(String p_branch_name); + void pull(String p_remote); + void push(String p_remote, bool p_force); + void fetch(String p_remote); + List<DiffHunk> get_line_diff(String p_file_path, String p_text); - EditorVCSInterface(); - virtual ~EditorVCSInterface(); + // Helper functions to create and convert Dictionary into data structures + Dictionary create_diff_line(int p_new_line_no, int p_old_line_no, String p_content, String p_status); + Dictionary create_diff_hunk(int p_old_start, int p_new_start, int p_old_lines, int p_new_lines); + Dictionary create_diff_file(String p_new_file, String p_old_file); + Dictionary create_commit(String p_msg, String p_author, String p_id, int64_t p_unix_timestamp, int64_t p_offset_minutes); + Dictionary create_status_file(String p_file_path, ChangeType p_change, TreeArea p_area); + Dictionary add_line_diffs_into_diff_hunk(Dictionary p_diff_hunk, Array p_line_diffs); + Dictionary add_diff_hunks_into_diff_file(Dictionary p_diff_file, Array p_diff_hunks); + + void popup_error(String p_msg); }; +VARIANT_ENUM_CAST(EditorVCSInterface::ChangeType); +VARIANT_ENUM_CAST(EditorVCSInterface::TreeArea); + #endif // EDITOR_VCS_INTERFACE_H diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp index ffe9b8130b..19788e70da 100644 --- a/editor/filesystem_dock.cpp +++ b/editor/filesystem_dock.cpp @@ -276,7 +276,7 @@ void FileSystemDock::_update_tree(const Vector<String> &p_uncollapsed_paths, boo ti->set_text(0, text); ti->set_icon(0, icon); ti->set_icon_modulate(0, color); - ti->set_tooltip(0, fave); + ti->set_tooltip_text(0, fave); ti->set_selectable(0, true); ti->set_metadata(0, fave); if (p_select_in_favorites && fave == path) { diff --git a/editor/groups_editor.cpp b/editor/groups_editor.cpp index 15add50fd4..dac86acae4 100644 --- a/editor/groups_editor.cpp +++ b/editor/groups_editor.cpp @@ -89,7 +89,7 @@ void GroupDialog::_load_nodes(Node *p_current) { if (keep) { node->set_text(0, item_name); node->set_metadata(0, path); - node->set_tooltip(0, path); + node->set_tooltip_text(0, path); Ref<Texture2D> icon = EditorNode::get_singleton()->get_object_icon(p_current, "Node"); node->set_icon(0, icon); diff --git a/editor/icons/CameraEffects.svg b/editor/icons/CameraAttributes.svg index 1ee7e15c87..1ee7e15c87 100644 --- a/editor/icons/CameraEffects.svg +++ b/editor/icons/CameraAttributes.svg diff --git a/editor/icons/VcsBranches.svg b/editor/icons/VcsBranches.svg new file mode 100644 index 0000000000..e79019590f --- /dev/null +++ b/editor/icons/VcsBranches.svg @@ -0,0 +1 @@ +<svg clip-rule="evenodd" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="1.5" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0" fill-rule="nonzero"><path d="m3.755 1.396c-1.599 0-2.914 1.315-2.914 2.913 0 1.599 1.315 2.914 2.914 2.914 1.598 0 2.913-1.315 2.913-2.914 0-1.598-1.315-2.913-2.913-2.913zm0 1.462c.796 0 1.451.655 1.451 1.451 0 .797-.655 1.452-1.451 1.452-.797 0-1.452-.655-1.452-1.452 0-.796.655-1.451 1.452-1.451z"/><path d="m12.073 8.956c-1.599 0-2.914 1.316-2.914 2.914s1.315 2.914 2.914 2.914c1.598 0 2.914-1.316 2.914-2.914s-1.316-2.914-2.914-2.914zm0 1.463c.796 0 1.451.655 1.451 1.451s-.655 1.451-1.451 1.451-1.451-.655-1.451-1.451.655-1.451 1.451-1.451z"/><path d="m12.073 1.396c-1.599 0-2.914 1.315-2.914 2.913 0 1.599 1.315 2.914 2.914 2.914 1.598 0 2.914-1.315 2.914-2.914 0-1.598-1.316-2.913-2.914-2.913zm0 1.462c.796 0 1.451.655 1.451 1.451 0 .797-.655 1.452-1.451 1.452s-1.451-.655-1.451-1.452c0-.796.655-1.451 1.451-1.451z"/></g><path d="m9.159 11.87h-2.491l-2.913-2.914v-1.733" fill="none" stroke="#e0e0e0" stroke-width="1.5"/><path d="m9.159 4.309h-2.491" fill="none" stroke="#e0e0e0" stroke-width="1.5"/></svg> diff --git a/editor/import/audio_stream_import_settings.cpp b/editor/import/audio_stream_import_settings.cpp index cc7c5809d6..e3da82a5cb 100644 --- a/editor/import/audio_stream_import_settings.cpp +++ b/editor/import/audio_stream_import_settings.cpp @@ -57,13 +57,13 @@ void AudioStreamImportSettings::_notification(int p_what) { zoom_out->set_icon(get_theme_icon(SNAME("ZoomLess"), SNAME("EditorIcons"))); zoom_reset->set_icon(get_theme_icon(SNAME("ZoomReset"), SNAME("EditorIcons"))); - _indicator->update(); - _preview->update(); + _indicator->queue_redraw(); + _preview->queue_redraw(); } break; case NOTIFICATION_PROCESS: { _current = _player->get_playback_position(); - _indicator->update(); + _indicator->queue_redraw(); } break; case NOTIFICATION_VISIBILITY_CHANGED: { @@ -167,7 +167,7 @@ void AudioStreamImportSettings::_draw_preview() { void AudioStreamImportSettings::_preview_changed(ObjectID p_which) { if (stream.is_valid() && stream->get_instance_id() == p_which) { - _preview->update(); + _preview->queue_redraw(); } } @@ -179,8 +179,8 @@ void AudioStreamImportSettings::_preview_zoom_in() { zoom_bar->set_page(page_size * 0.5); zoom_bar->set_value(zoom_bar->get_value() + page_size * 0.25); - _preview->update(); - _indicator->update(); + _preview->queue_redraw(); + _indicator->queue_redraw(); } void AudioStreamImportSettings::_preview_zoom_out() { @@ -191,8 +191,8 @@ void AudioStreamImportSettings::_preview_zoom_out() { zoom_bar->set_page(MIN(zoom_bar->get_max(), page_size * 2.0)); zoom_bar->set_value(zoom_bar->get_value() - page_size * 0.5); - _preview->update(); - _indicator->update(); + _preview->queue_redraw(); + _indicator->queue_redraw(); } void AudioStreamImportSettings::_preview_zoom_reset() { @@ -202,22 +202,22 @@ void AudioStreamImportSettings::_preview_zoom_reset() { zoom_bar->set_max(stream->get_length()); zoom_bar->set_page(zoom_bar->get_max()); zoom_bar->set_value(0); - _preview->update(); - _indicator->update(); + _preview->queue_redraw(); + _indicator->queue_redraw(); } void AudioStreamImportSettings::_preview_zoom_offset_changed(double) { - _preview->update(); - _indicator->update(); + _preview->queue_redraw(); + _indicator->queue_redraw(); } void AudioStreamImportSettings::_audio_changed() { if (!is_visible()) { return; } - _preview->update(); - _indicator->update(); - color_rect->update(); + _preview->queue_redraw(); + _indicator->queue_redraw(); + color_rect->queue_redraw(); } void AudioStreamImportSettings::_play() { @@ -238,7 +238,7 @@ void AudioStreamImportSettings::_stop() { _player->stop(); _play_button->set_icon(get_theme_icon(SNAME("MainPlay"), SNAME("EditorIcons"))); _current = 0; - _indicator->update(); + _indicator->queue_redraw(); set_process(false); } @@ -246,7 +246,7 @@ void AudioStreamImportSettings::_on_finished() { _play_button->set_icon(get_theme_icon(SNAME("MainPlay"), SNAME("EditorIcons"))); if (!_pausing) { _current = 0; - _indicator->update(); + _indicator->queue_redraw(); } else { _pausing = false; } @@ -310,7 +310,7 @@ void AudioStreamImportSettings::_draw_indicator() { void AudioStreamImportSettings::_on_indicator_mouse_exited() { _hovering_beat = -1; - _indicator->update(); + _indicator->queue_redraw(); } void AudioStreamImportSettings::_on_input_indicator(Ref<InputEvent> p_event) { @@ -353,11 +353,11 @@ void AudioStreamImportSettings::_on_input_indicator(Ref<InputEvent> p_event) { int new_hovering_beat = _get_beat_at_pos(mm->get_position().x); if (new_hovering_beat != _hovering_beat) { _hovering_beat = new_hovering_beat; - _indicator->update(); + _indicator->queue_redraw(); } } else if (_hovering_beat != -1) { _hovering_beat = -1; - _indicator->update(); + _indicator->queue_redraw(); } } } @@ -391,7 +391,7 @@ void AudioStreamImportSettings::_seek_to(real_t p_x) { _current = zoom_bar->get_value() + p_x / _preview->get_rect().size.x * zoom_bar->get_page(); _current = CLAMP(_current, 0, stream->get_length()); _player->seek(_current); - _indicator->update(); + _indicator->queue_redraw(); } void AudioStreamImportSettings::edit(const String &p_path, const String &p_importer, const Ref<AudioStream> &p_stream) { @@ -410,9 +410,9 @@ void AudioStreamImportSettings::edit(const String &p_path, const String &p_impor if (!stream.is_null()) { stream->connect("changed", callable_mp(this, &AudioStreamImportSettings::_audio_changed)); - _preview->update(); - _indicator->update(); - color_rect->update(); + _preview->queue_redraw(); + _indicator->queue_redraw(); + color_rect->queue_redraw(); } else { hide(); } @@ -500,9 +500,9 @@ void AudioStreamImportSettings::_settings_changed() { updating_settings = false; - _preview->update(); - _indicator->update(); - color_rect->update(); + _preview->queue_redraw(); + _indicator->queue_redraw(); + color_rect->queue_redraw(); } void AudioStreamImportSettings::_reimport() { diff --git a/editor/import/dynamic_font_import_settings.cpp b/editor/import/dynamic_font_import_settings.cpp index 0575f3cbf3..405d8d2169 100644 --- a/editor/import/dynamic_font_import_settings.cpp +++ b/editor/import/dynamic_font_import_settings.cpp @@ -474,7 +474,7 @@ void DynamicFontImportSettings::_main_prop_changed(const String &p_edited_proper font_preview_label->add_theme_font_override("font", font_preview); font_preview_label->add_theme_font_size_override("font_size", 200 * EDSCALE); - font_preview_label->update(); + font_preview_label->queue_redraw(); } /*************************************************************************/ @@ -1096,7 +1096,7 @@ void DynamicFontImportSettings::open_settings(const String &p_path) { } font_preview_label->add_theme_font_override("font", font_preview); font_preview_label->add_theme_font_size_override("font_size", 200 * EDSCALE); - font_preview_label->update(); + font_preview_label->queue_redraw(); _variations_validate(); diff --git a/editor/import/scene_import_settings.cpp b/editor/import/scene_import_settings.cpp index 21292d3282..730aa3bd61 100644 --- a/editor/import/scene_import_settings.cpp +++ b/editor/import/scene_import_settings.cpp @@ -30,6 +30,7 @@ #include "scene_import_settings.h" +#include "core/config/project_settings.h" #include "editor/editor_file_dialog.h" #include "editor/editor_file_system.h" #include "editor/editor_inspector.h" @@ -176,7 +177,7 @@ void SceneImportSettings::_fill_material(Tree *p_tree, const Ref<Material> &p_ma item->set_meta("type", "Material"); item->set_meta("import_id", import_id); - item->set_tooltip(0, vformat(TTR("Import ID: %s"), import_id)); + item->set_tooltip_text(0, vformat(TTR("Import ID: %s"), import_id)); item->set_selectable(0, true); if (p_tree == scene_tree) { @@ -232,7 +233,7 @@ void SceneImportSettings::_fill_mesh(Tree *p_tree, const Ref<Mesh> &p_mesh, Tree item->set_meta("type", "Mesh"); item->set_meta("import_id", import_id); - item->set_tooltip(0, vformat(TTR("Import ID: %s"), import_id)); + item->set_tooltip_text(0, vformat(TTR("Import ID: %s"), import_id)); item->set_selectable(0, true); @@ -331,7 +332,7 @@ void SceneImportSettings::_fill_scene(Node *p_node, TreeItem *p_parent_item) { item->set_meta("type", "Node"); item->set_meta("class", type); item->set_meta("import_id", import_id); - item->set_tooltip(0, vformat(TTR("Type: %s\nImport ID: %s"), type, import_id)); + item->set_tooltip_text(0, vformat(TTR("Type: %s\nImport ID: %s"), type, import_id)); item->set_selectable(0, true); @@ -979,7 +980,7 @@ void SceneImportSettings::_save_path_changed(const String &p_path) { if (FileAccess::exists(p_path)) { save_path_item->set_text(2, "Warning: File exists"); - save_path_item->set_tooltip(2, TTR("Existing file with the same name will be replaced.")); + save_path_item->set_tooltip_text(2, TTR("Existing file with the same name will be replaced.")); save_path_item->set_icon(2, get_theme_icon(SNAME("StatusWarning"), SNAME("EditorIcons"))); } else { @@ -1024,7 +1025,7 @@ void SceneImportSettings::_save_dir_callback(const String &p_path) { if (md.has_import_id) { if (md.settings.has("use_external/enabled") && bool(md.settings["use_external/enabled"])) { item->set_text(2, "Already External"); - item->set_tooltip(2, TTR("This material already references an external file, no action will be taken.\nDisable the external property for it to be extracted again.")); + item->set_tooltip_text(2, TTR("This material already references an external file, no action will be taken.\nDisable the external property for it to be extracted again.")); } else { item->set_metadata(0, E.key); item->set_editable(0, true); @@ -1039,7 +1040,7 @@ void SceneImportSettings::_save_dir_callback(const String &p_path) { item->set_text(1, path); if (FileAccess::exists(path)) { item->set_text(2, "Warning: File exists"); - item->set_tooltip(2, TTR("Existing file with the same name will be replaced.")); + item->set_tooltip_text(2, TTR("Existing file with the same name will be replaced.")); item->set_icon(2, get_theme_icon(SNAME("StatusWarning"), SNAME("EditorIcons"))); } else { @@ -1052,7 +1053,7 @@ void SceneImportSettings::_save_dir_callback(const String &p_path) { } else { item->set_text(2, "No import ID"); - item->set_tooltip(2, TTR("Material has no name nor any other way to identify on re-import.\nPlease name it or ensure it is exported with an unique ID.")); + item->set_tooltip_text(2, TTR("Material has no name nor any other way to identify on re-import.\nPlease name it or ensure it is exported with an unique ID.")); item->set_icon(2, get_theme_icon(SNAME("StatusError"), SNAME("EditorIcons"))); } @@ -1077,7 +1078,7 @@ void SceneImportSettings::_save_dir_callback(const String &p_path) { if (md.has_import_id) { if (md.settings.has("save_to_file/enabled") && bool(md.settings["save_to_file/enabled"])) { item->set_text(2, "Already Saving"); - item->set_tooltip(2, TTR("This mesh already saves to an external resource, no action will be taken.")); + item->set_tooltip_text(2, TTR("This mesh already saves to an external resource, no action will be taken.")); } else { item->set_metadata(0, E.key); item->set_editable(0, true); @@ -1092,7 +1093,7 @@ void SceneImportSettings::_save_dir_callback(const String &p_path) { item->set_text(1, path); if (FileAccess::exists(path)) { item->set_text(2, "Warning: File exists"); - item->set_tooltip(2, TTR("Existing file with the same name will be replaced on import.")); + item->set_tooltip_text(2, TTR("Existing file with the same name will be replaced on import.")); item->set_icon(2, get_theme_icon(SNAME("StatusWarning"), SNAME("EditorIcons"))); } else { @@ -1105,7 +1106,7 @@ void SceneImportSettings::_save_dir_callback(const String &p_path) { } else { item->set_text(2, "No import ID"); - item->set_tooltip(2, TTR("Mesh has no name nor any other way to identify on re-import.\nPlease name it or ensure it is exported with an unique ID.")); + item->set_tooltip_text(2, TTR("Mesh has no name nor any other way to identify on re-import.\nPlease name it or ensure it is exported with an unique ID.")); item->set_icon(2, get_theme_icon(SNAME("StatusError"), SNAME("EditorIcons"))); } @@ -1129,7 +1130,7 @@ void SceneImportSettings::_save_dir_callback(const String &p_path) { if (ad.settings.has("save_to_file/enabled") && bool(ad.settings["save_to_file/enabled"])) { item->set_text(2, "Already Saving"); - item->set_tooltip(2, TTR("This animation already saves to an external resource, no action will be taken.")); + item->set_tooltip_text(2, TTR("This animation already saves to an external resource, no action will be taken.")); } else { item->set_metadata(0, E.key); item->set_editable(0, true); @@ -1144,7 +1145,7 @@ void SceneImportSettings::_save_dir_callback(const String &p_path) { item->set_text(1, path); if (FileAccess::exists(path)) { item->set_text(2, "Warning: File exists"); - item->set_tooltip(2, TTR("Existing file with the same name will be replaced on import.")); + item->set_tooltip_text(2, TTR("Existing file with the same name will be replaced on import.")); item->set_icon(2, get_theme_icon(SNAME("StatusWarning"), SNAME("EditorIcons"))); } else { @@ -1288,6 +1289,11 @@ SceneImportSettings::SceneImportSettings() { base_viewport->add_child(camera); camera->make_current(); + if (GLOBAL_GET("rendering/lights_and_shadows/use_physical_light_units")) { + camera_attributes.instantiate(); + camera->set_attributes(camera_attributes); + } + light = memnew(DirectionalLight3D); light->set_transform(Transform3D().looking_at(Vector3(-1, -2, -0.6), Vector3(0, 1, 0))); base_viewport->add_child(light); diff --git a/editor/import/scene_import_settings.h b/editor/import/scene_import_settings.h index b5cf82f64b..104a7a9f7e 100644 --- a/editor/import/scene_import_settings.h +++ b/editor/import/scene_import_settings.h @@ -74,6 +74,7 @@ class SceneImportSettings : public ConfirmationDialog { SubViewport *base_viewport = nullptr; Camera3D *camera = nullptr; + Ref<CameraAttributesPractical> camera_attributes; bool first_aabb = false; AABB contents_aabb; diff --git a/editor/localization_editor.cpp b/editor/localization_editor.cpp index 77a1700ebf..683481ecc1 100644 --- a/editor/localization_editor.cpp +++ b/editor/localization_editor.cpp @@ -193,7 +193,7 @@ void LocalizationEditor::_translation_res_option_popup(bool p_arrow_clicked) { TreeItem *ed = translation_remap_options->get_edited(); ERR_FAIL_COND(!ed); - locale_select->set_locale(ed->get_tooltip(1)); + locale_select->set_locale(ed->get_tooltip_text(1)); locale_select->popup_locale_dialog(); } @@ -202,7 +202,7 @@ void LocalizationEditor::_translation_res_option_selected(const String &p_locale ERR_FAIL_COND(!ed); ed->set_text(1, TranslationServer::get_singleton()->get_locale_name(p_locale)); - ed->set_tooltip(1, p_locale); + ed->set_tooltip_text(1, p_locale); LocalizationEditor::_translation_res_option_changed(); } @@ -226,7 +226,7 @@ void LocalizationEditor::_translation_res_option_changed() { String key = k->get_metadata(0); int idx = ed->get_metadata(0); String path = ed->get_metadata(1); - String locale = ed->get_tooltip(1); + String locale = ed->get_tooltip_text(1); ERR_FAIL_COND(!remaps.has(key)); PackedStringArray r = remaps[key]; @@ -486,7 +486,7 @@ void LocalizationEditor::update_translations() { TreeItem *t = translation_list->create_item(root); t->set_editable(0, false); t->set_text(0, translations[i].replace_first("res://", "")); - t->set_tooltip(0, translations[i]); + t->set_tooltip_text(0, translations[i]); t->set_metadata(0, i); t->add_button(0, get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), 0, false, TTR("Remove")); } @@ -520,14 +520,14 @@ void LocalizationEditor::update_translations() { TreeItem *t = translation_remap->create_item(root); t->set_editable(0, false); t->set_text(0, keys[i].replace_first("res://", "")); - t->set_tooltip(0, keys[i]); + t->set_tooltip_text(0, keys[i]); t->set_metadata(0, keys[i]); t->add_button(0, get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), 0, false, TTR("Remove")); // Display that it has been removed if this is the case. if (!FileAccess::exists(keys[i])) { t->set_text(0, t->get_text(0) + vformat(" (%s)", TTR("Removed"))); - t->set_tooltip(0, vformat(TTR("%s cannot be found."), t->get_tooltip(0))); + t->set_tooltip_text(0, vformat(TTR("%s cannot be found."), t->get_tooltip_text(0))); } if (keys[i] == remap_selected) { @@ -544,19 +544,19 @@ void LocalizationEditor::update_translations() { TreeItem *t2 = translation_remap_options->create_item(root2); t2->set_editable(0, false); t2->set_text(0, path.replace_first("res://", "")); - t2->set_tooltip(0, path); + t2->set_tooltip_text(0, path); t2->set_metadata(0, j); t2->add_button(0, get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), 0, false, TTR("Remove")); t2->set_cell_mode(1, TreeItem::CELL_MODE_CUSTOM); t2->set_text(1, TranslationServer::get_singleton()->get_locale_name(locale)); t2->set_editable(1, true); t2->set_metadata(1, path); - t2->set_tooltip(1, locale); + t2->set_tooltip_text(1, locale); // Display that it has been removed if this is the case. if (!FileAccess::exists(path)) { t2->set_text(0, t2->get_text(0) + vformat(" (%s)", TTR("Removed"))); - t2->set_tooltip(0, vformat(TTR("%s cannot be found."), t2->get_tooltip(0))); + t2->set_tooltip_text(0, vformat(TTR("%s cannot be found."), t2->get_tooltip_text(0))); } } } @@ -573,7 +573,7 @@ void LocalizationEditor::update_translations() { TreeItem *t = translation_pot_list->create_item(root); t->set_editable(0, false); t->set_text(0, pot_translations[i].replace_first("res://", "")); - t->set_tooltip(0, pot_translations[i]); + t->set_tooltip_text(0, pot_translations[i]); t->set_metadata(0, i); t->add_button(0, get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), 0, false, TTR("Remove")); } diff --git a/editor/plugins/animation_blend_space_1d_editor.cpp b/editor/plugins/animation_blend_space_1d_editor.cpp index 3b7829c37b..b79f4c90bf 100644 --- a/editor/plugins/animation_blend_space_1d_editor.cpp +++ b/editor/plugins/animation_blend_space_1d_editor.cpp @@ -120,7 +120,7 @@ void AnimationNodeBlendSpace1DEditor::_blend_space_gui_input(const Ref<InputEven } if (mb.is_valid() && mb->is_pressed() && tool_select->is_pressed() && mb->get_button_index() == MouseButton::LEFT) { - blend_space_draw->update(); // why not + blend_space_draw->queue_redraw(); // why not // try to see if a point can be selected selected_point = -1; @@ -167,7 +167,7 @@ void AnimationNodeBlendSpace1DEditor::_blend_space_gui_input(const Ref<InputEven dragging_selected_attempt = false; dragging_selected = false; - blend_space_draw->update(); + blend_space_draw->queue_redraw(); } } @@ -178,20 +178,20 @@ void AnimationNodeBlendSpace1DEditor::_blend_space_gui_input(const Ref<InputEven blend_pos += blend_space->get_min_space(); AnimationTreeEditor::get_singleton()->get_tree()->set(get_blend_position_path(), blend_pos); - blend_space_draw->update(); + blend_space_draw->queue_redraw(); } Ref<InputEventMouseMotion> mm = p_event; if (mm.is_valid() && !blend_space_draw->has_focus()) { blend_space_draw->grab_focus(); - blend_space_draw->update(); + blend_space_draw->queue_redraw(); } if (mm.is_valid() && dragging_selected_attempt) { dragging_selected = true; drag_ofs = ((mm->get_position() - drag_from) / blend_space_draw->get_size()) * ((blend_space->get_max_space() - blend_space->get_min_space()) * Vector2(1, 0)); - blend_space_draw->update(); + blend_space_draw->queue_redraw(); _update_edited_point_pos(); } @@ -202,7 +202,7 @@ void AnimationNodeBlendSpace1DEditor::_blend_space_gui_input(const Ref<InputEven AnimationTreeEditor::get_singleton()->get_tree()->set(get_blend_position_path(), blend_pos); - blend_space_draw->update(); + blend_space_draw->queue_redraw(); } } @@ -330,7 +330,7 @@ void AnimationNodeBlendSpace1DEditor::_update_space() { snap_value->set_value(blend_space->get_snap()); - blend_space_draw->update(); + blend_space_draw->queue_redraw(); updating = false; } @@ -355,7 +355,7 @@ void AnimationNodeBlendSpace1DEditor::_config_changed(double) { undo_redo->commit_action(); updating = false; - blend_space_draw->update(); + blend_space_draw->queue_redraw(); } void AnimationNodeBlendSpace1DEditor::_labels_changed(String) { @@ -374,7 +374,7 @@ void AnimationNodeBlendSpace1DEditor::_labels_changed(String) { } void AnimationNodeBlendSpace1DEditor::_snap_toggled() { - blend_space_draw->update(); + blend_space_draw->queue_redraw(); } void AnimationNodeBlendSpace1DEditor::_file_opened(const String &p_file) { @@ -425,7 +425,7 @@ void AnimationNodeBlendSpace1DEditor::_add_menu_type(int p_index) { undo_redo->commit_action(); updating = false; - blend_space_draw->update(); + blend_space_draw->queue_redraw(); } void AnimationNodeBlendSpace1DEditor::_add_animation_type(int p_index) { @@ -443,7 +443,7 @@ void AnimationNodeBlendSpace1DEditor::_add_animation_type(int p_index) { undo_redo->commit_action(); updating = false; - blend_space_draw->update(); + blend_space_draw->queue_redraw(); } void AnimationNodeBlendSpace1DEditor::_tool_switch(int p_tool) { @@ -456,7 +456,7 @@ void AnimationNodeBlendSpace1DEditor::_tool_switch(int p_tool) { } _update_tool_erase(); - blend_space_draw->update(); + blend_space_draw->queue_redraw(); } void AnimationNodeBlendSpace1DEditor::_update_edited_point_pos() { @@ -517,7 +517,7 @@ void AnimationNodeBlendSpace1DEditor::_erase_selected() { updating = false; - blend_space_draw->update(); + blend_space_draw->queue_redraw(); } } @@ -537,7 +537,7 @@ void AnimationNodeBlendSpace1DEditor::_edit_point_pos(double) { undo_redo->commit_action(); updating = false; - blend_space_draw->update(); + blend_space_draw->queue_redraw(); } void AnimationNodeBlendSpace1DEditor::_open_editor() { diff --git a/editor/plugins/animation_blend_space_2d_editor.cpp b/editor/plugins/animation_blend_space_2d_editor.cpp index d904ccb5e0..1646a1cef4 100644 --- a/editor/plugins/animation_blend_space_2d_editor.cpp +++ b/editor/plugins/animation_blend_space_2d_editor.cpp @@ -52,7 +52,7 @@ bool AnimationNodeBlendSpace2DEditor::can_edit(const Ref<AnimationNode> &p_node) } void AnimationNodeBlendSpace2DEditor::_blend_space_changed() { - blend_space_draw->update(); + blend_space_draw->queue_redraw(); } void AnimationNodeBlendSpace2DEditor::edit(const Ref<AnimationNode> &p_node) { @@ -161,7 +161,7 @@ void AnimationNodeBlendSpace2DEditor::_blend_space_gui_input(const Ref<InputEven } if (mb.is_valid() && mb->is_pressed() && tool_select->is_pressed() && mb->get_button_index() == MouseButton::LEFT) { - blend_space_draw->update(); //update anyway + blend_space_draw->queue_redraw(); //update anyway //try to see if a point can be selected selected_point = -1; selected_triangle = -1; @@ -201,7 +201,7 @@ void AnimationNodeBlendSpace2DEditor::_blend_space_gui_input(const Ref<InputEven } if (mb.is_valid() && mb->is_pressed() && tool_triangle->is_pressed() && mb->get_button_index() == MouseButton::LEFT) { - blend_space_draw->update(); //update anyway + blend_space_draw->queue_redraw(); //update anyway //try to see if a point can be selected selected_point = -1; @@ -260,7 +260,7 @@ void AnimationNodeBlendSpace2DEditor::_blend_space_gui_input(const Ref<InputEven } dragging_selected_attempt = false; dragging_selected = false; - blend_space_draw->update(); + blend_space_draw->queue_redraw(); } if (mb.is_valid() && mb->is_pressed() && tool_blend->is_pressed() && mb->get_button_index() == MouseButton::LEFT) { @@ -271,14 +271,14 @@ void AnimationNodeBlendSpace2DEditor::_blend_space_gui_input(const Ref<InputEven AnimationTreeEditor::get_singleton()->get_tree()->set(get_blend_position_path(), blend_pos); - blend_space_draw->update(); + blend_space_draw->queue_redraw(); } Ref<InputEventMouseMotion> mm = p_event; if (mm.is_valid() && !blend_space_draw->has_focus()) { blend_space_draw->grab_focus(); - blend_space_draw->update(); + blend_space_draw->queue_redraw(); } if (mm.is_valid() && dragging_selected_attempt) { @@ -286,17 +286,17 @@ void AnimationNodeBlendSpace2DEditor::_blend_space_gui_input(const Ref<InputEven if (!read_only) { drag_ofs = ((mm->get_position() - drag_from) / blend_space_draw->get_size()) * (blend_space->get_max_space() - blend_space->get_min_space()) * Vector2(1, -1); } - blend_space_draw->update(); + blend_space_draw->queue_redraw(); _update_edited_point_pos(); } if (mm.is_valid() && tool_triangle->is_pressed() && making_triangle.size()) { - blend_space_draw->update(); + blend_space_draw->queue_redraw(); } if (mm.is_valid() && !tool_triangle->is_pressed() && making_triangle.size()) { making_triangle.clear(); - blend_space_draw->update(); + blend_space_draw->queue_redraw(); } if (mm.is_valid() && tool_blend->is_pressed() && (mm->get_button_mask() & MouseButton::MASK_LEFT) != MouseButton::NONE) { @@ -307,7 +307,7 @@ void AnimationNodeBlendSpace2DEditor::_blend_space_gui_input(const Ref<InputEven AnimationTreeEditor::get_singleton()->get_tree()->set(get_blend_position_path(), blend_pos); - blend_space_draw->update(); + blend_space_draw->queue_redraw(); } } @@ -359,7 +359,7 @@ void AnimationNodeBlendSpace2DEditor::_add_menu_type(int p_index) { undo_redo->commit_action(); updating = false; - blend_space_draw->update(); + blend_space_draw->queue_redraw(); } void AnimationNodeBlendSpace2DEditor::_add_animation_type(int p_index) { @@ -377,7 +377,7 @@ void AnimationNodeBlendSpace2DEditor::_add_animation_type(int p_index) { undo_redo->commit_action(); updating = false; - blend_space_draw->update(); + blend_space_draw->queue_redraw(); } void AnimationNodeBlendSpace2DEditor::_update_tool_erase() { @@ -424,7 +424,7 @@ void AnimationNodeBlendSpace2DEditor::_tool_switch(int p_tool) { tool_erase_sep->hide(); } _update_tool_erase(); - blend_space_draw->update(); + blend_space_draw->queue_redraw(); } void AnimationNodeBlendSpace2DEditor::_blend_space_draw() { @@ -614,7 +614,7 @@ void AnimationNodeBlendSpace2DEditor::_blend_space_draw() { } void AnimationNodeBlendSpace2DEditor::_snap_toggled() { - blend_space_draw->update(); + blend_space_draw->queue_redraw(); } void AnimationNodeBlendSpace2DEditor::_update_space() { @@ -647,7 +647,7 @@ void AnimationNodeBlendSpace2DEditor::_update_space() { snap_x->set_value(blend_space->get_snap().x); snap_y->set_value(blend_space->get_snap().y); - blend_space_draw->update(); + blend_space_draw->queue_redraw(); updating = false; } @@ -674,7 +674,7 @@ void AnimationNodeBlendSpace2DEditor::_config_changed(double) { undo_redo->commit_action(); updating = false; - blend_space_draw->update(); + blend_space_draw->queue_redraw(); } void AnimationNodeBlendSpace2DEditor::_labels_changed(String) { @@ -716,7 +716,7 @@ void AnimationNodeBlendSpace2DEditor::_erase_selected() { undo_redo->commit_action(); updating = false; - blend_space_draw->update(); + blend_space_draw->queue_redraw(); } else if (selected_triangle != -1) { updating = true; undo_redo->create_action(TTR("Remove BlendSpace2D Triangle")); @@ -728,7 +728,7 @@ void AnimationNodeBlendSpace2DEditor::_erase_selected() { undo_redo->commit_action(); updating = false; - blend_space_draw->update(); + blend_space_draw->queue_redraw(); } } @@ -767,7 +767,7 @@ void AnimationNodeBlendSpace2DEditor::_edit_point_pos(double) { undo_redo->commit_action(); updating = false; - blend_space_draw->update(); + blend_space_draw->queue_redraw(); } void AnimationNodeBlendSpace2DEditor::_notification(int p_what) { diff --git a/editor/plugins/animation_library_editor.cpp b/editor/plugins/animation_library_editor.cpp index f9e5aa799a..50ba1a71c0 100644 --- a/editor/plugins/animation_library_editor.cpp +++ b/editor/plugins/animation_library_editor.cpp @@ -635,7 +635,7 @@ void AnimationLibraryEditor::update_tree() { String al_path = al->get_path(); if (!al_path.is_resource_file()) { libitem->set_text(1, TTR("[built-in]")); - libitem->set_tooltip(1, al_path); + libitem->set_tooltip_text(1, al_path); int srpos = al_path.find("::"); if (srpos != -1) { String base = al_path.substr(0, srpos); @@ -687,7 +687,7 @@ void AnimationLibraryEditor::update_tree() { String anim_path = anim->get_path(); if (!anim_path.is_resource_file()) { anitem->set_text(1, TTR("[built-in]")); - anitem->set_tooltip(1, anim_path); + anitem->set_tooltip_text(1, anim_path); int srpos = anim_path.find("::"); if (srpos != -1) { String base = anim_path.substr(0, srpos); diff --git a/editor/plugins/animation_state_machine_editor.cpp b/editor/plugins/animation_state_machine_editor.cpp index be1e531cb8..2809eb01cd 100644 --- a/editor/plugins/animation_state_machine_editor.cpp +++ b/editor/plugins/animation_state_machine_editor.cpp @@ -128,7 +128,7 @@ void AnimationNodeStateMachineEditor::_state_machine_gui_input(const Ref<InputEv //travel playback->travel(node_rects[i].node_name); } - state_machine_draw->update(); + state_machine_draw->queue_redraw(); return; } @@ -168,7 +168,7 @@ void AnimationNodeStateMachineEditor::_state_machine_gui_input(const Ref<InputEv Ref<AnimationNode> anode = state_machine->get_node(selected_node); EditorNode::get_singleton()->push_item(anode.ptr(), "", true); - state_machine_draw->update(); + state_machine_draw->queue_redraw(); dragging_selected_attempt = true; dragging_selected = false; drag_from = mb->get_position(); @@ -228,7 +228,7 @@ void AnimationNodeStateMachineEditor::_state_machine_gui_input(const Ref<InputEv } } - state_machine_draw->update(); + state_machine_draw->queue_redraw(); _update_mode(); } @@ -259,7 +259,7 @@ void AnimationNodeStateMachineEditor::_state_machine_gui_input(const Ref<InputEv dragging_selected_attempt = false; dragging_selected = false; - state_machine_draw->update(); + state_machine_draw->queue_redraw(); } // Connect nodes @@ -296,7 +296,7 @@ void AnimationNodeStateMachineEditor::_state_machine_gui_input(const Ref<InputEv _open_menu(mb->get_position()); } connecting_to_node = StringName(); - state_machine_draw->update(); + state_machine_draw->queue_redraw(); } // Start box selecting @@ -319,7 +319,7 @@ void AnimationNodeStateMachineEditor::_state_machine_gui_input(const Ref<InputEv // End box selecting if (mb.is_valid() && mb->get_button_index() == MouseButton::LEFT && !mb->is_pressed() && box_selecting) { box_selecting = false; - state_machine_draw->update(); + state_machine_draw->queue_redraw(); _update_mode(); } @@ -335,7 +335,7 @@ void AnimationNodeStateMachineEditor::_state_machine_gui_input(const Ref<InputEv if (mm.is_valid() && connecting && !read_only) { connecting_to = mm->get_position(); connecting_to_node = StringName(); - state_machine_draw->update(); + state_machine_draw->queue_redraw(); for (int i = node_rects.size() - 1; i >= 0; i--) { //inverse to draw order if (node_rects[i].node_name != connecting_from && node_rects[i].node.has_point(connecting_to)) { //select node since nothing else was selected @@ -382,7 +382,7 @@ void AnimationNodeStateMachineEditor::_state_machine_gui_input(const Ref<InputEv } } - state_machine_draw->update(); + state_machine_draw->queue_redraw(); } // Move mouse while moving box select @@ -412,7 +412,7 @@ void AnimationNodeStateMachineEditor::_state_machine_gui_input(const Ref<InputEv } } - state_machine_draw->update(); + state_machine_draw->queue_redraw(); } if (mm.is_valid()) { @@ -442,7 +442,7 @@ void AnimationNodeStateMachineEditor::_state_machine_gui_input(const Ref<InputEv if (new_over_node != over_node || new_over_node_what != over_node_what) { over_node = new_over_node; over_node_what = new_over_node_what; - state_machine_draw->update(); + state_machine_draw->queue_redraw(); } // set tooltip for transition @@ -620,7 +620,7 @@ void AnimationNodeStateMachineEditor::_group_selected_nodes() { selected_nodes.clear(); selected_nodes.insert(group_name); - state_machine_draw->update(); + state_machine_draw->queue_redraw(); accept_event(); _update_mode(); } @@ -721,7 +721,7 @@ void AnimationNodeStateMachineEditor::_ungroup_selected_nodes() { if (find) { selected_nodes = new_selected_nodes; selected_node = StringName(); - state_machine_draw->update(); + state_machine_draw->queue_redraw(); accept_event(); _update_mode(); } @@ -802,8 +802,7 @@ void AnimationNodeStateMachineEditor::_open_connect_menu(const Vector2 &p_positi if (anodesm.is_valid()) { _create_submenu(connect_menu, anodesm, connecting_to_node, connecting_to_node); } else { - Ref<AnimationNodeStateMachine> prev = state_machine; - _create_submenu(connect_menu, prev, connecting_to_node, connecting_to_node, true); + _create_submenu(connect_menu, state_machine, connecting_to_node, connecting_to_node, true); } connect_menu->add_submenu_item(TTR("To") + " Animation", connecting_to_node); @@ -835,6 +834,10 @@ bool AnimationNodeStateMachineEditor::_create_submenu(PopupMenu *p_menu, Ref<Ani String prev_path; Vector<Ref<AnimationNodeStateMachine>> parents = p_parents; + if (from_root && p_nodesm->get_prev_state_machine() == nullptr) { + return false; + } + if (from_root) { AnimationNodeStateMachine *prev = p_nodesm->get_prev_state_machine(); @@ -844,6 +847,8 @@ bool AnimationNodeStateMachineEditor::_create_submenu(PopupMenu *p_menu, Ref<Ani prev_path += "../"; prev = prev->get_prev_state_machine(); } + end_menu->add_item("Root", nodes_to_connect.size()); + nodes_to_connect.push_back(prev_path + state_machine->end_node); prev_path.remove_at(prev_path.size() - 1); } @@ -874,22 +879,22 @@ bool AnimationNodeStateMachineEditor::_create_submenu(PopupMenu *p_menu, Ref<Ani } if (ansm.is_valid()) { - bool found = false; + bool parent_found = false; for (int i = 0; i < parents.size(); i++) { if (parents[i] == ansm) { path = path.replace_first("/../" + E, ""); - found = true; + parent_found = true; break; } } - if (!found) { - state_machine_menu->add_item(E, nodes_to_connect.size()); - nodes_to_connect.push_back(path); - } else { + if (parent_found) { end_menu->add_item(E, nodes_to_connect.size()); nodes_to_connect.push_back(path + "/" + state_machine->end_node); + } else { + state_machine_menu->add_item(E, nodes_to_connect.size()); + nodes_to_connect.push_back(path); } if (_create_submenu(nodes_menu, ansm, E, path, false, parents)) { @@ -909,7 +914,7 @@ bool AnimationNodeStateMachineEditor::_create_submenu(PopupMenu *p_menu, Ref<Ani void AnimationNodeStateMachineEditor::_stop_connecting() { connecting = false; - state_machine_draw->update(); + state_machine_draw->queue_redraw(); } void AnimationNodeStateMachineEditor::_delete_selected() { @@ -1028,7 +1033,7 @@ void AnimationNodeStateMachineEditor::_add_menu_type(int p_index) { undo_redo->commit_action(); updating = false; - state_machine_draw->update(); + state_machine_draw->queue_redraw(); } void AnimationNodeStateMachineEditor::_add_animation_type(int p_index) { @@ -1056,7 +1061,7 @@ void AnimationNodeStateMachineEditor::_add_animation_type(int p_index) { undo_redo->commit_action(); updating = false; - state_machine_draw->update(); + state_machine_draw->queue_redraw(); } void AnimationNodeStateMachineEditor::_connect_to(int p_index) { @@ -1475,7 +1480,7 @@ void AnimationNodeStateMachineEditor::_state_machine_draw() { v_scroll->set_value(state_machine->get_graph_offset().y); updating = false; - state_machine_play_pos->update(); + state_machine_play_pos->queue_redraw(); } void AnimationNodeStateMachineEditor::_state_machine_pos_draw() { @@ -1537,7 +1542,7 @@ void AnimationNodeStateMachineEditor::_update_graph() { updating = true; - state_machine_draw->update(); + state_machine_draw->queue_redraw(); updating = false; } @@ -1609,34 +1614,34 @@ void AnimationNodeStateMachineEditor::_notification(int p_what) { } if (tidx == -1) { //missing transition, should redraw - state_machine_draw->update(); + state_machine_draw->queue_redraw(); break; } if (transition_lines[i].disabled != state_machine->get_transition(tidx)->is_disabled()) { - state_machine_draw->update(); + state_machine_draw->queue_redraw(); break; } if (transition_lines[i].auto_advance != state_machine->get_transition(tidx)->has_auto_advance()) { - state_machine_draw->update(); + state_machine_draw->queue_redraw(); break; } if (transition_lines[i].advance_condition_name != state_machine->get_transition(tidx)->get_advance_condition_name()) { - state_machine_draw->update(); + state_machine_draw->queue_redraw(); break; } if (transition_lines[i].mode != state_machine->get_transition(tidx)->get_switch_mode()) { - state_machine_draw->update(); + state_machine_draw->queue_redraw(); break; } bool acstate = transition_lines[i].advance_condition_name != StringName() && bool(AnimationTreeEditor::get_singleton()->get_tree()->get(AnimationTreeEditor::get_singleton()->get_base_path() + String(transition_lines[i].advance_condition_name))); if (transition_lines[i].advance_condition_state != acstate) { - state_machine_draw->update(); + state_machine_draw->queue_redraw(); break; } } @@ -1671,14 +1676,14 @@ void AnimationNodeStateMachineEditor::_notification(int p_what) { } } - //update if travel state changed + //redraw if travel state changed if (!same_travel_path || last_active != is_playing || last_current_node != current_node || last_blend_from_node != blend_from_node) { - state_machine_draw->update(); + state_machine_draw->queue_redraw(); last_travel_path = tp; last_current_node = current_node; last_active = is_playing; last_blend_from_node = blend_from_node; - state_machine_play_pos->update(); + state_machine_play_pos->queue_redraw(); } { @@ -1703,7 +1708,7 @@ void AnimationNodeStateMachineEditor::_notification(int p_what) { if (last_play_pos != play_pos) { last_play_pos = play_pos; - state_machine_play_pos->update(); + state_machine_play_pos->queue_redraw(); } } break; @@ -1749,7 +1754,7 @@ void AnimationNodeStateMachineEditor::_name_edited(const String &p_text) { name_edit_popup->hide(); updating = false; - state_machine_draw->update(); + state_machine_draw->queue_redraw(); } void AnimationNodeStateMachineEditor::_name_edited_focus_out() { @@ -1766,7 +1771,7 @@ void AnimationNodeStateMachineEditor::_scroll_changed(double) { } state_machine->set_graph_offset(Vector2(h_scroll->get_value(), v_scroll->get_value())); - state_machine_draw->update(); + state_machine_draw->queue_redraw(); } void AnimationNodeStateMachineEditor::_erase_selected(const bool p_nested_action) { @@ -1857,7 +1862,7 @@ void AnimationNodeStateMachineEditor::_erase_selected(const bool p_nested_action selected_multi_transition = TransitionLine(); } - state_machine_draw->update(); + state_machine_draw->queue_redraw(); } void AnimationNodeStateMachineEditor::_update_mode() { diff --git a/editor/plugins/bone_map_editor_plugin.cpp b/editor/plugins/bone_map_editor_plugin.cpp index c16dca00a3..988f9cc394 100644 --- a/editor/plugins/bone_map_editor_plugin.cpp +++ b/editor/plugins/bone_map_editor_plugin.cpp @@ -609,7 +609,7 @@ int BoneMapper::search_bone_by_name(Skeleton3D *p_skeleton, Vector<String> p_pic } BoneMapper::BoneSegregation BoneMapper::guess_bone_segregation(String p_bone_name) { - String fixed_bn = p_bone_name.camelcase_to_underscore().to_lower(); + String fixed_bn = p_bone_name.to_snake_case(); LocalVector<String> left_words; left_words.push_back("(?<![a-zA-Z])left"); diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index 37c79d4974..c4a32d6d4b 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -487,21 +487,21 @@ void CanvasItemEditor::shortcut_input(const Ref<InputEvent> &p_ev) { if (k.is_valid()) { if (k->get_keycode() == Key::CTRL || k->get_keycode() == Key::ALT || k->get_keycode() == Key::SHIFT) { - viewport->update(); + viewport->queue_redraw(); } if (k->is_pressed() && !k->is_ctrl_pressed() && !k->is_echo() && (grid_snap_active || _is_grid_visible())) { if (multiply_grid_step_shortcut.is_valid() && multiply_grid_step_shortcut->matches_event(p_ev)) { // Multiply the grid size grid_step_multiplier = MIN(grid_step_multiplier + 1, 12); - viewport->update(); + viewport->queue_redraw(); } else if (divide_grid_step_shortcut.is_valid() && divide_grid_step_shortcut->matches_event(p_ev)) { // Divide the grid size Point2 new_grid_step = grid_step * Math::pow(2.0, grid_step_multiplier - 1); if (new_grid_step.x >= 1.0 && new_grid_step.y >= 1.0) { grid_step_multiplier--; } - viewport->update(); + viewport->queue_redraw(); } } } @@ -758,7 +758,7 @@ bool CanvasItemEditor::_select_click_on_item(CanvasItem *item, Point2 p_click_po } } } - viewport->update(); + viewport->queue_redraw(); return still_selected; } @@ -875,15 +875,15 @@ void CanvasItemEditor::_commit_canvas_item_state(List<CanvasItem *> p_canvas_ite } } } - undo_redo->add_do_method(viewport, "update"); - undo_redo->add_undo_method(viewport, "update"); + undo_redo->add_do_method(viewport, "queue_redraw"); + undo_redo->add_undo_method(viewport, "queue_redraw"); undo_redo->commit_action(); } void CanvasItemEditor::_snap_changed() { static_cast<SnapDialog *>(snap_dialog)->get_fields(grid_offset, grid_step, primary_grid_steps, snap_rotation_offset, snap_rotation_step, snap_scale_step); grid_step_multiplier = 0; - viewport->update(); + viewport->queue_redraw(); } void CanvasItemEditor::_selection_result_pressed(int p_result) { @@ -983,7 +983,7 @@ void CanvasItemEditor::_on_grid_menu_id_pressed(int p_id) { case GRID_VISIBILITY_SHOW_WHEN_SNAPPING: case GRID_VISIBILITY_HIDE: grid_visibility = (GridVisibility)p_id; - viewport->update(); + viewport->queue_redraw(); view_menu->get_popup()->hide(); return; } @@ -1010,7 +1010,7 @@ void CanvasItemEditor::_on_grid_menu_id_pressed(int p_id) { break; } } - viewport->update(); + viewport->queue_redraw(); } bool CanvasItemEditor::_gui_input_rulers_and_guides(const Ref<InputEvent> &p_event) { @@ -1105,7 +1105,7 @@ bool CanvasItemEditor::_gui_input_rulers_and_guides(const Ref<InputEvent> &p_eve drag_to = xform.affine_inverse().xform(m->get_position()); dragged_guide_pos = xform.xform(snap_point(drag_to, SNAP_GRID | SNAP_PIXEL | SNAP_OTHER_NODES)); - viewport->update(); + viewport->queue_redraw(); return true; } @@ -1128,14 +1128,14 @@ bool CanvasItemEditor::_gui_input_rulers_and_guides(const Ref<InputEvent> &p_eve undo_redo->create_action(TTR("Move Vertical Guide")); undo_redo->add_do_method(EditorNode::get_singleton()->get_edited_scene(), "set_meta", "_edit_vertical_guides_", vguides); undo_redo->add_undo_method(EditorNode::get_singleton()->get_edited_scene(), "set_meta", "_edit_vertical_guides_", prev_vguides); - undo_redo->add_undo_method(viewport, "update"); + undo_redo->add_undo_method(viewport, "queue_redraw"); undo_redo->commit_action(); } else { vguides.push_back(edited.x); undo_redo->create_action(TTR("Create Vertical Guide")); undo_redo->add_do_method(EditorNode::get_singleton()->get_edited_scene(), "set_meta", "_edit_vertical_guides_", vguides); undo_redo->add_undo_method(EditorNode::get_singleton()->get_edited_scene(), "set_meta", "_edit_vertical_guides_", prev_vguides); - undo_redo->add_undo_method(viewport, "update"); + undo_redo->add_undo_method(viewport, "queue_redraw"); undo_redo->commit_action(); } } else { @@ -1148,7 +1148,7 @@ bool CanvasItemEditor::_gui_input_rulers_and_guides(const Ref<InputEvent> &p_eve undo_redo->add_do_method(EditorNode::get_singleton()->get_edited_scene(), "set_meta", "_edit_vertical_guides_", vguides); } undo_redo->add_undo_method(EditorNode::get_singleton()->get_edited_scene(), "set_meta", "_edit_vertical_guides_", prev_vguides); - undo_redo->add_undo_method(viewport, "update"); + undo_redo->add_undo_method(viewport, "queue_redraw"); undo_redo->commit_action(); } } @@ -1161,14 +1161,14 @@ bool CanvasItemEditor::_gui_input_rulers_and_guides(const Ref<InputEvent> &p_eve undo_redo->create_action(TTR("Move Horizontal Guide")); undo_redo->add_do_method(EditorNode::get_singleton()->get_edited_scene(), "set_meta", "_edit_horizontal_guides_", hguides); undo_redo->add_undo_method(EditorNode::get_singleton()->get_edited_scene(), "set_meta", "_edit_horizontal_guides_", prev_hguides); - undo_redo->add_undo_method(viewport, "update"); + undo_redo->add_undo_method(viewport, "queue_redraw"); undo_redo->commit_action(); } else { hguides.push_back(edited.y); undo_redo->create_action(TTR("Create Horizontal Guide")); undo_redo->add_do_method(EditorNode::get_singleton()->get_edited_scene(), "set_meta", "_edit_horizontal_guides_", hguides); undo_redo->add_undo_method(EditorNode::get_singleton()->get_edited_scene(), "set_meta", "_edit_horizontal_guides_", prev_hguides); - undo_redo->add_undo_method(viewport, "update"); + undo_redo->add_undo_method(viewport, "queue_redraw"); undo_redo->commit_action(); } } else { @@ -1181,7 +1181,7 @@ bool CanvasItemEditor::_gui_input_rulers_and_guides(const Ref<InputEvent> &p_eve undo_redo->add_do_method(EditorNode::get_singleton()->get_edited_scene(), "set_meta", "_edit_horizontal_guides_", hguides); } undo_redo->add_undo_method(EditorNode::get_singleton()->get_edited_scene(), "set_meta", "_edit_horizontal_guides_", prev_hguides); - undo_redo->add_undo_method(viewport, "update"); + undo_redo->add_undo_method(viewport, "queue_redraw"); undo_redo->commit_action(); } } @@ -1197,7 +1197,7 @@ bool CanvasItemEditor::_gui_input_rulers_and_guides(const Ref<InputEvent> &p_eve undo_redo->add_do_method(EditorNode::get_singleton()->get_edited_scene(), "set_meta", "_edit_horizontal_guides_", hguides); undo_redo->add_undo_method(EditorNode::get_singleton()->get_edited_scene(), "set_meta", "_edit_vertical_guides_", prev_vguides); undo_redo->add_undo_method(EditorNode::get_singleton()->get_edited_scene(), "set_meta", "_edit_horizontal_guides_", prev_hguides); - undo_redo->add_undo_method(viewport, "update"); + undo_redo->add_undo_method(viewport, "queue_redraw"); undo_redo->commit_action(); } } @@ -1205,7 +1205,7 @@ bool CanvasItemEditor::_gui_input_rulers_and_guides(const Ref<InputEvent> &p_eve snap_target[0] = SNAP_TARGET_NONE; snap_target[1] = SNAP_TARGET_NONE; _reset_drag(); - viewport->update(); + viewport->queue_redraw(); return true; } } @@ -1380,7 +1380,7 @@ bool CanvasItemEditor::_gui_input_pivot(const Ref<InputEvent> &p_event) { if (b.is_valid() && b->get_button_index() == MouseButton::RIGHT && b->is_pressed()) { _restore_canvas_item_state(drag_selection); _reset_drag(); - viewport->update(); + viewport->queue_redraw(); return true; } } @@ -1430,7 +1430,7 @@ bool CanvasItemEditor::_gui_input_rotate(const Ref<InputEvent> &p_event) { //Rotate the opposite way if the canvas item's compounded scale has an uneven number of negative elements bool opposite = (canvas_item->get_global_transform().get_scale().sign().dot(canvas_item->get_transform().get_scale().sign()) == 0); canvas_item->_edit_set_rotation(snap_angle(canvas_item->_edit_get_rotation() + (opposite ? -1 : 1) * (drag_from - drag_rotation_center).angle_to(drag_to - drag_rotation_center), canvas_item->_edit_get_rotation())); - viewport->update(); + viewport->queue_redraw(); } return true; } @@ -1463,7 +1463,7 @@ bool CanvasItemEditor::_gui_input_rotate(const Ref<InputEvent> &p_event) { if (b.is_valid() && b->get_button_index() == MouseButton::RIGHT && b->is_pressed()) { _restore_canvas_item_state(drag_selection); _reset_drag(); - viewport->update(); + viewport->queue_redraw(); return true; } } @@ -1625,7 +1625,7 @@ bool CanvasItemEditor::_gui_input_anchors(const Ref<InputEvent> &p_event) { if (b.is_valid() && b->get_button_index() == MouseButton::RIGHT && b->is_pressed()) { _restore_canvas_item_state(drag_selection); _reset_drag(); - viewport->update(); + viewport->queue_redraw(); return true; } } @@ -1824,7 +1824,7 @@ bool CanvasItemEditor::_gui_input_resize(const Ref<InputEvent> &p_event) { snap_target[0] = SNAP_TARGET_NONE; snap_target[1] = SNAP_TARGET_NONE; _reset_drag(); - viewport->update(); + viewport->queue_redraw(); return true; } @@ -1834,7 +1834,7 @@ bool CanvasItemEditor::_gui_input_resize(const Ref<InputEvent> &p_event) { snap_target[0] = SNAP_TARGET_NONE; snap_target[1] = SNAP_TARGET_NONE; _reset_drag(); - viewport->update(); + viewport->queue_redraw(); return true; } } @@ -1963,7 +1963,7 @@ bool CanvasItemEditor::_gui_input_scale(const Ref<InputEvent> &p_event) { } _reset_drag(); - viewport->update(); + viewport->queue_redraw(); return true; } @@ -1971,7 +1971,7 @@ bool CanvasItemEditor::_gui_input_scale(const Ref<InputEvent> &p_event) { if (b.is_valid() && b->get_button_index() == MouseButton::RIGHT && b->is_pressed()) { _restore_canvas_item_state(drag_selection); _reset_drag(); - viewport->update(); + viewport->queue_redraw(); return true; } } @@ -2096,7 +2096,7 @@ bool CanvasItemEditor::_gui_input_move(const Ref<InputEvent> &p_event) { snap_target[1] = SNAP_TARGET_NONE; _reset_drag(); - viewport->update(); + viewport->queue_redraw(); return true; } @@ -2106,7 +2106,7 @@ bool CanvasItemEditor::_gui_input_move(const Ref<InputEvent> &p_event) { snap_target[0] = SNAP_TARGET_NONE; snap_target[1] = SNAP_TARGET_NONE; _reset_drag(); - viewport->update(); + viewport->queue_redraw(); return true; } } @@ -2214,7 +2214,7 @@ bool CanvasItemEditor::_gui_input_move(const Ref<InputEvent> &p_event) { } _reset_drag(); } - viewport->update(); + viewport->queue_redraw(); return true; } @@ -2339,7 +2339,7 @@ bool CanvasItemEditor::_gui_input_select(const Ref<InputEvent> &p_event) { if (!b->is_shift_pressed()) { // Clear the selection if not additive editor_selection->clear(); - viewport->update(); + viewport->queue_redraw(); selected_from_canvas = true; }; @@ -2415,21 +2415,21 @@ bool CanvasItemEditor::_gui_input_select(const Ref<InputEvent> &p_event) { } _reset_drag(); - viewport->update(); + viewport->queue_redraw(); return true; } if (b.is_valid() && b->is_pressed() && b->get_button_index() == MouseButton::RIGHT) { // Cancel box selection _reset_drag(); - viewport->update(); + viewport->queue_redraw(); return true; } if (m.is_valid()) { // Update box selection box_selecting_to = transform.affine_inverse().xform(m->get_position()); - viewport->update(); + viewport->queue_redraw(); return true; } } @@ -2437,7 +2437,7 @@ bool CanvasItemEditor::_gui_input_select(const Ref<InputEvent> &p_event) { if (k.is_valid() && k->is_pressed() && k->get_keycode() == Key::ESCAPE && drag_type == DRAG_NONE && tool == TOOL_SELECT) { // Unselect everything editor_selection->clear(); - viewport->update(); + viewport->queue_redraw(); } return false; } @@ -2463,12 +2463,12 @@ bool CanvasItemEditor::_gui_input_ruler_tool(const Ref<InputEvent> &p_event) { ruler_tool_active = false; } - viewport->update(); + viewport->queue_redraw(); return true; } if (m.is_valid() && (ruler_tool_active || (grid_snap_active && previous_origin != ruler_tool_origin))) { - viewport->update(); + viewport->queue_redraw(); return true; } @@ -2480,7 +2480,7 @@ bool CanvasItemEditor::_gui_input_hover(const Ref<InputEvent> &p_event) { if (m.is_valid()) { Point2 click = transform.affine_inverse().xform(m->get_position()); - // Checks if the hovered items changed, update the viewport if so + // Checks if the hovered items changed, redraw the viewport if so Vector<_SelectResult> hovering_results_items; _get_canvas_items_at_pos(click, hovering_results_items); hovering_results_items.sort(); @@ -2502,7 +2502,7 @@ bool CanvasItemEditor::_gui_input_hover(const Ref<InputEvent> &p_event) { hovering_results_tmp.push_back(hover_result); } - // Check if changed, if so, update. + // Check if changed, if so, redraw. bool changed = false; if (hovering_results_tmp.size() == hovering_results.size()) { for (int i = 0; i < hovering_results_tmp.size(); i++) { @@ -2519,7 +2519,7 @@ bool CanvasItemEditor::_gui_input_hover(const Ref<InputEvent> &p_event) { if (changed) { hovering_results = hovering_results_tmp; - viewport->update(); + viewport->queue_redraw(); } return true; @@ -3827,7 +3827,7 @@ void CanvasItemEditor::_draw_viewport() { void CanvasItemEditor::update_viewport() { _update_scrollbars(); - viewport->update(); + viewport->queue_redraw(); } void CanvasItemEditor::set_current_tool(Tool p_tool) { @@ -3895,7 +3895,7 @@ void CanvasItemEditor::_notification(int p_what) { Transform2D xform = canvas_item->get_transform(); if (rect != se->prev_rect || xform != se->prev_xform) { - viewport->update(); + viewport->queue_redraw(); se->prev_rect = rect; se->prev_xform = xform; } @@ -3917,7 +3917,7 @@ void CanvasItemEditor::_notification(int p_what) { se->prev_anchors[SIDE_RIGHT] = anchors[SIDE_RIGHT]; se->prev_anchors[SIDE_TOP] = anchors[SIDE_TOP]; se->prev_anchors[SIDE_BOTTOM] = anchors[SIDE_BOTTOM]; - viewport->update(); + viewport->queue_redraw(); } } @@ -3933,7 +3933,7 @@ void CanvasItemEditor::_notification(int p_what) { for (KeyValue<BoneKey, BoneList> &E : bone_list) { Object *b = ObjectDB::get_instance(E.key.from); if (!b) { - viewport->update(); + viewport->queue_redraw(); break; } @@ -3946,13 +3946,13 @@ void CanvasItemEditor::_notification(int p_what) { if (global_xform != E.value.xform) { E.value.xform = global_xform; - viewport->update(); + viewport->queue_redraw(); } Bone2D *bone = Object::cast_to<Bone2D>(b); if (bone && bone->get_length() != E.value.length) { E.value.length = bone->get_length(); - viewport->update(); + viewport->queue_redraw(); } } } break; @@ -4106,7 +4106,7 @@ void CanvasItemEditor::_update_scroll(real_t) { view_offset.x = h_scroll->get_value(); view_offset.y = v_scroll->get_value(); - viewport->update(); + viewport->queue_redraw(); } void CanvasItemEditor::_zoom_on_position(real_t p_zoom, Point2 p_position) { @@ -4148,12 +4148,12 @@ void CanvasItemEditor::_shortcut_zoom_set(real_t p_zoom) { void CanvasItemEditor::_button_toggle_smart_snap(bool p_status) { smart_snap_active = p_status; - viewport->update(); + viewport->queue_redraw(); } void CanvasItemEditor::_button_toggle_grid_snap(bool p_status) { grid_snap_active = p_status; - viewport->update(); + viewport->queue_redraw(); } void CanvasItemEditor::_button_override_camera(bool p_pressed) { @@ -4174,7 +4174,7 @@ void CanvasItemEditor::_button_tool_select(int p_index) { tool = (Tool)p_index; - viewport->update(); + viewport->queue_redraw(); _update_cursor(); } @@ -4276,25 +4276,25 @@ void CanvasItemEditor::_popup_callback(int p_op) { show_origin = !show_origin; int idx = view_menu->get_popup()->get_item_index(SHOW_ORIGIN); view_menu->get_popup()->set_item_checked(idx, show_origin); - viewport->update(); + viewport->queue_redraw(); } break; case SHOW_VIEWPORT: { show_viewport = !show_viewport; int idx = view_menu->get_popup()->get_item_index(SHOW_VIEWPORT); view_menu->get_popup()->set_item_checked(idx, show_viewport); - viewport->update(); + viewport->queue_redraw(); } break; case SHOW_EDIT_LOCKS: { show_edit_locks = !show_edit_locks; int idx = view_menu->get_popup()->get_item_index(SHOW_EDIT_LOCKS); view_menu->get_popup()->set_item_checked(idx, show_edit_locks); - viewport->update(); + viewport->queue_redraw(); } break; case SHOW_TRANSFORMATION_GIZMOS: { show_transformation_gizmos = !show_transformation_gizmos; int idx = view_menu->get_popup()->get_item_index(SHOW_TRANSFORMATION_GIZMOS); view_menu->get_popup()->set_item_checked(idx, show_transformation_gizmos); - viewport->update(); + viewport->queue_redraw(); } break; case SNAP_USE_NODE_PARENT: { snap_node_parent = !snap_node_parent; @@ -4340,7 +4340,7 @@ void CanvasItemEditor::_popup_callback(int p_op) { snap_relative = !snap_relative; int idx = snap_config_menu->get_popup()->get_item_index(SNAP_RELATIVE); snap_config_menu->get_popup()->set_item_checked(idx, snap_relative); - viewport->update(); + viewport->queue_redraw(); } break; case SNAP_USE_PIXEL: { snap_pixel = !snap_pixel; @@ -4370,20 +4370,20 @@ void CanvasItemEditor::_popup_callback(int p_op) { show_helpers = !show_helpers; int idx = view_menu->get_popup()->get_item_index(SHOW_HELPERS); view_menu->get_popup()->set_item_checked(idx, show_helpers); - viewport->update(); + viewport->queue_redraw(); } break; case SHOW_RULERS: { show_rulers = !show_rulers; int idx = view_menu->get_popup()->get_item_index(SHOW_RULERS); view_menu->get_popup()->set_item_checked(idx, show_rulers); _update_scrollbars(); - viewport->update(); + viewport->queue_redraw(); } break; case SHOW_GUIDES: { show_guides = !show_guides; int idx = view_menu->get_popup()->get_item_index(SHOW_GUIDES); view_menu->get_popup()->set_item_checked(idx, show_guides); - viewport->update(); + viewport->queue_redraw(); } break; case LOCK_SELECTED: { undo_redo->create_action(TTR("Lock Selected")); @@ -4403,8 +4403,8 @@ void CanvasItemEditor::_popup_callback(int p_op) { undo_redo->add_do_method(this, "emit_signal", "item_lock_status_changed"); undo_redo->add_undo_method(this, "emit_signal", "item_lock_status_changed"); } - undo_redo->add_do_method(viewport, "update"); - undo_redo->add_undo_method(viewport, "update"); + undo_redo->add_do_method(viewport, "queue_redraw"); + undo_redo->add_undo_method(viewport, "queue_redraw"); undo_redo->commit_action(); } break; case UNLOCK_SELECTED: { @@ -4425,8 +4425,8 @@ void CanvasItemEditor::_popup_callback(int p_op) { undo_redo->add_do_method(this, "emit_signal", "item_lock_status_changed"); undo_redo->add_undo_method(this, "emit_signal", "item_lock_status_changed"); } - undo_redo->add_do_method(viewport, "update"); - undo_redo->add_undo_method(viewport, "update"); + undo_redo->add_do_method(viewport, "queue_redraw"); + undo_redo->add_undo_method(viewport, "queue_redraw"); undo_redo->commit_action(); } break; case GROUP_SELECTED: { @@ -4447,8 +4447,8 @@ void CanvasItemEditor::_popup_callback(int p_op) { undo_redo->add_do_method(this, "emit_signal", "item_group_status_changed"); undo_redo->add_undo_method(this, "emit_signal", "item_group_status_changed"); } - undo_redo->add_do_method(viewport, "update"); - undo_redo->add_undo_method(viewport, "update"); + undo_redo->add_do_method(viewport, "queue_redraw"); + undo_redo->add_undo_method(viewport, "queue_redraw"); undo_redo->commit_action(); } break; case UNGROUP_SELECTED: { @@ -4469,8 +4469,8 @@ void CanvasItemEditor::_popup_callback(int p_op) { undo_redo->add_do_method(this, "emit_signal", "item_group_status_changed"); undo_redo->add_undo_method(this, "emit_signal", "item_group_status_changed"); } - undo_redo->add_do_method(viewport, "update"); - undo_redo->add_undo_method(viewport, "update"); + undo_redo->add_do_method(viewport, "queue_redraw"); + undo_redo->add_undo_method(viewport, "queue_redraw"); undo_redo->commit_action(); } break; @@ -4590,7 +4590,7 @@ void CanvasItemEditor::_popup_callback(int p_op) { undo_redo->add_do_method(root, "remove_meta", "_edit_vertical_guides_"); undo_redo->add_undo_method(root, "set_meta", "_edit_vertical_guides_", vguides); } - undo_redo->add_undo_method(viewport, "update"); + undo_redo->add_undo_method(viewport, "queue_redraw"); undo_redo->commit_action(); } @@ -4704,7 +4704,7 @@ void CanvasItemEditor::_focus_selection(int p_op) { real_t scale_y = viewport->get_size().y / rect.size.y; zoom = scale_x < scale_y ? scale_x : scale_y; zoom *= 0.90; - viewport->update(); + viewport->queue_redraw(); zoom_widget->set_zoom(zoom); call_deferred(SNAME("_popup_callback"), VIEW_CENTER_TO_SELECTION); } @@ -4930,7 +4930,7 @@ void CanvasItemEditor::set_state(const Dictionary &p_state) { if (update_scrollbars) { _update_scrollbars(); } - viewport->update(); + viewport->queue_redraw(); } void CanvasItemEditor::add_control_to_menu_panel(Control *p_control) { @@ -4980,7 +4980,7 @@ CanvasItemEditor::CanvasItemEditor() { undo_redo = EditorNode::get_singleton()->get_undo_redo(); editor_selection = EditorNode::get_singleton()->get_editor_selection(); editor_selection->add_editor_plugin(this); - editor_selection->connect("selection_changed", callable_mp((CanvasItem *)this, &CanvasItem::update)); + editor_selection->connect("selection_changed", callable_mp((CanvasItem *)this, &CanvasItem::queue_redraw)); editor_selection->connect("selection_changed", callable_mp(this, &CanvasItemEditor::_selection_changed)); SceneTreeDock::get_singleton()->connect("node_created", callable_mp(this, &CanvasItemEditor::_node_created)); diff --git a/editor/plugins/curve_editor_plugin.cpp b/editor/plugins/curve_editor_plugin.cpp index 013a9f10a4..0e84381279 100644 --- a/editor/plugins/curve_editor_plugin.cpp +++ b/editor/plugins/curve_editor_plugin.cpp @@ -87,7 +87,7 @@ void CurveEditor::set_curve(Ref<Curve> curve) { _hover_point = -1; _selected_tangent = TANGENT_NONE; - update(); + queue_redraw(); // Note: if you edit a curve, then set another, and try to undo, // it will normally apply on the previous curve, but you won't see it @@ -311,7 +311,7 @@ void CurveEditor::on_preset_item_selected(int preset_id) { } void CurveEditor::_curve_changed() { - update(); + queue_redraw(); // Point count can change in case of undo if (_selected_point >= _curve_ref->get_point_count()) { set_selected_point(-1); @@ -512,14 +512,14 @@ void CurveEditor::toggle_linear(TangentIndex tangent) { void CurveEditor::set_selected_point(int index) { if (index != _selected_point) { _selected_point = index; - update(); + queue_redraw(); } } void CurveEditor::set_hover_point_index(int index) { if (index != _hover_point) { _hover_point = index; - update(); + queue_redraw(); } } @@ -579,7 +579,7 @@ template <typename T> static void plot_curve_accurate(const Curve &curve, float step, T plot_func) { if (curve.get_point_count() <= 1) { // Not enough points to make a curve, so it's just a straight line - float y = curve.interpolate(0); + float y = curve.sample(0); plot_func(Vector2(0, y), Vector2(1.f, y), true); } else { @@ -603,7 +603,7 @@ static void plot_curve_accurate(const Curve &curve, float step, T plot_func) { for (float x = step; x < len; x += step) { pos.x = a.x + x; - pos.y = curve.interpolate_local_nocheck(i - 1, x); + pos.y = curve.sample_local_nocheck(i - 1, x); plot_func(prev_pos, pos, true); prev_pos = pos; } @@ -817,7 +817,7 @@ Ref<Texture2D> CurvePreviewGenerator::generate(const Ref<Resource> &p_from, cons int prev_y = 0; for (int x = 0; x < im.get_width(); ++x) { float t = static_cast<float>(x) / im.get_width(); - float v = (curve.interpolate_baked(t) - curve.get_min_value()) / range_y; + float v = (curve.sample_baked(t) - curve.get_min_value()) / range_y; int y = CLAMP(im.get_height() - v * im.get_height(), 0, im.get_height()); // Plot point diff --git a/editor/plugins/editor_preview_plugins.cpp b/editor/plugins/editor_preview_plugins.cpp index f4a718119e..369ab0745e 100644 --- a/editor/plugins/editor_preview_plugins.cpp +++ b/editor/plugins/editor_preview_plugins.cpp @@ -342,6 +342,12 @@ EditorMaterialPreviewPlugin::EditorMaterialPreviewPlugin() { RS::get_singleton()->camera_set_transform(camera, Transform3D(Basis(), Vector3(0, 0, 3))); RS::get_singleton()->camera_set_perspective(camera, 45, 0.1, 10); + if (GLOBAL_GET("rendering/lights_and_shadows/use_physical_light_units")) { + camera_attributes = RS::get_singleton()->camera_attributes_create(); + RS::get_singleton()->camera_attributes_set_exposure(camera_attributes, 1.0, 0.000032552); // Matches default CameraAttributesPhysical to work well with default DirectionalLight3Ds. + RS::get_singleton()->camera_set_camera_attributes(camera, camera_attributes); + } + light = RS::get_singleton()->directional_light_create(); light_instance = RS::get_singleton()->instance_create2(light, scenario); RS::get_singleton()->instance_set_transform(light_instance, Transform3D().looking_at(Vector3(-1, -1, -1), Vector3(0, 1, 0))); @@ -440,6 +446,7 @@ EditorMaterialPreviewPlugin::~EditorMaterialPreviewPlugin() { RS::get_singleton()->free(light2); RS::get_singleton()->free(light_instance2); RS::get_singleton()->free(camera); + RS::get_singleton()->free(camera_attributes); RS::get_singleton()->free(scenario); } @@ -743,6 +750,12 @@ EditorMeshPreviewPlugin::EditorMeshPreviewPlugin() { //RS::get_singleton()->camera_set_perspective(camera,45,0.1,10); RS::get_singleton()->camera_set_orthogonal(camera, 1.0, 0.01, 1000.0); + if (GLOBAL_GET("rendering/lights_and_shadows/use_physical_light_units")) { + camera_attributes = RS::get_singleton()->camera_attributes_create(); + RS::get_singleton()->camera_attributes_set_exposure(camera_attributes, 1.0, 0.000032552); // Matches default CameraAttributesPhysical to work well with default DirectionalLight3Ds. + RS::get_singleton()->camera_set_camera_attributes(camera, camera_attributes); + } + light = RS::get_singleton()->directional_light_create(); light_instance = RS::get_singleton()->instance_create2(light, scenario); RS::get_singleton()->instance_set_transform(light_instance, Transform3D().looking_at(Vector3(-1, -1, -1), Vector3(0, 1, 0))); @@ -768,6 +781,7 @@ EditorMeshPreviewPlugin::~EditorMeshPreviewPlugin() { RS::get_singleton()->free(light2); RS::get_singleton()->free(light_instance2); RS::get_singleton()->free(camera); + RS::get_singleton()->free(camera_attributes); RS::get_singleton()->free(scenario); } diff --git a/editor/plugins/editor_preview_plugins.h b/editor/plugins/editor_preview_plugins.h index 163cfe79f9..efb2c80cfd 100644 --- a/editor/plugins/editor_preview_plugins.h +++ b/editor/plugins/editor_preview_plugins.h @@ -91,6 +91,7 @@ class EditorMaterialPreviewPlugin : public EditorResourcePreviewGenerator { RID light2; RID light_instance2; RID camera; + RID camera_attributes; Semaphore preview_done; void _generate_frame_started(); @@ -133,6 +134,7 @@ class EditorMeshPreviewPlugin : public EditorResourcePreviewGenerator { RID light2; RID light_instance2; RID camera; + RID camera_attributes; Semaphore preview_done; void _generate_frame_started(); diff --git a/editor/plugins/font_config_plugin.cpp b/editor/plugins/font_config_plugin.cpp index 935b0a5501..2df951518e 100644 --- a/editor/plugins/font_config_plugin.cpp +++ b/editor/plugins/font_config_plugin.cpp @@ -942,7 +942,7 @@ Size2 FontPreview::get_minimum_size() const { void FontPreview::set_data(const Ref<Font> &p_f) { prev_font = p_f; - update(); + queue_redraw(); } FontPreview::FontPreview() { diff --git a/editor/plugins/gradient_editor.cpp b/editor/plugins/gradient_editor.cpp new file mode 100644 index 0000000000..c13b162db6 --- /dev/null +++ b/editor/plugins/gradient_editor.cpp @@ -0,0 +1,492 @@ +/*************************************************************************/ +/* gradient_editor.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* 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 "gradient_editor.h" + +#include "core/os/keyboard.h" +#include "editor/editor_node.h" +#include "editor/editor_scale.h" +#include "editor/editor_undo_redo_manager.h" + +void GradientEditor::set_gradient(const Ref<Gradient> &p_gradient) { + gradient = p_gradient; + connect("ramp_changed", callable_mp(this, &GradientEditor::_ramp_changed)); + gradient->connect("changed", callable_mp(this, &GradientEditor::_gradient_changed)); + set_points(gradient->get_points()); + set_interpolation_mode(gradient->get_interpolation_mode()); +} + +void GradientEditor::reverse_gradient() { + gradient->reverse(); + set_points(gradient->get_points()); + emit_signal(SNAME("ramp_changed")); + queue_redraw(); +} + +int GradientEditor::_get_point_from_pos(int x) { + int result = -1; + int total_w = get_size().width - get_size().height - draw_spacing; + float min_distance = 1e20; + for (int i = 0; i < points.size(); i++) { + // Check if we clicked at point. + float distance = ABS(x - points[i].offset * total_w); + float min = (draw_point_width / 2 * 1.7); //make it easier to grab + if (distance <= min && distance < min_distance) { + result = i; + min_distance = distance; + } + } + return result; +} + +void GradientEditor::_show_color_picker() { + if (grabbed == -1) { + return; + } + picker->set_pick_color(points[grabbed].color); + Size2 minsize = popup->get_contents_minimum_size(); + bool show_above = false; + if (get_global_position().y + get_size().y + minsize.y > get_viewport_rect().size.y) { + show_above = true; + } + if (show_above) { + popup->set_position(get_screen_position() - Vector2(0, minsize.y)); + } else { + popup->set_position(get_screen_position() + Vector2(0, get_size().y)); + } + popup->popup(); +} + +void GradientEditor::_gradient_changed() { + if (editing) { + return; + } + + editing = true; + Vector<Gradient::Point> points = gradient->get_points(); + set_points(points); + set_interpolation_mode(gradient->get_interpolation_mode()); + queue_redraw(); + editing = false; +} + +void GradientEditor::_ramp_changed() { + editing = true; + Ref<EditorUndoRedoManager> undo_redo = EditorNode::get_undo_redo(); + undo_redo->create_action(TTR("Gradient Edited"), UndoRedo::MERGE_ENDS); + undo_redo->add_do_method(gradient.ptr(), "set_offsets", get_offsets()); + undo_redo->add_do_method(gradient.ptr(), "set_colors", get_colors()); + undo_redo->add_do_method(gradient.ptr(), "set_interpolation_mode", get_interpolation_mode()); + undo_redo->add_undo_method(gradient.ptr(), "set_offsets", gradient->get_offsets()); + undo_redo->add_undo_method(gradient.ptr(), "set_colors", gradient->get_colors()); + undo_redo->add_undo_method(gradient.ptr(), "set_interpolation_mode", gradient->get_interpolation_mode()); + undo_redo->commit_action(); + editing = false; +} + +void GradientEditor::_color_changed(const Color &p_color) { + if (grabbed == -1) { + return; + } + points.write[grabbed].color = p_color; + queue_redraw(); + emit_signal(SNAME("ramp_changed")); +} + +void GradientEditor::set_ramp(const Vector<float> &p_offsets, const Vector<Color> &p_colors) { + ERR_FAIL_COND(p_offsets.size() != p_colors.size()); + points.clear(); + for (int i = 0; i < p_offsets.size(); i++) { + Gradient::Point p; + p.offset = p_offsets[i]; + p.color = p_colors[i]; + points.push_back(p); + } + + points.sort(); + queue_redraw(); +} + +Vector<float> GradientEditor::get_offsets() const { + Vector<float> ret; + for (int i = 0; i < points.size(); i++) { + ret.push_back(points[i].offset); + } + return ret; +} + +Vector<Color> GradientEditor::get_colors() const { + Vector<Color> ret; + for (int i = 0; i < points.size(); i++) { + ret.push_back(points[i].color); + } + return ret; +} + +void GradientEditor::set_points(Vector<Gradient::Point> &p_points) { + if (points.size() != p_points.size()) { + grabbed = -1; + } + points.clear(); + points = p_points; + points.sort(); +} + +Vector<Gradient::Point> &GradientEditor::get_points() { + return points; +} + +void GradientEditor::set_interpolation_mode(Gradient::InterpolationMode p_interp_mode) { + interpolation_mode = p_interp_mode; +} + +Gradient::InterpolationMode GradientEditor::get_interpolation_mode() { + return interpolation_mode; +} + +ColorPicker *GradientEditor::get_picker() { + return picker; +} + +PopupPanel *GradientEditor::get_popup() { + return popup; +} + +Size2 GradientEditor::get_minimum_size() const { + return Size2(0, 60) * EDSCALE; +} + +void GradientEditor::gui_input(const Ref<InputEvent> &p_event) { + ERR_FAIL_COND(p_event.is_null()); + + Ref<InputEventKey> k = p_event; + + if (k.is_valid() && k->is_pressed() && k->get_keycode() == Key::KEY_DELETE && grabbed != -1) { + points.remove_at(grabbed); + grabbed = -1; + grabbing = false; + queue_redraw(); + emit_signal(SNAME("ramp_changed")); + accept_event(); + } + + Ref<InputEventMouseButton> mb = p_event; + // Show color picker on double click. + if (mb.is_valid() && mb->get_button_index() == MouseButton::LEFT && mb->is_double_click() && mb->is_pressed()) { + grabbed = _get_point_from_pos(mb->get_position().x); + _show_color_picker(); + accept_event(); + } + + // Delete point on right click. + if (mb.is_valid() && mb->get_button_index() == MouseButton::RIGHT && mb->is_pressed()) { + grabbed = _get_point_from_pos(mb->get_position().x); + if (grabbed != -1) { + points.remove_at(grabbed); + grabbed = -1; + grabbing = false; + queue_redraw(); + emit_signal(SNAME("ramp_changed")); + accept_event(); + } + } + + // Hold alt key to duplicate selected color. + if (mb.is_valid() && mb->get_button_index() == MouseButton::LEFT && mb->is_pressed() && mb->is_alt_pressed()) { + int x = mb->get_position().x; + grabbed = _get_point_from_pos(x); + + if (grabbed != -1) { + int total_w = get_size().width - get_size().height - draw_spacing; + Gradient::Point new_point = points[grabbed]; + new_point.offset = CLAMP(x / float(total_w), 0, 1); + + points.push_back(new_point); + points.sort(); + for (int i = 0; i < points.size(); ++i) { + if (points[i].offset == new_point.offset) { + grabbed = i; + break; + } + } + + emit_signal(SNAME("ramp_changed")); + queue_redraw(); + } + } + + // Select. + if (mb.is_valid() && mb->get_button_index() == MouseButton::LEFT && mb->is_pressed()) { + queue_redraw(); + int x = mb->get_position().x; + int total_w = get_size().width - get_size().height - draw_spacing; + + //Check if color selector was clicked. + if (x > total_w + draw_spacing) { + _show_color_picker(); + return; + } + + grabbing = true; + + grabbed = _get_point_from_pos(x); + //grab or select + if (grabbed != -1) { + return; + } + + // Insert point. + Gradient::Point new_point; + new_point.offset = CLAMP(x / float(total_w), 0, 1); + + Gradient::Point prev; + Gradient::Point next; + + int pos = -1; + for (int i = 0; i < points.size(); i++) { + if (points[i].offset < new_point.offset) { + pos = i; + } + } + + if (pos == -1) { + prev.color = Color(0, 0, 0); + prev.offset = 0; + if (points.size()) { + next = points[0]; + } else { + next.color = Color(1, 1, 1); + next.offset = 1.0; + } + } else { + if (pos == points.size() - 1) { + next.color = Color(1, 1, 1); + next.offset = 1.0; + } else { + next = points[pos + 1]; + } + prev = points[pos]; + } + + new_point.color = prev.color.lerp(next.color, (new_point.offset - prev.offset) / (next.offset - prev.offset)); + + points.push_back(new_point); + points.sort(); + for (int i = 0; i < points.size(); i++) { + if (points[i].offset == new_point.offset) { + grabbed = i; + break; + } + } + + emit_signal(SNAME("ramp_changed")); + } + + if (mb.is_valid() && mb->get_button_index() == MouseButton::LEFT && !mb->is_pressed()) { + if (grabbing) { + grabbing = false; + emit_signal(SNAME("ramp_changed")); + } + queue_redraw(); + } + + Ref<InputEventMouseMotion> mm = p_event; + + if (mm.is_valid() && grabbing) { + int total_w = get_size().width - get_size().height - draw_spacing; + + int x = mm->get_position().x; + + float newofs = CLAMP(x / float(total_w), 0, 1); + + // Snap to "round" coordinates if holding Ctrl. + // Be more precise if holding Shift as well. + if (mm->is_ctrl_pressed()) { + newofs = Math::snapped(newofs, mm->is_shift_pressed() ? 0.025 : 0.1); + } else if (mm->is_shift_pressed()) { + // Snap to nearest point if holding just Shift + const float snap_threshold = 0.03; + float smallest_ofs = snap_threshold; + bool found = false; + int nearest_point = 0; + for (int i = 0; i < points.size(); ++i) { + if (i != grabbed) { + float temp_ofs = ABS(points[i].offset - newofs); + if (temp_ofs < smallest_ofs) { + smallest_ofs = temp_ofs; + nearest_point = i; + if (found) { + break; + } + found = true; + } + } + } + if (found) { + if (points[nearest_point].offset < newofs) { + newofs = points[nearest_point].offset + 0.00001; + } else { + newofs = points[nearest_point].offset - 0.00001; + } + newofs = CLAMP(newofs, 0, 1); + } + } + + bool valid = true; + for (int i = 0; i < points.size(); i++) { + if (points[i].offset == newofs && i != grabbed) { + valid = false; + break; + } + } + + if (!valid || grabbed == -1) { + return; + } + points.write[grabbed].offset = newofs; + + points.sort(); + for (int i = 0; i < points.size(); i++) { + if (points[i].offset == newofs) { + grabbed = i; + break; + } + } + + emit_signal(SNAME("ramp_changed")); + + queue_redraw(); + } +} + +void GradientEditor::_notification(int p_what) { + switch (p_what) { + case NOTIFICATION_ENTER_TREE: { + if (!picker->is_connected("color_changed", callable_mp(this, &GradientEditor::_color_changed))) { + picker->connect("color_changed", callable_mp(this, &GradientEditor::_color_changed)); + } + [[fallthrough]]; + } + case NOTIFICATION_THEME_CHANGED: { + draw_spacing = BASE_SPACING * get_theme_default_base_scale(); + draw_point_width = BASE_POINT_WIDTH * get_theme_default_base_scale(); + } break; + + case NOTIFICATION_DRAW: { + int w = get_size().x; + int h = get_size().y; + + if (w == 0 || h == 0) { + return; // Safety check. We have division by 'h'. And in any case there is nothing to draw with such size. + } + + int total_w = get_size().width - get_size().height - draw_spacing; + + // Draw checker pattern for ramp. + draw_texture_rect(get_theme_icon(SNAME("GuiMiniCheckerboard"), SNAME("EditorIcons")), Rect2(0, 0, total_w, h), true); + + // Draw color ramp. + gradient_cache->set_points(points); + gradient_cache->set_interpolation_mode(interpolation_mode); + preview_texture->set_gradient(gradient_cache); + draw_texture_rect(preview_texture, Rect2(0, 0, total_w, h)); + + // Draw point markers. + for (int i = 0; i < points.size(); i++) { + Color col = points[i].color.inverted(); + col.a = 0.9; + + draw_line(Vector2(points[i].offset * total_w, 0), Vector2(points[i].offset * total_w, h / 2), col); + Rect2 rect = Rect2(points[i].offset * total_w - draw_point_width / 2, h / 2, draw_point_width, h / 2); + draw_rect(rect, points[i].color, true); + draw_rect(rect, col, false); + if (grabbed == i) { + rect = rect.grow(-1); + if (has_focus()) { + draw_rect(rect, Color(1, 0, 0, 0.9), false); + } else { + draw_rect(rect, Color(0.6, 0, 0, 0.9), false); + } + + rect = rect.grow(-1); + draw_rect(rect, col, false); + } + } + + // Draw "button" for color selector. + draw_texture_rect(get_theme_icon(SNAME("GuiMiniCheckerboard"), SNAME("EditorIcons")), Rect2(total_w + draw_spacing, 0, h, h), true); + if (grabbed != -1) { + // Draw with selection color. + draw_rect(Rect2(total_w + draw_spacing, 0, h, h), points[grabbed].color); + } else { + // If no color selected draw grey color with 'X' on top. + draw_rect(Rect2(total_w + draw_spacing, 0, h, h), Color(0.5, 0.5, 0.5, 1)); + draw_line(Vector2(total_w + draw_spacing, 0), Vector2(total_w + draw_spacing + h, h), Color(1, 1, 1, 0.6)); + draw_line(Vector2(total_w + draw_spacing, h), Vector2(total_w + draw_spacing + h, 0), Color(1, 1, 1, 0.6)); + } + + // Draw borders around color ramp if in focus. + if (has_focus()) { + draw_line(Vector2(-1, -1), Vector2(total_w + 1, -1), Color(1, 1, 1, 0.6)); + draw_line(Vector2(total_w + 1, -1), Vector2(total_w + 1, h + 1), Color(1, 1, 1, 0.6)); + draw_line(Vector2(total_w + 1, h + 1), Vector2(-1, h + 1), Color(1, 1, 1, 0.6)); + draw_line(Vector2(-1, -1), Vector2(-1, h + 1), Color(1, 1, 1, 0.6)); + } + } break; + + case NOTIFICATION_VISIBILITY_CHANGED: { + if (!is_visible()) { + grabbing = false; + } + } break; + } +} + +void GradientEditor::_bind_methods() { + ADD_SIGNAL(MethodInfo("ramp_changed")); +} + +GradientEditor::GradientEditor() { + set_focus_mode(FOCUS_ALL); + + popup = memnew(PopupPanel); + picker = memnew(ColorPicker); + popup->add_child(picker); + popup->connect("about_to_popup", callable_mp(EditorNode::get_singleton(), &EditorNode::setup_color_picker).bind(GradientEditor::get_picker())); + + gradient_cache.instantiate(); + preview_texture.instantiate(); + + preview_texture->set_width(1024); + add_child(popup, false, INTERNAL_MODE_FRONT); +} + +GradientEditor::~GradientEditor() { +} diff --git a/editor/plugins/gradient_editor.h b/editor/plugins/gradient_editor.h new file mode 100644 index 0000000000..816b539ba2 --- /dev/null +++ b/editor/plugins/gradient_editor.h @@ -0,0 +1,96 @@ +/*************************************************************************/ +/* gradient_editor.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* 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 GRADIENT_EDITOR_H +#define GRADIENT_EDITOR_H + +#include "scene/gui/color_picker.h" +#include "scene/gui/popup.h" +#include "scene/resources/gradient.h" + +class GradientEditor : public Control { + GDCLASS(GradientEditor, Control); + + PopupPanel *popup = nullptr; + ColorPicker *picker = nullptr; + + bool grabbing = false; + int grabbed = -1; + Vector<Gradient::Point> points; + Gradient::InterpolationMode interpolation_mode = Gradient::GRADIENT_INTERPOLATE_LINEAR; + + bool editing = false; + Ref<Gradient> gradient; + Ref<Gradient> gradient_cache; + Ref<GradientTexture1D> preview_texture; + + // Make sure to use the scaled value below. + const int BASE_SPACING = 3; + const int BASE_POINT_WIDTH = 8; + + int draw_spacing = BASE_SPACING; + int draw_point_width = BASE_POINT_WIDTH; + + void _gradient_changed(); + void _ramp_changed(); + void _color_changed(const Color &p_color); + + int _get_point_from_pos(int x); + void _show_color_picker(); + +protected: + virtual void gui_input(const Ref<InputEvent> &p_event) override; + void _notification(int p_what); + static void _bind_methods(); + +public: + void set_gradient(const Ref<Gradient> &p_gradient); + void reverse_gradient(); + + void set_ramp(const Vector<float> &p_offsets, const Vector<Color> &p_colors); + + Vector<float> get_offsets() const; + Vector<Color> get_colors() const; + void set_points(Vector<Gradient::Point> &p_points); + Vector<Gradient::Point> &get_points(); + + void set_interpolation_mode(Gradient::InterpolationMode p_interp_mode); + Gradient::InterpolationMode get_interpolation_mode(); + + ColorPicker *get_picker(); + PopupPanel *get_popup(); + + virtual Size2 get_minimum_size() const override; + + GradientEditor(); + virtual ~GradientEditor(); +}; + +#endif // GRADIENT_EDITOR_H diff --git a/editor/plugins/gradient_editor_plugin.cpp b/editor/plugins/gradient_editor_plugin.cpp index f368d5bea1..0f412aaefd 100644 --- a/editor/plugins/gradient_editor_plugin.cpp +++ b/editor/plugins/gradient_editor_plugin.cpp @@ -37,62 +37,6 @@ #include "editor/editor_undo_redo_manager.h" #include "node_3d_editor_plugin.h" -Size2 GradientEditor::get_minimum_size() const { - return Size2(0, 60) * EDSCALE; -} - -void GradientEditor::_gradient_changed() { - if (editing) { - return; - } - - editing = true; - Vector<Gradient::Point> points = gradient->get_points(); - set_points(points); - set_interpolation_mode(gradient->get_interpolation_mode()); - update(); - editing = false; -} - -void GradientEditor::_ramp_changed() { - editing = true; - Ref<EditorUndoRedoManager> undo_redo = EditorNode::get_undo_redo(); - undo_redo->create_action(TTR("Gradient Edited"), UndoRedo::MERGE_ENDS); - undo_redo->add_do_method(gradient.ptr(), "set_offsets", get_offsets()); - undo_redo->add_do_method(gradient.ptr(), "set_colors", get_colors()); - undo_redo->add_do_method(gradient.ptr(), "set_interpolation_mode", get_interpolation_mode()); - undo_redo->add_undo_method(gradient.ptr(), "set_offsets", gradient->get_offsets()); - undo_redo->add_undo_method(gradient.ptr(), "set_colors", gradient->get_colors()); - undo_redo->add_undo_method(gradient.ptr(), "set_interpolation_mode", gradient->get_interpolation_mode()); - undo_redo->commit_action(); - editing = false; -} - -void GradientEditor::_bind_methods() { -} - -void GradientEditor::set_gradient(const Ref<Gradient> &p_gradient) { - gradient = p_gradient; - connect("ramp_changed", callable_mp(this, &GradientEditor::_ramp_changed)); - gradient->connect("changed", callable_mp(this, &GradientEditor::_gradient_changed)); - set_points(gradient->get_points()); - set_interpolation_mode(gradient->get_interpolation_mode()); -} - -void GradientEditor::reverse_gradient() { - gradient->reverse(); - set_points(gradient->get_points()); - emit_signal(SNAME("ramp_changed")); - update(); -} - -GradientEditor::GradientEditor() { - GradientEdit::get_popup()->connect("about_to_popup", callable_mp(EditorNode::get_singleton(), &EditorNode::setup_color_picker).bind(GradientEdit::get_picker())); - editing = false; -} - -/////////////////////// - void GradientReverseButton::_notification(int p_what) { switch (p_what) { case NOTIFICATION_DRAW: { diff --git a/editor/plugins/gradient_editor_plugin.h b/editor/plugins/gradient_editor_plugin.h index 26bf76fecd..ab191d83e2 100644 --- a/editor/plugins/gradient_editor_plugin.h +++ b/editor/plugins/gradient_editor_plugin.h @@ -32,26 +32,7 @@ #define GRADIENT_EDITOR_PLUGIN_H #include "editor/editor_plugin.h" -#include "scene/gui/gradient_edit.h" - -class GradientEditor : public GradientEdit { - GDCLASS(GradientEditor, GradientEdit); - - bool editing; - Ref<Gradient> gradient; - - void _gradient_changed(); - void _ramp_changed(); - -protected: - static void _bind_methods(); - -public: - virtual Size2 get_minimum_size() const override; - void set_gradient(const Ref<Gradient> &p_gradient); - void reverse_gradient(); - GradientEditor(); -}; +#include "gradient_editor.h" class GradientReverseButton : public BaseButton { GDCLASS(GradientReverseButton, BaseButton); diff --git a/editor/plugins/gradient_texture_2d_editor_plugin.cpp b/editor/plugins/gradient_texture_2d_editor_plugin.cpp index 5aaf450d3f..dc01a52bb3 100644 --- a/editor/plugins/gradient_texture_2d_editor_plugin.cpp +++ b/editor/plugins/gradient_texture_2d_editor_plugin.cpp @@ -89,17 +89,17 @@ void GradientTexture2DEditorRect::gui_input(const Ref<InputEvent> &p_event) { void GradientTexture2DEditorRect::set_texture(Ref<GradientTexture2D> &p_texture) { texture = p_texture; - texture->connect("changed", callable_mp((CanvasItem *)this, &CanvasItem::update)); + texture->connect("changed", callable_mp((CanvasItem *)this, &CanvasItem::queue_redraw)); } void GradientTexture2DEditorRect::set_snap_enabled(bool p_snap_enabled) { snap_enabled = p_snap_enabled; - update(); + queue_redraw(); } void GradientTexture2DEditorRect::set_snap_size(float p_snap_size) { snap_size = p_snap_size; - update(); + queue_redraw(); } void GradientTexture2DEditorRect::_notification(int p_what) { diff --git a/editor/plugins/material_editor_plugin.cpp b/editor/plugins/material_editor_plugin.cpp index 74a6e90a6d..d204873f92 100644 --- a/editor/plugins/material_editor_plugin.cpp +++ b/editor/plugins/material_editor_plugin.cpp @@ -30,6 +30,7 @@ #include "material_editor_plugin.h" +#include "core/config/project_settings.h" #include "editor/editor_node.h" #include "editor/editor_scale.h" #include "editor/editor_settings.h" @@ -153,7 +154,7 @@ MaterialEditor::MaterialEditor() { vc->add_child(viewport); viewport->set_disable_input(true); viewport->set_transparent_background(true); - viewport->set_msaa(Viewport::MSAA_4X); + viewport->set_msaa_3d(Viewport::MSAA_4X); camera = memnew(Camera3D); camera->set_transform(Transform3D(Basis(), Vector3(0, 0, 3))); @@ -161,6 +162,10 @@ MaterialEditor::MaterialEditor() { // without much distortion. camera->set_perspective(20, 0.1, 10); camera->make_current(); + if (GLOBAL_GET("rendering/lights_and_shadows/use_physical_light_units")) { + camera_attributes.instantiate(); + camera->set_attributes(camera_attributes); + } viewport->add_child(camera); light1 = memnew(DirectionalLight3D); diff --git a/editor/plugins/material_editor_plugin.h b/editor/plugins/material_editor_plugin.h index 06ae43e6d7..828dd9f972 100644 --- a/editor/plugins/material_editor_plugin.h +++ b/editor/plugins/material_editor_plugin.h @@ -55,6 +55,7 @@ class MaterialEditor : public Control { DirectionalLight3D *light1 = nullptr; DirectionalLight3D *light2 = nullptr; Camera3D *camera = nullptr; + Ref<CameraAttributesPractical> camera_attributes; Ref<SphereMesh> sphere_mesh; Ref<BoxMesh> box_mesh; diff --git a/editor/plugins/mesh_editor_plugin.cpp b/editor/plugins/mesh_editor_plugin.cpp index 980d2974a0..d8977ea6fc 100644 --- a/editor/plugins/mesh_editor_plugin.cpp +++ b/editor/plugins/mesh_editor_plugin.cpp @@ -30,6 +30,7 @@ #include "mesh_editor_plugin.h" +#include "core/config/project_settings.h" #include "editor/editor_scale.h" void MeshEditor::gui_input(const Ref<InputEvent> &p_event) { @@ -112,13 +113,18 @@ MeshEditor::MeshEditor() { viewport->set_world_3d(world_3d); //use own world add_child(viewport); viewport->set_disable_input(true); - viewport->set_msaa(Viewport::MSAA_4X); + viewport->set_msaa_3d(Viewport::MSAA_4X); set_stretch(true); camera = memnew(Camera3D); camera->set_transform(Transform3D(Basis(), Vector3(0, 0, 1.1))); camera->set_perspective(45, 0.1, 10); viewport->add_child(camera); + if (GLOBAL_GET("rendering/lights_and_shadows/use_physical_light_units")) { + camera_attributes.instantiate(); + camera->set_attributes(camera_attributes); + } + light1 = memnew(DirectionalLight3D); light1->set_transform(Transform3D().looking_at(Vector3(-1, -1, -1), Vector3(0, 1, 0))); viewport->add_child(light1); diff --git a/editor/plugins/mesh_editor_plugin.h b/editor/plugins/mesh_editor_plugin.h index fb61f03485..ab7b5db7c4 100644 --- a/editor/plugins/mesh_editor_plugin.h +++ b/editor/plugins/mesh_editor_plugin.h @@ -36,6 +36,7 @@ #include "scene/3d/light_3d.h" #include "scene/3d/mesh_instance_3d.h" #include "scene/gui/subviewport_container.h" +#include "scene/resources/camera_attributes.h" #include "scene/resources/material.h" class MeshEditor : public SubViewportContainer { @@ -50,6 +51,7 @@ class MeshEditor : public SubViewportContainer { DirectionalLight3D *light1 = nullptr; DirectionalLight3D *light2 = nullptr; Camera3D *camera = nullptr; + Ref<CameraAttributesPractical> camera_attributes; Ref<Mesh> mesh; diff --git a/editor/plugins/node_3d_editor_gizmos.cpp b/editor/plugins/node_3d_editor_gizmos.cpp index 878f8c9a95..0c27ed46c5 100644 --- a/editor/plugins/node_3d_editor_gizmos.cpp +++ b/editor/plugins/node_3d_editor_gizmos.cpp @@ -1365,7 +1365,8 @@ void Light3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_i void Light3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { Light3D *light = Object::cast_to<Light3D>(p_gizmo->get_spatial_node()); - Color color = light->get_color(); + Color color = light->get_color().srgb_to_linear() * light->get_correlated_color().srgb_to_linear(); + color = color.linear_to_srgb(); // Make the gizmo color as bright as possible for better visibility color.set_hsv(color.get_h(), color.get_s(), 1); diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp index f165b83999..1a704a5777 100644 --- a/editor/plugins/node_3d_editor_plugin.cpp +++ b/editor/plugins/node_3d_editor_plugin.cpp @@ -99,7 +99,7 @@ void ViewportRotationControl::_notification(int p_what) { axis_colors.push_back(get_theme_color(SNAME("axis_x_color"), SNAME("Editor"))); axis_colors.push_back(get_theme_color(SNAME("axis_y_color"), SNAME("Editor"))); axis_colors.push_back(get_theme_color(SNAME("axis_z_color"), SNAME("Editor"))); - update(); + queue_redraw(); if (!is_connected("mouse_exited", callable_mp(this, &ViewportRotationControl::_on_mouse_exited))) { connect("mouse_exited", callable_mp(this, &ViewportRotationControl::_on_mouse_exited)); @@ -247,13 +247,13 @@ void ViewportRotationControl::_update_focus() { } if (focused_axis != original_focus) { - update(); + queue_redraw(); } } void ViewportRotationControl::_on_mouse_exited() { focused_axis = -2; - update(); + queue_redraw(); } void ViewportRotationControl::set_viewport(Node3DEditorViewport *p_viewport) { @@ -350,7 +350,7 @@ void Node3DEditorViewport::_update_camera(real_t p_interp_delta) { } update_transform_gizmo_view(); - rotation_control->update(); + rotation_control->queue_redraw(); spatial_editor->update_grid(); } } @@ -1614,7 +1614,7 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) { } } - surface->update(); + surface->queue_redraw(); } else { if (_edit.gizmo.is_valid()) { _edit.gizmo->commit_handle(_edit.gizmo_handle, _edit.gizmo_handle_secondary, _edit.gizmo_initial_value, false); @@ -1632,7 +1632,7 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) { if (cursor.region_select) { _select_region(); cursor.region_select = false; - surface->update(); + surface->queue_redraw(); } } @@ -1657,7 +1657,7 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) { _edit.mode = TRANSFORM_NONE; set_message(""); } - surface->update(); + surface->queue_redraw(); } } break; @@ -1741,7 +1741,7 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) { if (cursor.region_select) { cursor.region_end = m->get_position(); - surface->update(); + surface->queue_redraw(); return; } @@ -2244,12 +2244,12 @@ void Node3DEditorViewport::set_freelook_active(bool active_now) { void Node3DEditorViewport::scale_fov(real_t p_fov_offset) { cursor.fov_scale = CLAMP(cursor.fov_scale + p_fov_offset, 0.1, 2.5); - surface->update(); + surface->queue_redraw(); } void Node3DEditorViewport::reset_fov() { cursor.fov_scale = 1.0; - surface->update(); + surface->queue_redraw(); } void Node3DEditorViewport::scale_cursor_distance(real_t scale) { @@ -2268,7 +2268,7 @@ void Node3DEditorViewport::scale_cursor_distance(real_t scale) { } zoom_indicator_delay = ZOOM_FREELOOK_INDICATOR_DELAY_S; - surface->update(); + surface->queue_redraw(); } void Node3DEditorViewport::scale_freelook_speed(real_t scale) { @@ -2281,7 +2281,7 @@ void Node3DEditorViewport::scale_freelook_speed(real_t scale) { } zoom_indicator_delay = ZOOM_FREELOOK_INDICATOR_DELAY_S; - surface->update(); + surface->queue_redraw(); } Point2i Node3DEditorViewport::_get_warped_mouse_motion(const Ref<InputEventMouseMotion> &p_ev_mouse_motion) const { @@ -2375,12 +2375,12 @@ void Node3DEditorPlugin::edited_scene_changed() { void Node3DEditorViewport::_project_settings_changed() { //update shadow atlas if changed - int shadowmap_size = ProjectSettings::get_singleton()->get("rendering/shadows/positional_shadow/atlas_size"); - bool shadowmap_16_bits = ProjectSettings::get_singleton()->get("rendering/shadows/positional_shadow/atlas_16_bits"); - int atlas_q0 = ProjectSettings::get_singleton()->get("rendering/shadows/positional_shadow/atlas_quadrant_0_subdiv"); - int atlas_q1 = ProjectSettings::get_singleton()->get("rendering/shadows/positional_shadow/atlas_quadrant_1_subdiv"); - int atlas_q2 = ProjectSettings::get_singleton()->get("rendering/shadows/positional_shadow/atlas_quadrant_2_subdiv"); - int atlas_q3 = ProjectSettings::get_singleton()->get("rendering/shadows/positional_shadow/atlas_quadrant_3_subdiv"); + int shadowmap_size = ProjectSettings::get_singleton()->get("rendering/lights_and_shadows/positional_shadow/atlas_size"); + bool shadowmap_16_bits = ProjectSettings::get_singleton()->get("rendering/lights_and_shadows/positional_shadow/atlas_16_bits"); + int atlas_q0 = ProjectSettings::get_singleton()->get("rendering/lights_and_shadows/positional_shadow/atlas_quadrant_0_subdiv"); + int atlas_q1 = ProjectSettings::get_singleton()->get("rendering/lights_and_shadows/positional_shadow/atlas_quadrant_1_subdiv"); + int atlas_q2 = ProjectSettings::get_singleton()->get("rendering/lights_and_shadows/positional_shadow/atlas_quadrant_2_subdiv"); + int atlas_q3 = ProjectSettings::get_singleton()->get("rendering/lights_and_shadows/positional_shadow/atlas_quadrant_3_subdiv"); viewport->set_positional_shadow_atlas_size(shadowmap_size); viewport->set_positional_shadow_atlas_16_bits(shadowmap_16_bits); @@ -2393,8 +2393,8 @@ void Node3DEditorViewport::_project_settings_changed() { // Update MSAA, screen-space AA and debanding if changed - const int msaa_mode = ProjectSettings::get_singleton()->get("rendering/anti_aliasing/quality/msaa"); - viewport->set_msaa(Viewport::MSAA(msaa_mode)); + const int msaa_mode = ProjectSettings::get_singleton()->get("rendering/anti_aliasing/quality/msaa_3d"); + viewport->set_msaa_3d(Viewport::MSAA(msaa_mode)); const int ssaa_mode = GLOBAL_GET("rendering/anti_aliasing/quality/screen_space_aa"); viewport->set_screen_space_aa(Viewport::ScreenSpaceAA(ssaa_mode)); const bool use_taa = GLOBAL_GET("rendering/anti_aliasing/quality/use_taa"); @@ -2454,7 +2454,7 @@ void Node3DEditorViewport::_notification(int p_what) { if (zoom_indicator_delay > 0) { zoom_indicator_delay -= delta; if (zoom_indicator_delay <= 0) { - surface->update(); + surface->queue_redraw(); zoom_limit_label->hide(); } } @@ -2472,7 +2472,7 @@ void Node3DEditorViewport::_notification(int p_what) { previewing = cam; previewing->connect("tree_exited", callable_mp(this, &Node3DEditorViewport::_preview_exited_scene)); RS::get_singleton()->viewport_attach_camera(viewport->get_viewport_rid(), cam->get_camera()); - surface->update(); + surface->queue_redraw(); } } @@ -2538,13 +2538,13 @@ void Node3DEditorViewport::_notification(int p_what) { if (message_time > 0) { if (message != last_message) { - surface->update(); + surface->queue_redraw(); last_message = message; } message_time -= get_physics_process_delta_time(); if (message_time < 0) { - surface->update(); + surface->queue_redraw(); } } @@ -3356,13 +3356,13 @@ void Node3DEditorViewport::_toggle_camera_preview(bool p_activate) { if (!preview) { preview_camera->hide(); } - surface->update(); + surface->queue_redraw(); } else { previewing = preview; previewing->connect("tree_exiting", callable_mp(this, &Node3DEditorViewport::_preview_exited_scene)); RS::get_singleton()->viewport_attach_camera(viewport->get_viewport_rid(), preview->get_camera()); //replace - surface->update(); + surface->queue_redraw(); } } @@ -3384,7 +3384,7 @@ void Node3DEditorViewport::_toggle_cinema_preview(bool p_activate) { preview_camera->show(); } view_menu->show(); - surface->update(); + surface->queue_redraw(); } } @@ -3619,7 +3619,7 @@ void Node3DEditorViewport::set_state(const Dictionary &p_state) { previewing = Object::cast_to<Camera3D>(pv); previewing->connect("tree_exiting", callable_mp(this, &Node3DEditorViewport::_preview_exited_scene)); RS::get_singleton()->viewport_attach_camera(viewport->get_viewport_rid(), previewing->get_camera()); //replace - surface->update(); + surface->queue_redraw(); preview_camera->set_pressed(true); preview_camera->show(); } @@ -4392,7 +4392,7 @@ void Node3DEditorViewport::update_transform(Point2 p_mousepos, bool p_shift) { } spatial_editor->update_transform_gizmo(); - surface->update(); + surface->queue_redraw(); } break; @@ -4491,7 +4491,7 @@ void Node3DEditorViewport::update_transform(Point2 p_mousepos, bool p_shift) { } spatial_editor->update_transform_gizmo(); - surface->update(); + surface->queue_redraw(); } break; @@ -4595,7 +4595,7 @@ void Node3DEditorViewport::update_transform(Point2 p_mousepos, bool p_shift) { } spatial_editor->update_transform_gizmo(); - surface->update(); + surface->queue_redraw(); } break; default: { @@ -4608,7 +4608,7 @@ void Node3DEditorViewport::finish_transform() { spatial_editor->update_transform_gizmo(); _edit.mode = TRANSFORM_NONE; _edit.instant = false; - surface->update(); + surface->queue_redraw(); } // Register a shortcut and also add it as an input action with the same events. @@ -5010,7 +5010,7 @@ void Node3DEditorViewportContainer::gui_input(const Ref<InputEvent> &p_event) { hovering_v = mm->get_position().y > (mid_h - v_sep / 2) && mm->get_position().y < (mid_h + v_sep / 2); if (was_hovering_h != hovering_h || was_hovering_v != hovering_v) { - update(); + queue_redraw(); } } @@ -5019,14 +5019,14 @@ void Node3DEditorViewportContainer::gui_input(const Ref<InputEvent> &p_event) { new_ratio = CLAMP(new_ratio, 40 / get_size().width, (get_size().width - 40) / get_size().width); ratio_h = new_ratio; queue_sort(); - update(); + queue_redraw(); } if (dragging_v) { real_t new_ratio = drag_begin_ratio.y + (mm->get_position().y - drag_begin_pos.y) / get_size().height; new_ratio = CLAMP(new_ratio, 40 / get_size().height, (get_size().height - 40) / get_size().height); ratio_v = new_ratio; queue_sort(); - update(); + queue_redraw(); } } } @@ -5036,7 +5036,7 @@ void Node3DEditorViewportContainer::_notification(int p_what) { case NOTIFICATION_MOUSE_ENTER: case NOTIFICATION_MOUSE_EXIT: { mouseover = (p_what == NOTIFICATION_MOUSE_ENTER); - update(); + queue_redraw(); } break; case NOTIFICATION_DRAW: { @@ -7122,6 +7122,9 @@ void Node3DEditor::_add_environment_to_scene(bool p_already_added_sun) { WorldEnvironment *new_env = memnew(WorldEnvironment); new_env->set_environment(preview_environment->get_environment()->duplicate(true)); + if (GLOBAL_GET("rendering/lights_and_shadows/use_physical_light_units")) { + new_env->set_camera_attributes(preview_environment->get_camera_attributes()->duplicate(true)); + } undo_redo->create_action(TTR("Add Preview Environment to Scene")); undo_redo->add_do_method(base, "add_child", new_env, true); @@ -7581,14 +7584,14 @@ void Node3DEditor::_preview_settings_changed() { Transform3D t; t.basis = Basis(Vector3(sun_rotation.x, sun_rotation.y, 0)); preview_sun->set_transform(t); - sun_direction->update(); + sun_direction->queue_redraw(); preview_sun->set_param(Light3D::PARAM_ENERGY, sun_energy->get_value()); preview_sun->set_param(Light3D::PARAM_SHADOW_MAX_DISTANCE, sun_max_distance->get_value()); preview_sun->set_color(sun_color->get_pick_color()); } { //preview env - sky_material->set_sky_energy(environ_energy->get_value()); + sky_material->set_sky_energy_multiplier(environ_energy->get_value()); Color hz_color = environ_sky_color->get_pick_color().lerp(environ_ground_color->get_pick_color(), 0.5).lerp(Color(1, 1, 1), 0.5); sky_material->set_sky_top_color(environ_sky_color->get_pick_color()); sky_material->set_sky_horizon_color(hz_color); @@ -7615,7 +7618,7 @@ void Node3DEditor::_load_default_preview_settings() { sun_angle_altitude->set_value(-Math::rad_to_deg(sun_rotation.x)); sun_angle_azimuth->set_value(180.0 - Math::rad_to_deg(sun_rotation.y)); - sun_direction->update(); + sun_direction->queue_redraw(); environ_sky_color->set_pick_color(Color(0.385, 0.454, 0.55)); environ_ground_color->set_pick_color(Color(0.2, 0.169, 0.133)); environ_energy->set_value(1.0); @@ -8308,6 +8311,10 @@ void fragment() { preview_environment = memnew(WorldEnvironment); environment.instantiate(); preview_environment->set_environment(environment); + if (GLOBAL_GET("rendering/lights_and_shadows/use_physical_light_units")) { + camera_attributes.instantiate(); + preview_environment->set_camera_attributes(camera_attributes); + } Ref<Sky> sky; sky.instantiate(); sky_material.instantiate(); diff --git a/editor/plugins/node_3d_editor_plugin.h b/editor/plugins/node_3d_editor_plugin.h index e0298ebd5f..580cb878ce 100644 --- a/editor/plugins/node_3d_editor_plugin.h +++ b/editor/plugins/node_3d_editor_plugin.h @@ -433,7 +433,7 @@ protected: static void _bind_methods(); public: - void update_surface() { surface->update(); } + void update_surface() { surface->queue_redraw(); } void update_transform_gizmo_view(); void set_can_preview(Camera3D *p_preview); @@ -765,6 +765,7 @@ private: DirectionalLight3D *preview_sun = nullptr; WorldEnvironment *preview_environment = nullptr; Ref<Environment> environment; + Ref<CameraAttributesPhysical> camera_attributes; Ref<ProceduralSkyMaterial> sky_material; bool sun_environ_updating = false; diff --git a/editor/plugins/polygon_2d_editor_plugin.cpp b/editor/plugins/polygon_2d_editor_plugin.cpp index b71cee8882..a652d1d12f 100644 --- a/editor/plugins/polygon_2d_editor_plugin.cpp +++ b/editor/plugins/polygon_2d_editor_plugin.cpp @@ -155,8 +155,8 @@ void Polygon2DEditor::_sync_bones() { undo_redo->add_undo_method(node, "_set_bones", prev_bones); undo_redo->add_do_method(this, "_update_bone_list"); undo_redo->add_undo_method(this, "_update_bone_list"); - undo_redo->add_do_method(uv_edit_draw, "update"); - undo_redo->add_undo_method(uv_edit_draw, "update"); + undo_redo->add_do_method(uv_edit_draw, "queue_redraw"); + undo_redo->add_undo_method(uv_edit_draw, "queue_redraw"); undo_redo->commit_action(); } @@ -195,11 +195,11 @@ void Polygon2DEditor::_update_bone_list() { cb->connect("pressed", callable_mp(this, &Polygon2DEditor::_bone_paint_selected).bind(i)); } - uv_edit_draw->update(); + uv_edit_draw->queue_redraw(); } void Polygon2DEditor::_bone_paint_selected(int p_index) { - uv_edit_draw->update(); + uv_edit_draw->queue_redraw(); } void Polygon2DEditor::_uv_edit_mode_select(int p_mode) { @@ -269,7 +269,7 @@ void Polygon2DEditor::_uv_edit_mode_select(int p_mode) { } uv_edit->set_size(uv_edit->get_size()); // Necessary readjustment of the popup window. - uv_edit_draw->update(); + uv_edit_draw->queue_redraw(); } void Polygon2DEditor::_uv_edit_popup_hide() { @@ -293,8 +293,8 @@ void Polygon2DEditor::_menu_option(int p_option) { undo_redo->create_action(TTR("Create UV Map")); undo_redo->add_do_method(node, "set_uv", points); undo_redo->add_undo_method(node, "set_uv", uvs); - undo_redo->add_do_method(uv_edit_draw, "update"); - undo_redo->add_undo_method(uv_edit_draw, "update"); + undo_redo->add_do_method(uv_edit_draw, "queue_redraw"); + undo_redo->add_undo_method(uv_edit_draw, "queue_redraw"); undo_redo->commit_action(); } @@ -314,8 +314,8 @@ void Polygon2DEditor::_menu_option(int p_option) { undo_redo->create_action(TTR("Create UV Map")); undo_redo->add_do_method(node, "set_uv", points); undo_redo->add_undo_method(node, "set_uv", uvs); - undo_redo->add_do_method(uv_edit_draw, "update"); - undo_redo->add_undo_method(uv_edit_draw, "update"); + undo_redo->add_do_method(uv_edit_draw, "queue_redraw"); + undo_redo->add_undo_method(uv_edit_draw, "queue_redraw"); undo_redo->commit_action(); } break; case UVEDIT_UV_TO_POLYGON: { @@ -328,8 +328,8 @@ void Polygon2DEditor::_menu_option(int p_option) { undo_redo->create_action(TTR("Create Polygon")); undo_redo->add_do_method(node, "set_polygon", uvs); undo_redo->add_undo_method(node, "set_polygon", points); - undo_redo->add_do_method(uv_edit_draw, "update"); - undo_redo->add_undo_method(uv_edit_draw, "update"); + undo_redo->add_do_method(uv_edit_draw, "queue_redraw"); + undo_redo->add_undo_method(uv_edit_draw, "queue_redraw"); undo_redo->commit_action(); } break; case UVEDIT_UV_CLEAR: { @@ -340,8 +340,8 @@ void Polygon2DEditor::_menu_option(int p_option) { undo_redo->create_action(TTR("Create UV Map")); undo_redo->add_do_method(node, "set_uv", Vector<Vector2>()); undo_redo->add_undo_method(node, "set_uv", uvs); - undo_redo->add_do_method(uv_edit_draw, "update"); - undo_redo->add_undo_method(uv_edit_draw, "update"); + undo_redo->add_do_method(uv_edit_draw, "queue_redraw"); + undo_redo->add_undo_method(uv_edit_draw, "queue_redraw"); undo_redo->commit_action(); } break; case UVEDIT_GRID_SETTINGS: { @@ -391,8 +391,8 @@ void Polygon2DEditor::_update_polygon_editing_state() { void Polygon2DEditor::_commit_action() { // Makes that undo/redoing actions made outside of the UV editor still affect its polygon. - undo_redo->add_do_method(uv_edit_draw, "update"); - undo_redo->add_undo_method(uv_edit_draw, "update"); + undo_redo->add_do_method(uv_edit_draw, "queue_redraw"); + undo_redo->add_undo_method(uv_edit_draw, "queue_redraw"); undo_redo->add_do_method(CanvasItemEditor::get_singleton(), "update_viewport"); undo_redo->add_undo_method(CanvasItemEditor::get_singleton(), "update_viewport"); undo_redo->commit_action(); @@ -406,31 +406,31 @@ void Polygon2DEditor::_set_use_snap(bool p_use) { void Polygon2DEditor::_set_show_grid(bool p_show) { snap_show_grid = p_show; EditorSettings::get_singleton()->set_project_metadata("polygon_2d_uv_editor", "show_grid", p_show); - uv_edit_draw->update(); + uv_edit_draw->queue_redraw(); } void Polygon2DEditor::_set_snap_off_x(real_t p_val) { snap_offset.x = p_val; EditorSettings::get_singleton()->set_project_metadata("polygon_2d_uv_editor", "snap_offset", snap_offset); - uv_edit_draw->update(); + uv_edit_draw->queue_redraw(); } void Polygon2DEditor::_set_snap_off_y(real_t p_val) { snap_offset.y = p_val; EditorSettings::get_singleton()->set_project_metadata("polygon_2d_uv_editor", "snap_offset", snap_offset); - uv_edit_draw->update(); + uv_edit_draw->queue_redraw(); } void Polygon2DEditor::_set_snap_step_x(real_t p_val) { snap_step.x = p_val; EditorSettings::get_singleton()->set_project_metadata("polygon_2d_uv_editor", "snap_step", snap_step); - uv_edit_draw->update(); + uv_edit_draw->queue_redraw(); } void Polygon2DEditor::_set_snap_step_y(real_t p_val) { snap_step.y = p_val; EditorSettings::get_singleton()->set_project_metadata("polygon_2d_uv_editor", "snap_step", snap_step); - uv_edit_draw->update(); + uv_edit_draw->queue_redraw(); } void Polygon2DEditor::_uv_mode(int p_mode) { @@ -495,7 +495,7 @@ void Polygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) { node->set_uv(points_prev); node->set_internal_vertex_count(0); - uv_edit_draw->update(); + uv_edit_draw->queue_redraw(); } else { Vector2 tuv = mtx.affine_inverse().xform(snap_point(mb->get_position())); @@ -514,8 +514,8 @@ void Polygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) { undo_redo->add_undo_method(node, "_set_bones", uv_create_bones_prev); undo_redo->add_do_method(this, "_update_polygon_editing_state"); undo_redo->add_undo_method(this, "_update_polygon_editing_state"); - undo_redo->add_do_method(uv_edit_draw, "update"); - undo_redo->add_undo_method(uv_edit_draw, "update"); + undo_redo->add_do_method(uv_edit_draw, "queue_redraw"); + undo_redo->add_undo_method(uv_edit_draw, "queue_redraw"); undo_redo->commit_action(); uv_drag = false; uv_create = false; @@ -566,8 +566,8 @@ void Polygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) { undo_redo->add_undo_method(node, "set_internal_vertex_count", internal_vertices); undo_redo->add_do_method(this, "_update_polygon_editing_state"); undo_redo->add_undo_method(this, "_update_polygon_editing_state"); - undo_redo->add_do_method(uv_edit_draw, "update"); - undo_redo->add_undo_method(uv_edit_draw, "update"); + undo_redo->add_do_method(uv_edit_draw, "queue_redraw"); + undo_redo->add_undo_method(uv_edit_draw, "queue_redraw"); undo_redo->commit_action(); } @@ -621,8 +621,8 @@ void Polygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) { undo_redo->add_undo_method(node, "set_internal_vertex_count", internal_vertices); undo_redo->add_do_method(this, "_update_polygon_editing_state"); undo_redo->add_undo_method(this, "_update_polygon_editing_state"); - undo_redo->add_do_method(uv_edit_draw, "update"); - undo_redo->add_undo_method(uv_edit_draw, "update"); + undo_redo->add_do_method(uv_edit_draw, "queue_redraw"); + undo_redo->add_undo_method(uv_edit_draw, "queue_redraw"); undo_redo->commit_action(); } @@ -679,8 +679,8 @@ void Polygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) { undo_redo->create_action(TTR("Add Custom Polygon")); undo_redo->add_do_method(node, "set_polygons", polygons); undo_redo->add_undo_method(node, "set_polygons", node->get_polygons()); - undo_redo->add_do_method(uv_edit_draw, "update"); - undo_redo->add_undo_method(uv_edit_draw, "update"); + undo_redo->add_do_method(uv_edit_draw, "queue_redraw"); + undo_redo->add_undo_method(uv_edit_draw, "queue_redraw"); undo_redo->commit_action(); } @@ -720,8 +720,8 @@ void Polygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) { undo_redo->create_action(TTR("Remove Custom Polygon")); undo_redo->add_do_method(node, "set_polygons", polygons); undo_redo->add_undo_method(node, "set_polygons", node->get_polygons()); - undo_redo->add_do_method(uv_edit_draw, "update"); - undo_redo->add_undo_method(uv_edit_draw, "update"); + undo_redo->add_do_method(uv_edit_draw, "queue_redraw"); + undo_redo->add_undo_method(uv_edit_draw, "queue_redraw"); undo_redo->commit_action(); } } @@ -748,15 +748,15 @@ void Polygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) { undo_redo->create_action(TTR("Transform UV Map")); undo_redo->add_do_method(node, "set_uv", node->get_uv()); undo_redo->add_undo_method(node, "set_uv", points_prev); - undo_redo->add_do_method(uv_edit_draw, "update"); - undo_redo->add_undo_method(uv_edit_draw, "update"); + undo_redo->add_do_method(uv_edit_draw, "queue_redraw"); + undo_redo->add_undo_method(uv_edit_draw, "queue_redraw"); undo_redo->commit_action(); } else if (uv_edit_mode[1]->is_pressed() && uv_move_current == UV_MODE_EDIT_POINT) { // Edit polygon. undo_redo->create_action(TTR("Transform Polygon")); undo_redo->add_do_method(node, "set_polygon", node->get_polygon()); undo_redo->add_undo_method(node, "set_polygon", points_prev); - undo_redo->add_do_method(uv_edit_draw, "update"); - undo_redo->add_undo_method(uv_edit_draw, "update"); + undo_redo->add_do_method(uv_edit_draw, "queue_redraw"); + undo_redo->add_undo_method(uv_edit_draw, "queue_redraw"); undo_redo->commit_action(); } @@ -767,8 +767,8 @@ void Polygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) { undo_redo->create_action(TTR("Paint Bone Weights")); undo_redo->add_do_method(node, "set_bone_weights", bone_painting_bone, node->get_bone_weights(bone_painting_bone)); undo_redo->add_undo_method(node, "set_bone_weights", bone_painting_bone, prev_weights); - undo_redo->add_do_method(uv_edit_draw, "update"); - undo_redo->add_undo_method(uv_edit_draw, "update"); + undo_redo->add_do_method(uv_edit_draw, "queue_redraw"); + undo_redo->add_undo_method(uv_edit_draw, "queue_redraw"); undo_redo->commit_action(); bone_painting = false; } @@ -780,7 +780,7 @@ void Polygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) { node->set_bone_weights(bone_painting_bone, prev_weights); } - uv_edit_draw->update(); + uv_edit_draw->queue_redraw(); } } @@ -906,14 +906,14 @@ void Polygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) { node->set_bone_weights(bone_painting_bone, painted_weights); } - uv_edit_draw->update(); + uv_edit_draw->queue_redraw(); CanvasItemEditor::get_singleton()->update_viewport(); } else if (polygon_create.size()) { uv_create_to = mtx.affine_inverse().xform(mm->get_position()); - uv_edit_draw->update(); + uv_edit_draw->queue_redraw(); } else if (uv_mode == UV_MODE_PAINT_WEIGHT || uv_mode == UV_MODE_CLEAR_WEIGHT) { bone_paint_pos = mm->get_position(); - uv_edit_draw->update(); + uv_edit_draw->queue_redraw(); } } @@ -954,7 +954,7 @@ void Polygon2DEditor::_uv_scroll_changed(real_t) { uv_draw_ofs.x = uv_hscroll->get_value(); uv_draw_ofs.y = uv_vscroll->get_value(); uv_draw_zoom = uv_zoom->get_value(); - uv_edit_draw->update(); + uv_edit_draw->queue_redraw(); } void Polygon2DEditor::_uv_draw() { diff --git a/editor/plugins/resource_preloader_editor_plugin.cpp b/editor/plugins/resource_preloader_editor_plugin.cpp index 80566419b1..21647d1b69 100644 --- a/editor/plugins/resource_preloader_editor_plugin.cpp +++ b/editor/plugins/resource_preloader_editor_plugin.cpp @@ -196,7 +196,7 @@ void ResourcePreloaderEditor::_update_library() { String type = r->get_class(); ti->set_icon(0, EditorNode::get_singleton()->get_class_icon(type, "Object")); - ti->set_tooltip(0, TTR("Instance:") + " " + r->get_path() + "\n" + TTR("Type:") + " " + type); + ti->set_tooltip_text(0, TTR("Instance:") + " " + r->get_path() + "\n" + TTR("Type:") + " " + type); ti->set_text(1, r->get_path()); ti->set_editable(1, false); diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp index aa1d630372..ad114e022f 100644 --- a/editor/plugins/script_editor_plugin.cpp +++ b/editor/plugins/script_editor_plugin.cpp @@ -940,50 +940,6 @@ void ScriptEditor::_resave_scripts(const String &p_str) { disk_changed->hide(); } -void ScriptEditor::_reload_scripts() { - for (int i = 0; i < tab_container->get_tab_count(); i++) { - ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_tab_control(i)); - if (!se) { - continue; - } - - Ref<Resource> edited_res = se->get_edited_resource(); - - if (edited_res->is_built_in()) { - continue; //internal script, who cares - } - - uint64_t last_date = edited_res->get_last_modified_time(); - uint64_t date = FileAccess::get_modified_time(edited_res->get_path()); - - if (last_date == date) { - continue; - } - - Ref<Script> script = edited_res; - if (script != nullptr) { - Ref<Script> rel_script = ResourceLoader::load(script->get_path(), script->get_class(), ResourceFormatLoader::CACHE_MODE_IGNORE); - ERR_CONTINUE(!rel_script.is_valid()); - script->set_source_code(rel_script->get_source_code()); - script->set_last_modified_time(rel_script->get_last_modified_time()); - script->reload(true); - } - - Ref<TextFile> text_file = edited_res; - if (text_file != nullptr) { - Error err; - Ref<TextFile> rel_text_file = _load_text_file(text_file->get_path(), &err); - ERR_CONTINUE(!rel_text_file.is_valid()); - text_file->set_text(rel_text_file->get_text()); - text_file->set_last_modified_time(rel_text_file->get_last_modified_time()); - } - se->reload_text(); - } - - disk_changed->hide(); - _update_script_names(); -} - void ScriptEditor::_res_saved_callback(const Ref<Resource> &p_res) { for (int i = 0; i < tab_container->get_tab_count(); i++) { ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_tab_control(i)); @@ -1077,7 +1033,7 @@ bool ScriptEditor::_test_script_times_on_disk(Ref<Resource> p_for_script) { if (need_reload) { if (!need_ask) { - script_editor->_reload_scripts(); + script_editor->reload_scripts(); need_reload = false; } else { disk_changed->call_deferred(SNAME("popup_centered_ratio"), 0.5); @@ -2588,6 +2544,50 @@ void ScriptEditor::apply_scripts() const { } } +void ScriptEditor::reload_scripts() { + for (int i = 0; i < tab_container->get_tab_count(); i++) { + ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_tab_control(i)); + if (!se) { + continue; + } + + Ref<Resource> edited_res = se->get_edited_resource(); + + if (edited_res->is_built_in()) { + continue; //internal script, who cares + } + + uint64_t last_date = edited_res->get_last_modified_time(); + uint64_t date = FileAccess::get_modified_time(edited_res->get_path()); + + if (last_date == date) { + continue; + } + + Ref<Script> script = edited_res; + if (script != nullptr) { + Ref<Script> rel_script = ResourceLoader::load(script->get_path(), script->get_class(), ResourceFormatLoader::CACHE_MODE_IGNORE); + ERR_CONTINUE(!rel_script.is_valid()); + script->set_source_code(rel_script->get_source_code()); + script->set_last_modified_time(rel_script->get_last_modified_time()); + script->reload(true); + } + + Ref<TextFile> text_file = edited_res; + if (text_file != nullptr) { + Error err; + Ref<TextFile> rel_text_file = _load_text_file(text_file->get_path(), &err); + ERR_CONTINUE(!rel_text_file.is_valid()); + text_file->set_text(rel_text_file->get_text()); + text_file->set_last_modified_time(rel_text_file->get_last_modified_time()); + } + se->reload_text(); + } + + disk_changed->hide(); + _update_script_names(); +} + void ScriptEditor::open_script_create_dialog(const String &p_base_name, const String &p_base_path) { _menu_option(FILE_NEW); script_create_dialog->config(p_base_name, p_base_path); @@ -3918,7 +3918,7 @@ ScriptEditor::ScriptEditor() { vbc->add_child(disk_changed_list); disk_changed_list->set_v_size_flags(SIZE_EXPAND_FILL); - disk_changed->connect("confirmed", callable_mp(this, &ScriptEditor::_reload_scripts)); + disk_changed->connect("confirmed", callable_mp(this, &ScriptEditor::reload_scripts)); disk_changed->set_ok_button_text(TTR("Reload")); disk_changed->add_button(TTR("Resave"), !DisplayServer::get_singleton()->get_swap_cancel_ok(), "resave"); diff --git a/editor/plugins/script_editor_plugin.h b/editor/plugins/script_editor_plugin.h index d1898efb69..a8e6cc6868 100644 --- a/editor/plugins/script_editor_plugin.h +++ b/editor/plugins/script_editor_plugin.h @@ -327,7 +327,6 @@ class ScriptEditor : public PanelContainer { String _get_debug_tooltip(const String &p_text, Node *_se); void _resave_scripts(const String &p_str); - void _reload_scripts(); bool _test_script_times_on_disk(Ref<Resource> p_for_script = Ref<Resource>()); @@ -478,6 +477,7 @@ public: bool toggle_scripts_panel(); bool is_scripts_panel_toggled(); void apply_scripts() const; + void reload_scripts(); void open_script_create_dialog(const String &p_base_name, const String &p_base_path); void open_text_file_create_dialog(const String &p_base_path, const String &p_base_name = ""); Ref<Resource> open_file(const String &p_file); diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp index 85e53011d6..fff956a05e 100644 --- a/editor/plugins/script_text_editor.cpp +++ b/editor/plugins/script_text_editor.cpp @@ -1124,15 +1124,15 @@ void ScriptTextEditor::_edit_option(int p_op) { } break; case EDIT_TOGGLE_FOLD_LINE: { tx->toggle_foldable_line(tx->get_caret_line()); - tx->update(); + tx->queue_redraw(); } break; case EDIT_FOLD_ALL_LINES: { tx->fold_all_lines(); - tx->update(); + tx->queue_redraw(); } break; case EDIT_UNFOLD_ALL_LINES: { tx->unfold_all_lines(); - tx->update(); + tx->queue_redraw(); } break; case EDIT_TOGGLE_COMMENT: { _edit_option_toggle_inline_comment(); @@ -1590,7 +1590,7 @@ void ScriptTextEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data } } - String variable_name = String(node->get_name()).camelcase_to_underscore(true).validate_identifier(); + String variable_name = String(node->get_name()).to_snake_case().validate_identifier(); if (use_type) { text_to_drop += vformat("@onready var %s: %s = %s%s\n", variable_name, node->get_class_name(), is_unique ? "%" : "$", path); } else { @@ -1760,7 +1760,7 @@ void ScriptTextEditor::_color_changed(const Color &p_color) { code_editor->get_text_editor()->begin_complex_operation(); code_editor->get_text_editor()->set_line(color_position.x, line_with_replaced_args); code_editor->get_text_editor()->end_complex_operation(); - code_editor->get_text_editor()->update(); + code_editor->get_text_editor()->queue_redraw(); } void ScriptTextEditor::_prepare_edit_menu() { diff --git a/editor/plugins/skeleton_3d_editor_plugin.cpp b/editor/plugins/skeleton_3d_editor_plugin.cpp index eac075c139..b85e44e106 100644 --- a/editor/plugins/skeleton_3d_editor_plugin.cpp +++ b/editor/plugins/skeleton_3d_editor_plugin.cpp @@ -182,27 +182,27 @@ void BoneTransformEditor::_update_properties() { if (split[2] == "enabled") { enabled_checkbox->set_read_only(E.usage & PROPERTY_USAGE_READ_ONLY); enabled_checkbox->update_property(); - enabled_checkbox->update(); + enabled_checkbox->queue_redraw(); } if (split[2] == "position") { position_property->set_read_only(E.usage & PROPERTY_USAGE_READ_ONLY); position_property->update_property(); - position_property->update(); + position_property->queue_redraw(); } if (split[2] == "rotation") { rotation_property->set_read_only(E.usage & PROPERTY_USAGE_READ_ONLY); rotation_property->update_property(); - rotation_property->update(); + rotation_property->queue_redraw(); } if (split[2] == "scale") { scale_property->set_read_only(E.usage & PROPERTY_USAGE_READ_ONLY); scale_property->update_property(); - scale_property->update(); + scale_property->queue_redraw(); } if (split[2] == "rest") { rest_matrix->set_read_only(E.usage & PROPERTY_USAGE_READ_ONLY); rest_matrix->update_property(); - rest_matrix->update(); + rest_matrix->queue_redraw(); } } } @@ -426,7 +426,9 @@ PhysicalBone3D *Skeleton3DEditor::create_physical_bone(int bone_id, int bone_chi bone_shape->set_name("CollisionShape3D"); Transform3D capsule_transform; - capsule_transform.basis = Basis(Vector3(1, 0, 0), Vector3(0, 0, 1), Vector3(0, -1, 0)); + capsule_transform.basis.rows[0] = Vector3(1, 0, 0); + capsule_transform.basis.rows[1] = Vector3(0, 0, 1); + capsule_transform.basis.rows[2] = Vector3(0, -1, 0); bone_shape->set_transform(capsule_transform); /// Get an up vector not collinear with child rest origin diff --git a/editor/plugins/sprite_2d_editor_plugin.cpp b/editor/plugins/sprite_2d_editor_plugin.cpp index e45c907e86..615fd5dba9 100644 --- a/editor/plugins/sprite_2d_editor_plugin.cpp +++ b/editor/plugins/sprite_2d_editor_plugin.cpp @@ -128,7 +128,7 @@ void Sprite2DEditor::_menu_option(int p_option) { _update_mesh_data(); debug_uv_dialog->popup_centered(); - debug_uv->update(); + debug_uv->queue_redraw(); } break; case MENU_OPTION_CONVERT_TO_POLYGON_2D: { @@ -137,7 +137,7 @@ void Sprite2DEditor::_menu_option(int p_option) { _update_mesh_data(); debug_uv_dialog->popup_centered(); - debug_uv->update(); + debug_uv->queue_redraw(); } break; case MENU_OPTION_CREATE_COLLISION_POLY_2D: { debug_uv_dialog->set_ok_button_text(TTR("Create CollisionPolygon2D")); @@ -145,7 +145,7 @@ void Sprite2DEditor::_menu_option(int p_option) { _update_mesh_data(); debug_uv_dialog->popup_centered(); - debug_uv->update(); + debug_uv->queue_redraw(); } break; case MENU_OPTION_CREATE_LIGHT_OCCLUDER_2D: { @@ -154,7 +154,7 @@ void Sprite2DEditor::_menu_option(int p_option) { _update_mesh_data(); debug_uv_dialog->popup_centered(); - debug_uv->update(); + debug_uv->queue_redraw(); } break; } @@ -302,7 +302,7 @@ void Sprite2DEditor::_update_mesh_data() { } } - debug_uv->update(); + debug_uv->queue_redraw(); } void Sprite2DEditor::_create_node() { diff --git a/editor/plugins/sprite_frames_editor_plugin.cpp b/editor/plugins/sprite_frames_editor_plugin.cpp index 87f0fc4ad0..9508835442 100644 --- a/editor/plugins/sprite_frames_editor_plugin.cpp +++ b/editor/plugins/sprite_frames_editor_plugin.cpp @@ -182,7 +182,7 @@ void SpriteFramesEditor::_sheet_preview_input(const Ref<InputEvent> &p_event) { if (last_frame_selected != idx || idx != -1) { last_frame_selected = idx; - split_sheet_preview->update(); + split_sheet_preview->queue_redraw(); } } @@ -208,7 +208,7 @@ void SpriteFramesEditor::_sheet_preview_input(const Ref<InputEvent> &p_event) { } last_frame_selected = idx; - split_sheet_preview->update(); + split_sheet_preview->queue_redraw(); } } } @@ -307,7 +307,7 @@ void SpriteFramesEditor::_sheet_select_clear_all_frames() { frames_selected.clear(); } - split_sheet_preview->update(); + split_sheet_preview->queue_redraw(); } void SpriteFramesEditor::_sheet_spin_changed(double p_value, int p_dominant_param) { @@ -363,7 +363,7 @@ void SpriteFramesEditor::_sheet_spin_changed(double p_value, int p_dominant_para frames_selected.clear(); last_frame_selected = -1; - split_sheet_preview->update(); + split_sheet_preview->queue_redraw(); } void SpriteFramesEditor::_prepare_sprite_sheet(const String &p_file) { diff --git a/editor/plugins/style_box_editor_plugin.cpp b/editor/plugins/style_box_editor_plugin.cpp index d4baff34e2..fffcce6d9a 100644 --- a/editor/plugins/style_box_editor_plugin.cpp +++ b/editor/plugins/style_box_editor_plugin.cpp @@ -36,7 +36,7 @@ bool StyleBoxPreview::grid_preview_enabled = true; void StyleBoxPreview::_grid_preview_toggled(bool p_active) { grid_preview_enabled = p_active; - preview->update(); + preview->queue_redraw(); } bool EditorInspectorPluginStyleBox::can_handle(Object *p_object) { @@ -66,7 +66,7 @@ void StyleBoxPreview::edit(const Ref<StyleBox> &p_stylebox) { } void StyleBoxPreview::_sb_changed() { - preview->update(); + preview->queue_redraw(); } void StyleBoxPreview::_notification(int p_what) { diff --git a/editor/plugins/sub_viewport_preview_editor_plugin.cpp b/editor/plugins/sub_viewport_preview_editor_plugin.cpp index c8bb0cd56f..074a9708b7 100644 --- a/editor/plugins/sub_viewport_preview_editor_plugin.cpp +++ b/editor/plugins/sub_viewport_preview_editor_plugin.cpp @@ -39,7 +39,7 @@ void EditorInspectorPluginSubViewportPreview::parse_begin(Object *p_object) { TexturePreview *sub_viewport_preview = memnew(TexturePreview(sub_viewport->get_texture(), false)); // Otherwise `sub_viewport_preview`'s `texture_display` doesn't update properly when `sub_viewport`'s size changes. - sub_viewport->connect("size_changed", callable_mp((CanvasItem *)sub_viewport_preview->get_texture_display(), &CanvasItem::update)); + sub_viewport->connect("size_changed", callable_mp((CanvasItem *)sub_viewport_preview->get_texture_display(), &CanvasItem::queue_redraw)); add_custom_control(sub_viewport_preview); } diff --git a/editor/plugins/text_editor.cpp b/editor/plugins/text_editor.cpp index 0900415b04..76332b2d10 100644 --- a/editor/plugins/text_editor.cpp +++ b/editor/plugins/text_editor.cpp @@ -339,15 +339,15 @@ void TextEditor::_edit_option(int p_op) { } break; case EDIT_TOGGLE_FOLD_LINE: { tx->toggle_foldable_line(tx->get_caret_line()); - tx->update(); + tx->queue_redraw(); } break; case EDIT_FOLD_ALL_LINES: { tx->fold_all_lines(); - tx->update(); + tx->queue_redraw(); } break; case EDIT_UNFOLD_ALL_LINES: { tx->unfold_all_lines(); - tx->update(); + tx->queue_redraw(); } break; case EDIT_TRIM_TRAILING_WHITESAPCE: { trim_trailing_whitespace(); diff --git a/editor/plugins/texture_3d_editor_plugin.cpp b/editor/plugins/texture_3d_editor_plugin.cpp index 64cafa17f3..c2517b4b79 100644 --- a/editor/plugins/texture_3d_editor_plugin.cpp +++ b/editor/plugins/texture_3d_editor_plugin.cpp @@ -53,7 +53,7 @@ void Texture3DEditor::_texture_changed() { if (!is_visible()) { return; } - update(); + queue_redraw(); } void Texture3DEditor::_update_material() { @@ -124,7 +124,7 @@ void Texture3DEditor::edit(Ref<Texture3D> p_texture) { } texture->connect("changed", callable_mp(this, &Texture3DEditor::_texture_changed)); - update(); + queue_redraw(); texture_rect->set_material(material); setting = true; layer->set_max(texture->get_depth() - 1); diff --git a/editor/plugins/texture_layered_editor_plugin.cpp b/editor/plugins/texture_layered_editor_plugin.cpp index 2c6f70463d..1118f18605 100644 --- a/editor/plugins/texture_layered_editor_plugin.cpp +++ b/editor/plugins/texture_layered_editor_plugin.cpp @@ -64,7 +64,7 @@ void TextureLayeredEditor::_texture_changed() { if (!is_visible()) { return; } - update(); + queue_redraw(); } void TextureLayeredEditor::_update_material() { @@ -190,7 +190,7 @@ void TextureLayeredEditor::edit(Ref<TextureLayered> p_texture) { } texture->connect("changed", callable_mp(this, &TextureLayeredEditor::_texture_changed)); - update(); + queue_redraw(); texture_rect->set_material(materials[texture->get_layered_type()]); setting = true; if (texture->get_layered_type() == TextureLayered::LAYERED_TYPE_2D_ARRAY) { diff --git a/editor/plugins/texture_region_editor_plugin.cpp b/editor/plugins/texture_region_editor_plugin.cpp index 50a7dc7f96..f0e3619060 100644 --- a/editor/plugins/texture_region_editor_plugin.cpp +++ b/editor/plugins/texture_region_editor_plugin.cpp @@ -381,8 +381,8 @@ void TextureRegionEditor::_region_input(const Ref<InputEvent> &p_input) { } undo_redo->add_do_method(this, "_update_rect"); undo_redo->add_undo_method(this, "_update_rect"); - undo_redo->add_do_method(edit_draw, "update"); - undo_redo->add_undo_method(edit_draw, "update"); + undo_redo->add_do_method(edit_draw, "queue_redraw"); + undo_redo->add_undo_method(edit_draw, "queue_redraw"); undo_redo->commit_action(); break; } @@ -455,8 +455,8 @@ void TextureRegionEditor::_region_input(const Ref<InputEvent> &p_input) { } undo_redo->add_do_method(this, "_update_rect"); undo_redo->add_undo_method(this, "_update_rect"); - undo_redo->add_do_method(edit_draw, "update"); - undo_redo->add_undo_method(edit_draw, "update"); + undo_redo->add_do_method(edit_draw, "queue_redraw"); + undo_redo->add_undo_method(edit_draw, "queue_redraw"); undo_redo->commit_action(); drag = false; creating = false; @@ -477,7 +477,7 @@ void TextureRegionEditor::_region_input(const Ref<InputEvent> &p_input) { } else { apply_rect(rect_prev); rect = rect_prev; - edit_draw->update(); + edit_draw->queue_redraw(); drag_index = -1; } } @@ -546,7 +546,7 @@ void TextureRegionEditor::_region_input(const Ref<InputEvent> &p_input) { rect = Rect2(drag_from, Size2()); rect.expand_to(new_pos); apply_rect(rect); - edit_draw->update(); + edit_draw->queue_redraw(); return; } @@ -601,7 +601,7 @@ void TextureRegionEditor::_region_input(const Ref<InputEvent> &p_input) { } break; } } - edit_draw->update(); + edit_draw->queue_redraw(); } } @@ -642,7 +642,7 @@ void TextureRegionEditor::_scroll_changed(float) { draw_ofs.x = hscroll->get_value(); draw_ofs.y = vscroll->get_value(); - edit_draw->update(); + edit_draw->queue_redraw(); } void TextureRegionEditor::_set_snap_mode(int p_mode) { @@ -658,37 +658,37 @@ void TextureRegionEditor::_set_snap_mode(int p_mode) { _update_autoslice(); } - edit_draw->update(); + edit_draw->queue_redraw(); } void TextureRegionEditor::_set_snap_off_x(float p_val) { snap_offset.x = p_val; - edit_draw->update(); + edit_draw->queue_redraw(); } void TextureRegionEditor::_set_snap_off_y(float p_val) { snap_offset.y = p_val; - edit_draw->update(); + edit_draw->queue_redraw(); } void TextureRegionEditor::_set_snap_step_x(float p_val) { snap_step.x = p_val; - edit_draw->update(); + edit_draw->queue_redraw(); } void TextureRegionEditor::_set_snap_step_y(float p_val) { snap_step.y = p_val; - edit_draw->update(); + edit_draw->queue_redraw(); } void TextureRegionEditor::_set_snap_sep_x(float p_val) { snap_separation.x = p_val; - edit_draw->update(); + edit_draw->queue_redraw(); } void TextureRegionEditor::_set_snap_sep_y(float p_val) { snap_separation.y = p_val; - edit_draw->update(); + edit_draw->queue_redraw(); } void TextureRegionEditor::_zoom_on_position(float p_zoom, Point2 p_position) { @@ -702,7 +702,7 @@ void TextureRegionEditor::_zoom_on_position(float p_zoom, Point2 p_position) { ofs = ofs / prev_zoom - ofs / draw_zoom; draw_ofs = (draw_ofs + ofs).round(); - edit_draw->update(); + edit_draw->queue_redraw(); } void TextureRegionEditor::_zoom_in() { @@ -933,7 +933,7 @@ void TextureRegionEditor::edit(Object *p_obj) { obj_styleBox = Ref<StyleBoxTexture>(nullptr); atlas_tex = Ref<AtlasTexture>(nullptr); } - edit_draw->update(); + edit_draw->queue_redraw(); popup_centered_ratio(0.5); request_center = true; } @@ -963,7 +963,7 @@ void TextureRegionEditor::_edit_region() { _zoom_reset(); hscroll->hide(); vscroll->hide(); - edit_draw->update(); + edit_draw->queue_redraw(); return; } @@ -979,7 +979,7 @@ void TextureRegionEditor::_edit_region() { } _update_rect(); - edit_draw->update(); + edit_draw->queue_redraw(); } Vector2 TextureRegionEditor::snap_point(Vector2 p_target) const { diff --git a/editor/plugins/theme_editor_preview.cpp b/editor/plugins/theme_editor_preview.cpp index ea8da1e86d..8cc96201e7 100644 --- a/editor/plugins/theme_editor_preview.cpp +++ b/editor/plugins/theme_editor_preview.cpp @@ -56,7 +56,7 @@ void ThemeEditorPreview::add_preview_overlay(Control *p_overlay) { void ThemeEditorPreview::_propagate_redraw(Control *p_at) { p_at->notification(NOTIFICATION_THEME_CHANGED); p_at->update_minimum_size(); - p_at->update(); + p_at->queue_redraw(); for (int i = 0; i < p_at->get_child_count(); i++) { Control *a = Object::cast_to<Control>(p_at->get_child(i)); if (a) { @@ -174,7 +174,7 @@ void ThemeEditorPreview::_gui_input_picker_overlay(const Ref<InputEvent> &p_even if (mm.is_valid()) { Vector2 mp = preview_content->get_local_mouse_position(); hovered_control = _find_hovered_control(preview_content, mp); - picker_overlay->update(); + picker_overlay->queue_redraw(); } // Forward input to the scroll container underneath to allow scrolling. @@ -183,7 +183,7 @@ void ThemeEditorPreview::_gui_input_picker_overlay(const Ref<InputEvent> &p_even void ThemeEditorPreview::_reset_picker_overlay() { hovered_control = nullptr; - picker_overlay->update(); + picker_overlay->queue_redraw(); } void ThemeEditorPreview::_notification(int p_what) { diff --git a/editor/plugins/tiles/tile_atlas_view.cpp b/editor/plugins/tiles/tile_atlas_view.cpp index 8d2b150d6d..5f0576a675 100644 --- a/editor/plugins/tiles/tile_atlas_view.cpp +++ b/editor/plugins/tiles/tile_atlas_view.cpp @@ -404,12 +404,12 @@ void TileAtlasView::set_atlas_source(TileSet *p_tile_set, TileSetAtlasSource *p_ _update_zoom_and_panning(); // Update. - base_tiles_draw->update(); - base_tiles_texture_grid->update(); - base_tiles_shape_grid->update(); - alternatives_draw->update(); - background_left->update(); - background_right->update(); + base_tiles_draw->queue_redraw(); + base_tiles_texture_grid->queue_redraw(); + base_tiles_shape_grid->queue_redraw(); + alternatives_draw->queue_redraw(); + background_left->queue_redraw(); + background_right->queue_redraw(); } float TileAtlasView::get_zoom() const { @@ -493,13 +493,13 @@ Rect2i TileAtlasView::get_alternative_tile_rect(const Vector2i p_coords, int p_a return alternative_tiles_rect_cache[p_coords][p_alternative_tile]; } -void TileAtlasView::update() { - base_tiles_draw->update(); - base_tiles_texture_grid->update(); - base_tiles_shape_grid->update(); - alternatives_draw->update(); - background_left->update(); - background_right->update(); +void TileAtlasView::queue_redraw() { + base_tiles_draw->queue_redraw(); + base_tiles_texture_grid->queue_redraw(); + base_tiles_shape_grid->queue_redraw(); + alternatives_draw->queue_redraw(); + background_left->queue_redraw(); + background_right->queue_redraw(); } void TileAtlasView::_notification(int p_what) { diff --git a/editor/plugins/tiles/tile_atlas_view.h b/editor/plugins/tiles/tile_atlas_view.h index 1c0b622bb1..c710eac107 100644 --- a/editor/plugins/tiles/tile_atlas_view.h +++ b/editor/plugins/tiles/tile_atlas_view.h @@ -154,8 +154,8 @@ public: p_control->set_mouse_filter(Control::MOUSE_FILTER_PASS); }; - // Update everything. - void update(); + // Redraw everything. + void queue_redraw(); TileAtlasView(); }; diff --git a/editor/plugins/tiles/tile_data_editors.cpp b/editor/plugins/tiles/tile_data_editors.cpp index 73e07e6647..1bfbd342c2 100644 --- a/editor/plugins/tiles/tile_data_editors.cpp +++ b/editor/plugins/tiles/tile_data_editors.cpp @@ -240,12 +240,12 @@ void GenericTilePolygonEditor::_base_control_draw() { void GenericTilePolygonEditor::_center_view() { panning = Vector2(); - base_control->update(); + base_control->queue_redraw(); button_center_view->set_disabled(true); } void GenericTilePolygonEditor::_zoom_changed() { - base_control->update(); + base_control->queue_redraw(); } void GenericTilePolygonEditor::_advanced_menu_item_pressed(int p_item_pressed) { @@ -266,26 +266,26 @@ void GenericTilePolygonEditor::_advanced_menu_item_pressed(int p_item_pressed) { polygon.write[i] = polygon[i] * tile_set->get_tile_size(); } undo_redo->add_do_method(this, "add_polygon", polygon); - undo_redo->add_do_method(base_control, "update"); + undo_redo->add_do_method(base_control, "queue_redraw"); undo_redo->add_do_method(this, "emit_signal", "polygons_changed"); undo_redo->add_undo_method(this, "clear_polygons"); for (unsigned int i = 0; i < polygons.size(); i++) { undo_redo->add_undo_method(this, "add_polygon", polygons[i]); } - undo_redo->add_undo_method(base_control, "update"); + undo_redo->add_undo_method(base_control, "queue_redraw"); undo_redo->add_undo_method(this, "emit_signal", "polygons_changed"); undo_redo->commit_action(true); } break; case CLEAR_TILE: { undo_redo->create_action(TTR("Clear Polygons")); undo_redo->add_do_method(this, "clear_polygons"); - undo_redo->add_do_method(base_control, "update"); + undo_redo->add_do_method(base_control, "queue_redraw"); undo_redo->add_do_method(this, "emit_signal", "polygons_changed"); undo_redo->add_undo_method(this, "clear_polygons"); for (unsigned int i = 0; i < polygons.size(); i++) { undo_redo->add_undo_method(this, "add_polygon", polygons[i]); } - undo_redo->add_undo_method(base_control, "update"); + undo_redo->add_undo_method(base_control, "queue_redraw"); undo_redo->add_undo_method(this, "emit_signal", "polygons_changed"); undo_redo->commit_action(true); } break; @@ -318,12 +318,12 @@ void GenericTilePolygonEditor::_advanced_menu_item_pressed(int p_item_pressed) { } undo_redo->add_do_method(this, "set_polygon", i, new_polygon); } - undo_redo->add_do_method(base_control, "update"); + undo_redo->add_do_method(base_control, "queue_redraw"); undo_redo->add_do_method(this, "emit_signal", "polygons_changed"); for (unsigned int i = 0; i < polygons.size(); i++) { undo_redo->add_undo_method(this, "set_polygon", polygons[i]); } - undo_redo->add_undo_method(base_control, "update"); + undo_redo->add_undo_method(base_control, "queue_redraw"); undo_redo->add_undo_method(this, "emit_signal", "polygons_changed"); undo_redo->commit_action(true); } break; @@ -491,9 +491,9 @@ void GenericTilePolygonEditor::_base_control_gui_input(Ref<InputEvent> p_event) undo_redo->add_do_method(this, "clear_polygons"); } undo_redo->add_do_method(this, "add_polygon", in_creation_polygon); - undo_redo->add_do_method(base_control, "update"); + undo_redo->add_do_method(base_control, "queue_redraw"); undo_redo->add_undo_method(this, "remove_polygon", added); - undo_redo->add_undo_method(base_control, "update"); + undo_redo->add_undo_method(base_control, "queue_redraw"); undo_redo->commit_action(false); emit_signal(SNAME("polygons_changed")); } else { @@ -539,8 +539,8 @@ void GenericTilePolygonEditor::_base_control_gui_input(Ref<InputEvent> p_event) undo_redo->add_do_method(this, "set_polygon", closest_polygon, polygons[closest_polygon]); undo_redo->add_undo_method(this, "set_polygon", closest_polygon, old_polygon); } - undo_redo->add_do_method(base_control, "update"); - undo_redo->add_undo_method(base_control, "update"); + undo_redo->add_do_method(base_control, "queue_redraw"); + undo_redo->add_undo_method(base_control, "queue_redraw"); undo_redo->commit_action(false); emit_signal(SNAME("polygons_changed")); } @@ -549,9 +549,9 @@ void GenericTilePolygonEditor::_base_control_gui_input(Ref<InputEvent> p_event) if (drag_type == DRAG_TYPE_DRAG_POINT) { undo_redo->create_action(TTR("Edit Polygons")); undo_redo->add_do_method(this, "set_polygon", drag_polygon_index, polygons[drag_polygon_index]); - undo_redo->add_do_method(base_control, "update"); + undo_redo->add_do_method(base_control, "queue_redraw"); undo_redo->add_undo_method(this, "set_polygon", drag_polygon_index, drag_old_polygon); - undo_redo->add_undo_method(base_control, "update"); + undo_redo->add_undo_method(base_control, "queue_redraw"); undo_redo->commit_action(false); emit_signal(SNAME("polygons_changed")); } else if (drag_type == DRAG_TYPE_CREATE_POINT) { @@ -586,8 +586,8 @@ void GenericTilePolygonEditor::_base_control_gui_input(Ref<InputEvent> p_event) undo_redo->add_do_method(this, "set_polygon", closest_polygon, polygons[closest_polygon]); undo_redo->add_undo_method(this, "set_polygon", closest_polygon, old_polygon); } - undo_redo->add_do_method(base_control, "update"); - undo_redo->add_undo_method(base_control, "update"); + undo_redo->add_do_method(base_control, "queue_redraw"); + undo_redo->add_undo_method(base_control, "queue_redraw"); undo_redo->commit_action(false); emit_signal(SNAME("polygons_changed")); } else { @@ -611,7 +611,7 @@ void GenericTilePolygonEditor::_base_control_gui_input(Ref<InputEvent> p_event) } } - base_control->update(); + base_control->queue_redraw(); } void GenericTilePolygonEditor::set_use_undo_redo(bool p_use_undo_redo) { @@ -659,7 +659,7 @@ void GenericTilePolygonEditor::set_background(Ref<Texture2D> p_texture, Rect2 p_ background_v_flip = p_flip_v; background_transpose = p_transpose; background_modulate = p_modulate; - base_control->update(); + base_control->queue_redraw(); } int GenericTilePolygonEditor::get_polygon_count() { @@ -672,13 +672,13 @@ int GenericTilePolygonEditor::add_polygon(Vector<Point2> p_polygon, int p_index) if (p_index < 0) { polygons.push_back(p_polygon); - base_control->update(); + base_control->queue_redraw(); button_edit->set_pressed(true); return polygons.size() - 1; } else { polygons.insert(p_index, p_polygon); button_edit->set_pressed(true); - base_control->update(); + base_control->queue_redraw(); return p_index; } } @@ -690,12 +690,12 @@ void GenericTilePolygonEditor::remove_polygon(int p_index) { if (polygons.size() == 0) { button_create->set_pressed(true); } - base_control->update(); + base_control->queue_redraw(); } void GenericTilePolygonEditor::clear_polygons() { polygons.clear(); - base_control->update(); + base_control->queue_redraw(); } void GenericTilePolygonEditor::set_polygon(int p_polygon_index, Vector<Point2> p_polygon) { @@ -703,7 +703,7 @@ void GenericTilePolygonEditor::set_polygon(int p_polygon_index, Vector<Point2> p ERR_FAIL_COND(p_polygon.size() < 3); polygons[p_polygon_index] = p_polygon; button_edit->set_pressed(true); - base_control->update(); + base_control->queue_redraw(); } Vector<Point2> GenericTilePolygonEditor::get_polygon(int p_polygon_index) { @@ -713,7 +713,7 @@ Vector<Point2> GenericTilePolygonEditor::get_polygon(int p_polygon_index) { void GenericTilePolygonEditor::set_polygons_color(Color p_color) { polygon_color = p_color; - base_control->update(); + base_control->queue_redraw(); } void GenericTilePolygonEditor::set_multiple_polygon_mode(bool p_multiple_polygon_mode) { diff --git a/editor/plugins/tiles/tile_map_editor.cpp b/editor/plugins/tiles/tile_map_editor.cpp index 556788f50c..ec406ef9ba 100644 --- a/editor/plugins/tiles/tile_map_editor.cpp +++ b/editor/plugins/tiles/tile_map_editor.cpp @@ -351,7 +351,7 @@ void TileMapEditorTilesPlugin::_update_atlas_view() { tile_atlas_view->set_atlas_source(*tile_map->get_tileset(), atlas_source, source_id); TilesEditorPlugin::get_singleton()->synchronize_atlas_view(tile_atlas_view); - tile_atlas_control->update(); + tile_atlas_control->queue_redraw(); } void TileMapEditorTilesPlugin::_update_scenes_collection_view() { @@ -1651,8 +1651,8 @@ void TileMapEditorTilesPlugin::_update_tileset_selection_from_selection_pattern( } } _update_source_display(); - tile_atlas_control->update(); - alternative_tiles_control->update(); + tile_atlas_control->queue_redraw(); + alternative_tiles_control->queue_redraw(); } void TileMapEditorTilesPlugin::_tile_atlas_control_draw() { @@ -1736,7 +1736,7 @@ void TileMapEditorTilesPlugin::_tile_atlas_control_mouse_exited() { hovered_tile.set_atlas_coords(TileSetSource::INVALID_ATLAS_COORDS); hovered_tile.alternative_tile = TileSetSource::INVALID_TILE_ALTERNATIVE; tile_set_dragging_selection = false; - tile_atlas_control->update(); + tile_atlas_control->queue_redraw(); } void TileMapEditorTilesPlugin::_tile_atlas_control_gui_input(const Ref<InputEvent> &p_event) { @@ -1780,8 +1780,8 @@ void TileMapEditorTilesPlugin::_tile_atlas_control_gui_input(const Ref<InputEven Ref<InputEventMouseMotion> mm = p_event; if (mm.is_valid()) { - tile_atlas_control->update(); - alternative_tiles_control->update(); + tile_atlas_control->queue_redraw(); + alternative_tiles_control->queue_redraw(); } Ref<InputEventMouseButton> mb = p_event; @@ -1841,7 +1841,7 @@ void TileMapEditorTilesPlugin::_tile_atlas_control_gui_input(const Ref<InputEven } tile_set_dragging_selection = false; } - tile_atlas_control->update(); + tile_atlas_control->queue_redraw(); } } @@ -1895,7 +1895,7 @@ void TileMapEditorTilesPlugin::_tile_alternatives_control_mouse_exited() { hovered_tile.set_atlas_coords(TileSetSource::INVALID_ATLAS_COORDS); hovered_tile.alternative_tile = TileSetSource::INVALID_TILE_ALTERNATIVE; tile_set_dragging_selection = false; - alternative_tiles_control->update(); + alternative_tiles_control->queue_redraw(); } void TileMapEditorTilesPlugin::_tile_alternatives_control_gui_input(const Ref<InputEvent> &p_event) { @@ -1938,8 +1938,8 @@ void TileMapEditorTilesPlugin::_tile_alternatives_control_gui_input(const Ref<In Ref<InputEventMouseMotion> mm = p_event; if (mm.is_valid()) { - tile_atlas_control->update(); - alternative_tiles_control->update(); + tile_atlas_control->queue_redraw(); + alternative_tiles_control->queue_redraw(); } Ref<InputEventMouseButton> mb = p_event; @@ -1959,8 +1959,8 @@ void TileMapEditorTilesPlugin::_tile_alternatives_control_gui_input(const Ref<In } _update_selection_pattern_from_tileset_tiles_selection(); } - tile_atlas_control->update(); - alternative_tiles_control->update(); + tile_atlas_control->queue_redraw(); + alternative_tiles_control->queue_redraw(); } } @@ -3618,7 +3618,7 @@ void TileMapEditor::_tab_changed(int p_tab_id) { } // Graphical update. - tabs_data[tabs_bar->get_current_tab()].panel->update(); + tabs_data[tabs_bar->get_current_tab()].panel->queue_redraw(); CanvasItemEditor::get_singleton()->update_viewport(); } diff --git a/editor/plugins/tiles/tile_set_atlas_source_editor.cpp b/editor/plugins/tiles/tile_set_atlas_source_editor.cpp index 46093469e3..2aea020902 100644 --- a/editor/plugins/tiles/tile_set_atlas_source_editor.cpp +++ b/editor/plugins/tiles/tile_set_atlas_source_editor.cpp @@ -624,8 +624,8 @@ void TileSetAtlasSourceEditor::_update_tile_data_editors() { TileDataTextureOffsetEditor *tile_data_texture_offset_editor = memnew(TileDataTextureOffsetEditor); tile_data_texture_offset_editor->hide(); tile_data_texture_offset_editor->setup_property_editor(Variant::VECTOR2, "texture_offset"); - tile_data_texture_offset_editor->connect("needs_redraw", callable_mp((CanvasItem *)tile_atlas_control_unscaled, &Control::update)); - tile_data_texture_offset_editor->connect("needs_redraw", callable_mp((CanvasItem *)alternative_tiles_control_unscaled, &Control::update)); + tile_data_texture_offset_editor->connect("needs_redraw", callable_mp((CanvasItem *)tile_atlas_control_unscaled, &Control::queue_redraw)); + tile_data_texture_offset_editor->connect("needs_redraw", callable_mp((CanvasItem *)alternative_tiles_control_unscaled, &Control::queue_redraw)); tile_data_editors["texture_offset"] = tile_data_texture_offset_editor; } @@ -634,8 +634,8 @@ void TileSetAtlasSourceEditor::_update_tile_data_editors() { TileDataDefaultEditor *tile_data_modulate_editor = memnew(TileDataDefaultEditor()); tile_data_modulate_editor->hide(); tile_data_modulate_editor->setup_property_editor(Variant::COLOR, "modulate", "", Color(1.0, 1.0, 1.0, 1.0)); - tile_data_modulate_editor->connect("needs_redraw", callable_mp((CanvasItem *)tile_atlas_control_unscaled, &Control::update)); - tile_data_modulate_editor->connect("needs_redraw", callable_mp((CanvasItem *)alternative_tiles_control_unscaled, &Control::update)); + tile_data_modulate_editor->connect("needs_redraw", callable_mp((CanvasItem *)tile_atlas_control_unscaled, &Control::queue_redraw)); + tile_data_modulate_editor->connect("needs_redraw", callable_mp((CanvasItem *)alternative_tiles_control_unscaled, &Control::queue_redraw)); tile_data_editors["modulate"] = tile_data_modulate_editor; } @@ -644,8 +644,8 @@ void TileSetAtlasSourceEditor::_update_tile_data_editors() { TileDataDefaultEditor *tile_data_z_index_editor = memnew(TileDataDefaultEditor()); tile_data_z_index_editor->hide(); tile_data_z_index_editor->setup_property_editor(Variant::INT, "z_index"); - tile_data_z_index_editor->connect("needs_redraw", callable_mp((CanvasItem *)tile_atlas_control_unscaled, &Control::update)); - tile_data_z_index_editor->connect("needs_redraw", callable_mp((CanvasItem *)alternative_tiles_control_unscaled, &Control::update)); + tile_data_z_index_editor->connect("needs_redraw", callable_mp((CanvasItem *)tile_atlas_control_unscaled, &Control::queue_redraw)); + tile_data_z_index_editor->connect("needs_redraw", callable_mp((CanvasItem *)alternative_tiles_control_unscaled, &Control::queue_redraw)); tile_data_editors["z_index"] = tile_data_z_index_editor; } @@ -654,8 +654,8 @@ void TileSetAtlasSourceEditor::_update_tile_data_editors() { TileDataYSortEditor *tile_data_y_sort_editor = memnew(TileDataYSortEditor); tile_data_y_sort_editor->hide(); tile_data_y_sort_editor->setup_property_editor(Variant::INT, "y_sort_origin"); - tile_data_y_sort_editor->connect("needs_redraw", callable_mp((CanvasItem *)tile_atlas_control_unscaled, &Control::update)); - tile_data_y_sort_editor->connect("needs_redraw", callable_mp((CanvasItem *)alternative_tiles_control_unscaled, &Control::update)); + tile_data_y_sort_editor->connect("needs_redraw", callable_mp((CanvasItem *)tile_atlas_control_unscaled, &Control::queue_redraw)); + tile_data_y_sort_editor->connect("needs_redraw", callable_mp((CanvasItem *)alternative_tiles_control_unscaled, &Control::queue_redraw)); tile_data_editors["y_sort_origin"] = tile_data_y_sort_editor; } @@ -665,8 +665,8 @@ void TileSetAtlasSourceEditor::_update_tile_data_editors() { TileDataOcclusionShapeEditor *tile_data_occlusion_shape_editor = memnew(TileDataOcclusionShapeEditor()); tile_data_occlusion_shape_editor->hide(); tile_data_occlusion_shape_editor->set_occlusion_layer(i); - tile_data_occlusion_shape_editor->connect("needs_redraw", callable_mp((CanvasItem *)tile_atlas_control_unscaled, &Control::update)); - tile_data_occlusion_shape_editor->connect("needs_redraw", callable_mp((CanvasItem *)alternative_tiles_control_unscaled, &Control::update)); + tile_data_occlusion_shape_editor->connect("needs_redraw", callable_mp((CanvasItem *)tile_atlas_control_unscaled, &Control::queue_redraw)); + tile_data_occlusion_shape_editor->connect("needs_redraw", callable_mp((CanvasItem *)alternative_tiles_control_unscaled, &Control::queue_redraw)); tile_data_editors[vformat("occlusion_layer_%d", i)] = tile_data_occlusion_shape_editor; } } @@ -680,8 +680,8 @@ void TileSetAtlasSourceEditor::_update_tile_data_editors() { if (!tile_data_editors.has("terrain_set")) { TileDataTerrainsEditor *tile_data_terrains_editor = memnew(TileDataTerrainsEditor); tile_data_terrains_editor->hide(); - tile_data_terrains_editor->connect("needs_redraw", callable_mp((CanvasItem *)tile_atlas_control_unscaled, &Control::update)); - tile_data_terrains_editor->connect("needs_redraw", callable_mp((CanvasItem *)alternative_tiles_control_unscaled, &Control::update)); + tile_data_terrains_editor->connect("needs_redraw", callable_mp((CanvasItem *)tile_atlas_control_unscaled, &Control::queue_redraw)); + tile_data_terrains_editor->connect("needs_redraw", callable_mp((CanvasItem *)alternative_tiles_control_unscaled, &Control::queue_redraw)); tile_data_editors["terrain_set"] = tile_data_terrains_editor; } @@ -691,8 +691,8 @@ void TileSetAtlasSourceEditor::_update_tile_data_editors() { TileDataDefaultEditor *tile_data_probability_editor = memnew(TileDataDefaultEditor()); tile_data_probability_editor->hide(); tile_data_probability_editor->setup_property_editor(Variant::FLOAT, "probability", "", 1.0); - tile_data_probability_editor->connect("needs_redraw", callable_mp((CanvasItem *)tile_atlas_control_unscaled, &Control::update)); - tile_data_probability_editor->connect("needs_redraw", callable_mp((CanvasItem *)alternative_tiles_control_unscaled, &Control::update)); + tile_data_probability_editor->connect("needs_redraw", callable_mp((CanvasItem *)tile_atlas_control_unscaled, &Control::queue_redraw)); + tile_data_probability_editor->connect("needs_redraw", callable_mp((CanvasItem *)alternative_tiles_control_unscaled, &Control::queue_redraw)); tile_data_editors["probability"] = tile_data_probability_editor; } @@ -704,8 +704,8 @@ void TileSetAtlasSourceEditor::_update_tile_data_editors() { TileDataCollisionEditor *tile_data_collision_editor = memnew(TileDataCollisionEditor()); tile_data_collision_editor->hide(); tile_data_collision_editor->set_physics_layer(i); - tile_data_collision_editor->connect("needs_redraw", callable_mp((CanvasItem *)tile_atlas_control_unscaled, &Control::update)); - tile_data_collision_editor->connect("needs_redraw", callable_mp((CanvasItem *)alternative_tiles_control_unscaled, &Control::update)); + tile_data_collision_editor->connect("needs_redraw", callable_mp((CanvasItem *)tile_atlas_control_unscaled, &Control::queue_redraw)); + tile_data_collision_editor->connect("needs_redraw", callable_mp((CanvasItem *)alternative_tiles_control_unscaled, &Control::queue_redraw)); tile_data_editors[vformat("physics_layer_%d", i)] = tile_data_collision_editor; } } @@ -722,8 +722,8 @@ void TileSetAtlasSourceEditor::_update_tile_data_editors() { TileDataNavigationEditor *tile_data_navigation_editor = memnew(TileDataNavigationEditor()); tile_data_navigation_editor->hide(); tile_data_navigation_editor->set_navigation_layer(i); - tile_data_navigation_editor->connect("needs_redraw", callable_mp((CanvasItem *)tile_atlas_control_unscaled, &Control::update)); - tile_data_navigation_editor->connect("needs_redraw", callable_mp((CanvasItem *)alternative_tiles_control_unscaled, &Control::update)); + tile_data_navigation_editor->connect("needs_redraw", callable_mp((CanvasItem *)tile_atlas_control_unscaled, &Control::queue_redraw)); + tile_data_navigation_editor->connect("needs_redraw", callable_mp((CanvasItem *)alternative_tiles_control_unscaled, &Control::queue_redraw)); tile_data_editors[vformat("navigation_layer_%d", i)] = tile_data_navigation_editor; } } @@ -744,8 +744,8 @@ void TileSetAtlasSourceEditor::_update_tile_data_editors() { TileDataDefaultEditor *tile_data_custom_data_editor = memnew(TileDataDefaultEditor()); tile_data_custom_data_editor->hide(); tile_data_custom_data_editor->setup_property_editor(tile_set->get_custom_data_layer_type(i), vformat("custom_data_%d", i), tile_set->get_custom_data_layer_name(i)); - tile_data_custom_data_editor->connect("needs_redraw", callable_mp((CanvasItem *)tile_atlas_control_unscaled, &Control::update)); - tile_data_custom_data_editor->connect("needs_redraw", callable_mp((CanvasItem *)alternative_tiles_control_unscaled, &Control::update)); + tile_data_custom_data_editor->connect("needs_redraw", callable_mp((CanvasItem *)tile_atlas_control_unscaled, &Control::queue_redraw)); + tile_data_custom_data_editor->connect("needs_redraw", callable_mp((CanvasItem *)alternative_tiles_control_unscaled, &Control::queue_redraw)); tile_data_editors[vformat("custom_data_%d", i)] = tile_data_custom_data_editor; } } @@ -872,10 +872,10 @@ void TileSetAtlasSourceEditor::_tile_data_editor_dropdown_button_pressed() { void TileSetAtlasSourceEditor::_tile_data_editors_tree_selected() { tile_data_editors_popup->call_deferred(SNAME("hide")); _update_current_tile_data_editor(); - tile_atlas_control->update(); - tile_atlas_control_unscaled->update(); - alternative_tiles_control->update(); - alternative_tiles_control_unscaled->update(); + tile_atlas_control->queue_redraw(); + tile_atlas_control_unscaled->queue_redraw(); + alternative_tiles_control->queue_redraw(); + alternative_tiles_control_unscaled->queue_redraw(); } void TileSetAtlasSourceEditor::_update_atlas_view() { @@ -923,11 +923,11 @@ void TileSetAtlasSourceEditor::_update_atlas_view() { tile_atlas_view->set_padding(Side::SIDE_RIGHT, texture_region_base_size_min); // Redraw everything. - tile_atlas_control->update(); - tile_atlas_control_unscaled->update(); - alternative_tiles_control->update(); - alternative_tiles_control_unscaled->update(); - tile_atlas_view->update(); + tile_atlas_control->queue_redraw(); + tile_atlas_control_unscaled->queue_redraw(); + alternative_tiles_control->queue_redraw(); + alternative_tiles_control_unscaled->queue_redraw(); + tile_atlas_view->queue_redraw(); // Synchronize atlas view. TilesEditorPlugin::get_singleton()->synchronize_atlas_view(tile_atlas_view); @@ -961,14 +961,14 @@ void TileSetAtlasSourceEditor::_update_toolbar() { void TileSetAtlasSourceEditor::_tile_atlas_control_mouse_exited() { hovered_base_tile_coords = TileSetSource::INVALID_ATLAS_COORDS; - tile_atlas_control->update(); - tile_atlas_control_unscaled->update(); - tile_atlas_view->update(); + tile_atlas_control->queue_redraw(); + tile_atlas_control_unscaled->queue_redraw(); + tile_atlas_view->queue_redraw(); } void TileSetAtlasSourceEditor::_tile_atlas_view_transform_changed() { - tile_atlas_control->update(); - tile_atlas_control_unscaled->update(); + tile_atlas_control->queue_redraw(); + tile_atlas_control_unscaled->queue_redraw(); } void TileSetAtlasSourceEditor::_tile_atlas_control_gui_input(const Ref<InputEvent> &p_event) { @@ -983,11 +983,11 @@ void TileSetAtlasSourceEditor::_tile_atlas_control_gui_input(const Ref<InputEven // Update only what's needed. tile_set_changed_needs_update = false; - tile_atlas_control->update(); - tile_atlas_control_unscaled->update(); - alternative_tiles_control->update(); - alternative_tiles_control_unscaled->update(); - tile_atlas_view->update(); + tile_atlas_control->queue_redraw(); + tile_atlas_control_unscaled->queue_redraw(); + alternative_tiles_control->queue_redraw(); + alternative_tiles_control_unscaled->queue_redraw(); + tile_atlas_view->queue_redraw(); return; } else { // Handle the event. @@ -1132,11 +1132,11 @@ void TileSetAtlasSourceEditor::_tile_atlas_control_gui_input(const Ref<InputEven } // Redraw for the hovered tile. - tile_atlas_control->update(); - tile_atlas_control_unscaled->update(); - alternative_tiles_control->update(); - alternative_tiles_control_unscaled->update(); - tile_atlas_view->update(); + tile_atlas_control->queue_redraw(); + tile_atlas_control_unscaled->queue_redraw(); + alternative_tiles_control->queue_redraw(); + alternative_tiles_control_unscaled->queue_redraw(); + tile_atlas_view->queue_redraw(); return; } @@ -1283,11 +1283,11 @@ void TileSetAtlasSourceEditor::_tile_atlas_control_gui_input(const Ref<InputEven // Left click released. _end_dragging(); } - tile_atlas_control->update(); - tile_atlas_control_unscaled->update(); - alternative_tiles_control->update(); - alternative_tiles_control_unscaled->update(); - tile_atlas_view->update(); + tile_atlas_control->queue_redraw(); + tile_atlas_control_unscaled->queue_redraw(); + alternative_tiles_control->queue_redraw(); + alternative_tiles_control_unscaled->queue_redraw(); + tile_atlas_view->queue_redraw(); return; } else if (mb->get_button_index() == MouseButton::RIGHT) { // Right click pressed. @@ -1298,11 +1298,11 @@ void TileSetAtlasSourceEditor::_tile_atlas_control_gui_input(const Ref<InputEven // Right click released. _end_dragging(); } - tile_atlas_control->update(); - tile_atlas_control_unscaled->update(); - alternative_tiles_control->update(); - alternative_tiles_control_unscaled->update(); - tile_atlas_view->update(); + tile_atlas_control->queue_redraw(); + tile_atlas_control_unscaled->queue_redraw(); + alternative_tiles_control->queue_redraw(); + alternative_tiles_control_unscaled->queue_redraw(); + tile_atlas_view->queue_redraw(); return; } } @@ -1872,20 +1872,20 @@ void TileSetAtlasSourceEditor::_tile_alternatives_control_gui_input(const Ref<In if (current_tile_data_editor) { current_tile_data_editor->forward_painting_alternatives_gui_input(tile_atlas_view, tile_set_atlas_source, p_event); } - tile_atlas_control->update(); - tile_atlas_control_unscaled->update(); - alternative_tiles_control->update(); - alternative_tiles_control_unscaled->update(); - tile_atlas_view->update(); + tile_atlas_control->queue_redraw(); + tile_atlas_control_unscaled->queue_redraw(); + alternative_tiles_control->queue_redraw(); + alternative_tiles_control_unscaled->queue_redraw(); + tile_atlas_view->queue_redraw(); return; } Ref<InputEventMouseMotion> mm = p_event; if (mm.is_valid()) { - tile_atlas_control->update(); - tile_atlas_control_unscaled->update(); - alternative_tiles_control->update(); - alternative_tiles_control_unscaled->update(); + tile_atlas_control->queue_redraw(); + tile_atlas_control_unscaled->queue_redraw(); + alternative_tiles_control->queue_redraw(); + alternative_tiles_control_unscaled->queue_redraw(); if (drag_type == DRAG_TYPE_MAY_POPUP_MENU) { if (Vector2(drag_start_mouse_pos).distance_to(alternative_tiles_control->get_local_mouse_position()) > 5.0 * EDSCALE) { @@ -1942,19 +1942,19 @@ void TileSetAtlasSourceEditor::_tile_alternatives_control_gui_input(const Ref<In drag_type = DRAG_TYPE_NONE; } } - tile_atlas_control->update(); - tile_atlas_control_unscaled->update(); - alternative_tiles_control->update(); - alternative_tiles_control_unscaled->update(); + tile_atlas_control->queue_redraw(); + tile_atlas_control_unscaled->queue_redraw(); + alternative_tiles_control->queue_redraw(); + alternative_tiles_control_unscaled->queue_redraw(); } } void TileSetAtlasSourceEditor::_tile_alternatives_control_mouse_exited() { hovered_alternative_tile_coords = Vector3i(TileSetSource::INVALID_ATLAS_COORDS.x, TileSetSource::INVALID_ATLAS_COORDS.y, TileSetSource::INVALID_TILE_ALTERNATIVE); - tile_atlas_control->update(); - tile_atlas_control_unscaled->update(); - alternative_tiles_control->update(); - alternative_tiles_control_unscaled->update(); + tile_atlas_control->queue_redraw(); + tile_atlas_control_unscaled->queue_redraw(); + alternative_tiles_control->queue_redraw(); + alternative_tiles_control_unscaled->queue_redraw(); } void TileSetAtlasSourceEditor::_tile_alternatives_control_draw() { diff --git a/editor/plugins/version_control_editor_plugin.cpp b/editor/plugins/version_control_editor_plugin.cpp index 2b55ba64c3..fba760d57f 100644 --- a/editor/plugins/version_control_editor_plugin.cpp +++ b/editor/plugins/version_control_editor_plugin.cpp @@ -30,25 +30,59 @@ #include "version_control_editor_plugin.h" -#include "core/object/script_language.h" +#include "core/config/project_settings.h" #include "core/os/keyboard.h" +#include "core/os/time.h" #include "editor/editor_file_system.h" #include "editor/editor_node.h" #include "editor/editor_scale.h" #include "editor/editor_settings.h" +#include "editor/filesystem_dock.h" #include "scene/gui/separator.h" +#define CHECK_PLUGIN_INITIALIZED() \ + ERR_FAIL_COND_MSG(!EditorVCSInterface::get_singleton(), "No VCS plugin is initialized. Select a Version Control Plugin from Project menu."); + VersionControlEditorPlugin *VersionControlEditorPlugin::singleton = nullptr; void VersionControlEditorPlugin::_bind_methods() { - ClassDB::bind_method(D_METHOD("popup_vcs_set_up_dialog"), &VersionControlEditorPlugin::popup_vcs_set_up_dialog); + ClassDB::bind_method(D_METHOD("_initialize_vcs"), &VersionControlEditorPlugin::_initialize_vcs); + ClassDB::bind_method(D_METHOD("_set_credentials"), &VersionControlEditorPlugin::_set_credentials); + ClassDB::bind_method(D_METHOD("_update_set_up_warning"), &VersionControlEditorPlugin::_update_set_up_warning); + ClassDB::bind_method(D_METHOD("_commit"), &VersionControlEditorPlugin::_commit); + ClassDB::bind_method(D_METHOD("_refresh_stage_area"), &VersionControlEditorPlugin::_refresh_stage_area); + ClassDB::bind_method(D_METHOD("_move_all"), &VersionControlEditorPlugin::_move_all); + ClassDB::bind_method(D_METHOD("_load_diff"), &VersionControlEditorPlugin::_load_diff); + ClassDB::bind_method(D_METHOD("_display_diff"), &VersionControlEditorPlugin::_display_diff); + ClassDB::bind_method(D_METHOD("_item_activated"), &VersionControlEditorPlugin::_item_activated); + ClassDB::bind_method(D_METHOD("_update_branch_create_button"), &VersionControlEditorPlugin::_update_branch_create_button); + ClassDB::bind_method(D_METHOD("_update_remote_create_button"), &VersionControlEditorPlugin::_update_remote_create_button); + ClassDB::bind_method(D_METHOD("_update_commit_button"), &VersionControlEditorPlugin::_update_commit_button); + ClassDB::bind_method(D_METHOD("_refresh_branch_list"), &VersionControlEditorPlugin::_refresh_branch_list); + ClassDB::bind_method(D_METHOD("_set_commit_list_size"), &VersionControlEditorPlugin::_set_commit_list_size); + ClassDB::bind_method(D_METHOD("_refresh_commit_list"), &VersionControlEditorPlugin::_refresh_commit_list); + ClassDB::bind_method(D_METHOD("_refresh_remote_list"), &VersionControlEditorPlugin::_refresh_remote_list); + ClassDB::bind_method(D_METHOD("_ssh_public_key_selected"), &VersionControlEditorPlugin::_ssh_public_key_selected); + ClassDB::bind_method(D_METHOD("_ssh_private_key_selected"), &VersionControlEditorPlugin::_ssh_private_key_selected); + ClassDB::bind_method(D_METHOD("_commit_message_gui_input"), &VersionControlEditorPlugin::_commit_message_gui_input); + ClassDB::bind_method(D_METHOD("_cell_button_pressed"), &VersionControlEditorPlugin::_cell_button_pressed); + ClassDB::bind_method(D_METHOD("_discard_all"), &VersionControlEditorPlugin::_discard_all); + ClassDB::bind_method(D_METHOD("_create_branch"), &VersionControlEditorPlugin::_create_branch); + ClassDB::bind_method(D_METHOD("_create_remote"), &VersionControlEditorPlugin::_create_remote); + ClassDB::bind_method(D_METHOD("_remove_branch"), &VersionControlEditorPlugin::_remove_branch); + ClassDB::bind_method(D_METHOD("_remove_remote"), &VersionControlEditorPlugin::_remove_remote); + ClassDB::bind_method(D_METHOD("_branch_item_selected"), &VersionControlEditorPlugin::_branch_item_selected); + ClassDB::bind_method(D_METHOD("_remote_selected"), &VersionControlEditorPlugin::_remote_selected); + ClassDB::bind_method(D_METHOD("_fetch"), &VersionControlEditorPlugin::_fetch); + ClassDB::bind_method(D_METHOD("_pull"), &VersionControlEditorPlugin::_pull); + ClassDB::bind_method(D_METHOD("_push"), &VersionControlEditorPlugin::_push); + ClassDB::bind_method(D_METHOD("_extra_option_selected"), &VersionControlEditorPlugin::_extra_option_selected); + ClassDB::bind_method(D_METHOD("_update_extra_options"), &VersionControlEditorPlugin::_update_extra_options); + ClassDB::bind_method(D_METHOD("_popup_branch_remove_confirm"), &VersionControlEditorPlugin::_popup_branch_remove_confirm); + ClassDB::bind_method(D_METHOD("_popup_remote_remove_confirm"), &VersionControlEditorPlugin::_popup_remote_remove_confirm); + ClassDB::bind_method(D_METHOD("_popup_file_dialog"), &VersionControlEditorPlugin::_popup_file_dialog); - // Used to track the status of files in the staging area - BIND_ENUM_CONSTANT(CHANGE_TYPE_NEW); - BIND_ENUM_CONSTANT(CHANGE_TYPE_MODIFIED); - BIND_ENUM_CONSTANT(CHANGE_TYPE_RENAMED); - BIND_ENUM_CONSTANT(CHANGE_TYPE_DELETED); - BIND_ENUM_CONSTANT(CHANGE_TYPE_TYPECHANGE); + ClassDB::bind_method(D_METHOD("popup_vcs_set_up_dialog"), &VersionControlEditorPlugin::popup_vcs_set_up_dialog); } void VersionControlEditorPlugin::_create_vcs_metadata_files() { @@ -56,21 +90,25 @@ void VersionControlEditorPlugin::_create_vcs_metadata_files() { EditorVCSInterface::create_vcs_metadata_files(EditorVCSInterface::VCSMetadata(metadata_selection->get_selected()), dir); } -void VersionControlEditorPlugin::_selected_a_vcs(int p_id) { - List<StringName> available_addons = get_available_vcs_names(); - const StringName selected_vcs = set_up_choice->get_item_text(p_id); -} +void VersionControlEditorPlugin::_notification(int p_what) { + if (p_what == NOTIFICATION_READY) { + String installed_plugin = GLOBAL_DEF("editor/version_control/plugin_name", ""); + String project_path = GLOBAL_DEF("editor/version_control/project_path", OS::get_singleton()->get_resource_dir()); + project_path_input->set_text(project_path); + bool has_autoload_enable = GLOBAL_DEF("editor/version_control/autoload_on_startup", false); -void VersionControlEditorPlugin::_populate_available_vcs_names() { - static bool called = false; - - if (!called) { - List<StringName> available_addons = get_available_vcs_names(); - for (int i = 0; i < available_addons.size(); i++) { - set_up_choice->add_item(available_addons[i]); + if (installed_plugin != "" && has_autoload_enable) { + if (_load_plugin(installed_plugin, project_path)) { + _set_credentials(); + } } + } +} - called = true; +void VersionControlEditorPlugin::_populate_available_vcs_names() { + set_up_choice->clear(); + for (int i = 0; i < available_plugins.size(); i++) { + set_up_choice->add_item(available_plugins[i]); } } @@ -83,9 +121,8 @@ void VersionControlEditorPlugin::popup_vcs_metadata_dialog() { } void VersionControlEditorPlugin::popup_vcs_set_up_dialog(const Control *p_gui_base) { - fetch_available_vcs_addon_names(); - List<StringName> available_addons = get_available_vcs_names(); - if (available_addons.size() >= 1) { + fetch_available_vcs_plugin_names(); + if (!available_plugins.is_empty()) { Size2 popup_size = Size2(400, 100); Size2 window_size = p_gui_base->get_viewport_rect().size; popup_size.x = MIN(window_size.x * 0.5, popup_size.x); @@ -95,213 +132,782 @@ void VersionControlEditorPlugin::popup_vcs_set_up_dialog(const Control *p_gui_ba set_up_dialog->popup_centered_clamped(popup_size * EDSCALE); } else { - EditorNode::get_singleton()->show_warning(TTR("No VCS addons are available."), TTR("Error")); + // TODO: Give info to user on how to fix this error. + EditorNode::get_singleton()->show_warning(TTR("No VCS plugins are available in the project. Install a VCS plugin to use VCS integration features."), TTR("Error")); } } void VersionControlEditorPlugin::_initialize_vcs() { - register_editor(); - - ERR_FAIL_COND_MSG(EditorVCSInterface::get_singleton(), EditorVCSInterface::get_singleton()->get_vcs_name() + " is already active"); + ERR_FAIL_COND_MSG(EditorVCSInterface::get_singleton(), EditorVCSInterface::get_singleton()->get_vcs_name() + " is already active."); const int id = set_up_choice->get_selected_id(); - String selected_addon = set_up_choice->get_item_text(id); + String selected_plugin = set_up_choice->get_item_text(id); - String path = ScriptServer::get_global_class_path(selected_addon); - Ref<Script> script = ResourceLoader::load(path); + if (_load_plugin(selected_plugin, project_path_input->get_text())) { + ProjectSettings::get_singleton()->set("editor/version_control/autoload_on_startup", true); + ProjectSettings::get_singleton()->set("editor/version_control/plugin_name", selected_plugin); + ProjectSettings::get_singleton()->set("editor/version_control/project_path", project_path_input->get_text()); + ProjectSettings::get_singleton()->save(); + } +} - ERR_FAIL_COND_MSG(!script.is_valid(), "VCS Addon path is invalid"); +void VersionControlEditorPlugin::_set_vcs_ui_state(bool p_enabled) { + select_project_path_button->set_disabled(p_enabled); + set_up_dialog->get_ok_button()->set_disabled(!p_enabled); + project_path_input->set_editable(!p_enabled); + set_up_choice->set_disabled(p_enabled); + toggle_vcs_choice->set_pressed_no_signal(p_enabled); +} - EditorVCSInterface *vcs_interface = memnew(EditorVCSInterface); - ScriptInstance *addon_script_instance = script->instance_create(vcs_interface); +void VersionControlEditorPlugin::_set_credentials() { + CHECK_PLUGIN_INITIALIZED(); + + String username = set_up_username->get_text(); + String password = set_up_password->get_text(); + String ssh_public_key = set_up_ssh_public_key_path->get_text(); + String ssh_private_key = set_up_ssh_private_key_path->get_text(); + String ssh_passphrase = set_up_ssh_passphrase->get_text(); + + EditorVCSInterface::get_singleton()->set_credentials( + username, + password, + ssh_public_key, + ssh_private_key, + ssh_passphrase); + + EditorSettings::get_singleton()->set_setting("version_control/username", username); + EditorSettings::get_singleton()->set_setting("version_control/ssh_public_key_path", ssh_public_key); + EditorSettings::get_singleton()->set_setting("version_control/ssh_private_key_path", ssh_private_key); +} - ERR_FAIL_COND_MSG(!addon_script_instance, "Failed to create addon script instance."); +bool VersionControlEditorPlugin::_load_plugin(String p_name, String p_project_path) { + Object *extension_instance = ClassDB::instantiate(p_name); + ERR_FAIL_NULL_V_MSG(extension_instance, false, "Received a nullptr VCS extension instance during construction."); - // The addon is attached as a script to the VCS interface as a proxy end-point - vcs_interface->set_script_and_instance(script, addon_script_instance); + EditorVCSInterface *vcs_plugin = Object::cast_to<EditorVCSInterface>(extension_instance); + ERR_FAIL_NULL_V_MSG(vcs_plugin, false, vformat("Could not cast VCS extension instance to %s.", EditorVCSInterface::get_class_static())); - EditorVCSInterface::set_singleton(vcs_interface); - EditorFileSystem::get_singleton()->connect("filesystem_changed", callable_mp(this, &VersionControlEditorPlugin::_refresh_stage_area)); + String res_dir = project_path_input->get_text(); - String res_dir = OS::get_singleton()->get_resource_dir(); + ERR_FAIL_COND_V_MSG(!vcs_plugin->initialize(res_dir), false, "Could not initialize " + p_name); - ERR_FAIL_COND_MSG(!EditorVCSInterface::get_singleton()->initialize(res_dir), "VCS was not initialized"); + EditorVCSInterface::set_singleton(vcs_plugin); + + register_editor(); + EditorFileSystem::get_singleton()->connect(SNAME("filesystem_changed"), callable_mp(this, &VersionControlEditorPlugin::_refresh_stage_area)); _refresh_stage_area(); + _refresh_commit_list(); + _refresh_branch_list(); + _refresh_remote_list(); + + return true; } -void VersionControlEditorPlugin::_send_commit_msg() { - if (EditorVCSInterface::get_singleton()) { - if (staged_files_count == 0) { - commit_status->set_text(TTR("No files added to stage")); - return; +void VersionControlEditorPlugin::_update_set_up_warning(String p_new_text) { + bool empty_settings = set_up_username->get_text().strip_edges().is_empty() && + set_up_password->get_text().is_empty() && + set_up_ssh_public_key_path->get_text().strip_edges().is_empty() && + set_up_ssh_private_key_path->get_text().strip_edges().is_empty() && + set_up_ssh_passphrase->get_text().is_empty(); + + if (empty_settings) { + set_up_warning_text->add_theme_color_override(SNAME("font_color"), EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("warning_color"), SNAME("Editor"))); + set_up_warning_text->set_text(TTR("Remote settings are empty. VCS features that use the network may not work.")); + } else { + set_up_warning_text->set_text(""); + } +} + +void VersionControlEditorPlugin::_refresh_branch_list() { + CHECK_PLUGIN_INITIALIZED(); + + List<String> branch_list = EditorVCSInterface::get_singleton()->get_branch_list(); + branch_select->clear(); + + branch_select->set_disabled(branch_list.is_empty()); + + String current_branch = EditorVCSInterface::get_singleton()->get_current_branch_name(); + + for (int i = 0; i < branch_list.size(); i++) { + branch_select->add_icon_item(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("VcsBranches"), SNAME("EditorIcons")), branch_list[i], i); + + if (branch_list[i] == current_branch) { + branch_select->select(i); } + } +} + +String VersionControlEditorPlugin::_get_date_string_from(int64_t p_unix_timestamp, int64_t p_offset_minutes) const { + return vformat( + "%s %s", + Time::get_singleton()->get_datetime_string_from_unix_time(p_unix_timestamp + p_offset_minutes * 60, true), + Time::get_singleton()->get_offset_string_from_offset_minutes(p_offset_minutes)); +} - EditorVCSInterface::get_singleton()->commit(commit_message->get_text()); +void VersionControlEditorPlugin::_set_commit_list_size(int p_index) { + _refresh_commit_list(); +} - commit_message->set_text(""); - version_control_dock_button->set_pressed(false); - } else { - WARN_PRINT("No VCS addon is initialized. Select a Version Control Addon from Project menu"); +void VersionControlEditorPlugin::_refresh_commit_list() { + CHECK_PLUGIN_INITIALIZED(); + + commit_list->get_root()->clear_children(); + + List<EditorVCSInterface::Commit> commit_info_list = EditorVCSInterface::get_singleton()->get_previous_commits(commit_list_size_button->get_selected_metadata()); + + for (List<EditorVCSInterface::Commit>::Element *e = commit_info_list.front(); e; e = e->next()) { + EditorVCSInterface::Commit commit = e->get(); + TreeItem *item = commit_list->create_item(); + + // Only display the first line of a commit message + int line_ending = commit.msg.find_char('\n'); + String commit_display_msg = commit.msg.substr(0, line_ending); + String commit_date_string = _get_date_string_from(commit.unix_timestamp, commit.offset_minutes); + + Dictionary meta_data; + meta_data[SNAME("commit_id")] = commit.id; + meta_data[SNAME("commit_title")] = commit_display_msg; + meta_data[SNAME("commit_subtitle")] = commit.msg.substr(line_ending).strip_edges(); + meta_data[SNAME("commit_unix_timestamp")] = commit.unix_timestamp; + meta_data[SNAME("commit_author")] = commit.author; + meta_data[SNAME("commit_date_string")] = commit_date_string; + + item->set_text(0, commit_display_msg); + item->set_text(1, commit.author.strip_edges()); + item->set_metadata(0, meta_data); } +} + +void VersionControlEditorPlugin::_refresh_remote_list() { + CHECK_PLUGIN_INITIALIZED(); + + List<String> remotes = EditorVCSInterface::get_singleton()->get_remotes(); + + String current_remote = remote_select->get_selected_metadata(); + remote_select->clear(); - _update_commit_status(); + remote_select->set_disabled(remotes.is_empty()); + + for (int i = 0; i < remotes.size(); i++) { + remote_select->add_icon_item(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("ArrowUp"), SNAME("EditorIcons")), remotes[i], i); + remote_select->set_item_metadata(i, remotes[i]); + + if (remotes[i] == current_remote) { + remote_select->select(i); + } + } +} + +void VersionControlEditorPlugin::_commit() { + CHECK_PLUGIN_INITIALIZED(); + + String msg = commit_message->get_text().strip_edges(); + + ERR_FAIL_COND_MSG(msg.is_empty(), "No commit message was provided."); + + EditorVCSInterface::get_singleton()->commit(msg); + + version_control_dock_button->set_pressed(false); + + commit_message->release_focus(); + commit_button->release_focus(); + commit_message->set_text(""); + + _refresh_stage_area(); + _refresh_commit_list(); + _refresh_branch_list(); + _clear_diff(); +} + +void VersionControlEditorPlugin::_branch_item_selected(int p_index) { + CHECK_PLUGIN_INITIALIZED(); + + String branch_name = branch_select->get_item_text(p_index); + EditorVCSInterface::get_singleton()->checkout_branch(branch_name); + + EditorFileSystem::get_singleton()->scan_changes(); + ScriptEditor::get_singleton()->reload_scripts(); + + _refresh_branch_list(); + _refresh_commit_list(); _refresh_stage_area(); - _clear_file_diff(); + _clear_diff(); + + _update_opened_tabs(); +} + +void VersionControlEditorPlugin::_remote_selected(int p_index) { + _refresh_remote_list(); +} + +void VersionControlEditorPlugin::_ssh_public_key_selected(String p_path) { + set_up_ssh_public_key_path->set_text(p_path); +} + +void VersionControlEditorPlugin::_ssh_private_key_selected(String p_path) { + set_up_ssh_private_key_path->set_text(p_path); +} + +void VersionControlEditorPlugin::_popup_file_dialog(Variant p_file_dialog_variant) { + FileDialog *file_dialog = Object::cast_to<FileDialog>(p_file_dialog_variant); + ERR_FAIL_NULL(file_dialog); + + file_dialog->popup_centered_ratio(); +} + +void VersionControlEditorPlugin::_create_branch() { + CHECK_PLUGIN_INITIALIZED(); + + String new_branch_name = branch_create_name_input->get_text().strip_edges(); + + EditorVCSInterface::get_singleton()->create_branch(new_branch_name); + EditorVCSInterface::get_singleton()->checkout_branch(new_branch_name); + + branch_create_name_input->clear(); + _refresh_branch_list(); +} + +void VersionControlEditorPlugin::_create_remote() { + CHECK_PLUGIN_INITIALIZED(); + + String new_remote_name = remote_create_name_input->get_text().strip_edges(); + String new_remote_url = remote_create_url_input->get_text().strip_edges(); + + EditorVCSInterface::get_singleton()->create_remote(new_remote_name, new_remote_url); + + remote_create_name_input->clear(); + remote_create_url_input->clear(); + _refresh_remote_list(); +} + +void VersionControlEditorPlugin::_update_branch_create_button(String p_new_text) { + branch_create_ok->set_disabled(p_new_text.strip_edges().is_empty()); +} + +void VersionControlEditorPlugin::_update_remote_create_button(String p_new_text) { + remote_create_ok->set_disabled(p_new_text.strip_edges().is_empty()); +} + +int VersionControlEditorPlugin::_get_item_count(Tree *p_tree) { + if (!p_tree->get_root()) { + return 0; + } + return p_tree->get_root()->get_children().size(); } void VersionControlEditorPlugin::_refresh_stage_area() { - if (EditorVCSInterface::get_singleton()) { - staged_files_count = 0; - clear_stage_area(); - - Dictionary modified_file_paths = EditorVCSInterface::get_singleton()->get_modified_files_data(); - String file_path; - for (int i = 0; i < modified_file_paths.size(); i++) { - file_path = modified_file_paths.get_key_at_index(i); - TreeItem *found = stage_files->search_item_text(file_path, nullptr, true); - if (!found) { - ChangeType change_index = (ChangeType)(int)modified_file_paths.get_value_at_index(i); - String change_text = file_path + " (" + change_type_to_strings[change_index] + ")"; - Color &change_color = change_type_to_color[change_index]; - TreeItem *new_item = stage_files->create_item(stage_files->get_root()); - new_item->set_cell_mode(0, TreeItem::CELL_MODE_CHECK); - new_item->set_text(0, change_text); - new_item->set_metadata(0, file_path); - new_item->set_custom_color(0, change_color); - new_item->set_checked(0, true); - new_item->set_editable(0, true); - } else { - if (found->get_metadata(0) == diff_file_name->get_text()) { - _refresh_file_diff(); - } - } - commit_status->set_text(TTR("New changes detected")); + CHECK_PLUGIN_INITIALIZED(); + + staged_files->get_root()->clear_children(); + unstaged_files->get_root()->clear_children(); + + List<EditorVCSInterface::StatusFile> status_files = EditorVCSInterface::get_singleton()->get_modified_files_data(); + for (List<EditorVCSInterface::StatusFile>::Element *E = status_files.front(); E; E = E->next()) { + EditorVCSInterface::StatusFile sf = E->get(); + if (sf.area == EditorVCSInterface::TREE_AREA_STAGED) { + _add_new_item(staged_files, sf.file_path, sf.change_type); + } else if (sf.area == EditorVCSInterface::TREE_AREA_UNSTAGED) { + _add_new_item(unstaged_files, sf.file_path, sf.change_type); } + } + + staged_files->queue_redraw(); + unstaged_files->queue_redraw(); + + int total_changes = status_files.size(); + String commit_tab_title = TTR("Commit") + (total_changes > 0 ? " (" + itos(total_changes) + ")" : ""); + version_commit_dock->set_name(commit_tab_title); +} + +void VersionControlEditorPlugin::_discard_file(String p_file_path, EditorVCSInterface::ChangeType p_change) { + CHECK_PLUGIN_INITIALIZED(); + + if (p_change == EditorVCSInterface::CHANGE_TYPE_NEW) { + Ref<DirAccess> dir = DirAccess::create(DirAccess::ACCESS_RESOURCES); + dir->remove(p_file_path); } else { - WARN_PRINT("No VCS addon is initialized. Select a Version Control Addon from Project menu."); + CHECK_PLUGIN_INITIALIZED(); + EditorVCSInterface::get_singleton()->discard_file(p_file_path); } + // FIXIT: The project.godot file shows weird behaviour + EditorFileSystem::get_singleton()->update_file(p_file_path); } -void VersionControlEditorPlugin::_stage_selected() { - if (!EditorVCSInterface::get_singleton()) { - WARN_PRINT("No VCS addon is initialized. Select a Version Control Addon from Project menu"); - return; +void VersionControlEditorPlugin::_discard_all() { + TreeItem *file_entry = unstaged_files->get_root()->get_first_child(); + while (file_entry) { + String file_path = file_entry->get_meta(SNAME("file_path")); + EditorVCSInterface::ChangeType change = (EditorVCSInterface::ChangeType)(int)file_entry->get_meta(SNAME("change_type")); + _discard_file(file_path, change); + + file_entry = file_entry->get_next(); } + _refresh_stage_area(); +} - staged_files_count = 0; - TreeItem *root = stage_files->get_root(); - if (root) { - TreeItem *file_entry = root->get_first_child(); - while (file_entry) { - if (file_entry->is_checked(0)) { - EditorVCSInterface::get_singleton()->stage_file(file_entry->get_metadata(0)); - file_entry->set_icon_modulate(0, EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("success_color"), SNAME("Editor"))); - staged_files_count++; - } else { - EditorVCSInterface::get_singleton()->unstage_file(file_entry->get_metadata(0)); - file_entry->set_icon_modulate(0, EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("error_color"), SNAME("Editor"))); - } +void VersionControlEditorPlugin::_add_new_item(Tree *p_tree, String p_file_path, EditorVCSInterface::ChangeType p_change) { + String change_text = p_file_path + " (" + change_type_to_strings[p_change] + ")"; - file_entry = file_entry->get_next(); - } + TreeItem *new_item = p_tree->create_item(); + new_item->set_text(0, change_text); + new_item->set_icon(0, change_type_to_icon[p_change]); + new_item->set_meta(SNAME("file_path"), p_file_path); + new_item->set_meta(SNAME("change_type"), p_change); + new_item->set_custom_color(0, change_type_to_color[p_change]); + + new_item->add_button(0, EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("File"), SNAME("EditorIcons")), BUTTON_TYPE_OPEN, false, TTR("Open in editor")); + if (p_tree == unstaged_files) { + new_item->add_button(0, EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Close"), SNAME("EditorIcons")), BUTTON_TYPE_DISCARD, false, TTR("Discard changes")); } +} + +void VersionControlEditorPlugin::_fetch() { + CHECK_PLUGIN_INITIALIZED(); - _update_stage_status(); + EditorVCSInterface::get_singleton()->fetch(remote_select->get_selected_metadata()); + _refresh_branch_list(); } -void VersionControlEditorPlugin::_stage_all() { - if (!EditorVCSInterface::get_singleton()) { - WARN_PRINT("No VCS addon is initialized. Select a Version Control Addon from Project menu"); - return; - } +void VersionControlEditorPlugin::_pull() { + CHECK_PLUGIN_INITIALIZED(); + + EditorVCSInterface::get_singleton()->pull(remote_select->get_selected_metadata()); + _refresh_stage_area(); + _refresh_branch_list(); + _refresh_commit_list(); + _clear_diff(); + _update_opened_tabs(); +} + +void VersionControlEditorPlugin::_push() { + CHECK_PLUGIN_INITIALIZED(); + + EditorVCSInterface::get_singleton()->push(remote_select->get_selected_metadata(), false); +} + +void VersionControlEditorPlugin::_force_push() { + CHECK_PLUGIN_INITIALIZED(); - staged_files_count = 0; - TreeItem *root = stage_files->get_root(); - if (root) { - TreeItem *file_entry = root->get_first_child(); - while (file_entry) { - EditorVCSInterface::get_singleton()->stage_file(file_entry->get_metadata(0)); - file_entry->set_icon_modulate(0, EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("success_color"), SNAME("Editor"))); - file_entry->set_checked(0, true); - staged_files_count++; + EditorVCSInterface::get_singleton()->push(remote_select->get_selected_metadata(), true); +} - file_entry = file_entry->get_next(); +void VersionControlEditorPlugin::_update_opened_tabs() { + Vector<EditorData::EditedScene> open_scenes = EditorNode::get_singleton()->get_editor_data().get_edited_scenes(); + for (int i = 0; i < open_scenes.size(); i++) { + if (open_scenes[i].root == NULL) { + continue; } + EditorNode::get_singleton()->reload_scene(open_scenes[i].path); } +} - _update_stage_status(); +void VersionControlEditorPlugin::_move_all(Object *p_tree) { + Tree *tree = Object::cast_to<Tree>(p_tree); + + TreeItem *file_entry = tree->get_root()->get_first_child(); + while (file_entry) { + _move_item(tree, file_entry); + + file_entry = file_entry->get_next(); + } + _refresh_stage_area(); } -void VersionControlEditorPlugin::_view_file_diff() { +void VersionControlEditorPlugin::_load_diff(Object *p_tree) { + CHECK_PLUGIN_INITIALIZED(); + version_control_dock_button->set_pressed(true); - String file_path = stage_files->get_selected()->get_metadata(0); + Tree *tree = Object::cast_to<Tree>(p_tree); + if (tree == staged_files) { + show_commit_diff_header = false; + String file_path = tree->get_selected()->get_meta(SNAME("file_path")); + diff_title->set_text(TTR("Staged Changes")); + diff_content = EditorVCSInterface::get_singleton()->get_diff(file_path, EditorVCSInterface::TREE_AREA_STAGED); + } else if (tree == unstaged_files) { + show_commit_diff_header = false; + String file_path = tree->get_selected()->get_meta(SNAME("file_path")); + diff_title->set_text(TTR("Unstaged Changes")); + diff_content = EditorVCSInterface::get_singleton()->get_diff(file_path, EditorVCSInterface::TREE_AREA_UNSTAGED); + } else if (tree == commit_list) { + show_commit_diff_header = true; + Dictionary meta_data = tree->get_selected()->get_metadata(0); + String commit_id = meta_data[SNAME("commit_id")]; + String commit_title = meta_data[SNAME("commit_title")]; + diff_title->set_text(commit_title); + diff_content = EditorVCSInterface::get_singleton()->get_diff(commit_id, EditorVCSInterface::TREE_AREA_COMMIT); + } + _display_diff(0); +} + +void VersionControlEditorPlugin::_clear_diff() { + diff->clear(); + diff_content.clear(); + diff_title->set_text(""); +} + +void VersionControlEditorPlugin::_item_activated(Object *p_tree) { + Tree *tree = Object::cast_to<Tree>(p_tree); - _display_file_diff(file_path); + _move_item(tree, tree->get_selected()); + _refresh_stage_area(); +} + +void VersionControlEditorPlugin::_move_item(Tree *p_tree, TreeItem *p_item) { + CHECK_PLUGIN_INITIALIZED(); + + if (p_tree == staged_files) { + EditorVCSInterface::get_singleton()->unstage_file(p_item->get_meta(SNAME("file_path"))); + } else { + EditorVCSInterface::get_singleton()->stage_file(p_item->get_meta(SNAME("file_path"))); + } } -void VersionControlEditorPlugin::_display_file_diff(String p_file_path) { - TypedArray<Dictionary> diff_content = EditorVCSInterface::get_singleton()->get_file_diff(p_file_path); +void VersionControlEditorPlugin::_cell_button_pressed(Object *p_item, int p_column, int p_id, int p_mouse_button_index) { + TreeItem *item = Object::cast_to<TreeItem>(p_item); + String file_path = item->get_meta(SNAME("file_path")); + EditorVCSInterface::ChangeType change = (EditorVCSInterface::ChangeType)(int)item->get_meta(SNAME("change_type")); - diff_file_name->set_text(p_file_path); + if (p_id == BUTTON_TYPE_OPEN && change != EditorVCSInterface::CHANGE_TYPE_DELETED) { + Ref<DirAccess> dir = DirAccess::create(DirAccess::ACCESS_RESOURCES); + if (!dir->file_exists(file_path)) { + return; + } + + file_path = "res://" + file_path; + if (ResourceLoader::get_resource_type(file_path) == "PackedScene") { + EditorNode::get_singleton()->open_request(file_path); + } else if (file_path.ends_with(".gd")) { + EditorNode::get_singleton()->load_resource(file_path); + ScriptEditor::get_singleton()->reload_scripts(); + } else { + FileSystemDock::get_singleton()->navigate_to_path(file_path); + } + + } else if (p_id == BUTTON_TYPE_DISCARD) { + _discard_file(file_path, change); + _refresh_stage_area(); + } +} + +void VersionControlEditorPlugin::_display_diff(int p_idx) { + DiffViewType diff_view = (DiffViewType)diff_view_type_select->get_selected(); diff->clear(); - diff->push_font(EditorNode::get_singleton()->get_gui_base()->get_theme_font(SNAME("source"), SNAME("EditorFonts"))); + + if (show_commit_diff_header) { + Dictionary meta_data = commit_list->get_selected()->get_metadata(0); + String commit_id = meta_data[SNAME("commit_id")]; + String commit_subtitle = meta_data[SNAME("commit_subtitle")]; + String commit_date = meta_data[SNAME("commit_date")]; + String commit_author = meta_data[SNAME("commit_author")]; + String commit_date_string = meta_data[SNAME("commit_date_string")]; + + diff->push_font(EditorNode::get_singleton()->get_gui_base()->get_theme_font(SNAME("doc_bold"), SNAME("EditorFonts"))); + diff->push_color(EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("accent_color"), SNAME("Editor"))); + diff->add_text(TTR("Commit:") + " " + commit_id); + diff->add_newline(); + diff->add_text(TTR("Author:") + " " + commit_author); + diff->add_newline(); + diff->add_text(TTR("Date:") + " " + commit_date_string); + diff->add_newline(); + if (!commit_subtitle.is_empty()) { + diff->add_text(TTR("Subtitle:") + " " + commit_subtitle); + diff->add_newline(); + } + diff->add_newline(); + diff->pop(); + diff->pop(); + } + for (int i = 0; i < diff_content.size(); i++) { - Dictionary line_result = diff_content[i]; + EditorVCSInterface::DiffFile diff_file = diff_content[i]; + + diff->push_font(EditorNode::get_singleton()->get_gui_base()->get_theme_font(SNAME("doc_bold"), SNAME("EditorFonts"))); + diff->push_color(EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("accent_color"), SNAME("Editor"))); + diff->add_text(TTR("File:") + " " + diff_file.new_file); + diff->pop(); + diff->pop(); + + diff->add_newline(); + diff->push_font(EditorNode::get_singleton()->get_gui_base()->get_theme_font(SNAME("status_source"), SNAME("EditorFonts"))); + for (int j = 0; j < diff_file.diff_hunks.size(); j++) { + EditorVCSInterface::DiffHunk hunk = diff_file.diff_hunks[j]; + + String old_start = String::num_int64(hunk.old_start); + String new_start = String::num_int64(hunk.new_start); + String old_lines = String::num_int64(hunk.old_lines); + String new_lines = String::num_int64(hunk.new_lines); + + diff->append_text("[center]@@ " + old_start + "," + old_lines + " " + new_start + "," + new_lines + " @@[/center]"); + diff->add_newline(); + + switch (diff_view) { + case DIFF_VIEW_TYPE_SPLIT: + _display_diff_split_view(hunk.diff_lines); + break; + case DIFF_VIEW_TYPE_UNIFIED: + _display_diff_unified_view(hunk.diff_lines); + break; + } + diff->add_newline(); + diff->add_newline(); + } + diff->pop(); + + diff->add_newline(); + } +} + +void VersionControlEditorPlugin::_display_diff_split_view(List<EditorVCSInterface::DiffLine> &p_diff_content) { + List<EditorVCSInterface::DiffLine> parsed_diff; + + for (int i = 0; i < p_diff_content.size(); i++) { + EditorVCSInterface::DiffLine diff_line = p_diff_content[i]; + String line = diff_line.content.strip_edges(false, true); + + if (diff_line.new_line_no >= 0 && diff_line.old_line_no >= 0) { + diff_line.new_text = line; + diff_line.old_text = line; + parsed_diff.push_back(diff_line); + } else if (diff_line.new_line_no == -1) { + diff_line.new_text = ""; + diff_line.old_text = line; + parsed_diff.push_back(diff_line); + } else if (diff_line.old_line_no == -1) { + int j = parsed_diff.size() - 1; + while (j >= 0 && parsed_diff[j].new_line_no == -1) { + j--; + } + + if (j == parsed_diff.size() - 1) { + // no lines are modified + diff_line.new_text = line; + diff_line.old_text = ""; + parsed_diff.push_back(diff_line); + } else { + // lines are modified + EditorVCSInterface::DiffLine modified_line = parsed_diff[j + 1]; + modified_line.new_text = line; + modified_line.new_line_no = diff_line.new_line_no; + parsed_diff[j + 1] = modified_line; + } + } + } + + diff->push_table(6); + /* + [cell]Old Line No[/cell] + [cell]prefix[/cell] + [cell]Old Code[/cell] + + [cell]New Line No[/cell] + [cell]prefix[/cell] + [cell]New Line[/cell] + */ + + diff->set_table_column_expand(2, true); + diff->set_table_column_expand(5, true); + + for (int i = 0; i < parsed_diff.size(); i++) { + EditorVCSInterface::DiffLine diff_line = parsed_diff[i]; + + bool has_change = diff_line.status != " "; + static const Color red = EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("error_color"), SNAME("Editor")); + static const Color green = EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("success_color"), SNAME("Editor")); + static const Color white = EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("font_color"), SNAME("Label")) * Color(1, 1, 1, 0.6); + + if (diff_line.old_line_no >= 0) { + diff->push_cell(); + diff->push_indent(1); + diff->push_color(has_change ? red : white); + diff->add_text(String::num_int64(diff_line.old_line_no)); + diff->pop(); + diff->pop(); + diff->pop(); + + diff->push_cell(); + diff->push_color(has_change ? red : white); + diff->add_text(has_change ? "-|" : " |"); + diff->pop(); + diff->pop(); + + diff->push_cell(); + diff->push_color(has_change ? red : white); + diff->add_text(diff_line.old_text); + diff->pop(); + diff->pop(); - if (line_result["status"] == "+") { - diff->push_color(EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("success_color"), SNAME("Editor"))); - } else if (line_result["status"] == "-") { - diff->push_color(EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("error_color"), SNAME("Editor"))); } else { - diff->push_color(EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("font_color"), SNAME("Label"))); + diff->push_cell(); + diff->pop(); + + diff->push_cell(); + diff->pop(); + + diff->push_cell(); + diff->pop(); } - diff->add_text((String)line_result["content"]); + if (diff_line.new_line_no >= 0) { + diff->push_cell(); + diff->push_indent(1); + diff->push_color(has_change ? green : white); + diff->add_text(String::num_int64(diff_line.new_line_no)); + diff->pop(); + diff->pop(); + diff->pop(); + + diff->push_cell(); + diff->push_color(has_change ? green : white); + diff->add_text(has_change ? "+|" : " |"); + diff->pop(); + diff->pop(); + + diff->push_cell(); + diff->push_color(has_change ? green : white); + diff->add_text(diff_line.new_text); + diff->pop(); + diff->pop(); + } else { + diff->push_cell(); + diff->pop(); - diff->pop(); + diff->push_cell(); + diff->pop(); + + diff->push_cell(); + diff->pop(); + } } diff->pop(); } -void VersionControlEditorPlugin::_refresh_file_diff() { - String open_file = diff_file_name->get_text(); - if (!open_file.is_empty()) { - _display_file_diff(diff_file_name->get_text()); +void VersionControlEditorPlugin::_display_diff_unified_view(List<EditorVCSInterface::DiffLine> &p_diff_content) { + diff->push_table(4); + diff->set_table_column_expand(3, true); + + /* + [cell]Old Line No[/cell] + [cell]New Line No[/cell] + [cell]status[/cell] + [cell]code[/cell] + */ + for (int i = 0; i < p_diff_content.size(); i++) { + EditorVCSInterface::DiffLine diff_line = p_diff_content[i]; + String line = diff_line.content.strip_edges(false, true); + + Color color; + if (diff_line.status == "+") { + color = EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("success_color"), SNAME("Editor")); + } else if (diff_line.status == "-") { + color = EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("error_color"), SNAME("Editor")); + } else { + color = EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("font_color"), SNAME("Label")); + color *= Color(1, 1, 1, 0.6); + } + + diff->push_cell(); + diff->push_color(color); + diff->push_indent(1); + diff->add_text(diff_line.old_line_no >= 0 ? String::num_int64(diff_line.old_line_no) : ""); + diff->pop(); + diff->pop(); + diff->pop(); + + diff->push_cell(); + diff->push_color(color); + diff->push_indent(1); + diff->add_text(diff_line.new_line_no >= 0 ? String::num_int64(diff_line.new_line_no) : ""); + diff->pop(); + diff->pop(); + diff->pop(); + + diff->push_cell(); + diff->push_color(color); + diff->add_text(diff_line.status != "" ? diff_line.status + "|" : " |"); + diff->pop(); + diff->pop(); + + diff->push_cell(); + diff->push_color(color); + diff->add_text(line); + diff->pop(); + diff->pop(); } + + diff->pop(); } -void VersionControlEditorPlugin::_clear_file_diff() { - diff->clear(); - diff_file_name->set_text(""); - version_control_dock_button->set_pressed(false); +void VersionControlEditorPlugin::_update_commit_button() { + commit_button->set_disabled(commit_message->get_text().strip_edges().is_empty()); } -void VersionControlEditorPlugin::_update_stage_status() { - String status; - if (staged_files_count == 1) { - status = TTR("Stage contains 1 file"); - } else { - status = vformat(TTR("Stage contains %d files"), staged_files_count); +void VersionControlEditorPlugin::_remove_branch() { + CHECK_PLUGIN_INITIALIZED(); + + EditorVCSInterface::get_singleton()->remove_branch(branch_to_remove); + branch_to_remove.clear(); + + _refresh_branch_list(); +} + +void VersionControlEditorPlugin::_remove_remote() { + CHECK_PLUGIN_INITIALIZED(); + + EditorVCSInterface::get_singleton()->remove_remote(remote_to_remove); + remote_to_remove.clear(); + + _refresh_remote_list(); +} + +void VersionControlEditorPlugin::_extra_option_selected(int p_index) { + CHECK_PLUGIN_INITIALIZED(); + + switch ((ExtraOption)p_index) { + case EXTRA_OPTION_FORCE_PUSH: + _force_push(); + break; + case EXTRA_OPTION_CREATE_BRANCH: + branch_create_confirm->popup_centered(); + break; + case EXTRA_OPTION_CREATE_REMOTE: + remote_create_confirm->popup_centered(); + break; } - commit_status->set_text(status); } -void VersionControlEditorPlugin::_update_commit_status() { - String status; - if (staged_files_count == 1) { - status = TTR("Committed 1 file"); - } else { - status = vformat(TTR("Committed %d files"), staged_files_count); +void VersionControlEditorPlugin::_popup_branch_remove_confirm(int p_index) { + branch_to_remove = extra_options_remove_branch_list->get_item_text(p_index); + + branch_remove_confirm->set_text(vformat(TTR("Do you want to remove the %s branch?"), branch_to_remove)); + branch_remove_confirm->popup_centered(); +} + +void VersionControlEditorPlugin::_popup_remote_remove_confirm(int p_index) { + remote_to_remove = extra_options_remove_remote_list->get_item_text(p_index); + + remote_remove_confirm->set_text(vformat(TTR("Do you want to remove the %s remote?"), branch_to_remove)); + remote_remove_confirm->popup_centered(); +} + +void VersionControlEditorPlugin::_update_extra_options() { + extra_options_remove_branch_list->clear(); + for (int i = 0; i < branch_select->get_item_count(); i++) { + extra_options_remove_branch_list->add_icon_item(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("VcsBranches"), SNAME("EditorIcons")), branch_select->get_item_text(branch_select->get_item_id(i))); + } + extra_options_remove_branch_list->update_canvas_items(); + + extra_options_remove_remote_list->clear(); + for (int i = 0; i < remote_select->get_item_count(); i++) { + extra_options_remove_remote_list->add_icon_item(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("ArrowUp"), SNAME("EditorIcons")), remote_select->get_item_text(remote_select->get_item_id(i))); } - commit_status->set_text(status); - staged_files_count = 0; + extra_options_remove_remote_list->update_canvas_items(); } -void VersionControlEditorPlugin::_update_commit_button() { - commit_button->set_disabled(commit_message->get_text().strip_edges().is_empty()); +bool VersionControlEditorPlugin::_is_staging_area_empty() { + return staged_files->get_root()->get_child_count() == 0; } void VersionControlEditorPlugin::_commit_message_gui_input(const Ref<InputEvent> &p_event) { @@ -316,266 +922,660 @@ void VersionControlEditorPlugin::_commit_message_gui_input(const Ref<InputEvent> if (k.is_valid() && k->is_pressed()) { if (ED_IS_SHORTCUT("version_control/commit", p_event)) { - if (staged_files_count == 0) { + if (_is_staging_area_empty()) { // Stage all files only when no files were previously staged. - _stage_all(); + _move_all(unstaged_files); } - _send_commit_msg(); + + _commit(); + commit_message->accept_event(); - return; } } } -void VersionControlEditorPlugin::register_editor() { - if (!EditorVCSInterface::get_singleton()) { - EditorNode::get_singleton()->add_control_to_dock(EditorNode::DOCK_SLOT_RIGHT_UL, version_commit_dock); - TabContainer *dock_vbc = (TabContainer *)version_commit_dock->get_parent_control(); - dock_vbc->set_tab_title(dock_vbc->get_tab_idx_from_control(version_commit_dock), TTR("Commit")); - - Button *vc = EditorNode::get_singleton()->add_bottom_panel_item(TTR("Version Control"), version_control_dock); - set_version_control_tool_button(vc); +void VersionControlEditorPlugin::_toggle_vcs_integration(bool p_toggled) { + if (p_toggled) { + _initialize_vcs(); + } else { + shut_down(); } } -void VersionControlEditorPlugin::fetch_available_vcs_addon_names() { - List<StringName> global_classes; - ScriptServer::get_global_class_list(&global_classes); - - for (int i = 0; i != global_classes.size(); i++) { - String path = ScriptServer::get_global_class_path(global_classes[i]); - Ref<Script> script = ResourceLoader::load(path); - ERR_FAIL_COND(script.is_null()); +void VersionControlEditorPlugin::_project_path_selected(String p_project_path) { + project_path_input->set_text(p_project_path); +} - if (script->get_instance_base_type() == "EditorVCSInterface") { - available_addons.push_back(global_classes[i]); - } - } +void VersionControlEditorPlugin::fetch_available_vcs_plugin_names() { + available_plugins.clear(); + ClassDB::get_direct_inheriters_from_class(EditorVCSInterface::get_class_static(), &available_plugins); } -void VersionControlEditorPlugin::clear_stage_area() { - stage_files->get_root()->clear_children(); +void VersionControlEditorPlugin::register_editor() { + EditorNode::get_singleton()->add_control_to_dock(EditorNode::DOCK_SLOT_RIGHT_UL, version_commit_dock); + + version_control_dock_button = EditorNode::get_singleton()->add_bottom_panel_item(TTR("Version Control"), version_control_dock); + + _set_vcs_ui_state(true); } void VersionControlEditorPlugin::shut_down() { - if (EditorVCSInterface::get_singleton()) { - if (EditorFileSystem::get_singleton()->is_connected("filesystem_changed", callable_mp(this, &VersionControlEditorPlugin::_refresh_stage_area))) { - EditorFileSystem::get_singleton()->disconnect("filesystem_changed", callable_mp(this, &VersionControlEditorPlugin::_refresh_stage_area)); - } - EditorVCSInterface::get_singleton()->shut_down(); - memdelete(EditorVCSInterface::get_singleton()); - EditorVCSInterface::set_singleton(nullptr); + if (!EditorVCSInterface::get_singleton()) { + return; + } - EditorNode::get_singleton()->remove_control_from_dock(version_commit_dock); - EditorNode::get_singleton()->remove_bottom_panel_item(version_control_dock); + if (EditorFileSystem::get_singleton()->is_connected(SNAME("filesystem_changed"), callable_mp(this, &VersionControlEditorPlugin::_refresh_stage_area))) { + EditorFileSystem::get_singleton()->disconnect(SNAME("filesystem_changed"), callable_mp(this, &VersionControlEditorPlugin::_refresh_stage_area)); } -} -bool VersionControlEditorPlugin::is_vcs_initialized() const { - return EditorVCSInterface::get_singleton() ? EditorVCSInterface::get_singleton()->is_vcs_initialized() : false; -} + EditorVCSInterface::get_singleton()->shut_down(); + memdelete(EditorVCSInterface::get_singleton()); + EditorVCSInterface::set_singleton(nullptr); + + EditorNode::get_singleton()->remove_control_from_dock(version_commit_dock); + EditorNode::get_singleton()->remove_bottom_panel_item(version_control_dock); -const String VersionControlEditorPlugin::get_vcs_name() const { - return EditorVCSInterface::get_singleton() ? EditorVCSInterface::get_singleton()->get_vcs_name() : ""; + _set_vcs_ui_state(false); } VersionControlEditorPlugin::VersionControlEditorPlugin() { singleton = this; - staged_files_count = 0; version_control_actions = memnew(PopupMenu); metadata_dialog = memnew(ConfirmationDialog); metadata_dialog->set_title(TTR("Create Version Control Metadata")); metadata_dialog->set_min_size(Size2(200, 40)); + metadata_dialog->get_ok_button()->connect(SNAME("pressed"), callable_mp(this, &VersionControlEditorPlugin::_create_vcs_metadata_files)); version_control_actions->add_child(metadata_dialog); VBoxContainer *metadata_vb = memnew(VBoxContainer); + metadata_dialog->add_child(metadata_vb); + HBoxContainer *metadata_hb = memnew(HBoxContainer); metadata_hb->set_custom_minimum_size(Size2(200, 20)); + metadata_vb->add_child(metadata_hb); + Label *l = memnew(Label); l->set_text(TTR("Create VCS metadata files for:")); metadata_hb->add_child(l); + metadata_selection = memnew(OptionButton); metadata_selection->set_custom_minimum_size(Size2(100, 20)); metadata_selection->add_item("None", (int)EditorVCSInterface::VCSMetadata::NONE); metadata_selection->add_item("Git", (int)EditorVCSInterface::VCSMetadata::GIT); metadata_selection->select((int)EditorVCSInterface::VCSMetadata::GIT); - metadata_dialog->get_ok_button()->connect("pressed", callable_mp(this, &VersionControlEditorPlugin::_create_vcs_metadata_files)); metadata_hb->add_child(metadata_selection); - metadata_vb->add_child(metadata_hb); + l = memnew(Label); l->set_text(TTR("Existing VCS metadata files will be overwritten.")); metadata_vb->add_child(l); - metadata_dialog->add_child(metadata_vb); set_up_dialog = memnew(AcceptDialog); - set_up_dialog->set_title(TTR("Set Up Version Control")); - set_up_dialog->set_min_size(Size2(400, 100)); + set_up_dialog->set_title(TTR("Local Settings")); + set_up_dialog->set_min_size(Size2(600, 100)); + set_up_dialog->add_cancel_button("Cancel"); + set_up_dialog->set_hide_on_ok(true); version_control_actions->add_child(set_up_dialog); - set_up_ok_button = set_up_dialog->get_ok_button(); - set_up_ok_button->set_text(TTR("Close")); + Button *set_up_apply_button = set_up_dialog->get_ok_button(); + set_up_apply_button->set_text(TTR("Apply")); + set_up_apply_button->connect(SNAME("pressed"), callable_mp(this, &VersionControlEditorPlugin::_set_credentials)); set_up_vbc = memnew(VBoxContainer); set_up_vbc->set_alignment(BoxContainer::ALIGNMENT_CENTER); set_up_dialog->add_child(set_up_vbc); - set_up_hbc = memnew(HBoxContainer); - set_up_hbc->set_h_size_flags(BoxContainer::SIZE_EXPAND_FILL); + HBoxContainer *set_up_hbc = memnew(HBoxContainer); + set_up_hbc->set_h_size_flags(Control::SIZE_EXPAND_FILL); set_up_vbc->add_child(set_up_hbc); - set_up_vcs_status = memnew(RichTextLabel); - set_up_vcs_status->set_text(TTR("VCS Addon is not initialized")); - set_up_vbc->add_child(set_up_vcs_status); - - set_up_vcs_label = memnew(Label); - set_up_vcs_label->set_text(TTR("Version Control System")); + Label *set_up_vcs_label = memnew(Label); + set_up_vcs_label->set_h_size_flags(Control::SIZE_EXPAND_FILL); + set_up_vcs_label->set_text(TTR("VCS Provider")); set_up_hbc->add_child(set_up_vcs_label); set_up_choice = memnew(OptionButton); - set_up_choice->set_h_size_flags(HBoxContainer::SIZE_EXPAND_FILL); - set_up_choice->connect("item_selected", callable_mp(this, &VersionControlEditorPlugin::_selected_a_vcs)); + set_up_choice->set_h_size_flags(Control::SIZE_EXPAND_FILL); set_up_hbc->add_child(set_up_choice); - set_up_init_settings = nullptr; - - set_up_init_button = memnew(Button); - set_up_init_button->set_text(TTR("Initialize")); - set_up_init_button->connect("pressed", callable_mp(this, &VersionControlEditorPlugin::_initialize_vcs)); - set_up_vbc->add_child(set_up_init_button); + HBoxContainer *project_path_hbc = memnew(HBoxContainer); + project_path_hbc->set_h_size_flags(Control::SIZE_FILL); + set_up_vbc->add_child(project_path_hbc); + + Label *project_path_label = memnew(Label); + project_path_label->set_h_size_flags(Control::SIZE_EXPAND_FILL); + project_path_label->set_text(TTR("VCS Project Path")); + project_path_hbc->add_child(project_path_label); + + project_path_input = memnew(LineEdit); + project_path_input->set_h_size_flags(Control::SIZE_EXPAND_FILL); + project_path_input->set_text(OS::get_singleton()->get_resource_dir()); + project_path_hbc->add_child(project_path_input); + + FileDialog *select_project_path_file_dialog = memnew(FileDialog); + select_project_path_file_dialog->set_access(FileDialog::ACCESS_FILESYSTEM); + select_project_path_file_dialog->set_file_mode(FileDialog::FILE_MODE_OPEN_DIR); + select_project_path_file_dialog->set_show_hidden_files(true); + select_project_path_file_dialog->set_current_dir(OS::get_singleton()->get_resource_dir()); + select_project_path_file_dialog->connect(SNAME("dir_selected"), callable_mp(this, &VersionControlEditorPlugin::_project_path_selected)); + project_path_hbc->add_child(select_project_path_file_dialog); + + select_project_path_button = memnew(Button); + select_project_path_button->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon("Folder", "EditorIcons")); + select_project_path_button->connect(SNAME("pressed"), callable_mp(this, &VersionControlEditorPlugin::_popup_file_dialog).bind(select_project_path_file_dialog)); + select_project_path_button->set_tooltip_text(TTR("Select VCS project path")); + project_path_hbc->add_child(select_project_path_button); + + HBoxContainer *toggle_vcs_hbc = memnew(HBoxContainer); + toggle_vcs_hbc->set_h_size_flags(Control::SIZE_EXPAND_FILL); + set_up_vbc->add_child(toggle_vcs_hbc); + + Label *toggle_vcs_label = memnew(Label); + toggle_vcs_label->set_h_size_flags(Control::SIZE_EXPAND_FILL); + toggle_vcs_label->set_text(TTR("Connect to VCS")); + toggle_vcs_hbc->add_child(toggle_vcs_label); + + toggle_vcs_choice = memnew(CheckButton); + toggle_vcs_choice->set_h_size_flags(Control::SIZE_EXPAND_FILL); + toggle_vcs_choice->set_pressed_no_signal(false); + toggle_vcs_choice->connect(SNAME("toggled"), callable_mp(this, &VersionControlEditorPlugin::_toggle_vcs_integration)); + toggle_vcs_hbc->add_child(toggle_vcs_choice); + + set_up_vbc->add_child(memnew(HSeparator)); + + set_up_settings_vbc = memnew(VBoxContainer); + set_up_settings_vbc->set_alignment(BoxContainer::ALIGNMENT_CENTER); + set_up_vbc->add_child(set_up_settings_vbc); + + Label *remote_login = memnew(Label); + remote_login->set_h_size_flags(Control::SIZE_EXPAND_FILL); + remote_login->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER); + remote_login->set_text(TTR("Remote Login")); + set_up_settings_vbc->add_child(remote_login); + + HBoxContainer *set_up_username_input = memnew(HBoxContainer); + set_up_username_input->set_h_size_flags(Control::SIZE_EXPAND_FILL); + set_up_settings_vbc->add_child(set_up_username_input); + + Label *set_up_username_label = memnew(Label); + set_up_username_label->set_h_size_flags(Control::SIZE_EXPAND_FILL); + set_up_username_label->set_text(TTR("Username")); + set_up_username_input->add_child(set_up_username_label); + + set_up_username = memnew(LineEdit); + set_up_username->set_h_size_flags(Control::SIZE_EXPAND_FILL); + set_up_username->set_text(EDITOR_DEF("version_control/username", "")); + set_up_username->connect(SNAME("text_changed"), callable_mp(this, &VersionControlEditorPlugin::_update_set_up_warning)); + set_up_username_input->add_child(set_up_username); + + HBoxContainer *set_up_password_input = memnew(HBoxContainer); + set_up_password_input->set_h_size_flags(Control::SIZE_EXPAND_FILL); + set_up_settings_vbc->add_child(set_up_password_input); + + Label *set_up_password_label = memnew(Label); + set_up_password_label->set_text(TTR("Password")); + set_up_password_label->set_h_size_flags(Control::SIZE_EXPAND_FILL); + set_up_password_input->add_child(set_up_password_label); + + set_up_password = memnew(LineEdit); + set_up_password->set_h_size_flags(Control::SIZE_EXPAND_FILL); + set_up_password->set_secret(true); + set_up_password->connect(SNAME("text_changed"), callable_mp(this, &VersionControlEditorPlugin::_update_set_up_warning)); + set_up_password_input->add_child(set_up_password); + + HBoxContainer *set_up_ssh_public_key_input = memnew(HBoxContainer); + set_up_ssh_public_key_input->set_h_size_flags(Control::SIZE_EXPAND_FILL); + set_up_settings_vbc->add_child(set_up_ssh_public_key_input); + + Label *set_up_ssh_public_key_label = memnew(Label); + set_up_ssh_public_key_label->set_text(TTR("SSH Public Key Path")); + set_up_ssh_public_key_label->set_h_size_flags(Control::SIZE_EXPAND_FILL); + set_up_ssh_public_key_input->add_child(set_up_ssh_public_key_label); + + HBoxContainer *set_up_ssh_public_key_input_hbc = memnew(HBoxContainer); + set_up_ssh_public_key_input_hbc->set_h_size_flags(Control::SIZE_EXPAND_FILL); + set_up_ssh_public_key_input->add_child(set_up_ssh_public_key_input_hbc); + + set_up_ssh_public_key_path = memnew(LineEdit); + set_up_ssh_public_key_path->set_h_size_flags(Control::SIZE_EXPAND_FILL); + set_up_ssh_public_key_path->set_text(EDITOR_DEF("version_control/ssh_public_key_path", "")); + set_up_ssh_public_key_path->connect(SNAME("text_changed"), callable_mp(this, &VersionControlEditorPlugin::_update_set_up_warning)); + set_up_ssh_public_key_input_hbc->add_child(set_up_ssh_public_key_path); + + set_up_ssh_public_key_file_dialog = memnew(FileDialog); + set_up_ssh_public_key_file_dialog->set_access(FileDialog::ACCESS_FILESYSTEM); + set_up_ssh_public_key_file_dialog->set_file_mode(FileDialog::FILE_MODE_OPEN_FILE); + set_up_ssh_public_key_file_dialog->set_show_hidden_files(true); + // TODO: Make this start at the user's home folder + Ref<DirAccess> d = DirAccess::open(OS::get_singleton()->get_system_dir(OS::SYSTEM_DIR_DOCUMENTS)); + d->change_dir("../"); + set_up_ssh_public_key_file_dialog->set_current_dir(d->get_current_dir()); + set_up_ssh_public_key_file_dialog->connect(SNAME("file_selected"), callable_mp(this, &VersionControlEditorPlugin::_ssh_public_key_selected)); + 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_theme_icon("Folder", "EditorIcons")); + select_public_path_button->connect(SNAME("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); + + HBoxContainer *set_up_ssh_private_key_input = memnew(HBoxContainer); + set_up_ssh_private_key_input->set_h_size_flags(Control::SIZE_EXPAND_FILL); + set_up_settings_vbc->add_child(set_up_ssh_private_key_input); + + Label *set_up_ssh_private_key_label = memnew(Label); + set_up_ssh_private_key_label->set_text(TTR("SSH Private Key Path")); + set_up_ssh_private_key_label->set_h_size_flags(Control::SIZE_EXPAND_FILL); + set_up_ssh_private_key_input->add_child(set_up_ssh_private_key_label); + + HBoxContainer *set_up_ssh_private_key_input_hbc = memnew(HBoxContainer); + set_up_ssh_private_key_input_hbc->set_h_size_flags(Control::SIZE_EXPAND_FILL); + set_up_ssh_private_key_input->add_child(set_up_ssh_private_key_input_hbc); + + set_up_ssh_private_key_path = memnew(LineEdit); + set_up_ssh_private_key_path->set_h_size_flags(Control::SIZE_EXPAND_FILL); + set_up_ssh_private_key_path->set_text(EDITOR_DEF("version_control/ssh_private_key_path", "")); + set_up_ssh_private_key_path->connect(SNAME("text_changed"), callable_mp(this, &VersionControlEditorPlugin::_update_set_up_warning)); + set_up_ssh_private_key_input_hbc->add_child(set_up_ssh_private_key_path); + + set_up_ssh_private_key_file_dialog = memnew(FileDialog); + set_up_ssh_private_key_file_dialog->set_access(FileDialog::ACCESS_FILESYSTEM); + set_up_ssh_private_key_file_dialog->set_file_mode(FileDialog::FILE_MODE_OPEN_FILE); + set_up_ssh_private_key_file_dialog->set_show_hidden_files(true); + // TODO: Make this start at the user's home folder + set_up_ssh_private_key_file_dialog->set_current_dir(d->get_current_dir()); + set_up_ssh_private_key_file_dialog->connect("file_selected", callable_mp(this, &VersionControlEditorPlugin::_ssh_private_key_selected)); + 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_theme_icon("Folder", "EditorIcons")); + select_private_path_button->connect(SNAME("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); + + HBoxContainer *set_up_ssh_passphrase_input = memnew(HBoxContainer); + set_up_ssh_passphrase_input->set_h_size_flags(Control::SIZE_EXPAND_FILL); + set_up_settings_vbc->add_child(set_up_ssh_passphrase_input); + + Label *set_up_ssh_passphrase_label = memnew(Label); + set_up_ssh_passphrase_label->set_text(TTR("SSH Passphrase")); + set_up_ssh_passphrase_label->set_h_size_flags(Control::SIZE_EXPAND_FILL); + set_up_ssh_passphrase_input->add_child(set_up_ssh_passphrase_label); + + set_up_ssh_passphrase = memnew(LineEdit); + set_up_ssh_passphrase->set_h_size_flags(Control::SIZE_EXPAND_FILL); + set_up_ssh_passphrase->set_secret(true); + set_up_ssh_passphrase->connect(SNAME("text_changed"), callable_mp(this, &VersionControlEditorPlugin::_update_set_up_warning)); + set_up_ssh_passphrase_input->add_child(set_up_ssh_passphrase); + + set_up_warning_text = memnew(Label); + set_up_warning_text->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER); + set_up_warning_text->set_h_size_flags(Control::SIZE_EXPAND_FILL); + set_up_settings_vbc->add_child(set_up_warning_text); version_commit_dock = memnew(VBoxContainer); version_commit_dock->set_visible(false); + version_commit_dock->set_name(TTR("Commit")); - commit_box_vbc = memnew(VBoxContainer); - commit_box_vbc->set_alignment(VBoxContainer::ALIGNMENT_BEGIN); - commit_box_vbc->set_h_size_flags(VBoxContainer::SIZE_EXPAND_FILL); - commit_box_vbc->set_v_size_flags(VBoxContainer::SIZE_EXPAND_FILL); - version_commit_dock->add_child(commit_box_vbc); + VBoxContainer *unstage_area = memnew(VBoxContainer); + unstage_area->set_v_size_flags(Control::SIZE_EXPAND_FILL); + unstage_area->set_h_size_flags(Control::SIZE_EXPAND_FILL); + version_commit_dock->add_child(unstage_area); - stage_tools = memnew(HSplitContainer); - stage_tools->set_dragger_visibility(SplitContainer::DRAGGER_HIDDEN_COLLAPSED); - commit_box_vbc->add_child(stage_tools); + HBoxContainer *unstage_title = memnew(HBoxContainer); + unstage_area->add_child(unstage_title); - staging_area_label = memnew(Label); - staging_area_label->set_h_size_flags(Label::SIZE_EXPAND_FILL); - staging_area_label->set_text(TTR("Staging area")); - stage_tools->add_child(staging_area_label); + Label *unstage_label = memnew(Label); + unstage_label->set_text(TTR("Unstaged Changes")); + unstage_label->set_h_size_flags(Control::SIZE_EXPAND_FILL); + unstage_title->add_child(unstage_label); refresh_button = memnew(Button); refresh_button->set_tooltip_text(TTR("Detect new changes")); - refresh_button->set_text(TTR("Refresh")); + refresh_button->set_flat(true); refresh_button->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Reload"), SNAME("EditorIcons"))); - refresh_button->connect("pressed", callable_mp(this, &VersionControlEditorPlugin::_refresh_stage_area)); - stage_tools->add_child(refresh_button); - - stage_files = memnew(Tree); - stage_files->set_h_size_flags(Tree::SIZE_EXPAND_FILL); - stage_files->set_v_size_flags(Tree::SIZE_EXPAND_FILL); - stage_files->set_columns(1); - stage_files->set_column_title(0, TTR("Changes")); - stage_files->set_column_titles_visible(true); - stage_files->set_allow_reselect(true); - stage_files->set_allow_rmb_select(true); - stage_files->set_select_mode(Tree::SelectMode::SELECT_MULTI); - stage_files->set_edit_checkbox_cell_only_when_checkbox_is_pressed(true); - stage_files->connect("cell_selected", callable_mp(this, &VersionControlEditorPlugin::_view_file_diff)); - stage_files->create_item(); - stage_files->set_hide_root(true); - commit_box_vbc->add_child(stage_files); - - change_type_to_strings[CHANGE_TYPE_NEW] = TTR("New"); - change_type_to_strings[CHANGE_TYPE_MODIFIED] = TTR("Modified"); - change_type_to_strings[CHANGE_TYPE_RENAMED] = TTR("Renamed"); - change_type_to_strings[CHANGE_TYPE_DELETED] = TTR("Deleted"); - change_type_to_strings[CHANGE_TYPE_TYPECHANGE] = TTR("Typechange"); - - change_type_to_color[CHANGE_TYPE_NEW] = EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("success_color"), SNAME("Editor")); - change_type_to_color[CHANGE_TYPE_MODIFIED] = EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("warning_color"), SNAME("Editor")); - change_type_to_color[CHANGE_TYPE_RENAMED] = EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("disabled_font_color"), SNAME("Editor")); - change_type_to_color[CHANGE_TYPE_DELETED] = EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("error_color"), SNAME("Editor")); - change_type_to_color[CHANGE_TYPE_TYPECHANGE] = EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("font_color"), SNAME("Editor")); - - stage_buttons = memnew(HSplitContainer); - stage_buttons->set_dragger_visibility(SplitContainer::DRAGGER_HIDDEN_COLLAPSED); - commit_box_vbc->add_child(stage_buttons); - - stage_selected_button = memnew(Button); - stage_selected_button->set_h_size_flags(Button::SIZE_EXPAND_FILL); - stage_selected_button->set_text(TTR("Stage Selected")); - stage_selected_button->connect("pressed", callable_mp(this, &VersionControlEditorPlugin::_stage_selected)); - stage_buttons->add_child(stage_selected_button); + refresh_button->connect(SNAME("pressed"), callable_mp(this, &VersionControlEditorPlugin::_refresh_stage_area)); + refresh_button->connect(SNAME("pressed"), callable_mp(this, &VersionControlEditorPlugin::_refresh_commit_list)); + refresh_button->connect(SNAME("pressed"), callable_mp(this, &VersionControlEditorPlugin::_refresh_branch_list)); + refresh_button->connect(SNAME("pressed"), callable_mp(this, &VersionControlEditorPlugin::_refresh_remote_list)); + unstage_title->add_child(refresh_button); + + discard_all_button = memnew(Button); + discard_all_button->set_tooltip_text(TTR("Discard all changes")); + discard_all_button->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Close"), SNAME("EditorIcons"))); + discard_all_button->connect(SNAME("pressed"), callable_mp(this, &VersionControlEditorPlugin::_discard_all)); + discard_all_button->set_flat(true); + unstage_title->add_child(discard_all_button); stage_all_button = memnew(Button); - stage_all_button->set_text(TTR("Stage All")); - stage_all_button->connect("pressed", callable_mp(this, &VersionControlEditorPlugin::_stage_all)); - stage_buttons->add_child(stage_all_button); - - commit_box_vbc->add_child(memnew(HSeparator)); + stage_all_button->set_flat(true); + stage_all_button->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("MoveDown"), SNAME("EditorIcons"))); + stage_all_button->set_tooltip_text(TTR("Stage all changes")); + unstage_title->add_child(stage_all_button); + + unstaged_files = memnew(Tree); + unstaged_files->set_h_size_flags(Tree::SIZE_EXPAND_FILL); + unstaged_files->set_v_size_flags(Tree::SIZE_EXPAND_FILL); + unstaged_files->set_select_mode(Tree::SELECT_ROW); + unstaged_files->connect(SNAME("item_selected"), callable_mp(this, &VersionControlEditorPlugin::_load_diff).bind(unstaged_files)); + unstaged_files->connect(SNAME("item_activated"), callable_mp(this, &VersionControlEditorPlugin::_item_activated).bind(unstaged_files)); + unstaged_files->connect(SNAME("button_clicked"), callable_mp(this, &VersionControlEditorPlugin::_cell_button_pressed)); + unstaged_files->create_item(); + unstaged_files->set_hide_root(true); + unstage_area->add_child(unstaged_files); + + VBoxContainer *stage_area = memnew(VBoxContainer); + stage_area->set_v_size_flags(Control::SIZE_EXPAND_FILL); + stage_area->set_h_size_flags(Control::SIZE_EXPAND_FILL); + version_commit_dock->add_child(stage_area); + + HBoxContainer *stage_title = memnew(HBoxContainer); + stage_area->add_child(stage_title); + + Label *stage_label = memnew(Label); + stage_label->set_text(TTR("Staged Changes")); + stage_label->set_h_size_flags(Control::SIZE_EXPAND_FILL); + stage_title->add_child(stage_label); + + unstage_all_button = memnew(Button); + unstage_all_button->set_flat(true); + unstage_all_button->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("MoveUp"), SNAME("EditorIcons"))); + unstage_all_button->set_tooltip_text(TTR("Unstage all changes")); + stage_title->add_child(unstage_all_button); + + staged_files = memnew(Tree); + staged_files->set_h_size_flags(Tree::SIZE_EXPAND_FILL); + staged_files->set_v_size_flags(Tree::SIZE_EXPAND_FILL); + staged_files->set_select_mode(Tree::SELECT_ROW); + staged_files->connect(SNAME("item_selected"), callable_mp(this, &VersionControlEditorPlugin::_load_diff).bind(staged_files)); + staged_files->connect(SNAME("button_clicked"), callable_mp(this, &VersionControlEditorPlugin::_cell_button_pressed)); + staged_files->connect(SNAME("item_activated"), callable_mp(this, &VersionControlEditorPlugin::_item_activated).bind(staged_files)); + staged_files->create_item(); + staged_files->set_hide_root(true); + stage_area->add_child(staged_files); + + // Editor crashes if bind is null + unstage_all_button->connect(SNAME("pressed"), callable_mp(this, &VersionControlEditorPlugin::_move_all).bind(staged_files)); + stage_all_button->connect(SNAME("pressed"), callable_mp(this, &VersionControlEditorPlugin::_move_all).bind(unstaged_files)); + + version_commit_dock->add_child(memnew(HSeparator)); + + VBoxContainer *commit_area = memnew(VBoxContainer); + version_commit_dock->add_child(commit_area); + + Label *commit_label = memnew(Label); + commit_label->set_text(TTR("Commit Message")); + commit_label->set_h_size_flags(Control::SIZE_EXPAND_FILL); + commit_area->add_child(commit_label); commit_message = memnew(TextEdit); commit_message->set_h_size_flags(Control::SIZE_EXPAND_FILL); commit_message->set_h_grow_direction(Control::GrowDirection::GROW_DIRECTION_BEGIN); commit_message->set_v_grow_direction(Control::GrowDirection::GROW_DIRECTION_END); commit_message->set_custom_minimum_size(Size2(200, 100)); - commit_message->set_line_wrapping_mode(TextEdit::LineWrappingMode::LINE_WRAPPING_BOUNDARY); - commit_message->connect("text_changed", callable_mp(this, &VersionControlEditorPlugin::_update_commit_button)); - commit_message->connect("gui_input", callable_mp(this, &VersionControlEditorPlugin::_commit_message_gui_input)); - commit_box_vbc->add_child(commit_message); + commit_message->set_line_wrapping_mode(TextEdit::LINE_WRAPPING_BOUNDARY); + commit_message->connect(SNAME("text_changed"), callable_mp(this, &VersionControlEditorPlugin::_update_commit_button)); + commit_message->connect(SNAME("gui_input"), callable_mp(this, &VersionControlEditorPlugin::_commit_message_gui_input)); + commit_area->add_child(commit_message); + ED_SHORTCUT("version_control/commit", TTR("Commit"), KeyModifierMask::CMD | Key::ENTER); commit_button = memnew(Button); commit_button->set_text(TTR("Commit Changes")); commit_button->set_disabled(true); - commit_button->connect("pressed", callable_mp(this, &VersionControlEditorPlugin::_send_commit_msg)); - commit_box_vbc->add_child(commit_button); - - commit_status = memnew(Label); - commit_status->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER); - commit_box_vbc->add_child(commit_status); - - version_control_dock = memnew(PanelContainer); + commit_button->connect(SNAME("pressed"), callable_mp(this, &VersionControlEditorPlugin::_commit)); + commit_area->add_child(commit_button); + + version_commit_dock->add_child(memnew(HSeparator)); + + HBoxContainer *commit_list_hbc = memnew(HBoxContainer); + version_commit_dock->add_child(commit_list_hbc); + + Label *commit_list_label = memnew(Label); + commit_list_label->set_text(TTR("Commit List")); + commit_list_label->set_h_size_flags(Control::SIZE_EXPAND_FILL); + commit_list_hbc->add_child(commit_list_label); + + commit_list_size_button = memnew(OptionButton); + commit_list_size_button->set_tooltip_text(TTR("Commit list size")); + commit_list_size_button->add_item("10"); + commit_list_size_button->set_item_metadata(0, 10); + commit_list_size_button->add_item("20"); + commit_list_size_button->set_item_metadata(1, 20); + commit_list_size_button->add_item("30"); + commit_list_size_button->set_item_metadata(2, 30); + commit_list_size_button->connect(SNAME("item_selected"), callable_mp(this, &VersionControlEditorPlugin::_set_commit_list_size)); + commit_list_hbc->add_child(commit_list_size_button); + + commit_list = memnew(Tree); + commit_list->set_h_size_flags(Control::SIZE_EXPAND_FILL); + commit_list->set_v_grow_direction(Control::GrowDirection::GROW_DIRECTION_END); + commit_list->set_custom_minimum_size(Size2(200, 160)); + commit_list->create_item(); + commit_list->set_hide_root(true); + commit_list->set_select_mode(Tree::SELECT_ROW); + commit_list->set_columns(2); // Commit msg, author + commit_list->set_column_custom_minimum_width(0, 40); + commit_list->set_column_custom_minimum_width(1, 20); + commit_list->connect(SNAME("item_selected"), callable_mp(this, &VersionControlEditorPlugin::_load_diff).bind(commit_list)); + version_commit_dock->add_child(commit_list); + + version_commit_dock->add_child(memnew(HSeparator)); + + HBoxContainer *menu_bar = memnew(HBoxContainer); + menu_bar->set_h_size_flags(Control::SIZE_EXPAND_FILL); + menu_bar->set_v_size_flags(Control::SIZE_FILL); + version_commit_dock->add_child(menu_bar); + + branch_select = memnew(OptionButton); + branch_select->set_tooltip_text(TTR("Branches")); + branch_select->set_h_size_flags(Control::SIZE_EXPAND_FILL); + branch_select->connect(SNAME("item_selected"), callable_mp(this, &VersionControlEditorPlugin::_branch_item_selected)); + branch_select->connect(SNAME("pressed"), callable_mp(this, &VersionControlEditorPlugin::_refresh_branch_list)); + menu_bar->add_child(branch_select); + + branch_create_confirm = memnew(AcceptDialog); + branch_create_confirm->set_title(TTR("Create New Branch")); + branch_create_confirm->set_min_size(Size2(400, 100)); + branch_create_confirm->set_hide_on_ok(true); + version_commit_dock->add_child(branch_create_confirm); + + branch_create_ok = branch_create_confirm->get_ok_button(); + branch_create_ok->set_text(TTR("Create")); + branch_create_ok->set_disabled(true); + branch_create_ok->connect(SNAME("pressed"), callable_mp(this, &VersionControlEditorPlugin::_create_branch)); + + branch_remove_confirm = memnew(AcceptDialog); + branch_remove_confirm->set_title(TTR("Remove Branch")); + branch_remove_confirm->add_cancel_button(); + version_commit_dock->add_child(branch_remove_confirm); + + Button *branch_remove_ok = branch_remove_confirm->get_ok_button(); + branch_remove_ok->set_text(TTR("Remove")); + branch_remove_ok->connect(SNAME("pressed"), callable_mp(this, &VersionControlEditorPlugin::_remove_branch)); + + VBoxContainer *branch_create_vbc = memnew(VBoxContainer); + branch_create_vbc->set_alignment(BoxContainer::ALIGNMENT_CENTER); + branch_create_confirm->add_child(branch_create_vbc); + + HBoxContainer *branch_create_hbc = memnew(HBoxContainer); + branch_create_hbc->set_h_size_flags(Control::SIZE_EXPAND_FILL); + branch_create_vbc->add_child(branch_create_hbc); + + Label *branch_create_name_label = memnew(Label); + branch_create_name_label->set_h_size_flags(Control::SIZE_EXPAND_FILL); + branch_create_name_label->set_text(TTR("Branch Name")); + branch_create_hbc->add_child(branch_create_name_label); + + branch_create_name_input = memnew(LineEdit); + branch_create_name_input->set_h_size_flags(Control::SIZE_EXPAND_FILL); + branch_create_name_input->connect(SNAME("text_changed"), callable_mp(this, &VersionControlEditorPlugin::_update_branch_create_button)); + branch_create_hbc->add_child(branch_create_name_input); + + remote_select = memnew(OptionButton); + remote_select->set_tooltip_text(TTR("Remotes")); + remote_select->set_h_size_flags(Control::SIZE_EXPAND_FILL); + remote_select->connect(SNAME("item_selected"), callable_mp(this, &VersionControlEditorPlugin::_remote_selected)); + remote_select->connect(SNAME("pressed"), callable_mp(this, &VersionControlEditorPlugin::_refresh_remote_list)); + menu_bar->add_child(remote_select); + + remote_create_confirm = memnew(AcceptDialog); + remote_create_confirm->set_title(TTR("Create New Remote")); + remote_create_confirm->set_min_size(Size2(400, 100)); + remote_create_confirm->set_hide_on_ok(true); + version_commit_dock->add_child(remote_create_confirm); + + remote_create_ok = remote_create_confirm->get_ok_button(); + remote_create_ok->set_text(TTR("Create")); + remote_create_ok->set_disabled(true); + remote_create_ok->connect(SNAME("pressed"), callable_mp(this, &VersionControlEditorPlugin::_create_remote)); + + remote_remove_confirm = memnew(AcceptDialog); + remote_remove_confirm->set_title(TTR("Remove Remote")); + remote_remove_confirm->add_cancel_button(); + version_commit_dock->add_child(remote_remove_confirm); + + Button *remote_remove_ok = remote_remove_confirm->get_ok_button(); + remote_remove_ok->set_text(TTR("Remove")); + remote_remove_ok->connect(SNAME("pressed"), callable_mp(this, &VersionControlEditorPlugin::_remove_remote)); + + VBoxContainer *remote_create_vbc = memnew(VBoxContainer); + remote_create_vbc->set_alignment(BoxContainer::ALIGNMENT_CENTER); + remote_create_confirm->add_child(remote_create_vbc); + + HBoxContainer *remote_create_name_hbc = memnew(HBoxContainer); + remote_create_name_hbc->set_h_size_flags(Control::SIZE_EXPAND_FILL); + remote_create_vbc->add_child(remote_create_name_hbc); + + Label *remote_create_name_label = memnew(Label); + remote_create_name_label->set_h_size_flags(Control::SIZE_EXPAND_FILL); + remote_create_name_label->set_text(TTR("Remote Name")); + remote_create_name_hbc->add_child(remote_create_name_label); + + remote_create_name_input = memnew(LineEdit); + remote_create_name_input->set_h_size_flags(Control::SIZE_EXPAND_FILL); + remote_create_name_input->connect(SNAME("text_changed"), callable_mp(this, &VersionControlEditorPlugin::_update_remote_create_button)); + remote_create_name_hbc->add_child(remote_create_name_input); + + HBoxContainer *remote_create_hbc = memnew(HBoxContainer); + remote_create_hbc->set_h_size_flags(Control::SIZE_EXPAND_FILL); + remote_create_vbc->add_child(remote_create_hbc); + + Label *remote_create_url_label = memnew(Label); + remote_create_url_label->set_h_size_flags(Control::SIZE_EXPAND_FILL); + remote_create_url_label->set_text(TTR("Remote URL")); + remote_create_hbc->add_child(remote_create_url_label); + + remote_create_url_input = memnew(LineEdit); + remote_create_url_input->set_h_size_flags(Control::SIZE_EXPAND_FILL); + remote_create_url_input->connect(SNAME("text_changed"), callable_mp(this, &VersionControlEditorPlugin::_update_remote_create_button)); + remote_create_hbc->add_child(remote_create_url_input); + + fetch_button = memnew(Button); + fetch_button->set_flat(true); + fetch_button->set_tooltip_text(TTR("Fetch")); + fetch_button->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Reload"), SNAME("EditorIcons"))); + fetch_button->connect(SNAME("pressed"), callable_mp(this, &VersionControlEditorPlugin::_fetch)); + menu_bar->add_child(fetch_button); + + pull_button = memnew(Button); + pull_button->set_flat(true); + pull_button->set_tooltip_text(TTR("Pull")); + pull_button->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("MoveDown"), SNAME("EditorIcons"))); + pull_button->connect(SNAME("pressed"), callable_mp(this, &VersionControlEditorPlugin::_pull)); + menu_bar->add_child(pull_button); + + push_button = memnew(Button); + push_button->set_flat(true); + push_button->set_tooltip_text(TTR("Push")); + push_button->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("MoveUp"), SNAME("EditorIcons"))); + push_button->connect(SNAME("pressed"), callable_mp(this, &VersionControlEditorPlugin::_push)); + menu_bar->add_child(push_button); + + extra_options = memnew(MenuButton); + extra_options->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("GuiTabMenuHl"), SNAME("EditorIcons"))); + extra_options->get_popup()->connect(SNAME("about_to_popup"), callable_mp(this, &VersionControlEditorPlugin::_update_extra_options)); + extra_options->get_popup()->connect(SNAME("id_pressed"), callable_mp(this, &VersionControlEditorPlugin::_extra_option_selected)); + menu_bar->add_child(extra_options); + + extra_options->get_popup()->add_item(TTR("Force Push"), EXTRA_OPTION_FORCE_PUSH); + extra_options->get_popup()->add_separator(); + extra_options->get_popup()->add_item(TTR("Create New Branch"), EXTRA_OPTION_CREATE_BRANCH); + + extra_options_remove_branch_list = memnew(PopupMenu); + extra_options_remove_branch_list->connect(SNAME("id_pressed"), callable_mp(this, &VersionControlEditorPlugin::_popup_branch_remove_confirm)); + extra_options_remove_branch_list->set_name("Remove Branch"); + extra_options->get_popup()->add_child(extra_options_remove_branch_list); + extra_options->get_popup()->add_submenu_item(TTR("Remove Branch"), "Remove Branch"); + + extra_options->get_popup()->add_separator(); + extra_options->get_popup()->add_item(TTR("Create New Remote"), EXTRA_OPTION_CREATE_REMOTE); + + extra_options_remove_remote_list = memnew(PopupMenu); + extra_options_remove_remote_list->connect(SNAME("id_pressed"), callable_mp(this, &VersionControlEditorPlugin::_popup_remote_remove_confirm)); + extra_options_remove_remote_list->set_name("Remove Remote"); + extra_options->get_popup()->add_child(extra_options_remove_remote_list); + extra_options->get_popup()->add_submenu_item(TTR("Remove Remote"), "Remove Remote"); + + change_type_to_strings[EditorVCSInterface::CHANGE_TYPE_NEW] = TTR("New"); + change_type_to_strings[EditorVCSInterface::CHANGE_TYPE_MODIFIED] = TTR("Modified"); + change_type_to_strings[EditorVCSInterface::CHANGE_TYPE_RENAMED] = TTR("Renamed"); + change_type_to_strings[EditorVCSInterface::CHANGE_TYPE_DELETED] = TTR("Deleted"); + change_type_to_strings[EditorVCSInterface::CHANGE_TYPE_TYPECHANGE] = TTR("Typechange"); + change_type_to_strings[EditorVCSInterface::CHANGE_TYPE_UNMERGED] = TTR("Unmerged"); + + change_type_to_color[EditorVCSInterface::CHANGE_TYPE_NEW] = EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("success_color"), SNAME("Editor")); + change_type_to_color[EditorVCSInterface::CHANGE_TYPE_MODIFIED] = EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("warning_color"), SNAME("Editor")); + change_type_to_color[EditorVCSInterface::CHANGE_TYPE_RENAMED] = EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("warning_color"), SNAME("Editor")); + change_type_to_color[EditorVCSInterface::CHANGE_TYPE_DELETED] = EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("error_color"), SNAME("Editor")); + change_type_to_color[EditorVCSInterface::CHANGE_TYPE_TYPECHANGE] = EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("font_color"), SNAME("Editor")); + change_type_to_color[EditorVCSInterface::CHANGE_TYPE_UNMERGED] = EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("warning_color"), SNAME("Editor")); + + change_type_to_icon[EditorVCSInterface::CHANGE_TYPE_NEW] = EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("StatusSuccess"), SNAME("EditorIcons")); + change_type_to_icon[EditorVCSInterface::CHANGE_TYPE_MODIFIED] = EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("StatusWarning"), SNAME("EditorIcons")); + change_type_to_icon[EditorVCSInterface::CHANGE_TYPE_RENAMED] = EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("StatusWarning"), SNAME("EditorIcons")); + change_type_to_icon[EditorVCSInterface::CHANGE_TYPE_TYPECHANGE] = EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("StatusWarning"), SNAME("EditorIcons")); + change_type_to_icon[EditorVCSInterface::CHANGE_TYPE_DELETED] = EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("StatusError"), SNAME("EditorIcons")); + change_type_to_icon[EditorVCSInterface::CHANGE_TYPE_UNMERGED] = EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("StatusWarning"), SNAME("EditorIcons")); + + version_control_dock = memnew(VBoxContainer); version_control_dock->set_v_size_flags(Control::SIZE_EXPAND_FILL); version_control_dock->set_custom_minimum_size(Size2(0, 300) * EDSCALE); version_control_dock->hide(); - diff_vbc = memnew(VBoxContainer); - diff_vbc->set_h_size_flags(HBoxContainer::SIZE_FILL); - diff_vbc->set_v_size_flags(HBoxContainer::SIZE_FILL); - version_control_dock->add_child(diff_vbc); - - diff_hbc = memnew(HBoxContainer); - diff_hbc->set_h_size_flags(HBoxContainer::SIZE_FILL); - diff_vbc->add_child(diff_hbc); - - diff_heading = memnew(Label); - diff_heading->set_text(TTR("Status")); + HBoxContainer *diff_heading = memnew(HBoxContainer); + diff_heading->set_h_size_flags(Control::SIZE_EXPAND_FILL); diff_heading->set_tooltip_text(TTR("View file diffs before committing them to the latest version")); - diff_hbc->add_child(diff_heading); + version_control_dock->add_child(diff_heading); - diff_file_name = memnew(Label); - diff_file_name->set_text(TTR("No file diff is active")); - diff_file_name->set_h_size_flags(Label::SIZE_EXPAND_FILL); - diff_file_name->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_RIGHT); - diff_hbc->add_child(diff_file_name); + diff_title = memnew(Label); + diff_title->set_h_size_flags(Control::SIZE_EXPAND_FILL); + diff_heading->add_child(diff_title); - diff_refresh_button = memnew(Button); - diff_refresh_button->set_tooltip_text(TTR("Detect changes in file diff")); - diff_refresh_button->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Reload"), SNAME("EditorIcons"))); - diff_refresh_button->connect("pressed", callable_mp(this, &VersionControlEditorPlugin::_refresh_file_diff)); - diff_hbc->add_child(diff_refresh_button); + Label *view = memnew(Label); + view->set_text(TTR("View:")); + diff_heading->add_child(view); + + diff_view_type_select = memnew(OptionButton); + diff_view_type_select->add_item(TTR("Split"), DIFF_VIEW_TYPE_SPLIT); + diff_view_type_select->add_item(TTR("Unified"), DIFF_VIEW_TYPE_UNIFIED); + diff_view_type_select->connect(SNAME("item_selected"), callable_mp(this, &VersionControlEditorPlugin::_display_diff)); + diff_heading->add_child(diff_view_type_select); diff = memnew(RichTextLabel); diff->set_h_size_flags(TextEdit::SIZE_EXPAND_FILL); diff->set_v_size_flags(TextEdit::SIZE_EXPAND_FILL); + diff->set_use_bbcode(true); diff->set_selection_enabled(true); - diff_vbc->add_child(diff); + version_control_dock->add_child(diff); + + _update_set_up_warning(""); } VersionControlEditorPlugin::~VersionControlEditorPlugin() { shut_down(); - memdelete(version_control_dock); memdelete(version_commit_dock); + memdelete(version_control_dock); memdelete(version_control_actions); } diff --git a/editor/plugins/version_control_editor_plugin.h b/editor/plugins/version_control_editor_plugin.h index fa721268ba..3340384a92 100644 --- a/editor/plugins/version_control_editor_plugin.h +++ b/editor/plugins/version_control_editor_plugin.h @@ -33,9 +33,12 @@ #include "editor/editor_plugin.h" #include "editor/editor_vcs_interface.h" -#include "scene/gui/box_container.h" +#include "scene/gui/check_button.h" +#include "scene/gui/container.h" +#include "scene/gui/file_dialog.h" +#include "scene/gui/menu_button.h" #include "scene/gui/rich_text_label.h" -#include "scene/gui/split_container.h" +#include "scene/gui/tab_container.h" #include "scene/gui/text_edit.h" #include "scene/gui/tree.h" @@ -43,79 +46,154 @@ class VersionControlEditorPlugin : public EditorPlugin { GDCLASS(VersionControlEditorPlugin, EditorPlugin) public: - enum ChangeType { - CHANGE_TYPE_NEW = 0, - CHANGE_TYPE_MODIFIED = 1, - CHANGE_TYPE_RENAMED = 2, - CHANGE_TYPE_DELETED = 3, - CHANGE_TYPE_TYPECHANGE = 4 + enum ButtonType { + BUTTON_TYPE_OPEN = 0, + BUTTON_TYPE_DISCARD = 1, + }; + + enum DiffViewType { + DIFF_VIEW_TYPE_SPLIT = 0, + DIFF_VIEW_TYPE_UNIFIED = 1, + }; + + enum ExtraOption { + EXTRA_OPTION_FORCE_PUSH, + EXTRA_OPTION_CREATE_BRANCH, + EXTRA_OPTION_CREATE_REMOTE, }; private: static VersionControlEditorPlugin *singleton; - int staged_files_count; - List<StringName> available_addons; + List<StringName> available_plugins; PopupMenu *version_control_actions = nullptr; ConfirmationDialog *metadata_dialog = nullptr; OptionButton *metadata_selection = nullptr; AcceptDialog *set_up_dialog = nullptr; - VBoxContainer *set_up_vbc = nullptr; - HBoxContainer *set_up_hbc = nullptr; - Label *set_up_vcs_label = nullptr; + CheckButton *toggle_vcs_choice = nullptr; OptionButton *set_up_choice = nullptr; - PanelContainer *set_up_init_settings = nullptr; - Button *set_up_init_button = nullptr; - RichTextLabel *set_up_vcs_status = nullptr; - Button *set_up_ok_button = nullptr; - - HashMap<ChangeType, String> change_type_to_strings; - HashMap<ChangeType, Color> change_type_to_color; + LineEdit *project_path_input = nullptr; + Button *select_project_path_button = nullptr; + VBoxContainer *set_up_vbc = nullptr; + VBoxContainer *set_up_settings_vbc = nullptr; + LineEdit *set_up_username = nullptr; + LineEdit *set_up_password = nullptr; + LineEdit *set_up_ssh_public_key_path = nullptr; + LineEdit *set_up_ssh_private_key_path = nullptr; + LineEdit *set_up_ssh_passphrase = nullptr; + FileDialog *set_up_ssh_public_key_file_dialog = nullptr; + FileDialog *set_up_ssh_private_key_file_dialog = nullptr; + Label *set_up_warning_text = nullptr; + + OptionButton *commit_list_size_button = nullptr; + + AcceptDialog *branch_create_confirm = nullptr; + LineEdit *branch_create_name_input = nullptr; + Button *branch_create_ok = nullptr; + + AcceptDialog *remote_create_confirm = nullptr; + LineEdit *remote_create_name_input = nullptr; + LineEdit *remote_create_url_input = nullptr; + Button *remote_create_ok = nullptr; + + HashMap<EditorVCSInterface::ChangeType, String> change_type_to_strings; + HashMap<EditorVCSInterface::ChangeType, Color> change_type_to_color; + HashMap<EditorVCSInterface::ChangeType, Ref<Texture>> change_type_to_icon; VBoxContainer *version_commit_dock = nullptr; - VBoxContainer *commit_box_vbc = nullptr; - HSplitContainer *stage_tools = nullptr; - Tree *stage_files = nullptr; - TreeItem *new_files = nullptr; - TreeItem *modified_files = nullptr; - TreeItem *renamed_files = nullptr; - TreeItem *deleted_files = nullptr; - TreeItem *typechange_files = nullptr; - Label *staging_area_label = nullptr; - HSplitContainer *stage_buttons = nullptr; + Tree *staged_files = nullptr; + Tree *unstaged_files = nullptr; + Tree *commit_list = nullptr; + + OptionButton *branch_select = nullptr; + Button *branch_remove_button = nullptr; + AcceptDialog *branch_remove_confirm = nullptr; + + Button *fetch_button = nullptr; + Button *pull_button = nullptr; + Button *push_button = nullptr; + OptionButton *remote_select = nullptr; + Button *remote_remove_button = nullptr; + AcceptDialog *remote_remove_confirm = nullptr; + MenuButton *extra_options = nullptr; + PopupMenu *extra_options_remove_branch_list = nullptr; + PopupMenu *extra_options_remove_remote_list = nullptr; + + String branch_to_remove; + String remote_to_remove; + Button *stage_all_button = nullptr; - Button *stage_selected_button = nullptr; + Button *unstage_all_button = nullptr; + Button *discard_all_button = nullptr; Button *refresh_button = nullptr; TextEdit *commit_message = nullptr; Button *commit_button = nullptr; - Label *commit_status = nullptr; - PanelContainer *version_control_dock = nullptr; + VBoxContainer *version_control_dock = nullptr; Button *version_control_dock_button = nullptr; - VBoxContainer *diff_vbc = nullptr; - HBoxContainer *diff_hbc = nullptr; - Button *diff_refresh_button = nullptr; - Label *diff_file_name = nullptr; - Label *diff_heading = nullptr; + Label *diff_title = nullptr; RichTextLabel *diff = nullptr; + OptionButton *diff_view_type_select = nullptr; + bool show_commit_diff_header = false; + List<EditorVCSInterface::DiffFile> diff_content; - void _populate_available_vcs_names(); - void _create_vcs_metadata_files(); - void _selected_a_vcs(int p_id); + void _notification(int p_what); void _initialize_vcs(); - void _send_commit_msg(); + void _set_vcs_ui_state(bool p_enabled); + void _set_credentials(); + void _ssh_public_key_selected(String p_path); + void _ssh_private_key_selected(String p_path); + void _populate_available_vcs_names(); + void _update_remotes_list(); + void _update_set_up_warning(String p_new_text); + void _update_opened_tabs(); + void _update_extra_options(); + + bool _load_plugin(String p_name, String p_project_path); + + void _pull(); + void _push(); + void _force_push(); + void _fetch(); + void _commit(); + void _discard_all(); void _refresh_stage_area(); - void _stage_selected(); - void _stage_all(); - void _view_file_diff(); - void _display_file_diff(String p_file_path); - void _refresh_file_diff(); - void _clear_file_diff(); - void _update_stage_status(); - void _update_commit_status(); + void _refresh_branch_list(); + void _set_commit_list_size(int p_index); + void _refresh_commit_list(); + void _refresh_remote_list(); + void _display_diff(int p_idx); + void _move_all(Object *p_tree); + void _load_diff(Object *p_tree); + void _clear_diff(); + int _get_item_count(Tree *p_tree); + void _item_activated(Object *p_tree); + void _create_branch(); + void _create_remote(); + void _update_branch_create_button(String p_new_text); + void _update_remote_create_button(String p_new_text); + void _branch_item_selected(int p_index); + void _remote_selected(int p_index); + void _remove_branch(); + void _remove_remote(); + void _popup_branch_remove_confirm(int p_index); + void _popup_remote_remove_confirm(int p_index); + void _move_item(Tree *p_tree, TreeItem *p_itme); + void _display_diff_split_view(List<EditorVCSInterface::DiffLine> &p_diff_content); + void _display_diff_unified_view(List<EditorVCSInterface::DiffLine> &p_diff_content); + void _discard_file(String p_file_path, EditorVCSInterface::ChangeType p_change); + void _cell_button_pressed(Object *p_item, int p_column, int p_id, int p_mouse_button_index); + void _add_new_item(Tree *p_tree, String p_file_path, EditorVCSInterface::ChangeType p_change); void _update_commit_button(); void _commit_message_gui_input(const Ref<InputEvent> &p_event); + void _extra_option_selected(int p_index); + bool _is_staging_area_empty(); + String _get_date_string_from(int64_t p_unix_timestamp, int64_t p_offset_minutes) const; + void _create_vcs_metadata_files(); + void _popup_file_dialog(Variant p_file_dialog_variant); + void _toggle_vcs_integration(bool p_toggled); + void _project_path_selected(String p_project_path); friend class EditorVCSInterface; @@ -127,25 +205,15 @@ public: void popup_vcs_metadata_dialog(); void popup_vcs_set_up_dialog(const Control *p_gui_base); - void set_version_control_tool_button(Button *p_button) { version_control_dock_button = p_button; } PopupMenu *get_version_control_actions_panel() const { return version_control_actions; } - VBoxContainer *get_version_commit_dock() const { return version_commit_dock; } - PanelContainer *get_version_control_dock() const { return version_control_dock; } - - List<StringName> get_available_vcs_names() const { return available_addons; } - bool is_vcs_initialized() const; - const String get_vcs_name() const; void register_editor(); - void fetch_available_vcs_addon_names(); - void clear_stage_area(); + void fetch_available_vcs_plugin_names(); void shut_down(); VersionControlEditorPlugin(); ~VersionControlEditorPlugin(); }; -VARIANT_ENUM_CAST(VersionControlEditorPlugin::ChangeType); - #endif // VERSION_CONTROL_EDITOR_PLUGIN_H diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp index 83341b3016..2fb8bbe86b 100644 --- a/editor/plugins/visual_shader_editor_plugin.cpp +++ b/editor/plugins/visual_shader_editor_plugin.cpp @@ -6263,7 +6263,7 @@ void VisualShaderNodePortPreview::setup(const Ref<VisualShader> &p_shader, Visua type = p_type; port = p_port; node = p_node; - update(); + queue_redraw(); _shader_changed(); } diff --git a/editor/project_converter_3_to_4.cpp b/editor/project_converter_3_to_4.cpp index 83275a2a7b..dbd2a7555d 100644 --- a/editor/project_converter_3_to_4.cpp +++ b/editor/project_converter_3_to_4.cpp @@ -397,6 +397,7 @@ static const char *gdscript_function_renames[][2] = { { "http_unescape", "uri_decode" }, // String { "import_scene_from_other_importer", "_import_scene" }, //EditorSceneFormatImporter { "instance_set_surface_material", "instance_set_surface_override_material" }, // RenderingServer + { "interpolate", "sample" }, // Curve, Curve2D, Curve3D, Gradient { "intersect_polygons_2d", "intersect_polygons" }, // Geometry2D { "intersect_polyline_with_polygon_2d", "intersect_polyline_with_polygon" }, // Geometry2D { "is_a_parent_of", "is_ancestor_of" }, // Node @@ -526,7 +527,6 @@ static const char *gdscript_function_renames[][2] = { { "set_tangent", "surface_set_tangent" }, // ImmediateGeometry broke SurfaceTool { "set_text_align", "set_text_alignment" }, // Button { "set_timer_process_mode", "set_timer_process_callback" }, // Timer - { "set_tonemap_auto_exposure", "set_tonemap_auto_exposure_enabled" }, // Environment { "set_translation", "set_position" }, // Node3D - this broke GLTFNode which is used rarely { "set_unit_offset", "set_progress_ratio" }, // PathFollow2D, PathFollow3D { "set_uv2", "surface_set_uv2" }, // ImmediateMesh broke Surffacetool @@ -1246,12 +1246,12 @@ static const char *project_settings_renames[][2] = { { "rendering/quality/shading/force_lambert_over_burley.mobile", "rendering/shading/overrides/force_lambert_over_burley.mobile" }, { "rendering/quality/shading/force_vertex_shading", "rendering/shading/overrides/force_vertex_shading" }, { "rendering/quality/shading/force_vertex_shading.mobile", "rendering/shading/overrides/force_vertex_shading.mobile" }, - { "rendering/quality/shadow_atlas/quadrant_0_subdiv", "rendering/shadows/shadow_atlas/quadrant_0_subdiv" }, - { "rendering/quality/shadow_atlas/quadrant_1_subdiv", "rendering/shadows/shadow_atlas/quadrant_1_subdiv" }, - { "rendering/quality/shadow_atlas/quadrant_2_subdiv", "rendering/shadows/shadow_atlas/quadrant_2_subdiv" }, - { "rendering/quality/shadow_atlas/quadrant_3_subdiv", "rendering/shadows/shadow_atlas/quadrant_3_subdiv" }, - { "rendering/quality/shadow_atlas/size", "rendering/shadows/shadow_atlas/size" }, - { "rendering/quality/shadow_atlas/size.mobile", "rendering/shadows/shadow_atlas/size.mobile" }, + { "rendering/quality/shadow_atlas/quadrant_0_subdiv", "rendering/lights_and_shadows/shadow_atlas/quadrant_0_subdiv" }, + { "rendering/quality/shadow_atlas/quadrant_1_subdiv", "rendering/lights_and_shadows/shadow_atlas/quadrant_1_subdiv" }, + { "rendering/quality/shadow_atlas/quadrant_2_subdiv", "rendering/lights_and_shadows/shadow_atlas/quadrant_2_subdiv" }, + { "rendering/quality/shadow_atlas/quadrant_3_subdiv", "rendering/lights_and_shadows/shadow_atlas/quadrant_3_subdiv" }, + { "rendering/quality/shadow_atlas/size", "rendering/lights_and_shadows/shadow_atlas/size" }, + { "rendering/quality/shadow_atlas/size.mobile", "rendering/lights_and_shadows/shadow_atlas/size.mobile" }, { "rendering/vram_compression/import_bptc", "rendering/textures/vram_compression/import_bptc" }, { "rendering/vram_compression/import_etc", "rendering/textures/vram_compression/import_etc" }, { "rendering/vram_compression/import_etc2", "rendering/textures/vram_compression/import_etc2" }, diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp index 9779ce398b..ed8c7b14c8 100644 --- a/editor/project_manager.cpp +++ b/editor/project_manager.cpp @@ -962,12 +962,12 @@ public: switch (p_what) { case NOTIFICATION_MOUSE_ENTER: { hover = true; - update(); + queue_redraw(); } break; case NOTIFICATION_MOUSE_EXIT: { hover = false; - update(); + queue_redraw(); } break; case NOTIFICATION_DRAW: { @@ -1321,7 +1321,7 @@ void ProjectList::update_dock_menu() { } favs_added = 0; } - DisplayServer::get_singleton()->global_menu_add_item("_dock", _projects[i].project_name + " ( " + _projects[i].path + " )", callable_mp(this, &ProjectList::_global_menu_open_project), i); + DisplayServer::get_singleton()->global_menu_add_item("_dock", _projects[i].project_name + " ( " + _projects[i].path + " )", callable_mp(this, &ProjectList::_global_menu_open_project), Callable(), i); total_added++; } } @@ -1682,7 +1682,7 @@ void ProjectList::select_project(int p_index) { _selected_project_paths.clear(); for (int i = 0; i < previous_selected_items.size(); ++i) { - previous_selected_items[i].control->update(); + previous_selected_items[i].control->queue_redraw(); } toggle_select(p_index); @@ -1728,7 +1728,7 @@ void ProjectList::toggle_select(int p_index) { } else { _selected_project_paths.insert(item.path); } - item.control->update(); + item.control->queue_redraw(); } void ProjectList::erase_selected_projects(bool p_delete_project_contents) { @@ -1860,7 +1860,7 @@ void ProjectManager::_notification(int p_what) { case NOTIFICATION_TRANSLATION_CHANGED: case NOTIFICATION_LAYOUT_DIRECTION_CHANGED: { settings_hb->set_anchors_and_offsets_preset(Control::PRESET_TOP_RIGHT); - update(); + queue_redraw(); } break; case NOTIFICATION_ENTER_TREE: { diff --git a/editor/rename_dialog.cpp b/editor/rename_dialog.cpp index 7b4df696b7..300a3d0f05 100644 --- a/editor/rename_dialog.cpp +++ b/editor/rename_dialog.cpp @@ -500,7 +500,7 @@ String RenameDialog::_postprocess(const String &subject) { if (style_id == 1) { // PascalCase to snake_case - result = result.camelcase_to_underscore(true); + result = result.to_snake_case(); result = _regex("_+", result, "_"); } else if (style_id == 2) { @@ -521,7 +521,7 @@ String RenameDialog::_postprocess(const String &subject) { end = start + 1; } buffer += result.substr(end, result.size() - (end + 1)); - result = buffer.replace("_", "").capitalize(); + result = buffer.to_pascal_case(); } } diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp index 3e98c854c5..e2265f2f83 100644 --- a/editor/scene_tree_dock.cpp +++ b/editor/scene_tree_dock.cpp @@ -1237,7 +1237,7 @@ void SceneTreeDock::_notification(int p_what) { if (canvas_item_plugin) { canvas_item_plugin->get_canvas_item_editor()->connect("item_lock_status_changed", Callable(scene_tree, "_update_tree")); canvas_item_plugin->get_canvas_item_editor()->connect("item_group_status_changed", Callable(scene_tree, "_update_tree")); - scene_tree->connect("node_changed", callable_mp((CanvasItem *)canvas_item_plugin->get_canvas_item_editor()->get_viewport_control(), &CanvasItem::update)); + scene_tree->connect("node_changed", callable_mp((CanvasItem *)canvas_item_plugin->get_canvas_item_editor()->get_viewport_control(), &CanvasItem::queue_redraw)); } Node3DEditorPlugin *spatial_editor_plugin = Object::cast_to<Node3DEditorPlugin>(editor_data->get_editor("3D")); @@ -2164,7 +2164,7 @@ void SceneTreeDock::_delete_confirm(bool p_cut) { // hack, force 2d editor viewport to refresh after deletion if (CanvasItemEditor *editor = CanvasItemEditor::get_singleton()) { - editor->get_viewport_control()->update(); + editor->get_viewport_control()->queue_redraw(); } _push_item(nullptr); diff --git a/editor/scene_tree_editor.cpp b/editor/scene_tree_editor.cpp index 00fd0c3aac..c120468ecb 100644 --- a/editor/scene_tree_editor.cpp +++ b/editor/scene_tree_editor.cpp @@ -354,7 +354,7 @@ void SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) { tooltip += "\n\n" + p_node->get_editor_description(); } - item->set_tooltip(0, tooltip); + item->set_tooltip_text(0, tooltip); } else if (p_node != get_scene_node() && !p_node->get_scene_file_path().is_empty() && can_open_instance) { item->add_button(0, get_theme_icon(SNAME("InstanceOptions"), SNAME("EditorIcons")), BUTTON_SUBSCENE, false, TTR("Open in Editor")); @@ -363,7 +363,7 @@ void SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) { tooltip += "\n\n" + p_node->get_editor_description(); } - item->set_tooltip(0, tooltip); + item->set_tooltip_text(0, tooltip); } else { StringName type = EditorNode::get_singleton()->get_object_custom_type_name(p_node); if (type == StringName()) { @@ -375,7 +375,7 @@ void SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) { tooltip += "\n\n" + p_node->get_editor_description(); } - item->set_tooltip(0, tooltip); + item->set_tooltip_text(0, tooltip); } if (can_open_instance && undo_redo.is_valid()) { //Show buttons only when necessary(SceneTreeDock) to avoid crashes @@ -386,10 +386,18 @@ void SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) { Ref<Script> script = p_node->get_script(); if (!script.is_null()) { - item->add_button(0, get_theme_icon(SNAME("Script"), SNAME("EditorIcons")), BUTTON_SCRIPT, false, TTR("Open Script:") + " " + script->get_path()); + String additional_notes; + // Can't set tooltip after adding button, need to do it before. + if (script->is_tool()) { + additional_notes += "\n" + TTR("This script is currently running in the editor."); + } + item->add_button(0, get_theme_icon(SNAME("Script"), SNAME("EditorIcons")), BUTTON_SCRIPT, false, TTR("Open Script:") + " " + script->get_path() + additional_notes); if (EditorNode::get_singleton()->get_object_custom_type_base(p_node) == script) { item->set_button_color(0, item->get_button_count(0) - 1, Color(1, 1, 1, 0.5)); } + if (script->is_tool()) { + item->set_button_color(0, item->get_button_count(0) - 1, get_theme_color(SNAME("accent_color"), SNAME("Editor"))); + } } if (p_node->is_class("CanvasItem")) { @@ -505,7 +513,7 @@ void SceneTreeEditor::_node_visibility_changed(Node *p_node) { if (p_node->is_class("CanvasItem") || p_node->is_class("CanvasLayer") || p_node->is_class("Window")) { visible = p_node->call("is_visible"); - CanvasItemEditor::get_singleton()->get_viewport_control()->update(); + CanvasItemEditor::get_singleton()->get_viewport_control()->queue_redraw(); } else if (p_node->is_class("Node3D")) { visible = p_node->call("is_visible"); } diff --git a/editor/script_create_dialog.cpp b/editor/script_create_dialog.cpp index e09862263c..7d065b4920 100644 --- a/editor/script_create_dialog.cpp +++ b/editor/script_create_dialog.cpp @@ -898,7 +898,7 @@ ScriptLanguage::ScriptTemplate ScriptCreateDialog::_parse_template(const ScriptL // Get name from file name if no name in meta information if (script_template.name == String()) { - script_template.name = p_filename.get_basename().replace("_", " ").capitalize(); + script_template.name = p_filename.get_basename().capitalize(); } return script_template; diff --git a/editor/shader_create_dialog.cpp b/editor/shader_create_dialog.cpp index 8c4a231e8a..522fd7c645 100644 --- a/editor/shader_create_dialog.cpp +++ b/editor/shader_create_dialog.cpp @@ -161,7 +161,7 @@ void ShaderCreateDialog::_create_new() { shader = text_shader; StringBuilder code; - code += vformat("shader_type %s;\n", mode_menu->get_text().replace(" ", "").camelcase_to_underscore()); + code += vformat("shader_type %s;\n", mode_menu->get_text().to_snake_case()); if (current_template == 0) { // Default template. code += "\n"; diff --git a/editor/translations/extract.py b/editor/translations/extract.py index 7f3da400e7..07026baee2 100755 --- a/editor/translations/extract.py +++ b/editor/translations/extract.py @@ -139,7 +139,7 @@ theme_property_patterns = { } -# See String::camelcase_to_underscore(). +# See String::_camelcase_to_underscore(). capitalize_re = re.compile(r"(?<=\D)(?=\d)|(?<=\d)(?=\D([a-z]|\d))") |