From: Nicolas Roard Date: Mon, 14 Mar 2011 20:23:18 +0000 (-0700) Subject: Improving HTML5 video controls X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=833c9ceaa300f52cf2d1b12a9b3482ad417a3c21;p=android-x86%2Fexternal-webkit.git Improving HTML5 video controls - correct support for the fullscreen button - change the controls to be 48px high - auto-hide the controls, touching the video makes them appear again bug:2126902 Change-Id: Idd2b720034de3d5d432c9ea62d9045934c46f6c1 --- diff --git a/WebCore/css/mediaControlsAndroid.css b/WebCore/css/mediaControlsAndroid.css index f33c7d59e..77f8b0884 100644 --- a/WebCore/css/mediaControlsAndroid.css +++ b/WebCore/css/mediaControlsAndroid.css @@ -27,7 +27,7 @@ audio { width: 200px; - height: 32px; + height: 48px; } audio::-webkit-media-controls-panel, video::-webkit-media-controls-panel { @@ -40,26 +40,26 @@ audio::-webkit-media-controls-panel, video::-webkit-media-controls-panel { width: 100%; z-index: 0; overflow: hidden; - height: 32px; + height: 48px; text-align: right; } video:-webkit-full-page-media::-webkit-media-controls-panel { - bottom: -32px; + bottom: -48px; } audio::-webkit-media-controls-mute-button, video::-webkit-media-controls-mute-button { -webkit-appearance: media-mute-button; display: -webkit-box; - width: 32px; - height: 32px; + width: 48px; + height: 48px; } audio::-webkit-media-controls-play-button, video::-webkit-media-controls-play-button { -webkit-appearance: media-play-button; display: -webkit-box; - width: 32px; - height: 32px; + width: 48px; + height: 48px; } audio::-webkit-media-controls-timeline-container, video::-webkit-media-controls-timeline-container { @@ -70,7 +70,7 @@ audio::-webkit-media-controls-timeline-container, video::-webkit-media-controls- -webkit-box-pack: end; -webkit-box-flex: 1; -webkit-user-select: none; - height: 32px; + height: 48px; } audio::-webkit-media-controls-current-time-display, video::-webkit-media-controls-current-time-display { @@ -85,8 +85,8 @@ audio::-webkit-media-controls-timeline, video::-webkit-media-controls-timeline { -webkit-appearance: media-slider; display: -webkit-box; -webkit-box-flex: 1; - height: 32px; - padding: 0px 2px; + height: 48px; + padding: 0px 0px; } audio::-webkit-media-controls-volume-slider-container, video::-webkit-media-controls-volume-slider-container { @@ -100,22 +100,22 @@ audio::-webkit-media-controls-volume-slider, video::-webkit-media-controls-volum audio::-webkit-media-controls-seek-back-button, video::-webkit-media-controls-seek-back-button { -webkit-appearance: media-seek-back-button; display: -webkit-box; - width: 32px; - height: 32px; + width: 48px; + height: 48px; } audio::-webkit-media-controls-seek-forward-button, video::-webkit-media-controls-seek-forward-button { -webkit-appearance: media-seek-forward-button; display: -webkit-box; - width: 32px; - height: 32px; + width: 48px; + height: 48px; } audio::-webkit-media-controls-fullscreen-button, video::-webkit-media-controls-fullscreen-button { - -webkit-appearance: media-play-button; + -webkit-appearance: media-fullscreen-button; display: -webkit-box; - width: 32px; - height: 32px; + width: 48px; + height: 48px; } audio::-webkit-media-controls-rewind-button, video::-webkit-media-controls-rewind-button { @@ -129,6 +129,6 @@ audio::-webkit-media-controls-return-to-realtime-button, video::-webkit-media-co audio::-webkit-media-controls-toggle-closed-captions-button, video::-webkit-media-controls-toggle-closed-captions-button { -webkit-appearance: media-toggle-closed-captions-button; display: -webkit-box; - width: 32px; - height: 32px + width: 48px; + height: 48px } diff --git a/WebCore/platform/android/RenderThemeAndroid.cpp b/WebCore/platform/android/RenderThemeAndroid.cpp index 525321930..5a0bfb8b1 100644 --- a/WebCore/platform/android/RenderThemeAndroid.cpp +++ b/WebCore/platform/android/RenderThemeAndroid.cpp @@ -262,12 +262,12 @@ bool RenderThemeAndroid::shouldRenderMediaControlPart(ControlPart part, Element* } } -bool paintMediaFullscreenButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect& rect) +bool RenderThemeAndroid::paintMediaFullscreenButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect& rect) { bool translucent = false; if (o && toParentMediaElement(o) && toParentMediaElement(o)->hasTagName(HTMLNames::videoTag)) translucent = true; - RenderSkinMediaButton::Draw(getCanvasFromInfo(paintInfo), rect, RenderSkinMediaButton::PLAY, translucent); + RenderSkinMediaButton::Draw(getCanvasFromInfo(paintInfo), rect, RenderSkinMediaButton::FULLSCREEN, translucent); return false; } diff --git a/WebCore/platform/android/RenderThemeAndroid.h b/WebCore/platform/android/RenderThemeAndroid.h index 74820f2c9..8314a9cfc 100644 --- a/WebCore/platform/android/RenderThemeAndroid.h +++ b/WebCore/platform/android/RenderThemeAndroid.h @@ -81,13 +81,16 @@ protected: virtual String extraMediaControlsStyleSheet(); virtual void adjustSliderThumbSize(RenderObject* o) const; virtual bool shouldRenderMediaControlPart(ControlPart part, Element* e); - bool paintMediaMuteButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r); - bool paintMediaPlayButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r); - bool paintMediaSeekBackButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r); - bool paintMediaSeekForwardButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r); - bool paintMediaSliderTrack(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r); - bool paintMediaSliderThumb(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r); + virtual bool paintMediaFullscreenButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r); + virtual bool paintMediaMuteButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r); + virtual bool paintMediaPlayButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r); + virtual bool paintMediaSeekBackButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r); + virtual bool paintMediaSeekForwardButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r); + virtual bool paintMediaSliderTrack(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r); + virtual bool paintMediaSliderThumb(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r); virtual bool paintMediaControlsBackground(RenderObject* object, const PaintInfo& paintInfo, const IntRect& rect); + virtual double mediaControlsFadeInDuration() { return 0.5; } + virtual double mediaControlsFadeOutDuration() { return 0.5; } #endif virtual bool paintRadio(RenderObject*, const PaintInfo&, const IntRect&); diff --git a/WebCore/platform/graphics/android/MediaPlayerPrivateAndroid.h b/WebCore/platform/graphics/android/MediaPlayerPrivateAndroid.h index 66b35dd00..694879979 100644 --- a/WebCore/platform/graphics/android/MediaPlayerPrivateAndroid.h +++ b/WebCore/platform/graphics/android/MediaPlayerPrivateAndroid.h @@ -50,8 +50,9 @@ public: virtual IntSize naturalSize() const { return m_naturalSize; } - virtual bool hasAudio() const { return false; } - virtual bool hasVideo() const { return false; } + virtual bool supportsFullscreen() const = 0; + virtual bool hasAudio() const = 0; + virtual bool hasVideo() const = 0; virtual void setVisible(bool); diff --git a/WebCore/rendering/RenderMedia.cpp b/WebCore/rendering/RenderMedia.cpp index 49a536cfb..f19ca9602 100644 --- a/WebCore/rendering/RenderMedia.cpp +++ b/WebCore/rendering/RenderMedia.cpp @@ -39,6 +39,10 @@ #include #include +#if PLATFORM(ANDROID) +#define TOUCH_DELAY 4 +#endif + using namespace std; namespace WebCore { @@ -57,6 +61,9 @@ RenderMedia::RenderMedia(HTMLMediaElement* video) , m_opacityAnimationDuration(0) , m_opacityAnimationFrom(0) , m_opacityAnimationTo(1.0f) +#if PLATFORM(ANDROID) + , m_lastTouch(0) +#endif { setImageResource(RenderImageResource::create()); } @@ -70,6 +77,9 @@ RenderMedia::RenderMedia(HTMLMediaElement* video, const IntSize& intrinsicSize) , m_opacityAnimationDuration(0) , m_opacityAnimationFrom(0) , m_opacityAnimationTo(1.0f) +#if PLATFORM(ANDROID) + , m_lastTouch(0) +#endif { setImageResource(RenderImageResource::create()); setIntrinsicSize(intrinsicSize); @@ -456,7 +466,14 @@ void RenderMedia::updateControlVisibility() // Don't fade if the media element is not visible if (style()->visibility() != VISIBLE) return; - + +#if PLATFORM(ANDROID) + if (WTF::currentTime() - m_lastTouch > TOUCH_DELAY) + m_mouseOver = false; + else + m_mouseOver = true; +#endif + bool shouldHideController = !m_mouseOver && !media->canPlay(); // Do fading manually, css animations don't work with shadow trees @@ -535,6 +552,11 @@ void RenderMedia::updateVolumeSliderContainer(bool visible) void RenderMedia::forwardEvent(Event* event) { +#if PLATFORM(ANDROID) + if (event->isMouseEvent()) + m_lastTouch = WTF::currentTime(); +#endif + if (event->isMouseEvent() && m_controlsShadowRoot) { MouseEvent* mouseEvent = static_cast(event); IntPoint point(mouseEvent->absoluteLocation()); diff --git a/WebCore/rendering/RenderMedia.h b/WebCore/rendering/RenderMedia.h index aa725ff06..65fdc7dab 100644 --- a/WebCore/rendering/RenderMedia.h +++ b/WebCore/rendering/RenderMedia.h @@ -151,6 +151,9 @@ private: double m_opacityAnimationDuration; float m_opacityAnimationFrom; float m_opacityAnimationTo; +#if PLATFORM(ANDROID) + double m_lastTouch; +#endif }; inline RenderMedia* toRenderMedia(RenderObject* object) diff --git a/WebKit/android/RenderSkinMediaButton.cpp b/WebKit/android/RenderSkinMediaButton.cpp index f9da7cf52..c3ab80fac 100644 --- a/WebKit/android/RenderSkinMediaButton.cpp +++ b/WebKit/android/RenderSkinMediaButton.cpp @@ -51,6 +51,7 @@ static const PatchData gFiles[] = { "ic_media_pause.png", 0, 0 }, // MUTE { "ic_media_rew.png", 0, 0 }, // REWIND { "ic_media_ff.png", 0, 0 }, // FORWARD + { "ic_media_fullscreen.png", 0, 0 }, // FULLSCREEN { "btn_media_player_disabled.9.png", 0, 0 }, // BACKGROUND_SLIDER { "scrubber_track_holo_dark.9.png", 0, 0 }, // SLIDER_TRACK { "scrubber_control_holo.png", 0, 0 } // SLIDER_THUMB @@ -113,6 +114,7 @@ void RenderSkinMediaButton::Draw(SkCanvas* canvas, const IntRect& r, int buttonT case MUTE: case REWIND: case FORWARD: + case FULLSCREEN: { imageIndex = buttonType + 1; paint.setColor(backgroundColor); diff --git a/WebKit/android/RenderSkinMediaButton.h b/WebKit/android/RenderSkinMediaButton.h index 124db3218..bde31ebae 100644 --- a/WebKit/android/RenderSkinMediaButton.h +++ b/WebKit/android/RenderSkinMediaButton.h @@ -48,7 +48,7 @@ public: /** * Button types */ - enum { PAUSE, PLAY, MUTE, REWIND, FORWARD, BACKGROUND_SLIDER, SLIDER_TRACK, SLIDER_THUMB }; + enum { PAUSE, PLAY, MUTE, REWIND, FORWARD, FULLSCREEN, BACKGROUND_SLIDER, SLIDER_TRACK, SLIDER_THUMB }; /** * Slider dimensions */ diff --git a/WebKit/android/WebCoreSupport/MediaPlayerPrivateAndroid.cpp b/WebKit/android/WebCoreSupport/MediaPlayerPrivateAndroid.cpp index 8f84c2ff8..4cc9cf48a 100644 --- a/WebKit/android/WebCoreSupport/MediaPlayerPrivateAndroid.cpp +++ b/WebKit/android/WebCoreSupport/MediaPlayerPrivateAndroid.cpp @@ -103,6 +103,7 @@ void MediaPlayerPrivate::pause() return; m_paused = true; + m_player->playbackStateChanged(); env->CallVoidMethod(m_glue->m_javaProxy, m_glue->m_pause); checkException(env); } @@ -162,6 +163,7 @@ void MediaPlayerPrivate::onEnded() m_currentTime = duration(); m_player->timeChanged(); m_paused = true; + m_player->playbackStateChanged(); m_hasVideo = false; m_networkState = MediaPlayer::Idle; } @@ -169,6 +171,7 @@ void MediaPlayerPrivate::onEnded() void MediaPlayerPrivate::onPaused() { m_paused = true; + m_player->playbackStateChanged(); m_hasVideo = false; m_networkState = MediaPlayer::Idle; m_player->playbackStateChanged(); @@ -207,6 +210,7 @@ public: return; m_paused = false; + m_player->playbackStateChanged(); if (m_currentTime == duration()) m_currentTime = 0; @@ -284,9 +288,9 @@ public: m_player->sizeChanged(); } - bool hasAudio() { return false; } // do not display the audio UI - bool hasVideo() { return m_hasVideo; } - bool suppportsFullscreen() { return true; } + virtual bool hasAudio() const { return false; } // do not display the audio UI + virtual bool hasVideo() const { return m_hasVideo; } + virtual bool supportsFullscreen() const { return true; } MediaPlayerVideoPrivate(MediaPlayer* player) : MediaPlayerPrivate(player) { @@ -394,13 +398,14 @@ public: return; m_paused = false; + m_player->playbackStateChanged(); env->CallVoidMethod(m_glue->m_javaProxy, m_glue->m_play); checkException(env); } - bool hasAudio() { return true; } - bool hasVideo() { return false; } - bool suppportsFullscreen() { return false; } + virtual bool hasAudio() const { return true; } + virtual bool hasVideo() const { return false; } + virtual bool supportsFullscreen() const { return false; } float maxTimeSeekable() const {