Seam Cutting in Faceselect Mode:
[blender.git] / source / blender / src / header_image.c
1 /**
2  * header_image.c oct-2003
3  *
4  * Functions to draw the "UV/Image Editor" window header
5  * and handle user events sent to it.
6  * 
7  * $Id$
8  *
9  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version. The Blender
15  * Foundation also sells licenses for use in proprietary software under
16  * the Blender License.  See http://www.blender.org/BL/ for information
17  * about this.
18  *
19  * This program is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU General Public License for more details.
23  *
24  * You should have received a copy of the GNU General Public License
25  * along with this program; if not, write to the Free Software Foundation,
26  * Inc., 59 Temple Place - Suite 330, Boston, MA        02111-1307, USA.
27  *
28  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
29  * All rights reserved.
30  *
31  * The Original Code is: all of this file.
32  *
33  * Contributor(s): none yet.
34  *
35  * ***** END GPL/BL DUAL LICENSE BLOCK *****
36  */
37
38 #include <stdlib.h>
39 #include <string.h>
40
41 #ifdef HAVE_CONFIG_H
42 #include <config.h>
43 #endif
44
45 #include "DNA_ID.h"
46 #include "DNA_image_types.h"
47 #include "DNA_mesh_types.h"
48 #include "DNA_object_types.h"
49 #include "DNA_packedFile_types.h"
50 #include "DNA_scene_types.h"
51 #include "DNA_screen_types.h"
52 #include "DNA_space_types.h"
53 #include "DNA_userdef_types.h"
54
55 #include "BDR_drawmesh.h"
56 #include "BDR_unwrapper.h"
57 #include "BKE_global.h"
58 #include "BKE_image.h"
59 #include "BKE_library.h"
60 #include "BKE_main.h"
61 #include "BKE_packedFile.h"
62 #include "BKE_utildefines.h"
63 #include "BKE_depsgraph.h"
64
65 #include "BLI_blenlib.h"
66 #include "BIF_drawimage.h"
67 #include "BIF_editsima.h"
68 #include "BIF_interface.h"
69 #include "BIF_resources.h"
70 #include "BIF_screen.h"
71 #include "BIF_space.h"
72 #include "BIF_toets.h"
73 #include "BIF_toolbox.h"
74 #include "BIF_transform.h"
75 #include "BIF_writeimage.h"
76
77 #include "BSE_filesel.h"
78 #include "BSE_headerbuttons.h"
79
80 #include "BPY_extern.h"
81 #include "BPY_menus.h"
82
83 #include "IMB_imbuf.h"
84 #include "IMB_imbuf_types.h"
85 #include "BSE_trans_types.h"
86
87 #include "blendef.h"
88 #include "mydevice.h"
89
90 static void load_space_image(char *str) /* called from fileselect */
91 {
92         Image *ima=0;
93  
94         if(G.obedit) {
95                 error("Can't perfom this in editmode");
96                 return;
97         }
98
99         ima= add_image(str);
100         if(ima) {
101
102                 G.sima->image= ima;
103
104                 free_image_buffers(ima);        /* force read again */
105                 ima->ok= 1;
106                 image_changed(G.sima, 0);
107
108         }
109         BIF_undo_push("Load image UV");
110         allqueue(REDRAWIMAGE, 0);
111 }
112
113 static void image_replace(Image *old, Image *new)
114 {
115         TFace *tface;
116         Mesh *me;
117         int a, rep=0;
118
119         new->tpageflag= old->tpageflag;
120         new->twsta= old->twsta;
121         new->twend= old->twend;
122         new->xrep= old->xrep;
123         new->yrep= old->yrep;
124  
125         me= G.main->mesh.first;
126         while(me) {
127
128                 if(me->tface) {
129                         tface= me->tface;
130                         a= me->totface;
131                         while(a--) {
132                                 if(tface->tpage==old) {
133                                         tface->tpage= new;
134                                         rep++;
135                                 }
136                                 tface++;
137                         }
138                 }
139                 me= me->id.next;
140  
141         }
142         if(rep) {
143                 if(new->id.us==0) new->id.us= 1;
144         }
145         else error("Nothing replaced");
146 }
147
148 static void replace_space_image(char *str)              /* called from fileselect */
149 {
150         Image *ima=0;
151
152         if(G.obedit) {
153                 error("Can't perfom this in editmode");
154                 return;
155         }
156
157         ima= add_image(str);
158         if(ima) {
159  
160                 if(G.sima->image && G.sima->image != ima) {
161                         image_replace(G.sima->image, ima);
162                 }
163  
164                 G.sima->image= ima;
165
166                 free_image_buffers(ima);        /* force read again */
167                 ima->ok= 1;
168                 /* replace also assigns: */
169                 image_changed(G.sima, 0);
170
171         }
172         BIF_undo_push("Replace image UV");
173         allqueue(REDRAWIMAGE, 0);
174 }
175
176 static void save_paint(char *name)
177 {
178         char str[FILE_MAXDIR+FILE_MAXFILE];
179         Image *ima = G.sima->image;
180
181         if (ima  && ima->ibuf) {
182                 BLI_strncpy(str, name, sizeof(str));
183
184                 BLI_convertstringcode(str, G.sce, G.scene->r.cfra);
185                 
186                 if (saveover(str)) {
187                         if (BKE_write_ibuf(ima->ibuf, str, G.scene->r.imtype, G.scene->r.subimtype, G.scene->r.quality)) {
188                                 BLI_strncpy(ima->name, name, sizeof(ima->name));
189                                 ima->ibuf->userflags &= ~IB_BITMAPDIRTY;
190                                 allqueue(REDRAWHEADERS, 0);
191                                 allqueue(REDRAWBUTSSHADING, 0);
192                         } else {
193                                 error("Couldn't write image: %s", str);
194                         }
195                 }
196         }
197 }
198
199 void do_image_buttons(unsigned short event)
200 {
201         Image *ima;
202         ID *id, *idtest;
203         int nr;
204         char name[256];
205
206         if(curarea->win==0) return;
207
208         switch(event) {
209         case B_SIMAGEHOME:
210                 image_home();
211                 break;
212
213         case B_SIMABROWSE:      
214                 if(G.sima->imanr== -2) {
215                         activate_databrowse((ID *)G.sima->image, ID_IM, 0, B_SIMABROWSE,
216                                                                                         &G.sima->imanr, do_image_buttons);
217                         return;
218                 }
219                 if(G.sima->imanr < 0) break;
220         
221                 nr= 1;
222                 id= (ID *)G.sima->image;
223
224                 idtest= G.main->image.first;
225                 while(idtest) {
226                         if(nr==G.sima->imanr) {
227                                 break;
228                         }
229                         nr++;
230                         idtest= idtest->next;
231                 }
232                 if(idtest==0) { /* no new */
233                         return;
234                 }
235         
236                 if(idtest!=id) {
237                         G.sima->image= (Image *)idtest;
238                         if(idtest->us==0) idtest->us= 1;
239                         allqueue(REDRAWIMAGE, 0);
240                 }
241                 /* also when image is the same: assign! 0==no tileflag: */
242                 image_changed(G.sima, 0);
243                 BIF_undo_push("Assign image UV");
244
245                 break;
246         case B_SIMAGELOAD:
247                 
248                 if(G.sima->image) strcpy(name, G.sima->image->name);
249                 else strcpy(name, U.textudir);
250                 
251                 if(G.qual==LR_CTRLKEY)
252                         activate_imageselect(FILE_SPECIAL, "SELECT IMAGE", name, load_space_image);
253                 else
254                         activate_fileselect(FILE_SPECIAL, "SELECT IMAGE", name, load_space_image);
255                 break;
256                 
257         case B_SIMAGEREPLACE:
258                 
259                 if(G.sima->image) strcpy(name, G.sima->image->name);
260                 else strcpy(name, U.textudir);
261                 
262                 if(G.qual==LR_CTRLKEY)
263                         activate_imageselect(FILE_SPECIAL, "REPLACE IMAGE", name, replace_space_image);
264                 else
265                         activate_fileselect(FILE_SPECIAL, "REPLACE IMAGE", name, replace_space_image);
266                 break;
267                 
268         case B_SIMAGEDRAW:
269                 
270                 if(G.f & G_FACESELECT) {
271                         make_repbind(G.sima->image);
272                         image_changed(G.sima, 1);
273                 }
274                 allqueue(REDRAWVIEW3D, 0);
275                 allqueue(REDRAWIMAGE, 0);
276                 break;
277
278         case B_SIMAGEDRAW1:
279                 image_changed(G.sima, 2);               /* 2: only tileflag */
280                 allqueue(REDRAWVIEW3D, 0);
281                 allqueue(REDRAWIMAGE, 0);
282                 break;
283                 
284         case B_TWINANIM:
285                 ima = G.sima->image;
286                 if (ima) {
287                         if(ima->flag & IMA_TWINANIM) {
288                                 nr= ima->xrep*ima->yrep;
289                                 if(ima->twsta>=nr) ima->twsta= 1;
290                                 if(ima->twend>=nr) ima->twend= nr-1;
291                                 if(ima->twsta>ima->twend) ima->twsta= 1;
292                                 allqueue(REDRAWIMAGE, 0);
293                         }
294                 }
295                 break;
296
297         case B_SIMAGEPAINTTOOL:
298                 // check for packed file here
299                 allqueue(REDRAWIMAGE, 0);
300                 allqueue(REDRAWVIEW3D, 0);
301                 break;
302         case B_SIMAPACKIMA:
303                 ima = G.sima->image;
304                 if (ima) {
305                         if (ima->packedfile) {
306                                 if (G.fileflags & G_AUTOPACK) {
307                                         if (okee("Disable AutoPack ?")) {
308                                                 G.fileflags &= ~G_AUTOPACK;
309                                         }
310                                 }
311                                 
312                                 if ((G.fileflags & G_AUTOPACK) == 0) {
313                                         unpackImage(ima, PF_ASK);
314                                 }
315                         } else {
316                                 if (ima->ibuf && (ima->ibuf->userflags & IB_BITMAPDIRTY)) {
317                                         error("Can't pack painted image. Save image first.");
318                                 } else {
319                                         ima->packedfile = newPackedFile(ima->name);
320                                 }
321                         }
322                         allqueue(REDRAWBUTSSHADING, 0);
323                         allqueue(REDRAWHEADERS, 0);
324                 }
325                 break;
326         case B_SIMAGESAVE:
327                 ima = G.sima->image;
328                 if (ima) {
329                         strcpy(name, ima->name);
330                         if (ima->ibuf) {
331                                 char str[64];
332                                 save_image_filesel_str(str);
333                                 
334                                 if(G.scene->r.scemode & R_EXTENSION) 
335                                         BKE_add_image_extension(name, G.scene->r.imtype);
336                                 
337                                 activate_fileselect(FILE_SPECIAL, str, name, save_paint);
338                         }
339                 }
340                 break;
341         case B_SIMA_USE_ALPHA:
342                 G.sima->flag &= ~(SI_SHOW_ALPHA|SI_SHOW_ZBUF);
343                 scrarea_queue_winredraw(curarea);
344                 scrarea_queue_headredraw(curarea);
345                 break;
346         case B_SIMA_SHOW_ALPHA:
347                 G.sima->flag &= ~(SI_USE_ALPHA|SI_SHOW_ZBUF);
348                 scrarea_queue_winredraw(curarea);
349                 scrarea_queue_headredraw(curarea);
350                 break;
351         case B_SIMA_SHOW_ZBUF:
352                 G.sima->flag &= ~(SI_SHOW_ALPHA|SI_USE_ALPHA);
353                 scrarea_queue_winredraw(curarea);
354                 scrarea_queue_headredraw(curarea);
355                 break;
356         }
357 }
358
359 static void do_image_view_viewnavmenu(void *arg, int event)
360 {
361         switch(event) {
362         case 1: /* Zoom In */
363                 image_viewzoom(PADPLUSKEY, 0);
364                 break;
365         case 2: /* Zoom Out */
366                 image_viewzoom(PADMINUS, 0);
367                 break;
368         case 3: /* Zoom 8:1 */
369                 image_viewzoom(PAD8, 0);
370                 break;
371         case 4: /* Zoom 4:1 */
372                 image_viewzoom(PAD4, 0);
373                 break;
374         case 5: /* Zoom 2:1 */
375                 image_viewzoom(PAD2, 0);
376                 break;
377         case 6: /* Zoom 1:1 */
378                 image_viewzoom(PAD1, 0);
379                 break;
380         case 7: /* Zoom 1:2 */
381                 image_viewzoom(PAD2, 1);
382                 break;
383         case 8: /* Zoom 1:4 */
384                 image_viewzoom(PAD4, 1);
385                 break;
386         case 9: /* Zoom 1:8 */
387                 image_viewzoom(PAD8, 1);
388                 break;
389         }
390         allqueue(REDRAWIMAGE, 0);
391 }
392
393 static uiBlock *image_view_viewnavmenu(void *arg_unused)
394 {
395 /*              static short tog=0; */
396         uiBlock *block;
397         short yco= 0, menuwidth=120;
398         
399         block= uiNewBlock(&curarea->uiblocks, "image_view_viewnavmenu", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
400         uiBlockSetButmFunc(block, do_image_view_viewnavmenu, NULL);
401         
402         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Zoom In|NumPad +", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 1, "");
403         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Zoom Out|NumPad -",      0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 2, "");
404
405         uiDefBut(block, SEPR, 0, "",        0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
406
407         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Zoom 1:8", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 3, "");
408         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Zoom 1:4", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 4, "");
409         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Zoom 1:2", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 5, "");
410         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Zoom 1:1", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 6, "");
411         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Zoom 2:1", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 7, "");
412         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Zoom 4:1", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 8, "");
413         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Zoom 8:1", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 9, "");
414
415         uiBlockSetDirection(block, UI_RIGHT);
416         uiTextBoundsBlock(block, 50);
417         return block;
418 }
419
420 static void do_image_viewmenu(void *arg, int event)
421 {
422
423         switch(event) {
424         case 0: /* Update Automatically */
425                 if(G.sima->lock) G.sima->lock = 0;
426                 else G.sima->lock = 1;
427                 break;
428         case 1: /* View All */
429                 do_image_buttons(B_SIMAGEHOME);
430                 break;
431         case 2: /* Maximize Window */
432                 /* using event B_FULL */
433                 break;
434         case 5: /* Draw Shadow Mesh */
435                 if(G.sima->flag & SI_DRAWSHADOW)
436                         G.sima->flag &= ~SI_DRAWSHADOW;
437                 else
438                         G.sima->flag |= SI_DRAWSHADOW;
439                 allqueue(REDRAWIMAGE, 0);
440                 break;
441         case 6: /* Draw Faces */
442                 if(G.f & G_DRAWFACES)
443                         G.f &= ~G_DRAWFACES;
444                 else
445                         G.f |= G_DRAWFACES;
446                 allqueue(REDRAWIMAGE, 0);
447                 break;
448         case 7: /* Properties  Panel */
449                 add_blockhandler(curarea, IMAGE_HANDLER_PROPERTIES, UI_PNL_UNSTOW);
450                 break;
451         case 8: /* Paint Panel... */
452                 add_blockhandler(curarea, IMAGE_HANDLER_PAINT, UI_PNL_UNSTOW);
453                 break;
454         case 9:
455                 image_viewcentre();
456         case 10: /* Display Normalized Coordinates */
457                 G.sima->flag ^= SI_COORDFLOATS;
458                 allqueue(REDRAWIMAGE, 0);
459                 break;
460         case 11: /* Curves Panel... */
461                 add_blockhandler(curarea, IMAGE_HANDLER_CURVES, UI_PNL_UNSTOW);
462                 break;
463         }
464         allqueue(REDRAWVIEW3D, 0);
465 }
466
467 static uiBlock *image_viewmenu(void *arg_unused)
468 {
469 /*      static short tog=0; */
470         uiBlock *block;
471         short yco= 0, menuwidth=120;
472         
473         block= uiNewBlock(&curarea->uiblocks, "image_viewmenu", UI_EMBOSSP, UI_HELV, curarea->headwin);
474         uiBlockSetButmFunc(block, do_image_viewmenu, NULL);
475
476         uiDefIconTextBut(block, BUTM, 1, ICON_MENU_PANEL, "Show Properties...", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 7, "");
477         uiDefIconTextBut(block, BUTM, 1, ICON_MENU_PANEL, "Show Paint Tool...|C",       0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 8, "");
478         uiDefIconTextBut(block, BUTM, 1, ICON_MENU_PANEL, "Show Curves Tool...",        0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 11, "");
479
480         if(G.sima->flag & SI_COORDFLOATS) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Display Normalized Coordinates|", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 10, "");
481         else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Display Normalized Coordinates|", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 10, "");
482         if(G.f & G_DRAWFACES) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Draw Faces", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 6, "");
483         else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Draw Faces|", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 6, "");
484         if(G.sima->flag & SI_DRAWSHADOW) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Draw Shadow Mesh", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 5, "");
485         else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Draw Shadow Mesh|", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 5, "");
486
487         uiDefBut(block, SEPR, 0, "",        0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
488         uiDefIconTextBlockBut(block, image_view_viewnavmenu, NULL, ICON_RIGHTARROW_THIN, "View Navigation", 0, yco-=20, 120, 19, "");
489
490         if(G.sima->lock) {
491                 uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Update Automatically|", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 0, "");
492         } else {
493                 uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Update Automatically|", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 0, "");
494         } 
495
496         uiDefBut(block, SEPR, 0, "",                                    0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
497         
498         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "View Selected|NumPad .",                 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 9, "");
499         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "View All|Home", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 1, "");
500                 
501         if(!curarea->full) uiDefIconTextBut(block, BUTM, B_FULL, ICON_BLANK1, "Maximize Window|Ctrl UpArrow", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 2, "");
502         else uiDefIconTextBut(block, BUTM, B_FULL, ICON_BLANK1, "Tile Window|Ctrl DownArrow", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 2, "");
503         
504         if(curarea->headertype==HEADERTOP) {
505                 uiBlockSetDirection(block, UI_DOWN);
506         }
507         else {
508                 uiBlockSetDirection(block, UI_TOP);
509                 uiBlockFlipOrder(block);
510         }
511
512         uiTextBoundsBlock(block, 50);
513         
514         return block;
515 }
516
517 static void do_image_selectmenu(void *arg, int event)
518 {
519         switch(event)
520         {
521         case 0: /* Border Select */
522                 borderselect_sima(UV_SELECT_ALL);
523                 break;
524         case 8: /* Border Select Pinned */
525                 borderselect_sima(UV_SELECT_PINNED);
526                 break;
527         case 1: /* Select/Deselect All */
528                 select_swap_tface_uv();
529                 break;
530         case 2: /* Unlink Selection */
531                 unlink_selection();
532                 break;
533         case 3: /* Linked UVs */
534                 select_linked_tface_uv(2);
535                 break;
536         case 4: /* Toggle Local UVs Stick to Vertex in Mesh */
537                 if(G.sima->flag & SI_LOCALSTICKY)
538                         G.sima->flag &= ~SI_LOCALSTICKY;
539                 else {
540                         G.sima->flag |= SI_LOCALSTICKY;
541                         G.sima->flag &= ~SI_STICKYUVS;
542                 }
543                 allqueue(REDRAWIMAGE, 0);
544                 break;  
545         case 5: /* Toggle UVs Stick to Vertex in Mesh */
546                 if(G.sima->flag & SI_STICKYUVS) {
547                         G.sima->flag &= ~SI_STICKYUVS;
548                         G.sima->flag |= SI_LOCALSTICKY;
549                 }
550                 else {
551                         G.sima->flag |= SI_STICKYUVS;
552                         G.sima->flag &= ~SI_LOCALSTICKY;
553                 }
554                 allqueue(REDRAWIMAGE, 0);
555                 break;  
556         case 6: /* Toggle Active Face Select */
557                 if(G.sima->flag & SI_SELACTFACE)
558                         G.sima->flag &= ~SI_SELACTFACE;
559                 else
560                         G.sima->flag |= SI_SELACTFACE;
561                 allqueue(REDRAWIMAGE, 0);
562                 break;
563         case 7: /* Pinned UVs */
564                 select_pinned_tface_uv();
565                 break;
566         }
567 }
568
569 static uiBlock *image_selectmenu(void *arg_unused)
570 {
571         uiBlock *block;
572         short yco= 0, menuwidth=120;
573
574         block= uiNewBlock(&curarea->uiblocks, "image_selectmenu", UI_EMBOSSP, UI_HELV, curarea->headwin);
575         uiBlockSetButmFunc(block, do_image_selectmenu, NULL);
576
577         if(G.sima->flag & SI_SELACTFACE) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Active Face Select|C", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 6, "");
578         else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Active Face Select|C", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 6, "");
579
580         uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");        
581
582         if(G.sima->flag & SI_LOCALSTICKY) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Stick Local UVs to Mesh Vertex|Shift C", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 4, "");
583         else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Stick Local UVs to Mesh Vertex|Shift C", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 4, "");
584
585         if(G.sima->flag & SI_STICKYUVS) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Stick UVs to Mesh Vertex|Ctrl C", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 5, "");
586         else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Stick UVs to Mesh Vertex|Ctrl C", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 5, "");
587
588         uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
589
590         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Border Select|B", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 0, "");
591         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Border Select Pinned|Shift B", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 8, "");
592
593         uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");        
594
595         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Select/Deselect All|A", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 1, "");
596
597         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Unlink Selection|Alt L", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 2, "");
598         
599         uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");        
600
601         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Pinned UVs|Shift P", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 7, "");
602         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Linked UVs|Ctrl L", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 3, "");
603
604         if(curarea->headertype==HEADERTOP) {
605                 uiBlockSetDirection(block, UI_DOWN);
606         }
607         else {
608                 uiBlockSetDirection(block, UI_TOP);
609                 uiBlockFlipOrder(block);
610         }
611
612         uiTextBoundsBlock(block, 50);
613
614         return block;
615 }
616
617 static void do_image_image_rtmappingmenu(void *arg, int event)
618 {
619         switch(event) {
620         case 0: /* UV Co-ordinates */
621                 G.sima->image->flag = BCLR(G.sima->image->flag, 4);
622                 break;
623         case 1: /* Reflection */
624                 G.sima->image->flag = BSET(G.sima->image->flag, 4);
625                 break;
626                 }
627
628         allqueue(REDRAWVIEW3D, 0);
629 }
630
631 static uiBlock *image_image_rtmappingmenu(void *arg_unused)
632 {
633         uiBlock *block;
634         short yco = 20, menuwidth = 120;
635
636         block= uiNewBlock(&curarea->uiblocks, "image_image_rtmappingmenu", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
637         uiBlockSetButmFunc(block, do_image_image_rtmappingmenu, NULL);
638         
639         if (G.sima->image->flag & IMA_REFLECT) {
640                 uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "UV Co-ordinates",        0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 0, "");
641                 uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Reflection",               0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 1, "");
642         } else {
643                 uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "UV Co-ordinates",  0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 0, "");
644                 uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Reflection",             0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 1, "");
645         }
646
647         uiBlockSetDirection(block, UI_RIGHT);
648         uiTextBoundsBlock(block, 60);
649         return block;
650 }
651
652 static void do_image_imagemenu(void *arg, int event)
653 {
654         Image *ima;
655         char name[256];
656
657         switch(event)
658         {
659         case 0: /* Open */
660                 if(G.sima->image) strcpy(name, G.sima->image->name);
661                 else strcpy(name, U.textudir);
662                 if(G.qual==LR_CTRLKEY)
663                         activate_imageselect(FILE_SPECIAL, "Open Image", name, load_space_image);
664                 else
665                         activate_fileselect(FILE_SPECIAL, "Open Image", name, load_space_image);
666                 break;
667         case 1: /* Replace */
668                 if(G.sima->image) strcpy(name, G.sima->image->name);
669                 else strcpy(name, U.textudir);
670                 
671                 if(G.qual==LR_CTRLKEY)
672                         activate_imageselect(FILE_SPECIAL, "Replace Image", name, replace_space_image);
673                 else
674                         activate_fileselect(FILE_SPECIAL, "Replace Image", name, replace_space_image);
675                 break;
676         case 2: /* Pack Image */
677                 ima = G.sima->image;
678                 if (ima) {
679                         if (ima->packedfile) {
680                                 error("Image is already packed.");
681                         } else {
682                                 if (ima->ibuf && (ima->ibuf->userflags & IB_BITMAPDIRTY)) {
683                                         error("Can't pack painted image. Save the painted image first.");
684                                 } else {
685                                         ima->packedfile = newPackedFile(ima->name);
686                                 }
687                         }
688                 }
689                 BIF_undo_push("Pack image");
690                 allqueue(REDRAWBUTSSHADING, 0);
691                 allqueue(REDRAWHEADERS, 0);
692                 break;
693         case 3: /* Unpack Image */
694                 ima = G.sima->image;
695                 if (ima) {
696                         if (ima->packedfile) {
697                                 if (G.fileflags & G_AUTOPACK) {
698                                         if (okee("Disable AutoPack?")) {
699                                                 G.fileflags &= ~G_AUTOPACK;
700                                         }
701                                 }
702                                 
703                                 if ((G.fileflags & G_AUTOPACK) == 0) {
704                                         unpackImage(ima, PF_ASK);
705                                 }
706                         } else {
707                                 error("There are no packed images to unpack");
708                         }
709                 }
710                 BIF_undo_push("Unpack image");
711                 allqueue(REDRAWBUTSSHADING, 0);
712                 allqueue(REDRAWHEADERS, 0);
713                 break;
714         case 4: /* Texture Painting */
715                 if(G.sima->flag & SI_DRAWTOOL) G.sima->flag &= ~SI_DRAWTOOL;
716                 else G.sima->flag |= SI_DRAWTOOL;
717                 break;
718         case 5: /* Save Painted Image */
719                 ima = G.sima->image;
720                 if (ima) {
721                         strcpy(name, ima->name);
722                         if (ima->ibuf) {
723                                 char str[64];
724                                 save_image_filesel_str(str);
725                                 
726                                 if(G.scene->r.scemode & R_EXTENSION) 
727                                         BKE_add_image_extension(name, G.scene->r.imtype);
728                                 
729                                 activate_fileselect(FILE_SPECIAL, str, name, save_paint);
730                         }
731                 }
732                 break;
733         case 6: /* Reload Image */
734                 ima = G.sima->image;
735                 if (ima) {
736                         if (ima->packedfile) {
737                                 PackedFile *pf;
738                                 pf = newPackedFile(ima->name);
739                                 if (pf) {
740                                         freePackedFile(ima->packedfile);
741                                         ima->packedfile = pf;
742                                 }
743                                 else
744                                         error("Image not available. Keeping packed image.");
745                         }
746                         free_image_buffers(ima);        /* force read again */
747                         ima->ok= 1;
748                         image_changed(G.sima, 0);
749                 }
750                 allqueue(REDRAWIMAGE, 0);
751                 allqueue(REDRAWVIEW3D, 0);
752                 break;
753         case 7: /* New Image */
754                 {
755                         static int width= 256, height= 256;
756                         static short uvtestgrid=0;
757                         char name[256];
758
759                         strcpy(name, "Image");
760
761                         add_numbut(0, TEX, "Name:", 0, 255, name, NULL);
762                         add_numbut(1, NUM|INT, "Width:", 1, 5000, &width, NULL);
763                         add_numbut(2, NUM|INT, "Height:", 1, 5000, &height, NULL);
764                         add_numbut(3, TOG|SHO, "UV Test Grid", 0, 0, &uvtestgrid, NULL);
765                         if (!do_clever_numbuts("New Image", 4, REDRAW))
766                                 return;
767
768                         G.sima->image= new_image(width, height, name, uvtestgrid);
769                         image_changed(G.sima, 0);
770
771                         allqueue(REDRAWIMAGE, 0);
772                         allqueue(REDRAWVIEW3D, 0);
773
774                         break;
775                 }
776         }
777 }
778
779 static uiBlock *image_imagemenu(void *arg_unused)
780 {
781         uiBlock *block;
782         short yco= 0, menuwidth=150;
783
784         block= uiNewBlock(&curarea->uiblocks, "image_imagemenu", UI_EMBOSSP, UI_HELV, curarea->headwin);
785         uiBlockSetButmFunc(block, do_image_imagemenu, NULL);
786
787         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "New...", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 7, "");
788         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Open...", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 0, "");
789         
790         if (G.sima->image) {
791                 uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Save...", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 5, "");
792                 uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Replace...", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 1, "");
793                 uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Reload", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 6, "");
794
795                 uiDefBut(block, SEPR, 0, "",        0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, ""); 
796                 
797                 if (G.sima->image->packedfile) {
798                         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Unpack Image...", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 3, "");
799                 } else {
800                         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Pack Image", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 2, "");
801                 }
802                         
803                 uiDefBut(block, SEPR, 0, "",        0, yco-=7, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
804
805                 if(G.sima->flag & SI_DRAWTOOL) {
806                         uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Texture Painting", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 4, "");
807                 } else {
808                         uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Texture Painting", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 4, "");
809                 }
810                 
811                 uiDefBut(block, SEPR, 0, "",        0, yco-=7, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
812                 
813                 uiDefIconTextBlockBut(block, image_image_rtmappingmenu, NULL, ICON_RIGHTARROW_THIN, "Realtime Texture Mapping", 0, yco-=20, 120, 19, "");
814                 // uiDefIconTextBut(block, BUTM, 1, ICON_MENU_PANEL, "Realtime Texture Animation|",             0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 7, "");
815         }
816         
817         if(curarea->headertype==HEADERTOP) {
818                 uiBlockSetDirection(block, UI_DOWN);
819         }
820         else {
821                 uiBlockSetDirection(block, UI_TOP);
822                 uiBlockFlipOrder(block);
823         }
824
825         uiTextBoundsBlock(block, 80);
826
827         return block;
828 }
829
830 static void do_image_uvs_showhidemenu(void *arg, int event)
831 {
832         switch(event) {
833         case 4: /* show hidden faces */
834                 reveal_tface_uv();
835                 break;
836         case 5: /* hide selected faces */
837                 hide_tface_uv(0);
838                 break;
839         case 6: /* hide deselected faces */
840                 hide_tface_uv(1);
841                 break;
842         }
843         allqueue(REDRAWVIEW3D, 0);
844 }
845
846 static uiBlock *image_uvs_showhidemenu(void *arg_unused)
847 {
848         uiBlock *block;
849         short yco = 20, menuwidth = 120;
850
851         block= uiNewBlock(&curarea->uiblocks, "image_uvs_showhidemenu", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
852         uiBlockSetButmFunc(block, do_image_uvs_showhidemenu, NULL);
853         
854         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Show Hidden Faces|Alt H",                0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 4, "");
855         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Hide Selected Faces|H",          0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 5, "");
856         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Hide Deselected Faces|Shift H",          0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 6, "");
857
858         uiBlockSetDirection(block, UI_RIGHT);
859         uiTextBoundsBlock(block, 60);
860         return block;
861 }
862
863 static void do_image_uvs_propfalloffmenu(void *arg, int event)
864 {
865         G.scene->prop_mode= event;
866         allqueue(REDRAWVIEW3D, 1);
867 }
868
869 static uiBlock *image_uvs_propfalloffmenu(void *arg_unused)
870 {
871         uiBlock *block;
872         short yco = 20, menuwidth = 120;
873
874         block= uiNewBlock(&curarea->uiblocks, "image_uvs_propfalloffmenu", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
875         uiBlockSetButmFunc(block, do_image_uvs_propfalloffmenu, NULL);
876         
877         if (G.scene->prop_mode==PROP_SMOOTH) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Smooth|Shift O", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, PROP_SMOOTH, "");
878         else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Smooth|Shift O",    0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, PROP_SMOOTH, "");
879         if (G.scene->prop_mode==PROP_SPHERE) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Sphere|Shift O", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, PROP_SPHERE, "");
880         else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Sphere|Shift O",    0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, PROP_SPHERE, "");
881         if (G.scene->prop_mode==PROP_ROOT) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Root|Shift O", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, PROP_ROOT, "");
882         else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Root|Shift O",      0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, PROP_ROOT, "");
883         if (G.scene->prop_mode==PROP_SHARP) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Sharp|Shift O",        0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, PROP_SHARP, "");
884         else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Sharp|Shift O", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, PROP_SHARP, "");
885         if (G.scene->prop_mode==PROP_LIN) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Linear|Shift O", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, PROP_LIN, "");
886         else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Linear|Shift O",    0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, PROP_LIN, "");
887         if (G.scene->prop_mode==PROP_CONST) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Constant|Shift O", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, PROP_CONST, "");
888         else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Constant|Shift O",  0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, PROP_CONST, "");
889                 
890         uiBlockSetDirection(block, UI_RIGHT);
891         uiTextBoundsBlock(block, 60);
892         return block;
893 }
894
895 static void do_image_uvs_transformmenu(void *arg, int event)
896 {
897         switch(event) {
898         case 0: /* Grab */
899                 initTransform(TFM_TRANSLATION, CTX_NONE);
900                 Transform();
901                 break;
902         case 1: /* Rotate */
903                 initTransform(TFM_ROTATION, CTX_NONE);
904                 Transform();
905                 break;
906         case 2: /* Scale */
907                 initTransform(TFM_RESIZE, CTX_NONE);
908                 Transform();
909                 break;
910         }
911 }
912
913 static uiBlock *image_uvs_transformmenu(void *arg_unused)
914 {
915         uiBlock *block;
916         short yco = 20, menuwidth = 120;
917
918         block= uiNewBlock(&curarea->uiblocks, "image_uvs_transformmenu", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
919         uiBlockSetButmFunc(block, do_image_uvs_transformmenu, NULL);
920         
921         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Grab/Move|G", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 0, "");
922         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Rotate|R", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 1, "");
923         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Scale|S", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 2, "");
924
925         uiBlockSetDirection(block, UI_RIGHT);
926         uiTextBoundsBlock(block, 60);
927         return block;
928 }
929
930 static void do_image_uvs_mirrormenu(void *arg, int event)
931 {
932         switch(event) {
933         case 0: /* X axis */
934                 mirror_tface_uv('x');
935                 break;
936         case 1: /* Y axis */
937                 mirror_tface_uv('y');
938                 break;
939         }
940         
941         BIF_undo_push("Mirror UV");
942 }
943
944 static uiBlock *image_uvs_mirrormenu(void *arg_unused)
945 {
946         uiBlock *block;
947         short yco = 20, menuwidth = 120;
948
949         block= uiNewBlock(&curarea->uiblocks, "image_uvs_mirrormenu", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
950         uiBlockSetButmFunc(block, do_image_uvs_mirrormenu, NULL);
951         
952         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "X Axis|M, 1", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 0, "");
953         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Y Axis|M, 2", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 1, "");
954
955         uiBlockSetDirection(block, UI_RIGHT);
956         uiTextBoundsBlock(block, 60);
957         return block;
958 }
959
960 static void do_image_uvs_weldalignmenu(void *arg, int event)
961 {
962         switch(event) {
963         case 0: /* Weld */
964                 weld_align_tface_uv('w');
965                 break;
966         case 1: /* Align X */
967                 weld_align_tface_uv('x');
968                 break;
969         case 2: /* Align Y */
970                 weld_align_tface_uv('y');
971                 break;
972         }
973         
974         if(event==0) BIF_undo_push("Weld UV");
975         else if(event==1 || event==2) BIF_undo_push("Align UV");
976 }
977
978 static uiBlock *image_uvs_weldalignmenu(void *arg_unused)
979 {
980         uiBlock *block;
981         short yco = 20, menuwidth = 120;
982
983         block= uiNewBlock(&curarea->uiblocks, "image_uvs_weldalignmenu", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
984         uiBlockSetButmFunc(block, do_image_uvs_weldalignmenu, NULL);
985         
986         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Weld|W, 1", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 0, "");
987         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Align X|W, 2", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 1, "");
988         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Align Y|W, 3", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 2, "");
989
990         uiBlockSetDirection(block, UI_RIGHT);
991         uiTextBoundsBlock(block, 60);
992         return block;
993 }
994
995 static void do_image_uvsmenu(void *arg, int event)
996 {
997         /* events >=20 are registered bpython scripts */
998         if (event >= 20) BPY_menu_do_python(PYMENU_UV, event - 20);
999
1000         else switch(event)
1001         {
1002         case 1: /* UVs Constrained Rectangular */
1003                 if(G.sima->flag & SI_BE_SQUARE) G.sima->flag &= ~SI_BE_SQUARE;
1004                 else G.sima->flag |= SI_BE_SQUARE;
1005                 break;
1006         case 2: /* UVs Clipped to Image Size */
1007                 if(G.sima->flag & SI_CLIP_UV) G.sima->flag &= ~SI_CLIP_UV;
1008                 else G.sima->flag |= SI_CLIP_UV;
1009                 break;
1010         case 3: /* Limit Stitch UVs */
1011                 stitch_uv_tface(1);
1012                 break;
1013         case 4: /* Stitch UVs */
1014                 stitch_uv_tface(0);
1015                 break;
1016         case 5: /* Proportional Edit (toggle) */
1017                 if(G.scene->proportional)
1018                         G.scene->proportional= 0;
1019                 else
1020                         G.scene->proportional= 1;
1021                 break;
1022         case 7: /* UVs Snap to Pixel */
1023                 G.sima->flag ^= SI_PIXELSNAP;
1024                 break;
1025     case 8:
1026                 pin_tface_uv(1);
1027                 break;
1028     case 9:
1029                 pin_tface_uv(0);
1030                 break;
1031     case 10:
1032                 unwrap_lscm(0);
1033                 break;
1034         case 11:
1035                 if(G.sima->flag & SI_LIVE_UNWRAP) G.sima->flag &= ~SI_LIVE_UNWRAP;
1036                 else G.sima->flag |= SI_LIVE_UNWRAP;
1037                 break;
1038         case 12:
1039                 minimize_stretch_tface_uv();
1040                 break;
1041         }
1042 }
1043
1044 static uiBlock *image_uvsmenu(void *arg_unused)
1045 {
1046         uiBlock *block;
1047         short yco= 0, menuwidth=120;
1048         BPyMenu *pym;
1049         int i = 0;
1050
1051         block= uiNewBlock(&curarea->uiblocks, "image_uvsmenu", UI_EMBOSSP, UI_HELV, curarea->headwin);
1052         uiBlockSetButmFunc(block, do_image_uvsmenu, NULL);
1053
1054         // uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Transform Properties...|N", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 0, "");
1055         // uiDefBut(block, SEPR, 0, "",        0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
1056         if(G.sima->flag & SI_PIXELSNAP) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Snap to Pixels|", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 7, "");
1057         else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Snap to Pixels|", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 7, "");
1058
1059         if(G.sima->flag & SI_BE_SQUARE) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Quads Constrained Rectangular|", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 1, "");
1060         else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Quads Constrained Rectangular|", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 1, "");
1061         
1062         if(G.sima->flag & SI_CLIP_UV) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Layout Clipped to Image Size|", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 2, "");
1063         else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Layout Clipped to Image Size|", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 2, "");
1064
1065         uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");        
1066
1067         if(G.sima->flag & SI_LIVE_UNWRAP) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Live Unwrap Transform", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 11, "");
1068         else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Live Unwrap Transform", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 11, "");
1069         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Unwrap|E", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 10, "");
1070         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Unpin|Alt P", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 9, "");
1071         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Pin|P", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 8, "");
1072
1073         uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");        
1074
1075         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Minimize Stretch|Ctrl V", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 12, "");
1076         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Limit Stitch...|Shift V", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 3, "");
1077         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Stitch|V", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 4, "");
1078         uiDefIconTextBlockBut(block, image_uvs_transformmenu, NULL, ICON_RIGHTARROW_THIN, "Transform", 0, yco-=20, 120, 19, "");
1079
1080         uiDefBut(block, SEPR, 0, "",                            0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
1081         
1082         uiDefIconTextBlockBut(block, image_uvs_mirrormenu, NULL, ICON_RIGHTARROW_THIN, "Mirror", 0, yco-=20, 120, 19, "");
1083         uiDefIconTextBlockBut(block, image_uvs_weldalignmenu, NULL, ICON_RIGHTARROW_THIN, "Weld/Align", 0, yco-=20, 120, 19, "");
1084         
1085         uiDefBut(block, SEPR, 0, "",                            0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
1086
1087         if(G.scene->proportional)
1088                 uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Proportional Editing|O", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 5, "");
1089         else
1090                 uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Proportional Editing|O", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 5, "");
1091
1092         uiDefIconTextBlockBut(block, image_uvs_propfalloffmenu, NULL, ICON_RIGHTARROW_THIN, "Proportional Falloff", 0, yco-=20, 120, 19, "");
1093
1094         uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");        
1095         
1096         /* note that we acount for the 3 previous entries with i+3: */
1097         for (pym = BPyMenuTable[PYMENU_UV]; pym; pym = pym->next, i++) {
1098
1099                 uiDefIconTextBut(block, BUTM, 1, ICON_PYTHON, pym->name, 0, yco-=20, menuwidth, 19, 
1100                                  NULL, 0.0, 0.0, 1, i+20, 
1101                                  pym->tooltip?pym->tooltip:pym->filename);
1102         }
1103
1104         uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");        
1105
1106         uiDefIconTextBlockBut(block, image_uvs_showhidemenu, NULL, ICON_RIGHTARROW_THIN, "Show/Hide Faces", 0, yco-=20, menuwidth, 19, "");
1107
1108         if(curarea->headertype==HEADERTOP) {
1109                 uiBlockSetDirection(block, UI_DOWN);
1110         }
1111         else {
1112                 uiBlockSetDirection(block, UI_TOP);
1113                 uiBlockFlipOrder(block);
1114         }
1115
1116         uiTextBoundsBlock(block, 50);
1117
1118         return block;
1119 }
1120
1121 void image_buttons(void)
1122 {
1123         uiBlock *block;
1124         short xco, xmax;
1125         char naam[256];
1126         /* This should not be a static var */
1127         static int headerbuttons_packdummy;
1128
1129         headerbuttons_packdummy = 0;
1130                 
1131         sprintf(naam, "header %d", curarea->headwin);
1132         block= uiNewBlock(&curarea->uiblocks, naam, UI_EMBOSS, UI_HELV, curarea->headwin);
1133
1134         if(area_is_active_area(curarea)) uiBlockSetCol(block, TH_HEADER);
1135         else uiBlockSetCol(block, TH_HEADERDESEL);
1136
1137         what_image(G.sima);
1138
1139         curarea->butspacetype= SPACE_IMAGE;
1140
1141         xco = 8;
1142         uiDefIconTextButC(block, ICONTEXTROW,B_NEWSPACE, ICON_VIEW3D, windowtype_pup(), xco,0,XIC+10,YIC, &(curarea->butspacetype), 1.0, SPACEICONMAX, 0, 0, "Current Window Type. Click for menu of available types.");
1143         xco+= XIC+14;
1144
1145         uiBlockSetEmboss(block, UI_EMBOSSN);
1146         if(curarea->flag & HEADER_NO_PULLDOWN) {
1147                 uiDefIconButBitS(block, TOG, HEADER_NO_PULLDOWN, B_FLIPINFOMENU, ICON_DISCLOSURE_TRI_RIGHT,
1148                                 xco,2,XIC,YIC-2,
1149                                 &(curarea->flag), 0, 0, 0, 0, "Show pulldown menus");
1150         } else {
1151                 uiDefIconButBitS(block, TOG, HEADER_NO_PULLDOWN, B_FLIPINFOMENU, ICON_DISCLOSURE_TRI_DOWN,
1152                                 xco,2,XIC,YIC-2,
1153                                 &(curarea->flag), 0, 0, 0, 0, "Hide pulldown menus");
1154         }
1155         uiBlockSetEmboss(block, UI_EMBOSS);
1156         xco+=XIC;
1157
1158         if((curarea->flag & HEADER_NO_PULLDOWN)==0) {
1159                 /* pull down menus */
1160                 uiBlockSetEmboss(block, UI_EMBOSSP);
1161         
1162                 xmax= GetButStringLength("View");
1163                 uiDefPulldownBut(block, image_viewmenu, NULL, "View", xco, -2, xmax-3, 24, "");
1164                 xco+= xmax;
1165                 
1166                 xmax= GetButStringLength("Select");
1167                 uiDefPulldownBut(block, image_selectmenu, NULL, "Select", xco, -2, xmax-3, 24, "");
1168         
1169                 xco+= xmax;
1170                 
1171                 xmax= GetButStringLength("Image");
1172                 uiDefPulldownBut(block, image_imagemenu, NULL, "Image", xco, -2, xmax-3, 24, "");
1173                 xco+= xmax;
1174                 
1175                 xmax= GetButStringLength("UVs");
1176                 uiDefPulldownBut(block, image_uvsmenu, NULL, "UVs", xco, -2, xmax-3, 24, "");
1177                 xco+= xmax;
1178         }
1179         
1180         /* other buttons: */
1181         uiBlockSetEmboss(block, UI_EMBOSS);
1182
1183         xco= std_libbuttons(block, xco, 0, 0, NULL, B_SIMABROWSE, ID_IM, 0, (ID *)G.sima->image, 0, &(G.sima->imanr), 0, 0, B_IMAGEDELETE, 0, 0);
1184
1185         if (G.sima->image) {
1186                 xco+= 8;
1187         
1188                 if (G.sima->image->packedfile) {
1189                         headerbuttons_packdummy = 1;
1190                 }
1191                 uiDefIconButBitI(block, TOG, 1, B_SIMAPACKIMA, ICON_PACKAGE,    xco,0,XIC,YIC, &headerbuttons_packdummy, 0, 0, 0, 0, "Pack/Unpack this image");
1192                 xco+= XIC+8;
1193
1194                 uiDefIconButBitS(block, TOG, SI_DRAWTOOL, B_SIMAGEPAINTTOOL, ICON_TPAINT_HLT, xco,0,XIC,YIC, &G.sima->flag, 0, 0, 0, 0, "Enables painting textures on the image with left mouse button");
1195                 xco+= XIC+8;
1196
1197                 uiBlockBeginAlign(block);
1198                 uiDefIconButBitS(block, TOG, SI_USE_ALPHA, B_SIMA_USE_ALPHA, ICON_TRANSP_HLT, xco,0,XIC,YIC, &G.sima->flag, 0, 0, 0, 0, "Draws image with alpha");
1199                 xco+= XIC;
1200                 uiDefIconButBitS(block, TOG, SI_SHOW_ALPHA, B_SIMA_SHOW_ALPHA, ICON_DOT, xco,0,XIC,YIC, &G.sima->flag, 0, 0, 0, 0, "Draws only alpha");
1201                 xco+= XIC;
1202                 if(G.sima->image->ibuf) {
1203                         if(G.sima->image->ibuf->zbuf || G.sima->image->ibuf->zbuf_float) {
1204                                 uiDefIconButBitS(block, TOG, SI_SHOW_ZBUF, B_SIMA_SHOW_ZBUF, ICON_SOLID, xco,0,XIC,YIC, &G.sima->flag, 0, 0, 0, 0, "Draws zbuffer values");
1205                                 xco+= XIC;
1206                         }
1207                         else G.sima->flag &= ~SI_SHOW_ZBUF;     /* no confusing display for non-zbuf images */
1208                 }               
1209                 uiBlockEndAlign(block);
1210                 xco+= 8;
1211         }
1212
1213         /* draw LOCK */
1214         uiDefIconButS(block, ICONTOG, 0, ICON_UNLOCKED, xco,0,XIC,YIC, &(G.sima->lock), 0, 0, 0, 0, "Updates other affected window spaces automatically to reflect changes in real time");
1215
1216         /* Always do this last */
1217         curarea->headbutlen= xco+2*XIC;
1218         
1219         uiDrawBlock(block);
1220 }
1221