looper/backends/ui/qt/slider.cpp

278 lines
7.9 KiB
C++
Raw Permalink Normal View History

2024-11-20 08:15:45 -08:00
#include "slider.hpp"
LooperSlider::LooperSlider(const char *name, const char *label, double min, double max, double tick, bool logarithmic) : QWidget() {
root_layout = new QBoxLayout(QBoxLayout::LeftToRight, this);
text_layout_view = new QBoxLayout(QBoxLayout::TopToBottom);
QWidget *text_layout_widget = new QWidget();
text_layout_widget->setLayout(text_layout_view);
root_layout->addWidget(text_layout_widget);
text_label = new QLabel();
slider = new _looperSlider(Qt::Orientation::Horizontal);
slider->connect(slider, &_looperSlider::mousePressed, [=,this]() {
pressed = true;
slider_value_changed_after_release = false;
emit(mousePressed());
});
slider->connect(slider, &_looperSlider::mouseReleased, [=,this]() {
emit(mouseReleased());
pressed = false;
});
slider->connect(slider, &QSlider::valueChanged, [=,this](int value) {
if (slider_value_updating) return;
double actual_value = value * tick;
if (logarithmic) actual_value = scaler->unscale_log(actual_value);
this->SetValue(actual_value);
emit(changed(actual_value));
slider_value_changed_after_release = true;
});
text_layout_view->addWidget(slider);
btn = new QPushButton();
btn->connect(btn, &QPushButton::pressed, [=,this]() {
SwitchModes();
});
root_layout->addWidget(btn);
text = new QLineEdit();
text->setVisible(false);
text_layout_view->addWidget(text);
text->connect(text, &QLineEdit::textChanged, [=,this]() {
const char *value = text->text().toLocal8Bit().constData();
bool ok = true;
double output = this->Value();
try {
output = std::stod(value);
} catch (std::exception) {
ok = false;
}
if (ok) {
textChanged = true;
emit(changed(output));
this->SetValue(output);
}
});
limits_view = new QBoxLayout(QBoxLayout::LeftToRight);
min_label_view = new QLabel();
limits_view->addWidget(min_label_view, 0, Qt::Alignment::enum_type::AlignLeft);
max_label_view = new QLabel();
limits_view->addWidget(max_label_view, 0, Qt::Alignment::enum_type::AlignRight);
scaler = new LooperLogScaler(min, max);
set_min(min);
set_max(max);
set_tick(tick);
set_logarithmic(logarithmic);
this->label = strdup(label);
this->value = min;
UpdateSlider(true);
}
bool LooperSlider::IsPressed() {
return pressed;
}
double LooperSlider::Value() {
return value;
}
void LooperSlider::set_value(double value) {
if (!pressed && slider_value_changed_after_release) this->value = value;
this->UpdateSlider(true);
}
void LooperSlider::SetValue(double value) {
set_value(value);
}
void LooperSlider::set_min(double min) {
settings_changed = true;
this->min = min;
}
void LooperSlider::set_max(double max) {
settings_changed = true;
this->max = max;
}
void LooperSlider::set_logarithmic(bool logarithmic) {
settings_changed = true;
this->logarithmic = true;
}
void LooperSlider::UpdateLogScaler() {
this->scaler->update_min_max(this->min, this->max);
}
void LooperSlider::SetMin(double min) {
this->set_min(min);
UpdateSlider(false);
}
void LooperSlider::SetMax(double max) {
this->set_max(max);
UpdateSlider(false);
}
double LooperSlider::Min() {
return this->min;
}
double LooperSlider::Max() {
return this->max;
}
void LooperSlider::SetLimits(double min, double max) {
set_min(min);
set_max(max);
UpdateSlider(false);
}
void LooperSlider::SetMinLabel(const char *label) {
if (this->min_label) free((void*)this->min_label);
this->min_label = strdup(label);
UpdateSlider();
}
void LooperSlider::SetMaxLabel(const char *label) {
if (this->max_label) free((void*)this->max_label);
this->max_label = strdup(label);
UpdateSlider();
}
void LooperSlider::SetLimitLabels(const char *min, const char *max) {
SetMinLabel(min);
SetMaxLabel(max);
}
LooperSlider::~LooperSlider() {
if (this->min_label) free((void*)this->min_label);
if (this->max_label) free((void*)this->max_label);
if (this->label) free((void*)this->label);
}
const char *LooperSlider::MinLabel() {
return this->min_label;
}
const char *LooperSlider::MaxLabel() {
return this->max_label;
}
void LooperSlider::SetLogarithmic(bool logarithmic) {
set_logarithmic(logarithmic);
UpdateSlider(false);
}
bool LooperSlider::IsLogarithmic() {
return this->logarithmic;
}
void LooperSlider::SetLabel(const char *label) {
if (this->label) free((void*)this->label);
this->label = strdup(label);
}
const char *LooperSlider::Label() {
return this->label;
}
double LooperSlider::Tick() {
return this->tick;
}
void LooperSlider::SetMode(bool use_text_editor) {
this->text_edit_mode = use_text_editor;
UpdateSlider(true);
}
void LooperSlider::EnableModeButton(bool enabled) {
btn->setVisible(enabled);
}
void LooperSlider::SetTick(double value) {
set_tick(value);
UpdateSlider(false);
}
void LooperSlider::set_tick(double value) {
this->settings_changed = true;
this->tick = value;
}
void LooperSlider::UpdateSlider(bool update_value) {
UpdateLogScaler();
if (this->min_label == NULL) {
this->min_label_view->setText("");
} else {
this->min_label_view->setText(this->min_label);
}
if (this->max_label == NULL) {
this->max_label_view->setText("");
} else {
this->max_label_view->setText(this->max_label);
}
limits_visible = (this->min_label == NULL && this->max_label == NULL);
if (limits_visible) {
if (!limits_actually_visible) {
this->text_layout_view->addItem(this->limits_view);
limits_actually_visible = true;
}
} else {
if (limits_actually_visible) {
this->text_layout_view->removeItem(this->limits_view);
limits_actually_visible = false;
}
}
if (this->label == NULL) {
if (text_label_visible) {
this->text_layout_view->removeWidget(this->text_label);
text_label_visible = false;
}
} else {
this->text_label->setText(this->label);
if (!text_label_visible) {
this->text_layout_view->insertWidget(0, this->text_label);
text_label_visible = true;
}
}
if (this->text_edit_mode) {
if (!text_editor_visible) {
this->text_layout_view->insertWidget(1, this->text);
text_editor_visible = true;
}
if (slider_visible) {
this->text_layout_view->removeWidget(this->slider);
slider_visible = false;
}
} else {
if (!slider_visible) {
this->text_layout_view->insertWidget(1, this->slider);
slider_visible = true;
}
if (text_editor_visible) {
this->text_layout_view->removeWidget(this->text);
text_editor_visible = false;
}
}
auto icon = QIcon::fromTheme(text_edit_mode ? "slider_edit_mode" : "text_edit_mode", QIcon::fromTheme(text_edit_mode ? "dialog-ok" : "edit"));
auto text = text_edit_mode ? "Imprecise" : "Precise";
if (icon.isNull() || show_button_text) {
this->btn->setText(text);
} else {
this->btn->setText("");
}
if (show_button_icon && !icon.isNull()) {
this->btn->setIcon(icon);
} else {
QIcon emptyIcon;
this->btn->setIcon(emptyIcon);
}
this->slider->setVisible(slider_visible);
this->text->setVisible(text_editor_visible);
this->text_label->setVisible(text_label_visible);
this->min_label_view->setVisible(limits_actually_visible);
this->max_label_view->setVisible(limits_actually_visible);
if (update_value) {
if (textChanged) {
textChanged = false;
} else {
if (!pressed && !text_edit_mode) this->text->setText(fmt::to_string(this->value).c_str());
}
slider_value_updating = true;
if (!pressed && slider_value_changed_after_release) {
this->slider->setValue(this->logarithmic ? (this->scaler->scale_log(this->value) / this->tick) : (this->value / this->tick));
this->slider->setMinimum(this->min / tick);
this->slider->setMaximum(this->max / tick);
}
slider_value_updating = false;
}
}
bool LooperSlider::ShowButtonText() {
return show_button_text;
}
bool LooperSlider::ShowButtonIcon() {
return show_button_icon;
}
void LooperSlider::SetShowButtonIcon(bool enable) {
this->show_button_icon = enable;
UpdateSlider();
}
void LooperSlider::SetShowButtonText(bool enable) {
this->show_button_text = enable;
UpdateSlider();
}
void LooperSlider::changeEvent(QEvent *event) {
if (event->type() == QEvent::EnabledChange) {
this->slider->setEnabled(isEnabled());
this->text->setEnabled(isEnabled());
}
}