Browse Source

Merge remote-tracking branch 'origin/master'

Michael Onken 14 years ago
parent
commit
cb40633c00

+ 12 - 8
CMakeExternals/DCMTK.cmake

@@ -45,14 +45,18 @@ IF(${add_project})
       )
     SET(DCMTK_DIR ${ep_install_dir})
 
-    ExternalProject_Add_Step(${proj} force_rebuild
-      COMMENT "Force ${proj} re-build"
-      DEPENDERS build    # Steps that depend on this step
-      ALWAYS 1
-      WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/${proj}-build
-      DEPENDS
-        ${proj_DEPENDENCIES}
-      )
+# This was used during heavy development on DCMTK itself.
+# Disabling it for now. (It also leads to to build errors
+# with the XCode CMake generator on Mac).
+#
+#    ExternalProject_Add_Step(${proj} force_rebuild
+#      COMMENT "Force ${proj} re-build"
+#      DEPENDERS build    # Steps that depend on this step
+#      ALWAYS 1
+#      WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/${proj}-build
+#      DEPENDS
+#        ${proj_DEPENDENCIES}
+#      )
       
     # Since DCMTK is statically build, there is not need to add its corresponding 
     # library output directory to CTK_EXTERNAL_LIBRARY_DIRS

+ 5 - 0
Libs/Widgets/Testing/Cpp/ctkAxesWidgetTest1.cpp

@@ -86,8 +86,13 @@ int ctkAxesWidgetTest1(int argc, char * argv [] )
     }
   axes.setAutoReset(false);
   axes.setAutoReset(true);
+  axes.setWindowTitle("AutoReset=On");
   axes.show();
 
