📄 rendertheme.cpp
字号:
/** * This file is part of the theme implementation for form controls in WebCore. * * Copyright (C) 2005, 2006, 2007, 2008 Apple Computer, Inc. * * 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 "RenderTheme.h"#include "CSSValueKeywords.h"#include "Document.h"#include "FocusController.h"#include "FontSelector.h"#include "Frame.h"#include "GraphicsContext.h"#include "HTMLInputElement.h"#include "HTMLNames.h"#include "Page.h"#include "RenderStyle.h"#include "RenderView.h"#include "SelectionController.h"#include "Settings.h"// The methods in this file are shared by all themes on every platform.namespace WebCore {using namespace HTMLNames;RenderTheme::RenderTheme()#if USE(NEW_THEME) : m_theme(platformTheme())#endif{}void RenderTheme::adjustStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e, bool UAHasAppearance, const BorderData& border, const FillLayer& background, const Color& backgroundColor){ // Force inline and table display styles to be inline-block (except for table- which is block) ControlPart part = style->appearance(); if (style->display() == INLINE || style->display() == INLINE_TABLE || style->display() == TABLE_ROW_GROUP || style->display() == TABLE_HEADER_GROUP || style->display() == TABLE_FOOTER_GROUP || style->display() == TABLE_ROW || style->display() == TABLE_COLUMN_GROUP || style->display() == TABLE_COLUMN || style->display() == TABLE_CELL || style->display() == TABLE_CAPTION) style->setDisplay(INLINE_BLOCK); else if (style->display() == COMPACT || style->display() == RUN_IN || style->display() == LIST_ITEM || style->display() == TABLE) style->setDisplay(BLOCK); if (UAHasAppearance && theme()->isControlStyled(style, border, background, backgroundColor)) { if (part == MenulistPart) { style->setAppearance(MenulistButtonPart); part = MenulistButtonPart; } else style->setAppearance(NoControlPart); } if (!style->hasAppearance()) return; // Never support box-shadow on native controls. style->setBoxShadow(0); #if USE(NEW_THEME) switch (part) { case CheckboxPart: case RadioPart: case PushButtonPart: case SquareButtonPart: case DefaultButtonPart: case ButtonPart: { // Border LengthBox borderBox(style->borderTopWidth(), style->borderRightWidth(), style->borderBottomWidth(), style->borderLeftWidth()); borderBox = m_theme->controlBorder(part, style->font(), borderBox, style->effectiveZoom()); if (borderBox.top().value() != style->borderTopWidth()) { if (borderBox.top().value()) style->setBorderTopWidth(borderBox.top().value()); else style->resetBorderTop(); } if (borderBox.right().value() != style->borderRightWidth()) { if (borderBox.right().value()) style->setBorderRightWidth(borderBox.right().value()); else style->resetBorderRight(); } if (borderBox.bottom().value() != style->borderBottomWidth()) { style->setBorderBottomWidth(borderBox.bottom().value()); if (borderBox.bottom().value()) style->setBorderBottomWidth(borderBox.bottom().value()); else style->resetBorderBottom(); } if (borderBox.left().value() != style->borderLeftWidth()) { style->setBorderLeftWidth(borderBox.left().value()); if (borderBox.left().value()) style->setBorderLeftWidth(borderBox.left().value()); else style->resetBorderLeft(); } // Padding LengthBox paddingBox = m_theme->controlPadding(part, style->font(), style->paddingBox(), style->effectiveZoom()); if (paddingBox != style->paddingBox()) style->setPaddingBox(paddingBox); // Whitespace if (m_theme->controlRequiresPreWhiteSpace(part)) style->setWhiteSpace(PRE); // Width / Height // The width and height here are affected by the zoom. // FIXME: Check is flawed, since it doesn't take min-width/max-width into account. LengthSize controlSize = m_theme->controlSize(part, style->font(), LengthSize(style->width(), style->height()), style->effectiveZoom()); if (controlSize.width() != style->width()) style->setWidth(controlSize.width()); if (controlSize.height() != style->height()) style->setHeight(controlSize.height()); // Min-Width / Min-Height LengthSize minControlSize = m_theme->minimumControlSize(part, style->font(), style->effectiveZoom()); if (minControlSize.width() != style->minWidth()) style->setMinWidth(minControlSize.width()); if (minControlSize.height() != style->minHeight()) style->setMinHeight(minControlSize.height()); // Font FontDescription controlFont = m_theme->controlFont(part, style->font(), style->effectiveZoom()); if (controlFont != style->font().fontDescription()) { // Reset our line-height style->setLineHeight(RenderStyle::initialLineHeight()); // Now update our font. if (style->setFontDescription(controlFont)) style->font().update(0); } } default: break; }#endif // Call the appropriate style adjustment method based off the appearance value. switch (style->appearance()) {#if !USE(NEW_THEME) case CheckboxPart: return adjustCheckboxStyle(selector, style, e); case RadioPart: return adjustRadioStyle(selector, style, e); case PushButtonPart: case SquareButtonPart: case DefaultButtonPart: case ButtonPart: return adjustButtonStyle(selector, style, e);#endif case TextFieldPart: return adjustTextFieldStyle(selector, style, e); case TextAreaPart: return adjustTextAreaStyle(selector, style, e); case MenulistPart: return adjustMenuListStyle(selector, style, e); case MenulistButtonPart: return adjustMenuListButtonStyle(selector, style, e); case MediaSliderPart: case SliderHorizontalPart: case SliderVerticalPart: return adjustSliderTrackStyle(selector, style, e); case SliderThumbHorizontalPart: case SliderThumbVerticalPart: return adjustSliderThumbStyle(selector, style, e); case SearchFieldPart: return adjustSearchFieldStyle(selector, style, e); case SearchFieldCancelButtonPart: return adjustSearchFieldCancelButtonStyle(selector, style, e); case SearchFieldDecorationPart: return adjustSearchFieldDecorationStyle(selector, style, e); case SearchFieldResultsDecorationPart: return adjustSearchFieldResultsDecorationStyle(selector, style, e); case SearchFieldResultsButtonPart: return adjustSearchFieldResultsButtonStyle(selector, style, e); default: break; }}bool RenderTheme::paint(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r){ // If painting is disabled, but we aren't updating control tints, then just bail. // If we are updating control tints, just schedule a repaint if the theme supports tinting // for that control. if (paintInfo.context->updatingControlTints()) { if (controlSupportsTints(o)) o->repaint(); return false; } if (paintInfo.context->paintingDisabled()) return false; ControlPart part = o->style()->appearance();#if USE(NEW_THEME) switch (part) { case CheckboxPart: case RadioPart: case PushButtonPart: case SquareButtonPart: case DefaultButtonPart: case ButtonPart: m_theme->paint(part, controlStatesForRenderer(o), const_cast<GraphicsContext*>(paintInfo.context), r, o->style()->effectiveZoom(), o->view()->frameView()); return false; default: break; }#endif // Call the appropriate paint method based off the appearance value. switch (part) {#if !USE(NEW_THEME) case CheckboxPart: return paintCheckbox(o, paintInfo, r); case RadioPart: return paintRadio(o, paintInfo, r); case PushButtonPart: case SquareButtonPart: case DefaultButtonPart: case ButtonPart: return paintButton(o, paintInfo, r);#endif case MenulistPart: return paintMenuList(o, paintInfo, r); case SliderHorizontalPart: case SliderVerticalPart: return paintSliderTrack(o, paintInfo, r); case SliderThumbHorizontalPart: case SliderThumbVerticalPart: if (o->parent()->isSlider()) return paintSliderThumb(o, paintInfo, r); // We don't support drawing a slider thumb without a parent slider break; case MediaFullscreenButtonPart: return paintMediaFullscreenButton(o, paintInfo, r); case MediaPlayButtonPart: return paintMediaPlayButton(o, paintInfo, r); case MediaMuteButtonPart: return paintMediaMuteButton(o, paintInfo, r); case MediaSeekBackButtonPart: return paintMediaSeekBackButton(o, paintInfo, r); case MediaSeekForwardButtonPart: return paintMediaSeekForwardButton(o, paintInfo, r); case MediaSliderPart: return paintMediaSliderTrack(o, paintInfo, r); case MediaSliderThumbPart: if (o->parent()->isSlider()) return paintMediaSliderThumb(o, paintInfo, r); break; case MediaTimeRemainingPart: return paintMediaTimeRemaining(o, paintInfo, r); case MediaCurrentTimePart: return paintMediaCurrentTime(o, paintInfo, r); case MediaTimelineContainerPart: return paintMediaTimelineContainer(o, paintInfo, r); case MenulistButtonPart: case TextFieldPart: case TextAreaPart: case ListboxPart: return true; case SearchFieldPart: return paintSearchField(o, paintInfo, r); case SearchFieldCancelButtonPart: return paintSearchFieldCancelButton(o, paintInfo, r); case SearchFieldDecorationPart: return paintSearchFieldDecoration(o, paintInfo, r); case SearchFieldResultsDecorationPart: return paintSearchFieldResultsDecoration(o, paintInfo, r); case SearchFieldResultsButtonPart: return paintSearchFieldResultsButton(o, paintInfo, r); default: break; } return true; // We don't support the appearance, so let the normal background/border paint.}bool RenderTheme::paintBorderOnly(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r){ if (paintInfo.context->paintingDisabled()) return false; // Call the appropriate paint method based off the appearance value. switch (o->style()->appearance()) { case TextFieldPart: return paintTextField(o, paintInfo, r); case ListboxPart: case TextAreaPart: return paintTextArea(o, paintInfo, r); case MenulistButtonPart: return true; case CheckboxPart: case RadioPart: case PushButtonPart: case SquareButtonPart: case DefaultButtonPart: case ButtonPart: case MenulistPart: case SliderHorizontalPart: case SliderVerticalPart: case SliderThumbHorizontalPart: case SliderThumbVerticalPart: case SearchFieldPart: case SearchFieldCancelButtonPart: case SearchFieldDecorationPart: case SearchFieldResultsDecorationPart: case SearchFieldResultsButtonPart: default: break; } return false;}bool RenderTheme::paintDecorations(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r){ if (paintInfo.context->paintingDisabled()) return false; // Call the appropriate paint method based off the appearance value. switch (o->style()->appearance()) { case MenulistButtonPart: return paintMenuListButton(o, paintInfo, r); case TextFieldPart: case TextAreaPart: case ListboxPart: case CheckboxPart: case RadioPart: case PushButtonPart: case SquareButtonPart: case DefaultButtonPart: case ButtonPart: case MenulistPart: case SliderHorizontalPart: case SliderVerticalPart: case SliderThumbHorizontalPart: case SliderThumbVerticalPart: case SearchFieldPart: case SearchFieldCancelButtonPart: case SearchFieldDecorationPart: case SearchFieldResultsDecorationPart: case SearchFieldResultsButtonPart: default: break; } return false;}#if ENABLE(VIDEO)bool RenderTheme::hitTestMediaControlPart(RenderObject* o, const IntPoint& absPoint){ if (!o->isBox()) return false; FloatPoint localPoint = o->absoluteToLocal(absPoint, false, true); // respect transforms return toRenderBox(o)->borderBoxRect().contains(roundedIntPoint(localPoint));}#endifColor RenderTheme::activeSelectionBackgroundColor() const{ if (!m_activeSelectionBackgroundColor.isValid()) m_activeSelectionBackgroundColor = platformActiveSelectionBackgroundColor().blendWithWhite(); return m_activeSelectionBackgroundColor;}Color RenderTheme::inactiveSelectionBackgroundColor() const{ if (!m_inactiveSelectionBackgroundColor.isValid()) m_inactiveSelectionBackgroundColor = platformInactiveSelectionBackgroundColor().blendWithWhite(); return m_inactiveSelectionBackgroundColor;}Color RenderTheme::activeSelectionForegroundColor() const{ if (!m_activeSelectionForegroundColor.isValid() && supportsSelectionForegroundColors()) m_activeSelectionForegroundColor = platformActiveSelectionForegroundColor(); return m_activeSelectionForegroundColor;}Color RenderTheme::inactiveSelectionForegroundColor() const{ if (!m_inactiveSelectionForegroundColor.isValid() && supportsSelectionForegroundColors()) m_inactiveSelectionForegroundColor = platformInactiveSelectionForegroundColor(); return m_inactiveSelectionForegroundColor;}Color RenderTheme::activeListBoxSelectionBackgroundColor() const{ if (!m_activeListBoxSelectionBackgroundColor.isValid()) m_activeListBoxSelectionBackgroundColor = platformActiveListBoxSelectionBackgroundColor(); return m_activeListBoxSelectionBackgroundColor;}Color RenderTheme::inactiveListBoxSelectionBackgroundColor() const{ if (!m_inactiveListBoxSelectionBackgroundColor.isValid()) m_inactiveListBoxSelectionBackgroundColor = platformInactiveListBoxSelectionBackgroundColor(); return m_inactiveListBoxSelectionBackgroundColor;}Color RenderTheme::activeListBoxSelectionForegroundColor() const{ if (!m_activeListBoxSelectionForegroundColor.isValid() && supportsListBoxSelectionForegroundColors()) m_activeListBoxSelectionForegroundColor = platformActiveListBoxSelectionForegroundColor(); return m_activeListBoxSelectionForegroundColor;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -