cwIo.h/cpp, cwIoTest.h/cpp, html/ioTest.* : Many changes and additions to support first working Ui and audio subsystem.
This commit is contained in:
parent
f4e99e3771
commit
e763ed1607
169
cwIo.h
169
cwIo.h
@ -6,6 +6,7 @@
|
||||
#include "cwSerialPortDecls.h"
|
||||
#include "cwAudioDeviceDecls.h"
|
||||
#include "cwSocketDecls.h"
|
||||
#include "cwUiDecls.h"
|
||||
|
||||
namespace cw
|
||||
{
|
||||
@ -20,7 +21,8 @@ namespace cw
|
||||
kMidiTId,
|
||||
kAudioTId,
|
||||
kSockTid,
|
||||
kWebSockTId
|
||||
kWebSockTId,
|
||||
kUiTId
|
||||
};
|
||||
|
||||
typedef struct serial_msg_str
|
||||
@ -37,23 +39,37 @@ namespace cw
|
||||
|
||||
typedef audio::device::sample_t sample_t;
|
||||
|
||||
typedef struct audio_group_dev_str
|
||||
{
|
||||
const char* name; // Audio device name
|
||||
unsigned devIdx; // Audio device index
|
||||
unsigned chCnt; // Count of audio channels on this device
|
||||
unsigned cbCnt; // Count of device driver callbacks
|
||||
std::atomic_uint readyCnt;// Used internally do not read or write.
|
||||
struct audio_group_dev_str* link; //
|
||||
} audio_group_dev_t;
|
||||
|
||||
typedef struct audio_msg_str
|
||||
{
|
||||
unsigned iDevIdx;
|
||||
sample_t** iBufArray;
|
||||
unsigned iBufChCnt;
|
||||
time::spec_t* iTimeStampPtr;
|
||||
unsigned groupId; // Unique group id
|
||||
double srate; // Group sample rate.
|
||||
unsigned dspFrameCnt; // Count of samples in each buffer pointed to by iBufArray[] and oBufArray[]
|
||||
|
||||
unsigned oDevIdx;
|
||||
sample_t** oBufArray;
|
||||
unsigned oBufChCnt;
|
||||
time::spec_t* oTimeStampPtr;
|
||||
sample_t** iBufArray; // Array of ptrs to buffers of size bufSmpCnt
|
||||
unsigned iBufChCnt; // Count of elements in iBufArray[]
|
||||
time::spec_t* iTimeStampPtr; //
|
||||
audio_group_dev_t* iDevL; // Linked list of input devices which map directly to channels in iBufArray[]
|
||||
|
||||
sample_t** oBufArray; //
|
||||
unsigned oBufChCnt; //
|
||||
time::spec_t* oTimeStampPtr; //
|
||||
audio_group_dev_t* oDevL; // Linked list of output devices which map directly to channels in oBufArray[]
|
||||
|
||||
} audio_msg_t;
|
||||
|
||||
typedef struct socket_msg_str
|
||||
{
|
||||
sock::cbOpId_t cbId;
|
||||
sock::cbOpId_t cbId;
|
||||
unsigned userId;
|
||||
unsigned connId;
|
||||
const void* byteA;
|
||||
@ -61,37 +77,63 @@ namespace cw
|
||||
const struct sockaddr_in* srcAddr;
|
||||
} socket_msg_t;
|
||||
|
||||
typedef struct ui_msg_str
|
||||
{
|
||||
ui::opId_t opId;
|
||||
unsigned wsSessId;
|
||||
unsigned parentAppId;
|
||||
unsigned uuId;
|
||||
unsigned appId;
|
||||
const ui::value_t* value;
|
||||
} ui_msg_t;
|
||||
|
||||
typedef struct msg_str
|
||||
{
|
||||
unsigned tid;
|
||||
union
|
||||
{
|
||||
const serial_msg_t* serial;
|
||||
const midi_msg_t* midi;
|
||||
const audio_msg_t audio;
|
||||
const socket_msg_t sock;
|
||||
serial_msg_t* serial;
|
||||
midi_msg_t* midi;
|
||||
audio_msg_t* audio;
|
||||
socket_msg_t* sock;
|
||||
ui_msg_t ui;
|
||||
} u;
|
||||
} msg_t;
|
||||
|
||||
typedef void(*cbFunc_t)( void* arg, const msg_t* m );
|
||||
typedef rc_t (*cbFunc_t)( void* arg, const msg_t* m );
|
||||
|
||||
rc_t create(
|
||||
handle_t& h,
|
||||
const char* cfgStr, // configuration information as text
|
||||
cbFunc_t cbFunc,
|
||||
void* cbArg,
|
||||
const char* cfgLabel="io" );
|
||||
handle_t& h,
|
||||
const object_t* cfg, // configuration object
|
||||
cbFunc_t cbFunc,
|
||||
void* cbArg,
|
||||
const ui::appIdMap_t* mapA = nullptr,
|
||||
unsigned mapN = 0,
|
||||
const char* cfgLabel = "io" );
|
||||
|
||||
rc_t destroy( handle_t& h );
|
||||
|
||||
rc_t start( handle_t h );
|
||||
rc_t pause( handle_t h );
|
||||
rc_t stop( handle_t h );
|
||||
rc_t exec( handle_t h );
|
||||
bool isShuttingDown( handle_t h );
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------
|
||||
//
|
||||
// Serial
|
||||
//
|
||||
|
||||
unsigned serialDeviceCount( handle_t h );
|
||||
const char* serialDeviceName( handle_t h, unsigned devIdx );
|
||||
unsigned serialDeviceIndex( handle_t h, const char* name );
|
||||
rc_t serialDeviceSend( handle_t h, unsigned devIdx, const void* byteA, unsigned byteN );
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------
|
||||
//
|
||||
// MIDI
|
||||
//
|
||||
|
||||
unsigned midiDeviceCount( handle_t h );
|
||||
const char* midiDeviceName( handle_t h, unsigned devIdx );
|
||||
unsigned midiDeviceIndex( handle_t h, const char* devName );
|
||||
@ -101,6 +143,11 @@ namespace cw
|
||||
rc_t midiDeviceSend( handle_t h, unsigned devIdx, unsigned portIdx, uint8_t status, uint8_t d0, uint8_t d1 );
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------
|
||||
//
|
||||
// Audio
|
||||
//
|
||||
|
||||
unsigned audioDeviceCount( handle_t h );
|
||||
unsigned audioDeviceLabelToIndex( handle_t h, const char* label );
|
||||
const char* audioDeviceLabel( handle_t h, unsigned devIdx );
|
||||
@ -122,21 +169,28 @@ namespace cw
|
||||
sample_t audioDeviceChannelMeter( handle_t h, unsigned devIdx, unsigned chIdx, unsigned dirFl );
|
||||
rc_t audioDeviceChannelSetGain( handle_t h, unsigned devIdx, unsigned chIdx, unsigned dirFl, double gain );
|
||||
double audioDeviceChannelGain( handle_t h, unsigned devIdx, unsigned chIdx, unsigned dirFl );
|
||||
|
||||
rc_t audioDeviceStart( handle_t h, unsigned devIdx );
|
||||
rc_t audioDeviceStop( handle_t h, unsigned devIdx );
|
||||
bool audioDeviceIsStarted( handle_t h, unsigned devIdx );
|
||||
|
||||
unsigned audioGroupCount( handle_t h );
|
||||
const char* audioGroupLabel( handle_t h, unsigned groupIdx );
|
||||
unsigned audioGroupId( handle_t h, unsigned groupIdx );
|
||||
rc_t audioGroupSetId( handle_t h, unsigned groupIdx, unsigned groupId );
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------
|
||||
//
|
||||
// Socket
|
||||
//
|
||||
|
||||
rc_t socketSetup( handle_t h, unsigned timeOutMs, unsigned recvBufByteN, unsigned maxSocketN );
|
||||
|
||||
rc_t socketCreate(
|
||||
handle_t h,
|
||||
unsigned userId,
|
||||
short port,
|
||||
unsigned flags,
|
||||
const char* remoteAddr = nullptr,
|
||||
sock::portNumber_t remotePort = sock::kInvalidPortNumber,
|
||||
const char* localAddr = nullptr );
|
||||
handle_t h,
|
||||
unsigned userId,
|
||||
short port,
|
||||
unsigned flags,
|
||||
const char* remoteAddr = nullptr,
|
||||
sock::portNumber_t remotePort = sock::kInvalidPortNumber,
|
||||
const char* localAddr = nullptr );
|
||||
|
||||
rc_t socketDestroy( handle_t h, unsigned userId );
|
||||
|
||||
@ -150,9 +204,58 @@ namespace cw
|
||||
rc_t socketSend( handle_t h, unsigned userId, const void* data, unsigned dataByteCnt, const char* remoteAddr, sock::portNumber_t port );
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------
|
||||
//
|
||||
// UI
|
||||
//
|
||||
|
||||
|
||||
// Find id's associated with elements.
|
||||
unsigned uiFindElementAppId( handle_t h, unsigned parentUuId, const char* eleName );
|
||||
unsigned uiFindElementUuId( handle_t h, unsigned parentUuId, const char* eleName );
|
||||
unsigned uiFindElementUuId( handle_t h, unsigned parentUuId, unsigned appId );
|
||||
const char* uiFindElementName( handle_t h, unsigned uuId );
|
||||
unsigned uiFindElementAppId( handle_t h, unsigned uuId );
|
||||
|
||||
// Return the uuid of the first matching 'eleName'.
|
||||
unsigned uiFindElementUuId( handle_t h, const char* eleName );
|
||||
|
||||
rc_t uiCreateFromObject( handle_t h, const object_t* o, unsigned wsSessId, unsigned parentUuId=kInvalidId, const char* eleName=nullptr);
|
||||
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 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.
|
||||
// Create check: w/ value. The value will be sent to the engine as the new value of the associated varaible.
|
||||
rc_t uiCreateCheck( handle_t h, unsigned& uuIdRef, unsigned wsSessId, unsigned parentUuId, const char* eleName, unsigned appId, const char* clas, const char* title );
|
||||
rc_t uiCreateCheck( handle_t h, unsigned& uuIdRef, unsigned wsSessId, unsigned parentUuId, const char* eleName, unsigned appId, const char* clas, const char* title, bool value );
|
||||
|
||||
rc_t uiCreateSelect( handle_t h, unsigned& uuIdRef, unsigned wsSessId, unsigned parentUuId, const char* eleName, unsigned appId, const char* clas, const char* title );
|
||||
rc_t uiCreateOption( handle_t h, unsigned& uuIdRef, unsigned wsSessId, unsigned parentUuId, const char* eleName, unsigned appId, const char* clas, const char* title );
|
||||
|
||||
rc_t uiCreateStr( handle_t h, unsigned& uuIdRef, unsigned wsSessId, unsigned parentUuId, const char* eleName, unsigned appId, const char* clas, const char* title );
|
||||
rc_t uiCreateStr( handle_t h, unsigned& uuIdRef, unsigned wsSessId, unsigned parentUuId, const char* eleName, unsigned appId, const char* clas, const char* title, const char* value );
|
||||
|
||||
rc_t uiCreateNumbDisplay(handle_t h, unsigned& uuIdRef, unsigned wsSessId, unsigned parentUuId, const char* eleName, unsigned appId, const char* clas, const char* title, unsigned decPl );
|
||||
rc_t uiCreateNumbDisplay(handle_t h, unsigned& uuIdRef, unsigned wsSessId, unsigned parentUuId, const char* eleName, unsigned appId, const char* clas, const char* title, unsigned decPl, double value );
|
||||
|
||||
rc_t uiCreateNumb( 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 );
|
||||
rc_t uiCreateNumb( 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 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 );
|
||||
|
||||
// Register parent/child/name app id's
|
||||
rc_t uiRegisterAppIdMap( handle_t h, const ui::appIdMap_t* map, unsigned mapN );
|
||||
|
||||
// Send a value to the user interface
|
||||
template< typename T >
|
||||
rc_t uiValueToUI( handle_t h, unsigned wsSessId, unsigned uuId, const T& value );
|
||||
|
||||
|
||||
}
|
||||
|
250
cwIoTest.cpp
250
cwIoTest.cpp
@ -2,9 +2,11 @@
|
||||
#include "cwLog.h"
|
||||
#include "cwCommonImpl.h"
|
||||
#include "cwMem.h"
|
||||
#include "cwObject.h"
|
||||
#include "cwTime.h"
|
||||
#include "cwMidiDecls.h"
|
||||
#include "cwMidi.h"
|
||||
#include "cwUiDecls.h"
|
||||
#include "cwIo.h"
|
||||
#include "cwIoTest.h"
|
||||
|
||||
@ -12,65 +14,221 @@ namespace cw
|
||||
{
|
||||
namespace io
|
||||
{
|
||||
void testCb( void* arg, const msg_t* m )
|
||||
// Application Id's for UI elements
|
||||
enum
|
||||
{
|
||||
// Resource Based elements
|
||||
kPanelDivId,
|
||||
kQuitBtnId,
|
||||
kPanelBtn1Id,
|
||||
kPanelCheck1Id,
|
||||
kPanelBtn2Id,
|
||||
kPanelCheck2Id,
|
||||
kPanelFloaterId,
|
||||
kSelId,
|
||||
kOpt1Id,
|
||||
kOpt2Id,
|
||||
kOpt3Id
|
||||
};
|
||||
|
||||
// Application Id's for the resource based UI elements.
|
||||
ui::appIdMap_t mapA[] =
|
||||
{
|
||||
{ ui::kRootAppId, kPanelDivId, "panelDivId" },
|
||||
{ kPanelDivId, kQuitBtnId, "quitBtnId" },
|
||||
{ kPanelDivId, kPanelBtn1Id, "myBtn1Id" },
|
||||
{ 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]);
|
||||
|
||||
// Application object
|
||||
typedef struct app_str
|
||||
{
|
||||
handle_t ioH;
|
||||
} app_t;
|
||||
|
||||
rc_t _onUiInit(app_t* app, const ui_msg_t& m )
|
||||
{
|
||||
rc_t rc = kOkRC;
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc_t _onUiValue(app_t* app, const ui_msg_t& m )
|
||||
{
|
||||
rc_t rc = kOkRC;
|
||||
|
||||
switch( m.appId )
|
||||
{
|
||||
case kQuitBtnId:
|
||||
io::stop( app->ioH );
|
||||
break;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc_t _onUiEcho(app_t* app, const ui_msg_t& m )
|
||||
{
|
||||
rc_t rc = kOkRC;
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc_t uiCb( app_t* app, const ui_msg_t& m )
|
||||
{
|
||||
rc_t rc = kOkRC;
|
||||
|
||||
switch( m.opId )
|
||||
{
|
||||
case ui::kConnectOpId:
|
||||
cwLogInfo("IO Test Connect: wsSessId:%i.",m.wsSessId);
|
||||
break;
|
||||
|
||||
case ui::kDisconnectOpId:
|
||||
cwLogInfo("IO Test Disconnect: wsSessId:%i.",m.wsSessId);
|
||||
break;
|
||||
|
||||
case ui::kInitOpId:
|
||||
_onUiInit(app,m);
|
||||
break;
|
||||
|
||||
case ui::kValueOpId:
|
||||
_onUiValue( app, m );
|
||||
break;
|
||||
|
||||
case ui::kEchoOpId:
|
||||
_onUiEcho( app, m );
|
||||
break;
|
||||
|
||||
case ui::kIdleOpId:
|
||||
break;
|
||||
|
||||
case ui::kInvalidOpId:
|
||||
// fall through
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc_t audioCb( app_t* app, const audio_msg_t& m )
|
||||
{
|
||||
rc_t rc = kOkRC;
|
||||
|
||||
unsigned chN = std::min(m.iBufChCnt,m.oBufChCnt);
|
||||
unsigned byteCnt = m.dspFrameCnt * sizeof(sample_t);
|
||||
|
||||
// Copy the input to the output
|
||||
for(unsigned i=0; i<chN; ++i)
|
||||
if( m.oBufArray[i] != NULL )
|
||||
{
|
||||
// the input channel is not disabled
|
||||
if( m.iBufArray[i] != NULL )
|
||||
memcpy(m.oBufArray[i], m.iBufArray[i], byteCnt);
|
||||
else
|
||||
// the input channel is disabled but the output is not - so fill the output with zeros
|
||||
memset(m.oBufArray[i], 0, byteCnt);
|
||||
}
|
||||
|
||||
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
// The main application callback
|
||||
rc_t testCb( void* arg, const msg_t* m )
|
||||
{
|
||||
rc_t rc = kOkRC;
|
||||
app_t* app = reinterpret_cast<app_t*>(arg);
|
||||
|
||||
switch( m->tid )
|
||||
{
|
||||
case kSerialTId:
|
||||
break;
|
||||
|
||||
case kMidiTId:
|
||||
break;
|
||||
|
||||
case kAudioTId:
|
||||
if( m->u.audio != nullptr )
|
||||
rc = audioCb(app,*m->u.audio);
|
||||
break;
|
||||
|
||||
case kSockTid:
|
||||
break;
|
||||
|
||||
case kWebSockTId:
|
||||
break;
|
||||
|
||||
case kUiTId:
|
||||
rc = uiCb(app,m->u.ui);
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
void report( handle_t h )
|
||||
{
|
||||
for(unsigned i=0; i<serialDeviceCount(h); ++i)
|
||||
printf("serial: %s\n", serialDeviceName(h,i));
|
||||
|
||||
for(unsigned i=0; i<midiDeviceCount(h); ++i)
|
||||
for(unsigned j=0; j<2; ++j)
|
||||
{
|
||||
bool inputFl = j==0;
|
||||
unsigned m = midiDevicePortCount(h,i,inputFl);
|
||||
for(unsigned k=0; k<m; ++k)
|
||||
printf("midi: %s: %s : %s\n", inputFl ? "in ":"out", midiDeviceName(h,i), midiDevicePortName(h,i,inputFl,k));
|
||||
|
||||
}
|
||||
|
||||
for(unsigned i=0; i<audioDeviceCount(h); ++i)
|
||||
printf("audio: %s\n", audioDeviceLabel(h,i));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
cw::rc_t cw::io::test()
|
||||
cw::rc_t cw::io::test( const object_t* cfg )
|
||||
{
|
||||
|
||||
const char* cfgStr = R"(
|
||||
{
|
||||
io: {
|
||||
serial: [
|
||||
{
|
||||
name: "port1",
|
||||
device: "/dev/ttyACM0",
|
||||
baud: 38400,
|
||||
bits: 8,
|
||||
stop: 1,
|
||||
parity: no,
|
||||
pollPeriodMs: 50
|
||||
}
|
||||
]
|
||||
|
||||
midi: {
|
||||
parserBufByteN: 1024,
|
||||
}
|
||||
|
||||
audio: {
|
||||
meterMs: 50,
|
||||
|
||||
deviceL: [
|
||||
{
|
||||
enableFl: true,
|
||||
name: "Default",
|
||||
device: "HDA Intel PCH CS4208 Analog",
|
||||
srate: 48000,
|
||||
dspFrameCnt: 64,
|
||||
cycleCnt: 3
|
||||
}
|
||||
]
|
||||
}
|
||||
})";
|
||||
|
||||
|
||||
handle_t h;
|
||||
|
||||
rc_t rc;
|
||||
app_t app = {};
|
||||
|
||||
if((rc = create(h,cfgStr,testCb,nullptr)) != kOkRC )
|
||||
if((rc = create(app.ioH,cfg,testCb,&app,mapA,mapN)) != kOkRC )
|
||||
return rc;
|
||||
|
||||
char c;
|
||||
while((c = getchar()) != 'q')
|
||||
{
|
||||
//report(app.ioH);
|
||||
|
||||
if((rc = start(app.ioH)) != kOkRC )
|
||||
cwLogError(rc,"Test app start failed.");
|
||||
else
|
||||
{
|
||||
while( !isShuttingDown(app.ioH))
|
||||
{
|
||||
exec(app.ioH);
|
||||
sleepMs(50);
|
||||
}
|
||||
}
|
||||
|
||||
destroy(h);
|
||||
|
||||
destroy(app.ioH);
|
||||
printf("ioTest Done.\n");
|
||||
return rc;
|
||||
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ namespace cw
|
||||
{
|
||||
namespace io
|
||||
{
|
||||
rc_t test();
|
||||
rc_t test( const object_t* cfg);
|
||||
}
|
||||
}
|
||||
|
||||
|
75
html/ioTest/css/ui.css
Normal file
75
html/ioTest/css/ui.css
Normal file
@ -0,0 +1,75 @@
|
||||
|
||||
body {
|
||||
background-color: LightCyan;
|
||||
}
|
||||
|
||||
|
||||
.title_disconnected {
|
||||
color: red;
|
||||
}
|
||||
|
||||
.title_connected {
|
||||
color: green;
|
||||
}
|
||||
|
||||
input, label, button, select {
|
||||
font-family: sans-serif;
|
||||
font-size: 10px;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
|
||||
div {
|
||||
/*border: 1px solid black; */
|
||||
background-color: LightSteelBlue;
|
||||
}
|
||||
|
||||
div p {
|
||||
font-family: sans-serif;
|
||||
font-size: 12px;
|
||||
margin-top: 2px;
|
||||
margin-bottom: 2px;
|
||||
background-color: LightSteelBlue;
|
||||
}
|
||||
|
||||
label {
|
||||
/*border: 1px solid red;*/
|
||||
width: 50px;
|
||||
padding-left: 10px;
|
||||
margin-top: 3px;
|
||||
}
|
||||
|
||||
|
||||
.uiCtlDiv {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
background-color: LightBlue;
|
||||
}
|
||||
|
||||
.uiCtlDiv input {
|
||||
background-color: PowderBlue;
|
||||
}
|
||||
|
||||
.uiNumberDiv input {
|
||||
width: 50px;
|
||||
}
|
||||
|
||||
.uiPanel {
|
||||
background-color: LightBlue;
|
||||
}
|
||||
|
||||
.uiRow {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
background-color: LightBlue;
|
||||
}
|
||||
|
||||
.uiCol {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
background-color: LightBlue;
|
||||
}
|
||||
|
25
html/ioTest/index.html
Normal file
25
html/ioTest/index.html
Normal file
@ -0,0 +1,25 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>UI Test App</title>
|
||||
<script type="text/javascript" src="js/ui.js"></script>
|
||||
<link href="css/ui.css" rel="stylesheet">
|
||||
|
||||
<script text="text/javascript">
|
||||
window.addEventListener("load",main, false )
|
||||
</script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="appTitleDiv" class="uiRow">
|
||||
<p id="appTitleId">UI Test:</p>
|
||||
<p id="connectTitleId">Disconnected</p>
|
||||
</div>
|
||||
|
||||
<div id="0" class="uiAppDiv">
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
818
html/ioTest/js/ui.js
Normal file
818
html/ioTest/js/ui.js
Normal file
@ -0,0 +1,818 @@
|
||||
var _ws = null;
|
||||
var _rootId = "0";
|
||||
var _nextEleId = 0;
|
||||
|
||||
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<children.length; i++)
|
||||
{
|
||||
if( children[i].id == r.ele_id )
|
||||
{
|
||||
select_ele.selectedIndex = i
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function uiOnSelectClick( ele )
|
||||
{
|
||||
cmdstr = "mode ui ele_type select op choose parent_id "+ele.parentElement.id+" option_id " + ele.id
|
||||
websocket.send(cmdstr);
|
||||
|
||||
}
|
||||
|
||||
function uiNumberOnKeyUp( e )
|
||||
{
|
||||
if( e.keyCode == 13 )
|
||||
{
|
||||
//console.log(e)
|
||||
cmdstr = "mode ui ele_type number op change parent_id "+e.srcElement.parentElement.id+" ele_id " + e.srcElement.id + " value " + e.srcElement.value
|
||||
websocket.send(cmdstr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function uiNumberCreate( r )
|
||||
{
|
||||
var parent_ele;
|
||||
|
||||
if((parent_ele = uiGetParent(r)) != null )
|
||||
{
|
||||
ele = document.createElement("input")
|
||||
ele.id = r.ele_id
|
||||
ele.setAttribute('type','number')
|
||||
ele.addEventListener('keyup',uiNumberOnKeyUp)
|
||||
parent_ele.appendChild(ele)
|
||||
}
|
||||
}
|
||||
|
||||
function uiNumberSet( r )
|
||||
{
|
||||
var ele;
|
||||
|
||||
//console.log("ele_id:" + r.ele_id + " parent_id:" + r.parent_id + " value:" + r.value)
|
||||
|
||||
if((ele = document.getElementById(r.parent_id)) != null)
|
||||
{
|
||||
switch( r.ele_id )
|
||||
{
|
||||
case "0": ele.min = r.value; break;
|
||||
case "1": ele.max = r.value; break;
|
||||
case "2": ele.step = r.value; break;
|
||||
case "3": ele.value = r.value; break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
function dom_child_by_id( parentEle, child_id )
|
||||
{
|
||||
var childrenL = parentEle.children
|
||||
for(var i=0; i<childrenL.length; i++)
|
||||
{
|
||||
if( childrenL[i].id == child_id )
|
||||
{
|
||||
return childrenL[i];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function dom_set_option_by_text( ele_id, text )
|
||||
{
|
||||
var ele = dom_id_to_ele(ele_id);
|
||||
|
||||
for (var i = 0; i < ele.options.length; i++)
|
||||
{
|
||||
if (ele.options[i].text === text)
|
||||
{
|
||||
ele.selectedIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
function dom_set_number( ele_id, val )
|
||||
{
|
||||
dom_id_to_ele(ele_id).value = val
|
||||
}
|
||||
|
||||
|
||||
//==============================================================================
|
||||
|
||||
function dom_id_to_ele( id )
|
||||
{ return document.getElementById(id); }
|
||||
|
||||
function dom_set_checkbox( ele_id, fl )
|
||||
{ dom_id_to_ele(ele_id).checked = fl }
|
||||
|
||||
function dom_get_checkbox( ele_id )
|
||||
{ return dom_id_to_ele(ele_id).checked }
|
||||
|
||||
function dom_create_ele( ele_type )
|
||||
{
|
||||
ele = document.createElement(ele_type);
|
||||
return ele
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
|
||||
function ui_error( msg )
|
||||
{
|
||||
console.log("Error: " + msg )
|
||||
}
|
||||
|
||||
function ui_send_value( ele, typeId, value )
|
||||
{
|
||||
ws_send("value " + ele.id + " " + typeId + " : " + value)
|
||||
}
|
||||
|
||||
function ui_send_bool_value( ele, value ) { ui_send_value(ele,'b',value); }
|
||||
function ui_send_int_value( ele, value ) { ui_send_value(ele,'i',value); }
|
||||
function ui_send_float_value( ele, value ) { ui_send_value(ele,'f',value); }
|
||||
function ui_send_string_value( ele, value ) { ui_send_value(ele,'s',value); }
|
||||
|
||||
function ui_send_echo( ele )
|
||||
{
|
||||
ws_send("echo " + ele.id )
|
||||
}
|
||||
|
||||
function ui_print_children( eleId )
|
||||
{
|
||||
var childrenL = dom_id_to_ele(eleId).children
|
||||
|
||||
for(var i=0; i<childrenL.length; i++)
|
||||
{
|
||||
console.log( childrenL[i] )
|
||||
}
|
||||
}
|
||||
|
||||
function ui_get_parent( parentId )
|
||||
{
|
||||
if( parentId==null || parentId.trim().length == 0 )
|
||||
parentId = _rootId
|
||||
|
||||
parent_ele = dom_id_to_ele(parentId);
|
||||
|
||||
if( parent_ele == null )
|
||||
{
|
||||
ui_error("Parent element id: " + parentId + " not found.")
|
||||
}
|
||||
|
||||
return parent_ele;
|
||||
}
|
||||
|
||||
|
||||
function ui_create_ele( parent_ele, ele_type, d, dfltClassName )
|
||||
{
|
||||
// create the ctl object
|
||||
var ele = dom_create_ele(ele_type);
|
||||
|
||||
if( ele == null )
|
||||
ui_error(ele_type +" element create failed.");
|
||||
else
|
||||
{
|
||||
ele.id = d.uuId;
|
||||
|
||||
if(d.hasOwnProperty('className') )
|
||||
ele.className = d.className;
|
||||
else
|
||||
ele.className = dfltClassName;
|
||||
|
||||
if(d.hasOwnProperty('appId'))
|
||||
ele.appId = d.appId;
|
||||
else
|
||||
ele.appId = null;
|
||||
|
||||
//console.log("Created: " + ele_type + " parent:" + d.parentUuId + " id:" + ele.id + " appId:" + ele.appId)
|
||||
|
||||
parent_ele.appendChild(ele);
|
||||
|
||||
|
||||
}
|
||||
return ele
|
||||
}
|
||||
|
||||
function ui_create_ctl( parent_ele, ele_type, label, d, dfltEleClassName )
|
||||
{
|
||||
// create an enclosing div
|
||||
var div_ele = dom_create_ele("div");
|
||||
|
||||
div_ele.className = "uiCtlDiv " + dfltEleClassName + "Div"
|
||||
|
||||
parent_ele.appendChild( div_ele );
|
||||
|
||||
var label_ele = div_ele
|
||||
|
||||
// if label is not null then create an enclosing 'label' element
|
||||
if( label != null )
|
||||
{
|
||||
label = label.trim();
|
||||
|
||||
if( label.length > 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_title( parent_ele, d )
|
||||
{
|
||||
var ele = ui_create_ele( parent_ele, "label", d, "uiTitle" );
|
||||
|
||||
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<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 )
|
||||
{
|
||||
var ele = ui_create_ctl( parent_ele, "select", d.title, d, "uiSelect" );
|
||||
ele.onchange = function() { ui_on_select(this) }
|
||||
|
||||
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 )
|
||||
{
|
||||
var opt_ele = ui_create_ele( parent_ele, "option", d, "uiOption" );
|
||||
|
||||
if( opt_ele != null )
|
||||
{
|
||||
if(d.hasOwnProperty('className'))
|
||||
opt_ele.className = d.className;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
function ui_create_string( parent_ele, d )
|
||||
{
|
||||
var ele = ui_create_ctl( parent_ele, "input", d.title, d, "uiString" );
|
||||
|
||||
if( ele != null )
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
function ui_number_keyup( e )
|
||||
{
|
||||
if( e.keyCode===13 )
|
||||
{
|
||||
var ele = dom_id_to_ele(e.target.id)
|
||||
|
||||
if( ele != null )
|
||||
{
|
||||
//console.log("min:"+ele.minValue+" max:"+ele.maxValue)
|
||||
|
||||
var val = 0;
|
||||
if( ele.decpl == 0 )
|
||||
val = Number.parseInt(ele.value)
|
||||
else
|
||||
val = Number.parseFloat(ele.value)
|
||||
|
||||
if( !(ele.minValue<=val && val<=ele.maxValue))
|
||||
ele.style.borderColor = "red"
|
||||
else
|
||||
{
|
||||
ele.style.borderColor = ""
|
||||
|
||||
if( ele.decpl == 0 )
|
||||
ui_send_int_value(ele,ele.value);
|
||||
else
|
||||
ui_send_float_value(ele,ele.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 );
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
function ui_set_progress( ele_id, value )
|
||||
{
|
||||
var ele = dom_id_to_ele(ele_id);
|
||||
|
||||
ele.value = Math.round( ele.max * (value - ele.minValue) / (ele.maxValue - ele.minValue));
|
||||
}
|
||||
|
||||
function ui_create_progress( parent_ele, d )
|
||||
{
|
||||
var ele = ui_create_ctl( parent_ele, "progress", d.title, d, "uiProgress" );
|
||||
|
||||
if( ele != null )
|
||||
{
|
||||
ele.max = 100;
|
||||
ele.maxValue = d.max;
|
||||
ele.minValue = d.min;
|
||||
if( !d.hasOwnProperty('value') )
|
||||
ui_send_echo(ele);
|
||||
else
|
||||
{
|
||||
ui_set_progress( ele.id, d.value );
|
||||
ui_send_int_value( ele, ele.value );
|
||||
}
|
||||
|
||||
}
|
||||
return ele
|
||||
}
|
||||
|
||||
function ui_set_value( d )
|
||||
{
|
||||
//console.log(d)
|
||||
var ele = dom_id_to_ele(d.uuId.toString())
|
||||
|
||||
if( ele == null )
|
||||
console.log("ele 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 "title":
|
||||
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 "string":
|
||||
ele.value = d.value
|
||||
break;
|
||||
|
||||
case "number":
|
||||
ele.value = d.value
|
||||
break;
|
||||
|
||||
case "progress":
|
||||
ele.value = d.value
|
||||
break;
|
||||
|
||||
default:
|
||||
ui_error("Unknown UI element type: " + d.type )
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 "title":
|
||||
ele = ui_create_title( 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 "string":
|
||||
ele = ui_create_string( parent_ele, d );
|
||||
break;
|
||||
|
||||
case "number":
|
||||
ele = ui_create_number( parent_ele, d );
|
||||
break;
|
||||
|
||||
case "progress":
|
||||
ele = ui_create_progress( parent_ele, d );
|
||||
break;
|
||||
|
||||
default:
|
||||
ui_error("Unknown UI element type: " + d.type )
|
||||
}
|
||||
|
||||
if( ele != null )
|
||||
{
|
||||
ele.uiEleType = d.type;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
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 'value':
|
||||
ui_set_value( 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;
|
||||
|
||||
|
||||
}
|
||||
|
66
html/ioTest/ui.cfg
Normal file
66
html/ioTest/ui.cfg
Normal file
@ -0,0 +1,66 @@
|
||||
{
|
||||
|
||||
parent: "uiDivId"
|
||||
|
||||
panel: {
|
||||
|
||||
name: "panelDivId",
|
||||
title: "My resource based panel",
|
||||
|
||||
row: {
|
||||
button:{ name: quitBtnId, title:"Quit" },
|
||||
},
|
||||
|
||||
row: {
|
||||
button:{ name: myBtn1Id, title:"Push Me" },
|
||||
check:{ name: myCheck1Id, title:"Check Me", 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 2" },
|
||||
check:{ name: myCheck2Id, title:"Check 2" },
|
||||
number:{ name: myFloater, title:"Floater", min:0.0, max:12.34, step:0.1, decpl:4 },
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
panel: {
|
||||
row: {
|
||||
|
||||
col: {
|
||||
title:"Bank 0",
|
||||
},
|
||||
|
||||
col: {
|
||||
title: "x",
|
||||
title:{ title:"mute" },
|
||||
title:{ title:"touch" },
|
||||
title:{ title:"fader" },
|
||||
},
|
||||
|
||||
col: {
|
||||
title:"0",
|
||||
check:{ name: mute0Chk },
|
||||
check:{ name: touch0Chk },
|
||||
number:{ name: fader0Numb, min:0, max:1023, step:1, decpl:0 },
|
||||
},
|
||||
|
||||
col: {
|
||||
title:"1",
|
||||
check:{ name: mute1Chk },
|
||||
check:{ name: touch1Chk },
|
||||
number:{ name: fader1Numb, min:0, max:1023, step:1, decpl:0 },
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user