2 * Copyright (C) 2009 Apple Inc. All Rights Reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
30 #include "RenderMediaControls.h"
32 #include "GraphicsContext.h"
33 #include "HTMLMediaElement.h"
34 #include "HTMLNames.h"
35 #include "PaintInfo.h"
36 #include "RenderTheme.h"
38 // FIXME: Unify more of the code for Mac and Win.
41 #include <CoreGraphics/CoreGraphics.h>
42 #include <WebKitSystemInterface/WebKitSystemInterface.h>
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)
60 static WKMediaControllerThemeState determineState(RenderObject* o)
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);
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)
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());
88 static const int mediaSliderThumbWidth = 13;
89 static const int mediaSliderThumbHeight = 14;
91 void RenderMediaControls::adjustMediaSliderThumbSize(RenderStyle* style)
94 switch (style->appearance()) {
95 case MediaSliderThumbPart:
96 part = MediaSliderThumb;
98 case MediaVolumeSliderThumbPart:
99 part = MediaVolumeSliderThumb;
101 case MediaFullScreenVolumeSliderThumbPart:
102 part = MediaFullScreenVolumeSliderThumb;
109 wkMeasureMediaUIPart(part, WKMediaControllerThemeQuickTime, 0, &size);
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));
116 bool RenderMediaControls::paintMediaControlsPart(MediaControlElementType part, RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
118 static const int themeStyle = WKMediaControllerThemeQuickTime;
119 GraphicsContextStateSaver stateSaver(*paintInfo.context);
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));
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));
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));
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));
150 case MediaRewindButton:
151 wkDrawMediaUIPart(WKMediaUIPartRewindButton, themeStyle, paintInfo.context->platformContext(), r, determineState(o));
153 case MediaReturnToRealtimeButton:
154 wkDrawMediaUIPart(WKMediaUIPartSeekToRealtimeButton, themeStyle, paintInfo.context->platformContext(), r, determineState(o));
156 case MediaSeekBackButton:
157 wkDrawMediaUIPart(WKMediaUIPartSeekBackButton, themeStyle, paintInfo.context->platformContext(), r, determineState(o));
159 case MediaSeekForwardButton:
160 wkDrawMediaUIPart(WKMediaUIPartSeekForwardButton, themeStyle, paintInfo.context->platformContext(), r, determineState(o));
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));
169 case MediaSliderThumb:
170 wkDrawMediaUIPart(WKMediaUIPartTimelineSliderThumb, themeStyle, paintInfo.context->platformContext(), r, determineState(o));
172 case MediaVolumeSliderContainer:
173 wkDrawMediaUIPart(WKMediaUIPartVolumeSliderContainer, themeStyle, paintInfo.context->platformContext(), r, determineState(o));
175 case MediaVolumeSlider:
176 wkDrawMediaUIPart(WKMediaUIPartVolumeSlider, themeStyle, paintInfo.context->platformContext(), r, determineState(o));
178 case MediaVolumeSliderThumb:
179 wkDrawMediaUIPart(WKMediaUIPartVolumeSliderThumb, themeStyle, paintInfo.context->platformContext(), r, determineState(o));
181 case MediaFullScreenVolumeSlider:
182 wkDrawMediaUIPart(WKMediaUIPartFullScreenVolumeSlider, themeStyle, paintInfo.context->platformContext(), r, determineState(o));
184 case MediaFullScreenVolumeSliderThumb:
185 wkDrawMediaUIPart(WKMediaUIPartFullScreenVolumeSliderThumb, themeStyle, paintInfo.context->platformContext(), r, determineState(o));
187 case MediaTimelineContainer:
188 wkDrawMediaUIPart(WKMediaUIPartBackground, themeStyle, paintInfo.context->platformContext(), r, determineState(o));
190 case MediaCurrentTimeDisplay:
191 ASSERT_NOT_REACHED();
193 case MediaTimeRemainingDisplay:
194 ASSERT_NOT_REACHED();
196 case MediaControlsPanel:
197 ASSERT_NOT_REACHED();
198 case MediaTextTrackDisplayContainer:
199 case MediaTextTrackDisplay:
200 ASSERT_NOT_REACHED();
209 IntPoint RenderMediaControls::volumeSliderOffsetFromMuteButton(RenderBox* muteButtonBox, const IntSize& size)
211 static const int xOffset = -4;
212 static const int yOffset = 5;
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);