Blender V2.61 - r43446

image_buttons.c

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