Bladeren bron

Add ctkProxyStyle and apply to ctkCheckBox, ctkCollapsibleGroupBox

Closes #262, #285
Julien Finet 12 jaren geleden
bovenliggende
commit
66799eeac9

+ 3 - 0
Libs/Widgets/CMakeLists.txt

@@ -120,6 +120,8 @@ set(KIT_SRCS
   ctkPopupWidget.cpp
   ctkPopupWidget.h
   ctkPopupWidget_p.h
+  ctkProxyStyle.cpp
+  ctkProxyStyle.h
   ctkQImageView.cpp
   ctkQImageView.h
   ctkRangeSlider.cpp
@@ -239,6 +241,7 @@ set(KIT_MOC_SRCS
   ctkPathListButtonsWidget_p.h
   ctkPopupWidget.h
   ctkPopupWidget_p.h
+  ctkProxyStyle.h
   ctkQImageView.h
   ctkRangeSlider.h
   ctkRangeWidget.h

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

@@ -55,6 +55,7 @@ set(TEST_SOURCES
   ctkPathListWidgetTest.cpp
   ctkPathListWidgetWithButtonsTest.cpp
   ctkPopupWidgetTest1.cpp
+  ctkProxyStyleTest1.cpp
   ctkRangeSliderTest.cpp
   ctkRangeSliderTest1.cpp
   ctkRangeWidgetTest1.cpp
@@ -257,6 +258,7 @@ SIMPLE_TEST( ctkPathLineEditTest1 )
 SIMPLE_TEST( ctkPathListWidgetTest )
 SIMPLE_TEST( ctkPathListWidgetWithButtonsTest )
 SIMPLE_TEST( ctkPopupWidgetTest1 )
+SIMPLE_TEST( ctkProxyStyleTest1 )
 SIMPLE_TEST( ctkRangeSliderTest )
 SIMPLE_TEST( ctkRangeSliderTest1 )
 SIMPLE_TEST( ctkRangeWidgetTest1 )

+ 41 - 17
Libs/Widgets/Testing/Cpp/ctkCheckBoxTest1.cpp

@@ -21,34 +21,45 @@
 // Qt includes
 #include <QApplication>
 #include <QDebug>
-#include <QStyle>
+#include <QFormLayout>
+#include <QProxyStyle>
 #include <QTimer>
-#include <QVBoxLayout>
 
 // CTK includes
 #include "ctkCheckBox.h"
+#include "ctkProxyStyle.h"
 
 // STD includes
 #include <cstdlib>
 #include <iostream>
 
 //-----------------------------------------------------------------------------
-int ctkCheckBoxTest1(int argc, char * argv [] )
+int ctkCheckBoxTest1(int argc, char * argv [])
 {
+  //QPlastiqueStyle* style = new QPlastiqueStyle;
+  //QApplication::setStyle(style);
   QApplication app(argc, argv);
 
-  QWidget topLevel;
-  ctkCheckBox* checkBoxWithoutIcon = new ctkCheckBox(0);
-  ctkCheckBox* checkBoxWithIcon = new ctkCheckBox(0);
-  checkBoxWithIcon->setIcon(QApplication::style()->standardIcon(QStyle::SP_FileIcon));
-  ctkCheckBox* checkBoxWithIconAndText = new ctkCheckBox(0);
+  QPixmap onPixmap =
+    QApplication::style()->standardPixmap(QStyle::SP_DriveCDIcon);
+  QPixmap offPixmap =
+    QApplication::style()->standardPixmap(QStyle::SP_DesktopIcon);
   QIcon icon;
-  icon.addPixmap(QApplication::style()->standardPixmap(QStyle::SP_DriveCDIcon),
+  icon.addPixmap(offPixmap,
                  QIcon::Normal,
                  QIcon::On);
-  icon.addPixmap(QApplication::style()->standardPixmap(QStyle::SP_DesktopIcon),
+  icon.addPixmap(onPixmap,
                  QIcon::Normal,
                  QIcon::Off);
+
+  QWidget topLevel;
+  ctkCheckBox* checkBoxWithoutIcon = new ctkCheckBox(0);
+  checkBoxWithoutIcon->setIndicatorIcon(icon);
+
+  ctkCheckBox* checkBoxWithIcon = new ctkCheckBox(0);
+  checkBoxWithIcon->setIcon(QApplication::style()->standardIcon(QStyle::SP_FileIcon));
+
+  ctkCheckBox* checkBoxWithIconAndText = new ctkCheckBox(0);
   checkBoxWithoutIcon->setIndicatorIcon(icon);
 //  checkBoxWithoutIcon->setIndicatorIconSize(QSize(15,15));
   checkBoxWithIcon->setIndicatorIcon(icon);
@@ -76,16 +87,29 @@ int ctkCheckBoxTest1(int argc, char * argv [] )
   checkBoxWithIconAndText2->setText("Test1");
   checkBoxWithIconAndText2->setIcon(QApplication::style()->standardIcon(QStyle::SP_FileIcon));
 
-  QVBoxLayout* layout = new QVBoxLayout;
-  layout->addWidget(checkBoxWithoutIcon);
-  layout->addWidget(checkBoxWithIcon);
-  layout->addWidget(checkBoxWithIconAndText);
-  layout->addWidget(checkBoxWithoutIcon2);
-  layout->addWidget(checkBoxWithIcon2);
-  layout->addWidget(checkBoxWithIconAndText2);
+  QFormLayout* layout = new QFormLayout(&topLevel);
+  layout->addRow("Indicator:", checkBoxWithoutIcon);
+  layout->addRow("Icon:", checkBoxWithIcon);
+  layout->addRow("Indicator, Icon, Text:", checkBoxWithIconAndText);
+  layout->addRow("Default:", checkBoxWithoutIcon2);
+  layout->addRow("Icon:", checkBoxWithIcon2);
+  layout->addRow("Icon, Text:", checkBoxWithIconAndText2);
   topLevel.setLayout(layout);
   topLevel.show();
 
+  // Style check
+  ctkProxyStyle* checkBoxStyle = qobject_cast<ctkProxyStyle*>(checkBoxWithoutIcon->style());
+  if (!checkBoxStyle)
+    {
+    std::cerr << "Not a ctkProxyStyle" << std::endl;
+    return EXIT_FAILURE;
+    }
+  checkBoxStyle->ensureBaseStyle();
+  if (checkBoxStyle->baseStyle()->proxy() != checkBoxStyle)
+    {
+    std::cerr << "Wrong proxy: " << checkBoxStyle->baseStyle()->proxy() << std::endl;
+    return EXIT_FAILURE;
+    }
 
   if (argc < 2 || QString(argv[1]) != "-I" )
     {

+ 90 - 0
Libs/Widgets/Testing/Cpp/ctkProxyStyleTest1.cpp

@@ -0,0 +1,90 @@
+/*=========================================================================
+
+  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 <QPlastiqueStyle>
+#include <QProxyStyle>
+#include <QTimer>
+#include <QVBoxLayout>
+
+// CTK includes
+#include "ctkCheckBox.h"
+#include "ctkCollapsibleButton.h"
+#include "ctkCollapsibleGroupBox.h"
+#include "ctkProxyStyle.h"
+
+// STD includes
+#include <cstdlib>
+#include <iostream>
+
+//-----------------------------------------------------------------------------
+int ctkProxyStyleTest1(int argc, char * argv [])
+{
+  //QPlastiqueStyle* style = new QPlastiqueStyle;
+  //QApplication::setStyle(style);
+  QApplication app(argc, argv);
+
+  QPixmap onPixmap =
+    QApplication::style()->standardPixmap(QStyle::SP_DriveCDIcon);
+  QPixmap offPixmap =
+    QApplication::style()->standardPixmap(QStyle::SP_DesktopIcon);
+  QIcon icon;
+  icon.addPixmap(offPixmap,
+                 QIcon::Normal,
+                 QIcon::On);
+  icon.addPixmap(onPixmap,
+                 QIcon::Normal,
+                 QIcon::Off);
+
+  QWidget topLevel;
+  QVBoxLayout* topLevelLayout = new QVBoxLayout(&topLevel);
+  topLevel.setLayout(topLevelLayout);
+  for (int i = 0; i < 2 ; ++i)
+    {
+    ctkCollapsibleButton* button = new ctkCollapsibleButton;
+    QVBoxLayout* buttonLayout = new QVBoxLayout(button);
+    button->setLayout(buttonLayout);
+    for (int j = 0; j < 2; ++j)
+      {
+      ctkCollapsibleGroupBox* groupBox = new ctkCollapsibleGroupBox;
+      QVBoxLayout* groupBoxLayout = new QVBoxLayout(groupBox);
+      groupBox->setLayout(groupBoxLayout);
+      for (int k = 0; k < 2; ++k)
+        {
+        ctkCheckBox* checkBox = new ctkCheckBox;
+        checkBox->setIndicatorIcon(icon);
+        groupBoxLayout->addWidget(checkBox);
+        }
+      buttonLayout->addWidget(groupBox);
+      }
+    topLevelLayout->addWidget(button);
+    }
+
+  topLevel.show();
+
+  if (argc < 2 || QString(argv[1]) != "-I" )
+    {
+    QTimer::singleShot(200, &app, SLOT(quit()));
+    }
+
+  return app.exec();
+}

+ 19 - 9
Libs/Widgets/ctkCheckBox.cpp

@@ -19,19 +19,22 @@
 =========================================================================*/
 // QT includes
 #include <QApplication>
-#include <QProxyStyle>
 #include <QStyleOption>
 
 // CTK includes
 #include "ctkCheckBox.h"
+#include "ctkProxyStyle.h"
 
+// STD includes
 #include <iostream>
 
 // ----------------------------------------------------------------------------
-class ctkCheckBoxStyle : public QProxyStyle
+class ctkCheckBoxStyle : public ctkProxyStyle
 {
-  public:
-  ctkCheckBoxStyle(QStyle *parentStyle);
+public:
+  typedef ctkProxyStyle Superclass;
+  ctkCheckBoxStyle(QStyle* baseStyle, QObject* parent = 0);
+  virtual ~ctkCheckBoxStyle();
 
   virtual void drawPrimitive(QStyle::PrimitiveElement pe,
                              const QStyleOption * opt,
@@ -50,8 +53,14 @@ class ctkCheckBoxStyle : public QProxyStyle
 //  Methods ctkCheckBoxStyle
 
 // ----------------------------------------------------------------------------
-ctkCheckBoxStyle::ctkCheckBoxStyle(QStyle *parentStyle)
-  : QProxyStyle(parentStyle)
+ctkCheckBoxStyle::ctkCheckBoxStyle(QStyle *baseStyle, QObject* parent)
+  : Superclass(baseStyle)
+{
+  this->setParent(parent);
+}
+
+// ----------------------------------------------------------------------------
+ctkCheckBoxStyle::~ctkCheckBoxStyle()
 {
 }
 
@@ -86,7 +95,7 @@ void ctkCheckBoxStyle::drawPrimitive(QStyle::PrimitiveElement pe,
       return;
       }
     }
-  this->QProxyStyle::drawPrimitive(pe, opt, p, widget);
+  this->Superclass::drawPrimitive(pe, opt, p, widget);
 }
 
 // ----------------------------------------------------------------------------
@@ -106,7 +115,7 @@ int ctkCheckBoxStyle::pixelMetric(QStyle::PixelMetric metric,
       return this->indicatorIcon.actualSize(this->indicatorSize).width();
       }
     }
-  return this->QProxyStyle::pixelMetric(metric, option, widget);
+  return this->Superclass::pixelMetric(metric, option, widget);
 }
 
 // ----------------------------------------------------------------------------
@@ -138,8 +147,9 @@ void ctkCheckBoxPrivate::init()
   Q_Q(ctkCheckBox);
   QWidget* parent = q->parentWidget();
   QStyle* parentStyle = (parent) ? parent->style() : QApplication::style();
-  this->iconStyle = new ctkCheckBoxStyle(parentStyle);
+  this->iconStyle = new ctkCheckBoxStyle(parentStyle, q);
   q->setStyle(this->iconStyle);
+  this->iconStyle->ensureBaseStyle();
 }
 
 // ----------------------------------------------------------------------------

+ 9 - 7
Libs/Widgets/ctkCollapsibleGroupBox.cpp

@@ -31,13 +31,14 @@
 #include "ctkCollapsibleGroupBox.h"
 
 #if QT_VERSION >= 0x040600
-#include <QProxyStyle>
+#include "ctkProxyStyle.h"
 
 //-----------------------------------------------------------------------------
-class ctkCollapsibleGroupBoxStyle:public QProxyStyle
+class ctkCollapsibleGroupBoxStyle:public ctkProxyStyle
 {
-  public:
-  ctkCollapsibleGroupBoxStyle(QStyle* style = 0) : QProxyStyle(style)
+public:
+  typedef ctkProxyStyle Superclass;
+  ctkCollapsibleGroupBoxStyle(QStyle* style = 0) : Superclass(style)
   {
   }
   virtual void drawPrimitive(PrimitiveElement pe, const QStyleOption * opt, QPainter * p, const QWidget * widget = 0) const
@@ -47,11 +48,11 @@ class ctkCollapsibleGroupBoxStyle:public QProxyStyle
       const ctkCollapsibleGroupBox* groupBox= qobject_cast<const ctkCollapsibleGroupBox*>(widget);
       if (groupBox)
         {
-        this->QProxyStyle::drawPrimitive(groupBox->isChecked() ? QStyle::PE_IndicatorArrowDown : QStyle::PE_IndicatorArrowRight, opt, p, widget);
+        this->Superclass::drawPrimitive(groupBox->isChecked() ? QStyle::PE_IndicatorArrowDown : QStyle::PE_IndicatorArrowRight, opt, p, widget);
         return;
         }
       }
-    this->QProxyStyle::drawPrimitive(pe, opt, p, widget);
+    this->Superclass::drawPrimitive(pe, opt, p, widget);
   }
   virtual int pixelMetric(PixelMetric metric, const QStyleOption * option, const QWidget * widget) const
   {
@@ -63,7 +64,7 @@ class ctkCollapsibleGroupBoxStyle:public QProxyStyle
         return groupBox->fontMetrics().height();
         }
       }
-    return this->QProxyStyle::pixelMetric(metric, option, widget);
+    return this->Superclass::pixelMetric(metric, option, widget);
   }
 };
 #endif
