}
-void CtrlButton::draw( OSGraphics &rImage, int xDest, int yDest )
-{
- if( m_pImg )
+void CtrlButton::draw( OSGraphics &rImage, int xDest, int yDest, int w, int h )
+{
+ const Position *pPos = getPosition();
+ rect region( pPos->getLeft(), pPos->getTop(),
+ pPos->getWidth(), pPos->getHeight() );
+ rect clip( xDest, yDest, w, h );
+ rect inter;
+ if( rect::intersect( region, clip, &inter ) && m_pImg )
{
// Draw the current image
- m_pImg->draw( rImage, xDest, yDest );
+ m_pImg->draw( rImage, inter.x, inter.y, inter.width, inter.height,
+ inter.x - pPos->getLeft(),
+ inter.y - pPos->getTop() );
}
}
-
void CtrlButton::setImage( AnimBitmap *pImg )
{
AnimBitmap *pOldImg = m_pImg;
void CtrlButton::onUpdate( Subject<AnimBitmap> &rBitmap, void *arg )
{
- notifyLayout();
+ notifyLayout( m_pImg->getWidth(), m_pImg->getHeight() );
}
virtual bool mouseOver( int x, int y ) const;
/// Draw the control on the given graphics
- virtual void draw( OSGraphics &rImage, int xDest, int yDest );
+ virtual void draw( OSGraphics &rImage, int xDest, int yDest, int w, int h );
/// Get the text of the tooltip
virtual UString getTooltipText() const { return m_tooltip; }
}
-void CtrlCheckbox::draw( OSGraphics &rImage, int xDest, int yDest )
+void CtrlCheckbox::draw( OSGraphics &rImage, int xDest, int yDest, int w, int h )
{
- if( m_pImgCurrent )
+ if( !m_pImgCurrent )
+ return;
+
+ const Position *pPos = getPosition();
+ // rect region( pPos->getLeft(), pPos->getTop(),
+ // pPos->getWidth(), pPos->getHeight() );
+ rect region( pPos->getLeft(), pPos->getTop(),
+ m_pImgCurrent->getWidth(), m_pImgCurrent->getHeight() );
+ rect clip( xDest, yDest, w, h );
+ rect inter;
+ if( rect::intersect( region, clip, &inter ) )
{
// Draw the current image
- m_pImgCurrent->draw( rImage, xDest, yDest );
+ m_pImgCurrent->draw( rImage,
+ inter.x, inter.y, inter.width, inter.height,
+ inter.x - pPos->getLeft(),
+ inter.y - pPos->getTop() );
}
}
void CtrlCheckbox::onUpdate( Subject<AnimBitmap> &rBitmap, void *arg )
{
- notifyLayout();
+ notifyLayout( m_pImgCurrent->getWidth(), m_pImgCurrent->getHeight() );
}
virtual bool mouseOver( int x, int y ) const;
/// Draw the control on the given graphics
- virtual void draw( OSGraphics &rImage, int xDest, int yDest );
+ virtual void draw( OSGraphics &rImage, int xDest, int yDest, int w, int h );
/// Get the text of the tooltip XXX
virtual UString getTooltipText() const { return *m_pTooltip; }
}
void CtrlGeneric::notifyLayout( int width, int height,
- int xOffSet, int yOffSet ) const
+ int xOffSet, int yOffSet )
{
+ width = ( width > 0 ) ? width : m_pPosition->getWidth();
+ height = ( height > 0 ) ? height : m_pPosition->getHeight();
+
// Notify the layout
if( m_pLayout )
{
virtual bool mouseOver( int x, int y ) const { return false; }
/// Draw the control on the given graphics
- virtual void draw( OSGraphics &rImage, int xDest, int yDest ) { }
+ virtual void draw( OSGraphics &rImage, int xDest, int yDest, int w, int h ) { }
/// Set the position and the associated layout of the control
virtual void setLayout( GenericLayout *pLayout,
* Use the default values to repaint the whole window
*/
virtual void notifyLayout( int witdh = -1, int height = -1,
- int xOffSet = 0, int yOffSet = 0 ) const;
+ int xOffSet = 0, int yOffSet = 0 );
/**
* Same as notifyLayout(), but takes optional images as parameters.
}
-void CtrlImage::draw( OSGraphics &rImage, int xDest, int yDest )
+void CtrlImage::draw( OSGraphics &rImage, int xDest, int yDest, int w, int h )
{
const Position *pPos = getPosition();
if( !pPos )
if( width <= 0 || height <= 0 )
return;
+ rect region( pPos->getLeft(), pPos->getTop(),
+ pPos->getWidth(), pPos->getHeight() );
+ rect clip( xDest, yDest, w, h );
+ rect inter;
+ if( !rect::intersect( region, clip, &inter ) )
+ return;
+
if( m_resizeMethod == kScale )
{
// Use scaling method
m_pImage = pOsFactory->createOSGraphics( width, height );
m_pImage->drawBitmap( bmp, 0, 0 );
}
- rImage.drawGraphics( *m_pImage, 0, 0, xDest, yDest );
+ rImage.drawGraphics( *m_pImage,
+ inter.x - pPos->getLeft(),
+ inter.y - pPos->getTop(),
+ inter.x, inter.y,
+ inter.width, inter.height );
}
else if( m_resizeMethod == kMosaic )
{
+ int xDest0 = pPos->getLeft();
+ int yDest0 = pPos->getTop();
+
// Use mosaic method
while( width > 0 )
{
int curWidth = __MIN( width, m_pImage->getWidth() );
height = pPos->getHeight();
- int curYDest = yDest;
+ int curYDest = yDest0;
while( height > 0 )
{
int curHeight = __MIN( height, m_pImage->getHeight() );
- rImage.drawGraphics( *m_pImage, 0, 0, xDest, curYDest,
- curWidth, curHeight );
+ rect region1( xDest0, curYDest, curWidth, curHeight );
+ rect inter1;
+ if( rect::intersect( region1, clip, &inter1 ) )
+ {
+ rImage.drawGraphics( *m_pImage,
+ inter1.x - region1.x,
+ inter1.y - region1.y,
+ inter1.x, inter1.y,
+ inter1.width, inter1.height );
+ }
curYDest += curHeight;
height -= m_pImage->getHeight();
}
- xDest += curWidth;
+ xDest0 += curWidth;
width -= m_pImage->getWidth();
}
}
}
// draw the scaled image at offset (m_x, m_y) from control origin
- rImage.drawGraphics( *m_pImage, 0, 0, xDest + m_x, yDest + m_y );
+ rect region1( pPos->getLeft() + m_x, pPos->getTop() + m_y, w, h );
+ rect inter1;
+ if( rect::intersect( region1, inter, &inter1 ) )
+ {
+ rImage.drawGraphics( *m_pImage,
+ inter1.x - pPos->getLeft() - m_x,
+ inter1.y - pPos->getTop() - m_y,
+ inter1.x, inter1.y,
+ inter1.width, inter1.height );
+ }
}
}
virtual bool mouseOver( int x, int y ) const;
/// Draw the control on the given graphics
- virtual void draw( OSGraphics &rImage, int xDest, int yDest );
+ virtual void draw( OSGraphics &rImage, int xDest, int yDest, int w, int h );
/// Get the type of control (custom RTTI)
virtual string getType() const { return "image"; }
}
-void CtrlList::draw( OSGraphics &rImage, int xDest, int yDest )
+void CtrlList::draw( OSGraphics &rImage, int xDest, int yDest, int w, int h )
{
- if( m_pImage )
+ const Position *pPos = getPosition();
+ rect region( pPos->getLeft(), pPos->getTop(),
+ pPos->getWidth(), pPos->getHeight() );
+ rect clip( xDest, yDest, w, h );
+ rect inter;
+ if( rect::intersect( region, clip, &inter ) && m_pImage )
{
- rImage.drawGraphics( *m_pImage, 0, 0, xDest, yDest );
+ rImage.drawGraphics( *m_pImage,
+ inter.x - pPos->getLeft(),
+ inter.y - pPos->getTop(),
+ inter.x, inter.y, inter.width, inter.height );
}
}
virtual bool mouseOver( int x, int y ) const;
/// Draw the control on the given graphics
- virtual void draw( OSGraphics &rImage, int xDest, int yDest );
+ virtual void draw( OSGraphics &rImage, int xDest, int yDest, int w, int h );
/// Called when the layout is resized
virtual void onResize();
}
-void CtrlMove::draw( OSGraphics &rImage, int xDest, int yDest )
+void CtrlMove::draw( OSGraphics &rImage, int xDest, int yDest, int w, int h )
{
- m_rCtrl.draw( rImage, xDest, yDest );
+ m_rCtrl.draw( rImage, xDest, yDest, w, h );
}
virtual bool mouseOver( int x, int y ) const;
/// Draw the control on the given graphics
- virtual void draw( OSGraphics &rImage, int xDest, int yDest );
+ virtual void draw( OSGraphics &rImage, int xDest, int yDest, int w, int h );
/// Set the position and the associated layout of the decorated control
virtual void setLayout( GenericLayout *pLayout,
}
-void CtrlRadialSlider::draw( OSGraphics &rImage, int xDest, int yDest )
+void CtrlRadialSlider::draw( OSGraphics &rImage, int xDest, int yDest, int w, int h )
{
- rImage.drawGraphics( *m_pImgSeq, 0, m_position * m_height, xDest, yDest,
- m_width, m_height );
+ const Position *pPos = getPosition();
+ rect region( pPos->getLeft(), pPos->getTop(), m_width, m_height );
+ rect clip( xDest, yDest, w ,h );
+ rect inter;
+ if( rect::intersect( region, clip, &inter ) )
+ rImage.drawGraphics( *m_pImgSeq,
+ inter.x - region.x,
+ inter.y - region.y + m_position * m_height,
+ inter.x, inter.y,
+ inter.width, inter.height );
}
void CtrlRadialSlider::onUpdate( Subject<VarPercent> &rVariable,
void *arg )
{
- m_position = (int)( m_rVariable.get() * ( m_numImg - 1 ) );
- notifyLayout( m_width, m_height );
+ if( &rVariable == &m_rVariable )
+ {
+ int position = (int)( m_rVariable.get() * ( m_numImg - 1 ) );
+ if( position == m_position )
+ return;
+
+ m_position = position;
+ notifyLayout( m_width, m_height );
+ }
}
virtual bool mouseOver( int x, int y ) const;
/// Draw the control on the given graphics
- virtual void draw( OSGraphics &rImage, int xDest, int yDest );
+ virtual void draw( OSGraphics &rImage, int xDest, int yDest, int w, int h );
/// Get the type of control (custom RTTI)
virtual string getType() const { return "radial_slider"; }
}
-void CtrlResize::draw( OSGraphics &rImage, int xDest, int yDest )
+void CtrlResize::draw( OSGraphics &rImage, int xDest, int yDest, int w, int h )
{
- m_rCtrl.draw( rImage, xDest, yDest );
+ m_rCtrl.draw( rImage, xDest, yDest, w, h );
}
virtual bool mouseOver( int x, int y ) const;
/// Draw the control on the given graphics
- virtual void draw( OSGraphics &rImage, int xDest, int yDest );
+ virtual void draw( OSGraphics &rImage, int xDest, int yDest, int w, int h );
/// Set the position and the associated layout of the decorated control
virtual void setLayout( GenericLayout *pLayout,
}
-void CtrlSliderCursor::draw( OSGraphics &rImage, int xDest, int yDest )
+void CtrlSliderCursor::draw( OSGraphics &rImage, int xDest, int yDest, int w, int h )
{
if( m_pImg )
{
- // Compute the position of the cursor
- int xPos, yPos;
- m_rCurve.getPoint( m_rVariable.get(), xPos, yPos );
+ // Draw the current image
+ rect inter;
+ rect clip( xDest, yDest, w, h);
+
+ if( rect::intersect( m_currentCursorRect, clip, &inter ) )
+ rImage.drawGraphics( *m_pImg,
+ inter.x - m_currentCursorRect.x,
+ inter.y - m_currentCursorRect.y,
+ inter.x, inter.y, inter.width, inter.height );
+ }
+}
- // Compute the resize factors
- float factorX, factorY;
- getResizeFactors( factorX, factorY );
- xPos = (int)(xPos * factorX);
- yPos = (int)(yPos * factorY);
- // Draw the current image
- rImage.drawGraphics( *m_pImg, 0, 0,
- xDest + xPos - m_pImg->getWidth() / 2,
- yDest + yPos - m_pImg->getHeight() / 2 );
+void CtrlSliderCursor::onPositionChange()
+{
+ // Compute the position of the cursor
+ int xPos, yPos;
+ m_rCurve.getPoint( m_rVariable.get(), xPos, yPos );
+
+ // Compute the resize factors
+ float factorX, factorY;
+ getResizeFactors( factorX, factorY );
+ xPos = (int)(xPos * factorX);
+ yPos = (int)(yPos * factorY);
+
+ const Position *pPos = getPosition();
+
+ int x = pPos->getLeft() + xPos - m_pImg->getWidth() / 2;
+ int y = pPos->getTop() + yPos - m_pImg->getHeight() / 2;
+
+ m_currentCursorRect = rect( x, y, m_pImg->getWidth(), m_pImg->getHeight() );
+}
+
+
+void CtrlSliderCursor::onResize()
+{
+ onPositionChange();
+}
+
+
+void CtrlSliderCursor::notifyLayout( int width, int height, int xOffSet, int yOffSet )
+{
+ if( width > 0 && height > 0 )
+ {
+ CtrlGeneric::notifyLayout( width, height, xOffSet, yOffSet );
+ }
+ else
+ {
+ onPositionChange();
+
+ const Position *pPos = getPosition();
+ CtrlGeneric::notifyLayout( m_currentCursorRect.width,
+ m_currentCursorRect.height,
+ m_currentCursorRect.x - pPos->getLeft(),
+ m_currentCursorRect.y - pPos->getTop() );
}
}
void *arg )
{
// The position has changed
- refreshLayout();
+ refreshLayout( false );
}
}
-void CtrlSliderCursor::refreshLayout()
+void CtrlSliderCursor::refreshLayout( bool force )
{
- if( !m_pImg )
- notifyLayout();
- else
+ // Compute the position of the cursor
+ int xPos, yPos;
+ m_rCurve.getPoint( m_rVariable.get(), xPos, yPos );
+
+ // Compute the resize factors
+ float factorX, factorY;
+ getResizeFactors( factorX, factorY );
+ xPos = (int)(xPos * factorX);
+ yPos = (int)(yPos * factorY);
+
+ const Position *pPos = getPosition();
+
+ int x = pPos->getLeft() + xPos - m_pImg->getWidth() / 2;
+ int y = pPos->getTop() + yPos - m_pImg->getHeight() / 2;
+
+ rect region( x, y, m_pImg->getWidth(), m_pImg->getHeight() );
+
+
+ if( !force &&
+ region.x == m_currentCursorRect.x &&
+ region.y == m_currentCursorRect.y &&
+ region.width == m_currentCursorRect.width &&
+ region.height == m_currentCursorRect.height )
{
- // Compute the resize factors
- float factorX, factorY;
- getResizeFactors( factorX, factorY );
+ return;
+ }
- notifyLayout( (int)(m_rCurve.getWidth() * factorX) + m_pImg->getWidth(),
- (int)(m_rCurve.getHeight() * factorY) + m_pImg->getHeight(),
- - m_pImg->getWidth() / 2,
- - m_pImg->getHeight() / 2 );
+ rect join;
+ if( rect::join( m_currentCursorRect, region, &join ) )
+ {
+ m_currentCursorRect = region;
+ notifyLayout( join.width, join.height,
+ join.x - pPos->getLeft(),
+ join.y - pPos->getTop() );
}
}
m_width( rCurve.getWidth() ), m_height( rCurve.getHeight() ),
m_pImgSeq( pBackground ), m_nbHoriz( nbHoriz ), m_nbVert( nbVert ),
m_padHoriz( padHoriz ), m_padVert( padVert ), m_bgWidth( 0 ),
- m_bgHeight( 0 ), m_position( 0 )
+ m_bgHeight( 0 ), m_position( 0 ), m_pScaledBmp( NULL )
{
- if( pBackground )
+ if( m_pImgSeq )
{
// Build the background image sequence
// Note: we suppose that the last padding is not included in the
CtrlSliderBg::~CtrlSliderBg()
{
- m_rVariable.delObserver( this );
+ if( m_pImgSeq )
+ m_rVariable.delObserver( this );
+
+ delete m_pScaledBmp;
}
}
-void CtrlSliderBg::draw( OSGraphics &rImage, int xDest, int yDest )
+void CtrlSliderBg::draw( OSGraphics &rImage, int xDest, int yDest, int w, int h )
{
if( !m_pImgSeq || m_bgWidth <=0 || m_bgHeight <= 0 )
return;
float factorX, factorY;
getResizeFactors( factorX, factorY );
- // Rescale the image with the actual size of the control
- ScaledBitmap bmp( getIntf(), *m_pImgSeq,
- m_bgWidth * m_nbHoriz - (int)(m_padHoriz * factorX),
- m_bgHeight * m_nbVert - (int)(m_padVert * factorY) );
+ int width = m_bgWidth * m_nbHoriz - (int)(m_padHoriz * factorX);
+ int height = m_bgHeight * m_nbVert - (int)(m_padVert * factorY);
+
+ // Rescale the image with the actual size of the control if needed
+ if( !m_pScaledBmp ||
+ m_pScaledBmp->getWidth() != width ||
+ m_pScaledBmp->getHeight() != height )
+ {
+ delete m_pScaledBmp;
+ m_pScaledBmp = new ScaledBitmap( getIntf(), *m_pImgSeq, width, height );
+ }
// Locate the right image in the background bitmap
int x = m_bgWidth * ( m_position % m_nbHoriz );
int y = m_bgHeight * ( m_position / m_nbHoriz );
+
// Draw the background image
- rImage.drawBitmap( bmp, x, y, xDest, yDest,
- m_bgWidth - (int)(m_padHoriz * factorX),
- m_bgHeight - (int)(m_padVert * factorY) );
+ const Position *pPos = getPosition();
+ rect region( pPos->getLeft(), pPos->getTop(),
+ m_bgWidth - (int)(m_padHoriz * factorX),
+ m_bgHeight - (int)(m_padVert * factorY) );
+ rect clip( xDest, yDest, w, h );
+ rect inter;
+ if( rect::intersect( region, clip, &inter ) )
+ rImage.drawBitmap( *m_pScaledBmp,
+ x + inter.x - region.x,
+ y + inter.y - region.y,
+ inter.x, inter.y,
+ inter.width, inter.height );
}
class GenericBitmap;
+class ScaledBitmap;
class OSGraphics;
class VarPercent;
virtual bool mouseOver( int x, int y ) const;
/// Draw the control on the given graphics
- virtual void draw( OSGraphics &rImage, int xDest, int yDest );
+ virtual void draw( OSGraphics &rImage, int xDest, int yDest, int w, int h );
+
+ /// Called when the position is set
+ virtual void onPositionChange();
+
+ /// Method called when the control is resized
+ virtual void onResize();
+
+ /// Method called to notify are to be updated
+ virtual void notifyLayout( int witdh = -1, int height = -1,
+ int xOffSet = 0, int yOffSet = 0 );
+
/// Get the text of the tooltip
virtual UString getTooltipText() const { return m_tooltip; }
int m_width, m_height;
/// Position of the cursor
int m_xPosition, m_yPosition;
+ rect m_currentCursorRect;
/// Callback objects
DEFINE_CALLBACK( CtrlSliderCursor, OverDown )
DEFINE_CALLBACK( CtrlSliderCursor, DownOver )
void getResizeFactors( float &rFactorX, float &rFactorY ) const;
/// Call notifyLayout
- void refreshLayout();
+ void refreshLayout( bool force = true );
};
virtual bool mouseOver( int x, int y ) const;
/// Draw the control on the given graphics
- virtual void draw( OSGraphics &rImage, int xDest, int yDest );
+ virtual void draw( OSGraphics &rImage, int xDest, int yDest, int w, int h );
/// Handle an event
virtual void handleEvent( EvtGeneric &rEvent );
int m_width, m_height;
/// Background image sequence (optional)
GenericBitmap *m_pImgSeq;
+ /// Scaled bitmap if needed
+ ScaledBitmap *m_pScaledBmp;
/// Number of images in the background bitmap
int m_nbHoriz, m_nbVert;
/// Number of pixels between two images
}
-void CtrlText::draw( OSGraphics &rImage, int xDest, int yDest )
+void CtrlText::draw( OSGraphics &rImage, int xDest, int yDest, int w, int h )
{
+ rect clip( xDest, yDest, w, h );
+ const Position *pPos = getPosition();
if( m_pCurrImg )
{
// Compute the dimensions to draw
else if( m_alignment == kCenter &&
width < getPosition()->getWidth() )
{
- // The text is shorter than the width of the control, so we
- // can center it
+ // The text is shorter than the width of the control, so we
+ // can center it
offset = (getPosition()->getWidth() - width) / 2;
}
- rImage.drawBitmap( *m_pCurrImg, -m_xPos, 0, xDest + offset,
- yDest, width, height, true );
+ rect region( pPos->getLeft() + offset,
+ pPos->getTop(), width, height );
+ rect inter;
+ if( rect::intersect( region, clip, &inter ) )
+ rImage.drawBitmap( *m_pCurrImg, -m_xPos + inter.x - region.x,
+ inter.y - region.y,
+ inter.x, inter.y,
+ inter.width, inter.height, true );
}
}
}
virtual bool mouseOver( int x, int y ) const;
/// Draw the control on the given graphics
- virtual void draw( OSGraphics &rImage, int xDest, int yDest );
+ virtual void draw( OSGraphics &rImage, int xDest, int yDest, int w, int h );
/// Set the text of the control, with an optional color
/// This takes effect immediatly
x >= 0 && x <= pPos->getWidth() && y >= 0 && y <= pPos->getHeight();
}
-void CtrlTree::draw( OSGraphics &rImage, int xDest, int yDest )
+void CtrlTree::draw( OSGraphics &rImage, int xDest, int yDest, int w, int h)
{
- if( m_pImage )
- rImage.drawGraphics( *m_pImage, 0, 0, xDest, yDest );
+ const Position *pPos = getPosition();
+ rect region( pPos->getLeft(), pPos->getTop(),
+ pPos->getWidth(), pPos->getHeight() );
+ rect clip( xDest, yDest, w, h );
+ rect inter;
+
+ if( rect::intersect( region, clip, &inter ) && m_pImage )
+ rImage.drawGraphics( *m_pImage,
+ inter.x - pPos->getLeft(),
+ inter.y - pPos->getTop(),
+ inter.x, inter.y, inter.width, inter.height );
}
bool CtrlTree::ensureVisible( VarTree::Iterator item )
virtual bool mouseOver( int x, int y ) const;
/// Draw the control on the given graphics
- virtual void draw( OSGraphics &rImage, int xDest, int yDest );
+ virtual void draw( OSGraphics &rImage, int xDest, int yDest, int w, int h );
/// Called when the layout is resized
virtual void onResize();
}
-void CtrlVideo::draw( OSGraphics &rImage, int xDest, int yDest )
+void CtrlVideo::draw( OSGraphics &rImage, int xDest, int yDest, int w, int h)
{
const Position *pPos = getPosition();
- if( pPos )
+ rect region( pPos->getLeft(), pPos->getTop(),
+ pPos->getWidth(), pPos->getHeight() );
+ rect clip( xDest, yDest, w, h );
+ rect inter;
+
+ if( rect::intersect( region, clip, &inter ) )
{
// Draw a black rectangle under the video to avoid transparency
- rImage.fillRect( pPos->getLeft(), pPos->getTop(), pPos->getWidth(),
- pPos->getHeight(), 0 );
+ rImage.fillRect( inter.x, inter.y, inter.width, inter.height, 0 );
+ }
+
+ if( m_pVoutWindow )
+ {
+ m_pVoutWindow->move( pPos->getLeft(), pPos->getTop() );
+ m_pVoutWindow->resize( pPos->getWidth(), pPos->getHeight() );
+ m_pVoutWindow->show();
}
}
virtual void onPositionChange();
/// Draw the control on the given graphics
- virtual void draw( OSGraphics &rImage, int xDest, int yDest );
+ virtual void draw( OSGraphics &rImage, int xDest, int yDest, int w, int h );
/// Get the type of control (custom RTTI)
virtual string getType() const { return "video"; }
}
-void AnimBitmap::draw( OSGraphics &rImage, int xDest, int yDest )
+void AnimBitmap::draw( OSGraphics &rImage, int xDest, int yDest, int w, int h,
+ int xOffset, int yOffset )
{
// Draw the current frame
int height = m_pImage->getHeight() / m_nbFrames;
// rImage.drawGraphics( *m_pImage, 0, ySrc, xDest, yDest,
// m_pImage->getWidth(), height );
- // A new way .... needs to be tested thoroughly
- rImage.drawBitmap( m_rBitmap, 0, ySrc, xDest, yDest,
- m_pImage->getWidth(), height, true );
+ rImage.drawBitmap( m_rBitmap,
+ xOffset, ySrc + yOffset,
+ xDest, yDest, w, h, true );
}
void stopAnim();
/// Draw the current frame on another graphics
- void draw( OSGraphics &rImage, int xDest, int yDest );
+ void draw( OSGraphics &rImage, int xDest, int yDest, int w, int h, int xOffset = 0, int yOffset = 0 );
/// Tell whether the pixel at the given position is visible
bool hit( int x, int y ) const;
// Associate this layout to the control
pControl->setLayout( this, rPosition );
- // Draw the control
- if( pControl->isVisible() )
- pControl->draw( *m_pImage, rPosition.getLeft(), rPosition.getTop() );
-
// Add the control in the list.
// This list must remain sorted by layer order
list<LayeredControl>::iterator it;
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 );
+ }
}
}
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 );
}
}
// first apply new shape to the window
pWindow->updateShape();
- // Check boundaries
- if( x < 0 )
- x = 0;
- if( y < 0)
- y = 0;
- if( x + width > m_rect.getWidth() )
- width = m_rect.getWidth() - x;
- if( y + height > m_rect.getHeight() )
- height = m_rect.getHeight() - y;
-
pWindow->refresh( x, y, width, height );
}
}
};
+class rect
+{
+public:
+ rect( int v_x = 0, int v_y = 0, int v_width = 0, int v_height = 0 )
+ : x( v_x ), y( v_y ), width( v_width ), height( v_height ) { }
+ ~rect() { }
+ int x;
+ int y;
+ int width;
+ int height;
+
+ // rect2 fully included in rect1
+ static bool isIncluded( rect& rect2, rect& rect1 )
+ {
+ int x1 = rect1.x;
+ int y1 = rect1.y;
+ int w1 = rect1.width;
+ int h1 = rect1.height;
+
+ int x2 = rect2.x;
+ int y2 = rect2.y;
+ int w2 = rect2.width;
+ int h2 = rect2.height;
+
+ return x2 >= x1 && x2 < x1 + w1
+ && y2 >= y1 && y2 < y1 + h1
+ && w2 <= w1
+ && h2 <= h1;
+ }
+
+ static bool areDisjunct( rect& rect2, rect& rect1 )
+ {
+ int x1 = rect1.x;
+ int y1 = rect1.y;
+ int w1 = rect1.width;
+ int h1 = rect1.height;
+
+ int x2 = rect2.x;
+ int y2 = rect2.y;
+ int w2 = rect2.width;
+ int h2 = rect2.height;
+
+ return y2 + h2 -1 < y1 // rect2 above rect1
+ || y2 > y1 + h1 - 1 // rect2 under rect1
+ || x2 > x1 + w1 -1 // rect2 right of rect1
+ || x2 + w2 - 1 < x1; // rect2 left of rect1
+ }
+
+ static bool intersect( rect& rect1, rect& rect2, rect* pRect )
+ {
+ int x1 = rect1.x;
+ int y1 = rect1.y;
+ int w1 = rect1.width;
+ int h1 = rect1.height;
+
+ int x2 = rect2.x;
+ int y2 = rect2.y;
+ int w2 = rect2.width;
+ int h2 = rect2.height;
+
+ if( areDisjunct( rect1, rect2 ) )
+ return false;
+ else
+ {
+ int left = max( x1, x2 );
+ int right = min( x1 + w1 - 1, x2 + w2 - 1 );
+ int top = max( y1, y2 );
+ int bottom = min( y1 + h1 - 1, y2 + h2 -1 );
+ pRect->x = left;
+ pRect->y = top;
+ pRect->width = right - left + 1;
+ pRect->height = bottom - top + 1;
+
+ return pRect->width > 0 && pRect->height > 0;
+ }
+ }
+
+ static bool join( rect& rect1, rect& rect2, rect* pRect )
+ {
+ int x1 = rect1.x;
+ int y1 = rect1.y;
+ int w1 = rect1.width;
+ int h1 = rect1.height;
+
+ int x2 = rect2.x;
+ int y2 = rect2.y;
+ int w2 = rect2.width;
+ int h2 = rect2.height;
+
+ int left = min( x1, x2 );
+ int right = max( x1 + w1 - 1, x2 + w2 - 1 );
+ int top = min( y1, y2 );
+ int bottom = max( y1 + h1 - 1, y2 + h2 -1 );
+ pRect->x = left;
+ pRect->y = top;
+ pRect->width = right - left + 1;
+ pRect->height = bottom - top + 1;
+
+ return pRect->width > 0 && pRect->height > 0;
+ }
+ static int min( int x, int y ) { return x < y ? x : y; }
+ static int max( int x, int y ) { return x < y ? y : x; }
+
+};
+
+
#endif