Browse Source

Merge branch 'ctkThumbnailWidget-sizing'

* ctkThumbnailWidget-sizing:
  Fix ctkThumbnailWidget autosizing
Julien Finet 13 years ago
parent
commit
e5d6c6422e

+ 2 - 0
Libs/DICOM/Widgets/Testing/Cpp/CMakeLists.txt

@@ -11,6 +11,7 @@ CREATE_TEST_SOURCELIST(Tests ${KIT}CppTests.cpp
   ctkDICOMQueryResultsTabWidgetTest1.cpp
   ctkDICOMQueryRetrieveWidgetTest1.cpp
   ctkDICOMServerNodeWidgetTest1.cpp
+  ctkDICOMThumbnailListWidgetTest1.cpp
   )
 
 SET (TestsToRun ${Tests})
@@ -52,3 +53,4 @@ SET_PROPERTY(TEST ctkDICOMModelTest2 PROPERTY LABELS ${PROJECT_NAME})
 
 SIMPLE_TEST(ctkDICOMQueryRetrieveWidgetTest1)
 SIMPLE_TEST(ctkDICOMQueryResultsTabWidgetTest1)
+SIMPLE_TEST(ctkDICOMThumbnailListWidgetTest1)

+ 46 - 0
Libs/DICOM/Widgets/Testing/Cpp/ctkDICOMThumbnailListWidgetTest1.cpp

@@ -0,0 +1,46 @@
+/*=========================================================================
+
+  Library:   CTK
+
+  Copyright (c) Kitware Inc.
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0.txt
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+
+=========================================================================*/
+
+// Qt includes
+#include <QApplication>
+#include <QDir>
+#include <QTimer>
+
+// ctkDICOMCore includes
+#include "ctkDICOMThumbnailListWidget.h"
+
+// STD includes
+#include <iostream>
+
+int ctkDICOMThumbnailListWidgetTest1( int argc, char * argv [] )
+{
+  QApplication app(argc, argv);
+
+  ctkDICOMThumbnailListWidget widget;
+  widget.setDatabaseDirectory(QDir::currentPath());
+  widget.show();
+
+  if (argc <= 1 || QString(argv[1]) != "-I")
+    {
+    QTimer::singleShot(200, &app, SLOT(quit()));
+    }
+
+  return app.exec();
+}

+ 3 - 2
Libs/DICOM/Widgets/ctkDICOMAppWidget.cpp

@@ -127,7 +127,8 @@ ctkDICOMAppWidget::ctkDICOMAppWidget(QWidget* _parent):Superclass(_parent),
   d->DICOMProxyModel.setSourceModel(&d->DICOMModel);
   d->TreeView->setModel(&d->DICOMModel);
 
-  d->ThumbnailsWidget->setThumbnailWidth(d->ThumbnailWidthSlider->value());
+  d->ThumbnailsWidget->setThumbnailSize(
+    QSize(d->ThumbnailWidthSlider->value(), d->ThumbnailWidthSlider->value()));
 
   connect(d->TreeView, SIGNAL(collapsed(QModelIndex)), this, SLOT(onTreeCollapsed(QModelIndex)));
   connect(d->TreeView, SIGNAL(expanded(QModelIndex)), this, SLOT(onTreeExpanded(QModelIndex)));
