aboutsummaryrefslogtreecommitdiffstats
path: root/src/quicktemplates2/qquickscrollbar.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/quicktemplates2/qquickscrollbar.cpp')
-rw-r--r--src/quicktemplates2/qquickscrollbar.cpp474
1 files changed, 351 insertions, 123 deletions
diff --git a/src/quicktemplates2/qquickscrollbar.cpp b/src/quicktemplates2/qquickscrollbar.cpp
index c17b3be6..3dcb720a 100644
--- a/src/quicktemplates2/qquickscrollbar.cpp
+++ b/src/quicktemplates2/qquickscrollbar.cpp
@@ -35,11 +35,11 @@
****************************************************************************/
#include "qquickscrollbar_p.h"
-#include "qquickcontrol_p_p.h"
+#include "qquickscrollbar_p_p.h"
+#include "qquickscrollview_p.h"
#include <QtQml/qqmlinfo.h>
#include <QtQuick/private/qquickflickable_p.h>
-#include <QtQuick/private/qquickitemchangelistener_p.h>
QT_BEGIN_NAMESPACE
@@ -151,37 +151,36 @@ QT_BEGIN_NAMESPACE
\sa ScrollIndicator, {Customizing ScrollBar}, {Indicator Controls}
*/
-class QQuickScrollBarPrivate : public QQuickControlPrivate
-{
- Q_DECLARE_PUBLIC(QQuickScrollBar)
+static const QQuickItemPrivate::ChangeTypes changeTypes = QQuickItemPrivate::Geometry | QQuickItemPrivate::Destroyed;
+static const QQuickItemPrivate::ChangeTypes horizontalChangeTypes = changeTypes | QQuickItemPrivate::ImplicitHeight;
+static const QQuickItemPrivate::ChangeTypes verticalChangeTypes = changeTypes | QQuickItemPrivate::ImplicitWidth;
-public:
- QQuickScrollBarPrivate() : size(0), position(0), stepSize(0), offset(0),
- active(false), pressed(false), moving(false),
- orientation(Qt::Vertical)
- {
- }
+QQuickScrollBarPrivate::QQuickScrollBarPrivate()
+ : size(0),
+ position(0),
+ stepSize(0),
+ offset(0),
+ active(false),
+ pressed(false),
+ moving(false),
+ interactive(true),
+ explicitInteractive(false),
+ orientation(Qt::Vertical),
+ snapMode(QQuickScrollBar::NoSnap),
+ policy(QQuickScrollBar::AsNeeded)
+{
+}
- static QQuickScrollBarPrivate *get(QQuickScrollBar *bar)
- {
- return bar->d_func();
- }
+qreal QQuickScrollBarPrivate::snapPosition(qreal position) const
+{
+ const qreal effectiveStep = stepSize * (1.0 - size);
+ if (qFuzzyIsNull(effectiveStep))
+ return position;
- qreal positionAt(const QPoint &point) const;
- void updateActive();
- void resizeContent() override;
-
- qreal size;
- qreal position;
- qreal stepSize;
- qreal offset;
- bool active;
- bool pressed;
- bool moving;
- Qt::Orientation orientation;
-};
+ return qRound(position / effectiveStep) * effectiveStep;
+}
-qreal QQuickScrollBarPrivate::positionAt(const QPoint &point) const
+qreal QQuickScrollBarPrivate::positionAt(const QPointF &point) const
{
Q_Q(const QQuickScrollBar);
if (orientation == Qt::Horizontal)
@@ -190,10 +189,28 @@ qreal QQuickScrollBarPrivate::positionAt(const QPoint &point) const
return (point.y() - q->topPadding()) / q->availableHeight();
}
+void QQuickScrollBarPrivate::setInteractive(bool enabled)
+{
+ Q_Q(QQuickScrollBar);
+ if (interactive == enabled)
+ return;
+
+ interactive = enabled;
+ q->setAcceptedMouseButtons(interactive ? Qt::LeftButton : Qt::NoButton);
+ if (!interactive)
+ q->ungrabMouse();
+ emit q->interactiveChanged();
+}
+
void QQuickScrollBarPrivate::updateActive()
{
Q_Q(QQuickScrollBar);
- q->setActive(moving || pressed || hovered);
+#if QT_CONFIG(quicktemplates2_hover)
+ bool hover = hovered;
+#else
+ bool hover = false;
+#endif
+ q->setActive(moving || (interactive && (pressed || hover)));
}
void QQuickScrollBarPrivate::resizeContent()
@@ -202,17 +219,58 @@ void QQuickScrollBarPrivate::resizeContent()
if (!contentItem)
return;
+ // - negative overshoot (pos < 0): clamp the pos to 0, and deduct the overshoot from the size
+ // - positive overshoot (pos + size > 1): clamp the size to 1-pos
+ const qreal clampedSize = qBound<qreal>(0, size + qMin<qreal>(0, position), 1.0 - position);
+ const qreal clampedPos = qBound<qreal>(0, position, 1.0 - clampedSize);
+
if (orientation == Qt::Horizontal) {
- contentItem->setPosition(QPointF(q->leftPadding() + position * q->availableWidth(), q->topPadding()));
- contentItem->setSize(QSizeF(q->availableWidth() * size, q->availableHeight()));
+ contentItem->setPosition(QPointF(q->leftPadding() + clampedPos * q->availableWidth(), q->topPadding()));
+ contentItem->setSize(QSizeF(q->availableWidth() * clampedSize, q->availableHeight()));
} else {
- contentItem->setPosition(QPointF(q->leftPadding(), q->topPadding() + position * q->availableHeight()));
- contentItem->setSize(QSizeF(q->availableWidth(), q->availableHeight() * size));
+ contentItem->setPosition(QPointF(q->leftPadding(), q->topPadding() + clampedPos * q->availableHeight()));
+ contentItem->setSize(QSizeF(q->availableWidth(), q->availableHeight() * clampedSize));
}
}
-QQuickScrollBar::QQuickScrollBar(QQuickItem *parent) :
- QQuickControl(*(new QQuickScrollBarPrivate), parent)
+void QQuickScrollBarPrivate::handlePress(const QPointF &point)
+{
+ Q_Q(QQuickScrollBar);
+ offset = positionAt(point) - position;
+ if (offset < 0 || offset > size)
+ offset = size / 2;
+ q->setPressed(true);
+}
+
+void QQuickScrollBarPrivate::handleMove(const QPointF &point)
+{
+ Q_Q(QQuickScrollBar);
+ qreal pos = qBound<qreal>(0.0, positionAt(point) - offset, 1.0 - size);
+ if (snapMode == QQuickScrollBar::SnapAlways)
+ pos = snapPosition(pos);
+ q->setPosition(pos);
+}
+
+void QQuickScrollBarPrivate::handleRelease(const QPointF &point)
+{
+ Q_Q(QQuickScrollBar);
+ qreal pos = qBound<qreal>(0.0, positionAt(point) - offset, 1.0 - size);
+ if (snapMode != QQuickScrollBar::NoSnap)
+ pos = snapPosition(pos);
+ q->setPosition(pos);
+ offset = 0.0;
+ q->setPressed(false);
+}
+
+void QQuickScrollBarPrivate::handleUngrab()
+{
+ Q_Q(QQuickScrollBar);
+ offset = 0.0;
+ q->setPressed(false);
+}
+
+QQuickScrollBar::QQuickScrollBar(QQuickItem *parent)
+ : QQuickControl(*(new QQuickScrollBarPrivate), parent)
{
setKeepMouseGrab(true);
setAcceptedMouseButtons(Qt::LeftButton);
@@ -220,11 +278,7 @@ QQuickScrollBar::QQuickScrollBar(QQuickItem *parent) :
QQuickScrollBarAttached *QQuickScrollBar::qmlAttachedProperties(QObject *object)
{
- QQuickFlickable *flickable = qobject_cast<QQuickFlickable *>(object);
- if (!flickable)
- qmlInfo(object) << "ScrollBar must be attached to a Flickable";
-
- return new QQuickScrollBarAttached(flickable);
+ return new QQuickScrollBarAttached(object);
}
/*!
@@ -246,7 +300,6 @@ qreal QQuickScrollBar::size() const
void QQuickScrollBar::setSize(qreal size)
{
Q_D(QQuickScrollBar);
- size = qBound<qreal>(0.0, size, 1.0 - d->position);
if (qFuzzyCompare(d->size, size))
return;
@@ -275,7 +328,6 @@ qreal QQuickScrollBar::position() const
void QQuickScrollBar::setPosition(qreal position)
{
Q_D(QQuickScrollBar);
- position = qBound<qreal>(0.0, position, 1.0 - d->size);
if (qFuzzyCompare(d->position, position))
return;
@@ -290,7 +342,7 @@ void QQuickScrollBar::setPosition(qreal position)
This property holds the step size. The default value is \c 0.0.
- \sa increase(), decrease()
+ \sa snapMode, increase(), decrease()
*/
qreal QQuickScrollBar::stepSize() const
{
@@ -390,6 +442,107 @@ void QQuickScrollBar::setOrientation(Qt::Orientation orientation)
}
/*!
+ \since QtQuick.Controls 2.2
+ \qmlproperty enumeration QtQuick.Controls::ScrollBar::snapMode
+
+ This property holds the snap mode.
+
+ Possible values:
+ \value ScrollBar.NoSnap The scrollbar does not snap (default).
+ \value ScrollBar.SnapAlways The scrollbar snaps while dragged.
+ \value ScrollBar.SnapOnRelease The scrollbar does not snap while being dragged, but only after released.
+
+ In the following table, the various modes are illustrated with animations.
+ The movement and the \l stepSize (\c 0.25) are identical in each animation.
+
+ \table
+ \header
+ \row \li \b Value \li \b Example
+ \row \li \c ScrollBar.NoSnap \li \image qtquickcontrols2-scrollbar-nosnap.gif
+ \row \li \c ScrollBar.SnapAlways \li \image qtquickcontrols2-scrollbar-snapalways.gif
+ \row \li \c ScrollBar.SnapOnRelease \li \image qtquickcontrols2-scrollbar-snaponrelease.gif
+ \endtable
+
+ \sa stepSize
+*/
+QQuickScrollBar::SnapMode QQuickScrollBar::snapMode() const
+{
+ Q_D(const QQuickScrollBar);
+ return d->snapMode;
+}
+
+void QQuickScrollBar::setSnapMode(SnapMode mode)
+{
+ Q_D(QQuickScrollBar);
+ if (d->snapMode == mode)
+ return;
+
+ d->snapMode = mode;
+ emit snapModeChanged();
+}
+
+/*!
+ \since QtQuick.Controls 2.2
+ \qmlproperty bool QtQuick.Controls::ScrollBar::interactive
+
+ This property holds whether the scroll bar is interactive. The default value is \c true.
+
+ A non-interactive scroll bar is visually and behaviorally similar to \l ScrollIndicator.
+ This property is useful for switching between typical mouse- and touch-orientated UIs
+ with interactive and non-interactive scroll bars, respectively.
+*/
+bool QQuickScrollBar::isInteractive() const
+{
+ Q_D(const QQuickScrollBar);
+ return d->interactive;
+}
+
+void QQuickScrollBar::setInteractive(bool interactive)
+{
+ Q_D(QQuickScrollBar);
+ d->explicitInteractive = true;
+ d->setInteractive(interactive);
+}
+
+void QQuickScrollBar::resetInteractive()
+{
+ Q_D(QQuickScrollBar);
+ d->explicitInteractive = false;
+ d->setInteractive(true);
+}
+
+/*!
+ \since QtQuick.Controls 2.2
+ \qmlproperty enumeration QtQuick.Controls::ScrollBar::policy
+
+ This property holds the policy of the scroll bar. The default policy is \c ScrollBar.AsNeeded.
+
+ Possible values:
+ \value ScrollBar.AsNeeded The scroll bar is only shown when the content is too large to fit.
+ \value ScrollBar.AlwaysOff The scroll bar is never shown.
+ \value ScrollBar.AlwaysOn The scroll bar is always shown.
+
+ The following example keeps the vertical scroll bar always visible:
+
+ \snippet qtquickcontrols2-scrollbar-policy.qml 1
+*/
+QQuickScrollBar::Policy QQuickScrollBar::policy() const
+{
+ Q_D(const QQuickScrollBar);
+ return d->policy;
+}
+
+void QQuickScrollBar::setPolicy(Policy policy)
+{
+ Q_D(QQuickScrollBar);
+ if (d->policy == policy)
+ return;
+
+ d->policy = policy;
+ emit policyChanged();
+}
+
+/*!
\qmlmethod void QtQuick.Controls::ScrollBar::increase()
Increases the position by \l stepSize or \c 0.1 if stepSize is \c 0.0.
@@ -402,7 +555,7 @@ void QQuickScrollBar::increase()
qreal step = qFuzzyIsNull(d->stepSize) ? 0.1 : d->stepSize;
bool wasActive = d->active;
setActive(true);
- setPosition(d->position + step);
+ setPosition(qMin<qreal>(1.0 - d->size, d->position + step));
setActive(wasActive);
}
@@ -419,7 +572,7 @@ void QQuickScrollBar::decrease()
qreal step = qFuzzyIsNull(d->stepSize) ? 0.1 : d->stepSize;
bool wasActive = d->active;
setActive(true);
- setPosition(d->position - step);
+ setPosition(qMax<qreal>(0.0, d->position - step));
setActive(wasActive);
}
@@ -427,35 +580,39 @@ void QQuickScrollBar::mousePressEvent(QMouseEvent *event)
{
Q_D(QQuickScrollBar);
QQuickControl::mousePressEvent(event);
- d->offset = d->positionAt(event->pos()) - d->position;
- if (d->offset < 0 || d->offset > d->size)
- d->offset = d->size / 2;
- setPressed(true);
+ d->handlePress(event->localPos());
}
void QQuickScrollBar::mouseMoveEvent(QMouseEvent *event)
{
Q_D(QQuickScrollBar);
QQuickControl::mouseMoveEvent(event);
- setPosition(qBound<qreal>(0.0, d->positionAt(event->pos()) - d->offset, 1.0 - d->size));
+ d->handleMove(event->localPos());
}
void QQuickScrollBar::mouseReleaseEvent(QMouseEvent *event)
{
Q_D(QQuickScrollBar);
QQuickControl::mouseReleaseEvent(event);
- setPosition(qBound<qreal>(0.0, d->positionAt(event->pos()) - d->offset, 1.0 - d->size));
- d->offset = 0.0;
- setPressed(false);
+ d->handleRelease(event->localPos());
+}
+
+void QQuickScrollBar::mouseUngrabEvent()
+{
+ Q_D(QQuickScrollBar);
+ QQuickControl::mouseUngrabEvent();
+ d->handleUngrab();
}
+#if QT_CONFIG(quicktemplates2_hover)
void QQuickScrollBar::hoverChange()
{
Q_D(QQuickScrollBar);
d->updateActive();
}
+#endif
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(accessibility)
void QQuickScrollBar::accessibilityActiveChanged(bool active)
{
QQuickControl::accessibilityActiveChanged(active);
@@ -471,27 +628,102 @@ QAccessible::Role QQuickScrollBar::accessibleRole() const
}
#endif
-class QQuickScrollBarAttachedPrivate : public QObjectPrivate, public QQuickItemChangeListener
+QQuickScrollBarAttachedPrivate::QQuickScrollBarAttachedPrivate()
+ : flickable(nullptr),
+ horizontal(nullptr),
+ vertical(nullptr)
+{
+}
+
+void QQuickScrollBarAttachedPrivate::setFlickable(QQuickFlickable *item)
{
-public:
- QQuickScrollBarAttachedPrivate(QQuickFlickable *flickable) : flickable(flickable), horizontal(nullptr), vertical(nullptr) { }
+ if (flickable) {
+ // NOTE: Use removeItemChangeListener(Geometry) instead of updateOrRemoveGeometryChangeListener(Size).
+ // The latter doesn't remove the listener but only resets its types. Thus, it leaves behind a dangling
+ // pointer on destruction.
+ QQuickItemPrivate::get(flickable)->removeItemChangeListener(this, QQuickItemPrivate::Geometry);
+ if (horizontal)
+ cleanupHorizontal();
+ if (vertical)
+ cleanupVertical();
+ }
- void activateHorizontal();
- void activateVertical();
- void scrollHorizontal();
- void scrollVertical();
- void mirrorVertical();
+ flickable = item;
- void layoutHorizontal(bool move = true);
- void layoutVertical(bool move = true);
+ if (item) {
+ QQuickItemPrivate::get(item)->updateOrAddGeometryChangeListener(this, QQuickGeometryChange::Size);
+ if (horizontal)
+ initHorizontal();
+ if (vertical)
+ initVertical();
+ }
+}
- void itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &diff) override;
- void itemDestroyed(QQuickItem *item) override;
+void QQuickScrollBarAttachedPrivate::initHorizontal()
+{
+ Q_ASSERT(flickable && horizontal);
- QQuickFlickable *flickable;
- QQuickScrollBar *horizontal;
- QQuickScrollBar *vertical;
-};
+ connect(flickable, &QQuickFlickable::movingHorizontallyChanged, this, &QQuickScrollBarAttachedPrivate::activateHorizontal);
+
+ // TODO: export QQuickFlickableVisibleArea
+ QObject *area = flickable->property("visibleArea").value<QObject *>();
+ QObject::connect(area, SIGNAL(widthRatioChanged(qreal)), horizontal, SLOT(setSize(qreal)));
+ QObject::connect(area, SIGNAL(xPositionChanged(qreal)), horizontal, SLOT(setPosition(qreal)));
+
+ // ensure that the ScrollBar is stacked above the Flickable in a ScrollView
+ QQuickItem *parent = horizontal->parentItem();
+ if (parent && parent == flickable->parentItem())
+ horizontal->stackAfter(flickable);
+
+ layoutHorizontal();
+ horizontal->setSize(area->property("widthRatio").toReal());
+ horizontal->setPosition(area->property("xPosition").toReal());
+}
+
+void QQuickScrollBarAttachedPrivate::initVertical()
+{
+ Q_ASSERT(flickable && vertical);
+
+ connect(flickable, &QQuickFlickable::movingVerticallyChanged, this, &QQuickScrollBarAttachedPrivate::activateVertical);
+
+ // TODO: export QQuickFlickableVisibleArea
+ QObject *area = flickable->property("visibleArea").value<QObject *>();
+ QObject::connect(area, SIGNAL(heightRatioChanged(qreal)), vertical, SLOT(setSize(qreal)));
+ QObject::connect(area, SIGNAL(yPositionChanged(qreal)), vertical, SLOT(setPosition(qreal)));
+
+ // ensure that the ScrollBar is stacked above the Flickable in a ScrollView
+ QQuickItem *parent = vertical->parentItem();
+ if (parent && parent == flickable->parentItem())
+ vertical->stackAfter(flickable);
+
+ layoutVertical();
+ vertical->setSize(area->property("heightRatio").toReal());
+ vertical->setPosition(area->property("yPosition").toReal());
+}
+
+void QQuickScrollBarAttachedPrivate::cleanupHorizontal()
+{
+ Q_ASSERT(flickable && horizontal);
+
+ disconnect(flickable, &QQuickFlickable::movingHorizontallyChanged, this, &QQuickScrollBarAttachedPrivate::activateHorizontal);
+
+ // TODO: export QQuickFlickableVisibleArea
+ QObject *area = flickable->property("visibleArea").value<QObject *>();
+ QObject::disconnect(area, SIGNAL(widthRatioChanged(qreal)), horizontal, SLOT(setSize(qreal)));
+ QObject::disconnect(area, SIGNAL(xPositionChanged(qreal)), horizontal, SLOT(setPosition(qreal)));
+}
+
+void QQuickScrollBarAttachedPrivate::cleanupVertical()
+{
+ Q_ASSERT(flickable && vertical);
+
+ disconnect(flickable, &QQuickFlickable::movingVerticallyChanged, this, &QQuickScrollBarAttachedPrivate::activateVertical);
+
+ // TODO: export QQuickFlickableVisibleArea
+ QObject *area = flickable->property("visibleArea").value<QObject *>();
+ QObject::disconnect(area, SIGNAL(heightRatioChanged(qreal)), vertical, SLOT(setSize(qreal)));
+ QObject::disconnect(area, SIGNAL(yPositionChanged(qreal)), vertical, SLOT(setPosition(qreal)));
+}
void QQuickScrollBarAttachedPrivate::activateHorizontal()
{
@@ -570,7 +802,8 @@ void QQuickScrollBarAttachedPrivate::itemGeometryChanged(QQuickItem *item, const
#else
bool move = qFuzzyIsNull(horizontal->y()) || qFuzzyCompare(horizontal->y(), item->height() - diff.height() - horizontal->height());
#endif
- layoutHorizontal(move);
+ if (flickable)
+ layoutHorizontal(move);
}
if (vertical && vertical->width() > 0) {
#ifdef QT_QUICK_NEW_GEOMETRY_CHANGED_HANDLING // TODO: correct/rename diff to oldGeometry
@@ -578,10 +811,23 @@ void QQuickScrollBarAttachedPrivate::itemGeometryChanged(QQuickItem *item, const
#else
bool move = qFuzzyIsNull(vertical->x()) || qFuzzyCompare(vertical->x(), item->width() - diff.width() - vertical->width());
#endif
- layoutVertical(move);
+ if (flickable)
+ layoutVertical(move);
}
}
+void QQuickScrollBarAttachedPrivate::itemImplicitWidthChanged(QQuickItem *item)
+{
+ if (item == vertical && flickable)
+ layoutVertical(true);
+}
+
+void QQuickScrollBarAttachedPrivate::itemImplicitHeightChanged(QQuickItem *item)
+{
+ if (item == horizontal && flickable)
+ layoutHorizontal(true);
+}
+
void QQuickScrollBarAttachedPrivate::itemDestroyed(QQuickItem *item)
{
if (item == horizontal)
@@ -590,26 +836,28 @@ void QQuickScrollBarAttachedPrivate::itemDestroyed(QQuickItem *item)
vertical = nullptr;
}
-QQuickScrollBarAttached::QQuickScrollBarAttached(QQuickFlickable *flickable) :
- QObject(*(new QQuickScrollBarAttachedPrivate(flickable)), flickable)
+QQuickScrollBarAttached::QQuickScrollBarAttached(QObject *parent)
+ : QObject(*(new QQuickScrollBarAttachedPrivate), parent)
{
Q_D(QQuickScrollBarAttached);
- if (flickable) {
- QQuickItemPrivate *p = QQuickItemPrivate::get(flickable);
- p->updateOrAddGeometryChangeListener(d, QQuickGeometryChange::Size);
- }
+ d->setFlickable(qobject_cast<QQuickFlickable *>(parent));
+
+ if (parent && !d->flickable && !qobject_cast<QQuickScrollView *>(parent))
+ qmlWarning(parent) << "ScrollBar must be attached to a Flickable or ScrollView";
}
QQuickScrollBarAttached::~QQuickScrollBarAttached()
{
Q_D(QQuickScrollBarAttached);
- if (d->flickable) {
- if (d->horizontal)
- QQuickItemPrivate::get(d->horizontal)->removeItemChangeListener(d, QQuickItemPrivate::Geometry | QQuickItemPrivate::Destroyed);
- if (d->vertical)
- QQuickItemPrivate::get(d->vertical)->removeItemChangeListener(d, QQuickItemPrivate::Geometry | QQuickItemPrivate::Destroyed);
- QQuickItemPrivate::get(d->flickable)->removeItemChangeListener(d, QQuickItemPrivate::Geometry);
+ if (d->horizontal) {
+ QQuickItemPrivate::get(d->horizontal)->removeItemChangeListener(d, horizontalChangeTypes);
+ d->horizontal = nullptr;
+ }
+ if (d->vertical) {
+ QQuickItemPrivate::get(d->vertical)->removeItemChangeListener(d, verticalChangeTypes);
+ d->vertical = nullptr;
}
+ d->setFlickable(nullptr);
}
/*!
@@ -638,36 +886,26 @@ void QQuickScrollBarAttached::setHorizontal(QQuickScrollBar *horizontal)
if (d->horizontal == horizontal)
return;
- if (d->horizontal && d->flickable) {
- QQuickItemPrivate::get(d->horizontal)->removeItemChangeListener(d, QQuickItemPrivate::Geometry | QQuickItemPrivate::Destroyed);
+ if (d->horizontal) {
+ QQuickItemPrivate::get(d->horizontal)->removeItemChangeListener(d, horizontalChangeTypes);
QObjectPrivate::disconnect(d->horizontal, &QQuickScrollBar::positionChanged, d, &QQuickScrollBarAttachedPrivate::scrollHorizontal);
- QObjectPrivate::disconnect(d->flickable, &QQuickFlickable::movingHorizontallyChanged, d, &QQuickScrollBarAttachedPrivate::activateHorizontal);
- // TODO: export QQuickFlickableVisibleArea
- QObject *area = d->flickable->property("visibleArea").value<QObject *>();
- disconnect(area, SIGNAL(widthRatioChanged(qreal)), d->horizontal, SLOT(setSize(qreal)));
- disconnect(area, SIGNAL(xPositionChanged(qreal)), d->horizontal, SLOT(setPosition(qreal)));
+ if (d->flickable)
+ d->cleanupHorizontal();
}
d->horizontal = horizontal;
- if (horizontal && d->flickable) {
+ if (horizontal) {
if (!horizontal->parentItem())
- horizontal->setParentItem(d->flickable);
+ horizontal->setParentItem(qobject_cast<QQuickItem *>(parent()));
horizontal->setOrientation(Qt::Horizontal);
- QQuickItemPrivate::get(horizontal)->addItemChangeListener(d, QQuickItemPrivate::Geometry | QQuickItemPrivate::Destroyed);
+ QQuickItemPrivate::get(horizontal)->addItemChangeListener(d, horizontalChangeTypes);
QObjectPrivate::connect(horizontal, &QQuickScrollBar::positionChanged, d, &QQuickScrollBarAttachedPrivate::scrollHorizontal);
- QObjectPrivate::connect(d->flickable, &QQuickFlickable::movingHorizontallyChanged, d, &QQuickScrollBarAttachedPrivate::activateHorizontal);
- // TODO: export QQuickFlickableVisibleArea
- QObject *area = d->flickable->property("visibleArea").value<QObject *>();
- connect(area, SIGNAL(widthRatioChanged(qreal)), horizontal, SLOT(setSize(qreal)));
- connect(area, SIGNAL(xPositionChanged(qreal)), horizontal, SLOT(setPosition(qreal)));
-
- d->layoutHorizontal();
- horizontal->setSize(area->property("widthRatio").toReal());
- horizontal->setPosition(area->property("xPosition").toReal());
+ if (d->flickable)
+ d->initHorizontal();
}
emit horizontalChanged();
}
@@ -698,38 +936,28 @@ void QQuickScrollBarAttached::setVertical(QQuickScrollBar *vertical)
if (d->vertical == vertical)
return;
- if (d->vertical && d->flickable) {
- QQuickItemPrivate::get(d->vertical)->removeItemChangeListener(d, QQuickItemPrivate::Geometry | QQuickItemPrivate::Destroyed);
+ if (d->vertical) {
+ QQuickItemPrivate::get(d->vertical)->removeItemChangeListener(d, verticalChangeTypes);
QObjectPrivate::disconnect(d->vertical, &QQuickScrollBar::mirroredChanged, d, &QQuickScrollBarAttachedPrivate::mirrorVertical);
QObjectPrivate::disconnect(d->vertical, &QQuickScrollBar::positionChanged, d, &QQuickScrollBarAttachedPrivate::scrollVertical);
- QObjectPrivate::disconnect(d->flickable, &QQuickFlickable::movingVerticallyChanged, d, &QQuickScrollBarAttachedPrivate::activateVertical);
- // TODO: export QQuickFlickableVisibleArea
- QObject *area = d->flickable->property("visibleArea").value<QObject *>();
- disconnect(area, SIGNAL(heightRatioChanged(qreal)), d->vertical, SLOT(setSize(qreal)));
- disconnect(area, SIGNAL(yPositionChanged(qreal)), d->vertical, SLOT(setPosition(qreal)));
+ if (d->flickable)
+ d->cleanupVertical();
}
d->vertical = vertical;
- if (vertical && d->flickable) {
+ if (vertical) {
if (!vertical->parentItem())
- vertical->setParentItem(d->flickable);
+ vertical->setParentItem(qobject_cast<QQuickItem *>(parent()));
vertical->setOrientation(Qt::Vertical);
- QQuickItemPrivate::get(vertical)->addItemChangeListener(d, QQuickItemPrivate::Geometry | QQuickItemPrivate::Destroyed);
+ QQuickItemPrivate::get(vertical)->addItemChangeListener(d, verticalChangeTypes);
QObjectPrivate::connect(vertical, &QQuickScrollBar::mirroredChanged, d, &QQuickScrollBarAttachedPrivate::mirrorVertical);
QObjectPrivate::connect(vertical, &QQuickScrollBar::positionChanged, d, &QQuickScrollBarAttachedPrivate::scrollVertical);
- QObjectPrivate::connect(d->flickable, &QQuickFlickable::movingVerticallyChanged, d, &QQuickScrollBarAttachedPrivate::activateVertical);
-
- // TODO: export QQuickFlickableVisibleArea
- QObject *area = d->flickable->property("visibleArea").value<QObject *>();
- connect(area, SIGNAL(heightRatioChanged(qreal)), vertical, SLOT(setSize(qreal)));
- connect(area, SIGNAL(yPositionChanged(qreal)), vertical, SLOT(setPosition(qreal)));
- d->layoutVertical();
- vertical->setSize(area->property("heightRatio").toReal());
- vertical->setPosition(area->property("yPosition").toReal());
+ if (d->flickable)
+ d->initVertical();
}
emit verticalChanged();
}