Add IGUISpinBox functions getValueFor and getOldValue

Also documenting some missing feature (decimal places ignored with direct text input)
getValueFor allows to check the value a given text would have 
getOldValue can be used to check the previous value in a EGET_SPINBOX_CHANGED event

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@6429 dfc29bdd-3216-0410-991c-e03cc46cb475
This commit is contained in:
cutealien 2022-09-28 14:25:18 +00:00
parent 0ef9102ac6
commit a883d464f9
4 changed files with 55 additions and 24 deletions

View File

@ -1,6 +1,7 @@
-------------------------- --------------------------
Changes in 1.9 (not yet released) Changes in 1.9 (not yet released)
- Add IGUISpinBox functions getValueFor and getOldValue
- Bugfix: IGUIElement::getNextElement now passing includeInvisible and includeDisabled flags recursively instead of disabling those for children. - Bugfix: IGUIElement::getNextElement now passing includeInvisible and includeDisabled flags recursively instead of disabling those for children.
This fixes problems that elements sometimes didn't get a tab order because some parent was invisible and so tab'ing for them failed completely. This fixes problems that elements sometimes didn't get a tab order because some parent was invisible and so tab'ing for them failed completely.
Also setTabOrder(-1) now also checks for disabled elements for the same reason (disabled parent causing children to not get a tab-order). Also setTabOrder(-1) now also checks for disabled elements for the same reason (disabled parent causing children to not get a tab-order).

View File

@ -51,6 +51,12 @@ namespace gui
//! Get the current value of the spinbox //! Get the current value of the spinbox
virtual f32 getValue() const = 0; virtual f32 getValue() const = 0;
//! Get the value the spinbox would have for the given text
/** Note: There is no rounding for decimal places going on here
The reason is that so far spinbox doesn't restrict entering longer
numbers (or any other text) (TODO)*/
virtual f32 getValueFor(const wchar_t* text) const = 0;
//! set the range of values which can be used in the spinbox //! set the range of values which can be used in the spinbox
/** \param min: minimum value /** \param min: minimum value
\param max: maximum value */ \param max: maximum value */
@ -68,7 +74,8 @@ namespace gui
virtual void setStepSize(f32 step=1.f) = 0; virtual void setStepSize(f32 step=1.f) = 0;
//! Sets the number of decimal places to display. //! Sets the number of decimal places to display.
//! Note that this also rounds the range to the same number of decimal places. //! Note: This also rounds the range to the same number of decimal places.
//! Note: This is only used for the buttons so far, text-input ignores it (TODO)
/** \param places: The number of decimal places to display, use -1 to reset */ /** \param places: The number of decimal places to display, use -1 to reset */
virtual void setDecimalPlaces(s32 places) = 0; virtual void setDecimalPlaces(s32 places) = 0;
@ -82,6 +89,12 @@ namespace gui
//! Gets when the spinbox has to validate entered text. //! Gets when the spinbox has to validate entered text.
/** \return A combination of EGUI_SPINBOX_VALIDATION bit flags */ /** \return A combination of EGUI_SPINBOX_VALIDATION bit flags */
virtual u32 getValidateOn() const = 0; virtual u32 getValidateOn() const = 0;
//! Gets previous value in EGET_SPINBOX_CHANGED events
/** Note: That value changes as soon as a new value is set (to the new value).
So it's only useful to check for last value in the event and has no use otherwise.
Also it's possible to mess it up by setting text via the editbox sub-element directly. */
virtual f32 getOldValue() const = 0;
}; };

View File

