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