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

Side by Side Diff: Source/core/rendering/RenderMediaControlsChromium.cpp

Issue 25699002: Rename RenderMediaControlsChromium to RenderMediaControls (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 /*
2 * Copyright (C) 2009 Apple Inc.
3 * Copyright (C) 2009 Google Inc.
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
16 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
19 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
23 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28 #include "config.h"
29 #include "core/rendering/RenderMediaControlsChromium.h"
30
31 #include "bindings/v8/ExceptionStatePlaceholder.h"
32 #include "core/html/HTMLMediaElement.h"
33 #include "core/html/TimeRanges.h"
34 #include "core/platform/graphics/Gradient.h"
35 #include "core/platform/graphics/GraphicsContext.h"
36 #include "core/rendering/PaintInfo.h"
37
38 namespace WebCore {
39
40 typedef WTF::HashMap<const char*, Image*> MediaControlImageMap;
41 static MediaControlImageMap* gMediaControlImageMap = 0;
42
43 static Image* platformResource(const char* name)
44 {
45 if (!gMediaControlImageMap)
46 gMediaControlImageMap = new MediaControlImageMap();
47 if (Image* image = gMediaControlImageMap->get(name))
48 return image;
49 if (Image* image = Image::loadPlatformResource(name).leakRef()) {
50 gMediaControlImageMap->set(name, image);
51 return image;
52 }
53 ASSERT_NOT_REACHED();
54 return 0;
55 }
56
57 static bool hasSource(const HTMLMediaElement* mediaElement)
58 {
59 return mediaElement->networkState() != HTMLMediaElement::NETWORK_EMPTY
60 && mediaElement->networkState() != HTMLMediaElement::NETWORK_NO_SOURCE;
61 }
62
63 static bool paintMediaButton(GraphicsContext* context, const IntRect& rect, Imag e* image)
64 {
65 context->drawImage(image, rect);
66 return true;
67 }
68
69 static bool paintMediaMuteButton(RenderObject* object, const PaintInfo& paintInf o, const IntRect& rect)
70 {
71 HTMLMediaElement* mediaElement = toParentMediaElement(object);
72 if (!mediaElement)
73 return false;
74
75 static Image* soundLevel3 = platformResource("mediaplayerSoundLevel3");
76 static Image* soundLevel2 = platformResource("mediaplayerSoundLevel2");
77 static Image* soundLevel1 = platformResource("mediaplayerSoundLevel1");
78 static Image* soundLevel0 = platformResource("mediaplayerSoundLevel0");
79 static Image* soundDisabled = platformResource("mediaplayerSoundDisabled");
80
81 if (!hasSource(mediaElement) || !mediaElement->hasAudio())
82 return paintMediaButton(paintInfo.context, rect, soundDisabled);
83
84 if (mediaElement->muted() || mediaElement->volume() <= 0)
85 return paintMediaButton(paintInfo.context, rect, soundLevel0);
86
87 if (mediaElement->volume() <= 0.33)
88 return paintMediaButton(paintInfo.context, rect, soundLevel1);
89
90 if (mediaElement->volume() <= 0.66)
91 return paintMediaButton(paintInfo.context, rect, soundLevel2);
92
93 return paintMediaButton(paintInfo.context, rect, soundLevel3);
94 }
95
96 static bool paintMediaPlayButton(RenderObject* object, const PaintInfo& paintInf o, const IntRect& rect)
97 {
98 HTMLMediaElement* mediaElement = toParentMediaElement(object);
99 if (!mediaElement)
100 return false;
101
102 static Image* mediaPlay = platformResource("mediaplayerPlay");
103 static Image* mediaPause = platformResource("mediaplayerPause");
104 static Image* mediaPlayDisabled = platformResource("mediaplayerPlayDisabled" );
105
106 if (!hasSource(mediaElement))
107 return paintMediaButton(paintInfo.context, rect, mediaPlayDisabled);
108
109 return paintMediaButton(paintInfo.context, rect, mediaElement->canPlay() ? m ediaPlay : mediaPause);
110 }
111
112 static bool paintMediaOverlayPlayButton(RenderObject* object, const PaintInfo& p aintInfo, const IntRect& rect)
113 {
114 HTMLMediaElement* mediaElement = toParentMediaElement(object);
115 if (!mediaElement)
116 return false;
117
118 if (!hasSource(mediaElement) || !mediaElement->canPlay())
119 return false;
120
121 static Image* mediaOverlayPlay = platformResource("mediaplayerOverlayPlay");
122 return paintMediaButton(paintInfo.context, rect, mediaOverlayPlay);
123 }
124
125 static Image* getMediaSliderThumb()
126 {
127 static Image* mediaSliderThumb = platformResource("mediaplayerSliderThumb");
128 return mediaSliderThumb;
129 }
130
131 static void paintRoundedSliderBackground(const IntRect& rect, const RenderStyle* style, GraphicsContext* context)
132 {
133 int borderRadius = rect.height() / 2;
134 IntSize radii(borderRadius, borderRadius);
135 Color sliderBackgroundColor = Color(11, 11, 11);
136 context->save();
137 context->fillRoundedRect(rect, radii, radii, radii, radii, sliderBackgroundC olor);
138 context->restore();
139 }
140
141 static void paintSliderRangeHighlight(const IntRect& rect, const RenderStyle* st yle, GraphicsContext* context, int startPosition, int endPosition, Color startCo lor, Color endColor)
142 {
143 // Calculate border radius; need to avoid being smaller than half the slider height
144 // because of https://bugs.webkit.org/show_bug.cgi?id=30143.
145 int borderRadius = rect.height() / 2;
146 IntSize radii(borderRadius, borderRadius);
147
148 // Calculate highlight rectangle and edge dimensions.
149 int startOffset = startPosition;
150 int endOffset = rect.width() - endPosition;
151 int rangeWidth = endPosition - startPosition;
152
153 if (rangeWidth <= 0)
154 return;
155
156 // Make sure the range width is bigger than border radius at the edges to re tain rounded corners.
157 if (startOffset < borderRadius && rangeWidth < borderRadius)
158 rangeWidth = borderRadius;
159 if (endOffset < borderRadius && rangeWidth < borderRadius) {
160 startPosition -= borderRadius - rangeWidth;
161 rangeWidth = borderRadius;
162 }
163
164 // Set rectangle to highlight range.
165 IntRect highlightRect = rect;
166 highlightRect.move(startOffset, 0);
167 highlightRect.setWidth(rangeWidth);
168
169 // Don't bother drawing an empty area.
170 if (highlightRect.isEmpty())
171 return;
172
173 // Calculate white-grey gradient.
174 IntPoint sliderTopLeft = highlightRect.location();
175 IntPoint sliderBottomLeft = sliderTopLeft;
176 sliderBottomLeft.move(0, highlightRect.height());
177 RefPtr<Gradient> gradient = Gradient::create(sliderTopLeft, sliderBottomLeft );
178 gradient->addColorStop(0.0, startColor);
179 gradient->addColorStop(1.0, endColor);
180
181 // Fill highlight rectangle with gradient, potentially rounded if on left or right edge.
182 context->save();
183 context->setFillGradient(gradient);
184
185 if (startOffset < borderRadius && endOffset < borderRadius)
186 context->fillRoundedRect(highlightRect, radii, radii, radii, radii, star tColor);
187 else if (startOffset < borderRadius)
188 context->fillRoundedRect(highlightRect, radii, IntSize(0, 0), radii, Int Size(0, 0), startColor);
189 else if (endOffset < borderRadius)
190 context->fillRoundedRect(highlightRect, IntSize(0, 0), radii, IntSize(0, 0), radii, startColor);
191 else
192 context->fillRect(highlightRect);
193
194 context->restore();
195 }
196
197 const int mediaSliderThumbWidth = 32;
198
199 static bool paintMediaSlider(RenderObject* object, const PaintInfo& paintInfo, c onst IntRect& rect)
200 {
201 HTMLMediaElement* mediaElement = toParentMediaElement(object);
202 if (!mediaElement)
203 return false;
204
205 RenderStyle* style = object->style();
206 GraphicsContext* context = paintInfo.context;
207
208 paintRoundedSliderBackground(rect, style, context);
209
210 // Draw the buffered range. Since the element may have multiple buffered ran ges and it'd be
211 // distracting/'busy' to show all of them, show only the buffered range cont aining the current play head.
212 RefPtr<TimeRanges> bufferedTimeRanges = mediaElement->buffered();
213 float duration = mediaElement->duration();
214 float currentTime = mediaElement->currentTime();
215 if (std::isnan(duration) || std::isinf(duration) || !duration || std::isnan( currentTime))
216 return true;
217
218 for (unsigned i = 0; i < bufferedTimeRanges->length(); ++i) {
219 float start = bufferedTimeRanges->start(i, ASSERT_NO_EXCEPTION);
220 float end = bufferedTimeRanges->end(i, ASSERT_NO_EXCEPTION);
221 if (std::isnan(start) || std::isnan(end) || start > currentTime || end < currentTime)
222 continue;
223 int startPosition = int(start * rect.width() / duration);
224 int currentPosition = int(currentTime * rect.width() / duration);
225 int endPosition = int(end * rect.width() / duration);
226
227 // Add half the thumb width proportionally adjusted to the current paint ing position.
228 int thumbCenter = mediaSliderThumbWidth / 2;
229 int addWidth = thumbCenter * (1.0 - 2.0 * currentPosition / rect.width() );
230 currentPosition += addWidth;
231
232 // Draw white-ish highlight before current time.
233 Color startColor = Color(195, 195, 195);
234 Color endColor = Color(217, 217, 217);
235 if (currentPosition > startPosition)
236 paintSliderRangeHighlight(rect, style, context, startPosition, curre ntPosition, startColor, endColor);
237
238 // Draw grey-ish highlight after current time.
239 startColor = Color(60, 60, 60);
240 endColor = Color(76, 76, 76);
241
242 if (endPosition > currentPosition)
243 paintSliderRangeHighlight(rect, style, context, currentPosition, end Position, startColor, endColor);
244
245 return true;
246 }
247
248 return true;
249 }
250
251 static bool paintMediaSliderThumb(RenderObject* object, const PaintInfo& paintIn fo, const IntRect& rect)
252 {
253 ASSERT(object->node());
254 HTMLMediaElement* mediaElement = toParentMediaElement(object->node()->shadow Host());
255 if (!mediaElement)
256 return false;
257
258 if (!hasSource(mediaElement))
259 return true;
260
261 Image* mediaSliderThumb = getMediaSliderThumb();
262 return paintMediaButton(paintInfo.context, rect, mediaSliderThumb);
263 }
264
265 const int mediaVolumeSliderThumbWidth = 24;
266
267 static bool paintMediaVolumeSlider(RenderObject* object, const PaintInfo& paintI nfo, const IntRect& rect)
268 {
269 HTMLMediaElement* mediaElement = toParentMediaElement(object);
270 if (!mediaElement)
271 return false;
272
273 GraphicsContext* context = paintInfo.context;
274 RenderStyle* style = object->style();
275
276 paintRoundedSliderBackground(rect, style, context);
277
278 // Calculate volume position for white background rectangle.
279 float volume = mediaElement->volume();
280 if (std::isnan(volume) || volume < 0)
281 return true;
282 if (volume > 1)
283 volume = 1;
284 if (!hasSource(mediaElement) || !mediaElement->hasAudio() || mediaElement->m uted())
285 volume = 0;
286
287 // Calculate the position relative to the center of the thumb.
288 float fillWidth = 0;
289 if (volume > 0) {
290 float thumbCenter = mediaVolumeSliderThumbWidth / 2;
291 float zoomLevel = style->effectiveZoom();
292 float positionWidth = volume * (rect.width() - (zoomLevel * thumbCenter) );
293 fillWidth = positionWidth + (zoomLevel * thumbCenter / 2);
294 }
295
296 Color startColor = Color(195, 195, 195);
297 Color endColor = Color(217, 217, 217);
298
299 paintSliderRangeHighlight(rect, style, context, 0.0, fillWidth, startColor, endColor);
300
301 return true;
302 }
303
304 static bool paintMediaVolumeSliderThumb(RenderObject* object, const PaintInfo& p aintInfo, const IntRect& rect)
305 {
306 ASSERT(object->node());
307 HTMLMediaElement* mediaElement = toParentMediaElement(object->node()->shadow Host());
308 if (!mediaElement)
309 return false;
310
311 if (!hasSource(mediaElement) || !mediaElement->hasAudio())
312 return true;
313
314 static Image* mediaVolumeSliderThumb = platformResource("mediaplayerVolumeSl iderThumb");
315 return paintMediaButton(paintInfo.context, rect, mediaVolumeSliderThumb);
316 }
317
318 static bool paintMediaFullscreenButton(RenderObject* object, const PaintInfo& pa intInfo, const IntRect& rect)
319 {
320 HTMLMediaElement* mediaElement = toParentMediaElement(object);
321 if (!mediaElement)
322 return false;
323
324 static Image* mediaFullscreenButton = platformResource("mediaplayerFullscree n");
325 return paintMediaButton(paintInfo.context, rect, mediaFullscreenButton);
326 }
327
328 static bool paintMediaToggleClosedCaptionsButton(RenderObject* object, const Pai ntInfo& paintInfo, const IntRect& rect)
329 {
330 HTMLMediaElement* mediaElement = toParentMediaElement(object);
331 if (!mediaElement)
332 return false;
333
334 static Image* mediaClosedCaptionButton = platformResource("mediaplayerClosed Caption");
335 static Image* mediaClosedCaptionButtonDisabled = platformResource("mediaplay erClosedCaptionDisabled");
336
337 if (mediaElement->webkitClosedCaptionsVisible())
338 return paintMediaButton(paintInfo.context, rect, mediaClosedCaptionButto n);
339
340 return paintMediaButton(paintInfo.context, rect, mediaClosedCaptionButtonDis abled);
341 }
342
343
344 bool RenderMediaControlsChromium::paintMediaControlsPart(MediaControlElementType part, RenderObject* object, const PaintInfo& paintInfo, const IntRect& rect)
345 {
346 switch (part) {
347 case MediaMuteButton:
348 case MediaUnMuteButton:
349 return paintMediaMuteButton(object, paintInfo, rect);
350 case MediaPauseButton:
351 case MediaPlayButton:
352 return paintMediaPlayButton(object, paintInfo, rect);
353 case MediaShowClosedCaptionsButton:
354 return paintMediaToggleClosedCaptionsButton(object, paintInfo, rect);
355 case MediaSlider:
356 return paintMediaSlider(object, paintInfo, rect);
357 case MediaSliderThumb:
358 return paintMediaSliderThumb(object, paintInfo, rect);
359 case MediaVolumeSlider:
360 return paintMediaVolumeSlider(object, paintInfo, rect);
361 case MediaVolumeSliderThumb:
362 return paintMediaVolumeSliderThumb(object, paintInfo, rect);
363 case MediaEnterFullscreenButton:
364 case MediaExitFullscreenButton:
365 return paintMediaFullscreenButton(object, paintInfo, rect);
366 case MediaOverlayPlayButton:
367 return paintMediaOverlayPlayButton(object, paintInfo, rect);
368 case MediaVolumeSliderMuteButton:
369 case MediaSeekBackButton:
370 case MediaSeekForwardButton:
371 case MediaVolumeSliderContainer:
372 case MediaTimelineContainer:
373 case MediaCurrentTimeDisplay:
374 case MediaTimeRemainingDisplay:
375 case MediaControlsPanel:
376 case MediaRewindButton:
377 case MediaReturnToRealtimeButton:
378 case MediaStatusDisplay:
379 case MediaHideClosedCaptionsButton:
380 case MediaTextTrackDisplayContainer:
381 case MediaTextTrackDisplay:
382 case MediaFullScreenVolumeSlider:
383 case MediaFullScreenVolumeSliderThumb:
384 ASSERT_NOT_REACHED();
385 break;
386 }
387 return false;
388 }
389
390 const int mediaSliderThumbHeight = 24;
391 const int mediaVolumeSliderThumbHeight = 24;
392
393 void RenderMediaControlsChromium::adjustMediaSliderThumbSize(RenderStyle* style)
394 {
395 static Image* mediaSliderThumb = platformResource("mediaplayerSliderThumb");
396 static Image* mediaVolumeSliderThumb = platformResource("mediaplayerVolumeSl iderThumb");
397 int width = 0;
398 int height = 0;
399
400 Image* thumbImage = 0;
401 if (style->appearance() == MediaSliderThumbPart) {
402 thumbImage = mediaSliderThumb;
403 width = mediaSliderThumbWidth;
404 height = mediaSliderThumbHeight;
405 } else if (style->appearance() == MediaVolumeSliderThumbPart) {
406 thumbImage = mediaVolumeSliderThumb;
407 width = mediaVolumeSliderThumbWidth;
408 height = mediaVolumeSliderThumbHeight;
409 }
410
411 float zoomLevel = style->effectiveZoom();
412 if (thumbImage) {
413 style->setWidth(Length(static_cast<int>(width * zoomLevel), Fixed));
414 style->setHeight(Length(static_cast<int>(height * zoomLevel), Fixed));
415 }
416 }
417
418 static String formatChromiumMediaControlsTime(float time, float duration)
419 {
420 if (!std::isfinite(time))
421 time = 0;
422 if (!std::isfinite(duration))
423 duration = 0;
424 int seconds = static_cast<int>(fabsf(time));
425 int hours = seconds / (60 * 60);
426 int minutes = (seconds / 60) % 60;
427 seconds %= 60;
428
429 // duration defines the format of how the time is rendered
430 int durationSecs = static_cast<int>(fabsf(duration));
431 int durationHours = durationSecs / (60 * 60);
432 int durationMins = (durationSecs / 60) % 60;
433
434 if (durationHours || hours)
435 return String::format("%s%01d:%02d:%02d", (time < 0 ? "-" : ""), hours, minutes, seconds);
436 if (durationMins > 9)
437 return String::format("%s%02d:%02d", (time < 0 ? "-" : ""), minutes, sec onds);
438
439 return String::format("%s%01d:%02d", (time < 0 ? "-" : ""), minutes, seconds );
440 }
441
442 String RenderMediaControlsChromium::formatMediaControlsTime(float time)
443 {
444 return formatChromiumMediaControlsTime(time, time);
445 }
446
447 String RenderMediaControlsChromium::formatMediaControlsCurrentTime(float current Time, float duration)
448 {
449 return formatChromiumMediaControlsTime(currentTime, duration);
450 }
451
452 } // namespace WebCore
OLDNEW
« no previous file with comments | « Source/core/rendering/RenderMediaControlsChromium.h ('k') | Source/core/rendering/RenderThemeChromiumAndroid.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698