diff --git a/release/scripts/startup/bl_ui/properties_data_gpencil.py b/release/scripts/startup/bl_ui/properties_data_gpencil.py index e0a43a5fccc..883673ffd7a 100644 --- a/release/scripts/startup/bl_ui/properties_data_gpencil.py +++ b/release/scripts/startup/bl_ui/properties_data_gpencil.py @@ -21,6 +21,12 @@ import bpy from bpy.types import Menu, Panel, UIList from rna_prop_ui import PropertyPanel +from bl_ui.properties_grease_pencil_common import ( + GreasePencilLayerAdjustmentsPanel, + GreasePencilLayerRelationsPanel, + GreasePencilLayerDisplayPanel, +) + ############################### # Base-Classes (for shared stuff - e.g. poll, attributes, etc.) @@ -152,8 +158,8 @@ class DATA_PT_gpencil_layers(DataButtonsPanel, Panel): col.separator() sub = col.column(align=True) - sub.operator("gpencil.layer_isolate", icon='LOCKED', text="").affect_visibility = False sub.operator("gpencil.layer_isolate", icon='RESTRICT_VIEW_ON', text="").affect_visibility = True + sub.operator("gpencil.layer_isolate", icon='LOCKED', text="").affect_visibility = False # Layer main properties row = layout.row() @@ -173,83 +179,23 @@ class DATA_PT_gpencil_layers(DataButtonsPanel, Panel): col.prop(gpl, "opacity", text="Opacity", slider=True) -class DATA_PT_gpencil_layer_adjustments(LayerDataButtonsPanel, Panel): +class DATA_PT_gpencil_layer_adjustments(LayerDataButtonsPanel, GreasePencilLayerAdjustmentsPanel, Panel): bl_label = "Adjustments" bl_parent_id = 'DATA_PT_gpencil_layers' bl_options = {'DEFAULT_CLOSED'} - def draw(self, context): - layout = self.layout - layout.use_property_split = True - scene = context.scene - gpd = context.gpencil - gpl = gpd.layers.active - layout.active = not gpl.lock - - # Layer options - # Offsets - Color Tint - layout.enabled = not gpl.lock - col = layout.column(align=True) - col.prop(gpl, "tint_color") - col.prop(gpl, "tint_factor", text="Factor", slider=True) - - # Offsets - Thickness - col = layout.row(align=True) - col.prop(gpl, "line_change", text="Stroke Thickness") - - col = layout.row(align=True) - col.prop(gpl, "pass_index") - - col = layout.row(align=True) - col.prop_search(gpl, "viewlayer_render", scene, "view_layers", text="View Layer") - - col = layout.row(align=True) - col.prop(gpl, "lock_material") - - -class DATA_PT_gpencil_layer_relations(LayerDataButtonsPanel, Panel): +class DATA_PT_gpencil_layer_relations(LayerDataButtonsPanel, GreasePencilLayerRelationsPanel, Panel): bl_label = "Relations" bl_parent_id = 'DATA_PT_gpencil_layers' bl_options = {'DEFAULT_CLOSED'} - def draw(self, context): - layout = self.layout - layout.use_property_split = True - layout.use_property_decorate = False - gpd = context.gpencil - gpl = gpd.layers.active - - col = layout.column() - col.active = not gpl.lock - col.prop(gpl, "parent") - col.prop(gpl, "parent_type", text="Type") - parent = gpl.parent - - if parent and gpl.parent_type == 'BONE' and parent.type == 'ARMATURE': - col.prop_search(gpl, "parent_bone", parent.data, "bones", text="Bone") - - -class DATA_PT_gpencil_layer_display(LayerDataButtonsPanel, Panel): +class DATA_PT_gpencil_layer_display(LayerDataButtonsPanel, GreasePencilLayerDisplayPanel, Panel): bl_label = "Display" bl_parent_id = 'DATA_PT_gpencil_layers' bl_options = {'DEFAULT_CLOSED'} - def draw(self, context): - layout = self.layout - layout.use_property_split = True - layout.use_property_decorate = False - - gpd = context.gpencil - gpl = gpd.layers.active - - col = layout.row(align=True) - col.prop(gpl, "channel_color") - - col = layout.row(align=True) - col.prop(gpl, "use_solo_mode", text="Show Only On Keyframed") - class DATA_PT_gpencil_onion_skinning(DataButtonsPanel, Panel): bl_label = "Onion Skinning" diff --git a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py index bc76f57fa86..c2fb697337d 100644 --- a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py +++ b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py @@ -871,8 +871,8 @@ class GreasePencilMaterialsPanel: col.separator() sub = col.column(align=True) - sub.operator("gpencil.color_isolate", icon='LOCKED', text="").affect_visibility = False sub.operator("gpencil.color_isolate", icon='RESTRICT_VIEW_ON', text="").affect_visibility = True + sub.operator("gpencil.color_isolate", icon='LOCKED', text="").affect_visibility = False if show_full_ui: row = layout.row() @@ -935,8 +935,6 @@ class GPENCIL_UL_layer(UIList): icon='MOD_MASK' if gpl.mask_layer else 'LAYER_ACTIVE', emboss=False) - row.prop(gpl, "lock", text="", emboss=False) - row.prop(gpl, "hide", text="", emboss=False) subrow = row.row(align=True) subrow.prop( gpl, @@ -945,6 +943,8 @@ class GPENCIL_UL_layer(UIList): icon='ONIONSKIN_ON' if gpl.use_onion_skinning else 'ONIONSKIN_OFF', emboss=False, ) + row.prop(gpl, "hide", text="", emboss=False) + row.prop(gpl, "lock", text="", emboss=False) elif self.layout_type == 'GRID': layout.alignment = 'CENTER' layout.label( @@ -981,6 +981,87 @@ class GreasePencilSimplifyPanel: sub.prop(rd, "simplify_gpencil_remove_lines", text="Lines") +class GreasePencilLayerAdjustmentsPanel: + bl_label = "Adjustments" + bl_parent_id = 'DOPESHEET_PT_gpencil_mode' + bl_options = {'DEFAULT_CLOSED'} + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + scene = context.scene + + ob = context.object + gpd = ob.data + gpl = gpd.layers.active + layout.active = not gpl.lock + + # Layer options + # Offsets - Color Tint + layout.enabled = not gpl.lock + col = layout.column(align=True) + col.prop(gpl, "tint_color") + col.prop(gpl, "tint_factor", text="Factor", slider=True) + + # Offsets - Thickness + col = layout.row(align=True) + col.prop(gpl, "line_change", text="Stroke Thickness") + + col = layout.row(align=True) + col.prop(gpl, "pass_index") + + col = layout.row(align=True) + col.prop_search(gpl, "viewlayer_render", scene, "view_layers", text="View Layer") + + col = layout.row(align=True) + col.prop(gpl, "lock_material") + + +class GreasePencilLayerRelationsPanel: + bl_label = "Relations" + bl_parent_id = 'DOPESHEET_PT_gpencil_mode' + bl_options = {'DEFAULT_CLOSED'} + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + layout.use_property_decorate = False + + ob = context.object + gpd = ob.data + gpl = gpd.layers.active + + col = layout.column() + col.active = not gpl.lock + col.prop(gpl, "parent") + col.prop(gpl, "parent_type", text="Type") + parent = gpl.parent + + if parent and gpl.parent_type == 'BONE' and parent.type == 'ARMATURE': + col.prop_search(gpl, "parent_bone", parent.data, "bones", text="Bone") + + +class GreasePencilLayerDisplayPanel: + bl_label = "Display" + bl_parent_id = 'DOPESHEET_PT_gpencil_mode' + bl_options = {'DEFAULT_CLOSED'} + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + layout.use_property_decorate = False + + ob = context.object + gpd = ob.data + gpl = gpd.layers.active + + col = layout.row(align=True) + col.prop(gpl, "channel_color") + + col = layout.row(align=True) + col.prop(gpl, "use_solo_mode", text="Show Only On Keyframed") + + classes = ( GPENCIL_MT_pie_tool_palette, GPENCIL_MT_pie_settings_palette, diff --git a/release/scripts/startup/bl_ui/properties_material_gpencil.py b/release/scripts/startup/bl_ui/properties_material_gpencil.py index 8ce97a88e35..4f419ec1f18 100644 --- a/release/scripts/startup/bl_ui/properties_material_gpencil.py +++ b/release/scripts/startup/bl_ui/properties_material_gpencil.py @@ -65,13 +65,13 @@ class GPENCIL_UL_matslots(UIList): row.prop(ma, "name", text="", emboss=False, icon_value=icon) row = layout.row(align=True) - row.prop(gpcolor, "lock", text="", emboss=False) - row.prop(gpcolor, "hide", text="", emboss=False) if gpcolor.ghost is True: icon = 'ONIONSKIN_OFF' else: icon = 'ONIONSKIN_ON' row.prop(gpcolor, "ghost", text="", icon=icon, emboss=False) + row.prop(gpcolor, "hide", text="", emboss=False) + row.prop(gpcolor, "lock", text="", emboss=False) elif self.layout_type == 'GRID': layout.alignment = 'CENTER' diff --git a/release/scripts/startup/bl_ui/space_dopesheet.py b/release/scripts/startup/bl_ui/space_dopesheet.py index 3b498b834bf..b8f86788b4c 100644 --- a/release/scripts/startup/bl_ui/space_dopesheet.py +++ b/release/scripts/startup/bl_ui/space_dopesheet.py @@ -25,6 +25,12 @@ from bpy.types import ( Panel, ) +from bl_ui.properties_grease_pencil_common import ( + GreasePencilLayerAdjustmentsPanel, + GreasePencilLayerRelationsPanel, + GreasePencilLayerDisplayPanel, +) + ####################################### # DopeSheet Filtering - Header Buttons @@ -243,6 +249,18 @@ class DOPESHEET_HT_editor_buttons(Header): layout.template_ID(st, "action", new="action.new", unlink="action.unlink") + # Layer management + if st.mode == 'GPENCIL': + row = layout.row(align=True) + row.operator("gpencil.layer_move", icon='TRIA_UP', text="").type = 'UP' + row.operator("gpencil.layer_move", icon='TRIA_DOWN', text="").type = 'DOWN' + + row = layout.row(align=True) + row.operator("gpencil.layer_add", icon='ADD', text="") + row.operator("gpencil.layer_remove", icon='REMOVE', text="") + + layout.separator_spacer() + layout.separator_spacer() if st.mode == 'DOPESHEET': @@ -639,6 +657,65 @@ class DOPESHEET_MT_snap_pie(Menu): pie.operator("action.snap", text="Nearest Second").type = 'NEAREST_SECOND' pie.operator("action.snap", text="Nearest Marker").type = 'NEAREST_MARKER' +class LayersDopeSheetPanel: + bl_space_type = 'DOPESHEET_EDITOR' + bl_region_type = 'UI' + bl_category = "View" + + @classmethod + def poll(cls, context): + st = context.space_data + ob = context.object + if st.mode != 'GPENCIL' or ob is None or ob.type != 'GPENCIL': + return False + + gpd = ob.data + gpl = gpd.layers.active + if gpl: + return True + + return False + + +class DOPESHEET_PT_gpencil_mode(LayersDopeSheetPanel, Panel): + # bl_space_type = 'DOPESHEET_EDITOR' + # bl_region_type = 'UI' + # bl_category = "View" + bl_label = "Layer" + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + layout.use_property_decorate = False + + ob = context.object + gpd = ob.data + gpl = gpd.layers.active + if gpl: + row = layout.row(align=True) + row.prop(gpl, "blend_mode", text="Blend") + + row = layout.row(align=True) + row.prop(gpl, "opacity", text="Opacity", slider=True) + + +class DOPESHEET_PT_gpencil_layer_adjustments(LayersDopeSheetPanel, GreasePencilLayerAdjustmentsPanel, Panel): + bl_label = "Adjustments" + bl_parent_id = 'DOPESHEET_PT_gpencil_mode' + bl_options = {'DEFAULT_CLOSED'} + + +class DOPESHEET_PT_gpencil_layer_relations(LayersDopeSheetPanel, GreasePencilLayerRelationsPanel, Panel): + bl_label = "Relations" + bl_parent_id = 'DOPESHEET_PT_gpencil_mode' + bl_options = {'DEFAULT_CLOSED'} + + +class DOPESHEET_PT_gpencil_layer_display(LayersDopeSheetPanel, GreasePencilLayerDisplayPanel, Panel): + bl_label = "Display" + bl_parent_id = 'DOPESHEET_PT_gpencil_mode' + bl_options = {'DEFAULT_CLOSED'} + classes = ( DOPESHEET_HT_header, @@ -657,6 +734,10 @@ classes = ( DOPESHEET_MT_channel_context_menu, DOPESHEET_MT_snap_pie, DOPESHEET_PT_filters, + DOPESHEET_PT_gpencil_mode, + DOPESHEET_PT_gpencil_layer_adjustments, + DOPESHEET_PT_gpencil_layer_relations, + DOPESHEET_PT_gpencil_layer_display, ) if __name__ == "__main__": # only for live edit. diff --git a/release/scripts/startup/bl_ui/space_topbar.py b/release/scripts/startup/bl_ui/space_topbar.py index fef0e095099..dcfeb6a210f 100644 --- a/release/scripts/startup/bl_ui/space_topbar.py +++ b/release/scripts/startup/bl_ui/space_topbar.py @@ -146,8 +146,8 @@ class TOPBAR_PT_gpencil_layers(Panel): col.separator() sub = col.column(align=True) - sub.operator("gpencil.layer_isolate", icon='LOCKED', text="").affect_visibility = False sub.operator("gpencil.layer_isolate", icon='HIDE_OFF', text="").affect_visibility = True + sub.operator("gpencil.layer_isolate", icon='LOCKED', text="").affect_visibility = False class TOPBAR_MT_editor_menus(Menu): diff --git a/source/blender/blenloader/intern/versioning_defaults.c b/source/blender/blenloader/intern/versioning_defaults.c index 1c88f6b00af..bc43d9605e2 100644 --- a/source/blender/blenloader/intern/versioning_defaults.c +++ b/source/blender/blenloader/intern/versioning_defaults.c @@ -218,6 +218,19 @@ static void blo_update_defaults_screen(bScreen *screen, } } } + + /* 2D animation template. */ + if (app_template && STREQ(app_template, "2D_Animation")) { + for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { + for (ARegion *ar = sa->regionbase.first; ar; ar = ar->next) { + if (sa->spacetype == SPACE_ACTION) { + SpaceAction *saction = sa->spacedata.first; + /* Enable Sliders. */ + saction->flag |= SACTION_SLIDERS; + } + } + } + } } void BLO_update_defaults_workspace(WorkSpace *workspace, const char *app_template) diff --git a/source/blender/editors/animation/anim_channels_defines.c b/source/blender/editors/animation/anim_channels_defines.c index 8951677b32f..a2b9913ba14 100644 --- a/source/blender/editors/animation/anim_channels_defines.c +++ b/source/blender/editors/animation/anim_channels_defines.c @@ -4222,7 +4222,8 @@ void ANIM_channel_draw( * - Slider should start before the toggles (if they're visible) * to keep a clean line down the side. */ - if ((draw_sliders) && ELEM(ale->type, ANIMTYPE_FCURVE, ANIMTYPE_NLACURVE, ANIMTYPE_SHAPEKEY)) { + if ((draw_sliders) && + ELEM(ale->type, ANIMTYPE_FCURVE, ANIMTYPE_NLACURVE, ANIMTYPE_SHAPEKEY, ANIMTYPE_GPLAYER)) { /* adjust offset */ offset += SLIDER_WIDTH; } @@ -4992,7 +4993,8 @@ void ANIM_channel_draw_widgets(const bContext *C, * - Slider should start before the toggles (if they're visible) * to keep a clean line down the side. */ - if ((draw_sliders) && ELEM(ale->type, ANIMTYPE_FCURVE, ANIMTYPE_NLACURVE, ANIMTYPE_SHAPEKEY)) { + if ((draw_sliders) && + ELEM(ale->type, ANIMTYPE_FCURVE, ANIMTYPE_NLACURVE, ANIMTYPE_SHAPEKEY, ANIMTYPE_GPLAYER)) { /* adjust offset */ /* TODO: make slider width dynamic, * so that they can be easier to use when the view is wide enough. */ @@ -5053,8 +5055,70 @@ void ANIM_channel_draw_widgets(const bContext *C, rna_path = BKE_keyblock_curval_rnapath_get(key, kb); free_path = 1; } + /* Special for Grease Pencil Layer. */ + else if (ale->type == ANIMTYPE_GPLAYER) { + /* Add some offset to make it more pleasing to the eye. */ + offset += SLIDER_WIDTH / 2.1f; - /* only if RNA-Path found */ + char *gp_rna_path = NULL; + bGPDlayer *gpl = (bGPDlayer *)ale->data; + const short width = SLIDER_WIDTH / 5; + + /* Create the RNA pointers. */ + RNA_pointer_create(ale->id, &RNA_GPencilLayer, ale->data, &ptr); + RNA_id_pointer_create(ale->id, &id_ptr); + int icon; + + /* Mask Layer. */ + UI_block_emboss_set(block, UI_EMBOSS_NONE); + prop = RNA_struct_find_property(&ptr, "mask_layer"); + gp_rna_path = RNA_path_from_ID_to_property(&ptr, prop); + if (RNA_path_resolve_property(&id_ptr, gp_rna_path, &ptr, &prop)) { + icon = (gpl->flag & GP_LAYER_USE_MASK) ? ICON_MOD_MASK : ICON_LAYER_ACTIVE; + uiDefAutoButR( + block, &ptr, prop, array_index, "", icon, offset, ymid, width, channel_height); + } + MEM_freeN(gp_rna_path); + + /* Layer opacity. */ + UI_block_emboss_set(block, UI_EMBOSS); + prop = RNA_struct_find_property(&ptr, "opacity"); + gp_rna_path = RNA_path_from_ID_to_property(&ptr, prop); + if (RNA_path_resolve_property(&id_ptr, gp_rna_path, &ptr, &prop)) { + uiDefAutoButR(block, + &ptr, + prop, + array_index, + "", + ICON_NONE, + offset + width, + ymid, + width * 3, + channel_height); + } + MEM_freeN(gp_rna_path); + + /* Layer onion skinning switch. */ + UI_block_emboss_set(block, UI_EMBOSS_NONE); + prop = RNA_struct_find_property(&ptr, "use_onion_skinning"); + gp_rna_path = RNA_path_from_ID_to_property(&ptr, prop); + if (RNA_path_resolve_property(&id_ptr, gp_rna_path, &ptr, &prop)) { + icon = (gpl->onion_flag & GP_LAYER_ONIONSKIN) ? ICON_ONIONSKIN_ON : ICON_ONIONSKIN_OFF; + uiDefAutoButR(block, + &ptr, + prop, + array_index, + "", + icon, + offset + (width * 4), + ymid, + width, + channel_height); + } + MEM_freeN(gp_rna_path); + } + + /* Only if RNA-Path found. */ if (rna_path) { /* get RNA pointer, and resolve the path */ RNA_id_pointer_create(ale->id, &id_ptr); diff --git a/source/blender/editors/gpencil/gpencil_utils.c b/source/blender/editors/gpencil/gpencil_utils.c index 91af444c28a..300d7d9e925 100644 --- a/source/blender/editors/gpencil/gpencil_utils.c +++ b/source/blender/editors/gpencil/gpencil_utils.c @@ -105,6 +105,7 @@ bGPdata **ED_gpencil_data_get_pointers_direct( /* XXX: Should we reduce reliance on context.gpencil_data for these cases? */ case SPACE_PROPERTIES: /* properties */ case SPACE_INFO: /* header info (needed after workspaces merge) */ + case SPACE_ACTION: /* Dopesheet header. */ { if (ob && (ob->type == OB_GPENCIL)) { /* GP Object */