2.50: svn merge https://svn.blender.org/svnroot/bf-blender/trunk/blender -r19323...
[blender.git] / source / blender / editors / space_image / image_header.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version. 
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19  *
20  * The Original Code is Copyright (C) 2008 Blender Foundation.
21  * All rights reserved.
22  *
23  * 
24  * Contributor(s): Blender Foundation
25  *
26  * ***** END GPL LICENSE BLOCK *****
27  */
28
29 #include <string.h>
30 #include <stdio.h>
31
32 #include "DNA_object_types.h"
33 #include "DNA_mesh_types.h"
34 #include "DNA_customdata_types.h"
35 #include "DNA_space_types.h"
36 #include "DNA_scene_types.h"
37 #include "DNA_screen_types.h"
38 #include "DNA_windowmanager_types.h"
39
40 #include "MEM_guardedalloc.h"
41
42 #include "BLI_blenlib.h"
43 #include "BLI_editVert.h"
44
45 #include "BKE_context.h"
46 #include "BKE_customdata.h"
47 #include "BKE_image.h"
48 #include "BKE_mesh.h"
49 #include "BKE_screen.h"
50 #include "BKE_utildefines.h"
51
52 #include "IMB_imbuf.h"
53 #include "IMB_imbuf_types.h"
54
55 #include "ED_image.h"
56 #include "ED_mesh.h"
57 #include "ED_screen.h"
58 #include "ED_types.h"
59 #include "ED_util.h"
60
61 #include "WM_api.h"
62 #include "WM_types.h"
63
64 #include "BIF_gl.h"
65 #include "BIF_glutil.h"
66 #include "BIF_transform.h"
67
68 #include "UI_interface.h"
69 #include "UI_resources.h"
70 #include "UI_view2d.h"
71
72 #include "RNA_access.h"
73
74 #include "RE_pipeline.h"
75
76 #include "image_intern.h"
77
78 /* ************************ header area region *********************** */
79
80 #define B_NOP                           -1
81 #define B_REDR                          1
82 #define B_SIMAGEPAINTTOOL       4
83 #define B_SIMA_USE_ALPHA        5
84 #define B_SIMA_SHOW_ALPHA       6
85 #define B_SIMA_SHOW_ZBUF        7
86 #define B_SIMA_RECORD           8
87 #define B_SIMA_PLAY                     9
88
89 static void image_view_viewnavmenu(bContext *C, uiMenuItem *head, void *arg_unused)
90 {
91         int a;
92         
93         uiMenuItemO(head, 0, "IMAGE_OT_view_zoom_in");
94         uiMenuItemO(head, 0, "IMAGE_OT_view_zoom_out");
95
96         uiMenuSeparator(head);
97
98         for(a=0; a<7; a++) {
99                 const int ratios[7][2] = {{1, 8}, {1, 4}, {1, 2}, {1, 1}, {2, 1}, {4, 1}, {8, 1}};
100                 char namestr[128];
101
102                 sprintf(namestr, "Zoom %d:%d", ratios[a][0], ratios[a][1]);
103                 uiMenuItemFloatO(head, namestr, 0, "IMAGE_OT_view_zoom_ratio", "ratio", (float)ratios[a][0]/(float)ratios[a][1]);
104         }
105 }
106
107 #if 0
108 static void do_viewmenu(bContext *C, void *arg, int event)
109 {
110         add_blockhandler(curarea, IMAGE_HANDLER_VIEW_PROPERTIES, UI_PNL_UNSTOW);
111         add_blockhandler(curarea, IMAGE_HANDLER_PROPERTIES, UI_PNL_UNSTOW);
112         add_blockhandler(curarea, IMAGE_HANDLER_PAINT, UI_PNL_UNSTOW);
113         add_blockhandler(curarea, IMAGE_HANDLER_CURVES, UI_PNL_UNSTOW);
114
115         toggle_blockhandler(curarea, IMAGE_HANDLER_PREVIEW, 0);
116         scrarea_queue_winredraw(curarea);
117
118         add_blockhandler(curarea, IMAGE_HANDLER_GAME_PROPERTIES, UI_PNL_UNSTOW);
119         add_blockhandler(curarea, IMAGE_HANDLER_GREASEPENCIL, UI_PNL_UNSTOW);
120
121         allqueue(REDRAWIMAGE, 0);
122         allqueue(REDRAWVIEW3D, 0);
123 }
124 #endif
125
126 static void image_viewmenu(bContext *C, uiMenuItem *head, void *arg_unused)
127 {
128         bScreen *sc= CTX_wm_screen(C);
129         ScrArea *sa= CTX_wm_area(C);
130         SpaceImage *sima= (SpaceImage*)CTX_wm_space_data(C);
131         PointerRNA spaceptr, uvptr;
132         int show_paint, show_render, show_uvedit;
133
134         /* retrieve state */
135         RNA_pointer_create(&sc->id, &RNA_SpaceImageEditor, sima, &spaceptr);
136         RNA_pointer_create(&sc->id, &RNA_SpaceUVEditor, sima, &uvptr);
137
138         show_render= ED_space_image_show_render(sima);
139         show_paint= ED_space_image_show_paint(sima);
140         show_uvedit= ED_space_image_show_uvedit(sima, CTX_data_edit_object(C));
141         
142         /* create menu */
143         uiMenuItemO(head, ICON_MENU_PANEL, "IMAGE_OT_toggle_view_properties_panel"); // View Properties...
144         uiMenuItemO(head, ICON_MENU_PANEL, "IMAGE_OT_toggle_image_properties_panel"); // Image Properties...|N
145         uiMenuItemO(head, ICON_MENU_PANEL, "IMAGE_OT_toggle_realtime_properties_panel"); // Real-time properties...
146         if(show_paint) uiMenuItemO(head, ICON_MENU_PANEL, "IMAGE_OT_toggle_paint_panel"); // Paint Tool...|C
147         uiMenuItemO(head, ICON_MENU_PANEL, "IMAGE_OT_toggle_curves_panel"); // Curves Tool...
148         if(show_render) uiMenuItemO(head, ICON_MENU_PANEL, "IMAGE_OT_toggle_compositing_preview_panel"); // Compositing Preview...|Shift P
149         uiMenuItemO(head, ICON_MENU_PANEL, "IMAGE_OT_toggle_grease_pencil_panel"); // Grease Pencil...
150
151         uiMenuSeparator(head);
152
153         uiMenuItemBooleanR(head, &spaceptr, "update_automatically");
154         // XXX if(show_uvedit) uiMenuItemBooleanR(head, &uvptr, "local_view"); // "UV Local View", Numpad /
155
156         uiMenuSeparator(head);
157
158         uiMenuLevel(head, "View Navigation", image_view_viewnavmenu);
159         if(show_uvedit) uiMenuItemO(head, 0, "IMAGE_OT_view_selected");
160         uiMenuItemO(head, 0, "IMAGE_OT_view_all");
161
162         if(sa->full) uiMenuItemO(head, 0, "SCREEN_OT_screen_full_area"); // "Tile Window", Ctrl UpArrow
163         else uiMenuItemO(head, 0, "SCREEN_OT_screen_full_area"); // "Maximize Window", Ctr DownArrow
164 }
165
166 static void image_selectmenu(bContext *C, uiMenuItem *head, void *arg_unused)
167 {
168         uiMenuItemO(head, 0, "UV_OT_select_border");
169         uiMenuItemBooleanO(head, "Border Select Pinned", 0, "UV_OT_select_border", "pinned", 1); // Border Select Pinned|Shift B
170
171         uiMenuSeparator(head);
172         
173         uiMenuItemO(head, 0, "UV_OT_select_all_toggle");
174         uiMenuItemO(head, 0, "UV_OT_select_invert");
175         uiMenuItemO(head, 0, "UV_OT_unlink_selection");
176         
177         uiMenuSeparator(head);
178
179         uiMenuItemO(head, 0, "UV_OT_select_pinned");
180         uiMenuItemO(head, 0, "UV_OT_select_linked");
181 }
182
183 #if 0
184 static void do_image_imagemenu(void *arg, int event)
185 {
186         /* events >=20 are registered bpython scripts */
187 #ifndef DISABLE_PYTHON
188         if (event >= 20) BPY_menu_do_python(PYMENU_IMAGE, event - 20);
189 #endif  
190 }
191 #endif
192
193 static void image_imagemenu(bContext *C, uiMenuItem *head, void *arg_unused)
194 {
195         bScreen *sc= CTX_wm_screen(C);
196         SpaceImage *sima= (SpaceImage*)CTX_wm_space_data(C);
197         PointerRNA spaceptr, imaptr;
198         Image *ima;
199         ImBuf *ibuf;
200         int show_render;
201         
202         /* retrieve state */
203         ima= ED_space_image(sima);
204         ibuf= ED_space_image_buffer(sima);
205
206         show_render= ED_space_image_show_render(sima);
207
208         RNA_pointer_create(&sc->id, &RNA_SpaceImageEditor, sima, &spaceptr);
209
210         /* create menu */
211         uiMenuItemO(head, 0, "IMAGE_OT_new"); // New...
212         uiMenuItemO(head, 0, "IMAGE_OT_open"); // Open...
213
214         if(ima) {
215                 if(!show_render) {
216                         uiMenuItemO(head, 0, "IMAGE_OT_replace"); // Replace...
217                         uiMenuItemO(head, 0, "IMAGE_OT_reload"); // Reload...
218                 }
219                 uiMenuItemO(head, 0, "IMAGE_OT_save"); // Save
220                 uiMenuItemO(head, 0, "IMAGE_OT_save_as"); // Save As...
221                 if(ima->source == IMA_SRC_SEQUENCE)
222                         uiMenuItemO(head, 0, "IMAGE_OT_save_sequence"); // Save Changed Sequence Images
223
224                 if(!show_render) {
225                         uiMenuSeparator(head);
226
227                         if(ima->packedfile) uiMenuItemO(head, 0, "IMAGE_OT_unpack"); // Unpack Image...
228                         else uiMenuItemO(head, 0, "IMAGE_OT_pack"); // Pack Image
229
230                         /* only for dirty && specific image types : XXX poll? */
231                         if(ibuf && (ibuf->userflags & IB_BITMAPDIRTY))
232                                 if(ELEM(ima->source, IMA_SRC_FILE, IMA_SRC_GENERATED) && ima->type != IMA_TYPE_MULTILAYER)
233                                         uiMenuItemBooleanO(head, "Pack As PNG", 0, "IMAGE_OT_pack", "as_png", 1); // Pack Image As PNG
234
235                         uiMenuSeparator(head);
236
237                         uiMenuItemBooleanR(head, &spaceptr, "image_painting");
238                         
239                         /* move to realtime properties panel */
240                         RNA_id_pointer_create(&ima->id, &imaptr);
241                         uiMenuLevelEnumR(head, &imaptr, "mapping");
242                 }
243         }
244
245 #if 0
246 #ifndef DISABLE_PYTHON
247         {
248                 BPyMenu *pym;
249                 int i = 0;
250
251                 /* note that we acount for the N previous entries with i+20: */
252                 for (pym = BPyMenuTable[PYMENU_IMAGE]; pym; pym = pym->next, i++) {
253
254                         uiDefIconTextBut(block, BUTM, 1, ICON_PYTHON, pym->name, 0, yco-=20, menuwidth, 19, 
255                                          NULL, 0.0, 0.0, 1, i+20, 
256                                          pym->tooltip?pym->tooltip:pym->filename);
257                 }
258         }
259 #endif
260 #endif
261 }
262
263 static void image_uvs_showhidemenu(bContext *C, uiMenuItem *head, void *arg_unused)
264 {
265         uiMenuItemO(head, 0, "UV_OT_reveal");
266         uiMenuItemO(head, 0, "UV_OT_hide");
267         uiMenuItemBooleanO(head, "Hide Unselected", 0, "UV_OT_hide", "unselected", 1);
268 }
269
270 static void image_uvs_transformmenu(bContext *C, uiMenuItem *head, void *arg_unused)
271 {
272         uiMenuItemEnumO(head, "", 0, "TFM_OT_transform", "mode", TFM_TRANSLATION);
273         uiMenuItemEnumO(head, "", 0, "TFM_OT_transform", "mode", TFM_ROTATION);
274         uiMenuItemEnumO(head, "", 0, "TFM_OT_transform", "mode", TFM_RESIZE);
275 }
276
277 static void image_uvs_mirrormenu(bContext *C, uiMenuItem *head, void *arg_unused)
278 {
279         uiMenuItemEnumO(head, "", 0, "UV_OT_mirror", "axis", 'x'); // "X Axis", M, 1
280         uiMenuItemEnumO(head, "", 0, "UV_OT_mirror", "axis", 'y'); // "Y Axis", M, 2
281 }
282
283 static void image_uvs_weldalignmenu(bContext *C, uiMenuItem *head, void *arg_unused)
284 {
285         uiMenuItemO(head, 0, "UV_OT_weld"); // W, 1
286         uiMenuItemsEnumO(head, "UV_OT_align", "axis"); // W, 2/3/4
287 }
288
289 #if 0
290 #ifndef DISABLE_PYTHON
291 static void do_image_uvs_scriptsmenu(void *arg, int event)
292 {
293         BPY_menu_do_python(PYMENU_UV, event);
294
295         allqueue(REDRAWIMAGE, 0);
296 }
297
298 static void image_uvs_scriptsmenu (void *args_unused)
299 {
300         uiBlock *block;
301         BPyMenu *pym;
302         int i= 0;
303         short yco = 20, menuwidth = 120;
304         
305         block= uiNewBlock(&curarea->uiblocks, "image_uvs_scriptsmenu", UI_EMBOSSP);
306         uiBlockSetButmFunc(block, do_image_uvs_scriptsmenu, NULL);
307         
308         /* note that we acount for the N previous entries with i+20: */
309         for (pym = BPyMenuTable[PYMENU_UV]; pym; pym = pym->next, i++) {
310                 
311                 uiDefIconTextBut(block, BUTM, 1, ICON_PYTHON, pym->name, 0, yco-=20, menuwidth, 19, 
312                                                  NULL, 0.0, 0.0, 1, i, 
313                                                  pym->tooltip?pym->tooltip:pym->filename);
314         }
315         
316         uiBlockSetDirection(block, UI_RIGHT);
317         uiTextBoundsBlock(block, 60);
318         
319         return block;
320 }
321 #endif /* DISABLE_PYTHON */
322 #endif
323
324 static void image_uvsmenu(bContext *C, uiMenuItem *head, void *arg_unused)
325 {
326         bScreen *sc= CTX_wm_screen(C);
327         Scene *scene= CTX_data_scene(C);
328         SpaceImage *sima= (SpaceImage*)CTX_wm_space_data(C);
329         PointerRNA uvptr, sceneptr;
330         Image *ima;
331         ImBuf *ibuf;
332         
333         /* retrieve state */
334         ima= ED_space_image(sima);
335         ibuf= ED_space_image_buffer(sima);
336
337         RNA_pointer_create(&sc->id, &RNA_SpaceUVEditor, sima, &uvptr);
338         RNA_id_pointer_create(&scene->id, &sceneptr);
339
340         /* create menu */
341         uiMenuItemBooleanR(head, &uvptr, "snap_to_pixels");
342         uiMenuItemBooleanR(head, &uvptr, "constrain_to_image_bounds");
343
344         uiMenuSeparator(head);
345
346         uiMenuItemBooleanR(head, &uvptr, "live_unwrap");
347         uiMenuItemO(head, 0, "UV_OT_unwrap");
348         uiMenuItemBooleanO(head, "Unpin", 0, "UV_OT_pin", "clear", 1);
349         uiMenuItemO(head, 0, "UV_OT_pin");
350
351         uiMenuSeparator(head);
352
353         uiMenuItemO(head, 0, "UV_OT_pack_islands");
354         uiMenuItemO(head, 0, "UV_OT_average_islands_scale");
355         uiMenuItemO(head, 0, "UV_OT_minimize_stretch");
356         uiMenuItemO(head, 0, "UV_OT_stitch");
357
358         uiMenuSeparator(head);
359
360         uiMenuLevel(head, "Transform", image_uvs_transformmenu);
361         uiMenuLevel(head, "Mirror", image_uvs_mirrormenu);
362         uiMenuLevel(head, "Weld/Align", image_uvs_weldalignmenu);
363
364         uiMenuSeparator(head);
365
366         uiMenuItemBooleanR(head, &sceneptr, "proportional_editing");
367         uiMenuLevelEnumR(head, &sceneptr, "proportional_editing_falloff");
368
369         uiMenuSeparator(head);
370
371         uiMenuLevel(head, "Show/Hide Faces", image_uvs_showhidemenu);
372
373 #if 0
374 #ifndef DISABLE_PYTHON
375         uiMenuSeparator(head);
376
377         uiMenuLevel(head, "Scripts", image_uvs_scriptsmenu);
378 #endif
379 #endif
380 }
381
382 static void image_menu_uvlayers(Object *obedit, char *menustr, int *active)
383 {
384         Mesh *me= (Mesh*)obedit->data;
385         EditMesh *em= BKE_mesh_get_editmesh(me);
386         CustomDataLayer *layer;
387         int i, count = 0;
388
389         menustr[0]= '\0';
390
391         for(i=0; i<em->fdata.totlayer; i++) {
392                 layer = &em->fdata.layers[i];
393
394                 if(layer->type == CD_MTFACE) {
395                         menustr += sprintf(menustr, "%s%%x%d|", layer->name, count);
396                         count++;
397                 }
398         }
399
400         *active= CustomData_get_active_layer(&em->fdata, CD_MTFACE);
401
402         BKE_mesh_end_editmesh(me, em);
403 }
404
405 static void do_image_buttons(bContext *C, void *arg, int event)
406 {
407         switch(event) {
408                 case B_REDR:
409                         ED_area_tag_redraw(CTX_wm_area(C));
410                         break;
411         }
412
413 #if 0
414         ToolSettings *settings= G.scene->toolsettings;
415         ID *id, *idtest;
416         int nr;
417
418         if(curarea->win==0) return;
419
420         if(event<=100) {
421                 if(event<=50) do_global_buttons2(event);
422                 else do_global_buttons(event);
423                 return;
424         }
425         
426         switch(event) {
427         case B_SIMABROWSE:      
428                 if(sima->imanr== -2) {
429                         if(G.qual & LR_CTRLKEY) {
430                                 activate_databrowse_imasel((ID *)sima->image, ID_IM, 0, B_SIMABROWSE,
431                                                                                         &sima->imanr, do_image_buttons);
432                         } else {
433                                 activate_databrowse((ID *)sima->image, ID_IM, 0, B_SIMABROWSE,
434                                                                                         &sima->imanr, do_image_buttons);
435                         }
436                         return;
437                 }
438                 if(sima->imanr < 0) break;
439         
440                 nr= 1;
441                 id= (ID *)sima->image;
442
443                 idtest= BLI_findlink(&G.main->image, sima->imanr-1);
444                 if(idtest==NULL) { /* no new */
445                         return;
446                 }
447         
448                 if(idtest!=id) {
449                         sima->image= (Image *)idtest;
450                         if(idtest->us==0) idtest->us= 1;
451                         BKE_image_signal(sima->image, &sima->iuser, IMA_SIGNAL_USER_NEW_IMAGE);
452                         allqueue(REDRAWIMAGE, 0);
453                 }
454                 /* also when image is the same: assign! 0==no tileflag: */
455                 image_changed(sima, (Image *)idtest);
456                 BIF_undo_push("Assign image UV");
457
458                 break;
459         case B_SIMAGETILE:
460                 image_set_tile(sima, 1);                /* 1: only tileflag */
461                 allqueue(REDRAWVIEW3D, 0);
462                 allqueue(REDRAWIMAGE, 0);
463                 break;
464         case B_SIMA3DVIEWDRAW:
465                 allqueue(REDRAWVIEW3D, 0);
466                 break;
467         case B_SIMA_REDR_IMA_3D:
468                 allqueue(REDRAWVIEW3D, 0);
469                 allqueue(REDRAWIMAGE, 0);
470                 break;
471
472         case B_SIMAPACKIMA:
473                 pack_image_sima();
474                 break;
475                 
476         case B_SIMA_REPACK:
477                 BKE_image_memorypack(sima->image);
478                 allqueue(REDRAWIMAGE, 0);
479                 break;
480                 
481         case B_SIMA_USE_ALPHA:
482                 sima->flag &= ~(SI_SHOW_ALPHA|SI_SHOW_ZBUF);
483                 scrarea_queue_winredraw(curarea);
484                 scrarea_queue_headredraw(curarea);
485                 break;
486         case B_SIMA_SHOW_ALPHA:
487                 sima->flag &= ~(SI_USE_ALPHA|SI_SHOW_ZBUF);
488                 scrarea_queue_winredraw(curarea);
489                 scrarea_queue_headredraw(curarea);
490                 break;
491         case B_SIMA_SHOW_ZBUF:
492                 sima->flag &= ~(SI_SHOW_ALPHA|SI_USE_ALPHA);
493                 scrarea_queue_winredraw(curarea);
494                 scrarea_queue_headredraw(curarea);
495                 break;
496         case B_SIMARELOAD:
497                 reload_image_sima();
498                 break;
499         case B_SIMAGELOAD:
500                 open_image_sima(0);
501                 break;
502         case B_SIMANAME:
503                 if(sima->image) {
504                         Image *ima;
505                         char str[FILE_MAXDIR+FILE_MAXFILE];
506                         
507                         /* name in ima has been changed by button! */
508                         BLI_strncpy(str, sima->image->name, sizeof(str));
509                         ima= BKE_add_image_file(str);
510                         if(ima) {
511                                 BKE_image_signal(ima, &sima->iuser, IMA_SIGNAL_RELOAD);
512                                 image_changed(sima, ima);
513                         }
514                         BIF_undo_push("Load image");
515                         allqueue(REDRAWIMAGE, 0);
516                 }
517                 break;
518         case B_SIMAMULTI:
519                 if(sima && sima->image) {
520                         BKE_image_multilayer_index(sima->image->rr, &sima->iuser);
521                         allqueue(REDRAWIMAGE, 0);
522                 }
523                 break;
524         case B_TRANS_IMAGE:
525                 image_editvertex_buts(NULL);
526                 break;
527         case B_CURSOR_IMAGE:
528                 image_editcursor_buts(NULL);
529                 break;
530                 
531         case B_TWINANIM:
532         {
533                 Image *ima;
534                 int nr;
535                 
536                 ima = sima->image;
537                 if (ima) {
538                         if(ima->flag & IMA_TWINANIM) {
539                                 nr= ima->xrep*ima->yrep;
540                                 if(ima->twsta>=nr) ima->twsta= 1;
541                                 if(ima->twend>=nr) ima->twend= nr-1;
542                                 if(ima->twsta>ima->twend) ima->twsta= 1;
543                         }
544
545                         allqueue(REDRAWIMAGE, 0);
546                         allqueue(REDRAWVIEW3D, 0);
547                 }
548                 break;
549         }       
550         case B_SIMACLONEBROWSE:
551                 if(settings->imapaint.brush) {
552                         Brush *brush= settings->imapaint.brush;
553                 
554                         if(sima->menunr== -2) {
555                                 if(G.qual & LR_CTRLKEY) {
556                                         activate_databrowse_imasel((ID *)brush->clone.image, ID_IM, 0, B_SIMACLONEBROWSE,
557                                                                                                 &sima->menunr, do_image_buttons);
558                                 } else {
559                                         activate_databrowse((ID *)brush->clone.image, ID_IM, 0, B_SIMACLONEBROWSE,
560                                                                                                 &sima->menunr, do_image_buttons);
561                                 }
562                                 break;
563                         }
564                         if(sima->menunr < 0) break;
565
566                         if(brush_clone_image_set_nr(brush, sima->menunr))
567                                 allqueue(REDRAWIMAGE, 0);
568                 }
569                 break;
570                 
571         case B_SIMACLONEDELETE:
572                 if (settings->imapaint.brush)
573                         if (brush_clone_image_delete(settings->imapaint.brush))
574                                 allqueue(REDRAWIMAGE, 0);
575                 break;
576                 
577         case B_SIMABRUSHCHANGE:
578                 allqueue(REDRAWIMAGE, 0);
579                 allqueue(REDRAWBUTSEDIT, 0);
580                 break;
581                 
582         case B_SIMACURVES:
583                 curvemapping_do_ibuf(sima->cumap, imagewindow_get_ibuf(sima));
584                 allqueue(REDRAWIMAGE, 0);
585                 break;
586                 
587         case B_SIMARANGE:
588                 curvemapping_set_black_white(sima->cumap, NULL, NULL);
589                 curvemapping_do_ibuf(sima->cumap, imagewindow_get_ibuf(sima));
590                 allqueue(REDRAWIMAGE, 0);
591                 break;
592                 
593         case B_SIMABRUSHBROWSE:
594                 if(sima->menunr==-2) {
595                         activate_databrowse((ID*)settings->imapaint.brush, ID_BR, 0, B_SIMABRUSHBROWSE, &sima->menunr, do_global_buttons);
596                         break;
597                 }
598                 else if(sima->menunr < 0) break;
599                 
600                 if(brush_set_nr(&settings->imapaint.brush, sima->menunr)) {
601                         BIF_undo_push("Browse Brush");
602                         allqueue(REDRAWBUTSEDIT, 0);
603                         allqueue(REDRAWIMAGE, 0);
604                 }
605                 break;
606         case B_SIMABRUSHDELETE:
607                 if(brush_delete(&settings->imapaint.brush)) {
608                         BIF_undo_push("Unlink Brush");
609                         allqueue(REDRAWIMAGE, 0);
610                         allqueue(REDRAWBUTSEDIT, 0);
611                 }
612                 break;
613         case B_KEEPDATA:
614                 brush_toggled_fake_user(settings->imapaint.brush);
615                 allqueue(REDRAWIMAGE, 0);
616                 allqueue(REDRAWBUTSEDIT, 0);
617                 break;
618         case B_SIMABRUSHLOCAL:
619                 if(settings->imapaint.brush && settings->imapaint.brush->id.lib) {
620                         if(okee("Make local")) {
621                                 make_local_brush(settings->imapaint.brush);
622                                 allqueue(REDRAWIMAGE, 0);
623                                 allqueue(REDRAWBUTSEDIT, 0);
624                         }
625                 }
626                 break;
627         case B_SIMABTEXBROWSE:
628                 if(settings->imapaint.brush) {
629                         Brush *brush= settings->imapaint.brush;
630                         
631                         if(sima->menunr==-2) {
632                                 MTex *mtex= brush->mtex[brush->texact];
633                                 ID *id= (ID*)((mtex)? mtex->tex: NULL);
634                                 if(G.qual & LR_CTRLKEY) {
635                                         activate_databrowse_imasel(id, ID_TE, 0, B_SIMABTEXBROWSE, &sima->menunr, do_image_buttons);
636                                 } else {
637                                         activate_databrowse(id, ID_TE, 0, B_SIMABTEXBROWSE, &sima->menunr, do_image_buttons);
638                                 }
639                                 break;
640                         }
641                         else if(sima->menunr < 0) break;
642                         
643                         if(brush_texture_set_nr(brush, sima->menunr)) {
644                                 BIF_undo_push("Browse Brush Texture");
645                                 allqueue(REDRAWBUTSSHADING, 0);
646                                 allqueue(REDRAWBUTSEDIT, 0);
647                                 allqueue(REDRAWIMAGE, 0);
648                         }
649                 }
650                 break;
651         case B_SIMABTEXDELETE:
652                 if(settings->imapaint.brush) {
653                         if (brush_texture_delete(settings->imapaint.brush)) {
654                                 BIF_undo_push("Unlink Brush Texture");
655                                 allqueue(REDRAWBUTSSHADING, 0);
656                                 allqueue(REDRAWBUTSEDIT, 0);
657                                 allqueue(REDRAWIMAGE, 0);
658                         }
659                 }
660                 break;
661         case B_SIMA_PLAY:
662                 play_anim(0);
663                 break;
664         case B_SIMA_RECORD:
665                 imagespace_composite_flipbook(curarea);
666                 break;
667         }
668 #endif
669 }
670
671 #if 0
672 static void do_image_buttons_set_uvlayer_callback(void *act, void *data)
673 {
674         CustomData_set_layer_active(&G.editMesh->fdata, CD_MTFACE, *((int *)act));
675         
676         BIF_undo_push("Set Active UV Texture");
677         allqueue(REDRAWVIEW3D, 0);
678         allqueue(REDRAWBUTSEDIT, 0);
679         allqueue(REDRAWIMAGE, 0);
680 }
681 #endif
682
683 static void sima_idpoin_handle(bContext *C, ID *id, int event)
684 {
685         SpaceImage *sima= (SpaceImage*)CTX_wm_space_data(C);
686         Scene *scene= CTX_data_scene(C);
687         Object *obedit= CTX_data_edit_object(C);
688
689         switch(event) {
690                 case UI_ID_BROWSE:
691                 case UI_ID_DELETE:
692                         ED_space_image_set(C, sima, scene, obedit, (Image*)id);
693                         ED_undo_push(C, "Assign Image UV");
694                         break;
695                 case UI_ID_RENAME:
696                         break;
697                 case UI_ID_ADD_NEW:
698                         WM_operator_name_call(C, "IMAGE_OT_new", WM_OP_INVOKE_REGION_WIN, NULL);
699                         break;
700                 case UI_ID_OPEN:
701                         WM_operator_name_call(C, "IMAGE_OT_open", WM_OP_INVOKE_REGION_WIN, NULL);
702                         break;
703                 case UI_ID_PIN:
704                         ED_area_tag_refresh(CTX_wm_area(C));
705                         break;
706         }
707 }
708
709 void image_header_buttons(const bContext *C, ARegion *ar)
710 {
711         bScreen *sc= CTX_wm_screen(C);
712         ScrArea *sa= CTX_wm_area(C);
713         Scene *scene= CTX_data_scene(C);
714         SpaceImage *sima= (SpaceImage*)CTX_wm_space_data(C);
715         Image *ima;
716         ImBuf *ibuf;
717         uiBlock *block;
718         uiBut *but;
719         PointerRNA spaceptr, uvptr, sceneptr;
720         int xco, yco= 3, show_uvedit, show_render, show_paint, pinflag;
721
722         /* retrieve state */
723         ima= ED_space_image(sima);
724         ibuf= ED_space_image_buffer(sima);
725
726         show_render= ED_space_image_show_render(sima);
727         show_paint= ED_space_image_show_paint(sima);
728         show_uvedit= ED_space_image_show_uvedit(sima, CTX_data_edit_object(C));
729
730         RNA_pointer_create(&sc->id, &RNA_SpaceImageEditor, sima, &spaceptr);
731         RNA_pointer_create(&sc->id, &RNA_SpaceUVEditor, sima, &uvptr);
732         RNA_id_pointer_create(&scene->id, &sceneptr);
733         
734         /* create block */
735         block= uiBeginBlock(C, ar, "header buttons", UI_EMBOSS);
736         uiBlockSetHandleFunc(block, do_image_buttons, NULL);
737         
738         xco= ED_area_header_standardbuttons(C, block, yco);
739         
740         /* create pulldown menus */
741         if((sa->flag & HEADER_NO_PULLDOWN)==0) {
742                 char *menuname;
743                 int xmax;
744                 
745                 xmax= GetButStringLength("View");
746                 uiDefMenuBut(block, image_viewmenu, NULL, "View", xco, yco, xmax-3, 20, "");
747                 xco+= xmax;
748                 
749                 if(show_uvedit) {
750                         xmax= GetButStringLength("Select");
751                         uiDefMenuBut(block, image_selectmenu, NULL, "Select", xco, yco, xmax-3, 20, "");
752                         xco+= xmax;
753                 }
754                 
755                 menuname= (ibuf && (ibuf->userflags & IB_BITMAPDIRTY))? "Image*": "Image";
756                 xmax= GetButStringLength(menuname);
757                 uiDefMenuBut(block, image_imagemenu, NULL, menuname, xco, yco, xmax-3, 20, "");
758                 xco+= xmax;
759
760                 if(show_uvedit) {
761                         xmax= GetButStringLength("UVs");
762                         uiDefMenuBut(block, image_uvsmenu, NULL, "UVs", xco, yco, xmax-3, 20, "");
763                         xco+= xmax;
764                 }
765         }
766
767         uiBlockSetEmboss(block, UI_EMBOSS);
768
769         /* image select */
770
771         pinflag= (show_render)? 0: UI_ID_PIN;
772         xco= uiDefIDPoinButs(block, CTX_data_main(C), NULL, (ID*)sima->image, ID_IM, &sima->pin, xco, yco,
773                 sima_idpoin_handle, UI_ID_BROWSE|UI_ID_BROWSE_RENDER|UI_ID_RENAME|UI_ID_ADD_NEW|UI_ID_OPEN|UI_ID_DELETE|pinflag);
774         xco += 8;
775
776         if(ima && !ELEM3(ima->source, IMA_SRC_SEQUENCE, IMA_SRC_MOVIE, IMA_SRC_VIEWER) && ima->ok) {
777                 /* XXX this should not be a static var */
778                 static int headerbuttons_packdummy;
779                 
780                 headerbuttons_packdummy = 0;
781
782                 if (ima->packedfile) {
783                         headerbuttons_packdummy = 1;
784                 }
785                 if (ima->packedfile && ibuf && (ibuf->userflags & IB_BITMAPDIRTY))
786                         uiDefIconButBitI(block, TOG, 1, 0 /* XXX B_SIMA_REPACK */, ICON_UGLYPACKAGE,    xco,yco,XIC,YIC, &headerbuttons_packdummy, 0, 0, 0, 0, "Re-Pack this image as PNG");
787                 else
788                         uiDefIconButBitI(block, TOG, 1, 0 /* XXX B_SIMAPACKIMA */, ICON_PACKAGE,        xco,yco,XIC,YIC, &headerbuttons_packdummy, 0, 0, 0, 0, "Pack/Unpack this image");
789                         
790                 xco+= XIC+8;
791         }
792         
793         /* uv editing */
794         if(show_uvedit) {
795                 /* pivot */
796                 uiDefIconTextButS(block, ICONTEXTROW, B_NOP, ICON_ROTATE,
797                                 "Pivot: %t|Bounding Box Center %x0|Median Point %x3|2D Cursor %x1",
798                                 xco,yco,XIC+10,YIC, &ar->v2d.around, 0, 3.0, 0, 0,
799                                 "Rotation/Scaling Pivot (Hotkeys: Comma, Shift Comma, Period)");
800                 xco+= XIC + 18;
801                 
802                 /* selection modes */
803                 uiDefIconButBitS(block, TOG, UV_SYNC_SELECTION, B_REDR, ICON_EDIT, xco,yco,XIC,YIC, &scene->toolsettings->uv_flag, 0, 0, 0, 0, "Sync UV and Mesh Selection");
804                 xco+= XIC+8;
805
806                 if(scene->toolsettings->uv_flag & UV_SYNC_SELECTION) {
807                         uiBlockBeginAlign(block);
808                         
809                         uiDefIconButBitS(block, TOG, SCE_SELECT_VERTEX, B_REDR, ICON_VERTEXSEL,
810                                 xco,yco,XIC,YIC, &scene->selectmode, 1.0, 0.0, 0, 0, "Vertex select mode");
811                         uiDefIconButBitS(block, TOG, SCE_SELECT_EDGE, B_REDR, ICON_EDGESEL,
812                                 xco+=XIC,yco,XIC,YIC, &scene->selectmode, 1.0, 0.0, 0, 0, "Edge select mode");
813                         uiDefIconButBitS(block, TOG, SCE_SELECT_FACE, B_REDR, ICON_FACESEL,
814                                 xco+=XIC,yco,XIC,YIC, &scene->selectmode, 1.0, 0.0, 0, 0, "Face select mode");
815
816                         uiBlockEndAlign(block);
817                 }
818                 else {
819                         uiBlockBeginAlign(block);
820
821                         uiDefIconButS(block, ROW, B_REDR, ICON_VERTEXSEL,
822                                 xco,yco,XIC,YIC, &scene->toolsettings->uv_selectmode, 1.0, UV_SELECT_VERTEX, 0, 0, "Vertex select mode");
823                         uiDefIconButS(block, ROW, B_REDR, ICON_EDGESEL,
824                                 xco+=XIC,yco,XIC,YIC, &scene->toolsettings->uv_selectmode, 1.0, UV_SELECT_EDGE, 0, 0, "Edge select mode");
825                         uiDefIconButS(block, ROW, B_REDR, ICON_FACESEL,
826                                 xco+=XIC,yco,XIC,YIC, &scene->toolsettings->uv_selectmode, 1.0, UV_SELECT_FACE, 0, 0, "Face select mode");
827                         uiDefIconButS(block, ROW, B_REDR, ICON_LINKEDSEL,
828                                 xco+=XIC,yco,XIC,YIC, &scene->toolsettings->uv_selectmode, 1.0, UV_SELECT_ISLAND, 0, 0, "Island select mode");
829
830                         uiBlockEndAlign(block);
831
832                         /* would use these if const's could go in strings 
833                          * SI_STICKY_LOC SI_STICKY_DISABLE SI_STICKY_VERTEX */
834                         but = uiDefIconTextButC(block, ICONTEXTROW, B_REDR, ICON_STICKY_UVS_LOC,
835                                         "Sticky UV Selection: %t|Disable%x1|Shared Location%x0|Shared Vertex%x2",
836                                         xco+=XIC+10,yco,XIC+10,YIC, &(sima->sticky), 0, 3.0, 0, 0,
837                                         "Sticky UV Selection (Hotkeys: Shift C, Alt C, Ctrl C)");
838                 }
839
840                 xco+= XIC + 16;
841                 
842                 /* snap options, identical to options in 3d view header */
843                 uiBlockBeginAlign(block);
844
845                 if (scene->snap_flag & SCE_SNAP) {
846                         uiDefIconButBitS(block, TOG, SCE_SNAP, B_REDR, ICON_SNAP_GEO,xco,yco,XIC,YIC, &scene->snap_flag, 0, 0, 0, 0, "Use Snap or Grid (Shift Tab).");
847                         xco+= XIC;
848                         uiDefButS(block, MENU, B_NOP, "Mode%t|Closest%x0|Center%x1|Median%x2",xco,yco,70,YIC, &scene->snap_target, 0, 0, 0, 0, "Snap Target Mode.");
849                         xco+= 70;
850                 }
851                 else {
852                         uiDefIconButBitS(block, TOG, SCE_SNAP, B_REDR, ICON_SNAP_GEAR,xco,yco,XIC,YIC, &scene->snap_flag, 0, 0, 0, 0, "Snap while Ctrl is held during transform (Shift Tab)."); 
853                         xco+= XIC;
854                 }
855
856                 uiBlockEndAlign(block);
857                 xco+= 8;
858
859                 /* uv layers */
860                 {
861                         Object *obedit= CTX_data_edit_object(C);
862                         char menustr[34*MAX_MTFACE];
863                         static int act;
864                         
865                         image_menu_uvlayers(obedit, menustr, &act);
866
867                         but = uiDefButI(block, MENU, B_NOP, menustr ,xco,yco,85,YIC, &act, 0, 0, 0, 0, "Active UV Layer for editing.");
868                         // uiButSetFunc(but, do_image_buttons_set_uvlayer_callback, &act, NULL);
869                         
870                         xco+= 85;
871                 }
872
873                 xco+= 8;
874         }
875         
876         if(ima) {
877                 RenderResult *rr;
878         
879                 /* render layers and passes */
880                 rr= BKE_image_get_renderresult(scene, ima);
881                 if(rr) {
882                         uiBlockBeginAlign(block);
883 #if 0
884                         uiblock_layer_pass_buttons(block, rr, &sima->iuser, B_REDR, xco, 0, 160);
885 #endif
886                         uiBlockEndAlign(block);
887                         xco+= 166;
888                 }
889
890                 /* painting */
891                 uiDefIconButR(block, TOG, B_REDR, ICON_TPAINT_HLT, xco,yco,XIC,YIC, &spaceptr, "image_painting", 0, 0, 0, 0, 0, NULL);
892                 xco+= XIC+8;
893
894                 /* image draw options */
895                 uiBlockBeginAlign(block);
896                 uiDefIconButR(block, ROW, B_REDR, ICON_IMAGE_RGB, xco,yco,XIC,YIC, &spaceptr, "draw_channels", 0, 0, 0, 0, 0, NULL);
897                 xco+= XIC;
898                 if(ibuf==NULL || ibuf->channels==4) {
899                         uiDefIconButR(block, ROW, B_REDR, ICON_IMAGE_RGB_ALPHA, xco,yco,XIC,YIC, &spaceptr, "draw_channels", 0, 0, SI_USE_ALPHA, 0, 0, NULL);
900                         xco+= XIC;
901                         uiDefIconButR(block, ROW, B_REDR, ICON_IMAGE_ALPHA, xco,yco,XIC,YIC, &spaceptr, "draw_channels", 0, 0, SI_SHOW_ALPHA, 0, 0, NULL);
902                         xco+= XIC;
903                 }
904                 if(ibuf) {
905                         if(ibuf->zbuf || ibuf->zbuf_float || (ibuf->channels==1)) {
906                                 uiDefIconButR(block, ROW, B_REDR, ICON_IMAGE_ZDEPTH, xco,yco,XIC,YIC, &spaceptr, "draw_channels", 0, 0, SI_SHOW_ZBUF, 0, 0, NULL);
907                                 xco+= XIC;
908                         }
909                 }               
910                 xco+= 8;
911                 
912                 /* record & play */
913                 uiBlockBeginAlign(block);
914                 if(ima->type==IMA_TYPE_COMPOSITE) {
915                         uiDefIconButO(block, BUT, "IMAGE_OT_record_composite", WM_OP_INVOKE_REGION_WIN, ICON_REC, xco, yco, XIC, YIC, NULL); // Record Composite
916                         xco+= XIC;
917                 }
918                 if((ima->type==IMA_TYPE_COMPOSITE) || ELEM(ima->source, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE)) {
919 //XXX                   uiDefIconButO(block, BUT, "IMAGE_OT_play_composite", WM_OP_INVOKE_REGION_WIN, ICON_PLAY, xco, yco, XIC, YIC, NULL); // PLAY
920                         xco+= XIC;
921                 }
922                 uiBlockEndAlign(block);
923                 xco+= 8;
924         }
925         
926         /* draw lock */
927         uiDefIconButR(block, ICONTOG, 0, ICON_UNLOCKED, xco,yco,XIC,YIC, &spaceptr, "update_automatically", 0, 0, 0, 0, 0, NULL);
928
929         /* always as last  */
930         UI_view2d_totRect_set(&ar->v2d, xco+XIC+80, ar->v2d.tot.ymax-ar->v2d.tot.ymin);
931         
932         uiEndBlock(C, block);
933         uiDrawBlock(C, block);
934 }
935
936 /********************** toolbox operator *********************/
937
938 static int toolbox_invoke(bContext *C, wmOperator *op, wmEvent *event)
939 {
940         SpaceImage *sima= (SpaceImage*)CTX_wm_space_data(C);
941         Object *obedit= CTX_data_edit_object(C);
942         uiMenuItem *head;
943         int show_uvedit;
944
945         show_uvedit= ED_space_image_show_uvedit(sima, obedit);
946
947         head= uiPupMenuBegin("Toolbox", 0);
948
949         uiMenuLevel(head, "View", image_viewmenu);
950         if(show_uvedit) uiMenuLevel(head, "Select", image_selectmenu);
951         uiMenuLevel(head, "Image", image_imagemenu);
952         if(show_uvedit) uiMenuLevel(head, "UVs", image_uvsmenu);
953
954         uiPupMenuEnd(C, head);
955
956         return OPERATOR_CANCELLED;
957 }
958
959 void IMAGE_OT_toolbox(wmOperatorType *ot)
960 {
961         /* identifiers */
962         ot->name= "Toolbox";
963         ot->idname= "IMAGE_OT_toolbox";
964         
965         /* api callbacks */
966         ot->invoke= toolbox_invoke;
967         ot->poll= space_image_main_area_poll;
968 }
969