Removed UI for point cache users.
[blender.git] / release / scripts / startup / bl_ui / properties_grease_pencil_common.py
index e86fc79e343e3df719e5dcf9b966f8853a75c43d..013f4e648547f5157d5047ca0d2e43cb0116cfaf 100644 (file)
 from bpy.types import Menu, UIList
 
 
-def gpencil_stroke_placement_settings(context, layout, gpd):
+def gpencil_stroke_placement_settings(context, layout):
+    if context.space_data.type == 'VIEW_3D':
+        propname = "gpencil_stroke_placement_view3d"
+    elif context.space_data.type == 'SEQUENCE_EDITOR':
+        propname = "gpencil_stroke_placement_sequencer_preview"
+    elif context.space_data.type == 'IMAGE_EDITOR':
+        propname = "gpencil_stroke_placement_image_editor"
+    else:
+        propname = "gpencil_stroke_placement_view2d"
+
+    ts = context.tool_settings
+
     col = layout.column(align=True)
 
     col.label(text="Stroke Placement:")
 
     row = col.row(align=True)
-    row.prop_enum(gpd, "draw_mode", 'VIEW')
-    row.prop_enum(gpd, "draw_mode", 'CURSOR')
+    row.prop_enum(ts, propname, 'VIEW')
+    row.prop_enum(ts, propname, 'CURSOR')
 
     if context.space_data.type == 'VIEW_3D':
         row = col.row(align=True)
-        row.prop_enum(gpd, "draw_mode", 'SURFACE')
-        row.prop_enum(gpd, "draw_mode", 'STROKE')
+        row.prop_enum(ts, propname, 'SURFACE')
+        row.prop_enum(ts, propname, 'STROKE')
 
         row = col.row(align=False)
-        row.active = gpd.draw_mode in {'SURFACE', 'STROKE'}
-        row.prop(gpd, "use_stroke_endpoints")
+        row.active = getattr(ts, propname) in {'SURFACE', 'STROKE'}
+        row.prop(ts, "use_gpencil_stroke_endpoints")
 
 
 class GreasePencilDrawingToolsPanel:
@@ -56,15 +67,19 @@ class GreasePencilDrawingToolsPanel:
 
         col.label(text="Draw:")
         row = col.row(align=True)
-        row.operator("gpencil.draw", text="Draw").mode = 'DRAW'
-        row.operator("gpencil.draw", text="Erase").mode = 'ERASER'
+        row.operator("gpencil.draw", icon='GREASEPENCIL', text="Draw").mode = 'DRAW'
+        row.operator("gpencil.draw", icon='FORCE_CURVE', text="Erase").mode = 'ERASER'  # XXX: Needs a dedicated icon
 
         row = col.row(align=True)
-        row.operator("gpencil.draw", text="Line").mode = 'DRAW_STRAIGHT'
-        row.operator("gpencil.draw", text="Poly").mode = 'DRAW_POLY'
+        row.operator("gpencil.draw", icon='LINE_DATA', text="Line").mode = 'DRAW_STRAIGHT'
+        row.operator("gpencil.draw", icon='MESH_DATA', text="Poly").mode = 'DRAW_POLY'
 
-        row = col.row(align=True)
-        row.prop(context.tool_settings, "use_grease_pencil_sessions", text="Continuous Drawing")
+        sub = col.column(align=True)
+        sub.prop(context.tool_settings, "use_gpencil_additive_drawing", text="Additive Drawing")
+        sub.prop(context.tool_settings, "use_gpencil_continuous_drawing", text="Continuous Drawing")
+
+        col.separator()
+        col.separator()
 
         if context.space_data.type in {'VIEW_3D', 'CLIP_EDITOR'}:
             col.separator()
@@ -75,10 +90,19 @@ class GreasePencilDrawingToolsPanel:
             elif context.space_data.type == 'CLIP_EDITOR':
                 row.prop(context.space_data, "grease_pencil_source", expand=True)
 
+        col.separator()
+        col.separator()
+
+        gpencil_stroke_placement_settings(context, col)
+
         gpd = context.gpencil_data
