2007-06-30 16:30:40 -07:00
|
|
|
// Copyright (C) 2006 Michael Zeilfelder
|
|
|
|
// This file uses the licence of the Irrlicht Engine.
|
|
|
|
|
|
|
|
#include "IrrCompileConfig.h"
|
|
|
|
#include "CGUISpinBox.h"
|
|
|
|
#include "CGUIEditBox.h"
|
|
|
|
#include "CGUIButton.h"
|
|
|
|
#include "IGUIEnvironment.h"
|
|
|
|
#include "IEventReceiver.h"
|
|
|
|
#include "fast_atof.h"
|
|
|
|
#include <float.h>
|
|
|
|
#include <wchar.h>
|
|
|
|
|
|
|
|
|
|
|
|
namespace irr
|
|
|
|
{
|
|
|
|
namespace gui
|
|
|
|
{
|
|
|
|
|
|
|
|
//! constructor
|
|
|
|
CGUISpinBox::CGUISpinBox(const wchar_t* text, IGUIEnvironment* environment,
|
|
|
|
IGUIElement* parent, s32 id, const core::rect<s32>& rectangle)
|
2007-07-01 03:16:39 -07:00
|
|
|
: IGUISpinBox(environment, parent, id, rectangle),
|
|
|
|
EditBox(0), ButtonSpinUp(0), ButtonSpinDown(0), StepSize(1.f),
|
|
|
|
RangeMin(-FLT_MAX), RangeMax(FLT_MAX), FormatString(L"%f"),
|
|
|
|
DecimalPlaces(-1)
|
2007-06-30 16:30:40 -07:00
|
|
|
{
|
|
|
|
s32 ButtonWidth = 16;
|
|
|
|
IGUISpriteBank *sb = 0;
|
|
|
|
if (environment && environment->getSkin())
|
|
|
|
{
|
|
|
|
ButtonWidth = environment->getSkin()->getSize(EGDS_SCROLLBAR_SIZE);
|
|
|
|
sb = environment->getSkin()->getSpriteBank();
|
|
|
|
}
|
|
|
|
|
2007-07-01 03:16:39 -07:00
|
|
|
ButtonSpinDown = Environment->addButton(
|
|
|
|
core::rect<s32>(rectangle.getWidth() - ButtonWidth, rectangle.getHeight()/2 +1,
|
2007-06-30 16:30:40 -07:00
|
|
|
rectangle.getWidth(), rectangle.getHeight()), this);
|
2007-07-01 03:16:39 -07:00
|
|
|
ButtonSpinDown->grab();
|
2007-06-30 16:30:40 -07:00
|
|
|
ButtonSpinDown->setSubElement(true);
|
|
|
|
ButtonSpinDown->setAlignment(EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_CENTER, EGUIA_LOWERRIGHT);
|
|
|
|
|
2007-07-01 03:16:39 -07:00
|
|
|
ButtonSpinUp = Environment->addButton(
|
|
|
|
core::rect<s32>(rectangle.getWidth() - ButtonWidth, 0,
|
2007-06-30 16:30:40 -07:00
|
|
|
rectangle.getWidth(), rectangle.getHeight()/2), this);
|
2007-07-01 03:16:39 -07:00
|
|
|
ButtonSpinUp->grab();
|
2007-06-30 16:30:40 -07:00
|
|
|
ButtonSpinUp->setSubElement(true);
|
|
|
|
ButtonSpinUp->setAlignment(EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_CENTER);
|
|
|
|
if (sb)
|
|
|
|
{
|
|
|
|
IGUISkin *skin = environment->getSkin();
|
|
|
|
ButtonSpinDown->setSpriteBank(sb);
|
|
|
|
ButtonSpinDown->setSprite(EGBS_BUTTON_UP, skin->getIcon(EGDI_SMALL_CURSOR_DOWN), skin->getColor(EGDC_WINDOW_SYMBOL));
|
|
|
|
ButtonSpinDown->setSprite(EGBS_BUTTON_DOWN, skin->getIcon(EGDI_SMALL_CURSOR_DOWN), skin->getColor(EGDC_WINDOW_SYMBOL));
|
|
|
|
ButtonSpinUp->setSpriteBank(sb);
|
|
|
|
ButtonSpinUp->setSprite(EGBS_BUTTON_UP, skin->getIcon(EGDI_SMALL_CURSOR_UP), skin->getColor(EGDC_WINDOW_SYMBOL));
|
|
|
|
ButtonSpinUp->setSprite(EGBS_BUTTON_DOWN, skin->getIcon(EGDI_SMALL_CURSOR_UP), skin->getColor(EGDC_WINDOW_SYMBOL));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ButtonSpinDown->setText(L"-");
|
|
|
|
ButtonSpinUp->setText(L"+");
|
|
|
|
}
|
|
|
|
|
2007-07-01 03:16:39 -07:00
|
|
|
core::rect<s32> rectEdit(0, 0, rectangle.getWidth() - ButtonWidth - 1, rectangle.getHeight());
|
|
|
|
EditBox = Environment->addEditBox(text, rectEdit, true, this, -1);
|
|
|
|
EditBox->grab();
|
2007-06-30 16:30:40 -07:00
|
|
|
EditBox->setSubElement(true);
|
|
|
|
EditBox->setAlignment(EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT);
|
|
|
|
|
|
|
|
// verifyValueRange();
|
|
|
|
}
|
|
|
|
|
|
|
|
//! destructor
|
|
|
|
CGUISpinBox::~CGUISpinBox()
|
|
|
|
{
|
|
|
|
if (ButtonSpinUp)
|
|
|
|
ButtonSpinUp->drop();
|
2007-07-01 03:16:39 -07:00
|
|
|
if (ButtonSpinDown)
|
|
|
|
ButtonSpinDown->drop();
|
|
|
|
if (EditBox)
|
|
|
|
EditBox->drop();
|
2007-06-30 16:30:40 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
IGUIEditBox* CGUISpinBox::getEditBox()
|
|
|
|
{
|
2007-07-01 03:16:39 -07:00
|
|
|
return EditBox;
|
2007-06-30 16:30:40 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void CGUISpinBox::setValue(f32 val)
|
|
|
|
{
|
2007-07-01 03:16:39 -07:00
|
|
|
wchar_t str[100];
|
|
|
|
|
|
|
|
swprintf(str, 99, FormatString.c_str(), val);
|
|
|
|
EditBox->setText(str);
|
|
|
|
verifyValueRange();
|
2007-06-30 16:30:40 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
f32 CGUISpinBox::getValue()
|
|
|
|
{
|
2007-07-01 03:16:39 -07:00
|
|
|
const wchar_t* val = EditBox->getText();
|
|
|
|
if ( !val )
|
|
|
|
return 0.f;
|
2007-06-30 16:30:40 -07:00
|
|
|
core::stringc tmp(val);
|
2007-07-01 03:16:39 -07:00
|
|
|
return core::fast_atof(tmp.c_str());
|
2007-06-30 16:30:40 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void CGUISpinBox::setRange(f32 min, f32 max)
|
|
|
|
{
|
2007-07-01 03:16:39 -07:00
|
|
|
RangeMin = min;
|
|
|
|
RangeMax = max;
|
|
|
|
verifyValueRange();
|
2007-06-30 16:30:40 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
f32 CGUISpinBox::getMin()
|
|
|
|
{
|
2007-07-01 03:16:39 -07:00
|
|
|
return RangeMin;
|
2007-06-30 16:30:40 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
f32 CGUISpinBox::getMax()
|
|
|
|
{
|
2007-07-01 03:16:39 -07:00
|
|
|
return RangeMax;
|
2007-06-30 16:30:40 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
f32 CGUISpinBox::getStepSize()
|
|
|
|
{
|
|
|
|
return StepSize;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CGUISpinBox::setStepSize(f32 step)
|
|
|
|
{
|
2007-07-01 03:16:39 -07:00
|
|
|
StepSize = step;
|
2007-06-30 16:30:40 -07:00
|
|
|
}
|
|
|
|
|
2007-07-01 03:16:39 -07:00
|
|
|
//! Sets the number of decimal places to display.
|
2007-06-30 16:30:40 -07:00
|
|
|
void CGUISpinBox::setDecimalPlaces(s32 places)
|
|
|
|
{
|
|
|
|
DecimalPlaces = places;
|
|
|
|
if (places == -1)
|
|
|
|
FormatString = "%f";
|
|
|
|
else
|
|
|
|
{
|
2007-07-01 03:16:39 -07:00
|
|
|
FormatString = "%.";
|
|
|
|
FormatString += places;
|
2007-06-30 16:30:40 -07:00
|
|
|
FormatString += "f";
|
|
|
|
}
|
|
|
|
setValue(getValue());
|
|
|
|
}
|
|
|
|
|
|
|
|
bool CGUISpinBox::OnEvent(SEvent event)
|
|
|
|
{
|
2007-07-01 03:16:39 -07:00
|
|
|
bool changeEvent = false;
|
|
|
|
switch(event.EventType)
|
2007-06-30 16:30:40 -07:00
|
|
|
{
|
|
|
|
case EET_GUI_EVENT:
|
|
|
|
if (event.GUIEvent.EventType == EGET_BUTTON_CLICKED)
|
|
|
|
{
|
2007-07-01 03:16:39 -07:00
|
|
|
if (event.GUIEvent.Caller == ButtonSpinUp)
|
|
|
|
{
|
|
|
|
f32 val = getValue();
|
|
|
|
val += StepSize;
|
|
|
|
setValue(val);
|
|
|
|
changeEvent = true;
|
|
|
|
}
|
|
|
|
else if ( event.GUIEvent.Caller == ButtonSpinDown)
|
|
|
|
{
|
|
|
|
f32 val = getValue();
|
|
|
|
val -= StepSize;
|
|
|
|
setValue(val);
|
|
|
|
changeEvent = true;
|
|
|
|
}
|
2007-06-30 16:30:40 -07:00
|
|
|
}
|
|
|
|
if ( event.GUIEvent.EventType == EGET_EDITBOX_ENTER )
|
|
|
|
{
|
2007-07-01 03:16:39 -07:00
|
|
|
if (event.GUIEvent.Caller == EditBox)
|
|
|
|
{
|
|
|
|
verifyValueRange();
|
|
|
|
changeEvent = true;
|
|
|
|
}
|
2007-06-30 16:30:40 -07:00
|
|
|
}
|
|
|
|
break;
|
2007-07-01 03:16:39 -07:00
|
|
|
default:
|
|
|
|
break;
|
2007-06-30 16:30:40 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
if ( changeEvent )
|
|
|
|
{
|
2007-07-01 03:16:39 -07:00
|
|
|
SEvent e;
|
|
|
|
e.EventType = EET_GUI_EVENT;
|
|
|
|
e.GUIEvent.Caller = this;
|
|
|
|
//fprintf(stderr, "EGET_SPINBOX_CHANGED caller:%p id: %d\n", e.GUIEvent.Caller, e.GUIEvent.Caller->getID() );
|
|
|
|
e.GUIEvent.EventType = EGET_SPINBOX_CHANGED;
|
|
|
|
if ( Parent )
|
|
|
|
Parent->OnEvent(e);
|
2007-06-30 16:30:40 -07:00
|
|
|
}
|
|
|
|
|
2007-07-01 03:16:39 -07:00
|
|
|
return false;
|
2007-06-30 16:30:40 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void CGUISpinBox::verifyValueRange()
|
|
|
|
{
|
2007-07-01 03:16:39 -07:00
|
|
|
f32 val = getValue();
|
|
|
|
if ( val < RangeMin )
|
|
|
|
val = RangeMin;
|
|
|
|
else if ( val > RangeMax )
|
|
|
|
val = RangeMax;
|
|
|
|
else
|
|
|
|
return;
|
2007-06-30 16:30:40 -07:00
|
|
|
|
2007-07-01 03:16:39 -07:00
|
|
|
setValue(val);
|
2007-06-30 16:30:40 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
//! Sets the new caption of the element
|
|
|
|
void CGUISpinBox::setText(const wchar_t* text)
|
|
|
|
{
|
2007-07-01 03:16:39 -07:00
|
|
|
EditBox->setText(text);
|
2007-06-30 16:30:40 -07:00
|
|
|
setValue(getValue());
|
|
|
|
verifyValueRange();
|
|
|
|
}
|
|
|
|
|
|
|
|
//! Returns caption of this element.
|
|
|
|
const wchar_t* CGUISpinBox::getText()
|
|
|
|
{
|
2007-07-01 03:16:39 -07:00
|
|
|
return EditBox->getText();
|
2007-06-30 16:30:40 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
//! Writes attributes of the element.
|
|
|
|
void CGUISpinBox::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options)
|
|
|
|
{
|
|
|
|
IGUIElement::serializeAttributes(out, options);
|
|
|
|
out->addFloat("Min", getMin());
|
|
|
|
out->addFloat("Max", getMax());
|
|
|
|
out->addFloat("Step", getStepSize());
|
|
|
|
out->addInt("DecimalPlaces", DecimalPlaces);
|
|
|
|
}
|
|
|
|
|
|
|
|
//! Reads attributes of the element
|
|
|
|
void CGUISpinBox::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options)
|
|
|
|
{
|
|
|
|
IGUIElement::deserializeAttributes(in, options);
|
|
|
|
setRange(in->getAttributeAsFloat("Min"), in->getAttributeAsFloat("Max"));
|
|
|
|
setStepSize(in->getAttributeAsFloat("Step"));
|
|
|
|
setDecimalPlaces(in->getAttributeAsInt("DecimalPlaces"));
|
|
|
|
}
|
|
|
|
|
|
|
|
} // end namespace gui
|
|
|
|
} // end namespace irr
|