mirror of
https://github.com/BanjoRecomp/BanjoRecomp
synced 2026-06-11 12:39:51 -04:00
Initial boot
This commit is contained in:
@@ -0,0 +1,145 @@
|
||||
#include "ui_slider.h"
|
||||
|
||||
#include <cmath>
|
||||
#include <charconv>
|
||||
|
||||
namespace recompui {
|
||||
|
||||
void Slider::set_value_internal(double v, bool setup, bool trigger_callbacks) {
|
||||
if (step_value != 0.0) {
|
||||
v = std::lround(v / step_value) * step_value;
|
||||
}
|
||||
|
||||
if (value != v || setup) {
|
||||
value = v;
|
||||
update_circle_position();
|
||||
update_label_text();
|
||||
|
||||
if (trigger_callbacks) {
|
||||
for (auto callback : value_changed_callbacks) {
|
||||
callback(v);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Slider::bar_clicked(float x, float) {
|
||||
update_value_from_mouse(x);
|
||||
}
|
||||
|
||||
void Slider::bar_dragged(float x, float, DragPhase) {
|
||||
update_value_from_mouse(x);
|
||||
}
|
||||
|
||||
void Slider::circle_dragged(float x, float, DragPhase) {
|
||||
update_value_from_mouse(x);
|
||||
}
|
||||
|
||||
void Slider::update_value_from_mouse(float x) {
|
||||
double left = slider_element->get_absolute_left();
|
||||
double width = slider_element->get_client_width();
|
||||
double ratio = std::clamp((x - left) / width, 0.0, 1.0);
|
||||
set_value_internal(min_value + ratio * (max_value - min_value), false, true);
|
||||
}
|
||||
|
||||
void Slider::update_circle_position() {
|
||||
double ratio = std::clamp((value - min_value) / (max_value - min_value), 0.0, 1.0);
|
||||
circle_element->set_left(slider_width_dp * ratio);
|
||||
}
|
||||
|
||||
void Slider::update_label_text() {
|
||||
char text_buffer[32];
|
||||
int precision = type == SliderType::Double ? 1 : 0;
|
||||
auto result = std::to_chars(text_buffer, text_buffer + sizeof(text_buffer) - 1, value, std::chars_format::fixed, precision);
|
||||
if (result.ec == std::errc()) {
|
||||
if (type == SliderType::Percent) {
|
||||
*result.ptr = '%';
|
||||
result.ptr++;
|
||||
}
|
||||
|
||||
value_label->set_text(std::string(text_buffer, result.ptr));
|
||||
}
|
||||
}
|
||||
|
||||
Slider::Slider(Element *parent, SliderType type) : Element(parent) {
|
||||
this->type = type;
|
||||
|
||||
set_display(Display::Flex);
|
||||
set_flex(1.0f, 1.0f, 100.0f, Unit::Percent);
|
||||
set_flex_direction(FlexDirection::Row);
|
||||
|
||||
ContextId context = get_current_context();
|
||||
|
||||
value_label = context.create_element<Label>(this, "0", LabelStyle::Small);
|
||||
value_label->set_margin_right(20.0f);
|
||||
value_label->set_min_width(60.0f);
|
||||
value_label->set_max_width(60.0f);
|
||||
|
||||
slider_element = context.create_element<Element>(this);
|
||||
slider_element->set_width(slider_width_dp);
|
||||
|
||||
{
|
||||
bar_element = context.create_element<Clickable>(slider_element, true);
|
||||
bar_element->set_width(100.0f, Unit::Percent);
|
||||
bar_element->set_height(2.0f);
|
||||
bar_element->set_margin_top(8.0f);
|
||||
bar_element->set_background_color(Color{ 255, 255, 255, 50 });
|
||||
bar_element->add_pressed_callback(std::bind(&Slider::bar_clicked, this, std::placeholders::_1, std::placeholders::_2));
|
||||
bar_element->add_dragged_callback(std::bind(&Slider::bar_dragged, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
|
||||
|
||||
circle_element = context.create_element<Clickable>(slider_element, true);
|
||||
circle_element->set_position(Position::Relative);
|
||||
circle_element->set_width(16.0f);
|
||||
circle_element->set_height(16.0f);
|
||||
circle_element->set_margin_top(-8.0f);
|
||||
circle_element->set_margin_right(-8.0f);
|
||||
circle_element->set_margin_left(-8.0f);
|
||||
circle_element->set_background_color(Color{ 204, 204, 204, 255 });
|
||||
circle_element->set_border_radius(8.0f);
|
||||
circle_element->add_dragged_callback(std::bind(&Slider::circle_dragged, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
|
||||
circle_element->set_cursor(Cursor::Pointer);
|
||||
}
|
||||
|
||||
set_value_internal(value, true, false);
|
||||
}
|
||||
|
||||
Slider::~Slider() {
|
||||
|
||||
}
|
||||
|
||||
void Slider::set_value(double v) {
|
||||
set_value_internal(v, false, false);
|
||||
}
|
||||
|
||||
double Slider::get_value() const {
|
||||
return value;
|
||||
}
|
||||
void Slider::set_min_value(double v) {
|
||||
min_value = v;
|
||||
}
|
||||
|
||||
double Slider::get_min_value() const {
|
||||
return min_value;
|
||||
}
|
||||
|
||||
void Slider::set_max_value(double v) {
|
||||
max_value = v;
|
||||
}
|
||||
|
||||
double Slider::get_max_value() const {
|
||||
return max_value;
|
||||
}
|
||||
|
||||
void Slider::set_step_value(double v) {
|
||||
step_value = v;
|
||||
}
|
||||
|
||||
double Slider::get_step_value() const {
|
||||
return step_value;
|
||||
}
|
||||
|
||||
void Slider::add_value_changed_callback(std::function<void(double)> callback) {
|
||||
value_changed_callbacks.emplace_back(callback);
|
||||
}
|
||||
|
||||
} // namespace recompui
|
||||
Reference in New Issue
Block a user