summaryrefslogtreecommitdiffstats
path: root/WebCore/platform/qt/RenderThemeQt.cpp
diff options
context:
space:
mode:
authorUpstream <upstream-import@none>1970-01-12 13:46:40 +0000
committerUpstream <upstream-import@none>1970-01-12 13:46:40 +0000
commitd8543bb6618c17b12da906afa77d216f58cf4058 (patch)
treec58dc05ed86825bd0ef8d305d58c8205106b540f /WebCore/platform/qt/RenderThemeQt.cpp
downloadexternal_webkit-d8543bb6618c17b12da906afa77d216f58cf4058.zip
external_webkit-d8543bb6618c17b12da906afa77d216f58cf4058.tar.gz
external_webkit-d8543bb6618c17b12da906afa77d216f58cf4058.tar.bz2
external/webkit r30707
Diffstat (limited to 'WebCore/platform/qt/RenderThemeQt.cpp')
-rw-r--r--WebCore/platform/qt/RenderThemeQt.cpp593
1 files changed, 593 insertions, 0 deletions
diff --git a/WebCore/platform/qt/RenderThemeQt.cpp b/WebCore/platform/qt/RenderThemeQt.cpp
new file mode 100644
index 0000000..d17d6b5
--- /dev/null
+++ b/WebCore/platform/qt/RenderThemeQt.cpp
@@ -0,0 +1,593 @@
+/*
+ * This file is part of the WebKit project.
+ *
+ * Copyright (C) 2006 Zack Rusin <zack@kde.org>
+ * 2006 Dirk Mueller <mueller@kde.org>
+ * 2006 Nikolas Zimmermann <zimmermann@kde.org>
+ *
+ * All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+
+#include "qwebpage.h"
+#include "RenderThemeQt.h"
+#include "ChromeClientQt.h"
+#include "NotImplemented.h"
+
+#include <QApplication>
+#include <QColor>
+#include <QDebug>
+#include <QStyle>
+#include <QWidget>
+#include <QPainter>
+#include <QStyleOptionButton>
+#include <QStyleOptionFrameV2>
+
+#include "Color.h"
+#include "Document.h"
+#include "Page.h"
+#include "Font.h"
+#include "RenderTheme.h"
+#include "GraphicsContext.h"
+
+namespace WebCore {
+
+RenderTheme* theme()
+{
+ static RenderThemeQt rt;
+ return &rt;
+}
+
+RenderThemeQt::RenderThemeQt()
+ : RenderTheme()
+{
+}
+
+bool RenderThemeQt::supportsHover(const RenderStyle*) const
+{
+ return true;
+}
+
+bool RenderThemeQt::supportsFocusRing(const RenderStyle* style) const
+{
+ return supportsFocus(style->appearance());
+}
+
+short RenderThemeQt::baselinePosition(const RenderObject* o) const
+{
+ if (o->style()->appearance() == CheckboxAppearance ||
+ o->style()->appearance() == RadioAppearance)
+ return o->marginTop() + o->height() - 2; // Same as in old khtml
+ return RenderTheme::baselinePosition(o);
+}
+
+bool RenderThemeQt::controlSupportsTints(const RenderObject* o) const
+{
+ if (!isEnabled(o))
+ return false;
+
+ // Checkboxes only have tint when checked.
+ if (o->style()->appearance() == CheckboxAppearance)
+ return isChecked(o);
+
+ // For now assume other controls have tint if enabled.
+ return true;
+}
+
+bool RenderThemeQt::supportsControlTints() const
+{
+ return true;
+}
+
+void RenderThemeQt::adjustRepaintRect(const RenderObject* o, IntRect& r)
+{
+ switch (o->style()->appearance()) {
+ case CheckboxAppearance: {
+ break;
+ }
+ case RadioAppearance: {
+ break;
+ }
+ case PushButtonAppearance:
+ case ButtonAppearance: {
+ break;
+ }
+ case MenulistAppearance: {
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+bool RenderThemeQt::isControlStyled(const RenderStyle* style, const BorderData& border,
+ const BackgroundLayer& background, const Color& backgroundColor) const
+{
+ if (style->appearance() == TextFieldAppearance || style->appearance() == TextAreaAppearance)
+ return style->border() != border;
+
+ return RenderTheme::isControlStyled(style, border, background, backgroundColor);
+}
+
+Color RenderThemeQt::platformActiveSelectionBackgroundColor() const
+{
+ QPalette pal = QApplication::palette();
+ return pal.brush(QPalette::Active, QPalette::Highlight).color();
+}
+
+Color RenderThemeQt::platformInactiveSelectionBackgroundColor() const
+{
+ QPalette pal = QApplication::palette();
+ return pal.brush(QPalette::Inactive, QPalette::Highlight).color();
+}
+
+Color RenderThemeQt::platformActiveSelectionForegroundColor() const
+{
+ QPalette pal = QApplication::palette();
+ return pal.brush(QPalette::Active, QPalette::HighlightedText).color();
+}
+
+Color RenderThemeQt::platformInactiveSelectionForegroundColor() const
+{
+ QPalette pal = QApplication::palette();
+ return pal.brush(QPalette::Inactive, QPalette::HighlightedText).color();
+}
+
+void RenderThemeQt::systemFont(int propId, FontDescription& fontDescription) const
+{
+ // no-op
+}
+
+int RenderThemeQt::minimumMenuListSize(RenderStyle*) const
+{
+ const QFontMetrics &fm = QApplication::fontMetrics();
+ return 7 * fm.width(QLatin1Char('x'));
+}
+
+void RenderThemeQt::adjustSliderThumbSize(RenderObject* o) const
+{
+ RenderTheme::adjustSliderThumbSize(o);
+}
+
+bool RenderThemeQt::paintCheckbox(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r)
+{
+ return paintButton(o, i, r);
+}
+
+void RenderThemeQt::setCheckboxSize(RenderStyle* style) const
+{
+ // If the width and height are both specified, then we have nothing to do.
+ if (!style->width().isIntrinsicOrAuto() && !style->height().isAuto())
+ return;
+
+ // FIXME: A hard-coded size of 13 is used. This is wrong but necessary for now. It matches Firefox.
+ // At different DPI settings on Windows, querying the theme gives you a larger size that accounts for
+ // the higher DPI. Until our entire engine honors a DPI setting other than 96, we can't rely on the theme's
+ // metrics.
+ const int ff = 13;
+ if (style->width().isIntrinsicOrAuto())
+ style->setWidth(Length(ff, Fixed));
+
+ if (style->height().isAuto())
+ style->setHeight(Length(ff, Fixed));
+}
+
+bool RenderThemeQt::paintRadio(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r)
+{
+ return paintButton(o, i, r);
+}
+
+void RenderThemeQt::setRadioSize(RenderStyle* style) const
+{
+ // This is the same as checkboxes.
+ setCheckboxSize(style);
+}
+
+void RenderThemeQt::adjustButtonStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const
+{
+ // Ditch the border.
+ style->resetBorder();
+
+ // Height is locked to auto.
+ style->setHeight(Length(Auto));
+
+ // White-space is locked to pre
+ style->setWhiteSpace(PRE);
+
+ setButtonSize(style);
+
+ setButtonPadding(style);
+}
+
+bool RenderThemeQt::paintButton(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r)
+{
+ QStyle* style = 0;
+ QPainter* painter = 0;
+ QWidget* widget = 0;
+
+ if (!getStylePainterAndWidgetFromPaintInfo(i, style, painter, widget))
+ return true;
+
+ QStyleOptionButton option;
+ if (widget)
+ option.initFrom(widget);
+ option.rect = r;
+
+ // Get the correct theme data for a button
+ EAppearance appearance = applyTheme(option, o);
+
+ if(appearance == PushButtonAppearance || appearance == ButtonAppearance)
+ style->drawControl(QStyle::CE_PushButton, &option, painter);
+ else if(appearance == RadioAppearance)
+ style->drawPrimitive(QStyle::PE_IndicatorRadioButton, &option, painter, widget);
+ else if(appearance == CheckboxAppearance)
+ style->drawPrimitive(QStyle::PE_IndicatorCheckBox, &option, painter, widget);
+
+ return false;
+}
+
+void RenderThemeQt::setButtonSize(RenderStyle* style) const
+{
+ setPrimitiveSize(style);
+}
+
+bool RenderThemeQt::paintTextField(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r)
+{
+ QStyle* style = 0;
+ QPainter* painter = 0;
+ QWidget* widget = 0;
+
+ if (!getStylePainterAndWidgetFromPaintInfo(i, style, painter, widget))
+ return true;
+
+ QStyleOptionFrameV2 panel;
+ if (widget)
+ panel.initFrom(widget);
+ panel.rect = r;
+ panel.state |= QStyle::State_Sunken;
+ panel.features = QStyleOptionFrameV2::None;
+
+ // Get the correct theme data for a button
+ EAppearance appearance = applyTheme(panel, o);
+ Q_ASSERT(appearance == TextFieldAppearance || appearance == SearchFieldAppearance);
+
+ // Now paint the text field.
+ style->drawPrimitive(QStyle::PE_PanelLineEdit, &panel, painter, widget);
+ style->drawPrimitive(QStyle::PE_FrameLineEdit, &panel, painter, widget);
+
+ return false;
+}
+
+void RenderThemeQt::adjustTextFieldStyle(CSSStyleSelector*, RenderStyle* style, Element*) const
+{
+}
+
+void RenderThemeQt::adjustMenuListStyle(CSSStyleSelector*, RenderStyle* style, Element*) const
+{
+ style->resetBorder();
+
+ // Height is locked to auto.
+ style->setHeight(Length(Auto));
+
+ // White-space is locked to pre
+ style->setWhiteSpace(PRE);
+
+ setPrimitiveSize(style);
+
+ // Add in the padding that we'd like to use.
+ setPopupPadding(style);
+
+ // Our font is locked to the appropriate system font size for the control. To clarify, we first use the CSS-specified font to figure out
+ // a reasonable control size, but once that control size is determined, we throw that font away and use the appropriate
+ // system font for the control size instead.
+ //setFontFromControlSize(selector, style);
+}
+
+bool RenderThemeQt::paintMenuList(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r)
+{
+ QStyle* style = 0;
+ QPainter* painter = 0;
+ QWidget* widget = 0;
+
+ if (!getStylePainterAndWidgetFromPaintInfo(i, style, painter, widget))
+ return true;
+
+ QStyleOptionComboBox opt;
+ if (widget)
+ opt.initFrom(widget);
+ EAppearance appearance = applyTheme(opt, o);
+ const QPoint topLeft = r.topLeft();
+ painter->translate(topLeft);
+ opt.rect.moveTo(QPoint(0,0));
+ opt.rect.setSize(r.size());
+
+ opt.frame = false;
+
+ style->drawComplexControl(QStyle::CC_ComboBox, &opt, painter, widget);
+ painter->translate(-topLeft);
+ return false;
+}
+
+
+bool RenderThemeQt::paintMenuListButton(RenderObject* o, const RenderObject::PaintInfo& pi,
+ const IntRect& r)
+{
+ notImplemented();
+ return RenderTheme::paintMenuListButton(o, pi, r);
+}
+
+void RenderThemeQt::adjustMenuListButtonStyle(CSSStyleSelector* selector, RenderStyle* style,
+ Element* e) const
+{
+ notImplemented();
+ RenderTheme::adjustMenuListButtonStyle(selector, style, e);
+}
+
+bool RenderThemeQt::paintSliderTrack(RenderObject* o, const RenderObject::PaintInfo& pi,
+ const IntRect& r)
+{
+ notImplemented();
+ return RenderTheme::paintSliderTrack(o, pi, r);
+}
+
+bool RenderThemeQt::paintSliderThumb(RenderObject* o, const RenderObject::PaintInfo& pi,
+ const IntRect& r)
+{
+ notImplemented();
+ return RenderTheme::paintSliderThumb(o, pi, r);
+}
+
+bool RenderThemeQt::paintSearchField(RenderObject* o, const RenderObject::PaintInfo& pi,
+ const IntRect& r)
+{
+ paintTextField(o, pi, r);
+ return false;
+}
+
+void RenderThemeQt::adjustSearchFieldStyle(CSSStyleSelector* selector, RenderStyle* style,
+ Element* e) const
+{
+ notImplemented();
+ RenderTheme::adjustSearchFieldStyle(selector, style, e);
+}
+
+void RenderThemeQt::adjustSearchFieldCancelButtonStyle(CSSStyleSelector* selector, RenderStyle* style,
+ Element* e) const
+{
+ notImplemented();
+ RenderTheme::adjustSearchFieldCancelButtonStyle(selector, style, e);
+}
+
+bool RenderThemeQt::paintSearchFieldCancelButton(RenderObject* o, const RenderObject::PaintInfo& pi,
+ const IntRect& r)
+{
+ notImplemented();
+ return RenderTheme::paintSearchFieldCancelButton(o, pi, r);
+}
+
+void RenderThemeQt::adjustSearchFieldDecorationStyle(CSSStyleSelector* selector, RenderStyle* style,
+ Element* e) const
+{
+ notImplemented();
+ RenderTheme::adjustSearchFieldDecorationStyle(selector, style, e);
+}
+
+bool RenderThemeQt::paintSearchFieldDecoration(RenderObject* o, const RenderObject::PaintInfo& pi,
+ const IntRect& r)
+{
+ notImplemented();
+ return RenderTheme::paintSearchFieldDecoration(o, pi, r);
+}
+
+void RenderThemeQt::adjustSearchFieldResultsDecorationStyle(CSSStyleSelector* selector, RenderStyle* style,
+ Element* e) const
+{
+ notImplemented();
+ RenderTheme::adjustSearchFieldResultsDecorationStyle(selector, style, e);
+}
+
+bool RenderThemeQt::paintSearchFieldResultsDecoration(RenderObject* o, const RenderObject::PaintInfo& pi,
+ const IntRect& r)
+{
+ notImplemented();
+ return RenderTheme::paintSearchFieldResultsDecoration(o, pi, r);
+}
+
+bool RenderThemeQt::supportsFocus(EAppearance appearance) const
+{
+ switch (appearance) {
+ case PushButtonAppearance:
+ case ButtonAppearance:
+ case TextFieldAppearance:
+ case MenulistAppearance:
+ case RadioAppearance:
+ case CheckboxAppearance:
+ return true;
+ default: // No for all others...
+ return false;
+ }
+}
+
+bool RenderThemeQt::getStylePainterAndWidgetFromPaintInfo(const RenderObject::PaintInfo& i, QStyle*& style,
+ QPainter*& painter, QWidget*& widget) const
+{
+ painter = (i.context ? static_cast<QPainter*>(i.context->platformContext()) : 0);
+ widget = 0;
+ QPaintDevice* dev = 0;
+ if (painter)
+ dev = painter->device();
+ if (dev && dev->devType() == QInternal::Widget)
+ widget = static_cast<QWidget*>(dev);
+ style = (widget ? widget->style() : QApplication::style());
+
+ return (painter && style);
+}
+
+EAppearance RenderThemeQt::applyTheme(QStyleOption& option, RenderObject* o) const
+{
+ // Default bits: no focus, no mouse over
+ option.state &= ~(QStyle::State_HasFocus | QStyle::State_MouseOver);
+
+ if (!isEnabled(o))
+ option.state &= ~QStyle::State_Enabled;
+
+ if (isReadOnlyControl(o))
+ // Readonly is supported on textfields.
+ option.state |= QStyle::State_ReadOnly;
+
+ if (supportsFocus(o->style()->appearance()) && isFocused(o))
+ option.state |= QStyle::State_HasFocus;
+
+ if (isHovered(o))
+ option.state |= QStyle::State_MouseOver;
+
+ EAppearance result = o->style()->appearance();
+
+ switch (result) {
+ case PushButtonAppearance:
+ case SquareButtonAppearance:
+ case ButtonAppearance:
+ case ButtonBevelAppearance:
+ case ListItemAppearance:
+ case MenulistButtonAppearance:
+ case ScrollbarButtonLeftAppearance:
+ case ScrollbarButtonRightAppearance:
+ case ScrollbarTrackHorizontalAppearance:
+ case ScrollbarTrackVerticalAppearance:
+ case ScrollbarThumbHorizontalAppearance:
+ case ScrollbarThumbVerticalAppearance:
+ case SearchFieldResultsButtonAppearance:
+ case SearchFieldCancelButtonAppearance: {
+ if (isPressed(o))
+ option.state |= QStyle::State_Sunken;
+ else if (result == PushButtonAppearance)
+ option.state |= QStyle::State_Raised;
+ break;
+ }
+ }
+
+ if(result == RadioAppearance || result == CheckboxAppearance)
+ option.state |= (isChecked(o) ? QStyle::State_On : QStyle::State_Off);
+
+ // If the webview has a custom palette, use it
+ Page* page = o->document()->page();
+ if (page) {
+ QWidget* view = static_cast<ChromeClientQt*>(page->chrome()->client())->m_webPage->view();
+ if (view)
+ option.palette = view->palette();
+ }
+
+ return result;
+}
+
+void RenderThemeQt::setSizeFromFont(RenderStyle* style) const
+{
+ // FIXME: Check is flawed, since it doesn't take min-width/max-width into account.
+ IntSize size = sizeForFont(style);
+ if (style->width().isIntrinsicOrAuto() && size.width() > 0)
+ style->setWidth(Length(size.width(), Fixed));
+ if (style->height().isAuto() && size.height() > 0)
+ style->setHeight(Length(size.height(), Fixed));
+}
+
+IntSize RenderThemeQt::sizeForFont(RenderStyle* style) const
+{
+ const QFontMetrics fm(style->font().font());
+ QSize size(0, 0);
+ switch (style->appearance()) {
+ case CheckboxAppearance: {
+ break;
+ }
+ case RadioAppearance: {
+ break;
+ }
+ case PushButtonAppearance:
+ case ButtonAppearance: {
+ QSize sz = fm.size(Qt::TextShowMnemonic, QString::fromLatin1("X"));
+ QStyleOptionButton opt;
+ sz = QApplication::style()->sizeFromContents(QStyle::CT_PushButton,
+ &opt, sz, 0);
+ size.setHeight(sz.height());
+ break;
+ }
+ case MenulistAppearance: {
+ QSize sz;
+ sz.setHeight(qMax(fm.lineSpacing(), 14) + 2);
+ QStyleOptionComboBox opt;
+ sz = QApplication::style()->sizeFromContents(QStyle::CT_ComboBox,
+ &opt, sz, 0);
+ size.setHeight(sz.height());
+ break;
+ }
+ case TextFieldAppearance: {
+ const int verticalMargin = 1;
+ const int horizontalMargin = 2;
+ int h = qMax(fm.lineSpacing(), 14) + 2*verticalMargin;
+ int w = fm.width(QLatin1Char('x')) * 17 + 2*horizontalMargin;
+ QStyleOptionFrameV2 opt;
+ opt.lineWidth = QApplication::style()->pixelMetric(QStyle::PM_DefaultFrameWidth,
+ &opt, 0);
+ QSize sz = QApplication::style()->sizeFromContents(QStyle::CT_LineEdit,
+ &opt,
+ QSize(w, h).expandedTo(QApplication::globalStrut()),
+ 0);
+ size.setHeight(sz.height());
+ break;
+ }
+ default:
+ break;
+ }
+ return size;
+}
+
+void RenderThemeQt::setButtonPadding(RenderStyle* style) const
+{
+ const int padding = 8;
+ style->setPaddingLeft(Length(padding, Fixed));
+ style->setPaddingRight(Length(padding, Fixed));
+ style->setPaddingTop(Length(0, Fixed));
+ style->setPaddingBottom(Length(0, Fixed));
+}
+
+void RenderThemeQt::setPopupPadding(RenderStyle* style) const
+{
+ const int padding = 8;
+ style->setPaddingLeft(Length(padding, Fixed));
+ QStyleOptionComboBox opt;
+ int w = QApplication::style()->pixelMetric(QStyle::PM_ButtonIconSize, &opt, 0);
+ style->setPaddingRight(Length(padding + w, Fixed));
+
+ style->setPaddingTop(Length(1, Fixed));
+ style->setPaddingBottom(Length(0, Fixed));
+}
+
+void RenderThemeQt::setPrimitiveSize(RenderStyle* style) const
+{
+ // If the width and height are both specified, then we have nothing to do.
+ if (!style->width().isIntrinsicOrAuto() && !style->height().isAuto())
+ return;
+
+ // Use the font size to determine the intrinsic width of the control.
+ setSizeFromFont(style);
+}
+
+}
+
+// vim: ts=4 sw=4 et