+  ctkAxesWidget axes2;
+  axes2.setWindowTitle("AutoReset=Off");
+  axes2.show();
+
   if (argc < 2 || QString(argv[1]) != "-I" )
     {
     QTimer::singleShot(200, &app, SLOT(quit()));

+ 55 - 4
Libs/Widgets/Testing/Cpp/ctkPopupWidgetTest1.cpp

@@ -21,13 +21,17 @@
 // Qt includes
 #include <QApplication>
 #include <QComboBox>
-#include <QVBoxLayout>
+#include <QHBoxLayout>
+#include <QMenu>
 #include <QPushButton>
 #include <QSlider>
 #include <QTimer>
+#include <QToolButton>
+#include <QVBoxLayout>
 
 // CTK includes
 #include "ctkCallback.h"
+#include "ctkCollapsibleButton.h"
 #include "ctkPopupWidget.h"
 
 // STD includes
@@ -38,31 +42,58 @@
 QWidget* createPanel(const QString& title, QList<ctkPopupWidget*>& popups)
 {
   QWidget* topLevel = new QWidget(0);
+  topLevel->setObjectName("topLevelWidget");
   topLevel->setWindowTitle(title);
+  ctkCollapsibleButton* button = new ctkCollapsibleButton;
   
   QComboBox* focusComboBox = new QComboBox;
+  focusComboBox->setObjectName("focusComboBox");
   focusComboBox->addItem("Focus popup");
   focusComboBox->addItem("Focus popup");
   focusComboBox->addItem("Focus popup");
   focusComboBox->addItem("Focus popup");
   QPushButton* openButton = new QPushButton("Open popup");
+  openButton->setObjectName("openButton");
   QPushButton* toggleButton = new QPushButton("Toggle popup");
+  toggleButton->setObjectName("toggleButton");
   toggleButton->setCheckable(true);
+  QToolButton* pinButton = new QToolButton(0);
+  pinButton->setCheckable(true);
+
+  QVBoxLayout* collapsibleLayout = new QVBoxLayout;
+  collapsibleLayout->addWidget(focusComboBox);
+  button->setLayout(collapsibleLayout);
 
   QVBoxLayout* vlayout = new QVBoxLayout;
-  vlayout->addWidget(focusComboBox);
+  vlayout->addWidget(button);
   vlayout->addWidget(openButton);
   vlayout->addWidget(toggleButton);
+  vlayout->addWidget(pinButton);
   topLevel->setLayout(vlayout);
 
   ctkPopupWidget* focusPopup = new ctkPopupWidget;
+  focusPopup->setObjectName("focusPopup");
   focusPopup->setAutoShow(true);
   focusPopup->setAutoHide(true);
   QPushButton* focusPopupContent = new QPushButton("button");
-  QVBoxLayout* focusLayout = new QVBoxLayout;
+  focusPopupContent->setObjectName("focusPopupContent");
+  QToolButton* popupToolButton = new QToolButton;
+  popupToolButton->setObjectName("popupToolButton");
+  QMenu* menu = new QMenu(popupToolButton);
+  menu->setObjectName("menu");
+  menu->addAction("first menu item");
+  menu->addAction("second menu item");
+  menu->addAction("third menu item");
+  menu->addAction("fourth menu item");
+  popupToolButton->setPopupMode(QToolButton::InstantPopup);
+  popupToolButton->setMenu(menu);
+
+  QHBoxLayout* focusLayout = new QHBoxLayout;
   focusLayout->addWidget(focusPopupContent);
+  focusLayout->addWidget(popupToolButton);
   focusPopup->setLayout(focusLayout);
   focusPopup->setBaseWidget(focusComboBox);
+  focusLayout->setContentsMargins(0,0,0,0);
 
   QPalette palette = focusPopup->palette();
   QLinearGradient linearGradient(QPointF(0.f, 0.f), QPointF(0.f, 0.666f));
@@ -74,12 +105,14 @@ QWidget* createPanel(const QString& title, QList<ctkPopupWidget*>& popups)
   focusPopup->setPalette(palette);
 
   ctkPopupWidget* openPopup = new ctkPopupWidget;
+  openPopup->setObjectName("openPopup");
   openPopup->setFrameStyle(QFrame::Box);
   openPopup->setLineWidth(1);
   openPopup->setAutoShow(false);
   openPopup->setAutoHide(false);
   openPopup->setWindowOpacity(0.7);
   QPushButton* openPopupContent = new QPushButton("Close popup");
+  openPopupContent->setObjectName("openPopupContent");
   QVBoxLayout* openLayout = new QVBoxLayout;
   openLayout->addWidget(openPopupContent);
   openPopup->setLayout(openLayout);
@@ -90,9 +123,11 @@ QWidget* createPanel(const QString& title, QList<ctkPopupWidget*>& popups)
                    openPopup, SLOT(hidePopup()));
                    
   ctkPopupWidget* togglePopup = new ctkPopupWidget;
+  togglePopup->setObjectName("togglePopup");
   togglePopup->setAutoShow(false);
   togglePopup->setAutoHide(false);
   QPushButton* togglePopupContent = new QPushButton("useless button");
+  togglePopupContent->setObjectName("togglePopupContent");
   QVBoxLayout* toggleLayout = new QVBoxLayout;
   toggleLayout->addWidget(togglePopupContent);
   togglePopup->setLayout(toggleLayout);
@@ -101,7 +136,23 @@ QWidget* createPanel(const QString& title, QList<ctkPopupWidget*>& popups)
                    togglePopup, SLOT(showPopup(bool)));
   togglePopup->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
   
-  popups << focusPopup << openPopup << togglePopup;
+  ctkPopupWidget* pinPopup = new ctkPopupWidget;
+  pinPopup->setObjectName("pinPopup");
+  pinPopup->setBaseWidget(pinButton);
+  QPushButton* pinPopupContent = new QPushButton("pin button");
+  pinPopupContent->setCheckable(true);
+  QObject::connect(pinPopupContent, SIGNAL(toggled(bool)),
+                   pinButton, SLOT(setChecked(bool)));
+  QObject::connect(pinButton, SIGNAL(toggled(bool)),
+                   pinPopupContent, SLOT(setChecked(bool)));
+  pinPopupContent->setObjectName("pinPopupContent");
+  QVBoxLayout* pinLayout = new QVBoxLayout;
+  pinLayout->addWidget(pinPopupContent);
+  pinPopup->setLayout(pinLayout);
+  QObject::connect(pinButton, SIGNAL(toggled(bool)),
+                   pinPopup, SLOT(pinPopup(bool)));
+  
+  popups << focusPopup << openPopup << togglePopup << pinPopup;
   return topLevel;
 }
 

