Added RNA based transform properties for pose bones too.
[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_ID.h"
35 #include "DNA_action_types.h"
36 #include "DNA_armature_types.h"
37 #include "DNA_curve_types.h"
38 #include "DNA_camera_types.h"
39 #include "DNA_gpencil_types.h"
40 #include "DNA_lamp_types.h"
41 #include "DNA_lattice_types.h"
42 #include "DNA_meta_types.h"
43 #include "DNA_mesh_types.h"
44 #include "DNA_meshdata_types.h"
45 #include "DNA_object_types.h"
46 #include "DNA_space_types.h"
47 #include "DNA_scene_types.h"
48 #include "DNA_screen_types.h"
49 #include "DNA_userdef_types.h"
50 #include "DNA_view3d_types.h"
51 #include "DNA_world_types.h"
52
53 #include "MEM_guardedalloc.h"
54
55 #include "BLI_arithb.h"
56 #include "BLI_blenlib.h"
57 #include "BLI_editVert.h"
58 #include "BLI_rand.h"
59
60 #include "BKE_action.h"
61 #include "BKE_brush.h"
62 #include "BKE_context.h"
63 #include "BKE_curve.h"
64 #include "BKE_customdata.h"
65 #include "BKE_depsgraph.h"
66 #include "BKE_idprop.h"
67 #include "BKE_mesh.h"
68 #include "BKE_object.h"
69 #include "BKE_global.h"
70 #include "BKE_scene.h"
71 #include "BKE_screen.h"
72 #include "BKE_utildefines.h"
73
74 #include "BIF_gl.h"
75
76 #include "WM_api.h"
77 #include "WM_types.h"
78
79 #include "RNA_access.h"
80 #include "RNA_define.h"
81
82 #include "ED_armature.h"
83 #include "ED_curve.h"
84 #include "ED_image.h"
85 #include "ED_gpencil.h"
86 #include "ED_keyframing.h"
87 #include "ED_mesh.h"
88 #include "ED_object.h"
89 #include "ED_particle.h"
90 #include "ED_screen.h"
91 #include "ED_transform.h"
92 #include "ED_types.h"
93 #include "ED_util.h"
94
95 #include "UI_interface.h"
96 #include "UI_resources.h"
97 #include "UI_view2d.h"
98
99 #include "view3d_intern.h"      // own include
100
101
102 /* ******************* view3d space & buttons ************** */
103 #define B_NOP           1
104 #define B_REDR          2
105 #define B_OBJECTPANELROT        1007
106 #define B_OBJECTPANELMEDIAN 1008
107 #define B_ARMATUREPANEL1        1009
108 #define B_ARMATUREPANEL2        1010
109 #define B_OBJECTPANELPARENT 1011
110 #define B_OBJECTPANEL           1012
111 #define B_ARMATUREPANEL3        1013
112 #define B_OBJECTPANELSCALE      1014
113 #define B_OBJECTPANELDIMS       1015
114 #define B_TRANSFORMSPACEADD     1016
115 #define B_TRANSFORMSPACECLEAR   1017
116 #define B_SETPT_AUTO    2125
117 #define B_SETPT_VECTOR  2126
118 #define B_SETPT_ALIGN   2127
119 #define B_SETPT_FREE    2128
120 #define B_RECALCMBALL   2501
121
122 #define B_WEIGHT0_0             2840
123 #define B_WEIGHT1_4             2841
124 #define B_WEIGHT1_2             2842
125 #define B_WEIGHT3_4             2843
126 #define B_WEIGHT1_0             2844
127
128 #define B_OPA1_8                2845
129 #define B_OPA1_4                2846
130 #define B_OPA1_2                2847
131 #define B_OPA3_4                2848
132 #define B_OPA1_0                2849
133
134 #define B_CLR_WPAINT    2850
135
136 #define B_RV3D_LOCKED   2900
137 #define B_RV3D_BOXVIEW  2901
138 #define B_RV3D_BOXCLIP  2902
139
140 #define B_IDNAME                3000
141
142 /* temporary struct for storing transform properties */
143 typedef struct {
144         float ob_eul[4];        // used for quat too....
145         float ob_scale[3]; // need temp space due to linked values
146         float ob_dims[3];
147         short link_scale;
148         float ve_median[5];
149         int curdef;
150         float *defweightp;
151 } TransformProperties;
152
153
154 /* is used for both read and write... */
155 static void v3d_editvertex_buts(const bContext *C, uiLayout *layout, View3D *v3d, Object *ob, float lim)
156 {
157         uiBlock *block= (layout)? uiLayoutAbsoluteBlock(layout): NULL;
158         MDeformVert *dvert=NULL;
159         TransformProperties *tfp= v3d->properties_storage;
160         float median[5], ve_median[5];
161         int tot, totw, totweight, totedge;
162         char defstr[320];
163         
164         median[0]= median[1]= median[2]= median[3]= median[4]= 0.0;
165         tot= totw= totweight= totedge= 0;
166         defstr[0]= 0;
167
168         if(ob->type==OB_MESH) {
169                 Mesh *me= ob->data;
170                 EditMesh *em = BKE_mesh_get_editmesh(me);
171                 EditVert *eve, *evedef=NULL;
172                 EditEdge *eed;
173                 
174                 eve= em->verts.first;
175                 while(eve) {
176                         if(eve->f & SELECT) {
177                                 evedef= eve;
178                                 tot++;
179                                 VecAddf(median, median, eve->co);
180                         }
181                         eve= eve->next;
182                 }
183                 eed= em->edges.first;
184                 while(eed) {
185                         if((eed->f & SELECT)) {
186                                 totedge++;
187                                 median[3]+= eed->crease;
188                         }
189                         eed= eed->next;
190                 }
191
192                 /* check for defgroups */
193                 if(evedef)
194                         dvert= CustomData_em_get(&em->vdata, evedef->data, CD_MDEFORMVERT);
195                 if(tot==1 && dvert && dvert->totweight) {
196                         bDeformGroup *dg;
197                         int i, max=1, init=1;
198                         char str[320];
199                         
200                         for (i=0; i<dvert->totweight; i++){
201                                 dg = BLI_findlink (&ob->defbase, dvert->dw[i].def_nr);
202                                 if(dg) {
203                                         max+= BLI_snprintf(str, sizeof(str), "%s %%x%d|", dg->name, dvert->dw[i].def_nr); 
204                                         if(max<320) strcat(defstr, str);
205                                 }
206                                 else printf("oh no!\n");
207                                 if(tfp->curdef==dvert->dw[i].def_nr) {
208                                         init= 0;
209                                         tfp->defweightp= &dvert->dw[i].weight;
210                                 }
211                         }
212                         
213                         if(init) {      // needs new initialized 
214                                 tfp->curdef= dvert->dw[0].def_nr;
215                                 tfp->defweightp= &dvert->dw[0].weight;
216                         }
217                 }
218
219                 BKE_mesh_end_editmesh(me, em);
220         }
221         else if(ob->type==OB_CURVE || ob->type==OB_SURF) {
222                 Curve *cu= ob->data;
223                 Nurb *nu;
224                 BPoint *bp;
225                 BezTriple *bezt;
226                 int a;
227                 
228                 nu= cu->editnurb->first;
229                 while(nu) {
230                         if(nu->type == CU_BEZIER) {
231                                 bezt= nu->bezt;
232                                 a= nu->pntsu;
233                                 while(a--) {
234                                         if(bezt->f2 & SELECT) {
235                                                 VecAddf(median, median, bezt->vec[1]);
236                                                 tot++;
237                                                 median[4]+= bezt->weight;
238                                                 totweight++;
239                                         }
240                                         else {
241                                                 if(bezt->f1 & SELECT) {
242                                                         VecAddf(median, median, bezt->vec[0]);
243                                                         tot++;
244                                                 }
245                                                 if(bezt->f3 & SELECT) {
246                                                         VecAddf(median, median, bezt->vec[2]);
247                                                         tot++;
248                                                 }
249                                         }
250                                         bezt++;
251                                 }
252                         }
253                         else {
254                                 bp= nu->bp;
255                                 a= nu->pntsu*nu->pntsv;
256                                 while(a--) {
257                                         if(bp->f1 & SELECT) {
258                                                 VecAddf(median, median, bp->vec);
259                                                 median[3]+= bp->vec[3];
260                                                 totw++;
261                                                 tot++;
262                                                 median[4]+= bp->weight;
263                                                 totweight++;
264                                         }
265                                         bp++;
266                                 }
267                         }
268                         nu= nu->next;
269                 }
270         }
271         else if(ob->type==OB_LATTICE) {
272                 Lattice *lt= ob->data;
273                 BPoint *bp;
274                 int a;
275                 
276                 a= lt->editlatt->pntsu*lt->editlatt->pntsv*lt->editlatt->pntsw;
277                 bp= lt->editlatt->def;
278                 while(a--) {
279                         if(bp->f1 & SELECT) {
280                                 VecAddf(median, median, bp->vec);
281                                 tot++;
282                                 median[4]+= bp->weight;
283                                 totweight++;
284                         }
285                         bp++;
286                 }
287         }
288         
289         if(tot==0) return;
290
291         median[0] /= (float)tot;
292         median[1] /= (float)tot;
293         median[2] /= (float)tot;
294         if(totedge) median[3] /= (float)totedge;
295         else if(totw) median[3] /= (float)totw;
296         if(totweight) median[4] /= (float)totweight;
297         
298         if(v3d->flag & V3D_GLOBAL_STATS)
299                 Mat4MulVecfl(ob->obmat, median);
300         
301         if(block) {     // buttons
302                 int but_y;
303                 if((ob->parent) && (ob->partype == PARBONE))    but_y = 135;
304                 else                                                                                    but_y = 150;
305                 
306                 
307                 
308                 memcpy(tfp->ve_median, median, sizeof(tfp->ve_median));
309                 
310                 uiBlockBeginAlign(block);
311                 if(tot==1) {
312                         uiDefBut(block, LABEL, 0, "Vertex:",                                    0, 130, 200, 20, 0, 0, 0, 0, 0, "");
313                         uiBlockBeginAlign(block);
314                         uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "X:",                0, 110, 200, 20, &(tfp->ve_median[0]), -lim, lim, 10, 3, "");
315                         uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Y:",                0, 90, 200, 20, &(tfp->ve_median[1]), -lim, lim, 10, 3, "");
316                         uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Z:",                0, 70, 200, 20, &(tfp->ve_median[2]), -lim, lim, 10, 3, "");
317                         
318                         if(totw==1) {
319                                 uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "W:",        0, 50, 200, 20, &(tfp->ve_median[3]), 0.01, 100.0, 10, 3, "");
320                                 uiBlockBeginAlign(block);
321                                 uiDefButBitS(block, TOG, V3D_GLOBAL_STATS, B_REDR, "Global",            0, 25, 100, 20, &v3d->flag, 0, 0, 0, 0, "Displays global values");
322                                 uiDefButBitS(block, TOGN, V3D_GLOBAL_STATS, B_REDR, "Local",            100, 25, 100, 20, &v3d->flag, 0, 0, 0, 0, "Displays local values");
323                                 uiBlockEndAlign(block);
324                                 if(totweight)
325                                         uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Weight:",   0, 0, 200, 20, &(tfp->ve_median[4]), 0.0, 1.0, 10, 3, "");
326                                 }
327                         else {
328                                 uiBlockBeginAlign(block);
329                                 uiDefButBitS(block, TOG, V3D_GLOBAL_STATS, B_REDR, "Global",            0, 45, 100, 20, &v3d->flag, 0, 0, 0, 0, "Displays global values");
330                                 uiDefButBitS(block, TOGN, V3D_GLOBAL_STATS, B_REDR, "Local",            100, 45, 100, 20, &v3d->flag, 0, 0, 0, 0, "Displays local values");
331                                 uiBlockEndAlign(block);
332                                 if(totweight)
333                                         uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Weight:",   0, 20, 200, 20, &(tfp->ve_median[4]), 0.0, 1.0, 10, 3, "");
334                         }
335                 }
336                 else {
337                         uiDefBut(block, LABEL, 0, "Median:",                                    0, 130, 200, 20, 0, 0, 0, 0, 0, "");
338                         uiBlockBeginAlign(block);
339                         uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "X:",                0, 110, 200, 20, &(tfp->ve_median[0]), -lim, lim, 10, 3, "");
340                         uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Y:",                0, 90, 200, 20, &(tfp->ve_median[1]), -lim, lim, 10, 3, "");
341                         uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Z:",                0, 70, 200, 20, &(tfp->ve_median[2]), -lim, lim, 10, 3, "");
342                         if(totw==tot) {
343                                 uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "W:",        0, 50, 200, 20, &(tfp->ve_median[3]), 0.01, 100.0, 10, 3, "");
344                                 uiBlockEndAlign(block);
345                                 uiBlockBeginAlign(block);
346                                 uiDefButBitS(block, TOG, V3D_GLOBAL_STATS, B_REDR, "Global",            0, 25, 100, 20, &v3d->flag, 0, 0, 0, 0, "Displays global values");
347                                 uiDefButBitS(block, TOGN, V3D_GLOBAL_STATS, B_REDR, "Local",            100, 25, 100, 20, &v3d->flag, 0, 0, 0, 0, "Displays local values");
348                                 uiBlockEndAlign(block);
349                                 if(totweight)
350                                         uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Weight:",   0, 0, 200, 20, &(tfp->ve_median[4]), 0.0, 1.0, 10, 3, "Weight is used for SoftBody Goal");
351                                 uiBlockEndAlign(block);
352                         }
353                         else {
354                                 uiBlockBeginAlign(block);
355                                 uiDefButBitS(block, TOG, V3D_GLOBAL_STATS, B_REDR, "Global",            0, 45, 100, 20, &v3d->flag, 0, 0, 0, 0, "Displays global values");
356                                 uiDefButBitS(block, TOGN, V3D_GLOBAL_STATS, B_REDR, "Local",            100, 45, 100, 20, &v3d->flag, 0, 0, 0, 0, "Displays local values");
357                                 uiBlockEndAlign(block);
358                                 if(totweight)
359                                         uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Weight:",   0, 20, 200, 20, &(tfp->ve_median[4]), 0.0, 1.0, 10, 3, "Weight is used for SoftBody Goal");
360                                 uiBlockEndAlign(block);
361                         }
362                 }
363                                 
364                 if(totedge==1)
365                         uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Crease:",   0, 20, 200, 20, &(tfp->ve_median[3]), 0.0, 1.0, 10, 3, "");
366                 else if(totedge>1)
367                         uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Median Crease:",    0, 20, 200, 20, &(tfp->ve_median[3]), 0.0, 1.0, 10, 3, "");
368                 
369         }
370         else {  // apply
371                 memcpy(ve_median, tfp->ve_median, sizeof(tfp->ve_median));
372                 
373                 if(v3d->flag & V3D_GLOBAL_STATS) {
374                         Mat4Invert(ob->imat, ob->obmat);
375                         Mat4MulVecfl(ob->imat, median);
376                         Mat4MulVecfl(ob->imat, ve_median);
377                 }
378                 VecSubf(median, ve_median, median);
379                 median[3]= ve_median[3]-median[3];
380                 median[4]= ve_median[4]-median[4];
381                 
382                 if(ob->type==OB_MESH) {
383                         Mesh *me= ob->data;
384                         EditMesh *em = BKE_mesh_get_editmesh(me);
385                         EditVert *eve;
386                         EditEdge *eed;
387                         
388                         eve= em->verts.first;
389                         while(eve) {
390                                 if(eve->f & SELECT) {
391                                         VecAddf(eve->co, eve->co, median);
392                                 }
393                                 eve= eve->next;
394                         }
395                         
396                         for(eed= em->edges.first; eed; eed= eed->next) {
397                                 if(eed->f & SELECT) {
398                                         /* ensure the median can be set to zero or one */
399                                         if(ve_median[3]==0.0f) eed->crease= 0.0f;
400                                         else if(ve_median[3]==1.0f) eed->crease= 1.0f;
401                                         else {
402                                                 eed->crease+= median[3];
403                                                 CLAMP(eed->crease, 0.0, 1.0);
404                                         }
405                                 }
406                         }
407                         
408                         recalc_editnormals(em);
409
410                         BKE_mesh_end_editmesh(me, em);
411                 }
412                 else if(ob->type==OB_CURVE || ob->type==OB_SURF) {
413                         Curve *cu= ob->data;
414                         Nurb *nu;
415                         BPoint *bp;
416                         BezTriple *bezt;
417                         int a;
418                         
419                         nu= cu->editnurb->first;
420                         while(nu) {
421                                 if(nu->type == CU_BEZIER) {
422                                         bezt= nu->bezt;
423                                         a= nu->pntsu;
424                                         while(a--) {
425                                                 if(bezt->f2 & SELECT) {
426                                                         VecAddf(bezt->vec[0], bezt->vec[0], median);
427                                                         VecAddf(bezt->vec[1], bezt->vec[1], median);
428                                                         VecAddf(bezt->vec[2], bezt->vec[2], median);
429                                                         bezt->weight+= median[4];
430                                                 }
431                                                 else {
432                                                         if(bezt->f1 & SELECT) {
433                                                                 VecAddf(bezt->vec[0], bezt->vec[0], median);
434                                                         }
435                                                         if(bezt->f3 & SELECT) {
436                                                                 VecAddf(bezt->vec[2], bezt->vec[2], median);
437                                                         }
438                                                 }
439                                                 bezt++;
440                                         }
441                                 }
442                                 else {
443                                         bp= nu->bp;
444                                         a= nu->pntsu*nu->pntsv;
445                                         while(a--) {
446                                                 if(bp->f1 & SELECT) {
447                                                         VecAddf(bp->vec, bp->vec, median);
448                                                         bp->vec[3]+= median[3];
449                                                         bp->weight+= median[4];
450                                                 }
451                                                 bp++;
452                                         }
453                                 }
454                                 test2DNurb(nu);
455                                 testhandlesNurb(nu); /* test for bezier too */
456
457                                 nu= nu->next;
458                         }
459                 }
460                 else if(ob->type==OB_LATTICE) {
461                         Lattice *lt= ob->data;
462                         BPoint *bp;
463                         int a;
464                         
465                         a= lt->editlatt->pntsu*lt->editlatt->pntsv*lt->editlatt->pntsw;
466                         bp= lt->editlatt->def;
467                         while(a--) {
468                                 if(bp->f1 & SELECT) {
469                                         VecAddf(bp->vec, bp->vec, median);
470                                         bp->weight+= median[4];
471                                 }
472                                 bp++;
473                         }
474                 }
475                 
476 //              ED_undo_push(C, "Transform properties");
477         }
478 }
479
480 #if 0
481 /* assumes armature active */
482 static void validate_bonebutton_cb(bContext *C, void *bonev, void *namev)
483 {
484         Object *ob= CTX_data_active_object(C);
485         
486         if(ob && ob->type==OB_ARMATURE) {
487                 Bone *bone= bonev;
488                 char oldname[32], newname[32];
489                 
490                 /* need to be on the stack */
491                 BLI_strncpy(newname, bone->name, 32);
492                 BLI_strncpy(oldname, (char *)namev, 32);
493                 /* restore */
494                 BLI_strncpy(bone->name, oldname, 32);
495                 
496                 ED_armature_bone_rename(ob->data, oldname, newname); // editarmature.c
497         }
498 }
499 #endif
500
501 static void v3d_transform_butsR(uiLayout *layout, PointerRNA *ptr)
502 {
503         uiLayout *split, *colsub;
504         
505         split = uiLayoutSplit(layout, 0.8);
506         
507         if (ptr->type == &RNA_PoseChannel) {
508                 PointerRNA boneptr;
509                 Bone *bone;
510                 
511                 boneptr = RNA_pointer_get(ptr, "bone");
512                 bone = boneptr.data;
513                 uiLayoutSetActive(split, !(bone->parent && bone->flag & BONE_CONNECTED));
514         }
515         colsub = uiLayoutColumn(split, 1);
516         uiItemR(colsub, "Location", 0, ptr, "location", 0);
517         colsub = uiLayoutColumn(split, 1);
518         uiItemL(colsub, "", 0);
519         uiItemR(colsub, "", ICON_LOCKED, ptr, "lock_location", UI_ITEM_R_TOGGLE+UI_ITEM_R_ICON_ONLY);
520         
521         split = uiLayoutSplit(layout, 0.8);
522         
523         switch(RNA_enum_get(ptr, "rotation_mode")) {
524                 case ROT_MODE_XYZ:
525                 case ROT_MODE_XZY:
526                 case ROT_MODE_YXZ:
527                 case ROT_MODE_YZX:
528                 case ROT_MODE_ZXY:
529                 case ROT_MODE_ZYX:
530                         colsub = uiLayoutColumn(split, 1);
531                         uiItemR(colsub, "Rotation", 0, ptr, "rotation_euler", 0);
532                         colsub = uiLayoutColumn(split, 1);
533                         uiItemL(colsub, "", 0);
534                         uiItemR(colsub, "", ICON_LOCKED, ptr, "lock_rotation", UI_ITEM_R_TOGGLE+UI_ITEM_R_ICON_ONLY);
535                         break;
536                 case ROT_MODE_QUAT:
537                         colsub = uiLayoutColumn(split, 1);
538                         uiItemR(colsub, "Rotation", 0, ptr, "rotation_quaternion", 0);
539                         colsub = uiLayoutColumn(split, 1);
540                         uiItemR(colsub, "W", 0, ptr, "lock_rotations_4d", UI_ITEM_R_TOGGLE);
541                         if (RNA_boolean_get(ptr, "lock_rotations_4d"))
542                                 uiItemR(colsub, "", ICON_LOCKED, ptr, "lock_rotation_w", UI_ITEM_R_TOGGLE+UI_ITEM_R_ICON_ONLY);
543                         else
544                                 uiItemL(colsub, "", 0);
545                         uiItemR(colsub, "", ICON_LOCKED, ptr, "lock_rotation", UI_ITEM_R_TOGGLE+UI_ITEM_R_ICON_ONLY);
546                         break;
547                 case ROT_MODE_AXISANGLE:
548                         colsub = uiLayoutColumn(split, 1);
549                         uiItemR(colsub, "Rotation", 0, ptr, "rotation_axis_angle", 0);
550                         colsub = uiLayoutColumn(split, 1);
551                         uiItemR(colsub, "W", 0, ptr, "lock_rotations_4d", UI_ITEM_R_TOGGLE);
552                         if (RNA_boolean_get(ptr, "lock_rotations_4d"))
553                                 uiItemR(colsub, "", ICON_LOCKED, ptr, "lock_rotation_w", UI_ITEM_R_TOGGLE+UI_ITEM_R_ICON_ONLY);
554                         else
555                                 uiItemL(colsub, "", 0);
556                         uiItemR(colsub, "", ICON_LOCKED, ptr, "lock_rotation", UI_ITEM_R_TOGGLE+UI_ITEM_R_ICON_ONLY);
557                         break;
558         }
559         uiItemR(layout, "", 0, ptr, "rotation_mode", 0);
560         
561         split = uiLayoutSplit(layout, 0.8);
562         colsub = uiLayoutColumn(split, 1);
563         uiItemR(colsub, "Scale", 0, ptr, "scale", 0);
564         colsub = uiLayoutColumn(split, 1);
565         uiItemL(colsub, "", 0);
566         uiItemR(colsub, "", ICON_LOCKED, ptr, "lock_scale", UI_ITEM_R_TOGGLE+UI_ITEM_R_ICON_ONLY);
567         
568         if (ptr->type == &RNA_Object) {
569                 Object *ob = ptr->data;
570                 if (ELEM5(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_MBALL))
571                         uiItemR(layout, "Dimensions", 0, ptr, "dimensions", 0);
572         }
573 }
574
575 static void v3d_posearmature_buts(uiLayout *layout, View3D *v3d, Object *ob, float lim)
576 {
577         uiBlock *block= uiLayoutGetBlock(layout);
578         bArmature *arm;
579         bPoseChannel *pchan;
580         Bone *bone= NULL;
581         TransformProperties *tfp= v3d->properties_storage;
582         PointerRNA pchanptr;
583         uiLayout *row, *col;
584
585         arm = ob->data;
586         if (!arm || !ob->pose) return;
587
588         for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
589                 bone = pchan->bone;
590                 if(bone && (bone->flag & BONE_ACTIVE) && (bone->layer & arm->layer))
591                         break;
592         }
593         if (!pchan)     {
594                 row= uiLayoutRow(layout, 0);
595                 uiItemL(row, "No Active Bone", 0);
596                 return; 
597         }
598         row= uiLayoutRow(layout, 0);
599         
600         RNA_pointer_create(&ob->id, &RNA_PoseChannel, pchan, &pchanptr);
601         
602         uiItemL(row, "", ICON_BONE_DATA);
603         uiItemR(row, "", 0, &pchanptr, "name", 0);
604
605         col= uiLayoutColumn(layout, 0);
606         
607         /* XXX: RNA buts show data in native types (i.e. quats, 4-component axis/angle, etc.)
608          * but oldskool UI shows in eulers always. Do we want to be able to still display in Eulers?
609          * Maybe needs RNA/ui options to display rotations as different types... */
610         v3d_transform_butsR(col, &pchanptr);
611
612 #if 0
613         uiLayoutAbsoluteBlock(layout);
614
615         if (pchan->rotmode == ROT_MODE_AXISANGLE) {
616                 float quat[4];
617                 /* convert to euler, passing through quats... */
618                 AxisAngleToQuat(quat, pchan->rotAxis, pchan->rotAngle);
619                 QuatToEul(quat, tfp->ob_eul);
620         }
621         else if (pchan->rotmode == ROT_MODE_QUAT)
622                 QuatToEul(pchan->quat, tfp->ob_eul);
623         else
624                 VecCopyf(tfp->ob_eul, pchan->eul);
625         tfp->ob_eul[0]*= 180.0/M_PI;
626         tfp->ob_eul[1]*= 180.0/M_PI;
627         tfp->ob_eul[2]*= 180.0/M_PI;
628         
629         uiDefBut(block, LABEL, 0, "Location:",                  0, 240, 100, 20, 0, 0, 0, 0, 0, "");
630         uiBlockBeginAlign(block);
631         uiDefButF(block, NUM, B_ARMATUREPANEL2, "X:",   0, 220, 120, 19, pchan->loc, -lim, lim, 100, 3, "");
632         uiDefButF(block, NUM, B_ARMATUREPANEL2, "Y:",   0, 200, 120, 19, pchan->loc+1, -lim, lim, 100, 3, "");
633         uiDefButF(block, NUM, B_ARMATUREPANEL2, "Z:",   0, 180, 120, 19, pchan->loc+2, -lim, lim, 100, 3, "");
634         uiBlockEndAlign(block);
635         
636         uiBlockBeginAlign(block);
637         uiDefIconButBitS(block, ICONTOG, OB_LOCK_LOCX, B_REDR, ICON_UNLOCKED,   125, 220, 25, 19, &(pchan->protectflag), 0, 0, 0, 0, "Protects X Location value from being Transformed");
638         uiDefIconButBitS(block, ICONTOG, OB_LOCK_LOCY, B_REDR, ICON_UNLOCKED,   125, 200, 25, 19, &(pchan->protectflag), 0, 0, 0, 0, "Protects Y Location value from being Transformed");
639         uiDefIconButBitS(block, ICONTOG, OB_LOCK_LOCZ, B_REDR, ICON_UNLOCKED,   125, 180, 25, 19, &(pchan->protectflag), 0, 0, 0, 0, "Protects Z Location value from being Transformed");
640         uiBlockEndAlign(block);
641         
642         uiDefBut(block, LABEL, 0, "Rotation:",                  0, 160, 100, 20, 0, 0, 0, 0, 0, "");
643         uiBlockBeginAlign(block);
644         uiDefButF(block, NUM, B_ARMATUREPANEL3, "X:",   0, 140, 120, 19, tfp->ob_eul, -1000.0, 1000.0, 100, 3, "");
645         uiDefButF(block, NUM, B_ARMATUREPANEL3, "Y:",   0, 120, 120, 19, tfp->ob_eul+1, -1000.0, 1000.0, 100, 3, "");
646         uiDefButF(block, NUM, B_ARMATUREPANEL3, "Z:",   0, 100, 120, 19, tfp->ob_eul+2, -1000.0, 1000.0, 100, 3, "");
647         uiBlockEndAlign(block);
648         
649         uiBlockBeginAlign(block);
650         uiDefIconButBitS(block, ICONTOG, OB_LOCK_ROTX, B_REDR, ICON_UNLOCKED,   125, 140, 25, 19, &(pchan->protectflag), 0, 0, 0, 0, "Protects X Rotation value from being Transformed");
651         uiDefIconButBitS(block, ICONTOG, OB_LOCK_ROTY, B_REDR, ICON_UNLOCKED,   125, 120, 25, 19, &(pchan->protectflag), 0, 0, 0, 0, "Protects Y Rotation value from being Transformed");
652         uiDefIconButBitS(block, ICONTOG, OB_LOCK_ROTZ, B_REDR, ICON_UNLOCKED,   125, 100, 25, 19, &(pchan->protectflag), 0, 0, 0, 0, "Protects Z Rotation value from being Transformed");
653         uiBlockEndAlign(block);
654         
655         uiDefBut(block, LABEL, 0, "Scale:",                             0, 80, 100, 20, 0, 0, 0, 0, 0, "");
656         uiBlockBeginAlign(block);
657         uiDefButF(block, NUM, B_ARMATUREPANEL2, "X:",   0, 60, 120, 19, pchan->size, -lim, lim, 10, 3, "");
658         uiDefButF(block, NUM, B_ARMATUREPANEL2, "Y:",   0, 40, 120, 19, pchan->size+1, -lim, lim, 10, 3, "");
659         uiDefButF(block, NUM, B_ARMATUREPANEL2, "Z:",   0, 20, 120, 19, pchan->size+2, -lim, lim, 10, 3, "");
660         uiBlockEndAlign(block);
661         
662         uiBlockBeginAlign(block);
663         uiDefIconButBitS(block, ICONTOG, OB_LOCK_SCALEX, B_REDR, ICON_UNLOCKED, 125, 60, 25, 19, &(pchan->protectflag), 0, 0, 0, 0, "Protects X Scale value from being Transformed");
664         uiDefIconButBitS(block, ICONTOG, OB_LOCK_SCALEY, B_REDR, ICON_UNLOCKED, 125, 40, 25, 19, &(pchan->protectflag), 0, 0, 0, 0, "Protects Y Scale value from being Transformed");
665         uiDefIconButBitS(block, ICONTOG, OB_LOCK_SCALEZ, B_REDR, ICON_UNLOCKED, 125, 20, 25, 19, &(pchan->protectflag), 0, 0, 0, 0, "Protects z Scale value from being Transformed");
666         uiBlockEndAlign(block);
667 #endif
668 }
669
670 /* assumes armature editmode */
671 void validate_editbonebutton_cb(bContext *C, void *bonev, void *namev)
672 {
673         EditBone *eBone= bonev;
674         char oldname[32], newname[32];
675         
676         /* need to be on the stack */
677         BLI_strncpy(newname, eBone->name, 32);
678         BLI_strncpy(oldname, (char *)namev, 32);
679         /* restore */
680         BLI_strncpy(eBone->name, oldname, 32);
681         
682         ED_armature_bone_rename(CTX_data_edit_object(C)->data, oldname, newname); // editarmature.c
683         WM_event_add_notifier(C, NC_OBJECT|ND_BONE_SELECT, CTX_data_edit_object(C)); // XXX fix
684 }
685
686 static void v3d_editarmature_buts(uiLayout *layout, View3D *v3d, Object *ob, float lim)
687 {
688         uiBlock *block= uiLayoutGetBlock(layout);
689         bArmature *arm= ob->data;
690         EditBone *ebone;
691         TransformProperties *tfp= v3d->properties_storage;
692         uiLayout *row;
693         PointerRNA eboneptr;
694         
695         ebone= arm->edbo->first;
696
697         for (ebone = arm->edbo->first; ebone; ebone=ebone->next){
698                 if ((ebone->flag & BONE_ACTIVE) && (ebone->layer & arm->layer))
699                         break;
700         }
701
702         if (!ebone)
703                 return;
704         
705         row= uiLayoutRow(layout, 0);
706         RNA_pointer_create(&arm->id, &RNA_EditBone, ebone, &eboneptr);
707         uiItemL(row, "", ICON_BONE_DATA);
708         uiItemR(row, "", 0, &eboneptr, "name", 0);
709
710         uiLayoutAbsoluteBlock(layout);
711         
712         uiDefBut(block, LABEL, 0, "Head:",                                      0, 210, 100, 20, 0, 0, 0, 0, 0, "");
713         uiBlockBeginAlign(block);
714         uiDefButF(block, NUM, B_ARMATUREPANEL1, "X:",           0, 190, 100, 19, ebone->head, -lim, lim, 10, 3, "X Location of the head end of the bone");
715         uiDefButF(block, NUM, B_ARMATUREPANEL1, "Y:",           0, 170, 100, 19, ebone->head+1, -lim, lim, 10, 3, "Y Location of the head end of the bone");
716         uiDefButF(block, NUM, B_ARMATUREPANEL1, "Z:",           0, 150, 100, 19, ebone->head+2, -lim, lim, 10, 3, "Z Location of the head end of the bone");
717         if (ebone->parent && ebone->flag & BONE_CONNECTED )
718                 uiDefButF(block, NUM, B_ARMATUREPANEL1, "Radius:",      0, 130, 100, 19, &ebone->parent->rad_tail, 0, lim, 10, 3, "Head radius. Visualize with the Envelope display option");
719         else
720                 uiDefButF(block, NUM, B_ARMATUREPANEL1, "Radius:",      0, 130, 100, 19, &ebone->rad_head, 0, lim, 10, 3, "Head radius. Visualize with the Envelope display option");
721         uiBlockEndAlign(block);
722         
723         uiBlockEndAlign(block);
724         uiDefBut(block, LABEL, 0, "Tail:",                                      0, 110, 100, 20, 0, 0, 0, 0, 0, "");
725         uiBlockBeginAlign(block);
726         uiDefButF(block, NUM, B_ARMATUREPANEL1, "X:",           0, 90, 100, 19, ebone->tail, -lim, lim, 10, 3, "X Location of the tail end of the bone");
727         uiDefButF(block, NUM, B_ARMATUREPANEL1, "Y:",           0, 70, 100, 19, ebone->tail+1, -lim, lim, 10, 3, "Y Location of the tail end of the bone");
728         uiDefButF(block, NUM, B_ARMATUREPANEL1, "Z:",           0, 50, 100, 19, ebone->tail+2, -lim, lim, 10, 3, "Z Location of the tail end of the bone");
729         uiDefButF(block, NUM, B_ARMATUREPANEL1, "Radius:",      0, 30, 100, 19, &ebone->rad_tail, 0, lim, 10, 3, "Tail radius. Visualize with the Envelope display option");
730         uiBlockEndAlign(block);
731         
732         tfp->ob_eul[0]= 180.0*ebone->roll/M_PI;
733         uiDefButF(block, NUM, B_ARMATUREPANEL1, "Roll:",        0, 0, 100, 19, tfp->ob_eul, -lim, lim, 1000, 3, "Bone rotation around head-tail axis");
734         uiBlockBeginAlign(block);
735         
736         
737 }
738
739 static void v3d_editmetaball_buts(uiLayout *layout, Object *ob, float lim)
740 {
741         uiBlock *block= uiLayoutAbsoluteBlock(layout);
742         MetaElem *lastelem= NULL; // XXX
743
744         if(lastelem) {
745                 uiBlockBeginAlign(block);
746                 uiDefButF(block, NUM, B_RECALCMBALL, "LocX:", 10, 70, 140, 19, &lastelem->x, -lim, lim, 100, 3, "");
747                 uiDefButF(block, NUM, B_RECALCMBALL, "LocY:", 10, 50, 140, 19, &lastelem->y, -lim, lim, 100, 3, "");
748                 uiDefButF(block, NUM, B_RECALCMBALL, "LocZ:", 10, 30, 140, 19, &lastelem->z, -lim, lim, 100, 3, "");
749
750                 uiBlockBeginAlign(block);
751                 if(lastelem->type!=MB_BALL)
752                         uiDefButF(block, NUM, B_RECALCMBALL, "dx:", 160, 70, 140, 19, &lastelem->expx, 0, lim, 100, 3, "");
753                 if((lastelem->type!=MB_BALL) && (lastelem->type!=MB_TUBE))
754                         uiDefButF(block, NUM, B_RECALCMBALL, "dy:", 160, 50, 140, 19, &lastelem->expy, 0, lim, 100, 3, "");
755                 if((lastelem->type==MB_ELIPSOID) || (lastelem->type==MB_CUBE))
756                         uiDefButF(block, NUM, B_RECALCMBALL, "dz:", 160, 30, 140, 19, &lastelem->expz, 0, lim, 100, 3, "");
757
758                 uiBlockEndAlign(block); 
759
760                 uiBlockBeginAlign(block);
761                 uiDefButF(block, NUM, B_RECALCMBALL, "Radius:", 10, 120, 140, 19, &lastelem->rad, 0, lim, 100, 3, "Size of the active metaball");
762                 uiDefButF(block, NUM, B_RECALCMBALL, "Stiffness:", 10, 100, 140, 19, &lastelem->s, 0, 10, 100, 3, "Stiffness of the active metaball");
763                 uiBlockEndAlign(block);
764                 
765                 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");
766                 
767         }
768 }
769
770 /* test if 'ob' is a parent somewhere in par's parents */
771 static int test_parent_loop(Object *par, Object *ob)
772 {
773         if(par == NULL) return 0;
774         if(ob == par) return 1;
775         return test_parent_loop(par->parent, ob);
776 }
777
778 static void do_view3d_region_buttons(bContext *C, void *arg, int event)
779 {
780         Scene *scene= CTX_data_scene(C);
781         Object *obedit= CTX_data_edit_object(C);
782         View3D *v3d= CTX_wm_view3d(C);
783         BoundBox *bb;
784         Object *ob= OBACT;
785         TransformProperties *tfp= v3d->properties_storage;
786         
787         switch(event) {
788         
789         case B_REDR:
790                 ED_area_tag_redraw(CTX_wm_area(C));
791                 return; /* no notifier! */
792                 
793         case B_OBJECTPANEL:
794                 DAG_id_flush_update(&ob->id, OB_RECALC_OB);
795                 break;
796
797         
798         case B_OBJECTPANELMEDIAN:
799                 if(ob) {
800                         v3d_editvertex_buts(C, NULL, v3d, ob, 1.0);
801                         DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
802                 }
803                 break;
804                 
805                 /* note; this case also used for parbone */
806         case B_OBJECTPANELPARENT:
807                 if(ob) {
808                         if(ob->id.lib || test_parent_loop(ob->parent, ob) ) 
809                                 ob->parent= NULL;
810                         else {
811                                 DAG_scene_sort(scene);
812                                 DAG_id_flush_update(&ob->id, OB_RECALC_OB);
813                         }
814                 }
815                 break;
816                 
817         case B_ARMATUREPANEL1:
818                 {
819                         bArmature *arm= obedit->data;
820                         EditBone *ebone, *child;
821                         
822                         for (ebone = arm->edbo->first; ebone; ebone=ebone->next){
823                                 if ((ebone->flag & BONE_ACTIVE) && (ebone->layer & arm->layer))
824                                         break;
825                         }
826                         if (ebone) {
827                                 ebone->roll= M_PI*tfp->ob_eul[0]/180.0;
828                                 //      Update our parent
829                                 if (ebone->parent && ebone->flag & BONE_CONNECTED){
830                                         VECCOPY (ebone->parent->tail, ebone->head);
831                                 }
832                         
833                                 //      Update our children if necessary
834                                 for (child = arm->edbo->first; child; child=child->next){
835                                         if (child->parent == ebone && (child->flag & BONE_CONNECTED)){
836                                                 VECCOPY (child->head, ebone->tail);
837                                         }
838                                 }
839                                 if(arm->flag & ARM_MIRROR_EDIT) {
840                                         EditBone *eboflip= ED_armature_bone_get_mirrored(arm->edbo, ebone);
841                                         if(eboflip) {
842                                                 eboflip->roll= -ebone->roll;
843                                                 eboflip->head[0]= -ebone->head[0];
844                                                 eboflip->tail[0]= -ebone->tail[0];
845                                                 
846                                                 //      Update our parent
847                                                 if (eboflip->parent && eboflip->flag & BONE_CONNECTED){
848                                                         VECCOPY (eboflip->parent->tail, eboflip->head);
849                                                 }
850                                                 
851                                                 //      Update our children if necessary
852                                                 for (child = arm->edbo->first; child; child=child->next){
853                                                         if (child->parent == eboflip && (child->flag & BONE_CONNECTED)){
854                                                                 VECCOPY (child->head, eboflip->tail);
855                                                         }
856                                                 }
857                                         }
858                                 }
859                         }
860                 }
861                 break;
862         case B_ARMATUREPANEL3:  // rotate button on channel
863                 {
864                         bArmature *arm;
865                         bPoseChannel *pchan;
866                         Bone *bone;
867                         float eul[3];
868                         
869                         arm = ob->data;
870                         if (!arm || !ob->pose) return;
871                                 
872                         for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
873                                 bone = pchan->bone;
874                                 if(bone && (bone->flag & BONE_ACTIVE) && (bone->layer & arm->layer))
875                                         break;
876                         }
877                         if (!pchan) return;
878                         
879                         /* make a copy to eul[3], to allow TAB on buttons to work */
880                         eul[0]= M_PI*tfp->ob_eul[0]/180.0;
881                         eul[1]= M_PI*tfp->ob_eul[1]/180.0;
882                         eul[2]= M_PI*tfp->ob_eul[2]/180.0;
883                         
884                         if (pchan->rotmode == ROT_MODE_AXISANGLE) {
885                                 float quat[4];
886                                 /* convert to axis-angle, passing through quats  */
887                                 EulToQuat(eul, quat);
888                                 QuatToAxisAngle(quat, pchan->rotAxis, &pchan->rotAngle);
889                         }
890                         else if (pchan->rotmode == ROT_MODE_QUAT)
891                                 EulToQuat(eul, pchan->quat);
892                         else
893                                 VecCopyf(pchan->eul, eul);
894                 }
895                 /* no break, pass on */
896         case B_ARMATUREPANEL2:
897                 {
898                         ob->pose->flag |= (POSE_LOCKED|POSE_DO_UNLOCK);
899                         DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
900                 }
901                 break;
902         case B_TRANSFORMSPACEADD:
903                 BIF_createTransformOrientation(C, NULL, "", 1, 0);
904                 break;
905         case B_TRANSFORMSPACECLEAR:
906                 BIF_clearTransformOrientation(C);
907                 break;
908                 
909 #if 0 // XXX
910         case B_WEIGHT0_0:
911                 wpaint->weight = 0.0f;
912                 break;
913                 
914         case B_WEIGHT1_4:
915                 wpaint->weight = 0.25f;
916                 break;
917         case B_WEIGHT1_2:
918                 wpaint->weight = 0.5f;
919                 break;
920         case B_WEIGHT3_4:
921                 wpaint->weight = 0.75f;
922                 break;
923         case B_WEIGHT1_0:
924                 wpaint->weight = 1.0f;
925                 break;
926                 
927         case B_OPA1_8:
928                 wpaint->a = 0.125f;
929                 break;
930         case B_OPA1_4:
931                 wpaint->a = 0.25f;
932                 break;
933         case B_OPA1_2:
934                 wpaint->a = 0.5f;
935                 break;
936         case B_OPA3_4:
937                 wpaint->a = 0.75f;
938                 break;
939         case B_OPA1_0:
940                 wpaint->a = 1.0f;
941                 break;
942 #endif
943         case B_CLR_WPAINT:
944 //              if(!multires_level1_test()) {
945                 {
946                         bDeformGroup *defGroup = BLI_findlink(&ob->defbase, ob->actdef-1);
947                         if(defGroup) {
948                                 Mesh *me= ob->data;
949                                 int a;
950                                 for(a=0; a<me->totvert; a++)
951                                         ED_vgroup_vert_remove (ob, defGroup, a);
952                                 DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
953                         }
954                 }
955                 break;
956         case B_RV3D_LOCKED:
957         case B_RV3D_BOXVIEW:
958         case B_RV3D_BOXCLIP:
959                 {
960                         ScrArea *sa= CTX_wm_area(C);
961                         ARegion *ar= sa->regionbase.last;
962                         RegionView3D *rv3d;
963                         short viewlock;
964                         
965                         ar= ar->prev;
966                         rv3d= ar->regiondata;
967                         viewlock= rv3d->viewlock;
968                         
969                         if((viewlock & RV3D_LOCKED)==0)
970                                 viewlock= 0;
971                         else if((viewlock & RV3D_BOXVIEW)==0)
972                                 viewlock &= ~RV3D_BOXCLIP;
973                         
974                         for(; ar; ar= ar->prev) {
975                                 if(ar->alignment==RGN_ALIGN_QSPLIT) {
976                                         rv3d= ar->regiondata;
977                                         rv3d->viewlock= viewlock;
978                                 }
979                         }
980                         
981                         if(rv3d->viewlock & RV3D_BOXVIEW)
982                                 view3d_boxview_copy(sa, sa->regionbase.last);
983                         
984                         ED_area_tag_redraw(sa);
985                 }
986                 break;
987         }
988
989         /* default for now */
990         WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, ob);
991 }
992
993 void removeTransformOrientation_func(bContext *C, void *target, void *unused)
994 {
995         BIF_removeTransformOrientation(C, (TransformOrientation *) target);
996 }
997
998 void selectTransformOrientation_func(bContext *C, void *target, void *unused)
999 {
1000         BIF_selectTransformOrientation(C, (TransformOrientation *) target);
1001 }
1002
1003 #if 0 // XXX not used
1004 static void view3d_panel_transform_spaces(const bContext *C, Panel *pa)
1005 {
1006         Scene *scene= CTX_data_scene(C);
1007         Object *obedit= CTX_data_edit_object(C);
1008         View3D *v3d= CTX_wm_view3d(C);
1009         ListBase *transform_spaces = &scene->transform_spaces;
1010         TransformOrientation *ts = transform_spaces->first;
1011         uiBlock *block;
1012         uiBut *but;
1013         int xco = 20, yco = 70;
1014         int index;
1015
1016         block= uiLayoutAbsoluteBlock(pa->layout);
1017
1018         uiBlockBeginAlign(block);
1019         
1020         if (obedit)
1021                 uiDefBut(block, BUT, B_TRANSFORMSPACEADD, "Add", xco,120,80,20, 0, 0, 0, 0, 0, "Add the selected element as a Transform Orientation");
1022         else
1023                 uiDefBut(block, BUT, B_TRANSFORMSPACEADD, "Add", xco,120,80,20, 0, 0, 0, 0, 0, "Add the active object as a Transform Orientation");
1024
1025         uiDefBut(block, BUT, B_TRANSFORMSPACECLEAR, "Clear", xco + 80,120,80,20, 0, 0, 0, 0, 0, "Removal all Transform Orientations");
1026         
1027         uiBlockEndAlign(block);
1028         
1029         uiBlockBeginAlign(block);
1030         
1031         uiDefButS(block, ROW, B_REDR, "Global", xco,            90, 40,20, &v3d->twmode, 5.0, (float)V3D_MANIP_GLOBAL,0, 0, "Global Transform Orientation");
1032         uiDefButS(block, ROW, B_REDR, "Local",  xco + 40,       90, 40,20, &v3d->twmode, 5.0, (float)V3D_MANIP_LOCAL, 0, 0, "Local Transform Orientation");
1033         uiDefButS(block, ROW, B_REDR, "Normal", xco + 80,       90, 40,20, &v3d->twmode, 5.0, (float)V3D_MANIP_NORMAL,0, 0, "Normal Transform Orientation");
1034         uiDefButS(block, ROW, B_REDR, "View",           xco + 120,      90, 40,20, &v3d->twmode, 5.0, (float)V3D_MANIP_VIEW,    0, 0, "View Transform Orientation");
1035         
1036         for (index = V3D_MANIP_CUSTOM, ts = transform_spaces->first ; ts ; ts = ts->next, index++) {
1037
1038                 if (v3d->twmode == index) {
1039                         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");
1040                 }
1041                 else {
1042                         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");
1043                 }
1044                 uiButSetFunc(but, selectTransformOrientation_func, ts, NULL);
1045                 uiDefBut(block, TEX, 0, "", xco+=XIC, yco,100+XIC,20, &ts->name, 0, 30, 0, 0, "Edits the name of this Transform Orientation");
1046                 but = uiDefIconBut(block, BUT, B_REDR, ICON_X, xco+=100+XIC,yco,XIC,YIC, 0, 0, 0, 0, 0, "Deletes this Transform Orientation");
1047                 uiButSetFunc(but, removeTransformOrientation_func, ts, NULL);
1048
1049                 xco = 20;
1050                 yco -= 25;
1051         }
1052         uiBlockEndAlign(block);
1053 }
1054 #endif // XXX not used
1055
1056 #if 0
1057 static void brush_idpoin_handle(bContext *C, ID *id, int event)
1058 {
1059         Brush **br = current_brush_source(CTX_data_scene(C));
1060
1061         if(!br)
1062                 return;
1063
1064         switch(event) {
1065         case UI_ID_BROWSE:
1066                 (*br) = (Brush*)id;
1067                 break;
1068         case UI_ID_DELETE:
1069                 brush_delete(br);
1070                 break;
1071         case UI_ID_RENAME:
1072                 /* XXX ? */
1073                 break;
1074         case UI_ID_ADD_NEW:
1075                 if(id) {
1076                         (*br) = copy_brush((Brush*)id);
1077                         id->us--;
1078                 }
1079                 else
1080                         (*br) = add_brush("Brush");
1081                 break;
1082         case UI_ID_OPEN:
1083                 /* XXX not implemented */
1084                 break;
1085         }
1086 }
1087 #endif
1088
1089 static void view3d_panel_object(const bContext *C, Panel *pa)
1090 {
1091         uiBlock *block;
1092         Scene *scene= CTX_data_scene(C);
1093         Object *obedit= CTX_data_edit_object(C);
1094         View3D *v3d= CTX_wm_view3d(C);
1095         //uiBut *bt;
1096         Object *ob= OBACT;
1097         TransformProperties *tfp;
1098         PointerRNA obptr;
1099         uiLayout *col, *row;
1100         float lim;
1101         
1102         if(ob==NULL) return;
1103
1104         /* make sure we got storage */
1105         if(v3d->properties_storage==NULL)
1106                 v3d->properties_storage= MEM_callocN(sizeof(TransformProperties), "TransformProperties");
1107         tfp= v3d->properties_storage;
1108         
1109 // XXX  uiSetButLock(object_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
1110         /*
1111         if(ob->mode & (OB_MODE_VERTEX_PAINT|OB_MODE_WEIGHT_PAINT|OB_MODE_TEXTURE_PAINT)) {
1112         }
1113         else {
1114                 if((ob->mode & OB_MODE_PARTICLE_EDIT)==0) {
1115                         uiBlockEndAlign(block);
1116                 }
1117         }
1118         */
1119
1120         lim= 10000.0f*MAX2(1.0, v3d->grid);
1121
1122         block= uiLayoutGetBlock(pa->layout);
1123         uiBlockSetHandleFunc(block, do_view3d_region_buttons, NULL);
1124
1125         col= uiLayoutColumn(pa->layout, 0);
1126         row= uiLayoutRow(col, 0);
1127         RNA_id_pointer_create(&ob->id, &obptr);
1128         uiItemL(row, "", ICON_OBJECT_DATA);
1129         uiItemR(row, "", 0, &obptr, "name", 0);
1130
1131         if(ob==obedit) {
1132                 if(ob->type==OB_ARMATURE) v3d_editarmature_buts(col, v3d, ob, lim);
1133                 if(ob->type==OB_MBALL) v3d_editmetaball_buts(col, ob, lim);
1134                 else v3d_editvertex_buts(C, col, v3d, ob, lim);
1135         }
1136         else if(ob->mode & OB_MODE_POSE) {
1137                 v3d_posearmature_buts(col, v3d, ob, lim);
1138         }
1139         else {
1140
1141                 v3d_transform_butsR(col, &obptr);
1142         }
1143 }
1144
1145 #if 0
1146 static void view3d_panel_preview(bContext *C, ARegion *ar, short cntrl) // VIEW3D_HANDLER_PREVIEW
1147 {
1148         uiBlock *block;
1149         View3D *v3d= sa->spacedata.first;
1150         int ofsx, ofsy;
1151         
1152         block= uiBeginBlock(C, ar, "view3d_panel_preview", UI_EMBOSS);
1153         uiPanelControl(UI_PNL_SOLID | UI_PNL_CLOSE | UI_PNL_SCALE | cntrl);
1154         uiSetPanelHandler(VIEW3D_HANDLER_PREVIEW);  // for close and esc
1155         
1156         ofsx= -150+(sa->winx/2)/v3d->blockscale;
1157         ofsy= -100+(sa->winy/2)/v3d->blockscale;
1158         if(uiNewPanel(C, ar, block, "Preview", "View3d", ofsx, ofsy, 300, 200)==0) return;
1159
1160         uiBlockSetDrawExtraFunc(block, BIF_view3d_previewdraw);
1161         
1162         if(scene->recalc & SCE_PRV_CHANGED) {
1163                 scene->recalc &= ~SCE_PRV_CHANGED;
1164                 //printf("found recalc\n");
1165                 BIF_view3d_previewrender_free(sa->spacedata.first);
1166                 BIF_preview_changed(0);
1167         }
1168 }
1169 #endif
1170
1171 #if 0 // XXX not used
1172 static void delete_sketch_armature(bContext *C, void *arg1, void *arg2)
1173 {
1174         BIF_deleteSketch(C);
1175 }
1176
1177 static void convert_sketch_armature(bContext *C, void *arg1, void *arg2)
1178 {
1179         BIF_convertSketch(C);
1180 }
1181
1182 static void assign_template_sketch_armature(bContext *C, void *arg1, void *arg2)
1183 {
1184         int index = *(int*)arg1;
1185         BIF_setTemplate(C, index);
1186 }
1187
1188
1189 static int view3d_panel_bonesketch_spaces_poll(const bContext *C, PanelType *pt)
1190 {
1191         Object *obedit = CTX_data_edit_object(C);
1192
1193         /* replace with check call to sketching lib */
1194         return (obedit && obedit->type == OB_ARMATURE);
1195 }
1196 static void view3d_panel_bonesketch_spaces(const bContext *C, Panel *pa)
1197 {
1198         Scene *scene = CTX_data_scene(C);
1199         static int template_index;
1200         static char joint_label[128];
1201         uiBlock *block;
1202         uiBut *but;
1203         char *bone_name;
1204         int yco = 130;
1205         int nb_joints;
1206         static char subdiv_tooltip[4][64] = {
1207                 "Subdivide arcs based on a fixed number of bones",
1208                 "Subdivide arcs in bones of equal length",
1209                 "Subdivide arcs based on correlation",
1210                 "Retarget template to stroke"
1211                 };
1212
1213         
1214         block= uiLayoutAbsoluteBlock(pa->layout);
1215         uiBlockSetHandleFunc(block, do_view3d_region_buttons, NULL);
1216
1217         uiBlockBeginAlign(block);
1218         
1219         /* use real flag instead of 1 */
1220         uiDefButBitC(block, TOG, BONE_SKETCHING, B_REDR, "Use Bone Sketching", 10, yco, 160, 20, &scene->toolsettings->bone_sketching, 0, 0, 0, 0, "Use sketching to create and edit bones, (Ctrl snaps to mesh volume)");
1221         uiDefButBitC(block, TOG, BONE_SKETCHING_ADJUST, B_REDR, "A", 170, yco, 20, 20, &scene->toolsettings->bone_sketching, 0, 0, 0, 0, "Adjust strokes by drawing near them");
1222         uiDefButBitC(block, TOG, BONE_SKETCHING_QUICK, B_REDR, "Q", 190, yco, 20, 20, &scene->toolsettings->bone_sketching, 0, 0, 0, 0, "Automatically convert and delete on stroke end");
1223         yco -= 20;
1224         
1225         but = uiDefBut(block, BUT, B_REDR, "Convert", 10,yco,100,20, 0, 0, 0, 0, 0, "Convert sketch to armature");
1226         uiButSetFunc(but, convert_sketch_armature, NULL, NULL);
1227
1228         but = uiDefBut(block, BUT, B_REDR, "Delete", 110,yco,100,20, 0, 0, 0, 0, 0, "Delete sketch");
1229         uiButSetFunc(but, delete_sketch_armature, NULL, NULL);
1230         yco -= 20;
1231         
1232         uiBlockEndAlign(block);
1233
1234         uiBlockBeginAlign(block);
1235         
1236         uiDefButC(block, MENU, B_REDR, "Subdivision Method%t|Length%x1|Adaptative%x2|Fixed%x0|Template%x3", 10,yco,60,19, &scene->toolsettings->bone_sketching_convert, 0, 0, 0, 0, subdiv_tooltip[(unsigned char)scene->toolsettings->bone_sketching_convert]);
1237
1238         switch(scene->toolsettings->bone_sketching_convert)
1239         {
1240         case SK_CONVERT_CUT_LENGTH:
1241                 uiDefButF(block, NUM, B_REDR,                                   "Lim:",         70, yco, 140, 19, &scene->toolsettings->skgen_length_limit,0.1,50.0, 10, 0,             "Maximum length of the subdivided bones");
1242                 yco -= 20;
1243                 break;
1244         case SK_CONVERT_CUT_ADAPTATIVE:
1245                 uiDefButF(block, NUM, B_REDR,                                   "Thres:",                       70, yco, 140, 19, &scene->toolsettings->skgen_correlation_limit,0.0, 1.0, 0.01, 0,      "Correlation threshold for subdivision");
1246                 yco -= 20;
1247                 break;
1248         default:
1249         case SK_CONVERT_CUT_FIXED:
1250                 uiDefButC(block, NUM, B_REDR,                                   "Num:",         70, yco, 140, 19, &scene->toolsettings->skgen_subdivision_number,1, 100, 1, 5,  "Number of subdivided bones");
1251                 yco -= 20;
1252                 break;
1253         case SK_CONVERT_RETARGET:
1254                 uiDefButC(block, ROW, B_NOP, "No",                      70,  yco, 40,19, &scene->toolsettings->skgen_retarget_roll, 0, 0, 0, 0,                                                                 "No special roll treatment");
1255                 uiDefButC(block, ROW, B_NOP, "View",            110,  yco, 50,19, &scene->toolsettings->skgen_retarget_roll, 0, SK_RETARGET_ROLL_VIEW, 0, 0,                            "Roll bones perpendicular to view");
1256                 uiDefButC(block, ROW, B_NOP, "Joint",           160, yco, 50,19, &scene->toolsettings->skgen_retarget_roll, 0, SK_RETARGET_ROLL_JOINT, 0, 0,                            "Roll bones relative to joint bend");
1257                 yco -= 30;
1258
1259                 uiBlockEndAlign(block);
1260
1261                 uiBlockBeginAlign(block);
1262                 /* button here to select what to do (copy or not), template, ...*/
1263
1264                 BIF_makeListTemplates(C);
1265                 template_index = BIF_currentTemplate(C);
1266                 
1267                 but = uiDefButI(block, MENU, B_REDR, BIF_listTemplates(C), 10,yco,200,19, &template_index, 0, 0, 0, 0, "Template");
1268                 uiButSetFunc(but, assign_template_sketch_armature, &template_index, NULL);
1269                 
1270                 yco -= 20;
1271                 
1272                 uiDefButF(block, NUM, B_NOP,                                                    "A:",                   10, yco, 66,19, &scene->toolsettings->skgen_retarget_angle_weight, 0, 10, 1, 0,         "Angle Weight");
1273                 uiDefButF(block, NUM, B_NOP,                                                    "L:",                   76, yco, 67,19, &scene->toolsettings->skgen_retarget_length_weight, 0, 10, 1, 0,                "Length Weight");
1274                 uiDefButF(block, NUM, B_NOP,                                                    "D:",           143,yco, 67,19, &scene->toolsettings->skgen_retarget_distance_weight, 0, 10, 1, 0,              "Distance Weight");
1275                 yco -= 20;
1276                 
1277                 uiDefBut(block, TEX,B_REDR,"S:",                                                        10,  yco, 90, 20, scene->toolsettings->skgen_side_string, 0.0, 8.0, 0, 0, "Text to replace &S with");
1278                 uiDefBut(block, TEX,B_REDR,"N:",                                                        100, yco, 90, 20, scene->toolsettings->skgen_num_string, 0.0, 8.0, 0, 0, "Text to replace &N with");
1279                 uiDefIconButBitC(block, TOG, SK_RETARGET_AUTONAME, B_NOP, ICON_AUTO,190,yco,20,20, &scene->toolsettings->skgen_retarget_options, 0, 0, 0, 0, "Use Auto Naming");        
1280                 yco -= 20;
1281
1282                 /* auto renaming magic */
1283                 uiBlockEndAlign(block);
1284                 
1285                 nb_joints = BIF_nbJointsTemplate(C);
1286
1287                 if (nb_joints == -1)
1288                 {
1289                         //XXX
1290                         //nb_joints = G.totvertsel;
1291                 }
1292                 
1293                 bone_name = BIF_nameBoneTemplate(C);
1294                 
1295                 BLI_snprintf(joint_label, 32, "%i joints: %s", nb_joints, bone_name);
1296                 
1297                 uiDefBut(block, LABEL, 1, joint_label,                                  10, yco, 200, 20, NULL, 0.0, 0.0, 0, 0, "");
1298                 yco -= 20;
1299                 break;
1300         }
1301
1302         uiBlockEndAlign(block);
1303 }
1304
1305 /* op->invoke */
1306 static void redo_cb(bContext *C, void *arg_op, void *arg2)
1307 {
1308         wmOperator *lastop= arg_op;
1309         
1310         if(lastop) {
1311                 int retval;
1312                 
1313                 printf("operator redo %s\n", lastop->type->name);
1314                 ED_undo_pop(C);
1315                 retval= WM_operator_repeat(C, lastop);
1316                 if((retval & OPERATOR_FINISHED)==0) {
1317                         printf("operator redo failed %s\n", lastop->type->name);
1318                         ED_undo_redo(C);
1319                 }
1320         }
1321 }
1322
1323 static void view3d_panel_operator_redo(const bContext *C, Panel *pa)
1324 {
1325         wmWindowManager *wm= CTX_wm_manager(C);
1326         wmOperator *op;
1327         PointerRNA ptr;
1328         uiBlock *block;
1329         
1330         block= uiLayoutGetBlock(pa->layout);
1331
1332         /* only for operators that are registered and did an undo push */
1333         for(op= wm->operators.last; op; op= op->prev)
1334                 if((op->type->flag & OPTYPE_REGISTER) && (op->type->flag & OPTYPE_UNDO))
1335                         break;
1336         
1337         if(op==NULL)
1338                 return;
1339         
1340         uiBlockSetFunc(block, redo_cb, op, NULL);
1341         
1342         if(!op->properties) {
1343                 IDPropertyTemplate val = {0};
1344                 op->properties= IDP_New(IDP_GROUP, val, "wmOperatorProperties");
1345         }
1346         
1347         RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr);
1348         uiDefAutoButsRNA(C, pa->layout, &ptr, 2);
1349 }
1350 #endif // XXX not used
1351
1352 void view3d_buttons_register(ARegionType *art)
1353 {
1354         PanelType *pt;
1355
1356         pt= MEM_callocN(sizeof(PanelType), "spacetype view3d panel object");
1357         strcpy(pt->idname, "VIEW3D_PT_object");
1358         strcpy(pt->label, "Transform");
1359         pt->draw= view3d_panel_object;
1360         BLI_addtail(&art->paneltypes, pt);
1361         
1362         pt= MEM_callocN(sizeof(PanelType), "spacetype view3d panel gpencil");
1363         strcpy(pt->idname, "VIEW3D_PT_gpencil");
1364         strcpy(pt->label, "Grease Pencil");
1365         pt->draw= gpencil_panel_standard;
1366         BLI_addtail(&art->paneltypes, pt);
1367         
1368         // XXX view3d_panel_preview(C, ar, 0);
1369 }
1370
1371 static int view3d_properties(bContext *C, wmOperator *op)
1372 {
1373         ScrArea *sa= CTX_wm_area(C);
1374         ARegion *ar= view3d_has_buttons_region(sa);
1375         
1376         if(ar)
1377                 ED_region_toggle_hidden(C, ar);
1378
1379         return OPERATOR_FINISHED;
1380 }
1381
1382 void VIEW3D_OT_properties(wmOperatorType *ot)
1383 {
1384         ot->name= "Properties";
1385         ot->description= "Toggles the properties panel display.";
1386         ot->idname= "VIEW3D_OT_properties";
1387         
1388         ot->exec= view3d_properties;
1389         ot->poll= ED_operator_view3d_active;
1390         
1391         /* flags */
1392         ot->flag= 0;
1393 }