diff options
-rw-r--r-- | release/scripts/startup/bl_ui/space_info.py | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/icons.c | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/screen.c | 3 | ||||
-rw-r--r-- | source/blender/blenloader/intern/readfile.c | 2 | ||||
-rw-r--r-- | source/blender/blenloader/intern/writefile.c | 2 | ||||
-rw-r--r-- | source/blender/editors/include/ED_screen.h | 4 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_icons.c | 23 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_regions.c | 5 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_templates.c | 23 | ||||
-rw-r--r-- | source/blender/editors/render/render_preview.c | 7 | ||||
-rw-r--r-- | source/blender/editors/screen/CMakeLists.txt | 1 | ||||
-rw-r--r-- | source/blender/editors/screen/screen_draw.c | 111 | ||||
-rw-r--r-- | source/blender/editors/screen/screen_edit.c | 5 | ||||
-rw-r--r-- | source/blender/editors/screen/screen_ops.c | 7 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_screen_types.h | 2 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_window.c | 3 |
16 files changed, 189 insertions, 13 deletions
diff --git a/release/scripts/startup/bl_ui/space_info.py b/release/scripts/startup/bl_ui/space_info.py index 780dc4cf982..d77113ef7fc 100644 --- a/release/scripts/startup/bl_ui/space_info.py +++ b/release/scripts/startup/bl_ui/space_info.py @@ -40,7 +40,7 @@ class INFO_HT_header(Header): layout.operator("screen.back_to_previous", icon='SCREEN_BACK', text="Back to Previous") layout.separator() else: - layout.template_ID(context.window, "screen", new="screen.new", unlink="screen.delete") + layout.template_ID_preview(context.window, "screen", new="screen.new", unlink="screen.delete", rows=2, cols=6) layout.template_ID(context.screen, "scene", new="scene.new", unlink="scene.delete") layout.separator() diff --git a/source/blender/blenkernel/intern/icons.c b/source/blender/blenkernel/intern/icons.c index 7669c4ba112..70cf0d5a445 100644 --- a/source/blender/blenkernel/intern/icons.c +++ b/source/blender/blenkernel/intern/icons.c @@ -42,6 +42,7 @@ #include "DNA_material_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" +#include "DNA_screen_types.h" #include "DNA_texture_types.h" #include "DNA_world_types.h" #include "DNA_brush_types.h" @@ -252,6 +253,7 @@ PreviewImage **BKE_previewimg_id_get_p(ID *id) ID_PRV_CASE(ID_OB, Object); ID_PRV_CASE(ID_GR, Group); ID_PRV_CASE(ID_SCE, Scene); + ID_PRV_CASE(ID_SCR, bScreen); #undef ID_PRV_CASE } diff --git a/source/blender/blenkernel/intern/screen.c b/source/blender/blenkernel/intern/screen.c index 14820565478..c5d00d63b6d 100644 --- a/source/blender/blenkernel/intern/screen.c +++ b/source/blender/blenkernel/intern/screen.c @@ -50,6 +50,7 @@ #include "BLI_utildefines.h" #include "BLI_rect.h" +#include "BKE_icons.h" #include "BKE_idprop.h" #include "BKE_screen.h" @@ -394,6 +395,8 @@ void BKE_screen_free(bScreen *sc) BLI_freelistN(&sc->vertbase); BLI_freelistN(&sc->edgebase); BLI_freelistN(&sc->areabase); + + BKE_previewimg_free(&sc->preview); } /* for depsgraph */ diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index cca9338e814..605ccd30136 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -6567,6 +6567,8 @@ static bool direct_link_screen(FileData *fd, bScreen *sc) sc->mainwin = sc->subwinactive= 0; /* indices */ sc->swap = 0; + sc->preview = direct_link_preview_image(fd, sc->preview); + /* edges */ for (se = sc->edgebase.first; se; se = se->next) { se->v1 = newdataadr(fd, se->v1); diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index d8097f1a50a..169ca10f652 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -2781,6 +2781,8 @@ static void write_screens(WriteData *wd, ListBase *scrbase) writestruct(wd, ID_SCRN, bScreen, 1, sc); write_iddata(wd, &sc->id); + write_previews(wd, sc->preview); + /* direct data */ for (sv = sc->vertbase.first; sv; sv = sv->next) { writestruct(wd, DATA, ScrVert, 1, sv); diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h index ec09add56b8..f5f66a07aea 100644 --- a/source/blender/editors/include/ED_screen.h +++ b/source/blender/editors/include/ED_screen.h @@ -36,6 +36,8 @@ #include "DNA_view2d_types.h" #include "DNA_view3d_types.h" +#include "BLI_compiler_attrs.h" + struct wmWindowManager; struct wmWindow; struct wmNotifier; @@ -47,6 +49,7 @@ struct bScreen; struct ARegion; struct uiBlock; struct rcti; +struct Main; /* regions */ void ED_region_do_listen(struct bScreen *sc, struct ScrArea *sa, struct ARegion *ar, struct wmNotifier *note); @@ -118,6 +121,7 @@ void ED_screen_full_restore(struct bContext *C, ScrArea *sa); struct ScrArea *ED_screen_state_toggle(struct bContext *C, struct wmWindow *win, struct ScrArea *sa, const short state); void ED_screens_header_tools_menu_create(struct bContext *C, struct uiLayout *layout, void *arg); bool ED_screen_stereo3d_required(struct bScreen *screen); +void ED_screen_preview_render(const struct bScreen *screen, int size_x, int size_y, unsigned int *r_rect) ATTR_NONNULL(); /* anim */ void ED_update_for_newframe(struct Main *bmain, struct Scene *scene, int mute); diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c index c0360d9b0a7..3d22a26f34b 100644 --- a/source/blender/editors/interface/interface_icons.c +++ b/source/blender/editors/interface/interface_icons.c @@ -851,12 +851,15 @@ void ui_icon_ensure_deferred(const bContext *C, const int icon_id, const bool bi { ID *id = (icon->type != 0) ? icon->obj : NULL; PreviewImage *prv = id ? BKE_previewimg_id_ensure(id) : icon->obj; + /* Using jobs for screen previews crashes due to offscreen rendering. + * XXX would be nicer if PreviewImage could store if it supports jobs */ + const bool use_jobs = !id || (GS(id->name) != ID_SCR); if (prv) { const int size = big ? ICON_SIZE_PREVIEW : ICON_SIZE_ICON; if (id || (prv->tag & PRV_TAG_DEFFERED) != 0) { - ui_id_preview_image_render_size(C, NULL, id, prv, size, true); + ui_id_preview_image_render_size(C, NULL, id, prv, size, use_jobs); } } break; @@ -1169,7 +1172,7 @@ void UI_id_icon_render(const bContext *C, Scene *scene, ID *id, const bool big, } } -static void ui_id_brush_render(const bContext *C, ID *id) +static void ui_id_icon_render(const bContext *C, ID *id, bool use_jobs) { PreviewImage *pi = BKE_previewimg_id_ensure(id); enum eIconSizes i; @@ -1181,7 +1184,7 @@ static void ui_id_brush_render(const bContext *C, ID *id) /* check if rect needs to be created; changed * only set by dynamic icons */ if (((pi->flag[i] & PRV_CHANGED) || !pi->rect[i])) { - icon_set_image(C, NULL, id, pi, i, true); + icon_set_image(C, NULL, id, pi, i, use_jobs); pi->flag[i] &= ~PRV_CHANGED; } } @@ -1194,7 +1197,7 @@ static int ui_id_brush_get_icon(const bContext *C, ID *id) if (br->flag & BRUSH_CUSTOM_ICON) { BKE_icon_id_ensure(id); - ui_id_brush_render(C, id); + ui_id_icon_render(C, id, true); } else { Object *ob = CTX_data_active_object(C); @@ -1241,6 +1244,15 @@ static int ui_id_brush_get_icon(const bContext *C, ID *id) return id->icon_id; } +static int ui_id_screen_get_icon(const bContext *C, ID *id) +{ + BKE_icon_id_ensure(id); + /* Don't use jobs here, offscreen rendering doesn't like this and crashes. */ + ui_id_icon_render(C, id, false); + + return id->icon_id; +} + int ui_id_icon_get(const bContext *C, ID *id, const bool big) { int iconid = 0; @@ -1259,6 +1271,9 @@ int ui_id_icon_get(const bContext *C, ID *id, const bool big) /* checks if not exists, or changed */ UI_id_icon_render(C, NULL, id, big, true); break; + case ID_SCR: + iconid = ui_id_screen_get_icon(C, id); + break; default: break; } diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c index 466978272bc..62bab15dfb3 100644 --- a/source/blender/editors/interface/interface_regions.c +++ b/source/blender/editors/interface/interface_regions.c @@ -1059,7 +1059,7 @@ int ui_searchbox_autocomplete(bContext *C, ARegion *ar, uiBut *but, char *str) return match; } -static void ui_searchbox_region_draw_cb(const bContext *UNUSED(C), ARegion *ar) +static void ui_searchbox_region_draw_cb(const bContext *C, ARegion *ar) { uiSearchboxData *data = ar->regiondata; @@ -1077,6 +1077,9 @@ static void ui_searchbox_region_draw_cb(const bContext *UNUSED(C), ARegion *ar) if (data->preview) { /* draw items */ for (a = 0; a < data->items.totitem; a++) { + /* ensure icon is up-to-date */ + ui_icon_ensure_deferred(C, data->items.icons[a], data->preview); + ui_searchbox_butrect(&rect, data, a); /* widget itself */ diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index 80784e86b1e..9527ddc7088 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -415,17 +415,30 @@ static void template_ID( type = idptr.type; if (flag & UI_ID_PREVIEWS) { + ARegion *region = CTX_wm_region(C); + const bool use_big_size = (region->regiontype != RGN_TYPE_HEADER); /* silly check, could be more generic */ + /* Ugly exception for screens here, drawing their preview in icon size looks ugly/useless */ + const bool use_preview_icon = use_big_size || (id && (GS(id->name) != ID_SCR)); + const short width = UI_UNIT_X * (use_big_size ? 6 : 1.6f); + const short height = UI_UNIT_Y * (use_big_size ? 6: 1); + template->preview = true; - but = uiDefBlockButN(block, id_search_menu, MEM_dupallocN(template), "", 0, 0, UI_UNIT_X * 6, UI_UNIT_Y * 6, + but = uiDefBlockButN(block, id_search_menu, MEM_dupallocN(template), "", 0, 0, width, height, TIP_(template_id_browse_tip(type))); - ui_def_but_icon(but, id ? ui_id_icon_get(C, id, true) : RNA_struct_ui_icon(type), - UI_HAS_ICON | UI_BUT_ICON_PREVIEW); + if (use_preview_icon) { + ui_def_but_icon(but, ui_id_icon_get(C, id, use_big_size), UI_HAS_ICON | UI_BUT_ICON_PREVIEW); + } + else { + ui_def_but_icon(but, RNA_struct_ui_icon(type), UI_HAS_ICON); + UI_but_drawflag_enable(but, UI_BUT_ICON_LEFT); + } if ((idfrom && idfrom->lib) || !editable) UI_but_flag_enable(but, UI_BUT_DISABLED); - - uiLayoutRow(layout, true); + if (use_big_size) { + uiLayoutRow(layout, true); + } } 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 87c08dc6583..c48e142f233 100644 --- a/source/blender/editors/render/render_preview.c +++ b/source/blender/editors/render/render_preview.c @@ -94,6 +94,7 @@ #include "ED_datafiles.h" #include "ED_render.h" +#include "ED_screen.h" #ifndef NDEBUG /* Used for database init assert(). */ @@ -1022,6 +1023,12 @@ static void icon_preview_startjob(void *customdata, short *stop, short *do_updat *do_update = true; } + else if (idtype == ID_SCR) { + bScreen *screen = (bScreen *)id; + + ED_screen_preview_render(screen, sp->sizex, sp->sizey, sp->pr_rect); + *do_update = true; + } else { /* re-use shader job */ shader_preview_startjob(customdata, stop, do_update); diff --git a/source/blender/editors/screen/CMakeLists.txt b/source/blender/editors/screen/CMakeLists.txt index ed86ffa5e16..43e044b613a 100644 --- a/source/blender/editors/screen/CMakeLists.txt +++ b/source/blender/editors/screen/CMakeLists.txt @@ -42,6 +42,7 @@ set(SRC area.c glutil.c screen_context.c + screen_draw.c screen_edit.c screen_ops.c screendump.c diff --git a/source/blender/editors/screen/screen_draw.c b/source/blender/editors/screen/screen_draw.c new file mode 100644 index 00000000000..4332112abe6 --- /dev/null +++ b/source/blender/editors/screen/screen_draw.c @@ -0,0 +1,111 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/screen/screen_draw.c + * \ingroup edscr + */ + +#include "ED_screen.h" + +#include "GPU_framebuffer.h" +#include "GPU_immediate.h" + +#include "WM_api.h" + + +/** + * Calculates a scale factor to squash the preview for \a screen into a rectangle of given size and aspect. + */ +static void screen_preview_scale_get( + const bScreen *screen, float size_x, float size_y, + const float asp[2], + float r_scale[2]) +{ + float max_x = 0, max_y = 0; + + for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { + max_x = MAX2(max_x, sa->totrct.xmax); + max_y = MAX2(max_y, sa->totrct.ymax); + } + r_scale[0] = (size_x * asp[0]) / max_x; + r_scale[1] = (size_y * asp[1]) / max_y; +} + +static void screen_preview_draw_areas(const bScreen *screen, const float scale[2], const float col[4], + const float ofs_between_areas) +{ + const float ofs_h = ofs_between_areas * 0.5f; + unsigned int pos = add_attrib(immVertexFormat(), "pos", GL_FLOAT, 2, KEEP_FLOAT); + rctf rect; + + immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); + immUniformColor4fv(col); + + for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { + rect.xmin = sa->totrct.xmin * scale[0] + ofs_h; + rect.xmax = sa->totrct.xmax * scale[0] - ofs_h; + rect.ymin = sa->totrct.ymin * scale[1] + ofs_h; + rect.ymax = sa->totrct.ymax * scale[1] - ofs_h; + + immBegin(PRIM_TRIANGLE_FAN, 4); + immVertex2f(pos, rect.xmin, rect.ymin); + immVertex2f(pos, rect.xmax, rect.ymin); + immVertex2f(pos, rect.xmax, rect.ymax); + immVertex2f(pos, rect.xmin, rect.ymax); + immEnd(); + } + + immUnbindProgram(); +} + +static void screen_preview_draw(const bScreen *screen, int size_x, int size_y) +{ + const float asp[2] = {1.0f, 0.8f}; /* square previews look a bit ugly */ + /* could use theme color (tui.wcol_menu_item.text), but then we'd need to regenerate all previews when changing */ + const float col[4] = {1.0f, 1.0f, 1.0f, 1.0f}; + float scale[2]; + + wmOrtho2(0.0f, size_x, 0.0f, size_y); + /* center */ + glTranslatef(size_x * (1.0f - asp[0]) * 0.5f, size_y * (1.0f - asp[1]) * 0.5f, 0.0f); + + screen_preview_scale_get(screen, size_x, size_y, asp, scale); + screen_preview_draw_areas(screen, scale, col, 1.5f); +} + +/** + * Render the preview for a screen layout in \a screen. + */ +void ED_screen_preview_render(const bScreen *screen, int size_x, int size_y, unsigned int *r_rect) +{ + char err_out[256] = "unknown"; + GPUOffScreen *offscreen = GPU_offscreen_create(size_x, size_y, 0, err_out); + + GPU_offscreen_bind(offscreen, true); + glClearColor(0.0, 0.0, 0.0, 0.0); + glClear(GL_COLOR_BUFFER_BIT); + + screen_preview_draw(screen, size_x, size_y); + + GPU_offscreen_read_pixels(offscreen, GL_UNSIGNED_BYTE, r_rect); + GPU_offscreen_unbind(offscreen, true); + + GPU_offscreen_free(offscreen); +} diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c index 8f9ce329231..1f3092359e0 100644 --- a/source/blender/editors/screen/screen_edit.c +++ b/source/blender/editors/screen/screen_edit.c @@ -42,6 +42,7 @@ #include "BKE_context.h" #include "BKE_depsgraph.h" +#include "BKE_icons.h" #include "BKE_image.h" #include "BKE_global.h" #include "BKE_library.h" @@ -615,7 +616,9 @@ int screen_area_join(bContext *C, bScreen *scr, ScrArea *sa1, ScrArea *sa2) screen_delarea(C, scr, sa2); removedouble_scrverts(scr); sa1->flag &= ~AREA_FLAG_DRAWJOINFROM; - + /* Update preview thumbnail */ + BKE_icon_changed(scr->id.icon_id); + return 1; } diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index c69e01422e0..681b5954512 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -53,6 +53,7 @@ #include "BKE_context.h" #include "BKE_customdata.h" #include "BKE_global.h" +#include "BKE_icons.h" #include "BKE_main.h" #include "BKE_object.h" #include "BKE_report.h" @@ -1220,6 +1221,8 @@ static void area_move_apply_do(bContext *C, int origval, int delta, int dir, int } WM_event_add_notifier(C, NC_SCREEN | NA_EDITED, NULL); /* redraw everything */ + /* Update preview thumbnail */ + BKE_icon_changed(sc->id.icon_id); } } @@ -1508,7 +1511,9 @@ static int area_split_apply(bContext *C, wmOperator *op) ED_area_tag_redraw(sd->narea); WM_event_add_notifier(C, NC_SCREEN | NA_EDITED, NULL); - + /* Update preview thumbnail */ + BKE_icon_changed(sc->id.icon_id); + return 1; } diff --git a/source/blender/makesdna/DNA_screen_types.h b/source/blender/makesdna/DNA_screen_types.h index 2efb9d1f1ac..ce1f8d1a7d4 100644 --- a/source/blender/makesdna/DNA_screen_types.h +++ b/source/blender/makesdna/DNA_screen_types.h @@ -76,6 +76,8 @@ typedef struct bScreen { struct wmTimer *animtimer; /* if set, screen has timer handler added in window */ void *context; /* context callback */ + + PreviewImage *preview; } bScreen; typedef struct ScrVert { diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c index 718a9afea1f..e271225e437 100644 --- a/source/blender/windowmanager/intern/wm_window.c +++ b/source/blender/windowmanager/intern/wm_window.c @@ -51,6 +51,7 @@ #include "BKE_blender.h" #include "BKE_context.h" +#include "BKE_icons.h" #include "BKE_library.h" #include "BKE_global.h" #include "BKE_main.h" @@ -1105,6 +1106,7 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr wm_window_make_drawable(wm, win); wm_draw_window_clear(win); + BKE_icon_changed(win->screen->id.icon_id); WM_event_add_notifier(C, NC_SCREEN | NA_EDITED, NULL); WM_event_add_notifier(C, NC_WINDOW | NA_EDITED, NULL); @@ -1206,6 +1208,7 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr if (U.pixelsize != prev_pixelsize) { BKE_blender_userdef_refresh(); + BKE_icon_changed(win->screen->id.icon_id); // close all popups since they are positioned with the pixel // size baked in and it's difficult to correct them |