소스 검색

Add ctkPopupWidget::active to stop listening events

from the application or the base widget.
In case ctkPopupWidget is embedded into a layout, we might not want to
hide the widget anymore (when the current window changes or other cases
that are only valid when the widget is toplevel).
Julien Finet 14 년 전
부모
커밋
2705ca72ca
4개의 변경된 파일61개의 추가작업 그리고 3개의 파일을 삭제
  1. 9 0
      Libs/Widgets/ctkBasePopupWidget.cpp
  2. 39 3
      Libs/Widgets/ctkPopupWidget.cpp
  3. 12 0
      Libs/Widgets/ctkPopupWidget.h
  4. 1 0
      Libs/Widgets/ctkPopupWidget_p.h

+ 9 - 0
Libs/Widgets/ctkBasePopupWidget.cpp

@@ -425,6 +425,15 @@ QRect ctkBasePopupWidgetPrivate::desiredOpenGeometry(QRect baseGeometry)const
 void ctkBasePopupWidgetPrivate::hideAll()
 {
   Q_Q(ctkBasePopupWidget);
+
+  // It is possible to have the popup widget not being a popup but inside
+  // a layout: maybe the popup has been pin-down in a way that it gets parented
+  // In that case, there is no reason to hide the popup.
+  if (q->parentWidget() != 0)
+    {
+    return;
+    }
+
   // Before hiding, transfer the active window flag to its parent, this will
   // prevent the application to send a ApplicationDeactivate signal that
   // doesn't need to be done.

+ 39 - 3
Libs/Widgets/ctkPopupWidget.cpp

@@ -45,6 +45,7 @@
 ctkPopupWidgetPrivate::ctkPopupWidgetPrivate(ctkPopupWidget& object)
   :Superclass(object)
 {
+  this->Active = false;
   this->AutoShow = true;
   this->AutoHide = true;
 }
@@ -60,8 +61,7 @@ void ctkPopupWidgetPrivate::init()
   Q_Q(ctkPopupWidget);
   this->setParent(q);
   this->Superclass::init();
-  this->PopupPixmapWidget->installEventFilter(q);
-  qApp->installEventFilter(this);
+  q->setActive(true);
 }
 
 // -------------------------------------------------------------------------
@@ -258,6 +258,42 @@ ctkPopupWidget::~ctkPopupWidget()
 }
 
 // -------------------------------------------------------------------------
+bool ctkPopupWidget::isActive()const
+{
+  Q_D(const ctkPopupWidget);
+  return d->Active;
+}
+
+// -------------------------------------------------------------------------
+void ctkPopupWidget::setActive(bool active)
+{
+  Q_D(ctkPopupWidget);
+  if (active == d->Active)
+    {
+    return;
+    }
+  d->Active = active;
+  if (d->Active)
+    {
+    if (d->BaseWidget)
+      {
+      d->BaseWidget->installEventFilter(this);
+      }
+    d->PopupPixmapWidget->installEventFilter(this);
+    qApp->installEventFilter(d);
+    }
+  else // not active
+    {
+    if (d->BaseWidget)
+      {
+      d->BaseWidget->removeEventFilter(this);
+      }
+    d->PopupPixmapWidget->removeEventFilter(this);
+    qApp->removeEventFilter(d);
+    }
+}
+
+// -------------------------------------------------------------------------
 void ctkPopupWidget::setBaseWidget(QWidget* widget)
 {
   Q_D(ctkPopupWidget);
@@ -266,7 +302,7 @@ void ctkPopupWidget::setBaseWidget(QWidget* widget)
     d->BaseWidget->removeEventFilter(this);
     }
   this->Superclass::setBaseWidget(widget);
-  if (d->BaseWidget)
+  if (d->BaseWidget && d->Active)
     {
     d->BaseWidget->installEventFilter(this);
     }

+ 12 - 0
Libs/Widgets/ctkPopupWidget.h

@@ -31,6 +31,15 @@ class CTK_WIDGETS_EXPORT ctkPopupWidget : public ctkBasePopupWidget
 {
   Q_OBJECT
 
+  /// Control wether the popup listens to the application and baseWidget
+  /// events and decides if it needs to be permanently or temporarily hidden.
+  /// You might want to setActive(false) when embedding the popup
+  /// into a static layout intead of having it top-level (no parent).
+  /// Consider also removing its windowFlags (Qt::ToolTip |
+  /// Qt::FramelessWindowHint) and removing the baseWidget.
+  /// True by default
+  Q_PROPERTY( bool active READ isActive WRITE setActive)
+
   /// Control wether the popup automatically opens when the mouse
   /// enter the widget. True by default
   Q_PROPERTY( bool autoShow READ autoShow WRITE setAutoShow)
@@ -49,6 +58,9 @@ public:
   /// it tries to resize itself to fit the same width of \a baseWidget.
   virtual void setBaseWidget(QWidget* baseWidget);
 
+  bool isActive()const;
+  void setActive(bool);
+
   bool autoShow()const;
   /// Calling setAutoShow automatically updates opens the popup if the cursor
   /// is above the popup or the base widget.

+ 1 - 0
Libs/Widgets/ctkPopupWidget_p.h

@@ -54,6 +54,7 @@ public slots:
   void onApplicationDeactivate();
 
 protected:
+  bool Active;
   bool AutoShow;
   bool AutoHide;
 };