⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 window_manager.cpp

📁 video linux conference
💻 CPP
字号:
/***************************************************************************** * window_manager.cpp ***************************************************************************** * Copyright (C) 2003 VideoLAN * $Id: window_manager.cpp 10101 2005-03-02 16:47:31Z robux4 $ * * Authors: Cyril Deguet     <asmax@via.ecp.fr> *          Olivier Teuli鑢e <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., 59 Temple Place - Suite 330, Boston, MA  02111, USA. *****************************************************************************/#include "window_manager.hpp"#include "generic_layout.hpp"#include "generic_window.hpp"#include "os_factory.hpp"#include "anchor.hpp"#include "tooltip.hpp"#include "../utils/position.hpp"#include "../src/var_manager.hpp"WindowManager::WindowManager( intf_thread_t *pIntf ):    SkinObject( pIntf ), m_magnet( 0 ), m_pTooltip( 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::synchVisibility() const{    WinSet_t::const_iterator it;    for( it = m_allWindows.begin(); it != m_allWindows.end(); it++ )    {        // Show the window if it has to be visible        if( (*it)->getVisibleVar().get() )        {            (*it)->innerShow();        }    }}void WindowManager::raiseAll() const{    // Raise all the windows    WinSet_t::const_iterator it;    for( it = m_allWindows.begin(); it != m_allWindows.end(); it++ )    {        (*it)->raise();    }}void WindowManager::showAll() const{    // Show all the windows    WinSet_t::const_iterator it;    for( it = m_allWindows.begin(); it != m_allWindows.end(); it++ )    {        (*it)->show();        (*it)->setOpacity( m_alpha );    }}void WindowManager::hideAll() const{    WinSet_t::const_iterator it;    for( it = m_allWindows.begin(); it != m_allWindows.end(); it++ )    {        (*it)->hide();    }}void WindowManager::toggleOnTop(){    // Update the boolean variable    VarBoolImpl *pVarOnTop = (VarBoolImpl*)m_cVarOnTop.get();    pVarOnTop->set( !pVarOnTop->get() );    // Toggle the "on top" status    WinSet_t::const_iterator it;    for( it = m_allWindows.begin(); it != m_allWindows.end(); it++ )    {        (*it)->toggleOnTop( pVarOnTop->get() );    }}void WindowManager::buildDependSet( WinSet_t &rWinSet,                                    TopWindow *pWindow ){    // pWindow is in the set    rWinSet.insert( pWindow );    // Iterate through the anchored windows    const WinSet_t &anchored = m_dependencies[pWindow];    WinSet_t::const_iterator iter;    for( iter = anchored.begin(); iter != anchored.end(); iter++ )    {        // Check that the window isn't already in the set before adding it        if( rWinSet.find( *iter ) == rWinSet.end() )        {            buildDependSet( rWinSet, *iter );        }    }}void WindowManager::checkAnchors( TopWindow *pWindow,                                  int &xOffset, int &yOffset ) const{    WinSet_t::const_iterator itMov, itSta;    AncList_t::const_iterator itAncMov, itAncSta;    // Check magnetism with screen edges first (actually it is the work area)    Rect workArea = OSFactory::instance( getIntf() )->getWorkArea();    // Iterate through the moving windows    for( itMov = m_movingWindows.begin();         itMov != m_movingWindows.end(); itMov++ )    {        int newLeft = (*itMov)->getLeft() + xOffset;        int newTop = (*itMov)->getTop() + yOffset;        if( newLeft > workArea.getLeft() - m_magnet &&            newLeft < workArea.getLeft() + m_magnet )        {            xOffset = workArea.getLeft() - (*itMov)->getLeft();        }        if( newTop > workArea.getTop() - m_magnet &&            newTop < workArea.getTop() + m_magnet )        {            yOffset = workArea.getTop() - (*itMov)->getTop();        }        if( newLeft + (*itMov)->getWidth() > workArea.getRight() - m_magnet &&            newLeft + (*itMov)->getWidth() < workArea.getRight() + m_magnet )        {            xOffset = workArea.getRight() - (*itMov)->getLeft()                      - (*itMov)->getWidth();        }        if( newTop + (*itMov)->getHeight() > workArea.getBottom() - m_magnet &&            newTop + (*itMov)->getHeight() <  workArea.getBottom() + m_magnet )        {            yOffset =  workArea.getBottom() - (*itMov)->getTop()                       - (*itMov)->getHeight();        }    }    // Iterate through the moving windows    for( itMov = m_movingWindows.begin();         itMov != m_movingWindows.end(); itMov++ )    {        // Skip the invisible windows        if( ! (*itMov)->getVisibleVar().get() )        {            continue;        }        // Get the anchors in the main layout of this moving window        const AncList_t &movAnchors =            (*itMov)->getActiveLayout().getAnchorList();        // Iterate through the static windows        for( itSta = m_allWindows.begin();             itSta != m_allWindows.end(); itSta++ )        {            // Skip the moving windows and the invisible ones            if( m_movingWindows.find( (*itSta) ) != m_movingWindows.end() ||                ! (*itSta)->getVisibleVar().get() )            {                continue;            }            // Get the anchors in the main layout of this static window            const AncList_t &staAnchors =                (*itSta)->getActiveLayout().getAnchorList();            // Check if there is an anchoring between one of the movAnchors            // and one of the staAnchors            for( itAncMov = movAnchors.begin();                 itAncMov != movAnchors.end(); itAncMov++ )            {                for( itAncSta = staAnchors.begin();                     itAncSta != staAnchors.end(); itAncSta++ )                {                    if( (*itAncSta)->canHang( **itAncMov, xOffset, yOffset ) )                    {                        // We have found an anchoring!                        // There is nothing to do here, since xOffset and                        // yOffset are automatically modified by canHang()                        // Don't check the other anchors, one is enough...                        return;                    }                    else                    {                        // Temporary variables                        int xOffsetTemp = -xOffset;                        int yOffsetTemp = -yOffset;                        if( (*itAncMov)->canHang( **itAncSta, xOffsetTemp,                                                  yOffsetTemp ) )                        {                            // We have found an anchoring!                            // xOffsetTemp and yOffsetTemp have been updated,                            // we just need to change xOffset and yOffset                            xOffset = -xOffsetTemp;                            yOffset = -yOffsetTemp;                            // Don't check the other anchors, one is enough...                            return;                        }                    }                }            }        }    }}void WindowManager::createTooltip( const GenericFont &rTipFont ){    // Create the tooltip window    if( !m_pTooltip )    {        m_pTooltip = new Tooltip( getIntf(), rTipFont, 500 );    }    else    {        msg_Warn( getIntf(), "Tooltip already created!");    }}void WindowManager::showTooltip(){    if( m_pTooltip )    {        m_pTooltip->show();    }}void WindowManager::hideTooltip(){    if( m_pTooltip )    {        m_pTooltip->hide();    }}void WindowManager::addLayout( TopWindow &rWindow, GenericLayout &rLayout ){    rWindow.setActiveLayout( &rLayout );}void WindowManager::setActiveLayout( TopWindow &rWindow,                                     GenericLayout &rLayout ){    rWindow.setActiveLayout( &rLayout );    // Rebuild the dependencies    stopMove();}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -