looper/backends/ui/gtk/options_window.cpp

125 lines
No EOL
4.8 KiB
C++

#include "options_window.hpp"
#include <backend.hpp>
#include <options.hpp>
#include <optional>
Glib::RefPtr<UIBackendColumns> UIBackendColumns::create(const Glib::ustring &id, const Glib::ustring &name) {
return Glib::make_refptr_for_instance<UIBackendColumns>(new UIBackendColumns(id, name));
}
UIBackendColumns::UIBackendColumns(const Glib::ustring &id, const Glib::ustring &name)
: backendId(id),
backendName(name)
{ }
void OptionsWindow::add_option(Glib::ustring title, Gtk::Widget *widget, std::string key) {
mainBox.insert_row(mainBoxRow);
Gtk::Label *label = new Gtk::Label();
label->set_text(title);
mainBox.attach(*label, 0, mainBoxRow);
optionWidgets.push_back(label);
mainBox.attach(*widget, 1, mainBoxRow);
optionWidgets.push_back(widget);
mainBoxRow++;
modifiableOptions.insert(key);
}
void OptionsWindow::revert() {
Looper::Options::load_options();
for (auto option : modifiableOptions) {
optionChanged.emit(option);
}
needsRestartLabel.set_visible(savedOptionRequiresRestart);
}
void OptionsWindow::save() {
Looper::Options::save_options();
savedOptionRequiresRestart = needsRestartLabel.get_visible();
}
OptionsWindow::OptionsWindow() {
set_title("Options...");
set_icon_name("preferences-other");
mainBox.set_expand();
mainBox.insert_column(0);
mainBox.insert_column(1);
needsRestartLabel.set_text("A restart is needed to apply some changes.");
needsRestartLabel.set_visible(false);
needsRestartLabel.insert_at_start(rootBox);
Gtk::DropDown *uiBackendBox = new Gtk::DropDown();
Glib::RefPtr<Gio::ListStore<UIBackendColumns>> listStore = Gio::ListStore<UIBackendColumns>::create();
for (auto kv : UIBackend::backends) {
auto backend = kv.second;
Glib::ustring id(backend->get_id().c_str());
Glib::ustring name(backend->get_name().c_str());
listStore->append(UIBackendColumns::create(id, name));
}
uiBackendBox->set_model(listStore);
auto factory = Gtk::SignalListItemFactory::create();
factory->signal_setup().connect([this](const Glib::RefPtr<Gtk::ListItem>& list_item) {
auto box = Gtk::make_managed<Gtk::Box>(Gtk::Orientation::HORIZONTAL, 10);
box->append(*Gtk::make_managed<Gtk::Label>());
box->append(*Gtk::make_managed<Gtk::Label>());
list_item->set_child(*box);
});
factory->signal_bind().connect([this](const Glib::RefPtr<Gtk::ListItem>& list_item) {
auto col = std::dynamic_pointer_cast<UIBackendColumns>(list_item->get_item());
if (!col) return;
auto box = dynamic_cast<Gtk::Box*>(list_item->get_child());
if (!box) return;
auto name_label = dynamic_cast<Gtk::Label*>(box->get_first_child());
name_label->set_hexpand();
name_label->set_text(col->backendName);
if (!name_label) return;
auto id_label = dynamic_cast<Gtk::Label*>(name_label->get_next_sibling());
if (!id_label) return;
id_label->set_opacity(0.5);
id_label->set_text(col->backendId);
});
uiBackendBox->set_factory(factory);
uiBackendBox->property_selected().signal_changed().connect([uiBackendBox, listStore, this]() {
std::string backendId = listStore->get_item(uiBackendBox->get_selected())->backendId;
this->change_option("ui.frontend", backendId);
this->needsRestartLabel.set_visible();
});
add_option("UI frontend", uiBackendBox, "ui.frontend");
optionChanged.connect([this, uiBackendBox, listStore](std::string key) {
if (key == "ui.frontend") {
std::string frontend = Looper::Options::get_option<std::string>("ui.frontend");
for (int i = 0; i < listStore->get_n_items(); i++) {
if (std::string(listStore->get_item(i)->backendId.c_str()) == frontend) {
uiBackendBox->set_selected(i);
break;
}
}
}
});
mainBox.insert_at_end(rootBox);
okBtn.set_label("OK");
cancelBtn.set_label("Cancel");
saveBtn.set_label("Save");
revertBtn.set_label("Revert");
okBtn.signal_clicked().connect([this]() {
this->save();
this->close();
});
cancelBtn.signal_clicked().connect([this]() {
this->revert();
this->close();
});
revertBtn.signal_clicked().connect([this]() {
this->revert();
});
saveBtn.signal_clicked().connect([this]() {
this->save();
});
okBtn.insert_at_end(btnBox);
saveBtn.insert_at_end(btnBox);
revertBtn.insert_at_end(btnBox);
cancelBtn.insert_at_end(btnBox);
btnBox.set_orientation(Gtk::Orientation::HORIZONTAL);
btnBox.insert_at_end(rootBox);
rootBox.set_orientation(Gtk::Orientation::VERTICAL);
rootBox.set_expand();
set_child(rootBox);
}
OptionsWindow::~OptionsWindow() {
for (auto widget : optionWidgets) {
delete widget;
}
}