173 lines
No EOL
4.8 KiB
C++
173 lines
No EOL
4.8 KiB
C++
#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");
|
|
}
|
|
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);
|
|
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);
|
|
}
|
|
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);
|
|
} |