#include "os_factory.hpp"
#include "os_graphics.hpp"
#include "var_manager.hpp"
+#include "anchor.hpp"
#include "../controls/ctrl_generic.hpp"
#include "../controls/ctrl_video.hpp"
#include "../utils/var_bool.hpp"
+#include <set>
GenericLayout::GenericLayout( intf_thread_t *pIntf, int width, int height,
int minWidth, int maxWidth, int minHeight,
int maxHeight ):
- SkinObject( pIntf ), m_pWindow( NULL ), m_width( width ),
- m_height( height ), m_minWidth( minWidth ), m_maxWidth( maxWidth ),
- m_minHeight( minHeight ), m_maxHeight( maxHeight ), m_pVideoControl( NULL ),
+ SkinObject( pIntf ), m_pWindow( NULL ), m_rect( 0, 0, width, height ),
+ m_minWidth( minWidth ), m_maxWidth( maxWidth ),
+ m_minHeight( minHeight ), m_maxHeight( maxHeight ), m_pVideoCtrlSet(),
m_visible( false ), m_pVarActive( NULL )
{
// Get the OSFactory
GenericLayout::~GenericLayout()
{
- if( m_pImage )
+ delete m_pImage;
+
+ list<Anchor*>::const_iterator it;
+ for( it = m_anchorList.begin(); it != m_anchorList.end(); it++ )
{
- delete m_pImage;
+ delete *it;
}
+
+ list<LayeredControl>::const_iterator iter;
+ for( iter = m_controlList.begin(); iter != m_controlList.end(); iter++ )
+ {
+ CtrlGeneric *pCtrl = (*iter).m_pControl;
+ pCtrl->unsetLayout();
+ }
+
}
// Associate this layout to the control
pControl->setLayout( this, rPosition );
- // Draw the control
- pControl->draw( *m_pImage, rPosition.getLeft(), rPosition.getTop() );
-
// Add the control in the list.
- // This list must remain sorted by layer order
+ // This list must remain sorted by layer order
list<LayeredControl>::iterator it;
for( it = m_controlList.begin(); it != m_controlList.end(); it++ )
{
// Check if it is a video control
if( pControl->getType() == "video" )
{
- m_pVideoControl = (CtrlVideo*)pControl;
+ m_pVideoCtrlSet.insert( (CtrlVideo*)pControl );
}
}
else
int width, int height,
int xOffSet, int yOffSet )
{
- // The size is not valid, refresh the whole layout
- if( width <= 0 || height <= 0 )
- {
- refreshAll();
+ // Do nothing if the layout or control is hidden
+ if( !m_visible )
return;
- }
const Position *pPos = rCtrl.getPosition();
- if( pPos )
+ if( width > 0 && height > 0 )
{
- refreshRect( pPos->getLeft() + xOffSet,
+ // make sure region is within the layout
+ rect region( pPos->getLeft() + xOffSet,
pPos->getTop() + yOffSet,
width, height );
+ rect layout( 0, 0, m_rect.getWidth(), m_rect.getHeight() );
+ rect inter;
+ if( rect::intersect( layout, region, &inter ) )
+ {
+ refreshRect( inter.x, inter.y, inter.width, inter.height );
+ }
}
}
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;
+ m_rect = SkinsRect( 0, 0 , width, height );
// Recreate a new image
if( m_pImage )
{
// Resize the window
pWindow->resize( width, height );
- refreshAll();
// Change the shape of the window and redraw it
- pWindow->updateShape();
refreshAll();
}
}
void GenericLayout::refreshAll()
{
- refreshRect( 0, 0, m_width, m_height );
+ refreshRect( 0, 0, m_rect.getWidth(), m_rect.getHeight() );
}
if( !m_visible )
return;
+ // update the transparency global mask
+ m_pImage->clear( x, y, width, height );
+
// Draw all the controls of the layout
list<LayeredControl>::const_iterator iter;
list<LayeredControl>::const_iterator iterVideo = m_controlList.end();
for( iter = m_controlList.begin(); iter != m_controlList.end(); iter++ )
{
CtrlGeneric *pCtrl = (*iter).m_pControl;
- const Position *pPos = pCtrl->getPosition();
- if( pPos && pCtrl->isVisible() )
+ if( pCtrl->isVisible() )
{
- pCtrl->draw( *m_pImage, pPos->getLeft(), pPos->getTop() );
+ pCtrl->draw( *m_pImage, x, y, width, height );
}
}
TopWindow *pWindow = getWindow();
if( pWindow )
{
- // Check boundaries
- if( x < 0 )
- x = 0;
- if( y < 0)
- y = 0;
- if( x + width > m_width )
- width = m_width - x;
- if( y + height > m_height )
- height = m_height - y;
-
- // Refresh the window... but do not paint on a video control!
- if( !m_pVideoControl )
- {
- // No video control, we can safely repaint the rectangle
- pWindow->refresh( x, y, width, height );
- }
- else
- {
- // Bad luck, there is a video control somewhere (not necessarily
- // in the repainting zone, btw).
- // We will divide the repainting into 4 regions (top, left, bottom
- // and right). The overlapping parts (i.e. the corners) of these
- // regions will be painted twice, because otherwise the algorithm
- // becomes a real mess :)
-
- // Use short variable names for convenience
- int xx = m_pVideoControl->getPosition()->getLeft();
- int yy = m_pVideoControl->getPosition()->getTop();
- int ww = m_pVideoControl->getPosition()->getWidth();
- int hh = m_pVideoControl->getPosition()->getHeight();
-
- // Top part:
- if( y < yy )
- pWindow->refresh( x, y, width, yy - y );
- // Left part:
- if( x < xx )
- pWindow->refresh( x, y, xx - x, height );
- // Bottom part
- if( y + height > yy + hh )
- pWindow->refresh( x, yy + hh, width, y + height - (yy + hh) );
- // Right part
- if( x + width > xx + ww )
- pWindow->refresh( xx + ww, y, x + width - (xx + ww), height );
- }
+ // first apply new shape to the window
+ pWindow->updateShape();
+
+ pWindow->refresh( x, y, width, height );
}
}
m_visible = true;
refreshAll();
- // TODO find a better way to handle the vout ?
- if( m_pVideoControl )
- {
- m_pVideoControl->setVisible( true );
- }
}
void GenericLayout::onHide()
{
m_visible = false;
-
- // TODO find a better way to handle the vout ?
- if( m_pVideoControl )
- {
- m_pVideoControl->setVisible( false );
- }
}