#include "my_slider.hpp" #include #include #include 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"); } std::vector 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); update_log_data(); if (min_value <= max_value) { if (logarithmic) { slider.set_range(log_data.x0, log_data.x1); } else { slider.set_range(min_value, max_value); } } 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); if (force || text_editing) { update_slider(value); } if (force || !text_editing) { update_text_entry(value_str); } update_occurring = false; } 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); } void MySlider::set_logarithmic(bool value) { logarithmic = true; update_log_data(); } bool MySlider::get_logarithmic() { return logarithmic; } double MySlider::unscale_log(double input) { return (exp(value) / log_data.b) - log_data.a; } void MySlider::set_value(double value, bool force) { this->value = value; 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; 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) { 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; update_log_data(); } double MySlider::get_max_value() { return max_value; } void MySlider::set_max_value(double value) { max_value = value; update_log_data(); } MySlider::MySlider() { 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); value_label.set_css_classes({"value-label"}); value_label.insert_at_end(*this); 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); suffix_label.set_css_classes({"suffix-label"}); suffix_label.insert_at_end(*this); slider.insert_at_end(*this); edit_btn.insert_at_end(*this); edit_btn.set_css_classes({"edit-btn"}); edit_btn.signal_clicked().connect([this]() { update(); text_editing = !text_editing; update(); }); 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(); }); slider.signal_value_changed().connect([this]() { if (get_logarithmic()) { value = unscale_log(slider.get_value()); } else { value = slider.get_value(); } value_changed.emit(value); update(); }); update(true); }