Newer
Older
The subproperties are created by a QtDoublePropertyManager object. This
manager can be retrieved using the subDoublePropertyManager() function. In
order to provide editing widgets for the subproperties in a
property browser widget, this manager must be associated with an
editor factory.
A size property also has a range of valid values defined by a
minimum size and a maximum size. These sizes can be retrieved
using the minimum() and the maximum() functions, and set using the
setMinimum() and setMaximum() slots. Alternatively, the range can
be defined in one go using the setRange() slot.
In addition, QtSizeFPropertyManager provides the valueChanged() signal
which is emitted whenever a property created by this manager
changes, and the rangeChanged() signal which is emitted whenever
such a property changes its range of valid sizes.
\sa QtAbstractPropertyManager, QtDoublePropertyManager, QtSizePropertyManager
\fn void QtSizeFPropertyManager::valueChanged(QtProperty *property, const QSizeF &value)
This signal is emitted whenever a property created by this manager
changes its value, passing a pointer to the \a property and the new
\a value as parameters.
\sa setValue()
*/
/**
\fn void QtSizeFPropertyManager::rangeChanged(QtProperty *property, const QSizeF &minimum, const QSizeF &maximum)
This signal is emitted whenever a property created by this manager
changes its range of valid sizes, passing a pointer to the \a
property and the new \a minimum and \a maximum sizes.
\sa setRange()
*/
/**
\fn void QtSizeFPropertyManager::decimalsChanged(QtProperty *property, int prec)
This signal is emitted whenever a property created by this manager
changes its precision of value, passing a pointer to the
\a property and the new \a prec value
\sa setDecimals()
*/
/**
Creates a manager with the given \a parent.
*/
QtSizeFPropertyManager::QtSizeFPropertyManager(QObject *parent)
: QtAbstractPropertyManager(parent)
{
d_ptr = new QtSizeFPropertyManagerPrivate;
d_ptr->q_ptr = this;
d_ptr->m_doublePropertyManager = new QtDoublePropertyManager(this);
connect(d_ptr->m_doublePropertyManager, SIGNAL(valueChanged(QtProperty *, double)),
this, SLOT(slotDoubleChanged(QtProperty *, double)));
connect(d_ptr->m_doublePropertyManager, SIGNAL(propertyDestroyed(QtProperty *)),
this, SLOT(slotPropertyDestroyed(QtProperty *)));
}
/**
Destroys this manager, and all the properties it has created.
*/
QtSizeFPropertyManager::~QtSizeFPropertyManager()
{
clear();
delete d_ptr;
}
/**
Returns the manager that creates the nested \e width and \e height
subproperties.
In order to provide editing widgets for the \e width and \e height
properties in a property browser widget, this manager must be
associated with an editor factory.
\sa QtAbstractPropertyBrowser::setFactoryForManager()
*/
QtDoublePropertyManager *QtSizeFPropertyManager::subDoublePropertyManager() const
{
return d_ptr->m_doublePropertyManager;
}
/**
Returns the given \a property's value.
If the given \a property is not managed by this manager, this
function returns an invalid size
\sa setValue()
*/
QSizeF QtSizeFPropertyManager::value(const QtProperty *property) const
{
return getValue<QSizeF>(d_ptr->m_values, property);
}
/**
Returns the given \a property's precision, in decimals.
\sa setDecimals()
*/
int QtSizeFPropertyManager::decimals(const QtProperty *property) const
{
return getData<int>(d_ptr->m_values, &QtSizeFPropertyManagerPrivate::Data::decimals, property, 0);
}
/**
Returns the given \a property's minimum size value.
\sa setMinimum(), maximum(), setRange()
*/
QSizeF QtSizeFPropertyManager::minimum(const QtProperty *property) const
{
return getMinimum<QSizeF>(d_ptr->m_values, property);
}
/**
Returns the given \a property's maximum size value.
\sa setMaximum(), minimum(), setRange()
*/
QSizeF QtSizeFPropertyManager::maximum(const QtProperty *property) const
{
return getMaximum<QSizeF>(d_ptr->m_values, property);
QString QtSizeFPropertyManager::valueText(const QtProperty *property) const
{
const QtSizeFPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property);
if (it == d_ptr->m_values.constEnd())
return QString();
const QSizeF v = it.value().val;
const int dec = it.value().decimals;
return QString(tr("%1 x %2").arg(QString::number(v.width(), 'f', dec))
.arg(QString::number(v.height(), 'f', dec)));
\fn void QtSizeFPropertyManager::setValue(QtProperty *property, const QSizeF &value)
Sets the value of the given \a property to \a value.
If the specified \a value is not valid according to the given \a
property's size range, the \a value is adjusted to the nearest
valid value within the size range.
\sa value(), setRange(), valueChanged()
*/
void QtSizeFPropertyManager::setValue(QtProperty *property, const QSizeF &val)
{
setValueInRange<const QSizeF &, QtSizeFPropertyManagerPrivate, QtSizeFPropertyManager, QSizeF>(this, d_ptr,
&QtSizeFPropertyManager::propertyChanged,
&QtSizeFPropertyManager::valueChanged,
property, val, &QtSizeFPropertyManagerPrivate::setValue);
}
/**
\fn void QtSizeFPropertyManager::setDecimals(QtProperty *property, int prec)
Sets the precision of the given \a property to \a prec.
The valid decimal range is 0-13. The default is 2.
\sa decimals()
*/
void QtSizeFPropertyManager::setDecimals(QtProperty *property, int prec)
{
const QtSizeFPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property);
if (it == d_ptr->m_values.end())
return;
QtSizeFPropertyManagerPrivate::Data data = it.value();
if (prec > 13)
prec = 13;
else if (prec < 0)
prec = 0;
if (data.decimals == prec)
return;
data.decimals = prec;
d_ptr->m_doublePropertyManager->setDecimals(d_ptr->m_propertyToW[property], prec);
d_ptr->m_doublePropertyManager->setDecimals(d_ptr->m_propertyToH[property], prec);
emit decimalsChanged(property, data.decimals);
}
/**
Sets the minimum size value for the given \a property to \a minVal.
When setting the minimum size value, the maximum and current
values are adjusted if necessary (ensuring that the size range
remains valid and that the current value is within the range).
\sa minimum(), setRange(), rangeChanged()
*/
void QtSizeFPropertyManager::setMinimum(QtProperty *property, const QSizeF &minVal)
{
setBorderValue<const QSizeF &, QtSizeFPropertyManagerPrivate, QtSizeFPropertyManager, QSizeF, QtSizeFPropertyManagerPrivate::Data>(this, d_ptr,
&QtSizeFPropertyManager::propertyChanged,
&QtSizeFPropertyManager::valueChanged,
&QtSizeFPropertyManager::rangeChanged,
property,
&QtSizeFPropertyManagerPrivate::Data::minimumValue,
&QtSizeFPropertyManagerPrivate::Data::setMinimumValue,
minVal, &QtSizeFPropertyManagerPrivate::setRange);
}
/**
Sets the maximum size value for the given \a property to \a maxVal.
When setting the maximum size value, the minimum and current
values are adjusted if necessary (ensuring that the size range
remains valid and that the current value is within the range).
\sa maximum(), setRange(), rangeChanged()
*/
void QtSizeFPropertyManager::setMaximum(QtProperty *property, const QSizeF &maxVal)
{
setBorderValue<const QSizeF &, QtSizeFPropertyManagerPrivate, QtSizeFPropertyManager, QSizeF, QtSizeFPropertyManagerPrivate::Data>(this, d_ptr,
&QtSizeFPropertyManager::propertyChanged,
&QtSizeFPropertyManager::valueChanged,
&QtSizeFPropertyManager::rangeChanged,
property,
&QtSizeFPropertyManagerPrivate::Data::maximumValue,
&QtSizeFPropertyManagerPrivate::Data::setMaximumValue,
maxVal, &QtSizeFPropertyManagerPrivate::setRange);
\fn void QtSizeFPropertyManager::setRange(QtProperty *property, const QSizeF &minimum, const QSizeF &maximum)
Sets the range of valid values.
This is a convenience function defining the range of valid values
in one go; setting the \a minimum and \a maximum values for the
given \a property with a single function call.
When setting a new range, the current value is adjusted if
necessary (ensuring that the value remains within the range).
\sa setMinimum(), setMaximum(), rangeChanged()
*/
void QtSizeFPropertyManager::setRange(QtProperty *property, const QSizeF &minVal, const QSizeF &maxVal)
{
setBorderValues<const QSizeF &, QtSizeFPropertyManagerPrivate, QtSizeFPropertyManager, QSizeF>(this, d_ptr,
&QtSizeFPropertyManager::propertyChanged,
&QtSizeFPropertyManager::valueChanged,
&QtSizeFPropertyManager::rangeChanged,
property, minVal, maxVal, &QtSizeFPropertyManagerPrivate::setRange);
void QtSizeFPropertyManager::initializeProperty(QtProperty *property)
{
d_ptr->m_values[property] = QtSizeFPropertyManagerPrivate::Data();
QtProperty *wProp = d_ptr->m_doublePropertyManager->addProperty();
wProp->setPropertyName(tr("Width"));
d_ptr->m_doublePropertyManager->setDecimals(wProp, decimals(property));
d_ptr->m_doublePropertyManager->setValue(wProp, 0);
d_ptr->m_doublePropertyManager->setMinimum(wProp, 0);
d_ptr->m_propertyToW[property] = wProp;
d_ptr->m_wToProperty[wProp] = property;
property->addSubProperty(wProp);
QtProperty *hProp = d_ptr->m_doublePropertyManager->addProperty();
hProp->setPropertyName(tr("Height"));
d_ptr->m_doublePropertyManager->setDecimals(hProp, decimals(property));
d_ptr->m_doublePropertyManager->setValue(hProp, 0);
d_ptr->m_doublePropertyManager->setMinimum(hProp, 0);
d_ptr->m_propertyToH[property] = hProp;
d_ptr->m_hToProperty[hProp] = property;
property->addSubProperty(hProp);
void QtSizeFPropertyManager::uninitializeProperty(QtProperty *property)
{
QtProperty *wProp = d_ptr->m_propertyToW[property];
if (wProp) {
d_ptr->m_wToProperty.remove(wProp);
delete wProp;
}
d_ptr->m_propertyToW.remove(property);
QtProperty *hProp = d_ptr->m_propertyToH[property];
if (hProp) {
d_ptr->m_hToProperty.remove(hProp);
delete hProp;
}
d_ptr->m_propertyToH.remove(property);
d_ptr->m_values.remove(property);
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
void QtRectPropertyManagerPrivate::slotIntChanged(QtProperty *property, int value)
{
if (QtProperty *prop = m_xToProperty.value(property, 0)) {
QRect r = m_values[prop].val;
r.moveLeft(value);
q_ptr->setValue(prop, r);
} else if (QtProperty *prop = m_yToProperty.value(property)) {
QRect r = m_values[prop].val;
r.moveTop(value);
q_ptr->setValue(prop, r);
} else if (QtProperty *prop = m_wToProperty.value(property, 0)) {
Data data = m_values[prop];
QRect r = data.val;
r.setWidth(value);
if (!data.constraint.isNull() && data.constraint.x() + data.constraint.width() < r.x() + r.width()) {
r.moveLeft(data.constraint.left() + data.constraint.width() - r.width());
}
q_ptr->setValue(prop, r);
} else if (QtProperty *prop = m_hToProperty.value(property, 0)) {
Data data = m_values[prop];
QRect r = data.val;
r.setHeight(value);
if (!data.constraint.isNull() && data.constraint.y() + data.constraint.height() < r.y() + r.height()) {
r.moveTop(data.constraint.top() + data.constraint.height() - r.height());
}
q_ptr->setValue(prop, r);
}
void QtRectPropertyManagerPrivate::slotPropertyDestroyed(QtProperty *property)
{
if (QtProperty *pointProp = m_xToProperty.value(property, 0)) {
m_propertyToX[pointProp] = 0;
m_xToProperty.remove(property);
} else if (QtProperty *pointProp = m_yToProperty.value(property, 0)) {
m_propertyToY[pointProp] = 0;
m_yToProperty.remove(property);
} else if (QtProperty *pointProp = m_wToProperty.value(property, 0)) {
m_propertyToW[pointProp] = 0;
m_wToProperty.remove(property);
} else if (QtProperty *pointProp = m_hToProperty.value(property, 0)) {
m_propertyToH[pointProp] = 0;
m_hToProperty.remove(property);
}
}
void QtRectPropertyManagerPrivate::setConstraint(QtProperty *property,
const QRect &constraint, const QRect &val)
{
const bool isNull = constraint.isNull();
const int left = isNull ? INT_MIN : constraint.left();
const int right = isNull ? INT_MAX : constraint.left() + constraint.width();
const int top = isNull ? INT_MIN : constraint.top();
const int bottom = isNull ? INT_MAX : constraint.top() + constraint.height();
const int width = isNull ? INT_MAX : constraint.width();
const int height = isNull ? INT_MAX : constraint.height();
m_intPropertyManager->setRange(m_propertyToX[property], left, right);
m_intPropertyManager->setRange(m_propertyToY[property], top, bottom);
m_intPropertyManager->setRange(m_propertyToW[property], 0, width);
m_intPropertyManager->setRange(m_propertyToH[property], 0, height);
m_intPropertyManager->setValue(m_propertyToX[property], val.x());
m_intPropertyManager->setValue(m_propertyToY[property], val.y());
m_intPropertyManager->setValue(m_propertyToW[property], val.width());
m_intPropertyManager->setValue(m_propertyToH[property], val.height());
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
}
/**
\class QtRectPropertyManager
\brief The QtRectPropertyManager provides and manages QRect properties.
A rectangle property has nested \e x, \e y, \e width and \e height
subproperties. The top-level property's value can be retrieved
using the value() function, and set using the setValue() slot.
The subproperties are created by a QtIntPropertyManager object. This
manager can be retrieved using the subIntPropertyManager() function. In
order to provide editing widgets for the subproperties in a
property browser widget, this manager must be associated with an
editor factory.
A rectangle property also has a constraint rectangle which can be
retrieved using the constraint() function, and set using the
setConstraint() slot.
In addition, QtRectPropertyManager provides the valueChanged() signal
which is emitted whenever a property created by this manager
changes, and the constraintChanged() signal which is emitted
whenever such a property changes its constraint rectangle.
\sa QtAbstractPropertyManager, QtIntPropertyManager, QtRectFPropertyManager
*/
/**
\fn void QtRectPropertyManager::valueChanged(QtProperty *property, const QRect &value)
This signal is emitted whenever a property created by this manager
changes its value, passing a pointer to the \a property and the new
\a value as parameters.
\sa setValue()
*/
/**
\fn void QtRectPropertyManager::constraintChanged(QtProperty *property, const QRect &constraint)
This signal is emitted whenever property changes its constraint
rectangle, passing a pointer to the \a property and the new \a
constraint rectangle as parameters.
\sa setConstraint()
*/
/**
Creates a manager with the given \a parent.
*/
QtRectPropertyManager::QtRectPropertyManager(QObject *parent)
: QtAbstractPropertyManager(parent)
{
d_ptr = new QtRectPropertyManagerPrivate;
d_ptr->q_ptr = this;
d_ptr->m_intPropertyManager = new QtIntPropertyManager(this);
connect(d_ptr->m_intPropertyManager, SIGNAL(valueChanged(QtProperty *, int)),
this, SLOT(slotIntChanged(QtProperty *, int)));
connect(d_ptr->m_intPropertyManager, SIGNAL(propertyDestroyed(QtProperty *)),
this, SLOT(slotPropertyDestroyed(QtProperty *)));
}
/**
Destroys this manager, and all the properties it has created.
*/
QtRectPropertyManager::~QtRectPropertyManager()
{
clear();
delete d_ptr;
}
/**
Returns the manager that creates the nested \e x, \e y, \e width
and \e height subproperties.
In order to provide editing widgets for the mentioned
subproperties in a property browser widget, this manager must be
associated with an editor factory.
\sa QtAbstractPropertyBrowser::setFactoryForManager()
*/
QtIntPropertyManager *QtRectPropertyManager::subIntPropertyManager() const
{
return d_ptr->m_intPropertyManager;
}
/**
Returns the given \a property's value.
If the given \a property is not managed by this manager, this
function returns an invalid rectangle.
\sa setValue(), constraint()
*/
QRect QtRectPropertyManager::value(const QtProperty *property) const
{
return getValue<QRect>(d_ptr->m_values, property);
Returns the given \a property's constraining rectangle. If returned value is null QRect it means there is no constraint applied.
QRect QtRectPropertyManager::constraint(const QtProperty *property) const
{
return getData<QRect>(d_ptr->m_values, &QtRectPropertyManagerPrivate::Data::constraint, property, QRect());
QString QtRectPropertyManager::valueText(const QtProperty *property) const
{
const QtRectPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property);
if (it == d_ptr->m_values.constEnd())
return QString();
const QRect v = it.value().val;
return QString(tr("[(%1, %2), %3 x %4]").arg(QString::number(v.x()))
.arg(QString::number(v.y()))
.arg(QString::number(v.width()))
.arg(QString::number(v.height())));
\fn void QtRectPropertyManager::setValue(QtProperty *property, const QRect &value)
Sets the value of the given \a property to \a value. Nested
properties are updated automatically.
If the specified \a value is not inside the given \a property's
constraining rectangle, the value is adjusted accordingly to fit
within the constraint.
\sa value(), setConstraint(), valueChanged()
*/
void QtRectPropertyManager::setValue(QtProperty *property, const QRect &val)
{
const QtRectPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property);
if (it == d_ptr->m_values.end())
return;
QtRectPropertyManagerPrivate::Data data = it.value();
QRect newRect = val.normalized();
if (!data.constraint.isNull() && !data.constraint.contains(newRect)) {
const QRect r1 = data.constraint;
const QRect r2 = newRect;
newRect.setLeft(qMax(r1.left(), r2.left()));
newRect.setRight(qMin(r1.right(), r2.right()));
newRect.setTop(qMax(r1.top(), r2.top()));
newRect.setBottom(qMin(r1.bottom(), r2.bottom()));
if (newRect.width() < 0 || newRect.height() < 0)
return;
}
if (data.val == newRect)
return;
it.value() = data;
d_ptr->m_intPropertyManager->setValue(d_ptr->m_propertyToX[property], newRect.x());
d_ptr->m_intPropertyManager->setValue(d_ptr->m_propertyToY[property], newRect.y());
d_ptr->m_intPropertyManager->setValue(d_ptr->m_propertyToW[property], newRect.width());
d_ptr->m_intPropertyManager->setValue(d_ptr->m_propertyToH[property], newRect.height());
emit propertyChanged(property);
emit valueChanged(property, data.val);
}
/**
Sets the given \a property's constraining rectangle to \a
constraint.
When setting the constraint, the current value is adjusted if
necessary (ensuring that the current rectangle value is inside the
constraint). In order to reset the constraint pass a null QRect value.
\sa setValue(), constraint(), constraintChanged()
*/
void QtRectPropertyManager::setConstraint(QtProperty *property, const QRect &constraint)
{
const QtRectPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property);
if (it == d_ptr->m_values.end())
return;
QtRectPropertyManagerPrivate::Data data = it.value();
QRect newConstraint = constraint.normalized();
if (data.constraint == newConstraint)
return;
const QRect oldVal = data.val;
data.constraint = newConstraint;
if (!data.constraint.isNull() && !data.constraint.contains(oldVal)) {
QRect r1 = data.constraint;
QRect r2 = data.val;
if (r2.width() > r1.width())
r2.setWidth(r1.width());
if (r2.height() > r1.height())
r2.setHeight(r1.height());
if (r2.left() < r1.left())
r2.moveLeft(r1.left());
else if (r2.right() > r1.right())
r2.moveRight(r1.right());
if (r2.top() < r1.top())
r2.moveTop(r1.top());
else if (r2.bottom() > r1.bottom())
r2.moveBottom(r1.bottom());
emit constraintChanged(property, data.constraint);
d_ptr->setConstraint(property, data.constraint, data.val);
if (data.val == oldVal)
return;
emit propertyChanged(property);
emit valueChanged(property, data.val);
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
void QtRectPropertyManager::initializeProperty(QtProperty *property)
{
d_ptr->m_values[property] = QtRectPropertyManagerPrivate::Data();
QtProperty *xProp = d_ptr->m_intPropertyManager->addProperty();
xProp->setPropertyName(tr("X"));
d_ptr->m_intPropertyManager->setValue(xProp, 0);
d_ptr->m_propertyToX[property] = xProp;
d_ptr->m_xToProperty[xProp] = property;
property->addSubProperty(xProp);
QtProperty *yProp = d_ptr->m_intPropertyManager->addProperty();
yProp->setPropertyName(tr("Y"));
d_ptr->m_intPropertyManager->setValue(yProp, 0);
d_ptr->m_propertyToY[property] = yProp;
d_ptr->m_yToProperty[yProp] = property;
property->addSubProperty(yProp);
QtProperty *wProp = d_ptr->m_intPropertyManager->addProperty();
wProp->setPropertyName(tr("Width"));
d_ptr->m_intPropertyManager->setValue(wProp, 0);
d_ptr->m_intPropertyManager->setMinimum(wProp, 0);
d_ptr->m_propertyToW[property] = wProp;
d_ptr->m_wToProperty[wProp] = property;
property->addSubProperty(wProp);
QtProperty *hProp = d_ptr->m_intPropertyManager->addProperty();
hProp->setPropertyName(tr("Height"));
d_ptr->m_intPropertyManager->setValue(hProp, 0);
d_ptr->m_intPropertyManager->setMinimum(hProp, 0);
d_ptr->m_propertyToH[property] = hProp;
d_ptr->m_hToProperty[hProp] = property;
property->addSubProperty(hProp);
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
void QtRectPropertyManager::uninitializeProperty(QtProperty *property)
{
QtProperty *xProp = d_ptr->m_propertyToX[property];
if (xProp) {
d_ptr->m_xToProperty.remove(xProp);
delete xProp;
}
d_ptr->m_propertyToX.remove(property);
QtProperty *yProp = d_ptr->m_propertyToY[property];
if (yProp) {
d_ptr->m_yToProperty.remove(yProp);
delete yProp;
}
d_ptr->m_propertyToY.remove(property);
QtProperty *wProp = d_ptr->m_propertyToW[property];
if (wProp) {
d_ptr->m_wToProperty.remove(wProp);
delete wProp;
}
d_ptr->m_propertyToW.remove(property);
QtProperty *hProp = d_ptr->m_propertyToH[property];
if (hProp) {
d_ptr->m_hToProperty.remove(hProp);
delete hProp;
}
d_ptr->m_propertyToH.remove(property);
d_ptr->m_values.remove(property);
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
void QtRectFPropertyManagerPrivate::slotDoubleChanged(QtProperty *property, double value)
{
if (QtProperty *prop = m_xToProperty.value(property, 0)) {
QRectF r = m_values[prop].val;
r.moveLeft(value);
q_ptr->setValue(prop, r);
} else if (QtProperty *prop = m_yToProperty.value(property, 0)) {
QRectF r = m_values[prop].val;
r.moveTop(value);
q_ptr->setValue(prop, r);
} else if (QtProperty *prop = m_wToProperty.value(property, 0)) {
Data data = m_values[prop];
QRectF r = data.val;
r.setWidth(value);
if (!data.constraint.isNull() && data.constraint.x() + data.constraint.width() < r.x() + r.width()) {
r.moveLeft(data.constraint.left() + data.constraint.width() - r.width());
}
q_ptr->setValue(prop, r);
} else if (QtProperty *prop = m_hToProperty.value(property, 0)) {
Data data = m_values[prop];
QRectF r = data.val;
r.setHeight(value);
if (!data.constraint.isNull() && data.constraint.y() + data.constraint.height() < r.y() + r.height()) {
r.moveTop(data.constraint.top() + data.constraint.height() - r.height());
}
q_ptr->setValue(prop, r);
}
void QtRectFPropertyManagerPrivate::slotPropertyDestroyed(QtProperty *property)
{
if (QtProperty *pointProp = m_xToProperty.value(property, 0)) {
m_propertyToX[pointProp] = 0;
m_xToProperty.remove(property);
} else if (QtProperty *pointProp = m_yToProperty.value(property, 0)) {
m_propertyToY[pointProp] = 0;
m_yToProperty.remove(property);
} else if (QtProperty *pointProp = m_wToProperty.value(property, 0)) {
m_propertyToW[pointProp] = 0;
m_wToProperty.remove(property);
} else if (QtProperty *pointProp = m_hToProperty.value(property, 0)) {
m_propertyToH[pointProp] = 0;
m_hToProperty.remove(property);
}
}
void QtRectFPropertyManagerPrivate::setConstraint(QtProperty *property,
const QRectF &constraint, const QRectF &val)
{
const bool isNull = constraint.isNull();
const qreal left = isNull ? FLT_MIN : constraint.left();
const qreal right = isNull ? FLT_MAX : constraint.left() + constraint.width();
const qreal top = isNull ? FLT_MIN : constraint.top();
const qreal bottom = isNull ? FLT_MAX : constraint.top() + constraint.height();
const qreal width = isNull ? FLT_MAX : constraint.width();
const qreal height = isNull ? FLT_MAX : constraint.height();
m_doublePropertyManager->setRange(m_propertyToX[property], left, right);
m_doublePropertyManager->setRange(m_propertyToY[property], top, bottom);
m_doublePropertyManager->setRange(m_propertyToW[property], 0, width);
m_doublePropertyManager->setRange(m_propertyToH[property], 0, height);
m_doublePropertyManager->setValue(m_propertyToX[property], val.x());
m_doublePropertyManager->setValue(m_propertyToY[property], val.y());
m_doublePropertyManager->setValue(m_propertyToW[property], val.width());
m_doublePropertyManager->setValue(m_propertyToH[property], val.height());
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
}
/**
\class QtRectFPropertyManager
\brief The QtRectFPropertyManager provides and manages QRectF properties.
A rectangle property has nested \e x, \e y, \e width and \e height
subproperties. The top-level property's value can be retrieved
using the value() function, and set using the setValue() slot.
The subproperties are created by a QtDoublePropertyManager object. This
manager can be retrieved using the subDoublePropertyManager() function. In
order to provide editing widgets for the subproperties in a
property browser widget, this manager must be associated with an
editor factory.
A rectangle property also has a constraint rectangle which can be
retrieved using the constraint() function, and set using the
setConstraint() slot.
In addition, QtRectFPropertyManager provides the valueChanged() signal
which is emitted whenever a property created by this manager
changes, and the constraintChanged() signal which is emitted
whenever such a property changes its constraint rectangle.
\sa QtAbstractPropertyManager, QtDoublePropertyManager, QtRectPropertyManager
\fn void QtRectFPropertyManager::valueChanged(QtProperty *property, const QRectF &value)
This signal is emitted whenever a property created by this manager
changes its value, passing a pointer to the \a property and the new
\a value as parameters.
\sa setValue()
*/
/**
\fn void QtRectFPropertyManager::constraintChanged(QtProperty *property, const QRectF &constraint)
This signal is emitted whenever property changes its constraint
rectangle, passing a pointer to the \a property and the new \a
constraint rectangle as parameters.
\sa setConstraint()
*/
/**
\fn void QtRectFPropertyManager::decimalsChanged(QtProperty *property, int prec)
This signal is emitted whenever a property created by this manager
changes its precision of value, passing a pointer to the
\a property and the new \a prec value
\sa setDecimals()
*/
/**
Creates a manager with the given \a parent.
*/
QtRectFPropertyManager::QtRectFPropertyManager(QObject *parent)
: QtAbstractPropertyManager(parent)
{
d_ptr = new QtRectFPropertyManagerPrivate;
d_ptr->q_ptr = this;
d_ptr->m_doublePropertyManager = new QtDoublePropertyManager(this);
connect(d_ptr->m_doublePropertyManager, SIGNAL(valueChanged(QtProperty *, double)),
this, SLOT(slotDoubleChanged(QtProperty *, double)));
connect(d_ptr->m_doublePropertyManager, SIGNAL(propertyDestroyed(QtProperty *)),
this, SLOT(slotPropertyDestroyed(QtProperty *)));
}
/**
Destroys this manager, and all the properties it has created.
*/
QtRectFPropertyManager::~QtRectFPropertyManager()
{
clear();
delete d_ptr;
}
/**
Returns the manager that creates the nested \e x, \e y, \e width
and \e height subproperties.
In order to provide editing widgets for the mentioned
subproperties in a property browser widget, this manager must be
associated with an editor factory.
\sa QtAbstractPropertyBrowser::setFactoryForManager()
*/
QtDoublePropertyManager *QtRectFPropertyManager::subDoublePropertyManager() const
{
return d_ptr->m_doublePropertyManager;
}
/**
Returns the given \a property's value.
If the given \a property is not managed by this manager, this
function returns an invalid rectangle.
\sa setValue(), constraint()
*/
QRectF QtRectFPropertyManager::value(const QtProperty *property) const
{
return getValue<QRectF>(d_ptr->m_values, property);
}
/**
Returns the given \a property's precision, in decimals.
\sa setDecimals()
*/
int QtRectFPropertyManager::decimals(const QtProperty *property) const
{
return getData<int>(d_ptr->m_values, &QtRectFPropertyManagerPrivate::Data::decimals, property, 0);
Returns the given \a property's constraining rectangle. If returned value is null QRectF it means there is no constraint applied.
QRectF QtRectFPropertyManager::constraint(const QtProperty *property) const
{
return getData<QRectF>(d_ptr->m_values, &QtRectFPropertyManagerPrivate::Data::constraint, property, QRect());
QString QtRectFPropertyManager::valueText(const QtProperty *property) const
{
const QtRectFPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property);
if (it == d_ptr->m_values.constEnd())
return QString();
const QRectF v = it.value().val;
const int dec = it.value().decimals;
return QString(tr("[(%1, %2), %3 x %4]").arg(QString::number(v.x(), 'f', dec))
.arg(QString::number(v.y(), 'f', dec))
.arg(QString::number(v.width(), 'f', dec))
.arg(QString::number(v.height(), 'f', dec)));
\fn void QtRectFPropertyManager::setValue(QtProperty *property, const QRectF &value)
Sets the value of the given \a property to \a value. Nested
properties are updated automatically.
If the specified \a value is not inside the given \a property's
constraining rectangle, the value is adjusted accordingly to fit
within the constraint.
\sa value(), setConstraint(), valueChanged()
*/
void QtRectFPropertyManager::setValue(QtProperty *property, const QRectF &val)
{
const QtRectFPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property);
if (it == d_ptr->m_values.end())
return;
QtRectFPropertyManagerPrivate::Data data = it.value();
QRectF newRect = val.normalized();
if (!data.constraint.isNull() && !data.constraint.contains(newRect)) {
const QRectF r1 = data.constraint;
const QRectF r2 = newRect;
newRect.setLeft(qMax(r1.left(), r2.left()));
newRect.setRight(qMin(r1.right(), r2.right()));
newRect.setTop(qMax(r1.top(), r2.top()));
newRect.setBottom(qMin(r1.bottom(), r2.bottom()));
if (newRect.width() < 0 || newRect.height() < 0)
return;
}
if (data.val == newRect)
return;
it.value() = data;
d_ptr->m_doublePropertyManager->setValue(d_ptr->m_propertyToX[property], newRect.x());
d_ptr->m_doublePropertyManager->setValue(d_ptr->m_propertyToY[property], newRect.y());
d_ptr->m_doublePropertyManager->setValue(d_ptr->m_propertyToW[property], newRect.width());
d_ptr->m_doublePropertyManager->setValue(d_ptr->m_propertyToH[property], newRect.height());
emit propertyChanged(property);
emit valueChanged(property, data.val);
}
/**
Sets the given \a property's constraining rectangle to \a
constraint.
When setting the constraint, the current value is adjusted if
necessary (ensuring that the current rectangle value is inside the
constraint). In order to reset the constraint pass a null QRectF value.
\sa setValue(), constraint(), constraintChanged()
*/
void QtRectFPropertyManager::setConstraint(QtProperty *property, const QRectF &constraint)
{
const QtRectFPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property);
if (it == d_ptr->m_values.end())
return;
QtRectFPropertyManagerPrivate::Data data = it.value();
QRectF newConstraint = constraint.normalized();
if (data.constraint == newConstraint)
return;
const QRectF oldVal = data.val;
data.constraint = newConstraint;
if (!data.constraint.isNull() && !data.constraint.contains(oldVal)) {
QRectF r1 = data.constraint;
QRectF r2 = data.val;
if (r2.width() > r1.width())
r2.setWidth(r1.width());
if (r2.height() > r1.height())
r2.setHeight(r1.height());
if (r2.left() < r1.left())
r2.moveLeft(r1.left());
else if (r2.right() > r1.right())
r2.moveRight(r1.right());
if (r2.top() < r1.top())
r2.moveTop(r1.top());
else if (r2.bottom() > r1.bottom())
r2.moveBottom(r1.bottom());
emit constraintChanged(property, data.constraint);