Index: ps/trunk/source/gui/CSlider.cpp =================================================================== --- ps/trunk/source/gui/CSlider.cpp (revision 22163) +++ ps/trunk/source/gui/CSlider.cpp (revision 22164) @@ -1,141 +1,147 @@ -/* Copyright (C) 2017 Wildfire Games. +/* Copyright (C) 2019 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * 0 A.D. is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with 0 A.D. If not, see . */ #include "precompiled.h" #include "CSlider.h" #include "GUI.h" #include "lib/ogl.h" #include "ps/CLogger.h" CSlider::CSlider() : m_IsPressed(false), m_ButtonSide(0) { AddSetting(GUIST_float, "value"); AddSetting(GUIST_float, "min_value"); AddSetting(GUIST_float, "max_value"); AddSetting(GUIST_int, "cell_id"); AddSetting(GUIST_CGUISpriteInstance, "sprite"); AddSetting(GUIST_CGUISpriteInstance, "sprite_bar"); AddSetting(GUIST_float, "button_width"); 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); } CSlider::~CSlider() { } +float CSlider::GetSliderRatio() const +{ + return (m_MaxValue - m_MinValue) / (m_CachedActualSize.GetWidth() - m_ButtonSide); +} + +void CSlider::IncrementallyChangeValue(const float difference) +{ + m_Value = Clamp(m_Value + difference, m_MinValue, m_MaxValue); + UpdateValue(); +} + void CSlider::HandleMessage(SGUIMessage& Message) { switch (Message.type) { case GUIM_SETTINGS_UPDATED: { 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); break; } case GUIM_MOUSE_WHEEL_DOWN: { if (m_IsPressed) break; - m_Value = std::max(m_Value - 0.01f, m_MinValue); - UpdateValue(); + IncrementallyChangeValue(-0.01f); break; } case GUIM_MOUSE_WHEEL_UP: { if (m_IsPressed) break; - m_Value = std::min(m_Value + 0.01f, m_MaxValue); - UpdateValue(); + IncrementallyChangeValue(0.01f); break; } case GUIM_MOUSE_PRESS_LEFT: { - if (GetButtonRect().PointInside(GetMousePos())) - { - m_Mouse = GetMousePos(); - m_IsPressed = true; - } + m_Mouse = GetMousePos(); + m_IsPressed = true; + + IncrementallyChangeValue((m_Mouse.x - GetButtonRect().CenterPoint().x) * GetSliderRatio()); break; } case GUIM_MOUSE_RELEASE_LEFT: { m_IsPressed = false; break; } case GUIM_MOUSE_MOTION: { if (!MouseOver()) 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; + float difference = float(GetMousePos().x - m_Mouse.x) * GetSliderRatio(); m_Mouse = GetMousePos(); - m_Value = Clamp(m_Value + difference, m_MinValue, m_MaxValue); - UpdateValue(); + IncrementallyChangeValue(difference); } break; } default: break; } } void CSlider::Draw() { if (!GetGUI()) return; CGUISpriteInstance* sprite; CGUISpriteInstance* sprite_button; int cell_id; GUI::GetSettingPointer(this, "sprite_bar", sprite); GUI::GetSettingPointer(this, "sprite", sprite_button); GUI::GetSetting(this, "cell_id", cell_id); CRect slider_line(m_CachedActualSize); slider_line.left += m_ButtonSide / 2.0f; slider_line.right -= m_ButtonSide / 2.0f; float bz = GetBufferedZ(); GetGUI()->DrawSprite(*sprite, cell_id, bz, slider_line); GetGUI()->DrawSprite(*sprite_button, cell_id, bz, GetButtonRect()); } void CSlider::UpdateValue() -{ +{ GUI::SetSetting(this, "value", m_Value); ScriptEvent("valuechange"); } CRect CSlider::GetButtonRect() { float ratio = m_MaxValue > m_MinValue ? (m_Value - m_MinValue) / (m_MaxValue - m_MinValue) : 0.0f; float x = m_CachedActualSize.left + ratio * (m_CachedActualSize.GetWidth() - m_ButtonSide); float y = m_CachedActualSize.top + (m_CachedActualSize.GetHeight() - m_ButtonSide) / 2.0; return CRect(x, y, x + m_ButtonSide, y + m_ButtonSide); } Index: ps/trunk/source/gui/CSlider.h =================================================================== --- ps/trunk/source/gui/CSlider.h (revision 22163) +++ ps/trunk/source/gui/CSlider.h (revision 22164) @@ -1,58 +1,65 @@ -/* Copyright (C) 2017 Wildfire Games. +/* Copyright (C) 2019 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * 0 A.D. is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with 0 A.D. If not, see . */ #ifndef INCLUDED_CSLIDER #define INCLUDED_CSLIDER #include "GUI.h" class CSlider : public IGUIObject { GUI_OBJECT(CSlider) public: CSlider(); virtual ~CSlider(); protected: /** * @see IGUIObject#HandleMessage() */ virtual void HandleMessage(SGUIMessage& Message); virtual void Draw(); /** * Change settings and send the script event */ void UpdateValue(); CRect GetButtonRect(); + /** + * @return ratio between the value of the slider and its actual size in the GUI + */ + float GetSliderRatio() const; + + void IncrementallyChangeValue(const float value); + float m_MinValue, m_MaxValue, m_Value; private: bool m_IsPressed; CPos m_Mouse; float m_ButtonSide; }; #endif // INCLUDED_CSLIDER