Initial commit

This commit is contained in:
kpl 2012-11-03 13:05:46 -07:00
parent 7e8b9b5570
commit 4d4988c764
15 changed files with 3034 additions and 815 deletions

View File

@ -56,7 +56,11 @@ include_HEADERS += $(cmHDR)
lib_LTLIBRARIES += src/libcm/libcm.la
src_cmflapp_cmflapp_SOURCES = src/cmflapp/main.cpp src/cmflapp/app.h src/cmflapp/app.cpp
src_cmflapp_cmflapp_SOURCES += src/cmflapp/Fl_Splitter.h src/cmflapp/Fl_Splitter.cpp
src_cmflapp_cmflapp_LDADD = $(CMLIBS) $(MYLIBS)
bin_PROGRAMS += src/cmflapp/cmflapp
src_kc_kc_SOURCES = src/kc/kcMain.cpp
src_kc_kc_SOURCES += src/kc/kcApp.h src/kc/kcApp.cpp
src_kc_kc_SOURCES += src/kc/Fl_Splitter.h src/kc/Fl_Splitter.cpp
src_kc_kc_SOURCES += src/kc/Fl_File_Btn.h src/kc/Fl_Vert_Progress.h
src_kc_kc_SOURCES += src/kc/Fl_File_Btn.cpp src/kc/Fl_Vert_Progress.cpp
src_kc_kc_LDADD = $(CMLIBS) $(MYLIBS)
bin_PROGRAMS += src/kc/kc

View File

@ -3,10 +3,10 @@
# this configure.ac or any of the Makefile.am files.
#
AC_INIT([cmflapp],[1.0],[cmflapp@larke.org])
AC_INIT([kc],[1.0],[kc@larke.org])
AC_CONFIG_AUX_DIR([build-aux]) # put aux files in build-aux
AM_INIT_AUTOMAKE([1.9 -Wall foreign subdir-objects]) # subdir-objects needed for non-recursive make
AC_CONFIG_SRCDIR([src/cmflapp/main.cpp])
AC_CONFIG_SRCDIR([src/kc/kcMain.cpp])
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_MACRO_DIR([m4])

View File

