mirror of
https://github.com/unknownworlds/NS.git
synced 2024-11-26 14:30:56 +00:00
265 lines
6.6 KiB
C++
265 lines
6.6 KiB
C++
|
#include "../util/nowarnings.h"
|
||
|
#include "ui/SliderPlus.h"
|
||
|
#include "ui/UIUtil.h"
|
||
|
#include "VGUI_MouseCode.h"
|
||
|
|
||
|
SliderPlus::SliderPlus(int inX, int inY,int inWidth, int inHeight, bool inIsVertical) : Panel(inX, inY, inWidth, inHeight)
|
||
|
{
|
||
|
this->mDragging = false;
|
||
|
this->mNobDragStartPos[0] = this->mNobDragStartPos[1] = 0;
|
||
|
this->mDragStartPos[0] = this->mDragStartPos[1] = 0;
|
||
|
this->mNobPos[0] = this->mNobPos[1] = 0;
|
||
|
this->mRange[0] = 0;
|
||
|
this->mRange[1] = 10;
|
||
|
this->mValue = 0;
|
||
|
this->mRangeWindow = 10;
|
||
|
this->mIsVertical = inIsVertical;
|
||
|
this->mLastMouseX = this->mLastMouseY = 0;
|
||
|
|
||
|
// Add ourselves as our own input signal...kinda strange sounding but useful
|
||
|
this->addInputSignal(this);
|
||
|
}
|
||
|
|
||
|
void SliderPlus::addIntChangeSignal(IntChangeSignal* inChangeSignal)
|
||
|
{
|
||
|
// Add inChangeSignal to list
|
||
|
}
|
||
|
|
||
|
void SliderPlus::computeNobBox(int& outStartX, int& outStartY, int& outEndX, int& outEndY)
|
||
|
{
|
||
|
int theWidth, theHeight;
|
||
|
this->getSize(theWidth, theHeight);
|
||
|
|
||
|
outStartX = this->mNobPos[0];
|
||
|
outStartY = this->mNobPos[1];
|
||
|
|
||
|
if(this->mIsVertical)
|
||
|
{
|
||
|
outEndX = outStartX + theWidth - 1;
|
||
|
outEndY = outStartY + this->mRangeWindow;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
outEndX = outStartX + this->mRangeWindow;
|
||
|
outEndY = outStartY + theHeight - 1;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void SliderPlus::fireIntChangeSignal()
|
||
|
{
|
||
|
// Run through list of change signals, calling intChanged() on each one
|
||
|
}
|
||
|
|
||
|
void SliderPlus::getNobPos(int& outMin, int& outMax)
|
||
|
{
|
||
|
// Return the upper left corner of the nob
|
||
|
outMin = this->mNobPos[0];
|
||
|
outMax = this->mNobPos[1];
|
||
|
}
|
||
|
|
||
|
void SliderPlus::getRange(int& outMinRange, int& outMaxRange)
|
||
|
{
|
||
|
// Return the min and max range
|
||
|
outMinRange = this->mRange[0];
|
||
|
outMaxRange = this->mRange[1];
|
||
|
}
|
||
|
|
||
|
int SliderPlus::getRangeWindow()
|
||
|
{
|
||
|
return this->mRangeWindow;
|
||
|
}
|
||
|
|
||
|
int SliderPlus::getValue()
|
||
|
{
|
||
|
return this->mValue;
|
||
|
}
|
||
|
|
||
|
bool SliderPlus::hasFullRange()
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
bool SliderPlus::isVertical()
|
||
|
{
|
||
|
return this->mIsVertical;
|
||
|
}
|
||
|
|
||
|
void SliderPlus::paintBackground()
|
||
|
{
|
||
|
int theStartX, theStartY;
|
||
|
int theWidth, theHeight;
|
||
|
int theEndX, theEndY;
|
||
|
|
||
|
//this->getPos(theStartX, theStartY);
|
||
|
theStartX = theStartY = 0;
|
||
|
|
||
|
this->getSize(theWidth, theHeight);
|
||
|
|
||
|
Color theColor;
|
||
|
int theR, theG, theB, theA;
|
||
|
|
||
|
this->getBgColor(theColor);
|
||
|
theColor.getColor(theR, theG, theB, theA);
|
||
|
|
||
|
// Draw rectangle the size of the slider in background color
|
||
|
theEndX = theStartX + theWidth;
|
||
|
theEndY = theStartY + theHeight;
|
||
|
|
||
|
// Draw hollow box in bg color
|
||
|
vguiSimpleBox(theStartX, theStartY, theEndX-1, theEndY-1, theR, theG, theB, theA);
|
||
|
|
||
|
// Draw nob in foreground color, size of range window
|
||
|
this->getFgColor(theColor);
|
||
|
theColor.getColor(theR, theG, theB, theA);
|
||
|
|
||
|
// Compute the nob position so we can draw a box for it, all numbers are in pixels relative to component
|
||
|
this->computeNobBox(theStartX, theStartY, theEndX, theEndY);
|
||
|
|
||
|
// Draw hollow box in fg color
|
||
|
vguiSimpleBox(theStartX, theStartY, theEndX, theEndY, theR, theG, theB, theA);
|
||
|
}
|
||
|
|
||
|
void SliderPlus::cursorMoved(int inX, int inY, Panel* inPanel)
|
||
|
{
|
||
|
// Are we dragging the nub?
|
||
|
if(this->mDragging)
|
||
|
{
|
||
|
// Look at inX, inY and set our new nob pos
|
||
|
this->mNobPos[0] = this->mNobPos[1] = 0;
|
||
|
|
||
|
if(this->mIsVertical)
|
||
|
{
|
||
|
this->mNobPos[1] = inY;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
this->mNobPos[0] = inX;
|
||
|
}
|
||
|
|
||
|
// Recompute the value from it
|
||
|
this->recomputeValueFromNobPos();
|
||
|
}
|
||
|
|
||
|
this->mLastMouseX = inX;
|
||
|
this->mLastMouseY = inY;
|
||
|
}
|
||
|
|
||
|
void SliderPlus::mousePressed(MouseCode inCode, Panel* inPanel)
|
||
|
{
|
||
|
int theStartX, theStartY, theEndX, theEndY;
|
||
|
this->computeNobBox(theStartX, theStartY, theEndX, theEndY);
|
||
|
|
||
|
// Was LMB was pressed?
|
||
|
if(inCode == MOUSE_LEFT)
|
||
|
{
|
||
|
// Pressed while over the nob?
|
||
|
if((this->mLastMouseX >= theStartX) && (this->mLastMouseX <= theEndX) && (this->mLastMouseY >= theStartY) && (this->mLastMouseY <= theEndY))
|
||
|
{
|
||
|
// Remember this starting point and remember that we're dragging
|
||
|
this->mDragStartPos[0] = this->mLastMouseX;
|
||
|
this->mDragStartPos[1] = this->mLastMouseY;
|
||
|
this->mDragging = true;
|
||
|
}
|
||
|
// Above or below nub?
|
||
|
else
|
||
|
{
|
||
|
// TODO?: Remember this so we can start adjusting by big increments. For now, just adjust once.
|
||
|
// Adjust value by major increment
|
||
|
//this->recomputeNobPosFromValue();
|
||
|
}
|
||
|
}
|
||
|
// Was RMB pressed above or below the nub?
|
||
|
else if(inCode == MOUSE_RIGHT)
|
||
|
{
|
||
|
// TODO?: Remember this so we can start adjusting by tiny increments. For now, just adjust once.
|
||
|
// Adjust value by minor increment
|
||
|
//this->recomputeNobPosFromValue();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void SliderPlus::mouseReleased(MouseCode inCode, Panel* inPanel)
|
||
|
{
|
||
|
// Forget that we are dragging or adjusting by big or small increments.
|
||
|
if(inCode == MOUSE_LEFT)
|
||
|
{
|
||
|
this->mDragging = false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void SliderPlus::mouseWheeled(int delta, Panel* panel)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
void SliderPlus::recomputeNobPosFromValue()
|
||
|
{
|
||
|
// Look at current value and range and set the nob pos from it
|
||
|
int theWidth, theHeight;
|
||
|
this->getSize(theWidth, theHeight);
|
||
|
|
||
|
float theNormalizedNobPos = (this->mValue - this->mRange[0])/(float)(this->mRange[1]);
|
||
|
if(this->mIsVertical)
|
||
|
{
|
||
|
this->mNobPos[0] = 0;
|
||
|
this->mNobPos[1] = (int)(theNormalizedNobPos*theHeight);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
this->mNobPos[0] = (int)(theNormalizedNobPos*theWidth);
|
||
|
this->mNobPos[1] = 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void SliderPlus::recomputeValueFromNobPos()
|
||
|
{
|
||
|
// Look at nob pos and set new value
|
||
|
int theWidth, theHeight;
|
||
|
this->getSize(theWidth, theHeight);
|
||
|
|
||
|
int theRelevantValue = this->mNobPos[0];
|
||
|
int theRelevantMaxPixels = theWidth;
|
||
|
|
||
|
if(this->mIsVertical)
|
||
|
{
|
||
|
theRelevantValue = this->mNobPos[1];
|
||
|
theRelevantMaxPixels = theHeight;
|
||
|
}
|
||
|
|
||
|
float theNormalizedValue = (theRelevantValue/(float)theRelevantMaxPixels);
|
||
|
int theNewValue = this->mRange[0] + (int)(theNormalizedValue*this->mRange[1]);
|
||
|
|
||
|
this->setValue(theNewValue);
|
||
|
}
|
||
|
|
||
|
void SliderPlus::setRange(int inMinRange, int inMaxRange)
|
||
|
{
|
||
|
// Set the range ("value")
|
||
|
this->mRange[0] = min(inMinRange, inMaxRange);
|
||
|
this->mRange[1] = max(inMinRange, inMaxRange);
|
||
|
}
|
||
|
|
||
|
void SliderPlus::setRangeWindow(int inRangeWindow)
|
||
|
{
|
||
|
// Set the range window (in pixels)
|
||
|
this->mRangeWindow = inRangeWindow;
|
||
|
}
|
||
|
|
||
|
void SliderPlus::setSize(int inWidth, int inHeight)
|
||
|
{
|
||
|
// Call parent setSize
|
||
|
Panel::setSize(inWidth, inHeight);
|
||
|
|
||
|
// Recompute something?
|
||
|
}
|
||
|
|
||
|
void SliderPlus::setValue(int inValue)
|
||
|
{
|
||
|
// Only allow setting the value within our specified range
|
||
|
int theNewValue = inValue;
|
||
|
theNewValue = max(theNewValue, this->mRange[0]);
|
||
|
theNewValue = min(theNewValue, this->mRange[1]);
|
||
|
|
||
|
this->mValue = theNewValue;
|
||
|
|
||
|
this->recomputeNobPosFromValue();
|
||
|
}
|