RenderMediaControlsChromium.cpp [plain text]
#include "config.h"
#include "RenderMediaControlsChromium.h"
#include "Gradient.h"
#include "GraphicsContext.h"
#include "HTMLMediaElement.h"
#include "HTMLNames.h"
namespace WebCore {
#if ENABLE(VIDEO)
typedef WTF::HashMap<const char*, Image*> MediaControlImageMap;
static MediaControlImageMap* gMediaControlImageMap = 0;
static Image* platformResource(const char* name)
{
if (!gMediaControlImageMap)
gMediaControlImageMap = new MediaControlImageMap();
if (Image* image = gMediaControlImageMap->get(name))
return image;
if (Image* image = Image::loadPlatformResource(name).releaseRef()) {
gMediaControlImageMap->set(name, image);
return image;
}
ASSERT_NOT_REACHED();
return 0;
}
static bool hasSource(const HTMLMediaElement* mediaElement)
{
return mediaElement->networkState() != HTMLMediaElement::NETWORK_EMPTY
&& mediaElement->networkState() != HTMLMediaElement::NETWORK_NO_SOURCE;
}
static bool paintMediaButton(GraphicsContext* context, const IntRect& rect, Image* image)
{
IntRect imageRect = image->rect();
context->drawImage(image, DeviceColorSpace, rect);
return true;
}
static bool paintMediaMuteButton(RenderObject* object, const RenderObject::PaintInfo& paintInfo, const IntRect& rect)
{
HTMLMediaElement* mediaElement = toParentMediaElement(object);
if (!mediaElement)
return false;
static Image* soundFull = platformResource("mediaSoundFull");
static Image* soundNone = platformResource("mediaSoundNone");
static Image* soundDisabled = platformResource("mediaSoundDisabled");
if (!hasSource(mediaElement) || !mediaElement->hasAudio())
return paintMediaButton(paintInfo.context, rect, soundDisabled);
return paintMediaButton(paintInfo.context, rect, mediaElement->muted() ? soundNone: soundFull);
}
static bool paintMediaPlayButton(RenderObject* object, const RenderObject::PaintInfo& paintInfo, const IntRect& rect)
{
HTMLMediaElement* mediaElement = toParentMediaElement(object);
if (!mediaElement)
return false;
static Image* mediaPlay = platformResource("mediaPlay");
static Image* mediaPause = platformResource("mediaPause");
static Image* mediaPlayDisabled = platformResource("mediaPlayDisabled");
if (!hasSource(mediaElement))
return paintMediaButton(paintInfo.context, rect, mediaPlayDisabled);
return paintMediaButton(paintInfo.context, rect, mediaElement->paused() ? mediaPlay : mediaPause);
}
static bool paintMediaSlider(RenderObject* object, const RenderObject::PaintInfo& paintInfo, const IntRect& rect)
{
HTMLMediaElement* mediaElement = toParentMediaElement(object);
if (!mediaElement)
return false;
RenderStyle* style = object->style();
GraphicsContext* context = paintInfo.context;
context->save();
context->setShouldAntialias(true);
context->setStrokeStyle(SolidStroke);
context->setStrokeColor(style->visitedDependentColor(CSSPropertyBorderLeftColor), DeviceColorSpace);
context->setStrokeThickness(style->borderLeftWidth());
context->setFillColor(style->visitedDependentColor(CSSPropertyBackgroundColor), DeviceColorSpace);
context->drawRect(rect);
context->restore();
IntRect bufferedRect = rect;
bufferedRect.inflate(-style->borderLeftWidth());
bufferedRect.setWidth((bufferedRect.width() * mediaElement->percentLoaded()));
if (!bufferedRect.isEmpty()) {
IntPoint sliderTopLeft = bufferedRect.location();
IntPoint sliderTopRight = sliderTopLeft;
sliderTopRight.move(0, bufferedRect.height());
RefPtr<Gradient> gradient = Gradient::create(sliderTopLeft, sliderTopRight);
Color startColor = object->style()->visitedDependentColor(CSSPropertyColor);
gradient->addColorStop(0.0, startColor);
gradient->addColorStop(1.0, Color(startColor.red() / 2, startColor.green() / 2, startColor.blue() / 2, startColor.alpha()));
context->save();
context->setStrokeStyle(NoStroke);
context->setFillGradient(gradient);
context->fillRect(bufferedRect);
context->restore();
}
return true;
}
static bool paintMediaSliderThumb(RenderObject* object, const RenderObject::PaintInfo& paintInfo, const IntRect& rect)
{
if (!object->parent()->isSlider())
return false;
HTMLMediaElement* mediaElement = toParentMediaElement(object->parent());
if (!mediaElement)
return false;
if (!hasSource(mediaElement))
return true;
static Image* mediaSliderThumb = platformResource("mediaSliderThumb");
return paintMediaButton(paintInfo.context, rect, mediaSliderThumb);
}
static bool paintMediaVolumeSlider(RenderObject* object, const RenderObject::PaintInfo& paintInfo, const IntRect& rect)
{
HTMLMediaElement* mediaElement = toParentMediaElement(object);
if (!mediaElement)
return false;
GraphicsContext* context = paintInfo.context;
Color originalColor = context->strokeColor();
if (originalColor != Color::white)
context->setStrokeColor(Color::white, DeviceColorSpace);
int x = rect.x() + rect.width() / 2;
context->drawLine(IntPoint(x, rect.y()), IntPoint(x, rect.y() + rect.height()));
if (originalColor != Color::white)
context->setStrokeColor(originalColor, DeviceColorSpace);
return true;
}
static bool paintMediaVolumeSliderThumb(RenderObject* object, const RenderObject::PaintInfo& paintInfo, const IntRect& rect)
{
if (!object->parent()->isSlider())
return false;
static Image* mediaVolumeSliderThumb = platformResource("mediaVolumeSliderThumb");
return paintMediaButton(paintInfo.context, rect, mediaVolumeSliderThumb);
}
static bool paintMediaTimelineContainer(RenderObject* object, const RenderObject::PaintInfo& paintInfo, const IntRect& rect)
{
HTMLMediaElement* mediaElement = toParentMediaElement(object);
if (!mediaElement)
return false;
if (!rect.isEmpty()) {
GraphicsContext* context = paintInfo.context;
Color originalColor = context->strokeColor();
float originalThickness = context->strokeThickness();
StrokeStyle originalStyle = context->strokeStyle();
context->setStrokeStyle(SolidStroke);
context->setStrokeThickness(object->style()->borderLeftWidth());
context->setStrokeColor(object->style()->visitedDependentColor(CSSPropertyBorderLeftColor).rgb(), DeviceColorSpace);
context->drawLine(IntPoint(rect.x() + 1, rect.y()),
IntPoint(rect.x() + 1, rect.y() + rect.height()));
context->setStrokeThickness(object->style()->borderRightWidth());
context->setStrokeColor(object->style()->visitedDependentColor(CSSPropertyBorderRightColor).rgb(), DeviceColorSpace);
context->drawLine(IntPoint(rect.x() + rect.width() - 1, rect.y()),
IntPoint(rect.x() + rect.width() - 1, rect.y() + rect.height()));
context->setStrokeColor(originalColor, DeviceColorSpace);
context->setStrokeThickness(originalThickness);
context->setStrokeStyle(originalStyle);
}
return true;
}
bool RenderMediaControlsChromium::shouldRenderMediaControlPart(ControlPart part, Element* e)
{
UNUSED_PARAM(e);
switch (part) {
case MediaMuteButtonPart:
case MediaPlayButtonPart:
case MediaSliderPart:
case MediaSliderThumbPart:
case MediaVolumeSliderContainerPart:
case MediaVolumeSliderPart:
case MediaVolumeSliderThumbPart:
case MediaControlsBackgroundPart:
case MediaCurrentTimePart:
case MediaTimeRemainingPart:
return true;
default:
;
}
return false;
}
bool RenderMediaControlsChromium::paintMediaControlsPart(MediaControlElementType part, RenderObject* object, const RenderObject::PaintInfo& paintInfo, const IntRect& rect)
{
switch (part) {
case MediaMuteButton:
case MediaUnMuteButton:
return paintMediaMuteButton(object, paintInfo, rect);
case MediaPauseButton:
case MediaPlayButton:
return paintMediaPlayButton(object, paintInfo, rect);
case MediaSlider:
return paintMediaSlider(object, paintInfo, rect);
case MediaSliderThumb:
return paintMediaSliderThumb(object, paintInfo, rect);
case MediaVolumeSlider:
return paintMediaVolumeSlider(object, paintInfo, rect);
case MediaVolumeSliderThumb:
return paintMediaVolumeSliderThumb(object, paintInfo, rect);
case MediaTimelineContainer:
return paintMediaTimelineContainer(object, paintInfo, rect);
case MediaFullscreenButton:
case MediaSeekBackButton:
case MediaSeekForwardButton:
case MediaVolumeSliderContainer:
case MediaCurrentTimeDisplay:
case MediaTimeRemainingDisplay:
case MediaControlsPanel:
case MediaRewindButton:
case MediaReturnToRealtimeButton:
case MediaStatusDisplay:
case MediaShowClosedCaptionsButton:
case MediaHideClosedCaptionsButton:
ASSERT_NOT_REACHED();
break;
}
return false;
}
void RenderMediaControlsChromium::adjustMediaSliderThumbSize(RenderObject* object)
{
static Image* mediaSliderThumb = platformResource("mediaSliderThumb");
static Image* mediaVolumeSliderThumb = platformResource("mediaVolumeSliderThumb");
Image* thumbImage = 0;
if (object->style()->appearance() == MediaSliderThumbPart)
thumbImage = mediaSliderThumb;
else if (object->style()->appearance() == MediaVolumeSliderThumbPart)
thumbImage = mediaVolumeSliderThumb;
float zoomLevel = object->style()->effectiveZoom();
if (thumbImage) {
object->style()->setWidth(Length(static_cast<int>(thumbImage->width() * zoomLevel), Fixed));
object->style()->setHeight(Length(static_cast<int>(thumbImage->height() * zoomLevel), Fixed));
}
}
#endif // #if ENABLE(VIDEO)
}