From 15f64c74934f17a2ecc04a899b595c6ec17a6f99 Mon Sep 17 00:00:00 2001 From: kevin Date: Fri, 5 Nov 2021 22:21:25 -0400 Subject: [PATCH] cwUi.h/cpp: Added findNewElementUuId( h, parentUuid, ... ) Added use of eleTypePropertyA[] in cwUi.cpp - div's can now pass arbitrary element attributes. --- cwUi.cpp | 220 +++++++++++++++++++++++++-------------- cwUi.h | 8 +- html/preset_sel/js/ui.js | 186 ++++++++++++++++++++++++++------- 3 files changed, 293 insertions(+), 121 deletions(-) diff --git a/cwUi.cpp b/cwUi.cpp index f3a9c40..1544138 100644 --- a/cwUi.cpp +++ b/cwUi.cpp @@ -21,6 +21,31 @@ namespace cw { namespace ui { + typedef struct ele_type_propery_str + { + const char* label; + bool is_div_fl; + } ele_type_property_t; + + ele_type_property_t eleTypePropertyA[] = + { + { "div", true }, + { "panel", true }, + { "row", true }, + { "col", true }, + { "label", false }, + { "button", false }, + { "check", false }, + { "select", false }, + { "option", false }, + { "string", false }, + { "numb_disp", false }, + { "number", false }, + { "progress", false }, + { "log", false }, + { "list", false }, + { nullptr, false }, + }; typedef struct appIdMapRecd_str { @@ -33,8 +58,9 @@ namespace cw typedef struct ele_str { - struct ele_str* parent; // pointer to parent ele - or nullptr if this ele is the root ui ele - unsigned parentAppId; + struct ele_str* phys_parent; // pointer to actual parent ele - or nullptr if this ele is the root ui ele + struct ele_str* logical_parent; // pointer to the nearest ancestor that has a valid appId - this is useful to skip over unnamed containers like rows and columns + 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 chanId; // @@ -69,7 +95,7 @@ namespace cw for(unsigned i=0; ieleN; ++i) { ele_t* e = p->eleA[i]; - printf("%15s u:%i : u:%i a:%i %s\n",e->parent==nullptr?"" : e->parent->eleName,e->parent==nullptr? -1 :e->parent->uuId,e->uuId,e->appId,e->eleName); + printf("%15s u:%i : u:%i a:%i %s\n",e->phys_parent==nullptr?"" : e->phys_parent->eleName,e->phys_parent==nullptr? -1 :e->phys_parent->uuId,e->uuId,e->appId,e->eleName); } } @@ -104,6 +130,27 @@ namespace cw return rc; } + ele_type_property_t* _labelToEleTypeProperty( const char* label ) + { + for(unsigned i=0; eleTypePropertyA[i].label != nullptr; ++i) + if( textIsEqual(eleTypePropertyA[i].label,label) ) + return eleTypePropertyA + i; + + return nullptr; + } + + bool _isEleTypeDiv( const char* label ) + { + ele_type_property_t* etp; + if((etp = _labelToEleTypeProperty(label)) == nullptr ) + return false; + + return etp->is_div_fl; + } + + bool _isEleTypeLabel( const char* label ) + { return _labelToEleTypeProperty(label) != nullptr; } + appIdMapRecd_t* _findAppIdMap( ui_t* p, unsigned parentAppId, const char* eleName ) { appIdMapRecd_t* m = p->appIdMap; @@ -186,21 +233,37 @@ namespace cw return nullptr; } - unsigned _findElementUuId( ui_t* p, const char* eleName ) + unsigned _findElementUuId( ui_t* p, unsigned parentUuId, const char* eleName, unsigned chanId=kInvalidId ) { for(unsigned i=0; ieleN; ++i) - if( textCompare(p->eleA[i]->eleName,eleName) == 0 ) - return p->eleA[i]->uuId; - + if( p->eleA[i]->logical_parent != nullptr ) // skip the root + { + if(( parentUuId == kInvalidId || p->eleA[i]->logical_parent->uuId == parentUuId) && + ( chanId == kInvalidId || p->eleA[i]->chanId == chanId) && + ( textCompare(p->eleA[i]->eleName,eleName) == 0)) + { + return p->eleA[i]->uuId; + } + } + return kInvalidId; } - unsigned _findElementUuId( ui_t* p, unsigned appId ) + unsigned _findElementUuId( ui_t* p, unsigned parentUuId, unsigned appId, unsigned chanId=kInvalidId ) { + if( appId == kRootAppId ) + return kRootUuId; + for(unsigned i=0; ieleN; ++i) - if( p->eleA[i]->appId == appId ) - return p->eleA[i]->uuId; - + if( p->eleA[i]->logical_parent != nullptr ) //skip the root + { + if( ( parentUuId == kInvalidId || p->eleA[i]->logical_parent->uuId == parentUuId ) && + ( chanId == kInvalidId || p->eleA[i]->chanId == chanId ) && + p->eleA[i]->appId == appId ) + { + return p->eleA[i]->uuId; + } + } return kInvalidId; } @@ -300,11 +363,11 @@ namespace cw rc_t rc = kOkRC; assert( ele != nullptr ); - assert( ele->parent != nullptr ); + assert( ele->phys_parent != nullptr ); unsigned i = snprintf( p->buf, p->bufN, "{ \"op\":\"create\", \"parentUuId\":\"%i\", \"eleName\":\"%s\", \"appId\":\"%i\", \"uuId\":%i ", - ele->parent->uuId, + ele->phys_parent->uuId, ele->eleName==nullptr ? "" : ele->eleName, ele->appId, ele->uuId ); @@ -339,7 +402,7 @@ namespace cw // Note that this requires going through all the nodes and picking out the ones whose // parent uuid matches the current ele's uuid for(unsigned i=0; ieleN; ++i) - if( p->eleA[i]->uuId != kRootUuId && p->eleA[i]->uuId != ele->uuId && p->eleA[i]->parent->uuId == ele->uuId ) + if( p->eleA[i]->uuId != kRootUuId && p->eleA[i]->uuId != ele->uuId && p->eleA[i]->phys_parent->uuId == ele->uuId ) if((rc = _transmitTree(p,wsSessId,p->eleA[i]))!=kOkRC ) break; @@ -354,31 +417,32 @@ namespace cw ele_t* _createBaseEle( ui_t* p, ele_t* parent, unsigned appId, unsigned chanId, const char* eleName, const char* eleTypeStr=nullptr, const char* eleClass=nullptr, const char* eleTitle=nullptr ) { ele_t* e = mem::allocZ(); - unsigned parentAppId = kInvalidId; + ele_t* logical_parent = nullptr; - // Go up the tree looking for the first parent with a valid appId + // Go up the tree looking for the first parent with a valid appId. + // The logical parent is the first ancestor element that has a valid 'appId'. // This is useful to cover the situation where the parent is an unamed div (e.g. row, col, panel) // and the appIdMap gives the panel name as the parent. if( parent != nullptr ) { - parentAppId = parent->appId; - for(const ele_t* par=parent; par!=nullptr; par=par->parent) + for(ele_t* par=parent; par!=nullptr; par=par->phys_parent) if( par->appId != kInvalidId ) { - parentAppId = par->appId; + logical_parent = par; break; } } + + assert( appId == kRootAppId || logical_parent != nullptr ); // because the root always has a valid appid - - e->parent = parent; - e->parentAppId = parentAppId; - e->uuId = p->eleN; - e->appId = appId; - e->chanId = chanId; - e->eleName = eleName==nullptr ? nullptr : mem::duplStr(eleName); - e->attr = newDictObject(); + e->phys_parent = parent; + e->logical_parent = logical_parent; + e->uuId = p->eleN; + e->appId = appId; + e->chanId = chanId; + e->eleName = eleName==nullptr ? nullptr : mem::duplStr(eleName); + e->attr = newDictObject(); if( eleTypeStr != nullptr ) e->attr->insert_pair("type",eleTypeStr); @@ -408,7 +472,7 @@ namespace cw appIdMapRecd_t* m; // ... then try to look it up from the appIdMap. - if((m = _findAppIdMap(p, e->parentAppId, eleName)) != nullptr ) + if((m = _findAppIdMap(p, e->logical_parent->appId, eleName)) != nullptr ) e->appId = m->appId; } @@ -448,23 +512,6 @@ namespace cw return rc; } - - bool _is_div_type( const char* eleType ) - { - const char* divAliasA[] = { "div","row","col","panel",nullptr }; // all these types are div's - bool divAliasFl = false; - - // is this element a 'div' alias? - for(unsigned i=0; divAliasA[i]!=nullptr; ++i) - if( textCompare(divAliasA[i],eleType) == 0 ) - { - divAliasFl = true; - break; - } - - return divAliasFl; - } - rc_t _createElementsFromChildList( ui_t* p, const object_t* po, unsigned wsSessId, ele_t* parentEle, unsigned chanId ); rc_t _createEleFromRsrsc( ui_t* p, ele_t* parentEle, const char* eleType, unsigned chanId, const object_t* srcObj, unsigned wsSessId ) @@ -486,7 +533,7 @@ namespace cw co->unlink(); } - divAliasFl = _is_div_type(eleType); + divAliasFl = _isEleTypeDiv(eleType); // get the ui ele name if((rc = o->get("name",eleName, cw::kOptionalFl)) != kOkRC ) @@ -508,9 +555,7 @@ namespace cw rc = cwLogError(kOpFailRC,"The local element '%s' could not be created.",cwStringNullGuard(eleName)); goto errLabel; } - - - if( !divAliasFl ) + else { unsigned childN = o->child_count(); unsigned child_idx = 0; @@ -523,16 +568,15 @@ namespace cw //if( textCompare(eleType,"list")==0 ) // printf("%i list: %s %i\n",i,pair_label,o->child_count()); - - if( textCompare(pair_label,"name") != 0 && _is_div_type(pair_label)==false ) + + // skip the 'name' attribute any child notes that refer to child elements + if( textIsEqual(pair_label,"name") || _isEleTypeLabel(pair_label) ) + child_idx += 1; + else { child->unlink(); ele->attr->append_child(child); } - else - { - child_idx += 1; - } } } @@ -1035,7 +1079,7 @@ cw::rc_t cw::ui::onReceive( handle_t h, unsigned wsSessId, const void* msg, unsi cwLogError(kOpFailRC,"UI Value message parse failed."); else { - p->uiCbFunc( p->uiCbArg, wsSessId, opId, ele->parentAppId, ele->uuId, ele->appId, ele->chanId, &value ); + p->uiCbFunc( p->uiCbArg, wsSessId, opId, ele->logical_parent->appId, ele->uuId, ele->appId, ele->chanId, &value ); } break; @@ -1045,7 +1089,7 @@ cw::rc_t cw::ui::onReceive( handle_t h, unsigned wsSessId, const void* msg, unsi cwLogError(kOpFailRC,"UI Value message parse failed."); else { - p->uiCbFunc( p->uiCbArg, wsSessId, opId, ele->parentAppId, ele->uuId, ele->appId, ele->chanId, &value ); + p->uiCbFunc( p->uiCbArg, wsSessId, opId, ele->logical_parent->appId, ele->uuId, ele->appId, ele->chanId, &value ); } break; @@ -1054,7 +1098,7 @@ cw::rc_t cw::ui::onReceive( handle_t h, unsigned wsSessId, const void* msg, unsi cwLogError(kOpFailRC,"UI Echo message parse failed."); else { - p->uiCbFunc( p->uiCbArg, wsSessId, opId, ele->parentAppId, ele->uuId, ele->appId, ele->chanId,nullptr ); + p->uiCbFunc( p->uiCbArg, wsSessId, opId, ele->logical_parent->appId, ele->uuId, ele->appId, ele->chanId,nullptr ); } break; @@ -1075,12 +1119,12 @@ cw::rc_t cw::ui::onReceive( handle_t h, unsigned wsSessId, const void* msg, unsi return rc; } -unsigned cw::ui::findElementAppId( handle_t h, unsigned parentAppId, const char* eleName ) +unsigned cw::ui::parentAndNameToAppId( handle_t h, unsigned parentAppId, const char* eleName ) { ui_t* p = _handleToPtr(h); for(unsigned i=0; ieleN; ++i) - if( p->eleA[i]->parentAppId==parentAppId && strcmp(p->eleA[i]->eleName,eleName) == 0 ) + if( p->eleA[i]->logical_parent->appId==parentAppId && strcmp(p->eleA[i]->eleName,eleName) == 0 ) return p->eleA[i]->appId; return kInvalidId; @@ -1091,7 +1135,7 @@ unsigned cw::ui::parentAndNameToUuId( handle_t h, unsigned parentAppId, const ch ui_t* p = _handleToPtr(h); for(unsigned i=0; ieleN; ++i) - if( p->eleA[i]->parentAppId==parentAppId && strcmp(p->eleA[i]->eleName,eleName) == 0 ) + if( p->eleA[i]->logical_parent->appId==parentAppId && strcmp(p->eleA[i]->eleName,eleName) == 0 ) return p->eleA[i]->uuId; return kInvalidId; @@ -1102,8 +1146,8 @@ unsigned cw::ui::parentAndAppIdToUuId( handle_t h, unsigned parentAppId, unsigne ui_t* p = _handleToPtr(h); for(unsigned i=0; ieleN; ++i) - if(((p->eleA[i]->parent==nullptr && parentAppId==kRootAppId) || - (p->eleA[i]->parentAppId==parentAppId)) + if(((p->eleA[i]->phys_parent==nullptr && parentAppId==kRootAppId) || + (p->eleA[i]->logical_parent->appId==parentAppId)) && p->eleA[i]->appId == appId ) return p->eleA[i]->uuId; return kInvalidId; @@ -1115,21 +1159,6 @@ const char* cw::ui::findElementName( handle_t h, unsigned uuId ) return _findEleEleName(p,uuId); } -unsigned cw::ui::findElementUuId( handle_t h, const char* eleName ) -{ - ui_t* p = _handleToPtr(h); - - return _findElementUuId(p,eleName); -} - -unsigned cw::ui::findElementUuId( handle_t h, unsigned appId ) -{ - ui_t* p = _handleToPtr(h); - - return _findElementUuId(p,appId); -} - - unsigned cw::ui::findElementAppId( handle_t h, unsigned uuId ) { ui_t* p = _handleToPtr(h); @@ -1139,6 +1168,35 @@ unsigned cw::ui::findElementAppId( handle_t h, unsigned uuId ) return ele==nullptr ? kInvalidId : ele->uuId; } +unsigned cw::ui::findElementUuId( handle_t h, const char* eleName, unsigned chanId ) +{ + ui_t* p = _handleToPtr(h); + + return _findElementUuId(p,kInvalidId,eleName,chanId); +} + +unsigned cw::ui::findElementUuId( handle_t h, unsigned appId, unsigned chanId ) +{ + ui_t* p = _handleToPtr(h); + + return _findElementUuId(p,kInvalidId,appId,chanId); +} + +unsigned cw::ui::findElementUuId( handle_t h, unsigned parentUuId, const char* eleName, unsigned chanId ) +{ + ui_t* p = _handleToPtr(h); + + return _findElementUuId(p,parentUuId, eleName,chanId); +} + +unsigned cw::ui::findElementUuId( handle_t h, unsigned parentUuId, unsigned appId, unsigned chanId ) +{ + ui_t* p = _handleToPtr(h); + + return _findElementUuId(p,parentUuId,appId,chanId); +} + + cw::rc_t cw::ui::createFromObject( handle_t h, const object_t* o, unsigned parentUuId, unsigned chanId, const char* fieldName ) { @@ -1475,10 +1533,10 @@ void cw::ui::report( handle_t h ) { const ele_t* e = p->eleA[i]; - unsigned parUuId = e->parent==NULL ? kInvalidId : e->parent->uuId; - const char* parEleName = e->parent==NULL || e->parent->eleName == NULL ? "" : e->parent->eleName; + unsigned parUuId = e->phys_parent==NULL ? kInvalidId : e->phys_parent->uuId; + const char* parEleName = e->phys_parent==NULL || e->phys_parent->eleName == NULL ? "" : e->phys_parent->eleName; - printf("uu:%5i app:%5i %20s : parent uu:%5i app:%5i %20s ", e->uuId, e->appId, e->eleName == NULL ? "" : e->eleName, parUuId, e->parentAppId, parEleName ); + printf("uu:%5i app:%5i %20s : parent uu:%5i app:%5i %20s ", e->uuId, e->appId, e->eleName == NULL ? "" : e->eleName, parUuId, e->logical_parent->appId, parEleName ); for(unsigned i=0; iattr->child_count(); ++i) { diff --git a/cwUi.h b/cwUi.h index 043374d..3717c80 100644 --- a/cwUi.h +++ b/cwUi.h @@ -45,7 +45,7 @@ namespace cw rc_t onReceive( handle_t h, unsigned wsSessId, const void* msg, unsigned byteN ); // Locate an element whose parent uuid is 'parentUuId' with a child named 'eleName'. - unsigned findElementAppId( handle_t h, unsigned parentAppId, const char* eleName ); + unsigned parentAndNameToAppId( handle_t h, unsigned parentAppId, const char* eleName ); unsigned parentAndNameToUuId( handle_t h, unsigned parentAppId, const char* eleName ); unsigned parentAndAppIdToUuId( handle_t h, unsigned parentAppId, unsigned appId ); @@ -53,8 +53,10 @@ namespace cw unsigned findElementAppId( handle_t h, unsigned uuId ); // Return the uuid of the first matching 'eleName' or 'appId'. - unsigned findElementUuId( handle_t h, const char* eleName ); - unsigned findElementUuId( handle_t h, unsigned appId ); + unsigned findElementUuId( handle_t h, const char* eleName, unsigned chanId = kInvalidId ); + unsigned findElementUuId( handle_t h, unsigned appId, unsigned chanId = kInvalidId ); + unsigned findElementUuId( handle_t h, unsigned parentUuId, const char* eleName, unsigned chanId = kInvalidId ); + unsigned findElementUuId( handle_t h, unsigned parentUuId, unsigned appId, unsigned chanId = kInvalidId ); // Create multiple UI elements from an object_t representation. diff --git a/html/preset_sel/js/ui.js b/html/preset_sel/js/ui.js index 2043de7..8b9ece4 100644 --- a/html/preset_sel/js/ui.js +++ b/html/preset_sel/js/ui.js @@ -237,6 +237,14 @@ function ui_send_int_value( ele, value ) { ui_send_value(ele,'i',value); } function ui_send_float_value( ele, value ) { ui_send_value(ele,'f',value); } function ui_send_string_value( ele, value ) { ui_send_value(ele,'s',value); } +function ui_send_click( ele ) +{ + console.log("click " + ele.id ) + + ws_send("click " + ele.id ) +} + + function ui_send_echo( ele ) { ws_send("echo " + ele.id ) @@ -267,6 +275,11 @@ function ui_get_parent( parentId ) return parent_ele; } +function ui_on_click( ele, evt ) +{ + ui_send_click(ele); + evt.stopPropagation(); +} function ui_create_ele( parent_ele, ele_type, d, dfltClassName ) { @@ -284,16 +297,29 @@ function ui_create_ele( parent_ele, ele_type, d, dfltClassName ) else ele.className = dfltClassName; + if(d.hasOwnProperty('addClassName') ) + { + ele.className += " " + d.addClassName + } + if(d.hasOwnProperty('appId')) ele.appId = d.appId; else ele.appId = null; + if( d.hasOwnProperty('clickable') ) + ui_set_clickable( ele, d.clickable ); + + if( d.hasOwnProperty('enable') ) + ui_set_enable( ele, d.enable ) + //console.log("Created: " + ele_type + " parent:" + d.parentUuId + " id:" + ele.id + " appId:" + ele.appId) parent_ele.appendChild(ele); + + } return ele } @@ -355,10 +381,12 @@ function ui_create_div( parent_ele, d ) function ui_create_panel_div( parent_ele, d ) { d.type = "div" - var div_ele = ui_create_div( parent_ele, d ); if( !d.hasOwnProperty('className') ) - div_ele.className = "uiPanel" + d.className = "uiPanel" + + var div_ele = ui_create_div( parent_ele, d ); + return div_ele } @@ -366,10 +394,12 @@ function ui_create_panel_div( parent_ele, d ) function ui_create_row_div( parent_ele, d ) { d.type = "div" - var div_ele = ui_create_div( parent_ele, d ); if( !d.hasOwnProperty('className') ) - div_ele.className = "uiRow" + d.className = "uiRow" + + var div_ele = ui_create_div( parent_ele, d ); + return div_ele } @@ -377,10 +407,12 @@ function ui_create_row_div( parent_ele, d ) function ui_create_col_div( parent_ele, d ) { d.type = "div" - var div_ele = ui_create_div( parent_ele, d ); if( !d.hasOwnProperty('className') ) - div_ele.className = "uiCol" + d.className = "uiCol" + + var div_ele = ui_create_div( parent_ele, d ); + return div_ele } @@ -650,6 +682,8 @@ function ui_create_number( parent_ele, d ) function ui_set_number_display( ele_id, value ) { + //console.log("Numb disp: " + ele_id + " " + value) + var ele = dom_id_to_ele(ele_id); if( typeof(value)=="number") @@ -736,25 +770,6 @@ function _on_log_click( evt ) pre_ele.auto_scroll_flag = !pre_ele.auto_scroll_flag; } - -function ui_create_log( parent_ele, d ) -{ - - // create a containing div with the label - d.className = "uiLog" - var log_ele = ui_create_ctl( parent_ele, "div", d.title, d, "uiLog" ) - - // add a
 to the containing div
-    var ele = dom_create_ele("pre")
-    
-    ele.id      = log_ele.id + "_pre"  
-    ele.onclick = _on_log_click;
-    ele.auto_scroll_flag = true;
-    
-    log_ele.appendChild(ele)
-
-    return log_ele
-}
 
 function ui_set_log_text( ele, value )
 {
@@ -772,10 +787,34 @@ function ui_set_log_text( ele, value )
 	    
 	    break;
 	}
