tornavis/doc/python_api/examples/bpy.types.FileHandler.2.py

100 lines
3.6 KiB
Python

"""
Basic FileHandler for Operator that imports multiple files
----------------------------------------------------------
Also operators can be invoked with multiple files from 'drag-and-drop',
but for this it is require to define the following properties:
.. code-block:: python
directory: StringProperty(subtype='FILE_PATH')
files: CollectionProperty(type=bpy.types.OperatorFileListElement)
This ``directory`` and ``files`` properties now will be used by the
``FileHandler`` to set 'drag-and-drop' filepath data.
"""
import bpy
from bpy_extras.io_utils import ImportHelper
from mathutils import Vector
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"
"""
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', '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):
return (context.region and context.region.type == 'WINDOW'
and context.area and context.area.ui_type == 'ShaderNodeTree'
and context.object and context.object.type == 'MESH'
and context.material)
def execute(self, context):
""" The directory property need to be set. """
if not self.directory:
return {'CANCELLED'}
x = 0.0
y = 0.0
for file in self.files:
"""
Calls to the operator can set unfiltered file names,
ensure the file extension is .txt
"""
if file.name.endswith(".txt"):
node_tree = context.material.node_tree
text_node = node_tree.nodes.new(type="ShaderNodeScript")
text_node.mode = 'EXTERNAL'
import os
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'}
"""
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):
return self.invoke_popup(context)
class SHADER_FH_script_import(bpy.types.FileHandler):
bl_idname = "SHADER_FH_script_import"
bl_label = "File handler for shader script node import"
bl_import_operator = "shader.script_import"
bl_file_extensions = ".txt"
@classmethod
def poll_drop(cls, context):
return (context.region and context.region.type == 'WINDOW'
and context.area and context.area.ui_type == 'ShaderNodeTree')
bpy.utils.register_class(ShaderScriptImport)
bpy.utils.register_class(SHADER_FH_script_import)