125 lines
4.8 KiB
C++
125 lines
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;
|
||
|
}
|
||
|
}
|