Main Page | Modules | Class Hierarchy | Class List | Directories | File List | Class Members | File Members | Related Pages

generic_layout.cpp

00001 /*****************************************************************************
00002  * generic_layout.cpp
00003  *****************************************************************************
00004  * Copyright (C) 2003 the VideoLAN team
00005  * $Id: generic_layout.cpp 12469 2005-09-03 22:25:36Z ipkiss $
00006  *
00007  * Authors: Cyril Deguet     <[email protected]>
00008  *          Olivier Teulière <[email protected]>
00009  *
00010  * This program is free software; you can redistribute it and/or modify
00011  * it under the terms of the GNU General Public License as published by
00012  * the Free Software Foundation; either version 2 of the License, or
00013  * (at your option) any later version.
00014  *
00015  * This program is distributed in the hope that it will be useful,
00016  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018  * GNU General Public License for more details.
00019  *
00020  * You should have received a copy of the GNU General Public License
00021  * along with this program; if not, write to the Free Software
00022  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
00023  *****************************************************************************/
00024 
00025 #include "generic_layout.hpp"
00026 #include "top_window.hpp"
00027 #include "os_factory.hpp"
00028 #include "os_graphics.hpp"
00029 #include "../controls/ctrl_generic.hpp"
00030 
00031 
00032 GenericLayout::GenericLayout( intf_thread_t *pIntf, int width, int height,
00033                               int minWidth, int maxWidth, int minHeight,
00034                               int maxHeight ):
00035     SkinObject( pIntf ), m_pWindow( NULL ), m_width( width ),
00036     m_height( height ), m_minWidth( minWidth ), m_maxWidth( maxWidth ),
00037     m_minHeight( minHeight ), m_maxHeight( maxHeight )
00038 {
00039     // Get the OSFactory
00040     OSFactory *pOsFactory = OSFactory::instance( getIntf() );
00041     // Create the graphics buffer
00042     m_pImage = pOsFactory->createOSGraphics( width, height );
00043 }
00044 
00045 
00046 GenericLayout::~GenericLayout()
00047 {
00048     if( m_pImage )
00049     {
00050         delete m_pImage;
00051     }
00052 }
00053 
00054 
00055 void GenericLayout::setWindow( TopWindow *pWindow )
00056 {
00057     m_pWindow = pWindow;
00058 }
00059 
00060 
00061 void GenericLayout::onControlCapture( const CtrlGeneric &rCtrl )
00062 {
00063     // Just forward the request to the window
00064     TopWindow *pWindow = getWindow();
00065     if( pWindow )
00066     {
00067         pWindow->onControlCapture( rCtrl );
00068     }
00069 }
00070 
00071 
00072 void GenericLayout::onControlRelease( const CtrlGeneric &rCtrl )
00073 {
00074     // Just forward the request to the window
00075     TopWindow *pWindow = getWindow();
00076     if( pWindow )
00077     {
00078         pWindow->onControlRelease( rCtrl );
00079     }
00080 }
00081 
00082 
00083 void GenericLayout::addControl( CtrlGeneric *pControl,
00084                                 const Position &rPosition, int layer )
00085 {
00086     if( pControl )
00087     {
00088         // Associate this layout to the control
00089         pControl->setLayout( this, rPosition );
00090 
00091         // Draw the control
00092         pControl->draw( *m_pImage, rPosition.getLeft(), rPosition.getTop() );
00093 
00094         // Add the control in the list.
00095         // This list must remain sorted by layer order 
00096         list<LayeredControl>::iterator it;
00097         for( it = m_controlList.begin(); it != m_controlList.end(); it++ )
00098         {
00099             if( layer < (*it).m_layer )
00100             {
00101                 m_controlList.insert( it, LayeredControl( pControl, layer ) );
00102                 break;
00103             }
00104         }
00105         // If this control is in front of all the previous ones
00106         if( it == m_controlList.end() )
00107         {
00108             m_controlList.push_back( LayeredControl( pControl, layer ) );
00109         }
00110     }
00111     else
00112     {
00113         msg_Dbg( getIntf(), "Adding NULL control in the layout" );
00114     }
00115 }
00116 
00117 
00118 const list<LayeredControl> &GenericLayout::getControlList() const
00119 {
00120     return m_controlList;
00121 }
00122 
00123 
00124 void GenericLayout::onControlUpdate( const CtrlGeneric &rCtrl,
00125                                      int width, int height,
00126                                      int xOffSet, int yOffSet )
00127 {
00128     // The size is not valid, refresh the whole layout
00129     if( width <= 0 || height <= 0 )
00130     {
00131         refreshAll();
00132         return;
00133     }
00134 
00135     const Position *pPos = rCtrl.getPosition();
00136     if( pPos )
00137     {
00138         refreshRect( pPos->getLeft() + xOffSet,
00139                      pPos->getTop() + yOffSet,
00140                      width, height );
00141     }
00142 }
00143 
00144 
00145 void GenericLayout::resize( int width, int height )
00146 {
00147     if( width == m_width && height == m_height )
00148     {
00149         return;
00150     }
00151 
00152     // Update the window size
00153     m_width = width;
00154     m_height = height;
00155 
00156     // Recreate a new image
00157     if( m_pImage )
00158     {
00159         delete m_pImage;
00160         OSFactory *pOsFactory = OSFactory::instance( getIntf() );
00161         m_pImage = pOsFactory->createOSGraphics( width, height );
00162     }
00163 
00164     // Notify all the controls that the size has changed and redraw them
00165     list<LayeredControl>::const_iterator iter;
00166     for( iter = m_controlList.begin(); iter != m_controlList.end(); iter++ )
00167     {
00168         (*iter).m_pControl->onResize();
00169         const Position *pPos = (*iter).m_pControl->getPosition();
00170         if( pPos )
00171         {
00172             (*iter).m_pControl->draw( *m_pImage, pPos->getLeft(),
00173                                       pPos->getTop() );
00174         }
00175     }
00176 
00177     // Resize and refresh the associated window
00178     TopWindow *pWindow = getWindow();
00179     if( pWindow )
00180     {
00181         // Resize the window
00182         pWindow->refresh( 0, 0, width, height );
00183         pWindow->resize( width, height );
00184         pWindow->refresh( 0, 0, width, height );
00185 
00186         // Change the shape of the window and redraw it
00187         pWindow->updateShape();
00188         pWindow->refresh( 0, 0, width, height );
00189     }
00190 }
00191 
00192 
00193 void GenericLayout::refreshAll()
00194 {
00195     refreshRect( 0, 0, m_width, m_height );
00196 }
00197 
00198 
00199 void GenericLayout::refreshRect( int x, int y, int width, int height )
00200 {
00201     // Draw all the controls of the layout
00202     list<LayeredControl>::const_iterator iter;
00203     list<LayeredControl>::const_iterator iterVideo = m_controlList.end();
00204     for( iter = m_controlList.begin(); iter != m_controlList.end(); iter++ )
00205     {
00206         CtrlGeneric *pCtrl = (*iter).m_pControl;
00207         const Position *pPos = pCtrl->getPosition();
00208         if( pCtrl->isVisible() && pPos )
00209         {
00210             pCtrl->draw( *m_pImage, pPos->getLeft(), pPos->getTop() );
00211             // Remember the video control (we assume there is at most one video
00212             // control per layout)
00213             if( pCtrl->getType() == "video" && pCtrl->getPosition() )
00214                 iterVideo = iter;
00215         }
00216     }
00217 
00218     // Refresh the associated window
00219     TopWindow *pWindow = getWindow();
00220     if( pWindow )
00221     {
00222         // Check boundaries
00223         if( x < 0 )
00224             x = 0;
00225         if( y < 0)
00226             y = 0;
00227         if( x + width > m_width )
00228             width = m_width - x;
00229         if( y + height > m_height )
00230             height = m_height - y;
00231 
00232         // Refresh the window... but do not paint on a video control!
00233         if( iterVideo == m_controlList.end() )
00234         {
00235             // No video control, we can safely repaint the rectangle
00236             pWindow->refresh( x, y, width, height );
00237         }
00238         else
00239         {
00240             // Bad luck, there is a video control somewhere (not necessarily
00241             // in the repainting zone, btw).
00242             // We will divide the repainting into 4 regions (top, left, bottom
00243             // and right). The overlapping parts (i.e. the corners) of these
00244             // regions will be painted twice, because otherwise the algorithm
00245             // becomes a real mess :)
00246 
00247             // Use short variable names for convenience
00248             int xx = iterVideo->m_pControl->getPosition()->getLeft();
00249             int yy = iterVideo->m_pControl->getPosition()->getTop();
00250             int ww = iterVideo->m_pControl->getPosition()->getWidth();
00251             int hh = iterVideo->m_pControl->getPosition()->getHeight();
00252 
00253             // Top part:
00254             if( y < yy )
00255                 pWindow->refresh( x, y, width, yy - y );
00256             // Left part:
00257             if( x < xx )
00258                 pWindow->refresh( x, y, xx - x, height );
00259             // Bottom part
00260             if( y + height > yy + hh )
00261                 pWindow->refresh( x, yy + hh, width, y + height - (yy + hh) );
00262             // Right part
00263             if( x + width > xx + ww )
00264                 pWindow->refresh( xx + ww, y, x + width - (xx + ww), height );
00265         }
00266     }
00267 }
00268 
00269 
00270 const list<Anchor*>& GenericLayout::getAnchorList() const
00271 {
00272     return m_anchorList;
00273 }
00274 
00275 
00276 void GenericLayout::addAnchor( Anchor *pAnchor )
00277 {
00278     m_anchorList.push_back( pAnchor );
00279 }
00280 

Generated on Tue Dec 20 10:14:42 2005 for vlc-0.8.4a by  doxygen 1.4.2