437 lines
7.9 KiB
C++
437 lines
7.9 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
|
|
{
|
|
private:
|
|
Slider2* _slider;
|
|
|
|
public:
|
|
FooDefaultSliderSignal(Slider2* slider)
|
|
{
|
|
_slider = slider;
|
|
}
|
|
|
|
public:
|
|
void cursorMoved(int x, int y, Panel* panel) override
|
|
{
|
|
_slider->privateCursorMoved(x, y, panel);
|
|
}
|
|
void cursorEntered(Panel* panel) override {}
|
|
void cursorExited(Panel* panel) override {}
|
|
void mouseDoublePressed(MouseCode code, Panel* panel) override {}
|
|
void mousePressed(MouseCode code, Panel* panel) override
|
|
{
|
|
_slider->privateMousePressed(code, panel);
|
|
}
|
|
void mouseReleased(MouseCode code, Panel* panel) override
|
|
{
|
|
_slider->privateMouseReleased(code, panel);
|
|
}
|
|
void mouseWheeled(int delta, Panel* panel) override {}
|
|
void keyPressed(KeyCode code, Panel* panel) override {}
|
|
void keyTyped(KeyCode code, Panel* panel) override {}
|
|
void keyReleased(KeyCode code, Panel* panel) override {}
|
|
void keyFocusTicked(Panel* panel) override {}
|
|
};
|
|
}
|
|
|
|
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;
|
|
}
|