Blender  V2.59
logic_window.c
Go to the documentation of this file.
00001 /*
00002  * $Id: logic_window.c 37455 2011-06-13 17:08:33Z dfelinto $
00003  *
00004  * ***** BEGIN GPL LICENSE BLOCK *****
00005  *
00006  * This program is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU General Public License
00008  * as published by the Free Software Foundation; either version 2
00009  * of the License, or (at your option) any later version. 
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software Foundation,
00018  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00019  *
00020  * The Original Code is Copyright (C) 2009 Blender Foundation.
00021  * All rights reserved.
00022  *
00023  * 
00024  * Contributor(s): Blender Foundation
00025  *
00026  * ***** END GPL LICENSE BLOCK *****
00027  */
00028 
00034 #include <string.h>
00035 #include <stdio.h>
00036 #include <stddef.h>
00037 #include <float.h>
00038 
00039 #include "DNA_actuator_types.h"
00040 #include "DNA_controller_types.h"
00041 #include "DNA_property_types.h"
00042 #include "DNA_space_types.h"
00043 #include "DNA_scene_types.h"
00044 #include "DNA_screen_types.h"
00045 #include "DNA_sensor_types.h"
00046 #include "DNA_constraint_types.h"
00047 #include "DNA_windowmanager_types.h"
00048 #include "DNA_object_types.h"
00049 
00050 #include "MEM_guardedalloc.h"
00051 
00052 #include "BLI_blenlib.h"
00053 #include "BLI_utildefines.h"
00054 
00055 #include "BKE_action.h"
00056 #include "BKE_context.h"
00057 #include "BKE_global.h"
00058 #include "BKE_library.h"
00059 #include "BKE_main.h"
00060 #include "BKE_sca.h"
00061 
00062 #include "ED_util.h"
00063 
00064 #include "WM_types.h"
00065 
00066 #include "BIF_gl.h"
00067 
00068 #include "UI_interface.h"
00069 
00070 #include "RNA_access.h"
00071 
00072 /* XXX BAD BAD */
00073 #include "../interface/interface_intern.h"
00074 
00075 #include "logic_intern.h"
00076 
00077 
00078 #define MAX_RENDER_PASS   100
00079 #define B_REDR          1
00080 #define B_IDNAME        2
00081 
00082 #define B_ADD_SENS              2703
00083 #define B_CHANGE_SENS           2704
00084 #define B_DEL_SENS              2705
00085 
00086 #define B_ADD_CONT              2706
00087 #define B_CHANGE_CONT           2707
00088 #define B_DEL_CONT              2708
00089 
00090 #define B_ADD_ACT               2709
00091 #define B_CHANGE_ACT            2710
00092 #define B_DEL_ACT               2711
00093 
00094 #define B_SOUNDACT_BROWSE       2712
00095 
00096 #define B_SETSECTOR             2713
00097 #define B_SETPROP               2714
00098 #define B_SETACTOR              2715
00099 #define B_SETMAINACTOR          2716
00100 #define B_SETDYNA               2717
00101 #define B_SET_STATE_BIT 2718
00102 #define B_INIT_STATE_BIT        2719
00103 
00104 /* proto */
00105 static ID **get_selected_and_linked_obs(bContext *C, short *count, short scavisflag);
00106 
00107 static int vergname(const void *v1, const void *v2)
00108 {
00109         char **x1, **x2;
00110         
00111         x1= (char **)v1;
00112         x2= (char **)v2;
00113         
00114         return strcmp(*x1, *x2);
00115 }
00116 
00117 void make_unique_prop_names(bContext *C, char *str)
00118 {
00119         Object *ob;
00120         bProperty *prop;
00121         bSensor *sens;
00122         bController *cont;
00123         bActuator *act;
00124         ID **idar;
00125         short a, obcount, propcount=0, nr;
00126         char **names;
00127         
00128         /* this function is called by a Button, and gives the current
00129                 * stringpointer as an argument, this is the one that can change
00130                 */
00131         
00132         idar= get_selected_and_linked_obs(C, &obcount, BUTS_SENS_SEL|BUTS_SENS_ACT|BUTS_ACT_SEL|BUTS_ACT_ACT|BUTS_CONT_SEL|BUTS_CONT_ACT);
00133         
00134         /* for each object, make properties and sca names unique */
00135         
00136         /* count total names */
00137         for(a=0; a<obcount; a++) {
00138                 ob= (Object *)idar[a];
00139                 propcount+= BLI_countlist(&ob->prop);
00140                 propcount+= BLI_countlist(&ob->sensors);
00141                 propcount+= BLI_countlist(&ob->controllers);
00142                 propcount+= BLI_countlist(&ob->actuators);
00143         }       
00144         if(propcount==0) {
00145                 if(idar) MEM_freeN(idar);
00146                 return;
00147         }
00148         
00149         /* make names array for sorting */
00150         names= MEM_callocN(propcount*sizeof(void *), "names");
00151         
00152         /* count total names */
00153         nr= 0;
00154         for(a=0; a<obcount; a++) {
00155                 ob= (Object *)idar[a];
00156                 prop= ob->prop.first;
00157                 while(prop) {
00158                         names[nr++]= prop->name;
00159                         prop= prop->next;
00160                 }
00161                 sens= ob->sensors.first;
00162                 while(sens) {
00163                         names[nr++]= sens->name;
00164                         sens= sens->next;
00165                 }
00166                 cont= ob->controllers.first;
00167                 while(cont) {
00168                         names[nr++]= cont->name;
00169                         cont= cont->next;
00170                 }
00171                 act= ob->actuators.first;
00172                 while(act) {
00173                         names[nr++]= act->name;
00174                         act= act->next;
00175                 }
00176         }
00177         
00178         qsort(names, propcount, sizeof(void *), vergname);
00179         
00180         /* now we check for double names, and change them */
00181         
00182         for(nr=0; nr<propcount; nr++) {
00183                 if(names[nr]!=str && strcmp( names[nr], str )==0 ) {
00184                         BLI_newname(str, +1);
00185                 }
00186         }
00187         
00188         MEM_freeN(idar);
00189         MEM_freeN(names);
00190 }
00191 
00192 static void make_unique_prop_names_cb(bContext *C, void *strv, void *UNUSED(redraw_view3d_flagv))
00193 {
00194         char *str= strv;
00195 //      int redraw_view3d_flag= GET_INT_FROM_POINTER(redraw_view3d_flagv);
00196         
00197         make_unique_prop_names(C, str);
00198 }
00199 
00200 
00201 static void old_sca_move_sensor(bContext *C, void *datav, void *move_up)
00202 {
00203         /* deprecated, no longer using it (moved to sca.c) */
00204         Scene *scene= CTX_data_scene(C);
00205         bSensor *sens_to_delete= datav;
00206         int val;
00207         Base *base;
00208         bSensor *sens, *tmp;
00209         
00210         // val= pupmenu("Move up%x1|Move down %x2");
00211         val = move_up ? 1:2;
00212         
00213         if(val>0) {
00214                 /* now find out which object has this ... */
00215                 base= FIRSTBASE;
00216                 while(base) {
00217                 
00218                         sens= base->object->sensors.first;
00219                         while(sens) {
00220                                 if(sens == sens_to_delete) break;
00221                                 sens= sens->next;
00222                         }
00223                         
00224                         if(sens) {
00225                                 if( val==1 && sens->prev) {
00226                                         for (tmp=sens->prev; tmp; tmp=tmp->prev) {
00227                                                 if (tmp->flag & SENS_VISIBLE)
00228                                                         break;
00229                                         }
00230                                         if (tmp) {
00231                                                 BLI_remlink(&base->object->sensors, sens);
00232                                                 BLI_insertlinkbefore(&base->object->sensors, tmp, sens);
00233                                         }
00234                                 }
00235                                 else if( val==2 && sens->next) {
00236                                         for (tmp=sens->next; tmp; tmp=tmp->next) {
00237                                                 if (tmp->flag & SENS_VISIBLE)
00238                                                         break;
00239                                         }
00240                                         if (tmp) {
00241                                                 BLI_remlink(&base->object->sensors, sens);
00242                                                 BLI_insertlink(&base->object->sensors, tmp, sens);
00243                                         }
00244                                 }
00245                                 ED_undo_push(C, "Move sensor");
00246                                 break;
00247                         }
00248                         
00249                         base= base->next;
00250                 }
00251         }
00252 }
00253 
00254 static void old_sca_move_controller(bContext *C, void *datav, void *move_up)
00255 {
00256         /* deprecated, no longer using it (moved to sca.c) */
00257         Scene *scene= CTX_data_scene(C);
00258         bController *controller_to_del= datav;
00259         int val;
00260         Base *base;
00261         bController *cont, *tmp;
00262         
00263         //val= pupmenu("Move up%x1|Move down %x2");
00264         val = move_up ? 1:2;
00265         
00266         if(val>0) {
00267                 /* now find out which object has this ... */
00268                 base= FIRSTBASE;
00269                 while(base) {
00270                 
00271                         cont= base->object->controllers.first;
00272                         while(cont) {
00273                                 if(cont == controller_to_del) break;
00274                                 cont= cont->next;
00275                         }
00276                         
00277                         if(cont) {
00278                                 if( val==1 && cont->prev) {
00279                                         /* locate the controller that has the same state mask but is earlier in the list */
00280                                         tmp = cont->prev;
00281                                         while(tmp) {
00282                                                 if(tmp->state_mask & cont->state_mask) 
00283                                                         break;
00284                                                 tmp = tmp->prev;
00285                                         }
00286                                         if (tmp) {
00287                                                 BLI_remlink(&base->object->controllers, cont);
00288                                                 BLI_insertlinkbefore(&base->object->controllers, tmp, cont);
00289                                         }
00290                                 }
00291                                 else if( val==2 && cont->next) {
00292                                         tmp = cont->next;
00293                                         while(tmp) {
00294                                                 if(tmp->state_mask & cont->state_mask) 
00295                                                         break;
00296                                                 tmp = tmp->next;
00297                                         }
00298                                         BLI_remlink(&base->object->controllers, cont);
00299                                         BLI_insertlink(&base->object->controllers, tmp, cont);
00300                                 }
00301                                 ED_undo_push(C, "Move controller");
00302                                 break;
00303                         }
00304                         
00305                         base= base->next;
00306                 }
00307         }
00308 }
00309 
00310 static void old_sca_move_actuator(bContext *C, void *datav, void *move_up)
00311 {
00312         /* deprecated, no longer using it (moved to sca.c) */
00313         Scene *scene= CTX_data_scene(C);
00314         bActuator *actuator_to_move= datav;
00315         int val;
00316         Base *base;
00317         bActuator *act, *tmp;
00318         
00319         //val= pupmenu("Move up%x1|Move down %x2");
00320         val = move_up ? 1:2;
00321         
00322         if(val>0) {
00323                 /* now find out which object has this ... */
00324                 base= FIRSTBASE;
00325                 while(base) {
00326                 
00327                         act= base->object->actuators.first;
00328                         while(act) {
00329                                 if(act == actuator_to_move) break;
00330                                 act= act->next;
00331                         }
00332                         
00333                         if(act) {
00334                                 if( val==1 && act->prev) {
00335                                         /* locate the first visible actuators before this one */
00336                                         for (tmp = act->prev; tmp; tmp=tmp->prev) {
00337                                                 if (tmp->flag & ACT_VISIBLE)
00338                                                         break;
00339                                         }
00340                                         if (tmp) {
00341                                                 BLI_remlink(&base->object->actuators, act);
00342                                                 BLI_insertlinkbefore(&base->object->actuators, tmp, act);
00343                                         }
00344                                 }
00345                                 else if( val==2 && act->next) {
00346                                         for (tmp=act->next; tmp; tmp=tmp->next) {
00347                                                 if (tmp->flag & ACT_VISIBLE)
00348                                                         break;
00349                                         }
00350                                         if (tmp) {
00351                                                 BLI_remlink(&base->object->actuators, act);
00352                                                 BLI_insertlink(&base->object->actuators, tmp, act);
00353                                         }
00354                                 }
00355                                 ED_undo_push(C, "Move actuator");
00356                                 break;
00357                         }
00358                         
00359                         base= base->next;
00360                 }
00361         }
00362 }
00363 
00364 static void do_logic_buts(bContext *C, void *UNUSED(arg), int event)
00365 {
00366         Main *bmain= CTX_data_main(C);
00367         bSensor *sens;
00368         bController *cont;
00369         bActuator *act;
00370         Object *ob;
00371         int didit, bit;
00372         
00373         ob= CTX_data_active_object(C);
00374         if(ob==NULL) return;
00375         
00376         switch(event) {
00377 
00378         case B_SETPROP:
00379                 /* check for inconsistent types */
00380                 ob->gameflag &= ~(OB_SECTOR|OB_MAINACTOR|OB_DYNAMIC|OB_ACTOR);
00381                 break;
00382 
00383         case B_SETACTOR:
00384         case B_SETDYNA:
00385         case B_SETMAINACTOR:
00386                 ob->gameflag &= ~(OB_SECTOR|OB_PROP);
00387                 break;
00388         
00389         case B_ADD_SENS:
00390                 for(ob=bmain->object.first; ob; ob=ob->id.next) {
00391                         if(ob->scaflag & OB_ADDSENS) {
00392                                 ob->scaflag &= ~OB_ADDSENS;
00393                                 sens= new_sensor(SENS_ALWAYS);
00394                                 BLI_addtail(&(ob->sensors), sens);
00395                                 make_unique_prop_names(C, sens->name);
00396                                 ob->scaflag |= OB_SHOWSENS;
00397                         }
00398                 }
00399                 
00400                 ED_undo_push(C, "Add sensor");
00401                 break;
00402 
00403         case B_CHANGE_SENS:
00404                 for(ob=bmain->object.first; ob; ob=ob->id.next) {
00405                         sens= ob->sensors.first;
00406                         while(sens) {
00407                                 if(sens->type != sens->otype) {
00408                                         init_sensor(sens);
00409                                         sens->otype= sens->type;
00410                                         break;
00411                                 }
00412                                 sens= sens->next;
00413                         }
00414                 }
00415                 break;
00416         
00417         case B_DEL_SENS:
00418                 for(ob=bmain->object.first; ob; ob=ob->id.next) {
00419                         sens= ob->sensors.first;
00420                         while(sens) {
00421                                 if(sens->flag & SENS_DEL) {
00422                                         BLI_remlink(&(ob->sensors), sens);
00423                                         free_sensor(sens);
00424                                         break;
00425                                 }
00426                                 sens= sens->next;
00427                         }
00428                 }
00429                 ED_undo_push(C, "Delete sensor");
00430                 break;
00431         
00432         case B_ADD_CONT:
00433                 for(ob=bmain->object.first; ob; ob=ob->id.next) {
00434                         if(ob->scaflag & OB_ADDCONT) {
00435                                 ob->scaflag &= ~OB_ADDCONT;
00436                                 cont= new_controller(CONT_LOGIC_AND);
00437                                 make_unique_prop_names(C, cont->name);
00438                                 ob->scaflag |= OB_SHOWCONT;
00439                                 BLI_addtail(&(ob->controllers), cont);
00440                                 /* set the controller state mask from the current object state.
00441                                    A controller is always in a single state, so select the lowest bit set
00442                                    from the object state */
00443                                 for (bit=0; bit<32; bit++) {
00444                                         if (ob->state & (1<<bit))
00445                                                 break;
00446                                 }
00447                                 cont->state_mask = (1<<bit);
00448                                 if (cont->state_mask == 0) {
00449                                         /* shouldn't happen, object state is never 0 */
00450                                         cont->state_mask = 1;
00451                                 }
00452                         }
00453                 }
00454                 ED_undo_push(C, "Add controller");
00455                 break;
00456 
00457         case B_SET_STATE_BIT:
00458                 for(ob=bmain->object.first; ob; ob=ob->id.next) {
00459                         if(ob->scaflag & OB_ALLSTATE) {
00460                                 ob->scaflag &= ~OB_ALLSTATE;
00461                                 ob->state = 0x3FFFFFFF;
00462                         }
00463                 }
00464                 break;
00465 
00466         case B_INIT_STATE_BIT:
00467                 for(ob=bmain->object.first; ob; ob=ob->id.next) {
00468                         if(ob->scaflag & OB_INITSTBIT) {
00469                                 ob->scaflag &= ~OB_INITSTBIT;
00470                                 ob->state = ob->init_state;
00471                                 if (!ob->state)
00472                                         ob->state = 1;
00473                         }
00474                 }
00475                 break;
00476 
00477         case B_CHANGE_CONT:
00478                 for(ob=bmain->object.first; ob; ob=ob->id.next) {
00479                         cont= ob->controllers.first;
00480                         while(cont) {
00481                                 if(cont->type != cont->otype) {
00482                                         init_controller(cont);
00483                                         cont->otype= cont->type;
00484                                         break;
00485                                 }
00486                                 cont= cont->next;
00487                         }
00488                 }
00489                 break;
00490         
00491 
00492         case B_DEL_CONT:
00493                 for(ob=bmain->object.first; ob; ob=ob->id.next) {
00494                         cont= ob->controllers.first;
00495                         while(cont) {
00496                                 if(cont->flag & CONT_DEL) {
00497                                         BLI_remlink(&(ob->controllers), cont);
00498                                         unlink_controller(cont);
00499                                         free_controller(cont);
00500                                         break;
00501                                 }
00502                                 cont= cont->next;
00503                         }
00504                 }
00505                 ED_undo_push(C, "Delete controller");
00506                 break;
00507 
00508         case B_ADD_ACT:
00509                 for(ob=bmain->object.first; ob; ob=ob->id.next) {
00510                         if(ob->scaflag & OB_ADDACT) {
00511                                 ob->scaflag &= ~OB_ADDACT;
00512                                 act= new_actuator(ACT_OBJECT);
00513                                 make_unique_prop_names(C, act->name);
00514                                 BLI_addtail(&(ob->actuators), act);
00515                                 ob->scaflag |= OB_SHOWACT;
00516                         }
00517                 }
00518                 ED_undo_push(C, "Add actuator");
00519                 break;
00520 
00521         case B_CHANGE_ACT:
00522                 for(ob=bmain->object.first; ob; ob=ob->id.next) {
00523                         act= ob->actuators.first;
00524                         while(act) {
00525                                 if(act->type != act->otype) {
00526                                         init_actuator(act);
00527                                         act->otype= act->type;
00528                                         break;
00529                                 }
00530                                 act= act->next;
00531                         }
00532                 }
00533                 break;
00534 
00535         case B_DEL_ACT:
00536                 for(ob=bmain->object.first; ob; ob=ob->id.next) {
00537                         act= ob->actuators.first;
00538                         while(act) {
00539                                 if(act->flag & ACT_DEL) {
00540                                         BLI_remlink(&(ob->actuators), act);
00541                                         unlink_actuator(act);
00542                                         free_actuator(act);
00543                                         break;
00544                                 }
00545                                 act= act->next;
00546                         }
00547                 }
00548                 ED_undo_push(C, "Delete actuator");
00549                 break;
00550         
00551         case B_SOUNDACT_BROWSE:
00552                 /* since we don't know which... */
00553                 didit= 0;
00554                 for(ob=bmain->object.first; ob; ob=ob->id.next) {
00555                         act= ob->actuators.first;
00556                         while(act)
00557                         {
00558                                 if(act->type==ACT_SOUND)
00559                                 {
00560                                         bSoundActuator *sa= act->data;
00561                                         if(sa->sndnr)
00562                                         {
00563                                                 ID *sound= bmain->sound.first;
00564                                                 int nr= 1;
00565 
00566                                                 if(sa->sndnr == -2) {
00567 // XXX                                                  activate_databrowse((ID *)bmain->sound.first, ID_SO, 0, B_SOUNDACT_BROWSE,
00568 //                                                                                      &sa->sndnr, do_logic_buts);
00569                                                         break;
00570                                                 }
00571 
00572                                                 while(sound)
00573                                                 {
00574                                                         if(nr==sa->sndnr)
00575                                                                 break;
00576                                                         nr++;
00577                                                         sound= sound->next;
00578                                                 }
00579                                                 
00580                                                 if(sa->sound)
00581                                                         ((ID *)sa->sound)->us--;
00582                                                 
00583                                                 sa->sound= (struct bSound *)sound;
00584                                                 
00585                                                 if(sound)
00586                                                         sound->us++;
00587                                                 
00588                                                 sa->sndnr= 0;
00589                                                 didit= 1;
00590                                         }
00591                                 }
00592                                 act= act->next;
00593                         }
00594                         if(didit)
00595                                 break;
00596                 }
00597 
00598                 break;
00599         }
00600 }
00601 
00602 
00603 static const char *sensor_name(int type)
00604 {
00605         switch (type) {
00606         case SENS_ALWAYS:
00607                 return "Always";
00608         case SENS_TOUCH:
00609                 return "Touch";
00610         case SENS_NEAR:
00611                 return "Near";
00612         case SENS_KEYBOARD:
00613                 return "Keyboard";
00614         case SENS_PROPERTY:
00615                 return "Property";
00616         case SENS_ARMATURE:
00617                 return "Armature";
00618         case SENS_ACTUATOR:
00619                 return "Actuator";
00620         case SENS_DELAY:
00621                 return "Delay";
00622         case SENS_MOUSE:
00623                 return "Mouse";
00624         case SENS_COLLISION:
00625                 return "Collision";
00626         case SENS_RADAR:
00627                 return "Radar";
00628         case SENS_RANDOM:
00629                 return "Random";
00630         case SENS_RAY:
00631                 return "Ray";
00632         case SENS_MESSAGE:
00633                 return "Message";
00634         case SENS_JOYSTICK:
00635                 return "Joystick";
00636         }
00637         return "unknown";
00638 }
00639 
00640 static const char *sensor_pup(void)
00641 {
00642         /* the number needs to match defines in DNA_sensor_types.h */
00643         return "Sensors %t|Always %x0|Delay %x13|Keyboard %x3|Mouse %x5|"
00644                 "Touch %x1|Collision %x6|Near %x2|Radar %x7|"
00645                 "Property %x4|Random %x8|Ray %x9|Message %x10|Joystick %x11|Actuator %x12|Armature %x14";
00646 }
00647 
00648 static const char *controller_name(int type)
00649 {
00650         switch (type) {
00651         case CONT_LOGIC_AND:
00652                 return "And";
00653         case CONT_LOGIC_OR:
00654                 return "Or";
00655         case CONT_LOGIC_NAND:
00656                 return "Nand";
00657         case CONT_LOGIC_NOR:
00658                 return "Nor";
00659         case CONT_LOGIC_XOR:
00660                 return "Xor";
00661         case CONT_LOGIC_XNOR:
00662                 return "Xnor";
00663         case CONT_EXPRESSION:
00664                 return "Expression";
00665         case CONT_PYTHON:
00666                 return "Python";
00667         }
00668         return "unknown";
00669 }
00670 
00671 static const char *controller_pup(void)
00672 {
00673         return "Controllers   %t|AND %x0|OR %x1|XOR %x6|NAND %x4|NOR %x5|XNOR %x7|Expression %x2|Python %x3";
00674 }
00675 
00676 static const char *actuator_name(int type)
00677 {
00678         switch (type) {
00679         case ACT_SHAPEACTION:
00680                 return "Shape Action";
00681         case ACT_ACTION:
00682                 return "Action";
00683         case ACT_OBJECT:
00684                 return "Motion";
00685         case ACT_IPO:
00686                 return "F-Curve";
00687         case ACT_LAMP:
00688                 return "Lamp";
00689         case ACT_CAMERA:
00690                 return "Camera";
00691         case ACT_MATERIAL:
00692                 return "Material";
00693         case ACT_SOUND:
00694                 return "Sound";
00695         case ACT_PROPERTY:
00696                 return "Property";
00697         case ACT_EDIT_OBJECT:
00698                 return "Edit Object";
00699         case ACT_CONSTRAINT:
00700                 return "Constraint";
00701         case ACT_SCENE:
00702                 return "Scene";
00703         case ACT_GROUP:
00704                 return "Group";
00705         case ACT_RANDOM:
00706                 return "Random";
00707         case ACT_MESSAGE:
00708                 return "Message";
00709         case ACT_GAME:
00710                 return "Game";
00711         case ACT_VISIBILITY:
00712                 return "Visibility";
00713         case ACT_2DFILTER:
00714                 return "Filter 2D";
00715         case ACT_PARENT:
00716                 return "Parent";
00717         case ACT_STATE:
00718                 return "State";
00719         case ACT_ARMATURE:
00720                 return "Armature";
00721         }
00722         return "unknown";
00723 }
00724 
00725 
00726 
00727 
00728 static const char *actuator_pup(Object *owner)
00729 {
00730         switch (owner->type)
00731         {
00732         case OB_ARMATURE:
00733                 return "Actuators  %t|Action %x15|Armature %x23|Motion %x0|Constraint %x9|Ipo %x1"
00734                         "|Camera %x3|Sound %x5|Property %x6|Edit Object %x10"
00735                                                 "|Scene %x11|Random %x13|Message %x14|Game %x17"
00736                         "|Visibility %x18|2D Filter %x19|Parent %x20|State %x22";
00737                 break;
00738 
00739         case OB_MESH:
00740                 return "Actuators  %t|Shape Action %x21|Motion %x0|Constraint %x9|Ipo %x1"
00741                         "|Camera %x3|Sound %x5|Property %x6|Edit Object %x10"
00742                                                 "|Scene %x11|Random %x13|Message %x14|Game %x17"
00743                         "|Visibility %x18|2D Filter %x19|Parent %x20|State %x22";
00744                 break;
00745 
00746         default:
00747                 return "Actuators  %t|Motion %x0|Constraint %x9|Ipo %x1"
00748                         "|Camera %x3|Sound %x5|Property %x6|Edit Object %x10"
00749                                                 "|Scene %x11|Random %x13|Message %x14|Game %x17"
00750                         "|Visibility %x18|2D Filter %x19|Parent %x20|State %x22";
00751         }
00752 }
00753 
00754 
00755 
00756 static void set_sca_ob(Object *ob)
00757 {
00758         bController *cont;
00759         bActuator *act;
00760 
00761         cont= ob->controllers.first;
00762         while(cont) {
00763                 cont->mynew= (bController *)ob;
00764                 cont= cont->next;
00765         }
00766         act= ob->actuators.first;
00767         while(act) {
00768                 act->mynew= (bActuator *)ob;
00769                 act= act->next;
00770         }
00771 }
00772 
00773 static ID **get_selected_and_linked_obs(bContext *C, short *count, short scavisflag)
00774 {
00775         Base *base;
00776         Main *bmain= CTX_data_main(C);
00777         Scene *scene= CTX_data_scene(C);
00778         Object *ob, *obt, *obact= CTX_data_active_object(C);
00779         ID **idar;
00780         bSensor *sens;
00781         bController *cont;
00782         unsigned int lay;
00783         int a, nr, doit;
00784         
00785         /* we need a sorted object list */
00786         /* set scavisflags flags in Objects to indicate these should be evaluated */
00787         /* also hide ob pointers in ->new entries of controllerss/actuators */
00788         
00789         *count= 0;
00790         
00791         if(scene==NULL) return NULL;
00792         
00793         ob= bmain->object.first;
00794         while(ob) {
00795                 ob->scavisflag= 0;
00796                 set_sca_ob(ob);
00797                 ob= ob->id.next;
00798         }
00799         
00800         /* XXX here it checked 3d lay */
00801         lay= scene->lay;
00802         
00803         base= FIRSTBASE;
00804         while(base) {
00805                 if(base->lay & lay) {
00806                         if(base->flag & SELECT) {
00807                                 if(scavisflag & BUTS_SENS_SEL) base->object->scavisflag |= OB_VIS_SENS;
00808                                 if(scavisflag & BUTS_CONT_SEL) base->object->scavisflag |= OB_VIS_CONT;
00809                                 if(scavisflag & BUTS_ACT_SEL) base->object->scavisflag |= OB_VIS_ACT;
00810                         }
00811                 }
00812                 base= base->next;
00813         }
00814 
00815         if(obact) {
00816                 if(scavisflag & BUTS_SENS_ACT) obact->scavisflag |= OB_VIS_SENS;
00817                 if(scavisflag & BUTS_CONT_ACT) obact->scavisflag |= OB_VIS_CONT;
00818                 if(scavisflag & BUTS_ACT_ACT) obact->scavisflag |= OB_VIS_ACT;
00819         }
00820         
00821         /* BUTS_XXX_STATE are similar to BUTS_XXX_LINK for selecting the object */
00822         if(scavisflag & (BUTS_SENS_LINK|BUTS_CONT_LINK|BUTS_ACT_LINK|BUTS_SENS_STATE|BUTS_ACT_STATE)) {
00823                 doit= 1;
00824                 while(doit) {
00825                         doit= 0;
00826                         
00827                         ob= bmain->object.first;
00828                         while(ob) {
00829                         
00830                                 /* 1st case: select sensor when controller selected */
00831                                 if((scavisflag & (BUTS_SENS_LINK|BUTS_SENS_STATE)) && (ob->scavisflag & OB_VIS_SENS)==0) {
00832                                         sens= ob->sensors.first;
00833                                         while(sens) {
00834                                                 for(a=0; a<sens->totlinks; a++) {
00835                                                         if(sens->links[a]) {
00836                                                                 obt= (Object *)sens->links[a]->mynew;
00837                                                                 if(obt && (obt->scavisflag & OB_VIS_CONT)) {
00838                                                                         doit= 1;
00839                                                                         ob->scavisflag |= OB_VIS_SENS;
00840                                                                         break;
00841                                                                 }
00842                                                         }
00843                                                 }
00844                                                 if(doit) break;
00845                                                 sens= sens->next;
00846                                         }
00847                                 }
00848                                 
00849                                 /* 2nd case: select cont when act selected */
00850                                 if((scavisflag & BUTS_CONT_LINK)  && (ob->scavisflag & OB_VIS_CONT)==0) {
00851                                         cont= ob->controllers.first;
00852                                         while(cont) {
00853                                                 for(a=0; a<cont->totlinks; a++) {
00854                                                         if(cont->links[a]) {
00855                                                                 obt= (Object *)cont->links[a]->mynew;
00856                                                                 if(obt && (obt->scavisflag & OB_VIS_ACT)) {
00857                                                                         doit= 1;
00858                                                                         ob->scavisflag |= OB_VIS_CONT;
00859                                                                         break;
00860                                                                 }
00861                                                         }
00862                                                 }
00863                                                 if(doit) break;
00864                                                 cont= cont->next;
00865                                         }
00866                                 }
00867                                 
00868                                 /* 3rd case: select controller when sensor selected */
00869                                 if((scavisflag & BUTS_CONT_LINK) && (ob->scavisflag & OB_VIS_SENS)) {
00870                                         sens= ob->sensors.first;
00871                                         while(sens) {
00872                                                 for(a=0; a<sens->totlinks; a++) {
00873                                                         if(sens->links[a]) {
00874                                                                 obt= (Object *)sens->links[a]->mynew;
00875                                                                 if(obt && (obt->scavisflag & OB_VIS_CONT)==0) {
00876                                                                         doit= 1;
00877                                                                         obt->scavisflag |= OB_VIS_CONT;
00878                                                                 }
00879                                                         }
00880                                                 }
00881                                                 sens= sens->next;
00882                                         }
00883                                 }
00884                                 
00885                                 /* 4th case: select actuator when controller selected */
00886                                 if( (scavisflag & (BUTS_ACT_LINK|BUTS_ACT_STATE))  && (ob->scavisflag & OB_VIS_CONT)) {
00887                                         cont= ob->controllers.first;
00888                                         while(cont) {
00889                                                 for(a=0; a<cont->totlinks; a++) {
00890                                                         if(cont->links[a]) {
00891                                                                 obt= (Object *)cont->links[a]->mynew;
00892                                                                 if(obt && (obt->scavisflag & OB_VIS_ACT)==0) {
00893                                                                         doit= 1;
00894                                                                         obt->scavisflag |= OB_VIS_ACT;
00895                                                                 }
00896                                                         }
00897                                                 }
00898                                                 cont= cont->next;
00899                                         }
00900                                         
00901                                 }
00902                                 ob= ob->id.next;
00903                         }
00904                 }
00905         } 
00906         
00907         /* now we count */
00908         ob= bmain->object.first;
00909         while(ob) {
00910                 if( ob->scavisflag ) (*count)++;
00911                 ob= ob->id.next;
00912         }
00913 
00914         if(*count==0) return NULL;
00915         if(*count>24) *count= 24;               /* temporal */
00916         
00917         idar= MEM_callocN( (*count)*sizeof(void *), "idar");
00918         
00919         ob= bmain->object.first;
00920         nr= 0;
00921 
00922         /* make the active object always the first one of the list */
00923         if (obact) {
00924                 idar[0]= (ID *)obact;
00925                 nr++;
00926         }
00927 
00928         while(ob) {
00929                 if( (ob->scavisflag) && (ob != obact)) {
00930                         idar[nr]= (ID *)ob;
00931                         nr++;
00932                 }
00933                 if(nr>=24) break;
00934                 ob= ob->id.next;
00935         }
00936         
00937         /* just to be sure... these were set in set_sca_done_ob() */
00938         clear_sca_new_poins();
00939         
00940         return idar;
00941 }
00942 
00943 
00944 static int get_col_sensor(int type)
00945 {
00946         /* XXX themecolors not here */
00947         
00948         switch(type) {
00949         case SENS_ALWAYS:               return TH_PANEL;
00950         case SENS_DELAY:                return TH_PANEL;
00951         case SENS_TOUCH:                return TH_PANEL;
00952         case SENS_COLLISION:    return TH_PANEL;
00953         case SENS_NEAR:                 return TH_PANEL; 
00954         case SENS_KEYBOARD:             return TH_PANEL;
00955         case SENS_PROPERTY:             return TH_PANEL;
00956         case SENS_ARMATURE:             return TH_PANEL;
00957         case SENS_ACTUATOR:             return TH_PANEL;
00958         case SENS_MOUSE:                return TH_PANEL;
00959         case SENS_RADAR:                return TH_PANEL;
00960         case SENS_RANDOM:               return TH_PANEL;
00961         case SENS_RAY:                  return TH_PANEL;
00962         case SENS_MESSAGE:              return TH_PANEL;
00963         case SENS_JOYSTICK:             return TH_PANEL;
00964         default:                                return TH_PANEL;
00965         }
00966 }
00967 static void set_col_sensor(int type, int medium)
00968 {
00969         int col= get_col_sensor(type);
00970         UI_ThemeColorShade(col, medium?30:0);
00971 }
00972 
00973 
00974 static void verify_logicbutton_func(bContext *UNUSED(C), void *data1, void *data2)
00975 {
00976         bSensor *sens= (bSensor*)data1;
00977         
00978         if(sens->level && sens->tap) {
00979                 if(data2 == &(sens->level))     
00980                         sens->tap= 0;
00981                 else
00982                         sens->level= 0;
00983         }
00984 }
00985 
00986 static void test_scriptpoin_but(struct bContext *C, const char *name, ID **idpp)
00987 {
00988         *idpp= BLI_findstring(&CTX_data_main(C)->text, name, offsetof(ID, name) + 2);
00989 }
00990 
00991 static void test_actionpoin_but(struct bContext *C, const char *name, ID **idpp)
00992 {
00993         *idpp= BLI_findstring(&CTX_data_main(C)->action, name, offsetof(ID, name) + 2);
00994         if(*idpp)
00995                 id_us_plus(*idpp);
00996 }
00997 
00998 
00999 static void test_obpoin_but(struct bContext *C, const char *name, ID **idpp)
01000 {
01001         *idpp= BLI_findstring(&CTX_data_main(C)->object, name, offsetof(ID, name) + 2);
01002         if(*idpp)
01003                 id_lib_extern(*idpp);   /* checks lib data, sets correct flag for saving then */
01004 }
01005 
01006 static void test_meshpoin_but(struct bContext *C, const char *name, ID **idpp)
01007 {
01008         *idpp= BLI_findstring(&CTX_data_main(C)->mesh, name, offsetof(ID, name) + 2);
01009         if(*idpp)
01010                 id_us_plus(*idpp);
01011 }
01012 
01013 static void test_matpoin_but(struct bContext *C, const char *name, ID **idpp)
01014 {
01015         *idpp= BLI_findstring(&CTX_data_main(C)->mat, name, offsetof(ID, name) + 2);
01016         if(*idpp)
01017                 id_us_plus(*idpp);
01018 }
01019 
01020 static void test_scenepoin_but(struct bContext *C, const char *name, ID **idpp)
01021 {
01022         *idpp= BLI_findstring(&CTX_data_main(C)->scene, name, offsetof(ID, name) + 2);
01023         if(*idpp)
01024                 id_us_plus(*idpp);
01025 }
01026 
01027 static void test_keyboard_event(struct bContext *UNUSED(C), void *arg_ks, void *UNUSED(arg))
01028 {
01029         bKeyboardSensor *ks= (bKeyboardSensor*)arg_ks;
01030         
01031         if(!ISKEYBOARD(ks->key))
01032                 ks->key= 0;
01033         if(!ISKEYBOARD(ks->qual))
01034                 ks->qual= 0;
01035         if(!ISKEYBOARD(ks->qual2))
01036                 ks->qual2= 0;
01037 }
01038 
01043 static void draw_default_sensor_header(bSensor *sens,
01044                                                                 uiBlock *block,
01045                                                                 short x,
01046                                                                 short y,
01047                                                                 short w) 
01048 {
01049         uiBut *but;
01050         
01051         /* Pulsing and frequency */
01052         uiBlockBeginAlign(block);
01053         uiDefIconButBitS(block, TOG, SENS_PULSE_REPEAT, 1, ICON_DOTSUP,
01054                          (short)(x + 10 + 0. * (w-20)), (short)(y - 21), (short)(0.1 * (w-20)), 19,
01055                          &sens->pulse, 0.0, 0.0, 0, 0,
01056                          "Activate TRUE level triggering (pulse mode)");
01057 
01058         uiDefIconButBitS(block, TOG, SENS_NEG_PULSE_MODE, 1, ICON_DOTSDOWN,
01059                          (short)(x + 10 + 0.1 * (w-20)), (short)(y - 21), (short)(0.1 * (w-20)), 19,
01060                          &sens->pulse, 0.0, 0.0, 0, 0,
01061                          "Activate FALSE level triggering (pulse mode)");
01062         uiDefButS(block, NUM, 1, "f:",
01063                          (short)(x + 10 + 0.2 * (w-20)), (short)(y - 21), (short)(0.275 * (w-20)), 19,
01064                          &sens->freq, 0.0, 10000.0, 0, 0,
01065                          "Delay between repeated pulses (in logic tics, 0 = no delay)");
01066         uiBlockEndAlign(block);
01067         
01068         /* value or shift? */
01069         uiBlockBeginAlign(block);
01070         but= uiDefButS(block, TOG, 1, "Level",
01071                          (short)(x + 10 + 0.5 * (w-20)), (short)(y - 21), (short)(0.20 * (w-20)), 19,
01072                          &sens->level, 0.0, 0.0, 0, 0,
01073                          "Level detector, trigger controllers of new states (only applicable upon logic state transition)");
01074         uiButSetFunc(but, verify_logicbutton_func, sens, &(sens->level));
01075         but= uiDefButS(block, TOG, 1, "Tap",
01076                          (short)(x + 10 + 0.702 * (w-20)), (short)(y - 21), (short)(0.12 * (w-20)), 19,
01077                          &sens->tap, 0.0, 0.0, 0, 0,
01078                          "Trigger controllers only for an instant, even while the sensor remains true");
01079         uiButSetFunc(but, verify_logicbutton_func, sens, &(sens->tap));
01080         uiBlockEndAlign(block);
01081         
01082         uiDefButS(block, TOG, 1, "Inv",
01083                          (short)(x + 10 + 0.85 * (w-20)), (short)(y - 21), (short)(0.15 * (w-20)), 19,
01084                          &sens->invert, 0.0, 0.0, 0, 0,
01085                          "Invert the level (output) of this sensor");
01086 }
01087 
01088 static void get_armature_bone_constraint(Object *ob, const char *posechannel, const char *constraint_name, bConstraint **constraint)
01089 {
01090         /* check that bone exist in the active object */
01091         if (ob->type == OB_ARMATURE && ob->pose) {
01092                 bPoseChannel *pchan= get_pose_channel(ob->pose, posechannel);
01093                 if(pchan) {
01094                         bConstraint *con= BLI_findstring(&pchan->constraints, constraint_name, offsetof(bConstraint, name));
01095                         if(con) {
01096                                 *constraint= con;
01097                         }
01098                 }
01099         }
01100         /* didn't find any */
01101 }
01102 static void check_armature_bone_constraint(Object *ob, char *posechannel, char *constraint)
01103 {
01104         /* check that bone exist in the active object */
01105         if (ob->type == OB_ARMATURE && ob->pose) {
01106                 bPoseChannel *pchan;
01107                 bPose *pose = ob->pose;
01108                 for (pchan=pose->chanbase.first; pchan; pchan=pchan->next) {
01109                         if (!strcmp(pchan->name, posechannel)) {
01110                                 /* found it, now look for constraint channel */
01111                                 bConstraint *con;
01112                                 for (con=pchan->constraints.first; con; con=con->next) {
01113                                         if (!strcmp(con->name, constraint)) {
01114                                                 /* found it, all ok */
01115                                                 return;                                         
01116                                         }
01117                                 }
01118                                 /* didn't find constraint, make empty */
01119                                 constraint[0] = 0;
01120                                 return;
01121                         }
01122                 }
01123         }
01124         /* didn't find any */
01125         posechannel[0] = 0;
01126         constraint[0] = 0;
01127 }
01128 
01129 static void check_armature_sensor(bContext *C, void *arg1_but, void *arg2_sens)
01130 {
01131         bArmatureSensor *sens = arg2_sens;
01132         uiBut *but = arg1_but;
01133         Object *ob= CTX_data_active_object(C);
01134 
01135         /* check that bone exist in the active object */
01136         but->retval = B_REDR;
01137         check_armature_bone_constraint(ob, sens->posechannel, sens->constraint);
01138 }
01139 
01140 static short draw_sensorbuttons(Object *ob, bSensor *sens, uiBlock *block, short xco, short yco, short width)
01141 {
01142         bNearSensor      *ns           = NULL;
01143         bTouchSensor     *ts           = NULL;
01144         bKeyboardSensor  *ks           = NULL;
01145         bPropertySensor  *ps           = NULL;
01146         bArmatureSensor  *arm          = NULL;
01147         bMouseSensor     *ms           = NULL;
01148         bCollisionSensor *cs           = NULL;
01149         bRadarSensor     *rs           = NULL;
01150         bRandomSensor    *randomSensor = NULL;
01151         bRaySensor       *raySens      = NULL;
01152         bMessageSensor   *mes          = NULL;
01153         bJoystickSensor  *joy              = NULL;
01154         bActuatorSensor  *as           = NULL;
01155         bDelaySensor     *ds               = NULL;
01156         uiBut *but;
01157         short ysize;
01158         const char *str;
01159         
01160         /* yco is at the top of the rect, draw downwards */
01161         
01162         set_col_sensor(sens->type, 0);
01163         
01164         switch (sens->type)
01165         {
01166         case SENS_ALWAYS:
01167                 {
01168                         ysize= 24;
01169                         
01170                         glRects(xco, yco-ysize, xco+width, yco);
01171                         uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
01172                         
01173                         draw_default_sensor_header(sens, block, xco, yco, width);
01174                         
01175                         yco-= ysize;
01176                         
01177                         break;
01178                 }
01179         case SENS_TOUCH:
01180                 {
01181                         ysize= 48; 
01182                         
01183                         glRects(xco, yco-ysize, xco+width, yco); 
01184                         uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); 
01185                         
01186                         draw_default_sensor_header(sens, block, xco, yco, width);
01187                         
01188                         ts= sens->data; 
01189                         
01190                         /* uiDefBut(block, TEX, 1, "Property:", xco,yco-22,width, 19, &ts->name, 0, 31, 0, 0, "Only look for Objects with this property"); */
01191                         uiDefIDPoinBut(block, test_matpoin_but, ID_MA, 1, "MA:",(short)(xco + 10),(short)(yco-44), (short)(width - 20), 19, &ts->ma,  "Only look for floors with this Material"); 
01193                         yco-= ysize; 
01194                         break; 
01195                 }
01196         case SENS_COLLISION:
01197                 {
01198                         ysize= 48;
01199                         
01200                         glRects(xco, yco-ysize, xco+width, yco);
01201                         uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
01202                         
01203                         draw_default_sensor_header(sens, block, xco, yco, width);
01204                         cs= sens->data;
01205                         
01206                         /* The collision sensor will become a generic collision (i.e. it     */
01207                         /* absorb the old touch sensor).                                     */
01208 
01209                         uiDefButBitS(block, TOG, SENS_COLLISION_PULSE, B_REDR, "Pulse",(short)(xco + 10),(short)(yco - 44),
01210                                 (short)(0.20 * (width-20)), 19, &cs->mode, 0.0, 0.0, 0, 0,
01211                                 "Changes to the set of colliding objects generated pulses");
01212                         
01213                         uiDefButBitS(block, TOG, SENS_COLLISION_MATERIAL, B_REDR, "M/P",(short)(xco + 10 + (0.20 * (width-20))),(short)(yco - 44),
01214                                 (short)(0.20 * (width-20)), 19, &cs->mode, 0.0, 0.0, 0, 0,
01215                                 "Toggle collision on material or property");
01216                         
01217                         if (cs->mode & SENS_COLLISION_MATERIAL) {
01218                                 uiDefBut(block, TEX, 1, "Material:", (short)(xco + 10 + 0.40 * (width-20)),
01219                                         (short)(yco-44), (short)(0.6*(width-20)), 19, &cs->materialName, 0, 31, 0, 0,
01220                                         "Only look for Objects with this material");
01221                         } else {
01222                                 uiDefBut(block, TEX, 1, "Property:", (short)(xco + 10 + 0.40 * (width-20)), (short)(yco-44),
01223                                         (short)(0.6*(width-20)), 19, &cs->name, 0, 31, 0, 0,
01224                                         "Only look for Objects with this property");
01225                         }
01226         
01227                         /*              uiDefButS(block, NUM, 1, "Damp:",       xco+10+width-90,yco-24, 70, 19, &cs->damp, 0, 250, 0, 0, "For 'damp' time don't detect another collision"); */
01228                         
01229                         yco-= ysize;
01230                         break;
01231                 }
01232         case SENS_NEAR:
01233                 {
01234                         ysize= 72;
01235                         
01236                         glRects(xco, yco-ysize, xco+width, yco);
01237                         uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
01238                         
01239                         draw_default_sensor_header(sens, block, xco, yco, width);
01240                         ns= sens->data;
01241                         
01242                         uiDefBut(block, TEX, 1, "Property:",(short)(10+xco),(short)(yco-44), (short)(width-20), 19,
01243                                 &ns->name, 0, 31, 0, 0, "Only look for Objects with this property");
01244                         uiDefButF(block, NUM, 1, "Dist",(short)(10+xco),(short)(yco-68),(short)((width-22)/2), 19,
01245                                 &ns->dist, 0.0, 1000.0, 1000, 0, "Trigger distance");
01246                         uiDefButF(block, NUM, 1, "Reset",(short)(10+xco+(width-22)/2), (short)(yco-68), (short)((width-22)/2), 19,
01247                                 &ns->resetdist, 0.0, 1000.0, 1000, 0, "Reset distance"); 
01248                         yco-= ysize;
01249                         break;
01250                 }
01251         case SENS_RADAR:
01252                 {
01253                         ysize= 72; 
01254                         
01255                         glRects(xco, yco-ysize, xco+width, yco);
01256                         uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
01257                         
01258                         draw_default_sensor_header(sens, block, xco, yco, width);
01259                         
01260                         rs= sens->data;
01261                         
01262                         uiDefBut(block, TEX, 1, "Prop:",
01263                                          (short)(10+xco),(short)(yco-44), (short)(0.7 * (width-20)), 19,
01264                                          &rs->name, 0, 31, 0, 0,
01265                                          "Only look for Objects with this property");
01266 
01267                         str = "Type %t|+X axis %x0|+Y axis %x1|+Z axis %x2|-X axis %x3|-Y axis %x4|-Z axis %x5"; 
01268                         uiDefButS(block, MENU, B_REDR, str,
01269                                 (short)(10+xco+0.7 * (width-20)), (short)(yco-44), (short)(0.3 * (width-22)), 19,
01270                                 &rs->axis, 2.0, 31, 0, 0,
01271                                 "Specify along which axis the radar cone is cast");
01272                                 
01273                         uiDefButF(block, NUM, 1, "Ang:",
01274                                          (short)(10+xco), (short)(yco-68), (short)((width-20)/2), 19,
01275                                          &rs->angle, 0.0, 179.9, 10, 0,
01276                                          "Opening angle of the radar cone");
01277                         uiDefButF(block, NUM, 1, "Dist:",
01278                                          (short)(xco+10 + (width-20)/2), (short)(yco-68), (short)((width-20)/2), 19,
01279                                          &rs->range, 0.01, 10000.0, 100, 0,
01280                                          "Depth of the radar cone");
01281                         yco-= ysize;
01282                         break;
01283                 }
01284         case SENS_KEYBOARD:
01285                 {
01286                         ks= sens->data;
01287                         
01288                         /* 5 lines: 120 height */
01289                         ysize= (ks->type&1) ? 96:120;
01290                         
01291                         glRects(xco, yco-ysize, xco+width, yco);
01292                         uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
01293                         
01294                         /* header line */
01295                         draw_default_sensor_header(sens, block, xco, yco, width);
01296                         
01297                         /* part of line 1 */
01298                         uiDefBut(block, LABEL, 0, "Key",          xco, yco-44, 40, 19, NULL, 0, 0, 0, 0, "");
01299                         uiDefButBitS(block, TOG, 1, B_REDR, "All keys",   xco+40+(width/2), yco-44, (width/2)-50, 19,
01300                                 &ks->type, 0, 0, 0, 0, "");
01301                         
01302                         
01303                         if ((ks->type&1)==0) { /* is All Keys option off? */
01304                                 /* line 2: hotkey and allkeys toggle */
01305                                 but= uiDefKeyevtButS(block, 0, "", xco+40, yco-44, (width)/2, 19, &ks->key, "Key code");
01306                                 uiButSetFunc(but, test_keyboard_event, ks, NULL);
01307                                 
01308                                 /* line 3: two key modifyers (qual1, qual2) */
01309                                 uiDefBut(block, LABEL, 0, "Hold",         xco, yco-68, 40, 19, NULL, 0, 0, 0, 0, "");
01310                                 but= uiDefKeyevtButS(block, 0, "", xco+40, yco-68, (width-50)/2, 19, &ks->qual, "Modifier key code");
01311                                 uiButSetFunc(but, test_keyboard_event, ks, NULL);
01312                                 but= uiDefKeyevtButS(block, 0, "", xco+40+(width-50)/2, yco-68, (width-50)/2, 19, &ks->qual2, "Second Modifier key code");
01313                                 uiButSetFunc(but, test_keyboard_event, ks, NULL);
01314                         }
01315                         
01316                         /* line 4: toggle property for string logging mode */
01317                         uiDefBut(block, TEX, 1, "LogToggle: ",
01318                                 xco+10, yco-((ks->type&1) ? 68:92), (width-20), 19,
01319                                 ks->toggleName, 0, 31, 0, 0,
01320                                 "Property that indicates whether to log "
01321                                 "keystrokes as a string");
01322                         
01323                         /* line 5: target property for string logging mode */
01324                         uiDefBut(block, TEX, 1, "Target: ",
01325                                 xco+10, yco-((ks->type&1) ? 92:116), (width-20), 19,
01326                                 ks->targetName, 0, 31, 0, 0,
01327                                 "Property that receives the keystrokes in case "
01328                                 "a string is logged");
01329                         
01330                         yco-= ysize;
01331                         break;
01332                 }
01333         case SENS_PROPERTY:
01334                 {
01335                         ysize= 96;
01336                         
01337                         glRects(xco, yco-ysize, xco+width, yco);
01338                         uiEmboss((float)xco, (float)yco-ysize,
01339                                 (float)xco+width, (float)yco, 1);
01340                         
01341                         draw_default_sensor_header(sens, block, xco, yco, width);
01342                         ps= sens->data;
01343                         
01344                         str= "Type %t|Equal %x0|Not Equal %x1|Interval %x2|Changed %x3"; 
01345                         /* str= "Type %t|Equal %x0|Not Equal %x1"; */
01346                         uiDefButI(block, MENU, B_REDR, str,                     xco+30,yco-44,width-60, 19,
01347                                 &ps->type, 0, 31, 0, 0, "Type");
01348                         
01349                         if (ps->type != SENS_PROP_EXPRESSION)
01350                         {
01351                                 uiDefBut(block, TEX, 1, "Prop: ",                       xco+30,yco-68,width-60, 19,
01352                                         ps->name, 0, 31, 0, 0,  "Property name");
01353                         }
01354                         
01355                         if(ps->type == SENS_PROP_INTERVAL)
01356                         {
01357                                 uiDefBut(block, TEX, 1, "Min: ",                xco,yco-92,width/2, 19,
01358                                         ps->value, 0, 31, 0, 0, "check for min value");
01359                                 uiDefBut(block, TEX, 1, "Max: ",                xco+width/2,yco-92,width/2, 19,
01360                                         ps->maxvalue, 0, 31, 0, 0, "check for max value");
01361                         }
01362                         else if(ps->type == SENS_PROP_CHANGED);
01363                         else
01364                         {
01365                                 uiDefBut(block, TEX, 1, "Value: ",              xco+30,yco-92,width-60, 19,
01366                                         ps->value, 0, 31, 0, 0, "check for value");
01367                         }
01368                         
01369                         yco-= ysize;
01370                         break;
01371                 }
01372         case SENS_ARMATURE:
01373                 {
01374                         ysize= 70;
01375                         
01376                         glRects(xco, yco-ysize, xco+width, yco);
01377                         uiEmboss((float)xco, (float)yco-ysize,
01378                                 (float)xco+width, (float)yco, 1);
01379                         
01380                         draw_default_sensor_header(sens, block, xco, yco, width);
01381                         arm= sens->data;
01382 
01383                         if (ob->type == OB_ARMATURE) {
01384                                 uiBlockBeginAlign(block);
01385                                 but = uiDefBut(block, TEX, 1, "Bone: ",
01386                                                 (xco+10), (yco-44), (width-20)/2, 19,
01387                                                 arm->posechannel, 0, 31, 0, 0,
01388                                                 "Bone on which you want to check a constraint");
01389                                 uiButSetFunc(but, check_armature_sensor, but, arm);
01390                                 but = uiDefBut(block, TEX, 1, "Cons: ",
01391                                                 (xco+10)+(width-20)/2, (yco-44), (width-20)/2, 19,
01392                                                 arm->constraint, 0, 31, 0, 0,
01393                                                 "Name of the constraint you want to control");
01394                                 uiButSetFunc(but, check_armature_sensor, but, arm);
01395                                 uiBlockEndAlign(block);
01396 
01397                                 str= "Type %t|State changed %x0|Lin error below %x1|Lin error above %x2|Rot error below %x3|Rot error above %x4"; 
01398 
01399                                 uiDefButI(block, MENU, B_REDR, str,                     xco+10,yco-66,0.4*(width-20), 19,
01400                                         &arm->type, 0, 31, 0, 0, "Type");
01401                         
01402                                 if (arm->type != SENS_ARM_STATE_CHANGED)
01403                                 {
01404                                         uiDefButF(block, NUM, 1, "Value: ",             xco+10+0.4*(width-20),yco-66,0.6*(width-20), 19,
01405                                         &arm->value, -10000.0, 10000.0, 100, 0, "Test the error against this value");
01406                                 }
01407                         }
01408                         yco-= ysize;
01409                         break;
01410                 }
01411         case SENS_ACTUATOR:
01412                 {
01413                         ysize= 48;
01414                         
01415                         glRects(xco, yco-ysize, xco+width, yco);
01416                         uiEmboss((float)xco, (float)yco-ysize,
01417                                 (float)xco+width, (float)yco, 1);
01418                         
01419                         draw_default_sensor_header(sens, block, xco, yco, width);
01420                         as= sens->data;
01421                         
01422                         uiDefBut(block, TEX, 1, "Act: ",                        xco+30,yco-44,width-60, 19,
01423                                         as->name, 0, 31, 0, 0,  "Actuator name, actuator active state modifications will be detected");
01424                         yco-= ysize;
01425                         break;
01426                 }
01427         case SENS_DELAY:
01428                 {
01429                         ysize= 48;
01430                         
01431                         glRects(xco, yco-ysize, xco+width, yco);
01432                         uiEmboss((float)xco, (float)yco-ysize,
01433                                 (float)xco+width, (float)yco, 1);
01434                         
01435                         draw_default_sensor_header(sens, block, xco, yco, width);
01436                         ds = sens->data;
01437                         
01438                         uiDefButS(block, NUM, 0, "Delay",(short)(10+xco),(short)(yco-44),(short)((width-22)*0.4+10), 19,
01439                                 &ds->delay, 0.0, 5000.0, 0, 0, "Delay in number of logic tics before the positive trigger (default 60 per second)");
01440                         uiDefButS(block, NUM, 0, "Dur",(short)(10+xco+(width-22)*0.4+10),(short)(yco-44),(short)((width-22)*0.4-10), 19,
01441                                 &ds->duration, 0.0, 5000.0, 0, 0, "If >0, delay in number of logic tics before the negative trigger following the positive trigger");
01442                         uiDefButBitS(block, TOG, SENS_DELAY_REPEAT, 0, "REP",(short)(xco + 10 + (width-22)*0.8),(short)(yco - 44),
01443                                 (short)(0.20 * (width-22)), 19, &ds->flag, 0.0, 0.0, 0, 0,
01444                                 "Toggle repeat option. If selected, the sensor restarts after Delay+Dur logic tics");
01445                         yco-= ysize;
01446                         break;
01447                 }
01448         case SENS_MOUSE:
01449                 {
01450                         ms= sens->data;
01451                         /* Two lines: 48 pixels high. */
01452                         ysize = 48;
01453                         
01454                         glRects(xco, yco-ysize, xco+width, yco);
01455                         uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
01456                         
01457                         /* line 1: header */
01458                         draw_default_sensor_header(sens, block, xco, yco, width);
01459                         
01460                         /* Line 2: type selection. The number are a bit mangled to get
01461                         * proper compatibility with older .blend files. */
01462                         /* Any sensor type default is 0 but the ms enum starts in 1.
01463                          * Therefore the mosue sensor is initialized to 1 in sca.c */
01464                         str= "Type %t|Left button %x1|Middle button %x2|"
01465                                 "Right button %x4|Wheel Up %x5|Wheel Down %x6|Movement %x8|Mouse over %x16|Mouse over any%x32"; 
01466                         uiDefButS(block, MENU, B_REDR, str, xco+10, yco-44, (width*0.8f)-20, 19,
01467                                 &ms->type, 0, 31, 0, 0,
01468                                 "Specify the type of event this mouse sensor should trigger on");
01469                         
01470                         if(ms->type==32) {
01471                                 uiDefButBitS(block, TOG, SENS_MOUSE_FOCUS_PULSE, B_REDR, "Pulse",(short)(xco + 10) + (width*0.8f)-20,(short)(yco - 44),
01472                                         (short)(0.20 * (width-20)), 19, &ms->flag, 0.0, 0.0, 0, 0,
01473                                         "Moving the mouse over a different object generates a pulse");  
01474                         }
01475                         
01476                         yco-= ysize;
01477                         break;
01478                 }
01479         case SENS_RANDOM:
01480                 {
01481                         ysize = 48;
01482                         
01483                         glRects(xco, yco-ysize, xco+width, yco);
01484                         uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
01485                         
01486                         draw_default_sensor_header(sens, block, xco, yco, width);
01487                         randomSensor = sens->data;
01488                         /* some files were wrongly written, avoid crash now */
01489                         if (randomSensor)
01490                         {
01491                                 uiDefButI(block, NUM, 1, "Seed: ",              xco+10,yco-44,(width-20), 19,
01492                                         &randomSensor->seed, 0, 1000, 0, 0,
01493                                         "Initial seed of the generator. (Choose 0 for not random)");
01494                         }
01495                         yco-= ysize;
01496                         break;
01497                 }
01498         case SENS_RAY:
01499                 {
01500                         ysize = 72;
01501                         glRects(xco, yco-ysize, xco+width, yco);
01502                         uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
01503                         
01504                         draw_default_sensor_header(sens, block, xco, yco, width);
01505                         raySens = sens->data;
01506                         
01507                         /* 1. property or material */
01508                         uiDefButBitS(block, TOG, SENS_COLLISION_MATERIAL, B_REDR, "M/P",
01509                                 xco + 10,yco - 44, 0.20 * (width-20), 19,
01510                                 &raySens->mode, 0.0, 0.0, 0, 0,
01511                                 "Toggle collision on material or property");
01512                         
01513                         if (raySens->mode & SENS_COLLISION_MATERIAL)
01514                         {
01515                                 uiDefBut(block, TEX, 1, "Material:", xco + 10 + 0.20 * (width-20), yco-44, 0.8*(width-20), 19,
01516                                         &raySens->matname, 0, 31, 0, 0,
01517                                         "Only look for Objects with this material");
01518                         }
01519                         else
01520                         {
01521                                 uiDefBut(block, TEX, 1, "Property:", xco + 10 + 0.20 * (width-20), yco-44, 0.8*(width-20), 19,
01522                                         &raySens->propname, 0, 31, 0, 0,
01523                                         "Only look for Objects with this property");
01524                         }
01525 
01526                         /* X-Ray option */
01527                         uiDefButBitS(block, TOG, SENS_RAY_XRAY, 1, "X",
01528                                 xco + 10,yco - 68, 0.10 * (width-20), 19,
01529                                 &raySens->mode, 0.0, 0.0, 0, 0,
01530                                 "Toggle X-Ray option (see through objects that don't have the property)");
01531                         /* 2. sensing range */
01532                         uiDefButF(block, NUM, 1, "Range", xco+10 + 0.10 * (width-20), yco-68, 0.5 * (width-20), 19,
01533                                 &raySens->range, 0.01, 10000.0, 100, 0,
01534                                 "Sense objects no farther than this distance");
01535                         
01536                         /* 3. axis choice */
01537                         str = "Type %t|+ X axis %x1|+ Y axis %x0|+ Z axis %x2|- X axis %x3|- Y axis %x4|- Z axis %x5"; 
01538                         uiDefButI(block, MENU, B_REDR, str, xco+10 + 0.6 * (width-20), yco-68, 0.4 * (width-20), 19,
01539                                 &raySens->axisflag, 2.0, 31, 0, 0,
01540                                 "Specify along which axis the ray is cast");
01541                         
01542                         yco-= ysize;            
01543                         break;
01544                 }
01545         case SENS_MESSAGE:
01546                 {
01547                         mes = sens->data;
01548                         ysize = 2 * 24; /* total number of lines * 24 pixels/line */
01549                         
01550                         glRects(xco, yco-ysize, xco+width, yco);
01551                         uiEmboss((float)xco, (float)yco-ysize,
01552                                 (float)xco+width, (float)yco, 1);
01553                         
01554                         /* line 1: header line */
01555                         draw_default_sensor_header(sens, block, xco, yco, width);
01556                         
01557                         /* line 2: Subject filter */
01558                         uiDefBut(block, TEX, 1, "Subject: ",
01559                                 (xco+10), (yco-44), (width-20), 19,
01560                                 mes->subject, 0, 31, 0, 0,
01561                                 "Optional subject filter: only accept messages with this subject"
01562                                 ", or empty for all");
01563                         
01564                         yco -= ysize;
01565                         break;
01566                 }
01567                 case SENS_JOYSTICK:
01568                 {
01569 
01570                         ysize =  72;
01571                         
01572                         glRects(xco, yco-ysize, xco+width, yco);
01573                         uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
01574                         
01575                         /* line 1: header */
01576                         draw_default_sensor_header(sens, block, xco, yco, width);
01577 
01578                         joy= sens->data;
01579 
01580                         uiDefButC(block, NUM, 1, "Index:", xco+10, yco-44, 0.33 * (width-20), 19,
01581                         &joy->joyindex, 0, SENS_JOY_MAXINDEX-1, 100, 0,
01582                         "Specify which joystick to use");                       
01583 
01584                         str= "Type %t|Button %x0|Axis %x1|Single Axis %x3|Hat%x2"; 
01585                         uiDefButC(block, MENU, B_REDR, str, xco+87, yco-44, 0.26 * (width-20), 19,
01586                                 &joy->type, 0, 31, 0, 0,
01587                                 "The type of event this joystick sensor is triggered on");
01588                         
01589                         if (joy->type != SENS_JOY_AXIS_SINGLE) {
01590                                 if (joy->flag & SENS_JOY_ANY_EVENT) {
01591                                         switch (joy->type) {
01592                                         case SENS_JOY_AXIS:     
01593                                                 str = "All Axis Events";
01594                                                 break;
01595                                         case SENS_JOY_BUTTON:   
01596                                                 str = "All Button Events";
01597                                                 break;
01598                                         default:
01599                                                 str = "All Hat Events";
01600                                                 break;
01601                                         }
01602                                 } else {
01603                                         str = "All";
01604                                 }
01605                                 
01606                                 uiDefButBitS(block, TOG, SENS_JOY_ANY_EVENT, B_REDR, str,
01607                                         xco+10 + 0.475 * (width-20), yco-68, ((joy->flag & SENS_JOY_ANY_EVENT) ? 0.525 : 0.12) * (width-20), 19,
01608                                         &joy->flag, 0, 0, 0, 0,
01609                                         "Triggered by all events on this joysticks current type (axis/button/hat)");
01610                         }
01611                         if(joy->type == SENS_JOY_BUTTON)
01612                         {
01613                                 if ((joy->flag & SENS_JOY_ANY_EVENT)==0) {
01614                                         uiDefButI(block, NUM, 1, "Number:", xco+10 + 0.6 * (width-20), yco-68, 0.4 * (width-20), 19,
01615                                         &joy->button, 0, 18, 100, 0,
01616                                         "Specify which button to use");
01617                                 }
01618                         }
01619                         else if(joy->type == SENS_JOY_AXIS)
01620                         {
01621                                 uiDefButS(block, NUM, 1, "Number:", xco+10, yco-68, 0.46 * (width-20), 19,
01622                                 &joy->axis, 1, 8.0, 100, 0,
01623                                 "Specify which axis pair to use, 1 is useually the main direction input");
01624 
01625                                 uiDefButI(block, NUM, 1, "Threshold:", xco+10 + 0.6 * (width-20),yco-44, 0.4 * (width-20), 19,
01626                                 &joy->precision, 0, 32768.0, 100, 0,
01627                                 "Specify the precision of the axis");
01628 
01629                                 if ((joy->flag & SENS_JOY_ANY_EVENT)==0) {
01630                                         str = "Type %t|Up Axis %x1 |Down Axis %x3|Left Axis %x2|Right Axis %x0"; 
01631                                         uiDefButI(block, MENU, B_REDR, str, xco+10 + 0.6 * (width-20), yco-68, 0.4 * (width-20), 19,
01632                                         &joy->axisf, 2.0, 31, 0, 0,
01633                                         "The direction of the axis, use 'All Events' to receive events on any direction");
01634                                 }
01635                         }
01636                         else if (joy->type == SENS_JOY_HAT)
01637                         {
01638                                 uiDefButI(block, NUM, 1, "Number:", xco+10, yco-68, 0.46 * (width-20), 19,
01639                                 &joy->hat, 1, 4.0, 100, 0,
01640                                 "Specify which hat to use");
01641                                 
01642                                 if ((joy->flag & SENS_JOY_ANY_EVENT)==0) {
01643                                         str = "Direction%t|Up%x1|Down%x4|Left%x8|Right%x2|%l|Up/Right%x3|Down/Left%x12|Up/Left%x9|Down/Right%x6"; 
01644                                         uiDefButI(block, MENU, 0, str, xco+10 + 0.6 * (width-20), yco-68, 0.4 * (width-20), 19,
01645                                         &joy->hatf, 2.0, 31, 0, 0,
01646                                         "The direction of the hat, use 'All Events' to receive events on any direction");
01647                                 }
01648                         }
01649                         else { /* (joy->type == SENS_JOY_AXIS_SINGLE)*/
01650                                 uiDefButS(block, NUM, 1, "Number:", xco+10, yco-68, 0.46 * (width-20), 19,
01651                                 &joy->axis_single, 1, 16.0, 100, 0,
01652                                 "Specify a single axis (verticle/horizontal/other) to detect");
01653                                 
01654                                 uiDefButI(block, NUM, 1, "Threshold:", xco+10 + 0.6 * (width-20),yco-44, 0.4 * (width-20), 19,
01655                                 &joy->precision, 0, 32768.0, 100, 0,
01656                                 "Specify the precision of the axis");
01657                         }
01658                         yco-= ysize;
01659                         break;
01660                 }
01661         }
01662         
01663         return yco-4;
01664 }
01665 
01666 
01667 
01668 static short draw_controllerbuttons(bController *cont, uiBlock *block, short xco, short yco, short width)
01669 {
01670         bExpressionCont *ec;
01671         bPythonCont *pc;
01672         short ysize;
01673         
01674         switch (cont->type) {
01675         case CONT_EXPRESSION:
01676                 ysize= 28;
01677 
01678                 UI_ThemeColor(TH_PANEL);
01679                 glRects(xco, yco-ysize, xco+width, yco);
01680                 uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
01681                 
01682                 /* uiDefBut(block, LABEL, 1, "Not yet...", xco,yco-24,80, 19, NULL, 0, 0, 0, 0, ""); */
01683                 ec= cont->data; 
01684                 /* uiDefBut(block, BUT, 1, "Variables", xco,yco-24,80, 19, NULL, 0, 0, 0, 0, "Available variables for expression"); */
01685                 uiDefBut(block, TEX, 1, "Exp:",         xco + 10 , yco-21, width-20, 19,
01686                                  ec->str, 0, 127, 0, 0,
01687                                  "Expression"); 
01688                 
01689                 yco-= ysize;
01690                 break;
01691         case CONT_PYTHON:
01692                 ysize= 28;
01693                 
01694                 if(cont->data==NULL) init_controller(cont);
01695                 pc= cont->data;
01696                 
01697                 UI_ThemeColor(TH_PANEL);
01698                 glRects(xco, yco-ysize, xco+width, yco);
01699                 uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
01700 
01701         
01702                 uiBlockBeginAlign(block);
01703                 uiDefButI(block, MENU, B_REDR, "Execution Method%t|Script%x0|Module%x1", xco+4,yco-23, 66, 19, &pc->mode, 0, 0, 0, 0, "Python script type (textblock or module - faster)");
01704                 if(pc->mode==0)
01705                         uiDefIDPoinBut(block, test_scriptpoin_but, ID_TXT, 1, "", xco+70,yco-23,width-74, 19, &pc->text, "Blender textblock to run as a script");
01706                 else {
01707                         uiDefBut(block, TEX, 1, "", xco+70,yco-23,(width-70)-25, 19, pc->module, 0, 63, 0, 0, "Module name and function to run e.g. \"someModule.main\". Internal texts and external python files can be used");
01708                         uiDefButBitI(block, TOG, CONT_PY_DEBUG, B_REDR, "D", (xco+width)-25, yco-23, 19, 19, &pc->flag, 0, 0, 0, 0, "Continuously reload the module from disk for editing external modules without restarting");
01709                 }
01710                 uiBlockEndAlign(block);
01711                 
01712                 yco-= ysize;
01713                 break;
01714                 
01715         default:
01716                 ysize= 4;
01717 
01718                 UI_ThemeColor(TH_PANEL);
01719                 glRects(xco, yco-ysize, xco+width, yco);
01720                 uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
01721                 
01722                 yco-= ysize;
01723         }
01724         
01725         return yco;
01726 }
01727 
01728 static int get_col_actuator(int type)
01729 {
01730         switch(type) {
01731         case ACT_ACTION:                return TH_PANEL;
01732         case ACT_SHAPEACTION:   return TH_PANEL;
01733         case ACT_OBJECT:                return TH_PANEL;
01734         case ACT_IPO:                   return TH_PANEL;
01735         case ACT_PROPERTY:              return TH_PANEL;
01736         case ACT_SOUND:                 return TH_PANEL;
01737         case ACT_CAMERA:                return TH_PANEL;
01738         case ACT_EDIT_OBJECT:           return TH_PANEL;
01739         case ACT_GROUP:                 return TH_PANEL;
01740         case ACT_RANDOM:                return TH_PANEL;
01741         case ACT_SCENE:                 return TH_PANEL;
01742         case ACT_MESSAGE:               return TH_PANEL;
01743         case ACT_GAME:                  return TH_PANEL;
01744         case ACT_VISIBILITY:            return TH_PANEL;
01745         case ACT_CONSTRAINT:            return TH_PANEL;
01746         case ACT_STATE:                 return TH_PANEL;
01747         case ACT_ARMATURE:                      return TH_PANEL;
01748         default:                                return TH_PANEL;
01749         }
01750 }
01751 static void set_col_actuator(int item, int medium) 
01752 {
01753         int col= get_col_actuator(item);
01754         UI_ThemeColorShade(col, medium?30:10);
01755         
01756 }
01757 
01758 static void change_object_actuator(bContext *UNUSED(C), void *act, void *UNUSED(arg))
01759 {
01760         bObjectActuator *oa = act;
01761 
01762         if (oa->type != oa->otype) {
01763                 switch (oa->type) {
01764                 case ACT_OBJECT_NORMAL:
01765                         memset(oa, 0, sizeof(bObjectActuator));
01766                         oa->flag = ACT_FORCE_LOCAL|ACT_TORQUE_LOCAL|ACT_DLOC_LOCAL|ACT_DROT_LOCAL;
01767                         oa->type = ACT_OBJECT_NORMAL;
01768                         break;
01769 
01770                 case ACT_OBJECT_SERVO:
01771                         memset(oa, 0, sizeof(bObjectActuator));
01772                         oa->flag = ACT_LIN_VEL_LOCAL;
01773                         oa->type = ACT_OBJECT_SERVO;
01774                         oa->forcerot[0] = 30.0f;
01775                         oa->forcerot[1] = 0.5f;
01776                         oa->forcerot[2] = 0.0f;
01777                         break;
01778                 }
01779         }
01780 }
01781 
01782 static void change_ipo_actuator(bContext *UNUSED(C), void *arg1_but, void *arg2_ia)
01783 {
01784         bIpoActuator *ia = arg2_ia;
01785         uiBut *but = arg1_but;
01786 
01787         if (but->retval & ACT_IPOFORCE)
01788                 ia->flag &= ~ACT_IPOADD;
01789         else if (but->retval & ACT_IPOADD)
01790                 ia->flag &= ~ACT_IPOFORCE;
01791         but->retval = B_REDR;
01792 }
01793 
01794 static void update_object_actuator_PID(bContext *UNUSED(C), void *act, void *UNUSED(arg))
01795 {
01796         bObjectActuator *oa = act;
01797         oa->forcerot[0] = 60.0f*oa->forcerot[1];
01798 }
01799 
01800 static char *get_state_name(Object *ob, short bit)
01801 {
01802         bController *cont;
01803         unsigned int mask;
01804 
01805         mask = (1<<bit);
01806         cont = ob->controllers.first;
01807         while (cont) {
01808                 if (cont->state_mask & mask) {
01809                         return cont->name;
01810                 }
01811                 cont = cont->next;
01812         }
01813         return (char*)"";
01814 }
01815 
01816 static void check_state_mask(bContext *C, void *arg1_but, void *arg2_mask)
01817 {
01818         wmWindow *win= CTX_wm_window(C);
01819         int shift= win->eventstate->shift;
01820         unsigned int *cont_mask = arg2_mask;
01821         uiBut *but = arg1_but;
01822 
01823         if (*cont_mask == 0 || !(shift))
01824                 *cont_mask = (1<<but->retval);
01825         but->retval = B_REDR;
01826 }
01827 
01828 static void check_armature_actuator(bContext *C, void *arg1_but, void *arg2_act)
01829 {
01830         bArmatureActuator *act = arg2_act;
01831         uiBut *but = arg1_but;
01832         Object *ob= CTX_data_active_object(C);
01833 
01834         /* check that bone exist in the active object */
01835         but->retval = B_REDR;
01836         check_armature_bone_constraint(ob, act->posechannel, act->constraint);
01837 }
01838 
01839 
01840 static short draw_actuatorbuttons(Main *bmain, Object *ob, bActuator *act, uiBlock *block, short xco, short yco, short width)
01841 {
01842         bSoundActuator      *sa      = NULL;
01843         bObjectActuator     *oa      = NULL;
01844         bIpoActuator        *ia      = NULL;
01845         bPropertyActuator   *pa      = NULL;
01846         bCameraActuator     *ca      = NULL;
01847         bEditObjectActuator *eoa     = NULL;
01848         bConstraintActuator *coa     = NULL;
01849         bSceneActuator      *sca     = NULL;
01850         bGroupActuator      *ga      = NULL;
01851         bRandomActuator     *randAct = NULL;
01852         bMessageActuator    *ma      = NULL;
01853         bActionActuator     *aa      = NULL;
01854         bGameActuator       *gma     = NULL;
01855         bVisibilityActuator *visAct  = NULL;
01856         bTwoDFilterActuator     *tdfa    = NULL;
01857         bParentActuator     *parAct  = NULL;
01858         bStateActuator          *staAct  = NULL;
01859         bArmatureActuator   *armAct  = NULL;
01860         
01861         float *fp;
01862         short ysize = 0, wval;
01863         const char *str;
01864         int myline, stbit;
01865         uiBut *but;
01866 
01867 
01868         /* yco is at the top of the rect, draw downwards */
01869         set_col_actuator(act->type, 0);
01870         
01871         switch (act->type)
01872         {
01873         case ACT_OBJECT:
01874                 {
01875                         oa = act->data;
01876                         wval = (width-100)/3;
01877                         if (oa->type == ACT_OBJECT_NORMAL)
01878                         {
01879                                 if ( ob->gameflag & OB_DYNAMIC )
01880                                 {
01881                                         ysize= 175;
01882                                 }
01883                                 else
01884                                 {
01885                                         ysize= 72;
01886                                 }
01887 
01888                                 glRects(xco, yco-ysize, xco+width, yco);
01889                                 uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
01890                                 
01891                                 uiBlockBeginAlign(block);
01892                                 uiDefBut(block, LABEL, 0, "Loc",        xco, yco-45, 45, 19, NULL, 0, 0, 0, 0, "Sets the location");
01893                                 uiDefButF(block, NUM, 0, "",            xco+45, yco-45, wval, 19, oa->dloc, -10000.0, 10000.0, 10, 0, "");
01894                                 uiDefButF(block, NUM, 0, "",            xco+45+wval, yco-45, wval, 19, oa->dloc+1, -10000.0, 10000.0, 10, 0, "");
01895                                 uiDefButF(block, NUM, 0, "",            xco+45+2*wval, yco-45, wval, 19, oa->dloc+2, -10000.0, 10000.0, 10, 0, "");
01896                                 uiBlockEndAlign(block);
01897                                 
01898                                 uiDefBut(block, LABEL, 0, "Rot",        xco, yco-64, 45, 19, NULL, 0, 0, 0, 0, "Sets the rotation");
01899                                 uiBlockBeginAlign(block);
01900                                 uiDefButF(block, NUM, 0, "",            xco+45, yco-64, wval, 19, oa->drot, -10000.0, 10000.0, 10, 0, "");
01901                                 uiDefButF(block, NUM, 0, "",            xco+45+wval, yco-64, wval, 19, oa->drot+1, -10000.0, 10000.0, 10, 0, "");
01902                                 uiDefButF(block, NUM, 0, "",            xco+45+2*wval, yco-64, wval, 19, oa->drot+2, -10000.0, 10000.0, 10, 0, "");
01903                                 uiBlockEndAlign(block);
01904 
01905                                 uiDefButBitS(block, TOG, ACT_DLOC_LOCAL, 0, "L",                xco+45+3*wval, yco-45, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation");
01906                                 uiDefButBitS(block, TOG, ACT_DROT_LOCAL, 0, "L",                xco+45+3*wval, yco-64, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation");
01907         
01908                                 if ( ob->gameflag & OB_DYNAMIC )
01909                                 {
01910                                         uiDefBut(block, LABEL, 0, "Force",      xco, yco-87, 55, 19, NULL, 0, 0, 0, 0, "Sets the force");
01911                                         uiBlockBeginAlign(block);
01912                                         uiDefButF(block, NUM, 0, "",            xco+45, yco-87, wval, 19, oa->forceloc, -10000.0, 10000.0, 10, 0, "");
01913                                         uiDefButF(block, NUM, 0, "",            xco+45+wval, yco-87, wval, 19, oa->forceloc+1, -10000.0, 10000.0, 10, 0, "");
01914                                         uiDefButF(block, NUM, 0, "",            xco+45+2*wval, yco-87, wval, 19, oa->forceloc+2, -10000.0, 10000.0, 10, 0, "");
01915                                         uiBlockEndAlign(block);
01916 
01917                                         uiDefBut(block, LABEL, 0, "Torque", xco, yco-106, 55, 19, NULL, 0, 0, 0, 0, "Sets the torque");
01918                                         uiBlockBeginAlign(block);
01919                                         uiDefButF(block, NUM, 0, "",            xco+45, yco-106, wval, 19, oa->forcerot, -10000.0, 10000.0, 10, 0, "");
01920                                         uiDefButF(block, NUM, 0, "",            xco+45+wval, yco-106, wval, 19, oa->forcerot+1, -10000.0, 10000.0, 10, 0, "");
01921                                         uiDefButF(block, NUM, 0, "",            xco+45+2*wval, yco-106, wval, 19, oa->forcerot+2, -10000.0, 10000.0, 10, 0, "");                                
01922                                         uiBlockEndAlign(block);
01923                                 }
01924                                 
01925                                 if ( ob->gameflag & OB_DYNAMIC )
01926                                 {
01927                                         uiDefBut(block, LABEL, 0, "LinV",       xco, yco-129, 45, 19, NULL, 0, 0, 0, 0, "Sets the linear velocity");
01928                                         uiBlockBeginAlign(block);
01929                                         uiDefButF(block, NUM, 0, "",            xco+45, yco-129, wval, 19, oa->linearvelocity, -10000.0, 10000.0, 10, 0, "");
01930                                         uiDefButF(block, NUM, 0, "",            xco+45+wval, yco-129, wval, 19, oa->linearvelocity+1, -10000.0, 10000.0, 10, 0, "");
01931                                         uiDefButF(block, NUM, 0, "",            xco+45+2*wval, yco-129, wval, 19, oa->linearvelocity+2, -10000.0, 10000.0, 10, 0, "");
01932                                         uiBlockEndAlign(block);
01933                                 
01934                                         uiDefBut(block, LABEL, 0, "AngV",       xco, yco-148, 45, 19, NULL, 0, 0, 0, 0, "Sets the angular velocity");
01935                                         uiBlockBeginAlign(block);
01936                                         uiDefButF(block, NUM, 0, "",            xco+45, yco-148, wval, 19, oa->angularvelocity, -10000.0, 10000.0, 10, 0, "");
01937                                         uiDefButF(block, NUM, 0, "",            xco+45+wval, yco-148, wval, 19, oa->angularvelocity+1, -10000.0, 10000.0, 10, 0, "");
01938                                         uiDefButF(block, NUM, 0, "",            xco+45+2*wval, yco-148, wval, 19, oa->angularvelocity+2, -10000.0, 10000.0, 10, 0, "");
01939                                         uiBlockEndAlign(block);
01940                                 
01941                                         uiDefBut(block, LABEL, 0, "Damp",       xco, yco-171, 45, 19, NULL, 0, 0, 0, 0, "Number of frames to reach the target velocity");
01942                                         uiDefButS(block, NUM, 0, "",            xco+45, yco-171, wval, 19, &oa->damping, 0.0, 1000.0, 100, 0, "");
01943 
01944                                         uiDefButBitS(block, TOG, ACT_FORCE_LOCAL, 0, "L",               xco+45+3*wval, yco-87, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation");
01945                                         uiDefButBitS(block, TOG, ACT_TORQUE_LOCAL, 0, "L",              xco+45+3*wval, yco-106, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation");
01946                                         uiDefButBitS(block, TOG, ACT_LIN_VEL_LOCAL, 0, "L",             xco+45+3*wval, yco-129, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation");
01947                                         uiDefButBitS(block, TOG, ACT_ANG_VEL_LOCAL, 0, "L",             xco+45+3*wval, yco-148, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation");
01948                                 
01949                                         uiDefButBitS(block, TOG, ACT_ADD_LIN_VEL, 0, "use_additive",xco+45+3*wval+15, yco-129, 35, 19, &oa->flag, 0.0, 0.0, 0, 0, "Toggles between ADD and SET linV");
01950                                 }                               
01951                         } else if (oa->type == ACT_OBJECT_SERVO)
01952                         {
01953                                 ysize= 195;
01954                                 
01955                                 glRects(xco, yco-ysize, xco+width, yco);
01956                                 uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
01957                                 
01958                                 uiDefBut(block, LABEL, 0, "Ref",        xco, yco-45, 45, 19, NULL, 0, 0, 0, 0, "");
01959                                 uiDefIDPoinBut(block, test_obpoin_but, ID_OB, 1, "OB:",         xco+45, yco-45, wval*3, 19, &(oa->reference), "Reference object for velocity calculation, leave empty for world reference");
01960                                 uiDefBut(block, LABEL, 0, "linV",       xco, yco-68, 45, 19, NULL, 0, 0, 0, 0, "Sets the target relative linear velocity, it will be achieved by automatic application of force. Null velocity is a valid target");
01961                                 uiBlockBeginAlign(block);
01962                                 uiDefButF(block, NUM, 0, "",            xco+45, yco-68, wval, 19, oa->linearvelocity, -10000.0, 10000.0, 10, 0, "");
01963                                 uiDefButF(block, NUM, 0, "",            xco+45+wval, yco-68, wval, 19, oa->linearvelocity+1, -10000.0, 10000.0, 10, 0, "");
01964                                 uiDefButF(block, NUM, 0, "",            xco+45+2*wval, yco-68, wval, 19, oa->linearvelocity+2, -10000.0, 10000.0, 10, 0, "");
01965                                 uiBlockEndAlign(block);
01966                                 uiDefButBitS(block, TOG, ACT_LIN_VEL_LOCAL, 0, "L",             xco+45+3*wval, yco-68, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Velocity is defined in local coordinates");
01967 
01968                                 uiDefBut(block, LABEL, 0, "Limit",      xco, yco-91, 45, 19, NULL, 0, 0, 0, 0, "Select if the force needs to be limited along certain axis (local or global depending on LinV Local flag)");
01969                                 uiBlockBeginAlign(block);
01970                                 uiDefButBitS(block, TOG, ACT_SERVO_LIMIT_X, B_REDR, "X",                xco+45, yco-91, wval, 19, &oa->flag, 0.0, 0.0, 0, 0, "Set limit to force along the X axis");
01971                                 uiDefButBitS(block, TOG, ACT_SERVO_LIMIT_Y, B_REDR, "Y",                xco+45+wval, yco-91, wval, 19, &oa->flag, 0.0, 0.0, 0, 0, "Set limit to force along the Y axis");
01972                                 uiDefButBitS(block, TOG, ACT_SERVO_LIMIT_Z, B_REDR, "Z",                xco+45+2*wval, yco-91, wval, 19, &oa->flag, 0.0, 0.0, 0, 0, "Set limit to force along the Z axis");
01973                                 uiBlockEndAlign(block);
01974                                 uiDefBut(block, LABEL, 0, "Max",        xco, yco-110, 45, 19, NULL, 0, 0, 0, 0, "Set the upper limit for force");
01975                                 uiDefBut(block, LABEL, 0, "Min",        xco, yco-129, 45, 19, NULL, 0, 0, 0, 0, "Set the lower limit for force");
01976                                 if (oa->flag & ACT_SERVO_LIMIT_X) {
01977                                         uiDefButF(block, NUM, 0, "",            xco+45, yco-110, wval, 19, oa->dloc, -10000.0, 10000.0, 10, 0, "");
01978                                         uiDefButF(block, NUM, 0, "",            xco+45, yco-129, wval, 19, oa->drot, -10000.0, 10000.0, 10, 0, "");
01979                                 }
01980                                 if (oa->flag & ACT_SERVO_LIMIT_Y) {
01981                                         uiDefButF(block, NUM, 0, "",            xco+45+wval, yco-110, wval, 19, oa->dloc+1, -10000.0, 10000.0, 10, 0, "");
01982                                         uiDefButF(block, NUM, 0, "",            xco+45+wval, yco-129, wval, 19, oa->drot+1, -10000.0, 10000.0, 10, 0, "");
01983                                 }
01984                                 if (oa->flag & ACT_SERVO_LIMIT_Z) {
01985                                         uiDefButF(block, NUM, 0, "",            xco+45+2*wval, yco-110, wval, 19, oa->dloc+2, -10000.0, 10000.0, 10, 0, "");
01986                                         uiDefButF(block, NUM, 0, "",            xco+45+2*wval, yco-129, wval, 19, oa->drot+2, -10000.0, 10000.0, 10, 0, "");
01987                                 }
01988                                 uiDefBut(block, LABEL, 0, "Servo",      xco, yco-152, 45, 19, NULL, 0, 0, 0, 0, "Coefficients of the PID servo controller");
01989                                 uiDefButF(block, NUMSLI, B_REDR, "P: ",         xco+45, yco-152, wval*3, 19, oa->forcerot, 0.00, 200.0, 100, 0, "Proportional coefficient, typical value is 60x Integral coefficient");
01990                                 uiDefBut(block, LABEL, 0, "Slow",       xco, yco-171, 45, 19, NULL, 0, 0, 0, 0, "Low value of I coefficient correspond to slow response");
01991                                 but = uiDefButF(block, NUMSLI, B_REDR, " I : ",         xco+45, yco-171, wval*3, 19, oa->forcerot+1, 0.0, 3.0, 1, 0, "Integral coefficient, low value (0.01) for slow response, high value (0.5) for fast response");
01992                                 uiButSetFunc(but, update_object_actuator_PID, oa, NULL);
01993                                 uiDefBut(block, LABEL, 0, "Fast",       xco+45+3*wval, yco-171, 45, 19, NULL, 0, 0, 0, 0, "High value of I coefficient correspond to fast response");
01994                                 uiDefButF(block, NUMSLI, B_REDR, "D: ",         xco+45, yco-190, wval*3, 19, oa->forcerot+2, -100.0, 100.0, 100, 0, "Derivate coefficient, not required, high values can cause instability");
01995                         }
01996                         str= "Motion Type %t|Simple motion %x0|Servo Control %x1";
01997                         but = uiDefButS(block, MENU, B_REDR, str,               xco+40, yco-23, (width-80), 19, &oa->type, 0.0, 0.0, 0, 0, "");
01998                         oa->otype = oa->type;
01999                         uiButSetFunc(but, change_object_actuator, oa, NULL);
02000                         yco-= ysize;
02001                         break;
02002                 }
02003         case ACT_ACTION:
02004         case ACT_SHAPEACTION:
02005                 {
02006                         /* DrawAct */
02007 #ifdef __NLA_ACTION_BY_MOTION_ACTUATOR
02008                         ysize = 112;
02009 #else
02010                         ysize= 92;
02011 #endif
02012                         
02013                         glRects(xco, yco-ysize, xco+width, yco);
02014                         uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
02015                         
02016                         aa = act->data;
02017                         wval = (width-60)/3;
02018                         
02019                         //              str= "Action types   %t|Play %x0|Ping Pong %x1|Flipper %x2|Loop Stop %x3|Loop End %x4|Property %x6";
02020 #ifdef __NLA_ACTION_BY_MOTION_ACTUATOR
02021                         str= "Action types   %t|Play %x0|Flipper %x2|Loop Stop %x3|Loop End %x4|Property %x6|Displacement %x7";
02022 #else
02023                         str= "Action types   %t|Play %x0|Flipper %x2|Loop Stop %x3|Loop End %x4|Property %x6";
02024 #endif
02025                         uiDefButS(block, MENU, B_REDR, str, xco+10, yco-24, width/3, 19, &aa->type, 0.0, 0.0, 0.0, 0.0, "Action playback type");
02026                         uiDefIDPoinBut(block, test_actionpoin_but, ID_AC, 1, "AC: ", xco+10+ (width/3), yco-24, ((width/3)*2) - (20 + 60), 19, &aa->act, "Action name");
02027                         
02028                         uiDefButBitS(block, TOGN, 1, 0, "Continue", xco+((width/3)*2)+20, yco-24, 60, 19,
02029                                          &aa->end_reset, 0.0, 0.0, 0, 0, "Restore last frame when switching on/off, otherwise play from the start each time");
02030                         
02031                         
02032                         if(aa->type == ACT_ACTION_FROM_PROP)
02033                         {
02034                                 uiDefBut(block, TEX, 0, "Prop: ",xco+10, yco-44, width-20, 19, aa->name, 0.0, 31.0, 0, 0, "Use this property to define the Action position");
02035                         }
02036                         else
02037                         {
02038                                 uiDefButF(block, NUM, 0, "Sta: ",xco+10, yco-44, (width-20)/2, 19, &aa->sta, 1.0, MAXFRAMEF, 0, 0, "Start frame");
02039                                 uiDefButF(block, NUM, 0, "End: ",xco+10+(width-20)/2, yco-44, (width-20)/2, 19, &aa->end, 1.0, MAXFRAMEF, 0, 0, "End frame");
02040                         }
02041                                                 
02042                         uiDefButS(block, NUM, 0, "Blendin: ", xco+10, yco-64, (width-20)/2, 19, &aa->blendin, 0.0, 32767, 0.0, 0.0, "Number of frames of motion blending");
02043                         uiDefButS(block, NUM, 0, "Priority: ", xco+10+(width-20)/2, yco-64, (width-20)/2, 19, &aa->priority, 0.0, 100.0, 0.0, 0.0, "Execution priority - lower numbers will override actions with higher numbers, With 2 or more actions at once, the overriding channels must be lower in the stack");
02044                         
02045                         uiDefBut(block, TEX, 0, "FrameProp: ",xco+10, yco-84, width-20, 19, aa->frameProp, 0.0, 31.0, 0, 0, "Assign the action's current frame number to this property");
02046 
02047                         
02048 #ifdef __NLA_ACTION_BY_MOTION_ACTUATOR
02049                         if(aa->type == ACT_ACTION_MOTION)
02050                         {
02051                                 uiDefButF(block, NUM, 0, "Cycle: ",xco+30, yco-84, (width-60)/2, 19, &aa->stridelength, 0.0, 2500.0, 0, 0, "Distance covered by a single cycle of the action");
02052                         }
02053 #endif
02054                         
02055                         
02056                         
02057                         yco-=ysize;
02058                         break;
02059                 }
02060         case ACT_IPO:
02061                 {
02062                         ia= act->data;
02063                         
02064                         ysize= 72;
02065                         
02066                         glRects(xco, yco-ysize, xco+width, yco);
02067                         uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
02068                         
02069                         str = "Ipo types   %t|Play %x0|Ping Pong %x1|Flipper %x2|Loop Stop %x3|Loop End %x4|Property %x6";
02070                         
02071                         uiDefButS(block, MENU, B_REDR, str,             xco+10, yco-24, (width-20)/2, 19, &ia->type, 0, 0, 0, 0, "");
02072 
02073                         but = uiDefButBitS(block, TOG, ACT_IPOFORCE, ACT_IPOFORCE, 
02074                                 "Force", xco+10+(width-20)/2, yco-24, (width-20)/4-10, 19, 
02075                                 &ia->flag, 0, 0, 0, 0, 
02076                                 "Apply Ipo as a global or local force depending on the local option (dynamic objects only)"); 
02077                         uiButSetFunc(but, change_ipo_actuator, but, ia);
02078 
02079                         but = uiDefButBitS(block, TOG, ACT_IPOADD, ACT_IPOADD, 
02080                                 "Add", xco+3*(width-20)/4, yco-24, (width-20)/4-10, 19, 
02081                                 &ia->flag, 0, 0, 0, 0, 
02082                                 "Ipo is added to the current loc/rot/scale in global or local coordinate according to Local flag"); 
02083                         uiButSetFunc(but, change_ipo_actuator, but, ia);
02084                         
02085                         /* Only show the do-force-local toggle if force is requested */
02086                         if (ia->flag & (ACT_IPOFORCE|ACT_IPOADD)) {
02087                                 uiDefButBitS(block, TOG, ACT_IPOLOCAL, 0, 
02088                                         "L", xco+width-30, yco-24, 20, 19, 
02089                                         &ia->flag, 0, 0, 0, 0, 
02090                                         "Let the ipo acts in local coordinates, used in Force and Add mode"); 
02091                         }
02092 
02093                         if(ia->type==ACT_IPO_FROM_PROP) {
02094                                 uiDefBut(block, TEX, 0, 
02095                                         "Prop: ",               xco+10, yco-44, width-80, 19, 
02096                                         ia->name, 0.0, 31.0, 0, 0, 
02097                                         "Use this property to define the Ipo position");
02098                         }
02099                         else {
02100                                 uiDefButF(block, NUM, 0, 
02101                                         "Sta",          xco+10, yco-44, (width-80)/2, 19, 
02102                                         &ia->sta, 1.0, MAXFRAMEF, 0, 0, 
02103                                         "Start frame");
02104                                 uiDefButF(block, NUM, 0, 
02105                                         "End",          xco+10+(width-80)/2, yco-44, (width-80)/2, 19, 
02106                                         &ia->end, 1.0, MAXFRAMEF, 0, 0, 
02107                                         "End frame");
02108                         }
02109                         uiDefButBitS(block, TOG, ACT_IPOCHILD,  B_REDR, 
02110                                 "Child",        xco+10+(width-80), yco-44, 60, 19, 
02111                                 &ia->flag, 0, 0, 0, 0, 
02112                                 "Update IPO on all children Objects as well");
02113                         uiDefBut(block, TEX, 0, 
02114                                 "FrameProp: ",          xco+10, yco-64, width-20, 19, 
02115                                 ia->frameProp, 0.0, 31.0, 0, 0, 
02116                                 "Assign the action's current frame number to this property");
02117 
02118                         yco-= ysize;
02119                         break;
02120                 }
02121         case ACT_PROPERTY:
02122                 {
02123                         ysize= 68;
02124                         
02125                         glRects(xco, yco-ysize, xco+width, yco);
02126                         uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
02127                         
02128                         pa= act->data;
02129                         
02130                         str= "Type%t|Assign%x0|Add %x1|Copy %x2|Toggle (bool/int/float/timer)%x3";
02131                         uiDefButI(block, MENU, B_REDR, str,             xco+30,yco-24,width-60, 19, &pa->type, 0, 31, 0, 0, "Type");
02132                         
02133                         uiDefBut(block, TEX, 1, "Prop: ",               xco+30,yco-44,width-60, 19, pa->name, 0, 31, 0, 0, "Property name");
02134                         
02135                         
02136                         if(pa->type==ACT_PROP_TOGGLE) {
02137                                 /* no ui */
02138                                 ysize -= 22;
02139                         }
02140                         else if(pa->type==ACT_PROP_COPY) {
02141                                 uiDefIDPoinBut(block, test_obpoin_but, ID_OB, 1, "OB:", xco+10, yco-64, (width-20)/2, 19, &(pa->ob), "Copy from this Object");
02142                                 uiDefBut(block, TEX, 1, "Prop: ",               xco+10+(width-20)/2, yco-64, (width-20)/2, 19, pa->value, 0, 31, 0, 0, "Copy this property");
02143                         }
02144                         else {
02145                                 uiDefBut(block, TEX, 1, "Value: ",              xco+30,yco-64,width-60, 19, pa->value, 0, 31, 0, 0, "change with this value, use \"\" around strings");
02146                         }
02147                         yco-= ysize;
02148                         
02149                         break;
02150                 }
02151         case ACT_SOUND:
02152                 {
02153                         sa = act->data;
02154                         sa->sndnr = 0;
02155                         
02156                         if(sa->flag & ACT_SND_3D_SOUND)
02157                                 ysize = 180;
02158                         else
02159                                 ysize = 92;
02160 
02161                         wval = (width-20)/2;
02162                         glRects(xco, yco-ysize, xco+width, yco);
02163                         uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
02164                         
02165                         if(bmain->sound.first) {
02166                                 IDnames_to_pupstring(&str, "Sound files", NULL, &(bmain->sound), (ID *)sa->sound, &(sa->sndnr));
02167                                 /* reset this value, it is for handling the event */
02168                                 sa->sndnr = 0;
02169                                 uiDefButS(block, MENU, B_SOUNDACT_BROWSE, str, xco+10,yco-22,20,19, &(sa->sndnr), 0, 0, 0, 0, "");      
02170                                 uiDefButO(block, BUT, "sound.open", 0, "Load Sound", xco+wval+10, yco-22, wval, 19, "Load a sound file. Remember to set caching on for small sounds that are played often.");
02171 
02172                                 if(sa->sound) {
02173                                         char dummy_str[] = "Sound mode %t|Play Stop %x0|Play End %x1|Loop Stop %x2|Loop End %x3|Loop Ping Pong Stop %x5|Loop Ping Pong %x4";
02174                                         uiDefBut(block, TEX, B_IDNAME, "SO:",xco+30,yco-22,wval-20,19, ((ID *)sa->sound)->name+2,    0.0, 21.0, 0, 0, "");
02175                                         uiDefButS(block, MENU, 1, dummy_str,xco+10,yco-44,width-20, 19, &sa->type, 0.0, 0.0, 0, 0, "");
02176                                         uiDefButF(block, NUM, 0, "Volume:", xco+10,yco-66,wval, 19, &sa->volume, 0.0,  1.0, 0, 0, "Sets the volume of this sound");
02177                                         uiDefButF(block, NUM, 0, "Pitch:",xco+wval+10,yco-66,wval, 19, &sa->pitch,-12.0, 12.0, 0, 0, "Sets the pitch of this sound");
02178                                         uiDefButS(block, TOG | BIT, 0, "3D Sound", xco+10, yco-88, width-20, 19, &sa->flag, 0.0, 1.0, 0.0, 0.0, "Plays the sound positioned in 3D space.");
02179                                         if(sa->flag & ACT_SND_3D_SOUND)
02180                                         {
02181                                                 uiDefButF(block, NUM, 0, "Minimum Gain: ", xco+10, yco-110, wval, 19, &sa->sound3D.min_gain, 0.0, 1.0, 0.0, 0.0, "The minimum gain of the sound, no matter how far it is away.");
02182                                                 uiDefButF(block, NUM, 0, "Maximum Gain: ", xco+10, yco-132, wval, 19, &sa->sound3D.max_gain, 0.0, 1.0, 0.0, 0.0, "The maximum gain of the sound, no matter how near it is.");
02183                                                 uiDefButF(block, NUM, 0, "Reference Distance: ", xco+10, yco-154, wval, 19, &sa->sound3D.reference_distance, 0.0, FLT_MAX, 0.0, 0.0, "The reference distance is the distance where the sound has a gain of 1.0.");
02184                                                 uiDefButF(block, NUM, 0, "Maximum Distance: ", xco+10, yco-176, wval, 19, &sa->sound3D.max_distance, 0.0, FLT_MAX, 0.0, 0.0, "The maximum distance at which you can hear the sound.");
02185                                                 uiDefButF(block, NUM, 0, "Rolloff: ", xco+wval+10, yco-110, wval, 19, &sa->sound3D.rolloff_factor, 0.0, 5.0, 0.0, 0.0, "The rolloff factor defines the influence factor on volume depending on distance.");
02186                                                 uiDefButF(block, NUM, 0, "Cone Outer Gain: ", xco+wval+10, yco-132, wval, 19, &sa->sound3D.cone_outer_gain, 0.0, 1.0, 0.0, 0.0, "The gain outside the outer cone. The gain in the outer cone will be interpolated between this value and the normal gain in the inner cone.");
02187                                                 uiDefButF(block, NUM, 0, "Cone Outer Angle: ", xco+wval+10, yco-154, wval, 19, &sa->sound3D.cone_outer_angle, 0.0, 360.0, 0.0, 0.0, "The angle of the outer cone.");
02188                                                 uiDefButF(block, NUM, 0, "Cone Inner Angle: ", xco+wval+10, yco-176, wval, 19, &sa->sound3D.cone_inner_angle, 0.0, 360.0, 0.0, 0.0, "The angle of the inner cone.");
02189                                         }
02190                                 }
02191                                 MEM_freeN((void *)str);
02192                         } 
02193                         else {
02194                                 uiDefButO(block, BUT, "sound.open", 0, "Load Sound", xco+10, yco-22, width-20, 19, "Load a sound file.");
02195                         }
02196                                         
02197                         yco-= ysize;
02198                         
02199                         break;
02200                 }
02201         case ACT_CAMERA:
02202 
02203                 ysize= 48;
02204 
02205                 glRects(xco, yco-ysize, xco+width, yco);
02206                 uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
02207                 
02208                 ca= act->data;
02209 
02210                 uiDefIDPoinBut(block, test_obpoin_but, ID_OB, 1, "OB:",         xco+10, yco-24, (width-20)/2, 19, &(ca->ob), "Look at this Object");
02211                 uiDefButF(block, NUM, 0, "Height:",     xco+10+(width-20)/2, yco-24, (width-20)/2, 19, &ca->height, 0.0, 20.0, 0, 0, "");
02212                 
02213                 uiDefButF(block, NUM, 0, "Min:",        xco+10, yco-44, (width-60)/2, 19, &ca->min, 0.0, 20.0, 0, 0, "");
02214                 
02215                 if(ca->axis==0) ca->axis= 'x';
02216                 uiDefButS(block, ROW, 0, "X",   xco+10+(width-60)/2, yco-44, 20, 19, &ca->axis, 4.0, (float)'x', 0, 0, "Camera tries to get behind the X axis");
02217                 uiDefButS(block, ROW, 0, "Y",   xco+30+(width-60)/2, yco-44, 20, 19, &ca->axis, 4.0, (float)'y', 0, 0, "Camera tries to get behind the Y axis");
02218                 
02219                 uiDefButF(block, NUM, 0, "Max:",        xco+20+(width)/2, yco-44, (width-60)/2, 19, &ca->max, 0.0, 20.0, 0, 0, "");
02220 
02221                 yco-= ysize;
02222 
02223                 break;
02224 
02225         case ACT_EDIT_OBJECT:
02226                 
02227                 eoa= act->data;
02228 
02229                 if(eoa->type==ACT_EDOB_ADD_OBJECT) {
02230                         ysize = 92;
02231                         glRects(xco, yco-ysize, xco+width, yco);
02232                         uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
02233 
02234                         uiDefIDPoinBut(block, test_obpoin_but, ID_OB, 1, "OB:",         xco+10, yco-44, (width-20)/2, 19, &(eoa->ob), "Add this Object and all its children (cant be on an visible layer)");
02235                         uiDefButI(block, NUM, 0, "Time:",       xco+10+(width-20)/2, yco-44, (width-20)/2, 19, &eoa->time, 0.0, 2000.0, 0, 0, "Duration the new Object lives");
02236 
02237                         wval= (width-60)/3;
02238                         uiDefBut(block, LABEL, 0, "linV",       xco,           yco-68,   45, 19,
02239                                          NULL, 0, 0, 0, 0,
02240                                          "Velocity upon creation");
02241                         uiDefButF(block, NUM, 0, "",            xco+45,        yco-68, wval, 19,
02242                                          eoa->linVelocity, -100.0, 100.0, 10, 0,
02243                                          "Velocity upon creation, x component");
02244                         uiDefButF(block, NUM, 0, "",            xco+45+wval,   yco-68, wval, 19,
02245                                          eoa->linVelocity+1, -100.0, 100.0, 10, 0,
02246                                          "Velocity upon creation, y component");
02247                         uiDefButF(block, NUM, 0, "",            xco+45+2*wval, yco-68, wval, 19,
02248                                          eoa->linVelocity+2, -100.0, 100.0, 10, 0,
02249                                          "Velocity upon creation, z component");
02250                         uiDefButBitS(block, TOG, ACT_EDOB_LOCAL_LINV, 0, "L", xco+45+3*wval, yco-68, 15, 19,
02251                                          &eoa->localflag, 0.0, 0.0, 0, 0,
02252                                          "Apply the transformation locally");
02253                         
02254                         
02255                         uiDefBut(block, LABEL, 0, "AngV",       xco,           yco-90,   45, 19,
02256                                          NULL, 0, 0, 0, 0,
02257                                          "Angular velocity upon creation");
02258                         uiDefButF(block, NUM, 0, "",            xco+45,        yco-90, wval, 19,
02259                                          eoa->angVelocity, -10000.0, 10000.0, 10, 0,
02260                                          "Angular velocity upon creation, x component");
02261                         uiDefButF(block, NUM, 0, "",            xco+45+wval,   yco-90, wval, 19,
02262                                          eoa->angVelocity+1, -10000.0, 10000.0, 10, 0,
02263                                          "Angular velocity upon creation, y component");
02264                         uiDefButF(block, NUM, 0, "",            xco+45+2*wval, yco-90, wval, 19,
02265                                          eoa->angVelocity+2, -10000.0, 10000.0, 10, 0,
02266                                          "Angular velocity upon creation, z component");
02267                         uiDefButBitS(block, TOG, ACT_EDOB_LOCAL_ANGV, 0, "L", xco+45+3*wval, yco-90, 15, 19,
02268                                          &eoa->localflag, 0.0, 0.0, 0, 0,
02269                                          "Apply the rotation locally");
02270                                          
02271 
02272                 }
02273                 else if(eoa->type==ACT_EDOB_END_OBJECT) {
02274                         ysize= 28;
02275                         glRects(xco, yco-ysize, xco+width, yco);
02276                         uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
02277                 }
02278                 else if(eoa->type==ACT_EDOB_REPLACE_MESH) {
02279                         ysize= 48;
02280                         glRects(xco, yco-ysize, xco+width, yco);
02281                         uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
02282          
02283                         uiDefIDPoinBut(block, test_meshpoin_but, ID_ME, 1, "ME:",               xco+40, yco-44, (width-80)/2, 19, &(eoa->me), "replace the existing, when left blank 'Phys' will remake the existing physics mesh");
02284                         
02285                         uiDefButBitS(block, TOGN, ACT_EDOB_REPLACE_MESH_NOGFX, 0, "Gfx",        xco+40 + (width-80)/2, yco-44, (width-80)/4, 19, &eoa->flag, 0, 0, 0, 0, "Replace the display mesh");
02286                         uiDefButBitS(block, TOG, ACT_EDOB_REPLACE_MESH_PHYS, 0, "Phys", xco+40 + (width-80)/2 +(width-80)/4, yco-44, (width-80)/4, 19, &eoa->flag, 0, 0, 0, 0, "Replace the physics mesh (triangle bounds only. compound shapes not supported)");
02287                 }
02288                 else if(eoa->type==ACT_EDOB_TRACK_TO) {
02289                         ysize= 48;
02290                         glRects(xco, yco-ysize, xco+width, yco);
02291                         uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
02292          
02293                         uiDefIDPoinBut(block, test_obpoin_but, ID_OB, 1, "OB:",         xco+10, yco-44, (width-20)/2, 19, &(eoa->ob), "Track to this Object");
02294                         uiDefButI(block, NUM, 0, "Time:",       xco+10+(width-20)/2, yco-44, (width-20)/2-40, 19, &eoa->time, 0.0, 2000.0, 0, 0, "Duration the tracking takes");
02295                         uiDefButS(block, TOG, 0, "3D",  xco+width-50, yco-44, 40, 19, &eoa->flag, 0.0, 0.0, 0, 0, "Enable 3D tracking");
02296                 }
02297                 else if(eoa->type==ACT_EDOB_DYNAMICS) {
02298                         ysize= 69;
02299                         glRects(xco, yco-ysize, xco+width, yco);
02300                         uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
02301                         
02302                         str= "Dynamic Operation %t|Restore Dynamics %x0|Suspend Dynamics %x1|Enable Rigid Body %x2|Disable Rigid Body %x3|Set Mass %x4";
02303                         uiDefButS(block, MENU, B_REDR, str,             xco+40, yco-44, (width-80), 19,  &(eoa->dyn_operation), 0.0, 0.0, 0, 0, "");
02304                         if(eoa->dyn_operation==4) {
02305                                 uiDefButF(block, NUM, 0, "",            xco+40, yco-63, width-80, 19,
02306                                          &eoa->mass, 0.0, 10000.0, 10, 0,
02307                                          "Mass for object");
02308                         }
02309                 }
02310                 str= "Edit Object %t|Add Object %x0|End Object %x1|Replace Mesh %x2|Track to %x3|Dynamics %x4";
02311                 uiDefButS(block, MENU, B_REDR, str,             xco+40, yco-24, (width-80), 19, &eoa->type, 0.0, 0.0, 0, 0, "");
02312 
02313                  yco-= ysize;
02314 
02315                 break;
02316 
02317         case ACT_CONSTRAINT:
02318                 coa= act->data;
02319         
02320                 if (coa->type == ACT_CONST_TYPE_LOC) {
02321                         ysize= 69;
02322 
02323                         glRects(xco, yco-ysize, xco+width, yco);
02324                         uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
02325                         
02326         /*              str= "Limit %t|None %x0|Loc X %x1|Loc Y %x2|Loc Z %x4|Rot X %x8|Rot Y %x16|Rot Z %x32"; */
02327         /*                      coa->flag &= ~(63); */
02328                         str= "Limit %t|None %x0|Loc X %x1|Loc Y %x2|Loc Z %x4";
02329                         coa->flag &= 7;
02330                         coa->time = 0;
02331                         uiDefButS(block, MENU, 1, str,          xco+10, yco-65, 70, 19, &coa->flag, 0.0, 0.0, 0, 0, "");
02332                 
02333                         uiDefButS(block, NUM,           0, "damp",      xco+10, yco-45, 70, 19, &coa->damp, 0.0, 100.0, 0, 0, "Damping factor: time constant (in frame) of low pass filter");
02334                         uiDefBut(block, LABEL,                  0, "Min",       xco+80, yco-45, (width-90)/2, 19, NULL, 0.0, 0.0, 0, 0, "");
02335                         uiDefBut(block, LABEL,                  0, "Max",       xco+80+(width-90)/2, yco-45, (width-90)/2, 19, NULL, 0.0, 0.0, 0, 0, "");
02336 
02337                         if(coa->flag & ACT_CONST_LOCX) fp= coa->minloc;
02338                         else if(coa->flag & ACT_CONST_LOCY) fp= coa->minloc+1;
02339                         else if(coa->flag & ACT_CONST_LOCZ) fp= coa->minloc+2;
02340                         else if(coa->flag & ACT_CONST_ROTX) fp= coa->minrot;
02341                         else if(coa->flag & ACT_CONST_ROTY) fp= coa->minrot+1;
02342                         else fp= coa->minrot+2;
02343                         
02344                         uiDefButF(block, NUM, 0, "",            xco+80, yco-65, (width-90)/2, 19, fp, -2000.0, 2000.0, 10, 0, "");
02345                         uiDefButF(block, NUM, 0, "",            xco+80+(width-90)/2, yco-65, (width-90)/2, 19, fp+3, -2000.0, 2000.0, 10, 0, "");
02346                 } else if (coa->type == ACT_CONST_TYPE_DIST) {
02347                         ysize= 106;
02348 
02349                         glRects(xco, yco-ysize, xco+width, yco);
02350                         uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
02351                         
02352                         str= "Direction %t|None %x0|X axis %x1|Y axis %x2|Z axis %x4|-X axis %x8|-Y axis %x16|-Z axis %x32";
02353                         uiDefButS(block, MENU, B_REDR, str,             xco+10, yco-65, 70, 19, &coa->mode, 0.0, 0.0, 0, 0, "Set the direction of the ray");
02354                 
02355                         uiDefButS(block, NUM,           0, "damp",      xco+10, yco-45, 70, 19, &coa->damp, 0.0, 100.0, 0, 0, "Damping factor: time constant (in frame) of low pass filter");
02356                         uiDefBut(block, LABEL,                  0, "Range",     xco+80, yco-45, (width-115)/2, 19, NULL, 0.0, 0.0, 0, 0, "Set the maximum length of ray");
02357                         uiDefButBitS(block, TOG, ACT_CONST_DISTANCE, B_REDR, "Dist",    xco+80+(width-115)/2, yco-45, (width-115)/2, 19, &coa->flag, 0.0, 0.0, 0, 0, "Force distance of object to point of impact of ray");
02358                         uiDefButBitS(block, TOG, ACT_CONST_LOCAL, 0, "L", xco+80+(width-115), yco-45, 25, 19,
02359                                          &coa->flag, 0.0, 0.0, 0, 0, "Set ray along object's axis or global axis");
02360 
02361                         if(coa->mode & (ACT_CONST_DIRPX|ACT_CONST_DIRNX)) fp= coa->minloc;
02362                         else if(coa->mode & (ACT_CONST_DIRPY|ACT_CONST_DIRNY)) fp= coa->minloc+1;
02363                         else fp= coa->minloc+2;
02364 
02365                         uiDefButF(block, NUM, 0, "",            xco+80, yco-65, (width-115)/2, 19, fp+3, 0.0, 2000.0, 10, 0, "Maximum length of ray");
02366                         if (coa->flag & ACT_CONST_DISTANCE)
02367                                 uiDefButF(block, NUM, 0, "",            xco+80+(width-115)/2, yco-65, (width-115)/2, 19, fp, -2000.0, 2000.0, 10, 0, "Keep this distance to target");
02368                         uiDefButBitS(block, TOG, ACT_CONST_NORMAL, 0, "N", xco+80+(width-115), yco-65, 25, 19,
02369                                          &coa->flag, 0.0, 0.0, 0, 0, "Set object axis along (local axis) or parallel (global axis) to the normal at hit position");
02370                         uiDefButBitS(block, TOG, ACT_CONST_MATERIAL, B_REDR, "M/P", xco+10, yco-84, 40, 19,
02371                                          &coa->flag, 0.0, 0.0, 0, 0, "Detect material instead of property");
02372                         if (coa->flag & ACT_CONST_MATERIAL)
02373                         {
02374                                 uiDefBut(block, TEX, 1, "Material:", xco + 50, yco-84, (width-60), 19,
02375                                         coa->matprop, 0, 31, 0, 0,
02376                                         "Ray detects only Objects with this material");
02377                         }
02378                         else
02379                         {
02380                                 uiDefBut(block, TEX, 1, "Property:", xco + 50, yco-84, (width-60), 19,
02381                                         coa->matprop, 0, 31, 0, 0,
02382                                         "Ray detect only Objects with this property");
02383                         }
02384                         uiDefButBitS(block, TOG, ACT_CONST_PERMANENT, 0, "PER", xco+10, yco-103, 40, 19,
02385                                 &coa->flag, 0.0, 0.0, 0, 0, "Persistent actuator: stays active even if ray does not reach target");
02386                         uiDefButS(block, NUM, 0, "time", xco+50, yco-103, (width-60)/2, 19, &(coa->time), 0.0, 1000.0, 0, 0, "Maximum activation time in frame, 0 for unlimited");
02387                         uiDefButS(block, NUM, 0, "rotDamp", xco+50+(width-60)/2, yco-103, (width-60)/2, 19, &(coa->rotdamp), 0.0, 100.0, 0, 0, "Use a different damping for orientation");
02388                 } else if (coa->type == ACT_CONST_TYPE_ORI) {
02389                         ysize= 87;
02390 
02391                         glRects(xco, yco-ysize, xco+width, yco);
02392                         uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
02393                         
02394                         str= "Direction %t|None %x0|X axis %x1|Y axis %x2|Z axis %x4";
02395                         uiDefButS(block, MENU, B_REDR, str,             xco+10, yco-65, 70, 19, &coa->mode, 0.0, 0.0, 0, 0, "Select the axis to be aligned along the reference direction");
02396                 
02397                         uiDefButS(block, NUM,           0, "damp",      xco+10, yco-45, 70, 19, &coa->damp, 0.0, 100.0, 0, 0, "Damping factor: time constant (in frame) of low pass filter");
02398                         uiDefBut(block, LABEL,                  0, "X", xco+80, yco-45, (width-115)/3, 19, NULL, 0.0, 0.0, 0, 0, "");
02399                         uiDefBut(block, LABEL,                  0, "Y", xco+80+(width-115)/3, yco-45, (width-115)/3, 19, NULL, 0.0, 0.0, 0, 0, "");
02400                         uiDefBut(block, LABEL,                  0, "Z", xco+80+2*(width-115)/3, yco-45, (width-115)/3, 19, NULL, 0.0, 0.0, 0, 0, "");
02401 
02402                         uiDefButF(block, NUM, 0, "",            xco+80, yco-65, (width-115)/3, 19, &coa->maxrot[0], -2000.0, 2000.0, 10, 0, "X component of reference direction");
02403                         uiDefButF(block, NUM, 0, "",            xco+80+(width-115)/3, yco-65, (width-115)/3, 19, &coa->maxrot[1], -2000.0, 2000.0, 10, 0, "Y component of reference direction");
02404                         uiDefButF(block, NUM, 0, "",            xco+80+2*(width-115)/3, yco-65, (width-115)/3, 19, &coa->maxrot[2], -2000.0, 2000.0, 10, 0, "Z component of reference direction");
02405 
02406                         uiDefButS(block, NUM, 0, "time", xco+10, yco-84, 70, 19, &(coa->time), 0.0, 1000.0, 0, 0, "Maximum activation time in frame, 0 for unlimited");
02407                         uiDefButF(block, NUM, 0, "min", xco+80, yco-84, (width-115)/2, 19, &(coa->minloc[0]), 0.0, 180.0, 10, 1, "Minimum angle (in degree) to maintain with target direction. No correction is done if angle with target direction is between min and max");
02408                         uiDefButF(block, NUM, 0, "max", xco+80+(width-115)/2, yco-84, (width-115)/2, 19, &(coa->maxloc[0]), 0.0, 180.0, 10, 1, "Maximum angle (in degree) allowed with target direction. No correction is done if angle with target direction is between min and max");
02409                 } else if (coa->type == ACT_CONST_TYPE_FH) {
02410                         ysize= 106;
02411 
02412                         glRects(xco, yco-ysize, xco+width, yco);
02413                         uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
02414                         
02415                         str= "Direction %t|None %x0|X axis %x1|Y axis %x2|Z axis %x4|-X axis %x8|-Y axis %x16|-Z axis %x32";
02416                         uiDefButS(block, MENU, B_REDR, str,             xco+10, yco-65, 70, 19, &coa->mode, 0.0, 0.0, 0, 0, "Set the direction of the ray (in world coordinate)");
02417 
02418                         if(coa->mode & (ACT_CONST_DIRPX|ACT_CONST_DIRNX)) fp= coa->minloc;
02419                         else if(coa->mode & (ACT_CONST_DIRPY|ACT_CONST_DIRNY)) fp= coa->minloc+1;
02420                         else fp= coa->minloc+2;
02421 
02422                         uiDefButF(block, NUM,           0, "damp",      xco+10, yco-45, (width-70)/2, 19, &coa->maxrot[0], 0.0, 1.0, 1, 0, "Damping factor of the Fh spring force");
02423                         uiDefButF(block, NUM,           0, "dist",      xco+10+(width-70)/2, yco-45, (width-70)/2, 19, fp, 0.010, 2000.0, 10, 0, "Height of the Fh area");
02424                         uiDefButBitS(block, TOG, ACT_CONST_DOROTFH, 0, "Rot Fh",        xco+10+(width-70), yco-45, 50, 19, &coa->flag, 0.0, 0.0, 0, 0, "Keep object axis parallel to normal");
02425 
02426                         uiDefButF(block, NUMSLI, 0, "Fh ",              xco+80, yco-65, (width-115), 19, fp+3, 0.0, 1.0, 0, 0, "Spring force within the Fh area");
02427                         uiDefButBitS(block, TOG, ACT_CONST_NORMAL, 0, "N", xco+80+(width-115), yco-65, 25, 19,
02428                                          &coa->flag, 0.0, 0.0, 0, 0, "Add a horizontal spring force on slopes");
02429                         uiDefButBitS(block, TOG, ACT_CONST_MATERIAL, B_REDR, "M/P", xco+10, yco-84, 40, 19,
02430                                          &coa->flag, 0.0, 0.0, 0, 0, "Detect material instead of property");
02431                         if (coa->flag & ACT_CONST_MATERIAL)
02432                         {
02433                                 uiDefBut(block, TEX, 1, "Material:", xco + 50, yco-84, (width-60), 19,
02434                                         coa->matprop, 0, 31, 0, 0,
02435                                         "Ray detects only Objects with this material");
02436                         }
02437                         else
02438                         {
02439                                 uiDefBut(block, TEX, 1, "Property:", xco + 50, yco-84, (width-60), 19,
02440                                         coa->matprop, 0, 31, 0, 0,
02441                                         "Ray detect only Objects with this property");
02442                         }
02443                         uiDefButBitS(block, TOG, ACT_CONST_PERMANENT, 0, "PER", xco+10, yco-103, 40, 19,
02444                                 &coa->flag, 0.0, 0.0, 0, 0, "Persistent actuator: stays active even if ray does not reach target");
02445                         uiDefButS(block, NUM, 0, "time", xco+50, yco-103, 90, 19, &(coa->time), 0.0, 1000.0, 0, 0, "Maximum activation time in frame, 0 for unlimited");
02446                         uiDefButF(block, NUM, 0, "rotDamp", xco+140, yco-103, (width-150), 19, &coa->maxrot[1], 0.0, 1.0, 1, 0, "Use a different damping for rotation");
02447                 }
02448                 str= "Constraint Type %t|Location %x0|Distance %x1|Orientation %x2|Force field %x3";
02449                 but = uiDefButS(block, MENU, B_REDR, str,               xco+40, yco-23, (width-80), 19, &coa->type, 0.0, 0.0, 0, 0, "");
02450                  yco-= ysize;
02451                 break;
02452  
02453         case ACT_SCENE:
02454                 sca= act->data;
02455                 
02456                 if(sca->type==ACT_SCENE_RESTART) {
02457                         ysize= 28;
02458                         glRects(xco, yco-ysize, xco+width, yco);
02459                         uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
02460                 }
02461                 else if(sca->type==ACT_SCENE_CAMERA) {
02462 
02463                         ysize= 48;
02464                         glRects(xco, yco-ysize, xco+width, yco);
02465                         uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
02466 
02467                         uiDefIDPoinBut(block, test_obpoin_but, ID_OB, 1, "OB:",         xco+40, yco-44, (width-80), 19, &(sca->camera), "Set this Camera. Leave empty to refer to self object");
02468                 }
02469                 else if(sca->type==ACT_SCENE_SET) {
02470                         
02471                         ysize= 48;
02472                         glRects(xco, yco-ysize, xco+width, yco);
02473                         uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
02474 
02475                         uiDefIDPoinBut(block, test_scenepoin_but, ID_SCE, 1, "SCE:",            xco+40, yco-44, (width-80), 19, &(sca->scene), "Set this Scene");
02476                 }
02477                 else if(sca->type==ACT_SCENE_ADD_FRONT) { 
02478                         
02479                         ysize= 48;
02480                         glRects(xco, yco-ysize, xco+width, yco);
02481                         uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
02482 
02483                         uiDefIDPoinBut(block, test_scenepoin_but, ID_SCE, 1, "SCE:",            xco+40, yco-44, (width-80), 19, &(sca->scene), "Add an Overlay Scene");
02484                 }
02485                 else if(sca->type==ACT_SCENE_ADD_BACK) { 
02486                         
02487                         ysize= 48;
02488                         glRects(xco, yco-ysize, xco+width, yco);
02489                         uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
02490 
02491                         uiDefIDPoinBut(block, test_scenepoin_but, ID_SCE, 1, "SCE:",            xco+40, yco-44, (width-80), 19, &(sca->scene), "Add a Background Scene");
02492                 }
02493                 else if(sca->type==ACT_SCENE_REMOVE) { 
02494                         
02495                         ysize= 48;
02496                         glRects(xco, yco-ysize, xco+width, yco);
02497                         uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
02498 
02499                         uiDefIDPoinBut(block, test_scenepoin_but, ID_SCE, 1, "SCE:",            xco+40, yco-44, (width-80), 19, &(sca->scene), "Remove a Scene");
02500                 }
02501                 else if(sca->type==ACT_SCENE_SUSPEND) { 
02502                         
02503                         ysize= 48;
02504                         glRects(xco, yco-ysize, xco+width, yco);
02505                         uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
02506 
02507                         uiDefIDPoinBut(block, test_scenepoin_but, ID_SCE, 1, "SCE:",            xco+40, yco-44, (width-80), 19, &(sca->scene), "Pause a Scene");
02508                 }
02509                 else if(sca->type==ACT_SCENE_RESUME) { 
02510                         
02511                         ysize= 48;
02512                         glRects(xco, yco-ysize, xco+width, yco);
02513                         uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
02514 
02515                         uiDefIDPoinBut(block, test_scenepoin_but, ID_SCE, 1, "SCE:",            xco+40, yco-44, (width-80), 19, &(sca->scene), "Unpause a Scene");
02516                 }
02517 
02518                 str= "Scene %t|Restart %x0|Set Scene %x1|Set Camera %x2|Add OverlayScene %x3|Add BackgroundScene %x4|Remove Scene %x5|Suspend Scene %x6|Resume Scene %x7";
02519                 uiDefButS(block, MENU, B_REDR, str,             xco+40, yco-24, (width-80), 19, &sca->type, 0.0, 0.0, 0, 0, ""); 
02520 
02521                   yco-= ysize; 
02522                   break; 
02523         case ACT_GAME:
02524                 {
02525                         gma = act->data; 
02526                         if (gma->type == ACT_GAME_LOAD)
02527                         {
02528                                 //ysize = 68;
02529                                 ysize = 48;
02530                                 glRects(xco, yco-ysize, xco+width, yco); 
02531                                 uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); 
02532                                    uiDefBut(block, TEX, 1, "File: ", xco+10, yco-44,width-20,19, &(gma->filename), 0, 63, 0, 0, "Load this blend file, use the \"//\" prefix for a path relative to the current blend file");
02533 //                              uiDefBut(block, TEX, 1, "Anim: ", xco+10, yco-64,width-20,19, &(gma->loadaniname), 0, 63, 0, 0, "Use this loadinganimation");
02534                         }
02535 /*                      else if (gma->type == ACT_GAME_START)
02536                         {
02537                                 ysize = 68; 
02538                                 glRects(xco, yco-ysize, xco+width, yco); 
02539                                 uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
02540 
02541                                    uiDefBut(block, TEX, 1, "File: ", xco+10, yco-44,width-20,19, &(gma->filename), 0, 63, 0, 0, "Load this file");
02542                                 uiDefBut(block, TEX, 1, "Anim: ", xco+10, yco-64,width-20,19, &(gma->loadaniname), 0, 63, 0, 0, "Use this loadinganimation");
02543                         }
02544 */                      else if (ELEM4(gma->type, ACT_GAME_RESTART, ACT_GAME_QUIT, ACT_GAME_SAVECFG, ACT_GAME_LOADCFG))
02545                         {
02546                                 ysize = 28; 
02547                                 glRects(xco, yco-ysize, xco+width, yco); 
02548                                 uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); 
02549                         }
02550 
02551                         //str = "Scene %t|Load game%x0|Start loaded game%x1|Restart this game%x2|Quit this game %x3";
02552                         str = "Scene %t|Start new game%x0|Restart this game%x2|Quit this game %x3|Save bge.logic.globalDict %x4|Load bge.logic.globalDict %x5";
02553                         uiDefButS(block, MENU, B_REDR, str, xco+40, yco-24, (width-80), 19, &gma->type, 0.0, 0.0, 0, 0, ""); 
02554                         
02555                         yco -= ysize; 
02556                         break; 
02557                 }
02558         case ACT_GROUP:
02559                 ga= act->data;
02560 
02561                 ysize= 52;
02562 
02563                 glRects(xco, yco-ysize, xco+width, yco);
02564                 uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
02565                 
02566                 str= "GroupKey types   %t|Set Key %x6|Play %x0|Ping Pong %x1|Flipper %x2|Loop Stop %x3|Loop End %x4|Property %x5";
02567 
02568                 uiDefButS(block, MENU, 1, str,                  xco+20, yco-24, width-40, 19, &ga->type, 0, 0, 0, 0, "");
02569                 if(ga->type==ACT_GROUP_SET) {
02570                         uiDefBut(block, TEX, 0, "Key: ",                xco+20, yco-44, (width-10)/2, 19, ga->name, 0.0, 31.0, 0, 0, "This name defines groupkey to be set");
02571                         uiDefButI(block, NUM, 0, "Frame:",      xco+20+(width-10)/2, yco-44, (width-70)/2, 19, &ga->sta, 0.0, 2500.0, 0, 0, "Set this frame");
02572                 }
02573                 else if(ga->type==ACT_GROUP_FROM_PROP) {
02574                         uiDefBut(block, TEX, 0, "Prop: ",               xco+20, yco-44, width-40, 19, ga->name, 0.0, 31.0, 0, 0, "Use this property to define the Group position");
02575                 }
02576                 else {
02577                         uiDefButI(block, NUM, 0, "State",               xco+20, yco-44, (width-40)/2, 19, &ga->sta, 0.0, 2500.0, 0, 0, "Start frame");
02578                         uiDefButI(block, NUM, 0, "End",         xco+20+(width-40)/2, yco-44, (width-40)/2, 19, &ga->end, 0.0, 2500.0, 0, 0, "End frame");
02579                 }
02580                 yco-= ysize;
02581                 break;
02582 
02583         case ACT_VISIBILITY:
02584                 ysize = 24;
02585 
02586                 glRects(xco, yco-ysize, xco+width, yco);
02587                 uiEmboss((float)xco,
02588                          (float)yco-ysize, (float)xco+width, (float)yco, 1);
02589                 
02590                 visAct = act->data;
02591 
02592                 uiBlockBeginAlign(block);
02593                 uiDefButBitI(block, TOGN, ACT_VISIBILITY_INVISIBLE, B_REDR,
02594                           "Visible",
02595                           xco + 10, yco - 20, (width - 20)/3, 19, &visAct->flag,
02596                           0.0, 0.0, 0, 0,
02597                           "Set the objects visible. Initialized from the objects render restriction toggle (access in the outliner)");
02598                 uiDefButBitI(block, TOG, ACT_VISIBILITY_OCCLUSION, B_REDR,
02599                           "Occlusion",
02600                           xco + 10 + ((width - 20)/3), yco - 20, (width - 20)/3, 19, &visAct->flag,
02601                           0.0, 0.0, 0, 0,
02602                           "Set the object to occlude objects behind it. Initialized from the object type in physics button");
02603                 uiBlockEndAlign(block);
02604                 
02605                 uiDefButBitI(block, TOG, ACT_VISIBILITY_RECURSIVE, 0,
02606                           "Children",
02607                           xco + 10 + (((width - 20)/3)*2)+10, yco - 20, ((width - 20)/3)-10, 19, &visAct->flag,
02608                           0.0, 0.0, 0, 0,
02609                           "Sets all the children of this object to the same visibility/occlusion recursively");
02610 
02611                 yco-= ysize;
02612 
02613                 break;
02614                 
02615         case ACT_STATE:
02616                 ysize = 34;
02617 
02618                 glRects(xco, yco-ysize, xco+width, yco);
02619                 uiEmboss((float)xco,
02620                          (float)yco-ysize, (float)xco+width, (float)yco, 1);
02621                 
02622                 staAct = act->data;
02623 
02624                 str= "Operation %t|Cpy %x0|Add %x1|Sub %x2|Inv %x3";
02625 
02626                 uiDefButI(block, MENU, B_REDR, str,
02627                           xco + 10, yco - 24, 65, 19, &staAct->type,
02628                           0.0, 0.0, 0, 0,
02629                           "Select the bit operation on object state mask");
02630 
02631                 for (wval=0; wval<15; wval+=5) {
02632                         uiBlockBeginAlign(block);
02633                         for (stbit=0; stbit<5; stbit++) {
02634                                 but = uiDefButBitI(block,  TOG, 1<<(stbit+wval), stbit+wval, "",        (short)(xco+85+12*stbit+13*wval), yco-17, 12, 12, (int *)&(staAct->mask), 0, 0, 0, 0, get_state_name(ob, (short)(stbit+wval)));
02635                                 uiButSetFunc(but, check_state_mask, but, &(staAct->mask));
02636                         }
02637                         for (stbit=0; stbit<5; stbit++) {
02638                                 but = uiDefButBitI(block, TOG, 1<<(stbit+wval+15), stbit+wval+15, "",   (short)(xco+85+12*stbit+13*wval), yco-29, 12, 12, (int *)&(staAct->mask), 0, 0, 0, 0, get_state_name(ob, (short)(stbit+wval+15)));
02639                                 uiButSetFunc(but, check_state_mask, but, &(staAct->mask));
02640                         }
02641                 }
02642                 uiBlockEndAlign(block);
02643 
02644                 yco-= ysize;
02645 
02646                 break;
02647 
02648         case ACT_RANDOM:
02649                 ysize  = 69;
02650 
02651                 glRects(xco, yco-ysize, xco+width, yco);
02652                 uiEmboss((float)xco,
02653                                   (float)yco-ysize, (float)xco+width, (float)yco, 1);
02654                 
02655                 randAct = act->data;
02656 
02657                 /* 1. seed */
02658                 uiDefButI(block, NUM, 1, "Seed: ",              (xco+10),yco-24, 0.4 *(width-20), 19,
02659                                  &randAct->seed, 0, 1000, 0, 0,
02660                                  "Initial seed of the random generator. Use Python for more freedom. "
02661                                  " (Choose 0 for not random)");
02662 
02663                 /* 2. distribution type */
02664                 /* One pick per distribution. These numbers MUST match the #defines  */
02665                 /* in game.h !!!                                                     */
02666                 str= "Distribution %t|Bool Constant %x0|Bool Uniform %x1"
02667                         "|Bool Bernoulli %x2|Int Constant %x3|Int Uniform %x4"
02668                         "|Int Poisson %x5|Float Constant %x6|Float Uniform %x7"
02669                         "|Float Normal %x8|Float Neg. Exp. %x9";
02670                 uiDefButI(block, MENU, B_REDR, str, (xco+10) + 0.4 * (width-20), yco-24, 0.6 * (width-20), 19,
02671                                  &randAct->distribution, 0.0, 0.0, 0, 0,
02672                                  "Choose the type of distribution");
02673 
02674                 /* 3. property */
02675                 uiDefBut(block, TEX, 1, "Property:", (xco+10), yco-44, (width-20), 19,
02676                                  &randAct->propname, 0, 31, 0, 0,
02677                                  "Assign the random value to this property"); 
02678 
02679                 /*4. and 5. arguments for the distribution*/
02680                 switch (randAct->distribution) {
02681                 case ACT_RANDOM_BOOL_CONST:
02682                         uiDefButBitI(block, TOG, 1, 1, "Always true", (xco+10), yco-64, (width-20), 19,
02683                                          &randAct->int_arg_1, 2.0, 1, 0, 0,
02684                                          "Always false or always true");                        
02685                         break;
02686                 case ACT_RANDOM_BOOL_UNIFORM:
02687                         uiDefBut(block, LABEL, 0, "     Do a 50-50 pick",       (xco+10), yco-64, (width-20), 19,
02688                                          NULL, 0, 0, 0, 0,
02689                                          "Choose between true and false, 50% chance each");
02690                         break;
02691                 case ACT_RANDOM_BOOL_BERNOUILLI:
02692                         uiDefButF(block, NUM, 1, "Chance", (xco+10), yco-64, (width-20), 19,
02693                                          &randAct->float_arg_1, 0.0, 1.0, 0, 0,
02694                                          "Pick a number between 0 and 1. Success if you stay "
02695                                          "below this value");                   
02696                         break;
02697                 case ACT_RANDOM_INT_CONST:
02698                         uiDefButI(block, NUM, 1, "Value: ",             (xco+10), yco-64, (width-20), 19,
02699                                          &randAct->int_arg_1, -1000, 1000, 0, 0,
02700                                          "Always return this number");
02701                         break;
02702                 case ACT_RANDOM_INT_UNIFORM:
02703                         uiDefButI(block, NUM, 1, "Min: ",               (xco+10), yco-64, (width-20)/2, 19,
02704                                          &randAct->int_arg_1, -1000, 1000, 0, 0,
02705                                          "Choose a number from a range. "
02706                                          "Lower boundary of the range");
02707                         uiDefButI(block, NUM, 1, "Max: ",               (xco+10) + (width-20)/2, yco-64, (width-20)/2, 19,
02708                                          &randAct->int_arg_2, -1000, 1000, 0, 0,
02709                                          "Choose a number from a range. "
02710                                          "Upper boundary of the range");
02711                         break;
02712                 case ACT_RANDOM_INT_POISSON:
02713                         uiDefButF(block, NUM, 1, "Mean: ", (xco+10), yco-64, (width-20), 19,
02714                                          &randAct->float_arg_1, 0.01, 100.0, 0, 0,
02715                                          "Expected mean value of the distribution");                                            
02716                         break;
02717                 case ACT_RANDOM_FLOAT_CONST:
02718                         uiDefButF(block, NUM, 1, "Value: ", (xco+10), yco-64, (width-20), 19,
02719                                          &randAct->float_arg_1, 0.0, 1.0, 0, 0,
02720                                          "Always return this number");
02721                         break;
02722                 case ACT_RANDOM_FLOAT_UNIFORM:
02723                         uiDefButF(block, NUM, 1, "Min: ",               (xco+10), yco-64, (width-20)/2, 19,
02724                                          &randAct->float_arg_1, -10000.0, 10000.0, 0, 0,
02725                                          "Choose a number from a range"
02726                                          "Lower boundary of the range");
02727                         uiDefButF(block, NUM, 1, "Max: ",               (xco+10) + (width-20)/2, yco-64, (width-20)/2, 19,
02728                                          &randAct->float_arg_2, -10000.0, 10000.0, 0, 0,
02729                                          "Choose a number from a range"
02730                                          "Upper boundary of the range");
02731                         break;
02732                 case ACT_RANDOM_FLOAT_NORMAL:
02733                         uiDefButF(block, NUM, 1, "Mean: ",              (xco+10), yco-64, (width-20)/2, 19,
02734                                          &randAct->float_arg_1, -10000.0, 10000.0, 0, 0,
02735                                          "A normal distribution. Mean of the distribution");
02736                         uiDefButF(block, NUM, 1, "SD: ",                (xco+10) + (width-20)/2, yco-64, (width-20)/2, 19,
02737                                          &randAct->float_arg_2, 0.0, 10000.0, 0, 0,
02738                                          "A normal distribution. Standard deviation of the "
02739                                          "distribution");
02740                         break;
02741                 case ACT_RANDOM_FLOAT_NEGATIVE_EXPONENTIAL:
02742                         uiDefButF(block, NUM, 1, "Half-life time: ", (xco+10), yco-64, (width-20), 19,
02743                                          &randAct->float_arg_1, 0.001, 10000.0, 0, 0,
02744                                          "Negative exponential dropoff");
02745                         break;
02746                 default:
02747                         ; /* don't know what this distro is... can be useful for testing */
02748                         /* though :)                                                     */
02749                 }
02750 
02751                 yco-= ysize;
02752                 break;
02753         case ACT_MESSAGE:
02754                 ma = act->data;
02755 
02756                 ysize = 4 + (3 * 24); /* footer + number of lines * 24 pixels/line */
02757         
02758                 glRects(xco, yco-ysize, xco+width, yco);
02759                 uiEmboss((float)xco,        (float)yco-ysize,
02760                                  (float)xco+width,  (float)yco, 1);
02761 
02762                 myline=1;
02763 
02764                 /* line 1: To */
02765                 uiDefBut(block, TEX, 1, "To: ",
02766                         (xco+10), (yco-(myline++*24)), (width-20), 19,
02767                         &ma->toPropName, 0, 31, 0, 0,
02768                         "Optional send message to objects with this name only, or empty to broadcast");
02769 
02770                 /* line 2: Message Subject */
02771                 uiDefBut(block, TEX, 1, "Subject: ",
02772                 (xco+10), (yco-(myline++*24)), (width-20), 19,
02773                 &ma->subject, 0, 31, 0, 0,
02774                 "Optional message subject. This is what can be filtered on");
02775 
02776                 /* line 3: Text/Property */
02777                 uiDefButBitS(block, TOG, 1, B_REDR, "T/P",
02778                         (xco+10),(yco-(myline*24)), (0.20 * (width-20)), 19,
02779                         &ma->bodyType, 0.0, 0.0, 0, 0,
02780                         "Toggle message type: either Text or a PropertyName");
02781 
02782                 if (ma->bodyType == ACT_MESG_MESG)
02783                 {
02784                         /* line 3: Message Body */
02785                         uiDefBut(block, TEX, 1, "Body: ",
02786                         (xco+10+(0.20*(width-20))),(yco-(myline++*24)),(0.8*(width-20)),19,
02787                         &ma->body, 0, 31, 0, 0,
02788                         "Optional message body Text");
02789                 } else
02790                 {
02791                         /* line 3: Property body (set by property) */
02792                         uiDefBut(block, TEX, 1, "Propname: ",
02793                         (xco+10+(0.20*(width-20))),(yco-(myline++*24)),(0.8*(width-20)),19,
02794                         &ma->body, 0, 31, 0, 0,
02795                         "The message body will be set by the Property Value");
02796                 }
02797                 
02798                 yco -= ysize;
02799                 break;
02800         case ACT_2DFILTER:
02801                 tdfa = act->data;
02802 
02803                 ysize = 50;
02804                 if(tdfa->type == ACT_2DFILTER_CUSTOMFILTER)
02805                 {
02806                         ysize +=20;
02807                 }
02808                 glRects( xco, yco-ysize, xco+width, yco ); 
02809                 uiEmboss( (float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1 );
02810 
02811                 switch(tdfa->type)
02812                 {
02813                         case ACT_2DFILTER_MOTIONBLUR:
02814                                 if(!tdfa->flag)
02815                                 {
02816                                         uiDefButS(block, TOG, B_REDR, "D",      xco+30,yco-44,19, 19, &tdfa->flag, 0.0, 0.0, 0.0, 0.0, "Disable Motion Blur");
02817                                         uiDefButF(block, NUM, B_REDR, "Value:", xco+52,yco-44,width-82,19,&tdfa->float_arg,0.0,1.0,0.0,0.0,"Set motion blur value");
02818                                 }
02819                                 else
02820                                 {
02821                                         uiDefButS(block, TOG, B_REDR, "Disabled",       xco+30,yco-44,width-60, 19, &tdfa->flag, 0.0, 0.0, 0.0, 0.0, "Enable Motion Blur");
02822                                 }
02823                                 break;
02824                         case ACT_2DFILTER_BLUR:
02825                         case ACT_2DFILTER_SHARPEN:
02826                         case ACT_2DFILTER_DILATION:
02827                         case ACT_2DFILTER_EROSION:
02828                         case ACT_2DFILTER_LAPLACIAN:
02829                         case ACT_2DFILTER_SOBEL:
02830                         case ACT_2DFILTER_PREWITT:
02831                         case ACT_2DFILTER_GRAYSCALE:
02832                         case ACT_2DFILTER_SEPIA:
02833                         case ACT_2DFILTER_INVERT:
02834                         case ACT_2DFILTER_NOFILTER:
02835                         case ACT_2DFILTER_DISABLED:
02836                         case ACT_2DFILTER_ENABLED:
02837                                 uiDefButI(block, NUM, B_REDR, "Pass Number:", xco+30,yco-44,width-60,19,&tdfa->int_arg,0.0,MAX_RENDER_PASS-1,0.0,0.0,"Set filter order");
02838                                 break;
02839                         case ACT_2DFILTER_CUSTOMFILTER:
02840                                 uiDefButI(block, NUM, B_REDR, "Pass Number:", xco+30,yco-44,width-60,19,&tdfa->int_arg,0.0,MAX_RENDER_PASS-1,0.0,0.0,"Set filter order");
02841                                 uiDefIDPoinBut(block, test_scriptpoin_but, ID_SCRIPT, 1, "Script: ", xco+30,yco-64,width-60, 19, &tdfa->text, "");
02842                                 break;
02843                 }
02844                 
02845                 str= "2D Filter   %t|Motion Blur   %x1|Blur %x2|Sharpen %x3|Dilation %x4|Erosion %x5|"
02846                                 "Laplacian %x6|Sobel %x7|Prewitt %x8|Gray Scale %x9|Sepia %x10|Invert %x11|Custom Filter %x12|"
02847                                 "Enable Filter %x-2|Disable Filter %x-1|Remove Filter %x0|";
02848                 uiDefButS(block, MENU, B_REDR, str,     xco+30,yco-24,width-60, 19, &tdfa->type, 0.0, 0.0, 0.0, 0.0, "2D filter type");
02849                 
02850                 yco -= ysize;
02851                 break;
02852         case ACT_PARENT:
02853                 parAct = act->data;
02854 
02855                 if(parAct->type==ACT_PARENT_SET) {
02856                         
02857                         ysize= 48;
02858                         glRects(xco, yco-ysize, xco+width, yco);
02859                         uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
02860                         uiDefIDPoinBut(block, test_obpoin_but, ID_OB, 1, "OB:",         xco+95, yco-24, (width-100), 19, &(parAct->ob), "Set this object as parent");
02861                         uiBlockBeginAlign(block);
02862                         uiDefButBitS(block, TOGN, ACT_PARENT_COMPOUND, B_REDR,
02863                         "Compound",
02864                         xco + 5, yco - 44, (width - 10)/2, 19, &parAct->flag,
02865                         0.0, 0.0, 0, 0,
02866                         "Add this object shape to the parent shape (only if the parent shape is already compound)");
02867                         uiDefButBitS(block, TOGN, ACT_PARENT_GHOST, B_REDR,
02868                         "Ghost",
02869                         xco + 5 + ((width - 10)/2), yco - 44, (width - 10)/2, 19, &parAct->flag,
02870                         0.0, 0.0, 0, 0,
02871                         "Make this object ghost while parented (only if not compound)");
02872                         uiBlockEndAlign(block);
02873                 }
02874                 else if(parAct->type==ACT_PARENT_REMOVE) {
02875 
02876                         ysize= 28;
02877                         glRects(xco, yco-ysize, xco+width, yco);
02878                         uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
02879                 }
02880 
02881                 str= "Parent %t|Set Parent %x0|Remove Parent %x1";
02882                 uiDefButI(block, MENU, B_REDR, str,             xco+5, yco-24, parAct->type==1?(width-80):90, 19, &parAct->type, 0.0, 0.0, 0, 0, ""); 
02883 
02884                 yco-= ysize;
02885                 break;
02886         case ACT_ARMATURE:
02887                 armAct = act->data;
02888 
02889                 if (ob->type == OB_ARMATURE) {
02890                         str= "Constraint %t|Run armature %x0|Enable %x1|Disable %x2|Set target %x3|Set weight %x4";
02891                         uiDefButI(block, MENU, B_REDR, str,             xco+5, yco-24, (width-10)*0.35, 19, &armAct->type, 0.0, 0.0, 0, 0, ""); 
02892 
02893                         switch (armAct->type) {
02894                         case ACT_ARM_RUN:
02895                                 ysize = 28;
02896                                 break;
02897                         default:
02898                                 uiBlockBeginAlign(block);
02899                                 but = uiDefBut(block, TEX, 1, "Bone: ",
02900                                                 (xco+5), (yco-44), (width-10)/2, 19,
02901                                                 armAct->posechannel, 0, 31, 0, 0,
02902                                                 "Bone on which the constraint is defined");
02903                                 uiButSetFunc(but, check_armature_actuator, but, armAct);
02904                                 but = uiDefBut(block, TEX, 1, "Cons: ",
02905                                                 (xco+5)+(width-10)/2, (yco-44), (width-10)/2, 19,
02906                                                 armAct->constraint, 0, 31, 0, 0,
02907                                                 "Name of the constraint you want to control");
02908                                 uiButSetFunc(but, check_armature_actuator, but, armAct);
02909                                 uiBlockEndAlign(block);
02910                                 ysize = 48;
02911                                 switch (armAct->type) {
02912                                 case ACT_ARM_SETTARGET:
02913                                         uiDefIDPoinBut(block, test_obpoin_but, ID_OB, 1, "Target: ",            xco+5, yco-64, (width-10), 19, &(armAct->target), "Set this object as the target of the constraint"); 
02914                                         uiDefIDPoinBut(block, test_obpoin_but, ID_OB, 1, "Secondary Target: ",          xco+5, yco-84, (width-10), 19, &(armAct->subtarget), "Set this object as the secondary target of the constraint (only IK polar target at the moment)"); 
02915                                         ysize += 40;
02916                                         break;
02917                                 case ACT_ARM_SETWEIGHT:
02918                                         uiDefButF(block, NUM, B_REDR, "Weight:", xco+5+(width-10)*0.35,yco-24,(width-10)*0.65,19,&armAct->weight,0.0,1.0,0.0,0.0,"Set weight of this constraint");
02919                                         break;
02920                                 }
02921                         }
02922                   }
02923                 glRects(xco, yco-ysize, xco+width, yco); 
02924                 uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); 
02925                 yco-= ysize;
02926                 break;
02927 
02928          default:
02929                 ysize= 4;
02930 
02931                 glRects(xco, yco-ysize, xco+width, yco);
02932                 uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
02933                 
02934                 yco-= ysize;
02935                 break;
02936         }
02937 
02938         uiBlockSetEmboss(block, UI_EMBOSS);
02939 
02940         return yco-4;
02941 }
02942 
02943 static void do_sensor_menu(bContext *C, void *UNUSED(arg), int event)
02944 {       
02945         SpaceLogic *slogic= CTX_wm_space_logic(C);
02946         ID **idar;
02947         Object *ob;
02948         bSensor *sens;
02949         short count, a;
02950         
02951         idar= get_selected_and_linked_obs(C, &count, slogic->scaflag);
02952         
02953         for(a=0; a<count; a++) {
02954                 ob= (Object *)idar[a];
02955                 if(event==0 || event==2) ob->scaflag |= OB_SHOWSENS;
02956                 else if(event==1) ob->scaflag &= ~OB_SHOWSENS;
02957         }
02958                 
02959         for(a=0; a<count; a++) {
02960                 ob= (Object *)idar[a];
02961                 sens= ob->sensors.first;
02962                 while(sens) {
02963                         if(event==2) sens->flag |= SENS_SHOW;
02964                         else if(event==3) sens->flag &= ~SENS_SHOW;
02965                         sens= sens->next;
02966                 }
02967         }
02968 
02969         if(idar) MEM_freeN(idar);
02970 }
02971 
02972 static uiBlock *sensor_menu(bContext *C, ARegion *ar, void *UNUSED(arg))
02973 {
02974         uiBlock *block;
02975         int yco=0;
02976         
02977         block= uiBeginBlock(C, ar, "filemenu", UI_EMBOSSP);
02978         uiBlockSetButmFunc(block, do_sensor_menu, NULL);
02979         
02980         uiDefBut(block, BUTM, 1, "Show Objects",        0, (short)(yco-=20), 160, 19, NULL, 0.0, 0.0, 1, 0, "");
02981         uiDefBut(block, BUTM, 1, "Hide Objects",        0, (short)(yco-=20), 160, 19, NULL, 0.0, 0.0, 1, 1, "");
02982         uiDefBut(block, SEPR, 0, "",    0, (short)(yco-=6), 160, 6, NULL, 0.0, 0.0, 0, 0, "");
02983         uiDefBut(block, BUTM, 1, "Show Sensors",        0, (short)(yco-=20), 160, 19, NULL, 0.0, 0.0, 1, 2, "");
02984         uiDefBut(block, BUTM, 1, "Hide Sensors",        0, (short)(yco-=20), 160, 19, NULL, 0.0, 0.0, 1, 3, "");
02985 
02986         uiBlockSetDirection(block, UI_TOP);
02987         uiEndBlock(C, block);
02988         
02989         return block;
02990 }
02991 
02992 static void do_controller_menu(bContext *C, void *UNUSED(arg), int event)
02993 {       
02994         SpaceLogic *slogic= CTX_wm_space_logic(C);
02995         ID **idar;
02996         Object *ob;
02997         bController *cont;
02998         short count, a;
02999         
03000         idar= get_selected_and_linked_obs(C, &count, slogic->scaflag);
03001         
03002         for(a=0; a<count; a++) {
03003                 ob= (Object *)idar[a];
03004                 if(event==0 || event==2) ob->scaflag |= OB_SHOWCONT;
03005                 else if(event==1) ob->scaflag &= ~OB_SHOWCONT;
03006         }
03007 
03008         for(a=0; a<count; a++) {
03009                 ob= (Object *)idar[a];
03010                 cont= ob->controllers.first;
03011                 while(cont) {
03012                         if(event==2) cont->flag |= CONT_SHOW;
03013                         else if(event==3) cont->flag &= ~CONT_SHOW;
03014                         cont= cont->next;
03015                 }
03016         }
03017 
03018         if(idar) MEM_freeN(idar);
03019 }
03020 
03021 static uiBlock *controller_menu(bContext *C, ARegion *ar, void *UNUSED(arg))
03022 {
03023         uiBlock *block;
03024         int yco=0;
03025         
03026         block= uiBeginBlock(C, ar, "filemenu", UI_EMBOSSP);
03027         uiBlockSetButmFunc(block, do_controller_menu, NULL);
03028         
03029         uiDefBut(block, BUTM, 1, "Show Objects",        0, (short)(yco-=20), 160, 19, NULL, 0.0, 0.0, 1, 0, "");
03030         uiDefBut(block, BUTM, 1, "Hide Objects",        0,(short)(yco-=20), 160, 19, NULL, 0.0, 0.0, 1, 1, "");
03031         uiDefBut(block, SEPR, 0, "",                                    0, (short)(yco-=6), 160, 6, NULL, 0.0, 0.0, 0, 0, "");
03032         uiDefBut(block, BUTM, 1, "Show Controllers",    0, (short)(yco-=20), 160, 19, NULL, 0.0, 0.0, 2, 2, "");
03033         uiDefBut(block, BUTM, 1, "Hide Controllers",    0, (short)(yco-=20), 160, 19, NULL, 0.0, 0.0, 3, 3, "");
03034 
03035         uiBlockSetDirection(block, UI_TOP);
03036         uiEndBlock(C, block);
03037         
03038         return block;
03039 }
03040 
03041 static void do_actuator_menu(bContext *C, void *UNUSED(arg), int event)
03042 {       
03043         SpaceLogic *slogic= CTX_wm_space_logic(C);
03044         ID **idar;
03045         Object *ob;
03046         bActuator *act;
03047         short count, a;
03048         
03049         idar= get_selected_and_linked_obs(C, &count, slogic->scaflag);
03050         
03051         for(a=0; a<count; a++) {
03052                 ob= (Object *)idar[a];
03053                 if(event==0 || event==2) ob->scaflag |= OB_SHOWACT;
03054                 else if(event==1) ob->scaflag &= ~OB_SHOWACT;
03055         }
03056 
03057         for(a=0; a<count; a++) {
03058                 ob= (Object *)idar[a];
03059                 act= ob->actuators.first;
03060                 while(act) {
03061                         if(event==2) act->flag |= ACT_SHOW;
03062                         else if(event==3) act->flag &= ~ACT_SHOW;
03063                         act= act->next;
03064                 }
03065         }
03066 
03067         if(idar) MEM_freeN(idar);
03068 }
03069 
03070 static uiBlock *actuator_menu(bContext *C, ARegion *ar, void *UNUSED(arg))
03071 {
03072         uiBlock *block;
03073         int xco=0;
03074         
03075         block= uiBeginBlock(C, ar, "filemenu", UI_EMBOSSP);
03076         uiBlockSetButmFunc(block, do_actuator_menu, NULL);
03077         
03078         uiDefBut(block, BUTM, 1, "Show Objects",        0, (short)(xco-=20), 160, 19, NULL, 0.0, 0.0, 1, 0, "");
03079         uiDefBut(block, BUTM, 1, "Hide Objects",        0, (short)(xco-=20), 160, 19, NULL, 0.0, 0.0, 1, 1, "");
03080         uiDefBut(block, SEPR, 0, "",    0, (short)(xco-=6), 160, 6, NULL, 0.0, 0.0, 0, 0, "");
03081         uiDefBut(block, BUTM, 1, "Show Actuators",      0, (short)(xco-=20), 160, 19, NULL, 0.0, 0.0, 1, 2, "");
03082         uiDefBut(block, BUTM, 1, "Hide Actuators",      0, (short)(xco-=20), 160, 19, NULL, 0.0, 0.0, 1, 3, "");
03083 
03084         uiBlockSetDirection(block, UI_TOP);
03085         uiEndBlock(C, block);
03086         
03087         return block;
03088 }
03089 
03090 
03091 
03092 static void check_controller_state_mask(bContext *UNUSED(C), void *arg1_but, void *arg2_mask)
03093 {
03094         unsigned int *cont_mask = arg2_mask;
03095         uiBut *but = arg1_but;
03096         
03097         /* a controller is always in a single state */
03098         *cont_mask = (1<<but->retval);
03099         but->retval = B_REDR;
03100 }
03101 
03102 static int first_bit(unsigned int mask)
03103 {
03104         int bit;
03105 
03106         for (bit=0; bit<32; bit++) {
03107                 if (mask & (1<<bit))
03108                         return bit;
03109         }
03110         return -1;
03111 }
03112 
03113 static uiBlock *controller_state_mask_menu(bContext *C, ARegion *ar, void *arg_cont)
03114 {
03115         uiBlock *block;
03116         uiBut *but;
03117         bController *cont = arg_cont;
03118 
03119         short yco = 12, xco = 0, stbit, offset;
03120 
03121         block= uiBeginBlock(C, ar, "Controller state mask", UI_EMBOSS);
03122 
03123         /* use this for a fake extra empy space around the buttons */
03124         uiDefBut(block, LABEL, 0, "",                   -5, -5, 200, 34, NULL, 0, 0, 0, 0, "");
03125         
03126         for (offset=0; offset<15; offset+=5) {
03127                 uiBlockBeginAlign(block);
03128                 for (stbit=0; stbit<5; stbit++) {
03129                         but = uiDefButBitI(block, TOG, (1<<(stbit+offset)), (stbit+offset), "", (short)(xco+12*stbit+13*offset), yco, 12, 12, (int *)&(cont->state_mask), 0, 0, 0, 0, "");
03130                         uiButSetFunc(but, check_controller_state_mask, but, &(cont->state_mask));
03131                 }
03132                 for (stbit=0; stbit<5; stbit++) {
03133                         but = uiDefButBitI(block, TOG, (1<<(stbit+offset+15)), (stbit+offset+15), "",   (short)(xco+12*stbit+13*offset), yco-12, 12, 12, (int *)&(cont->state_mask), 0, 0, 0, 0, "");
03134                         uiButSetFunc(but, check_controller_state_mask, but, &(cont->state_mask));
03135                 }
03136         }
03137         uiBlockEndAlign(block);
03138 
03139         uiBlockSetDirection(block, UI_TOP);
03140         uiEndBlock(C, block);
03141 
03142         return block;
03143 }
03144 
03145 static void do_object_state_menu(bContext *UNUSED(C), void *arg, int event)
03146 {       
03147         Object *ob = arg;
03148 
03149         switch (event) {
03150         case 0:
03151                 ob->state = 0x3FFFFFFF;
03152                 break;
03153         case 1:
03154                 ob->state = ob->init_state;
03155                 if (!ob->state)
03156                         ob->state = 1;
03157                 break;
03158         case 2:
03159                 ob->init_state = ob->state;
03160                 break;
03161         }
03162 }
03163 
03164 static uiBlock *object_state_mask_menu(bContext *C, ARegion *ar, void *arg_obj)
03165 {
03166         uiBlock *block;
03167         short xco = 0;
03168 
03169         block= uiBeginBlock(C, ar, "obstatemenu", UI_EMBOSSP);
03170         uiBlockSetButmFunc(block, do_object_state_menu, arg_obj);
03171         
03172         uiDefBut(block, BUTM, 1, "Set all bits",                0, (short)(xco-=20), 160, 19, NULL, 0.0, 0.0, 1, 0, "");
03173         uiDefBut(block, BUTM, 1, "Recall init state",   0, (short)(xco-=20), 160, 19, NULL, 0.0, 0.0, 1, 1, "");
03174         uiDefBut(block, SEPR, 0, "",                                    0, (short)(xco-=6),      160, 6,  NULL, 0.0, 0.0, 0, 0, "");
03175         uiDefBut(block, BUTM, 1, "Store init state",    0, (short)(xco-=20), 160, 19, NULL, 0.0, 0.0, 1, 2, "");
03176 
03177         uiBlockSetDirection(block, UI_TOP);
03178         uiEndBlock(C, block);
03179         
03180         return block;
03181 }
03182 
03183 static int is_sensor_linked(uiBlock *block, bSensor *sens)
03184 {
03185         bController *cont;
03186         int i;
03187 
03188         for (i=0; i<sens->totlinks; i++) {
03189                 cont = sens->links[i];
03190                 if (uiFindInlink(block, cont) != NULL)
03191                         return 1;
03192         }
03193         return 0;
03194 }
03195 
03196 /* Sensors code */
03197 
03198 static void draw_sensor_header(uiLayout *layout, PointerRNA *ptr, PointerRNA *logic_ptr)
03199 {
03200         uiLayout *box, *row, *subrow;
03201         bSensor *sens= (bSensor *)ptr->data;
03202         
03203         box= uiLayoutBox(layout);
03204         row= uiLayoutRow(box, 0);
03205         
03206         uiItemR(row, ptr, "show_expanded", UI_ITEM_R_NO_BG, "", ICON_NONE);
03207         if(RNA_boolean_get(ptr, "show_expanded")) {
03208                 uiItemR(row, ptr, "type", 0, "", ICON_NONE);
03209                 uiItemR(row, ptr, "name", 0, "", ICON_NONE);
03210         } else {
03211                 uiItemL(row, sensor_name(sens->type), ICON_NONE);
03212                 uiItemL(row, sens->name, ICON_NONE);
03213         }
03214 
03215         subrow= uiLayoutRow(row, 0);
03216         uiLayoutSetActive(subrow, ((RNA_boolean_get(logic_ptr, "show_sensors_active_states")
03217                                                         && RNA_boolean_get(ptr, "show_expanded")) || RNA_boolean_get(ptr, "pin")));
03218         uiItemR(subrow, ptr, "pin", UI_ITEM_R_NO_BG, "", ICON_NONE);
03219 
03220         if(RNA_boolean_get(ptr, "show_expanded")==0) {
03221                 subrow= uiLayoutRow(row, 1);
03222                 uiItemEnumO(subrow, "LOGIC_OT_sensor_move", "", ICON_TRIA_UP, "direction", 1); // up
03223                 uiItemEnumO(subrow, "LOGIC_OT_sensor_move", "", ICON_TRIA_DOWN, "direction", 2); // down
03224         }
03225 
03226         uiItemO(row, "", ICON_X, "LOGIC_OT_sensor_remove");
03227 }
03228 
03229 static void draw_sensor_internal_header(uiLayout *layout, PointerRNA *ptr)
03230 {
03231         uiLayout *box, *split, *subrow, *row;
03232 
03233         box= uiLayoutBox(layout);
03234         split = uiLayoutSplit(box, 0.45, 0);
03235         
03236         row= uiLayoutRow(split, 1);
03237         uiItemR(row, ptr, "use_pulse_true_level", 0, "", ICON_DOTSUP);
03238         uiItemR(row, ptr, "use_pulse_false_level", 0, "", ICON_DOTSDOWN);
03239 
03240         subrow=uiLayoutRow(row, 0);
03241         uiLayoutSetActive(subrow, (RNA_boolean_get(ptr, "use_pulse_true_level")
03242                                                         || RNA_boolean_get(ptr, "use_pulse_false_level")));
03243         uiItemR(subrow, ptr, "frequency", 0, "Freq", ICON_NONE);
03244         
03245         row= uiLayoutRow(split, 1);
03246         uiItemR(row, ptr, "use_level", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
03247         uiItemR(row, ptr, "use_tap", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
03248         
03249         row= uiLayoutRow(split, 1);
03250         uiItemR(row, ptr, "invert", UI_ITEM_R_TOGGLE, "Invert", ICON_NONE);
03251 }
03252 /* sensors in alphabetical order */
03253 
03254 static void draw_sensor_actuator(uiLayout *layout, PointerRNA *ptr)
03255 {
03256         Object *ob = (Object *)ptr->id.data;
03257         PointerRNA settings_ptr;
03258 
03259         RNA_pointer_create((ID *)ob, &RNA_GameObjectSettings, ob, &settings_ptr);
03260         uiItemPointerR(layout, ptr, "actuator", &settings_ptr, "actuators", NULL, ICON_LOGIC);
03261 }
03262 
03263 static void draw_sensor_armature(uiLayout *layout, PointerRNA *ptr)
03264 {
03265         bSensor *sens = (bSensor*)ptr->data;
03266         bArmatureSensor *as = (bArmatureSensor *) sens->data;
03267         Object *ob = (Object *)ptr->id.data;
03268         PointerRNA pose_ptr, pchan_ptr;
03269         PropertyRNA *bones_prop= NULL;
03270         uiLayout *row;
03271 
03272         if(ob->type != OB_ARMATURE){
03273                 uiItemL(layout, "Sensor only available for armatures", ICON_NONE);
03274                 return;
03275         }
03276 
03277         if (ob->pose) {
03278                 RNA_pointer_create((ID *)ob, &RNA_Pose, ob->pose, &pose_ptr);
03279                 bones_prop = RNA_struct_find_property(&pose_ptr, "bones");
03280         }
03281 
03282         if (&pose_ptr.data) {
03283                 uiItemPointerR(layout, ptr, "bone", &pose_ptr, "bones", NULL, ICON_BONE_DATA);
03284 
03285                 if (RNA_property_collection_lookup_string(&pose_ptr, bones_prop, as->posechannel, &pchan_ptr))
03286                         uiItemPointerR(layout, ptr, "constraint", &pchan_ptr, "constraints", NULL, ICON_CONSTRAINT_BONE);
03287         }
03288         row = uiLayoutRow(layout, 1);
03289         uiItemR(row, ptr, "test_type", 0, NULL, ICON_NONE);
03290         if (RNA_enum_get(ptr, "test_type") != SENS_ARM_STATE_CHANGED)
03291                 uiItemR(row, ptr, "value", 0, NULL, ICON_NONE);
03292 }
03293 
03294 static void draw_sensor_collision(uiLayout *layout, PointerRNA *ptr, bContext *C)
03295 {
03296         uiLayout *row, *split;
03297         PointerRNA main_ptr;
03298 
03299         RNA_main_pointer_create(CTX_data_main(C), &main_ptr);
03300 
03301         split = uiLayoutSplit(layout, 0.3, 0);
03302         row = uiLayoutRow(split, 1);
03303         uiItemR(row, ptr, "use_pulse", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
03304         uiItemR(row, ptr, "use_material", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
03305 
03306         switch (RNA_boolean_get(ptr, "use_material")) {
03307                 case SENS_COLLISION_PROPERTY:
03308                         uiItemR(split, ptr, "property", 0, NULL, ICON_NONE);
03309                         break;
03310                 case SENS_COLLISION_MATERIAL:
03311                         uiItemPointerR(split, ptr, "material", &main_ptr, "materials", NULL, ICON_MATERIAL_DATA);
03312                         break;
03313         }
03314 }
03315 
03316 static void draw_sensor_delay(uiLayout *layout, PointerRNA *ptr)
03317 {
03318         uiLayout *row;
03319         
03320         row= uiLayoutRow(layout, 0);
03321 
03322         uiItemR(row, ptr, "delay", 0, NULL, ICON_NONE);
03323         uiItemR(row, ptr, "duration", 0, NULL, ICON_NONE);
03324         uiItemR(row, ptr, "use_repeat", 0, NULL, ICON_NONE);
03325 }
03326 
03327 static void draw_sensor_joystick(uiLayout *layout, PointerRNA *ptr)
03328 {
03329         uiLayout *col, *row;
03330 
03331         uiItemR(layout, ptr, "joystick_index", 0, NULL, ICON_NONE);
03332         uiItemR(layout, ptr, "event_type", 0, NULL, ICON_NONE);
03333 
03334         switch (RNA_enum_get(ptr, "event_type")) {
03335                 case SENS_JOY_BUTTON:
03336                         uiItemR(layout, ptr, "use_all_events", 0, NULL, ICON_NONE);
03337 
03338                         col = uiLayoutColumn(layout, 0);
03339                         uiLayoutSetActive(col, RNA_boolean_get(ptr, "use_all_events")==0);
03340                         uiItemR(col, ptr, "button_number", 0, NULL, ICON_NONE);
03341                         break;
03342                 case SENS_JOY_AXIS:
03343                         row = uiLayoutRow(layout, 0);
03344                         uiItemR(row, ptr, "axis_number", 0, NULL, ICON_NONE);
03345                         uiItemR(row, ptr, "axis_threshold", 0, NULL, ICON_NONE);
03346 
03347                         uiItemR(layout, ptr, "use_all_events", 0, NULL, ICON_NONE);
03348                         col = uiLayoutColumn(layout, 0);
03349                         uiLayoutSetActive(col, RNA_boolean_get(ptr, "use_all_events")==0);
03350                         uiItemR(col, ptr, "axis_direction", 0, NULL, ICON_NONE);
03351                         break;
03352                 case SENS_JOY_HAT:
03353                         uiItemR(layout, ptr, "hat_number", 0, NULL, ICON_NONE);
03354                         uiItemR(layout, ptr, "use_all_events", 0, NULL, ICON_NONE);
03355 
03356                         col = uiLayoutColumn(layout, 0);
03357                         uiLayoutSetActive(col, RNA_boolean_get(ptr, "use_all_events")==0);
03358                         uiItemR(col, ptr, "hat_direction", 0, NULL, ICON_NONE);
03359                         break;
03360                 case SENS_JOY_AXIS_SINGLE:
03361                         row = uiLayoutRow(layout, 0);
03362                         uiItemR(row, ptr, "single_axis_number", 0, NULL, ICON_NONE);
03363                         uiItemR(row, ptr, "axis_threshold", 0, NULL, ICON_NONE);
03364                         break;
03365         }
03366 }
03367 
03368 static void draw_sensor_keyboard(uiLayout *layout, PointerRNA *ptr)
03369 {
03370         Object *ob = (Object *)ptr->id.data;
03371         PointerRNA settings_ptr;
03372         uiLayout *row, *col;
03373 
03374         row = uiLayoutRow(layout, 0);
03375         uiItemL(row, "Key:", ICON_NONE);
03376         col = uiLayoutColumn(row, 0);
03377         uiLayoutSetActive(col, RNA_boolean_get(ptr, "use_all_keys")==0);
03378         uiItemR(col, ptr, "key", UI_ITEM_R_EVENT, "", ICON_NONE);
03379         col = uiLayoutColumn(row, 0);
03380         uiItemR(col, ptr, "use_all_keys", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
03381         
03382         col = uiLayoutColumn(layout, 0);
03383         uiLayoutSetActive(col, RNA_boolean_get(ptr, "use_all_keys")==0);
03384         row = uiLayoutRow(col, 0);
03385         uiItemL(row, "First Modifier:", ICON_NONE);
03386         uiItemR(row, ptr, "modifier_key_1", UI_ITEM_R_EVENT, "", ICON_NONE);
03387         
03388         row = uiLayoutRow(col, 0);
03389         uiItemL(row, "Second Modifier:", ICON_NONE);
03390         uiItemR(row, ptr, "modifier_key_2", UI_ITEM_R_EVENT, "", ICON_NONE);
03391 
03392         RNA_pointer_create((ID *)ob, &RNA_GameObjectSettings, ob, &settings_ptr);
03393         uiItemPointerR(layout, ptr, "log", &settings_ptr, "properties", NULL, ICON_NONE);
03394         uiItemPointerR(layout, ptr, "target", &settings_ptr, "properties", NULL, ICON_NONE);
03395 }
03396 
03397 static void draw_sensor_message(uiLayout *layout, PointerRNA *ptr)
03398 {
03399         uiItemR(layout, ptr, "subject", 0, NULL, ICON_NONE);
03400 }
03401 
03402 static void draw_sensor_mouse(uiLayout *layout, PointerRNA *ptr)
03403 {
03404         uiItemR(layout, ptr, "mouse_event", 0, NULL, ICON_NONE);
03405 }
03406 
03407 static void draw_sensor_near(uiLayout *layout, PointerRNA *ptr)
03408 {
03409         uiLayout *row;
03410 
03411         uiItemR(layout, ptr, "property", 0, NULL, ICON_NONE);
03412 
03413         row= uiLayoutRow(layout, 1);
03414         uiItemR(row, ptr, "distance", 0, NULL, ICON_NONE);
03415         uiItemR(row, ptr, "reset_distance", 0, NULL, ICON_NONE);
03416 }
03417 
03418 static void draw_sensor_property(uiLayout *layout, PointerRNA *ptr)
03419 {
03420         Object *ob = (Object *)ptr->id.data;
03421         PointerRNA settings_ptr;
03422 
03423         uiLayout *row;
03424         uiItemR(layout, ptr, "evaluation_type", 0, NULL, ICON_NONE);
03425 
03426         RNA_pointer_create((ID *)ob, &RNA_GameObjectSettings, ob, &settings_ptr);
03427         uiItemPointerR(layout, ptr, "property", &settings_ptr, "properties", NULL, ICON_NONE);
03428 
03429         switch (RNA_enum_get(ptr, "evaluation_type")) {
03430                 case SENS_PROP_INTERVAL:
03431                         row = uiLayoutRow(layout, 0);
03432                         uiItemR(row, ptr, "value_min", 0, NULL, ICON_NONE);
03433                         uiItemR(row, ptr, "value_max", 0, NULL, ICON_NONE);
03434                         break;
03435                 case SENS_PROP_EQUAL:
03436                         uiItemR(layout, ptr, "value", 0, NULL, ICON_NONE);
03437                         break;
03438                 case SENS_PROP_NEQUAL:
03439                         uiItemR(layout, ptr, "value", 0, NULL, ICON_NONE);
03440                         break;
03441                 case SENS_PROP_CHANGED:
03442                         break;
03443         }
03444 }
03445 
03446 static void draw_sensor_radar(uiLayout *layout, PointerRNA *ptr)
03447 {
03448         uiLayout *row;
03449 
03450         uiItemR(layout, ptr, "property", 0, NULL, ICON_NONE);
03451         uiItemR(layout, ptr, "axis", 0, NULL, ICON_NONE);
03452 
03453         row= uiLayoutRow(layout, 0);
03454         uiItemR(row, ptr, "angle", 0, NULL, ICON_NONE);
03455         uiItemR(row, ptr, "distance", 0, NULL, ICON_NONE);
03456 }
03457 
03458 static void draw_sensor_random(uiLayout *layout, PointerRNA *ptr)
03459 {
03460         uiItemR(layout, ptr, "seed", 0, NULL, ICON_NONE);
03461 }
03462 
03463 static void draw_sensor_ray(uiLayout *layout, PointerRNA *ptr, bContext *C)
03464 {
03465         uiLayout *split, *row;
03466         PointerRNA main_ptr;
03467 
03468         RNA_main_pointer_create(CTX_data_main(C), &main_ptr);
03469         split= uiLayoutSplit(layout, 0.3, 0);
03470         uiItemR(split, ptr, "ray_type", 0, "", ICON_NONE);
03471         switch (RNA_enum_get(ptr, "ray_type")) {
03472                 case SENS_RAY_PROPERTY:
03473                         uiItemR(split, ptr, "property", 0, "", ICON_NONE);
03474                         break;
03475                 case SENS_RAY_MATERIAL:
03476                         uiItemPointerR(split, ptr, "material", &main_ptr, "materials", "", ICON_MATERIAL_DATA);
03477                         break;
03478         }
03479 
03480         split= uiLayoutSplit(layout, 0.3, 0);
03481         uiItemR(split, ptr, "axis", 0, "", ICON_NONE);
03482         row= uiLayoutRow(split, 0);     
03483         uiItemR(row, ptr, "range", 0, NULL, ICON_NONE);
03484         uiItemR(row, ptr, "use_x_ray", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
03485 }
03486 
03487 static void draw_sensor_touch(uiLayout *layout, PointerRNA *ptr)
03488 {
03489         uiItemR(layout, ptr, "material", 0, NULL, ICON_NONE);
03490 }
03491 
03492 static void draw_brick_sensor(uiLayout *layout, PointerRNA *ptr, bContext *C)
03493 {
03494         uiLayout *box;
03495         
03496         if (!RNA_boolean_get(ptr, "show_expanded"))
03497                 return;
03498 
03499         draw_sensor_internal_header(layout, ptr);
03500         
03501         box = uiLayoutBox(layout);
03502 
03503         switch (RNA_enum_get(ptr, "type")) {
03504 
03505                 case SENS_ACTUATOR:
03506                         draw_sensor_actuator(box, ptr);
03507                         break;
03508                 case SENS_ALWAYS:
03509                         break;
03510                 case SENS_ARMATURE:
03511                         draw_sensor_armature(box, ptr);
03512                         break;
03513                 case SENS_COLLISION:
03514                         draw_sensor_collision(box, ptr, C);
03515                         break;
03516                 case SENS_DELAY:
03517                         draw_sensor_delay(box, ptr);
03518                         break;
03519                 case SENS_JOYSTICK:
03520                         draw_sensor_joystick(box, ptr);
03521                         break;
03522                 case SENS_KEYBOARD:
03523                         draw_sensor_keyboard(box, ptr);
03524                         break;
03525                 case SENS_MESSAGE:
03526                         draw_sensor_message(box, ptr);
03527                         break;
03528                 case SENS_MOUSE:
03529                         draw_sensor_mouse(box, ptr);
03530                         break;
03531                 case SENS_NEAR:
03532                         draw_sensor_near(box, ptr);
03533                         break;
03534                 case SENS_PROPERTY:
03535                         draw_sensor_property(box, ptr);
03536                         break;
03537                 case SENS_RADAR:
03538                         draw_sensor_radar(box, ptr);
03539                         break;
03540                 case SENS_RANDOM:
03541                         draw_sensor_random(box, ptr);
03542                         break;
03543                 case SENS_RAY:
03544                         draw_sensor_ray(box, ptr, C);
03545                         break;
03546                 case SENS_TOUCH:
03547                         draw_sensor_touch(box, ptr);
03548                         break;
03549         }
03550 }
03551 
03552 /* Controller code */
03553 static void draw_controller_header(uiLayout *layout, PointerRNA *ptr, int xco, int width, int yco)
03554 {
03555         uiLayout *box, *row, *subrow;
03556         bController *cont= (bController *)ptr->data;
03557 
03558         char state[3];
03559         sprintf(state, "%d", RNA_int_get(ptr, "states"));
03560         
03561         box= uiLayoutBox(layout);
03562         row= uiLayoutRow(box, 0);
03563         
03564         uiItemR(row, ptr, "show_expanded", UI_ITEM_R_NO_BG, "", ICON_NONE);
03565         if(RNA_boolean_get(ptr, "show_expanded")) {
03566                 uiItemR(row, ptr, "type", 0, "", ICON_NONE);
03567                 uiItemR(row, ptr, "name", 0, "", ICON_NONE);
03568                 /* XXX provisory for Blender 2.50Beta */
03569                 uiDefBlockBut(uiLayoutGetBlock(layout), controller_state_mask_menu, cont, state, (short)(xco+width-44), yco, 22+22, UI_UNIT_Y, "Set controller state index (from 1 to 30)");
03570         } else {
03571                 uiItemL(row, controller_name(cont->type), ICON_NONE);
03572                 uiItemL(row, cont->name, ICON_NONE);
03573                 uiItemL(row, state, ICON_NONE);
03574         }
03575 
03576         uiItemR(row, ptr, "use_priority", 0, "", ICON_NONE);
03577 
03578         if(RNA_boolean_get(ptr, "show_expanded")==0) {
03579                 subrow= uiLayoutRow(row, 1);
03580                 uiItemEnumO(subrow, "LOGIC_OT_controller_move", "", ICON_TRIA_UP, "direction", 1); // up
03581                 uiItemEnumO(subrow, "LOGIC_OT_controller_move", "", ICON_TRIA_DOWN, "direction", 2); // down
03582         }
03583         uiItemO(row, "", ICON_X, "LOGIC_OT_controller_remove");
03584 }
03585 
03586 static void draw_controller_expression(uiLayout *layout, PointerRNA *ptr)
03587 {
03588         uiItemR(layout, ptr, "expression", 0, "", ICON_NONE);
03589 }
03590 
03591 static void draw_controller_python(uiLayout *layout, PointerRNA *ptr)
03592 {
03593         uiLayout *split, *subsplit;
03594 
03595         split = uiLayoutSplit(layout, 0.3, 1);
03596         uiItemR(split, ptr, "mode", 0, "", ICON_NONE);
03597         if (RNA_enum_get(ptr, "mode") == CONT_PY_SCRIPT) {
03598                 uiItemR(split, ptr, "text", 0, "", ICON_NONE);
03599         }
03600         else {
03601                 subsplit = uiLayoutSplit(split, 0.8, 0);
03602                 uiItemR(subsplit, ptr, "module", 0, "", ICON_NONE);
03603                 uiItemR(subsplit, ptr, "use_debug", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
03604         }
03605 }
03606 
03607 static void draw_controller_state(uiLayout *UNUSED(layout), PointerRNA *UNUSED(ptr))
03608 {
03609 
03610 }
03611 
03612 static void draw_brick_controller(uiLayout *layout, PointerRNA *ptr)
03613 {
03614         uiLayout *box;
03615         
03616         if (!RNA_boolean_get(ptr, "show_expanded"))
03617                 return;
03618         
03619         box = uiLayoutBox(layout);
03620 
03621         draw_controller_state(box, ptr);
03622         
03623         switch (RNA_enum_get(ptr, "type")) {
03624                 case CONT_LOGIC_AND:
03625                         break;
03626                 case CONT_LOGIC_OR:
03627                         break;
03628                 case CONT_EXPRESSION:
03629                         draw_controller_expression(box, ptr);
03630                         break;
03631                 case CONT_PYTHON:
03632                         draw_controller_python(box, ptr);
03633                         break;
03634                 case CONT_LOGIC_NAND:
03635                         break;
03636                 case CONT_LOGIC_NOR:
03637                         break;
03638                 case CONT_LOGIC_XOR:
03639                         break;
03640                 case CONT_LOGIC_XNOR:
03641                         break;
03642         }
03643 }
03644 
03645 /* Actuator code */
03646 static void draw_actuator_header(uiLayout *layout, PointerRNA *ptr, PointerRNA *logic_ptr)
03647 {
03648         uiLayout *box, *row, *subrow;
03649         bActuator *act= (bActuator *)ptr->data;
03650         
03651         box= uiLayoutBox(layout);
03652         row= uiLayoutRow(box, 0);
03653         
03654         uiItemR(row, ptr, "show_expanded", UI_ITEM_R_NO_BG, "", ICON_NONE);
03655         if(RNA_boolean_get(ptr, "show_expanded")) {
03656                 uiItemR(row, ptr, "type", 0, "", ICON_NONE);
03657                 uiItemR(row, ptr, "name", 0, "", ICON_NONE);
03658         } else {
03659                 uiItemL(row, actuator_name(act->type), ICON_NONE);
03660                 uiItemL(row, act->name, ICON_NONE);
03661         }
03662 
03663         subrow= uiLayoutRow(row, 0);
03664         uiLayoutSetActive(subrow, ((RNA_boolean_get(logic_ptr, "show_actuators_active_states")
03665                                                         && RNA_boolean_get(ptr, "show_expanded")) || RNA_boolean_get(ptr, "pin")));
03666         uiItemR(subrow, ptr, "pin", UI_ITEM_R_NO_BG, "", ICON_NONE);
03667 
03668         if(RNA_boolean_get(ptr, "show_expanded")==0) {
03669                 subrow= uiLayoutRow(row, 1);
03670                 uiItemEnumO(subrow, "LOGIC_OT_actuator_move", "", ICON_TRIA_UP, "direction", 1); // up
03671                 uiItemEnumO(subrow, "LOGIC_OT_actuator_move", "", ICON_TRIA_DOWN, "direction", 2); // down
03672         }
03673         uiItemO(row, "", ICON_X, "LOGIC_OT_actuator_remove");
03674 }
03675 
03676 static void draw_actuator_action(uiLayout *layout, PointerRNA *ptr)
03677 {
03678         Object *ob = (Object *)ptr->id.data;
03679         PointerRNA settings_ptr;
03680         uiLayout *row;
03681 
03682         if(ob->type != OB_ARMATURE){
03683                 uiItemL(layout, "Actuator only available for armatures", ICON_NONE);
03684                 return;
03685         }
03686         RNA_pointer_create((ID *)ob, &RNA_GameObjectSettings, ob, &settings_ptr);
03687 
03688         row= uiLayoutRow(layout, 0);
03689         uiItemR(row, ptr, "play_mode", 0, "", ICON_NONE);
03690         uiItemR(row, ptr, "action", 0, "", ICON_NONE);
03691         uiItemR(row, ptr, "use_continue_last_frame", 0, NULL, ICON_NONE);
03692 
03693         row= uiLayoutRow(layout, 0);
03694         if((RNA_enum_get(ptr, "play_mode") == ACT_ACTION_FROM_PROP))
03695                 uiItemPointerR(row, ptr, "property", &settings_ptr, "properties", NULL, ICON_NONE);
03696 
03697         else {
03698                 uiItemR(row, ptr, "frame_start", 0, NULL, ICON_NONE);
03699                 uiItemR(row, ptr, "frame_end", 0, NULL, ICON_NONE);
03700         }
03701 
03702         row= uiLayoutRow(layout, 0);
03703         uiItemR(row, ptr, "frame_blend_in", 0, NULL, ICON_NONE);
03704         uiItemR(row, ptr, "priority", 0, NULL, ICON_NONE);
03705 
03706         row= uiLayoutRow(layout, 0);
03707         uiItemPointerR(layout, ptr, "frame_property", &settings_ptr, "properties", NULL, ICON_NONE);
03708 
03709 #ifdef __NLA_ACTION_BY_MOTION_ACTUATOR
03710         uiItemR(row, "stride_length", 0, NULL, ICON_NONE);
03711 #endif
03712 }
03713 
03714 static void draw_actuator_armature(uiLayout *layout, PointerRNA *ptr)
03715 {
03716         bActuator *act = (bActuator*)ptr->data;
03717         bArmatureActuator *aa = (bArmatureActuator *) act->data;
03718         Object *ob = (Object *)ptr->id.data;
03719         bConstraint *constraint = NULL;
03720         PointerRNA pose_ptr, pchan_ptr;
03721         PropertyRNA *bones_prop = NULL;
03722 
03723         if(ob->type != OB_ARMATURE){
03724                 uiItemL(layout, "Actuator only available for armatures", ICON_NONE);
03725                 return;
03726         }
03727         
03728         if (ob->pose) {
03729                 RNA_pointer_create((ID *)ob, &RNA_Pose, ob->pose, &pose_ptr);
03730                 bones_prop = RNA_struct_find_property(&pose_ptr, "bones");
03731         }
03732         
03733         uiItemR(layout, ptr, "mode", 0, NULL, ICON_NONE);
03734         
03735         switch (RNA_enum_get(ptr, "mode"))
03736         {
03737                 case ACT_ARM_RUN:
03738                         break;
03739                 case ACT_ARM_ENABLE:
03740                 case ACT_ARM_DISABLE:
03741                         if (ob->pose) {
03742                                 uiItemPointerR(layout, ptr, "bone", &pose_ptr, "bones", NULL, ICON_BONE_DATA);
03743 
03744                                 if (RNA_property_collection_lookup_string(&pose_ptr, bones_prop, aa->posechannel, &pchan_ptr))
03745                                         uiItemPointerR(layout, ptr, "constraint", &pchan_ptr, "constraints", NULL, ICON_CONSTRAINT_BONE);
03746                         }
03747                         break;
03748                 case ACT_ARM_SETTARGET:
03749                         if (ob->pose) {
03750                                 uiItemPointerR(layout, ptr, "bone", &pose_ptr, "bones", NULL, ICON_BONE_DATA);
03751                                 
03752                                 if (RNA_property_collection_lookup_string(&pose_ptr, bones_prop, aa->posechannel, &pchan_ptr))
03753                                         uiItemPointerR(layout, ptr, "constraint", &pchan_ptr, "constraints", NULL, ICON_CONSTRAINT_BONE);
03754                         }
03755 
03756                         uiItemR(layout, ptr, "target", 0, NULL, ICON_NONE);
03757 
03758                         /* show second target only if the constraint supports it */
03759                         get_armature_bone_constraint(ob, aa->posechannel, aa->constraint, &constraint);
03760                         if (constraint && constraint->type == CONSTRAINT_TYPE_KINEMATIC) {
03761                                 uiItemR(layout, ptr, "secondary_target", 0, NULL, ICON_NONE);
03762                         }
03763                         break;
03764                 case ACT_ARM_SETWEIGHT:
03765                         if (ob->pose) {
03766                                 uiItemPointerR(layout, ptr, "bone", &pose_ptr, "bones", NULL, ICON_BONE_DATA);
03767                                 
03768                                 if (RNA_property_collection_lookup_string(&pose_ptr, bones_prop, aa->posechannel, &pchan_ptr))
03769                                         uiItemPointerR(layout, ptr, "constraint", &pchan_ptr, "constraints", NULL, ICON_CONSTRAINT_BONE);
03770                         }
03771 
03772                         uiItemR(layout, ptr, "weight", 0, NULL, ICON_NONE);
03773                         break;
03774         }
03775 }
03776 
03777 static void draw_actuator_camera(uiLayout *layout, PointerRNA *ptr)
03778 {
03779         uiLayout *row;
03780         uiItemR(layout, ptr, "object", 0, NULL, ICON_NONE);
03781 
03782         row = uiLayoutRow(layout, 0);
03783         uiItemR(row, ptr, "height", 0, NULL, ICON_NONE);
03784         uiItemR(row, ptr, "axis", 0, NULL, ICON_NONE);
03785 
03786         row = uiLayoutRow(layout, 1);
03787         uiItemR(row, ptr, "min", 0, NULL, ICON_NONE);
03788         uiItemR(row, ptr, "max", 0, NULL, ICON_NONE);
03789 
03790         uiItemR(layout, ptr, "damping", 0, NULL, ICON_NONE);
03791 }
03792 
03793 static void draw_actuator_constraint(uiLayout *layout, PointerRNA *ptr, bContext *C)
03794 {
03795         uiLayout *row, *col, *subcol, *split;
03796         PointerRNA main_ptr;
03797 
03798         RNA_main_pointer_create(CTX_data_main(C), &main_ptr);
03799 
03800         uiItemR(layout, ptr, "mode", 0, NULL, ICON_NONE);
03801         switch (RNA_enum_get(ptr, "mode"))
03802         {
03803                 case ACT_CONST_TYPE_LOC:
03804                         uiItemR(layout, ptr, "limit", 0, NULL, ICON_NONE);
03805 
03806                         row = uiLayoutRow(layout, 1);
03807                         uiItemR(row, ptr, "limit_min", 0, NULL, ICON_NONE);
03808                         uiItemR(row, ptr, "limit_max", 0, NULL, ICON_NONE);
03809 
03810                         uiItemR(layout, ptr, "damping", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
03811                         break;
03812 
03813                 case ACT_CONST_TYPE_DIST:
03814                         split = uiLayoutSplit(layout, 0.8, 0);
03815                         uiItemR(split, ptr, "direction", 0, NULL, ICON_NONE);
03816                         row = uiLayoutRow(split, 1);
03817                         uiItemR(row, ptr, "use_local", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
03818                         uiItemR(row, ptr, "use_normal", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
03819 
03820                         row = uiLayoutRow(layout, 0);
03821                         col = uiLayoutColumn(row, 0);
03822                         uiItemL(col, "Range:", ICON_NONE);
03823                         uiItemR(col, ptr, "range", 0, "", ICON_NONE);
03824 
03825                         col = uiLayoutColumn(row, 1);
03826                         uiItemR(col, ptr, "use_force_distance", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
03827                         subcol = uiLayoutColumn(col, 0);
03828                         uiLayoutSetActive(subcol, RNA_boolean_get(ptr, "use_force_distance")==1);
03829                         uiItemR(subcol, ptr, "distance", 0, "", ICON_NONE);
03830 
03831                         uiItemR(layout, ptr, "damping", UI_ITEM_R_SLIDER , NULL, ICON_NONE);
03832 
03833                         split = uiLayoutSplit(layout, 0.15, 0);
03834                         uiItemR(split, ptr, "use_material_detect", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
03835                         if (RNA_boolean_get(ptr, "use_material_detect"))
03836                                 uiItemPointerR(split, ptr, "material", &main_ptr, "materials", NULL, ICON_MATERIAL_DATA);
03837                         else
03838                                 uiItemR(split, ptr, "property", 0, NULL, ICON_NONE);
03839 
03840                         split = uiLayoutSplit(layout, 0.15, 0);
03841                         uiItemR(split, ptr, "use_persistent", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
03842 
03843                         row = uiLayoutRow(split, 1);
03844                         uiItemR(row, ptr, "time", 0, NULL, ICON_NONE);
03845                         uiItemR(row, ptr, "damping_rotation", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
03846                         break;
03847 
03848                 case ACT_CONST_TYPE_ORI:
03849                         uiItemR(layout, ptr, "direction_axis_pos", 0, NULL, ICON_NONE);
03850 
03851                         row=uiLayoutRow(layout, 1);
03852                         uiItemR(row, ptr, "damping", UI_ITEM_R_SLIDER , NULL, ICON_NONE);
03853                         uiItemR(row, ptr, "time", 0, NULL, ICON_NONE);
03854 
03855                         row=uiLayoutRow(layout, 0);
03856                         uiItemR(row, ptr, "rotation_max", 0, NULL, ICON_NONE);
03857 
03858                         row=uiLayoutRow(layout, 1);
03859                         uiItemR(row, ptr, "angle_min", 0, NULL, ICON_NONE);
03860                         uiItemR(row, ptr, "angle_max", 0, NULL, ICON_NONE);
03861                         break;
03862 
03863                 case ACT_CONST_TYPE_FH:
03864                         split=uiLayoutSplit(layout, 0.75, 0);
03865                         row= uiLayoutRow(split, 0);
03866                         uiItemR(row, ptr, "fh_damping", UI_ITEM_R_SLIDER , NULL, ICON_NONE);
03867 
03868                         uiItemR(row, ptr, "fh_height", 0, NULL, ICON_NONE);
03869                         uiItemR(split, ptr, "use_fh_paralel_axis", UI_ITEM_R_TOGGLE , NULL, ICON_NONE);
03870 
03871                         row = uiLayoutRow(layout, 0);
03872                         uiItemR(row, ptr, "direction_axis", 0, NULL, ICON_NONE);
03873                         split = uiLayoutSplit(row, 0.9, 0);
03874                         uiItemR(split, ptr, "fh_force", 0, NULL, ICON_NONE);
03875                         uiItemR(split, ptr, "use_fh_normal", UI_ITEM_R_TOGGLE , NULL, ICON_NONE);
03876 
03877                         split = uiLayoutSplit(layout, 0.15, 0);
03878                         uiItemR(split, ptr, "use_material_detect", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
03879                         if (RNA_boolean_get(ptr, "use_material_detect"))
03880                                 uiItemPointerR(split, ptr, "material", &main_ptr, "materials", NULL, ICON_MATERIAL_DATA);
03881                         else
03882                                 uiItemR(split, ptr, "property", 0, NULL, ICON_NONE);
03883 
03884                         split = uiLayoutSplit(layout, 0.15, 0);
03885                         uiItemR(split, ptr, "use_persistent", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
03886 
03887                         row = uiLayoutRow(split, 0);
03888                         uiItemR(row, ptr, "time", 0, NULL, ICON_NONE);
03889                         uiItemR(row, ptr, "damping_rotation", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
03890                         break;
03891         }
03892 }
03893 
03894 static void draw_actuator_edit_object(uiLayout *layout, PointerRNA *ptr)
03895 {
03896         Object *ob = (Object *)ptr->id.data;
03897         uiLayout *row, *split, *subsplit;
03898         uiItemR(layout, ptr, "mode", 0, NULL, ICON_NONE);
03899 
03900         switch (RNA_enum_get(ptr, "mode"))
03901         {
03902                 case ACT_EDOB_ADD_OBJECT:
03903                         row = uiLayoutRow(layout, 0);
03904                         uiItemR(row, ptr, "object", 0, NULL, ICON_NONE);
03905                         uiItemR(row, ptr, "time", 0, NULL, ICON_NONE);
03906 
03907                         split = uiLayoutSplit(layout, 0.9, 0);
03908                         row = uiLayoutRow(split, 0);
03909                         uiItemR(row, ptr, "linear_velocity", 0, NULL, ICON_NONE);
03910                         uiItemR(split, ptr, "use_local_linear_velocity", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
03911 
03912                         split = uiLayoutSplit(layout, 0.9, 0);
03913                         row = uiLayoutRow(split, 0);
03914                         uiItemR(row, ptr, "angular_velocity", 0, NULL, ICON_NONE);
03915                         uiItemR(split, ptr, "use_local_angular_velocity", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
03916                         break;
03917                 case ACT_EDOB_END_OBJECT:
03918                         break;
03919                 case ACT_EDOB_REPLACE_MESH:
03920                         if(ob->type != OB_MESH) {
03921                                 uiItemL(layout, "Mode only available for mesh objects", ICON_NONE);
03922                                 break;
03923                         }
03924                         split = uiLayoutSplit(layout, 0.6, 0);
03925                         uiItemR(split, ptr, "mesh", 0, NULL, ICON_NONE);
03926                         row = uiLayoutRow(split, 0);
03927                         uiItemR(row, ptr, "use_replace_display_mesh", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
03928                         uiItemR(row, ptr, "use_replace_physics_mesh", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
03929                         break;
03930                 case ACT_EDOB_TRACK_TO:
03931                         split = uiLayoutSplit(layout, 0.5, 0);
03932                         uiItemR(split, ptr, "track_object", 0, NULL, ICON_NONE);
03933                         subsplit = uiLayoutSplit(split, 0.7, 0);
03934                         uiItemR(subsplit, ptr, "time", 0, NULL, ICON_NONE);
03935                         uiItemR(subsplit, ptr, "use_3d_tracking", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
03936                         break;
03937                 case ACT_EDOB_DYNAMICS:
03938                         if(ob->type != OB_MESH) {
03939                                 uiItemL(layout, "Mode only available for mesh objects", ICON_NONE);
03940                                 break;
03941                         }
03942                         uiItemR(layout, ptr, "dynamic_operation", 0, NULL, ICON_NONE);
03943                         if (RNA_enum_get(ptr, "dynamic_operation") == ACT_EDOB_SET_MASS)
03944                                 uiItemR(layout, ptr, "mass", 0, NULL, ICON_NONE);
03945                         break;
03946         }
03947 }
03948 
03949 static void draw_actuator_filter_2d(uiLayout *layout, PointerRNA *ptr)
03950 {
03951         uiLayout *row, *split;
03952 
03953         uiItemR(layout, ptr, "mode", 0, NULL, ICON_NONE);
03954         switch (RNA_enum_get(ptr, "mode"))
03955         {
03956                 case ACT_2DFILTER_CUSTOMFILTER:
03957                         uiItemR(layout, ptr, "filter_pass", 0, NULL, ICON_NONE);
03958                         uiItemR(layout, ptr, "glsl_shader", 0, NULL, ICON_NONE);
03959                         break;
03960                 case ACT_2DFILTER_MOTIONBLUR:
03961                         split=uiLayoutSplit(layout, 0.75, 1);
03962                         row= uiLayoutRow(split, 0);
03963                         uiLayoutSetActive(row, RNA_boolean_get(ptr, "use_motion_blur")==1);
03964                         uiItemR(row, ptr, "motion_blur_factor", 0, NULL, ICON_NONE);
03965                         uiItemR(split, ptr, "use_motion_blur", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
03966                         break;
03967                 default: // all other 2D Filters
03968                         uiItemR(layout, ptr, "filter_pass", 0, NULL, ICON_NONE);
03969                         break;
03970         }
03971 }
03972 
03973 static void draw_actuator_game(uiLayout *layout, PointerRNA *ptr)
03974 {
03975         uiItemR(layout, ptr, "mode", 0, NULL, ICON_NONE);
03976         if (RNA_enum_get(ptr, "mode") == ACT_GAME_LOAD)
03977                 uiItemR(layout, ptr, "filename", 0, NULL, ICON_NONE);
03978 }
03979 
03980 static void draw_actuator_ipo(uiLayout *layout, PointerRNA *ptr)
03981 {
03982         Object *ob;
03983         PointerRNA settings_ptr;
03984         uiLayout *row, *subrow, *col;
03985 
03986         ob = (Object *)ptr->id.data;
03987         RNA_pointer_create((ID *)ob, &RNA_GameObjectSettings, ob, &settings_ptr);
03988 
03989         row= uiLayoutRow(layout, 0);
03990         uiItemR(row, ptr, "play_type", 0, "", ICON_NONE);
03991         subrow= uiLayoutRow(row, 1);
03992         uiItemR(subrow, ptr, "use_force", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
03993         uiItemR(subrow, ptr, "use_additive", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
03994 
03995         col = uiLayoutColumn(subrow, 0);
03996         uiLayoutSetActive(col, (RNA_boolean_get(ptr, "use_additive") || RNA_boolean_get(ptr, "use_force")));
03997         uiItemR(col, ptr, "use_local", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
03998 
03999         row= uiLayoutRow(layout, 0);
04000         if((RNA_enum_get(ptr, "play_type") == ACT_IPO_FROM_PROP))
04001                 uiItemPointerR(row, ptr, "property", &settings_ptr, "properties", NULL, ICON_NONE);
04002 
04003         else {
04004                 uiItemR(row, ptr, "frame_start", 0, NULL, ICON_NONE);
04005                 uiItemR(row, ptr, "frame_end", 0, NULL, ICON_NONE);
04006         }
04007         uiItemR(row, ptr, "apply_to_children", 0, NULL, ICON_NONE);
04008 
04009         row= uiLayoutRow(layout, 0);
04010         uiItemPointerR(row, ptr, "frame_property", &settings_ptr, "properties", NULL, ICON_NONE);
04011 }
04012 
04013 static void draw_actuator_message(uiLayout *layout, PointerRNA *ptr, bContext *C)
04014 {
04015         Object *ob;
04016         PointerRNA main_ptr, settings_ptr;
04017         uiLayout *row;
04018 
04019         RNA_main_pointer_create(CTX_data_main(C), &main_ptr);
04020 
04021         ob = (Object *)ptr->id.data;
04022         RNA_pointer_create((ID *)ob, &RNA_GameObjectSettings, ob, &settings_ptr);
04023 
04024         uiItemPointerR(layout, ptr, "to_property", &main_ptr, "objects", NULL, ICON_OBJECT_DATA);
04025         uiItemR(layout, ptr, "subject", 0, NULL, ICON_NONE);
04026 
04027         row= uiLayoutRow(layout, 1);
04028         uiItemR(row, ptr, "body_type", 0, NULL, ICON_NONE);
04029 
04030         if(RNA_enum_get(ptr, "body_type") == ACT_MESG_MESG)
04031                 uiItemR(row, ptr, "body_message", 0, "", ICON_NONE);
04032         else // mode == ACT_MESG_PROP
04033                 uiItemPointerR(row, ptr, "body_property", &settings_ptr, "properties", "", ICON_NONE);
04034 }
04035 
04036 static void draw_actuator_motion(uiLayout *layout, PointerRNA *ptr)
04037 {
04038         Object *ob;
04039         PointerRNA settings_ptr;
04040         uiLayout *split, *row, *col, *subcol;
04041         int physics_type;
04042 
04043         ob = (Object *)ptr->id.data;    
04044         RNA_pointer_create((ID *)ob, &RNA_GameObjectSettings, ob, &settings_ptr);
04045         physics_type = RNA_enum_get(&settings_ptr, "physics_type");
04046         
04047         uiItemR(layout, ptr, "mode", 0, NULL, ICON_NONE);
04048         
04049         switch (RNA_enum_get(ptr, "mode")) {
04050                 case ACT_OBJECT_NORMAL:
04051                         split = uiLayoutSplit(layout, 0.9, 0);
04052                         row = uiLayoutRow(split, 0);
04053                         uiItemR(row, ptr, "offset_location", 0, NULL, ICON_NONE);
04054                         uiItemR(split, ptr, "use_local_location", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
04055 
04056                         split = uiLayoutSplit(layout, 0.9, 0);
04057                         row = uiLayoutRow(split, 0);
04058                         uiItemR(row, ptr, "offset_rotation", 0, NULL, ICON_NONE);
04059                         uiItemR(split, ptr, "use_local_rotation", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
04060                         
04061                         if (ELEM3(physics_type, OB_BODY_TYPE_DYNAMIC, OB_BODY_TYPE_RIGID, OB_BODY_TYPE_SOFT)) {                 
04062                                 uiItemL(layout, "Dynamic Object Settings:", ICON_NONE);
04063                                 split = uiLayoutSplit(layout, 0.9, 0);
04064                                 row = uiLayoutRow(split, 0);
04065                                 uiItemR(row, ptr, "force", 0, NULL, ICON_NONE);
04066                                 uiItemR(split, ptr, "use_local_force", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
04067 
04068                                 split = uiLayoutSplit(layout, 0.9, 0);
04069                                 row = uiLayoutRow(split, 0);
04070                                 uiItemR(row, ptr, "torque", 0, NULL, ICON_NONE);
04071                                 uiItemR(split, ptr, "use_local_torque", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
04072 
04073                                 split = uiLayoutSplit(layout, 0.9, 0);
04074                                 row = uiLayoutRow(split, 0);
04075                                 uiItemR(row, ptr, "linear_velocity", 0, NULL, ICON_NONE);
04076                                 row = uiLayoutRow(split, 1);
04077                                 uiItemR(row, ptr, "use_local_linear_velocity", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
04078                                 uiItemR(row, ptr, "use_add_linear_velocity", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
04079 
04080                                 split = uiLayoutSplit(layout, 0.9, 0);
04081                                 row = uiLayoutRow(split, 0);
04082                                 uiItemR(row, ptr, "angular_velocity", 0, NULL, ICON_NONE);
04083                                 uiItemR(split, ptr, "use_local_angular_velocity", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
04084 
04085                                 uiItemR(layout, ptr, "damping", 0, NULL, ICON_NONE);
04086                         }
04087                         break;
04088                 case ACT_OBJECT_SERVO:
04089                         uiItemR(layout, ptr, "reference_object", 0, NULL, ICON_NONE);
04090 
04091                         split = uiLayoutSplit(layout, 0.9, 0);
04092                         row = uiLayoutRow(split, 0);
04093                         uiItemR(row, ptr, "linear_velocity", 0, NULL, ICON_NONE);
04094                         uiItemR(split, ptr, "use_local_linear_velocity", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
04095 
04096                         row = uiLayoutRow(layout, 0);
04097                         col = uiLayoutColumn(row, 0);
04098                         uiItemR(col, ptr, "use_servo_limit_x", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
04099                         subcol = uiLayoutColumn(col, 1);
04100                         uiLayoutSetActive(subcol, RNA_boolean_get(ptr, "use_servo_limit_x")==1);
04101                         uiItemR(subcol, ptr, "force_max_x", 0, NULL, ICON_NONE);
04102                         uiItemR(subcol, ptr, "force_min_x", 0, NULL, ICON_NONE);
04103 
04104                         col = uiLayoutColumn(row, 0);
04105                         uiItemR(col, ptr, "use_servo_limit_y", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
04106                         subcol = uiLayoutColumn(col, 1);
04107                         uiLayoutSetActive(subcol, RNA_boolean_get(ptr, "use_servo_limit_y")==1);
04108                         uiItemR(subcol, ptr, "force_max_y", 0, NULL, ICON_NONE);
04109                         uiItemR(subcol, ptr, "force_min_y", 0, NULL, ICON_NONE);
04110 
04111                         col = uiLayoutColumn(row, 0);
04112                         uiItemR(col, ptr, "use_servo_limit_z", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
04113                         subcol = uiLayoutColumn(col, 1);
04114                         uiLayoutSetActive(subcol, RNA_boolean_get(ptr, "use_servo_limit_z")==1);
04115                         uiItemR(subcol, ptr, "force_max_z", 0, NULL, ICON_NONE);
04116                         uiItemR(subcol, ptr, "force_min_z", 0, NULL, ICON_NONE);
04117 
04118                         //XXXACTUATOR missing labels from original 2.49 ui (e.g. Servo, Min, Max, Fast)
04119                         //Layout designers willing to help on that, please compare with 2.49 ui
04120                         // (since the old code is going to be deleted ... soon)
04121 
04122                         col = uiLayoutColumn(layout, 1);
04123                         uiItemR(col, ptr, "proportional_coefficient", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
04124                         uiItemR(col, ptr, "integral_coefficient", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
04125                         uiItemR(col, ptr, "derivate_coefficient", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
04126                         break;
04127         }
04128 }
04129 
04130 static void draw_actuator_parent(uiLayout *layout, PointerRNA *ptr)
04131 {
04132         uiLayout *row, *subrow;
04133 
04134         uiItemR(layout, ptr, "mode", 0, NULL, ICON_NONE);
04135 
04136         if (RNA_enum_get(ptr, "mode") == ACT_PARENT_SET) {
04137                 uiItemR(layout, ptr, "object", 0, NULL, ICON_NONE);
04138 
04139                 row = uiLayoutRow(layout, 0);
04140                 uiItemR(row, ptr, "use_compound", 0, NULL, ICON_NONE);
04141                 subrow= uiLayoutRow(row, 0);
04142                 uiLayoutSetActive(subrow, RNA_boolean_get(ptr, "use_compound")==1);
04143                 uiItemR(subrow, ptr, "use_ghost", 0, NULL, ICON_NONE);
04144         }
04145 }
04146 
04147 static void draw_actuator_property(uiLayout *layout, PointerRNA *ptr)
04148 {
04149         Object *ob = (Object *)ptr->id.data;
04150         bActuator *act = (bActuator *)ptr->data;
04151         bPropertyActuator *pa = (bPropertyActuator *) act->data;
04152         Object *ob_from= pa->ob;
04153         PointerRNA settings_ptr, obj_settings_ptr;
04154 
04155         uiLayout *row, *subrow;
04156 
04157         RNA_pointer_create((ID *)ob, &RNA_GameObjectSettings, ob, &settings_ptr);
04158 
04159         uiItemR(layout, ptr, "mode", 0, NULL, ICON_NONE);
04160         uiItemPointerR(layout, ptr, "property", &settings_ptr, "properties", NULL, ICON_NONE);
04161 
04162         switch(RNA_enum_get(ptr, "mode"))
04163         {
04164                 case ACT_PROP_TOGGLE:
04165                         break;
04166                 case ACT_PROP_ADD:
04167                         uiItemR(layout, ptr, "value", 0, NULL, ICON_NONE);
04168                         break;
04169                 case ACT_PROP_ASSIGN:
04170                         uiItemR(layout, ptr, "value", 0, NULL, ICON_NONE);
04171                         break;
04172                 case ACT_PROP_COPY:
04173                         row = uiLayoutRow(layout, 0);
04174                         uiItemR(row, ptr, "object", 0, NULL, ICON_NONE);
04175                         if(ob_from){
04176                                 RNA_pointer_create((ID *)ob_from, &RNA_GameObjectSettings, ob_from, &obj_settings_ptr);
04177                                 uiItemPointerR(row, ptr, "object_property", &obj_settings_ptr, "properties", NULL, ICON_NONE);
04178                         }else
04179                         {
04180                                 subrow= uiLayoutRow(row, 0);
04181                                 uiLayoutSetActive(subrow, 0);
04182                                 uiItemR(subrow, ptr, "object_property", 0, NULL, ICON_NONE);
04183                         }
04184                         break;
04185         }
04186 }
04187 
04188 static void draw_actuator_random(uiLayout *layout, PointerRNA *ptr)
04189 {
04190         Object *ob;
04191         PointerRNA settings_ptr;
04192         uiLayout *row;
04193 
04194         ob = (Object *)ptr->id.data;
04195         RNA_pointer_create((ID *)ob, &RNA_GameObjectSettings, ob, &settings_ptr);
04196 
04197         row = uiLayoutRow(layout, 0);
04198 
04199         uiItemR(row, ptr, "seed", 0, NULL, ICON_NONE);
04200         uiItemR(row, ptr, "distribution", 0, NULL, ICON_NONE);
04201 
04202         row = uiLayoutRow(layout, 0);
04203         uiItemPointerR(row, ptr, "property", &settings_ptr, "properties", NULL, ICON_NONE);
04204 
04205         row = uiLayoutRow(layout, 0);
04206 
04207         switch (RNA_enum_get(ptr, "distribution")){
04208                 case ACT_RANDOM_BOOL_CONST:
04209                         uiItemR(row, ptr, "use_always_true", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
04210                         break;
04211 
04212                 case ACT_RANDOM_BOOL_UNIFORM:
04213                         uiItemL(row, "Choose between true and false, 50% chance each", ICON_NONE);
04214                         break;
04215 
04216                 case ACT_RANDOM_BOOL_BERNOUILLI:
04217                         uiItemR(row, ptr, "chance", 0, NULL, ICON_NONE);
04218                         break;
04219 
04220                 case ACT_RANDOM_INT_CONST:
04221                         uiItemR(row, ptr, "int_value", 0, NULL, ICON_NONE);
04222                         break;
04223 
04224                 case ACT_RANDOM_INT_UNIFORM:
04225                         uiItemR(row, ptr, "int_min", 0, NULL, ICON_NONE);
04226                         uiItemR(row, ptr, "int_max", 0, NULL, ICON_NONE);
04227                         break;
04228 
04229                 case ACT_RANDOM_INT_POISSON:
04230                         uiItemR(row, ptr, "int_mean", 0, NULL, ICON_NONE);
04231                         break;
04232 
04233                 case ACT_RANDOM_FLOAT_CONST:
04234                         uiItemR(row, ptr, "float_value", 0, NULL, ICON_NONE);
04235                         break;
04236 
04237                 case ACT_RANDOM_FLOAT_UNIFORM:
04238                         uiItemR(row, ptr, "float_min", 0, NULL, ICON_NONE);
04239                         uiItemR(row, ptr, "float_max", 0, NULL, ICON_NONE);
04240                         break;
04241 
04242                 case ACT_RANDOM_FLOAT_NORMAL:
04243                         uiItemR(row, ptr, "float_mean", 0, NULL, ICON_NONE);
04244                         uiItemR(row, ptr, "standard_derivation", 0, NULL, ICON_NONE);
04245                         break;
04246 
04247                 case ACT_RANDOM_FLOAT_NEGATIVE_EXPONENTIAL:
04248                         uiItemR(row, ptr, "half_life_time", 0, NULL, ICON_NONE);
04249                         break;
04250         }
04251 }
04252 
04253 static void draw_actuator_scene(uiLayout *layout, PointerRNA *ptr)
04254 {
04255         uiItemR(layout, ptr, "mode", 0, NULL, ICON_NONE);
04256 
04257         switch (RNA_enum_get(ptr, "mode")) {
04258                 case ACT_SCENE_CAMERA:
04259                         uiItemR(layout, ptr, "camera", 0, NULL, ICON_NONE);
04260                         break;
04261                 case ACT_SCENE_RESTART:
04262                         break;
04263                 default: // ACT_SCENE_SET|ACT_SCENE_ADD_FRONT|ACT_SCENE_ADD_BACK|ACT_SCENE_REMOVE|ACT_SCENE_SUSPEND|ACT_SCENE_RESUME
04264                         uiItemR(layout, ptr, "scene", 0, NULL, ICON_NONE);
04265                         break;
04266         }
04267 }
04268 
04269 static void draw_actuator_shape_action(uiLayout *layout, PointerRNA *ptr)
04270 {
04271         Object *ob = (Object *)ptr->id.data;
04272         PointerRNA settings_ptr;
04273         uiLayout *row;
04274 
04275         if(ob->type != OB_MESH){
04276                 uiItemL(layout, "Actuator only available for mesh objects", ICON_NONE);
04277                 return;
04278         }
04279 
04280         RNA_pointer_create((ID *)ob, &RNA_GameObjectSettings, ob, &settings_ptr);
04281 
04282         row= uiLayoutRow(layout, 0);
04283         uiItemR(row, ptr, "mode", 0, "", ICON_NONE);
04284         uiItemR(row, ptr, "action", 0, "", ICON_NONE);
04285         uiItemR(row, ptr, "use_continue_last_frame", 0, NULL, ICON_NONE);
04286 
04287         row= uiLayoutRow(layout, 0);
04288         if((RNA_enum_get(ptr, "mode") == ACT_ACTION_FROM_PROP))
04289                 uiItemPointerR(row, ptr, "property", &settings_ptr, "properties", NULL, ICON_NONE);
04290 
04291         else {
04292                 uiItemR(row, ptr, "frame_start", 0, NULL, ICON_NONE);
04293                 uiItemR(row, ptr, "frame_end", 0, NULL, ICON_NONE);
04294         }
04295 
04296         row= uiLayoutRow(layout, 0);
04297         uiItemR(row, ptr, "frame_blend_in", 0, NULL, ICON_NONE);
04298         uiItemR(row, ptr, "priority", 0, NULL, ICON_NONE);
04299 
04300         row= uiLayoutRow(layout, 0);
04301         uiItemPointerR(row, ptr, "frame_property", &settings_ptr, "properties", NULL, ICON_NONE);
04302 
04303 #ifdef __NLA_ACTION_BY_MOTION_ACTUATOR
04304         uiItemR(row, "stride_length", 0, NULL, ICON_NONE);
04305 #endif
04306 }
04307 
04308 static void draw_actuator_sound(uiLayout *layout, PointerRNA *ptr, bContext *C)
04309 {
04310         uiLayout *row, *col;
04311 
04312         uiTemplateID(layout, C, ptr, "sound", NULL, "SOUND_OT_open", NULL);
04313         if (!RNA_pointer_get(ptr, "sound").data)
04314         {
04315                 uiItemL(layout, "Select a sound from the list or load a new one", ICON_NONE);
04316                 return;
04317         }
04318         uiItemR(layout, ptr, "mode", 0, NULL, ICON_NONE);
04319 
04320         row = uiLayoutRow(layout, 0);
04321         uiItemR(row, ptr, "volume", 0, NULL, ICON_NONE);
04322         uiItemR(row, ptr, "pitch", 0, NULL, ICON_NONE);
04323 
04324         uiItemR(layout, ptr, "use_sound_3d", 0, NULL, ICON_NONE);
04325         
04326         col = uiLayoutColumn(layout, 0);
04327         uiLayoutSetActive(col, RNA_boolean_get(ptr, "use_sound_3d")==1);
04328 
04329         row = uiLayoutRow(col, 0);
04330         uiItemR(row, ptr, "gain_3d_min", 0, NULL, ICON_NONE);
04331         uiItemR(row, ptr, "gain_3d_max", 0, NULL, ICON_NONE);
04332 
04333         row = uiLayoutRow(col, 0);
04334         uiItemR(row, ptr, "distance_3d_reference", 0, NULL, ICON_NONE);
04335         uiItemR(row, ptr, "distance_3d_max", 0, NULL, ICON_NONE);
04336 
04337         row = uiLayoutRow(col, 0);
04338         uiItemR(row, ptr, "rolloff_factor_3d", 0, NULL, ICON_NONE);
04339         uiItemR(row, ptr, "cone_outer_gain_3d", 0, NULL, ICON_NONE);
04340 
04341         row = uiLayoutRow(col, 0);
04342         uiItemR(row, ptr, "cone_outer_angle_3d", 0, NULL, ICON_NONE);
04343         uiItemR(row, ptr, "cone_inner_angle_3d", 0, NULL, ICON_NONE);
04344 }
04345 
04346 static void draw_actuator_state(uiLayout *layout, PointerRNA *ptr)
04347 {
04348         uiLayout *split;
04349         Object *ob = (Object *)ptr->id.data;
04350         PointerRNA settings_ptr;
04351         RNA_pointer_create((ID *)ob, &RNA_GameObjectSettings, ob, &settings_ptr);
04352 
04353         split = uiLayoutSplit(layout, 0.35, 0);
04354         uiItemR(split, ptr, "operation", 0, NULL, ICON_NONE);
04355 
04356         uiTemplateLayers(split, ptr, "states", &settings_ptr, "used_states", 0);
04357 }
04358 
04359 static void draw_actuator_visibility(uiLayout *layout, PointerRNA *ptr)
04360 {
04361         uiLayout *row;
04362         row = uiLayoutRow(layout, 0);
04363 
04364         uiItemR(row, ptr, "use_visible", 0, NULL, ICON_NONE);
04365         uiItemR(row, ptr, "use_occlusion", 0, NULL, ICON_NONE);
04366         uiItemR(row, ptr, "apply_to_children", 0, NULL, ICON_NONE);
04367 }
04368 
04369 static void draw_brick_actuator(uiLayout *layout, PointerRNA *ptr, bContext *C)
04370 {
04371         uiLayout *box;
04372         
04373         if (!RNA_boolean_get(ptr, "show_expanded"))
04374                 return;
04375         
04376         box = uiLayoutBox(layout);
04377         
04378         switch (RNA_enum_get(ptr, "type")) {
04379                 case ACT_ACTION:
04380                         draw_actuator_action(box, ptr);
04381                         break;
04382                 case ACT_ARMATURE:
04383                         draw_actuator_armature(box, ptr);
04384                         break;
04385                 case ACT_CAMERA:
04386                         draw_actuator_camera(box, ptr);
04387                         break;
04388                 case ACT_CONSTRAINT:
04389                         draw_actuator_constraint(box, ptr, C);
04390                         break;
04391                 case ACT_EDIT_OBJECT:
04392                         draw_actuator_edit_object(box, ptr);
04393                         break;
04394                 case ACT_2DFILTER:
04395                         draw_actuator_filter_2d(box, ptr);
04396                         break;
04397                 case ACT_GAME:
04398                         draw_actuator_game(box, ptr);
04399                         break;
04400                 case ACT_IPO:
04401                         draw_actuator_ipo(box, ptr);
04402                         break;
04403                 case ACT_MESSAGE:
04404                         draw_actuator_message(box, ptr, C);
04405                         break;
04406                 case ACT_OBJECT:
04407                         draw_actuator_motion(box, ptr);
04408                         break;
04409                 case ACT_PARENT:
04410                         draw_actuator_parent(box, ptr);
04411                         break;
04412                 case ACT_PROPERTY:
04413                         draw_actuator_property(box, ptr);
04414                         break;
04415                 case ACT_RANDOM:
04416                         draw_actuator_random(box, ptr);
04417                         break;
04418                 case ACT_SCENE:
04419                         draw_actuator_scene(box, ptr);
04420                         break;
04421                 case ACT_SHAPEACTION:
04422                         draw_actuator_shape_action(box, ptr);
04423                         break;
04424                 case ACT_SOUND:
04425                         draw_actuator_sound(box, ptr, C);
04426                         break;
04427                 case ACT_STATE:
04428                         draw_actuator_state(box, ptr);
04429                         break;
04430                 case ACT_VISIBILITY:
04431                         draw_actuator_visibility(box, ptr);
04432                         break;
04433         }
04434 }
04435 
04436 static void logic_buttons_new(bContext *C, ARegion *ar)
04437 {
04438         SpaceLogic *slogic= CTX_wm_space_logic(C);
04439         Object *ob= CTX_data_active_object(C);
04440         Object *act_ob= ob;
04441         ID **idar;
04442         
04443         PointerRNA logic_ptr, settings_ptr;
04444         
04445         uiLayout *layout, *row, *box;
04446         uiBlock *block;
04447         uiBut *but;
04448         char name[32];
04449         short a, count;
04450         int xco, yco, width;
04451         
04452         if(ob==NULL) return;
04453         
04454         RNA_pointer_create(NULL, &RNA_SpaceLogicEditor, slogic, &logic_ptr);
04455         idar= get_selected_and_linked_obs(C, &count, slogic->scaflag);
04456         
04457         sprintf(name, "buttonswin %p", (void *)ar);
04458         block= uiBeginBlock(C, ar, name, UI_EMBOSS);
04459         uiBlockSetHandleFunc(block, do_logic_buts, NULL);
04460         
04461         /* loop over all objects and set visible/linked flags for the logic bricks */
04462         for(a=0; a<count; a++) {
04463                 bActuator *act;
04464                 bSensor *sens;
04465                 bController *cont;
04466                 int iact;
04467                 short flag;
04468 
04469                 ob= (Object *)idar[a];
04470                 
04471                 /* clean ACT_LINKED and ACT_VISIBLE of all potentially visible actuators so that we can determine which is actually linked/visible */
04472                 act = ob->actuators.first;
04473                 while(act) {
04474                         act->flag &= ~(ACT_LINKED|ACT_VISIBLE);
04475                         act = act->next;
04476                 }
04477                 /* same for sensors */
04478                 sens= ob->sensors.first;
04479                 while(sens) {
04480                         sens->flag &= ~(SENS_VISIBLE);
04481                         sens = sens->next;
04482                 }
04483 
04484                 /* mark the linked and visible actuators */
04485                 cont= ob->controllers.first;
04486                 while(cont) {
04487                         flag = ACT_LINKED;
04488 
04489                         /* this controller is visible, mark all its actuator */
04490                         if ((ob->scaflag & OB_ALLSTATE) || (ob->state & cont->state_mask))
04491                                 flag |= ACT_VISIBLE;
04492 
04493                         for (iact=0; iact<cont->totlinks; iact++) {
04494                                 act = cont->links[iact];
04495                                 if (act)
04496                                         act->flag |= flag;
04497                         }
04498                         cont = cont->next;
04499                 }
04500         }
04501         
04502         /* ****************** Controllers ****************** */
04503         
04504         xco= 420; yco= 170; width= 300;
04505         layout= uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, xco, yco, width, 20, U.uistyles.first);
04506         row = uiLayoutRow(layout, 1);
04507         
04508         uiDefBlockBut(block, controller_menu, NULL, "Controllers", xco-10, yco, 300, UI_UNIT_Y, "");            /* replace this with uiLayout stuff later */
04509         
04510         uiItemR(row, &logic_ptr, "show_controllers_selected_objects", 0, "Sel", ICON_NONE);
04511         uiItemR(row, &logic_ptr, "show_controllers_active_object", 0, "Act", ICON_NONE);
04512         uiItemR(row, &logic_ptr, "show_controllers_linked_controller", 0, "Link", ICON_NONE);
04513 
04514         for(a=0; a<count; a++) {
04515                 bController *cont;
04516                 PointerRNA ptr;
04517                 uiLayout *split, *subsplit, *col;
04518 
04519                 
04520                 ob= (Object *)idar[a];
04521 
04522                 /* only draw the controller common header if "use_visible" */
04523                 if( (ob->scavisflag & OB_VIS_CONT) == 0) continue;
04524         
04525                 /* Drawing the Controller Header common to all Selected Objects */
04526 
04527                 RNA_pointer_create((ID *)ob, &RNA_GameObjectSettings, ob, &settings_ptr);
04528 
04529                 split= uiLayoutSplit(layout, 0.05, 0);
04530                 uiItemR(split, &settings_ptr, "show_state_panel", UI_ITEM_R_NO_BG, "", ICON_DISCLOSURE_TRI_RIGHT);
04531 
04532                 row = uiLayoutRow(split, 1);
04533                 uiDefButBitS(block, TOG, OB_SHOWCONT, B_REDR, ob->id.name+2,(short)(xco-10), yco, (short)(width-30), UI_UNIT_Y, &ob->scaflag, 0, 31, 0, 0, "Object name, click to show/hide controllers");
04534                 if (ob == act_ob)
04535                         uiItemMenuEnumO(row, "LOGIC_OT_controller_add", "type", "Add Controller", ICON_NONE);
04536 
04537                 if (RNA_boolean_get(&settings_ptr, "show_state_panel")) {
04538 
04539                         box= uiLayoutBox(layout);
04540                         split= uiLayoutSplit(box, 0.2, 0);
04541 
04542                         col= uiLayoutColumn(split, 0);
04543                         uiItemL(col, "Visible", ICON_NONE);
04544                         uiItemL(col, "Initial", ICON_NONE);
04545 
04546                         subsplit= uiLayoutSplit(split, 0.85, 0);
04547                         col= uiLayoutColumn(subsplit, 0);
04548                         row= uiLayoutRow(col, 0);
04549                         uiLayoutSetActive(row, RNA_boolean_get(&settings_ptr, "use_all_states")==0);
04550                         uiTemplateLayers(row, &settings_ptr, "states_visible", &settings_ptr, "used_states", 0);
04551                         row= uiLayoutRow(col, 0);
04552                         uiTemplateLayers(row, &settings_ptr, "states_initial", &settings_ptr, "used_states", 0);
04553 
04554                         col= uiLayoutColumn(subsplit, 0);
04555                         uiItemR(col, &settings_ptr, "use_all_states", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
04556                         uiItemR(col, &settings_ptr, "show_debug_state", 0, "", ICON_NONE);
04557                 }
04558 
04559                 /* End of Drawing the Controller Header common to all Selected Objects */
04560 
04561                 if ((ob->scaflag & OB_SHOWCONT) == 0) continue;
04562                 
04563 
04564                 uiItemS(layout);
04565                 
04566                 for(cont= ob->controllers.first; cont; cont=cont->next) {
04567                         RNA_pointer_create((ID *)ob, &RNA_Controller, cont, &ptr);
04568                         
04569                         if (!(ob->scaflag & OB_ALLSTATE) && !(ob->state & cont->state_mask))
04570                                 continue;
04571                         
04572                         /* use two nested splits to align inlinks/links properly */
04573                         split = uiLayoutSplit(layout, 0.05, 0);
04574                         
04575                         /* put inlink button to the left */
04576                         col = uiLayoutColumn(split, 0);
04577                         uiLayoutSetAlignment(col, UI_LAYOUT_ALIGN_LEFT);
04578                         uiDefIconBut(block, INLINK, 0, ICON_INLINK, 0, 0, UI_UNIT_X, UI_UNIT_Y, cont, LINK_CONTROLLER, 0, 0, 0, "");
04579                         
04580                         //col = uiLayoutColumn(split, 1);
04581                         /* nested split for middle and right columns */
04582                         subsplit = uiLayoutSplit(split, 0.95, 0);
04583                         
04584                         col = uiLayoutColumn(subsplit, 1);
04585                         uiLayoutSetContextPointer(col, "controller", &ptr);
04586                         
04587                         /* should make UI template for controller header.. function will do for now */
04588 //                      draw_controller_header(col, &ptr);
04589                         draw_controller_header(col, &ptr, xco, width, yco); //provisory for 2.50 beta
04590 
04591                         /* draw the brick contents */
04592                         draw_brick_controller(col, &ptr);
04593                         
04594                         
04595                         /* put link button to the right */
04596                         col = uiLayoutColumn(subsplit, 0);
04597                         uiLayoutSetAlignment(col, UI_LAYOUT_ALIGN_LEFT);
04598                         but= uiDefIconBut(block, LINK, 0, ICON_LINK, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, "");
04599                         uiSetButLink(but, NULL, (void ***)&(cont->links), &cont->totlinks, LINK_CONTROLLER, LINK_ACTUATOR);
04600                 }
04601         }
04602         uiBlockLayoutResolve(block, NULL, &yco);        /* stores final height in yco */
04603         
04604         
04605         /* ****************** Sensors ****************** */
04606         
04607         xco= 10; yco= 170; width= 340;
04608         layout= uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, xco, yco, width, 20, U.uistyles.first);
04609         row = uiLayoutRow(layout, 1);
04610         
04611         uiDefBlockBut(block, sensor_menu, NULL, "Sensors", xco-10, yco, 300, UI_UNIT_Y, "");            /* replace this with uiLayout stuff later */
04612         
04613         uiItemR(row, &logic_ptr, "show_sensors_selected_objects", 0, "Sel", ICON_NONE);
04614         uiItemR(row, &logic_ptr, "show_sensors_active_object", 0, "Act", ICON_NONE);
04615         uiItemR(row, &logic_ptr, "show_sensors_linked_controller", 0, "Link", ICON_NONE);
04616         uiItemR(row, &logic_ptr, "show_sensors_active_states", 0, "State", ICON_NONE);
04617         
04618         for(a=0; a<count; a++) {
04619                 bSensor *sens;
04620                 PointerRNA ptr;
04621                 
04622                 ob= (Object *)idar[a];
04623 
04624                 /* only draw the sensor common header if "use_visible" */
04625                 if((ob->scavisflag & OB_VIS_SENS) == 0) continue;
04626 
04627                 row = uiLayoutRow(layout, 1);
04628                 uiDefButBitS(block, TOG, OB_SHOWSENS, B_REDR, ob->id.name+2,(short)(xco-10), yco, (short)(width-30), UI_UNIT_Y, &ob->scaflag, 0, 31, 0, 0, "Object name, click to show/hide sensors");
04629                 if (ob == act_ob)
04630                         uiItemMenuEnumO(row, "LOGIC_OT_sensor_add", "type", "Add Sensor", ICON_NONE);
04631                 
04632                 if ((ob->scaflag & OB_SHOWSENS) == 0) continue;
04633                 
04634                 uiItemS(layout);
04635                 
04636                 for(sens= ob->sensors.first; sens; sens=sens->next) {
04637                         RNA_pointer_create((ID *)ob, &RNA_Sensor, sens, &ptr);
04638                         
04639                         if ((ob->scaflag & OB_ALLSTATE) ||
04640                                 !(slogic->scaflag & BUTS_SENS_STATE) ||
04641                                 (sens->totlinks == 0) ||                                                                                        /* always display sensor without links so that is can be edited */
04642                                 (sens->flag & SENS_PIN && slogic->scaflag & BUTS_SENS_STATE) || /* states can hide some sensors, pinned sensors ignore the visible state */
04643                                 (is_sensor_linked(block, sens))
04644                                 )
04645                         {       // gotta check if the current state is visible or not
04646                                 uiLayout *split, *col;
04647                                 
04648                                 /* make as visible, for move operator */
04649                                 sens->flag |= SENS_VISIBLE;
04650 
04651                                 split = uiLayoutSplit(layout, 0.95, 0);
04652                                 col = uiLayoutColumn(split, 1);
04653                                 uiLayoutSetContextPointer(col, "sensor", &ptr);
04654                                 
04655                                 /* should make UI template for sensor header.. function will do for now */
04656                                 draw_sensor_header(col, &ptr, &logic_ptr);
04657                                 
04658                                 /* draw the brick contents */
04659                                 draw_brick_sensor(col, &ptr, C);
04660                                 
04661                                 /* put link button to the right */
04662                                 col = uiLayoutColumn(split, 0);
04663                                 /* use oldskool uiButtons for links for now */
04664                                 but= uiDefIconBut(block, LINK, 0, ICON_LINK, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, "");
04665                                 uiSetButLink(but, NULL, (void ***)&(sens->links), &sens->totlinks, LINK_SENSOR, LINK_CONTROLLER);
04666                         }
04667                 }
04668         }
04669         uiBlockLayoutResolve(block, NULL, &yco);        /* stores final height in yco */
04670         
04671         /* ****************** Actuators ****************** */
04672         
04673         xco= 800; yco= 170; width= 340;
04674         layout= uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, xco, yco, width, 20, U.uistyles.first);
04675         row = uiLayoutRow(layout, 1);
04676         
04677         uiDefBlockBut(block, actuator_menu, NULL, "Actuators", xco-10, yco, 300, UI_UNIT_Y, "");                /* replace this with uiLayout stuff later */
04678         
04679         uiItemR(row, &logic_ptr, "show_actuators_selected_objects", 0, "Sel", ICON_NONE);
04680         uiItemR(row, &logic_ptr, "show_actuators_active_object", 0, "Act", ICON_NONE);
04681         uiItemR(row, &logic_ptr, "show_actuators_linked_controller", 0, "Link", ICON_NONE);
04682         uiItemR(row, &logic_ptr, "show_actuators_active_states", 0, "State", ICON_NONE);
04683         
04684         for(a=0; a<count; a++) {
04685                 bActuator *act;
04686                 PointerRNA ptr;
04687                 
04688                 ob= (Object *)idar[a];
04689 
04690                 /* only draw the actuator common header if "use_visible" */
04691                 if( (ob->scavisflag & OB_VIS_ACT) == 0) continue;
04692 
04693                 row = uiLayoutRow(layout, 1);
04694                 uiDefButBitS(block, TOG, OB_SHOWACT, B_REDR, ob->id.name+2,(short)(xco-10), yco, (short)(width-30), UI_UNIT_Y, &ob->scaflag, 0, 31, 0, 0, "Object name, click to show/hide actuators");
04695                 if (ob == act_ob)
04696                         uiItemMenuEnumO(row, "LOGIC_OT_actuator_add", "type", "Add Actuator", ICON_NONE);
04697 
04698                 if ((ob->scaflag & OB_SHOWACT) == 0) continue;
04699                 
04700                 uiItemS(layout);
04701                 
04702                 for(act= ob->actuators.first; act; act=act->next) {
04703                         
04704                         RNA_pointer_create((ID *)ob, &RNA_Actuator, act, &ptr);
04705                         
04706                         if ((ob->scaflag & OB_ALLSTATE) ||
04707                                 !(slogic->scaflag & BUTS_ACT_STATE) ||
04708                                 !(act->flag & ACT_LINKED) ||            /* always display actuators without links so that is can be edited */
04709                                 (act->flag & ACT_VISIBLE) ||            /* this actuator has visible connection, display it */
04710                                 (act->flag & ACT_PIN && slogic->scaflag & BUTS_ACT_STATE)       /* states can hide some sensors, pinned sensors ignore the visible state */
04711                                 )
04712                         {       // gotta check if the current state is visible or not
04713                                 uiLayout *split, *col;
04714                                 
04715                                 /* make as visible, for move operator */
04716                                 act->flag |= ACT_VISIBLE;
04717 
04718                                 split = uiLayoutSplit(layout, 0.05, 0);
04719                                 
04720                                 /* put inlink button to the left */
04721                                 col = uiLayoutColumn(split, 0);
04722                                 uiDefIconBut(block, INLINK, 0, ICON_INLINK, 0, 0, UI_UNIT_X, UI_UNIT_Y, act, LINK_ACTUATOR, 0, 0, 0, "");
04723 
04724                                 col = uiLayoutColumn(split, 1);
04725                                 uiLayoutSetContextPointer(col, "actuator", &ptr);
04726                                 
04727                                 /* should make UI template for actuator header.. function will do for now */
04728                                 draw_actuator_header(col, &ptr, &logic_ptr);
04729                                 
04730                                 /* draw the brick contents */
04731                                 draw_brick_actuator(col, &ptr, C);
04732                                 
04733                         }
04734                 }
04735         }
04736         uiBlockLayoutResolve(block, NULL, &yco);        /* stores final height in yco */
04737         
04738         
04739         uiComposeLinks(block);
04740         
04741         uiEndBlock(C, block);
04742         uiDrawBlock(C, block);
04743         
04744         if(idar) MEM_freeN(idar);
04745 }
04746 
04747 void logic_buttons(bContext *C, ARegion *ar)
04748 {
04749         Main *bmain= CTX_data_main(C);
04750         SpaceLogic *slogic= CTX_wm_space_logic(C);
04751         Object *ob= CTX_data_active_object(C);
04752         ID **idar;
04753         bSensor *sens;
04754         bController *cont;
04755         bActuator *act;
04756         uiBlock *block;
04757         uiBut *but;
04758         PointerRNA logic_ptr;
04759         int a, iact, stbit, offset;
04760         int xco, yco, width, ycoo;
04761         short count;
04762         char name[32];
04763         /* pin is a bool used for actuator and sensor drawing with states
04764          * pin so changing states dosnt hide the logic brick */
04765         char pin;
04766 
04767         if (G.rt == 0) {
04768                 logic_buttons_new(C, ar);
04769                 return;
04770         }
04771         
04772         if(ob==NULL) return;
04773 //      uiSetButLock(object_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
04774 
04775         sprintf(name, "buttonswin %p", (void *)ar);
04776         block= uiBeginBlock(C, ar, name, UI_EMBOSS);
04777         uiBlockSetHandleFunc(block, do_logic_buts, NULL);
04778 
04779         RNA_pointer_create(NULL, &RNA_SpaceLogicEditor, slogic, &logic_ptr);
04780         
04781         idar= get_selected_and_linked_obs(C, &count, slogic->scaflag);
04782 
04783         /* clean ACT_LINKED and ACT_VISIBLE of all potentially visible actuators so that 
04784            we can determine which is actually linked/visible */
04785         for(a=0; a<count; a++) {
04786                 ob= (Object *)idar[a];
04787                 act= ob->actuators.first;
04788                 while(act) {
04789                         act->flag &= ~(ACT_LINKED|ACT_VISIBLE);
04790                         act = act->next;
04791                 }
04792                 /* same for sensors */
04793                 sens= ob->sensors.first;
04794                 while(sens) {
04795                         sens->flag &= ~(SENS_VISIBLE);
04796                         sens = sens->next;
04797                 }
04798         }
04799                 
04800         /* start with the controller because we need to know which one is visible */
04801         /* ******************************* */
04802         xco= 400; yco= 170; width= 300;
04803 
04804         uiDefBlockBut(block, controller_menu, NULL, "Controllers", xco-10, yco+35, 100, UI_UNIT_Y, "");
04805         
04806         uiBlockBeginAlign(block);
04807         uiDefButBitS(block, TOG, BUTS_CONT_SEL,  B_REDR, "Sel", xco+110, yco+35, (width-100)/3, UI_UNIT_Y, &slogic->scaflag, 0, 0, 0, 0, "Show all selected Objects");
04808         uiDefButBitS(block, TOG, BUTS_CONT_ACT, B_REDR, "Act", xco+110+(width-100)/3, yco+35, (width-100)/3, UI_UNIT_Y, &slogic->scaflag, 0, 0, 0, 0, "Show active Object");
04809         uiDefButBitS(block, TOG, BUTS_CONT_LINK, B_REDR, "Link", xco+110+2*(width-100)/3, yco+35, (width-100)/3, UI_UNIT_Y, &slogic->scaflag, 0, 0, 0, 0, "Show linked Objects to Sensor/Actuator");
04810         uiBlockEndAlign(block);
04811         
04812         for(a=0; a<count; a++) {
04813                 unsigned int controller_state_mask = 0; /* store a bitmask for states that are used */
04814                 
04815                 ob= (Object *)idar[a];
04816 //              uiClearButLock();
04817 //              uiSetButLock(object_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
04818                 if( (ob->scavisflag & OB_VIS_CONT) == 0) continue;
04819 
04820                 /* presume it is only objects for now */
04821                 uiBlockBeginAlign(block);
04822 //              if(ob->controllers.first) uiSetCurFont(block, UI_HELVB);
04823                 uiDefButBitS(block, TOG, OB_SHOWCONT, B_REDR, ob->id.name+2,(short)(xco-10), yco, (short)(width-30), UI_UNIT_Y, &ob->scaflag, 0, 0, 0, 0, "Active Object name");
04824 //              if(ob->controllers.first) uiSetCurFont(block, UI_HELV);
04825                 uiDefButBitS(block, TOG, OB_ADDCONT, B_ADD_CONT, "Add",(short)(xco+width-40), yco, 50, UI_UNIT_Y, &ob->scaflag, 0, 0, 0, 0, "Add a new Controller");
04826                 uiBlockEndAlign(block);
04827                 yco-=20;
04828                 
04829                 /* mark all actuators linked to these controllers */
04830                 /* note that some of these actuators could be from objects that are not in the display list.
04831                    It's ok because those actuators will not be displayed here */
04832                 cont= ob->controllers.first;
04833                 while(cont) {
04834                         for (iact=0; iact<cont->totlinks; iact++) {
04835                                 act = cont->links[iact];
04836                                 if (act)
04837                                         act->flag |= ACT_LINKED;
04838                         }
04839                         controller_state_mask |= cont->state_mask;
04840                         cont = cont->next;
04841                 }
04842 
04843                 if(ob->scaflag & OB_SHOWCONT) {
04844 
04845                         /* first show the state */
04846                         uiDefBlockBut(block, object_state_mask_menu, ob, "State", (short)(xco-10), (short)(yco-10), 36, UI_UNIT_Y, "Object state menu: store and retrieve initial state");
04847 
04848                         if (!ob->state)
04849                                 ob->state = 1;
04850                         for (offset=0; offset<15; offset+=5) {
04851                                 uiBlockBeginAlign(block);
04852                                 for (stbit=0; stbit<5; stbit++) {
04853                                         but = uiDefButBitI(block, controller_state_mask&(1<<(stbit+offset)) ? BUT_TOGDUAL:TOG, 1<<(stbit+offset), stbit+offset, "",     (short)(xco+31+12*stbit+13*offset), yco, 12, 12, (int *)&(ob->state), 0, 0, 0, 0, get_state_name(ob, (short)(stbit+offset)));
04854                                         uiButSetFunc(but, check_state_mask, but, &(ob->state));
04855                                 }
04856                                 for (stbit=0; stbit<5; stbit++) {
04857                                         but = uiDefButBitI(block, controller_state_mask&(1<<(stbit+offset+15)) ? BUT_TOGDUAL:TOG, 1<<(stbit+offset+15), stbit+offset+15, "",    (short)(xco+31+12*stbit+13*offset), yco-12, 12, 12, (int *)&(ob->state), 0, 0, 0, 0, get_state_name(ob, (short)(stbit+offset+15)));
04858                                         uiButSetFunc(but, check_state_mask, but, &(ob->state));
04859                                 }
04860                         }
04861                         uiBlockBeginAlign(block);
04862                         uiDefButBitS(block, TOG, OB_ALLSTATE, B_SET_STATE_BIT, "All",(short)(xco+226), yco-10, 22, UI_UNIT_Y, &ob->scaflag, 0, 0, 0, 0, "Set all state bits");
04863                         uiDefButBitS(block, TOG, OB_INITSTBIT, B_INIT_STATE_BIT, "Ini",(short)(xco+248), yco-10, 22, UI_UNIT_Y, &ob->scaflag, 0, 0, 0, 0, "Set the initial state");
04864                         uiDefButBitS(block, TOG, OB_DEBUGSTATE, 0, "D",(short)(xco+270), yco-10, 15, UI_UNIT_Y, &ob->scaflag, 0, 0, 0, 0, "Print state debug info");
04865                         uiBlockEndAlign(block);
04866 
04867                         yco-=35;
04868                 
04869                         /* display only the controllers that match the current state */
04870                         offset = 0;
04871                         for (stbit=0; stbit<32; stbit++) {
04872                                 if (!(ob->state & (1<<stbit)))
04873                                         continue;
04874                                 /* add a separation between controllers of different states */
04875                                 if (offset) {
04876                                         offset = 0;
04877                                         yco -= 6;
04878                                 }
04879                                 cont= ob->controllers.first;
04880                                 while(cont) {
04881                                         if (cont->state_mask & (1<<stbit)) {
04882                                                 /* this controller is visible, mark all its actuator */
04883                                                 for (iact=0; iact<cont->totlinks; iact++) {
04884                                                         act = cont->links[iact];
04885                                                         if (act)
04886                                                                 act->flag |= ACT_VISIBLE;
04887                                                 }
04888                                                 uiDefIconButBitS(block, TOG, CONT_DEL, B_DEL_CONT, ICON_X,      xco, yco, 22, UI_UNIT_Y, &cont->flag, 0, 0, 0, 0, "Delete Controller");
04889                                                 uiDefIconButBitS(block, ICONTOG, CONT_SHOW, B_REDR, ICON_RIGHTARROW, (short)(xco+width-22), yco, 22, UI_UNIT_Y, &cont->flag, 0, 0, 0, 0, "Controller settings");
04890                                                 uiDefIconButBitS(block, TOG, CONT_PRIO, B_REDR, ICON_BOOKMARKS, (short)(xco+width-66), yco, 22, UI_UNIT_Y, &cont->flag, 0, 0, 0, 0, "Mark controller for execution before all non-marked controllers (good for startup scripts)");
04891 
04892                                                 sprintf(name, "%d", first_bit(cont->state_mask)+1);
04893                                                 uiDefBlockBut(block, controller_state_mask_menu, cont, name, (short)(xco+width-44), yco, 22, UI_UNIT_Y, "Set controller state index (from 1 to 30)");
04894                                 
04895                                                 if(cont->flag & CONT_SHOW) {
04896                                                         cont->otype= cont->type;
04897                                                         uiDefButS(block, MENU, B_CHANGE_CONT, controller_pup(),(short)(xco+22), yco, 70, UI_UNIT_Y, &cont->type, 0, 0, 0, 0, "Controller type");
04898                                                         but= uiDefBut(block, TEX, 1, "", (short)(xco+92), yco, (short)(width-158), UI_UNIT_Y, cont->name, 0, 31, 0, 0, "Controller name");
04899                                                         uiButSetFunc(but, make_unique_prop_names_cb, cont->name, (void*) 0);
04900                                 
04901                                                         ycoo= yco;
04902                                                         yco= draw_controllerbuttons(cont, block, xco, yco, width);
04903                                                         if(yco-6 < ycoo) ycoo= (yco+ycoo-20)/2;
04904                                                 }
04905                                                 else {
04906                                                         cpack(0x999999);
04907                                                         glRecti(xco+22, yco, xco+width-22,yco+19);
04908                                                         but= uiDefBut(block, LABEL, 0, controller_name(cont->type), (short)(xco+22), yco, 70, UI_UNIT_Y, cont, 0, 0, 0, 0, "Controller type");
04909                                                         //uiButSetFunc(but, old_sca_move_controller, cont, NULL);
04910                                                         but= uiDefBut(block, LABEL, 0, cont->name,(short)(xco+92), yco,(short)(width-158), UI_UNIT_Y, cont, 0, 0, 0, 0, "Controller name");
04911                                                         //uiButSetFunc(but, old_sca_move_controller, cont, NULL);
04912 
04913                                                         uiBlockBeginAlign(block);
04914                                                         but= uiDefIconBut(block, BUT, B_REDR, ICON_TRIA_UP, (short)(xco+width-(110+5)), yco, 22, UI_UNIT_Y, NULL, 0, 0, 0, 0, "Move this logic brick up");
04915                                                         uiButSetFunc(but, old_sca_move_controller, cont, (void *)TRUE);
04916                                                         but= uiDefIconBut(block, BUT, B_REDR, ICON_TRIA_DOWN, (short)(xco+width-(88+5)), yco, 22, UI_UNIT_Y, NULL, 0, 0, 0, 0, "Move this logic brick down");
04917                                                         uiButSetFunc(but, old_sca_move_controller, cont, (void *)FALSE);
04918                                                         uiBlockEndAlign(block);
04919 
04920                                                         ycoo= yco;
04921                                                 }
04922                                 
04923                                                 but= uiDefIconBut(block, LINK, 0, ICON_LINK,    (short)(xco+width), ycoo, UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, "");
04924                                                 uiSetButLink(but, NULL, (void ***)&(cont->links), &cont->totlinks, LINK_CONTROLLER, LINK_ACTUATOR);
04925                                 
04926                                                 uiDefIconBut(block, INLINK, 0, ICON_INLINK,(short)(xco-19), ycoo, UI_UNIT_X, UI_UNIT_Y, cont, LINK_CONTROLLER, 0, 0, 0, "");
04927                                                 /* offset is >0 if at least one controller was displayed */
04928                                                 offset++;
04929                                                 yco-=20;
04930                                         }
04931                                         cont= cont->next;
04932                                 }
04933 
04934                         }
04935                         yco-= 6;
04936                 }
04937         }
04938 
04939         /* ******************************* */
04940         xco= 10; yco= 170; width= 300;
04941 
04942         uiDefBlockBut(block, sensor_menu, NULL, "Sensors", xco-10, yco+35, 70, UI_UNIT_Y, "");
04943         
04944         uiBlockBeginAlign(block);
04945         uiDefButBitS(block, TOG, BUTS_SENS_SEL, B_REDR, "Sel", xco+80, yco+35, (width-70)/4, UI_UNIT_Y, &slogic->scaflag, 0, 0, 0, 0, "Show all selected Objects");
04946         uiDefButBitS(block, TOG, BUTS_SENS_ACT, B_REDR, "Act", xco+80+(width-70)/4, yco+35, (width-70)/4, UI_UNIT_Y, &slogic->scaflag, 0, 0, 0, 0, "Show active Object");
04947         uiDefButBitS(block, TOG, BUTS_SENS_LINK, B_REDR, "Link", xco+80+2*(width-70)/4, yco+35, (width-70)/4, UI_UNIT_Y, &slogic->scaflag, 0, 0, 0, 0, "Show linked Objects to Controller");
04948         uiDefButBitS(block, TOG, BUTS_SENS_STATE, B_REDR, "State", xco+80+3*(width-70)/4, yco+35, (width-70)/4, UI_UNIT_Y, &slogic->scaflag, 0, 0, 0, 0, "Show only sensors connected to active states");
04949         uiBlockEndAlign(block);
04950         
04951         for(a=0; a<count; a++) {
04952                 ob= (Object *)idar[a];
04953 //              uiClearButLock();
04954 //              uiSetButLock(object_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
04955                 
04956                 if( (ob->scavisflag & OB_VIS_SENS) == 0) continue;
04957                 
04958                 /* presume it is only objects for now */
04959                 uiBlockBeginAlign(block);
04960 //              if(ob->sensors.first) uiSetCurFont(block, UI_HELVB);
04961                 uiDefButBitS(block, TOG, OB_SHOWSENS, B_REDR, ob->id.name+2,(short)(xco-10), yco, (short)(width-30), UI_UNIT_Y, &ob->scaflag, 0, 31, 0, 0, "Object name, click to show/hide sensors");
04962 //              if(ob->sensors.first) uiSetCurFont(block, UI_HELV);
04963                 uiDefButBitS(block, TOG, OB_ADDSENS, B_ADD_SENS, "Add",(short)(xco+width-40), yco, 50, UI_UNIT_Y, &ob->scaflag, 0, 0, 0, 0, "Add a new Sensor");
04964                 uiBlockEndAlign(block);
04965                 yco-=20;
04966                 
04967                 if(ob->scaflag & OB_SHOWSENS) {
04968                         
04969                         sens= ob->sensors.first;
04970                         while(sens) {
04971                                 if (!(slogic->scaflag & BUTS_SENS_STATE) ||
04972                                          (sens->totlinks == 0) ||               /* always display sensor without links so that is can be edited */
04973                                          (sens->flag & SENS_PIN && slogic->scaflag & BUTS_SENS_STATE) || /* states can hide some sensors, pinned sensors ignore the visible state */
04974                                          (is_sensor_linked(block, sens))
04975                                 ) {
04976                                         /* should we draw the pin? - for now always draw when there is a state */
04977                                         pin = (slogic->scaflag & BUTS_SENS_STATE && (sens->flag & SENS_SHOW || sens->flag & SENS_PIN)) ? 1:0 ;
04978                                         
04979                                         sens->flag |= SENS_VISIBLE;
04980                                         uiDefIconButBitS(block, TOG, SENS_DEL, B_DEL_SENS, ICON_X,      xco, yco, 22, UI_UNIT_Y, &sens->flag, 0, 0, 0, 0, "Delete Sensor");
04981                                         if (pin)
04982                                                 uiDefIconButBitS(block, ICONTOG, SENS_PIN, B_REDR, ICON_PINNED, (short)(xco+width-44), yco, 22, UI_UNIT_Y, &sens->flag, 0, 0, 0, 0, "Display when not linked to a visible states controller");
04983                                         
04984                                         uiDefIconButBitS(block, ICONTOG, SENS_SHOW, B_REDR, ICON_RIGHTARROW, (short)(xco+width-22), yco, 22, UI_UNIT_Y, &sens->flag, 0, 0, 0, 0, "Sensor settings");
04985 
04986                                         ycoo= yco;
04987                                         if(sens->flag & SENS_SHOW)
04988                                         {
04989                                                 uiDefButS(block, MENU, B_CHANGE_SENS, sensor_pup(),     (short)(xco+22), yco, 80, UI_UNIT_Y, &sens->type, 0, 0, 0, 0, "Sensor type");
04990                                                 but= uiDefBut(block, TEX, 1, "", (short)(xco+102), yco, (short)(width-(pin?146:124)), UI_UNIT_Y, sens->name, 0, 31, 0, 0, "Sensor name");
04991                                                 uiButSetFunc(but, make_unique_prop_names_cb, sens->name, (void*) 0);
04992 
04993                                                 sens->otype= sens->type;
04994                                                 yco= draw_sensorbuttons(ob, sens, block, xco, yco, width);
04995                                                 if(yco-6 < ycoo) ycoo= (yco+ycoo-20)/2;
04996                                         }
04997                                         else {
04998                                                 set_col_sensor(sens->type, 1);
04999                                                 glRecti(xco+22, yco, xco+width-22,yco+19);
05000                                                 but= uiDefBut(block, LABEL, 0, sensor_name(sens->type), (short)(xco+22), yco, 80, UI_UNIT_Y, sens, 0, 0, 0, 0, "");
05001                                                 //uiButSetFunc(but, old_sca_move_sensor, sens, NULL);
05002                                                 but= uiDefBut(block, LABEL, 0, sens->name, (short)(xco+102), yco, (short)(width-(pin?146:124)), UI_UNIT_Y, sens, 0, 31, 0, 0, "");
05003                                                 //uiButSetFunc(but, old_sca_move_sensor, sens, NULL);
05004 
05005                                                 uiBlockBeginAlign(block);
05006                                                 but= uiDefIconBut(block, BUT, B_REDR, ICON_TRIA_UP, (short)(xco+width-(66+5)), yco, 22, UI_UNIT_Y, NULL, 0, 0, 0, 0, "Move this logic brick up");
05007                                                 uiButSetFunc(but, old_sca_move_sensor, sens, (void *)TRUE);
05008                                                 but= uiDefIconBut(block, BUT, B_REDR, ICON_TRIA_DOWN, (short)(xco+width-(44+5)), yco, 22, UI_UNIT_Y, NULL, 0, 0, 0, 0, "Move this logic brick down");
05009                                                 uiButSetFunc(but, old_sca_move_sensor, sens, (void *)FALSE);
05010                                                 uiBlockEndAlign(block);
05011                                         }
05012 
05013                                         but= uiDefIconBut(block, LINK, 0, ICON_LINK,    (short)(xco+width), ycoo, UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, "");
05014                                         uiSetButLink(but, NULL, (void ***)&(sens->links), &sens->totlinks, LINK_SENSOR, LINK_CONTROLLER);
05015 
05016                                         yco-=20;
05017                                 }
05018                                 sens= sens->next;
05019                         }
05020                         yco-= 6;
05021                 }
05022         }
05023         /* ******************************* */
05024         xco= 800; yco= 170; width= 300;
05025         uiDefBlockBut(block, actuator_menu, NULL, "Actuators", xco-10, yco+35, 90, UI_UNIT_Y, "");
05026 
05027         uiBlockBeginAlign(block);
05028         uiDefButBitS(block, TOG, BUTS_ACT_SEL, B_REDR, "Sel", xco+110, yco+35, (width-100)/4, UI_UNIT_Y, &slogic->scaflag, 0, 0, 0, 0, "Show all selected Objects");
05029         uiDefButBitS(block, TOG, BUTS_ACT_ACT, B_REDR, "Act", xco+110+(width-100)/4, yco+35, (width-100)/4, UI_UNIT_Y, &slogic->scaflag, 0, 0, 0, 0, "Show active Object");
05030         uiDefButBitS(block, TOG, BUTS_ACT_LINK, B_REDR, "Link", xco+110+2*(width-100)/4, yco+35, (width-100)/4, UI_UNIT_Y, &slogic->scaflag, 0, 0, 0, 0, "Show linked Objects to Controller");
05031         uiDefButBitS(block, TOG, BUTS_ACT_STATE, B_REDR, "State", xco+110+3*(width-100)/4, yco+35, (width-100)/4, UI_UNIT_Y, &slogic->scaflag, 0, 0, 0, 0, "Show only actuators connected to active states");
05032         uiBlockEndAlign(block);
05033         for(a=0; a<count; a++) {
05034                 ob= (Object *)idar[a];
05035 //              uiClearButLock();
05036 //              uiSetButLock(object_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
05037                 if( (ob->scavisflag & OB_VIS_ACT) == 0) continue;
05038 
05039                 /* presume it is only objects for now */
05040                 uiBlockBeginAlign(block);
05041 //              if(ob->actuators.first) uiSetCurFont(block, UI_HELVB);
05042                 uiDefButBitS(block, TOG, OB_SHOWACT, B_REDR, ob->id.name+2,(short)(xco-10), yco,(short)(width-30), UI_UNIT_Y, &ob->scaflag, 0, 31, 0, 0, "Object name, click to show/hide actuators");
05043 //              if(ob->actuators.first) uiSetCurFont(block, UI_HELV);
05044                 uiDefButBitS(block, TOG, OB_ADDACT, B_ADD_ACT, "Add",(short)(xco+width-40), yco, 50, UI_UNIT_Y, &ob->scaflag, 0, 0, 0, 0, "Add a new Actuator");
05045                 uiBlockEndAlign(block);
05046                 yco-=20;
05047                 
05048                 if(ob->scaflag & OB_SHOWACT) {
05049                         
05050                         act= ob->actuators.first;
05051                         while(act) {
05052                                 if (!(slogic->scaflag & BUTS_ACT_STATE) ||
05053                                         !(act->flag & ACT_LINKED) ||            /* always display actuators without links so that is can be edited */
05054                                          (act->flag & ACT_VISIBLE) ||           /* this actuator has visible connection, display it */
05055                                          (act->flag & ACT_PIN && slogic->scaflag & BUTS_ACT_STATE)) {
05056                                         
05057                                         pin = (slogic->scaflag & BUTS_ACT_STATE && (act->flag & SENS_SHOW || act->flag & SENS_PIN)) ? 1:0 ;
05058                                         
05059                                         act->flag |= ACT_VISIBLE;       /* mark the actuator as visible to help implementing the up/down action */
05060                                         uiDefIconButBitS(block, TOG, ACT_DEL, B_DEL_ACT, ICON_X,        xco, yco, 22, UI_UNIT_Y, &act->flag, 0, 0, 0, 0, "Delete Actuator");
05061                                         if (pin)
05062                                                 uiDefIconButBitS(block, ICONTOG, ACT_PIN, B_REDR, ICON_PINNED, (short)(xco+width-44), yco, 22, UI_UNIT_Y, &act->flag, 0, 0, 0, 0, "Display when not linked to a visible states controller");
05063                                         uiDefIconButBitS(block, ICONTOG, ACT_SHOW, B_REDR, ICON_RIGHTARROW, (short)(xco+width-22), yco, 22, UI_UNIT_Y, &act->flag, 0, 0, 0, 0, "Display the actuator");
05064                                         
05065                                         if(act->flag & ACT_SHOW) {
05066                                                 act->otype= act->type;
05067                                                 uiDefButS(block, MENU, B_CHANGE_ACT, actuator_pup(ob),  (short)(xco+22), yco, 90, UI_UNIT_Y, &act->type, 0, 0, 0, 0, "Actuator type");
05068                                                 but= uiDefBut(block, TEX, 1, "", (short)(xco+112), yco, (short)(width-(pin?156:134)), UI_UNIT_Y, act->name, 0, 31, 0, 0, "Actuator name");
05069                                                 uiButSetFunc(but, make_unique_prop_names_cb, act->name, (void*) 0);
05070 
05071                                                 ycoo= yco;
05072                                                 yco= draw_actuatorbuttons(bmain, ob, act, block, xco, yco, width);
05073                                                 if(yco-6 < ycoo) ycoo= (yco+ycoo-20)/2;
05074                                         }
05075                                         else {
05076                                                 set_col_actuator(act->type, 1);
05077                                                 glRecti((short)(xco+22), yco, (short)(xco+width-22),(short)(yco+19));
05078                                                 /* but= */ uiDefBut(block, LABEL, 0, actuator_name(act->type), (short)(xco+22), yco, 90, UI_UNIT_Y, act, 0, 0, 0, 0, "Actuator type");
05079                                                 // uiButSetFunc(but, old_sca_move_actuator, act, NULL);
05080                                                 /* but= */ uiDefBut(block, LABEL, 0, act->name, (short)(xco+112), yco, (short)(width-(pin?156:134)), UI_UNIT_Y, act, 0, 0, 0, 0, "Actuator name");
05081                                                 // uiButSetFunc(but, old_sca_move_actuator, act, NULL);
05082 
05083                                                 uiBlockBeginAlign(block);
05084                                                 but= uiDefIconBut(block, BUT, B_REDR, ICON_TRIA_UP, (short)(xco+width-(66+5)), yco, 22, UI_UNIT_Y, NULL, 0, 0, 0, 0, "Move this logic brick up");
05085                                                 uiButSetFunc(but, old_sca_move_actuator, act, (void *)TRUE);
05086                                                 but= uiDefIconBut(block, BUT, B_REDR, ICON_TRIA_DOWN, (short)(xco+width-(44+5)), yco, 22, UI_UNIT_Y, NULL, 0, 0, 0, 0, "Move this logic brick down");
05087                                                 uiButSetFunc(but, old_sca_move_actuator, act, (void *)FALSE);
05088                                                 uiBlockEndAlign(block);
05089 
05090                                                 ycoo= yco;
05091                                         }
05092 
05093                                         uiDefIconBut(block, INLINK, 0, ICON_INLINK,(short)(xco-19), ycoo, UI_UNIT_X, UI_UNIT_Y, act, LINK_ACTUATOR, 0, 0, 0, "");
05094 
05095                                         yco-=20;
05096                                 }
05097                                 act= act->next;
05098                         }
05099                         yco-= 6;
05100                 }
05101         }
05102 
05103         uiComposeLinks(block);
05104         
05105         uiEndBlock(C, block);
05106         uiDrawBlock(C, block);
05107 
05108         if(idar) MEM_freeN(idar);
05109 }
05110 
05111 
05112 
05113 
05114 
05115