/* Emacs, this is -*- C++ -*- */
#ifndef _PAGEOBJECT_H_
#define _PAGEOBJECT_H_
#include <qobject.h>
#include <qwidget.h>
#include <qrect.h>
#include <qpainter.h>
#include <qfile.h>
class Page;
class TreeItem;
/** Something that can be on a page.
A PageObject is an object (a QObject, to be precise) that is
on a page. (Thus the name.) Examples for a PageObject are Plots
or (yet to be implemented) Arrows and Texts.
The PageObject class defines the interface of all objects that
can be on a page, plus it defines some common properties, e.g.
the area an object covers on the page.
@see #Page where PageObject´s are on.
@see #Plot an example for a PageObject.
@author Patrick Schemitz
*/
class PageObject : public QObject
{
Q_OBJECT
public:
/** Construct a page object.
Set all values to zero.
*/
PageObject ();
/** Destruct the page object.
This deletes the tree item.
*/
~PageObject ();
/** The PageObject´s QObject.
Usually, this will just return a "this" pointer, and this
is the default implementation. This is unlikely to change.
*/
virtual QObject* object () { return this; }
/** The PageObject´s QWidget.
Every PageObject must have a QWidget in order to paint itself.
However, not every PageObject *is* a QWidget. A Plot, for
example, can *not* be a QWidget, because QWidgets cannot be
constructed before the QApplication has started. But the Plot
prototypes are constructed when they register themself to the
Plots() list, before main(). Thus, I´ve separated the object
from the widget. See the Plot implementation for the details.
PageObjects that *are* QWidgets may of course return "this"
as in object().
@see #Plot why widget() and object() are separated.
*/
virtual QWidget* widget () = 0;
/** Paint yourself on a QPainter.
Every PageObject must be able to paint itself on a given
QPainter. This may be the page window as well as a printer.
*/
virtual void paint (QPainter*) = 0;
/** A mouse press event in the PageObject.
When a mouse button is pressed in a page, the page checks
if there is a PageObject at the click position, and if there
is, passes on the QMouseEvent (after a transformation to
the widget´s coordiates).
*/
virtual void mousePressEvent (QMouseEvent*) = 0;
/** Tree entry for the PageObject.
Since PageObjects show up in the tree list, they must
provide a TreeItem entry.
When first invoked, the default implementation creates a
TreeItem and sets the pixmap to icon() and the text to
description(). This tree item is then returned. When you
don´t like this, you can redefine treeitem() or you can
change the tree item in your constructor:
treeitem()->setPixmap(myPixmap);
treeitem()->setText("Hello World");
*/
virtual TreeItem* treeitem ();
/** Called when the PageObject is about to become "active".
Some PageObjects, like Plots, have an activePlot pointer
which points to the "active" Plot. This is used to update
the main menu "Plot" entry.
The default implementation of this function just does nothing.
If your PageObject subclass has something like an activePlot,
you will have to reimplement it. If it doesn´t, just leave
this implementation.
@see #deactivate() the antagonist.
*/
virtual void activate () {}
/** Called when the PageObject is about to become "inactive".
See activate() for detailed description.
@see #activate() the agonist.
*/
virtual void deactivate () {}
/** Icon for the PageObject.
Every PageObject must provide one or two icon(s).
Depending on the type of the PageObject, you might
want separate icons for the active object and for the
inactive objects (Plots for example).
@see #changedTreeItem()
*/
virtual QPixmap* icon () = 0;
/** Gives a short description of the PageObject.
Every PageObject must provide a short description of
itself.
*/
virtual const char* description () = 0;
/** Store the PageObject to an already open QFile.
Every PageObject must be able to store itself to a file,
as well as to restore itself from a QFile.
The rules for storing/restoring are the following:
Your PageObject reads from the already opened QFile
until it hits a selfdefined end mark. You must make
sure that the complete entry of your PageObject is read,
since the QFile might contain multiple objects. When
you store a PageObject, you must make sure that you set
a unique end mark that your restore() function recognizes.
When Korigin writes objects to a file, it first writes the
class name, className(), to the file and then invokes the
class´s store() function. Then it writes the next object´s
className(), then invokes store() etc. Now when it comes to
read a file, Korigin reads the first line, interprets it as
the class name, instantiates the corresponding class and lets
the new instance restore() itself from the file. Then it reads
the next line and again interprets it as a class name...
You see, if your restore() function stops reading at the right
place, everything gets messed up. So be careful!
@see #restore()
*/
virtual bool store (QFile&);
/** Store the PageObject to an already open QFile.
Every PageObject must be able to store itself to a file,
as well as to restore itself from a QFile.
See @ref store for a detailed description of store/restore
mechanism.
@see #store()
*/
virtual bool restore (QFile&);
/** Returns the page the plot is on.
This is already implemented for you.
@see #setPage()
*/
Page* page () { return the_page; }
/** Set the page the plot is on.
This is already implemented for you.
@see #page()
*/
void setPage (Page* p) { the_page = p; }
/** Get the PageObject´s position on the page.
This is already implemented for you.
@see #setPosition()
*/
void position (float& x, float& y) { x=the_x_pos, y=the_y_pos; }
/** Set the PageObject´s position on the page.
This is already implemented for you.
@see #position()
*/
void setPosition (float x, float y) { the_x_pos=x, the_y_pos=y; }
/** Return the rectangle the PageObject occupies, in screen pixels.
This returns the area of the PageObject in real, screen pixels,
relative to the Page widget. This is needed when checking whether
a mouse click was in a PageObject or not. (Mouse positions are
in screen pixels, of course.) The physical area depends on the
size of the Page window.
There is also a virtual page resolution, independent of the Page
window size.
@see #virtual_area()
*/
QRect pixel_area ();
/** Return the rectangle the PageObject occupies, in virtual units.
These virtual units do not depend on the size of the Page window,
as the physical area, pixel_area(), does. The virtual size is
determinated by the page´s paper size (A4, Legal etc.), and the
assumed printer resolution. (Currently fixed to 300 dpi.)
@see #pixel_area()
*/
QRect virtual_area ();
signals:
/** Emitted when the page object changed its tree item.
For instance, when the icon is toggled from active to
inactive or vice versa. It is your concrete PageObject
subclass which must emit this signal.
This signal is connected to the tree view via the
PageObject´s page.
*/
void changedTreeItem ();
protected:
/** The PageObject´s tree item.
Usually, you won´t have to touch this directly. Specifically,
you shouldn´t delete it!
*/
TreeItem* the_treeitem;
private:
/// The PageObject´s page.
Page* the_page;
/// X position of the PageObject on it´s page.
float the_x_pos;
/// Y position of the PageObject on it´s page.
float the_y_pos;
};
#endif
Documentation generated by mh@jeff_clever on Thu Feb 5 14:15:25 MET 1998