summaryrefslogtreecommitdiffstats
path: root/editor/export/project_export.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'editor/export/project_export.cpp')
-rw-r--r--editor/export/project_export.cpp189
1 files changed, 186 insertions, 3 deletions
diff --git a/editor/export/project_export.cpp b/editor/export/project_export.cpp
index be9e0f78ec..f9137082d7 100644
--- a/editor/export/project_export.cpp
+++ b/editor/export/project_export.cpp
@@ -102,11 +102,13 @@ void ProjectExportDialog::_notification(int p_what) {
case NOTIFICATION_THEME_CHANGED: {
duplicate_preset->set_icon(presets->get_editor_theme_icon(SNAME("Duplicate")));
delete_preset->set_icon(presets->get_editor_theme_icon(SNAME("Remove")));
+ patch_add_btn->set_icon(get_editor_theme_icon(SNAME("Add")));
} break;
case NOTIFICATION_READY: {
duplicate_preset->set_icon(presets->get_editor_theme_icon(SNAME("Duplicate")));
delete_preset->set_icon(presets->get_editor_theme_icon(SNAME("Remove")));
+ patch_add_btn->set_icon(get_editor_theme_icon(SNAME("Add")));
connect(SceneStringName(confirmed), callable_mp(this, &ProjectExportDialog::_export_pck_zip));
_update_export_all();
} break;
@@ -248,6 +250,7 @@ void ProjectExportDialog::_edit_preset(int p_index) {
duplicate_preset->set_disabled(true);
delete_preset->set_disabled(true);
sections->hide();
+ patches->clear();
export_error->hide();
export_templates_error->hide();
return;
@@ -292,6 +295,21 @@ void ProjectExportDialog::_edit_preset(int p_index) {
exclude_filters->set_text(current->get_exclude_filter());
server_strip_message->set_visible(current->get_export_filter() == EditorExportPreset::EXPORT_CUSTOMIZED);
+ patches->clear();
+ TreeItem *patch_root = patches->create_item();
+ Vector<String> patch_list = current->get_patches();
+ for (int i = 0; i < patch_list.size(); i++) {
+ TreeItem *patch = patches->create_item(patch_root);
+ const String &patch_path = patch_list[i];
+ patch->set_cell_mode(0, TreeItem::CELL_MODE_STRING);
+ patch->set_editable(0, true);
+ patch->set_text(0, patch_path.get_file());
+ patch->set_tooltip_text(0, patch_path);
+ patch->set_metadata(0, i);
+ patch->add_button(0, get_editor_theme_icon(SNAME("Remove")), 0);
+ patch->add_button(0, get_editor_theme_icon(SNAME("FileBrowse")), 1);
+ }
+
_fill_resource_tree();
bool needs_templates;
@@ -664,6 +682,7 @@ void ProjectExportDialog::_duplicate_preset() {
preset->set_export_filter(current->get_export_filter());
preset->set_include_filter(current->get_include_filter());
preset->set_exclude_filter(current->get_exclude_filter());
+ preset->set_patches(current->get_patches());
preset->set_custom_features(current->get_custom_features());
for (const KeyValue<StringName, Variant> &E : current->get_values()) {
@@ -720,8 +739,22 @@ Variant ProjectExportDialog::get_drag_data_fw(const Point2 &p_point, Control *p_
return d;
}
- }
+ } else if (p_from == patches) {
+ TreeItem *item = patches->get_item_at_position(p_point);
+
+ if (item) {
+ int item_metadata = item->get_metadata(0);
+ Dictionary d;
+ d["type"] = "export_patch";
+ d["patch"] = item_metadata;
+ Label *label = memnew(Label);
+ label->set_text(item->get_text(0));
+ patches->set_drag_preview(label);
+
+ return d;
+ }
+ }
return Variant();
}
@@ -735,6 +768,18 @@ bool ProjectExportDialog::can_drop_data_fw(const Point2 &p_point, const Variant
if (presets->get_item_at_position(p_point, true) < 0 && !presets->is_pos_at_end_of_items(p_point)) {
return false;
}
+ } else if (p_from == patches) {
+ Dictionary d = p_data;
+ if (d.get("type", "") != "export_patch") {
+ return false;
+ }
+
+ TreeItem *item = patches->get_item_at_position(p_point);
+ if (!item) {
+ return false;
+ }
+
+ patches->set_drop_mode_flags(Tree::DROP_MODE_INBETWEEN);
}
return true;
@@ -771,6 +816,31 @@ void ProjectExportDialog::drop_data_fw(const Point2 &p_point, const Variant &p_d
} else {
_edit_preset(presets->get_item_count() - 1);
}
+ } else if (p_from == patches) {
+ Dictionary d = p_data;
+ int from_pos = d["patch"];
+
+ TreeItem *item = patches->get_item_at_position(p_point);
+ if (!item) {
+ return;
+ }
+
+ int to_pos = item->get_metadata(0);
+
+ if (patches->get_drop_section_at_position(p_point) > 0) {
+ to_pos++;
+ }
+
+ if (to_pos > from_pos) {
+ to_pos--;
+ }
+
+ Ref<EditorExportPreset> preset = get_current_preset();
+ String patch = preset->get_patch(from_pos);
+ preset->remove_patch(from_pos);
+ preset->add_patch(patch, to_pos);
+
+ _update_current_preset();
}
}
@@ -1026,6 +1096,75 @@ void ProjectExportDialog::_set_file_export_mode(int p_id) {
_propagate_file_export_mode(include_files->get_root(), EditorExportPreset::MODE_FILE_NOT_CUSTOMIZED);
}
+void ProjectExportDialog::_patch_tree_button_clicked(Object *p_item, int p_column, int p_id, int p_mouse_button_index) {
+ TreeItem *ti = Object::cast_to<TreeItem>(p_item);
+
+ patch_index = ti->get_metadata(0);
+
+ Ref<EditorExportPreset> current = get_current_preset();
+ ERR_FAIL_COND(current.is_null());
+
+ if (p_id == 0) {
+ Vector<String> preset_patches = current->get_patches();
+ ERR_FAIL_INDEX(patch_index, preset_patches.size());
+ patch_erase->set_text(vformat(TTR("Delete patch '%s' from list?"), preset_patches[patch_index].get_file()));
+ patch_erase->popup_centered();
+ } else {
+ patch_dialog->popup_file_dialog();
+ }
+}
+
+void ProjectExportDialog::_patch_tree_item_edited() {
+ TreeItem *item = patches->get_edited();
+ if (!item) {
+ return;
+ }
+
+ Ref<EditorExportPreset> current = get_current_preset();
+ ERR_FAIL_COND(current.is_null());
+
+ int index = item->get_metadata(0);
+ String patch_path = item->get_text(0);
+
+ current->set_patch(index, patch_path);
+ item->set_tooltip_text(0, patch_path);
+}
+
+void ProjectExportDialog::_patch_file_selected(const String &p_path) {
+ Ref<EditorExportPreset> current = get_current_preset();
+ ERR_FAIL_COND(current.is_null());
+
+ String relative_path = ProjectSettings::get_singleton()->get_resource_path().path_to_file(p_path);
+
+ Vector<String> preset_patches = current->get_patches();
+ if (patch_index >= preset_patches.size()) {
+ current->add_patch(relative_path);
+ } else {
+ current->set_patch(patch_index, relative_path);
+ }
+
+ _update_current_preset();
+}
+
+void ProjectExportDialog::_patch_delete_confirmed() {
+ Ref<EditorExportPreset> current = get_current_preset();
+ ERR_FAIL_COND(current.is_null());
+
+ Vector<String> preset_patches = current->get_patches();
+ if (patch_index < preset_patches.size()) {
+ current->remove_patch(patch_index);
+ _update_current_preset();
+ }
+}
+
+void ProjectExportDialog::_patch_add_pack_pressed() {
+ Ref<EditorExportPreset> current = get_current_preset();
+ ERR_FAIL_COND(current.is_null());
+
+ patch_index = current->get_patches().size();
+ patch_dialog->popup_file_dialog();
+}
+
void ProjectExportDialog::_export_pck_zip() {
Ref<EditorExportPreset> current = get_current_preset();
ERR_FAIL_COND(current.is_null());
@@ -1044,11 +1183,20 @@ void ProjectExportDialog::_export_pck_zip_selected(const String &p_path) {
const Dictionary &fd_option = export_pck_zip->get_selected_options();
bool export_debug = fd_option.get(TTR("Export With Debug"), true);
+ bool export_as_patch = fd_option.get(TTR("Export As Patch"), true);
if (p_path.ends_with(".zip")) {
- platform->export_zip(current, export_debug, p_path);
+ if (export_as_patch) {
+ platform->export_zip_patch(current, export_debug, p_path);
+ } else {
+ platform->export_zip(current, export_debug, p_path);
+ }
} else if (p_path.ends_with(".pck")) {
- platform->export_pack(current, export_debug, p_path);
+ if (export_as_patch) {
+ platform->export_pack_patch(current, export_debug, p_path);
+ } else {
+ platform->export_pack(current, export_debug, p_path);
+ }
} else {
ERR_FAIL_MSG("Path must end with .pck or .zip");
}
@@ -1386,6 +1534,40 @@ ProjectExportDialog::ProjectExportDialog() {
exclude_filters);
exclude_filters->connect(SceneStringName(text_changed), callable_mp(this, &ProjectExportDialog::_filter_changed));
+ // Patch packages.
+
+ VBoxContainer *patch_vb = memnew(VBoxContainer);
+ sections->add_child(patch_vb);
+ patch_vb->set_name(TTR("Patches"));
+
+ patches = memnew(Tree);
+ patches->set_v_size_flags(Control::SIZE_EXPAND_FILL);
+ patches->set_hide_root(true);
+ patches->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);
+ patches->connect("button_clicked", callable_mp(this, &ProjectExportDialog::_patch_tree_button_clicked));
+ patches->connect("item_edited", callable_mp(this, &ProjectExportDialog::_patch_tree_item_edited));
+ SET_DRAG_FORWARDING_GCD(patches, ProjectExportDialog);
+ patches->set_edit_checkbox_cell_only_when_checkbox_is_pressed(true);
+ patch_vb->add_margin_child(TTR("Base Packs:"), patches, true);
+
+ patch_dialog = memnew(EditorFileDialog);
+ patch_dialog->add_filter("*.pck", TTR("Godot Project Pack"));
+ patch_dialog->set_access(EditorFileDialog::ACCESS_FILESYSTEM);
+ patch_dialog->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_FILE);
+ patch_dialog->connect("file_selected", callable_mp(this, &ProjectExportDialog::_patch_file_selected));
+ add_child(patch_dialog);
+
+ patch_erase = memnew(ConfirmationDialog);
+ patch_erase->set_ok_button_text(TTR("Delete"));
+ patch_erase->connect(SceneStringName(confirmed), callable_mp(this, &ProjectExportDialog::_patch_delete_confirmed));
+ add_child(patch_erase);
+
+ patch_add_btn = memnew(Button);
+ patch_add_btn->set_text(TTR("Add Pack"));
+ patch_add_btn->set_h_size_flags(Control::SIZE_SHRINK_CENTER);
+ patch_add_btn->connect(SceneStringName(pressed), callable_mp(this, &ProjectExportDialog::_patch_add_pack_pressed));
+ patch_vb->add_child(patch_add_btn);
+
// Feature tags.
VBoxContainer *feature_vb = memnew(VBoxContainer);
@@ -1569,6 +1751,7 @@ ProjectExportDialog::ProjectExportDialog() {
export_project->add_option(TTR("Export With Debug"), Vector<String>(), true);
export_pck_zip->add_option(TTR("Export With Debug"), Vector<String>(), true);
+ export_pck_zip->add_option(TTR("Export As Patch"), Vector<String>(), true);
set_hide_on_ok(false);