You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

581 lines
18 KiB

/***************************************************************************
qscobject.h
-------------------
begin : Sun Jan 9 2000
copyright : (C) 2000 by Kamil Dobkowski
email : kamildbk@friko.onet.pl
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef QSCOBJECT_H
#define QSCOBJECT_H
#include"qsdrv.h"
#include"qsserializable.h"
#include<qobject.h>
//-------------------------------------------------------------------------------------------------//
class QSCObject;
template<class CHILD_OBJECT> class QSChildList;
/**
* \brief List of QSCObject's
*
* Object collection- it holds a list of QSCObjects. QSCGroup and QSPage contains object collections.
* Selection in QSPlotView is also an object collection. See also: QSCObject
*/
class QSCObjectCollection : public QObject, public QSSerializable
{
Q_OBJECT
public:
/**
* Constructor. set 'autoDelete' to false if you dont want objects
* to be deleted when collection is deleted or when callig 'removeDelete'.
*/
QSCObjectCollection( QObject *parent=NULL, bool autoDelete=true );
/**
* Destructor. If autoDelete is true deletes all objects
*/
~QSCObjectCollection();
/**
* Blocks / Enables and sends sigListChanged and sigChanged
*/
void setAutoUpdates( bool enable );
/**
* Returns auto updates setting.
*/
bool autoUpdates() const { return m_auto_updates; }
/**
* Returns true if selection doesn't contain any object.
*/
bool isEmpty() const { return count() == 0; }
/**
* Number of objects in collection.
*/
int count() const;
/**
* Deletes ( if autoDelete is false - only removes ) all objects in collection.
*/
void clear();
/**
* Adds a new object to the collection.
*/
void add( QSCObject *newObject );
/**
* Insert object into the collection at the given position ( 0 - at the back, count() - at the front ).
*/
virtual void insert( int position, QSCObject *object );
/**
* Removes an object at the position 'index' from the collection
*/
virtual void remove( int index );
/**
* Removes an object at the position 'index' from the collection and deletes it ( if autoDelete is true ).
*/
void removeDelete( int index );
/**
* Raises an object at the position 'index'.
*/
void raise( int index );
/**
* Lowers an object at the position 'index'.
*/
void lower( int index );
/**
* Brings to front an object at the position 'index'.
*/
void toFront( int index );
/**
* Sends to back an object at the position 'index'.
*/
void toBack( int index );
/**
* Moves to position 'position' an object at the position 'index'.
*/
void reorder( int position, int index );
/**
* Returns the position of the object 'object'.
*/
int find( QSCObject *object ) const;
/**
* Returns object at the position 'index'
*/
QSCObject *object( int index ) const;
/**
* Paints skeletons of all objects.
*/
void paintSkeleton( QPainter *p, double dpi = 72.0 );
/**
* Paints all object. If 'blocking' is false painter is copied using QSDrvQt::copyPainter
* each object gets its own painter object, and paints itself in the background.
*/
void paint( QPainter *p, double dpi = 72.0, bool blocking=true, bool transparent=true );
/**
* Draws all object using the given driver. If blocking is false, driver is copied using
* QSDrv::copy() and each object gets its own driver object and draws itself in the background.
*/
void draw( QSDrv *drv, bool blocking=true, bool transparent=true );
/**
* Returns if there is a busy object in this group.
*/
bool busy() const;
/**
* Stops drawing.
*/
void stop();
/**
* Returns object at position 'p'.
*/
QSCObject *objectAt( const QSPt2f &p, QSDrv* drv, bool recursive=false );
/**
* Returns if selection contains given object
*/
bool contains( QSCObject *object, bool recursive=false );
/**
* Saves all objects
*/
virtual void loadStateFromStream( QDataStream& stream, QSObjectFactory *factory );
/**
* Loads all objects
*/
virtual void saveStateToStream( QDataStream& stream, QSObjectFactory *factory );
signals:
/**
* Emitted before collection is changed
*/
void sigParametersChanging();
/**
* Emitted after collection was changed
*/
void sigParametersChanged();
/**
* Object added.
*/
void sigAdded( QSCObject *o );
/**
* Object added to the collection 'collection' ( which is this collection or the collection of any QSCGroup object in this collection ).
*/
void sigAdded( QSCObjectCollection *collection, QSCObject *o );
/**
* Object removed from this collection
*/
void sigRemoved( QSCObject *o );
/**
* Object added to the collection 'collection'.
*/
void sigRemoved( QSCObjectCollection *collection, QSCObject *o );
/**
* Object raised, lowered, reordered.
*/
void sigOrderChanged();
/**
* Order of objects changed ( including all grouped object )
*/
void sigOrderChanged( QSCObjectCollection *collection );
/**
* Object list changed.
*/
void sigListChanged();
/**
* Object list changed.
*/
void sigListChanged( QSCObjectCollection *collection );
/**
* Emitted when QSData child object list ( QSAxis and QSPlot are child objects of QSAxes ) has changed.
* Emmitted for all QSData objects ( QSAxes ) in this collection. I really needed such signal.
*/
void sigDataChildListChanged();
/**
* Object on the list changed. Collection needs redrawing
*/
void sigChanged();
/**
* Draw ends.
*/
void sigDrawEnds();
protected:
bool m_auto_updates;
QSChildList<QSCObject> *m_objects;
virtual void parametersChanging();
virtual void parametersChanged();
virtual void orderChanged();
virtual void listChanged();
virtual void changed();
bool tempAutoUpdatesOff();
void tempAutoUpdatesRestore( bool enable );
private slots:
void slot_object_changed();
void slot_data_child_list_changed();
void slot_added(QSCObjectCollection*,QSCObject*);
void slot_removed(QSCObjectCollection*,QSCObject*);
void slot_order_changed(QSCObjectCollection*);
void slot_list_changed(QSCObjectCollection*);
void slot_draw_ends(QSCObject*);
};
//-------------------------------------------------------------------------------------------------//
class QSAxes;
class QSAxis;
class QSData;
class QSCGroup;
#define SET_COBJECT_PROPERTY( property, new_value ) if ((property)!=(new_value)) { parametersChanging(); (property)=(new_value); parametersChanged(); }
/**
* \brief Base class for canvas objects which can be displayed on a page.
*
* It can paint itself using the given painter - see paint(). Sometimes it takes much time to draw some
* objects such as graphs with many datapoints, so it supports drawing in the background. See paint() ( 'blocking' argument ),
* busy(), stop(), sigDrawEnds() methods. QSCObject is usually a member of some object collection, see collection(). It can be
* the main object collection of QSPage, but it can be also QSCGroup collection if object is grouped with others. In this case group()
* method returns a pointer to this group. QSCObject can be bound to some QSAxes object - see setParentAxes(). It is useful when, for example,
* QSCArrow should point at some data point in your graph. You can transform coordinates between various coordinate systems
* using mixedToCanvas(), canvasToMixed(). Notice that a single QSAxes object can have many coordinate systems, defined by
* every set of its axes. So you can choose which axes you want to use - see setDefaultXAxis(), setDefaultYAxis(), setDefaultZAxis().
* OQSCObject notifies when its parameters are changing, so it needs redrawing - see sigUpdate(). Use setBox() for positioning and resizing
* the object.
* @author Kamil Dobkowski
*/
class QSCObject : public QObject, public QSSerializable {
friend class QSCObjectCollection;
friend class QSCGroup;
Q_OBJECT
Q_PROPERTY( int defaultXAxis READ defaultXAxis WRITE setDefaultXAxis )
Q_PROPERTY( int defaultYAxis READ defaultYAxis WRITE setDefaultYAxis )
Q_PROPERTY( int defaultZAxis READ defaultZAxis WRITE setDefaultZAxis )
public:
/**
* Constructor.
*/
QSCObject( QObject *parent=NULL );
/**
* Destructor. Removes an object from a parent child list.
*/
virtual ~QSCObject();
/**
* Returns object's parent group if it is grouped or NULL.
*/
QSCGroup *group() const { return m_group; }
/**
* Returns collection to which this object belongs to or NULL. If collection is not autoDelete
* object doesn't belong to it.
*/
QSCObjectCollection *collection() const { return m_collection; }
/**
* Returns a root group of this object It digs through all group hierarchy.
* It will be usually the main object collection on QSPage.
*/
QSCObjectCollection *rootCollection();
/**
* Sets a parent axes object. Position of this object can be set
* as a relative to the parent object position. This function is called by
* QSAxes object ( or rather by its shadow QSCObject ), when this object is
* grouped with axes.
*/
virtual void setParentAxes( QSAxes *axes );
/**
* Returns a parent axes or NULL
*/
QSAxes *parentAxes() const { return m_parent_axes; }
/**
* Style of this object.
*/
enum Style { Rotateable = 1U<<0,
Resizeable = 1U<<1,
Moveable = 1U<<2 };
/**
* Returns a bitwise-OR of Style values. Informs the parent what actions
* on this object are allowed. Currently not used.
*/
virtual int style() { return 0; }
/**
* Control whether sigParametersChnged emits sigUpdate
*/
virtual void setAutoUpdates( bool enabled );
/**
* Returns auto-update state
*/
bool autoUpdates() const { return m_auto_updates; }
/**
* Raises object on a parent collection stack.
*/
virtual void raise();
/**
* Lowers object on a parent collection stack.
*/
virtual void lower();
/**
* Brings object to front on a parent collection stack.
*/
virtual void toFront();
/**
* Sends object to back on a parent collection stack.
*/
virtual void toBack();
/**
* Moves object to position 'newPosition' on a parent collection stack.
*/
virtual void reorder( int newPosition );
/**
* Paint simplified version of this object ( called when resizing, redrawing ).
*/
virtual void paintSkeleton( QPainter *p, double dpi = 72.0 );
/**
* Requests a repaint operation. If blocking is false the painter is copied using QSDrvQt::copyPainter(),
* this function returns and drawing is performed in the background
*/
virtual void paint( QPainter *p, double dpi = 72.0, bool blocking=true, bool transparent=true );
/**
* Requests a repaint operation. If blocking is false the driver is copied using QSDrv::copy(),
* this function returns and drawing is performed in the background
*/
virtual void draw( QSDrv *drv, bool blocking=true, bool transparent=true ) = 0;
/**
* When drawing is in background
*/
virtual bool busy() const { return false; }
/**
* Stops repainting immediately. This should be reimplemented if you allowind to repaint
* object in background.
*/
virtual void stop() {}
/**
* Return true if object is hit by mouse click.
*/
virtual bool isHit( const QSPt2f &p, QSDrv* drv ) { return box(drv).contains(p); }
/**
* Resize to canvas rect. Rect can be unnormalized ( size can be < 0 ).
* Drv ( its dpi value ) is used to map this values to mm's,
* calculating sizes of text labels, etc.
*/
virtual void setBox( const QSRectf& canvas_rect, QSDrv *drv );
/**
* Return a bounding box of the object. Result rect can be unnormalized ( size can be < 0 )
* Drv is used to obtains size of text labels etc.
*/
virtual QSRectf box( QSDrv *drv );
/**
* Called when a new angle is set.
*/
virtual void setAngle( int deg );
/**
* Returns the current angle
*/
virtual int angle() const { return 0; }
/**
* Return a center of a rotation.
*/
virtual QSPt2f rCenter( QSDrv *drv );
/**
* Returns an object's name ( for a list of object etc. )
*/
virtual QString name() { return tr("Unknown object"); }
/**
* Don't change it. It must always return 'false'. Do not reimplement this function in your own objects !.
*/
virtual bool isAxesShadow() { return false; }
/**
* Sets default X,Y or Z axia. Does not emit sigUpdate.
*/
void setDefaultAxis( QSAxis *axis );
/**
* Default X,Y or Z axis.
*/
QSAxis *defaultAxis( int axisType ) const;
/**
* Maps position 'pos' to canvas ( screen ) coords. It is a simple wrapper around
* QSAxes::mixedToCanvas(). If there are no parent axes it always maps mmToPixels
* Returns a depth also. See QSAxes::CoordinateSystem
*/
QSPt3f mixedToCanvas( const QSPt3f& pos, int xCoordIn, int yCoordIn, int zCoordIn, double dpi );
/**
* If there are no parent axes it always maps pixlesToMM. Useful tool to use in your own objects.
* See QSAxes::CoordinateSystem
*/
QSPt3f canvasToMixed( const QSPt3f& pos, int xCoordOut, int yCoordOut, int zCoordOut, double dpi );
/**
* Sets the default axis.
*/
void setDefaultXAxis( int axisIndex );
/**
* Sets the default axis.
*/
void setDefaultYAxis( int axisIndex );
/**
* Sets the default axis.
*/
void setDefaultZAxis( int axisIndex );
/**
* Returns an index of the default axis
*/
int defaultXAxis() const;
/**
* Returns an index of the default axis
*/
int defaultYAxis() const;
/**
* Returns an index of the default axis
*/
int defaultZAxis() const;
/**
* Saves all QObject properties
*/
virtual void loadStateFromStream( QDataStream& stream, QSObjectFactory *factory );
/**
* Restores all QObject properties
*/
virtual void saveStateToStream( QDataStream& stream, QSObjectFactory *factory );
public slots:
/**
* Calls stop()
*/
virtual void parametersChanging();
/**
* Emits sigUpdate()
*/
virtual void parametersChanged();
/**
* Emits sigUpdate()
*/
virtual void forceUpdate();
signals:
void sigDrawEnds( QSCObject *me );
/**
* Parameters has changed
*/
void sigUpdate( QSCObject *me );
/**
* Parameters has changed ( the same as a signal above ).
*/
void sigUpdate();
protected:
QSAxes *m_parent_axes;
QSAxis *m_default_axis[3];
bool m_auto_updates;
QSCObjectCollection *m_collection;
QSCGroup *m_group;
/**
* Called by collection when this object is inserted or removed (collection=NULL) from its list.
*/
virtual void setCollection( QSCObjectCollection *collection );
/**
* Called when object is grouped or ungrouped(group=NULL)
*/
virtual void setGroup( QSCGroup *group );
private slots:
/**
* Checks if default axis is removed, if it is binds to another axis
*/
void axisRemoved( QSData *removedObject );
/**
* Checks if parent axes are removed, Sets a parent axes to NULL in this case.
*/
void parentAxesRemoved( QSData *removedObject );
};
//-------------------------------------------------------------------------------------------------//
/**
* \brief Group of QSCObject s, which is also QSCObject.
*
* All its functionality is exposed through its object collection - see objects().
*/
class QSCGroup : public QSCObject
{
Q_OBJECT
public:
/**
* Constructor
*/
QSCGroup( QObject *parent=NULL );
/**
* Destructor
*/
virtual ~QSCGroup();
/**
* Sets parent axes in all contained objects.
*/
virtual void setParentAxes( QSAxes *axes );
/**
* Returns a list of grouped object.
*/
QSCObjectCollection *objects() const { return m_objects; }
/**
* Default style is Moveable | Resizeable
*/
virtual int style() { return Moveable | Resizeable; }
/**
* Reimplemented
*/
virtual void paintSkeleton( QPainter *p, double dpi = 72.0 );
/**
* Reimplemented
*/
virtual void paint( QPainter *p, double dpi = 72.0, bool blocking=true, bool transparent=true );
/**
* Reimplemented
*/
virtual void draw( QSDrv *drv, bool blocking=true, bool transparent=true );
/**
* Reimplemented
*/
virtual bool busy() const;
/**
* Reimplemented
*/
virtual void stop();
/**
* Reimplemented
*/
virtual bool isHit( const QSPt2f &p, QSDrv* drv );
/**
* Reimplemented
*/
virtual void setBox( const QSRectf& canvas_rect, QSDrv *drv );
/**
* Reimplemented
*/
virtual QSRectf box( QSDrv *drv );
/**
* Reimplemented
*/
virtual QString name();
/**
* Reimplemented
*/
virtual void loadStateFromStream( QDataStream& stream, QSObjectFactory *factory );
/**
* Reimplemented
*/
virtual void saveStateToStream( QDataStream& stream, QSObjectFactory *factory );
protected:
QSCObjectCollection *m_objects;
bool m_w_minus;
bool m_h_minus;
protected slots:
void slot_draw_ends();
void slot_collection_changed();
void slot_object_added( QSCObject * );
void slot_object_removed( QSCObject * );
};
#endif