📄 window_manager.cpp
字号:
/***************************************************************************** * window_manager.cpp ***************************************************************************** * Copyright (C) 2003 the VideoLAN team * $Id$ * * Authors: Cyril Deguet <asmax@via.ecp.fr> * Olivier Teulière <ipkiss@via.ecp.fr> * * 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. *****************************************************************************/#include "window_manager.hpp"#include "generic_layout.hpp"#include "generic_window.hpp"#include "os_factory.hpp"#include "anchor.hpp"#include "tooltip.hpp"#include "var_manager.hpp"WindowManager::WindowManager( intf_thread_t *pIntf ): SkinObject( pIntf ), m_magnet( 0 ), m_direction( kNone ), m_maximizeRect(0, 0, 50, 50), m_pTooltip( NULL ), m_pPopup( NULL ){ // Create and register a variable for the "on top" status VarManager *pVarManager = VarManager::instance( getIntf() ); m_cVarOnTop = VariablePtr( new VarBoolImpl( getIntf() ) ); pVarManager->registerVar( m_cVarOnTop, "vlc.isOnTop" );}WindowManager::~WindowManager(){ delete m_pTooltip;}void WindowManager::registerWindow( TopWindow &rWindow ){ // Add the window to the set m_allWindows.insert( &rWindow );}void WindowManager::unregisterWindow( TopWindow &rWindow ){ // Erase every possible reference to the window m_allWindows.erase( &rWindow ); m_movingWindows.erase( &rWindow ); m_dependencies.erase( &rWindow );}void WindowManager::startMove( TopWindow &rWindow ){ // Rebuild the set of moving windows m_movingWindows.clear(); buildDependSet( m_movingWindows, &rWindow );#ifdef WIN32 if( config_GetInt( getIntf(), "skins2-transparency" ) ) { // Change the opacity of the moving windows WinSet_t::const_iterator it; for( it = m_movingWindows.begin(); it != m_movingWindows.end(); it++ ) { (*it)->setOpacity( m_moveAlpha ); } // FIXME: We need to refresh the windows, because if 2 windows overlap // and one of them becomes transparent, the other one is not refreshed // automatically. I don't know why... -- Ipkiss for( it = m_allWindows.begin(); it != m_allWindows.end(); it++ ) { (*it)->refresh( 0, 0, (*it)->getWidth(), (*it)->getHeight() ); } }#endif}void WindowManager::stopMove(){ WinSet_t::const_iterator itWin1, itWin2; AncList_t::const_iterator itAnc1, itAnc2;#ifdef WIN32 if( config_GetInt( getIntf(), "skins2-transparency" ) ) { // Restore the opacity of the moving windows WinSet_t::const_iterator it; for( it = m_movingWindows.begin(); it != m_movingWindows.end(); it++ ) { (*it)->setOpacity( m_alpha ); } }#endif // Delete the dependencies m_dependencies.clear(); // Now we rebuild the dependencies. // Iterate through all the windows for( itWin1 = m_allWindows.begin(); itWin1 != m_allWindows.end(); itWin1++ ) { // Get the anchors of the layout associated to the window const AncList_t &ancList1 = (*itWin1)->getActiveLayout().getAnchorList(); // Iterate through all the windows, starting with (*itWin1) for( itWin2 = itWin1; itWin2 != m_allWindows.end(); itWin2++ ) { // A window can't anchor itself... if( (*itWin2) == (*itWin1) ) continue; // Now, check for anchoring between the 2 windows const AncList_t &ancList2 = (*itWin2)->getActiveLayout().getAnchorList(); for( itAnc1 = ancList1.begin(); itAnc1 != ancList1.end(); itAnc1++ ) { for( itAnc2 = ancList2.begin(); itAnc2 != ancList2.end(); itAnc2++ ) { if( (*itAnc1)->isHanging( **itAnc2 ) ) { // (*itWin1) anchors (*itWin2) m_dependencies[*itWin1].insert( *itWin2 ); } else if( (*itAnc2)->isHanging( **itAnc1 ) ) { // (*itWin2) anchors (*itWin1) m_dependencies[*itWin2].insert( *itWin1 ); } } } } }}void WindowManager::move( TopWindow &rWindow, int left, int top ) const{ // Compute the real move offset int xOffset = left - rWindow.getLeft(); int yOffset = top - rWindow.getTop(); // Check anchoring; this can change the values of xOffset and yOffset checkAnchors( &rWindow, xOffset, yOffset ); // Move all the windows WinSet_t::const_iterator it; for( it = m_movingWindows.begin(); it != m_movingWindows.end(); it++ ) { (*it)->move( (*it)->getLeft() + xOffset, (*it)->getTop() + yOffset ); }}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::maximize( TopWindow &rWindow ){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -