@@ -65,6 +65,12 @@ void LocalizationEditor::_notification(int p_what) {
6565 _update_pot_file_extensions ();
6666 pot_generate_dialog->add_filter (" *.pot" );
6767 } break ;
68+
69+ case NOTIFICATION_DRAG_END: {
70+ for (Tree *tree : trees) {
71+ tree->set_drop_mode_flags (Tree::DROP_MODE_DISABLED);
72+ }
73+ } break ;
6874 }
6975}
7076
@@ -503,6 +509,89 @@ void LocalizationEditor::_filesystem_file_removed(const String &p_file) {
503509 }
504510}
505511
512+ Variant LocalizationEditor::get_drag_data_fw (const Point2 &p_point, Control *p_from) {
513+ Tree *tree = Object::cast_to<Tree>(p_from);
514+ ERR_FAIL_COND_V (trees.find (tree) == -1 , Variant ());
515+
516+ if (tree->get_button_id_at_position (p_point) != -1 ) {
517+ return Variant ();
518+ }
519+
520+ TreeItem *selected = tree->get_next_selected (nullptr );
521+ if (!selected) {
522+ return Variant ();
523+ }
524+ tree->set_drop_mode_flags (Tree::DROP_MODE_INBETWEEN);
525+
526+ Label *preview = memnew (Label);
527+ preview->set_text (selected->get_text (0 ));
528+ set_drag_preview (preview);
529+
530+ Dictionary drag_data;
531+ drag_data[" type" ] = tree_data_types[tree];
532+ drag_data[" item" ] = selected;
533+
534+ return drag_data;
535+ }
536+
537+ bool LocalizationEditor::can_drop_data_fw (const Point2 &p_point, const Variant &p_data, Control *p_from) const {
538+ Tree *tree = Object::cast_to<Tree>(p_from);
539+ ERR_FAIL_COND_V (trees.find (tree) == -1 , false );
540+
541+ Dictionary drop_data = p_data;
542+ return drop_data.get (" type" , " " ) == tree_data_types[tree];
543+ }
544+
545+ void LocalizationEditor::drop_data_fw (const Point2 &p_point, const Variant &p_data, Control *p_from) {
546+ Tree *tree = Object::cast_to<Tree>(p_from);
547+ ERR_FAIL_COND (trees.find (tree) == -1 );
548+
549+ if (!can_drop_data_fw (p_point, p_data, p_from)) {
550+ return ;
551+ }
552+
553+ TreeItem *item = tree->get_item_at_position (p_point);
554+ if (!item) {
555+ return ;
556+ }
557+ int section = MAX (tree->get_drop_section_at_position (p_point), 0 );
558+ Dictionary drop_data = p_data;
559+
560+ TreeItem *from = Object::cast_to<TreeItem>(drop_data[" item" ]);
561+ if (item == from) {
562+ return ;
563+ }
564+
565+ const StringName &setting = tree_settings[tree];
566+ PackedStringArray setting_value = GLOBAL_GET (setting);
567+ const PackedStringArray original_setting_value = setting_value;
568+ const int index_from = from->get_metadata (0 );
569+ const String path = setting_value[index_from];
570+
571+ int target_index = item->get_metadata (0 );
572+ target_index = MAX (target_index + section, 0 );
573+ if (target_index > index_from) {
574+ target_index -= 1 ; // Account for item being removed.
575+ }
576+
577+ if (target_index == index_from) {
578+ return ;
579+ }
580+
581+ setting_value.remove_at (index_from);
582+ setting_value.insert (target_index, path);
583+
584+ EditorUndoRedoManager *ur_man = EditorUndoRedoManager::get_singleton ();
585+ ur_man->create_action (TTR (" Rearrange Localization Items" ));
586+ ur_man->add_do_method (ProjectSettings::get_singleton (), " set" , setting, setting_value);
587+ ur_man->add_do_method (ProjectSettings::get_singleton (), " save" );
588+ ur_man->add_do_method (this , " update_translations" );
589+ ur_man->add_undo_method (ProjectSettings::get_singleton (), " set" , setting, original_setting_value);
590+ ur_man->add_undo_method (ProjectSettings::get_singleton (), " save" );
591+ ur_man->add_undo_method (this , " update_translations" );
592+ ur_man->commit_action ();
593+ }
594+
506595void LocalizationEditor::update_translations () {
507596 if (updating_translations) {
508597 return ;
@@ -652,6 +741,9 @@ LocalizationEditor::LocalizationEditor() {
652741 translation_list = memnew (Tree);
653742 translation_list->set_v_size_flags (Control::SIZE_EXPAND_FILL);
654743 tmc->add_child (translation_list);
744+ trees.push_back (translation_list);
745+ tree_data_types[translation_list] = " localization_editor_translation_item" ;
746+ tree_settings[translation_list] = " internationalization/locale/translations" ;
655747
656748 locale_select = memnew (EditorLocaleDialog);
657749 locale_select->connect (" locale_selected" , callable_mp (this , &LocalizationEditor::_translation_res_option_selected));
@@ -755,6 +847,9 @@ LocalizationEditor::LocalizationEditor() {
755847 translation_pot_list = memnew (Tree);
756848 translation_pot_list->set_v_size_flags (Control::SIZE_EXPAND_FILL);
757849 tvb->add_child (translation_pot_list);
850+ trees.push_back (translation_pot_list);
851+ tree_data_types[translation_pot_list] = " localization_editor_pot_item" ;
852+ tree_settings[translation_pot_list] = " internationalization/locale/translations_pot_files" ;
758853
759854 translation_pot_add_builtin = memnew (CheckBox (TTRC (" Add Built-in Strings to POT" )));
760855 translation_pot_add_builtin->set_tooltip_text (TTRC (" Add strings from built-in components such as certain Control nodes." ));
@@ -772,4 +867,8 @@ LocalizationEditor::LocalizationEditor() {
772867 pot_file_open_dialog->connect (" files_selected" , callable_mp (this , &LocalizationEditor::_pot_add));
773868 add_child (pot_file_open_dialog);
774869 }
870+
871+ for (Tree *tree : trees) {
872+ SET_DRAG_FORWARDING_GCD (tree, LocalizationEditor);
873+ }
775874}
0 commit comments