-    }
-    
+    }    
 }
 
+function ui_create_log( parent_ele, d )
+{
+    // create a containing div with the label
+    d.className = "uiLog"
+    var log_ele  = ui_create_ctl( parent_ele, "div", d.title, d, "uiLog" )
+
+    // add a 
 to the containing div
+    var ele = dom_create_ele("pre")
+    
+    ele.id      = log_ele.id + "_pre"  
+    ele.onclick = _on_log_click;
+    ele.auto_scroll_flag = true;
+    
+    log_ele.appendChild(ele)
+
+    return log_ele
+}
+
+function ui_create_list( parent_ele, d )
+{
+    //console.log(d)
+    var list_ele  = ui_create_ctl( parent_ele, "div", d.title, d, "uiList" )
+    
+    return list_ele
+}
 
 function ui_set_value( d )
 {
@@ -843,11 +882,69 @@ function ui_set_value( d )
 	    break
 	    
 	    default:
-	    ui_error("Unknown UI element type: " + d.type )
+	    ui_error("Unknown UI element type on set value: " + d.type )
 	}
     }
 }
 
+function _ui_modify_class( ele, classLabelArg, enableFl )
+{
+    let classLabel  = " " + classLabelArg; // prefix the class label with a space
+    
+    let isEnabledFl = ele.className.includes(classLabel)
+
+    // if the class is not already enabled/disabled
+    if( enableFl != isEnabledFl )
+    {
+	if( enableFl )
+	    ele.className += classLabel;
+	else
+	    ele.className = ele.className.replace(classLabel, "");
+    }
+}
+
+function ui_set_select( ele, enableFl )
+{
+    _ui_modify_class("uiSelected")
+}
+
+
+function ui_set_clickable( ele, enableFl )
+{
+    ele.clickableFl = enableFl
+    
+    if(enableFl)
+	ele.onclick = function( evt ){ ui_on_click( this, evt ); }
+    else
+	ele.onclick = null
+}
+
+function ui_set_visible( ele, enableFl )
+{    
+    if(enableFl)
+    {
+	if(ele.hasOwnProperty("style_display") )
+	{
+	    ele.style.display = ele.style_display;
+	}
+	else
+	{
+	    ele.style.display = "block";
+	}
+    }
+    else
+    {
+	ele.style_display = ele.style.display;
+	ele.style.display = "none";
+    }
+}
+
+function ui_set_enable( ele, enableFl )
+{
+    ele.disabled = !enableFl
+}
+
+
 function ui_set( d )
 {
     //console.log(d)
@@ -855,24 +952,35 @@ function ui_set( d )
 
     if( ele == null )
 	console.log("ele not found");
-    else
-	if( !ele.hasOwnProperty("uiEleType") )
-	    console.log("No type");
     
-    if( ele != null && ele.hasOwnProperty("uiEleType"))
+    if( ele != null)
     {
-	//console.log("found: "+ele.uiEleType)
-	
-	switch( ele.uiEleType )
+	switch( d.type )
 	{
-	    case "number":
+	    case "number_range":
 	    ui_set_number_range(ele, d)
 	    break;
 
-	    case "progress":
+	    case "progress_range":
 	    ui_set_prog_range(ele, d)
 	    break;
 
+	    case "select":
+	    ui_set_select(ele,d.enableFl)
+	    break
+
+	    case "clickable":
+	    ui_set_clickable(ele,d.enableFl)
+	    break
+
+	    case "visible":
+	    ui_set_visible(ele,d.enableFl)
+	    break
+
+	    case "enable":
+	    ui_set_enable(ele,d.enableFl)
+	    break
+	    
 	}
     }
 }
@@ -952,6 +1060,10 @@ function ui_create( d )
 	    case "log":
 	    ele = ui_create_log( parent_ele, d );
 	    break;
+
+	    case "list":
+	    ele = ui_create_list( parent_ele, d );
+	    break;
 	    
 	    default:
 	    ui_error("Unknown UI element type: " + d.type )