|
Blender
V2.59
|
00001 /* 00002 * $Id: render_view.c 37232 2011-06-06 00:42:36Z campbellbarton $ 00003 * 00004 * ***** BEGIN GPL LICENSE BLOCK ***** 00005 * 00006 * This program is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU General Public License 00008 * as published by the Free Software Foundation; either version 2 00009 * of the License, or (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software Foundation, 00018 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00019 * 00020 * The Original Code is Copyright (C) 2008 Blender Foundation. 00021 * All rights reserved. 00022 * 00023 * 00024 * ***** END GPL LICENSE BLOCK ***** 00025 */ 00026 00031 #include <string.h> 00032 #include <stddef.h> 00033 00034 #include "MEM_guardedalloc.h" 00035 00036 #include "BLI_blenlib.h" 00037 #include "BLI_utildefines.h" 00038 00039 #include "DNA_scene_types.h" 00040 00041 #include "BKE_blender.h" 00042 #include "BKE_context.h" 00043 #include "BKE_image.h" 00044 #include "BKE_global.h" 00045 #include "BKE_main.h" 00046 #include "BKE_node.h" 00047 #include "BKE_report.h" 00048 #include "BKE_screen.h" 00049 00050 #include "WM_api.h" 00051 #include "WM_types.h" 00052 00053 #include "ED_screen.h" 00054 00055 #include "wm_window.h" 00056 00057 #include "render_intern.h" 00058 00059 /*********************** utilities for finding areas *************************/ 00060 00061 /* returns biggest area that is not uv/image editor. Note that it uses buttons */ 00062 /* window as the last possible alternative. */ 00063 static ScrArea *biggest_non_image_area(bContext *C) 00064 { 00065 bScreen *sc= CTX_wm_screen(C); 00066 ScrArea *sa, *big= NULL; 00067 int size, maxsize= 0, bwmaxsize= 0; 00068 short foundwin= 0; 00069 00070 for(sa= sc->areabase.first; sa; sa= sa->next) { 00071 if(sa->winx > 30 && sa->winy > 30) { 00072 size= sa->winx*sa->winy; 00073 if(sa->spacetype == SPACE_BUTS) { 00074 if(foundwin == 0 && size > bwmaxsize) { 00075 bwmaxsize= size; 00076 big= sa; 00077 } 00078 } 00079 else if(sa->spacetype != SPACE_IMAGE && size > maxsize) { 00080 maxsize= size; 00081 big= sa; 00082 foundwin= 1; 00083 } 00084 } 00085 } 00086 00087 return big; 00088 } 00089 00090 static ScrArea *biggest_area(bContext *C) 00091 { 00092 bScreen *sc= CTX_wm_screen(C); 00093 ScrArea *sa, *big= NULL; 00094 int size, maxsize= 0; 00095 00096 for(sa= sc->areabase.first; sa; sa= sa->next) { 00097 size= sa->winx*sa->winy; 00098 if(size > maxsize) { 00099 maxsize= size; 00100 big= sa; 00101 } 00102 } 00103 return big; 00104 } 00105 00106 static ScrArea *find_area_showing_r_result(bContext *C, wmWindow **win) 00107 { 00108 wmWindowManager *wm= CTX_wm_manager(C); 00109 ScrArea *sa = NULL; 00110 SpaceImage *sima; 00111 00112 /* find an imagewindow showing render result */ 00113 for(*win=wm->windows.first; *win; *win= (*win)->next) { 00114 for(sa= (*win)->screen->areabase.first; sa; sa= sa->next) { 00115 if(sa->spacetype==SPACE_IMAGE) { 00116 sima= sa->spacedata.first; 00117 if(sima->image && sima->image->type==IMA_TYPE_R_RESULT) 00118 break; 00119 } 00120 } 00121 if(sa) 00122 break; 00123 } 00124 00125 return sa; 00126 } 00127 00128 static ScrArea *find_area_image_empty(bContext *C) 00129 { 00130 bScreen *sc= CTX_wm_screen(C); 00131 ScrArea *sa; 00132 SpaceImage *sima; 00133 00134 /* find an imagewindow showing render result */ 00135 for(sa=sc->areabase.first; sa; sa= sa->next) { 00136 if(sa->spacetype==SPACE_IMAGE) { 00137 sima= sa->spacedata.first; 00138 if(!sima->image) 00139 break; 00140 } 00141 } 00142 00143 return sa; 00144 } 00145 00146 /********************** open image editor for render *************************/ 00147 00148 /* new window uses x,y to set position */ 00149 void render_view_open(bContext *C, int mx, int my) 00150 { 00151 wmWindow *win= CTX_wm_window(C); 00152 Scene *scene= CTX_data_scene(C); 00153 ScrArea *sa= NULL; 00154 SpaceImage *sima; 00155 int area_was_image=0; 00156 00157 if(scene->r.displaymode==R_OUTPUT_NONE) 00158 return; 00159 00160 if(scene->r.displaymode==R_OUTPUT_WINDOW) { 00161 rcti rect; 00162 int sizex, sizey; 00163 00164 sizex= 10 + (scene->r.xsch*scene->r.size)/100; 00165 sizey= 40 + (scene->r.ysch*scene->r.size)/100; 00166 00167 /* arbitrary... miniature image window views don't make much sense */ 00168 if(sizex < 320) sizex= 320; 00169 if(sizey < 256) sizey= 256; 00170 00171 /* XXX some magic to calculate postition */ 00172 rect.xmin= mx + win->posx - sizex/2; 00173 rect.ymin= my + win->posy - sizey/2; 00174 rect.xmax= rect.xmin + sizex; 00175 rect.ymax= rect.ymin + sizey; 00176 00177 /* changes context! */ 00178 WM_window_open_temp(C, &rect, WM_WINDOW_RENDER); 00179 00180 sa= CTX_wm_area(C); 00181 } 00182 else if(scene->r.displaymode==R_OUTPUT_SCREEN) { 00183 if (CTX_wm_area(C) && CTX_wm_area(C)->spacetype == SPACE_IMAGE) 00184 area_was_image = 1; 00185 00186 /* this function returns with changed context */ 00187 sa= ED_screen_full_newspace(C, CTX_wm_area(C), SPACE_IMAGE); 00188 } 00189 00190 if(!sa) { 00191 sa= find_area_showing_r_result(C, &win); 00192 if(sa==NULL) 00193 sa= find_area_image_empty(C); 00194 00195 /* if area found in other window, we make that one show in front */ 00196 if(win && win!=CTX_wm_window(C)) 00197 wm_window_raise(win); 00198 00199 if(sa==NULL) { 00200 /* find largest open non-image area */ 00201 sa= biggest_non_image_area(C); 00202 if(sa) { 00203 ED_area_newspace(C, sa, SPACE_IMAGE); 00204 sima= sa->spacedata.first; 00205 00206 /* makes ESC go back to prev space */ 00207 sima->flag |= SI_PREVSPACE; 00208 } 00209 else { 00210 /* use any area of decent size */ 00211 sa= biggest_area(C); 00212 if(sa->spacetype!=SPACE_IMAGE) { 00213 // XXX newspace(sa, SPACE_IMAGE); 00214 sima= sa->spacedata.first; 00215 00216 /* makes ESC go back to prev space */ 00217 sima->flag |= SI_PREVSPACE; 00218 } 00219 } 00220 } 00221 } 00222 sima= sa->spacedata.first; 00223 00224 /* get the correct image, and scale it */ 00225 sima->image= BKE_image_verify_viewer(IMA_TYPE_R_RESULT, "Render Result"); 00226 00227 00228 /* if we're rendering to full screen, set appropriate hints on image editor 00229 * so it can restore properly on pressing esc */ 00230 if(sa->full) { 00231 sima->flag |= SI_FULLWINDOW; 00232 00233 /* Tell the image editor to revert to previous space in space list on close 00234 * _only_ if it wasn't already an image editor when the render was invoked */ 00235 if (area_was_image == 0) 00236 sima->flag |= SI_PREVSPACE; 00237 else { 00238 /* Leave it alone so the image editor will just go back from 00239 * full screen to the original tiled setup */ 00240 ; 00241 } 00242 } 00243 } 00244 00245 /*************************** cancel render viewer **********************/ 00246 00247 static int render_view_cancel_exec(bContext *C, wmOperator *UNUSED(op)) 00248 { 00249 wmWindow *win= CTX_wm_window(C); 00250 ScrArea *sa= CTX_wm_area(C); 00251 SpaceImage *sima= sa->spacedata.first; 00252 00253 /* test if we have a temp screen in front */ 00254 if(CTX_wm_window(C)->screen->temp) { 00255 wm_window_lower(CTX_wm_window(C)); 00256 return OPERATOR_FINISHED; 00257 } 00258 /* determine if render already shows */ 00259 else if(sima->flag & SI_PREVSPACE) { 00260 sima->flag &= ~SI_PREVSPACE; 00261 00262 if(sima->flag & SI_FULLWINDOW) { 00263 sima->flag &= ~SI_FULLWINDOW; 00264 ED_screen_full_prevspace(C, sa); 00265 } 00266 else 00267 ED_area_prevspace(C, sa); 00268 00269 return OPERATOR_FINISHED; 00270 } 00271 else if(sima->flag & SI_FULLWINDOW) { 00272 sima->flag &= ~SI_FULLWINDOW; 00273 ED_screen_full_toggle(C, win, sa); 00274 return OPERATOR_FINISHED; 00275 } 00276 00277 return OPERATOR_PASS_THROUGH; 00278 } 00279 00280 void RENDER_OT_view_cancel(struct wmOperatorType *ot) 00281 { 00282 /* identifiers */ 00283 ot->name= "Cancel Render View"; 00284 ot->description= "Cancel show render view"; 00285 ot->idname= "RENDER_OT_view_cancel"; 00286 00287 /* api callbacks */ 00288 ot->exec= render_view_cancel_exec; 00289 ot->poll= ED_operator_image_active; 00290 } 00291 00292 /************************* show render viewer *****************/ 00293 00294 static int render_view_show_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event) 00295 { 00296 wmWindow *wincur = CTX_wm_window(C); 00297 00298 /* test if we have currently a temp screen active */ 00299 if(wincur->screen->temp) { 00300 wm_window_lower(wincur); 00301 } 00302 else { 00303 wmWindow *win, *winshow; 00304 ScrArea *sa= find_area_showing_r_result(C, &winshow); 00305 00306 /* is there another window showing result? */ 00307 for(win= CTX_wm_manager(C)->windows.first; win; win= win->next) { 00308 if(win->screen->temp || (win==winshow && winshow!=wincur)) { 00309 wm_window_raise(win); 00310 return OPERATOR_FINISHED; 00311 } 00312 } 00313 00314 /* determine if render already shows */ 00315 if(sa) { 00316 /* but don't close it when rendering */ 00317 if(!G.rendering) { 00318 SpaceImage *sima= sa->spacedata.first; 00319 00320 if(sima->flag & SI_PREVSPACE) { 00321 sima->flag &= ~SI_PREVSPACE; 00322 00323 if(sima->flag & SI_FULLWINDOW) { 00324 sima->flag &= ~SI_FULLWINDOW; 00325 ED_screen_full_prevspace(C, sa); 00326 } 00327 else if(sima->next) { 00328 /* workaround for case of double prevspace, render window 00329 with a file browser on top of it (same as in ED_area_prevspace) */ 00330 if(sima->next->spacetype == SPACE_FILE && sima->next->next) 00331 ED_area_newspace(C, sa, sima->next->next->spacetype); 00332 else 00333 ED_area_newspace(C, sa, sima->next->spacetype); 00334 ED_area_tag_redraw(sa); 00335 } 00336 } 00337 } 00338 } 00339 else { 00340 render_view_open(C, event->x, event->y); 00341 } 00342 } 00343 00344 return OPERATOR_FINISHED; 00345 } 00346 00347 void RENDER_OT_view_show(struct wmOperatorType *ot) 00348 { 00349 /* identifiers */ 00350 ot->name= "Show/Hide Render View"; 00351 ot->description= "Toggle show render view"; 00352 ot->idname= "RENDER_OT_view_show"; 00353 00354 /* api callbacks */ 00355 ot->invoke= render_view_show_invoke; 00356 ot->poll= ED_operator_screenactive; 00357 } 00358