|
Blender
V2.59
|
00001 /* 00002 * $Id: image_buttons.c 38551 2011-07-21 00:41:00Z 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) 2001-2002 by NaN Holding BV. 00021 * All rights reserved. 00022 * 00023 * Contributor(s): Blender Foundation, 2002-2009 00024 * 00025 * ***** END GPL LICENSE BLOCK ***** 00026 */ 00027 00034 #include <string.h> 00035 #include <stdio.h> 00036 00037 #include "DNA_meshdata_types.h" 00038 #include "DNA_object_types.h" 00039 #include "DNA_node_types.h" 00040 #include "DNA_scene_types.h" 00041 00042 #include "MEM_guardedalloc.h" 00043 00044 #include "BLI_blenlib.h" 00045 #include "BLI_math.h" 00046 #include "BLI_editVert.h" 00047 #include "BLI_rand.h" 00048 #include "BLI_utildefines.h" 00049 00050 #include "BKE_colortools.h" 00051 #include "BKE_context.h" 00052 #include "BKE_customdata.h" 00053 #include "BKE_image.h" 00054 #include "BKE_mesh.h" 00055 #include "BKE_node.h" 00056 #include "BKE_screen.h" 00057 00058 #include "RE_pipeline.h" 00059 00060 #include "IMB_imbuf.h" 00061 #include "IMB_imbuf_types.h" 00062 00063 #include "ED_gpencil.h" 00064 #include "ED_image.h" 00065 #include "ED_screen.h" 00066 00067 #include "RNA_access.h" 00068 00069 #include "WM_api.h" 00070 #include "WM_types.h" 00071 00072 #include "UI_interface.h" 00073 #include "UI_resources.h" 00074 00075 #include "image_intern.h" 00076 00077 #define B_REDR 1 00078 #define B_IMAGECHANGED 2 00079 #define B_NOP 0 00080 #define B_TWINANIM 5 00081 #define B_SIMAGETILE 6 00082 #define B_IDNAME 10 00083 #define B_FACESEL_PAINT_TEST 11 00084 #define B_SIMA_RECORD 12 00085 #define B_SIMA_PLAY 13 00086 00087 #define B_SIMANOTHING 16 00088 #define B_SIMABRUSHCHANGE 17 00089 #define B_SIMABRUSHBROWSE 18 00090 #define B_SIMABRUSHLOCAL 19 00091 #define B_SIMABRUSHDELETE 20 00092 #define B_KEEPDATA 21 00093 #define B_SIMABTEXBROWSE 22 00094 #define B_SIMABTEXDELETE 23 00095 #define B_VPCOLSLI 24 00096 #define B_SIMACLONEBROWSE 25 00097 #define B_SIMACLONEDELETE 26 00098 00099 /* proto */ 00100 00101 static void image_info(Scene *scene, ImageUser *iuser, Image *ima, ImBuf *ibuf, char *str) 00102 { 00103 int ofs= 0; 00104 00105 str[0]= 0; 00106 00107 if(ima==NULL) return; 00108 00109 if(ibuf==NULL) { 00110 ofs+= sprintf(str, "Can't Load Image"); 00111 } 00112 else { 00113 if(ima->source==IMA_SRC_MOVIE) { 00114 ofs+= sprintf(str, "Movie"); 00115 if(ima->anim) 00116 ofs+= sprintf(str+ofs, "%d frs", IMB_anim_get_duration(ima->anim)); 00117 } 00118 else 00119 ofs+= sprintf(str, "Image"); 00120 00121 ofs+= sprintf(str+ofs, ": size %d x %d,", ibuf->x, ibuf->y); 00122 00123 if(ibuf->rect_float) { 00124 if(ibuf->channels!=4) { 00125 ofs+= sprintf(str+ofs, "%d float channel(s)", ibuf->channels); 00126 } 00127 else if(ibuf->depth==32) 00128 ofs+= sprintf(str+ofs, " RGBA float"); 00129 else 00130 ofs+= sprintf(str+ofs, " RGB float"); 00131 } 00132 else { 00133 if(ibuf->depth==32) 00134 ofs+= sprintf(str+ofs, " RGBA byte"); 00135 else 00136 ofs+= sprintf(str+ofs, " RGB byte"); 00137 } 00138 if(ibuf->zbuf || ibuf->zbuf_float) 00139 ofs+= sprintf(str+ofs, " + Z"); 00140 00141 if(ima->source==IMA_SRC_SEQUENCE) { 00142 char *file= BLI_last_slash(ibuf->name); 00143 if(file==NULL) file= ibuf->name; 00144 else file++; 00145 ofs+= sprintf(str+ofs, ", %s", file); 00146 } 00147 } 00148 00149 /* the frame number, even if we cant */ 00150 if(ima->source==IMA_SRC_SEQUENCE) { 00151 /* don't use iuser->framenr directly because it may not be updated if auto-refresh is off */ 00152 const int framenr= BKE_image_user_get_frame(iuser, CFRA, 0); 00153 ofs+= sprintf(str+ofs, ", Frame: %d", framenr); 00154 } 00155 00156 (void)ofs; 00157 } 00158 00159 /* gets active viewer user */ 00160 struct ImageUser *ntree_get_active_iuser(bNodeTree *ntree) 00161 { 00162 bNode *node; 00163 00164 if(ntree) 00165 for(node= ntree->nodes.first; node; node= node->next) 00166 if( ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER)) 00167 if(node->flag & NODE_DO_OUTPUT) 00168 return node->storage; 00169 return NULL; 00170 } 00171 00172 00173 /* ************ panel stuff ************* */ 00174 00175 /* is used for both read and write... */ 00176 00177 static int image_panel_poll(const bContext *C, PanelType *UNUSED(pt)) 00178 { 00179 SpaceImage *sima= CTX_wm_space_image(C); 00180 ImBuf *ibuf; 00181 void *lock; 00182 int result; 00183 00184 ibuf= ED_space_image_acquire_buffer(sima, &lock); 00185 result= ibuf && ibuf->rect_float; 00186 ED_space_image_release_buffer(sima, lock); 00187 00188 return result; 00189 } 00190 00191 static void image_panel_curves(const bContext *C, Panel *pa) 00192 { 00193 bScreen *sc= CTX_wm_screen(C); 00194 SpaceImage *sima= CTX_wm_space_image(C); 00195 ImBuf *ibuf; 00196 PointerRNA simaptr; 00197 int levels; 00198 void *lock; 00199 00200 ibuf= ED_space_image_acquire_buffer(sima, &lock); 00201 00202 if(ibuf) { 00203 if(sima->cumap==NULL) 00204 sima->cumap= curvemapping_add(4, 0.0f, 0.0f, 1.0f, 1.0f); 00205 00206 /* curvemap black/white levels only works for RGBA */ 00207 levels= (ibuf->channels==4); 00208 00209 RNA_pointer_create(&sc->id, &RNA_SpaceImageEditor, sima, &simaptr); 00210 uiTemplateCurveMapping(pa->layout, &simaptr, "curve", 'c', levels, 0); 00211 } 00212 00213 ED_space_image_release_buffer(sima, lock); 00214 } 00215 00216 #if 0 00217 /* 0: disable preview 00218 otherwise refresh preview 00219 00220 XXX if you put this back, also check XXX in image_main_area_draw() */ 00221 */ 00222 void image_preview_event(int event) 00223 { 00224 int exec= 0; 00225 00226 if(event==0) { 00227 G.scene->r.scemode &= ~R_COMP_CROP; 00228 exec= 1; 00229 } 00230 else { 00231 if(image_preview_active(curarea, NULL, NULL)) { 00232 G.scene->r.scemode |= R_COMP_CROP; 00233 exec= 1; 00234 } 00235 else 00236 G.scene->r.scemode &= ~R_COMP_CROP; 00237 } 00238 00239 if(exec && G.scene->nodetree) { 00240 /* should work when no node editor in screen..., so we execute right away */ 00241 00242 ntreeCompositTagGenerators(G.scene->nodetree); 00243 00244 G.afbreek= 0; 00245 G.scene->nodetree->timecursor= set_timecursor; 00246 G.scene->nodetree->test_break= blender_test_break; 00247 00248 BIF_store_spare(); 00249 00250 ntreeCompositExecTree(G.scene->nodetree, &G.scene->r, 1); /* 1 is do_previews */ 00251 00252 G.scene->nodetree->timecursor= NULL; 00253 G.scene->nodetree->test_break= NULL; 00254 00255 scrarea_do_windraw(curarea); 00256 waitcursor(0); 00257 00258 WM_event_add_notifier(C, NC_IMAGE, ima_v); 00259 } 00260 } 00261 00262 00263 /* nothing drawn here, we use it to store values */ 00264 static void preview_cb(struct ScrArea *sa, struct uiBlock *block) 00265 { 00266 SpaceImage *sima= sa->spacedata.first; 00267 rctf dispf; 00268 rcti *disprect= &G.scene->r.disprect; 00269 int winx= (G.scene->r.size*G.scene->r.xsch)/100; 00270 int winy= (G.scene->r.size*G.scene->r.ysch)/100; 00271 int mval[2]; 00272 00273 if(G.scene->r.mode & R_BORDER) { 00274 winx*= (G.scene->r.border.xmax - G.scene->r.border.xmin); 00275 winy*= (G.scene->r.border.ymax - G.scene->r.border.ymin); 00276 } 00277 00278 /* while dragging we need to update the rects, otherwise it doesn't end with correct one */ 00279 00280 BLI_init_rctf(&dispf, 15.0f, (block->maxx - block->minx)-15.0f, 15.0f, (block->maxy - block->miny)-15.0f); 00281 ui_graphics_to_window_rct(sa->win, &dispf, disprect); 00282 00283 /* correction for gla draw */ 00284 BLI_translate_rcti(disprect, -curarea->winrct.xmin, -curarea->winrct.ymin); 00285 00286 calc_image_view(sima, 'p'); 00287 // printf("winrct %d %d %d %d\n", disprect->xmin, disprect->ymin,disprect->xmax, disprect->ymax); 00288 /* map to image space coordinates */ 00289 mval[0]= disprect->xmin; mval[1]= disprect->ymin; 00290 areamouseco_to_ipoco(v2d, mval, &dispf.xmin, &dispf.ymin); 00291 mval[0]= disprect->xmax; mval[1]= disprect->ymax; 00292 areamouseco_to_ipoco(v2d, mval, &dispf.xmax, &dispf.ymax); 00293 00294 /* map to render coordinates */ 00295 disprect->xmin= dispf.xmin; 00296 disprect->xmax= dispf.xmax; 00297 disprect->ymin= dispf.ymin; 00298 disprect->ymax= dispf.ymax; 00299 00300 CLAMP(disprect->xmin, 0, winx); 00301 CLAMP(disprect->xmax, 0, winx); 00302 CLAMP(disprect->ymin, 0, winy); 00303 CLAMP(disprect->ymax, 0, winy); 00304 // printf("drawrct %d %d %d %d\n", disprect->xmin, disprect->ymin,disprect->xmax, disprect->ymax); 00305 00306 } 00307 00308 static int is_preview_allowed(ScrArea *cur) 00309 { 00310 SpaceImage *sima= cur->spacedata.first; 00311 ScrArea *sa; 00312 00313 /* check if another areawindow has preview set */ 00314 for(sa=G.curscreen->areabase.first; sa; sa= sa->next) { 00315 if(sa!=cur && sa->spacetype==SPACE_IMAGE) { 00316 if(image_preview_active(sa, NULL, NULL)) 00317 return 0; 00318 } 00319 } 00320 /* check image type */ 00321 if(sima->image==NULL || sima->image->type!=IMA_TYPE_COMPOSITE) 00322 return 0; 00323 00324 return 1; 00325 } 00326 00327 00328 static void image_panel_preview(ScrArea *sa, short cntrl) // IMAGE_HANDLER_PREVIEW 00329 { 00330 uiBlock *block; 00331 SpaceImage *sima= sa->spacedata.first; 00332 int ofsx, ofsy; 00333 00334 if(is_preview_allowed(sa)==0) { 00335 rem_blockhandler(sa, IMAGE_HANDLER_PREVIEW); 00336 G.scene->r.scemode &= ~R_COMP_CROP; /* quite weak */ 00337 return; 00338 } 00339 00340 block= uiBeginBlock(C, ar, "image_panel_preview", UI_EMBOSS); 00341 uiPanelControl(UI_PNL_SOLID | UI_PNL_CLOSE | UI_PNL_SCALE | cntrl); 00342 uiSetPanelHandler(IMAGE_HANDLER_PREVIEW); // for close and esc 00343 00344 ofsx= -150+(sa->winx/2)/sima->blockscale; 00345 ofsy= -100+(sa->winy/2)/sima->blockscale; 00346 if(uiNewPanel(C, ar, block, "Preview", "Image", ofsx, ofsy, 300, 200)==0) return; 00347 00348 uiBlockSetDrawExtraFunc(block, preview_cb); 00349 00350 } 00351 #endif 00352 00353 00354 /* ********************* callbacks for standard image buttons *************** */ 00355 00356 static char *slot_menu(void) 00357 { 00358 char *str; 00359 int a, slot; 00360 00361 str= MEM_callocN(IMA_MAX_RENDER_SLOT*32, "menu slots"); 00362 00363 strcpy(str, "Slot %t"); 00364 a= strlen(str); 00365 00366 for(slot=0; slot<IMA_MAX_RENDER_SLOT; slot++) 00367 a += sprintf(str+a, "|Slot %d %%x%d", slot+1, slot); 00368 00369 return str; 00370 } 00371 00372 /* TODO, curlay should be removed? */ 00373 static char *layer_menu(RenderResult *rr, short *UNUSED(curlay)) 00374 { 00375 RenderLayer *rl; 00376 int len= 64 + 32*BLI_countlist(&rr->layers); 00377 short a, nr= 0; 00378 char *str= MEM_callocN(len, "menu layers"); 00379 00380 strcpy(str, "Layer %t"); 00381 a= strlen(str); 00382 00383 /* compo result */ 00384 if(rr->rectf) { 00385 a+= sprintf(str+a, "|Composite %%x0"); 00386 nr= 1; 00387 } 00388 for(rl= rr->layers.first; rl; rl= rl->next, nr++) { 00389 a+= sprintf(str+a, "|%s %%x%d", rl->name, nr); 00390 } 00391 00392 /* no curlay clip here, on render (redraws) the amount of layers can be 1 fir single-layer render */ 00393 00394 return str; 00395 } 00396 00397 /* rl==NULL means composite result */ 00398 static char *pass_menu(RenderLayer *rl, short *curpass) 00399 { 00400 RenderPass *rpass; 00401 int len= 64 + 32*(rl?BLI_countlist(&rl->passes):1); 00402 short a, nr= 0; 00403 char *str= MEM_callocN(len, "menu layers"); 00404 00405 strcpy(str, "Pass %t"); 00406 a= strlen(str); 00407 00408 /* rendered results don't have a Combined pass */ 00409 if(rl==NULL || rl->rectf) { 00410 a+= sprintf(str+a, "|Combined %%x0"); 00411 nr= 1; 00412 } 00413 00414 if(rl) 00415 for(rpass= rl->passes.first; rpass; rpass= rpass->next, nr++) 00416 a+= sprintf(str+a, "|%s %%x%d", rpass->name, nr); 00417 00418 if(*curpass >= nr) 00419 *curpass= 0; 00420 00421 return str; 00422 } 00423 00424 static void set_frames_cb(bContext *C, void *ima_v, void *iuser_v) 00425 { 00426 Scene *scene= CTX_data_scene(C); 00427 Image *ima= ima_v; 00428 ImageUser *iuser= iuser_v; 00429 00430 if(ima->anim) { 00431 iuser->frames = IMB_anim_get_duration(ima->anim); 00432 BKE_image_user_calc_frame(iuser, scene->r.cfra, 0); 00433 } 00434 } 00435 00436 /* 5 layer button callbacks... */ 00437 static void image_multi_cb(bContext *C, void *rr_v, void *iuser_v) 00438 { 00439 ImageUser *iuser= iuser_v; 00440 00441 BKE_image_multilayer_index(rr_v, iuser); 00442 WM_event_add_notifier(C, NC_IMAGE|ND_DRAW, NULL); 00443 } 00444 static void image_multi_inclay_cb(bContext *C, void *rr_v, void *iuser_v) 00445 { 00446 RenderResult *rr= rr_v; 00447 ImageUser *iuser= iuser_v; 00448 int tot= BLI_countlist(&rr->layers) + (rr->rectf?1:0); /* fake compo result layer */ 00449 00450 if(iuser->layer<tot-1) { 00451 iuser->layer++; 00452 BKE_image_multilayer_index(rr, iuser); 00453 WM_event_add_notifier(C, NC_IMAGE|ND_DRAW, NULL); 00454 } 00455 } 00456 static void image_multi_declay_cb(bContext *C, void *rr_v, void *iuser_v) 00457 { 00458 ImageUser *iuser= iuser_v; 00459 00460 if(iuser->layer>0) { 00461 iuser->layer--; 00462 BKE_image_multilayer_index(rr_v, iuser); 00463 WM_event_add_notifier(C, NC_IMAGE|ND_DRAW, NULL); 00464 } 00465 } 00466 static void image_multi_incpass_cb(bContext *C, void *rr_v, void *iuser_v) 00467 { 00468 RenderResult *rr= rr_v; 00469 ImageUser *iuser= iuser_v; 00470 RenderLayer *rl= BLI_findlink(&rr->layers, iuser->layer); 00471 00472 if(rl) { 00473 int tot= BLI_countlist(&rl->passes) + (rl->rectf?1:0); /* builtin render result has no combined pass in list */ 00474 if(iuser->pass<tot-1) { 00475 iuser->pass++; 00476 BKE_image_multilayer_index(rr, iuser); 00477 WM_event_add_notifier(C, NC_IMAGE|ND_DRAW, NULL); 00478 } 00479 } 00480 } 00481 static void image_multi_decpass_cb(bContext *C, void *rr_v, void *iuser_v) 00482 { 00483 ImageUser *iuser= iuser_v; 00484 00485 if(iuser->pass>0) { 00486 iuser->pass--; 00487 BKE_image_multilayer_index(rr_v, iuser); 00488 WM_event_add_notifier(C, NC_IMAGE|ND_DRAW, NULL); 00489 } 00490 } 00491 00492 #if 0 00493 static void image_pack_cb(bContext *C, void *ima_v, void *iuser_v) 00494 { 00495 if(ima_v) { 00496 Image *ima= ima_v; 00497 if(ima->source!=IMA_SRC_SEQUENCE && ima->source!=IMA_SRC_MOVIE) { 00498 if (ima->packedfile) { 00499 if (G.fileflags & G_AUTOPACK) { 00500 if (okee("Disable AutoPack ?")) { 00501 G.fileflags &= ~G_AUTOPACK; 00502 } 00503 } 00504 00505 if ((G.fileflags & G_AUTOPACK) == 0) { 00506 unpackImage(NULL, ima, PF_ASK); /* XXX report errors */ 00507 ED_undo_push(C, "Unpack image"); 00508 } 00509 } 00510 else { 00511 ImBuf *ibuf= BKE_image_get_ibuf(ima, iuser_v); 00512 if (ibuf && (ibuf->userflags & IB_BITMAPDIRTY)) { 00513 // XXX error("Can't pack painted image. Save image or use Repack as PNG."); 00514 } else { 00515 ima->packedfile = newPackedFile(NULL, ima->name); /* XXX report errors */ 00516 ED_undo_push(C, "Pack image"); 00517 } 00518 } 00519 } 00520 } 00521 } 00522 #endif 00523 00524 #if 0 00525 static void image_freecache_cb(bContext *C, void *ima_v, void *unused) 00526 { 00527 Scene *scene= CTX_data_scene(C); 00528 BKE_image_free_anim_ibufs(ima_v, scene->r.cfra); 00529 WM_event_add_notifier(C, NC_IMAGE, ima_v); 00530 } 00531 #endif 00532 00533 #if 0 00534 static void image_user_change(bContext *C, void *iuser_v, void *unused) 00535 { 00536 Scene *scene= CTX_data_scene(C); 00537 BKE_image_user_calc_imanr(iuser_v, scene->r.cfra, 0); 00538 } 00539 #endif 00540 00541 static void uiblock_layer_pass_buttons(uiLayout *layout, RenderResult *rr, ImageUser *iuser, int w, short *render_slot) 00542 { 00543 uiBlock *block= uiLayoutGetBlock(layout); 00544 uiBut *but; 00545 RenderLayer *rl= NULL; 00546 int wmenu1, wmenu2, wmenu3; 00547 char *strp; 00548 00549 uiLayoutRow(layout, 1); 00550 00551 /* layer menu is 1/3 larger than pass */ 00552 wmenu1= (2*w)/5; 00553 wmenu2= (3*w)/5; 00554 wmenu3= (3*w)/6; 00555 00556 /* menu buts */ 00557 if(render_slot) { 00558 strp= slot_menu(); 00559 but= uiDefButS(block, MENU, 0, strp, 0, 0, wmenu1, UI_UNIT_Y, render_slot, 0,0,0,0, "Select Slot"); 00560 uiButSetFunc(but, image_multi_cb, rr, iuser); 00561 MEM_freeN(strp); 00562 } 00563 00564 if(rr) { 00565 strp= layer_menu(rr, &iuser->layer); 00566 but= uiDefButS(block, MENU, 0, strp, 0, 0, wmenu2, UI_UNIT_Y, &iuser->layer, 0,0,0,0, "Select Layer"); 00567 uiButSetFunc(but, image_multi_cb, rr, iuser); 00568 MEM_freeN(strp); 00569 00570 rl= BLI_findlink(&rr->layers, iuser->layer - (rr->rectf?1:0)); /* fake compo layer, return NULL is meant to be */ 00571 strp= pass_menu(rl, &iuser->pass); 00572 but= uiDefButS(block, MENU, 0, strp, 0, 0, wmenu3, UI_UNIT_Y, &iuser->pass, 0,0,0,0, "Select Pass"); 00573 uiButSetFunc(but, image_multi_cb, rr, iuser); 00574 MEM_freeN(strp); 00575 } 00576 } 00577 00578 static void uiblock_layer_pass_arrow_buttons(uiLayout *layout, RenderResult *rr, ImageUser *iuser, short *render_slot) 00579 { 00580 uiBlock *block= uiLayoutGetBlock(layout); 00581 uiLayout *row; 00582 uiBut *but; 00583 const float dpi_fac= UI_DPI_FAC; 00584 00585 row= uiLayoutRow(layout, 1); 00586 00587 if(rr==NULL || iuser==NULL) 00588 return; 00589 if(rr->layers.first==NULL) { 00590 uiItemL(row, "No Layers in Render Result.", ICON_NONE); 00591 return; 00592 } 00593 00594 /* decrease, increase arrows */ 00595 but= uiDefIconBut(block, BUT, 0, ICON_TRIA_LEFT, 0,0,17,20, NULL, 0, 0, 0, 0, "Previous Layer"); 00596 uiButSetFunc(but, image_multi_declay_cb, rr, iuser); 00597 but= uiDefIconBut(block, BUT, 0, ICON_TRIA_RIGHT, 0,0,18,20, NULL, 0, 0, 0, 0, "Next Layer"); 00598 uiButSetFunc(but, image_multi_inclay_cb, rr, iuser); 00599 00600 uiblock_layer_pass_buttons(row, rr, iuser, 230 * dpi_fac, render_slot); 00601 00602 /* decrease, increase arrows */ 00603 but= uiDefIconBut(block, BUT, 0, ICON_TRIA_LEFT, 0,0,17,20, NULL, 0, 0, 0, 0, "Previous Pass"); 00604 uiButSetFunc(but, image_multi_decpass_cb, rr, iuser); 00605 but= uiDefIconBut(block, BUT, 0, ICON_TRIA_RIGHT, 0,0,18,20, NULL, 0, 0, 0, 0, "Next Pass"); 00606 uiButSetFunc(but, image_multi_incpass_cb, rr, iuser); 00607 00608 uiBlockEndAlign(block); 00609 } 00610 00611 // XXX HACK! 00612 // static int packdummy=0; 00613 00614 typedef struct RNAUpdateCb { 00615 PointerRNA ptr; 00616 PropertyRNA *prop; 00617 ImageUser *iuser; 00618 } RNAUpdateCb; 00619 00620 static void rna_update_cb(bContext *C, void *arg_cb, void *UNUSED(arg)) 00621 { 00622 RNAUpdateCb *cb= (RNAUpdateCb*)arg_cb; 00623 00624 /* ideally this would be done by RNA itself, but there we have 00625 no image user available, so we just update this flag here */ 00626 cb->iuser->ok= 1; 00627 00628 /* we call update here on the pointer property, this way the 00629 owner of the image pointer can still define it's own update 00630 and notifier */ 00631 RNA_property_update(C, &cb->ptr, cb->prop); 00632 } 00633 00634 void uiTemplateImage(uiLayout *layout, bContext *C, PointerRNA *ptr, const char *propname, PointerRNA *userptr, int compact) 00635 { 00636 PropertyRNA *prop; 00637 PointerRNA imaptr; 00638 RNAUpdateCb *cb; 00639 Image *ima; 00640 ImageUser *iuser; 00641 ImBuf *ibuf; 00642 Scene *scene= CTX_data_scene(C); 00643 uiLayout *row, *split, *col; 00644 uiBlock *block; 00645 uiBut *but; 00646 char str[128]; 00647 void *lock; 00648 00649 if(!ptr->data) 00650 return; 00651 00652 prop= RNA_struct_find_property(ptr, propname); 00653 if(!prop) { 00654 printf("uiTemplateImage: property not found: %s.%s\n", RNA_struct_identifier(ptr->type), propname); 00655 return; 00656 } 00657 00658 if(RNA_property_type(prop) != PROP_POINTER) { 00659 printf("uiTemplateImage: expected pointer property for %s.%s\n", RNA_struct_identifier(ptr->type), propname); 00660 return; 00661 } 00662 00663 block= uiLayoutGetBlock(layout); 00664 00665 imaptr= RNA_property_pointer_get(ptr, prop); 00666 ima= imaptr.data; 00667 iuser= userptr->data; 00668 00669 cb= MEM_callocN(sizeof(RNAUpdateCb), "RNAUpdateCb"); 00670 cb->ptr= *ptr; 00671 cb->prop= prop; 00672 cb->iuser= iuser; 00673 00674 uiLayoutSetContextPointer(layout, "edit_image", &imaptr); 00675 00676 if(!compact) 00677 uiTemplateID(layout, C, ptr, propname, "IMAGE_OT_new", "IMAGE_OT_open", NULL); 00678 00679 // XXX missing: reload, pack 00680 00681 if(ima) { 00682 uiBlockSetNFunc(block, rna_update_cb, MEM_dupallocN(cb), NULL); 00683 00684 if(ima->source == IMA_SRC_VIEWER) { 00685 ibuf= BKE_image_acquire_ibuf(ima, iuser, &lock); 00686 image_info(scene, iuser, ima, ibuf, str); 00687 BKE_image_release_ibuf(ima, lock); 00688 00689 uiItemL(layout, ima->id.name+2, ICON_NONE); 00690 uiItemL(layout, str, ICON_NONE); 00691 00692 if(ima->type==IMA_TYPE_COMPOSITE) { 00693 // XXX not working yet 00694 #if 0 00695 iuser= ntree_get_active_iuser(scene->nodetree); 00696 if(iuser) { 00697 uiBlockBeginAlign(block); 00698 uiDefIconTextBut(block, BUT, B_SIMA_RECORD, ICON_REC, "Record", 10,120,100,20, 0, 0, 0, 0, 0, ""); 00699 uiDefIconTextBut(block, BUT, B_SIMA_PLAY, ICON_PLAY, "Play", 110,120,100,20, 0, 0, 0, 0, 0, ""); 00700 but= uiDefBut(block, BUT, B_NOP, "Free Cache", 210,120,100,20, 0, 0, 0, 0, 0, ""); 00701 uiButSetFunc(but, image_freecache_cb, ima, NULL); 00702 00703 if(iuser->frames) 00704 sprintf(str, "(%d) Frames:", iuser->framenr); 00705 else strcpy(str, "Frames:"); 00706 uiBlockBeginAlign(block); 00707 uiDefButI(block, NUM, imagechanged, str, 10, 90,150, 20, &iuser->frames, 0.0, MAXFRAMEF, 0, 0, "Sets the number of images of a movie to use"); 00708 uiDefButI(block, NUM, imagechanged, "StartFr:", 160,90,150,20, &iuser->sfra, 1.0, MAXFRAMEF, 0, 0, "Sets the global starting frame of the movie"); 00709 } 00710 #endif 00711 } 00712 else if(ima->type==IMA_TYPE_R_RESULT) { 00713 /* browse layer/passes */ 00714 Render *re= RE_GetRender(scene->id.name); 00715 RenderResult *rr= RE_AcquireResultRead(re); 00716 uiblock_layer_pass_arrow_buttons(layout, rr, iuser, &ima->render_slot); 00717 RE_ReleaseResult(re); 00718 } 00719 } 00720 else { 00721 uiItemR(layout, &imaptr, "source", 0, NULL, ICON_NONE); 00722 00723 if(ima->source != IMA_SRC_GENERATED) { 00724 row= uiLayoutRow(layout, 1); 00725 if (ima->packedfile) 00726 uiItemO(row, "", ICON_PACKAGE, "image.unpack"); 00727 else 00728 uiItemO(row, "", ICON_UGLYPACKAGE, "image.pack"); 00729 00730 row= uiLayoutRow(row, 0); 00731 uiLayoutSetEnabled(row, ima->packedfile==NULL); 00732 uiItemR(row, &imaptr, "filepath", 0, "", ICON_NONE); 00733 uiItemO(row, "", ICON_FILE_REFRESH, "image.reload"); 00734 } 00735 00736 // XXX what was this for? 00737 #if 0 00738 /* check for re-render, only buttons */ 00739 if(imagechanged==B_IMAGECHANGED) { 00740 if(iuser->flag & IMA_ANIM_REFRESHED) { 00741 iuser->flag &= ~IMA_ANIM_REFRESHED; 00742 WM_event_add_notifier(C, NC_IMAGE, ima); 00743 } 00744 } 00745 #endif 00746 00747 /* multilayer? */ 00748 if(ima->type==IMA_TYPE_MULTILAYER && ima->rr) { 00749 uiblock_layer_pass_arrow_buttons(layout, ima->rr, iuser, NULL); 00750 } 00751 else if(ima->source != IMA_SRC_GENERATED) { 00752 if(compact == 0) { 00753 ibuf= BKE_image_acquire_ibuf(ima, iuser, &lock); 00754 image_info(scene, iuser, ima, ibuf, str); 00755 BKE_image_release_ibuf(ima, lock); 00756 uiItemL(layout, str, ICON_NONE); 00757 } 00758 } 00759 00760 if(ima->source != IMA_SRC_GENERATED) { 00761 if(compact == 0) { /* background image view doesnt need these */ 00762 uiItemS(layout); 00763 00764 split= uiLayoutSplit(layout, 0, 0); 00765 00766 col= uiLayoutColumn(split, 0); 00767 uiItemR(col, &imaptr, "use_fields", 0, NULL, ICON_NONE); 00768 row= uiLayoutRow(col, 0); 00769 uiLayoutSetActive(row, RNA_boolean_get(&imaptr, "use_fields")); 00770 uiItemR(row, &imaptr, "field_order", UI_ITEM_R_EXPAND, NULL, ICON_NONE); 00771 00772 uiItemR(split, &imaptr, "use_premultiply", 0, NULL, ICON_NONE); 00773 } 00774 } 00775 00776 if(ELEM(ima->source, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE)) { 00777 uiItemS(layout); 00778 00779 split= uiLayoutSplit(layout, 0, 0); 00780 00781 col= uiLayoutColumn(split, 0); 00782 00783 sprintf(str, "(%d) Frames", iuser->framenr); 00784 uiItemR(col, userptr, "frame_duration", 0, str, ICON_NONE); 00785 if(ima->anim) { 00786 block= uiLayoutGetBlock(col); 00787 but= uiDefBut(block, BUT, 0, "Match Movie Length", 0, 0, UI_UNIT_X*2, UI_UNIT_Y, NULL, 0, 0, 0, 0, "Set the number of frames to match the movie or sequence."); 00788 uiButSetFunc(but, set_frames_cb, ima, iuser); 00789 } 00790 00791 uiItemR(col, userptr, "frame_start", 0, "Start", ICON_NONE); 00792 uiItemR(col, userptr, "frame_offset", 0, NULL, ICON_NONE); 00793 00794 col= uiLayoutColumn(split, 0); 00795 row= uiLayoutRow(col, 0); 00796 uiLayoutSetActive(row, RNA_boolean_get(&imaptr, "use_fields")); 00797 uiItemR(row, userptr, "fields_per_frame", 0, "Fields", ICON_NONE); 00798 uiItemR(col, userptr, "use_auto_refresh", 0, NULL, ICON_NONE); 00799 uiItemR(col, userptr, "use_cyclic", 0, NULL, ICON_NONE); 00800 } 00801 else if(ima->source==IMA_SRC_GENERATED) { 00802 split= uiLayoutSplit(layout, 0, 0); 00803 00804 col= uiLayoutColumn(split, 1); 00805 uiItemR(col, &imaptr, "generated_width", 0, "X", ICON_NONE); 00806 uiItemR(col, &imaptr, "generated_height", 0, "Y", ICON_NONE); 00807 uiItemR(col, &imaptr, "use_generated_float", 0, NULL, ICON_NONE); 00808 00809 uiItemR(split, &imaptr, "generated_type", UI_ITEM_R_EXPAND, NULL, ICON_NONE); 00810 } 00811 00812 } 00813 00814 uiBlockSetNFunc(block, NULL, NULL, NULL); 00815 } 00816 00817 MEM_freeN(cb); 00818 } 00819 00820 void uiTemplateImageLayers(uiLayout *layout, bContext *C, Image *ima, ImageUser *iuser) 00821 { 00822 Scene *scene= CTX_data_scene(C); 00823 RenderResult *rr; 00824 00825 /* render layers and passes */ 00826 if(ima && iuser) { 00827 const float dpi_fac= UI_DPI_FAC; 00828 rr= BKE_image_acquire_renderresult(scene, ima); 00829 uiblock_layer_pass_buttons(layout, rr, iuser, 160 * dpi_fac, (ima->type==IMA_TYPE_R_RESULT)? &ima->render_slot: NULL); 00830 BKE_image_release_renderresult(scene, ima); 00831 } 00832 } 00833 00834 void image_buttons_register(ARegionType *art) 00835 { 00836 PanelType *pt; 00837 00838 pt= MEM_callocN(sizeof(PanelType), "spacetype image panel curves"); 00839 strcpy(pt->idname, "IMAGE_PT_curves"); 00840 strcpy(pt->label, "Curves"); 00841 pt->draw= image_panel_curves; 00842 pt->poll= image_panel_poll; 00843 pt->flag |= PNL_DEFAULT_CLOSED; 00844 BLI_addtail(&art->paneltypes, pt); 00845 00846 pt= MEM_callocN(sizeof(PanelType), "spacetype image panel gpencil"); 00847 strcpy(pt->idname, "IMAGE_PT_gpencil"); 00848 strcpy(pt->label, "Grease Pencil"); 00849 pt->draw= gpencil_panel_standard; 00850 BLI_addtail(&art->paneltypes, pt); 00851 } 00852 00853 static int image_properties(bContext *C, wmOperator *UNUSED(op)) 00854 { 00855 ScrArea *sa= CTX_wm_area(C); 00856 ARegion *ar= image_has_buttons_region(sa); 00857 00858 if(ar) 00859 ED_region_toggle_hidden(C, ar); 00860 00861 return OPERATOR_FINISHED; 00862 } 00863 00864 void IMAGE_OT_properties(wmOperatorType *ot) 00865 { 00866 ot->name= "Properties"; 00867 ot->idname= "IMAGE_OT_properties"; 00868 ot->description= "Toggle display properties panel"; 00869 00870 ot->exec= image_properties; 00871 ot->poll= ED_operator_image_active; 00872 00873 /* flags */ 00874 ot->flag= 0; 00875 } 00876 00877 static int image_scopes(bContext *C, wmOperator *UNUSED(op)) 00878 { 00879 ScrArea *sa= CTX_wm_area(C); 00880 ARegion *ar= image_has_scope_region(sa); 00881 00882 if(ar) 00883 ED_region_toggle_hidden(C, ar); 00884 00885 return OPERATOR_FINISHED; 00886 } 00887 00888 void IMAGE_OT_scopes(wmOperatorType *ot) 00889 { 00890 ot->name= "Scopes"; 00891 ot->idname= "IMAGE_OT_scopes"; 00892 ot->description= "Toggle display scopes panel"; 00893 00894 ot->exec= image_scopes; 00895 ot->poll= ED_operator_image_active; 00896 00897 /* flags */ 00898 ot->flag= 0; 00899 } 00900