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.
947 lines
28 KiB
947 lines
28 KiB
/***************************************************************************
|
|
qscobject.cpp
|
|
-------------------
|
|
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. *
|
|
* *
|
|
***************************************************************************/
|
|
|
|
#include "qscobject.h"
|
|
#include "qsdrvqt.h"
|
|
#include "qsaxes.h"
|
|
#include "qsaxis.h"
|
|
#include "qschildlist.h"
|
|
#include <math.h>
|
|
#include <qmetaobject.h>
|
|
#include <qcstring.h>
|
|
#include <qvariant.h>
|
|
#include <assert.h>
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
QSCObjectCollection::QSCObjectCollection( QObject *parent, bool autoDelete )
|
|
: QObject(parent), QSSerializable()
|
|
{
|
|
m_auto_updates = true;
|
|
m_objects = new QSChildList<QSCObject>(autoDelete);
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
QSCObjectCollection::~QSCObjectCollection()
|
|
{
|
|
stop();
|
|
delete m_objects;
|
|
//cout << "deleting object collection" << endl;
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSCObjectCollection::setAutoUpdates( bool enable )
|
|
{
|
|
if ( m_auto_updates != enable ) {
|
|
m_auto_updates = enable;
|
|
listChanged();
|
|
changed();
|
|
}
|
|
}
|
|
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
int QSCObjectCollection::count() const
|
|
{
|
|
return m_objects->count();
|
|
}
|
|
//-------------------------------------------------------------//
|
|
|
|
bool QSCObjectCollection::tempAutoUpdatesOff()
|
|
{
|
|
bool result = m_auto_updates;
|
|
m_auto_updates = false;
|
|
return result;
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSCObjectCollection::tempAutoUpdatesRestore( bool enable )
|
|
{
|
|
m_auto_updates = enable;
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSCObjectCollection::clear()
|
|
{
|
|
parametersChanging();
|
|
bool temp = tempAutoUpdatesOff();
|
|
while( count() ) removeDelete(0);
|
|
tempAutoUpdatesRestore( temp );
|
|
listChanged();
|
|
parametersChanged();
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSCObjectCollection::add( QSCObject *newObject )
|
|
{
|
|
insert( count(), newObject );
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSCObjectCollection::insert( int position, QSCObject *newObject )
|
|
{
|
|
if ( newObject && find(newObject) < 0 ) {
|
|
parametersChanging();
|
|
if ( m_objects->autoDelete() ) newObject->stop();
|
|
m_objects->insert( position, newObject );
|
|
connect( newObject, SIGNAL(sigUpdate()), this, SLOT(slot_object_changed()) );
|
|
if ( newObject->isAxesShadow() ) {
|
|
connect( newObject->parentAxes(), SIGNAL(sigChildListChanged()), this, SLOT(slot_data_child_list_changed()) );
|
|
}
|
|
if ( dynamic_cast<QSCGroup*>(newObject) ) {
|
|
QSCGroup *group = (QSCGroup *)newObject;
|
|
connect( group->objects(), SIGNAL(sigAdded(QSCObjectCollection*,QSCObject*)), this, SLOT(slot_added(QSCObjectCollection*,QSCObject*)) );
|
|
connect( group->objects(), SIGNAL(sigRemoved(QSCObjectCollection*,QSCObject*)), this, SLOT(slot_removed(QSCObjectCollection*,QSCObject*)) );
|
|
connect( group->objects(), SIGNAL(sigOrderChanged(QSCObjectCollection*)), this, SLOT(slot_order_changed(QSCObjectCollection*)) );
|
|
connect( group->objects(), SIGNAL(sigListChanged(QSCObjectCollection*)), this, SLOT(slot_list_changed(QSCObjectCollection*)) );
|
|
connect( group->objects(), SIGNAL(sigDataChildListChanged()), this, SLOT(slot_data_child_list_changed()) );
|
|
}
|
|
if ( m_objects->autoDelete() ) {
|
|
newObject->setCollection(this);
|
|
}
|
|
emit sigAdded( newObject );
|
|
emit sigAdded( this, newObject );
|
|
listChanged();
|
|
parametersChanged();
|
|
}
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSCObjectCollection::remove( int index )
|
|
{
|
|
QSCObject *object_to_remove = object( index );
|
|
if ( object_to_remove ) {
|
|
parametersChanging();
|
|
if ( m_objects->autoDelete() ) {
|
|
object_to_remove->stop();
|
|
object_to_remove->setCollection(NULL);
|
|
}
|
|
if ( object_to_remove->isAxesShadow() ) {
|
|
disconnect( object_to_remove->parentAxes(), SIGNAL(sigChildListChanged()), this, SLOT(slot_data_child_list_changed()) );
|
|
}
|
|
if ( dynamic_cast<QSCGroup*>(object_to_remove) ) {
|
|
QSCGroup *group = (QSCGroup *)object_to_remove;
|
|
disconnect( group->objects(), SIGNAL(sigAdded(QSCObjectCollection*,QSCObject*)), this, SLOT(slot_added(QSCObjectCollection*,QSCObject*)) );
|
|
disconnect( group->objects(), SIGNAL(sigRemoved(QSCObjectCollection*,QSCObject*)), this, SLOT(slot_removed(QSCObjectCollection*,QSCObject*)) );
|
|
disconnect( group->objects(), SIGNAL(sigOrderChanged(QSCObjectCollection*)), this, SLOT(slot_order_changed(QSCObjectCollection*)) );
|
|
disconnect( group->objects(), SIGNAL(sigListChanged(QSCObjectCollection*)), this, SLOT(slot_list_changed(QSCObjectCollection*)) );
|
|
disconnect( group->objects(), SIGNAL(sigDataChildListChanged()), this, SLOT(slot_data_child_list_changed()) );
|
|
}
|
|
disconnect( object_to_remove, SIGNAL(sigUpdate()), this, SLOT(slot_object_changed()) );
|
|
m_objects->remove( index );
|
|
emit sigRemoved( object_to_remove );
|
|
emit sigRemoved( this, object_to_remove );
|
|
listChanged();
|
|
parametersChanged();
|
|
}
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSCObjectCollection::removeDelete( int index )
|
|
{
|
|
QSCObject *object_to_delete = object( index );
|
|
if ( object_to_delete ) {
|
|
remove( index );
|
|
if ( m_objects->autoDelete() ) delete object_to_delete;
|
|
}
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSCObjectCollection::raise( int index )
|
|
{
|
|
parametersChanging();
|
|
m_objects->raise( index );
|
|
orderChanged();
|
|
parametersChanged();
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSCObjectCollection::lower( int index )
|
|
{
|
|
parametersChanging();
|
|
m_objects->lower( index );
|
|
orderChanged();
|
|
parametersChanged();
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSCObjectCollection::toFront( int index )
|
|
{
|
|
parametersChanging();
|
|
m_objects->toFront( index );
|
|
orderChanged();
|
|
parametersChanged();
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSCObjectCollection::toBack( int index )
|
|
{
|
|
parametersChanging();
|
|
m_objects->toBack( index );
|
|
orderChanged();
|
|
parametersChanged();
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSCObjectCollection::reorder( int position, int index )
|
|
{
|
|
parametersChanging();
|
|
m_objects->reorder( position, index );
|
|
orderChanged();
|
|
parametersChanged();
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
int QSCObjectCollection::find( QSCObject *object ) const
|
|
{
|
|
return m_objects->find( object );
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
QSCObject *QSCObjectCollection::object( int index ) const
|
|
{
|
|
return (*m_objects)[index];
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSCObjectCollection::paintSkeleton( QPainter *p, double dpi )
|
|
{
|
|
for( int i=0; i<count(); i++ ) object(i)->paintSkeleton( p, dpi );
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSCObjectCollection::paint( QPainter *p, double dpi, bool blocking, bool transparent )
|
|
{
|
|
for( int i=0; i<count(); i++ ) {
|
|
object(i)->paint( p, dpi, blocking, transparent );
|
|
if ( object(i)->busy() ) connect( object(i), SIGNAL(sigDrawEnds(QSCObject*)), this, SLOT(slot_draw_ends(QSCObject*)) );
|
|
}
|
|
slot_draw_ends(NULL);
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSCObjectCollection::draw( QSDrv *drv, bool blocking, bool transparent )
|
|
{
|
|
for( int i=0; i<count(); i++ ) {
|
|
object(i)->draw( drv, blocking, transparent );
|
|
if ( object(i)->busy() ) connect( object(i), SIGNAL(sigDrawEnds(QSCObject*)), this, SLOT(slot_draw_ends(QSCObject*)) );
|
|
}
|
|
slot_draw_ends(NULL);
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSCObjectCollection::slot_draw_ends( QSCObject *object )
|
|
{
|
|
if ( object ) disconnect( object, SIGNAL(sigDrawEnds(QSCObject*)), this, SLOT(slot_draw_ends(QSCObject*)) );
|
|
if ( !busy() ) emit sigDrawEnds();
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
bool QSCObjectCollection::busy() const
|
|
{
|
|
for( int i=0; i<count(); i++ ) if ( object(i)->busy() ) return true;
|
|
return false;
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSCObjectCollection::stop()
|
|
{
|
|
for( int i=0; i<count(); i++ ) object(i)->stop();
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
QSCObject *QSCObjectCollection::objectAt( const QSPt2f &p, QSDrv* drv, bool recursive )
|
|
{
|
|
for( int i=count()-1; i>=0; i-- )
|
|
if ( object(i)->isHit(p,drv) )
|
|
if ( recursive && dynamic_cast<QSCGroup*>(object(i)) ) {
|
|
QSCObject *hit_object = ((QSCGroup*)(object(i)))->objects()->objectAt( p, drv, recursive );
|
|
return hit_object ? hit_object : object(i);
|
|
} else {
|
|
return object(i);
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
bool QSCObjectCollection::contains( QSCObject *checkedObject, bool recursive )
|
|
{
|
|
if ( find(checkedObject) >= 0 ) return true;
|
|
if ( recursive )
|
|
for( int i=0; i<count(); i++ ) if ( dynamic_cast<QSCGroup*>(object(i)) ) {
|
|
if ( ((QSCGroup*)(object(i)))->objects()->contains( checkedObject, recursive ) ) return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSCObjectCollection::loadStateFromStream( QDataStream& stream, QSObjectFactory *factory )
|
|
// we dont load auto-delete
|
|
{
|
|
clear();
|
|
int object_count; stream >> object_count;
|
|
for( int i=0; i<object_count; i++ ) {
|
|
QSCObject *new_object = dynamic_cast<QSCObject *>(factory->loadObjectFromStream(stream));
|
|
assert( new_object ); add( new_object );
|
|
}
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSCObjectCollection::saveStateToStream( QDataStream& stream, QSObjectFactory *factory )
|
|
// we dont save auto-delete
|
|
{
|
|
QSSerializable::saveStateToStream( stream, factory );
|
|
stream << (int )count();
|
|
for( int i=0; i<count(); i++ ) factory->saveObjectToStream( object(i), stream );
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSCObjectCollection::parametersChanging()
|
|
{
|
|
emit sigParametersChanging();
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSCObjectCollection::parametersChanged()
|
|
{
|
|
emit sigParametersChanged();
|
|
changed();
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSCObjectCollection::orderChanged()
|
|
{
|
|
emit sigOrderChanged();
|
|
emit sigOrderChanged( this );
|
|
listChanged();
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSCObjectCollection::listChanged()
|
|
{
|
|
if ( m_auto_updates ) {
|
|
emit sigListChanged();
|
|
emit sigListChanged( this );
|
|
}
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSCObjectCollection::changed()
|
|
{
|
|
if ( m_auto_updates ) emit sigChanged();
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSCObjectCollection::slot_added( QSCObjectCollection *collection, QSCObject*object )
|
|
{
|
|
emit sigAdded( collection, object );
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSCObjectCollection::slot_removed( QSCObjectCollection *collection, QSCObject *object )
|
|
{
|
|
emit sigRemoved( collection, object );
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSCObjectCollection::slot_order_changed( QSCObjectCollection *collection )
|
|
{
|
|
emit sigOrderChanged( collection );
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSCObjectCollection::slot_list_changed( QSCObjectCollection *collection )
|
|
{
|
|
if ( m_auto_updates ) emit sigListChanged( collection );
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSCObjectCollection::slot_object_changed()
|
|
{
|
|
changed();
|
|
}
|
|
|
|
//---------------------------------------------------------------------------------------------------//
|
|
|
|
void QSCObjectCollection::slot_data_child_list_changed()
|
|
{
|
|
emit sigDataChildListChanged();
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
|
|
//-------------------------------------------------------------//
|
|
//-------------------------------------------------------------//
|
|
//-------------------------------------------------------------//
|
|
//-------------------------------------------------------------//
|
|
//-------------------------------------------------------------//
|
|
|
|
QSCObject::QSCObject( QObject *parent ):
|
|
QObject(parent), QSSerializable()
|
|
{
|
|
m_group = NULL;
|
|
m_collection = NULL;
|
|
m_parent_axes = NULL;
|
|
m_auto_updates = true;
|
|
m_default_axis[0] = NULL;
|
|
m_default_axis[1] = NULL;
|
|
m_default_axis[2] = NULL;
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
QSCObject::~QSCObject()
|
|
{
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSCObject::setParentAxes( QSAxes *axes )
|
|
{
|
|
if ( axes != m_parent_axes ) {
|
|
parametersChanging();
|
|
if ( m_parent_axes ) {
|
|
m_default_axis[0] = NULL;
|
|
m_default_axis[1] = NULL;
|
|
m_default_axis[2] = NULL;
|
|
disconnect( m_parent_axes, SIGNAL(sigChildRemoved(QSData*)), this, SLOT(axisRemoved(QSData*)) );
|
|
disconnect( m_parent_axes, SIGNAL(sigDeleted(QSData*)), this, SLOT(parentAxesRemoved(QSData*)) );
|
|
}
|
|
m_parent_axes = axes;
|
|
if ( m_parent_axes ) {
|
|
m_default_axis[0] = m_parent_axes->axisOfType(QSAxis::XAxisType);
|
|
m_default_axis[1] = m_parent_axes->axisOfType(QSAxis::YAxisType);
|
|
m_default_axis[2] = m_parent_axes->axisOfType(QSAxis::ZAxisType);
|
|
connect( m_parent_axes, SIGNAL(sigChildRemoved(QSData*)), this, SLOT(axisRemoved(QSData*)) );
|
|
connect( m_parent_axes, SIGNAL(sigDeleted(QSData*)), this, SLOT(parentAxesRemoved(QSData*)) );
|
|
}
|
|
parametersChanged();
|
|
}
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSCObject::setCollection( QSCObjectCollection *parent )
|
|
{
|
|
m_collection = parent;
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSCObject::setGroup( QSCGroup *group )
|
|
{
|
|
m_group = group;
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSCObject::raise()
|
|
{
|
|
if ( m_collection ) m_collection->raise( m_collection->find(this) );
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSCObject::lower()
|
|
{
|
|
if ( m_collection ) m_collection->lower( m_collection->find(this) );
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSCObject::toFront()
|
|
{
|
|
if ( m_collection ) m_collection->toFront( m_collection->find(this) );
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSCObject::toBack()
|
|
{
|
|
if ( m_collection ) m_collection->toBack( m_collection->find(this) );
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSCObject::reorder( int newPosition )
|
|
{
|
|
if ( m_collection ) m_collection->reorder( newPosition, m_collection->find(this) );
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSCObject::axisRemoved( QSData *removedObject )
|
|
{
|
|
if ( m_parent_axes ) {
|
|
if ( m_default_axis[0] == removedObject ) m_default_axis[0] = m_parent_axes->axisOfType(QSAxis::XAxisType);
|
|
if ( m_default_axis[1] == removedObject ) m_default_axis[1] = m_parent_axes->axisOfType(QSAxis::YAxisType);
|
|
if ( m_default_axis[2] == removedObject ) m_default_axis[2] = m_parent_axes->axisOfType(QSAxis::ZAxisType);
|
|
}
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSCObject::parentAxesRemoved( QSData *removedObject )
|
|
{
|
|
if ( removedObject == m_parent_axes ) {
|
|
setParentAxes(NULL);
|
|
}
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
QSAxis *QSCObject::defaultAxis( int axisType ) const
|
|
{
|
|
if ( axisType == QSAxis::XAxisType ||
|
|
axisType == QSAxis::YAxisType ||
|
|
axisType == QSAxis::ZAxisType ) {
|
|
return m_default_axis[axisType];
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSCObject::setDefaultAxis( QSAxis *axis )
|
|
{
|
|
if ( axis &&
|
|
axis->parentAxes() == m_parent_axes &&
|
|
( axis->type() == QSAxis::XAxisType ||
|
|
axis->type() == QSAxis::YAxisType ||
|
|
axis->type() == QSAxis::ZAxisType ) ) {
|
|
parametersChanging();
|
|
m_default_axis[axis->type()] = axis;
|
|
parametersChanged();
|
|
}
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
QSPt3f QSCObject::mixedToCanvas( const QSPt3f& pos, int xCoordIn, int yCoordIn, int zCoordIn, double dpi )
|
|
{
|
|
QSPt3f result;
|
|
|
|
if ( m_parent_axes ) {
|
|
QSAxes::CoordinateSystem in_coord[3];
|
|
in_coord[0] = (QSAxes::CoordinateSystem )xCoordIn;
|
|
in_coord[1] = (QSAxes::CoordinateSystem )yCoordIn;
|
|
in_coord[2] = (QSAxes::CoordinateSystem )zCoordIn;
|
|
result = m_parent_axes->mixedToCanvas( pos, in_coord, dpi, m_default_axis[0], m_default_axis[1], m_default_axis[2] );
|
|
} else {
|
|
result = QSPt3f( QSCoord::mmToPixels( pos.x, dpi ),
|
|
QSCoord::mmToPixels( pos.y, dpi ),
|
|
QSCoord::mmToPixels( pos.z, dpi ) );
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
QSPt3f QSCObject::canvasToMixed( const QSPt3f& pos, int xCoordOut, int yCoordOut, int zCoordOut, double dpi )
|
|
{
|
|
QSPt3f result;
|
|
|
|
if ( m_parent_axes ) {
|
|
QSAxes::CoordinateSystem out_coord[3];
|
|
out_coord[0] = (QSAxes::CoordinateSystem )xCoordOut;
|
|
out_coord[1] = (QSAxes::CoordinateSystem )yCoordOut;
|
|
out_coord[2] = (QSAxes::CoordinateSystem )zCoordOut;
|
|
result = m_parent_axes->canvasToMixed( pos, out_coord, dpi, m_default_axis[0], m_default_axis[1], m_default_axis[2] );
|
|
} else {
|
|
result = QSPt3f( QSCoord::pixelsToMM( pos.x, dpi ),
|
|
QSCoord::pixelsToMM( pos.y, dpi ),
|
|
QSCoord::pixelsToMM( pos.z, dpi ) );
|
|
}
|
|
return result;
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSCObject::setAutoUpdates( bool enabled )
|
|
{
|
|
m_auto_updates = enabled;
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSCObject::paintSkeleton( QPainter *p, double dpi )
|
|
{
|
|
QSCObject::paint( p, dpi );
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSCObject::paint( QPainter *p, double dpi, bool blocking, bool transparent )
|
|
{
|
|
QSDrvQt qtdrv;
|
|
qtdrv.setDC(p,dpi,false);
|
|
draw( &qtdrv, blocking, transparent );
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSCObject::setBox( const QSRectf&, QSDrv* )
|
|
{
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
QSRectf QSCObject::box( QSDrv * )
|
|
{
|
|
return QSRectf();
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSCObject::setAngle( int )
|
|
{
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
QSPt2f QSCObject::rCenter( QSDrv * )
|
|
{
|
|
return QSPt2f();
|
|
}
|
|
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSCObject::parametersChanging()
|
|
{
|
|
stop();
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSCObject::parametersChanged()
|
|
{
|
|
if ( m_auto_updates ) {
|
|
emit sigUpdate( this );
|
|
emit sigUpdate();
|
|
}
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSCObject::forceUpdate()
|
|
{
|
|
emit sigUpdate( this );
|
|
emit sigUpdate();
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSCObject::setDefaultXAxis( int axisIndex )
|
|
{
|
|
setDefaultAxis( m_parent_axes ? m_parent_axes->axis(axisIndex) : NULL );
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSCObject::setDefaultYAxis( int axisIndex )
|
|
{
|
|
setDefaultAxis( m_parent_axes ? m_parent_axes->axis(axisIndex) : NULL );
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSCObject::setDefaultZAxis( int axisIndex )
|
|
{
|
|
setDefaultAxis( m_parent_axes ? m_parent_axes->axis(axisIndex) : NULL );
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
int QSCObject::defaultXAxis() const
|
|
{
|
|
return m_parent_axes ? m_parent_axes->axisIndex(m_default_axis[QSAxis::XAxisType]) : -1;
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
int QSCObject::defaultYAxis() const
|
|
{
|
|
return m_parent_axes ? m_parent_axes->axisIndex(m_default_axis[QSAxis::YAxisType]) : -1;
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
int QSCObject::defaultZAxis() const
|
|
{
|
|
return m_parent_axes ? m_parent_axes->axisIndex(m_default_axis[QSAxis::ZAxisType]) : -1;
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
QSCObjectCollection *QSCObject::rootCollection()
|
|
{
|
|
QSCGroup *curr_group = group();
|
|
while( curr_group && curr_group->group() ) curr_group = curr_group->group();
|
|
if ( curr_group ) return curr_group->collection();
|
|
else return collection();
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSCObject::loadStateFromStream( QDataStream& stream, QSObjectFactory *factory )
|
|
{
|
|
QSSerializable::loadStateFromStream( stream, factory );
|
|
QMetaObject *meta_object = metaObject();
|
|
QStrList properties = meta_object->propertyNames( TRUE );
|
|
for( unsigned int property_nr=0; property_nr<properties.count(); property_nr++ ) {
|
|
QCString property_name;
|
|
QVariant property_value;
|
|
stream >> property_name >> property_value;
|
|
setProperty(property_name,property_value);
|
|
}
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSCObject::saveStateToStream( QDataStream& stream, QSObjectFactory *factory )
|
|
{
|
|
QSSerializable::saveStateToStream( stream, factory );
|
|
QMetaObject *meta_object = metaObject();
|
|
QStrList properties = meta_object->propertyNames( TRUE );
|
|
for( unsigned int property_nr=0; property_nr<properties.count(); property_nr++ ) {
|
|
stream << QCString(properties.at(property_nr)) << property(properties.at(property_nr));
|
|
}
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
//-------------------------------------------------------------//
|
|
//-------------------------------------------------------------//
|
|
//-------------------------------------------------------------//
|
|
|
|
QSCGroup::QSCGroup( QObject *parent )
|
|
: QSCObject(parent)
|
|
{
|
|
m_w_minus = false;
|
|
m_h_minus = false;
|
|
m_objects = new QSCObjectCollection( this );
|
|
connect( m_objects, SIGNAL(sigChanged()), this, SLOT(slot_collection_changed()) );
|
|
connect( m_objects, SIGNAL(sigParametersChanging()), this, SLOT(parametersChanging()) );
|
|
connect( m_objects, SIGNAL(sigParametersChanged()), this, SLOT(parametersChanged()) );
|
|
connect( m_objects, SIGNAL(sigAdded(QSCObject*)), this, SLOT(slot_object_added(QSCObject*)) );
|
|
connect( m_objects, SIGNAL(sigRemoved(QSCObject*)), this, SLOT(slot_object_removed(QSCObject*)) );
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
QSCGroup::~QSCGroup()
|
|
{
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSCGroup::paintSkeleton( QPainter *p, double dpi )
|
|
{
|
|
m_objects->paintSkeleton( p, dpi );
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSCGroup::paint( QPainter *p, double dpi, bool blocking, bool transparent )
|
|
{
|
|
connect( m_objects, SIGNAL(sigDrawEnds()), this, SLOT(slot_draw_ends()) );
|
|
m_objects->paint( p, dpi, blocking, transparent );
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSCGroup::draw( QSDrv *drv, bool blocking, bool transparent )
|
|
{
|
|
connect( m_objects, SIGNAL(sigDrawEnds()), this, SLOT(slot_draw_ends()) );
|
|
m_objects->draw( drv, blocking, transparent );
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSCGroup::slot_draw_ends()
|
|
{
|
|
disconnect( m_objects, SIGNAL(sigDrawEnds()), this, SLOT(slot_draw_ends()) );
|
|
emit sigDrawEnds( this );
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
bool QSCGroup::busy() const
|
|
{
|
|
return m_objects->busy();
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSCGroup::stop()
|
|
{
|
|
m_objects->stop();
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
bool QSCGroup::isHit( const QSPt2f &p, QSDrv* drv )
|
|
{
|
|
return (m_objects->objectAt(p,drv) != NULL);
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSCGroup::setBox( const QSRectf& new_rect, QSDrv *drv )
|
|
{
|
|
// Ups !!!
|
|
// allow rectangles with size < 0 (mirroring )
|
|
QSRectf newRect = new_rect;
|
|
if ( newRect.size.x >= 0.0 && newRect.size.x < 1.0 ) newRect.size.x = 1.0;
|
|
if ( newRect.size.y >= 0.0 && newRect.size.y < 1.0 ) newRect.size.y = 1.0;
|
|
if ( newRect.size.x < 0.0 && newRect.size.x > -1.0 ) newRect.size.x = -1.0;
|
|
if ( newRect.size.y < 0.0 && newRect.size.y > -1.0 ) newRect.size.y = -1.0;
|
|
|
|
parametersChanging();
|
|
disconnect( m_objects, SIGNAL(sigChanged()), this, SLOT(slot_collection_changed()) );
|
|
QSRectf rect = box(drv);
|
|
QSPt2f scale;
|
|
scale.x = newRect.size.x/rect.size.x;
|
|
scale.y = newRect.size.y/rect.size.y;
|
|
for( int i=0;i<objects()->count(); i++ ) {
|
|
QSRectf curr_rect = objects()->object(i)->box(drv);
|
|
curr_rect.pos = QSPt2f( ((curr_rect.pos.x-rect.pos.x)*scale.x+newRect.pos.x),
|
|
((curr_rect.pos.y-rect.pos.y)*scale.y+newRect.pos.y) );
|
|
curr_rect.size.x *= scale.x;
|
|
curr_rect.size.y *= scale.y;
|
|
objects()->object(i)->setBox(curr_rect,drv);
|
|
}
|
|
if ( (newRect.size.x < 0.0) != m_w_minus ) m_w_minus = !m_w_minus;
|
|
if ( (newRect.size.y < 0.0) != m_h_minus ) m_h_minus = !m_h_minus;
|
|
connect( m_objects, SIGNAL(sigChanged()), this, SLOT(slot_collection_changed()) );
|
|
parametersChanged();
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
QSRectf QSCGroup::box( QSDrv *drv )
|
|
{
|
|
QSRectf result;
|
|
if ( objects()->count() > 0 ) {
|
|
result = objects()->object(0)->box(drv).normalize();
|
|
for( int i=1; i<objects()->count(); i++ ) result.unite( objects()->object(i)->box(drv).normalize() );
|
|
}
|
|
if ( m_w_minus ) { result.pos.x += result.size.x; result.size.x = -result.size.x; }
|
|
if ( m_h_minus ) { result.pos.y += result.size.y; result.size.y = -result.size.y; }
|
|
return result;
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
QString QSCGroup::name()
|
|
{
|
|
return tr("Group of %1 objects").arg(objects()->count());
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSCGroup::setParentAxes( QSAxes *axes )
|
|
{
|
|
QSCObject::setParentAxes( axes );
|
|
for( int i=0; i<objects()->count(); i++ ) objects()->object(i)->setParentAxes( axes );
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSCGroup::slot_collection_changed()
|
|
{
|
|
emit sigUpdate(this);
|
|
emit sigUpdate();
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSCGroup::slot_object_added( QSCObject *object )
|
|
// we hope that this signal is received by this object before any other object which also connects
|
|
// to QSCObjectCollection::sigAdded will get this signal. So this other object will see a newly added object
|
|
// which has already group() property set.
|
|
{
|
|
object->setGroup( this );
|
|
object->setParentAxes( parentAxes() );
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSCGroup::slot_object_removed( QSCObject *object )
|
|
{
|
|
object->setGroup( NULL );
|
|
object->setParentAxes( NULL );
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSCGroup::loadStateFromStream( QDataStream& stream, QSObjectFactory *factory )
|
|
{
|
|
QSCObject::loadStateFromStream( stream, factory );
|
|
int w_minus; stream >> w_minus; m_w_minus = (bool )w_minus;
|
|
int h_minus; stream >> h_minus; m_h_minus = (bool )h_minus;
|
|
m_objects->loadStateFromStream( stream, factory );
|
|
}
|
|
|
|
//-------------------------------------------------------------//
|
|
|
|
void QSCGroup::saveStateToStream( QDataStream& stream, QSObjectFactory *factory )
|
|
{
|
|
QSCObject::saveStateToStream( stream, factory );
|
|
stream << (int)m_w_minus;
|
|
stream << (int)m_h_minus;
|
|
m_objects->saveStateToStream( stream, factory );
|
|
}
|