cwUi.h/cpp : Removed use of 'wsSessId' from 'createXXX()' calls, and added 'chanId' to 'createXXX()' calls.

Added 'click' event, 'clickable' and 'select' properties and associated setters/getters.
This commit is contained in:
kevin 2021-11-03 11:03:30 -04:00
parent 5ab42df103
commit dce46bd419
7 changed files with 422 additions and 215 deletions

410
cwUi.cpp
View File

@ -12,13 +12,14 @@
#include "cwUi.h" #include "cwUi.h"
#define UI_CLICKABLE_LABEL "clickable"
#define UI_SELECT_LABEL "select"
namespace cw namespace cw
{ {
namespace ui namespace ui
{ {
typedef struct appIdMapRecd_str typedef struct appIdMapRecd_str
{ {
struct appIdMapRecd_str* link; struct appIdMapRecd_str* link;
@ -33,9 +34,9 @@ namespace cw
struct ele_str* parent; // pointer to parent ele - or nullptr if this ele is attached to the root ui ele struct ele_str* parent; // pointer to parent ele - or nullptr if this ele is attached to the root ui ele
unsigned uuId; // UI unique id - automatically generated and unique among all elements that are part of this ui_t object. unsigned uuId; // UI unique id - automatically generated and unique among all elements that are part of this ui_t object.
unsigned appId; // application assigned id - application assigned id unsigned appId; // application assigned id - application assigned id
unsigned chanId; //
char* eleName; // javascript id char* eleName; // javascript id
object_t* attr; // attribute object object_t* attr; // attribute object
} ele_t; } ele_t;
typedef struct ui_str typedef struct ui_str
@ -182,33 +183,6 @@ namespace cw
return nullptr; return nullptr;
} }
/*
// Given a parent UuId and a eleName find the associated ele
ele_t* _parentUuId_EleName_ToEle( ui_t* p, unsigned parentUuId, const char* eleName, bool errorFl=true )
{
// if we are looking for the root
if( (parentUuId==kRootUuId || parentUuId == kInvalidId) && textCompare(eleName,"uiDivId")==0 )
{
for(unsigned i=0; i<p->eleN; ++i)
if( p->eleA[i]->parent==nullptr && p->eleA[i]->uuId==kRootUuId)
return p->eleA[i];
}
else // we are looking for an elment which is not the root
{
for(unsigned i=0; i<p->eleN; ++i)
if( ((p->eleA[i]->parent==nullptr && parentUuId == kRootUuId) || (p->eleA[i]->parent != nullptr && parentUuId == p->eleA[i]->parent->uuId)) && (textCompare(p->eleA[i]->eleName,eleName) == 0))
return p->eleA[i];
}
if( errorFl )
cwLogError(kInvalidIdRC,"The element with parent uuid:%i and eleName:%s is not found.",parentUuId,eleName);
return nullptr;
}
*/
unsigned _findElementUuId( ui_t* p, const char* eleName ) unsigned _findElementUuId( ui_t* p, const char* eleName )
{ {
for(unsigned i=0; i<p->eleN; ++i) for(unsigned i=0; i<p->eleN; ++i)
@ -259,6 +233,47 @@ namespace cw
} }
// terminating condition for format_attributes()
void _create_attributes( ele_t* e )
{ }
template<typename T, typename... ARGS>
void _create_attributes(ele_t* e, const char* label, T value, ARGS&&... args)
{
e->attr->insert_pair(label,value);
_create_attributes(e,std::forward<ARGS>(args)...);
}
bool _has_attribute( ele_t* e, const char* label )
{ return e->attr->find_child(label) != nullptr; }
bool _get_attribute_bool( ele_t* e, const char* label )
{
bool value = false;
const object_t* pair_value;
if((pair_value = e->attr->find(label)) == nullptr )
return false;
pair_value->value(value);
return value;
}
rc_t _set_attribute_bool( ele_t* e, const char* label, bool value )
{
object_t* pair_value;
if((pair_value = e->attr->find(label)) == nullptr )
_create_attributes(e,label,value);
else
pair_value->set_value(value);
return kOkRC;
}
// Convert the ele_t 'attr' object into the attributes for a JSON message. // Convert the ele_t 'attr' object into the attributes for a JSON message.
unsigned _format_attributes( char* buf, unsigned n, unsigned i, ele_t* ele ) unsigned _format_attributes( char* buf, unsigned n, unsigned i, ele_t* ele )
{ {
@ -333,13 +348,14 @@ namespace cw
// Create the base element record. The attributes mut be filled in by the calling function. // Create the base element record. The attributes mut be filled in by the calling function.
// Note that if 'appId' is kInvalidId then this function will attempt to lookup the appId in p->appIdMap[]. // Note that if 'appId' is kInvalidId then this function will attempt to lookup the appId in p->appIdMap[].
ele_t* _createBaseEle( ui_t* p, ele_t* parent, unsigned appId, const char* eleName, const char* eleTypeStr=nullptr, const char* eleClass=nullptr, const char* eleTitle=nullptr ) ele_t* _createBaseEle( ui_t* p, ele_t* parent, unsigned appId, unsigned chanId, const char* eleName, const char* eleTypeStr=nullptr, const char* eleClass=nullptr, const char* eleTitle=nullptr )
{ {
ele_t* e = mem::allocZ<ele_t>(); ele_t* e = mem::allocZ<ele_t>();
e->parent = parent; e->parent = parent;
e->uuId = p->eleN; e->uuId = p->eleN;
e->appId = appId; e->appId = appId;
e->chanId = chanId;
e->eleName = eleName==nullptr ? nullptr : mem::duplStr(eleName); e->eleName = eleName==nullptr ? nullptr : mem::duplStr(eleName);
e->attr = newDictObject(); e->attr = newDictObject();
@ -389,21 +405,9 @@ namespace cw
} }
// terminating condition for format_attributes()
void create_attributes( ele_t* e )
{ }
template<typename T, typename... ARGS>
void create_attributes(ele_t* e, const char* label, T value, ARGS&&... args)
{
e->attr->insert_pair(label,value);
create_attributes(e,std::forward<ARGS>(args)...);
}
template< typename... ARGS> template< typename... ARGS>
rc_t _createOneEle( ui_t* p, unsigned& uuIdRef, const char* eleTypeStr, unsigned wsSessId, unsigned parentUuId, const char* eleName, unsigned appId, const char* clas, const char* title, ARGS&&... args ) rc_t _createOneEle( ui_t* p, unsigned& uuIdRef, const char* eleTypeStr, unsigned wsSessId, unsigned parentUuId, const char* eleName, unsigned appId, unsigned chanId, const char* clas, const char* title, ARGS&&... args )
{ {
rc_t rc = kOkRC; rc_t rc = kOkRC;
ele_t* newEle = nullptr; ele_t* newEle = nullptr;
@ -419,10 +423,10 @@ namespace cw
return cwLogError( kInvalidArgRC, "Unable to locate the parent element (id:%i).", parentUuId ); return cwLogError( kInvalidArgRC, "Unable to locate the parent element (id:%i).", parentUuId );
// create the base element // create the base element
newEle = _createBaseEle(p, parentEle, appId, eleName, eleTypeStr, clas, title ); newEle = _createBaseEle(p, parentEle, appId, chanId, eleName, eleTypeStr, clas, title );
// create the attributes // create the attributes
create_attributes(newEle, std::forward<ARGS>(args)...); _create_attributes(newEle, std::forward<ARGS>(args)...);
uuIdRef = newEle->uuId; uuIdRef = newEle->uuId;
@ -448,9 +452,9 @@ namespace cw
return divAliasFl; return divAliasFl;
} }
rc_t _createElementsFromChildList( ui_t* p, const object_t* po, unsigned wsSessId, ele_t* parentEle ); rc_t _createElementsFromChildList( ui_t* p, const object_t* po, unsigned wsSessId, ele_t* parentEle, unsigned chanId );
rc_t _createEleFromRsrsc( ui_t* p, ele_t* parentEle, const char* eleType, const object_t* srcObj, unsigned wsSessId ) rc_t _createEleFromRsrsc( ui_t* p, ele_t* parentEle, const char* eleType, unsigned chanId, const object_t* srcObj, unsigned wsSessId )
{ {
rc_t rc = kOkRC; rc_t rc = kOkRC;
object_t* co = nullptr; object_t* co = nullptr;
@ -463,7 +467,7 @@ namespace cw
return cwLogError(kSyntaxErrorRC,"All ui element resource records must be dictionaries."); return cwLogError(kSyntaxErrorRC,"All ui element resource records must be dictionaries.");
// if this object has a 'children' list then unlink it and save it for later // if this object has a 'children' list then unlink it and save it for later
if((co = o->find("children", kNoRecurseFl | kOptionalFl)) != nullptr ) if((co = o->find("children", kOptionalFl)) != nullptr )
{ {
co = co->parent; co = co->parent;
co->unlink(); co->unlink();
@ -472,7 +476,7 @@ namespace cw
divAliasFl = _is_div_type(eleType); divAliasFl = _is_div_type(eleType);
// get the ui ele name // get the ui ele name
if((rc = o->get("name",eleName, cw::kNoRecurseFl | cw::kOptionalFl)) != kOkRC ) if((rc = o->get("name",eleName, cw::kOptionalFl)) != kOkRC )
{ {
// div's and titles don't need a 'name' // div's and titles don't need a 'name'
if( rc == kLabelNotFoundRC && (divAliasFl || textCompare(eleType,"label")==0) ) if( rc == kLabelNotFoundRC && (divAliasFl || textCompare(eleType,"label")==0) )
@ -486,7 +490,7 @@ namespace cw
} }
// get or create the ele record to associate with this ele // get or create the ele record to associate with this ele
if((ele = _createBaseEle(p, parentEle, kInvalidId, eleName, eleType, nullptr, nullptr)) == nullptr ) if((ele = _createBaseEle(p, parentEle, kInvalidId, chanId, eleName, eleType, nullptr, nullptr)) == nullptr )
{ {
rc = cwLogError(kOpFailRC,"The local element '%s' could not be created.",cwStringNullGuard(eleName)); rc = cwLogError(kOpFailRC,"The local element '%s' could not be created.",cwStringNullGuard(eleName));
goto errLabel; goto errLabel;
@ -495,17 +499,27 @@ namespace cw
if( !divAliasFl ) if( !divAliasFl )
{ {
unsigned childN = o->child_count();
unsigned child_idx = 0;
// transfer the attributes of this resource object to ele->attr // transfer the attributes of this resource object to ele->attr
for(unsigned i=0; i<o->child_count(); ++i) for(unsigned i=0; i<childN; ++i)
{ {
object_t* child = o->child_ele(i); object_t* child = o->child_ele(child_idx);
const char* pair_label = child->pair_label(); const char* pair_label = child->pair_label();
//if( textCompare(eleType,"list")==0 )
// printf("%i list: %s %i\n",i,pair_label,o->child_count());
if( textCompare(pair_label,"name") != 0 && _is_div_type(pair_label)==false ) if( textCompare(pair_label,"name") != 0 && _is_div_type(pair_label)==false )
{ {
child->unlink(); child->unlink();
ele->attr->append_child(child); ele->attr->append_child(child);
} }
else
{
child_idx += 1;
}
} }
} }
@ -517,7 +531,7 @@ namespace cw
// Note that 'div's need not have an explicit 'children' node. // Note that 'div's need not have an explicit 'children' node.
// Any child node of a 'div' with a dictionary as a value is a child control. // Any child node of a 'div' with a dictionary as a value is a child control.
const object_t* childL = co!=nullptr ? co->pair_value() : srcObj; const object_t* childL = co!=nullptr ? co->pair_value() : srcObj;
rc = _createElementsFromChildList(p, childL, wsSessId, ele ); rc = _createElementsFromChildList(p, childL, wsSessId, ele, chanId );
} }
errLabel: errLabel:
@ -534,7 +548,7 @@ namespace cw
// 'od' is an object dictionary where each pair in the dictionary has // 'od' is an object dictionary where each pair in the dictionary has
// the form: 'eleType':{ <object> } // the form: 'eleType':{ <object> }
rc_t _createElementsFromChildList( ui_t* p, const object_t* po, unsigned wsSessId, ele_t* parentEle ) rc_t _createElementsFromChildList( ui_t* p, const object_t* po, unsigned wsSessId, ele_t* parentEle, unsigned chanId )
{ {
rc_t rc = kOkRC; rc_t rc = kOkRC;
@ -553,7 +567,7 @@ namespace cw
// skip pairs whose value is not a dict // skip pairs whose value is not a dict
if( o->pair_value()->is_dict() ) if( o->pair_value()->is_dict() )
{ {
if((rc = _createEleFromRsrsc(p, parentEle, o->pair_label(), o->pair_value(), wsSessId )) != kOkRC ) if((rc = _createEleFromRsrsc(p, parentEle, o->pair_label(), chanId, o->pair_value(), wsSessId )) != kOkRC )
return rc; return rc;
} }
} }
@ -563,7 +577,7 @@ namespace cw
// This functions assumes that the cfg object 'o' contains a field named: 'parent' // This functions assumes that the cfg object 'o' contains a field named: 'parent'
// which contains the element name of the parent node. // which contains the element name of the parent node.
rc_t _createFromObj( ui_t* p, const object_t* o, unsigned wsSessId, unsigned parentUuId ) rc_t _createFromObj( ui_t* p, const object_t* o, unsigned wsSessId, unsigned parentUuId, unsigned chanId )
{ {
rc_t rc = kOkRC; rc_t rc = kOkRC;
const object_t* po = nullptr; const object_t* po = nullptr;
@ -573,7 +587,7 @@ namespace cw
if( parentUuId == kInvalidId ) if( parentUuId == kInvalidId )
{ {
// locate the the 'parent' ele name value object // locate the the 'parent' ele name value object
if((po = o->find("parent",kNoRecurseFl | kOptionalFl)) == nullptr ) if((po = o->find("parent",kOptionalFl)) == nullptr )
return cwLogError(kSyntaxErrorRC,"UI resources must have a root 'parent' value."); return cwLogError(kSyntaxErrorRC,"UI resources must have a root 'parent' value.");
// get the parent element name // get the parent element name
@ -595,7 +609,7 @@ namespace cw
return cwLogError(kSyntaxErrorRC,"A parent UI element named '%s' could not be found.",cwStringNullGuard(eleName)); return cwLogError(kSyntaxErrorRC,"A parent UI element named '%s' could not be found.",cwStringNullGuard(eleName));
rc = _createElementsFromChildList( p, o, wsSessId, parentEle ); rc = _createElementsFromChildList( p, o, wsSessId, parentEle, chanId );
return rc; return rc;
} }
@ -614,7 +628,7 @@ namespace cw
if( msg == nullptr ) if( msg == nullptr )
{ {
cwLogWarning("Empty message received from UI."); cwLogWarning("Empty 'value' message received from UI.");
return nullptr; return nullptr;
} }
@ -623,7 +637,7 @@ namespace cw
if( s == nullptr || sscanf(msg, "value %i %c ",&eleUuId,&argType) != 2 ) if( s == nullptr || sscanf(msg, "value %i %c ",&eleUuId,&argType) != 2 )
{ {
cwLogError(kSyntaxErrorRC,"Invalid message from UI: '%s'.", msg ); cwLogError(kSyntaxErrorRC,"Invalid 'value' message from UI: '%s'.", msg );
goto errLabel; goto errLabel;
} }
@ -680,6 +694,37 @@ namespace cw
return ele; return ele;
} }
ele_t* _parse_click_msg( ui_t* p, const char* msg )
{
ele_t* ele = nullptr;
unsigned eleUuId = kInvalidId;
if( msg == nullptr )
{
cwLogWarning("Empty click message received from UI.");
return nullptr;
}
//
if( sscanf(msg, "click %i ",&eleUuId) != 1 )
{
cwLogError(kSyntaxErrorRC,"Invalid 'click' message from UI: '%s'.", msg );
goto errLabel;
}
// locate the element record
if((ele = _uuIdToEle( p, eleUuId )) == nullptr )
{
cwLogError(kInvalidIdRC,"UI message elment not found.");
goto errLabel;
}
errLabel:
return ele;
}
ele_t* _parse_echo_msg( ui_t* p, const char* msg ) ele_t* _parse_echo_msg( ui_t* p, const char* msg )
{ {
unsigned eleUuId = kInvalidId; unsigned eleUuId = kInvalidId;
@ -718,6 +763,7 @@ namespace cw
{ kConnectOpId, "connect" }, { kConnectOpId, "connect" },
{ kInitOpId, "init" }, { kInitOpId, "init" },
{ kValueOpId, "value" }, { kValueOpId, "value" },
{ kClickOpId, "click" },
{ kEchoOpId, "echo" }, { kEchoOpId, "echo" },
{ kIdleOpId, "idle" }, { kIdleOpId, "idle" },
{ kDisconnectOpId, "disconnect" }, { kDisconnectOpId, "disconnect" },
@ -732,13 +778,13 @@ namespace cw
} }
template< typename T > template< typename T >
rc_t _sendValue( ui_t* p, unsigned wsSessId, unsigned uuId, const char* vFmt, const T& value, int vbufN=32 ) rc_t _sendValue( ui_t* p, unsigned wsSessId, unsigned uuId, const char* vFmt, const T& value, const char* opStr="value", int vbufN=32 )
{ {
rc_t rc = kOkRC; rc_t rc = kOkRC;
if( p->sendCbFunc != nullptr ) if( p->sendCbFunc != nullptr )
{ {
const char* mFmt = "{ \"op\":\"value\", \"uuId\":%i, \"value\":%s }"; const char* mFmt = "{ \"op\":\"%s\", \"uuId\":%i, \"value\":%s }";
const int mbufN = 128; const int mbufN = 128;
char vbuf[vbufN]; char vbuf[vbufN];
char mbuf[mbufN]; char mbuf[mbufN];
@ -746,7 +792,7 @@ namespace cw
if( snprintf(vbuf,vbufN,vFmt,value) >= vbufN-1 ) if( snprintf(vbuf,vbufN,vFmt,value) >= vbufN-1 )
return cwLogError(kBufTooSmallRC,"The value msg buffer is too small."); return cwLogError(kBufTooSmallRC,"The value msg buffer is too small.");
if( snprintf(mbuf,mbufN,mFmt,uuId,vbuf) >= mbufN-1 ) if( snprintf(mbuf,mbufN,mFmt,opStr,uuId,vbuf) >= mbufN-1 )
return cwLogError(kBufTooSmallRC,"The msg buffer is too small."); return cwLogError(kBufTooSmallRC,"The msg buffer is too small.");
//p->sendCbFunc(p->sendCbArg,wsSessId,mbuf,strlen(mbuf)); //p->sendCbFunc(p->sendCbArg,wsSessId,mbuf,strlen(mbuf));
@ -773,6 +819,48 @@ namespace cw
return rc; return rc;
} }
rc_t _setPropertyFlag( handle_t h, const char* propertyStr, unsigned uuId, bool enableFl )
{
ui_t* p = _handleToPtr(h);
rc_t rc = kOkRC;
ele_t* ele = nullptr;
const char* mFmt = "{ \"op\":\"set\", \"type\":\"%s\", \"uuId\":%i, \"enableFl\":%i }";
const int mbufN = 256;
char mbuf[mbufN];
if( snprintf(mbuf,mbufN,mFmt,propertyStr,uuId,enableFl?1:0) >= mbufN-1 )
{
rc = cwLogError(kBufTooSmallRC,"The msg buffer is too small.");
goto errLabel;
}
if((ele = _uuIdToEle(p,uuId)) == nullptr )
{
rc = kInvalidIdRC;
goto errLabel;
}
if((rc = _set_attribute_bool(ele,propertyStr,enableFl)) != kOkRC )
{
cwLogError(rc,"Property assignment failed.");
goto errLabel;
}
if((rc = _websockSend(p,kInvalidId,mbuf)) != kOkRC )
{
cwLogError(rc,"'%s' msg transmit failed.",propertyStr);
goto errLabel;
}
errLabel:
if( rc != kOkRC )
rc = cwLogError(rc,"Set '%s' failed.",propertyStr);
return rc;
}
} }
} }
@ -813,7 +901,7 @@ cw::rc_t cw::ui::create(
p->bufN = fmtBufByteN; p->bufN = fmtBufByteN;
// create the root element // create the root element
if((ele = _createBaseEle(p, nullptr, kRootAppId, "uiDivId" )) == nullptr || ele->uuId != kRootUuId ) if((ele = _createBaseEle(p, nullptr, kRootAppId, kInvalidId, "uiDivId" )) == nullptr || ele->uuId != kRootUuId )
{ {
cwLogError(kOpFailRC,"The UI root element creation failed."); cwLogError(kOpFailRC,"The UI root element creation failed.");
goto errLabel; goto errLabel;
@ -824,7 +912,7 @@ cw::rc_t cw::ui::create(
goto errLabel; goto errLabel;
if( uiRsrc != nullptr ) if( uiRsrc != nullptr )
if((rc = _createFromObj( p, uiRsrc, kInvalidId, kRootUuId )) != kOkRC ) if((rc = _createFromObj( p, uiRsrc, kInvalidId, kRootUuId, kInvalidId )) != kOkRC )
rc = cwLogError(rc,"Create from UI resource failed."); rc = cwLogError(rc,"Create from UI resource failed.");
@ -886,7 +974,7 @@ cw::rc_t cw::ui::onConnect( handle_t h, unsigned wsSessId )
// append the new session id // append the new session id
p->sessA[p->sessN++] = wsSessId; p->sessA[p->sessN++] = wsSessId;
p->uiCbFunc( p->uiCbArg, wsSessId, kConnectOpId, kInvalidId, kInvalidId, kInvalidId, nullptr ); p->uiCbFunc( p->uiCbArg, wsSessId, kConnectOpId, kInvalidId, kInvalidId, kInvalidId, kInvalidId, nullptr );
return kOkRC; return kOkRC;
} }
@ -894,7 +982,7 @@ cw::rc_t cw::ui::onDisconnect( handle_t h, unsigned wsSessId )
{ {
ui_t* p = _handleToPtr(h); ui_t* p = _handleToPtr(h);
p->uiCbFunc( p->uiCbArg, wsSessId, kDisconnectOpId, kInvalidId, kInvalidId, kInvalidId, nullptr ); p->uiCbFunc( p->uiCbArg, wsSessId, kDisconnectOpId, kInvalidId, kInvalidId, kInvalidId, kInvalidId, nullptr );
// erase the disconnected session id by shrinking the array // erase the disconnected session id by shrinking the array
for(unsigned i=0; i<p->sessN; ++i) for(unsigned i=0; i<p->sessN; ++i)
@ -926,7 +1014,7 @@ cw::rc_t cw::ui::onReceive( handle_t h, unsigned wsSessId, const void* msg, unsi
_onNewRemoteUi( p, wsSessId ); _onNewRemoteUi( p, wsSessId );
// Pass on the 'init' msg to the app. // Pass on the 'init' msg to the app.
p->uiCbFunc( p->uiCbArg, wsSessId, opId, kInvalidId, kInvalidId, kInvalidId, nullptr ); p->uiCbFunc( p->uiCbArg, wsSessId, opId, kInvalidId, kInvalidId, kInvalidId, kInvalidId, nullptr );
break; break;
case kValueOpId: case kValueOpId:
@ -936,11 +1024,22 @@ cw::rc_t cw::ui::onReceive( handle_t h, unsigned wsSessId, const void* msg, unsi
{ {
unsigned parentEleAppId = ele->parent == nullptr ? kInvalidId : ele->parent->appId; unsigned parentEleAppId = ele->parent == nullptr ? kInvalidId : ele->parent->appId;
p->uiCbFunc( p->uiCbArg, wsSessId, opId, parentEleAppId, ele->uuId, ele->appId, &value ); p->uiCbFunc( p->uiCbArg, wsSessId, opId, parentEleAppId, ele->uuId, ele->appId, ele->chanId, &value );
} }
break; break;
case kClickOpId:
if((ele = _parse_click_msg(p, (const char*)msg )) == nullptr )
cwLogError(kOpFailRC,"UI Value message parse failed.");
else
{
unsigned parentEleAppId = ele->parent == nullptr ? kInvalidId : ele->parent->appId;
p->uiCbFunc( p->uiCbArg, wsSessId, opId, parentEleAppId, ele->uuId, ele->appId, ele->chanId, &value );
}
break;
case kEchoOpId: case kEchoOpId:
if((ele = _parse_echo_msg(p,(const char*)msg)) == nullptr ) if((ele = _parse_echo_msg(p,(const char*)msg)) == nullptr )
cwLogError(kOpFailRC,"UI Echo message parse failed."); cwLogError(kOpFailRC,"UI Echo message parse failed.");
@ -948,12 +1047,12 @@ cw::rc_t cw::ui::onReceive( handle_t h, unsigned wsSessId, const void* msg, unsi
{ {
unsigned parentEleAppId = ele->parent == nullptr ? kInvalidId : ele->parent->appId; unsigned parentEleAppId = ele->parent == nullptr ? kInvalidId : ele->parent->appId;
p->uiCbFunc( p->uiCbArg, wsSessId, opId, parentEleAppId, ele->uuId, ele->appId, nullptr ); p->uiCbFunc( p->uiCbArg, wsSessId, opId, parentEleAppId, ele->uuId, ele->appId, ele->chanId,nullptr );
} }
break; break;
case kIdleOpId: case kIdleOpId:
p->uiCbFunc( p->uiCbArg, kInvalidId, opId, kInvalidId, kInvalidId, kInvalidId, nullptr ); p->uiCbFunc( p->uiCbArg, kInvalidId, opId, kInvalidId, kInvalidId, kInvalidId, kInvalidId, nullptr );
break; break;
case kInvalidOpId: case kInvalidOpId:
@ -1034,21 +1133,21 @@ unsigned cw::ui::findElementAppId( handle_t h, unsigned uuId )
} }
cw::rc_t cw::ui::createFromObject( handle_t h, const object_t* o, unsigned wsSessId, unsigned parentUuId, const char* eleName ) cw::rc_t cw::ui::createFromObject( handle_t h, const object_t* o, unsigned parentUuId, unsigned chanId, const char* fieldName )
{ {
ui_t* p = _handleToPtr(h); ui_t* p = _handleToPtr(h);
rc_t rc = kOkRC; rc_t rc = kOkRC;
//ele_t* parentEle = nullptr; //ele_t* parentEle = nullptr;
if( eleName != nullptr ) if( fieldName != nullptr )
if((o = o->find(eleName)) == nullptr ) if((o = o->find(fieldName)) == nullptr )
{ {
rc = cwLogError(kSyntaxErrorRC,"Unable to locate the '%s' sub-configuration.",cwStringNullGuard(eleName)); rc = cwLogError(kSyntaxErrorRC,"Unable to locate the '%s' sub-configuration.",cwStringNullGuard(fieldName));
goto errLabel; goto errLabel;
} }
if((rc = _createFromObj( p, o, wsSessId, parentUuId )) != kOkRC ) if((rc = _createFromObj( p, o, kInvalidId, parentUuId, chanId )) != kOkRC )
goto errLabel; goto errLabel;
errLabel: errLabel:
@ -1059,7 +1158,7 @@ cw::rc_t cw::ui::createFromObject( handle_t h, const object_t* o, unsigned wsS
} }
cw::rc_t cw::ui::createFromFile( handle_t h, const char* fn, unsigned wsSessId, unsigned parentUuId) cw::rc_t cw::ui::createFromFile( handle_t h, const char* fn, unsigned parentUuId, unsigned chanId)
{ {
ui_t* p = _handleToPtr(h); ui_t* p = _handleToPtr(h);
rc_t rc = kOkRC; rc_t rc = kOkRC;
@ -1068,7 +1167,7 @@ cw::rc_t cw::ui::createFromFile( handle_t h, const char* fn, unsigned wsSessId
if((rc = objectFromFile( fn, o )) != kOkRC ) if((rc = objectFromFile( fn, o )) != kOkRC )
goto errLabel; goto errLabel;
if((rc = _createFromObj( p, o, wsSessId, parentUuId )) != kOkRC ) if((rc = _createFromObj( p, o, kInvalidId, parentUuId, chanId )) != kOkRC )
goto errLabel; goto errLabel;
errLabel: errLabel:
@ -1081,7 +1180,7 @@ cw::rc_t cw::ui::createFromFile( handle_t h, const char* fn, unsigned wsSessId
return rc; return rc;
} }
cw::rc_t cw::ui::createFromText( handle_t h, const char* text, unsigned wsSessId, unsigned parentUuId) cw::rc_t cw::ui::createFromText( handle_t h, const char* text, unsigned parentUuId, unsigned chanId )
{ {
ui_t* p = _handleToPtr(h); ui_t* p = _handleToPtr(h);
rc_t rc = kOkRC; rc_t rc = kOkRC;
@ -1090,7 +1189,7 @@ cw::rc_t cw::ui::createFromText( handle_t h, const char* text, unsigned wsSessId
if((rc = objectFromString( text, o )) != kOkRC ) if((rc = objectFromString( text, o )) != kOkRC )
goto errLabel; goto errLabel;
if((rc = _createFromObj( p, o, wsSessId, parentUuId )) != kOkRC ) if((rc = _createFromObj( p, o, kInvalidId, parentUuId, chanId )) != kOkRC )
goto errLabel; goto errLabel;
errLabel: errLabel:
@ -1103,93 +1202,93 @@ cw::rc_t cw::ui::createFromText( handle_t h, const char* text, unsigned wsSessId
return rc; return rc;
} }
cw::rc_t cw::ui::createDiv( handle_t h, unsigned& uuIdRef, unsigned wsSessId, unsigned parentUuId, const char* eleName, unsigned appId, const char* clas, const char* title ) cw::rc_t cw::ui::createDiv( handle_t h, unsigned& uuIdRef, unsigned parentUuId, const char* eleName, unsigned appId, unsigned chanId, const char* clas, const char* title )
{ return _createOneEle( _handleToPtr(h), uuIdRef, "div", wsSessId, parentUuId, eleName, appId, clas, title ); } { return _createOneEle( _handleToPtr(h), uuIdRef, "div", kInvalidId, parentUuId, eleName, appId, chanId, clas, title ); }
cw::rc_t cw::ui::createLabel( handle_t h, unsigned& uuIdRef, unsigned wsSessId, unsigned parentUuId, const char* eleName, unsigned appId, const char* clas, const char* title ) cw::rc_t cw::ui::createLabel( handle_t h, unsigned& uuIdRef, unsigned parentUuId, const char* eleName, unsigned appId, unsigned chanId, const char* clas, const char* title )
{ return _createOneEle( _handleToPtr(h), uuIdRef, "label", wsSessId, parentUuId, eleName, appId, clas, title ); } { return _createOneEle( _handleToPtr(h), uuIdRef, "label", kInvalidId, parentUuId, eleName, appId, chanId, clas, title ); }
cw::rc_t cw::ui::createButton( handle_t h, unsigned& uuIdRef, unsigned wsSessId, unsigned parentUuId, const char* eleName, unsigned appId, const char* clas, const char* title ) cw::rc_t cw::ui::createButton( handle_t h, unsigned& uuIdRef, unsigned parentUuId, const char* eleName, unsigned appId, unsigned chanId, const char* clas, const char* title )
{ return _createOneEle( _handleToPtr(h), uuIdRef, "button", wsSessId, parentUuId, eleName, appId, clas, title ); } { return _createOneEle( _handleToPtr(h), uuIdRef, "button", kInvalidId, parentUuId, eleName, appId, chanId, clas, title ); }
cw::rc_t cw::ui::createCheck( handle_t h, unsigned& uuIdRef, unsigned wsSessId, unsigned parentUuId, const char* eleName, unsigned appId, const char* clas, const char* title ) cw::rc_t cw::ui::createCheck( handle_t h, unsigned& uuIdRef, unsigned parentUuId, const char* eleName, unsigned appId, unsigned chanId, const char* clas, const char* title )
{ return _createOneEle( _handleToPtr(h), uuIdRef, "check", wsSessId, parentUuId, eleName, appId, clas, title ); } { return _createOneEle( _handleToPtr(h), uuIdRef, "check", kInvalidId, parentUuId, eleName, appId, chanId, clas, title ); }
cw::rc_t cw::ui::createCheck( handle_t h, unsigned& uuIdRef, unsigned wsSessId, unsigned parentUuId, const char* eleName, unsigned appId, const char* clas, const char* title, bool value ) cw::rc_t cw::ui::createCheck( handle_t h, unsigned& uuIdRef, unsigned parentUuId, const char* eleName, unsigned appId, unsigned chanId, const char* clas, const char* title, bool value )
{ return _createOneEle( _handleToPtr(h), uuIdRef, "check", wsSessId, parentUuId, eleName, appId, clas, title, "value", value ); } { return _createOneEle( _handleToPtr(h), uuIdRef, "check", kInvalidId, parentUuId, eleName, appId, chanId, clas, title, "value", value ); }
cw::rc_t cw::ui::createSelect( handle_t h, unsigned& uuIdRef, unsigned wsSessId, unsigned parentUuId, const char* eleName, unsigned appId, const char* clas, const char* title ) cw::rc_t cw::ui::createSelect( handle_t h, unsigned& uuIdRef, unsigned parentUuId, const char* eleName, unsigned appId, unsigned chanId, const char* clas, const char* title )
{ return _createOneEle( _handleToPtr(h), uuIdRef, "select", wsSessId, parentUuId, eleName, appId, clas, title ); } { return _createOneEle( _handleToPtr(h), uuIdRef, "select", kInvalidId, parentUuId, eleName, appId, chanId, clas, title ); }
cw::rc_t cw::ui::createOption( handle_t h, unsigned& uuIdRef, unsigned wsSessId, unsigned parentUuId, const char* eleName, unsigned appId, const char* clas, const char* title ) cw::rc_t cw::ui::createOption( handle_t h, unsigned& uuIdRef, unsigned parentUuId, const char* eleName, unsigned appId, unsigned chanId, const char* clas, const char* title )
{ return _createOneEle( _handleToPtr(h), uuIdRef, "option", wsSessId, parentUuId, eleName, appId, clas, title ); } { return _createOneEle( _handleToPtr(h), uuIdRef, "option", kInvalidId, parentUuId, eleName, appId, chanId, clas, title ); }
cw::rc_t cw::ui::createStr( handle_t h, unsigned& uuIdRef, unsigned wsSessId, unsigned parentUuId, const char* eleName, unsigned appId, const char* clas, const char* title ) cw::rc_t cw::ui::createStr( handle_t h, unsigned& uuIdRef, unsigned parentUuId, const char* eleName, unsigned appId, unsigned chanId, const char* clas, const char* title )
{ return _createOneEle( _handleToPtr(h), uuIdRef, "string", wsSessId, parentUuId, eleName, appId, clas, title ); } { return _createOneEle( _handleToPtr(h), uuIdRef, "string", kInvalidId, parentUuId, eleName, appId, chanId, clas, title ); }
cw::rc_t cw::ui::createStr( handle_t h, unsigned& uuIdRef, unsigned wsSessId, unsigned parentUuId, const char* eleName, unsigned appId, const char* clas, const char* title, const char* value ) cw::rc_t cw::ui::createStr( handle_t h, unsigned& uuIdRef, unsigned parentUuId, const char* eleName, unsigned appId, unsigned chanId, const char* clas, const char* title, const char* value )
{ return _createOneEle( _handleToPtr(h), uuIdRef, "string", wsSessId, parentUuId, eleName, appId, clas, title, "value", value ); } { return _createOneEle( _handleToPtr(h), uuIdRef, "string", kInvalidId, parentUuId, eleName, appId, chanId, clas, title, "value", value ); }
cw::rc_t cw::ui::createNumbDisplay( handle_t h, unsigned& uuIdRef, unsigned wsSessId, unsigned parentUuId, const char* eleName, unsigned appId, const char* clas, const char* title, unsigned decpl ) cw::rc_t cw::ui::createNumbDisplay( handle_t h, unsigned& uuIdRef, unsigned parentUuId, const char* eleName, unsigned appId, unsigned chanId, const char* clas, const char* title, unsigned decpl )
{ return _createOneEle( _handleToPtr(h), uuIdRef, "numb_disp", wsSessId, parentUuId, eleName, appId, clas, title, "decpl", decpl ); } { return _createOneEle( _handleToPtr(h), uuIdRef, "numb_disp", kInvalidId, parentUuId, eleName, appId, chanId, clas, title, "decpl", decpl ); }
cw::rc_t cw::ui::createNumbDisplay( handle_t h, unsigned& uuIdRef, unsigned wsSessId, unsigned parentUuId, const char* eleName, unsigned appId, const char* clas, const char* title, unsigned decpl, double value ) cw::rc_t cw::ui::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 )
{ return _createOneEle( _handleToPtr(h), uuIdRef, "numb_disp", wsSessId, parentUuId, eleName, appId, clas, title, "decpl", decpl, "value", value ); } { return _createOneEle( _handleToPtr(h), uuIdRef, "numb_disp", kInvalidId, parentUuId, eleName, appId, chanId, clas, title, "decpl", decpl, "value", value ); }
cw::rc_t cw::ui::createNumb( handle_t h, unsigned& uuIdRef, unsigned wsSessId, unsigned parentUuId, const char* eleName, unsigned appId, const char* clas, const char* title, double minValue, double maxValue, double stepValue, unsigned decpl ) cw::rc_t cw::ui::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 )
{ return _createOneEle( _handleToPtr(h), uuIdRef, "number", wsSessId, parentUuId, eleName, appId, clas, title, "min", minValue, "max", maxValue, "step", stepValue, "decpl", decpl ); } { return _createOneEle( _handleToPtr(h), uuIdRef, "number", kInvalidId, parentUuId, eleName, appId, chanId, clas, title, "min", minValue, "max", maxValue, "step", stepValue, "decpl", decpl ); }
cw::rc_t cw::ui::createNumb( handle_t h, unsigned& uuIdRef, unsigned wsSessId, unsigned parentUuId, const char* eleName, unsigned appId, const char* clas, const char* title, double minValue, double maxValue, double stepValue, unsigned decpl, double value ) cw::rc_t cw::ui::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 )
{ return _createOneEle( _handleToPtr(h), uuIdRef, "number", wsSessId, parentUuId, eleName, appId, clas, title, "min", minValue, "max", maxValue, "step", stepValue, "decpl", decpl, "value", value ); } { return _createOneEle( _handleToPtr(h), uuIdRef, "number", kInvalidId, parentUuId, eleName, appId, chanId, clas, title, "min", minValue, "max", maxValue, "step", stepValue, "decpl", decpl, "value", value ); }
cw::rc_t cw::ui::createProg( handle_t h, unsigned& uuIdRef, unsigned wsSessId, unsigned parentUuId, const char* eleName, unsigned appId, const char* clas, const char* title, double minValue, double maxValue ) cw::rc_t cw::ui::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 )
{ return _createOneEle( _handleToPtr(h), uuIdRef, "progress", wsSessId, parentUuId, eleName, appId, clas, title, "min", minValue, "max", maxValue ); } { return _createOneEle( _handleToPtr(h), uuIdRef, "progress", kInvalidId, parentUuId, eleName, appId, chanId, clas, title, "min", minValue, "max", maxValue ); }
cw::rc_t cw::ui::createProg( handle_t h, unsigned& uuIdRef, unsigned wsSessId, unsigned parentUuId, const char* eleName, unsigned appId, const char* clas, const char* title, double minValue, double maxValue, double value ) cw::rc_t cw::ui::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 )
{ return _createOneEle( _handleToPtr(h), uuIdRef, "progress", wsSessId, parentUuId, eleName, appId, clas, title, "value", value, "min", minValue, "max", maxValue ); } { return _createOneEle( _handleToPtr(h), uuIdRef, "progress", kInvalidId, parentUuId, eleName, appId, chanId, clas, title, "value", value, "min", minValue, "max", maxValue ); }
cw::rc_t cw::ui::createLog( handle_t h, unsigned& uuIdRef, unsigned wsSessId, unsigned parentUuId, const char* eleName, unsigned appId, const char* clas, const char* title ) cw::rc_t cw::ui::createLog( handle_t h, unsigned& uuIdRef, unsigned parentUuId, const char* eleName, unsigned appId, unsigned chanId, const char* clas, const char* title )
{ return _createOneEle( _handleToPtr(h), uuIdRef, "log", wsSessId, parentUuId, eleName, appId, clas, title); } { return _createOneEle( _handleToPtr(h), uuIdRef, "log", kInvalidId, parentUuId, eleName, appId, chanId, clas, title); }
cw::rc_t cw::ui::createList( handle_t h, unsigned& uuIdRef, unsigned wsSessId, unsigned parentUuId, const char* eleName, unsigned appId, const char* clas, const char* title ) cw::rc_t cw::ui::createList( handle_t h, unsigned& uuIdRef, unsigned parentUuId, const char* eleName, unsigned appId, unsigned chanId, const char* clas, const char* title )
{ return _createOneEle( _handleToPtr(h), uuIdRef, "list", wsSessId, parentUuId, eleName, appId, clas, title); } { return _createOneEle( _handleToPtr(h), uuIdRef, "list", kInvalidId, parentUuId, eleName, appId, chanId, clas, title); }
cw::rc_t cw::ui::setNumbRange( handle_t h, unsigned wsSessId, unsigned uuId, double minValue, double maxValue, double stepValue, unsigned decPl, double value ) cw::rc_t cw::ui::setNumbRange( handle_t h, unsigned uuId, double minValue, double maxValue, double stepValue, unsigned decPl, double value )
{ {
rc_t rc = kOkRC; rc_t rc = kOkRC;
ui_t* p = _handleToPtr(h); ui_t* p = _handleToPtr(h);
const char* mFmt = "{ \"op\":\"set\", \"uuId\":%i, \"min\":%f, \"max\":%f, \"step\":%f, \"decpl\":%i, \"value\":%f }"; const char* mFmt = "{ \"op\":\"set\", \"type\":\"number_range\", \"uuId\":%i, \"min\":%f, \"max\":%f, \"step\":%f, \"decpl\":%i, \"value\":%f }";
const int mbufN = 256; const int mbufN = 256;
char mbuf[mbufN]; char mbuf[mbufN];
if( snprintf(mbuf,mbufN,mFmt,uuId,minValue,maxValue,stepValue,decPl,value) >= mbufN-1 ) if( snprintf(mbuf,mbufN,mFmt,uuId,minValue,maxValue,stepValue,decPl,value) >= mbufN-1 )
return cwLogError(kBufTooSmallRC,"The msg buffer is too small."); return cwLogError(kBufTooSmallRC,"The msg buffer is too small.");
rc = _websockSend(p,wsSessId,mbuf); rc = _websockSend(p,kInvalidId,mbuf);
return rc; return rc;
} }
cw::rc_t cw::ui::setProgRange( handle_t h, unsigned wsSessId, unsigned uuId, double minValue, double maxValue, double value ) cw::rc_t cw::ui::setProgRange( handle_t h, unsigned uuId, double minValue, double maxValue, double value )
{ {
rc_t rc = kOkRC; rc_t rc = kOkRC;
ui_t* p = _handleToPtr(h); ui_t* p = _handleToPtr(h);
const char* mFmt = "{ \"op\":\"set\", \"uuId\":%i, \"min\":%f, \"max\":%f, \"value\":%f }"; const char* mFmt = "{ \"op\":\"set\", \"type\":\"progress_range\", \"uuId\":%i, \"min\":%f, \"max\":%f, \"value\":%f }";
const int mbufN = 256; const int mbufN = 256;
char mbuf[mbufN]; char mbuf[mbufN];
if( snprintf(mbuf,mbufN,mFmt,uuId,minValue,maxValue,value) >= mbufN-1 ) if( snprintf(mbuf,mbufN,mFmt,uuId,minValue,maxValue,value) >= mbufN-1 )
return cwLogError(kBufTooSmallRC,"The msg buffer is too small."); return cwLogError(kBufTooSmallRC,"The msg buffer is too small.");
rc = _websockSend(p,wsSessId,mbuf); rc = _websockSend(p,kInvalidId,mbuf);
return rc; return rc;
} }
cw::rc_t cw::ui::setLogLine( handle_t h, unsigned wsSessId, unsigned uuId, const char* text ) cw::rc_t cw::ui::setLogLine( handle_t h, unsigned uuId, const char* text )
{ {
rc_t rc = kOkRC; rc_t rc = kOkRC;
@ -1200,7 +1299,7 @@ cw::rc_t cw::ui::setLogLine( handle_t h, unsigned wsSessId, unsigned uuId, con
++n; ++n;
if( n == 0 ) if( n == 0 )
rc = sendValueString(h,wsSessId,uuId,text); rc = sendValueString(h,uuId,text);
else else
{ {
int sn = textLength(text); int sn = textLength(text);
@ -1236,13 +1335,50 @@ cw::rc_t cw::ui::setLogLine( handle_t h, unsigned wsSessId, unsigned uuId, con
printf("%s %s\n",text,s); printf("%s %s\n",text,s);
rc = sendValueString(h,wsSessId,uuId,s); rc = sendValueString(h,uuId,s);
} }
return rc; return rc;
} }
cw::rc_t cw::ui::setClickable( handle_t h, unsigned uuId, bool clickableFl )
{ return _setPropertyFlag( h, UI_CLICKABLE_LABEL, uuId, clickableFl ); }
cw::rc_t cw::ui::clearClickable( handle_t h, unsigned uuId )
{ return setClickable(h,uuId,false); }
bool cw::ui::isClickable( handle_t h, unsigned uuId )
{
ui_t* p = _handleToPtr(h);
ele_t* ele = nullptr;
bool clickableFl = false;
if((ele = _uuIdToEle(p,uuId)) != nullptr )
clickableFl = _get_attribute_bool(ele,UI_CLICKABLE_LABEL);
return clickableFl;
}
cw::rc_t cw::ui::setSelect( handle_t h, unsigned uuId, bool enableFl )
{ return _setPropertyFlag( h, UI_SELECT_LABEL, uuId, enableFl ); }
cw::rc_t cw::ui::clearSelect( handle_t h, unsigned uuId )
{ return setSelect(h,uuId,false); }
bool cw::ui::isSelected( handle_t h, unsigned uuId )
{
ui_t* p = _handleToPtr(h);
ele_t* ele = nullptr;
bool selectFl = false;
if((ele = _uuIdToEle(p,uuId)) != nullptr )
selectFl = _get_attribute_bool(ele,UI_SELECT_LABEL);
return selectFl;
}
cw::rc_t cw::ui::registerAppIdMap( handle_t h, const appIdMap_t* map, unsigned mapN ) cw::rc_t cw::ui::registerAppIdMap( handle_t h, const appIdMap_t* map, unsigned mapN )
@ -1250,42 +1386,42 @@ cw::rc_t cw::ui::registerAppIdMap( handle_t h, const appIdMap_t* map, unsigned
return _registerAppIdMap( _handleToPtr(h), map, mapN); return _registerAppIdMap( _handleToPtr(h), map, mapN);
} }
cw::rc_t cw::ui::sendValueBool( handle_t h, unsigned wsSessId, unsigned uuId, bool value ) cw::rc_t cw::ui::sendValueBool( handle_t h, unsigned uuId, bool value )
{ {
ui_t* p = _handleToPtr(h); ui_t* p = _handleToPtr(h);
return _sendValue<int>(p,wsSessId,uuId,"%i",value?1:0); return _sendValue<int>(p,kInvalidId,uuId,"%i",value?1:0);
} }
cw::rc_t cw::ui::sendValueInt( handle_t h, unsigned wsSessId, unsigned uuId, int value ) cw::rc_t cw::ui::sendValueInt( handle_t h, unsigned uuId, int value )
{ {
ui_t* p = _handleToPtr(h); ui_t* p = _handleToPtr(h);
return _sendValue<int>(p,wsSessId,uuId,"%i",value); return _sendValue<int>(p,kInvalidId,uuId,"%i",value);
} }
cw::rc_t cw::ui::sendValueUInt( handle_t h, unsigned wsSessId, unsigned uuId, unsigned value ) cw::rc_t cw::ui::sendValueUInt( handle_t h, unsigned uuId, unsigned value )
{ {
ui_t* p = _handleToPtr(h); ui_t* p = _handleToPtr(h);
return _sendValue<unsigned>(p,wsSessId,uuId,"%i",value); return _sendValue<unsigned>(p,kInvalidId,uuId,"%i",value);
} }
cw::rc_t cw::ui::sendValueFloat( handle_t h, unsigned wsSessId, unsigned uuId, float value ) cw::rc_t cw::ui::sendValueFloat( handle_t h, unsigned uuId, float value )
{ {
ui_t* p = _handleToPtr(h); ui_t* p = _handleToPtr(h);
return _sendValue<float>(p,wsSessId,uuId,"%f",value); return _sendValue<float>(p,kInvalidId,uuId,"%f",value);
} }
cw::rc_t cw::ui::sendValueDouble( handle_t h, unsigned wsSessId, unsigned uuId, double value ) cw::rc_t cw::ui::sendValueDouble( handle_t h, unsigned uuId, double value )
{ {
ui_t* p = _handleToPtr(h); ui_t* p = _handleToPtr(h);
return _sendValue<double>(p,wsSessId,uuId,"%f",value); return _sendValue<double>(p,kInvalidId,uuId,"%f",value);
} }
cw::rc_t cw::ui::sendValueString( handle_t h, unsigned wsSessId, unsigned uuId, const char* value ) cw::rc_t cw::ui::sendValueString( handle_t h, unsigned uuId, const char* value )
{ {
ui_t* p = _handleToPtr(h); ui_t* p = _handleToPtr(h);
// +10 allows for extra value buffer space for double quotes and slashed // +10 allows for extra value buffer space for double quotes and slashed
return _sendValue<const char*>(p,wsSessId,uuId,"\"%s\"",value,strlen(value)+10); return _sendValue<const char*>(p,kInvalidId,uuId,"\"%s\"",value,"value",strlen(value)+10);
} }
void cw::ui::report( handle_t h ) void cw::ui::report( handle_t h )
@ -1375,7 +1511,7 @@ namespace cw
rc_t _webSockSend( void* cbArg, unsigned wsSessId, const void* msg, unsigned msgByteN ) rc_t _webSockSend( void* cbArg, unsigned wsSessId, const void* msg, unsigned msgByteN )
{ {
ui_ws_t* p = static_cast<ui_ws_t*>(cbArg); ui_ws_t* p = static_cast<ui_ws_t*>(cbArg);
return websock::send( p->wsH, kUiProtocolId, wsSessId, msg, msgByteN ); return websock::send( p->wsH, kUiProtocolId, kInvalidId, msg, msgByteN );
} }
} }

73
cwUi.h
View File

@ -12,7 +12,7 @@ namespace cw
// Callback for application notification. // Callback for application notification.
// (e.g. the GUI changed the value of a UI element) // (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, const value_t* value ); 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 // Callback with messages for the GUI as JSON strings
// { "op":"create", "type":<>, "appId":<>, "parentUuId":<>, "name":<> (type specific fields) } // { "op":"create", "type":<>, "appId":<>, "parentUuId":<>, "name":<> (type specific fields) }
@ -58,9 +58,11 @@ namespace cw
// Create multiple UI elements from an object_t representation. // Create multiple UI elements from an object_t representation.
rc_t createFromObject( handle_t h, const object_t* o, unsigned wsSessId, unsigned parentUuId=kInvalidId, const char* eleName=nullptr); // The channel id of all elements created from the object will be assigned 'chanId'.
rc_t createFromFile( handle_t h, const char* fn, unsigned wsSessId, unsigned parentUuId=kInvalidId); // The 'fieldName' string identifies
rc_t createFromText( handle_t h, const char* text, unsigned wsSessId, unsigned parentUuId=kInvalidId); rc_t createFromObject( handle_t h, const object_t* o, unsigned parentUuId=kInvalidId, unsigned chanId=kInvalidId, const char* fieldName=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);
// //
// Create Sincgle UI elements on the UI instance identified by wsSessId. // Create Sincgle UI elements on the UI instance identified by wsSessId.
@ -88,44 +90,53 @@ namespace cw
// title: (optional) Visible Text label associated with this element. // title: (optional) Visible Text label associated with this element.
// //
rc_t createDiv( handle_t h, unsigned& uuIdRef, unsigned wsSessId, unsigned parentUuId, const char* eleName, unsigned appId, const char* clas, const char* title ); 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 wsSessId, unsigned parentUuId, const char* eleName, unsigned appId, 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 wsSessId, unsigned parentUuId, const char* eleName, unsigned appId, 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. // 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 wsSessId, unsigned parentUuId, const char* eleName, unsigned appId, const char* clas, const char* title ); 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. // 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 wsSessId, unsigned parentUuId, const char* eleName, unsigned appId, const char* clas, const char* title, bool value ); 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 wsSessId, unsigned parentUuId, const char* eleName, unsigned appId, const char* clas, const char* title ); 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 wsSessId, unsigned parentUuId, const char* eleName, unsigned appId, 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 createStr( handle_t h, unsigned& uuIdRef, unsigned wsSessId, unsigned parentUuId, const char* eleName, unsigned appId, 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 );
rc_t createStr( handle_t h, unsigned& uuIdRef, unsigned wsSessId, unsigned parentUuId, const char* eleName, unsigned appId, 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, const char* value );
rc_t createNumbDisplay(handle_t h, unsigned& uuIdRef, unsigned wsSessId, unsigned parentUuId, const char* eleName, unsigned appId, 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 );
rc_t createNumbDisplay(handle_t h, unsigned& uuIdRef, unsigned wsSessId, unsigned parentUuId, const char* eleName, unsigned appId, const char* clas, const char* title, unsigned decPl, double 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, double value );
rc_t createNumb( handle_t h, unsigned& uuIdRef, unsigned wsSessId, unsigned parentUuId, const char* eleName, unsigned appId, 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 );
rc_t createNumb( handle_t h, unsigned& uuIdRef, unsigned wsSessId, unsigned parentUuId, const char* eleName, unsigned appId, const char* clas, const char* title, double minValue, double maxValue, double stepValue, 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, double value );
rc_t createProg( handle_t h, unsigned& uuIdRef, unsigned wsSessId, unsigned parentUuId, const char* eleName, unsigned appId, 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 );
rc_t createProg( handle_t h, unsigned& uuIdRef, unsigned wsSessId, unsigned parentUuId, const char* eleName, unsigned appId, const char* clas, const char* title, double minValue, double maxValue, 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, double value );
rc_t createLog( handle_t h, unsigned& uuIdRef, unsigned wsSessId, unsigned parentUuId, const char* eleName, unsigned appId, const char* clas, const char* title ); 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 createList( handle_t h, unsigned& uuIdRef, unsigned wsSessId, unsigned parentUuId, const char* eleName, unsigned appId, const char* clas, const char* title ); rc_t createList( handle_t h, unsigned& uuIdRef, unsigned parentUuId, const char* eleName, unsigned appId, unsigned chanId, const char* clas, const char* title );
rc_t setNumbRange( handle_t h, unsigned wsSessId, unsigned uuId, double minValue, double maxValue, double stepValue, unsigned decPl, double value ); 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 wsSessId, unsigned uuId, double minValue, double maxValue, double value ); rc_t setProgRange( handle_t h, unsigned uuId, double minValue, double maxValue, double value );
rc_t setLogLine( handle_t h, unsigned wsSessId, unsigned uuId, const char* text ); rc_t setLogLine( handle_t h, unsigned uuId, const char* text );
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 );
// Register parent/child/name app id's // Register parent/child/name app id's
rc_t registerAppIdMap( handle_t h, const appIdMap_t* map, unsigned mapN ); rc_t registerAppIdMap( handle_t h, const appIdMap_t* map, unsigned mapN );
// Send a value from the application to the UI via a JSON messages. // Send a value from the application to the UI via a JSON messages.
// Set wsSessId to kInvalidId to send to all sessions. // Set wsSessId to kInvalidId to send to all sessions.
rc_t sendValueBool( handle_t h, unsigned wsSessId, unsigned uuId, bool value ); rc_t sendValueBool( handle_t h, unsigned uuId, bool value );
rc_t sendValueInt( handle_t h, unsigned wsSessId, unsigned uuId, int value ); rc_t sendValueInt( handle_t h, unsigned uuId, int value );
rc_t sendValueUInt( handle_t h, unsigned wsSessId, unsigned uuId, unsigned value ); rc_t sendValueUInt( handle_t h, unsigned uuId, unsigned value );
rc_t sendValueFloat( handle_t h, unsigned wsSessId, unsigned uuId, float value ); rc_t sendValueFloat( handle_t h, unsigned uuId, float value );
rc_t sendValueDouble( handle_t h, unsigned wsSessId, unsigned uuId, double value ); rc_t sendValueDouble( handle_t h, unsigned uuId, double value );
rc_t sendValueString( handle_t h, unsigned wsSessId, unsigned uuId, const char* value ); rc_t sendValueString( handle_t h, unsigned uuId, const char* value );
void report( handle_t h ); void report( handle_t h );
@ -147,7 +158,7 @@ namespace cw
unsigned wsTimeOutMs; unsigned wsTimeOutMs;
} args_t; } args_t;
rc_t parseArgs( const object_t& o, args_t& args, const char* object_label=nullptr ); rc_t parseArgs( const object_t& o, args_t& args, const char* object_label="ui" );
rc_t releaseArgs( args_t& args ); rc_t releaseArgs( args_t& args );
rc_t create( handle_t& h, rc_t create( handle_t& h,

View File

@ -17,6 +17,7 @@ namespace cw
kConnectOpId, // A new remote user interface was connected kConnectOpId, // A new remote user interface was connected
kInitOpId, // A remote user interface instance was created and is available. It needs to be updated with the current state of the UI from the server. kInitOpId, // A remote user interface instance was created and is available. It needs to be updated with the current state of the UI from the server.
kValueOpId, // The value of a remote user interface control changed. Send this value to the application engine. kValueOpId, // The value of a remote user interface control changed. Send this value to the application engine.
kClickOpId, // A element on a remote user interface was clicked.
kEchoOpId, // A remote user interface is requesting an application engine value. The the current value of a ui element must be sent to the remote UI. kEchoOpId, // A remote user interface is requesting an application engine value. The the current value of a ui element must be sent to the remote UI.
kIdleOpId, // The application (UI server) is idle and waiting for the next event from a remote UI. kIdleOpId, // The application (UI server) is idle and waiting for the next event from a remote UI.
kDisconnectOpId // A reemot user interface was disconnected. kDisconnectOpId // A reemot user interface was disconnected.

View File

@ -77,44 +77,43 @@ namespace cw
rc_t rc = kOkRC; rc_t rc = kOkRC;
unsigned uuid = kInvalidId; unsigned uuid = kInvalidId;
unsigned selUuId = kInvalidId; unsigned selUuId = kInvalidId;
unsigned chanId = 0;
handle_t uiH = srv::uiHandle(p->wsUiSrvH); handle_t uiH = srv::uiHandle(p->wsUiSrvH);
// Create a UI elements programatically. // Create a UI elements programatically.
if((rc = createDiv( uiH, p->myPanelUuId, wsSessId, kInvalidId, "myDivId", kDivId, "divClass", "My Panel" )) != kOkRC ) if((rc = createDiv( uiH, p->myPanelUuId, kInvalidId, "myDivId", kDivId, chanId, "divClass", "My Panel" )) != kOkRC )
goto errLabel; goto errLabel;
if((rc = createCheck( uiH, uuid, wsSessId, p->myPanelUuId, "myCheckId", kCheckId, "checkClass", "Check Me", true )) != kOkRC ) if((rc = createCheck( uiH, uuid, p->myPanelUuId, "myCheckId", kCheckId, chanId, "checkClass", "Check Me", true )) != kOkRC )
goto errLabel; goto errLabel;
if((rc = createSelect( uiH, selUuId, wsSessId, p->myPanelUuId, "mySelId", kSelectId, "selClass", "Select" )) != kOkRC ) if((rc = createSelect( uiH, selUuId, p->myPanelUuId, "mySelId", kSelectId, chanId, "selClass", "Select" )) != kOkRC )
goto errLabel; goto errLabel;
if((rc = createOption( uiH, uuid, wsSessId, selUuId, "myOpt0Id", kOption0Id, "optClass", "Option 0" )) != kOkRC ) if((rc = createOption( uiH, uuid, selUuId, "myOpt0Id", kOption0Id, chanId, "optClass", "Option 0" )) != kOkRC )
goto errLabel; goto errLabel;
if((rc = createOption( uiH, uuid, wsSessId, selUuId, "myOpt1Id", kOption1Id, "optClass", "Option 1" )) != kOkRC ) if((rc = createOption( uiH, uuid, selUuId, "myOpt1Id", kOption1Id, chanId, "optClass", "Option 1" )) != kOkRC )
goto errLabel; goto errLabel;
if((rc = createOption( uiH, uuid, wsSessId, selUuId, "myOpt2Id", kOption2Id, "optClass", "Option 2" )) != kOkRC ) if((rc = createOption( uiH, uuid, selUuId, "myOpt2Id", kOption2Id, chanId, "optClass", "Option 2" )) != kOkRC )
goto errLabel; goto errLabel;
if((rc = createStr( uiH, uuid, wsSessId, p->myPanelUuId, "myStringId", kStringId, "stringClass", "String", "a string value" )) != kOkRC ) if((rc = createStr( uiH, uuid, p->myPanelUuId, "myStringId", kStringId, chanId, "stringClass", "String", "a string value" )) != kOkRC )
goto errLabel; goto errLabel;
if((rc = createNumb( uiH, uuid, wsSessId, p->myPanelUuId, "myIntegerId", kIntegerId, "integerClass", "Integer", 0, 100, 1, 0, 10 )) != kOkRC ) if((rc = createNumb( uiH, uuid, p->myPanelUuId, "myIntegerId", kIntegerId, chanId, "integerClass", "Integer", 0, 100, 1, 0, 10 )) != kOkRC )
goto errLabel; goto errLabel;
if((rc = createNumb( uiH, uuid, wsSessId, p->myPanelUuId, "myFloatId", kFloatId, "floatClass", "Float", 0.53, 100.97, 1.0, 5, 10.0 )) != kOkRC ) if((rc = createNumb( uiH, uuid, p->myPanelUuId, "myFloatId", kFloatId, chanId, "floatClass", "Float", 0.53, 100.97, 1.0, 5, 10.0 )) != kOkRC )
goto errLabel; goto errLabel;
if((rc = createProg( uiH, uuid, wsSessId, p->myPanelUuId, "myProgressId", kProgressId, "progressClass", "Progress", 0, 10, 5 )) != kOkRC ) if((rc = createProg( uiH, uuid, p->myPanelUuId, "myProgressId", kProgressId, chanId, "progressClass", "Progress", 0, 10, 5 )) != kOkRC )
goto errLabel; goto errLabel;
if((rc = createLog( uiH, p->logUuId, p->myPanelUuId, "myLogId", kLogId, chanId, "logClass", "My Log (click toggles auto-scroll)" )) != kOkRC )
if((rc = createLog( uiH, p->logUuId, wsSessId, p->myPanelUuId, "myLogId", kLogId, "logClass", "My Log (click toggles auto-scroll)" )) != kOkRC )
goto errLabel; goto errLabel;
errLabel: errLabel:
@ -137,7 +136,7 @@ namespace cw
} }
rc_t _insert_list_ele( ui_test_t* p, unsigned wsSessId ) rc_t _insert_list_ele( ui_test_t* p )
{ {
rc_t rc = kOkRC; rc_t rc = kOkRC;
@ -148,16 +147,16 @@ namespace cw
printf("list uuid:%i\n",listUuId); printf("list uuid:%i\n",listUuId);
rc = createFromObject( uiH, p->listEleCfg, wsSessId, listUuId ); rc = createFromObject( uiH, p->listEleCfg, listUuId, kInvalidId );
} }
return rc; return rc;
} }
rc_t _insert_log_line( ui_test_t* p, unsigned wsSessId, const char* text ) rc_t _insert_log_line( ui_test_t* p, const char* text )
{ {
return ui::setLogLine( srv::uiHandle(p->wsUiSrvH), wsSessId, p->logUuId, text ); return ui::setLogLine( srv::uiHandle(p->wsUiSrvH), p->logUuId, text );
} }
rc_t _handleUiValueMsg( ui_test_t* p, unsigned wsSessId, unsigned parentAppId, unsigned uuId, unsigned appId, const value_t* v ) rc_t _handleUiValueMsg( ui_test_t* p, unsigned wsSessId, unsigned parentAppId, unsigned uuId, unsigned appId, const value_t* v )
@ -173,7 +172,7 @@ namespace cw
case kCheckId: case kCheckId:
printf("Check:%i\n", v->u.b); printf("Check:%i\n", v->u.b);
p->appCheckFl = v->u.b; p->appCheckFl = v->u.b;
_insert_log_line( p, wsSessId, "check!\n" ); _insert_log_line( p, "check!\n" );
break; break;
case kSelectId: case kSelectId:
@ -195,7 +194,7 @@ namespace cw
handle_t uiH = srv::uiHandle(p->wsUiSrvH); handle_t uiH = srv::uiHandle(p->wsUiSrvH);
unsigned progUuId = findElementUuId( uiH, p->myPanelUuId, kProgressId ); unsigned progUuId = findElementUuId( uiH, p->myPanelUuId, kProgressId );
sendValueInt( uiH, wsSessId, progUuId, v->u.i ); sendValueInt( uiH, progUuId, v->u.i );
} }
break; break;
@ -224,7 +223,7 @@ namespace cw
case kPanelCheck2Id: case kPanelCheck2Id:
printf("check 1: %i\n",v->u.b); printf("check 1: %i\n",v->u.b);
p->appCheck1Fl = v->u.b; p->appCheck1Fl = v->u.b;
_insert_list_ele( p, wsSessId ); _insert_list_ele( p );
break; break;
case kPanelFloaterId: case kPanelFloaterId:
@ -249,43 +248,43 @@ namespace cw
switch( appId ) switch( appId )
{ {
case kCheckId: case kCheckId:
sendValueBool( uiHandle( p->wsUiSrvH ), wsSessId, uuId, p->appCheckFl ); sendValueBool( uiHandle( p->wsUiSrvH ), uuId, p->appCheckFl );
break; break;
case kSelectId: case kSelectId:
sendValueInt( uiHandle( p->wsUiSrvH ), wsSessId, uuId, p->appSelOptAppId ); sendValueInt( uiHandle( p->wsUiSrvH ), uuId, p->appSelOptAppId );
break; break;
case kStringId: case kStringId:
sendValueString( uiHandle( p->wsUiSrvH ), wsSessId, uuId, p->appString ); sendValueString( uiHandle( p->wsUiSrvH ), uuId, p->appString );
break; break;
case kIntegerId: case kIntegerId:
sendValueInt( uiHandle( p->wsUiSrvH ), wsSessId, uuId, p->appInteger ); sendValueInt( uiHandle( p->wsUiSrvH ), uuId, p->appInteger );
break; break;
case kFloatId: case kFloatId:
sendValueFloat( uiHandle( p->wsUiSrvH ), wsSessId, uuId, p->appFloat ); sendValueFloat( uiHandle( p->wsUiSrvH ), uuId, p->appFloat );
break; break;
case kProgressId: case kProgressId:
sendValueInt( uiHandle( p->wsUiSrvH ), wsSessId, uuId, p->appProgress ); sendValueInt( uiHandle( p->wsUiSrvH ), uuId, p->appProgress );
break; break;
case kPanelCheck1Id: case kPanelCheck1Id:
sendValueBool( uiHandle( p->wsUiSrvH ), wsSessId, uuId, p->appCheck1Fl); sendValueBool( uiHandle( p->wsUiSrvH ), uuId, p->appCheck1Fl);
break; break;
case kPanelCheck2Id: case kPanelCheck2Id:
sendValueBool( uiHandle( p->wsUiSrvH ), wsSessId, uuId, p->appCheck2Fl); sendValueBool( uiHandle( p->wsUiSrvH ), uuId, p->appCheck2Fl);
break; break;
case kPanelFloaterId: case kPanelFloaterId:
sendValueFloat( uiHandle( p->wsUiSrvH ), wsSessId, uuId, p->appNumb ); sendValueFloat( uiHandle( p->wsUiSrvH ), uuId, p->appNumb );
break; break;
case kSelId: case kSelId:
sendValueInt( uiHandle( p->wsUiSrvH ), wsSessId, uuId, p->appSelId ); sendValueInt( uiHandle( p->wsUiSrvH ), uuId, p->appSelId );
break; break;
} }
return rc; return rc;
@ -294,7 +293,7 @@ namespace cw
// This function is called by the websocket with messages coming from a remote UI. // This function is called by the websocket with messages coming from a remote UI.
rc_t _uiTestCallback( void* cbArg, unsigned wsSessId, opId_t opId, unsigned parentAppId, unsigned uuId, unsigned appId, const value_t* v ) rc_t _uiTestCallback( void* cbArg, unsigned wsSessId, opId_t opId, unsigned parentAppId, unsigned uuId, unsigned appId, unsigned chanId, const value_t* v )
{ {
ui_test_t* p = (ui_test_t*)cbArg; ui_test_t* p = (ui_test_t*)cbArg;
@ -316,6 +315,17 @@ namespace cw
_handleUiValueMsg( p, wsSessId, parentAppId, uuId, appId, v ); _handleUiValueMsg( p, wsSessId, parentAppId, uuId, appId, v );
break; break;
case kClickOpId:
{
printf("APP clicked. uu:%i app:%i ch:%i\n",uuId,appId,chanId);
handle_t uiH = srv::uiHandle(p->wsUiSrvH);
bool selectedFl = isSelected(uiH,uuId);
setSelect( uiH, uuId, !selectedFl );
}
break;
case kEchoOpId: case kEchoOpId:
_handleUiEchoMsg( p, wsSessId, parentAppId, uuId, appId ); _handleUiEchoMsg( p, wsSessId, parentAppId, uuId, appId );
break; break;

View File

@ -138,3 +138,7 @@ label {
background-color: PowderBlue; background-color: PowderBlue;
} }
.uiSelected {
border: 1px solid red;
}

View File

@ -237,6 +237,14 @@ function ui_send_int_value( ele, value ) { ui_send_value(ele,'i',value); }
function ui_send_float_value( ele, value ) { ui_send_value(ele,'f',value); } function ui_send_float_value( ele, value ) { ui_send_value(ele,'f',value); }
function ui_send_string_value( ele, value ) { ui_send_value(ele,'s',value); } function ui_send_string_value( ele, value ) { ui_send_value(ele,'s',value); }
function ui_send_click( ele )
{
console.log("click " + ele.id )
ws_send("click " + ele.id )
}
function ui_send_echo( ele ) function ui_send_echo( ele )
{ {
ws_send("echo " + ele.id ) ws_send("echo " + ele.id )
@ -267,6 +275,11 @@ function ui_get_parent( parentId )
return parent_ele; return parent_ele;
} }
function ui_on_click( ele, evt )
{
ui_send_click(ele);
evt.stopPropagation();
}
function ui_create_ele( parent_ele, ele_type, d, dfltClassName ) function ui_create_ele( parent_ele, ele_type, d, dfltClassName )
{ {
@ -289,6 +302,9 @@ function ui_create_ele( parent_ele, ele_type, d, dfltClassName )
else else
ele.appId = null; ele.appId = null;
if( d.hasOwnProperty('clickable') )
ui_set_clickable( ele, d.clickable );
//console.log("Created: " + ele_type + " parent:" + d.parentUuId + " id:" + ele.id + " appId:" + ele.appId) //console.log("Created: " + ele_type + " parent:" + d.parentUuId + " id:" + ele.id + " appId:" + ele.appId)
parent_ele.appendChild(ele); parent_ele.appendChild(ele);
@ -777,6 +793,7 @@ function ui_create_log( parent_ele, d )
function ui_create_list( parent_ele, d ) function ui_create_list( parent_ele, d )
{ {
d.className = "uiList" d.className = "uiList"
console.log(d)
var list_ele = ui_create_ctl( parent_ele, "div", d.title, d, "uiList" ) var list_ele = ui_create_ctl( parent_ele, "div", d.title, d, "uiList" )
return list_ele return list_ele
@ -848,11 +865,37 @@ function ui_set_value( d )
break break
default: default:
ui_error("Unknown UI element type: " + d.type ) ui_error("Unknown UI element type on set value: " + d.type )
} }
} }
} }
function ui_set_select( ele, enableFl )
{
let selectClassLabel = " uiSelected"
let isSelectSetFl = ele.className.includes(selectClassLabel)
if( enableFl != isSelectSetFl )
{
if( enableFl )
ele.className += selectClassLabel;
else
ele.className = ele.className.replace(selectClassLabel, "");
}
}
function ui_set_clickable( ele, enableFl )
{
ele.clickableFl = enableFl
if(enableFl)
ele.onclick = function( evt ){ ui_on_click( this, evt ); }
else
ele.onclick = null
}
function ui_set( d ) function ui_set( d )
{ {
//console.log(d) //console.log(d)
@ -860,24 +903,26 @@ function ui_set( d )
if( ele == null ) if( ele == null )
console.log("ele not found"); console.log("ele not found");
else
if( !ele.hasOwnProperty("uiEleType") )
console.log("No type");
if( ele != null && ele.hasOwnProperty("uiEleType")) if( ele != null)
{ {
//console.log("found: "+ele.uiEleType) switch( d.type )
switch( ele.uiEleType )
{ {
case "number": case "number_range":
ui_set_number_range(ele, d) ui_set_number_range(ele, d)
break; break;
case "progress": case "progress_range":
ui_set_prog_range(ele, d) ui_set_prog_range(ele, d)
break; break;
case "select":
ui_set_select(ele,d.enableFl)
break
case "clickable":
ui_set_clickable(ele,d.enableFl)
break
} }
} }
} }

View File

@ -34,7 +34,7 @@
row: { row: {
list:{ name: myListId, title:"My List" }, list:{ name: myListId, title:"My List", clickable: 1 },
}, },