+
         if gpd:
-            col.separator()
-            gpencil_stroke_placement_settings(context, col, gpd)
+            layout.separator()
+            layout.separator()
+
+            col = layout.column(align=True)
+            col.prop(gpd, "use_stroke_edit_mode", text="Enable Editing", icon='EDIT', toggle=True)
 
         if context.space_data.type == 'VIEW_3D':
             col.separator()
@@ -95,67 +119,110 @@ class GreasePencilStrokeEditPanel:
     bl_label = "Edit Strokes"
     bl_category = "Grease Pencil"
     bl_region_type = 'TOOLS'
+    bl_options = {'DEFAULT_CLOSED'}
 
     @classmethod
     def poll(cls, context):
-        return (context.gpencil_data is not None)
+        if context.gpencil_data is None:
+            return False
+
+        gpd = context.gpencil_data
+        return bool(context.editable_gpencil_strokes) and bool(gpd.use_stroke_edit_mode)
 
     @staticmethod
     def draw(self, context):
         layout = self.layout
 
-        gpd = context.gpencil_data
-        edit_ok = bool(context.editable_gpencil_strokes) and bool(gpd.use_stroke_edit_mode)
+        layout.label(text="Select:")
+        col = layout.column(align=True)
+        col.operator("gpencil.select_all", text="Select All")
+        col.operator("gpencil.select_border")
+        col.operator("gpencil.select_circle")
+
+        layout.separator()
 
         col = layout.column(align=True)
-        col.prop(gpd, "use_stroke_edit_mode", text="Enable Editing", icon='EDIT', toggle=True)
+        col.operator("gpencil.select_linked")
+        col.operator("gpencil.select_more")
+        col.operator("gpencil.select_less")
 
-        col.separator()
+        layout.separator()
 
-        col.label(text="Select:")
-        subcol = col.column(align=True)
-        subcol.active = edit_ok
-        subcol.operator("gpencil.select_all", text="Select All")
-        subcol.operator("gpencil.select_border")
-        subcol.operator("gpencil.select_circle")
+        layout.label(text="Edit:")
+        row = layout.row(align=True)
+        row.operator("gpencil.copy", text="Copy")
+        row.operator("gpencil.paste", text="Paste")
 
-        col.separator()
+        col = layout.column(align=True)
+        col.operator("gpencil.delete", text="Delete")
+        col.operator("gpencil.duplicate_move", text="Duplicate")
+        col.operator("transform.mirror", text="Mirror")
 
-        subcol = col.column(align=True)
-        subcol.active = edit_ok
-        subcol.operator("gpencil.select_linked")
-        subcol.operator("gpencil.select_more")
-        subcol.operator("gpencil.select_less")
+        layout.separator()
 
-        col.separator()
+        col = layout.column(align=True)
+        col.operator("transform.translate")                # icon='MAN_TRANS'
+        col.operator("transform.rotate")                   # icon='MAN_ROT'
+        col.operator("transform.resize", text="Scale")     # icon='MAN_SCALE'
 
-        col.label(text="Edit:")
-        row = col.row(align=True)
-        row.active = edit_ok
-        row.operator("gpencil.copy", text="Copy")
-        row.operator("gpencil.paste", text="Paste")
+        layout.separator()
 
-        subcol = col.column(align=True)
-        subcol.active = edit_ok
-        subcol.operator("gpencil.delete", text="Delete")
-        subcol.operator("gpencil.duplicate_move", text="Duplicate")
-        subcol.operator("transform.mirror", text="Mirror").gpencil_strokes = True
+        col = layout.column(align=True)
+        col.operator("transform.bend", text="Bend")
+        col.operator("transform.shear", text="Shear")
+        col.operator("transform.tosphere", text="To Sphere")
 
-        col.separator()
 
