summaryrefslogtreecommitdiff
path: root/src/user/settings
diff options
context:
space:
mode:
Diffstat (limited to 'src/user/settings')
-rw-r--r--src/user/settings/color_editor.cpp16
-rw-r--r--src/user/settings/color_editor.h19
-rw-r--r--src/user/settings/color_kind.cpp36
-rw-r--r--src/user/settings/color_kind.h8
-rw-r--r--src/user/settings/editor.cpp30
-rw-r--r--src/user/settings/editor.h20
-rw-r--r--src/user/settings/main.cpp190
-rw-r--r--src/user/settings/model.cpp60
-rw-r--r--src/user/settings/model.h60
-rw-r--r--src/user/settings/str_editor.cpp17
-rw-r--r--src/user/settings/str_editor.h19
-rw-r--r--src/user/settings/string_kind.cpp52
-rw-r--r--src/user/settings/string_kind.h8
13 files changed, 226 insertions, 309 deletions
diff --git a/src/user/settings/color_editor.cpp b/src/user/settings/color_editor.cpp
deleted file mode 100644
index 1673824..0000000
--- a/src/user/settings/color_editor.cpp
+++ /dev/null
@@ -1,16 +0,0 @@
-#include "color_editor.h"
-
-color_editor::color_editor(struct setting *s, const char *sname)
- : c(&s->data.color), p(s->data.color) {
- editing_widget_ready(p, sname);
-}
-
-#include <knob/format.h>
-
-void color_editor::set_data() {
- const _pixel_t new_c = p.get_picked_color();
- if ((c->r != new_c.r) || (c->g != new_c.g) || (c->b != new_c.b)) {
- *c = new_c;
- main_w->is_saved = false;
- }
-} \ No newline at end of file
diff --git a/src/user/settings/color_editor.h b/src/user/settings/color_editor.h
deleted file mode 100644
index c41ec3f..0000000
--- a/src/user/settings/color_editor.h
+++ /dev/null
@@ -1,19 +0,0 @@
-#ifndef COLOR_EDITOR_H
-#define COLOR_EDITOR_H
-
-#include <raleigh/w/colorpicker.h>
-
-#include "editor.h"
-#include "model.h"
-
-class color_editor : public editor {
-public:
- color_editor(struct setting *s, const char *sname);
- void set_data() override;
-
-private:
- _pixel_t *c;
- colorpicker p;
-};
-
-#endif \ No newline at end of file
diff --git a/src/user/settings/color_kind.cpp b/src/user/settings/color_kind.cpp
new file mode 100644
index 0000000..08fb2d9
--- /dev/null
+++ b/src/user/settings/color_kind.cpp
@@ -0,0 +1,36 @@
+#include "color_kind.h"
+
+#include <raleigh/w/colorpicker.h>
+
+void write_color_main(uint32_t &data_offset, file *f, const backing_t backing) {
+ _pixel_t main[2];
+ main[0] = *(const _pixel_t *)backing;
+ write_to_file(f, 8, main);
+}
+
+void write_color_data(file *f, const backing_t backing) {}
+
+backing_t read_color_backing(file *f, uint32_t data_start) {
+ _pixel_t *p = new _pixel_t[1];
+ read_from_file(f, 3, p);
+ return (backing_t)p;
+}
+
+void load_into_picker(raleigh::colorpicker &e, _pixel_t *s) {
+ e.set_picked_color(*s);
+}
+
+void save_from_picker(raleigh::colorpicker &e, _pixel_t *&s) {
+ *s = e.get_picked_color();
+}
+
+void open_color_editor(setting &s) {
+ do_common_editor<_pixel_t *, raleigh::colorpicker, &load_into_picker, &save_from_picker>(s);
+}
+
+const setting_kind_info color_kind = {
+ &write_color_main,
+ &write_color_data,
+ &read_color_backing,
+ &open_color_editor
+}; \ No newline at end of file
diff --git a/src/user/settings/color_kind.h b/src/user/settings/color_kind.h
new file mode 100644
index 0000000..b5a12c8
--- /dev/null
+++ b/src/user/settings/color_kind.h
@@ -0,0 +1,8 @@
+#ifndef COLOR_KIND_H
+#define COLOR_KIND_H
+
+#include "model.h"
+
+extern const setting_kind_info color_kind;
+
+#endif \ No newline at end of file
diff --git a/src/user/settings/editor.cpp b/src/user/settings/editor.cpp
deleted file mode 100644
index 1804a85..0000000
--- a/src/user/settings/editor.cpp
+++ /dev/null
@@ -1,30 +0,0 @@
-#include <raleigh/w/padding.h>
-#include <raleigh/w/button.h>
-#include <raleigh/w/label.h>
-#include <raleigh/w/vbox.h>
-#include "editor.h"
-
-bool editor_save(window_tag_t e) {
- ((editor *)e)->set_data();
- return true;
-}
-
-editor::editor()
- : w(0) {}
-
-void editor::editing_widget_ready(widget &e, const char *s) {
- label *l = new label(s);
- padding *p = new padding(*l, 4);
-
- dllist<widget &> *list = new dllist<widget &>();
- list->add_back(*p);
- list->add_back(e);
-
- vbox *box = new vbox(*list);
-
- w = new window(*box, RGB(bf, bf, bf), &editor_save, this);
-}
-
-void editor::show() {
- w->show();
-} \ No newline at end of file
diff --git a/src/user/settings/editor.h b/src/user/settings/editor.h
deleted file mode 100644
index 2980884..0000000
--- a/src/user/settings/editor.h
+++ /dev/null
@@ -1,20 +0,0 @@
-#ifndef EDITOR_H
-#define EDITOR_H
-
-#include <raleigh/d/saving_window.h>
-
-using namespace raleigh;
-
-class editor {
- friend bool editor_save(window_tag_t e);
-public:
- void show();
-protected:
- editor();
- void editing_widget_ready(widget &e, const char *sname);
- virtual void set_data() = 0;
-private:
- window *w;
-};
-
-#endif \ No newline at end of file
diff --git a/src/user/settings/main.cpp b/src/user/settings/main.cpp
index 2045137..cb318b1 100644
--- a/src/user/settings/main.cpp
+++ b/src/user/settings/main.cpp
@@ -1,191 +1,35 @@
-#include <raleigh/d/saving_window.h>
-#include <raleigh/w/padding.h>
+#include "model.h"
+
#include <raleigh/w/button.h>
#include <raleigh/w/label.h>
#include <raleigh/w/vbox.h>
-#include <structs/map.h>
-#include <knob/format.h>
-#include <knob/file.h>
-#include <stdint.h>
-
-#include "color_editor.h"
-#include "str_editor.h"
-#include "model.h"
-struct file_header {
- uint32_t main_offset;
- uint32_t main_entries;
- uint32_t names_offset;
- uint32_t data_offset;
-} __attribute__ ((packed));
-
-struct main_entry {
- uint32_t name_offset;
- uint8_t name_len;
- enum : uint8_t {
- STRING = 0,
- COLOR
- } kind;
- uint16_t pad;
- union {
- struct {
- uint32_t data_offset;
- uint32_t data_len;
- } as_string;
- _pixel_t as_color;
- };
-} __attribute__ ((packed));
-
-#define SETTINGS_FILE "sys/settings.pls"
+#define SETTINGS_FILE "/sys/settings.pls"
using namespace raleigh;
-bool save(save_tag_t) {
- struct file *f = open_file(SETTINGS_FILE);
- struct file_header fh;
- fh.main_offset = sizeof(struct file_header);
- fh.main_entries = settings.n_entries;
- fh.names_offset = fh.main_offset + sizeof(struct main_entry) * settings.n_entries;
-
- uint32_t name_i = 0;
- uint32_t data_i = 0;
- seek_file_to(f, sizeof(struct file_header));
- struct main_entry me;
-
- for (struct setting *i = settings.buf; i < settings.buf + settings.n_entries; ++i) {
- me.name_offset = name_i;
- me.name_len = strlen(i->name);
- name_i += me.name_len;
-
- switch (i->kind) {
- case setting::STRING:
- me.kind = main_entry::STRING;
- me.as_string.data_offset = data_i;
- me.as_string.data_len = strlen(i->data.string);
- data_i += me.as_string.data_len;
- break;
- case setting::COLOR:
- me.kind = main_entry::COLOR;
- me.as_color = i->data.color;
- break;
- }
-
- write_to_file(f, sizeof(struct main_entry), &me);
- }
-
- seek_file_to(f, fh.names_offset);
- for (struct setting *i = settings.buf; i < settings.buf + settings.n_entries; ++i)
- write_to_file(f, strlen(i->name), (void *)i->name);
-
- fh.data_offset = get_file_pos(f);
- for (struct setting *i = settings.buf; i < settings.buf + settings.n_entries; ++i)
- switch (i->kind) {
- case setting::STRING:
- write_to_file(f, strlen(i->data.string), (void *)i->data.string);
- break;
- default:
- break;
- }
-
- trunc_file(f);
- seek_file_to(f, 0);
- write_to_file(f, sizeof(struct file_header), &fh);
- close_file(f);
-
- main_w->is_saved = true;
- return true;
-}
-
-void on_button_click(button_tag_t n) {
- struct setting *const s = settings.buf + (uint32_t)n;
- editor *e;
- switch (s->kind) {
- case setting::STRING:
- e = new str_editor(s, s->name);
- break;
- case setting::COLOR:
- e = new color_editor(s, s->name);
- break;
- default:
- show_error_and_quitf("Internal model corrupted: setting %s had type 0x%2x.", s->name, s->kind);
- }
- e->show();
-}
-
-button *make_button(uint32_t i) {
- label *l = new label(settings.buf[i].name);
- padding *p = new padding(*l, 2);
- return new button(*p, &on_button_click, (button_tag_t)i);
+void on_button(button_tag_t tag) {
+ setting *s = (setting *)tag;
+ s->kind->open_editor(*s);
}
void main() {
- struct file *f = open_file(SETTINGS_FILE);
-
- struct file_header file_head;
- read_from_file(f, sizeof(struct file_header), &file_head);
-
- settings = alist<struct setting>(file_head.main_entries + 10);
-
- dllist<widget &> for_vbox;
+ settings_model sm(SETTINGS_FILE);
- label l("Click a setting name below to edit its value.");
- label l2("A restart is required for changes to take effect.");
+ label instructions("Click a button below to edit that setting.");
- dllist<widget &> for_subbox;
- for_subbox.add_back(l);
- for_subbox.add_back(l2);
- vbox subbox(for_subbox);
+ dllist<widget &> box_widgets;
+ box_widgets.add_back(instructions);
- padding p_subbox(subbox, 2);
- for_vbox.add_back(p_subbox);
-
- for (uint32_t i = 0; i < file_head.main_entries; ++i) {
- struct main_entry entry;
- seek_file_to(f, file_head.main_offset + i * sizeof(struct main_entry));
- read_from_file(f, sizeof(struct main_entry), &entry);
-
- char *const sname = new char[entry.name_len + 1];
- seek_file_to(f, file_head.names_offset + entry.name_offset);
- read_from_file(f, entry.name_len, sname);
- sname[entry.name_len] = '\0';
-
- switch (entry.kind) {
- char *sz;
- struct setting s;
- case main_entry::STRING:
- sz = new char[entry.as_string.data_len + 1];
- seek_file_to(f, file_head.data_offset + entry.as_string.data_offset);
- read_from_file(f, entry.as_string.data_len, sz);
- sz[entry.as_string.data_len] = '\0';
-
- s.kind = setting::STRING;
- s.data.string = sz;
- s.name = sname;
- settings.add_back(s);
- break;
-
- case main_entry::COLOR:
- s.kind = setting::COLOR;
- s.data.color = entry.as_color;
- s.name = sname;
- settings.add_back(s);
- break;
- default:
- show_error_and_quitf("Refusing to open " SETTINGS_FILE ":\n\"%s\" has unrecognized type id 0x%2x.\nHighest known is 0x01.", sname, entry.kind);
- }
-
- button *const b = make_button(settings.n_entries - 1);
-
- padding *p = new padding(*b, 2);
- for_vbox.add_back(*p);
+ for (uint32_t i = 0; i < sm.settings.n_entries; ++i) {
+ label *l = new label(sm.settings.buf[i].name);
+ button *b = new button(*l, &on_button, (button_tag_t)&sm.settings.buf[i]);
+ box_widgets.add_back(*b);
}
- close_file(f);
-
- vbox box(for_vbox);
- padding pbox(box, 2);
+ vbox box(box_widgets);
+ window w(box);
+ w.show();
- main_w = new saving_window(&save, 0, pbox);
- main_w->show();
start_runtime();
} \ No newline at end of file
diff --git a/src/user/settings/model.cpp b/src/user/settings/model.cpp
index e27de0d..db0a4ce 100644
--- a/src/user/settings/model.cpp
+++ b/src/user/settings/model.cpp
@@ -1,4 +1,58 @@
-#include "model.h"
+#include <raleigh/util.h>
-alist<struct setting> settings;
-raleigh::saving_window *main_w; \ No newline at end of file
+#include "string_kind.h"
+#include "color_kind.h"
+
+#define N_SETTING_KINDS 2
+const setting_kind_info *setting_kinds[] = {
+ &string_kind,
+ &color_kind
+};
+
+struct file_head {
+ uint32_t main_start;
+ uint32_t count;
+ uint32_t names_start;
+ uint32_t data_start;
+} __attribute__ ((__packed__));
+
+struct setting_head {
+ uint32_t name_offset;
+ uint8_t name_length;
+ uint8_t type;
+} __attribute__ ((__packed__));
+
+settings_model::settings_model(const char *from_file)
+ : settings() {
+ file *f = open_file(from_file);
+
+ file_head header;
+ read_from_file(f, 16, &header);
+ settings.expand_to(header.count);
+ settings.n_entries = header.count;
+
+ for (uint32_t i = 0; i < header.count; ++i) {
+ setting_head shead;
+ seek_file_to(f, header.main_start + i * 16);
+ read_from_file(f, sizeof(setting_head), &shead);
+
+ char *name = new char[shead.name_length + 1];
+ seek_file_to(f, header.names_start + shead.name_offset);
+ read_from_file(f, shead.name_length, name);
+ name[shead.name_length] = '\0';
+
+ if (shead.type >= N_SETTING_KINDS)
+ raleigh::show_error_popup_and_quitf("setting \"%s\" has unkown type 0x%2x.", name, shead.type);
+
+ setting ns;
+ ns.name = name;
+ ns.kind = setting_kinds[shead.type];
+
+ seek_file_to(f, header.main_start + i * 16 + 8);
+ ns.backing = ns.kind->read_backing(f, header.data_start);
+
+ settings.buf[i] = ns;
+ }
+
+ close_file(f);
+} \ No newline at end of file
diff --git a/src/user/settings/model.h b/src/user/settings/model.h
index 0c9b1d2..410121f 100644
--- a/src/user/settings/model.h
+++ b/src/user/settings/model.h
@@ -1,24 +1,60 @@
#ifndef MODEL_H
#define MODEL_H
-#include <raleigh/d/saving_window.h>
-#include <structs/alist.h>
+#include <raleigh/d/dialog.h>
+#include <raleigh/w/button.h>
+#include <raleigh/w/label.h>
+#include <raleigh/w/vbox.h>
+#include <raleigh/window.h>
+#include <structs/map.h>
+#include <knob/file.h>
-union setting_data {
- char *string;
- _pixel_t color;
+typedef void *backing_t;
+
+struct setting;
+
+struct setting_kind_info {
+ void (*write_main)(uint32_t &data_offset, file *f, const backing_t backing);
+ void (*write_data)(file *f, const backing_t backing);
+ backing_t (*read_backing)(file *f, uint32_t data_start);
+ void (*open_editor)(setting &s);
};
struct setting {
- enum {
- STRING,
- COLOR
- } kind;
- union setting_data data;
const char *name;
+ const setting_kind_info *kind;
+ void *backing;
+};
+
+class settings_model {
+public:
+ settings_model(const char *from_file);
+
+ void write_to_file(const char *to_file);
+
+ alist<setting> settings;
};
-extern alist<struct setting> settings;
-extern raleigh::saving_window *main_w;
+using namespace raleigh;
+
+template<class backing_type, class editing_widget, void (*load_into_widget)(editing_widget &ew, backing_type s), void (*save_from_widget)(editing_widget &ew, backing_type &s)>
+void do_common_editor(setting &s) {
+ dllist<widget &> widgets;
+
+ label l(s.name);
+ widgets.add_back(l);
+
+ editing_widget ew;
+ load_into_widget(ew, (backing_type)s.backing);
+ widgets.add_back(ew);
+
+ vbox box(widgets);
+
+ dialog d(box, okay_cancel);
+ d.show_modal();
+
+ if (d.result == OKAY)
+ save_from_widget(ew, (backing_type &)s.backing);
+}
#endif \ No newline at end of file
diff --git a/src/user/settings/str_editor.cpp b/src/user/settings/str_editor.cpp
deleted file mode 100644
index 5e86e96..0000000
--- a/src/user/settings/str_editor.cpp
+++ /dev/null
@@ -1,17 +0,0 @@
-#include <knob/block.h>
-
-#include "str_editor.h"
-
-str_editor::str_editor(struct setting *s, const char *sname)
- : e(10, 25, s->data.string), s(&s->data.string) {
- editing_widget_ready(e, sname);
-}
-
-void str_editor::set_data() {
- const char *const contents = e.get_contents();
- if (strequ(contents, *s))
- return;
- delete *s;
- *s = strdup(contents);
- main_w->is_saved = false;
-} \ No newline at end of file
diff --git a/src/user/settings/str_editor.h b/src/user/settings/str_editor.h
deleted file mode 100644
index 02bd7d8..0000000
--- a/src/user/settings/str_editor.h
+++ /dev/null
@@ -1,19 +0,0 @@
-#ifndef STR_EDITOR_H
-#define STR_EDITOR_H
-
-#include <raleigh/w/entry.h>
-
-#include "editor.h"
-#include "model.h"
-
-class str_editor : public editor {
-public:
- str_editor(struct setting *s, const char *sname);
- void set_data() override;
-
-private:
- entry e;
- char **s;
-};
-
-#endif \ No newline at end of file
diff --git a/src/user/settings/string_kind.cpp b/src/user/settings/string_kind.cpp
new file mode 100644
index 0000000..0afe102
--- /dev/null
+++ b/src/user/settings/string_kind.cpp
@@ -0,0 +1,52 @@
+#include "string_kind.h"
+
+#include <raleigh/w/entry.h>
+
+void write_string_main(uint32_t &data_offset, file *f, const backing_t backing) {
+ const uint32_t len = strlen((const char *)backing);
+
+ uint32_t main[2];
+ main[0] = data_offset;
+ main[1] = len;
+
+ data_offset += len;
+
+ write_to_file(f, 8, main);
+}
+
+void write_string_data(file *f, const backing_t backing) {
+ const char *b = (const char *)backing;
+ write_to_file(f, strlen(b), b);
+}
+
+backing_t read_string_backing(file *f, uint32_t data_start) {
+ uint32_t main[2];
+ read_from_file(f, 8, main);
+
+ seek_file_to(f, data_start + main[0]);
+
+ char *buf = new char[main[1] + 1];
+ read_from_file(f, main[1], buf);
+ buf[main[1]] = '\0';
+
+ return (backing_t)buf;
+}
+
+void load_into_entry(raleigh::entry &e, const char *s) {
+ e.set_contents(s);
+}
+
+void save_from_entry(raleigh::entry &e, const char *&s) {
+ s = e.get_contents();
+}
+
+void open_string_editor(setting &s) {
+ do_common_editor<const char *, raleigh::entry, &load_into_entry, &save_from_entry>(s);
+}
+
+const setting_kind_info string_kind = {
+ &write_string_main,
+ &write_string_data,
+ &read_string_backing,
+ &open_string_editor
+}; \ No newline at end of file
diff --git a/src/user/settings/string_kind.h b/src/user/settings/string_kind.h
new file mode 100644
index 0000000..b62244f
--- /dev/null
+++ b/src/user/settings/string_kind.h
@@ -0,0 +1,8 @@
+#ifndef STRING_KIND_H
+#define STRING_KIND_H
+
+#include "model.h"
+
+extern const setting_kind_info string_kind;
+
+#endif \ No newline at end of file