Fix the issue that Web Audio test case fails on PR3.
[framework/web/webkit-efl.git] / Source / WebCore / rendering / RenderMediaControls.cpp
1 /*
2  * Copyright (C) 2009 Apple Inc. All Rights Reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25
26 #include "config.h"
27
28 #if ENABLE(VIDEO)
29
30 #include "RenderMediaControls.h"
31
32 #include "GraphicsContext.h"
33 #include "HTMLMediaElement.h"
34 #include "HTMLNames.h"
35 #include "PaintInfo.h"
36 #include "RenderTheme.h"
37
38 // FIXME: Unify more of the code for Mac and Win.
39 #if PLATFORM(WIN)
40
41 #include <CoreGraphics/CoreGraphics.h>
42 #include <WebKitSystemInterface/WebKitSystemInterface.h>
43
44 // The Windows version of WKSI defines these functions as capitalized, while the Mac version defines them as lower case.
45 // FIXME: Is this necessary anymore?
46 #define wkMediaControllerThemeAvailable(themeStyle) WKMediaControllerThemeAvailable(themeStyle)
47 #define wkHitTestMediaUIPart(part, themeStyle, bounds, point) WKHitTestMediaUIPart(part, themeStyle, bounds, point)
48 #define wkMeasureMediaUIPart(part, themeStyle, bounds, naturalSize) WKMeasureMediaUIPart(part, themeStyle, bounds, naturalSize)
49 #define wkDrawMediaUIPart(part, themeStyle, context, rect, state) WKDrawMediaUIPart(part, themeStyle, context, rect, state)
50 #define wkDrawMediaSliderTrack(themeStyle, context, rect, timeLoaded, currentTime, duration, state) WKDrawMediaSliderTrack(themeStyle, context, rect, timeLoaded, currentTime, duration, state)
51
52 #endif
53  
54 using namespace std;
55  
56 namespace WebCore {
57
58 #if PLATFORM(WIN)
59
60 static WKMediaControllerThemeState determineState(RenderObject* o)
61 {
62     int result = 0;
63     RenderTheme* theme = o->theme();
64     if (!theme->isEnabled(o) || theme->isReadOnlyControl(o))
65         result |= WKMediaControllerFlagDisabled;
66     if (theme->isPressed(o))
67         result |= WKMediaControllerFlagPressed;
68     if (theme->isFocused(o))
69         result |= WKMediaControllerFlagFocused;
70     return static_cast<WKMediaControllerThemeState>(result);
71 }
72
73 // Utility to scale when the UI part are not scaled by wkDrawMediaUIPart
74 static FloatRect getUnzoomedRectAndAdjustCurrentContext(RenderObject* o, const PaintInfo& paintInfo, const IntRect &originalRect)
75 {
76     float zoomLevel = o->style()->effectiveZoom();
77     FloatRect unzoomedRect(originalRect);
78     if (zoomLevel != 1.0f) {
79         unzoomedRect.setWidth(unzoomedRect.width() / zoomLevel);
80         unzoomedRect.setHeight(unzoomedRect.height() / zoomLevel);
81         paintInfo.context->translate(unzoomedRect.x(), unzoomedRect.y());
82         paintInfo.context->scale(FloatSize(zoomLevel, zoomLevel));
83         paintInfo.context->translate(-unzoomedRect.x(), -unzoomedRect.y());
84     }
85     return unzoomedRect;
86 }
87
88 static const int mediaSliderThumbWidth = 13;
89 static const int mediaSliderThumbHeight = 14;
90
91 void RenderMediaControls::adjustMediaSliderThumbSize(RenderStyle* style)
92 {
93     int part;
94     switch (style->appearance()) {
95     case MediaSliderThumbPart:
96         part = MediaSliderThumb;
97         break;
98     case MediaVolumeSliderThumbPart:
99         part = MediaVolumeSliderThumb;
100         break;
101     case MediaFullScreenVolumeSliderThumbPart:
102         part = MediaFullScreenVolumeSliderThumb;
103         break;
104     default:
105         return;
106     }
107
108     CGSize size;
109     wkMeasureMediaUIPart(part, WKMediaControllerThemeQuickTime, 0, &size);
110
111     float zoomLevel = style->effectiveZoom();
112     style->setWidth(Length(static_cast<int>(size.width * zoomLevel), Fixed));
113     style->setHeight(Length(static_cast<int>(size.height * zoomLevel), Fixed));
114 }
115
116 bool RenderMediaControls::paintMediaControlsPart(MediaControlElementType part, RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
117 {
118     static const int themeStyle = WKMediaControllerThemeQuickTime;
119     GraphicsContextStateSaver stateSaver(*paintInfo.context);
120
121     switch (part) {
122     case MediaEnterFullscreenButton:
123     case MediaExitFullscreenButton:
124         if (MediaControlFullscreenButtonElement* btn = static_cast<MediaControlFullscreenButtonElement*>(o->node())) {
125             bool enterButton = btn->displayType() == MediaEnterFullscreenButton;
126             wkDrawMediaUIPart(enterButton ? WKMediaUIPartFullscreenButton : WKMediaUIPartExitFullscreenButton, themeStyle, paintInfo.context->platformContext(), r, determineState(o));
127         }
128         break;
129     case MediaShowClosedCaptionsButton:
130     case MediaHideClosedCaptionsButton:
131         if (MediaControlToggleClosedCaptionsButtonElement* btn = static_cast<MediaControlToggleClosedCaptionsButtonElement*>(o->node())) {
132             bool captionsVisible = btn->displayType() == MediaHideClosedCaptionsButton;
133             wkDrawMediaUIPart(captionsVisible ? WKMediaUIPartHideClosedCaptionsButton : WKMediaUIPartShowClosedCaptionsButton, themeStyle, paintInfo.context->platformContext(), r, determineState(o));
134         }
135         break;
136     case MediaMuteButton:
137     case MediaUnMuteButton:
138         if (MediaControlMuteButtonElement* btn = static_cast<MediaControlMuteButtonElement*>(o->node())) {
139             bool audioEnabled = btn->displayType() == MediaMuteButton;
140             wkDrawMediaUIPart(audioEnabled ? WKMediaUIPartMuteButton : WKMediaUIPartUnMuteButton, themeStyle, paintInfo.context->platformContext(), r, determineState(o));
141         }
142         break;
143     case MediaPauseButton:
144     case MediaPlayButton:
145         if (MediaControlPlayButtonElement* btn = static_cast<MediaControlPlayButtonElement*>(o->node())) {
146             bool canPlay = btn->displayType() == MediaPlayButton;
147             wkDrawMediaUIPart(canPlay ? WKMediaUIPartPlayButton : WKMediaUIPartPauseButton, themeStyle, paintInfo.context->platformContext(), r, determineState(o));
148         }
149         break;
150     case MediaRewindButton:
151         wkDrawMediaUIPart(WKMediaUIPartRewindButton, themeStyle, paintInfo.context->platformContext(), r, determineState(o));
152         break;
153     case MediaReturnToRealtimeButton:
154         wkDrawMediaUIPart(WKMediaUIPartSeekToRealtimeButton, themeStyle, paintInfo.context->platformContext(), r, determineState(o));
155         break;
156     case MediaSeekBackButton:
157         wkDrawMediaUIPart(WKMediaUIPartSeekBackButton, themeStyle, paintInfo.context->platformContext(), r, determineState(o));
158         break;
159     case MediaSeekForwardButton:
160         wkDrawMediaUIPart(WKMediaUIPartSeekForwardButton, themeStyle, paintInfo.context->platformContext(), r, determineState(o));
161         break;
162     case MediaSlider: {
163         if (HTMLMediaElement* mediaElement = toParentMediaElement(o)) {
164             FloatRect unzoomedRect = getUnzoomedRectAndAdjustCurrentContext(o, paintInfo, r);
165             wkDrawMediaSliderTrack(themeStyle, paintInfo.context->platformContext(), unzoomedRect, mediaElement->percentLoaded() * mediaElement->duration(), mediaElement->currentTime(), mediaElement->duration(), determineState(o));
166         }
167         break;
168     }
169     case MediaSliderThumb:
170         wkDrawMediaUIPart(WKMediaUIPartTimelineSliderThumb, themeStyle, paintInfo.context->platformContext(), r, determineState(o));
171         break;
172     case MediaVolumeSliderContainer:
173         wkDrawMediaUIPart(WKMediaUIPartVolumeSliderContainer, themeStyle, paintInfo.context->platformContext(), r, determineState(o));
174         break;
175     case MediaVolumeSlider:
176         wkDrawMediaUIPart(WKMediaUIPartVolumeSlider, themeStyle, paintInfo.context->platformContext(), r, determineState(o));
177         break;
178     case MediaVolumeSliderThumb:
179         wkDrawMediaUIPart(WKMediaUIPartVolumeSliderThumb, themeStyle, paintInfo.context->platformContext(), r, determineState(o));
180         break;
181     case MediaFullScreenVolumeSlider:
182         wkDrawMediaUIPart(WKMediaUIPartFullScreenVolumeSlider, themeStyle, paintInfo.context->platformContext(), r, determineState(o));
183         break;
184     case MediaFullScreenVolumeSliderThumb:
185         wkDrawMediaUIPart(WKMediaUIPartFullScreenVolumeSliderThumb, themeStyle, paintInfo.context->platformContext(), r, determineState(o));
186         break;
187     case MediaTimelineContainer:
188         wkDrawMediaUIPart(WKMediaUIPartBackground, themeStyle, paintInfo.context->platformContext(), r, determineState(o));
189         break;
190     case MediaCurrentTimeDisplay:
191         ASSERT_NOT_REACHED();
192         break;
193     case MediaTimeRemainingDisplay:
194         ASSERT_NOT_REACHED();
195         break;
196     case MediaControlsPanel:
197         ASSERT_NOT_REACHED();
198     case MediaTextTrackDisplayContainer:
199     case MediaTextTrackDisplay:
200         ASSERT_NOT_REACHED();
201         break;
202 }
203
204     return false;
205 }
206
207 #endif
208
209 IntPoint RenderMediaControls::volumeSliderOffsetFromMuteButton(RenderBox* muteButtonBox, const IntSize& size)
210 {
211     static const int xOffset = -4;
212     static const int yOffset = 5;
213
214     float zoomLevel = muteButtonBox->style()->effectiveZoom();
215     int y = yOffset * zoomLevel + muteButtonBox->pixelSnappedOffsetHeight() - size.height();
216     FloatPoint absPoint = muteButtonBox->localToAbsolute(FloatPoint(muteButtonBox->pixelSnappedOffsetLeft(), y), true, true);
217     if (absPoint.y() < 0)
218         y = muteButtonBox->pixelSnappedHeight();
219     return IntPoint(xOffset * zoomLevel, y);
220 }
221
222 }
223
224 #endif