[Bf-blender-cvs] [846f5d8f744] greasepencil-object: Annotations: Dynamically updating layer-color preview icons + "Active Note" enum

Joshua Leung noreply at git.blender.org
Tue Jul 24 07:26:38 CEST 2018


Commit: 846f5d8f744601914ba0481dc23ec75c5dc7509d
Author: Joshua Leung
Date:   Tue Jul 24 02:28:35 2018 +1200
Branches: greasepencil-object
https://developer.blender.org/rB846f5d8f744601914ba0481dc23ec75c5dc7509d

Annotations: Dynamically updating layer-color preview icons + "Active Note" enum

This adds a new enum with dynamically-generated icons to show previews
for the icons associated with each GP layer used for annotations. This
enum is used as part of the UI for annotations (specifically, in the
topbar settings for the active  tool), making it easier for users to
see what color strokes drawn using the active note/layer will look like.

I ended up needing to create a new icon type in BKE_icons.h so that
we can store references to the layer/color used.

Known issues:
* The icon seems a bit too big, and would look a bit nicer with
  rounded corners. But there are too many issues with the UI roundbox
  functions (e.g. _aa() makes colors too dark, and non-aa versions look
  too rough).

* Changing layer colors doesn't redraw the icons. A manual refresh
  (by mousing over the widget) is needed.

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

M	release/scripts/startup/bl_ui/space_toolsystem_toolbar.py
M	source/blender/blenkernel/BKE_icons.h
M	source/blender/blenkernel/intern/gpencil.c
M	source/blender/blenkernel/intern/icons.c
M	source/blender/blenloader/intern/readfile.c
M	source/blender/editors/gpencil/gpencil_utils.c
M	source/blender/editors/interface/interface_icons.c
M	source/blender/makesdna/DNA_gpencil_types.h
M	source/blender/makesrna/intern/rna_gpencil.c

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

diff --git a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py
index 0d2d6445203..9668c398658 100644
--- a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py
+++ b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py
@@ -184,7 +184,7 @@ class _defs_annotate:
         gpl = context.active_gpencil_layer
 
         if gpd and gpl:
-            layout.prop_search(gpd.layers, "active", gpd, "layers", text="")
+            layout.prop(gpd.layers, "active_note", text="")
             layout.prop(gpl, "line_change", text="Thickness")  # XXX: Replace with proper thickness control
         else:
             layout.prop(user_prefs.edit, "grease_pencil_default_color", text="Color")
