Ver código fonte

Add ctkComboBox::ScrollEffect

Julien Finet 11 anos atrás
pai
commit
71dd74a85e
2 arquivos alterados com 102 adições e 8 exclusões
  1. 63 0
      Libs/Widgets/ctkComboBox.cpp
  2. 39 8
      Libs/Widgets/ctkComboBox.h

+ 63 - 0
Libs/Widgets/ctkComboBox.cpp

@@ -22,6 +22,9 @@
 #include <QStylePainter>
 #include <QApplication>
 #include <QDebug>
+#include <QScrollArea>
+#include <QScrollBar>
+#include <QWheelEvent>
 
 // CTK includes
 #include "ctkComboBox.h"
@@ -40,6 +43,7 @@ public:
   QIcon   DefaultIcon;
   bool    ForceDefault;
   Qt::TextElideMode ElideMode;
+  ctkComboBox::ScrollEffect ScrollWheelEffect;
 
   mutable QSize MinimumSizeHint;
   mutable QSize SizeHint;
@@ -52,6 +56,7 @@ ctkComboBoxPrivate::ctkComboBoxPrivate(ctkComboBox& object)
   this->DefaultText = "";
   this->ForceDefault = false;
   this->ElideMode = Qt::ElideNone;
+  this->ScrollWheelEffect = ctkComboBox::AlwaysScroll;
 }
 
 // -------------------------------------------------------------------------
@@ -248,6 +253,22 @@ bool ctkComboBox::isDefaultForced()const
 }
 
 // -------------------------------------------------------------------------
+ctkComboBox::ScrollEffect ctkComboBox::scrollWheelEffect()const
+{
+  Q_D(const ctkComboBox);
+  return d->ScrollWheelEffect;
+}
+
+// -------------------------------------------------------------------------
+void ctkComboBox::setScrollWheelEffect(ctkComboBox::ScrollEffect scroll)
+{
+  Q_D(ctkComboBox);
+  d->ScrollWheelEffect = scroll;
+  this->setFocusPolicy( d->ScrollWheelEffect == ctkComboBox::ScrollWithFocus ?
+                        Qt::StrongFocus : Qt::WheelFocus );
+}
+
+// -------------------------------------------------------------------------
 void ctkComboBox::paintEvent(QPaintEvent*)
 {
   Q_D(ctkComboBox);
@@ -302,3 +323,45 @@ void ctkComboBox::changeEvent(QEvent *e)
 
   this->QComboBox::changeEvent(e);
 }
+
+// -------------------------------------------------------------------------
+void ctkComboBox::wheelEvent(QWheelEvent* event)
+{
+  Q_D(ctkComboBox);
+  bool scroll = false;
+  switch (d->ScrollWheelEffect)
+    {
+    case AlwaysScroll:
+      scroll = true;
+      break;
+    case ScrollWithFocus:
+      scroll = this->hasFocus();
+      break;
+    case ScrollWithNoVScrollBar:
+      scroll = true;
+      for (QWidget* ancestor = this->parentWidget();
+           ancestor; ancestor = ancestor->parentWidget())
+        {
+        if (QScrollArea* scrollArea = qobject_cast<QScrollArea*>(ancestor))
+          {
+          scroll = !scrollArea->verticalScrollBar()->isVisible();
+          if (!scroll)
+            {
+            break;
+            }
+          }
+        }
+      break;
+    default:
+    case NeverScroll:
+      break;
+    }
+  if (scroll)
+    {
+    this->QComboBox::wheelEvent(event);
+    }
+  else
+    {
+    event->ignore();
+    }
+}

+ 39 - 8
Libs/Widgets/ctkComboBox.h

@@ -30,13 +30,17 @@
 class ctkComboBoxPrivate;
 
 /// \ingroup Widgets
-/// ctkComboBox is an advanced QComboBox. It allows the display of a default
-/// text/icon when the combobox current index is invalid (-1). A typical
-/// default text would be "Select a XXX..."
-/// forceDefault can force the display of the default text at all time (with
-/// a valid current index). The text displayed in the combo box can be
-/// elided when the size is too small.
+/// \brief ctkComboBox is an advanced QComboBox.
+/// It adds multiple features:
+///  * Display a default text and/or icon when the combobox current index is
+///    invalid (-1). A typical default text would be "Select a XXX...".
+///    forceDefault can force the display of the default text at all time (with
+///    a valid current index). The text displayed in the combo box can be
+///    elided when the size is too small.
+///  * Optionally prevent the mouse scroll events from changing the current
+///    index.
 /// ctkComboBox works exactly the same as QComboBox by default.
+/// \sa QComboBox
 class CTK_WIDGETS_EXPORT ctkComboBox : public QComboBox
 {
   Q_OBJECT
@@ -44,7 +48,12 @@ class CTK_WIDGETS_EXPORT ctkComboBox : public QComboBox
   Q_PROPERTY(QIcon defaultIcon READ defaultIcon WRITE setDefaultIcon)
   Q_PROPERTY(bool forceDefault READ isDefaultForced WRITE forceDefault)
   Q_PROPERTY(Qt::TextElideMode elideMode READ elideMode WRITE setElideMode)
+  /// This property controls the behavior of the mouse scroll wheel.
+  /// ScrollOn by default.
+  /// /sa scrollWheelEffect, setScrollWheelEffect
+  Q_PROPERTY(ScrollEffect scrollWheelEffect READ scrollWheelEffect WRITE setScrollWheelEffect)
 
+  Q_ENUMS(ScrollEffect);
 public:
   /// Constructor, build a ctkComboBox that behave like QComboBox.
   explicit ctkComboBox(QWidget* parent = 0);
@@ -68,6 +77,27 @@ public:
   void setElideMode(const Qt::TextElideMode& newMode);
   Qt::TextElideMode elideMode()const;
 
+  /// \tbd turn into flags ?
+  enum ScrollEffect
+  {
+    /// Scrolling is not possible with the mouse wheel.
+    NeverScroll,
+    /// Scrolling is always possible with the mouse wheel.
+    AlwaysScroll,
+    /// Scrolling is only possible if the combobox has the focus.
+    /// The focus policy is automatically set to Qt::StrongFocus
+    ScrollWithFocus,
+    /// Scrolling is not possible when the combobox is inside a scrollarea with
+    /// a visible vertical scrollbar.
+    ScrollWithNoVScrollBar
+  };
+  /// Return the scrollWheelEffect property value.
+  /// \sa scrollEffect
+  ScrollEffect scrollWheelEffect()const;
+  /// Set the scrollWheelEffect property value.
+  /// \sa scrollEffect
+  void setScrollWheelEffect(ScrollEffect scroll);
+
   /// Reimplemented for internal reasons
   virtual QSize minimumSizeHint()const;
   /// Reimplemented for internal reasons
@@ -75,8 +105,9 @@ public:
 
 protected:
   /// Reimplemented for internal reasons
-  virtual void paintEvent(QPaintEvent*);
-  virtual void changeEvent(QEvent *e);
+  virtual void paintEvent(QPaintEvent* event);
+  virtual void changeEvent(QEvent* event);
+  virtual void wheelEvent(QWheelEvent* event);
 
 protected:
   QScopedPointer<ctkComboBoxPrivate> d_ptr;