Browse Source

Merge pull request #841 from jcfr/improve-VTKScalarsToColorsWidget

Improve vtk scalars to colors widget
Jean-Christophe Fillion-Robin 6 years ago
parent
commit
a78063d1f9

+ 9 - 0
Libs/Visualization/VTK/Widgets/Testing/Cpp/ctkVTKScalarsToColorsWidgetTest1.cpp

@@ -24,6 +24,7 @@
 #include <QTimer>
 
 // CTK includes
+#include "ctkCoreTestingMacros.h"
 #include "ctkVTKScalarsToColorsView.h"
 #include "ctkVTKScalarsToColorsWidget.h"
 
@@ -61,12 +62,20 @@ int ctkVTKScalarsToColorsWidgetTest1(int argc, char * argv [] )
   opacityFunction->AddPoint(1.,0.8, 0.5, 0.5);
 
   ctkVTKScalarsToColorsWidget widget(0);
+
+  // check default values
+  CHECK_BOOL(widget.editColors(), true)
+  CHECK_BOOL(widget.areTopWidgetsVisible(), true)
+  CHECK_NULL(widget.currentControlPointsItem())
+
   // add transfer function item
   vtkPlot* plot = widget.view()->addOpacityFunction(opacityFunction);
   plot->SetColor(0, 67,  247, 255);
   widget.view()->setAxesToChartBounds();
   widget.show();
 
