Quellcode durchsuchen

ENH: Add ctkSpinBox

The ctkSpinBow is a wrapper around the QDoubleSpinBox that allows a tighter
 control over it.
Fix testing accordingly.

See Issue #2986
Johan Andruejol vor 12 Jahren
Ursprung
Commit
d34e05343d

+ 3 - 0
Libs/Widgets/CMakeLists.txt

@@ -147,6 +147,8 @@ set(KIT_SRCS
   ctkSizeGrip.h
   ctkSliderWidget.cpp
   ctkSliderWidget.h
+  ctkSpinBox.cpp
+  ctkSpinBox.h
   ctkTestApplication.cpp
   ctkTestApplication.h
   ctkThumbnailLabel.cpp
@@ -255,6 +257,7 @@ set(KIT_MOC_SRCS
   ctkSimpleLayoutManager.h
   ctkSizeGrip.h
   ctkSliderWidget.h
+  ctkSpinBox.h
   ctkTestApplication.h
   ctkThumbnailLabel.h
   ctkThumbnailListWidget.h

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

@@ -90,6 +90,8 @@ set(PLUGIN_SRCS
   ctkSettingsDialogPlugin.h
   ctkSliderWidgetPlugin.cpp
   ctkSliderWidgetPlugin.h
+  ctkSpinBoxPlugin.cpp
+  ctkSpinBoxPlugin.h
   ctkWorkflowButtonBoxWidgetPlugin.cpp
   ctkWorkflowButtonBoxWidgetPlugin.h
   ctkWorkflowWidgetStepPlugin.cpp
@@ -139,6 +141,7 @@ set(PLUGIN_MOC_SRCS
   ctkSettingsPanelPlugin.h
   ctkSettingsDialogPlugin.h
   ctkSliderWidgetPlugin.h
+  ctkSpinBoxPlugin.h
   ctkWorkflowButtonBoxWidgetPlugin.h
   ctkWorkflowWidgetStepPlugin.h
   )

+ 67 - 0
Libs/Widgets/Plugins/ctkSpinBoxPlugin.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.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.
+
+=========================================================================*/
+
+// CTK includes
+#include "ctkSpinBoxPlugin.h"
+#include "ctkSpinBox.h"
+
+// --------------------------------------------------------------------------
+ctkSpinBoxPlugin::ctkSpinBoxPlugin(QObject *_parent)
+  : QObject(_parent)
+{
+}
+
+// --------------------------------------------------------------------------
+QWidget *ctkSpinBoxPlugin::createWidget(QWidget *_parent)
+{
+  ctkSpinBox* _widget = new ctkSpinBox(_parent);
+  return _widget;
+}
+
+// --------------------------------------------------------------------------
+QString ctkSpinBoxPlugin::domXml() const
+{
+  return "<widget class=\"ctkSpinBox\" name=\"SpinBox\">\n"
+    "</widget>\n";
+}
+
+// --------------------------------------------------------------------------
+QIcon ctkSpinBoxPlugin::icon() const
+{
+  return QIcon(":/Icons/doublespinbox.png");
+}
+
+// --------------------------------------------------------------------------
+QString ctkSpinBoxPlugin::includeFile() const
+{
+  return "ctkSpinBox.h";
+}
+
+// --------------------------------------------------------------------------
+bool ctkSpinBoxPlugin::isContainer() const
+{
+  return false;
+}
+
+// --------------------------------------------------------------------------
+QString ctkSpinBoxPlugin::name() const
+{
+  return "ctkSpinBox";
+}

+ 45 - 0
Libs/Widgets/Plugins/ctkSpinBoxPlugin.h

@@ -0,0 +1,45 @@
+/*=========================================================================
+
+  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.
+
+=========================================================================*/
+
+#ifndef __ctkSpinBoxPlugin_h
+#define __ctkSpinBoxPlugin_h
+
+// CTK includes
+#include "ctkWidgetsAbstractPlugin.h"
+
+class CTK_WIDGETS_PLUGINS_EXPORT ctkSpinBoxPlugin :
+  public QObject,
+  public ctkWidgetsAbstractPlugin
+{
+  Q_OBJECT
+
+public:
+  ctkSpinBoxPlugin(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

@@ -60,6 +60,7 @@
 #include "ctkSettingsPanelPlugin.h"
 #include "ctkSettingsDialogPlugin.h"
 #include "ctkSliderWidgetPlugin.h"
+#include "ctkSpinBoxPlugin.h"
 #include "ctkThumbnailLabelPlugin.h"
 #include "ctkTransferFunctionViewPlugin.h"
 #include "ctkTreeComboBoxPlugin.h"
@@ -111,6 +112,7 @@ public:
             << new ctkSettingsPanelPlugin
             << new ctkSettingsDialogPlugin
             << new ctkSliderWidgetPlugin
+            << new ctkSpinBoxPlugin
             << new ctkThumbnailLabelPlugin
             << new ctkTransferFunctionViewPlugin
             << new ctkTreeComboBoxPlugin

+ 7 - 2
Libs/Widgets/Resources/UI/ctkRangeWidget.ui

@@ -24,7 +24,7 @@
     <number>0</number>
    </property>
    <item row="0" column="0">
-    <widget class="QDoubleSpinBox" name="MinimumSpinBox"/>
+    <widget class="ctkSpinBox" name="MinimumSpinBox"/>
    </item>
    <item row="0" column="1">
     <widget class="ctkDoubleRangeSlider" name="Slider">
@@ -34,7 +34,7 @@
     </widget>
    </item>
    <item row="0" column="2">
-    <widget class="QDoubleSpinBox" name="MaximumSpinBox"/>
+    <widget class="ctkSpinBox" name="MaximumSpinBox"/>
    </item>
   </layout>
  </widget>
@@ -44,6 +44,11 @@
    <extends>QWidget</extends>
    <header>ctkDoubleRangeSlider.h</header>
   </customwidget>
+  <customwidget>
+   <class>ctkSpinBox</class>
+   <extends>QWidget</extends>
+   <header>ctkSpinBox.h</header>
+  </customwidget>
  </customwidgets>
  <resources/>
  <connections/>

+ 6 - 1
Libs/Widgets/Resources/UI/ctkScreenshotDialog.ui

@@ -151,7 +151,7 @@
        </widget>
       </item>
       <item row="3" column="1">
-       <widget class="QDoubleSpinBox" name="ScaleFactorSpinBox">
+       <widget class="ctkSpinBox" name="ScaleFactorSpinBox">
         <property name="toolTip">
          <string>Select an integer scale factor (between 0.5 and 5) for the image file, e.g. a value of &quot;2&quot; will save an image twice the size.</string>
         </property>
@@ -285,6 +285,11 @@
    <extends>QWidget</extends>
    <header>ctkPathLineEdit.h</header>
   </customwidget>
+  <customwidget>
+   <class>ctkSpinBox</class>
+   <extends>QWidget</extends>
+   <header>ctkSpinBox.h</header>
+  </customwidget>
  </customwidgets>
  <resources>
   <include location="../ctkWidgets.qrc"/>

+ 6 - 1
Libs/Widgets/Resources/UI/ctkSliderWidget.ui

@@ -31,7 +31,7 @@
     </widget>
    </item>
    <item>
-    <widget class="QDoubleSpinBox" name="SpinBox"/>
+    <widget class="ctkSpinBox" name="SpinBox"/>
    </item>
   </layout>
  </widget>
@@ -41,6 +41,11 @@
    <extends>QWidget</extends>
    <header>ctkDoubleSlider.h</header>
   </customwidget>
+  <customwidget>
+   <class>ctkSpinBox</class>
+   <extends>QWidget</extends>
+   <header>ctkSpinBox.h</header>
+  </customwidget>
  </customwidgets>
  <resources/>
  <connections/>

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

@@ -71,6 +71,7 @@ set(TEST_SOURCES
   ctkSignalMapperTest1.cpp
   ctkSliderWidgetTest1.cpp
   ctkSliderWidgetTest2.cpp
+  ctkSpinBoxTest1.cpp
   ctkThumbnailListWidgetTest1.cpp
   ctkThumbnailLabelTest1.cpp
   ctkToolTipTrapperTest1.cpp
@@ -274,6 +275,7 @@ SIMPLE_TEST( ctkSettingsTest1 )
 SIMPLE_TEST( ctkSignalMapperTest1 )
 SIMPLE_TEST( ctkSliderWidgetTest1 )
 SIMPLE_TEST( ctkSliderWidgetTest2 )
+SIMPLE_TEST( ctkSpinBoxTest1 )
 SIMPLE_TEST( ctkThumbnailListWidgetTest1 )
 SIMPLE_TEST( ctkThumbnailLabelTest1 )
 SIMPLE_TEST( ctkToolTipTrapperTest1 )

+ 7 - 11
Libs/Widgets/Testing/Cpp/ctkCoordinatesWidgetEventTranslatorPlayerTest1.xml

@@ -1,16 +1,12 @@
 <?xml version="1.0"?>
 <QtTesting>
     <events>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/1ctkCoordinatesWidget0/1QDoubleSpinBox0" command="spin" arguments="up"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/1ctkCoordinatesWidget0/1QDoubleSpinBox0" command="spin" arguments="up"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/1ctkCoordinatesWidget0/1QDoubleSpinBox0" command="spin" arguments="up"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/1ctkCoordinatesWidget0/1QDoubleSpinBox0" command="spin" arguments="up"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/1ctkCoordinatesWidget0/1QDoubleSpinBox0" command="spin" arguments="up"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/1ctkCoordinatesWidget0/1QDoubleSpinBox0" command="spin" arguments="up"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/1ctkCoordinatesWidget0/1QDoubleSpinBox0" command="spin" arguments="up"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/1ctkCoordinatesWidget0/1QDoubleSpinBox0" command="spin" arguments="up"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/1ctkCoordinatesWidget0/1QDoubleSpinBox0" command="spin" arguments="down"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/1ctkCoordinatesWidget0/1QDoubleSpinBox0" command="spin" arguments="down"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/1ctkCoordinatesWidget0/1QDoubleSpinBox0" command="spin" arguments="down"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/1ctkCoordinatesWidget0/1ctkSpinBox0/1QDoubleSpinBox0" command="set_double" arguments="1"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/1ctkCoordinatesWidget0/1ctkSpinBox0/1QDoubleSpinBox0" command="set_double" arguments="2"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/1ctkCoordinatesWidget0/1ctkSpinBox0/1QDoubleSpinBox0" command="set_double" arguments="3"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/1ctkCoordinatesWidget0/1ctkSpinBox0/1QDoubleSpinBox0" command="set_double" arguments="6"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/1ctkCoordinatesWidget0/1ctkSpinBox1/1QDoubleSpinBox0" command="set_double" arguments="15.0"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/1ctkCoordinatesWidget0/1ctkSpinBox2/1QDoubleSpinBox0" command="set_double" arguments="8.36"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/1ctkCoordinatesWidget0/1ctkSpinBox2/1QDoubleSpinBox0" command="set_double" arguments="3"/>
     </events>
 </QtTesting>

+ 0 - 7
Libs/Widgets/Testing/Cpp/ctkSliderWidgetEventTranslatorPlayerTest1.cpp

@@ -69,13 +69,6 @@ int ctkSliderWidgetEventTranslatorPlayerTest1(int argc, char * argv [] )
                         xmlDirectory + "ctkSliderWidgetEventTranslatorPlayerTest1.xml",
                         &checkFinalWidgetState);
 
-  // Test case 2
-  ctkSliderWidget* widget2 = new ctkSliderWidget();
-  widget2->setObjectName("SliderWidgetTest2");
-  etpWidget.addTestCase(widget2,
-                        xmlDirectory + "ctkSliderWidgetEventTranslatorPlayerTest2.xml",
-                        &checkFinalWidgetState);
-
   // ------------------------
   if (!app.arguments().contains("-I"))
     {

+ 97 - 94
Libs/Widgets/Testing/Cpp/ctkSliderWidgetEventTranslatorPlayerTest1.xml

@@ -1,99 +1,102 @@
 <?xml version="1.0"?>
 <QtTesting>
     <events>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/ctkSliderWidget/Slider/1QSlider0" command="set_int" arguments="1"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/ctkSliderWidget/Slider/1QSlider0" command="set_int" arguments="2"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/ctkSliderWidget/Slider/1QSlider0" command="set_int" arguments="3"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/ctkSliderWidget/Slider/1QSlider0" command="set_int" arguments="4"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/ctkSliderWidget/Slider/1QSlider0" command="set_int" arguments="5"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/ctkSliderWidget/Slider/1QSlider0" command="set_int" arguments="6"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/ctkSliderWidget/Slider/1QSlider0" command="set_int" arguments="8"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/ctkSliderWidget/Slider/1QSlider0" command="set_int" arguments="9"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/ctkSliderWidget/Slider/1QSlider0" command="set_int" arguments="11"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/ctkSliderWidget/Slider/1QSlider0" command="set_int" arguments="13"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/ctkSliderWidget/Slider/1QSlider0" command="set_int" arguments="14"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/ctkSliderWidget/Slider/1QSlider0" command="set_int" arguments="16"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/ctkSliderWidget/Slider/1QSlider0" command="set_int" arguments="17"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/ctkSliderWidget/Slider/1QSlider0" command="set_int" arguments="19"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/ctkSliderWidget/Slider/1QSlider0" command="set_int" arguments="21"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/ctkSliderWidget/Slider/1QSlider0" command="set_int" arguments="23"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/ctkSliderWidget/Slider/1QSlider0" command="set_int" arguments="25"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/ctkSliderWidget/Slider/1QSlider0" command="set_int" arguments="27"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/ctkSliderWidget/Slider/1QSlider0" command="set_int" arguments="28"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/ctkSliderWidget/Slider/1QSlider0" command="set_int" arguments="29"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/ctkSliderWidget/Slider/1QSlider0" command="set_int" arguments="30"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/ctkSliderWidget/Slider/1QSlider0" command="set_int" arguments="31"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/ctkSliderWidget/Slider/1QSlider0" command="set_int" arguments="32"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/ctkSliderWidget/Slider/1QSlider0" command="set_int" arguments="33"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/ctkSliderWidget/Slider/1QSlider0" command="set_int" arguments="35"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/ctkSliderWidget/Slider/1QSlider0" command="set_int" arguments="36"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/ctkSliderWidget/Slider/1QSlider0" command="set_int" arguments="37"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/ctkSliderWidget/Slider/1QSlider0" command="set_int" arguments="39"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/ctkSliderWidget/Slider/1QSlider0" command="set_int" arguments="40"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/ctkSliderWidget/Slider/1QSlider0" command="set_int" arguments="42"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/ctkSliderWidget/Slider/1QSlider0" command="set_int" arguments="43"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/ctkSliderWidget/Slider/1QSlider0" command="set_int" arguments="45"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/ctkSliderWidget/Slider/1QSlider0" command="set_int" arguments="46"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/ctkSliderWidget/Slider/1QSlider0" command="set_int" arguments="47"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/ctkSliderWidget/Slider/1QSlider0" command="set_int" arguments="48"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/ctkSliderWidget/Slider/1QSlider0" command="set_int" arguments="50"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/ctkSliderWidget/Slider/1QSlider0" command="set_int" arguments="51"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/ctkSliderWidget/Slider/1QSlider0" command="set_int" arguments="52"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/ctkSliderWidget/Slider/1QSlider0" command="set_int" arguments="54"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/ctkSliderWidget/Slider/1QSlider0" command="set_int" arguments="55"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/ctkSliderWidget/Slider/1QSlider0" command="set_int" arguments="56"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/ctkSliderWidget/Slider/1QSlider0" command="set_int" arguments="57"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/ctkSliderWidget/Slider/1QSlider0" command="set_int" arguments="58"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/ctkSliderWidget/Slider/1QSlider0" command="set_int" arguments="59"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/ctkSliderWidget/Slider/1QSlider0" command="set_int" arguments="60"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/ctkSliderWidget/Slider/1QSlider0" command="set_int" arguments="61"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/ctkSliderWidget/Slider/1QSlider0" command="set_int" arguments="62"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/ctkSliderWidget/Slider/1QSlider0" command="set_int" arguments="63"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/ctkSliderWidget/Slider/1QSlider0" command="set_int" arguments="64"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/ctkSliderWidget/Slider/1QSlider0" command="set_int" arguments="65"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/ctkSliderWidget/Slider/1QSlider0" command="set_int" arguments="66"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/ctkSliderWidget/Slider/1QSlider0" command="set_int" arguments="67"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/ctkSliderWidget/Slider/1QSlider0" command="set_int" arguments="68"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/ctkSliderWidget/Slider/1QSlider0" command="set_int" arguments="69"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/ctkSliderWidget/Slider/1QSlider0" command="set_int" arguments="70"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/ctkSliderWidget/Slider/1QSlider0" command="set_int" arguments="69"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/ctkSliderWidget/Slider/1QSlider0" command="set_int" arguments="68"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/ctkSliderWidget/Slider/1QSlider0" command="set_int" arguments="67"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/ctkSliderWidget/Slider/1QSlider0" command="set_int" arguments="66"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/ctkSliderWidget/Slider/1QSlider0" command="set_int" arguments="65"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/ctkSliderWidget/Slider/1QSlider0" command="set_int" arguments="64"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/ctkSliderWidget/Slider/1QSlider0" command="set_int" arguments="63"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/ctkSliderWidget/Slider/1QSlider0" command="set_int" arguments="62"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/ctkSliderWidget/Slider/1QSlider0" command="set_int" arguments="61"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/ctkSliderWidget/Slider/1QSlider0" command="set_int" arguments="60"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/ctkSliderWidget/Slider/1QSlider0" command="set_int" arguments="59"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/ctkSliderWidget/Slider/1QSlider0" command="set_int" arguments="58"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/ctkSliderWidget/Slider/1QSlider0" command="set_int" arguments="57"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/ctkSliderWidget/Slider/1QSlider0" command="set_int" arguments="56"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/ctkSliderWidget/Slider/1QSlider0" command="set_int" arguments="55"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/ctkSliderWidget/Slider/1QSlider0" command="set_int" arguments="54"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/ctkSliderWidget/Slider/1QSlider0" command="set_int" arguments="53"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/ctkSliderWidget/Slider/1QSlider0" command="set_int" arguments="52"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/ctkSliderWidget/Slider/1QSlider0" command="set_int" arguments="51"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/ctkSliderWidget/Slider/1QSlider0" command="set_int" arguments="50"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/ctkSliderWidget/Slider/1QSlider0" command="set_int" arguments="49"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/ctkSliderWidget/Slider/1QSlider0" command="set_int" arguments="48"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/ctkSliderWidget/Slider/1QSlider0" command="set_int" arguments="47"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/ctkSliderWidget/Slider/1QSlider0" command="set_int" arguments="46"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/ctkSliderWidget/Slider/1QSlider0" command="set_int" arguments="45"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/ctkSliderWidget/Slider/1QSlider0" command="set_int" arguments="44"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/ctkSliderWidget/Slider/1QSlider0" command="set_int" arguments="43"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/ctkSliderWidget/Slider/1QSlider0" command="set_int" arguments="42"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/ctkSliderWidget/Slider/1QSlider0" command="set_int" arguments="41"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/ctkSliderWidget/Slider/1QSlider0" command="set_int" arguments="40"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/ctkSliderWidget/Slider/1QSlider0" command="set_int" arguments="39"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/ctkSliderWidget/Slider/1QSlider0" command="set_int" arguments="38"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/ctkSliderWidget/Slider/1QSlider0" command="set_int" arguments="37"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/ctkSliderWidget/Slider/1QSlider0" command="set_int" arguments="36"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/ctkSliderWidget/Slider/1QSlider0" command="set_int" arguments="35"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/ctkSliderWidget/Slider/1QSlider0" command="set_int" arguments="34"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/ctkSliderWidget/Slider/1QSlider0" command="set_int" arguments="33"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/ctkSliderWidget/SpinBox" command="spin" arguments="down"/>
-        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/ctkSliderWidget/SpinBox" command="spin" arguments="down"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1/Slider/1QSlider0" command="set_int" arguments="1"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1/Slider/1QSlider0" command="set_int" arguments="2"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1/Slider/1QSlider0" command="set_int" arguments="3"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1/Slider/1QSlider0" command="set_int" arguments="4"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1/Slider/1QSlider0" command="set_int" arguments="5"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1/Slider/1QSlider0" command="set_int" arguments="6"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1/Slider/1QSlider0" command="set_int" arguments="8"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1/Slider/1QSlider0" command="set_int" arguments="9"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1/Slider/1QSlider0" command="set_int" arguments="11"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1/Slider/1QSlider0" command="set_int" arguments="13"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1/Slider/1QSlider0" command="set_int" arguments="14"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1/Slider/1QSlider0" command="set_int" arguments="16"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1/Slider/1QSlider0" command="set_int" arguments="17"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1/Slider/1QSlider0" command="set_int" arguments="19"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1/Slider/1QSlider0" command="set_int" arguments="21"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1/Slider/1QSlider0" command="set_int" arguments="23"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1/Slider/1QSlider0" command="set_int" arguments="25"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1/Slider/1QSlider0" command="set_int" arguments="27"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1/Slider/1QSlider0" command="set_int" arguments="28"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1/Slider/1QSlider0" command="set_int" arguments="29"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1/Slider/1QSlider0" command="set_int" arguments="30"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1/Slider/1QSlider0" command="set_int" arguments="31"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1/Slider/1QSlider0" command="set_int" arguments="32"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1/Slider/1QSlider0" command="set_int" arguments="33"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1/Slider/1QSlider0" command="set_int" arguments="35"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1/Slider/1QSlider0" command="set_int" arguments="36"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1/Slider/1QSlider0" command="set_int" arguments="37"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1/Slider/1QSlider0" command="set_int" arguments="39"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1/Slider/1QSlider0" command="set_int" arguments="40"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1/Slider/1QSlider0" command="set_int" arguments="42"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1/Slider/1QSlider0" command="set_int" arguments="43"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1/Slider/1QSlider0" command="set_int" arguments="45"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1/Slider/1QSlider0" command="set_int" arguments="46"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1/Slider/1QSlider0" command="set_int" arguments="47"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1/Slider/1QSlider0" command="set_int" arguments="48"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1/Slider/1QSlider0" command="set_int" arguments="50"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1/Slider/1QSlider0" command="set_int" arguments="51"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1/Slider/1QSlider0" command="set_int" arguments="52"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1/Slider/1QSlider0" command="set_int" arguments="54"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1/Slider/1QSlider0" command="set_int" arguments="55"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1/Slider/1QSlider0" command="set_int" arguments="56"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1/Slider/1QSlider0" command="set_int" arguments="57"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1/Slider/1QSlider0" command="set_int" arguments="58"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1/Slider/1QSlider0" command="set_int" arguments="59"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1/Slider/1QSlider0" command="set_int" arguments="60"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1/Slider/1QSlider0" command="set_int" arguments="61"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1/Slider/1QSlider0" command="set_int" arguments="62"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1/Slider/1QSlider0" command="set_int" arguments="63"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1/Slider/1QSlider0" command="set_int" arguments="64"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1/Slider/1QSlider0" command="set_int" arguments="65"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1/Slider/1QSlider0" command="set_int" arguments="66"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1/Slider/1QSlider0" command="set_int" arguments="67"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1/Slider/1QSlider0" command="set_int" arguments="68"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1/Slider/1QSlider0" command="set_int" arguments="69"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1/Slider/1QSlider0" command="set_int" arguments="70"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1/Slider/1QSlider0" command="set_int" arguments="69"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1/Slider/1QSlider0" command="set_int" arguments="68"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1/Slider/1QSlider0" command="set_int" arguments="67"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1/Slider/1QSlider0" command="set_int" arguments="66"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1/Slider/1QSlider0" command="set_int" arguments="65"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1/Slider/1QSlider0" command="set_int" arguments="64"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1/Slider/1QSlider0" command="set_int" arguments="63"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1/Slider/1QSlider0" command="set_int" arguments="62"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1/Slider/1QSlider0" command="set_int" arguments="61"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1/Slider/1QSlider0" command="set_int" arguments="60"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1/Slider/1QSlider0" command="set_int" arguments="59"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1/Slider/1QSlider0" command="set_int" arguments="58"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1/Slider/1QSlider0" command="set_int" arguments="57"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1/Slider/1QSlider0" command="set_int" arguments="56"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1/Slider/1QSlider0" command="set_int" arguments="55"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1/Slider/1QSlider0" command="set_int" arguments="54"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1/Slider/1QSlider0" command="set_int" arguments="53"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1/Slider/1QSlider0" command="set_int" arguments="52"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1/Slider/1QSlider0" command="set_int" arguments="51"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1/Slider/1QSlider0" command="set_int" arguments="50"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1/Slider/1QSlider0" command="set_int" arguments="49"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1/Slider/1QSlider0" command="set_int" arguments="48"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1/Slider/1QSlider0" command="set_int" arguments="47"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1/Slider/1QSlider0" command="set_int" arguments="46"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1/Slider/1QSlider0" command="set_int" arguments="45"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1/Slider/1QSlider0" command="set_int" arguments="44"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1/Slider/1QSlider0" command="set_int" arguments="43"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1/Slider/1QSlider0" command="set_int" arguments="42"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1/Slider/1QSlider0" command="set_int" arguments="41"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1/Slider/1QSlider0" command="set_int" arguments="40"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1/Slider/1QSlider0" command="set_int" arguments="39"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1/Slider/1QSlider0" command="set_int" arguments="38"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1/Slider/1QSlider0" command="set_int" arguments="37"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1/Slider/1QSlider0" command="set_int" arguments="36"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1/Slider/1QSlider0" command="set_int" arguments="35"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1/Slider/1QSlider0" command="set_int" arguments="34"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1/Slider/1QSlider0" command="set_int" arguments="33"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1" command="mousePress" arguments="1,1,0,328,247"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1" command="mouseRelease" arguments="1,0,0,328,247"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1/SpinBox/1QDoubleSpinBox0" command="set_double" arguments="32"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1/SpinBox/1QDoubleSpinBox0" command="set_double" arguments="31"/>
+        <event widget="ctkEventTranslatorPlayerWidget/centralwidget/stackedWidget/SliderWidgetTest1/SpinBox/1QDoubleSpinBox0" command="set_double" arguments="30"/>
     </events>
 </QtTesting>

+ 206 - 0
Libs/Widgets/Testing/Cpp/ctkSpinBoxTest1.cpp

@@ -0,0 +1,206 @@
+/*=========================================================================
+
+  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 <QDebug>
+#include <QSignalSpy>
+#include <QTimer>
+
+// CTK includes
+#include "ctkSpinBox.h"
+
+// STD includes
+#include <cstdlib>
+#include <iostream>
+
+//-----------------------------------------------------------------------------
+int ctkSpinBoxTest1(int argc, char * argv [] )
+{
+  QApplication app(argc, argv);
+
+  ctkSpinBox spinBox;
+
+  // ----------------------------------------
+  // Regular SpinBox methods
+  // ----------------------------------------
+
+  qDebug()<<"Prefix:";
+  spinBox.setPrefix("$");
+  if (spinBox.prefix() != "$")
+    {
+    qDebug()<<"Prefix does not correspond. Got: "<<spinBox.prefix();
+    return EXIT_FAILURE;
+    }
+  spinBox.setValue(3.0);
+  if (spinBox.text() != "$3.00")
+    {
+    qDebug()<<"Text does not correspond. Got: "<<spinBox.text();
+    return EXIT_FAILURE;
+    }
+
+  qDebug()<<"Suffix:";
+  spinBox.setSuffix("#");
+  if (spinBox.suffix() != "#")
+    {
+    qDebug()<<"suffix does not correspond. Got: "<<spinBox.suffix();
+    return EXIT_FAILURE;
+    }
+  spinBox.setValue(8.69);
+  if (spinBox.text() != "$8.69#")
+    {
+    qDebug()<<"Text does not correspond. Got: "<<spinBox.text();
+    return EXIT_FAILURE;
+    }
+
+  qDebug()<<"cleanText:";
+  if (spinBox.cleanText() != "8.69")
+    {
+    qDebug()<<"cleanText does not correspond. Got: "<<spinBox.cleanText();
+    return EXIT_FAILURE;
+    }
+
+  qDebug()<<"SingleStep:";
+  spinBox.setSingleStep(0.01);
+  if (spinBox.singleStep() != 0.01)
+    {
+    qDebug()<<"singleStep does not correspond. Got: "<<spinBox.singleStep();
+    return EXIT_FAILURE;
+    }
+  spinBox.stepUp();
+  if (spinBox.value() != 8.70)
+    {
+    qDebug()<<"Value does not correspond. Got: "<<spinBox.value();
+    return EXIT_FAILURE;
+    }
+  spinBox.setSingleStep(1.0);
+  spinBox.stepDown();
+  if (spinBox.displayedValue() != 7.7)
+    {
+    qDebug()<<"Value does not correspond. Got: "<<spinBox.value();
+    return EXIT_FAILURE;
+    }
+
+  qDebug()<<"Minimum:";
+  spinBox.setMinimum(9.1);
+  if (spinBox.minimum() != 9.1)
+    {
+    qDebug()<<"minimum does not correspond. Got: "<<spinBox.minimum();
+    return EXIT_FAILURE;
+    }
+  if (spinBox.value() != 9.1)
+    {
+    qDebug()<<"Value does not correspond. Got: "<<spinBox.value();
+    return EXIT_FAILURE;
+    }
+
+  qDebug()<<"Maximum:";
+  spinBox.setValue(18.34);
+  spinBox.setMaximum(15);
+  if (spinBox.maximum() != 15)
+    {
+    qDebug()<<"maximum does not correspond. Got: "<<spinBox.maximum();
+    return EXIT_FAILURE;
+    }
+  if (spinBox.value() != 15)
+    {
+    qDebug()<<"Value does not correspond. Got: "<<spinBox.value();
+    return EXIT_FAILURE;
+    }
+
+  qDebug()<<"Range:";
+  spinBox.setRange(-3.6, 42);
+  if (spinBox.maximum() != 42 || spinBox.minimum() != -3.6)
+    {
+    qDebug()<<"Range does not correspond. Got: "
+      <<spinBox.minimum()<<" : "<<spinBox.minimum();
+    return EXIT_FAILURE;
+    }
+
+  qDebug()<<"Decimals:";
+  spinBox.setDecimals(6);
+  if (spinBox.decimals() != 6)
+    {
+    qDebug()<<"Decimals does not correspond. Got: "<<spinBox.cleanText();
+    return EXIT_FAILURE;
+    }
+  if (spinBox.cleanText() != "15.000000")
+    {
+    qDebug()<<"Decimals does not correspond. Got: "<<spinBox.cleanText();
+    return EXIT_FAILURE;
+    }
+
+  qDebug()<<"Round:";
+  spinBox.setDecimals(3);
+  double roundedValue = spinBox.round(6.67899156);
+  if (roundedValue != 6.679)
+    {
+    qDebug()<<"Round does not correspond. Got: "<<roundedValue;
+    return EXIT_FAILURE;
+    }
+
+  QSignalSpy spy(&spinBox, SIGNAL(valueChanged(double)));
+
+  qDebug()<<"SetValue:";
+  spinBox.setValue(28.36);
+  if (spinBox.value() != 28.36)
+    {
+    qDebug()<<"setValue does not correspond. Got: "<<spinBox.value() ;
+    return EXIT_FAILURE;
+    }
+
+  spinBox.setValue(28.366917352);
+  if (spinBox.value() != 28.367)
+    {
+    qDebug()<<"setValue does not correspond. Got: "<<spinBox.value() ;
+    return EXIT_FAILURE;
+    }
+
+  qDebug()<<"SetValueIfDifferent:";
+  spinBox.setValueIfDifferent(33.312587);
+  if (spinBox.value() != 33.313)
+    {
+    qDebug()<<"setValueIfDifferent does not correspond. Got: "<<spinBox.value() ;
+    return EXIT_FAILURE;
+    }
+
+  spinBox.setValueIfDifferent(33.312960134);
+  if (spinBox.value() != 33.313)
+    {
+    qDebug()<<"setValueIfDifferent does not correspond. Got: "<<spinBox.value() ;
+    return EXIT_FAILURE;
+    }
+
+  if (spy.count() != 3)
+    {
+    qDebug()<<"spy got wrong number of signal sent : "<<spy.count() ;
+    return EXIT_FAILURE;
+    }
+
+//-----------------------------------------------------------------------------
+  spinBox.show();
+
+  if (argc < 2 || QString(argv[1]) != "-I" )
+    {
+    QTimer::singleShot(100, &app, SLOT(quit()));
+    }
+
+  return app.exec();
+}

+ 12 - 12
Libs/Widgets/ctkCoordinatesWidget.cpp

@@ -20,11 +20,11 @@
 
 // Qt includes
 #include <QDebug>
-#include <QDoubleSpinBox>
 #include <QHBoxLayout>
 
 // CTK includes
 #include "ctkCoordinatesWidget.h"
+#include "ctkSpinBox.h"
 
 // STD includes
 #include <cmath>
@@ -56,7 +56,7 @@ ctkCoordinatesWidget::~ctkCoordinatesWidget()
 //------------------------------------------------------------------------------
 void ctkCoordinatesWidget::addSpinBox()
 {
-  QDoubleSpinBox* spinBox = new QDoubleSpinBox(this);
+  ctkSpinBox* spinBox = new ctkSpinBox(this);
   spinBox->setDecimals(this->Decimals);
   spinBox->setSingleStep(this->SingleStep);
   spinBox->setMinimum(this->Minimum);
@@ -117,7 +117,7 @@ void ctkCoordinatesWidget::setMinimum(double min)
   for (int i = 0; this->layout()->itemAt(i); ++i)
     {
     QLayoutItem* item = this->layout()->itemAt(i);
-    QDoubleSpinBox* spinBox = item ? dynamic_cast<QDoubleSpinBox*>(
+    ctkSpinBox* spinBox = item ? qobject_cast<ctkSpinBox*>(
       item->widget()) : 0;
     if (spinBox)
       {
@@ -139,7 +139,7 @@ void ctkCoordinatesWidget::setMaximum(double max)
   for (int i = 0; this->layout()->itemAt(i); ++i)
     {
     QLayoutItem* item = this->layout()->itemAt(i);
-    QDoubleSpinBox* spinBox = item ? dynamic_cast<QDoubleSpinBox*>(
+    ctkSpinBox* spinBox = item ? qobject_cast<ctkSpinBox*>(
       item->widget()) : 0;
     if (spinBox)
       {
@@ -186,7 +186,7 @@ void ctkCoordinatesWidget::setDecimals(int newDecimals)
   for (int i = 0; this->layout()->itemAt(i); ++i)
     {
     QLayoutItem* item = this->layout()->itemAt(i);
-    QDoubleSpinBox* spinBox = item ? dynamic_cast<QDoubleSpinBox*>(
+    ctkSpinBox* spinBox = item ? qobject_cast<ctkSpinBox*>(
       item->widget()) : 0;
     if (spinBox)
       {
@@ -207,7 +207,7 @@ void ctkCoordinatesWidget::setSingleStep(double step)
   for (int i = 0; this->layout()->itemAt(i); ++i)
     {
     QLayoutItem* item = this->layout()->itemAt(i);
-    QDoubleSpinBox* spinBox = item ? dynamic_cast<QDoubleSpinBox*>(
+    ctkSpinBox* spinBox = item ? qobject_cast<ctkSpinBox*>(
       item->widget()) : 0;
     if (spinBox)
       {
@@ -270,8 +270,8 @@ void ctkCoordinatesWidget::setCoordinates(double* coordinates)
   for (int i = 0; i < this->Dimension; ++i)
     {
     QLayoutItem* item = this->layout()->itemAt(i);
-    QDoubleSpinBox* spinBox =
-      item ? dynamic_cast<QDoubleSpinBox*>(item->widget()) : 0;
+    ctkSpinBox* spinBox =
+      item ? qobject_cast<ctkSpinBox*>(item->widget()) : 0;
     if (spinBox)
       {
       // we don't want updateCoordinate() to be called.
@@ -326,8 +326,8 @@ void ctkCoordinatesWidget::updateCoordinate(double coordinate)
   for (int i = 0; i < this->Dimension; ++i)
     {
     QLayoutItem* item = this->layout()->itemAt(i);
-    QDoubleSpinBox* spinBox =
-      item ? qobject_cast<QDoubleSpinBox*>(item->widget()) : 0;
+    ctkSpinBox* spinBox =
+      item ? qobject_cast<ctkSpinBox*>(item->widget()) : 0;
     if ( spinBox && spinBox == this->sender())
       {
       this->Coordinates[i] = coordinate;
@@ -432,8 +432,8 @@ void ctkCoordinatesWidget::updateCoordinates()
   for (int i = 0; i < this->Dimension; ++i)
     {
     QLayoutItem* item = this->layout()->itemAt(i);
-    QDoubleSpinBox* spinBox =
-      item ? qobject_cast<QDoubleSpinBox*>(item->widget()) : 0;
+    ctkSpinBox* spinBox =
+      item ? qobject_cast<ctkSpinBox*>(item->widget()) : 0;
     if ( spinBox)
       {
       this->Coordinates[i] = spinBox->value();

+ 4 - 4
Libs/Widgets/ctkCoordinatesWidget.h

@@ -59,22 +59,22 @@ public:
   void setDimension(int dim);
   int dimension() const;
 
-  /// Set/Get the number of decimals of each coordinate QDoubleSpinBoxes
+  /// Set/Get the number of decimals of each coordinate spin box
   /// The default number of decimals is 3.
   void setDecimals(int decimals);
   int decimals() const;
 
-  /// Set/Get the single step of each coordinate QDoubleSpinBoxes
+  /// Set/Get the single step of each coordinate spin box
   /// The default single step is 1.
   void setSingleStep(double step);
   double singleStep() const;
 
-  /// Set/Get the minimum value of each coordinate QDoubleSpinBoxes
+  /// Set/Get the minimum value of each coordinate spin box
   /// The default minimum is -100000.
   void setMinimum(double minimum);
   double minimum() const;
 
-  /// Set/Get the maximum value of each coordinate QDoubleSpinBoxes
+  /// Set/Get the maximum value of each coordinate spin box
   /// The default maximum is 100000.
   void setMaximum(double minimum);
   double maximum() const;

+ 3 - 3
Libs/Widgets/ctkMatrixWidget.cpp

@@ -20,10 +20,10 @@
 
 // CTK includes
 #include "ctkMatrixWidget.h"
+#include "ctkSpinBox.h"
 
 // Qt includes
 #include <QDebug>
-#include <QDoubleSpinBox>
 #include <QHBoxLayout>
 #include <QHeaderView>
 #include <QItemEditorFactory>
@@ -40,11 +40,11 @@
 namespace
 {
 //-----------------------------------------------------------------------------
-  class ctkMatrixDoubleSpinBox : public QDoubleSpinBox
+  class ctkMatrixDoubleSpinBox : public ctkSpinBox
   {
   public:
     ctkMatrixDoubleSpinBox(QWidget * parentWidget)
-      : QDoubleSpinBox(parentWidget)
+      : ctkSpinBox(parentWidget)
     {
       // We know that the parentWidget() of parentWidget will be a
       // ctkMatrixWidget because this object is

+ 1 - 11
Libs/Widgets/ctkSliderWidget.cpp

@@ -401,11 +401,6 @@ void ctkSliderWidget::setPrefix(const QString& newPrefix)
 {
   Q_D(ctkSliderWidget);
   d->SpinBox->setPrefix(newPrefix);
-#if QT_VERSION < 0x040800
-  /// Setting the prefix doesn't recompute the sizehint, do it manually here:
-  /// See: http://bugreports.qt.nokia.com/browse/QTBUG-9530
-  d->SpinBox->setRange(d->SpinBox->minimum(), d->SpinBox->maximum());
-#endif
   d->updateSpinBoxWidth();
 }
 
@@ -421,11 +416,6 @@ void ctkSliderWidget::setSuffix(const QString& newSuffix)
 {
   Q_D(ctkSliderWidget);
   d->SpinBox->setSuffix(newSuffix);
-#if QT_VERSION < 0x040800
-  /// Setting the suffix doesn't recompute the sizehint, do it manually here:
-  /// See: http://bugreports.qt.nokia.com/browse/QTBUG-9530
-  d->SpinBox->setRange(d->SpinBox->minimum(), d->SpinBox->maximum());
-#endif
   d->updateSpinBoxWidth();
 }
 
@@ -566,7 +556,7 @@ ctkPopupWidget* ctkSliderWidget::popup()const
 }
 
 // --------------------------------------------------------------------------
-QDoubleSpinBox* ctkSliderWidget::spinBox()
+ctkSpinBox* ctkSliderWidget::spinBox()
 {
   Q_D(ctkSliderWidget);
   return d->SpinBox;

+ 2 - 2
Libs/Widgets/ctkSliderWidget.h

@@ -23,7 +23,6 @@
 
 // Qt includes
 #include <QSlider>
-class QDoubleSpinBox;
 
 // CTK includes
 #include <ctkPimpl.h>
@@ -33,6 +32,7 @@ class QDoubleSpinBox;
 class ctkDoubleSlider;
 class ctkPopupWidget;
 class ctkSliderWidgetPrivate;
+class ctkSpinBox;
 
 /// \ingroup Widgets
 ///
@@ -198,7 +198,7 @@ public:
   /// Returns the spinbox synchronized with the slider. Be careful
   /// with what you do with the spinbox as the slider might change
   /// properties automatically.
-  QDoubleSpinBox* spinBox();
+  ctkSpinBox* spinBox();
 
   ///
   /// Returns the slider synchronized with the spinbox. Be careful

+ 388 - 0
Libs/Widgets/ctkSpinBox.cpp

@@ -0,0 +1,388 @@
+/*=========================================================================
+
+  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.
+
+=========================================================================*/
+
+// CTK includes
+#include "ctkSpinBox.h"
+#include "ctkUtils.h"
+#include "ctkPimpl.h"
+
+#include <QDebug>
+
+// Qt includes
+#include <QDoubleSpinBox>
+#include <QEvent>
+#include <QHBoxLayout>
+#include <QKeySequence>
+#include <QShortcut>
+#include <QSizePolicy>
+#include <QVariant>
+
+//-----------------------------------------------------------------------------
+class ctkSpinBoxPrivate
+{
+  Q_DECLARE_PUBLIC(ctkSpinBox);
+protected:
+  ctkSpinBox* const q_ptr;
+public:
+  ctkSpinBoxPrivate(ctkSpinBox& object);
+
+  QDoubleSpinBox* SpinBox;
+  ctkSpinBox::SetMode Mode;
+
+  void init();
+  // Compare two double previously rounded according to the number of decimals
+  bool compare(double x1, double x2) const;
+};
+
+//-----------------------------------------------------------------------------
+ctkSpinBoxPrivate::ctkSpinBoxPrivate(ctkSpinBox& object) : q_ptr(&object)
+{
+  qRegisterMetaType<ctkSpinBox::SetMode>("ctkSpinBox::SetMode");
+  this->SpinBox = 0;
+  this->Mode = ctkSpinBox::SetIfDifferent;
+}
+
+//-----------------------------------------------------------------------------
+void ctkSpinBoxPrivate::init()
+{
+  Q_Q(ctkSpinBox);
+  this->SpinBox = new QDoubleSpinBox(q);
+  QObject::connect(this->SpinBox, SIGNAL(valueChanged(double)),
+    q, SIGNAL(valueChanged(double)));
+  QObject::connect(this->SpinBox, SIGNAL(valueChanged(const QString&)),
+    q, SIGNAL(valueChanged(const QString &)));
+  QObject::connect(this->SpinBox, SIGNAL(editingFinished()),
+    q, SIGNAL(editingFinished()));
+
+  QHBoxLayout* l = new QHBoxLayout(q);
+  l->addWidget(this->SpinBox);
+  l->setContentsMargins(0,0,0,0);
+  q->setLayout(l);
+  q->setSizePolicy(QSizePolicy(QSizePolicy::Minimum,
+    QSizePolicy::Fixed, QSizePolicy::ButtonBox));
+}
+
+//-----------------------------------------------------------------------------
+bool ctkSpinBoxPrivate::compare(double x1, double x2) const
+{
+  Q_Q(const ctkSpinBox);
+  return q->round(x1) == q->round(x2);
+}
+
+//-----------------------------------------------------------------------------
+ctkSpinBox::ctkSpinBox(QWidget* newParent)
+  : QWidget(newParent)
+  , d_ptr(new ctkSpinBoxPrivate(*this))
+{
+  Q_D(ctkSpinBox);
+  d->init();
+}
+
+//-----------------------------------------------------------------------------
+ctkSpinBox::ctkSpinBox(ctkSpinBox::SetMode mode, QWidget* newParent)
+  : QWidget(newParent)
+  , d_ptr(new ctkSpinBoxPrivate(*this))
+{
+  Q_D(ctkSpinBox);
+  d->init();
+  this->setSetMode(mode);
+}
+
+//-----------------------------------------------------------------------------
+double ctkSpinBox::value() const
+{
+  Q_D(const ctkSpinBox);
+  return d->SpinBox->value();
+}
+
+//-----------------------------------------------------------------------------
+double ctkSpinBox::displayedValue() const
+{
+  Q_D(const ctkSpinBox);
+  return this->round(this->value());
+}
+
+//-----------------------------------------------------------------------------
+QString ctkSpinBox::text() const
+{
+  Q_D(const ctkSpinBox);
+  return d->SpinBox->text();
+}
+
+//-----------------------------------------------------------------------------
+QString ctkSpinBox::cleanText() const
+{
+  Q_D(const ctkSpinBox);
+  return d->SpinBox->cleanText();
+}
+
+//-----------------------------------------------------------------------------
+Qt::Alignment ctkSpinBox::alignment() const
+{
+  Q_D(const ctkSpinBox);
+  return d->SpinBox->alignment();
+}
+
+//-----------------------------------------------------------------------------
+void ctkSpinBox::setAlignment(Qt::Alignment flag)
+{
+  Q_D(const ctkSpinBox);
+  if (d->Mode == ctkSpinBox::SetIfDifferent && flag == d->SpinBox->alignment())
+    {
+    return;
+    }
+
+  d->SpinBox->setAlignment(flag);
+}
+
+//-----------------------------------------------------------------------------
+void ctkSpinBox::setFrame(bool frame)
+{
+  Q_D(const ctkSpinBox);
+  if (d->Mode == ctkSpinBox::SetIfDifferent && frame == d->SpinBox->hasFrame())
+    {
+    return;
+    }
+
+  d->SpinBox->setFrame(frame);
+}
+
+//-----------------------------------------------------------------------------
+bool ctkSpinBox::hasFrame() const
+{
+  Q_D(const ctkSpinBox);
+  return d->SpinBox->hasFrame();
+}
+
+//-----------------------------------------------------------------------------
+QString ctkSpinBox::prefix() const
+{
+  Q_D(const ctkSpinBox);
+  return d->SpinBox->prefix();
+}
+
+//-----------------------------------------------------------------------------
+void ctkSpinBox::setPrefix(const QString &prefix)
+{
+  Q_D(const ctkSpinBox);
+  if (d->Mode == ctkSpinBox::SetIfDifferent && prefix == d->SpinBox->prefix())
+    {
+    return;
+    }
+
+#if QT_VERSION < 0x040800
+  /// Setting the prefix doesn't recompute the sizehint, do it manually here:
+  /// See: http://bugreports.qt.nokia.com/browse/QTBUG-9530
+  d->SpinBox->setRange(d->SpinBox->minimum(), d->SpinBox->maximum());
+#endif
+
+  d->SpinBox->setPrefix(prefix);
+}
+
+//-----------------------------------------------------------------------------
+QString ctkSpinBox::suffix() const
+{
+  Q_D(const ctkSpinBox);
+  return d->SpinBox->suffix();
+}
+
+//-----------------------------------------------------------------------------
+void ctkSpinBox::setSuffix(const QString &suffix)
+{
+  Q_D(const ctkSpinBox);
+  if (d->Mode == ctkSpinBox::SetIfDifferent && suffix == d->SpinBox->suffix())
+    {
+    return;
+    }
+
+#if QT_VERSION < 0x040800
+  /// Setting the suffix doesn't recompute the sizehint, do it manually here:
+  /// See: http://bugreports.qt.nokia.com/browse/QTBUG-9530
+  d->SpinBox->setRange(d->SpinBox->minimum(), d->SpinBox->maximum());
+#endif
+
+  d->SpinBox->setSuffix(suffix);
+}
+
+//-----------------------------------------------------------------------------
+double ctkSpinBox::singleStep() const
+{
+  Q_D(const ctkSpinBox);
+  return d->SpinBox->singleStep();
+}
+
+//-----------------------------------------------------------------------------
+void ctkSpinBox::setSingleStep(double step)
+{
+  Q_D(ctkSpinBox);
+  if (d->Mode == ctkSpinBox::SetIfDifferent
+    && d->compare(step, this->singleStep()))
+    {
+    return;
+    }
+
+  d->SpinBox->setSingleStep(step);
+}
+
+//-----------------------------------------------------------------------------
+double ctkSpinBox::minimum() const
+{
+  Q_D(const ctkSpinBox);
+  return d->SpinBox->minimum();
+}
+
+//-----------------------------------------------------------------------------
+void ctkSpinBox::setMinimum(double min)
+{
+  Q_D(ctkSpinBox);
+  if (d->Mode == ctkSpinBox::SetIfDifferent
+    && d->compare(min, this->minimum()))
+    {
+    return;
+    }
+
+  d->SpinBox->setMinimum(min);
+}
+
+//-----------------------------------------------------------------------------
+double ctkSpinBox::maximum() const
+{
+  Q_D(const ctkSpinBox);
+  return d->SpinBox->maximum();
+}
+
+//-----------------------------------------------------------------------------
+void ctkSpinBox::setMaximum(double max)
+{
+  Q_D(ctkSpinBox);
+  if (d->Mode == ctkSpinBox::SetIfDifferent
+    && d->compare(max, this->maximum()))
+    {
+    return;
+    }
+
+  d->SpinBox->setMaximum(max);
+}
+
+//-----------------------------------------------------------------------------
+void ctkSpinBox::setRange(double min, double max)
+{
+  Q_D(ctkSpinBox);
+  if (d->Mode == ctkSpinBox::SetIfDifferent
+    && d->compare(max, this->maximum()) && d->compare(min, this->minimum()))
+    {
+    return;
+    }
+
+  d->SpinBox->setRange(min, max);
+}
+
+//-----------------------------------------------------------------------------
+int ctkSpinBox::decimals() const
+{
+  Q_D(const ctkSpinBox);
+  return d->SpinBox->decimals();
+}
+
+//-----------------------------------------------------------------------------
+void ctkSpinBox::setDecimals(int dec)
+{
+  Q_D(const ctkSpinBox);
+  if (d->Mode == ctkSpinBox::SetIfDifferent && dec == d->SpinBox->decimals())
+    {
+    return;
+    }
+
+  d->SpinBox->setDecimals(dec);
+}
+
+//-----------------------------------------------------------------------------
+double ctkSpinBox::round(double value) const
+{
+  Q_D(const ctkSpinBox);
+  return QString::number(value, 'f', d->SpinBox->decimals()).toDouble();
+}
+
+//-----------------------------------------------------------------------------
+QDoubleSpinBox* ctkSpinBox::spinBox() const
+{
+  Q_D(const ctkSpinBox);
+  return d->SpinBox;
+}
+
+//-----------------------------------------------------------------------------
+void ctkSpinBox::setValue(double value)
+{
+  Q_D(const ctkSpinBox);
+  if (d->Mode == ctkSpinBox::SetIfDifferent)
+    {
+    this->setValueIfDifferent(value);
+    }
+  else
+    {
+    this->setValueAlways(value);
+    }
+}
+
+//-----------------------------------------------------------------------------
+void ctkSpinBox::setValueIfDifferent(double value)
+{
+  Q_D(ctkSpinBox);
+  if (! d->compare(this->value(), value))
+    {
+    d->SpinBox->setValue(value);
+    }
+}
+
+//-----------------------------------------------------------------------------
+void ctkSpinBox::setValueAlways(double value)
+{
+  Q_D(const ctkSpinBox);
+  d->SpinBox->setValue(value);
+}
+
+//-----------------------------------------------------------------------------
+void ctkSpinBox::stepUp()
+{
+  Q_D(const ctkSpinBox);
+  d->SpinBox->stepUp();
+}
+
+//-----------------------------------------------------------------------------
+void ctkSpinBox::stepDown()
+{
+  Q_D(const ctkSpinBox);
+  d->SpinBox->stepDown();
+}
+
+//-----------------------------------------------------------------------------
+ctkSpinBox::SetMode ctkSpinBox::setMode() const
+{
+  Q_D(const ctkSpinBox);
+  return d->Mode;
+}
+
+//-----------------------------------------------------------------------------
+void ctkSpinBox::setSetMode(ctkSpinBox::SetMode newMode)
+{
+  Q_D(ctkSpinBox);
+  d->Mode = newMode;
+}
+

+ 190 - 0
Libs/Widgets/ctkSpinBox.h

@@ -0,0 +1,190 @@
+/*=========================================================================
+
+  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.
+
+=========================================================================*/
+
+#ifndef __ctkSpinBox_h
+#define __ctkSpinBox_h
+
+// Qt includes
+#include <QMetaType>
+#include <QString>
+#include <QWidget>
+
+class QDoubleSpinBox;
+
+// CTK includes
+#include "ctkWidgetsExport.h"
+
+class ctkSpinBoxPrivate;
+
+/// \brief Custom SpinBox
+/// The ctkSpinBox internaly uses a QDoubleSpinBox while it retain controls
+/// over it.
+/// \sa ctkDoubleSlider, ctkSliderWidget, ctkRangeSlider
+class CTK_WIDGETS_EXPORT ctkSpinBox : public QWidget
+{
+  Q_OBJECT
+  Q_ENUMS(SetMode)
+  Q_PROPERTY(SetMode setMode READ setMode WRITE setSetMode)
+  Q_PROPERTY(Qt::Alignment alignment READ alignment WRITE setAlignment)
+  Q_PROPERTY(bool frame READ hasFrame WRITE setFrame)
+  Q_PROPERTY(QString prefix READ prefix WRITE setPrefix)
+  Q_PROPERTY(QString suffix READ suffix WRITE setSuffix)
+  Q_PROPERTY(QString cleanText READ cleanText)
+  Q_PROPERTY(int decimals READ decimals WRITE setDecimals)
+  Q_PROPERTY(double minimum READ minimum WRITE setMinimum)
+  Q_PROPERTY(double maximum READ maximum WRITE setMaximum)
+  Q_PROPERTY(double singleStep READ singleStep WRITE setSingleStep)
+  Q_PROPERTY(double value READ value WRITE setValue NOTIFY valueChanged USER true)
+
+public:
+
+  /// SetMode enums for the spinbox behavior.
+  /// SetAlways:
+  /// No check is made and the given parameters is directly set
+  /// on the internal QDoubleSpinBox.
+  /// SetIfDifferent:
+  /// Default mode, the given parameter is checked agains the
+  /// current internal value and only set if they are different.
+  /// For double, the comparison is based on the input parameters rounded
+  /// with the current number of decimals (see round()).
+  /// \sa setMode(), setSetMode(), round()
+  enum SetMode
+    {
+    SetAlways,
+    SetIfDifferent,
+    };
+
+  typedef QWidget Superclass;
+
+  /// Constructor, creates a ctkSpinBox. The look and feel
+  /// are the same as of a QDoubleSpinBox
+  ctkSpinBox(QWidget* parent = 0);
+  ctkSpinBox(ctkSpinBox::SetMode mode, QWidget* parent = 0);
+
+  /// Get the spinbox current value
+  /// \sa setValue(), cleanText()
+  double value() const;
+
+  /// Get the spinbox current displayed value
+  /// \sa value(), cleanText()
+  double displayedValue() const;
+
+  /// Get the spinbox current text. This includes any prefix or suffix.
+  /// \sa prefix(), suffix()
+  QString text() const;
+
+  /// Get the spinbox current text. This excludes any prefix or suffix.
+  /// \sa value()
+  QString cleanText() const;
+
+  /// Set/Get the spinbox alignement
+  Qt::Alignment alignment () const;
+  void setAlignment (Qt::Alignment flag);
+
+  /// Set/Get the frame
+  void setFrame(bool frame);
+  bool hasFrame() const;
+
+  /// Add/Get a prefix to the displayed value. For example, one might want to
+  /// add the $ sign.
+  /// \sa suffix(), text()
+  QString prefix() const;
+  void setPrefix(const QString &prefix);
+
+  /// Add/Get a suffix to the displayed value. For example, one might want to
+  /// add the F (fahrenheit) sign.
+  /// \sa prefix(), text()
+  QString suffix() const;
+  void setSuffix(const QString &suffix);
+
+  /// Set/Get the single step. This represents by how much the value will
+  /// decrease or increase when clicking the spinbox arrow or using stepUp or
+  /// stepDown(). Default is 1.0.
+  /// \sa setUp(), stepDown(), setDecimals().
+  double singleStep() const;
+  void setSingleStep(double value);
+
+  /// Set/Get the range of the spinbox. Default range is [0.0, 9.9].
+  double minimum() const;
+  void setMinimum(double min);
+  double maximum() const;
+  void setMaximum(double max);
+  void setRange(double min, double max);
+
+  /// Set/Get number of decimals displayed. For a spinbox dealing only with
+  /// integers, set this to 0.
+  /// \sa addOneDecimal(), removeOneDecimal()
+  int decimals() const;
+  void setDecimals(int decimal);
+
+  /// Returns the rounded value according to the number of decimals of
+  /// the spinbox.
+  /// \sa decimals()
+  double round(double value) const;
+
+  /// Get a pointer on the spinbox used internally. It can be useful to
+  /// change display properties for example. To use with caution.
+  /// \sa QDoubleSpinBox::QDoubleSpinBox
+  QDoubleSpinBox* spinBox() const;
+
+  /// Set the spinbox mode when using a set*() method.
+  //// \sa round(), setValue(), setValueIfDifferent(), setValueAlways()
+  ctkSpinBox::SetMode setMode() const;
+  void setSetMode(SetMode mode);
+
+public Q_SLOTS:
+  /// Set the value of the spinbox following the current mode.
+  /// \sa setMode(), value(), setValueIfDifferent(), setValueAlways()
+  void setValue(double value);
+
+  /// Set the value of the spinbox followin the SetIfDifferent mode.
+  /// \sa value(), setValue(), setMode(), setValueAlways()
+  void setValueIfDifferent(double value);
+
+  /// Set the value of the spinbox following the SetAlways mode.
+  /// \sa value(), setValue(), setMode(), setValueIfDifferent()
+  void setValueAlways(double value);
+
+  /// Increase/Decrease the current value by a single step.
+  /// \sa value(), singleStep()
+  void stepUp();
+  void stepDown();
+
+Q_SIGNALS:
+  /// Emitted everytime the spinbox value is modified
+  /// \sa QDoubleSpinBox::valueChanged()
+  void valueChanged(double);
+  void valueChanged(const QString &);
+
+  /// Simple broadcast of the QAbstractSpinbox::editingFinished
+  /// \sa QAbstractSpinbox::editingFinished
+  void editingFinished();
+
+protected:
+  ctkSpinBoxPrivate* const d_ptr;
+
+private:
+  Q_DECLARE_PRIVATE(ctkSpinBox);
+  Q_DISABLE_COPY(ctkSpinBox);
+};
+
+Q_DECLARE_METATYPE(ctkSpinBox::SetMode)
+
+#endif //__ctkSpinBox_h