[Bf-blender-cvs] [5368505] GPencil_Editing_Stage3: GPencil Layer Management: Lock/Unlock All + Isolate Layer

Joshua Leung noreply at git.blender.org
Thu Dec 10 07:19:50 CET 2015


Commit: 5368505ef32b39c1c12e1090bf69f25de78f959f
Author: Joshua Leung
Date:   Thu Dec 10 19:11:19 2015 +1300
Branches: GPencil_Editing_Stage3
https://developer.blender.org/rB5368505ef32b39c1c12e1090bf69f25de78f959f

GPencil Layer Management: Lock/Unlock All + Isolate Layer

This commit introduces a few operators to make it easier to perform a few common
layer-manipulation operations. Some of these have been sorely needed for quite
a while now...

* Lock/Unlock All - Just as their names suggest, these operators will lock and unlock
  all layers in the GP datablock. This is a quick way to unlock all layers previously
  locked. These can be found in the new dropdown which replaces the old "Duplicate"
  below the +/- (for adding/removing layers); also featured in the dropdown are
  the "Duplicate Layers" operator, as well as the show/hide ones.

* Isolate Layer - This operator makes it easy to focus on just a single layer (e.g. the
  outlines for a particular character). The "star" button affects editability, while the
  "eye" below it toggles editability + visibility.

  If any layer is visible/unlocked, this operator will lock and/or hide all; otherwise,
  it will unlock/unhide all (to reverse the previous operation).

===================================================================

M	release/scripts/startup/bl_ui/properties_grease_pencil_common.py
M	source/blender/editors/gpencil/gpencil_data.c
M	source/blender/editors/gpencil/gpencil_intern.h
M	source/blender/editors/gpencil/gpencil_ops.c

===================================================================

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 ab574ab..f7d80ea 100644
--- a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py
+++ b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py
@@ -451,6 +451,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'
@@ -502,7 +521,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()
@@ -511,6 +530,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)
 
diff --git a/source/blender/editors/gpencil/gpencil_data.c b/source/blender/editors/gpencil/gpencil_data.c
index 10dfe9a..4f03a53 100644
--- a/source/blender/editors/gpencil/gpencil_data.c
+++ b/source/blender/editors/gpencil/gpencil_data.c
@@ -446,6 +446,156 @@ void GPENCIL_OT_reveal(wmOperatorType *ot)
 	ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
 }
 