@@ -660,7 +661,7 @@ void ctkDICOMAppWidget::onAutoPlayTimer(){
 //----------------------------------------------------------------------------
 void ctkDICOMAppWidget::onThumbnailWidthSliderValueChanged(int val){
   Q_D(ctkDICOMAppWidget);
-  d->ThumbnailsWidget->setThumbnailWidth(val);
+  d->ThumbnailsWidget->setThumbnailSize(QSize(val, val));
 }
 
 //----------------------------------------------------------------------------

+ 2 - 3
Libs/DICOM/Widgets/ctkDICOMThumbnailListWidget.cpp

@@ -199,9 +199,8 @@ void ctkDICOMThumbnailListWidgetPrivate::addThumbnailWidget(const QModelIndex& i
         widget->setText( widgetLabel );
         QPixmap pix(thumbnailPath);
         logger.debug("Setting pixmap to " + thumbnailPath);
-        if(this->ThumbnailWidth > 0){
-          widget->setMaximumWidth(this->ThumbnailWidth);
-          widget->setMinimumWidth(this->ThumbnailWidth);
+        if(this->ThumbnailSize.isValid()){
+          widget->setFixedSize(this->ThumbnailSize);
         }
         widget->setPixmap(pix);
 

+ 0 - 9
Libs/Widgets/Resources/UI/ctkThumbnailWidget.ui

@@ -13,9 +13,6 @@
   <property name="windowTitle">
    <string>Thumbnail</string>
   </property>
-  <property name="styleSheet">
-   <string notr="true">background-color:white</string>
-  </property>
   <layout class="QGridLayout" name="gridLayout" rowstretch="0,1" columnstretch="0,1">
    <property name="margin">
     <number>4</number>
@@ -32,12 +29,6 @@
    </item>
    <item row="1" column="1">
     <widget class="QLabel" name="PixmapLabel">
-     <property name="sizePolicy">
-      <sizepolicy hsizetype="Ignored" vsizetype="Ignored">
-       <horstretch>0</horstretch>
-       <verstretch>0</verstretch>
-      </sizepolicy>
-     </property>
      <property name="alignment">
       <set>Qt::AlignCenter</set>
      </property>

+ 9 - 4
Libs/Widgets/Testing/Cpp/ctkThumbnailListWidgetTest1.cpp

@@ -40,25 +40,30 @@ int ctkThumbnailListWidgetTest1( int argc, char * argv [] )
   QPixmap pix1(QSize(128, 128));;
   QPixmap pix2(QSize(64, 64));
   QPixmap pix3(QSize(256, 256));
+  QPixmap pix4(QSize(256, 128));
+
 
   pix1.fill(Qt::green);
   pix2.fill(Qt::yellow);
   pix3.fill(Qt::blue);
+  pix4.fill(Qt::red);
 
   QList<QPixmap> pixList;
 
-  widget.setThumbnailWidth(128);
-  if(widget.thumbnailWidth() != 128)
+  widget.setThumbnailSize(QSize(128, 128));
+  if(widget.thumbnailSize() != QSize(128, 128))
     {
       std::cerr << "ctkThumbnailListWidget::setThumbnailWidth failed."
-		<< " text: " << qPrintable(QVariant(widget.thumbnailWidth()).toString())
-		<< " expected: 128" << std::endl;
+        << " size: " << widget.thumbnailSize().width()
+        << "," << widget.thumbnailSize().height()
+        << " expected: 128" << std::endl;
       return EXIT_FAILURE;
     }
 
   pixList.append(pix1);
   pixList.append(pix2);
   pixList.append(pix3);
+  pixList.append(pix4);
 
   widget.addThumbnails(pixList);
 

+ 13 - 15
Libs/Widgets/ctkThumbnailListWidget.cpp

@@ -60,7 +60,7 @@ void ctkThumbnailListWidgetPrivate::init(){
   this->ScrollAreaContentWidget->setLayout(new ctkFlowLayout);
   qobject_cast<ctkFlowLayout*>(this->ScrollAreaContentWidget->layout())->setHorizontalSpacing(4);
 
-  this->ThumbnailWidth = -1;
+  this->ThumbnailSize = QSize(-1, -1);
   this->CurrentThumbnail = -1;
 }
 
@@ -98,6 +98,7 @@ ctkThumbnailListWidget::ctkThumbnailListWidget(QWidget* _parent):
   d->init();
 }
 
+//----------------------------------------------------------------------------
 ctkThumbnailListWidget::ctkThumbnailListWidget(ctkThumbnailListWidgetPrivate *_ptr, QWidget *_parent):
   Superclass(_parent),
   d_ptr(_ptr)
@@ -123,8 +124,8 @@ void ctkThumbnailListWidget::addThumbnails(QList<QPixmap> thumbnails)
     {
       ctkThumbnailWidget* widget = new ctkThumbnailWidget(d->ScrollAreaContentWidget);
       widget->setText("");
-      if(d->ThumbnailWidth > 0){
-        widget->setFixedWidth(d->ThumbnailWidth);
+      if(d->ThumbnailSize.isValid()){
+        widget->setFixedSize(d->ThumbnailSize);
       }
       widget->setPixmap(thumbnails[i]);
       d->ScrollAreaContentWidget->layout()->addWidget(widget);
@@ -183,26 +184,23 @@ void ctkThumbnailListWidget::onThumbnailSelected(const ctkThumbnailWidget &widge
 }
 
 //----------------------------------------------------------------------------
-void ctkThumbnailListWidget::setThumbnailWidth(int width){
+void ctkThumbnailListWidget::setThumbnailSize(QSize size){
   Q_D(ctkThumbnailListWidget);
-  for(int i=0; i<d->ScrollAreaContentWidget->layout()->count(); i++)
+  if (size.isValid())
     {
-    ctkThumbnailWidget* thumbnailWidget = qobject_cast<ctkThumbnailWidget*>(d->ScrollAreaContentWidget->layout()->itemAt(i)->widget());
-    if(thumbnailWidget)
+    foreach( ctkThumbnailWidget* thumbnail,
+             this->findChildren<ctkThumbnailWidget*>())
       {
-        if(width > 0){
-          thumbnailWidget->setFixedWidth(width);
-        }
+      thumbnail->setFixedSize(size);
       }
     }
-
-  d->ThumbnailWidth = width;
+  d->ThumbnailSize = size;
 }
 
 //----------------------------------------------------------------------------
-int ctkThumbnailListWidget::thumbnailWidth(){
-  Q_D(ctkThumbnailListWidget);
-  return d->ThumbnailWidth;
+QSize ctkThumbnailListWidget::thumbnailSize()const{
+  Q_D(const ctkThumbnailListWidget);
+  return d->ThumbnailSize;
 }
 
 //----------------------------------------------------------------------------

+ 7 - 6
Libs/Widgets/ctkThumbnailListWidget.h

@@ -34,7 +34,7 @@ class CTK_WIDGETS_EXPORT ctkThumbnailListWidget : public QWidget
 {
   Q_OBJECT
   Q_PROPERTY(int currentThumbnail READ currentThumbnail WRITE setCurrentThumbnail)
-  Q_PROPERTY(int thumbnailWidth READ thumbnailWidth WRITE setThumbnailWidth)
+  Q_PROPERTY(QSize thumbnailSize READ thumbnailSize WRITE setThumbnailSize)
 public:
   typedef QWidget Superclass;
   explicit ctkThumbnailListWidget(QWidget* parent=0);
@@ -53,18 +53,19 @@ public:
   void clearThumbnails();
 
   /// Get thumbnail width
-  int thumbnailWidth();
+  QSize thumbnailSize()const;
+
+public slots:
+  /// Set thumbnail width
+  void setThumbnailSize(QSize size);
 
 signals:
   void selected(const ctkThumbnailWidget& widget);
   void doubleClicked(const ctkThumbnailWidget& widget);
 
-public slots:
+protected slots:
   void onThumbnailSelected(const ctkThumbnailWidget& widget);
 
-  /// Set thumbnail width
-  void setThumbnailWidth(int width);
-
 protected:
   explicit ctkThumbnailListWidget(ctkThumbnailListWidgetPrivate* ptr, QWidget* parent=0);
   ctkThumbnailListWidgetPrivate* d_ptr;

+ 4 - 4
Libs/Widgets/ctkThumbnailListWidget_p.h

@@ -29,6 +29,9 @@ class ctkThumbnailListWidget;
 //----------------------------------------------------------------------------
 class CTK_WIDGETS_EXPORT ctkThumbnailListWidgetPrivate : public Ui_ctkThumbnailListWidget
 {
+  Q_DECLARE_PUBLIC(ctkThumbnailListWidget);
+protected:
+  ctkThumbnailListWidget* const q_ptr;
 public:
   ctkThumbnailListWidgetPrivate(ctkThumbnailListWidget* parent);
 
@@ -38,10 +41,7 @@ public:
   void clearAllThumbnails();
 
   int CurrentThumbnail;
-  int ThumbnailWidth;
-
-  ctkThumbnailListWidget* const q_ptr;
-  Q_DECLARE_PUBLIC(ctkThumbnailListWidget);
+  QSize ThumbnailSize;
 };
 
 #endif

+ 89 - 34
Libs/Widgets/ctkThumbnailWidget.cpp

@@ -18,39 +18,45 @@
 
 =========================================================================*/
 
-// ctkDICOMWidgets includes
+// Qt includes
+#include <QApplication>
+#include <QColor>
+#include <QPainter>
+
+// ctkCore includes
+#include "ctkLogger.h"
+static ctkLogger logger("org.commontk.Widgets.ctkThumbnailWidget");
+
+// ctkWidgets includes
 #include "ctkThumbnailWidget.h"
 #include "ui_ctkThumbnailWidget.h"
 
 // STD includes
 #include <iostream>
 
-// Qt includes
-#include <QColor>
-
-// logger includes
-#include "ctkLogger.h"
-static ctkLogger logger("org.commontk.Widgets.ctkDICOMThumbnailListWidget");
-
 //----------------------------------------------------------------------------
 class ctkThumbnailWidgetPrivate: public Ui_ctkThumbnailWidget
 {
+  Q_DECLARE_PUBLIC(ctkThumbnailWidget);
+protected:
+  ctkThumbnailWidget* const q_ptr;
 public:
-    ctkThumbnailWidget* const q_ptr;
-    Q_DECLARE_PUBLIC(ctkThumbnailWidget);
+  typedef Ui_ctkThumbnailWidget Superclass;
+
+  // Constructor
+  ctkThumbnailWidgetPrivate(ctkThumbnailWidget* parent);
 
-    // Constructor
-    ctkThumbnailWidgetPrivate(ctkThumbnailWidget* parent);
+  virtual void setupUi(QWidget* widget);
 
-    Qt::Alignment TextPosition;
-    bool SelectedFlag;
-    QColor SelectedColor;
-    QModelIndex SourceIndex;
-    QPixmap OriginalThumbnail;
-    Qt::TransformationMode TransformationMode;
+  Qt::Alignment TextPosition;
+  bool SelectedFlag;
+  QColor SelectedColor;
+  QModelIndex SourceIndex;
+  QPixmap OriginalThumbnail;
+  Qt::TransformationMode TransformationMode;
 
-    // Redraw thumbnail
-    void updateThumbnail();
+  // Redraw thumbnail
+  void updateThumbnail();
 };
 
 //----------------------------------------------------------------------------
@@ -69,6 +75,16 @@ ctkThumbnailWidgetPrivate::ctkThumbnailWidgetPrivate(ctkThumbnailWidget* parent)
 }
 
 //----------------------------------------------------------------------------
+void ctkThumbnailWidgetPrivate::setupUi(QWidget* widget)
+{
+  Q_Q(ctkThumbnailWidget);
+  this->Superclass::setupUi(widget);
+  q->layout()->setSizeConstraint(QLayout::SetNoConstraint);
+  // no text by default
+  q->setText(QString());
+}
+
+//----------------------------------------------------------------------------
 void ctkThumbnailWidgetPrivate::updateThumbnail()
 {
   this->PixmapLabel->setPixmap(
@@ -89,7 +105,6 @@ ctkThumbnailWidget::ctkThumbnailWidget(QWidget* parentWidget)
   Q_D(ctkThumbnailWidget);
 
   d->setupUi(this);
-  this->setTextPosition(Qt::AlignTop | Qt::AlignHCenter);
 }
 
 //----------------------------------------------------------------------------
@@ -103,6 +118,9 @@ void ctkThumbnailWidget::setText(const QString &text)
   Q_D(ctkThumbnailWidget);
 
   d->TextLabel->setText(text);
+  d->TextLabel->setVisible(!text.isEmpty() &&
+    ! (d->TextPosition & Qt::AlignHCenter &&
+       d->TextPosition & Qt::AlignVCenter) );
 }
 
 //----------------------------------------------------------------------------
@@ -206,23 +224,26 @@ void ctkThumbnailWidget::setTransformationMode(Qt::TransformationMode mode)
 }
 
 //----------------------------------------------------------------------------
-void ctkThumbnailWidget::setSelected(bool flag)
+void ctkThumbnailWidget::paintEvent(QPaintEvent* event)
 {
   Q_D(ctkThumbnailWidget);
-
-  if(flag && d->SelectedColor.isValid())
+  this->Superclass::paintEvent(event);
+  if (d->SelectedFlag && d->SelectedColor.isValid())
     {
-    QPalette p(this->palette());
-    p.setColor(QPalette::Window, d->SelectedColor);
-    this->setPalette(p);
-    this->setAutoFillBackground(true);
-    }
-  else
-    {
-    this->setAutoFillBackground(false);
+    QPainter p(this);
+    QPen pen(d->SelectedColor);
+    pen.setWidth(7);
+    p.setPen(pen);
+    p.drawRect(QRect(0,0, this->width() -1, this->height() -1));
     }
+}
 
+//----------------------------------------------------------------------------
+void ctkThumbnailWidget::setSelected(bool flag)
+{
+  Q_D(ctkThumbnailWidget);
   d->SelectedFlag = flag;
+  this->update();
 }
 
 //----------------------------------------------------------------------------
@@ -237,8 +258,7 @@ void ctkThumbnailWidget::setSelectedColor(const QColor& color)
 {
   Q_D(ctkThumbnailWidget);
   d->SelectedColor = color;
-  // repaint if the color has changed.
-  this->setSelected(this->isSelected());
+  this->update();
 }
 
 //----------------------------------------------------------------------------
@@ -249,6 +269,41 @@ QColor ctkThumbnailWidget::selectedColor()const
 }
 
 //----------------------------------------------------------------------------
+QSize ctkThumbnailWidget::minimumSizeHint()const
+{
+  Q_D(const ctkThumbnailWidget);
+  if (d->TextLabel->isVisibleTo(const_cast<ctkThumbnailWidget*>(this)) &&
+      !d->TextLabel->text().isEmpty())
+    {
+    return d->TextLabel->minimumSizeHint();
+    }
+  return QSize();
+}
+
+//----------------------------------------------------------------------------
+QSize ctkThumbnailWidget::sizeHint()const
+{
+  Q_D(const ctkThumbnailWidget);
+  return d->OriginalThumbnail.isNull() ?
+    this->Superclass::sizeHint() :
+    d->OriginalThumbnail.size().expandedTo(QApplication::globalStrut());
+}
+
+//----------------------------------------------------------------------------
+int ctkThumbnailWidget::heightForWidth(int width)const
+{
+  Q_D(const ctkThumbnailWidget);
+  if (d->OriginalThumbnail.isNull() ||
+      d->OriginalThumbnail.width() == 0)
+    {
+    return this->Superclass::heightForWidth(width);
+    }
+  double ratio = static_cast<double>(d->OriginalThumbnail.height()) /
+    static_cast<double>(d->OriginalThumbnail.width());
+  return static_cast<int>(ratio * width + 0.5);
+}
+
+//----------------------------------------------------------------------------
 void ctkThumbnailWidget::mousePressEvent(QMouseEvent* event)
 {
   this->Superclass::mousePressEvent(event);

+ 8 - 0
Libs/Widgets/ctkThumbnailWidget.h

@@ -32,9 +32,12 @@ class ctkThumbnailWidgetPrivate;
 class CTK_WIDGETS_EXPORT ctkThumbnailWidget : public QWidget
 {
   Q_OBJECT
+  /// If the text is empty, the space allocated for the text is hidden
+  /// Empty by default
   Q_PROPERTY(QString text READ text WRITE setText)
   /// Position of the text relative to the pixmap.
   /// Qt::AlignTop | Qt::AlignHCenter by default.
+  /// For now, if the alignment is HCenter|VCenter, no text is shown.
   Q_PROPERTY(Qt::Alignment textPosition READ textPosition WRITE setTextPosition)
   Q_PROPERTY(QPixmap pixmap READ pixmap WRITE setPixmap)
   /// Qt::FastTransformation by default
@@ -66,9 +69,14 @@ public:
   void setSelectedColor(const QColor& color);
   QColor selectedColor()const;
 
+  virtual QSize minimumSizeHint()const;
+  virtual QSize sizeHint()const;
+  virtual int heightForWidth(int width)const;
+
 protected:
   QScopedPointer<ctkThumbnailWidgetPrivate> d_ptr;
 
+  virtual void paintEvent(QPaintEvent* event);
   virtual void mousePressEvent(QMouseEvent* event);
   virtual void mouseDoubleClickEvent(QMouseEvent* event);