IlvGraphic: The Graphic Objects Class
Views graphic objects inherit attributes from the abstract base class
IlvGraphic. This class allows a Views graphic object to draw itself at a given destination port, and, if desired, with a transformation of its coordinates determined by an associated object of the
IlvTransformer class.
IlvGraphic has member functions that allow you to set and change geometric dimensions. A handful of member functions are given to set and get user properties that can be associated with an object for application-specific purposes. The
IlvGraphic class does not actually implement these member functions. They are declared as virtual member functions, and are defined to do various operations in the classes that inherit
IlvGraphic attributes. Though the member functions to manipulate geometric shapes and graphic attributes are present, they do nothing.
Member Functions
IlvGraphic member functions can be presented in several groups:
Geometric properties These member functions handle location, size, and drawing properties, which include the
draw method used to draw the graphic object. The virtual
draw method should be defined conjointly with the method
boundingBox, which defines the smallest rectangle that entirely contains all the area covered by the graphic object.
Graphic properties Use these member functions to change the visible aspect of the objects, that is, their color or pattern. You do so by means of member functions that indicate graphic properties of graphic objects and modify the palette bound to these graphic objects. The following example shows how to set the background of any graphic object:
IlvButton* mybutton = new IlvButton(display, IlvPoint(20,20), "Quit"); IlvColor* color = display->getColor("gold"); if (color) mybutton->setBackground(color); |
User properties IlvGraphic objects can be associated with a set of source code user properties. User properties are a set of
key-value pairs, where the key is an object and the value may be any kind of information value. User properties are not persistent.
These member functions provide you with a simple way to connect your graphic objects with information that comes from your application. You can keep track of the graphic part of your application by storing the pointers to objects you create, and connect the graphic side to the application by means of user properties, for example:
IlInt index = 10; IlSymbol* key = IlGetSymbol("objectIndex"); mybutton->addProperty(key, (IlAny)index); |
Some member functions provide tag management. Tags are markers that you can apply to graphic objects to identify them. You can then use various Views functions to manipulate only the tagged objects.
Gadget properties Gadget properties handle the sensitivity of objects to events, the callbacks to be called when the object is activated, the client data stored with objects, and the object interactor associated with the object class. For details on using callbacks, see the section
Callbackspage 45.
Focus chain properties The
focus indicates the object on the screen that is receiving any keyboard events. The
focus chain is the order of the objects on the screen that receive the focus. The focus moves to the next object in the focus chain when, typically, the Tab key is pressed, or to the previous object when shift-Tab is pressed.
Class information Subtypes of the class
IlvGraphic can handle information at the class level. This means that all instances of a given class can share the same information. For example,
IlvGraphic::className allows you to get the class name and
IlvGraphic::isSubtypeOf returns
IlTrue if the target
IlvGraphic object is a subclass of the given class argument. This example shows how to use class information member functions:
IlvButton* button = new IlvButton(display, IlvPoint(10,10), "sample"); // Get the IlvClassInfo object associated with the button class. IlvClassInfo* classInfo = button->getClassInfo(); // Get the name of the IlvGraphic class and print it: "IlvButton" const char* name = classInfo->getClassName(); IlvPrint(name); // Get the name of the super class and print it: "IlvMessageLabel" name = classInfo->getSuperClass()->getClassName(); IlvPrint(name); IlBoolean isSubtype = classInfo->isSubtypeOf(IlvSimpleGraphic::ClassInfo()); name = isSubtype ? "It's a subtype" : "error"; IlvPrint(name); |
Class properties Static member functions and their non-static equivalents let you handle properties at the class level, that is, these properties are defined for every instance of the class. In some methods, the
IlBoolean parameter allows you to operate iteratively on each superclass of the object until a match is found. Here are the member functions that deal with class properties:
void AddProperty(const IlSymbol* key, IlAny value); void RemoveProperty(const IlSymbol* key); void ReplaceProperty(const IlSymbol* key, IlAny value); void GetProperty(const IlSymbol* key, IlBoolean checkSuperClass = IlFalse); const IlvClassInfo* HasProperty(const IlSymbol* key, IlBoolean checkSuperClass = IlFalse); void addClassProperty(const IlSymbol* key, IlAny value); IlBoolean removeClassProperty(const IlSymbol* key); IlBoolean replaceClassProperty(const IlSymbol* key, IlAny value); IlAny getClassProperty(const IlSymbol* key, IlBoolean checkSupCl = IlFalse) const; const IlvClassInfo* hasClassProperty(const IlSymbol* key, IlBoolean checkSupCl = IlFalse) const; |
Here is an example that shows how to use class properties:
Let us imagine a map where graphic instances are shown with toggle-like sensitive behavior (Views provides specific objects called interactors that allow you to associate a behavior with graphic objects). Sometimes we may want these elements to be insensitive. Instead of scanning the object list to set the sensitivity to IlFalse, we use a class-level property in this way:
// Add the class-level property myClass* obj = new myClass(display); obj->addClassProperty(IlGetSymbol("sensitive"), (IlAny)IlTrue); |
In the applicative code, the application tests whether sensitivity must be inverted. There is another way to add a property to a class object, using a static member function, since both statements are equivalent:
if (anyValue == IlTrue) { myClass::AddProperty(IlGetSymbol("sensitive"), (IlAny)IlFalse); } |
In the implementation file of the
myInteractor class, we redefine the parent class method
IlvInteractor::handleEvent to add our specific behavior, that is freezing the sensitivity when a certain condition is present:
IlBoolean myInteractor::handleEvent(IlvGraphic* object, IlvEvent& event, IlvContainer* cont, IlvTransformer* transf) { // gets the sensitivity state IlSymbol* symbol = IlGetSymbol("sensitive"); if (object->hasClassProperty(symbol)) { if (!object->getClassProperty(symbol)) return IlFalse; } return IlvViewToggleInteractor::handleEvent(object, event, cont, transf); } |
Input/Output properties These member functions let you read and write your object descriptions from and to special kinds of streams, known as
IlvInputFile and
IlvOutputFile, which handle the reading and writing of objects from C++ streams.
Views offers a basic implementation of these classes, which were designed so that you can easily add your specific information. Therefore, when you need to save and load application-dependent data, you should create your own subtypes of these two classes.
Writing Graphic Objects The
IlvOutputFile class writes the complete description of a series of objects in an output stream. You can use this class in the following way:
// Open a file output stream fstream outstream("image.ilv", ios::out | ios::trunc); // Initialize the number of objects and their array of pointers const IlvUInt n = 10; IlvGraphic* outObjects[n]; for (IlvUInt i=0; i<n; i++) outObjects[i] = new IlvRectangle(display, IlvRect(0, 0, 200, 100)); // Create the IlvOutputFile IlvOutputFile outfile(outstream); // Write the objects and get in outTotalCount the number // of objects actually stored IlvUInt outTotalCount = 0; outfile.saveObjects(n, outObjects, outTotalCount); |
Reading Graphic Objects The
IlvInputFile class is the main class for reading objects from a stream. The following code shows how to read
IlvGraphic objects from an input stream:
// Open a file input stream fstream instream("image.ilv", ios::in); // Create the IlvInputFile IlvInputFile infile(instream); // Get the number of created objects and their array of pointers IlUInt InTotalCount = 0; IlvGraphic* const* inObjects = infile.readObjects(display, InTotalCount); |
Published date: 05/24/2022
Last modified date: 02/24/2022