[Bf-blender-cvs] [1cb6813] ui-preview-buttons: Rework previews handling to be 'simpler' on py-level, as discussed with Campbell
Bastien Montagne
noreply at git.blender.org
Mon Apr 27 18:18:29 CEST 2015
Commit: 1cb68135fd02be478d73e9afa3f0c73e7042814b
Author: Bastien Montagne
Date: Mon Apr 27 16:59:04 2015 +0200
Branches: ui-preview-buttons
https://developer.blender.org/rB1cb68135fd02be478d73e9afa3f0c73e7042814b
Rework previews handling to be 'simpler' on py-level, as discussed with Campbell
This removes ID-free previews handling from RNA, adds a low-level hidden API
in bpy.app._previews, and the real previews manager in bpy.utils.
There is still lots of cleanup and renaming to be done...
===================================================================
M release/scripts/modules/bpy/utils.py
M source/blender/blenkernel/BKE_icons.h
M source/blender/blenkernel/intern/icons.c
M source/blender/editors/interface/interface_icons.c
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
M source/blender/python/intern/CMakeLists.txt
M source/blender/python/intern/bpy_app.c
A source/blender/python/intern/bpy_app_previews.c
A source/blender/python/intern/bpy_app_previews.h
===================================================================
diff --git a/release/scripts/modules/bpy/utils.py b/release/scripts/modules/bpy/utils.py
index 5f235ae..3047f02 100644
--- a/release/scripts/modules/bpy/utils.py
+++ b/release/scripts/modules/bpy/utils.py
@@ -38,6 +38,7 @@ __all__ = (
"unregister_manual_map",
"make_rna_paths",
"manual_map",
+ "previews",
"resource_path",
"script_path_user",
"script_path_pref",
@@ -51,6 +52,7 @@ __all__ = (
)
from _bpy import (
+ app,
escape_identifier,
register_class,
unregister_class,
@@ -697,3 +699,89 @@ def make_rna_paths(struct_name, prop_name, enum_name):
else:
src = src_rna = struct_name
return src, src_rna, src_enum
+
+
+# High-level previews manager.
+class BPyPreviewsManager:
+ """
+ Fake module like class.
+
+ bpy.app.previews_manager
+ """
+ __slots__ = ('_previews_collections',)
+
+ def __init__(self):
+ self._previews_collections = {}
+
+ def __del__(self):
+ self.clear()
+
+ def new(self, name):
+ """
+ Return a new preview collection, or existing one if 'name' already exists.
+ """
+ return self._previews_collections.setdefault(name, BPyPreviewsCollection(name))
+
+ def _remove(self, name):
+ return self._previews_collections.pop(name, None)
+
+ def delete(self, name):
+ pcoll = self._remove(name)
+ if pcoll is not None:
+ del pcoll
+
+ def clear(self):
+ for pcoll in self._previews_collections.values():
+ del pcoll
+ self._previews_collections.clear()
+
+ def __repr__(self):
+ return "<module like class 'bpy.app.previews_manager'>"
+
+
+class BPyPreviewsCollection:
+ """
+ Fake dict-like class of previews.
+ """
+ __slots__ = ('_previews', '_coll_name')
+
+ def __init__(self, name):
+ self._previews = {}
+ self._coll_name = name
+
+ def __del__(self):
+ self.clear()
+
+ def _gen_key(self, name):
+ return self._coll_name + name
+
+ def new(self, name):
+ """
+ Return a new empty preview, or existing one if 'name' already exists.
+ """
+ return self._previews.setdefault(name, app._previews.new(self._gen_key(name)))
+
+ def load(self, name, path, path_type, force_reload=False):
+ """
+ Return a new preview from given file path, or existing one if 'name' already exists.
+ """
+ pkey = self._gen_key(name)
+ if force_reload:
+ self._previews[name] = p = app._previews.load(pkey, path, path_type, True)
+ return p
+ else:
+ return self._previews.setdefault(name, app._previews.load(pkey, path, path_type, False))
+
+ def release(self, name):
+ p = self._previews.pop(name, None)
+ if p is not None:
+ del p
+ app._previews.release(self._gen_key(name))
+
+ def clear(self):
+ for name in self._previews.keys():
+ _previews.release(self._gen_key(name))
+ self._previews.clear()
+
+previews = BPyPreviewsManager()
+
diff --git a/source/blender/blenkernel/BKE_icons.h b/source/blender/blenkernel/BKE_icons.h
index 58f3edf..a950caa 100644
--- a/source/blender/blenkernel/BKE_icons.h
+++ b/source/blender/blenkernel/BKE_icons.h
@@ -90,12 +90,16 @@ 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, const int source, bool force_update);
-
/* create a copy of the preview image */
struct PreviewImage *BKE_previewimg_copy(struct PreviewImage *prv);
+struct PreviewImage *BKE_previewimg_name_get(const char *name);
+
+struct PreviewImage *BKE_previewimg_thumbnail_get(const char *name, const char *path, const int source, bool force_update);
+
+void BKE_previewimg_name_release(const char *name);
+
/* retrieve existing or create new preview image */
-struct PreviewImage *BKE_previewimg_get(struct ID *id);
+struct PreviewImage *BKE_previewimg_id_get(struct ID *id);
#endif /* __BKE_ICONS_H__ */
diff --git a/source/blender/blenkernel/intern/icons.c b/source/blender/blenkernel/intern/icons.c
index 857fd1d..a54a80e 100644
--- a/source/blender/blenkernel/intern/icons.c
+++ b/source/blender/blenkernel/intern/icons.c
@@ -45,6 +45,7 @@
#include "BLI_utildefines.h"
#include "BLI_ghash.h"
+#include "BLI_string.h"
#include "BKE_icons.h"
#include "BKE_global.h" /* only for G.background test */
@@ -125,7 +126,7 @@ void BKE_icons_free(void)
}
if (gFilePreviews) {
- BLI_ghash_free(gFilePreviews, NULL, BKE_previewimg_freefunc);
+ BLI_ghash_free(gFilePreviews, MEM_freeN, BKE_previewimg_freefunc);
gFilePreviews = NULL;
}
}
@@ -144,72 +145,6 @@ 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, const int source, bool force_update)
-{
- PreviewImage *prv = NULL;
- void **prv_v;
- int icon_w, icon_h;
-
- prv_v = BLI_ghash_lookup_p(gFilePreviews, path);
-
- if (prv_v) {
- prv = *prv_v;
- BLI_assert(prv);
- }
-
- if (prv && force_update) {
- BKE_previewimg_clear(prv, ICON_SIZE_ICON);
- BKE_previewimg_clear(prv, ICON_SIZE_PREVIEW);
- }
- else if (!prv) {
- prv = BKE_previewimg_create();
- force_update = true;
- }
-
- if (force_update) {
- 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->flag[ICON_SIZE_PREVIEW] &= ~(CHANGED | USER_EDITED);
-
- 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->flag[ICON_SIZE_ICON] &= ~(CHANGED | USER_EDITED);
-
- IMB_freeImBuf(thumb);
- }
-
- if (prv_v) {
- *prv_v = prv;
- }
- else {
- BLI_ghash_insert(gFilePreviews, (void *)path, prv);
- }
- }
-
- return prv;
-}
-
void BKE_previewimg_freefunc(void *link)
{
PreviewImage *prv = (PreviewImage *)link;
@@ -299,7 +234,114 @@ void BKE_previewimg_free_id(ID *id)
}
}
-PreviewImage *BKE_previewimg_get(ID *id)
+/**
+ * Generate an empty PreviewImage, if not yet existing.
+ */
+PreviewImage *BKE_previewimg_name_get(const char *name)
+{
+ PreviewImage *prv = NULL;
+ void **prv_v;
+
+ prv_v = BLI_ghash_lookup_p(gFilePreviews, name);
+
+ if (prv_v) {
+ prv = *prv_v;
+ BLI_assert(prv);
+ }
+
+ if (!prv) {
+ prv = BKE_previewimg_create();
+ }
+
+ if (prv_v) {
+ *prv_v = prv;
+ }
+ else {
+ BLI_ghash_insert(gFilePreviews, (void *)BLI_strdup(name), prv);
+ }
+
+ return prv;
+}
+
+/**
+ * Generate a PreviewImage from given file path, using thumbnails management, if not yet existing.
+ */
+PreviewImage *BKE_previewimg_thumbnail_get(const char *name, const char *path, const int source, bool force_update)
+{
+ PreviewImage *prv = NULL;
+ void **prv_v;
+ int icon_w, icon_h;
+
+ prv_v = BLI_ghash_lookup_p(gFilePreviews, name);
+
+ if (prv_v) {
+ prv = *prv_v;
+ BLI_assert(prv);
+ }
+
+ if (prv && force_update) {
+ BKE_previewimg_clear(prv, ICON_SIZE_ICON);
+ BKE_previewimg_clear(prv, ICON_SIZE_PREVIEW);
+ }
+ else if (!prv) {
+ prv = BKE_previewimg_create();
+ force_update = true;
+ }
+
+ if (force_update) {
+ 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->flag[ICON_SIZE_PREVIEW] &= ~(CHANGED | USER_EDITED);
+
+ 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->flag[ICON_SIZE_ICON] &= ~(CHANGED | USER_EDITED);
+
+ IMB_freeImBuf(thumb);
+ }
+
+ if (prv_v) {
+ *prv_v = prv;
+ }
+ else {
+ BLI_ghash_insert(gFilePreviews, (void *)BLI_strdup(name), prv);
+ }
+ }
+
+ return prv;
+}
+
+void BKE_previewimg_name_release(const char *name)
+{
+ PreviewImage *prv = BLI_ghash_popkey(gFilePreviews, (void *)name, MEM_freeN);
+
+ if (prv) {
+ if (prv->icon_id) {
+ BKE_icon_delete(prv->icon_id);
+ }
+ BKE_previewimg_freefunc(prv);
+ }
+}
+
+PreviewImage *BKE_previewimg_id_get(ID *id)
{
PreviewImage *prv_img = NULL;
@@ -346,7 +388,7 @@ void BKE_icon_changed(int id)
icon = BLI_ghash_lookup(gIcons, SET_INT_IN_POINTER(id));
if (icon) {
- PreviewImage *prv = BKE_previewimg_get((ID *)icon->obj);
+ PreviewImage *prv = BKE_previewimg_id_get((ID *)icon->obj);
/* all previews changed */
if (prv) {
diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c
index fb5960f..979cad1 100644
--- a/source/blender/editors/interface/interface_icons.c
+++ b/source/blender/editors/interface/interface_icons.c
@@ -1156,7 +1156,7 @@ static void icon_draw_size(float x, float y, int icon_id, float aspect, float al
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
else if (di->type == ICON_TYPE_PREVIEW) {
- PreviewImage *pi = icon->type ? BKE_previewimg_get((ID *)icon->obj) : icon->obj;
+ PreviewImage *pi = icon->type ? BKE_previewimg_id_get((ID *)icon->obj) : icon->obj;
if (pi) {
/* no create icon on this level in code */
@@ -1183,7 +1183,7 @@ static void u
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list