Fixed misc nsNativeThemeQt rendering
authorpekka.vanhoja
Sat, 19 Apr 2008 19:07:29 +0300
changeset 16875 0d35a81c2f9cc76b2c059e3e7a140f3427bfe3e6
parent 16874 89a5cfa2fb9c6e9ce871d13615e71ae72e6439c8
child 16876 29cfa6ba3abc3f52da66722013713c8791df5465
push id1298
push userpavlov@mozilla.com
push dateSun, 17 Aug 2008 05:03:09 +0000
treeherderautoland@4a506fa751d8 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone2.0a1pre
Fixed misc nsNativeThemeQt rendering
widget/src/qt/nsNativeThemeQt.cpp
widget/src/qt/nsNativeThemeQt.h
--- a/widget/src/qt/nsNativeThemeQt.cpp
+++ b/widget/src/qt/nsNativeThemeQt.cpp
@@ -17,16 +17,17 @@
  * David Hyatt (hyatt@netscape.com).
  * Portions created by the Initial Developer are Copyright (C) 2001
  * the Initial Developer. All Rights Reserved.
  *
  * Contributor(s):
  *   Lars Knoll <knoll@kde.org>
  *   Zack Rusin <zack@kde.org>
  *   Tim Hill (tim@prismelite.com)
+ *   Vladimir Vukicevic <vladimir@pobox.com>
  *
  * Alternatively, the contents of this file may be used under the terms of
  * either of the GNU General Public License Version 2 or later (the "GPL"),
  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  * in which case the provisions of the GPL or the LGPL are applicable instead
  * of those above. If you wish to allow use of your version of this file only
  * under the terms of either the GPL or the LGPL, and not to allow others to
  * use your version of this file under the terms of the MPL, indicate your
@@ -70,16 +71,17 @@
 #include "gfxContext.h"
 #include "gfxQPainterSurface.h"
 #include "nsIRenderingContext.h"
 
 nsNativeThemeQt::nsNativeThemeQt()
 {
     combo = new QComboBox((QWidget *)0);
     combo->resize(0, 0);
+    mNoBackgroundPalette.setColor(QPalette::Window, Qt::transparent);
     ThemeChanged();
 }
 
 nsNativeThemeQt::~nsNativeThemeQt()
 {
     delete combo;
 }
 
@@ -96,33 +98,33 @@ static inline QRect qRectInPixels(const 
 
 NS_IMETHODIMP
 nsNativeThemeQt::DrawWidgetBackground(nsIRenderingContext* aContext,
                                       nsIFrame* aFrame,
                                       PRUint8 aWidgetType,
                                       const nsRect& aRect,
                                       const nsRect& aClipRect)
 {
-//    qDebug("%s : %d", __PRETTY_FUNCTION__, IsDisabled(aFrame));
-
     gfxContext* context = aContext->ThebesContext();
     nsRefPtr<gfxASurface> surface = context->CurrentSurface();
 
+    context->UpdateSurfaceClip();
+
     if (surface->GetType() != gfxASurface::SurfaceTypeQPainter)
         return NS_ERROR_NOT_IMPLEMENTED;
 
     gfxQPainterSurface* qSurface = (gfxQPainterSurface*) (surface.get());
     QPainter* qPainter = qSurface->GetQPainter();
 
-//     qDebug("aWidgetType = %d", aWidgetType);
-    if (!qPainter)
+    NS_ASSERTION(qPainter, "Where'd my QPainter go?");
+
+    if (qPainter == nsnull)
         return NS_OK;
 
     QStyle* style = qApp->style();
-//    const QPalette::ColorGroup cg = qApp->palette().currentColorGroup();
 
     qPainter->save();
 
     gfxPoint offs = surface->GetDeviceOffset();
     qPainter->translate(offs.x, offs.y);
 
     gfxMatrix ctm = context->CurrentMatrix();
     if (!ctm.HasNonTranslation()) {
@@ -133,185 +135,124 @@ nsNativeThemeQt::DrawWidgetBackground(ns
     QMatrix qctm(ctm.xx, ctm.xy, ctm.yx, ctm.yy, ctm.x0, ctm.y0);
     qPainter->setWorldMatrix(qctm, true);
 
     PRInt32 p2a = GetAppUnitsPerDevPixel(aContext);
 
     QRect r = qRectInPixels(aRect, p2a);
     QRect cr = qRectInPixels(aClipRect, p2a);
 
-//     qDebug("rect=%d %d %d %d\nr=%d %d %d %d",
-//         aRect.x, aRect.y, aRect.width, aRect.height,
-//         r.x(), r.y(), r.width(), r.height());
-
-    QStyle::PrimitiveElement pe = QStyle::PE_CustomBase;
-
-    QStyle::ControlElement ce = QStyle::CE_CustomBase;
-
-    QStyle::State eventFlags = QStyle::State_None;
-    /*IsDisabled(aFrame) ?
-                            QStyle::State_None :
-                            QStyle::State_Enabled;*/
-
-    PRInt32 eventState = GetContentState(aFrame, aWidgetType);
-//     qDebug("eventState = %d",  eventState);
-
-    if (eventState & NS_EVENT_STATE_HOVER) {
-//        qDebug("NS_EVENT_STATE_HOVER");
-        eventFlags |= QStyle::State_MouseOver;
-    }
-    if (eventState & NS_EVENT_STATE_FOCUS) {
-//        qDebug("NS_EVENT_STATE_FOCUS");
-        eventFlags |= QStyle::State_HasFocus;
-    }
-    if (eventState & NS_EVENT_STATE_ACTIVE) {
-//        qDebug("NS_EVENT_STATE_ACTIVE");
-        eventFlags |= QStyle::State_DownArrow;
-    }
+    QStyle::State extraFlags = QStyle::State_None;
 
     switch (aWidgetType) {
     case NS_THEME_RADIO:
-    case NS_THEME_RADIO_SMALL: {
-//        qDebug("NS_THEME_RADIO");
-
-        ce = QStyle::CE_RadioButton;
+    case NS_THEME_RADIO_SMALL: 
+    case NS_THEME_CHECKBOX:
+    case NS_THEME_CHECKBOX_SMALL: {
+        QStyleOptionButton opt;
+        InitButtonStyle (aWidgetType, aFrame, r, opt);
 
-        QStyleOptionButton option;
-
-        ButtonStyle(aFrame, r, &option, eventFlags);
-
-        style->drawControl(ce, &option, qPainter, NULL);
+        if (aWidgetType == NS_THEME_CHECKBOX ||
+            aWidgetType == NS_THEME_CHECKBOX_SMALL)
+        {
+            style->drawPrimitive (QStyle::PE_IndicatorCheckBox, &opt, qPainter);
+        } else {
+            style->drawPrimitive (QStyle::PE_IndicatorRadioButton, &opt, qPainter);
+        }
         break;
     }
-    case NS_THEME_CHECKBOX:
-    case NS_THEME_CHECKBOX_SMALL: {
-//        qDebug("NS_THEME_CHECKBOX");
-
-        ce = QStyle::CE_CheckBox;
+    case NS_THEME_BUTTON:
+    case NS_THEME_BUTTON_BEVEL: {
+        QStyleOptionButton opt;
+        InitButtonStyle (aWidgetType, aFrame, r, opt);
 
-        QStyleOptionButton option;
-
-        ButtonStyle(aFrame, r, &option, eventFlags);
-
-        style->drawControl(ce, &option, qPainter, NULL);
+        if (aWidgetType == NS_THEME_BUTTON) {
+            style->drawPrimitive(QStyle::PE_PanelButtonCommand, &opt, qPainter);
+            if (IsDefaultButton(aFrame))
+                style->drawPrimitive(QStyle::PE_FrameDefaultButton, &opt, qPainter);
+        } else {
+            style->drawPrimitive(QStyle::PE_PanelButtonBevel, &opt, qPainter);
+            style->drawPrimitive(QStyle::PE_FrameButtonBevel, &opt, qPainter);
+        }
         break;
     }
     case NS_THEME_SCROLLBAR: {
-//        qDebug("NS_THEME_SCROLLBAR");
         qPainter->fillRect(r, qApp->palette().brush(QPalette::Active, QPalette::Background));
         break;
     }
     case NS_THEME_SCROLLBAR_TRACK_HORIZONTAL: {
-//        qDebug("NS_THEME_SCROLLBAR_TRACK_HORIZONTAL");
         qPainter->fillRect(r, qApp->palette().brush(QPalette::Active, QPalette::Background));
         break;
     }
     case NS_THEME_SCROLLBAR_TRACK_VERTICAL: {
-//        qDebug("NS_THEME_SCROLLBAR_TRACK_VERTICAL");
         qPainter->fillRect(r, qApp->palette().brush(QPalette::Active, QPalette::Background));
         break;
     }
-    case NS_THEME_SCROLLBAR_BUTTON_LEFT: {
-//        qDebug("NS_THEME_SCROLLBAR_BUTTON_LEFT");
-        eventFlags |= QStyle::State_Horizontal;
-    }
-    // Fall through 
+    case NS_THEME_SCROLLBAR_BUTTON_LEFT:
+        extraFlags |= QStyle::State_Horizontal;
+        // fall through 
     case NS_THEME_SCROLLBAR_BUTTON_UP: {
-//        qDebug("NS_THEME_SCROLLBAR_BUTTON_UP");
-        
-        ce = QStyle::CE_ScrollBarSubLine;
-        
         QStyleOption option;
+        InitPlainStyle(aWidgetType, aFrame, r, option, extraFlags);
 
-        PlainStyle(aFrame, r, &option, eventFlags);
-
-        style->drawControl(ce, &option, qPainter, NULL);
+        style->drawControl(QStyle::CE_ScrollBarSubLine, &option, qPainter, NULL);
         break;
     }
-    case NS_THEME_SCROLLBAR_BUTTON_RIGHT: {
-//        qDebug("NS_THEME_SCROLLBAR_BUTTON_RIGHT");
-        eventFlags |= QStyle::State_Horizontal;
-    }
-    // Fall through 
+    case NS_THEME_SCROLLBAR_BUTTON_RIGHT:
+        extraFlags |= QStyle::State_Horizontal;
+        // fall through
     case NS_THEME_SCROLLBAR_BUTTON_DOWN: {
-//        qDebug("NS_THEME_SCROLLBAR_BUTTON_DOWN");
-        
-        ce = QStyle::CE_ScrollBarAddLine;
-        
         QStyleOption option;
+        InitPlainStyle(aWidgetType, aFrame, r, option, extraFlags);
 
-        PlainStyle(aFrame, r, &option, eventFlags);
+        style->drawControl(QStyle::CE_ScrollBarAddLine, &option, qPainter, NULL);
 
-        style->drawControl(ce, &option, qPainter, NULL);
         break;
     }
     //case NS_THEME_SCROLLBAR_GRIPPER_HORIZONTAL:
     //case NS_THEME_SCROLLBAR_GRIPPER_VERTICAL:
-    case NS_THEME_SCROLLBAR_THUMB_HORIZONTAL: {
-//        qDebug("NS_THEME_SCROLLBAR_THUMB_HORIZONTAL");
-        eventFlags |= QStyle::State_Horizontal;
-    }
-    // Fall through
+    case NS_THEME_SCROLLBAR_THUMB_HORIZONTAL:
+        extraFlags |= QStyle::State_Horizontal;
+        // fall through
     case NS_THEME_SCROLLBAR_THUMB_VERTICAL: {
-//        qDebug("NS_THEME_SCROLLBAR_THUMB_VERTICAL");
-        
-        ce = QStyle::CE_ScrollBarSlider;
-        
         QStyleOption option;
-
-        PlainStyle(aFrame, r, &option, eventFlags);
+        InitPlainStyle(aWidgetType, aFrame, r, option, extraFlags);
 
-        style->drawControl(ce, &option, qPainter, NULL);
-        break;
-    }
-    case NS_THEME_BUTTON_BEVEL:
-//        qDebug("NS_THEME_BUTTON_BEVEL");
-//         ce = QStyle::CE_PushButtonBevel;
-//         flags |= QStyle::State_Raised;
-        break;
-    case NS_THEME_BUTTON: {
-//        qDebug("NS_THEME_BUTTON %d", IsDefaultButton(aFrame));
-
-        ce = QStyle::CE_PushButton;
-
-        eventFlags |= QStyle::State_Raised;
-
-        QStyleOptionButton option;
-        
-        ButtonStyle(aFrame, r, &option, eventFlags);
-        
-        style->drawControl(ce, &option, qPainter, NULL);
-        break;
+        style->drawControl(QStyle::CE_ScrollBarSlider, &option, qPainter, NULL);
     }
     case NS_THEME_DROPDOWN:
-//        qDebug("NS_THEME_DROPDOWN");
 //        style.drawComplexControl(QStyle::CC_ComboBox, qPainter, combo, r, cg, flags, QStyle::SC_ComboBoxFrame);
         break;
     case NS_THEME_DROPDOWN_BUTTON:
-//        qDebug("NS_THEME_DROPDOWN_BUTTON");
 //         r.translate(frameWidth, -frameWidth);
 //         r.setHeight(r.height() + 2*frameWidth);
 //        style.drawComplexControl(QStyle::CC_ComboBox, qPainter, combo, r, cg, flags, QStyle::SC_ComboBoxArrow);
         break;
     case NS_THEME_DROPDOWN_TEXT:
     case NS_THEME_DROPDOWN_TEXTFIELD:
-//        qDebug("NS_THEME_DROPDOWN_TEXT");
         break;
     case NS_THEME_TEXTFIELD:
     case NS_THEME_TEXTFIELD_MULTILINE:
     case NS_THEME_LISTBOX: {
-//        qDebug("NS_THEME_TEXTFIELD");
-        
-        pe = QStyle::PE_PanelLineEdit;
+        QStyleOption panelOpt;
+        QStyleOptionFrameV2 frameOpt;
 
-        QStyleOptionFrameV2 option;
+        if (!IsDisabled(aFrame)) {
+            panelOpt.state |= QStyle::State_Enabled;
+            frameOpt.state |= QStyle::State_Enabled;
+        }
+    
+        panelOpt.rect = r;
 
-        FrameStyle(aFrame, r, &option, eventFlags);
+        frameOpt.rect = r;
+        frameOpt.features = QStyleOptionFrameV2::Flat;
+        frameOpt.palette = mNoBackgroundPalette;
 
-        style->drawPrimitive(pe, &option, qPainter, NULL);
+        style->drawPrimitive(QStyle::PE_PanelLineEdit, &panelOpt, qPainter, NULL);
+        style->drawPrimitive(QStyle::PE_FrameLineEdit, &frameOpt, qPainter, NULL);
         break;
     }
     default:
         break;
     }
 
     qPainter->restore();
     return NS_OK;
@@ -374,17 +315,17 @@ nsNativeThemeQt::GetMinimumWidgetSize(ns
     case NS_THEME_CHECKBOX_SMALL:
     case NS_THEME_CHECKBOX: {
         nsRect frameRect = aFrame->GetRect();
 
         QRect qRect = qRectInPixels(frameRect, p2a);
 
         QStyleOptionButton option;
 
-        ButtonStyle(aFrame, qRect, &option);
+        InitButtonStyle(aWidgetType, aFrame, qRect, option);
 
         QRect rect = s->subElementRect(
             (aWidgetType == NS_THEME_CHECKBOX || aWidgetType == NS_THEME_CHECKBOX_SMALL ) ?
                 QStyle::SE_CheckBoxIndicator :
                 QStyle::SE_RadioButtonIndicator,
             &option,
             NULL);
 
@@ -394,17 +335,17 @@ nsNativeThemeQt::GetMinimumWidgetSize(ns
     }
     case NS_THEME_BUTTON: {
         nsRect frameRect = aFrame->GetRect();
 
         QRect qRect = qRectInPixels(frameRect, p2a);
 
         QStyleOptionButton option;
 
-        ButtonStyle(aFrame, qRect, &option);
+        InitButtonStyle(aWidgetType, aFrame, qRect, option);
 
         QRect rect = s->subElementRect(
             QStyle::SE_PushButtonFocusRect,
             &option,
             NULL);
 
         (*aResult).width = rect.width();
         (*aResult).height = rect.height();
@@ -552,71 +493,69 @@ nsNativeThemeQt::ThemeDrawsFocusForWidge
 
 PRBool
 nsNativeThemeQt::ThemeNeedsComboboxDropmarker()
 {
 //    qDebug("%s", __PRETTY_FUNCTION__);
     return PR_FALSE;
 }
 
-
+void
+nsNativeThemeQt::InitButtonStyle(PRUint8 aWidgetType,
+                                 nsIFrame* aFrame,
+                                 QRect rect,
+                                 QStyleOptionButton &opt)
+{
+    PRInt32 eventState = GetContentState(aFrame, aWidgetType);
 
-void
-nsNativeThemeQt::ButtonStyle(nsIFrame* aFrame,
-                             QRect aRect,
-                             QStyleOptionButton* aOption,
-                             QStyle::State optFlags /*= QStyle::State_None*/)
-{
-    QStyle::State flags = IsDisabled(aFrame) ?
-        QStyle::State_None :
-        QStyle::State_Enabled;
+    opt.rect = rect;
+    opt.palette = mNoBackgroundPalette;
+
+    PRBool disabled = IsDisabled(aFrame);
 
-    flags |= IsChecked(aFrame) ?
-        QStyle::State_On :
-        QStyle::State_Off;
-
-    flags |= optFlags;
+    if (!disabled)
+        opt.state |= QStyle::State_Enabled;
+    if (eventState & NS_EVENT_STATE_HOVER)
+        opt.state |= QStyle::State_MouseOver;
+    if (eventState & NS_EVENT_STATE_FOCUS)
+        opt.state |= QStyle::State_HasFocus;
+    if (!disabled && eventState & NS_EVENT_STATE_ACTIVE)
+        // Don't allow sunken when disabled
+        opt.state |= QStyle::State_Sunken;
 
-    (*aOption).direction = QApplication::layoutDirection();
-    (*aOption).rect = aRect;
-    (*aOption).type = QStyleOption::SO_Button;
-    (*aOption).state = flags;
-    (*aOption).features = QStyleOptionButton::None;
+    switch (aWidgetType) {
+    case NS_THEME_RADIO:
+    case NS_THEME_RADIO_SMALL:
+    case NS_THEME_CHECKBOX:
+    case NS_THEME_CHECKBOX_SMALL:
+        if (IsChecked(aFrame))
+            opt.state |= QStyle::State_On;
+        else
+            opt.state |= QStyle::State_Off;
+
+        break;
+    default:
+        if (!(eventState & NS_EVENT_STATE_ACTIVE))
+            opt.state |= QStyle::State_Raised;
+        break;
+    }
 }
 
 void
-nsNativeThemeQt::FrameStyle(nsIFrame* aFrame,
-                            QRect aRect,
-                            QStyleOptionFrameV2* aOption,
-                            QStyle::State optFlags /*= QStyle::State_None*/)
+nsNativeThemeQt::InitPlainStyle(PRUint8 aWidgetType,
+                                nsIFrame* aFrame,
+                                QRect rect,
+                                QStyleOption &opt,
+                                QStyle::State extraFlags)
 {
-    QStyle::State flags = IsDisabled(aFrame) ?
-        QStyle::State_None :
-        QStyle::State_Enabled;
-    
-    flags |= optFlags;
+    PRInt32 eventState = GetContentState(aFrame, aWidgetType);
+
+    opt.rect = rect;
 
-    (*aOption).direction = QApplication::layoutDirection();
-    (*aOption).rect = aRect;
-    (*aOption).type = QStyleOption::SO_Frame;
-    (*aOption).state = flags;
-    (*aOption).lineWidth = 1;
-    (*aOption).midLineWidth = 1;
-    (*aOption).features = QStyleOptionFrameV2::Flat;
+    if (!IsDisabled(aFrame))
+        opt.state |= QStyle::State_Enabled;
+    if (eventState & NS_EVENT_STATE_HOVER)
+        opt.state |= QStyle::State_MouseOver;
+    if (eventState & NS_EVENT_STATE_FOCUS)
+        opt.state |= QStyle::State_HasFocus;
+
+    opt.state |= extraFlags;
 }
-
-void
-nsNativeThemeQt::PlainStyle(nsIFrame* aFrame,
-                            QRect aRect,
-                            QStyleOption* aOption,
-                            QStyle::State optFlags /*= QStyle::State_None*/)
-{
-    QStyle::State flags = IsDisabled(aFrame) ?
-        QStyle::State_None :
-        QStyle::State_Enabled;
-    
-    flags |= optFlags;
-
-    (*aOption).direction = QApplication::layoutDirection();
-    (*aOption).rect = aRect;
-    (*aOption).type = QStyleOption::SO_Default;
-    (*aOption).state = flags;
-}
--- a/widget/src/qt/nsNativeThemeQt.h
+++ b/widget/src/qt/nsNativeThemeQt.h
@@ -35,16 +35,17 @@
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include <QStyle>
+#include <QPalette>
 
 #include "nsITheme.h"
 #include "nsCOMPtr.h"
 #include "nsIAtom.h"
 #include "nsNativeTheme.h"
 #include "nsIDeviceContext.h"
 
 class QComboBox;
@@ -103,31 +104,28 @@ public:
 private:
 
   inline PRInt32 GetAppUnitsPerDevPixel(nsIRenderingContext* aContext){
     nsCOMPtr<nsIDeviceContext> dctx = nsnull;
     aContext->GetDeviceContext(*getter_AddRefs(dctx));
     return dctx->AppUnitsPerDevPixel();
   }
 
-  void ButtonStyle(nsIFrame* aFrame,
-                   QRect aRect,
-                   QStyleOptionButton* aOption,
-                   QStyle::State optFlags = QStyle::State_None);
+  void InitButtonStyle(PRUint8 widgetType,
+                       nsIFrame* aFrame,
+                       QRect rect,
+                       QStyleOptionButton &opt);
 
-  void FrameStyle(nsIFrame* aFrame,
-                  QRect aRect,
-                  QStyleOptionFrameV2* aOption,
-                  QStyle::State optFlags = QStyle::State_None);
-
-  void PlainStyle(nsIFrame* aFrame,
-                  QRect aRect,
-                  QStyleOption* aOption,
-                  QStyle::State optFlags = QStyle::State_None);
+  void InitPlainStyle(PRUint8 aWidgetType,
+                      nsIFrame* aFrame,
+                      QRect rect,
+                      QStyleOption &opt,
+                      QStyle::State extraFlags = QStyle::State_None);
 
 private:
 
   QComboBox *combo;
 
   PRInt32 frameWidth;
 
+  QPalette mNoBackgroundPalette;
 };