looper/backends/ui/gtk/my_slider.cpp

173 lines
4.8 KiB
C++
Raw Normal View History

#include "my_slider.hpp"
#include <sstream>
#include <iomanip>
#include <util.hpp>
double MySlider::get_value() {
return value;
}
void MySlider::update(bool force) {
if (update_occurring) {
return;
}
update_occurring = true;
std::string value_str = to_string_with_decimals(value, digits_after_decimal);
try {
value = std::stod(value_str);
} catch (std::out_of_range) {
} catch (std::invalid_argument) {
}
if (text_editing) {
edit_btn.set_icon_name("document-save-symbolic");
} else {
edit_btn.set_icon_name("edit-symbolic");
}
2024-03-26 18:39:02 -07:00
std::vector<Glib::ustring> classes;
classes.push_back("precise-slider");
if (text_editing) {
classes.push_back("text-editing");
}
if (get_hexpand()) {
classes.push_back("hexpand");
}
set_css_classes(classes);
2024-05-01 09:07:08 -07:00
update_log_data();
2024-03-26 18:39:02 -07:00
if (min_value <= max_value) {
2024-05-01 09:07:08 -07:00
if (logarithmic) {
slider.set_range(log_data.x0, log_data.x1);
} else {
slider.set_range(min_value, max_value);
}
2024-03-26 18:39:02 -07:00
}
prefix_label.set_text(prefix);
value_label.set_text(value_str.c_str());
suffix_label.set_text(suffix);
text_entry.set_visible(text_editing);
value_label.set_visible(!text_editing);
slider.set_visible(!text_editing);
2024-03-26 18:39:02 -07:00
if (force || text_editing) {
update_slider(value);
}
if (force || !text_editing) {
update_text_entry(value_str);
}
update_occurring = false;
}
2024-05-01 09:07:08 -07:00
double MySlider::scale_log(double input) {
return log_data.a + (log_data.b * log(value));
}
void MySlider::update_log_data() {
log_data.xmin = min_value;
log_data.xmax = max_value;
log_data.x0 = log(log_data.xmin);
log_data.x1 = log(log_data.xmax);
log_data.b = (log_data.x1 - log_data.x0) / log(log_data.xmax - log_data.xmin);
log_data.a = log_data.x0 - (log_data.b * log_data.x0);
}
double MySlider::unscale_log(double input) {
return (exp(value) / log_data.b) - log_data.a;
}
2024-03-26 18:39:02 -07:00
void MySlider::set_value(double value, bool force) {
this->value = value;
2024-03-26 18:39:02 -07:00
update(force);
}
Glib::ustring MySlider::get_prefix() {
return prefix;
}
void MySlider::set_prefix(Glib::ustring value) {
prefix = value;
}
Glib::ustring MySlider::get_suffix() {
return suffix;
}
void MySlider::set_suffix(Glib::ustring value) {
suffix = value;
}
unsigned MySlider::get_digits_after_decimal() {
return digits_after_decimal;
}
void MySlider::set_digits_after_decimal(unsigned value) {
digits_after_decimal = value;
2024-03-26 18:39:02 -07:00
slider.set_digits(digits_after_decimal);
}
void MySlider::update_text_entry(std::string text) {
text_entry.delete_text(0, text_entry.get_text_length());
int pos = 0;
text_entry.insert_text(text.c_str(), text.size(), pos);
}
void MySlider::update_slider(double value) {
2024-05-01 09:07:08 -07:00
if (logarithmic) {
slider.set_value(scale_log(value));
}
}
double MySlider::get_min_value() {
return min_value;
}
void MySlider::set_min_value(double value) {
min_value = value;
2024-05-01 09:07:08 -07:00
update_log_data();
}
double MySlider::get_max_value() {
return max_value;
}
void MySlider::set_max_value(double value) {
max_value = value;
2024-05-01 09:07:08 -07:00
update_log_data();
}
MySlider::MySlider() {
2024-03-26 18:39:02 -07:00
min_value = 0;
max_value = 1;
value = 0;
text_valid = false;
text_editing = false;
update_occurring = false;
prefix = "";
suffix = "";
digits_after_decimal = 0;
prefix_label.set_css_classes({"prefix-label"});
prefix_label.insert_at_end(*this);
2024-03-26 18:39:02 -07:00
value_label.set_css_classes({"value-label"});
value_label.insert_at_end(*this);
2024-03-26 18:39:02 -07:00
slider.set_css_classes({"imprecise-slider"});
text_entry.set_css_classes({"precise-number-editor"});
slider.set_hexpand();
slider.set_size_request(100);
text_entry.set_hexpand();
text_entry.insert_at_end(*this);
2024-03-26 18:39:02 -07:00
suffix_label.set_css_classes({"suffix-label"});
suffix_label.insert_at_end(*this);
2024-03-26 18:39:02 -07:00
slider.insert_at_end(*this);
edit_btn.insert_at_end(*this);
2024-03-26 18:39:02 -07:00
edit_btn.set_css_classes({"edit-btn"});
edit_btn.signal_clicked().connect([this]() {
update();
text_editing = !text_editing;
update();
});
2024-03-26 18:39:02 -07:00
text_entry.property_width_chars().set_value(0);
text_entry.signal_changed().connect([this]() {
try {
value = std::stod(text_entry.get_text().c_str());
text_valid = true;
} catch(std::out_of_range) {
text_valid = false;
} catch (std::invalid_argument) {
text_valid = false;
}
if (text_valid) {
value_changed.emit(value);
}
update();
});
2024-03-26 18:39:02 -07:00
slider.signal_value_changed().connect([this]() {
2024-05-01 09:07:08 -07:00
if (get_logarithmic()) {
value = unscale_log(slider.get_value());
} else {
value = slider.get_value();
}
value_changed.emit(value);
update();
});
2024-03-26 18:39:02 -07:00
update(true);
}