OLD | NEW |
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 24 matching lines...) Expand all Loading... |
35 #include "core/html/track/TextTrackContainer.h" | 35 #include "core/html/track/TextTrackContainer.h" |
36 #include "core/layout/LayoutTheme.h" | 36 #include "core/layout/LayoutTheme.h" |
37 #include "platform/EventDispatchForbiddenScope.h" | 37 #include "platform/EventDispatchForbiddenScope.h" |
38 | 38 |
39 namespace blink { | 39 namespace blink { |
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 // We only want to show the overflow menu if it contains at least two buttons |
| 46 static const int minOverflowMenuControlElementsNum = 2; |
| 47 |
45 static bool shouldShowFullscreenButton(const HTMLMediaElement& mediaElement) | 48 static bool shouldShowFullscreenButton(const HTMLMediaElement& mediaElement) |
46 { | 49 { |
47 // Unconditionally allow the user to exit fullscreen if we are in it | 50 // Unconditionally allow the user to exit fullscreen if we are in it |
48 // now. Especially on android, when we might not yet know if | 51 // now. Especially on android, when we might not yet know if |
49 // fullscreen is supported, we sometimes guess incorrectly and show | 52 // fullscreen is supported, we sometimes guess incorrectly and show |
50 // the button earlier, and we don't want to remove it here if the | 53 // the button earlier, and we don't want to remove it here if the |
51 // user chose to enter fullscreen. crbug.com/500732 . | 54 // user chose to enter fullscreen. crbug.com/500732 . |
52 if (mediaElement.isFullscreen()) | 55 if (mediaElement.isFullscreen()) |
53 return true; | 56 return true; |
54 | 57 |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
110 , m_enclosure(nullptr) | 113 , m_enclosure(nullptr) |
111 , m_panel(nullptr) | 114 , m_panel(nullptr) |
112 , m_playButton(nullptr) | 115 , m_playButton(nullptr) |
113 , m_timeline(nullptr) | 116 , m_timeline(nullptr) |
114 , m_currentTimeDisplay(nullptr) | 117 , m_currentTimeDisplay(nullptr) |
115 , m_durationDisplay(nullptr) | 118 , m_durationDisplay(nullptr) |
116 , m_muteButton(nullptr) | 119 , m_muteButton(nullptr) |
117 , m_volumeSlider(nullptr) | 120 , m_volumeSlider(nullptr) |
118 , m_toggleClosedCaptionsButton(nullptr) | 121 , m_toggleClosedCaptionsButton(nullptr) |
119 , m_textTrackList(nullptr) | 122 , m_textTrackList(nullptr) |
| 123 , m_overflowList(nullptr) |
120 , m_castButton(nullptr) | 124 , m_castButton(nullptr) |
121 , m_fullScreenButton(nullptr) | 125 , m_fullScreenButton(nullptr) |
122 , m_hideMediaControlsTimer(this, &MediaControls::hideMediaControlsTimerFired
) | 126 , m_hideMediaControlsTimer(this, &MediaControls::hideMediaControlsTimerFired
) |
123 , m_hideTimerBehaviorFlags(IgnoreNone) | 127 , m_hideTimerBehaviorFlags(IgnoreNone) |
124 , m_isMouseOverControls(false) | 128 , m_isMouseOverControls(false) |
125 , m_isPausedForScrubbing(false) | 129 , m_isPausedForScrubbing(false) |
126 , m_panelWidthChangedTimer(this, &MediaControls::panelWidthChangedTimerFired
) | 130 , m_panelWidthChangedTimer(this, &MediaControls::panelWidthChangedTimerFired
) |
127 , m_panelWidth(0) | 131 , m_panelWidth(0) |
128 , m_allowHiddenVolumeControls(RuntimeEnabledFeatures::newMediaPlaybackUiEnab
led()) | 132 , m_allowHiddenVolumeControls(RuntimeEnabledFeatures::newMediaPlaybackUiEnab
led()) |
129 { | 133 { |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
235 | 239 |
236 m_panel = panel; | 240 m_panel = panel; |
237 enclosure->appendChild(panel); | 241 enclosure->appendChild(panel); |
238 | 242 |
239 m_enclosure = enclosure; | 243 m_enclosure = enclosure; |
240 appendChild(enclosure); | 244 appendChild(enclosure); |
241 | 245 |
242 MediaControlTextTrackListElement* textTrackList = MediaControlTextTrackListE
lement::create(*this); | 246 MediaControlTextTrackListElement* textTrackList = MediaControlTextTrackListE
lement::create(*this); |
243 m_textTrackList = textTrackList; | 247 m_textTrackList = textTrackList; |
244 appendChild(textTrackList); | 248 appendChild(textTrackList); |
| 249 |
| 250 MediaControlOverflowMenuButtonElement* overflowMenu = MediaControlOverflowMe
nuButtonElement::create(*this); |
| 251 m_overflowMenu = overflowMenu; |
| 252 panel->appendChild(overflowMenu); |
| 253 |
| 254 MediaControlOverflowMenuListElement* overflowList = MediaControlOverflowMenu
ListElement::create(*this); |
| 255 m_overflowList = overflowList; |
| 256 appendChild(overflowList); |
| 257 |
| 258 // Buttons we'd like to show in the overflow menu. |
| 259 std::vector<MediaControlInputElement*> buttons = { m_muteButton, m_castButto
n, m_toggleClosedCaptionsButton, |
| 260 m_fullScreenButton}; |
| 261 |
| 262 for (MediaControlInputElement* elem : buttons) { |
| 263 m_overflowList->appendChild(elem->createOverflowElement(*this)); |
| 264 } |
245 } | 265 } |
246 | 266 |
247 void MediaControls::reset() | 267 void MediaControls::reset() |
248 { | 268 { |
249 EventDispatchForbiddenScope::AllowUserAgentEvents allowEventsInShadow; | 269 EventDispatchForbiddenScope::AllowUserAgentEvents allowEventsInShadow; |
250 const bool useNewUi = RuntimeEnabledFeatures::newMediaPlaybackUiEnabled(); | 270 const bool useNewUi = RuntimeEnabledFeatures::newMediaPlaybackUiEnabled(); |
251 BatchedControlUpdate batch(this); | 271 BatchedControlUpdate batch(this); |
252 | 272 |
253 m_allowHiddenVolumeControls = useNewUi; | 273 m_allowHiddenVolumeControls = useNewUi; |
254 | 274 |
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
426 } | 446 } |
427 | 447 |
428 // Allow the theme to format the time. | 448 // Allow the theme to format the time. |
429 m_currentTimeDisplay->setInnerText(LayoutTheme::theme().formatMediaControlsC
urrentTime(now, duration), IGNORE_EXCEPTION); | 449 m_currentTimeDisplay->setInnerText(LayoutTheme::theme().formatMediaControlsC
urrentTime(now, duration), IGNORE_EXCEPTION); |
430 m_currentTimeDisplay->setCurrentValue(now); | 450 m_currentTimeDisplay->setCurrentValue(now); |
431 } | 451 } |
432 | 452 |
433 void MediaControls::updateVolume() | 453 void MediaControls::updateVolume() |
434 { | 454 { |
435 m_muteButton->updateDisplayType(); | 455 m_muteButton->updateDisplayType(); |
| 456 |
436 // Invalidate the mute button because it paints differently according to vol
ume. | 457 // Invalidate the mute button because it paints differently according to vol
ume. |
437 invalidate(m_muteButton); | 458 invalidate(m_muteButton); |
438 | 459 |
439 if (mediaElement().muted()) | 460 if (mediaElement().muted()) |
440 m_volumeSlider->setVolume(0); | 461 m_volumeSlider->setVolume(0); |
441 else | 462 else |
442 m_volumeSlider->setVolume(mediaElement().volume()); | 463 m_volumeSlider->setVolume(mediaElement().volume()); |
443 | 464 |
444 // Update the visibility of our audio elements. | 465 // Update the visibility of our audio elements. |
445 // We never want the volume slider if there's no audio. | 466 // We never want the volume slider if there's no audio. |
(...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
723 // This prevents the wrong controls from being shown briefly | 744 // This prevents the wrong controls from being shown briefly |
724 // immediately after the first layout and paint, but before we have | 745 // immediately after the first layout and paint, but before we have |
725 // a chance to revise them. | 746 // a chance to revise them. |
726 for (MediaControlElement* element : elements) { | 747 for (MediaControlElement* element : elements) { |
727 if (element) | 748 if (element) |
728 element->setDoesFit(false); | 749 element->setDoesFit(false); |
729 } | 750 } |
730 return; | 751 return; |
731 } | 752 } |
732 | 753 |
| 754 int numOverflowElements = 0; |
733 // For each control that fits, enable it in order of decreasing priority. | 755 // For each control that fits, enable it in order of decreasing priority. |
734 bool droppedCastButton = false; | 756 bool droppedCastButton = false; |
735 for (MediaControlElement* element : elements) { | 757 for (MediaControlElement* element : elements) { |
736 if (!element) | 758 if (!element) |
737 continue; | 759 continue; |
738 | 760 |
739 if (element->isWanted()) { | 761 if (element->isWanted()) { |
740 if (usedWidth + minimumWidth <= m_panelWidth) { | 762 if (usedWidth + minimumWidth <= m_panelWidth) { |
741 element->setDoesFit(true); | 763 element->setDoesFit(true); |
742 usedWidth += minimumWidth; | 764 usedWidth += minimumWidth; |
| 765 element->shouldShowButtonInOverflowMenu(false); |
743 } else { | 766 } else { |
744 element->setDoesFit(false); | 767 element->setDoesFit(false); |
745 if (element == m_castButton.get()) | 768 if (element == m_castButton.get()) |
746 droppedCastButton = true; | 769 droppedCastButton = true; |
| 770 element->shouldShowButtonInOverflowMenu(true); |
| 771 if (element->hasOverflowButton()) |
| 772 numOverflowElements++; |
747 } | 773 } |
748 } | 774 } |
749 } | 775 } |
750 | 776 |
| 777 // We display an overflow menu only when we have at least two items |
| 778 // within it. |
| 779 if (numOverflowElements >= minOverflowMenuControlElementsNum) { |
| 780 m_overflowMenu->setIsWanted(true); |
| 781 } else { |
| 782 m_overflowMenu->setIsWanted(false); |
| 783 m_overflowList->showOverflowMenu(false); |
| 784 } |
| 785 |
751 // Special case for cast: if we want a cast button but dropped it, then | 786 // Special case for cast: if we want a cast button but dropped it, then |
752 // show the overlay cast button instead. | 787 // show the overlay cast button instead. |
753 if (m_castButton->isWanted()) { | 788 if (m_castButton->isWanted()) { |
754 if (droppedCastButton) | 789 if (droppedCastButton) |
755 m_overlayCastButton->tryShowOverlay(); | 790 m_overlayCastButton->tryShowOverlay(); |
756 else | 791 else |
757 m_overlayCastButton->setIsWanted(false); | 792 m_overlayCastButton->setIsWanted(false); |
758 } | 793 } |
759 } | 794 } |
760 | 795 |
(...skipping 16 matching lines...) Expand all Loading... |
777 void MediaControls::networkStateChanged() | 812 void MediaControls::networkStateChanged() |
778 { | 813 { |
779 invalidate(m_playButton); | 814 invalidate(m_playButton); |
780 invalidate(m_overlayPlayButton); | 815 invalidate(m_overlayPlayButton); |
781 invalidate(m_muteButton); | 816 invalidate(m_muteButton); |
782 invalidate(m_fullScreenButton); | 817 invalidate(m_fullScreenButton); |
783 invalidate(m_timeline); | 818 invalidate(m_timeline); |
784 invalidate(m_volumeSlider); | 819 invalidate(m_volumeSlider); |
785 } | 820 } |
786 | 821 |
| 822 bool MediaControls::overflowMenuVisible() |
| 823 { |
| 824 return m_overflowList->isWanted(); |
| 825 } |
| 826 |
| 827 void MediaControls::toggleOverflowMenu() |
| 828 { |
| 829 m_overflowList->showOverflowMenu(!m_overflowList->isWanted()); |
| 830 } |
| 831 |
787 DEFINE_TRACE(MediaControls) | 832 DEFINE_TRACE(MediaControls) |
788 { | 833 { |
789 visitor->trace(m_mediaElement); | 834 visitor->trace(m_mediaElement); |
790 visitor->trace(m_panel); | 835 visitor->trace(m_panel); |
791 visitor->trace(m_overlayPlayButton); | 836 visitor->trace(m_overlayPlayButton); |
792 visitor->trace(m_overlayEnclosure); | 837 visitor->trace(m_overlayEnclosure); |
793 visitor->trace(m_playButton); | 838 visitor->trace(m_playButton); |
794 visitor->trace(m_currentTimeDisplay); | 839 visitor->trace(m_currentTimeDisplay); |
795 visitor->trace(m_timeline); | 840 visitor->trace(m_timeline); |
796 visitor->trace(m_muteButton); | 841 visitor->trace(m_muteButton); |
797 visitor->trace(m_volumeSlider); | 842 visitor->trace(m_volumeSlider); |
798 visitor->trace(m_toggleClosedCaptionsButton); | 843 visitor->trace(m_toggleClosedCaptionsButton); |
799 visitor->trace(m_fullScreenButton); | 844 visitor->trace(m_fullScreenButton); |
800 visitor->trace(m_durationDisplay); | 845 visitor->trace(m_durationDisplay); |
801 visitor->trace(m_enclosure); | 846 visitor->trace(m_enclosure); |
802 visitor->trace(m_textTrackList); | 847 visitor->trace(m_textTrackList); |
| 848 visitor->trace(m_overflowMenu); |
| 849 visitor->trace(m_overflowList); |
803 visitor->trace(m_castButton); | 850 visitor->trace(m_castButton); |
804 visitor->trace(m_overlayCastButton); | 851 visitor->trace(m_overlayCastButton); |
805 HTMLDivElement::trace(visitor); | 852 HTMLDivElement::trace(visitor); |
806 } | 853 } |
807 | 854 |
808 } // namespace blink | 855 } // namespace blink |
OLD | NEW |