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