Last active
February 8, 2024 14:41
-
-
Save p2or/37ec841fa315481836c2655ebc4b1b42 to your computer and use it in GitHub Desktop.
Blend file list based on: https://blender.stackexchange.com/q/30444/ #Blender
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import bpy | |
from bpy.props import IntProperty, CollectionProperty, StringProperty, EnumProperty | |
from bpy.types import Panel, UIList, PropertyGroup, Operator | |
from bpy_extras.io_utils import ImportHelper | |
import os | |
class CUSTOM_OT_actionsUIList(Operator): | |
bl_idname = "custom.list_action" | |
bl_label = "List Action" | |
action: EnumProperty( | |
items=( | |
('UP', "Up", ""), | |
('DOWN', "Down", ""), | |
('REMOVE', "Remove", ""), | |
('ADD', "Add", ""), | |
) | |
) | |
def invoke(self, context, event): | |
scn = context.scene | |
idx = scn.custom_index | |
try: | |
item = scn.custom[idx] | |
except IndexError: | |
pass | |
else: | |
if self.action == 'DOWN' and idx < len(scn.custom) - 1: | |
item_next = scn.custom[idx+1].name | |
scn.custom_index += 1 | |
info = 'Item %d selected' % (scn.custom_index + 1) | |
self.report({'INFO'}, info) | |
elif self.action == 'UP' and idx >= 1: | |
item_prev = scn.custom[idx-1].name | |
scn.custom_index -= 1 | |
info = 'Item %d selected' % (scn.custom_index + 1) | |
self.report({'INFO'}, info) | |
elif self.action == 'REMOVE': | |
info = 'Item %s removed from list' % (scn.custom[scn.custom_index].name) | |
scn.custom_index -= 1 | |
self.report({'INFO'}, info) | |
scn.custom.remove(idx) | |
if self.action == 'ADD': | |
bpy.ops.custom.blend_select('INVOKE_DEFAULT') | |
scn.custom_index = (len(scn.custom)) # (len(scn.custom)-1) | |
return {"FINISHED"} | |
class CUSTOM_OT_blendSelect(bpy.types.Operator, ImportHelper): | |
"""This appears in the tooltip of the operator and in the generated docs""" | |
bl_idname = "custom.blend_select" | |
bl_label = "Blend Selector" | |
bl_options = {'PRESET', 'UNDO'} | |
# ImportHelper mixin class uses this | |
filename_ext = ".blend" | |
filter_glob: StringProperty( | |
default="*.blend", | |
options={'HIDDEN'}, | |
) | |
# Selected files | |
files: CollectionProperty(type=PropertyGroup) | |
def execute(self, context): | |
scn = context.scene | |
# get the folder | |
folder = (os.path.dirname(self.filepath)) | |
# iterate through the selected files | |
for i in self.files: | |
# generate full path to file | |
path_to_file = (os.path.join(folder, i.name)) | |
item = scn.custom.add() | |
item.id = len(scn.custom) | |
item.name = i.name # assign name of selected object | |
item.path = path_to_file | |
self.report({'INFO'}, "Files Added") | |
return {'FINISHED'} | |
class CUSTOM_UL_items(UIList): | |
def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index): | |
split = layout.split(factor=0.7) | |
split.prop(item, "name", text="", emboss=False, translate=False, icon='FILE_BLEND') | |
split.label(text="Index: %d" % (index)) | |
def invoke(self, context, event): | |
pass | |
class CUSTOM_PT_blendFiles(Panel): | |
"""Creates a Panel in the Object properties window""" | |
bl_idname = 'OBJECT_PT_my_panel' | |
bl_space_type = "TEXT_EDITOR" | |
bl_region_type = "UI" | |
bl_label = "Custom Blend File List" | |
def draw(self, context): | |
layout = self.layout | |
scn = bpy.context.scene | |
try: | |
current_item = (scn.custom[scn.custom_index].name) | |
except IndexError: | |
current_item = "" | |
rows = 2 | |
row = layout.row() | |
row.template_list("CUSTOM_UL_items", "", scn, "custom", scn, "custom_index", rows=rows) | |
col = row.column(align=True) | |
col.operator(CUSTOM_OT_actionsUIList.bl_idname, icon='TRIA_UP', text="").action = 'UP' | |
col.operator(CUSTOM_OT_actionsUIList.bl_idname, icon='TRIA_DOWN', text="").action = 'DOWN' | |
row = layout.row() | |
col = layout.column(align=True) | |
rowsub = col.row(align=True) | |
rowsub.operator(CUSTOM_OT_actionsUIList.bl_idname, icon='ZOOM_IN', text="Add Files to List").action = 'ADD' | |
rowsub.operator(CUSTOM_OT_actionsUIList.bl_idname, icon='ZOOM_OUT', text="Remove File").action = 'REMOVE' | |
row = layout.row() | |
col = row.column(align=True) | |
col.operator("custom.active_item", icon="CONSOLE") | |
col.operator("custom.print_list", icon="WORDWRAP_ON") | |
col.operator("custom.clear_list", icon="X") | |
row = layout.row(align=True) | |
row.label(text="Active Item is: {}".format(current_item)) | |
class CUSTOM_OT_clearListItems(bpy.types.Operator): | |
bl_idname = "custom.clear_list" | |
bl_label = "Clear List" | |
bl_description = "Clear all items in the list" | |
def execute(self, context): | |
scn = context.scene | |
lst = scn.custom | |
current_index = scn.custom_index | |
if len(lst) > 0: | |
# reverse range to remove last item first | |
for i in range(len(lst)-1,-1,-1): | |
scn.custom.remove(i) | |
self.report({'INFO'}, "All items removed") | |
else: | |
self.report({'INFO'}, "Nothing to remove") | |
return{'FINISHED'} | |
# print button | |
class CUSTOM_OT_printListItems(Operator): | |
bl_idname = "custom.print_list" | |
bl_label = "Print Name, ID and Path to Console" | |
bl_description = "Print all items to the Console" | |
def execute(self, context): | |
scn = context.scene | |
for i in scn.custom: | |
print ("Blend-File:", i.name, "ID:", i.id, "Path:", i.path) | |
return{'FINISHED'} | |
# select button | |
class CUSTOM_OT_selectAllItems(Operator): | |
bl_idname = "custom.active_item" | |
bl_label = "Print Active Item to Console" | |
bl_description = "Print Active Selection" | |
def execute(self, context): | |
scn = context.scene | |
print (scn.custom[scn.custom_index].name) | |
return{'FINISHED'} | |
# Create custom property group | |
class CUSTOM_PG_items(PropertyGroup): | |
# name: StringProperty() - instantiated by default | |
id: IntProperty() | |
path: StringProperty() | |
# ------------------------------------------------------------------- | |
# Registration | |
# ------------------------------------------------------------------- | |
classes = ( | |
CUSTOM_OT_actionsUIList, | |
CUSTOM_OT_blendSelect, | |
CUSTOM_UL_items, | |
CUSTOM_PT_blendFiles, | |
CUSTOM_OT_clearListItems, | |
CUSTOM_OT_printListItems, | |
CUSTOM_OT_selectAllItems, | |
CUSTOM_PG_items | |
) | |
def register(): | |
from bpy.utils import register_class | |
for cls in classes: | |
register_class(cls) | |
bpy.types.Scene.custom = CollectionProperty(type=CUSTOM_PG_items) | |
bpy.types.Scene.custom_index = IntProperty() | |
def unregister(): | |
from bpy.utils import unregister_class | |
for cls in reversed(classes): | |
unregister_class(cls) | |
del bpy.types.Scene.custom | |
del bpy.types.Scene.custom_index | |
if __name__ == "__main__": | |
register() |
Hi @dt192, updated the gist. You forgot to replace the assignment operators in the item group and to change the class names according to the current requirements in your fork hence the warnings in the console. Cheers
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I've updated it to work with Blender 2.9.3, as they broke stuff. Check the fork.