174 lines
No EOL
7 KiB
C++
174 lines
No EOL
7 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_css_classes({"option-label"});
|
|
label->set_justify(Gtk::Justification::LEFT);
|
|
label->set_hexpand(false);
|
|
label->set_text(title);
|
|
mainBox.attach(*label, 0, mainBoxRow);
|
|
optionWidgets.push_back(label);
|
|
Gtk::Label *emptyLabel = new Gtk::Label();
|
|
emptyLabel->set_hexpand(true);
|
|
emptyLabel->set_text("");
|
|
mainBox.attach(*emptyLabel, 1, mainBoxRow);
|
|
optionWidgets.push_back(emptyLabel);
|
|
auto widget_css_classes = widget->get_css_classes();
|
|
widget_css_classes.push_back("option-editor");
|
|
widget->set_css_classes(widget_css_classes);
|
|
if (!widget->get_hexpand()) {
|
|
widget->set_halign(Gtk::Align::END);
|
|
}
|
|
|
|
mainBox.attach(*widget, 2, 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();
|
|
optionsSaved.emit();
|
|
savedOptionRequiresRestart = needsRestartLabel.get_visible();
|
|
}
|
|
OptionsWindow::OptionsWindow() {
|
|
set_title("Options...");
|
|
set_icon_name("preferences-other");
|
|
set_name("options-window");
|
|
rootBox.set_name("options-window-root");
|
|
mainBox.set_expand();
|
|
mainBox.insert_column(0);
|
|
mainBox.insert_column(1);
|
|
mainBox.insert_column(2);
|
|
mainBox.set_name("options-main-box");
|
|
needsRestartLabel.set_name("options-needs-restart-label");
|
|
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;
|
|
box->set_css_classes({"ui-backend-option"});
|
|
auto name_label = dynamic_cast<Gtk::Label*>(box->get_first_child());
|
|
name_label->set_hexpand();
|
|
name_label->set_text(col->backendName);
|
|
name_label->set_css_classes({"ui-backend-name", "primary"});
|
|
if (!name_label) return;
|
|
auto id_label = dynamic_cast<Gtk::Label*>(name_label->get_next_sibling());
|
|
if (!id_label) return;
|
|
id_label->set_text(col->backendId);
|
|
id_label->set_css_classes({"ui-backend-id", "secondary"});
|
|
});
|
|
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");
|
|
Gtk::Switch *darkModeSwitch = new Gtk::Switch();
|
|
darkModeSwitch->set_active(Looper::Options::get_option<bool>("ui.gtk.dark_mode", false));
|
|
darkModeSwitch->property_active().signal_changed().connect([this, darkModeSwitch]() {
|
|
Looper::Options::set_option<bool>("ui.gtk.dark_mode", darkModeSwitch->get_active());
|
|
});
|
|
add_option("Dark mode", darkModeSwitch, "ui.gtk.dark_mode");
|
|
optionChanged.connect([this, uiBackendBox, listStore, darkModeSwitch](std::string key) {
|
|
if (key == "ui.frontend") {
|
|
std::string frontend = Looper::Options::get_option<std::string>(key);
|
|
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;
|
|
}
|
|
}
|
|
} else if (key == "ui.gtk.dark_mode") {
|
|
darkModeSwitch->set_active(Looper::Options::get_option<bool>(key));
|
|
}
|
|
});
|
|
mainBox.set_row_spacing(2);
|
|
mainBox.set_column_spacing(2);
|
|
mainBox.insert_at_end(rootBox);
|
|
okBtn.set_name("options-ok-btn");
|
|
okBtn.set_css_classes({"options-window-btn"});
|
|
okBtn.set_label("OK");
|
|
cancelBtn.set_name("options-cancel-btn");
|
|
cancelBtn.set_css_classes({"options-window-btn"});
|
|
cancelBtn.set_label("Cancel");
|
|
saveBtn.set_name("options-save-btn");
|
|
saveBtn.set_css_classes({"options-window-btn"});
|
|
saveBtn.set_label("Save");
|
|
revertBtn.set_name("options-revert-btn");
|
|
revertBtn.set_css_classes({"options-window-btn"});
|
|
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);
|
|
rootBox.set_spacing(8);
|
|
btnBox.set_spacing(2);
|
|
btnBox.set_orientation(Gtk::Orientation::HORIZONTAL);
|
|
btnBox.set_name("options-window-btns");
|
|
btnBox.set_halign(Gtk::Align::END);
|
|
btnBox.insert_at_end(rootBox);
|
|
rootBox.set_orientation(Gtk::Orientation::VERTICAL);
|
|
rootBox.set_expand();
|
|
set_child(rootBox);
|
|
Gtk::Requisition min;
|
|
Gtk::Requisition nat;
|
|
rootBox.get_preferred_size(min, nat);
|
|
set_default_size(nat.get_width(), nat.get_height());
|
|
}
|
|
OptionsWindow::~OptionsWindow() {
|
|
for (auto widget : optionWidgets) {
|
|
delete widget;
|
|
}
|
|
} |