diff --git a/libs/ui/dialogs/kis_dlg_preferences.h b/libs/ui/dialogs/kis_dlg_preferences.h
--- a/libs/ui/dialogs/kis_dlg_preferences.h
+++ b/libs/ui/dialogs/kis_dlg_preferences.h
@@ -79,6 +79,9 @@
bool showCanvasMessages();
bool compressKra();
bool toolOptionsInDocker();
+ int kineticScrollingGesture();
+ int kineticScrollingSensitivity();
+ bool kineticScrollingScrollbar();
bool switchSelectionCtrlAlt();
bool convertToImageColorspaceOnImport();
diff --git a/libs/ui/dialogs/kis_dlg_preferences.cc b/libs/ui/dialogs/kis_dlg_preferences.cc
--- a/libs/ui/dialogs/kis_dlg_preferences.cc
+++ b/libs/ui/dialogs/kis_dlg_preferences.cc
@@ -108,6 +108,10 @@
m_cmbOutlineShape->addItem(i18n("Preview Outline"));
m_cmbOutlineShape->addItem(i18n("Tilt Outline"));
+ m_cmbKineticScrollingGesture->addItem(i18n("Disabled"));
+ m_cmbKineticScrollingGesture->addItem(i18n("On Touch Drag"));
+ m_cmbKineticScrollingGesture->addItem(i18n("On Click Drag"));
+
m_cmbCursorShape->setCurrentIndex(cfg.newCursorStyle());
m_cmbOutlineShape->setCurrentIndex(cfg.newOutlineStyle());
@@ -143,6 +147,9 @@
m_chkSingleApplication->setChecked(kritarc.value("EnableSingleApplication", true).toBool());
m_radioToolOptionsInDocker->setChecked(cfg.toolOptionsInDocker());
+ m_cmbKineticScrollingGesture->setCurrentIndex(cfg.kineticScrollingGesture());
+ m_kineticScrollingSensitivity->setValue(cfg.kineticScrollingSensitivity());
+ m_chkKineticScrollingScrollbar->setChecked(cfg.kineticScrollingScrollbar());
m_chkSwitchSelectionCtrlAlt->setChecked(cfg.switchSelectionCtrlAlt());
chkEnableTouch->setChecked(!cfg.disableTouchOnCanvas());
m_chkConvertOnImport->setChecked(cfg.convertToImageColorspaceOnImport());
@@ -187,6 +194,9 @@
m_chkHiDPI->setChecked(true);
m_radioToolOptionsInDocker->setChecked(cfg.toolOptionsInDocker(true));
+ m_cmbKineticScrollingGesture->setCurrentIndex(cfg.kineticScrollingGesture(true));
+ m_kineticScrollingSensitivity->setValue(cfg.kineticScrollingSensitivity(true));
+ m_chkKineticScrollingScrollbar->setChecked(cfg.kineticScrollingScrollbar(true));
m_chkSwitchSelectionCtrlAlt->setChecked(cfg.switchSelectionCtrlAlt(true));
chkEnableTouch->setChecked(!cfg.disableTouchOnCanvas(true));
m_chkConvertOnImport->setChecked(cfg.convertToImageColorspaceOnImport(true));
@@ -258,6 +268,21 @@
return m_radioToolOptionsInDocker->isChecked();
}
+int GeneralTab::kineticScrollingGesture()
+{
+ return m_cmbKineticScrollingGesture->currentIndex();
+}
+
+int GeneralTab::kineticScrollingSensitivity()
+{
+ return m_kineticScrollingSensitivity->value();
+}
+
+bool GeneralTab::kineticScrollingScrollbar()
+{
+ return m_chkKineticScrollingScrollbar->isChecked();
+}
+
bool GeneralTab::switchSelectionCtrlAlt()
{
return m_chkSwitchSelectionCtrlAlt->isChecked();
@@ -1168,6 +1193,9 @@
kritarc.setValue("EnableSingleApplication", dialog->m_general->m_chkSingleApplication->isChecked());
cfg.setToolOptionsInDocker(dialog->m_general->toolOptionsInDocker());
+ cfg.setKineticScrollingGesture(dialog->m_general->kineticScrollingGesture());
+ cfg.setKineticScrollingSensitivity(dialog->m_general->kineticScrollingSensitivity());
+ cfg.setKineticScrollingScrollbar(dialog->m_general->kineticScrollingScrollbar());
cfg.setSwitchSelectionCtrlAlt(dialog->m_general->switchSelectionCtrlAlt());
cfg.setDisableTouchOnCanvas(!dialog->m_general->chkEnableTouch->isChecked());
cfg.setConvertToImageColorspaceOnImport(dialog->m_general->convertToImageColorspaceOnImport());
diff --git a/libs/ui/forms/wdggeneralsettings.ui b/libs/ui/forms/wdggeneralsettings.ui
--- a/libs/ui/forms/wdggeneralsettings.ui
+++ b/libs/ui/forms/wdggeneralsettings.ui
@@ -406,6 +406,64 @@
+ -
+
+
+ Kinetic Scrolling (needs restart)
+
+
+
-
+
+
+ -
+
+
-
+
+
+ Sensitivity (0-100):
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 50
+ 0
+
+
+
+ 0
+
+
+ 100
+
+
+ 1
+
+
+ 75
+
+
+
+
+
+ -
+
+
+ Show Scrollbar
+
+
+
+
+
+
-
diff --git a/libs/ui/kis_config.h b/libs/ui/kis_config.h
--- a/libs/ui/kis_config.h
+++ b/libs/ui/kis_config.h
@@ -493,6 +493,15 @@
bool toolOptionsInDocker(bool defaultValue = false) const;
void setToolOptionsInDocker(bool inDocker);
+ int kineticScrollingGesture(bool defaultValue = false) const;
+ void setKineticScrollingGesture(int kineticScroll);
+
+ int kineticScrollingSensitivity(bool defaultValue = false) const;
+ void setKineticScrollingSensitivity(int sensitivity);
+
+ bool kineticScrollingScrollbar(bool defaultValue = false) const;
+ void setKineticScrollingScrollbar(bool scrollbar);
+
void setEnableOpenGLFramerateLogging(bool value) const;
bool enableOpenGLFramerateLogging(bool defaultValue = false) const;
diff --git a/libs/ui/kis_config.cc b/libs/ui/kis_config.cc
--- a/libs/ui/kis_config.cc
+++ b/libs/ui/kis_config.cc
@@ -1712,6 +1712,36 @@
m_cfg.writeEntry("ToolOptionsInDocker", inDocker);
}
+int KisConfig::kineticScrollingGesture(bool defaultValue) const
+{
+ return (defaultValue ? 0 : m_cfg.readEntry("KineticScrollingGesture", 0));
+}
+
+void KisConfig::setKineticScrollingGesture(int gesture)
+{
+ m_cfg.writeEntry("KineticScrollingGesture", gesture);
+}
+
+int KisConfig::kineticScrollingSensitivity(bool defaultValue) const
+{
+ return (defaultValue ? 75 : m_cfg.readEntry("KineticScrollingSensitivity", 75));
+}
+
+void KisConfig::setKineticScrollingSensitivity(int sensitivity)
+{
+ m_cfg.writeEntry("KineticScrollingSensitivity", sensitivity);
+}
+
+bool KisConfig::kineticScrollingScrollbar(bool defaultValue) const
+{
+ return (defaultValue ? true : m_cfg.readEntry("KineticScrollingScrollbar", true));
+}
+
+void KisConfig::setKineticScrollingScrollbar(bool scrollbar)
+{
+ m_cfg.writeEntry("KineticScrollingScrollbar", scrollbar);
+}
+
const KoColorSpace* KisConfig::customColorSelectorColorSpace(bool defaultValue) const
{
const KoColorSpace *cs = 0;
diff --git a/libs/ui/widgets/kis_preset_chooser.cpp b/libs/ui/widgets/kis_preset_chooser.cpp
--- a/libs/ui/widgets/kis_preset_chooser.cpp
+++ b/libs/ui/widgets/kis_preset_chooser.cpp
@@ -29,6 +29,7 @@
#include
#include
+#include
#include
@@ -214,6 +215,11 @@
m_chooser->setSynced(true);
layout->addWidget(m_chooser);
+ KisConfig cfg;
+ m_chooser->configureKineticScrolling(cfg.kineticScrollingGesture(),
+ cfg.kineticScrollingSensitivity(),
+ cfg.kineticScrollingScrollbar());
+
connect(m_chooser, SIGNAL(resourceSelected(KoResource*)),
this, SIGNAL(resourceSelected(KoResource*)));
connect(m_chooser, SIGNAL(resourceClicked(KoResource*)),
diff --git a/libs/widgets/KoResourceItemChooser.h b/libs/widgets/KoResourceItemChooser.h
--- a/libs/widgets/KoResourceItemChooser.h
+++ b/libs/widgets/KoResourceItemChooser.h
@@ -27,6 +27,7 @@
#define KO_RESOURCE_ITEM_CHOOSER
#include
+#include
#include "kritawidgets_export.h"
@@ -110,6 +111,9 @@
bool eventFilter(QObject *object, QEvent *event) override;
+ /// sets up this chooser for kinetic (drag triggered) scrolling
+ void configureKineticScrolling(int gesture, int sensitivity, bool scrollbar);
+
Q_SIGNALS:
/// Emitted when a resource was selected
void resourceSelected(KoResource *resource);
diff --git a/libs/widgets/KoResourceItemChooser.cpp b/libs/widgets/KoResourceItemChooser.cpp
--- a/libs/widgets/KoResourceItemChooser.cpp
+++ b/libs/widgets/KoResourceItemChooser.cpp
@@ -533,6 +533,61 @@
return QObject::eventFilter(object, event);
}
+void KoResourceItemChooser::configureKineticScrolling(int gesture, int sensitivity, bool scrollbar)
+{
+ QScroller::ScrollerGestureType gestureType;
+
+ switch (gesture) {
+ case 1: {
+ gestureType = QScroller::TouchGesture;
+ break;
+ }
+ case 2: {
+ gestureType = QScroller::LeftMouseButtonGesture;
+ break;
+ }
+ default:
+ return;
+ }
+
+ KoResourceItemView *view = itemView();
+
+ view->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
+ if (!scrollbar) {
+ view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+ }
+
+ QScroller *scroller = QScroller::scroller(view);
+ scroller->grabGesture(view, gestureType);
+
+ QScrollerProperties sp;
+
+ // 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; // 1 millimeter
+ const float resistance = 1.0f - (sensitivity / 100.0f);
+
+ sp.setScrollMetric(QScrollerProperties::DragStartDistance, resistance * 10.0f * mm);
+ sp.setScrollMetric(QScrollerProperties::DragVelocitySmoothingFactor, 1.0f);
+ sp.setScrollMetric(QScrollerProperties::MinimumVelocity, 0.0f);
+ sp.setScrollMetric(QScrollerProperties::AxisLockThreshold, 1.0f);
+ sp.setScrollMetric(QScrollerProperties::MaximumClickThroughVelocity, 0.0f);
+ sp.setScrollMetric(QScrollerProperties::MousePressEventDelay, 1.0f - 0.75f * resistance);
+ sp.setScrollMetric(QScrollerProperties::AcceleratingFlickSpeedupFactor, 1.5f);
+
+ sp.setScrollMetric(QScrollerProperties::VerticalOvershootPolicy, QScrollerProperties::OvershootAlwaysOn);
+ sp.setScrollMetric(QScrollerProperties::OvershootDragResistanceFactor, 0.1);
+ sp.setScrollMetric(QScrollerProperties::OvershootDragDistanceFactor, 0.3);
+ sp.setScrollMetric(QScrollerProperties::OvershootScrollDistanceFactor, 0.1);
+ sp.setScrollMetric(QScrollerProperties::OvershootScrollTime, 0.4);
+
+ scroller->setScrollerProperties(sp);
+}
+
void KoResourceItemChooser::resizeEvent(QResizeEvent *event)
{
QWidget::resizeEvent(event);