cwUi.h/cpp, cwUiTest.cpp, html/uiTest : Initial working version of cwUI.
This commit is contained in:
parent
d3d4c7c6f9
commit
b6d716e8ff
376
cwUi.cpp
376
cwUi.cpp
@ -19,7 +19,7 @@ namespace cw
|
|||||||
struct appIdMapRecd_str* link;
|
struct appIdMapRecd_str* link;
|
||||||
unsigned parentAppId;
|
unsigned parentAppId;
|
||||||
unsigned appId;
|
unsigned appId;
|
||||||
char* jsId;
|
char* eleName;
|
||||||
} appIdMapRecd_t;
|
} appIdMapRecd_t;
|
||||||
|
|
||||||
|
|
||||||
@ -28,7 +28,7 @@ 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
|
||||||
char* jsId; // javascript id
|
char* eleName; // javascript id
|
||||||
} ele_t;
|
} ele_t;
|
||||||
|
|
||||||
typedef struct ui_str
|
typedef struct ui_str
|
||||||
@ -52,7 +52,7 @@ namespace cw
|
|||||||
for(unsigned i=0; i<p->eleN; ++i)
|
for(unsigned i=0; i<p->eleN; ++i)
|
||||||
{
|
{
|
||||||
ele_t* e = p->eleA[i];
|
ele_t* e = p->eleA[i];
|
||||||
printf("%15s u:%i : u:%i a:%i %s\n",e->parent==nullptr?"<null>" : e->parent->jsId,e->parent==nullptr? -1 :e->parent->uuId,e->uuId,e->appId,e->jsId);
|
printf("%15s u:%i : u:%i a:%i %s\n",e->parent==nullptr?"<null>" : e->parent->eleName,e->parent==nullptr? -1 :e->parent->uuId,e->uuId,e->appId,e->eleName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,7 +66,7 @@ namespace cw
|
|||||||
|
|
||||||
for(unsigned i=0; i<p->eleN; ++i)
|
for(unsigned i=0; i<p->eleN; ++i)
|
||||||
{
|
{
|
||||||
mem::release(p->eleA[i]->jsId);
|
mem::release(p->eleA[i]->eleName);
|
||||||
mem::release(p->eleA[i]);
|
mem::release(p->eleA[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -74,22 +74,23 @@ namespace cw
|
|||||||
while( m!=nullptr )
|
while( m!=nullptr )
|
||||||
{
|
{
|
||||||
appIdMapRecd_t* m0 = m->link;
|
appIdMapRecd_t* m0 = m->link;
|
||||||
mem::release(m->jsId);
|
mem::release(m->eleName);
|
||||||
mem::release(m);
|
mem::release(m);
|
||||||
m = m0;
|
m = m0;
|
||||||
}
|
}
|
||||||
|
|
||||||
mem::release(p->eleA);
|
mem::release(p->eleA);
|
||||||
|
mem::release(p->buf);
|
||||||
mem::release(p);
|
mem::release(p);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
appIdMapRecd_t* _findAppIdMap( ui_t* p, unsigned parentAppId, const char* jsId )
|
appIdMapRecd_t* _findAppIdMap( ui_t* p, unsigned parentAppId, const char* eleName )
|
||||||
{
|
{
|
||||||
appIdMapRecd_t* m = p->appIdMap;
|
appIdMapRecd_t* m = p->appIdMap;
|
||||||
for(; m != nullptr; m=m->link)
|
for(; m != nullptr; m=m->link)
|
||||||
if( m->parentAppId==parentAppId && textCompare(jsId,m->jsId)==0 )
|
if( m->parentAppId==parentAppId && textCompare(eleName,m->eleName)==0 )
|
||||||
return m;
|
return m;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@ -103,41 +104,41 @@ namespace cw
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc_t _allocAppIdMap( ui_t* p, unsigned parentAppId, unsigned appId, const char* jsId )
|
rc_t _allocAppIdMap( ui_t* p, unsigned parentAppId, unsigned appId, const char* eleName )
|
||||||
{
|
{
|
||||||
rc_t rc = kOkRC;
|
rc_t rc = kOkRC;
|
||||||
|
|
||||||
// The 'jsId' must be valid (or there is no reason to create the map.
|
// The 'eleName' must be valid (or there is no reason to create the map.
|
||||||
// (since it will ultimately be used to locate the appId give the parentAppId and jsId)
|
// (since it will ultimately be used to locate the appId give the parentAppId and eleName)
|
||||||
if( jsId == nullptr || strlen(jsId) == 0 )
|
if( eleName == nullptr || strlen(eleName) == 0 )
|
||||||
return cwLogError(kInvalidIdRC,"Registered parent/child app id's must have a valid 'jsId'.");
|
return cwLogError(kInvalidIdRC,"Registered parent/child app id's must have a valid 'eleName'.");
|
||||||
|
|
||||||
// verify that the parent/child pair is unique
|
// verify that the parent/child pair is unique
|
||||||
if( _findAppIdMap(p,parentAppId,appId) != nullptr )
|
if( _findAppIdMap(p,parentAppId,appId) != nullptr )
|
||||||
return cwLogError(kDuplicateRC,"An attempt was made to register a duplicate parent/child appid pair. parentId:%i appId:%i jsId:'%s'.",parentAppId,appId,cwStringNullGuard(jsId));
|
return cwLogError(kDuplicateRC,"An attempt was made to register a duplicate parent/child appid pair. parentId:%i appId:%i eleName:'%s'.",parentAppId,appId,cwStringNullGuard(eleName));
|
||||||
|
|
||||||
// verify that the parent/js pair is unique
|
// verify that the parent/js pair is unique
|
||||||
if( _findAppIdMap(p,parentAppId,jsId) != nullptr )
|
if( _findAppIdMap(p,parentAppId,eleName) != nullptr )
|
||||||
return cwLogError(kDuplicateRC,"An attempt was made to register a duplicate parent app id/js id pair. parentId:%i appId:%i jsId:'%s'.",parentAppId,appId,cwStringNullGuard(jsId));
|
return cwLogError(kDuplicateRC,"An attempt was made to register a duplicate parent app id/js id pair. parentId:%i appId:%i eleName:'%s'.",parentAppId,appId,cwStringNullGuard(eleName));
|
||||||
|
|
||||||
// allocate and link in a new appId map record
|
// allocate and link in a new appId map record
|
||||||
appIdMapRecd_t* m = mem::allocZ<appIdMapRecd_t>();
|
appIdMapRecd_t* m = mem::allocZ<appIdMapRecd_t>();
|
||||||
m->parentAppId = parentAppId;
|
m->parentAppId = parentAppId;
|
||||||
m->appId = appId;
|
m->appId = appId;
|
||||||
m->jsId = mem::duplStr(jsId);
|
m->eleName = mem::duplStr(eleName);
|
||||||
m->link = p->appIdMap;
|
m->link = p->appIdMap;
|
||||||
p->appIdMap = m;
|
p->appIdMap = m;
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
ele_t* _createEle( ui_t* p, ele_t* parent, unsigned appId, const char* jsId )
|
ele_t* _createEle( ui_t* p, ele_t* parent, unsigned appId, const char* eleName )
|
||||||
{
|
{
|
||||||
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->jsId = mem::duplStr(jsId);
|
e->eleName = mem::duplStr(eleName);
|
||||||
|
|
||||||
if( p->eleN == p->eleAllocN )
|
if( p->eleN == p->eleAllocN )
|
||||||
{
|
{
|
||||||
@ -148,6 +149,15 @@ namespace cw
|
|||||||
p->eleA[ p->eleN ] = e;
|
p->eleA[ p->eleN ] = e;
|
||||||
p->eleN += 1;
|
p->eleN += 1;
|
||||||
|
|
||||||
|
// if the given appId was not valid ...
|
||||||
|
if( appId == kInvalidId && parent != nullptr )
|
||||||
|
{
|
||||||
|
appIdMapRecd_t* m;
|
||||||
|
// ... then try to look it up from the appIdMap.
|
||||||
|
if((m = _findAppIdMap( p, parent->appId, eleName)) != nullptr )
|
||||||
|
e->appId = m->appId;
|
||||||
|
}
|
||||||
|
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -163,33 +173,57 @@ namespace cw
|
|||||||
return p->eleA[ uuId ];
|
return p->eleA[ uuId ];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Given a parent UuId and a javascript id find the associated ele
|
ele_t* _eleNameToEle( ui_t* p, const char* eleName, bool errorFl=true )
|
||||||
ele_t* _parentUuId_JsId_ToEle( ui_t* p, unsigned parentUuId, const char* jsId, bool errorFl=true )
|
|
||||||
{
|
{
|
||||||
for(unsigned i=0; i<p->eleN; ++i)
|
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)) && (strcmp(p->eleA[i]->jsId,jsId) == 0))
|
if( textCompare(p->eleA[i]->eleName,eleName) == 0 )
|
||||||
return p->eleA[i];
|
return p->eleA[i];
|
||||||
|
|
||||||
if( errorFl )
|
if( errorFl )
|
||||||
cwLogError(kInvalidIdRC,"The element with parent uuid:%i and jsId:%s is not found.",parentUuId,jsId);
|
cwLogError(kInvalidIdRC,"The element with eleName:%s not found.",cwStringNullGuard(eleName));
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned _findElementUuId( ui_t* p, const char* jsId )
|
// 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)
|
for(unsigned i=0; i<p->eleN; ++i)
|
||||||
if( strcmp(p->eleA[i]->jsId,jsId) == 0 )
|
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 )
|
||||||
|
{
|
||||||
|
for(unsigned i=0; i<p->eleN; ++i)
|
||||||
|
if( strcmp(p->eleA[i]->eleName,eleName) == 0 )
|
||||||
return p->eleA[i]->uuId;
|
return p->eleA[i]->uuId;
|
||||||
|
|
||||||
return kInvalidId;
|
return kInvalidId;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* _findEleJsId( ui_t* p, unsigned uuId )
|
const char* _findEleEleName( ui_t* p, unsigned uuId )
|
||||||
{
|
{
|
||||||
for(unsigned i=0; i<p->eleN; ++i)
|
for(unsigned i=0; i<p->eleN; ++i)
|
||||||
if( p->eleA[i]->uuId == uuId )
|
if( p->eleA[i]->uuId == uuId )
|
||||||
return p->eleA[i]->jsId;
|
return p->eleA[i]->eleName;
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@ -234,11 +268,10 @@ namespace cw
|
|||||||
}
|
}
|
||||||
|
|
||||||
template< typename... ARGS>
|
template< typename... ARGS>
|
||||||
rc_t _createOneEle( ui_t* p, unsigned& uuIdRef, const char* eleTypeStr, unsigned wsSessId, unsigned parentUuId, const char* jsId, 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, const char* clas, const char* title, ARGS&&... args )
|
||||||
{
|
{
|
||||||
// { op:create, parent:my_parent_id, value:{ button:{ jsId:my_jsId, appId:appId, uuId:uuId, class:clas, title:'my title' } }
|
// { op:create, parent:my_parent_id, value:{ button:{ eleName:my_eleName, appId:appId, uuId:uuId, class:clas, title:'my title' } }
|
||||||
rc_t rc = kOkRC;
|
rc_t rc = kOkRC;
|
||||||
const char* parentJsId = "";
|
|
||||||
ele_t* newEle = nullptr;
|
ele_t* newEle = nullptr;
|
||||||
ele_t* parentEle = nullptr;
|
ele_t* parentEle = nullptr;
|
||||||
//const unsigned bufN = 1024; // TODO: use preallocated buffer
|
//const unsigned bufN = 1024; // TODO: use preallocated buffer
|
||||||
@ -253,20 +286,19 @@ namespace cw
|
|||||||
if(( parentEle = _uuIdToEle(p, parentUuId )) == nullptr )
|
if(( parentEle = _uuIdToEle(p, parentUuId )) == nullptr )
|
||||||
return cwLogError( kInvalidArgRC, "Unable to locate the parent element (id:%i).", parentUuId );
|
return cwLogError( kInvalidArgRC, "Unable to locate the parent element (id:%i).", parentUuId );
|
||||||
|
|
||||||
// get the parent jsId
|
|
||||||
parentJsId = parentEle->jsId;
|
|
||||||
|
|
||||||
// create the local representation of the new element
|
// create the local representation of the new element
|
||||||
newEle = _createEle( p, parentEle, appId, jsId );
|
newEle = _createEle( p, parentEle, appId, eleName );
|
||||||
|
|
||||||
// form the create json message string
|
// form the create json message string
|
||||||
unsigned i = snprintf( p->buf, p->bufN, "{ \"op\":\"create\", \"parent\":\"%s\", \"children\":{ \"%s\":{ \"jsId\":\"%s\", \"appId\":%i, \"uuId\":%i, \"class\":\"%s\", \"title\":\"%s\" ", parentJsId, eleTypeStr, jsId, appId, newEle->uuId, clas, title );
|
//unsigned i = snprintf( p->buf, p->bufN, "{ \"op\":\"create\", \"parent\":\"%s\", \"children\":{ \"%s\":{ \"eleName\":\"%s\", \"appId\":%i, \"uuId\":%i, \"class\":\"%s\", \"title\":\"%s\" ", parentEleName, eleTypeStr, eleName, appId, newEle->uuId, clas, title );
|
||||||
|
unsigned i = snprintf( p->buf, p->bufN, "{ \"op\":\"create\", \"parentUuId\":\"%i\", \"type\":\"%s\", \"eleName\":\"%s\", \"appId\":\"%i\", \"uuId\":%i, \"class\":\"%s\", \"title\":\"%s\" ", parentEle->uuId, eleTypeStr, eleName, appId, newEle->uuId, clas, title );
|
||||||
|
|
||||||
|
|
||||||
// add the UI specific attributes
|
// add the UI specific attributes
|
||||||
i += format_attributes(p->buf+i, p->bufN-i, 0, std::forward<ARGS>(args)...);
|
i += format_attributes(p->buf+i, p->bufN-i, 0, std::forward<ARGS>(args)...);
|
||||||
|
|
||||||
// terminate the message
|
// terminate the message
|
||||||
i += toText(p->buf+i, p->bufN-i, "}}}");
|
i += toText(p->buf+i, p->bufN-i, "}");
|
||||||
|
|
||||||
if( i >= p->bufN )
|
if( i >= p->bufN )
|
||||||
return cwLogError(kBufTooSmallRC,"The UI message formatting buffer is too small. (size:%i bytes)", p->bufN);
|
return cwLogError(kBufTooSmallRC,"The UI message formatting buffer is too small. (size:%i bytes)", p->bufN);
|
||||||
@ -281,93 +313,169 @@ namespace cw
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc_t _decorateObj( ui_t* p, object_t* o )
|
ele_t* _findOrCreateEle( ui_t* p, ele_t* parentEle, const char* eleName )
|
||||||
|
{
|
||||||
|
ele_t* ele;
|
||||||
|
if((ele = _parentUuId_EleName_ToEle( p, parentEle->uuId, eleName, false )) == nullptr )
|
||||||
|
ele = _createEle(p, parentEle, kInvalidId, eleName );
|
||||||
|
|
||||||
|
return ele;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc_t _createElementsFromChildList( ui_t* p, object_t* po, unsigned wsSessId, ele_t* parentEle );
|
||||||
|
|
||||||
|
//
|
||||||
|
rc_t _createEleFromRsrsc( ui_t* p, ele_t* parentEle, const char* eleType, object_t* o, unsigned wsSessId )
|
||||||
{
|
{
|
||||||
rc_t rc = kOkRC;
|
rc_t rc = kOkRC;
|
||||||
const object_t* oo;
|
object_t* co = nullptr;
|
||||||
//ele_t* parent_ele;
|
ele_t* ele = nullptr;
|
||||||
const char* jsId;
|
char* eleName = nullptr;
|
||||||
|
|
||||||
// find the parent pair
|
if( !o->is_dict() )
|
||||||
if((oo = o->find( "parent", kNoRecurseFl | kOptionalFl)) != nullptr )
|
return cwLogError(kSyntaxErrorRC,"All ui element resource records must be dictionaries.");
|
||||||
|
|
||||||
|
// if this object has a 'children' list then unlink it an save it for later
|
||||||
|
if((co = o->find("children", kNoRecurseFl | kOptionalFl)) != nullptr )
|
||||||
{
|
{
|
||||||
|
co = co->parent;
|
||||||
|
co->unlink();
|
||||||
}
|
}
|
||||||
|
|
||||||
// find the parent JsId
|
// get the ui ele name
|
||||||
if((rc = oo->value(jsId)) != kOkRC )
|
if((rc = o->get("name",eleName)) != kOkRC )
|
||||||
{
|
{
|
||||||
|
rc = cwLogError(rc,"The UI element name could not be read.");
|
||||||
|
goto errLabel;
|
||||||
}
|
}
|
||||||
|
|
||||||
// find the parent element
|
// get or create the ele record to associate with this ele
|
||||||
//if((parent_ele = _jsIdToEle( p, jsId )) == nullptr )
|
if((ele = _findOrCreateEle( p, parentEle, eleName )) == nullptr )
|
||||||
//{
|
{
|
||||||
//}
|
rc = cwLogError(kOpFailRC,"The local element '%s' could not be created.",cwStringNullGuard(eleName));
|
||||||
|
goto errLabel;
|
||||||
|
|
||||||
return rc;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( o->insertPair("uuId",ele->uuId) == nullptr )
|
||||||
rc_t _createFromObj( ui_t* p, object_t* o, unsigned wsSessId, unsigned parentUuId )
|
|
||||||
{
|
{
|
||||||
rc_t rc = kOkRC;
|
rc = cwLogError(kOpFailRC,"The 'uuid' node insertion failed on UI element '%s'.",cwStringNullGuard(eleName));
|
||||||
const char* parentJsId = "";
|
goto errLabel;
|
||||||
const int kBufN = 512; // TODO: preallocate this buffer as part of ui_t.
|
|
||||||
char buf0[ kBufN ];
|
|
||||||
char buf1[ kBufN ];
|
|
||||||
|
|
||||||
// if a parentUuid was given ...
|
|
||||||
if( parentUuId != kInvalidId )
|
|
||||||
{
|
|
||||||
// ... then find the associated JS id
|
|
||||||
if((parentJsId = _findEleJsId( p, parentUuId )) == nullptr )
|
|
||||||
return cwLogError(kInvalidIdRC, "The JS id associated with the uuid '%i' could not be found for an resource object.", parentUuId );
|
|
||||||
}
|
}
|
||||||
else // if no parentUuid was given then look for one in the resource
|
|
||||||
|
if( ele->appId != kInvalidId )
|
||||||
{
|
{
|
||||||
// get the parent JS id from the cfg object
|
if( o->insertPair("appId",ele->appId) == nullptr )
|
||||||
rc = o->get("parent",parentJsId,kNoRecurseFl | kOptionalFl);
|
|
||||||
|
|
||||||
switch(rc)
|
|
||||||
{
|
{
|
||||||
case kOkRC:
|
rc = cwLogError(kOpFailRC,"The 'appId' node insertion failed on UI element '%s'.",cwStringNullGuard(eleName));
|
||||||
// get a pointer to the jsId from the local list (the copy in the object is about to be deleted)
|
|
||||||
parentJsId = _findEleJsId( p, _findElementUuId(p,parentJsId));
|
|
||||||
|
|
||||||
//remove the parent link
|
|
||||||
o->find("parent")->parent->free();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case kLabelNotFoundRC:
|
|
||||||
parentJsId = _findEleJsId( p, kRootUuId );
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
rc = cwLogError(rc,"The resource object parent id '%s' could not be found.", parentJsId );
|
|
||||||
goto errLabel;
|
goto errLabel;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// form the msg string from the resource
|
if( o->insertPair("parentUuId",parentEle->uuId) == nullptr )
|
||||||
if( o->to_string( buf0, kBufN ) >= kBufN )
|
{
|
||||||
return cwLogError(kBufTooSmallRC,"The resource object string buffer is too small (buf bytes:%i).",kBufN);
|
rc = cwLogError(kOpFailRC,"The 'parentUuId' node insertion failed on UI element '%s'.",cwStringNullGuard(eleName));
|
||||||
|
goto errLabel;
|
||||||
|
}
|
||||||
|
|
||||||
printf("buf0: %s\n",buf0);
|
if( o->insertPair("op","create") == nullptr )
|
||||||
if( snprintf( buf1, kBufN, "{ \"op\":\"create\", \"parent\":\"%s\", \"children\":%s }", parentJsId, buf0 ) >= kBufN )
|
{
|
||||||
return cwLogError(kBufTooSmallRC,"The resource object string buffer is too small (buf bytes:%i).",kBufN);
|
rc = cwLogError(kOpFailRC,"The 'op' node insertion failed on UI element '%s'.",cwStringNullGuard(eleName));
|
||||||
|
goto errLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( o->insertPair("type",eleType) == nullptr )
|
||||||
|
{
|
||||||
|
rc = cwLogError(kOpFailRC,"The 'eleType' node insertion failed on UI element '%s'.",cwStringNullGuard(eleName));
|
||||||
|
goto errLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( o->to_string(p->buf,p->bufN) >= p->bufN )
|
||||||
|
{
|
||||||
|
rc = cwLogError(kOpFailRC,"Conversion to JSON string failed on UI element '%s'.",cwStringNullGuard(eleName));
|
||||||
|
goto errLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("%s\n",p->buf);
|
||||||
|
|
||||||
|
if((rc = _websockSend( p, wsSessId, p->buf )) != kOkRC )
|
||||||
|
{
|
||||||
|
rc = cwLogError(rc,"The creation request send failed on UI element '%s'.", cwStringNullGuard(eleName));
|
||||||
|
goto errLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// send the msg string
|
// if this element has a list of children then create them here
|
||||||
printf("buf1: %s\n",buf1);
|
if( co != nullptr )
|
||||||
|
rc = _createElementsFromChildList(p, co->pair_value(), wsSessId, ele );
|
||||||
rc = _websockSend( p, wsSessId, buf1 );
|
|
||||||
|
|
||||||
|
|
||||||
errLabel:
|
errLabel:
|
||||||
|
if( co != nullptr )
|
||||||
|
co->free();
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 'od' is an object dictionary where each pair in the dictionary has
|
||||||
|
// the form: 'eleType':{ <object> }
|
||||||
|
rc_t _createElementsFromChildList( ui_t* p, object_t* po, unsigned wsSessId, ele_t* parentEle )
|
||||||
|
{
|
||||||
|
rc_t rc = kOkRC;
|
||||||
|
|
||||||
|
if( !po->is_dict() )
|
||||||
|
return cwLogError(kSyntaxErrorRC,"All UI resource elements must be containers.");
|
||||||
|
|
||||||
|
unsigned childN = po->child_count();
|
||||||
|
|
||||||
|
for(unsigned i=0; i<childN; ++i)
|
||||||
|
{
|
||||||
|
object_t* o = po->child_ele(i);
|
||||||
|
|
||||||
|
if( !o->is_pair() )
|
||||||
|
return cwLogError(kSyntaxErrorRC,"All object dictionary children must be pairs.");
|
||||||
|
|
||||||
|
if((rc = _createEleFromRsrsc(p, parentEle, o->pair_label(), o->pair_value(), wsSessId )) != kOkRC )
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc_t _createFromObj( ui_t* p, object_t* o, unsigned wsSessId, unsigned parentUuId )
|
||||||
|
{
|
||||||
|
rc_t rc = kOkRC;
|
||||||
|
object_t* po = nullptr;
|
||||||
|
ele_t* parentEle = nullptr;
|
||||||
|
char* eleName = nullptr;
|
||||||
|
|
||||||
|
// locate the the 'parent' ele name value object
|
||||||
|
if((po = o->find("parent",kNoRecurseFl | kOptionalFl)) == nullptr )
|
||||||
|
return cwLogError(kSyntaxErrorRC,"UI resources must have a root 'parent' value.");
|
||||||
|
|
||||||
|
|
||||||
|
// get the parent element name
|
||||||
|
if((rc = po->value(eleName)) != kOkRC )
|
||||||
|
return cwLogError(kOpFailRC,"The root 'parent' value could not be accessed.");
|
||||||
|
|
||||||
|
// find the parent element
|
||||||
|
if((parentEle = _parentUuId_EleName_ToEle( p, parentUuId, eleName )) == nullptr )
|
||||||
|
return cwLogError(kSyntaxErrorRC,"A parent UI element named '%s' could not be found.",cwStringNullGuard(eleName));
|
||||||
|
|
||||||
|
// unlink the 'parent' pair
|
||||||
|
po = po->parent;
|
||||||
|
|
||||||
|
po->unlink();
|
||||||
|
|
||||||
|
rc = _createElementsFromChildList( p, o, wsSessId, parentEle );
|
||||||
|
|
||||||
|
po->free();
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ele_t* _parse_value_msg( ui_t* p, value_t& valueRef, const char* msg )
|
ele_t* _parse_value_msg( ui_t* p, value_t& valueRef, const char* msg )
|
||||||
{
|
{
|
||||||
rc_t rc = kOkRC;
|
rc_t rc = kOkRC;
|
||||||
@ -449,7 +557,7 @@ namespace cw
|
|||||||
{
|
{
|
||||||
rc_t rc = kOkRC;
|
rc_t rc = kOkRC;
|
||||||
|
|
||||||
unsigned i = snprintf(p->buf,p->bufN,"{ \"op\":\"set_app_id\", \"parentUuId\":%i, \"jsId\":\"%s\", \"appId\":%i, \"uuId\":%i }", ele->parent->uuId, ele->jsId, ele->parent->appId, ele->appId );
|
unsigned i = snprintf(p->buf,p->bufN,"{ \"op\":\"set_app_id\", \"parentUuId\":%i, \"eleName\":\"%s\", \"appId\":%i, \"uuId\":%i }", ele->parent->uuId, ele->eleName, ele->parent->appId, ele->appId );
|
||||||
|
|
||||||
if( i >= p->bufN )
|
if( i >= p->bufN )
|
||||||
return cwLogError(kBufTooSmallRC,"The 'app_id' msg formatting buffer is too small (%i bytes).", p->bufN);
|
return cwLogError(kBufTooSmallRC,"The 'app_id' msg formatting buffer is too small (%i bytes).", p->bufN);
|
||||||
@ -475,10 +583,10 @@ namespace cw
|
|||||||
|
|
||||||
const char* s0 = nextNonWhiteChar(msg + strlen("register"));
|
const char* s0 = nextNonWhiteChar(msg + strlen("register"));
|
||||||
|
|
||||||
const char* jsId = nextNonWhiteChar(nextWhiteChar(s0));
|
const char* eleName = nextNonWhiteChar(nextWhiteChar(s0));
|
||||||
|
|
||||||
// verifity the message tokens
|
// verifity the message tokens
|
||||||
if( s0 == nullptr || jsId == nullptr )
|
if( s0 == nullptr || eleName == nullptr )
|
||||||
{
|
{
|
||||||
cwLogError(kSyntaxErrorRC, "'register' msg format error: '%s' is not a valid message.", cwStringNullGuard(msg) );
|
cwLogError(kSyntaxErrorRC, "'register' msg format error: '%s' is not a valid message.", cwStringNullGuard(msg) );
|
||||||
goto errLabel;
|
goto errLabel;
|
||||||
@ -499,15 +607,15 @@ namespace cw
|
|||||||
}
|
}
|
||||||
|
|
||||||
// if the child element does not already exist
|
// if the child element does not already exist
|
||||||
if(( ele = _parentUuId_JsId_ToEle( p, parentUuId, jsId, false )) == nullptr )
|
if(( ele = _parentUuId_EleName_ToEle( p, parentUuId, eleName, false )) == nullptr )
|
||||||
{
|
{
|
||||||
// look up the parent/jsId pair map
|
// look up the parent/eleName pair map
|
||||||
appIdMapRecd_t* m = _findAppIdMap( p, parentEle->appId, jsId );
|
appIdMapRecd_t* m = _findAppIdMap( p, parentEle->appId, eleName );
|
||||||
|
|
||||||
// create the ele
|
// create the ele
|
||||||
ele = _createEle( p, parentEle, m==nullptr ? kInvalidId : m->appId, jsId );
|
ele = _createEle( p, parentEle, m==nullptr ? kInvalidId : m->appId, eleName );
|
||||||
|
|
||||||
printf("creating: parent uuid:%i js:%s \n", parentUuId,jsId);
|
printf("creating: parent uuid:%i js:%s \n", parentUuId,eleName);
|
||||||
|
|
||||||
// notify the app of the new ele's uuid and appId
|
// notify the app of the new ele's uuid and appId
|
||||||
if( m != nullptr )
|
if( m != nullptr )
|
||||||
@ -516,7 +624,7 @@ namespace cw
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
printf("parent uuid:%i js:%s already exists.\n", parentUuId,jsId);
|
printf("parent uuid:%i js:%s already exists.\n", parentUuId,eleName);
|
||||||
}
|
}
|
||||||
|
|
||||||
if( ele != nullptr )
|
if( ele != nullptr )
|
||||||
@ -585,10 +693,6 @@ namespace cw
|
|||||||
// Pass on the 'init' msg to the app.
|
// Pass on the 'init' msg to the app.
|
||||||
p->cbFunc( p->cbArg, wsSessId, opId, kInvalidId, kInvalidId, kInvalidId, nullptr );
|
p->cbFunc( p->cbArg, wsSessId, opId, kInvalidId, kInvalidId, kInvalidId, nullptr );
|
||||||
|
|
||||||
// The UI is initialized - begin the id update process
|
|
||||||
if( _websockSend( p, wsSessId, "{ \"op\":\"begin_app_id_update\" }" ) != kOkRC )
|
|
||||||
cwLogError(kOpFailRC,"'begin_app_id_update' transmit failed.");
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case kValueOpId:
|
case kValueOpId:
|
||||||
@ -684,7 +788,7 @@ cw::rc_t cw::ui::createUi(
|
|||||||
p->bufN = fmtBufByteN;
|
p->bufN = fmtBufByteN;
|
||||||
|
|
||||||
// create the root element
|
// create the root element
|
||||||
if((ele = _createEle(p, nullptr, kRootEleAppId, "uiDivId" )) == nullptr || ele->uuId != kRootUuId )
|
if((ele = _createEle(p, nullptr, kRootAppId, "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;
|
||||||
@ -739,22 +843,22 @@ cw::rc_t cw::ui::destroyUi( handle_t& h )
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned cw::ui::findElementAppId( handle_t h, unsigned parentUuId, const char* jsId )
|
unsigned cw::ui::findElementAppId( handle_t h, unsigned parentUuId, const char* eleName )
|
||||||
{
|
{
|
||||||
ui_t* p = _handleToPtr(h);
|
ui_t* p = _handleToPtr(h);
|
||||||
|
|
||||||
for(unsigned i=0; i<p->eleN; ++i)
|
for(unsigned i=0; i<p->eleN; ++i)
|
||||||
if( p->eleA[i]->parent->uuId==parentUuId && strcmp(p->eleA[i]->jsId,jsId) == 0 )
|
if( p->eleA[i]->parent->uuId==parentUuId && strcmp(p->eleA[i]->eleName,eleName) == 0 )
|
||||||
return p->eleA[i]->appId;
|
return p->eleA[i]->appId;
|
||||||
return kInvalidId;
|
return kInvalidId;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned cw::ui::findElementUuId( handle_t h, unsigned parentUuId, const char* jsId )
|
unsigned cw::ui::findElementUuId( handle_t h, unsigned parentUuId, const char* eleName )
|
||||||
{
|
{
|
||||||
ui_t* p = _handleToPtr(h);
|
ui_t* p = _handleToPtr(h);
|
||||||
ele_t* ele;
|
ele_t* ele;
|
||||||
|
|
||||||
if((ele = _parentUuId_JsId_ToEle(p, parentUuId, jsId )) != nullptr )
|
if((ele = _parentUuId_EleName_ToEle(p, parentUuId, eleName )) != nullptr )
|
||||||
return ele->uuId;
|
return ele->uuId;
|
||||||
|
|
||||||
return kInvalidId;
|
return kInvalidId;
|
||||||
@ -770,17 +874,17 @@ unsigned cw::ui::findElementUuId( handle_t h, unsigned parentUuId, unsigned appI
|
|||||||
return kInvalidId;
|
return kInvalidId;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* cw::ui::findElementJsId( handle_t h, unsigned uuId )
|
const char* cw::ui::findElementName( handle_t h, unsigned uuId )
|
||||||
{
|
{
|
||||||
ui_t* p = _handleToPtr(h);
|
ui_t* p = _handleToPtr(h);
|
||||||
return _findEleJsId(p,uuId);
|
return _findEleEleName(p,uuId);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned cw::ui::findElementUuId( handle_t h, const char* jsId )
|
unsigned cw::ui::findElementUuId( handle_t h, const char* eleName )
|
||||||
{
|
{
|
||||||
ui_t* p = _handleToPtr(h);
|
ui_t* p = _handleToPtr(h);
|
||||||
|
|
||||||
return _findElementUuId(p,jsId);
|
return _findElementUuId(p,eleName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -830,34 +934,34 @@ 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* jsId, unsigned appId, const char* clas, const char* title )
|
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 )
|
||||||
{ return _createOneEle( _handleToPtr(h), uuIdRef, "div", wsSessId, parentUuId, jsId, appId, clas, title ); }
|
{ return _createOneEle( _handleToPtr(h), uuIdRef, "div", wsSessId, parentUuId, eleName, appId, clas, title ); }
|
||||||
|
|
||||||
cw::rc_t cw::ui::createTitle( handle_t h, unsigned& uuIdRef, unsigned wsSessId, unsigned parentUuId, const char* jsId, unsigned appId, const char* clas, const char* title )
|
cw::rc_t cw::ui::createTitle( handle_t h, unsigned& uuIdRef, unsigned wsSessId, unsigned parentUuId, const char* eleName, unsigned appId, const char* clas, const char* title )
|
||||||
{ return _createOneEle( _handleToPtr(h), uuIdRef, "option", wsSessId, parentUuId, jsId, appId, clas, title ); }
|
{ return _createOneEle( _handleToPtr(h), uuIdRef, "option", wsSessId, parentUuId, eleName, appId, clas, title ); }
|
||||||
|
|
||||||
cw::rc_t cw::ui::createButton( handle_t h, unsigned& uuIdRef, unsigned wsSessId, unsigned parentUuId, const char* jsId, unsigned appId, const char* clas, const char* 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 )
|
||||||
{ return _createOneEle( _handleToPtr(h), uuIdRef, "button", wsSessId, parentUuId, jsId, appId, clas, title ); }
|
{ return _createOneEle( _handleToPtr(h), uuIdRef, "button", wsSessId, parentUuId, eleName, appId, clas, title ); }
|
||||||
|
|
||||||
cw::rc_t cw::ui::createCheck( handle_t h, unsigned& uuIdRef, unsigned wsSessId, unsigned parentUuId, const char* jsId, unsigned appId, const char* clas, const char* title, bool value )
|
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 )
|
||||||
{ return _createOneEle( _handleToPtr(h), uuIdRef, "check", wsSessId, parentUuId, jsId, appId, clas, title, "value", value ); }
|
{ return _createOneEle( _handleToPtr(h), uuIdRef, "check", wsSessId, parentUuId, eleName, appId, clas, title, "value", value ); }
|
||||||
|
|
||||||
cw::rc_t cw::ui::createSelect( handle_t h, unsigned& uuIdRef, unsigned wsSessId, unsigned parentUuId, const char* jsId, unsigned appId, const char* clas, const char* title )
|
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 )
|
||||||
{ return _createOneEle( _handleToPtr(h), uuIdRef, "select", wsSessId, parentUuId, jsId, appId, clas, title ); }
|
{ return _createOneEle( _handleToPtr(h), uuIdRef, "select", wsSessId, parentUuId, eleName, appId, clas, title ); }
|
||||||
|
|
||||||
cw::rc_t cw::ui::createOption( handle_t h, unsigned& uuIdRef, unsigned wsSessId, unsigned parentUuId, const char* jsId, unsigned appId, const char* clas, const char* 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 )
|
||||||
{ return _createOneEle( _handleToPtr(h), uuIdRef, "option", wsSessId, parentUuId, jsId, appId, clas, title ); }
|
{ return _createOneEle( _handleToPtr(h), uuIdRef, "option", wsSessId, parentUuId, eleName, appId, clas, title ); }
|
||||||
|
|
||||||
cw::rc_t cw::ui::createString( handle_t h, unsigned& uuIdRef, unsigned wsSessId, unsigned parentUuId, const char* jsId, unsigned appId, const char* clas, const char* title, const char* value )
|
cw::rc_t cw::ui::createString( handle_t h, unsigned& uuIdRef, unsigned wsSessId, unsigned parentUuId, const char* eleName, unsigned appId, const char* clas, const char* title, const char* value )
|
||||||
{ return _createOneEle( _handleToPtr(h), uuIdRef, "string", wsSessId, parentUuId, jsId, appId, clas, title, "value", value ); }
|
{ return _createOneEle( _handleToPtr(h), uuIdRef, "string", wsSessId, parentUuId, eleName, appId, clas, title, "value", value ); }
|
||||||
|
|
||||||
cw::rc_t cw::ui::createNumber( handle_t h, unsigned& uuIdRef, unsigned wsSessId, unsigned parentUuId, const char* jsId, unsigned appId, const char* clas, const char* title, double value, double minValue, double maxValue, double stepValue, unsigned decpl )
|
cw::rc_t cw::ui::createNumber( handle_t h, unsigned& uuIdRef, unsigned wsSessId, unsigned parentUuId, const char* eleName, unsigned appId, const char* clas, const char* title, double value, double minValue, double maxValue, double stepValue, unsigned decpl )
|
||||||
{ return _createOneEle( _handleToPtr(h), uuIdRef, "number", wsSessId, parentUuId, jsId, appId, clas, title, "value", value, "min", minValue, "max", maxValue, "step", stepValue, "decpl", decpl ); }
|
{ return _createOneEle( _handleToPtr(h), uuIdRef, "number", wsSessId, parentUuId, eleName, appId, clas, title, "value", value, "min", minValue, "max", maxValue, "step", stepValue, "decpl", decpl ); }
|
||||||
|
|
||||||
cw::rc_t cw::ui::createProgress( handle_t h, unsigned& uuIdRef, unsigned wsSessId, unsigned parentUuId, const char* jsId, unsigned appId, const char* clas, const char* title, double value, double minValue, double maxValue )
|
cw::rc_t cw::ui::createProgress( handle_t h, unsigned& uuIdRef, unsigned wsSessId, unsigned parentUuId, const char* eleName, unsigned appId, const char* clas, const char* title, double value, double minValue, double maxValue )
|
||||||
{ return _createOneEle( _handleToPtr(h), uuIdRef, "progress", wsSessId, parentUuId, jsId, appId, clas, title, "value", value, "min", minValue, "max", maxValue ); }
|
{ return _createOneEle( _handleToPtr(h), uuIdRef, "progress", wsSessId, parentUuId, eleName, appId, clas, title, "value", value, "min", minValue, "max", maxValue ); }
|
||||||
|
|
||||||
cw::rc_t cw::ui::createText( handle_t h, unsigned& uuIdRef, unsigned wsSessId, unsigned parentUuId, const char* jsId, unsigned appId, const char* clas, const char* title )
|
cw::rc_t cw::ui::createText( handle_t h, unsigned& uuIdRef, unsigned wsSessId, unsigned parentUuId, const char* eleName, unsigned appId, const char* clas, const char* title )
|
||||||
{
|
{
|
||||||
rc_t rc= kOkRC;
|
rc_t rc= kOkRC;
|
||||||
return rc;
|
return rc;
|
||||||
@ -871,7 +975,7 @@ cw::rc_t cw::ui::registerAppIds( handle_t h, const appIdMap_t* map, unsigned ma
|
|||||||
rc_t rc = kOkRC;
|
rc_t rc = kOkRC;
|
||||||
|
|
||||||
for(unsigned i=0; i<mapN; ++i)
|
for(unsigned i=0; i<mapN; ++i)
|
||||||
if((rc = _allocAppIdMap( p, map[i].parentAppId, map[i].appId, map[i].jsId )) != kOkRC )
|
if((rc = _allocAppIdMap( p, map[i].parentAppId, map[i].appId, map[i].eleName )) != kOkRC )
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
|
36
cwUi.h
36
cwUi.h
@ -41,7 +41,7 @@ namespace cw
|
|||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
kRootUuId = 0,
|
kRootUuId = 0,
|
||||||
kRootEleAppId,
|
kRootAppId,
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
@ -76,35 +76,35 @@ namespace cw
|
|||||||
rc_t start( handle_t h );
|
rc_t start( handle_t h );
|
||||||
rc_t stop( handle_t h );
|
rc_t stop( handle_t h );
|
||||||
|
|
||||||
unsigned findElementAppId( handle_t h, unsigned parentUuId, const char* jsId );
|
unsigned findElementAppId( handle_t h, unsigned parentUuId, const char* eleName );
|
||||||
unsigned findElementUuId( handle_t h, unsigned parentUuId, const char* jsId );
|
unsigned findElementUuId( handle_t h, unsigned parentUuId, const char* eleName );
|
||||||
unsigned findElementUuId( handle_t h, unsigned parentUuId, unsigned appId );
|
unsigned findElementUuId( handle_t h, unsigned parentUuId, unsigned appId );
|
||||||
const char* findElementJsId( handle_t h, unsigned uuId );
|
const char* findElementName( handle_t h, unsigned uuId );
|
||||||
|
|
||||||
// Return the uuid of the first matching 'jsId'.
|
// Return the uuid of the first matching 'eleName'.
|
||||||
unsigned findElementUuId( handle_t h, const char* jsId );
|
unsigned findElementUuId( handle_t h, const char* eleName );
|
||||||
|
|
||||||
rc_t createFromFile( handle_t h, const char* fn, unsigned wsSessId, unsigned parentUuId=kInvalidId);
|
rc_t createFromFile( handle_t h, const char* fn, unsigned wsSessId, unsigned parentUuId=kInvalidId);
|
||||||
rc_t createFromText( handle_t h, const char* text, unsigned wsSessId, unsigned parentUuId=kInvalidId);
|
rc_t createFromText( handle_t h, const char* text, unsigned wsSessId, unsigned parentUuId=kInvalidId);
|
||||||
rc_t createDiv( handle_t h, unsigned& uuIdRef, unsigned wsSessId, unsigned parentUuId, const char* jsId, unsigned appId, const char* clas, const char* title );
|
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 createTitle( handle_t h, unsigned& uuIdRef, unsigned wsSessId, unsigned parentUuId, const char* jsId, unsigned appId, const char* clas, const char* title );
|
rc_t createTitle( 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 wsSessId, unsigned parentUuId, const char* jsId, unsigned appId, 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 createCheck( handle_t h, unsigned& uuIdRef, unsigned wsSessId, unsigned parentUuId, const char* jsId, unsigned appId, const char* clas, const char* title, bool value );
|
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 createSelect( handle_t h, unsigned& uuIdRef, unsigned wsSessId, unsigned parentUuId, const char* jsId, unsigned appId, const char* clas, const char* title );
|
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 createOption( handle_t h, unsigned& uuIdRef, unsigned wsSessId, unsigned parentUuId, const char* jsId, unsigned appId, 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 createString( handle_t h, unsigned& uuIdRef, unsigned wsSessId, unsigned parentUuId, const char* jsId, unsigned appId, const char* clas, const char* title, const char* value );
|
rc_t createString( 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 createNumber( handle_t h, unsigned& uuIdRef, unsigned wsSessId, unsigned parentUuId, const char* jsId, unsigned appId, const char* clas, const char* title, double value, double minValue, double maxValue, double stepValue, unsigned decPl );
|
rc_t createNumber( handle_t h, unsigned& uuIdRef, unsigned wsSessId, unsigned parentUuId, const char* eleName, unsigned appId, const char* clas, const char* title, double value, double minValue, double maxValue, double stepValue, unsigned decPl );
|
||||||
rc_t createProgress( handle_t h, unsigned& uuIdRef, unsigned wsSessId, unsigned parentUuId, const char* jsId, unsigned appId, const char* clas, const char* title, double value, double minValue, double maxValue );
|
rc_t createProgress( handle_t h, unsigned& uuIdRef, unsigned wsSessId, unsigned parentUuId, const char* eleName, unsigned appId, const char* clas, const char* title, double value, double minValue, double maxValue );
|
||||||
rc_t createText( handle_t h, unsigned& uuIdRef, unsigned wsSessId, unsigned parentUuId, const char* jsId, unsigned appId, const char* clas, const char* title );
|
rc_t createText( handle_t h, unsigned& uuIdRef, unsigned wsSessId, unsigned parentUuId, const char* eleName, unsigned appId, const char* clas, const char* title );
|
||||||
|
|
||||||
typedef struct appIdMap_str
|
typedef struct appIdMap_str
|
||||||
{
|
{
|
||||||
unsigned parentAppId;
|
unsigned parentAppId;
|
||||||
unsigned appId;
|
unsigned appId;
|
||||||
const char* jsId;
|
const char* eleName;
|
||||||
} appIdMap_t;
|
} appIdMap_t;
|
||||||
|
|
||||||
// Register parent/child/js app id's
|
// Register parent/child/name app id's
|
||||||
rc_t registerAppIds( handle_t h, const appIdMap_t* map, unsigned mapN );
|
rc_t registerAppIds( handle_t h, const appIdMap_t* map, unsigned mapN );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
15
cwUiTest.cpp
15
cwUiTest.cpp
@ -28,7 +28,11 @@ namespace cw
|
|||||||
kOption3Id,
|
kOption3Id,
|
||||||
kStringId,
|
kStringId,
|
||||||
kNumberId,
|
kNumberId,
|
||||||
kProgressId
|
kProgressId,
|
||||||
|
|
||||||
|
kPanelDivId,
|
||||||
|
kPanelBtnId,
|
||||||
|
kPanelCheckId
|
||||||
};
|
};
|
||||||
|
|
||||||
rc_t _uiTestCreateUi( ui_test_t* p, unsigned wsSessId )
|
rc_t _uiTestCreateUi( ui_test_t* p, unsigned wsSessId )
|
||||||
@ -38,6 +42,15 @@ namespace cw
|
|||||||
unsigned selUuId = kInvalidId;
|
unsigned selUuId = kInvalidId;
|
||||||
unsigned divUuId = kInvalidId;
|
unsigned divUuId = kInvalidId;
|
||||||
|
|
||||||
|
appIdMap_t mapA[] =
|
||||||
|
{
|
||||||
|
{ ui::kRootAppId, kPanelDivId, "panelDivId" },
|
||||||
|
{ ui::kPanelDivId, kPanelBtnId, "myBtn1Id" },
|
||||||
|
{ ui::kPanelDivId, kPanelCheckId, "myCheck1Id" },
|
||||||
|
};
|
||||||
|
|
||||||
|
registerAppIds(p->uiH, mapA, sizeof(mapA)/sizeof(mapA[0]));
|
||||||
|
|
||||||
if((rc = createDiv( p->uiH, divUuId, wsSessId, kInvalidId, "myDivId", kDivId, "divClass", "My Panel" )) != kOkRC )
|
if((rc = createDiv( p->uiH, divUuId, wsSessId, kInvalidId, "myDivId", kDivId, "divClass", "My Panel" )) != kOkRC )
|
||||||
goto errLabel;
|
goto errLabel;
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
|
|
||||||
<p id="appTitleId">Disconnected</p>
|
<p id="appTitleId">Disconnected</p>
|
||||||
|
|
||||||
<div id="uiDivId" class="uiAppDiv">
|
<div id="0" class="uiAppDiv">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
var _ws = null;
|
var _ws = null;
|
||||||
var _rootJsId = "uiDivId";
|
var _rootId = "0";
|
||||||
var _nextEleId = 0;
|
var _nextEleId = 0;
|
||||||
|
|
||||||
function set_app_title( suffix, className )
|
function set_app_title( suffix, className )
|
||||||
@ -215,8 +215,7 @@ function dom_get_checkbox( ele_id )
|
|||||||
function dom_create_ele( ele_type )
|
function dom_create_ele( ele_type )
|
||||||
{
|
{
|
||||||
ele = document.createElement(ele_type);
|
ele = document.createElement(ele_type);
|
||||||
ele.id = _nextEleId;
|
return ele
|
||||||
_nextEleId += 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
@ -228,21 +227,13 @@ function ui_error( msg )
|
|||||||
|
|
||||||
function ui_send_value( ele, typeId, value )
|
function ui_send_value( ele, typeId, value )
|
||||||
{
|
{
|
||||||
if( ele.hasOwnProperty('uuId') )
|
ws_send("value " + ele.id + " " + typeId + " : " + value)
|
||||||
ws_send("value " + ele.uuId + " " + typeId + " : " + value)
|
|
||||||
else
|
|
||||||
ui_error("A value msg send failed because the value had no UuId.");
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function ui_send_bool_value( ele, value ) { ui_send_value(ele,'b',value); }
|
function ui_send_bool_value( ele, value ) { ui_send_value(ele,'b',value); }
|
||||||
function ui_send_int_value( ele, value ) { ui_send_value(ele,'i',value); }
|
function ui_send_int_value( ele, value ) { ui_send_value(ele,'i',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_register( ele )
|
|
||||||
{
|
|
||||||
ws_send("register " + ele.parentJsId + " " + ele.jsId + " " + ele.id + " " + ele.uuId + " " + ele.appId )
|
|
||||||
}
|
|
||||||
|
|
||||||
function ui_print_children( eleId )
|
function ui_print_children( eleId )
|
||||||
{
|
{
|
||||||
@ -257,7 +248,7 @@ function ui_print_children( eleId )
|
|||||||
function ui_get_parent( parentId )
|
function ui_get_parent( parentId )
|
||||||
{
|
{
|
||||||
if( parentId==null || parentId.trim().length == 0 )
|
if( parentId==null || parentId.trim().length == 0 )
|
||||||
parentId = _rootJsId
|
parentId = _rootId
|
||||||
|
|
||||||
parent_ele = dom_id_to_ele(parentId);
|
parent_ele = dom_id_to_ele(parentId);
|
||||||
|
|
||||||
@ -276,22 +267,20 @@ function ui_create_ele( parent_ele, ele_type, d )
|
|||||||
var ele = dom_create_ele(ele_type);
|
var ele = dom_create_ele(ele_type);
|
||||||
|
|
||||||
if( ele == null )
|
if( ele == null )
|
||||||
ui_error("'%s' element create failed.", ele_type);
|
ui_error(ele_type +" element create failed.");
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ele.jsId = d.jsId;
|
ele.id = d.uuId;
|
||||||
|
|
||||||
ele.parentJsId = d.parentJsId;
|
if(d.hasOwnProperty('appId'))
|
||||||
|
ele.appId = d.appId;
|
||||||
|
else
|
||||||
|
ele.appId = null;
|
||||||
|
|
||||||
ele.uuId = d.hasOwnProperty("uuId") ? d.uuId : null
|
console.log("Created: " + ele_type + " parent:" + d.parentUuId + " id:" + ele.id + " appId:" + ele.appId)
|
||||||
|
|
||||||
ele.appId = d.hasOwnProperty("appId") ? d.appId : null
|
|
||||||
|
|
||||||
console.log("Created: " + ele_type + " parent:" + d.parentJsId + " id:" + ele.id + " appId:" + ele.appId + " uuId:" + ele.uuId)
|
|
||||||
|
|
||||||
parent_ele.appendChild(ele);
|
parent_ele.appendChild(ele);
|
||||||
|
|
||||||
ui_send_register( ele );
|
|
||||||
|
|
||||||
}
|
}
|
||||||
return ele
|
return ele
|
||||||
@ -412,16 +401,30 @@ function ui_create_string( parent_ele, d )
|
|||||||
|
|
||||||
function ui_number_keyup( e )
|
function ui_number_keyup( e )
|
||||||
{
|
{
|
||||||
console.log(e)
|
|
||||||
if( e.keyCode===13 )
|
if( e.keyCode===13 )
|
||||||
{
|
{
|
||||||
var ele = dom_id_to_ele(e.target.id)
|
var ele = dom_id_to_ele(e.target.id)
|
||||||
console.log(ele.value)
|
|
||||||
if( ele != null )
|
if( ele != null )
|
||||||
{
|
{
|
||||||
|
console.log("min:"+ele.minValue+" max:"+ele.maxValue)
|
||||||
|
|
||||||
|
var val = 0;
|
||||||
|
if( ele.decpl == 0 )
|
||||||
|
val = Number.parseInt(ele.value)
|
||||||
|
else
|
||||||
|
val = Number.parseFloat(ele.value)
|
||||||
|
|
||||||
|
if( !(ele.minValue<=val && val<=ele.maxValue))
|
||||||
|
ele.style.borderColor = "red"
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ele.style.borderColor = ""
|
||||||
|
|
||||||
ui_send_int_value(ele,ele.value);
|
ui_send_int_value(ele,ele.value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function ui_create_number( parent_ele, d )
|
function ui_create_number( parent_ele, d )
|
||||||
@ -462,16 +465,21 @@ function ui_create_progress( parent_ele, d )
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function ui_create( parentId, ele_type, d )
|
function ui_create( d )
|
||||||
{
|
{
|
||||||
var parent_ele = ui_get_parent(parentId);
|
if( typeof(d.parentUuId) == "number")
|
||||||
|
d.parentUuId = d.parentUuId.toString()
|
||||||
|
|
||||||
|
if( typeof(d.uuId) == "number" )
|
||||||
|
d.uuId = d.uuId.toString()
|
||||||
|
|
||||||
|
|
||||||
|
var parent_ele = ui_get_parent(d.parentUuId);
|
||||||
var ele = null;
|
var ele = null;
|
||||||
|
|
||||||
if( parent_ele != null )
|
if( parent_ele != null )
|
||||||
{
|
{
|
||||||
d.parentJsId = parentId
|
switch( d.type )
|
||||||
|
|
||||||
switch( ele_type )
|
|
||||||
{
|
{
|
||||||
case "div":
|
case "div":
|
||||||
ele = ui_create_div( parent_ele, d )
|
ele = ui_create_div( parent_ele, d )
|
||||||
@ -510,65 +518,13 @@ function ui_create( parentId, ele_type, d )
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
ui_error("Unknown UI element type: " + ele_type )
|
ui_error("Unknown UI element type: " + d.type )
|
||||||
}
|
}
|
||||||
|
|
||||||
if( d.hasOwnProperty("children") )
|
|
||||||
{
|
|
||||||
for (const ele_type in d.children)
|
|
||||||
ui_create( d.jsId, ele_type, d.children[ele_type] )
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function ui_uuid_to_ele( uuId, ele=null )
|
|
||||||
{
|
|
||||||
if( ele == null )
|
|
||||||
ele = dom_id_to_ele( _rootJsId )
|
|
||||||
|
|
||||||
if( ele.hasOwnProperty('uuId') )
|
|
||||||
{
|
|
||||||
if( ele.uuId == uuId )
|
|
||||||
return ele
|
|
||||||
|
|
||||||
for(var i=0; i<ele.childElementCount; ++i)
|
|
||||||
ui_uuid_to_ele( uuId, ele.children[i] )
|
|
||||||
}
|
|
||||||
|
|
||||||
ui_error("The element with uuid: " + uuId + " was not found.")
|
|
||||||
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Do breadth first search for ele's without uuId's
|
|
||||||
function ui_next_ele_to_register( parentEle )
|
|
||||||
{
|
|
||||||
for(var i=0; i<parentEle.childElementCount; ++i)
|
|
||||||
{
|
|
||||||
var ele = parentEle.children[i]
|
|
||||||
|
|
||||||
if( ele.hasOwnProperty('uuId') && ele.uuId==null)
|
|
||||||
return ele
|
|
||||||
}
|
|
||||||
|
|
||||||
for(var i=0; i<parentEle.childElementCount; ++i)
|
|
||||||
{
|
|
||||||
var ele = ui_next_ele_to_register( parentEle.children[i])
|
|
||||||
|
|
||||||
if( ele != null )
|
|
||||||
return ele
|
|
||||||
}
|
|
||||||
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
function ui_set_app_uuId( d )
|
|
||||||
{
|
|
||||||
console.log(d)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function ws_send( s )
|
function ws_send( s )
|
||||||
@ -580,24 +536,16 @@ function ws_send( s )
|
|||||||
|
|
||||||
function ws_on_msg( jsonMsg )
|
function ws_on_msg( jsonMsg )
|
||||||
{
|
{
|
||||||
console.log(jsonMsg)
|
//console.log(jsonMsg)
|
||||||
|
|
||||||
d = JSON.parse(jsonMsg.data);
|
d = JSON.parse(jsonMsg.data);
|
||||||
|
|
||||||
switch( d.op )
|
switch( d.op )
|
||||||
{
|
{
|
||||||
case 'create':
|
case 'create':
|
||||||
for (const ele_type in d.children)
|
ui_create( d )
|
||||||
{
|
|
||||||
ui_create( d.parent, ele_type, d.children[ele_type] )
|
|
||||||
//console.log(`${ele_type}: ${d.value[ele_type]}`);
|
|
||||||
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'set_app_id':
|
|
||||||
ui_set_app_uuId(d)
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
ui_error("Unknown UI operation. " + d.op )
|
ui_error("Unknown UI operation. " + d.op )
|
||||||
@ -632,12 +580,12 @@ function ws_form_url(urlSuffix)
|
|||||||
|
|
||||||
function main()
|
function main()
|
||||||
{
|
{
|
||||||
rootEle = dom_id_to_ele(_rootJsId);
|
rootEle = dom_id_to_ele(_rootId);
|
||||||
rootEle.uuId = 0;
|
rootEle.uuId = 0;
|
||||||
rootEle.id = _nextEleId;
|
rootEle.id = _nextEleId;
|
||||||
_nextEleId += 1;
|
_nextEleId += 1;
|
||||||
|
|
||||||
console.log(ws_form_url(""))
|
//console.log(ws_form_url(""))
|
||||||
|
|
||||||
_ws = new WebSocket(ws_form_url(""),"ui_protocol")
|
_ws = new WebSocket(ws_form_url(""),"ui_protocol")
|
||||||
|
|
||||||
|
@ -5,14 +5,14 @@
|
|||||||
|
|
||||||
div: {
|
div: {
|
||||||
|
|
||||||
jsId: "panelDivId",
|
name: "panelDivId",
|
||||||
class: "myPanelClass",
|
class: "myPanelClass",
|
||||||
title: "My resource based panel",
|
title: "My resource based panel",
|
||||||
|
|
||||||
children: {
|
children: {
|
||||||
|
|
||||||
button:{ jsId: myBtn1Id, title:"Push Me" },
|
button:{ name: myBtn1Id, title:"Push Me" },
|
||||||
check:{ jsId: myCheck1Id, title:"Check Me" },
|
check:{ name: myCheck1Id, title:"Check Me" },
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user