cwUi.h/cpp, cwUiTest.cpp, html/uiTest : Initial working version of cwUI.

This commit is contained in:
kevin.larke 2020-04-06 19:17:04 -04:00
parent d3d4c7c6f9
commit b6d716e8ff
6 changed files with 635 additions and 570 deletions

392
cwUi.cpp
View File

@ -19,7 +19,7 @@ namespace cw
struct appIdMapRecd_str* link;
unsigned parentAppId;
unsigned appId;
char* jsId;
char* eleName;
} 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
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
char* jsId; // javascript id
char* eleName; // javascript id
} ele_t;
typedef struct ui_str
@ -52,7 +52,7 @@ namespace cw
for(unsigned i=0; i<p->eleN; ++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)
{
mem::release(p->eleA[i]->jsId);
mem::release(p->eleA[i]->eleName);
mem::release(p->eleA[i]);
}
@ -74,22 +74,23 @@ namespace cw
while( m!=nullptr )
{
appIdMapRecd_t* m0 = m->link;
mem::release(m->jsId);
mem::release(m->eleName);
mem::release(m);
m = m0;
}
mem::release(p->eleA);
mem::release(p->buf);
mem::release(p);
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;
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 nullptr;
}
@ -103,42 +104,42 @@ namespace cw
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;
// The 'jsId' 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)
if( jsId == nullptr || strlen(jsId) == 0 )
return cwLogError(kInvalidIdRC,"Registered parent/child app id's must have a valid 'jsId'.");
// 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 eleName)
if( eleName == nullptr || strlen(eleName) == 0 )
return cwLogError(kInvalidIdRC,"Registered parent/child app id's must have a valid 'eleName'.");
// verify that the parent/child pair is unique
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
if( _findAppIdMap(p,parentAppId,jsId) != 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));
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 eleName:'%s'.",parentAppId,appId,cwStringNullGuard(eleName));
// allocate and link in a new appId map record
appIdMapRecd_t* m = mem::allocZ<appIdMapRecd_t>();
m->parentAppId = parentAppId;
m->appId = appId;
m->jsId = mem::duplStr(jsId);
m->eleName = mem::duplStr(eleName);
m->link = p->appIdMap;
p->appIdMap = m;
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>();
e->parent = parent;
e->uuId = p->eleN;
e->appId = appId;
e->jsId = mem::duplStr(jsId);
e->eleName = mem::duplStr(eleName);
if( p->eleN == p->eleAllocN )
{
p->eleAllocN += 100;
@ -147,6 +148,15 @@ namespace cw
p->eleA[ p->eleN ] = e;
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;
}
@ -163,33 +173,57 @@ namespace cw
return p->eleA[ uuId ];
}
// Given a parent UuId and a javascript id find the associated ele
ele_t* _parentUuId_JsId_ToEle( ui_t* p, unsigned parentUuId, const char* jsId, bool errorFl=true )
ele_t* _eleNameToEle( ui_t* p, const char* eleName, bool errorFl=true )
{
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];
if( errorFl )
cwLogError(kInvalidIdRC,"The element with eleName:%s not found.",cwStringNullGuard(eleName));
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 jsId:%s is not found.",parentUuId,jsId);
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* jsId )
unsigned _findElementUuId( ui_t* p, const char* eleName )
{
for(unsigned i=0; i<p->eleN; ++i)
if( strcmp(p->eleA[i]->jsId,jsId) == 0 )
if( strcmp(p->eleA[i]->eleName,eleName) == 0 )
return p->eleA[i]->uuId;
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)
if( p->eleA[i]->uuId == uuId )
return p->eleA[i]->jsId;
return p->eleA[i]->eleName;
return nullptr;
}
@ -234,11 +268,10 @@ namespace cw
}
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;
const char* parentJsId = "";
ele_t* newEle = nullptr;
ele_t* parentEle = nullptr;
//const unsigned bufN = 1024; // TODO: use preallocated buffer
@ -253,20 +286,19 @@ namespace cw
if(( parentEle = _uuIdToEle(p, parentUuId )) == nullptr )
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
newEle = _createEle( p, parentEle, appId, jsId );
newEle = _createEle( p, parentEle, appId, eleName );
// 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
i += format_attributes(p->buf+i, p->bufN-i, 0, std::forward<ARGS>(args)...);
// terminate the message
i += toText(p->buf+i, p->bufN-i, "}}}");
i += toText(p->buf+i, p->bufN-i, "}");
if( i >= p->bufN )
return cwLogError(kBufTooSmallRC,"The UI message formatting buffer is too small. (size:%i bytes)", p->bufN);
@ -281,92 +313,168 @@ namespace cw
return rc;
}
rc_t _decorateObj( ui_t* p, object_t* o )
ele_t* _findOrCreateEle( ui_t* p, ele_t* parentEle, const char* eleName )
{
rc_t rc = kOkRC;
const object_t* oo;
//ele_t* parent_ele;
const char* jsId;
ele_t* ele;
if((ele = _parentUuId_EleName_ToEle( p, parentEle->uuId, eleName, false )) == nullptr )
ele = _createEle(p, parentEle, kInvalidId, eleName );
// find the parent pair
if((oo = o->find( "parent", kNoRecurseFl | kOptionalFl)) != nullptr )
{
}
// find the parent JsId
if((rc = oo->value(jsId)) != kOkRC )
{
}
// find the parent element
//if((parent_ele = _jsIdToEle( p, jsId )) == nullptr )
//{
//}
return rc;
return ele;
}
rc_t _createElementsFromChildList( ui_t* p, object_t* po, unsigned wsSessId, ele_t* parentEle );
rc_t _createFromObj( ui_t* p, object_t* o, unsigned wsSessId, unsigned parentUuId )
//
rc_t _createEleFromRsrsc( ui_t* p, ele_t* parentEle, const char* eleType, object_t* o, unsigned wsSessId )
{
rc_t rc = kOkRC;
const char* parentJsId = "";
const int kBufN = 512; // TODO: preallocate this buffer as part of ui_t.
char buf0[ kBufN ];
char buf1[ kBufN ];
rc_t rc = kOkRC;
object_t* co = nullptr;
ele_t* ele = nullptr;
char* eleName = nullptr;
// if a parentUuid was given ...
if( parentUuId != kInvalidId )
if( !o->is_dict() )
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 )
{
// ... 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 );
co = co->parent;
co->unlink();
}
else // if no parentUuid was given then look for one in the resource
// get the ui ele name
if((rc = o->get("name",eleName)) != kOkRC )
{
// get the parent JS id from the cfg object
rc = o->get("parent",parentJsId,kNoRecurseFl | kOptionalFl);
switch(rc)
rc = cwLogError(rc,"The UI element name could not be read.");
goto errLabel;
}
// get or create the ele record to associate with this ele
if((ele = _findOrCreateEle( p, parentEle, eleName )) == nullptr )
{
rc = cwLogError(kOpFailRC,"The local element '%s' could not be created.",cwStringNullGuard(eleName));
goto errLabel;
}
if( o->insertPair("uuId",ele->uuId) == nullptr )
{
rc = cwLogError(kOpFailRC,"The 'uuid' node insertion failed on UI element '%s'.",cwStringNullGuard(eleName));
goto errLabel;
}
if( ele->appId != kInvalidId )
{
if( o->insertPair("appId",ele->appId) == nullptr )
{
case kOkRC:
// 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;
rc = cwLogError(kOpFailRC,"The 'appId' node insertion failed on UI element '%s'.",cwStringNullGuard(eleName));
goto errLabel;
}
}
if( o->insertPair("parentUuId",parentEle->uuId) == nullptr )
{
rc = cwLogError(kOpFailRC,"The 'parentUuId' node insertion failed on UI element '%s'.",cwStringNullGuard(eleName));
goto errLabel;
}
if( o->insertPair("op","create") == nullptr )
{
rc = cwLogError(kOpFailRC,"The 'op' node insertion failed on UI element '%s'.",cwStringNullGuard(eleName));
goto errLabel;
}
// form the msg string from the resource
if( o->to_string( buf0, kBufN ) >= kBufN )
return cwLogError(kBufTooSmallRC,"The resource object string buffer is too small (buf bytes:%i).",kBufN);
if( o->insertPair("type",eleType) == nullptr )
{
rc = cwLogError(kOpFailRC,"The 'eleType' node insertion failed on UI element '%s'.",cwStringNullGuard(eleName));
goto errLabel;
}
printf("buf0: %s\n",buf0);
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);
// send the msg string
printf("buf1: %s\n",buf1);
rc = _websockSend( p, wsSessId, buf1 );
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;
}
// if this element has a list of children then create them here
if( co != nullptr )
rc = _createElementsFromChildList(p, co->pair_value(), wsSessId, ele );
errLabel:
if( co != nullptr )
co->free();
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 )
{
@ -449,7 +557,7 @@ namespace cw
{
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 )
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* jsId = nextNonWhiteChar(nextWhiteChar(s0));
const char* eleName = nextNonWhiteChar(nextWhiteChar(s0));
// 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) );
goto errLabel;
@ -499,15 +607,15 @@ namespace cw
}
// 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
appIdMapRecd_t* m = _findAppIdMap( p, parentEle->appId, jsId );
// look up the parent/eleName pair map
appIdMapRecd_t* m = _findAppIdMap( p, parentEle->appId, eleName );
// 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
if( m != nullptr )
@ -516,7 +624,7 @@ namespace cw
}
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 )
@ -585,10 +693,6 @@ namespace cw
// Pass on the 'init' msg to the app.
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;
case kValueOpId:
@ -684,7 +788,7 @@ cw::rc_t cw::ui::createUi(
p->bufN = fmtBufByteN;
// 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.");
goto errLabel;
@ -739,22 +843,22 @@ cw::rc_t cw::ui::destroyUi( handle_t& h )
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);
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 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);
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 kInvalidId;
@ -770,17 +874,17 @@ unsigned cw::ui::findElementUuId( handle_t h, unsigned parentUuId, unsigned appI
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);
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);
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;
}
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 )
{ return _createOneEle( _handleToPtr(h), uuIdRef, "div", wsSessId, parentUuId, jsId, appId, clas, 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, 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 )
{ return _createOneEle( _handleToPtr(h), uuIdRef, "option", wsSessId, parentUuId, jsId, appId, clas, 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, 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 )
{ return _createOneEle( _handleToPtr(h), uuIdRef, "button", wsSessId, parentUuId, jsId, appId, 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 )
{ 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 )
{ return _createOneEle( _handleToPtr(h), uuIdRef, "check", wsSessId, parentUuId, jsId, appId, clas, title, "value", 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, 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 )
{ return _createOneEle( _handleToPtr(h), uuIdRef, "select", wsSessId, parentUuId, jsId, appId, clas, 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, 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 )
{ return _createOneEle( _handleToPtr(h), uuIdRef, "option", wsSessId, parentUuId, jsId, appId, 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 )
{ 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 )
{ return _createOneEle( _handleToPtr(h), uuIdRef, "string", wsSessId, parentUuId, jsId, appId, clas, title, "value", 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, 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 )
{ return _createOneEle( _handleToPtr(h), uuIdRef, "number", wsSessId, parentUuId, jsId, appId, clas, title, "value", value, "min", minValue, "max", maxValue, "step", stepValue, "decpl", 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, 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 )
{ return _createOneEle( _handleToPtr(h), uuIdRef, "progress", wsSessId, parentUuId, jsId, appId, clas, title, "value", value, "min", minValue, "max", 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, 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;
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;
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;

36
cwUi.h
View File

@ -41,7 +41,7 @@ namespace cw
enum
{
kRootUuId = 0,
kRootEleAppId,
kRootAppId,
};
typedef struct
@ -76,35 +76,35 @@ namespace cw
rc_t start( handle_t h );
rc_t stop( handle_t h );
unsigned findElementAppId( handle_t h, unsigned parentUuId, const char* jsId );
unsigned findElementUuId( 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* eleName );
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'.
unsigned findElementUuId( handle_t h, const char* jsId );
// Return the uuid of the first matching 'eleName'.
unsigned findElementUuId( handle_t h, const char* eleName );
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 createDiv( 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* jsId, 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 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 createSelect( 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* jsId, 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 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 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 createText( 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* eleName, 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* 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* eleName, 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* 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* 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* 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* eleName, unsigned appId, const char* clas, const char* title );
typedef struct appIdMap_str
{
unsigned parentAppId;
unsigned appId;
const char* jsId;
const char* eleName;
} 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 );
}

View File

@ -28,7 +28,11 @@ namespace cw
kOption3Id,
kStringId,
kNumberId,
kProgressId
kProgressId,
kPanelDivId,
kPanelBtnId,
kPanelCheckId
};
rc_t _uiTestCreateUi( ui_test_t* p, unsigned wsSessId )
@ -38,6 +42,15 @@ namespace cw
unsigned selUuId = 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 )
goto errLabel;

View File

@ -15,7 +15,7 @@
<p id="appTitleId">Disconnected</p>
<div id="uiDivId" class="uiAppDiv">
<div id="0" class="uiAppDiv">
</div>
</body>

View File

@ -1,54 +1,54 @@
var _ws = null;
var _rootJsId = "uiDivId";
var _rootId = "0";
var _nextEleId = 0;
function set_app_title( suffix, className )
{
var ele = document.getElementById('appTitleId');
ele.innerHTML = "UI Test:" + suffix
ele.className = className
var ele = document.getElementById('appTitleId');
ele.innerHTML = "UI Test:" + suffix
ele.className = className
}
function uiOnError( msg, r)
{
console.log("Error:" + msg);
console.log("Error:" + msg);
}
function uiGetParent( r )
{
parent_ele = document.getElementById(r.parent_id);
if( parent_ele == null )
{
uiOnError("Parent not found. parent_id:" + r.parent_id,r);
}
parent_ele = document.getElementById(r.parent_id);
if( parent_ele == null )
{
uiOnError("Parent not found. parent_id:" + r.parent_id,r);
}
return parent_ele;
return parent_ele;
}
function uiCreateEle( r )
{
var parent_ele;
if((parent_ele = uiGetParent(r)) != null )
{
ele = document.createElement(r.ele_type)
ele.id = r.ele_id;
ele.className = r.value;
var parent_ele;
parent_ele.appendChild(ele)
}
if((parent_ele = uiGetParent(r)) != null )
{
ele = document.createElement(r.ele_type)
ele.id = r.ele_id;
ele.className = r.value;
parent_ele.appendChild(ele)
}
}
function uiRemoveChildren( r )
{
ele = document.getElementById(r.ele_id)
while (ele.firstChild)
{
ele.removeChild(ele.firstChild);
}
ele = document.getElementById(r.ele_id)
while (ele.firstChild)
{
ele.removeChild(ele.firstChild);
}
}
function uiDivCreate( r )
@ -56,148 +56,148 @@ function uiDivCreate( r )
function uiLabelCreate( r )
{
var parent_ele;
if((parent_ele = uiGetParent(r)) != null )
{
ele = document.createElement("label")
ele.htmlFor = r.ele_id
ele.innerHTML = r.value;
parent_ele.appendChild(ele)
}
var parent_ele;
if((parent_ele = uiGetParent(r)) != null )
{
ele = document.createElement("label")
ele.htmlFor = r.ele_id
ele.innerHTML = r.value;
parent_ele.appendChild(ele)
}
}
function uiSelectCreate( r )
{
uiCreateEle(r)
uiCreateEle(r)
}
function uiSelectClear( r )
{ uiRemoveChildren(r) }
function uiSelectInsert( r )
{
var select_ele;
if((select_ele = uiGetParent(r)) != null )
{
var option = document.createElement('option');
var select_ele;
if((select_ele = uiGetParent(r)) != null )
{
var option = document.createElement('option');
option.id = r.ele_id;
option.innerHTML = r.value;
option.value = r.ele_id;
option.onclick = function() { uiOnSelectClick(this) }
select_ele.appendChild(option)
}
option.id = r.ele_id;
option.innerHTML = r.value;
option.value = r.ele_id;
option.onclick = function() { uiOnSelectClick(this) }
select_ele.appendChild(option)
}
}
function uiSelectChoose( r )
{
var select_ele;
if((select_ele = uiGetParent(r)) != null )
{
if( select_ele.hasChildNodes())
var select_ele;
if((select_ele = uiGetParent(r)) != null )
{
var children = select_ele.childNodes
for(var i=0; i<children.length; i++)
{
if( children[i].id == r.ele_id )
if( select_ele.hasChildNodes())
{
select_ele.selectedIndex = i
break;
}
}
var children = select_ele.childNodes
for(var i=0; i<children.length; i++)
{
if( children[i].id == r.ele_id )
{
select_ele.selectedIndex = i
break;
}
}
}
}
}
}
function uiOnSelectClick( ele )
{
cmdstr = "mode ui ele_type select op choose parent_id "+ele.parentElement.id+" option_id " + ele.id
websocket.send(cmdstr);
cmdstr = "mode ui ele_type select op choose parent_id "+ele.parentElement.id+" option_id " + ele.id
websocket.send(cmdstr);
}
function uiNumberOnKeyUp( e )
{
if( e.keyCode == 13 )
{
//console.log(e)
cmdstr = "mode ui ele_type number op change parent_id "+e.srcElement.parentElement.id+" ele_id " + e.srcElement.id + " value " + e.srcElement.value
websocket.send(cmdstr);
}
if( e.keyCode == 13 )
{
//console.log(e)
cmdstr = "mode ui ele_type number op change parent_id "+e.srcElement.parentElement.id+" ele_id " + e.srcElement.id + " value " + e.srcElement.value
websocket.send(cmdstr);
}
}
function uiNumberCreate( r )
{
var parent_ele;
if((parent_ele = uiGetParent(r)) != null )
{
ele = document.createElement("input")
ele.id = r.ele_id
ele.setAttribute('type','number')
ele.addEventListener('keyup',uiNumberOnKeyUp)
parent_ele.appendChild(ele)
}
var parent_ele;
if((parent_ele = uiGetParent(r)) != null )
{
ele = document.createElement("input")
ele.id = r.ele_id
ele.setAttribute('type','number')
ele.addEventListener('keyup',uiNumberOnKeyUp)
parent_ele.appendChild(ele)
}
}
function uiNumberSet( r )
{
var ele;
var ele;
console.log("ele_id:" + r.ele_id + " parent_id:" + r.parent_id + " value:" + r.value)
if((ele = document.getElementById(r.parent_id)) != null)
{
switch( r.ele_id )
console.log("ele_id:" + r.ele_id + " parent_id:" + r.parent_id + " value:" + r.value)
if((ele = document.getElementById(r.parent_id)) != null)
{
case "0": ele.min = r.value; break;
case "1": ele.max = r.value; break;
case "2": ele.step = r.value; break;
case "3": ele.value = r.value; break;
switch( r.ele_id )
{
case "0": ele.min = r.value; break;
case "1": ele.max = r.value; break;
case "2": ele.step = r.value; break;
case "3": ele.value = r.value; break;
}
}
}
}
function dom_child_by_id( parentEle, child_id )
{
var childrenL = parentEle.children
for(var i=0; i<childrenL.length; i++)
{
if( childrenL[i].id == child_id )
var childrenL = parentEle.children
for(var i=0; i<childrenL.length; i++)
{
return childrenL[i];
if( childrenL[i].id == child_id )
{
return childrenL[i];
}
}
}
return null;
return null;
}
function dom_set_option_by_text( ele_id, text )
{
var ele = dom_id_to_ele(ele_id);
for (var i = 0; i < ele.options.length; i++)
{
if (ele.options[i].text === text)
{
ele.selectedIndex = i;
break;
var ele = dom_id_to_ele(ele_id);
for (var i = 0; i < ele.options.length; i++)
{
if (ele.options[i].text === text)
{
ele.selectedIndex = i;
break;
}
}
}
}
function dom_set_number( ele_id, val )
{
dom_id_to_ele(ele_id).value = val
dom_id_to_ele(ele_id).value = val
}
@ -214,437 +214,385 @@ function dom_get_checkbox( ele_id )
function dom_create_ele( ele_type )
{
ele = document.createElement(ele_type);
ele.id = _nextEleId;
_nextEleId += 1;
ele = document.createElement(ele_type);
return ele
}
//==============================================================================
function ui_error( msg )
{
console.log("Error: " + msg )
console.log("Error: " + msg )
}
function ui_send_value( ele, typeId, value )
{
if( ele.hasOwnProperty('uuId') )
ws_send("value " + ele.uuId + " " + typeId + " : " + value)
else
ui_error("A value msg send failed because the value had no UuId.");
ws_send("value " + ele.id + " " + typeId + " : " + 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_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 )
{
var childrenL = dom_id_to_ele(eleId).children
var childrenL = dom_id_to_ele(eleId).children
for(var i=0; i<childrenL.length; i++)
{
console.log( childrenL[i] )
}
for(var i=0; i<childrenL.length; i++)
{
console.log( childrenL[i] )
}
}
function ui_get_parent( parentId )
{
if( parentId==null || parentId.trim().length == 0 )
parentId = _rootJsId
parent_ele = dom_id_to_ele(parentId);
if( parent_ele == null )
{
ui_error("Parent element id: " + parentId + " not found.")
}
if( parentId==null || parentId.trim().length == 0 )
parentId = _rootId
parent_ele = dom_id_to_ele(parentId);
if( parent_ele == null )
{
ui_error("Parent element id: " + parentId + " not found.")
}
return parent_ele;
return parent_ele;
}
function ui_create_ele( parent_ele, ele_type, d )
{
// create the ctl object
var ele = dom_create_ele(ele_type);
// create the ctl object
var ele = dom_create_ele(ele_type);
if( ele == null )
ui_error("'%s' element create failed.", ele_type);
else
{
ele.jsId = d.jsId;
ele.parentJsId = d.parentJsId;
ele.uuId = d.hasOwnProperty("uuId") ? d.uuId : null
ele.appId = d.hasOwnProperty("appId") ? d.appId : null
if( ele == null )
ui_error(ele_type +" element create failed.");
else
{
ele.id = d.uuId;
console.log("Created: " + ele_type + " parent:" + d.parentJsId + " id:" + ele.id + " appId:" + ele.appId + " uuId:" + ele.uuId)
parent_ele.appendChild(ele);
if(d.hasOwnProperty('appId'))
ele.appId = d.appId;
else
ele.appId = null;
console.log("Created: " + ele_type + " parent:" + d.parentUuId + " id:" + ele.id + " appId:" + ele.appId)
parent_ele.appendChild(ele);
ui_send_register( ele );
}
return ele
}
return ele
}
function ui_create_ctl( parent_ele, ele_type, label, d )
{
// create an enclosing div
var div_ele = dom_create_ele("div");
// create an enclosing div
var div_ele = dom_create_ele("div");
div_ele.className = d.clas;
div_ele.className = d.clas;
parent_ele.appendChild( div_ele );
var label_ele = div_ele
// if label is not null then create an enclosing 'label' element
if( label != null )
{
label_ele = dom_create_ele("label");
parent_ele.appendChild( div_ele );
var label_ele = div_ele
// if label is not null then create an enclosing 'label' element
if( label != null )
{
label_ele = dom_create_ele("label");
label_ele.innerHTML = label;
label_ele.innerHTML = label;
div_ele.appendChild(label_ele)
}
div_ele.appendChild(label_ele)
}
return ui_create_ele( label_ele, ele_type, d );
return ui_create_ele( label_ele, ele_type, d );
}
function ui_create_div( parent_ele, d )
{
var div_ele = ui_create_ele( parent_ele, "div", d );
var div_ele = ui_create_ele( parent_ele, "div", d );
if( div_ele != null )
{
div_ele.className = d.clas
if( div_ele != null )
{
div_ele.className = d.clas
var p_ele = dom_create_ele("p")
if( d.title != null && d.title.length > 0 )
p_ele.innerHTML = d.title
div_ele.appendChild( p_ele )
}
var p_ele = dom_create_ele("p")
if( d.title != null && d.title.length > 0 )
p_ele.innerHTML = d.title
div_ele.appendChild( p_ele )
}
return div_ele;
return div_ele;
}
function ui_create_title( parent_ele, d )
{
return ui_create_ele( parent_ele, "label", d );
return ui_create_ele( parent_ele, "label", d );
}
function ui_create_button( parent_ele, d )
{
var ele = ui_create_ctl( parent_ele, "button", null, d );
var ele = ui_create_ctl( parent_ele, "button", null, d );
if( ele != null )
{
ele.innerHTML = d.title;
ele.onclick = function() { ui_send_int_value(this,1); }
}
return ele;
if( ele != null )
{
ele.innerHTML = d.title;
ele.onclick = function() { ui_send_int_value(this,1); }
}
return ele;
}
function ui_create_check( parent_ele, d )
{
var ele = ui_create_ctl( parent_ele, "input", d.title, d )
if( ele != null )
{
ele.type = "checkbox";
dom_set_checkbox(ele.id, d.value );
var ele = ui_create_ctl( parent_ele, "input", d.title, d )
ele.onclick = function() { ui_send_bool_value(this,dom_get_checkbox(this.id)); }
}
return ele;
if( ele != null )
{
ele.type = "checkbox";
dom_set_checkbox(ele.id, d.value );
ele.onclick = function() { ui_send_bool_value(this,dom_get_checkbox(this.id)); }
}
return ele;
}
function ui_on_select( ele )
{
ui_send_int_value(ele,ele.options[ ele.selectedIndex ].appId);
ui_send_int_value(ele,ele.options[ ele.selectedIndex ].appId);
}
function ui_create_select( parent_ele, d )
{
var sel_ele = ui_create_ctl( parent_ele, "select", d.title, d );
sel_ele.onchange = function() { ui_on_select(this) }
return sel_ele;
var sel_ele = ui_create_ctl( parent_ele, "select", d.title, d );
sel_ele.onchange = function() { ui_on_select(this) }
return sel_ele;
}
function ui_create_option( parent_ele, d )
{
var opt_ele = ui_create_ele( parent_ele, "option", d );
var opt_ele = ui_create_ele( parent_ele, "option", d );
if( opt_ele != null )
{
opt_ele.className = d.clas;
opt_ele.innerHTML = d.title;
}
return opt_ele;
if( opt_ele != null )
{
opt_ele.className = d.clas;
opt_ele.innerHTML = d.title;
}
return opt_ele;
}
function ui_create_string( parent_ele, d )
{
var ele = ui_create_ctl( parent_ele, "input", d.title, d );
var ele = ui_create_ctl( parent_ele, "input", d.title, d );
if( ele != null )
{
ele.value = d.value;
ele.addEventListener('keyup', function(e) { if(e.keyCode===13){ ui_send_string_value(this, this.value); }} );
}
if( ele != null )
{
ele.value = d.value;
ele.addEventListener('keyup', function(e) { if(e.keyCode===13){ ui_send_string_value(this, this.value); }} );
}
}
function ui_number_keyup( e )
{
console.log(e)
if( e.keyCode===13 )
{
var ele = dom_id_to_ele(e.target.id)
console.log(ele.value)
if( ele != null )
if( e.keyCode===13 )
{
ui_send_int_value(ele,ele.value);
var ele = dom_id_to_ele(e.target.id)
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);
}
}
}
}
}
function ui_create_number( parent_ele, d )
{
var ele = ui_create_ctl( parent_ele, "input", d.title, d );
if( ele != null )
{
ele.value = d.value;
ele.maxValue = d.max;
ele.minValue = d.min;
ele.stepValue = d.step;
ele.decpl = d.decpl;
ele.addEventListener('keyup', ui_number_keyup );
}
return ele;
var ele = ui_create_ctl( parent_ele, "input", d.title, d );
if( ele != null )
{
ele.value = d.value;
ele.maxValue = d.max;
ele.minValue = d.min;
ele.stepValue = d.step;
ele.decpl = d.decpl;
ele.addEventListener('keyup', ui_number_keyup );
}
return ele;
}
function ui_set_progress( ele_id, value )
{
var ele = dom_id_to_ele(ele_id);
var ele = dom_id_to_ele(ele_id);
ele.value = Math.round( ele.max * (value - ele.minValue) / (ele.maxValue - ele.minValue));
ele.value = Math.round( ele.max * (value - ele.minValue) / (ele.maxValue - ele.minValue));
}
function ui_create_progress( parent_ele, d )
{
var ele = ui_create_ctl( parent_ele, "progress", d.title, d );
var ele = ui_create_ctl( parent_ele, "progress", d.title, d );
if( ele != null )
{
ele.max = 100;
ele.maxValue = d.max;
ele.minValue = d.min;
ui_set_progress( ele.id, d.value );
}
return ele
}
function ui_create( parentId, ele_type, d )
{
var parent_ele = ui_get_parent(parentId);
var ele = null;
if( parent_ele != null )
{
d.parentJsId = parentId
switch( ele_type )
{
case "div":
ele = ui_create_div( parent_ele, d )
break;
case "title":
ele = ui_create_title( parent_ele, d )
break;
case "button":
ele = ui_create_button( parent_ele, d )
break;
case "check":
ele = ui_create_check( parent_ele, d )
break;
case "select":
ele = ui_create_select( parent_ele, d );
break;
case "option":
ele = ui_create_option( parent_ele, d );
break;
case "string":
ele = ui_create_string( parent_ele, d );
break;
case "number":
ele = ui_create_number( parent_ele, d );
break;
case "progress":
ele = ui_create_progress( parent_ele, d );
break;
default:
ui_error("Unknown UI element type: " + ele_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
{
ele.max = 100;
ele.maxValue = d.max;
ele.minValue = d.min;
ui_set_progress( ele.id, d.value );
}
return ele
}
//
function ui_set_app_uuId( d )
function ui_create( d )
{
console.log(d)
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;
if( parent_ele != null )
{
switch( d.type )
{
case "div":
ele = ui_create_div( parent_ele, d )
break;
case "title":
ele = ui_create_title( parent_ele, d )
break;
case "button":
ele = ui_create_button( parent_ele, d )
break;
case "check":
ele = ui_create_check( parent_ele, d )
break;
case "select":
ele = ui_create_select( parent_ele, d );
break;
case "option":
ele = ui_create_option( parent_ele, d );
break;
case "string":
ele = ui_create_string( parent_ele, d );
break;
case "number":
ele = ui_create_number( parent_ele, d );
break;
case "progress":
ele = ui_create_progress( parent_ele, d );
break;
default:
ui_error("Unknown UI element type: " + d.type )
}
}
}
function ws_send( s )
{
//console.log(s)
_ws.send(s+"\0")
//console.log(s)
_ws.send(s+"\0")
}
function ws_on_msg( jsonMsg )
{
console.log(jsonMsg)
d = JSON.parse(jsonMsg.data);
//console.log(jsonMsg)
d = JSON.parse(jsonMsg.data);
switch( d.op )
{
case 'create':
for (const ele_type in d.children)
switch( d.op )
{
ui_create( d.parent, ele_type, d.children[ele_type] )
//console.log(`${ele_type}: ${d.value[ele_type]}`);
}
break;
case 'create':
ui_create( d )
break;
case 'set_app_id':
ui_set_app_uuId(d)
break;
default:
ui_error("Unknown UI operation. " + d.op )
}
default:
ui_error("Unknown UI operation. " + d.op )
}
}
function ws_on_open()
{
set_app_title( "Connected", "title_connected" );
_ws.send("init")
set_app_title( "Connected", "title_connected" );
_ws.send("init")
}
function ws_on_close()
{
set_app_title( "Disconnected", "title_disconnected" );
set_app_title( "Disconnected", "title_disconnected" );
}
function ws_form_url(urlSuffix)
{
var pcol;
var u = document.URL;
var pcol;
var u = document.URL;
pcol = "ws://";
if (u.substring(0, 4) === "http")
u = u.substr(7);
pcol = "ws://";
if (u.substring(0, 4) === "http")
u = u.substr(7);
u = u.split("/");
u = u.split("/");
return pcol + u[0] + "/" + urlSuffix;
return pcol + u[0] + "/" + urlSuffix;
}
function main()
{
rootEle = dom_id_to_ele(_rootJsId);
rootEle.uuId = 0;
rootEle.id = _nextEleId;
_nextEleId += 1;
rootEle = dom_id_to_ele(_rootId);
rootEle.uuId = 0;
rootEle.id = _nextEleId;
_nextEleId += 1;
console.log(ws_form_url(""))
_ws = new WebSocket(ws_form_url(""),"ui_protocol")
_ws.onmessage = ws_on_msg
_ws.onopen = ws_on_open
_ws.onclose = ws_on_close;
//console.log(ws_form_url(""))
_ws = new WebSocket(ws_form_url(""),"ui_protocol")
_ws.onmessage = ws_on_msg
_ws.onopen = ws_on_open
_ws.onclose = ws_on_close;
}

View File

@ -5,14 +5,14 @@
div: {
jsId: "panelDivId",
name: "panelDivId",
class: "myPanelClass",
title: "My resource based panel",
children: {
button:{ jsId: myBtn1Id, title:"Push Me" },
check:{ jsId: myCheck1Id, title:"Check Me" },
button:{ name: myBtn1Id, title:"Push Me" },
check:{ name: myCheck1Id, title:"Check Me" },
}
}