From fd4557c4adddf710979a42e9f9d470bc8b3f77bd Mon Sep 17 00:00:00 2001 From: Benji Dial Date: Mon, 8 Mar 2021 18:06:38 -0500 Subject: hbox, better painting logic in raleigh --- src/user/raleigh/w/button.cpp | 20 ++++++----- src/user/raleigh/w/entry.cpp | 8 ++--- src/user/raleigh/w/hbox.cpp | 29 ++++++++++++++++ src/user/raleigh/w/multicontainer.cpp | 53 +++++++++++++++++++++++++++++ src/user/raleigh/w/padding.cpp | 4 +++ src/user/raleigh/w/vbox.cpp | 64 +++++------------------------------ src/user/raleigh/widget.cpp | 2 +- src/user/raleigh/window.cpp | 1 + 8 files changed, 112 insertions(+), 69 deletions(-) create mode 100644 src/user/raleigh/w/hbox.cpp create mode 100644 src/user/raleigh/w/multicontainer.cpp (limited to 'src/user/raleigh') diff --git a/src/user/raleigh/w/button.cpp b/src/user/raleigh/w/button.cpp index 224b930..da88f6a 100644 --- a/src/user/raleigh/w/button.cpp +++ b/src/user/raleigh/w/button.cpp @@ -18,18 +18,22 @@ namespace raleigh { } void button::paint(_pixel_t *pixbuf, uint32_t pitch) { + if (next_paint_full) { + next_paint_full = false; + for (uint32_t x = window_offset.x; x < window_offset.x + size.x; ++x) { + pixbuf[window_offset.y * pitch + x] = border_color; + pixbuf[(window_offset.y + size.y - 1) * pitch + x] = border_color; + } + for (uint32_t y = window_offset.y + 1; y < window_offset.y + size.y - 1; ++y) { + pixbuf[y * pitch + window_offset.x] = border_color; + pixbuf[y * pitch + window_offset.x + size.x - 1] = border_color; + } + } for (uint32_t y = window_offset.y + 1; y < window_offset.y + size.y - 1; ++y) for (uint32_t x = window_offset.x + 1; x < window_offset.x + size.x - 1; ++x) pixbuf[y * pitch + x] = is_pressed ? pressed_color : bg_color; + inner.next_paint_full = true; inner.paint(pixbuf, pitch); - for (uint32_t x = window_offset.x; x < window_offset.x + size.x; ++x) { - pixbuf[window_offset.y * pitch + x] = border_color; - pixbuf[(window_offset.y + size.y - 1) * pitch + x] = border_color; - } - for (uint32_t y = window_offset.y + 1; y < window_offset.y + size.y - 1; ++y) { - pixbuf[y * pitch + window_offset.x] = border_color; - pixbuf[y * pitch + window_offset.x + size.x - 1] = border_color; - } } void button::handle_click(coord window_coords, enum mouse_packet::mouse_button click_type, bool up) { diff --git a/src/user/raleigh/w/entry.cpp b/src/user/raleigh/w/entry.cpp index 1c6f91e..991d75a 100644 --- a/src/user/raleigh/w/entry.cpp +++ b/src/user/raleigh/w/entry.cpp @@ -9,8 +9,7 @@ namespace raleigh { 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]), first_paint(true), - has_focus(false) { + 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; @@ -78,7 +77,9 @@ namespace raleigh { _pixel_t *const cur_ptr = pixbuf + (window_offset.y + 3 + cur_y * fi->space_height) * pitch + (window_offset.x + 3 + cur_x * fi->space_width); _pixel_t *const old_cur_ptr = pixbuf + (window_offset.y + 3 + cur_y_last_paint * fi->space_height) * pitch + (window_offset.x + 3 + cur_x_last_paint * fi->space_width); - if (first_paint) { + if (next_paint_full) { + next_paint_full = false; + for (uint32_t x = 0; x < size.x; ++x) { pixbuf[(window_offset.y) * pitch + window_offset.x + x] = border_color; pixbuf[(window_offset.y + size.y - 1) * pitch + window_offset.x + x] = border_color; @@ -93,7 +94,6 @@ namespace raleigh { pixbuf[(window_offset.y + y) * pitch + (window_offset.x + x)] = bg; paint_text(pixbuf, pitch); - first_paint = false; } else if (text_changed_since_last_paint) { diff --git a/src/user/raleigh/w/hbox.cpp b/src/user/raleigh/w/hbox.cpp new file mode 100644 index 0000000..e989ff7 --- /dev/null +++ b/src/user/raleigh/w/hbox.cpp @@ -0,0 +1,29 @@ +#include + +namespace raleigh { + hbox::hbox(dllist widgets) + : multicontainer(widgets) { + size = determine_size(); + } + + coord hbox::determine_size() { + uint32_t w = 0, h = 0; + for (dllist::node *n = widgets.first; n; n = n->next) { + n->d.parent = this; + w += n->d.size.x; + if (n->d.size.y > h) + h = n->d.size.y; + } + return coord(w, h); + } + + void hbox::set_child_offsets() { + uint32_t x = window_offset.x; + for (dllist::node *n = widgets.first; n; n = n->next) { + n->d.w = w; + n->d.window_offset = coord(x, window_offset.y + size.y / 2 - n->d.size.y / 2); + n->d.notify_window_change(); + x += n->d.size.x; + } + } +} \ No newline at end of file diff --git a/src/user/raleigh/w/multicontainer.cpp b/src/user/raleigh/w/multicontainer.cpp new file mode 100644 index 0000000..3021deb --- /dev/null +++ b/src/user/raleigh/w/multicontainer.cpp @@ -0,0 +1,53 @@ +#include + +namespace raleigh { + multicontainer::multicontainer(dllist widgets) + : widgets(widgets) { + closest_opaque = 0; + } + + void multicontainer::notify_window_change() { + set_child_offsets(); + } + + void multicontainer::paint(_pixel_t *pixbuf, uint32_t pitch) { + for (dllist::node *n = widgets.first; n; n = n->next) { + if (next_paint_full) + n->d.next_paint_full = true; + n->d.paint(pixbuf, pitch); + } + if (next_paint_full) + next_paint_full = false; + } + + void multicontainer::handle_click(coord window_coords, enum mouse_packet::mouse_button click_type, bool up) { + for (dllist::node *n = widgets.first; n; n = n->next) + if ((window_coords.x >= n->d.window_offset.x) && + (window_coords.y >= n->d.window_offset.y) && + (window_coords.x < n->d.window_offset.x + n->d.size.x) && + (window_coords.y < n->d.window_offset.y + n->d.size.y)) + n->d.handle_click(window_coords, click_type, up); + } + + void multicontainer::notify_has_opaque_parent(widget *parent) { + closest_opaque = parent; + for (dllist::node *n = widgets.first; n; n = n->next) + n->d.notify_has_opaque_parent(parent); + } + + void multicontainer::notify_child_size_change(widget &from, coord old_size) { + set_size(determine_size()); + set_child_offsets(); + } + + void multicontainer::on_mouse_move(coord window_coords) { + for (dllist::node *n = widgets.first; n; n = n->next) + if ((window_coords.x >= n->d.window_offset.x) && + (window_coords.y >= n->d.window_offset.y) && + (window_coords.x < n->d.window_offset.x + n->d.size.x) && + (window_coords.y < n->d.window_offset.y + n->d.size.y)) { + n->d.on_mouse_move(window_coords); + return; + } + } +} \ No newline at end of file diff --git a/src/user/raleigh/w/padding.cpp b/src/user/raleigh/w/padding.cpp index 782a8a9..21289d4 100644 --- a/src/user/raleigh/w/padding.cpp +++ b/src/user/raleigh/w/padding.cpp @@ -15,6 +15,10 @@ namespace raleigh { } void padding::paint(_pixel_t *pixbuf, uint32_t pitch) { + if (next_paint_full) { + next_paint_full = false; + inner.next_paint_full = true; + } inner.paint(pixbuf, pitch); } diff --git a/src/user/raleigh/w/vbox.cpp b/src/user/raleigh/w/vbox.cpp index 77ce592..b05c8bf 100644 --- a/src/user/raleigh/w/vbox.cpp +++ b/src/user/raleigh/w/vbox.cpp @@ -1,7 +1,12 @@ #include namespace raleigh { - vbox::vbox(dllist widgets) : widgets(widgets) { + vbox::vbox(dllist widgets) + : multicontainer(widgets) { + size = determine_size(); + } + + coord vbox::determine_size() { uint32_t w = 0, h = 0; for (dllist::node *n = widgets.first; n; n = n->next) { n->d.parent = this; @@ -9,11 +14,10 @@ namespace raleigh { if (n->d.size.x > w) w = n->d.size.x; } - size = coord(w, h); - closest_opaque = 0; + return coord(w, h); } - void vbox::notify_window_change() { + void vbox::set_child_offsets() { uint32_t h = window_offset.y; for (dllist::node *n = widgets.first; n; n = n->next) { n->d.w = w; @@ -22,56 +26,4 @@ namespace raleigh { h += n->d.size.y; } } - - void vbox::paint(_pixel_t *pixbuf, uint32_t pitch) { - for (dllist::node *n = widgets.first; n; n = n->next) - n->d.paint(pixbuf, pitch); - } - - void vbox::handle_click(coord window_coords, enum mouse_packet::mouse_button click_type, bool up) { - uint32_t h = window_offset.y; - dllist::node *n = widgets.first; - while (h + n->d.size.y <= window_coords.y) { - h += n->d.size.y; - n = n->next; - } - if ((window_coords.x >= n->d.window_offset.x) && - (window_coords.x < n->d.window_offset.x + n->d.size.x)) - n->d.handle_click(window_coords, click_type, up); - } - - void vbox::notify_has_opaque_parent(widget *parent) { - closest_opaque = parent; - for (dllist::node *n = widgets.first; n; n = n->next) - n->d.notify_has_opaque_parent(parent); - } - - void vbox::notify_child_size_change(widget &from, coord old_size) { - if ((old_size.y == from.size.y) && (from.size.x <= size.x)) { - from.window_offset.x = window_offset.x + size.x / 2 - from.size.x / 2; - from.notify_window_change(); - } - - else {//lazy, less efficient approach - uint32_t h = 0, w = 0; - for (dllist::node *n = widgets.first; n; n = n->next) { - h += n->d.size.y; - if (n->d.size.x > w) - w = n->d.size.x; - } - set_size(coord(w, h)); - notify_window_change(); - } - } - - void vbox::on_mouse_move(coord window_coords) { - for (dllist::node *n = widgets.first; n; n = n->next) - if ((window_coords.x >= n->d.window_offset.x) && - (window_coords.y >= n->d.window_offset.y) && - (window_coords.x < n->d.window_offset.x + n->d.size.x) && - (window_coords.y < n->d.window_offset.y + n->d.size.y)) { - n->d.on_mouse_move(window_coords); - return; - } - } } \ No newline at end of file diff --git a/src/user/raleigh/widget.cpp b/src/user/raleigh/widget.cpp index 0a47c3b..df9c661 100644 --- a/src/user/raleigh/widget.cpp +++ b/src/user/raleigh/widget.cpp @@ -4,7 +4,7 @@ namespace raleigh { widget::widget() - : parent(0) {} + : parent(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 cb9f363..8501f7e 100644 --- a/src/user/raleigh/window.cpp +++ b/src/user/raleigh/window.cpp @@ -73,6 +73,7 @@ namespace raleigh { void window::paint_full() { for (uint32_t i = 0; i < size.x * size.y; ++i) pixbuf[i] = bg_color; + root.next_paint_full = true; root.paint(pixbuf, size.x); } -- cgit v1.2.3