diff --git a/source/blender/editors/io/CMakeLists.txt b/source/blender/editors/io/CMakeLists.txt index 217e57452e2..e98be6c35fc 100644 --- a/source/blender/editors/io/CMakeLists.txt +++ b/source/blender/editors/io/CMakeLists.txt @@ -36,9 +36,11 @@ set(SRC io_gpencil_utils.cc io_obj.cc io_ops.cc + io_ops_dropbox.cc io_ply_ops.cc io_stl_ops.cc io_usd.cc + io_utils.cc io_alembic.hh io_cache.hh @@ -46,9 +48,11 @@ set(SRC io_gpencil.hh io_obj.hh io_ops.h + io_ops_dropbox.h io_ply_ops.hh io_stl_ops.hh io_usd.hh + io_utils.hh ) set(LIB diff --git a/source/blender/editors/io/io_obj.cc b/source/blender/editors/io/io_obj.cc index 5b7b0f5c1b7..247857d4a2a 100644 --- a/source/blender/editors/io/io_obj.cc +++ b/source/blender/editors/io/io_obj.cc @@ -40,6 +40,8 @@ # include "IO_path_util_types.h" # include "IO_wavefront_obj.h" +# include "io_utils.hh" + # include "io_obj.hh" static const EnumPropertyItem io_obj_export_evaluation_mode[] = { @@ -373,12 +375,6 @@ void WM_OT_obj_export(wmOperatorType *ot) RNA_def_property_flag(prop, PROP_HIDDEN); } -static int wm_obj_import_invoke(bContext *C, wmOperator *op, const wmEvent * /*event*/) -{ - WM_event_add_fileselect(C, op); - return OPERATOR_RUNNING_MODAL; -} - static int wm_obj_import_exec(bContext *C, wmOperator *op) { OBJImportParams import_params{}; @@ -460,6 +456,7 @@ static void wm_obj_import_draw(bContext *C, wmOperator *op) PointerRNA ptr; wmWindowManager *wm = CTX_wm_manager(C); RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr); + files_drop_label_draw(C, op, ICON_FILE_3D, ".obj"); ui_obj_import_settings(op->layout, &ptr); } @@ -470,9 +467,9 @@ void WM_OT_obj_import(wmOperatorType *ot) ot->name = "Import Wavefront OBJ"; ot->description = "Load a Wavefront OBJ scene"; ot->idname = "WM_OT_obj_import"; - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_PRESET; + ot->flag = OPTYPE_UNDO | OPTYPE_PRESET; - ot->invoke = wm_obj_import_invoke; + ot->invoke = wm_io_import_invoke; ot->exec = wm_obj_import_exec; ot->poll = WM_operator_winactive; ot->ui = wm_obj_import_draw; @@ -486,6 +483,8 @@ void WM_OT_obj_import(wmOperatorType *ot) FILE_DEFAULTDISPLAY, FILE_SORT_DEFAULT); + skip_save_import_paths_props(ot, WM_FILESEL_FILEPATH | WM_FILESEL_DIRECTORY | WM_FILESEL_FILES); + RNA_def_float( ot->srna, "global_scale", diff --git a/source/blender/editors/io/io_ops_dropbox.cc b/source/blender/editors/io/io_ops_dropbox.cc new file mode 100644 index 00000000000..dc01602c196 --- /dev/null +++ b/source/blender/editors/io/io_ops_dropbox.cc @@ -0,0 +1,59 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include "BLI_listbase.h" +#include "BLI_path_util.h" + +#include "DNA_space_types.h" + +#include "RNA_access.h" +#include "RNA_define.h" + +#include "WM_api.h" + +#include "io_ops_dropbox.h" + +void files_drop_copy(bContext * /* C */, wmDrag *drag, wmDropBox *drop) +{ + RNA_string_set(drop->ptr, "filepath", WM_drag_get_path(drag)); + + if (!RNA_struct_find_property(drop->ptr, "directory")) { + return; + } + + // TODO(@guishe): Add support for multiple drag&drop files import + char dir[FILE_MAX], file[FILE_MAX]; + BLI_path_split_dir_file(WM_drag_get_path(drag), dir, sizeof(dir), file, sizeof(file)); + + RNA_string_set(drop->ptr, "directory", dir); + + PointerRNA itemptr{}; + RNA_collection_clear(drop->ptr, "files"); + RNA_collection_add(drop->ptr, "files", &itemptr); + RNA_string_set(&itemptr, "name", file); +} + +template +void add_drag_path_dropbox(ListBase *lb, const char *operator_name) +{ + auto poll = [](bContext * /*C*/, wmDrag *drag, const wmEvent * /*event*/) { + if (drag->type == WM_DRAG_PATH) { + const eFileSel_File_Types file_type = eFileSel_File_Types(WM_drag_get_path_file_type(drag)); + if (file_type == file_t && BLI_path_extension_check(WM_drag_get_path(drag), ext_t)) { + return true; + } + } + return false; + }; + + WM_dropbox_add(lb, operator_name, poll, files_drop_copy, nullptr, nullptr); +} + +void ED_dropboxes_io(void) +{ + ListBase *lb = WM_dropboxmap_find("Window", 0, 0); + +#ifdef WITH_IO_WAVEFRONT_OBJ + static const char obj_ext[] = ".obj"; + add_drag_path_dropbox(lb, "WM_OT_obj_import"); +#endif +} diff --git a/source/blender/editors/io/io_ops_dropbox.h b/source/blender/editors/io/io_ops_dropbox.h new file mode 100644 index 00000000000..cc4de72a50f --- /dev/null +++ b/source/blender/editors/io/io_ops_dropbox.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +void ED_dropboxes_io(void); + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/editors/io/io_utils.cc b/source/blender/editors/io/io_utils.cc new file mode 100644 index 00000000000..c2b27eb85c3 --- /dev/null +++ b/source/blender/editors/io/io_utils.cc @@ -0,0 +1,85 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#if defined(WITH_COLLADA) || defined(WITH_IO_GPENCIL) || defined(WITH_IO_WAVEFRONT_OBJ) || \ + defined(WITH_IO_PLY) || defined(WITH_IO_STL) || defined(WITH_USD) + +# include "BKE_context.h" + +# include "BLI_path_util.h" +# include "BLI_string.h" +# include "BLI_utildefines.h" + +# include "BLT_translation.h" + +# include "DNA_space_types.h" + +# include "ED_fileselect.h" + +# include "RNA_access.h" +# include "RNA_define.h" + +# include "UI_interface.h" + +# include "WM_api.h" + +# include "io_utils.hh" + +int wm_io_import_invoke(bContext *C, wmOperator *op, const wmEvent * /* event */) +{ + char filepath[FILE_MAX]; + RNA_string_get(op->ptr, "filepath", filepath); + + if (filepath[0]) { + return WM_operator_props_dialog_popup(C, op, 300); + } + + WM_event_add_fileselect(C, op); + return OPERATOR_RUNNING_MODAL; +} + +void skip_save_import_paths_props(wmOperatorType *ot, const eFileSel_Flag flag) +{ + PropertyRNA *prop; + if (flag & WM_FILESEL_FILEPATH) { + prop = RNA_struct_type_find_property(ot->srna, "filepath"); + RNA_def_property_flag(prop, PROP_SKIP_SAVE); + } + if (flag & WM_FILESEL_FILENAME) { + prop = RNA_struct_type_find_property(ot->srna, "filename"); + RNA_def_property_flag(prop, PROP_SKIP_SAVE); + } + if (flag & WM_FILESEL_DIRECTORY) { + prop = RNA_struct_type_find_property(ot->srna, "directory"); + RNA_def_property_flag(prop, PROP_SKIP_SAVE); + } + if (flag & WM_FILESEL_FILES) { + prop = RNA_struct_type_find_property(ot->srna, "files"); + RNA_def_property_flag(prop, PROP_SKIP_SAVE); + } + if (flag & WM_FILESEL_RELPATH) { + prop = RNA_struct_type_find_property(ot->srna, "relative_path"); + RNA_def_property_flag(prop, PROP_SKIP_SAVE); + } +} + +void files_drop_label_draw(bContext *C, wmOperator *op, int icon, const char *extension) +{ + ScrArea *area = CTX_wm_area(C); + + if (area->spacetype == SPACE_FILE) { + return; + } + + char label[FILE_MAX]; + RNA_string_get(op->ptr, "filepath", label); + + if (RNA_struct_find_property(op->ptr, "directory") && + RNA_collection_length(op->ptr, "files") > 1) { + sprintf(label, "%d %s files dropped.", RNA_collection_length(op->ptr, "files"), extension); + } + + uiLayout *box = uiLayoutBox(op->layout); + uiItemL(box, label, icon); +} + +#endif diff --git a/source/blender/editors/io/io_utils.hh b/source/blender/editors/io/io_utils.hh new file mode 100644 index 00000000000..a516e02f36e --- /dev/null +++ b/source/blender/editors/io/io_utils.hh @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#pragma once + +#if defined(WITH_COLLADA) || defined(WITH_IO_GPENCIL) || defined(WITH_IO_WAVEFRONT_OBJ) || \ + defined(WITH_IO_PLY) || defined(WITH_IO_STL) || defined(WITH_USD) + +# include "WM_types.h" + +struct wmOperator; +struct wmOperatorType; +struct wmDrag; +struct wmDropBox; + +int wm_io_import_invoke(bContext *C, wmOperator *op, const wmEvent *event); +void skip_save_import_paths_props(wmOperatorType *ot, const eFileSel_Flag flag); +void files_drop_label_draw(bContext *C, wmOperator *op, int icon, const char *extension); + +#endif diff --git a/source/blender/editors/space_api/spacetypes.c b/source/blender/editors/space_api/spacetypes.c index 4a572215358..773ef9950ff 100644 --- a/source/blender/editors/space_api/spacetypes.c +++ b/source/blender/editors/space_api/spacetypes.c @@ -59,6 +59,7 @@ #include "ED_uvedit.h" #include "io_ops.h" +#include "io_ops_dropbox.h" void ED_spacetypes_init(void) { @@ -115,6 +116,7 @@ void ED_spacetypes_init(void) ED_operatortypes_render(); ED_operatortypes_mask(); ED_operatortypes_io(); + ED_dropboxes_io(); ED_operatortypes_edutils(); ED_operatortypes_view2d();