Blender V5.0
render_view.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2008 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#include <algorithm>
10#include <cstddef>
11#include <cstring>
12
13#include "BLI_listbase.h"
14
15#include "DNA_scene_types.h"
16#include "DNA_userdef_types.h"
17
18#include "BKE_context.hh"
19#include "BKE_global.hh"
20#include "BKE_image.hh"
21#include "BKE_report.hh"
22#include "BKE_scene.hh"
23#include "BKE_screen.hh"
24
25#include "BLT_translation.hh"
26
27#include "WM_api.hh"
28#include "WM_types.hh"
29
30#include "ED_screen.hh"
31
32#include "wm_window.hh"
33
34#include "render_intern.hh"
35
36/* -------------------------------------------------------------------- */
39
46{
47 bScreen *screen = CTX_wm_screen(C);
48 ScrArea *big = nullptr;
49 int size, maxsize = 0, bwmaxsize = 0;
50 short foundwin = 0;
51
52 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
53 if (area->winx > 30 && area->winy > 30) {
54 size = area->winx * area->winy;
55 if (!area->full && area->spacetype == SPACE_PROPERTIES) {
56 if (foundwin == 0 && size > bwmaxsize) {
57 bwmaxsize = size;
58 big = area;
59 }
60 }
61 else if (area->spacetype != SPACE_IMAGE && size > maxsize) {
62 maxsize = size;
63 big = area;
64 foundwin = 1;
65 }
66 }
67 }
68
69 return big;
70}
71
73{
75 ScrArea *area_render = nullptr;
76 wmWindow *win_render = nullptr;
77
78 /* find an image-window showing render result */
79 LISTBASE_FOREACH (wmWindow *, win, &wm->windows) {
80 if (WM_window_get_active_scene(win) != scene) {
81 continue;
82 }
83
84 const bScreen *screen = WM_window_get_active_screen(win);
85 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
86 if (area->spacetype == SPACE_IMAGE) {
87 SpaceImage *sima = static_cast<SpaceImage *>(area->spacedata.first);
88 if (sima->image && sima->image->type == IMA_TYPE_R_RESULT) {
89 area_render = area;
90 win_render = win;
91 break;
92 }
93 }
94 }
95 if (area_render) {
96 break;
97 }
98 }
99
100 *r_win = win_render;
101 return area_render;
102}
103
105{
106 bScreen *screen = CTX_wm_screen(C);
107 ScrArea *area;
108 SpaceImage *sima;
109
110 /* find an image-window showing render result */
111 for (area = static_cast<ScrArea *>(screen->areabase.first); area; area = area->next) {
112 if (area->spacetype == SPACE_IMAGE) {
113 sima = static_cast<SpaceImage *>(area->spacedata.first);
114 if ((sima->mode == SI_MODE_VIEW) && !sima->image) {
115 break;
116 }
117 }
118 }
119
120 return area;
121}
122
124
125/* -------------------------------------------------------------------- */
128
129ScrArea *render_view_open(bContext *C, int mx, int my, ReportList *reports)
130{
131 Main *bmain = CTX_data_main(C);
132 Scene *scene = CTX_data_scene(C);
133 ScrArea *area = nullptr;
134 SpaceImage *sima;
135 bool area_was_image = false;
136
137 if (U.render_display_type == USER_RENDER_DISPLAY_NONE) {
138 return nullptr;
139 }
140
141 if (U.render_display_type == USER_RENDER_DISPLAY_WINDOW) {
142 int sizex, sizey;
143 BKE_render_resolution(&scene->r, false, &sizex, &sizey);
144
145 sizex += 30 * UI_SCALE_FAC;
146 sizey += 60 * UI_SCALE_FAC;
147
148 /* arbitrary... miniature image window views don't make much sense */
149 sizex = std::max(sizex, 320);
150 sizey = std::max(sizey, 256);
151
153 rctf *stored_bounds = &U.stored_bounds.image;
154 const bool bounds_valid = (stored_bounds && (BLI_rctf_size_x(stored_bounds) > 150.0f) &&
155 (BLI_rctf_size_y(stored_bounds) > 100.0f));
157 if (bounds_valid && mm_placement) {
158 mx = int(stored_bounds->xmin * UI_SCALE_FAC);
159 my = int(stored_bounds->ymin * UI_SCALE_FAC);
160 }
161
162 const rcti window_rect = {
163 /*xmin*/ mx,
164 /*xmax*/ mx + sizex,
165 /*ymin*/ my,
166 /*ymax*/ my + sizey,
167 };
168
169 /* changes context! */
170 if (WM_window_open(C,
171 IFACE_("Blender Render"),
172 &window_rect,
174 true,
175 false,
176 true,
178 nullptr,
179 nullptr) == nullptr)
180 {
181 BKE_report(reports, RPT_ERROR, "Failed to open window!");
182 return nullptr;
183 }
184
185 area = CTX_wm_area(C);
186 if (BLI_listbase_is_single(&area->spacedata) == false) {
187 sima = static_cast<SpaceImage *>(area->spacedata.first);
188 sima->flag |= SI_PREVSPACE;
189 }
190 }
191 else if (U.render_display_type == USER_RENDER_DISPLAY_SCREEN) {
192 area = CTX_wm_area(C);
193
194 /* If the active screen is already in full-screen mode, skip this and
195 * unset the area, so that the full-screen area is just changed later. */
196 if (area && area->full) {
197 area = nullptr;
198 }
199 else {
200 if (area && area->spacetype == SPACE_IMAGE) {
201 area_was_image = true;
202 }
203
204 /* this function returns with changed context */
206 }
207 }
208
209 if (!area) {
210 wmWindow *win_show = nullptr;
211 area = find_area_showing_render_result(C, scene, &win_show);
212 if (area == nullptr) {
213 /* No need to set `win_show` as the area selected will be from the active window. */
214 area = find_area_image_empty(C);
215 }
216
217 /* if area found in other window, we make that one show in front */
218 if (win_show && win_show != CTX_wm_window(C)) {
219 wm_window_raise(win_show);
220 }
221
222 if (area == nullptr) {
223 /* find largest open non-image area */
225 if (area) {
226 ED_area_newspace(C, area, SPACE_IMAGE, true);
227 sima = static_cast<SpaceImage *>(area->spacedata.first);
228
229 /* Makes "Escape" go back to previous space. */
230 sima->flag |= SI_PREVSPACE;
231
232 /* We already had a full-screen here -> mark new space as a stacked full-screen. */
233 if (area->full) {
235 }
236 }
237 else {
238 /* use any area of decent size */
240 if (area->spacetype != SPACE_IMAGE) {
241 // XXX newspace(area, SPACE_IMAGE);
242 sima = static_cast<SpaceImage *>(area->spacedata.first);
243
244 /* Makes "Escape" go back to previous space. */
245 sima->flag |= SI_PREVSPACE;
246 }
247 }
248 }
249 }
250 sima = static_cast<SpaceImage *>(area->spacedata.first);
252
253 /* get the correct image, and scale it */
254 sima->image = BKE_image_ensure_viewer(bmain, IMA_TYPE_R_RESULT, "Render Result");
255
256 /* If we're rendering to full screen, set appropriate hints on image editor
257 * so it can restore properly on pressing escape. */
258 if (area->full) {
259 sima->flag |= SI_FULLWINDOW;
260
261 /* Tell the image editor to revert to previous space in space list on close
262 * _only_ if it wasn't already an image editor when the render was invoked */
263 if (area_was_image == 0) {
264 sima->flag |= SI_PREVSPACE;
265 }
266 else {
267 /* Leave it alone so the image editor will just go back from
268 * full screen to the original tiled setup */
269 }
270 }
271
272 if ((sima->flag & SI_PREVSPACE) && sima->next) {
273 SpaceLink *old_sl = sima->next;
275 }
276
277 return area;
278}
279
281
282/* -------------------------------------------------------------------- */
285
287{
288 wmWindow *win = CTX_wm_window(C);
289 ScrArea *area = CTX_wm_area(C);
290 SpaceImage *sima = static_cast<SpaceImage *>(area->spacedata.first);
291
292 /* ensure image editor full-screen and area full-screen states are in sync */
293 if ((sima->flag & SI_FULLWINDOW) && !area->full) {
294 sima->flag &= ~SI_FULLWINDOW;
295 }
296
297 /* determine if render already shows */
298 if (sima->flag & SI_PREVSPACE) {
299 sima->flag &= ~SI_PREVSPACE;
300
301 if (sima->flag & SI_FULLWINDOW) {
302 sima->flag &= ~SI_FULLWINDOW;
304 }
305 else {
306 ED_area_prevspace(C, area);
307 }
308
309 return OPERATOR_FINISHED;
310 }
311 if (sima->flag & SI_FULLWINDOW) {
312 sima->flag &= ~SI_FULLWINDOW;
314 return OPERATOR_FINISHED;
315 }
316 if (WM_window_is_temp_screen(win)) {
318 return OPERATOR_FINISHED;
319 }
320
322}
323
325{
326 /* identifiers */
327 ot->name = "Cancel Render View";
328 ot->description = "Cancel show render view";
329 ot->idname = "RENDER_OT_view_cancel";
330
331 /* API callbacks. */
334}
335
337
338/* -------------------------------------------------------------------- */
341
343{
344 wmWindow *wincur = CTX_wm_window(C);
345
346 /* test if we have currently a temp screen active */
347 if (WM_window_is_temp_screen(wincur)) {
348 wm_window_lower(wincur);
349 }
350 else {
351 wmWindow *win_show = nullptr;
353
354 /* is there another window on current scene showing result? */
355 LISTBASE_FOREACH (wmWindow *, win, &CTX_wm_manager(C)->windows) {
356 const bScreen *screen = WM_window_get_active_screen(win);
357
358 if ((WM_window_is_temp_screen(win) &&
359 ((ScrArea *)screen->areabase.first)->spacetype == SPACE_IMAGE) ||
360 (win == win_show && win_show != wincur))
361 {
362 wm_window_raise(win);
363 return OPERATOR_FINISHED;
364 }
365 }
366
367 /* determine if render already shows */
368 if (area) {
369 /* but don't close it when rendering */
370 if (G.is_rendering == false) {
371 SpaceImage *sima = static_cast<SpaceImage *>(area->spacedata.first);
372
373 if (sima->flag & SI_PREVSPACE) {
374 sima->flag &= ~SI_PREVSPACE;
375
376 if (sima->flag & SI_FULLWINDOW) {
377 sima->flag &= ~SI_FULLWINDOW;
379 }
380 else {
381 ED_area_prevspace(C, area);
382 }
383 }
384 }
385 }
386 else {
387 render_view_open(C, event->xy[0], event->xy[1], op->reports);
388 }
389 }
390
391 return OPERATOR_FINISHED;
392}
393
395{
396 /* identifiers */
397 ot->name = "Show/Hide Render View";
398 ot->description = "Toggle show render view";
399 ot->idname = "RENDER_OT_view_show";
400
401 /* API callbacks. */
402 ot->invoke = render_view_show_invoke;
404}
405
bScreen * CTX_wm_screen(const bContext *C)
ScrArea * CTX_wm_area(const bContext *C)
wmWindow * CTX_wm_window(const bContext *C)
Scene * CTX_data_scene(const bContext *C)
Main * CTX_data_main(const bContext *C)
wmWindowManager * CTX_wm_manager(const bContext *C)
Image * BKE_image_ensure_viewer(Main *bmain, int type, const char *name)
@ RPT_ERROR
Definition BKE_report.hh:39
void BKE_report(ReportList *reports, eReportType type, const char *message)
Definition report.cc:153
void BKE_render_resolution(const RenderData *r, const bool use_crop, int *r_width, int *r_height)
Definition scene.cc:2915
ScrArea * BKE_screen_find_big_area(const bScreen *screen, int spacetype, short min)
Definition screen.cc:944
#define LISTBASE_FOREACH(type, var, list)
void void BLI_INLINE bool BLI_listbase_is_single(const ListBase *lb)
BLI_INLINE float BLI_rctf_size_x(const struct rctf *rct)
Definition BLI_rect.h:202
BLI_INLINE float BLI_rctf_size_y(const struct rctf *rct)
Definition BLI_rect.h:206
#define IFACE_(msgid)
@ IMA_TYPE_R_RESULT
@ AREA_FLAG_STACKED_FULLSCREEN
@ SCREENMAXIMIZED
@ SI_FULLWINDOW
@ SI_PREVSPACE
@ SPACE_FLAG_TYPE_WAS_ACTIVE
@ SPACE_FLAG_TYPE_TEMPORARY
@ SPACE_PROPERTIES
@ SPACE_IMAGE
@ SI_MODE_VIEW
#define SPACE_TYPE_ANY
#define UI_SCALE_FAC
@ USER_RENDER_DISPLAY_NONE
@ USER_RENDER_DISPLAY_SCREEN
@ USER_RENDER_DISPLAY_WINDOW
@ OPERATOR_FINISHED
@ OPERATOR_PASS_THROUGH
void ED_area_newspace(bContext *C, ScrArea *area, int type, bool skip_region_exit)
Definition area.cc:2699
bool ED_operator_screenactive(bContext *C)
ScrArea * ED_screen_full_newspace(bContext *C, ScrArea *area, int type)
bool ED_operator_image_active(bContext *C)
ScrArea * ED_screen_state_toggle(bContext *C, wmWindow *win, ScrArea *area, short state)
void ED_area_prevspace(bContext *C, ScrArea *area)
Definition area.cc:2866
void ED_screen_full_prevspace(bContext *C, ScrArea *area)
#define C
Definition RandGen.cpp:29
@ WIN_ALIGN_ABSOLUTE
Definition WM_api.hh:374
@ WM_CAPABILITY_MULTIMONITOR_PLACEMENT
Definition WM_api.hh:211
#define U
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition btDbvt.cpp:52
#define G(x, y, z)
void RENDER_OT_view_show(wmOperatorType *ot)
static ScrArea * find_area_showing_render_result(bContext *C, Scene *scene, wmWindow **r_win)
ScrArea * render_view_open(bContext *C, int mx, int my, ReportList *reports)
static wmOperatorStatus render_view_show_invoke(bContext *C, wmOperator *op, const wmEvent *event)
static ScrArea * find_area_image_empty(bContext *C)
static wmOperatorStatus render_view_cancel_exec(bContext *C, wmOperator *)
static ScrArea * biggest_non_image_area(bContext *C)
void RENDER_OT_view_cancel(wmOperatorType *ot)
void * first
struct RenderData r
ListBase spacedata
bScreen * full
struct ScrArea * next
SpaceLink * next
struct Image * image
ListBase areabase
float xmin
float ymin
int xy[2]
Definition WM_types.hh:761
struct ReportList * reports
wmOperatorType * ot
Definition wm_files.cc:4237
void wm_window_raise(wmWindow *win)
void wm_window_close(bContext *C, wmWindowManager *wm, wmWindow *win)
Definition wm_window.cc:463
void WM_window_dpi_set_userdef(const wmWindow *win)
Definition wm_window.cc:654
wmWindow * WM_window_open(bContext *C, const char *title, const rcti *rect_unscaled, int space_type, bool toplevel, bool dialog, bool temp, eWindowAlignment alignment, void(*area_setup_fn)(bScreen *screen, ScrArea *area, void *user_data), void *area_setup_user_data)
bool WM_window_is_temp_screen(const wmWindow *win)
eWM_CapabilitiesFlag WM_capabilities_flag()
Scene * WM_window_get_active_scene(const wmWindow *win)
void wm_window_lower(wmWindow *win)
bScreen * WM_window_get_active_screen(const wmWindow *win)