The V C++ GUI Framework User Guide:Tutorial:Tutorial code
Tutorial C++ Source The following is a complete tutorial V application. The source for this tutorial is available int the directory ~/v/tutor.
The Application tutapp.cpp
//======================================================================== // tutapp.cpp: Source file for tutorial V application // // Copyright 1995, Bruce E. Wampler. All rights reserved. //======================================================================== // // This file is used to define the main application object. There // will be exactly one instance of the application object. You will // usually derive you own app class from the vApp class. This file // defines a sample tutApp class. The usual purpose of tutApp is to // start the initial window, and act as a central controller for // your application. Rather than reading this file sequentially, // you should skip to the end and read the comments surrounding the // AppMain function.
// Files required for tutorial minimal application:
// tutapp.h: Header for the min app
// tutapp.cpp: Source code for min app
// tcmdwin.h: Header code for sample command window
// tcmdwin.cpp: Source code for sample command window
// tdialog.h: Header for sample modeless dialog
// tdialog.cpp: Source for sample modeless dialog
// tmodal.h: Header for sample modal dialog
// tmodal.cpp: Source for sample modal dialog
//
// First #include header files we need to use.
- include "tutapp.h" // our header file
//=========================>>> tutApp::NewAppWin <<<======================
vWindow* tutApp::NewAppWin(vWindow* win, char* name, int w, int h, vAppWinInfo* winInfo) { // This version of NewAppWin is provided with the information // required to name and size a window. // // Typically, this method would get a file name or other information // needed to setup the AppWinInfo class specifically for the // application. Thus, each open window usually represents a view of // a file or data object.
vWindow* thisWin = win; // local copy to use vAppWinInfo* awinfo = winInfo; char *myname = name; // local copy
if (!*name) myname = "Example"; // make up a name // The UserDebug macros are useful for tracking what is going on. // This shows we're building a window.
UserDebug1(Build,"tutApp::NewAppWin(%s)\n",myname);
// You may instantiate an instance of the window outside of // NewAppWin, or allow NewAppWin to create the instance.
if (!thisWin) // Didn't provide a window, so create one. thisWin = new tCmdWindow(myname, w, h);
// The vAppWinInfo class is meant to serve as a database used by the // tutApp controller. If you use this feature, you will probably // derive your own myAppWinInfo class from vAppWinInfo. The instance // of vAppWinInfo created here will be automatically deleted when // this window instance is closed through CloseAppWin.
if (!awinfo) // Did caller provide an appinfo? awinfo = new vAppWinInfo(myname);
// After you have created an instance of the window and an instance // of the AppWinInfo, you MUST call the base vApp::NewAppWin method. // You won't need to explicitly keep track of the pointer to // each new window -- unless it has to interact with other windows. // If that is the case, then you can use your derived vAppWinInfo // to coordinate the interaction.
return vApp::NewAppWin(thisWin,name,w,h,awinfo); }
//===========================>>> tutApp::Exit <<<=========================
void tutApp::Exit(void) { // This can be called to close all windows. If the app needs to do // something special, it can. Otherwise, it can call the general // vApp::Exit method, which will perform appropriate calls the the // specialized tutApp::CloseAppWin.
UserDebug(Build,"tutApp::Exit()\n");
vApp::Exit(); // easy default behavior }
//======================>>> tutApp::CloseAppWin <<<=======================
void tutApp::CloseAppWin(vWindow* win) { // This will be called BEFORE a window has been unregistered or // closed. The app can do whatever it needs to to close down the // data associated with this window. (It is invoked explicitly by // you in response to a Close menu pick, for example, or when the // user clicks the close button. It can also be called by vApp::Exit(). // After this method cleans up, it can then call the superclass // vApp::CloseAppWin to unregister and close this window. Note that // the win gives a handle that can be used with vApp::getAppWinInfo // to retrieve the AppWinInfo class.
UserDebug(Build,"tutApp::CloseAppWin()\n");
// Code to handle close of window (such as saving/closing // a file) would go here...
vApp::CloseAppWin(win); // Unregister and close the window. }
//=====================>>> tutApp::AppCommand <<<=========================
void tutApp::AppCommand(vWindow* win, ItemVal id, ItemVal val, CmdType cType) { // Any commands not processed by the window WindowCommand // method will be passed to here for default treatment.
UserDebug1(Build,"tutApp::AppCmd(ID: %d)\n",id); vApp::AppCommand(win, id, val, cType); }
//=======================>>> tutApp::KeyIn <<<============================
void tutApp::KeyIn(vWindow* win, vKey key, unsigned int shift) { // Any key strokes not processed by the window will be passed // along to here for default treatment.
vApp::KeyIn(win, key, shift); }
//======================================================================== // Remember that any static references to an object are constructed by // the C++ startup code before main or any other functions are called. // Thus, the constructor for tutApp (and thus vApp) is invoked before // anything else happens. This enables V to perform whatever // initializations are required by the host GUI system - and frees you // from having to worry about the typical gory details. All this means // that EVERY V application needs a static instance of the tutApp to // get things rolling. Note that the global variable theApp is set to // point to this instance, and is the easiest way to access the vApp // and tutApp methods (e.g., theApp->Exit()). //========================================================================
static tutApp tut_App("TutorApp"); // The single instance of the app
//===========================>>> AppMain <<<==============================
int AppMain(int argc, char** argv) { // The V framework defines the instance of main. After some // processing of command line arguments, AppMain is called with // cleaned up command line arguments. Note that at this time, no // windows have been defined. Normally, AppMain is the place to // start up the first window. You can perform any initialization you // need to do here.
(void) theApp->NewAppWin(0, "Tutorial V Example", 350, 100, 0);
// At this point, the window is up, and all events are being // routed through its methods.
// We MUST return 0 if the status is OK at this point. return 0; }
tutapp.h
//======================================================================== // tutapp.h: Header file for tutorial V application // // Copyright 1995, Bruce E. Wampler. All rights reserved. //========================================================================
- ifndef TUTAPP_H // Standard technique for avoiding
- define TUTAPP_H // problems with multiple #includes
- ifdef vDEBUG
- include <v/vdebug.h>
- endif
- include <v/vapp.h> // We are derived from vApp
- include <v/vawinfo.h> // Need for app info
- include "tcmdwin.h" // we use our tCmdWindow class
class tutApp : public vApp { friend int AppMain(int, char**); // allow AppMain access
public: //---------------------------------------- public
tutApp(char* name) : vApp(name) {} // just call vApp virtual ~tutApp() {}
// Routines from vApp that are normally overridden
virtual vWindow* NewAppWin(vWindow* win, char* name, int w, int h, vAppWinInfo* winInfo); virtual void Exit(void); virtual void CloseAppWin(vWindow* win); virtual void AppCommand(vWindow* win, ItemVal id, ItemVal val, CmdType cType); virtual void KeyIn(vWindow* win, vKey key, unsigned int shift);
// New routines for this particular app go here
protected: //------------------------------------- protected
private: //--------------------------------------- private
};
- endif
The Command Window
tcmdwin.cpp
//======================================================================== // tcmdwin.cpp: Source file for tutorial cmdwin class // // Copyright 1995, Bruce E. Wampler. All rights reserved. //========================================================================
// This file contains the source code for a typical command window // derived from the vCmdWindow class. It will contain the definitions // of the menu bar and command and status bars. It represents the main // interaction point with the user. // // We start out with the #includes needed to define this class plus // any V utility dialogs such as vNotice we use.
- include <v/vnotice.h> // so we can use notice
- include <v/vkeys.h> // to map keys
- include <v/vutil.h> // for utilities
- include <v/vfilesel.h> // for file select
- include "tcmdwin.h" // our header file
// Now, we define static arrays for the menus, command bars, and // status bars used by this window. This consists of defining the // constants needed for IDs, followed by the static declarations of // the menu and command arrays. Note that V predefines quite a few // standard IDs which you can use instead of defining your own.
// Start ID defines for the main window at 100
const ItemVal m_CheckMe = 100; // for CheckMe command const ItemVal m_CopySens = 101; // for Set Copy Sensitive const ItemVal m_Dialog = 102; // to pop up the dialog const ItemVal m_ModalDialog = 103; // for modal dialog const ItemVal m_Clear = 104; // Clear screen
// Now, the static declarations of the menu arrays. You first define // the pulldown menus, one for each main menu bar label.
static vMenu FileMenu[] = // Items for File menu { {"New",M_New,isSens,notChk,noKeyLbl,noKey,noSub}, {"Open",M_Open,isSens,notChk,noKeyLbl,noKey,noSub}, {"Save",M_Save,notSens,notChk,noKeyLbl,noKey,noSub}, {"Save As",M_SaveAs,notSens,notChk,noKeyLbl,noKey,noSub},
- ifdef vDEBUG // Defines V debug code
{"-",M_Line,notSens,notChk,noKeyLbl,noKey,noSub}, {"Debug",M_SetDebug,isSens,notChk,noKeyLbl,noKey,noSub},
- endif
{"-",M_Line,notSens,notChk,noKeyLbl,noKey,noSub}, {"Exit",M_Exit,isSens,notChk,noKeyLbl,noKey,noSub}, {NULL} };
static vMenu EditMenu[] = // Items for Edit menu { {"Cut",M_Cut,notSens,notChk,noKeyLbl,noKey,noSub}, {"Copy",M_Copy,notSens,notChk,noKeyLbl,noKey,noSub}, {"Paste",M_Paste,notSens,notChk,noKeyLbl,noKey,noSub}, {NULL} };
static vMenu TestMenu[] = // Items for Test menu { {"CheckMe",m_CheckMe,isSens,notChk,noKeyLbl, noKey,noSub}, {"Copy Sensitive",m_CopySens,isSens,notChk,noKeyLbl, noKey,noSub}, {"Dialog",m_Dialog,isSens,notChk,noKeyLbl, noKey,noSub}, {"Modal Dialog",m_ModalDialog,isSens,notChk,noKeyLbl, noKey,noSub}, {NULL} };
// Now, define the items on the menu bar
vMenu StandardMenu[] = // The menu bar with three items { {"File",M_File,isSens,notUsed,notUsed,noKey,&FileMenu[0]}, {"Edit",M_Edit,isSens,notUsed,notUsed,noKey,&EditMenu[0]}, {"Test",M_Test,isSens,notUsed,notUsed,noKey,&TestMenu[0]}, {NULL} };
// We now define a command bar. Command bars are optional, and there // may be more than one. You can place any CommandObject you want on a // command bar.
static CommandObject CommandBar[] = // A simple command bar { {C_Label,999,0 ,"Command Bar",NoList,CA_None, isSens,NoFrame,0,0}, {C_Button,M_Copy,M_Copy,"Copy",NoList,CA_None, notSens,NoFrame,0,0}, {C_Button,m_Dialog,m_Dialog,"Dialog",NoList,CA_None, isSens,NoFrame,0,0}, {C_Button,m_Clear,m_Clear,"Clear",NoList,CA_None, isSens,NoFrame,0,0}, {C_Button,M_Exit,M_Exit,"Exit",NoList,CA_None, isSens,NoFrame,0,0}, {C_EndOfList,0,0,0,0,CA_None,0,0,0} // This ends list };
// Sometimes it is easier to define IDs near the definition of // the dialog or status bar using them.
const ItemVal m_cmdMsg = 110; const ItemVal m_cmdCount = 111; const ItemVal m_keyMsg = 112; const ItemVal m_keyVal = 113;
static vStatus StatBar[] = // Define a simple status bar { {"Commands issued: ",m_cmdMsg,CA_NoBorder,isSens,0}, {" ",m_cmdCount,CA_None,isSens,0}, {"Last keypress: ",m_keyMsg,CA_NoBorder,isSens,0}, {" ",m_keyVal,CA_None,isSens,0}, {0,0,0,0,0} // This ends list };
static int copy_sens = 0; // local for tracking sensitive
//======================>>> tCmdWindow::tCmdWindow <<<====================
tCmdWindow::tCmdWindow(char* name, int width, int height) : vCmdWindow(name, width) { // This is the constructor for tCmdWindow. UserDebug1(Constructor,"tCmdWindow::tCmdWindow(%s) Constructor\n",name)
// The "Standard" window will consist of a menubar, a canvas, an // optional button bar, and an optional status bar. // // First, create and add the proper panes to the CmdWindow // Note: there must be a corresponding delete in the destructor
// Create and add the standard Menu Bar to this window myMenu = new vMenuPane(StandardMenu); AddPane(myMenu);
// Create and add our Canvas pane to this window myCanvas = new tCanvasPane; AddPane(myCanvas);
// Create and add the command pane to this window myCmdPane = new vCommandPane(CommandBar); AddPane(myCmdPane);
// Create and add the Status Bar to this window myStatus = new vStatusPane(StatBar); AddPane(myStatus);
// In the V model, a window may have dialogs. Each dialog used // by a window must have an instance pointer. The easiest way // to create dialogs is to construct each one using a new here // which only defines the dialog - you need to use its // ShowDialog method at the appropriate time to display it). // You delete dialogs in the destructor for this window. // // Now, create whatever dialogs this app defines: // instances of tDialog and tModalDialog
sampleDialog = new tDialog(this); sampleModalDialog = new tModalDialog(this);
// FINALLY, after all the panes have been constructed and // added, we must show the window!
ShowWindow(); }
//=====================>>> tCmdWindow::~tCmdWindow <<<====================
tCmdWindow::~tCmdWindow() { UserDebug(Destructor,"tCmdWindow::~tCmdWindow() destructor\n")
// Now put a delete for each new in the constructor.
delete myMenu; delete myCanvas; delete myStatus; delete myCmdPane; delete sampleDialog; delete sampleModalDialog; }
//========================>>> tCmdWindow::KeyIn <<<=======================
void tCmdWindow::KeyIn(vKey keysym, unsigned int shift) { // Keystrokes are routed to this window. This example code shows very // simple processing of keystrokes, and how to update the m_keyVal // field of the status bar.
static char ctrl[] = "^X "; static char chr[] = " X ";
if (VK_IsModifier(keysym)) SetString(m_keyVal, "mod"); // change status bar else if (keysym < ' ') // ctrl char { ctrl[1] = keysym + '@'; SetString(m_keyVal, ctrl); // change status bar } else if (keysym < 128) // normal printable char { chr[1] = keysym; SetString(m_keyVal, chr); // change status bar } else SetString(m_keyVal, "+++"); // change status bar }
//====================>>> tCmdWindow::WindowCommand <<<===================
void tCmdWindow::WindowCommand(ItemVal id, ItemVal val, CmdType cType) { // All commands generated from this window's menus and dialog bars // are routed through here. The easiest way to handle commands is to // use a single, sometimes large switch. Each time you add a command // to a menu or command bar, add a case to the switch here. In this // example, we use the V Notice dialog to display entered commands.
static int cmdCount = 0; // Used for sample status update vNoticeDialog note(this); // Used for default actions char buff[20]; // buffer for status bar
++cmdCount; // count commands that have been issued IntToStr(cmdCount,buff); // Use V utility routine to get string SetString(m_cmdCount, buff); // change status bar
UserDebug1(CmdEvents,"tCmdWindow:WindowCommand(%d)\n",id)
switch (id) // The main switch to handle commands { // File Menu commands ------------------------------------
case M_New: // For this example, we will open a { // new window using our NewAppWin. (void) theApp->NewAppWin(0,"",250,100); break; }
case M_Open: // This demos vFileSelect dialog { char name[100] = ""; // start out with null name vFileSelect fsel(this); // an instance of vFileSelect int fI; // Filter index static char* filter[] = { // Filter for file select "*", "*.txt", "*.c *.cpp *.h", 0 };
// Show the file select dialog int ans = fsel.FileSelect("Open file",name,99,filter,fI);
if (ans && *name) // User picked a file name { SetTitle(name); // Set title of window to name note.Notice(name); // Show the name } else // Notify no name selected note.Notice("No file name selected."); }
case M_Save: // This would usually save a file { note.Notice("Save"); break; }
case M_SaveAs: // Save to a specified name { note.Notice("Save As"); break; }
- ifdef vDEBUG // Include debugging like this
case M_SetDebug: { vDebugDialog debug(this); // an instance of debug debug.SetDebug(); // dialog - let user set break; }
- endif
case M_Exit: // Standard exit command { // Invoke the standard app Exit theApp->Exit(); // to close all windows break; // will never get here }
// Edit Menu commands ------------------------------------ case M_Cut: // Standard items for Edit menu { note.Notice("Cut"); break; }
case M_Copy: { note.Notice("Copy"); break; }
case M_Paste: { note.Notice("Paste"); break; }
// Test Menu commands ------------------------------------ case m_CheckMe: // Demonstrate using a checked menu { ItemVal curval = GetValue(id); // Get current status SetValue(m_CheckMe,!curval,Checked); // Toggle check
if (curval) // Change menu label SetString(m_CheckMe,"Check Me"); else SetString(m_CheckMe,"UnChk Me"); break; }
case m_CopySens: // Demo changing sensitivity { copy_sens = !copy_sens; // toggle // This will change both menu and command button SetValue(M_Copy,copy_sens,Sensitive); break; }
case m_Dialog: // Invoke our dialog { if (!sampleDialog->IsDisplayed()) // not twice! sampleDialog->ShowDialog("Sample Modeless Dialog"); break; }
case m_ModalDialog: // Invoke our modal dialog { ItemVal val, id; id = sampleModalDialog->ShowModalDialog("Sample Modal",val); // Now do something useful with id and val ... break; }
case m_Clear: // Clear the canvas { myCanvas->Clear(); // Invoke the canvas Clear break; }
default: // route unhandled commands up { // to superclass vCmdWindow::WindowCommand(id, val, cType); break; } } }
tcmdwin.h
//======================================================================== // tcmdwin.h: Header file for tutorial V command window // // Copyright 1995, Bruce E. Wampler. All rights reserved. //======================================================================== // // Derive a window from the vCmdWindow class
- ifndef TCMDWIN_H
- define TCMDWIN_H
- include <v/vcmdwin.h> // So we can use vCmdWindow
- include <v/vmenu.h> // For the menu pane
- include <v/vstatusp.h> // For the status pane
- include <v/vcmdpane.h> // command pane
- ifdef vDEBUG
- include <v/vdebug.h>
- endif
- include "tdialog.h" // user defined: tDialog
- include "tmodal.h" // user defined: tModalDialog
- include "tcanvas.h" // user defined: tCanvasPane
class tCmdWindow : public vCmdWindow { friend int AppMain(int, char**); // allow AppMain access
public: //---------------------------------------- public tCmdWindow(char*, int, int); // Constructor with size virtual ~tCmdWindow(); // Destructor virtual void WindowCommand(ItemVal id,ItemVal val,CmdType cType); virtual void KeyIn(vKey keysym, unsigned int shift);
protected: //------------------------------------- protected
private: //--------------------------------------- private
// Each user CmdWindow should conform to a "Standard" window, // which includes a menu bar, a canvas, an optional command bar, // and an optional status bar.
vMenuPane* myMenu; // For the menu bar tCanvasPane* myCanvas; // For the canvas vStatusPane* myStatus; // For the status bar vCommandPane* myCmdPane; // for the command pane
// Each user CmdWindow will probably have some dialogs and // subwindows. Declare pointers to each instance here.
tDialog* sampleDialog; tModalDialog* sampleModalDialog; };
- endif
The Canvas
tcanvas.cpp
//======================================================================== // tcanvas.cpp - source for tutorial canvas // // Copyright 1995, Bruce E. Wampler, All Rights Reserved. //======================================================================== // // Each V application usually needs a canvas. In order to handle // various events: mouse, redraw, resize, and scroll, you will need to // derive your own canvas class. The base V vCanvasPane class can only // draw -- it does not have any memory of what has been drawn on the // screen (the vTextCanvasPane does handle redrawing, but is still // limited). Thus, your class will usually be responsible for handling // redrawing. This example is very simple. It lets the user draw // lines - up to 200 - and will redraw the screen when it has been // exposed.
// The example does not handle scrolling.
- include "tcanvas.h" // include our header file
//====================>>> tCanvasPane::tCanvasPane <<<====================
tCanvasPane::tCanvasPane() { // The constructor initializes our simple data structure.
_mouseDown = 0; _nextpt = 0; _begx = -1; _begy = -1; _curx = -1; _cury = -1; _pt = new point[200]; // allocate only 200 lines }
//-===================>>> tCanvasPane::tCanvasPane <<<====================
tCanvasPane::~tCanvasPane() { delete [] _pt; // free the point array }
//======================>>> tCanvasPane::Clear <<<========================
void tCanvasPane::Clear() { vCanvasPane::Clear(); // clear the canvas _nextpt = 0; // start over at 0 }
// This example does not handle scrolling, but a derived canvas would // be likely to. Thus, we've included the derived scrolling methods, // but simply call the superclass method for default handling, which // is essentially a no op.
//======================>>> tCanvasPane::HPage <<<========================
void tCanvasPane::HPage(int shown, int top) { vCanvasPane::HPage(shown, top); }
//======================>>> tCanvasPane::VPage <<<========================
void tCanvasPane::VPage(int shown, int top) { vCanvasPane::VPage(shown, top); }
//======================>>> tCanvasPane::HScroll <<<======================
void tCanvasPane::HScroll(int step) { vCanvasPane::HScroll(step); }
//======================>>> tCanvasPane::VScroll <<<======================
void tCanvasPane::VScroll(int step) { vCanvasPane::VScroll(step); }
//=====================>>> tCanvasPane::MouseDown <<<=====================
void tCanvasPane::MouseDown(int X, int Y, int button) { // Mouse down means the user is starting a line. We don't care which // button was pressed. There is nothing to draw until the mouse moves.
_mouseDown = 1; // track mouse button _pt[_nextpt].x = _begx = _curx = X; // starting point _pt[_nextpt].y = _begy = _cury = Y; if (++_nextpt >= 200) // set next point and do a simple _nextpt = 0; // minded storage allocation }
//======================>>> tCanvasPane::MouseMove <<<====================
void tCanvasPane::MouseMove(int x, int y, int button) { // Mouse move means the user is drawing a line, so we have to draw // it on the screen. By drawing a Rubber Line, we can easily track // the user motions, and undraw the previous line.
if (_begx != _curx || _begy != _cury) // Was there a previous line? DrawRubberLine(_begx, _begy, _curx, _cury); // Undraw old line
if (_begx != x || _begy != y) // If we moved, draw new line DrawRubberLine(_begx, _begy, x, y); _curx = x; _cury = y; // update positions }
//========================>>> tCanvasPane::MouseUp <<<====================
void tCanvasPane::MouseUp(int X, int Y, int button) { // Mouse up means the user has ended a line, so we need to draw // a permanent line and update the data base.
_mouseDown = 0; // Mouse down now if (_begx != X || _begy != Y) // We drew a line DrawLine(_begx, _begy, X, Y); // So draw permanent version
_pt[_nextpt].x = X; _pt[_nextpt].y = Y; // End point
if (++_nextpt >= 200) // set next point and do a simple _nextpt = 0; // minded storage allocation
_begx = -1; _begy = -1; _curx = -1; _cury = -1; // for next line }
//========================>>> tCanvasPane::Redraw <<<=====================
void tCanvasPane::Redraw(int x, int y, int w, int h) { // This is a simple Redraw that just redraws everything. // Often, that will be more than fast enough, but the input // parameters can be used to make a more intelligent redraw.
for (int i = 0 ; i < _nextpt ; i += 2) DrawLine(_pt[i].x, _pt[i].y, _pt[i+1].x, _pt[i+1].y); }
//======================>>> tCanvasPane::Resize <<<=======================
void tCanvasPane::Resize(int w, int h) { // We also don't handle resizing in this example. vCanvasPane::Resize(w,h); }
tcanvas.h
//======================================================================== // tcanvas.h -- header file for tutorial canvas class // // Copyright 1995, Bruce E. Wampler, All Rights Reserved. //========================================================================
- ifndef TCANVAS_H
- define TCANVAS_H
- include <v/vcanvas.h> // derive from vCanvasPane
typedef struct point // simple structure for points { int x; int y; } point;
class tCanvasPane : public vCanvasPane { public: //---------------------------------------- public tCanvasPane(); virtual ~tCanvasPane();
// Windows virtual void Clear();
// Scrolling virtual void HPage(int, int); virtual void VPage(int, int); virtual void HScroll(int); virtual void VScroll(int);
// Events virtual void MouseDown(int, int, int); virtual void MouseUp(int, int, int); virtual void MouseMove(int, int, int); virtual void Redraw(int, int, int, int); // Expose/redraw event virtual void Resize(int, int); // Resize event
protected: //------------------------------------- protected
private: //--------------------------------------- private // Note that we try to use a leading underscore to indicate // private members. We aren't always consistent! int _mouseDown; // track if mouse down int _begx; int _begy; // starting point int _curx; int _cury; // current point point *_pt; // the array of points int _nextpt; // where next point goes };
- endif
A.4 A Modeless Dialog
tdialog.cpp
//======================================================================== // tdialog.cpp - Source file for tutorial tDialog class // // Copyright 1995, Bruce E. Wampler, All Rights Reserved //======================================================================== // #include the headers we need #include <v/vnotice.h> #include "tdialog.h" // The structure of a derived dialog class is very similar to the // structure of a command window class. First we define IDs for the // various command objects used in the dialog. Then we declare the // static array that defines the dialog. const ItemVal mdLbl1 = 200; const ItemVal mdFrm1 = 201; const ItemVal mdLbl2 = 202; const ItemVal mdCB1 = 203; const ItemVal mdCB2 = 204; const ItemVal mdCB3 = 205; const ItemVal mdFrmV1 = 206; const ItemVal mdLbl3 = 207; const ItemVal mdRB1 = 208; const ItemVal mdRB2 = 209; const ItemVal mdFrmV2 = 210; const ItemVal mdLbl4 = 211; const ItemVal mdBtn1 = 212; const ItemVal mdBtn2 = 213; const ItemVal mdBtnChange = 214; static char change_me[] = "Change Me A"; // a label to change // This defines the dialog static CommandObject DefaultCmds[] = { {C_Label, mdLbl1, 0,"X",NoList,CA_MainMsg,isSens,NoFrame, 0, 0}, {C_Frame,mdFrmV2,0,"",NoList,CA_None,isSens,NoFrame,0,mdLbl1}, {C_Label,mdLbl4,0,"Buttons",NoList,CA_None,isSens,mdFrmV2,0,0}, {C_Button,mdBtn1,mdBtn1,"Button 1",NoList,CA_None, isSens,mdFrmV2,0,mdLbl4}, {C_Button,mdBtn2,mdBtn2,"Button 2",NoList,CA_None, isSens,mdFrmV2,0,mdBtn1}, {C_Frame,mdFrm1,0,"",NoList,CA_None,isSens,NoFrame,mdFrmV2,mdLbl1}, {C_Label,mdLbl2,0,"CheckBox",NoList,CA_None,isSens,mdFrm1,0,0}, {C_CheckBox,mdCB1,0,"Test A",NoList,CA_None, isSens,mdFrm1,0,mdLbl2}, {C_CheckBox,mdCB2,0,"Test B",NoList,CA_None, isSens,mdFrm1,mdCB1,mdLbl2}, {C_CheckBox,mdCB3,1,"Test C",NoList,CA_None,isSens,mdFrm1,0,mdCB1}, {C_Frame,mdFrmV1,0,"",NoList,CA_None,isSens,NoFrame,mdFrm1,mdLbl1}, {C_Label,mdLbl3,0,"Radios",NoList,CA_None,isSens,mdFrmV1,0,0}, {C_RadioButton,mdRB1,1,"KOB",NoList,CA_None, isSens,mdFrmV1,0,mdLbl3}, {C_RadioButton,mdRB2,0,"KOAT",NoList,CA_None, isSens,mdFrmV1,0,mdRB1}, {C_Button,mdBtnChange,0,change_me,NoList,CA_None, isSens,NoFrame,0,mdFrmV1}, {C_Button,M_Cancel,M_Cancel," Cancel ",NoList,CA_None, isSens,NoFrame,mdBtnChange,mdFrmV1}, {C_Button,M_OK,M_OK," OK ",NoList,CA_DefaultButton, isSens,NoFrame,M_Cancel,mdFrmV1}, {C_EndOfList,0,0,0,0,CA_None,0,0,0} }; //==========================>>> tDialog::tDialog <<<====================== tDialog::tDialog(vBaseWindow* bw) : vDialog(bw) { // The constructor for a derived dialog calls the superclass // constructor, and then adds the command objects to the dialog // by calling AddDialogCmds. UserDebug(Constructor,"tDialog::tDialog()\n") AddDialogCmds(DefaultCmds); // add the command objects } //=========================>>> tDialog::~tDialog <<<====================== tDialog::~tDialog() { // Destructor often doesn't need to do anything UserDebug(Destructor,"tDialog::~tDialog() destructor\n") } //====================>>> tDialog::DialogCommand <<<====================== void tDialog::DialogCommand(ItemVal id, ItemVal retval, CmdType ctype) { // After the user has selected a command from the dialog, // this routine is called with the value. vNoticeDialog note(this); // an instance we can use UserDebug1(CmdEvents,"tDialog::DialogCommand(id:%d)\n",id) switch (id) // We will do some things depending on value { case mdCB1: // CheckBox note.Notice("Test A"); break; case mdCB2: // CheckBox note.Notice("Test B"); break; case mdCB3: // CheckBox note.Notice("Test C"); break; case mdRB1: // Radio Button note.Notice("KOB"); break; case mdRB2: // Radio Button note.Notice("KOAT"); break; case mdBtn1: // Button note.Notice("Button 1"); break; case mdBtn2: // Button note.Notice("Button 2"); break; case mdBtnChange: // Example: change my own label // We will change the label on this button change_me[10]++; // change the "A" SetString(mdBtnChange, change_me); break; } // All commands should also route through the parent handler // which has useful default behaviors for Cancel and OK vDialog::DialogCommand(id,retval,ctype); } tdialog.h //======================================================================== // // tdialog.h - Header file for tutorial tDialog class // // Copyright 1995, Bruce E. Wampler, All Rights Reserved //======================================================================== #ifndef TDIALOG_H #define TDIALOG_H #include <v/vdialog.h> // we derive from vDialog class tDialog : public vDialog { public: //---------------------------------------- public tDialog(vBaseWindow*); virtual ~tDialog(); // Destructor virtual void DialogCommand(ItemVal id, ItemVal retval, CmdType ctype); protected: //------------------------------------- protected private: //--------------------------------------- private int _toggleId; }; #endif ==A.5 A Modal Dialog== tmodal.cpp <PRE> //======================================================================== // tmodal.cpp - Source file for tutorial tModalDialog class // // Copyright 1995, Bruce E. Wampler, All Rights Reserved //======================================================================== // #include "tmodal.h" // our header file #include <v/vnotice.h> const ItemVal mmLbl1 = 300; const ItemVal mmBtn1 = 301; const ItemVal mmBtn2 = 302; static DefaultCmds[] = { {C_Label, mmLbl1, 0,"X",NoList,CA_MainMsg,isSens,NoFrame, 0, 0}, {C_Button,mmBtn1,mmBtn1," Test 1 ",NoList,CA_None, isSens,NoFrame,0,mmLbl1}, {C_Button,mmBtn2,mmBtn2," Test 2 ",NoList,CA_None, isSens,NoFrame, mmBtn1,mmLbl1}, {C_Button,M_Cancel,M_Cancel," Cancel ",NoList,CA_None, isSens,NoFrame, 0,mmBtn1}, {C_Button,M_OK,M_OK," OK ",NoList,CA_DefaultButton, isSens,NoFrame,M_Cancel,mmBtn1}, {C_EndOfList,0,0,0,0,CA_None,0,0,0} }; //======================>>> tModalDialog::tModalDialog <<<================ tModalDialog::tModalDialog(vBaseWindow* bw) : vModalDialog(bw) { UserDebug(Constructor,"tModalDialog::tModalDialog()\n") AddDialogCmds(DefaultCmds); // add the predefined commands } //=================>>> tModalDialog::~tModalDialog <<<==================== tModalDialog::~tModalDialog() { UserDebug(Destructor,"tModalDialog::~tModalDialog() destructor\n") } //===================>>> tModalDialog::DialogCommand <<<================== void tModalDialog::DialogCommand(ItemVal id,ItemVal retval,CmdType ctype) { // After the user has selected a command from the dialog, // this routine is called with the id and retval. vNoticeDialog note(this); UserDebug1(CmdEvents,"tModalDialog::DialogCommand(id:%d)\n",id) switch (id) // We will do some things depending on value { case mmBtn1: // Button 1 note.Notice(" Test 1 "); break; case mmBtn2: // Button 2 note.Notice(" Test 2 "); break; } // let default behavior handle Cancel and OK vModalDialog::DialogCommand(id,retval,ctype); }
tmodal.h
//======================================================== // tmodal.h - Header file for tModalDialog class // // Copyright 1995, Bruce E. Wampler, All Rights Reserved //======================================================== #ifndef TMODAL_H #define TMODAL_H #include <v/vmodald.h> // derived from vModalDialog class tModalDialog : public vModalDialog { public: //---------------------------------------- public tModalDialog(vBaseWindow*); virtual ~tModalDialog(); // Destructor virtual void DialogCommand(ItemVal id, ItemVal retval, CmdType ctype); protected: //--------------------------------------- protected private: //--------------------------------------- private }; #endif
A.6 The Makefile
makefile
# Sample GNU make makefile for V tutorial application CC = g++ # Note: Platform dependent for a Linux system HOME = /home/bruce X11INC = /usr/X11/include X11LIB = /usr/X11R6/lib Arch = intel LIBS = -lV -lXaw -lXmu -lXt -lXext -lX11 VPATH = ../include # Architecture dependent VLibDir = $(HOME)/v/lib/$(Arch) oDir = ../obj/$(Arch) LibDir = ../lib/$(Arch) Bin = ../bin/$(Arch) #-------------------------------------------------------------- # Typical flags for includes and libraries CFLAGS = -O -I$(X11INC) -I$(HOME) LFLAGS = -O -L$(X11LIB) -L$(VLibDir) EXOBJS = $(oDir)/tutapp.o \ $(oDir)/tdialog.o \ $(oDir)/tmodal.o \ $(oDir)/tcanvas.o \ $(oDir)/tcmdwin.o all: $(Bin)/tutapp $(Bin)/tutapp: $(EXOBJS) $(VLibDir)/libV.a $(CC) -o $@ $(LFLAGS) $(EXOBJS) $(LIBS) $(oDir)/tcanvas.o: tcanvas.cpp v_defs.h tcanvas.h $(CC) -c $(CFLAGS) -o $@ $< $(oDir)/tdialog.o: tdialog.cpp v_defs.h tdialog.h $(CC) -c $(CFLAGS) -o $@ $< $(oDir)/tmodal.o: tmodal.cpp v_defs.h tmodal.h $(CC) -c $(CFLAGS) -o $@ $< $(oDir)/tcmdwin.o: tcmdwin.cpp v_defs.h tcmdwin.h $(CC) -c $(CFLAGS) -o $@ $< $(oDir)/tutapp.o: tutapp.cpp v_defs.h tdialog.h tmodal.h \ tutapp.h tcmdwin.h $(CC) -c $(CFLAGS) -o $@ $<