summaryrefslogtreecommitdiff
path: root/src/user/raleigh
diff options
context:
space:
mode:
Diffstat (limited to 'src/user/raleigh')
-rw-r--r--src/user/raleigh/d/dialog.cpp74
-rw-r--r--src/user/raleigh/d/saving_window.cpp55
-rw-r--r--src/user/raleigh/runtime.cpp19
-rw-r--r--src/user/raleigh/util.cpp6
-rw-r--r--src/user/raleigh/w/button.cpp6
-rw-r--r--src/user/raleigh/w/colorpicker.cpp6
-rw-r--r--src/user/raleigh/w/entry.cpp33
-rw-r--r--src/user/raleigh/w/multicontainer.cpp16
-rw-r--r--src/user/raleigh/widget.cpp2
-rw-r--r--src/user/raleigh/window.cpp51
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) {