@ -1,555 +0,0 @@
#include <FL/Fl.H>
#include <FL/Fl_Widget.H>
#include <FL/Fl_Double_Window.H>
#include <FL/Fl_Text_Buffer.H>
#include <FL/Fl_Text_Display.H>
#include <FL/Fl_Tabs.H>
#include <FL/Fl_Menu_Item.H>
#include <FL/Fl_Menu_Bar.H>
#include <FL/Fl_Button.H>
#include <FL/Fl_Check_Button.H>
#include <FL/Fl_Menu_Button.H>
#include <FL/Fl_Value_Input.H>
#include <FL/Fl_Value_Slider.H>
#include <FL/Fl_Input.H>
#include <FL/Fl_Box.H>
#include <FL/Fl_File_Chooser.H>
#include <FL/fl_draw.H>
#include "Fl_Splitter.h"
#include "cmPrefix.h"
#include "cmGlobal.h"
#include "cmRpt.h"
#include "cmErr.h"
#include "cmCtx.h"
#include "cmMem.h"
#include "cmMallocDebug.h"
#include "cmFileSys.h"
#include "cmThread.h"
#include "appErr.h"
#include "app.h"
class drawWnd : public Fl_Widget
{
public:
drawWnd(app* ap, int x, int y, int w, int h, const char* label = NULL );
virtual ~drawWnd();
virtual int handle(int event);
virtual void resize(int x, int y, int w, int h );
protected:
virtual void draw();
private:
app* _app;
};
drawWnd::drawWnd(app* ap, int x, int y, int w, int h, const char* label )
: Fl_Widget(x,y,w,h,label),
_app(ap)
{}
drawWnd::~drawWnd()
{}
int drawWnd::handle(int event)
{
switch(event)
{
case FL_PUSH:
{
const char* label;
switch( Fl::event_button() )
{
case FL_LEFT_MOUSE: label = "left"; break;
case FL_RIGHT_MOUSE: label = "right"; break;
case FL_MIDDLE_MOUSE: label = "middle"; break;
default:
label = "none";
}
_app->print("%i %i %s\n",Fl::event_x(),Fl::event_y(),label);
}
break;
default:
return Fl_Widget::handle(event);
}
return 1;
}
void drawWnd::resize(int x, int y, int w, int h )
{
// must call base to make size change
Fl_Widget::resize(x,y,w,h);
}
void drawWnd::draw()
{
int offs = 10;
//fl_draw_box(FL_DOWN_BOX,x()+10,y()+10,w()-20,h()-20,FL_RED);
//fl_frame("XXXX",x()+offs,y()+offs,w()-2*offs,h()-2*offs);
fl_line_style(FL_SOLID,1,NULL);
fl_color(FL_RED);
fl_line(x()+offs,y()+offs,x()+w()-offs,y()+h()-offs);
int x = w()/2;
int y = h()/2;
fl_color(FL_BLACK);
fl_draw(90,"string",x,y);
// XXXXXXX
// X00000X
// X00000X
// X00X00X
// X00000X
// X00000X
// XXXXXXX
fl_rect(x-3,y-3,7,7);
fl_point(x,y);
}
//----------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------
app::app(cmCtx_t* ctx, cmTsMp1cH_t printqH, int w, int h, const char* label, int argc, char* argv[])
: Fl_Double_Window(w,h,label), _timerPeriodSecs(0),
_ctx(ctx), _splt(NULL),_buf(NULL),_con(NULL),_tabs(NULL),_menu(NULL),
_printqH(printqH),_printFl(0)
{
// install a callback to cleanup when the app window closes
// (the btn and menu callbacks also rely on a pointer to 'this' being found in app.user_data()
// see _getApp())
callback(_s_callback,this);
// the main window is divided between the menu bar on top
// and a horizontal splitter on the bottom
begin();
createMenu(w,kMenuH);
_splt = new Fl_HSplitter(0, kMenuH, w, h-kStatusH, h-kStatusH-100);
end();
// Create a text display object for console output and
// add it to the lower splitter area
_buf = new Fl_Text_Buffer();
_con = new Fl_Text_Display(_splt->container2->x(),_splt->container2->y(),_splt->container2->w(),_splt->container2->h());
_con->buffer(_buf);
_splt->container2->add(_con);
// create tabbed windows
const char* titles[] = { "Title 1", "Title 2" };
_create_tabs(2,titles);
// make the splitter the resizable group element (thereby making the menu non-resizable).
// see:http://fltk.org/articles.php?L415+I0+T+M1000+P1
resizable(_splt);
show(argc, argv);
// The application is now visible.
// direct all output to the console window
cmRptSetup(&_ctx->rpt,_s_print,_s_print, this);
cmTsMp1cSetCbFunc(_printqH, _s_print_queue_cb, this );
// install a timer
_timerPeriodSecs = 0.1;
Fl::add_timeout(_timerPeriodSecs,app::_s_timer_cb,this);
// install an idle callback
//Fl::add_idle(_s_idle_cb,this);
print("Started!\n");
}
app::~app()
{}
void app::createControls(Fl_Group* grp)
{
const int vBord = 3;
const int ctl_width = 100;
int xx = grp->x() + 5;
int yy = grp->y() + vBord;
Fl_Check_Button* cbt = new Fl_Check_Button(xx,yy,ctl_width,kCtlH,"Check");
cbt->callback( _s_btn_cb, kBtn1MId );
yy += cbt->h() + vBord;
Fl_Button* btn = new Fl_Button(xx,yy,ctl_width,kCtlH,"Button");
btn->callback( _s_btn_cb, kBtn2MId );
yy += btn->h() + vBord;
// menu buttons callback through menuCallback() not btnCallback()
Fl_Menu_Button* mbt = new Fl_Menu_Button(xx,yy,ctl_width,kCtlH,"Menu");
mbt->add("Item 1",0,_s_menu_btn_cb, (void*)kMenuBtn1MId, 0);
mbt->add("Item 2",0,_s_menu_btn_cb, (void*)kMenuBtn2MId, 0);
yy += mbt->h() + vBord;
Fl_Value_Input* vip = new Fl_Value_Input(xx,yy,ctl_width/2,kCtlH,"Value In");
vip->callback(_s_value_cb, kValue1MId );
vip->align(FL_ALIGN_RIGHT); // place label to the right of the input ctl
// Only make the callback when the enter key is struck or the ctl loses focus and the value has changed.
// Removing this line causes the callback whenever the input changes.
vip->when(FL_WHEN_ENTER_KEY | FL_WHEN_RELEASE );
vip->bounds(-10.0,10.0);
vip->step(0.1);
yy += vip->h() + vBord;
Fl_Value_Slider* sdp = new Fl_Value_Slider(xx,yy,ctl_width,kCtlH,"Slider");
sdp->callback(_s_value_cb, kValue2MId );
sdp->align(FL_ALIGN_RIGHT);
sdp->type(FL_HOR_NICE_SLIDER);
sdp->bounds(-10.0,10.0);
sdp->step(0.1);
yy += sdp->h() + vBord;
Fl_Input* inp = new Fl_Input(xx,yy,ctl_width/2,kCtlH,"Text");
inp->callback(_s_input_cb,kInput1MId);
inp->align(FL_ALIGN_RIGHT);
yy += inp->h() + vBord;
}
void app::initializeTab(int tabIndex, int x, int y, int w, int h, const char* label)
{
switch(tabIndex)
{
case 0:
{
Fl_Group* grp = new Fl_Group(x,y,w,h,label);
grp->begin();
createControls(grp);
grp->end();
}
break;
case 1:
{
Fl_Group* grp = new Fl_Group(x,y,w,h,label);
grp->begin();
_draw = new drawWnd(this,x,y,w,h,NULL);
grp->end();
}
break;
}
}
void app::createMenu(int w, int h)
{
Fl_Menu_Item items[] =
{
{ "&File", 0, 0, 0, FL_SUBMENU },
{ "&New File", FL_COMMAND + 'n', (Fl_Callback*)_s_menu_cb, (void*)kFileNewMId },
{ "&Open File", FL_COMMAND + 'o', (Fl_Callback*)_s_menu_cb, (void*)kFileOpenMId },
{ 0 },
{ "&Edit", 0, 0, 0, FL_SUBMENU },
{ "&Copy", FL_COMMAND + 'c', (Fl_Callback*)_s_menu_cb, (void*)kEditCopyMId },
{ "&Paste", FL_COMMAND + 'v', (Fl_Callback*)_s_menu_cb, (void*)kEditPasteMId },
{ 0 },
{ 0 }
};
_menu = new Fl_Menu_Bar(0,0,w,h);
_menu->copy(items);
}
void app::menuCallback(const Fl_Menu_Item* mip, long int id)
{
switch(id)
{
case kFileOpenMId:
{
// file chooser demo
const char* pathStr = cmFsUserDir(); // make the default dir the user's home dir
const char patStr[] = "Text Files (*.txt)\tAudio Files (*.{wav,aif,aiff})"; // All Files (*.*) is append to this automatically
const char titleStr[] = "Select files";
Fl_File_Chooser fc = Fl_File_Chooser(pathStr,patStr,Fl_File_Chooser::MULTI,titleStr);
fc.preview(0); // default the previous option to 'off'.
fc.show(); // show the chooser
// make the chooser modal
while( fc.shown() )
Fl::wait();
// print the selected files
int i;
for(i=1; i<=fc.count(); ++i)
print("%i %s\n",i,cmStringNullGuard(fc.value(i)));
}
break;
}
print("%i %s\n",id,mip->label());
}
void app::btnCallback(const Fl_Button* bp, int id )
{
print("%i %s %i\n",id,bp->label(),bp->value());
}
void app::valueCallback(const Fl_Valuator* vp, int id )
{
print("%i %s %f\n",id,vp->label(),vp->value());
}
void app::inputCallback(const Fl_Input* ip, int id )
{
print("%i %s %s\n",id,ip->label(),ip->value());
}
void app::appCallback(Fl_Widget* wp)
{
switch( Fl::event() )
{
case FL_CLOSE:
{
/*
int cc = _closeCnt;
// attempt to shut down the pgm
_closeCnt += finalizePgm() == false;
// the first time the pgm fails to shut down
// do not allow the pgm to close the main window
// this will give a chance for the error messages
// to be diplayed in the console - all successive
// times the return value from finalizePgm() is
// ignored and the program is terminated.
if( _closeCnt == 1 && cc==0)
{
// send a strong hint that a problem occurred on shutdown
// and prevent the app from receiving events that might cause it to
// crash
deactivate();
return;
}
*/
// When all windows are windows are closed then the app.
// will close - so hiding the application window
// causes the program to close.
//
// Note that simply returning from this callback will
// prevent the application from closing. Because the existence
// of the callback alone is enough to disable default
// event handling.
hide();
}
break;
}
}
bool app::idleCallback()
{ return true; }
bool app::timerCallback()
{
_checkPrintQueue();
return true;
}
void app::error( const char* fmt, ... )
{
va_list vl;
va_start(vl,fmt);
int bufCharCnt = 511;
char buf[bufCharCnt+1];
int n = vsnprintf(buf,bufCharCnt,fmt,vl);
if( n > 0 )
print("%s Error: %s\n",label(),buf);
va_end(vl);
}
void app::vprint(const char* fmt, va_list vl )
{
int bufCharCnt = 511;
char buf[bufCharCnt+1];
int n = vsnprintf(buf,bufCharCnt,fmt,vl);
if( n > 0 )
{
// if the print queue exists (it might not during startup or shutdown) ...
if( cmTsMp1cIsValid(_printqH) )
{
cmThRC_t thRC;
// ... enqueue the text to print
if((thRC = cmTsMp1cEnqueueMsg(_printqH,buf,n+1)) != kOkThRC && _printFl==0 )
{
// Print queue error msg's directly to stdout rather than throught
// the error mechanism - this prevents generating a stack overflow
// when the print queue runs out of space and attempts to print a
// 'queue out of memory' error msg.
// The queue itself does will not print errors because it does
// not have a valid cmRpt_t pointer. See cmMp1cCreate() above.
++_printFl;
cmErrMsg(&_ctx->err,kQueueFailAppRC,"Print enqueue failed.");
--_printFl;
}
}
else
_print(buf); // ... otherwise just send the text directly to the output console
}
}
void app::print( const char* fmt, ... )
{
va_list vl;
va_start(vl,fmt);
vprint(fmt,vl);
va_end(vl);
}
void app::_s_menu_cb(Fl_Widget* wp, void* data)
{
const Fl_Menu_Item* mip;
app* ap;
if((ap=_getApp(wp)) != NULL )
if((mip = ap->_menu->mvalue()) != NULL )
ap->menuCallback(mip,(long int)mip->user_data());
}
void app::_s_menu_btn_cb(Fl_Widget* wp, void* data)
{
const Fl_Menu_Button* bp;
const Fl_Menu_Item* mip;
app* ap;
if((ap=_getApp(wp)) != NULL )
if((bp = static_cast<Fl_Menu_Button*>(wp)) != NULL )
if((mip = bp->mvalue()) != NULL)
ap->menuCallback(mip,(long int)data);
}
void app::_s_btn_cb(Fl_Widget* wp, long data )
{
app* ap;
if((ap = _getApp(wp)) != NULL )
if( wp != NULL )
ap->btnCallback( static_cast<const Fl_Button*>(wp),data);
}
void app::_s_value_cb( Fl_Widget* wp, long data)
{
app* ap;
Fl_Valuator* vp;
if((ap = _getApp(wp)) != NULL )
if((vp = static_cast<Fl_Valuator*>(wp)) != NULL)
ap->valueCallback(vp,data);
}
void app::_s_input_cb( Fl_Widget* wp, long data)
{
app* ap;
Fl_Input* inp;
if((ap = _getApp(wp)) != NULL)
if((inp = static_cast<Fl_Input*>(wp)) != NULL )
ap->inputCallback(inp,data);
}
void app::_s_callback(Fl_Widget* wp, void* data)
{ ((app*)data)->appCallback(wp); }
void app::_s_idle_cb(void *data)
{
app* thisPtr = (app*)data;
if( thisPtr->idleCallback() == false )
Fl::remove_idle(_s_idle_cb,data);
}
void app::_s_timer_cb(void* userPtr)
{
app* thisPtr = (app*)userPtr;
if( thisPtr->timerCallback() )
Fl::repeat_timeout(thisPtr->_timerPeriodSecs,_s_timer_cb,userPtr);
}
void app::_s_print( void* userPtr, const char* text )
{ ((app*)userPtr)->print(text); }
void app::_create_tabs(int titleCnt, const char* titleArray[])
{
// Create a tab view and added it to the upper splitter area
_tabs = new Fl_Tabs(_splt->container1->x(),_splt->container1->y(),_splt->container1->w(),_splt->container1->h());
_splt->container1->add(_tabs);
int tx,ty,th,tw,i;
_tabs->client_area(tx,ty,tw,th);
for(i=0; i<titleCnt; ++i)
{
_tabs->begin();
initializeTab(i,tx,ty,tw,th,titleArray[i]);
_tabs->end();
}
// Create an empty tab group and make it resizable
// to prevent the other tab groups from being resizable.
_tabs->begin();
_tabs->resizable(new Fl_Group(tx,ty+30,1,1));
_tabs->end();
}
app* app::_getApp( Fl_Widget* w )
{
// walk up the widget tree until the top widget is found
Fl_Group* gp = w->parent();
while( gp->parent() != NULL )
gp=gp->parent();
// the user data for the top widget is a pointer app - as set in: callback(_s_callback,this);
return (app*)gp->user_data();
}
cmRC_t app::_s_print_queue_cb(void* userCbPtr, unsigned msgByteCnt, const void* msgDataPtr )
{
app* ap = (app*)userCbPtr;
ap->_print((const char*)msgDataPtr);
return cmOkRC;
}
void app::_checkPrintQueue()
{
while( cmTsMp1cMsgWaiting(_printqH) )
if( cmTsMp1cDequeueMsg(_printqH, NULL, 0) != kOkThRC )
error("Print dequeue failed.");
}
void app::_print( const char* text )
{
if( _con != NULL )
_con->insert(text);
}