+ 3 - 3
Libs/Widgets/ctkAxesWidget.cpp

@@ -265,7 +265,7 @@ void ctkAxesWidget::paintEvent(QPaintEvent *)
         {
         pen.setWidth(3);
         //pen.setColor(QColor(64, 64, 72)); // Payne's grey
-        pen.setColor(this->palette().color(QPalette::Highlight));
+        pen.setColor(this->palette().color(QPalette::Active, QPalette::Highlight));
         }
       painter.setPen(pen);
       }
@@ -280,11 +280,11 @@ void ctkAxesWidget::paintEvent(QPaintEvent *)
   if (//d->HighlightAxes &&
       d->HighlightAxis == ctkAxesWidget::None)
     {
-    rg.setColorAt(0., this->palette().color(QPalette::Highlight));
+    rg.setColorAt(0., this->palette().color(QPalette::Active, QPalette::Highlight));
     }
   else
     {
-    rg.setColorAt(0., this->palette().color(QPalette::Light));
+    rg.setColorAt(0., this->palette().color(QPalette::Active, QPalette::Light));
     }
   rg.setColorAt(1., QColor(64, 64, 72));
   painter.setBrush(QBrush(rg));

+ 62 - 15
Libs/Widgets/ctkPopupWidget.cpp

@@ -29,6 +29,7 @@
 #include <QMouseEvent>
 #include <QMoveEvent>
 #include <QPainter>
+#include <QPointer>
 #include <QPropertyAnimation>
 #include <QStyle>
 #include <QTimer>
@@ -184,14 +185,17 @@ bool ctkPopupWidgetPrivate::mouseOver()
       }
     }
   // Warning QApplication::widgetAt(QCursor::pos()) can be a bit slow...
-  QWidget* widgetUnderCursor = qApp->widgetAt(QCursor::pos());
+  const QPoint pos = QCursor::pos();
+  QWidget* widgetUnderCursor = qApp->widgetAt(pos);
   foreach(const QWidget* focusWidget, widgets)
     {
     if (this->isAncestorOf(focusWidget, widgetUnderCursor) &&
         // Ignore when cursor is above a title bar of a focusWidget, underMouse
         // wouldn't have return false, but QApplication::widgetAt would return
         // the widget
-        focusWidget != widgetUnderCursor)
+        (focusWidget != widgetUnderCursor ||
+         QRect(QPoint(0,0), focusWidget->size()).contains(
+          focusWidget->mapFromGlobal(pos))))
       {
       widgetUnderCursor->installEventFilter(q);
       return true;
@@ -478,6 +482,8 @@ void ctkPopupWidgetPrivate::updateVisibility()
           topLevelWidget != (this->BaseWidget ? this->BaseWidget->window() : 0) &&
           topLevelWidget->frameGeometry().intersects(q->geometry()))
         {
+        //qDebug() << "hide" << q << "because of: " << topLevelWidget
+        //         << " with windowType: " << topLevelWidget->windowType();
         this->temporarilyHiddenOn();
         return;
         }
@@ -499,7 +505,7 @@ void ctkPopupWidgetPrivate::updateVisibility()
 void ctkPopupWidgetPrivate::onBaseWidgetDestroyed()
 {
   Q_Q(ctkPopupWidget);
-  q->hide();
+  this->hideAll();
   q->setBaseWidget(0);
   // could be a property.
   q->deleteLater();
@@ -516,8 +522,7 @@ void ctkPopupWidgetPrivate::temporarilyHiddenOn()
     this->setProperty("forcedClosed", this->isOpening() ? 2 : 1);
     }
   this->currentAnimation()->stop();
-  this->PopupPixmapWidget->hide();
-  q->hide();
+  this->hideAll();
 }
 
 // -------------------------------------------------------------------------
@@ -542,6 +547,30 @@ void ctkPopupWidgetPrivate::temporarilyHiddenOff()
 }
 
 // -------------------------------------------------------------------------
