summaryrefslogtreecommitdiffstats
path: root/WebCore/rendering/RenderMedia.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/rendering/RenderMedia.cpp')
-rw-r--r--WebCore/rendering/RenderMedia.cpp156
1 files changed, 112 insertions, 44 deletions
diff --git a/WebCore/rendering/RenderMedia.cpp b/WebCore/rendering/RenderMedia.cpp
index b87e99d..7100435 100644
--- a/WebCore/rendering/RenderMedia.cpp
+++ b/WebCore/rendering/RenderMedia.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -33,6 +33,7 @@
#include "HTMLNames.h"
#include "MediaControlElements.h"
#include "MouseEvent.h"
+#include "RenderTheme.h"
#include <wtf/CurrentTime.h>
#include <wtf/MathExtras.h>
@@ -44,32 +45,30 @@ using namespace HTMLNames;
static const double cTimeUpdateRepeatDelay = 0.2;
static const double cOpacityAnimationRepeatDelay = 0.05;
-// FIXME get this from style
-static const double cOpacityAnimationDurationFadeIn = 0.1;
-static const double cOpacityAnimationDurationFadeOut = 0.3;
RenderMedia::RenderMedia(HTMLMediaElement* video)
- : RenderReplaced(video)
+ : RenderImage(video)
, m_timeUpdateTimer(this, &RenderMedia::timeUpdateTimerFired)
, m_opacityAnimationTimer(this, &RenderMedia::opacityAnimationTimerFired)
, m_mouseOver(false)
, m_opacityAnimationStartTime(0)
- , m_opacityAnimationDuration(cOpacityAnimationDurationFadeIn)
+ , m_opacityAnimationDuration(0)
, m_opacityAnimationFrom(0)
, m_opacityAnimationTo(1.0f)
{
}
RenderMedia::RenderMedia(HTMLMediaElement* video, const IntSize& intrinsicSize)
- : RenderReplaced(video, intrinsicSize)
+ : RenderImage(video)
, m_timeUpdateTimer(this, &RenderMedia::timeUpdateTimerFired)
, m_opacityAnimationTimer(this, &RenderMedia::opacityAnimationTimerFired)
, m_mouseOver(false)
, m_opacityAnimationStartTime(0)
- , m_opacityAnimationDuration(cOpacityAnimationDurationFadeIn)
+ , m_opacityAnimationDuration(0)
, m_opacityAnimationFrom(0)
, m_opacityAnimationTo(1.0f)
{
+ setIntrinsicSize(intrinsicSize);
}
RenderMedia::~RenderMedia()
@@ -88,7 +87,7 @@ void RenderMedia::destroy()
m_controlsShadowRoot->detach();
m_controlsShadowRoot = 0;
}
- RenderReplaced::destroy();
+ RenderImage::destroy();
}
HTMLMediaElement* RenderMedia::mediaElement() const
@@ -103,7 +102,7 @@ MediaPlayer* RenderMedia::player() const
void RenderMedia::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
{
- RenderReplaced::styleDidChange(diff, oldStyle);
+ RenderImage::styleDidChange(diff, oldStyle);
if (m_controlsShadowRoot) {
if (m_panel)
@@ -120,6 +119,8 @@ void RenderMedia::styleDidChange(StyleDifference diff, const RenderStyle* oldSty
m_rewindButton->updateStyle();
if (m_returnToRealtimeButton)
m_returnToRealtimeButton->updateStyle();
+ if (m_toggleClosedCaptionsButton)
+ m_toggleClosedCaptionsButton->updateStyle();
if (m_statusDisplay)
m_statusDisplay->updateStyle();
if (m_timelineContainer)
@@ -132,6 +133,10 @@ void RenderMedia::styleDidChange(StyleDifference diff, const RenderStyle* oldSty
m_currentTimeDisplay->updateStyle();
if (m_timeRemainingDisplay)
m_timeRemainingDisplay->updateStyle();
+ if (m_volumeSliderContainer)
+ m_volumeSliderContainer->updateStyle();
+ if (m_volumeSlider)
+ m_volumeSlider->updateStyle();
}
}
@@ -139,7 +144,7 @@ void RenderMedia::layout()
{
IntSize oldSize = contentBoxRect().size();
- RenderReplaced::layout();
+ RenderImage::layout();
RenderBox* controlsRenderer = m_controlsShadowRoot ? m_controlsShadowRoot->renderBox() : 0;
if (!controlsRenderer)
@@ -218,6 +223,13 @@ void RenderMedia::createReturnToRealtimeButton()
m_returnToRealtimeButton->attachToParent(m_panel.get());
}
+void RenderMedia::createToggleClosedCaptionsButton()
+{
+ ASSERT(!m_toggleClosedCaptionsButton);
+ m_toggleClosedCaptionsButton = new MediaControlToggleClosedCaptionsButtonElement(document(), mediaElement());
+ m_toggleClosedCaptionsButton->attachToParent(m_panel.get());
+}
+
void RenderMedia::createStatusDisplay()
{
ASSERT(!m_statusDisplay);
@@ -240,6 +252,23 @@ void RenderMedia::createTimeline()
m_timeline->attachToParent(m_timelineContainer.get());
}
+void RenderMedia::createVolumeSliderContainer()
+{
+ ASSERT(!m_volumeSliderContainer);
+ m_volumeSliderContainer = new MediaControlVolumeSliderContainerElement(document(), mediaElement());
+ m_volumeSliderContainer->attachToParent(m_panel.get());
+}
+
+void RenderMedia::createVolumeSlider()
+{
+ ASSERT(!m_volumeSlider);
+ m_volumeSlider = new MediaControlVolumeSliderElement(document(), mediaElement());
+ m_volumeSlider->setAttribute(precisionAttr, "float");
+ m_volumeSlider->setAttribute(maxAttr, "1");
+ m_volumeSlider->setAttribute(valueAttr, String::number(mediaElement()->volume()));
+ m_volumeSlider->attachToParent(m_volumeSliderContainer.get());
+}
+
void RenderMedia::createCurrentTimeDisplay()
{
ASSERT(!m_currentTimeDisplay);
@@ -285,7 +314,10 @@ void RenderMedia::updateControls()
m_currentTimeDisplay = 0;
m_timeRemainingDisplay = 0;
m_fullscreenButton = 0;
+ m_volumeSliderContainer = 0;
+ m_volumeSlider = 0;
m_controlsShadowRoot = 0;
+ m_toggleClosedCaptionsButton = 0;
}
m_opacityAnimationTo = 1.0f;
m_opacityAnimationTimer.stop();
@@ -298,19 +330,23 @@ void RenderMedia::updateControls()
createPanel();
if (m_panel) {
createRewindButton();
- createMuteButton();
createPlayButton();
createReturnToRealtimeButton();
createStatusDisplay();
createTimelineContainer();
- createSeekBackButton();
- createSeekForwardButton();
- createFullscreenButton();
if (m_timelineContainer) {
createCurrentTimeDisplay();
createTimeline();
createTimeRemainingDisplay();
}
+ createSeekBackButton();
+ createSeekForwardButton();
+ createToggleClosedCaptionsButton();
+ createFullscreenButton();
+ createMuteButton();
+ createVolumeSliderContainer();
+ if (m_volumeSliderContainer)
+ createVolumeSlider();
m_panel->attach();
}
}
@@ -336,6 +372,8 @@ void RenderMedia::updateControls()
m_playButton->update();
if (m_timelineContainer)
m_timelineContainer->update();
+ if (m_volumeSliderContainer)
+ m_volumeSliderContainer->update();
if (m_timeline)
m_timeline->update();
if (m_currentTimeDisplay)
@@ -350,10 +388,14 @@ void RenderMedia::updateControls()
m_rewindButton->update();
if (m_returnToRealtimeButton)
m_returnToRealtimeButton->update();
+ if (m_toggleClosedCaptionsButton)
+ m_toggleClosedCaptionsButton->update();
if (m_statusDisplay)
m_statusDisplay->update();
if (m_fullscreenButton)
m_fullscreenButton->update();
+ if (m_volumeSlider)
+ m_volumeSlider->update();
updateTimeDisplay();
updateControlVisibility();
@@ -366,37 +408,20 @@ void RenderMedia::timeUpdateTimerFired(Timer<RenderMedia>*)
updateTimeDisplay();
}
-String RenderMedia::formatTime(float time)
-{
- if (!isfinite(time))
- time = 0;
- int seconds = (int)fabsf(time);
- int hours = seconds / (60 * 60);
- int minutes = (seconds / 60) % 60;
- seconds %= 60;
- if (hours) {
- if (hours > 9)
- return String::format("%s%02d:%02d:%02d", (time < 0 ? "-" : ""), hours, minutes, seconds);
- else
- return String::format("%s%01d:%02d:%02d", (time < 0 ? "-" : ""), hours, minutes, seconds);
- }
- else
- return String::format("%s%02d:%02d", (time < 0 ? "-" : ""), minutes, seconds);
-}
-
void RenderMedia::updateTimeDisplay()
{
if (!m_currentTimeDisplay || !m_currentTimeDisplay->renderer() || m_currentTimeDisplay->renderer()->style()->display() == NONE || style()->visibility() != VISIBLE)
return;
+
float now = mediaElement()->currentTime();
float duration = mediaElement()->duration();
- String timeString = formatTime(now);
+ // Allow the theme to format the time
ExceptionCode ec;
- m_currentTimeDisplay->setInnerText(timeString, ec);
-
- timeString = formatTime(now - duration);
- m_timeRemainingDisplay->setInnerText(timeString, ec);
+ m_currentTimeDisplay->setInnerText(theme()->formatMediaControlsCurrentTime(now, duration), ec);
+ m_currentTimeDisplay->setCurrentValue(now);
+ m_timeRemainingDisplay->setInnerText(theme()->formatMediaControlsRemainingTime(now, duration), ec);
+ m_timeRemainingDisplay->setCurrentValue(now - duration);
}
void RenderMedia::updateControlVisibility()
@@ -430,9 +455,9 @@ void RenderMedia::updateControlVisibility()
}
if (animateFrom < animateTo)
- m_opacityAnimationDuration = cOpacityAnimationDurationFadeIn;
+ m_opacityAnimationDuration = m_panel->renderer()->theme()->mediaControlsFadeInDuration();
else
- m_opacityAnimationDuration = cOpacityAnimationDurationFadeOut;
+ m_opacityAnimationDuration = m_panel->renderer()->theme()->mediaControlsFadeOutDuration();
m_opacityAnimationFrom = animateFrom;
m_opacityAnimationTo = animateTo;
@@ -463,13 +488,53 @@ void RenderMedia::opacityAnimationTimerFired(Timer<RenderMedia>*)
changeOpacity(m_panel.get(), opacity);
}
+void RenderMedia::updateVolumeSliderContainer(bool visible)
+{
+ if (!mediaElement()->hasAudio() || !m_volumeSliderContainer || !m_volumeSlider)
+ return;
+
+ if (visible && !m_volumeSliderContainer->isVisible()) {
+ if (!m_muteButton || !m_muteButton->renderer() || !m_muteButton->renderBox())
+ return;
+
+ RefPtr<RenderStyle> s = m_volumeSliderContainer->styleForElement();
+ int height = s->height().isPercent() ? 0 : s->height().value();
+ int x = m_muteButton->renderBox()->offsetLeft();
+ int y = m_muteButton->renderBox()->offsetTop() - height;
+ FloatPoint absPoint = m_muteButton->renderer()->localToAbsolute(FloatPoint(x, y), true, true);
+ if (absPoint.y() < 0)
+ y = m_muteButton->renderBox()->offsetTop() + m_muteButton->renderBox()->height();
+ m_volumeSliderContainer->setVisible(true);
+ m_volumeSliderContainer->setPosition(x, y);
+ m_volumeSliderContainer->update();
+ m_volumeSlider->update();
+ } else if (!visible && m_volumeSliderContainer->isVisible()) {
+ m_volumeSliderContainer->setVisible(false);
+ m_volumeSliderContainer->updateStyle();
+ }
+}
+
void RenderMedia::forwardEvent(Event* event)
{
if (event->isMouseEvent() && m_controlsShadowRoot) {
MouseEvent* mouseEvent = static_cast<MouseEvent*>(event);
IntPoint point(mouseEvent->absoluteLocation());
- if (m_muteButton && m_muteButton->hitTest(point))
+ bool showVolumeSlider = false;
+ if (m_muteButton && m_muteButton->hitTest(point)) {
m_muteButton->defaultEventHandler(event);
+ if (event->type() != eventNames().mouseoutEvent)
+ showVolumeSlider = true;
+ }
+
+ if (m_volumeSliderContainer && m_volumeSliderContainer->hitTest(point))
+ showVolumeSlider = true;
+
+ if (m_volumeSlider && m_volumeSlider->hitTest(point)) {
+ m_volumeSlider->defaultEventHandler(event);
+ showVolumeSlider = true;
+ }
+
+ updateVolumeSliderContainer(showVolumeSlider);
if (m_playButton && m_playButton->hitTest(point))
m_playButton->defaultEventHandler(event);
@@ -486,6 +551,9 @@ void RenderMedia::forwardEvent(Event* event)
if (m_returnToRealtimeButton && m_returnToRealtimeButton->hitTest(point))
m_returnToRealtimeButton->defaultEventHandler(event);
+ if (m_toggleClosedCaptionsButton && m_toggleClosedCaptionsButton->hitTest(point))
+ m_toggleClosedCaptionsButton->defaultEventHandler(event);
+
if (m_timeline && m_timeline->hitTest(point))
m_timeline->defaultEventHandler(event);
@@ -508,7 +576,7 @@ void RenderMedia::forwardEvent(Event* event)
int RenderMedia::lowestPosition(bool includeOverflowInterior, bool includeSelf) const
{
- int bottom = RenderReplaced::lowestPosition(includeOverflowInterior, includeSelf);
+ int bottom = RenderImage::lowestPosition(includeOverflowInterior, includeSelf);
if (!m_controlsShadowRoot || !m_controlsShadowRoot->renderer())
return bottom;
@@ -517,7 +585,7 @@ int RenderMedia::lowestPosition(bool includeOverflowInterior, bool includeSelf)
int RenderMedia::rightmostPosition(bool includeOverflowInterior, bool includeSelf) const
{
- int right = RenderReplaced::rightmostPosition(includeOverflowInterior, includeSelf);
+ int right = RenderImage::rightmostPosition(includeOverflowInterior, includeSelf);
if (!m_controlsShadowRoot || !m_controlsShadowRoot->renderer())
return right;
@@ -526,7 +594,7 @@ int RenderMedia::rightmostPosition(bool includeOverflowInterior, bool includeSel
int RenderMedia::leftmostPosition(bool includeOverflowInterior, bool includeSelf) const
{
- int left = RenderReplaced::leftmostPosition(includeOverflowInterior, includeSelf);
+ int left = RenderImage::leftmostPosition(includeOverflowInterior, includeSelf);
if (!m_controlsShadowRoot || !m_controlsShadowRoot->renderer())
return left;