# from . import addon_updater_ops from .utils import get_addon_prefs import bpy from pathlib import Path ## UI in properties ### dataprop_panel not used --> transferred to sidebar """ class GPTB_PT_dataprop_panel(bpy.types.Panel): bl_space_type = 'PROPERTIES' bl_region_type = 'WINDOW' # bl_space_type = 'VIEW_3D' # bl_region_type = 'UI' # bl_category = "Tool" # bl_idname = "ADDONID_PT_panel_name"# identifier, if ommited, takes the name of the class. bl_label = "Pseudo color"# title bl_parent_id = "DATA_PT_gpencil_layers"#subpanel of this ID bl_options = {'DEFAULT_CLOSED'} def draw(self, context): layout = self.layout layout.use_property_split = True settings = context.scene.gptoolprops col = layout.column(align = True) row = col.split(align=False, factor=0.63) row.prop(settings, 'autotint_offset') row.prop(settings, 'autotint_namespace') col.operator("gp.auto_tint_gp_layers", icon = "COLOR").reset = False col.operator("gp.auto_tint_gp_layers", text = "Reset tint", icon = "COLOR").reset = True """ ## UI in Gpencil sidebar menu class GPTB_PT_sidebar_panel(bpy.types.Panel): bl_label = "GP Toolbox" bl_space_type = "VIEW_3D" bl_region_type = "UI" bl_category = "Gpencil" def draw(self, context): layout = self.layout # layout.use_property_split = True prefs = get_addon_prefs() rd = context.scene.render # check for update # addon_updater_ops.check_for_update_background() # layout.label(text='View options:') col = layout.column() ## flip X cam if context.scene.camera and context.scene.camera.scale.x < 0: # layout.label(text='! Flipped !') row = col.row(align=True) row.operator('gp.mirror_flipx', text = 'Mirror flip', icon = 'MOD_MIRROR')# ARROW_LEFTRIGHT row.label(text='',icon='LOOP_BACK') else: col.operator('gp.mirror_flipx', text = 'Mirror flip', icon = 'MOD_MIRROR')# ARROW_LEFTRIGHT ## draw/manipulation camera if context.scene.camera and context.scene.camera.name.startswith(('draw', 'obj')): row = col.row(align=True) row.operator('gp.draw_cam_switch', text = 'Main cam', icon = 'OUTLINER_OB_CAMERA') row.label(text='',icon='LOOP_BACK') if context.scene.camera.name.startswith('draw'): col.operator('gp.reset_cam_rot', text='reset rotation')#.swapmethod ? = CAM else: col.operator('gp.set_view_as_cam', text='set view')#.swapmethod ? = CAM else: row = col.row(align=True) row.operator('gp.draw_cam_switch', text = 'Draw cam', icon = 'CON_CAMERASOLVER').cam_mode = 'draw' row.operator('gp.draw_cam_switch', text = 'Object cam', icon = 'CON_CAMERASOLVER').cam_mode = 'object' col.label(text='In main camera', icon = 'OUTLINER_OB_CAMERA') # layout.operator('gp.overlay_presets', text = 'Toggle overlays', icon = 'OVERLAY') if context.scene.camera: row = layout.row(align=True)# .split(factor=0.5) row.label(text='Passepartout') if context.scene.camera.name == 'draw_cam': row.prop(context.scene.gptoolprops, 'drawcam_passepartout', text='', icon ='OBJECT_HIDDEN') else: row.prop(context.scene.camera.data, 'show_passepartout', text='', icon ='OBJECT_HIDDEN') row.prop(context.scene.camera.data, 'passepartout_alpha', text='') row = layout.row(align=True) row.operator('view3d.zoom_camera_1_to_1', text = 'Zoom 1:1', icon = 'ZOOM_PREVIOUS') # FULLSCREEN_EXIT row.operator('view3d.view_center_camera', text = 'Zoom fit', icon = 'FULLSCREEN_ENTER') ## background images/videos if context.scene.camera.data.background_images: layout.separator() icon_bg = 'RESTRICT_VIEW_OFF' if context.scene.camera.data.show_background_images else 'RESTRICT_VIEW_ON'# IMAGE_BACKGROUND#IMAGE_PLANE # icon_bg = 'TRIA_DOWN' if context.scene.camera.data.show_background_images else 'IMAGE_BACKGROUND' box = layout.box() box.prop(context.scene.camera.data, 'show_background_images', text='Ref in cam', icon=icon_bg) if context.scene.camera.data.show_background_images: # box = layout.box() for bg_img in context.scene.camera.data.background_images: if bg_img.source == 'IMAGE' and bg_img.image: row = box.row(align=True) row.prop(bg_img, 'show_background_image', text='', icon='IMAGE_RGB') row.prop(bg_img, 'alpha', text=bg_img.image.name) # options={'HIDDEN'} # row.label(icon='IMAGE_RGB') # icon = 'HIDE_OFF' if bg_img.show_background_image else 'HIDE_ON' # row.prop(bg_img, 'show_background_image', text='', icon=icon) if bg_img.source == 'MOVIE_CLIP' and bg_img.clip: row = box.row(align=True) row.prop(bg_img, 'show_background_image', text='', icon='FILE_MOVIE') row.prop(bg_img, 'alpha', text=bg_img.clip.name) # options={'HIDDEN'} # row.label(icon='FILE_MOVIE') # icon = 'HIDE_OFF' if bg_img.show_background_image else 'HIDE_ON' # row.prop(bg_img, 'show_background_image', text='', icon=icon) else: layout.label(text='No camera !', icon = 'ERROR') ## Straight line ops from official greasepencil_tools addon if enabled. # if any(x in context.preferences.addons.keys() for x in ('greasepencil_tools', 'greasepencil-addon')): # check enabled addons if hasattr(bpy.types, 'GP_OT_straight_stroke'): # check if operator exists : bpy.ops.gp.straight_stroke.idname() layout.operator('gp.straight_stroke', icon ="CURVE_PATH") ## Options col = layout.column() col.label(text = 'Options:') ## Kf Jump filter col.prop(context.scene.gptoolprops, 'keyframe_type', text='Jump On') # Keyframe Jump # col.prop(context.space_data.overlay, 'use_gpencil_onion_skin') # not often used if context.object and context.object.type == 'GPENCIL': # col.prop(context.object.data, 'use_autolock_layers') # not often used col.prop(context.object, 'show_in_front', text='X-ray') # default text "In Front" ## rename datablock temporary layout if context.object.name != context.object.data.name: box = col.box() box.label(text='different name for object and data:', icon='INFO') row = box.row(align=False) row.operator('gp.rename_data_from_obj').rename_all = False row.operator('gp.rename_data_from_obj', text='Rename all').rename_all = True ## Check base palette if prefs.warn_base_palette and prefs.palette_path: if not all(x in [m.name for m in context.object.data.materials if m] for x in ("line", "invisible")): box = col.box() box.label(text='Missing base material setup', icon='INFO') box.operator('gp.load_default_palette') else: col.label(text='No GP object selected') col.prop(context.scene.gptoolprops, 'edit_lines_opacity') # Mention update as notice # addon_updater_ops.update_notice_box_ui(self, context) # row = layout.row(align=False) # row.label(text='arrow choice') # row.operator("my_operator.multi_op", text='', icon='TRIA_LEFT').left = 1 # row.operator("my_operator.multi_op", text='', icon='TRIA_RIGHT').left = 0 class GPTB_PT_anim_manager(bpy.types.Panel): bl_label = "Animation Manager" bl_space_type = "VIEW_3D" bl_region_type = "UI" bl_category = "Gpencil" bl_parent_id = "GPTB_PT_sidebar_panel" bl_options = {'DEFAULT_CLOSED'} # def draw_header(self,context): # self.layout.prop(context.scene.camera.data, "show_background_images", text="") def draw(self, context): layout = self.layout layout.use_property_split = True col = layout.column() ## Animation enable disable anim (shift click to select) OP_helpers.GPTB_OT_toggle_mute_animation col.operator('gp.list_disabled_anims') ## Objs () row = col.row(align=True) row.label(text='Obj anims:') ops = row.operator('gp.toggle_mute_animation', text = 'ON')#, icon = 'GRAPH' ops.skip_gp = True ops.skip_obj = False ops.mute = False ops = row.operator('gp.toggle_mute_animation', text = 'OFF')#, icon = 'GRAPH' ops.skip_gp = True ops.skip_obj = False ops.mute = True ## GPs row = col.row(align=True) row.label(text='Gp anims:') ops = row.operator('gp.toggle_mute_animation', text = 'ON')#, icon = 'GRAPH' ops.skip_gp = False ops.skip_obj = True ops.mute = False ops = row.operator('gp.toggle_mute_animation', text = 'OFF')#, icon = 'GRAPH' ops.skip_gp = False ops.skip_obj = True ops.mute = True ## GP modifiers row = col.row(align=True) row.label(text='Gp modifiers:') row.operator('gp.toggle_hide_gp_modifier', text = 'ON').show = True row.operator('gp.toggle_hide_gp_modifier', text = 'OFF').show = False ## This can go in an extra category... col = layout.column() col.use_property_split = False text, icon = ('Cursor Follow On', 'PIVOT_CURSOR') if context.scene.gptoolprops.cursor_follow else ('Cursor Follow Off', 'CURSOR') col.prop(context.scene.gptoolprops, 'cursor_follow', text=text, icon=icon) class GPTB_PT_toolbox_playblast(bpy.types.Panel): bl_label = "Playblast" bl_space_type = "VIEW_3D" bl_region_type = "UI" bl_category = "Gpencil" bl_parent_id = "GPTB_PT_sidebar_panel" bl_options = {'DEFAULT_CLOSED'} def draw(self, context): layout = self.layout rd = context.scene.render row = layout.row(align=False) # split(factor=0.6) percent = context.scene.gptoolprops.resolution_percentage row.label(text = f'{rd.resolution_x * percent // 100} x {rd.resolution_y * percent // 100}') row.prop(context.scene.gptoolprops, 'resolution_percentage', text='') # row.prop(rd, 'resolution_percentage', text='') # real percent scene percentage row = layout.row(align=True) row.operator('render.thread_playblast', text = 'Playblast', icon = 'RENDER_ANIMATION')# non blocking background render playblast # row.operator('render.playblast_anim', text = 'Playblast', icon = 'RENDER_ANIMATION').use_view = False # old (but robust) blocking playblast row.operator('render.playblast_anim', text = 'Viewport').use_view = True class GPTB_PT_tint_layers(bpy.types.Panel): bl_label = "Tint Layers" bl_space_type = "VIEW_3D" bl_region_type = "UI" bl_category = "Gpencil" bl_parent_id = "GPTB_PT_sidebar_panel" bl_options = {'DEFAULT_CLOSED'} # def draw_header(self,context): # self.layout.prop(context.scene.camera.data, "show_background_images", text="") def draw(self, context): layout = self.layout layout.use_property_split = True ## pseudo color layers # layout.separator() col = layout.column(align = True) row = col.split(align=False, factor=0.63) row.prop(context.scene.gptoolprops, 'autotint_offset') row.prop(context.scene.gptoolprops, 'autotint_namespace') col.operator("gp.auto_tint_gp_layers", icon = "COLOR").reset = False col.operator("gp.auto_tint_gp_layers", text = "Reset tint", icon = "COLOR").reset = True class GPTB_PT_checker(bpy.types.Panel): bl_label = "Checker" bl_space_type = "VIEW_3D" bl_region_type = "UI" bl_category = "Gpencil" bl_parent_id = "GPTB_PT_sidebar_panel" bl_options = {'DEFAULT_CLOSED'} # def draw_header(self,context): # self.layout.prop(context.scene.camera.data, "show_background_images", text="") def draw(self, context): layout = self.layout col = layout.column() row = col.row(align=True) ## realign / reproject row.operator('gp.realign', icon='AXIS_FRONT') ## move in depth row.operator('object.depth_proportional_move', text='Depth move', icon='TRANSFORM_ORIGINS') ## col.operator('gp.batch_reproject_all_frames') # text=Batch Reproject # added to context menu ## check drawing alignement col.operator('gp.check_canvas_alignement', icon='DRIVER_ROTATIONAL_DIFFERENCE') ## File checker row = col.row(align=True) row.operator('gp.file_checker', text = 'Check file', icon = 'SCENE_DATA') row.operator('gp.links_checker', text = 'Check links', icon = 'UNLINKED') class GPTB_PT_color(bpy.types.Panel): bl_label = "Color" bl_space_type = "VIEW_3D" bl_region_type = "UI" bl_category = "Gpencil" bl_parent_id = "GPTB_PT_sidebar_panel" bl_options = {'DEFAULT_CLOSED'} def draw(self, context): layout = self.layout ## Create empty frame on layer layout.operator('gp.create_empty_frames', icon='DECORATE_KEYFRAME') """ # unused : added in Animation Manager class GPTB_PT_extra(bpy.types.Panel): bl_label = "Extra" bl_space_type = "VIEW_3D" bl_region_type = "UI" bl_category = "Gpencil" bl_parent_id = "GPTB_PT_sidebar_panel" bl_options = {'DEFAULT_CLOSED'} def draw(self, context): layout = self.layout col = layout.column() text, icon = ('Cursor Follow On', 'PIVOT_CURSOR') if context.scene.gptoolprops.cursor_follow else ('Cursor Follow Off', 'CURSOR') col.prop(context.scene.gptoolprops, 'cursor_follow', text=text, icon=icon) """ """ ## unused -- (integrated in sidebar_panel) class GPTB_PT_cam_ref_panel(bpy.types.Panel): bl_label = "Background imgs" bl_space_type = "VIEW_3D" bl_region_type = "UI" bl_category = "Gpencil" bl_parent_id = "GPTB_PT_sidebar_panel" @classmethod def poll(cls, context): return context.scene.camera def draw_header(self,context): self.layout.prop(context.scene.camera.data, "show_background_images", text="") def draw(self, context): layout = self.layout layout.use_property_split = True if context.scene.camera.data.show_background_images: for bg_img in context.scene.camera.data.background_images: if bg_img.image: row = layout.row(align=False) row.label(text=bg_img.image.name, icon='IMAGE_RGB') row.prop(bg_img, 'show_background_image', text='')# options={'HIDDEN'} """ def palette_manager_menu(self, context): """Palette menu to append in existing menu""" # GPENCIL_MT_material_context_menu layout = self.layout # {'EDIT_GPENCIL', 'PAINT_GPENCIL','SCULPT_GPENCIL','WEIGHT_GPENCIL', 'VERTEX_GPENCIL'} layout.separator() prefs = get_addon_prefs() layout.operator("gp.copy_active_to_selected_palette", text='Append Materials To Selected', icon='MATERIAL') layout.operator("gp.load_palette", text='Load json Palette', icon='IMPORT').filepath = prefs.palette_path layout.operator("gp.save_palette", text='Save json Palette', icon='EXPORT').filepath = prefs.palette_path layout.operator("gp.load_blend_palette", text='Load color Palette', icon='COLOR').filepath = prefs.palette_path layout.operator("gp.clean_material_stack", text='Clean material Stack', icon='NODE_MATERIAL') classes = ( GPTB_PT_sidebar_panel, GPTB_PT_checker, GPTB_PT_anim_manager, GPTB_PT_color, GPTB_PT_tint_layers, GPTB_PT_toolbox_playblast, # GPTB_PT_extra, ) def register(): for cls in classes: bpy.utils.register_class(cls) bpy.types.GPENCIL_MT_material_context_menu.append(palette_manager_menu) def unregister(): bpy.types.GPENCIL_MT_material_context_menu.remove(palette_manager_menu) for cls in reversed(classes): bpy.utils.unregister_class(cls) """ ## direct panel def append (no submenu with arrow) ## need to use append and remove in register/unregister # bpy.types.DATA_PT_gpencil_layers.append(UI_tools.GPdata_toolbox_panel) # bpy.types.DATA_PT_gpencil_layers.remove(UI_tools.GPdata_toolbox_panel) def GPdata_toolbox_panel(self, context): layout = self.layout layout.use_property_split = True settings = context.scene.gptoolprops col = layout.column(align = True) col.prop(settings, 'autotint_offset') col.operator("gp.auto_tint_gp_layers", icon = "COLOR").reset = False col.operator("gp.auto_tint_gp_layers", text = "Reset tint", icon = "COLOR").reset = True """ ### old """ col = layout.column(align = True) col.operator("gpencil.stroke_change_color", text="Move to Color",icon = "COLOR") col.operator("transform.shear", text="Shear") col.operator("gpencil.stroke_cyclical_set", text="Toggle Cyclic").type = 'TOGGLE' col.operator("gpencil.stroke_subdivide", text="Subdivide",icon = "OUTLINER_DATA_MESH") row = layout.row(align = True) row.operator("gpencil.stroke_join", text="Join").type = 'JOIN' row.operator("grease_pencil.stroke_separate", text = "Separate") col.operator("gpencil.stroke_flip", text="Flip Direction",icon = "ARROW_LEFTRIGHT") col = layout.column(align = True) col.operator("gptools.randomise",icon = 'RNDCURVE') col.operator("gptools.thickness",icon = 'LINE_DATA') col.operator("gptools.angle_split",icon = 'MOD_BEVEL',text='Angle Splitting') col.operator("gptools.stroke_uniform_density",icon = 'MESH_DATA',text = 'Density') row = layout.row(align = True) row.prop(settings,"extra_tools",text='',icon = "DOWNARROW_HLT" if settings.extra_tools else "RIGHTARROW",emboss = False) row.label("Extra tools") if settings.extra_tools : layout.operator_menu_enum("gpencil.stroke_arrange", text="Arrange Strokes...", property="direction") """