ns/releases/3.02/source/ui/SliderPlus.cpp
tankefugl 7b18f64309 Branched for 3.02 changes
git-svn-id: https://unknownworlds.svn.cloudforge.com/ns1@16 67975925-1194-0748-b3d5-c16f83f1a3a1
2005-03-30 12:54:33 +00:00

264 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();
}