+void ctkPopupWidgetPrivate::hideAll()
+{
+  Q_Q(ctkPopupWidget);
+  // 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.
+  if (q->isActiveWindow() && this->BaseWidget)
+    {
+    qApp->setActiveWindow(this->BaseWidget->window());
+    }
+
+  q->hide();
+  this->PopupPixmapWidget->hide();
+
+  // If there is a popup open in the ctkPopupWidget children, then hide it
+  // as well so we don't have a popup open while the ctkPopupWidget is hidden.
+  QPointer<QWidget> activePopupWidget = qApp->activePopupWidget();
+  if (activePopupWidget && this->isAncestorOf(q, activePopupWidget))
+    {
+    activePopupWidget->close();
+    }
+}
+
+// -------------------------------------------------------------------------
 // Qt::FramelessWindowHint is required on Windows for Translucent background
 // Qt::Toolip is preferred to Qt::Popup as it would close itself at the first
 // click outside the widget (typically a click in the BaseWidget)
@@ -713,15 +742,14 @@ void ctkPopupWidget::onEffectFinished()
     }
   if (qobject_cast<QAbstractAnimation*>(this->sender())->direction() == QAbstractAnimation::Backward)
     {
-    // 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.
-    if (this->isActiveWindow())
+    d->hideAll();
+    emit this->popupOpened(false);
+    /// restore the AutoShow if needed.
+    if (!this->property("AutoShowOnClose").isNull())
       {
-      qApp->setActiveWindow(d->BaseWidget ? d->BaseWidget->window() : 0);
+      d->AutoShow = this->property("AutoShowOnClose").toBool();
+      this->setProperty("AutoShowOnClose", QVariant());
       }
-    this->hide();
-    emit this->popupOpened(false);
     }
   else
     {
@@ -799,10 +827,15 @@ bool ctkPopupWidget::eventFilter(QObject* obj, QEvent* event)
 	    }	    
     case QEvent::Hide:
     case QEvent::Close:
-      if (obj != d->BaseWidget)
+      // if the mouse was in a base widget child popup, then when we leave
+      // the popup we want to check if it needs to be closed.
+      if (obj != d->BaseWidget  &&
+          qobject_cast<QWidget*>(obj)->windowType() == Qt::Popup)
         {
-	      break;
-	      }
+        QTimer::singleShot(LEAVE_CLOSING_DELAY, this, SLOT(updatePopup()));
+        obj->removeEventFilter(this);
+        break;
+        }
       d->temporarilyHiddenOn();
 	    break;
     case QEvent::Show:
@@ -838,12 +871,22 @@ bool ctkPopupWidget::eventFilter(QObject* obj, QEvent* event)
         }
       break;
     case QEvent::Leave:
+      // Don't listen to base widget children that are popups as what
+      // matters here is their close event instead
+      if (obj != d->BaseWidget &&
+          qobject_cast<QWidget*>(obj)->windowType() == Qt::Popup)
+        {
+        break;
+        }
+      // The mouse might have left the area that keeps the popup open
       QTimer::singleShot(LEAVE_CLOSING_DELAY, this, SLOT(updatePopup()));
       if (obj != d->BaseWidget)
         {
         obj->removeEventFilter(this);
         }
       break;
+    default:
+      break;
     }
   return this->QObject::eventFilter(obj, event);
 }
@@ -988,6 +1031,7 @@ void ctkPopupWidget::hidePopup()
 // --------------------------------------------------------------------------
 void ctkPopupWidget::pinPopup(bool pin)
 {
+  Q_D(ctkPopupWidget);
   this->setAutoHide(!pin);
   if (pin)
     {
@@ -995,6 +1039,9 @@ void ctkPopupWidget::pinPopup(bool pin)
     }
   else
     {
+    // When closing, we don't want to inadvertently re-open the menu.
+    this->setProperty("AutoShowOnClose", this->autoShow());
+    d->AutoShow = false;
     this->hidePopup();
     }
 }

+ 2 - 0
Libs/Widgets/ctkPopupWidget_p.h

@@ -76,6 +76,8 @@ public:
   void temporarilyHiddenOn();
   void temporarilyHiddenOff();
 
+  void hideAll();
+
 public slots:
   void updateVisibility();
   void onBaseWidgetDestroyed();