668d4a85bbdeaf471ddb5fcb99dc7aaf0413af26
[blender.git] / source / blender / editors / space_image / image_buttons.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
19  * All rights reserved.
20  *
21  * Contributor(s): Blender Foundation, 2002-2009
22  *
23  * ***** END GPL LICENSE BLOCK *****
24  */
25
26 /** \file blender/editors/space_image/image_buttons.c
27  *  \ingroup spimage
28  */
29
30 #include <string.h>
31 #include <stdio.h>
32
33 #include "DNA_meshdata_types.h"
34 #include "DNA_object_types.h"
35 #include "DNA_node_types.h"
36 #include "DNA_scene_types.h"
37
38 #include "MEM_guardedalloc.h"
39
40 #include "BLI_blenlib.h"
41 #include "BLI_math.h"
42 #include "BLI_rand.h"
43 #include "BLI_utildefines.h"
44
45 #include "BLF_translation.h"
46
47 #include "BKE_colortools.h"
48 #include "BKE_context.h"
49 #include "BKE_customdata.h"
50 #include "BKE_image.h"
51 #include "BKE_mesh.h"
52 #include "BKE_node.h"
53 #include "BKE_screen.h"
54
55 #include "RE_pipeline.h"
56
57 #include "IMB_imbuf.h"
58 #include "IMB_imbuf_types.h"
59
60 #include "ED_gpencil.h"
61 #include "ED_image.h"
62 #include "ED_screen.h"
63
64 #include "RNA_access.h"
65
66 #include "WM_api.h"
67 #include "WM_types.h"
68
69 #include "UI_interface.h"
70 #include "UI_resources.h"
71
72 #include "image_intern.h"
73
74 /* proto */
75
76 static void image_info(Scene *scene, ImageUser *iuser, Image *ima, ImBuf *ibuf, char *str)
77 {
78         int ofs = 0;
79
80         str[0] = 0;
81         
82         if (ima == NULL) return;
83
84         if (ibuf == NULL) {
85                 ofs += sprintf(str, IFACE_("Can't Load Image"));
86         }
87         else {
88                 if (ima->source == IMA_SRC_MOVIE) {
89                         ofs += sprintf(str, IFACE_("Movie"));
90                         if (ima->anim)
91                                 ofs += sprintf(str + ofs, IFACE_(" %d frs"), IMB_anim_get_duration(ima->anim, IMB_TC_RECORD_RUN));
92                 }
93                 else
94                         ofs += sprintf(str, IFACE_("Image"));
95
96                 ofs += sprintf(str + ofs, IFACE_(": size %d x %d,"), ibuf->x, ibuf->y);
97
98                 if (ibuf->rect_float) {
99                         if (ibuf->channels != 4) {
100                                 ofs += sprintf(str + ofs, IFACE_("%d float channel(s)"), ibuf->channels);
101                         }
102                         else if (ibuf->planes == R_IMF_PLANES_RGBA)
103                                 ofs += sprintf(str + ofs, IFACE_(" RGBA float"));
104                         else
105                                 ofs += sprintf(str + ofs, IFACE_(" RGB float"));
106                 }
107                 else {
108                         if (ibuf->planes == R_IMF_PLANES_RGBA)
109                                 ofs += sprintf(str + ofs, IFACE_(" RGBA byte"));
110                         else
111                                 ofs += sprintf(str + ofs, IFACE_(" RGB byte"));
112                 }
113                 if (ibuf->zbuf || ibuf->zbuf_float)
114                         ofs += sprintf(str + ofs, IFACE_(" + Z"));
115
116                 if (ima->source == IMA_SRC_SEQUENCE) {
117                         const char *file = BLI_last_slash(ibuf->name);
118                         if (file == NULL) file = ibuf->name;
119                         else file++;
120                         ofs += sprintf(str + ofs, ", %s", file);
121                 }
122         }
123
124         /* the frame number, even if we cant */
125         if (ima->source == IMA_SRC_SEQUENCE) {
126                 /* don't use iuser->framenr directly because it may not be updated if auto-refresh is off */
127                 const int framenr = BKE_image_user_frame_get(iuser, CFRA, 0, NULL);
128                 ofs += sprintf(str + ofs, IFACE_(", Frame: %d"), framenr);
129         }
130
131         (void)ofs;
132 }
133
134 /* gets active viewer user */
135 struct ImageUser *ntree_get_active_iuser(bNodeTree *ntree)
136 {
137         bNode *node;
138         
139         if (ntree)
140                 for (node = ntree->nodes.first; node; node = node->next)
141                         if (ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER))
142                                 if (node->flag & NODE_DO_OUTPUT)
143                                         return node->storage;
144         return NULL;
145 }
146
147
148 /* ************ panel stuff ************* */
149
150 #if 0
151 /* 0: disable preview 
152  * otherwise refresh preview
153  *
154  * XXX if you put this back, also check XXX in image_main_area_draw() */
155  * /
156 void image_preview_event(int event)
157 {
158         int exec = 0;
159         
160         if (event == 0) {
161                 G.scene->r.scemode &= ~R_COMP_CROP;
162                 exec = 1;
163         }
164         else {
165                 if (image_preview_active(curarea, NULL, NULL)) {
166                         G.scene->r.scemode |= R_COMP_CROP;
167                         exec = 1;
168                 }
169                 else
170                         G.scene->r.scemode &= ~R_COMP_CROP;
171         }
172         
173         if (exec && G.scene->nodetree) {
174                 Scene *scene = G.scene;
175                 /* should work when no node editor in screen..., so we execute right away */
176                 
177                 ntreeCompositTagGenerators(G.scene->nodetree);
178
179                 G.is_break = FALSE;
180                 G.scene->nodetree->timecursor = set_timecursor;
181                 G.scene->nodetree->test_break = blender_test_break;
182                 
183                 BIF_store_spare();
184                 
185                 ntreeCompositExecTree(scene->nodetree, &scene->r, 1, &scene->view_settings, &scene->display_settings);   /* 1 is do_previews */
186                 
187                 G.scene->nodetree->timecursor = NULL;
188                 G.scene->nodetree->test_break = NULL;
189                 
190                 scrarea_do_windraw(curarea);
191                 waitcursor(0);
192                 
193                 WM_event_add_notifier(C, NC_IMAGE, ima_v);
194         }
195 }
196
197
198 /* nothing drawn here, we use it to store values */
199 static void preview_cb(ScrArea *sa, struct uiBlock *block)
200 {
201         SpaceImage *sima = sa->spacedata.first;
202         rctf dispf;
203         rcti *disprect = &G.scene->r.disprect;
204         int winx = (G.scene->r.size * G.scene->r.xsch) / 100;
205         int winy = (G.scene->r.size * G.scene->r.ysch) / 100;
206         int mval[2];
207         
208         if (G.scene->r.mode & R_BORDER) {
209                 winx *= BLI_rcti_size_x(&G.scene->r.border);
210                 winy *= BLI_rctf_size_y(&G.scene->r.border);
211         }
212         
213         /* while dragging we need to update the rects, otherwise it doesn't end with correct one */
214
215         BLI_rctf_init(&dispf, 15.0f, BLI_rcti_size_x(&block->rect) - 15.0f, 15.0f, (BLI_rctf_size_y(&block->rect)) - 15.0f);
216         ui_graphics_to_window_rct(sa->win, &dispf, disprect);
217         
218         /* correction for gla draw */
219         BLI_rcti_translate(disprect, -curarea->winrct.xmin, -curarea->winrct.ymin);
220         
221         calc_image_view(sima, 'p');
222 //      printf("winrct %d %d %d %d\n", disprect->xmin, disprect->ymin, disprect->xmax, disprect->ymax);
223         /* map to image space coordinates */
224         mval[0] = disprect->xmin; mval[1] = disprect->ymin;
225         areamouseco_to_ipoco(v2d, mval, &dispf.xmin, &dispf.ymin);
226         mval[0] = disprect->xmax; mval[1] = disprect->ymax;
227         areamouseco_to_ipoco(v2d, mval, &dispf.xmax, &dispf.ymax);
228         
229         /* map to render coordinates */
230         disprect->xmin = dispf.xmin;
231         disprect->xmax = dispf.xmax;
232         disprect->ymin = dispf.ymin;
233         disprect->ymax = dispf.ymax;
234         
235         CLAMP(disprect->xmin, 0, winx);
236         CLAMP(disprect->xmax, 0, winx);
237         CLAMP(disprect->ymin, 0, winy);
238         CLAMP(disprect->ymax, 0, winy);
239 //      printf("drawrct %d %d %d %d\n", disprect->xmin, disprect->ymin, disprect->xmax, disprect->ymax);
240
241 }
242
243 static int is_preview_allowed(ScrArea *cur)
244 {
245         SpaceImage *sima = cur->spacedata.first;
246         ScrArea *sa;
247
248         /* check if another areawindow has preview set */
249         for (sa = G.curscreen->areabase.first; sa; sa = sa->next) {
250                 if (sa != cur && sa->spacetype == SPACE_IMAGE) {
251                         if (image_preview_active(sa, NULL, NULL))
252                                 return 0;
253                 }
254         }
255         /* check image type */
256         if (sima->image == NULL || sima->image->type != IMA_TYPE_COMPOSITE)
257                 return 0;
258         
259         return 1;
260 }
261
262
263 static void image_panel_preview(ScrArea *sa, short cntrl)   // IMAGE_HANDLER_PREVIEW
264 {
265         uiBlock *block;
266         SpaceImage *sima = sa->spacedata.first;
267         int ofsx, ofsy;
268         
269         if (is_preview_allowed(sa) == 0) {
270                 rem_blockhandler(sa, IMAGE_HANDLER_PREVIEW);
271                 G.scene->r.scemode &= ~R_COMP_CROP; /* quite weak */
272                 return;
273         }
274         
275         block = uiBeginBlock(C, ar, __func__, UI_EMBOSS);
276         uiPanelControl(UI_PNL_SOLID | UI_PNL_CLOSE | UI_PNL_SCALE | cntrl);
277         uiSetPanelHandler(IMAGE_HANDLER_PREVIEW);  // for close and esc
278         
279         ofsx = -150 + (sa->winx / 2) / sima->blockscale;
280         ofsy = -100 + (sa->winy / 2) / sima->blockscale;
281         if (uiNewPanel(C, ar, block, "Preview", "Image", ofsx, ofsy, 300, 200) == 0) return;
282         
283         uiBlockSetDrawExtraFunc(block, preview_cb);
284         
285 }
286 #endif
287
288
289 /* ********************* callbacks for standard image buttons *************** */
290
291 static char *slot_menu(void)
292 {
293         char *str;
294         int a, slot;
295         
296         str = MEM_callocN(IMA_MAX_RENDER_SLOT * 32, "menu slots");
297         
298         strcpy(str, IFACE_("Slot %t"));
299         a = strlen(str);
300
301         for (slot = 0; slot < IMA_MAX_RENDER_SLOT; slot++)
302                 a += sprintf(str + a, IFACE_("|Slot %d %%x%d"), slot + 1, slot);
303         
304         return str;
305 }
306
307 /* TODO, curlay should be removed? */
308 static char *layer_menu(RenderResult *rr, short *UNUSED(curlay))
309 {
310         RenderLayer *rl;
311         int len = 64 + RE_MAXNAME * BLI_countlist(&rr->layers);
312         short a, nr = 0;
313         char *str = MEM_callocN(len, "menu layers");
314         
315         strcpy(str, IFACE_("Layer %t"));
316         a = strlen(str);
317         
318         /* compo result */
319         if (rr->rectf) {
320                 a += sprintf(str + a, "|%s %%x0", IFACE_("Composite"));
321                 nr = 1;
322         }
323         else if (rr->rect32) {
324                 a += sprintf(str + a, "|%s %%x0", IFACE_("Sequence"));
325                 nr = 1;
326         }
327         for (rl = rr->layers.first; rl; rl = rl->next, nr++) {
328                 a += sprintf(str + a, "|%s %%x%d", rl->name, nr);
329         }
330         
331         /* no curlay clip here, on render (redraws) the amount of layers can be 1 fir single-layer render */
332         
333         return str;
334 }
335
336 /* rl==NULL means composite result */
337 static char *pass_menu(RenderLayer *rl, short *curpass)
338 {
339         RenderPass *rpass;
340         int len = 64 + 32 * (rl ? BLI_countlist(&rl->passes) : 1);
341         short a, nr = 0;
342         char *str = MEM_callocN(len, "menu layers");
343         
344         strcpy(str, IFACE_("Pass %t"));
345         a = strlen(str);
346         
347         /* rendered results don't have a Combined pass */
348         if (rl == NULL || rl->rectf) {
349                 a += sprintf(str + a, "|%s %%x0", IFACE_("Combined"));
350                 nr = 1;
351         }
352         
353         if (rl)
354                 for (rpass = rl->passes.first; rpass; rpass = rpass->next, nr++)
355                         a += sprintf(str + a, "|%s %%x%d", IFACE_(rpass->name), nr);
356         
357         if (*curpass >= nr)
358                 *curpass = 0;
359         
360         return str;
361 }
362
363 /* 5 layer button callbacks... */
364 static void image_multi_cb(bContext *C, void *rr_v, void *iuser_v) 
365 {
366         ImageUser *iuser = iuser_v;
367
368         BKE_image_multilayer_index(rr_v, iuser); 
369         WM_event_add_notifier(C, NC_IMAGE | ND_DRAW, NULL);
370 }
371 static void image_multi_inclay_cb(bContext *C, void *rr_v, void *iuser_v) 
372 {
373         RenderResult *rr = rr_v;
374         ImageUser *iuser = iuser_v;
375         int tot = BLI_countlist(&rr->layers);
376
377         if (rr->rectf || rr->rect32)
378                 tot++;  /* fake compo/sequencer layer */
379
380         if (iuser->layer < tot - 1) {
381                 iuser->layer++;
382                 BKE_image_multilayer_index(rr, iuser); 
383                 WM_event_add_notifier(C, NC_IMAGE | ND_DRAW, NULL);
384         }
385 }
386 static void image_multi_declay_cb(bContext *C, void *rr_v, void *iuser_v) 
387 {
388         ImageUser *iuser = iuser_v;
389
390         if (iuser->layer > 0) {
391                 iuser->layer--;
392                 BKE_image_multilayer_index(rr_v, iuser); 
393                 WM_event_add_notifier(C, NC_IMAGE | ND_DRAW, NULL);
394         }
395 }
396 static void image_multi_incpass_cb(bContext *C, void *rr_v, void *iuser_v) 
397 {
398         RenderResult *rr = rr_v;
399         ImageUser *iuser = iuser_v;
400         RenderLayer *rl = BLI_findlink(&rr->layers, iuser->layer);
401
402         if (rl) {
403                 int tot = BLI_countlist(&rl->passes);
404
405                 if (rr->rectf || rr->rect32)
406                         tot++;  /* fake compo/sequencer layer */
407
408                 if (iuser->pass < tot - 1) {
409                         iuser->pass++;
410                         BKE_image_multilayer_index(rr, iuser); 
411                         WM_event_add_notifier(C, NC_IMAGE | ND_DRAW, NULL);
412                 }
413         }
414 }
415 static void image_multi_decpass_cb(bContext *C, void *rr_v, void *iuser_v) 
416 {
417         ImageUser *iuser = iuser_v;
418
419         if (iuser->pass > 0) {
420                 iuser->pass--;
421                 BKE_image_multilayer_index(rr_v, iuser); 
422                 WM_event_add_notifier(C, NC_IMAGE | ND_DRAW, NULL);
423         }
424 }
425
426 #if 0
427 static void image_freecache_cb(bContext *C, void *ima_v, void *unused) 
428 {
429         Scene *scene = CTX_data_scene(C);
430         BKE_image_free_anim_ibufs(ima_v, scene->r.cfra);
431         WM_event_add_notifier(C, NC_IMAGE, ima_v);
432 }
433 #endif
434
435 #if 0
436 static void image_user_change(bContext *C, void *iuser_v, void *unused)
437 {
438         Scene *scene = CTX_data_scene(C);
439         BKE_image_user_calc_imanr(iuser_v, scene->r.cfra, 0);
440 }
441 #endif
442
443 static void uiblock_layer_pass_buttons(uiLayout *layout, RenderResult *rr, ImageUser *iuser, int w, short *render_slot)
444 {
445         uiBlock *block = uiLayoutGetBlock(layout);
446         uiBut *but;
447         RenderLayer *rl = NULL;
448         int wmenu1, wmenu2, wmenu3, layer;
449         char *strp;
450
451         uiLayoutRow(layout, TRUE);
452
453         /* layer menu is 1/3 larger than pass */
454         wmenu1 = (2 * w) / 5;
455         wmenu2 = (3 * w) / 5;
456         wmenu3 = (3 * w) / 6;
457         
458         /* menu buts */
459         if (render_slot) {
460                 strp = slot_menu();
461                 but = uiDefButS(block, MENU, 0, strp, 0, 0, wmenu1, UI_UNIT_Y, render_slot, 0, 0, 0, 0, TIP_("Select Slot"));
462                 uiButSetFunc(but, image_multi_cb, rr, iuser);
463                 MEM_freeN(strp);
464         }
465
466         if (rr) {
467                 strp = layer_menu(rr, &iuser->layer);
468                 but = uiDefButS(block, MENU, 0, strp, 0, 0, wmenu2, UI_UNIT_Y, &iuser->layer, 0, 0, 0, 0, TIP_("Select Layer"));
469                 uiButSetFunc(but, image_multi_cb, rr, iuser);
470                 MEM_freeN(strp);
471
472                 layer = iuser->layer;
473                 if (rr->rectf || rr->rect32)
474                         layer--;  /* fake compo/sequencer layer */
475                 
476                 rl = BLI_findlink(&rr->layers, layer); /* return NULL is meant to be */
477                 strp = pass_menu(rl, &iuser->pass);
478                 but = uiDefButS(block, MENU, 0, strp, 0, 0, wmenu3, UI_UNIT_Y, &iuser->pass, 0, 0, 0, 0, TIP_("Select Pass"));
479                 uiButSetFunc(but, image_multi_cb, rr, iuser);
480                 MEM_freeN(strp);
481         }
482 }
483
484 static void uiblock_layer_pass_arrow_buttons(uiLayout *layout, RenderResult *rr, ImageUser *iuser, short *render_slot)
485 {
486         uiBlock *block = uiLayoutGetBlock(layout);
487         uiLayout *row;
488         uiBut *but;
489         const float dpi_fac = UI_DPI_FAC;
490         
491         row = uiLayoutRow(layout, TRUE);
492
493         if (rr == NULL || iuser == NULL)
494                 return;
495         if (rr->layers.first == NULL) {
496                 uiItemL(row, IFACE_("No Layers in Render Result"), ICON_NONE);
497                 return;
498         }
499
500         /* decrease, increase arrows */
501         but = uiDefIconBut(block, BUT, 0, ICON_TRIA_LEFT,   0, 0, 0.85f * UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, TIP_("Previous Layer"));
502         uiButSetFunc(but, image_multi_declay_cb, rr, iuser);
503         but = uiDefIconBut(block, BUT, 0, ICON_TRIA_RIGHT,  0, 0, 0.90f * UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, TIP_("Next Layer"));
504         uiButSetFunc(but, image_multi_inclay_cb, rr, iuser);
505
506         uiblock_layer_pass_buttons(row, rr, iuser, 230 * dpi_fac, render_slot);
507
508         /* decrease, increase arrows */
509         but = uiDefIconBut(block, BUT, 0, ICON_TRIA_LEFT,   0, 0, 0.85f * UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, TIP_("Previous Pass"));
510         uiButSetFunc(but, image_multi_decpass_cb, rr, iuser);
511         but = uiDefIconBut(block, BUT, 0, ICON_TRIA_RIGHT,  0, 0, 0.90f * UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, TIP_("Next Pass"));
512         uiButSetFunc(but, image_multi_incpass_cb, rr, iuser);
513
514         uiBlockEndAlign(block);
515 }
516
517 // XXX HACK!
518 // static int packdummy=0;
519
520 typedef struct RNAUpdateCb {
521         PointerRNA ptr;
522         PropertyRNA *prop;
523         ImageUser *iuser;
524 } RNAUpdateCb;
525
526 static void rna_update_cb(bContext *C, void *arg_cb, void *UNUSED(arg))
527 {
528         RNAUpdateCb *cb = (RNAUpdateCb *)arg_cb;
529
530         /* ideally this would be done by RNA itself, but there we have
531          * no image user available, so we just update this flag here */
532         cb->iuser->ok = 1;
533
534         /* we call update here on the pointer property, this way the
535          * owner of the image pointer can still define it's own update
536          * and notifier */
537         RNA_property_update(C, &cb->ptr, cb->prop);
538 }
539
540 void uiTemplateImage(uiLayout *layout, bContext *C, PointerRNA *ptr, const char *propname, PointerRNA *userptr, int compact)
541 {
542         PropertyRNA *prop;
543         PointerRNA imaptr;
544         RNAUpdateCb *cb;
545         Image *ima;
546         ImageUser *iuser;
547         ImBuf *ibuf;
548         Scene *scene = CTX_data_scene(C);
549         uiLayout *row, *split, *col;
550         uiBlock *block;
551         char str[128];
552
553         void *lock;
554
555         if (!ptr->data)
556                 return;
557
558         prop = RNA_struct_find_property(ptr, propname);
559         if (!prop) {
560                 printf("%s: property not found: %s.%s\n",
561                        __func__, RNA_struct_identifier(ptr->type), propname);
562                 return;
563         }
564
565         if (RNA_property_type(prop) != PROP_POINTER) {
566                 printf("%s: expected pointer property for %s.%s\n",
567                        __func__, RNA_struct_identifier(ptr->type), propname);
568                 return;
569         }
570
571         block = uiLayoutGetBlock(layout);
572
573         imaptr = RNA_property_pointer_get(ptr, prop);
574         ima = imaptr.data;
575         iuser = userptr->data;
576
577         BKE_image_user_check_frame_calc(iuser, (int)scene->r.cfra, 0);
578
579         cb = MEM_callocN(sizeof(RNAUpdateCb), "RNAUpdateCb");
580         cb->ptr = *ptr;
581         cb->prop = prop;
582         cb->iuser = iuser;
583
584         uiLayoutSetContextPointer(layout, "edit_image", &imaptr);
585         uiLayoutSetContextPointer(layout, "edit_image_user", userptr);
586
587         if (!compact)
588                 uiTemplateID(layout, C, ptr, propname, "IMAGE_OT_new", "IMAGE_OT_open", NULL);
589
590         if (ima) {
591                 uiBlockSetNFunc(block, rna_update_cb, MEM_dupallocN(cb), NULL);
592
593                 if (ima->source == IMA_SRC_VIEWER) {
594                         ibuf = BKE_image_acquire_ibuf(ima, iuser, &lock);
595                         image_info(scene, iuser, ima, ibuf, str);
596                         BKE_image_release_ibuf(ima, ibuf, lock);
597
598                         uiItemL(layout, ima->id.name + 2, ICON_NONE);
599                         uiItemL(layout, str, ICON_NONE);
600
601                         if (ima->type == IMA_TYPE_COMPOSITE) {
602                                 // XXX not working yet
603 #if 0
604                                 iuser = ntree_get_active_iuser(scene->nodetree);
605                                 if (iuser) {
606                                         uiBlockBeginAlign(block);
607                                         uiDefIconTextBut(block, BUT, B_SIMA_RECORD, ICON_REC, "Record", 10, 120, 100, 20, 0, 0, 0, 0, 0, "");
608                                         uiDefIconTextBut(block, BUT, B_SIMA_PLAY, ICON_PLAY, "Play",    110, 120, 100, 20, 0, 0, 0, 0, 0, "");
609                                         but = uiDefBut(block, BUT, B_NOP, "Free Cache", 210, 120, 100, 20, 0, 0, 0, 0, 0, "");
610                                         uiButSetFunc(but, image_freecache_cb, ima, NULL);
611                                         
612                                         if (iuser->frames)
613                                                 BLI_snprintf(str, sizeof(str), "(%d) Frames:", iuser->framenr);
614                                         else strcpy(str, "Frames:");
615                                         uiBlockBeginAlign(block);
616                                         uiDefButI(block, NUM, imagechanged, str,        10, 90, 150, 20, &iuser->frames, 0.0, MAXFRAMEF, 0, 0, "Number of images of a movie to use");
617                                         uiDefButI(block, NUM, imagechanged, "StartFr:", 160, 90, 150, 20, &iuser->sfra, 1.0, MAXFRAMEF, 0, 0, "Global starting frame of the movie");
618                                 }
619 #endif
620                         }
621                         else if (ima->type == IMA_TYPE_R_RESULT) {
622                                 /* browse layer/passes */
623                                 RenderResult *rr;
624
625                                 /* use BKE_image_acquire_renderresult  so we get the correct slot in the menu */
626                                 rr = BKE_image_acquire_renderresult(scene, ima);
627                                 uiblock_layer_pass_arrow_buttons(layout, rr, iuser, &ima->render_slot);
628                                 BKE_image_release_renderresult(scene, ima);
629                         }
630                 }
631                 else {
632                         uiItemR(layout, &imaptr, "source", 0, NULL, ICON_NONE);
633
634                         if (ima->source != IMA_SRC_GENERATED) {
635                                 row = uiLayoutRow(layout, TRUE);
636                                 if (ima->packedfile)
637                                         uiItemO(row, "", ICON_PACKAGE, "image.unpack");
638                                 else
639                                         uiItemO(row, "", ICON_UGLYPACKAGE, "image.pack");
640                                 
641                                 row = uiLayoutRow(row, FALSE);
642                                 uiLayoutSetEnabled(row, ima->packedfile == NULL);
643                                 uiItemR(row, &imaptr, "filepath", 0, "", ICON_NONE);
644                                 uiItemO(row, "", ICON_FILE_REFRESH, "image.reload");
645                         }
646
647                         // XXX what was this for?
648 #if 0
649                         /* check for re-render, only buttons */
650                         if (imagechanged == B_IMAGECHANGED) {
651                                 if (iuser->flag & IMA_ANIM_REFRESHED) {
652                                         iuser->flag &= ~IMA_ANIM_REFRESHED;
653                                         WM_event_add_notifier(C, NC_IMAGE, ima);
654                                 }
655                         }
656 #endif
657
658                         /* multilayer? */
659                         if (ima->type == IMA_TYPE_MULTILAYER && ima->rr) {
660                                 uiblock_layer_pass_arrow_buttons(layout, ima->rr, iuser, NULL);
661                         }
662                         else if (ima->source != IMA_SRC_GENERATED) {
663                                 if (compact == 0) {
664                                         ibuf = BKE_image_acquire_ibuf(ima, iuser, &lock);
665                                         image_info(scene, iuser, ima, ibuf, str);
666                                         BKE_image_release_ibuf(ima, ibuf, lock);
667                                         uiItemL(layout, str, ICON_NONE);
668                                 }
669                         }
670
671                         col = uiLayoutColumn(layout, FALSE);
672                         uiTemplateColorspaceSettings(col, &imaptr, "colorspace_settings");
673                         uiItemR(col, &imaptr, "view_as_render", 0, NULL, ICON_NONE);
674
675                         if (ima->source != IMA_SRC_GENERATED) {
676                                 if (compact == 0) { /* background image view doesnt need these */
677                                         ImBuf *ibuf = BKE_image_acquire_ibuf(ima, iuser, NULL);
678                                         int has_alpha = TRUE;
679
680                                         if (ibuf) {
681                                                 int imtype = BKE_ftype_to_imtype(ibuf->ftype);
682                                                 char valid_channels = BKE_imtype_valid_channels(imtype);
683
684                                                 has_alpha = valid_channels & IMA_CHAN_FLAG_ALPHA;
685
686                                                 BKE_image_release_ibuf(ima, ibuf, NULL);
687                                         }
688
689                                         if (has_alpha) {
690                                                 col = uiLayoutColumn(layout, FALSE);
691                                                 uiItemR(col, &imaptr, "use_alpha", 0, NULL, ICON_NONE);
692                                                 uiItemR(col, &imaptr, "alpha_mode", 0, "Alpha", ICON_NONE);
693                                         }
694
695                                         uiItemS(layout);
696
697                                         split = uiLayoutSplit(layout, 0.0f, FALSE);
698
699                                         col = uiLayoutColumn(split, FALSE);
700                                         /* XXX Why only display fields_per_frame only for video image types?
701                                          *     And why allow fields for non-video image types at all??? */
702                                         if (ELEM(ima->source, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE)) {
703                                                 uiLayout *subsplit = uiLayoutSplit(col, 0.0f, FALSE);
704                                                 uiLayout *subcol = uiLayoutColumn(subsplit, FALSE);
705                                                 uiItemR(subcol, &imaptr, "use_fields", 0, NULL, ICON_NONE);
706                                                 subcol = uiLayoutColumn(subsplit, FALSE);
707                                                 uiLayoutSetActive(subcol, RNA_boolean_get(&imaptr, "use_fields"));
708                                                 uiItemR(subcol, userptr, "fields_per_frame", 0, IFACE_("Fields"), ICON_NONE);
709                                         }
710                                         else
711                                                 uiItemR(col, &imaptr, "use_fields", 0, NULL, ICON_NONE);
712                                         row = uiLayoutRow(col, FALSE);
713                                         uiLayoutSetActive(row, RNA_boolean_get(&imaptr, "use_fields"));
714                                         uiItemR(row, &imaptr, "field_order", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
715                                 }
716                         }
717
718                         if (ELEM(ima->source, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE)) {
719                                 uiItemS(layout);
720
721                                 split = uiLayoutSplit(layout, 0.0f, FALSE);
722
723                                 col = uiLayoutColumn(split, FALSE);
724
725                                 BLI_snprintf(str, sizeof(str), IFACE_("(%d) Frames"), iuser->framenr);
726                                 uiItemR(col, userptr, "frame_duration", 0, str, ICON_NONE);
727                                 uiItemR(col, userptr, "frame_start", 0, IFACE_("Start"), ICON_NONE);
728                                 uiItemR(col, userptr, "frame_offset", 0, NULL, ICON_NONE);
729
730                                 col = uiLayoutColumn(split, FALSE);
731                                 uiItemO(col, NULL, ICON_NONE, "IMAGE_OT_match_movie_length");
732                                 uiItemR(col, userptr, "use_auto_refresh", 0, NULL, ICON_NONE);
733                                 uiItemR(col, userptr, "use_cyclic", 0, NULL, ICON_NONE);
734                         }
735                         else if (ima->source == IMA_SRC_GENERATED) {
736                                 split = uiLayoutSplit(layout, 0.0f, FALSE);
737
738                                 col = uiLayoutColumn(split, TRUE);
739                                 uiItemR(col, &imaptr, "generated_width", 0, "X", ICON_NONE);
740                                 uiItemR(col, &imaptr, "generated_height", 0, "Y", ICON_NONE);
741                                 
742                                 uiItemR(col, &imaptr, "use_generated_float", 0, NULL, ICON_NONE);
743
744                                 uiItemR(split, &imaptr, "generated_type", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
745                         }
746
747                 }
748
749                 uiBlockSetNFunc(block, NULL, NULL, NULL);
750         }
751
752         MEM_freeN(cb);
753 }
754
755 void uiTemplateImageSettings(uiLayout *layout, PointerRNA *imfptr, int color_management)
756 {
757         ImageFormatData *imf = imfptr->data;
758         ID *id = imfptr->id.data;
759         PointerRNA display_settings_ptr;
760         PropertyRNA *prop;
761         const int depth_ok = BKE_imtype_valid_depths(imf->imtype);
762         /* some settings depend on this being a scene thats rendered */
763         const short is_render_out = (id && GS(id->name) == ID_SCE);
764
765         uiLayout *col, *row, *split, *sub;
766         int show_preview = FALSE;
767
768         col = uiLayoutColumn(layout, FALSE);
769
770         split = uiLayoutSplit(col, 0.5f, FALSE);
771         
772         uiItemR(split, imfptr, "file_format", 0, "", ICON_NONE);
773         sub = uiLayoutRow(split, FALSE);
774         uiItemR(sub, imfptr, "color_mode", UI_ITEM_R_EXPAND, IFACE_("Color"), ICON_NONE);
775
776         /* only display depth setting if multiple depths can be used */
777         if ((ELEM7(depth_ok,
778                    R_IMF_CHAN_DEPTH_1,
779                    R_IMF_CHAN_DEPTH_8,
780                    R_IMF_CHAN_DEPTH_10,
781                    R_IMF_CHAN_DEPTH_12,
782                    R_IMF_CHAN_DEPTH_16,
783                    R_IMF_CHAN_DEPTH_24,
784                    R_IMF_CHAN_DEPTH_32)) == 0)
785         {
786                 row = uiLayoutRow(col, FALSE);
787
788                 uiItemL(row, IFACE_("Color Depth:"), ICON_NONE);
789                 uiItemR(row, imfptr, "color_depth", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
790         }
791
792         if (BKE_imtype_supports_quality(imf->imtype)) {
793                 uiItemR(col, imfptr, "quality", 0, NULL, ICON_NONE);
794         }
795
796         if (BKE_imtype_supports_compress(imf->imtype)) {
797                 uiItemR(col, imfptr, "compression", 0, NULL, ICON_NONE);
798         }
799
800         if (ELEM(imf->imtype, R_IMF_IMTYPE_OPENEXR, R_IMF_IMTYPE_MULTILAYER)) {
801                 uiItemR(col, imfptr, "exr_codec", 0, NULL, ICON_NONE);
802         }
803         
804         row = uiLayoutRow(col, FALSE);
805         if (BKE_imtype_supports_zbuf(imf->imtype)) {
806                 uiItemR(row, imfptr, "use_zbuffer", 0, NULL, ICON_NONE);
807         }
808
809         if (is_render_out && (imf->imtype == R_IMF_IMTYPE_OPENEXR)) {
810                 show_preview = TRUE;
811                 uiItemR(row, imfptr, "use_preview", 0, NULL, ICON_NONE);
812         }
813
814         if (imf->imtype == R_IMF_IMTYPE_JP2) {
815                 uiItemR(col, imfptr, "jpeg2k_codec", 0, NULL, ICON_NONE);
816
817                 row = uiLayoutRow(col, FALSE);
818                 uiItemR(row, imfptr, "use_jpeg2k_cinema_preset", 0, NULL, ICON_NONE);
819                 uiItemR(row, imfptr, "use_jpeg2k_cinema_48", 0, NULL, ICON_NONE);
820                 
821                 uiItemR(col, imfptr, "use_jpeg2k_ycc", 0, NULL, ICON_NONE);
822         }
823
824         if (imf->imtype == R_IMF_IMTYPE_DPX) {
825                 uiItemR(col, imfptr, "use_cineon_log", 0, NULL, ICON_NONE);
826         }
827
828         if (imf->imtype == R_IMF_IMTYPE_CINEON) {
829 #if 1
830                 uiItemL(col, IFACE_("Hard coded Non-Linear, Gamma:1.7"), ICON_NONE);
831 #else
832                 uiItemR(col, imfptr, "use_cineon_log", 0, NULL, ICON_NONE);
833                 uiItemR(col, imfptr, "cineon_black", 0, NULL, ICON_NONE);
834                 uiItemR(col, imfptr, "cineon_white", 0, NULL, ICON_NONE);
835                 uiItemR(col, imfptr, "cineon_gamma", 0, NULL, ICON_NONE);
836 #endif
837         }
838
839         /* color management */
840         if (color_management &&
841             (!BKE_imtype_requires_linear_float(imf->imtype) ||
842              (show_preview && imf->flag & R_IMF_FLAG_PREVIEW_JPG)))
843         {
844                 prop = RNA_struct_find_property(imfptr, "display_settings");
845                 display_settings_ptr = RNA_property_pointer_get(imfptr, prop);
846
847                 col = uiLayoutColumn(layout, FALSE);
848                 uiItemL(col, IFACE_("Color Management"), ICON_NONE);
849
850                 uiItemR(col, &display_settings_ptr, "display_device", 0, NULL, ICON_NONE);
851
852                 uiTemplateColormanagedViewSettings(col, NULL, imfptr, "view_settings");
853         }
854 }
855
856 void uiTemplateImageLayers(uiLayout *layout, bContext *C, Image *ima, ImageUser *iuser)
857 {
858         Scene *scene = CTX_data_scene(C);
859
860         /* render layers and passes */
861         if (ima && iuser) {
862                 const float dpi_fac = UI_DPI_FAC;
863                 RenderResult *rr;
864
865                 /* use BKE_image_acquire_renderresult  so we get the correct slot in the menu */
866                 rr = BKE_image_acquire_renderresult(scene, ima);
867                 uiblock_layer_pass_buttons(layout, rr, iuser, 160 * dpi_fac, (ima->type == IMA_TYPE_R_RESULT) ? &ima->render_slot : NULL);
868                 BKE_image_release_renderresult(scene, ima);
869         }
870 }
871
872 void image_buttons_register(ARegionType *art)
873 {
874         PanelType *pt;
875
876         pt = MEM_callocN(sizeof(PanelType), "spacetype image panel gpencil");
877         strcpy(pt->idname, "IMAGE_PT_gpencil");
878         strcpy(pt->label, "Grease Pencil");
879         pt->draw_header = gpencil_panel_standard_header;
880         pt->draw = gpencil_panel_standard;
881         BLI_addtail(&art->paneltypes, pt);
882 }
883
884 static int image_properties(bContext *C, wmOperator *UNUSED(op))
885 {
886         ScrArea *sa = CTX_wm_area(C);
887         ARegion *ar = image_has_buttons_region(sa);
888         
889         if (ar)
890                 ED_region_toggle_hidden(C, ar);
891
892         return OPERATOR_FINISHED;
893 }
894
895 void IMAGE_OT_properties(wmOperatorType *ot)
896 {
897         ot->name = "Properties";
898         ot->idname = "IMAGE_OT_properties";
899         ot->description = "Toggle display properties panel";
900         
901         ot->exec = image_properties;
902         ot->poll = ED_operator_image_active;
903         
904         /* flags */
905         ot->flag = 0;
906 }
907
908 static int image_scopes(bContext *C, wmOperator *UNUSED(op))
909 {
910         ScrArea *sa = CTX_wm_area(C);
911         ARegion *ar = image_has_scope_region(sa);
912         
913         if (ar)
914                 ED_region_toggle_hidden(C, ar);
915         
916         return OPERATOR_FINISHED;
917 }
918
919 void IMAGE_OT_scopes(wmOperatorType *ot)
920 {
921         ot->name = "Scopes";
922         ot->idname = "IMAGE_OT_scopes";
923         ot->description = "Toggle display scopes panel";
924         
925         ot->exec = image_scopes;
926         ot->poll = ED_operator_image_active;
927         
928         /* flags */
929         ot->flag = 0;
930 }
931