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