View File

@ -1,119 +0,0 @@
#ifndef app_h
#define app_h
class Fl_HSplitter;
class Fl_Text_Buffer;
class Fl_Text_Display;
class Fl_Box;
class Fl_Tabs;
struct Fl_Menu_Item;
class Fl_Menu_Bar;
class Fl_Group;
class Fl_Button;
class Fl_Valuator;
class Fl_Input;
class drawWnd;
class app : public Fl_Double_Window
{
public:
// widget id's for widgets created by createControls()
enum
{
kFileOpenMId,
kFileNewMId,
kEditCopyMId,
kEditPasteMId,
kBtn1MId,
kBtn2MId,
kBtn3MId,
kMenuBtn1MId,
kMenuBtn2MId,
kValue1MId,
kValue2MId,
kInput1MId
};
app(cmCtx_t* ctx, cmTsMp1cH_t printqH, int w, int h, const char *l, int argc, char *argv[]);
virtual ~app();
// Example tabbed window initialization example function
// which also demonstrates some widgets
void createControls(Fl_Group* grp);
// called once from app() to initialize each tabbed window
virtual void initializeTab(int tabIndex, int x, int y, int w, int h, const char* label);
// Create the application menu
virtual void createMenu( int menuWidth, int menuHeight );
// Widget type specific callbacks
virtual void menuCallback( const Fl_Menu_Item* ip, long int id ); // menu and menu btn callback
virtual void btnCallback( const Fl_Button* bp, int id ); // btn callback
virtual void valueCallback(const Fl_Valuator* vp, int id ); // valuator callback
virtual void inputCallback(const Fl_Input* ip, int id ); // text input callback
virtual void appCallback(Fl_Widget* wp); // app event callback
virtual bool idleCallback(); // return false to stop callback
virtual bool timerCallback(); // return false to stop callback
void error( const char* fmt, ... ); // report on error
// print to the console
virtual void vprint( const char* fmt, va_list vl );
virtual void print( const char* fmt, ... );
protected:
enum
{
kStatusH = 30,
kMenuH = 30,
kCtlH = 30
};
// static callbacks
static void _s_menu_cb( Fl_Widget* wp, void* data); // menu item callback
static void _s_menu_btn_cb(Fl_Widget* wp, void* data); // menu btn callback
static void _s_btn_cb( Fl_Widget* wp, long data); // button callback
static void _s_value_cb( Fl_Widget* wp, long data); // value input or slider callback
static void _s_input_cb( Fl_Widget* wp, long data); // text input callback
static void _s_callback( Fl_Widget* wp, void* data); // main app callback
static void _s_idle_cb( void* data); // idle callback
static void _s_timer_cb( void* userPtr); // timer callback
static void _s_print( void* userPtr, const char* text ); // print text to the console
void _create_tabs(int titleCnt, const char* titleArray[]);
// walk down the widget tree until the app (root) widget is located
static app* _getApp( Fl_Widget* w );
// called internally by cmTsQueueDequeue() to send text to _print()
static cmRC_t _s_print_queue_cb(void* userCbPtr, unsigned msgByteCnt, const void* msgDataPtr );
// called periodically to check the print queue for waiting text.
void _checkPrintQueue();
// send a string of text directly to the output console window
void _print( const char* text );
double _timerPeriodSecs; // repeat period for the timer callback
cmCtx_t* _ctx; //
Fl_HSplitter* _splt; // main splitter window
Fl_Text_Buffer* _buf; // text buffer used by _con
Fl_Text_Display* _con; // text console output window
Fl_Tabs* _tabs; // tabs window
Fl_Menu_Bar* _menu; // app. menu
drawWnd* _draw; // custom widget
cmTsMp1cH_t _printqH; // thread-safe queue for controlling access to the output console from multiple threads
int _printFl; // used to prevent recursion due to throwing printing error
};
#endif

