//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: New version of the slider bar // // $NoKeywords: $ //============================================================================= #include "vgui_slider2.h" #include #include #include #include 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(maxmax) { 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; }