Исходник Animated slider // supremacy c+p ready

Начинающий
Начинающий
Статус
Оффлайн
Регистрация
15 Окт 2019
Сообщения
45
Реакции
8
slider.h:
Expand Collapse Copy
#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:
Expand Collapse Copy
#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);
}
 
Назад
Сверху Снизу