# SPDX-License-Identifier: GPL-2.0-or-later import bpy import os from bpy.props import ( BoolProperty, CollectionProperty, EnumProperty, IntProperty, PointerProperty, StringProperty, ) from bpy.types import PropertyGroup, UIList from pprint import pprint as pp from vse_toolbox.bl_utils import get_addon_prefs, get_scene_settings from vse_toolbox.constants import ASSET_PREVIEWS, TRACKERS from vse_toolbox.file_utils import norm_str def get_episodes_items(self, context): settings = get_scene_settings() project = settings.active_project if not project: return [('NONE', 'None', '', 0)] episodes = project.episodes if not episodes: return [('NONE', 'None', '', 0)] return [(e, e, '', i) for i, e in enumerate(episodes.keys())] def get_project_items(self, context): if not self.projects: return [('NONE', 'None', '', 0)] return [(p, p, '', i) for i, p in enumerate(self.projects.keys())] def update_episodes(self, context): settings = get_scene_settings() settings['episodes'] = 0 def get_tracker_items(self, context): return [(norm_str(a.name, format=str.upper), a.name, "", i) for i, a in enumerate(TRACKERS)] class Asset(PropertyGroup): name : StringProperty(default='') id : StringProperty(default='') norm_name : StringProperty(default='') asset_type : StringProperty(default='') tracker_name : StringProperty(default='') preview : StringProperty(default='') @property def label(self): return f"{self.asset_type} / {self.norm_name}" @property def icon_id(self): ico = ASSET_PREVIEWS.get(self.preview) if ico: return ico.icon_id class AssetCasting(PropertyGroup): id : StringProperty(default='') instance : IntProperty(default=1) def __iter__(self): return (getattr(self, p) for p in self.bl_rna.properties.keys() if p not in ('rna_type', 'name')) @property def asset(self): settings = get_scene_settings() project = settings.active_project return project.assets.get(self.id) def to_dict(self): return {k: v for k,v in self.items()} class Episode(PropertyGroup): id : StringProperty(default='') @property def active(self): settings = get_scene_settings() return self.get(settings.project_name) class Project(PropertyGroup): id : StringProperty(default='') sequence_increment : IntProperty( name="Sequence Increment", default=10, min=0, step=10) shot_increment : IntProperty( name="Shot Increment", default=10, min=0, step=10) sequence_template : StringProperty( name="Sequence Name", default="sq{index:03d}") episode_template : StringProperty( name="Episode Name", default="e{index:03d}") shot_template : StringProperty( name="Shot Name", default="{episode}s{index:04d}") episode_name : EnumProperty(items=get_episodes_items) episodes : CollectionProperty(type=Episode) assets : CollectionProperty(type=Asset) #FIXME Trouver une solution pour mettre des method dans les CollectionProperty class Projects(PropertyGroup): pass # @property # def active(self): # settings = get_scene_settings() # return self.get(settings.project_name) class VSETB_UL_casting(UIList): order_by_type : BoolProperty(default=False) def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index): settings = get_scene_settings() project = settings.active_project # asset = next((a for a in project.assets if a.id == item.id), None) asset = item.asset if asset is None: #TODO deal if asset was removed pass icon_id = asset.icon_id params = {'icon_value': icon_id} if icon_id else {'icon': 'BLANK1'} # Make sure your code supports all 3 layout types if self.layout_type in {'DEFAULT', 'COMPACT'}: layout.label(**params) split = layout.split(factor=0.6) split.label(text=f"{asset.norm_name.title()}") split.label(text=f"{asset.asset_type.title()}") split.prop(item, 'instance', text='') elif self.layout_type in {'GRID'}: layout.alignment = 'CENTER' layout.label(text="") def draw_filter(self, context, layout): row = layout.row() subrow = row.row(align=True) subrow.prop(self, "filter_name", text="") subrow.prop(self, "use_filter_invert", text="", icon='ARROW_LEFTRIGHT') subrow.separator() subrow.prop(self, "order_by_type", text="Order by Type", icon='MESH_DATA') def filter_items(self, context, data, propname): """Filter and order items in the list.""" helper_funcs = bpy.types.UI_UL_list filtered = [] ordered = [] items = getattr(data, propname) # Filtering by name if self.filter_name: filtered = helper_funcs.filter_items_by_name(self.filter_name, self.bitflag_filter_item, items, "name", reverse=self.use_filter_sort_alpha) # Order by types if self.order_by_type: _sort = [(idx, casting_item) for idx, casting_item in enumerate(items)] sort_items = helper_funcs.sort_items_helper ordered = sort_items(_sort, lambda x: x[1].asset.label) return filtered, ordered class VSETB_PGT_scene_settings(PropertyGroup): projects : CollectionProperty(type=Project) project_name : EnumProperty(items=get_project_items, update=update_episodes) tracker_name : EnumProperty(items=get_tracker_items) toogle_prefs : BoolProperty(description='Toogle VSE ToolBox Preferences', default=True) auto_select_strip : BoolProperty( name='Auto Select Strip',description='Auto select strip', default=True) channel : EnumProperty( items=[ ('AUDIO', 'Audio', '', 0), ('MOVIE', 'Movie', '', 1), ('SHOTS', 'Shots', '', 2), ('SEQUENCES', 'Sequences', '', 3), ] ) sequence_channel_name : StringProperty( name="Sequences Channel Name", default="Sequences") shot_channel_name : StringProperty( name="Shot Channel Name", default="Shots") @property def active_project(self): settings = get_scene_settings() return settings.projects.get(settings.project_name) @property def active_episode(self): project = self.active_project if project: return project.episodes.get(project.episode_name) class VSETB_PGT_strip_settings(PropertyGroup): casting : CollectionProperty(type=AssetCasting) casting_index : IntProperty(name='Casting Index', default=0) source_name : StringProperty(name='') classes=( Asset, Episode, Project, AssetCasting, VSETB_UL_casting, VSETB_PGT_scene_settings, VSETB_PGT_strip_settings, ) def register(): for cls in classes: bpy.utils.register_class(cls) bpy.types.Scene.vsetb_settings = PointerProperty(type=VSETB_PGT_scene_settings) bpy.types.Sequence.vsetb_strip_settings = PointerProperty(type=VSETB_PGT_strip_settings) def unregister(): for cls in reversed(classes): bpy.utils.unregister_class(cls) del bpy.types.Sequence.vsetb_strip_settings del bpy.types.Scene.vsetb_settings