//| Copyright: (C) 2020-2024 Kevin Larke //| License: GNU GPL version 3.0 or above. See the accompanying LICENSE file. #ifndef cwUI_H #define cwUI_H #include "cwUiDecls.h" namespace cw { namespace ui { typedef handle handle_t; // Callback for application notification. // (e.g. the GUI changed the value of a UI element) typedef rc_t (*uiCallback_t)( void* cbArg, unsigned wsSessId, opId_t opId, unsigned parentAppId, unsigned uuId, unsigned appId, unsigned chanId, const value_t* value ); // Callback with messages for the GUI as JSON strings // { "op":"create", "type":<>, "appId":<>, "parentUuId":<>, "name":<> (type specific fields) } // { "op":""value", "uuid":<> "value":<> } typedef rc_t (*sendCallback_t)( void* cbArg, unsigned wsSessId, const void* msg, unsigned msgByteN ); rc_t create( handle_t& h, sendCallback_t sendCbFunc, void* sendCbArg, uiCallback_t uiCbFunc, void* uiCbArg, const object_t* uiRsrc = nullptr, const appIdMap_t* appIdMapA = nullptr, unsigned appIdMapN = 0, unsigned fmtBufByteN = 4096 ); rc_t destroy( handle_t& h ); rc_t enableCache( handle_t h, unsigned cacheByteCnt=4096 ); rc_t flushCache( handle_t h ); unsigned sessionIdCount(handle_t h); // Count of connected remote UI's const unsigned* sessionIdArray(handle_t h); // Array of 'sessionIdCount()' remote UI id's // A new remote UI was connected rc_t onConnect( handle_t h, unsigned wsSessId ); // A UI was disconnected rc_t onDisconnect( handle_t h, unsigned wsSessId ); // Receive a msg from a remote UI. // // Note that individual messages are delinated with zero termination. // Therefore a message which is not zero terminated is considered // a partial message and will be buffered until the suffix of the message // arrives. rc_t onReceive( handle_t h, unsigned wsSessId, const void* msg, unsigned byteN ); // Locate an element whose parent uuid is 'parentUuId' with a child named 'eleName'. unsigned parentAndNameToAppId( handle_t h, unsigned parentAppId, const char* eleName ); unsigned parentAndNameToUuId( handle_t h, unsigned parentAppId, const char* eleName ); unsigned parentAndAppIdToUuId( handle_t h, unsigned parentAppId, unsigned appId ); const char* findElementName( handle_t h, unsigned uuId ); unsigned findElementAppId( handle_t h, unsigned uuId ); // Return the uuid of the first matching 'eleName' or 'appId'. unsigned findElementUuId( handle_t h, const char* eleName, unsigned chanId = kInvalidId ); unsigned findElementUuId( handle_t h, unsigned appId, unsigned chanId = kInvalidId ); unsigned findElementUuId( handle_t h, unsigned parentUuId, const char* eleName, unsigned chanId = kInvalidId ); unsigned findElementUuId( handle_t h, unsigned parentUuId, unsigned appId, unsigned chanId = kInvalidId ); // Create multiple UI elements from an object_t representation. // The channel id of all elements created from the object will be assigned 'chanId'. // The 'label' string identifies a child wihtin the outer object (e.g. o,fn,text, create( ... uiRsrc, ...)) which should be used to create the element. rc_t createFromObject( handle_t h, const object_t* o, unsigned parentUuId=kInvalidId, unsigned chanId=kInvalidId, const char* label=nullptr); rc_t createFromFile( handle_t h, const char* fn, unsigned parentUuId=kInvalidId, unsigned chanId=kInvalidId); rc_t createFromText( handle_t h, const char* text, unsigned parentUuId=kInvalidId, unsigned chanId=kInvalidId); // This function uses 'label' to locate the child of the internal uiRsrc (passed to 'create()') as the element configuration resource. rc_t createFromRsrc( handle_t h, const char* label, unsigned parentUuId=kInvalidId, unsigned chanId=kInvalidId); // // Create Sincgle UI elements on the UI instance identified by wsSessId. // // uuIdRef: Returns the automatically generated id for this element. // It is unique across all elements associated with this ui::handle. // Note that this id is NOT generated per wsSession, it is only generated // the first time a particular element of this ui::handle is created. // // wsSessId: Identifies a particular instance (websock session) of the UI. // Multiple instances of a UI may exist for a single application instance each will have a unique wsSessId. // Set this value to kInvalidId to create this element on all existing websock sessions. Note that this is // an unusual use since UI elements are usually created when new sessions are connected and therefore // a specific wsSessId is available. // // parentUuId: uuid of parent element that the new element will be a child of. // // eleName: (optional) HTML ele id of the new element. // // appId: (optional) Application id. This is the application variable which this UI element represents. // This id is generally the same across all UI instances. // // clas: (optional) HTML class of the new element // // title: (optional) Visible Text label associated with this element. // rc_t createDiv( handle_t h, unsigned& uuIdRef, unsigned parentUuId, const char* eleName, unsigned appId, unsigned chanId, const char* clas, const char* title ); rc_t createLabel( handle_t h, unsigned& uuIdRef, unsigned parentUuId, const char* eleName, unsigned appId, unsigned chanId, const char* clas, const char* title ); rc_t createButton( handle_t h, unsigned& uuIdRef, unsigned parentUuId, const char* eleName, unsigned appId, unsigned chanId, const char* clas, const char* title ); // Create check: w/o value. The value will be read from the engine via the UI 'echo' event. rc_t createCheck( handle_t h, unsigned& uuIdRef, unsigned parentUuId, const char* eleName, unsigned appId, unsigned chanId, const char* clas, const char* title ); // Create check: w/ value. The value will be sent to the engine as the new value of the associated varaible. rc_t createCheck( handle_t h, unsigned& uuIdRef, unsigned parentUuId, const char* eleName, unsigned appId, unsigned chanId, const char* clas, const char* title, bool value ); rc_t createSelect( handle_t h, unsigned& uuIdRef, unsigned parentUuId, const char* eleName, unsigned appId, unsigned chanId, const char* clas, const char* title ); rc_t createOption( handle_t h, unsigned& uuIdRef, unsigned parentUuId, const char* eleName, unsigned appId, unsigned chanId, const char* clas, const char* title ); rc_t createStrDisplay( handle_t h, unsigned& uuIdRef, unsigned parentUuId, const char* eleName, unsigned appId, unsigned chanId, const char* clas, const char* title ); rc_t createStrDisplay( handle_t h, unsigned& uuIdRef, unsigned parentUuId, const char* eleName, unsigned appId, unsigned chanId, const char* clas, const char* title, const char* value ); rc_t createStr( handle_t h, unsigned& uuIdRef, unsigned parentUuId, const char* eleName, unsigned appId, unsigned chanId, const char* clas, const char* title ); rc_t createStr( handle_t h, unsigned& uuIdRef, unsigned parentUuId, const char* eleName, unsigned appId, unsigned chanId, const char* clas, const char* title, const char* value ); rc_t createNumbDisplay(handle_t h, unsigned& uuIdRef, unsigned parentUuId, const char* eleName, unsigned appId, unsigned chanId, const char* clas, const char* title, unsigned decPl ); rc_t createNumbDisplay(handle_t h, unsigned& uuIdRef, unsigned parentUuId, const char* eleName, unsigned appId, unsigned chanId, const char* clas, const char* title, unsigned decPl, double value ); rc_t createNumb( handle_t h, unsigned& uuIdRef, unsigned parentUuId, const char* eleName, unsigned appId, unsigned chanId, const char* clas, const char* title, double minValue, double maxValue, double stepValue, unsigned decPl ); rc_t createNumb( handle_t h, unsigned& uuIdRef, unsigned parentUuId, const char* eleName, unsigned appId, unsigned chanId, const char* clas, const char* title, double minValue, double maxValue, double stepValue, unsigned decPl, double value ); rc_t createProg( handle_t h, unsigned& uuIdRef, unsigned parentUuId, const char* eleName, unsigned appId, unsigned chanId, const char* clas, const char* title, double minValue, double maxValue ); rc_t createProg( handle_t h, unsigned& uuIdRef, unsigned parentUuId, const char* eleName, unsigned appId, unsigned chanId, const char* clas, const char* title, double minValue, double maxValue, double value ); rc_t createLog( handle_t h, unsigned& uuIdRef, unsigned parentUuId, const char* eleName, unsigned appId, unsigned chanId, const char* clas, const char* title ); rc_t createVList( handle_t h, unsigned& uuIdRef, unsigned parentUuId, const char* eleName, unsigned appId, unsigned chanId, const char* clas, const char* title ); rc_t createHList( handle_t h, unsigned& uuIdRef, unsigned parentUuId, const char* eleName, unsigned appId, unsigned chanId, const char* clas, const char* title ); rc_t setTitle( handle_t h, unsigned uuId, const char* title ); rc_t setNumbRange( handle_t h, unsigned uuId, double minValue, double maxValue, double stepValue, unsigned decPl, double value ); rc_t setProgRange( handle_t h, unsigned uuId, double minValue, double maxValue, double value ); rc_t setLogLine( handle_t h, unsigned uuId, const char* text ); rc_t emptyParent( handle_t h, unsigned uuId ); rc_t setClickable( handle_t h, unsigned uuId, bool clickableFl=true ); rc_t clearClickable( handle_t h, unsigned uuId ); bool isClickable( handle_t h, unsigned uuId ); rc_t setSelect( handle_t h, unsigned uuId, bool enableFl=true ); rc_t clearSelect( handle_t h, unsigned uuId ); bool isSelected( handle_t h, unsigned uuId ); rc_t setVisible( handle_t h, unsigned uuId, bool enableFl=true ); rc_t clearVisible( handle_t h, unsigned uuId ); bool isVisible( handle_t h, unsigned uuId ); rc_t setEnable( handle_t h, unsigned uuId, bool enableFl=true ); rc_t clearEnable( handle_t h, unsigned uuId ); bool isEnabled( handle_t h, unsigned uuId ); rc_t setOrderKey( handle_t h, unsigned uuId, int orderKey ); int getOrderKey( handle_t h, unsigned uuId ); // Scroll the element identified by 'uuId' to the top of the list. // (uuId must identify a list element whose parent is a 'uiList') rc_t setScrollTop( handle_t h, unsigned uuId ); // setBlob() allocates internal memeory and copies the contents of blob[blobByeN] rc_t setBlob( handle_t h, unsigned uuId, const void* blob, unsigned blobByteN ); const void* getBlob( handle_t h, unsigned uuId, unsigned& blobByteN_Ref ); rc_t clearBlob( handle_t h, unsigned uuId ); // Register parent/child/name app id's rc_t registerAppIdMap( handle_t h, const appIdMap_t* map, unsigned mapN ); unsigned elementChildCount( handle_t h, unsigned uuId ); rc_t elementChildUuId( handle_t h, unsigned uuId, unsigned* bufA, unsigned bufN, unsigned& actualN ); unsigned elementPhysChildCount( handle_t h, unsigned uuId ); rc_t elementPhysChildUuId( handle_t h, unsigned uuId, unsigned* bufA, unsigned bufN, unsigned& actualN ); // Release an element an all of it's children. rc_t destroyElement( handle_t h, unsigned uuId ); // Send a value from the application to the UI via a JSON messages. // Set wsSessId to kInvalidId to send to all sessions. rc_t sendValueBool( handle_t h, unsigned uuId, bool value ); rc_t sendValueInt( handle_t h, unsigned uuId, int value ); rc_t sendValueUInt( handle_t h, unsigned uuId, unsigned value ); rc_t sendValueFloat( handle_t h, unsigned uuId, float value ); rc_t sendValueDouble( handle_t h, unsigned uuId, double value ); rc_t sendValueString( handle_t h, unsigned uuId, const char* value ); rc_t sendMsg( handle_t h, const char* msg ); void report( handle_t h ); void realTimeReport( handle_t h ); namespace ws { typedef handle handle_t; typedef struct args_str { const char* physRootDir; const char* dfltPageFn; object_t* uiRsrc; unsigned port; unsigned rcvBufByteN; unsigned xmtBufByteN; unsigned fmtBufByteN; unsigned idleMsgPeriodMs; // min period without messages before an idle message is generated unsigned queueBlkCnt; unsigned queueBlkByteCnt; bool extraLogsFl; // Report the websock LLL_NOTICE logs } args_t; rc_t parseArgs( const object_t& o, args_t& args, const char* object_label="ui" ); rc_t releaseArgs( args_t& args ); rc_t create( handle_t& h, const args_t& args, void* cbArg, uiCallback_t uiCbFunc, const object_t* uiRsrc = nullptr, const appIdMap_t* appIdMapA = nullptr, unsigned appIdMapN = 0, websock::cbFunc_t wsCbFunc = nullptr ); rc_t create( handle_t& h, unsigned port, const char* physRootDir, void* cbArg, uiCallback_t uiCbFunc, const object_t* uiRsrc = nullptr, const appIdMap_t* appIdMapA = nullptr, unsigned appIdMapN = 0, websock::cbFunc_t wsCbFunc = nullptr, const char* dfltPageFn = "index.html", unsigned idleMsgPeriodMs = 50, unsigned rcvBufByteN = 1024, unsigned xmtBufByteN = 1024, unsigned fmtBufByteN = 4096, unsigned queueBlkCnt = 4, unsigned queueBlkByteCnt = 4096, bool extraLogsFl = false ); rc_t destroy( handle_t& h ); // This function should be called periodically to send and receive // queued messages to and from the websocket. // Note that this call may block for up to 'wsTimeOutMs' milliseconds // while waiting for incoming websocket messages. rc_t exec( handle_t h, unsigned wsTimeOutMs ); // This function executes the internal default websock callback function. // It is useful if the user provides a custom websock callback function // and wants to fallback to the default websock->ui interaction. rc_t onReceive( handle_t h, unsigned protocolId, unsigned sessionId, websock::msgTypeId_t msg_type, const void* msg, unsigned byteN ); websock::handle_t websockHandle( handle_t h ); ui::handle_t uiHandle( handle_t h ); void realTimeReport( handle_t h ); } namespace srv { typedef handle handle_t; rc_t create( handle_t& h, const ws::args_t& args, void* cbArg, uiCallback_t uiCbFunc, const appIdMap_t* appIdMapA = nullptr, unsigned appIdMapN = 0, unsigned wsTimeOutMs = 50, websock::cbFunc_t wsCbFunc = nullptr ); rc_t create( handle_t& h, unsigned port, const char* physRootDir, void* cbArg, uiCallback_t uiCbFunc, const object_t* uiRsrc = nullptr, const appIdMap_t* appIdMapA = nullptr, unsigned appIdMapN = 0, unsigned wsTimeOutMs = 50, websock::cbFunc_t wsCbFunc = nullptr, const char* dfltPageFn = "index.html", unsigned idleMsgPeriodMs = 50, unsigned rcvBufByteN = 1024, unsigned xmtBufByteN = 1024, unsigned fmtBufByteN = 4096, unsigned queueBlkCnt = 4, unsigned queueBlkByteCnt = 4096, bool extraLogsFl = false ); rc_t destroy( handle_t& h ); rc_t start( handle_t h ); rc_t stop( handle_t h ); thread::handle_t threadHandle( handle_t h ); websock::handle_t websockHandle( handle_t h ); ui::handle_t uiHandle( handle_t h ); } } } #endif