2.5
[blender.git] / source / blender / editors / space_view3d / view3d_buttons.c
1 /**
2  * $Id:
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version. 
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19  *
20  * The Original Code is Copyright (C) 2009 Blender Foundation.
21  * All rights reserved.
22  *
23  * 
24  * Contributor(s): Blender Foundation
25  *
26  * ***** END GPL LICENSE BLOCK *****
27  */
28
29 #include <string.h>
30 #include <stdio.h>
31 #include <math.h>
32 #include <float.h>
33
34 #include "DNA_action_types.h"
35 #include "DNA_armature_types.h"
36 #include "DNA_curve_types.h"
37 #include "DNA_camera_types.h"
38 #include "DNA_lamp_types.h"
39 #include "DNA_lattice_types.h"
40 #include "DNA_meta_types.h"
41 #include "DNA_mesh_types.h"
42 #include "DNA_meshdata_types.h"
43 #include "DNA_object_types.h"
44 #include "DNA_space_types.h"
45 #include "DNA_scene_types.h"
46 #include "DNA_screen_types.h"
47 #include "DNA_userdef_types.h"
48 #include "DNA_view3d_types.h"
49 #include "DNA_world_types.h"
50
51 #include "MEM_guardedalloc.h"
52
53 #include "BLI_arithb.h"
54 #include "BLI_blenlib.h"
55 #include "BLI_editVert.h"
56 #include "BLI_rand.h"
57
58 #include "BKE_action.h"
59 #include "BKE_context.h"
60 #include "BKE_curve.h"
61 #include "BKE_customdata.h"
62 #include "BKE_depsgraph.h"
63 #include "BKE_object.h"
64 #include "BKE_global.h"
65 #include "BKE_scene.h"
66 #include "BKE_screen.h"
67 #include "BKE_utildefines.h"
68
69 #include "BIF_gl.h"
70 #include "BIF_transform.h"
71
72 #include "WM_api.h"
73 #include "WM_types.h"
74
75 #include "RNA_access.h"
76 #include "RNA_define.h"
77
78 #include "ED_armature.h"
79 #include "ED_curve.h"
80 #include "ED_editparticle.h"
81 #include "ED_keyframing.h"
82 #include "ED_mesh.h"
83 #include "ED_object.h"
84 #include "ED_screen.h"
85 #include "ED_types.h"
86 #include "ED_util.h"
87
88 #include "UI_interface.h"
89 #include "UI_resources.h"
90 #include "UI_view2d.h"
91
92 #include "view3d_intern.h"      // own include
93
94
95 /* ******************* view3d space & buttons ************** */
96 #define B_NOP           1
97 #define B_REDR          2
98 #define B_OBJECTPANELROT        1007
99 #define B_OBJECTPANELMEDIAN 1008
100 #define B_ARMATUREPANEL1        1009
101 #define B_ARMATUREPANEL2        1010
102 #define B_OBJECTPANELPARENT 1011
103 #define B_OBJECTPANEL           1012
104 #define B_ARMATUREPANEL3        1013
105 #define B_OBJECTPANELSCALE      1014
106 #define B_OBJECTPANELDIMS       1015
107 #define B_TRANSFORMSPACEADD     1016
108 #define B_TRANSFORMSPACECLEAR   1017
109 #define B_SETPT_AUTO    2125
110 #define B_SETPT_VECTOR  2126
111 #define B_SETPT_ALIGN   2127
112 #define B_SETPT_FREE    2128
113 #define B_RECALCMBALL   2501
114
115 #define B_WEIGHT0_0             2840
116 #define B_WEIGHT1_4             2841
117 #define B_WEIGHT1_2             2842
118 #define B_WEIGHT3_4             2843
119 #define B_WEIGHT1_0             2844
120
121 #define B_OPA1_8                2845
122 #define B_OPA1_4                2846
123 #define B_OPA1_2                2847
124 #define B_OPA3_4                2848
125 #define B_OPA1_0                2849
126
127 #define B_CLR_WPAINT    2850
128
129 #define B_RV3D_LOCKED   2900
130 #define B_RV3D_BOXVIEW  2901
131 #define B_RV3D_BOXCLIP  2902
132
133 #define B_IDNAME                3000
134
135 /* temporary struct for storing transform properties */
136 typedef struct {
137         float ob_eul[4];        // used for quat too....
138         float ob_scale[3]; // need temp space due to linked values
139         float ob_dims[3];
140         short link_scale;
141         float ve_median[5];
142         int curdef;
143         float *defweightp;
144 } TransformProperties;
145
146
147 /* is used for both read and write... */
148 static void v3d_editvertex_buts(const bContext *C, uiBlock *block, View3D *v3d, Object *ob, float lim)
149 {
150         MDeformVert *dvert=NULL;
151         TransformProperties *tfp= v3d->properties_storage;
152         float median[5], ve_median[5];
153         int tot, totw, totweight, totedge;
154         char defstr[320];
155         
156         median[0]= median[1]= median[2]= median[3]= median[4]= 0.0;
157         tot= totw= totweight= totedge= 0;
158         defstr[0]= 0;
159
160         if(ob->type==OB_MESH) {
161                 Mesh *me= ob->data;
162                 EditMesh *em = me->edit_mesh;
163                 EditVert *eve, *evedef=NULL;
164                 EditEdge *eed;
165                 
166                 eve= em->verts.first;
167                 while(eve) {
168                         if(eve->f & SELECT) {
169                                 evedef= eve;
170                                 tot++;
171                                 VecAddf(median, median, eve->co);
172                         }
173                         eve= eve->next;
174                 }
175                 eed= em->edges.first;
176                 while(eed) {
177                         if((eed->f & SELECT)) {
178                                 totedge++;
179                                 median[3]+= eed->crease;
180                         }
181                         eed= eed->next;
182                 }
183
184                 /* check for defgroups */
185                 if(evedef)
186                         dvert= CustomData_em_get(&em->vdata, evedef->data, CD_MDEFORMVERT);
187                 if(tot==1 && dvert && dvert->totweight) {
188                         bDeformGroup *dg;
189                         int i, max=1, init=1;
190                         char str[320];
191                         
192                         for (i=0; i<dvert->totweight; i++){
193                                 dg = BLI_findlink (&ob->defbase, dvert->dw[i].def_nr);
194                                 if(dg) {
195                                         max+= BLI_snprintf(str, sizeof(str), "%s %%x%d|", dg->name, dvert->dw[i].def_nr); 
196                                         if(max<320) strcat(defstr, str);
197                                 }
198                                 else printf("oh no!\n");
199                                 if(tfp->curdef==dvert->dw[i].def_nr) {
200                                         init= 0;
201                                         tfp->defweightp= &dvert->dw[i].weight;
202                                 }
203                         }
204                         
205                         if(init) {      // needs new initialized 
206                                 tfp->curdef= dvert->dw[0].def_nr;
207                                 tfp->defweightp= &dvert->dw[0].weight;
208                         }
209                 }
210         }
211         else if(ob->type==OB_CURVE || ob->type==OB_SURF) {
212                 Curve *cu= ob->data;
213                 Nurb *nu;
214                 BPoint *bp;
215                 BezTriple *bezt;
216                 int a;
217                 
218                 nu= cu->editnurb->first;
219                 while(nu) {
220                         if((nu->type & 7)==CU_BEZIER) {
221                                 bezt= nu->bezt;
222                                 a= nu->pntsu;
223                                 while(a--) {
224                                         if(bezt->f2 & SELECT) {
225                                                 VecAddf(median, median, bezt->vec[1]);
226                                                 tot++;
227                                                 median[4]+= bezt->weight;
228                                                 totweight++;
229                                         }
230                                         else {
231                                                 if(bezt->f1 & SELECT) {
232                                                         VecAddf(median, median, bezt->vec[0]);
233                                                         tot++;
234                                                 }
235                                                 if(bezt->f3 & SELECT) {
236                                                         VecAddf(median, median, bezt->vec[2]);
237                                                         tot++;
238                                                 }
239                                         }
240                                         bezt++;
241                                 }
242                         }
243                         else {
244                                 bp= nu->bp;
245                                 a= nu->pntsu*nu->pntsv;
246                                 while(a--) {
247                                         if(bp->f1 & SELECT) {
248                                                 VecAddf(median, median, bp->vec);
249                                                 median[3]+= bp->vec[3];
250                                                 totw++;
251                                                 tot++;
252                                                 median[4]+= bp->weight;
253                                                 totweight++;
254                                         }
255                                         bp++;
256                                 }
257                         }
258                         nu= nu->next;
259                 }
260         }
261         else if(ob->type==OB_LATTICE) {
262                 Lattice *lt= ob->data;
263                 BPoint *bp;
264                 int a;
265                 
266                 a= lt->editlatt->pntsu*lt->editlatt->pntsv*lt->editlatt->pntsw;
267                 bp= lt->editlatt->def;
268                 while(a--) {
269                         if(bp->f1 & SELECT) {
270                                 VecAddf(median, median, bp->vec);
271                                 tot++;
272                                 median[4]+= bp->weight;
273                                 totweight++;
274                         }
275                         bp++;
276                 }
277         }
278         
279         if(tot==0) return;
280
281         median[0] /= (float)tot;
282         median[1] /= (float)tot;
283         median[2] /= (float)tot;
284         if(totedge) median[3] /= (float)totedge;
285         else if(totw) median[3] /= (float)totw;
286         if(totweight) median[4] /= (float)totweight;
287         
288         if(v3d->flag & V3D_GLOBAL_STATS)
289                 Mat4MulVecfl(ob->obmat, median);
290         
291         if(block) {     // buttons
292                 int but_y;
293                 if((ob->parent) && (ob->partype == PARBONE))    but_y = 135;
294                 else                                                                                    but_y = 150;
295                 
296                 uiBlockBeginAlign(block);
297                 uiDefButBitS(block, TOG, V3D_GLOBAL_STATS, B_REDR, "Global",            160, but_y, 70, 19, &v3d->flag, 0, 0, 0, 0, "Displays global values");
298                 uiDefButBitS(block, TOGN, V3D_GLOBAL_STATS, B_REDR, "Local",            230, but_y, 70, 19, &v3d->flag, 0, 0, 0, 0, "Displays local values");
299                 uiBlockEndAlign(block);
300                 
301                 memcpy(tfp->ve_median, median, sizeof(tfp->ve_median));
302                 
303                 uiBlockBeginAlign(block);
304                 if(tot==1) {
305                         uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Vertex X:", 10, 110, 290, 19, &(tfp->ve_median[0]), -lim, lim, 10, 3, "");
306                         uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Vertex Y:", 10, 90, 290, 19, &(tfp->ve_median[1]), -lim, lim, 10, 3, "");
307                         uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Vertex Z:", 10, 70, 290, 19, &(tfp->ve_median[2]), -lim, lim, 10, 3, "");
308                         if(totw==1)
309                                 uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Vertex W:", 10, 50, 290, 19, &(tfp->ve_median[3]), 0.01, 100.0, 10, 3, "");
310                         uiBlockEndAlign(block);
311         
312                         if(defstr[0]) {
313                                 uiDefBut(block, LABEL, 1, "Vertex Deform Groups",               10, 40, 290, 20, NULL, 0.0, 0.0, 0, 0, "");
314
315                                 uiBlockBeginAlign(block);
316                                 uiDefButF(block, NUM, B_NOP, "Weight:",                 10, 20, 150, 19, tfp->defweightp, 0.0f, 1.0f, 10, 3, "Weight value");
317                                 uiDefButI(block, MENU, B_REDR, defstr,  160, 20, 140, 19, &tfp->curdef, 0.0, 0.0, 0, 0, "Current Vertex Group");
318                                 uiBlockEndAlign(block);
319                         }
320                         else if(totweight)
321                                 uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Weight:",   10, 20, 290, 19, &(tfp->ve_median[4]), 0.0, 1.0, 10, 3, "");
322
323                 }
324                 else {
325                         uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Median X:", 10, 110, 290, 19, &(tfp->ve_median[0]), -lim, lim, 10, 3, "");
326                         uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Median Y:", 10, 90, 290, 19, &(tfp->ve_median[1]), -lim, lim, 10, 3, "");
327                         uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Median Z:", 10, 70, 290, 19, &(tfp->ve_median[2]), -lim, lim, 10, 3, "");
328                         if(totw==tot)
329                                 uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Median W:", 10, 50, 290, 19, &(tfp->ve_median[3]), 0.01, 100.0, 10, 3, "");
330                         uiBlockEndAlign(block);
331                         if(totweight)
332                                 uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Weight:",   10, 20, 290, 19, &(tfp->ve_median[4]), 0.0, 1.0, 10, 3, "Weight is used for SoftBody Goal");
333                 }
334                 
335                 if(ob->type==OB_CURVE && (totw==0)) { /* bez curves have no w */
336                         uiBlockBeginAlign(block);
337                         uiDefBut(block, BUT,B_SETPT_AUTO,"Auto",        10, 44, 72, 19, 0, 0, 0, 0, 0, "Auto handles (Shift H)");
338                         uiDefBut(block, BUT,B_SETPT_VECTOR,"Vector",82, 44, 73, 19, 0, 0, 0, 0, 0, "Vector handles (V)");
339                         uiDefBut(block, BUT,B_SETPT_ALIGN,"Align",155, 44, 73, 19, 0, 0, 0, 0, 0, "Align handles (H Toggles)");
340                         uiDefBut(block, BUT,B_SETPT_FREE,"Free",        227, 44, 72, 19, 0, 0, 0, 0, 0, "Align handles (H Toggles)");
341                         uiBlockEndAlign(block);
342                 }
343                 
344                 if(totedge==1)
345                         uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Crease W:", 10, 30, 290, 19, &(tfp->ve_median[3]), 0.0, 1.0, 10, 3, "");
346                 else if(totedge>1)
347                         uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Median Crease W:",  10, 30, 290, 19, &(tfp->ve_median[3]), 0.0, 1.0, 10, 3, "");
348                 
349         }
350         else {  // apply
351                 memcpy(ve_median, tfp->ve_median, sizeof(tfp->ve_median));
352                 
353                 if(v3d->flag & V3D_GLOBAL_STATS) {
354                         Mat4Invert(ob->imat, ob->obmat);
355                         Mat4MulVecfl(ob->imat, median);
356                         Mat4MulVecfl(ob->imat, ve_median);
357                 }
358                 VecSubf(median, ve_median, median);
359                 median[3]= ve_median[3]-median[3];
360                 median[4]= ve_median[4]-median[4];
361                 
362                 if(ob->type==OB_MESH) {
363                         Mesh *me= ob->data;
364                         EditMesh *em = me->edit_mesh;
365                         EditVert *eve;
366                         EditEdge *eed;
367                         
368                         eve= em->verts.first;
369                         while(eve) {
370                                 if(eve->f & SELECT) {
371                                         VecAddf(eve->co, eve->co, median);
372                                 }
373                                 eve= eve->next;
374                         }
375                         
376                         for(eed= em->edges.first; eed; eed= eed->next) {
377                                 if(eed->f & SELECT) {
378                                         /* ensure the median can be set to zero or one */
379                                         if(ve_median[3]==0.0f) eed->crease= 0.0f;
380                                         else if(ve_median[3]==1.0f) eed->crease= 1.0f;
381                                         else {
382                                                 eed->crease+= median[3];
383                                                 CLAMP(eed->crease, 0.0, 1.0);
384                                         }
385                                 }
386                         }
387                         
388                         recalc_editnormals(em);
389                 }
390                 else if(ob->type==OB_CURVE || ob->type==OB_SURF) {
391                         Curve *cu= ob->data;
392                         Nurb *nu;
393                         BPoint *bp;
394                         BezTriple *bezt;
395                         int a;
396                         
397                         nu= cu->editnurb->first;
398                         while(nu) {
399                                 if((nu->type & 7)==1) {
400                                         bezt= nu->bezt;
401                                         a= nu->pntsu;
402                                         while(a--) {
403                                                 if(bezt->f2 & SELECT) {
404                                                         VecAddf(bezt->vec[0], bezt->vec[0], median);
405                                                         VecAddf(bezt->vec[1], bezt->vec[1], median);
406                                                         VecAddf(bezt->vec[2], bezt->vec[2], median);
407                                                         bezt->weight+= median[4];
408                                                 }
409                                                 else {
410                                                         if(bezt->f1 & SELECT) {
411                                                                 VecAddf(bezt->vec[0], bezt->vec[0], median);
412                                                         }
413                                                         if(bezt->f3 & SELECT) {
414                                                                 VecAddf(bezt->vec[2], bezt->vec[2], median);
415                                                         }
416                                                 }
417                                                 bezt++;
418                                         }
419                                 }
420                                 else {
421                                         bp= nu->bp;
422                                         a= nu->pntsu*nu->pntsv;
423                                         while(a--) {
424                                                 if(bp->f1 & SELECT) {
425                                                         VecAddf(bp->vec, bp->vec, median);
426                                                         bp->vec[3]+= median[3];
427                                                         bp->weight+= median[4];
428                                                 }
429                                                 bp++;
430                                         }
431                                 }
432                                 test2DNurb(nu);
433                                 testhandlesNurb(nu); /* test for bezier too */
434
435                                 nu= nu->next;
436                         }
437                 }
438                 else if(ob->type==OB_LATTICE) {
439                         Lattice *lt= ob->data;
440                         BPoint *bp;
441                         int a;
442                         
443                         a= lt->editlatt->pntsu*lt->editlatt->pntsv*lt->editlatt->pntsw;
444                         bp= lt->editlatt->def;
445                         while(a--) {
446                                 if(bp->f1 & SELECT) {
447                                         VecAddf(bp->vec, bp->vec, median);
448                                         bp->weight+= median[4];
449                                 }
450                                 bp++;
451                         }
452                 }
453                 
454 //              ED_undo_push(C, "Transform properties");
455         }
456 }
457
458 /* assumes armature active */
459 static void validate_bonebutton_cb(bContext *C, void *bonev, void *namev)
460 {
461         Object *ob= CTX_data_active_object(C);
462         
463         if(ob && ob->type==OB_ARMATURE) {
464                 Bone *bone= bonev;
465                 char oldname[32], newname[32];
466                 
467                 /* need to be on the stack */
468                 BLI_strncpy(newname, bone->name, 32);
469                 BLI_strncpy(oldname, (char *)namev, 32);
470                 /* restore */
471                 BLI_strncpy(bone->name, oldname, 32);
472                 
473                 armature_bone_rename(ob, oldname, newname); // editarmature.c
474         }
475 }
476
477 static void v3d_posearmature_buts(uiBlock *block, View3D *v3d, Object *ob, float lim)
478 {
479         uiBut *but;
480         bArmature *arm;
481         bPoseChannel *pchan;
482         Bone *bone= NULL;
483         TransformProperties *tfp= v3d->properties_storage;
484
485         arm = ob->data;
486         if (!arm || !ob->pose) return;
487
488         for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
489                 bone = pchan->bone;
490                 if(bone && (bone->flag & BONE_ACTIVE) && (bone->layer & arm->layer))
491                         break;
492         }
493         if (!pchan || !bone) return;
494
495         if((ob->parent) && (ob->partype == PARBONE))
496                 but= uiDefBut (block, TEX, B_NOP, "Bone:",                              160, 130, 140, 19, bone->name, 1, 31, 0, 0, "");
497         else
498                 but= uiDefBut(block, TEX, B_NOP, "Bone:",                               160, 140, 140, 19, bone->name, 1, 31, 0, 0, "");
499         uiButSetFunc(but, validate_bonebutton_cb, bone, NULL);
500         uiButSetCompleteFunc(but, autocomplete_bone, (void *)ob);
501
502         QuatToEul(pchan->quat, tfp->ob_eul);
503         tfp->ob_eul[0]*= 180.0/M_PI;
504         tfp->ob_eul[1]*= 180.0/M_PI;
505         tfp->ob_eul[2]*= 180.0/M_PI;
506         
507         uiBlockBeginAlign(block);
508         uiDefIconButBitS(block, ICONTOG, OB_LOCK_LOCX, B_REDR, ICON_UNLOCKED,   10,140,20,19, &(pchan->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
509         uiDefButF(block, NUM, B_ARMATUREPANEL2, "LocX:",        30, 140, 120, 19, pchan->loc, -lim, lim, 100, 3, "");
510         uiDefIconButBitS(block, ICONTOG, OB_LOCK_LOCY, B_REDR, ICON_UNLOCKED,   10,120,20,19, &(pchan->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
511         uiDefButF(block, NUM, B_ARMATUREPANEL2, "LocY:",        30, 120, 120, 19, pchan->loc+1, -lim, lim, 100, 3, "");
512         uiDefIconButBitS(block, ICONTOG, OB_LOCK_LOCZ, B_REDR, ICON_UNLOCKED,   10,100,20,19, &(pchan->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
513         uiDefButF(block, NUM, B_ARMATUREPANEL2, "LocZ:",        30, 100, 120, 19, pchan->loc+2, -lim, lim, 100, 3, "");
514
515         uiBlockBeginAlign(block);
516         uiDefIconButBitS(block, ICONTOG, OB_LOCK_ROTX, B_REDR, ICON_UNLOCKED,   10,70,20,19, &(pchan->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
517         uiDefButF(block, NUM, B_ARMATUREPANEL3, "RotX:",        30, 70, 120, 19, tfp->ob_eul, -1000.0, 1000.0, 100, 3, "");
518         uiDefIconButBitS(block, ICONTOG, OB_LOCK_ROTY, B_REDR, ICON_UNLOCKED,   10,50,20,19, &(pchan->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
519         uiDefButF(block, NUM, B_ARMATUREPANEL3, "RotY:",        30, 50, 120, 19, tfp->ob_eul+1, -1000.0, 1000.0, 100, 3, "");
520         uiDefIconButBitS(block, ICONTOG, OB_LOCK_ROTZ, B_REDR, ICON_UNLOCKED,   10,30,20,19, &(pchan->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
521         uiDefButF(block, NUM, B_ARMATUREPANEL3, "RotZ:",        30, 30, 120, 19, tfp->ob_eul+2, -1000.0, 1000.0, 100, 3, "");
522         
523         uiBlockBeginAlign(block);
524         uiDefIconButBitS(block, ICONTOG, OB_LOCK_SCALEX, B_REDR, ICON_UNLOCKED, 160,70,20,19, &(pchan->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
525         uiDefButF(block, NUM, B_ARMATUREPANEL2, "ScaleX:",      180, 70, 120, 19, pchan->size, -lim, lim, 10, 3, "");
526         uiDefIconButBitS(block, ICONTOG, OB_LOCK_SCALEY, B_REDR, ICON_UNLOCKED, 160,50,20,19, &(pchan->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
527         uiDefButF(block, NUM, B_ARMATUREPANEL2, "ScaleY:",      180, 50, 120, 19, pchan->size+1, -lim, lim, 10, 3, "");
528         uiDefIconButBitS(block, ICONTOG, OB_LOCK_SCALEZ, B_REDR, ICON_UNLOCKED, 160,30,20,19, &(pchan->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
529         uiDefButF(block, NUM, B_ARMATUREPANEL2, "ScaleZ:",      180, 30, 120, 19, pchan->size+2, -lim, lim, 10, 3, "");
530         uiBlockEndAlign(block);
531 }
532
533 /* assumes armature editmode */
534 void validate_editbonebutton_cb(bContext *C, void *bonev, void *namev)
535 {
536         EditBone *eBone= bonev;
537         char oldname[32], newname[32];
538         
539         /* need to be on the stack */
540         BLI_strncpy(newname, eBone->name, 32);
541         BLI_strncpy(oldname, (char *)namev, 32);
542         /* restore */
543         BLI_strncpy(eBone->name, oldname, 32);
544         
545         armature_bone_rename(CTX_data_edit_object(C), oldname, newname); // editarmature.c
546         WM_event_add_notifier(C, NC_OBJECT|ND_BONE_SELECT, CTX_data_edit_object(C)); // XXX fix
547 }
548
549 static void v3d_editarmature_buts(uiBlock *block, View3D *v3d, Object *ob, float lim)
550 {
551         bArmature *arm= ob->data;
552         EditBone *ebone;
553         uiBut *but;
554         TransformProperties *tfp= v3d->properties_storage;
555         
556         ebone= arm->edbo->first;
557
558         for (ebone = arm->edbo->first; ebone; ebone=ebone->next){
559                 if ((ebone->flag & BONE_ACTIVE) && (ebone->layer & arm->layer))
560                         break;
561         }
562
563         if (!ebone)
564                 return;
565         
566         if((ob->parent) && (ob->partype == PARBONE))
567                 but= uiDefBut(block, TEX, B_NOP, "Bone:", 160, 130, 140, 19, ebone->name, 1, 31, 0, 0, "");
568         else
569                 but= uiDefBut(block, TEX, B_NOP, "Bone:",                       160, 150, 140, 19, ebone->name, 1, 31, 0, 0, "");
570         uiButSetFunc(but, validate_editbonebutton_cb, ebone, NULL);
571
572         uiBlockBeginAlign(block);
573         uiDefButF(block, NUM, B_ARMATUREPANEL1, "HeadX:",       10, 70, 140, 19, ebone->head, -lim, lim, 10, 3, "");
574         uiDefButF(block, NUM, B_ARMATUREPANEL1, "HeadY:",       10, 50, 140, 19, ebone->head+1, -lim, lim, 10, 3, "");
575         uiDefButF(block, NUM, B_ARMATUREPANEL1, "HeadZ:",       10, 30, 140, 19, ebone->head+2, -lim, lim, 10, 3, "");
576         uiBlockBeginAlign(block);
577         uiDefButF(block, NUM, B_ARMATUREPANEL1, "TailX:",       160, 70, 140, 19, ebone->tail, -lim, lim, 10, 3, "");
578         uiDefButF(block, NUM, B_ARMATUREPANEL1, "TailY:",       160, 50, 140, 19, ebone->tail+1, -lim, lim, 10, 3, "");
579         uiDefButF(block, NUM, B_ARMATUREPANEL1, "TailZ:",       160, 30, 140, 19, ebone->tail+2, -lim, lim, 10, 3, "");
580         uiBlockEndAlign(block);
581         
582         tfp->ob_eul[0]= 180.0*ebone->roll/M_PI;
583         uiDefButF(block, NUM, B_ARMATUREPANEL1, "Roll:",        10, 100, 140, 19, tfp->ob_eul, -lim, lim, 1000, 3, "");
584
585         uiDefButBitI(block, TOG, BONE_EDITMODE_LOCKED, B_REDR, "Lock", 160, 100, 140, 19, &(ebone->flag), 0, 0, 0, 0, "Prevents bone from being transformed in edit mode");
586         
587         uiBlockBeginAlign(block);
588         uiDefButF(block, NUM, B_ARMATUREPANEL1, "TailRadius:",  10, 150, 140, 19, &ebone->rad_tail, 0, lim, 10, 3, "");
589         if (ebone->parent && ebone->flag & BONE_CONNECTED )
590                 uiDefButF(block, NUM, B_ARMATUREPANEL1, "HeadRadius:",  10, 130, 140, 19, &ebone->parent->rad_tail, 0, lim, 10, 3, "");
591         else
592                 uiDefButF(block, NUM, B_ARMATUREPANEL1, "HeadRadius:",  10, 130, 140, 19, &ebone->rad_head, 0, lim, 10, 3, "");
593         uiBlockEndAlign(block);
594 }
595
596 static void v3d_editmetaball_buts(uiBlock *block, Object *ob, float lim)
597 {
598         MetaElem *lastelem= NULL; // XXX
599
600         if(lastelem) {
601                 uiBlockBeginAlign(block);
602                 uiDefButF(block, NUM, B_RECALCMBALL, "LocX:", 10, 70, 140, 19, &lastelem->x, -lim, lim, 100, 3, "");
603                 uiDefButF(block, NUM, B_RECALCMBALL, "LocY:", 10, 50, 140, 19, &lastelem->y, -lim, lim, 100, 3, "");
604                 uiDefButF(block, NUM, B_RECALCMBALL, "LocZ:", 10, 30, 140, 19, &lastelem->z, -lim, lim, 100, 3, "");
605
606                 uiBlockBeginAlign(block);
607                 if(lastelem->type!=MB_BALL)
608                         uiDefButF(block, NUM, B_RECALCMBALL, "dx:", 160, 70, 140, 19, &lastelem->expx, 0, lim, 100, 3, "");
609                 if((lastelem->type!=MB_BALL) && (lastelem->type!=MB_TUBE))
610                         uiDefButF(block, NUM, B_RECALCMBALL, "dy:", 160, 50, 140, 19, &lastelem->expy, 0, lim, 100, 3, "");
611                 if((lastelem->type==MB_ELIPSOID) || (lastelem->type==MB_CUBE))
612                         uiDefButF(block, NUM, B_RECALCMBALL, "dz:", 160, 30, 140, 19, &lastelem->expz, 0, lim, 100, 3, "");
613
614                 uiBlockEndAlign(block); 
615
616                 uiBlockBeginAlign(block);
617                 uiDefButF(block, NUM, B_RECALCMBALL, "Radius:", 10, 120, 140, 19, &lastelem->rad, 0, lim, 100, 3, "Size of the active metaball");
618                 uiDefButF(block, NUM, B_RECALCMBALL, "Stiffness:", 10, 100, 140, 19, &lastelem->s, 0, 10, 100, 3, "Stiffness of the active metaball");
619                 uiBlockEndAlign(block);
620                 
621                 uiDefButS(block, MENU, B_RECALCMBALL, "Type%t|Ball%x0|Tube%x4|Plane%x5|Elipsoid%x6|Cube%x7", 160, 120, 140, 19, &lastelem->type, 0.0, 0.0, 0, 0, "Set active element type");
622                 
623         }
624 }
625
626 /* test if 'ob' is a parent somewhere in par's parents */
627 static int test_parent_loop(Object *par, Object *ob)
628 {
629         if(par == NULL) return 0;
630         if(ob == par) return 1;
631         return test_parent_loop(par->parent, ob);
632 }
633
634 static void do_view3d_region_buttons(bContext *C, void *arg, int event)
635 {
636         Scene *scene= CTX_data_scene(C);
637         Object *obedit= CTX_data_edit_object(C);
638         View3D *v3d= CTX_wm_view3d(C);
639         BoundBox *bb;
640         Object *ob= OBACT;
641         TransformProperties *tfp= v3d->properties_storage;
642         VPaint *wpaint= scene->toolsettings->wpaint;
643         
644         switch(event) {
645         
646         case B_REDR:
647                 ED_area_tag_redraw(CTX_wm_area(C));
648                 return; /* no notifier! */
649                 
650         case B_OBJECTPANEL:
651                 DAG_object_flush_update(scene, ob, OB_RECALC_OB);
652                 break;
653                 
654         case B_OBJECTPANELROT:
655                 if(ob) {
656                         ob->rot[0]= M_PI*tfp->ob_eul[0]/180.0;
657                         ob->rot[1]= M_PI*tfp->ob_eul[1]/180.0;
658                         ob->rot[2]= M_PI*tfp->ob_eul[2]/180.0;
659                         DAG_object_flush_update(scene, ob, OB_RECALC_OB);
660                 }
661                 break;
662
663         case B_OBJECTPANELSCALE:
664                 if(ob) {
665
666                         /* link scale; figure out which axis changed */
667                         if (tfp->link_scale) {
668                                 float ratio, tmp, max = 0.0;
669                                 int axis;
670                                 
671                                 axis = 0;
672                                 max = fabs(tfp->ob_scale[0] - ob->size[0]);
673                                 tmp = fabs(tfp->ob_scale[1] - ob->size[1]);
674                                 if (tmp > max) {
675                                         axis = 1;
676                                         max = tmp;
677                                 }
678                                 tmp = fabs(tfp->ob_scale[2] - ob->size[2]);
679                                 if (tmp > max) {
680                                         axis = 2;
681                                         max = tmp;
682                                 }
683                         
684                                 if (ob->size[axis] != tfp->ob_scale[axis]) {
685                                         if (fabs(ob->size[axis]) > FLT_EPSILON) {
686                                                 ratio = tfp->ob_scale[axis] / ob->size[axis];
687                                                 ob->size[0] *= ratio;
688                                                 ob->size[1] *= ratio;
689                                                 ob->size[2] *= ratio;
690                                         }
691                                 }
692                         }
693                         else {
694                                 VECCOPY(ob->size, tfp->ob_scale);
695                                 
696                         }
697                         DAG_object_flush_update(scene, ob, OB_RECALC_OB);
698                 }
699                 break;
700
701         case B_OBJECTPANELDIMS:
702                 bb= object_get_boundbox(ob);
703                 if(bb) {
704                         float old_dims[3], scale[3], ratio, len[3];
705                         int axis;
706
707                         Mat4ToSize(ob->obmat, scale);
708
709                         len[0] = bb->vec[4][0] - bb->vec[0][0];
710                         len[1] = bb->vec[2][1] - bb->vec[0][1];
711                         len[2] = bb->vec[1][2] - bb->vec[0][2];
712
713                         old_dims[0] = fabs(scale[0]) * len[0];
714                         old_dims[1] = fabs(scale[1]) * len[1];
715                         old_dims[2] = fabs(scale[2]) * len[2];
716
717                         /* for each axis changed */
718                         for (axis = 0; axis<3; axis++) {
719                                 if (fabs(old_dims[axis] - tfp->ob_dims[axis]) > 0.0001) {
720                                         if (old_dims[axis] > 0.0) {
721                                                 ratio = tfp->ob_dims[axis] / old_dims[axis]; 
722                                                 if (tfp->link_scale) {
723                                                         ob->size[0] *= ratio;
724                                                         ob->size[1] *= ratio;
725                                                         ob->size[2] *= ratio;
726                                                         break;
727                                                 }
728                                                 else {
729                                                         ob->size[axis] *= ratio;
730                                                 }
731                                         }
732                                         else {
733                                                 if (len[axis] > 0) {
734                                                         ob->size[axis] = tfp->ob_dims[axis] / len[axis];
735                                                 }
736                                         }
737                                 }
738                         }
739                         
740                         /* prevent multiple B_OBJECTPANELDIMS events to keep scaling, cycling with TAB on buttons can cause that */
741                         VECCOPY(tfp->ob_dims, old_dims);
742                         
743                         DAG_object_flush_update(scene, ob, OB_RECALC_OB);
744                 }
745                 break;
746         
747         case B_OBJECTPANELMEDIAN:
748                 if(ob) {
749                         v3d_editvertex_buts(C, NULL, v3d, ob, 1.0);
750                         DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
751                 }
752                 break;
753                 
754                 /* note; this case also used for parbone */
755         case B_OBJECTPANELPARENT:
756                 if(ob) {
757                         if(ob->id.lib || test_parent_loop(ob->parent, ob) ) 
758                                 ob->parent= NULL;
759                         else {
760                                 DAG_scene_sort(scene);
761                                 DAG_object_flush_update(scene, ob, OB_RECALC_OB);
762                         }
763                 }
764                 break;
765                 
766         case B_ARMATUREPANEL1:
767                 {
768                         bArmature *arm= obedit->data;
769                         EditBone *ebone, *child;
770                         
771                         for (ebone = arm->edbo->first; ebone; ebone=ebone->next){
772                                 if ((ebone->flag & BONE_ACTIVE) && (ebone->layer & arm->layer))
773                                         break;
774                         }
775                         if (ebone) {
776                                 ebone->roll= M_PI*tfp->ob_eul[0]/180.0;
777                                 //      Update our parent
778                                 if (ebone->parent && ebone->flag & BONE_CONNECTED){
779                                         VECCOPY (ebone->parent->tail, ebone->head);
780                                 }
781                         
782                                 //      Update our children if necessary
783                                 for (child = arm->edbo->first; child; child=child->next){
784                                         if (child->parent == ebone && (child->flag & BONE_CONNECTED)){
785                                                 VECCOPY (child->head, ebone->tail);
786                                         }
787                                 }
788                                 if(arm->flag & ARM_MIRROR_EDIT) {
789                                         EditBone *eboflip= ED_armature_bone_get_mirrored(arm->edbo, ebone);
790                                         if(eboflip) {
791                                                 eboflip->roll= -ebone->roll;
792                                                 eboflip->head[0]= -ebone->head[0];
793                                                 eboflip->tail[0]= -ebone->tail[0];
794                                                 
795                                                 //      Update our parent
796                                                 if (eboflip->parent && eboflip->flag & BONE_CONNECTED){
797                                                         VECCOPY (eboflip->parent->tail, eboflip->head);
798                                                 }
799                                                 
800                                                 //      Update our children if necessary
801                                                 for (child = arm->edbo->first; child; child=child->next){
802                                                         if (child->parent == eboflip && (child->flag & BONE_CONNECTED)){
803                                                                 VECCOPY (child->head, eboflip->tail);
804                                                         }
805                                                 }
806                                         }
807                                 }
808                         }
809                 }
810                 break;
811         case B_ARMATUREPANEL3:  // rotate button on channel
812                 {
813                         bArmature *arm;
814                         bPoseChannel *pchan;
815                         Bone *bone;
816                         float eul[3];
817                         
818                         arm = ob->data;
819                         if (!arm || !ob->pose) return;
820                                 
821                         for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
822                                 bone = pchan->bone;
823                                 if(bone && (bone->flag & BONE_ACTIVE) && (bone->layer & arm->layer))
824                                         break;
825                         }
826                         if (!pchan) return;
827                         
828                         /* make a copy to eul[3], to allow TAB on buttons to work */
829                         eul[0]= M_PI*tfp->ob_eul[0]/180.0;
830                         eul[1]= M_PI*tfp->ob_eul[1]/180.0;
831                         eul[2]= M_PI*tfp->ob_eul[2]/180.0;
832                         EulToQuat(eul, pchan->quat);
833                 }
834                 /* no break, pass on */
835         case B_ARMATUREPANEL2:
836                 {
837                         ob->pose->flag |= (POSE_LOCKED|POSE_DO_UNLOCK);
838                         DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
839                 }
840                 break;
841         case B_TRANSFORMSPACEADD:
842                 BIF_manageTransformOrientation(C, 1, 0);
843                 break;
844         case B_TRANSFORMSPACECLEAR:
845                 BIF_clearTransformOrientation(C);
846                 break;
847                 
848         case B_WEIGHT0_0:
849                 wpaint->weight = 0.0f;
850                 break;
851                 
852         case B_WEIGHT1_4:
853                 wpaint->weight = 0.25f;
854                 break;
855         case B_WEIGHT1_2:
856                 wpaint->weight = 0.5f;
857                 break;
858         case B_WEIGHT3_4:
859                 wpaint->weight = 0.75f;
860                 break;
861         case B_WEIGHT1_0:
862                 wpaint->weight = 1.0f;
863                 break;
864                 
865         case B_OPA1_8:
866                 wpaint->a = 0.125f;
867                 break;
868         case B_OPA1_4:
869                 wpaint->a = 0.25f;
870                 break;
871         case B_OPA1_2:
872                 wpaint->a = 0.5f;
873                 break;
874         case B_OPA3_4:
875                 wpaint->a = 0.75f;
876                 break;
877         case B_OPA1_0:
878                 wpaint->a = 1.0f;
879                 break;
880         case B_CLR_WPAINT:
881 //              if(!multires_level1_test()) {
882                 {
883                         bDeformGroup *defGroup = BLI_findlink(&ob->defbase, ob->actdef-1);
884                         if(defGroup) {
885                                 Mesh *me= ob->data;
886                                 int a;
887                                 for(a=0; a<me->totvert; a++)
888                                         remove_vert_defgroup (ob, defGroup, a);
889                                 DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
890                         }
891                 }
892                 break;
893         case B_RV3D_LOCKED:
894         case B_RV3D_BOXVIEW:
895         case B_RV3D_BOXCLIP:
896                 {
897                         ScrArea *sa= CTX_wm_area(C);
898                         ARegion *ar= sa->regionbase.last;
899                         RegionView3D *rv3d;
900                         short viewlock;
901                         
902                         ar= ar->prev;
903                         rv3d= ar->regiondata;
904                         viewlock= rv3d->viewlock;
905                         
906                         if((viewlock & RV3D_LOCKED)==0)
907                                 viewlock= 0;
908                         else if((viewlock & RV3D_BOXVIEW)==0)
909                                 viewlock &= ~RV3D_BOXCLIP;
910                         
911                         for(; ar; ar= ar->prev) {
912                                 if(ar->alignment==RGN_ALIGN_QSPLIT) {
913                                         rv3d= ar->regiondata;
914                                         rv3d->viewlock= viewlock;
915                                 }
916                         }
917                         
918                         if(rv3d->viewlock & RV3D_BOXVIEW)
919                                 view3d_boxview_copy(sa, sa->regionbase.last);
920                         
921                         ED_area_tag_redraw(sa);
922                 }
923                 break;
924         }
925
926         /* default for now */
927         WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, ob);
928 }
929
930 void removeTransformOrientation_func(bContext *C, void *target, void *unused)
931 {
932         BIF_removeTransformOrientation(C, (TransformOrientation *) target);
933 }
934
935 void selectTransformOrientation_func(bContext *C, void *target, void *unused)
936 {
937         BIF_selectTransformOrientation(C, (TransformOrientation *) target);
938 }
939
940 static void view3d_panel_transform_spaces(const bContext *C, ARegion *ar, short cntrl)
941 {
942         Scene *scene= CTX_data_scene(C);
943         Object *obedit= CTX_data_edit_object(C);
944         View3D *v3d= CTX_wm_view3d(C);
945         ListBase *transform_spaces = &scene->transform_spaces;
946         TransformOrientation *ts = transform_spaces->first;
947         uiBlock *block;
948         uiBut *but;
949         int xco = 20, yco = 70, height = 140;
950         int index;
951
952         block= uiBeginBlock(C, ar, "view3d_panel_transform", UI_EMBOSS, UI_HELV);
953         if(uiNewPanel(C, ar, block, "Transform Orientations", "View3d", 1000, 0, 318, height)==0) return;
954
955         uiNewPanelHeight(block, height);
956
957         uiBlockBeginAlign(block);
958         
959         if (obedit)
960                 uiDefBut(block, BUT, B_TRANSFORMSPACEADD, "Add", xco,120,80,20, 0, 0, 0, 0, 0, "Add the selected element as a Transform Orientation");
961         else
962                 uiDefBut(block, BUT, B_TRANSFORMSPACEADD, "Add", xco,120,80,20, 0, 0, 0, 0, 0, "Add the active object as a Transform Orientation");
963
964         uiDefBut(block, BUT, B_TRANSFORMSPACECLEAR, "Clear", xco + 80,120,80,20, 0, 0, 0, 0, 0, "Removal all Transform Orientations");
965         
966         uiBlockEndAlign(block);
967         
968         uiBlockBeginAlign(block);
969         
970         uiDefButS(block, ROW, B_REDR, "Global", xco,            90, 40,20, &v3d->twmode, 5.0, (float)V3D_MANIP_GLOBAL,0, 0, "Global Transform Orientation");
971         uiDefButS(block, ROW, B_REDR, "Local",  xco + 40,       90, 40,20, &v3d->twmode, 5.0, (float)V3D_MANIP_LOCAL, 0, 0, "Local Transform Orientation");
972         uiDefButS(block, ROW, B_REDR, "Normal", xco + 80,       90, 40,20, &v3d->twmode, 5.0, (float)V3D_MANIP_NORMAL,0, 0, "Normal Transform Orientation");
973         uiDefButS(block, ROW, B_REDR, "View",           xco + 120,      90, 40,20, &v3d->twmode, 5.0, (float)V3D_MANIP_VIEW,    0, 0, "View Transform Orientation");
974         
975         for (index = V3D_MANIP_CUSTOM, ts = transform_spaces->first ; ts ; ts = ts->next, index++) {
976
977                 UI_ThemeColor(TH_BUT_ACTION);
978                 if (v3d->twmode == index) {
979                         but = uiDefIconButS(block,ROW, B_REDR, ICON_CHECKBOX_HLT, xco,yco,XIC,YIC, &v3d->twmode, 5.0, (float)index, 0, 0, "Use this Custom Transform Orientation");
980                 }
981                 else {
982                         but = uiDefIconButS(block,ROW, B_REDR, ICON_CHECKBOX_DEHLT, xco,yco,XIC,YIC, &v3d->twmode, 5.0, (float)index, 0, 0, "Use this Custom Transform Orientation");
983                 }
984                 uiButSetFunc(but, selectTransformOrientation_func, ts, NULL);
985                 uiDefBut(block, TEX, 0, "", xco+=XIC, yco,100+XIC,20, &ts->name, 0, 30, 0, 0, "Edits the name of this Transform Orientation");
986                 but = uiDefIconBut(block, BUT, B_REDR, ICON_X, xco+=100+XIC,yco,XIC,YIC, 0, 0, 0, 0, 0, "Deletes this Transform Orientation");
987                 uiButSetFunc(but, removeTransformOrientation_func, ts, NULL);
988
989                 xco = 20;
990                 yco -= 25;
991         }
992         uiBlockEndAlign(block);
993         
994         if(yco < 0) uiNewPanelHeight(block, height-yco);
995         uiEndBlock(C, block);
996 }
997
998 static void weight_paint_buttons(Scene *scene, uiBlock *block)
999 {
1000         VPaint *wpaint= scene->toolsettings->wpaint;
1001         Object *ob;
1002         ob= OBACT;
1003         
1004         if(ob==NULL || ob->type!=OB_MESH) return;
1005         
1006         uiBlockBeginAlign(block);
1007         uiDefButF(block, NUMSLI, B_REDR, "Weight:",10,170,225,19, &wpaint->weight, 0, 1, 10, 0, "Sets the current vertex group's bone deformation strength");
1008         
1009         uiDefBut(block, BUT, B_WEIGHT0_0 , "0",                  10,150,45,19, 0, 0, 0, 0, 0, "");
1010         uiDefBut(block, BUT, B_WEIGHT1_4 , "1/4",                55,150,45,19, 0, 0, 0, 0, 0, "");
1011         uiDefBut(block, BUT, B_WEIGHT1_2 , "1/2",                100,150,45,19, 0, 0, 0, 0, 0, "");
1012         uiDefBut(block, BUT, B_WEIGHT3_4 , "3/4",                145,150,45,19, 0, 0, 0, 0, 0, "");
1013         uiDefBut(block, BUT, B_WEIGHT1_0 , "1",                  190,150,45,19, 0, 0, 0, 0, 0, "");
1014         
1015         uiDefButF(block, NUMSLI, B_NOP, "Opacity ",             10,130,225,19, &wpaint->a, 0.0, 1.0, 0, 0, "The amount of pressure on the brush");
1016         
1017         uiDefBut(block, BUT, B_OPA1_8 , "1/8",          10,110,45,19, 0, 0, 0, 0, 0, "");
1018         uiDefBut(block, BUT, B_OPA1_4 , "1/4",          55,110,45,19, 0, 0, 0, 0, 0, "");
1019         uiDefBut(block, BUT, B_OPA1_2 , "1/2",          100,110,45,19, 0, 0, 0, 0, 0, "");
1020         uiDefBut(block, BUT, B_OPA3_4 , "3/4",          145,110,45,19, 0, 0, 0, 0, 0, "");
1021         uiDefBut(block, BUT, B_OPA1_0 , "1",            190,110,45,19, 0, 0, 0, 0, 0, "");
1022         
1023         uiDefButF(block, NUMSLI, B_NOP, "Size ",        10,90,225,19, &wpaint->size, 2.0, 64.0, 0, 0, "The size of the brush");
1024         
1025         uiBlockBeginAlign(block);
1026         uiDefButS(block, ROW, B_NOP, "Mix",             250,170,60,17, &wpaint->mode, 1.0, 0.0, 0, 0, "Mix the vertex colors");
1027         uiDefButS(block, ROW, B_NOP, "Add",             250,152,60,17, &wpaint->mode, 1.0, 1.0, 0, 0, "Add the vertex colors");
1028         uiDefButS(block, ROW, B_NOP, "Sub",             250,134,60,17, &wpaint->mode, 1.0, 2.0, 0, 0, "Subtract from the vertex color");
1029         uiDefButS(block, ROW, B_NOP, "Mul",             250,116,60,17, &wpaint->mode, 1.0, 3.0, 0, 0, "Multiply the vertex color");
1030         uiDefButS(block, ROW, B_NOP, "Blur",            250, 98,60,17, &wpaint->mode, 1.0, 4.0, 0, 0, "Blur the weight with surrounding values");
1031         uiDefButS(block, ROW, B_NOP, "Lighter", 250, 80,60,17, &wpaint->mode, 1.0, 5.0, 0, 0, "Paint over darker areas only");
1032         uiDefButS(block, ROW, B_NOP, "Darker",          250, 62,60,17, &wpaint->mode, 1.0, 6.0, 0, 0, "Paint over lighter areas only");
1033         uiBlockEndAlign(block);
1034         
1035         /* draw options same as below */
1036         uiBlockBeginAlign(block);
1037         if (FACESEL_PAINT_TEST) {
1038                 Mesh *me= ob->data;
1039                 uiDefButBitI(block, TOG, ME_DRAWFACES, B_REDR, "Faces", 10,45,60,19, &me->drawflag, 0, 0, 0, 0, "Displays all faces as shades");
1040                 uiDefButBitI(block,TOG, ME_DRAWEDGES, B_REDR,"Edges",70,45,60,19, &me->drawflag, 2.0, 0, 0, 0,  "Displays edges of visible faces");
1041                 uiDefButBitI(block,TOG, ME_HIDDENEDGES, B_REDR,"Hidden Edges",130,45,100,19, &me->drawflag, 2.0, 1.0, 0, 0,  "Displays edges of hidden faces");
1042         } else{ 
1043                 uiDefButBitC(block, TOG, OB_DRAWWIRE, B_REDR, "Wire",   10,45,75,19, &ob->dtx, 0, 0, 0, 0, "Displays the active object's wireframe in shaded drawing modes");
1044         }
1045         uiBlockEndAlign(block);
1046         
1047         uiBlockBeginAlign(block);
1048         uiDefButBitS(block, TOG, VP_AREA, 0, "All Faces",       10,20,60,19, &wpaint->flag, 0, 0, 0, 0, "Paint on all faces inside brush (otherwise only on face under mouse cursor)");
1049         uiDefButBitS(block, TOG, VP_SOFT, 0, "Vert Dist", 70,20,60,19, &wpaint->flag, 0, 0, 0, 0, "Use distances to vertices (instead of all vertices of face)");
1050         uiDefButBitS(block, TOGN, VP_HARD, 0, "Soft",           130,20,60,19, &wpaint->flag, 0, 0, 0, 0, "Use a soft brush");
1051         uiDefButBitS(block, TOG, VP_NORMALS, 0, "Normals",      190,20,60,19, &wpaint->flag, 0, 0, 0, 0, "Applies the vertex normal before painting");
1052         uiDefButBitS(block, TOG, VP_SPRAY, 0, "Spray",          250,20,55,19, &wpaint->flag, 0, 0, 0, 0, "Keep applying paint effect while holding mouse");
1053         uiBlockEndAlign(block);
1054         
1055         if(ob) {
1056                 uiBlockBeginAlign(block);
1057                 uiDefButBitS(block, TOG, VP_ONLYVGROUP, B_REDR, "Vgroup",               10,0,100,19, &wpaint->flag, 0, 0, 0, 0, "Only paint on vertices in the selected vertex group.");
1058                 uiDefButBitS(block, TOG, VP_MIRROR_X, B_REDR, "X-Mirror",       110,0,100,19, &wpaint->flag, 0, 0, 0, 0, "Mirrored Paint, applying on mirrored Weight Group name");
1059                 uiDefBut(block, BUT, B_CLR_WPAINT, "Clear",                                     210,0,100,19, NULL, 0, 0, 0, 0, "Removes reference to this deform group from all vertices");
1060                 uiBlockEndAlign(block);
1061         }
1062 }
1063
1064 static void sculptmode_draw_interface_tools(Scene *scene, uiBlock *block, unsigned short cx, unsigned short cy)
1065 {
1066 #if 0   
1067         Sculpt *sd= scene->toolsettings->sculpt;
1068         
1069         uiBlockBeginAlign(block);
1070         
1071         uiDefBut(block,LABEL,B_NOP,"Brush",cx,cy,90,19,NULL,0,0,0,0,"");
1072         cy-= 20;
1073         
1074         uiBlockBeginAlign(block);       
1075         uiDefButS(block,ROW,B_REDR,"Draw",cx,cy,67,19,&sd->brush_type,14.0,DRAW_BRUSH,0,0,"Draw lines on the model");
1076         uiDefButS(block,ROW,REDRAWBUTSEDIT,"Smooth",cx+67,cy,67,19,&sd->brush_type,14.0,SMOOTH_BRUSH,0,0,"Interactively smooth areas of the model");
1077         uiDefButS(block,ROW,B_REDR,"Pinch",cx+134,cy,67,19,&sd->brush_type,14.0,PINCH_BRUSH,0,0,"Interactively pinch areas of the model");
1078         uiDefButS(block,ROW,B_REDR,"Inflate",cx+201,cy,67,19,&sd->brush_type,14,INFLATE_BRUSH,0,0,"Push vertices along the direction of their normals");
1079         cy-= 20;
1080         uiDefButS(block,ROW,B_REDR,"Grab", cx,cy,89,19,&sd->brush_type,14,GRAB_BRUSH,0,0,"Grabs a group of vertices and moves them with the mouse");
1081         uiDefButS(block,ROW,B_REDR,"Layer", cx+89,cy,89,19,&sd->brush_type,14, LAYER_BRUSH,0,0,"Adds a layer of depth");
1082         uiDefButS(block,ROW,B_REDR,"Flatten", cx+178,cy,90,19,&sd->brush_type,14, FLATTEN_BRUSH,0,0,"Interactively flatten areas of the model");
1083         cy-= 25;
1084         uiBlockEndAlign(block);
1085         
1086         uiBlockBeginAlign(block);
1087         uiDefBut(block,LABEL,B_NOP,"Shape",cx,cy,90,19,NULL,0,0,0,0,"");
1088         cy-= 20;
1089
1090         uiBlockBeginAlign(block);
1091         if(sd->brush_type != SMOOTH_BRUSH && sd->brush_type != GRAB_BRUSH && sd->brush_type != FLATTEN_BRUSH) {
1092                 uiDefButC(block,ROW,B_NOP,"Add",cx,cy,89,19,&sculptmode_brush()->dir,15.0,1.0,0, 0,"Add depth to model [Shift]");
1093                 uiDefButC(block,ROW,B_NOP,"Sub",cx+89,cy,89,19,&sculptmode_brush()->dir,15.0,2.0,0, 0,"Subtract depth from model [Shift]");
1094         }
1095         if(sd->brush_type!=GRAB_BRUSH)
1096                 uiDefButBitC(block, TOG, SCULPT_BRUSH_AIRBRUSH, B_NOP, "Airbrush", cx+178,cy,89,19, &sculptmode_brush()->flag,0,0,0,0, "Brush makes changes without waiting for the mouse to move");
1097         cy-= 20;
1098         uiDefButS(block,NUMSLI,B_NOP,"Size: ",cx,cy,268,19,&sculptmode_brush()->size,1.0,200.0,0,0,"Set brush radius in pixels");
1099         cy-= 20;
1100         if(sd->brush_type!=GRAB_BRUSH)
1101                 uiDefButC(block,NUMSLI,B_NOP,"Strength: ",cx,cy,268,19,&sculptmode_brush()->strength,1.0,100.0,0,0,"Set brush strength");
1102         cy-= 25;
1103         uiBlockEndAlign(block);
1104         
1105         uiBlockBeginAlign(block);
1106         uiDefBut( block,LABEL,B_NOP,"Symmetry",cx,cy,90,19,NULL,0,0,0,0,"");
1107         cy-= 20;
1108         uiBlockBeginAlign(block);
1109         uiDefButBitC(block, TOG, SYMM_X, B_NOP, "X", cx,cy,40,19, &sd->symm, 0,0,0,0, "Mirror brush across X axis");
1110         uiDefButBitC(block, TOG, SYMM_Y, B_NOP, "Y", cx+40,cy,40,19, &sd->symm, 0,0,0,0, "Mirror brush across Y axis");
1111         uiDefButBitC(block, TOG, SYMM_Z, B_NOP, "Z", cx+80,cy,40,19, &sd->symm, 0,0,0,0, "Mirror brush across Z axis");
1112         uiBlockEndAlign(block);
1113         
1114         
1115         cy+= 20;
1116         uiBlockBeginAlign(block);
1117         uiDefBut( block,LABEL,B_NOP,"LockAxis",cx+140,cy,90,19,NULL,0,0,0,0,"");
1118         cy-= 20;
1119         uiBlockBeginAlign(block);
1120         uiDefButBitC(block, TOG, AXISLOCK_X, B_NOP, "X", cx+140,cy,40,19, &sd->axislock, 0,0,0,0, "Constrain X axis");
1121         uiDefButBitC(block, TOG, AXISLOCK_Y, B_NOP, "Y", cx+180,cy,40,19, &sd->axislock, 0,0,0,0, "Constrain Y axis");
1122         uiDefButBitC(block, TOG, AXISLOCK_Z, B_NOP, "Z", cx+220,cy,40,19, &sd->axislock, 0,0,0,0, "Constrain Z axis");
1123         uiBlockEndAlign(block);
1124                 
1125         cx+= 210;
1126 #endif
1127 }
1128
1129
1130 static void view3d_panel_object(const bContext *C, ARegion *ar, short cntrl)    // VIEW3D_HANDLER_OBJECT
1131 {
1132         Scene *scene= CTX_data_scene(C);
1133         Object *obedit= CTX_data_edit_object(C);
1134         View3D *v3d= CTX_wm_view3d(C);
1135         uiBlock *block;
1136         uiBut *bt;
1137         Object *ob= OBACT;
1138         TransformProperties *tfp;
1139         float lim;
1140         static char hexcol[128];
1141         
1142         if(ob==NULL) return;
1143
1144         /* make sure we got storage */
1145         if(v3d->properties_storage==NULL)
1146                 v3d->properties_storage= MEM_callocN(sizeof(TransformProperties), "TransformProperties");
1147         tfp= v3d->properties_storage;
1148         
1149         block= uiBeginBlock(C, ar, "view3d_panel_object", UI_EMBOSS, UI_HELV);
1150         uiBlockSetHandleFunc(block, do_view3d_region_buttons, NULL);
1151         
1152         if((G.f & G_SCULPTMODE) && !obedit) {
1153                 if(!uiNewPanel(C, ar, block, "Transform Properties", "View3d", 10, 230, 318, 234))
1154                         return;
1155         } else if(G.f & G_PARTICLEEDIT && !obedit){
1156                 if(!uiNewPanel(C, ar, block, "Transform Properties", "View3d", 10, 230, 318, 234))
1157                         return;
1158         } else {
1159                 if(!uiNewPanel(C, ar, block, "Transform Properties", "View3d", 10, 230, 318, 204))
1160                         return;
1161         }
1162
1163 // XXX  uiSetButLock(object_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
1164         
1165         if(G.f & (G_VERTEXPAINT|G_TEXTUREPAINT|G_WEIGHTPAINT)) {
1166         }
1167         else {
1168                 bt= uiDefBut(block, TEX, B_IDNAME, "OB: ",      10,180,140,20, ob->id.name+2, 0.0, 21.0, 0, 0, "");
1169                 uiButSetFunc(bt, test_idbutton_cb, ob->id.name, NULL);
1170
1171                 if((G.f & G_PARTICLEEDIT)==0) {
1172                         uiBlockBeginAlign(block);
1173                         uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_OBJECTPANELPARENT, "Par:", 160, 180, 140, 20, &ob->parent, "Parent Object"); 
1174                         if((ob->parent) && (ob->partype == PARBONE)) {
1175                                 bt= uiDefBut(block, TEX, B_OBJECTPANELPARENT, "ParBone:", 160, 160, 140, 20, ob->parsubstr, 0, 30, 0, 0, "");
1176                                 uiButSetCompleteFunc(bt, autocomplete_bone, (void *)ob->parent);
1177                         }
1178                         else {
1179                                 strcpy(ob->parsubstr, "");
1180                         }
1181                         uiBlockEndAlign(block);
1182                 }
1183         }
1184
1185         lim= 10000.0f*MAX2(1.0, v3d->grid);
1186
1187         if(ob==obedit) {
1188                 if(ob->type==OB_ARMATURE) v3d_editarmature_buts(block, v3d, ob, lim);
1189                 if(ob->type==OB_MBALL) v3d_editmetaball_buts(block, ob, lim);
1190                 else v3d_editvertex_buts(C, block, v3d, ob, lim);
1191         }
1192         else if(ob->flag & OB_POSEMODE) {
1193                 v3d_posearmature_buts(block, v3d, ob, lim);
1194         }
1195         else if(G.f & G_WEIGHTPAINT) {
1196                 uiNewPanelTitle(block, "Weight Paint Properties");
1197                 weight_paint_buttons(scene, block);
1198         }
1199         else if(G.f & (G_VERTEXPAINT|G_TEXTUREPAINT)) {
1200                 static float hsv[3], old[3];    // used as temp mem for picker
1201                 float *rgb= NULL;
1202                 ToolSettings *settings= scene->toolsettings;
1203
1204                 if(G.f & G_VERTEXPAINT) rgb= &settings->vpaint->r;
1205                 else if(settings->imapaint.brush) rgb= settings->imapaint.brush->rgb;
1206                 
1207                 uiNewPanelTitle(block, "Paint Properties");
1208                 if (rgb)
1209                         /* 'f' is for floating panel */
1210                         uiBlockPickerButtons(block, rgb, hsv, old, hexcol, 'f', B_REDR);
1211         }
1212         else if(G.f & G_SCULPTMODE) {
1213                 uiNewPanelTitle(block, "Sculpt Properties");
1214                 sculptmode_draw_interface_tools(scene, block, 10, 150);
1215         } 
1216         else if(G.f & G_PARTICLEEDIT){
1217                 uiNewPanelTitle(block, "Particle Edit Properties");
1218 // XXX          particle_edit_buttons(block);
1219         } 
1220         else {
1221                 BoundBox *bb = NULL;
1222
1223                 uiBlockBeginAlign(block);
1224                 uiDefIconButBitS(block, ICONTOG, OB_LOCK_LOCX, B_REDR, ICON_UNLOCKED,   10,150,20,19, &(ob->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
1225                 uiDefButF(block, NUM, B_OBJECTPANEL, "LocX:",           30, 150, 120, 19, &(ob->loc[0]), -lim, lim, 100, 3, "");
1226                 uiDefIconButBitS(block, ICONTOG, OB_LOCK_LOCY, B_REDR, ICON_UNLOCKED,   10,130,20,19, &(ob->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
1227                 uiDefButF(block, NUM, B_OBJECTPANEL, "LocY:",           30, 130, 120, 19, &(ob->loc[1]), -lim, lim, 100, 3, "");
1228                 uiDefIconButBitS(block, ICONTOG, OB_LOCK_LOCZ, B_REDR, ICON_UNLOCKED,   10,110,20,19, &(ob->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
1229                 uiDefButF(block, NUM, B_OBJECTPANEL, "LocZ:",           30, 110, 120, 19, &(ob->loc[2]), -lim, lim, 100, 3, "");
1230                 
1231                 tfp->ob_eul[0]= 180.0*ob->rot[0]/M_PI;
1232                 tfp->ob_eul[1]= 180.0*ob->rot[1]/M_PI;
1233                 tfp->ob_eul[2]= 180.0*ob->rot[2]/M_PI;
1234                 
1235                 uiBlockBeginAlign(block);
1236                 if ((ob->parent) && (ob->partype == PARBONE)) {
1237                         uiDefIconButBitS(block, ICONTOG, OB_LOCK_ROTX, B_REDR, ICON_UNLOCKED,   160,130,20,19, &(ob->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
1238                         uiDefButF(block, NUM, B_OBJECTPANELROT, "RotX:",        180, 130, 120, 19, &(tfp->ob_eul[0]), -lim, lim, 1000, 3, "");
1239                         uiDefIconButBitS(block, ICONTOG, OB_LOCK_ROTY, B_REDR, ICON_UNLOCKED,   160,110,20,19, &(ob->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
1240                         uiDefButF(block, NUM, B_OBJECTPANELROT, "RotY:",        180, 110, 120, 19, &(tfp->ob_eul[1]), -lim, lim, 1000, 3, "");
1241                         uiDefIconButBitS(block, ICONTOG, OB_LOCK_ROTZ, B_REDR, ICON_UNLOCKED,   160,90,20,19, &(ob->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
1242                         uiDefButF(block, NUM, B_OBJECTPANELROT, "RotZ:",        180, 90, 120, 19, &(tfp->ob_eul[2]), -lim, lim, 1000, 3, "");
1243
1244                 }
1245                 else {
1246                         uiDefIconButBitS(block, ICONTOG, OB_LOCK_ROTX, B_REDR, ICON_UNLOCKED,   160,150,20,19, &(ob->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
1247                         uiDefButF(block, NUM, B_OBJECTPANELROT, "RotX:",        180, 150, 120, 19, &(tfp->ob_eul[0]), -lim, lim, 1000, 3, "");
1248                         uiDefIconButBitS(block, ICONTOG, OB_LOCK_ROTY, B_REDR, ICON_UNLOCKED,   160,130,20,19, &(ob->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
1249                         uiDefButF(block, NUM, B_OBJECTPANELROT, "RotY:",        180, 130, 120, 19, &(tfp->ob_eul[1]), -lim, lim, 1000, 3, "");
1250                         uiDefIconButBitS(block, ICONTOG, OB_LOCK_ROTZ, B_REDR, ICON_UNLOCKED,   160,110,20,19, &(ob->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
1251                         uiDefButF(block, NUM, B_OBJECTPANELROT, "RotZ:",        180, 110, 120, 19, &(tfp->ob_eul[2]), -lim, lim, 1000, 3, "");
1252                 }
1253
1254                 tfp->ob_scale[0]= ob->size[0];
1255                 tfp->ob_scale[1]= ob->size[1];
1256                 tfp->ob_scale[2]= ob->size[2];
1257
1258                 uiBlockBeginAlign(block);
1259                 uiDefIconButBitS(block, ICONTOG, OB_LOCK_SCALEX, B_REDR, ICON_UNLOCKED, 10,80,20,19, &(ob->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
1260                 uiDefButF(block, NUM, B_OBJECTPANELSCALE, "ScaleX:",            30, 80, 120, 19, &(tfp->ob_scale[0]), -lim, lim, 10, 3, "");
1261                 uiDefIconButBitS(block, ICONTOG, OB_LOCK_SCALEY, B_REDR, ICON_UNLOCKED, 10,60,20,19, &(ob->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
1262                 uiDefButF(block, NUM, B_OBJECTPANELSCALE, "ScaleY:",            30, 60, 120, 19, &(tfp->ob_scale[1]), -lim, lim, 10, 3, "");
1263                 uiDefIconButBitS(block, ICONTOG, OB_LOCK_SCALEZ, B_REDR, ICON_UNLOCKED, 10,40,20,19, &(ob->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
1264                 uiDefButF(block, NUM, B_OBJECTPANELSCALE, "ScaleZ:",            30, 40, 120, 19, &(tfp->ob_scale[2]), -lim, lim, 10, 3, "");
1265                 uiBlockEndAlign(block);
1266                 
1267                 uiDefButS(block, TOG, B_REDR, "Link Scale",             10, 10, 140, 19, &(tfp->link_scale), 0, 1, 0, 0, "Scale values vary proportionally in all directions");
1268
1269                 bb= object_get_boundbox(ob);
1270                 if (bb) {
1271                         float scale[3];
1272
1273                         Mat4ToSize(ob->obmat, scale);
1274
1275                         tfp->ob_dims[0] = fabs(scale[0]) * (bb->vec[4][0] - bb->vec[0][0]);
1276                         tfp->ob_dims[1] = fabs(scale[1]) * (bb->vec[2][1] - bb->vec[0][1]);
1277                         tfp->ob_dims[2] = fabs(scale[2]) * (bb->vec[1][2] - bb->vec[0][2]);
1278
1279                         uiBlockBeginAlign(block);
1280                         if ((ob->parent) && (ob->partype == PARBONE)) {
1281                                 uiDefButF(block, NUM, B_OBJECTPANELDIMS, "DimX:",               160, 60, 140, 19, &(tfp->ob_dims[0]), 0.0, lim, 10, 3, "Manipulate bounding box size");
1282                                 uiDefButF(block, NUM, B_OBJECTPANELDIMS, "DimY:",               160, 40, 140, 19, &(tfp->ob_dims[1]), 0.0, lim, 10, 3, "Manipulate bounding box size");
1283                                 uiDefButF(block, NUM, B_OBJECTPANELDIMS, "DimZ:",               160, 20, 140, 19, &(tfp->ob_dims[2]), 0.0, lim, 10, 3, "Manipulate bounding box size");
1284
1285                         }
1286                         else {
1287                                 uiDefButF(block, NUM, B_OBJECTPANELDIMS, "DimX:",               160, 80, 140, 19, &(tfp->ob_dims[0]), 0.0, lim, 10, 3, "Manipulate bounding box size");
1288                                 uiDefButF(block, NUM, B_OBJECTPANELDIMS, "DimY:",               160, 60, 140, 19, &(tfp->ob_dims[1]), 0.0, lim, 10, 3, "Manipulate bounding box size");
1289                                 uiDefButF(block, NUM, B_OBJECTPANELDIMS, "DimZ:",               160, 40, 140, 19, &(tfp->ob_dims[2]), 0.0, lim, 10, 3, "Manipulate bounding box size");
1290                         }
1291
1292                         uiBlockEndAlign(block);
1293                 }
1294         }
1295 // XXX  uiClearButLock();
1296         uiEndBlock(C, block);
1297 }
1298
1299 static void view3d_panel_background(const bContext *C, ARegion *ar, short cntrl)        // VIEW3D_HANDLER_BACKGROUND
1300 {
1301         View3D *v3d= CTX_wm_view3d(C);
1302         uiBlock *block;
1303
1304         block= uiBeginBlock(C, ar, "view3d_panel_background", UI_EMBOSS, UI_HELV);
1305         if(uiNewPanel(C, ar, block, "Background Image", "View3d", 340, 10, 318, 204)==0) return;
1306
1307         if(v3d->flag & V3D_DISPBGPIC) {
1308                 if(v3d->bgpic==NULL) {
1309                         v3d->bgpic= MEM_callocN(sizeof(BGpic), "bgpic");
1310                         v3d->bgpic->size= 5.0;
1311                         v3d->bgpic->blend= 0.5;
1312                         v3d->bgpic->iuser.fie_ima= 2;
1313                         v3d->bgpic->iuser.ok= 1;
1314                 }
1315         }
1316         
1317         if(!(v3d->flag & V3D_DISPBGPIC)) {
1318                 uiDefButBitS(block, TOG, V3D_DISPBGPIC, B_REDR, "Use Background Image", 10, 180, 150, 20, &v3d->flag, 0, 0, 0, 0, "Display an image in the background of this 3D View");
1319                 uiDefBut(block, LABEL, 1, " ",  160, 180, 150, 20, NULL, 0.0, 0.0, 0, 0, "");
1320         }
1321         else {
1322                 uiBlockBeginAlign(block);
1323                 uiDefButBitS(block, TOG, V3D_DISPBGPIC, B_REDR, "Use", 10, 225, 50, 20, &v3d->flag, 0, 0, 0, 0, "Display an image in the background of this 3D View");
1324                 uiDefButF(block, NUMSLI, B_REDR, "Blend:",      60, 225, 150, 20, &v3d->bgpic->blend, 0.0,1.0, 0, 0, "Set the transparency of the background image");
1325                 uiDefButF(block, NUM, B_REDR, "Size:",          210, 225, 100, 20, &v3d->bgpic->size, 0.1, 250.0*v3d->grid, 100, 0, "Set the size (width) of the background image");
1326
1327                 uiDefButF(block, NUM, B_REDR, "X Offset:",      10, 205, 150, 20, &v3d->bgpic->xof, -250.0*v3d->grid,250.0*v3d->grid, 10, 2, "Set the horizontal offset of the background image");
1328                 uiDefButF(block, NUM, B_REDR, "Y Offset:",      160, 205, 150, 20, &v3d->bgpic->yof, -250.0*v3d->grid,250.0*v3d->grid, 10, 2, "Set the vertical offset of the background image");
1329                 
1330 // XXX          uiblock_image_panel(block, &v3d->bgpic->ima, &v3d->bgpic->iuser, B_REDR, B_REDR);
1331                 uiBlockEndAlign(block);
1332         }
1333         uiEndBlock(C, block);
1334 }
1335
1336
1337 static void view3d_panel_properties(const bContext *C, ARegion *ar, short cntrl)        // VIEW3D_HANDLER_SETTINGS
1338 {
1339         ScrArea *sa= CTX_wm_area(C);
1340         ARegion *arlast;
1341         Scene *scene= CTX_data_scene(C);
1342         View3D *v3d= CTX_wm_view3d(C);
1343         RegionView3D *rv3d;
1344         uiBlock *block;
1345         float *curs;
1346
1347         block= uiBeginBlock(C, ar, "view3d_panel_properties", UI_EMBOSS, UI_HELV);
1348         if(uiNewPanel(C, ar, block, "View Properties", "View3d", 340, 30, 318, 254)==0) return;
1349         uiBlockSetHandleFunc(block, do_view3d_region_buttons, NULL);
1350
1351         /* to force height */
1352         uiNewPanelHeight(block, 264);
1353
1354         uiDefBut(block, LABEL, 1, "Grid:",                                      10, 220, 150, 19, NULL, 0.0, 0.0, 0, 0, "");
1355         uiBlockBeginAlign(block);
1356         uiDefButF(block, NUM, B_REDR, "Spacing:",               10, 200, 140, 19, &v3d->grid, 0.001, 100.0, 10, 0, "Set the distance between grid lines");
1357         uiDefButS(block, NUM, B_REDR, "Lines:",         10, 180, 140, 19, &v3d->gridlines, 0.0, 100.0, 100, 0, "Set the number of grid lines in perspective view");
1358         uiDefButS(block, NUM, B_REDR, "Divisions:",             10, 160, 140, 19, &v3d->gridsubdiv, 1.0, 100.0, 100, 0, "Set the number of grid lines");
1359         uiBlockEndAlign(block);
1360
1361         uiDefBut(block, LABEL, 1, "3D Display:",                                                        160, 220, 150, 19, NULL, 0.0, 0.0, 0, 0, "");
1362         uiDefButBitS(block, TOG, V3D_SHOW_FLOOR, B_REDR, "Grid Floor",160, 200, 150, 19, &v3d->gridflag, 0, 0, 0, 0, "Show the grid floor in free camera mode");
1363         uiDefButBitS(block, TOG, V3D_SHOW_X, B_REDR, "X Axis",          160, 176, 48, 19, &v3d->gridflag, 0, 0, 0, 0, "Show the X Axis line");
1364         uiDefButBitS(block, TOG, V3D_SHOW_Y, B_REDR, "Y Axis",          212, 176, 48, 19, &v3d->gridflag, 0, 0, 0, 0, "Show the Y Axis line");
1365         uiDefButBitS(block, TOG, V3D_SHOW_Z, B_REDR, "Z Axis",          262, 176, 48, 19, &v3d->gridflag, 0, 0, 0, 0, "Show the Z Axis line");
1366
1367         uiDefBut(block, LABEL, 1, "View Camera:",                       10, 140, 140, 19, NULL, 0.0, 0.0, 0, 0, "");
1368         
1369         uiDefButF(block, NUM, B_REDR, "Lens:",          10, 120, 140, 19, &v3d->lens, 10.0, 120.0, 100, 0, "The lens angle in perspective view");
1370         uiBlockBeginAlign(block);
1371         uiDefButF(block, NUM, B_REDR, "Clip Start:",    10, 96, 140, 19, &v3d->near, v3d->grid/100.0, 100.0, 10, 0, "Set the beginning of the range in which 3D objects are displayed (perspective view)");
1372         uiDefButF(block, NUM, B_REDR, "Clip End:",      10, 76, 140, 19, &v3d->far, 1.0, 10000.0*v3d->grid, 100, 0, "Set the end of the range in which 3D objects are displayed (perspective view)");
1373         uiBlockEndAlign(block);
1374
1375         uiDefBut(block, LABEL, 1, "3D Cursor:",                         160, 150, 140, 19, NULL, 0.0, 0.0, 0, 0, "");
1376
1377         uiBlockBeginAlign(block);
1378         curs= give_cursor(scene, v3d);
1379         uiDefButF(block, NUM, B_REDR, "X:",                     160, 130, 150, 22, curs, -10000.0*v3d->grid, 10000.0*v3d->grid, 10, 0, "X co-ordinate of the 3D cursor");
1380         uiDefButF(block, NUM, B_REDR, "Y:",                     160, 108, 150, 22, curs+1, -10000.0*v3d->grid, 10000.0*v3d->grid, 10, 0, "Y co-ordinate of the 3D cursor");
1381         uiDefButF(block, NUM, B_REDR, "Z:",                     160, 86, 150, 22, curs+2, -10000.0*v3d->grid, 10000.0*v3d->grid, 10, 0, "Z co-ordinate of the 3D cursor");
1382         uiBlockEndAlign(block);
1383
1384         uiDefBut(block, LABEL, 1, "Display:",                           10, 50, 150, 19, NULL, 0.0, 0.0, 0, 0, "");
1385         uiBlockBeginAlign(block);
1386         uiDefButBitS(block, TOG, V3D_SELECT_OUTLINE, B_REDR, "Outline Selected", 10, 30, 140, 19, &v3d->flag, 0, 0, 0, 0, "Highlight selected objects with an outline, in Solid, Shaded or Textured viewport shading modes");
1387         uiDefButBitS(block, TOG, V3D_DRAW_CENTERS, B_REDR, "All Object Centers", 10, 10, 140, 19, &v3d->flag, 0, 0, 0, 0, "Draw the center points on all objects");
1388         uiDefButBitS(block, TOGN, V3D_HIDE_HELPLINES, B_REDR, "Relationship Lines", 10, -10, 140, 19, &v3d->flag, 0, 0, 0, 0, "Draw dashed lines indicating Parent, Constraint, or Hook relationships");
1389         uiDefButBitS(block, TOG, V3D_SOLID_TEX, B_REDR, "Solid Tex", 10, -30, 140, 19, &v3d->flag2, 0, 0, 0, 0, "Display textures in Solid draw type (Shift T)");
1390         uiBlockEndAlign(block);
1391
1392         uiDefBut(block, LABEL, 1, "View Locking:",                              160, 60, 150, 19, NULL, 0.0, 0.0, 0, 0, "");
1393         uiBlockBeginAlign(block);
1394         uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_REDR, "Object:", 160, 40, 150, 19, &v3d->ob_centre, "Lock view to center to this Object"); 
1395         uiDefBut(block, TEX, B_REDR, "Bone:",                                           160, 20, 150, 19, v3d->ob_centre_bone, 1, 31, 0, 0, "If view locked to Object, use this Bone to lock to view to");
1396         uiBlockEndAlign(block); 
1397
1398         /* last region is always 3d... a bit weak */
1399         arlast= sa->regionbase.last;
1400         uiBlockBeginAlign(block);
1401         if(arlast->alignment==RGN_ALIGN_QSPLIT) {
1402                 arlast= arlast->prev;
1403                 rv3d= arlast->regiondata;
1404                 
1405                 uiDefButO(block, BUT, "SCREEN_OT_region_foursplit", WM_OP_EXEC_REGION_WIN, "End 4-Split View", 160, -10, 150, 19, "Join the 3D View");
1406                 uiDefButBitS(block, TOG, RV3D_LOCKED, B_RV3D_LOCKED, "Lock", 160, -30, 50, 19, &rv3d->viewlock, 0, 0, 0, 0, "");
1407                 uiDefButBitS(block, TOG, RV3D_BOXVIEW, B_RV3D_BOXVIEW, "Box", 210, -30, 50, 19, &rv3d->viewlock, 0, 0, 0, 0, "");
1408                 uiDefButBitS(block, TOG, RV3D_BOXCLIP, B_RV3D_BOXCLIP, "Clip", 260, -30, 50, 19, &rv3d->viewlock, 0, 0, 0, 0, "");
1409         }               
1410         else
1411                 uiDefButO(block, BUT, "SCREEN_OT_region_foursplit", WM_OP_EXEC_REGION_WIN, "4-Split View", 160, -10, 150, 19, "Split 3D View in 4 parts");
1412                 
1413         uiBlockEndAlign(block); 
1414                 
1415         
1416 // XXX
1417 //      uiDefBut(block, LABEL, 1, "Keyframe Display:",                          160, -2, 150, 19, NULL, 0.0, 0.0, 0, 0, "");
1418 //      uiBlockBeginAlign(block);
1419 //      uiDefButBitS(block, TOG, ANIMFILTER_ACTIVE, B_REDR, "Active",160, -22, 50, 19, &v3d->keyflags, 0, 0, 0, 0, "Show keyframes for active element only (i.e. active bone or active material)");
1420 //      uiDefButBitS(block, TOG, ANIMFILTER_MUTED, B_REDR, "Muted",210, -22, 50, 19, &v3d->keyflags, 0, 0, 0, 0, "Show keyframes in muted channels");
1421 //      uiDefButBitS(block, TOG, ANIMFILTER_LOCAL, B_REDR, "Local",260, -22, 50, 19, &v3d->keyflags, 0, 0, 0, 0, "Show keyframes directly connected to datablock");
1422 //      if ((v3d->keyflags & ANIMFILTER_LOCAL)==0) {
1423 //              uiDefButBitS(block, TOGN, ANIMFILTER_NOMAT, B_REDR, "Material",160, -42, 75, 19, &v3d->keyflags, 0, 0, 0, 0, "Show keyframes for any available Materials");
1424 //              uiDefButBitS(block, TOGN, ANIMFILTER_NOSKEY, B_REDR, "ShapeKey",235, -42, 75, 19, &v3d->keyflags, 0, 0, 0, 0, "Show keyframes for any available Shape Keys");
1425 //      }
1426         uiBlockEndAlign(block); 
1427         
1428         uiEndBlock(C, block);
1429 }
1430
1431 #if 0
1432 static void view3d_panel_preview(bContext *C, ARegion *ar, short cntrl) // VIEW3D_HANDLER_PREVIEW
1433 {
1434         uiBlock *block;
1435         View3D *v3d= sa->spacedata.first;
1436         int ofsx, ofsy;
1437         
1438         block= uiBeginBlock(C, ar, "view3d_panel_preview", UI_EMBOSS, UI_HELV);
1439         uiPanelControl(UI_PNL_SOLID | UI_PNL_CLOSE | UI_PNL_SCALE | cntrl);
1440         uiSetPanelHandler(VIEW3D_HANDLER_PREVIEW);  // for close and esc
1441         
1442         ofsx= -150+(sa->winx/2)/v3d->blockscale;
1443         ofsy= -100+(sa->winy/2)/v3d->blockscale;
1444         if(uiNewPanel(C, ar, block, "Preview", "View3d", ofsx, ofsy, 300, 200)==0) return;
1445
1446         uiBlockSetDrawExtraFunc(block, BIF_view3d_previewdraw);
1447         
1448         if(scene->recalc & SCE_PRV_CHANGED) {
1449                 scene->recalc &= ~SCE_PRV_CHANGED;
1450                 //printf("found recalc\n");
1451                 BIF_view3d_previewrender_free(sa->spacedata.first);
1452                 BIF_preview_changed(0);
1453         }
1454 }
1455 #endif
1456
1457 static void view3d_panel_gpencil(const bContext *C, ARegion *ar, short cntrl)   // VIEW3D_HANDLER_GREASEPENCIL
1458 {
1459         View3D *v3d= CTX_wm_view3d(C);
1460         uiBlock *block;
1461
1462         block= uiBeginBlock(C, ar, "view3d_panel_gpencil", UI_EMBOSS, UI_HELV);
1463         if (uiNewPanel(C, ar, block, "Grease Pencil", "View3d", 100, 30, 318, 204)==0) return;
1464
1465         /* allocate memory for gpd if drawing enabled (this must be done first or else we crash) */
1466         if (v3d->flag2 & V3D_DISPGP) {
1467 //              if (v3d->gpd == NULL)
1468 // XXX                  gpencil_data_setactive(ar, gpencil_data_addnew());
1469         }
1470         
1471         if (v3d->flag2 & V3D_DISPGP) {
1472 // XXX          bGPdata *gpd= v3d->gpd;
1473                 short newheight;
1474                 
1475                 /* this is a variable height panel, newpanel doesnt force new size on existing panels */
1476                 /* so first we make it default height */
1477                 uiNewPanelHeight(block, 204);
1478                 
1479                 /* draw button for showing gpencil settings and drawings */
1480                 uiDefButBitS(block, TOG, V3D_DISPGP, B_REDR, "Use Grease Pencil", 10, 225, 150, 20, &v3d->flag2, 0, 0, 0, 0, "Display freehand annotations overlay over this 3D View (draw using Shift-LMB)");
1481                 
1482                 /* extend the panel if the contents won't fit */
1483 //              newheight= draw_gpencil_panel(block, gpd, ar); 
1484                 uiNewPanelHeight(block, newheight);
1485         }
1486         else {
1487                 uiDefButBitS(block, TOG, V3D_DISPGP, B_REDR, "Use Grease Pencil", 10, 225, 150, 20, &v3d->flag2, 0, 0, 0, 0, "Display freehand annotations overlay over this 3D View");
1488                 uiDefBut(block, LABEL, 1, " ",  160, 180, 150, 20, NULL, 0.0, 0.0, 0, 0, "");
1489         }
1490         uiEndBlock(C, block);
1491 }
1492
1493
1494 void view3d_buttons_area_defbuts(const bContext *C, ARegion *ar)
1495 {
1496         
1497         view3d_panel_object(C, ar, 0);
1498         view3d_panel_properties(C, ar, 0);
1499         view3d_panel_background(C, ar, 0);
1500         // XXX view3d_panel_preview(C, ar, 0);
1501         view3d_panel_transform_spaces(C, ar, 0);
1502         if(0)
1503                 view3d_panel_gpencil(C, ar, 0);
1504         
1505         uiDrawPanels(C, 1);             /* 1 = align */
1506         uiMatchPanelsView2d(ar); /* sets v2d->totrct */
1507         
1508 }
1509
1510
1511 static int view3d_properties(bContext *C, wmOperator *op)
1512 {
1513         ScrArea *sa= CTX_wm_area(C);
1514         ARegion *ar= view3d_has_buttons_region(sa);
1515         
1516         if(ar) {
1517                 ar->flag ^= RGN_FLAG_HIDDEN;
1518                 ar->v2d.flag &= ~V2D_IS_INITIALISED; /* XXX should become hide/unhide api? */
1519                 
1520                 ED_area_initialize(CTX_wm_manager(C), CTX_wm_window(C), sa);
1521                 ED_area_tag_redraw(sa);
1522         }
1523         return OPERATOR_FINISHED;
1524 }
1525
1526 void VIEW3D_OT_properties(wmOperatorType *ot)
1527 {
1528         ot->name= "Properties";
1529         ot->idname= "VIEW3D_OT_properties";
1530         
1531         ot->exec= view3d_properties;
1532         ot->poll= ED_operator_view3d_active;
1533         
1534         /* flags */
1535         ot->flag= 0;
1536 }