1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
|
/* This file is part of the KDE project
* Copyright (C) 2018 Emmet O'Neill <emmetoneill.pdx@gmail.com>
* Copyright (C) 2018 Eoin O'Neill <eoinoneill1991@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include <KoKineticScroller.h>
#include <QAbstractItemView>
#include <ksharedconfig.h>
#include <kconfiggroup.h>
QScroller* KoKineticScroller::createPreconfiguredScroller(QAbstractScrollArea *scrollArea)
{
KConfigGroup config = KSharedConfig::openConfig()->group("KoKineticScroller");
int sensitivity = config.readEntry("KineticScrollingSensitivity", 75);
bool enabled = config.readEntry("KineticScrollingEnabled", true);
bool hideScrollBars = config.readEntry("KineticScrollingHideScrollbar", false);
float resistanceCoefficient = config.readEntry("KineticScrollingResistanceCoefficient", 10.0f);
float dragVelocitySmoothFactor = config.readEntry("KineticScrollingDragVelocitySmoothingFactor", 1.0f);
float minimumVelocity = config.readEntry("KineticScrollingMinimumVelocity", 0.0f);
float axisLockThresh = config.readEntry("KineticScrollingAxisLockThreshold", 1.0f);
float maximumClickThroughVelocity = config.readEntry("KineticScrollingMaxClickThroughVelocity", 0.0f);
float flickAccelerationFactor = config.readEntry("KineticScrollingFlickAccelerationFactor", 1.5f);
float overshootDragResistanceFactor = config.readEntry("KineticScrollingOvershotDragResistanceFactor", 0.1f);
float overshootDragDistanceFactor = config.readEntry("KineticScrollingOvershootDragDistanceFactor", 0.3f);
float overshootScrollDistanceFactor = config.readEntry("KineticScrollingOvershootScrollDistanceFactor", 0.1f);
float overshootScrollTime = config.readEntry("KineticScrollingOvershootScrollTime", 0.4f);
QScroller::ScrollerGestureType gestureType = getConfiguredGestureType();
if (enabled && scrollArea) {
if (hideScrollBars) {
scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarPolicy::ScrollBarAlwaysOff);
scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarPolicy::ScrollBarAlwaysOff);
}
QAbstractItemView *itemView = qobject_cast<QAbstractItemView *>(scrollArea);
if (itemView) {
itemView->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
}
QScroller *scroller = QScroller::scroller(scrollArea);
scroller->grabGesture(scrollArea, gestureType);
QScrollerProperties properties;
// DragStartDistance seems to be based on meter per second; though it's
// not explicitly documented, other QScroller values are in that metric.
// To start kinetic scrolling, with minimal sensitity, we expect a drag
// of 10 mm, with minimum sensitity any > 0 mm.
const float mm = 0.001f;
const float resistance = 1.0f - (sensitivity / 100.0f);
const float mousePressEventDelay = config.readEntry("KineticScrollingMousePressDelay", 1.0f - 0.75f * resistance);
properties.setScrollMetric(QScrollerProperties::DragStartDistance, resistance * resistanceCoefficient * mm);
properties.setScrollMetric(QScrollerProperties::DragVelocitySmoothingFactor, dragVelocitySmoothFactor);
properties.setScrollMetric(QScrollerProperties::MinimumVelocity, minimumVelocity);
properties.setScrollMetric(QScrollerProperties::AxisLockThreshold, axisLockThresh);
properties.setScrollMetric(QScrollerProperties::MaximumClickThroughVelocity, maximumClickThroughVelocity);
properties.setScrollMetric(QScrollerProperties::MousePressEventDelay, mousePressEventDelay);
properties.setScrollMetric(QScrollerProperties::AcceleratingFlickSpeedupFactor, flickAccelerationFactor);
properties.setScrollMetric(QScrollerProperties::VerticalOvershootPolicy, QScrollerProperties::OvershootAlwaysOn);
properties.setScrollMetric(QScrollerProperties::OvershootDragResistanceFactor, overshootDragResistanceFactor);
properties.setScrollMetric(QScrollerProperties::OvershootDragDistanceFactor, overshootDragDistanceFactor);
properties.setScrollMetric(QScrollerProperties::OvershootScrollDistanceFactor, overshootScrollDistanceFactor);
properties.setScrollMetric(QScrollerProperties::OvershootScrollTime, overshootScrollTime);
scroller->setScrollerProperties(properties);
return scroller;
}
return nullptr;
}
QScroller::ScrollerGestureType KoKineticScroller::getConfiguredGestureType()
{
KConfigGroup config = KSharedConfig::openConfig()->group("KoKineticScroller");
int gesture = config.readEntry("KineticScrollingGesture", 0);
switch (gesture) {
case 0: {
return QScroller::TouchGesture;
}
case 1: {
return QScroller::LeftMouseButtonGesture;
}
case 2: {
return QScroller::MiddleMouseButtonGesture;
}
case 3: {
return QScroller::RightMouseButtonGesture;
}
default:
return QScroller::MiddleMouseButtonGesture;
}
}
void KoKineticScroller::updateCursor(QWidget *source, QScroller::State state)
{
if( state == QScroller::State::Pressed ) {
source->setCursor(Qt::OpenHandCursor);
} else if (state == QScroller::State::Dragging) {
source->setCursor(Qt::ClosedHandCursor);
} else {
source->setCursor(Qt::ArrowCursor);
}
}
|