Tuesday merger of bf-blender into orange branch.
[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 (BIF_write_ibuf(ima->ibuf, str)) {
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                                 activate_fileselect(FILE_SPECIAL, "Save in own image type", name, save_paint);
332                         }
333                 }
334                 break;
335         }
336 }
337
338 static void do_image_view_viewnavmenu(void *arg, int event)
339 {
340         switch(event) {
341         case 1: /* Zoom In */
342                 image_viewzoom(PADPLUSKEY, 0);
343                 break;
344         case 2: /* Zoom Out */
345                 image_viewzoom(PADMINUS, 0);
346                 break;
347         case 3: /* Zoom 8:1 */
348                 image_viewzoom(PAD8, 0);
349                 break;
350         case 4: /* Zoom 4:1 */
351                 image_viewzoom(PAD4, 0);
352                 break;
353         case 5: /* Zoom 2:1 */
354                 image_viewzoom(PAD2, 0);
355                 break;
356         case 6: /* Zoom 1:1 */
357                 image_viewzoom(PAD1, 0);
358                 break;
359         case 7: /* Zoom 1:2 */
360                 image_viewzoom(PAD2, 1);
361                 break;
362         case 8: /* Zoom 1:4 */
363                 image_viewzoom(PAD4, 1);
364                 break;
365         case 9: /* Zoom 1:8 */
366                 image_viewzoom(PAD8, 1);
367                 break;
368         }
369         allqueue(REDRAWIMAGE, 0);
370 }
371
372 static uiBlock *image_view_viewnavmenu(void *arg_unused)
373 {
374 /*              static short tog=0; */
375         uiBlock *block;
376         short yco= 0, menuwidth=120;
377         
378         block= uiNewBlock(&curarea->uiblocks, "image_view_viewnavmenu", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
379         uiBlockSetButmFunc(block, do_image_view_viewnavmenu, NULL);
380         
381         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Zoom In|NumPad +", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 1, "");
382         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Zoom Out|NumPad -",      0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 2, "");
383
384         uiDefBut(block, SEPR, 0, "",        0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
385
386         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Zoom 1:8", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 3, "");
387         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Zoom 1:4", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 4, "");
388         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Zoom 1:2", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 5, "");
389         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Zoom 1:1", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 6, "");
390         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Zoom 2:1", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 7, "");
391         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Zoom 4:1", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 8, "");
392         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Zoom 8:1", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 9, "");
393
394         uiBlockSetDirection(block, UI_RIGHT);
395         uiTextBoundsBlock(block, 50);
396         return block;
397 }
398
399 static void do_image_viewmenu(void *arg, int event)
400 {
401
402         switch(event) {
403         case 0: /* Update Automatically */
404                 if(G.sima->lock) G.sima->lock = 0;
405                 else G.sima->lock = 1;
406                 break;
407         case 1: /* View All */
408                 do_image_buttons(B_SIMAGEHOME);
409                 break;
410         case 2: /* Maximize Window */
411                 /* using event B_FULL */
412                 break;
413         case 5: /* Draw Shadow Mesh */
414                 if(G.sima->flag & SI_DRAWSHADOW)
415                         G.sima->flag &= ~SI_DRAWSHADOW;
416                 else
417                         G.sima->flag |= SI_DRAWSHADOW;
418                 allqueue(REDRAWIMAGE, 0);
419                 break;
420         case 6: /* Draw Faces */
421                 if(G.f & G_DRAWFACES)
422                         G.f &= ~G_DRAWFACES;
423                 else
424                         G.f |= G_DRAWFACES;
425                 allqueue(REDRAWIMAGE, 0);
426                 break;
427         case 7: /* Properties  Panel */
428                 add_blockhandler(curarea, IMAGE_HANDLER_PROPERTIES, UI_PNL_UNSTOW);
429                 break;
430         case 8: /* Paint Panel... */
431                 add_blockhandler(curarea, IMAGE_HANDLER_PAINT, UI_PNL_UNSTOW);
432                 break;
433         case 9:
434                 image_viewcentre();
435         case 10: /* Display Normalized Coordinates */
436                 G.sima->flag ^= SI_COORDFLOATS;
437                 allqueue(REDRAWIMAGE, 0);
438                 break;
439         case 11: /* Curves Panel... */
440                 add_blockhandler(curarea, IMAGE_HANDLER_CURVES, UI_PNL_UNSTOW);
441                 break;
442         }
443         allqueue(REDRAWVIEW3D, 0);
444 }
445
446 static uiBlock *image_viewmenu(void *arg_unused)
447 {
448 /*      static short tog=0; */
449         uiBlock *block;
450         short yco= 0, menuwidth=120;
451         
452         block= uiNewBlock(&curarea->uiblocks, "image_viewmenu", UI_EMBOSSP, UI_HELV, curarea->headwin);
453         uiBlockSetButmFunc(block, do_image_viewmenu, NULL);
454
455         uiDefIconTextBut(block, BUTM, 1, ICON_MENU_PANEL, "Show Properties...", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 7, "");
456         uiDefIconTextBut(block, BUTM, 1, ICON_MENU_PANEL, "Show Paint Tool...|C",       0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 8, "");
457         uiDefIconTextBut(block, BUTM, 1, ICON_MENU_PANEL, "Show Curves Tool...",        0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 11, "");
458
459         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, "");
460         else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Display Normalized Coordinates|", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 10, "");
461         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, "");
462         else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Draw Faces|", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 6, "");
463         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, "");
464         else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Draw Shadow Mesh|", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 5, "");
465
466         uiDefBut(block, SEPR, 0, "",        0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
467         uiDefIconTextBlockBut(block, image_view_viewnavmenu, NULL, ICON_RIGHTARROW_THIN, "View Navigation", 0, yco-=20, 120, 19, "");
468
469         if(G.sima->lock) {
470                 uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Update Automatically|", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 0, "");
471         } else {
472                 uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Update Automatically|", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 0, "");
473         } 
474
475         uiDefBut(block, SEPR, 0, "",                                    0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
476         
477         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "View Selected|NumPad .",                 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 9, "");
478         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "View All|Home", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 1, "");
479                 
480         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, "");
481         else uiDefIconTextBut(block, BUTM, B_FULL, ICON_BLANK1, "Tile Window|Ctrl DownArrow", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 2, "");
482         
483         if(curarea->headertype==HEADERTOP) {
484                 uiBlockSetDirection(block, UI_DOWN);
485         }
486         else {
487                 uiBlockSetDirection(block, UI_TOP);
488                 uiBlockFlipOrder(block);
489         }
490
491         uiTextBoundsBlock(block, 50);
492         
493         return block;
494 }
495
496 static void do_image_selectmenu(void *arg, int event)
497 {
498         switch(event)
499         {
500         case 0: /* Border Select */
501                 borderselect_sima(UV_SELECT_ALL);
502                 break;
503         case 8: /* Border Select Pinned */
504                 borderselect_sima(UV_SELECT_PINNED);
505                 break;
506         case 1: /* Select/Deselect All */
507                 select_swap_tface_uv();
508                 break;
509         case 2: /* Unlink Selection */
510                 unlink_selection();
511                 break;
512         case 3: /* Linked UVs */
513                 select_linked_tface_uv(2);
514                 break;
515         case 4: /* Toggle Local UVs Stick to Vertex in Mesh */
516                 if(G.sima->flag & SI_LOCALSTICKY)
517                         G.sima->flag &= ~SI_LOCALSTICKY;
518                 else {
519                         G.sima->flag |= SI_LOCALSTICKY;
520                         G.sima->flag &= ~SI_STICKYUVS;
521                 }
522                 allqueue(REDRAWIMAGE, 0);
523                 break;  
524         case 5: /* Toggle UVs Stick to Vertex in Mesh */
525                 if(G.sima->flag & SI_STICKYUVS)
526                         G.sima->flag &= ~SI_STICKYUVS;
527                 else {
528                         G.sima->flag |= SI_STICKYUVS;
529                         G.sima->flag &= ~SI_LOCALSTICKY;
530                 }
531                 allqueue(REDRAWIMAGE, 0);
532                 break;  
533         case 6: /* Toggle Active Face Select */
534                 if(G.sima->flag & SI_SELACTFACE)
535                         G.sima->flag &= ~SI_SELACTFACE;
536                 else
537                         G.sima->flag |= SI_SELACTFACE;
538                 allqueue(REDRAWIMAGE, 0);
539                 break;
540         case 7: /* Pinned UVs */
541                 select_pinned_tface_uv();
542                 break;
543         }
544 }
545
546 static uiBlock *image_selectmenu(void *arg_unused)
547 {
548         uiBlock *block;
549         short yco= 0, menuwidth=120;
550
551         block= uiNewBlock(&curarea->uiblocks, "image_selectmenu", UI_EMBOSSP, UI_HELV, curarea->headwin);
552         uiBlockSetButmFunc(block, do_image_selectmenu, NULL);
553
554         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, "");
555         else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Active Face Select|C", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 6, "");
556
557         uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");        
558
559         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, "");
560         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, "");
561
562         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, "");
563         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, "");
564
565         uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
566
567         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Border Select|B", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 0, "");
568         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Border Select Pinned|Shift B", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 8, "");
569
570         uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");        
571
572         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Select/Deselect All|A", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 1, "");
573
574         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Unlink Selection|Alt L", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 2, "");
575         
576         uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");        
577
578         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Pinned UVs|Shift P", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 7, "");
579         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Linked UVs|Ctrl L", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 3, "");
580
581         if(curarea->headertype==HEADERTOP) {
582                 uiBlockSetDirection(block, UI_DOWN);
583         }
584         else {
585                 uiBlockSetDirection(block, UI_TOP);
586                 uiBlockFlipOrder(block);
587         }
588
589         uiTextBoundsBlock(block, 50);
590
591         return block;
592 }
593
594 static void do_image_image_rtmappingmenu(void *arg, int event)
595 {
596         switch(event) {
597         case 0: /* UV Co-ordinates */
598                 G.sima->image->flag = BCLR(G.sima->image->flag, 4);
599                 break;
600         case 1: /* Reflection */
601                 G.sima->image->flag = BSET(G.sima->image->flag, 4);
602                 break;
603                 }
604
605         allqueue(REDRAWVIEW3D, 0);
606 }
607
608 static uiBlock *image_image_rtmappingmenu(void *arg_unused)
609 {
610         uiBlock *block;
611         short yco = 20, menuwidth = 120;
612
613         block= uiNewBlock(&curarea->uiblocks, "image_image_rtmappingmenu", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
614         uiBlockSetButmFunc(block, do_image_image_rtmappingmenu, NULL);
615         
616         if (G.sima->image->flag & IMA_REFLECT) {
617                 uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "UV Co-ordinates",        0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 0, "");
618                 uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Reflection",               0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 1, "");
619         } else {
620                 uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "UV Co-ordinates",  0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 0, "");
621                 uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Reflection",             0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 1, "");
622         }
623
624         uiBlockSetDirection(block, UI_RIGHT);
625         uiTextBoundsBlock(block, 60);
626         return block;
627 }
628
629 static void do_image_imagemenu(void *arg, int event)
630 {
631         Image *ima;
632         char name[256];
633
634         switch(event)
635         {
636         case 0: /* Open */
637                 if(G.sima->image) strcpy(name, G.sima->image->name);
638                 else strcpy(name, U.textudir);
639                 if(G.qual==LR_CTRLKEY)
640                         activate_imageselect(FILE_SPECIAL, "Open Image", name, load_space_image);
641                 else
642                         activate_fileselect(FILE_SPECIAL, "Open Image", name, load_space_image);
643                 break;
644         case 1: /* Replace */
645                 if(G.sima->image) strcpy(name, G.sima->image->name);
646                 else strcpy(name, U.textudir);
647                 
648                 if(G.qual==LR_CTRLKEY)
649                         activate_imageselect(FILE_SPECIAL, "Replace Image", name, replace_space_image);
650                 else
651                         activate_fileselect(FILE_SPECIAL, "Replace Image", name, replace_space_image);
652                 break;
653         case 2: /* Pack Image */
654                 ima = G.sima->image;
655                 if (ima) {
656                         if (ima->packedfile) {
657                                 error("Image is already packed.");
658                         } else {
659                                 if (ima->ibuf && (ima->ibuf->userflags & IB_BITMAPDIRTY)) {
660                                         error("Can't pack painted image. Save the painted image first.");
661                                 } else {
662                                         ima->packedfile = newPackedFile(ima->name);
663                                 }
664                         }
665                 }
666                 BIF_undo_push("Pack image");
667                 allqueue(REDRAWBUTSSHADING, 0);
668                 allqueue(REDRAWHEADERS, 0);
669                 break;
670         case 3: /* Unpack Image */
671                 ima = G.sima->image;
672                 if (ima) {
673                         if (ima->packedfile) {
674                                 if (G.fileflags & G_AUTOPACK) {
675                                         if (okee("Disable AutoPack?")) {
676                                                 G.fileflags &= ~G_AUTOPACK;
677                                         }
678                                 }
679                                 
680                                 if ((G.fileflags & G_AUTOPACK) == 0) {
681                                         unpackImage(ima, PF_ASK);
682                                 }
683                         } else {
684                                 error("There are no packed images to unpack");
685                         }
686                 }
687                 BIF_undo_push("Unpack image");
688                 allqueue(REDRAWBUTSSHADING, 0);
689                 allqueue(REDRAWHEADERS, 0);
690                 break;
691         case 4: /* Texture Painting */
692                 if(G.sima->flag & SI_DRAWTOOL) G.sima->flag &= ~SI_DRAWTOOL;
693                 else G.sima->flag |= SI_DRAWTOOL;
694                 break;
695         case 5: /* Save Painted Image */
696                 ima = G.sima->image;
697                 if (ima) {
698                         strcpy(name, ima->name);
699                         if (ima->ibuf) {
700                                 activate_fileselect(FILE_SPECIAL, "Save in own image type", name, save_paint);
701                         }
702                 }
703                 break;
704         case 6: /* Reload Image */
705                 ima = G.sima->image;
706                 if (ima) {
707                         if (ima->packedfile) {
708                                 PackedFile *pf;
709                                 pf = newPackedFile(ima->name);
710                                 if (pf) {
711                                         freePackedFile(ima->packedfile);
712                                         ima->packedfile = pf;
713                                 }
714                                 else
715                                         error("Image not available. Keeping packed image.");
716                         }
717                         free_image_buffers(ima);        /* force read again */
718                         ima->ok= 1;
719                         image_changed(G.sima, 0);
720                 }
721                 allqueue(REDRAWIMAGE, 0);
722                 allqueue(REDRAWVIEW3D, 0);
723                 break;
724         case 7: /* New Image */
725                 {
726                         static int width= 256, height= 256;
727                         static short uvtestgrid=0;
728                         char name[256];
729
730                         strcpy(name, "Image");
731
732                         add_numbut(0, TEX, "Name:", 0, 255, name, NULL);
733                         add_numbut(1, NUM|INT, "Width:", 1, 5000, &width, NULL);
734                         add_numbut(2, NUM|INT, "Height:", 1, 5000, &height, NULL);
735                         add_numbut(3, TOG|SHO, "UV Test Grid", 0, 0, &uvtestgrid, NULL);
736                         if (!do_clever_numbuts("New Image", 4, REDRAW))
737                                 return;
738
739                         G.sima->image= new_image(width, height, name, uvtestgrid);
740                         image_changed(G.sima, 0);
741
742                         allqueue(REDRAWIMAGE, 0);
743                         allqueue(REDRAWVIEW3D, 0);
744
745                         break;
746                 }
747         }
748 }
749
750 static uiBlock *image_imagemenu(void *arg_unused)
751 {
752         uiBlock *block;
753         short yco= 0, menuwidth=150;
754
755         block= uiNewBlock(&curarea->uiblocks, "image_imagemenu", UI_EMBOSSP, UI_HELV, curarea->headwin);
756         uiBlockSetButmFunc(block, do_image_imagemenu, NULL);
757
758         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "New...", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 7, "");
759         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Open...", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 0, "");
760         
761         if (G.sima->image) {
762                 uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Save...", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 5, "");
763                 uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Replace...", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 1, "");
764                 uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Reload", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 6, "");
765
766                 uiDefBut(block, SEPR, 0, "",        0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, ""); 
767                 
768                 if (G.sima->image->packedfile) {
769                         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Unpack Image...", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 3, "");
770                 } else {
771                         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Pack Image", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 2, "");
772                 }
773                         
774                 uiDefBut(block, SEPR, 0, "",        0, yco-=7, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
775
776                 if(G.sima->flag & SI_DRAWTOOL) {
777                         uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Texture Painting", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 4, "");
778                 } else {
779                         uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Texture Painting", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 4, "");
780                 }
781                 
782                 uiDefBut(block, SEPR, 0, "",        0, yco-=7, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
783                 
784                 uiDefIconTextBlockBut(block, image_image_rtmappingmenu, NULL, ICON_RIGHTARROW_THIN, "Realtime Texture Mapping", 0, yco-=20, 120, 19, "");
785                 // uiDefIconTextBut(block, BUTM, 1, ICON_MENU_PANEL, "Realtime Texture Animation|",             0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 7, "");
786         }
787         
788         if(curarea->headertype==HEADERTOP) {
789                 uiBlockSetDirection(block, UI_DOWN);
790         }
791         else {
792                 uiBlockSetDirection(block, UI_TOP);
793                 uiBlockFlipOrder(block);
794         }
795
796         uiTextBoundsBlock(block, 80);
797
798         return block;
799 }
800
801 static void do_image_uvs_showhidemenu(void *arg, int event)
802 {
803         switch(event) {
804         case 4: /* show hidden faces */
805                 reveal_tface_uv();
806                 break;
807         case 5: /* hide selected faces */
808                 hide_tface_uv(0);
809                 break;
810         case 6: /* hide deselected faces */
811                 hide_tface_uv(1);
812                 break;
813         }
814         allqueue(REDRAWVIEW3D, 0);
815 }
816
817 static uiBlock *image_uvs_showhidemenu(void *arg_unused)
818 {
819         uiBlock *block;
820         short yco = 20, menuwidth = 120;
821
822         block= uiNewBlock(&curarea->uiblocks, "image_uvs_showhidemenu", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
823         uiBlockSetButmFunc(block, do_image_uvs_showhidemenu, NULL);
824         
825         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Show Hidden Faces|Alt H",                0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 4, "");
826         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Hide Selected Faces|H",          0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 5, "");
827         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Hide Deselected Faces|Shift H",          0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 6, "");
828
829         uiBlockSetDirection(block, UI_RIGHT);
830         uiTextBoundsBlock(block, 60);
831         return block;
832 }
833
834 static void do_image_uvs_propfalloffmenu(void *arg, int event)
835 {
836         G.scene->prop_mode= event;
837         allqueue(REDRAWVIEW3D, 1);
838 }
839
840 static uiBlock *image_uvs_propfalloffmenu(void *arg_unused)
841 {
842         uiBlock *block;
843         short yco = 20, menuwidth = 120;
844
845         block= uiNewBlock(&curarea->uiblocks, "image_uvs_propfalloffmenu", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
846         uiBlockSetButmFunc(block, do_image_uvs_propfalloffmenu, NULL);
847         
848         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, "");
849         else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Smooth|Shift O",    0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, PROP_SMOOTH, "");
850         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, "");
851         else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Sphere|Shift O",    0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, PROP_SPHERE, "");
852         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, "");
853         else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Root|Shift O",      0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, PROP_ROOT, "");
854         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, "");
855         else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Sharp|Shift O", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, PROP_SHARP, "");
856         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, "");
857         else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Linear|Shift O",    0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, PROP_LIN, "");
858         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, "");
859         else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Constant|Shift O",  0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, PROP_CONST, "");
860                 
861         uiBlockSetDirection(block, UI_RIGHT);
862         uiTextBoundsBlock(block, 60);
863         return block;
864 }
865
866 static void do_image_uvs_transformmenu(void *arg, int event)
867 {
868         switch(event) {
869         case 0: /* Grab */
870                 initTransform(TFM_TRANSLATION, CTX_NONE);
871                 Transform();
872                 break;
873         case 1: /* Rotate */
874                 initTransform(TFM_ROTATION, CTX_NONE);
875                 Transform();
876                 break;
877         case 2: /* Scale */
878                 initTransform(TFM_RESIZE, CTX_NONE);
879                 Transform();
880                 break;
881         }
882 }
883
884 static uiBlock *image_uvs_transformmenu(void *arg_unused)
885 {
886         uiBlock *block;
887         short yco = 20, menuwidth = 120;
888
889         block= uiNewBlock(&curarea->uiblocks, "image_uvs_transformmenu", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
890         uiBlockSetButmFunc(block, do_image_uvs_transformmenu, NULL);
891         
892         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Grab/Move|G", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 0, "");
893         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Rotate|R", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 1, "");
894         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Scale|S", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 2, "");
895
896         uiBlockSetDirection(block, UI_RIGHT);
897         uiTextBoundsBlock(block, 60);
898         return block;
899 }
900
901 static void do_image_uvs_mirrormenu(void *arg, int event)
902 {
903         switch(event) {
904         case 0: /* X axis */
905                 mirror_tface_uv('x');
906                 break;
907         case 1: /* Y axis */
908                 mirror_tface_uv('y');
909                 break;
910         }
911         
912         BIF_undo_push("Mirror UV");
913 }
914
915 static uiBlock *image_uvs_mirrormenu(void *arg_unused)
916 {
917         uiBlock *block;
918         short yco = 20, menuwidth = 120;
919
920         block= uiNewBlock(&curarea->uiblocks, "image_uvs_mirrormenu", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
921         uiBlockSetButmFunc(block, do_image_uvs_mirrormenu, NULL);
922         
923         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "X Axis|M, 1", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 0, "");
924         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Y Axis|M, 2", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 1, "");
925
926         uiBlockSetDirection(block, UI_RIGHT);
927         uiTextBoundsBlock(block, 60);
928         return block;
929 }
930
931 static void do_image_uvs_weldalignmenu(void *arg, int event)
932 {
933         switch(event) {
934         case 0: /* Weld */
935                 weld_align_tface_uv('w');
936                 break;
937         case 1: /* Align X */
938                 weld_align_tface_uv('x');
939                 break;
940         case 2: /* Align Y */
941                 weld_align_tface_uv('y');
942                 break;
943         }
944         
945         if(event==0) BIF_undo_push("Weld UV");
946         else if(event==1 || event==2) BIF_undo_push("Align UV");
947 }
948
949 static uiBlock *image_uvs_weldalignmenu(void *arg_unused)
950 {
951         uiBlock *block;
952         short yco = 20, menuwidth = 120;
953
954         block= uiNewBlock(&curarea->uiblocks, "image_uvs_weldalignmenu", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
955         uiBlockSetButmFunc(block, do_image_uvs_weldalignmenu, NULL);
956         
957         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Weld|W, 1", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 0, "");
958         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Align X|W, 2", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 1, "");
959         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Align Y|W, 3", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 2, "");
960
961         uiBlockSetDirection(block, UI_RIGHT);
962         uiTextBoundsBlock(block, 60);
963         return block;
964 }
965
966 static void do_image_uvsmenu(void *arg, int event)
967 {
968         /* events >=20 are registered bpython scripts */
969         if (event >= 20) BPY_menu_do_python(PYMENU_UV, event - 20);
970
971         else switch(event)
972         {
973         case 1: /* UVs Constrained Rectangular */
974                 if(G.sima->flag & SI_BE_SQUARE) G.sima->flag &= ~SI_BE_SQUARE;
975                 else G.sima->flag |= SI_BE_SQUARE;
976                 break;
977         case 2: /* UVs Clipped to Image Size */
978                 if(G.sima->flag & SI_CLIP_UV) G.sima->flag &= ~SI_CLIP_UV;
979                 else G.sima->flag |= SI_CLIP_UV;
980                 break;
981         case 3: /* Limit Stitch UVs */
982                 stitch_uv_tface(1);
983                 break;
984         case 4: /* Stitch UVs */
985                 stitch_uv_tface(0);
986                 break;
987         case 5: /* Proportional Edit (toggle) */
988                 if(G.scene->proportional)
989                         G.scene->proportional= 0;
990                 else
991                         G.scene->proportional= 1;
992                 break;
993         case 7: /* UVs Snap to Pixel */
994                 G.sima->flag ^= SI_PIXELSNAP;
995                 break;
996     case 8:
997                 pin_tface_uv(1);
998                 break;
999     case 9:
1000                 pin_tface_uv(0);
1001                 break;
1002     case 10:
1003                 unwrap_lscm();
1004                 break;
1005         case 11:
1006                 if(G.sima->flag & SI_LSCM_LIVE) G.sima->flag &= ~SI_LSCM_LIVE;
1007                 else G.sima->flag |= SI_LSCM_LIVE;
1008                 break;
1009         case 12:
1010                 minimize_stretch_tface_uv();
1011                 break;
1012         }
1013 }
1014
1015 static uiBlock *image_uvsmenu(void *arg_unused)
1016 {
1017         uiBlock *block;
1018         short yco= 0, menuwidth=120;
1019         BPyMenu *pym;
1020         int i = 0;
1021
1022         block= uiNewBlock(&curarea->uiblocks, "image_uvsmenu", UI_EMBOSSP, UI_HELV, curarea->headwin);
1023         uiBlockSetButmFunc(block, do_image_uvsmenu, NULL);
1024
1025         // uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Transform Properties...|N", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 0, "");
1026         // uiDefBut(block, SEPR, 0, "",        0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
1027         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, "");
1028         else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Snap to Pixels|", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 7, "");
1029
1030         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, "");
1031         else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Quads Constrained Rectangular|", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 1, "");
1032         
1033         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, "");
1034         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, "");
1035
1036         uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");        
1037
1038         if(G.sima->flag & SI_LSCM_LIVE) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "LSCM Live Transform", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 11, "");
1039         else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "LSCM Live Transform", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 11, "");
1040         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "LSCM Unwrap|E", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 10, "");
1041         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Unpin|Alt P", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 9, "");
1042         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Pin|P", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 8, "");
1043
1044         uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");        
1045
1046         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Minimize Stretch|Ctrl V", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 3, "");
1047         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Limit Stitch...|Shift V", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 3, "");
1048         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Stitch|V", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 4, "");
1049         uiDefIconTextBlockBut(block, image_uvs_transformmenu, NULL, ICON_RIGHTARROW_THIN, "Transform", 0, yco-=20, 120, 19, "");
1050
1051         uiDefBut(block, SEPR, 0, "",                            0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
1052         
1053         uiDefIconTextBlockBut(block, image_uvs_mirrormenu, NULL, ICON_RIGHTARROW_THIN, "Mirror", 0, yco-=20, 120, 19, "");
1054         uiDefIconTextBlockBut(block, image_uvs_weldalignmenu, NULL, ICON_RIGHTARROW_THIN, "Weld/Align", 0, yco-=20, 120, 19, "");
1055         
1056         uiDefBut(block, SEPR, 0, "",                            0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
1057
1058         if(G.scene->proportional)
1059                 uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Proportional Editing|O", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 5, "");
1060         else
1061                 uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Proportional Editing|O", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 5, "");
1062
1063         uiDefIconTextBlockBut(block, image_uvs_propfalloffmenu, NULL, ICON_RIGHTARROW_THIN, "Proportional Falloff", 0, yco-=20, 120, 19, "");
1064
1065         uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");        
1066         
1067         /* note that we acount for the 3 previous entries with i+3: */
1068         for (pym = BPyMenuTable[PYMENU_UV]; pym; pym = pym->next, i++) {
1069
1070                 uiDefIconTextBut(block, BUTM, 1, ICON_PYTHON, pym->name, 0, yco-=20, menuwidth, 19, 
1071                                  NULL, 0.0, 0.0, 1, i+20, 
1072                                  pym->tooltip?pym->tooltip:pym->filename);
1073         }
1074
1075         uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");        
1076
1077         uiDefIconTextBlockBut(block, image_uvs_showhidemenu, NULL, ICON_RIGHTARROW_THIN, "Show/Hide Faces", 0, yco-=20, menuwidth, 19, "");
1078
1079         if(curarea->headertype==HEADERTOP) {
1080                 uiBlockSetDirection(block, UI_DOWN);
1081         }
1082         else {
1083                 uiBlockSetDirection(block, UI_TOP);
1084                 uiBlockFlipOrder(block);
1085         }
1086
1087         uiTextBoundsBlock(block, 50);
1088
1089         return block;
1090 }
1091
1092 void image_buttons(void)
1093 {
1094         uiBlock *block;
1095         short xco, xmax;
1096         char naam[256];
1097         /* This should not be a static var */
1098         static int headerbuttons_packdummy;
1099         extern short CurrentUnwrapper;
1100
1101         headerbuttons_packdummy = 0;
1102                 
1103         sprintf(naam, "header %d", curarea->headwin);
1104         block= uiNewBlock(&curarea->uiblocks, naam, UI_EMBOSS, UI_HELV, curarea->headwin);
1105
1106         if(area_is_active_area(curarea)) uiBlockSetCol(block, TH_HEADER);
1107         else uiBlockSetCol(block, TH_HEADERDESEL);
1108
1109         what_image(G.sima);
1110
1111         curarea->butspacetype= SPACE_IMAGE;
1112
1113         xco = 8;
1114         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.");
1115         xco+= XIC+14;
1116
1117         uiBlockSetEmboss(block, UI_EMBOSSN);
1118         if(curarea->flag & HEADER_NO_PULLDOWN) {
1119                 uiDefIconButBitS(block, TOG, HEADER_NO_PULLDOWN, B_FLIPINFOMENU, ICON_DISCLOSURE_TRI_RIGHT,
1120                                 xco,2,XIC,YIC-2,
1121                                 &(curarea->flag), 0, 0, 0, 0, "Show pulldown menus");
1122         } else {
1123                 uiDefIconButBitS(block, TOG, HEADER_NO_PULLDOWN, B_FLIPINFOMENU, ICON_DISCLOSURE_TRI_DOWN,
1124                                 xco,2,XIC,YIC-2,
1125                                 &(curarea->flag), 0, 0, 0, 0, "Hide pulldown menus");
1126         }
1127         uiBlockSetEmboss(block, UI_EMBOSS);
1128         xco+=XIC;
1129
1130         if((curarea->flag & HEADER_NO_PULLDOWN)==0) {
1131                 /* pull down menus */
1132                 uiBlockSetEmboss(block, UI_EMBOSSP);
1133         
1134                 xmax= GetButStringLength("View");
1135                 uiDefPulldownBut(block, image_viewmenu, NULL, "View", xco, -2, xmax-3, 24, "");
1136                 xco+= xmax;
1137                 
1138                 xmax= GetButStringLength("Select");
1139                 uiDefPulldownBut(block, image_selectmenu, NULL, "Select", xco, -2, xmax-3, 24, "");
1140         
1141                 xco+= xmax;
1142                 
1143                 xmax= GetButStringLength("Image");
1144                 uiDefPulldownBut(block, image_imagemenu, NULL, "Image", xco, -2, xmax-3, 24, "");
1145                 xco+= xmax;
1146                 
1147                 xmax= GetButStringLength("UVs");
1148                 uiDefPulldownBut(block, image_uvsmenu, NULL, "UVs", xco, -2, xmax-3, 24, "");
1149                 xco+= xmax;
1150         }
1151         
1152         /* other buttons: */
1153         uiBlockSetEmboss(block, UI_EMBOSS);
1154
1155         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);
1156
1157         if (G.sima->image) {
1158                 xco+= 8;
1159         
1160                 if (G.sima->image->packedfile) {
1161                         headerbuttons_packdummy = 1;
1162                 }
1163                 uiDefIconButBitI(block, TOG, 1, B_SIMAPACKIMA, ICON_PACKAGE,    xco,0,XIC,YIC, &headerbuttons_packdummy, 0, 0, 0, 0, "Pack/Unpack this image");
1164                 
1165                 xco+= XIC;
1166         }
1167
1168         xco+= 8;
1169
1170         if (G.sima->image) {
1171                 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");
1172                 xco+= XIC+8;
1173         }
1174
1175         /* draw LOCK */
1176         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");
1177
1178         xco += 2*XIC;
1179         uiDefButS(block, MENU, B_NOP, "Unwrapper%t|Old LSCM%x0|New LSCM%x1",xco,0,85,YIC, &CurrentUnwrapper, 0, 0, 0, 0, "Unwrapper");
1180         
1181         /* Always do this last */
1182         curarea->headbutlen= xco+2*XIC;
1183         
1184         uiDrawBlock(block);
1185 }
1186