WIP: Experiment: Drop import operator helper and file drop type #111242

Closed
Guillermo Venegas wants to merge 23 commits from guishe/blender:drop-helper into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
8 changed files with 299 additions and 197 deletions
Showing only changes of commit 722b897785 - Show all commits

View File

@ -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

Probably should not have both STL importers here, in the end only one will be used when dropping?

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

In case there are 2 file handlers that can be used, you can choose which one to use with a menu <video src="/attachments/d3ccecac-20b6-4388-a3ba-d8df936b33d4" controls></video> 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.

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.
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

There is also usda, usdc, usdz.

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,
)

View File

@ -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

This should move to its own file, BKE_file_handler.h

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

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

Better to use OP_MAX_TYPENAME then, even if it means including a header.

Better to use `OP_MAX_TYPENAME` then, even if it means including a header.
ExtensionRNA rna_ext;
};
guishe marked this conversation as resolved Outdated

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.

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

View File

@ -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();

View File

@ -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

Move to new file_handler.cc file.

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);
}

View File

@ -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;
}

View File

@ -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.

View File

@ -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

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.

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.

I changed it to be just a string separated by ;, and also eliminated the IDProperty because it was only used for that purpose.

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 */

View File

@ -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"