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

Side by Side Diff: Source/core/html/shadow/MediaControls.cpp

Issue 1156993013: New media playback UI. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: cleaned up volume / mute hiding logic. Created 5 years, 5 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
1 /* 1 /*
2 * Copyright (C) 2011, 2012 Apple Inc. All rights reserved. 2 * Copyright (C) 2011, 2012 Apple Inc. All rights reserved.
3 * Copyright (C) 2011, 2012 Google Inc. All rights reserved. 3 * Copyright (C) 2011, 2012 Google Inc. All rights reserved.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
7 * are met: 7 * are met:
8 * 1. Redistributions of source code must retain the above copyright 8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
(...skipping 29 matching lines...) Expand all
40 40
41 // If you change this value, then also update the corresponding value in 41 // If you change this value, then also update the corresponding value in
42 // LayoutTests/media/media-controls.js. 42 // LayoutTests/media/media-controls.js.
43 static const double timeWithoutMouseMovementBeforeHidingMediaControls = 3; 43 static const double timeWithoutMouseMovementBeforeHidingMediaControls = 3;
44 44
45 static bool fullscreenIsSupported(const Document& document) 45 static bool fullscreenIsSupported(const Document& document)
46 { 46 {
47 return !document.settings() || document.settings()->fullscreenSupported(); 47 return !document.settings() || document.settings()->fullscreenSupported();
48 } 48 }
49 49
50 static bool preferHiddenVolumeSlider(const Document& document)
51 {
52 return !document.settings() || document.settings()->preferHiddenVolumeSlider ();
53 }
54
55 static bool preferHiddenMuteButton(const Document& document)
56 {
57 return !document.settings() || document.settings()->preferHiddenMuteButton() ;
58 }
59
60 static bool allowHiddenAudioElements(const Document& document)
61 {
62 // The new UI always allows this. The old one doesn't, but it's
63 // convenient for tests if it can enable it. This isn't included in the
64 // prefer...() functions because we have three different outcomes,
65 // especially for the mute button.
66 return RuntimeEnabledFeatures::newMediaPlaybackUiEnabled()
67 || (document.settings() && document.settings()->forceAllowHiddenAudioEle ments());
68 }
69
50 MediaControls::MediaControls(HTMLMediaElement& mediaElement) 70 MediaControls::MediaControls(HTMLMediaElement& mediaElement)
51 : HTMLDivElement(mediaElement.document()) 71 : HTMLDivElement(mediaElement.document())
52 , m_mediaElement(&mediaElement) 72 , m_mediaElement(&mediaElement)
53 , m_overlayEnclosure(nullptr) 73 , m_overlayEnclosure(nullptr)
54 , m_overlayPlayButton(nullptr) 74 , m_overlayPlayButton(nullptr)
55 , m_overlayCastButton(nullptr) 75 , m_overlayCastButton(nullptr)
56 , m_enclosure(nullptr) 76 , m_enclosure(nullptr)
57 , m_panel(nullptr) 77 , m_panel(nullptr)
58 , m_playButton(nullptr) 78 , m_playButton(nullptr)
59 , m_timeline(nullptr) 79 , m_timeline(nullptr)
60 , m_currentTimeDisplay(nullptr) 80 , m_currentTimeDisplay(nullptr)
61 , m_durationDisplay(nullptr) 81 , m_durationDisplay(nullptr)
62 , m_muteButton(nullptr) 82 , m_muteButton(nullptr)
63 , m_volumeSlider(nullptr) 83 , m_volumeSlider(nullptr)
64 , m_toggleClosedCaptionsButton(nullptr) 84 , m_toggleClosedCaptionsButton(nullptr)
65 , m_castButton(nullptr) 85 , m_castButton(nullptr)
66 , m_fullScreenButton(nullptr) 86 , m_fullScreenButton(nullptr)
67 , m_hideMediaControlsTimer(this, &MediaControls::hideMediaControlsTimerFired ) 87 , m_hideMediaControlsTimer(this, &MediaControls::hideMediaControlsTimerFired )
68 , m_hideTimerBehaviorFlags(IgnoreNone) 88 , m_hideTimerBehaviorFlags(IgnoreNone)
69 , m_isMouseOverControls(false) 89 , m_isMouseOverControls(false)
70 , m_isPausedForScrubbing(false) 90 , m_isPausedForScrubbing(false)
91 , m_panelWidthChangedTimer(this, &MediaControls::panelWidthChangedTimerFired )
92 , m_panelWidth(0)
71 { 93 {
72 } 94 }
73 95
74 PassRefPtrWillBeRawPtr<MediaControls> MediaControls::create(HTMLMediaElement& me diaElement) 96 PassRefPtrWillBeRawPtr<MediaControls> MediaControls::create(HTMLMediaElement& me diaElement)
75 { 97 {
76 RefPtrWillBeRawPtr<MediaControls> controls = adoptRefWillBeNoop(new MediaCon trols(mediaElement)); 98 RefPtrWillBeRawPtr<MediaControls> controls = adoptRefWillBeNoop(new MediaCon trols(mediaElement));
77 controls->setShadowPseudoId(AtomicString("-webkit-media-controls", AtomicStr ing::ConstructFromLiteral)); 99 controls->setShadowPseudoId(AtomicString("-webkit-media-controls", AtomicStr ing::ConstructFromLiteral));
78 controls->initializeControls(); 100 controls->initializeControls();
79 return controls.release(); 101 return controls.release();
80 } 102 }
81 103
82 // The media controls DOM structure looks like: 104 // The media controls DOM structure looks like:
83 // 105 //
84 // MediaControls (-webkit-media-controls) 106 // MediaControls (-webkit-media-controls)
85 // +-MediaControlOverlayEnclosureElement (-webkit-media-controls-o verlay-enclosure) 107 // +-MediaControlOverlayEnclosureElement (-webkit-media-controls-o verlay-enclosure)
86 // | +-MediaControlOverlayPlayButtonElement (-webkit-media-controls-o verlay-play-button) 108 // | +-MediaControlOverlayPlayButtonElement (-webkit-media-controls-o verlay-play-button)
87 // | | {if mediaControlsOverlayPlayButtonEnabled} 109 // | | {if mediaControlsOverlayPlayButtonEnabled}
88 // | \-MediaControlCastButtonElement (-internal-media-controls -overlay-cast-button) 110 // | \-MediaControlCastButtonElement (-internal-media-controls -overlay-cast-button)
89 // \-MediaControlPanelEnclosureElement (-webkit-media-controls-e nclosure) 111 // \-MediaControlPanelEnclosureElement (-webkit-media-controls-e nclosure)
90 // \-MediaControlPanelElement (-webkit-media-controls-p anel) 112 // \-MediaControlPanelElement (-webkit-media-controls-p anel)
91 // +-MediaControlPlayButtonElement (-webkit-media-controls-p lay-button) 113 // +-MediaControlPlayButtonElement (-webkit-media-controls-p lay-button)
114 // | {if !RTE::newMediaPlaybackUi()}
92 // +-MediaControlTimelineElement (-webkit-media-controls-t imeline) 115 // +-MediaControlTimelineElement (-webkit-media-controls-t imeline)
93 // +-MediaControlCurrentTimeDisplayElement (-webkit-media-controls-c urrent-time-display) 116 // +-MediaControlCurrentTimeDisplayElement (-webkit-media-controls-c urrent-time-display)
94 // +-MediaControlTimeRemainingDisplayElement (-webkit-media-controls-t ime-remaining-display) 117 // +-MediaControlTimeRemainingDisplayElement (-webkit-media-controls-t ime-remaining-display)
118 // | {if RTE::newMediaPlaybackUi()}
119 // +-MediaControlTimelineElement (-webkit-media-controls-t imeline)
95 // +-MediaControlMuteButtonElement (-webkit-media-controls-m ute-button) 120 // +-MediaControlMuteButtonElement (-webkit-media-controls-m ute-button)
96 // +-MediaControlVolumeSliderElement (-webkit-media-controls-v olume-slider) 121 // +-MediaControlVolumeSliderElement (-webkit-media-controls-v olume-slider)
97 // +-MediaControlToggleClosedCaptionsButtonElement (-webkit-media-controls-t oggle-closed-captions-button) 122 // +-MediaControlToggleClosedCaptionsButtonElement (-webkit-media-controls-t oggle-closed-captions-button)
98 // +-MediaControlCastButtonElement (-internal-media-controls -cast-button) 123 // +-MediaControlCastButtonElement (-internal-media-controls -cast-button)
99 // \-MediaControlFullscreenButtonElement (-webkit-media-controls-f ullscreen-button) 124 // \-MediaControlFullscreenButtonElement (-webkit-media-controls-f ullscreen-button)
100 void MediaControls::initializeControls() 125 void MediaControls::initializeControls()
101 { 126 {
127 const bool useNewUi = RuntimeEnabledFeatures::newMediaPlaybackUiEnabled();
102 RefPtrWillBeRawPtr<MediaControlOverlayEnclosureElement> overlayEnclosure = M ediaControlOverlayEnclosureElement::create(*this); 128 RefPtrWillBeRawPtr<MediaControlOverlayEnclosureElement> overlayEnclosure = M ediaControlOverlayEnclosureElement::create(*this);
103 129
104 if (document().settings() && document().settings()->mediaControlsOverlayPlay ButtonEnabled()) { 130 if (document().settings() && document().settings()->mediaControlsOverlayPlay ButtonEnabled()) {
105 RefPtrWillBeRawPtr<MediaControlOverlayPlayButtonElement> overlayPlayButt on = MediaControlOverlayPlayButtonElement::create(*this); 131 RefPtrWillBeRawPtr<MediaControlOverlayPlayButtonElement> overlayPlayButt on = MediaControlOverlayPlayButtonElement::create(*this);
106 m_overlayPlayButton = overlayPlayButton.get(); 132 m_overlayPlayButton = overlayPlayButton.get();
107 overlayEnclosure->appendChild(overlayPlayButton.release()); 133 overlayEnclosure->appendChild(overlayPlayButton.release());
108 } 134 }
109 135
110 RefPtrWillBeRawPtr<MediaControlCastButtonElement> overlayCastButton = MediaC ontrolCastButtonElement::create(*this, true); 136 RefPtrWillBeRawPtr<MediaControlCastButtonElement> overlayCastButton = MediaC ontrolCastButtonElement::create(*this, true);
111 m_overlayCastButton = overlayCastButton.get(); 137 m_overlayCastButton = overlayCastButton.get();
112 overlayEnclosure->appendChild(overlayCastButton.release()); 138 overlayEnclosure->appendChild(overlayCastButton.release());
113 139
114 m_overlayEnclosure = overlayEnclosure.get(); 140 m_overlayEnclosure = overlayEnclosure.get();
115 appendChild(overlayEnclosure.release()); 141 appendChild(overlayEnclosure.release());
116 142
117 // Create an enclosing element for the panel so we can visually offset the c ontrols correctly. 143 // Create an enclosing element for the panel so we can visually offset the c ontrols correctly.
118 RefPtrWillBeRawPtr<MediaControlPanelEnclosureElement> enclosure = MediaContr olPanelEnclosureElement::create(*this); 144 RefPtrWillBeRawPtr<MediaControlPanelEnclosureElement> enclosure = MediaContr olPanelEnclosureElement::create(*this);
119 145
120 RefPtrWillBeRawPtr<MediaControlPanelElement> panel = MediaControlPanelElemen t::create(*this); 146 RefPtrWillBeRawPtr<MediaControlPanelElement> panel = MediaControlPanelElemen t::create(*this);
121 147
122 RefPtrWillBeRawPtr<MediaControlPlayButtonElement> playButton = MediaControlP layButtonElement::create(*this); 148 RefPtrWillBeRawPtr<MediaControlPlayButtonElement> playButton = MediaControlP layButtonElement::create(*this);
123 m_playButton = playButton.get(); 149 m_playButton = playButton.get();
124 panel->appendChild(playButton.release()); 150 panel->appendChild(playButton.release());
125 151
126 RefPtrWillBeRawPtr<MediaControlTimelineElement> timeline = MediaControlTimel ineElement::create(*this); 152 RefPtrWillBeRawPtr<MediaControlTimelineElement> timeline = MediaControlTimel ineElement::create(*this);
127 m_timeline = timeline.get(); 153 m_timeline = timeline.get();
128 panel->appendChild(timeline.release()); 154 // In old UX, timeline is before the time / duration text.
155 if (!useNewUi)
156 panel->appendChild(timeline.release());
157 // else we will attach it later.
129 158
130 RefPtrWillBeRawPtr<MediaControlCurrentTimeDisplayElement> currentTimeDisplay = MediaControlCurrentTimeDisplayElement::create(*this); 159 RefPtrWillBeRawPtr<MediaControlCurrentTimeDisplayElement> currentTimeDisplay = MediaControlCurrentTimeDisplayElement::create(*this);
131 m_currentTimeDisplay = currentTimeDisplay.get(); 160 m_currentTimeDisplay = currentTimeDisplay.get();
132 m_currentTimeDisplay->hide(); 161 m_currentTimeDisplay->setIsWanted(useNewUi);
162
133 panel->appendChild(currentTimeDisplay.release()); 163 panel->appendChild(currentTimeDisplay.release());
134 164
135 RefPtrWillBeRawPtr<MediaControlTimeRemainingDisplayElement> durationDisplay = MediaControlTimeRemainingDisplayElement::create(*this); 165 RefPtrWillBeRawPtr<MediaControlTimeRemainingDisplayElement> durationDisplay = MediaControlTimeRemainingDisplayElement::create(*this);
136 m_durationDisplay = durationDisplay.get(); 166 m_durationDisplay = durationDisplay.get();
137 panel->appendChild(durationDisplay.release()); 167 panel->appendChild(durationDisplay.release());
138 168
169 // In new UX, timeline is after the time / duration text.
170 if (useNewUi)
171 panel->appendChild(timeline.release());
172
139 RefPtrWillBeRawPtr<MediaControlMuteButtonElement> muteButton = MediaControlM uteButtonElement::create(*this); 173 RefPtrWillBeRawPtr<MediaControlMuteButtonElement> muteButton = MediaControlM uteButtonElement::create(*this);
140 m_muteButton = muteButton.get(); 174 m_muteButton = muteButton.get();
141 panel->appendChild(muteButton.release()); 175 panel->appendChild(muteButton.release());
176 const bool allowHiddenAudio = allowHiddenAudioElements(document());
177 if (allowHiddenAudio && preferHiddenMuteButton(document()))
178 m_muteButton->setIsWanted(false);
142 179
143 RefPtrWillBeRawPtr<MediaControlVolumeSliderElement> slider = MediaControlVol umeSliderElement::create(*this); 180 RefPtrWillBeRawPtr<MediaControlVolumeSliderElement> slider = MediaControlVol umeSliderElement::create(*this);
144 m_volumeSlider = slider.get(); 181 m_volumeSlider = slider.get();
145 panel->appendChild(slider.release()); 182 panel->appendChild(slider.release());
183 if (allowHiddenAudio && preferHiddenVolumeSlider(document()))
184 m_volumeSlider->setIsWanted(false);
146 185
147 RefPtrWillBeRawPtr<MediaControlToggleClosedCaptionsButtonElement> toggleClos edCaptionsButton = MediaControlToggleClosedCaptionsButtonElement::create(*this); 186 RefPtrWillBeRawPtr<MediaControlToggleClosedCaptionsButtonElement> toggleClos edCaptionsButton = MediaControlToggleClosedCaptionsButtonElement::create(*this);
148 m_toggleClosedCaptionsButton = toggleClosedCaptionsButton.get(); 187 m_toggleClosedCaptionsButton = toggleClosedCaptionsButton.get();
149 panel->appendChild(toggleClosedCaptionsButton.release()); 188 panel->appendChild(toggleClosedCaptionsButton.release());
150 189
151 RefPtrWillBeRawPtr<MediaControlCastButtonElement> castButton = MediaControlC astButtonElement::create(*this, false); 190 RefPtrWillBeRawPtr<MediaControlCastButtonElement> castButton = MediaControlC astButtonElement::create(*this, false);
152 m_castButton = castButton.get(); 191 m_castButton = castButton.get();
153 panel->appendChild(castButton.release()); 192 panel->appendChild(castButton.release());
154 193
155 RefPtrWillBeRawPtr<MediaControlFullscreenButtonElement> fullscreenButton = M ediaControlFullscreenButtonElement::create(*this); 194 RefPtrWillBeRawPtr<MediaControlFullscreenButtonElement> fullscreenButton = M ediaControlFullscreenButtonElement::create(*this);
156 m_fullScreenButton = fullscreenButton.get(); 195 m_fullScreenButton = fullscreenButton.get();
157 panel->appendChild(fullscreenButton.release()); 196 panel->appendChild(fullscreenButton.release());
158 197
159 m_panel = panel.get(); 198 m_panel = panel.get();
160 enclosure->appendChild(panel.release()); 199 enclosure->appendChild(panel.release());
161 200
162 m_enclosure = enclosure.get(); 201 m_enclosure = enclosure.get();
163 appendChild(enclosure.release()); 202 appendChild(enclosure.release());
164 } 203 }
165 204
166 void MediaControls::reset() 205 void MediaControls::reset()
167 { 206 {
168 double duration = mediaElement().duration(); 207 const bool useNewUi = RuntimeEnabledFeatures::newMediaPlaybackUiEnabled();
208 const double duration = mediaElement().duration();
169 m_durationDisplay->setInnerText(LayoutTheme::theme().formatMediaControlsTime (duration), ASSERT_NO_EXCEPTION); 209 m_durationDisplay->setInnerText(LayoutTheme::theme().formatMediaControlsTime (duration), ASSERT_NO_EXCEPTION);
170 m_durationDisplay->setCurrentValue(duration); 210 m_durationDisplay->setCurrentValue(duration);
171 211
212 if (useNewUi) {
213 // Show everything that we might hide.
214 // If we don't have a duration, then mark it to be hidden. For the
215 // old UI case, want / don't want is the same as show / hide since
216 // it is never marked as not fitting.
217 if (std::isfinite(duration))
218 m_durationDisplay->setIsWanted(true);
219 else
220 m_durationDisplay->setIsWanted(false);
221 m_currentTimeDisplay->setIsWanted(true);
222 m_timeline->setIsWanted(true);
223 }
224
172 updatePlayState(); 225 updatePlayState();
173 226
174 updateCurrentTimeDisplay(); 227 updateCurrentTimeDisplay();
175 228
176 m_timeline->setDuration(duration); 229 m_timeline->setDuration(duration);
177 m_timeline->setPosition(mediaElement().currentTime()); 230 m_timeline->setPosition(mediaElement().currentTime());
178 231
179 if (!mediaElement().hasAudio())
180 m_volumeSlider->hide();
181 else
182 m_volumeSlider->show();
183 updateVolume(); 232 updateVolume();
184 233
185 refreshClosedCaptionsButtonVisibility(); 234 refreshClosedCaptionsButtonVisibility();
186 235
187 // Unconditionally allow the user to exit fullscreen if we are in it 236 // Unconditionally allow the user to exit fullscreen if we are in it
188 // now. Especially on android, when we might not yet know if 237 // now. Especially on android, when we might not yet know if
189 // fullscreen is supported, we sometimes guess incorrectly and show 238 // fullscreen is supported, we sometimes guess incorrectly and show
190 // the button earlier, and we don't want to remove it here if the 239 // the button earlier, and we don't want to remove it here if the
191 // user chose to enter fullscreen. crbug.com/500732 . 240 // user chose to enter fullscreen. crbug.com/500732 .
192 if ((mediaElement().hasVideo() && fullscreenIsSupported(document())) 241 m_fullScreenButton->setIsWanted((mediaElement().hasVideo()
193 || mediaElement().isFullscreen()) 242 && fullscreenIsSupported(document()))
194 m_fullScreenButton->show(); 243 || mediaElement().isFullscreen());
195 else
196 m_fullScreenButton->hide();
197 244
198 refreshCastButtonVisibility(); 245 refreshCastButtonVisibilityWithoutUpdate();
199 makeOpaque(); 246 makeOpaque();
247 changedControlSelections();
200 } 248 }
201 249
202 LayoutObject* MediaControls::layoutObjectForTextTrackLayout() 250 LayoutObject* MediaControls::layoutObjectForTextTrackLayout()
203 { 251 {
204 return m_panel->layoutObject(); 252 return m_panel->layoutObject();
205 } 253 }
206 254
207 void MediaControls::show() 255 void MediaControls::show()
208 { 256 {
209 makeOpaque(); 257 makeOpaque();
210 m_panel->show(); 258 m_panel->setIsWanted(true);
211 m_panel->setIsDisplayed(true); 259 m_panel->setIsDisplayed(true);
212 if (m_overlayPlayButton) 260 if (m_overlayPlayButton)
213 m_overlayPlayButton->updateDisplayType(); 261 m_overlayPlayButton->updateDisplayType();
214 } 262 }
215 263
216 void MediaControls::mediaElementFocused() 264 void MediaControls::mediaElementFocused()
217 { 265 {
218 if (mediaElement().shouldShowControls()) { 266 if (mediaElement().shouldShowControls()) {
219 show(); 267 show();
220 resetHideMediaControlsTimer(); 268 resetHideMediaControlsTimer();
221 } 269 }
222 } 270 }
223 271
224 void MediaControls::hide() 272 void MediaControls::hide()
225 { 273 {
226 m_panel->hide(); 274 m_panel->setIsWanted(false);
227 m_panel->setIsDisplayed(false); 275 m_panel->setIsDisplayed(false);
228 if (m_overlayPlayButton) 276 if (m_overlayPlayButton)
229 m_overlayPlayButton->hide(); 277 m_overlayPlayButton->setIsWanted(false);
230 } 278 }
231 279
232 void MediaControls::makeOpaque() 280 void MediaControls::makeOpaque()
233 { 281 {
234 m_panel->makeOpaque(); 282 m_panel->makeOpaque();
235 } 283 }
236 284
237 void MediaControls::makeTransparent() 285 void MediaControls::makeTransparent()
238 { 286 {
239 m_panel->makeTransparent(); 287 m_panel->makeTransparent();
(...skipping 16 matching lines...) Expand all
256 // controls/shadow tree. (Perform the checks separately to avoid going 304 // controls/shadow tree. (Perform the checks separately to avoid going
257 // through all the potential ancestor hosts for the focused element.) 305 // through all the potential ancestor hosts for the focused element.)
258 const bool ignoreFocus = behaviorFlags & IgnoreFocus; 306 const bool ignoreFocus = behaviorFlags & IgnoreFocus;
259 if (!ignoreFocus && (mediaElement().focused() || contains(document().focused Element()))) 307 if (!ignoreFocus && (mediaElement().focused() || contains(document().focused Element())))
260 return false; 308 return false;
261 return true; 309 return true;
262 } 310 }
263 311
264 void MediaControls::playbackStarted() 312 void MediaControls::playbackStarted()
265 { 313 {
266 m_currentTimeDisplay->show(); 314 if (!RuntimeEnabledFeatures::newMediaPlaybackUiEnabled()) {
267 m_durationDisplay->hide(); 315 m_currentTimeDisplay->setIsWanted(true);
316 m_durationDisplay->setIsWanted(false);
317 }
268 318
269 updatePlayState(); 319 updatePlayState();
270 m_timeline->setPosition(mediaElement().currentTime()); 320 m_timeline->setPosition(mediaElement().currentTime());
271 updateCurrentTimeDisplay(); 321 updateCurrentTimeDisplay();
272 322
273 startHideMediaControlsTimer(); 323 startHideMediaControlsTimer();
274 } 324 }
275 325
276 void MediaControls::playbackProgressed() 326 void MediaControls::playbackProgressed()
277 { 327 {
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
318 mediaElement().togglePlayState(); 368 mediaElement().togglePlayState();
319 } 369 }
320 } 370 }
321 371
322 void MediaControls::updateCurrentTimeDisplay() 372 void MediaControls::updateCurrentTimeDisplay()
323 { 373 {
324 double now = mediaElement().currentTime(); 374 double now = mediaElement().currentTime();
325 double duration = mediaElement().duration(); 375 double duration = mediaElement().duration();
326 376
327 // After seek, hide duration display and show current time. 377 // After seek, hide duration display and show current time.
328 if (now > 0) { 378 if (!RuntimeEnabledFeatures::newMediaPlaybackUiEnabled() && now > 0) {
329 m_currentTimeDisplay->show(); 379 m_currentTimeDisplay->setIsWanted(true);
330 m_durationDisplay->hide(); 380 m_durationDisplay->setIsWanted(false);
331 } 381 }
332 382
333 // Allow the theme to format the time. 383 // Allow the theme to format the time.
334 m_currentTimeDisplay->setInnerText(LayoutTheme::theme().formatMediaControlsC urrentTime(now, duration), IGNORE_EXCEPTION); 384 m_currentTimeDisplay->setInnerText(LayoutTheme::theme().formatMediaControlsC urrentTime(now, duration), IGNORE_EXCEPTION);
335 m_currentTimeDisplay->setCurrentValue(now); 385 m_currentTimeDisplay->setCurrentValue(now);
336 } 386 }
337 387
338 void MediaControls::updateVolume() 388 void MediaControls::updateVolume()
339 { 389 {
340 m_muteButton->updateDisplayType(); 390 m_muteButton->updateDisplayType();
341 // Invalidate the mute button because it paints differently according to vol ume. 391 // Invalidate the mute button because it paints differently according to vol ume.
342 if (LayoutObject* layoutObject = m_muteButton->layoutObject()) 392 if (LayoutObject* layoutObject = m_muteButton->layoutObject())
343 layoutObject->setShouldDoFullPaintInvalidation(); 393 layoutObject->setShouldDoFullPaintInvalidation();
344 394
345 if (mediaElement().muted()) 395 if (mediaElement().muted()) {
346 m_volumeSlider->setVolume(0); 396 m_volumeSlider->setVolume(0);
347 else 397 } else {
348 m_volumeSlider->setVolume(mediaElement().volume()); 398 m_volumeSlider->setVolume(mediaElement().volume());
399 }
400
401 // Update the visibility of our audio elements.
402 // Old and new UI never want the volume slider if there's no audio.
403 // If there is audio, then we want it unless hiding audio is enabled and
404 // we prefer to hide it.
405 const bool allowHiddenAudio = allowHiddenAudioElements(document());
406 m_volumeSlider->setIsWanted(mediaElement().hasAudio()
407 && !(allowHiddenAudio && preferHiddenVolumeSlider(document())));
408
409 // The mute button is a little more complicated. The old UI never
410 // sets it; it lets CSS choose. The new UI does. If we're allowing
philipj_slow 2015/07/10 14:51:59 I would be nice if these descriptions were in term
liberato (no reviews please) 2015/07/10 15:32:19 i agree that 'old' and 'new' are awful names. i'v
411 // hidden audio, then we may set it. Note that this is why
412 // allowHiddenAudio isn't rolled into prefer...().
413 if (allowHiddenAudio) {
414 // If there is no audio track, then hide the mute button. If there
415 // is an audio track, then we always show the mute button unless
416 // we prefer to hide it and the media isn't muted. If it's muted,
417 // then we show it to let the user unmute it.
418 m_muteButton->setIsWanted(mediaElement().hasAudio()
419 && (!preferHiddenMuteButton(document()) || mediaElement().muted()));
420 }
421
422
349 // Invalidate the volume slider because it paints differently according to v olume. 423 // Invalidate the volume slider because it paints differently according to v olume.
350 if (LayoutObject* layoutObject = m_volumeSlider->layoutObject()) 424 if (LayoutObject* layoutObject = m_volumeSlider->layoutObject())
351 layoutObject->setShouldDoFullPaintInvalidation(); 425 layoutObject->setShouldDoFullPaintInvalidation();
352 } 426 }
353 427
354 void MediaControls::changedClosedCaptionsVisibility() 428 void MediaControls::changedClosedCaptionsVisibility()
355 { 429 {
356 m_toggleClosedCaptionsButton->updateDisplayType(); 430 m_toggleClosedCaptionsButton->updateDisplayType();
357 } 431 }
358 432
359 void MediaControls::refreshClosedCaptionsButtonVisibility() 433 void MediaControls::refreshClosedCaptionsButtonVisibility()
360 { 434 {
361 if (mediaElement().hasClosedCaptions()) 435 m_toggleClosedCaptionsButton->setIsWanted(mediaElement().hasClosedCaptions() );
362 m_toggleClosedCaptionsButton->show();
363 else
364 m_toggleClosedCaptionsButton->hide();
365 } 436 }
366 437
367 static Element* elementFromCenter(Element& element) 438 static Element* elementFromCenter(Element& element)
368 { 439 {
369 ClientRect* clientRect = element.getBoundingClientRect(); 440 ClientRect* clientRect = element.getBoundingClientRect();
370 int centerX = static_cast<int>((clientRect->left() + clientRect->right()) / 2); 441 int centerX = static_cast<int>((clientRect->left() + clientRect->right()) / 2);
371 int centerY = static_cast<int>((clientRect->top() + clientRect->bottom()) / 2); 442 int centerY = static_cast<int>((clientRect->top() + clientRect->bottom()) / 2);
372 443
373 return element.document().elementFromPoint(centerX , centerY); 444 return element.document().elementFromPoint(centerX , centerY);
374 } 445 }
375 446
376 void MediaControls::tryShowOverlayCastButton() 447 void MediaControls::tryShowOverlayCastButton()
377 { 448 {
378 // The element needs to be shown to have its dimensions and position. 449 // The element needs to be shown to have its dimensions and position.
379 m_overlayCastButton->show(); 450 m_overlayCastButton->setIsWanted(true);
380
381 if (elementFromCenter(*m_overlayCastButton) != &mediaElement()) 451 if (elementFromCenter(*m_overlayCastButton) != &mediaElement())
382 m_overlayCastButton->hide(); 452 m_overlayCastButton->setIsWanted(false);
383 } 453 }
384 454
385 void MediaControls::refreshCastButtonVisibility() 455 void MediaControls::refreshCastButtonVisibility()
386 { 456 {
457 refreshCastButtonVisibilityWithoutUpdate();
458 changedControlSelections();
459 }
460
461 void MediaControls::refreshCastButtonVisibilityWithoutUpdate()
462 {
387 if (mediaElement().hasRemoteRoutes()) { 463 if (mediaElement().hasRemoteRoutes()) {
388 // The reason for the autoplay test is that some pages (e.g. vimeo.com) have an autoplay background video, which 464 // The reason for the autoplay test is that some pages (e.g. vimeo.com) have an autoplay background video, which
389 // doesn't autoplay on Chrome for Android (we prevent it) so starts paus ed. In such cases we don't want to automatically 465 // doesn't autoplay on Chrome for Android (we prevent it) so starts paus ed. In such cases we don't want to automatically
390 // show the cast button, since it looks strange and is unlikely to corre spond with anything the user wants to do. 466 // show the cast button, since it looks strange and is unlikely to corre spond with anything the user wants to do.
391 // If a user does want to cast a paused autoplay video then they can sti ll do so by touching or clicking on the 467 // If a user does want to cast a paused autoplay video then they can sti ll do so by touching or clicking on the
392 // video, which will cause the cast button to appear. 468 // video, which will cause the cast button to appear.
393 if (!mediaElement().shouldShowControls() && !mediaElement().autoplay() & & mediaElement().paused()) { 469 if (!mediaElement().shouldShowControls() && !mediaElement().autoplay() & & mediaElement().paused()) {
394 showOverlayCastButton(); 470 // Note that this is a case where we add the overlay cast button
471 // without wanting the panel cast button. We depend on the fact
472 // that computeWhichControlsFit() won't change overlay cast button
473 // visibility in the case where the cast button isn't wanted.
474 // We don't call compute...() here, but it will be called as
475 // non-cast changes (e.g., resize) occur. If the panel button
476 // is shown, however, compute...() will take control of the
477 // overlay cast button if it needs to hide it from the panel.
478 tryShowOverlayCastButton();
479 m_castButton->setIsWanted(false);
395 } else if (mediaElement().shouldShowControls()) { 480 } else if (mediaElement().shouldShowControls()) {
396 m_overlayCastButton->hide(); 481 m_overlayCastButton->setIsWanted(false);
397 m_castButton->show(); 482 m_castButton->setIsWanted(true);
398 // Check that the cast button actually fits on the bar. 483 // Check that the cast button actually fits on the bar. For the
399 if (m_fullScreenButton->getBoundingClientRect()->right() > m_panel-> getBoundingClientRect()->right()) { 484 // new ui, we let changedControlSelections() handle this.
400 m_castButton->hide(); 485 if ( !RuntimeEnabledFeatures::newMediaPlaybackUiEnabled()
486 && m_fullScreenButton->getBoundingClientRect()->right() > m_pane l->getBoundingClientRect()->right()) {
487 m_castButton->setIsWanted(false);
401 tryShowOverlayCastButton(); 488 tryShowOverlayCastButton();
402 } 489 }
403 } 490 }
404 } else { 491 } else {
405 m_castButton->hide(); 492 m_castButton->setIsWanted(false);
406 m_overlayCastButton->hide(); 493 m_overlayCastButton->setIsWanted(false);
407 } 494 }
408 } 495 }
409 496
410 void MediaControls::showOverlayCastButton() 497 void MediaControls::showOverlayCastButton()
411 { 498 {
412 tryShowOverlayCastButton(); 499 tryShowOverlayCastButton();
413 resetHideMediaControlsTimer(); 500 resetHideMediaControlsTimer();
414 } 501 }
415 502
416 void MediaControls::enteredFullscreen() 503 void MediaControls::enteredFullscreen()
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
487 unsigned behaviorFlags = m_hideTimerBehaviorFlags | IgnoreFocus | IgnoreVide oHover; 574 unsigned behaviorFlags = m_hideTimerBehaviorFlags | IgnoreFocus | IgnoreVide oHover;
488 m_hideTimerBehaviorFlags = IgnoreNone; 575 m_hideTimerBehaviorFlags = IgnoreNone;
489 576
490 if (mediaElement().togglePlayStateWillPlay()) 577 if (mediaElement().togglePlayStateWillPlay())
491 return; 578 return;
492 579
493 if (!shouldHideMediaControls(behaviorFlags)) 580 if (!shouldHideMediaControls(behaviorFlags))
494 return; 581 return;
495 582
496 makeTransparent(); 583 makeTransparent();
497 m_overlayCastButton->hide(); 584 m_overlayCastButton->setIsWanted(false);
498 } 585 }
499 586
500 void MediaControls::startHideMediaControlsTimer() 587 void MediaControls::startHideMediaControlsTimer()
501 { 588 {
502 m_hideMediaControlsTimer.startOneShot(timeWithoutMouseMovementBeforeHidingMe diaControls, FROM_HERE); 589 m_hideMediaControlsTimer.startOneShot(timeWithoutMouseMovementBeforeHidingMe diaControls, FROM_HERE);
503 } 590 }
504 591
505 void MediaControls::stopHideMediaControlsTimer() 592 void MediaControls::stopHideMediaControlsTimer()
506 { 593 {
507 m_hideMediaControlsTimer.stop(); 594 m_hideMediaControlsTimer.stop();
(...skipping 10 matching lines...) Expand all
518 bool MediaControls::containsRelatedTarget(Event* event) 605 bool MediaControls::containsRelatedTarget(Event* event)
519 { 606 {
520 if (!event->isMouseEvent()) 607 if (!event->isMouseEvent())
521 return false; 608 return false;
522 EventTarget* relatedTarget = toMouseEvent(event)->relatedTarget(); 609 EventTarget* relatedTarget = toMouseEvent(event)->relatedTarget();
523 if (!relatedTarget) 610 if (!relatedTarget)
524 return false; 611 return false;
525 return contains(relatedTarget->toNode()); 612 return contains(relatedTarget->toNode());
526 } 613 }
527 614
615 void MediaControls::notifyPanelWidthChanged(int panelWidth)
616 {
617 // Don't bother to do any work if this matches the most recent panel
618 // width, since we're called after layout.
619 if (panelWidth == 0)
620 return;
621
622 if (!RuntimeEnabledFeatures::newMediaPlaybackUiEnabled())
623 return;
624
625 m_panelWidth = panelWidth;
626 m_panelWidthChangedTimer.startOneShot(0, FROM_HERE);
627 }
628
629 void MediaControls::changedControlSelections()
630 {
631 int panelWidth = m_panel->clientWidth();
632 // Don't short-circuit update if the panel hasn't changed. The fit state
633 // is a function of the controls we want, so recompute if we can.
634 if (panelWidth == 0)
635 return;
636
637 m_panelWidth = panelWidth;
638 computeWhichControlsFit();
639 }
640
641 void MediaControls::panelWidthChangedTimerFired(Timer<MediaControls>*)
642 {
643 computeWhichControlsFit();
644 }
645
646 void MediaControls::computeWhichControlsFit()
647 {
648 // Hide all controls that don't fit, and show the ones that do.
649 // This might be better suited for a layout, but since JS media controls
650 // won't benefit from that anwyay, we just do it here like JS will.
651 // The order, in order of decreasing droppiness:
652 // Volume, time, seek bar, cast.
653
654 if (!RuntimeEnabledFeatures::newMediaPlaybackUiEnabled())
655 return;
656
657 if (!m_panelWidth)
658 return;
659
660 // Controls that we'll hide / show, in order of decreasing priority.
661 MediaControlElement* elements[] = {
662 m_playButton.get(),
663 m_toggleClosedCaptionsButton.get(),
664 m_fullScreenButton.get(),
665 m_timeline.get(),
666 m_currentTimeDisplay.get(),
667 m_volumeSlider.get(),
668 m_castButton.get(),
669 m_muteButton.get(),
670 m_durationDisplay.get(),
671 };
672
673 int usedWidth = 0;
674 bool droppedCastButton = false;
675 for (MediaControlElement* element : elements) {
676 if (!element)
677 continue;
678
679 if (element->isWanted()) {
680 if (usedWidth + element->minimumWidth() <= m_panelWidth) {
681 element->setDoesFit(true);
682 usedWidth += element->minimumWidth();
683 } else {
684 element->setDoesFit(false);
685 if (element == m_castButton.get())
686 droppedCastButton = true;
687 }
688 }
689 }
690
691 // Special case for cast: if we want a cast button but dropped it, then
692 // show the overlay cast button instead.
693 if (m_castButton->isWanted())
694 m_overlayCastButton->setIsWanted(!droppedCastButton);
695 }
696
528 DEFINE_TRACE(MediaControls) 697 DEFINE_TRACE(MediaControls)
529 { 698 {
530 visitor->trace(m_mediaElement); 699 visitor->trace(m_mediaElement);
531 visitor->trace(m_panel); 700 visitor->trace(m_panel);
532 visitor->trace(m_overlayPlayButton); 701 visitor->trace(m_overlayPlayButton);
533 visitor->trace(m_overlayEnclosure); 702 visitor->trace(m_overlayEnclosure);
534 visitor->trace(m_playButton); 703 visitor->trace(m_playButton);
535 visitor->trace(m_currentTimeDisplay); 704 visitor->trace(m_currentTimeDisplay);
536 visitor->trace(m_timeline); 705 visitor->trace(m_timeline);
537 visitor->trace(m_muteButton); 706 visitor->trace(m_muteButton);
538 visitor->trace(m_volumeSlider); 707 visitor->trace(m_volumeSlider);
539 visitor->trace(m_toggleClosedCaptionsButton); 708 visitor->trace(m_toggleClosedCaptionsButton);
540 visitor->trace(m_fullScreenButton); 709 visitor->trace(m_fullScreenButton);
541 visitor->trace(m_durationDisplay); 710 visitor->trace(m_durationDisplay);
542 visitor->trace(m_enclosure); 711 visitor->trace(m_enclosure);
543 visitor->trace(m_castButton); 712 visitor->trace(m_castButton);
544 visitor->trace(m_overlayCastButton); 713 visitor->trace(m_overlayCastButton);
545 HTMLDivElement::trace(visitor); 714 HTMLDivElement::trace(visitor);
546 } 715 }
547 716
548 } 717 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698