Chromium Code Reviews| OLD | NEW | 
|---|---|
| 1 /* | 1 /* | 
| 2 * Copyright (C) 2009 Apple Inc. | 2 * Copyright (C) 2009 Apple Inc. | 
| 3 * Copyright (C) 2009 Google Inc. | 3 * Copyright (C) 2009 Google Inc. | 
| 4 * All rights reserved. | 4 * All rights reserved. | 
| 5 * | 5 * | 
| 6 * Redistribution and use in source and binary forms, with or without | 6 * Redistribution and use in source and binary forms, with or without | 
| 7 * modification, are permitted provided that the following conditions | 7 * modification, are permitted provided that the following conditions | 
| 8 * are met: | 8 * are met: | 
| 9 * 1. Redistributions of source code must retain the above copyright | 9 * 1. Redistributions of source code must retain the above copyright | 
| 10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. | 
| (...skipping 26 matching lines...) Expand all Loading... | |
| 37 #include "platform/graphics/Gradient.h" | 37 #include "platform/graphics/Gradient.h" | 
| 38 #include "platform/graphics/GraphicsContext.h" | 38 #include "platform/graphics/GraphicsContext.h" | 
| 39 | 39 | 
| 40 namespace blink { | 40 namespace blink { | 
| 41 | 41 | 
| 42 static double kCurrentTimeBufferedDelta = 1.0; | 42 static double kCurrentTimeBufferedDelta = 1.0; | 
| 43 | 43 | 
| 44 typedef WTF::HashMap<const char*, Image*> MediaControlImageMap; | 44 typedef WTF::HashMap<const char*, Image*> MediaControlImageMap; | 
| 45 static MediaControlImageMap* gMediaControlImageMap = 0; | 45 static MediaControlImageMap* gMediaControlImageMap = 0; | 
| 46 | 46 | 
| 47 // Current UI slider thumbs sizes. | |
| 48 static const int mediaSliderThumbWidth = 32; | |
| 49 static const int mediaSliderThumbHeight = 24; | |
| 50 static const int mediaVolumeSliderThumbHeight = 24; | |
| 51 static const int mediaVolumeSliderThumbWidth = 24; | |
| 
 
liberato (no reviews please)
2015/07/14 22:10:37
i didn't move these into functions.  the result wa
 
 | |
| 52 | |
| 53 // New UI slider thumb sizes, shard between time and volume. | |
| 54 static const int mediaSliderThumbTouchWidthNew = 36; // Touch zone size. | |
| 55 static const int mediaSliderThumbTouchHeightNew = 48; | |
| 56 static const int mediaSliderThumbPaintWidthNew = 12; // Painted area. | |
| 57 static const int mediaSliderThumbPaintHeightNew = 12; | |
| 58 | |
| 59 // New UI overlay play button size. | |
| 60 static const int mediaOverlayPlayButtonWidthNew = 48; | |
| 61 static const int mediaOverlayPlayButtonHeightNew = 48; | |
| 62 | |
| 63 // New UI slider bar height. | |
| 64 static const int mediaSliderBarHeight = 2; | |
| 65 | |
| 66 // Alpha for disabled elements. | |
| 67 static const float kDisabledAlpha = 0.4; | |
| 68 | |
| 47 static Image* platformResource(const char* name) | 69 static Image* platformResource(const char* name) | 
| 48 { | 70 { | 
| 49 if (!gMediaControlImageMap) | 71 if (!gMediaControlImageMap) | 
| 50 gMediaControlImageMap = new MediaControlImageMap(); | 72 gMediaControlImageMap = new MediaControlImageMap(); | 
| 51 if (Image* image = gMediaControlImageMap->get(name)) | 73 if (Image* image = gMediaControlImageMap->get(name)) | 
| 52 return image; | 74 return image; | 
| 53 if (Image* image = Image::loadPlatformResource(name).leakRef()) { | 75 if (Image* image = Image::loadPlatformResource(name).leakRef()) { | 
| 54 gMediaControlImageMap->set(name, image); | 76 gMediaControlImageMap->set(name, image); | 
| 55 return image; | 77 return image; | 
| 56 } | 78 } | 
| 57 ASSERT_NOT_REACHED(); | 79 ASSERT_NOT_REACHED(); | 
| 58 return 0; | 80 return 0; | 
| 59 } | 81 } | 
| 60 | 82 | 
| 83 static Image* platformResource(const char* currentName, const char* newName) | |
| 84 { | |
| 85 // Return currentName or newName based on current or new playback. | |
| 86 return platformResource(RuntimeEnabledFeatures::newMediaPlaybackUiEnabled() ? newName : currentName); | |
| 87 } | |
| 88 | |
| 61 static bool hasSource(const HTMLMediaElement* mediaElement) | 89 static bool hasSource(const HTMLMediaElement* mediaElement) | 
| 62 { | 90 { | 
| 63 return mediaElement->networkState() != HTMLMediaElement::NETWORK_EMPTY | 91 return mediaElement->networkState() != HTMLMediaElement::NETWORK_EMPTY | 
| 64 && mediaElement->networkState() != HTMLMediaElement::NETWORK_NO_SOURCE; | 92 && mediaElement->networkState() != HTMLMediaElement::NETWORK_NO_SOURCE; | 
| 65 } | 93 } | 
| 66 | 94 | 
| 67 static bool paintMediaButton(GraphicsContext* context, const IntRect& rect, Imag e* image) | 95 static bool paintMediaButton(GraphicsContext* context, const IntRect& rect, Imag e* image, bool isEnabled = false) | 
| 68 { | 96 { | 
| 97 if (!RuntimeEnabledFeatures::newMediaPlaybackUiEnabled()) | |
| 98 isEnabled = false; // New UI only. | |
| 99 | |
| 100 if (isEnabled) | |
| 101 context->beginLayer(kDisabledAlpha); | |
| 102 | |
| 69 context->drawImage(image, rect); | 103 context->drawImage(image, rect); | 
| 104 | |
| 105 if (isEnabled) | |
| 106 context->endLayer(); | |
| 107 | |
| 70 return true; | 108 return true; | 
| 71 } | 109 } | 
| 72 | 110 | 
| 73 bool MediaControlsPainter::paintMediaMuteButton(LayoutObject* object, const Pain tInfo& paintInfo, const IntRect& rect) | 111 bool MediaControlsPainter::paintMediaMuteButton(LayoutObject* object, const Pain tInfo& paintInfo, const IntRect& rect) | 
| 74 { | 112 { | 
| 75 HTMLMediaElement* mediaElement = toParentMediaElement(object); | 113 HTMLMediaElement* mediaElement = toParentMediaElement(object); | 
| 76 if (!mediaElement) | 114 if (!mediaElement) | 
| 77 return false; | 115 return false; | 
| 78 | 116 | 
| 79 static Image* soundLevel3 = platformResource("mediaplayerSoundLevel3"); | 117 // The new UI uses "muted" and "not muted" only. | 
| 80 static Image* soundLevel2 = platformResource("mediaplayerSoundLevel2"); | 118 static Image* soundLevel3 = platformResource("mediaplayerSoundLevel3", | 
| 81 static Image* soundLevel1 = platformResource("mediaplayerSoundLevel1"); | 119 "mediaplayerSoundLevel3New"); | 
| 82 static Image* soundLevel0 = platformResource("mediaplayerSoundLevel0"); | 120 static Image* soundLevel2 = platformResource("mediaplayerSoundLevel2", | 
| 83 static Image* soundDisabled = platformResource("mediaplayerSoundDisabled"); | 121 "mediaplayerSoundLevel3New"); | 
| 122 static Image* soundLevel1 = platformResource("mediaplayerSoundLevel1", | |
| 123 "mediaplayerSoundLevel3New"); | |
| 124 static Image* soundLevel0 = platformResource("mediaplayerSoundLevel0", | |
| 125 "mediaplayerSoundLevel0New"); | |
| 126 static Image* soundDisabled = platformResource("mediaplayerSoundDisabled", | |
| 127 "mediaplayerSoundLevel0New"); | |
| 84 | 128 | 
| 85 if (!hasSource(mediaElement) || !mediaElement->hasAudio()) | 129 if (!hasSource(mediaElement) || !mediaElement->hasAudio()) | 
| 86 return paintMediaButton(paintInfo.context, rect, soundDisabled); | 130 return paintMediaButton(paintInfo.context, rect, soundDisabled, true); | 
| 87 | 131 | 
| 88 if (mediaElement->muted() || mediaElement->volume() <= 0) | 132 if (mediaElement->muted() || mediaElement->volume() <= 0) | 
| 89 return paintMediaButton(paintInfo.context, rect, soundLevel0); | 133 return paintMediaButton(paintInfo.context, rect, soundLevel0); | 
| 90 | 134 | 
| 91 if (mediaElement->volume() <= 0.33) | 135 if (mediaElement->volume() <= 0.33) | 
| 92 return paintMediaButton(paintInfo.context, rect, soundLevel1); | 136 return paintMediaButton(paintInfo.context, rect, soundLevel1); | 
| 93 | 137 | 
| 94 if (mediaElement->volume() <= 0.66) | 138 if (mediaElement->volume() <= 0.66) | 
| 95 return paintMediaButton(paintInfo.context, rect, soundLevel2); | 139 return paintMediaButton(paintInfo.context, rect, soundLevel2); | 
| 96 | 140 | 
| 97 return paintMediaButton(paintInfo.context, rect, soundLevel3); | 141 return paintMediaButton(paintInfo.context, rect, soundLevel3); | 
| 98 } | 142 } | 
| 99 | 143 | 
| 100 bool MediaControlsPainter::paintMediaPlayButton(LayoutObject* object, const Pain tInfo& paintInfo, const IntRect& rect) | 144 bool MediaControlsPainter::paintMediaPlayButton(LayoutObject* object, const Pain tInfo& paintInfo, const IntRect& rect) | 
| 101 { | 145 { | 
| 102 HTMLMediaElement* mediaElement = toParentMediaElement(object); | 146 HTMLMediaElement* mediaElement = toParentMediaElement(object); | 
| 103 if (!mediaElement) | 147 if (!mediaElement) | 
| 104 return false; | 148 return false; | 
| 105 | 149 | 
| 106 static Image* mediaPlay = platformResource("mediaplayerPlay"); | 150 static Image* mediaPlay = platformResource("mediaplayerPlay", "mediaplayerPl ayNew"); | 
| 107 static Image* mediaPause = platformResource("mediaplayerPause"); | 151 static Image* mediaPause = platformResource("mediaplayerPause", "mediaplayer PauseNew"); | 
| 108 static Image* mediaPlayDisabled = platformResource("mediaplayerPlayDisabled" ); | 152 // For this case, the new UI draws the normal icon, but the entire panel | 
| 153 // grays out. | |
| 154 static Image* mediaPlayDisabled = platformResource("mediaplayerPlayDisabled" , "mediaplayerPlayNew"); | |
| 109 | 155 | 
| 110 if (!hasSource(mediaElement)) | 156 if (!hasSource(mediaElement)) | 
| 111 return paintMediaButton(paintInfo.context, rect, mediaPlayDisabled); | 157 return paintMediaButton(paintInfo.context, rect, mediaPlayDisabled, true ); | 
| 112 | 158 | 
| 113 Image * image = !object->node()->isMediaControlElement() || mediaControlElem entType(object->node()) == MediaPlayButton ? mediaPlay : mediaPause; | 159 Image * image = !object->node()->isMediaControlElement() || mediaControlElem entType(object->node()) == MediaPlayButton ? mediaPlay : mediaPause; | 
| 114 return paintMediaButton(paintInfo.context, rect, image); | 160 return paintMediaButton(paintInfo.context, rect, image); | 
| 115 } | 161 } | 
| 116 | 162 | 
| 117 bool MediaControlsPainter::paintMediaOverlayPlayButton(LayoutObject* object, con st PaintInfo& paintInfo, const IntRect& rect) | 163 bool MediaControlsPainter::paintMediaOverlayPlayButton(LayoutObject* object, con st PaintInfo& paintInfo, const IntRect& rect) | 
| 118 { | 164 { | 
| 119 HTMLMediaElement* mediaElement = toParentMediaElement(object); | 165 HTMLMediaElement* mediaElement = toParentMediaElement(object); | 
| 120 if (!mediaElement) | 166 if (!mediaElement) | 
| 121 return false; | 167 return false; | 
| 122 | 168 | 
| 123 if (!hasSource(mediaElement) || !mediaElement->togglePlayStateWillPlay()) | 169 if (!hasSource(mediaElement) || !mediaElement->togglePlayStateWillPlay()) | 
| 124 return false; | 170 return false; | 
| 125 | 171 | 
| 126 static Image* mediaOverlayPlay = platformResource("mediaplayerOverlayPlay"); | 172 static Image* mediaOverlayPlay = platformResource("mediaplayerOverlayPlay", | 
| 127 return paintMediaButton(paintInfo.context, rect, mediaOverlayPlay); | 173 "mediaplayerOverlayPlayNew"); | 
| 174 | |
| 175 IntRect buttonRect(rect); | |
| 176 if (RuntimeEnabledFeatures::newMediaPlaybackUiEnabled()) { | |
| 177 // Overlay play button is full-screen, so center. | |
| 178 buttonRect.setX(rect.center().x() - mediaOverlayPlayButtonWidthNew / 2); | |
| 179 buttonRect.setY(rect.center().y() - mediaOverlayPlayButtonHeightNew / 2) ; | |
| 180 buttonRect.setWidth(mediaOverlayPlayButtonWidthNew); | |
| 181 buttonRect.setHeight(mediaOverlayPlayButtonHeightNew); | |
| 182 } | |
| 183 | |
| 184 return paintMediaButton(paintInfo.context, buttonRect, mediaOverlayPlay); | |
| 128 } | 185 } | 
| 129 | 186 | 
| 130 static Image* getMediaSliderThumb() | 187 static Image* getMediaSliderThumb() | 
| 131 { | 188 { | 
| 132 static Image* mediaSliderThumb = platformResource("mediaplayerSliderThumb"); | 189 static Image* mediaSliderThumb = platformResource("mediaplayerSliderThumb", | 
| 190 "mediaplayerSliderThumbNew"); | |
| 133 return mediaSliderThumb; | 191 return mediaSliderThumb; | 
| 134 } | 192 } | 
| 135 | 193 | 
| 136 static void paintRoundedSliderBackground(const IntRect& rect, const ComputedStyl e&, GraphicsContext* context) | 194 static IntRect adjustSliderRectIfNewUi(const IntRect& rect, const ComputedStyle& style) | 
| 137 { | 195 { | 
| 138 int borderRadius = rect.height() / 2; | 196 // If we're using the new UI, create a short, vertically centered rect. | 
| 197 // We don't specify this in CSS because it makes touch targets harder. | |
| 198 // Instead, we just adjust the drawing rect. If we're not using the | |
| 199 // new UI, then do nothing. | |
| 200 if (!RuntimeEnabledFeatures::newMediaPlaybackUiEnabled()) | |
| 201 return rect; | |
| 202 | |
| 203 IntRect adjustedRect(rect); | |
| 204 float zoomedHeight = mediaSliderBarHeight * style.effectiveZoom(); | |
| 205 adjustedRect.setY(rect.center().y() - zoomedHeight / 2); | |
| 206 adjustedRect.setHeight(zoomedHeight); | |
| 207 | |
| 208 return adjustedRect; | |
| 209 } | |
| 210 | |
| 211 static void paintRoundedSliderBackground(const IntRect& rect, const ComputedStyl e& style, GraphicsContext* context, Color sliderBackgroundColor ) | |
| 212 { | |
| 213 IntRect adjustedRect(adjustSliderRectIfNewUi(rect, style)); | |
| 214 int borderRadius = adjustedRect.height() / 2; | |
| 139 IntSize radii(borderRadius, borderRadius); | 215 IntSize radii(borderRadius, borderRadius); | 
| 140 Color sliderBackgroundColor = Color(11, 11, 11); | 216 | 
| 141 context->fillRoundedRect(FloatRoundedRect(rect, radii, radii, radii, radii), sliderBackgroundColor); | 217 context->fillRoundedRect(FloatRoundedRect(adjustedRect, radii, radii, radii, radii), sliderBackgroundColor); | 
| 142 } | 218 } | 
| 143 | 219 | 
| 144 static void paintSliderRangeHighlight(const IntRect& rect, const ComputedStyle& style, GraphicsContext* context, int startPosition, int endPosition, Color start Color, Color endColor) | 220 static void paintSliderRangeHighlight(const IntRect& rect, const ComputedStyle& style, GraphicsContext* context, int startPosition, int endPosition, Color start Color, Color endColor) | 
| 145 { | 221 { | 
| 222 IntRect adjustedRect(adjustSliderRectIfNewUi(rect, style)); | |
| 223 | |
| 146 // Calculate border radius; need to avoid being smaller than half the slider height | 224 // Calculate border radius; need to avoid being smaller than half the slider height | 
| 147 // because of https://bugs.webkit.org/show_bug.cgi?id=30143. | 225 // because of https://bugs.webkit.org/show_bug.cgi?id=30143. | 
| 148 int borderRadius = rect.height() / 2; | 226 int borderRadius = adjustedRect.height() / 2; | 
| 149 IntSize radii(borderRadius, borderRadius); | 227 IntSize radii(borderRadius, borderRadius); | 
| 150 | 228 | 
| 151 // Calculate highlight rectangle and edge dimensions. | 229 // Calculate highlight rectangle and edge dimensions. | 
| 152 int startOffset = startPosition; | 230 int startOffset = startPosition; | 
| 153 int endOffset = rect.width() - endPosition; | 231 int endOffset = adjustedRect.width() - endPosition; | 
| 154 int rangeWidth = endPosition - startPosition; | 232 int rangeWidth = endPosition - startPosition; | 
| 155 | 233 | 
| 156 if (rangeWidth <= 0) | 234 if (rangeWidth <= 0) | 
| 157 return; | 235 return; | 
| 158 | 236 | 
| 159 // Make sure the range width is bigger than border radius at the edges to re tain rounded corners. | 237 // Make sure the range width is bigger than border radius at the edges to re tain rounded corners. | 
| 160 if (startOffset < borderRadius && rangeWidth < borderRadius) | 238 if (startOffset < borderRadius && rangeWidth < borderRadius) | 
| 161 rangeWidth = borderRadius; | 239 rangeWidth = borderRadius; | 
| 162 if (endOffset < borderRadius && rangeWidth < borderRadius) | 240 if (endOffset < borderRadius && rangeWidth < borderRadius) | 
| 163 rangeWidth = borderRadius; | 241 rangeWidth = borderRadius; | 
| 164 | 242 | 
| 165 // Set rectangle to highlight range. | 243 // Set rectangle to highlight range. | 
| 166 IntRect highlightRect = rect; | 244 IntRect highlightRect = adjustedRect; | 
| 167 highlightRect.move(startOffset, 0); | 245 highlightRect.move(startOffset, 0); | 
| 168 highlightRect.setWidth(rangeWidth); | 246 highlightRect.setWidth(rangeWidth); | 
| 169 | 247 | 
| 170 // Don't bother drawing an empty area. | 248 // Don't bother drawing an empty area. | 
| 171 if (highlightRect.isEmpty()) | 249 if (highlightRect.isEmpty()) | 
| 172 return; | 250 return; | 
| 173 | 251 | 
| 174 // Calculate white-grey gradient. | 252 // Calculate white-grey gradient. | 
| 175 IntPoint sliderTopLeft = highlightRect.location(); | 253 IntPoint sliderTopLeft = highlightRect.location(); | 
| 176 IntPoint sliderBottomLeft = sliderTopLeft; | 254 IntPoint sliderBottomLeft = sliderTopLeft; | 
| (...skipping 11 matching lines...) Expand all Loading... | |
| 188 else if (startOffset < borderRadius) | 266 else if (startOffset < borderRadius) | 
| 189 context->fillRoundedRect(FloatRoundedRect(highlightRect, radii, IntSize( 0, 0), radii, IntSize(0, 0)), startColor); | 267 context->fillRoundedRect(FloatRoundedRect(highlightRect, radii, IntSize( 0, 0), radii, IntSize(0, 0)), startColor); | 
| 190 else if (endOffset < borderRadius) | 268 else if (endOffset < borderRadius) | 
| 191 context->fillRoundedRect(FloatRoundedRect(highlightRect, IntSize(0, 0), radii, IntSize(0, 0), radii), startColor); | 269 context->fillRoundedRect(FloatRoundedRect(highlightRect, IntSize(0, 0), radii, IntSize(0, 0), radii), startColor); | 
| 192 else | 270 else | 
| 193 context->fillRect(highlightRect); | 271 context->fillRect(highlightRect); | 
| 194 | 272 | 
| 195 context->restore(); | 273 context->restore(); | 
| 196 } | 274 } | 
| 197 | 275 | 
| 198 const int mediaSliderThumbWidth = 32; | |
| 199 | |
| 200 bool MediaControlsPainter::paintMediaSlider(LayoutObject* object, const PaintInf o& paintInfo, const IntRect& rect) | 276 bool MediaControlsPainter::paintMediaSlider(LayoutObject* object, const PaintInf o& paintInfo, const IntRect& rect) | 
| 201 { | 277 { | 
| 202 HTMLMediaElement* mediaElement = toParentMediaElement(object); | 278 HTMLMediaElement* mediaElement = toParentMediaElement(object); | 
| 203 if (!mediaElement) | 279 if (!mediaElement) | 
| 204 return false; | 280 return false; | 
| 205 | 281 | 
| 282 GraphicsContext* context = paintInfo.context; | |
| 283 | |
| 284 // Should we paint the slider partially transparent? | |
| 285 bool drawUiGrayed = !hasSource(mediaElement) && RuntimeEnabledFeatures::newM ediaPlaybackUiEnabled(); | |
| 286 if (drawUiGrayed) | |
| 287 context->beginLayer(kDisabledAlpha); | |
| 288 | |
| 289 paintMediaSliderInternal(object, paintInfo, rect); | |
| 290 | |
| 291 if (drawUiGrayed) | |
| 292 context->endLayer(); | |
| 293 | |
| 294 return true; | |
| 295 } | |
| 296 | |
| 297 void MediaControlsPainter::paintMediaSliderInternal(LayoutObject* object, const PaintInfo& paintInfo, const IntRect& rect) | |
| 298 { | |
| 299 const bool useNewUi = RuntimeEnabledFeatures::newMediaPlaybackUiEnabled(); | |
| 300 HTMLMediaElement* mediaElement = toParentMediaElement(object); | |
| 301 if (!mediaElement) | |
| 302 return; | |
| 303 | |
| 206 const ComputedStyle& style = object->styleRef(); | 304 const ComputedStyle& style = object->styleRef(); | 
| 207 GraphicsContext* context = paintInfo.context; | 305 GraphicsContext* context = paintInfo.context; | 
| 208 | 306 | 
| 209 paintRoundedSliderBackground(rect, style, context); | 307 // Paint the slider bar in the "no data buffered" state. | 
| 308 Color sliderBackgroundColor; | |
| 309 if (!useNewUi) | |
| 310 sliderBackgroundColor = Color(11, 11, 11); | |
| 311 else | |
| 312 sliderBackgroundColor = Color(0xda, 0xda, 0xda); | |
| 313 | |
| 314 paintRoundedSliderBackground(rect, style, context, sliderBackgroundColor); | |
| 210 | 315 | 
| 211 // Draw the buffered range. Since the element may have multiple buffered ran ges and it'd be | 316 // Draw the buffered range. Since the element may have multiple buffered ran ges and it'd be | 
| 212 // distracting/'busy' to show all of them, show only the buffered range cont aining the current play head. | 317 // distracting/'busy' to show all of them, show only the buffered range cont aining the current play head. | 
| 213 RefPtrWillBeRawPtr<TimeRanges> bufferedTimeRanges = mediaElement->buffered() ; | 318 RefPtrWillBeRawPtr<TimeRanges> bufferedTimeRanges = mediaElement->buffered() ; | 
| 214 float duration = mediaElement->duration(); | 319 float duration = mediaElement->duration(); | 
| 215 float currentTime = mediaElement->currentTime(); | 320 float currentTime = mediaElement->currentTime(); | 
| 216 if (std::isnan(duration) || std::isinf(duration) || !duration || std::isnan( currentTime)) | 321 if (std::isnan(duration) || std::isinf(duration) || !duration || std::isnan( currentTime)) | 
| 217 return true; | 322 return; | 
| 218 | 323 | 
| 219 for (unsigned i = 0; i < bufferedTimeRanges->length(); ++i) { | 324 for (unsigned i = 0; i < bufferedTimeRanges->length(); ++i) { | 
| 220 float start = bufferedTimeRanges->start(i, ASSERT_NO_EXCEPTION); | 325 float start = bufferedTimeRanges->start(i, ASSERT_NO_EXCEPTION); | 
| 221 float end = bufferedTimeRanges->end(i, ASSERT_NO_EXCEPTION); | 326 float end = bufferedTimeRanges->end(i, ASSERT_NO_EXCEPTION); | 
| 222 // The delta is there to avoid corner cases when buffered | 327 // The delta is there to avoid corner cases when buffered | 
| 223 // ranges is out of sync with current time because of | 328 // ranges is out of sync with current time because of | 
| 224 // asynchronous media pipeline and current time caching in | 329 // asynchronous media pipeline and current time caching in | 
| 225 // HTMLMediaElement. | 330 // HTMLMediaElement. | 
| 226 // This is related to https://www.w3.org/Bugs/Public/show_bug.cgi?id=281 25 | 331 // This is related to https://www.w3.org/Bugs/Public/show_bug.cgi?id=281 25 | 
| 227 // FIXME: Remove this workaround when WebMediaPlayer | 332 // FIXME: Remove this workaround when WebMediaPlayer | 
| 228 // has an asynchronous pause interface. | 333 // has an asynchronous pause interface. | 
| 229 if (std::isnan(start) || std::isnan(end) | 334 if (std::isnan(start) || std::isnan(end) | 
| 230 || start > currentTime + kCurrentTimeBufferedDelta || end < currentT ime) | 335 || start > currentTime + kCurrentTimeBufferedDelta || end < currentT ime) | 
| 231 continue; | 336 continue; | 
| 232 int startPosition = int(start * rect.width() / duration); | 337 int startPosition = int(start * rect.width() / duration); | 
| 233 int currentPosition = int(currentTime * rect.width() / duration); | 338 int currentPosition = int(currentTime * rect.width() / duration); | 
| 234 int endPosition = int(end * rect.width() / duration); | 339 int endPosition = int(end * rect.width() / duration); | 
| 235 | 340 | 
| 236 // Add half the thumb width proportionally adjusted to the current paint ing position. | 341 if (!useNewUi) { | 
| 237 int thumbCenter = mediaSliderThumbWidth / 2; | 342 // Add half the thumb width proportionally adjusted to the current p ainting position. | 
| 238 int addWidth = thumbCenter * (1.0 - 2.0 * currentPosition / rect.width() ); | 343 int thumbCenter = mediaSliderThumbWidth / 2; | 
| 239 currentPosition += addWidth; | 344 int addWidth = thumbCenter * (1.0 - 2.0 * currentPosition / rect.wid th()); | 
| 345 currentPosition += addWidth; | |
| 346 } | |
| 240 | 347 | 
| 241 // Draw white-ish highlight before current time. | 348 // Draw highlight before current time. | 
| 242 Color startColor = Color(195, 195, 195); | 349 Color startColor; | 
| 243 Color endColor = Color(217, 217, 217); | 350 Color endColor; | 
| 351 if (!useNewUi) { | |
| 352 startColor = Color(195, 195, 195); // white-ish. | |
| 353 endColor = Color(217, 217, 217); | |
| 354 } else { | |
| 355 startColor = endColor = Color(0x42, 0x85, 0xf4); // blue. | |
| 356 } | |
| 357 | |
| 244 if (currentPosition > startPosition) | 358 if (currentPosition > startPosition) | 
| 245 paintSliderRangeHighlight(rect, style, context, startPosition, curre ntPosition, startColor, endColor); | 359 paintSliderRangeHighlight(rect, style, context, startPosition, curre ntPosition, startColor, endColor); | 
| 246 | 360 | 
| 247 // Draw grey-ish highlight after current time. | 361 // Draw grey-ish highlight after current time. | 
| 248 startColor = Color(60, 60, 60); | 362 if (!useNewUi) { | 
| 249 endColor = Color(76, 76, 76); | 363 startColor = Color(60, 60, 60); | 
| 364 endColor = Color(76, 76, 76); | |
| 365 } else { | |
| 366 startColor = endColor = Color(0x9f, 0x9f, 0x9f); // light grey. | |
| 367 } | |
| 250 | 368 | 
| 251 if (endPosition > currentPosition) | 369 if (endPosition > currentPosition) | 
| 252 paintSliderRangeHighlight(rect, style, context, currentPosition, end Position, startColor, endColor); | 370 paintSliderRangeHighlight(rect, style, context, currentPosition, end Position, startColor, endColor); | 
| 253 | 371 | 
| 254 return true; | 372 return; | 
| 373 } | |
| 374 } | |
| 375 | |
| 376 void MediaControlsPainter::adjustMediaSliderThumbPaintSize(const IntRect& rect, const ComputedStyle& style, IntRect& rectOut) | |
| 377 { | |
| 378 // Adjust the rectangle to be centered, the right size for the image. | |
| 379 // We do this because it's quite hard to get the thumb touch target | |
| 380 // to match. So, we provide the touch target size with | |
| 381 // adjustMediaSliderThumbSize(), and scale it back when we paint. | |
| 382 rectOut = rect; | |
| 383 | |
| 384 if (!RuntimeEnabledFeatures::newMediaPlaybackUiEnabled()) { | |
| 385 // ...except for the old UI. | |
| 386 return; | |
| 255 } | 387 } | 
| 256 | 388 | 
| 257 return true; | 389 float zoomLevel = style.effectiveZoom(); | 
| 390 int zoomedPaintWidth = mediaSliderThumbPaintWidthNew * zoomLevel; | |
| 391 int zoomedPaintHeight = mediaSliderThumbPaintHeightNew * zoomLevel; | |
| 392 | |
| 393 rectOut.setX(rect.center().x() - zoomedPaintWidth / 2); | |
| 394 rectOut.setY(rect.center().y() - zoomedPaintHeight / 2); | |
| 395 rectOut.setWidth(zoomedPaintWidth); | |
| 396 rectOut.setHeight(zoomedPaintHeight); | |
| 258 } | 397 } | 
| 259 | 398 | 
| 260 bool MediaControlsPainter::paintMediaSliderThumb(LayoutObject* object, const Pai ntInfo& paintInfo, const IntRect& rect) | 399 bool MediaControlsPainter::paintMediaSliderThumb(LayoutObject* object, const Pai ntInfo& paintInfo, const IntRect& rect) | 
| 261 { | 400 { | 
| 262 if (!object->node()) | 401 if (!object->node()) | 
| 263 return false; | 402 return false; | 
| 264 | 403 | 
| 265 HTMLMediaElement* mediaElement = toParentMediaElement(object->node()->shadow Host()); | 404 HTMLMediaElement* mediaElement = toParentMediaElement(object->node()->shadow Host()); | 
| 266 if (!mediaElement) | 405 if (!mediaElement) | 
| 267 return false; | 406 return false; | 
| 268 | 407 | 
| 269 if (!hasSource(mediaElement)) | 408 if (!hasSource(mediaElement)) | 
| 270 return true; | 409 return true; | 
| 271 | 410 | 
| 272 Image* mediaSliderThumb = getMediaSliderThumb(); | 411 Image* mediaSliderThumb = getMediaSliderThumb(); | 
| 273 return paintMediaButton(paintInfo.context, rect, mediaSliderThumb); | 412 IntRect paintRect; | 
| 413 const ComputedStyle& style = object->styleRef(); | |
| 414 adjustMediaSliderThumbPaintSize(rect, style, paintRect); | |
| 415 return paintMediaButton(paintInfo.context, paintRect, mediaSliderThumb); | |
| 274 } | 416 } | 
| 275 | 417 | 
| 276 const int mediaVolumeSliderThumbWidth = 24; | |
| 277 | |
| 278 bool MediaControlsPainter::paintMediaVolumeSlider(LayoutObject* object, const Pa intInfo& paintInfo, const IntRect& rect) | 418 bool MediaControlsPainter::paintMediaVolumeSlider(LayoutObject* object, const Pa intInfo& paintInfo, const IntRect& rect) | 
| 279 { | 419 { | 
| 280 HTMLMediaElement* mediaElement = toParentMediaElement(object); | 420 HTMLMediaElement* mediaElement = toParentMediaElement(object); | 
| 281 if (!mediaElement) | 421 if (!mediaElement) | 
| 282 return false; | 422 return false; | 
| 283 | 423 | 
| 284 GraphicsContext* context = paintInfo.context; | 424 GraphicsContext* context = paintInfo.context; | 
| 285 const ComputedStyle& style = object->styleRef(); | 425 const ComputedStyle& style = object->styleRef(); | 
| 286 | 426 | 
| 287 paintRoundedSliderBackground(rect, style, context); | 427 // Paint the slider bar. | 
| 428 Color sliderBackgroundColor; | |
| 429 if (!RuntimeEnabledFeatures::newMediaPlaybackUiEnabled()) | |
| 430 sliderBackgroundColor = Color(11, 11, 11); | |
| 431 else | |
| 432 sliderBackgroundColor = Color(0x9f, 0x9f, 0x9f); | |
| 433 paintRoundedSliderBackground(rect, style, context, sliderBackgroundColor); | |
| 288 | 434 | 
| 289 // Calculate volume position for white background rectangle. | 435 // Calculate volume position for white background rectangle. | 
| 290 float volume = mediaElement->volume(); | 436 float volume = mediaElement->volume(); | 
| 291 if (std::isnan(volume) || volume < 0) | 437 if (std::isnan(volume) || volume < 0) | 
| 292 return true; | 438 return true; | 
| 293 if (volume > 1) | 439 if (volume > 1) | 
| 294 volume = 1; | 440 volume = 1; | 
| 295 if (!hasSource(mediaElement) || !mediaElement->hasAudio() || mediaElement->m uted()) | 441 if (!hasSource(mediaElement) || !mediaElement->hasAudio() || mediaElement->m uted()) | 
| 296 volume = 0; | 442 volume = 0; | 
| 297 | 443 | 
| 298 // Calculate the position relative to the center of the thumb. | 444 // Calculate the position relative to the center of the thumb. | 
| 299 float fillWidth = 0; | 445 float fillWidth = 0; | 
| 300 if (volume > 0) { | 446 if (!RuntimeEnabledFeatures::newMediaPlaybackUiEnabled()) { | 
| 301 float thumbCenter = mediaVolumeSliderThumbWidth / 2; | 447 if (volume > 0) { | 
| 302 float zoomLevel = style.effectiveZoom(); | 448 float thumbCenter = mediaVolumeSliderThumbWidth / 2; | 
| 303 float positionWidth = volume * (rect.width() - (zoomLevel * thumbCenter) ); | 449 float zoomLevel = style.effectiveZoom(); | 
| 304 fillWidth = positionWidth + (zoomLevel * thumbCenter / 2); | 450 float positionWidth = volume * (rect.width() - (zoomLevel * thumbCen ter)); | 
| 451 fillWidth = positionWidth + (zoomLevel * thumbCenter / 2); | |
| 452 } | |
| 453 } else { | |
| 454 fillWidth = volume * rect.width(); | |
| 305 } | 455 } | 
| 306 | 456 | 
| 307 Color startColor = Color(195, 195, 195); | 457 Color startColor = Color(195, 195, 195); | 
| 308 Color endColor = Color(217, 217, 217); | 458 Color endColor = Color(217, 217, 217); | 
| 459 if (RuntimeEnabledFeatures::newMediaPlaybackUiEnabled()) | |
| 460 startColor = endColor = Color(0x42, 0x85, 0xf4); // blue. | |
| 309 | 461 | 
| 310 paintSliderRangeHighlight(rect, style, context, 0.0, fillWidth, startColor, endColor); | 462 paintSliderRangeHighlight(rect, style, context, 0.0, fillWidth, startColor, endColor); | 
| 311 | 463 | 
| 312 return true; | 464 return true; | 
| 313 } | 465 } | 
| 314 | 466 | 
| 315 bool MediaControlsPainter::paintMediaVolumeSliderThumb(LayoutObject* object, con st PaintInfo& paintInfo, const IntRect& rect) | 467 bool MediaControlsPainter::paintMediaVolumeSliderThumb(LayoutObject* object, con st PaintInfo& paintInfo, const IntRect& rect) | 
| 316 { | 468 { | 
| 317 if (!object->node()) | 469 if (!object->node()) | 
| 318 return false; | 470 return false; | 
| 319 | 471 | 
| 320 HTMLMediaElement* mediaElement = toParentMediaElement(object->node()->shadow Host()); | 472 HTMLMediaElement* mediaElement = toParentMediaElement(object->node()->shadow Host()); | 
| 321 if (!mediaElement) | 473 if (!mediaElement) | 
| 322 return false; | 474 return false; | 
| 323 | 475 | 
| 324 if (!hasSource(mediaElement) || !mediaElement->hasAudio()) | 476 if (!hasSource(mediaElement) || !mediaElement->hasAudio()) | 
| 325 return true; | 477 return true; | 
| 326 | 478 | 
| 327 static Image* mediaVolumeSliderThumb = platformResource("mediaplayerVolumeSl iderThumb"); | 479 static Image* mediaVolumeSliderThumb = platformResource( | 
| 328 return paintMediaButton(paintInfo.context, rect, mediaVolumeSliderThumb); | 480 "mediaplayerVolumeSliderThumb", | 
| 481 "mediaplayerVolumeSliderThumbNew"); | |
| 482 | |
| 483 IntRect paintRect; | |
| 484 const ComputedStyle& style = object->styleRef(); | |
| 485 adjustMediaSliderThumbPaintSize(rect, style, paintRect); | |
| 486 return paintMediaButton(paintInfo.context, paintRect, mediaVolumeSliderThumb ); | |
| 329 } | 487 } | 
| 330 | 488 | 
| 331 bool MediaControlsPainter::paintMediaFullscreenButton(LayoutObject* object, cons t PaintInfo& paintInfo, const IntRect& rect) | 489 bool MediaControlsPainter::paintMediaFullscreenButton(LayoutObject* object, cons t PaintInfo& paintInfo, const IntRect& rect) | 
| 332 { | 490 { | 
| 333 HTMLMediaElement* mediaElement = toParentMediaElement(object); | 491 HTMLMediaElement* mediaElement = toParentMediaElement(object); | 
| 334 if (!mediaElement) | 492 if (!mediaElement) | 
| 335 return false; | 493 return false; | 
| 336 | 494 | 
| 337 static Image* mediaFullscreenButton = platformResource("mediaplayerFullscree n"); | 495 // With the new player UI, we have separate assets for enter / exit | 
| 338 return paintMediaButton(paintInfo.context, rect, mediaFullscreenButton); | 496 // fullscreen mode. | 
| 497 static Image* mediaEnterFullscreenButton = platformResource( | |
| 498 "mediaplayerFullscreen", | |
| 499 "mediaplayerEnterFullscreen"); | |
| 500 static Image* mediaExitFullscreenButton = platformResource( | |
| 501 "mediaplayerFullscreen", | |
| 502 "mediaplayerExitFullscreen"); | |
| 503 | |
| 504 bool isEnabled = hasSource(mediaElement); | |
| 505 | |
| 506 if (mediaControlElementType(object->node()) == MediaExitFullscreenButton) | |
| 507 return paintMediaButton(paintInfo.context, rect, mediaExitFullscreenButt on, !isEnabled); | |
| 508 return paintMediaButton(paintInfo.context, rect, mediaEnterFullscreenButton, !isEnabled); | |
| 339 } | 509 } | 
| 340 | 510 | 
| 341 bool MediaControlsPainter::paintMediaToggleClosedCaptionsButton(LayoutObject* ob ject, const PaintInfo& paintInfo, const IntRect& rect) | 511 bool MediaControlsPainter::paintMediaToggleClosedCaptionsButton(LayoutObject* ob ject, const PaintInfo& paintInfo, const IntRect& rect) | 
| 342 { | 512 { | 
| 343 HTMLMediaElement* mediaElement = toParentMediaElement(object); | 513 HTMLMediaElement* mediaElement = toParentMediaElement(object); | 
| 344 if (!mediaElement) | 514 if (!mediaElement) | 
| 345 return false; | 515 return false; | 
| 346 | 516 | 
| 347 static Image* mediaClosedCaptionButton = platformResource("mediaplayerClosed Caption"); | 517 static Image* mediaClosedCaptionButton = platformResource( | 
| 348 static Image* mediaClosedCaptionButtonDisabled = platformResource("mediaplay erClosedCaptionDisabled"); | 518 "mediaplayerClosedCaption", "mediaplayerClosedCaptionNew"); | 
| 519 static Image* mediaClosedCaptionButtonDisabled = platformResource( | |
| 520 "mediaplayerClosedCaptionDisabled", | |
| 521 "mediaplayerClosedCaptionDisabledNew"); | |
| 522 | |
| 523 bool isEnabled = hasSource(mediaElement); | |
| 349 | 524 | 
| 350 if (mediaElement->closedCaptionsVisible()) | 525 if (mediaElement->closedCaptionsVisible()) | 
| 351 return paintMediaButton(paintInfo.context, rect, mediaClosedCaptionButto n); | 526 return paintMediaButton(paintInfo.context, rect, mediaClosedCaptionButto n, !isEnabled); | 
| 352 | 527 | 
| 353 return paintMediaButton(paintInfo.context, rect, mediaClosedCaptionButtonDis abled); | 528 return paintMediaButton(paintInfo.context, rect, mediaClosedCaptionButtonDis abled, !isEnabled); | 
| 354 } | 529 } | 
| 355 | 530 | 
| 356 bool MediaControlsPainter::paintMediaCastButton(LayoutObject* object, const Pain tInfo& paintInfo, const IntRect& rect) | 531 bool MediaControlsPainter::paintMediaCastButton(LayoutObject* object, const Pain tInfo& paintInfo, const IntRect& rect) | 
| 357 { | 532 { | 
| 358 HTMLMediaElement* mediaElement = toParentMediaElement(object); | 533 HTMLMediaElement* mediaElement = toParentMediaElement(object); | 
| 359 if (!mediaElement) | 534 if (!mediaElement) | 
| 360 return false; | 535 return false; | 
| 361 | 536 | 
| 362 static Image* mediaCastOn = platformResource("mediaplayerCastOn"); | 537 static Image* mediaCastOn = platformResource("mediaplayerCastOn", "mediaplay erCastOnNew"); | 
| 363 static Image* mediaCastOff = platformResource("mediaplayerCastOff"); | 538 static Image* mediaCastOff = platformResource("mediaplayerCastOff", "mediapl ayerCastOffNew"); | 
| 364 // To ensure that the overlaid cast button is visible when overlaid on pale videos we use a | 539 // To ensure that the overlaid cast button is visible when overlaid on pale videos we use a | 
| 365 // different version of it for the overlaid case with a semi-opaque backgrou nd. | 540 // different version of it for the overlaid case with a semi-opaque backgrou nd. | 
| 366 static Image* mediaOverlayCastOff = platformResource("mediaplayerOverlayCast Off"); | 541 static Image* mediaOverlayCastOff = platformResource( | 
| 542 "mediaplayerOverlayCastOff", | |
| 543 "mediaplayerOverlayCastOffNew"); | |
| 544 | |
| 545 bool isEnabled = hasSource(mediaElement); | |
| 367 | 546 | 
| 368 switch (mediaControlElementType(object->node())) { | 547 switch (mediaControlElementType(object->node())) { | 
| 369 case MediaCastOnButton: | 548 case MediaCastOnButton: | 
| 549 return paintMediaButton(paintInfo.context, rect, mediaCastOn, !isEnabled ); | |
| 370 case MediaOverlayCastOnButton: | 550 case MediaOverlayCastOnButton: | 
| 371 return paintMediaButton(paintInfo.context, rect, mediaCastOn); | 551 return paintMediaButton(paintInfo.context, rect, mediaCastOn); | 
| 372 case MediaCastOffButton: | 552 case MediaCastOffButton: | 
| 373 return paintMediaButton(paintInfo.context, rect, mediaCastOff); | 553 return paintMediaButton(paintInfo.context, rect, mediaCastOff, !isEnable d); | 
| 374 case MediaOverlayCastOffButton: | 554 case MediaOverlayCastOffButton: | 
| 375 return paintMediaButton(paintInfo.context, rect, mediaOverlayCastOff); | 555 return paintMediaButton(paintInfo.context, rect, mediaOverlayCastOff); | 
| 376 default: | 556 default: | 
| 377 ASSERT_NOT_REACHED(); | 557 ASSERT_NOT_REACHED(); | 
| 378 return false; | 558 return false; | 
| 379 } | 559 } | 
| 380 } | 560 } | 
| 381 | 561 | 
| 382 const int mediaSliderThumbHeight = 24; | |
| 383 const int mediaVolumeSliderThumbHeight = 24; | |
| 384 | |
| 385 void MediaControlsPainter::adjustMediaSliderThumbSize(ComputedStyle& style) | 562 void MediaControlsPainter::adjustMediaSliderThumbSize(ComputedStyle& style) | 
| 386 { | 563 { | 
| 387 static Image* mediaSliderThumb = platformResource("mediaplayerSliderThumb"); | 564 static Image* mediaSliderThumb = platformResource("mediaplayerSliderThumb", | 
| 388 static Image* mediaVolumeSliderThumb = platformResource("mediaplayerVolumeSl iderThumb"); | 565 "mediaplayerSliderThumbNew"); | 
| 566 static Image* mediaVolumeSliderThumb = platformResource( | |
| 567 "mediaplayerVolumeSliderThumb", | |
| 568 "mediaplayerVolumeSliderThumbNew"); | |
| 389 int width = 0; | 569 int width = 0; | 
| 390 int height = 0; | 570 int height = 0; | 
| 391 | 571 | 
| 392 Image* thumbImage = 0; | 572 Image* thumbImage = 0; | 
| 393 if (style.appearance() == MediaSliderThumbPart) { | 573 | 
| 574 if (RuntimeEnabledFeatures::newMediaPlaybackUiEnabled()) { | |
| 575 // Volume and time sliders are the same. | |
| 576 thumbImage = mediaSliderThumb; | |
| 577 width = mediaSliderThumbTouchWidthNew; | |
| 578 height = mediaSliderThumbTouchHeightNew; | |
| 579 } else if (style.appearance() == MediaSliderThumbPart) { | |
| 394 thumbImage = mediaSliderThumb; | 580 thumbImage = mediaSliderThumb; | 
| 395 width = mediaSliderThumbWidth; | 581 width = mediaSliderThumbWidth; | 
| 396 height = mediaSliderThumbHeight; | 582 height = mediaSliderThumbHeight; | 
| 397 } else if (style.appearance() == MediaVolumeSliderThumbPart) { | 583 } else if (style.appearance() == MediaVolumeSliderThumbPart) { | 
| 398 thumbImage = mediaVolumeSliderThumb; | 584 thumbImage = mediaVolumeSliderThumb; | 
| 399 width = mediaVolumeSliderThumbWidth; | 585 width = mediaVolumeSliderThumbWidth; | 
| 400 height = mediaVolumeSliderThumbHeight; | 586 height = mediaVolumeSliderThumbHeight; | 
| 401 } | 587 } | 
| 402 | 588 | 
| 403 float zoomLevel = style.effectiveZoom(); | 589 float zoomLevel = style.effectiveZoom(); | 
| 404 if (thumbImage) { | 590 if (thumbImage) { | 
| 405 style.setWidth(Length(static_cast<int>(width * zoomLevel), Fixed)); | 591 style.setWidth(Length(static_cast<int>(width * zoomLevel), Fixed)); | 
| 406 style.setHeight(Length(static_cast<int>(height * zoomLevel), Fixed)); | 592 style.setHeight(Length(static_cast<int>(height * zoomLevel), Fixed)); | 
| 407 } | 593 } | 
| 408 } | 594 } | 
| 409 | 595 | 
| 410 } // namespace blink | 596 } // namespace blink | 
| OLD | NEW |