Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1092)

Unified Diff: Source/core/paint/ThemePainter.cpp

Issue 1102353008: Split ThemePainter out of LayoutTheme (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: themePainter() -> theme().painter() Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « Source/core/paint/ThemePainter.h ('k') | Source/core/paint/ThemePainterDefault.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/core/paint/ThemePainter.cpp
diff --git a/Source/core/paint/ThemePainter.cpp b/Source/core/paint/ThemePainter.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..9b6ea695280c9d5a07eb279c06833d83364ffa9b
--- /dev/null
+++ b/Source/core/paint/ThemePainter.cpp
@@ -0,0 +1,382 @@
+/**
+ * This file is part of the theme implementation for form controls in WebCore.
+ *
+ * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2012 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 "core/paint/ThemePainter.h"
+
+#include "core/InputTypeNames.h"
+#include "core/html/HTMLDataListElement.h"
+#include "core/html/HTMLDataListOptionsCollection.h"
+#include "core/html/HTMLInputElement.h"
+#include "core/html/HTMLOptionElement.h"
+#include "core/html/parser/HTMLParserIdioms.h"
+#include "core/html/shadow/ShadowElementNames.h"
+#include "core/layout/LayoutMeter.h"
+#include "core/layout/LayoutTheme.h"
+#include "core/layout/LayoutView.h"
+#include "core/paint/PaintInfo.h"
+#include "core/style/ComputedStyle.h"
+#include "platform/graphics/GraphicsContextStateSaver.h"
+#include "public/platform/Platform.h"
+#include "public/platform/WebFallbackThemeEngine.h"
+#include "public/platform/WebRect.h"
+
+#if USE(NEW_THEME)
+#include "platform/Theme.h"
+#endif
+
+// The methods in this file are shared by all themes on every platform.
+
+namespace blink {
+
+static WebFallbackThemeEngine::State getWebFallbackThemeState(const LayoutObject* o)
+{
+ if (!LayoutTheme::isEnabled(o))
+ return WebFallbackThemeEngine::StateDisabled;
+ if (LayoutTheme::isPressed(o))
+ return WebFallbackThemeEngine::StatePressed;
+ if (LayoutTheme::isHovered(o))
+ return WebFallbackThemeEngine::StateHover;
+
+ return WebFallbackThemeEngine::StateNormal;
+}
+
+bool ThemePainter::paint(LayoutObject* o, const PaintInfo& paintInfo, const IntRect& r)
+{
+ ControlPart part = o->styleRef().appearance();
+
+ if (LayoutTheme::theme().shouldUseFallbackTheme(o->styleRef()))
+ return paintUsingFallbackTheme(o, paintInfo, r);
+
+#if USE(NEW_THEME)
+ switch (part) {
+ case CheckboxPart:
+ case RadioPart:
+ case PushButtonPart:
+ case SquareButtonPart:
+ case ButtonPart:
+ case InnerSpinButtonPart:
+ platformTheme()->paint(part, LayoutTheme::controlStatesForLayoutObject(o), const_cast<GraphicsContext*>(paintInfo.context), r, o->styleRef().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 ButtonPart:
+ return paintButton(o, paintInfo, r);
+ case InnerSpinButtonPart:
+ return paintInnerSpinButton(o, paintInfo, r);
+#endif
+ case MenulistPart:
+ return paintMenuList(o, paintInfo, r);
+ case MeterPart:
+ case RelevancyLevelIndicatorPart:
+ case ContinuousCapacityLevelIndicatorPart:
+ case DiscreteCapacityLevelIndicatorPart:
+ case RatingLevelIndicatorPart:
+ return paintMeter(o, paintInfo, r);
+ case ProgressBarPart:
+ return paintProgressBar(o, paintInfo, r);
+ case SliderHorizontalPart:
+ case SliderVerticalPart:
+ return paintSliderTrack(o, paintInfo, r);
+ case SliderThumbHorizontalPart:
+ case SliderThumbVerticalPart:
+ return paintSliderThumb(o, paintInfo, r);
+ case MediaEnterFullscreenButtonPart:
+ case MediaExitFullscreenButtonPart:
+ return paintMediaFullscreenButton(o, paintInfo, r);
+ case MediaPlayButtonPart:
+ return paintMediaPlayButton(o, paintInfo, r);
+ case MediaOverlayPlayButtonPart:
+ return paintMediaOverlayPlayButton(o, paintInfo, r);
+ case MediaMuteButtonPart:
+ return paintMediaMuteButton(o, paintInfo, r);
+ case MediaToggleClosedCaptionsButtonPart:
+ return paintMediaToggleClosedCaptionsButton(o, paintInfo, r);
+ case MediaSliderPart:
+ return paintMediaSliderTrack(o, paintInfo, r);
+ case MediaSliderThumbPart:
+ return paintMediaSliderThumb(o, paintInfo, r);
+ case MediaVolumeSliderContainerPart:
+ return paintMediaVolumeSliderContainer(o, paintInfo, r);
+ case MediaVolumeSliderPart:
+ return paintMediaVolumeSliderTrack(o, paintInfo, r);
+ case MediaVolumeSliderThumbPart:
+ return paintMediaVolumeSliderThumb(o, paintInfo, r);
+ case MediaFullScreenVolumeSliderPart:
+ return paintMediaFullScreenVolumeSliderTrack(o, paintInfo, r);
+ case MediaFullScreenVolumeSliderThumbPart:
+ return paintMediaFullScreenVolumeSliderThumb(o, paintInfo, r);
+ case MediaTimeRemainingPart:
+ return paintMediaTimeRemaining(o, paintInfo, r);
+ case MediaCurrentTimePart:
+ return paintMediaCurrentTime(o, paintInfo, r);
+ case MediaControlsBackgroundPart:
+ return paintMediaControlsBackground(o, paintInfo, r);
+ case MediaCastOffButtonPart:
+ return paintMediaCastButton(o, paintInfo, r);
+ case MediaOverlayCastOffButtonPart:
+ return paintMediaCastButton(o, paintInfo, r);
+ case MenulistButtonPart:
+ case TextFieldPart:
+ case TextAreaPart:
+ 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);
+ default:
+ break;
+ }
+
+ return true; // We don't support the appearance, so let the normal background/border paint.
+}
+
+bool ThemePainter::paintBorderOnly(LayoutObject* o, const PaintInfo& paintInfo, const IntRect& r)
+{
+ // Call the appropriate paint method based off the appearance value.
+ switch (o->style()->appearance()) {
+ case TextFieldPart:
+ return paintTextField(o, paintInfo, r);
+ case TextAreaPart:
+ return paintTextArea(o, paintInfo, r);
+ case MenulistButtonPart:
+ case SearchFieldPart:
+ case ListboxPart:
+ return true;
+ case CheckboxPart:
+ case RadioPart:
+ case PushButtonPart:
+ case SquareButtonPart:
+ case ButtonPart:
+ case MenulistPart:
+ case MeterPart:
+ case RelevancyLevelIndicatorPart:
+ case ContinuousCapacityLevelIndicatorPart:
+ case DiscreteCapacityLevelIndicatorPart:
+ case RatingLevelIndicatorPart:
+ case ProgressBarPart:
+ case SliderHorizontalPart:
+ case SliderVerticalPart:
+ case SliderThumbHorizontalPart:
+ case SliderThumbVerticalPart:
+ case SearchFieldCancelButtonPart:
+ case SearchFieldDecorationPart:
+ case SearchFieldResultsDecorationPart:
+ default:
+ break;
+ }
+
+ return false;
+}
+
+bool ThemePainter::paintDecorations(LayoutObject* o, const PaintInfo& paintInfo, const IntRect& r)
+{
+ // 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 CheckboxPart:
+ case RadioPart:
+ case PushButtonPart:
+ case SquareButtonPart:
+ case ButtonPart:
+ case MenulistPart:
+ case MeterPart:
+ case RelevancyLevelIndicatorPart:
+ case ContinuousCapacityLevelIndicatorPart:
+ case DiscreteCapacityLevelIndicatorPart:
+ case RatingLevelIndicatorPart:
+ case ProgressBarPart:
+ case SliderHorizontalPart:
+ case SliderVerticalPart:
+ case SliderThumbHorizontalPart:
+ case SliderThumbVerticalPart:
+ case SearchFieldPart:
+ case SearchFieldCancelButtonPart:
+ case SearchFieldDecorationPart:
+ case SearchFieldResultsDecorationPart:
+ default:
+ break;
+ }
+
+ return false;
+}
+
+bool ThemePainter::paintMeter(LayoutObject*, const PaintInfo&, const IntRect&)
+{
+ return true;
+}
+
+void ThemePainter::paintSliderTicks(LayoutObject* o, const PaintInfo& paintInfo, const IntRect& rect)
+{
+ Node* node = o->node();
+ if (!isHTMLInputElement(node))
+ return;
+
+ HTMLInputElement* input = toHTMLInputElement(node);
+ if (input->type() != InputTypeNames::range)
+ return;
+
+ HTMLDataListElement* dataList = input->dataList();
+ if (!dataList)
+ return;
+
+ double min = input->minimum();
+ double max = input->maximum();
+ ControlPart part = o->style()->appearance();
+ // We don't support ticks on alternate sliders like MediaVolumeSliders.
+ if (part != SliderHorizontalPart && part != SliderVerticalPart)
+ return;
+ bool isHorizontal = part == SliderHorizontalPart;
+
+ IntSize thumbSize;
+ LayoutObject* thumbLayoutObject = input->userAgentShadowRoot()->getElementById(ShadowElementNames::sliderThumb())->layoutObject();
+ if (thumbLayoutObject) {
+ const ComputedStyle& thumbStyle = thumbLayoutObject->styleRef();
+ int thumbWidth = thumbStyle.width().intValue();
+ int thumbHeight = thumbStyle.height().intValue();
+ thumbSize.setWidth(isHorizontal ? thumbWidth : thumbHeight);
+ thumbSize.setHeight(isHorizontal ? thumbHeight : thumbWidth);
+ }
+
+ IntSize tickSize = LayoutTheme::theme().sliderTickSize();
+ float zoomFactor = o->style()->effectiveZoom();
+ FloatRect tickRect;
+ int tickRegionSideMargin = 0;
+ int tickRegionWidth = 0;
+ IntRect trackBounds;
+ LayoutObject* trackLayoutObject = input->userAgentShadowRoot()->getElementById(ShadowElementNames::sliderTrack())->layoutObject();
+ // We can ignoring transforms because transform is handled by the graphics context.
+ if (trackLayoutObject)
+ trackBounds = trackLayoutObject->absoluteBoundingBoxRectIgnoringTransforms();
+ IntRect sliderBounds = o->absoluteBoundingBoxRectIgnoringTransforms();
+
+ // Make position relative to the transformed ancestor element.
+ trackBounds.setX(trackBounds.x() - sliderBounds.x() + rect.x());
+ trackBounds.setY(trackBounds.y() - sliderBounds.y() + rect.y());
+
+ if (isHorizontal) {
+ tickRect.setWidth(floor(tickSize.width() * zoomFactor));
+ tickRect.setHeight(floor(tickSize.height() * zoomFactor));
+ tickRect.setY(floor(rect.y() + rect.height() / 2.0 + LayoutTheme::theme().sliderTickOffsetFromTrackCenter() * zoomFactor));
+ tickRegionSideMargin = trackBounds.x() + (thumbSize.width() - tickSize.width() * zoomFactor) / 2.0;
+ tickRegionWidth = trackBounds.width() - thumbSize.width();
+ } else {
+ tickRect.setWidth(floor(tickSize.height() * zoomFactor));
+ tickRect.setHeight(floor(tickSize.width() * zoomFactor));
+ tickRect.setX(floor(rect.x() + rect.width() / 2.0 + LayoutTheme::theme().sliderTickOffsetFromTrackCenter() * zoomFactor));
+ tickRegionSideMargin = trackBounds.y() + (thumbSize.width() - tickSize.width() * zoomFactor) / 2.0;
+ tickRegionWidth = trackBounds.height() - thumbSize.width();
+ }
+ RefPtrWillBeRawPtr<HTMLDataListOptionsCollection> options = dataList->options();
+ for (unsigned i = 0; HTMLOptionElement* optionElement = options->item(i); i++) {
+ String value = optionElement->value();
+ if (!input->isValidValue(value))
+ continue;
+ double parsedValue = parseToDoubleForNumberType(input->sanitizeValue(value));
+ double tickFraction = (parsedValue - min) / (max - min);
+ double tickRatio = isHorizontal && o->style()->isLeftToRightDirection() ? tickFraction : 1.0 - tickFraction;
+ double tickPosition = round(tickRegionSideMargin + tickRegionWidth * tickRatio);
+ if (isHorizontal)
+ tickRect.setX(tickPosition);
+ else
+ tickRect.setY(tickPosition);
+ paintInfo.context->fillRect(tickRect, o->resolveColor(CSSPropertyColor));
+ }
+}
+
+bool ThemePainter::paintUsingFallbackTheme(LayoutObject* o, const PaintInfo& i, const IntRect& r)
+{
+ ControlPart part = o->style()->appearance();
+ switch (part) {
+ case CheckboxPart:
+ return paintCheckboxUsingFallbackTheme(o, i, r);
+ case RadioPart:
+ return paintRadioUsingFallbackTheme(o, i, r);
+ default:
+ break;
+ }
+ return true;
+}
+
+bool ThemePainter::paintCheckboxUsingFallbackTheme(LayoutObject* o, const PaintInfo& i, const IntRect& r)
+{
+ WebFallbackThemeEngine::ExtraParams extraParams;
+ WebCanvas* canvas = i.context->canvas();
+ extraParams.button.checked = LayoutTheme::isChecked(o);
+ extraParams.button.indeterminate = LayoutTheme::isIndeterminate(o);
+
+ float zoomLevel = o->style()->effectiveZoom();
+ GraphicsContextStateSaver stateSaver(*i.context);
+ IntRect unzoomedRect = r;
+ if (zoomLevel != 1) {
+ unzoomedRect.setWidth(unzoomedRect.width() / zoomLevel);
+ unzoomedRect.setHeight(unzoomedRect.height() / zoomLevel);
+ i.context->translate(unzoomedRect.x(), unzoomedRect.y());
+ i.context->scale(zoomLevel, zoomLevel);
+ i.context->translate(-unzoomedRect.x(), -unzoomedRect.y());
+ }
+
+ Platform::current()->fallbackThemeEngine()->paint(canvas, WebFallbackThemeEngine::PartCheckbox, getWebFallbackThemeState(o), WebRect(unzoomedRect), &extraParams);
+ return false;
+}
+
+bool ThemePainter::paintRadioUsingFallbackTheme(LayoutObject* o, const PaintInfo& i, const IntRect& r)
+{
+ WebFallbackThemeEngine::ExtraParams extraParams;
+ WebCanvas* canvas = i.context->canvas();
+ extraParams.button.checked = LayoutTheme::isChecked(o);
+ extraParams.button.indeterminate = LayoutTheme::isIndeterminate(o);
+
+ float zoomLevel = o->style()->effectiveZoom();
+ GraphicsContextStateSaver stateSaver(*i.context);
+ IntRect unzoomedRect = r;
+ if (zoomLevel != 1) {
+ unzoomedRect.setWidth(unzoomedRect.width() / zoomLevel);
+ unzoomedRect.setHeight(unzoomedRect.height() / zoomLevel);
+ i.context->translate(unzoomedRect.x(), unzoomedRect.y());
+ i.context->scale(zoomLevel, zoomLevel);
+ i.context->translate(-unzoomedRect.x(), -unzoomedRect.y());
+ }
+
+ Platform::current()->fallbackThemeEngine()->paint(canvas, WebFallbackThemeEngine::PartRadio, getWebFallbackThemeState(o), WebRect(unzoomedRect), &extraParams);
+ return false;
+}
+
+} // namespace blink
« no previous file with comments | « Source/core/paint/ThemePainter.h ('k') | Source/core/paint/ThemePainterDefault.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698