Commit 6c686000 authored by Derk-Jan Hartman's avatar Derk-Jan Hartman

* backported [15796]-[15800] and [15802]. Someone please check the notify plugin.

parent 12a999b3
......@@ -1469,6 +1469,26 @@ AS_IF([test "${enable_growl}" != "no"], [
]
)
dnl
dnl Libnotify notification plugin
dnl
AC_ARG_ENABLE(notify,
[ --enable-notify libnotify notification plugin (default enabled)])
AS_IF([test "${enable_notify}" != "no"], [
PKG_CHECK_MODULES(NOTIFY, libnotify,
[
VLC_ADD_PLUGINS([notify])
VLC_ADD_CFLAGS(notify, [$NOTIFY_CFLAGS])
VLC_ADD_LDFLAGS(notify, [$NOTIFY_LIBS])
],[
AS_IF([test "${enable_notify}" = "yes"],[
AC_MSG_WARN( libnotify not found) ])
])
])
dnl
dnl Input plugins
......
......@@ -648,3 +648,10 @@ VLC is the greatest thing since sliced bread!
* E-bola is bouncing up and down while enjoying: Content-Length: 25
* E-bola is bouncing up and down while enjoying: --
%
<Meuuh> sam : could you delete FK_ from the access list ?
<sam> sure, why?
<Meuuh> he's now known as feepk
<sam> ah, ok
<sam> I thought he was banned for sending a patch to mplayer
-- #videolan
%
......@@ -379,6 +379,12 @@ difficulty to understand how VLC skins work.</para>
<para>...</para>
<para>Default value: 0</para>
</sect4>
<sect4 id="anchorlefttop">
<title>lefttop</title>
<para>Indicate to which corner of the Layout the top-left-hand corner of this anchor is attached, in case of resizing. Possible values are 'lefttop', 'leftbottom', 'righttop' and 'rightbottom'. Available since VLC 0.8.6.</para>
<para>Note that there is no "rightbottom" attribute for the anchors (contrarily to normal controls), because an anchor is not resizable (even when the anchor is not ponctual and follows a Bezier curve).</para>
<para>Default value: lefttop</para>
</sect4>
<sect4 id="anchorpriority">
<title>priority</title>
<para>Priority of anchor (see the previous description).</para>
......
......@@ -24,13 +24,14 @@
#include "cmd_resize.hpp"
#include "../src/generic_layout.hpp"
#include "../src/window_manager.hpp"
#include "../src/vlcproc.hpp"
CmdResize::CmdResize( intf_thread_t *pIntf, GenericLayout &rLayout, int width,
int height ):
CmdGeneric( pIntf ), m_rLayout( rLayout ), m_width( width ),
m_height( height )
CmdResize::CmdResize( intf_thread_t *pIntf, const WindowManager &rWindowManager,
GenericLayout &rLayout, int width, int height ):
CmdGeneric( pIntf ), m_rWindowManager( rWindowManager ),
m_rLayout( rLayout ), m_width( width ), m_height( height )
{
}
......@@ -38,7 +39,7 @@ CmdResize::CmdResize( intf_thread_t *pIntf, GenericLayout &rLayout, int width,
void CmdResize::execute()
{
// Resize the layout
m_rLayout.resize( m_width, m_height );
m_rWindowManager.resize( m_rLayout, m_width, m_height );
}
......
......@@ -27,6 +27,7 @@
#include "cmd_generic.hpp"
class WindowManager;
class GenericLayout;
......@@ -35,8 +36,8 @@ class CmdResize: public CmdGeneric
{
public:
/// Resize the given layout
CmdResize( intf_thread_t *pIntf, GenericLayout &rLayout, int width,
int height );
CmdResize( intf_thread_t *pIntf, const WindowManager &rWindowManager,
GenericLayout &rLayout, int width, int height );
virtual ~CmdResize() {}
/// This method does the real job of the command
......@@ -46,6 +47,7 @@ class CmdResize: public CmdGeneric
virtual string getType() const { return "resize"; }
private:
const WindowManager &m_rWindowManager;
GenericLayout &m_rLayout;
int m_width, m_height;
};
......
......@@ -33,10 +33,12 @@
#include "../commands/cmd_resize.hpp"
CtrlResize::CtrlResize( intf_thread_t *pIntf, CtrlFlat &rCtrl,
GenericLayout &rLayout, const UString &rHelp,
VarBool *pVisible, Direction_t direction ):
CtrlFlat( pIntf, rHelp, pVisible ), m_fsm( pIntf ), m_rCtrl( rCtrl ),
CtrlResize::CtrlResize( intf_thread_t *pIntf, WindowManager &rWindowManager,
CtrlFlat &rCtrl, GenericLayout &rLayout,
const UString &rHelp, VarBool *pVisible,
WindowManager::Direction_t direction ):
CtrlFlat( pIntf, rHelp, pVisible ), m_fsm( pIntf ),
m_rWindowManager( rWindowManager ), m_rCtrl( rCtrl ),
m_rLayout( rLayout ), m_direction( direction ), m_cmdOutStill( this ),
m_cmdStillOut( this ),
m_cmdStillStill( this ),
......@@ -103,16 +105,16 @@ void CtrlResize::handleEvent( EvtGeneric &rEvent )
}
void CtrlResize::changeCursor( Direction_t direction ) const
void CtrlResize::changeCursor( WindowManager::Direction_t direction ) const
{
OSFactory *pOsFactory = OSFactory::instance( getIntf() );
if( direction == kResizeSE )
if( direction == WindowManager::kResizeSE )
pOsFactory->changeCursor( OSFactory::kResizeNWSE );
else if( direction == kResizeS )
else if( direction == WindowManager::kResizeS )
pOsFactory->changeCursor( OSFactory::kResizeNS );
else if( direction == kResizeE )
else if( direction == WindowManager::kResizeE )
pOsFactory->changeCursor( OSFactory::kResizeWE );
else if( direction == kNone )
else if( direction == WindowManager::kNone )
pOsFactory->changeCursor( OSFactory::kDefaultArrow );
}
......@@ -125,7 +127,7 @@ void CtrlResize::CmdOutStill::execute()
void CtrlResize::CmdStillOut::execute()
{
m_pParent->changeCursor( kNone );
m_pParent->changeCursor( WindowManager::kNone );
}
......@@ -149,6 +151,9 @@ void CtrlResize::CmdStillResize::execute()
m_pParent->m_width = m_pParent->m_rLayout.getWidth();
m_pParent->m_height = m_pParent->m_rLayout.getHeight();
m_pParent->m_rWindowManager.startResize( m_pParent->m_rLayout,
m_pParent->m_direction);
}
......@@ -158,6 +163,8 @@ void CtrlResize::CmdResizeStill::execute()
m_pParent->changeCursor( m_pParent->m_direction );
m_pParent->releaseMouse();
m_pParent->m_rWindowManager.stopResize();
}
......@@ -169,17 +176,18 @@ void CtrlResize::CmdResizeResize::execute()
m_pParent->changeCursor( m_pParent->m_direction );
int newWidth = m_pParent->m_width;
newWidth += pEvtMotion->getXPos() - m_pParent->m_xPos;
int newHeight = m_pParent->m_height;
if( m_pParent->m_direction != kResizeS )
newWidth += pEvtMotion->getXPos() - m_pParent->m_xPos;
if( m_pParent->m_direction != kResizeE )
newHeight += pEvtMotion->getYPos() - m_pParent->m_yPos;
newHeight += pEvtMotion->getYPos() - m_pParent->m_yPos;
// Create a resize command
// Create a resize command, instead of calling the window manager directly.
// Thanks to this trick, the duplicate resizing commands will be trashed
// in the asynchronous queue, thus making resizing faster
CmdGeneric *pCmd = new CmdResize( m_pParent->getIntf(),
m_pParent->m_rWindowManager,
m_pParent->m_rLayout,
newWidth, newHeight );
// Push the command in the asynchronous command queue
AsyncQueue *pQueue = AsyncQueue::instance( m_pParent->getIntf() );
AsyncQueue *pQueue = AsyncQueue::instance( getIntf() );
pQueue->push( CmdGenericPtr( pCmd ) );
}
......@@ -27,24 +27,20 @@
#include "ctrl_flat.hpp"
#include "../commands/cmd_generic.hpp"
#include "../src/window_manager.hpp"
#include "../utils/fsm.hpp"
class WindowManager;
/// Control decorator for resizing windows
class CtrlResize: public CtrlFlat
{
public:
enum Direction_t
{
kResizeE, // East
kResizeSE, // South-East
kResizeS, // South
kNone // Reserved for internal use
};
CtrlResize( intf_thread_t *pIntf, CtrlFlat &rCtrl,
GenericLayout &rLayout, const UString &rHelp,
VarBool *pVisible, Direction_t direction );
CtrlResize( intf_thread_t *pIntf, WindowManager &rWindowManager,
CtrlFlat &rCtrl, GenericLayout &rLayout,
const UString &rHelp, VarBool *pVisible,
WindowManager::Direction_t direction );
virtual ~CtrlResize() {}
/// Handle an event
......@@ -68,6 +64,8 @@ class CtrlResize: public CtrlFlat
private:
FSM m_fsm;
/// Window manager
WindowManager &m_rWindowManager;
/// Decorated CtrlFlat
CtrlFlat &m_rCtrl;
/// The layout resized by this control
......@@ -77,10 +75,10 @@ class CtrlResize: public CtrlFlat
/// Position of the click that started the resizing
int m_xPos, m_yPos;
/// Direction of the resizing
Direction_t m_direction;
WindowManager::Direction_t m_direction;
/// Change the cursor, based on the given direction
void changeCursor( Direction_t direction ) const;
void changeCursor( WindowManager::Direction_t direction ) const;
/// Callback objects
DEFINE_CALLBACK( CtrlResize, OutStill )
......
......@@ -26,6 +26,7 @@
#include "../src/vout_window.hpp"
#include "../src/os_graphics.hpp"
#include "../src/vlcproc.hpp"
#include "../src/window_manager.hpp"
#include "../commands/async_queue.hpp"
#include "../commands/cmd_resize.hpp"
......@@ -106,11 +107,18 @@ void CtrlVideo::onUpdate( Subject<VarBox, void *> &rVoutSize, void *arg )
int newHeight = ((VarBox&)rVoutSize).getHeight() + m_yShift;
// Create a resize command
CmdGeneric *pCmd = new CmdResize( getIntf(), m_rLayout, newWidth,
newHeight );
// FIXME: this way of getting the window manager kind of sucks
WindowManager &rWindowManager =
getIntf()->p_sys->p_theme->getWindowManager();
rWindowManager.startResize( m_rLayout, WindowManager::kResizeSE );
CmdGeneric *pCmd = new CmdResize( getIntf(), rWindowManager,
m_rLayout, newWidth, newHeight );
// Push the command in the asynchronous command queue
AsyncQueue *pQueue = AsyncQueue::instance( getIntf() );
pQueue->push( CmdGenericPtr( pCmd ) );
// FIXME: this should be a command too
rWindowManager.stopResize();
}
......
......@@ -38,6 +38,7 @@
#include "../src/generic_layout.hpp"
#include "../src/popup.hpp"
#include "../src/theme.hpp"
#include "../src/window_manager.hpp"
#include "../commands/cmd_generic.hpp"
#include "../controls/ctrl_button.hpp"
#include "../controls/ctrl_checkbox.hpp"
......@@ -377,8 +378,13 @@ void Builder::addAnchor( const BuilderData::Anchor &rData )
}
m_pTheme->m_curves.push_back( BezierPtr( pCurve ) );
Anchor *pAnc = new Anchor( getIntf(), rData.m_xPos, rData.m_yPos,
rData.m_range, rData.m_priority,
// Compute the position of the anchor
const Position pos = makePosition( rData.m_leftTop, rData.m_leftTop,
rData.m_xPos, rData.m_yPos,
pCurve->getWidth(),
pCurve->getHeight(), *pLayout );
Anchor *pAnc = new Anchor( getIntf(), pos, rData.m_range, rData.m_priority,
*pCurve, *pLayout );
pLayout->addAnchor( pAnc );
}
......@@ -559,23 +565,26 @@ void Builder::addImage( const BuilderData::Image &rData )
}
else if( rData.m_actionId == "resizeS" )
{
CtrlResize *pResize = new CtrlResize( getIntf(), *pImage, *pLayout,
CtrlResize *pResize = new CtrlResize( getIntf(),
m_pTheme->getWindowManager(), *pImage, *pLayout,
UString( getIntf(), rData.m_help.c_str() ), pVisible,
CtrlResize::kResizeS );
WindowManager::kResizeS );
pLayout->addControl( pResize, pos, rData.m_layer );
}
else if( rData.m_actionId == "resizeE" )
{
CtrlResize *pResize = new CtrlResize( getIntf(), *pImage, *pLayout,
CtrlResize *pResize = new CtrlResize( getIntf(),
m_pTheme->getWindowManager(), *pImage, *pLayout,
UString( getIntf(), rData.m_help.c_str() ), pVisible,
CtrlResize::kResizeE );
WindowManager::kResizeE );
pLayout->addControl( pResize, pos, rData.m_layer );
}
else if( rData.m_actionId == "resizeSE" )
{
CtrlResize *pResize = new CtrlResize( getIntf(), *pImage, *pLayout,
CtrlResize *pResize = new CtrlResize( getIntf(),
m_pTheme->getWindowManager(), *pImage, *pLayout,
UString( getIntf(), rData.m_help.c_str() ), pVisible,
CtrlResize::kResizeSE );
WindowManager::kResizeSE );
pLayout->addControl( pResize, pos, rData.m_layer );
}
else
......
......@@ -8,7 +8,7 @@ MenuItem label:string action:string pos:int popupId:string
MenuSeparator pos:int popupId:string
Window id:string xPos:int yPos:int visible:bool dragDrop:bool playOnDrop:bool
Layout id:string width:int height:int minWidth:int maxWidth:int minHeight:int maxHeight:int windowId:string
Anchor xPos:int yPos:int range:int priority:int points:string layoutId:string
Anchor xPos:int yPos:int leftTop:string range:int priority:int points:string layoutId:string
Button id:string xPos:int yPos:int leftTop:string rightBottom:string visible:string upId:string downId:string overId:string actionId:string tooltip:string help:string layer:int windowId:string layoutId:string
Checkbox id:string xPos:int yPos:int leftTop:string rightBottom:string visible:string up1Id:string down1Id:string over1Id:string up2Id:string down2Id:string over2Id:string state:string action1:string action2:string tooltip1:string tooltip2:string help:string layer:int windowId:string layoutId:string
Image id:string xPos:int yPos:int leftTop:string rightBottom:string visible:string bmpId:string actionId:string action2Id:string resize:string help:string layer:int windowId:string layoutId:string
......
......@@ -186,11 +186,12 @@ m_id( id ), m_width( width ), m_height( height ), m_minWidth( minWidth ), m_maxW
/// Type definition
struct Anchor
{
Anchor( int xPos, int yPos, int range, int priority, const string & points, const string & layoutId ):
m_xPos( xPos ), m_yPos( yPos ), m_range( range ), m_priority( priority ), m_points( points ), m_layoutId( layoutId ) {}
Anchor( int xPos, int yPos, const string & leftTop, int range, int priority, const string & points, const string & layoutId ):
m_xPos( xPos ), m_yPos( yPos ), m_leftTop( leftTop ), m_range( range ), m_priority( priority ), m_points( points ), m_layoutId( layoutId ) {}
int m_xPos;
int m_yPos;
string m_leftTop;
int m_range;
int m_priority;
string m_points;
......
......@@ -88,12 +88,14 @@ void SkinParser::handleBeginElement( const string &rName, AttrList_t &attr )
RequireDefault( "priority" );
CheckDefault( "x", "0" );
CheckDefault( "y", "0" );
CheckDefault( "lefttop", "lefttop" );
CheckDefault( "points", "(0,0)" );
CheckDefault( "range", "10" );
const BuilderData::Anchor anchor( atoi( attr["x"] ) + m_xOffset,
atoi( attr["y"] ) + m_yOffset, atoi( attr["range"] ),
atoi( attr["priority"] ), attr["points"], m_curLayoutId );
atoi( attr["y"] ) + m_yOffset, attr["lefttop"],
atoi( attr["range"] ), atoi( attr["priority"] ),
attr["points"], m_curLayoutId );
m_pData->m_listAnchor.push_back( anchor );
}
......
......@@ -28,46 +28,60 @@
#include "skin_common.hpp"
#include "generic_layout.hpp"
#include "../utils/bezier.hpp"
#include "../utils/position.hpp"
/// Class for the windows anchors
class Anchor: public SkinObject
{
public:
Anchor( intf_thread_t *pIntf, int xPos, int yPos, int range,
Anchor( intf_thread_t *pIntf, const Position &rPosition, int range,
int priority, const Bezier &rCurve, GenericLayout &rLayout ):
SkinObject( pIntf ), m_xPos( xPos ), m_yPos( yPos ),
SkinObject( pIntf ), m_position( rPosition ),
m_rCurve( rCurve ), m_range( range ), m_priority( priority ),
m_rLayout( rLayout ) {}
virtual ~Anchor() {}
/// Return true if the given anchor is hanged by this one
/// Two conditions are required:
/// - the other anchor must be in position of anchoring (as defined
/// by canHang())
/// - the priority of the other anchor must be lower than this one's
/**
* Return true if the given anchor is hanged by this one
* Two conditions are required:
* - the other anchor must be in position of anchoring (as defined
* by canHang())
* - the priority of the other anchor must be lower than this one's
*/
bool isHanging( const Anchor &rOther ) const;
/// Return true if the other anchor, moved by the (xOffset, yOffset)
/// vector, is "hangable" by this one (i.e. if it is in its range of
/// action), else return false.
/// When the function returns true, the xOffset and yOffset parameters
/// are modified to indicate the position that the other anchor would
/// take if hanged by this one (this position is calculated to minimize
/// the difference with the old xOffset and yOffset, so that the window
/// doesn't "jump" in a strange way).
/**
* Return true if the other anchor, moved by the (xOffset, yOffset)
* vector, is "hangable" by this one (i.e. if it is in its range of
* action), else return false.
* When the function returns true, the xOffset and yOffset parameters
* are modified to indicate the position that the other anchor would
* take if hanged by this one (this position is calculated to minimize
* the difference with the old xOffset and yOffset, so that the window
* doesn't "jump" in a strange way).
*/
bool canHang( const Anchor &rOther, int &xOffset, int &yOffset ) const;
// Indicate whether this anchor is reduced to a single point
bool isPoint() const { return m_rCurve.getNbCtrlPoints() == 1; }
// Getters
int getXPosAbs() const { return (m_xPos + m_rLayout.getLeft()); }
int getYPosAbs() const { return (m_yPos + m_rLayout.getTop()); }
const Position & getPosition() const { return m_position; }
int getXPosAbs() const
{
return (m_position.getLeft() + m_rLayout.getLeft());
}
int getYPosAbs() const
{
return (m_position.getTop() + m_rLayout.getTop());
}
private:
/// Coordinates relative to the window
int m_xPos, m_yPos;
/// Position in the layout
Position m_position;
/// Curve of the anchor
const Bezier &m_rCurve;
......@@ -78,7 +92,7 @@ class Anchor: public SkinObject
/// Priority
int m_priority;
/// Parent window
/// Parent layout
GenericLayout &m_rLayout;
};
......
......@@ -158,29 +158,6 @@ void GenericLayout::onControlUpdate( const CtrlGeneric &rCtrl,
void GenericLayout::resize( int width, int height )
{
// Check boundaries
if( width < m_minWidth )
{
width = m_minWidth;
}
if( width > m_maxWidth )
{
width = m_maxWidth;
}
if( height < m_minHeight )
{
height = m_minHeight;
}
if( height > m_maxHeight )
{
height = m_maxHeight;
}
if( width == m_width && height == m_height )
{
return;
}
// Update the window size
m_width = width;
m_height = height;
......
......@@ -28,12 +28,13 @@
#include "os_factory.hpp"
#include "anchor.hpp"
#include "tooltip.hpp"
#include "var_manager.hpp"
#include "../utils/position.hpp"
#include "../src/var_manager.hpp"
WindowManager::WindowManager( intf_thread_t *pIntf ):
SkinObject( pIntf ), m_magnet( 0 ), m_pTooltip( NULL ), m_pPopup( NULL )
SkinObject( pIntf ), m_magnet( 0 ), m_direction( kNone ),
m_pTooltip( NULL ), m_pPopup( NULL )
{
// Create and register a variable for the "on top" status
VarManager *pVarManager = VarManager::instance( getIntf() );
......@@ -170,6 +171,152 @@ void WindowManager::move( TopWindow &rWindow, int left, int top ) const
}
void WindowManager::startResize( GenericLayout &rLayout, Direction_t direction )
{
m_direction = direction;
// Rebuild the set of moving windows.
// From the resized window, we only take into account the anchors which
// are mobile with the current type of resizing, and that are hanging a
// window. The hanged windows will come will all their dependencies.
m_resizeMovingE.clear();
m_resizeMovingS.clear();
m_resizeMovingSE.clear();
WinSet_t::const_iterator itWin;
AncList_t::const_iterator itAnc1, itAnc2;
// Get the anchors of the layout
const AncList_t &ancList1 = rLayout.getAnchorList();
// Iterate through all the hanged windows
for( itWin = m_dependencies[rLayout.getWindow()].begin();
itWin != m_dependencies[rLayout.getWindow()].end(); itWin++ )
{
// Now, check for anchoring between the 2 windows
const AncList_t &ancList2 =
(*itWin)->getActiveLayout().getAnchorList();
for( itAnc1 = ancList1.begin(); itAnc1 != ancList1.end(); itAnc1++ )
{
for( itAnc2 = ancList2.begin();
itAnc2 != ancList2.end(); itAnc2++ )
{
if( (*itAnc1)->isHanging( **itAnc2 ) )
{
// Add the dependencies of the hanged window to one of the
// lists of moving windows
Position::Ref_t aRefPos =
(*itAnc1)->getPosition().getRefLeftTop();
if( aRefPos == Position::kRightTop )
buildDependSet( m_resizeMovingE, *itWin );
else if( aRefPos == Position::kLeftBottom )
buildDependSet( m_resizeMovingS, *itWin );
else if( aRefPos == Position::kRightBottom )
buildDependSet( m_resizeMovingSE, *itWin );
break;
}
}
}
}
// The checkAnchors() method will need to have m_movingWindows properly set
// so let's insert in it the contents of the other sets
m_movingWindows.clear();
m_movingWindows.insert( rLayout.getWindow() );
m_movingWindows.insert( m_resizeMovingE.begin(), m_resizeMovingE.end() );
m_movingWindows.insert( m_resizeMovingS.begin(), m_resizeMovingS.end() );
m_movingWindows.insert( m_resizeMovingSE.begin(), m_resizeMovingSE.end() );
}
void WindowManager::stopResize()
{
// Nothing different from stopMove(), luckily
stopMove();
}
void WindowManager::resize( GenericLayout &rLayout,
int width, int height ) const
{
// TODO: handle anchored windows
// Compute the real resizing offset
int xOffset = width - rLayout.getWidth();
int yOffset = height - rLayout.getHeight();
// Check anchoring; this can change the values of xOffset and yOffset
checkAnchors( rLayout.getWindow(), xOffset, yOffset );
if( m_direction == kResizeS )
xOffset = 0;
if( m_direction == kResizeE )
yOffset = 0;
int newWidth = rLayout.getWidth() + xOffset;
int newHeight = rLayout.getHeight() + yOffset;
// Check boundaries
if( newWidth < rLayout.getMinWidth() )
{
newWidth = rLayout.getMinWidth();
}
if( newWidth > rLayout.getMaxWidth() )
{
newWidth = rLayout.getMaxWidth();
}
if( newHeight < rLayout.getMinHeight() )
{
newHeight = rLayout.getMinHeight();
}
if( newHeight > rLayout.getMaxHeight() )
{
newHeight = rLayout.getMaxHeight();
}
if( newWidth == rLayout.getWidth() && newHeight == rLayout.getHeight() )
{
return;
}
// New offset, after the last corrections
int xNewOffset = newWidth - rLayout.getWidth();
int yNewOffset = newHeight - rLayout.getHeight();
// Do the actual resizing
rLayout.resize( newWidth, newHeight );
// Move all the anchored windows
WinSet_t::const_iterator it;
if( m_direction == kResizeE ||
m_direction == kResizeSE )
{
for( it = m_resizeMovingE.begin(); it != m_resizeMovingE.end(); it++ )
{
(*it)->move( (*it)->getLeft() + xNewOffset,
(*it)->getTop() );
}
}
if( m_direction == kResizeE ||
m_direction == kResizeSE )
{
for( it = m_resizeMovingS.begin(); it != m_resizeMovingS.end(); it++ )
{
(*it)->move( (*it)->getLeft(),
(*it)->getTop( )+ yNewOffset );
}
}
if( m_direction == kResizeE ||
m_direction == kResizeS ||
m_direction == kResizeSE )
{
for( it = m_resizeMovingSE.begin(); it != m_resizeMovingSE.end(); it++ )
{
(*it)->move( (*it)->getLeft() + xNewOffset,
(*it)->getTop() + yNewOffset );
}
}
}
void WindowManager::synchVisibility() const
{
WinSet_t::const_iterator it;
......@@ -203,7 +350,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)->isVisible() || !firstTime )
{
(*it)->show();
}
......@@ -381,7 +528,7 @@ void WindowManager::createTooltip( const GenericFont &rTipFont )
}
else
{
msg_Warn( getIntf(), "tooltip already created!");
msg_Warn( getIntf(), "tooltip already created!" );
}
}
......
......@@ -44,6 +44,15 @@ class Popup;
class WindowManager: public SkinObject
{
public:
/// Direction of the resizing
enum Direction_t
{
kResizeE, // East
kResizeSE, // South-East
kResizeS, // South
kNone // Reserved for internal use
};
/// Constructor
WindowManager( intf_thread_t *pIntf);
......@@ -57,22 +66,38 @@ class WindowManager: public SkinObject
/// Remove a previously registered window
void unregisterWindow( TopWindow &rWindow );
/// Tell the window manager that a move is initiated for pWindow.
/// Tell the window manager that a move is initiated for rWindow
void startMove( TopWindow &rWindow );
/// Tell the window manager that the current move ended.
/// Tell the window manager that the current move ended
void stopMove();
/// Move the pWindow window to (left, top), and move all its
/// anchored windows.
/// If a new anchoring is detected, the windows will move accordingly.
/**
* Move the rWindow window to (left, top), and move all its
* anchored windows.
* If a new anchoring is detected, the windows will move accordingly.
*/
void move( TopWindow &rWindow, int left, int top ) const;
/// Tell the window manager that a resize is initiated for rWindow
void startResize( GenericLayout &rLayout, Direction_t direction );
/// Tell the window manager that the current resizing ended
void stopResize();
/**
* Resize the rWindow window to (width, height), and move all its
* anchored windows, if some anchors are moved during the resizing.
* If a new anchoring is detected, the windows will move (or resize)
* accordingly.
*/
void resize( GenericLayout &rLayout, int width, int height ) const;
/// Raise all the registered windows
void raiseAll() const;
/// Show all the registered windows
void showAll(bool firstTime = false) const;
void showAll( bool firstTime = false ) const;
/// Hide all the registered windows
void hideAll() const;
......@@ -142,6 +167,15 @@ class WindowManager: public SkinObject
/// Store the moving windows; this set is updated at every start of
/// move.
WinSet_t m_movingWindows;
/**
* Store the moving windows in the context of resizing
* These sets are updated at every start of move
*/
//@{
WinSet_t m_resizeMovingE;
WinSet_t m_resizeMovingS;
WinSet_t m_resizeMovingSE;
//@}
/// Indicate whether the windows are currently on top
VariablePtr m_cVarOnTop;
/// Magnetism of the screen edges (= scope of action)
......@@ -150,6 +184,8 @@ class WindowManager: public SkinObject
int m_alpha;
/// Alpha value of the moving windows
int m_moveAlpha;
/// Direction of the current resizing
Direction_t m_direction;
/// Tooltip
Tooltip *m_pTooltip;
/// Active popup, if any
......
......@@ -95,6 +95,9 @@ class Position
/// Get the size of the rectangle
int getWidth() const;
int getHeight() const;
/// Get the reference corners
Ref_t getRefLeftTop() const { return m_refLeftTop; }
Ref_t getRefRightBottom() const { return m_refRighBottom; }
private:
/// Position and reference edge/corner
......
......@@ -12,3 +12,4 @@ SOURCES_gnutls = gnutls.c
SOURCES_svg = svg.c
SOURCES_msn = msn.c
SOURCES_growl = growl.c
SOURCES_notify = notify.c
/*****************************************************************************
* notify.c : libnotify notification plugin
*****************************************************************************
* Copyright (C) 2006 the VideoLAN team
* $Id$
*
* Authors: Christophe Mutricy <xtophe -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.
*****************************************************************************/
/*****************************************************************************
* Preamble
*****************************************************************************/
#include <stdlib.h> /* malloc(), free() */
#include <errno.h>
#include <libnotify/notify.h>
#include <vlc/vlc.h>
#include <vlc/intf.h>
#include <vlc_meta.h>
/*****************************************************************************
* Local prototypes
*****************************************************************************/
static int Open ( vlc_object_t * );
static void Close ( vlc_object_t * );
static void Run ( intf_thread_t * );
static int ItemChange( vlc_object_t *, const char *,
vlc_value_t, vlc_value_t, void * );
static int Notify( vlc_object_t *, const char * );
#define MAX_LENGTH 256
/*****************************************************************************
* Module descriptor
****************************************************************************/
#define APPLICATION_NAME "VLC media player"
#define TIMEOUT_TEXT N_("Timeout (ms)")
#define TIMEOUT_LONGTEXT N_("How long the notification will be displayed ")
vlc_module_begin();
set_category( CAT_INTERFACE );
set_subcategory( SUBCAT_INTERFACE_CONTROL );
set_shortname( N_( "Notify" ) );
set_description( _("LibNotify Notification Plugin") );
add_integer( "notify-timeout", 4000,NULL,
TIMEOUT_TEXT, TIMEOUT_LONGTEXT, VLC_TRUE );
set_capability( "interface", 0 );
set_callbacks( Open, Close );
vlc_module_end();
/*****************************************************************************
* Open: initialize and create stuff
*****************************************************************************/
static int Open( vlc_object_t *p_this )
{
intf_thread_t *p_intf = (intf_thread_t *)p_this;
playlist_t *p_playlist = (playlist_t *)vlc_object_find(
p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
if( !p_playlist )
{
msg_Err( p_intf, "could not find playlist object" );
return VLC_ENOOBJ;
}
var_AddCallback( p_playlist, "playlist-current", ItemChange, p_intf );
/* var_AddCallback( p_playlist, "item-change", ItemChange, p_intf );*/
vlc_object_release( p_playlist );
if( !notify_init( APPLICATION_NAME ) )
{
msg_Err( p_intf, "can't find notification daemon" );
return VLC_EGENERIC;
}
p_intf->pf_run = Run;
msg_Dbg( p_intf,"notify plugin started");
return VLC_SUCCESS;
}
/*****************************************************************************
* Close: destroy interface stuff
*****************************************************************************/
static void Close( vlc_object_t *p_this )
{
playlist_t *p_playlist = (playlist_t *)vlc_object_find(
p_this, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
if( p_playlist )
{
var_DelCallback( p_playlist, "playlist-current", ItemChange, p_this );
vlc_object_release( p_playlist );
}
notify_uninit();
}
/*****************************************************************************
* Run
*****************************************************************************/
static void Run( intf_thread_t *p_this )
{
msleep( 100*INTF_IDLE_SLEEP );
}
/*****************************************************************************
* ItemChange: Playlist item change callback
*****************************************************************************/
static int ItemChange( vlc_object_t *p_this, const char *psz_var,
vlc_value_t oldval, vlc_value_t newval, void *param )
{
char psz_tmp[MAX_LENGTH];
playlist_t *p_playlist;
char *psz_title = NULL;
char *psz_artist = NULL;
char *psz_album = NULL;
input_thread_t *p_input=NULL;
p_playlist = (playlist_t *)vlc_object_find( p_this, VLC_OBJECT_PLAYLIST,
FIND_ANYWHERE );
if( !p_playlist ) return VLC_EGENERIC;
p_input = p_playlist->p_input;
vlc_object_release( p_playlist );
if( !p_input ) return VLC_SUCCESS;
vlc_object_yield( p_input );
if( p_input->b_dead || !p_input->input.p_item->psz_name )
{
/* Not playing anything ... */
vlc_object_release( p_input );
return VLC_SUCCESS;
}
/* Playing something ... */
psz_artist = vlc_input_item_GetInfo( p_input->input.p_item,
_("Meta-information"),
_(VLC_META_ARTIST) );
psz_album = vlc_input_item_GetInfo( p_input->input.p_item,
_("Meta-information"),
_("Album/movie/show title" ) );
psz_title = strdup( p_input->input.p_item->psz_name );
if( psz_title == NULL ) psz_title = strdup( N_("(no title)") );
if( psz_artist == NULL ) psz_artist = strdup( N_("(no artist)") );
if( psz_album == NULL ) psz_album = strdup( N_("(no album)") );
snprintf( psz_tmp, MAX_LENGTH, "<b>%s</b>\n%s - %s",
psz_title, psz_artist, psz_album );
free( psz_title );
free( psz_artist );
free( psz_album );
Notify( p_this, psz_tmp );
vlc_object_release( p_input );
return VLC_SUCCESS;
}
static int Notify( vlc_object_t *p_this, const char *psz_temp )
{
NotifyNotification * notification;
notification = notify_notification_new( _("Now Playing"),
psz_temp,
"/usr/share/pixmaps/vlc.png",NULL);
notify_notification_set_timeout( notification,
config_GetInt(p_this, "notify-timeout") );
notify_notification_set_urgency( notification, NOTIFY_URGENCY_LOW );
notify_notification_show( notification, NULL);
return VLC_SUCCESS;
}
......@@ -26,8 +26,8 @@ gettextsrcdir = $(datadir)/gettext/po
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
MKINSTALLDIRS = ${top_builddir}/@MKINSTALLDIRS@
mkinstalldirs = $(SHELL) `case "$(MKINSTALLDIRS)" in /*) echo "$(MKINSTALLDIRS)" ;; *) echo "$(MKINSTALLDIRS)" ;; esac`
MKINSTALLDIRS = @MKINSTALLDIRS@
mkinstalldirs = $(SHELL) `case "$(MKINSTALLDIRS)" in /*) echo "$(MKINSTALLDIRS)" ;; *) echo "$(top_builddir)/$(MKINSTALLDIRS)" ;; esac`
GMSGFMT = @GMSGFMT@
MSGFMT = @MSGFMT@
......
This diff is collapsed.
......@@ -99,6 +99,7 @@
<!ATTLIST Anchor
x CDATA "0"
y CDATA "0"
lefttop CDATA "lefttop"
priority CDATA #REQUIRED
points CDATA "(0,0)"
range CDATA "10"
......
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