looper/backends/ui/haiku/prefs.cpp
Zachary Hall 9899794b81
Some checks failed
Build / build-gentoo (push) Failing after 1m11s
Build / download-system-deps (push) Successful in 3m44s
Build / get-source-code (push) Successful in 13m23s
Build / build-deb (push) Successful in 11m40s
Build / build-appimage (push) Successful in 4m53s
Build / build-android (push) Failing after 3m19s
Build / build-windows (push) Failing after 8m9s
Add cat support
2024-12-21 14:23:00 -08:00

215 lines
8.2 KiB
C++

#include "prefs.h"
#include <OptionPopUp.h>
#include <options.hpp>
#include <backend.hpp>
#include <GroupView.h>
#include <RadioButton.h>
#include <Box.h>
#include <map>
#include "main_window.h"
using namespace Looper::Options;
#define CMD_UPDATE_LABEL_SETTING 0x1000
#define CMD_FRONTEND 0x1001
#define CMD_SET_SETTING 0x1002
#define CMD_REVERT 0x1003
#define CMD_APPLY 0x1004
#define CMD_SET_SETTING_CHECKBOX = 0x1005
bool show_icons, show_labels;
HaikuPrefsWindow::HaikuPrefsWindow(BLooper *next_handler) : BWindow(BRect(100, 100, 0, 0), "Preferences", B_TITLED_WINDOW, B_AUTO_UPDATE_SIZE_LIMITS) {
this->next_handler = next_handler;
for (auto &cat : get_cat_data()) {
switch (cat.get_type()) {
case CatDataType::Memory: {
MemoryCat mem_cat = cat.get_memory_cat();
AddCat(cat.get_name(), LoadCat(mem_cat.get_ptr(), mem_cat.get_len(), cat.get_path().c_str()));
} break;
case CatDataType::File: {
fs::path cat_path = cat.get_path();
AddCat(cat.get_name(), LoadCat(cat_path.c_str()));
} break;
}
}
auto *root_layout = new BGroupLayout(B_VERTICAL);
SetLayout(root_layout);
root_layout->SetSpacing(0.0);
restart_warning = new BStringView("prefs:restart_needed", "A restart is needed to apply some changes.");
root_layout->AddView(restart_warning);
restart_warning->Hide();
frontend_popup = new BOptionPopUp("prefs:frontend", "Frontend", new BMessage(CMD_FRONTEND));
auto frontend = get_option<std::string>("ui.frontend", "haiku");
for (auto &kv : UIBackend::backends) {
UIBackend *backend = kv.second;
const char *name = backend->get_name().c_str();
frontend_popup->AddOption(name, (int32)backend_ids.size());
std::string id = backend->get_id();
if (id == frontend) cur_option = (int32)backend_ids.size();
backend_ids.push_back(id);
}
BLayoutItem *frontend_item = root_layout->AddView(frontend_popup);
BAlignment align;
align.SetVertical(B_ALIGN_TOP);
frontend_item->SetExplicitAlignment(align);
BBox *box = new BBox("prefs:label_settings_box");
box->SetLabel("Labels and Icons");
auto *label_settings_group = new BGroupView(B_VERTICAL);
BGroupLayout *label_settings_layout = label_settings_group->GroupLayout();
BMessage *labels_only_msg = new BMessage(CMD_SET_SETTING);
labels_only_msg->AddString("pref_path", "ui.haiku.label_setting");
labels_only_msg->AddString("pref_value", "labels");
labels_only = new BRadioButton("prefs:labels_only", "Labels Only", labels_only_msg);
BMessage *icons_only_msg = new BMessage(CMD_SET_SETTING);
icons_only_msg->AddString("pref_path", "ui.haiku.label_setting");
icons_only_msg->AddString("pref_value", "icons");
icons_only = new BRadioButton("prefs:icons_only", "Icons Only", icons_only_msg);
BMessage *both_labels_icons_msg = new BMessage(CMD_SET_SETTING);
both_labels_icons_msg->AddString("pref_path", "ui.haiku.label_setting");
both_labels_icons_msg->AddString("pref_value", "both");
both_labels_icons = new BRadioButton("prefs:both_labels_and_icons", "Both", both_labels_icons_msg);
label_settings_layout->AddView(labels_only);
label_settings_layout->AddView(icons_only);
label_settings_layout->AddView(both_labels_icons);
BMessage *cat_enable_msg = new BMessage(CMD_SET_SETTING_CHECKBOX);
cat_enable_msg->AddString("pref_path", "ui.cat_enable");
cat_enable = new BCheckBox("Enable Cat", cat_enable_msg);
BGroupView *cat_group = new BGroupView(B_VERTICAL);
BGroupLayout *cat_layout = cat_group->GroupLayout();
for (auto &kv : cats) {
BMessage *msg = new BMessage(CMD_SET_SETTING);
msg->AddString("pref_path", "ui.cat");
msg->AddString("pref_value", kv.first.c_str());
BRadioButton *cat_radio = new BRadioButton(fmt::format("prefs:cat:{}", kv.first).c_str(), msg);
cat_btns[kv.first] = cat_radio;
BBitmap *cat_bmp = kv.second;
BRect src = cat_bmp->bounds();
float w = src.Width(), h = src.Height();
float rw = cat_radio->Bounds().Width(), rh = cat_radio->Bounds().Height();
if (w > rw || h > rh) {
float aspect = w / h;
if (h > rh) {
h = rh;
w = h * aspect;
}
if (w > rw) {
w = rw;
h = h / aspect;
}
}
BRect dst(rw - w, (rh - h) / 2, rw, rh);
cat_radio->SetOverlayBitmap(cat_bmp, src, dst, B_FOLLOW_RIGHT|B_FOLLOW_TOP_BOTTOM);
}
root_layout->AddView(box, 3.0);
BGroupView *btn_view = new BGroupView(B_HORIZONTAL);
BGroupLayout *btn_box = btn_view->GroupLayout();
revert_btn = new BButton("prefs:revert", "Revert", new BMessage(CMD_REVERT));
apply_btn = new BButton("prefs:apply", "Apply", new BMessage(CMD_APPLY));
root_layout->AddView(btn_view);
btn_box->AddView(revert_btn);
btn_box->AddView(apply_btn);
{
auto *msg = new BMessage(CMD_REVERT);
MessageReceived(msg);
delete msg;
}
}
bool HaikuPrefsWindow::QuitRequested() {
Hide();
return quitting;
}
void HaikuPrefsWindow::set_options_changed(bool changed) {
revert_btn->SetEnabled(changed);
apply_btn->SetEnabled(changed);
}
void HaikuPrefsWindow::update_label_setting() {
std::map<std::string, BRadioButton*> label_settings_map({{"labels", labels_only}, {"icons", icons_only}, {"both", both_labels_icons}});
auto cur_radio_btn = labels_only;
if (!label_settings_map.contains(new_label_setting)) {
new_label_setting = "icons";
}
cur_radio_btn = label_settings_map[new_label_setting];
show_icons = new_label_setting != "labels";
show_labels = new_label_setting != "icons";
cur_radio_btn->SetValue(B_CONTROL_ON);
}
void HaikuPrefsWindow::MessageReceived(BMessage *msg) {
if (msg->IsSystem()) return;
switch (msg->what) {
case CMD_APPLY: {
set_options_changed(false);
set_option<std::string>("ui.frontend", new_frontend);
if (new_frontend != "haiku") restart_warning->Show();
else restart_warning->Hide();
set_option<std::string>("ui.haiku.label_setting", new_label_setting);
update_label_setting();
set_option<std::string>("ui.cat", cat_id);
set_option<bool>("ui.enable_cat", enable_cat);
next_handler->PostMessage(CMD_UPDATE_LABEL_SETTING);
BMessage *cat_msg = new BMessage(CMD_SET_CAT);
if (enable_cat) cat_msg->AddBitmap("cat", cats[cat_id])
next_handler->PostMessage(cat_msg);
} break;
case CMD_REVERT: {
set_options_changed(false);
new_label_setting = get_option<std::string>("ui.haiku.label_setting", "icons");
new_frontend = get_option<std::string>("ui.frontend", "haiku");
if (new_frontend != "haiku") restart_warning->Show();
else restart_warning->Hide();
for (size_t i = 0; i < backend_ids.size(); i++) {
int32 backend_id = (int32)i;
if (backend_ids[i] == new_frontend) {
frontend_popup->SetValue(backend_id);
break;
}
}
cat_btns[cat_id].SetValue(B_CONTROL_OFF);
cat_id = get_option<std::string>("ui.cat", cats.empty() ? "" : cats.begin()->first);
if (cat_btns.contains(cat_id)) cat_btns[cat_id].SetValue(B_CONTROL_ON);
enable_cat = get_option<bool>("ui.enable_cat", false);
cat_enable->SetValue(enable_cat ? B_CONTROL_ON : B_CONTROL_OFF);
update_label_setting();
next_handler->PostMessage(CMD_UPDATE_LABEL_SETTING);
BMessage *cat_msg = new BMessage(CMD_SET_CAT);
if (enable_cat) cat_msg->AddBitmap("cat", cats[cat_id])
next_handler->PostMessage(cat_msg);
} break;
case CMD_FRONTEND: {
auto option = msg->GetInt32("be:value", cur_option);
if (backend_ids.size() < option && option >= 0) {
new_frontend = backend_ids[option];
}
set_options_changed(true);
} break;
case CMD_SET_SETTING: {
const char *setting;
if (msg->FindString("pref_path", &setting) == B_OK) {
const char *setting_value;
int32 setting_value_int32;
if (msg->FindString("pref_value", &setting_value) == B_OK) {
if (std::string(setting) == "ui.haiku.label_setting") {
new_label_setting = setting_value;
set_options_changed(true);
} else if (std::string(setting) == "ui.cat") {
cat_id = setting_value;
set_options_changed(true);
}
}
}
} break;
case CMD_SET_SETTING_CHECKBOX: {
const char *setting;
if (msg->FindString("pref_path", &setting) == B_OK) {
int32 setting_value_int32;
if (msg->FindInt32("be:value", &setting_value_int32) == B_OK) {
if (std::string(setting) == "ui.enable_cat") {
enable_cat = setting_value_int32 == B_CONTROL_ON;
set_options_changed(true);
}
}
}
} break;
}
}