Home | History | Annotate | Download | only in rendering
      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(RenderObject* o)
     92 {
     93     ControlPart part = o->style()->appearance();
     94 
     95     if (part != MediaSliderThumbPart && part != MediaVolumeSliderThumbPart)
     96         return;
     97 
     98     CGSize size;
     99     wkMeasureMediaUIPart(part == MediaSliderThumbPart ? MediaSliderThumb : MediaVolumeSliderThumb, WKMediaControllerThemeQuickTime, 0, &size);
    100 
    101     float zoomLevel = o->style()->effectiveZoom();
    102     o->style()->setWidth(Length(static_cast<int>(size.width * zoomLevel), Fixed));
    103     o->style()->setHeight(Length(static_cast<int>(size.height * zoomLevel), Fixed));
    104 }
    105 
    106 bool RenderMediaControls::paintMediaControlsPart(MediaControlElementType part, RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
    107 {
    108     static const int themeStyle = WKMediaControllerThemeQuickTime;
    109     paintInfo.context->save();
    110     switch (part) {
    111         case MediaFullscreenButton:
    112             wkDrawMediaUIPart(WKMediaUIPartFullscreenButton, themeStyle, paintInfo.context->platformContext(), r, determineState(o));
    113             break;
    114         case MediaShowClosedCaptionsButton:
    115         case MediaHideClosedCaptionsButton:
    116             if (MediaControlToggleClosedCaptionsButtonElement* btn = static_cast<MediaControlToggleClosedCaptionsButtonElement*>(o->node())) {
    117                 bool captionsVisible = btn->displayType() == MediaHideClosedCaptionsButton;
    118                 wkDrawMediaUIPart(captionsVisible ? WKMediaUIPartHideClosedCaptionsButton : WKMediaUIPartShowClosedCaptionsButton, themeStyle, paintInfo.context->platformContext(), r, determineState(o));
    119             }
    120             break;
    121         case MediaMuteButton:
    122         case MediaUnMuteButton:
    123             if (MediaControlMuteButtonElement* btn = static_cast<MediaControlMuteButtonElement*>(o->node())) {
    124                 bool audioEnabled = btn->displayType() == MediaMuteButton;
    125                 wkDrawMediaUIPart(audioEnabled ? WKMediaUIPartMuteButton : WKMediaUIPartUnMuteButton, themeStyle, paintInfo.context->platformContext(), r, determineState(o));
    126             }
    127             break;
    128         case MediaPauseButton:
    129         case MediaPlayButton:
    130             if (MediaControlPlayButtonElement* btn = static_cast<MediaControlPlayButtonElement*>(o->node())) {
    131                 bool canPlay = btn->displayType() == MediaPlayButton;
    132                 wkDrawMediaUIPart(canPlay ? WKMediaUIPartPlayButton : WKMediaUIPartPauseButton, themeStyle, paintInfo.context->platformContext(), r, determineState(o));
    133             }
    134             break;
    135         case MediaRewindButton:
    136             wkDrawMediaUIPart(WKMediaUIPartRewindButton, themeStyle, paintInfo.context->platformContext(), r, determineState(o));
    137             break;
    138         case MediaSeekBackButton:
    139             wkDrawMediaUIPart(WKMediaUIPartSeekBackButton, themeStyle, paintInfo.context->platformContext(), r, determineState(o));
    140             break;
    141         case MediaSeekForwardButton:
    142             wkDrawMediaUIPart(WKMediaUIPartSeekForwardButton, themeStyle, paintInfo.context->platformContext(), r, determineState(o));
    143             break;
    144         case MediaSlider: {
    145             if (HTMLMediaElement* mediaElement = toParentMediaElement(o)) {
    146                 FloatRect unzoomedRect = getUnzoomedRectAndAdjustCurrentContext(o, paintInfo, r);
    147                 wkDrawMediaSliderTrack(themeStyle, paintInfo.context->platformContext(), unzoomedRect, mediaElement->percentLoaded() * mediaElement->duration(), mediaElement->currentTime(), mediaElement->duration(), determineState(o));
    148             }
    149             break;
    150         }
    151         case MediaSliderThumb:
    152             wkDrawMediaUIPart(WKMediaUIPartTimelineSliderThumb, themeStyle, paintInfo.context->platformContext(), r, determineState(o));
    153             break;
    154         case MediaVolumeSliderContainer:
    155             wkDrawMediaUIPart(WKMediaUIPartVolumeSliderContainer, themeStyle, paintInfo.context->platformContext(), r, determineState(o));
    156             break;
    157         case MediaVolumeSlider:
    158             wkDrawMediaUIPart(WKMediaUIPartVolumeSlider, themeStyle, paintInfo.context->platformContext(), r, determineState(o));
    159             break;
    160         case MediaVolumeSliderThumb:
    161             wkDrawMediaUIPart(WKMediaUIPartVolumeSliderThumb, themeStyle, paintInfo.context->platformContext(), r, determineState(o));
    162             break;
    163         case MediaTimelineContainer:
    164             wkDrawMediaUIPart(WKMediaUIPartBackground, themeStyle, paintInfo.context->platformContext(), r, determineState(o));
    165             break;
    166         case MediaCurrentTimeDisplay:
    167             ASSERT_NOT_REACHED();
    168             break;
    169         case MediaTimeRemainingDisplay:
    170             ASSERT_NOT_REACHED();
    171             break;
    172         case MediaControlsPanel:
    173             ASSERT_NOT_REACHED();
    174             break;
    175     }
    176     paintInfo.context->restore();
    177 
    178     return false;
    179 }
    180 
    181 #endif
    182 
    183 IntPoint RenderMediaControls::volumeSliderOffsetFromMuteButton(RenderBox* muteButtonBox, const IntSize& size)
    184 {
    185     static const int xOffset = -4;
    186     static const int yOffset = 5;
    187 
    188     float zoomLevel = muteButtonBox->style()->effectiveZoom();
    189     int y = yOffset * zoomLevel + muteButtonBox->offsetHeight() - size.height();
    190     FloatPoint absPoint = muteButtonBox->localToAbsolute(FloatPoint(muteButtonBox->offsetLeft(), y), true, true);
    191     if (absPoint.y() < 0)
    192         y = muteButtonBox->height();
    193     return IntPoint(xOffset * zoomLevel, y);
    194 }
    195 
    196 }
    197 
    198 #endif
    199