Blender V2.61 - r43446

logic_window.c

Go to the documentation of this file.
00001 /*
00002  * ***** BEGIN GPL LICENSE BLOCK *****
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License
00006  * as published by the Free Software Foundation; either version 2
00007  * of the License, or (at your option) any later version. 
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software Foundation,
00016  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00017  *
00018  * The Original Code is Copyright (C) 2009 Blender Foundation.
00019  * All rights reserved.
00020  *
00021  * 
00022  * Contributor(s): Blender Foundation
00023  *
00024  * ***** END GPL LICENSE BLOCK *****
00025  */
00026 
00032 #include <string.h>
00033 #include <stdio.h>
00034 #include <stddef.h>
00035 #include <float.h>
00036 
00037 #include "DNA_actuator_types.h"
00038 #include "DNA_controller_types.h"
00039 #include "DNA_property_types.h"
00040 #include "DNA_space_types.h"
00041 #include "DNA_scene_types.h"
00042 #include "DNA_screen_types.h"
00043 #include "DNA_sensor_types.h"
00044 #include "DNA_constraint_types.h"
00045 #include "DNA_windowmanager_types.h"
00046 #include "DNA_object_types.h"
00047 
00048 #include "MEM_guardedalloc.h"
00049 
00050 #include "BLI_blenlib.h"
00051 #include "BLI_utildefines.h"
00052 
00053 #include "BKE_action.h"
00054 #include "BKE_context.h"
00055 #include "BKE_global.h"
00056 #include "BKE_library.h"
00057 #include "BKE_main.h"
00058 #include "BKE_sca.h"
00059 
00060 #include "ED_util.h"
00061 
00062 #include "WM_types.h"
00063 
00064 #include "BIF_gl.h"
00065 
00066 #include "UI_interface.h"
00067 
00068 #include "RNA_access.h"
00069 
00070 /* XXX BAD BAD */
00071 #include "../interface/interface_intern.h"
00072 
00073 #include "logic_intern.h"
00074 
00075 
00076 #define MAX_RENDER_PASS   100
00077 #define B_REDR      1
00078 #define B_IDNAME    2
00079 
00080 #define B_ADD_SENS      2703
00081 #define B_CHANGE_SENS       2704
00082 #define B_DEL_SENS      2705
00083 
00084 #define B_ADD_CONT      2706
00085 #define B_CHANGE_CONT       2707
00086 #define B_DEL_CONT      2708
00087 
00088 #define B_ADD_ACT       2709
00089 #define B_CHANGE_ACT        2710
00090 #define B_DEL_ACT       2711
00091 
00092 #define B_SOUNDACT_BROWSE   2712
00093 
00094 #define B_SETSECTOR     2713
00095 #define B_SETPROP       2714
00096 #define B_SETACTOR      2715
00097 #define B_SETMAINACTOR      2716
00098 #define B_SETDYNA       2717
00099 #define B_SET_STATE_BIT 2718
00100 #define B_INIT_STATE_BIT    2719
00101 
00102 /* proto */
00103 static ID **get_selected_and_linked_obs(bContext *C, short *count, short scavisflag);
00104 
00105 static int vergname(const void *v1, const void *v2)
00106 {
00107     char **x1, **x2;
00108     
00109     x1= (char **)v1;
00110     x2= (char **)v2;
00111     
00112     return strcmp(*x1, *x2);
00113 }
00114 
00115 void make_unique_prop_names(bContext *C, char *str)
00116 {
00117     Object *ob;
00118     bProperty *prop;
00119     bSensor *sens;
00120     bController *cont;
00121     bActuator *act;
00122     ID **idar;
00123     short a, obcount, propcount=0, nr;
00124     char **names;
00125     
00126     /* this function is called by a Button, and gives the current
00127         * stringpointer as an argument, this is the one that can change
00128         */
00129     
00130     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);
00131     
00132     /* for each object, make properties and sca names unique */
00133     
00134     /* count total names */
00135     for(a=0; a<obcount; a++) {
00136         ob= (Object *)idar[a];
00137         propcount+= BLI_countlist(&ob->prop);
00138         propcount+= BLI_countlist(&ob->sensors);
00139         propcount+= BLI_countlist(&ob->controllers);
00140         propcount+= BLI_countlist(&ob->actuators);
00141     }   
00142     if(propcount==0) {
00143         if(idar) MEM_freeN(idar);
00144         return;
00145     }
00146     
00147     /* make names array for sorting */
00148     names= MEM_callocN(propcount*sizeof(void *), "names");
00149     
00150     /* count total names */
00151     nr= 0;
00152     for(a=0; a<obcount; a++) {
00153         ob= (Object *)idar[a];
00154         prop= ob->prop.first;
00155         while(prop) {
00156             names[nr++]= prop->name;
00157             prop= prop->next;
00158         }
00159         sens= ob->sensors.first;
00160         while(sens) {
00161             names[nr++]= sens->name;
00162             sens= sens->next;
00163         }
00164         cont= ob->controllers.first;
00165         while(cont) {
00166             names[nr++]= cont->name;
00167             cont= cont->next;
00168         }
00169         act= ob->actuators.first;
00170         while(act) {
00171             names[nr++]= act->name;
00172             act= act->next;
00173         }
00174     }
00175     
00176     qsort(names, propcount, sizeof(void *), vergname);
00177     
00178     /* now we check for double names, and change them */
00179     
00180     for(nr=0; nr<propcount; nr++) {
00181         if(names[nr]!=str && strcmp( names[nr], str )==0 ) {
00182             BLI_newname(str, +1);
00183         }
00184     }
00185     
00186     MEM_freeN(idar);
00187     MEM_freeN(names);
00188 }
00189 
00190 static void make_unique_prop_names_cb(bContext *C, void *strv, void *UNUSED(redraw_view3d_flagv))
00191 {
00192     char *str= strv;
00193 //  int redraw_view3d_flag= GET_INT_FROM_POINTER(redraw_view3d_flagv);
00194     
00195     make_unique_prop_names(C, str);
00196 }
00197 
00198 
00199 static void old_sca_move_sensor(bContext *C, void *datav, void *move_up)
00200 {
00201     /* deprecated, no longer using it (moved to sca.c) */
00202     Scene *scene= CTX_data_scene(C);
00203     bSensor *sens_to_delete= datav;
00204     int val;
00205     Base *base;
00206     bSensor *sens, *tmp;
00207     
00208     // val= pupmenu("Move up%x1|Move down %x2");
00209     val = move_up ? 1:2;
00210     
00211     if(val>0) {
00212         /* now find out which object has this ... */
00213         base= FIRSTBASE;
00214         while(base) {
00215         
00216             sens= base->object->sensors.first;
00217             while(sens) {
00218                 if(sens == sens_to_delete) break;
00219                 sens= sens->next;
00220             }
00221             
00222             if(sens) {
00223                 if( val==1 && sens->prev) {
00224                     for (tmp=sens->prev; tmp; tmp=tmp->prev) {
00225                         if (tmp->flag & SENS_VISIBLE)
00226                             break;
00227                     }
00228                     if (tmp) {
00229                         BLI_remlink(&base->object->sensors, sens);
00230                         BLI_insertlinkbefore(&base->object->sensors, tmp, sens);
00231                     }
00232                 }
00233                 else if( val==2 && sens->next) {
00234                     for (tmp=sens->next; tmp; tmp=tmp->next) {
00235                         if (tmp->flag & SENS_VISIBLE)
00236                             break;
00237                     }
00238                     if (tmp) {
00239                         BLI_remlink(&base->object->sensors, sens);
00240                         BLI_insertlink(&base->object->sensors, tmp, sens);
00241                     }
00242                 }
00243                 ED_undo_push(C, "Move sensor");
00244                 break;
00245             }
00246             
00247             base= base->next;
00248         }
00249     }
00250 }
00251 
00252 static void old_sca_move_controller(bContext *C, void *datav, void *move_up)
00253 {
00254     /* deprecated, no longer using it (moved to sca.c) */
00255     Scene *scene= CTX_data_scene(C);
00256     bController *controller_to_del= datav;
00257     int val;
00258     Base *base;
00259     bController *cont, *tmp;
00260     
00261     //val= pupmenu("Move up%x1|Move down %x2");
00262     val = move_up ? 1:2;
00263     
00264     if(val>0) {
00265         /* now find out which object has this ... */
00266         base= FIRSTBASE;
00267         while(base) {
00268         
00269             cont= base->object->controllers.first;
00270             while(cont) {
00271                 if(cont == controller_to_del) break;
00272                 cont= cont->next;
00273             }
00274             
00275             if(cont) {
00276                 if( val==1 && cont->prev) {
00277                     /* locate the controller that has the same state mask but is earlier in the list */
00278                     tmp = cont->prev;
00279                     while(tmp) {
00280                         if(tmp->state_mask & cont->state_mask) 
00281                             break;
00282                         tmp = tmp->prev;
00283                     }
00284                     if (tmp) {
00285                         BLI_remlink(&base->object->controllers, cont);
00286                         BLI_insertlinkbefore(&base->object->controllers, tmp, cont);
00287                     }
00288                 }
00289                 else if( val==2 && cont->next) {
00290                     tmp = cont->next;
00291                     while(tmp) {
00292                         if(tmp->state_mask & cont->state_mask) 
00293                             break;
00294                         tmp = tmp->next;
00295                     }
00296                     BLI_remlink(&base->object->controllers, cont);
00297                     BLI_insertlink(&base->object->controllers, tmp, cont);
00298                 }
00299                 ED_undo_push(C, "Move controller");
00300                 break;
00301             }
00302             
00303             base= base->next;
00304         }
00305     }
00306 }
00307 
00308 static void old_sca_move_actuator(bContext *C, void *datav, void *move_up)
00309 {
00310     /* deprecated, no longer using it (moved to sca.c) */
00311     Scene *scene= CTX_data_scene(C);
00312     bActuator *actuator_to_move= datav;
00313     int val;
00314     Base *base;
00315     bActuator *act, *tmp;
00316     
00317     //val= pupmenu("Move up%x1|Move down %x2");
00318     val = move_up ? 1:2;
00319     
00320     if(val>0) {
00321         /* now find out which object has this ... */
00322         base= FIRSTBASE;
00323         while(base) {
00324         
00325             act= base->object->actuators.first;
00326             while(act) {
00327                 if(act == actuator_to_move) break;
00328                 act= act->next;
00329             }
00330             
00331             if(act) {
00332                 if( val==1 && act->prev) {
00333                     /* locate the first visible actuators before this one */
00334                     for (tmp = act->prev; tmp; tmp=tmp->prev) {
00335                         if (tmp->flag & ACT_VISIBLE)
00336                             break;
00337                     }
00338                     if (tmp) {
00339                         BLI_remlink(&base->object->actuators, act);
00340                         BLI_insertlinkbefore(&base->object->actuators, tmp, act);
00341                     }
00342                 }
00343                 else if( val==2 && act->next) {
00344                     for (tmp=act->next; tmp; tmp=tmp->next) {
00345                         if (tmp->flag & ACT_VISIBLE)
00346                             break;
00347                     }
00348                     if (tmp) {
00349                         BLI_remlink(&base->object->actuators, act);
00350                         BLI_insertlink(&base->object->actuators, tmp, act);
00351                     }
00352                 }
00353                 ED_undo_push(C, "Move actuator");
00354                 break;
00355             }
00356             
00357             base= base->next;
00358         }
00359     }
00360 }
00361 
00362 static void do_logic_buts(bContext *C, void *UNUSED(arg), int event)
00363 {
00364     Main *bmain= CTX_data_main(C);
00365     bSensor *sens;
00366     bController *cont;
00367     bActuator *act;
00368     Object *ob;
00369     int didit, bit;
00370     
00371     ob= CTX_data_active_object(C);
00372     if(ob==NULL) return;
00373     
00374     switch(event) {
00375 
00376     case B_SETPROP:
00377         /* check for inconsistent types */
00378         ob->gameflag &= ~(OB_SECTOR|OB_MAINACTOR|OB_DYNAMIC|OB_ACTOR);
00379         break;
00380 
00381     case B_SETACTOR:
00382     case B_SETDYNA:
00383     case B_SETMAINACTOR:
00384         ob->gameflag &= ~(OB_SECTOR|OB_PROP);
00385         break;
00386     
00387     case B_ADD_SENS:
00388         for(ob=bmain->object.first; ob; ob=ob->id.next) {
00389             if(ob->scaflag & OB_ADDSENS) {
00390                 ob->scaflag &= ~OB_ADDSENS;
00391                 sens= new_sensor(SENS_ALWAYS);
00392                 BLI_addtail(&(ob->sensors), sens);
00393                 make_unique_prop_names(C, sens->name);
00394                 ob->scaflag |= OB_SHOWSENS;
00395             }
00396         }
00397         
00398         ED_undo_push(C, "Add sensor");
00399         break;
00400 
00401     case B_CHANGE_SENS:
00402         for(ob=bmain->object.first; ob; ob=ob->id.next) {
00403             sens= ob->sensors.first;
00404             while(sens) {
00405                 if(sens->type != sens->otype) {
00406                     init_sensor(sens);
00407                     sens->otype= sens->type;
00408                     break;
00409                 }
00410                 sens= sens->next;
00411             }
00412         }
00413         break;
00414     
00415     case B_DEL_SENS:
00416         for(ob=bmain->object.first; ob; ob=ob->id.next) {
00417             sens= ob->sensors.first;
00418             while(sens) {
00419                 if(sens->flag & SENS_DEL) {
00420                     BLI_remlink(&(ob->sensors), sens);
00421                     free_sensor(sens);
00422                     break;
00423                 }
00424                 sens= sens->next;
00425             }
00426         }
00427         ED_undo_push(C, "Delete sensor");
00428         break;
00429     
00430     case B_ADD_CONT:
00431         for(ob=bmain->object.first; ob; ob=ob->id.next) {
00432             if(ob->scaflag & OB_ADDCONT) {
00433                 ob->scaflag &= ~OB_ADDCONT;
00434                 cont= new_controller(CONT_LOGIC_AND);
00435                 make_unique_prop_names(C, cont->name);
00436                 ob->scaflag |= OB_SHOWCONT;
00437                 BLI_addtail(&(ob->controllers), cont);
00438                 /* set the controller state mask from the current object state.
00439                    A controller is always in a single state, so select the lowest bit set
00440                    from the object state */
00441                 for (bit=0; bit<32; bit++) {
00442                     if (ob->state & (1<<bit))
00443                         break;
00444                 }
00445                 cont->state_mask = (1<<bit);
00446                 if (cont->state_mask == 0) {
00447                     /* shouldn't happen, object state is never 0 */
00448                     cont->state_mask = 1;
00449                 }
00450             }
00451         }
00452         ED_undo_push(C, "Add controller");
00453         break;
00454 
00455     case B_SET_STATE_BIT:
00456         for(ob=bmain->object.first; ob; ob=ob->id.next) {
00457             if(ob->scaflag & OB_ALLSTATE) {
00458                 ob->scaflag &= ~OB_ALLSTATE;
00459                 ob->state = 0x3FFFFFFF;
00460             }
00461         }
00462         break;
00463 
00464     case B_INIT_STATE_BIT:
00465         for(ob=bmain->object.first; ob; ob=ob->id.next) {
00466             if(ob->scaflag & OB_INITSTBIT) {
00467                 ob->scaflag &= ~OB_INITSTBIT;
00468                 ob->state = ob->init_state;
00469                 if (!ob->state)
00470                     ob->state = 1;
00471             }
00472         }
00473         break;
00474 
00475     case B_CHANGE_CONT:
00476         for(ob=bmain->object.first; ob; ob=ob->id.next) {
00477             cont= ob->controllers.first;
00478             while(cont) {
00479                 if(cont->type != cont->otype) {
00480                     init_controller(cont);
00481                     cont->otype= cont->type;
00482                     break;
00483                 }
00484                 cont= cont->next;
00485             }
00486         }
00487         break;
00488     
00489 
00490     case B_DEL_CONT:
00491         for(ob=bmain->object.first; ob; ob=ob->id.next) {
00492             cont= ob->controllers.first;
00493             while(cont) {
00494                 if(cont->flag & CONT_DEL) {
00495                     BLI_remlink(&(ob->controllers), cont);
00496                     unlink_controller(cont);
00497                     free_controller(cont);
00498                     break;
00499                 }
00500                 cont= cont->next;
00501             }
00502         }
00503         ED_undo_push(C, "Delete controller");
00504         break;
00505 
00506     case B_ADD_ACT:
00507         for(ob=bmain->object.first; ob; ob=ob->id.next) {
00508             if(ob->scaflag & OB_ADDACT) {
00509                 ob->scaflag &= ~OB_ADDACT;
00510                 act= new_actuator(ACT_OBJECT);
00511                 make_unique_prop_names(C, act->name);
00512                 BLI_addtail(&(ob->actuators), act);
00513                 ob->scaflag |= OB_SHOWACT;
00514             }
00515         }
00516         ED_undo_push(C, "Add actuator");
00517         break;
00518 
00519     case B_CHANGE_ACT:
00520         for(ob=bmain->object.first; ob; ob=ob->id.next) {
00521             act= ob->actuators.first;
00522             while(act) {
00523                 if(act->type != act->otype) {
00524                     init_actuator(act);
00525                     act->otype= act->type;
00526                     break;
00527                 }
00528                 act= act->next;
00529             }
00530         }
00531         break;
00532 
00533     case B_DEL_ACT:
00534         for(ob=bmain->object.first; ob; ob=ob->id.next) {
00535             act= ob->actuators.first;
00536             while(act) {
00537                 if(act->flag & ACT_DEL) {
00538                     BLI_remlink(&(ob->actuators), act);
00539                     unlink_actuator(act);
00540                     free_actuator(act);
00541                     break;
00542                 }
00543                 act= act->next;
00544             }
00545         }
00546         ED_undo_push(C, "Delete actuator");
00547         break;
00548     
00549     case B_SOUNDACT_BROWSE:
00550         /* since we don't know which... */
00551         didit= 0;
00552         for(ob=bmain->object.first; ob; ob=ob->id.next) {
00553             act= ob->actuators.first;
00554             while(act)
00555             {
00556                 if(act->type==ACT_SOUND)
00557                 {
00558                     bSoundActuator *sa= act->data;
00559                     if(sa->sndnr)
00560                     {
00561                         ID *sound= bmain->sound.first;
00562                         int nr= 1;
00563 
00564                         if(sa->sndnr == -2) {
00565 // XXX                          activate_databrowse((ID *)bmain->sound.first, ID_SO, 0, B_SOUNDACT_BROWSE,
00566 //                                          &sa->sndnr, do_logic_buts);
00567                             break;
00568                         }
00569 
00570                         while(sound)
00571                         {
00572                             if(nr==sa->sndnr)
00573                                 break;
00574                             nr++;
00575                             sound= sound->next;
00576                         }
00577                         
00578                         if(sa->sound)
00579                             ((ID *)sa->sound)->us--;
00580                         
00581                         sa->sound= (struct bSound *)sound;
00582                         
00583                         if(sound)
00584                             sound->us++;
00585                         
00586                         sa->sndnr= 0;
00587                         didit= 1;
00588                     }
00589                 }
00590                 act= act->next;
00591             }
00592             if(didit)
00593                 break;
00594         }
00595 
00596         break;
00597     }
00598 }
00599 
00600 
00601 static const char *sensor_name(int type)
00602 {
00603     switch (type) {
00604     case SENS_ALWAYS:
00605         return "Always";
00606     case SENS_TOUCH:
00607         return "Touch";
00608     case SENS_NEAR:
00609         return "Near";
00610     case SENS_KEYBOARD:
00611         return "Keyboard";
00612     case SENS_PROPERTY:
00613         return "Property";
00614     case SENS_ARMATURE:
00615         return "Armature";
00616     case SENS_ACTUATOR:
00617         return "Actuator";
00618     case SENS_DELAY:
00619         return "Delay";
00620     case SENS_MOUSE:
00621         return "Mouse";
00622     case SENS_COLLISION:
00623         return "Collision";
00624     case SENS_RADAR:
00625         return "Radar";
00626     case SENS_RANDOM:
00627         return "Random";
00628     case SENS_RAY:
00629         return "Ray";
00630     case SENS_MESSAGE:
00631         return "Message";
00632     case SENS_JOYSTICK:
00633         return "Joystick";
00634     }
00635     return "unknown";
00636 }
00637 
00638 static const char *sensor_pup(void)
00639 {
00640     /* the number needs to match defines in DNA_sensor_types.h */
00641     return "Sensors %t|Always %x0|Delay %x13|Keyboard %x3|Mouse %x5|"
00642         "Touch %x1|Collision %x6|Near %x2|Radar %x7|"
00643         "Property %x4|Random %x8|Ray %x9|Message %x10|Joystick %x11|Actuator %x12|Armature %x14";
00644 }
00645 
00646 static const char *controller_name(int type)
00647 {
00648     switch (type) {
00649     case CONT_LOGIC_AND:
00650         return "And";
00651     case CONT_LOGIC_OR:
00652         return "Or";
00653     case CONT_LOGIC_NAND:
00654         return "Nand";
00655     case CONT_LOGIC_NOR:
00656         return "Nor";
00657     case CONT_LOGIC_XOR:
00658         return "Xor";
00659     case CONT_LOGIC_XNOR:
00660         return "Xnor";
00661     case CONT_EXPRESSION:
00662         return "Expression";
00663     case CONT_PYTHON:
00664         return "Python";
00665     }
00666     return "unknown";
00667 }
00668 
00669 static const char *controller_pup(void)
00670 {
00671     return "Controllers   %t|AND %x0|OR %x1|XOR %x6|NAND %x4|NOR %x5|XNOR %x7|Expression %x2|Python %x3";
00672 }
00673 
00674 static const char *actuator_name(int type)
00675 {
00676     switch (type) {
00677     case ACT_SHAPEACTION:
00678         return "Shape Action";
00679     case ACT_ACTION:
00680         return "Action";
00681     case ACT_OBJECT:
00682         return "Motion";
00683     case ACT_IPO:
00684         return "F-Curve";
00685     case ACT_LAMP:
00686         return "Lamp";
00687     case ACT_CAMERA:
00688         return "Camera";
00689     case ACT_MATERIAL:
00690         return "Material";
00691     case ACT_SOUND:
00692         return "Sound";
00693     case ACT_PROPERTY:
00694         return "Property";
00695     case ACT_EDIT_OBJECT:
00696         return "Edit Object";
00697     case ACT_CONSTRAINT:
00698         return "Constraint";
00699     case ACT_SCENE:
00700         return "Scene";
00701     case ACT_GROUP:
00702         return "Group";
00703     case ACT_RANDOM:
00704         return "Random";
00705     case ACT_MESSAGE:
00706         return "Message";
00707     case ACT_GAME:
00708         return "Game";
00709     case ACT_VISIBILITY:
00710         return "Visibility";
00711     case ACT_2DFILTER:
00712         return "Filter 2D";
00713     case ACT_PARENT:
00714         return "Parent";
00715     case ACT_STATE:
00716         return "State";
00717     case ACT_ARMATURE:
00718         return "Armature";
00719     case ACT_STEERING:
00720         return "Steering";      
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, MAX_NAME, 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, MAX_NAME, 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, MAX_NAME, 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, MAX_NAME, 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, MAX_NAME, 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, MAX_NAME, 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, MAX_NAME, 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, MAX_NAME, 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, MAX_NAME, 0, 0, "check for min value");
01359                 uiDefBut(block, TEX, 1, "Max: ",        xco+width/2,yco-92,width/2, 19,
01360                     ps->maxvalue, 0, MAX_NAME, 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, MAX_NAME, 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, MAX_NAME, 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, MAX_NAME, 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, MAX_NAME, 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, MAX_NAME, 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, MAX_NAME, 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, MAX_NAME, 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, sizeof(ec->str), 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, sizeof(pc->module), 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     case ACT_STEERING:      return TH_PANEL;
01749     default:                return TH_PANEL;
01750     }
01751 }
01752 static void set_col_actuator(int item, int medium) 
01753 {
01754     int col= get_col_actuator(item);
01755     UI_ThemeColorShade(col, medium?30:10);
01756     
01757 }
01758 
01759 static void change_object_actuator(bContext *UNUSED(C), void *act, void *UNUSED(arg))
01760 {
01761     bObjectActuator *oa = act;
01762 
01763     if (oa->type != oa->otype) {
01764         switch (oa->type) {
01765         case ACT_OBJECT_NORMAL:
01766             memset(oa, 0, sizeof(bObjectActuator));
01767             oa->flag = ACT_FORCE_LOCAL|ACT_TORQUE_LOCAL|ACT_DLOC_LOCAL|ACT_DROT_LOCAL;
01768             oa->type = ACT_OBJECT_NORMAL;
01769             break;
01770 
01771         case ACT_OBJECT_SERVO:
01772             memset(oa, 0, sizeof(bObjectActuator));
01773             oa->flag = ACT_LIN_VEL_LOCAL;
01774             oa->type = ACT_OBJECT_SERVO;
01775             oa->forcerot[0] = 30.0f;
01776             oa->forcerot[1] = 0.5f;
01777             oa->forcerot[2] = 0.0f;
01778             break;
01779         }
01780     }
01781 }
01782 
01783 static void change_ipo_actuator(bContext *UNUSED(C), void *arg1_but, void *arg2_ia)
01784 {
01785     bIpoActuator *ia = arg2_ia;
01786     uiBut *but = arg1_but;
01787 
01788     if (but->retval & ACT_IPOFORCE)
01789         ia->flag &= ~ACT_IPOADD;
01790     else if (but->retval & ACT_IPOADD)
01791         ia->flag &= ~ACT_IPOFORCE;
01792     but->retval = B_REDR;
01793 }
01794 
01795 static void update_object_actuator_PID(bContext *UNUSED(C), void *act, void *UNUSED(arg))
01796 {
01797     bObjectActuator *oa = act;
01798     oa->forcerot[0] = 60.0f*oa->forcerot[1];
01799 }
01800 
01801 static char *get_state_name(Object *ob, short bit)
01802 {
01803     bController *cont;
01804     unsigned int mask;
01805 
01806     mask = (1<<bit);
01807     cont = ob->controllers.first;
01808     while (cont) {
01809         if (cont->state_mask & mask) {
01810             return cont->name;
01811         }
01812         cont = cont->next;
01813     }
01814     return (char*)"";
01815 }
01816 
01817 static void check_state_mask(bContext *C, void *arg1_but, void *arg2_mask)
01818 {
01819     wmWindow *win= CTX_wm_window(C);
01820     int shift= win->eventstate->shift;
01821     unsigned int *cont_mask = arg2_mask;
01822     uiBut *but = arg1_but;
01823 
01824     if (*cont_mask == 0 || !(shift))
01825         *cont_mask = (1<<but->retval);
01826     but->retval = B_REDR;
01827 }
01828 
01829 static void check_armature_actuator(bContext *C, void *arg1_but, void *arg2_act)
01830 {
01831     bArmatureActuator *act = arg2_act;
01832     uiBut *but = arg1_but;
01833     Object *ob= CTX_data_active_object(C);
01834 
01835     /* check that bone exist in the active object */
01836     but->retval = B_REDR;
01837     check_armature_bone_constraint(ob, act->posechannel, act->constraint);
01838 }
01839 
01840 
01841 static short draw_actuatorbuttons(Main *bmain, Object *ob, bActuator *act, uiBlock *block, short xco, short yco, short width)
01842 {
01843     bSoundActuator      *sa      = NULL;
01844     bObjectActuator     *oa      = NULL;
01845     bIpoActuator        *ia      = NULL;
01846     bPropertyActuator   *pa      = NULL;
01847     bCameraActuator     *ca      = NULL;
01848     bEditObjectActuator *eoa     = NULL;
01849     bConstraintActuator *coa     = NULL;
01850     bSceneActuator      *sca     = NULL;
01851     bGroupActuator      *ga      = NULL;
01852     bRandomActuator     *randAct = NULL;
01853     bMessageActuator    *ma      = NULL;
01854     bActionActuator     *aa      = NULL;
01855     bGameActuator       *gma     = NULL;
01856     bVisibilityActuator *visAct  = NULL;
01857     bTwoDFilterActuator *tdfa    = NULL;
01858     bParentActuator     *parAct  = NULL;
01859     bStateActuator      *staAct  = NULL;
01860     bArmatureActuator   *armAct  = NULL;
01861     
01862     float *fp;
01863     short ysize = 0, wval;
01864     const char *str;
01865     int myline, stbit;
01866     uiBut *but;
01867 
01868 
01869     /* yco is at the top of the rect, draw downwards */
01870     set_col_actuator(act->type, 0);
01871     
01872     switch (act->type)
01873     {
01874     case ACT_OBJECT:
01875         {
01876             oa = act->data;
01877             wval = (width-100)/3;
01878             if (oa->type == ACT_OBJECT_NORMAL)
01879             {
01880                 if ( ob->gameflag & OB_DYNAMIC )
01881                 {
01882                     ysize= 175;
01883                 }
01884                 else
01885                 {
01886                     ysize= 72;
01887                 }
01888 
01889                 glRects(xco, yco-ysize, xco+width, yco);
01890                 uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
01891                 
01892                 uiBlockBeginAlign(block);
01893                 uiDefBut(block, LABEL, 0, "Loc",    xco, yco-45, 45, 19, NULL, 0, 0, 0, 0, "Sets the location");
01894                 uiDefButF(block, NUM, 0, "",        xco+45, yco-45, wval, 19, oa->dloc, -10000.0, 10000.0, 10, 0, "");
01895                 uiDefButF(block, NUM, 0, "",        xco+45+wval, yco-45, wval, 19, oa->dloc+1, -10000.0, 10000.0, 10, 0, "");
01896                 uiDefButF(block, NUM, 0, "",        xco+45+2*wval, yco-45, wval, 19, oa->dloc+2, -10000.0, 10000.0, 10, 0, "");
01897                 uiBlockEndAlign(block);
01898                 
01899                 uiDefBut(block, LABEL, 0, "Rot",    xco, yco-64, 45, 19, NULL, 0, 0, 0, 0, "Sets the rotation");
01900                 uiBlockBeginAlign(block);
01901                 uiDefButF(block, NUM, 0, "",        xco+45, yco-64, wval, 19, oa->drot, -10000.0, 10000.0, 10, 0, "");
01902                 uiDefButF(block, NUM, 0, "",        xco+45+wval, yco-64, wval, 19, oa->drot+1, -10000.0, 10000.0, 10, 0, "");
01903                 uiDefButF(block, NUM, 0, "",        xco+45+2*wval, yco-64, wval, 19, oa->drot+2, -10000.0, 10000.0, 10, 0, "");
01904                 uiBlockEndAlign(block);
01905 
01906                 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");
01907                 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");
01908     
01909                 if ( ob->gameflag & OB_DYNAMIC )
01910                 {
01911                     uiDefBut(block, LABEL, 0, "Force",  xco, yco-87, 55, 19, NULL, 0, 0, 0, 0, "Sets the force");
01912                     uiBlockBeginAlign(block);
01913                     uiDefButF(block, NUM, 0, "",        xco+45, yco-87, wval, 19, oa->forceloc, -10000.0, 10000.0, 10, 0, "");
01914                     uiDefButF(block, NUM, 0, "",        xco+45+wval, yco-87, wval, 19, oa->forceloc+1, -10000.0, 10000.0, 10, 0, "");
01915                     uiDefButF(block, NUM, 0, "",        xco+45+2*wval, yco-87, wval, 19, oa->forceloc+2, -10000.0, 10000.0, 10, 0, "");
01916                     uiBlockEndAlign(block);
01917 
01918                     uiDefBut(block, LABEL, 0, "Torque", xco, yco-106, 55, 19, NULL, 0, 0, 0, 0, "Sets the torque");
01919                     uiBlockBeginAlign(block);
01920                     uiDefButF(block, NUM, 0, "",        xco+45, yco-106, wval, 19, oa->forcerot, -10000.0, 10000.0, 10, 0, "");
01921                     uiDefButF(block, NUM, 0, "",        xco+45+wval, yco-106, wval, 19, oa->forcerot+1, -10000.0, 10000.0, 10, 0, "");
01922                     uiDefButF(block, NUM, 0, "",        xco+45+2*wval, yco-106, wval, 19, oa->forcerot+2, -10000.0, 10000.0, 10, 0, "");                
01923                     uiBlockEndAlign(block);
01924                 }
01925                 
01926                 if ( ob->gameflag & OB_DYNAMIC )
01927                 {
01928                     uiDefBut(block, LABEL, 0, "LinV",   xco, yco-129, 45, 19, NULL, 0, 0, 0, 0, "Sets the linear velocity");
01929                     uiBlockBeginAlign(block);
01930                     uiDefButF(block, NUM, 0, "",        xco+45, yco-129, wval, 19, oa->linearvelocity, -10000.0, 10000.0, 10, 0, "");
01931                     uiDefButF(block, NUM, 0, "",        xco+45+wval, yco-129, wval, 19, oa->linearvelocity+1, -10000.0, 10000.0, 10, 0, "");
01932                     uiDefButF(block, NUM, 0, "",        xco+45+2*wval, yco-129, wval, 19, oa->linearvelocity+2, -10000.0, 10000.0, 10, 0, "");
01933                     uiBlockEndAlign(block);
01934                 
01935                     uiDefBut(block, LABEL, 0, "AngV",   xco, yco-148, 45, 19, NULL, 0, 0, 0, 0, "Sets the angular velocity");
01936                     uiBlockBeginAlign(block);
01937                     uiDefButF(block, NUM, 0, "",        xco+45, yco-148, wval, 19, oa->angularvelocity, -10000.0, 10000.0, 10, 0, "");
01938                     uiDefButF(block, NUM, 0, "",        xco+45+wval, yco-148, wval, 19, oa->angularvelocity+1, -10000.0, 10000.0, 10, 0, "");
01939                     uiDefButF(block, NUM, 0, "",        xco+45+2*wval, yco-148, wval, 19, oa->angularvelocity+2, -10000.0, 10000.0, 10, 0, "");
01940                     uiBlockEndAlign(block);
01941                 
01942                     uiDefBut(block, LABEL, 0, "Damp",   xco, yco-171, 45, 19, NULL, 0, 0, 0, 0, "Number of frames to reach the target velocity");
01943                     uiDefButS(block, NUM, 0, "",        xco+45, yco-171, wval, 19, &oa->damping, 0.0, 1000.0, 100, 0, "");
01944 
01945                     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");
01946                     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");
01947                     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");
01948                     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");
01949                 
01950                     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");
01951                 }               
01952             } else if (oa->type == ACT_OBJECT_SERVO)
01953             {
01954                 ysize= 195;
01955                 
01956                 glRects(xco, yco-ysize, xco+width, yco);
01957                 uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
01958                 
01959                 uiDefBut(block, LABEL, 0, "Ref",    xco, yco-45, 45, 19, NULL, 0, 0, 0, 0, "");
01960                 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");
01961                 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");
01962                 uiBlockBeginAlign(block);
01963                 uiDefButF(block, NUM, 0, "",        xco+45, yco-68, wval, 19, oa->linearvelocity, -10000.0, 10000.0, 10, 0, "");
01964                 uiDefButF(block, NUM, 0, "",        xco+45+wval, yco-68, wval, 19, oa->linearvelocity+1, -10000.0, 10000.0, 10, 0, "");
01965                 uiDefButF(block, NUM, 0, "",        xco+45+2*wval, yco-68, wval, 19, oa->linearvelocity+2, -10000.0, 10000.0, 10, 0, "");
01966                 uiBlockEndAlign(block);
01967                 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");
01968 
01969                 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)");
01970                 uiBlockBeginAlign(block);
01971                 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");
01972                 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");
01973                 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");
01974                 uiBlockEndAlign(block);
01975                 uiDefBut(block, LABEL, 0, "Max",    xco, yco-110, 45, 19, NULL, 0, 0, 0, 0, "Set the upper limit for force");
01976                 uiDefBut(block, LABEL, 0, "Min",    xco, yco-129, 45, 19, NULL, 0, 0, 0, 0, "Set the lower limit for force");
01977                 if (oa->flag & ACT_SERVO_LIMIT_X) {
01978                     uiDefButF(block, NUM, 0, "",        xco+45, yco-110, wval, 19, oa->dloc, -10000.0, 10000.0, 10, 0, "");
01979                     uiDefButF(block, NUM, 0, "",        xco+45, yco-129, wval, 19, oa->drot, -10000.0, 10000.0, 10, 0, "");
01980                 }
01981                 if (oa->flag & ACT_SERVO_LIMIT_Y) {
01982                     uiDefButF(block, NUM, 0, "",        xco+45+wval, yco-110, wval, 19, oa->dloc+1, -10000.0, 10000.0, 10, 0, "");
01983                     uiDefButF(block, NUM, 0, "",        xco+45+wval, yco-129, wval, 19, oa->drot+1, -10000.0, 10000.0, 10, 0, "");
01984                 }
01985                 if (oa->flag & ACT_SERVO_LIMIT_Z) {
01986                     uiDefButF(block, NUM, 0, "",        xco+45+2*wval, yco-110, wval, 19, oa->dloc+2, -10000.0, 10000.0, 10, 0, "");
01987                     uiDefButF(block, NUM, 0, "",        xco+45+2*wval, yco-129, wval, 19, oa->drot+2, -10000.0, 10000.0, 10, 0, "");
01988                 }
01989                 uiDefBut(block, LABEL, 0, "Servo",  xco, yco-152, 45, 19, NULL, 0, 0, 0, 0, "Coefficients of the PID servo controller");
01990                 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");
01991                 uiDefBut(block, LABEL, 0, "Slow",   xco, yco-171, 45, 19, NULL, 0, 0, 0, 0, "Low value of I coefficient correspond to slow response");
01992                 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");
01993                 uiButSetFunc(but, update_object_actuator_PID, oa, NULL);
01994                 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");
01995                 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");
01996             }
01997             str= "Motion Type %t|Simple motion %x0|Servo Control %x1";
01998             but = uiDefButS(block, MENU, B_REDR, str,       xco+40, yco-23, (width-80), 19, &oa->type, 0.0, 0.0, 0, 0, "");
01999             oa->otype = oa->type;
02000             uiButSetFunc(but, change_object_actuator, oa, NULL);
02001             yco-= ysize;
02002             break;
02003         }
02004     case ACT_ACTION:
02005     case ACT_SHAPEACTION:
02006         {
02007             /* DrawAct */
02008 #ifdef __NLA_ACTION_BY_MOTION_ACTUATOR
02009             ysize = 112;
02010 #else
02011             ysize= 92;
02012 #endif
02013             
02014             glRects(xco, yco-ysize, xco+width, yco);
02015             uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
02016             
02017             aa = act->data;
02018             wval = (width-60)/3;
02019             
02020             //      str= "Action types   %t|Play %x0|Ping Pong %x1|Flipper %x2|Loop Stop %x3|Loop End %x4|Property %x6";
02021 #ifdef __NLA_ACTION_BY_MOTION_ACTUATOR
02022             str= "Action types   %t|Play %x0|Flipper %x2|Loop Stop %x3|Loop End %x4|Property %x6|Displacement %x7";
02023 #else
02024             str= "Action types   %t|Play %x0|Flipper %x2|Loop Stop %x3|Loop End %x4|Property %x6";
02025 #endif
02026             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");
02027             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");
02028             
02029             uiDefButBitS(block, TOGN, 1, 0, "Continue", xco+((width/3)*2)+20, yco-24, 60, 19,
02030                      &aa->end_reset, 0.0, 0.0, 0, 0, "Restore last frame when switching on/off, otherwise play from the start each time");
02031             
02032             
02033             if(aa->type == ACT_ACTION_FROM_PROP)
02034             {
02035                 uiDefBut(block, TEX, 0, "Prop: ",xco+10, yco-44, width-20, 19, aa->name, 0.0, MAX_NAME, 0, 0, "Use this property to define the Action position");
02036             }
02037             else
02038             {
02039                 uiDefButF(block, NUM, 0, "Sta: ",xco+10, yco-44, (width-20)/2, 19, &aa->sta, 1.0, MAXFRAMEF, 0, 0, "Start frame");
02040                 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");
02041             }
02042                         
02043             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");
02044             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");
02045             
02046             uiDefBut(block, TEX, 0, "FrameProp: ",xco+10, yco-84, width-20, 19, aa->frameProp, 0.0, MAX_NAME, 0, 0, "Assign the action's current frame number to this property");
02047 
02048             
02049 #ifdef __NLA_ACTION_BY_MOTION_ACTUATOR
02050             if(aa->type == ACT_ACTION_MOTION)
02051             {
02052                 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");
02053             }
02054 #endif
02055             
02056             
02057             
02058             yco-=ysize;
02059             break;
02060         }
02061     case ACT_IPO:
02062         {
02063             ia= act->data;
02064             
02065             ysize= 72;
02066             
02067             glRects(xco, yco-ysize, xco+width, yco);
02068             uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
02069             
02070             str = "Ipo types   %t|Play %x0|Ping Pong %x1|Flipper %x2|Loop Stop %x3|Loop End %x4|Property %x6";
02071             
02072             uiDefButS(block, MENU, B_REDR, str,     xco+10, yco-24, (width-20)/2, 19, &ia->type, 0, 0, 0, 0, "");
02073 
02074             but = uiDefButBitS(block, TOG, ACT_IPOFORCE, ACT_IPOFORCE, 
02075                 "Force", xco+10+(width-20)/2, yco-24, (width-20)/4-10, 19, 
02076                 &ia->flag, 0, 0, 0, 0, 
02077                 "Apply Ipo as a global or local force depending on the local option (dynamic objects only)"); 
02078             uiButSetFunc(but, change_ipo_actuator, but, ia);
02079 
02080             but = uiDefButBitS(block, TOG, ACT_IPOADD, ACT_IPOADD, 
02081                 "Add", xco+3*(width-20)/4, yco-24, (width-20)/4-10, 19, 
02082                 &ia->flag, 0, 0, 0, 0, 
02083                 "Ipo is added to the current loc/rot/scale in global or local coordinate according to Local flag"); 
02084             uiButSetFunc(but, change_ipo_actuator, but, ia);
02085             
02086             /* Only show the do-force-local toggle if force is requested */
02087             if (ia->flag & (ACT_IPOFORCE|ACT_IPOADD)) {
02088                 uiDefButBitS(block, TOG, ACT_IPOLOCAL, 0, 
02089                     "L", xco+width-30, yco-24, 20, 19, 
02090                     &ia->flag, 0, 0, 0, 0, 
02091                     "Let the ipo acts in local coordinates, used in Force and Add mode"); 
02092             }
02093 
02094             if(ia->type==ACT_IPO_FROM_PROP) {
02095                 uiDefBut(block, TEX, 0, 
02096                     "Prop: ",       xco+10, yco-44, width-80, 19, 
02097                     ia->name, 0.0, MAX_NAME, 0, 0,
02098                     "Use this property to define the Ipo position");
02099             }
02100             else {
02101                 uiDefButF(block, NUM, 0, 
02102                     "Sta",      xco+10, yco-44, (width-80)/2, 19, 
02103                     &ia->sta, 1.0, MAXFRAMEF, 0, 0, 
02104                     "Start frame");
02105                 uiDefButF(block, NUM, 0, 
02106                     "End",      xco+10+(width-80)/2, yco-44, (width-80)/2, 19, 
02107                     &ia->end, 1.0, MAXFRAMEF, 0, 0, 
02108                     "End frame");
02109             }
02110             uiDefButBitS(block, TOG, ACT_IPOCHILD,  B_REDR, 
02111                 "Child",    xco+10+(width-80), yco-44, 60, 19, 
02112                 &ia->flag, 0, 0, 0, 0, 
02113                 "Update IPO on all children Objects as well");
02114             uiDefBut(block, TEX, 0, 
02115                 "FrameProp: ",      xco+10, yco-64, width-20, 19, 
02116                 ia->frameProp, 0.0, MAX_NAME, 0, 0,
02117                 "Assign the action's current frame number to this property");
02118 
02119             yco-= ysize;
02120             break;
02121         }
02122     case ACT_PROPERTY:
02123         {
02124             ysize= 68;
02125             
02126             glRects(xco, yco-ysize, xco+width, yco);
02127             uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
02128             
02129             pa= act->data;
02130             
02131             str= "Type%t|Assign%x0|Add %x1|Copy %x2|Toggle (bool/int/float/timer)%x3";
02132             uiDefButI(block, MENU, B_REDR, str,     xco+30,yco-24,width-60, 19, &pa->type, 0, 31, 0, 0, "Type");
02133             
02134             uiDefBut(block, TEX, 1, "Prop: ",       xco+30,yco-44,width-60, 19, pa->name, 0, MAX_NAME, 0, 0, "Property name");
02135             
02136             
02137             if(pa->type==ACT_PROP_TOGGLE) {
02138                 /* no ui */
02139                 ysize -= 22;
02140             }
02141             else if(pa->type==ACT_PROP_COPY) {
02142                 uiDefIDPoinBut(block, test_obpoin_but, ID_OB, 1, "OB:", xco+10, yco-64, (width-20)/2, 19, &(pa->ob), "Copy from this Object");
02143                 uiDefBut(block, TEX, 1, "Prop: ",       xco+10+(width-20)/2, yco-64, (width-20)/2, 19, pa->value, 0, MAX_NAME, 0, 0, "Copy this property");
02144             }
02145             else {
02146                 uiDefBut(block, TEX, 1, "Value: ",      xco+30,yco-64,width-60, 19, pa->value, 0, MAX_NAME, 0, 0, "change with this value, use \"\" around strings");
02147             }
02148             yco-= ysize;
02149             
02150             break;
02151         }
02152     case ACT_SOUND:
02153         {
02154             sa = act->data;
02155             sa->sndnr = 0;
02156             
02157             if(sa->flag & ACT_SND_3D_SOUND)
02158                 ysize = 180;
02159             else
02160                 ysize = 92;
02161 
02162             wval = (width-20)/2;
02163             glRects(xco, yco-ysize, xco+width, yco);
02164             uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
02165             
02166             if(bmain->sound.first) {
02167                 IDnames_to_pupstring(&str, "Sound files", NULL, &(bmain->sound), (ID *)sa->sound, &(sa->sndnr));
02168                 /* reset this value, it is for handling the event */
02169                 sa->sndnr = 0;
02170                 uiDefButS(block, MENU, B_SOUNDACT_BROWSE, str, xco+10,yco-22,20,19, &(sa->sndnr), 0, 0, 0, 0, "");  
02171                 uiDefButO(block, BUT, "sound.open", 0, "Load Sound", xco+wval+10, yco-22, wval, 19,
02172                           "Load a sound file (remember to set caching on for small sounds that are played often)");
02173 
02174                 if(sa->sound) {
02175                     char dummy_str[] = "Sound mode %t|Play Stop %x0|Play End %x1|Loop Stop %x2|"
02176                                        "Loop End %x3|Loop Ping Pong Stop %x5|Loop Ping Pong %x4";
02177                     uiDefBut(block, TEX, B_IDNAME, "SO:",xco+30,yco-22,wval-20,19,
02178                              ((ID *)sa->sound)->name+2, 0.0, MAX_ID_NAME-2, 0, 0, "");
02179                     uiDefButS(block, MENU, 1, dummy_str,xco+10,yco-44,width-20, 19,
02180                               &sa->type, 0.0, 0.0, 0, 0, "");
02181                     uiDefButF(block, NUM, 0, "Volume:", xco+10,yco-66,wval, 19, &sa->volume,
02182                               0.0, 1.0, 0, 0, "Sets the volume of this sound");
02183                     uiDefButF(block, NUM, 0, "Pitch:",xco+wval+10,yco-66,wval, 19, &sa->pitch,-12.0,
02184                               12.0, 0, 0, "Sets the pitch of this sound");
02185                     uiDefButS(block, TOG | BIT, 0, "3D Sound", xco+10, yco-88, width-20, 19,
02186                               &sa->flag, 0.0, 1.0, 0.0, 0.0, "Plays the sound positioned in 3D space");
02187                     if(sa->flag & ACT_SND_3D_SOUND)
02188                     {
02189                         uiDefButF(block, NUM, 0, "Minimum Gain: ", xco+10, yco-110, wval, 19,
02190                                   &sa->sound3D.min_gain, 0.0, 1.0, 0.0, 0.0,
02191                                   "The minimum gain of the sound, no matter how far it is away");
02192                         uiDefButF(block, NUM, 0, "Maximum Gain: ", xco+10, yco-132, wval, 19,
02193                                   &sa->sound3D.max_gain, 0.0, 1.0, 0.0, 0.0,
02194                                   "The maximum gain of the sound, no matter how near it is");
02195                         uiDefButF(block, NUM, 0, "Reference Distance: ", xco+10, yco-154, wval, 19,
02196                                   &sa->sound3D.reference_distance, 0.0, FLT_MAX, 0.0, 0.0,
02197                                   "The reference distance is the distance where the sound has a gain of 1.0");
02198                         uiDefButF(block, NUM, 0, "Maximum Distance: ", xco+10, yco-176, wval, 19,
02199                                   &sa->sound3D.max_distance, 0.0, FLT_MAX, 0.0, 0.0,
02200                                   "The maximum distance at which you can hear the sound");
02201                         uiDefButF(block, NUM, 0, "Rolloff: ", xco+wval+10, yco-110, wval, 19,
02202                                   &sa->sound3D.rolloff_factor, 0.0, 5.0, 0.0, 0.0,
02203                                   "The rolloff factor defines the influence factor on volume depending on distance");
02204                         uiDefButF(block, NUM, 0, "Cone Outer Gain: ", xco+wval+10, yco-132, wval, 19,
02205                                   &sa->sound3D.cone_outer_gain, 0.0, 1.0, 0.0, 0.0,
02206                                   "The gain outside the outer cone. The gain in the outer cone will be "
02207                                   "interpolated between this value and the normal gain in the inner cone");
02208                         uiDefButF(block, NUM, 0, "Cone Outer Angle: ", xco+wval+10, yco-154, wval,
02209                                   19, &sa->sound3D.cone_outer_angle, 0.0, 360.0, 0.0, 0.0,
02210                                   "The angle of the outer cone");
02211                         uiDefButF(block, NUM, 0, "Cone Inner Angle: ", xco+wval+10, yco-176, wval,
02212                                   19, &sa->sound3D.cone_inner_angle, 0.0, 360.0, 0.0, 0.0,
02213                                   "The angle of the inner cone");
02214                     }
02215                 }
02216                 MEM_freeN((void *)str);
02217             } 
02218             else {
02219                 uiDefButO(block, BUT, "sound.open", 0, "Load Sound", xco+10, yco-22, width-20, 19, "Load a sound file");
02220             }
02221                     
02222             yco-= ysize;
02223             
02224             break;
02225         }
02226     case ACT_CAMERA:
02227 
02228         ysize= 48;
02229 
02230         glRects(xco, yco-ysize, xco+width, yco);
02231         uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
02232         
02233         ca= act->data;
02234 
02235         uiDefIDPoinBut(block, test_obpoin_but, ID_OB, 1, "OB:",     xco+10, yco-24, (width-20)/2, 19, &(ca->ob), "Look at this Object");
02236         uiDefButF(block, NUM, 0, "Height:", xco+10+(width-20)/2, yco-24, (width-20)/2, 19, &ca->height, 0.0, 20.0, 0, 0, "");
02237         
02238         uiDefButF(block, NUM, 0, "Min:",    xco+10, yco-44, (width-60)/2, 19, &ca->min, 0.0, 20.0, 0, 0, "");
02239         
02240         if(ca->axis==0) ca->axis= 'x';
02241         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");
02242         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");
02243         
02244         uiDefButF(block, NUM, 0, "Max:",    xco+20+(width)/2, yco-44, (width-60)/2, 19, &ca->max, 0.0, 20.0, 0, 0, "");
02245 
02246         yco-= ysize;
02247 
02248         break;
02249 
02250     case ACT_EDIT_OBJECT:
02251         
02252         eoa= act->data;
02253 
02254         if(eoa->type==ACT_EDOB_ADD_OBJECT) {
02255             ysize = 92;
02256             glRects(xco, yco-ysize, xco+width, yco);
02257             uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
02258 
02259             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)");
02260             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");
02261 
02262             wval= (width-60)/3;
02263             uiDefBut(block, LABEL, 0, "linV",   xco,           yco-68,   45, 19,
02264                      NULL, 0, 0, 0, 0,
02265                      "Velocity upon creation");
02266             uiDefButF(block, NUM, 0, "",        xco+45,        yco-68, wval, 19,
02267                      eoa->linVelocity, -100.0, 100.0, 10, 0,
02268                      "Velocity upon creation, x component");
02269             uiDefButF(block, NUM, 0, "",        xco+45+wval,   yco-68, wval, 19,
02270                      eoa->linVelocity+1, -100.0, 100.0, 10, 0,
02271                      "Velocity upon creation, y component");
02272             uiDefButF(block, NUM, 0, "",        xco+45+2*wval, yco-68, wval, 19,
02273                      eoa->linVelocity+2, -100.0, 100.0, 10, 0,
02274                      "Velocity upon creation, z component");
02275             uiDefButBitS(block, TOG, ACT_EDOB_LOCAL_LINV, 0, "L", xco+45+3*wval, yco-68, 15, 19,
02276                      &eoa->localflag, 0.0, 0.0, 0, 0,
02277                      "Apply the transformation locally");
02278             
02279             
02280             uiDefBut(block, LABEL, 0, "AngV",   xco,           yco-90,   45, 19,
02281                      NULL, 0, 0, 0, 0,
02282                      "Angular velocity upon creation");
02283             uiDefButF(block, NUM, 0, "",        xco+45,        yco-90, wval, 19,
02284                      eoa->angVelocity, -10000.0, 10000.0, 10, 0,
02285                      "Angular velocity upon creation, x component");
02286             uiDefButF(block, NUM, 0, "",        xco+45+wval,   yco-90, wval, 19,
02287                      eoa->angVelocity+1, -10000.0, 10000.0, 10, 0,
02288                      "Angular velocity upon creation, y component");
02289             uiDefButF(block, NUM, 0, "",        xco+45+2*wval, yco-90, wval, 19,
02290                      eoa->angVelocity+2, -10000.0, 10000.0, 10, 0,
02291                      "Angular velocity upon creation, z component");
02292             uiDefButBitS(block, TOG, ACT_EDOB_LOCAL_ANGV, 0, "L", xco+45+3*wval, yco-90, 15, 19,
02293                      &eoa->localflag, 0.0, 0.0, 0, 0,
02294                      "Apply the rotation locally");
02295                      
02296 
02297         }
02298         else if(eoa->type==ACT_EDOB_END_OBJECT) {
02299             ysize= 28;
02300             glRects(xco, yco-ysize, xco+width, yco);
02301             uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
02302         }
02303         else if(eoa->type==ACT_EDOB_REPLACE_MESH) {
02304             ysize= 48;
02305             glRects(xco, yco-ysize, xco+width, yco);
02306             uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
02307      
02308             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");
02309             
02310             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");
02311             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)");
02312         }
02313         else if(eoa->type==ACT_EDOB_TRACK_TO) {
02314             ysize= 48;
02315             glRects(xco, yco-ysize, xco+width, yco);
02316             uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
02317      
02318             uiDefIDPoinBut(block, test_obpoin_but, ID_OB, 1, "OB:",     xco+10, yco-44, (width-20)/2, 19, &(eoa->ob), "Track to this Object");
02319             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");
02320             uiDefButS(block, TOG, 0, "3D",  xco+width-50, yco-44, 40, 19, &eoa->flag, 0.0, 0.0, 0, 0, "Enable 3D tracking");
02321         }
02322         else if(eoa->type==ACT_EDOB_DYNAMICS) {
02323             ysize= 69;
02324             glRects(xco, yco-ysize, xco+width, yco);
02325             uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
02326             
02327             str= "Dynamic Operation %t|Restore Dynamics %x0|Suspend Dynamics %x1|Enable Rigid Body %x2|Disable Rigid Body %x3|Set Mass %x4";
02328             uiDefButS(block, MENU, B_REDR, str,     xco+40, yco-44, (width-80), 19,  &(eoa->dyn_operation), 0.0, 0.0, 0, 0, "");
02329             if(eoa->dyn_operation==4) {
02330                 uiDefButF(block, NUM, 0, "",        xco+40, yco-63, width-80, 19,
02331                      &eoa->mass, 0.0, 10000.0, 10, 0,
02332                      "Mass for object");
02333             }
02334         }
02335         str= "Edit Object %t|Add Object %x0|End Object %x1|Replace Mesh %x2|Track to %x3|Dynamics %x4";
02336         uiDefButS(block, MENU, B_REDR, str,     xco+40, yco-24, (width-80), 19, &eoa->type, 0.0, 0.0, 0, 0, "");
02337 
02338         yco-= ysize;
02339 
02340         break;
02341 
02342     case ACT_CONSTRAINT:
02343         coa= act->data;
02344     
02345         if (coa->type == ACT_CONST_TYPE_LOC) {
02346             ysize= 69;
02347 
02348             glRects(xco, yco-ysize, xco+width, yco);
02349             uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
02350             
02351     /*          str= "Limit %t|None %x0|Loc X %x1|Loc Y %x2|Loc Z %x4|Rot X %x8|Rot Y %x16|Rot Z %x32"; */
02352     /*          coa->flag &= ~(63); */
02353             str= "Limit %t|None %x0|Loc X %x1|Loc Y %x2|Loc Z %x4";
02354             coa->flag &= 7;
02355             coa->time = 0;
02356             uiDefButS(block, MENU, 1, str,      xco+10, yco-65, 70, 19, &coa->flag, 0.0, 0.0, 0, 0, "");
02357         
02358             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");
02359             uiDefBut(block, LABEL,          0, "Min",   xco+80, yco-45, (width-90)/2, 19, NULL, 0.0, 0.0, 0, 0, "");
02360             uiDefBut(block, LABEL,          0, "Max",   xco+80+(width-90)/2, yco-45, (width-90)/2, 19, NULL, 0.0, 0.0, 0, 0, "");
02361 
02362             if(coa->flag & ACT_CONST_LOCX) fp= coa->minloc;
02363             else if(coa->flag & ACT_CONST_LOCY) fp= coa->minloc+1;
02364             else if(coa->flag & ACT_CONST_LOCZ) fp= coa->minloc+2;
02365             else if(coa->flag & ACT_CONST_ROTX) fp= coa->minrot;
02366             else if(coa->flag & ACT_CONST_ROTY) fp= coa->minrot+1;
02367             else fp= coa->minrot+2;
02368             
02369             uiDefButF(block, NUM, 0, "",        xco+80, yco-65, (width-90)/2, 19, fp, -2000.0, 2000.0, 10, 0, "");
02370             uiDefButF(block, NUM, 0, "",        xco+80+(width-90)/2, yco-65, (width-90)/2, 19, fp+3, -2000.0, 2000.0, 10, 0, "");
02371         } else if (coa->type == ACT_CONST_TYPE_DIST) {
02372             ysize= 106;
02373 
02374             glRects(xco, yco-ysize, xco+width, yco);
02375             uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
02376             
02377             str= "Direction %t|None %x0|X axis %x1|Y axis %x2|Z axis %x4|-X axis %x8|-Y axis %x16|-Z axis %x32";
02378             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");
02379         
02380             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");
02381             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");
02382             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");
02383             uiDefButBitS(block, TOG, ACT_CONST_LOCAL, 0, "L", xco+80+(width-115), yco-45, 25, 19,
02384                      &coa->flag, 0.0, 0.0, 0, 0, "Set ray along object's axis or global axis");
02385 
02386             if(coa->mode & (ACT_CONST_DIRPX|ACT_CONST_DIRNX)) fp= coa->minloc;
02387             else if(coa->mode & (ACT_CONST_DIRPY|ACT_CONST_DIRNY)) fp= coa->minloc+1;
02388             else fp= coa->minloc+2;
02389 
02390             uiDefButF(block, NUM, 0, "",        xco+80, yco-65, (width-115)/2, 19, fp+3, 0.0, 2000.0, 10, 0, "Maximum length of ray");
02391             if (coa->flag & ACT_CONST_DISTANCE)
02392                 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");
02393             uiDefButBitS(block, TOG, ACT_CONST_NORMAL, 0, "N", xco+80+(width-115), yco-65, 25, 19,
02394                      &coa->flag, 0.0, 0.0, 0, 0, "Set object axis along (local axis) or parallel (global axis) to the normal at hit position");
02395             uiDefButBitS(block, TOG, ACT_CONST_MATERIAL, B_REDR, "M/P", xco+10, yco-84, 40, 19,
02396                      &coa->flag, 0.0, 0.0, 0, 0, "Detect material instead of property");
02397             if (coa->flag & ACT_CONST_MATERIAL)
02398             {
02399                 uiDefBut(block, TEX, 1, "Material:", xco + 50, yco-84, (width-60), 19,
02400                     coa->matprop, 0, MAX_NAME, 0, 0,
02401                     "Ray detects only Objects with this material");
02402             }
02403             else
02404             {
02405                 uiDefBut(block, TEX, 1, "Property:", xco + 50, yco-84, (width-60), 19,
02406                     coa->matprop, 0, MAX_NAME, 0, 0,
02407                     "Ray detect only Objects with this property");
02408             }
02409             uiDefButBitS(block, TOG, ACT_CONST_PERMANENT, 0, "PER", xco+10, yco-103, 40, 19,
02410                 &coa->flag, 0.0, 0.0, 0, 0, "Persistent actuator: stays active even if ray does not reach target");
02411             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");
02412             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");
02413         } else if (coa->type == ACT_CONST_TYPE_ORI) {
02414             ysize= 87;
02415 
02416             glRects(xco, yco-ysize, xco+width, yco);
02417             uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
02418             
02419             str= "Direction %t|None %x0|X axis %x1|Y axis %x2|Z axis %x4";
02420             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");
02421         
02422             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");
02423             uiDefBut(block, LABEL,          0, "X", xco+80, yco-45, (width-115)/3, 19, NULL, 0.0, 0.0, 0, 0, "");
02424             uiDefBut(block, LABEL,          0, "Y", xco+80+(width-115)/3, yco-45, (width-115)/3, 19, NULL, 0.0, 0.0, 0, 0, "");
02425             uiDefBut(block, LABEL,          0, "Z", xco+80+2*(width-115)/3, yco-45, (width-115)/3, 19, NULL, 0.0, 0.0, 0, 0, "");
02426 
02427             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");
02428             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");
02429             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");
02430 
02431             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");
02432             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");
02433             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");
02434         } else if (coa->type == ACT_CONST_TYPE_FH) {
02435             ysize= 106;
02436 
02437             glRects(xco, yco-ysize, xco+width, yco);
02438             uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
02439             
02440             str= "Direction %t|None %x0|X axis %x1|Y axis %x2|Z axis %x4|-X axis %x8|-Y axis %x16|-Z axis %x32";
02441             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)");
02442 
02443             if(coa->mode & (ACT_CONST_DIRPX|ACT_CONST_DIRNX)) fp= coa->minloc;
02444             else if(coa->mode & (ACT_CONST_DIRPY|ACT_CONST_DIRNY)) fp= coa->minloc+1;
02445             else fp= coa->minloc+2;
02446 
02447             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");
02448             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");
02449             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");
02450 
02451             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");
02452             uiDefButBitS(block, TOG, ACT_CONST_NORMAL, 0, "N", xco+80+(width-115), yco-65, 25, 19,
02453                      &coa->flag, 0.0, 0.0, 0, 0, "Add a horizontal spring force on slopes");
02454             uiDefButBitS(block, TOG, ACT_CONST_MATERIAL, B_REDR, "M/P", xco+10, yco-84, 40, 19,
02455                      &coa->flag, 0.0, 0.0, 0, 0, "Detect material instead of property");
02456             if (coa->flag & ACT_CONST_MATERIAL)
02457             {
02458                 uiDefBut(block, TEX, 1, "Material:", xco + 50, yco-84, (width-60), 19,
02459                     coa->matprop, 0, MAX_NAME, 0, 0,
02460                     "Ray detects only Objects with this material");
02461             }
02462             else
02463             {
02464                 uiDefBut(block, TEX, 1, "Property:", xco + 50, yco-84, (width-60), 19,
02465                     coa->matprop, 0, MAX_NAME, 0, 0,
02466                     "Ray detect only Objects with this property");
02467             }
02468             uiDefButBitS(block, TOG, ACT_CONST_PERMANENT, 0, "PER", xco+10, yco-103, 40, 19,
02469                 &coa->flag, 0.0, 0.0, 0, 0, "Persistent actuator: stays active even if ray does not reach target");
02470             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");
02471             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");
02472         }
02473         str= "Constraint Type %t|Location %x0|Distance %x1|Orientation %x2|Force field %x3";
02474         but = uiDefButS(block, MENU, B_REDR, str,       xco+40, yco-23, (width-80), 19, &coa->type, 0.0, 0.0, 0, 0, "");
02475         yco-= ysize;
02476         break;
02477 
02478     case ACT_SCENE:
02479         sca= act->data;
02480         
02481         if(sca->type==ACT_SCENE_RESTART) {
02482             ysize= 28;
02483             glRects(xco, yco-ysize, xco+width, yco);
02484             uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
02485         }
02486         else if(sca->type==ACT_SCENE_CAMERA) {
02487 
02488             ysize= 48;
02489             glRects(xco, yco-ysize, xco+width, yco);
02490             uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
02491 
02492             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");
02493         }
02494         else if(sca->type==ACT_SCENE_SET) {
02495             
02496             ysize= 48;
02497             glRects(xco, yco-ysize, xco+width, yco);
02498             uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
02499 
02500             uiDefIDPoinBut(block, test_scenepoin_but, ID_SCE, 1, "SCE:",        xco+40, yco-44, (width-80), 19, &(sca->scene), "Set this Scene");
02501         }
02502         else if(sca->type==ACT_SCENE_ADD_FRONT) { 
02503             
02504             ysize= 48;
02505             glRects(xco, yco-ysize, xco+width, yco);
02506             uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
02507 
02508             uiDefIDPoinBut(block, test_scenepoin_but, ID_SCE, 1, "SCE:",        xco+40, yco-44, (width-80), 19, &(sca->scene), "Add an Overlay Scene");
02509         }
02510         else if(sca->type==ACT_SCENE_ADD_BACK) { 
02511             
02512             ysize= 48;
02513             glRects(xco, yco-ysize, xco+width, yco);
02514             uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
02515 
02516             uiDefIDPoinBut(block, test_scenepoin_but, ID_SCE, 1, "SCE:",        xco+40, yco-44, (width-80), 19, &(sca->scene), "Add a Background Scene");
02517         }
02518         else if(sca->type==ACT_SCENE_REMOVE) { 
02519             
02520             ysize= 48;
02521             glRects(xco, yco-ysize, xco+width, yco);
02522             uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
02523 
02524             uiDefIDPoinBut(block, test_scenepoin_but, ID_SCE, 1, "SCE:",        xco+40, yco-44, (width-80), 19, &(sca->scene), "Remove a Scene");
02525         }
02526         else if(sca->type==ACT_SCENE_SUSPEND) { 
02527             
02528             ysize= 48;
02529             glRects(xco, yco-ysize, xco+width, yco);
02530             uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
02531 
02532             uiDefIDPoinBut(block, test_scenepoin_but, ID_SCE, 1, "SCE:",        xco+40, yco-44, (width-80), 19, &(sca->scene), "Pause a Scene");
02533         }
02534         else if(sca->type==ACT_SCENE_RESUME) { 
02535             
02536             ysize= 48;
02537             glRects(xco, yco-ysize, xco+width, yco);
02538             uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
02539 
02540             uiDefIDPoinBut(block, test_scenepoin_but, ID_SCE, 1, "SCE:",        xco+40, yco-44, (width-80), 19, &(sca->scene), "Unpause a Scene");
02541         }
02542 
02543         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";
02544         uiDefButS(block, MENU, B_REDR, str,     xco+40, yco-24, (width-80), 19, &sca->type, 0.0, 0.0, 0, 0, ""); 
02545 
02546           yco-= ysize; 
02547           break; 
02548     case ACT_GAME:
02549         {
02550             gma = act->data; 
02551             if (gma->type == ACT_GAME_LOAD)
02552             {
02553                 //ysize = 68;
02554                 ysize = 48;
02555                 glRects(xco, yco-ysize, xco+width, yco); 
02556                 uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); 
02557                    uiDefBut(block, TEX, 1, "File: ", xco+10, yco-44,width-20,19, &(gma->filename), 0, sizeof(gma->filename), 0, 0, "Load this blend file, use the \"//\" prefix for a path relative to the current blend file");
02558 //              uiDefBut(block, TEX, 1, "Anim: ", xco+10, yco-64,width-20,19, &(gma->loadaniname), 0, sizeof(gma->loadaniname), 0, 0, "Use this loadinganimation");
02559             }
02560 /*          else if (gma->type == ACT_GAME_START)
02561             {
02562                 ysize = 68; 
02563                 glRects(xco, yco-ysize, xco+width, yco); 
02564                 uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
02565 
02566                    uiDefBut(block, TEX, 1, "File: ", xco+10, yco-44,width-20,19, &(gma->filename), 0, sizeof(gma->filename), 0, 0, "Load this file");
02567                 uiDefBut(block, TEX, 1, "Anim: ", xco+10, yco-64,width-20,19, &(gma->loadaniname), 0, sizeof(gma->loadaniname), 0, 0, "Use this loadinganimation");
02568             }
02569 */          else if (ELEM4(gma->type, ACT_GAME_RESTART, ACT_GAME_QUIT, ACT_GAME_SAVECFG, ACT_GAME_LOADCFG))
02570             {
02571                 ysize = 28; 
02572                 glRects(xco, yco-ysize, xco+width, yco); 
02573                 uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); 
02574             }
02575 
02576             //str = "Scene %t|Load game%x0|Start loaded game%x1|Restart this game%x2|Quit this game %x3";
02577             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";
02578             uiDefButS(block, MENU, B_REDR, str, xco+40, yco-24, (width-80), 19, &gma->type, 0.0, 0.0, 0, 0, ""); 
02579             
02580             yco -= ysize; 
02581             break; 
02582         }
02583     case ACT_GROUP:
02584         ga= act->data;
02585 
02586         ysize= 52;
02587 
02588         glRects(xco, yco-ysize, xco+width, yco);
02589         uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
02590         
02591         str= "GroupKey types   %t|Set Key %x6|Play %x0|Ping Pong %x1|Flipper %x2|Loop Stop %x3|Loop End %x4|Property %x5";
02592 
02593         uiDefButS(block, MENU, 1, str,          xco+20, yco-24, width-40, 19, &ga->type, 0, 0, 0, 0, "");
02594         if(ga->type==ACT_GROUP_SET) {
02595             uiDefBut(block, TEX, 0, "Key: ",        xco+20, yco-44, (width-10)/2, 19, ga->name, 0.0, MAX_NAME, 0, 0, "This name defines groupkey to be set");
02596             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");
02597         }
02598         else if(ga->type==ACT_GROUP_FROM_PROP) {
02599             uiDefBut(block, TEX, 0, "Prop: ",       xco+20, yco-44, width-40, 19, ga->name, 0.0, MAX_NAME, 0, 0, "Use this property to define the Group position");
02600         }
02601         else {
02602             uiDefButI(block, NUM, 0, "State",       xco+20, yco-44, (width-40)/2, 19, &ga->sta, 0.0, 2500.0, 0, 0, "Start frame");
02603             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");
02604         }
02605         yco-= ysize;
02606         break;
02607 
02608     case ACT_VISIBILITY:
02609         ysize = 24;
02610 
02611         glRects(xco, yco-ysize, xco+width, yco);
02612         uiEmboss((float)xco,
02613              (float)yco-ysize, (float)xco+width, (float)yco, 1);
02614         
02615         visAct = act->data;
02616 
02617         uiBlockBeginAlign(block);
02618         uiDefButBitI(block, TOGN, ACT_VISIBILITY_INVISIBLE, B_REDR,
02619               "Visible",
02620               xco + 10, yco - 20, (width - 20)/3, 19, &visAct->flag,
02621               0.0, 0.0, 0, 0,
02622               "Set the objects visible. Initialized from the objects render restriction toggle (access in the outliner)");
02623         uiDefButBitI(block, TOG, ACT_VISIBILITY_OCCLUSION, B_REDR,
02624               "Occlusion",
02625               xco + 10 + ((width - 20)/3), yco - 20, (width - 20)/3, 19, &visAct->flag,
02626               0.0, 0.0, 0, 0,
02627               "Set the object to occlude objects behind it. Initialized from the object type in physics button");
02628         uiBlockEndAlign(block);
02629         
02630         uiDefButBitI(block, TOG, ACT_VISIBILITY_RECURSIVE, 0,
02631               "Children",
02632               xco + 10 + (((width - 20)/3)*2)+10, yco - 20, ((width - 20)/3)-10, 19, &visAct->flag,
02633               0.0, 0.0, 0, 0,
02634               "Sets all the children of this object to the same visibility/occlusion recursively");
02635 
02636         yco-= ysize;
02637 
02638         break;
02639         
02640     case ACT_STATE:
02641         ysize = 34;
02642 
02643         glRects(xco, yco-ysize, xco+width, yco);
02644         uiEmboss((float)xco,
02645              (float)yco-ysize, (float)xco+width, (float)yco, 1);
02646         
02647         staAct = act->data;
02648 
02649         str= "Operation %t|Cpy %x0|Add %x1|Sub %x2|Inv %x3";
02650 
02651         uiDefButI(block, MENU, B_REDR, str,
02652               xco + 10, yco - 24, 65, 19, &staAct->type,
02653               0.0, 0.0, 0, 0,
02654               "Select the bit operation on object state mask");
02655 
02656         for (wval=0; wval<15; wval+=5) {
02657             uiBlockBeginAlign(block);
02658             for (stbit=0; stbit<5; stbit++) {
02659                 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)));
02660                 uiButSetFunc(but, check_state_mask, but, &(staAct->mask));
02661             }
02662             for (stbit=0; stbit<5; stbit++) {
02663                 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)));
02664                 uiButSetFunc(but, check_state_mask, but, &(staAct->mask));
02665             }
02666         }
02667         uiBlockEndAlign(block);
02668 
02669         yco-= ysize;
02670 
02671         break;
02672 
02673     case ACT_RANDOM:
02674         ysize  = 69;
02675 
02676         glRects(xco, yco-ysize, xco+width, yco);
02677         uiEmboss((float)xco,
02678                   (float)yco-ysize, (float)xco+width, (float)yco, 1);
02679         
02680         randAct = act->data;
02681 
02682         /* 1. seed */
02683         uiDefButI(block, NUM, 1, "Seed: ",      (xco+10),yco-24, 0.4 *(width-20), 19,
02684                  &randAct->seed, 0, 1000, 0, 0,
02685                  "Initial seed of the random generator. Use Python for more freedom. "
02686                  " (Choose 0 for not random)");
02687 
02688         /* 2. distribution type */
02689         /* One pick per distribution. These numbers MUST match the #defines  */
02690         /* in game.h !!!                                                     */
02691         str= "Distribution %t|Bool Constant %x0|Bool Uniform %x1"
02692             "|Bool Bernoulli %x2|Int Constant %x3|Int Uniform %x4"
02693             "|Int Poisson %x5|Float Constant %x6|Float Uniform %x7"
02694             "|Float Normal %x8|Float Neg. Exp. %x9";
02695         uiDefButI(block, MENU, B_REDR, str, (xco+10) + 0.4 * (width-20), yco-24, 0.6 * (width-20), 19,
02696                  &randAct->distribution, 0.0, 0.0, 0, 0,
02697                  "Choose the type of distribution");
02698 
02699         /* 3. property */
02700         uiDefBut(block, TEX, 1, "Property:", (xco+10), yco-44, (width-20), 19,
02701                  &randAct->propname, 0, MAX_NAME, 0, 0,
02702                  "Assign the random value to this property"); 
02703 
02704         /*4. and 5. arguments for the distribution*/
02705         switch (randAct->distribution) {
02706         case ACT_RANDOM_BOOL_CONST:
02707             uiDefButBitI(block, TOG, 1, 1, "Always true", (xco+10), yco-64, (width-20), 19,
02708                      &randAct->int_arg_1, 2.0, 1, 0, 0,
02709                      "Always false or always true");            
02710             break;
02711         case ACT_RANDOM_BOOL_UNIFORM:
02712             uiDefBut(block, LABEL, 0, "     Do a 50-50 pick",   (xco+10), yco-64, (width-20), 19,
02713                      NULL, 0, 0, 0, 0,
02714                      "Choose between true and false, 50% chance each");
02715             break;
02716         case ACT_RANDOM_BOOL_BERNOUILLI:
02717             uiDefButF(block, NUM, 1, "Chance", (xco+10), yco-64, (width-20), 19,
02718                      &randAct->float_arg_1, 0.0, 1.0, 0, 0,
02719                      "Pick a number between 0 and 1. Success if you stay "
02720                      "below this value");           
02721             break;
02722         case ACT_RANDOM_INT_CONST:
02723             uiDefButI(block, NUM, 1, "Value: ",     (xco+10), yco-64, (width-20), 19,
02724                      &randAct->int_arg_1, -1000, 1000, 0, 0,
02725                      "Always return this number");
02726             break;
02727         case ACT_RANDOM_INT_UNIFORM:
02728             uiDefButI(block, NUM, 1, "Min: ",       (xco+10), yco-64, (width-20)/2, 19,
02729                      &randAct->int_arg_1, -1000, 1000, 0, 0,
02730                      "Choose a number from a range. "
02731                      "Lower boundary of the range");
02732             uiDefButI(block, NUM, 1, "Max: ",       (xco+10) + (width-20)/2, yco-64, (width-20)/2, 19,
02733                      &randAct->int_arg_2, -1000, 1000, 0, 0,
02734                      "Choose a number from a range. "
02735                      "Upper boundary of the range");
02736             break;
02737         case ACT_RANDOM_INT_POISSON:
02738             uiDefButF(block, NUM, 1, "Mean: ", (xco+10), yco-64, (width-20), 19,
02739                      &randAct->float_arg_1, 0.01, 100.0, 0, 0,
02740                      "Expected mean value of the distribution");                        
02741             break;
02742         case ACT_RANDOM_FLOAT_CONST:
02743             uiDefButF(block, NUM, 1, "Value: ", (xco+10), yco-64, (width-20), 19,
02744                      &randAct->float_arg_1, 0.0, 1.0, 0, 0,
02745                      "Always return this number");
02746             break;
02747         case ACT_RANDOM_FLOAT_UNIFORM:
02748             uiDefButF(block, NUM, 1, "Min: ",       (xco+10), yco-64, (width-20)/2, 19,
02749                      &randAct->float_arg_1, -10000.0, 10000.0, 0, 0,
02750                      "Choose a number from a range"
02751                      "Lower boundary of the range");
02752             uiDefButF(block, NUM, 1, "Max: ",       (xco+10) + (width-20)/2, yco-64, (width-20)/2, 19,
02753                      &randAct->float_arg_2, -10000.0, 10000.0, 0, 0,
02754                      "Choose a number from a range"
02755                      "Upper boundary of the range");
02756             break;
02757         case ACT_RANDOM_FLOAT_NORMAL:
02758             uiDefButF(block, NUM, 1, "Mean: ",      (xco+10), yco-64, (width-20)/2, 19,
02759                      &randAct->float_arg_1, -10000.0, 10000.0, 0, 0,
02760                      "A normal distribution. Mean of the distribution");
02761             uiDefButF(block, NUM, 1, "SD: ",        (xco+10) + (width-20)/2, yco-64, (width-20)/2, 19,
02762                      &randAct->float_arg_2, 0.0, 10000.0, 0, 0,
02763                      "A normal distribution. Standard deviation of the "
02764                      "distribution");
02765             break;
02766         case ACT_RANDOM_FLOAT_NEGATIVE_EXPONENTIAL:
02767             uiDefButF(block, NUM, 1, "Half-life time: ", (xco+10), yco-64, (width-20), 19,
02768                      &randAct->float_arg_1, 0.001, 10000.0, 0, 0,
02769                      "Negative exponential dropoff");
02770             break;
02771         default:
02772             ; /* don't know what this distro is... can be useful for testing */
02773             /* though :)                                                     */
02774         }
02775 
02776         yco-= ysize;
02777         break;
02778     case ACT_MESSAGE:
02779         ma = act->data;
02780 
02781         ysize = 4 + (3 * 24); /* footer + number of lines * 24 pixels/line */
02782     
02783         glRects(xco, yco-ysize, xco+width, yco);
02784         uiEmboss((float)xco,        (float)yco-ysize,
02785                  (float)xco+width,  (float)yco, 1);
02786 
02787         myline=1;
02788 
02789         /* line 1: To */
02790         uiDefBut(block, TEX, 1, "To: ",
02791             (xco+10), (yco-(myline++*24)), (width-20), 19,
02792             &ma->toPropName, 0, MAX_NAME, 0, 0,
02793             "Optional send message to objects with this name only, or empty to broadcast");
02794 
02795         /* line 2: Message Subject */
02796         uiDefBut(block, TEX, 1, "Subject: ",
02797         (xco+10), (yco-(myline++*24)), (width-20), 19,
02798         &ma->subject, 0, MAX_NAME, 0, 0,
02799         "Optional message subject. This is what can be filtered on");
02800 
02801         /* line 3: Text/Property */
02802         uiDefButBitS(block, TOG, 1, B_REDR, "T/P",
02803             (xco+10),(yco-(myline*24)), (0.20 * (width-20)), 19,
02804             &ma->bodyType, 0.0, 0.0, 0, 0,
02805             "Toggle message type: either Text or a PropertyName");
02806 
02807         if (ma->bodyType == ACT_MESG_MESG)
02808         {
02809             /* line 3: Message Body */
02810             uiDefBut(block, TEX, 1, "Body: ",
02811             (xco+10+(0.20*(width-20))),(yco-(myline++*24)),(0.8*(width-20)),19,
02812             &ma->body, 0, MAX_NAME, 0, 0,
02813             "Optional message body Text");
02814         } else
02815         {
02816             /* line 3: Property body (set by property) */
02817             uiDefBut(block, TEX, 1, "Propname: ",
02818             (xco+10+(0.20*(width-20))),(yco-(myline++*24)),(0.8*(width-20)),19,
02819             &ma->body, 0, MAX_NAME, 0, 0,
02820             "The message body will be set by the Property Value");
02821         }
02822         
02823         yco -= ysize;
02824         break;
02825     case ACT_2DFILTER:
02826         tdfa = act->data;
02827 
02828         ysize = 50;
02829         if(tdfa->type == ACT_2DFILTER_CUSTOMFILTER)
02830         {
02831             ysize +=20;
02832         }
02833         glRects( xco, yco-ysize, xco+width, yco ); 
02834         uiEmboss( (float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1 );
02835 
02836         switch(tdfa->type)
02837         {
02838             case ACT_2DFILTER_MOTIONBLUR:
02839                 if(!tdfa->flag)
02840                 {
02841                     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");
02842                     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");
02843                 }
02844                 else
02845                 {
02846                     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");
02847                 }
02848                 break;
02849             case ACT_2DFILTER_BLUR:
02850             case ACT_2DFILTER_SHARPEN:
02851             case ACT_2DFILTER_DILATION:
02852             case ACT_2DFILTER_EROSION:
02853             case ACT_2DFILTER_LAPLACIAN:
02854             case ACT_2DFILTER_SOBEL:
02855             case ACT_2DFILTER_PREWITT:
02856             case ACT_2DFILTER_GRAYSCALE:
02857             case ACT_2DFILTER_SEPIA:
02858             case ACT_2DFILTER_INVERT:
02859             case ACT_2DFILTER_NOFILTER:
02860             case ACT_2DFILTER_DISABLED:
02861             case ACT_2DFILTER_ENABLED:
02862                 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");
02863                 break;
02864             case ACT_2DFILTER_CUSTOMFILTER:
02865                 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");
02866                 uiDefIDPoinBut(block, test_scriptpoin_but, ID_SCRIPT, 1, "Script: ", xco+30,yco-64,width-60, 19, &tdfa->text, "");
02867                 break;
02868         }
02869         
02870         str= "2D Filter   %t|Motion Blur   %x1|Blur %x2|Sharpen %x3|Dilation %x4|Erosion %x5|"
02871                 "Laplacian %x6|Sobel %x7|Prewitt %x8|Gray Scale %x9|Sepia %x10|Invert %x11|Custom Filter %x12|"
02872                 "Enable Filter %x-2|Disable Filter %x-1|Remove Filter %x0|";
02873         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");
02874         
02875         yco -= ysize;
02876         break;
02877     case ACT_PARENT:
02878         parAct = act->data;
02879 
02880         if(parAct->type==ACT_PARENT_SET) {
02881             
02882             ysize= 48;
02883             glRects(xco, yco-ysize, xco+width, yco);
02884             uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
02885             uiDefIDPoinBut(block, test_obpoin_but, ID_OB, 1, "OB:",     xco+95, yco-24, (width-100), 19, &(parAct->ob), "Set this object as parent");
02886             uiBlockBeginAlign(block);
02887             uiDefButBitS(block, TOGN, ACT_PARENT_COMPOUND, B_REDR,
02888             "Compound",
02889             xco + 5, yco - 44, (width - 10)/2, 19, &parAct->flag,
02890             0.0, 0.0, 0, 0,
02891             "Add this object shape to the parent shape (only if the parent shape is already compound)");
02892             uiDefButBitS(block, TOGN, ACT_PARENT_GHOST, B_REDR,
02893             "Ghost",
02894             xco + 5 + ((width - 10)/2), yco - 44, (width - 10)/2, 19, &parAct->flag,
02895             0.0, 0.0, 0, 0,
02896             "Make this object ghost while parented (only if not compound)");
02897             uiBlockEndAlign(block);
02898         }
02899         else if(parAct->type==ACT_PARENT_REMOVE) {
02900 
02901             ysize= 28;
02902             glRects(xco, yco-ysize, xco+width, yco);
02903             uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
02904         }
02905 
02906         str= "Parent %t|Set Parent %x0|Remove Parent %x1";
02907         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, ""); 
02908 
02909         yco-= ysize;
02910         break;
02911     case ACT_ARMATURE:
02912         armAct = act->data;
02913 
02914         if (ob->type == OB_ARMATURE) {
02915             str= "Constraint %t|Run armature %x0|Enable %x1|Disable %x2|Set target %x3|Set weight %x4";
02916             uiDefButI(block, MENU, B_REDR, str,     xco+5, yco-24, (width-10)*0.35, 19, &armAct->type, 0.0, 0.0, 0, 0, ""); 
02917 
02918             switch (armAct->type) {
02919             case ACT_ARM_RUN:
02920                 ysize = 28;
02921                 break;
02922             default:
02923                 uiBlockBeginAlign(block);
02924                 but = uiDefBut(block, TEX, 1, "Bone: ",
02925                         (xco+5), (yco-44), (width-10)/2, 19,
02926                         armAct->posechannel, 0, MAX_NAME, 0, 0,
02927                         "Bone on which the constraint is defined");
02928                 uiButSetFunc(but, check_armature_actuator, but, armAct);
02929                 but = uiDefBut(block, TEX, 1, "Cons: ",
02930                         (xco+5)+(width-10)/2, (yco-44), (width-10)/2, 19,
02931                         armAct->constraint, 0, MAX_NAME, 0, 0,
02932                         "Name of the constraint you want to control");
02933                 uiButSetFunc(but, check_armature_actuator, but, armAct);
02934                 uiBlockEndAlign(block);
02935                 ysize = 48;
02936                 switch (armAct->type) {
02937                 case ACT_ARM_SETTARGET:
02938                     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"); 
02939                     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)"); 
02940                     ysize += 40;
02941                     break;
02942                 case ACT_ARM_SETWEIGHT:
02943                     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");
02944                     break;
02945                 }
02946             }
02947           }
02948         glRects(xco, yco-ysize, xco+width, yco); 
02949         uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); 
02950         yco-= ysize;
02951         break;
02952 
02953      default:
02954         ysize= 4;
02955 
02956         glRects(xco, yco-ysize, xco+width, yco);
02957         uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
02958         
02959         yco-= ysize;
02960         break;
02961     }
02962 
02963     uiBlockSetEmboss(block, UI_EMBOSS);
02964 
02965     return yco-4;
02966 }
02967 
02968 static void do_sensor_menu(bContext *C, void *UNUSED(arg), int event)
02969 {   
02970     SpaceLogic *slogic= CTX_wm_space_logic(C);
02971     ID **idar;
02972     Object *ob;
02973     bSensor *sens;
02974     short count, a;
02975     
02976     idar= get_selected_and_linked_obs(C, &count, slogic->scaflag);
02977     
02978     for(a=0; a<count; a++) {
02979         ob= (Object *)idar[a];
02980         if(event==0 || event==2) ob->scaflag |= OB_SHOWSENS;
02981         else if(event==1) ob->scaflag &= ~OB_SHOWSENS;
02982     }
02983         
02984     for(a=0; a<count; a++) {
02985         ob= (Object *)idar[a];
02986         sens= ob->sensors.first;
02987         while(sens) {
02988             if(event==2) sens->flag |= SENS_SHOW;
02989             else if(event==3) sens->flag &= ~SENS_SHOW;
02990             sens= sens->next;
02991         }
02992     }
02993 
02994     if(idar) MEM_freeN(idar);
02995 }
02996 
02997 static uiBlock *sensor_menu(bContext *C, ARegion *ar, void *UNUSED(arg))
02998 {
02999     uiBlock *block;
03000     int yco=0;
03001     
03002     block= uiBeginBlock(C, ar, __func__, UI_EMBOSSP);
03003     uiBlockSetButmFunc(block, do_sensor_menu, NULL);
03004     
03005     uiDefBut(block, BUTM, 1, "Show Objects",    0, (short)(yco-=20), 160, 19, NULL, 0.0, 0.0, 1, 0, "");
03006     uiDefBut(block, BUTM, 1, "Hide Objects",    0, (short)(yco-=20), 160, 19, NULL, 0.0, 0.0, 1, 1, "");
03007     uiDefBut(block, SEPR, 0, "",    0, (short)(yco-=6), 160, 6, NULL, 0.0, 0.0, 0, 0, "");
03008     uiDefBut(block, BUTM, 1, "Show Sensors",    0, (short)(yco-=20), 160, 19, NULL, 0.0, 0.0, 1, 2, "");
03009     uiDefBut(block, BUTM, 1, "Hide Sensors",    0, (short)(yco-=20), 160, 19, NULL, 0.0, 0.0, 1, 3, "");
03010 
03011     uiBlockSetDirection(block, UI_TOP);
03012     uiEndBlock(C, block);
03013     
03014     return block;
03015 }
03016 
03017 static void do_controller_menu(bContext *C, void *UNUSED(arg), int event)
03018 {   
03019     SpaceLogic *slogic= CTX_wm_space_logic(C);
03020     ID **idar;
03021     Object *ob;
03022     bController *cont;
03023     short count, a;
03024     
03025     idar= get_selected_and_linked_obs(C, &count, slogic->scaflag);
03026     
03027     for(a=0; a<count; a++) {
03028         ob= (Object *)idar[a];
03029         if(event==0 || event==2) ob->scaflag |= OB_SHOWCONT;
03030         else if(event==1) ob->scaflag &= ~OB_SHOWCONT;
03031     }
03032 
03033     for(a=0; a<count; a++) {
03034         ob= (Object *)idar[a];
03035         cont= ob->controllers.first;
03036         while(cont) {
03037             if(event==2) cont->flag |= CONT_SHOW;
03038             else if(event==3) cont->flag &= ~CONT_SHOW;
03039             cont= cont->next;
03040         }
03041     }
03042 
03043     if(idar) MEM_freeN(idar);
03044 }
03045 
03046 static uiBlock *controller_menu(bContext *C, ARegion *ar, void *UNUSED(arg))
03047 {
03048     uiBlock *block;
03049     int yco=0;
03050     
03051     block= uiBeginBlock(C, ar, __func__, UI_EMBOSSP);
03052     uiBlockSetButmFunc(block, do_controller_menu, NULL);
03053     
03054     uiDefBut(block, BUTM, 1, "Show Objects",    0, (short)(yco-=20), 160, 19, NULL, 0.0, 0.0, 1, 0, "");
03055     uiDefBut(block, BUTM, 1, "Hide Objects",    0,(short)(yco-=20), 160, 19, NULL, 0.0, 0.0, 1, 1, "");
03056     uiDefBut(block, SEPR, 0, "",                    0, (short)(yco-=6), 160, 6, NULL, 0.0, 0.0, 0, 0, "");
03057     uiDefBut(block, BUTM, 1, "Show Controllers",    0, (short)(yco-=20), 160, 19, NULL, 0.0, 0.0, 2, 2, "");
03058     uiDefBut(block, BUTM, 1, "Hide Controllers",    0, (short)(yco-=20), 160, 19, NULL, 0.0, 0.0, 3, 3, "");
03059 
03060     uiBlockSetDirection(block, UI_TOP);
03061     uiEndBlock(C, block);
03062     
03063     return block;
03064 }
03065 
03066 static void do_actuator_menu(bContext *C, void *UNUSED(arg), int event)
03067 {   
03068     SpaceLogic *slogic= CTX_wm_space_logic(C);
03069     ID **idar;
03070     Object *ob;
03071     bActuator *act;
03072     short count, a;
03073     
03074     idar= get_selected_and_linked_obs(C, &count, slogic->scaflag);
03075     
03076     for(a=0; a<count; a++) {
03077         ob= (Object *)idar[a];
03078         if(event==0 || event==2) ob->scaflag |= OB_SHOWACT;
03079         else if(event==1) ob->scaflag &= ~OB_SHOWACT;
03080     }
03081 
03082     for(a=0; a<count; a++) {
03083         ob= (Object *)idar[a];
03084         act= ob->actuators.first;
03085         while(act) {
03086             if(event==2) act->flag |= ACT_SHOW;
03087             else if(event==3) act->flag &= ~ACT_SHOW;
03088             act= act->next;
03089         }
03090     }
03091 
03092     if(idar) MEM_freeN(idar);
03093 }
03094 
03095 static uiBlock *actuator_menu(bContext *C, ARegion *ar, void *UNUSED(arg))
03096 {
03097     uiBlock *block;
03098     int xco=0;
03099     
03100     block= uiBeginBlock(C, ar, __func__, UI_EMBOSSP);
03101     uiBlockSetButmFunc(block, do_actuator_menu, NULL);
03102     
03103     uiDefBut(block, BUTM, 1, "Show Objects",    0, (short)(xco-=20), 160, 19, NULL, 0.0, 0.0, 1, 0, "");
03104     uiDefBut(block, BUTM, 1, "Hide Objects",    0, (short)(xco-=20), 160, 19, NULL, 0.0, 0.0, 1, 1, "");
03105     uiDefBut(block, SEPR, 0, "",    0, (short)(xco-=6), 160, 6, NULL, 0.0, 0.0, 0, 0, "");
03106     uiDefBut(block, BUTM, 1, "Show Actuators",  0, (short)(xco-=20), 160, 19, NULL, 0.0, 0.0, 1, 2, "");
03107     uiDefBut(block, BUTM, 1, "Hide Actuators",  0, (short)(xco-=20), 160, 19, NULL, 0.0, 0.0, 1, 3, "");
03108 
03109     uiBlockSetDirection(block, UI_TOP);
03110     uiEndBlock(C, block);
03111     
03112     return block;
03113 }
03114 
03115 
03116 
03117 static void check_controller_state_mask(bContext *UNUSED(C), void *arg1_but, void *arg2_mask)
03118 {
03119     unsigned int *cont_mask = arg2_mask;
03120     uiBut *but = arg1_but;
03121     
03122     /* a controller is always in a single state */
03123     *cont_mask = (1<<but->retval);
03124     but->retval = B_REDR;
03125 }
03126 
03127 static int first_bit(unsigned int mask)
03128 {
03129     int bit;
03130 
03131     for (bit=0; bit<32; bit++) {
03132         if (mask & (1<<bit))
03133             return bit;
03134     }
03135     return -1;
03136 }
03137 
03138 static uiBlock *controller_state_mask_menu(bContext *C, ARegion *ar, void *arg_cont)
03139 {
03140     uiBlock *block;
03141     uiBut *but;
03142     bController *cont = arg_cont;
03143 
03144     short yco = 12, xco = 0, stbit, offset;
03145 
03146     block= uiBeginBlock(C, ar, __func__, UI_EMBOSS);
03147 
03148     /* use this for a fake extra empy space around the buttons */
03149     uiDefBut(block, LABEL, 0, "",           -5, -5, 200, 34, NULL, 0, 0, 0, 0, "");
03150     
03151     for (offset=0; offset<15; offset+=5) {
03152         uiBlockBeginAlign(block);
03153         for (stbit=0; stbit<5; stbit++) {
03154             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, "");
03155             uiButSetFunc(but, check_controller_state_mask, but, &(cont->state_mask));
03156         }
03157         for (stbit=0; stbit<5; stbit++) {
03158             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, "");
03159             uiButSetFunc(but, check_controller_state_mask, but, &(cont->state_mask));
03160         }
03161     }
03162     uiBlockEndAlign(block);
03163 
03164     uiBlockSetDirection(block, UI_TOP);
03165     uiEndBlock(C, block);
03166 
03167     return block;
03168 }
03169 
03170 static void do_object_state_menu(bContext *UNUSED(C), void *arg, int event)
03171 {   
03172     Object *ob = arg;
03173 
03174     switch (event) {
03175     case 0:
03176         ob->state = 0x3FFFFFFF;
03177         break;
03178     case 1:
03179         ob->state = ob->init_state;
03180         if (!ob->state)
03181             ob->state = 1;
03182         break;
03183     case 2:
03184         ob->init_state = ob->state;
03185         break;
03186     }
03187 }
03188 
03189 static uiBlock *object_state_mask_menu(bContext *C, ARegion *ar, void *arg_obj)
03190 {
03191     uiBlock *block;
03192     short xco = 0;
03193 
03194     block= uiBeginBlock(C, ar, __func__, UI_EMBOSSP);
03195     uiBlockSetButmFunc(block, do_object_state_menu, arg_obj);
03196     
03197     uiDefBut(block, BUTM, 1, "Set all bits",        0, (short)(xco-=20), 160, 19, NULL, 0.0, 0.0, 1, 0, "");
03198     uiDefBut(block, BUTM, 1, "Recall init state",   0, (short)(xco-=20), 160, 19, NULL, 0.0, 0.0, 1, 1, "");
03199     uiDefBut(block, SEPR, 0, "",                    0, (short)(xco-=6),  160, 6,  NULL, 0.0, 0.0, 0, 0, "");
03200     uiDefBut(block, BUTM, 1, "Store init state",    0, (short)(xco-=20), 160, 19, NULL, 0.0, 0.0, 1, 2, "");
03201 
03202     uiBlockSetDirection(block, UI_TOP);
03203     uiEndBlock(C, block);
03204     
03205     return block;
03206 }
03207 
03208 static int is_sensor_linked(uiBlock *block, bSensor *sens)
03209 {
03210     bController *cont;
03211     int i;
03212 
03213     for (i=0; i<sens->totlinks; i++) {
03214         cont = sens->links[i];
03215         if (uiFindInlink(block, cont) != NULL)
03216             return 1;
03217     }
03218     return 0;
03219 }
03220 
03221 /* Sensors code */
03222 
03223 static void draw_sensor_header(uiLayout *layout, PointerRNA *ptr, PointerRNA *logic_ptr)
03224 {
03225     uiLayout *box, *row, *sub;
03226     bSensor *sens= (bSensor *)ptr->data;
03227     
03228     box= uiLayoutBox(layout);
03229     row= uiLayoutRow(box, 0);
03230     
03231     uiItemR(row, ptr, "show_expanded", UI_ITEM_R_NO_BG, "", ICON_NONE);
03232     if(RNA_boolean_get(ptr, "show_expanded")) {
03233         uiItemR(row, ptr, "type", 0, "", ICON_NONE);
03234         uiItemR(row, ptr, "name", 0, "", ICON_NONE);
03235     } else {
03236         uiItemL(row, sensor_name(sens->type), ICON_NONE);
03237         uiItemL(row, sens->name, ICON_NONE);
03238     }
03239 
03240     sub= uiLayoutRow(row, 0);
03241     uiLayoutSetActive(sub, ((RNA_boolean_get(logic_ptr, "show_sensors_active_states")
03242                             && RNA_boolean_get(ptr, "show_expanded")) || RNA_boolean_get(ptr, "pin")));
03243     uiItemR(sub, ptr, "pin", UI_ITEM_R_NO_BG, "", ICON_NONE);
03244 
03245     if(RNA_boolean_get(ptr, "show_expanded")==0) {
03246         sub= uiLayoutRow(row, 1);
03247         uiItemEnumO(sub, "LOGIC_OT_sensor_move", "", ICON_TRIA_UP, "direction", 1); // up
03248         uiItemEnumO(sub, "LOGIC_OT_sensor_move", "", ICON_TRIA_DOWN, "direction", 2); // down
03249     }
03250 
03251     uiItemO(row, "", ICON_X, "LOGIC_OT_sensor_remove");
03252 }
03253 
03254 static void draw_sensor_internal_header(uiLayout *layout, PointerRNA *ptr)
03255 {
03256     uiLayout *box, *split, *sub, *row;
03257 
03258     box= uiLayoutBox(layout);
03259     split = uiLayoutSplit(box, 0.45, 0);
03260     
03261     row= uiLayoutRow(split, 1);
03262     uiItemR(row, ptr, "use_pulse_true_level", 0, "", ICON_DOTSUP);
03263     uiItemR(row, ptr, "use_pulse_false_level", 0, "", ICON_DOTSDOWN);
03264 
03265     sub=uiLayoutRow(row, 0);
03266     uiLayoutSetActive(sub, (RNA_boolean_get(ptr, "use_pulse_true_level")
03267                             || RNA_boolean_get(ptr, "use_pulse_false_level")));
03268     uiItemR(sub, ptr, "frequency", 0, "Freq", ICON_NONE);
03269     
03270     row= uiLayoutRow(split, 1);
03271     uiItemR(row, ptr, "use_level", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
03272     uiItemR(row, ptr, "use_tap", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
03273     
03274     uiItemR(split, ptr, "invert", UI_ITEM_R_TOGGLE, "Invert", ICON_NONE);
03275 }
03276 /* sensors in alphabetical order */
03277 
03278 static void draw_sensor_actuator(uiLayout *layout, PointerRNA *ptr)
03279 {
03280     Object *ob = (Object *)ptr->id.data;
03281     PointerRNA settings_ptr;
03282 
03283     RNA_pointer_create((ID *)ob, &RNA_GameObjectSettings, ob, &settings_ptr);
03284     uiItemPointerR(layout, ptr, "actuator", &settings_ptr, "actuators", NULL, ICON_LOGIC);
03285 }
03286 
03287 static void draw_sensor_armature(uiLayout *layout, PointerRNA *ptr)
03288 {
03289     bSensor *sens = (bSensor*)ptr->data;
03290     bArmatureSensor *as = (bArmatureSensor *) sens->data;
03291     Object *ob = (Object *)ptr->id.data;
03292     PointerRNA pose_ptr, pchan_ptr;
03293     PropertyRNA *bones_prop= NULL;
03294     uiLayout *row;
03295 
03296     if(ob->type != OB_ARMATURE){
03297         uiItemL(layout, "Sensor only available for armatures", ICON_NONE);
03298         return;
03299     }
03300 
03301     if (ob->pose) {
03302         RNA_pointer_create((ID *)ob, &RNA_Pose, ob->pose, &pose_ptr);
03303         bones_prop = RNA_struct_find_property(&pose_ptr, "bones");
03304     }
03305 
03306     if (&pose_ptr.data) {
03307         uiItemPointerR(layout, ptr, "bone", &pose_ptr, "bones", NULL, ICON_BONE_DATA);
03308 
03309         if (RNA_property_collection_lookup_string(&pose_ptr, bones_prop, as->posechannel, &pchan_ptr))
03310             uiItemPointerR(layout, ptr, "constraint", &pchan_ptr, "constraints", NULL, ICON_CONSTRAINT_BONE);
03311     }
03312     row = uiLayoutRow(layout, 1);
03313     uiItemR(row, ptr, "test_type", 0, NULL, ICON_NONE);
03314     if (RNA_enum_get(ptr, "test_type") != SENS_ARM_STATE_CHANGED)
03315         uiItemR(row, ptr, "value", 0, NULL, ICON_NONE);
03316 }
03317 
03318 static void draw_sensor_collision(uiLayout *layout, PointerRNA *ptr, bContext *C)
03319 {
03320     uiLayout *row, *split;
03321     PointerRNA main_ptr;
03322 
03323     RNA_main_pointer_create(CTX_data_main(C), &main_ptr);
03324 
03325     split = uiLayoutSplit(layout, 0.3, 0);
03326     row = uiLayoutRow(split, 1);
03327     uiItemR(row, ptr, "use_pulse", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
03328     uiItemR(row, ptr, "use_material", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
03329 
03330     switch (RNA_boolean_get(ptr, "use_material")) {
03331         case SENS_COLLISION_PROPERTY:
03332             uiItemR(split, ptr, "property", 0, NULL, ICON_NONE);
03333             break;
03334         case SENS_COLLISION_MATERIAL:
03335             uiItemPointerR(split, ptr, "material", &main_ptr, "materials", NULL, ICON_MATERIAL_DATA);
03336             break;
03337     }
03338 }
03339 
03340 static void draw_sensor_delay(uiLayout *layout, PointerRNA *ptr)
03341 {
03342     uiLayout *row;
03343     
03344     row= uiLayoutRow(layout, 0);
03345 
03346     uiItemR(row, ptr, "delay", 0, NULL, ICON_NONE);
03347     uiItemR(row, ptr, "duration", 0, NULL, ICON_NONE);
03348     uiItemR(row, ptr, "use_repeat", 0, NULL, ICON_NONE);
03349 }
03350 
03351 static void draw_sensor_joystick(uiLayout *layout, PointerRNA *ptr)
03352 {
03353     uiLayout *col, *row;
03354 
03355     uiItemR(layout, ptr, "joystick_index", 0, NULL, ICON_NONE);
03356     uiItemR(layout, ptr, "event_type", 0, NULL, ICON_NONE);
03357 
03358     switch (RNA_enum_get(ptr, "event_type")) {
03359         case SENS_JOY_BUTTON:
03360             uiItemR(layout, ptr, "use_all_events", 0, NULL, ICON_NONE);
03361 
03362             col = uiLayoutColumn(layout, 0);
03363             uiLayoutSetActive(col, RNA_boolean_get(ptr, "use_all_events")==0);
03364             uiItemR(col, ptr, "button_number", 0, NULL, ICON_NONE);
03365             break;
03366         case SENS_JOY_AXIS:
03367             row = uiLayoutRow(layout, 0);
03368             uiItemR(row, ptr, "axis_number", 0, NULL, ICON_NONE);
03369             uiItemR(row, ptr, "axis_threshold", 0, NULL, ICON_NONE);
03370 
03371             uiItemR(layout, ptr, "use_all_events", 0, NULL, ICON_NONE);
03372             col = uiLayoutColumn(layout, 0);
03373             uiLayoutSetActive(col, RNA_boolean_get(ptr, "use_all_events")==0);
03374             uiItemR(col, ptr, "axis_direction", 0, NULL, ICON_NONE);
03375             break;
03376         case SENS_JOY_HAT:
03377             uiItemR(layout, ptr, "hat_number", 0, NULL, ICON_NONE);
03378             uiItemR(layout, ptr, "use_all_events", 0, NULL, ICON_NONE);
03379 
03380             col = uiLayoutColumn(layout, 0);
03381             uiLayoutSetActive(col, RNA_boolean_get(ptr, "use_all_events")==0);
03382             uiItemR(col, ptr, "hat_direction", 0, NULL, ICON_NONE);
03383             break;
03384         case SENS_JOY_AXIS_SINGLE:
03385             row = uiLayoutRow(layout, 0);
03386             uiItemR(row, ptr, "single_axis_number", 0, NULL, ICON_NONE);
03387             uiItemR(row, ptr, "axis_threshold", 0, NULL, ICON_NONE);
03388             break;
03389     }
03390 }
03391 
03392 static void draw_sensor_keyboard(uiLayout *layout, PointerRNA *ptr)
03393 {
03394     Object *ob = (Object *)ptr->id.data;
03395     PointerRNA settings_ptr;
03396     uiLayout *row, *col;
03397 
03398     row = uiLayoutRow(layout, 0);
03399     uiItemL(row, "Key:", ICON_NONE);
03400     col = uiLayoutColumn(row, 0);
03401     uiLayoutSetActive(col, RNA_boolean_get(ptr, "use_all_keys")==0);
03402     uiItemR(col, ptr, "key", UI_ITEM_R_EVENT, "", ICON_NONE);
03403     col = uiLayoutColumn(row, 0);
03404     uiItemR(col, ptr, "use_all_keys", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
03405     
03406     col = uiLayoutColumn(layout, 0);
03407     uiLayoutSetActive(col, RNA_boolean_get(ptr, "use_all_keys")==0);
03408     row = uiLayoutRow(col, 0);
03409     uiItemL(row, "First Modifier:", ICON_NONE);
03410     uiItemR(row, ptr, "modifier_key_1", UI_ITEM_R_EVENT, "", ICON_NONE);
03411     
03412     row = uiLayoutRow(col, 0);
03413     uiItemL(row, "Second Modifier:", ICON_NONE);
03414     uiItemR(row, ptr, "modifier_key_2", UI_ITEM_R_EVENT, "", ICON_NONE);
03415 
03416     RNA_pointer_create((ID *)ob, &RNA_GameObjectSettings, ob, &settings_ptr);
03417     uiItemPointerR(layout, ptr, "log", &settings_ptr, "properties", NULL, ICON_NONE);
03418     uiItemPointerR(layout, ptr, "target", &settings_ptr, "properties", NULL, ICON_NONE);
03419 }
03420 
03421 static void draw_sensor_message(uiLayout *layout, PointerRNA *ptr)
03422 {
03423     uiItemR(layout, ptr, "subject", 0, NULL, ICON_NONE);
03424 }
03425 
03426 static void draw_sensor_mouse(uiLayout *layout, PointerRNA *ptr)
03427 {
03428     uiItemR(layout, ptr, "mouse_event", 0, NULL, ICON_NONE);
03429 }
03430 
03431 static void draw_sensor_near(uiLayout *layout, PointerRNA *ptr)
03432 {
03433     uiLayout *row;
03434 
03435     uiItemR(layout, ptr, "property", 0, NULL, ICON_NONE);
03436 
03437     row= uiLayoutRow(layout, 1);
03438     uiItemR(row, ptr, "distance", 0, NULL, ICON_NONE);
03439     uiItemR(row, ptr, "reset_distance", 0, NULL, ICON_NONE);
03440 }
03441 
03442 static void draw_sensor_property(uiLayout *layout, PointerRNA *ptr)
03443 {
03444     Object *ob = (Object *)ptr->id.data;
03445     PointerRNA settings_ptr;
03446 
03447     uiLayout *row;
03448     uiItemR(layout, ptr, "evaluation_type", 0, NULL, ICON_NONE);
03449 
03450     RNA_pointer_create((ID *)ob, &RNA_GameObjectSettings, ob, &settings_ptr);
03451     uiItemPointerR(layout, ptr, "property", &settings_ptr, "properties", NULL, ICON_NONE);
03452 
03453     switch (RNA_enum_get(ptr, "evaluation_type")) {
03454         case SENS_PROP_INTERVAL:
03455             row = uiLayoutRow(layout, 0);
03456             uiItemR(row, ptr, "value_min", 0, NULL, ICON_NONE);
03457             uiItemR(row, ptr, "value_max", 0, NULL, ICON_NONE);
03458             break;
03459         case SENS_PROP_EQUAL:
03460             uiItemR(layout, ptr, "value", 0, NULL, ICON_NONE);
03461             break;
03462         case SENS_PROP_NEQUAL:
03463             uiItemR(layout, ptr, "value", 0, NULL, ICON_NONE);
03464             break;
03465         case SENS_PROP_CHANGED:
03466             break;
03467     }
03468 }
03469 
03470 static void draw_sensor_radar(uiLayout *layout, PointerRNA *ptr)
03471 {
03472     uiLayout *row;
03473 
03474     uiItemR(layout, ptr, "property", 0, NULL, ICON_NONE);
03475     uiItemR(layout, ptr, "axis", 0, NULL, ICON_NONE);
03476 
03477     row= uiLayoutRow(layout, 0);
03478     uiItemR(row, ptr, "angle", 0, NULL, ICON_NONE);
03479     uiItemR(row, ptr, "distance", 0, NULL, ICON_NONE);
03480 }
03481 
03482 static void draw_sensor_random(uiLayout *layout, PointerRNA *ptr)
03483 {
03484     uiItemR(layout, ptr, "seed", 0, NULL, ICON_NONE);
03485 }
03486 
03487 static void draw_sensor_ray(uiLayout *layout, PointerRNA *ptr, bContext *C)
03488 {
03489     uiLayout *split, *row;
03490     PointerRNA main_ptr;
03491 
03492     RNA_main_pointer_create(CTX_data_main(C), &main_ptr);
03493     split= uiLayoutSplit(layout, 0.3, 0);
03494     uiItemR(split, ptr, "ray_type", 0, "", ICON_NONE);
03495     switch (RNA_enum_get(ptr, "ray_type")) {
03496         case SENS_RAY_PROPERTY:
03497             uiItemR(split, ptr, "property", 0, "", ICON_NONE);
03498             break;
03499         case SENS_RAY_MATERIAL:
03500             uiItemPointerR(split, ptr, "material", &main_ptr, "materials", "", ICON_MATERIAL_DATA);
03501             break;
03502     }
03503 
03504     split= uiLayoutSplit(layout, 0.3, 0);
03505     uiItemR(split, ptr, "axis", 0, "", ICON_NONE);
03506     row= uiLayoutRow(split, 0); 
03507     uiItemR(row, ptr, "range", 0, NULL, ICON_NONE);
03508     uiItemR(row, ptr, "use_x_ray", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
03509 }
03510 
03511 static void draw_sensor_touch(uiLayout *layout, PointerRNA *ptr)
03512 {
03513     uiItemR(layout, ptr, "material", 0, NULL, ICON_NONE);
03514 }
03515 
03516 static void draw_brick_sensor(uiLayout *layout, PointerRNA *ptr, bContext *C)
03517 {
03518     uiLayout *box;
03519     
03520     if (!RNA_boolean_get(ptr, "show_expanded"))
03521         return;
03522 
03523     draw_sensor_internal_header(layout, ptr);
03524     
03525     box = uiLayoutBox(layout);
03526 
03527     switch (RNA_enum_get(ptr, "type")) {
03528 
03529         case SENS_ACTUATOR:
03530             draw_sensor_actuator(box, ptr);
03531             break;
03532         case SENS_ALWAYS:
03533             break;
03534         case SENS_ARMATURE:
03535             draw_sensor_armature(box, ptr);
03536             break;
03537         case SENS_COLLISION:
03538             draw_sensor_collision(box, ptr, C);
03539             break;
03540         case SENS_DELAY:
03541             draw_sensor_delay(box, ptr);
03542             break;
03543         case SENS_JOYSTICK:
03544             draw_sensor_joystick(box, ptr);
03545             break;
03546         case SENS_KEYBOARD:
03547             draw_sensor_keyboard(box, ptr);
03548             break;
03549         case SENS_MESSAGE:
03550             draw_sensor_message(box, ptr);
03551             break;
03552         case SENS_MOUSE:
03553             draw_sensor_mouse(box, ptr);
03554             break;
03555         case SENS_NEAR:
03556             draw_sensor_near(box, ptr);
03557             break;
03558         case SENS_PROPERTY:
03559             draw_sensor_property(box, ptr);
03560             break;
03561         case SENS_RADAR:
03562             draw_sensor_radar(box, ptr);
03563             break;
03564         case SENS_RANDOM:
03565             draw_sensor_random(box, ptr);
03566             break;
03567         case SENS_RAY:
03568             draw_sensor_ray(box, ptr, C);
03569             break;
03570         case SENS_TOUCH:
03571             draw_sensor_touch(box, ptr);
03572             break;
03573     }
03574 }
03575 
03576 /* Controller code */
03577 static void draw_controller_header(uiLayout *layout, PointerRNA *ptr, int xco, int width, int yco)
03578 {
03579     uiLayout *box, *row, *sub;
03580     bController *cont= (bController *)ptr->data;
03581 
03582     char state[3];
03583     BLI_snprintf(state, sizeof(state), "%d", RNA_int_get(ptr, "states"));
03584     
03585     box= uiLayoutBox(layout);
03586     row= uiLayoutRow(box, 0);
03587     
03588     uiItemR(row, ptr, "show_expanded", UI_ITEM_R_NO_BG, "", ICON_NONE);
03589     if(RNA_boolean_get(ptr, "show_expanded")) {
03590         uiItemR(row, ptr, "type", 0, "", ICON_NONE);
03591         uiItemR(row, ptr, "name", 0, "", ICON_NONE);
03592         /* XXX provisory for Blender 2.50Beta */
03593         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)");
03594     } else {
03595         uiItemL(row, controller_name(cont->type), ICON_NONE);
03596         uiItemL(row, cont->name, ICON_NONE);
03597         uiItemL(row, state, ICON_NONE);
03598     }
03599 
03600     uiItemR(row, ptr, "use_priority", 0, "", ICON_NONE);
03601 
03602     if(RNA_boolean_get(ptr, "show_expanded")==0) {
03603         sub= uiLayoutRow(row, 1);
03604         uiItemEnumO(sub, "LOGIC_OT_controller_move", "", ICON_TRIA_UP, "direction", 1); // up
03605         uiItemEnumO(sub, "LOGIC_OT_controller_move", "", ICON_TRIA_DOWN, "direction", 2); // down
03606     }
03607     uiItemO(row, "", ICON_X, "LOGIC_OT_controller_remove");
03608 }
03609 
03610 static void draw_controller_expression(uiLayout *layout, PointerRNA *ptr)
03611 {
03612     uiItemR(layout, ptr, "expression", 0, "", ICON_NONE);
03613 }
03614 
03615 static void draw_controller_python(uiLayout *layout, PointerRNA *ptr)
03616 {
03617     uiLayout *split, *sub;
03618 
03619     split = uiLayoutSplit(layout, 0.3, 1);
03620     uiItemR(split, ptr, "mode", 0, "", ICON_NONE);
03621     if (RNA_enum_get(ptr, "mode") == CONT_PY_SCRIPT) {
03622         uiItemR(split, ptr, "text", 0, "", ICON_NONE);
03623     }
03624     else {
03625         sub = uiLayoutSplit(split, 0.8, 0);
03626         uiItemR(sub, ptr, "module", 0, "", ICON_NONE);
03627         uiItemR(sub, ptr, "use_debug", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
03628     }
03629 }
03630 
03631 static void draw_controller_state(uiLayout *UNUSED(layout), PointerRNA *UNUSED(ptr))
03632 {
03633 
03634 }
03635 
03636 static void draw_brick_controller(uiLayout *layout, PointerRNA *ptr)
03637 {
03638     uiLayout *box;
03639     
03640     if (!RNA_boolean_get(ptr, "show_expanded"))
03641         return;
03642     
03643     box = uiLayoutBox(layout);
03644 
03645     draw_controller_state(box, ptr);
03646     
03647     switch (RNA_enum_get(ptr, "type")) {
03648         case CONT_LOGIC_AND:
03649             break;
03650         case CONT_LOGIC_OR:
03651             break;
03652         case CONT_EXPRESSION:
03653             draw_controller_expression(box, ptr);
03654             break;
03655         case CONT_PYTHON:
03656             draw_controller_python(box, ptr);
03657             break;
03658         case CONT_LOGIC_NAND:
03659             break;
03660         case CONT_LOGIC_NOR:
03661             break;
03662         case CONT_LOGIC_XOR:
03663             break;
03664         case CONT_LOGIC_XNOR:
03665             break;
03666     }
03667 }
03668 
03669 /* Actuator code */
03670 static void draw_actuator_header(uiLayout *layout, PointerRNA *ptr, PointerRNA *logic_ptr)
03671 {
03672     uiLayout *box, *row, *sub;
03673     bActuator *act= (bActuator *)ptr->data;
03674     
03675     box= uiLayoutBox(layout);
03676     row= uiLayoutRow(box, 0);
03677     
03678     uiItemR(row, ptr, "show_expanded", UI_ITEM_R_NO_BG, "", ICON_NONE);
03679     if(RNA_boolean_get(ptr, "show_expanded")) {
03680         uiItemR(row, ptr, "type", 0, "", ICON_NONE);
03681         uiItemR(row, ptr, "name", 0, "", ICON_NONE);
03682     } else {
03683         uiItemL(row, actuator_name(act->type), ICON_NONE);
03684         uiItemL(row, act->name, ICON_NONE);
03685     }
03686 
03687     sub= uiLayoutRow(row, 0);
03688     uiLayoutSetActive(sub, ((RNA_boolean_get(logic_ptr, "show_actuators_active_states")
03689                             && RNA_boolean_get(ptr, "show_expanded")) || RNA_boolean_get(ptr, "pin")));
03690     uiItemR(sub, ptr, "pin", UI_ITEM_R_NO_BG, "", ICON_NONE);
03691 
03692     if(RNA_boolean_get(ptr, "show_expanded")==0) {
03693         sub= uiLayoutRow(row, 1);
03694         uiItemEnumO(sub, "LOGIC_OT_actuator_move", "", ICON_TRIA_UP, "direction", 1); // up
03695         uiItemEnumO(sub, "LOGIC_OT_actuator_move", "", ICON_TRIA_DOWN, "direction", 2); // down
03696     }
03697     uiItemO(row, "", ICON_X, "LOGIC_OT_actuator_remove");
03698 }
03699 
03700 static void draw_actuator_action(uiLayout *layout, PointerRNA *ptr)
03701 {
03702     Object *ob = (Object *)ptr->id.data;
03703     PointerRNA settings_ptr;
03704     uiLayout *row, *sub;
03705 
03706     RNA_pointer_create((ID *)ob, &RNA_GameObjectSettings, ob, &settings_ptr);
03707 
03708     row= uiLayoutRow(layout, 0);
03709     uiItemR(row, ptr, "play_mode", 0, "", ICON_NONE);
03710 
03711     sub= uiLayoutRow(row, 1);
03712     uiItemR(sub, ptr, "use_force", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
03713     uiItemR(sub, ptr, "use_additive", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
03714 
03715     row = uiLayoutColumn(sub, 0);
03716     uiLayoutSetActive(row, (RNA_boolean_get(ptr, "use_additive") || RNA_boolean_get(ptr, "use_force")));
03717     uiItemR(row, ptr, "use_local", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
03718 
03719     row= uiLayoutRow(layout, 0);
03720     uiItemR(row, ptr, "action", 0, "", ICON_NONE);
03721     uiItemR(row, ptr, "use_continue_last_frame", 0, NULL, ICON_NONE);
03722 
03723     row= uiLayoutRow(layout, 0);
03724     if((RNA_enum_get(ptr, "play_mode") == ACT_ACTION_FROM_PROP))
03725         uiItemPointerR(row, ptr, "property", &settings_ptr, "properties", NULL, ICON_NONE);
03726 
03727     else {
03728         uiItemR(row, ptr, "frame_start", 0, NULL, ICON_NONE);
03729         uiItemR(row, ptr, "frame_end", 0, NULL, ICON_NONE);
03730     }
03731 
03732     uiItemR(row, ptr, "apply_to_children", 0, NULL, ICON_NONE);
03733 
03734     row= uiLayoutRow(layout, 0);
03735     uiItemR(row, ptr, "frame_blend_in", 0, NULL, ICON_NONE);
03736     uiItemR(row, ptr, "priority", 0, NULL, ICON_NONE);
03737 
03738     row= uiLayoutRow(layout, 0);
03739     uiItemR(row, ptr, "layer", 0, NULL, ICON_NONE);
03740     uiItemR(row, ptr, "layer_weight", 0, NULL, ICON_NONE);
03741 
03742     uiItemPointerR(layout, ptr, "frame_property", &settings_ptr, "properties", NULL, ICON_NONE);
03743 
03744 #ifdef __NLA_ACTION_BY_MOTION_ACTUATOR
03745     uiItemR(layout, "stride_length", 0, NULL, ICON_NONE);
03746 #endif
03747 }
03748 
03749 static void draw_actuator_armature(uiLayout *layout, PointerRNA *ptr)
03750 {
03751     bActuator *act = (bActuator*)ptr->data;
03752     bArmatureActuator *aa = (bArmatureActuator *) act->data;
03753     Object *ob = (Object *)ptr->id.data;
03754     bConstraint *constraint = NULL;
03755     PointerRNA pose_ptr, pchan_ptr;
03756     PropertyRNA *bones_prop = NULL;
03757 
03758     if(ob->type != OB_ARMATURE){
03759         uiItemL(layout, "Actuator only available for armatures", ICON_NONE);
03760         return;
03761     }
03762     
03763     if (ob->pose) {
03764         RNA_pointer_create((ID *)ob, &RNA_Pose, ob->pose, &pose_ptr);
03765         bones_prop = RNA_struct_find_property(&pose_ptr, "bones");
03766     }
03767     
03768     uiItemR(layout, ptr, "mode", 0, NULL, ICON_NONE);
03769     
03770     switch (RNA_enum_get(ptr, "mode"))
03771     {
03772         case ACT_ARM_RUN:
03773             break;
03774         case ACT_ARM_ENABLE:
03775         case ACT_ARM_DISABLE:
03776             if (ob->pose) {
03777                 uiItemPointerR(layout, ptr, "bone", &pose_ptr, "bones", NULL, ICON_BONE_DATA);
03778 
03779                 if (RNA_property_collection_lookup_string(&pose_ptr, bones_prop, aa->posechannel, &pchan_ptr))
03780                     uiItemPointerR(layout, ptr, "constraint", &pchan_ptr, "constraints", NULL, ICON_CONSTRAINT_BONE);
03781             }
03782             break;
03783         case ACT_ARM_SETTARGET:
03784             if (ob->pose) {
03785                 uiItemPointerR(layout, ptr, "bone", &pose_ptr, "bones", NULL, ICON_BONE_DATA);
03786                 
03787                 if (RNA_property_collection_lookup_string(&pose_ptr, bones_prop, aa->posechannel, &pchan_ptr))
03788                     uiItemPointerR(layout, ptr, "constraint", &pchan_ptr, "constraints", NULL, ICON_CONSTRAINT_BONE);
03789             }
03790 
03791             uiItemR(layout, ptr, "target", 0, NULL, ICON_NONE);
03792 
03793             /* show second target only if the constraint supports it */
03794             get_armature_bone_constraint(ob, aa->posechannel, aa->constraint, &constraint);
03795             if (constraint && constraint->type == CONSTRAINT_TYPE_KINEMATIC) {
03796                 uiItemR(layout, ptr, "secondary_target", 0, NULL, ICON_NONE);
03797             }
03798             break;
03799         case ACT_ARM_SETWEIGHT:
03800             if (ob->pose) {
03801                 uiItemPointerR(layout, ptr, "bone", &pose_ptr, "bones", NULL, ICON_BONE_DATA);
03802                 
03803                 if (RNA_property_collection_lookup_string(&pose_ptr, bones_prop, aa->posechannel, &pchan_ptr))
03804                     uiItemPointerR(layout, ptr, "constraint", &pchan_ptr, "constraints", NULL, ICON_CONSTRAINT_BONE);
03805             }
03806 
03807             uiItemR(layout, ptr, "weight", 0, NULL, ICON_NONE);
03808             break;
03809     }
03810 }
03811 
03812 static void draw_actuator_camera(uiLayout *layout, PointerRNA *ptr)
03813 {
03814     uiLayout *row;
03815     uiItemR(layout, ptr, "object", 0, NULL, ICON_NONE);
03816 
03817     row = uiLayoutRow(layout, 0);
03818     uiItemR(row, ptr, "height", 0, NULL, ICON_NONE);
03819     uiItemR(row, ptr, "axis", 0, NULL, ICON_NONE);
03820 
03821     row = uiLayoutRow(layout, 1);
03822     uiItemR(row, ptr, "min", 0, NULL, ICON_NONE);
03823     uiItemR(row, ptr, "max", 0, NULL, ICON_NONE);
03824 
03825     uiItemR(layout, ptr, "damping", 0, NULL, ICON_NONE);
03826 }
03827 
03828 static void draw_actuator_constraint(uiLayout *layout, PointerRNA *ptr, bContext *C)
03829 {
03830     uiLayout *row, *col, *sub, *split;
03831     PointerRNA main_ptr;
03832 
03833     RNA_main_pointer_create(CTX_data_main(C), &main_ptr);
03834 
03835     uiItemR(layout, ptr, "mode", 0, NULL, ICON_NONE);
03836     switch (RNA_enum_get(ptr, "mode"))
03837     {
03838         case ACT_CONST_TYPE_LOC:
03839             uiItemR(layout, ptr, "limit", 0, NULL, ICON_NONE);
03840 
03841             row = uiLayoutRow(layout, 1);
03842             uiItemR(row, ptr, "limit_min", 0, NULL, ICON_NONE);
03843             uiItemR(row, ptr, "limit_max", 0, NULL, ICON_NONE);
03844 
03845             uiItemR(layout, ptr, "damping", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
03846             break;
03847 
03848         case ACT_CONST_TYPE_DIST:
03849             split = uiLayoutSplit(layout, 0.8, 0);
03850             uiItemR(split, ptr, "direction", 0, NULL, ICON_NONE);
03851             row = uiLayoutRow(split, 1);
03852             uiItemR(row, ptr, "use_local", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
03853             uiItemR(row, ptr, "use_normal", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
03854 
03855             row = uiLayoutRow(layout, 0);
03856             col = uiLayoutColumn(row, 1);
03857             uiItemL(col, "Range:", ICON_NONE);
03858             uiItemR(col, ptr, "range", 0, "", ICON_NONE);
03859 
03860             col = uiLayoutColumn(row, 1);
03861             uiItemR(col, ptr, "use_force_distance", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
03862             sub = uiLayoutColumn(col, 0);
03863             uiLayoutSetActive(sub, RNA_boolean_get(ptr, "use_force_distance")==1);
03864             uiItemR(sub, ptr, "distance", 0, "", ICON_NONE);
03865 
03866             uiItemR(layout, ptr, "damping", UI_ITEM_R_SLIDER , NULL, ICON_NONE);
03867 
03868             split = uiLayoutSplit(layout, 0.15, 0);
03869             uiItemR(split, ptr, "use_material_detect", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
03870             if (RNA_boolean_get(ptr, "use_material_detect"))
03871                 uiItemPointerR(split, ptr, "material", &main_ptr, "materials", NULL, ICON_MATERIAL_DATA);
03872             else
03873                 uiItemR(split, ptr, "property", 0, NULL, ICON_NONE);
03874 
03875             split = uiLayoutSplit(layout, 0.15, 0);
03876             uiItemR(split, ptr, "use_persistent", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
03877 
03878             row = uiLayoutRow(split, 1);
03879             uiItemR(row, ptr, "time", 0, NULL, ICON_NONE);
03880             uiItemR(row, ptr, "damping_rotation", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
03881             break;
03882 
03883         case ACT_CONST_TYPE_ORI:
03884             uiItemR(layout, ptr, "direction_axis_pos", 0, NULL, ICON_NONE);
03885 
03886             row=uiLayoutRow(layout, 1);
03887             uiItemR(row, ptr, "damping", UI_ITEM_R_SLIDER , NULL, ICON_NONE);
03888             uiItemR(row, ptr, "time", 0, NULL, ICON_NONE);
03889 
03890             row=uiLayoutRow(layout, 0);
03891             uiItemR(row, ptr, "rotation_max", 0, NULL, ICON_NONE);
03892 
03893             row=uiLayoutRow(layout, 1);
03894             uiItemR(row, ptr, "angle_min", 0, NULL, ICON_NONE);
03895             uiItemR(row, ptr, "angle_max", 0, NULL, ICON_NONE);
03896             break;
03897 
03898         case ACT_CONST_TYPE_FH:
03899             split=uiLayoutSplit(layout, 0.75, 0);
03900             row= uiLayoutRow(split, 0);
03901             uiItemR(row, ptr, "fh_damping", UI_ITEM_R_SLIDER , NULL, ICON_NONE);
03902 
03903             uiItemR(row, ptr, "fh_height", 0, NULL, ICON_NONE);
03904             uiItemR(split, ptr, "use_fh_paralel_axis", UI_ITEM_R_TOGGLE , NULL, ICON_NONE);
03905 
03906             row = uiLayoutRow(layout, 0);
03907             uiItemR(row, ptr, "direction_axis", 0, NULL, ICON_NONE);
03908             split = uiLayoutSplit(row, 0.9, 0);
03909             uiItemR(split, ptr, "fh_force", 0, NULL, ICON_NONE);
03910             uiItemR(split, ptr, "use_fh_normal", UI_ITEM_R_TOGGLE , NULL, ICON_NONE);
03911 
03912             split = uiLayoutSplit(layout, 0.15, 0);
03913             uiItemR(split, ptr, "use_material_detect", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
03914             if (RNA_boolean_get(ptr, "use_material_detect"))
03915                 uiItemPointerR(split, ptr, "material", &main_ptr, "materials", NULL, ICON_MATERIAL_DATA);
03916             else
03917                 uiItemR(split, ptr, "property", 0, NULL, ICON_NONE);
03918 
03919             split = uiLayoutSplit(layout, 0.15, 0);
03920             uiItemR(split, ptr, "use_persistent", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
03921 
03922             row = uiLayoutRow(split, 0);
03923             uiItemR(row, ptr, "time", 0, NULL, ICON_NONE);
03924             uiItemR(row, ptr, "damping_rotation", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
03925             break;
03926     }
03927 }
03928 
03929 static void draw_actuator_edit_object(uiLayout *layout, PointerRNA *ptr)
03930 {
03931     Object *ob = (Object *)ptr->id.data;
03932     uiLayout *row, *split, *sub;
03933     uiItemR(layout, ptr, "mode", 0, NULL, ICON_NONE);
03934 
03935     switch (RNA_enum_get(ptr, "mode"))
03936     {
03937         case ACT_EDOB_ADD_OBJECT:
03938             row = uiLayoutRow(layout, 0);
03939             uiItemR(row, ptr, "object", 0, NULL, ICON_NONE);
03940             uiItemR(row, ptr, "time", 0, NULL, ICON_NONE);
03941 
03942             split = uiLayoutSplit(layout, 0.9, 0);
03943             row = uiLayoutRow(split, 0);
03944             uiItemR(row, ptr, "linear_velocity", 0, NULL, ICON_NONE);
03945             uiItemR(split, ptr, "use_local_linear_velocity", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
03946 
03947             split = uiLayoutSplit(layout, 0.9, 0);
03948             row = uiLayoutRow(split, 0);
03949             uiItemR(row, ptr, "angular_velocity", 0, NULL, ICON_NONE);
03950             uiItemR(split, ptr, "use_local_angular_velocity", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
03951             break;
03952         case ACT_EDOB_END_OBJECT:
03953             break;
03954         case ACT_EDOB_REPLACE_MESH:
03955             if(ob->type != OB_MESH) {
03956                 uiItemL(layout, "Mode only available for mesh objects", ICON_NONE);
03957                 break;
03958             }
03959             split = uiLayoutSplit(layout, 0.6, 0);
03960             uiItemR(split, ptr, "mesh", 0, NULL, ICON_NONE);
03961             row = uiLayoutRow(split, 0);
03962             uiItemR(row, ptr, "use_replace_display_mesh", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
03963             uiItemR(row, ptr, "use_replace_physics_mesh", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
03964             break;
03965         case ACT_EDOB_TRACK_TO:
03966             split = uiLayoutSplit(layout, 0.5, 0);
03967             uiItemR(split, ptr, "track_object", 0, NULL, ICON_NONE);
03968             sub = uiLayoutSplit(split, 0.7, 0);
03969             uiItemR(sub, ptr, "time", 0, NULL, ICON_NONE);
03970             uiItemR(sub, ptr, "use_3d_tracking", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
03971             break;
03972         case ACT_EDOB_DYNAMICS:
03973             if(ob->type != OB_MESH) {
03974                 uiItemL(layout, "Mode only available for mesh objects", ICON_NONE);
03975                 break;
03976             }
03977             uiItemR(layout, ptr, "dynamic_operation", 0, NULL, ICON_NONE);
03978             if (RNA_enum_get(ptr, "dynamic_operation") == ACT_EDOB_SET_MASS)
03979                 uiItemR(layout, ptr, "mass", 0, NULL, ICON_NONE);
03980             break;
03981     }
03982 }
03983 
03984 static void draw_actuator_filter_2d(uiLayout *layout, PointerRNA *ptr)
03985 {
03986     uiLayout *row, *split;
03987 
03988     uiItemR(layout, ptr, "mode", 0, NULL, ICON_NONE);
03989     switch (RNA_enum_get(ptr, "mode"))
03990     {
03991         case ACT_2DFILTER_CUSTOMFILTER:
03992             uiItemR(layout, ptr, "filter_pass", 0, NULL, ICON_NONE);
03993             uiItemR(layout, ptr, "glsl_shader", 0, NULL, ICON_NONE);
03994             break;
03995         case ACT_2DFILTER_MOTIONBLUR:
03996             split=uiLayoutSplit(layout, 0.75, 1);
03997             row= uiLayoutRow(split, 0);
03998             uiLayoutSetActive(row, RNA_boolean_get(ptr, "use_motion_blur")==1);
03999             uiItemR(row, ptr, "motion_blur_factor", 0, NULL, ICON_NONE);
04000             uiItemR(split, ptr, "use_motion_blur", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
04001             break;
04002         default: // all other 2D Filters
04003             uiItemR(layout, ptr, "filter_pass", 0, NULL, ICON_NONE);
04004             break;
04005     }
04006 }
04007 
04008 static void draw_actuator_game(uiLayout *layout, PointerRNA *ptr)
04009 {
04010     uiItemR(layout, ptr, "mode", 0, NULL, ICON_NONE);
04011     if (RNA_enum_get(ptr, "mode") == ACT_GAME_LOAD)
04012         uiItemR(layout, ptr, "filename", 0, NULL, ICON_NONE);
04013 }
04014 
04015 static void draw_actuator_message(uiLayout *layout, PointerRNA *ptr, bContext *C)
04016 {
04017     Object *ob;
04018     PointerRNA main_ptr, settings_ptr;
04019     uiLayout *row;
04020 
04021     RNA_main_pointer_create(CTX_data_main(C), &main_ptr);
04022 
04023     ob = (Object *)ptr->id.data;
04024     RNA_pointer_create((ID *)ob, &RNA_GameObjectSettings, ob, &settings_ptr);
04025 
04026     uiItemPointerR(layout, ptr, "to_property", &main_ptr, "objects", NULL, ICON_OBJECT_DATA);
04027     uiItemR(layout, ptr, "subject", 0, NULL, ICON_NONE);
04028 
04029     row= uiLayoutRow(layout, 1);
04030     uiItemR(row, ptr, "body_type", 0, NULL, ICON_NONE);
04031 
04032     if(RNA_enum_get(ptr, "body_type") == ACT_MESG_MESG)
04033         uiItemR(row, ptr, "body_message", 0, "", ICON_NONE);
04034     else // mode == ACT_MESG_PROP
04035         uiItemPointerR(row, ptr, "body_property", &settings_ptr, "properties", "", ICON_NONE);
04036 }
04037 
04038 static void draw_actuator_motion(uiLayout *layout, PointerRNA *ptr)
04039 {
04040     Object *ob;
04041     PointerRNA settings_ptr;
04042     uiLayout *split, *row, *col, *sub;
04043     int physics_type;
04044 
04045     ob = (Object *)ptr->id.data;    
04046     RNA_pointer_create((ID *)ob, &RNA_GameObjectSettings, ob, &settings_ptr);
04047     physics_type = RNA_enum_get(&settings_ptr, "physics_type");
04048     
04049     uiItemR(layout, ptr, "mode", 0, NULL, ICON_NONE);
04050     
04051     switch (RNA_enum_get(ptr, "mode")) {
04052         case ACT_OBJECT_NORMAL:
04053             split = uiLayoutSplit(layout, 0.9, 0);
04054             row = uiLayoutRow(split, 0);
04055             uiItemR(row, ptr, "offset_location", 0, NULL, ICON_NONE);
04056             uiItemR(split, ptr, "use_local_location", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
04057 
04058             split = uiLayoutSplit(layout, 0.9, 0);
04059             row = uiLayoutRow(split, 0);
04060             uiItemR(row, ptr, "offset_rotation", 0, NULL, ICON_NONE);
04061             uiItemR(split, ptr, "use_local_rotation", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
04062             
04063             if (ELEM3(physics_type, OB_BODY_TYPE_DYNAMIC, OB_BODY_TYPE_RIGID, OB_BODY_TYPE_SOFT)) {         
04064                 uiItemL(layout, "Dynamic Object Settings:", ICON_NONE);
04065                 split = uiLayoutSplit(layout, 0.9, 0);
04066                 row = uiLayoutRow(split, 0);
04067                 uiItemR(row, ptr, "force", 0, NULL, ICON_NONE);
04068                 uiItemR(split, ptr, "use_local_force", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
04069 
04070                 split = uiLayoutSplit(layout, 0.9, 0);
04071                 row = uiLayoutRow(split, 0);
04072                 uiItemR(row, ptr, "torque", 0, NULL, ICON_NONE);
04073                 uiItemR(split, ptr, "use_local_torque", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
04074 
04075                 split = uiLayoutSplit(layout, 0.9, 0);
04076                 row = uiLayoutRow(split, 0);
04077                 uiItemR(row, ptr, "linear_velocity", 0, NULL, ICON_NONE);
04078                 row = uiLayoutRow(split, 1);
04079                 uiItemR(row, ptr, "use_local_linear_velocity", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
04080                 uiItemR(row, ptr, "use_add_linear_velocity", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
04081 
04082                 split = uiLayoutSplit(layout, 0.9, 0);
04083                 row = uiLayoutRow(split, 0);
04084                 uiItemR(row, ptr, "angular_velocity", 0, NULL, ICON_NONE);
04085                 uiItemR(split, ptr, "use_local_angular_velocity", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
04086 
04087                 uiItemR(layout, ptr, "damping", 0, NULL, ICON_NONE);
04088             }
04089             break;
04090         case ACT_OBJECT_SERVO:
04091             uiItemR(layout, ptr, "reference_object", 0, NULL, ICON_NONE);
04092 
04093             split = uiLayoutSplit(layout, 0.9, 0);
04094             row = uiLayoutRow(split, 0);
04095             uiItemR(row, ptr, "linear_velocity", 0, NULL, ICON_NONE);
04096             uiItemR(split, ptr, "use_local_linear_velocity", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
04097 
04098             row = uiLayoutRow(layout, 0);
04099             col = uiLayoutColumn(row, 0);
04100             uiItemR(col, ptr, "use_servo_limit_x", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
04101             sub = uiLayoutColumn(col, 1);
04102             uiLayoutSetActive(sub, RNA_boolean_get(ptr, "use_servo_limit_x")==1);
04103             uiItemR(sub, ptr, "force_max_x", 0, NULL, ICON_NONE);
04104             uiItemR(sub, ptr, "force_min_x", 0, NULL, ICON_NONE);
04105 
04106             col = uiLayoutColumn(row, 0);
04107             uiItemR(col, ptr, "use_servo_limit_y", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
04108             sub = uiLayoutColumn(col, 1);
04109             uiLayoutSetActive(sub, RNA_boolean_get(ptr, "use_servo_limit_y")==1);
04110             uiItemR(sub, ptr, "force_max_y", 0, NULL, ICON_NONE);
04111             uiItemR(sub, ptr, "force_min_y", 0, NULL, ICON_NONE);
04112 
04113             col = uiLayoutColumn(row, 0);
04114             uiItemR(col, ptr, "use_servo_limit_z", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
04115             sub = uiLayoutColumn(col, 1);
04116             uiLayoutSetActive(sub, RNA_boolean_get(ptr, "use_servo_limit_z")==1);
04117             uiItemR(sub, ptr, "force_max_z", 0, NULL, ICON_NONE);
04118             uiItemR(sub, ptr, "force_min_z", 0, NULL, ICON_NONE);
04119 
04120             //XXXACTUATOR missing labels from original 2.49 ui (e.g. Servo, Min, Max, Fast)
04121             //Layout designers willing to help on that, please compare with 2.49 ui
04122             // (since the old code is going to be deleted ... soon)
04123 
04124             col = uiLayoutColumn(layout, 1);
04125             uiItemR(col, ptr, "proportional_coefficient", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
04126             uiItemR(col, ptr, "integral_coefficient", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
04127             uiItemR(col, ptr, "derivate_coefficient", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
04128             break;
04129     }
04130 }
04131 
04132 static void draw_actuator_parent(uiLayout *layout, PointerRNA *ptr)
04133 {
04134     uiLayout *row, *sub;
04135 
04136     uiItemR(layout, ptr, "mode", 0, NULL, ICON_NONE);
04137 
04138     if (RNA_enum_get(ptr, "mode") == ACT_PARENT_SET) {
04139         uiItemR(layout, ptr, "object", 0, NULL, ICON_NONE);
04140 
04141         row = uiLayoutRow(layout, 0);
04142         uiItemR(row, ptr, "use_compound", 0, NULL, ICON_NONE);
04143         sub= uiLayoutRow(row, 0);
04144         uiLayoutSetActive(sub, RNA_boolean_get(ptr, "use_compound")==1);
04145         uiItemR(sub, ptr, "use_ghost", 0, NULL, ICON_NONE);
04146     }
04147 }
04148 
04149 static void draw_actuator_property(uiLayout *layout, PointerRNA *ptr)
04150 {
04151     Object *ob = (Object *)ptr->id.data;
04152     bActuator *act = (bActuator *)ptr->data;
04153     bPropertyActuator *pa = (bPropertyActuator *) act->data;
04154     Object *ob_from= pa->ob;
04155     PointerRNA settings_ptr, obj_settings_ptr;
04156 
04157     uiLayout *row, *sub;
04158 
04159     RNA_pointer_create((ID *)ob, &RNA_GameObjectSettings, ob, &settings_ptr);
04160 
04161     uiItemR(layout, ptr, "mode", 0, NULL, ICON_NONE);
04162     uiItemPointerR(layout, ptr, "property", &settings_ptr, "properties", NULL, ICON_NONE);
04163 
04164     switch(RNA_enum_get(ptr, "mode"))
04165     {
04166         case ACT_PROP_TOGGLE:
04167             break;
04168         case ACT_PROP_ADD:
04169             uiItemR(layout, ptr, "value", 0, NULL, ICON_NONE);
04170             break;
04171         case ACT_PROP_ASSIGN:
04172             uiItemR(layout, ptr, "value", 0, NULL, ICON_NONE);
04173             break;
04174         case ACT_PROP_COPY:
04175             row = uiLayoutRow(layout, 0);
04176             uiItemR(row, ptr, "object", 0, NULL, ICON_NONE);
04177             if(ob_from){
04178                 RNA_pointer_create((ID *)ob_from, &RNA_GameObjectSettings, ob_from, &obj_settings_ptr);
04179                 uiItemPointerR(row, ptr, "object_property", &obj_settings_ptr, "properties", NULL, ICON_NONE);
04180             }else
04181             {
04182                 sub= uiLayoutRow(row, 0);
04183                 uiLayoutSetActive(sub, 0);
04184                 uiItemR(sub, ptr, "object_property", 0, NULL, ICON_NONE);
04185             }
04186             break;
04187     }
04188 }
04189 
04190 static void draw_actuator_random(uiLayout *layout, PointerRNA *ptr)
04191 {
04192     Object *ob;
04193     PointerRNA settings_ptr;
04194     uiLayout *row;
04195 
04196     ob = (Object *)ptr->id.data;
04197     RNA_pointer_create((ID *)ob, &RNA_GameObjectSettings, ob, &settings_ptr);
04198 
04199     row = uiLayoutRow(layout, 0);
04200 
04201     uiItemR(row, ptr, "seed", 0, NULL, ICON_NONE);
04202     uiItemR(row, ptr, "distribution", 0, NULL, ICON_NONE);
04203 
04204     row = uiLayoutRow(layout, 0);
04205     uiItemPointerR(row, ptr, "property", &settings_ptr, "properties", NULL, ICON_NONE);
04206 
04207     row = uiLayoutRow(layout, 0);
04208 
04209     switch (RNA_enum_get(ptr, "distribution")){
04210         case ACT_RANDOM_BOOL_CONST:
04211             uiItemR(row, ptr, "use_always_true", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
04212             break;
04213 
04214         case ACT_RANDOM_BOOL_UNIFORM:
04215             uiItemL(row, "Choose between true and false, 50% chance each", ICON_NONE);
04216             break;
04217 
04218         case ACT_RANDOM_BOOL_BERNOUILLI:
04219             uiItemR(row, ptr, "chance", 0, NULL, ICON_NONE);
04220             break;
04221 
04222         case ACT_RANDOM_INT_CONST:
04223             uiItemR(row, ptr, "int_value", 0, NULL, ICON_NONE);
04224             break;
04225 
04226         case ACT_RANDOM_INT_UNIFORM:
04227             uiItemR(row, ptr, "int_min", 0, NULL, ICON_NONE);
04228             uiItemR(row, ptr, "int_max", 0, NULL, ICON_NONE);
04229             break;
04230 
04231         case ACT_RANDOM_INT_POISSON:
04232             uiItemR(row, ptr, "int_mean", 0, NULL, ICON_NONE);
04233             break;
04234 
04235         case ACT_RANDOM_FLOAT_CONST:
04236             uiItemR(row, ptr, "float_value", 0, NULL, ICON_NONE);
04237             break;
04238 
04239         case ACT_RANDOM_FLOAT_UNIFORM:
04240             uiItemR(row, ptr, "float_min", 0, NULL, ICON_NONE);
04241             uiItemR(row, ptr, "float_max", 0, NULL, ICON_NONE);
04242             break;
04243 
04244         case ACT_RANDOM_FLOAT_NORMAL:
04245             uiItemR(row, ptr, "float_mean", 0, NULL, ICON_NONE);
04246             uiItemR(row, ptr, "standard_derivation", 0, NULL, ICON_NONE);
04247             break;
04248 
04249         case ACT_RANDOM_FLOAT_NEGATIVE_EXPONENTIAL:
04250             uiItemR(row, ptr, "half_life_time", 0, NULL, ICON_NONE);
04251             break;
04252     }
04253 }
04254 
04255 static void draw_actuator_scene(uiLayout *layout, PointerRNA *ptr)
04256 {
04257     uiItemR(layout, ptr, "mode", 0, NULL, ICON_NONE);
04258 
04259     switch (RNA_enum_get(ptr, "mode")) {
04260         case ACT_SCENE_CAMERA:
04261             uiItemR(layout, ptr, "camera", 0, NULL, ICON_NONE);
04262             break;
04263         case ACT_SCENE_RESTART:
04264             break;
04265         default: // ACT_SCENE_SET|ACT_SCENE_ADD_FRONT|ACT_SCENE_ADD_BACK|ACT_SCENE_REMOVE|ACT_SCENE_SUSPEND|ACT_SCENE_RESUME
04266             uiItemR(layout, ptr, "scene", 0, NULL, ICON_NONE);
04267             break;
04268     }
04269 }
04270 
04271 static void draw_actuator_shape_action(uiLayout *layout, PointerRNA *ptr)
04272 {
04273     Object *ob = (Object *)ptr->id.data;
04274     PointerRNA settings_ptr;
04275     uiLayout *row;
04276 
04277     if(ob->type != OB_MESH){
04278         uiItemL(layout, "Actuator only available for mesh objects", ICON_NONE);
04279         return;
04280     }
04281 
04282     RNA_pointer_create((ID *)ob, &RNA_GameObjectSettings, ob, &settings_ptr);
04283 
04284     row= uiLayoutRow(layout, 0);
04285     uiItemR(row, ptr, "mode", 0, "", ICON_NONE);
04286     uiItemR(row, ptr, "action", 0, "", ICON_NONE);
04287     uiItemR(row, ptr, "use_continue_last_frame", 0, NULL, ICON_NONE);
04288 
04289     row= uiLayoutRow(layout, 0);
04290     if((RNA_enum_get(ptr, "mode") == ACT_ACTION_FROM_PROP))
04291         uiItemPointerR(row, ptr, "property", &settings_ptr, "properties", NULL, ICON_NONE);
04292 
04293     else {
04294         uiItemR(row, ptr, "frame_start", 0, NULL, ICON_NONE);
04295         uiItemR(row, ptr, "frame_end", 0, NULL, ICON_NONE);
04296     }
04297 
04298     row= uiLayoutRow(layout, 0);
04299     uiItemR(row, ptr, "frame_blend_in", 0, NULL, ICON_NONE);
04300     uiItemR(row, ptr, "priority", 0, NULL, ICON_NONE);
04301 
04302     row= uiLayoutRow(layout, 0);
04303     uiItemPointerR(row, ptr, "frame_property", &settings_ptr, "properties", NULL, ICON_NONE);
04304 
04305 #ifdef __NLA_ACTION_BY_MOTION_ACTUATOR
04306     uiItemR(row, "stride_length", 0, NULL, ICON_NONE);
04307 #endif
04308 }
04309 
04310 static void draw_actuator_sound(uiLayout *layout, PointerRNA *ptr, bContext *C)
04311 {
04312     uiLayout *row, *col;
04313 
04314     uiTemplateID(layout, C, ptr, "sound", NULL, "SOUND_OT_open", NULL);
04315     if (!RNA_pointer_get(ptr, "sound").data)
04316     {
04317         uiItemL(layout, "Select a sound from the list or load a new one", ICON_NONE);
04318         return;
04319     }
04320     uiItemR(layout, ptr, "mode", 0, NULL, ICON_NONE);
04321 
04322     row = uiLayoutRow(layout, 0);
04323     uiItemR(row, ptr, "volume", 0, NULL, ICON_NONE);
04324     uiItemR(row, ptr, "pitch", 0, NULL, ICON_NONE);
04325 
04326     uiItemR(layout, ptr, "use_sound_3d", 0, NULL, ICON_NONE);
04327     
04328     col = uiLayoutColumn(layout, 0);
04329     uiLayoutSetActive(col, RNA_boolean_get(ptr, "use_sound_3d")==1);
04330 
04331     row = uiLayoutRow(col, 0);
04332     uiItemR(row, ptr, "gain_3d_min", 0, NULL, ICON_NONE);
04333     uiItemR(row, ptr, "gain_3d_max", 0, NULL, ICON_NONE);
04334 
04335     row = uiLayoutRow(col, 0);
04336     uiItemR(row, ptr, "distance_3d_reference", 0, NULL, ICON_NONE);
04337     uiItemR(row, ptr, "distance_3d_max", 0, NULL, ICON_NONE);
04338 
04339     row = uiLayoutRow(col, 0);
04340     uiItemR(row, ptr, "rolloff_factor_3d", 0, NULL, ICON_NONE);
04341     uiItemR(row, ptr, "cone_outer_gain_3d", 0, NULL, ICON_NONE);
04342 
04343     row = uiLayoutRow(col, 0);
04344     uiItemR(row, ptr, "cone_outer_angle_3d", 0, NULL, ICON_NONE);
04345     uiItemR(row, ptr, "cone_inner_angle_3d", 0, NULL, ICON_NONE);
04346 }
04347 
04348 static void draw_actuator_state(uiLayout *layout, PointerRNA *ptr)
04349 {
04350     uiLayout *split;
04351     Object *ob = (Object *)ptr->id.data;
04352     PointerRNA settings_ptr;
04353     RNA_pointer_create((ID *)ob, &RNA_GameObjectSettings, ob, &settings_ptr);
04354 
04355     split = uiLayoutSplit(layout, 0.35, 0);
04356     uiItemR(split, ptr, "operation", 0, NULL, ICON_NONE);
04357 
04358     uiTemplateLayers(split, ptr, "states", &settings_ptr, "used_states", 0);
04359 }
04360 
04361 static void draw_actuator_visibility(uiLayout *layout, PointerRNA *ptr)
04362 {
04363     uiLayout *row;
04364     row = uiLayoutRow(layout, 0);
04365 
04366     uiItemR(row, ptr, "use_visible", 0, NULL, ICON_NONE);
04367     uiItemR(row, ptr, "use_occlusion", 0, NULL, ICON_NONE);
04368     uiItemR(row, ptr, "apply_to_children", 0, NULL, ICON_NONE);
04369 }
04370 
04371 static void draw_actuator_steering(uiLayout *layout, PointerRNA *ptr)
04372 {
04373     uiLayout *row;
04374     uiLayout *col;
04375 
04376     uiItemR(layout, ptr, "mode", 0, NULL, 0);
04377     uiItemR(layout, ptr, "target", 0, NULL, 0);
04378     uiItemR(layout, ptr, "navmesh", 0, NULL, 0);    
04379 
04380     row = uiLayoutRow(layout, 0);
04381     uiItemR(row, ptr, "distance", 0, NULL, 0);
04382     uiItemR(row, ptr, "velocity", 0, NULL, 0);
04383     row = uiLayoutRow(layout, 0);
04384     uiItemR(row, ptr, "acceleration", 0, NULL, 0);
04385     uiItemR(row, ptr, "turn_speed", 0, NULL, 0);
04386 
04387     row = uiLayoutRow(layout, 0);
04388     col = uiLayoutColumn(row, 0);
04389     uiItemR(col, ptr, "facing", 0, NULL, 0);
04390     col = uiLayoutColumn(row, 0);
04391     uiItemR(col, ptr, "facing_axis", 0, NULL, 0);
04392     if (!RNA_boolean_get(ptr, "facing"))
04393     {
04394         uiLayoutSetActive(col, 0);
04395     }
04396     col = uiLayoutColumn(row, 0);
04397     uiItemR(col, ptr, "normal_up", 0, NULL, 0);
04398     if (!RNA_pointer_get(ptr, "navmesh").data)
04399     {
04400         uiLayoutSetActive(col, 0);
04401     }
04402 
04403     row = uiLayoutRow(layout, 0);
04404     uiItemR(row, ptr, "self_terminated", 0, NULL, 0);
04405     if (RNA_enum_get(ptr, "mode")==ACT_STEERING_PATHFOLLOWING)
04406     {
04407         uiItemR(row, ptr, "update_period", 0, NULL, 0); 
04408         row = uiLayoutRow(layout, 0);
04409     }
04410     uiItemR(row, ptr, "show_visualization", 0, NULL, 0);    
04411 }
04412 
04413 static void draw_brick_actuator(uiLayout *layout, PointerRNA *ptr, bContext *C)
04414 {
04415     uiLayout *box;
04416     
04417     if (!RNA_boolean_get(ptr, "show_expanded"))
04418         return;
04419     
04420     box = uiLayoutBox(layout);
04421     
04422     switch (RNA_enum_get(ptr, "type")) {
04423         case ACT_ACTION:
04424             draw_actuator_action(box, ptr);
04425             break;
04426         case ACT_ARMATURE:
04427             draw_actuator_armature(box, ptr);
04428             break;
04429         case ACT_CAMERA:
04430             draw_actuator_camera(box, ptr);
04431             break;
04432         case ACT_CONSTRAINT:
04433             draw_actuator_constraint(box, ptr, C);
04434             break;
04435         case ACT_EDIT_OBJECT:
04436             draw_actuator_edit_object(box, ptr);
04437             break;
04438         case ACT_2DFILTER:
04439             draw_actuator_filter_2d(box, ptr);
04440             break;
04441         case ACT_GAME:
04442             draw_actuator_game(box, ptr);
04443             break;
04444         case ACT_MESSAGE:
04445             draw_actuator_message(box, ptr, C);
04446             break;
04447         case ACT_OBJECT:
04448             draw_actuator_motion(box, ptr);
04449             break;
04450         case ACT_PARENT:
04451             draw_actuator_parent(box, ptr);
04452             break;
04453         case ACT_PROPERTY:
04454             draw_actuator_property(box, ptr);
04455             break;
04456         case ACT_RANDOM:
04457             draw_actuator_random(box, ptr);
04458             break;
04459         case ACT_SCENE:
04460             draw_actuator_scene(box, ptr);
04461             break;
04462         case ACT_SHAPEACTION:
04463             draw_actuator_shape_action(box, ptr);
04464             break;
04465         case ACT_SOUND:
04466             draw_actuator_sound(box, ptr, C);
04467             break;
04468         case ACT_STATE:
04469             draw_actuator_state(box, ptr);
04470             break;
04471         case ACT_VISIBILITY:
04472             draw_actuator_visibility(box, ptr);
04473             break;
04474         case ACT_STEERING:
04475             draw_actuator_steering(box, ptr);
04476     }
04477 }
04478 
04479 static void logic_buttons_new(bContext *C, ARegion *ar)
04480 {
04481     SpaceLogic *slogic= CTX_wm_space_logic(C);
04482     Object *ob= CTX_data_active_object(C);
04483     Object *act_ob= ob;
04484     ID **idar;
04485     
04486     PointerRNA logic_ptr, settings_ptr;
04487     
04488     uiLayout *layout, *row, *box;
04489     uiBlock *block;
04490     uiBut *but;
04491     char uiblockstr[32];
04492     short a, count;
04493     int xco, yco, width;
04494     
04495     if(ob==NULL) return;
04496     
04497     RNA_pointer_create(NULL, &RNA_SpaceLogicEditor, slogic, &logic_ptr);
04498     idar= get_selected_and_linked_obs(C, &count, slogic->scaflag);
04499     
04500     BLI_snprintf(uiblockstr, sizeof(uiblockstr), "buttonswin %p", (void *)ar);
04501     block= uiBeginBlock(C, ar, uiblockstr, UI_EMBOSS);
04502     uiBlockSetHandleFunc(block, do_logic_buts, NULL);
04503     
04504     /* loop over all objects and set visible/linked flags for the logic bricks */
04505     for(a=0; a<count; a++) {
04506         bActuator *act;
04507         bSensor *sens;
04508         bController *cont;
04509         int iact;
04510         short flag;
04511 
04512         ob= (Object *)idar[a];
04513         
04514         /* clean ACT_LINKED and ACT_VISIBLE of all potentially visible actuators so that we can determine which is actually linked/visible */
04515         act = ob->actuators.first;
04516         while(act) {
04517             act->flag &= ~(ACT_LINKED|ACT_VISIBLE);
04518             act = act->next;
04519         }
04520         /* same for sensors */
04521         sens= ob->sensors.first;
04522         while(sens) {
04523             sens->flag &= ~(SENS_VISIBLE);
04524             sens = sens->next;
04525         }
04526 
04527         /* mark the linked and visible actuators */
04528         cont= ob->controllers.first;
04529         while(cont) {
04530             flag = ACT_LINKED;
04531 
04532             /* this controller is visible, mark all its actuator */
04533             if ((ob->scaflag & OB_ALLSTATE) || (ob->state & cont->state_mask))
04534                 flag |= ACT_VISIBLE;
04535 
04536             for (iact=0; iact<cont->totlinks; iact++) {
04537                 act = cont->links[iact];
04538                 if (act)
04539                     act->flag |= flag;
04540             }
04541             cont = cont->next;
04542         }
04543     }
04544     
04545     /* ****************** Controllers ****************** */
04546     
04547     xco= 420; yco= 170; width= 300;
04548     layout= uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, xco, yco, width, 20, UI_GetStyle());
04549     row = uiLayoutRow(layout, 1);
04550     
04551     uiDefBlockBut(block, controller_menu, NULL, "Controllers", xco-10, yco, 300, UI_UNIT_Y, "");        /* replace this with uiLayout stuff later */
04552     
04553     uiItemR(row, &logic_ptr, "show_controllers_selected_objects", 0, "Sel", ICON_NONE);
04554     uiItemR(row, &logic_ptr, "show_controllers_active_object", 0, "Act", ICON_NONE);
04555     uiItemR(row, &logic_ptr, "show_controllers_linked_controller", 0, "Link", ICON_NONE);
04556 
04557     for(a=0; a<count; a++) {
04558         bController *cont;
04559         PointerRNA ptr;
04560         uiLayout *split, *subsplit, *col;
04561 
04562         
04563         ob= (Object *)idar[a];
04564 
04565         /* only draw the controller common header if "use_visible" */
04566         if( (ob->scavisflag & OB_VIS_CONT) == 0) continue;
04567     
04568         /* Drawing the Controller Header common to all Selected Objects */
04569 
04570         RNA_pointer_create((ID *)ob, &RNA_GameObjectSettings, ob, &settings_ptr);
04571 
04572         split= uiLayoutSplit(layout, 0.05, 0);
04573         uiItemR(split, &settings_ptr, "show_state_panel", UI_ITEM_R_NO_BG, "", ICON_DISCLOSURE_TRI_RIGHT);
04574 
04575         row = uiLayoutRow(split, 1);
04576         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");
04577         if (ob == act_ob)
04578             uiItemMenuEnumO(row, "LOGIC_OT_controller_add", "type", "Add Controller", ICON_NONE);
04579 
04580         if (RNA_boolean_get(&settings_ptr, "show_state_panel")) {
04581 
04582             box= uiLayoutBox(layout);
04583             split= uiLayoutSplit(box, 0.2, 0);
04584 
04585             col= uiLayoutColumn(split, 0);
04586             uiItemL(col, "Visible", ICON_NONE);
04587             uiItemL(col, "Initial", ICON_NONE);
04588 
04589             subsplit= uiLayoutSplit(split, 0.85, 0);
04590             col= uiLayoutColumn(subsplit, 0);
04591             row= uiLayoutRow(col, 0);
04592             uiLayoutSetActive(row, RNA_boolean_get(&settings_ptr, "use_all_states")==0);
04593             uiTemplateLayers(row, &settings_ptr, "states_visible", &settings_ptr, "used_states", 0);
04594             row= uiLayoutRow(col, 0);
04595             uiTemplateLayers(row, &settings_ptr, "states_initial", &settings_ptr, "used_states", 0);
04596 
04597             col= uiLayoutColumn(subsplit, 0);
04598             uiItemR(col, &settings_ptr, "use_all_states", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
04599             uiItemR(col, &settings_ptr, "show_debug_state", 0, "", ICON_NONE);
04600         }
04601 
04602         /* End of Drawing the Controller Header common to all Selected Objects */
04603 
04604         if ((ob->scaflag & OB_SHOWCONT) == 0) continue;
04605         
04606 
04607         uiItemS(layout);
04608         
04609         for(cont= ob->controllers.first; cont; cont=cont->next) {
04610             RNA_pointer_create((ID *)ob, &RNA_Controller, cont, &ptr);
04611             
04612             if (!(ob->scaflag & OB_ALLSTATE) && !(ob->state & cont->state_mask))
04613                 continue;
04614             
04615             /* use two nested splits to align inlinks/links properly */
04616             split = uiLayoutSplit(layout, 0.05, 0);
04617             
04618             /* put inlink button to the left */
04619             col = uiLayoutColumn(split, 0);
04620             uiLayoutSetAlignment(col, UI_LAYOUT_ALIGN_LEFT);
04621             uiDefIconBut(block, INLINK, 0, ICON_INLINK, 0, 0, UI_UNIT_X, UI_UNIT_Y, cont, LINK_CONTROLLER, 0, 0, 0, "");
04622             
04623             //col = uiLayoutColumn(split, 1);
04624             /* nested split for middle and right columns */
04625             subsplit = uiLayoutSplit(split, 0.95, 0);
04626             
04627             col = uiLayoutColumn(subsplit, 1);
04628             uiLayoutSetContextPointer(col, "controller", &ptr);
04629             
04630             /* should make UI template for controller header.. function will do for now */
04631 //          draw_controller_header(col, &ptr);
04632             draw_controller_header(col, &ptr, xco, width, yco); //provisory for 2.50 beta
04633 
04634             /* draw the brick contents */
04635             draw_brick_controller(col, &ptr);
04636             
04637             
04638             /* put link button to the right */
04639             col = uiLayoutColumn(subsplit, 0);
04640             uiLayoutSetAlignment(col, UI_LAYOUT_ALIGN_LEFT);
04641             but= uiDefIconBut(block, LINK, 0, ICON_LINK, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, "");
04642             uiSetButLink(but, NULL, (void ***)&(cont->links), &cont->totlinks, LINK_CONTROLLER, LINK_ACTUATOR);
04643         }
04644     }
04645     uiBlockLayoutResolve(block, NULL, &yco);    /* stores final height in yco */
04646     
04647     
04648     /* ****************** Sensors ****************** */
04649     
04650     xco= 10; yco= 170; width= 340;
04651     layout= uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, xco, yco, width, 20, UI_GetStyle());
04652     row = uiLayoutRow(layout, 1);
04653     
04654     uiDefBlockBut(block, sensor_menu, NULL, "Sensors", xco-10, yco, 300, UI_UNIT_Y, "");        /* replace this with uiLayout stuff later */
04655     
04656     uiItemR(row, &logic_ptr, "show_sensors_selected_objects", 0, "Sel", ICON_NONE);
04657     uiItemR(row, &logic_ptr, "show_sensors_active_object", 0, "Act", ICON_NONE);
04658     uiItemR(row, &logic_ptr, "show_sensors_linked_controller", 0, "Link", ICON_NONE);
04659     uiItemR(row, &logic_ptr, "show_sensors_active_states", 0, "State", ICON_NONE);
04660     
04661     for(a=0; a<count; a++) {
04662         bSensor *sens;
04663         PointerRNA ptr;
04664         
04665         ob= (Object *)idar[a];
04666 
04667         /* only draw the sensor common header if "use_visible" */
04668         if((ob->scavisflag & OB_VIS_SENS) == 0) continue;
04669 
04670         row = uiLayoutRow(layout, 1);
04671         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");
04672         if (ob == act_ob)
04673             uiItemMenuEnumO(row, "LOGIC_OT_sensor_add", "type", "Add Sensor", ICON_NONE);
04674         
04675         if ((ob->scaflag & OB_SHOWSENS) == 0) continue;
04676         
04677         uiItemS(layout);
04678         
04679         for(sens= ob->sensors.first; sens; sens=sens->next) {
04680             RNA_pointer_create((ID *)ob, &RNA_Sensor, sens, &ptr);
04681             
04682             if ((ob->scaflag & OB_ALLSTATE) ||
04683                 !(slogic->scaflag & BUTS_SENS_STATE) ||
04684                 (sens->totlinks == 0) ||                                            /* always display sensor without links so that is can be edited */
04685                 (sens->flag & SENS_PIN && slogic->scaflag & BUTS_SENS_STATE) || /* states can hide some sensors, pinned sensors ignore the visible state */
04686                 (is_sensor_linked(block, sens))
04687                 )
04688             {   // gotta check if the current state is visible or not
04689                 uiLayout *split, *col;
04690                 
04691                 /* make as visible, for move operator */
04692                 sens->flag |= SENS_VISIBLE;
04693 
04694                 split = uiLayoutSplit(layout, 0.95, 0);
04695                 col = uiLayoutColumn(split, 1);
04696                 uiLayoutSetContextPointer(col, "sensor", &ptr);
04697                 
04698                 /* should make UI template for sensor header.. function will do for now */
04699                 draw_sensor_header(col, &ptr, &logic_ptr);
04700                 
04701                 /* draw the brick contents */
04702                 draw_brick_sensor(col, &ptr, C);
04703                 
04704                 /* put link button to the right */
04705                 col = uiLayoutColumn(split, 0);
04706                 /* use oldskool uiButtons for links for now */
04707                 but= uiDefIconBut(block, LINK, 0, ICON_LINK, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, "");
04708                 uiSetButLink(but, NULL, (void ***)&(sens->links), &sens->totlinks, LINK_SENSOR, LINK_CONTROLLER);
04709             }
04710         }
04711     }
04712     uiBlockLayoutResolve(block, NULL, &yco);    /* stores final height in yco */
04713     
04714     /* ****************** Actuators ****************** */
04715     
04716     xco= 800; yco= 170; width= 340;
04717     layout= uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, xco, yco, width, 20, UI_GetStyle());
04718     row = uiLayoutRow(layout, 1);
04719     
04720     uiDefBlockBut(block, actuator_menu, NULL, "Actuators", xco-10, yco, 300, UI_UNIT_Y, "");        /* replace this with uiLayout stuff later */
04721     
04722     uiItemR(row, &logic_ptr, "show_actuators_selected_objects", 0, "Sel", ICON_NONE);
04723     uiItemR(row, &logic_ptr, "show_actuators_active_object", 0, "Act", ICON_NONE);
04724     uiItemR(row, &logic_ptr, "show_actuators_linked_controller", 0, "Link", ICON_NONE);
04725     uiItemR(row, &logic_ptr, "show_actuators_active_states", 0, "State", ICON_NONE);
04726     
04727     for(a=0; a<count; a++) {
04728         bActuator *act;
04729         PointerRNA ptr;
04730         
04731         ob= (Object *)idar[a];
04732 
04733         /* only draw the actuator common header if "use_visible" */
04734         if( (ob->scavisflag & OB_VIS_ACT) == 0) continue;
04735 
04736         row = uiLayoutRow(layout, 1);
04737         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");
04738         if (ob == act_ob)
04739             uiItemMenuEnumO(row, "LOGIC_OT_actuator_add", "type", "Add Actuator", ICON_NONE);
04740 
04741         if ((ob->scaflag & OB_SHOWACT) == 0) continue;
04742         
04743         uiItemS(layout);
04744         
04745         for(act= ob->actuators.first; act; act=act->next) {
04746             
04747             RNA_pointer_create((ID *)ob, &RNA_Actuator, act, &ptr);
04748             
04749             if ((ob->scaflag & OB_ALLSTATE) ||
04750                 !(slogic->scaflag & BUTS_ACT_STATE) ||
04751                 !(act->flag & ACT_LINKED) ||        /* always display actuators without links so that is can be edited */
04752                 (act->flag & ACT_VISIBLE) ||        /* this actuator has visible connection, display it */
04753                 (act->flag & ACT_PIN && slogic->scaflag & BUTS_ACT_STATE)   /* states can hide some sensors, pinned sensors ignore the visible state */
04754                 )
04755             {   // gotta check if the current state is visible or not
04756                 uiLayout *split, *col;
04757                 
04758                 /* make as visible, for move operator */
04759                 act->flag |= ACT_VISIBLE;
04760 
04761                 split = uiLayoutSplit(layout, 0.05, 0);
04762                 
04763                 /* put inlink button to the left */
04764                 col = uiLayoutColumn(split, 0);
04765                 uiDefIconBut(block, INLINK, 0, ICON_INLINK, 0, 0, UI_UNIT_X, UI_UNIT_Y, act, LINK_ACTUATOR, 0, 0, 0, "");
04766 
04767                 col = uiLayoutColumn(split, 1);
04768                 uiLayoutSetContextPointer(col, "actuator", &ptr);
04769                 
04770                 /* should make UI template for actuator header.. function will do for now */
04771                 draw_actuator_header(col, &ptr, &logic_ptr);
04772                 
04773                 /* draw the brick contents */
04774                 draw_brick_actuator(col, &ptr, C);
04775                 
04776             }
04777         }
04778     }
04779     uiBlockLayoutResolve(block, NULL, &yco);    /* stores final height in yco */
04780     
04781     
04782     uiComposeLinks(block);
04783     
04784     uiEndBlock(C, block);
04785     uiDrawBlock(C, block);
04786     
04787     if(idar) MEM_freeN(idar);
04788 }
04789 
04790 void logic_buttons(bContext *C, ARegion *ar)
04791 {
04792     Main *bmain= CTX_data_main(C);
04793     SpaceLogic *slogic= CTX_wm_space_logic(C);
04794     Object *ob= CTX_data_active_object(C);
04795     ID **idar;
04796     bSensor *sens;
04797     bController *cont;
04798     bActuator *act;
04799     uiBlock *block;
04800     uiBut *but;
04801     PointerRNA logic_ptr;
04802     int a, iact, stbit, offset;
04803     int xco, yco, width, ycoo;
04804     short count;
04805     char numstr[32];
04806     /* pin is a bool used for actuator and sensor drawing with states
04807      * pin so changing states dosnt hide the logic brick */
04808     char pin;
04809 
04810     if (G.rt == 0) {
04811         logic_buttons_new(C, ar);
04812         return;
04813     }
04814     
04815     if(ob==NULL) return;
04816 //  uiSetButLock(object_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
04817 
04818     BLI_snprintf(numstr, sizeof(numstr), "buttonswin %p", (void *)ar);
04819     block= uiBeginBlock(C, ar, numstr, UI_EMBOSS);
04820     uiBlockSetHandleFunc(block, do_logic_buts, NULL);
04821 
04822     RNA_pointer_create(NULL, &RNA_SpaceLogicEditor, slogic, &logic_ptr);
04823     
04824     idar= get_selected_and_linked_obs(C, &count, slogic->scaflag);
04825 
04826     /* clean ACT_LINKED and ACT_VISIBLE of all potentially visible actuators so that 
04827        we can determine which is actually linked/visible */
04828     for(a=0; a<count; a++) {
04829         ob= (Object *)idar[a];
04830         act= ob->actuators.first;
04831         while(act) {
04832             act->flag &= ~(ACT_LINKED|ACT_VISIBLE);
04833             act = act->next;
04834         }
04835         /* same for sensors */
04836         sens= ob->sensors.first;
04837         while(sens) {
04838             sens->flag &= ~(SENS_VISIBLE);
04839             sens = sens->next;
04840         }
04841     }
04842         
04843     /* start with the controller because we need to know which one is visible */
04844     /* ******************************* */
04845     xco= 400; yco= 170; width= 300;
04846 
04847     uiDefBlockBut(block, controller_menu, NULL, "Controllers", xco-10, yco+35, 100, UI_UNIT_Y, "");
04848     
04849     uiBlockBeginAlign(block);
04850     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");
04851     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");
04852     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");
04853     uiBlockEndAlign(block);
04854     
04855     for(a=0; a<count; a++) {
04856         unsigned int controller_state_mask = 0; /* store a bitmask for states that are used */
04857         
04858         ob= (Object *)idar[a];
04859 //      uiClearButLock();
04860 //      uiSetButLock(object_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
04861         if( (ob->scavisflag & OB_VIS_CONT) == 0) continue;
04862 
04863         /* presume it is only objects for now */
04864         uiBlockBeginAlign(block);
04865 //      if(ob->controllers.first) uiSetCurFont(block, UI_HELVB);
04866         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");
04867 //      if(ob->controllers.first) uiSetCurFont(block, UI_HELV);
04868         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");
04869         uiBlockEndAlign(block);
04870         yco-=20;
04871         
04872         /* mark all actuators linked to these controllers */
04873         /* note that some of these actuators could be from objects that are not in the display list.
04874            It's ok because those actuators will not be displayed here */
04875         cont= ob->controllers.first;
04876         while(cont) {
04877             for (iact=0; iact<cont->totlinks; iact++) {
04878                 act = cont->links[iact];
04879                 if (act)
04880                     act->flag |= ACT_LINKED;
04881             }
04882             controller_state_mask |= cont->state_mask;
04883             cont = cont->next;
04884         }
04885 
04886         if(ob->scaflag & OB_SHOWCONT) {
04887 
04888             /* first show the state */
04889             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");
04890 
04891             if (!ob->state)
04892                 ob->state = 1;
04893             for (offset=0; offset<15; offset+=5) {
04894                 uiBlockBeginAlign(block);
04895                 for (stbit=0; stbit<5; stbit++) {
04896                     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)));
04897                     uiButSetFunc(but, check_state_mask, but, &(ob->state));
04898                 }
04899                 for (stbit=0; stbit<5; stbit++) {
04900                     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)));
04901                     uiButSetFunc(but, check_state_mask, but, &(ob->state));
04902                 }
04903             }
04904             uiBlockBeginAlign(block);
04905             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");
04906             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");
04907             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");
04908             uiBlockEndAlign(block);
04909 
04910             yco-=35;
04911         
04912             /* display only the controllers that match the current state */
04913             offset = 0;
04914             for (stbit=0; stbit<32; stbit++) {
04915                 if (!(ob->state & (1<<stbit)))
04916                     continue;
04917                 /* add a separation between controllers of different states */
04918                 if (offset) {
04919                     offset = 0;
04920                     yco -= 6;
04921                 }
04922                 cont= ob->controllers.first;
04923                 while(cont) {
04924                     if (cont->state_mask & (1<<stbit)) {
04925                         /* this controller is visible, mark all its actuator */
04926                         for (iact=0; iact<cont->totlinks; iact++) {
04927                             act = cont->links[iact];
04928                             if (act)
04929                                 act->flag |= ACT_VISIBLE;
04930                         }
04931                         uiDefIconButBitS(block, TOG, CONT_DEL, B_DEL_CONT, ICON_X,  xco, yco, 22, UI_UNIT_Y, &cont->flag, 0, 0, 0, 0, "Delete Controller");
04932                         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");
04933                         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)");
04934 
04935                         sprintf(numstr, "%d", first_bit(cont->state_mask)+1);
04936                         uiDefBlockBut(block, controller_state_mask_menu, cont, numstr, (short)(xco+width-44), yco, 22, UI_UNIT_Y, "Set controller state index (from 1 to 30)");
04937                 
04938                         if(cont->flag & CONT_SHOW) {
04939                             cont->otype= cont->type;
04940                             uiDefButS(block, MENU, B_CHANGE_CONT, controller_pup(),(short)(xco+22), yco, 70, UI_UNIT_Y, &cont->type, 0, 0, 0, 0, "Controller type");
04941                             but= uiDefBut(block, TEX, 1, "", (short)(xco+92), yco, (short)(width-158), UI_UNIT_Y, cont->name, 0, MAX_NAME, 0, 0, "Controller name");
04942                             uiButSetFunc(but, make_unique_prop_names_cb, cont->name, (void*) 0);
04943                 
04944                             ycoo= yco;
04945                             yco= draw_controllerbuttons(cont, block, xco, yco, width);
04946                             if(yco-6 < ycoo) ycoo= (yco+ycoo-20)/2;
04947                         }
04948                         else {
04949                             cpack(0x999999);
04950                             glRecti(xco+22, yco, xco+width-22,yco+19);
04951                             but= uiDefBut(block, LABEL, 0, controller_name(cont->type), (short)(xco+22), yco, 70, UI_UNIT_Y, cont, 0, 0, 0, 0, "Controller type");
04952                             //uiButSetFunc(but, old_sca_move_controller, cont, NULL);
04953                             but= uiDefBut(block, LABEL, 0, cont->name,(short)(xco+92), yco,(short)(width-158), UI_UNIT_Y, cont, 0, 0, 0, 0, "Controller name");
04954                             //uiButSetFunc(but, old_sca_move_controller, cont, NULL);
04955 
04956                             uiBlockBeginAlign(block);
04957                             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");
04958                             uiButSetFunc(but, old_sca_move_controller, cont, (void *)TRUE);
04959                             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");
04960                             uiButSetFunc(but, old_sca_move_controller, cont, (void *)FALSE);
04961                             uiBlockEndAlign(block);
04962 
04963                             ycoo= yco;
04964                         }
04965                 
04966                         but= uiDefIconBut(block, LINK, 0, ICON_LINK,    (short)(xco+width), ycoo, UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, "");
04967                         uiSetButLink(but, NULL, (void ***)&(cont->links), &cont->totlinks, LINK_CONTROLLER, LINK_ACTUATOR);
04968                 
04969                         uiDefIconBut(block, INLINK, 0, ICON_INLINK,(short)(xco-19), ycoo, UI_UNIT_X, UI_UNIT_Y, cont, LINK_CONTROLLER, 0, 0, 0, "");
04970                         /* offset is >0 if at least one controller was displayed */
04971                         offset++;
04972                         yco-=20;
04973                     }
04974                     cont= cont->next;
04975                 }
04976 
04977             }
04978             yco-= 6;
04979         }
04980     }
04981 
04982     /* ******************************* */
04983     xco= 10; yco= 170; width= 300;
04984 
04985     uiDefBlockBut(block, sensor_menu, NULL, "Sensors", xco-10, yco+35, 70, UI_UNIT_Y, "");
04986     
04987     uiBlockBeginAlign(block);
04988     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");
04989     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");
04990     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");
04991     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");
04992     uiBlockEndAlign(block);
04993     
04994     for(a=0; a<count; a++) {
04995         ob= (Object *)idar[a];
04996 //      uiClearButLock();
04997 //      uiSetButLock(object_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
04998         
04999         if( (ob->scavisflag & OB_VIS_SENS) == 0) continue;
05000         
05001         /* presume it is only objects for now */
05002         uiBlockBeginAlign(block);
05003 //      if(ob->sensors.first) uiSetCurFont(block, UI_HELVB);
05004         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");
05005 //      if(ob->sensors.first) uiSetCurFont(block, UI_HELV);
05006         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");
05007         uiBlockEndAlign(block);
05008         yco-=20;
05009         
05010         if(ob->scaflag & OB_SHOWSENS) {
05011             
05012             sens= ob->sensors.first;
05013             while(sens) {
05014                 if (!(slogic->scaflag & BUTS_SENS_STATE) ||
05015                      (sens->totlinks == 0) ||       /* always display sensor without links so that is can be edited */
05016                      (sens->flag & SENS_PIN && slogic->scaflag & BUTS_SENS_STATE) || /* states can hide some sensors, pinned sensors ignore the visible state */
05017                      (is_sensor_linked(block, sens))
05018                 ) {
05019                     /* should we draw the pin? - for now always draw when there is a state */
05020                     pin = (slogic->scaflag & BUTS_SENS_STATE && (sens->flag & SENS_SHOW || sens->flag & SENS_PIN)) ? 1:0 ;
05021                     
05022                     sens->flag |= SENS_VISIBLE;
05023                     uiDefIconButBitS(block, TOG, SENS_DEL, B_DEL_SENS, ICON_X,  xco, yco, 22, UI_UNIT_Y, &sens->flag, 0, 0, 0, 0, "Delete Sensor");
05024                     if (pin)
05025                         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");
05026                     
05027                     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");
05028 
05029                     ycoo= yco;
05030                     if(sens->flag & SENS_SHOW)
05031                     {
05032                         uiDefButS(block, MENU, B_CHANGE_SENS, sensor_pup(), (short)(xco+22), yco, 80, UI_UNIT_Y, &sens->type, 0, 0, 0, 0, "Sensor type");
05033                         but= uiDefBut(block, TEX, 1, "", (short)(xco+102), yco, (short)(width-(pin?146:124)), UI_UNIT_Y, sens->name, 0, MAX_NAME, 0, 0, "Sensor name");
05034                         uiButSetFunc(but, make_unique_prop_names_cb, sens->name, (void*) 0);
05035 
05036                         sens->otype= sens->type;
05037                         yco= draw_sensorbuttons(ob, sens, block, xco, yco, width);
05038                         if(yco-6 < ycoo) ycoo= (yco+ycoo-20)/2;
05039                     }
05040                     else {
05041                         set_col_sensor(sens->type, 1);
05042                         glRecti(xco+22, yco, xco+width-22,yco+19);
05043                         but= uiDefBut(block, LABEL, 0, sensor_name(sens->type), (short)(xco+22), yco, 80, UI_UNIT_Y, sens, 0, 0, 0, 0, "");
05044                         //uiButSetFunc(but, old_sca_move_sensor, sens, NULL);
05045                         but= uiDefBut(block, LABEL, 0, sens->name, (short)(xco+102), yco, (short)(width-(pin?146:124)), UI_UNIT_Y, sens, 0, MAX_NAME, 0, 0, "");
05046                         //uiButSetFunc(but, old_sca_move_sensor, sens, NULL);
05047 
05048                         uiBlockBeginAlign(block);
05049                         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");
05050                         uiButSetFunc(but, old_sca_move_sensor, sens, (void *)TRUE);
05051                         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");
05052                         uiButSetFunc(but, old_sca_move_sensor, sens, (void *)FALSE);
05053                         uiBlockEndAlign(block);
05054                     }
05055 
05056                     but= uiDefIconBut(block, LINK, 0, ICON_LINK,    (short)(xco+width), ycoo, UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, "");
05057                     uiSetButLink(but, NULL, (void ***)&(sens->links), &sens->totlinks, LINK_SENSOR, LINK_CONTROLLER);
05058 
05059                     yco-=20;
05060                 }
05061                 sens= sens->next;
05062             }
05063             yco-= 6;
05064         }
05065     }
05066     /* ******************************* */
05067     xco= 800; yco= 170; width= 300;
05068     uiDefBlockBut(block, actuator_menu, NULL, "Actuators", xco-10, yco+35, 90, UI_UNIT_Y, "");
05069 
05070     uiBlockBeginAlign(block);
05071     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");
05072     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");
05073     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");
05074     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");
05075     uiBlockEndAlign(block);
05076     for(a=0; a<count; a++) {
05077         ob= (Object *)idar[a];
05078 //      uiClearButLock();
05079 //      uiSetButLock(object_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
05080         if( (ob->scavisflag & OB_VIS_ACT) == 0) continue;
05081 
05082         /* presume it is only objects for now */
05083         uiBlockBeginAlign(block);
05084 //      if(ob->actuators.first) uiSetCurFont(block, UI_HELVB);
05085         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");
05086 //      if(ob->actuators.first) uiSetCurFont(block, UI_HELV);
05087         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");
05088         uiBlockEndAlign(block);
05089         yco-=20;
05090         
05091         if(ob->scaflag & OB_SHOWACT) {
05092             
05093             act= ob->actuators.first;
05094             while(act) {
05095                 if (!(slogic->scaflag & BUTS_ACT_STATE) ||
05096                     !(act->flag & ACT_LINKED) ||        /* always display actuators without links so that is can be edited */
05097                      (act->flag & ACT_VISIBLE) ||       /* this actuator has visible connection, display it */
05098                      (act->flag & ACT_PIN && slogic->scaflag & BUTS_ACT_STATE)) {
05099                     
05100                     pin = (slogic->scaflag & BUTS_ACT_STATE && (act->flag & SENS_SHOW || act->flag & SENS_PIN)) ? 1:0 ;
05101                     
05102                     act->flag |= ACT_VISIBLE;   /* mark the actuator as visible to help implementing the up/down action */
05103                     uiDefIconButBitS(block, TOG, ACT_DEL, B_DEL_ACT, ICON_X,    xco, yco, 22, UI_UNIT_Y, &act->flag, 0, 0, 0, 0, "Delete Actuator");
05104                     if (pin)
05105                         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");
05106                     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");
05107                     
05108                     if(act->flag & ACT_SHOW) {
05109                         act->otype= act->type;
05110                         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");
05111                         but= uiDefBut(block, TEX, 1, "", (short)(xco+112), yco, (short)(width-(pin?156:134)), UI_UNIT_Y, act->name, 0, MAX_NAME, 0, 0, "Actuator name");
05112                         uiButSetFunc(but, make_unique_prop_names_cb, act->name, (void*) 0);
05113 
05114                         ycoo= yco;
05115                         yco= draw_actuatorbuttons(bmain, ob, act, block, xco, yco, width);
05116                         if(yco-6 < ycoo) ycoo= (yco+ycoo-20)/2;
05117                     }
05118                     else {
05119                         set_col_actuator(act->type, 1);
05120                         glRecti((short)(xco+22), yco, (short)(xco+width-22),(short)(yco+19));
05121                         /* but= */ uiDefBut(block, LABEL, 0, actuator_name(act->type), (short)(xco+22), yco, 90, UI_UNIT_Y, act, 0, 0, 0, 0, "Actuator type");
05122                         // uiButSetFunc(but, old_sca_move_actuator, act, NULL);
05123                         /* 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");
05124                         // uiButSetFunc(but, old_sca_move_actuator, act, NULL);
05125 
05126                         uiBlockBeginAlign(block);
05127                         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");
05128                         uiButSetFunc(but, old_sca_move_actuator, act, (void *)TRUE);
05129                         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");
05130                         uiButSetFunc(but, old_sca_move_actuator, act, (void *)FALSE);
05131                         uiBlockEndAlign(block);
05132 
05133                         ycoo= yco;
05134                     }
05135 
05136                     uiDefIconBut(block, INLINK, 0, ICON_INLINK,(short)(xco-19), ycoo, UI_UNIT_X, UI_UNIT_Y, act, LINK_ACTUATOR, 0, 0, 0, "");
05137 
05138                     yco-=20;
05139                 }
05140                 act= act->next;
05141             }
05142             yco-= 6;
05143         }
05144     }
05145 
05146     uiComposeLinks(block);
05147     
05148     uiEndBlock(C, block);
05149     uiDrawBlock(C, block);
05150 
05151     if(idar) MEM_freeN(idar);
05152 }
05153 
05154 
05155 
05156 
05157 
05158