diff options
Diffstat (limited to 'src/user/raleigh')
-rw-r--r-- | src/user/raleigh/d/dialog.cpp | 74 | ||||
-rw-r--r-- | src/user/raleigh/d/saving_window.cpp | 55 | ||||
-rw-r--r-- | src/user/raleigh/runtime.cpp | 19 | ||||
-rw-r--r-- | src/user/raleigh/util.cpp | 6 | ||||
-rw-r--r-- | src/user/raleigh/w/button.cpp | 6 | ||||
-rw-r--r-- | src/user/raleigh/w/colorpicker.cpp | 6 | ||||
-rw-r--r-- | src/user/raleigh/w/entry.cpp | 33 | ||||
-rw-r--r-- | src/user/raleigh/w/multicontainer.cpp | 16 | ||||
-rw-r--r-- | src/user/raleigh/widget.cpp | 2 | ||||
-rw-r--r-- | src/user/raleigh/window.cpp | 51 |
10 files changed, 217 insertions, 51 deletions
diff --git a/src/user/raleigh/d/dialog.cpp b/src/user/raleigh/d/dialog.cpp new file mode 100644 index 0000000..38ca310 --- /dev/null +++ b/src/user/raleigh/d/dialog.cpp @@ -0,0 +1,74 @@ +#include <raleigh/d/dialog.h> + +#include <raleigh/w/padding.h> +#include <raleigh/w/button.h> +#include <raleigh/w/label.h> +#include <raleigh/w/hbox.h> + +using namespace raleigh; + +void dialog::show_modal() { + show(); + do { + _wait_for_action(); + _yield_task(); + consume_actions(); + } while (!result); + to_be_deleted.add_back(*this); +} + +static bool on_diag_close(window_tag_t) { + return false; +} + +struct diag_and_result { + dialog *d; + diag_result_t r; + diag_and_result(dialog *d, diag_result_t r) + : d(d), r(r) {} +}; + +static void set_diag_result(button_tag_t tag) { + const diag_and_result *const cast = (const diag_and_result *)tag; + cast->d->result = cast->r; + //TODO: go through all of raleigh and add destructors + //in this case, delete all of these tags when the window is closed +} + +dialog::dialog(widget &top_part, alist<duple<const char *, diag_result_t>> buttons) + : window(*new vbox(), RGB(bf, bf, bf), &on_diag_close), result(0), main_box((vbox *)&root) { + dllist<widget &> *button_row = new dllist<widget &>(); + for (duple<const char *, diag_result_t> *i = buttons.buf; i < buttons.buf + buttons.n_entries; ++i) { + label *l = new label(i->a); + padding *p = new padding(*l, 4); + button *b = new button(*p, &set_diag_result, new diag_and_result(this, i->b)); + padding *pb = new padding(*b, 2); + button_row->add_back(*pb); + } + hbox *button_box = new hbox(*button_row); + + padding *ptop = new padding(top_part, 2); + padding *pbot = new padding(*button_box, 2); + + main_box->add_end(*ptop); + main_box->add_end(*pbot); +} + +alist<duple<const char *, diag_result_t>> &mk_yes_no_cancel() { + alist<duple<const char *, diag_result_t>> *list = new alist<duple<const char *, diag_result_t>>(3, 1); + list->add_back(duple<const char *, diag_result_t>("Yes", YES)); + list->add_back(duple<const char *, diag_result_t>("No", NO)); + list->add_back(duple<const char *, diag_result_t>("Cancel", CANCEL)); + return *list; +} + +alist<duple<const char *, diag_result_t>> &mk_yes_no_retry() { + alist<duple<const char *, diag_result_t>> *list = new alist<duple<const char *, diag_result_t>>(3, 1); + list->add_back(duple<const char *, diag_result_t>("Yes", YES)); + list->add_back(duple<const char *, diag_result_t>("No", NO)); + list->add_back(duple<const char *, diag_result_t>("Retry", RETRY)); + return *list; +} + +alist<duple<const char *, diag_result_t>> &raleigh::yes_no_cancel(mk_yes_no_cancel()); +alist<duple<const char *, diag_result_t>> &raleigh::yes_no_retry(mk_yes_no_retry());
\ No newline at end of file diff --git a/src/user/raleigh/d/saving_window.cpp b/src/user/raleigh/d/saving_window.cpp new file mode 100644 index 0000000..a2d57e4 --- /dev/null +++ b/src/user/raleigh/d/saving_window.cpp @@ -0,0 +1,55 @@ +#include <raleigh/d/saving_window.h> +#include <raleigh/d/dialog.h> + +#include <raleigh/w/padding.h> +#include <raleigh/w/button.h> +#include <raleigh/w/label.h> +#include <raleigh/w/hbox.h> +#include <raleigh/w/vbox.h> + +#include <structs/dllist.h> + +namespace raleigh { + bool on_saving_window_close(window_tag_t tag) { + saving_window *const sw = (saving_window *)tag; + if (sw->is_saved) + return true; + + label text("There is unsaved content in this window."); + label text2("Would you like to save before closing it?"); + + dllist<widget &> rows; + rows.add_back(text); + rows.add_back(text2); + vbox vb(rows); + padding vbp(vb, 2); + + dialog diag(vbp, yes_no_cancel); + diag.show_modal(); + + switch (diag.result) { + case YES: + save: + if (!sw->save_func(sw->save_tag)) { + label text3("Failing saved. Still quit?"); + dialog diag2(text3, yes_no_retry); + diag2.show_modal(); + switch (diag2.result) { + case YES: + return true; + case RETRY: + goto save; + default: + return false; + } + } + case NO: + return true; + default: + return false; + } + } + + saving_window::saving_window(bool (*save_func)(save_tag_t), save_tag_t save_tag, widget &root, _pixel_t bg_color) + : window(root, bg_color, &on_saving_window_close, (window_tag_t)this), is_saved(true), save_func(save_func), save_tag(save_tag) {} +}
\ No newline at end of file diff --git a/src/user/raleigh/runtime.cpp b/src/user/raleigh/runtime.cpp index 6dafed1..d021537 100644 --- a/src/user/raleigh/runtime.cpp +++ b/src/user/raleigh/runtime.cpp @@ -4,19 +4,24 @@ namespace raleigh { dllist<window &> open_windows; + dllist<window &> to_be_deleted; __attribute__ ((noreturn)) void start_runtime() { while (1) { + for (dllist<window &>::node *w = open_windows.first; w; w = w->next) + w->d.consume_actions(); + l: + for (dllist<window &>::node *w = to_be_deleted.first; w; w = w->next) { + _delete_window(w->d.handle); + w->d.handle = 0; + open_windows.try_remove_by_ref(w->d); + w = to_be_deleted.remove_in_place(w); + if (!w) + goto l; + } if (!open_windows.first) __pcrt_quit(); - for (dllist<window &>::node *w = open_windows.first; w; w = w->next) - if (w->d.try_actions() == window::DELETE) { - _delete_window(w->d.handle); - w->d.handle = 0; - if (!(w = open_windows.remove_in_place(w))) - break; - } _wait_for_action(); _yield_task(); } diff --git a/src/user/raleigh/util.cpp b/src/user/raleigh/util.cpp index db0982b..a300d01 100644 --- a/src/user/raleigh/util.cpp +++ b/src/user/raleigh/util.cpp @@ -1,5 +1,5 @@ #include <raleigh/util.h> -#include <popups/info.h> +#include <knob/format.h> #include <pland/pcrt.h> namespace raleigh { @@ -13,9 +13,7 @@ namespace raleigh { va_list args; va_start(args, fmt); - struct popup info; - info_popupf_v(&info, fmt, RGB(7f, 00, 00), RGB(bf, bf, bf), args); - make_modal(&info); + syslogf_v(fmt, args); __pcrt_quit(); } diff --git a/src/user/raleigh/w/button.cpp b/src/user/raleigh/w/button.cpp index 5b5f756..b035ee2 100644 --- a/src/user/raleigh/w/button.cpp +++ b/src/user/raleigh/w/button.cpp @@ -1,9 +1,9 @@ #include <raleigh/w/button.h> namespace raleigh { - button::button(widget &inner, void (*on_click)(button &), + button::button(widget &inner, void (*on_click)(button_tag_t), button_tag_t tag, _pixel_t border_color, _pixel_t bg_color, _pixel_t pressed_color) - : inner(inner), on_click(on_click), border_color(border_color), + : inner(inner), on_click(on_click), tag(tag), border_color(border_color), bg_color(bg_color), pressed_color(pressed_color), is_pressed(false) { size = coord(inner.size.x + 2, inner.size.y + 2); closest_opaque = this; @@ -44,7 +44,7 @@ namespace raleigh { inner.window_offset = coord(window_offset.x + 1, window_offset.y + 1); inner.notify_window_change(); w->notify_needs_paint(*this); - on_click(*this); + on_click(tag); } else { is_pressed = true; diff --git a/src/user/raleigh/w/colorpicker.cpp b/src/user/raleigh/w/colorpicker.cpp index 5a9aa82..281eaaf 100644 --- a/src/user/raleigh/w/colorpicker.cpp +++ b/src/user/raleigh/w/colorpicker.cpp @@ -32,6 +32,12 @@ namespace raleigh { pb_ptr[y * pitch + x] = picked_color; } + void colorpicker::set_picked_color(_pixel_t c) { + picked_color = c; + if (w) + w->notify_needs_paint(*this); + } + void colorpicker::handle_click(coord window_coords, enum mouse_packet::mouse_button click_type, bool up) { if (up || (click_type != mouse_packet::LEFT)) return; diff --git a/src/user/raleigh/w/entry.cpp b/src/user/raleigh/w/entry.cpp index 991d75a..3053413 100644 --- a/src/user/raleigh/w/entry.cpp +++ b/src/user/raleigh/w/entry.cpp @@ -5,18 +5,10 @@ #include <knob/key.h> namespace raleigh { - entry::entry(uint32_t rows, uint32_t cols, const char *default_text, - const char *font, _pixel_t bg, _pixel_t fg, _pixel_t border_color) - : rows(rows), cols(cols), bg(bg), fg(fg), border_color(border_color), - fi(get_font(font)), data(new char[rows * cols]), - line_indices(new uint32_t[rows + 1]), has_focus(false) { - size = coord(fi->space_width * (cols - 1) + fi->char_width + 6, - fi->space_height * (rows - 1) + fi->char_height + 6); - closest_opaque = this; - - const uint32_t l = strlen(default_text); + void entry::set_contents(const char *s) { + const uint32_t l = strlen(s); const uint32_t cl = l > rows * cols - 1 ? rows * cols - 1 : l; - blockcpy(data, default_text, cl); + blockcpy(data, s, cl); data[cl] = '\0'; line_indices[0] = 0; @@ -24,6 +16,21 @@ namespace raleigh { cur_x = end_x; cur_y = end_y; cur_d = end_d; + + next_paint_full = true; + if (w) + w->notify_needs_paint(*this); + } + + entry::entry(uint32_t rows, uint32_t cols, const char *default_text, + const char *font, _pixel_t bg, _pixel_t fg, _pixel_t border_color) + : rows(rows), cols(cols), bg(bg), fg(fg), border_color(border_color), + fi(get_font(font)), data(new char[rows * cols]), + line_indices(new uint32_t[rows + 1]), has_focus(false) { + size = coord(fi->space_width * (cols - 1) + fi->char_width + 6, + fi->space_height * (rows - 1) + fi->char_height + 6); + closest_opaque = this; + set_contents(default_text); } void entry::get_indices(uint32_t from_y, uint32_t from_x, uint32_t from_d) { @@ -260,4 +267,8 @@ namespace raleigh { has_focus = false; w->notify_needs_paint(*this); } + + const char *entry::get_contents() { + return data; + } }
\ No newline at end of file diff --git a/src/user/raleigh/w/multicontainer.cpp b/src/user/raleigh/w/multicontainer.cpp index edc60aa..d713f51 100644 --- a/src/user/raleigh/w/multicontainer.cpp +++ b/src/user/raleigh/w/multicontainer.cpp @@ -39,4 +39,20 @@ namespace raleigh { set_size(determine_size()); set_child_offsets(); } + + void multicontainer::add_end(widget &n) { + widgets.add_back(n); + set_size(determine_size()); + set_child_offsets(); + if (w) + w->notify_needs_paint(*this); + } + + void multicontainer::add_start(widget &n) { + widgets.add_front(n); + set_size(determine_size()); + set_child_offsets(); + if (w) + w->notify_needs_paint(*this); + } }
\ No newline at end of file diff --git a/src/user/raleigh/widget.cpp b/src/user/raleigh/widget.cpp index df9c661..48a0496 100644 --- a/src/user/raleigh/widget.cpp +++ b/src/user/raleigh/widget.cpp @@ -4,7 +4,7 @@ namespace raleigh { widget::widget() - : parent(0), next_paint_full(true) {} + : parent(0), w(0), next_paint_full(true) {} void widget::notify_window_change() {} void widget::handle_click(coord window_coords, enum mouse_packet::mouse_button click_type, bool up) {} diff --git a/src/user/raleigh/window.cpp b/src/user/raleigh/window.cpp index b99346d..5fa82c3 100644 --- a/src/user/raleigh/window.cpp +++ b/src/user/raleigh/window.cpp @@ -5,25 +5,26 @@ #include <knob/format.h> namespace raleigh { - window::window(widget &root, _pixel_t bg_color, bool (*on_close)(window &)) - : handle(0), size(root.size), root(root), focussed(&root), - drag_reciever(0), bg_color(bg_color), on_close(on_close) { + window::window(widget &root, _pixel_t bg_color, bool (*on_close)(window_tag_t), window_tag_t tag) + : root(root), handle(0), pixbuf(0), size(root.size), focussed(&root), + drag_reciever(0), bg_color(bg_color), on_close(on_close), tag(tag) { root.w = this; root.window_offset = coord(0, 0); root.notify_window_change(); - pixbuf = new _pixel_t[size.x * size.y]; - if (!pixbuf) - show_error_and_quitf("Failed to create %d byte pixel buffer\nfor requested %dx%d pixel window.", size.x * size.y * sizeof(_pixel_t), size.x, size.y); + if (size.x && size.y) { + pixbuf = new _pixel_t[size.x * size.y]; + if (!pixbuf) + show_error_and_quitf("Failed to create %d byte pixel buffer\nfor requested %dx%d pixel window.", size.x * size.y * sizeof(_pixel_t), size.x, size.y); + } paint_full(); root.on_focus(); needs_repaint = false; } - window::try_actions_return_t window::try_actions() { + void window::consume_actions() { struct window_action wa; - window::try_actions_return_t got = NONE; while (1) { _get_win_action(handle, &wa); if (!wa.action_type) { @@ -31,15 +32,17 @@ namespace raleigh { needs_repaint = false; _paint_window(handle); } - return got; + return; } if ((wa.action_type == wa.KEY_DOWN) && (wa.as_key.modifiers & wa.as_key.ALTS) && - (wa.as_key.key_id == wa.as_key.KEY_F4)) - if (!on_close || on_close(*this)) - return DELETE; - got = GOOD; - if (wa.action_type == wa.MOUSE_DOWN) + (wa.as_key.key_id == wa.as_key.KEY_F4)) { + if (!on_close || on_close(tag)) { + to_be_deleted.add_back(*this); + return; + } + } + else if (wa.action_type == wa.MOUSE_DOWN) root.handle_click(coord(wa.as_mouse.x, wa.as_mouse.y), wa.as_mouse.which, false); else if (wa.action_type == wa.MOUSE_UP) { if (drag_reciever && (wa.as_mouse.which == drag_until)) @@ -47,14 +50,11 @@ namespace raleigh { root.handle_click(coord(wa.as_mouse.x, wa.as_mouse.y), wa.as_mouse.which, true); } else if (wa.action_type == wa.KEY_DOWN) { - for (dllist<duple<struct key_packet, void (*)(window &)>>::node *n = keybinds.first; n; n = n->next) - if (match_side_agnostic(wa.as_key, n->d.a)) { - n->d.b(*this); - goto next_loop; - } - focussed->handle_key(wa.as_key); - next_loop: - ; + void (*const f)(window_tag_t) = keybinds.transform(wa.as_key); + if (f) + f(tag); + else + focussed->handle_key(wa.as_key); } else if (wa.action_type == wa.FOCUS_ENTER) focussed->on_focus(); @@ -103,7 +103,8 @@ namespace raleigh { from.parent->notify_child_size_change(from, old_size); else { size = root.size; - delete[] pixbuf; + if (pixbuf) + delete[] pixbuf; pixbuf = new _pixel_t[size.x * size.y]; if (!pixbuf) show_error_and_quitf("Failed to allocate %u byte buffer while\nresizing window to %ux%u pixels.", size.x * size.y, size.x, size.y); @@ -112,8 +113,8 @@ namespace raleigh { } } - void window::add_keybind(struct key_packet kp, void (*handler)(window &)) { - keybinds.add_front(duple<struct key_packet, void (*)(window &)>(kp, handler)); + void window::add_keybind(struct key_packet kp, void (*handler)(window_tag_t)) { + keybinds.add_pair(kp, handler); } void window::notify_wants_movements(widget &from, enum mouse_packet::mouse_button while_down) { |