[Bf-blender-cvs] [74330c6] ui-preview-buttons: Initial support for icon/preview/thumbnail of files, including py API.

Bastien Montagne noreply at git.blender.org
Wed Apr 15 22:21:12 CEST 2015


Commit: 74330c659599dd25a8e85781fb3258dbdab02255
Author: Bastien Montagne
Date:   Wed Apr 15 22:15:37 2015 +0200
Branches: ui-preview-buttons
https://developer.blender.org/rB74330c659599dd25a8e85781fb3258dbdab02255

Initial support for icon/preview/thumbnail of files, including py API.

All this is rather rough at the edges still, but seems to be working from quick tests.
Basically, it:
* Rework a bi BKE_icon, adding a special kind of icons, which type is 0, and which
  own a PreviewImage in their obj field.
* Add helper to generate such icon from a file path.
* Add RNA API (to bpy.data currently).

So now, one can request a 'Preview' for a given path, that preview has an icon_id
that can be passed as 'icon_value' parameters of UILayout functions.

Main issue currently is, if you request several time same path, you'll get different
icons/previews each time, maybe we want to store paths in another ghash instead?

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

M	source/blender/blenkernel/BKE_icons.h
M	source/blender/blenkernel/intern/icons.c
M	source/blender/blenkernel/intern/image.c
M	source/blender/blenkernel/intern/lamp.c
M	source/blender/blenkernel/intern/material.c
M	source/blender/blenkernel/intern/texture.c
M	source/blender/blenkernel/intern/world.c
M	source/blender/blenlib/BLI_utildefines.h
M	source/blender/editors/include/UI_interface_icons.h
M	source/blender/editors/interface/interface_icons.c
M	source/blender/editors/render/render_preview.c
M	source/blender/editors/render/render_update.c
M	source/blender/editors/space_image/image_ops.c
M	source/blender/imbuf/intern/thumbs.c
M	source/blender/makesdna/DNA_ID.h
M	source/blender/makesrna/intern/rna_ID.c
M	source/blender/makesrna/intern/rna_brush.c
M	source/blender/makesrna/intern/rna_main_api.c

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

diff --git a/source/blender/blenkernel/BKE_icons.h b/source/blender/blenkernel/BKE_icons.h
index 5c4ab3c..ff3157e 100644
--- a/source/blender/blenkernel/BKE_icons.h
+++ b/source/blender/blenkernel/BKE_icons.h
@@ -53,7 +53,9 @@ enum eIconSizes;
 void BKE_icons_init(int first_dyn_id);
 
 /* return icon id for library object or create new icon if not found */
-int BKE_icon_getid(struct ID *id);
+int BKE_icon_id_get(struct ID *id);
+
+int BKE_icon_preview_get(struct PreviewImage *preview);
 
 /* retrieve icon for id */
 struct Icon *BKE_icon_get(int icon_id);
@@ -62,8 +64,10 @@ struct Icon *BKE_icon_get(int icon_id);
 /* used for inserting the internal icons */
 void BKE_icon_set(int icon_id, struct Icon *icon);
 
-/* remove icon and free date if library object becomes invalid */
-void BKE_icon_delete(struct ID *id);
+/* remove icon and free data if library object becomes invalid */
+void BKE_icon_id_delete(struct ID *id);
+
+void BKE_icon_delete(int icon_id);
 
 /* report changes - icon needs to be recalculated */
 void BKE_icon_changed(int icon_id);
@@ -86,6 +90,8 @@ void BKE_previewimg_free_id(struct ID *id);
 /* create a new preview image */
 struct PreviewImage *BKE_previewimg_create(void);
 
+struct PreviewImage *BKE_previewimg_thumbnail_create(const char *path, int source);
+
 /* create a copy of the preview image */
 struct PreviewImage *BKE_previewimg_copy(struct PreviewImage *prv);
 
