Output of file : VOBJECT.HPP contained in archive : DOSUIT07.ZIP

// Basic user interface drawable object.
#ifndef RECT_HPP
#include "rect.hpp"
#include "protect.hpp"

class MouseEvent;
class KeyboardEvent;
class InterruptEvent;
class CriticalErrorEvent;
class Window;

// Indicates the state and default appearance of a VObject.
enum StateFlag {
SFalloff = 0, // No flags set.
SFnormal = 0, // Draw in normal colour.
SFdisabled = BIT(0), // Disabled.
SFfocus = BIT(1), // Focus (if SFshowfocus).
SFnormonly = (SFdisabled|SFfocus),// Colour without highlighting.
SFhighlight = BIT(2), // Highlighted.
SFcolor = (SFnormonly|SFhighlight),// Colour index into a ColorSet.
SFshowfocus = BIT(3), // Change color if in focus.
SFselected = BIT(4), // Selected or pressed.
SFactfocus = BIT(5), // This gets unwanted keyboard input.
SFtabstop = BIT(6), // Tab key will move focus to this.
SFmousein = BIT(7), // Mouse pointer inside this VObject.
SFmouseflags = SFmousein // All mouse flags combined, for testing.

A structure containing the eight colors used to render a particular
Window. The color used for any individual VObject are determined
from the lowest 3 bits of its StateFlag (hence 8 colors). The 3 bits
in question represent disabled, focussed, and highlighted. Each
Window can have its own ColorSet. The library provides three sets -
normal windows (defaultColors), alert boxes (alertColors), and help
screens (helpColors), which automatically take account of current
screen mode (mono or color).
struct ColorSet {
color colors[8]; // Index using StateFlag & SFcolor.

This enum is used to indicate the internal state of a VObject. It is
not normally manipulated by user programs.
enum ControlFlag {
CFNone = 0, // No bits set.
CFfocus= BIT(0), // Keyboard focus on this VObject.
CFsize = BIT(1), // Change in size of object.
CFposition = BIT(2), // Object moved.
CFdirty = BIT(3), // Needs updating.
CFcontentsdirty = BIT(4), // Contents need updating.
CFpartdirty = BIT(5), // DirtyArea is valid.
CFclean = (CFsize|CFposition|CFdirty|CFcontentsdirty|CFpartdirty),
// Bits to reset when object has been painted.
CFupdate = (CFdirty|CFcontentsdirty|CFpartdirty),
// Bits to test if the object needs repainting.
CFactive = BIT(6) // Interested in events.

This enum is used to specify how objects are laid out within a
Cluster, and how to lay out objects on the screen.
enum AlignFlag {
// Horizontal alignment
AFHcenter = 0, // Centre in rectangle.
AFHleft = BIT(0), // Align to left of rectangle.
AFHright = BIT(1), // Align to right of rectangle.
AFHexpand = AFHleft|AFHright, // Expand to fit rectangle.
AFHoriz = (BIT(0)|BIT(1)), // Horizontal alignment.

// Vertical alignment
AFVcenter = 0, // Centre in rectangle.
AFVtop = BIT(2), // Align to top of rectangle.
AFVbottom = BIT(3), // Align to bottom of rectangle.
AFVexpand = AFVtop|AFVbottom, // Expand to fit rectangle.
AFVert = (BIT(2)|BIT(3)), // Vertical alignment.

// Often-used combinations
AFexpand = (AFHexpand|AFVexpand),
AFcenter = (AFHcenter|AFVcenter),

// Other flags
AFtabstop = BIT(6) // Set SFtabstop.

This enum is used to indicate the type of border on (for example)
Windows, Boxes, Clusters and Dialogs.
enum BorderFlag {
BFnone = BTnone, // No border.
BFsingle = BTsingle, // Single box border.
BFdouble = BTdouble, // Double box border.
BFbold = BTbold, // Bold box border.
BFstyle = 0x0f, // Mask the above only.
BFshowactive = BIT(4), // Double box if actfocus.
BFtitle = BIT(5), // Place title (name) in top border.
BFtabstop = BIT(6), // Set SFtabstop.
BFleft = BIT(7), // Left align title in box.
BFright = BIT(8), // Right align title in box.
BFalignment = BFleft | BFright // Mask the alignment only.

This is the base class for all objects that appear on the screen. It
has many virtual methods which may be overridden in subclasses to
determine their behaviour.
class VObject : public Rectangle, public NamedProtected
friend class Application;
VObject(const Rectangle &r,const char *n = "VObject");
// A protected constructor for derived classes that have already
// calculated their size and position.

VObject(const char *n = "VObject");
VObject(const coord l,const coord t,const coord r,const coord b,const char *n = "VObject");
VObject(const coord w,const coord h,const char *n = "VObject");
virtual ~VObject();
// The destructor is virtual, so any subclass destructor will always be
// called correctly.

//~ State Flag manipulation
StateFlag testFlag(StateFlag f) const { return StateFlag (sflags & f); }
void disable() { setFlag(SFdisabled); dirty(); }
// This disables selection of this VObject. It also helps determine
// color the VObject is painted.
void enable() { clearFlag(SFdisabled); dirty(); }
void highlight() { setFlag(SFhighlight); dirty(); }
// The highlight flag usually determines what color the VObject is
// painted.
void unhighlight() { clearFlag(SFhighlight); dirty(); }

//~ Control Flag manipulation
ControlFlag testcFlag(ControlFlag f) const { return ControlFlag (cflags & f); }
void ignoreEvents() { clearcFlag(CFactive); }
// This will stop the VObject receiving Events.
void recogniseEvents() { setcFlag(CFactive); }
void dirty() { setcFlag(CFdirty); }
// This is called whenever something happens which means the whole
// VObject needs to be repainted - e.g. after highlighting it.
void dirty(const Rectangle &r);
// This is called when some part of the VObject needs to be redrawn -
// e.g. after an obscuring Window is removed. Methods called by objects
// inside this one if their Control flags has changed.
void clean() { clearcFlag(CFclean); }
// This is called whenever the VObject has been freshly painted on the
// screen.

//~Notification methods
// Methods called by objects inside this one if their flags have changed -
// f is the flags that have CHANGED.
virtual void contentsSet(VObject* o,ControlFlag f);
virtual void contentsCleared(VObject* o,ControlFlag f);

virtual void contentsDeleted(VObject* v);
// Method called by objects inside this one if they are deleted.

//~Color methods
// Get color index - these are indices into the ColorSet of the Window
// used for the colors of this VObject when drawing it.
int getcolor() const { return testFlag(SFcolor); }
// Get color index.
int getnormal() const { return testFlag(SFnormonly); }
// Get color ignoring highlight attribute.
int gethighlight() const { return testFlag(SFcolor)|SFhighlight; }
// Get color with highlight attribute.

//~Setting container & window
void setcontainer(VObject *v) { container = v; }
VObject *getcontainer() { return container; }
virtual void setwindow(Window *w);
Window *getwindow() const { return window; }

//~Moving or resizing the VObject
virtual void move(coord x,coord y);
// This is the main move method, and is the only one which
// needs to be overridden in subclasses, as all the others call it.
void position(coord x,coord y) { move(x - left(),y - top()); }
void position(const Point &p) { position(p.x,p.y); }
void move(const Point& p) { move(p.x,p.y); }
virtual void setwidth(const coord w);
virtual void setheight(const coord h);
void setsize(coord x,coord y) { setwidth(x); setheight(y); }
void setsize(const Point &p) { setsize(p.x,p.y); }
void placeInside(const Rectangle& r);
// Place the VObject inside the Rectangle. First, if the VObject is too
// large to fit, is is reduced in size. Then it is moved the minimum
// distance to ensure it is wholly contained in the Rectangle.

virtual void align(AlignFlag a,const Rectangle& r);
// The VObject is lined up inside the Rectangle according to the AlignFlag.

//~Drawing the VObject
virtual void paint(Rectangle r);
// This is the method called to display the VObject in its Window. This
// method will be overridden in all VObjects which will actually show
// on the screen. The Rectangle is a clipping area - you need not paint
// any part of the VObject outside this area, as either the area is not
// visible on the screen, or it is already shown correctly. If you do
// paint outside this area, the Window will take care of any clipping
// which needs to be done to prevent your output "bleeding" through an
// overlapping Window.

void draw() { paint(*this); clean(); }
// Force the whole object to be drawn.

virtual void update();
// Draw any parts of Object which are dirty.

//~Determine size.
// These methods return the minimum size required to display the
// VObject. They are used by Clusters to lay out objects in Windows.
virtual coord minwidth() const;
virtual coord minheight() const;

// These methods return the "ideal" size required to display the
// VObject. The default is to return the same value as the "min"
// methods, but subclasses sometimes override this default - e.g. a DOS
// directory entry might have a minimum length just large enough to
// display the file name, and a maximum width long enough to display
// the file size and date, as well.
virtual coord maxwidth() const;
virtual coord maxheight() const;

//~Set & reset keyboard focus
virtual int setfocus(int tabstop = 1);
// Return 1 if this VObject will accept focus, 0 otherwise. If tabstop
// is zero, the VObject should only accept focus if it is not a tabstop
// - i.e. !testFlag(SFtabstop). It is normal for derived classes that
// wish to override this method to call the base class method, so that
// the correct flags etc. are set.
virtual void resetfocus();
// Called whenever the VObject loses focus. Again, it is normal for
// derived objects to call the base class method so that the correct
// flags are set.
virtual void clearfocus(VObject *v = 0);
// A special method called when a whole nest of VObjects must lose the
// focus - e.g. an Option in a Menu in a MeneButton in a MenuBar.
// Calling clearfocus for the Option will also clear the focus from the
// containers. The container calls will have v set to the contained
// VObject each time.

//~Increment and decrement keyboard focus
virtual int incfocus(int tabstop = 1,int decrement = 0);
// A virtual method for VObjects which contain other VObjects. Moves
// the focus to the next contained VObject which will accept it. The
// tabstop parameter is passed on to setfocus for the contained
// VObjects. The basic VObject always returns 0, as it doesn't have any
// contents.
int decfocus(int tabstop = 1) { return incfocus(tabstop,1); }
virtual int nextTabstop(int decrement = 0,int wrap = 0);
// Move the focus to the next tabstopped item. The basic VObject
// accepts the focus if it is a tabstop, and it hasn't got the focus
// already. A Group will pass the focus on to the next tabstop inside
// it. If the last tabstop already has focus, the Group will wrap round
// to the first, or return zero, depending of the value of wrap.

//~Set & reset mouse focus and repeat
void setmoufocus(int repeat = 0);
// Grab mouse focus. While a VObject has the mouse focus, it gets all
// MouseEvents. If repeat is non- zero, the VObject will receive
// repeated mouse movement events, even when the user does not move the
// mouse. This is useful e.g. for continuous scrolling while a mouse
// button is down in a list.
void resetmoufocus();

//~Determine the topmost (smallest) object containing a point
virtual VObject *containingObject(const Point &p);
// This is used by the MouseEvent despatch method to determine which
// VObject the mouse is over. If the current VObject does not contain
// the Point, it returns 0. If it does contain the Point, it determines
// if any VObject inside this one also contains the Point, and returns
// that VObject or itself.

//~Distribute an event among the following functions
virtual int handle(MouseEvent& e);
// This method takes a MouseEvent and farms it out to the different
// methods below. It is not often overridden, except to monitor all
// mouse events and pass them on to the base class handle method.

//~Virtual functions called for each type of event.
// It should only be necessary to override some of these to deal
// with those types of event in which a derived class is interested.
// If a VObject is not interested in a particular Event, the method
// should pass it on to the base class method. If it is interested, it
// should process the Event, and return 1. This will prevent the Event
// being passed on to containing VObjects. The default VObject version
// of most methods returns 0 (not interested).
virtual int mousemove(MouseEvent& e);
// All movement events.
virtual int mouseenter(MouseEvent& e);
// Called whenever the mouse enters the VObject's bounding rectangle.
virtual int mouseexit(MouseEvent& e);
// Called whenever the mouse leaves the VObject's bounding rectangle.

virtual int leftdown(MouseEvent& e);
virtual int middledown(MouseEvent& e);
virtual int rightdown(MouseEvent& e);

virtual int leftup(MouseEvent& e);
virtual int middleup(MouseEvent& e);
virtual int rightup(MouseEvent& e);

// Click methods are called when the mouse is clicked without moving,
// AFTER down and up messages have been processed
virtual int leftclick(MouseEvent& e);
virtual int middleclick(MouseEvent& e);
virtual int rightclick(MouseEvent& e);

// Doubleclick messages are called after all up and down messages
// and click messages have been processed
virtual int leftdoubleclick(MouseEvent& e);
virtual int middledoubleclick(MouseEvent& e);
virtual int rightdoubleclick(MouseEvent& e);

virtual int inspectclick(MouseEvent& e);
// If inspecting is on (library compiled without NINSPECT defined),
// this method will be called when the user does a left click while
// holding down the Alt key. The VObject will pop an Inspector up on
// the screen, showing the internal details of the VObject.

virtual int kbdevent(KeyboardEvent& e);
// KeyboardEvents are only received while the VObject has the focus.
virtual int dohotkey(KeyboardEvent& e);
// If the focus VObject and its containers are not interested in a
// KeyboardEvent the despatcher tries all the dohotkey methods.
virtual int interruptevent(InterruptEvent& e);
// Called when the user presses Ctrl-Break.
virtual int criterr(CriticalErrorEvent& e);
// Called when a DOS critical error has occurred, and a
// CriticalErrorHandler exists.

virtual int help();
// Try to display help for this object. The base VObject class passes
// its name to the Application help handler. This is usually sufficient
// for most things.

//~Inspection and debugging
virtual char *inspectinfo(char *buffer = 0,const char *s = 0) const;
// Get a textual description of what this object looks like inside, for
// the Inspector.

static FILE *debug;
// If debug tracing is enabled (library compiled without NDEBUG
// defined), you can set VObject::debug to a C FILE opened with fopen.
// Copious tracing information will be written to the file. Remember to
// set VObject::debug to zero if you close the file !
virtual char *debuginfo(char *buffer = 0) const;
// The trace function obtains its description of the VObject being
// traced by calling debuginfo. You may override this method to provide
// your own description (showing extra internal information) if you
// wish. The method uses an existing string buffer, or allocates a new
// one if buffer is zero. It returns the buffer used (or allocated).
// This makes it easy to add information to the base class information -
// call the base class debuginfo and strcat the extra information on
// the end.
static char debugbuf[2048]/*!*/;
virtual void dump(FILE *f) const;

VObject *container;
Window *window;
Rectangle dirtyArea;
// The area to be painted on next draw if only part of the VObject is
// dirty. This only contains valid information if
// testcFlag(CFpartdirty) is non-zero.
void moveDirtyArea(coord x,coord y);
// Move dirty area during scroll. This method is called when the
// VObject is scrolled, so that the dirty area is moved along with the
// scrolled information.

//~State Flag manipulation
void setFlag(StateFlag f) { sflags = StateFlag (sflags | f); }
void clearFlag(StateFlag f) { sflags = StateFlag (sflags & ~f); }
void toggleFlag(StateFlag f) { sflags = StateFlag (sflags ^ f); }

//~Control Flag manipulation
// These methods will pass flag information up through containing
// VObjects via the contentsSet and contentsCleared methods.
void setcFlag(ControlFlag f);
void clearcFlag(ControlFlag f);

//~Change name
void newname(const char *name) { namestring = name; }

StateFlag sflags;
ControlFlag cflags;

void build(); // set up default colors & flags.
friend class Window;

A VObject which will accept the keyboard focus. This is used as the
base class of all interactive objects, such as Buttons and TextEdits.
class Control : public VObject {
Control(const Rectangle &r,const char *n = "Control");

Control(const char *n = "Control");
Control(const coord l,const coord t,const coord r,const coord b,const char *n = "Control");
Control(const coord w,const coord h,const char *n = "Control");

Useful function for printing the values of bit flags.
Letters should have 1 char for each bit, BIT(0) first.
extern const char *transbits(unsigned int flags,const char *letters);

extern const VObject *EndList/*!*/;