*/}}
Quellcode durchsuchen

Change to animation holder structure.

YimingWu vor 1 Jahr
Ursprung
Commit
fda4189119
8 geänderte Dateien mit 185 neuen und 44 gelöschten Zeilen
  1. 124 21
      la_animation.c
  2. 16 2
      la_data.h
  3. 2 0
      la_kernel.c
  4. 2 0
      la_tns.h
  5. 2 2
      resources/la_operators.c
  6. 16 6
      resources/la_properties.c
  7. 19 11
      resources/la_templates.c
  8. 4 2
      resources/la_widgets.c

+ 124 - 21
la_animation.c

@@ -19,17 +19,62 @@
 #include "la_5.h"
 
 extern LA MAIN;
+extern tnsMain* T;
 
 int la_GetKeyablePropertyStorageSize(laProp* p);
 void la_AnimationEvaluateActions(int ClampOffsets);
+void laget_AnimationActionHolderCategory(void* a_unused, laActionHolder* ah, char* copy, char** ptr);
+void laui_AnimationActionHolder(laUiList *uil, laPropPack *This, laPropPack *Extra, laColumn *ExtraColumns, int context);
+
+int laAnimationRegisterHolderPath(const char* Path){
+    laPropPack PP={0}; if(!la_GetPropFromPath(&PP,0,Path,0)){ la_FreePropStepCache(PP.Go); return 0; }
+    la_EnsureSubTarget(PP.LastPs->p,0);
+    if((!PP.LastPs->p->SubProp) || (!la_PropLookup(&PP.LastPs->p->SubProp->Props,"__actions__"))){
+        la_FreePropStepCache(PP.Go); return 0;
+    }
+    laActionHolderPath* ahp=memAcquire(sizeof(laActionHolderPath));
+    ahp->OriginalPath=Path;
+    la_CopyPropPack(&PP,&ahp->PP); lstAppendItem(&MAIN.Animation->ActionHolderPaths,ahp);
+    la_FreePropStepCache(PP.Go);
+    return 1;
+}
+
+void laAnimationUpdateHolderList(){
+    laActionHolder* ah;
+    while(ah=lstPopItem(&MAIN.Animation->ActionHolders)){
+        strSafeDestroy(&ah->Name); strSafeDestroy(&ah->CategoryTitle); memFree(ah);
+    }
+
+    for(laActionHolderPath* ahp=MAIN.Animation->ActionHolderPaths.pFirst;ahp;ahp=ahp->Item.pNext){
+        la_StepPropPack(&ahp->PP); laSubProp* pa=ahp->PP.LastPs->p; la_EnsureSubTarget(pa,0); laPropIterator pi={0};
+        int ListOffset=0; laSubProp* paa=la_PropLookup(&pa->Base.SubProp->Props,"__actions__");
+        if((!paa) || (!paa->ListHandleOffset)){ continue; } ListOffset=paa->ListHandleOffset;
+        void* inst=laGetInstance(ahp->PP.LastPs->p,ahp->PP.LastPs->UseInstance,&pi); int FirstIn=1;
+        while(inst){
+            ah=memAcquire(sizeof(laActionHolder));
+            memAssignRef(ah,&ah->Instance,inst);
+            ah->ListHandleOffset=ListOffset;
+            char _id[64]="unamed", *id=_id;
+            laTryGetInstanceIdentifier(inst,pa->Base.SubProp,_id,&id);
+            strSafeSet(&ah->Name,id);
+            if(FirstIn){ strSafeSet(&ah->CategoryTitle,pa->Base.SubProp->Name); }
+            lstAppendItem(&MAIN.Animation->ActionHolders,ah);
+            inst=laGetNextInstance(ahp->PP.LastPs->p, inst, &pi);
+        }
+    }
+    laNotifyUsers("la.animation.action_holders"); 
+}
 
