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