437 lines
7.9 KiB
C++
437 lines
7.9 KiB
C++
|
//========= Copyright <20> 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
|
|||
|
{
|
|||
|
private:
|
|||
|
Slider2* _slider;
|
|||
|
public:
|
|||
|
FooDefaultSliderSignal(Slider2* slider)
|
|||
|
{
|
|||
|
_slider=slider;
|
|||
|
}
|
|||
|
public:
|
|||
|
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;
|
|||
|
}
|