Commit c9663d97 authored by Erwan Tulou's avatar Erwan Tulou Committed by Joseph

skins2: rework the fullscreen controller

This rework includes:
   - activation with mouse move
   - transparency and fading out supported if the WM allows it
   - fsc no longer a child window
     (this latter point should work out the refresh problems
      often mentioned on Vista and Win7)
parent 22405050
......@@ -150,6 +150,8 @@ SOURCES_skins2 = \
src/tooltip.hpp \
src/top_window.cpp \
src/top_window.hpp \
src/fsc_window.cpp \
src/fsc_window.hpp \
src/var_manager.cpp \
src/var_manager.hpp \
src/vlcproc.cpp \
......
......@@ -101,8 +101,6 @@ void CtrlVideo::draw( OSGraphics &rImage, int xDest, int yDest, int w, int h)
if( m_pVoutWindow )
{
m_pVoutWindow->move( pPos->getLeft(), pPos->getTop() );
m_pVoutWindow->resize( pPos->getWidth(), pPos->getHeight() );
m_pVoutWindow->show();
}
}
......
......@@ -30,6 +30,7 @@
#include "../src/os_factory.hpp"
#include "../src/generic_bitmap.hpp"
#include "../src/top_window.hpp"
#include "../src/fsc_window.hpp"
#include "../src/anchor.hpp"
#include "../src/bitmap_font.hpp"
#include "../src/ft2_font.hpp"
......@@ -359,16 +360,22 @@ void Builder::addMenuSeparator( const BuilderData::MenuSeparator &rData )
void Builder::addWindow( const BuilderData::Window &rData )
{
TopWindow *pWin =
new TopWindow( getIntf(), rData.m_xPos, rData.m_yPos,
TopWindow *pWin;
if( rData.m_id == "fullscreenController" )
{
pWin = new FscWindow( getIntf(), rData.m_xPos, rData.m_yPos,
m_pTheme->getWindowManager(),
rData.m_dragDrop, rData.m_playOnDrop,
rData.m_visible );
}
else
{
pWin = new TopWindow( getIntf(), rData.m_xPos, rData.m_yPos,
m_pTheme->getWindowManager(),
rData.m_dragDrop, rData.m_playOnDrop,
rData.m_visible );
}
m_pTheme->m_windows[rData.m_id] = TopWindowPtr( pWin );
if( rData.m_id == "fullscreenController" )
VoutManager::instance( getIntf())->registerFSC( pWin );
}
......
/*****************************************************************************
* fsc_window.cpp
*****************************************************************************
* Copyright (C) 2010 the VideoLAN team
* $Id$
*
* Author: Erwan Tulou <erwan10 at videolan Dot Org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#include "fsc_window.hpp"
#include "vout_manager.hpp"
#include "os_factory.hpp"
#include "os_timer.hpp"
#include "vlcproc.hpp"
/**
* Fading out is computed in the following way:
* - a timer is fired with a given period (FSC_DELAY)
* - a total of FSC_COUNT transitions are processed before
* hiding the controller
* - transparency is changed in the following way :
* - unaltered for the first FSC_COUNT2 transitions
* - then linear decrease from m_opacity to 0 till
* FSC_COUNT is reached.
**/
#define FSC_DELAY 50 // period for fading out (in msec)
#define FSC_COUNT 60 // total # of transitions for fading out
#define FSC_COUNT2 20 // # of transitions with opacity unaltered
FscWindow::FscWindow( intf_thread_t *pIntf, int left, int top,
WindowManager &rWindowManager,
bool dragDrop, bool playOnDrop, bool visible ) :
TopWindow( pIntf, left, top, rWindowManager, dragDrop,
playOnDrop, false, GenericWindow::FscWindow ), m_cmdFscHide( this ),
m_opacity( m_opacity ), m_count( 0 )
{
m_pTimer = OSFactory::instance( getIntf() )->createOSTimer( m_cmdFscHide );
VarBool &rFullscreen = VlcProc::instance( getIntf() )->getFullscreenVar();
rFullscreen.addObserver( this );
// opacity overridden by user
m_opacity = 255 * var_InheritFloat( getIntf(), "qt-fs-opacity" );
// register Fsc
VoutManager::instance( getIntf())->registerFSC( this );
}
FscWindow::~FscWindow()
{
// unregister Fsc
VoutManager::instance( getIntf())->registerFSC( NULL );
VarBool &rFullscreen = VlcProc::instance( getIntf() )->getFullscreenVar();
rFullscreen.delObserver( this );
delete m_pTimer;
}
void FscWindow::onMouseMoved( )
{
VarBool &rFullscreen = VlcProc::instance( getIntf() )->getFullscreenVar();
if( rFullscreen.get() )
{
show();
if( m_count < FSC_COUNT - FSC_COUNT2 )
{
m_pTimer->stop();
m_count = FSC_COUNT;
setOpacity( m_opacity );
m_pTimer->start( FSC_DELAY, false );
}
}
}
void FscWindow::onTimerExpired()
{
if( m_count )
{
if( m_count < FSC_COUNT - FSC_COUNT2 )
setOpacity( m_opacity * m_count / (FSC_COUNT - FSC_COUNT2 ) );
m_count--;
}
if( !m_count )
{
hide();
}
}
void FscWindow::processEvent( EvtMotion &rEvtMotion )
{
if( m_count )
{
m_pTimer->stop();
m_count = 0;
setOpacity( m_opacity );
}
TopWindow::processEvent( rEvtMotion );
}
void FscWindow::processEvent( EvtLeave &rEvtLeave )
{
if( m_count )
{
m_pTimer->stop();
m_count = 0;
}
m_count = FSC_COUNT;
setOpacity( m_opacity );
m_pTimer->start( FSC_DELAY, false );
TopWindow::processEvent( rEvtLeave );
}
void FscWindow::onUpdate( Subject<VarBool> &rVariable, void *arg )
{
VarBool &rFullscreen = VlcProc::instance( getIntf() )->getFullscreenVar();
if( &rVariable == &rFullscreen )
{
if( !rFullscreen.get() )
{
hide();
}
}
TopWindow::onUpdate( rVariable, arg );
}
void FscWindow::innerShow()
{
TopWindow::innerShow();
m_count = FSC_COUNT;
setOpacity( m_opacity );
m_pTimer->start( FSC_DELAY, false );
}
void FscWindow::innerHide()
{
m_pTimer->stop();
m_count = 0;
TopWindow::innerHide();
}
void FscWindow::CmdFscHide::execute()
{
m_pParent->onTimerExpired();
}
/*****************************************************************************
* fsc_window.hpp
*****************************************************************************
* Copyright (C) 2010 the VideoLAN team
* $Id$
*
* Author: Erwan Tulou <erwan10 At videolan Dot Org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifndef FSC_WINDOW_HPP
#define FSC_WINDOW_HPP
#include "../src/top_window.hpp"
#include "../commands/cmd_generic.hpp"
class OSTimer;
/// Class for the fullscreen controller
class FscWindow: public TopWindow
{
public:
FscWindow( intf_thread_t *pIntf, int left, int top,
WindowManager &rWindowManager,
bool dragDrop, bool playOnDrop, bool visible );
virtual ~FscWindow();
virtual void processEvent( EvtLeave &rEvtLeave );
virtual void processEvent( EvtMotion &rEvtMotion );
/// Method called when fullscreen indicator changes
virtual void onUpdate( Subject<VarBool> &rVariable , void* );
/// Action when window is shown
virtual void innerShow();
/// Action when window is hidden
virtual void innerHide();
/// Action when mouse moved
virtual void onMouseMoved();
/// Action for each transition of fading out
virtual void onTimerExpired();
private:
/// Timer for fsc fading-out
OSTimer *m_pTimer;
/// number of transitions when fading out
int m_count;
/// opacity set by user
int m_opacity;
/// Callback for the timer
DEFINE_CALLBACK( FscWindow, FscHide )
};
#endif
......@@ -55,6 +55,7 @@ public:
TopWindow,
VoutWindow,
FullscreenWindow,
FscWindow,
};
GenericWindow( intf_thread_t *pIntf, int xPos, int yPos,
......@@ -137,6 +138,9 @@ protected:
///
bool isVisible() const { return m_pVarVisible->get(); }
/// Method called when the observed variable is modified
virtual void onUpdate( Subject<VarBool> &rVariable , void*);
private:
/// Window position and size
int m_left, m_top, m_width, m_height;
......@@ -144,9 +148,6 @@ private:
OSWindow *m_pOsWindow;
/// Variable for the visibility of the window
mutable VarBoolImpl *m_pVarVisible;
/// Method called when the observed variable is modified
virtual void onUpdate( Subject<VarBool> &rVariable , void*);
};
......
......@@ -50,9 +50,10 @@
TopWindow::TopWindow( intf_thread_t *pIntf, int left, int top,
WindowManager &rWindowManager,
bool dragDrop, bool playOnDrop, bool visible ):
GenericWindow( pIntf, left, top, dragDrop, playOnDrop, NULL ),
m_visible( visible ), m_rWindowManager( rWindowManager ),
bool dragDrop, bool playOnDrop, bool visible,
GenericWindow::WindowType_t type ):
GenericWindow( pIntf, left, top, dragDrop, playOnDrop, NULL, type ),
m_initialVisibility( visible ), m_rWindowManager( rWindowManager ),
m_pActiveLayout( NULL ), m_pLastHitControl( NULL ),
m_pCapturingControl( NULL ), m_pFocusControl( NULL ), m_currModifier( 0 )
{
......
......@@ -44,7 +44,8 @@ private:
public:
TopWindow( intf_thread_t *pIntf, int xPos, int yPos,
WindowManager &rWindowManager,
bool dragDrop, bool playOnDrop, bool visible );
bool dragDrop, bool playOnDrop, bool visible,
GenericWindow::WindowType_t type = GenericWindow::TopWindow );
virtual ~TopWindow();
/// Methods to process OS events.
......@@ -81,7 +82,7 @@ public:
VarBool &getMaximizedVar() { return *m_pVarMaximized; }
/// Get the initial visibility status
bool isVisible() const { return m_visible; }
bool getInitialVisibility() const { return m_initialVisibility; }
protected:
/// Actually show the window
......@@ -100,7 +101,7 @@ private:
//@}
/// Initial visibility status
bool m_visible;
bool m_initialVisibility;
/// Window manager
WindowManager &m_rWindowManager;
/// Current active layout of the window
......
......@@ -39,6 +39,7 @@
#include "os_timer.hpp"
#include "var_manager.hpp"
#include "vout_manager.hpp"
#include "fsc_window.hpp"
#include "theme.hpp"
#include "window_manager.hpp"
#include "../commands/async_queue.hpp"
......@@ -404,6 +405,8 @@ int VlcProc::onGenericCallback( vlc_object_t *pObj, const char *pVariable,
ADD_CALLBACK_ENTRY( "intf-show", on_intf_show_changed, false )
ADD_CALLBACK_ENTRY( "mouse-moved", on_mouse_moved_changed, false )
#undef ADD_CALLBACK_ENTRY
msg_Err( pThis->getIntf(), "no callback entry for %s", pVariable );
......@@ -541,8 +544,26 @@ void VlcProc::on_intf_event_changed( vlc_object_t* p_obj, vlc_value_t newVal )
{
vout_thread_t* pVout = input_GetVout( pInput );
SET_BOOL( m_cVarHasVout, pVout != NULL );
if( pVout )
vlc_object_release( pVout );
if( !pVout || pVout == m_pVout )
{
// end of input or vout reuse (nothing to do)
if( pVout )
vlc_object_release( pVout );
break;
}
if( m_pVout )
{
// remove previous Vout callbacks
var_DelCallback( m_pVout, "mouse-moved",
onGenericCallback, this );
vlc_object_release( m_pVout );
m_pVout = NULL;
}
// add new Vout callbackx
var_AddCallback( pVout, "mouse-moved",
onGenericCallback, this );
m_pVout = pVout;
break;
}
......@@ -721,8 +742,8 @@ void VlcProc::on_intf_show_changed( vlc_object_t* p_obj, vlc_value_t newVal )
}
else
{
Theme* pTheme = getIntf()->p_sys->p_theme;
TopWindow *pWin = pTheme->getWindowById( "fullscreenController" );
VoutManager* pVoutManager = VoutManager::instance( getIntf() );
FscWindow *pWin = pVoutManager->getFscWindow();
if( pWin )
{
bool b_visible = pWin->getVisibleVar().get();
......@@ -746,6 +767,13 @@ void VlcProc::on_intf_show_changed( vlc_object_t* p_obj, vlc_value_t newVal )
}
}
void VlcProc::on_mouse_moved_changed( vlc_object_t* p_obj, vlc_value_t newVal )
{
FscWindow* pFscWindow = VoutManager::instance( getIntf() )->getFscWindow();
if( pFscWindow )
pFscWindow->onMouseMoved();
}
void VlcProc::reset_input()
{
SET_BOOL( m_cVarSeekable, false );
......
......@@ -111,6 +111,8 @@ public:
void on_intf_show_changed( vlc_object_t* p_obj, vlc_value_t newVal );
void on_mouse_moved_changed( vlc_object_t* p_obj, vlc_value_t newVal );
protected:
// Protected because it is a singleton
VlcProc( intf_thread_t *pIntf );
......
......@@ -90,13 +90,9 @@ void VoutManager::registerCtrlVideo( CtrlVideo* p_CtrlVideo )
}
void VoutManager::registerFSC( TopWindow* p_Win )
void VoutManager::registerFSC( FscWindow* p_Win )
{
m_pFscWindow = p_Win;
int x = p_Win->getLeft();
int y = p_Win->getTop();
p_Win->setParent( m_pVoutMainWindow, x , y, 0, 0 );
}
......
......@@ -37,6 +37,7 @@
class VarBool;
class GenericWindow;
class FscWindow;
#include <stdio.h>
......@@ -131,7 +132,10 @@ public:
void registerCtrlVideo( CtrlVideo* p_CtrlVideo );
// Register Video Controls (when building theme)
void registerFSC( TopWindow* p_Win );
void registerFSC( FscWindow* p_Win );
// get the fullscreen controller window
FscWindow* getFscWindow( ) { return m_pFscWindow; }
// save and restore vouts (when changing theme)
void saveVoutConfig( );
......@@ -166,7 +170,7 @@ private:
VoutMainWindow* m_pVoutMainWindow;
TopWindow* m_pFscWindow;
FscWindow* m_pFscWindow;
};
......
......@@ -34,14 +34,18 @@
WindowManager::WindowManager( intf_thread_t *pIntf ):
SkinObject( pIntf ), m_magnet( 0 ), m_direction( kNone ),
m_maximizeRect(0, 0, 50, 50), m_pTooltip( NULL ), m_pPopup( NULL ),
m_alpha( 255 ), m_moveAlpha( 255 ), m_OpacityEnabled( false )
m_alpha( 255 ), m_moveAlpha( 255 ), m_opacityEnabled( false )
{
// Create and register a variable for the "on top" status
VarManager *pVarManager = VarManager::instance( getIntf() );
m_cVarOnTop = VariablePtr( new VarBoolImpl( getIntf() ) );
pVarManager->registerVar( m_cVarOnTop, "vlc.isOnTop" );
m_OpacityEnabled = var_InheritBool( getIntf(), "skins2-transparency" );
// transparency switched on or off by user
m_opacityEnabled = var_InheritBool( getIntf(), "skins2-transparency" );
// opacity overridden by user
m_opacity = 255 * var_InheritFloat( getIntf(), "qt-opacity" );
}
......@@ -415,7 +419,7 @@ void WindowManager::showAll( bool firstTime ) const
{
// When the theme is opened for the first time,
// only show the window if set as visible in the XML
if( (*it)->isVisible() || !firstTime )
if( (*it)->getInitialVisibility() || !firstTime )
{
(*it)->show();
}
......
......@@ -135,10 +135,12 @@ public:
void setMagnetValue( int magnet ) { m_magnet = magnet; }
/// Set the alpha value of the static windows
void setAlphaValue( int alpha ) { m_alpha = alpha; }
void setAlphaValue( int alpha )
{ m_alpha = (m_opacity != 255) ? m_opacity : alpha; }
/// Set the alpha value of the moving windows
void setMoveAlphaValue( int moveAlpha ) { m_moveAlpha = moveAlpha; }
void setMoveAlphaValue( int moveAlpha )
{ m_moveAlpha = (m_opacity != 255) ? m_opacity : moveAlpha; }
/// Create the tooltip window
void createTooltip( const GenericFont &rTipFont );
......@@ -164,7 +166,7 @@ public:
/// getter to know whether opacity is needed
bool isOpacityNeeded() const
{ return (m_OpacityEnabled && (m_alpha != 255 || m_moveAlpha != 255 )); }
{ return (m_opacityEnabled && (m_alpha != 255 || m_moveAlpha != 255 )); }
private:
/// Some useful typedefs for lazy people like me
......@@ -210,7 +212,9 @@ private:
/// Alpha value of the moving windows
int m_moveAlpha;
/// transparency set by user
bool m_OpacityEnabled;
bool m_opacityEnabled;
/// opacity overridden by user
int m_opacity;
/// Direction of the current resizing
Direction_t m_direction;
/// Rect of the last maximized window
......
......@@ -26,6 +26,7 @@
#include "../src/generic_window.hpp"
#include "../src/vlcproc.hpp"
#include "../src/vout_manager.hpp"
#include "win32_window.hpp"
#include "win32_dragdrop.hpp"
#include "win32_factory.hpp"
......@@ -76,6 +77,22 @@ Win32Window::Win32Window( intf_thread_t *pIntf, GenericWindow &rWindow,
// Store with it a pointer to the interface thread
SetWindowLongPtr( m_hWnd, GWLP_USERDATA, (LONG_PTR)getIntf() );
}
else if( type == GenericWindow::FscWindow )
{
VoutManager* pVoutManager = VoutManager::instance( getIntf() );
GenericWindow* pParent =
(GenericWindow*)pVoutManager->getVoutMainWindow();
m_hWnd_parent = (HWND)pParent->getOSHandle();
// top-level window
m_hWnd = CreateWindowEx( WS_EX_APPWINDOW, vlc_class, vlc_name,
WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
0, 0, 0, 0, m_hWnd_parent, 0, hInst, NULL );
// Store with it a pointer to the interface thread
SetWindowLongPtr( m_hWnd, GWLP_USERDATA, (LONG_PTR)getIntf() );
}
else
{
// top-level window (owned by the root window)
......@@ -130,14 +147,8 @@ Win32Window::~Win32Window()
void Win32Window::reparent( void* OSHandle, int x, int y, int w, int h )
{
// Reparent the window
if( m_type == GenericWindow::TopWindow )
{
// fullscreen controller
SetWindowLongPtr( m_hWnd, GWL_STYLE, WS_CHILD );
}
SetParent( m_hWnd, (HWND)OSHandle );
if( !SetParent( m_hWnd, (HWND)OSHandle ) )
msg_Err( getIntf(), "SetParent failed (%lu)", GetLastError() );
MoveWindow( m_hWnd, x, y, w, h, TRUE );
}
......
......@@ -28,6 +28,7 @@
#include "../src/generic_wi