+/* ***************** Lock/Unlock All Layers ************************ */
+
+static int gp_lock_all_exec(bContext *C, wmOperator *UNUSED(op))
+{
+	bGPdata *gpd = ED_gpencil_data_get_active(C);
+	bGPDlayer *gpl;
+	
+	/* sanity checks */
+	if (gpd == NULL)
+		return OPERATOR_CANCELLED;
+	
+	/* make all layers non-editable */
+	for (gpl = gpd->layers.first; gpl; gpl = gpl->next) {
+		gpl->flag |= GP_LAYER_LOCKED;
+	}
+	
+	/* notifiers */
+	WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
+	
+	return OPERATOR_FINISHED;
+}
+
+void GPENCIL_OT_lock_all(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name = "Lock All Layers";
+	ot->idname = "GPENCIL_OT_lock_all";
+	ot->description = "Lock all Grease Pencil layers to prevent them from being accidentally modified";
+	
+	/* callbacks */
+	ot->exec = gp_lock_all_exec;
+	ot->poll = gp_reveal_poll; /* XXX: could use dedicated poll later */
+	
+	/* flags */
+	ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+/* -------------------------- */
+
+static int gp_unlock_all_exec(bContext *C, wmOperator *UNUSED(op))
+{
+	bGPdata *gpd = ED_gpencil_data_get_active(C);
+	bGPDlayer *gpl;
+	
+	/* sanity checks */
+	if (gpd == NULL)
+		return OPERATOR_CANCELLED;
+	
+	/* make all layers editable again */
+	for (gpl = gpd->layers.first; gpl; gpl = gpl->next) {
+		gpl->flag &= ~GP_LAYER_LOCKED;
+	}
+	
+	/* notifiers */
+	WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
+	
+	return OPERATOR_FINISHED;
+}
+
+void GPENCIL_OT_unlock_all(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name = "Unlock All Layers";
+	ot->idname = "GPENCIL_OT_unlock_all";
+	ot->description = "unlock all Grease Pencil layers so that they can be edited";
+	
+	/* callbacks */
+	ot->exec = gp_unlock_all_exec;
+	ot->poll = gp_reveal_poll; /* XXX: could use dedicated poll later */
+	
+	/* flags */
+	ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+/* ********************** Isolate Layer **************************** */
+
+static int gp_isolate_layer_exec(bContext *C, wmOperator *op)
+{
+	bGPdata *gpd = ED_gpencil_data_get_active(C);
+	bGPDlayer *layer = gpencil_layer_getactive(gpd);
+	bGPDlayer *gpl;
+	int flags = GP_LAYER_LOCKED;
+	bool isolate = false;
+	
+	if (RNA_boolean_get(op->ptr, "affect_visibility"))
+		flags |= GP_LAYER_HIDE;
+		
+	if (ELEM(NULL, gpd, layer)) {
+		BKE_report(op->reports, RPT_ERROR, "No active layer to isolate");
+		return OPERATOR_CANCELLED;
+	}
+	
+	/* Test whether to isolate or clear all flags */
+	for (gpl = gpd->layers.first; gpl; gpl = gpl->next) {
+		/* Skip if this is the active layer */
+		if (gpl == layer)
+			continue;
+		
+		/* If the flags aren't set, that means that the layer is
+		 * not alone, so we have some layers to isolate still
+		 */
+		if ((gpl->flag & flags) == 0) {
+			isolate = true;
+			break;
+		}
+	}
+	
+	/* Set/Clear flags as appropriate */
+	/* TODO: Include onionskinning on this list? */
+	if (isolate) {
+		/* Set flags on all "other" layers */
+		for (gpl = gpd->layers.first; gpl; gpl = gpl->next) {
+			if (gpl == layer)
+				continue;
+			else
+				gpl->flag |= flags;
+		}
+	}
+	else {
+		/* Clear flags - Restore everything else */
+		for (gpl = gpd->layers.first; gpl; gpl = gpl->next) {
+			gpl->flag &= ~flags;
+		}
+	}
+	
+	/* notifiers */
+	WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
+	
+	return OPERATOR_FINISHED;
+}
+
+void GPENCIL_OT_layer_isolate(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name = "Isolate Layer";
+	ot->idname = "GPENCIL_OT_layer_isolate";
+	ot->description = "Toggle whether the active layer is the only one that can be edited and/or visible";
+	
+	/* callbacks */
+	ot->exec = gp_isolate_layer_exec;
+	ot->poll = gp_active_layer_poll;
+	
+	/* flags */
+	ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+	
+	/* properties */
+	RNA_def_boolean(ot->srna, "affect_visibility", false, "Affect Visibility",
+	                "In addition to toggling the editability, also affect the visibility");
+}
+
 /* ********************** Change Layer ***************************** */
 
 static int gp_layer_change_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(evt))
diff --git a/source/blender/editors/gpencil/gpencil_intern.h b/source/blender/editors/gpencil/gpencil_intern.h
index 340b1ca..4032e43 100644
--- a/source/blender/editors/gpencil/gpencil_intern.h
+++ b/source/blender/editors/gpencil/gpencil_intern.h
@@ -188,6 +188,11 @@ void GPENCIL_OT_layer_duplicate(struct wmOperatorType *ot);
 void GPENCIL_OT_hide(struct wmOperatorType *ot);
 void GPENCIL_OT_reveal(struct wmOperatorType *ot);
 
+void GPENCIL_OT_lock_all(struct wmOperatorType *ot);
+void GPENCIL_OT_unlock_all(struct wmOperatorType *ot);
+
+void GPENCIL_OT_layer_isolate(struct wmOperatorType *ot);
+
 void GPENCIL_OT_active_frame_delete(struct wmOperatorType *ot);
 
 void GPENCIL_OT_convert(struct wmOperatorType *ot);
diff --git a/source/blender/editors/gpencil/gpencil_ops.c b/source/blender/editors/gpencil/gpencil_ops.c
index 3ed6b35..05e95df 100644
--- a/source/blender/editors/gpencil/gpencil_ops.c
+++ b/source/blender/editors/gpencil/gpencil_ops.c
@@ -330,6 +330,9 @@ void ED_operatortypes_gpencil(void)
 	
 	WM_operatortype_append(GPENCIL_OT_hide);
 	WM_operatortype_append(GPENCIL_OT_reveal);
+	WM_operatortype_append(GPENCIL_OT_lock_all);
+	WM_operatortype_append(GPENCIL_OT_unlock_all);
+	WM_operatortype_append(GPENCIL_OT_layer_isolate);
 	
 	WM_operatortype_append(GPENCIL_OT_active_frame_delete);




More information about the Bf-blender-cvs mailing list