-        subcol = col.column(align=True)
-        subcol.active = edit_ok
-        subcol.operator("transform.translate").gpencil_strokes = True   # icon='MAN_TRANS'
-        subcol.operator("transform.rotate").gpencil_strokes = True      # icon='MAN_ROT'
-        subcol.operator("transform.resize", text="Scale").gpencil_strokes = True      # icon='MAN_SCALE'
+class GreasePencilStrokeSculptPanel:
+    # subclass must set
+    # bl_space_type = 'IMAGE_EDITOR'
+    bl_label = "Sculpt Strokes"
+    bl_category = "Grease Pencil"
+    bl_region_type = 'TOOLS'
 
-        col.separator()
+    @classmethod
+    def poll(cls, context):
+        if context.gpencil_data is None:
+            return False
+
+        gpd = context.gpencil_data
+        return bool(context.editable_gpencil_strokes) and bool(gpd.use_stroke_edit_mode)
+
+    @staticmethod
+    def draw(self, context):
+        layout = self.layout
+
+        settings = context.tool_settings.gpencil_sculpt
+        tool = settings.tool
+        brush = settings.brush
 
-        subcol = col.column(align=True)
-        subcol.active = edit_ok
-        subcol.operator("transform.bend", text="Bend").gpencil_strokes = True
-        subcol.operator("transform.shear", text="Shear").gpencil_strokes = True
-        subcol.operator("transform.tosphere", text="To Sphere").gpencil_strokes = True
+        layout.column().prop(settings, "tool", expand=True)
+
+        col = layout.column()
+        col.prop(brush, "size", slider=True)
+        row = col.row(align=True)
+        row.prop(brush, "strength", slider=True)
+        row.prop(brush, "use_pressure_strength", text="")
+        col.prop(brush, "use_falloff")
+
+        layout.separator()
+
+        if settings.tool == 'THICKNESS':
+            layout.row().prop(brush, "direction", expand=True)
+        elif settings.tool == 'PINCH':
+            row = layout.row(align=True)
+            row.prop_enum(brush, "direction", 'ADD', text="Pinch")
+            row.prop_enum(brush, "direction", 'SUBTRACT', text="Inflate")
+        elif settings.tool == 'TWIST':
+            row = layout.row(align=True)
+            row.prop_enum(brush, "direction", 'SUBTRACT', text="CW")
+            row.prop_enum(brush, "direction", 'ADD', text="CCW")
+
+        layout.separator()
+        layout.prop(settings, "use_select_mask")
+
+        if settings.tool == 'SMOOTH':
+            layout.prop(brush, "affect_pressure")
 
 
 ###############################
@@ -190,14 +257,14 @@ class GPENCIL_PIE_tool_palette(Menu):
         if gpd:
             if gpd.use_stroke_edit_mode and context.editable_gpencil_strokes:
                 # S - Exit Edit Mode
-                pie.prop(gpd, "use_stroke_edit_mode", text="Exit Edit Mode", icon='EDIT')
+                pie.operator("gpencil.editmode_toggle", text="Exit Edit Mode", icon='EDIT')
 
                 # N - Transforms
                 col = pie.column()
                 row = col.row(align=True)
-                row.operator("transform.translate", icon='MAN_TRANS').gpencil_strokes = True
-                row.operator("transform.rotate", icon='MAN_ROT').gpencil_strokes = True
-                row.operator("transform.resize", text="Scale", icon='MAN_SCALE').gpencil_strokes = True
+                row.operator("transform.translate", icon='MAN_TRANS')
+                row.operator("transform.rotate", icon='MAN_ROT')
+                row.operator("transform.resize", text="Scale", icon='MAN_SCALE')
                 row = col.row(align=True)
                 row.label("Proportional Edit:")
                 row.prop(context.tool_settings, "proportional_edit", text="", icon_only=True)
@@ -224,7 +291,7 @@ class GPENCIL_PIE_tool_palette(Menu):
                 pie.operator("wm.call_menu_pie", text="More...").name = "GPENCIL_PIE_tools_more"
             else:
                 # Toggle Edit Mode
-                pie.prop(gpd, "use_stroke_edit_mode", text="Enable Stroke Editing", icon='EDIT')
+                pie.operator("gpencil.editmode_toggle", text="Enable Stroke Editing", icon='EDIT')
 
 
 class GPENCIL_PIE_settings_palette(Menu):
