b52d626580099c28d27802a9ef384c1301d38d44
[blender.git] / source / blender / editors / space_logic / logic_window.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version. 
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2009 Blender Foundation.
19  * All rights reserved.
20  *
21  * 
22  * Contributor(s): Blender Foundation
23  *
24  * ***** END GPL LICENSE BLOCK *****
25  */
26
27 /** \file blender/editors/space_logic/logic_window.c
28  *  \ingroup splogic
29  */
30
31
32 #include <string.h>
33 #include <stdio.h>
34 #include <stddef.h>
35 #include <float.h>
36
37 #include "DNA_actuator_types.h"
38 #include "DNA_controller_types.h"
39 #include "DNA_property_types.h"
40 #include "DNA_space_types.h"
41 #include "DNA_scene_types.h"
42 #include "DNA_screen_types.h"
43 #include "DNA_sensor_types.h"
44 #include "DNA_constraint_types.h"
45 #include "DNA_object_types.h"
46
47 #include "MEM_guardedalloc.h"
48
49 #include "BLI_blenlib.h"
50 #include "BLI_utildefines.h"
51
52 #include "BKE_action.h"
53 #include "BKE_context.h"
54 #include "BKE_main.h"
55 #include "BKE_sca.h"
56
57 #include "ED_util.h"
58
59 #include "BLF_translation.h"
60
61 #include "UI_interface.h"
62 #include "UI_view2d.h"
63
64 #include "RNA_access.h"
65
66 /* XXX BAD BAD */
67 #include "../interface/interface_intern.h"
68
69 #include "logic_intern.h"
70
71 #define B_REDR          1
72
73 #define B_ADD_SENS              2703
74 #define B_CHANGE_SENS           2704
75 #define B_DEL_SENS              2705
76
77 #define B_ADD_CONT              2706
78 #define B_CHANGE_CONT           2707
79 #define B_DEL_CONT              2708
80
81 #define B_ADD_ACT               2709
82 #define B_CHANGE_ACT            2710
83 #define B_DEL_ACT               2711
84
85 #define B_SOUNDACT_BROWSE       2712
86
87 #define B_SETPROP               2714
88 #define B_SETACTOR              2715
89 #define B_SETMAINACTOR          2716
90 #define B_SETDYNA               2717
91 #define B_SET_STATE_BIT 2718
92 #define B_INIT_STATE_BIT        2719
93
94 /* proto */
95 static ID **get_selected_and_linked_obs(bContext *C, short *count, short scavisflag);
96
97 static int vergname(const void *v1, const void *v2)
98 {
99         char **x1, **x2;
100         
101         x1 = (char **)v1;
102         x2 = (char **)v2;
103         
104         return BLI_natstrcmp(*x1, *x2);
105 }
106
107 void make_unique_prop_names(bContext *C, char *str)
108 {
109         Object *ob;
110         bProperty *prop;
111         bSensor *sens;
112         bController *cont;
113         bActuator *act;
114         ID **idar;
115         short a, obcount, propcount=0, nr;
116         const char **names;
117         
118         /* this function is called by a Button, and gives the current
119          * stringpointer as an argument, this is the one that can change
120          */
121         
122         idar= get_selected_and_linked_obs(C, &obcount, BUTS_SENS_SEL|BUTS_SENS_ACT|BUTS_ACT_SEL|BUTS_ACT_ACT|BUTS_CONT_SEL|BUTS_CONT_ACT);
123         
124         /* for each object, make properties and sca names unique */
125         
126         /* count total names */
127         for (a=0; a<obcount; a++) {
128                 ob= (Object *)idar[a];
129                 propcount+= BLI_countlist(&ob->prop);
130                 propcount+= BLI_countlist(&ob->sensors);
131                 propcount+= BLI_countlist(&ob->controllers);
132                 propcount+= BLI_countlist(&ob->actuators);
133         }
134         if (propcount==0) {
135                 if (idar) MEM_freeN(idar);
136                 return;
137         }
138         
139         /* make names array for sorting */
140         names= MEM_callocN(propcount*sizeof(void *), "names");
141         
142         /* count total names */
143         nr= 0;
144         for (a=0; a<obcount; a++) {
145                 ob= (Object *)idar[a];
146                 prop= ob->prop.first;
147                 while (prop) {
148                         names[nr++] = prop->name;
149                         prop= prop->next;
150                 }
151                 sens= ob->sensors.first;
152                 while (sens) {
153                         names[nr++] = sens->name;
154                         sens= sens->next;
155                 }
156                 cont= ob->controllers.first;
157                 while (cont) {
158                         names[nr++] = cont->name;
159                         cont= cont->next;
160                 }
161                 act= ob->actuators.first;
162                 while (act) {
163                         names[nr++] = act->name;
164                         act= act->next;
165                 }
166         }
167         
168         qsort(names, propcount, sizeof(void *), vergname);
169         
170         /* now we check for double names, and change them */
171         
172         for (nr=0; nr<propcount; nr++) {
173                 if (names[nr]!=str && strcmp( names[nr], str )==0 ) {
174                         BLI_newname(str, +1);
175                 }
176         }
177         
178         MEM_freeN(idar);
179         MEM_freeN(names);
180 }
181
182 static void do_logic_buts(bContext *C, void *UNUSED(arg), int event)
183 {
184         Main *bmain= CTX_data_main(C);
185         bSensor *sens;
186         bController *cont;
187         bActuator *act;
188         Object *ob;
189         int didit, bit;
190         
191         ob= CTX_data_active_object(C);
192         if (ob==NULL) return;
193         
194         switch (event) {
195
196         case B_SETPROP:
197                 /* check for inconsistent types */
198                 ob->gameflag &= ~(OB_SECTOR|OB_MAINACTOR|OB_DYNAMIC|OB_ACTOR);
199                 break;
200
201         case B_SETACTOR:
202         case B_SETDYNA:
203         case B_SETMAINACTOR:
204                 ob->gameflag &= ~(OB_SECTOR|OB_PROP);
205                 break;
206         
207         case B_ADD_SENS:
208                 for (ob=bmain->object.first; ob; ob=ob->id.next) {
209                         if (ob->scaflag & OB_ADDSENS) {
210                                 ob->scaflag &= ~OB_ADDSENS;
211                                 sens= new_sensor(SENS_ALWAYS);
212                                 BLI_addtail(&(ob->sensors), sens);
213                                 make_unique_prop_names(C, sens->name);
214                                 ob->scaflag |= OB_SHOWSENS;
215                         }
216                 }
217                 
218                 ED_undo_push(C, "Add sensor");
219                 break;
220
221         case B_CHANGE_SENS:
222                 for (ob=bmain->object.first; ob; ob=ob->id.next) {
223                         sens= ob->sensors.first;
224                         while (sens) {
225                                 if (sens->type != sens->otype) {
226                                         init_sensor(sens);
227                                         sens->otype= sens->type;
228                                         break;
229                                 }
230                                 sens= sens->next;
231                         }
232                 }
233                 break;
234         
235         case B_DEL_SENS:
236                 for (ob=bmain->object.first; ob; ob=ob->id.next) {
237                         sens= ob->sensors.first;
238                         while (sens) {
239                                 if (sens->flag & SENS_DEL) {
240                                         BLI_remlink(&(ob->sensors), sens);
241                                         free_sensor(sens);
242                                         break;
243                                 }
244                                 sens= sens->next;
245                         }
246                 }
247                 ED_undo_push(C, "Delete sensor");
248                 break;
249         
250         case B_ADD_CONT:
251                 for (ob=bmain->object.first; ob; ob=ob->id.next) {
252                         if (ob->scaflag & OB_ADDCONT) {
253                                 ob->scaflag &= ~OB_ADDCONT;
254                                 cont= new_controller(CONT_LOGIC_AND);
255                                 make_unique_prop_names(C, cont->name);
256                                 ob->scaflag |= OB_SHOWCONT;
257                                 BLI_addtail(&(ob->controllers), cont);
258                                 /* set the controller state mask from the current object state.
259                                  * A controller is always in a single state, so select the lowest bit set
260                                  * from the object state */
261                                 for (bit=0; bit<32; bit++) {
262                                         if (ob->state & (1<<bit))
263                                                 break;
264                                 }
265                                 cont->state_mask = (1<<bit);
266                                 if (cont->state_mask == 0) {
267                                         /* shouldn't happen, object state is never 0 */
268                                         cont->state_mask = 1;
269                                 }
270                         }
271                 }
272                 ED_undo_push(C, "Add controller");
273                 break;
274
275         case B_SET_STATE_BIT:
276                 for (ob=bmain->object.first; ob; ob=ob->id.next) {
277                         if (ob->scaflag & OB_ALLSTATE) {
278                                 ob->scaflag &= ~OB_ALLSTATE;
279                                 ob->state = 0x3FFFFFFF;
280                         }
281                 }
282                 break;
283
284         case B_INIT_STATE_BIT:
285                 for (ob=bmain->object.first; ob; ob=ob->id.next) {
286                         if (ob->scaflag & OB_INITSTBIT) {
287                                 ob->scaflag &= ~OB_INITSTBIT;
288                                 ob->state = ob->init_state;
289                                 if (!ob->state)
290                                         ob->state = 1;
291                         }
292                 }
293                 break;
294
295         case B_CHANGE_CONT:
296                 for (ob=bmain->object.first; ob; ob=ob->id.next) {
297                         cont= ob->controllers.first;
298                         while (cont) {
299                                 if (cont->type != cont->otype) {
300                                         init_controller(cont);
301                                         cont->otype= cont->type;
302                                         break;
303                                 }
304                                 cont= cont->next;
305                         }
306                 }
307                 break;
308         
309
310         case B_DEL_CONT:
311                 for (ob=bmain->object.first; ob; ob=ob->id.next) {
312                         cont= ob->controllers.first;
313                         while (cont) {
314                                 if (cont->flag & CONT_DEL) {
315                                         BLI_remlink(&(ob->controllers), cont);
316                                         unlink_controller(cont);
317                                         free_controller(cont);
318                                         break;
319                                 }
320                                 cont= cont->next;
321                         }
322                 }
323                 ED_undo_push(C, "Delete controller");
324                 break;
325
326         case B_ADD_ACT:
327                 for (ob=bmain->object.first; ob; ob=ob->id.next) {
328                         if (ob->scaflag & OB_ADDACT) {
329                                 ob->scaflag &= ~OB_ADDACT;
330                                 act= new_actuator(ACT_OBJECT);
331                                 make_unique_prop_names(C, act->name);
332                                 BLI_addtail(&(ob->actuators), act);
333                                 ob->scaflag |= OB_SHOWACT;
334                         }
335                 }
336                 ED_undo_push(C, "Add actuator");
337                 break;
338
339         case B_CHANGE_ACT:
340                 for (ob=bmain->object.first; ob; ob=ob->id.next) {
341                         act= ob->actuators.first;
342                         while (act) {
343                                 if (act->type != act->otype) {
344                                         init_actuator(act);
345                                         act->otype= act->type;
346                                         break;
347                                 }
348                                 act= act->next;
349                         }
350                 }
351                 break;
352
353         case B_DEL_ACT:
354                 for (ob=bmain->object.first; ob; ob=ob->id.next) {
355                         act= ob->actuators.first;
356                         while (act) {
357                                 if (act->flag & ACT_DEL) {
358                                         BLI_remlink(&(ob->actuators), act);
359                                         unlink_actuator(act);
360                                         free_actuator(act);
361                                         break;
362                                 }
363                                 act= act->next;
364                         }
365                 }
366                 ED_undo_push(C, "Delete actuator");
367                 break;
368         
369         case B_SOUNDACT_BROWSE:
370                 /* since we don't know which... */
371                 didit= 0;
372                 for (ob=bmain->object.first; ob; ob=ob->id.next) {
373                         act= ob->actuators.first;
374                         while (act) {
375                                 if (act->type==ACT_SOUND) {
376                                         bSoundActuator *sa= act->data;
377                                         if (sa->sndnr) {
378                                                 ID *sound= bmain->sound.first;
379                                                 int nr= 1;
380
381                                                 if (sa->sndnr == -2) {
382 // XXX                                                  activate_databrowse((ID *)bmain->sound.first, ID_SO, 0, B_SOUNDACT_BROWSE,
383 //                                                                                      &sa->sndnr, do_logic_buts);
384                                                         break;
385                                                 }
386
387                                                 while (sound) {
388                                                         if (nr==sa->sndnr)
389                                                                 break;
390                                                         nr++;
391                                                         sound= sound->next;
392                                                 }
393                                                 
394                                                 if (sa->sound)
395                                                         ((ID *)sa->sound)->us--;
396                                                 
397                                                 sa->sound= (struct bSound *)sound;
398                                                 
399                                                 if (sound)
400                                                         sound->us++;
401                                                 
402                                                 sa->sndnr= 0;
403                                                 didit= 1;
404                                         }
405                                 }
406                                 act= act->next;
407                         }
408                         if (didit)
409                                 break;
410                 }
411
412                 break;
413         }
414 }
415
416
417 static const char *sensor_name(int type)
418 {
419         switch (type) {
420         case SENS_ALWAYS:
421                 return N_("Always");
422         case SENS_NEAR:
423                 return N_("Near");
424         case SENS_KEYBOARD:
425                 return N_("Keyboard");
426         case SENS_PROPERTY:
427                 return N_("Property");
428         case SENS_ARMATURE:
429                 return N_("Armature");
430         case SENS_ACTUATOR:
431                 return N_("Actuator");
432         case SENS_DELAY:
433                 return N_("Delay");
434         case SENS_MOUSE:
435                 return N_("Mouse");
436         case SENS_COLLISION:
437                 return N_("Collision");
438         case SENS_RADAR:
439                 return N_("Radar");
440         case SENS_RANDOM:
441                 return N_("Random");
442         case SENS_RAY:
443                 return N_("Ray");
444         case SENS_MESSAGE:
445                 return N_("Message");
446         case SENS_JOYSTICK:
447                 return N_("Joystick");
448         }
449         return N_("Unknown");
450 }
451
452 static const char *controller_name(int type)
453 {
454         switch (type) {
455         case CONT_LOGIC_AND:
456                 return N_("And");
457         case CONT_LOGIC_OR:
458                 return N_("Or");
459         case CONT_LOGIC_NAND:
460                 return N_("Nand");
461         case CONT_LOGIC_NOR:
462                 return N_("Nor");
463         case CONT_LOGIC_XOR:
464                 return N_("Xor");
465         case CONT_LOGIC_XNOR:
466                 return N_("Xnor");
467         case CONT_EXPRESSION:
468                 return N_("Expression");
469         case CONT_PYTHON:
470                 return N_("Python");
471         }
472         return N_("Unknown");
473 }
474
475 static const char *actuator_name(int type)
476 {
477         switch (type) {
478         case ACT_SHAPEACTION:
479                 return N_("Shape Action");
480         case ACT_ACTION:
481                 return N_("Action");
482         case ACT_OBJECT:
483                 return N_("Motion");
484         case ACT_IPO:
485                 return N_("F-Curve");
486         case ACT_LAMP:
487                 return N_("Lamp");
488         case ACT_CAMERA:
489                 return N_("Camera");
490         case ACT_MATERIAL:
491                 return N_("Material");
492         case ACT_SOUND:
493                 return N_("Sound");
494         case ACT_PROPERTY:
495                 return N_("Property");
496         case ACT_EDIT_OBJECT:
497                 return N_("Edit Object");
498         case ACT_CONSTRAINT:
499                 return N_("Constraint");
500         case ACT_SCENE:
501                 return N_("Scene");
502         case ACT_GROUP:
503                 return N_("Group");
504         case ACT_RANDOM:
505                 return N_("Random");
506         case ACT_MESSAGE:
507                 return N_("Message");
508         case ACT_GAME:
509                 return N_("Game");
510         case ACT_VISIBILITY:
511                 return N_("Visibility");
512         case ACT_2DFILTER:
513                 return N_("Filter 2D");
514         case ACT_PARENT:
515                 return N_("Parent");
516         case ACT_STATE:
517                 return N_("State");
518         case ACT_ARMATURE:
519                 return N_("Armature");
520         case ACT_STEERING:
521                 return N_("Steering");
522         case ACT_MOUSE:
523                 return N_("Mouse");
524         }
525         return N_("Unknown");
526 }
527
528 static void set_sca_ob(Object *ob)
529 {
530         bController *cont;
531         bActuator *act;
532
533         cont= ob->controllers.first;
534         while (cont) {
535                 cont->mynew= (bController *)ob;
536                 cont= cont->next;
537         }
538         act= ob->actuators.first;
539         while (act) {
540                 act->mynew= (bActuator *)ob;
541                 act= act->next;
542         }
543 }
544
545 static ID **get_selected_and_linked_obs(bContext *C, short *count, short scavisflag)
546 {
547         Base *base;
548         Main *bmain= CTX_data_main(C);
549         Scene *scene= CTX_data_scene(C);
550         Object *ob, *obt, *obact= CTX_data_active_object(C);
551         ID **idar;
552         bSensor *sens;
553         bController *cont;
554         unsigned int lay;
555         int a, nr, do_it;
556         
557         /* we need a sorted object list */
558         /* set scavisflags flags in Objects to indicate these should be evaluated */
559         /* also hide ob pointers in ->new entries of controllerss/actuators */
560         
561         *count= 0;
562         
563         if (scene==NULL) return NULL;
564         
565         ob= bmain->object.first;
566         while (ob) {
567                 ob->scavisflag= 0;
568                 set_sca_ob(ob);
569                 ob= ob->id.next;
570         }
571         
572         /* XXX here it checked 3d lay */
573         lay= scene->lay;
574         
575         base= FIRSTBASE;
576         while (base) {
577                 if (base->lay & lay) {
578                         if (base->flag & SELECT) {
579                                 if (scavisflag & BUTS_SENS_SEL) base->object->scavisflag |= OB_VIS_SENS;
580                                 if (scavisflag & BUTS_CONT_SEL) base->object->scavisflag |= OB_VIS_CONT;
581                                 if (scavisflag & BUTS_ACT_SEL) base->object->scavisflag |= OB_VIS_ACT;
582                         }
583                 }
584                 base= base->next;
585         }
586
587         if (obact) {
588                 if (scavisflag & BUTS_SENS_ACT) obact->scavisflag |= OB_VIS_SENS;
589                 if (scavisflag & BUTS_CONT_ACT) obact->scavisflag |= OB_VIS_CONT;
590                 if (scavisflag & BUTS_ACT_ACT) obact->scavisflag |= OB_VIS_ACT;
591         }
592         
593         /* BUTS_XXX_STATE are similar to BUTS_XXX_LINK for selecting the object */
594         if (scavisflag & (BUTS_SENS_LINK|BUTS_CONT_LINK|BUTS_ACT_LINK|BUTS_SENS_STATE|BUTS_ACT_STATE)) {
595                 do_it = true;
596                 while (do_it) {
597                         do_it = false;
598                         
599                         ob= bmain->object.first;
600                         while (ob) {
601                         
602                                 /* 1st case: select sensor when controller selected */
603                                 if ((scavisflag & (BUTS_SENS_LINK|BUTS_SENS_STATE)) && (ob->scavisflag & OB_VIS_SENS)==0) {
604                                         sens= ob->sensors.first;
605                                         while (sens) {
606                                                 for (a=0; a<sens->totlinks; a++) {
607                                                         if (sens->links[a]) {
608                                                                 obt= (Object *)sens->links[a]->mynew;
609                                                                 if (obt && (obt->scavisflag & OB_VIS_CONT)) {
610                                                                         do_it = true;
611                                                                         ob->scavisflag |= OB_VIS_SENS;
612                                                                         break;
613                                                                 }
614                                                         }
615                                                 }
616                                                 if (do_it) break;
617                                                 sens= sens->next;
618                                         }
619                                 }
620                                 
621                                 /* 2nd case: select cont when act selected */
622                                 if ((scavisflag & BUTS_CONT_LINK) && (ob->scavisflag & OB_VIS_CONT)==0) {
623                                         cont= ob->controllers.first;
624                                         while (cont) {
625                                                 for (a=0; a<cont->totlinks; a++) {
626                                                         if (cont->links[a]) {
627                                                                 obt= (Object *)cont->links[a]->mynew;
628                                                                 if (obt && (obt->scavisflag & OB_VIS_ACT)) {
629                                                                         do_it = true;
630                                                                         ob->scavisflag |= OB_VIS_CONT;
631                                                                         break;
632                                                                 }
633                                                         }
634                                                 }
635                                                 if (do_it) break;
636                                                 cont= cont->next;
637                                         }
638                                 }
639                                 
640                                 /* 3rd case: select controller when sensor selected */
641                                 if ((scavisflag & BUTS_CONT_LINK) && (ob->scavisflag & OB_VIS_SENS)) {
642                                         sens= ob->sensors.first;
643                                         while (sens) {
644                                                 for (a=0; a<sens->totlinks; a++) {
645                                                         if (sens->links[a]) {
646                                                                 obt= (Object *)sens->links[a]->mynew;
647                                                                 if (obt && (obt->scavisflag & OB_VIS_CONT)==0) {
648                                                                         do_it = true;
649                                                                         obt->scavisflag |= OB_VIS_CONT;
650                                                                 }
651                                                         }
652                                                 }
653                                                 sens= sens->next;
654                                         }
655                                 }
656                                 
657                                 /* 4th case: select actuator when controller selected */
658                                 if ((scavisflag & (BUTS_ACT_LINK|BUTS_ACT_STATE)) && (ob->scavisflag & OB_VIS_CONT)) {
659                                         cont= ob->controllers.first;
660                                         while (cont) {
661                                                 for (a=0; a<cont->totlinks; a++) {
662                                                         if (cont->links[a]) {
663                                                                 obt= (Object *)cont->links[a]->mynew;
664                                                                 if (obt && (obt->scavisflag & OB_VIS_ACT)==0) {
665                                                                         do_it = true;
666                                                                         obt->scavisflag |= OB_VIS_ACT;
667                                                                 }
668                                                         }
669                                                 }
670                                                 cont= cont->next;
671                                         }
672                                         
673                                 }
674                                 ob= ob->id.next;
675                         }
676                 }
677         }
678         
679         /* now we count */
680         ob= bmain->object.first;
681         while (ob) {
682                 if ( ob->scavisflag ) (*count)++;
683                 ob= ob->id.next;
684         }
685
686         if (*count == 0) return NULL;
687         if (*count > 24) *count = 24;  /* temporal */
688         
689         idar= MEM_callocN((*count)*sizeof(void *), "idar");
690         
691         ob= bmain->object.first;
692         nr= 0;
693
694         /* make the active object always the first one of the list */
695         if (obact) {
696                 idar[0] = (ID *)obact;
697                 nr++;
698         }
699
700         while (ob) {
701                 if ((ob->scavisflag) && (ob != obact)) {
702                         idar[nr] = (ID *)ob;
703                         nr++;
704                 }
705                 if (nr >= 24) break;
706                 ob= ob->id.next;
707         }
708         
709         /* just to be sure... these were set in set_sca_done_ob() */
710         clear_sca_new_poins();
711         
712         return idar;
713 }
714
715 static void get_armature_bone_constraint(Object *ob, const char *posechannel, const char *constraint_name, bConstraint **constraint)
716 {
717         /* check that bone exist in the active object */
718         if (ob->type == OB_ARMATURE && ob->pose) {
719                 bPoseChannel *pchan= BKE_pose_channel_find_name(ob->pose, posechannel);
720                 if (pchan) {
721                         bConstraint *con= BLI_findstring(&pchan->constraints, constraint_name, offsetof(bConstraint, name));
722                         if (con) {
723                                 *constraint= con;
724                         }
725                 }
726         }
727         /* didn't find any */
728 }
729
730 static void do_sensor_menu(bContext *C, void *UNUSED(arg), int event)
731 {       
732         SpaceLogic *slogic= CTX_wm_space_logic(C);
733         ID **idar;
734         Object *ob;
735         bSensor *sens;
736         short count, a;
737         
738         idar= get_selected_and_linked_obs(C, &count, slogic->scaflag);
739         
740         for (a=0; a<count; a++) {
741                 ob= (Object *)idar[a];
742                 if (event==0 || event==2) ob->scaflag |= OB_SHOWSENS;
743                 else if (event==1) ob->scaflag &= ~OB_SHOWSENS;
744         }
745                 
746         for (a=0; a<count; a++) {
747                 ob= (Object *)idar[a];
748                 sens= ob->sensors.first;
749                 while (sens) {
750                         if (event==2) sens->flag |= SENS_SHOW;
751                         else if (event==3) sens->flag &= ~SENS_SHOW;
752                         sens= sens->next;
753                 }
754         }
755
756         if (idar) MEM_freeN(idar);
757 }
758
759 static uiBlock *sensor_menu(bContext *C, ARegion *ar, void *UNUSED(arg))
760 {
761         uiBlock *block;
762         int yco=0;
763         
764         block= uiBeginBlock(C, ar, __func__, UI_EMBOSSP);
765         uiBlockSetButmFunc(block, do_sensor_menu, NULL);
766         
767         uiDefBut(block, BUTM, 1, IFACE_("Show Objects"),        0, (short)(yco-=20), 160, 19, NULL, 0.0, 0.0, 1, 0, "");
768         uiDefBut(block, BUTM, 1, IFACE_("Hide Objects"),        0, (short)(yco-=20), 160, 19, NULL, 0.0, 0.0, 1, 1, "");
769         uiDefBut(block, SEPRLINE, 0, "",        0, (short)(yco-=6), 160, 6, NULL, 0.0, 0.0, 0, 0, "");
770         uiDefBut(block, BUTM, 1, IFACE_("Show Sensors"),        0, (short)(yco-=20), 160, 19, NULL, 0.0, 0.0, 1, 2, "");
771         uiDefBut(block, BUTM, 1, IFACE_("Hide Sensors"),        0, (short)(yco-=20), 160, 19, NULL, 0.0, 0.0, 1, 3, "");
772
773         uiBlockSetDirection(block, UI_TOP);
774         uiEndBlock(C, block);
775         
776         return block;
777 }
778
779 static void do_controller_menu(bContext *C, void *UNUSED(arg), int event)
780 {       
781         SpaceLogic *slogic= CTX_wm_space_logic(C);
782         ID **idar;
783         Object *ob;
784         bController *cont;
785         short count, a;
786         
787         idar= get_selected_and_linked_obs(C, &count, slogic->scaflag);
788         
789         for (a=0; a<count; a++) {
790                 ob= (Object *)idar[a];
791                 if (event==0 || event==2) ob->scaflag |= OB_SHOWCONT;
792                 else if (event==1) ob->scaflag &= ~OB_SHOWCONT;
793         }
794
795         for (a=0; a<count; a++) {
796                 ob= (Object *)idar[a];
797                 cont= ob->controllers.first;
798                 while (cont) {
799                         if (event==2) cont->flag |= CONT_SHOW;
800                         else if (event==3) cont->flag &= ~CONT_SHOW;
801                         cont= cont->next;
802                 }
803         }
804
805         if (idar) MEM_freeN(idar);
806 }
807
808 static uiBlock *controller_menu(bContext *C, ARegion *ar, void *UNUSED(arg))
809 {
810         uiBlock *block;
811         int yco=0;
812         
813         block= uiBeginBlock(C, ar, __func__, UI_EMBOSSP);
814         uiBlockSetButmFunc(block, do_controller_menu, NULL);
815         
816         uiDefBut(block, BUTM, 1, IFACE_("Show Objects"),        0, (short)(yco-=20), 160, 19, NULL, 0.0, 0.0, 1, 0, "");
817         uiDefBut(block, BUTM, 1, IFACE_("Hide Objects"),        0, (short)(yco-=20), 160, 19, NULL, 0.0, 0.0, 1, 1, "");
818         uiDefBut(block, SEPRLINE, 0, "",                                        0, (short)(yco-=6), 160, 6, NULL, 0.0, 0.0, 0, 0, "");
819         uiDefBut(block, BUTM, 1, IFACE_("Show Controllers"),    0, (short)(yco-=20), 160, 19, NULL, 0.0, 0.0, 2, 2, "");
820         uiDefBut(block, BUTM, 1, IFACE_("Hide Controllers"),    0, (short)(yco-=20), 160, 19, NULL, 0.0, 0.0, 3, 3, "");
821
822         uiBlockSetDirection(block, UI_TOP);
823         uiEndBlock(C, block);
824         
825         return block;
826 }
827
828 static void do_actuator_menu(bContext *C, void *UNUSED(arg), int event)
829 {       
830         SpaceLogic *slogic= CTX_wm_space_logic(C);
831         ID **idar;
832         Object *ob;
833         bActuator *act;
834         short count, a;
835         
836         idar= get_selected_and_linked_obs(C, &count, slogic->scaflag);
837         
838         for (a=0; a<count; a++) {
839                 ob= (Object *)idar[a];
840                 if (event==0 || event==2) ob->scaflag |= OB_SHOWACT;
841                 else if (event==1) ob->scaflag &= ~OB_SHOWACT;
842         }
843
844         for (a=0; a<count; a++) {
845                 ob= (Object *)idar[a];
846                 act= ob->actuators.first;
847                 while (act) {
848                         if (event==2) act->flag |= ACT_SHOW;
849                         else if (event==3) act->flag &= ~ACT_SHOW;
850                         act= act->next;
851                 }
852         }
853
854         if (idar) MEM_freeN(idar);
855 }
856
857 static uiBlock *actuator_menu(bContext *C, ARegion *ar, void *UNUSED(arg))
858 {
859         uiBlock *block;
860         int xco=0;
861         
862         block= uiBeginBlock(C, ar, __func__, UI_EMBOSSP);
863         uiBlockSetButmFunc(block, do_actuator_menu, NULL);
864         
865         uiDefBut(block, BUTM, 1, IFACE_("Show Objects"),        0, (short)(xco-=20), 160, 19, NULL, 0.0, 0.0, 1, 0, "");
866         uiDefBut(block, BUTM, 1, IFACE_("Hide Objects"),        0, (short)(xco-=20), 160, 19, NULL, 0.0, 0.0, 1, 1, "");
867         uiDefBut(block, SEPRLINE, 0, "",        0, (short)(xco-=6), 160, 6, NULL, 0.0, 0.0, 0, 0, "");
868         uiDefBut(block, BUTM, 1, IFACE_("Show Actuators"),      0, (short)(xco-=20), 160, 19, NULL, 0.0, 0.0, 1, 2, "");
869         uiDefBut(block, BUTM, 1, IFACE_("Hide Actuators"),      0, (short)(xco-=20), 160, 19, NULL, 0.0, 0.0, 1, 3, "");
870
871         uiBlockSetDirection(block, UI_TOP);
872         uiEndBlock(C, block);
873         
874         return block;
875 }
876
877 static void check_controller_state_mask(bContext *UNUSED(C), void *arg1_but, void *arg2_mask)
878 {
879         unsigned int *cont_mask = arg2_mask;
880         uiBut *but = arg1_but;
881         
882         /* a controller is always in a single state */
883         *cont_mask = (1<<but->retval);
884         but->retval = B_REDR;
885 }
886
887 static uiBlock *controller_state_mask_menu(bContext *C, ARegion *ar, void *arg_cont)
888 {
889         uiBlock *block;
890         uiBut *but;
891         bController *cont = arg_cont;
892
893         short yco = 12, xco = 0, stbit, offset;
894
895         block= uiBeginBlock(C, ar, __func__, UI_EMBOSS);
896
897         /* use this for a fake extra empy space around the buttons */
898         uiDefBut(block, LABEL, 0, "",                   -5, -5, 200, 34, NULL, 0, 0, 0, 0, "");
899         
900         for (offset=0; offset<15; offset += 5) {
901                 uiBlockBeginAlign(block);
902                 for (stbit=0; stbit<5; stbit++) {
903                         but = uiDefButBitI(block, TOG, (1<<(stbit+offset)), (stbit+offset), "", (short)(xco+12*stbit+13*offset), yco, 12, 12, (int *)&(cont->state_mask), 0, 0, 0, 0, "");
904                         uiButSetFunc(but, check_controller_state_mask, but, &(cont->state_mask));
905                 }
906                 for (stbit=0; stbit<5; stbit++) {
907                         but = uiDefButBitI(block, TOG, (1<<(stbit+offset+15)), (stbit+offset+15), "",   (short)(xco+12*stbit+13*offset), yco-12, 12, 12, (int *)&(cont->state_mask), 0, 0, 0, 0, "");
908                         uiButSetFunc(but, check_controller_state_mask, but, &(cont->state_mask));
909                 }
910         }
911         uiBlockEndAlign(block);
912
913         uiBlockSetDirection(block, UI_TOP);
914         uiEndBlock(C, block);
915
916         return block;
917 }
918
919 static bool is_sensor_linked(uiBlock *block, bSensor *sens)
920 {
921         bController *cont;
922         int i;
923
924         for (i=0; i<sens->totlinks; i++) {
925                 cont = sens->links[i];
926                 if (uiFindInlink(block, cont) != NULL)
927                         return 1;
928         }
929         return 0;
930 }
931
932 /* Sensors code */
933
934 static void draw_sensor_header(uiLayout *layout, PointerRNA *ptr, PointerRNA *logic_ptr)
935 {
936         uiLayout *box, *row, *sub;
937         bSensor *sens= (bSensor *)ptr->data;
938         
939         box = uiLayoutBox(layout);
940         row = uiLayoutRow(box, false);
941         
942         sub = uiLayoutRow(row, false);
943         uiLayoutSetActive(sub, RNA_boolean_get(ptr, "active"));
944         uiItemR(sub, ptr, "show_expanded", UI_ITEM_R_NO_BG, "", ICON_NONE);
945         if (RNA_boolean_get(ptr, "show_expanded")) {
946                 uiItemR(sub, ptr, "type", 0, "", ICON_NONE);
947                 uiItemR(sub, ptr, "name", 0, "", ICON_NONE);
948         }
949         else {
950                 uiItemL(sub, IFACE_(sensor_name(sens->type)), ICON_NONE);
951                 uiItemL(sub, sens->name, ICON_NONE);
952         }
953
954         sub = uiLayoutRow(row, false);
955         uiLayoutSetActive(sub, (((RNA_boolean_get(logic_ptr, "show_sensors_active_states") &&
956                                  RNA_boolean_get(ptr, "show_expanded")) || RNA_boolean_get(ptr, "pin")) &&
957                                                  RNA_boolean_get(ptr, "active")));
958         uiItemR(sub, ptr, "pin", UI_ITEM_R_NO_BG, "", ICON_NONE);
959
960         if (RNA_boolean_get(ptr, "show_expanded")==0) {
961                 sub = uiLayoutRow(row, true);
962                 uiLayoutSetActive(sub, RNA_boolean_get(ptr, "active"));
963                 uiItemEnumO(sub, "LOGIC_OT_sensor_move", "", ICON_TRIA_UP, "direction", 1); // up
964                 uiItemEnumO(sub, "LOGIC_OT_sensor_move", "", ICON_TRIA_DOWN, "direction", 2); // down
965         }
966
967         sub = uiLayoutRow(row, false);
968         uiItemR(sub, ptr, "active", 0, "", ICON_NONE);
969
970         sub = uiLayoutRow(row, false);
971         uiLayoutSetActive(sub, RNA_boolean_get(ptr, "active"));
972         uiItemO(sub, "", ICON_X, "LOGIC_OT_sensor_remove");
973 }
974
975 static void draw_sensor_internal_header(uiLayout *layout, PointerRNA *ptr)
976 {
977         uiLayout *box, *split, *sub, *row;
978
979         box = uiLayoutBox(layout);
980         uiLayoutSetActive(box, RNA_boolean_get(ptr, "active"));
981         split = uiLayoutSplit(box, 0.45f, false);
982         
983         row = uiLayoutRow(split, true);
984         uiItemR(row, ptr, "use_pulse_true_level", 0, "", ICON_DOTSUP);
985         uiItemR(row, ptr, "use_pulse_false_level", 0, "", ICON_DOTSDOWN);
986
987         sub = uiLayoutRow(row, false);
988         uiLayoutSetActive(sub, (RNA_boolean_get(ptr, "use_pulse_true_level") ||
989                                 RNA_boolean_get(ptr, "use_pulse_false_level")));
990         uiItemR(sub, ptr, "frequency", 0, IFACE_("Freq"), ICON_NONE);
991         
992         row = uiLayoutRow(split, true);
993         uiItemR(row, ptr, "use_level", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
994         uiItemR(row, ptr, "use_tap", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
995         
996         uiItemR(split, ptr, "invert", UI_ITEM_R_TOGGLE, IFACE_("Invert"), ICON_NONE);
997 }
998 /* sensors in alphabetical order */
999
1000 static void draw_sensor_actuator(uiLayout *layout, PointerRNA *ptr)
1001 {
1002         Object *ob = (Object *)ptr->id.data;
1003         PointerRNA settings_ptr;
1004
1005         RNA_pointer_create((ID *)ob, &RNA_GameObjectSettings, ob, &settings_ptr);
1006         uiItemPointerR(layout, ptr, "actuator", &settings_ptr, "actuators", NULL, ICON_LOGIC);
1007 }
1008
1009 static void draw_sensor_armature(uiLayout *layout, PointerRNA *ptr)
1010 {
1011         bSensor *sens = (bSensor *)ptr->data;
1012         bArmatureSensor *as = (bArmatureSensor *) sens->data;
1013         Object *ob = (Object *)ptr->id.data;
1014         uiLayout *row;
1015
1016         if (ob->type != OB_ARMATURE) {
1017                 uiItemL(layout, IFACE_("Sensor only available for armatures"), ICON_NONE);
1018                 return;
1019         }
1020
1021         if (ob->pose) {
1022                 PointerRNA pose_ptr, pchan_ptr;
1023                 PropertyRNA *bones_prop;
1024
1025                 RNA_pointer_create((ID *)ob, &RNA_Pose, ob->pose, &pose_ptr);
1026                 bones_prop = RNA_struct_find_property(&pose_ptr, "bones");
1027
1028                 uiItemPointerR(layout, ptr, "bone", &pose_ptr, "bones", NULL, ICON_BONE_DATA);
1029
1030                 if (RNA_property_collection_lookup_string(&pose_ptr, bones_prop, as->posechannel, &pchan_ptr))
1031                         uiItemPointerR(layout, ptr, "constraint", &pchan_ptr, "constraints", NULL, ICON_CONSTRAINT_BONE);
1032         }
1033         row = uiLayoutRow(layout, true);
1034         uiItemR(row, ptr, "test_type", 0, NULL, ICON_NONE);
1035         if (RNA_enum_get(ptr, "test_type") != SENS_ARM_STATE_CHANGED)
1036                 uiItemR(row, ptr, "value", 0, NULL, ICON_NONE);
1037 }
1038
1039 static void draw_sensor_collision(uiLayout *layout, PointerRNA *ptr, bContext *C)
1040 {
1041         uiLayout *row, *split;
1042         PointerRNA main_ptr;
1043
1044         RNA_main_pointer_create(CTX_data_main(C), &main_ptr);
1045
1046         split = uiLayoutSplit(layout, 0.3f, false);
1047         row = uiLayoutRow(split, true);
1048         uiItemR(row, ptr, "use_pulse", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
1049         uiItemR(row, ptr, "use_material", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
1050
1051         switch (RNA_boolean_get(ptr, "use_material")) {
1052                 case SENS_COLLISION_PROPERTY:
1053                         uiItemR(split, ptr, "property", 0, NULL, ICON_NONE);
1054                         break;
1055                 case SENS_COLLISION_MATERIAL:
1056                         uiItemPointerR(split, ptr, "material", &main_ptr, "materials", NULL, ICON_MATERIAL_DATA);
1057                         break;
1058         }
1059 }
1060
1061 static void draw_sensor_delay(uiLayout *layout, PointerRNA *ptr)
1062 {
1063         uiLayout *row;
1064         
1065         row = uiLayoutRow(layout, false);
1066
1067         uiItemR(row, ptr, "delay", 0, NULL, ICON_NONE);
1068         uiItemR(row, ptr, "duration", 0, NULL, ICON_NONE);
1069         uiItemR(row, ptr, "use_repeat", 0, NULL, ICON_NONE);
1070 }
1071
1072 static void draw_sensor_joystick(uiLayout *layout, PointerRNA *ptr)
1073 {
1074         uiLayout *col, *row;
1075
1076         uiItemR(layout, ptr, "joystick_index", 0, NULL, ICON_NONE);
1077         uiItemR(layout, ptr, "event_type", 0, NULL, ICON_NONE);
1078
1079         switch (RNA_enum_get(ptr, "event_type")) {
1080                 case SENS_JOY_BUTTON:
1081                         uiItemR(layout, ptr, "use_all_events", 0, NULL, ICON_NONE);
1082
1083                         col = uiLayoutColumn(layout, false);
1084                         uiLayoutSetActive(col, RNA_boolean_get(ptr, "use_all_events") == false);
1085                         uiItemR(col, ptr, "button_number", 0, NULL, ICON_NONE);
1086                         break;
1087                 case SENS_JOY_AXIS:
1088                         row = uiLayoutRow(layout, false);
1089                         uiItemR(row, ptr, "axis_number", 0, NULL, ICON_NONE);
1090                         uiItemR(row, ptr, "axis_threshold", 0, NULL, ICON_NONE);
1091
1092                         uiItemR(layout, ptr, "use_all_events", 0, NULL, ICON_NONE);
1093                         col = uiLayoutColumn(layout, false);
1094                         uiLayoutSetActive(col, RNA_boolean_get(ptr, "use_all_events") == false);
1095                         uiItemR(col, ptr, "axis_direction", 0, NULL, ICON_NONE);
1096                         break;
1097                 case SENS_JOY_HAT:
1098                         uiItemR(layout, ptr, "hat_number", 0, NULL, ICON_NONE);
1099                         uiItemR(layout, ptr, "use_all_events", 0, NULL, ICON_NONE);
1100
1101                         col = uiLayoutColumn(layout, false);
1102                         uiLayoutSetActive(col, RNA_boolean_get(ptr, "use_all_events") == false);
1103                         uiItemR(col, ptr, "hat_direction", 0, NULL, ICON_NONE);
1104                         break;
1105                 case SENS_JOY_AXIS_SINGLE:
1106                         row = uiLayoutRow(layout, false);
1107                         uiItemR(row, ptr, "single_axis_number", 0, NULL, ICON_NONE);
1108                         uiItemR(row, ptr, "axis_threshold", 0, NULL, ICON_NONE);
1109                         break;
1110         }
1111 }
1112
1113 static void draw_sensor_keyboard(uiLayout *layout, PointerRNA *ptr)
1114 {
1115         Object *ob = (Object *)ptr->id.data;
1116         PointerRNA settings_ptr;
1117         uiLayout *row, *col;
1118
1119         row = uiLayoutRow(layout, false);
1120         uiItemL(row, CTX_IFACE_(BLF_I18NCONTEXT_ID_WINDOWMANAGER, "Key:"), ICON_NONE);
1121         col = uiLayoutColumn(row, false);
1122         uiLayoutSetActive(col, RNA_boolean_get(ptr, "use_all_keys") == false);
1123         uiItemR(col, ptr, "key", UI_ITEM_R_EVENT, "", ICON_NONE);
1124         col = uiLayoutColumn(row, false);
1125         uiItemR(col, ptr, "use_all_keys", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
1126         
1127         col = uiLayoutColumn(layout, false);
1128         uiLayoutSetActive(col, RNA_boolean_get(ptr, "use_all_keys") == false);
1129         row = uiLayoutRow(col, false);
1130         uiItemL(row, IFACE_("First Modifier:"), ICON_NONE);
1131         uiItemR(row, ptr, "modifier_key_1", UI_ITEM_R_EVENT, "", ICON_NONE);
1132         
1133         row = uiLayoutRow(col, false);
1134         uiItemL(row, IFACE_("Second Modifier:"), ICON_NONE);
1135         uiItemR(row, ptr, "modifier_key_2", UI_ITEM_R_EVENT, "", ICON_NONE);
1136
1137         RNA_pointer_create((ID *)ob, &RNA_GameObjectSettings, ob, &settings_ptr);
1138         uiItemPointerR(layout, ptr, "log", &settings_ptr, "properties", NULL, ICON_NONE);
1139         uiItemPointerR(layout, ptr, "target", &settings_ptr, "properties", NULL, ICON_NONE);
1140 }
1141
1142 static void draw_sensor_message(uiLayout *layout, PointerRNA *ptr)
1143 {
1144         uiItemR(layout, ptr, "subject", 0, NULL, ICON_NONE);
1145 }
1146
1147 static void draw_sensor_mouse(uiLayout *layout, PointerRNA *ptr)
1148 {
1149         uiLayout *split;
1150
1151         split = uiLayoutSplit(layout, 0.8f, false);
1152         uiItemR(split, ptr, "mouse_event", 0, NULL, ICON_NONE);
1153
1154         if (RNA_enum_get(ptr, "mouse_event") == BL_SENS_MOUSE_MOUSEOVER_ANY)
1155                 uiItemR(split, ptr, "use_pulse", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
1156 }
1157
1158 static void draw_sensor_near(uiLayout *layout, PointerRNA *ptr)
1159 {
1160         uiLayout *row;
1161
1162         uiItemR(layout, ptr, "property", 0, NULL, ICON_NONE);
1163
1164         row = uiLayoutRow(layout, true);
1165         uiItemR(row, ptr, "distance", 0, NULL, ICON_NONE);
1166         uiItemR(row, ptr, "reset_distance", 0, NULL, ICON_NONE);
1167 }
1168
1169 static void draw_sensor_property(uiLayout *layout, PointerRNA *ptr)
1170 {
1171         Object *ob = (Object *)ptr->id.data;
1172         PointerRNA settings_ptr;
1173
1174         uiLayout *row;
1175         uiItemR(layout, ptr, "evaluation_type", 0, NULL, ICON_NONE);
1176
1177         RNA_pointer_create((ID *)ob, &RNA_GameObjectSettings, ob, &settings_ptr);
1178         uiItemPointerR(layout, ptr, "property", &settings_ptr, "properties", NULL, ICON_NONE);
1179
1180         switch (RNA_enum_get(ptr, "evaluation_type")) {
1181                 case SENS_PROP_INTERVAL:
1182                         row = uiLayoutRow(layout, false);
1183                         uiItemR(row, ptr, "value_min", 0, NULL, ICON_NONE);
1184                         uiItemR(row, ptr, "value_max", 0, NULL, ICON_NONE);
1185                         break;
1186                 case SENS_PROP_EQUAL:
1187                 case SENS_PROP_NEQUAL:
1188                 case SENS_PROP_LESSTHAN:
1189                 case SENS_PROP_GREATERTHAN:
1190                         uiItemR(layout, ptr, "value", 0, NULL, ICON_NONE);
1191                         break;
1192                 case SENS_PROP_CHANGED:
1193                         break;
1194         }
1195 }
1196
1197 static void draw_sensor_radar(uiLayout *layout, PointerRNA *ptr)
1198 {
1199         uiLayout *row;
1200
1201         uiItemR(layout, ptr, "property", 0, NULL, ICON_NONE);
1202         uiItemR(layout, ptr, "axis", 0, NULL, ICON_NONE);
1203
1204         row = uiLayoutRow(layout, false);
1205         uiItemR(row, ptr, "angle", 0, NULL, ICON_NONE);
1206         uiItemR(row, ptr, "distance", 0, NULL, ICON_NONE);
1207 }
1208
1209 static void draw_sensor_random(uiLayout *layout, PointerRNA *ptr)
1210 {
1211         uiItemR(layout, ptr, "seed", 0, NULL, ICON_NONE);
1212 }
1213
1214 static void draw_sensor_ray(uiLayout *layout, PointerRNA *ptr, bContext *C)
1215 {
1216         uiLayout *split, *row;
1217         PointerRNA main_ptr;
1218
1219         RNA_main_pointer_create(CTX_data_main(C), &main_ptr);
1220         split = uiLayoutSplit(layout, 0.3f, false);
1221         uiItemR(split, ptr, "ray_type", 0, "", ICON_NONE);
1222         switch (RNA_enum_get(ptr, "ray_type")) {
1223                 case SENS_RAY_PROPERTY:
1224                         uiItemR(split, ptr, "property", 0, "", ICON_NONE);
1225                         break;
1226                 case SENS_RAY_MATERIAL:
1227                         uiItemPointerR(split, ptr, "material", &main_ptr, "materials", "", ICON_MATERIAL_DATA);
1228                         break;
1229         }
1230
1231         split = uiLayoutSplit(layout, 0.3, false);
1232         uiItemR(split, ptr, "axis", 0, "", ICON_NONE);
1233         row = uiLayoutRow(split, false);
1234         uiItemR(row, ptr, "range", 0, NULL, ICON_NONE);
1235         uiItemR(row, ptr, "use_x_ray", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
1236 }
1237
1238 static void draw_brick_sensor(uiLayout *layout, PointerRNA *ptr, bContext *C)
1239 {
1240         uiLayout *box;
1241         
1242         if (!RNA_boolean_get(ptr, "show_expanded"))
1243                 return;
1244
1245         draw_sensor_internal_header(layout, ptr);
1246         
1247         box = uiLayoutBox(layout);
1248         uiLayoutSetActive(box, RNA_boolean_get(ptr, "active"));
1249
1250         switch (RNA_enum_get(ptr, "type")) {
1251
1252                 case SENS_ACTUATOR:
1253                         draw_sensor_actuator(box, ptr);
1254                         break;
1255                 case SENS_ALWAYS:
1256                         break;
1257                 case SENS_ARMATURE:
1258                         draw_sensor_armature(box, ptr);
1259                         break;
1260                 case SENS_COLLISION:
1261                         draw_sensor_collision(box, ptr, C);
1262                         break;
1263                 case SENS_DELAY:
1264                         draw_sensor_delay(box, ptr);
1265                         break;
1266                 case SENS_JOYSTICK:
1267                         draw_sensor_joystick(box, ptr);
1268                         break;
1269                 case SENS_KEYBOARD:
1270                         draw_sensor_keyboard(box, ptr);
1271                         break;
1272                 case SENS_MESSAGE:
1273                         draw_sensor_message(box, ptr);
1274                         break;
1275                 case SENS_MOUSE:
1276                         draw_sensor_mouse(box, ptr);
1277                         break;
1278                 case SENS_NEAR:
1279                         draw_sensor_near(box, ptr);
1280                         break;
1281                 case SENS_PROPERTY:
1282                         draw_sensor_property(box, ptr);
1283                         break;
1284                 case SENS_RADAR:
1285                         draw_sensor_radar(box, ptr);
1286                         break;
1287                 case SENS_RANDOM:
1288                         draw_sensor_random(box, ptr);
1289                         break;
1290                 case SENS_RAY:
1291                         draw_sensor_ray(box, ptr, C);
1292                         break;
1293         }
1294 }
1295
1296 /* Controller code */
1297 static void draw_controller_header(uiLayout *layout, PointerRNA *ptr, int xco, int width, int yco)
1298 {
1299         uiLayout *box, *row, *sub;
1300         bController *cont= (bController *)ptr->data;
1301
1302         char state[3];
1303         BLI_snprintf(state, sizeof(state), "%d", RNA_int_get(ptr, "states"));
1304         
1305         box = uiLayoutBox(layout);
1306         row = uiLayoutRow(box, false);
1307         
1308         sub = uiLayoutRow(row, false);
1309         uiLayoutSetActive(sub, RNA_boolean_get(ptr, "active"));
1310         uiItemR(sub, ptr, "show_expanded", UI_ITEM_R_NO_BG, "", ICON_NONE);
1311         if (RNA_boolean_get(ptr, "show_expanded")) {
1312                 uiItemR(sub, ptr, "type", 0, "", ICON_NONE);
1313                 uiItemR(sub, ptr, "name", 0, "", ICON_NONE);
1314                 /* XXX provisory for Blender 2.50Beta */
1315                 uiDefBlockBut(uiLayoutGetBlock(layout), controller_state_mask_menu, cont, state, (short)(xco+width-44), yco, 22+22, UI_UNIT_Y, IFACE_("Set controller state index (from 1 to 30)"));
1316         }
1317         else {
1318                 uiItemL(sub, IFACE_(controller_name(cont->type)), ICON_NONE);
1319                 uiItemL(sub, cont->name, ICON_NONE);
1320                 uiItemL(sub, state, ICON_NONE);
1321         }
1322
1323         sub = uiLayoutRow(row, false);
1324         uiLayoutSetActive(sub, RNA_boolean_get(ptr, "active"));
1325         uiItemR(sub, ptr, "use_priority", 0, "", ICON_NONE);
1326
1327         if (RNA_boolean_get(ptr, "show_expanded")==0) {
1328                 sub = uiLayoutRow(row, true);
1329                 uiLayoutSetActive(sub, RNA_boolean_get(ptr, "active"));
1330                 uiItemEnumO(sub, "LOGIC_OT_controller_move", "", ICON_TRIA_UP, "direction", 1); // up
1331                 uiItemEnumO(sub, "LOGIC_OT_controller_move", "", ICON_TRIA_DOWN, "direction", 2); // down
1332         }
1333
1334         sub = uiLayoutRow(row, false);
1335         uiItemR(sub, ptr, "active", 0, "", ICON_NONE);
1336
1337         sub = uiLayoutRow(row, false);
1338         uiLayoutSetActive(sub, RNA_boolean_get(ptr, "active"));
1339         uiItemO(sub, "", ICON_X, "LOGIC_OT_controller_remove");
1340 }
1341
1342 static void draw_controller_expression(uiLayout *layout, PointerRNA *ptr)
1343 {
1344         uiItemR(layout, ptr, "expression", 0, "", ICON_NONE);
1345 }
1346
1347 static void draw_controller_python(uiLayout *layout, PointerRNA *ptr)
1348 {
1349         uiLayout *split, *sub;
1350
1351         split = uiLayoutSplit(layout, 0.3, true);
1352         uiItemR(split, ptr, "mode", 0, "", ICON_NONE);
1353         if (RNA_enum_get(ptr, "mode") == CONT_PY_SCRIPT) {
1354                 uiItemR(split, ptr, "text", 0, "", ICON_NONE);
1355         }
1356         else {
1357                 sub = uiLayoutSplit(split, 0.8f, false);
1358                 uiItemR(sub, ptr, "module", 0, "", ICON_NONE);
1359                 uiItemR(sub, ptr, "use_debug", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
1360         }
1361 }
1362
1363 static void draw_controller_state(uiLayout *UNUSED(layout), PointerRNA *UNUSED(ptr))
1364 {
1365
1366 }
1367
1368 static void draw_brick_controller(uiLayout *layout, PointerRNA *ptr)
1369 {
1370         uiLayout *box;
1371         
1372         if (!RNA_boolean_get(ptr, "show_expanded"))
1373                 return;
1374         
1375         box = uiLayoutBox(layout);
1376         uiLayoutSetActive(box, RNA_boolean_get(ptr, "active"));
1377
1378         draw_controller_state(box, ptr);
1379         
1380         switch (RNA_enum_get(ptr, "type")) {
1381                 case CONT_LOGIC_AND:
1382                         break;
1383                 case CONT_LOGIC_OR:
1384                         break;
1385                 case CONT_EXPRESSION:
1386                         draw_controller_expression(box, ptr);
1387                         break;
1388                 case CONT_PYTHON:
1389                         draw_controller_python(box, ptr);
1390                         break;
1391                 case CONT_LOGIC_NAND:
1392                         break;
1393                 case CONT_LOGIC_NOR:
1394                         break;
1395                 case CONT_LOGIC_XOR:
1396                         break;
1397                 case CONT_LOGIC_XNOR:
1398                         break;
1399         }
1400 }
1401
1402 /* Actuator code */
1403 static void draw_actuator_header(uiLayout *layout, PointerRNA *ptr, PointerRNA *logic_ptr)
1404 {
1405         uiLayout *box, *row, *sub;
1406         bActuator *act= (bActuator *)ptr->data;
1407         
1408         box = uiLayoutBox(layout);
1409         row = uiLayoutRow(box, false);
1410
1411         sub = uiLayoutRow(row, false);
1412         uiLayoutSetActive(sub, RNA_boolean_get(ptr, "active"));
1413         uiItemR(sub, ptr, "show_expanded", UI_ITEM_R_NO_BG, "", ICON_NONE);
1414         if (RNA_boolean_get(ptr, "show_expanded")) {
1415                 uiItemR(sub, ptr, "type", 0, "", ICON_NONE);
1416                 uiItemR(sub, ptr, "name", 0, "", ICON_NONE);
1417         }
1418         else {
1419                 uiItemL(sub, IFACE_(actuator_name(act->type)), ICON_NONE);
1420                 uiItemL(sub, act->name, ICON_NONE);
1421         }
1422
1423         sub = uiLayoutRow(row, false);
1424         uiLayoutSetActive(sub, (((RNA_boolean_get(logic_ptr, "show_actuators_active_states") &&
1425                                   RNA_boolean_get(ptr, "show_expanded")) || RNA_boolean_get(ptr, "pin")) &&
1426                                   RNA_boolean_get(ptr, "active")));
1427         uiItemR(sub, ptr, "pin", UI_ITEM_R_NO_BG, "", ICON_NONE);
1428
1429         if (RNA_boolean_get(ptr, "show_expanded")==0) {
1430                 sub = uiLayoutRow(row, true);
1431                 uiLayoutSetActive(sub, RNA_boolean_get(ptr, "active"));
1432                 uiItemEnumO(sub, "LOGIC_OT_actuator_move", "", ICON_TRIA_UP, "direction", 1); // up
1433                 uiItemEnumO(sub, "LOGIC_OT_actuator_move", "", ICON_TRIA_DOWN, "direction", 2); // down
1434         }
1435
1436         sub = uiLayoutRow(row, false);
1437         uiItemR(sub, ptr, "active", 0, "", ICON_NONE);
1438
1439         sub = uiLayoutRow(row, false);
1440         uiLayoutSetActive(sub, RNA_boolean_get(ptr, "active"));
1441         uiItemO(sub, "", ICON_X, "LOGIC_OT_actuator_remove");
1442 }
1443
1444 static void draw_actuator_action(uiLayout *layout, PointerRNA *ptr)
1445 {
1446         Object *ob = (Object *)ptr->id.data;
1447         PointerRNA settings_ptr;
1448         uiLayout *row, *sub;
1449
1450         RNA_pointer_create((ID *)ob, &RNA_GameObjectSettings, ob, &settings_ptr);
1451
1452         row = uiLayoutRow(layout, false);
1453         uiItemR(row, ptr, "play_mode", 0, "", ICON_NONE);
1454
1455         sub = uiLayoutRow(row, true);
1456         uiItemR(sub, ptr, "use_force", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
1457         uiItemR(sub, ptr, "use_additive", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
1458
1459         row = uiLayoutColumn(sub, false);
1460         uiLayoutSetActive(row, (RNA_boolean_get(ptr, "use_additive") || RNA_boolean_get(ptr, "use_force")));
1461         uiItemR(row, ptr, "use_local", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
1462
1463         row = uiLayoutRow(layout, false);
1464         uiItemR(row, ptr, "action", 0, "", ICON_NONE);
1465         uiItemR(row, ptr, "use_continue_last_frame", 0, NULL, ICON_NONE);
1466
1467         row = uiLayoutRow(layout, false);
1468         if ((RNA_enum_get(ptr, "play_mode") == ACT_ACTION_FROM_PROP))
1469                 uiItemPointerR(row, ptr, "property", &settings_ptr, "properties", NULL, ICON_NONE);
1470
1471         else {
1472                 uiItemR(row, ptr, "frame_start", 0, NULL, ICON_NONE);
1473                 uiItemR(row, ptr, "frame_end", 0, NULL, ICON_NONE);
1474         }
1475
1476         uiItemR(row, ptr, "apply_to_children", 0, NULL, ICON_NONE);
1477
1478         row = uiLayoutRow(layout, false);
1479         uiItemR(row, ptr, "frame_blend_in", 0, NULL, ICON_NONE);
1480         uiItemR(row, ptr, "priority", 0, NULL, ICON_NONE);
1481
1482         row = uiLayoutRow(layout, false);
1483         uiItemR(row, ptr, "layer", 0, NULL, ICON_NONE);
1484         uiItemR(row, ptr, "layer_weight", 0, NULL, ICON_NONE);
1485         uiItemR(row, ptr, "blend_mode", 0, "", ICON_NONE);
1486
1487         uiItemPointerR(layout, ptr, "frame_property", &settings_ptr, "properties", NULL, ICON_NONE);
1488
1489 #ifdef __NLA_ACTION_BY_MOTION_ACTUATOR
1490         uiItemR(layout, "stride_length", 0, NULL, ICON_NONE);
1491 #endif
1492 }
1493
1494 static void draw_actuator_armature(uiLayout *layout, PointerRNA *ptr)
1495 {
1496         bActuator *act = (bActuator *)ptr->data;
1497         bArmatureActuator *aa = (bArmatureActuator *) act->data;
1498         Object *ob = (Object *)ptr->id.data;
1499         bConstraint *constraint = NULL;
1500         PointerRNA pose_ptr, pchan_ptr;
1501         PropertyRNA *bones_prop = NULL;
1502
1503         if (ob->type != OB_ARMATURE) {
1504                 uiItemL(layout, IFACE_("Actuator only available for armatures"), ICON_NONE);
1505                 return;
1506         }
1507         
1508         if (ob->pose) {
1509                 RNA_pointer_create((ID *)ob, &RNA_Pose, ob->pose, &pose_ptr);
1510                 bones_prop = RNA_struct_find_property(&pose_ptr, "bones");
1511         }
1512         
1513         uiItemR(layout, ptr, "mode", 0, NULL, ICON_NONE);
1514         
1515         switch (RNA_enum_get(ptr, "mode")) {
1516                 case ACT_ARM_RUN:
1517                         break;
1518                 case ACT_ARM_ENABLE:
1519                 case ACT_ARM_DISABLE:
1520                         if (ob->pose) {
1521                                 uiItemPointerR(layout, ptr, "bone", &pose_ptr, "bones", NULL, ICON_BONE_DATA);
1522
1523                                 if (RNA_property_collection_lookup_string(&pose_ptr, bones_prop, aa->posechannel, &pchan_ptr))
1524                                         uiItemPointerR(layout, ptr, "constraint", &pchan_ptr, "constraints", NULL, ICON_CONSTRAINT_BONE);
1525                         }
1526                         break;
1527                 case ACT_ARM_SETTARGET:
1528                         if (ob->pose) {
1529                                 uiItemPointerR(layout, ptr, "bone", &pose_ptr, "bones", NULL, ICON_BONE_DATA);
1530                                 
1531                                 if (RNA_property_collection_lookup_string(&pose_ptr, bones_prop, aa->posechannel, &pchan_ptr))
1532                                         uiItemPointerR(layout, ptr, "constraint", &pchan_ptr, "constraints", NULL, ICON_CONSTRAINT_BONE);
1533                         }
1534
1535                         uiItemR(layout, ptr, "target", 0, NULL, ICON_NONE);
1536
1537                         /* show second target only if the constraint supports it */
1538                         get_armature_bone_constraint(ob, aa->posechannel, aa->constraint, &constraint);
1539                         if (constraint && constraint->type == CONSTRAINT_TYPE_KINEMATIC) {
1540                                 uiItemR(layout, ptr, "secondary_target", 0, NULL, ICON_NONE);
1541                         }
1542                         break;
1543                 case ACT_ARM_SETWEIGHT:
1544                         if (ob->pose) {
1545                                 uiItemPointerR(layout, ptr, "bone", &pose_ptr, "bones", NULL, ICON_BONE_DATA);
1546                                 
1547                                 if (RNA_property_collection_lookup_string(&pose_ptr, bones_prop, aa->posechannel, &pchan_ptr))
1548                                         uiItemPointerR(layout, ptr, "constraint", &pchan_ptr, "constraints", NULL, ICON_CONSTRAINT_BONE);
1549                         }
1550
1551                         uiItemR(layout, ptr, "weight", 0, NULL, ICON_NONE);
1552                         break;
1553                 case ACT_ARM_SETINFLUENCE:
1554                         if (ob->pose) {
1555                                 uiItemPointerR(layout, ptr, "bone", &pose_ptr, "bones", NULL, ICON_BONE_DATA);
1556                                 
1557                                 if (RNA_property_collection_lookup_string(&pose_ptr, bones_prop, aa->posechannel, &pchan_ptr))
1558                                         uiItemPointerR(layout, ptr, "constraint", &pchan_ptr, "constraints", NULL, ICON_CONSTRAINT_BONE);
1559                         }
1560
1561                         uiItemR(layout, ptr, "influence", 0, NULL, ICON_NONE);
1562                         break;
1563         }
1564 }
1565
1566 static void draw_actuator_camera(uiLayout *layout, PointerRNA *ptr)
1567 {
1568         uiLayout *row;
1569         uiItemR(layout, ptr, "object", 0, NULL, ICON_NONE);
1570
1571         row = uiLayoutRow(layout, false);
1572         uiItemR(row, ptr, "height", 0, NULL, ICON_NONE);
1573         uiItemR(row, ptr, "axis", 0, NULL, ICON_NONE);
1574
1575         row = uiLayoutRow(layout, true);
1576         uiItemR(row, ptr, "min", 0, NULL, ICON_NONE);
1577         uiItemR(row, ptr, "max", 0, NULL, ICON_NONE);
1578
1579         uiItemR(layout, ptr, "damping", 0, NULL, ICON_NONE);
1580 }
1581
1582 static void draw_actuator_constraint(uiLayout *layout, PointerRNA *ptr, bContext *C)
1583 {
1584         uiLayout *row, *col, *sub, *split;
1585         PointerRNA main_ptr;
1586
1587         RNA_main_pointer_create(CTX_data_main(C), &main_ptr);
1588
1589         uiItemR(layout, ptr, "mode", 0, NULL, ICON_NONE);
1590         switch (RNA_enum_get(ptr, "mode")) {
1591                 case ACT_CONST_TYPE_LOC:
1592                         uiItemR(layout, ptr, "limit", 0, NULL, ICON_NONE);
1593
1594                         row = uiLayoutRow(layout, true);
1595                         uiItemR(row, ptr, "limit_min", 0, NULL, ICON_NONE);
1596                         uiItemR(row, ptr, "limit_max", 0, NULL, ICON_NONE);
1597
1598                         uiItemR(layout, ptr, "damping", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
1599                         break;
1600
1601                 case ACT_CONST_TYPE_DIST:
1602                         split = uiLayoutSplit(layout, 0.8, false);
1603                         uiItemR(split, ptr, "direction", 0, NULL, ICON_NONE);
1604                         row = uiLayoutRow(split, true);
1605                         uiItemR(row, ptr, "use_local", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
1606                         uiItemR(row, ptr, "use_normal", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
1607
1608                         row = uiLayoutRow(layout, false);
1609                         col = uiLayoutColumn(row, true);
1610                         uiItemL(col, IFACE_("Range:"), ICON_NONE);
1611                         uiItemR(col, ptr, "range", 0, "", ICON_NONE);
1612
1613                         col = uiLayoutColumn(row, true);
1614                         uiItemR(col, ptr, "use_force_distance", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
1615                         sub = uiLayoutColumn(col, false);
1616                         uiLayoutSetActive(sub, RNA_boolean_get(ptr, "use_force_distance") == true);
1617                         uiItemR(sub, ptr, "distance", 0, "", ICON_NONE);
1618
1619                         uiItemR(layout, ptr, "damping", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
1620
1621                         split = uiLayoutSplit(layout, 0.15f, false);
1622                         uiItemR(split, ptr, "use_material_detect", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
1623                         if (RNA_boolean_get(ptr, "use_material_detect"))
1624                                 uiItemPointerR(split, ptr, "material", &main_ptr, "materials", NULL, ICON_MATERIAL_DATA);
1625                         else
1626                                 uiItemR(split, ptr, "property", 0, NULL, ICON_NONE);
1627
1628                         split = uiLayoutSplit(layout, 0.15, false);
1629                         uiItemR(split, ptr, "use_persistent", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
1630
1631                         row = uiLayoutRow(split, true);
1632                         uiItemR(row, ptr, "time", 0, NULL, ICON_NONE);
1633                         uiItemR(row, ptr, "damping_rotation", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
1634                         break;
1635
1636                 case ACT_CONST_TYPE_ORI:
1637                         uiItemR(layout, ptr, "direction_axis_pos", 0, NULL, ICON_NONE);
1638
1639                         row=uiLayoutRow(layout, true);
1640                         uiItemR(row, ptr, "damping", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
1641                         uiItemR(row, ptr, "time", 0, NULL, ICON_NONE);
1642
1643                         row=uiLayoutRow(layout, false);
1644                         uiItemR(row, ptr, "rotation_max", 0, NULL, ICON_NONE);
1645
1646                         row=uiLayoutRow(layout, true);
1647                         uiItemR(row, ptr, "angle_min", 0, NULL, ICON_NONE);
1648                         uiItemR(row, ptr, "angle_max", 0, NULL, ICON_NONE);
1649                         break;
1650
1651                 case ACT_CONST_TYPE_FH:
1652                         split = uiLayoutSplit(layout, 0.75, false);
1653                         row = uiLayoutRow(split, false);
1654                         uiItemR(row, ptr, "fh_damping", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
1655
1656                         uiItemR(row, ptr, "fh_height", 0, NULL, ICON_NONE);
1657                         uiItemR(split, ptr, "use_fh_paralel_axis", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
1658
1659                         row = uiLayoutRow(layout, false);
1660                         uiItemR(row, ptr, "direction_axis", 0, NULL, ICON_NONE);
1661                         split = uiLayoutSplit(row, 0.9f, false);
1662                         uiItemR(split, ptr, "fh_force", 0, NULL, ICON_NONE);
1663                         uiItemR(split, ptr, "use_fh_normal", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
1664
1665                         split = uiLayoutSplit(layout, 0.15, false);
1666                         uiItemR(split, ptr, "use_material_detect", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
1667                         if (RNA_boolean_get(ptr, "use_material_detect"))
1668                                 uiItemPointerR(split, ptr, "material", &main_ptr, "materials", NULL, ICON_MATERIAL_DATA);
1669                         else
1670                                 uiItemR(split, ptr, "property", 0, NULL, ICON_NONE);
1671
1672                         split = uiLayoutSplit(layout, 0.15, false);
1673                         uiItemR(split, ptr, "use_persistent", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
1674
1675                         row = uiLayoutRow(split, false);
1676                         uiItemR(row, ptr, "time", 0, NULL, ICON_NONE);
1677                         uiItemR(row, ptr, "damping_rotation", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
1678                         break;
1679         }
1680 }
1681
1682 static void draw_actuator_edit_object(uiLayout *layout, PointerRNA *ptr)
1683 {
1684         Object *ob = (Object *)ptr->id.data;
1685         uiLayout *row, *split, *sub;
1686         uiItemR(layout, ptr, "mode", 0, NULL, ICON_NONE);
1687
1688         switch (RNA_enum_get(ptr, "mode")) {
1689                 case ACT_EDOB_ADD_OBJECT:
1690                         row = uiLayoutRow(layout, false);
1691                         uiItemR(row, ptr, "object", 0, NULL, ICON_NONE);
1692                         uiItemR(row, ptr, "time", 0, NULL, ICON_NONE);
1693
1694                         split = uiLayoutSplit(layout, 0.9, false);
1695                         row = uiLayoutRow(split, false);
1696                         uiItemR(row, ptr, "linear_velocity", 0, NULL, ICON_NONE);
1697                         uiItemR(split, ptr, "use_local_linear_velocity", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
1698
1699                         split = uiLayoutSplit(layout, 0.9, false);
1700                         row = uiLayoutRow(split, false);
1701                         uiItemR(row, ptr, "angular_velocity", 0, NULL, ICON_NONE);
1702                         uiItemR(split, ptr, "use_local_angular_velocity", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
1703                         break;
1704                 case ACT_EDOB_END_OBJECT:
1705                         break;
1706                 case ACT_EDOB_REPLACE_MESH:
1707                         if (ob->type != OB_MESH) {
1708                                 uiItemL(layout, IFACE_("Mode only available for mesh objects"), ICON_NONE);
1709                                 break;
1710                         }
1711                         split = uiLayoutSplit(layout, 0.6, false);
1712                         uiItemR(split, ptr, "mesh", 0, NULL, ICON_NONE);
1713                         row = uiLayoutRow(split, false);
1714                         uiItemR(row, ptr, "use_replace_display_mesh", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
1715                         uiItemR(row, ptr, "use_replace_physics_mesh", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
1716                         break;
1717                 case ACT_EDOB_TRACK_TO:
1718                         split = uiLayoutSplit(layout, 0.5, false);
1719                         uiItemR(split, ptr, "track_object", 0, NULL, ICON_NONE);
1720                         sub = uiLayoutSplit(split, 0.7f, false);
1721                         uiItemR(sub, ptr, "time", 0, NULL, ICON_NONE);
1722                         uiItemR(sub, ptr, "use_3d_tracking", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
1723                         break;
1724                 case ACT_EDOB_DYNAMICS:
1725                         if (ob->type != OB_MESH) {
1726                                 uiItemL(layout, IFACE_("Mode only available for mesh objects"), ICON_NONE);
1727                                 break;
1728                         }
1729                         uiItemR(layout, ptr, "dynamic_operation", 0, NULL, ICON_NONE);
1730                         if (RNA_enum_get(ptr, "dynamic_operation") == ACT_EDOB_SET_MASS)
1731                                 uiItemR(layout, ptr, "mass", 0, NULL, ICON_NONE);
1732                         break;
1733         }
1734 }
1735
1736 static void draw_actuator_filter_2d(uiLayout *layout, PointerRNA *ptr)
1737 {
1738         uiLayout *row, *split;
1739
1740         uiItemR(layout, ptr, "mode", 0, NULL, ICON_NONE);
1741         switch (RNA_enum_get(ptr, "mode")) {
1742                 case ACT_2DFILTER_CUSTOMFILTER:
1743                         uiItemR(layout, ptr, "filter_pass", 0, NULL, ICON_NONE);
1744                         uiItemR(layout, ptr, "glsl_shader", 0, NULL, ICON_NONE);
1745                         break;
1746                 case ACT_2DFILTER_MOTIONBLUR:
1747                         split=uiLayoutSplit(layout, 0.75f, true);
1748                         row = uiLayoutRow(split, false);
1749                         uiLayoutSetActive(row, RNA_boolean_get(ptr, "use_motion_blur") == true);
1750                         uiItemR(row, ptr, "motion_blur_factor", 0, NULL, ICON_NONE);
1751                         uiItemR(split, ptr, "use_motion_blur", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
1752                         break;
1753                 default: // all other 2D Filters
1754                         uiItemR(layout, ptr, "filter_pass", 0, NULL, ICON_NONE);
1755                         break;
1756         }
1757 }
1758
1759 static void draw_actuator_game(uiLayout *layout, PointerRNA *ptr)
1760 {
1761         uiItemR(layout, ptr, "mode", 0, NULL, ICON_NONE);
1762         if (RNA_enum_get(ptr, "mode") == ACT_GAME_LOAD)
1763                 uiItemR(layout, ptr, "filename", 0, NULL, ICON_NONE);
1764 }
1765
1766 static void draw_actuator_message(uiLayout *layout, PointerRNA *ptr, bContext *C)
1767 {
1768         Object *ob;
1769         PointerRNA main_ptr, settings_ptr;
1770         uiLayout *row;
1771
1772         RNA_main_pointer_create(CTX_data_main(C), &main_ptr);
1773
1774         ob = (Object *)ptr->id.data;
1775         RNA_pointer_create((ID *)ob, &RNA_GameObjectSettings, ob, &settings_ptr);
1776
1777         uiItemPointerR(layout, ptr, "to_property", &main_ptr, "objects", NULL, ICON_OBJECT_DATA);
1778         uiItemR(layout, ptr, "subject", 0, NULL, ICON_NONE);
1779
1780         row = uiLayoutRow(layout, true);
1781         uiItemR(row, ptr, "body_type", 0, NULL, ICON_NONE);
1782
1783         if (RNA_enum_get(ptr, "body_type") == ACT_MESG_MESG)
1784                 uiItemR(row, ptr, "body_message", 0, "", ICON_NONE);
1785         else // mode == ACT_MESG_PROP
1786                 uiItemPointerR(row, ptr, "body_property", &settings_ptr, "properties", "", ICON_NONE);
1787 }
1788
1789 static void draw_actuator_motion(uiLayout *layout, PointerRNA *ptr)
1790 {
1791         Object *ob;
1792         PointerRNA settings_ptr;
1793         uiLayout *split, *row, *col, *sub;
1794         int physics_type;
1795
1796         ob = (Object *)ptr->id.data;
1797         RNA_pointer_create((ID *)ob, &RNA_GameObjectSettings, ob, &settings_ptr);
1798         physics_type = RNA_enum_get(&settings_ptr, "physics_type");
1799         
1800         uiItemR(layout, ptr, "mode", 0, NULL, ICON_NONE);
1801         
1802         switch (RNA_enum_get(ptr, "mode")) {
1803                 case ACT_OBJECT_NORMAL:
1804                         split = uiLayoutSplit(layout, 0.9, false);
1805                         row = uiLayoutRow(split, false);
1806                         uiItemR(row, ptr, "offset_location", 0, NULL, ICON_NONE);
1807                         uiItemR(split, ptr, "use_local_location", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
1808
1809                         split = uiLayoutSplit(layout, 0.9, false);
1810                         row = uiLayoutRow(split, false);
1811                         uiItemR(row, ptr, "offset_rotation", 0, NULL, ICON_NONE);
1812                         uiItemR(split, ptr, "use_local_rotation", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
1813                         
1814                         if (ELEM3(physics_type, OB_BODY_TYPE_DYNAMIC, OB_BODY_TYPE_RIGID, OB_BODY_TYPE_SOFT)) {
1815                                 uiItemL(layout, IFACE_("Dynamic Object Settings:"), ICON_NONE);
1816                                 split = uiLayoutSplit(layout, 0.9, false);
1817                                 row = uiLayoutRow(split, false);
1818                                 uiItemR(row, ptr, "force", 0, NULL, ICON_NONE);
1819                                 uiItemR(split, ptr, "use_local_force", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
1820
1821                                 split = uiLayoutSplit(layout, 0.9, false);
1822                                 row = uiLayoutRow(split, false);
1823                                 uiItemR(row, ptr, "torque", 0, NULL, ICON_NONE);
1824                                 uiItemR(split, ptr, "use_local_torque", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
1825
1826                                 split = uiLayoutSplit(layout, 0.9, false);
1827                                 row = uiLayoutRow(split, false);
1828                                 uiItemR(row, ptr, "linear_velocity", 0, NULL, ICON_NONE);
1829                                 row = uiLayoutRow(split, true);
1830                                 uiItemR(row, ptr, "use_local_linear_velocity", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
1831                                 uiItemR(row, ptr, "use_add_linear_velocity", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
1832
1833                                 split = uiLayoutSplit(layout, 0.9, false);
1834                                 row = uiLayoutRow(split, false);
1835                                 uiItemR(row, ptr, "angular_velocity", 0, NULL, ICON_NONE);
1836                                 uiItemR(split, ptr, "use_local_angular_velocity", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
1837
1838                                 uiItemR(layout, ptr, "damping", 0, NULL, ICON_NONE);
1839                         }
1840                         break;
1841                 case ACT_OBJECT_SERVO:
1842                         uiItemR(layout, ptr, "reference_object", 0, NULL, ICON_NONE);
1843
1844                         split = uiLayoutSplit(layout, 0.9, false);
1845                         row = uiLayoutRow(split, false);
1846                         uiItemR(row, ptr, "linear_velocity", 0, NULL, ICON_NONE);
1847                         uiItemR(split, ptr, "use_local_linear_velocity", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
1848
1849                         row = uiLayoutRow(layout, false);
1850                         col = uiLayoutColumn(row, false);
1851                         uiItemR(col, ptr, "use_servo_limit_x", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
1852                         sub = uiLayoutColumn(col, true);
1853                         uiLayoutSetActive(sub, RNA_boolean_get(ptr, "use_servo_limit_x") == true);
1854                         uiItemR(sub, ptr, "force_max_x", 0, NULL, ICON_NONE);
1855                         uiItemR(sub, ptr, "force_min_x", 0, NULL, ICON_NONE);
1856
1857                         col = uiLayoutColumn(row, false);
1858                         uiItemR(col, ptr, "use_servo_limit_y", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
1859                         sub = uiLayoutColumn(col, true);
1860                         uiLayoutSetActive(sub, RNA_boolean_get(ptr, "use_servo_limit_y") == true);
1861                         uiItemR(sub, ptr, "force_max_y", 0, NULL, ICON_NONE);
1862                         uiItemR(sub, ptr, "force_min_y", 0, NULL, ICON_NONE);
1863
1864                         col = uiLayoutColumn(row, false);
1865                         uiItemR(col, ptr, "use_servo_limit_z", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
1866                         sub = uiLayoutColumn(col, true);
1867                         uiLayoutSetActive(sub, RNA_boolean_get(ptr, "use_servo_limit_z") == true);
1868                         uiItemR(sub, ptr, "force_max_z", 0, NULL, ICON_NONE);
1869                         uiItemR(sub, ptr, "force_min_z", 0, NULL, ICON_NONE);
1870
1871                         //XXXACTUATOR missing labels from original 2.49 ui (e.g. Servo, Min, Max, Fast)
1872                         //Layout designers willing to help on that, please compare with 2.49 ui
1873                         // (since the old code is going to be deleted ... soon)
1874
1875                         col = uiLayoutColumn(layout, true);
1876                         uiItemR(col, ptr, "proportional_coefficient", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
1877                         uiItemR(col, ptr, "integral_coefficient", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
1878                         uiItemR(col, ptr, "derivate_coefficient", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
1879                         break;
1880                 case ACT_OBJECT_CHARACTER:
1881                         split = uiLayoutSplit(layout, 0.9, false);
1882                         row = uiLayoutRow(split, false);
1883                         uiItemR(row, ptr, "offset_location", 0, NULL, ICON_NONE);
1884                         row = uiLayoutRow(split, true);
1885                         uiItemR(row, ptr, "use_local_location", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
1886                         uiItemR(row, ptr, "use_add_character_location", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
1887
1888                         split = uiLayoutSplit(layout, 0.9, false);
1889                         row = uiLayoutRow(split, false);
1890                         uiItemR(row, ptr, "offset_rotation", 0, NULL, ICON_NONE);
1891                         uiItemR(split, ptr, "use_local_rotation", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
1892
1893                         split = uiLayoutSplit(layout, 0.9, false);
1894                         row = uiLayoutRow(split, false);
1895                         split = uiLayoutSplit(row, 0.7, false);
1896                         uiItemL(split, "", ICON_NONE); /*Just use this for some spacing */
1897                         uiItemR(split, ptr, "use_character_jump", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
1898                         break;
1899         }
1900 }
1901
1902 static void draw_actuator_parent(uiLayout *layout, PointerRNA *ptr)
1903 {
1904         uiLayout *row, *sub;
1905
1906         uiItemR(layout, ptr, "mode", 0, NULL, ICON_NONE);
1907
1908         if (RNA_enum_get(ptr, "mode") == ACT_PARENT_SET) {
1909                 uiItemR(layout, ptr, "object", 0, NULL, ICON_NONE);
1910
1911                 row = uiLayoutRow(layout, false);
1912                 uiItemR(row, ptr, "use_compound", 0, NULL, ICON_NONE);
1913                 sub = uiLayoutRow(row, false);
1914                 uiLayoutSetActive(sub, RNA_boolean_get(ptr, "use_compound") == true);
1915                 uiItemR(sub, ptr, "use_ghost", 0, NULL, ICON_NONE);
1916         }
1917 }
1918
1919 static void draw_actuator_property(uiLayout *layout, PointerRNA *ptr)
1920 {
1921         Object *ob = (Object *)ptr->id.data;
1922         bActuator *act = (bActuator *)ptr->data;
1923         bPropertyActuator *pa = (bPropertyActuator *) act->data;
1924         Object *ob_from= pa->ob;
1925         PointerRNA settings_ptr, obj_settings_ptr;
1926
1927         uiLayout *row, *sub;
1928
1929         RNA_pointer_create((ID *)ob, &RNA_GameObjectSettings, ob, &settings_ptr);
1930
1931         uiItemR(layout, ptr, "mode", 0, NULL, ICON_NONE);
1932         uiItemPointerR(layout, ptr, "property", &settings_ptr, "properties", NULL, ICON_NONE);
1933
1934         switch (RNA_enum_get(ptr, "mode")) {
1935                 case ACT_PROP_TOGGLE:
1936                         break;
1937                 case ACT_PROP_ADD:
1938                         uiItemR(layout, ptr, "value", 0, NULL, ICON_NONE);
1939                         break;
1940                 case ACT_PROP_ASSIGN:
1941                         uiItemR(layout, ptr, "value", 0, NULL, ICON_NONE);
1942                         break;
1943                 case ACT_PROP_COPY:
1944                         row = uiLayoutRow(layout, false);
1945                         uiItemR(row, ptr, "object", 0, NULL, ICON_NONE);
1946                         if (ob_from) {
1947                                 RNA_pointer_create((ID *)ob_from, &RNA_GameObjectSettings, ob_from, &obj_settings_ptr);
1948                                 uiItemPointerR(row, ptr, "object_property", &obj_settings_ptr, "properties", NULL, ICON_NONE);
1949                         }
1950                         else {
1951                                 sub = uiLayoutRow(row, false);
1952                                 uiLayoutSetActive(sub, false);
1953                                 uiItemR(sub, ptr, "object_property", 0, NULL, ICON_NONE);
1954                         }
1955                         break;
1956         }
1957 }
1958
1959 static void draw_actuator_random(uiLayout *layout, PointerRNA *ptr)
1960 {
1961         Object *ob;
1962         PointerRNA settings_ptr;
1963         uiLayout *row;
1964
1965         ob = (Object *)ptr->id.data;
1966         RNA_pointer_create((ID *)ob, &RNA_GameObjectSettings, ob, &settings_ptr);
1967
1968         row = uiLayoutRow(layout, false);
1969
1970         uiItemR(row, ptr, "seed", 0, NULL, ICON_NONE);
1971         uiItemR(row, ptr, "distribution", 0, NULL, ICON_NONE);
1972
1973         row = uiLayoutRow(layout, false);
1974         uiItemPointerR(row, ptr, "property", &settings_ptr, "properties", NULL, ICON_NONE);
1975
1976         row = uiLayoutRow(layout, false);
1977
1978         switch (RNA_enum_get(ptr, "distribution")) {
1979                 case ACT_RANDOM_BOOL_CONST:
1980                         uiItemR(row, ptr, "use_always_true", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
1981                         break;
1982
1983                 case ACT_RANDOM_BOOL_UNIFORM:
1984                         uiItemL(row, IFACE_("Choose between true and false, 50% chance each"), ICON_NONE);
1985                         break;
1986
1987                 case ACT_RANDOM_BOOL_BERNOUILLI:
1988                         uiItemR(row, ptr, "chance", 0, NULL, ICON_NONE);
1989                         break;
1990
1991                 case ACT_RANDOM_INT_CONST:
1992                         uiItemR(row, ptr, "int_value", 0, NULL, ICON_NONE);
1993                         break;
1994
1995                 case ACT_RANDOM_INT_UNIFORM:
1996                         uiItemR(row, ptr, "int_min", 0, NULL, ICON_NONE);
1997                         uiItemR(row, ptr, "int_max", 0, NULL, ICON_NONE);
1998                         break;
1999
2000                 case ACT_RANDOM_INT_POISSON:
2001                         uiItemR(row, ptr, "int_mean", 0, NULL, ICON_NONE);
2002                         break;
2003
2004                 case ACT_RANDOM_FLOAT_CONST:
2005                         uiItemR(row, ptr, "float_value", 0, NULL, ICON_NONE);
2006                         break;
2007
2008                 case ACT_RANDOM_FLOAT_UNIFORM:
2009                         uiItemR(row, ptr, "float_min", 0, NULL, ICON_NONE);
2010                         uiItemR(row, ptr, "float_max", 0, NULL, ICON_NONE);
2011                         break;
2012
2013                 case ACT_RANDOM_FLOAT_NORMAL:
2014                         uiItemR(row, ptr, "float_mean", 0, NULL, ICON_NONE);
2015                         uiItemR(row, ptr, "standard_derivation", 0, NULL, ICON_NONE);
2016                         break;
2017
2018                 case ACT_RANDOM_FLOAT_NEGATIVE_EXPONENTIAL:
2019                         uiItemR(row, ptr, "half_life_time", 0, NULL, ICON_NONE);
2020                         break;
2021         }
2022 }
2023
2024 static void draw_actuator_scene(uiLayout *layout, PointerRNA *ptr)
2025 {
2026         uiItemR(layout, ptr, "mode", 0, NULL, ICON_NONE);
2027
2028         switch (RNA_enum_get(ptr, "mode")) {
2029                 case ACT_SCENE_CAMERA:
2030                         uiItemR(layout, ptr, "camera", 0, NULL, ICON_NONE);
2031                         break;
2032                 case ACT_SCENE_RESTART:
2033                         break;
2034                 default: // ACT_SCENE_SET|ACT_SCENE_ADD_FRONT|ACT_SCENE_ADD_BACK|ACT_SCENE_REMOVE|ACT_SCENE_SUSPEND|ACT_SCENE_RESUME
2035                         uiItemR(layout, ptr, "scene", 0, NULL, ICON_NONE);
2036                         break;
2037         }
2038 }
2039
2040 static void draw_actuator_shape_action(uiLayout *layout, PointerRNA *ptr)
2041 {
2042         Object *ob = (Object *)ptr->id.data;
2043         PointerRNA settings_ptr;
2044         uiLayout *row;
2045
2046         if (ob->type != OB_MESH) {
2047                 uiItemL(layout, IFACE_("Actuator only available for mesh objects"), ICON_NONE);
2048                 return;
2049         }
2050
2051         RNA_pointer_create((ID *)ob, &RNA_GameObjectSettings, ob, &settings_ptr);
2052
2053         row = uiLayoutRow(layout, false);
2054         uiItemR(row, ptr, "mode", 0, "", ICON_NONE);
2055         uiItemR(row, ptr, "action", 0, "", ICON_NONE);
2056         uiItemR(row, ptr, "use_continue_last_frame", 0, NULL, ICON_NONE);
2057
2058         row = uiLayoutRow(layout, false);
2059         if ((RNA_enum_get(ptr, "mode") == ACT_ACTION_FROM_PROP))
2060                 uiItemPointerR(row, ptr, "property", &settings_ptr, "properties", NULL, ICON_NONE);
2061
2062         else {
2063                 uiItemR(row, ptr, "frame_start", 0, NULL, ICON_NONE);
2064                 uiItemR(row, ptr, "frame_end", 0, NULL, ICON_NONE);
2065         }
2066
2067         row = uiLayoutRow(layout, false);
2068         uiItemR(row, ptr, "frame_blend_in", 0, NULL, ICON_NONE);
2069         uiItemR(row, ptr, "priority", 0, NULL, ICON_NONE);
2070
2071         row = uiLayoutRow(layout, false);
2072         uiItemPointerR(row, ptr, "frame_property", &settings_ptr, "properties", NULL, ICON_NONE);
2073
2074 #ifdef __NLA_ACTION_BY_MOTION_ACTUATOR
2075         uiItemR(row, "stride_length", 0, NULL, ICON_NONE);
2076 #endif
2077 }
2078
2079 static void draw_actuator_sound(uiLayout *layout, PointerRNA *ptr, bContext *C)
2080 {
2081         uiLayout *row, *col;
2082
2083         uiTemplateID(layout, C, ptr, "sound", NULL, "SOUND_OT_open", NULL);
2084         if (!RNA_pointer_get(ptr, "sound").data) {
2085                 uiItemL(layout, IFACE_("Select a sound from the list or load a new one"), ICON_NONE);
2086                 return;
2087         }
2088         uiItemR(layout, ptr, "mode", 0, NULL, ICON_NONE);
2089
2090         row = uiLayoutRow(layout, false);
2091         uiItemR(row, ptr, "volume", 0, NULL, ICON_NONE);
2092         uiItemR(row, ptr, "pitch", 0, NULL, ICON_NONE);
2093
2094         uiItemR(layout, ptr, "use_sound_3d", 0, NULL, ICON_NONE);
2095         
2096         col = uiLayoutColumn(layout, false);
2097         uiLayoutSetActive(col, RNA_boolean_get(ptr, "use_sound_3d") == true);
2098
2099         row = uiLayoutRow(col, false);
2100         uiItemR(row, ptr, "gain_3d_min", 0, NULL, ICON_NONE);
2101         uiItemR(row, ptr, "gain_3d_max", 0, NULL, ICON_NONE);
2102
2103         row = uiLayoutRow(col, false);
2104         uiItemR(row, ptr, "distance_3d_reference", 0, NULL, ICON_NONE);
2105         uiItemR(row, ptr, "distance_3d_max", 0, NULL, ICON_NONE);
2106
2107         row = uiLayoutRow(col, false);
2108         uiItemR(row, ptr, "rolloff_factor_3d", 0, NULL, ICON_NONE);
2109         uiItemR(row, ptr, "cone_outer_gain_3d", 0, NULL, ICON_NONE);
2110
2111         row = uiLayoutRow(col, false);
2112         uiItemR(row, ptr, "cone_outer_angle_3d", 0, NULL, ICON_NONE);
2113         uiItemR(row, ptr, "cone_inner_angle_3d", 0, NULL, ICON_NONE);
2114 }
2115
2116 static void draw_actuator_state(uiLayout *layout, PointerRNA *ptr)
2117 {
2118         uiLayout *split;
2119         Object *ob = (Object *)ptr->id.data;
2120         PointerRNA settings_ptr;
2121         RNA_pointer_create((ID *)ob, &RNA_GameObjectSettings, ob, &settings_ptr);
2122
2123         split = uiLayoutSplit(layout, 0.35, false);
2124         uiItemR(split, ptr, "operation", 0, NULL, ICON_NONE);
2125
2126         uiTemplateLayers(split, ptr, "states", &settings_ptr, "used_states", 0);
2127 }
2128
2129 static void draw_actuator_visibility(uiLayout *layout, PointerRNA *ptr)
2130 {
2131         uiLayout *row;
2132         row = uiLayoutRow(layout, false);
2133
2134         uiItemR(row, ptr, "use_visible", 0, NULL, ICON_NONE);
2135         uiItemR(row, ptr, "use_occlusion", 0, NULL, ICON_NONE);
2136         uiItemR(row, ptr, "apply_to_children", 0, NULL, ICON_NONE);
2137 }
2138
2139 static void draw_actuator_steering(uiLayout *layout, PointerRNA *ptr)
2140 {
2141         uiLayout *row;
2142         uiLayout *col;
2143
2144         uiItemR(layout, ptr, "mode", 0, NULL, ICON_NONE);
2145         uiItemR(layout, ptr, "target", 0, NULL, ICON_NONE);
2146         uiItemR(layout, ptr, "navmesh", 0, NULL, ICON_NONE);
2147
2148         row = uiLayoutRow(layout, false);
2149         uiItemR(row, ptr, "distance", 0, NULL, ICON_NONE);
2150         uiItemR(row, ptr, "velocity", 0, NULL, ICON_NONE);
2151         row = uiLayoutRow(layout, false);
2152         uiItemR(row, ptr, "acceleration", 0, NULL, ICON_NONE);
2153         uiItemR(row, ptr, "turn_speed", 0, NULL, ICON_NONE);
2154
2155         row = uiLayoutRow(layout, false);
2156         col = uiLayoutColumn(row, false);
2157         uiItemR(col, ptr, "facing", 0, NULL, ICON_NONE);
2158         col = uiLayoutColumn(row, false);
2159         uiItemR(col, ptr, "facing_axis", 0, NULL, ICON_NONE);
2160         if (!RNA_boolean_get(ptr, "facing")) {
2161                 uiLayoutSetActive(col, false);
2162         }
2163         col = uiLayoutColumn(row, false);
2164         uiItemR(col, ptr, "normal_up", 0, NULL, ICON_NONE);
2165         if (!RNA_pointer_get(ptr, "navmesh").data) {
2166                 uiLayoutSetActive(col, false);
2167         }
2168
2169         row = uiLayoutRow(layout, false);
2170         uiItemR(row, ptr, "self_terminated", 0, NULL, ICON_NONE);
2171         if (RNA_enum_get(ptr, "mode")==ACT_STEERING_PATHFOLLOWING) {
2172                 uiItemR(row, ptr, "update_period", 0, NULL, ICON_NONE);
2173                 row = uiLayoutRow(layout, false);
2174         }
2175         row = uiLayoutRow(layout, false);
2176         uiItemR(row, ptr, "show_visualization", 0, NULL, ICON_NONE);
2177         if (RNA_enum_get(ptr, "mode") != ACT_STEERING_PATHFOLLOWING) {
2178                 uiLayoutSetActive(row, false);
2179         }
2180 }
2181
2182 static void draw_actuator_mouse(uiLayout *layout, PointerRNA *ptr)
2183 {
2184         uiLayout *row, *col, *subcol, *split, *subsplit;
2185
2186         uiItemR(layout, ptr, "mode", 0, NULL, 0);
2187
2188         switch (RNA_enum_get(ptr, "mode")) {
2189                 case ACT_MOUSE_VISIBILITY:
2190                         row = uiLayoutRow(layout, 0);
2191                         uiItemR(row, ptr, "visible", UI_ITEM_R_TOGGLE, NULL, 0);
2192                         break;
2193
2194                 case ACT_MOUSE_LOOK:
2195                         /* X axis */
2196                         row = uiLayoutRow(layout, 0);
2197                         col = uiLayoutColumn(row, 1);
2198
2199                         uiItemR(col, ptr, "use_axis_x", UI_ITEM_R_TOGGLE, NULL, 0);
2200
2201                         subcol = uiLayoutColumn(col, 1);
2202                         uiLayoutSetActive(subcol, RNA_boolean_get(ptr, "use_axis_x")==1);
2203                         uiItemR(subcol, ptr, "sensitivity_x", 0, NULL, 0);
2204                         uiItemR(subcol, ptr, "threshold_x", 0, NULL, 0);
2205
2206                         uiItemR(subcol, ptr, "min_x", 0, NULL, 0);
2207                         uiItemR(subcol, ptr, "max_x", 0, NULL, 0);
2208
2209                         uiItemR(subcol, ptr, "object_axis_x", 0, NULL, 0);
2210
2211                         /* Y Axis */
2212                         col = uiLayoutColumn(row, 1);
2213
2214                         uiItemR(col, ptr, "use_axis_y", UI_ITEM_R_TOGGLE, NULL, 0);
2215
2216                         subcol = uiLayoutColumn(col, 1);
2217                         uiLayoutSetActive(subcol, RNA_boolean_get(ptr, "use_axis_y")==1);
2218                         uiItemR(subcol, ptr, "sensitivity_y", 0, NULL, 0);
2219                         uiItemR(subcol, ptr, "threshold_y", 0, NULL, 0);
2220
2221                         uiItemR(subcol, ptr, "min_y", 0, NULL, 0);
2222                         uiItemR(subcol, ptr, "max_y", 0, NULL, 0);
2223
2224                         uiItemR(subcol, ptr, "object_axis_y", 0, NULL, 0);
2225
2226                         /* Lower options */
2227                         row = uiLayoutRow(layout, 0);
2228                         split = uiLayoutSplit(row, 0.5, 0);
2229
2230                         subsplit = uiLayoutSplit(split, 0.5, 1);
2231                         uiLayoutSetActive(subsplit, RNA_boolean_get(ptr, "use_axis_x")==1);
2232                         uiItemR(subsplit, ptr, "local_x", UI_ITEM_R_TOGGLE, NULL, 0);
2233                         uiItemR(subsplit, ptr, "reset_x", UI_ITEM_R_TOGGLE, NULL, 0);
2234
2235                         subsplit = uiLayoutSplit(split, 0.5, 1);
2236                         uiLayoutSetActive(subsplit, RNA_boolean_get(ptr, "use_axis_y")==1);
2237                         uiItemR(subsplit, ptr, "local_y", UI_ITEM_R_TOGGLE, NULL, 0);
2238                         uiItemR(subsplit, ptr, "reset_y", UI_ITEM_R_TOGGLE, NULL, 0);
2239
2240                         break;
2241         }
2242 }
2243
2244 static void draw_brick_actuator(uiLayout *layout, PointerRNA *ptr, bContext *C)
2245 {
2246         uiLayout *box;
2247         
2248         if (!RNA_boolean_get(ptr, "show_expanded"))
2249                 return;
2250         
2251         box = uiLayoutBox(layout);
2252         uiLayoutSetActive(box, RNA_boolean_get(ptr, "active"));
2253         
2254         switch (RNA_enum_get(ptr, "type")) {
2255                 case ACT_ACTION:
2256                         draw_actuator_action(box, ptr);
2257                         break;
2258                 case ACT_ARMATURE:
2259                         draw_actuator_armature(box, ptr);
2260                         break;
2261                 case ACT_CAMERA:
2262                         draw_actuator_camera(box, ptr);
2263                         break;
2264                 case ACT_CONSTRAINT:
2265                         draw_actuator_constraint(box, ptr, C);
2266                         break;
2267                 case ACT_EDIT_OBJECT:
2268                         draw_actuator_edit_object(box, ptr);
2269                         break;
2270                 case ACT_2DFILTER:
2271                         draw_actuator_filter_2d(box, ptr);
2272                         break;
2273                 case ACT_GAME:
2274                         draw_actuator_game(box, ptr);
2275                         break;
2276                 case ACT_MESSAGE:
2277                         draw_actuator_message(box, ptr, C);
2278                         break;
2279                 case ACT_OBJECT:
2280                         draw_actuator_motion(box, ptr);
2281                         break;
2282                 case ACT_PARENT:
2283                         draw_actuator_parent(box, ptr);
2284                         break;
2285                 case ACT_PROPERTY:
2286                         draw_actuator_property(box, ptr);
2287                         break;
2288                 case ACT_RANDOM:
2289                         draw_actuator_random(box, ptr);
2290                         break;
2291                 case ACT_SCENE:
2292                         draw_actuator_scene(box, ptr);
2293                         break;
2294                 case ACT_SHAPEACTION:
2295                         draw_actuator_shape_action(box, ptr);
2296                         break;
2297                 case ACT_SOUND:
2298                         draw_actuator_sound(box, ptr, C);
2299                         break;
2300                 case ACT_STATE:
2301                         draw_actuator_state(box, ptr);
2302                         break;
2303                 case ACT_VISIBILITY:
2304                         draw_actuator_visibility(box, ptr);
2305                         break;
2306                 case ACT_STEERING:
2307                         draw_actuator_steering(box, ptr);
2308                         break;
2309                 case ACT_MOUSE:
2310                         draw_actuator_mouse(box, ptr);
2311                         break;
2312         }
2313 }
2314
2315 void logic_buttons(bContext *C, ARegion *ar)
2316 {
2317         SpaceLogic *slogic= CTX_wm_space_logic(C);
2318         Object *ob= CTX_data_active_object(C);
2319         ID **idar;
2320         PointerRNA logic_ptr, settings_ptr, object_ptr;
2321         uiLayout *layout, *row, *box;
2322         uiBlock *block;
2323         uiBut *but;
2324         char uiblockstr[32];
2325         short a, count;
2326         int xco, yco, width, height;
2327         
2328         if (ob==NULL) return;
2329         
2330         RNA_pointer_create(NULL, &RNA_SpaceLogicEditor, slogic, &logic_ptr);
2331         idar= get_selected_and_linked_obs(C, &count, slogic->scaflag);
2332         
2333         BLI_snprintf(uiblockstr, sizeof(uiblockstr), "buttonswin %p", (void *)ar);
2334         block= uiBeginBlock(C, ar, uiblockstr, UI_EMBOSS);
2335         uiBlockSetHandleFunc(block, do_logic_buts, NULL);
2336         uiBoundsBlock(block, U.widget_unit/2);
2337         
2338         /* loop over all objects and set visible/linked flags for the logic bricks */
2339         for (a=0; a<count; a++) {
2340                 bActuator *act;
2341                 bSensor *sens;
2342                 bController *cont;
2343                 int iact;
2344                 short flag;
2345
2346                 ob= (Object *)idar[a];
2347                 
2348                 /* clean ACT_LINKED and ACT_VISIBLE of all potentially visible actuators so that we can determine which is actually linked/visible */
2349                 act = ob->actuators.first;
2350                 while (act) {
2351                         act->flag &= ~(ACT_LINKED|ACT_VISIBLE);
2352                         act = act->next;
2353                 }
2354                 /* same for sensors */
2355                 sens= ob->sensors.first;
2356                 while (sens) {
2357                         sens->flag &= ~(SENS_VISIBLE);
2358                         sens = sens->next;
2359                 }
2360
2361                 /* mark the linked and visible actuators */
2362                 cont= ob->controllers.first;
2363                 while (cont) {
2364                         flag = ACT_LINKED;
2365
2366                         /* this controller is visible, mark all its actuator */
2367                         if ((ob->scaflag & OB_ALLSTATE) || (ob->state & cont->state_mask))
2368                                 flag |= ACT_VISIBLE;
2369
2370                         for (iact=0; iact<cont->totlinks; iact++) {
2371                                 act = cont->links[iact];
2372                                 if (act)
2373                                         act->flag |= flag;
2374                         }
2375                         cont = cont->next;
2376                 }
2377         }
2378         
2379         /* ****************** Controllers ****************** */
2380         
2381         xco= 21 * U.widget_unit; yco= - U.widget_unit / 2; width= 15 * U.widget_unit;
2382         layout= uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, xco, yco, width, 20, 0, UI_GetStyle());
2383         row = uiLayoutRow(layout, true);
2384         
2385         uiDefBlockBut(block, controller_menu, NULL, IFACE_("Controllers"), xco - U.widget_unit / 2, yco, width, UI_UNIT_Y, "");         /* replace this with uiLayout stuff later */
2386         
2387         uiItemR(row, &logic_ptr, "show_controllers_selected_objects", 0, IFACE_("Sel"), ICON_NONE);
2388         uiItemR(row, &logic_ptr, "show_controllers_active_object", 0, IFACE_("Act"), ICON_NONE);
2389         uiItemR(row, &logic_ptr, "show_controllers_linked_controller", 0, IFACE_("Link"), ICON_NONE);
2390
2391         for (a=0; a<count; a++) {
2392                 bController *cont;
2393                 PointerRNA ptr;
2394                 uiLayout *split, *subsplit, *col;
2395
2396                 
2397                 ob= (Object *)idar[a];
2398
2399                 /* only draw the controller common header if "use_visible" */
2400                 if ( (ob->scavisflag & OB_VIS_CONT) == 0) {
2401                         continue;
2402                 }
2403         
2404                 /* Drawing the Controller Header common to all Selected Objects */
2405
2406                 RNA_pointer_create((ID *)ob, &RNA_GameObjectSettings, ob, &settings_ptr);
2407
2408                 split = uiLayoutSplit(layout, 0.05f, false);
2409                 uiItemR(split, &settings_ptr, "show_state_panel", UI_ITEM_R_NO_BG, "", ICON_DISCLOSURE_TRI_RIGHT);
2410
2411                 row = uiLayoutRow(split, true);
2412                 uiDefButBitS(block, TOG, OB_SHOWCONT, B_REDR, ob->id.name + 2, (short)(xco - U.widget_unit / 2), yco, (short)(width - 1.5f * U.widget_unit), UI_UNIT_Y, &ob->scaflag, 0, 31, 0, 0, TIP_("Object name, click to show/hide controllers"));
2413
2414                 RNA_pointer_create((ID *)ob, &RNA_Object, ob, &object_ptr);
2415                 uiLayoutSetContextPointer(row, "object", &object_ptr);
2416                 uiItemMenuEnumO(row, C, "LOGIC_OT_controller_add", "type", IFACE_("Add Controller"), ICON_NONE);
2417
2418                 if (RNA_boolean_get(&settings_ptr, "show_state_panel")) {
2419
2420                         box = uiLayoutBox(layout);
2421                         split = uiLayoutSplit(box, 0.2f, false);
2422
2423                         col = uiLayoutColumn(split, false);
2424                         uiItemL(col, IFACE_("Visible"), ICON_NONE);
2425                         uiItemL(col, IFACE_("Initial"), ICON_NONE);
2426
2427                         subsplit = uiLayoutSplit(split, 0.85f, false);
2428                         col = uiLayoutColumn(subsplit, false);
2429                         row = uiLayoutRow(col, false);
2430                         uiLayoutSetActive(row, RNA_boolean_get(&settings_ptr, "use_all_states") == false);
2431                         uiTemplateGameStates(row, &settings_ptr, "states_visible", &settings_ptr, "used_states", 0);
2432                         row = uiLayoutRow(col, false);
2433                         uiTemplateGameStates(row, &settings_ptr, "states_initial", &settings_ptr, "used_states", 0);
2434
2435                         col = uiLayoutColumn(subsplit, false);
2436                         uiItemR(col, &settings_ptr, "use_all_states", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
2437                         uiItemR(col, &settings_ptr, "show_debug_state", 0, "", ICON_NONE);
2438                 }
2439
2440                 /* End of Drawing the Controller Header common to all Selected Objects */
2441
2442                 if ((ob->scaflag & OB_SHOWCONT) == 0) continue;
2443                 
2444
2445                 uiItemS(layout);
2446                 
2447                 for (cont= ob->controllers.first; cont; cont=cont->next) {
2448                         RNA_pointer_create((ID *)ob, &RNA_Controller, cont, &ptr);
2449                         
2450                         if (!(ob->scaflag & OB_ALLSTATE) && !(ob->state & cont->state_mask))
2451                                 continue;
2452                         
2453                         /* use two nested splits to align inlinks/links properly */
2454                         split = uiLayoutSplit(layout, 0.05f, false);
2455                         
2456                         /* put inlink button to the left */
2457                         col = uiLayoutColumn(split, false);
2458                         uiLayoutSetActive(col, RNA_boolean_get(&ptr, "active"));
2459                         uiLayoutSetAlignment(col, UI_LAYOUT_ALIGN_LEFT);
2460                         but = uiDefIconBut(block, INLINK, 0, ICON_INLINK, 0, 0, UI_UNIT_X, UI_UNIT_Y, cont, LINK_CONTROLLER, 0, 0, 0, "");
2461                         if (!RNA_boolean_get(&ptr, "active")) {
2462                                 uiButSetFlag(but, UI_BUT_SCA_LINK_GREY);
2463                         }
2464                         
2465                         //col = uiLayoutColumn(split, true);
2466                         /* nested split for middle and right columns */
2467                         subsplit = uiLayoutSplit(split, 0.95f, false);
2468                         
2469                         col = uiLayoutColumn(subsplit, true);
2470                         uiLayoutSetContextPointer(col, "controller", &ptr);
2471                         
2472                         /* should make UI template for controller header.. function will do for now */
2473 //                      draw_controller_header(col, &ptr);
2474                         draw_controller_header(col, &ptr, xco, width, yco); //provisory for 2.50 beta
2475
2476                         /* draw the brick contents */
2477                         draw_brick_controller(col, &ptr);
2478                         
2479                         /* put link button to the right */
2480                         col = uiLayoutColumn(subsplit, false);
2481                         uiLayoutSetActive(col, RNA_boolean_get(&ptr, "active"));
2482                         uiLayoutSetAlignment(col, UI_LAYOUT_ALIGN_LEFT);
2483                         but = uiDefIconBut(block, LINK, 0, ICON_LINK, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, "");
2484                         if (!RNA_boolean_get(&ptr, "active")) {
2485                                 uiButSetFlag(but, UI_BUT_SCA_LINK_GREY);
2486                         }
2487
2488                         uiSetButLink(but, NULL, (void ***)&(cont->links), &cont->totlinks, LINK_CONTROLLER, LINK_ACTUATOR);
2489
2490                 }
2491         }
2492         uiBlockLayoutResolve(block, NULL, &yco);        /* stores final height in yco */
2493         height = yco;
2494         
2495         /* ****************** Sensors ****************** */
2496         
2497         xco= U.widget_unit / 2; yco= -U.widget_unit / 2; width= 17 * U.widget_unit;
2498         layout= uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, xco, yco, width, 20, 0, UI_GetStyle());
2499         row = uiLayoutRow(layout, true);
2500         
2501         uiDefBlockBut(block, sensor_menu, NULL, IFACE_("Sensors"), xco - U.widget_unit / 2, yco, 15 * U.widget_unit, UI_UNIT_Y, "");            /* replace this with uiLayout stuff later */
2502         
2503         uiItemR(row, &logic_ptr, "show_sensors_selected_objects", 0, IFACE_("Sel"), ICON_NONE);
2504         uiItemR(row, &logic_ptr, "show_sensors_active_object", 0, IFACE_("Act"), ICON_NONE);
2505         uiItemR(row, &logic_ptr, "show_sensors_linked_controller", 0, IFACE_("Link"), ICON_NONE);
2506         uiItemR(row, &logic_ptr, "show_sensors_active_states", 0, IFACE_("State"), ICON_NONE);
2507         
2508         for (a=0; a<count; a++) {
2509                 bSensor *sens;
2510                 PointerRNA ptr;
2511                 
2512                 ob= (Object *)idar[a];
2513
2514                 /* only draw the sensor common header if "use_visible" */
2515                 if ((ob->scavisflag & OB_VIS_SENS) == 0) continue;
2516
2517                 row = uiLayoutRow(layout, true);
2518                 uiDefButBitS(block, TOG, OB_SHOWSENS, B_REDR, ob->id.name + 2, (short)(xco - U.widget_unit / 2), yco, (short)(width - 1.5f * U.widget_unit), UI_UNIT_Y, &ob->scaflag, 0, 31, 0, 0, TIP_("Object name, click to show/hide sensors"));
2519
2520                 RNA_pointer_create((ID *)ob, &RNA_Object, ob, &object_ptr);
2521                 uiLayoutSetContextPointer(row, "object", &object_ptr);
2522                 uiItemMenuEnumO(row, C, "LOGIC_OT_sensor_add", "type", IFACE_("Add Sensor"), ICON_NONE);
2523                 
2524                 if ((ob->scaflag & OB_SHOWSENS) == 0) continue;
2525                 
2526                 uiItemS(layout);
2527                 
2528                 for (sens= ob->sensors.first; sens; sens=sens->next) {
2529                         RNA_pointer_create((ID *)ob, &RNA_Sensor, sens, &ptr);
2530                         
2531                         if ((ob->scaflag & OB_ALLSTATE) ||
2532                                 !(slogic->scaflag & BUTS_SENS_STATE) ||
2533                                 (sens->totlinks == 0) ||                                                                                        /* always display sensor without links so that is can be edited */
2534                                 (sens->flag & SENS_PIN && slogic->scaflag & BUTS_SENS_STATE) || /* states can hide some sensors, pinned sensors ignore the visible state */
2535                                 (is_sensor_linked(block, sens))
2536                                 )
2537                         {       // gotta check if the current state is visible or not
2538                                 uiLayout *split, *col;
2539
2540                                 /* make as visible, for move operator */
2541                                 sens->flag |= SENS_VISIBLE;
2542
2543                                 split = uiLayoutSplit(layout, 0.95f, false);
2544                                 col = uiLayoutColumn(split, true);
2545                                 uiLayoutSetContextPointer(col, "sensor", &ptr);
2546                                 
2547                                 /* should make UI template for sensor header.. function will do for now */
2548                                 draw_sensor_header(col, &ptr, &logic_ptr);
2549                                 
2550                                 /* draw the brick contents */
2551                                 draw_brick_sensor(col, &ptr, C);
2552                                 
2553                                 /* put link button to the right */
2554                                 col = uiLayoutColumn(split, false);
2555                                 uiLayoutSetActive(col, RNA_boolean_get(&ptr, "active"));
2556                                 but = uiDefIconBut(block, LINK, 0, ICON_LINK, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, "");
2557                                 if (!RNA_boolean_get(&ptr, "active")) {
2558                                         uiButSetFlag(but, UI_BUT_SCA_LINK_GREY);
2559                                 }
2560
2561                                 /* use old-school uiButtons for links for now */
2562                                 uiSetButLink(but, NULL, (void ***)&sens->links, &sens->totlinks, LINK_SENSOR, LINK_CONTROLLER);
2563                         }
2564                 }
2565         }
2566         uiBlockLayoutResolve(block, NULL, &yco);        /* stores final height in yco */
2567         height = MIN2(height, yco);
2568         
2569         /* ****************** Actuators ****************** */
2570         
2571         xco= 40 * U.widget_unit; yco= -U.widget_unit / 2; width= 17 * U.widget_unit;
2572         layout= uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, xco, yco, width, 20, 0, UI_GetStyle());
2573         row = uiLayoutRow(layout, true);
2574         
2575         uiDefBlockBut(block, actuator_menu, NULL, IFACE_("Actuators"), xco - U.widget_unit / 2, yco, 15 * U.widget_unit, UI_UNIT_Y, "");                /* replace this with uiLayout stuff later */
2576         
2577         uiItemR(row, &logic_ptr, "show_actuators_selected_objects", 0, IFACE_("Sel"), ICON_NONE);
2578         uiItemR(row, &logic_ptr, "show_actuators_active_object", 0, IFACE_("Act"), ICON_NONE);
2579         uiItemR(row, &logic_ptr, "show_actuators_linked_controller", 0, IFACE_("Link"), ICON_NONE);
2580         uiItemR(row, &logic_ptr, "show_actuators_active_states", 0, IFACE_("State"), ICON_NONE);
2581         
2582         for (a=0; a<count; a++) {
2583                 bActuator *act;
2584                 PointerRNA ptr;
2585                 
2586                 ob= (Object *)idar[a];
2587
2588                 /* only draw the actuator common header if "use_visible" */
2589                 if ((ob->scavisflag & OB_VIS_ACT) == 0) {
2590                         continue;
2591                 }
2592
2593                 row = uiLayoutRow(layout, true);
2594                 uiDefButBitS(block, TOG, OB_SHOWACT, B_REDR, ob->id.name + 2, (short)(xco - U.widget_unit / 2), yco, (short)(width - 1.5f * U.widget_unit), UI_UNIT_Y, &ob->scaflag, 0, 31, 0, 0, TIP_("Object name, click to show/hide actuators"));
2595
2596                 RNA_pointer_create((ID *)ob, &RNA_Object, ob, &object_ptr);
2597                 uiLayoutSetContextPointer(row, "object", &object_ptr);
2598                 uiItemMenuEnumO(row, C, "LOGIC_OT_actuator_add", "type", IFACE_("Add Actuator"), ICON_NONE);
2599
2600                 if ((ob->scaflag & OB_SHOWACT) == 0) continue;
2601                 
2602                 uiItemS(layout);
2603                 
2604                 for (act= ob->actuators.first; act; act=act->next) {
2605                         
2606                         RNA_pointer_create((ID *)ob, &RNA_Actuator, act, &ptr);
2607                         
2608                         if ((ob->scaflag & OB_ALLSTATE) ||
2609                                 !(slogic->scaflag & BUTS_ACT_STATE) ||
2610                                 !(act->flag & ACT_LINKED) ||            /* always display actuators without links so that is can be edited */
2611                                 (act->flag & ACT_VISIBLE) ||            /* this actuator has visible connection, display it */
2612                                 (act->flag & ACT_PIN && slogic->scaflag & BUTS_ACT_STATE)       /* states can hide some sensors, pinned sensors ignore the visible state */
2613                                 )
2614                         {       // gotta check if the current state is visible or not
2615                                 uiLayout *split, *col;
2616                                 
2617                                 /* make as visible, for move operator */
2618                                 act->flag |= ACT_VISIBLE;
2619
2620                                 split = uiLayoutSplit(layout, 0.05f, false);
2621                                 
2622                                 /* put inlink button to the left */
2623                                 col = uiLayoutColumn(split, false);
2624                                 uiLayoutSetActive(col, RNA_boolean_get(&ptr, "active"));
2625                                 but = uiDefIconBut(block, INLINK, 0, ICON_INLINK, 0, 0, UI_UNIT_X, UI_UNIT_Y, act, LINK_ACTUATOR, 0, 0, 0, "");
2626                                 if (!RNA_boolean_get(&ptr, "active")) {
2627                                         uiButSetFlag(but, UI_BUT_SCA_LINK_GREY);
2628                                 }
2629
2630                                 col = uiLayoutColumn(split, true);
2631                                 uiLayoutSetContextPointer(col, "actuator", &ptr);
2632                                 
2633                                 /* should make UI template for actuator header.. function will do for now */
2634                                 draw_actuator_header(col, &ptr, &logic_ptr);
2635                                 
2636                                 /* draw the brick contents */
2637                                 draw_brick_actuator(col, &ptr, C);
2638                                 
2639                         }
2640                 }
2641         }
2642         uiBlockLayoutResolve(block, NULL, &yco);        /* stores final height in yco */
2643         height = MIN2(height, yco);
2644
2645         UI_view2d_totRect_set(&ar->v2d, 57.5f * U.widget_unit, height - U.widget_unit);
2646         
2647         /* set the view */
2648         UI_view2d_view_ortho(&ar->v2d);
2649
2650         uiComposeLinks(block);
2651         
2652         uiEndBlock(C, block);
2653         uiDrawBlock(C, block);
2654         
2655         /* restore view matrix */
2656         UI_view2d_view_restore(C);
2657         
2658         if (idar) MEM_freeN(idar);
2659 }
2660