home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fresh Fish 5
/
FreshFish_July-August1994.bin
/
bbs
/
gnu
/
aplusplus-1.01-src.lha
/
src
/
amiga
/
aplusplus-1.01
/
include
/
aplusplus
/
intuition
/
IntuiObject.h
< prev
next >
Wrap
C/C++ Source or Header
|
1994-05-09
|
10KB
|
251 lines
#ifndef APP_IntuiObject_H
#define APP_IntuiObject_H
/******************************************************************************
**
** C++ Class Library for the Amiga© system software.
**
** Copyright (C) 1994 by Armin Vogt ** EMail: armin@uni-paderborn.de
** All Rights Reserved.
**
** $VER: apphome:APlusPlus/intuition/IntuiObject.h 1.04 (04.05.94) $
**
******************************************************************************/
extern "C" {
#include <intuition/intuition.h>
#include <utility/tagitem.h>
}
#include <APlusPlus/environment/APPObject.h>
#include <APlusPlus/environment/MapArray.h>
#include <APlusPlus/exec/List.h>
#include <APlusPlus/intuition/ITransponder.h>
#include <APlusPlus/utility/AttrList.h>
/******************************************************************************************
« IntuiObject class » virtual base class
base class for all graphical user interface classes. This class provides a mechanism
to trace dependecies between the objects in an Intuition-based user interface.
All IntuiObjects have one owner that is to be supplied with the constructor call and
can have a list of dependent IntuiObjects themselves. That makes it easy to track all
IntuiObjects within one application. So, only the base object has to be deleted to
cause the deletion of its dependent objects.
Furthermore, the position of an object within the dependency tree has an effect on
some IntuiObject-derived objects (e.g. positioning within a window).
For further details look at the description of the GraphicObject class.
The implementation builds the dependency tree from MinListC lists: every object
has its double-linked list of dependent objects.
IntuiObject derived classes will get their specifications via an Attribute Tag list
which is defined in the AttrList class.
IntuiObjects can be declared to get the actual value for an attribute from an actual
value of one attribute of another IntuiObject. This dependency can be declared by
usage of setAttributes() or in the constructor's attribute list:
objA = new GT_Scroller(...,AttrList(...,GTSC_Top,1,...),...);
objB = new BoopsiGadget(...,AttrList(..,CONSTRAINT(PGA_Top,objA,GTSC_Top),...));
objA's "GTSC_Top" initialises obj's "PGA_Top"
******************************************************************************************/
class IOBrowser;
class IntuiRoot;
class IntuiObject : public MinNodeC, private APPObject, public MinListC
{
friend IntuiRoot;
friend IOBrowser;
friend ostream& operator << (ostream& OS,IntuiObject *iob);
private:
APTR iObject; // address of the shadowed Intuition object
ITransponder *iTransponder; // notification interconnection
AttrList attrList; // Taglist with create attributes
BOOL setAttributesIsRecurrent; // helps determine if there is a loop in the ITransponder dependenies
MapArray cTable; // constraints table
LONG reserved1;
void processAttrs(AttrList& attrs);
LONG newConstraint(Tag onChangedTag,IntuiObject *notifyThis,Tag mapToTag);
// returns the actual value for the 'mapToTag' attribute of the 'notifyThis' IntuiObject
void releaseObject(IntuiObject *obj); // remove all notify dependencies to 'obj'
void changedAttrs(AttrList& attrs);
protected:
// The type of the Intuition object addressed in iObject is stored in APPObject
/** if no owner is given (owner == NULL) the object is attached to the base object.
** However, this might cause some classes not to work proper,
** (e.g. a gadget must have a window or something similar as its (maybe indirect) owner)
** others are most times only dependent of the base object (e.g. the window classes).
**/
IntuiObject(IntuiObject *,const AttrList&); // add to the owner's list
BOOL notificationLoop() { return setAttributesIsRecurrent; }
// check within setAttributes() for a notification loop
void setIOType(LONG type) { setID( ID() | type); }
// imprint the class id after successful initialisation within the constructor
APTR& IObject() { return iObject; }
AttrList &intuiAttrs() { return attrList; }
// access to the attribute taglist for the class implementor.
void setAttrs(AttrList& attrs) { IntuiObject::setAttributes(attrs); }
// alter attribute values including notification triggering
APPObject::setError;
// if the constructor fails an error code ought to be set instead of the class id
public:
virtual ~IntuiObject(); // remove from the owner's list
/** Note for the class implementor: YOU MUST CALL setAttributes() with the received taglist
** for your class' base class when you have sought information from the attributes.
** The attribute tags will be updated and notification will be triggered NOT BEFORE
** the taglist propagation arrives at IntuiObject::setAttributes().
** Your setAttributes() method MUST NOT alter the taglist if you want the attribute
** values to be applied.
** The notification system is capable of inhibiting 'setAttributes()' loops.
** Note that the loop is broken not before the setAttributes() call reaches the
** IntuiObject base class! To prevent derived classes from getting the recursive
** setAttributes() call each class' setAttributes() method must check with
** 'BOOL notificationLoop()' and return immediately on TRUE return value.
**/
virtual ULONG setAttributes(AttrList& );
// each IntuiObject may implement class specific action
virtual ULONG getAttribute(Tag tagValue,ULONG& tagData);
// accessing the attributes taglist for the class user.
APTR object() { return iObject; } // read only public version
IntuiObject *findOwner() { return (IntuiObject*)findList(); }
// find the owner of this object
IntuiObject *findRootOfKind(LONG basetype);
// get the first object upwards searching in the tree..
IntuiObject *findRootOfType(LONG type);
// ..that is kindOf() or isType() of the given ID.
ULONG getIOType() { return ID()&0x0000ffff; }
BOOL isKindOf(LONG basetype) { return ((ID()&basetype)==basetype); }
// (BOOL)(((LONG)ID()&bt)) is always 0 for bt>2^16-1 !!!
BOOL isKindOfIntuiObject() { return isKindOf(INTUIOBJECT_CLASS); }
// check unknown APPObjects
BOOL isType(LONG type) { return (ID()==(INTUIOBJECT_CLASS|type)); }
APPObject::Ok; // check for validity
APPObject::isClass; // compares with ID()
APPObject::error;
APPObject::status;
static IntuiObject *confirm(IntuiObject *iob) { return iob; }
};
class IOBrowser
{
private:
#define IOBSTACKSIZE 50
IntuiObject *stack[IOBSTACKSIZE];
int sp;
void push(IntuiObject *iob)
{ if (sp<IOBSTACKSIZE) stack[sp++] = iob; else cerr << "IOBrowser: stack overflow\n"; }
IntuiObject *pop()
{ return sp<=0?NULL:stack[--sp]; }
public:
IOBrowser(IntuiObject *start);
IntuiObject *getNext(LONG type);
};
ostream& operator << (ostream& OS,struct TagItem *taglist);
#define OWNER_NULL ((IntuiObject*)NULL)
#define OWNER_ROOT OWNER_NULL
/* Use for attaching IntuiObjects to the root. Note that this is incompatible with
most GraphicObjects which need a WindowCV object.
*/
#define IOB_Dummy (TAG_USER|0x10)
#define IOB_CnstSource (IOB_Dummy+1)
#define IOB_CnstTag (IOB_Dummy+2)
/* Some tags for constraint definition. Do not use these but instead use the define below.
*/
#define CONSTRAINT(tag,sourceObj,sourceTag) IOB_CnstSource,IntuiObject::confirm(sourceObj),IOB_CnstTag,sourceTag,tag,0
/* macro to define an attribute constraint between two IntuiObjects within an attribute tag list.
*/
#define IOB_ITransponder (IOB_Dummy+3)
/* Do not use this tag immediately.
*/
#define ITRANSPONDER(itp) IOB_ITransponder,ITransponder::confirm(itp)
/* macro to attach an ITransponder object to the IntuiObject.
*/
//------------- errors --------------