diff --git a/source/blender/blenkernel/intern/icons.c b/source/blender/blenkernel/intern/icons.c
index 8d9472c..dbf2935 100644
--- a/source/blender/blenkernel/intern/icons.c
+++ b/source/blender/blenkernel/intern/icons.c
@@ -53,6 +53,10 @@
 
 #include "GPU_extensions.h"
 
+#include "IMB_imbuf.h"
+#include "IMB_imbuf_types.h"
+#include "IMB_thumbs.h"
+
 /* GLOBALS */
 
 static GHash *gIcons = NULL;
@@ -73,6 +77,10 @@ static void icon_free(void *val)
 		else if (icon->drawinfo) {
 			MEM_freeN(icon->drawinfo);
 		}
+		if (!icon->type && icon->obj) {
+			/* 'preview' icons own preview data too. */
+			BKE_previewimg_freefunc(icon->obj);
+		}
 		MEM_freeN(icon);
 	}
 }
@@ -129,6 +137,45 @@ PreviewImage *BKE_previewimg_create(void)
 	return prv_img;
 }
 
+/**
+ * Generate a PreviewImage from given file path, using thumbnails management.
+ */
+PreviewImage *BKE_previewimg_thumbnail_create(const char *path, int source)
+{
+	PreviewImage *prv = BKE_previewimg_create();
+	int icon_w, icon_h;
+
+	ImBuf *thumb = IMB_thumb_manage(path, THB_NORMAL, source);
+
+	if (thumb) {
+		prv->w[ICON_SIZE_PREVIEW] = thumb->x;
+		prv->h[ICON_SIZE_PREVIEW] = thumb->y;
+		prv->rect[ICON_SIZE_PREVIEW] = MEM_dupallocN(thumb->rect);
+		prv->changed[ICON_SIZE_PREVIEW] = 0;
+
+		if (thumb->x > thumb->y) {
+			icon_w = ICON_RENDER_DEFAULT_HEIGHT;
+			icon_h = (thumb->y * icon_w) / thumb->x + 1;
+		}
+		else if (thumb->x < thumb->y) {
+			icon_h = ICON_RENDER_DEFAULT_HEIGHT;
+			icon_w = (thumb->x * icon_h) / thumb->y + 1;
+		}
+		else {
+			icon_w = icon_h = ICON_RENDER_DEFAULT_HEIGHT;
+		}
+
+		IMB_scaleImBuf(thumb, icon_w, icon_h);
+		prv->w[ICON_SIZE_ICON] = icon_w;
+		prv->h[ICON_SIZE_ICON] = icon_h;
+		prv->rect[ICON_SIZE_ICON] = MEM_dupallocN(thumb->rect);
+		prv->changed[ICON_SIZE_ICON] = 0;
+
+		IMB_freeImBuf(thumb);
+	}
+	return prv;
+}
+
 void BKE_previewimg_freefunc(void *link)
 {
 	PreviewImage *prv = (PreviewImage *)link;
@@ -278,7 +325,7 @@ void BKE_icon_changed(int id)
 	}
 }
 
-int BKE_icon_getid(struct ID *id)
+int BKE_icon_id_get(struct ID *id)
 {
 	Icon *new_icon = NULL;
 
@@ -291,11 +338,11 @@ int BKE_icon_getid(struct ID *id)
 	id->icon_id = get_next_free_id();
 
 	if (!id->icon_id) {
-		printf("BKE_icon_getid: Internal error - not enough IDs\n");
+		printf("%s: Internal error - not enough IDs\n", __func__);
 		return 0;
 	}
 
-	new_icon = MEM_callocN(sizeof(Icon), "texicon");
+	new_icon = MEM_mallocN(sizeof(Icon), __func__);
 
 	new_icon->obj = id;
 	new_icon->type = GS(id->name);
@@ -309,6 +356,41 @@ int BKE_icon_getid(struct ID *id)
 	return id->icon_id;
 }
 
