ImportHelper: Common methods for FileHandler drag and drop support
Provide common implementations for two operations that all Python FileHandlers will typically use. - `poll_file_object_drop` To be used inside the FileHandler `poll_drop` callback - `invoke_popup` To be used inside the Operator `invoke` callback The above code closely mirrors what is currently done inside the existing Blender c++ FileHandlers. Pull Request: https://projects.blender.org/blender/blender/pulls/119774
This commit is contained in:
parent
6dd0f6627e
commit
af7a34dee7
|
@ -16,10 +16,11 @@ This ``directory`` and ``files`` properties now will be used by the
|
|||
"""
|
||||
|
||||
import bpy
|
||||
from bpy_extras.io_utils import ImportHelper
|
||||
from mathutils import Vector
|
||||
|
||||
|
||||
class ShaderScriptImport(bpy.types.Operator):
|
||||
class ShaderScriptImport(bpy.types.Operator, ImportHelper):
|
||||
"""Test importer that creates scripts nodes from .txt files"""
|
||||
bl_idname = "shader.script_import"
|
||||
bl_label = "Import a text file as a script node"
|
||||
|
@ -28,8 +29,11 @@ class ShaderScriptImport(bpy.types.Operator):
|
|||
This Operator can import multiple .txt files, we need following directory and files
|
||||
properties that the file handler will use to set files path data
|
||||
"""
|
||||
directory: bpy.props.StringProperty(subtype='FILE_PATH', options={'SKIP_SAVE'})
|
||||
files: bpy.props.CollectionProperty(type=bpy.types.OperatorFileListElement, options={'SKIP_SAVE'})
|
||||
directory: bpy.props.StringProperty(subtype='FILE_PATH', options={'SKIP_SAVE', 'HIDDEN'})
|
||||
files: bpy.props.CollectionProperty(type=bpy.types.OperatorFileListElement, options={'SKIP_SAVE', 'HIDDEN'})
|
||||
|
||||
"""Allow the user to select if the node's label is set or not"""
|
||||
set_label: bpy.props.BoolProperty(name="Set Label", default=False)
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
|
@ -57,23 +61,25 @@ class ShaderScriptImport(bpy.types.Operator):
|
|||
filepath = os.path.join(self.directory, file.name)
|
||||
text_node.filepath = filepath
|
||||
text_node.location = Vector((x, y))
|
||||
|
||||
# Set the node's title to the file name
|
||||
if self.set_label:
|
||||
text_node.label = file.name
|
||||
|
||||
x += 20.0
|
||||
y -= 20.0
|
||||
return {'FINISHED'}
|
||||
|
||||
"""
|
||||
By default the file handler invokes the operator with the directory and files properties set.
|
||||
In this example if this properties are set the operator is executed, if not the
|
||||
file select window is invoked.
|
||||
This depends on setting ``options={'SKIP_SAVE'}`` to the properties options to avoid
|
||||
to reuse filepath data between operator calls.
|
||||
"""
|
||||
Use ImportHelper's invoke_popup() to handle the invocation so that this operator's properties
|
||||
are shown in a popup. This allows the user to configure additional settings on the operator like
|
||||
the `set_label` property. Consider having a draw() method on the operator in order to layout the
|
||||
properties in the UI appropriately.
|
||||
|
||||
If filepath information is not provided the file select window will be invoked instead.
|
||||
"""
|
||||
def invoke(self, context, event):
|
||||
if self.directory:
|
||||
return self.execute(context)
|
||||
context.window_manager.fileselect_add(self)
|
||||
return {'RUNNING_MODAL'}
|
||||
return self.invoke_popup(context)
|
||||
|
||||
|
||||
class SHADER_FH_script_import(bpy.types.FileHandler):
|
||||
|
|
|
@ -23,7 +23,10 @@ from bpy.props import (
|
|||
EnumProperty,
|
||||
StringProperty,
|
||||
)
|
||||
from bpy.app.translations import pgettext_data as data_
|
||||
from bpy.app.translations import (
|
||||
pgettext_iface as iface_,
|
||||
pgettext_data as data_,
|
||||
)
|
||||
|
||||
|
||||
def _check_axis_conversion(op):
|
||||
|
@ -96,12 +99,28 @@ class ImportHelper:
|
|||
description="Filepath used for importing the file",
|
||||
maxlen=1024,
|
||||
subtype='FILE_PATH',
|
||||
options={'SKIP_PRESET', 'HIDDEN'}
|
||||
)
|
||||
|
||||
def invoke(self, context, _event):
|
||||
context.window_manager.fileselect_add(self)
|
||||
return {'RUNNING_MODAL'}
|
||||
|
||||
def invoke_popup(self, context, confirm_text=""):
|
||||
if self.properties.is_property_set("filepath"):
|
||||
title = self.filepath
|
||||
if len(self.files) > 1:
|
||||
title = iface_("Import {} files").format(len(self.files))
|
||||
|
||||
if not confirm_text:
|
||||
confirm_text = self.bl_label
|
||||
|
||||
confirm_text = iface_(confirm_text)
|
||||
return context.window_manager.invoke_props_dialog(self, confirm_text=confirm_text, title=title, translate=False)
|
||||
|
||||
context.window_manager.fileselect_add(self)
|
||||
return {'RUNNING_MODAL'}
|
||||
|
||||
def check(self, _context):
|
||||
return _check_axis_conversion(self)
|
||||
|
||||
|
@ -394,6 +413,19 @@ def unpack_face_list(list_of_tuples):
|
|||
return flat_ls
|
||||
|
||||
|
||||
def poll_file_object_drop(context):
|
||||
"""
|
||||
A default implementation for FileHandler poll_drop methods. Allows for both the 3D Viewport and
|
||||
the Outliner (in ViewLayer display mode) to be targets for file drag and drop.
|
||||
"""
|
||||
area = context.area
|
||||
if not area:
|
||||
return False
|
||||
is_v3d = area.type == 'VIEW_3D'
|
||||
is_outliner_view_layer = area.type == 'OUTLINER' and area.spaces.active.display_mode == 'VIEW_LAYER'
|
||||
return is_v3d or is_outliner_view_layer
|
||||
|
||||
|
||||
path_reference_mode = EnumProperty(
|
||||
name="Path Mode",
|
||||
description="Method used to reference paths",
|
||||
|
|
Loading…
Reference in New Issue