Index: binaries/data/mods/mod/gui/gui.rnc =================================================================== --- binaries/data/mods/mod/gui/gui.rnc +++ binaries/data/mods/mod/gui/gui.rnc @@ -99,6 +99,7 @@ attribute sprite2_pressed { text }?& attribute sprite_selectarea { text }?& attribute square_side { xsd:decimal }?& + attribute steps { xsd:nonNegativeInteger }?& attribute textcolor { ccolor }?& attribute textcolor_disabled { ccolor }?& attribute textcolor_over { ccolor }?& Index: binaries/data/mods/mod/gui/gui.rng =================================================================== --- binaries/data/mods/mod/gui/gui.rng +++ binaries/data/mods/mod/gui/gui.rng @@ -380,6 +380,11 @@ + + + + + Index: source/gui/CSlider.h =================================================================== --- source/gui/CSlider.h +++ source/gui/CSlider.h @@ -46,6 +46,7 @@ CRect GetButtonRect(); float m_MinValue, m_MaxValue, m_Value; + int m_Steps, m_Step; private: bool m_IsPressed; @@ -53,6 +54,8 @@ CPos m_Mouse; float m_ButtonSide; + float m_OldValue; + int m_OldStep; }; #endif // INCLUDED_CSLIDER Index: source/gui/CSlider.cpp =================================================================== --- source/gui/CSlider.cpp +++ source/gui/CSlider.cpp @@ -23,7 +23,7 @@ CSlider::CSlider() - : m_IsPressed(false), m_ButtonSide(0) + : m_IsPressed(false), m_ButtonSide(0.f), m_Steps(0), m_Step(0) { AddSetting(GUIST_float, "value"); AddSetting(GUIST_float, "min_value"); @@ -32,12 +32,26 @@ AddSetting(GUIST_CGUISpriteInstance, "sprite"); AddSetting(GUIST_CGUISpriteInstance, "sprite_bar"); AddSetting(GUIST_float, "button_width"); + AddSetting(GUIST_int, "step"); + AddSetting(GUIST_int, "steps"); - GUI::GetSetting(this, "value", m_Value); + GUI::GetSetting(this, "button_width", m_ButtonSide); GUI::GetSetting(this, "min_value", m_MinValue); GUI::GetSetting(this, "max_value", m_MaxValue); - GUI::GetSetting(this, "button_width", m_ButtonSide); - m_Value = Clamp(m_Value, m_MinValue, m_MaxValue); + GUI::GetSetting(this, "steps", m_Steps); + if (m_Steps < 0) + m_Steps = 0; + if (m_Steps > 0) + { + GUI::GetSetting(this, "step", m_Step); + m_Step = Clamp(m_Step, 0, m_Steps); + m_Value = m_MinValue + (m_MaxValue - m_MinValue) / (m_Steps + 1) * m_Step; + } + else + { + GUI::GetSetting(this, "value", m_Value); + m_Value = Clamp(m_Value, m_MinValue, m_MaxValue); + } } CSlider::~CSlider() @@ -50,18 +64,33 @@ { case GUIM_SETTINGS_UPDATED: { + GUI::GetSetting(this, "button_width", m_ButtonSide); GUI::GetSetting(this, "value", m_Value); GUI::GetSetting(this, "min_value", m_MinValue); GUI::GetSetting(this, "max_value", m_MaxValue); - GUI::GetSetting(this, "button_width", m_ButtonSide); m_Value = Clamp(m_Value, m_MinValue, m_MaxValue); + GUI::GetSetting(this, "steps", m_Steps); + if (m_Steps < 0) + m_Steps = 0; + if (m_Steps > 0) + { + m_Step = round(m_Value * (m_Steps + 1) / (m_MaxValue - m_MinValue)); + m_Step = Clamp(m_Step, 0, m_Steps); + m_Value = m_MinValue + (m_MaxValue - m_MinValue) / (m_Steps + 1) * m_Step; + } break; } case GUIM_MOUSE_WHEEL_DOWN: { if (m_IsPressed) break; - m_Value = std::max(m_Value - 0.01f, m_MinValue); + if (!m_Steps) + m_Value = std::max(m_Value - 0.01f, m_MinValue); + else + { + m_Step = std::min(m_Step + 1, m_Steps); + m_Value = m_MinValue + (m_MaxValue - m_MinValue) / (m_Steps + 1) * m_Step; + } UpdateValue(); break; } @@ -69,7 +98,26 @@ { if (m_IsPressed) break; - m_Value = std::min(m_Value + 0.01f, m_MaxValue); + if (!m_Steps) + m_Value = std::min(m_Value + m_Step, m_MaxValue); + else + { + m_Step = std::max(m_Step - 1, 0); + m_Value = m_MinValue + (m_MaxValue - m_MinValue) / (m_Steps + 1) * m_Step; + } + UpdateValue(); + break; + } + case GUIM_MOUSE_DBLCLICK_LEFT: + { + m_IsPressed = false; + if (!m_Steps) + m_Value = (m_MaxValue + m_MinValue) / 2.f; + else + { + m_Step = m_Steps / 2; + m_Value = m_MinValue + (m_MaxValue - m_MinValue) / (m_Steps + 1) * m_Step; + } UpdateValue(); break; } @@ -78,6 +126,10 @@ if (GetButtonRect().PointInside(GetMousePos())) { m_Mouse = GetMousePos(); + if (!m_Steps) + m_OldValue = m_Value; + else + m_OldStep = m_Step; m_IsPressed = true; } break; @@ -93,10 +145,18 @@ m_IsPressed = false; if (m_IsPressed) { - float ratio = (m_MaxValue - m_MinValue) / (m_CachedActualSize.GetWidth() - m_ButtonSide); - float difference = float(GetMousePos().x - m_Mouse.x) * ratio; - m_Mouse = GetMousePos(); - m_Value = Clamp(m_Value + difference, m_MinValue, m_MaxValue); + float difference = float(GetMousePos().x - m_Mouse.x); + if (!m_Steps) + { + float ratio = (m_MaxValue - m_MinValue) / (m_CachedActualSize.GetWidth() - m_ButtonSide); + m_Value = Clamp(m_OldValue + difference * ratio, m_MinValue, m_MaxValue); + } + else + { + float step_length = (m_CachedActualSize.GetWidth() - m_ButtonSide) / (m_Steps + 1); + m_Step = Clamp(m_OldStep + int(std::round(difference / step_length)), 0, m_Steps); + m_Value = m_MinValue + (m_MaxValue - m_MinValue) / (m_Steps + 1) * m_Step; + } UpdateValue(); } break; @@ -127,8 +187,9 @@ } void CSlider::UpdateValue() -{ +{ GUI::SetSetting(this, "value", m_Value); + GUI::SetSetting(this, "step", m_Step); ScriptEvent("valuechange"); }