The V C++ GUI Framework User Guide:Tutorial:Tutorial code

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.


 * 1) 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 // specialized tutApp::CloseAppWin.

UserDebug(Build,"tutApp::Exit\n");

vApp::Exit;      // easy default behaviour }

//======================>>> 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 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. //========================================================================


 * 1) ifndef TUTAPP_H               // Standard technique for avoiding
 * 2) define TUTAPP_H               // problems with multiple #includes


 * 1) ifdef vDEBUG
 * 2) include 
 * 3) endif


 * 1) include     // We are derived from vApp
 * 2) include  // Need for app info


 * 1) 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

}; 
 * 1) 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.


 * 1) include  // so we can use notice
 * 2) include    // to map keys
 * 3) include    // for utilities
 * 4) include  // for file select


 * 1) 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}, {"-",M_Line,notSens,notChk,noKeyLbl,noKey,noSub}, {"Debug",M_SetDebug,isSens,notChk,noKeyLbl,noKey,noSub}, {"-",M_Line,notSens,notChk,noKeyLbl,noKey,noSub}, {"Exit",M_Exit,isSens,notChk,noKeyLbl,noKey,noSub}, {NULL} };
 * 1) ifdef vDEBUG                  // Defines V debug code
 * 1) endif

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; }

case M_SetDebug: {           vDebugDialog debug(this);   // an instance of debug debug.SetDebug;          // dialog - let user set break; }
 * 1) ifdef vDEBUG                  // Include debugging like this
 * 1) 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


 * 1) ifndef TCMDWIN_H
 * 2) define TCMDWIN_H


 * 1) include  // So we can use vCmdWindow
 * 2) include    // For the menu pane
 * 3) include <v/vstatusp.h> // For the status pane
 * 4) include <v/vcmdpane.h> // command pane


 * 1) ifdef vDEBUG
 * 2) include <v/vdebug.h>
 * 3) endif


 * 1) include "tdialog.h"   // user defined: tDialog
 * 2) include "tmodal.h"    // user defined: tModalDialog
 * 3) 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; }; </PRE>
 * 1) 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.


 * 1) 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); } </PRE> tcanvas.h  //======================================================================== // tcanvas.h -- header file for tutorial canvas class // //     Copyright 1995, Bruce E. Wampler, All Rights Reserved. //========================================================================


 * 1) ifndef TCANVAS_H
 * 2) define TCANVAS_H


 * 1) 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 }; </PRE>
 * 1) 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
 * 1) include <v/vnotice.h>
 * 2) 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); } </PRE> tdialog.h  //======================================================================== // // tdialog.h - Header file for tutorial tDialog class // // Copyright 1995, Bruce E. Wampler, All Rights Reserved //========================================================================


 * 1) ifndef TDIALOG_H
 * 2) define TDIALOG_H


 * 1) 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; }; </PRE>
 * 1) endif

A.5 A Modal Dialog
tmodal.cpp  //======================================================================== // tmodal.cpp - Source file for tutorial tModalDialog class // // Copyright 1995, Bruce E. Wampler, All Rights Reserved //======================================================================== //
 * 1) include "tmodal.h"            // our header file
 * 2) 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); } </PRE> tmodal.h  //======================================================== // tmodal.h - Header file for tModalDialog class // // Copyright 1995, Bruce E. Wampler, All Rights Reserved //========================================================


 * 1) ifndef TMODAL_H
 * 2) define TMODAL_H


 * 1) 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

}; </PRE>
 * 1) endif

A.6 The Makefile
makefile  CC     =       g++
 * 1) Sample GNU make makefile for V tutorial application

HOME   =       /home/bruce X11INC =       /usr/X11/include X11LIB =       /usr/X11R6/lib Arch   =       intel LIBS   =       -lV -lXaw -lXmu -lXt -lXext -lX11 VPATH  =       ../include
 * 1) Note: Platform dependent for a Linux system

VLibDir =      $(HOME)/v/lib/$(Arch) oDir   =       ../obj/$(Arch) LibDir =       ../lib/$(Arch) Bin    =       ../bin/$(Arch)
 * 1) Architecture dependent

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
 * 1) Typical flags for includes and libraries
 * 1) Typical flags for includes and libraries

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 $@ $< </PRE>