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