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