var _ws = null; var _rootId = "0"; var _nextEleId = 0; var _focusId = null; var _focusVal = 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 ) { uiOnError("Parent not found. parent_id:" + r.parent_id,r); } 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) } } 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) { label_ele = dom_create_ele("label"); label_ele.innerHTML = label; div_ele.appendChild(label_ele) } } return ui_create_ele( div_ele, ele_type, d, dfltEleClassName ); } function ui_create_div( parent_ele, d ) { var div_ele = ui_create_ele( parent_ele, "div", d, "uiDiv" ); if( div_ele != null ) { if( d.title != null ) { var title = d.title.trim() if( title.length > 0 ) { var p_ele = dom_create_ele("p") p_ele.innerHTML = title div_ele.appendChild( p_ele ) } } } return div_ele; } 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" return div_ele } 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" return div_ele } 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" return div_ele } function ui_create_label( parent_ele, d ) { var ele = ui_create_ele( parent_ele, "label", d, "uiLabel" ); if( ele != null ) { ele.innerHTML = d.title; } return ele; } function ui_create_button( parent_ele, d ) { var ele = ui_create_ctl( parent_ele, "button", null, d, "uiButton" ); 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, "uiCheck" ) if( ele != null ) { ele.type = "checkbox"; 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 ); ui_send_bool_value(ele,dom_get_checkbox(ele.id)) } } return ele; } // // Note: The value of a 'select' widget is always set by the 'appId' // of the selected 'option'. Likewise the 'appId' of the selected // option is returned as the value of the select widget. // function ui_on_select( ele ) { ui_send_int_value(ele,ele.options[ ele.selectedIndex ].appId); } function ui_select_set_from_option_app_id( sel_ele, option_appId ) { var i; for(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 ) { d.className = "uiList" console.log(d) var list_ele = ui_create_ctl( parent_ele, "div", d.title, d, "uiList" ) return list_ele } function ui_set_value( d ) { //console.log(d) var eleId = d.uuId.toString() var ele = dom_id_to_ele(eleId) if( ele == null ) console.log("ele '"+eleId+"' not found"); else { if( !ele.hasOwnProperty("uiEleType") ) { console.log("No type"); } } if( ele != null && ele.hasOwnProperty("uiEleType")) { //console.log("found: "+ele.uiEleType) switch( ele.uiEleType ) { case "div": break; case "label": ele.innerHTML = d.value break; case "button": break; case "check": dom_set_checkbox(ele.id,d.value) break; case "select": ui_select_set_from_option_app_id(ele,d.value) break; case "option": break; case "str_disp": ui_set_str_display(ele.id,d.value); break case "string": ele.value = d.value break; case "number": ele.value = d.value break; 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 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(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 "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_create( 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 "panel": ele = ui_create_panel_div( parent_ele, d ) break; case "row": ele = ui_create_row_div( parent_ele, d ) break; case "col": ele = ui_create_col_div( parent_ele, d ) break; case "label": ele = ui_create_label( 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 "str_disp": ele = ui_create_str_display( 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 "numb_disp": ele = ui_create_number_display( parent_ele, d ); break; case "text_disp": ele = ui_create_text_display( parent_ele, d ); break; case "progress": ele = ui_create_progress( parent_ele, d ); break; 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 ) } if( ele != null ) { ele.uiEleType = d.type; } } } function ui_destroy( d ) { if( typeof(d.uuId) == "number" ) d.uuId = d.uuId.toString() var ele = dom_id_to_ele(d.uuId) if( ele != null ) ele.parentElement.removeChild( ele ) } function ws_send( s ) { //console.log(s) _ws.send(s+"\0") } function ws_on_msg( jsonMsg ) { //console.log(jsonMsg) d = JSON.parse(jsonMsg.data); switch( d.op ) { case 'create': ui_create( d ) break; case 'destroy': ui_destroy( d ) break case 'value': ui_set_value( d ) break; case 'set': ui_set( d ) break; default: ui_error("Unknown UI operation. " + d.op ) } } function ws_on_open() { set_app_title( "Connected", "title_connected" ); _ws.send("init") } function ws_on_close() { set_app_title( "Disconnected", "title_disconnected" ); } function ws_form_url(urlSuffix) { var pcol; var u = document.URL; pcol = "ws://"; if (u.substring(0, 4) === "http") u = u.substr(7); u = u.split("/"); return pcol + u[0] + "/" + urlSuffix; } function main() { 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; }