Commit 60c63d39 authored by Olivier Teulière's avatar Olivier Teulière

* skins2: Other attempt at supporting transparency on Windows (win2k, winxp).

   As it is not perfect yet, a new config option allows to disable transparency
   effects.
parent 1dcec75f
......@@ -88,15 +88,15 @@ void SkinParser::handleBeginElement( const string &rName, AttrList_t &attr )
else if( rName == "Bitmap" )
{
const BuilderData::Bitmap bitmap( attr["id"] ,
ConvertFileName( attr["file"] ),
ConvertColor( attr["alphacolor"] ) );
convertFileName( attr["file"] ),
convertColor( attr["alphacolor"] ) );
m_data.m_listBitmap.push_back( bitmap );
}
else if( rName == "BitmapFont" )
{
const BuilderData::BitmapFont font( attr["id"],
ConvertFileName( attr["file"] ),
convertFileName( attr["file"] ),
attr["type"] );
m_data.m_listBitmapFont.push_back( font );
}
......@@ -128,7 +128,7 @@ void SkinParser::handleBeginElement( const string &rName, AttrList_t &attr )
else if( rName == "Font" )
{
const BuilderData::Font fontData( attr["id"],
ConvertFileName( attr["file"] ),
convertFileName( attr["file"] ),
atoi( attr["size"] ) );
m_data.m_listFont.push_back( fontData );
}
......@@ -170,11 +170,11 @@ void SkinParser::handleBeginElement( const string &rName, AttrList_t &attr )
m_xOffset, atoi( attr["y"] ) + m_yOffset, attr["visible"],
atoi( attr["width"]), atoi( attr["height"] ),
attr["lefttop"], attr["rightbottom"],
attr["font"], attr["var"], ConvertColor( attr["fgcolor"] ),
ConvertColor( attr["playcolor"] ),
ConvertColor( attr["bgcolor1"] ),
ConvertColor( attr["bgcolor2"] ),
ConvertColor( attr["selcolor"] ), attr["help"],
attr["font"], attr["var"], convertColor( attr["fgcolor"] ),
convertColor( attr["playcolor"] ),
convertColor( attr["bgcolor1"] ),
convertColor( attr["bgcolor2"] ),
convertColor( attr["selcolor"] ), attr["help"],
m_curLayer, m_curWindowId, m_curLayoutId );
m_curLayer++;
m_data.m_listList.push_back( listData );
......@@ -219,7 +219,7 @@ void SkinParser::handleBeginElement( const string &rName, AttrList_t &attr )
atoi( attr["x"] ) + m_xOffset, atoi( attr["y"] ) + m_yOffset,
attr["visible"], attr["font"],
attr["text"], atoi( attr["width"] ),
ConvertColor( attr["color"] ), attr["help"], m_curLayer,
convertColor( attr["color"] ), attr["help"], m_curLayer,
m_curWindowId, m_curLayoutId );
m_curLayer++;
m_data.m_listText.push_back( textData );
......@@ -236,14 +236,16 @@ void SkinParser::handleBeginElement( const string &rName, AttrList_t &attr )
return;
}
const BuilderData::Theme theme( attr["tooltipfont"],
atoi( attr["magnet"] ), atoi( attr["alpha"] ),
atoi( attr["movealpha"] ), atoi( attr["fadetime"] ) );
atoi( attr["magnet"] ),
convertInRange( attr["alpha"], 1, 255, "alpha" ),
convertInRange( attr["movealpha"], 1, 255, "movealpha" ),
atoi( attr["fadetime"] ) );
m_data.m_listTheme.push_back( theme );
}
else if( rName == "ThemeInfo" )
{
msg_Warn( getIntf(), "skin: %s author: %s", attr["name"],
msg_Info( getIntf(), "skin: %s author: %s", attr["name"],
attr["author"] );
}
......@@ -264,9 +266,9 @@ void SkinParser::handleBeginElement( const string &rName, AttrList_t &attr )
m_curWindowId = uniqueId( attr["id"] );
const BuilderData::Window window( m_curWindowId,
atoi( attr["x"] ) + m_xOffset, atoi( attr["y"] ) + m_yOffset,
ConvertBoolean( attr["visible"] ),
ConvertBoolean( attr["dragdrop"] ),
ConvertBoolean( attr["playondrop"] ) );
convertBoolean( attr["visible"] ),
convertBoolean( attr["dragdrop"] ),
convertBoolean( attr["playondrop"] ) );
m_data.m_listWindow.push_back( window );
}
}
......@@ -289,13 +291,13 @@ void SkinParser::handleEndElement( const string &rName )
}
bool SkinParser::ConvertBoolean( const char *value ) const
bool SkinParser::convertBoolean( const char *value ) const
{
return strcmp( value, "true" ) == 0;
}
int SkinParser::ConvertColor( const char *transcolor ) const
int SkinParser::convertColor( const char *transcolor ) const
{
unsigned long iRed, iGreen, iBlue;
iRed = iGreen = iBlue = 0;
......@@ -303,11 +305,39 @@ int SkinParser::ConvertColor( const char *transcolor ) const
return ( iRed << 16 | iGreen << 8 | iBlue );
}
string SkinParser::ConvertFileName( const char *fileName ) const
string SkinParser::convertFileName( const char *fileName ) const
{
return m_path + string( fileName );
}
int SkinParser::convertInRange( const char *value, int minValue, int maxValue,
const string &rAttribute ) const
{
int intValue = atoi( value );
if( intValue < minValue )
{
msg_Warn( getIntf(), "Value of \"%s\" attribute (%i) is out of the "
"expected range [%i, %i], using %i instead",
rAttribute.c_str(), intValue, minValue, maxValue, minValue );
return minValue;
}
else if( intValue > maxValue )
{
msg_Warn( getIntf(), "Value of \"%s\" attribute (%i) is out of the "
"expected range [%i, %i], using %i instead",
rAttribute.c_str(), intValue, minValue, maxValue, maxValue );
return maxValue;
}
else
{
return intValue;
}
}
const string SkinParser::generateId() const
{
static int i = 1;
......
......@@ -64,9 +64,15 @@ class SkinParser: public XMLParser
virtual void handleEndElement( const string &rName );
/// Helper functions
bool ConvertBoolean( const char *value ) const;
int ConvertColor( const char *transcolor ) const;
string ConvertFileName( const char *fileName ) const;
//@{
bool convertBoolean( const char *value ) const;
int convertColor( const char *transcolor ) const;
string convertFileName( const char *fileName ) const;
/// Transform to int, and check that it is in the given range (if not,
/// the closest range boundary will be used)
int convertInRange( const char *value, int minValue, int maxValue,
const string &rAttribute ) const;
//@}
/// Generate a new id
const string generateId() const;
......
......@@ -223,16 +223,24 @@ static void Run( intf_thread_t *p_intf )
//---------------------------------------------------------------------------
// Module descriptor
//---------------------------------------------------------------------------
#define DEFAULT_SKIN N_("Last skin used")
#define DEFAULT_SKIN_LONG N_("Select the path to the last skin used.")
#define SKIN_CONFIG N_("Config of last used skin")
#define SKIN_CONFIG_LONG N_("Config of last used skin.")
#define SKINS2_LAST N_("Last skin used")
#define SKINS2_LAST_LONG N_("Select the path to the last skin used.")
#define SKINS2_CONFIG N_("Config of last used skin")
#define SKINS2_CONFIG_LONG N_("Config of last used skin.")
#define SKINS2_TRANSPARENCY N_("Enable transparency effects")
#define SKINS2_TRANSPARENCY_LONG N_("You can disable all transparency effects" \
" if you want. This is mainly useful when moving windows does not behave" \
" correctly.")
vlc_module_begin();
add_string( "skins2-last", "", NULL, DEFAULT_SKIN, DEFAULT_SKIN_LONG,
add_string( "skins2-last", "", NULL, SKINS2_LAST, SKINS2_LAST_LONG,
VLC_TRUE );
add_string( "skins2-config", "", NULL, SKIN_CONFIG, SKIN_CONFIG_LONG,
add_string( "skins2-config", "", NULL, SKINS2_CONFIG, SKINS2_CONFIG_LONG,
VLC_TRUE );
#ifdef WIN32
add_bool( "skins2-transparency", VLC_TRUE, NULL, SKINS2_TRANSPARENCY,
SKINS2_TRANSPARENCY_LONG, VLC_FALSE );
#endif
set_description( _("Skinnable Interface") );
set_capability( "interface", 30 );
set_callbacks( Open, Close );
......
......@@ -65,11 +65,22 @@ void WindowManager::startMove( TopWindow &rWindow )
m_movingWindows.clear();
buildDependSet( m_movingWindows, &rWindow );
// Change the opacity of the moving windows
WinSet_t::const_iterator it;
for( it = m_movingWindows.begin(); it != m_movingWindows.end(); it++ )
if( config_GetInt( getIntf(), "skins2-transparency" ) )
{
(*it)->setOpacity( m_moveAlpha );
// Change the opacity of the moving windows
WinSet_t::const_iterator it;
for( it = m_movingWindows.begin(); it != m_movingWindows.end(); it++ )
{
(*it)->setOpacity( m_moveAlpha );
}
// FIXME: We need to refresh the windows, because if 2 windows overlap
// and one of them becomes transparent, the other one is not refreshed
// automatically. I don't know why... -- Ipkiss
for( it = m_allWindows.begin(); it != m_allWindows.end(); it++ )
{
(*it)->refresh( 0, 0, (*it)->getWidth(), (*it)->getHeight() );
}
}
}
......@@ -79,11 +90,14 @@ void WindowManager::stopMove()
WinSet_t::const_iterator itWin1, itWin2;
AncList_t::const_iterator itAnc1, itAnc2;
// Restore the opacity of the moving windows
WinSet_t::const_iterator it;
for( it = m_movingWindows.begin(); it != m_movingWindows.end(); it++ )
if( config_GetInt( getIntf(), "skins2-transparency" ) )
{
(*it)->setOpacity( m_alpha );
// Restore the opacity of the moving windows
WinSet_t::const_iterator it;
for( it = m_movingWindows.begin(); it != m_movingWindows.end(); it++ )
{
(*it)->setOpacity( m_alpha );
}
}
// Delete the dependencies
......
......@@ -41,7 +41,7 @@ Win32Window::Win32Window( intf_thread_t *pIntf, GenericWindow &rWindow,
HINSTANCE hInst, HWND hParentWindow,
bool dragDrop, bool playOnDrop,
Win32Window *pParentWindow ):
OSWindow( pIntf ), m_dragDrop( dragDrop )
OSWindow( pIntf ), m_dragDrop( dragDrop ), m_isLayered( false )
{
// Create the window
if( pParentWindow )
......@@ -66,11 +66,6 @@ Win32Window::Win32Window( intf_thread_t *pIntf, GenericWindow &rWindow,
return;
}
// We do it this way otherwise CreateWindowEx will fail if WS_EX_LAYERED
// is not supported
// SetWindowLongPtr( m_hWnd, GWL_EXSTYLE,
// GetWindowLong( m_hWnd, GWL_EXSTYLE ) | WS_EX_LAYERED );
// Store a pointer to the GenericWindow in a map
Win32Factory *pFactory = (Win32Factory*)Win32Factory::instance( getIntf() );
pFactory->m_windowMap[m_hWnd] = &rWindow;
......@@ -138,37 +133,49 @@ void Win32Window::raise() const
void Win32Window::setOpacity( uint8_t value ) const
{
#if 0
Win32Factory *pFactory = (Win32Factory*)Win32Factory::instance( getIntf() );
if( value == 255 )
{
// If the window is opaque, we remove the WS_EX_LAYERED attribute
// which slows resizing for nothing
SetWindowLongPtr( m_hWnd, GWL_EXSTYLE,
GetWindowLong( m_hWnd, GWL_EXSTYLE ) & !WS_EX_LAYERED );
SetWindowPos( m_hWnd, HWND_TOP, 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED );
// which slows down resizing for nothing
if( m_isLayered )
{
SetWindowLongPtr( m_hWnd, GWL_EXSTYLE,
GetWindowLong( m_hWnd, GWL_EXSTYLE ) & ~WS_EX_LAYERED );
// Redraw the window, otherwise we may end up with a grey rectangle
// for some strange reason
RedrawWindow(m_hWnd, NULL, NULL,
RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN);
m_isLayered = false;
}
}
else
{
if( pFactory->SetLayeredWindowAttributes )
{
// (Re)Add the WS_EX_LAYERED attribute.
// Resizing will be very slow, now :)
SetWindowLongPtr( m_hWnd, GWL_EXSTYLE,
GetWindowLong( m_hWnd, GWL_EXSTYLE ) | WS_EX_LAYERED );
SetWindowPos( m_hWnd, HWND_TOP, 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED );
if( ! m_isLayered )
{
// (Re)Add the WS_EX_LAYERED attribute.
// Resizing will be very slow, now :)
SetWindowLongPtr( m_hWnd, GWL_EXSTYLE,
GetWindowLong( m_hWnd, GWL_EXSTYLE ) | WS_EX_LAYERED );
// Redraw the window, otherwise we may end up with a grey
// rectangle for some strange reason
RedrawWindow(m_hWnd, NULL, NULL,
RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN);
m_isLayered = true;
}
// Change the opacity
pFactory->SetLayeredWindowAttributes(
m_hWnd, 0, value, LWA_ALPHA|LWA_COLORKEY );
}
}
UpdateWindow( m_hWnd );
#endif
}
......
......@@ -69,6 +69,8 @@ class Win32Window: public OSWindow
bool m_dragDrop;
/// Drop target
LPDROPTARGET m_pDropTarget;
/// Indicates whether the window is layered
mutable bool m_isLayered;
};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment