You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
953 lines
24 KiB
953 lines
24 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: |
|
// |
|
// $NoKeywords: $ |
|
//=============================================================================// |
|
|
|
#include <stdio.h> |
|
#define PROTECTED_THINGS_DISABLE |
|
|
|
#include <vgui/MouseCode.h> |
|
#include <KeyValues.h> |
|
#include <vgui/IBorder.h> |
|
#include <vgui/IInput.h> |
|
#include <vgui/ISystem.h> |
|
#include <vgui/IScheme.h> |
|
#include <vgui/ISurface.h> |
|
#include <vgui/ILocalize.h> |
|
|
|
#include <vgui_controls/Slider.h> |
|
#include <vgui_controls/Controls.h> |
|
#include <vgui_controls/TextImage.h> |
|
|
|
// memdbgon must be the last include file in a .cpp file!!! |
|
#include <tier0/memdbgon.h> |
|
|
|
using namespace vgui; |
|
|
|
DECLARE_BUILD_FACTORY( Slider ); |
|
|
|
static const float NOB_SIZE = 8.0f; |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Create a slider bar with ticks underneath it |
|
//----------------------------------------------------------------------------- |
|
Slider::Slider(Panel *parent, const char *panelName ) : BaseClass(parent, panelName) |
|
{ |
|
m_bIsDragOnRepositionNob = false; |
|
_dragging = false; |
|
_value = 0; |
|
_range[0] = 0; |
|
_range[1] = 0; |
|
_buttonOffset = 0; |
|
_sliderBorder = NULL; |
|
_insetBorder = NULL; |
|
m_nNumTicks = 10; |
|
_leftCaption = NULL; |
|
_rightCaption = NULL; |
|
|
|
_subrange[ 0 ] = 0; |
|
_subrange[ 1 ] = 0; |
|
m_bUseSubRange = false; |
|
m_bInverted = false; |
|
|
|
SetThumbWidth( 8 ); |
|
RecomputeNobPosFromValue(); |
|
AddActionSignalTarget(this); |
|
SetBlockDragChaining( true ); |
|
} |
|
|
|
// This allows the slider to behave like it's larger than what's actually being drawn |
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Input : bEnable - |
|
// 0 - |
|
// 100 - |
|
//----------------------------------------------------------------------------- |
|
void Slider::SetSliderThumbSubRange( bool bEnable, int nMin /*= 0*/, int nMax /*= 100*/ ) |
|
{ |
|
m_bUseSubRange = bEnable; |
|
_subrange[ 0 ] = nMin; |
|
_subrange[ 1 ] = nMax; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Set the size of the slider bar. |
|
// Warning less than 30 pixels tall and everything probably won't fit. |
|
//----------------------------------------------------------------------------- |
|
void Slider::OnSizeChanged(int wide,int tall) |
|
{ |
|
BaseClass::OnSizeChanged(wide,tall); |
|
|
|
RecomputeNobPosFromValue(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Set the value of the slider to one of the ticks. |
|
//----------------------------------------------------------------------------- |
|
void Slider::SetValue(int value, bool bTriggerChangeMessage) |
|
{ |
|
int oldValue=_value; |
|
|
|
if ( _range[0] < _range[1] ) |
|
{ |
|
if(value<_range[0]) |
|
{ |
|
value=_range[0]; |
|
} |
|
if(value>_range[1]) |
|
{ |
|
value=_range[1]; |
|
} |
|
} |
|
else |
|
{ |
|
if(value<_range[1]) |
|
{ |
|
value=_range[1]; |
|
} |
|
if(value>_range[0]) |
|
{ |
|
value=_range[0]; |
|
} |
|
} |
|
|
|
_value = value; |
|
|
|
RecomputeNobPosFromValue(); |
|
|
|
if (_value != oldValue && bTriggerChangeMessage) |
|
{ |
|
SendSliderMovedMessage(); |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Return the value of the slider |
|
//----------------------------------------------------------------------------- |
|
int Slider::GetValue() |
|
{ |
|
return _value; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Layout the slider before drawing it on screen. |
|
//----------------------------------------------------------------------------- |
|
void Slider::PerformLayout() |
|
{ |
|
BaseClass::PerformLayout(); |
|
RecomputeNobPosFromValue(); |
|
|
|
if (_leftCaption) |
|
{ |
|
_leftCaption->ResizeImageToContent(); |
|
} |
|
if (_rightCaption) |
|
{ |
|
_rightCaption->ResizeImageToContent(); |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Move the nob on the slider in response to changing its value. |
|
//----------------------------------------------------------------------------- |
|
void Slider::RecomputeNobPosFromValue() |
|
{ |
|
//int wide,tall; |
|
//GetPaintSize(wide,tall); |
|
int x, y, wide, tall; |
|
GetTrackRect( x, y, wide, tall ); |
|
|
|
float usevalue = _value; |
|
int *userange = &_range[ 0 ]; |
|
if ( m_bUseSubRange ) |
|
{ |
|
userange = &_subrange[ 0 ]; |
|
usevalue = clamp( _value, _subrange[ 0 ], _subrange[ 1 ] ); |
|
} |
|
|
|
float fwide=(float)wide; |
|
float frange=(float)(userange[1] -userange[0]); |
|
float fvalue=(float)(usevalue -userange[0]); |
|
float fper = (frange != 0.0f) ? fvalue / frange : 0.0f; |
|
|
|
if ( m_bInverted ) |
|
fper = 1.0f - fper; |
|
|
|
float freepixels = fwide - _nobSize; |
|
float leftpixel = (float)x; |
|
float firstpixel = leftpixel + freepixels * fper + 0.5f; |
|
|
|
_nobPos[0]=(int)( firstpixel ); |
|
_nobPos[1]=(int)( firstpixel + _nobSize ); |
|
|
|
|
|
int rightEdge = x + wide; |
|
|
|
if(_nobPos[1]> rightEdge ) |
|
{ |
|
_nobPos[0]=rightEdge-((int)_nobSize); |
|
_nobPos[1]=rightEdge; |
|
} |
|
|
|
Repaint(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Sync the slider's value up with the nob's position. |
|
//----------------------------------------------------------------------------- |
|
void Slider::RecomputeValueFromNobPos() |
|
{ |
|
int value = EstimateValueAtPos( _nobPos[ 0 ], 0 ); |
|
SetValue( value ); |
|
} |
|
|
|
int Slider::EstimateValueAtPos( int localMouseX, int /*localMouseY*/ ) |
|
{ |
|
int x, y, wide, tall; |
|
GetTrackRect( x, y, wide, tall ); |
|
|
|
int *userange = &_range[ 0 ]; |
|
if ( m_bUseSubRange ) |
|
{ |
|
userange = &_subrange[ 0 ]; |
|
} |
|
|
|
float fwide = (float)wide; |
|
float fvalue = (float)( _value - userange[0] ); |
|
float fnob = (float)( localMouseX - x ); |
|
float freepixels = fwide - _nobSize; |
|
|
|
// Map into reduced range |
|
fvalue = freepixels != 0.0f ? fnob / freepixels : 0.0f; |
|
|
|
return (int) (RemapVal( fvalue, 0.0, 1.0, userange[0], userange[1] )); |
|
} |
|
|
|
void Slider::SetInverted( bool bInverted ) |
|
{ |
|
m_bInverted = bInverted; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Send a message to interested parties when the slider moves |
|
//----------------------------------------------------------------------------- |
|
void Slider::SendSliderMovedMessage() |
|
{ |
|
// send a changed message |
|
KeyValues *pParams = new KeyValues("SliderMoved", "position", _value); |
|
pParams->SetPtr( "panel", this ); |
|
PostActionSignal( pParams ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Send a message to interested parties when the user begins dragging the slider |
|
//----------------------------------------------------------------------------- |
|
void Slider::SendSliderDragStartMessage() |
|
{ |
|
// send a message |
|
KeyValues *pParams = new KeyValues("SliderDragStart", "position", _value); |
|
pParams->SetPtr( "panel", this ); |
|
PostActionSignal( pParams ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Send a message to interested parties when the user ends dragging the slider |
|
//----------------------------------------------------------------------------- |
|
void Slider::SendSliderDragEndMessage() |
|
{ |
|
// send a message |
|
KeyValues *pParams = new KeyValues("SliderDragEnd", "position", _value); |
|
pParams->SetPtr( "panel", this ); |
|
PostActionSignal( pParams ); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void Slider::ApplySchemeSettings(IScheme *pScheme) |
|
{ |
|
BaseClass::ApplySchemeSettings(pScheme); |
|
|
|
SetFgColor(GetSchemeColor("Slider.NobColor", pScheme)); |
|
// this line is useful for debugging |
|
//SetBgColor(GetSchemeColor("0 0 0 255")); |
|
|
|
m_TickColor = pScheme->GetColor( "Slider.TextColor", GetFgColor() ); |
|
m_TrackColor = pScheme->GetColor( "Slider.TrackColor", GetFgColor() ); |
|
|
|
#ifdef _X360 |
|
m_DepressedBgColor = GetSchemeColor("Slider.NobFocusColor", pScheme); |
|
#endif |
|
|
|
m_DisabledTextColor1 = pScheme->GetColor( "Slider.DisabledTextColor1", GetFgColor() ); |
|
m_DisabledTextColor2 = pScheme->GetColor( "Slider.DisabledTextColor2", GetFgColor() ); |
|
|
|
_sliderBorder = pScheme->GetBorder("ButtonBorder"); |
|
_insetBorder = pScheme->GetBorder("ButtonDepressedBorder"); |
|
|
|
if ( _leftCaption ) |
|
{ |
|
_leftCaption->SetFont(pScheme->GetFont("DefaultVerySmall", IsProportional() )); |
|
} |
|
|
|
if ( _rightCaption ) |
|
{ |
|
_rightCaption->SetFont(pScheme->GetFont("DefaultVerySmall", IsProportional() )); |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void Slider::GetSettings(KeyValues *outResourceData) |
|
{ |
|
BaseClass::GetSettings(outResourceData); |
|
|
|
char buf[256]; |
|
if (_leftCaption) |
|
{ |
|
_leftCaption->GetUnlocalizedText(buf, sizeof(buf)); |
|
outResourceData->SetString("leftText", buf); |
|
} |
|
|
|
if (_rightCaption) |
|
{ |
|
_rightCaption->GetUnlocalizedText(buf, sizeof(buf)); |
|
outResourceData->SetString("rightText", buf); |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void Slider::ApplySettings(KeyValues *inResourceData) |
|
{ |
|
BaseClass::ApplySettings(inResourceData); |
|
|
|
const char *left = inResourceData->GetString("leftText", NULL); |
|
const char *right = inResourceData->GetString("rightText", NULL); |
|
|
|
int thumbWidth = inResourceData->GetInt("thumbwidth", 0); |
|
if (thumbWidth != 0) |
|
{ |
|
SetThumbWidth(thumbWidth); |
|
} |
|
|
|
SetTickCaptions(left, right); |
|
|
|
int nNumTicks = inResourceData->GetInt( "numTicks", -1 ); |
|
if ( nNumTicks >= 0 ) |
|
{ |
|
SetNumTicks( nNumTicks ); |
|
} |
|
|
|
int nCurrentRange[2]; |
|
GetRange( nCurrentRange[0], nCurrentRange[1] ); |
|
KeyValues *pRangeMin = inResourceData->FindKey( "rangeMin", false ); |
|
KeyValues *pRangeMax = inResourceData->FindKey( "rangeMax", false ); |
|
bool bDoClamp = false; |
|
if ( pRangeMin ) |
|
{ |
|
_range[0] = inResourceData->GetInt( "rangeMin" ); |
|
bDoClamp = true; |
|
} |
|
if ( pRangeMax ) |
|
{ |
|
_range[1] = inResourceData->GetInt( "rangeMax" ); |
|
bDoClamp = true; |
|
} |
|
|
|
if ( bDoClamp ) |
|
{ |
|
ClampRange(); |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
const char *Slider::GetDescription() |
|
{ |
|
static char buf[1024]; |
|
Q_snprintf(buf, sizeof(buf), "%s, string leftText, string rightText", BaseClass::GetDescription()); |
|
return buf; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Get the rectangle to draw the slider track in. |
|
//----------------------------------------------------------------------------- |
|
void Slider::GetTrackRect( int& x, int& y, int& w, int& h ) |
|
{ |
|
int wide, tall; |
|
GetPaintSize( wide, tall ); |
|
|
|
x = 0; |
|
y = IsProportional() ? scheme()->GetProportionalScaledValue( 8.f ) : 8;; |
|
w = wide - (int)_nobSize; |
|
h = IsProportional() ? scheme()->GetProportionalScaledValue( 4.f ) : 4; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Draw everything on screen |
|
//----------------------------------------------------------------------------- |
|
void Slider::Paint() |
|
{ |
|
DrawTicks(); |
|
|
|
DrawTickLabels(); |
|
|
|
// Draw nob last so it draws over ticks. |
|
DrawNob(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Draw the ticks below the slider. |
|
//----------------------------------------------------------------------------- |
|
void Slider::DrawTicks() |
|
{ |
|
int x, y; |
|
int wide,tall; |
|
GetTrackRect( x, y, wide, tall ); |
|
|
|
// Figure out how to draw the ticks |
|
// GetPaintSize( wide, tall ); |
|
|
|
float fwide = (float)wide; |
|
float freepixels = fwide - _nobSize; |
|
|
|
float leftpixel = _nobSize / 2.0f; |
|
|
|
float pixelspertick = freepixels / ( m_nNumTicks ); |
|
|
|
y += (int)_nobSize; |
|
int tickHeight = 5; |
|
|
|
if (IsEnabled()) |
|
{ |
|
surface()->DrawSetColor( m_TickColor ); //vgui::Color( 127, 140, 127, 255 ) ); |
|
for ( int i = 0; i <= m_nNumTicks; i++ ) |
|
{ |
|
int xpos = (int)( leftpixel + i * pixelspertick ); |
|
|
|
surface()->DrawFilledRect( xpos, y, xpos + 1, y + tickHeight ); |
|
} |
|
} |
|
else |
|
{ |
|
surface()->DrawSetColor( m_DisabledTextColor1 ); //vgui::Color( 127, 140, 127, 255 ) ); |
|
for ( int i = 0; i <= m_nNumTicks; i++ ) |
|
{ |
|
int xpos = (int)( leftpixel + i * pixelspertick ); |
|
surface()->DrawFilledRect( xpos+1, y+1, xpos + 2, y + tickHeight + 1 ); |
|
} |
|
surface()->DrawSetColor( m_DisabledTextColor2 ); //vgui::Color( 127, 140, 127, 255 ) ); |
|
for ( int i = 0; i <= m_nNumTicks; i++ ) |
|
{ |
|
int xpos = (int)( leftpixel + i * pixelspertick ); |
|
surface()->DrawFilledRect( xpos, y, xpos + 1, y + tickHeight ); |
|
} |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Draw Tick labels under the ticks. |
|
//----------------------------------------------------------------------------- |
|
void Slider::DrawTickLabels() |
|
{ |
|
int x, y; |
|
int wide,tall; |
|
GetTrackRect( x, y, wide, tall ); |
|
|
|
// Figure out how to draw the ticks |
|
// GetPaintSize( wide, tall ); |
|
y += (int)NOB_SIZE + 4; |
|
|
|
// Draw Start and end range values |
|
if (IsEnabled()) |
|
surface()->DrawSetTextColor( m_TickColor ); //vgui::Color( 127, 140, 127, 255 ) ); |
|
else |
|
surface()->DrawSetTextColor( m_DisabledTextColor1 ); //vgui::Color( 127, 140, 127, 255 ) ); |
|
|
|
|
|
if ( _leftCaption != NULL ) |
|
{ |
|
_leftCaption->SetPos(0, y); |
|
if (IsEnabled()) |
|
{ |
|
_leftCaption->SetColor( m_TickColor ); |
|
} |
|
else |
|
{ |
|
_leftCaption->SetColor( m_DisabledTextColor1 ); |
|
} |
|
|
|
_leftCaption->Paint(); |
|
} |
|
|
|
if ( _rightCaption != NULL) |
|
{ |
|
int rwide, rtall; |
|
_rightCaption->GetSize(rwide, rtall); |
|
_rightCaption->SetPos((int)(wide - rwide) , y); |
|
if (IsEnabled()) |
|
{ |
|
_rightCaption->SetColor( m_TickColor ); |
|
} |
|
else |
|
{ |
|
_rightCaption->SetColor( m_DisabledTextColor1 ); |
|
} |
|
|
|
_rightCaption->Paint(); |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Draw the nob part of the slider. |
|
//----------------------------------------------------------------------------- |
|
void Slider::DrawNob() |
|
{ |
|
// horizontal nob |
|
int x, y; |
|
int wide,tall; |
|
GetTrackRect( x, y, wide, tall ); |
|
Color col = GetFgColor(); |
|
#ifdef _X360 |
|
if(HasFocus()) |
|
{ |
|
col = m_DepressedBgColor; |
|
} |
|
#endif |
|
surface()->DrawSetColor(col); |
|
|
|
int nobheight = IsProportional() ? scheme()->GetProportionalScaledValue( 16.f ) : 16.f; |
|
|
|
surface()->DrawFilledRect( |
|
_nobPos[0], |
|
y + tall / 2 - nobheight / 2, |
|
_nobPos[1], |
|
y + tall / 2 + nobheight / 2); |
|
// border |
|
if (_sliderBorder) |
|
{ |
|
_sliderBorder->Paint( |
|
_nobPos[0], |
|
y + tall / 2 - nobheight / 2, |
|
_nobPos[1], |
|
y + tall / 2 + nobheight / 2); |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Set the text labels of the Start and end ticks. |
|
//----------------------------------------------------------------------------- |
|
void Slider::SetTickCaptions( const char *left, const char *right ) |
|
{ |
|
if (left) |
|
{ |
|
if (_leftCaption) |
|
{ |
|
_leftCaption->SetText(left); |
|
} |
|
else |
|
{ |
|
_leftCaption = new TextImage(left); |
|
} |
|
} |
|
if (right) |
|
{ |
|
if (_rightCaption) |
|
{ |
|
_rightCaption->SetText(right); |
|
} |
|
else |
|
{ |
|
_rightCaption = new TextImage(right); |
|
} |
|
} |
|
InvalidateLayout(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Set the text labels of the Start and end ticks. |
|
//----------------------------------------------------------------------------- |
|
void Slider::SetTickCaptions( const wchar_t *left, const wchar_t *right ) |
|
{ |
|
if (left) |
|
{ |
|
if (_leftCaption) |
|
{ |
|
_leftCaption->SetText(left); |
|
} |
|
else |
|
{ |
|
_leftCaption = new TextImage(left); |
|
} |
|
} |
|
if (right) |
|
{ |
|
if (_rightCaption) |
|
{ |
|
_rightCaption->SetText(right); |
|
} |
|
else |
|
{ |
|
_rightCaption = new TextImage(right); |
|
} |
|
} |
|
InvalidateLayout(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Draw the slider track |
|
//----------------------------------------------------------------------------- |
|
void Slider::PaintBackground() |
|
{ |
|
BaseClass::PaintBackground(); |
|
|
|
int x, y; |
|
int wide,tall; |
|
|
|
GetTrackRect( x, y, wide, tall ); |
|
|
|
surface()->DrawSetColor( m_TrackColor ); |
|
surface()->DrawFilledRect( x, y, x + wide, y + tall ); |
|
if (_insetBorder) |
|
{ |
|
_insetBorder->Paint( x, y, x + wide, y + tall ); |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Set the range of the slider. |
|
//----------------------------------------------------------------------------- |
|
void Slider::SetRange(int min,int max) |
|
{ |
|
_range[0]=min; |
|
_range[1]=max; |
|
|
|
ClampRange(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Sanity check and clamp the range if necessary. |
|
//----------------------------------------------------------------------------- |
|
void Slider::ClampRange() |
|
{ |
|
if ( _range[0] < _range[1] ) |
|
{ |
|
if(_value<_range[0]) |
|
{ |
|
SetValue( _range[0], false ); |
|
} |
|
else if( _value>_range[1]) |
|
{ |
|
SetValue( _range[1], false ); |
|
} |
|
} |
|
else |
|
{ |
|
if(_value<_range[1]) |
|
{ |
|
SetValue( _range[1], false ); |
|
} |
|
else if( _value>_range[0]) |
|
{ |
|
SetValue( _range[0], false ); |
|
} |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Get the max and min values of the slider |
|
//----------------------------------------------------------------------------- |
|
void Slider::GetRange(int& min,int& max) |
|
{ |
|
min=_range[0]; |
|
max=_range[1]; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Respond when the cursor is moved in our window if we are clicking |
|
// and dragging. |
|
//----------------------------------------------------------------------------- |
|
void Slider::OnCursorMoved(int x,int y) |
|
{ |
|
if(!_dragging) |
|
{ |
|
return; |
|
} |
|
|
|
// input()->GetCursorPos(x,y); |
|
input()->GetCursorPosition( x, y ); |
|
ScreenToLocal(x,y); |
|
|
|
// int wide,tall; |
|
// GetPaintSize(wide,tall); |
|
int _x, _y, wide, tall; |
|
GetTrackRect( _x, _y, wide, tall ); |
|
|
|
_nobPos[0]=_nobDragStartPos[0]+(x-_dragStartPos[0]); |
|
_nobPos[1]=_nobDragStartPos[1]+(x-_dragStartPos[0]); |
|
|
|
int rightEdge = _x +wide; |
|
int unclamped = _nobPos[ 0 ]; |
|
|
|
if(_nobPos[1]>rightEdge) |
|
{ |
|
_nobPos[0]=rightEdge-(_nobPos[1]-_nobPos[0]); |
|
_nobPos[1]=rightEdge; |
|
} |
|
|
|
if(_nobPos[0]<_x) |
|
{ |
|
int offset = _x - _nobPos[0]; |
|
_nobPos[1]=_nobPos[1]-offset; |
|
_nobPos[0]=0; |
|
} |
|
|
|
int value = EstimateValueAtPos( unclamped, 0 ); |
|
SetValue( value ); |
|
|
|
// RecomputeValueFromNobPos(); |
|
Repaint(); |
|
SendSliderMovedMessage(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: If you click on the slider outside of the nob, the nob jumps |
|
// to the click position, and if this setting is enabled, the nob |
|
// is then draggable from the new position until the mouse is released |
|
// Input : state - |
|
//----------------------------------------------------------------------------- |
|
void Slider::SetDragOnRepositionNob( bool state ) |
|
{ |
|
m_bIsDragOnRepositionNob = state; |
|
} |
|
|
|
bool Slider::IsDragOnRepositionNob() const |
|
{ |
|
return m_bIsDragOnRepositionNob; |
|
} |
|
|
|
bool Slider::IsDragged( void ) const |
|
{ |
|
return _dragging; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Respond to mouse presses. Trigger Record staring positon. |
|
//----------------------------------------------------------------------------- |
|
void Slider::OnMousePressed(MouseCode code) |
|
{ |
|
int x,y; |
|
|
|
if (!IsEnabled()) |
|
return; |
|
|
|
// input()->GetCursorPos(x,y); |
|
input()->GetCursorPosition( x, y ); |
|
|
|
ScreenToLocal(x,y); |
|
RequestFocus(); |
|
|
|
bool startdragging = false, bPostDragStartSignal = false; |
|
|
|
if ((x >= _nobPos[0]) && (x < _nobPos[1])) |
|
{ |
|
startdragging = true; |
|
bPostDragStartSignal = true; |
|
} |
|
else |
|
{ |
|
// we clicked elsewhere on the slider; move the nob to that position |
|
int min, max; |
|
GetRange(min, max); |
|
if ( m_bUseSubRange ) |
|
{ |
|
min = _subrange[ 0 ]; |
|
max = _subrange[ 1 ]; |
|
} |
|
|
|
// int wide = GetWide(); |
|
int _x, _y, wide, tall; |
|
GetTrackRect( _x, _y, wide, tall ); |
|
if ( wide > 0 ) |
|
{ |
|
float frange = ( float )( max - min ); |
|
float clickFrac = clamp( ( float )( x - _x ) / (float)( wide - 1 ), 0.0f, 1.0f ); |
|
|
|
float value = (float)min + clickFrac * frange; |
|
|
|
startdragging = IsDragOnRepositionNob(); |
|
|
|
if ( startdragging ) |
|
{ |
|
_dragging = true; // Required when as |
|
SendSliderDragStartMessage(); |
|
} |
|
|
|
SetValue( ( int )( value + 0.5f ) ); |
|
} |
|
} |
|
|
|
if ( startdragging ) |
|
{ |
|
// drag the nob |
|
_dragging = true; |
|
input()->SetMouseCapture(GetVPanel()); |
|
_nobDragStartPos[0] = _nobPos[0]; |
|
_nobDragStartPos[1] = _nobPos[1]; |
|
_dragStartPos[0] = x; |
|
_dragStartPos[1] = y; |
|
} |
|
|
|
if ( bPostDragStartSignal ) |
|
SendSliderDragStartMessage(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Just handle double presses like mouse presses |
|
//----------------------------------------------------------------------------- |
|
void Slider::OnMouseDoublePressed(MouseCode code) |
|
{ |
|
OnMousePressed(code); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
#ifdef _X360 |
|
void Slider::OnKeyCodePressed(KeyCode code) |
|
{ |
|
switch ( GetBaseButtonCode( code ) ) |
|
{ |
|
case KEY_XBUTTON_LEFT: |
|
case KEY_XSTICK1_LEFT: |
|
case KEY_XSTICK2_LEFT: |
|
SetValue(GetValue() - 1); |
|
break; |
|
case KEY_XBUTTON_RIGHT: |
|
case KEY_XSTICK1_RIGHT: |
|
case KEY_XSTICK2_RIGHT: |
|
SetValue(GetValue() + 1); |
|
break; |
|
default: |
|
BaseClass::OnKeyCodePressed(code); |
|
break; |
|
} |
|
} |
|
#endif |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Handle key presses |
|
//----------------------------------------------------------------------------- |
|
void Slider::OnKeyCodeTyped(KeyCode code) |
|
{ |
|
switch (code) |
|
{ |
|
// for now left and right arrows just open or close submenus if they are there. |
|
case KEY_LEFT: |
|
case KEY_DOWN: |
|
{ |
|
int val = GetValue(); |
|
SetValue(val-1); |
|
break; |
|
} |
|
case KEY_RIGHT: |
|
case KEY_UP: |
|
{ |
|
int val = GetValue(); |
|
SetValue(val+1); |
|
break; |
|
} |
|
case KEY_PAGEDOWN: |
|
{ |
|
int min, max; |
|
GetRange(min, max); |
|
float range = (float) max-min; |
|
float pertick = range/m_nNumTicks; |
|
int val = GetValue(); |
|
SetValue(val - (int) pertick); |
|
break; |
|
} |
|
case KEY_PAGEUP: |
|
{ |
|
int min, max; |
|
GetRange(min, max); |
|
float range = (float) max-min; |
|
float pertick = range/m_nNumTicks; |
|
int val = GetValue(); |
|
SetValue(val + (int) pertick); |
|
break; |
|
} |
|
case KEY_HOME: |
|
{ |
|
int min, max; |
|
GetRange(min, max); |
|
SetValue(min); |
|
break; |
|
} |
|
case KEY_END: |
|
{ |
|
int min, max; |
|
GetRange(min, max); |
|
SetValue(max); |
|
break; |
|
} |
|
default: |
|
BaseClass::OnKeyCodeTyped(code); |
|
break; |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Stop dragging when the mouse is released. |
|
//----------------------------------------------------------------------------- |
|
void Slider::OnMouseReleased(MouseCode code) |
|
{ |
|
if ( _dragging ) |
|
{ |
|
_dragging=false; |
|
input()->SetMouseCapture(null); |
|
} |
|
|
|
if ( IsEnabled() ) |
|
{ |
|
SendSliderDragEndMessage(); |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Get the nob's position (the ends of each side of the nob) |
|
//----------------------------------------------------------------------------- |
|
void Slider::GetNobPos(int& min, int& max) |
|
{ |
|
min=_nobPos[0]; |
|
max=_nobPos[1]; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void Slider::SetButtonOffset(int buttonOffset) |
|
{ |
|
_buttonOffset=buttonOffset; |
|
} |
|
|
|
void Slider::SetThumbWidth( int width ) |
|
{ |
|
_nobSize = IsProportional() ? scheme()->GetProportionalScaledValue( (float)width) : (float)width; |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Set the number of ticks that appear under the slider. |
|
//----------------------------------------------------------------------------- |
|
void Slider::SetNumTicks( int ticks ) |
|
{ |
|
m_nNumTicks = ticks; |
|
}
|
|
|