diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c index 3feda5d4db4..7c2d411e076 100644 --- a/source/blender/editors/interface/interface_icons.c +++ b/source/blender/editors/interface/interface_icons.c @@ -1013,21 +1013,26 @@ static void icon_draw_size(float x, float y, int icon_id, float aspect, float al } } +static void ui_id_preview_image_render_size(bContext *C, ID *id, PreviewImage *pi, int size) +{ + if ((pi->changed[size] ||!pi->rect[size])) /* changed only ever set by dynamic icons */ + { + /* create the rect if necessary */ + icon_set_image(C, id, pi, size); + + pi->changed[size] = 0; + } +} + static void ui_id_icon_render(bContext *C, ID *id, int big) { - PreviewImage *pi = BKE_previewimg_get(id); - - if (pi) { - if ((pi->changed[0] ||!pi->rect[0])) /* changed only ever set by dynamic icons */ - { - /* create the rect if necessary */ - - icon_set_image(C, id, pi, ICON_SIZE_ICON); /* icon size */ - if (big) - icon_set_image(C, id, pi, ICON_SIZE_PREVIEW); /* bigger preview size */ - - pi->changed[0] = 0; - } + PreviewImage *pi = BKE_previewimg_get(id); + + if (pi) { + if (big) + ui_id_preview_image_render_size(C, id, pi, ICON_SIZE_PREVIEW); /* bigger preview size */ + else + ui_id_preview_image_render_size(C, id, pi, ICON_SIZE_ICON); /* icon size */ } } diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c index 429cd658dea..b3b187f92a2 100644 --- a/source/blender/editors/interface/interface_layout.c +++ b/source/blender/editors/interface/interface_layout.c @@ -1281,7 +1281,7 @@ static void rna_search_cb(const struct bContext *C, void *arg_but, const char *s BLI_strncpy(name_ui, id->name+2, sizeof(name_ui)); #endif name= BLI_strdup(name_ui); - iconid= ui_id_icon_get((bContext*)C, id, 1); + iconid= ui_id_icon_get((bContext*)C, id, 0); } else { name= RNA_struct_name_get_alloc(&itemptr, NULL, 0, NULL); /* could use the string length here */ diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index 4a797b0e960..a73291ec352 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -96,6 +96,7 @@ typedef struct TemplateID { ListBase *idlb; int prv_rows, prv_cols; + int preview; } TemplateID; /* Search browse menu, assign */ @@ -143,7 +144,7 @@ static void id_search_cb(const bContext *C, void *arg_template, const char *str, char name_ui[MAX_ID_NAME]; name_uiprefix_id(name_ui, id); - iconid= ui_id_icon_get((bContext*)C, id, 1); + iconid= ui_id_icon_get((bContext*)C, id, template->preview); if(!uiSearchItemAdd(items, name_ui, id, iconid)) break; @@ -370,6 +371,7 @@ static void template_ID(bContext *C, uiLayout *layout, TemplateID *template, Str uiButSetFlag(but, UI_BUT_DISABLED); uiLayoutRow(layout, 1); + template->preview= 1; } else if(flag & UI_ID_BROWSE) { but= uiDefBlockButN(block, id_search_menu, MEM_dupallocN(template), "", 0, 0, UI_UNIT_X*1.6, UI_UNIT_Y, diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c index 3e34a55a3d9..3eda30e1554 100644 --- a/source/blender/editors/render/render_preview.c +++ b/source/blender/editors/render/render_preview.c @@ -164,6 +164,19 @@ typedef struct ShaderPreview { } ShaderPreview; +typedef struct IconPreviewSize { + struct IconPreviewSize *next, *prev; + int sizex, sizey; + unsigned int *rect; +} IconPreviewSize; + +typedef struct IconPreview { + Scene *scene; + void *owner; + ID *id; + ListBase sizes; +} IconPreview; + /* *************************** Preview for buttons *********************** */ static Main *pr_main= NULL; @@ -944,38 +957,96 @@ static void common_preview_startjob(void *customdata, short *stop, short *do_upd shader_preview_startjob(customdata, stop, do_update); } -static void common_preview_endjob(void *customdata) -{ - ShaderPreview *sp= customdata; +/* exported functions */ - if(sp->id && GS(sp->id->name) == ID_BR) - WM_main_add_notifier(NC_BRUSH|NA_EDITED, sp->id); +static void icon_preview_add_size(IconPreview *ip, unsigned int *rect, int sizex, int sizey) +{ + IconPreviewSize *cur_size = ip->sizes.first, *new_size; + + while (cur_size) { + if (cur_size->sizex == sizex && cur_size->sizey == sizey) { + /* requested size is already in list, no need to add it again */ + return; + } + + cur_size = cur_size->next; + } + + new_size = MEM_callocN(sizeof(IconPreviewSize), "IconPreviewSize"); + new_size->sizex = sizex; + new_size->sizey = sizey; + new_size->rect = rect; + + BLI_addtail(&ip->sizes, new_size); } -/* exported functions */ +static void icon_preview_startjob_all_sizes(void *customdata, short *stop, short *do_update, float *progress) +{ + IconPreview *ip = (IconPreview *)customdata; + IconPreviewSize *cur_size = ip->sizes.first; + + while (cur_size) { + ShaderPreview sp; + + memset(&sp, 0, sizeof(ShaderPreview)); + + /* construct shader preview from image size and previewcustomdata */ + sp.scene= ip->scene; + sp.owner= ip->owner; + sp.sizex= cur_size->sizex; + sp.sizey= cur_size->sizey; + sp.pr_method= PR_ICON_RENDER; + sp.pr_rect= cur_size->rect; + sp.id = ip->id; + + common_preview_startjob(&sp, stop, do_update, progress); + + cur_size = cur_size->next; + } +} + +static void icon_preview_endjob(void *customdata) +{ + IconPreview *ip = customdata; + + if (ip->id && GS(ip->id->name) == ID_BR) + WM_main_add_notifier(NC_BRUSH|NA_EDITED, ip->id); +} + +static void icon_preview_free(void *customdata) +{ + IconPreview *ip = (IconPreview *)customdata; + + BLI_freelistN(&ip->sizes); + MEM_freeN(ip); +} void ED_preview_icon_job(const bContext *C, void *owner, ID *id, unsigned int *rect, int sizex, int sizey) { wmJob *steve; - ShaderPreview *sp; + IconPreview *ip, *old_ip; /* suspended start means it starts after 1 timer step, see WM_jobs_timer below */ steve= WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), owner, "Icon Preview", WM_JOB_EXCL_RENDER|WM_JOB_SUSPEND); - sp= MEM_callocN(sizeof(ShaderPreview), "shader preview"); + + ip= MEM_callocN(sizeof(IconPreview), "icon preview"); + + /* render all resolutions from suspended job too */ + old_ip= WM_jobs_get_customdata(steve); + if (old_ip) + BLI_movelisttolist(&ip->sizes, &old_ip->sizes); /* customdata for preview thread */ - sp->scene= CTX_data_scene(C); - sp->owner= id; - sp->sizex= sizex; - sp->sizey= sizey; - sp->pr_method= PR_ICON_RENDER; - sp->pr_rect= rect; - sp->id = id; + ip->scene= CTX_data_scene(C); + ip->owner= id; + ip->id= id; + + icon_preview_add_size(ip, rect, sizex, sizey); /* setup job */ - WM_jobs_customdata(steve, sp, shader_preview_free); + WM_jobs_customdata(steve, ip, icon_preview_free); WM_jobs_timer(steve, 0.25, NC_MATERIAL, NC_MATERIAL); - WM_jobs_callbacks(steve, common_preview_startjob, NULL, NULL, common_preview_endjob); + WM_jobs_callbacks(steve, icon_preview_startjob_all_sizes, NULL, NULL, icon_preview_endjob); WM_jobs_start(CTX_wm_manager(C), steve); } diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c index 3a5793461ea..8063dc6c902 100644 --- a/source/blender/editors/space_image/space_image.c +++ b/source/blender/editors/space_image/space_image.c @@ -873,6 +873,12 @@ static void image_buttons_area_listener(ARegion *ar, wmNotifier *wmn) if(wmn->action==NA_EDITED) ED_region_tag_redraw(ar); break; + case NC_TEXTURE: + case NC_MATERIAL: + /* sending by texture render job and needed to properly update displaying + * brush texture icon */ + ED_region_tag_redraw(ar); + break; } } diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c index 94ab847c91b..72a068af095 100644 --- a/source/blender/editors/space_view3d/space_view3d.c +++ b/source/blender/editors/space_view3d/space_view3d.c @@ -933,6 +933,7 @@ static void view3d_buttons_area_listener(ARegion *ar, wmNotifier *wmn) ED_region_tag_redraw(ar); break; case NC_TEXTURE: + case NC_MATERIAL: /* for brush textures */ ED_region_tag_redraw(ar); break;