-laAction* laAnimiationNewAction(char* Name){
+laAction* laAnimiationNewAction(laActionHolder* ah, char* Name){
     laAction* aa=memAcquire(sizeof(laAction));
     if(!Name || !Name[0]){ Name="New Action"; }
     strSafeSet(&aa->Name,Name);
     aa->Length=2; aa->FrameCount=24;
     memAssignRef(MAIN.Animation,&MAIN.Animation->CurrentAction,aa);
-    lstAppendItem(&MAIN.Animation->Actions,aa); laNotifyUsers("la.animation.actions");
+    void* lh=((uint8_t*)ah->Instance)+ah->ListHandleOffset;
+    lstAppendItem(lh,aa);
+    laNotifyInstanceUsers(ah->Instance);
+    laNotifyUsers("la.animation.current_action");
     return aa;
 }
 laActionProp* laAnimationEnsureProp(void* hyper1, laProp* p){
@@ -95,11 +140,55 @@ void laAnimationSetPlayHead(real time){
     MAIN.Animation->PlayHead=time;
 }
 
-
+STRUCTURE(laNewActionData){
+    laActionHolder* SelectedHolder;
+};
+laActionHolder* laget_AnimationFirstActionHolder(void* unused1, void* unused2){
+    return MAIN.Animation->ActionHolders.pFirst;
+}
+void laset_AnimationNewActionSetHolder(laNewActionData *np, laActionHolder *ah, int State){
+    np->SelectedHolder = ah;
+}
 int OPINV_AnimationNewAction(laOperator *a, laEvent *e){
-    laAnimiationNewAction(0);
-    return LA_FINISHED;
+    laAnimationUpdateHolderList();
+    laNewActionData* np= CreateNew(laNewActionData);
+    a->CustomData = np;
+    laEnableOperatorPanel(a, 0, e->x-50,e->y-50,500,500,10000,0,0,0,0,0,0,0,e);
+    return LA_RUNNING;
+}
+int OPMOD_AnimationNewAction(laOperator *a, laEvent *e){
+    laNewActionData* np=a->CustomData;
+
+    if(!a->ConfirmData) return LA_RUNNING;
+
+    if(a->ConfirmData->Mode == LA_CONFIRM_CANCEL||a->ConfirmData->Mode == LA_CONFIRM_OK){ if(np) free(np); return LA_CANCELED; }
+
+    if(a->ConfirmData->Mode == LA_CONFIRM_DATA){
+        if (!np || !np->SelectedHolder){ if(np) free(np); return LA_CANCELED; }
+        laAnimiationNewAction(np->SelectedHolder,0); free(np);
+        return LA_FINISHED;
+    }
+
+    return LA_RUNNING;
 }
+void laui_AnimationNewAction(laUiList *uil, laPropPack *This, laPropPack *OperatorProps, laColumn *UNUSED, int context){
+    laColumn *c = laFirstColumn(uil);
+    laUiItem* ui=laShowItem(uil, c, OperatorProps, "holder");ui->SymbolID=3; ui->Flags|=LA_UI_FLAGS_NO_DECAL;
+}
+
+int OPINV_AnimationSelectAction(laOperator *a, laEvent *e){
+    laEnableOperatorPanel(a, 0, e->x-50,e->y-50,500,500,10000,0,0,0,0,0,0,0,e);
+    return LA_RUNNING;
+}
+void laui_AnimationSelectAction(laUiList *uil, laPropPack *This, laPropPack *OperatorProps, laColumn *UNUSED, int context){
+    laColumn *c = laFirstColumn(uil);
+    for(laActionHolderPath* ahp=MAIN.Animation->ActionHolderPaths.pFirst;ahp;ahp=ahp->Item.pNext){
+        laShowLabel(uil,c,ahp->PP.LastPs->p->Name,0,0)->Flags|=LA_UI_FLAGS_DISABLED|LA_TEXT_MONO;
+        laShowItemFull(uil,c,0,ahp->OriginalPath,LA_WIDGET_COLLECTION,0,laui_AnimationActionHolder,0)->Flags|=LA_UI_FLAGS_NO_DECAL|LA_UI_FLAGS_NO_GAP;
+    }
+}
+
+
 int OPINV_AnimationPlayAction(laOperator *a, laEvent *e){
     char* str=strGetArgumentString(a->ExtraInstructionsP, "mode");
     int PlayStatus=LA_ANIMATION_STATUS_PAUSED;
@@ -192,23 +281,28 @@ void la_AnimationEvaluateActionChannels(laAction* aa){
 void la_AnimationEvaluateActions(int ClampOffsets){
     int any=0;
     la_AnimationMarkPropReset();
-    for(laAction* aa=MAIN.Animation->Actions.pFirst;aa;aa=aa->Item.pNext){
-        real preoffset=0,postoffset=aa->Offset/aa->Length;
-        if(ClampOffsets || (MAIN.Animation->PlayStatus!=LA_ANIMATION_STATUS_PAUSED)){
-            while(aa->Offset>aa->Length){ aa->Offset-=aa->Length; }
-            while(aa->Offset<-1e-6){ aa->Offset+=aa->Length; }
-            preoffset=aa->Offset; postoffset=0;
+    for(laActionHolder* ah=MAIN.Animation->ActionHolders.pFirst;ah;ah=ah->Item.pNext){
+        if(!ah->Instance) continue;
+        laListHandle* lh=((uint8_t*)ah->Instance)+ah->ListHandleOffset;
+        for(laAction* aa=lh->pFirst;aa;aa=aa->Item.pNext){
+            real preoffset=0,postoffset=aa->Offset/aa->Length;
+            if(ClampOffsets || (MAIN.Animation->PlayStatus!=LA_ANIMATION_STATUS_PAUSED)){
+                while(aa->Offset>aa->Length){ aa->Offset-=aa->Length; }
+                while(aa->Offset<-1e-6){ aa->Offset+=aa->Length; }
+                preoffset=aa->Offset; postoffset=0;
+            }
+            real UseTime=MAIN.Animation->PlayHead-preoffset;
+            int repeats=UseTime/aa->Length;
+            real remaining=UseTime-repeats*aa->Length;
+            while(remaining<0){ remaining+=aa->Length; }
+            if(aa->PlayMode==LA_ANIMATION_PLAY_MODE_REPEAT){ aa->PlayHead=remaining/aa->Length-postoffset; }
+            elif(aa->PlayMode==LA_ANIMATION_PLAY_MODE_HOLD){ aa->PlayHead=((UseTime>aa->Length)?1.0:(UseTime<0?0:UseTime/aa->Length))-postoffset; }
+            elif(aa->PlayMode==LA_ANIMATION_PLAY_MODE_BOUNCE){ real t=remaining/aa->Length; aa->PlayHead=((repeats%2)?(1-t):t)-postoffset; }
+            any=1;
+            la_AnimationEvaluateActionChannels(aa);
         }
-        real UseTime=MAIN.Animation->PlayHead-preoffset;
-        int repeats=UseTime/aa->Length;
-        real remaining=UseTime-repeats*aa->Length;
-        while(remaining<0){ remaining+=aa->Length; }
-        if(aa->PlayMode==LA_ANIMATION_PLAY_MODE_REPEAT){ aa->PlayHead=remaining/aa->Length-postoffset; }
-        elif(aa->PlayMode==LA_ANIMATION_PLAY_MODE_HOLD){ aa->PlayHead=((UseTime>aa->Length)?1.0:(UseTime<0?0:UseTime/aa->Length))-postoffset; }
-        elif(aa->PlayMode==LA_ANIMATION_PLAY_MODE_BOUNCE){ real t=remaining/aa->Length; aa->PlayHead=((repeats%2)?(1-t):t)-postoffset; }
-        any=1;
-        la_AnimationEvaluateActionChannels(aa);
     }
+    
     for(laActionProp* ap=MAIN.Animation->Props.pFirst;ap;ap=ap->Item.pNext){ if(ap->Reset){ continue; }
         la_AnimationSetPropValue(ap);
     }
@@ -548,7 +642,16 @@ void la_AnimationActionDrawOverlay(laUiItem *ui, int h){
 void la_RegisterAnimationResources(){
     laPropContainer *pc; laProp *p; laOperatorType *at; laEnumProp *ep;
 
-    laCreateOperatorType("LA_animation_new_action", "New Action", "Add a new action",0,0,0,OPINV_AnimationNewAction,0,U'🞦',0);
+    at=laCreateOperatorType("LA_animation_new_action", "New Action", "Add a new action",0,0,0,OPINV_AnimationNewAction,OPMOD_AnimationNewAction,U'🞦',0);
+    pc = laDefineOperatorProps(at, 0);
+    p = laAddSubGroup(pc, "holder", "Holder", "Action holder to add the new action into", "la_animation_action_holder",
+        0, 0, laui_IdentifierOnly, -1, laget_AnimationFirstActionHolder, 0, laget_ListNext, 0, 0, laset_AnimationNewActionSetHolder,0,0);
+    laSubGroupExtraFunctions(p,0,0,0,laget_AnimationActionHolderCategory);
+    at->UiDefine=laui_AnimationNewAction;
+
+    at=laCreateOperatorType("LA_animation_select_action", "Select Action", "Select an action",0,0,0,OPINV_AnimationSelectAction,OPMOD_FinishOnData,U'⯆',0);
+    at->UiDefine=laui_AnimationSelectAction;
+
     laCreateOperatorType("LA_animation_set_play_status", "Set Play", "Set global animation player status",0,0,0,OPINV_AnimationPlayAction,0,0,0);
     laCreateOperatorType("LA_animation_reset_time", "Reset Time", "Reset Time",0,0,0,OPINV_AnimationResetTime,0,U'🡄',0);
 

+ 16 - 2
la_data.h

@@ -661,10 +661,23 @@ STRUCTURE(laDiffPost){
 #define LA_ANIMATION_MIX_ADD     1
 
 NEED_STRUCTURE(laAction);
+STRUCTURE(laActionHolder){
+    laListItem Item;
+    void* Instance; int ListHandleOffset;
+    laPropContainer* Container;
+    laSafeString* Name;
+    laSafeString* CategoryTitle;
+};
+STRUCTURE(laActionHolderPath){
+    laListItem Item;
+    laPropPack PP;
+    char* OriginalPath;
+};
 STRUCTURE(laAnimation){
     real _PAD;
     laAction*    CurrentAction;
-    laListHandle Actions;
+    laListHandle ActionHolders;
+    laListHandle ActionHolderPaths;
     laListHandle Props;
     real PlayHead;
     int PlayStatus;
@@ -1033,7 +1046,7 @@ void laRedo();
 #define LA_ANIMATION_STATUS_PLAY_FWD 1
 #define LA_ANIMATION_STATUS_PLAY_REV 2
 
-laAction* laAnimiationNewAction(char* Name);
+laAction* laAnimiationNewAction(laActionHolder* ah, char* Name);
 laActionChannel* laAnimationEnsureChannel(laAction* aa, void* hyper1, laProp* p);
 laActionChannel* laAnimationEnsureFrame(laActionChannel* ac, int frame);
 void laAnimationStoreKeyValue(laActionChannel* ac, laActionKey* ak);
@@ -1045,3 +1058,4 @@ void laAnimationSetPlayHead(real time);
 void la_AnimationPreFrame();
 void la_AnimationPostFrame();
 
+int laAnimationRegisterHolderPath(const char* Path);

+ 2 - 0
la_kernel.c

@@ -906,6 +906,8 @@ int laGetReadyWith(int GLMajor, int GLMinor, int BufferSamples){
 
     la_RegenerateWireColors();
 
+    laAnimationRegisterHolderPath("tns.world.root_objects");
+
     logPrintNew("Initialization Completed\n");
     MAIN.InitDone=1;
 

+ 2 - 0
la_tns.h

@@ -609,6 +609,8 @@ struct _tnsObject
     laListHandle ChildObjects;
 
     laListHandle Drivers; // rack
+
+    laListHandle Actions;
 };
 
 NEED_STRUCTURE(laNodeInSocket);

+ 2 - 2
resources/la_operators.c

@@ -1006,10 +1006,10 @@ int OPMOD_NewPanel(laOperator *a, laEvent *e){
 
     if(!a->ConfirmData) return LA_RUNNING;
 
-    if(a->ConfirmData->Mode == LA_CONFIRM_CANCEL||a->ConfirmData->Mode == LA_CONFIRM_OK) return LA_CANCELED;
+    if(a->ConfirmData->Mode == LA_CONFIRM_CANCEL||a->ConfirmData->Mode == LA_CONFIRM_OK){ if(np) free(np);  return LA_CANCELED; }
 
     if(a->ConfirmData->Mode == LA_CONFIRM_DATA){
-        if (!np || !np->SelectedTemplate) return LA_CANCELED;
+        if (!np || !np->SelectedTemplate){ if(np) free(np); return LA_CANCELED; }
         laPanel *p = la_FindFreePanelByTemplate(MAIN.CurrentWindow, np->SelectedTemplate);
         if (!p){
             p = laCreateTopPanel(MAIN.CurrentWindow, np->SelectedTemplate->Identifier->Ptr, e->x, e->y,0,0,0,0,0,0,0,0,0,0);

+ 16 - 6
resources/la_properties.c

@@ -514,11 +514,11 @@ void* laget_FirstDriverPage(void* unused, void* unused2){
 void* laget_CurrentRackPage(laRackPageCollection* c){
     return c->CurrentPage;
 }
-void* laget_CurrentAnimationAction(laAnimation* a){
-    return a->CurrentAction;
+void* laget_CurrentAnimationAction(void* unused_a){
+    return MAIN.Animation->CurrentAction;
 }
-void* laset_CurrentAnimationAction(laAnimation* a, laAction* c){
-    memAssignRef(a,&a->CurrentAction,c);
+void* laset_CurrentAnimationAction(void* unused_a, laAction* c){
+    memAssignRef(MAIN.Animation,&MAIN.Animation->CurrentAction,c);
 }
 
 void laset_WindowColorSpace(laWindow* w, int space){
@@ -825,6 +825,10 @@ laPropContainer* tnsget_ObjectType(tnsObject* o){
     }
 }
 
+void laget_AnimationActionHolderCategory(void* a_unused, laActionHolder* ah, char* copy, char** ptr){
+    if(ah->CategoryTitle&&ah->CategoryTitle->Ptr) *ptr=ah->CategoryTitle->Ptr;
+}
+
 int laget_AnimationActionCurrentFrame(laAction* aa){
     return LA_ACTION_FRAME(aa);
 }
@@ -1414,8 +1418,10 @@ void la_RegisterInternalProps(){
 
 
         p = laAddPropertyContainer("la_animation", "Animation", "Animation data",0,0,sizeof(laAnimation),0,0,1);{
-            laAddSubGroup(p, "actions", "Actions", "All animation actions","la_animation_action",0,0,0,-1,0,laget_CurrentAnimationAction,0,laset_CurrentAnimationAction,0,0,offsetof(laAnimation,Actions),0);
-            laAddSubGroup(p, "current_action", "Current Action", "Current action","la_animation_action",0,0,0,offsetof(laAnimation,CurrentAction),0,0,0,0,0,0,0,LA_UDF_REFER);
+            sp = laAddSubGroup(p, "action_holders", "Action Holders", "All action holders","la_animation_action_holder",0,0,0,-1,0,0,0,0,0,0,offsetof(laAnimation,ActionHolders),0);
+            laSubGroupExtraFunctions(sp,0,0,0,laget_AnimationActionHolderCategory);
+
+            laAddSubGroup(p, "current_action", "Current Action", "Current action","la_animation_action",0,0,0,offsetof(laAnimation,CurrentAction),0,0,0,0,0,0,0,LA_UDF_REFER|LA_READ_ONLY);
             
             laAddFloatProperty(p, "play_head","Play Head","Animation viewer global playhead",0,0,"s",0,0,0.1,0,0,offsetof(laAnimation,PlayHead),0,0,0,0,0,0,0,0,0,0,0);
             ep=laAddEnumProperty(p, "play_status", "Play Status", "Animation viewer global play status", 0,0,0,0,0,offsetof(laAnimation, PlayStatus),0,0,0,0,0,0,0,0,0,0);
@@ -1463,6 +1469,9 @@ void la_RegisterInternalProps(){
             laAddIntProperty(p, "at","At","Frame number of this key frame",0,0,0,0,0,0,0,0,offsetof(laActionKey,At),0,0,0,0,0,0,0,0,0,0,0);
             // XXX: RAW for r/w.
         }
+        p = laAddPropertyContainer("la_animation_action_holder", "Action Holder", "Action holder",0,0,sizeof(laActionHolder),0,0,1);{
+            laAddStringProperty(p,"name","Name","Name of the action",0,0,0,0,1,offsetof(laActionHolder,Name),0,0,0,0,LA_AS_IDENTIFIER);
+        }
     }
 
     // TNS WORLD ============================================================================================
@@ -1547,6 +1556,7 @@ void la_RegisterInternalProps(){
         laAddSubGroup(p, "in_root", "In Root", "Root object of this object", "tns_object",0,0,0,offsetof(tnsObject, InRoot), 0,0,0,0,0,0,0,LA_UDF_REFER);
         laAddSubGroup(p, "parent", "Parent", "Object parent", "tns_object",0,0,0,offsetof(tnsObject, ParentObject), 0,0,0,0,0,0,0,LA_UDF_REFER);
         laAddSubGroup(p, "children", "Children", "The Children Of This Object", "tns_child_object",0,0,0,-1, 0,0,0,0,0,0,offsetof(tnsObject, ChildObjects), 0);
+        laAddSubGroup(p, "__actions__", "Actions", "Animation actions", "la_animation_action",0,0,0,-1,0,laget_CurrentAnimationAction,0,laset_CurrentAnimationAction,0,0,offsetof(tnsObject, Actions), 0);
     }
     p = laAddPropertyContainer("tns_mesh_object", "Mesh Object", "Mesh object", 0,0,sizeof(tnsMeshObject), tnspost_Object, 0,2);{
         laPropContainerExtraFunctions(p,0,0,tnstouched_Object,0/*tnspropagate_Object*/,0);

+ 19 - 11
resources/la_templates.c

@@ -1564,10 +1564,11 @@ void laui_Drivers(laUiList *uil, laPropPack *This, laPropPack *Extra, laColumn *
     laShowItemFull(uil,c,Extra,"page",LA_WIDGET_COLLECTION_SINGLE,0,laui_RackPage,0)->Flags|=LA_UI_FLAGS_NO_DECAL;;
 }
 
+
 void laui_AnimationActionSimple(laUiList *uil, laPropPack *This, laPropPack *Extra, laColumn *ExtraColumns, int context){
     laColumn* c=laFirstColumn(uil);
     laUiItem* b=laBeginRow(uil,c,0,0);{
-        laUiItem* b2=laOnConditionThat(uil,c,laEqual(laPropExpression(This,"__self"),laPropExpression(0,"la.animation.actions")));{
+        laUiItem* b2=laOnConditionThat(uil,c,laEqual(laPropExpression(This,"__self"),laPropExpression(0,"la.animation.current_action")));{
             laShowLabel(uil,c,"🠶",0,0)->Flags|=LA_TEXT_MONO|LA_TEXT_ALIGN_RIGHT;
         }laElse(uil,b2);{
             laShowLabel(uil,c,"  ",0,0)->Flags|=LA_TEXT_MONO;
@@ -1580,10 +1581,14 @@ void laui_AnimationActionSimple(laUiList *uil, laPropPack *This, laPropPack *Ext
     }
     laEndRow(uil,b);
 }
+void laui_AnimationActionHolder(laUiList *uil, laPropPack *This, laPropPack *Extra, laColumn *ExtraColumns, int context){
+    laColumn* c=laFirstColumn(uil);
+    laShowItemFull(uil,c,This,"__actions__",0,0,laui_AnimationActionSimple,0)->Flags|=LA_UI_FLAGS_NO_DECAL;
+}
 void laui_AnimationActionListItem(laUiList *uil, laPropPack *This, laPropPack *Extra, laColumn *ExtraColumns, int context){
     laColumn* c=laFirstColumn(uil); laUiItem* ui;
     laUiItem* b=laBeginRow(uil,c,0,0);{
-        //laUiItem* b2=laOnConditionThat(uil,c,laNot(laEqual(laPropExpression(This,"__self"),laPropExpression(0,"la.animation.actions"))));{
+        //laUiItem* b2=laOnConditionThat(uil,c,laNot(laEqual(laPropExpression(This,"__self"),laPropExpression(0,"la.animation.current_action"))));{
         //    ui=laShowItemFull(uil,c,This,"play_head",LA_WIDGET_VALUE_METER,0,0,0);
         //    ui->Flags|=LA_UI_FLAGS_NO_LABEL|LA_UI_FLAGS_UNDERNEATH; ui->Expand=1;
         //}laEndCondition(uil,b2);
@@ -1614,19 +1619,21 @@ void laui_AnimationActions(laUiList *uil, laPropPack *This, laPropPack *Extra, l
 
     ui=laMakeEmptyGroup(uil,c,"Use Format",0); laUiList* gu=ui->Page; laColumn* gc=laFirstColumn(gu);
     gu->HeightCoeff=-3; //ui->Flags|=LA_UI_FLAGS_NO_DECAL;
-    laShowItemFull(gu,gc,0,"la.animation.actions",LA_WIDGET_COLLECTION,0,laui_AnimationActionSimple,0)->Flags|=LA_UI_FLAGS_NO_DECAL;
+    for(laActionHolderPath* ahp=MAIN.Animation->ActionHolderPaths.pFirst;ahp;ahp=ahp->Item.pNext){
+        laShowLabel(gu,gc,ahp->PP.LastPs->p->Name,0,0)->Flags|=LA_UI_FLAGS_DISABLED|LA_TEXT_MONO;
+        laShowItemFull(gu,gc,0,ahp->OriginalPath,LA_WIDGET_COLLECTION,0,laui_AnimationActionHolder,0)->Flags|=LA_UI_FLAGS_NO_DECAL|LA_UI_FLAGS_NO_GAP;
+    }
 
     row=laBeginRow(uil,cl,0,0);
     laShowItemFull(uil,cl,0,"LA_animation_new_action",0,"text=New",0,0);//->Flags|=LA_UI_FLAGS_ICON;
     laEndRow(uil,row);
 }
 void laui_AnimationActionChannels(laUiList *uil, laPropPack *This, laPropPack *Extra, laColumn *UNUSED, int context){
-    laColumn* c=laFirstColumn(uil),*cl, *cr, *cll,*clr, *crl, *crr, *crrl,*crrr;
+    laColumn* c=laFirstColumn(uil),*cl, *cr, *cll,*clr, *crl, *crr;
     laSplitColumn(uil,c,0.3); cl=laLeftColumn(c,6); cr=laRightColumn(c,0);
     laSplitColumn(uil,cl,0.75); cll=laLeftColumn(cl,0); clr=laRightColumn(cl,1);
-    laSplitColumn(uil,cr,0.6); crl=laLeftColumn(cr,0); crr=laRightColumn(cr,12);
-    laSplitColumn(uil,crr,0.5); crrl=laLeftColumn(crr,0); crrr=laRightColumn(crr,0);
-    laUiItem* b,*ui,*b2;
+    laSplitColumn(uil,cr,0.75); crl=laLeftColumn(cr,0); crr=laRightColumn(cr,10);
+    laUiItem* b,*ui,*b2,*b3;
 
     laUiItem* row=laBeginRow(uil,cll,0,0);
     laShowItemFull(uil,cll,0,"LA_animation_reset_time",0,"current=true;text=1",0,0)->Flags|=LA_UI_FLAGS_EXIT_WHEN_TRIGGERED;
@@ -1650,8 +1657,10 @@ void laui_AnimationActionChannels(laUiList *uil, laPropPack *This, laPropPack *E
         laShowItem(uil,crl,0,"la.animation.current_action.frame_count")->Flags|=LA_TEXT_ALIGN_CENTER;
         laShowItem(uil,crl,0,"la.animation.current_action.length");
         laEndRow(uil,row);
-        laShowItem(uil,crrl,0,"la.animation.current_action.name");
-        laShowItemFull(uil,crrr,0,"la.animation.actions",LA_WIDGET_COLLECTION_SELECTOR,0,laui_AnimationActionListItem,0);
+        b3=laBeginRow(uil,crr,0,0);
+        laShowItem(uil,crr,0,"la.animation.current_action.name")->Expand=1;
+        laShowItemFull(uil,crr,0,"LA_animation_select_action",0,0,0,0)->Flags|=LA_UI_FLAGS_ICON;
+        laEndRow(uil,b3);
         b=laOnConditionToggle(uil,clr,0,0,0,0,0);{
             row=laBeginRow(uil,cr,0,0);
             laShowItem(uil,cr,0,"la.animation.current_action.mix_mode")->Flags|=LA_UI_FLAGS_EXPAND;
@@ -1663,10 +1672,9 @@ void laui_AnimationActionChannels(laUiList *uil, laPropPack *This, laPropPack *E
         }laEndCondition(uil,b);
     }laElse(uil,b2);{
         laShowLabel(uil,crl,"Please select an action.",0,0);
-        laShowItemFull(uil,crrr,0,"la.animation.actions",LA_WIDGET_COLLECTION_SELECTOR,0,laui_AnimationActionListItem,0);
+        laShowItemFull(uil,crr,0,"LA_animation_select_action",0,0,0,0);
     }laEndCondition(uil,b2);
 
-
     laShowCanvas(uil,c,0,"la.animation.current_action","la_AnimationActionDrawCanvas",-1);
 }
 

+ 4 - 2
resources/la_widgets.c

@@ -2692,7 +2692,7 @@ int OPMOD_Collection(laOperator *a, laEvent *e){
     if (e->Type == LA_L_MOUSE_DOWN && (!laIsPropertyReadOnly(&ui->PP)) && ui->Type!=_LA_UI_COLLECTION_SINGLE){
         laUiList *uil;
         for (uil = ui->Subs.pFirst; uil; uil = uil->Item.pNext){
-            if (a->ConfirmData) return LA_RUNNING;
+            if (a->ConfirmData) return LA_RUNNING_PASS;
             if (laIsInBound(e->x, e->y, uil->L, uil->R, uil->U, uil->B)){
                 laRecalcCurrentPanel();
                 laPropPack PP={0}; la_CopyPropPack(&ui->PP, &PP); //needed because layout can be switched after set active.
@@ -2727,6 +2727,7 @@ int OPMOD_CollectionSelector(laOperator *a, laEvent *e){
     laEnumProp *ep = ui->PP.LastPs->p;
     int NoTooltip=ui->Flags&LA_UI_FLAGS_NO_TOOLTIP;
     int at = 0;
+    int ReadOnly=laIsPropertyReadOnly(&ui->PP);
 
     if (a->ConfirmData /* && a->ConfirmData->Mode == LA_CONFIRM_DATA*/){
         ui->State = LA_UI_NORMAL;
@@ -2749,8 +2750,9 @@ int OPMOD_CollectionSelector(laOperator *a, laEvent *e){
         laColumn *col;
         laPanel *p;
         int GX = ui->L, GY = ui->B, GR = ui->R, t = 0;
+        if(ReadOnly){ return LA_FINISHED; }
 
-        if ((!laIsPropertyReadOnly(&ui->PP)) && e->x >= TNS_MAX2(ui->R - LA_RH,(ui->R+ui->L)/2) && e->x < ui->R){
+        if (e->x >= TNS_MAX2(ui->R - LA_RH,(ui->R+ui->L)/2) && e->x < ui->R){
             laSetActiveInstance(ui->PP.LastPs->p, ui->PP.LastPs->UseInstance, 0);
             laRecordAndPushProp(&ui->PP,0); laMarkPropChanged(&ui->PP);
             return LA_FINISHED;