| OLD | NEW |
| (Empty) | |
| 1 /** |
| 2 * This file is part of the theme implementation for form controls in WebCore. |
| 3 * |
| 4 * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2012 Apple Computer, Inc. |
| 5 * |
| 6 * This library is free software; you can redistribute it and/or |
| 7 * modify it under the terms of the GNU Library General Public |
| 8 * License as published by the Free Software Foundation; either |
| 9 * version 2 of the License, or (at your option) any later version. |
| 10 * |
| 11 * This library is distributed in the hope that it will be useful, |
| 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 14 * Library General Public License for more details. |
| 15 * |
| 16 * You should have received a copy of the GNU Library General Public License |
| 17 * along with this library; see the file COPYING.LIB. If not, write to |
| 18 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
| 19 * Boston, MA 02110-1301, USA. |
| 20 */ |
| 21 |
| 22 #include "config.h" |
| 23 #include "core/paint/ThemePainter.h" |
| 24 |
| 25 #include "core/InputTypeNames.h" |
| 26 #include "core/html/HTMLDataListElement.h" |
| 27 #include "core/html/HTMLDataListOptionsCollection.h" |
| 28 #include "core/html/HTMLInputElement.h" |
| 29 #include "core/html/HTMLOptionElement.h" |
| 30 #include "core/html/parser/HTMLParserIdioms.h" |
| 31 #include "core/html/shadow/ShadowElementNames.h" |
| 32 #include "core/layout/LayoutMeter.h" |
| 33 #include "core/layout/LayoutTheme.h" |
| 34 #include "core/layout/LayoutView.h" |
| 35 #include "core/paint/PaintInfo.h" |
| 36 #include "core/style/ComputedStyle.h" |
| 37 #include "platform/graphics/GraphicsContextStateSaver.h" |
| 38 #include "public/platform/Platform.h" |
| 39 #include "public/platform/WebFallbackThemeEngine.h" |
| 40 #include "public/platform/WebRect.h" |
| 41 |
| 42 #if USE(NEW_THEME) |
| 43 #include "platform/Theme.h" |
| 44 #endif |
| 45 |
| 46 // The methods in this file are shared by all themes on every platform. |
| 47 |
| 48 namespace blink { |
| 49 |
| 50 static WebFallbackThemeEngine::State getWebFallbackThemeState(const LayoutObject
* o) |
| 51 { |
| 52 if (!LayoutTheme::isEnabled(o)) |
| 53 return WebFallbackThemeEngine::StateDisabled; |
| 54 if (LayoutTheme::isPressed(o)) |
| 55 return WebFallbackThemeEngine::StatePressed; |
| 56 if (LayoutTheme::isHovered(o)) |
| 57 return WebFallbackThemeEngine::StateHover; |
| 58 |
| 59 return WebFallbackThemeEngine::StateNormal; |
| 60 } |
| 61 |
| 62 bool ThemePainter::paint(LayoutObject* o, const PaintInfo& paintInfo, const IntR
ect& r) |
| 63 { |
| 64 ControlPart part = o->styleRef().appearance(); |
| 65 |
| 66 if (LayoutTheme::theme().shouldUseFallbackTheme(o->styleRef())) |
| 67 return paintUsingFallbackTheme(o, paintInfo, r); |
| 68 |
| 69 #if USE(NEW_THEME) |
| 70 switch (part) { |
| 71 case CheckboxPart: |
| 72 case RadioPart: |
| 73 case PushButtonPart: |
| 74 case SquareButtonPart: |
| 75 case ButtonPart: |
| 76 case InnerSpinButtonPart: |
| 77 platformTheme()->paint(part, LayoutTheme::controlStatesForLayoutObject(o
), const_cast<GraphicsContext*>(paintInfo.context), r, o->styleRef().effectiveZo
om(), o->view()->frameView()); |
| 78 return false; |
| 79 default: |
| 80 break; |
| 81 } |
| 82 #endif |
| 83 |
| 84 // Call the appropriate paint method based off the appearance value. |
| 85 switch (part) { |
| 86 #if !USE(NEW_THEME) |
| 87 case CheckboxPart: |
| 88 return paintCheckbox(o, paintInfo, r); |
| 89 case RadioPart: |
| 90 return paintRadio(o, paintInfo, r); |
| 91 case PushButtonPart: |
| 92 case SquareButtonPart: |
| 93 case ButtonPart: |
| 94 return paintButton(o, paintInfo, r); |
| 95 case InnerSpinButtonPart: |
| 96 return paintInnerSpinButton(o, paintInfo, r); |
| 97 #endif |
| 98 case MenulistPart: |
| 99 return paintMenuList(o, paintInfo, r); |
| 100 case MeterPart: |
| 101 case RelevancyLevelIndicatorPart: |
| 102 case ContinuousCapacityLevelIndicatorPart: |
| 103 case DiscreteCapacityLevelIndicatorPart: |
| 104 case RatingLevelIndicatorPart: |
| 105 return paintMeter(o, paintInfo, r); |
| 106 case ProgressBarPart: |
| 107 return paintProgressBar(o, paintInfo, r); |
| 108 case SliderHorizontalPart: |
| 109 case SliderVerticalPart: |
| 110 return paintSliderTrack(o, paintInfo, r); |
| 111 case SliderThumbHorizontalPart: |
| 112 case SliderThumbVerticalPart: |
| 113 return paintSliderThumb(o, paintInfo, r); |
| 114 case MediaEnterFullscreenButtonPart: |
| 115 case MediaExitFullscreenButtonPart: |
| 116 return paintMediaFullscreenButton(o, paintInfo, r); |
| 117 case MediaPlayButtonPart: |
| 118 return paintMediaPlayButton(o, paintInfo, r); |
| 119 case MediaOverlayPlayButtonPart: |
| 120 return paintMediaOverlayPlayButton(o, paintInfo, r); |
| 121 case MediaMuteButtonPart: |
| 122 return paintMediaMuteButton(o, paintInfo, r); |
| 123 case MediaToggleClosedCaptionsButtonPart: |
| 124 return paintMediaToggleClosedCaptionsButton(o, paintInfo, r); |
| 125 case MediaSliderPart: |
| 126 return paintMediaSliderTrack(o, paintInfo, r); |
| 127 case MediaSliderThumbPart: |
| 128 return paintMediaSliderThumb(o, paintInfo, r); |
| 129 case MediaVolumeSliderContainerPart: |
| 130 return paintMediaVolumeSliderContainer(o, paintInfo, r); |
| 131 case MediaVolumeSliderPart: |
| 132 return paintMediaVolumeSliderTrack(o, paintInfo, r); |
| 133 case MediaVolumeSliderThumbPart: |
| 134 return paintMediaVolumeSliderThumb(o, paintInfo, r); |
| 135 case MediaFullScreenVolumeSliderPart: |
| 136 return paintMediaFullScreenVolumeSliderTrack(o, paintInfo, r); |
| 137 case MediaFullScreenVolumeSliderThumbPart: |
| 138 return paintMediaFullScreenVolumeSliderThumb(o, paintInfo, r); |
| 139 case MediaTimeRemainingPart: |
| 140 return paintMediaTimeRemaining(o, paintInfo, r); |
| 141 case MediaCurrentTimePart: |
| 142 return paintMediaCurrentTime(o, paintInfo, r); |
| 143 case MediaControlsBackgroundPart: |
| 144 return paintMediaControlsBackground(o, paintInfo, r); |
| 145 case MediaCastOffButtonPart: |
| 146 return paintMediaCastButton(o, paintInfo, r); |
| 147 case MediaOverlayCastOffButtonPart: |
| 148 return paintMediaCastButton(o, paintInfo, r); |
| 149 case MenulistButtonPart: |
| 150 case TextFieldPart: |
| 151 case TextAreaPart: |
| 152 return true; |
| 153 case SearchFieldPart: |
| 154 return paintSearchField(o, paintInfo, r); |
| 155 case SearchFieldCancelButtonPart: |
| 156 return paintSearchFieldCancelButton(o, paintInfo, r); |
| 157 case SearchFieldDecorationPart: |
| 158 return paintSearchFieldDecoration(o, paintInfo, r); |
| 159 case SearchFieldResultsDecorationPart: |
| 160 return paintSearchFieldResultsDecoration(o, paintInfo, r); |
| 161 default: |
| 162 break; |
| 163 } |
| 164 |
| 165 return true; // We don't support the appearance, so let the normal backgroun
d/border paint. |
| 166 } |
| 167 |
| 168 bool ThemePainter::paintBorderOnly(LayoutObject* o, const PaintInfo& paintInfo,
const IntRect& r) |
| 169 { |
| 170 // Call the appropriate paint method based off the appearance value. |
| 171 switch (o->style()->appearance()) { |
| 172 case TextFieldPart: |
| 173 return paintTextField(o, paintInfo, r); |
| 174 case TextAreaPart: |
| 175 return paintTextArea(o, paintInfo, r); |
| 176 case MenulistButtonPart: |
| 177 case SearchFieldPart: |
| 178 case ListboxPart: |
| 179 return true; |
| 180 case CheckboxPart: |
| 181 case RadioPart: |
| 182 case PushButtonPart: |
| 183 case SquareButtonPart: |
| 184 case ButtonPart: |
| 185 case MenulistPart: |
| 186 case MeterPart: |
| 187 case RelevancyLevelIndicatorPart: |
| 188 case ContinuousCapacityLevelIndicatorPart: |
| 189 case DiscreteCapacityLevelIndicatorPart: |
| 190 case RatingLevelIndicatorPart: |
| 191 case ProgressBarPart: |
| 192 case SliderHorizontalPart: |
| 193 case SliderVerticalPart: |
| 194 case SliderThumbHorizontalPart: |
| 195 case SliderThumbVerticalPart: |
| 196 case SearchFieldCancelButtonPart: |
| 197 case SearchFieldDecorationPart: |
| 198 case SearchFieldResultsDecorationPart: |
| 199 default: |
| 200 break; |
| 201 } |
| 202 |
| 203 return false; |
| 204 } |
| 205 |
| 206 bool ThemePainter::paintDecorations(LayoutObject* o, const PaintInfo& paintInfo,
const IntRect& r) |
| 207 { |
| 208 // Call the appropriate paint method based off the appearance value. |
| 209 switch (o->style()->appearance()) { |
| 210 case MenulistButtonPart: |
| 211 return paintMenuListButton(o, paintInfo, r); |
| 212 case TextFieldPart: |
| 213 case TextAreaPart: |
| 214 case CheckboxPart: |
| 215 case RadioPart: |
| 216 case PushButtonPart: |
| 217 case SquareButtonPart: |
| 218 case ButtonPart: |
| 219 case MenulistPart: |
| 220 case MeterPart: |
| 221 case RelevancyLevelIndicatorPart: |
| 222 case ContinuousCapacityLevelIndicatorPart: |
| 223 case DiscreteCapacityLevelIndicatorPart: |
| 224 case RatingLevelIndicatorPart: |
| 225 case ProgressBarPart: |
| 226 case SliderHorizontalPart: |
| 227 case SliderVerticalPart: |
| 228 case SliderThumbHorizontalPart: |
| 229 case SliderThumbVerticalPart: |
| 230 case SearchFieldPart: |
| 231 case SearchFieldCancelButtonPart: |
| 232 case SearchFieldDecorationPart: |
| 233 case SearchFieldResultsDecorationPart: |
| 234 default: |
| 235 break; |
| 236 } |
| 237 |
| 238 return false; |
| 239 } |
| 240 |
| 241 bool ThemePainter::paintMeter(LayoutObject*, const PaintInfo&, const IntRect&) |
| 242 { |
| 243 return true; |
| 244 } |
| 245 |
| 246 void ThemePainter::paintSliderTicks(LayoutObject* o, const PaintInfo& paintInfo,
const IntRect& rect) |
| 247 { |
| 248 Node* node = o->node(); |
| 249 if (!isHTMLInputElement(node)) |
| 250 return; |
| 251 |
| 252 HTMLInputElement* input = toHTMLInputElement(node); |
| 253 if (input->type() != InputTypeNames::range) |
| 254 return; |
| 255 |
| 256 HTMLDataListElement* dataList = input->dataList(); |
| 257 if (!dataList) |
| 258 return; |
| 259 |
| 260 double min = input->minimum(); |
| 261 double max = input->maximum(); |
| 262 ControlPart part = o->style()->appearance(); |
| 263 // We don't support ticks on alternate sliders like MediaVolumeSliders. |
| 264 if (part != SliderHorizontalPart && part != SliderVerticalPart) |
| 265 return; |
| 266 bool isHorizontal = part == SliderHorizontalPart; |
| 267 |
| 268 IntSize thumbSize; |
| 269 LayoutObject* thumbLayoutObject = input->userAgentShadowRoot()->getElementBy
Id(ShadowElementNames::sliderThumb())->layoutObject(); |
| 270 if (thumbLayoutObject) { |
| 271 const ComputedStyle& thumbStyle = thumbLayoutObject->styleRef(); |
| 272 int thumbWidth = thumbStyle.width().intValue(); |
| 273 int thumbHeight = thumbStyle.height().intValue(); |
| 274 thumbSize.setWidth(isHorizontal ? thumbWidth : thumbHeight); |
| 275 thumbSize.setHeight(isHorizontal ? thumbHeight : thumbWidth); |
| 276 } |
| 277 |
| 278 IntSize tickSize = LayoutTheme::theme().sliderTickSize(); |
| 279 float zoomFactor = o->style()->effectiveZoom(); |
| 280 FloatRect tickRect; |
| 281 int tickRegionSideMargin = 0; |
| 282 int tickRegionWidth = 0; |
| 283 IntRect trackBounds; |
| 284 LayoutObject* trackLayoutObject = input->userAgentShadowRoot()->getElementBy
Id(ShadowElementNames::sliderTrack())->layoutObject(); |
| 285 // We can ignoring transforms because transform is handled by the graphics c
ontext. |
| 286 if (trackLayoutObject) |
| 287 trackBounds = trackLayoutObject->absoluteBoundingBoxRectIgnoringTransfor
ms(); |
| 288 IntRect sliderBounds = o->absoluteBoundingBoxRectIgnoringTransforms(); |
| 289 |
| 290 // Make position relative to the transformed ancestor element. |
| 291 trackBounds.setX(trackBounds.x() - sliderBounds.x() + rect.x()); |
| 292 trackBounds.setY(trackBounds.y() - sliderBounds.y() + rect.y()); |
| 293 |
| 294 if (isHorizontal) { |
| 295 tickRect.setWidth(floor(tickSize.width() * zoomFactor)); |
| 296 tickRect.setHeight(floor(tickSize.height() * zoomFactor)); |
| 297 tickRect.setY(floor(rect.y() + rect.height() / 2.0 + LayoutTheme::theme(
).sliderTickOffsetFromTrackCenter() * zoomFactor)); |
| 298 tickRegionSideMargin = trackBounds.x() + (thumbSize.width() - tickSize.w
idth() * zoomFactor) / 2.0; |
| 299 tickRegionWidth = trackBounds.width() - thumbSize.width(); |
| 300 } else { |
| 301 tickRect.setWidth(floor(tickSize.height() * zoomFactor)); |
| 302 tickRect.setHeight(floor(tickSize.width() * zoomFactor)); |
| 303 tickRect.setX(floor(rect.x() + rect.width() / 2.0 + LayoutTheme::theme()
.sliderTickOffsetFromTrackCenter() * zoomFactor)); |
| 304 tickRegionSideMargin = trackBounds.y() + (thumbSize.width() - tickSize.w
idth() * zoomFactor) / 2.0; |
| 305 tickRegionWidth = trackBounds.height() - thumbSize.width(); |
| 306 } |
| 307 RefPtrWillBeRawPtr<HTMLDataListOptionsCollection> options = dataList->option
s(); |
| 308 for (unsigned i = 0; HTMLOptionElement* optionElement = options->item(i); i+
+) { |
| 309 String value = optionElement->value(); |
| 310 if (!input->isValidValue(value)) |
| 311 continue; |
| 312 double parsedValue = parseToDoubleForNumberType(input->sanitizeValue(val
ue)); |
| 313 double tickFraction = (parsedValue - min) / (max - min); |
| 314 double tickRatio = isHorizontal && o->style()->isLeftToRightDirection()
? tickFraction : 1.0 - tickFraction; |
| 315 double tickPosition = round(tickRegionSideMargin + tickRegionWidth * tic
kRatio); |
| 316 if (isHorizontal) |
| 317 tickRect.setX(tickPosition); |
| 318 else |
| 319 tickRect.setY(tickPosition); |
| 320 paintInfo.context->fillRect(tickRect, o->resolveColor(CSSPropertyColor))
; |
| 321 } |
| 322 } |
| 323 |
| 324 bool ThemePainter::paintUsingFallbackTheme(LayoutObject* o, const PaintInfo& i,
const IntRect& r) |
| 325 { |
| 326 ControlPart part = o->style()->appearance(); |
| 327 switch (part) { |
| 328 case CheckboxPart: |
| 329 return paintCheckboxUsingFallbackTheme(o, i, r); |
| 330 case RadioPart: |
| 331 return paintRadioUsingFallbackTheme(o, i, r); |
| 332 default: |
| 333 break; |
| 334 } |
| 335 return true; |
| 336 } |
| 337 |
| 338 bool ThemePainter::paintCheckboxUsingFallbackTheme(LayoutObject* o, const PaintI
nfo& i, const IntRect& r) |
| 339 { |
| 340 WebFallbackThemeEngine::ExtraParams extraParams; |
| 341 WebCanvas* canvas = i.context->canvas(); |
| 342 extraParams.button.checked = LayoutTheme::isChecked(o); |
| 343 extraParams.button.indeterminate = LayoutTheme::isIndeterminate(o); |
| 344 |
| 345 float zoomLevel = o->style()->effectiveZoom(); |
| 346 GraphicsContextStateSaver stateSaver(*i.context); |
| 347 IntRect unzoomedRect = r; |
| 348 if (zoomLevel != 1) { |
| 349 unzoomedRect.setWidth(unzoomedRect.width() / zoomLevel); |
| 350 unzoomedRect.setHeight(unzoomedRect.height() / zoomLevel); |
| 351 i.context->translate(unzoomedRect.x(), unzoomedRect.y()); |
| 352 i.context->scale(zoomLevel, zoomLevel); |
| 353 i.context->translate(-unzoomedRect.x(), -unzoomedRect.y()); |
| 354 } |
| 355 |
| 356 Platform::current()->fallbackThemeEngine()->paint(canvas, WebFallbackThemeEn
gine::PartCheckbox, getWebFallbackThemeState(o), WebRect(unzoomedRect), &extraPa
rams); |
| 357 return false; |
| 358 } |
| 359 |
| 360 bool ThemePainter::paintRadioUsingFallbackTheme(LayoutObject* o, const PaintInfo
& i, const IntRect& r) |
| 361 { |
| 362 WebFallbackThemeEngine::ExtraParams extraParams; |
| 363 WebCanvas* canvas = i.context->canvas(); |
| 364 extraParams.button.checked = LayoutTheme::isChecked(o); |
| 365 extraParams.button.indeterminate = LayoutTheme::isIndeterminate(o); |
| 366 |
| 367 float zoomLevel = o->style()->effectiveZoom(); |
| 368 GraphicsContextStateSaver stateSaver(*i.context); |
| 369 IntRect unzoomedRect = r; |
| 370 if (zoomLevel != 1) { |
| 371 unzoomedRect.setWidth(unzoomedRect.width() / zoomLevel); |
| 372 unzoomedRect.setHeight(unzoomedRect.height() / zoomLevel); |
| 373 i.context->translate(unzoomedRect.x(), unzoomedRect.y()); |
| 374 i.context->scale(zoomLevel, zoomLevel); |
| 375 i.context->translate(-unzoomedRect.x(), -unzoomedRect.y()); |
| 376 } |
| 377 |
| 378 Platform::current()->fallbackThemeEngine()->paint(canvas, WebFallbackThemeEn
gine::PartRadio, getWebFallbackThemeState(o), WebRect(unzoomedRect), &extraParam
s); |
| 379 return false; |
| 380 } |
| 381 |
| 382 } // namespace blink |
| OLD | NEW |