+/**
+ * Return icon id of given preview, or create new icon if not found.
+ * Note it takes ownership of given peview data!
+ */
+int BKE_icon_preview_get(PreviewImage *preview)
+{
+	Icon *new_icon = NULL;
+
+	if (!preview || G.background)
+		return 0;
+
+	if (preview->icon_id)
+		return preview->icon_id;
+
+	preview->icon_id = get_next_free_id();
+
+	if (!preview->icon_id) {
+		printf("%s: Internal error - not enough IDs\n", __func__);
+		return 0;
+	}
+
+	new_icon = MEM_mallocN(sizeof(Icon), __func__);
+
+	new_icon->obj = preview;
+	new_icon->type = 0;  /* Special, tags as non-ID icon/preview. */
+
+	/* next two lines make sure image gets created */
+	new_icon->drawinfo = NULL;
+	new_icon->drawinfo_free = NULL;
+
+	BLI_ghash_insert(gIcons, SET_INT_IN_POINTER(preview->icon_id), new_icon);
+
+	return preview->icon_id;
+}
+
 Icon *BKE_icon_get(int icon_id)
 {
 	Icon *icon = NULL;
@@ -316,7 +398,7 @@ Icon *BKE_icon_get(int icon_id)
 	icon = BLI_ghash_lookup(gIcons, SET_INT_IN_POINTER(icon_id));
 	
 	if (!icon) {
-		printf("BKE_icon_get: Internal error, no icon for icon ID: %d\n", icon_id);
+		printf("%s: Internal error, no icon for icon ID: %d\n", __func__, icon_id);
 		return NULL;
 	}
 
@@ -328,18 +410,36 @@ void BKE_icon_set(int icon_id, struct Icon *icon)
 	void **val_p;
 
 	if (BLI_ghash_ensure_p(gIcons, SET_INT_IN_POINTER(icon_id), &val_p)) {
-		printf("BKE_icon_set: Internal error, icon already set: %d\n", icon_id);
+		printf("%s: Internal error, icon already set: %d\n", __func__, icon_id);
 		return;
 	}
 
 	*val_p = icon;
 }
 
-void BKE_icon_delete(struct ID *id)
+void BKE_icon_id_delete(struct ID *id)
 {
-
 	if (!id->icon_id) return;  /* no icon defined for library object */
 
 	BLI_ghash_remove(gIcons, SET_INT_IN_POINTER(id->icon_id), NULL, icon_free);
 	id->icon_id = 0;
 }
+
+/**
+ * Remove icon and free data (including preview if this is a 'preview icon').
+ */
+void BKE_icon_delete(int icon_id)
+{
+	Icon *icon;
+
+	if (!icon_id) return;  /* no icon defined for library object */
+
+	icon = BLI_ghash_popkey(gIcons, SET_INT_IN_POINTER(icon_id), NULL);
+
+	if (icon) {
+		if (icon->type) {
+			((ID *)(icon->obj))->icon_id = 0;
+		}
+		icon_free(icon);
+	}
+}
diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c
index 8082853..3169db9 100644
--- a/source/blender/blenkernel/intern/image.c
+++ b/source/blender/blenkernel/intern/image.c
@@ -338,7 +338,7 @@ void BKE_image_free(Image *ima)
 
 	image_free_packedfiles(ima);
 
-	BKE_icon_delete(&ima->id);
+	BKE_icon_id_delete(&ima->id);
 	ima->id.icon_id = 0;
 
 	BKE_previewimg_free(&ima->preview);
@@ -2978,7 +2978,7 @@ static void image_initialize_after_load(Image *ima, ImBuf *ibuf)
 {
 	/* preview is NULL when it has never been used as an icon before */
 	if (G.background == 0 && ima->preview == NULL)
-		BKE_icon_changed(BKE_icon_getid(&ima->id));
+		BKE_icon_changed(BKE_icon_id_get(&ima->id));
 
 	/* fields */
 	if (ima->flag & IMA_FIELDS) {
diff --git a/source/blender/blenkernel/intern/lamp.c b/source/blender/blenkernel/intern/lamp.c
index 96b0b95..44e35c6 100644
--- a/source/blender/blenkernel/intern/lamp.c
+++ b/source/blender/blenkernel/intern/lamp.c
@@ -232,7 +232,7 @@ void BKE_lamp_free(Lamp *la)
 	}
 	
 	BKE_previewimg_free(&la->preview);
-	BKE_icon_delete(&la->id);
+	BKE_icon_id_delete(&la->id);
 	la->id.icon_id = 0;
 }
 
diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c
index b5b7f3d..b3bfa97 100644
--- a/source/blender/blenkernel/intern/material.c
+++ b/source/blender/blenkernel/intern/material.c
@@ -103,7 +103,7 @@ void BKE_material_free_ex(Material *ma, bool do_id_user)
 	
 	if (ma->preview)
 		BKE_previewimg_free(&ma->preview);
-	BKE_icon_delete((struct ID *)ma);
+	BKE_icon_id_delete((struct ID *)ma);
 	ma->id.icon_id = 0;
 	
 	/* is no lib link block, but material extension */
diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c
index 8e4fcc5..246e3f2 100644
--- a/source/blender/blenkernel/intern/texture.c
+++ b/source/blender/blenkernel/intern/texture.c
@@ -567,7 +567,7 @@ void BKE_texture_free(Tex *tex)
 	BKE_animdata_free((struct ID *)tex);
 	
 	BKE_previewimg_free(&tex->preview);
-	BKE_icon_delete((struct ID *)tex);
+	BKE_icon_id_delete((struct ID *)tex);
 	tex->id.icon_id = 0;
 	
 	if (tex->nodetree) {
diff --git a/source/blender/blenkernel/intern/world.c b/source/blender/blenkernel/intern/world.c
index f26cbf7..e4736b1 100644
--- a/source/blender/blenkernel/intern/world.c
+++ b/source/blender/blenkernel/intern/world.c
@@ -74,7 +74,7 @@ void BKE_world_free_ex(World *wrld, bool do_id_user)
 	if (wrld->gpumaterial.first)
 		GPU_material_free(&wrld->gpumaterial);
 	
-	BKE_icon_delete((struct ID *)wrld);
+	BKE_icon_id_delete((struct ID *)wrld);
 	wrld->id.icon_id = 0;
 }
 
diff --git a/source/blender/blenlib/BLI_utildefines.h b/source/blender/blenlib/BLI_utildefines.h
index 2ddc8fa..699f4ed 100644
--- a/source/blender/blenlib/BLI_utildefines.h
+++ b/source/blender/blenlib/BLI_utildefines.h
@@ -674,6 +674,11 @@ extern void BLI_system_backtrace(FILE *fp);
 #  define UNLIKELY(x)     (x)
 #endif
 
+/* XXX Find a better place for that? DNA?
+ *     Thing is, we need those defines in IMB, BKE, editors... */
+#define ICON_RENDER_DEFAULT_HEIGHT 32
+#define PREVIEW_RENDER_DEFAULT_HEIGHT 128
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/source/blender/editors/include/UI_interface_icons.h b/source/blender/editors/include/UI_interface_icons.h
index 2d4ab93..adaa364 100644
--- a/source/blender/editors/include/UI_interface_icons.h
+++ b/source/blender/editors/include/UI_interface_icons.h
@@ -51,9 +51,6 @@ typedef struct IconFile {
 #define ICON_DEFAULT_HEIGHT_SCALE ((int)(UI_UNIT_Y * 0.8f))
 #define ICON_DEFAULT_WIDTH_SCALE  ((int)(UI_UNIT_X * 0.8f))
 
-#define ICON_RENDER_DEFAULT_HEIGHT 32
-#define PREVIEW_RENDER_DEFAULT_HEIGHT 128
-
 /*
  * Resizable Icons for Blender
  */
diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c
index 94dfceb..6a12031 100644
--- a/source/blender/editors/interface/interface_icons.c
+++ b/source/blender/editors/interface/interf

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list