*/}}

la_animation.c 3.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. /*
  2. * LaGUI: A graphical application framework.
  3. * Copyright (C) 2022-2023 Wu Yiming
  4. *
  5. * This program is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation, either version 3 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. #include "la_5.h"
  19. extern LA MAIN;
  20. int la_GetKeyablePropertyStorageSize(laProp* p);
  21. laAction* laNewAction(char* Name){
  22. laAction* aa=memAcquire(sizeof(laAction));
  23. if(!Name || !Name[0]){ Name="New Action"; }
  24. strSafeSet(&aa->Name,Name);
  25. aa->Length=5; aa->FrameCount=120;
  26. lstAppendItem(&MAIN.Actions,aa);
  27. laNotifyUsers("la.actions");
  28. return aa;
  29. }
  30. laAnimationChannel* laAnimationEnsureChannel(laAction* aa, void* hyper1, laProp* p){
  31. laAnimationChannel* acf=0;
  32. int DataSize=la_GetKeyablePropertyStorageSize(p); if(!DataSize) return 0;
  33. for(laAnimationChannel* ac=aa->Channels.pFirst;ac;ac=ac->Item.pNext){
  34. if(ac->For==hyper1 && ac->Prop==p){ acf=ac; break; }
  35. }
  36. if(acf) return acf;
  37. acf=memAcquire(sizeof(laAnimationChannel));
  38. memAssignRef(acf,&acf->For,hyper1); acf->Prop=p;
  39. acf->DataSize = DataSize;
  40. lstAppendItem(&aa->Channels,acf);
  41. return acf;
  42. }
  43. laAnimationChannel* laAnimationEnsureFrame(laAnimationChannel* ac, int frame){
  44. laAnimationKey* akf=0,*beforeakf=0;
  45. for(laAnimationKey* ak=ac->Keys.pFirst;ak;ak=ak->Item.pNext){
  46. if(ak->At==frame){ akf=ak; break; } if(ak->At>frame){ beforeakf=ak; break; }
  47. }
  48. if(!akf){
  49. akf=memAcquireSimple(sizeof(laAnimationKey)-sizeof(uint64_t)+ac->DataSize);
  50. akf->At=frame;
  51. if(beforeakf){ lstInsertItemBefore(&ac->Keys, akf, beforeakf); }
  52. lstAppendItem(&ac->Keys, akf);
  53. }
  54. return akf;
  55. }
  56. void laAnimationStoreKeyValue(laAnimationChannel* ac, laAnimationKey* ak){
  57. laPropPack PP={0}; laPropStep PS={0};
  58. PS.p=ac->Prop; PS.Type='.'; PS.UseInstance=ac->For; PP.LastPs=&PS; PP.EndInstance=ac->For;
  59. switch(ac->Prop->PropertyType){
  60. case LA_PROP_INT: case LA_PROP_INT | LA_PROP_ARRAY: laGetIntArray(&PP,(int*)&ak->Data);
  61. case LA_PROP_FLOAT: case LA_PROP_FLOAT | LA_PROP_ARRAY: laGetFloatArray(&PP,(real*)&ak->Data);
  62. case LA_PROP_ENUM: case LA_PROP_ENUM | LA_PROP_ARRAY: laGetEnumArray(&PP,(laEnumItem**)&ak->Data);
  63. case LA_PROP_SUB: case LA_PROP_OPERATOR: case LA_PROP_STRING: case LA_PROP_RAW: default: return;
  64. }
  65. }
  66. laAnimationKey* laAnimationInsertKeyFrame(laAction* aa, void* hyper1, laProp* p){
  67. laAnimationChannel* ac=laAnimationEnsureChannel(aa,hyper1,p); if(!ac || !ac->For) return;
  68. int frame=aa->PlayHead/aa->Length*aa->FrameCount;
  69. laAnimationKey* ak=laAnimationEnsureFrame(ac->DataSize,frame);
  70. laAnimationStoreKeyValue(ac,ak);
  71. }
  72. int OPINV_NewAction(laOperator *a, laEvent *e){
  73. laNewAction(0);
  74. return LA_FINISHED;
  75. }
  76. void la_RegisterAnimationResources(){
  77. laPropContainer *pc; laProp *p; laOperatorType *at; laEnumProp *ep;
  78. laCreateOperatorType("LA_new_action", "New Action", "Add a new action",0,0,0,OPINV_NewAction,0,0,0);
  79. }