import bpy from bpy.types import Menu, Panel, UIList from bpy.props import EnumProperty, StringProperty from bone_widget import ctx from pathlib import Path def add_row(layout, prop, data=None, name='', icon=None, operator=None, properties={}): data = data or ctx.prefs split = layout.split(factor=0.33, align=True) split.alignment= 'RIGHT' split.label(text=name+':' if name else '') row = split.row(align=True) row.prop(data, prop, text='') if icon and not operator: row.label(icon=icon) row.separator() if operator: op = row.operator(operator, icon=icon, text='', emboss=False) for k, v in properties.items(): setattr(op, k, v) else: row.label(icon='BLANK1') def add_bool_row(layout, prop, data=None, name='', icon=None): data = data or ctx.prefs row = layout.row(align=True) row.label(icon=icon) row.prop(data, prop, text=name) ''' def add_color_row(layout, data=None, name='', index=0): data = data or ctx.prefs.colors #split = layout.split(factor=0.25, align=True) #split.alignment= 'RIGHT' #split.label(text=name+':' if name else '') split = layout.split(factor=0.66, align=True) row = split.row(align=True) row.prop(data, 'name', text='') row = split.row(align=True) row.prop(data, 'value', text='') row.separator() #row = split.row(align=True) row.operator('bonewidget.remove_color', icon='REMOVE', text='', emboss=False).index = index ''' def draw_prefs(layout): box = layout.box() col = box.column(align=False) add_row(col, 'category', name='Tab', icon='COPY_ID') add_row(col, 'collection', name='Collection', icon='OUTLINER_COLLECTION') add_row(col, 'use_custom_collection', name='Custom Collection', icon='OUTLINER_COLLECTION') add_row(col, 'prefix', name='Prefix', icon='SYNTAX_OFF') col.separator() add_row(col, 'path', data=ctx.prefs.default_folder, name='Folders', icon='ADD', operator='bonewidget.add_folder') for i, f in enumerate(ctx.prefs.folders): add_row(col, 'path', icon='REMOVE', operator='bonewidget.remove_folder', data=f, properties={'index': i}) col.separator() split = col.split(factor=0.33, align=True) split.alignment= 'RIGHT' split.label(text='Auto:') col = split.column(align=True) add_bool_row(col, 'auto_symmetrize', name='Symmetrize', icon='MOD_MIRROR') add_bool_row(col, 'auto_separate', name='Separate', icon='UNLINKED') #col = row.column(align=True) add_bool_row(col, 'auto_match_transform', name='Match Transform', icon='TRANSFORM_ORIGINS') add_bool_row(col, 'auto_rename', name='Rename', icon='SYNTAX_OFF') #bpy.ops.wm.save_userpref() prefs_unsaved = bpy.context.preferences.is_dirty layout.operator('wm.save_userpref', text="Save Preferences" + (" *" if prefs_unsaved else "")) #col.prop(ctx.prefs, 'symmetrize', text='Symetrize', icon='MOD_MIRROR') #col.prop(ctx.prefs, 'separate', text='Separate', icon='UNLINKED') #col.prop(ctx.prefs, 'match_transform', text='Match Transform', icon='TRANSFORM_ORIGINS') #col.prop(ctx.prefs, 'rename', text='Rename', icon='SYNTAX_OFF') ''' layout.separator() split = layout.split(factor=0.33, align=True) split.alignment= 'RIGHT' split.label(text='Bone Colors:') #split.prop(ctx.prefs, 'use_custom_colors') col = split.column(align=True) row = col.row(align=True) row.prop(ctx.prefs, 'select_color', text='') row.prop(ctx.prefs, 'active_color', text='') row.separator() row.operator("bonewidget.add_color", icon='ADD', text='', emboss=False) #if ctx.prefs.use_custom_colors: col.separator() for i, c in enumerate(ctx.prefs.colors): add_color_row(col, data=c, index=i) ''' class BW_UL_widget(UIList): def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index, flt_flag): icon = data.get_widget_icon(item) icon_id = icon.icon_id if icon else -1 #layout.scale_x = 1.5 row = layout.row(align=True) row.use_property_split = False row.prop(item, 'name', text="", emboss=False, icon_value=icon_id) class BW_MT_folder(Menu): bl_label = "Folder Special Menu" def draw(self, context): layout = self.layout #layout.operator("bonewidget.add_folder", icon='ADD') #layout.operator("bonewidget.remove_folder", icon='REMOVE') #layout.operator("bonewidget.rename_folder", icon='SYNTAX_OFF') layout.operator('bonewidget.refresh_folders', icon='FILE_REFRESH') layout.operator('bonewidget.remove_unused_shape', icon='TRASH') #layout.operator('bonewidget.show_preferences', icon='PREFERENCES') layout.operator('bonewidget.copy_widgets', icon='COPYDOWN') layout.operator('bonewidget.paste_widgets', icon='PASTEDOWN') #layout.prop(ctx.prefs, 'grid_view') class BW_PT_transforms(Panel): bl_label = "Transforms" bl_category = ctx.category bl_space_type = 'VIEW_3D' bl_region_type = 'UI' bl_parent_id = 'BW_PT_main' bl_options = {'DEFAULT_CLOSED'} @classmethod def poll(cls, context): return ctx.show_transforms def draw_header(self, context): layout = self.layout layout.label(icon='EMPTY_ARROWS') def draw(self, context): layout = self.layout col = layout.column() transforms = ctx.prefs.transforms col.prop(transforms, "loc") col.prop(transforms, "rot") col.prop(transforms, "scale") class BW_PT_main(Panel): bl_label = "Bone Widget" bl_category = ctx.category bl_space_type = 'VIEW_3D' bl_region_type = 'UI' def get_nb_col(self, context) : icon_size = 35 if context.region.width < 100: return 1 _, y0 = context.region.view2d.region_to_view(0, 0) _, y1 = context.region.view2d.region_to_view(0, 10) region_scale = 10 / abs(y1 - y0) ui_scale = context.preferences.view.ui_scale cols = int((context.region.width - 48) / (ui_scale*region_scale*icon_size)) return max(1, cols) def draw(self, context): layout = self.layout row = layout.row() tool_col = row.column(align=True) tool_col.scale_x = 1.05 tool_col.scale_y = 1.05 tool_col.menu('BW_MT_folder', icon='TRIA_DOWN', text='') #tool_col.separator() tool_col.operator('bonewidget.add_widget', icon='ADD', text='') tool_col.operator('bonewidget.remove_widget', icon='REMOVE', text='') tool_col.separator() tool_col.separator() #if ctx.prefs.auto_symmetrize: # tool_col.operator('bonewidget.symmetrize_widget', icon='MOD_MIRROR', text='') op_col = tool_col.column(align=True) op_col.scale_y = 1.5 op_col.operator('bonewidget.transform_widget', icon='EMPTY_ARROWS', text='') # op_col.operator('bonewidget.clean_widget', icon='SHADERFX', text='') op_col.separator() tool_col.prop(ctx.prefs, 'show_preferences', icon='PREFERENCES', text='') folder = ctx.active_folder widget_col = row.column(align=True) folder_row = widget_col.row(align=True) folder_row.scale_y = 1.05 #folder_row.scale_y = 1.15 #folder_row.scale_x = 1.25 if len(ctx.folder_items) <= 3: folder_row.prop(ctx.prefs, 'folder_enum', expand=True) else: folder_row.prop(ctx.prefs, 'folder_enum', text='', icon='FILE_FOLDER') if folder: widget_col.template_list('BW_UL_widget', 'BW_widgets', folder, 'widgets', folder, 'widget_index', rows=6, columns=self.get_nb_col(context), type='DEFAULT') #widget_col.template_list('UI_UL_list', 'BW_widgets', folder, 'widgets', folder, 'widget_index', rows=4) #layout.prop(self, 'folder_enum') edit_row = widget_col.row(align=True) if context.mode in ('EDIT_MESH', 'OBJECT') and ctx.bone: edit_row.operator('bonewidget.return_to_rig', text='Return', icon='LOOP_BACK') else: edit_row.operator('bonewidget.create_widget', text='Create') edit_row.operator('bonewidget.edit_widget', text='Edit') # Draw Active Bone Shape if context.active_pose_bone: widget_col.separator() col = widget_col.column(align=False) col.use_property_split = True col.prop(context.active_pose_bone, 'name', text='Bone Name') col.prop(context.active_pose_bone, 'custom_shape', text='Widget') if ctx.prefs.use_custom_collection and ctx.rig: widget_col.separator() row = widget_col.row() row.use_property_split = True row.prop(ctx.rig.data, 'widget_collection', text='Widget Collection') if ctx.show_transforms: data = context.window_manager.operators[-1].properties layout.separator() #opt_box = layout.box() opt_col = layout.column(align=True) #opt_col.operator("bonewidget.match_transform",icon = 'GROUP_BONE') row = opt_col.row(align =True) row.label(text='Size :') row.operator("bonewidget.match_transform", text='Relative').relative = True row.operator("bonewidget.match_transform", text='Absolute').relative = False opt_col.separator() transforms = ctx.prefs.transforms opt_col.prop(transforms, "size") opt_col.prop(transforms, "xz_scale") opt_col.prop(transforms, "slide") elif ctx.clean_widget_op: data = ctx.clean_widget_op.properties #layout.separator() #opt_col = layout.column() elif ctx.prefs.show_preferences: #layout.separator() draw_prefs(layout) classes = ( BW_UL_widget, BW_MT_folder, BW_PT_main, BW_PT_transforms, ) def update_tab(): panels = (bpy.types.BW_PT_main, bpy.types.BW_PT_transforms) for p in panels: p.bl_category = ctx.prefs.category bpy.utils.unregister_class(p) for p in panels: bpy.utils.register_class(p) def register(): for cls in classes: bpy.utils.register_class(cls) update_tab() def unregister(): for cls in reversed(classes): bpy.utils.unregister_class(cls)