+  CHECK_NOT_NULL(widget.currentControlPointsItem())
+
   if (argc < 2 || QString(argv[1]) != "-I")
     {
     QTimer::singleShot(200, &app, SLOT(quit()));

+ 9 - 0
Libs/Visualization/VTK/Widgets/Testing/Cpp/ctkVTKScalarsToColorsWidgetTest2.cpp

@@ -24,6 +24,7 @@
 #include <QTimer>
 
 // CTK includes
+#include "ctkCoreTestingMacros.h"
 #include "ctkVTKScalarsToColorsView.h"
 #include "ctkVTKScalarsToColorsWidget.h"
 
@@ -71,11 +72,19 @@ int ctkVTKScalarsToColorsWidgetTest2(int argc, char * argv [] )
   opacityFunction->AddPoint(0.8, 0.45);
 
   ctkVTKScalarsToColorsWidget widget(0);
+
+  // check default values
+  CHECK_BOOL(widget.editColors(), true)
+  CHECK_BOOL(widget.areTopWidgetsVisible(), true)
+  CHECK_NULL(widget.currentControlPointsItem())
+
   // add transfer function item
   widget.view()->addCompositeFunction(ctf, opacityFunction);
   widget.view()->setAxesToChartBounds();
   widget.show();
 
+  CHECK_NOT_NULL(widget.currentControlPointsItem())
+
   if (argc < 2 || QString(argv[1]) != "-I")
     {
     QTimer::singleShot(200, &app, SLOT(quit()));

+ 9 - 0
Libs/Visualization/VTK/Widgets/Testing/Cpp/ctkVTKScalarsToColorsWidgetTest3.cpp

@@ -24,6 +24,7 @@
 #include <QTimer>
 
 // CTK includes
+#include "ctkCoreTestingMacros.h"
 #include "ctkVTKScalarsToColorsView.h"
 #include "ctkVTKScalarsToColorsWidget.h"
 
@@ -63,11 +64,19 @@ int ctkVTKScalarsToColorsWidgetTest3(int argc, char * argv [] )
   ctf->AddRGBPoint(1.,  183./255., 7./255., 140./255.);
 
   ctkVTKScalarsToColorsWidget widget(0);
+
+  // check default values
+  CHECK_BOOL(widget.editColors(), true)
+  CHECK_BOOL(widget.areTopWidgetsVisible(), true)
+  CHECK_NULL(widget.currentControlPointsItem())
+
   // add transfer function item
   widget.view()->addColorTransferFunction(ctf);
   widget.view()->setAxesToChartBounds();
   widget.show();
 
+  CHECK_NOT_NULL(widget.currentControlPointsItem())
+
   if (argc < 2 || QString(argv[1]) != "-I")
     {
     QTimer::singleShot(200, &app, SLOT(quit()));

+ 42 - 9
Libs/Visualization/VTK/Widgets/ctkVTKScalarsToColorsWidget.cpp

@@ -63,6 +63,7 @@ public:
 
   vtkControlPointsItem* CurrentControlPointsItem;
   bool EditColors;
+  bool TopWidgetsVisible;
 };
 
 // ----------------------------------------------------------------------------
@@ -75,6 +76,7 @@ ctkVTKScalarsToColorsWidgetPrivate::ctkVTKScalarsToColorsWidgetPrivate(
 {
   this->CurrentControlPointsItem = 0;
   this->EditColors = true;
+  this->TopWidgetsVisible = true;
 }
 
 // ----------------------------------------------------------------------------
@@ -249,10 +251,35 @@ void ctkVTKScalarsToColorsWidget::setEditColors(bool edit)
 }
 
 // ----------------------------------------------------------------------------
+bool ctkVTKScalarsToColorsWidget::areTopWidgetsVisible()const
+{
+  Q_D(const ctkVTKScalarsToColorsWidget);
+  return d->TopWidgetsVisible;
+}
+
+// ----------------------------------------------------------------------------
+void ctkVTKScalarsToColorsWidget::setTopWidgetsVisible(bool visible)
+{
+  Q_D(ctkVTKScalarsToColorsWidget);
+  d->ExpandButton->setVisible(visible);
+  d->PointIdLabel->setVisible(visible);
+  d->PointIdSpinBox->setVisible(visible);
+  foreach(QWidget* widget, this->extraWidgets())
+  {
+    widget->setVisible(visible);
+  }
+  d->TopSpacer->changeSize(visible ? 40 : 0, visible ? 20 : 0);
+  d->TopSpacer->invalidate();
+  d->TopWidgetsVisible = visible;
+}
+
+// ----------------------------------------------------------------------------
 void ctkVTKScalarsToColorsWidget::onPlotAdded(vtkPlot* plot)
 {
-  if (vtkControlPointsItem::SafeDownCast(plot))
+  vtkControlPointsItem* controlPoints = vtkControlPointsItem::SafeDownCast(plot);
+  if (controlPoints)
     {
+    this->setCurrentControlPointsItem(controlPoints);
     this->qvtkConnect(plot, vtkControlPointsItem::CurrentPointChangedEvent,
                       this, SLOT(setCurrentPoint(vtkObject*,void*)));
     }
@@ -319,15 +346,17 @@ void ctkVTKScalarsToColorsWidget::setCurrentControlPointsItem(vtkControlPointsIt
   d->CurrentControlPointsItem = item;
   if (item)
     {
-    d->ColorPickerButton->setVisible( d->EditColors &&
+    d->ColorPickerButton->setVisible( d->EditColors && d->TopWidgetsVisible &&
       (vtkColorTransferControlPointsItem::SafeDownCast(item) != 0 ||
        vtkCompositeControlPointsItem::SafeDownCast(item) != 0));
-    d->XLabel->setVisible(true);
-    d->XSpinBox->setVisible(true);
-    d->OpacityLabel->setVisible(vtkPiecewiseControlPointsItem::SafeDownCast(item) != 0 ||
-                                vtkCompositeControlPointsItem::SafeDownCast(item) != 0);
-    d->OpacitySpinBox->setVisible(vtkPiecewiseControlPointsItem::SafeDownCast(item) != 0 ||
-                                  vtkCompositeControlPointsItem::SafeDownCast(item) != 0);
+    d->XLabel->setVisible(d->TopWidgetsVisible);
+    d->XSpinBox->setVisible(d->TopWidgetsVisible);
+    d->OpacityLabel->setVisible(d->TopWidgetsVisible &&
+      (vtkPiecewiseControlPointsItem::SafeDownCast(item) != 0 ||
+       vtkCompositeControlPointsItem::SafeDownCast(item) != 0));
+    d->OpacitySpinBox->setVisible(d->TopWidgetsVisible &&
+      (vtkPiecewiseControlPointsItem::SafeDownCast(item) != 0 ||
+       vtkCompositeControlPointsItem::SafeDownCast(item) != 0));
     this->onAxesModified();
     }
   d->PointIdSpinBox->setEnabled(item != 0);
@@ -393,7 +422,7 @@ void ctkVTKScalarsToColorsWidget::updateCurrentPoint()
   vtkAxis* xAxis = d->CurrentControlPointsItem ?
     d->CurrentControlPointsItem->GetXAxis() : d->View->chart()->GetAxis(vtkAxis::BOTTOM);
   Q_ASSERT(xAxis);
-  if (xAxis && xAxis->GetMinimumLimit() > point[0] || xAxis->GetMaximumLimit() < point[0])
+  if (xAxis && (xAxis->GetMinimumLimit() > point[0] || xAxis->GetMaximumLimit() < point[0]))
     {
     xAxis->SetMinimumLimit(qMin(xAxis->GetMinimumLimit(), point[0]));
     xAxis->SetMaximumLimit(qMax(xAxis->GetMaximumLimit(), point[0]));
@@ -646,4 +675,8 @@ void ctkVTKScalarsToColorsWidget::addExtraWidget(QWidget* extraWidget)
 {
   Q_D(const ctkVTKScalarsToColorsWidget);
   d->TopLayout->insertWidget(this->extraWidgets().count(), extraWidget);
+  if (!d->TopWidgetsVisible)
+    {
+    extraWidget->setVisible(d->TopWidgetsVisible);
+    }
 }

+ 34 - 2
Libs/Visualization/VTK/Widgets/ctkVTKScalarsToColorsWidget.h

@@ -35,6 +35,24 @@ class vtkControlPointsItem;
 class vtkPlot;
 
 /// \ingroup Visualization_VTK_Widgets
+///
+/// This widget includes a ctkVTKScalarsToColorsView and a "top widget" to display and update its properties.
+///
+/// Features are:
+/// * vertical and horizontal scrollbars (if needed, visible by default)
+/// * a "top widget" including selected point index, its coordinate and color. An expand button allows to access
+///   advanced properties like mid point and sharpness.
+/// * if a piecewise or composite function are added to the view, the opacity is available in the "top widget" advanced properties.
+/// * color associated with points can be updated in place (editable by default).
+/// * support customization of widget shown in the top-left corner. See addExtraWidget().
+/// * visibility of the "top widgets" can easily be updated.
+///
+/// Observing vtkControlPointsItem allows to be notified of point selection or
+/// point update:
+/// * event vtkControlPointsItem::CurrentPointChangedEvent is invoked each time a point is selected. Associated
+///   call data is the point index.
+/// * event vtkCommand::ModifiedEvent is invoked each time a point is updated.
+///
 class CTK_VISUALIZATION_VTK_WIDGETS_EXPORT ctkVTKScalarsToColorsWidget : public QWidget
 {
   Q_OBJECT
@@ -42,6 +60,7 @@ class CTK_VISUALIZATION_VTK_WIDGETS_EXPORT ctkVTKScalarsToColorsWidget : public
   Q_PROPERTY(bool horizontalSliderVisible READ isHorizontalSliderVisible WRITE setHorizontalSliderVisible)
   Q_PROPERTY(bool verticalSliderVisible READ isVerticalSliderVisible WRITE setVerticalSliderVisible)
   Q_PROPERTY(bool editColors READ editColors WRITE setEditColors)
+  Q_PROPERTY(bool areTopWidgetsVisible READ areTopWidgetsVisible WRITE setTopWidgetsVisible)
 public:
   ctkVTKScalarsToColorsWidget(QWidget* parent = 0);
   virtual ~ctkVTKScalarsToColorsWidget();
@@ -61,13 +80,26 @@ public:
   void xRange(double* range)const;
   void yRange(double* range)const;
 
+  /// Hide all widgets displayed above the color view.
   ///
+  /// This function internally keeps track of the selected visibility state
+  /// by setting a "TopWidgetsVisible" property. This means that:
+  /// (1) widgets for editing point coordinate and color are
+  ///     not shown in the "top widgets" when a point is selected or modified.
+  /// (2) widgets added using addExtraWidget() are explicitly hidden if it applies.
+  bool areTopWidgetsVisible()const;
+  void setTopWidgetsVisible(bool visible);
+
   /// Return the top-left corner widget if any.
+  ///
+  /// \sa addExtraWidget()
   QWidgetList extraWidgets()const;
 
-  ///
   /// Add a widget in the top-left corner.
-  /// ctkVTKScalarsToColorsWidget takes ownership of the widget
+  ///
+  /// ctkVTKScalarsToColorsWidget takes ownership of the widget.
+  ///
+  /// \sa extraWidgets()
   void addExtraWidget(QWidget* extraWidget);
 
 public Q_SLOTS: