diff --git a/cwIo.cpp b/cwIo.cpp index 3539e6d..d6d37d8 100644 --- a/cwIo.cpp +++ b/cwIo.cpp @@ -2624,12 +2624,12 @@ cw::rc_t cw::io::uiCreateDiv( handle_t h, unsigned& uuIdRef, unsigned wsS return rc; } -cw::rc_t cw::io::uiCreateTitle( handle_t h, unsigned& uuIdRef, unsigned wsSessId, unsigned parentUuId, const char* eleName, unsigned appId, const char* clas, const char* title ) +cw::rc_t cw::io::uiCreateLabel( handle_t h, unsigned& uuIdRef, unsigned wsSessId, unsigned parentUuId, const char* eleName, unsigned appId, const char* clas, const char* title ) { rc_t rc; ui::handle_t uiH; if((rc = _handleToUiHandle(h,uiH)) == kOkRC ) - rc = ui::createTitle(uiH,uuIdRef,wsSessId,parentUuId,eleName,appId,clas,title); + rc = ui::createLabel(uiH,uuIdRef,wsSessId,parentUuId,eleName,appId,clas,title); return rc; } @@ -2750,15 +2750,34 @@ cw::rc_t cw::io::uiCreateProg( handle_t h, unsigned& uuIdRef, unsigned wsS return rc; } -cw::rc_t cw::io::uiCreateText( handle_t h, unsigned& uuIdRef, unsigned wsSessId, unsigned parentUuId, const char* eleName, unsigned appId, const char* clas, const char* title ) +cw::rc_t cw::io::uiCreateLog( handle_t h, unsigned& uuIdRef, unsigned wsSessId, unsigned parentUuId, const char* eleName, unsigned appId, const char* clas, const char* title ) { rc_t rc; ui::handle_t uiH; if((rc = _handleToUiHandle(h,uiH)) == kOkRC ) - rc = ui::createText(uiH,uuIdRef,wsSessId,parentUuId,eleName,appId,clas,title); + rc = ui::createLog(uiH,uuIdRef,wsSessId,parentUuId,eleName,appId,clas,title); return rc; } +cw::rc_t cw::io::uiSetNumbRange( handle_t h, unsigned wsSessId, unsigned uuId, double minValue, double maxValue, double stepValue, unsigned decPl, double value ) +{ + rc_t rc; + ui::handle_t uiH; + if((rc = _handleToUiHandle(h,uiH)) == kOkRC ) + rc = ui::setNumbRange(uiH,wsSessId,uuId,minValue,maxValue,stepValue,decPl,value); + return rc; +} + +cw::rc_t cw::io::uiSetProgRange( handle_t h, unsigned wsSessId, unsigned uuId, double minValue, double maxValue, double value ) +{ + rc_t rc; + ui::handle_t uiH; + if((rc = _handleToUiHandle(h,uiH)) == kOkRC ) + rc = ui::setProgRange(uiH,wsSessId,uuId,minValue,maxValue,value); + return rc; +} + + cw::rc_t cw::io::uiRegisterAppIdMap( handle_t h, const ui::appIdMap_t* map, unsigned mapN ) { rc_t rc; diff --git a/cwIo.h b/cwIo.h index d98628b..b36169f 100644 --- a/cwIo.h +++ b/cwIo.h @@ -279,7 +279,7 @@ namespace cw rc_t uiCreateFromFile( handle_t h, const char* fn, unsigned wsSessId, unsigned parentUuId=kInvalidId); rc_t uiCreateFromText( handle_t h, const char* text, unsigned wsSessId, unsigned parentUuId=kInvalidId); rc_t uiCreateDiv( handle_t h, unsigned& uuIdRef, unsigned wsSessId, unsigned parentUuId, const char* eleName, unsigned appId, const char* clas, const char* title ); - rc_t uiCreateTitle( handle_t h, unsigned& uuIdRef, unsigned wsSessId, unsigned parentUuId, const char* eleName, unsigned appId, const char* clas, const char* title ); + rc_t uiCreateLabel( handle_t h, unsigned& uuIdRef, unsigned wsSessId, unsigned parentUuId, const char* eleName, unsigned appId, const char* clas, const char* title ); rc_t uiCreateButton( handle_t h, unsigned& uuIdRef, unsigned wsSessId, unsigned parentUuId, const char* eleName, unsigned appId, const char* clas, const char* title ); // Create check: w/o value. The value will be read from the engine via the UI 'echo' event. @@ -302,8 +302,12 @@ namespace cw rc_t uiCreateProg( handle_t h, unsigned& uuIdRef, unsigned wsSessId, unsigned parentUuId, const char* eleName, unsigned appId, const char* clas, const char* title, double minValue, double maxValue ); rc_t uiCreateProg( handle_t h, unsigned& uuIdRef, unsigned wsSessId, unsigned parentUuId, const char* eleName, unsigned appId, const char* clas, const char* title, double minValue, double maxValue, double value ); - rc_t uiCreateText( handle_t h, unsigned& uuIdRef, unsigned wsSessId, unsigned parentUuId, const char* eleName, unsigned appId, const char* clas, const char* title ); + rc_t uiCreateLog( handle_t h, unsigned& uuIdRef, unsigned wsSessId, unsigned parentUuId, const char* eleName, unsigned appId, const char* clas, const char* title ); + + rc_t uiSetNumbRange( handle_t h, unsigned wsSessId, unsigned uuId, double minValue, double maxValue, double stepValue, unsigned decPl, double value ); + rc_t uiSetProgRange( handle_t h, unsigned wsSessId, unsigned uuId, double minValue, double maxValue, double value ); + // Register parent/child/name app id's rc_t uiRegisterAppIdMap( handle_t h, const ui::appIdMap_t* map, unsigned mapN ); diff --git a/cwUi.cpp b/cwUi.cpp index cd676a1..85465ff 100644 --- a/cwUi.cpp +++ b/cwUi.cpp @@ -444,7 +444,7 @@ namespace cw if((rc = o->get("name",eleName, cw::kNoRecurseFl | cw::kOptionalFl)) != kOkRC ) { // div's and titles don't need a 'name' - if( rc == kLabelNotFoundRC && (divAliasFl || textCompare(eleType,"title")==0) ) + if( rc == kLabelNotFoundRC && (divAliasFl || textCompare(eleType,"label")==0) ) rc = kOkRC; else { @@ -1086,8 +1086,8 @@ cw::rc_t cw::ui::createFromText( handle_t h, const char* text, unsigned wsSessId 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* eleName, unsigned appId, const char* clas, const char* title ) -{ return _createOneEle( _handleToPtr(h), uuIdRef, "title", wsSessId, parentUuId, eleName, appId, clas, title ); } +cw::rc_t cw::ui::createLabel( handle_t h, unsigned& uuIdRef, unsigned wsSessId, unsigned parentUuId, const char* eleName, unsigned appId, const char* clas, const char* title ) +{ return _createOneEle( _handleToPtr(h), uuIdRef, "label", wsSessId, parentUuId, eleName, 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 ); } @@ -1128,9 +1128,94 @@ cw::rc_t cw::ui::createProg( handle_t h, unsigned& uuIdRef, unsigned wsSessId, cw::rc_t cw::ui::createProg( handle_t h, unsigned& uuIdRef, unsigned wsSessId, unsigned parentUuId, const char* eleName, unsigned appId, const char* clas, const char* title, double minValue, double maxValue, double value ) { 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* eleName, unsigned appId, const char* clas, const char* title ) +cw::rc_t cw::ui::createLog( handle_t h, unsigned& uuIdRef, unsigned wsSessId, unsigned parentUuId, const char* eleName, unsigned appId, const char* clas, const char* title ) +{ return _createOneEle( _handleToPtr(h), uuIdRef, "log", wsSessId, parentUuId, eleName, appId, clas, title); } + +cw::rc_t cw::ui::setNumbRange( handle_t h, unsigned wsSessId, unsigned uuId, double minValue, double maxValue, double stepValue, unsigned decPl, double value ) { - rc_t rc= kOkRC; + rc_t rc = kOkRC; + ui_t* p = _handleToPtr(h); + + const char* mFmt = "{ \"op\":\"set\", \"uuId\":%i, \"min\":%f, \"max\":%f, \"step\":%f, \"decpl\":%i, \"value\":%f }"; + const int mbufN = 256; + char mbuf[mbufN]; + + if( snprintf(mbuf,mbufN,mFmt,uuId,minValue,maxValue,stepValue,decPl,value) >= mbufN-1 ) + return cwLogError(kBufTooSmallRC,"The msg buffer is too small."); + + rc = _websockSend(p,wsSessId,mbuf); + + return rc; +} + +cw::rc_t cw::ui::setProgRange( handle_t h, unsigned wsSessId, unsigned uuId, double minValue, double maxValue, double value ) +{ + rc_t rc = kOkRC; + ui_t* p = _handleToPtr(h); + + const char* mFmt = "{ \"op\":\"set\", \"uuId\":%i, \"min\":%f, \"max\":%f, \"value\":%f }"; + const int mbufN = 256; + char mbuf[mbufN]; + + if( snprintf(mbuf,mbufN,mFmt,uuId,minValue,maxValue,value) >= mbufN-1 ) + return cwLogError(kBufTooSmallRC,"The msg buffer is too small."); + + rc = _websockSend(p,wsSessId,mbuf); + + return rc; +} + +cw::rc_t cw::ui::setLogLine( handle_t h, unsigned wsSessId, unsigned uuId, const char* text ) +{ + rc_t rc = kOkRC; + + unsigned n = 0; + const char* c = text; + for(; *c; ++c ) + if( *c == '\n') + ++n; + + if( n == 0 ) + rc = sendValueString(h,wsSessId,uuId,text); + else + { + int sn = textLength(text); + sn += n + 1; + + char s[ sn ]; + unsigned i,j; + for( i=0,j=0; text[i]; ++i,++j) + { + char ch = text[i]; + bool escape_fl = true; + + switch( ch ) + { + case '\\': ch='\\'; break; + case '\b': ch='b'; break; + case '\f': ch='f'; break; + case '\n': ch='n'; break; + case '\r': ch='r'; break; + case '\t': ch='t'; break; + default: + escape_fl = false; + break; + } + + if( escape_fl ) + s[j++] = '\\'; + + s[j] = ch; + } + + s[sn-1] = 0; + + printf("%s %s\n",text,s); + + rc = sendValueString(h,wsSessId,uuId,s); + + } + return rc; } diff --git a/cwUi.h b/cwUi.h index ffe8756..5429a17 100644 --- a/cwUi.h +++ b/cwUi.h @@ -82,7 +82,7 @@ namespace cw // 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 createLabel( 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 ); // Create check: w/o value. The value will be read from the engine via the UI 'echo' event. @@ -101,8 +101,12 @@ namespace cw rc_t createNumb( handle_t h, unsigned& uuIdRef, unsigned wsSessId, unsigned parentUuId, const char* eleName, unsigned appId, const char* clas, const char* title, double minValue, double maxValue, double stepValue, unsigned decPl, double value ); rc_t createProg( handle_t h, unsigned& uuIdRef, unsigned wsSessId, unsigned parentUuId, const char* eleName, unsigned appId, const char* clas, const char* title, double minValue, double maxValue ); rc_t createProg( handle_t h, unsigned& uuIdRef, unsigned wsSessId, unsigned parentUuId, const char* eleName, unsigned appId, const char* clas, const char* title, double minValue, double maxValue, double value ); - rc_t createText( handle_t h, unsigned& uuIdRef, unsigned wsSessId, unsigned parentUuId, const char* eleName, unsigned appId, const char* clas, const char* title ); + rc_t createLog( handle_t h, unsigned& uuIdRef, unsigned wsSessId, unsigned parentUuId, const char* eleName, unsigned appId, const char* clas, const char* title ); + rc_t setNumbRange( handle_t h, unsigned wsSessId, unsigned uuId, double minValue, double maxValue, double stepValue, unsigned decPl, double value ); + rc_t setProgRange( handle_t h, unsigned wsSessId, unsigned uuId, double minValue, double maxValue, double value ); + rc_t setLogLine( handle_t h, unsigned wsSessId, unsigned uuId, const char* text ); + // Register parent/child/name app id's rc_t registerAppIdMap( handle_t h, const appIdMap_t* map, unsigned mapN ); @@ -114,6 +118,8 @@ namespace cw rc_t sendValueFloat( handle_t h, unsigned wsSessId, unsigned uuId, float value ); rc_t sendValueDouble( handle_t h, unsigned wsSessId, unsigned uuId, double value ); rc_t sendValueString( handle_t h, unsigned wsSessId, unsigned uuId, const char* value ); + + namespace ws { diff --git a/cwUiTest.cpp b/cwUiTest.cpp index f4edc74..0a80e3e 100644 --- a/cwUiTest.cpp +++ b/cwUiTest.cpp @@ -32,6 +32,9 @@ namespace cw bool appCheck2Fl; float appNumb; unsigned appSelId; + + unsigned myPanelUuId; + unsigned logUuId; } ui_test_t; @@ -51,6 +54,7 @@ namespace cw kIntegerId, kFloatId, kProgressId, + kLogId, // Resource Based elements kPanelDivId, @@ -70,23 +74,22 @@ namespace cw rc_t rc = kOkRC; unsigned uuid = kInvalidId; unsigned selUuId = kInvalidId; - unsigned divUuId = kInvalidId; handle_t uiH = srv::uiHandle(p->wsUiSrvH); // Create a UI elements programatically. - if((rc = createDiv( uiH, divUuId, wsSessId, kInvalidId, "myDivId", kDivId, "divClass", "My Panel" )) != kOkRC ) + if((rc = createDiv( uiH, p->myPanelUuId, wsSessId, kInvalidId, "myDivId", kDivId, "divClass", "My Panel" )) != kOkRC ) goto errLabel; - if((rc = createButton( uiH, uuid, wsSessId, divUuId, "myBtnId", kBtnId, "btnClass", "Quit" )) != kOkRC ) + if((rc = createButton( uiH, uuid, wsSessId, p->myPanelUuId, "myBtnId", kBtnId, "btnClass", "Quit" )) != kOkRC ) goto errLabel; - if((rc = createCheck( uiH, uuid, wsSessId, divUuId, "myCheckId", kCheckId, "checkClass", "Check Me", true )) != kOkRC ) + if((rc = createCheck( uiH, uuid, wsSessId, p->myPanelUuId, "myCheckId", kCheckId, "checkClass", "Check Me", true )) != kOkRC ) goto errLabel; - if((rc = createSelect( uiH, selUuId, wsSessId, divUuId, "mySelId", kSelectId, "selClass", "Select" )) != kOkRC ) + if((rc = createSelect( uiH, selUuId, wsSessId, p->myPanelUuId, "mySelId", kSelectId, "selClass", "Select" )) != kOkRC ) goto errLabel; if((rc = createOption( uiH, uuid, wsSessId, selUuId, "myOpt0Id", kOption0Id, "optClass", "Option 0" )) != kOkRC ) @@ -98,16 +101,20 @@ namespace cw if((rc = createOption( uiH, uuid, wsSessId, selUuId, "myOpt2Id", kOption2Id, "optClass", "Option 2" )) != kOkRC ) goto errLabel; - if((rc = createStr( uiH, uuid, wsSessId, divUuId, "myStringId", kStringId, "stringClass", "String", "a string value" )) != kOkRC ) + if((rc = createStr( uiH, uuid, wsSessId, p->myPanelUuId, "myStringId", kStringId, "stringClass", "String", "a string value" )) != kOkRC ) goto errLabel; - if((rc = createNumb( uiH, uuid, wsSessId, divUuId, "myIntegerId", kIntegerId, "integerClass", "Integer", 0, 100, 1, 0, 10 )) != kOkRC ) + if((rc = createNumb( uiH, uuid, wsSessId, p->myPanelUuId, "myIntegerId", kIntegerId, "integerClass", "Integer", 0, 100, 1, 0, 10 )) != kOkRC ) goto errLabel; - if((rc = createNumb( uiH, uuid, wsSessId, divUuId, "myFloatId", kFloatId, "floatClass", "Float", 0.53, 100.97, 1.0, 5, 10.0 )) != kOkRC ) + if((rc = createNumb( uiH, uuid, wsSessId, p->myPanelUuId, "myFloatId", kFloatId, "floatClass", "Float", 0.53, 100.97, 1.0, 5, 10.0 )) != kOkRC ) goto errLabel; - if((rc = createProg( uiH, uuid, wsSessId, divUuId, "myProgressId", kProgressId, "progressClass", "Progress", 0, 10, 5 )) != kOkRC ) + if((rc = createProg( uiH, uuid, wsSessId, p->myPanelUuId, "myProgressId", kProgressId, "progressClass", "Progress", 0, 10, 5 )) != kOkRC ) + goto errLabel; + + + if((rc = createLog( uiH, p->logUuId, wsSessId, p->myPanelUuId, "myLogId", kLogId, "logClass", "My Log (click toggles auto-scroll)" )) != kOkRC ) goto errLabel; //if((rc = createFromFile( uiH, p->uiCfgFn, wsSessId )) != kOkRC ) @@ -132,7 +139,19 @@ namespace cw p->appSelId); } - + + rc_t _insert_log_line( ui_test_t* p, unsigned wsSessId, const char* text ) + { + + rc_t rc = kOkRC; + + handle_t uiH = srv::uiHandle(p->wsUiSrvH); + + //rc = ui::sendValueString( uiH, wsSessId, p->logUuId, text ); + rc = ui::setLogLine( uiH, wsSessId, p->logUuId, text ); + + return rc; + } rc_t _handleUiValueMsg( ui_test_t* p, unsigned wsSessId, unsigned parentAppId, unsigned uuId, unsigned appId, const value_t* v ) { @@ -147,6 +166,7 @@ namespace cw case kCheckId: printf("Check:%i\n", v->u.b); p->appCheckFl = v->u.b; + _insert_log_line( p, wsSessId, "check!\n" ); break; case kSelectId: @@ -162,8 +182,14 @@ namespace cw break; case kIntegerId: - printf("Integer: %i\n",v->u.i); - p->appInteger = v->u.i; + { + printf("Integer: %i\n",v->u.i); + p->appInteger = v->u.i; + + handle_t uiH = srv::uiHandle(p->wsUiSrvH); + unsigned progUuId = findElementUuId( uiH, p->myPanelUuId, kProgressId ); + sendValueInt( uiH, wsSessId, progUuId, v->u.i ); + } break; case kFloatId: diff --git a/html/uiTest/css/ui.css b/html/uiTest/css/ui.css index 509e421..195c9c1 100644 --- a/html/uiTest/css/ui.css +++ b/html/uiTest/css/ui.css @@ -40,6 +40,7 @@ label { } + .uiCtlDiv { display: flex; flex-direction: row; @@ -73,3 +74,37 @@ label { background-color: LightBlue; } + +/* outer log div - contains the log label and the log scroller */ +.uiLogDiv { + display: flex; + flex-direction: column; + + align-items: flex-start; /* left justify */ + align-content: flex-stretch; /* fill horizontal space */ + +} + +.uiLogDiv label { + width: 100%; +} + + +/* log scroller */ +.uiLog { + display:flex; + flex-direction: column; + + height: 150px; + overflow-x: hidden; /* 'hidden' to remove scroll bar */ + overflow-y: scroll; + width: 100%; + + background-color: PowderBlue; + +} + +/* The log text */ +.uiLog pre { + +} diff --git a/html/uiTest/js/ui.js b/html/uiTest/js/ui.js index 8c6f8c4..00e2041 100644 --- a/html/uiTest/js/ui.js +++ b/html/uiTest/js/ui.js @@ -384,10 +384,10 @@ function ui_create_col_div( parent_ele, d ) } -function ui_create_title( parent_ele, d ) +function ui_create_label( parent_ele, d ) { - var ele = ui_create_ele( parent_ele, "label", d, "uiTitle" ); - + var ele = ui_create_ele( parent_ele, "label", d, "uiLabel" ); + if( ele != null ) { ele.innerHTML = d.title; @@ -552,26 +552,51 @@ function ui_number_keyup( e ) } } +function _ui_set_number_range( ele, d ) +{ + if(d.max < d.min) + { + ui_error("Numeric range max: " + d.maxValue + " is not greater than " + d.minValue + ".") + } + else + { + ele.maxValue = d.max; + ele.minValue = d.min; + ele.stepValue = d.step; + ele.decpl = d.decpl; + } +} + +function ui_set_number_value( ele, value ) +{ + if( ele.minValue <= value && value <= ele.maxValue ) + { + ele.value = value; + if( ele.decpl == 0 ) + ui_send_int_value( ele, ele.value ) + else + ui_send_float_value( ele, ele.value ) + } + else + { + ui_error("Number value " + value + " out of range. min:" + ele.minValue + " max:" +ele.maxValue ) + } + +} + function ui_create_number( parent_ele, d ) { var ele = ui_create_ctl( parent_ele, "input", d.title, d, "uiNumber" ); if( ele != null ) { - ele.maxValue = d.max; - ele.minValue = d.min; - ele.stepValue = d.step; - ele.decpl = d.decpl; ele.addEventListener('keyup', ui_number_keyup ); + _ui_set_number_range(ele,d) + - if( d.hasOwnProperty('value') && d.min <= d.value && d.value <= d.max ) + if( d.hasOwnProperty('value') ) { - - ele.value = d.value; - if( d.decpl == 0 ) - ui_send_int_value( ele, ele.value ) - else - ui_send_float_value( ele, ele.value ) + ui_set_number_value(ele,d.value) } else { @@ -580,14 +605,24 @@ function ui_create_number( parent_ele, d ) } return ele; } - -function ui_set_progress( ele_id, value ) +function ui_set_number_range( ele, d ) { - var ele = dom_id_to_ele(ele_id); + _ui_set_number_range(ele,d) + if( d.hasOwnProperty('value') ) + ui_set_number_value(ele,d.value) +} +function ui_set_progress( ele, value ) +{ ele.value = Math.round( ele.max * (value - ele.minValue) / (ele.maxValue - ele.minValue)); } +function _ui_set_prog_range( ele, d ) +{ + ele.maxValue = d.max; + ele.minValue = d.min; +} + function ui_create_progress( parent_ele, d ) { var ele = ui_create_ctl( parent_ele, "progress", d.title, d, "uiProgress" ); @@ -595,13 +630,13 @@ function ui_create_progress( parent_ele, d ) if( ele != null ) { ele.max = 100; - ele.maxValue = d.max; - ele.minValue = d.min; + _ui_set_prog_range(ele,d) + if( !d.hasOwnProperty('value') ) ui_send_echo(ele); else { - ui_set_progress( ele.id, d.value ); + ui_set_progress( ele, d.value ); ui_send_int_value( ele, ele.value ); } @@ -609,6 +644,60 @@ function ui_create_progress( parent_ele, d ) return ele } +function ui_set_prog_range( ele, d ) +{ + _ui_set_prog_range(ele,d) + if( d.hasOwnProperty('value')) + ui_set_progress(ele,d.value) +} + +function _on_log_click( evt ) +{ + var pre_ele = dom_id_to_ele(evt.target.id) + + 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 )
+{
+    var child_id = ele.id + "_pre"
+
+    for(var i=0; i