@@ -261,11 +328,15 @@ class GPENCIL_PIE_settings_palette(Menu):
         col.prop(gpl, "use_onion_skinning")
 
         # N - Active Layer
-        # XXX: this should show an operator to change the active layer instead
         col = pie.column()
         col.label("Active Layer:      ")
-        col.prop(gpl, "info", text="")
-        # col.prop(gpd, "layers")
+
+        row = col.row()
+        row.operator_context = 'EXEC_REGION_WIN'
+        row.operator_menu_enum("gpencil.layer_change", "layer", text="", icon='GREASEPENCIL')
+        row.prop(gpl, "info", text="")
+        row.operator("gpencil.layer_remove", text="", icon='X')
+
         row = col.row()
         row.prop(gpl, "lock")
         row.prop(gpl, "hide")
@@ -294,15 +365,82 @@ class GPENCIL_PIE_tools_more(Menu):
         col.operator("gpencil.select_more", icon='ZOOMIN')
         col.operator("gpencil.select_less", icon='ZOOMOUT')
 
-        pie.operator("transform.mirror", icon='MOD_MIRROR').gpencil_strokes = True
-        pie.operator("transform.bend", icon='MOD_SIMPLEDEFORM').gpencil_strokes = True
-        pie.operator("transform.shear", icon='MOD_TRIANGULATE').gpencil_strokes = True
-        pie.operator("transform.tosphere", icon='MOD_MULTIRES').gpencil_strokes = True
+        pie.operator("transform.mirror", icon='MOD_MIRROR')
+        pie.operator("transform.bend", icon='MOD_SIMPLEDEFORM')
+        pie.operator("transform.shear", icon='MOD_TRIANGULATE')
+        pie.operator("transform.tosphere", icon='MOD_MULTIRES')
 
         pie.operator("gpencil.convert", icon='OUTLINER_OB_CURVE', text="Convert...")
         pie.operator("wm.call_menu_pie", text="Back to Main Palette...").name = "GPENCIL_PIE_tool_palette"
 
 
+class GPENCIL_PIE_sculpt(Menu):
+    """A pie menu for accessing Grease Pencil stroke sculpting settings"""
+    bl_label = "Grease Pencil Sculpt"
+
+    @classmethod
+    def poll(cls, context):
+        gpd = context.gpencil_data
+        return bool(gpd and gpd.use_stroke_edit_mode and context.editable_gpencil_strokes)
+
+    def draw(self, context):
+        layout = self.layout
+
+        pie = layout.menu_pie()
+
+        settings = context.tool_settings.gpencil_sculpt
+        brush = settings.brush
+
+        # W - Launch Sculpt Mode
+        col = pie.column()
+        # col.label("Tool:")
+        col.prop(settings, "tool", text="")
+        col.operator("gpencil.brush_paint", text="Sculpt", icon='SCULPTMODE_HLT')
+
+        # E - Common Settings
+        col = pie.column(align=True)
+        col.prop(brush, "size", slider=True)
+        row = col.row(align=True)
+        row.prop(brush, "strength", slider=True)
+        # row.prop(brush, "use_pressure_strength", text="", icon_only=True)
+        col.prop(brush, "use_falloff")
+
+        # S - Change Brush Type Shortcuts
+        row = pie.row()
+        row.prop_enum(settings, "tool", value='GRAB')
+        row.prop_enum(settings, "tool", value='PUSH')
+        row.prop_enum(settings, "tool", value='CLONE')
+
+        # N - Change Brush Type Shortcuts
+        row = pie.row()
+        row.prop_enum(settings, "tool", value='SMOOTH')
+        row.prop_enum(settings, "tool", value='THICKNESS')
+        row.prop_enum(settings, "tool", value='RANDOMIZE')
+
+
+###############################
+
+
+class GPENCIL_MT_snap(Menu):
+    bl_label = "Snap"
+
+    def draw(self, context):
+        layout = self.layout
+
+        layout.operator("gpencil.snap_to_grid", text="Selection to Grid")
+        layout.operator("gpencil.snap_to_cursor", text="Selection to Cursor").use_offset = False
+        layout.operator("gpencil.snap_to_cursor", text="Selection to Cursor (Offset)").use_offset = True
+
+        layout.separator()
+
+        layout.operator("gpencil.snap_cursor_to_selected", text="Cursor to Selected")
+        layout.operator("view3d.snap_cursor_to_center", text="Cursor to Center")
+        layout.operator("view3d.snap_cursor_to_grid", text="Cursor to Grid")
+
+
+###############################
+
+
 class GPENCIL_UL_layer(UIList):
     def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
         # assert(isinstance(item, bpy.types.GPencilLayer)
