/* * Part of LaGUI demonstration programs * 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; STRUCTURE(Calculator){ laListHandle Item; laSafeString* Title; laSafeString* ResultString; laListHandle Racks; }; STRUCTURE(CalculatorCollection){ void* base; laListHandle Calculators; Calculator* CurrentCalculator; }; STRUCTURE(CalcRack){ laListItem Item; laListHandle Nodes; }; STRUCTURE(CalcNode){ laListItem Item; int Type; int Gap; laNodeOutSocket* OutA; }; STRUCTURE(CalcOpNode){ CalcNode Base; int Operation; laNodeInSocket* inA; real AVal; laNodeInSocket* inB; real BVal; }; STRUCTURE(CalcMixNode){ CalcOpNode Base; laNodeInSocket* inFactor; real Factor; }; STRUCTURE(CalcNumberNode){ CalcNode Base; int Mode; // Integer/Real int iValue; real rValue; }; STRUCTURE(CalcResultNode){ CalcNode Base; laNodeInSocket* inResult; }; STRUCTURE(CalcRefNode){ CalcNode Base; Calculator* Reference; laNodeInSocket* inResult; }; #define CALC_NODE_GENERIC 0 #define CALC_NODE_NUMBER 1 #define CALC_NODE_ 2 #define CALC_NODE_MIX 3 #define CALC_NODE_RESULT 4 #define CALC_NODE_REF 5 #define CALC__ADD 0 #define CALC__SUB 1 #define CALC__MUL 2 #define CALC__DIV 3 CalculatorCollection* CC=0; laPropContainer* pcNumber,*pcOp,*pcMix,*pcResult,*pcGeneric,*pcRef; laTheme* LightTheme, *DarkTheme; void UiCalcNumberNode(laUiList *uil, laPropPack *This, laPropPack *DetachedProps, laColumn *UNUSED, int context){ laColumn* c=laFirstColumn(uil); laUiItem* b=laBeginRow(uil,c,0,0); laShowHeightAdjuster(uil,c,This,"base.__gap",0); laShowItem(uil,c,This,"mode"); laUiItem* b1=laOnConditionThat(uil,c,laEqual(laPropExpression(This,"mode"),laIntExpression(0)));{ laShowItem(uil,c,This,"value_i"); }laElse(uil,b1);{ laShowItem(uil,c,This,"value_r"); }laEndCondition(uil,b1); laShowSeparator(uil,c)->Expand=1; laShowNodeSocket(uil,c,This,"base.out_a",0); laShowLabel(uil,c,"🤙",0,0)->Flags|=LA_TEXT_ALIGN_RIGHT; laEndRow(uil,b); } void UiCalcOpNode(laUiList *uil, laPropPack *This, laPropPack *DetachedProps, laColumn *UNUSED, int context){ laColumn* c=laFirstColumn(uil); laUiItem* b=laBeginRow(uil,c,0,0); laShowHeightAdjuster(uil,c,This,"base.__gap",0); laShowNodeSocket(uil,c,This,"in_a",0); laUiItem* b1=laOnConditionThat(uil,c,laNot(laPropExpression(This,"in_a.source")));{ laShowItem(uil,c,This,"val_a"); }laEndCondition(uil,b1); laShowNodeSocket(uil,c,This,"in_b",0); b1=laOnConditionThat(uil,c,laNot(laPropExpression(This,"in_b.source")));{ laShowItem(uil,c,This,"val_b"); }laEndCondition(uil,b1); laShowItem(uil,c,This,"operation"); laShowSeparator(uil,c)->Expand=1; laShowNodeSocket(uil,c,This,"base.out_a",0); laShowLabel(uil,c,"🤔",0,0)->Flags|=LA_TEXT_ALIGN_RIGHT; laEndRow(uil,b); } void UiCalcMixNode(laUiList *uil, laPropPack *This, laPropPack *DetachedProps, laColumn *UNUSED, int context){ laColumn* c=laFirstColumn(uil); laUiItem* b=laBeginRow(uil,c,0,0); laShowHeightAdjuster(uil,c,This,"base.base.__gap",0); laShowNodeSocket(uil,c,This,"base.in_a",0); laUiItem* b1=laOnConditionThat(uil,c,laNot(laPropExpression(This,"base.in_a.source")));{ laShowItem(uil,c,This,"base.val_a"); }laEndCondition(uil,b1); laShowNodeSocket(uil,c,This,"base.in_b",0); b1=laOnConditionThat(uil,c,laNot(laPropExpression(This,"base.in_b.source")));{ laShowItem(uil,c,This,"base.val_b"); }laEndCondition(uil,b1); laShowItem(uil,c,This,"in_factor"); b1=laOnConditionThat(uil,c,laNot(laPropExpression(This,"in_factor.source")));{ laShowItem(uil,c,This,"factor"); }laEndCondition(uil,b1); laShowSeparator(uil,c)->Expand=1; laShowNodeSocket(uil,c,This,"base.base.out_a",0); laShowLabel(uil,c,"🤝",0,0)->Flags|=LA_TEXT_ALIGN_RIGHT; laEndRow(uil,b); } void UiCalcResultNode(laUiList *uil, laPropPack *This, laPropPack *DetachedProps, laColumn *UNUSED, int context){ laColumn* c=laFirstColumn(uil); laUiItem* b=laBeginRow(uil,c,0,0); laShowHeightAdjuster(uil,c,This,"base.__gap",0); laShowNodeSocket(uil,c,This,"in_result",0); laShowSeparator(uil,c)->Expand=1; laShowLabel(uil,c,"😋",0,0)->Flags|=LA_TEXT_ALIGN_RIGHT; laEndRow(uil,b); } void UiCalcRefNode(laUiList *uil, laPropPack *This, laPropPack *DetachedProps, laColumn *UNUSED, int context){ laColumn* c=laFirstColumn(uil); laUiItem* b=laBeginRow(uil,c,0,0); laShowHeightAdjuster(uil,c,This,"base.__gap",0); laShowNodeSocket(uil,c,This,"in_result",0); laShowSeparator(uil,c)->Expand=1; laShowLabel(uil,c,"😋",0,0)->Flags|=LA_TEXT_ALIGN_RIGHT; laEndRow(uil,b); laShowItemFull(uil,c,This,"ref",LA_WIDGET_COLLECTION_SELECTOR,0,laui_IdentifierOnly,0); } void UiRack(laUiList *uil, laPropPack *This, laPropPack *DetachedProps, laColumn *UNUSED, int context){ laColumn* c=laFirstColumn(uil); laShowItem(uil,c,This,"nodes")->Flags|=LA_UI_FLAGS_NO_DECAL; laShowItem(uil,c,This,"add_node"); } void UiCalculator(laUiList *uil, laPropPack *This, laPropPack *DetachedProps, laColumn *UNUSED, int context){ laColumn* c=laFirstColumn(uil); laShowItem(uil,c,This,"title"); laUiItem*b=laBeginRow(uil,c,0,0); laShowItemFull(uil,c,This,"add_rack",0,"position=head;",0,0)->Flags|=LA_UI_FLAGS_ICON; laUiItem* ui=laShowLabel(uil,c,"Racks",0,0); ui->Flags|=LA_TEXT_ALIGN_CENTER; ui->Expand=1; laShowItemFull(uil,c,This,"add_rack",0,0,0,0)->Flags|=LA_UI_FLAGS_ICON; laEndRow(uil,b); laUiItem* g=laMakeGroup(uil,c,"Racks",0);{ g->Flags|=LA_UI_FLAGS_NO_GAP|LA_UI_FLAGS_NO_DECAL|LA_UI_FLAGS_NODE_CONTAINER; laUiList* gu=g->Page; laColumn* gc=laFirstColumn(gu); gu->AllowScale=1; gu->HeightCoeff=-3; g->State=LA_UI_ACTIVE; laUiItem* hui=laShowItem(gu,gc,This,"racks"); hui->Expand=15; hui->Flags|=LA_UI_FLAGS_NO_GAP|LA_UI_FLAGS_NO_DECAL; } laShowItem(uil,c,This,"result"); } void CalcPanel(laUiList *uil, laPropPack *This, laPropPack *DetachedProps, laColumn *UNUSED, int context){ laColumn* c=laFirstColumn(uil); laColumn* cl,*cr; laSplitColumn(uil,c,0.5); cl=laLeftColumn(c,0); cr=laRightColumn(c,0); laShowLabel(uil,c,"You can use \"Data\" panel to see lagui-property structure.",0,0)->Flags|=LA_TEXT_LINE_WRAP; laShowItemFull(uil,cl,0,"calc.current",LA_WIDGET_COLLECTION_SELECTOR,0,laui_IdentifierOnly,0); laShowItem(uil,cr,0,"CALC_add_calculator"); laShowItemFull(uil,c,0,"calc.current",LA_WIDGET_COLLECTION_SINGLE,0,0,0)->Flags|=LA_UI_COLLECTION_NO_HIGHLIGHT; } void CalcPanelRegular(laUiList *uil, laPropPack *This, laPropPack *DetachedProps, laColumn *UNUSED, int context){ laColumn* c=laFirstColumn(uil); laShowItemFull(uil,c,0,"calc.current",0,0,laui_SubPropInfoDefault,1); } int INV_AddCalculator(laOperator* a, laEvent* e){ Calculator* c=memAcquireHyper(sizeof(Calculator)); strSafeSet(&c->Title, "New Calculator"); lstAppendItem(&CC->Calculators,c); memAssignRef(CC,&CC->CurrentCalculator,c); laRecordAndPushProp(0, "calc"); laNotifyUsers("calc"); laPrintDBInstInfo(); return LA_FINISHED; } int INV_AddRack(laOperator* a, laEvent* e){ Calculator* c=a->This?a->This->EndInstance:CC->CurrentCalculator; if(!c) return LA_FINISHED; CalcRack* cr=memAcquire(sizeof(CalcRack)); if(strSame(strGetArgumentString(a->ExtraInstructionsP,"position"),"head")){ lstPushItem(&c->Racks,cr); } else lstAppendItem(&c->Racks,cr); laRecordAndPushProp(0, "calc"); laNotifyUsers("calc"); laPrintDBInstInfo(); return LA_FINISHED; } void AddNodesPanel(laUiList *uil, laPropPack *This, laPropPack *DetachedProps, laColumn *UNUSED, int context){ laColumn* c=laFirstColumn(uil); laShowLabel(uil,c,"Select node type:",0,0); laShowItemFull(uil,c,0,"LA_confirm",0,"icon=🤙;text=Number;feedback=NUMBER;",0,0); laShowItemFull(uil,c,0,"LA_confirm",0,"icon=🤔;text=Calculate;feedback=CALC;",0,0); laShowItemFull(uil,c,0,"LA_confirm",0,"icon=🤝;text=Mix;feedback=MIX;",0,0); laShowItemFull(uil,c,0,"LA_confirm",0,"icon=😋;text=Result;feedback=RESULT;",0,0); laShowItemFull(uil,c,0,"LA_confirm",0,"icon=🡬;text=Reference;feedback=REF;",0,0); } int INV_AddNode_(laOperator* a, laEvent* e){ CalcRack* cr=a->This?a->This->EndInstance:0; if(!cr) return LA_FINISHED; laEnableOperatorPanel(a, a->This, e->x,e->y,0,0,0,0,0,0,0,0,0,0,e); return LA_RUNNING; } int MOD_AddNode_(laOperator* a, laEvent* e){ if(!a->This){ return LA_FINISHED; } CalcRack* cr=a->This->EndInstance; if(a->ConfirmData){ char* str; CalcNode* n=0; if(strSame(a->ConfirmData->StrData, "NUMBER")){ n=memAcquire(sizeof(CalcNumberNode)); CalcNumberNode* cn=n; n->Type=CALC_NODE_NUMBER; cn->Base.OutA=laCreateOutSocket(cn, "A", 0); }elif(strSame(a->ConfirmData->StrData, "CALC")){ n=memAcquire(sizeof(CalcOpNode)); CalcOpNode* cn=n; n->Type=CALC_NODE_; cn->Base.OutA=laCreateOutSocket(cn, "Out", 0); cn->inA=laCreateInSocket("A", 0); cn->inB=laCreateInSocket("B", 0); }elif(strSame(a->ConfirmData->StrData, "MIX")){ n=memAcquire(sizeof(CalcMixNode)); CalcMixNode*cn=n; n->Type=CALC_NODE_MIX; cn->Base.Base.OutA=laCreateOutSocket(cn, "Out", 0); cn->Base.inA=laCreateInSocket("A", 0); cn->Base.inB=laCreateInSocket("B", 0); cn->inFactor=laCreateInSocket("Factor", 0); }elif(strSame(a->ConfirmData->StrData, "RESULT")){ n=memAcquire(sizeof(CalcResultNode)); CalcResultNode*cn=n; n->Type=CALC_NODE_RESULT; cn->Base.OutA=laCreateOutSocket(cn, "Out", 0); cn->inResult=laCreateInSocket("Result", 0); }elif(strSame(a->ConfirmData->StrData, "REF")){ n=memAcquire(sizeof(CalcRefNode)); CalcRefNode*cn=n; n->Type=CALC_NODE_REF; cn->Base.OutA=laCreateOutSocket(cn, "Out", 0); cn->inResult=laCreateInSocket("Result", 0); } if(n){ lstAppendItem(&cr->Nodes,n); laRecordAndPushProp(0, "calc"); laNotifyUsers("calc"); laPrintDBInstInfo(); } return LA_FINISHED_PASS; } return LA_RUNNING; } laPropContainer* CalcGetNodeType(CalcNode* n){ switch(n->Type){ case CALC_NODE_NUMBER: return pcNumber; case CALC_NODE_: return pcOp; case CALC_NODE_MIX: return pcMix; case CALC_NODE_RESULT: return pcResult; case CALC_NODE_REF: return pcRef; default: case CALC_NODE_GENERIC: return pcGeneric; } } void* CalcGetCollection(void* unused,void* unused1){ return CC; } void *CalcGetFirstCalculator(void* unusedcc, void* unused){ return CC->Calculators.pFirst; } laBoxedTheme* CalcGetTheme(CalcRack* rack_unused, CalcNode* n){ if(n->Type == CALC_NODE_MIX) return (MAIN.CurrentTheme==LightTheme?DarkTheme:LightTheme); return 0; } int CalcGetGap(CalcRack* rack_unused, CalcNode* n){ return n->Gap; } void CalcSetGap(CalcNode* n, int gap){ if(gap<0){ int done=0; CalcNode* nn=n; while(nn){ if(nn->Gap>0){ nn->Gap--; done=1; break; } nn=nn->Item.pPrev; } if(done){ nn=n->Item.pNext; while(nn){ if(nn->Gap>0){ nn->Gap++; break; } nn=nn->Item.pNext; } } } if(gap>0){ n->Gap+=gap; CalcNode* nn=n->Item.pNext; while(nn){ if(nn->Gap>0){ nn->Gap--; break; } nn=nn->Item.pNext; } } } int RegisterCalculator(){ LightTheme=laGetTheme("Classic Light"); DarkTheme=laGetTheme("Classic Dark"); CC=memAcquire(sizeof(CalculatorCollection)); laRegisterUiTemplate("panel_calc", "Calculator", CalcPanel, 0, 0,0, 0,0,0); laRegisterUiTemplate("panel_calc_regular", "Data", CalcPanelRegular, 0, 0,0, 0,0,0); laCreateOperatorType("CALC_add_calculator", "Add Calculator", "Add a calculator", 0,0,0,INV_AddCalculator,0,'+',0); laCreateOperatorType("CALC_add_rack", "Add Rack", "Add a rack into the calculator", 0,0,0,INV_AddRack,0,'+',0); laCreateOperatorType("CALC_add_node", "Add Node", "Add a fruit into the basket or bundle", 0,0,0,INV_AddNode_,MOD_AddNode_,'+',0)->UiDefine=AddNodesPanel; laPropContainer* pc=laDefineRoot(); laAddSubGroup(pc, "calc", "Calculator Collections", "The collection of calculators", "calc_collection",0,0,0,-1,CalcGetCollection,0,0,0,0,0,0,LA_UDF_SINGLE|LA_UDF_LOCAL); laProp*p; pc=laAddPropertyContainer("calc_collection", "Calculator Collection", "Collection of calculators", 0, CalcPanel, sizeof(CalculatorCollection), 0, 0, 1|LA_UDF_LOCAL|LA_UDF_SINGLE); laAddSubGroup(pc, "calculators", "Calculators","Calculators","calculator",0,0,0,offsetof(CalculatorCollection, CurrentCalculator),0,0,0,0,0,0,offsetof(CalculatorCollection,Calculators),0); laAddSubGroup(pc, "current", "Current Calculator","Current calculator","calculator",0,0,0,offsetof(CalculatorCollection,CurrentCalculator),0,0,0,0,0,0,offsetof(CalculatorCollection,Calculators),LA_UDF_REFER); laAddOperatorProperty(pc,"add_calculator", "Add Calculator", "Add a calculator", "CALC_add_calculator", 0, 0); pc=laAddPropertyContainer("calculator", "Calculator", "A node-based calculator", 0, UiCalculator, sizeof(Calculator), 0, 0, 2); laAddStringProperty(pc,"title","Title","Name of the calculator",0,0,0,0,1,offsetof(Calculator,Title),0,0,0,0,LA_AS_IDENTIFIER); laAddStringProperty(pc,"result","Result","Result produced by the calculator",0,0,0,0,1,offsetof(Calculator,ResultString),0,0,0,0,0); laAddSubGroup(pc, "racks", "Racks","Node racks of this calculator","calc_rack",0,0,0,-1,0,0,0,0,0,0,offsetof(Calculator,Racks),0); laAddOperatorProperty(pc,"add_rack", "Add Rack", "Add a rack into the calculator", "CALC_add_rack", 0, 0); pc=laAddPropertyContainer("calc_rack", "Rack", "A node rack", 0, UiRack, sizeof(CalcRack), 0, 0, 1); p= laAddSubGroup(pc, "nodes", "Nodes","Nodes on this rack","calc_node",CalcGetNodeType,0,0,-1,0,0,0,0,0,0,offsetof(CalcRack,Nodes),0); laSubGroupExtraFunctions(p,0,0,CalcGetTheme,CalcGetGap,0); laAddOperatorProperty(pc,"add_node", "Add Node", "Add a node", "CALC_add_node", 0, 0); pcGeneric=pc=laAddPropertyContainer("calc_node", "Node", "A calculator node", 0, 0, sizeof(CalcNode), 0, 0, 1); laAddIntProperty(pc,"__gap", "Gap", "Gap of the node", 0,0,0,0,0,0,0,0,offsetof(CalcNode,Gap),0,CalcSetGap,0,0,0,0,0,0,0,0,0); p=laAddEnumProperty(pc,"type","Type","Type",0,0,0,0,0,offsetof(CalcNode,Type),0,0,0,0,0,0,0,0,0,LA_AS_IDENTIFIER|LA_READ_ONLY); laAddEnumItemAs(p,"GENERIC","Generic","Generic", CALC_NODE_GENERIC, 0); laAddEnumItemAs(p,"NUMBER","Number","Number", CALC_NODE_NUMBER, 0); laAddEnumItemAs(p,"","Op","Op", CALC_NODE_, 0); laAddEnumItemAs(p,"MIX","Mix","Mix", CALC_NODE_MIX, 0); laAddEnumItemAs(p,"RESULT","Result","Result", CALC_NODE_RESULT, 0); laAddEnumItemAs(p,"REF","Reference","Reference", CALC_NODE_REF, 0); laAddSubGroup(pc, "out_a", "Out A","Out A","la_out_socket",0,0,0,offsetof(CalcNode,OutA),0,0,0,0,0,0,0,LA_UDF_SINGLE); pcNumber=pc=laAddPropertyContainer("calc_number_node", "Number Node", "A node that outputs a constant number", 0, UiCalcNumberNode, sizeof(CalcNumberNode), 0, 0, 1); laAddSubGroup(pc, "base", "Base","Base","calc_node",0,0,0,0,0,0,0,0,0,0,0,LA_UDF_LOCAL); laAddIntProperty(pc,"value_i", "Int Value", "Integer value", 0,0,0,0,0,0,0,0,offsetof(CalcNumberNode,iValue),0,0,0,0,0,0,0,0,0,0,0); laAddFloatProperty(pc,"value_r", "Real Value", "Real value", 0,0,0,0,0,0,0,0,offsetof(CalcNumberNode,rValue),0,0,0,0,0,0,0,0,0,0,0); p=laAddEnumProperty(pc,"mode","Mode","Number mode",0,0,0,0,0,offsetof(CalcNumberNode,Mode),0,0,0,0,0,0,0,0,0,0); laAddEnumItemAs(p,"INT","Integer","Integer", 0, 0); laAddEnumItemAs(p,"REAL","Real","Real", 1, 0); pcOp=pc=laAddPropertyContainer("calc_op_node", "Op Node", "A node that does an operation between two values", 0, UiCalcOpNode, sizeof(CalcOpNode), 0, 0, 1); laAddSubGroup(pc, "base", "Base","Base","calc_node",0,0,0,0,0,0,0,0,0,0,0,LA_UDF_LOCAL); p=laAddEnumProperty(pc,"operation","Operation","Operation on two values",0,0,0,0,0,offsetof(CalcOpNode,Operation),0,0,0,0,0,0,0,0,0,0); laAddEnumItemAs(p,"ADD","Add","A + B", CALC__ADD,0); laAddEnumItemAs(p,"SUB","Subtract","A - B", CALC__SUB,0); laAddEnumItemAs(p,"MUL","Multiply","A * B", CALC__MUL,0); laAddEnumItemAs(p,"DIV","Divide","A / B", CALC__DIV,0); laAddSubGroup(pc, "in_a", "A","Input value A","la_in_socket",0,0,0,offsetof(CalcOpNode,inA),0,0,0,0,0,0,0,LA_UDF_SINGLE); laAddSubGroup(pc, "in_b", "B","Input value B","la_in_socket",0,0,0,offsetof(CalcOpNode,inB),0,0,0,0,0,0,0,LA_UDF_SINGLE); laAddFloatProperty(pc,"val_a", "A", "Internal value A", 0,0,0,0,0,0,0,0,offsetof(CalcOpNode,AVal),0,0,0,0,0,0,0,0,0,0,0); laAddFloatProperty(pc,"val_b", "B", "Internal value B", 0,0,0,0,0,0,0,0,offsetof(CalcOpNode,BVal),0,0,0,0,0,0,0,0,0,0,0); pcMix=pc=laAddPropertyContainer("calc_mix_node", "Mix Node", "A node that mixes two values", 0, UiCalcMixNode, sizeof(CalcMixNode), 0, 0, 1); laAddSubGroup(pc, "base", "Base","Base","calc_op_node",0,0,0,0,0,0,0,0,0,0,0,LA_UDF_LOCAL); laAddSubGroup(pc, "in_factor", "Factor","Input factor","la_in_socket",0,0,0,offsetof(CalcMixNode,inFactor),0,0,0,0,0,0,0,LA_UDF_SINGLE); laAddFloatProperty(pc,"factor", "Factor", "Internal factor", 0,0,0,0,0,0,0,0,offsetof(CalcMixNode,Factor),0,0,0,0,0,0,0,0,0,0,0); pcResult=pc=laAddPropertyContainer("calc_result_node", "Result Node", "A node that records the result", 0, UiCalcResultNode, sizeof(CalcResultNode), 0, 0, 1); laAddSubGroup(pc, "base", "Base","Base","calc_node",0,0,0,0,0,0,0,0,0,0,0,LA_UDF_LOCAL); laAddSubGroup(pc, "in_result", "Result","Input result","la_in_socket",0,0,0,offsetof(CalcResultNode,inResult),0,0,0,0,0,0,0,LA_UDF_SINGLE); pcRef=pc=laAddPropertyContainer("calc_ref_node", "Reference Node", "A node that references other calculators", 0, UiCalcRefNode, sizeof(CalcRefNode), 0, 0, 1); laAddSubGroup(pc, "base", "Base","Base","calc_node",0,0,0,0,0,0,0,0,0,0,0,LA_UDF_LOCAL); laAddSubGroup(pc, "ref", "Reference","Referenced calculator","calculator",0,0,0,offsetof(CalcRefNode,Reference),CalcGetFirstCalculator,0,laget_ListNext,0,0,0,0,LA_UDF_REFER); laAddSubGroup(pc, "in_result", "Result","Input result","la_in_socket",0,0,0,offsetof(CalcRefNode,inResult),0,0,0,0,0,0,0,LA_UDF_SINGLE); laSaveProp("calc"); } int main(int argc, char *argv[]){ laGetReady(); RegisterCalculator(); laRefreshUDFRegistries(); // Use this to save and load preference when exit and during start up // laEnsureUserPreferences(); laAddRootDBInst("calc"); laWindow* w = laDesignWindow(-1,-1,600,600); laLayout* l = laDesignLayout(w, "Settings Layout"); laBlock* b = l->FirstBlock; laPanel* p=laCreatePanel(b, "LAUI_user_preferences"); l = laDesignLayout(w, "Nodes list"); b = l->FirstBlock; p=laCreatePanel(b, "panel_calc_help"); p=laCreatePanel(b, "panel_calc_regular"); p=laCreatePanel(b, "panel_calc"); laStartWindow(w); laMainLoop(); }