<commit_before>/*****************************************************************************
 * generic_layout.cpp
 *****************************************************************************
 * Copyright (C) 2003 the VideoLAN team
 * $Id$
 *
 * Authors: <NAME>     <<EMAIL>>
 *          <NAME> <<EMAIL>>
 *
 * 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 "generic_layout.hpp"
#include "top_window.hpp"
#include "os_factory.hpp"
#include "os_graphics.hpp"
#include "var_manager.hpp"
#include "../controls/ctrl_generic.hpp"
#include "../controls/ctrl_video.hpp"
#include "../utils/var_bool.hpp"


GenericLayout::GenericLayout( intf_thread_t *pIntf, int width, int height,
                              int minWidth, int maxWidth, int minHeight,
                              int maxHeight ):
    SkinObject( pIntf ), m_pWindow( NULL ), m_width( width ),
    m_height( height ), m_minWidth( minWidth ), m_maxWidth( maxWidth ),
    m_minHeight( minHeight ), m_maxHeight( maxHeight ), m_pVideoControl( NULL ),
    m_visible( false ), m_pVarActive( NULL )
{
    // Get the OSFactory
    OSFactory *pOsFactory = OSFactory::instance( getIntf() );
    // Create the graphics buffer
    m_pImage = pOsFactory->createOSGraphics( width, height );

    // Create the "active layout" variable and register it in the manager
    m_pVarActive = new VarBoolImpl( pIntf );
    VarManager::instance( pIntf )->registerVar( VariablePtr( m_pVarActive ) );
}


GenericLayout::~GenericLayout()
{
    if( m_pImage )
    {
        delete m_pImage;
    }
}


void GenericLayout::setWindow( TopWindow *pWindow )
{
    m_pWindow = pWindow;
}


void GenericLayout::onControlCapture( const CtrlGeneric &rCtrl )
{
    // Just forward the request to the window
    TopWindow *pWindow = getWindow();
    if( pWindow )
    {
        pWindow->onControlCapture( rCtrl );
    }
}


void GenericLayout::onControlRelease( const CtrlGeneric &rCtrl )
{
    // Just forward the request to the window
    TopWindow *pWindow = getWindow();
    if( pWindow )
    {
        pWindow->onControlRelease( rCtrl );
    }
}


void GenericLayout::addControl( CtrlGeneric *pControl,
                                const Position &rPosition, int layer )
{
    if( pControl )
    {
        // Associate this layout to the control
        pControl->setLayout( this, rPosition );

        // Draw the control
        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;
        for( it = m_controlList.begin(); it != m_controlList.end(); it++ )
        {
            if( layer < (*it).m_layer )
            {
                m_controlList.insert( it, LayeredControl( pControl, layer ) );
                break;
            }
        }
        // If this control is in front of all the previous ones
        if( it == m_controlList.end() )
        {
            m_controlList.push_back( LayeredControl( pControl, layer ) );
        }

        // Check if it is a video control
        if( pControl->getType() == "video" )
        {
            m_pVideoControl = (CtrlVideo*)pControl;
        }
    }
    else
    {
        msg_Dbg( getIntf(), "adding NULL control in the layout" );
    }
}


const list<LayeredControl> &GenericLayout::getControlList() const
{
    return m_controlList;
}


void GenericLayout::onControlUpdate( const CtrlGeneric &rCtrl,
                                     int width, int height,
                                     int xOffSet, int yOffSet )
{
    // The size is not valid, refresh the whole layout
    if( width <= 0 || height <= 0 )
    {
        refreshAll();
        return;
    }

    const Position *pPos = rCtrl.getPosition();
    if( pPos )
    {
        refreshRect( pPos->getLeft() + xOffSet,
                     pPos->getTop() + yOffSet,
                     width, height );
    }
}


void GenericLayout::resize( int width, int height )
{
    // Update the window size
    m_width = width;
    m_height = height;

    // Recreate a new image
    if( m_pImage )
    {
        delete m_pImage;
        OSFactory *pOsFactory = OSFactory::instance( getIntf() );
        m_pImage = pOsFactory->createOSGraphics( width, height );
    }

    // Notify all the controls that the size has changed and redraw them
    list<LayeredControl>::const_iterator iter;
    for( iter = m_controlList.begin(); iter != m_controlList.end(); iter++ )
    {
        iter->m_pControl->onResize();
    }

    // Resize and refresh the associated window
    TopWindow *pWindow = getWindow();
    if( pWindow )
    {
        // Resize the window
        pWindow->resize( width, height );
        refreshAll();
        // Change the shape of the window and redraw it
        pWindow->updateShape();
        refreshAll();
    }
}


void GenericLayout::refreshAll()
{
    refreshRect( 0, 0, m_width, m_height );
}


void GenericLayout::refreshRect( int x, int y, int width, int height )
{
    // Do nothing if the layout is hidden
    if( !m_visible )
        return;

    // Draw all the controls of the layout
    list<LayeredControl>::const_iterator iter;
    list<LayeredControl>::const_iterator iterVideo = m_controlList.end();
    for( iter = m_controlList.begin(); iter != m_controlList.end(); iter++ )
    {
        CtrlGeneric *pCtrl = (*iter).m_pControl;
        const Position *pPos = pCtrl->getPosition();
        if( pPos && pCtrl->isVisible() )
        {
            pCtrl->draw( *m_pImage, pPos->getLeft(), pPos->getTop() );
        }
    }

    // Refresh the associated window
    TopWindow *pWindow = getWindow();
    if( pWindow )
    {
        // Check boundaries
        if( x < 0 )
            x = 0;
        if( y < 0)
            y = 0;
        if( x + width > m_width )
            width = m_width - x;
        if( y + height > m_height )
            height = m_height - y;

        // Refresh the window... but do not paint on a video control!
        if( !m_pVideoControl )
        {
            // No video control, we can safely repaint the rectangle
            pWindow->refresh( x, y, width, height );
        }
        else
        {
            // Bad luck, there is a video control somewhere (not necessarily<commit_msg> * skins2/src/generic_layout.cpp: refresh the area of the Video control when it    is not visible<commit_after>/*****************************************************************************
 * generic_layout.cpp
 *****************************************************************************
 * Copyright (C) 2003 the VideoLAN team
 * $Id$
 *
 * Authors: <NAME>     <<EMAIL>>
 *          <NAME> <<EMAIL>>
 *
 * 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 "generic_layout.hpp"
#include "top_window.hpp"
#include "os_factory.hpp"
#include "os_graphics.hpp"
#include "var_manager.hpp"
#include "../controls/ctrl_generic.hpp"
#include "../controls/ctrl_video.hpp"
#include "../utils/var_bool.hpp"


GenericLayout::GenericLayout( intf_thread_t *pIntf, int width, int height,
                              int minWidth, int maxWidth, int minHeight,
                              int maxHeight ):
    SkinObject( pIntf ), m_pWindow( NULL ), m_width( width ),
    m_height( height ), m_minWidth( minWidth ), m_maxWidth( maxWidth ),
    m_minHeight( minHeight ), m_maxHeight( maxHeight ), m_pVideoControl( NULL ),
    m_visible( false ), m_pVarActive( NULL )
{
    // Get the OSFactory
    OSFactory *pOsFactory = OSFactory::instance( getIntf() );
    // Create the graphics buffer
    m_pImage = pOsFactory->createOSGraphics( width, height );

    // Create the "active layout" variable and register it in the manager
    m_pVarActive = new VarBoolImpl( pIntf );
    VarManager::instance( pIntf )->registerVar( VariablePtr( m_pVarActive ) );
}


GenericLayout::~GenericLayout()
{
    if( m_pImage )
    {
        delete m_pImage;
    }
}


void GenericLayout::setWindow( TopWindow *pWindow )
{
    m_pWindow = pWindow;
}


void GenericLayout::onControlCapture( const CtrlGeneric &rCtrl )
{
    // Just forward the request to the window
    TopWindow *pWindow = getWindow();
    if( pWindow )
    {
        pWindow->onControlCapture( rCtrl );
    }
}


void GenericLayout::onControlRelease( const CtrlGeneric &rCtrl )
{
    // Just forward the request to the window
    TopWindow *pWindow = getWindow();
    if( pWindow )
    {
        pWindow->onControlRelease( rCtrl );
    }
}


void GenericLayout::addControl( CtrlGeneric *pControl,
                                const Position &rPosition, int layer )
{
    if( pControl )
    {
        // Associate this layout to the control
        pControl->setLayout( this, rPosition );

        // Draw the control
        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;
        for( it = m_controlList.begin(); it != m_controlList.end(); it++ )
        {
            if( layer < (*it).m_layer )
            {
                m_controlList.insert( it, LayeredControl( pControl, layer ) );
                break;
            }
        }
        // If this control is in front of all the previous ones
        if( it == m_controlList.end() )
        {
            m_controlList.push_back( LayeredControl( pControl, layer ) );
        }

        // Check if it is a video control
        if( pControl->getType() == "video" )
        {
            m_pVideoControl = (CtrlVideo*)pControl;
        }
    }
    else
    {
        msg_Dbg( getIntf(), "adding NULL control in the layout" );
    }
}


const list<LayeredControl> &GenericLayout::getControlList() const
{
    return m_controlList;
}


void GenericLayout::onControlUpdate( const CtrlGeneric &rCtrl,
                                     int width, int height,
                                     int xOffSet, int yOffSet )
{
    // The size is not valid, refresh the whole layout
    if( width <= 0 || height <= 0 )
    {
        refreshAll();
        return;
    }

    const Position *pPos = rCtrl.getPosition();
    if( pPos )
    {
        refreshRect( pPos->getLeft() + xOffSet,
                     pPos->getTop() + yOffSet,
                     width, height );
    }
}


void GenericLayout::resize( int width, int height )
{
    // Update the window size
    m_width = width;
    m_height = height;

    // Recreate a new image
    if( m_pImage )
    {
        delete m_pImage;
        OSFactory *pOsFactory = OSFactory::instance( getIntf() );
        m_pImage = pOsFactory->createOSGraphics( width, height );
    }

    // Notify all the controls that the size has changed and redraw them
    list<LayeredControl>::const_iterator iter;
    for( iter = m_controlList.begin(); iter != m_controlList.end(); iter++ )
    {
        iter->m_pControl->onResize();
    }

    // Resize and refresh the associated window
    TopWindow *pWindow = getWindow();
    if( pWindow )
    {
        // Resize the window
        pWindow->resize( width, height );
        refreshAll();
        // Change the shape of the window and redraw it
        pWindow->updateShape();
        refreshAll();
    }
}


void GenericLayout::refreshAll()
{
    refreshRect( 0, 0, m_width, m_height );
}


void GenericLayout::refreshRect( int x, int y, int width, int height )
{
    // Do nothing if the layout is hidden
    if( !m_visible )
        return;

    // Draw all the controls of the layout
    list<LayeredControl>::const_iterator iter;
    list<LayeredControl>::const_iterator iterVideo = m_controlList.end();
    for( iter = m_controlList.begin(); iter != m_controlList.end(); iter++ )
    {
        CtrlGeneric *pCtrl = (*iter).m_pControl;
        const Position *pPos = pCtrl->getPosition();
        if( pPos && pCtrl->isVisible() )
        {
            pCtrl->draw( *m_pImage, pPos->getLeft(), pPos->getTop() );
        }
    }

    // Refresh the associated window
    TopWindow *pWindow = getWindow();
    if( pWindow )
    {
        // Check boundaries
        if( x < 0 )
            x = 0;
        if( y < 0)
            y = 0;
        if( x + width > m_width )
            width = m_width - x;
        if( y + height > m_height )
            height = m_height - y;

        // Refresh the window... but do not paint on a visible video control!
        if( !m_pVideoControl || !m_pVideoControl->isVisible() )
        {
            // No video control, we can safely repaint the rectangle
            pWindow->refresh( x, y, width, height );
        }
        else
        {
            // Bad luck, there is a video control somewhere (not necessarily
{'fraction_non_alphanumeric': 0.13418845584607794, 'fraction_numerical': 0.003453379378391712, 'mean_word_length': 2.3380381086803106, 'pattern_counts': {'":': 0, '<': 35, '<?xml version=': 0, '>': 70, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 12, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3421087', 'n_tokens_mistral': 4104, 'n_tokens_neox': 3968, 'n_words': 1256}