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,8 @@ bool showCanvasMessages(); bool compressKra(); bool toolOptionsInDocker(); + int kineticScrollingGesture(); + int kineticScrollingSensitivity(); 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,8 @@ m_chkSingleApplication->setChecked(kritarc.value("EnableSingleApplication", true).toBool()); m_radioToolOptionsInDocker->setChecked(cfg.toolOptionsInDocker()); + m_cmbKineticScrollingGesture->setCurrentIndex(cfg.kineticScrollingGesture()); + m_kineticScrollingSensitivity->setValue(cfg.kineticScrollingSensitivity()); m_chkSwitchSelectionCtrlAlt->setChecked(cfg.switchSelectionCtrlAlt()); chkEnableTouch->setChecked(!cfg.disableTouchOnCanvas()); m_chkConvertOnImport->setChecked(cfg.convertToImageColorspaceOnImport()); @@ -187,6 +193,8 @@ m_chkHiDPI->setChecked(true); m_radioToolOptionsInDocker->setChecked(cfg.toolOptionsInDocker(true)); + m_cmbKineticScrollingGesture->setCurrentIndex(cfg.kineticScrollingGesture(true)); + m_kineticScrollingSensitivity->setValue(cfg.kineticScrollingSensitivity(true)); m_chkSwitchSelectionCtrlAlt->setChecked(cfg.switchSelectionCtrlAlt(true)); chkEnableTouch->setChecked(!cfg.disableTouchOnCanvas(true)); m_chkConvertOnImport->setChecked(cfg.convertToImageColorspaceOnImport(true)); @@ -258,6 +266,16 @@ return m_radioToolOptionsInDocker->isChecked(); } +int GeneralTab::kineticScrollingGesture() +{ + return m_cmbKineticScrollingGesture->currentIndex(); +} + +int GeneralTab::kineticScrollingSensitivity() +{ + return m_kineticScrollingSensitivity->value(); +} + bool GeneralTab::switchSelectionCtrlAlt() { return m_chkSwitchSelectionCtrlAlt->isChecked(); @@ -1164,6 +1182,8 @@ 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.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 @@ -407,6 +407,57 @@ + + + Kinetic Scrolling (needs restart) + + + + + + + + + + + Sensitivity (0-100): + + + + + + + + 0 + 0 + + + + + 50 + 0 + + + + 0 + + + 100 + + + 1 + + + 75 + + + + + + + + + Qt::Vertical 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 @@ -484,6 +484,12 @@ 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); + 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 @@ -1679,6 +1679,24 @@ 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); +} + 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 @@ -202,6 +203,14 @@ m_chooser->setSynced(true); layout->addWidget(m_chooser); + KisConfig cfg; + const int kineticGesture = cfg.kineticScrollingGesture(); + if (kineticGesture == 1) { + m_chooser->setKineticScrolling(QScroller::TouchGesture, cfg.kineticScrollingSensitivity()); + } else if (kineticGesture == 2) { + m_chooser->setKineticScrolling(QScroller::LeftMouseButtonGesture, cfg.kineticScrollingSensitivity()); + } + 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 setKineticScrolling(QScroller::ScrollerGestureType gesture, int drag); + 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,39 @@ return QObject::eventFilter(object, event); } +void KoResourceItemChooser::setKineticScrolling(QScroller::ScrollerGestureType gesture, int drag) +{ + KoResourceItemView *view = itemView(); + + view->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel); + view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + + QScroller *scroller = QScroller::scroller(view); + scroller->grabGesture(view, gesture); + + 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 - (drag / 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); + + + scroller->setScrollerProperties(sp); +} + void KoResourceItemChooser::resizeEvent(QResizeEvent *event) { QWidget::resizeEvent(event);