Начинающий
- Статус
- Оффлайн
- Регистрация
- 15 Окт 2019
- Сообщения
- 45
- Реакции
- 8
slider.h:
#pragma once
#define SLIDER_X_OFFSET 20
#define SLIDER_HEIGHT 8
class Slider : public Element {
public:
__forceinline Slider() : m_drag{false}, m_value{}, m_min{}, m_max{}, m_step{}, m_fill{}, m_precision{}, m_label{}, m_suffix{}, m_offset{} {
m_flags = DRAW | CLICK | SAVE;
m_type = SLIDER;
m_show = true;
}
__forceinline void setup(const std::string& label, const std::string& file_id, float min, float max,
bool use_label = true, int precision = 0, float value = 0.f, float step = 1.f, const std::wstring& suffix = L"") {
m_file_id = file_id;
m_use_label = use_label;
if (m_use_label)
m_label = label;
m_offset = m_use_label ? 15 : 0;
m_h = m_offset + SLIDER_HEIGHT;
m_base_h = m_h;
m_min = min;
m_max = max;
m_value = value;
m_precision = precision;
m_step = step;
m_suffix = suffix;
}
__forceinline void set(float value) {
bool changed = value != m_value;
// set new value
m_value = value;
// clamp the value.
math::clamp(m_value, m_min, m_max);
if (changed && m_callback)
m_callback();
}
__forceinline float get() {
return m_value;
}
protected:
bool m_drag;
float m_value;
float m_min;
float m_max;
float m_step;
float m_fill_anim;
int m_fill;
int m_precision;
std::string m_label;
std::wstring m_suffix;
int m_offset;
void draw() override;
void think() override;
void click() override;
};
slider.cpp:
#include "../../../includes.h"
void Slider::draw() {
Rect area{ m_parent->GetElementsRect() };
Point p{ area.x + m_pos.x, area.y + m_pos.y };
// get gui color.
Color color = g_gui.m_color;
color.a() = m_parent->m_alpha;
// draw label.
if (m_use_label)
render::menu.string(p.x + LABEL_OFFSET, p.y - 2, { 205, 205, 205, m_parent->m_alpha }, m_label);
// outline.
render::rect(p.x + SLIDER_X_OFFSET, p.y + m_offset, m_w - SLIDER_X_OFFSET, SLIDER_HEIGHT, { 0, 0, 0, m_parent->m_alpha });
// background.
render::gradient(p.x + SLIDER_X_OFFSET + 1, p.y + m_offset + 1, m_w - SLIDER_X_OFFSET - 2, SLIDER_HEIGHT - 2, { 75, 75, 75, m_parent->m_alpha }, { 50, 50, 50, m_parent->m_alpha });
// animate the fill.
m_fill_anim = math::interp(m_fill_anim, (float)m_fill, g_csgo.m_globals->m_frametime * 8.f);
// snap to target if close enough to prevent jitter.
if (std::abs(m_fill_anim - (float)m_fill) < 0.5f)
m_fill_anim = (float)m_fill;
// bar.
render::rect_filled(p.x + SLIDER_X_OFFSET + 1, p.y + m_offset + 1, m_fill_anim - 2, SLIDER_HEIGHT - 2, color);
render::rect_filled_fade(p.x + SLIDER_X_OFFSET + 1, p.y + m_offset + 1, m_fill_anim - 2, SLIDER_HEIGHT - 2, { 50, 50, 35, m_parent->m_alpha }, 0, 150);
// to stringstream.
std::wstringstream ss;
ss << std::fixed << std::setprecision(m_precision) << m_value << m_suffix;
// get size.
render::FontSize_t size = render::menu.wsize(ss.str());
// draw value.
render::menu.wstring(p.x + SLIDER_X_OFFSET + m_fill_anim - size.m_width / 2, p.y + m_offset + 1, { 255, 255, 255, m_parent->m_alpha }, ss.str());
}
void Slider::think() {
Rect area{ m_parent->GetElementsRect() };
Point p{ area.x + m_pos.x, area.y + m_pos.y };
// how many steps do we have?
float steps = (m_max - m_min) / m_step;
// compute the amount of pixels for one step.
float pixels = (m_w - SLIDER_X_OFFSET) / steps;
// clamp the current value.
math::clamp(m_value, m_min, m_max);
// compute the fill ratio.
m_fill = (int)std::floor(std::max((m_value - m_min) / m_step * pixels, 0.f));
// we are draggin this mofo!
if (m_drag) {
// left mouse is still down.
if (g_input.GetKeyState(VK_LBUTTON)) {
// compute the new value.
float updated = m_min + (g_input.m_mouse.x - SLIDER_X_OFFSET - p.x) / pixels * m_step;
// set updated value to closest step.
float remainder = std::fmod(updated, m_step);
if (remainder > m_step / 2)
updated += m_step - remainder;
else
updated -= remainder;
m_value = updated;
// clamp the value.
math::clamp(m_value, m_min, m_max);
if (m_callback)
m_callback();
}
// left mouse has been released.
else
m_drag = false;
}
}
void Slider::click() {
Rect area{ m_parent->GetElementsRect() };
Point p{ area.x + m_pos.x, area.y + m_pos.y };
// get slider area.
Rect slider{ p.x + SLIDER_X_OFFSET, p.y + m_offset, m_w - SLIDER_X_OFFSET, SLIDER_HEIGHT };
// detect dragging.
if (g_input.IsCursorInRect(slider))
m_drag = true;
// clamp the updated value.
math::clamp(m_value, m_min, m_max);
}