b923bb046c9a958274243bec7d3b51e5aa0b2734
[WebKit-https.git] / Source / WebCore / html / shadow / MediaControlRootElementChromium.cpp
1 /*
2  * Copyright (C) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
3  * Copyright (C) 2011 Google Inc. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
15  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
18  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26
27 #include "config.h"
28
29 #if ENABLE(VIDEO)
30 #include "MediaControlRootElementChromium.h"
31
32 #include "MediaControlElements.h"
33 #include "MouseEvent.h"
34 #include "Page.h"
35 #include "RenderTheme.h"
36
37 using namespace std;
38
39 namespace WebCore {
40
41 MediaControlRootElementChromium::MediaControlRootElementChromium(Document* document)
42     : MediaControls(document)
43     , m_mediaController(0)
44     , m_playButton(0)
45     , m_currentTimeDisplay(0)
46     , m_timeline(0)
47     , m_timelineContainer(0)
48     , m_panelMuteButton(0)
49     , m_volumeSlider(0)
50     , m_volumeSliderContainer(0)
51     , m_panel(0)
52     , m_opaque(true)
53     , m_isMouseOverControls(false)
54 {
55 }
56
57 PassRefPtr<MediaControls> MediaControls::create(Document* document)
58 {
59     return MediaControlRootElementChromium::create(document);
60 }
61
62 PassRefPtr<MediaControlRootElementChromium> MediaControlRootElementChromium::create(Document* document)
63 {
64     if (!document->page())
65         return 0;
66
67     RefPtr<MediaControlRootElementChromium> controls = adoptRef(new MediaControlRootElementChromium(document));
68
69     RefPtr<MediaControlPanelElement> panel = MediaControlPanelElement::create(document);
70
71     ExceptionCode ec;
72
73     RefPtr<MediaControlPlayButtonElement> playButton = MediaControlPlayButtonElement::create(document);
74     controls->m_playButton = playButton.get();
75     panel->appendChild(playButton.release(), ec, true);
76     if (ec)
77         return 0;
78
79     RefPtr<MediaControlTimelineContainerElement> timelineContainer = MediaControlTimelineContainerElement::create(document);
80
81     RefPtr<MediaControlTimelineElement> timeline = MediaControlTimelineElement::create(document, controls.get());
82     controls->m_timeline = timeline.get();
83     timelineContainer->appendChild(timeline.release(), ec, true);
84     if (ec)
85         return 0;
86
87     RefPtr<MediaControlCurrentTimeDisplayElement> currentTimeDisplay = MediaControlCurrentTimeDisplayElement::create(document);
88     controls->m_currentTimeDisplay = currentTimeDisplay.get();
89     timelineContainer->appendChild(currentTimeDisplay.release(), ec, true);
90     if (ec)
91         return 0;
92
93     controls->m_timelineContainer = timelineContainer.get();
94     panel->appendChild(timelineContainer.release(), ec, true);
95     if (ec)
96         return 0;
97
98     RefPtr<MediaControlPanelMuteButtonElement> panelMuteButton = MediaControlPanelMuteButtonElement::create(document, controls.get());
99     controls->m_panelMuteButton = panelMuteButton.get();
100     panel->appendChild(panelMuteButton.release(), ec, true);
101     if (ec)
102         return 0;
103
104     RefPtr<MediaControlVolumeSliderContainerElement> volumeSliderContainer = MediaControlVolumeSliderContainerElement::create(document);
105
106     RefPtr<MediaControlVolumeSliderElement> slider = MediaControlVolumeSliderElement::create(document);
107     controls->m_volumeSlider = slider.get();
108     volumeSliderContainer->appendChild(slider.release(), ec, true);
109     if (ec)
110         return 0;
111
112     controls->m_volumeSliderContainer = volumeSliderContainer.get();
113     panel->appendChild(volumeSliderContainer.release(), ec, true);
114     if (ec)
115         return 0;
116
117     controls->m_panel = panel.get();
118     controls->appendChild(panel.release(), ec, true);
119     if (ec)
120         return 0;
121
122     return controls.release();
123 }
124
125 void MediaControlRootElementChromium::setMediaController(MediaControllerInterface* controller)
126 {
127     if (m_mediaController == controller)
128         return;
129     m_mediaController = controller;
130
131     if (m_playButton)
132         m_playButton->setMediaController(controller);
133     if (m_currentTimeDisplay)
134         m_currentTimeDisplay->setMediaController(controller);
135     if (m_timeline)
136         m_timeline->setMediaController(controller);
137     if (m_timelineContainer)
138         m_timelineContainer->setMediaController(controller);
139     if (m_panelMuteButton)
140         m_panelMuteButton->setMediaController(controller);
141     if (m_volumeSlider)
142         m_volumeSlider->setMediaController(controller);
143     if (m_volumeSliderContainer)
144         m_volumeSliderContainer->setMediaController(controller);
145     if (m_panel)
146         m_panel->setMediaController(controller);
147     reset();
148 }
149
150 void MediaControlRootElementChromium::show()
151 {
152     m_panel->show();
153 }
154
155 void MediaControlRootElementChromium::hide()
156 {
157     m_panel->hide();
158 }
159
160 void MediaControlRootElementChromium::makeOpaque()
161 {
162     m_panel->makeOpaque();
163 }
164
165 void MediaControlRootElementChromium::makeTransparent()
166 {
167     m_panel->makeTransparent();
168 }
169
170 void MediaControlRootElementChromium::reset()
171 {
172     Page* page = document()->page();
173     if (!page)
174         return;
175
176     updateStatusDisplay();
177
178     float duration = m_mediaController->duration();
179     m_timeline->setDuration(duration);
180     m_timelineContainer->show();
181     m_timeline->setPosition(m_mediaController->currentTime());
182     updateTimeDisplay();
183
184     m_panelMuteButton->show();
185
186     if (m_volumeSlider)
187         m_volumeSlider->setVolume(m_mediaController->volume());
188
189     makeOpaque();
190 }
191
192 void MediaControlRootElementChromium::playbackStarted()
193 {
194     m_playButton->updateDisplayType();
195     m_timeline->setPosition(m_mediaController->currentTime());
196     updateTimeDisplay();
197 }
198
199 void MediaControlRootElementChromium::playbackProgressed()
200 {
201     m_timeline->setPosition(m_mediaController->currentTime());
202     updateTimeDisplay();
203
204     if (!m_isMouseOverControls && m_mediaController->hasVideo())
205         makeTransparent();
206 }
207
208 void MediaControlRootElementChromium::playbackStopped()
209 {
210     m_playButton->updateDisplayType();
211     m_timeline->setPosition(m_mediaController->currentTime());
212     updateTimeDisplay();
213     makeOpaque();
214 }
215
216 void MediaControlRootElementChromium::updateTimeDisplay()
217 {
218     float now = m_mediaController->currentTime();
219     float duration = m_mediaController->duration();
220
221     Page* page = document()->page();
222     if (!page)
223         return;
224
225     // Allow the theme to format the time.
226     ExceptionCode ec;
227     m_currentTimeDisplay->setInnerText(page->theme()->formatMediaControlsCurrentTime(now, duration), ec);
228     m_currentTimeDisplay->setCurrentValue(now);
229 }
230
231 void MediaControlRootElementChromium::reportedError()
232 {
233     Page* page = document()->page();
234     if (!page)
235         return;
236
237     m_timelineContainer->hide();
238     m_panelMuteButton->hide();
239     m_volumeSliderContainer->hide();
240 }
241
242 void MediaControlRootElementChromium::updateStatusDisplay()
243 {
244 }
245
246 bool MediaControlRootElementChromium::shouldHideControls()
247 {
248     return !m_panel->hovered();
249 }
250
251 void MediaControlRootElementChromium::loadedMetadata()
252 {
253     reset();
254 }
255
256 bool MediaControlRootElementChromium::containsRelatedTarget(Event* event)
257 {
258     if (!event->isMouseEvent())
259         return false;
260     EventTarget* relatedTarget = static_cast<MouseEvent*>(event)->relatedTarget();
261     if (!relatedTarget)
262         return false;
263     return contains(relatedTarget->toNode());
264 }
265
266 void MediaControlRootElementChromium::defaultEventHandler(Event* event)
267 {
268     MediaControls::defaultEventHandler(event);
269
270     if (event->type() == eventNames().mouseoverEvent) {
271         if (!containsRelatedTarget(event)) {
272             m_isMouseOverControls = true;
273             if (!m_mediaController->canPlay())
274                 makeOpaque();
275         }
276     } else if (event->type() == eventNames().mouseoutEvent) {
277         if (!containsRelatedTarget(event))
278             m_isMouseOverControls = false;
279     }
280 }
281
282 void MediaControlRootElementChromium::changedClosedCaptionsVisibility()
283 {
284 }
285
286 void MediaControlRootElementChromium::changedMute()
287 {
288     m_panelMuteButton->changedMute();
289 }
290
291 void MediaControlRootElementChromium::changedVolume()
292 {
293     m_volumeSlider->setVolume(m_mediaController->volume());
294 }
295
296 void MediaControlRootElementChromium::enteredFullscreen()
297 {
298 }
299
300 void MediaControlRootElementChromium::exitedFullscreen()
301 {
302 }
303
304 void MediaControlRootElementChromium::showVolumeSlider()
305 {
306     if (!m_mediaController->hasAudio())
307         return;
308
309     m_volumeSliderContainer->show();
310 }
311
312 const AtomicString& MediaControlRootElementChromium::shadowPseudoId() const
313 {
314     DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls"));
315     return id;
316 }
317
318 }
319
320 #endif