diff options
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/blenkernel/BKE_icons.h | 6 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/icons.c | 77 | ||||
-rw-r--r-- | source/blender/editors/include/ED_util.h | 1 | ||||
-rw-r--r-- | source/blender/editors/render/render_preview.c | 2 | ||||
-rw-r--r-- | source/blender/editors/screen/screen_ops.c | 1 | ||||
-rw-r--r-- | source/blender/editors/util/ed_util.c | 72 |
6 files changed, 132 insertions, 27 deletions
diff --git a/source/blender/blenkernel/BKE_icons.h b/source/blender/blenkernel/BKE_icons.h index d6cf5eae323..534b24236e8 100644 --- a/source/blender/blenkernel/BKE_icons.h +++ b/source/blender/blenkernel/BKE_icons.h @@ -130,6 +130,9 @@ void BKE_previewimg_clear_single(struct PreviewImage *prv, enum eIconSizes size) /* get the preview from any pointer */ struct PreviewImage **BKE_previewimg_id_get_p(const struct ID *id); +/* Trigger deferred loading of a custom image file into the preview buffer. */ +void BKE_previewimg_id_custom_set(struct ID *id, const char *path); + /* free the preview image belonging to the id */ void BKE_previewimg_id_free(struct ID *id); @@ -156,7 +159,8 @@ struct PreviewImage *BKE_previewimg_cached_thumbnail_read(const char *name, bool force_update); void BKE_previewimg_cached_release(const char *name); -void BKE_previewimg_cached_release_pointer(struct PreviewImage *prv); + +void BKE_previewimg_deferred_release(struct PreviewImage *prv); void BKE_previewimg_blend_write(struct BlendWriter *writer, const struct PreviewImage *prv); void BKE_previewimg_blend_read(struct BlendDataReader *reader, struct PreviewImage *prv); diff --git a/source/blender/blenkernel/intern/icons.c b/source/blender/blenkernel/intern/icons.c index eec9013d067..58b4a8ce315 100644 --- a/source/blender/blenkernel/intern/icons.c +++ b/source/blender/blenkernel/intern/icons.c @@ -230,6 +230,20 @@ static PreviewImage *previewimg_create_ex(size_t deferred_data_size) return prv_img; } +static PreviewImage *previewimg_deferred_create(const char *path, int source) +{ + /* We pack needed data for lazy loading (source type, in a single char, and path). */ + const size_t deferred_data_size = strlen(path) + 2; + char *deferred_data; + + PreviewImage *prv = previewimg_create_ex(deferred_data_size); + deferred_data = (char *)PRV_DEFERRED_DATA(prv); + deferred_data[0] = source; + memcpy(&deferred_data[1], path, deferred_data_size - 1); + + return prv; +} + PreviewImage *BKE_previewimg_create(void) { return previewimg_create_ex(0); @@ -364,6 +378,42 @@ PreviewImage *BKE_previewimg_id_ensure(ID *id) return NULL; } +void BKE_previewimg_deferred_release(PreviewImage *prv) +{ + if (prv) { + if (prv->tag & PRV_TAG_DEFFERED_RENDERING) { + /* We cannot delete the preview while it is being loaded in another thread... */ + prv->tag |= PRV_TAG_DEFFERED_DELETE; + return; + } + if (prv->icon_id) { + BKE_icon_delete(prv->icon_id); + } + BKE_previewimg_freefunc(prv); + } +} + +void BKE_previewimg_id_custom_set(ID *id, const char *path) +{ + PreviewImage **prv = BKE_previewimg_id_get_p(id); + + /* Thumbnail previews must use the deferred pipeline. But we force them to be immediately + * generated here still. */ + + if (*prv) { + BKE_previewimg_deferred_release(*prv); + } + *prv = previewimg_deferred_create(path, THB_SOURCE_IMAGE); + + /* Can't lazy-render the preview on access. ID previews are saved to files and we want them to be + * there in time. Not only if something happened to have accessed it meanwhile. */ + for (int i = 0; i < NUM_ICON_SIZES; i++) { + BKE_previewimg_ensure(*prv, i); + /* Prevent auto-updates. */ + (*prv)->flag[i] |= PRV_USER_EDITED; + } +} + PreviewImage *BKE_previewimg_cached_get(const char *name) { return BLI_ghash_lookup(gCachedPreviews, name); @@ -417,15 +467,7 @@ PreviewImage *BKE_previewimg_cached_thumbnail_read(const char *name, } if (!prv) { - /* We pack needed data for lazy loading (source type, in a single char, and path). */ - const size_t deferred_data_size = strlen(path) + 2; - char *deferred_data; - - prv = previewimg_create_ex(deferred_data_size); - deferred_data = PRV_DEFERRED_DATA(prv); - deferred_data[0] = source; - memcpy(&deferred_data[1], path, deferred_data_size - 1); - + previewimg_deferred_create(path, source); force_update = true; } @@ -441,26 +483,11 @@ PreviewImage *BKE_previewimg_cached_thumbnail_read(const char *name, return prv; } -void BKE_previewimg_cached_release_pointer(PreviewImage *prv) -{ - if (prv) { - if (prv->tag & PRV_TAG_DEFFERED_RENDERING) { - /* We cannot delete the preview while it is being loaded in another thread... */ - prv->tag |= PRV_TAG_DEFFERED_DELETE; - return; - } - if (prv->icon_id) { - BKE_icon_delete(prv->icon_id); - } - BKE_previewimg_freefunc(prv); - } -} - void BKE_previewimg_cached_release(const char *name) { PreviewImage *prv = BLI_ghash_popkey(gCachedPreviews, name, MEM_freeN); - BKE_previewimg_cached_release_pointer(prv); + BKE_previewimg_deferred_release(prv); } /** diff --git a/source/blender/editors/include/ED_util.h b/source/blender/editors/include/ED_util.h index 68ae3589064..d74a80045f1 100644 --- a/source/blender/editors/include/ED_util.h +++ b/source/blender/editors/include/ED_util.h @@ -53,6 +53,7 @@ void ED_spacedata_id_remap(struct ScrArea *area, struct ID *new_id); void ED_OT_flush_edits(struct wmOperatorType *ot); +void ED_OT_lib_id_load_custom_preview(struct wmOperatorType *ot); /* ************** XXX OLD CRUFT WARNING ************* */ diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c index 095deccada0..d67113083a3 100644 --- a/source/blender/editors/render/render_preview.c +++ b/source/blender/editors/render/render_preview.c @@ -1304,7 +1304,7 @@ static void icon_preview_endjob(void *customdata) prv_img->tag &= ~PRV_TAG_DEFFERED_RENDERING; if (prv_img->tag & PRV_TAG_DEFFERED_DELETE) { BLI_assert(prv_img->tag & PRV_TAG_DEFFERED); - BKE_previewimg_cached_release_pointer(prv_img); + BKE_previewimg_deferred_release(prv_img); } } } diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index 649279f8e08..a0c5762c73c 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -5510,6 +5510,7 @@ void ED_operatortypes_screen(void) WM_operatortype_append(ED_OT_undo_history); WM_operatortype_append(ED_OT_flush_edits); + WM_operatortype_append(ED_OT_lib_id_load_custom_preview); } /** \} */ diff --git a/source/blender/editors/util/ed_util.c b/source/blender/editors/util/ed_util.c index 76c261c9cba..5e3f443ce9c 100644 --- a/source/blender/editors/util/ed_util.c +++ b/source/blender/editors/util/ed_util.c @@ -35,6 +35,7 @@ #include "DNA_screen_types.h" #include "DNA_space_types.h" +#include "BLI_fileops.h" #include "BLI_listbase.h" #include "BLI_path_util.h" #include "BLI_string.h" @@ -44,6 +45,7 @@ #include "BKE_context.h" #include "BKE_global.h" +#include "BKE_icons.h" #include "BKE_layer.h" #include "BKE_main.h" #include "BKE_material.h" @@ -51,6 +53,7 @@ #include "BKE_object.h" #include "BKE_packedFile.h" #include "BKE_paint.h" +#include "BKE_report.h" #include "BKE_screen.h" #include "BKE_undo_system.h" #include "BKE_workspace.h" @@ -501,3 +504,72 @@ void ED_OT_flush_edits(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_INTERNAL; } + +static bool lib_id_load_custom_preview_poll(bContext *C) +{ + const PointerRNA idptr = CTX_data_pointer_get(C, "active_id"); + BLI_assert(!idptr.data || RNA_struct_is_ID(idptr.type)); + + const ID *id = idptr.data; + if (!id) { + return false; + } + if (ID_IS_LINKED(id)) { + CTX_wm_operator_poll_msg_set(C, TIP_("Can't edit external library data")); + return false; + } + if (ID_IS_OVERRIDE_LIBRARY(id)) { + CTX_wm_operator_poll_msg_set(C, TIP_("Can't edit previews of overridden library data")); + return false; + } + if (!BKE_previewimg_id_get_p(id)) { + CTX_wm_operator_poll_msg_set(C, TIP_("Data-block does not support previews")); + return false; + } + + return true; +} + +static int lib_id_load_custom_preview_exec(bContext *C, wmOperator *op) +{ + char path[FILE_MAX]; + + RNA_string_get(op->ptr, "filepath", path); + + if (!BLI_is_file(path)) { + BKE_reportf(op->reports, RPT_ERROR, "File not found '%s'", path); + return OPERATOR_CANCELLED; + } + + PointerRNA idptr = CTX_data_pointer_get(C, "active_id"); + ID *id = idptr.data; + + BKE_previewimg_id_custom_set(id, path); + + // WM_event_add_notifier(C, NC_ASSET, NULL); + + return OPERATOR_FINISHED; +} + +void ED_OT_lib_id_load_custom_preview(wmOperatorType *ot) +{ + ot->name = "Load Custom Preview"; + ot->description = "Choose an image to help identify the data-block visually"; + ot->idname = "ED_OT_lib_id_load_custom_preview"; + + /* api callbacks */ + ot->poll = lib_id_load_custom_preview_poll; + ot->exec = lib_id_load_custom_preview_exec; + ot->invoke = WM_operator_filesel; + + /* flags */ + ot->flag = OPTYPE_INTERNAL; + + WM_operator_properties_filesel(ot, + FILE_TYPE_FOLDER | FILE_TYPE_IMAGE, + FILE_SPECIAL, + FILE_OPENFILE, + WM_FILESEL_FILEPATH, + FILE_DEFAULTDISPLAY, + FILE_SORT_DEFAULT); +} |