diff --git a/cwIoAudioPanel.cpp b/cwIoAudioPanel.cpp index 609f91b..984fb02 100644 --- a/cwIoAudioPanel.cpp +++ b/cwIoAudioPanel.cpp @@ -350,6 +350,9 @@ cw::rc_t cw::io::audio_panel::exec( handle_t h, const msg_t& m ) rc = _uiCb(p,m.u.ui); break; + case kExecTId: + break; + default: assert(0); diff --git a/cwIoSocketChat.cpp b/cwIoSocketChat.cpp index 8efe48a..17e7fb4 100644 --- a/cwIoSocketChat.cpp +++ b/cwIoSocketChat.cpp @@ -70,8 +70,9 @@ namespace cw { const int sn = 63; char s[sn+1]; snprintf(s,sn,"Chat: %i", io::socketPort(p->ioH, p->sockIdx )); + - uiCreateDiv( p->ioH, divUuId, parentUuId, nullptr, p->baseAppId + kUiDivAppId, chanId, "uiCol", s ); + uiCreateDiv( p->ioH, divUuId, parentUuId, nullptr, p->baseAppId + kUiDivAppId, chanId, "uiPanel", s ); uiCreateStr( p->ioH, uuid, divUuId, nullptr, p->baseAppId + kUiSendTextAppId, chanId, "uiText", "Send" ); uiCreateStr( p->ioH, uuid, divUuId, nullptr, p->baseAppId + kUiRemoteAddrAppId, chanId, "uiText", "Addr", "127.0.0.1" ); uiCreateNumb( p->ioH, uuid, divUuId, nullptr, p->baseAppId + kUiRemotePortAppId, chanId, "uiNumb", "Port", 0, 0xffff, 1, 0, 0 ); @@ -305,6 +306,9 @@ cw::rc_t cw::io::sock_chat::exec( handle_t h, const msg_t& m ) rc = _uiCb(p,m.u.ui); break; + case kExecTId: + break; + default: assert(0); diff --git a/cwIoTest.cpp b/cwIoTest.cpp index 801e4b5..e2f9b11 100644 --- a/cwIoTest.cpp +++ b/cwIoTest.cpp @@ -210,6 +210,9 @@ namespace cw rc = uiCb(app,m->u.ui); break; + case kExecTId: + break; + default: assert(0); diff --git a/html/ioTest/css/ui.css b/html/ioTest/css/ui.css index 509e421..abd66f4 100644 --- a/html/ioTest/css/ui.css +++ b/html/ioTest/css/ui.css @@ -40,6 +40,7 @@ label { } + .uiCtlDiv { display: flex; flex-direction: row; @@ -73,3 +74,105 @@ 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%; + background-color: LightSteelBlue; + +} + + +/* log scroller */ +.uiLog { + display:flex; + flex-direction: column; + + height: 150px; + overflow-x: hidden; /* 'hidden' to remove x scroll bar */ + overflow-y: auto; + width: 100%; + + background-color: PowderBlue; + +} + +/* The log text */ +.uiLog pre { +} + + +/* outer list div - contains the list label and the list scroller */ +.uiListDiv { + display: flex; + flex-direction: column; + + align-items: flex-start; /* left justify */ + align-content: flex-stretch; /* fill horizontal space */ + +} + +.uiListDiv label { + width: 100%; + background-color: LightSteelBlue; + +} + +.uiList { + display:flex; + flex-direction: column; + + height: 100px; + width: 100%; + overflow-x: hidden; /* 'hidden' to remove scroll bar */ + overflow-y: auto; + + background-color: PowderBlue; +} + + +/* outer list div - contains the list label and the list scroller */ +.uiHListDiv { + display: flex; + flex-direction: row; + + align-items: flex-start; /* left justify */ + align-content: flex-stretch; /* fill horizontal space */ + +} + +.uiHListDiv label { + width: 100%; + background-color: LightSteelBlue; + +} + +.uiHList { + display:flex; + flex-direction: row; + + height: 100%; + overflow-x: auto; + overflow-y: hidden; /* 'hidden' to remove scroll bar */ + + background-color: PowderBlue; +} + + +.uiStringDisp { + width: 100%; +} + +.uiSelected { + border: 1px solid blue; +} + diff --git a/html/ioTest/index.html b/html/ioTest/index.html index 1821edd..22191e5 100644 --- a/html/ioTest/index.html +++ b/html/ioTest/index.html @@ -2,7 +2,7 @@ - UI Test App + IO Test App diff --git a/html/ioTest/js/ui.js b/html/ioTest/js/ui.js index da3f795..c23793d 100644 --- a/html/ioTest/js/ui.js +++ b/html/ioTest/js/ui.js @@ -1,172 +1,25 @@ -var _ws = null; -var _rootId = "0"; -var _nextEleId = 0; -var _focusId = null; -var _focusVal = null; +var _ws = null; +var _rootId = "0"; +var _nextEleId = 0; +var _focusId = null; +var _focusVal = null; +var _rootDivEle = null; +var _rootEle = null; function set_app_title( suffix, className ) { var ele = document.getElementById('connectTitleId'); - ele.innerHTML = suffix - ele.className = className -} - - -function uiOnError( msg, r) -{ - console.log("Error:" + msg); -} - -function uiGetParent( r ) -{ - parent_ele = document.getElementById(r.parent_id); - - if( parent_ele == null ) + if(ele != null) { - uiOnError("Parent not found. parent_id:" + r.parent_id,r); + ele.innerHTML = suffix + ele.className = className } - - 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; - - parent_ele.appendChild(ele) + else + { + console.log("Ele. not found. Set title failed.") } } -function uiRemoveChildren( r ) -{ - ele = document.getElementById(r.ele_id) - - while (ele.firstChild) - { - ele.removeChild(ele.firstChild); - } -} - -function uiDivCreate( r ) -{ uiCreateEle(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) - } - -} - -function uiSelectCreate( 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'); - - 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 children = select_ele.childNodes - for(var i=0; i 0 ) { @@ -355,10 +268,13 @@ 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 +282,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,19 +295,21 @@ 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 } -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; @@ -422,7 +342,9 @@ function ui_create_check( parent_ele, d ) ele.onclick = function() { ui_send_bool_value(this,dom_get_checkbox(this.id)); } if( !d.hasOwnProperty('value') ) + { ui_send_echo(ele) + } else { dom_set_checkbox(ele.id, d.value ); @@ -460,7 +382,8 @@ function ui_create_select( parent_ele, d ) { var ele = ui_create_ctl( parent_ele, "select", d.title, d, "uiSelect" ); ele.onchange = function() { ui_on_select(this) } - + ele.onclick = function() { ui_on_select(this) } + if( !d.hasOwnProperty('value') ) { ui_send_echo(ele) @@ -504,8 +427,39 @@ function ui_create_option( parent_ele, d ) function _ui_on_focus( ele ) { - _focusId=ele.id; - _focusVal=ele.value; + _focusId = ele.id; + _focusVal = ele.value; +} + + +function ui_set_str_display( ele_id, value ) +{ + + var ele = dom_id_to_ele(ele_id); + + if( typeof(value)=="string") + { + ele.innerHTML = value; + } +} + +function ui_create_str_display( parent_ele, d ) +{ + var ele = ui_create_ctl( parent_ele, "label", d.title, d, "uiStringDisp" ); + + if( ele != null ) + { + if( d.hasOwnProperty('value') ) + { + ui_set_str_display(ele.id, d.value); + } + else + { + ui_send_echo(ele); + } + } + + return ele; } function _ui_on_string_blur( ele ) @@ -540,6 +494,7 @@ function ui_create_string( parent_ele, d ) return ele; } + function _ui_send_number( ele ) { var val = 0; @@ -549,7 +504,10 @@ function _ui_send_number( ele ) val = Number.parseFloat(ele.value) if( !(ele.minValue<=val && val<=ele.maxValue)) + { ele.style.borderColor = "red" + ui_send_corrupt_state(ele) + } else { ele.style.borderColor = "" @@ -558,20 +516,7 @@ function _ui_send_number( ele ) ui_send_int_value(ele,ele.value); else ui_send_float_value(ele,ele.value); - } - -} - -function _ui_on_number_blur( ele ) -{ - if( ele.id == _focusId ) - { - if( ele.value != _focusVal ) - { - _ui_send_number(ele) - } - - } + } } function ui_number_keyup( e ) @@ -588,28 +533,92 @@ function ui_number_keyup( e ) } } +function _ui_on_number_blur( ele ) +{ + if( ele.id == _focusId ) + { + if( ele.value != _focusVal ) + _ui_send_number(ele) + } +} + +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 ) +{ + var min_ok_fl = (!ele.hasOwnProperty('minValue')) || (value >= ele.minValue) + var max_ok_fl = (!ele.hasOwnProperty('maxValue')) || (value <= ele.maxValue) + + if( min_ok_fl && max_ok_fl ) + { + 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_set_title( ele, d ) +{ + if( ele.tagName.toLowerCase() == "button" ) + ele.innerHTML = d.value; + else + { + // most controls will have a sibling element of type 'label' + var label_eles = ele.parentNode.getElementsByTagName("label"); + + if( label_eles != null && label_eles.length > 0 ) + { + label_eles[0].innerHTML = d.value + } + else + { + ui_error("set_title() target element not found."); + } + } +} + +function ui_set_number_range( ele, d ) +{ + _ui_set_number_range(ele,d) + if( d.hasOwnProperty('value') ) + ui_set_number_value(ele,d.value) +} + 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 ); ele.addEventListener('focus', function(e) { _ui_on_focus(this); } ); ele.addEventListener('blur', function(e) { _ui_on_number_blur(this); } ); + _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 { @@ -619,13 +628,62 @@ function ui_create_number( parent_ele, d ) return ele; } -function ui_set_progress( ele_id, value ) +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") + { + var val = value.toString(); + + if( ele.decpl == 0 ) + ele.innerHTML = parseInt(val,10); + else + ele.innerHTML = parseFloat(val); + } +} + +function ui_create_number_display( parent_ele, d ) +{ + var ele = ui_create_ctl( parent_ele, "label", d.title, d, "uiNumbDisp" ); + + if( ele != null ) + { + ele.decpl = d.decpl; + + if( d.hasOwnProperty('value') ) + { + ui_set_number_display(ele.id, d.value); + } + else + { + ui_send_echo(ele); + } + } + + return ele; + +} + +function ui_create_text_display( parent_ele, d ) +{ + return ui_create_ctl( parent_ele, "label", d.title, d, "uiTextDisp" ); +} + + +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" ); @@ -633,13 +691,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 ); } @@ -647,16 +705,83 @@ 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_set_log_text( ele, value ) +{ + var child_id = ele.id + "_pre" + + for(var i=0; i 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, class_label ) +{ + var list_ele = ui_create_ctl( parent_ele, "div", d.title, d, class_label ) + + return list_ele +} + function ui_set_value( d ) { - //console.log(d) - var ele = dom_id_to_ele(d.uuId.toString()) + var eleId = d.uuId.toString() + var ele = dom_id_to_ele(eleId) if( ele == null ) - console.log("ele not found: uuid: "+d.uuId); + console.log("ele '"+eleId+"' not found"); else + { if( !ele.hasOwnProperty("uiEleType") ) + { console.log("No type"); + } + } if( ele != null && ele.hasOwnProperty("uiEleType")) { @@ -667,7 +792,7 @@ function ui_set_value( d ) case "div": break; - case "title": + case "label": ele.innerHTML = d.value break; @@ -685,6 +810,10 @@ function ui_set_value( d ) case "option": break; + case "str_disp": + ui_set_str_display(ele.id,d.value); + break + case "string": ele.value = d.value break; @@ -693,16 +822,171 @@ function ui_set_value( d ) ele.value = d.value break; - case "progress": - ele.value = d.value + case "numb_disp": + ui_set_number_display(ele.id,d.value); break; + case "progress": + ui_set_progress( ele, d.value ) + //ele.value = d.value + break; + + case "log": + ui_set_log_text( ele, d.value ) + 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 + + //console.log(ele.id + " " + classLabelArg + " " + enableFl ) + + let isEnabledFl = false; + + if( ele.hasOwnProperty("className") ) + isEnabledFl = ele.className.includes(classLabel) + else + ele.className = "" + + // if the class is not already enabled/disabled + if( enableFl != isEnabledFl ) + { + if( enableFl ) + ele.className += classLabel; + else + ele.className = ele.className.replace(classLabel, ""); + } + + //console.log(ele.id + " " + ele.className + " " + enableFl ) +} + +function ui_set_select( ele, enableFl ) +{ + _ui_modify_class(ele,"uiSelected",enableFl) + ui_send_select( ele, enableFl ) +} + + +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_order_key(ele, orderKey) +{ + let parent = ele.parentElement // get the parent of the element to reorder + ele = parent.removeChild( ele ) // remove the element to reorder from the parent list + + ele.order = orderKey + + let i = 0; + for(i=0; i= orderKey) + { + parent.insertBefore( ele, parent.children[i] ) + break + } + } + + // no element was found greater than this element .... + if( i == parent.children.length ) + parent.appendChild(ele) // ... insert the element at the end of the child lsit + +} + +function ui_set( d ) +{ + //console.log(d) + var ele = dom_id_to_ele(d.uuId.toString()) + + if( ele == null ) + console.log("ele not found"); + + if( ele != null) + { + switch( d.type ) + { + case "title": + ui_set_title(ele,d); + break; + + case "number_range": + ui_set_number_range(ele, d) + break; + + case "progress_range": + ui_set_prog_range(ele, d) + break; + + case "select": + ui_set_select(ele,d.value) + break + + case "clickable": + ui_set_clickable(ele,d.value) + break + + case "visible": + ui_set_visible(ele,d.value) + break + + case "enable": + ui_set_enable(ele,d.value) + break + + case "order": + ui_set_order_key(ele,d.value) + break + + } + } +} + +function ui_cache( d ) +{ + for(i=0; i