@@ -128,6 +129,7 @@ void ctkCollapsibleGroupBoxPrivate::init()
   QStyle* parentStyle = (parent) ? parent->style() : QApplication::style();
   this->GroupBoxStyle = new ctkCollapsibleGroupBoxStyle(parentStyle);
   q->setStyle(this->GroupBoxStyle);
+  this->GroupBoxStyle->ensureBaseStyle();
 #else
   this->setStyleSheet(
     "ctkCollapsibleGroupBox::indicator:checked{"

+ 333 - 0
Libs/Widgets/ctkProxyStyle.cpp

@@ -0,0 +1,333 @@
+/*=========================================================================
+
+  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 <QPointer>
+#include <QStyleFactory>
+
+// CTK includes
+#include "ctkProxyStyle.h"
+
+// ----------------------------------------------------------------------------
+class ctkProxyStylePrivate
+{
+  Q_DECLARE_PUBLIC(ctkProxyStyle)
+protected:
+  ctkProxyStyle* const q_ptr;
+public:
+  void setProxyStyle(QProxyStyle* proxy, QStyle *style)const;
+  void setBaseStyle(QProxyStyle* proxyStyle, QStyle* baseStyle)const;
+private:
+  ctkProxyStylePrivate(ctkProxyStyle& object);
+  mutable bool InEnsureBaseStyle;
+  mutable QPointer <QStyle> baseStyle;
+};
+
+// ----------------------------------------------------------------------------
+ctkProxyStylePrivate::ctkProxyStylePrivate(ctkProxyStyle& object)
+  : q_ptr(&object)
+  , InEnsureBaseStyle(false)
+{
+}
+
+// ----------------------------------------------------------------------------
+void ctkProxyStylePrivate::setProxyStyle(QProxyStyle* proxy, QStyle *style)const
+{
+  if (style->proxy() == proxy)
+    {
+    return;
+    }
+  this->setBaseStyle(proxy, style);
+}
+// ----------------------------------------------------------------------------
+void ctkProxyStylePrivate::setBaseStyle(QProxyStyle* proxy, QStyle *style)const
+{
+  if (proxy->baseStyle() == style &&
+      style->proxy() == proxy)
+    {
+    return;
+    }
+  QObject* parent = style->parent();
+  QStyle* oldStyle = proxy->baseStyle();
+  QObject* oldParent = oldStyle ? oldStyle->parent() : 0;
+  if (oldParent == proxy)
+    {
+    oldStyle->setParent(0);// make sure setBaseStyle doesn't delete baseStyle
+    }
+  proxy->setBaseStyle(style);
+  style->setParent(parent);
+  if (oldParent == proxy)
+    {
+    oldStyle->setParent(oldParent);
+    }
+  //if (style == qApp->style())
+  //  {
+  //  style->setParent(qApp); // don't delete the application style.
+  //  }
+}
+
+// ----------------------------------------------------------------------------
+ctkProxyStyle::ctkProxyStyle(QStyle *style)
+  : d_ptr(new ctkProxyStylePrivate(*this))
+{
+  Q_D(ctkProxyStyle);
+  d->baseStyle = style;
+  this->setBaseStyle(style);
+}
+
+// ----------------------------------------------------------------------------
+ctkProxyStyle::~ctkProxyStyle()
+{
+  Q_D(ctkProxyStyle);
+  if (d->baseStyle == qApp->style())
+    {
+    d->baseStyle->setParent(qApp); // don't delete the application style.
+    }
+}
+
+// ----------------------------------------------------------------------------
+void ctkProxyStyle::ensureBaseStyle() const
+{
+  Q_D(const ctkProxyStyle);
+  d->baseStyle = this->baseStyle();
+  if (d->InEnsureBaseStyle)
+    {
+    //return;
+    }
+  d->InEnsureBaseStyle = true;
+  // Set the proxy to the entire hierarchy.
+  QProxyStyle* proxyStyle = const_cast<QProxyStyle*>(qobject_cast<const QProxyStyle*>(
+    this->proxy() ? this->proxy() : this));
+  QStyle* proxyBaseStyle = proxyStyle->baseStyle(); // calls ensureBaseStyle
+  QStyle* baseStyle = proxyBaseStyle;
+  while (baseStyle)
+    {
+    d->setProxyStyle(proxyStyle, baseStyle);// set proxy on itself to all children
+    QProxyStyle* proxy = qobject_cast<QProxyStyle*>(baseStyle);
+    baseStyle = proxy ? proxy->baseStyle() : 0;
+    }
+  d->setBaseStyle(proxyStyle, proxyBaseStyle);
+  d->InEnsureBaseStyle = false;
+}
+
+// ----------------------------------------------------------------------------
+void ctkProxyStyle::drawPrimitive(PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const
+{
+    Q_D(const ctkProxyStyle);
+    this->ensureBaseStyle();
+    d->baseStyle->drawPrimitive(element, option, painter, widget);
+}
+
+// ----------------------------------------------------------------------------
+void ctkProxyStyle::drawControl(ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const
+{
+    Q_D(const ctkProxyStyle);
+    this->ensureBaseStyle();
+    d->baseStyle->drawControl(element, option, painter, widget);
+}
+
+// ----------------------------------------------------------------------------
+void ctkProxyStyle::drawComplexControl(ComplexControl control, const QStyleOptionComplex *option, QPainter *painter, const QWidget *widget) const
+{
+    Q_D(const ctkProxyStyle);
+    this->ensureBaseStyle();
+    d->baseStyle->drawComplexControl(control, option, painter, widget);
+}
+
+// ----------------------------------------------------------------------------
+void ctkProxyStyle::drawItemText(QPainter *painter, const QRect &rect, int flags, const QPalette &pal, bool enabled,
+                               const QString &text, QPalette::ColorRole textRole) const
+{
+    Q_D(const ctkProxyStyle);
+    this->ensureBaseStyle();
+    d->baseStyle->drawItemText(painter, rect, flags, pal, enabled, text, textRole);
+}
+
+// ----------------------------------------------------------------------------
+void ctkProxyStyle::drawItemPixmap(QPainter *painter, const QRect &rect, int alignment, const QPixmap &pixmap) const
+{
+    Q_D(const ctkProxyStyle);
+    this->ensureBaseStyle();
+    d->baseStyle->drawItemPixmap(painter, rect, alignment, pixmap);
+}
+
+// ----------------------------------------------------------------------------
+QSize ctkProxyStyle::sizeFromContents(ContentsType type, const QStyleOption *option, const QSize &size, const QWidget *widget) const
+{
+    Q_D(const ctkProxyStyle);
+    this->ensureBaseStyle();
+    return d->baseStyle->sizeFromContents(type, option, size, widget);
+}
+
+// ----------------------------------------------------------------------------
+QRect ctkProxyStyle::subElementRect(SubElement element, const QStyleOption *option, const QWidget *widget) const
+{
+    Q_D(const ctkProxyStyle);
+    this->ensureBaseStyle();
+    return d->baseStyle->subElementRect(element, option, widget);
+}
+
+// ----------------------------------------------------------------------------
+QRect ctkProxyStyle::subControlRect(ComplexControl cc, const QStyleOptionComplex *option, SubControl sc, const QWidget *widget) const
+{
+    Q_D(const ctkProxyStyle);
+    this->ensureBaseStyle();
+    return d->baseStyle->subControlRect(cc, option, sc, widget);
+}
+
+// ----------------------------------------------------------------------------
+QRect ctkProxyStyle::itemTextRect(const QFontMetrics &fm, const QRect &r, int flags, bool enabled, const QString &text) const
+{
+    Q_D(const ctkProxyStyle);
+    this->ensureBaseStyle();
+    return d->baseStyle->itemTextRect(fm, r, flags, enabled, text);
+}
+
+// ----------------------------------------------------------------------------
+QRect ctkProxyStyle::itemPixmapRect(const QRect &r, int flags, const QPixmap &pixmap) const
+{
+    Q_D(const ctkProxyStyle);
+    this->ensureBaseStyle();
+    return d->baseStyle->itemPixmapRect(r, flags, pixmap);
+}
+
+// ----------------------------------------------------------------------------
+QStyle::SubControl ctkProxyStyle::hitTestComplexControl(ComplexControl control, const QStyleOptionComplex *option, const QPoint &pos, const QWidget *widget) const
+{
+    Q_D(const ctkProxyStyle);
+    this->ensureBaseStyle();
+    return d->baseStyle->hitTestComplexControl(control, option, pos, widget);
+}
+
+// ----------------------------------------------------------------------------
+int ctkProxyStyle::styleHint(StyleHint hint, const QStyleOption *option, const QWidget *widget, QStyleHintReturn *returnData) const
+{
+    Q_D(const ctkProxyStyle);
+    this->ensureBaseStyle();
+    return d->baseStyle->styleHint(hint, option, widget, returnData);
+}
+
+// ----------------------------------------------------------------------------
+int ctkProxyStyle::pixelMetric(PixelMetric metric, const QStyleOption *option, const QWidget *widget) const
+{
+    Q_D(const ctkProxyStyle);
+    this->ensureBaseStyle();
+    return d->baseStyle->pixelMetric(metric, option, widget);
+}
+
+// ----------------------------------------------------------------------------
+QPixmap ctkProxyStyle::standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt, const QWidget *widget) const
+{
+    Q_D(const ctkProxyStyle);
+    this->ensureBaseStyle();
+    return d->baseStyle->standardPixmap(standardPixmap, opt, widget);
+}
+
+// ----------------------------------------------------------------------------
+QPixmap ctkProxyStyle::generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap, const QStyleOption *opt) const
+{
+    Q_D(const ctkProxyStyle);
+    this->ensureBaseStyle();
+    return d->baseStyle->generatedIconPixmap(iconMode, pixmap, opt);
+}
+
+// ----------------------------------------------------------------------------
+QPalette ctkProxyStyle::standardPalette() const
+{
+    Q_D(const ctkProxyStyle);
+    this->ensureBaseStyle();
+    return d->baseStyle->standardPalette();
+}
+
+// ----------------------------------------------------------------------------
+void ctkProxyStyle::polish(QWidget *widget)
+{
+    Q_D(const ctkProxyStyle);
+    this->ensureBaseStyle();
+    d->baseStyle->polish(widget);
+}
+
+// ----------------------------------------------------------------------------
+void ctkProxyStyle::polish(QPalette &pal)
+{
+    Q_D(const ctkProxyStyle);
+    this->ensureBaseStyle();
+    d->baseStyle->polish(pal);
+}
+
+// ----------------------------------------------------------------------------
+void ctkProxyStyle::polish(QApplication *app)
+{
+    Q_D(const ctkProxyStyle);
+    this->ensureBaseStyle();
+    d->baseStyle->polish(app);
+}
+
+// ----------------------------------------------------------------------------
+void ctkProxyStyle::unpolish(QWidget *widget)
+{
+    Q_D(const ctkProxyStyle);
+    this->ensureBaseStyle();
+    d->baseStyle->unpolish(widget);
+}
+
+// ----------------------------------------------------------------------------
+void ctkProxyStyle::unpolish(QApplication *app)
+{
+    Q_D(const ctkProxyStyle);
+    this->ensureBaseStyle();
+    d->baseStyle->unpolish(app);
+}
+
+// ----------------------------------------------------------------------------
+bool ctkProxyStyle::event(QEvent *e)
+{
+    Q_D(const ctkProxyStyle);
+    if (e->type() != QEvent::ParentChange &&
+        e->type() != QEvent::ChildRemoved &&
+        e->type() != QEvent::ChildAdded)
+      {
+      this->ensureBaseStyle();
+      }
+    return !d->baseStyle.isNull() ? d->baseStyle->event(e) : false;
+}
+
+// ----------------------------------------------------------------------------
+QIcon ctkProxyStyle::standardIconImplementation(StandardPixmap standardIcon,
+                                              const QStyleOption *option,
+                                              const QWidget *widget) const
+{
+    Q_D(const ctkProxyStyle);
+    this->ensureBaseStyle();
+    return d->baseStyle->standardIcon(standardIcon, option, widget);
+}
+
+// ----------------------------------------------------------------------------
+int ctkProxyStyle::layoutSpacingImplementation(QSizePolicy::ControlType control1,
+                                             QSizePolicy::ControlType control2,
+                                             Qt::Orientation orientation,
+                                             const QStyleOption *option,
+                                             const QWidget *widget) const
+{
+    Q_D(const ctkProxyStyle);
+    this->ensureBaseStyle();
+    return d->baseStyle->layoutSpacing(control1, control2, orientation, option, widget);
+}

+ 86 - 0
Libs/Widgets/ctkProxyStyle.h

@@ -0,0 +1,86 @@
+/*=========================================================================
+
+  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 __ctkProxyStyle_h
+#define __ctkProxyStyle_h
+
+// QT includes
+#include <QProxyStyle>
+
+// CTK includes
+#include "ctkWidgetsExport.h"
+
+class ctkProxyStylePrivate;
+
+/// \ingroup Widgets
+/// ctkProxyStyle fixes some issues with QProxyStyle
+
+class CTK_WIDGETS_EXPORT ctkProxyStyle : public QProxyStyle
+{
+  Q_OBJECT
+public:
+  ctkProxyStyle(QStyle *baseStyle = 0);
+  virtual ~ctkProxyStyle();
+
+  void ensureBaseStyle()const;
+
+  virtual void drawPrimitive(PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget = 0) const;
+  virtual void drawControl(ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget = 0) const;
+  virtual void drawComplexControl(ComplexControl control, const QStyleOptionComplex *option, QPainter *painter, const QWidget *widget = 0) const;
+  virtual void drawItemText(QPainter *painter, const QRect &rect, int flags, const QPalette &pal, bool enabled,
+                            const QString &text, QPalette::ColorRole textRole = QPalette::NoRole) const;
+  virtual void drawItemPixmap(QPainter *painter, const QRect &rect, int alignment, const QPixmap &pixmap) const;
+
+  virtual QSize sizeFromContents(ContentsType type, const QStyleOption *option, const QSize &size, const QWidget *widget) const;
+
+  virtual QRect subElementRect(SubElement element, const QStyleOption *option, const QWidget *widget) const;
+  virtual QRect subControlRect(ComplexControl cc, const QStyleOptionComplex *opt, SubControl sc, const QWidget *widget) const;
+  virtual QRect itemTextRect(const QFontMetrics &fm, const QRect &r, int flags, bool enabled, const QString &text) const;
+  virtual QRect itemPixmapRect(const QRect &r, int flags, const QPixmap &pixmap) const;
+
+  virtual SubControl hitTestComplexControl(ComplexControl control, const QStyleOptionComplex *option, const QPoint &pos, const QWidget *widget = 0) const;
+  virtual int styleHint(StyleHint hint, const QStyleOption *option = 0, const QWidget *widget = 0, QStyleHintReturn *returnData = 0) const;
+  virtual int pixelMetric(PixelMetric metric, const QStyleOption *option = 0, const QWidget *widget = 0) const;
+
+  virtual QPixmap standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt, const QWidget *widget = 0) const;
+  virtual QPixmap generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap, const QStyleOption *opt) const;
+  virtual QPalette standardPalette() const;
+
+  virtual void polish(QWidget *widget);
+  virtual void polish(QPalette &pal);
+  virtual void polish(QApplication *app);
+
+  virtual void unpolish(QWidget *widget);
+  virtual void unpolish(QApplication *app);
+
+protected:
+  QScopedPointer<ctkProxyStylePrivate> d_ptr;
+  virtual bool event(QEvent *e);
+
+protected Q_SLOTS:
+  virtual QIcon standardIconImplementation(StandardPixmap standardIcon, const QStyleOption *option, const QWidget *widget) const;
+  virtual int layoutSpacingImplementation(QSizePolicy::ControlType control1, QSizePolicy::ControlType control2,
+                                  Qt::Orientation orientation, const QStyleOption *option = 0, const QWidget *widget = 0) const;
+private:
+  Q_DISABLE_COPY(ctkProxyStyle)
+  Q_DECLARE_PRIVATE(ctkProxyStyle)
+};
+
+#endif