@ -23,7 +23,8 @@ CGUISpinBox::CGUISpinBox(const wchar_t* text, bool border,IGUIEnvironment* envir
: IGUISpinBox(environment, parent, id, rectangle), : IGUISpinBox(environment, parent, id, rectangle),
EditBox(0), ButtonSpinUp(0), ButtonSpinDown(0), StepSize(1.f), EditBox(0), ButtonSpinUp(0), ButtonSpinDown(0), StepSize(1.f),
RangeMin(-FLT_MAX), RangeMax(FLT_MAX), FormatString(L"%f"), RangeMin(-FLT_MAX), RangeMax(FLT_MAX), FormatString(L"%f"),
DecimalPlaces(-1), ValidateOn(EGUI_SBV_ENTER|EGUI_SBV_LOSE_FOCUS) DecimalPlaces(-1), ValidateOn(EGUI_SBV_ENTER|EGUI_SBV_LOSE_FOCUS),
OldValue(0.f)
{ {
#ifdef _DEBUG #ifdef _DEBUG
setDebugName("CGUISpinBox"); setDebugName("CGUISpinBox");
@ -55,6 +56,8 @@ CGUISpinBox::CGUISpinBox(const wchar_t* text, bool border,IGUIEnvironment* envir
EditBox->setAlignment(EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT); EditBox->setAlignment(EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT);
refreshSprites(); refreshSprites();
OldValue = getValue();
} }
@ -103,24 +106,28 @@ IGUIEditBox* CGUISpinBox::getEditBox() const
void CGUISpinBox::setValue(f32 val) void CGUISpinBox::setValue(f32 val)
{ {
wchar_t str[100]; OldValue = val;
wchar_t str[100];
swprintf_irr(str, 99, FormatString.c_str(), val); swprintf_irr(str, 99, FormatString.c_str(), val);
EditBox->setText(str); EditBox->setText(str);
verifyValueRange(); verifyValueRange(getValue());
} }
f32 CGUISpinBox::getValue() const f32 CGUISpinBox::getValue() const
{ {
const wchar_t* val = EditBox->getText(); return getValueFor(EditBox->getText());
}
f32 CGUISpinBox::getValueFor(const wchar_t* val) const
{
if ( !val ) if ( !val )
return 0.f; return 0.f;
core::stringc tmp(val); core::stringc tmp(val);
return core::fast_atof(tmp.c_str()); return core::fast_atof(tmp.c_str());
} }
void CGUISpinBox::setRange(f32 min, f32 max) void CGUISpinBox::setRange(f32 min, f32 max)
{ {
if (max<min) if (max<min)
@ -135,7 +142,7 @@ void CGUISpinBox::setRange(f32 min, f32 max)
swprintf_irr(str, 99, FormatString.c_str(), RangeMax); swprintf_irr(str, 99, FormatString.c_str(), RangeMax);
RangeMax = core::fast_atof(core::stringc(str).c_str()); RangeMax = core::fast_atof(core::stringc(str).c_str());
verifyValueRange(); verifyValueRange(getValue());
} }
@ -194,6 +201,7 @@ bool CGUISpinBox::OnEvent(const SEvent& event)
{ {
if (IsEnabled) if (IsEnabled)
{ {
f32 oldValue = OldValue;
bool changeEvent = false; bool changeEvent = false;
bool eatEvent = false; bool eatEvent = false;
switch(event.EventType) switch(event.EventType)
@ -240,7 +248,8 @@ bool CGUISpinBox::OnEvent(const SEvent& event)
|| (event.GUIEvent.EventType == EGET_ELEMENT_FOCUS_LOST && ValidateOn & EGUI_SBV_LOSE_FOCUS) || (event.GUIEvent.EventType == EGET_ELEMENT_FOCUS_LOST && ValidateOn & EGUI_SBV_LOSE_FOCUS)
) )
{ {
verifyValueRange(); OldValue = getValue(); // no call to setValue when text was changed without setText call
verifyValueRange(OldValue);
changeEvent = true; changeEvent = true;
} }
} }
@ -250,15 +259,19 @@ bool CGUISpinBox::OnEvent(const SEvent& event)
} }
if ( changeEvent ) if ( changeEvent )
{
if ( Parent )
{ {
SEvent e; SEvent e;
e.EventType = EET_GUI_EVENT; e.EventType = EET_GUI_EVENT;
e.GUIEvent.Caller = this; e.GUIEvent.Caller = this;
e.GUIEvent.Element = 0; e.GUIEvent.Element = 0;
e.GUIEvent.EventType = EGET_SPINBOX_CHANGED; e.GUIEvent.EventType = EGET_SPINBOX_CHANGED;
if ( Parent )
core::swap(oldValue, OldValue);
Parent->OnEvent(e); Parent->OnEvent(e);
core::swap(oldValue, OldValue);
}
if ( eatEvent ) if ( eatEvent )
return true; return true;
} }
@ -286,17 +299,12 @@ void CGUISpinBox::draw()
IGUISpinBox::draw(); IGUISpinBox::draw();
} }
void CGUISpinBox::verifyValueRange() void CGUISpinBox::verifyValueRange(f32 val)
{ {
f32 val = getValue();
if ( val+core::ROUNDING_ERROR_f32 < RangeMin ) if ( val+core::ROUNDING_ERROR_f32 < RangeMin )
val = RangeMin; setValue(RangeMin);
else if ( val-core::ROUNDING_ERROR_f32 > RangeMax ) else if ( val-core::ROUNDING_ERROR_f32 > RangeMax )
val = RangeMax; setValue(RangeMax);
else
return;
setValue(val);
} }
@ -305,7 +313,6 @@ void CGUISpinBox::setText(const wchar_t* text)
{ {
EditBox->setText(text); EditBox->setText(text);
setValue(getValue()); setValue(getValue());
verifyValueRange();
} }

View File

@ -41,6 +41,9 @@ namespace gui
//! Get the current value of the spinbox //! Get the current value of the spinbox
virtual f32 getValue() const IRR_OVERRIDE; virtual f32 getValue() const IRR_OVERRIDE;
//! Get the value the spinbox would have for the given text
virtual f32 getValueFor(const wchar_t* text) const IRR_OVERRIDE;
//! set the range of values which can be used in the spinbox //! set the range of values which can be used in the spinbox
/** \param min: minimum value /** \param min: minimum value
\param max: maximum value */ \param max: maximum value */
@ -83,6 +86,12 @@ namespace gui
//! Gets when the spinbox has to validate entered text. //! Gets when the spinbox has to validate entered text.
virtual u32 getValidateOn() const IRR_OVERRIDE; virtual u32 getValidateOn() const IRR_OVERRIDE;
//! Gets previous value in EGET_SPINBOX_CHANGED events
virtual f32 getOldValue() const IRR_OVERRIDE
{
return OldValue;
}
//! Writes attributes of the element. //! Writes attributes of the element.
virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const IRR_OVERRIDE; virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const IRR_OVERRIDE;
@ -90,7 +99,7 @@ namespace gui
virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options) IRR_OVERRIDE; virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options) IRR_OVERRIDE;
protected: protected:
virtual void verifyValueRange(); void verifyValueRange(f32 val);
void refreshSprites(); void refreshSprites();
IGUIEditBox * EditBox; IGUIEditBox * EditBox;
@ -104,6 +113,7 @@ namespace gui
core::stringw FormatString; core::stringw FormatString;
s32 DecimalPlaces; s32 DecimalPlaces;
u32 ValidateOn; // combination of EGUI_SPINBOX_VALIDATION bit-flags u32 ValidateOn; // combination of EGUI_SPINBOX_VALIDATION bit-flags
f32 OldValue;
}; };