hlsdk-xash3d/game_shared/vgui_slider2.cpp

440 lines
8.0 KiB
C++

//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============
//
// Purpose: New version of the slider bar
//
// $NoKeywords: $
//=============================================================================
#include "vgui_slider2.h"
#include <VGUI_InputSignal.h>
#include <VGUI_App.h>
#include <VGUI_IntChangeSignal.h>
#include <VGUI_MouseCode.h>
using namespace vgui;
namespace
{
class FooDefaultSliderSignal : public InputSignal
{
Slider2 *_slider;
public:
FooDefaultSliderSignal( Slider2 *slider )
{
_slider = slider;
}
void cursorMoved( int x, int y, Panel *panel )
{
_slider->privateCursorMoved( x, y, panel );
}
void cursorEntered( Panel *panel ) {}
void cursorExited( Panel *panel ) {}
void mouseDoublePressed( MouseCode code, Panel *panel ) {}
void mousePressed( MouseCode code, Panel *panel )
{
_slider->privateMousePressed( code, panel );
}
void mouseReleased( MouseCode code, Panel *panel )
{
_slider->privateMouseReleased( code, panel );
}
void mouseWheeled( int delta, Panel *panel ) {}
void keyPressed( KeyCode code, Panel *panel ) {}
void keyTyped( KeyCode code, Panel *panel ) {}
void keyReleased( KeyCode code, Panel *panel ) {}
void keyFocusTicked( Panel *panel ) {}
};
}
Slider2::Slider2( int x, int y, int wide, int tall, bool vertical ) : Panel( x, y, wide, tall )
{
_vertical = vertical;
_dragging = false;
_value = 0;
_range[0] = 0;
_range[1] = 299;
_rangeWindow = 0;
_rangeWindowEnabled = false;
_buttonOffset = 0;
recomputeNobPosFromValue();
addInputSignal( new FooDefaultSliderSignal( this ) );
}
void Slider2::setSize( int wide, int tall )
{
Panel::setSize( wide, tall );
recomputeNobPosFromValue();
}
bool Slider2::isVertical()
{
return _vertical;
}
void Slider2::setValue( int value )
{
int oldValue = _value;
if( value < _range[0] )
{
value = _range[0];
}
if( value > _range[1] )
{
value=_range[1];
}
_value = value;
recomputeNobPosFromValue();
if( _value != oldValue )
{
fireIntChangeSignal();
}
}
int Slider2::getValue()
{
return _value;
}
void Slider2::recomputeNobPosFromValue()
{
int wide, tall;
getPaintSize( wide, tall );
float fwide = (float)wide;
float ftall = (float)tall;
float frange = (float)(_range[1] - _range[0]);
float fvalue = (float)(_value - _range[0]);
float fper = fvalue / frange;
float frangewindow = (float)_rangeWindow;
if( frangewindow < 0 )
{
frangewindow = 0;
}
if( !_rangeWindowEnabled )
{
frangewindow = frange;
}
if( frangewindow > 0 )
{
if( _vertical )
{
float fnobsize=frangewindow;
float freepixels = ftall - fnobsize;
float firstpixel = freepixels * fper;
_nobPos[0] = (int)( firstpixel );
_nobPos[1] = (int)( firstpixel + fnobsize );
if( _nobPos[1] > tall )
{
_nobPos[0] = tall - ((int)fnobsize);
_nobPos[1] = tall;
}
}
else
{
float fnobsize = frangewindow;
float freepixels = fwide - fnobsize;
float firstpixel = freepixels * fper;
_nobPos[0]=(int)( firstpixel );
_nobPos[1]=(int)( firstpixel + fnobsize );
if( _nobPos[1] > wide )
{
_nobPos[0] = wide - ((int)fnobsize);
_nobPos[1] = wide;
}
}
}
repaint();
}
void Slider2::recomputeValueFromNobPos()
{
int wide,tall;
getPaintSize( wide, tall );
float fwide = (float)wide;
float ftall = (float)tall;
float frange = (float)(_range[1] - _range[0]);
float fvalue = (float)(_value - _range[0]);
float fnob = (float)_nobPos[0];
float frangewindow = (float)(_rangeWindow);
if( frangewindow < 0 )
{
frangewindow = 0;
}
if( !_rangeWindowEnabled )
{
frangewindow = frange;
}
if( frangewindow > 0 )
{
if( _vertical )
{
float fnobsize = frangewindow;
fvalue = frange * ( fnob / ( ftall - fnobsize ) );
}
else
{
float fnobsize = frangewindow;
fvalue = frange * ( fnob / ( fwide - fnobsize ) );
}
}
// Take care of rounding issues.
_value = (int)( fvalue+_range[0] + 0.5 );
// Clamp final result
_value = ( _value < _range[1] ) ? _value : _range[1];
}
bool Slider2::hasFullRange()
{
int wide, tall;
getPaintSize( wide, tall );
float fwide = (float)wide;
float ftall = (float)tall;
float frange = (float)( _range[1] - _range[0] );
float frangewindow = (float)( _rangeWindow );
if( frangewindow < 0 )
{
frangewindow = 0;
}
if( !_rangeWindowEnabled )
{
frangewindow = frange;
}
if( frangewindow > 0 )
{
if( _vertical )
{
if( frangewindow <= ( ftall + _buttonOffset ) )
{
return true;
}
}
else
{
if( frangewindow <= ( fwide + _buttonOffset ) )
{
return true;
}
}
}
return false;
}
void Slider2::addIntChangeSignal( IntChangeSignal *s )
{
_intChangeSignalDar.putElement(s);
}
void Slider2::fireIntChangeSignal()
{
for( int i = 0; i < _intChangeSignalDar.getCount(); i++ )
{
_intChangeSignalDar[i]->intChanged( getValue(), this );
}
}
void Slider2::paintBackground()
{
int wide, tall;
getPaintSize( wide, tall );
if( _vertical )
{
// background behind slider
drawSetColor( 40, 40, 40, 0 );
drawFilledRect( 0, 0, wide, tall );
// slider front
drawSetColor( 0, 0, 0, 0 );
drawFilledRect( 0, _nobPos[0], wide, _nobPos[1] );
// slider border
drawSetColor( 60, 60, 60, 0 );
drawFilledRect( 0, _nobPos[0], wide, _nobPos[0] + 1 ); // top
drawFilledRect( 0, _nobPos[1], wide, _nobPos[1] + 1 ); // bottom
drawFilledRect( 0, _nobPos[0] + 1, 1, _nobPos[1] ); // left
drawFilledRect( wide - 1, _nobPos[0] + 1, wide, _nobPos[1] ); // right
}
else
{
//!! doesn't work
drawSetColor( Scheme::sc_secondary3 );
drawFilledRect( 0, 0, wide, tall );
drawSetColor( Scheme::sc_black );
drawOutlinedRect( 0, 0, wide, tall );
drawSetColor( Scheme::sc_primary2 );
drawFilledRect( _nobPos[0], 0, _nobPos[1], tall );
drawSetColor( Scheme::sc_black );
drawOutlinedRect( _nobPos[0], 0, _nobPos[1], tall );
}
}
void Slider2::setRange( int min, int max )
{
if( max < min )
{
max =min;
}
if( min > max )
{
min = max;
}
_range[0] = min;
_range[1] = max;
}
void Slider2::getRange( int &min, int &max )
{
min = _range[0];
max = _range[1];
}
void Slider2::privateCursorMoved( int x, int y, Panel *panel )
{
if( !_dragging )
{
return;
}
getApp()->getCursorPos( x, y );
screenToLocal( x, y );
int wide, tall;
getPaintSize( wide, tall);
if( _vertical )
{
_nobPos[0] = _nobDragStartPos[0] + ( y - _dragStartPos[1] );
_nobPos[1] = _nobDragStartPos[1] + ( y - _dragStartPos[1] );
if( _nobPos[1] > tall )
{
_nobPos[0] = tall - ( _nobPos[1] - _nobPos[0] );
_nobPos[1] = tall;
}
if( _nobPos[0] < 0 )
{
_nobPos[1] = _nobPos[1] - _nobPos[0];
_nobPos[0] = 0;
}
}
else
{
_nobPos[0] = _nobDragStartPos[0] + ( x - _dragStartPos[0] );
_nobPos[1] = _nobDragStartPos[1] + ( x - _dragStartPos[0] );
if( _nobPos[1] > wide )
{
_nobPos[0] = wide - ( _nobPos[1] - _nobPos[0] );
_nobPos[1] = wide;
}
if( _nobPos[0] < 0 )
{
_nobPos[1] = _nobPos[1] - _nobPos[0];
_nobPos[0] = 0;
}
}
recomputeValueFromNobPos();
repaint();
fireIntChangeSignal();
}
void Slider2::privateMousePressed( MouseCode code, Panel *panel )
{
int x,y;
getApp()->getCursorPos( x, y );
screenToLocal( x, y );
if( _vertical )
{
if( ( y >= _nobPos[0] ) && ( y < _nobPos[1] ) )
{
_dragging = true;
getApp()->setMouseCapture( this );
_nobDragStartPos[0] = _nobPos[0];
_nobDragStartPos[1] = _nobPos[1];
_dragStartPos[0] = x;
_dragStartPos[1] = y;
}
}
else
{
if( ( x >= _nobPos[0] ) && ( x < _nobPos[1] ) )
{
_dragging = true;
getApp()->setMouseCapture( this );
_nobDragStartPos[0] = _nobPos[0];
_nobDragStartPos[1] = _nobPos[1];
_dragStartPos[0] = x;
_dragStartPos[1] = y;
}
}
}
void Slider2::privateMouseReleased( MouseCode code, Panel *panel )
{
_dragging = false;
getApp()->setMouseCapture( null );
}
void Slider2::getNobPos( int &min, int &max )
{
min = _nobPos[0];
max = _nobPos[1];
}
void Slider2::setRangeWindow( int rangeWindow )
{
_rangeWindow=rangeWindow;
}
void Slider2::setRangeWindowEnabled( bool state )
{
_rangeWindowEnabled=state;
}
void Slider2::setButtonOffset( int buttonOffset )
{
_buttonOffset=buttonOffset;
}