View File

@ -1,24 +0,0 @@
#ifndef appErr_h
#define appErr_h
#ifdef __cplusplus
extern "C" {
#endif
enum
{
kOkAppRC,
kQueueFailAppRC,
kFileSysFailAppRC,
kMemFailAppRC,
kTextSysFailAppRC,
kPrefsFailAppRC
};
typedef unsigned cmAppRC_t;
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,110 +0,0 @@
#include <FL/Fl.H>
#include <Fl/fl_draw.H>
#include <FL/Fl_Double_Window.H>
#include "cmPrefix.h"
#include "cmGlobal.h"
#include "cmFloatTypes.h"
#include "cmRpt.h"
#include "cmErr.h"
#include "cmCtx.h"
#include "cmMem.h"
#include "cmMallocDebug.h"
#include "cmLinkedHeap.h"
#include "cmThread.h"
#include "cmFileSys.h"
#include "cmText.h"
#include "appErr.h"
#include "app.h"
void print( void*, const cmChar_t* text)
{ puts(text); }
cmRC_t print_queue_cb(void* userCbPtr, unsigned msgByteCnt, const void* msgDataPtr )
{
print(NULL,(const char*)msgDataPtr);
return cmOkRC;
}
int main( int argc, char* argv[] )
{
cmCtx_t ctx;
cmTsMp1cH_t printqH = cmTsMp1cNullHandle;
int appWndW = 1000;
int appWndH = 750;
const char* appPrefDir = "gv";
const char* appTitle = "GV Console";
bool memDebugFl = cmDEBUG_FL;
unsigned memPadByteCnt = memDebugFl ? 8 : 0;
unsigned memAlignByteCnt = 16;
unsigned memFlags = memDebugFl ? (kTrackMmFl | kDeferFreeMmFl | kFillUninitMmFl) : 0;
cmCtxSetup(&ctx,appTitle,print,print,NULL,memPadByteCnt,memAlignByteCnt,memFlags);
// initialize the memory mgr
if(cmMdInitialize( memPadByteCnt, memAlignByteCnt, memFlags, &ctx.rpt ) != kOkMmRC )
{
cmErrMsg(&ctx.err,kMemFailAppRC,"Heap initialization failed.");
goto errLabel;
}
// initialize the file system
if( cmFsInitialize( &ctx, appPrefDir ) != kOkFsRC )
cmErrMsg(&ctx.err,kFileSysFailAppRC,"File system initialization failed.");
// initialize the text system
if( cmTsInitialize(&ctx) != kOkTxRC )
cmErrMsg(&ctx.err,kTextSysFailAppRC,"Text system initialization failed.");
// create the print queue
if( cmTsMp1cCreate( &printqH, 8192, print_queue_cb, NULL, NULL ) != kOkThRC )
cmErrMsg(&ctx.err,kQueueFailAppRC,"Print queue creation failed.");
if( cmErrLastRC(&ctx.err) == kOkAppRC )
{
app proj(&ctx, printqH, appWndW, appWndH, appTitle, argc, argv);
Fl::run();
// reset the pgm context and print queue console output to stdout
cmRptSetup(&ctx.rpt,print,print,NULL);
cmTsMp1cSetCbFunc(printqH, print_queue_cb, NULL );
}
// empty any pending text to stdout
while( cmTsMp1cMsgWaiting(printqH) )
if( cmTsMp1cDequeueMsg(printqH, NULL, 0) != kOkThRC )
cmErrMsg(&ctx.err,kQueueFailAppRC,"Print dequeue failed.");
// destroy the print queue
if( cmTsMp1cDestroy(&printqH) != kOkThRC )
cmErrMsg(&ctx.err,kQueueFailAppRC,"Print queue destroy failed.");
// finalize the text system
if( cmTsFinalize() != kOkTxRC )
cmErrMsg(&ctx.err,kTextSysFailAppRC,"Text system finalization failed.");
// finalize the file system
if( cmFsFinalize() != kOkFsRC )
cmErrMsg(&ctx.err,kFileSysFailAppRC,"File system finalize failed.");
// report memory mgr errors
if( cmMdIsValid() )
cmMdReport( kIgnoreNormalMmFl );
// finalize the memory manager
if( cmMdFinalize() != kOkMmRC )
cmErrMsg(&ctx.err,kMemFailAppRC,"Heap finalization failed.");
errLabel:
return 0;
}

103
src/kc/Fl_File_Btn.cpp Normal file
View File

@ -0,0 +1,103 @@
#include <Fl/Fl.H>
#include <Fl/Fl_Button.H>
#include <Fl/Fl_File_Chooser.H>
#include <Fl/Fl_Output.H>
#include <Fl/Fl_Group.H>
#include "Fl_File_Btn.h"
Fl_File_Btn::Fl_File_Btn( int xx, int yy, int ww, int hh, const char* l )
: Fl_Group(xx,yy,ww,hh,l),
_patStr(NULL),_typeId(kFile_Type_Id),_btn(NULL),_out(NULL)
{
_init();
}
Fl_File_Btn::Fl_File_Btn( unsigned typeId, const char* patStr, int xx, int yy, int ww, int hh, const char* l )
: Fl_Group(xx,yy,ww,hh,l),
_patStr(NULL),_typeId(typeId),_btn(NULL),_out(NULL)
{
_init();
type(typeId);
pattern_string(patStr);
}
Fl_File_Btn::~Fl_File_Btn()
{ delete[] _patStr; }
unsigned Fl_File_Btn::type()
{ return _typeId; }
void Fl_File_Btn::type( unsigned typeId )
{
switch(typeId)
{
case kFile_Type_Id:
_btn->label("File");
_typeId = typeId;
break;
case kDir_Type_Id:
_btn->label("Dir");
_typeId = typeId;
break;
}
}
const char* Fl_File_Btn::pattern_string()
{ return _patStr; }
void Fl_File_Btn::pattern_string( const char* pat)
{
delete[] _patStr;
if( pat != NULL )
{
_patStr = new char[ strlen(pat) + 1];
strcpy(_patStr,pat);
}
}
void Fl_File_Btn::btn_width( int ww )
{
_btn->resize(_btn->x(),_btn->y(),ww,_btn->h());
_out->resize(_btn->x() + _btn->w() + 2, _out->y(), w() - _btn->w() - 2, _out->h());
}
int Fl_File_Btn::btn_width()
{ return _btn->w(); }
void Fl_File_Btn::filename( const char* fn )
{ _out->value(fn); _out->redraw(); }
const char* Fl_File_Btn::filename() const
{ return _out->value(); }
void Fl_File_Btn::_s_btn_cb(Fl_Widget* w, void* data)
{ ((Fl_File_Btn*)data)->_btn_cb(); }
void Fl_File_Btn::_btn_cb()
{
char* fn;
if( _typeId == kFile_Type_Id )
fn = fl_file_chooser("Select a file",_patStr,_out->value(),0);
else
fn = fl_dir_chooser("Select a directory",_out->value(),0);
if( fn != NULL )
{
_out->value(fn);
do_callback(this,user_data());
}
}
void Fl_File_Btn::_init()
{
_btn = new Fl_Button(x(),y(),40,h(),_typeId==kFile_Type_Id ? "File" : "Dir");
_btn->callback(_s_btn_cb,this);
_out = new Fl_Output(x() + _btn->w() + 2, y(), w() - _btn->w(), h());
}

47
src/kc/Fl_File_Btn.h Normal file
View File

@ -0,0 +1,47 @@
#ifndef Fl_File_Btn_h
#define Fl_File_Btn_h
class Fl_Button;
class Fl_Output;
class Fl_File_Btn : public Fl_Group
{
public:
enum
{
kFile_Type_Id,
kDir_Type_Id
};
Fl_File_Btn( int x, int y, int w, int h, const char* l = 0 );
Fl_File_Btn( unsigned typeId, const char* patStr, int x, int y, int w, int h, const char* l = 0 );
virtual ~Fl_File_Btn();
unsigned type();
void type( unsigned typeId );
const char* pattern_string();
void pattern_string( const char* pat);
void btn_width( int w );
int btn_width();
void filename( const char* fn );
const char* filename() const;
private:
char* _patStr;
unsigned _typeId;
Fl_Button* _btn;
Fl_Output* _out;
static void _s_btn_cb(Fl_Widget* w, void* data);
void _btn_cb();
void _init();
};
#endif

View File

@ -1,6 +1,6 @@
// Code based on: http://www.mail-archive.com/fltk@easysw.com/msg04573.html
// Lucas Sanner/Ian MacArthur
#include <stdio.h>
#include "Fl_Splitter.h"
void Fl_HSplitter::draw()

View File

@ -0,0 +1,77 @@
#include <FL/Fl.H>
#include <FL/fl_draw.H>
#include <Fl/Fl_Progress.H>
#include "Fl_Vert_Progress.h"
Fl_Vert_Progress::Fl_Vert_Progress(int x, int y, int w, int h, const char* l)
: Fl_Progress(x,y,w,h)
{
}
void Fl_Vert_Progress::draw()
{
int progress; // Size of progress bar...
int bx, by, bw, bh; // Box areas...
int tx, ty, tw, th; // Temporary X + width
float min_ = minimum();
float max_ = maximum();
float val_ = value();
// Get the box borders...
bx = Fl::box_dx(box());
by = Fl::box_dy(box());
bw = Fl::box_dw(box());
bh = Fl::box_dh(box());
tx = x() + bx;
ty = y() + by;
tw = w() - bw;
th = h() - bh;
// Draw the progress bar...
if (max_ > min_)
progress = (int)( th * (val_ - min_) / (max_ - min_) );
else
progress = 0;
// Draw the box and label...
if (progress > 0)
{
Fl_Color c = labelcolor();
labelcolor(fl_contrast(labelcolor(), selection_color()));
// draw the progress area
//fl_push_clip(x(), y() + h() - progress, w(), progress);
fl_push_clip(tx,ty + th - progress, tw, progress );
draw_box(box(), x(), y(), w(), h(), active_r() ? selection_color() : fl_inactive(selection_color()));
draw_label(tx, y() + by, tw, h() - bh);
fl_pop_clip();
labelcolor(c);
if (progress<w())
{
// draw the non-progress area
//fl_push_clip(x(), y(), w(), h() - progress );
fl_push_clip(tx,ty,tw,th-progress );
draw_box(box(), x(), y(), w(), h(), active_r() ? color() : fl_inactive(color()));
draw_label(tx, y() + by, tw, h() - bh);
fl_pop_clip();
}
}
else
{
draw_box(box(), x(), y(), w(), h(), active_r() ? color() : fl_inactive(color()));
draw_label(tx, y() + by, tw, h() - bh);
}
//fl_draw_box(FL_FLAT_BOX,x(),y(),w(),h(), FL_RED);
//fl_draw_box(FL_FLAT_BOX,tx,ty,tw,th, FL_GREEN);
//fl_draw_box(FL_FLAT_BOX,tx,ty,tw,th-progress, FL_BLACK); // non-prog
//fl_draw_box(FL_FLAT_BOX,tx,ty + th - progress,tw,progress,FL_BLUE); // prog
}

14
src/kc/Fl_Vert_Progress.h Normal file
View File

@ -0,0 +1,14 @@
#ifndef Fl_Vert_Progress_h
#define Fl_Vert_Progress_h
class Fl_Vert_Progress : public Fl_Progress
{
protected:
virtual void draw();
public:
Fl_Vert_Progress(int x, int y, int w, int h, const char* l=0);
};
#endif

2337
src/kc/kcApp.cpp Normal file

File diff suppressed because it is too large Load Diff

406
src/kc/kcApp.h Normal file
View File

@ -0,0 +1,406 @@
#ifndef kcApp_h
#define kcApp_h
extern "C" struct cmApBufState_str;
class Fl_Menu_Bar;
class Fl_HSplitter;
class Fl_Text_Buffer;
class Fl_Text_Display;
class Fl_Box;
class Fl_Tabs;
class Fl_Check_Button;
class Fl_Value_Slider;
class Fl_Menu_Button;
class Fl_File_Btn;
class Fl_Select_Browser;
class Fl_Valuator;
class Fl_Value_Input;
class Fl_Progress;
class kcApp : public Fl_Double_Window
{
public:
typedef unsigned kcKmRC_t;
enum
{
kOkKmRC,
kEngFailKmRC,
kMemFailKmRC,
kPrefsNotFoundKmRC,
kPrefWriteFailKmRC,
kPrefLoadFailKmRC,
kPrefFailKmRC,
kPrefSetFailKmRC,
kMlistLoadFailKmRC,
kJsonFailKmRC,
kDeserialFailKmRC,
kPrintQueFailKmRC,
};
kcApp(int w, int h, const char *l, int argc, char *argv[]);
virtual ~kcApp();
kcKmRC_t audioDspInitialize( cmCtx_t* ctx, cmRptPrintFunc_t printFunc, void* printFuncArg );
kcKmRC_t audioDspFinalize();
bool audioDspIsValid();
void print( const char* fmt, ... );
void vprint( const char* fmt, va_list vl );
private:
enum
{
kMenuH = 30,
kStatusH = 30,
kIndH = 25,
kIndW = 25,
kSsPhaseMax = 20
};
Fl_Menu_Bar* menu;
Fl_HSplitter* splt;
Fl_Box* ind[4];
Fl_Text_Buffer* buf;
Fl_Text_Display* con;
Fl_Tabs* tabs;
Fl_Check_Button* ena_chk;
//Fl_Group* ctl_grp;
Fl_Menu_Button* as_btn;
Fl_Menu_Button* ai_btn;
Fl_Menu_Button* ao_btn;
Fl_Menu_Button* pgm_btn;
Fl_Menu_Button* ss_btn;
Fl_Menu_Button* sr_btn;
Fl_Group* mstr_grp;
enum
{
kSldrTypeId,
kNumbTypeId,
kTextTypeId,
kButnTypeId,
kChckTypeId,
kLablTypeId,
kFnamTypeId,
kMlstTypeId,
kMetrTypeId,
kSldrMinArgIdx = 0,
kSldrMaxArgIdx = 1,
kSldrStpArgIdx = 2,
kSldrValArgIdx = 3,
kSldrLblArgIdx = 4,
kSldrVarCnt = 5,
kTextValArgIdx = 0,
kTextLblArgIdx = 1,
kTextVarCnt = 2,
kButnValArgIdx = 0,
kButnLblArgIdx = 1,
kButnVarCnt = 2,
kLablValArgIdx = 0,
kLablAlignArgIdx= 1,
kLablVarCnt = 2,
kChckValArgIdx = 0,
kChckLblArgIdx = 1,
kChckVarCnt = 2,
kFnamValArgIdx = 0,
kFnamPatArgIdx = 1,
kFnamDirArgIdx = 2,
kFnamVarCnt = 3,
kMlstHgtArgIdx = 0,
kMlstSelArgIdx = 1,
kMlstLstArgIdx = 2,
kMlstVarCnt = 3,
kMetrMinArgIdx = 0,
kMetrMaxArgIdx = 1,
kMetrValArgIdx = 2,
kMetrLblArgIdx = 3,
kMetrVarCnt = 4
};
enum
{
kEnableBtnId = 1,
kAudDevRptBtnId,
kAudioSysCfgBtnId,
kInAudDevBtnId,
kOutAudDevBtnId,
kPgmBtnId,
kSubSystemIdxBtnId,
kSrateBtnId,
kTestBtnId
};
enum
{
k44100SrateIdx,
k48000SrateIdx,
k96000SrateIdx
};
typedef struct sldr_str
{
union
{
Fl_Value_Slider* sldr;
Fl_Value_Input* numb;
} u;
Fl_Valuator* val;
double defaultVal;
unsigned varIdArray[ kSldrVarCnt ];
} sldr_t;
typedef struct text_str
{
Fl_Input* text;
char* val;
unsigned varIdArray[ kTextVarCnt ];
} text_t;
typedef struct butn_str
{
Fl_Button* butn;
double val;
unsigned varIdArray[ kButnVarCnt ];
} butn_t;
typedef struct chck_str
{
Fl_Check_Button* chck;
double val;
unsigned varIdArray[ kChckVarCnt ];
} chck_t;
typedef struct labl_str
{
Fl_Box* box;
unsigned varIdArray[ kLablVarCnt ];
} labl_t;
typedef struct fname_str
{
Fl_File_Btn* fnam;
unsigned varIdArray[ kFnamVarCnt ];
} fnam_t;
typedef struct mlst_str
{
Fl_Select_Browser* mlst;
Fl_Menu_Button* mbtn;
int sel;
unsigned varIdArray[ kMlstVarCnt ];
} mlst_t;
typedef struct metr_str
{
Fl_Progress* prog;
unsigned varIdArray[ kMetrVarCnt ];
} metr_t;
typedef struct ctl_str
{
kcApp* thisPtr;
unsigned asSubIdx;
unsigned typeId;
unsigned instId;
Fl_Widget* wdgtPtr;
bool mstrFl;
union
{
sldr_t sldr;
text_t text;
butn_t butn;
chck_t chck;
labl_t labl;
fnam_t fnam;
mlst_t mlst;
metr_t metr;
} u;
struct ctl_str* linkPtr;
} ctl_t;
typedef struct page_str
{
Fl_Group* grp;
struct page_str* link;
page_str() : grp(NULL), link(NULL) {}
} page_t;
enum
{
kUpdateSsIdx,
kWakeupSsIdx,
kMsgSsIdx,
kAudioCbSsIdx,
kProgSsCnt
};
// each audio sub-system is represented by an ss_t record in _ssArray[_ssCnt]
typedef struct ss_str
{
Fl_Progress* prog[kProgSsCnt]; // status indicator controls
unsigned cnt[kProgSsCnt]; // previous status count value
} ss_t;
cmCtx_t _ctx;
cmAdlH_t _adlH;
cmAiH_t _aiH;
unsigned _statIdx;
page_t* _pageList;
ctl_t* _ctlList;
const cmChar_t* _prefFn;
cmPrH_t _prH;
const cmChar_t* _prefsFn;
bool _stopTimerFl;
cmJsonH_t _jsH;
bool _newPageFl;
unsigned _incrColW;
unsigned _colW;
bool _horzBordFl;
unsigned _horzBord;
unsigned _closeCnt;
unsigned _ssCnt; // count of audio system sub-systems (set in _handleSsInitMsg())
ss_t* _ssArray;
int _ssPhase;
bool _ssUpdateFl;
cmTsQueueH_t _printqH; // thread-safe queue for controlling access to the output console from multiple threads
void resize(int x, int y, int w, int h);
void _createSetupDlg(Fl_Group* grp);
void _createPage( const char* title );
unsigned _getCtlCount() const;
void _clearCtlList(bool mstrFl);
void _clearSsArray();
void _getNewCtlPosn( const cmDspUiHdr_t* m, int& x, int& y, int& w, int& h );
ctl_t* _findCtl( unsigned instId, unsigned asSubIdx, unsigned mstrFl=false );
ctl_t* _createCtl( const cmDspUiHdr_t* m, unsigned typeId, int& x, int& y, int& w, int& h );
void _insertNewCtl( ctl_t* cp, const cmDspUiHdr_t* m, Fl_Widget* wdgt, unsigned* varIdArray, unsigned varIdCnt );
void _createSlider( const cmDspUiHdr_t* m );
void _setSldrValue( ctl_t* cp, unsigned instVarId, const cmDspValue_t* vp );
void _createText( const cmDspUiHdr_t* m );
void _setTextValue( ctl_t* cp, unsigned instVarId, const cmDspValue_t* vp );
void _createFnameCtl( const cmDspUiHdr_t* m );
void _setFnamValue( ctl_t* cp, unsigned instVarId, const cmDspValue_t* vp );
void _createMlistCtl( const cmDspUiHdr_t* m );
kcKmRC_t _loadMlist( ctl_t* cp, const cmJsonNode_t* np );
void _setMlistValue( ctl_t* cp, unsigned instVarId, const cmDspValue_t* vp );
void _createMeter( const cmDspUiHdr_t* m );
void _setMeterValue( ctl_t* cp, unsigned instVarId, const cmDspValue_t* vp );
void _createButton( const cmDspUiHdr_t* m );
void _setButtonValue( ctl_t* cp, unsigned instVarId, const cmDspValue_t* vp );
void _createCheck( const cmDspUiHdr_t* m );
void _setCheckValue( ctl_t* cp, unsigned instVarId, const cmDspValue_t* vp );
void _createLabel( const cmDspUiHdr_t* m );
void _setLabelValue( ctl_t* cp, unsigned instVarId, const cmDspValue_t* vp );
void _newColumn( const cmDspUiHdr_t* m );
void _insertAudioSysCfgLabel(unsigned long idx, const cmChar_t* label );
void _insertDeviceLabel( unsigned long idx, bool inputFl, const cmChar_t* label );
void _insertProgramLabel( unsigned long idx, const cmChar_t* label );
void _insertSubSysCnt( unsigned long subSysCnt );
unsigned _getCurAudioSubSysIdx();
void _setMenuButton( Fl_Menu_Button* b, unsigned value, const char* dfltLabel );
void _setDeviceMenuButton( unsigned asSubIdx, bool inputFl, unsigned devIdx );
void _setSampleRateBtn( unsigned value );
void _updateMeters( unsigned asSubIdx, unsigned devIdx, unsigned inFl, const double* meterArray, unsigned meterCnt );
void _updateSsStatusIndicator( unsigned asSubIdx, unsigned indicatorIdx, unsigned cnt );
void _printStatusCounts();
void _handleStatusMsg( const cmAudioSysStatus_t* st, const double* iMeterArray, const double* oMeterArray );
void _clearStatusIndicators();
void _sendMasterUiMsg( unsigned asSubIdx, unsigned selId, unsigned instId, unsigned instVarId, const cmDspValue_t* v );
void _sendMasterUiValue(unsigned asSubIdx, unsigned instId, const double* v, unsigned vn, const cmChar_t* text );
void _createMasterCtl( unsigned asSubIdx, unsigned selId, unsigned instId, unsigned varCnt, const double* dv, unsigned dn, const cmChar_t* label);
void _handleSsInitMsg( const cmAudioSysSsInitMsg_t* m, const cmChar_t* inDevLabel, const cmChar_t* outDevLabel );
void _onRecvValue( const cmDspUiHdr_t* m );
void _handleUiMsg( const cmDspUiHdr_t* m );
void _getEngMsg();
static cmRC_t _s_handleSsInitMsg( void* cbDataPtr, const cmAudioSysSsInitMsg_t* r, const char* iDevLabel, const char* oDevLabel );
static cmRC_t _s_handleStatusMsg( void* cbDataPtr, const cmAudioSysStatus_t* r, const double* iMeterArray, const double* oMeterArray );
static cmRC_t _s_handleUiMsg( void* cbDataPtr, const cmDspUiHdr_t* r );
static kcApp* _getApp( Fl_Widget* w );
kcKmRC_t _restartEngine();
void _testStub();
// main app callback
static void _s_callback(Fl_Widget* wp, void* data);
void _callback(void* data);
// idle callback
static void _s_on_idle(void* data);
void _on_idle();
// timer callback
static void _s_status_timeout_cb(void* userPtr);
bool _status_timeout_cb();
static void _s_file_new_cb(Fl_Widget *w, void *data);
void _file_new_cb(Fl_Widget *w);
static void _s_file_open_cb(Fl_Widget *w, void *data);
void _file_open_cb(Fl_Widget *w);
static void _s_edit_copy_cb(Fl_Widget *w, void *data);
void _edit_copy_cb(Fl_Widget *w);
static void _s_edit_paste_cb(Fl_Widget *w, void *data);
void _edit_paste_cb(Fl_Widget *w);
static void _s_btn_cb(Fl_Widget* w, long data);
void _btn_cb(Fl_Widget* w, long arg);
static void _s_ctl_cb(Fl_Widget* w, void* data);
void _ctl_cb(ctl_t* cp);
static void _s_tab_cb(Fl_Widget* w, void* data);
void _tab_cb(Fl_Widget* w);
//
static void _s_print( void* userPtr, const char* text );
// called internally by cmTsQueueDequeue() to send text to _print()
static cmRC_t _s_print_queue_cb(void* userCbPtr, unsigned msgByteCnt, const void* msgDataPtr );
// called periodically to check the print queue for waiting text.
void _checkPrintQueue();
// send a string of text directly to the output console window
void _print( const char* text );
};
#endif

39
src/kc/kcMain.cpp Normal file
View File

@ -0,0 +1,39 @@
#include <FL/Fl.H>
#include <FL/Fl_Double_Window.H>
#include <FL/Fl_Menu_Item.H>
#include <Fl/Fl_Menu_Bar.H>
#include <Fl/Fl_Button.H>
#include <Fl/Fl_Text_Buffer.H>
#include <Fl/Fl_Text_Display.H>
#include <Fl/Fl_Tabs.H>
#include <Fl/Fl_File_Chooser.H>
#include "Fl_Splitter.h"
#include "cmGlobal.h"
#include "cmFloatTypes.h"
#include "cmRpt.h"
#include "cmErr.h"
#include "cmCtx.h"
#include "cmPrefs.h"
#include "cmJson.h"
#include "cmThread.h"
#include "cmDspValue.h"
#include "cmMsgProtocol.h"
#include "cmAudDspIF.h"
#include "cmAudDspLocal.h"
#include "kcApp.h"
void print(void* cmRptUserPtr, const char* text)
{ printf("%s",text); }
int main(int argc, char* argv[] )
{
kcApp myApp(1600, 750, "Console", argc, argv);
Fl::run();
//test();
return 0;
}