diff options
-rw-r--r-- | examples/declarative/aspectratio/face_fit.qml | 26 | ||||
-rw-r--r-- | examples/declarative/aspectratio/face_fit_animated.qml | 28 | ||||
-rw-r--r-- | examples/declarative/aspectratio/pics/face.png | bin | 0 -> 905 bytes | |||
-rw-r--r-- | examples/declarative/aspectratio/scale_and_crop.qml | 21 | ||||
-rw-r--r-- | examples/declarative/aspectratio/scale_and_sidecrop.qml | 22 | ||||
-rw-r--r-- | examples/declarative/aspectratio/scale_to_fit.qml | 21 | ||||
-rw-r--r-- | src/declarative/util/qmlfollow.cpp | 29 | ||||
-rw-r--r-- | src/declarative/util/qmlfollow.h | 3 |
8 files changed, 148 insertions, 2 deletions
diff --git a/examples/declarative/aspectratio/face_fit.qml b/examples/declarative/aspectratio/face_fit.qml new file mode 100644 index 0000000..35c63ce --- /dev/null +++ b/examples/declarative/aspectratio/face_fit.qml @@ -0,0 +1,26 @@ +// The Image primitive does not have any special handling for maintaining +// aspect ratio. This example shows that you can provide whatever specific +// behaviour you like. +// +// Here, we implement a hybrid of the "scale to fit" and "scale and crop" +// behaviours which will crop up to 25% from *one* dimension if necessary +// to fully scale the other. This is a realistic algorithm, for example +// when the edges of the image contain less vital information than the +// center - such as a face. +// +Rect { + // default size: whole image, unscaled + width: Image.width + height: Image.height + color: "gray" + clip: true + + Image { + id: Image + source: "pics/face.png" + x: (parent.width-width*scale)/2 + y: (parent.height-height*scale)/2 + scale: Math.max(Math.min(parent.width/width*1.333,parent.height/height), + Math.min(parent.width/width,parent.height/height*1.333)) + } +} diff --git a/examples/declarative/aspectratio/face_fit_animated.qml b/examples/declarative/aspectratio/face_fit_animated.qml new file mode 100644 index 0000000..366d27b --- /dev/null +++ b/examples/declarative/aspectratio/face_fit_animated.qml @@ -0,0 +1,28 @@ +// The Image primitive does not have any special handling for maintaining +// aspect ratio. This example shows that you can provide whatever specific +// behaviour you like. +// +// Here, we extend the "face_fit" example with animation to show how truly +// diverse and usage-specific behaviours are made possible by NOT putting a +// hard-coded aspect ratio feature into the Image primitive. +// +Rect { + // default size: whole image, unscaled + width: Image.width + height: Image.height + color: "gray" + clip: true + + Image { + id: Image + source: "pics/face.png" + x: (parent.width-width*scale)/2 + y: (parent.height-height*scale)/2 + scale: Follow { + source: Math.max(Math.min(Image.parent.width/Image.width*1.333,Image.parent.height/Image.height), + Math.min(Image.parent.width/Image.width,Image.parent.height/Image.height*1.333)) + spring: 1 + damping: 0.05 + } + } +} diff --git a/examples/declarative/aspectratio/pics/face.png b/examples/declarative/aspectratio/pics/face.png Binary files differnew file mode 100644 index 0000000..9623b1a --- /dev/null +++ b/examples/declarative/aspectratio/pics/face.png diff --git a/examples/declarative/aspectratio/scale_and_crop.qml b/examples/declarative/aspectratio/scale_and_crop.qml new file mode 100644 index 0000000..a5409f9 --- /dev/null +++ b/examples/declarative/aspectratio/scale_and_crop.qml @@ -0,0 +1,21 @@ +// The Image primitive does not have any special handling for maintaining +// aspect ratio. This example shows that you can provide whatever specific +// behaviour you like. +// +// Here, we implement "Scale and Crop" behaviour. +// +Rect { + // default size: whole image, unscaled + width: Image.width + height: Image.height + color: "gray" + clip: true + + Image { + id: Image + source: "pics/face.png" + x: (parent.width-width*scale)/2 + y: (parent.height-height*scale)/2 + scale: Math.max(parent.width/width,parent.height/height) + } +} diff --git a/examples/declarative/aspectratio/scale_and_sidecrop.qml b/examples/declarative/aspectratio/scale_and_sidecrop.qml new file mode 100644 index 0000000..e076735 --- /dev/null +++ b/examples/declarative/aspectratio/scale_and_sidecrop.qml @@ -0,0 +1,22 @@ +// The Image primitive does not have any special handling for maintaining +// aspect ratio. This example shows that you can provide whatever specific +// behaviour you like. +// +// Here, we implement a variant of "Scale and Crop" behaviour, where we +// crop the sides if necessary to fully fit vertically, but not the reverse. +// +Rect { + // default size: whole image, unscaled + width: Image.width + height: Image.height + color: "gray" + clip: true + + Image { + id: Image + source: "pics/face.png" + x: (parent.width-width*scale)/2 + y: (parent.height-height*scale)/2 + scale: parent.height/height + } +} diff --git a/examples/declarative/aspectratio/scale_to_fit.qml b/examples/declarative/aspectratio/scale_to_fit.qml new file mode 100644 index 0000000..61a4082 --- /dev/null +++ b/examples/declarative/aspectratio/scale_to_fit.qml @@ -0,0 +1,21 @@ +// The Image primitive does not have any special handling for maintaining +// aspect ratio. This example shows that you can provide whatever specific +// behaviour you like. +// +// Here, we implement "Scale to Fit" behaviour. +// +Rect { + // default size: whole image, unscaled + width: Image.width + height: Image.height + color: "gray" + clip: true + + Image { + id: Image + source: "pics/face.png" + x: (parent.width-width*scale)/2 + y: (parent.height-height*scale)/2 + scale: Math.min(parent.width/width,parent.height/height) + } +} diff --git a/src/declarative/util/qmlfollow.cpp b/src/declarative/util/qmlfollow.cpp index 998166a..8e5ae69 100644 --- a/src/declarative/util/qmlfollow.cpp +++ b/src/declarative/util/qmlfollow.cpp @@ -55,7 +55,7 @@ class QmlFollowPrivate : public QObjectPrivate public: QmlFollowPrivate() : sourceValue(0), maxVelocity(0), lastTime(0) - , mass(1.0), spring(0.), damping(0.), velocity(0), enabled(true), mode(Track), clock(this) {} + , mass(1.0), spring(0.), damping(0.), velocity(0), epsilon(0.005), enabled(true), mode(Track), clock(this) {} QmlMetaProperty property; qreal currentValue; @@ -67,6 +67,7 @@ public: qreal spring; qreal damping; qreal velocity; + qreal epsilon; bool enabled; enum Mode { @@ -111,7 +112,7 @@ void QmlFollowPrivate::tick(int time) } currentValue += velocity * 10.0 / 1000.0; } - if (qAbs(velocity) < 0.5 && qAbs(sourceValue - currentValue) < 0.5) { + if (qAbs(velocity) < epsilon && qAbs(sourceValue - currentValue) < epsilon) { velocity = 0.0; currentValue = sourceValue; clock.stop(); @@ -300,6 +301,30 @@ void QmlFollow::setDamping(qreal damping) d->damping = damping; } + +/*! + \qmlproperty qreal Follow::epsilon + This property holds the spring epsilon + + The epsilon is the rate and amount of change in the value which is close enough + to 0 to be considered equal to zero. This will depend on the usage of the value. + For pixel positions, 0.25 would suffice. For scale, 0.005 will suffice. + + The default is 0.005. Small performance improvements can result in tuning this + value. +*/ +qreal QmlFollow::epsilon() const +{ + Q_D(const QmlFollow); + return d->epsilon; +} + +void QmlFollow::setEpsilon(qreal epsilon) +{ + Q_D(QmlFollow); + d->epsilon = epsilon; +} + /*! \qmlproperty qreal Follow::followValue The current value. diff --git a/src/declarative/util/qmlfollow.h b/src/declarative/util/qmlfollow.h index aac4c01..bd9363a 100644 --- a/src/declarative/util/qmlfollow.h +++ b/src/declarative/util/qmlfollow.h @@ -63,6 +63,7 @@ class Q_DECLARATIVE_EXPORT QmlFollow : public QmlPropertyValueSource, Q_PROPERTY(qreal velocity READ velocity WRITE setVelocity); Q_PROPERTY(qreal spring READ spring WRITE setSpring); Q_PROPERTY(qreal damping READ damping WRITE setDamping); + Q_PROPERTY(qreal epsilon READ epsilon WRITE setEpsilon); Q_PROPERTY(bool enabled READ enabled WRITE setEnabled); Q_PROPERTY(qreal followValue READ value NOTIFY valueChanged); @@ -80,6 +81,8 @@ public: void setSpring(qreal spring); qreal damping() const; void setDamping(qreal damping); + qreal epsilon() const; + void setEpsilon(qreal epsilon); bool enabled() const; void setEnabled(bool enabled); |