diff options
Diffstat (limited to 'src/user/settings')
-rw-r--r-- | src/user/settings/color_editor.cpp | 16 | ||||
-rw-r--r-- | src/user/settings/color_editor.h | 19 | ||||
-rw-r--r-- | src/user/settings/color_kind.cpp | 36 | ||||
-rw-r--r-- | src/user/settings/color_kind.h | 8 | ||||
-rw-r--r-- | src/user/settings/editor.cpp | 30 | ||||
-rw-r--r-- | src/user/settings/editor.h | 20 | ||||
-rw-r--r-- | src/user/settings/main.cpp | 190 | ||||
-rw-r--r-- | src/user/settings/model.cpp | 60 | ||||
-rw-r--r-- | src/user/settings/model.h | 60 | ||||
-rw-r--r-- | src/user/settings/str_editor.cpp | 17 | ||||
-rw-r--r-- | src/user/settings/str_editor.h | 19 | ||||
-rw-r--r-- | src/user/settings/string_kind.cpp | 52 | ||||
-rw-r--r-- | src/user/settings/string_kind.h | 8 |
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 |