|  | @@ -857,6 +857,20 @@ void laset_InputMappingEntryKeyString(laInputMappingEntry* ime, char* key){
 | 
											
												
													
														|  |  void laset_InputMappingEntrySignalString(laInputMappingEntry* ime, char* sig){
 |  |  void laset_InputMappingEntrySignalString(laInputMappingEntry* ime, char* sig){
 | 
											
												
													
														|  |      strSafeSet(&ime->Signal,sig); laInputMappingUpdateSignal(ime); 
 |  |      strSafeSet(&ime->Signal,sig); laInputMappingUpdateSignal(ime); 
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  | 
 |  | +void laset_InputMappingEntryMove(laInputMappingEntry* ime, int move){
 | 
											
												
													
														|  | 
 |  | +    laInputMapping* im = ime->Parent;
 | 
											
												
													
														|  | 
 |  | +    if(move<0 && ime->Item.pPrev){ lstMoveUp(&im->Entries, ime); laNotifyUsers("la.input_mapping"); }
 | 
											
												
													
														|  | 
 |  | +    elif(move>0 && ime->Item.pNext){ lstMoveDown(&im->Entries, ime); laNotifyUsers("la.input_mapping"); }
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  | 
 |  | +void laset_InputMappingEntryOperatorString(laInputMappingEntry* ime, char* string){
 | 
											
												
													
														|  | 
 |  | +    strSafeSet(&ime->Operator,string);
 | 
											
												
													
														|  | 
 |  | +    laOperatorType* at=laGetOperatorType(string);
 | 
											
												
													
														|  | 
 |  | +    if(at){
 | 
											
												
													
														|  | 
 |  | +        strSafeSet(&ime->OperatorName, at->Name);
 | 
											
												
													
														|  | 
 |  | +    }else{
 | 
											
												
													
														|  | 
 |  | +        strSafeDestroy(&ime->OperatorName);
 | 
											
												
													
														|  | 
 |  | +    }
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  |  void laset_SignalFilter(void* unused, char* sig){
 |  |  void laset_SignalFilter(void* unused, char* sig){
 | 
											
												
													
														|  |      strSafeSet(&MAIN.SignalFilter,sig);
 |  |      strSafeSet(&MAIN.SignalFilter,sig);
 | 
											
												
													
														|  |      laNotifyUsers("la.filtered_signals");
 |  |      laNotifyUsers("la.filtered_signals");
 | 
											
										
											
												
													
														|  | @@ -871,6 +885,30 @@ void* lagetnext_FilteredSignal(laCustomSignal* p, laPropIterator* pi){
 | 
											
												
													
														|  |      while(!strstr(SSTR(p->Name),SSTR(MAIN.SignalFilter))){ p=p->Item.pNext; if(!p){ return 0; } }
 |  |      while(!strstr(SSTR(p->Name),SSTR(MAIN.SignalFilter))){ p=p->Item.pNext; if(!p){ return 0; } }
 | 
											
												
													
														|  |      return p;
 |  |      return p;
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  | 
 |  | +void laset_OperatorFilter(void* unused, char* sig){
 | 
											
												
													
														|  | 
 |  | +    strSafeSet(&MAIN.OperatorFilter,sig);
 | 
											
												
													
														|  | 
 |  | +    laNotifyUsers("la.filtered_operators");
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  | 
 |  | +void* laget_FirstFilteredOperator(void* unused1,laPropIterator* pi){
 | 
											
												
													
														|  | 
 |  | +    laOperatorType* at = MAIN.OperatorList.pFirst;
 | 
											
												
													
														|  | 
 |  | +    while(at->ExtraMark & (LA_ACTUATOR_HIDDEN|LA_ACTUATOR_SYSTEM)){
 | 
											
												
													
														|  | 
 |  | +        at=at->ListItem.pNext; if(!at){ return 0; }
 | 
											
												
													
														|  | 
 |  | +    }
 | 
											
												
													
														|  | 
 |  | +    while((!strstr(at->Name,SSTR(MAIN.OperatorFilter))) && (!strstr(at->Identifier,SSTR(MAIN.OperatorFilter)))){
 | 
											
												
													
														|  | 
 |  | +        at=at->ListItem.pNext; if(!at){ return 0; }
 | 
											
												
													
														|  | 
 |  | +    }
 | 
											
												
													
														|  | 
 |  | +    return at;
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  | 
 |  | +void* lagetnext_FilteredOperator(laOperatorType* at, laPropIterator* pi){
 | 
											
												
													
														|  | 
 |  | +    at=at->ListItem.pNext; if(!at){ return 0; }
 | 
											
												
													
														|  | 
 |  | +    while(at->ExtraMark & (LA_ACTUATOR_HIDDEN|LA_ACTUATOR_SYSTEM)){
 | 
											
												
													
														|  | 
 |  | +        at=at->ListItem.pNext; if(!at){ return 0; }
 | 
											
												
													
														|  | 
 |  | +    }
 | 
											
												
													
														|  | 
 |  | +    while((!strstr(at->Name,SSTR(MAIN.OperatorFilter))) && (!strstr(at->Identifier,SSTR(MAIN.OperatorFilter)))){
 | 
											
												
													
														|  | 
 |  | +        at=at->ListItem.pNext; if(!at){ return 0; }
 | 
											
												
													
														|  | 
 |  | +    }
 | 
											
												
													
														|  | 
 |  | +    return at;
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  void tnspost_World(tnsWorld *w){
 |  |  void tnspost_World(tnsWorld *w){
 | 
											
												
													
														|  |      tnsRefreshMaterialLibraries();
 |  |      tnsRefreshMaterialLibraries();
 | 
											
										
											
												
													
														|  | @@ -1581,8 +1619,10 @@ void la_RegisterInternalProps(){
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |              laAddSubGroup(p,"input_mapping","Input Mapping","Input mapping bundle","la_input_mapping_bundle",0,0,0,offsetof(LA,InputMapping),0,0,0,0,0,0,0,LA_UDF_SINGLE);
 |  |              laAddSubGroup(p,"input_mapping","Input Mapping","Input mapping bundle","la_input_mapping_bundle",0,0,0,offsetof(LA,InputMapping),0,0,0,0,0,0,0,LA_UDF_SINGLE);
 | 
											
												
													
														|  |              laAddStringProperty(p,"signal_filter","Signal Filter","Filter displayed signals",0,0,0,0,1,offsetof(LA,SignalFilter),0,0,laset_SignalFilter,0,0);
 |  |              laAddStringProperty(p,"signal_filter","Signal Filter","Filter displayed signals",0,0,0,0,1,offsetof(LA,SignalFilter),0,0,laset_SignalFilter,0,0);
 | 
											
												
													
														|  | 
 |  | +            laAddStringProperty(p,"operator_filter","Operator Filter","Filter displayed operators",0,0,0,0,1,offsetof(LA,OperatorFilter),0,0,laset_OperatorFilter,0,0);
 | 
											
												
													
														|  |              laAddSubGroup(p,"custom_signals","Signals","Registered custom signals","la_custom_signal",0,0,laui_IdentifierOnly,-1,laget_FirstCustomSignal,0,laget_ListNext,0,0,0,0,LA_UDF_IGNORE);
 |  |              laAddSubGroup(p,"custom_signals","Signals","Registered custom signals","la_custom_signal",0,0,laui_IdentifierOnly,-1,laget_FirstCustomSignal,0,laget_ListNext,0,0,0,0,LA_UDF_IGNORE);
 | 
											
												
													
														|  |              laAddSubGroup(p,"filtered_signals","Filtered Signals","Filtered custom signals","la_custom_signal",0,0,laui_IdentifierOnly,-1,laget_FirstFilteredCustomSignal,0,lagetnext_FilteredSignal,0,0,0,0,LA_UDF_IGNORE);
 |  |              laAddSubGroup(p,"filtered_signals","Filtered Signals","Filtered custom signals","la_custom_signal",0,0,laui_IdentifierOnly,-1,laget_FirstFilteredCustomSignal,0,lagetnext_FilteredSignal,0,0,0,0,LA_UDF_IGNORE);
 | 
											
												
													
														|  | 
 |  | +            laAddSubGroup(p,"filtered_operators","Filtered Operators","Filtered operators","la_operator_type",0,0,laui_IdentifierOnly,-1,laget_FirstFilteredOperator,0,lagetnext_FilteredOperator,0,0,0,0,LA_UDF_IGNORE);
 | 
											
												
													
														|  |              
 |  |              
 | 
											
												
													
														|  |              laAddStringProperty(p, "identifier", "Identifier", "Identifier", 0,0,0,0,0,0,0,laget_MainIdentifier, 0,0,LA_AS_IDENTIFIER|LA_READ_ONLY);
 |  |              laAddStringProperty(p, "identifier", "Identifier", "Identifier", 0,0,0,0,0,0,0,laget_MainIdentifier, 0,0,LA_AS_IDENTIFIER|LA_READ_ONLY);
 | 
											
												
													
														|  |    
 |  |    
 | 
											
										
											
												
													
														|  | @@ -1814,21 +1854,41 @@ void la_RegisterInternalProps(){
 | 
											
												
													
														|  |              laAddOperatorProperty(p,"new_entry","New Entry","New mapping entry","LA_new_input_mapping_entry",'+',0);
 |  |              laAddOperatorProperty(p,"new_entry","New Entry","New mapping entry","LA_new_input_mapping_entry",'+',0);
 | 
											
												
													
														|  |          }
 |  |          }
 | 
											
												
													
														|  |          p = laAddPropertyContainer("la_input_mapping_entry", "Input Mapping Entry", "Input mapping entry", 0,0,sizeof(laInputMappingEntry), 0,0,1);{
 |  |          p = laAddPropertyContainer("la_input_mapping_entry", "Input Mapping Entry", "Input mapping entry", 0,0,sizeof(laInputMappingEntry), 0,0,1);{
 | 
											
												
													
														|  | 
 |  | +            laAddIntProperty(p,"__move","Move Slider","Move Slider",LA_WIDGET_HEIGHT_ADJUSTER,0,0,0,0,0,0,0,0,0,laset_InputMappingEntryMove,0,0,0,0,0,0,0,0,LA_UDF_IGNORE);
 | 
											
												
													
														|  | 
 |  | +            ep=laAddEnumProperty(p,"disabled","Enabled","Enable or disable this input mapping entry",0,0,0,0,0,offsetof(laInputMappingEntry,Disabled),0,0,0,0,0,0,0,0,0,0);
 | 
											
												
													
														|  | 
 |  | +            laAddEnumItemAs(ep, "ENABLED", "Enabled", "Entry enabled", 0, U'✓');
 | 
											
												
													
														|  | 
 |  | +            laAddEnumItemAs(ep, "DISABLED", "Disabled", "Entry disabled", 1, U'✗');
 | 
											
												
													
														|  |              ep=laAddEnumProperty(p,"device_type","Device Type","Device type of the input event",0,0,0,0,0,offsetof(laInputMappingEntry,DeviceType),0,0,0,0,0,0,0,0,0,0);
 |  |              ep=laAddEnumProperty(p,"device_type","Device Type","Device type of the input event",0,0,0,0,0,offsetof(laInputMappingEntry,DeviceType),0,0,0,0,0,0,0,0,0,0);
 | 
											
												
													
														|  | -            laAddEnumItemAs(ep, "KEYBOARD", "Keyboard", "Keyboard input", LA_INPUT_DEVICE_KEYBOARD, 0);
 |  | 
 | 
											
												
													
														|  | -            laAddEnumItemAs(ep, "JOYSTICK", "Joystick", "Joystick input", LA_INPUT_DEVICE_JOYSTICK, 0);
 |  | 
 | 
											
												
													
														|  | 
 |  | +            laAddEnumItemAs(ep, "KEYBOARD", "Keyboard", "Keyboard input", LA_INPUT_DEVICE_KEYBOARD, U'🖮');
 | 
											
												
													
														|  | 
 |  | +            laAddEnumItemAs(ep, "JOYSTICK", "Joystick", "Joystick input", LA_INPUT_DEVICE_JOYSTICK, U'🕹');
 | 
											
												
													
														|  |              laAddIntProperty(p,"joystick_device","Joystick Device","Joystick device number",0,0,0,0,0,0,0,0,offsetof(laInputMappingEntry,JoystickDevice),0,0,0,0,0,0,0,0,0,0,0);
 |  |              laAddIntProperty(p,"joystick_device","Joystick Device","Joystick device number",0,0,0,0,0,0,0,0,offsetof(laInputMappingEntry,JoystickDevice),0,0,0,0,0,0,0,0,0,0,0);
 | 
											
												
													
														|  |              laAddStringProperty(p,"key","Key","Event key",0,0,0,0,1,offsetof(laInputMappingEntry,Key),0,0,laset_InputMappingEntryKeyString,0,0);
 |  |              laAddStringProperty(p,"key","Key","Event key",0,0,0,0,1,offsetof(laInputMappingEntry,Key),0,0,laset_InputMappingEntryKeyString,0,0);
 | 
											
												
													
														|  |              laAddStringProperty(p,"signal","Signal","Target signal",0,0,0,0,1,offsetof(laInputMappingEntry,Signal),0,0,laset_InputMappingEntrySignalString,0,0);
 |  |              laAddStringProperty(p,"signal","Signal","Target signal",0,0,0,0,1,offsetof(laInputMappingEntry,Signal),0,0,laset_InputMappingEntrySignalString,0,0);
 | 
											
												
													
														|  |              laAddSubGroup(p,"signal_selection","Signal","Signal selection","la_custom_signal",0,0,laui_IdentifierOnly,-1,laget_FirstCustomSignal,0,laget_ListNext,laset_InputMappingEntrySignal,0,0,0,LA_UDF_IGNORE);
 |  |              laAddSubGroup(p,"signal_selection","Signal","Signal selection","la_custom_signal",0,0,laui_IdentifierOnly,-1,laget_FirstCustomSignal,0,laget_ListNext,laset_InputMappingEntrySignal,0,0,0,LA_UDF_IGNORE);
 | 
											
												
													
														|  |              laAddOperatorProperty(p,"remove","Remove","Remove this entry","LA_remove_input_mapping_entry",U'🞫',0);
 |  |              laAddOperatorProperty(p,"remove","Remove","Remove this entry","LA_remove_input_mapping_entry",U'🞫',0);
 | 
											
												
													
														|  |              laAddOperatorProperty(p,"select_signal","Select","Select signal","LA_input_mapping_entry_select_signal",0,0);
 |  |              laAddOperatorProperty(p,"select_signal","Select","Select signal","LA_input_mapping_entry_select_signal",0,0);
 | 
											
												
													
														|  | 
 |  | +            laAddOperatorProperty(p,"select_operator","Select","Select operator","LA_input_mapping_entry_select_operator",0,0);
 | 
											
												
													
														|  |              laAddOperatorProperty(p,"select_key","Select Key","Select key","LA_input_mapping_entry_select_key",0,0);
 |  |              laAddOperatorProperty(p,"select_key","Select Key","Select key","LA_input_mapping_entry_select_key",0,0);
 | 
											
												
													
														|  |              laAddSubGroup(p,"parent","Parent","Parent group","la_input_mapping",0,0,0,offsetof(laInputMappingEntry,Parent),0,0,0,0,0,0,0,LA_UDF_REFER);
 |  |              laAddSubGroup(p,"parent","Parent","Parent group","la_input_mapping",0,0,0,offsetof(laInputMappingEntry,Parent),0,0,0,0,0,0,0,LA_UDF_REFER);
 | 
											
												
													
														|  | 
 |  | +            ep=laAddEnumProperty(p,"use_operator","Device Type","Device type of the input event",0,0,0,0,0,offsetof(laInputMappingEntry,UseOperator),0,0,0,0,0,0,0,0,0,0);
 | 
											
												
													
														|  | 
 |  | +            laAddEnumItemAs(ep, "SIGNAL", "Signal", "Send signal upon input", 0, U'⚟');
 | 
											
												
													
														|  | 
 |  | +            laAddEnumItemAs(ep, "OPERATOR", "Operator", "Run operator upon input", 1, U'🏃');
 | 
											
												
													
														|  | 
 |  | +            laAddStringProperty(p,"operator","Operator","Operator to call",0,0,0,0,1,offsetof(laInputMappingEntry,Operator),0,0,laset_InputMappingEntryOperatorString,0,0);
 | 
											
												
													
														|  | 
 |  | +            laAddStringProperty(p,"operator_name","Operator Name","Target operator name",0,0,0,0,1,offsetof(laInputMappingEntry,OperatorName),0,0,0,0,LA_READ_ONLY);
 | 
											
												
													
														|  | 
 |  | +            laAddStringProperty(p,"operator_arguments","Arguments","Extra arguments for the operator",0,0,0,0,1,offsetof(laInputMappingEntry,OperatorArguments),0,0,0,0,0);
 | 
											
												
													
														|  | 
 |  | +            ep=laAddEnumProperty(p,"operator_base","Operator Base","Operator parent context base",0,0,0,0,0,offsetof(laInputMappingEntry,OperatorBase),0,0,0,0,0,0,0,0,0,0);
 | 
											
												
													
														|  | 
 |  | +            laAddEnumItemAs(ep, "NONE", "None", "Run operator directly", 0, 0);
 | 
											
												
													
														|  | 
 |  | +            laAddEnumItemAs(ep, "WIDGET", "Widget", "Run operator with extra reference of current UI", LA_KM_SEL_UI_EXTRA, 0);
 | 
											
												
													
														|  | 
 |  | +            laAddEnumItemAs(ep, "PANEL", "Panel", "Run operator with extra reference of current panel", LA_KM_SEL_PANEL, 0);
 | 
											
												
													
														|  |          }
 |  |          }
 | 
											
												
													
														|  |          p = laAddPropertyContainer("la_custom_signal", "Custom Signal", "Custom signal", 0,0,sizeof(laCustomSignal), 0,0,1);{
 |  |          p = laAddPropertyContainer("la_custom_signal", "Custom Signal", "Custom signal", 0,0,sizeof(laCustomSignal), 0,0,1);{
 | 
											
												
													
														|  |              laAddStringProperty(p, "name", "Name", "The name of this mapping", 0,0,0,"Mapping", 1, offsetof(laCustomSignal, Name), 0,0,0,0,LA_AS_IDENTIFIER);
 |  |              laAddStringProperty(p, "name", "Name", "The name of this mapping", 0,0,0,"Mapping", 1, offsetof(laCustomSignal, Name), 0,0,0,0,LA_AS_IDENTIFIER);
 | 
											
												
													
														|  |          }
 |  |          }
 | 
											
												
													
														|  | 
 |  | +        p = laAddPropertyContainer("la_operator_type", "Operator Type", "Operator type", 0,laui_OperatorTypeEntry,sizeof(laOperatorType), 0,0,1);{
 | 
											
												
													
														|  | 
 |  | +            laAddStringProperty(p, "identifier", "Identifier", "The identifier of the operator", 0,0,0, "none", 0, offsetof(laOperatorType, Identifier), 0,0,0,0,LA_AS_IDENTIFIER|LA_READ_ONLY);
 | 
											
												
													
														|  | 
 |  | +            laAddStringProperty(p, "name", "Name", "The name of operator", 0,0,0, "none", 0, offsetof(laOperatorType, Name), 0,0,0,0,LA_READ_ONLY);
 | 
											
												
													
														|  | 
 |  | +            laAddStringProperty(p, "description", "Description", "Description of the operator", 0,0,0, "none", 0, offsetof(laOperatorType, Description), 0,0,0,0,LA_READ_ONLY);
 | 
											
												
													
														|  | 
 |  | +        }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |          p = laAddPropertyContainer("la_translation_language", "Language", "Translation language pack", 0,0,sizeof(laTranslationNode), 0,0,1);{
 |  |          p = laAddPropertyContainer("la_translation_language", "Language", "Translation language pack", 0,0,sizeof(laTranslationNode), 0,0,1);{
 | 
											
												
													
														|  |              laAddStringProperty(p, "name", "Name", "The name of this language", 0,0,0,"Unknown", 1, offsetof(laTranslationNode, LanguageName), 0,0,0,0,LA_AS_IDENTIFIER);
 |  |              laAddStringProperty(p, "name", "Name", "The name of this language", 0,0,0,"Unknown", 1, offsetof(laTranslationNode, LanguageName), 0,0,0,0,LA_AS_IDENTIFIER);
 |