diff --git a/source/blender/blenkernel/BKE_icons.h b/source/blender/blenkernel/BKE_icons.h
index 22897d2ea80..7a5262e0a14 100644
--- a/source/blender/blenkernel/BKE_icons.h
+++ b/source/blender/blenkernel/BKE_icons.h
@@ -43,7 +43,10 @@ enum {
 	ICON_DATA_PREVIEW,
 	/** 2D triangles: obj is #Icon_Geom */
 	ICON_DATA_GEOM,
+	/** Studiolight */
 	ICON_DATA_STUDIOLIGHT,
+	/** GPencil Layer color preview (annotations): obj is #bGPDlayer */
+	ICON_DATA_GPLAYER,
 };
 
 struct Icon {
@@ -79,6 +82,7 @@ struct ImBuf;
 struct PreviewImage;
 struct ID;
 struct StudioLight;
+struct bGPDlayer;
 
 enum eIconSizes;
 
@@ -87,6 +91,9 @@ void BKE_icons_init(int first_dyn_id);
 /* return icon id for library object or create new icon if not found */
 int BKE_icon_id_ensure(struct ID *id);
 
+/* return icon id for Grease Pencil layer (color preview) or create new icon if not found */
+int BKE_icon_gplayer_color_ensure(struct bGPDlayer *gpl);
+
 int BKE_icon_preview_ensure(struct ID *id, struct PreviewImage *preview);
 
 /* retrieve icon for id */
diff --git a/source/blender/blenkernel/intern/gpencil.c b/source/blender/blenkernel/intern/gpencil.c
index 424b5955486..de3f891f9f9 100644
--- a/source/blender/blenkernel/intern/gpencil.c
+++ b/source/blender/blenkernel/intern/gpencil.c
@@ -60,6 +60,7 @@
 #include "BKE_global.h"
 #include "BKE_gpencil.h"
 #include "BKE_colortools.h"
+#include "BKE_icons.h"
 #include "BKE_library.h"
 #include "BKE_main.h"
 #include "BKE_object.h"
@@ -1031,6 +1032,9 @@ void BKE_gpencil_layer_delete(bGPdata *gpd, bGPDlayer *gpl)
 	/* free layer */
 	BKE_gpencil_free_frames(gpl);
 
+	/* free icon providing preview of icon color */
+	BKE_icon_delete(gpl->runtime.icon_id);
+
 	/* free derived data */
 	BKE_gpencil_clear_derived(gpl);
 	if (gpl->runtime.derived_data) {
diff --git a/source/blender/blenkernel/intern/icons.c b/source/blender/blenkernel/intern/icons.c
index 1c2575dfa52..3a4bf53e22d 100644
--- a/source/blender/blenkernel/intern/icons.c
+++ b/source/blender/blenkernel/intern/icons.c
@@ -37,6 +37,8 @@
 
 #include "MEM_guardedalloc.h"
 
+#include "DNA_brush_types.h"
+#include "DNA_gpencil_types.h"
 #include "DNA_group_types.h"
 #include "DNA_lamp_types.h"
 #include "DNA_material_types.h"
@@ -45,7 +47,6 @@
 #include "DNA_screen_types.h"
 #include "DNA_texture_types.h"
 #include "DNA_world_types.h"
-#include "DNA_brush_types.h"
 
 #include "BLI_utildefines.h"
 #include "BLI_ghash.h"
@@ -127,6 +128,9 @@ static void icon_free_data(int icon_id, Icon *icon)
 	else if (icon->obj_type == ICON_DATA_PREVIEW) {
 		((PreviewImage *)(icon->obj))->icon_id = 0;
 	}
+	else if (icon->obj_type == ICON_DATA_GPLAYER) {
+		((bGPDlayer *)(icon->obj))->runtime.icon_id = 0;
+	}
 	else if (icon->obj_type == ICON_DATA_GEOM) {
 		((struct Icon_Geom *)(icon->obj))->icon_id = 0;
 	}
@@ -598,6 +602,44 @@ int BKE_icon_id_ensure(struct ID *id)
 	return icon_id_ensure_create_icon(id);
 }
 
+
+static int icon_gplayer_color_ensure_create_icon(bGPDlayer *gpl)
+{
+	BLI_assert(BLI_thread_is_main());
+
+	/* NOTE: The color previews for GP Layers don't really need
+	 * to be "rendered" to image per se (as it will just be a plain
+	 * colored rectangle), we need to define icon data here so that
+	 * we can store a pointer to the layer data in icon->obj.
+	 */
+	Icon *icon = icon_create(gpl->runtime.icon_id, ICON_DATA_GPLAYER, gpl);
+	icon->flag = ICON_FLAG_MANAGED;
+
+	return gpl->runtime.icon_id;
+}
+
+int BKE_icon_gplayer_color_ensure(bGPDlayer *gpl)
+{
+	/* Never handle icons in non-main thread! */
+	BLI_assert(BLI_thread_is_main());
+
+	if (!gpl || G.background) {
+		return 0;
+	}
+
+	if (gpl->runtime.icon_id)
+		return gpl->runtime.icon_id;
+
+	gpl->runtime.icon_id = get_next_free_id();
+
+	if (!gpl->runtime.icon_id) {
+		printf("%s: Internal error - not enough IDs\n", __func__);
+		return 0;
+	}
+
+	return icon_gplayer_color_ensure_create_icon(gpl);
+}
+
 /**
  * Return icon id of given preview, or create new icon if not found.
  */
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 8eae6a1cefd..80c9072863f 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -6591,7 +6591,9 @@ static void direct_link_gpencil(FileData *fd, bGPdata *gpd)
 		link_list(fd, &gpl->frames);
 
 		gpl->actframe = newdataadr(fd, gpl->actframe);
+
 		gpl->runtime.derived_data = NULL;
+		gpl->runtime.icon_id = 0;
 
 		for (gpf = gpl->frames.first; gpf; gpf = gpf->next) {
 			/* relink strokes (and their points) */
diff --git a/source/blender/editors/gpencil/gpencil_utils.c b/source/blender/editors/gpencil/gpencil_utils.c
index 0d62580a861..b792d2af6d5 100644
--- a/source/blender/editors/gpencil/gpencil_utils.c
+++ b/source/blender/editors/gpencil/gpencil_utils.c
@@ -387,7 +387,7 @@ const EnumPropertyItem *ED_gpencil_layers_with_new_enum_itemf(
 	/* Create new layer */
 	/* TODO: have some way of specifying that we don't want this? */
 	{
-		/* active Keying Set */
+		/* "New Layer" entry */
 		item_tmp.identifier = "__CREATE__";
 		item_tmp.name = "New Layer";
 		item_tmp.value = -1;
diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c
index 371899beeab..0e8444e983a 100644
--- a/source/blender/editors/interface/interface_icons.c
+++ b/source/blender/editors/interface/interface_icons.c
@@ -110,6 +110,7 @@ typedef void (*VectorDrawFunc)(int x, int y, int w, int h, float alpha);
 #define ICON_TYPE_VECTOR         4
 #define ICON_TYPE_GEOM           5
 #define ICON_TYPE_EVENT          6  /* draw keymap entries using custom renderer. */
+#define ICON_TYPE_GPLAYER        7
 
 typedef struct DrawInfo {
 	int type;
@@ -392,6 +393,28 @@ DEF_VICON_COLORSET_DRAW_NTH(20, 19)
 
 #undef DEF_VICON_COLORSET_DRAW_NTH
 
+/* Dynamically render icon instead of rendering a plain color to a texture/buffer
+ * This is mot strictly a "vicon", as it needs access to icon->obj to get the color info,
+ * but it works in a very similar way.
+ */
+static void vicon_gplayer_color_draw(Icon *icon, int x, int y, int w, int h)
+{
+	bGPDlayer *gpl = (bGPDlayer *)icon->obj;
+
+	/* Just draw a colored rect - Like for vicon_colorset_draw() */
+	/* TODO: Make this have rounded corners, and maybe be a bit smaller.
+	 * However, UI_draw_roundbox_aa() draws the colors too dark, so can't be used.
+	 */
+	uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
+	immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
+	immUniformColor3fv(gpl->color);
+	immRecti(pos, x, y, x + w - 1, y + h - 1);
+
+	immUnbindProgram();
+}
+
+
 #ifndef WITH_HEADLESS
 
 static void init_brush_icons(void)
@@ -902,6 +925,9 @@ static DrawInfo *icon_create_drawinfo(Icon *icon)
 	else if (icon_data_type == ICON_DATA_STUDIOLIGHT) {
 		di->type = ICON_TYPE_BUFFER;
 	}
+	else if (icon_data_type == ICON_DATA_GPLAYER) {
+		di->type = ICON_TYPE_GPLAYER;
+	}
 	else {
 		BLI_assert(0);
 	}
@@ -1510,6 +1536,15 @@ static void icon_draw_size(
 			GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
 		}
 	}
+	else if (di->type == ICON_TYPE_GPLAYER) {
+		BLI_assert(icon->obj != NULL);
+
+		/* We need to flush widget base first to ensure correct ordering. */
+		UI_widgetbase_draw_cache_flush();
+
+		/* Just draw a colored rect - Like for vicon_colorset_draw() */
+		vicon_gplayer_color_draw(icon, (int)x, (int)y,  w, h);
+	}
 }
 
 static void ui_id_preview_image_render_size(
diff --git a/source/blender/makesdna/DNA_gpencil_types.h b/source/blender/makesdna/DNA_gpencil_types.h
index 731ba83d934..0ee8c25839a 100644
--- a/source/blender/makesdna/DNA_gpencil_types.h
+++ b/source/blender/makesdna/DNA_gpencil_types.h
@@ -235,6 +235,8 @@ typedef enum eGPDframe_Flag {
 /* Runtime temp data for bGPDlayer */
 typedef struct bGPDlayer_runtime {
 	struct GHash *derived_data;     /* runtime data created by modifiers */
+	int icon_id;                    /* id for dynamic icon used to show annotation color preview for layer */
+	char pad[4];
 } bGPDlayer_runtime;
 
 /* Grease-Pencil Annotations - 'Layer' */
diff --git a/source/blender/makesrna/intern/rna_gpencil.c b/source/blender/makesrna/intern/rna_gpencil.c
index ebda00e47a1..c2f984d2bbe 100644
--- a/source/blender/makesrna/intern/rna_gpencil.c
+++ b/source/blender/makesrna/intern/rna_gpencil.c
@@ -42,6 +42,7 @@
 
 #include "RNA_access.h"
 #include "RNA_define.h"
+#include "RNA_enum_types.h"
 
 #include "rna_internal.h"
 
@@ -81,9 +82,10 @@ static EnumPropertyItem rna_enum_gpencil_onion_modes_items[] = {
 
 #include "WM_api.h"
 
+#include "BKE_action.h"
 #include "BKE_animsys.h"
 #include "BKE_gpencil.h"
-#include "BKE_action.h"
+#include "BKE_icons.h"
 
 #include "DEG_depsgraph.h"
 
@@ -356,6 +358,35 @@ static void rna_GPencil_active_layer_index_range(PointerRNA *ptr, int *min, int
 	*softmax = *max;
 }
 
+static const EnumPropertyItem *rna_GPencil_active_layer_itemf(bContext *C, PointerRNA *ptr, PropertyRNA *prop, bool *r_free)
+{
+	bGPdata *gpd = (bGPdata *)ptr->id.data;
+	bGPDlayer *gpl;
+	EnumPropertyItem *item = NULL, item_tmp = {0};
+	int totitem = 0;
+	int i = 0;
+
+	if (ELEM(NULL, C, gpd)) {
+		return DummyRNA_NULL_items;
+	}
+
+	/* Existing layers */
+	for (gpl = gpd->layers.first, i = 0; gpl; gpl = gpl->next, i++) {
+		item_tmp.identifier = gpl->info;
+		item_tmp.name = gpl->info;
+		item_tmp.value = i;
+
+		item_tmp.ico

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list