*/}}
Browse Source

Key selector

YimingWu 3 tháng trước cách đây
mục cha
commit
2e20b91e2f
6 tập tin đã thay đổi với 236 bổ sung40 xóa
  1. 30 2
      la_interface.h
  2. 50 25
      la_kernel.c
  3. 90 3
      resources/la_operators.c
  4. 47 5
      resources/la_properties.c
  5. 11 3
      resources/la_templates.c
  6. 8 2
      resources/la_widgets.c

+ 30 - 2
la_interface.h

@@ -414,6 +414,10 @@ STRUCTURE(LA){
 
     laHash256 OperatorTypeHash;
 
+    //laHash256 CustomCommandHash;
+    laSafeString* SignalFilter;
+    laListHandle CustomSignals;
+
     laListHandle ExtraExtensions;
     laListHandle ExtraPreferencePaths;
     laListHandle ExtraPreferencePages;
@@ -1126,6 +1130,7 @@ STRUCTURE(laWidget){
 #define LA_UI_FLAGS_COLORFUL LA_UI_FLAGS_ICON
 
 #define LA_UI_FLAGS_TERMINAL_INPUT LA_UI_FLAGS_COLOR_SPACE_CLAY
+#define LA_UI_FLAGS_IMMEDIATE_INPUT LA_UI_FLAGS_CYCLE
 
 #define LA_UI_FLAGS_MOMENTARY (LA_UI_FLAGS_CYCLE|LA_UI_FLAGS_NODE_CONTAINER)
 #define LA_UI_FLAGS_KNOB LA_UI_FLAGS_NODE_CONTAINER
@@ -1380,6 +1385,8 @@ STRUCTURE(laConfirmData){
     real FData;
     void *CustomData;
     char *StrData;
+    void* PointerData;
+    laPropContainer* PointerType;
     laConfirmDataDestroyFunc Destroy;
 };
 
@@ -1408,6 +1415,7 @@ STRUCTURE(laOperator){
 
     int Using;
     int StopNow;
+    int ModalOver;
 
     laPanel *ToPanel;
     laPanel *OperatorPanel;
@@ -1431,7 +1439,7 @@ STRUCTURE(laInputMappingEntry){
     int JoystickDevice;
     laSafeString* Key; int KeyValue;
     int SpecialKeyBits;
-    laSafeString* TargetMessage; int MessageValue;
+    laSafeString* Signal; int SignalValue;
 };
 STRUCTURE(laInputMappingBundle){
     void* _pad;
@@ -1439,6 +1447,17 @@ STRUCTURE(laInputMappingBundle){
     laInputMapping* CurrentInputMapping;
 };
 
+#define LA_SIGNAL_NEW 1
+#define LA_SIGNAL_DELETE 2
+#define LA_SIGNAL_CONFIRM 3
+
+STRUCTURE(laCustomSignal){
+    laListItem Item;
+    //laListItem Item2;
+    laSafeString* Name;
+    int Signal;
+};
+
 #define LA_JS_MAX_AXES 32
 #define LA_JS_MAX_BUTTONS 128
 STRUCTURE(laController){
@@ -1904,6 +1923,7 @@ void la_RegisterBuiltinTemplates();
 void la_RegisterWindowKeys();
 void la_RegisterGeneralProps();
 void la_RegisterInternalProps();
+void la_RegisterDefaultSignals();
 
 void la_RegisterAnimationResources();
 
@@ -2106,11 +2126,16 @@ void laSetMenuBarTemplates(laUiDefineFunc MenuButtons, laUiDefineFunc MenuExtras
 void laSetAboutTemplates(laUiDefineFunc AboutContent, laUiDefineFunc AboutVersion, laUiDefineFunc AboutAuthor);
 void laSetPreferenceTemplates(laUiDefineFunc PreferencePageDisplay, laUiDefineFunc PreferencePageInput, laUiDefineFunc PreferencePageResource, laUiDefineFunc PreferencePageTheme);
 
+laCustomSignal* laFindSignal(char* Name);
+void laInputMappingUpdateSignal(laInputMappingEntry* ime);
 laInputMapping* laNewInputMapping(char* Name);
-laInputMappingEntry* laNewInputMappingEntry(laInputMapping* im, int DeviceType, int JoystickDevice, char* Key, int SpecialKeyBit, char* TargetMessage);
+laInputMappingEntry* laNewInputMappingEntry(laInputMapping* im, int DeviceType, int JoystickDevice, char* Key, int SpecialKeyBit, char* Signal);
 void laRemoveInputMappingEntry(laInputMapping* im, laInputMappingEntry* e);
 void laRemoveInputMapping(laInputMapping* im);
 
+laCustomSignal* laNewCustomSignal(char* Name, int Signal);
+void laRemoveCustomSignal(laCustomSignal* cs);
+
 laWindow *laDesignWindow(int X, int Y, int W, int H);
 laLayout *laDesignLayout(laWindow *w, char *Title);
 void laDestroyLayout(laWindow *w, laLayout* l);
@@ -2166,6 +2191,8 @@ laPanel *laEnableOperatorPanel(laOperator *For, laPropPack *This, int X, int Y,
 laPanel *laEnableYesNoPanel(laOperator *a, laPanel *Attachment, char *Title, char *Message, int X, int Y, int W, laEvent *e);
 laPanel *laEnableMessagePanel(laOperator *a, laPanel *Attachment, char *Title, char *Message, int X, int Y, int W, laEvent *e);
 
+void laOperatorModalOver(laOperator* For);
+
 void la_PropPanelUserRemover(void* This, laItemUserLinker* iul);
 
 void la_EnsurePanelExtras(laPanel *p);
@@ -2380,6 +2407,7 @@ void la_StopAllOperators();
 
 int la_ProcessTextEdit(laEvent *e, laStringEdit *se, laUiItem* ui);
 
+void laConfirmPointer(laOperator *a, void* Data,laPropContainer* PointerType, int mode);
 void laConfirmInt(laOperator *a, int Data, int mode);
 void laConfirmFloat(laOperator *a, real Data, int mode);
 void laConfirmString(laOperator *a, char *Str, int mode);

+ 50 - 25
la_kernel.c

@@ -1211,6 +1211,7 @@ int laGetReadyWith(laInitArguments* ia){
     la_MakeTranslations();
 
     //tns_RegisterResourcesForSoftwareRender();
+    la_RegisterDefaultSignals();
     la_RegisterGeneralProps();
     la_RegisterBuiltinTemplates();
     la_RegisterMainThemes();
@@ -1384,19 +1385,30 @@ void laSetPreferenceTemplates(laUiDefineFunc PreferencePageDisplay, laUiDefineFu
     MAIN.PreferencePageResource=PreferencePageResource; MAIN.PreferencePageTheme=PreferencePageTheme;
 }
 
+laCustomSignal* laFindSignal(char* Name){
+    for(laCustomSignal* cs=MAIN.CustomSignals.pFirst;cs;cs=cs->Item.pNext){ if(strSame(SSTR(cs->Name),Name)) return cs; }
+    return 0;
+}
+void laInputMappingUpdateSignal(laInputMappingEntry* ime){
+    if(ime->DeviceType == LA_INPUT_DEVICE_KEYBOARD){ char* str=SSTR(ime->Key); if(str&&str[0]){ int adv; ime->KeyValue=laToUnicode(str,&adv); }else{ ime->KeyValue=0; } }
+    if(ime->DeviceType == LA_INPUT_DEVICE_JOYSTICK){ int key=0; sscanf(SSTR(ime->Key),"%d",&key); ime->KeyValue=key; }
+    char* signal = SSTR(ime->Signal);
+    laCustomSignal *cs=laFindSignal(signal); if(cs){ ime->SignalValue=cs->Signal; }else{ ime->SignalValue=0;}
+}
 laInputMapping* laNewInputMapping(char* Name){
     laInputMapping* im=memAcquireHyper(sizeof(laInputMapping)); lstAppendItem(&MAIN.InputMapping->InputMappings,im);
     memAssignRef(MAIN.InputMapping,&MAIN.InputMapping->CurrentInputMapping,im);
     strSafeSet(&im->Name,Name);
 }
-laInputMappingEntry* laNewInputMappingEntry(laInputMapping* im, int DeviceType, int JoystickDevice, char* Key, int SpecialKeyBit, char* TargetMessage){
+laInputMappingEntry* laNewInputMappingEntry(laInputMapping* im, int DeviceType, int JoystickDevice, char* Key, int SpecialKeyBit, char* Signal){
     laInputMappingEntry* e=memAcquire(sizeof(laInputMappingEntry)); lstAppendItem(&im->Entries,e);
     e->DeviceType = DeviceType; e->JoystickDevice=JoystickDevice; e->SpecialKeyBits=SpecialKeyBit;
     memAssignRef(e,&e->Parent,im);
-    if(TargetMessage){ strSafeSet(&e->TargetMessage,TargetMessage); } if(Key){ strSafeSet(&e->Key,Key); }
+    if(Signal){ strSafeSet(&e->Signal,Signal); } if(Key){ strSafeSet(&e->Key,Key); }
+    laInputMappingUpdateSignal(e);
 }
 void laRemoveInputMappingEntry(laInputMapping* im, laInputMappingEntry* e){
-    memAssignRef(e,&e->Parent,0); lstRemoveItem(&im->Entries,e); strSafeDestroy(&e->TargetMessage); strSafeDestroy(&e->Key); memFree(e);
+    memAssignRef(e,&e->Parent,0); lstRemoveItem(&im->Entries,e); strSafeDestroy(&e->Signal); strSafeDestroy(&e->Key); memFree(e);
 }
 void laRemoveInputMapping(laInputMapping* im){
     laInputMappingEntry* e; while(e=im->Entries.pFirst){ laRemoveInputMappingEntry(im,e); }
@@ -1405,6 +1417,15 @@ void laRemoveInputMapping(laInputMapping* im){
     lstRemoveItem(&MAIN.InputMapping->InputMappings,im); strSafeDestroy(&im->Name); memFree(im);
 }
 
+laCustomSignal* laNewCustomSignal(char* Name, int Signal){
+    laCustomSignal* cs=memAcquire(sizeof(laCustomSignal)); lstAppendItem(&MAIN.CustomSignals,cs);
+    strSafeSet(&cs->Name,Name); cs->Signal = Signal;
+    return cs;
+}
+void laRemoveCustomSignal(laCustomSignal* cs){
+    strSafeDestroy(&cs->Name); lstRemoveItem(&MAIN.CustomSignals,cs); memFree(cs);
+}
+
 //MSG====================================================
 
 int la_IsThisSysWindow(laWindow *wnd, SYSWINDOW hwnd){
@@ -3569,6 +3590,10 @@ laPanel *laEnableMessagePanel(laOperator *a, laPanel *Attachment, char *Title, c
     return p;
 }
 
+void laOperatorModalOver(laOperator* For){
+    For->ModalOver = 1;
+}
+
 void laDeferredRedraw(laPanel* p){
     for(laListItemPointer* lip=MAIN.DeferredRedrawList.pFirst;lip;lip=lip->pNext){
         if(lip->p==p) return;
@@ -6675,7 +6700,7 @@ void *la_DestroyOperator(laOperator **a, laListHandle *Operators, int OnlyThisOn
     laOperator *ac = ((*a)->Child);
     void *Ret = 0;
 
-    if (!OnlyThisOne && ac && la_OperatorExists(ac) && !ac->Using){
+    if (!OnlyThisOne && ac && la_OperatorExists(ac) && !ac->Using && !ac->ModalOver){
         la_DestroyOperator(&ac, Operators, OnlyThisOne);
     }
 
@@ -6801,7 +6826,8 @@ int laInvokeP(laOperator *From, laOperatorType *at, laEvent *e, laPropPack *This
     }
 
     if (!a->StopNow && (rev&LA_BLOCK || rev&LA_PASS_ON)){
-        lstAppendItem(&MAIN.CurrentWindow->PendingOperators, a);
+        if(a->ModalOver){ lstPushItem(&MAIN.CurrentWindow->PendingOperators, a); }
+        else{ lstAppendItem(&MAIN.CurrentWindow->PendingOperators, a); }
         a->State = rev;
         a->PP.EndInstance = a->CustomData;
         if (a->PP.LastPs) a->PP.LastPs->Type = U'.';
@@ -6866,7 +6892,8 @@ int laInvokePCreateThis(laOperator *From, laOperatorType *at, laEvent *e, laProp
     }
 
     if (!a->StopNow && (rev&LA_BLOCK || rev&LA_PASS_ON)){
-        lstAppendItem(&MAIN.CurrentWindow->PendingOperators, a);
+        if(a->ModalOver){ lstPushItem(&MAIN.CurrentWindow->PendingOperators, a); }
+        else{ lstAppendItem(&MAIN.CurrentWindow->PendingOperators, a); }
         a->State = rev;
         a->PP.EndInstance = a->CustomData;
     }else
@@ -6982,30 +7009,25 @@ void la_StopAllOperators(){
 
 void la_DestroyConfirmData(laConfirmData **cd){
     if((!cd)||!(*cd)) return;
-    if ((*cd)->CustomData) (*cd)->Destroy((*cd)->CustomData);
+    if ((*cd)->CustomData && (*cd)->Destroy) (*cd)->Destroy((*cd)->CustomData);
     if ((*cd)->StrData) free((*cd)->StrData);
     FreeMem((*cd));
     (*cd) = 0;
 }
+void laConfirmPointer(laOperator *a, void* Data,laPropContainer* PointerType, int mode){
+    laOperator *ai = a; laConfirmData *cd = CreateNew(laConfirmData);
+    cd->PointerData = Data; cd->Mode = mode; cd->PointerType=PointerType;
+    ai->NextConfirmData = cd; laRetriggerOperators();
+}
 void laConfirmInt(laOperator *a, int Data, int mode){
-    laOperator *ai = a;
-    laConfirmData *cd = CreateNew(laConfirmData);
-
-    cd->IData = Data;
-    cd->Mode = mode;
-
-    ai->NextConfirmData = cd;
-    laRetriggerOperators();
+    laOperator *ai = a;laConfirmData *cd = CreateNew(laConfirmData);
+    cd->IData = Data; cd->Mode = mode;
+    ai->NextConfirmData = cd; laRetriggerOperators();
 }
 void laConfirmFloat(laOperator *a, real Data, int mode){
-    laOperator *ai = a;
-    laConfirmData *cd = CreateNew(laConfirmData);
-
-    cd->FData = Data;
-    cd->Mode = mode;
-
-    ai->NextConfirmData = cd;
-    laRetriggerOperators();
+    laOperator *ai = a;laConfirmData *cd = CreateNew(laConfirmData);
+    cd->FData = Data; cd->Mode = mode;
+    ai->NextConfirmData = cd; laRetriggerOperators();
 }
 void laConfirmString(laOperator *a, char *Str, int mode){
     laOperator *ai = a;
@@ -7038,6 +7060,8 @@ int laConfirmSameDataIfAny(laOperator *a){
     //cd->CustomData = cd->CustomData;
     cd->IData = ai->ConfirmData->IData;
     cd->FData = ai->ConfirmData->FData;
+    cd->PointerData = ai->ConfirmData->PointerData;
+    cd->PointerType = a->ConfirmData->PointerType;
     cd->StrData = buf;
     cd->Mode = ai->ConfirmData->Mode;
     cd->Destroy = ai->ConfirmData->Destroy;
@@ -7348,8 +7372,6 @@ int la_HandleSingleEvent(laEvent *e, laListHandle *Operators){
         }
 
         if (a->State & LA_BLOCK){ Result = a->Type->Modal(a, e); }
-
-        //la_PrintOperatorStack();
         
         if (a->Type->ExtraMark & LA_EXTRA_TO_PANEL){
             laLocalToWindow(a, a->ToPanel, &e->x, &e->y);
@@ -7382,6 +7404,9 @@ int la_HandleSingleEvent(laEvent *e, laListHandle *Operators){
         if (Result & LA_FINISH || Result == LA_CANCEL || (a->StopNow && a->Using == 0)){
             if (a->Type->Exit) a->Type->Exit(a, Result);
             la_DestroyOperator(&a, Operators, 0);
+            int found=0;
+            for(laOperator*iop=Operators->pFirst;iop;iop=iop->Item.pNext){ if(iop==NextA){found=1;} }
+            if(!found){ NextA=0; }
             if(Result == LA_OPERATOR_CALLS_SHUTOFF){ return 0; }
         }
 

+ 90 - 3
resources/la_operators.c

@@ -764,6 +764,87 @@ int OPMOD_RemoveInputMappingEntry(laOperator *a, laEvent *e){
     return LA_RUNNING;
 }
 
+int OPINV_InputMappingEntrySelectSignal(laOperator *a, laEvent *e){
+    if(!a->This || !a->This->EndInstance) return LA_CANCELED; laInputMappingEntry* ime=a->This->EndInstance;
+    laEnableOperatorPanel(a,a->This,e->x-LA_RH*5,e->y-LA_RH,LA_RH*10,LA_RH*10,LA_RH*30,LA_RH*30,0,0,0,0,0,0,e);
+    return LA_RUNNING;
+}
+int OPMOD_InputMappingEntrySelectSignal(laOperator *a, laEvent *e){
+    if(!a->This || !a->This->EndInstance) return LA_CANCELED; laInputMappingEntry* ime=a->This->EndInstance;
+    if(a->ConfirmData){
+        if(a->ConfirmData->Mode == LA_CONFIRM_DATA && a->ConfirmData->PointerData && strSame(a->ConfirmData->PointerType->Identifier,"la_custom_signal")){
+            laCustomSignal* cs=a->ConfirmData->PointerData;
+            ime->SignalValue = cs->Signal; strSafeSet(&ime->Signal,SSTR(cs->Name));
+            laNotifyUsers("la.input_mapping");
+        }
+        return LA_FINISHED;
+    }
+    return LA_RUNNING;
+}
+void laui_InputMappingEntrySignalSelector(laUiList *uil, laPropPack *Base, laPropPack *OperatorInst, laColumn *ExtraColumns, int context){
+    laColumn* c=laFirstColumn(uil);
+
+    laUiItem* b=laBeginRow(uil,c,0,0);
+    laShowLabel(uil,c,"🔍",0,0);
+    laUiItem* ui=laShowItem(uil,c,0,"la.signal_filter");ui->Expand=1;ui->Flags|=LA_UI_FLAGS_IMMEDIATE_INPUT;
+    laEndRow(uil,b);
+    laUiItem* g=laMakeEmptyGroup(uil,c,0,0); laUiList* guil=g->Page; laColumn* gc=laFirstColumn(guil); guil->HeightCoeff=10;
+    laShowItemFull(guil,gc,0,"la.filtered_signals",LA_WIDGET_COLLECTION,0,0,0)->Flags|=LA_UI_FLAGS_NO_DECAL;
+}
+
+STRUCTURE(laKeyDetectorData){
+    int pad;
+    int Key;
+    laSafeString* Str;
+};
+int OPEXT_InputMappingEntrySelectKey(laOperator* a,int exitmode){
+    laKeyDetectorData* kdd=a->CustomData;
+    strSafeDestroy(&kdd->Str);
+    memFree(kdd);
+}
+int OPINV_InputMappingEntrySelectKey(laOperator *a, laEvent *e){
+    if(!a->This || !a->This->EndInstance) return LA_CANCELED; laInputMappingEntry* ime=a->This->EndInstance;
+    a->CustomData = memAcquire(sizeof(laKeyDetectorData));
+    laEnableOperatorPanel(a,a->This,e->x-LA_RH*5,e->y-LA_RH,LA_RH*10,LA_RH*10,LA_RH*20,LA_RH*20,0,0,0,0,0,0,e);
+    laOperatorModalOver(a);
+    return LA_RUNNING;
+}
+int OPMOD_InputMappingEntrySelectKey(laOperator *a, laEvent *e){
+    if(!a->This || !a->This->EndInstance) return LA_CANCELED; laInputMappingEntry* ime=a->This->EndInstance;
+    laKeyDetectorData* kdd=a->CustomData; if(!kdd){ return LA_FINISHED; }
+    char buf[64],*_next=buf;
+    if(ime->DeviceType == LA_INPUT_DEVICE_KEYBOARD){
+        if(e->Type == LA_KEY_DOWN || e->Type == LA_KEY_UP){
+            kdd->Key = e->key; laToUTF8(e->key,buf,&_next); *_next=0; strSafeSet(&kdd->Str,buf);
+            laNotifyInstanceUsers(kdd);
+            return LA_RUNNING;
+        }
+    }else{
+        return LA_FINISHED;
+    }
+    if(a->ConfirmData){
+        if(a->ConfirmData->Mode == LA_CONFIRM_OK){
+            strSafeSet(&ime->Key,SSTR(kdd->Str)); ime->KeyValue = kdd->Key; laNotifyInstanceUsers(ime);
+        }
+        return LA_FINISHED_PASS;
+    }
+    return LA_RUNNING_PASS;
+}
+void laui_InputMappingEntryKeySelector(laUiList *uil, laPropPack *Base, laPropPack *OperatorInst, laColumn *ExtraColumns, int context){
+    laColumn* c=laFirstColumn(uil);
+
+    laShowLabel(uil,c,"Press a Key:",0,0);
+    laShowItem(uil,c,OperatorInst,"pressed_string")->Flags|=LA_UI_FLAGS_PLAIN;
+
+    laUiItem* b=laBeginRow(uil,c,0,0);
+    laShowSeparator(uil,c)->Expand=1;
+    laShowItem(uil,c,0,"LA_confirm");
+    laEndRow(uil,b);
+}
+void laget_KeyDetectorPressedString(laKeyDetectorData* kdd, char* out, char** pivot){
+    sprintf(out, "\"%s\" (0x%0x)", SSTR(kdd->Str), kdd->Key);
+}
+
 
 int OPINV_SaveUserPreferences(laOperator *a, laEvent *e){
     laSaveUserPreferences(); return LA_FINISHED;
@@ -2195,9 +2276,15 @@ void la_RegisterBuiltinOperators(){
 
     laCreateOperatorType("LA_new_input_mapping", "New Mapping", "New input mapping", 0, 0, 0, OPINV_NewInputMapping, 0, '+', LA_ACTUATOR_SYSTEM);
     laCreateOperatorType("LA_new_input_mapping_entry", "New Entry", "New input mapping entry", 0, 0, 0, OPINV_NewInputMappingEntry, 0, '+', LA_ACTUATOR_SYSTEM);
-    laCreateOperatorType("LA_new_remove_mapping", "Remove Mapping", "Remove input mapping", 0, 0, 0, OPINV_RemoveInputMapping, OPMOD_RemoveInputMapping, U'🞫', LA_ACTUATOR_SYSTEM);
-    laCreateOperatorType("LA_new_remove_mapping_entry", "Remove Entry", "Remove input mapping entry", 0, 0, 0, OPINV_RemoveInputMappingEntry, OPMOD_RemoveInputMappingEntry, U'🞫', LA_ACTUATOR_SYSTEM);
-
+    laCreateOperatorType("LA_remove_input_mapping", "Remove Mapping", "Remove input mapping", 0, 0, 0, OPINV_RemoveInputMapping, OPMOD_RemoveInputMapping, U'🞫', LA_ACTUATOR_SYSTEM);
+    laCreateOperatorType("LA_remove_input_mapping_entry", "Remove Entry", "Remove input mapping entry", 0, 0, 0, OPINV_RemoveInputMappingEntry, OPMOD_RemoveInputMappingEntry, U'🞫', LA_ACTUATOR_SYSTEM);
+    at = laCreateOperatorType("LA_input_mapping_entry_select_signal", "Select Signal", "Select signal for this entry", 0, 0, 0, OPINV_InputMappingEntrySelectSignal, OPMOD_InputMappingEntrySelectSignal, U'⯆', LA_ACTUATOR_SYSTEM);
+    at->UiDefine = laui_InputMappingEntrySignalSelector;
+    at = laCreateOperatorType("LA_input_mapping_entry_select_key", "Select Key", "Select key for this entry", 0, 0, OPEXT_InputMappingEntrySelectKey, OPINV_InputMappingEntrySelectKey, OPMOD_InputMappingEntrySelectKey, U'K', LA_ACTUATOR_SYSTEM);
+    at->UiDefine = laui_InputMappingEntryKeySelector;
+    pc = laDefineOperatorProps(at, 1);
+    laAddStringProperty(pc,"pressed_string","Pressed String","String of the pressed key",LA_WIDGET_STRING_PLAIN,0,0,0,1,-1,0,laget_KeyDetectorPressedString,0,0,LA_READ_ONLY);
+    
     laCreateOperatorType("LA_save_user_preferences", "Save Preferences", "Save user preferences", 0, 0, 0, OPINV_SaveUserPreferences, 0, 0, LA_ACTUATOR_SYSTEM);
     laCreateOperatorType("LA_restore_factory", "Restore Factory Settings", "Restore factory settings", 0, 0, 0, OPINV_RestoreFactorySettings, OPMOD_RestoreFactorySettings, 0, LA_ACTUATOR_SYSTEM);
 

+ 47 - 5
resources/la_properties.c

@@ -813,6 +813,33 @@ void* laget_FirstInputMapping(void* unused1,void* unused2){
 void* laget_CurrentInputMapping(laInputMappingBundle* imb){
     return imb->CurrentInputMapping;
 }
+void* laget_FirstCustomSignal(void* unused1,void* unused2){
+    return MAIN.CustomSignals.pFirst;
+}
+void laset_InputMappingEntrySignal(laInputMappingEntry* ime, laCustomSignal* cs){
+    if(cs){ strSafeSet(&ime->Signal,SSTR(cs->Name)); ime->SignalValue=cs->Signal; }
+    else{ strSafeSet(&ime->Signal,"none"); ime->SignalValue=0; }
+}
+void laset_InputMappingEntryKeyString(laInputMappingEntry* ime, char* key){
+    strSafeSet(&ime->Key,key); laInputMappingUpdateSignal(ime); 
+}
+void laset_InputMappingEntrySignalString(laInputMappingEntry* ime, char* sig){
+    strSafeSet(&ime->Signal,sig); laInputMappingUpdateSignal(ime); 
+}
+void laset_SignalFilter(void* unused, char* sig){
+    strSafeSet(&MAIN.SignalFilter,sig);
+    laNotifyUsers("la.filtered_signals");
+}
+void* laget_FirstFilteredCustomSignal(void* unused1,laPropIterator* pi){
+    laCustomSignal* p = MAIN.CustomSignals.pFirst;
+    while(!strstr(SSTR(p->Name),SSTR(MAIN.SignalFilter))){ p=p->Item.pNext; if(!p){ return 0; } }
+    return p;
+}
+void* lagetnext_FilteredSignal(laCustomSignal* p, laPropIterator* pi){
+    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;
+}
 
 void tnspost_World(tnsWorld *w){
     tnsRefreshMaterialLibraries();
@@ -1500,7 +1527,10 @@ void la_RegisterInternalProps(){
             if(MAIN.InitArgs.HasAudio) laAddSubGroup(p, "audio", "Audio", "Audio data","la_audio",0,0,0,offsetof(LA,Audio),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);
+            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);
+            
             laAddStringProperty(p, "identifier", "Identifier", "Identifier", 0,0,0,0,0,0,0,laget_MainIdentifier, 0,0,LA_AS_IDENTIFIER|LA_READ_ONLY);
             laAddSubGroup(p, "test_ucn", "TEST UCN", "---", "udf_content_node",0,0,0,offsetof(LA, TEST_Link), 0,0,0,0,0,0,0,0);
             
@@ -1714,7 +1744,7 @@ void la_RegisterInternalProps(){
         p = laAddPropertyContainer("la_input_mapping", "Input Mapping", "Input mapping data", 0,0,sizeof(laInputMapping), 0,0,2);{
             laAddStringProperty(p, "name", "Name", "The name of this mapping", 0,0,0,"Mapping", 1, offsetof(laInputMapping, Name), 0,0,0,0,LA_AS_IDENTIFIER);
             laAddSubGroup(p, "entries","Entries","Input mapping entries","la_input_mapping_entry",0,0,0,-1,0,0,0,0,0,0,offsetof(laInputMapping,Entries),0);
-            laAddOperatorProperty(p,"remove","Remove","Remove this mapping","LA_new_remove_mapping",U'🞫',0);
+            laAddOperatorProperty(p,"remove","Remove","Remove this mapping","LA_remove_input_mapping",U'🞫',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);{
@@ -1722,9 +1752,15 @@ void la_RegisterInternalProps(){
             laAddEnumItemAs(ep, "KEYBOARD", "Keyboard", "Keyboard input", LA_INPUT_DEVICE_KEYBOARD, 0);
             laAddEnumItemAs(ep, "JOYSTICK", "Joystick", "Joystick input", LA_INPUT_DEVICE_JOYSTICK, 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,0,0,0);
-            laAddStringProperty(p,"message","Message","Target message",0,0,0,0,1,offsetof(laInputMappingEntry,TargetMessage),0,0,0,0,0);
-            laAddOperatorProperty(p,"remove","Remove","Remove this entry","LA_new_remove_mapping_entry",U'🞫',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);
+            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,"select_signal","Select","Select signal","LA_input_mapping_entry_select_signal",0,0);
+            laAddOperatorProperty(p,"select_key","Select Key","Select key","LA_input_mapping_entry_select_key",0,0);
+        }
+        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);
         }
 
         p = laAddPropertyContainer("la_translation_language", "Language", "Translation language pack", 0,0,sizeof(laTranslationNode), 0,0,1);{
@@ -2019,3 +2055,9 @@ void la_RegisterInternalProps(){
 
     la_RegisterTNSProps();
 }
+
+void la_RegisterDefaultSignals(){
+    laNewCustomSignal("la.new",LA_SIGNAL_NEW);
+    laNewCustomSignal("la.delete",LA_SIGNAL_DELETE);
+    laNewCustomSignal("la.confirm",LA_SIGNAL_CONFIRM);
+}

+ 11 - 3
resources/la_templates.c

@@ -1549,14 +1549,22 @@ void laui_InputMappingEntry(laUiList *uil, laPropPack *This, laPropPack *Extra,
     laColumn* c=laFirstColumn(uil);
 
     laUiItem* b=laBeginRow(uil,c,0,0);
+
+    laShowItem(uil,c,This,"remove")->Flags|=LA_UI_FLAGS_ICON;
+
     laShowItem(uil,c,This,"device_type");
     laUiItem* b1=laOnConditionThat(uil,c,laEqual(laPropExpression(This,"device_type"),laIntExpression(LA_INPUT_DEVICE_JOYSTICK)));{
         laShowItem(uil,c,This,"joystick_device");
     }laEndCondition(uil,b1);
 
-    laShowItem(uil,c,This,"key")->Expand=1; laShowItem(uil,c,This,"message")->Expand=1;
-    laShowItem(uil,c,This,"remove")->Flags|=LA_UI_FLAGS_ICON;
-        
+    laShowItem(uil,c,This,"key")->Expand=1;
+    laShowItem(uil,c,This,"select_key")->Flags|=LA_UI_FLAGS_ICON;
+
+    
+    laShowItem(uil,c,This,"signal")->Expand=1;
+    //laShowItemFull(uil,c,This,"signal_selection",LA_WIDGET_COLLECTION_SELECTOR,0,0,0)->Flags|=LA_UI_COLLECTION_SIMPLE_SELECTOR;
+    laShowItem(uil,c,This,"select_signal")->Flags|=LA_UI_FLAGS_ICON;
+
     laEndRow(uil,b);
 }
 void laui_InputMapping(laUiList *uil, laPropPack *This, laPropPack *Extra, laColumn *UNUSED, int context){

+ 8 - 2
resources/la_widgets.c

@@ -2881,6 +2881,7 @@ int OPMOD_SingleLineString(laOperator *a, laEvent *e){
     int NoEvent = ui->Flags&LA_UI_FLAGS_NO_EVENT;
     int NoTooltip=ui->Flags&LA_UI_FLAGS_NO_TOOLTIP;
     int IsTerminal=ui->Flags&LA_UI_FLAGS_TERMINAL_INPUT;
+    int ImmediateInput=ui->Flags&LA_UI_FLAGS_IMMEDIATE_INPUT;
 
     if (!laIsInUiItem(ui, e->x, e->y)){
         if (ui->State != LA_UI_EDITING){
@@ -2957,7 +2958,12 @@ int OPMOD_SingleLineString(laOperator *a, laEvent *e){
     }
 
     if (ui->State == LA_UI_EDITING){
-        if (la_ProcessTextEdit(e, se, ui))laRedrawCurrentPanel();
+        if (la_ProcessTextEdit(e, se, ui)){
+            laRedrawCurrentPanel();
+            if(ImmediateInput){
+                buf=strGetEditString(uit->Edit,0); laSetString(&ui->PP, buf); free(buf);
+            }
+        }
         return LA_RUNNING;
     }
 
@@ -3151,7 +3157,7 @@ int OPMOD_Collection(laOperator *a, laEvent *e) {
         char *cmd;
         if ((!(cmd = strGetArgumentString(ui->Instructions, "feedback"))) ||
             (!strSame(cmd, "NONE"))) {
-          laConfirmInt(a, 0, LA_CONFIRM_DATA);
+            laConfirmPointer(a, uil->Instance, la_EnsureSubTarget(ui->PP.LastPs->p, uil->Instance), LA_CONFIRM_DATA);
         }
         laSetActiveInstance(ui->PP.LastPs->p, ui->PP.LastPs->UseInstance,
                             uil->Instance);