/* * LaGUI: A graphical application framework. * Copyright (C) 2022-2023 Wu Yiming * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "la_5.h" extern LA MAIN; int la_GetKeyablePropertyStorageSize(laProp* p); laAction* laNewAction(char* Name){ laAction* aa=memAcquire(sizeof(laAction)); if(!Name || !Name[0]){ Name="New Action"; } strSafeSet(&aa->Name,Name); aa->Length=5; aa->FrameCount=120; lstAppendItem(&MAIN.Actions,aa); laNotifyUsers("la.actions"); return aa; } laAnimationChannel* laAnimationEnsureChannel(laAction* aa, void* hyper1, laProp* p){ laAnimationChannel* acf=0; int DataSize=la_GetKeyablePropertyStorageSize(p); if(!DataSize) return 0; for(laAnimationChannel* ac=aa->Channels.pFirst;ac;ac=ac->Item.pNext){ if(ac->For==hyper1 && ac->Prop==p){ acf=ac; break; } } if(acf) return acf; acf=memAcquire(sizeof(laAnimationChannel)); memAssignRef(acf,&acf->For,hyper1); acf->Prop=p; acf->DataSize = DataSize; lstAppendItem(&aa->Channels,acf); return acf; } laAnimationChannel* laAnimationEnsureFrame(laAnimationChannel* ac, int frame){ laAnimationKey* akf=0,*beforeakf=0; for(laAnimationKey* ak=ac->Keys.pFirst;ak;ak=ak->Item.pNext){ if(ak->At==frame){ akf=ak; break; } if(ak->At>frame){ beforeakf=ak; break; } } if(!akf){ akf=memAcquireSimple(sizeof(laAnimationKey)-sizeof(uint64_t)+ac->DataSize); akf->At=frame; if(beforeakf){ lstInsertItemBefore(&ac->Keys, akf, beforeakf); } lstAppendItem(&ac->Keys, akf); } return akf; } void laAnimationStoreKeyValue(laAnimationChannel* ac, laAnimationKey* ak){ laPropPack PP={0}; laPropStep PS={0}; PS.p=ac->Prop; PS.Type='.'; PS.UseInstance=ac->For; PP.LastPs=&PS; PP.EndInstance=ac->For; switch(ac->Prop->PropertyType){ case LA_PROP_INT: case LA_PROP_INT | LA_PROP_ARRAY: laGetIntArray(&PP,(int*)&ak->Data); case LA_PROP_FLOAT: case LA_PROP_FLOAT | LA_PROP_ARRAY: laGetFloatArray(&PP,(real*)&ak->Data); case LA_PROP_ENUM: case LA_PROP_ENUM | LA_PROP_ARRAY: laGetEnumArray(&PP,(laEnumItem**)&ak->Data); case LA_PROP_SUB: case LA_PROP_OPERATOR: case LA_PROP_STRING: case LA_PROP_RAW: default: return; } } laAnimationKey* laAnimationInsertKeyFrame(laAction* aa, void* hyper1, laProp* p){ laAnimationChannel* ac=laAnimationEnsureChannel(aa,hyper1,p); if(!ac || !ac->For) return; int frame=aa->PlayHead/aa->Length*aa->FrameCount; laAnimationKey* ak=laAnimationEnsureFrame(ac->DataSize,frame); laAnimationStoreKeyValue(ac,ak); } int OPINV_NewAction(laOperator *a, laEvent *e){ laNewAction(0); return LA_FINISHED; } void la_RegisterAnimationResources(){ laPropContainer *pc; laProp *p; laOperatorType *at; laEnumProp *ep; laCreateOperatorType("LA_new_action", "New Action", "Add a new action",0,0,0,OPINV_NewAction,0,0,0); }