cwUiTest.cpp : Added more extensive example of resource based UI creation. Created 'value' UI element attribute.

This commit is contained in:
kevin.larke 2020-04-28 08:42:16 -04:00
parent a324184c7a
commit 99af70eb37
4 changed files with 219 additions and 50 deletions

View File

@ -18,12 +18,18 @@ namespace cw
const char* uiCfgFn; const char* uiCfgFn;
srv::handle_t wsUiSrvH; srv::handle_t wsUiSrvH;
std::atomic<bool> quitFl;
bool appCheckFl; bool appCheckFl;
unsigned appSelectIndex; unsigned appSelOptAppId;
int appInteger; int appInteger;
float appFloat; float appFloat;
int appProgress; int appProgress;
char* appString; char* appString;
bool appCheck1Fl;
bool appCheck2Fl;
float appNumb;
unsigned appSelId;
} ui_test_t; } ui_test_t;
@ -43,8 +49,15 @@ namespace cw
kProgressId, kProgressId,
kPanelDivId, kPanelDivId,
kPanelBtnId, kPanelBtn1Id,
kPanelCheckId kPanelCheck1Id,
kPanelBtn2Id,
kPanelCheck2Id,
kPanelFloaterId,
kSelId,
kOpt1Id,
kOpt2Id,
kOpt3Id
}; };
rc_t _uiTestCreateUi( ui_test_t* p, unsigned wsSessId ) rc_t _uiTestCreateUi( ui_test_t* p, unsigned wsSessId )
@ -63,7 +76,7 @@ namespace cw
if((rc = createDiv( uiH, divUuId, wsSessId, kInvalidId, "myDivId", kDivId, "divClass", "My Panel" )) != kOkRC ) if((rc = createDiv( uiH, divUuId, wsSessId, kInvalidId, "myDivId", kDivId, "divClass", "My Panel" )) != kOkRC )
goto errLabel; goto errLabel;
if((rc = createButton( uiH, uuid, wsSessId, divUuId, "myBtnId", kBtnId, "btnClass", "Push Me" )) != kOkRC ) if((rc = createButton( uiH, uuid, wsSessId, divUuId, "myBtnId", kBtnId, "btnClass", "Quit" )) != kOkRC )
goto errLabel; goto errLabel;
if((rc = createCheck( uiH, uuid, wsSessId, divUuId, "myCheckId", kCheckId, "checkClass", "Check Me", true )) != kOkRC ) if((rc = createCheck( uiH, uuid, wsSessId, divUuId, "myCheckId", kCheckId, "checkClass", "Check Me", true )) != kOkRC )
@ -100,6 +113,23 @@ namespace cw
return rc; return rc;
} }
void _print_state( ui_test_t* p )
{
printf("check:%i sel:%i int:%i flt:%f prog:%i str:%s chk1:%i chk2:%i numb:%f sel:%i\n",
p->appCheckFl,
p->appSelOptAppId,
p->appInteger,
p->appFloat,
p->appProgress,
p->appString,
p->appCheck1Fl,
p->appCheck2Fl,
p->appNumb,
p->appSelId);
}
rc_t _handleUiValueMsg( ui_test_t* p, unsigned wsSessId, unsigned parentAppId, unsigned uuId, unsigned appId, const value_t* v ) rc_t _handleUiValueMsg( ui_test_t* p, unsigned wsSessId, unsigned parentAppId, unsigned uuId, unsigned appId, const value_t* v )
{ {
rc_t rc = kOkRC; rc_t rc = kOkRC;
@ -107,7 +137,7 @@ namespace cw
switch( appId ) switch( appId )
{ {
case kBtnId: case kBtnId:
printf("Click!\n"); p->quitFl.store(true);
break; break;
case kCheckId: case kCheckId:
@ -116,8 +146,8 @@ namespace cw
break; break;
case kSelectId: case kSelectId:
printf("Selected: optionId:%i\n", v->u.i); printf("Selected: option appId:%i\n", v->u.i);
p->appSelectIndex = v->u.i; p->appSelOptAppId = v->u.i;
break; break;
case kStringId: case kStringId:
@ -136,6 +166,36 @@ namespace cw
printf("Float: %f\n",v->u.f); printf("Float: %f\n",v->u.f);
p->appFloat = v->u.f; p->appFloat = v->u.f;
case kPanelBtn1Id:
printf("Button 1\n");
_print_state(p);
break;
case kPanelCheck1Id:
printf("check 1: %i\n",v->u.b);
p->appCheck1Fl = v->u.b;
break;
case kPanelBtn2Id:
printf("Button 2\n");
_print_state(p);
break;
case kPanelCheck2Id:
printf("check 1: %i\n",v->u.b);
p->appCheck1Fl = v->u.b;
break;
case kPanelFloaterId:
printf("numb: %f\n",v->u.f);
p->appNumb = v->u.f;
break;
case kSelId:
printf("sel: %i\n",v->u.i);
p->appSelId = v->u.i;
break;
} }
return rc; return rc;
@ -152,7 +212,7 @@ namespace cw
break; break;
case kSelectId: case kSelectId:
sendValueInt( uiHandle( p->wsUiSrvH ), wsSessId, uuId, p->appSelectIndex ); sendValueInt( uiHandle( p->wsUiSrvH ), wsSessId, uuId, p->appSelOptAppId );
break; break;
case kStringId: case kStringId:
@ -170,6 +230,22 @@ namespace cw
case kProgressId: case kProgressId:
sendValueInt( uiHandle( p->wsUiSrvH ), wsSessId, uuId, p->appProgress ); sendValueInt( uiHandle( p->wsUiSrvH ), wsSessId, uuId, p->appProgress );
break; break;
case kPanelCheck1Id:
sendValueBool( uiHandle( p->wsUiSrvH ), wsSessId, uuId, p->appCheck1Fl);
break;
case kPanelCheck2Id:
sendValueBool( uiHandle( p->wsUiSrvH ), wsSessId, uuId, p->appCheck2Fl);
break;
case kPanelFloaterId:
sendValueFloat( uiHandle( p->wsUiSrvH ), wsSessId, uuId, p->appNumb );
break;
case kSelId:
sendValueInt( uiHandle( p->wsUiSrvH ), wsSessId, uuId, p->appSelId );
break;
} }
return rc; return rc;
} }
@ -224,25 +300,37 @@ cw::rc_t cw::ui::test( )
unsigned xmtBufByteN = 2048; unsigned xmtBufByteN = 2048;
unsigned fmtBufByteN = 4096; unsigned fmtBufByteN = 4096;
unsigned websockTimeOutMs = 50; unsigned websockTimeOutMs = 50;
const unsigned sbufN = 31;
char sbuf[ sbufN+1 ];
ui_test_t* app = mem::allocZ<ui_test_t>(); ui_test_t* app = mem::allocZ<ui_test_t>();
app->quitFl.store(false);
appIdMap_t mapA[] = appIdMap_t mapA[] =
{ {
{ kRootAppId, kPanelDivId, "panelDivId" }, { kRootAppId, kPanelDivId, "panelDivId" },
{ kPanelDivId, kPanelBtnId, "myBtn1Id" }, { kPanelDivId, kPanelBtn1Id, "myBtn1Id" },
{ kPanelDivId, kPanelCheckId, "myCheck1Id" }, { kPanelDivId, kPanelCheck1Id, "myCheck1Id" },
{ kPanelDivId, kPanelBtn2Id, "myBtn2Id" },
{ kPanelDivId, kPanelCheck2Id, "myCheck2Id" },
{ kPanelDivId, kPanelFloaterId, "myFloater" },
{ kPanelDivId, kSelId, "mySel" },
{ kSelId, kOpt1Id, "myOpt1" },
{ kSelId, kOpt2Id, "myOpt2" },
{ kSelId, kOpt3Id, "myOpt3" },
}; };
unsigned mapN = sizeof(mapA)/sizeof(mapA[0]); unsigned mapN = sizeof(mapA)/sizeof(mapA[0]);
app->appCheckFl = true; app->appCheckFl = true;
app->appSelectIndex = 1; app->appSelOptAppId = kOption1Id;
app->appInteger = 5; app->appInteger = 5;
app->appFloat = 2.56; app->appFloat = 2.56;
app->appProgress = 7; app->appProgress = 7;
app->appString = mem::duplStr("fooz"); app->appString = mem::duplStr("fooz");
app->appCheck1Fl = false;
app->appCheck2Fl = true;
app->appNumb = 1.23;
app->appSelId = kOpt3Id;
app->uiCfgFn = "/home/kevin/src/cwtest/src/libcw/html/uiTest/ui.cfg"; app->uiCfgFn = "/home/kevin/src/cwtest/src/libcw/html/uiTest/ui.cfg";
@ -260,16 +348,9 @@ cw::rc_t cw::ui::test( )
printf("'quit' to exit\n"); printf("'quit' to exit\n");
// readline loop // readline loop
while( true ) while( !app->quitFl.load() )
{ {
printf("? "); sleepMs(50);
if( std::fgets(sbuf,sbufN,stdin) == sbuf )
{
printf("Sending:%s",sbuf);
if( strcmp(sbuf,"quit\n") == 0)
break;
}
} }
errLabel: errLabel:

