ソースを参照

Add ctkMaterialPropertyWidget

Julien Finet 14 年 前
コミット
612e9728b9

+ 4 - 0
Libs/Widgets/CMakeLists.txt

@@ -56,6 +56,8 @@ SET(KIT_SRCS
   ctkIconEnginePlugin.h
   ctkMaterialPropertyPreviewLabel.cpp
   ctkMaterialPropertyPreviewLabel.h
+  ctkMaterialPropertyWidget.cpp
+  ctkMaterialPropertyWidget.h
   ctkMatrixWidget.cpp
   ctkMatrixWidget.h
   ctkMenuButton.cpp
@@ -132,6 +134,7 @@ SET(KIT_MOC_SRCS
   ctkFittedTextBrowser.h
   ctkIconEnginePlugin.h
   ctkMaterialPropertyPreviewLabel.h
+  ctkMaterialPropertyWidget.h
   ctkMatrixWidget.h
   ctkMenuButton.h
   ctkRangeSlider.h
@@ -163,6 +166,7 @@ SET(KIT_UI_FORMS
   Resources/UI/ctkAddRemoveComboBox.ui
   Resources/UI/ctkRangeWidget.ui
   Resources/UI/ctkDateRangeWidget.ui
+  Resources/UI/ctkMaterialPropertyWidget.ui
   Resources/UI/ctkScreenshotDialog.ui
   Resources/UI/ctkSliderWidget.ui
   Resources/UI/ctkWorkflowGroupBox.ui

+ 3 - 0
Libs/Widgets/Plugins/CMakeLists.txt

@@ -41,6 +41,8 @@ SET(PLUGIN_SRCS
   ctkFittedTextBrowserPlugin.h
   ctkMaterialPropertyPreviewLabelPlugin.cpp
   ctkMaterialPropertyPreviewLabelPlugin.h
+  ctkMaterialPropertyWidgetPlugin.cpp
+  ctkMaterialPropertyWidgetPlugin.h
   ctkMatrixWidgetPlugin.cpp
   ctkMatrixWidgetPlugin.h
   ctkMenuButtonPlugin.cpp
@@ -78,6 +80,7 @@ SET(PLUGIN_MOC_SRCS
   ctkDynamicSpacerPlugin.h
   #ctkExtensionFactory.h
   ctkFittedTextBrowserPlugin.h
+  ctkMaterialPropertyWidgetPlugin.h
   ctkMaterialPropertyPreviewLabelPlugin.h
   ctkMatrixWidgetPlugin.h
   ctkMenuButtonPlugin.h

+ 67 - 0
Libs/Widgets/Plugins/ctkMaterialPropertyWidgetPlugin.cpp

@@ -0,0 +1,67 @@
+/*=========================================================================
+
+  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.commontk.org/LICENSE
+
+  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.
+
+=========================================================================*/
+
+// CTK includes
+#include "ctkMaterialPropertyWidgetPlugin.h"
+#include "ctkMaterialPropertyWidget.h"
+
+//-----------------------------------------------------------------------------
+ctkMaterialPropertyWidgetPlugin::ctkMaterialPropertyWidgetPlugin(QObject *_parent) : QObject(_parent)
+{
+}
+
+//-----------------------------------------------------------------------------
+QWidget *ctkMaterialPropertyWidgetPlugin::createWidget(QWidget *_parent)
+{
+  ctkMaterialPropertyWidget* _widget = new ctkMaterialPropertyWidget(_parent);
+  return _widget;
+}
+
+//-----------------------------------------------------------------------------
+QString ctkMaterialPropertyWidgetPlugin::domXml() const
+{
+  return "<widget class=\"ctkMaterialPropertyWidget\" \
+          name=\"MaterialPropertyWidget\">\n"
+          "</widget>\n";
+}
+
+//-----------------------------------------------------------------------------
+QIcon ctkMaterialPropertyWidgetPlugin::icon() const
+{
+  return QIcon(":/Icons/pushbutton.png");
+}
+
+//-----------------------------------------------------------------------------
+QString ctkMaterialPropertyWidgetPlugin::includeFile() const
+{
+  return "ctkMaterialPropertyWidget.h";
+}
+
+//-----------------------------------------------------------------------------
+bool ctkMaterialPropertyWidgetPlugin::isContainer() const
+{
+  return false;
+}
+
+//-----------------------------------------------------------------------------
+QString ctkMaterialPropertyWidgetPlugin::name() const
+{
+  return "ctkMaterialPropertyWidget";
+}

+ 44 - 0
Libs/Widgets/Plugins/ctkMaterialPropertyWidgetPlugin.h

@@ -0,0 +1,44 @@
+/*=========================================================================
+
+  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.commontk.org/LICENSE
+
+  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.
+
+=========================================================================*/
+
+#ifndef __ctkMaterialPropertyWidgetPlugin_h
+#define __ctkMaterialPropertyWidgetPlugin_h
+
+// CTK includes
+#include "ctkWidgetsAbstractPlugin.h"
+
+class CTK_WIDGETS_PLUGINS_EXPORT ctkMaterialPropertyWidgetPlugin :
+  public QObject,
+  public ctkWidgetsAbstractPlugin
+{
+  Q_OBJECT
+
+public:
+  ctkMaterialPropertyWidgetPlugin(QObject *_parent = 0);
+  
+  QWidget *createWidget(QWidget *_parent);
+  QString  domXml() const;
+  QIcon    icon() const;
+  QString  includeFile() const;
+  bool     isContainer() const;
+  QString  name() const;
+};
+
+#endif

+ 2 - 0
Libs/Widgets/Plugins/ctkWidgetsPlugins.h

@@ -39,6 +39,7 @@
 #include "ctkDynamicSpacerPlugin.h"
 #include "ctkFittedTextBrowserPlugin.h"
 #include "ctkMaterialPropertyPreviewLabelPlugin.h"
+#include "ctkMaterialPropertyWidgetPlugin.h"
 #include "ctkMatrixWidgetPlugin.h"
 #include "ctkMenuButtonPlugin.h"
 #include "ctkRangeSliderPlugin.h"
@@ -73,6 +74,7 @@ public:
             << new ctkDynamicSpacerPlugin
             << new ctkFittedTextBrowserPlugin
             << new ctkMaterialPropertyPreviewLabelPlugin
+            << new ctkMaterialPropertyWidgetPlugin
             << new ctkMatrixWidgetPlugin
             << new ctkMenuButtonPlugin
             << new ctkRangeSliderPlugin

+ 248 - 0
Libs/Widgets/Resources/UI/ctkMaterialPropertyWidget.ui

@@ -0,0 +1,248 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>ctkMaterialPropertyWidget</class>
+ <widget class="QWidget" name="ctkMaterialPropertyWidget">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>370</width>
+    <height>196</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Material Property</string>
+  </property>
+  <layout class="QFormLayout" name="formLayout">
+   <property name="fieldGrowthPolicy">
+    <enum>QFormLayout::AllNonFixedFieldsGrow</enum>
+   </property>
+   <property name="labelAlignment">
+    <set>Qt::AlignCenter</set>
+   </property>
+   <property name="margin">
+    <number>0</number>
+   </property>
+   <item row="1" column="0">
+    <widget class="QLabel" name="AmbientLabel">
+     <property name="text">
+      <string>Ambient:</string>
+     </property>
+    </widget>
+   </item>
+   <item row="1" column="1">
+    <widget class="ctkSliderWidget" name="AmbientSliderSpinBox">
+     <property name="singleStep">
+      <double>0.010000000000000</double>
+     </property>
+     <property name="maximum">
+      <double>1.000000000000000</double>
+     </property>
+    </widget>
+   </item>
+   <item row="2" column="0">
+    <widget class="QLabel" name="DiffuseLabel">
+     <property name="text">
+      <string>Diffuse:</string>
+     </property>
+    </widget>
+   </item>
+   <item row="2" column="1">
+    <widget class="ctkSliderWidget" name="DiffuseSliderSpinBox">
+     <property name="singleStep">
+      <double>0.010000000000000</double>
+     </property>
+     <property name="maximum">
+      <double>1.000000000000000</double>
+     </property>
+    </widget>
+   </item>
+   <item row="3" column="0">
+    <widget class="QLabel" name="SpecularLabel">
+     <property name="text">
+      <string>Specular:</string>
+     </property>
+    </widget>
+   </item>
+   <item row="3" column="1">
+    <widget class="ctkSliderWidget" name="SpecularSliderSpinBox">
+     <property name="singleStep">
+      <double>0.010000000000000</double>
+     </property>
+     <property name="maximum">
+      <double>1.000000000000000</double>
+     </property>
+    </widget>
+   </item>
+   <item row="4" column="0">
+    <widget class="QLabel" name="SpecularPowerLabel">
+     <property name="toolTip">
+      <string>Specular power</string>
+     </property>
+     <property name="text">
+      <string>Power:</string>
+     </property>
+    </widget>
+   </item>
+   <item row="4" column="1">
+    <widget class="ctkSliderWidget" name="SpecularPowerSliderSpinBox">
+     <property name="decimals">
+      <number>1</number>
+     </property>
+     <property name="singleStep">
+      <double>0.500000000000000</double>
+     </property>
+     <property name="minimum">
+      <double>1.000000000000000</double>
+     </property>
+     <property name="maximum">
+      <double>50.000000000000000</double>
+     </property>
+    </widget>
+   </item>
+   <item row="5" column="0">
+    <widget class="QLabel" name="PresetsLabel">
+     <property name="text">
+      <string>Presets:</string>
+     </property>
+    </widget>
+   </item>
+   <item row="5" column="1">
+    <widget class="QListWidget" name="PresetsListWidget">
+     <property name="maximumSize">
+      <size>
+       <width>16777215</width>
+       <height>50</height>
+      </size>
+     </property>
+     <property name="verticalScrollBarPolicy">
+      <enum>Qt::ScrollBarAlwaysOff</enum>
+     </property>
+     <property name="horizontalScrollBarPolicy">
+      <enum>Qt::ScrollBarAlwaysOn</enum>
+     </property>
+     <property name="editTriggers">
+      <set>QAbstractItemView::NoEditTriggers</set>
+     </property>
+     <property name="flow">
+      <enum>QListView::LeftToRight</enum>
+     </property>
+     <property name="uniformItemSizes">
+      <bool>true</bool>
+     </property>
+    </widget>
+   </item>
+   <item row="6" column="0">
+    <widget class="QLabel" name="PreviewLabel">
+     <property name="text">
+      <string>Preview:</string>
+     </property>
+    </widget>
+   </item>
+   <item row="6" column="1">
+    <widget class="ctkMaterialPropertyPreviewLabel" name="MaterialPropertyPreviewLabel">
+     <property name="sizePolicy">
+      <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+       <horstretch>0</horstretch>
+       <verstretch>0</verstretch>
+      </sizepolicy>
+     </property>
+     <property name="ambient">
+      <double>0.000000000000000</double>
+     </property>
+     <property name="diffuse">
+      <double>0.000000000000000</double>
+     </property>
+     <property name="specular">
+      <double>0.000000000000000</double>
+     </property>
+     <property name="specularPower">
+      <double>1.000000000000000</double>
+     </property>
+     <property name="gridOpacity">
+      <double>0.000000000000000</double>
+     </property>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <customwidgets>
+  <customwidget>
+   <class>ctkMaterialPropertyPreviewLabel</class>
+   <extends>QFrame</extends>
+   <header>ctkMaterialPropertyPreviewLabel.h</header>
+  </customwidget>
+  <customwidget>
+   <class>ctkSliderWidget</class>
+   <extends>QWidget</extends>
+   <header>ctkSliderWidget.h</header>
+  </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>AmbientSliderSpinBox</sender>
+   <signal>valueChanged(double)</signal>
+   <receiver>MaterialPropertyPreviewLabel</receiver>
+   <slot>setAmbient(double)</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>81</x>
+     <y>12</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>65</x>
+     <y>172</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>DiffuseSliderSpinBox</sender>
+   <signal>valueChanged(double)</signal>
+   <receiver>MaterialPropertyPreviewLabel</receiver>
+   <slot>setDiffuse(double)</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>115</x>
+     <y>46</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>74</x>
+     <y>173</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>SpecularSliderSpinBox</sender>
+   <signal>valueChanged(double)</signal>
+   <receiver>MaterialPropertyPreviewLabel</receiver>
+   <slot>setSpecular(double)</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>135</x>
+     <y>65</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>76</x>
+     <y>179</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>SpecularPowerSliderSpinBox</sender>
+   <signal>valueChanged(double)</signal>
+   <receiver>MaterialPropertyPreviewLabel</receiver>
+   <slot>setSpecularPower(double)</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>147</x>
+     <y>95</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>74</x>
+     <y>184</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>

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

@@ -23,6 +23,7 @@ CREATE_TEST_SOURCELIST(Tests ${KIT}CppTests.cxx
   ctkFileDialogTest1.cpp
   ctkFittedTextBrowserTest1.cpp
   ctkMaterialPropertyPreviewLabelTest1.cpp
+  ctkMaterialPropertyWidgetTest1.cpp
   ctkMatrixWidgetTest1.cpp
   ctkMatrixWidgetTest2.cpp
   ctkMenuButtonTest1.cpp
@@ -94,6 +95,7 @@ SIMPLE_TEST( ctkDynamicSpacerTest2 )
 SIMPLE_TEST( ctkFileDialogTest1 )
 SIMPLE_TEST( ctkFittedTextBrowserTest1 )
 SIMPLE_TEST( ctkMaterialPropertyPreviewLabelTest1 )
+SIMPLE_TEST( ctkMaterialPropertyWidgetTest1 )
 SIMPLE_TEST( ctkMatrixWidgetTest1 )
 SIMPLE_TEST( ctkMatrixWidgetTest2 )
 SIMPLE_TEST( ctkMenuButtonTest1 )

+ 46 - 0
Libs/Widgets/Testing/Cpp/ctkMaterialPropertyWidgetTest1.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.commontk.org/LICENSE
+
+  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 includse
+#include <QApplication>
+#include <QTimer>
+
+// CTK includes
+#include "ctkMaterialPropertyWidget.h"
+
+// STD includes
+#include <iostream>
+
+//-----------------------------------------------------------------------------
+int ctkMaterialPropertyWidgetTest1(int argc, char * argv [] )
+{
+  QApplication app(argc, argv);
+
+  ctkMaterialPropertyWidget label;
+  label.show();
+
+  if (argc < 2 || QString(argv[1]) != "-I" )
+    {
+    QTimer::singleShot(200, &app, SLOT(quit()));
+    }
+
+  return app.exec();
+}
+

+ 15 - 3
Libs/Widgets/ctkMaterialPropertyPreviewLabel.cpp

@@ -59,11 +59,10 @@ ctkMaterialPropertyPreviewLabelPrivate::ctkMaterialPropertyPreviewLabelPrivate(c
   this->Specular = 0.5;
   this->SpecularPower = 50;
   
-  this->Color = Qt::red;
+  this->Color = Qt::white;
   this->GridOpacity = 0.6;
 }
 
-
 //ctkMaterialPropertyPreviewLabel
 //-----------------------------------------------------------------------------
 ctkMaterialPropertyPreviewLabel::ctkMaterialPropertyPreviewLabel(QWidget *newParent)
@@ -73,6 +72,19 @@ ctkMaterialPropertyPreviewLabel::ctkMaterialPropertyPreviewLabel(QWidget *newPar
 }
 
 //-----------------------------------------------------------------------------
+ctkMaterialPropertyPreviewLabel::ctkMaterialPropertyPreviewLabel(
+  double ambient, double diffuse, double specular, double specularPower, QWidget *newParent)
+  : QFrame(newParent)
+  , d_ptr(new ctkMaterialPropertyPreviewLabelPrivate(*this))
+{
+  Q_D(ctkMaterialPropertyPreviewLabel);
+  d->Ambient = ambient;
+  d->Diffuse = diffuse;
+  d->Specular = specular;
+  d->SpecularPower = specularPower;  
+}
+
+//-----------------------------------------------------------------------------
 ctkMaterialPropertyPreviewLabel::~ctkMaterialPropertyPreviewLabel()
 {
 }
@@ -240,7 +252,7 @@ void ctkMaterialPropertyPreviewLabel::draw(QImage& image)
         ref.setZ( 2.*normal.z()*dot - light.z());
         ref.normalize();
 
-        qreal diffuseComp = diffuse * .01 * dot;
+        qreal diffuseComp = diffuse * dot;
         if (diffuseComp < 0)
           {
           diffuseComp = 0.;

+ 2 - 1
Libs/Widgets/ctkMaterialPropertyPreviewLabel.h

@@ -43,6 +43,7 @@ class CTK_WIDGETS_EXPORT ctkMaterialPropertyPreviewLabel : public QFrame
 public : 
 
   ctkMaterialPropertyPreviewLabel(QWidget *parent = 0);
+  ctkMaterialPropertyPreviewLabel(double ambient, double diffuse, double specular, double specularPower, QWidget *parent = 0);
   virtual ~ctkMaterialPropertyPreviewLabel();
   
   double ambient()const;
@@ -64,7 +65,7 @@ public slots:
   void setDiffuse(double newDiffuse);
   /// Valid range: [0,1]
   void setSpecular(double newSpecular);
-  /// Valid range: [0,100]
+  /// Valid range: [1,inf[
   void setSpecularPower(double newSpecularPower);
   
   void setColor(const QColor& newColor);

+ 164 - 0
Libs/Widgets/ctkMaterialPropertyWidget.cpp

@@ -0,0 +1,164 @@
+/*=========================================================================
+
+  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.commontk.org/LICENSE
+
+  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 <QDebug>
+#include <QListWidgetItem>
+#include <QScrollBar>
+
+// CTK includes
+#include "ctkMaterialPropertyWidget.h"
+#include "ctkMaterialPropertyPreviewLabel.h"
+#include "ui_ctkMaterialPropertyWidget.h"
+#include "ctkLogger.h"
+
+static ctkLogger logger("org.commontk.libs.widgets.ctkMaterialPropertyWidget");
+
+//-----------------------------------------------------------------------------
+class ctkMaterialPropertyWidgetPrivate: public Ui_ctkMaterialPropertyWidget
+{
+  Q_DECLARE_PUBLIC(ctkMaterialPropertyWidget);
+protected:
+  ctkMaterialPropertyWidget* const q_ptr;
+public:
+  ctkMaterialPropertyWidgetPrivate(ctkMaterialPropertyWidget& object);
+};
+
+// --------------------------------------------------------------------------
+ctkMaterialPropertyWidgetPrivate::ctkMaterialPropertyWidgetPrivate(ctkMaterialPropertyWidget& object)
+  :q_ptr(&object)
+{
+}
+
+// --------------------------------------------------------------------------
+ctkMaterialPropertyWidget::ctkMaterialPropertyWidget(QWidget* _parent)
+  : Superclass(_parent)
+  , d_ptr(new ctkMaterialPropertyWidgetPrivate(*this))
+{
+  Q_D(ctkMaterialPropertyWidget);
+  
+  d->setupUi(this);
+  
+  connect(d->PresetsListWidget, SIGNAL(itemClicked(QListWidgetItem*)),
+          this, SLOT(selectPreset(QListWidgetItem*)));
+
+  this->addPreset(1.,0.,0.,1.,"Full ambient eliminating all directional shading.");
+  this->addPreset(0.2,1.,0.,1.,"Dull material properties (no specular lighting).");
+  this->addPreset(0.1,0.9,0.2,10.,"Smooth material properties (moderate specular lighting).");
+  this->addPreset(0.1,0.6,0.5,40.,"Shiny material properties (high specular lighting).");
+  
+  d->PresetsListWidget->viewport()->setAutoFillBackground( false);
+  d->PresetsListWidget->setAutoFillBackground( false );
+  d->PresetsListWidget->setMaximumHeight(
+    d->MaterialPropertyPreviewLabel->sizeHint().height()
+    + d->PresetsListWidget->horizontalScrollBar()->sizeHint().height()
+    + 2. * d->PresetsListWidget->frameWidth());
+}
+
+// --------------------------------------------------------------------------
+ctkMaterialPropertyWidget::~ctkMaterialPropertyWidget()
+{
+}
+
+// --------------------------------------------------------------------------
+void ctkMaterialPropertyWidget::setAmbient(double newAmbient)
+{
+  Q_D(const ctkMaterialPropertyWidget);
+  d->DiffuseSliderSpinBox->setValue(newAmbient);
+}
+
+// --------------------------------------------------------------------------
+double ctkMaterialPropertyWidget::ambient()const
+{
+  Q_D(const ctkMaterialPropertyWidget);
+  return d->DiffuseSliderSpinBox->value();
+}
+
+// --------------------------------------------------------------------------
+void ctkMaterialPropertyWidget::setDiffuse(double newDiffuse)
+{
+  Q_D(const ctkMaterialPropertyWidget);
+  d->DiffuseSliderSpinBox->setValue(newDiffuse);
+}
+
+// --------------------------------------------------------------------------
+double ctkMaterialPropertyWidget::diffuse()const
+{
+  Q_D(const ctkMaterialPropertyWidget);
+  return d->DiffuseSliderSpinBox->value();
+}
+
+// --------------------------------------------------------------------------
+void ctkMaterialPropertyWidget::setSpecular(double newSpecular)
+{
+  Q_D(const ctkMaterialPropertyWidget);
+  d->SpecularSliderSpinBox->setValue(newSpecular);
+}
+
+// --------------------------------------------------------------------------
+double ctkMaterialPropertyWidget::specular()const
+{
+  Q_D(const ctkMaterialPropertyWidget);
+  return d->SpecularSliderSpinBox->value();
+}
+
+// --------------------------------------------------------------------------
+void ctkMaterialPropertyWidget::setSpecularPower(double newSpecularPower)
+{
+  Q_D(const ctkMaterialPropertyWidget);
+  d->SpecularPowerSliderSpinBox->setValue(newSpecularPower);
+}
+
+// --------------------------------------------------------------------------
+double ctkMaterialPropertyWidget::specularPower()const
+{
+  Q_D(const ctkMaterialPropertyWidget);
+  return d->SpecularPowerSliderSpinBox->value();
+}
+
+// --------------------------------------------------------------------------
+void ctkMaterialPropertyWidget::addPreset(
+  double ambient, double diffuse, double specular, double power, const QString& label)
+{
+  Q_D(ctkMaterialPropertyWidget);
+  d->PresetsListWidget->addItem("");
+  QListWidgetItem* item = d->PresetsListWidget->item(d->PresetsListWidget->count()-1);
+  item->setToolTip(label);
+  item->setData(Qt::UserRole, ambient); 
+  item->setData(Qt::UserRole + 1, diffuse);
+  item->setData(Qt::UserRole + 2, specular);
+  item->setData(Qt::UserRole + 3, power);
+  ctkMaterialPropertyPreviewLabel* preset =
+    new ctkMaterialPropertyPreviewLabel(ambient, diffuse, specular, power);
+  preset->setColor(d->MaterialPropertyPreviewLabel->color());
+  preset->setGridOpacity(d->MaterialPropertyPreviewLabel->gridOpacity());
+  item->setSizeHint(preset->sizeHint());
+  d->PresetsListWidget->setItemWidget(item, preset);
+}
+
+// --------------------------------------------------------------------------
+void ctkMaterialPropertyWidget::selectPreset(QListWidgetItem* preset)
+{
+  Q_D(ctkMaterialPropertyWidget);
+  d->AmbientSliderSpinBox->setValue(preset->data(Qt::UserRole).toDouble());
+  d->DiffuseSliderSpinBox->setValue(preset->data(Qt::UserRole + 1).toDouble());
+  d->SpecularSliderSpinBox->setValue(preset->data(Qt::UserRole + 2).toDouble());
+  d->SpecularPowerSliderSpinBox->setValue(preset->data(Qt::UserRole + 3).toDouble());
+}

+ 80 - 0
Libs/Widgets/ctkMaterialPropertyWidget.h

@@ -0,0 +1,80 @@
+/*=========================================================================
+
+  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.commontk.org/LICENSE
+
+  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.
+
+=========================================================================*/
+
+#ifndef __ctkMaterialPropertyWidget_h
+#define __ctkMaterialPropertyWidget_h
+
+// Qt includes
+#include <QWidget>
+
+// CTK includes
+#include "ctkWidgetsExport.h"
+
+class ctkMaterialPropertyWidgetPrivate;
+class QListWidgetItem;
+
+class CTK_WIDGETS_EXPORT ctkMaterialPropertyWidget : public QWidget
+{
+  Q_OBJECT
+  Q_PROPERTY(double ambient READ ambient WRITE setAmbient);
+  Q_PROPERTY(double diffuse READ diffuse WRITE setDiffuse);
+  Q_PROPERTY(double specular READ specular WRITE setSpecular);
+  Q_PROPERTY(double specularPower READ specularPower WRITE setSpecularPower);
+public:
+  /// Superclass typedef
+  typedef QWidget Superclass;
+
+  /// Constructor
+  explicit ctkMaterialPropertyWidget(QWidget* parent = 0);
+  
+  /// Destructor
+  virtual ~ctkMaterialPropertyWidget();
+
+  double ambient()const;
+  double diffuse()const;
+  double specular()const;
+  double specularPower()const;
+  
+  void addPreset(double ambient, double diffuse, double specular, double power, const QString& label);
+
+public slots:
+  void setAmbient(double newAmbient);
+  void setDiffuse(double newDiffuse);
+  void setSpecular(double newSpecular);
+  void setSpecularPower(double newSpecularPower);
+
+signals:
+  void ambientChanged(double newAmbient);
+  void diffuseChanged(double newDiffuse);
+  void specularChanged(double newSpecular);
+  void specularPowerChanged(double newSpecularPower);
+  
+protected slots:
+  void selectPreset(QListWidgetItem*);
+
+protected:
+  QScopedPointer<ctkMaterialPropertyWidgetPrivate> d_ptr;
+
+private:
+  Q_DECLARE_PRIVATE(ctkMaterialPropertyWidget);
+  Q_DISABLE_COPY(ctkMaterialPropertyWidget);
+};
+
+#endif