diff options
author | Upstream <upstream-import@none> | 1970-01-12 13:46:40 +0000 |
---|---|---|
committer | Upstream <upstream-import@none> | 1970-01-12 13:46:40 +0000 |
commit | d8543bb6618c17b12da906afa77d216f58cf4058 (patch) | |
tree | c58dc05ed86825bd0ef8d305d58c8205106b540f /WebCore/platform/qt/RenderThemeQt.cpp | |
download | external_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.cpp | 593 |
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 |