00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "window_manager.hpp"
00026 #include "generic_layout.hpp"
00027 #include "generic_window.hpp"
00028 #include "os_factory.hpp"
00029 #include "anchor.hpp"
00030 #include "tooltip.hpp"
00031 #include "../utils/position.hpp"
00032 #include "../src/var_manager.hpp"
00033
00034
00035 WindowManager::WindowManager( intf_thread_t *pIntf ):
00036 SkinObject( pIntf ), m_magnet( 0 ), m_pTooltip( NULL )
00037 {
00038
00039 VarManager *pVarManager = VarManager::instance( getIntf() );
00040 m_cVarOnTop = VariablePtr( new VarBoolImpl( getIntf() ) );
00041 pVarManager->registerVar( m_cVarOnTop, "vlc.isOnTop" );
00042 }
00043
00044
00045 WindowManager::~WindowManager()
00046 {
00047 delete m_pTooltip;
00048 }
00049
00050
00051 void WindowManager::registerWindow( TopWindow &rWindow )
00052 {
00053
00054 m_allWindows.insert( &rWindow );
00055 }
00056
00057
00058 void WindowManager::unregisterWindow( TopWindow &rWindow )
00059 {
00060
00061 m_allWindows.erase( &rWindow );
00062 m_movingWindows.erase( &rWindow );
00063 m_dependencies.erase( &rWindow );
00064 }
00065
00066
00067 void WindowManager::startMove( TopWindow &rWindow )
00068 {
00069
00070 m_movingWindows.clear();
00071 buildDependSet( m_movingWindows, &rWindow );
00072
00073 #ifdef WIN32
00074 if( config_GetInt( getIntf(), "skins2-transparency" ) )
00075 {
00076
00077 WinSet_t::const_iterator it;
00078 for( it = m_movingWindows.begin(); it != m_movingWindows.end(); it++ )
00079 {
00080 (*it)->setOpacity( m_moveAlpha );
00081 }
00082
00083
00084
00085
00086 for( it = m_allWindows.begin(); it != m_allWindows.end(); it++ )
00087 {
00088 (*it)->refresh( 0, 0, (*it)->getWidth(), (*it)->getHeight() );
00089 }
00090 }
00091 #endif
00092 }
00093
00094
00095 void WindowManager::stopMove()
00096 {
00097 WinSet_t::const_iterator itWin1, itWin2;
00098 AncList_t::const_iterator itAnc1, itAnc2;
00099
00100 #ifdef WIN32
00101 if( config_GetInt( getIntf(), "skins2-transparency" ) )
00102 {
00103
00104 WinSet_t::const_iterator it;
00105 for( it = m_movingWindows.begin(); it != m_movingWindows.end(); it++ )
00106 {
00107 (*it)->setOpacity( m_alpha );
00108 }
00109 }
00110 #endif
00111
00112
00113 m_dependencies.clear();
00114
00115
00116
00117 for( itWin1 = m_allWindows.begin(); itWin1 != m_allWindows.end(); itWin1++ )
00118 {
00119
00120 const AncList_t &ancList1 =
00121 (*itWin1)->getActiveLayout().getAnchorList();
00122
00123
00124 for( itWin2 = itWin1; itWin2 != m_allWindows.end(); itWin2++ )
00125 {
00126
00127 if( (*itWin2) == (*itWin1) )
00128 continue;
00129
00130
00131 const AncList_t &ancList2 =
00132 (*itWin2)->getActiveLayout().getAnchorList();
00133 for( itAnc1 = ancList1.begin(); itAnc1 != ancList1.end(); itAnc1++ )
00134 {
00135 for( itAnc2 = ancList2.begin();
00136 itAnc2 != ancList2.end(); itAnc2++ )
00137 {
00138 if( (*itAnc1)->isHanging( **itAnc2 ) )
00139 {
00140
00141 m_dependencies[*itWin1].insert( *itWin2 );
00142 }
00143 else if( (*itAnc2)->isHanging( **itAnc1 ) )
00144 {
00145
00146 m_dependencies[*itWin2].insert( *itWin1 );
00147 }
00148 }
00149 }
00150 }
00151 }
00152 }
00153
00154
00155 void WindowManager::move( TopWindow &rWindow, int left, int top ) const
00156 {
00157
00158 int xOffset = left - rWindow.getLeft();
00159 int yOffset = top - rWindow.getTop();
00160
00161
00162 checkAnchors( &rWindow, xOffset, yOffset );
00163
00164
00165 WinSet_t::const_iterator it;
00166 for( it = m_movingWindows.begin(); it != m_movingWindows.end(); it++ )
00167 {
00168 (*it)->move( (*it)->getLeft() + xOffset, (*it)->getTop() + yOffset );
00169 }
00170 }
00171
00172
00173 void WindowManager::synchVisibility() const
00174 {
00175 WinSet_t::const_iterator it;
00176 for( it = m_allWindows.begin(); it != m_allWindows.end(); it++ )
00177 {
00178
00179 if( (*it)->getVisibleVar().get() )
00180 {
00181 (*it)->innerShow();
00182 }
00183 }
00184 }
00185
00186
00187 void WindowManager::raiseAll() const
00188 {
00189
00190 WinSet_t::const_iterator it;
00191 for( it = m_allWindows.begin(); it != m_allWindows.end(); it++ )
00192 {
00193 (*it)->raise();
00194 }
00195 }
00196
00197
00198 void WindowManager::showAll( bool firstTime ) const
00199 {
00200
00201 WinSet_t::const_iterator it;
00202 for( it = m_allWindows.begin(); it != m_allWindows.end(); it++ )
00203 {
00204
00205
00206 if ((*it)->isVisible() || !firstTime)
00207 {
00208 (*it)->show();
00209 }
00210 (*it)->setOpacity( m_alpha );
00211 }
00212 }
00213
00214
00215 void WindowManager::hideAll() const
00216 {
00217 WinSet_t::const_iterator it;
00218 for( it = m_allWindows.begin(); it != m_allWindows.end(); it++ )
00219 {
00220 (*it)->hide();
00221 }
00222 }
00223
00224
00225 void WindowManager::toggleOnTop()
00226 {
00227
00228 VarBoolImpl *pVarOnTop = (VarBoolImpl*)m_cVarOnTop.get();
00229 pVarOnTop->set( !pVarOnTop->get() );
00230
00231
00232 WinSet_t::const_iterator it;
00233 for( it = m_allWindows.begin(); it != m_allWindows.end(); it++ )
00234 {
00235 (*it)->toggleOnTop( pVarOnTop->get() );
00236 }
00237 }
00238
00239
00240 void WindowManager::buildDependSet( WinSet_t &rWinSet,
00241 TopWindow *pWindow )
00242 {
00243
00244 rWinSet.insert( pWindow );
00245
00246
00247 const WinSet_t &anchored = m_dependencies[pWindow];
00248 WinSet_t::const_iterator iter;
00249 for( iter = anchored.begin(); iter != anchored.end(); iter++ )
00250 {
00251
00252 if( rWinSet.find( *iter ) == rWinSet.end() )
00253 {
00254 buildDependSet( rWinSet, *iter );
00255 }
00256 }
00257 }
00258
00259
00260 void WindowManager::checkAnchors( TopWindow *pWindow,
00261 int &xOffset, int &yOffset ) const
00262 {
00263 WinSet_t::const_iterator itMov, itSta;
00264 AncList_t::const_iterator itAncMov, itAncSta;
00265
00266
00267 Rect workArea = OSFactory::instance( getIntf() )->getWorkArea();
00268
00269 for( itMov = m_movingWindows.begin();
00270 itMov != m_movingWindows.end(); itMov++ )
00271 {
00272
00273 if( ! (*itMov)->getVisibleVar().get() )
00274 {
00275 continue;
00276 }
00277
00278 int newLeft = (*itMov)->getLeft() + xOffset;
00279 int newTop = (*itMov)->getTop() + yOffset;
00280 if( newLeft > workArea.getLeft() - m_magnet &&
00281 newLeft < workArea.getLeft() + m_magnet )
00282 {
00283 xOffset = workArea.getLeft() - (*itMov)->getLeft();
00284 }
00285 if( newTop > workArea.getTop() - m_magnet &&
00286 newTop < workArea.getTop() + m_magnet )
00287 {
00288 yOffset = workArea.getTop() - (*itMov)->getTop();
00289 }
00290 if( newLeft + (*itMov)->getWidth() > workArea.getRight() - m_magnet &&
00291 newLeft + (*itMov)->getWidth() < workArea.getRight() + m_magnet )
00292 {
00293 xOffset = workArea.getRight() - (*itMov)->getLeft()
00294 - (*itMov)->getWidth();
00295 }
00296 if( newTop + (*itMov)->getHeight() > workArea.getBottom() - m_magnet &&
00297 newTop + (*itMov)->getHeight() < workArea.getBottom() + m_magnet )
00298 {
00299 yOffset = workArea.getBottom() - (*itMov)->getTop()
00300 - (*itMov)->getHeight();
00301 }
00302 }
00303
00304
00305 for( itMov = m_movingWindows.begin();
00306 itMov != m_movingWindows.end(); itMov++ )
00307 {
00308
00309 if( ! (*itMov)->getVisibleVar().get() )
00310 {
00311 continue;
00312 }
00313
00314
00315 const AncList_t &movAnchors =
00316 (*itMov)->getActiveLayout().getAnchorList();
00317
00318
00319 for( itSta = m_allWindows.begin();
00320 itSta != m_allWindows.end(); itSta++ )
00321 {
00322
00323 if( m_movingWindows.find( (*itSta) ) != m_movingWindows.end() ||
00324 ! (*itSta)->getVisibleVar().get() )
00325 {
00326 continue;
00327 }
00328
00329
00330 const AncList_t &staAnchors =
00331 (*itSta)->getActiveLayout().getAnchorList();
00332
00333
00334
00335 for( itAncMov = movAnchors.begin();
00336 itAncMov != movAnchors.end(); itAncMov++ )
00337 {
00338 for( itAncSta = staAnchors.begin();
00339 itAncSta != staAnchors.end(); itAncSta++ )
00340 {
00341 if( (*itAncSta)->canHang( **itAncMov, xOffset, yOffset ) )
00342 {
00343
00344
00345
00346
00347
00348 return;
00349 }
00350 else
00351 {
00352
00353 int xOffsetTemp = -xOffset;
00354 int yOffsetTemp = -yOffset;
00355 if( (*itAncMov)->canHang( **itAncSta, xOffsetTemp,
00356 yOffsetTemp ) )
00357 {
00358
00359
00360
00361 xOffset = -xOffsetTemp;
00362 yOffset = -yOffsetTemp;
00363
00364
00365 return;
00366 }
00367 }
00368 }
00369 }
00370 }
00371 }
00372 }
00373
00374
00375 void WindowManager::createTooltip( const GenericFont &rTipFont )
00376 {
00377
00378 if( !m_pTooltip )
00379 {
00380 m_pTooltip = new Tooltip( getIntf(), rTipFont, 500 );
00381 }
00382 else
00383 {
00384 msg_Warn( getIntf(), "Tooltip already created!");
00385 }
00386 }
00387
00388
00389 void WindowManager::showTooltip()
00390 {
00391 if( m_pTooltip )
00392 {
00393 m_pTooltip->show();
00394 }
00395 }
00396
00397
00398 void WindowManager::hideTooltip()
00399 {
00400 if( m_pTooltip )
00401 {
00402 m_pTooltip->hide();
00403 }
00404 }
00405
00406
00407 void WindowManager::addLayout( TopWindow &rWindow, GenericLayout &rLayout )
00408 {
00409 rWindow.setActiveLayout( &rLayout );
00410 }
00411
00412
00413 void WindowManager::setActiveLayout( TopWindow &rWindow,
00414 GenericLayout &rLayout )
00415 {
00416 rWindow.setActiveLayout( &rLayout );
00417
00418 stopMove();
00419 }