View File

@ -65,7 +65,7 @@ label {
background-color: LightBlue; background-color: LightBlue;
} }
.uiRow { .uiCol {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;

View File

@ -150,7 +150,7 @@ function uiNumberSet( r )
{ {
var ele; var ele;
console.log("ele_id:" + r.ele_id + " parent_id:" + r.parent_id + " value:" + r.value) //console.log("ele_id:" + r.ele_id + " parent_id:" + r.parent_id + " value:" + r.value)
if((ele = document.getElementById(r.parent_id)) != null) if((ele = document.getElementById(r.parent_id)) != null)
{ {
@ -357,7 +357,7 @@ function ui_create_row_div( parent_ele, d )
var div_ele = ui_create_div( parent_ele, d ); var div_ele = ui_create_div( parent_ele, d );
if( !d.hasOwnProperty('className') ) if( !d.hasOwnProperty('className') )
div_ele.className = "uiPanel" div_ele.className = "uiRow"
return div_ele return div_ele
} }
@ -368,7 +368,7 @@ function ui_create_col_div( parent_ele, d )
var div_ele = ui_create_div( parent_ele, d ); var div_ele = ui_create_div( parent_ele, d );
if( !d.hasOwnProperty('className') ) if( !d.hasOwnProperty('className') )
div_ele.className = "uiPanel" div_ele.className = "uiCol"
return div_ele return div_ele
} }
@ -400,23 +400,60 @@ function ui_create_check( parent_ele, d )
{ {
ele.type = "checkbox"; ele.type = "checkbox";
dom_set_checkbox(ele.id, d.value );
ele.onclick = function() { ui_send_bool_value(this,dom_get_checkbox(this.id)); } 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; 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 ) function ui_on_select( ele )
{ {
ui_send_int_value(ele,ele.options[ ele.selectedIndex ].appId); 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<sel_ele.options.length; ++i)
if( sel_ele.options[i].appId == option_appId )
{
sel_ele.selectedIndex = i;
return;
}
ui_error("Select option index not found.");
}
function ui_create_select( parent_ele, d ) function ui_create_select( parent_ele, d )
{ {
var sel_ele = ui_create_ctl( parent_ele, "select", d.title, d, "uiSelect" ); var ele = ui_create_ctl( parent_ele, "select", d.title, d, "uiSelect" );
sel_ele.onchange = function() { ui_on_select(this) } ele.onchange = function() { ui_on_select(this) }
return sel_ele;
if( !d.hasOwnProperty('value') )
{
ui_send_echo(ele)
}
else
{
// Note that d.value is the appId of the default selected option
ele.defaultOptionAppId = d.value;
ui_send_int_value(ele,ele.defaultOptionAppId)
}
return ele;
} }
function ui_create_option( parent_ele, d ) function ui_create_option( parent_ele, d )
@ -425,8 +462,22 @@ function ui_create_option( parent_ele, d )
if( opt_ele != null ) if( opt_ele != null )
{ {
if(d.hasOwnProperty('className'))
opt_ele.className = d.className; opt_ele.className = d.className;
opt_ele.innerHTML = d.title; opt_ele.innerHTML = d.title;
// d.value, if it exists, is a boolean indicating that this is the default option
var fl0 = d.hasOwnProperty('value') && d.value != 0;
// The parent 'select' element may also have been given the app id of the default option
// (and this option may be it)
var fl1 = parent_ele.hasOwnProperty('defaultOptionAppId') && parent_ele.defaultOptionAppId == ele.appId;
if(fl0 || fl1 )
{
parent_ele.selectedIndex = parent_ele.options.length-1;
}
} }
return opt_ele; return opt_ele;
@ -438,8 +489,16 @@ function ui_create_string( parent_ele, d )
if( ele != null ) if( ele != null )
{ {
ele.value = d.value;
ele.addEventListener('keyup', function(e) { if(e.keyCode===13){ ui_send_string_value(this, this.value); }} ); ele.addEventListener('keyup', function(e) { if(e.keyCode===13){ ui_send_string_value(this, this.value); }} );
if( !d.hasOwnProperty('value') )
ui_send_echo(ele);
else
{
ele.value = d.value;
ui_send_string_value(ele,ele.value)
}
} }
return ele; return ele;
@ -453,7 +512,7 @@ function ui_number_keyup( e )
if( ele != null ) if( ele != null )
{ {
console.log("min:"+ele.minValue+" max:"+ele.maxValue) //console.log("min:"+ele.minValue+" max:"+ele.maxValue)
var val = 0; var val = 0;
if( ele.decpl == 0 ) if( ele.decpl == 0 )
@ -468,17 +527,13 @@ function ui_number_keyup( e )
ele.style.borderColor = "" ele.style.borderColor = ""
if( ele.decpl == 0 ) if( ele.decpl == 0 )
{
ui_send_int_value(ele,ele.value); ui_send_int_value(ele,ele.value);
}
else else
{
ui_send_float_value(ele,ele.value); ui_send_float_value(ele,ele.value);
} }
} }
} }
} }
}
function ui_create_number( parent_ele, d ) function ui_create_number( parent_ele, d )
{ {
@ -486,12 +541,25 @@ function ui_create_number( parent_ele, d )
if( ele != null ) if( ele != null )
{ {
ele.value = d.value;
ele.maxValue = d.max; ele.maxValue = d.max;
ele.minValue = d.min; ele.minValue = d.min;
ele.stepValue = d.step; ele.stepValue = d.step;
ele.decpl = d.decpl; ele.decpl = d.decpl;
ele.addEventListener('keyup', ui_number_keyup ); ele.addEventListener('keyup', ui_number_keyup );
if( d.hasOwnProperty('value') && d.min <= d.value && d.value <= d.max )
{
ele.value = d.value;
if( d.decpl == 0 )
ui_send_int_value( ele, ele.value )
else
ui_send_float_value( ele, ele.value )
}
else
{
ui_send_echo(ele);
}
} }
return ele; return ele;
} }
@ -512,14 +580,21 @@ function ui_create_progress( parent_ele, d )
ele.max = 100; ele.max = 100;
ele.maxValue = d.max; ele.maxValue = d.max;
ele.minValue = d.min; ele.minValue = d.min;
if( !d.hasOwnProperty('value') )
ui_send_echo(ele);
else
{
ui_set_progress( ele.id, d.value ); ui_set_progress( ele.id, d.value );
ui_send_int_value( ele, ele.value );
}
} }
return ele return ele
} }
function ui_set_value( d ) function ui_set_value( d )
{ {
console.log(d) //console.log(d)
var ele = dom_id_to_ele(d.uuId.toString()) var ele = dom_id_to_ele(d.uuId.toString())
if( ele == null ) if( ele == null )
@ -530,7 +605,7 @@ function ui_set_value( d )
if( ele != null && ele.hasOwnProperty("uiEleType")) if( ele != null && ele.hasOwnProperty("uiEleType"))
{ {
console.log("found: "+ele.uiEleType) //console.log("found: "+ele.uiEleType)
switch( ele.uiEleType ) switch( ele.uiEleType )
{ {
@ -545,12 +620,11 @@ function ui_set_value( d )
break; break;
case "check": case "check":
console.log(d)
dom_set_checkbox(ele.id,d.value) dom_set_checkbox(ele.id,d.value)
break; break;
case "select": case "select":
ele.selectedIndex = d.value ui_select_set_from_option_app_id(ele,d.value)
break; break;
case "option": case "option":
@ -645,7 +719,6 @@ function ui_create( d )
if( ele != null ) if( ele != null )
{ {
ele.uiEleType = d.type; ele.uiEleType = d.type;
ui_send_echo(ele);
} }
} }

View File

@ -8,9 +8,24 @@
name: "panelDivId", name: "panelDivId",
title: "My resource based panel", title: "My resource based panel",
row: { row: {
button:{ name: myBtn1Id, title:"Push Me" }, button:{ name: myBtn1Id, title:"Push Me 1" },
check:{ name: myCheck1Id, title:"Check Me" }, check:{ name: myCheck1Id, title:"Check Me 1", value:true },
select:{ name: mySel, title:"Select",
children:
{
option:{ name: myOpt1, title:"Sel 1" },
option:{ name: myOpt2, title:"Sel 2" },
option:{ name: myOpt3, title:"Sel 3" }
},
},
},
row: {
button:{ name: myBtn2Id, title:"Push Me 2" },
check:{ name: myCheck2Id, title:"Check Me 2" },
number:{ name: myFloater, title:"Floater", min:0.0, max:12.34, step:0.1, decpl:4 },
} }
} }