WIP: Experiment: Drop import operator helper and file drop type #111242
|
@ -3499,82 +3499,92 @@ class WM_OT_drop_blend_file(Operator):
|
|||
col.operator("wm.append", text="Append...", icon='APPEND_BLEND').filepath = self.filepath
|
||||
|
||||
|
||||
class WM_FDT_alembic(bpy.types.FileDrop):
|
||||
bl_space_type = "VIEW_3D"
|
||||
bl_idname = "WM_FDT_alembic"
|
||||
bl_operator = "WM_OT_alembic_import"
|
||||
class WM_FH_alembic(bpy.types.FileHandler):
|
||||
bl_idname = "WM_FH_alembic"
|
||||
bl_label = "alembic"
|
||||
bl_import_operator = "WM_OT_alembic_import"
|
||||
bl_extensions = [{"name": ".abc"}, {"name": ".abc"}, {"name": ".abc"}]
|
||||
|
||||
@classmethod
|
||||
def poll_extension(cls, context, extension):
|
||||
return extension == ".abc"
|
||||
def poll(cls, context):
|
||||
return context.area.type == "VIEW_3D"
|
||||
|
||||
|
||||
class WM_FDT_collada(bpy.types.FileDrop):
|
||||
bl_space_type = "VIEW_3D"
|
||||
bl_idname = "WM_FDT_collada"
|
||||
bl_operator = "WM_OT_collada_import"
|
||||
class WM_FH_collada(bpy.types.FileHandler):
|
||||
bl_idname = "WM_FH_collada"
|
||||
bl_label = "collada"
|
||||
bl_import_operator = "WM_OT_collada_import"
|
||||
bl_extensions = [{"name": ".dae"}]
|
||||
|
||||
@classmethod
|
||||
def poll_extension(cls, context, extension):
|
||||
return extension == ".dae"
|
||||
def poll(cls, context):
|
||||
return context.area.type == "VIEW_3D"
|
||||
|
||||
|
||||
class WM_FDT_gpencil(bpy.types.FileDrop):
|
||||
bl_space_type = "VIEW_3D"
|
||||
bl_idname = "WM_FDT_gpencil"
|
||||
bl_operator = "WM_OT_gpencil_import_svg"
|
||||
class WM_FH_gpencil(bpy.types.FileHandler):
|
||||
bl_idname = "WM_FH_gpencil"
|
||||
bl_label = "gpencil"
|
||||
bl_import_operator = "WM_OT_gpencil_import_svg"
|
||||
bl_extensions = [{"name": ".svg"}]
|
||||
|
||||
@classmethod
|
||||
def poll_extension(cls, context, extension):
|
||||
return extension == ".svg"
|
||||
def poll(cls, context):
|
||||
return context.area.type == "VIEW_3D"
|
||||
|
||||
|
||||
class WM_FDT_obj(bpy.types.FileDrop):
|
||||
bl_space_type = "VIEW_3D"
|
||||
bl_idname = "WM_FDT_obj"
|
||||
bl_operator = "WM_OT_obj_import"
|
||||
class WM_FH_obj(bpy.types.FileHandler):
|
||||
bl_idname = "WM_FH_obj"
|
||||
bl_label = "obj"
|
||||
bl_import_operator = "WM_OT_obj_import"
|
||||
bl_extensions = [{"name": ".obj"}]
|
||||
|
||||
@classmethod
|
||||
def poll_extension(cls, context, extension):
|
||||
return extension == ".obj"
|
||||
def poll(cls, context):
|
||||
return context.area.type == "VIEW_3D"
|
||||
|
||||
|
||||
class WM_FDT_ply(bpy.types.FileDrop):
|
||||
bl_space_type = "VIEW_3D"
|
||||
bl_idname = "WM_FDT_ply"
|
||||
bl_operator = "WM_OT_ply_import"
|
||||
class WM_FH_ply(bpy.types.FileHandler):
|
||||
bl_idname = "WM_FH_ply"
|
||||
bl_label = "ply"
|
||||
bl_import_operator = "WM_OT_ply_import"
|
||||
bl_extensions = [{"name": ".ply"}]
|
||||
|
||||
@classmethod
|
||||
def poll_extension(cls, context, extension):
|
||||
return extension == ".ply"
|
||||
def poll(cls, context):
|
||||
return context.area.type == "VIEW_3D"
|
||||
|
||||
|
||||
class WM_FDT_stl(bpy.types.FileDrop):
|
||||
bl_space_type = "VIEW_3D"
|
||||
bl_idname = "WM_FDT_stl"
|
||||
bl_operator = "WM_OT_stl_import"
|
||||
class WM_FH_stl(bpy.types.FileHandler):
|
||||
bl_idname = "WM_FH_stl"
|
||||
bl_label = "stl"
|
||||
bl_import_operator = "WM_OT_stl_import"
|
||||
bl_extensions = [{"name": ".stl"}]
|
||||
|
||||
@classmethod
|
||||
def poll_extension(cls, context, extension):
|
||||
return extension == ".stl"
|
||||
def poll(cls, context):
|
||||
return context.area.type == "VIEW_3D"
|
||||
|
||||
class WM_FDT_import_mesh_stl(bpy.types.FileDrop):
|
||||
bl_space_type = "VIEW_3D"
|
||||
bl_idname = "WM_FDT_import_mesh_stl"
|
||||
bl_operator = "import_mesh.stl"
|
||||
|
||||
class WM_FH_import_mesh_stl(bpy.types.FileHandler):
|
||||
bl_idname = "WM_FH_import_mesh_stl"
|
||||
bl_label = "stl"
|
||||
bl_import_operator = "import_mesh.stl"
|
||||
bl_extensions = [{"name": ".stl"}]
|
||||
|
||||
@classmethod
|
||||
def poll_extension(cls, context, extension):
|
||||
return extension == ".stl"
|
||||
def poll(cls, context):
|
||||
return context.area.type == "VIEW_3D"
|
||||
brecht marked this conversation as resolved
|
||||
|
||||
class WM_FDT_usd(bpy.types.FileDrop):
|
||||
bl_space_type = "VIEW_3D"
|
||||
bl_idname = "WM_FDT_usd"
|
||||
bl_operator = "WM_OT_usd_import"
|
||||
|
||||
class WM_FH_usd(bpy.types.FileHandler):
|
||||
bl_idname = "WM_FH_usd"
|
||||
bl_label = "usd"
|
||||
bl_import_operator = "WM_OT_usd_import"
|
||||
bl_extensions = [{"name": ".usd"}]
|
||||
guishe marked this conversation as resolved
Outdated
Brecht Van Lommel
commented
There is also There is also `usda`, `usdc`, `usdz`.
|
||||
|
||||
@classmethod
|
||||
def poll_extension(cls, context, extension):
|
||||
return extension == ".usd"
|
||||
def poll(cls, context):
|
||||
return context.area.type == "VIEW_3D"
|
||||
|
||||
|
||||
classes = (
|
||||
|
@ -3624,12 +3634,12 @@ classes = (
|
|||
WM_MT_splash_about,
|
||||
WM_MT_region_toggle_pie,
|
||||
|
||||
WM_FDT_alembic,
|
||||
WM_FDT_collada,
|
||||
WM_FDT_gpencil,
|
||||
WM_FDT_obj,
|
||||
WM_FDT_ply,
|
||||
WM_FDT_stl,
|
||||
WM_FDT_import_mesh_stl,
|
||||
WM_FDT_usd,
|
||||
WM_FH_alembic,
|
||||
WM_FH_collada,
|
||||
WM_FH_gpencil,
|
||||
WM_FH_obj,
|
||||
WM_FH_ply,
|
||||
WM_FH_stl,
|
||||
WM_FH_import_mesh_stl,
|
||||
WM_FH_usd,
|
||||
)
|
||||
|
|
|
@ -139,9 +139,6 @@ typedef struct SpaceType {
|
|||
/** Asset shelf type definitions. */
|
||||
ListBase asset_shelf_types; /* #AssetShelfType */
|
||||
|
||||
/** File drop type definitions. */
|
||||
ListBase file_drop_types; /* #FileDropType */
|
||||
|
||||
/* read and write... */
|
||||
|
||||
/** Default key-maps to add. */
|
||||
|
@ -479,28 +476,6 @@ typedef struct AssetShelfType {
|
|||
ExtensionRNA rna_ext;
|
||||
} AssetShelfType;
|
||||
|
||||
typedef struct FileDropType {
|
||||
struct FileDropType *next, *prev;
|
||||
|
||||
char idname[BKE_ST_MAXNAME]; /* unique name */
|
||||
|
||||
char op_name[BKE_ST_MAXNAME]; /* operator name */
|
||||
|
||||
int space_type;
|
||||
|
||||
/** Determine if the operator can handle a specific file extension. */
|
||||
bool (*poll_extension)(const struct bContext *C,
|
||||
FileDropType *file_drop_type,
|
||||
const char *extension);
|
||||
|
||||
/* RNA integration */
|
||||
ExtensionRNA rna_ext;
|
||||
} FileDropType;
|
||||
|
||||
typedef struct FileDrop {
|
||||
struct FileDropType *type; /* runtime */
|
||||
} FileDrop;
|
||||
|
||||
/* Space-types. */
|
||||
|
||||
struct SpaceType *BKE_spacetype_from_id(int spaceid);
|
||||
|
@ -685,3 +660,35 @@ bool BKE_screen_blend_read_data(struct BlendDataReader *reader, struct bScreen *
|
|||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
struct bFileExtension {
|
||||
char extension[64];
|
||||
};
|
||||
struct FileHandlerType {
|
||||
|
||||
char idname[BKE_ST_MAXNAME]; /* unique name */
|
||||
|
||||
char label[BKE_ST_MAXNAME]; /* label */
|
||||
|
||||
char import_operator[BKE_ST_MAXNAME]; /* import operator name */
|
||||
|
||||
guishe marked this conversation as resolved
Outdated
Brecht Van Lommel
commented
This should move to its own file, This should move to its own file, `BKE_file_handler.h`
|
||||
/** TODO */
|
||||
bool (*poll)(const struct bContext *C, FileHandlerType *file_handle_type);
|
||||
guishe marked this conversation as resolved
Outdated
Brecht Van Lommel
commented
Leave empty line between struct definitions. Leave empty line between struct definitions.
|
||||
|
||||
blender::Vector<bFileExtension> extensions;
|
||||
|
||||
/** Equivalent to datablocks ID properties. */
|
||||
struct IDProperty *id_properties;
|
||||
|
||||
/* RNA integration */
|
||||
guishe marked this conversation as resolved
Outdated
Brecht Van Lommel
commented
Better to use Better to use `OP_MAX_TYPENAME` then, even if it means including a header.
|
||||
ExtensionRNA rna_ext;
|
||||
};
|
||||
|
||||
guishe marked this conversation as resolved
Outdated
Brecht Van Lommel
commented
Maybe call this Maybe call this `poll_drop` to clarify that it is used for drag & drop. We could imagine adding other poll types in the future to this type.
|
||||
void BKE_file_handlers_free(void);
|
||||
blender::Span<FileHandlerType *> BKE_file_handlers();
|
||||
void BKE_file_handler_add(FileHandlerType *file_handler);
|
||||
void BKE_file_handler_remove(FileHandlerType *file_handler);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -70,7 +70,7 @@ void BKE_blender_free()
|
|||
}
|
||||
|
||||
BKE_spacetypes_free(); /* after free main, it uses space callbacks */
|
||||
|
||||
BKE_file_handlers_free();
|
||||
IMB_exit();
|
||||
BKE_cachefiles_exit();
|
||||
DEG_free_node_types();
|
||||
|
|
|
@ -231,7 +231,6 @@ static void spacetype_free(SpaceType *st)
|
|||
|
||||
BLI_freelistN(&st->regiontypes);
|
||||
BLI_freelistN(&st->asset_shelf_types);
|
||||
BLI_freelistN(&st->file_drop_types);
|
||||
}
|
||||
|
||||
void BKE_spacetypes_free()
|
||||
|
@ -1339,3 +1338,40 @@ void BKE_screen_area_blend_read_after_liblink(BlendLibReader *reader, ID *parent
|
|||
regions_remove_invalid(space_type, regionbase);
|
||||
}
|
||||
}
|
||||
|
||||
static blender::Vector<FileHandlerType *> file_handlers{};
|
||||
guishe marked this conversation as resolved
Outdated
Brecht Van Lommel
commented
Move to new Move to new `file_handler.cc` file.
|
||||
|
||||
void file_handler_free(FileHandlerType *file_handler)
|
||||
{
|
||||
if (file_handler->id_properties) {
|
||||
IDP_FreeProperty(file_handler->id_properties);
|
||||
}
|
||||
MEM_delete(file_handler);
|
||||
}
|
||||
|
||||
void BKE_file_handlers_free()
|
||||
{
|
||||
for (auto *file_handler : file_handlers) {
|
||||
if (file_handler->rna_ext.free) {
|
||||
file_handler->rna_ext.free(file_handler->rna_ext.data);
|
||||
}
|
||||
file_handler_free(file_handler);
|
||||
}
|
||||
file_handlers.clear_and_shrink();
|
||||
}
|
||||
|
||||
blender::Span<FileHandlerType *> BKE_file_handlers()
|
||||
{
|
||||
return file_handlers.as_span();
|
||||
}
|
||||
|
||||
void BKE_file_handler_add(FileHandlerType *file_handler)
|
||||
{
|
||||
file_handlers.append(file_handler);
|
||||
}
|
||||
|
||||
void BKE_file_handler_remove(FileHandlerType *file_handler)
|
||||
{
|
||||
file_handlers.remove(file_handlers.first_index_of(file_handler));
|
||||
file_handler_free(file_handler);
|
||||
}
|
||||
|
|
|
@ -22,24 +22,33 @@
|
|||
|
||||
#include "io_drop_import_helper.hh"
|
||||
|
||||
static bool poll_extension(blender::Span<bFileExtension> file_extensions, const char *extension)
|
||||
{
|
||||
for (auto &file_extension : file_extensions) {
|
||||
if (STREQ(extension, file_extension.extension)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static blender::Vector<wmOperatorType *> poll_operators_for_extension(const bContext *C,
|
||||
const char *extension)
|
||||
{
|
||||
const ScrArea *area = CTX_wm_area(C);
|
||||
const SpaceType *st = area->type;
|
||||
|
||||
blender::Vector<wmOperatorType *> operators;
|
||||
|
||||
LISTBASE_FOREACH (FileDropType *, file_drop_test, &st->file_drop_types) {
|
||||
if (file_drop_test->poll_extension &&
|
||||
file_drop_test->poll_extension(C, file_drop_test, extension)) {
|
||||
wmOperatorType *test_operator = WM_operatortype_find(file_drop_test->op_name, false);
|
||||
if (!test_operator) {
|
||||
continue;
|
||||
}
|
||||
operators.append(test_operator);
|
||||
for (auto *file_handler : BKE_file_handlers()) {
|
||||
if (!poll_extension(file_handler->extensions, extension)) {
|
||||
continue;
|
||||
}
|
||||
};
|
||||
if (!(file_handler->poll && file_handler->poll(C, file_handler))) {
|
||||
continue;
|
||||
}
|
||||
wmOperatorType *test_operator = WM_operatortype_find(file_handler->import_operator, false);
|
||||
if (!test_operator) {
|
||||
continue;
|
||||
}
|
||||
operators.append(test_operator);
|
||||
}
|
||||
return operators;
|
||||
}
|
||||
|
||||
|
|
|
@ -805,6 +805,11 @@ typedef struct AssetShelf {
|
|||
AssetShelfSettings settings;
|
||||
} AssetShelf;
|
||||
|
||||
typedef struct FileHandler {
|
||||
DNA_DEFINE_CXX_METHODS(FileHandler)
|
||||
struct FileHandlerType *type; /* runtime */
|
||||
} FileHandler;
|
||||
|
||||
/**
|
||||
* Region-data for the main asset shelf region (#RGN_TYPE_ASSET_SHELF). Managed by the asset shelf
|
||||
* internals.
|
||||
|
|
|
@ -1269,23 +1269,20 @@ static void rna_Menu_bl_description_set(PointerRNA *ptr, const char *value)
|
|||
}
|
||||
}
|
||||
|
||||
/* File Drop */
|
||||
/* File Handler */
|
||||
|
||||
static bool file_drop_poll_extension(const bContext *C,
|
||||
FileDropType *file_drop_type,
|
||||
const char *extension)
|
||||
static bool file_handler_poll(const bContext *C, FileHandlerType *file_handler_type)
|
||||
{
|
||||
extern FunctionRNA rna_FileDrop_poll_extension_func;
|
||||
extern FunctionRNA rna_FileHandler_poll_func;
|
||||
|
||||
PointerRNA ptr = RNA_pointer_create(nullptr, file_drop_type->rna_ext.srna, nullptr); /* dummy */
|
||||
/* RNA_struct_find_function(&ptr, "poll"); */
|
||||
FunctionRNA *func = &rna_FileDrop_poll_extension_func;
|
||||
PointerRNA ptr = RNA_pointer_create(
|
||||
nullptr, file_handler_type->rna_ext.srna, nullptr); /* dummy */
|
||||
FunctionRNA *func = &rna_FileHandler_poll_func;
|
||||
|
||||
ParameterList list;
|
||||
RNA_parameter_list_create(&list, &ptr, func);
|
||||
RNA_parameter_set_lookup(&list, "context", &C);
|
||||
RNA_parameter_set_lookup(&list, "extension", &extension);
|
||||
file_drop_type->rna_ext.call((bContext *)C, &ptr, func, &list);
|
||||
file_handler_type->rna_ext.call((bContext *)C, &ptr, func, &list);
|
||||
|
||||
void *ret;
|
||||
RNA_parameter_get_lookup(&list, "visible", &ret);
|
||||
|
@ -1297,108 +1294,117 @@ static bool file_drop_poll_extension(const bContext *C,
|
|||
return is_visible;
|
||||
}
|
||||
|
||||
static bool rna_FileDrop_unregister(Main * /*bmain*/, StructRNA *type)
|
||||
static bool rna_FileHandler_unregister(Main * /*bmain*/, StructRNA *type)
|
||||
{
|
||||
FileDropType *file_drop_type = static_cast<FileDropType *>(RNA_struct_blender_type_get(type));
|
||||
FileHandlerType *file_handler_type = static_cast<FileHandlerType *>(
|
||||
RNA_struct_blender_type_get(type));
|
||||
|
||||
if (!file_drop_type) {
|
||||
if (!file_handler_type) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SpaceType *space_type = BKE_spacetype_from_id(file_drop_type->space_type);
|
||||
if (!space_type) {
|
||||
return false;
|
||||
}
|
||||
|
||||
RNA_struct_free_extension(type, &file_drop_type->rna_ext);
|
||||
RNA_struct_free_extension(type, &file_handler_type->rna_ext);
|
||||
RNA_struct_free(&BLENDER_RNA, type);
|
||||
|
||||
BLI_freelinkN(&space_type->file_drop_types, file_drop_type);
|
||||
|
||||
/* update while blender is running */
|
||||
WM_main_add_notifier(NC_WINDOW, nullptr);
|
||||
BKE_file_handler_remove(file_handler_type);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static StructRNA *rna_FileDrop_register(Main *bmain,
|
||||
ReportList *reports,
|
||||
void *data,
|
||||
const char *identifier,
|
||||
StructValidateFunc validate,
|
||||
StructCallbackFunc call,
|
||||
StructFreeFunc free)
|
||||
static StructRNA *rna_FileHandler_register(Main *bmain,
|
||||
ReportList *reports,
|
||||
void *data,
|
||||
const char *identifier,
|
||||
StructValidateFunc validate,
|
||||
StructCallbackFunc call,
|
||||
StructFreeFunc free)
|
||||
{
|
||||
FileDropType dummy_file_drop_type = {};
|
||||
FileDrop dummy_file_drop = {};
|
||||
dummy_file_drop.type = &dummy_file_drop_type;
|
||||
/* setup dummy file drop type to store static properties in */
|
||||
PointerRNA dummy_file_drop_ptr = RNA_pointer_create(nullptr, &RNA_FileDrop, &dummy_file_drop);
|
||||
|
||||
FileHandlerType dummy_file_handler_type = {};
|
||||
FileHandler dummy_file_handler = {};
|
||||
|
||||
dummy_file_handler.type = &dummy_file_handler_type;
|
||||
|
||||
/* setup dummy file handler type to store static properties in */
|
||||
PointerRNA dummy_file_handler_ptr = RNA_pointer_create(
|
||||
nullptr, &RNA_FileHandler, &dummy_file_handler);
|
||||
|
||||
bool have_function[1];
|
||||
|
||||
/* validate the python class */
|
||||
if (validate(&dummy_file_drop_ptr, data, have_function) != 0) {
|
||||
if (validate(&dummy_file_handler_ptr, data, have_function) != 0) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (strlen(identifier) >= sizeof(dummy_file_drop_type.idname)) {
|
||||
if (strlen(identifier) >= sizeof(dummy_file_handler_type.idname)) {
|
||||
BKE_reportf(reports,
|
||||
RPT_ERROR,
|
||||
"Registering file drop class: '%s' is too long, maximum length is %d",
|
||||
"Registering file handler class: '%s' is too long, maximum length is %d",
|
||||
identifier,
|
||||
(int)sizeof(dummy_file_drop_type.idname));
|
||||
(int)sizeof(dummy_file_handler_type.idname));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
SpaceType *space_type = BKE_spacetype_from_id(dummy_file_drop_type.space_type);
|
||||
if (!space_type) {
|
||||
BLI_assert_unreachable();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/* Check if we have registered this file drop type before, and remove it. */
|
||||
LISTBASE_FOREACH (FileDropType *, iter_file_drop_type, &space_type->file_drop_types) {
|
||||
if (STREQ(iter_file_drop_type->idname, dummy_file_drop_type.idname)) {
|
||||
if (iter_file_drop_type->rna_ext.srna) {
|
||||
rna_FileDrop_unregister(bmain, iter_file_drop_type->rna_ext.srna);
|
||||
/* Check if we have registered this file handler type before, and remove it. */
|
||||
for (auto *iter_file_handler_type : BKE_file_handlers()) {
|
||||
if (STREQ(iter_file_handler_type->idname, dummy_file_handler_type.idname)) {
|
||||
if (iter_file_handler_type->rna_ext.srna) {
|
||||
rna_FileHandler_unregister(bmain, iter_file_handler_type->rna_ext.srna);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!RNA_struct_available_or_report(reports, dummy_file_drop_type.idname)) {
|
||||
|
||||
if (!RNA_struct_available_or_report(reports, dummy_file_handler_type.idname)) {
|
||||
return nullptr;
|
||||
}
|
||||
if (!RNA_struct_bl_idname_ok_or_report(reports, dummy_file_drop_type.idname, "_FDT_")) {
|
||||
if (!RNA_struct_bl_idname_ok_or_report(reports, dummy_file_handler_type.idname, "_FH_")) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/* Create the new file drop type. */
|
||||
FileDropType *file_drop_type = MEM_cnew<FileDropType>(__func__);
|
||||
memcpy(file_drop_type, &dummy_file_drop_type, sizeof(*file_drop_type));
|
||||
/* Create the new file handler type. */
|
||||
FileHandlerType *file_handler_type = MEM_new<FileHandlerType>(__func__);
|
||||
|
||||
file_drop_type->rna_ext.srna = RNA_def_struct_ptr(
|
||||
&BLENDER_RNA, file_drop_type->idname, &RNA_FileDrop);
|
||||
file_drop_type->rna_ext.data = data;
|
||||
file_drop_type->rna_ext.call = call;
|
||||
file_drop_type->rna_ext.free = free;
|
||||
RNA_struct_blender_type_set(file_drop_type->rna_ext.srna, file_drop_type);
|
||||
strcpy(file_handler_type->idname, dummy_file_handler_type.idname);
|
||||
strcpy(file_handler_type->label, dummy_file_handler_type.label);
|
||||
strcpy(file_handler_type->import_operator, dummy_file_handler_type.import_operator);
|
||||
file_handler_type->id_properties = dummy_file_handler_type.id_properties;
|
||||
file_handler_type->rna_ext = dummy_file_handler_type.rna_ext;
|
||||
memcpy(&file_handler_type->rna_ext, &dummy_file_handler_type.rna_ext, sizeof(ExtensionRNA));
|
||||
int extensions_len = RNA_collection_length(&dummy_file_handler_ptr, "bl_extensions");
|
||||
PropertyRNA *prop = RNA_struct_find_property(&dummy_file_handler_ptr, "bl_extensions");
|
||||
|
||||
file_drop_type->poll_extension = have_function[0] ? file_drop_poll_extension : nullptr;
|
||||
for (int i = 0; i < extensions_len; i++) {
|
||||
PointerRNA fileptr;
|
||||
bFileExtension extension;
|
||||
|
||||
BLI_addtail(&space_type->file_drop_types, file_drop_type);
|
||||
RNA_property_collection_lookup_int(&dummy_file_handler_ptr, prop, i, &fileptr);
|
||||
RNA_string_get(&fileptr, "name", extension.extension);
|
||||
|
||||
file_handler_type->extensions.append(extension);
|
||||
}
|
||||
|
||||
/* update while blender is running */
|
||||
WM_main_add_notifier(NC_WINDOW, nullptr);
|
||||
RNA_collection_clear(&dummy_file_handler_ptr, "bl_extensions");
|
||||
|
||||
return file_drop_type->rna_ext.srna;
|
||||
file_handler_type->rna_ext.srna = RNA_def_struct_ptr(
|
||||
&BLENDER_RNA, file_handler_type->idname, &RNA_FileHandler);
|
||||
file_handler_type->rna_ext.data = data;
|
||||
file_handler_type->rna_ext.call = call;
|
||||
file_handler_type->rna_ext.free = free;
|
||||
RNA_struct_blender_type_set(file_handler_type->rna_ext.srna, file_handler_type);
|
||||
|
||||
file_handler_type->poll = have_function[0] ? file_handler_poll : nullptr;
|
||||
|
||||
BKE_file_handler_add(file_handler_type);
|
||||
|
||||
return file_handler_type->rna_ext.srna;
|
||||
}
|
||||
|
||||
static StructRNA *rna_FileDrop_refine(PointerRNA *file_drop_ptr)
|
||||
static StructRNA *rna_FileHandler_refine(PointerRNA *file_handler_ptr)
|
||||
{
|
||||
FileDrop *file_drop = (FileDrop *)file_drop_ptr->data;
|
||||
return (file_drop && file_drop->type->rna_ext.srna) ? file_drop->type->rna_ext.srna :
|
||||
&RNA_FileDrop;
|
||||
FileHandler *file_handler = (FileHandler *)file_handler_ptr->data;
|
||||
return (file_handler && file_handler->type->rna_ext.srna) ? file_handler->type->rna_ext.srna :
|
||||
&RNA_FileHandler;
|
||||
}
|
||||
|
||||
/* UILayout */
|
||||
|
@ -1570,6 +1576,12 @@ static void rna_UILayout_property_decorate_set(PointerRNA *ptr, bool value)
|
|||
uiLayoutSetPropDecorate(static_cast<uiLayout *>(ptr->data), value);
|
||||
}
|
||||
|
||||
static IDProperty **rna_FileHandler_idprops(PointerRNA *ptr)
|
||||
{
|
||||
FileHandler *fh = (FileHandler *)ptr->data;
|
||||
return &fh->type->id_properties;
|
||||
}
|
||||
|
||||
#else /* RNA_RUNTIME */
|
||||
|
||||
static void rna_def_ui_layout(BlenderRNA *brna)
|
||||
|
@ -2209,20 +2221,32 @@ static void rna_def_menu(BlenderRNA *brna)
|
|||
RNA_define_verify_sdna(true);
|
||||
}
|
||||
|
||||
static void rna_def_file_drop(BlenderRNA *brna)
|
||||
static void rna_def_file_handler_extensions(BlenderRNA *brna, PropertyRNA *cprop)
|
||||
{
|
||||
StructRNA *srna;
|
||||
|
||||
RNA_def_property_srna(cprop, "FileExtensions");
|
||||
srna = RNA_def_struct(brna, "FileExtensions", nullptr);
|
||||
RNA_def_struct_sdna(srna, "bFileExtension");
|
||||
RNA_def_struct_ui_text(srna, "File Extensions", "TODO");
|
||||
brecht marked this conversation as resolved
Outdated
Brecht Van Lommel
commented
I'm not sure about this mechanism. We don't have a good way to pass a list of strings here currently, but the easier workaround to me seems to have a string of extensions separated by I'm not sure about this mechanism. We don't have a good way to pass a list of strings here currently, but the easier workaround to me seems to have a string of extensions separated by `;` or something like that.
Guillermo Venegas
commented
I changed it to be just a string separated by I changed it to be just a string separated by `;`, and also eliminated the `IDProperty` because it was only used for that purpose.
|
||||
}
|
||||
|
||||
static void rna_def_file_handler(BlenderRNA *brna)
|
||||
{
|
||||
StructRNA *srna;
|
||||
PropertyRNA *prop;
|
||||
|
||||
srna = RNA_def_struct(brna, "FileDrop", nullptr);
|
||||
RNA_def_struct_ui_text(srna, "File Drop Type", "File drop polling function class");
|
||||
RNA_def_struct_sdna(srna, "FileDrop");
|
||||
RNA_def_struct_refine_func(srna, "rna_FileDrop_refine");
|
||||
RNA_def_struct_register_funcs(srna, "rna_FileDrop_register", "rna_FileDrop_unregister", nullptr);
|
||||
RNA_def_struct_translation_context(srna, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
|
||||
RNA_def_struct_flag(srna, STRUCT_PUBLIC_NAMESPACE_INHERIT);
|
||||
srna = RNA_def_struct(brna, "FileHandler", nullptr);
|
||||
RNA_def_struct_ui_text(srna, "File Handler Type", "TODO");
|
||||
RNA_def_struct_sdna(srna, "FileHandler");
|
||||
RNA_def_struct_refine_func(srna, "rna_FileHandler_refine");
|
||||
RNA_def_struct_idprops_func(srna, "rna_FileHandler_idprops");
|
||||
RNA_def_struct_register_funcs(
|
||||
srna, "rna_FileHandler_register", "rna_FileHandler_unregister", nullptr);
|
||||
|
||||
/* registration */
|
||||
RNA_define_verify_sdna(false); /* not in sdna */
|
||||
|
||||
RNA_define_verify_sdna(true); /* not in sdna */
|
||||
prop = RNA_def_property(srna, "bl_idname", PROP_STRING, PROP_NONE);
|
||||
RNA_def_property_string_sdna(prop, nullptr, "type->idname");
|
||||
RNA_def_property_flag(prop, PROP_REGISTER);
|
||||
|
@ -2230,38 +2254,34 @@ static void rna_def_file_drop(BlenderRNA *brna)
|
|||
"ID Name",
|
||||
"If this is set, the asset gets a custom ID, otherwise it takes the "
|
||||
"name of the class used to define the menu (for example, if the "
|
||||
"class name is \"OBJECT_FDT_hello\", and bl_idname is not set by the "
|
||||
"script, then bl_idname = \"OBJECT_FDT_hello\")");
|
||||
"class name is \"OBJECT_FH_hello\", and bl_idname is not set by the "
|
||||
"script, then bl_idname = \"OBJECT_FH_hello\")");
|
||||
|
||||
prop = RNA_def_property(srna, "bl_space_type", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_sdna(prop, nullptr, "type->space_type");
|
||||
RNA_def_property_enum_items(prop, rna_enum_space_type_items);
|
||||
prop = RNA_def_property(srna, "bl_import_operator", PROP_STRING, PROP_NONE);
|
||||
RNA_def_property_string_sdna(prop, nullptr, "type->import_operator");
|
||||
RNA_def_property_flag(prop, PROP_REGISTER);
|
||||
RNA_def_property_ui_text(
|
||||
prop, "Space Type", "The space type where file dropped cin be used by the operator");
|
||||
RNA_def_property_ui_text(prop, "Operator", "TODO");
|
||||
|
||||
prop = RNA_def_property(srna, "bl_operator", PROP_STRING, PROP_NONE);
|
||||
RNA_def_property_string_sdna(prop, nullptr, "type->op_name");
|
||||
prop = RNA_def_property(srna, "bl_label", PROP_STRING, PROP_NONE);
|
||||
RNA_def_property_string_sdna(prop, nullptr, "type->label");
|
||||
RNA_def_property_flag(prop, PROP_REGISTER);
|
||||
RNA_def_property_ui_text(
|
||||
prop, "Operator", "Operator to call if the poll_extension is successful");
|
||||
RNA_def_property_ui_text(prop, "Label", "TODO");
|
||||
|
||||
prop = RNA_def_property(srna, "bl_extensions", PROP_COLLECTION, PROP_NONE);
|
||||
RNA_def_property_flag(prop, PROP_REGISTER | PROP_IDPROPERTY);
|
||||
RNA_def_property_struct_type(prop, "FileExtension");
|
||||
RNA_def_property_ui_text(prop, "Extensions", "TODO");
|
||||
rna_def_file_handler_extensions(brna, prop);
|
||||
|
||||
PropertyRNA *parm;
|
||||
FunctionRNA *func;
|
||||
|
||||
func = RNA_def_function(srna, "poll_extension", nullptr);
|
||||
RNA_def_function_ui_description(
|
||||
func, "If this method returns a non-null output, the file importer will be used");
|
||||
func = RNA_def_function(srna, "poll", nullptr);
|
||||
RNA_def_function_ui_description(func, "TODO");
|
||||
RNA_def_function_flag(func, FUNC_NO_SELF | FUNC_REGISTER_OPTIONAL);
|
||||
RNA_def_function_return(func, RNA_def_boolean(func, "visible", true, "", ""));
|
||||
parm = RNA_def_pointer(func, "context", "Context", "", "");
|
||||
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED);
|
||||
|
||||
parm = RNA_def_string(
|
||||
func, "extension", nullptr, 256, "extension", "Extension to test for dropped file");
|
||||
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED);
|
||||
|
||||
RNA_define_verify_sdna(true);
|
||||
}
|
||||
|
||||
static void rna_def_asset_shelf(BlenderRNA *brna)
|
||||
|
@ -2365,6 +2385,20 @@ static void rna_def_asset_shelf(BlenderRNA *brna)
|
|||
RNA_def_property_update(prop, NC_SPACE | ND_REGIONS_ASSET_SHELF, nullptr);
|
||||
}
|
||||
|
||||
static void rna_def_file_extension(BlenderRNA *brna)
|
||||
{
|
||||
StructRNA *srna;
|
||||
PropertyRNA *prop;
|
||||
srna = RNA_def_struct(brna, "FileExtension", nullptr);
|
||||
RNA_def_struct_sdna(srna, "bFileExtension");
|
||||
RNA_def_struct_ui_text(srna, "File Extension", "TODO");
|
||||
|
||||
RNA_define_verify_sdna(false);
|
||||
prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
|
||||
RNA_def_property_string_sdna(prop, nullptr, "extension");
|
||||
RNA_def_property_ui_text(prop, "Extension", "TODO");
|
||||
RNA_define_verify_sdna(true);
|
||||
}
|
||||
void RNA_def_ui(BlenderRNA *brna)
|
||||
{
|
||||
rna_def_ui_layout(brna);
|
||||
|
@ -2373,7 +2407,8 @@ void RNA_def_ui(BlenderRNA *brna)
|
|||
rna_def_header(brna);
|
||||
rna_def_menu(brna);
|
||||
rna_def_asset_shelf(brna);
|
||||
rna_def_file_drop(brna);
|
||||
rna_def_file_extension(brna);
|
||||
rna_def_file_handler(brna);
|
||||
}
|
||||
|
||||
#endif /* RNA_RUNTIME */
|
||||
|
|
|
@ -8874,7 +8874,7 @@ PyDoc_STRVAR(pyrna_register_class_doc,
|
|||
" :class:`bpy.types.Panel`, :class:`bpy.types.UIList`,\n"
|
||||
" :class:`bpy.types.Menu`, :class:`bpy.types.Header`,\n"
|
||||
" :class:`bpy.types.Operator`, :class:`bpy.types.KeyingSetInfo`,\n"
|
||||
" :class:`bpy.types.RenderEngine`, :class:`bpy.types.AssetShelf`\n"
|
||||
" :class:`bpy.types.RenderEngine`, :class:`bpy.types.AssetShelf`, :class:`bpy.types.FileHandler`\n"
|
||||
" :type cls: class\n"
|
||||
" :raises ValueError:\n"
|
||||
" if the class is not a subclass of a registerable blender class.\n"
|
||||
|
|
Loading…
Reference in New Issue
Probably should not have both STL importers here, in the end only one will be used when dropping?
In case there are 2 file handlers that can be used, you can choose which one to use with a menu
But the add-on one can include the file handle registration in its owns files
Ok, that makes sense. It would be better to have to just a single importer that is stable, but that's not a problem to be solved by this PR.