slider.cpp

来自「VLC媒体播放程序」· C++ 代码 · 共 416 行

CPP
416
字号
/***************************************************************************** * slider.cpp: Slider control ***************************************************************************** * Copyright (C) 2003 VideoLAN * $Id: slider.cpp,v 1.10 2003/05/02 15:53:32 gbazin Exp $ * * Authors: Olivier Teuli鑢e <ipkiss@via.ecp.fr> *          Emmanuel Puig    <karibu@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. *****************************************************************************///--- GENERAL ---------------------------------------------------------------#include <math.h>#include <stdio.h>//--- VLC -------------------------------------------------------------------#include <vlc/intf.h>//--- SKIN ------------------------------------------------------------------#include "../os_api.h"#include "../src/bitmap.h"#include "../src/bezier.h"#include "../src/banks.h"#include "../src/graphics.h"#include "../os_graphics.h"#include "generic.h"#include "slider.h"#include "../src/event.h"#include "../src/theme.h"#include "../src/window.h"#include "../src/skin_common.h"//---------------------------------------------------------------------------// Control Slider//---------------------------------------------------------------------------ControlSlider::ControlSlider( string id, bool visible, string type,    string cursorUp, string cursorDown, double *ptx, double *pty, int nb,    string tooltiptext, string help, SkinWindow *Parent )    : GenericControl( id, visible, help, Parent ){    Type             = type;    Left             = 0;    Top              = 0;    State            = 1;    Value            = 0;    Selected         = false;    Enabled          = false;    this->cursorUp   = cursorUp;    this->cursorDown = cursorDown;    Curve            = new Bezier( ptx, pty, nb );    UpdateEvent      = NULL;    SliderRange      = SLIDER_RANGE;    LastRefreshTime  = OSAPI_GetTime();    // Tool tip text    BaseToolTipText = tooltiptext;    FullToolTipText = BaseToolTipText;}//---------------------------------------------------------------------------ControlSlider::~ControlSlider(){    delete[] CursorX;    delete[] CursorY;    delete (OSRegion *)HitRgn;}//---------------------------------------------------------------------------void ControlSlider::Init(){    int i;    // Get bitmap from list    Img    = new (Bitmap *[2]);    Img[0] = p_intf->p_sys->p_theme->BmpBank->Get( cursorUp );    Img[1] = p_intf->p_sys->p_theme->BmpBank->Get( cursorDown );    // Get images sizes    Img[0]->GetSize( CWidth, CHeight );    // Computing slider curve : get points    MaxValue = Curve->GetNumOfDifferentPoints();    CursorX  = new int[MaxValue + 1];    CursorY  = new int[MaxValue + 1];    Curve->GetDifferentPoints( CursorX, CursorY, -CWidth / 2, -CHeight / 2 );        // Search for size value        Left   = CursorX[0];        Top    = CursorY[0];        Width  = CursorX[0];        Height = CursorY[0];        for( i = 1; i <= MaxValue; i++ )        {            if( CursorX[i] < Left )                Left = CursorX[i];            if( CursorY[i] < Top )                Top  = CursorY[i];            if( CursorX[i] > Width )                Width = CursorX[i];            if( CursorY[i] > Height )                Height  = CursorY[i];        }        Width  += CWidth  - Left;        Height += CHeight - Top;        // Curve is no more needed so delete it        delete Curve;    // Create Hit Region    HitRgn = (SkinRegion *)new OSRegion;    // Create slider hit region and move cursor inside control    for( i = 0; i <= MaxValue; i++ )    {        HitRgn->AddElipse( CursorX[i], CursorY[i], CWidth, CHeight );        CursorX[i] -= Left;        CursorY[i] -= Top;    }    // Select type of slider    if( Type == "time" )    {        Enabled = false;        UpdateEvent = p_intf->p_sys->p_theme->EvtBank->Get( "time" );    }    else if( Type == "volume" )    {        Enabled = true;        UpdateEvent = p_intf->p_sys->p_theme->EvtBank->Get( "volume_refresh" );    }    else    {        Enabled = false;        UpdateEvent = p_intf->p_sys->p_theme->EvtBank->Get( "none" );    }}//---------------------------------------------------------------------------bool ControlSlider::ProcessEvent( Event *evt ){    unsigned int msg = evt->GetMessage();    unsigned int p1  = evt->GetParam1();    int          p2  = evt->GetParam2();    switch( msg )    {        case CTRL_ENABLED:            Enable( (Event*)p1, (bool)p2 );            return true;        case CTRL_SET_SLIDER:            if( UpdateEvent->IsEqual( (Event*)p1 ) )            {                SetCursorPosition( (long)p2 );            }            return true;    }    return false;}//---------------------------------------------------------------------------void ControlSlider::MoveRelative( int xOff, int yOff ){    Left += xOff;    Top  += yOff;    HitRgn->Move( xOff, yOff );}//---------------------------------------------------------------------------void ControlSlider::SetCursorPosition( long Pos ){    if( Pos < 0 )        Pos = 0;    if( Pos > SliderRange )        Pos = SliderRange;    if( !Selected )    {        if( SliderRange == 0 )            MoveCursor( 0 );        else            MoveCursor( Pos * MaxValue / SliderRange );    }}//---------------------------------------------------------------------------long ControlSlider::GetCursorPosition(){    return SliderRange * Value / MaxValue;}//---------------------------------------------------------------------------void ControlSlider::MoveCursor( int newValue ){    int X, Y, W, H;    int OldValue = Value;    Value = newValue;    if( OldValue != Value )    {        X = (CursorX[Value] > CursorX[OldValue])            ? Left + CursorX[OldValue] : Left + CursorX[Value];        Y = (CursorY[Value] > CursorY[OldValue])            ? Top  + CursorY[OldValue] : Top  + CursorY[Value];        W = (CursorX[Value] > CursorX[OldValue])            ? CursorX[Value] - CursorX[OldValue] + CWidth            : CursorX[OldValue] - CursorX[Value] + CWidth;        H = (CursorY[Value] > CursorY[OldValue])            ? CursorY[Value] - CursorY[OldValue] + CHeight            : CursorY[OldValue] - CursorY[Value] + CHeight;        if( 2 * CWidth * CHeight < W * H )        {            ParentWindow->Refresh( Left + CursorX[OldValue],                Top + CursorY[OldValue], CWidth, CHeight );            ParentWindow->Refresh( Left + CursorX[Value],                Top + CursorY[Value], CWidth, CHeight );        }        else        {            ParentWindow->Refresh( X, Y, W, H );        }        // Change tooltip        if( BaseToolTipText != "none" )        {            char *percent = new char[6];            sprintf( percent, "%i %%", Value * 100 / MaxValue );            FullToolTipText = BaseToolTipText + " - " + (string)percent;            delete[] percent;        }    }}//---------------------------------------------------------------------------void ControlSlider::Draw( int x, int y, int w, int h, Graphics *dest ){    if( !Visible )        return;    int xI, yI, wI, hI;    if( GetIntersectRgn( x, y, w, h, Left+CursorX[Value], Top+CursorY[Value],                         CWidth, CHeight, xI, yI, wI, hI ) )    {        Img[1 - State]->DrawBitmap( xI - Left - CursorX[Value],            yI - Top - CursorY[Value], wI, hI, xI - x, yI - y, dest );    }}//---------------------------------------------------------------------------bool ControlSlider::MouseUp( int x, int y, int button ){    State = 1;    if( Enabled && Selected )    {        Selected = false;        ParentWindow->Refresh( Left + CursorX[Value],            Top + CursorY[Value], CWidth, CHeight );        UpdateEvent->SetParam2( GetCursorPosition() );        UpdateEvent->SendEvent();    }    return false;}//---------------------------------------------------------------------------bool ControlSlider::MouseDown( int x, int y, int button ){    if( !Enabled )        return false;    // If hit into cursor or indide active slider region    if( HitRgn->Hit( x, y ) && button == 1 )    {        State = 0;        Selected = true;        ParentWindow->Refresh( Left + CursorX[Value],            Top + CursorY[Value], CWidth, CHeight );        MoveCursor( FindNearestPoint( x, y ) );        UpdateEvent->SetParam2( GetCursorPosition() );        UpdateEvent->SendEvent();        return true;    }    return false;}//---------------------------------------------------------------------------bool ControlSlider::MouseMove( int x, int y, int button ){    if( !Enabled || !Selected || !button )        return false;    MoveCursor( FindNearestPoint( x, y ) );    // Refresh value if time ellapsed since last refresh is more than 200 ms    int time = OSAPI_GetTime();    if( time > LastRefreshTime + 250 )    {        UpdateEvent->SetParam2( GetCursorPosition() );        UpdateEvent->SendEvent();        LastRefreshTime = time;    }    return true;}//---------------------------------------------------------------------------bool ControlSlider::MouseOver( int x, int y ){    if( HitRgn->Hit( x, y ) )        return true;    else        return false;}//---------------------------------------------------------------------------bool ControlSlider::MouseScroll( int x, int y, int direction ){    if( !Enabled || !MouseOver( x, y ) )        return false;    int val = Value;    switch( direction )    {        case MOUSE_SCROLL_DOWN:            if( val > 0 ) val--;            break;        case MOUSE_SCROLL_UP:            if( val < MaxValue ) val++;            break;    }    MoveCursor( val );    UpdateEvent->SetParam2( GetCursorPosition() );    UpdateEvent->SendEvent();    return true;}//---------------------------------------------------------------------------bool ControlSlider::ToolTipTest( int x, int y ){    if( MouseOver( x, y ) )    {        if( BaseToolTipText == "none" )        {            ParentWindow->ChangeToolTipText( BaseToolTipText );        }        else        {            ParentWindow->ChangeToolTipText( FullToolTipText );        }        return true;    }    return false;}//---------------------------------------------------------------------------void ControlSlider::ChangeSliderRange( int NewRange ){    if( NewRange == SliderRange )        return;    SliderRange = NewRange;    int Pos = GetCursorPosition();    SetCursorPosition( Pos );}//---------------------------------------------------------------------------void ControlSlider::Enable( Event *event, bool enabled ){    if( !UpdateEvent->IsEqual( event ) )        return;    if( enabled && !Enabled )    {        Enabled = true;        ParentWindow->Refresh( Left, Top, Width, Height );    }    else if( !enabled && Enabled )    {        Enabled = false;        ParentWindow->Refresh( Left, Top, Width, Height );    }}//---------------------------------------------------------------------------int ControlSlider::FindNearestPoint( int x, int y ){    int i, wx, wy;    double D;    double minD = 50;    int RefValue = Value;    // Move point inside control    OSAPI_GetMousePos( x, y );              // This is used to avoid bug with                                            // negative values    ParentWindow->GetPos( wx, wy );    x += -wx - Left - CWidth  / 2;    y += -wy - Top  - CHeight / 2;    // Search nearest point    for( i = 0; i <= MaxValue; i++ )    {        D = sqrt( ( CursorX[i] - x ) * ( CursorX[i] - x ) +                  ( CursorY[i] - y ) * ( CursorY[i] - y ) );        if( D < minD )        {            minD = D;            RefValue = i;        }    }    return RefValue;}//---------------------------------------------------------------------------

⌨️ 快捷键说明

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