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