@@ -326,6 +464,25 @@ class GPENCIL_UL_layer(UIList):
             layout.label(text="", icon_value=icon)
 
 
+class GPENCIL_MT_layer_specials(Menu):
+    bl_label = "Layer"
+
+    def draw(self, context):
+        layout = self.layout
+
+        layout.operator("gpencil.layer_duplicate", icon='COPY_ID')  # XXX: needs a dedicated icon
+
+        layout.separator()
+
+        layout.operator("gpencil.reveal", icon='RESTRICT_VIEW_OFF', text="Show All")
+        layout.operator("gpencil.hide", icon='RESTRICT_VIEW_ON', text="Hide Others").unselected = True
+
+        layout.separator()
+
+        layout.operator("gpencil.lock_all", icon='LOCKED', text="Lock All")
+        layout.operator("gpencil.unlock_all", icon='UNLOCKED', text="UnLock All")
+
+
 class GreasePencilDataPanel:
     # subclass must set
     # bl_space_type = 'IMAGE_EDITOR'
@@ -354,7 +511,9 @@ class GreasePencilDataPanel:
         layout.template_ID(gpd_owner, "grease_pencil", new="gpencil.data_add", unlink="gpencil.data_unlink")
 
         # Grease Pencil data...
-        if gpd:
+        if (gpd is None) or (not gpd.layers):
+            layout.operator("gpencil.layer_add", text="New Layer")
+        else:
             self.draw_layers(context, layout, gpd)
 
     def draw_layers(self, context, layout, gpd):
@@ -375,7 +534,7 @@ class GreasePencilDataPanel:
 
         gpl = context.active_gpencil_layer
         if gpl:
-            sub.operator("gpencil.layer_duplicate", icon='COPY_ID', text="")  # XXX: needs a dedicated icon
+            sub.menu("GPENCIL_MT_layer_specials", icon='DOWNARROW_HLT', text="")
 
             if len(gpd.layers) > 1:
                 col.separator()
@@ -384,6 +543,12 @@ class GreasePencilDataPanel:
                 sub.operator("gpencil.layer_move", icon='TRIA_UP', text="").type = 'UP'
                 sub.operator("gpencil.layer_move", icon='TRIA_DOWN', text="").type = 'DOWN'
 
+                col.separator()
+
+                sub = col.column(align=True)
+                sub.operator("gpencil.layer_isolate", icon='SOLO_OFF', text="").affect_visibility = False
+                sub.operator("gpencil.layer_isolate", icon='RESTRICT_VIEW_OFF', text="").affect_visibility = True
+
         if gpl:
             self.draw_layer(layout, gpl)
 
@@ -457,6 +622,13 @@ class GreasePencilDataPanel:
         row.prop(gpl, "after_color", text="")
         sub.prop(gpl, "ghost_after_range", text="After")
 
+        # Smooth and subdivide new strokes
+        layout.separator()
+        col = layout.column(align=True)
+        col.label(text="New Stroke Quality:")
+        col.prop(gpl, "pen_smooth_factor")
+        col.prop(gpl, "pen_subdivision_steps")
+
 
 class GreasePencilToolsPanel:
     # subclass must set
@@ -488,4 +660,4 @@ class GreasePencilToolsPanel:
         layout.separator()
         layout.separator()
 
-        gpencil_stroke_placement_settings(context, layout, gpd)
+        gpencil_stroke_placement_settings(context, layout)