diff options
author | Benji Dial <benji6283@gmail.com> | 2021-03-08 18:06:38 -0500 |
---|---|---|
committer | Benji Dial <benji6283@gmail.com> | 2021-03-08 18:06:38 -0500 |
commit | fd4557c4adddf710979a42e9f9d470bc8b3f77bd (patch) | |
tree | 485ff6f0514cc1918f8758927a1e2da2198e7d8a /src/user | |
parent | 920f1f010284d59bad86f78355ed90ac2f3e1d2c (diff) | |
download | portland-os-fd4557c4adddf710979a42e9f9d470bc8b3f77bd.tar.gz |
hbox, better painting logic in raleigh
Diffstat (limited to 'src/user')
-rw-r--r-- | src/user/include/cxx/raleigh/w/entry.h | 1 | ||||
-rw-r--r-- | src/user/include/cxx/raleigh/w/hbox.h | 18 | ||||
-rw-r--r-- | src/user/include/cxx/raleigh/w/multicontainer.h | 29 | ||||
-rw-r--r-- | src/user/include/cxx/raleigh/w/vbox.h | 14 | ||||
-rw-r--r-- | src/user/include/cxx/raleigh/widget.h | 1 | ||||
-rw-r--r-- | src/user/raleigh/w/button.cpp | 20 | ||||
-rw-r--r-- | src/user/raleigh/w/entry.cpp | 8 | ||||
-rw-r--r-- | src/user/raleigh/w/hbox.cpp | 29 | ||||
-rw-r--r-- | src/user/raleigh/w/multicontainer.cpp | 53 | ||||
-rw-r--r-- | src/user/raleigh/w/padding.cpp | 4 | ||||
-rw-r--r-- | src/user/raleigh/w/vbox.cpp | 64 | ||||
-rw-r--r-- | src/user/raleigh/widget.cpp | 2 | ||||
-rw-r--r-- | src/user/raleigh/window.cpp | 1 | ||||
-rw-r--r-- | src/user/rhello/main.cpp | 24 |
14 files changed, 184 insertions, 84 deletions
diff --git a/src/user/include/cxx/raleigh/w/entry.h b/src/user/include/cxx/raleigh/w/entry.h index fcae122..001cae2 100644 --- a/src/user/include/cxx/raleigh/w/entry.h +++ b/src/user/include/cxx/raleigh/w/entry.h @@ -42,7 +42,6 @@ namespace raleigh { //the index of the null terminator uint32_t end_d; - bool first_paint; bool has_focus; bool had_focus_last_paint; bool text_changed_since_last_paint; diff --git a/src/user/include/cxx/raleigh/w/hbox.h b/src/user/include/cxx/raleigh/w/hbox.h new file mode 100644 index 0000000..166056d --- /dev/null +++ b/src/user/include/cxx/raleigh/w/hbox.h @@ -0,0 +1,18 @@ +#ifndef RALEIGH_W_HBOX_H +#define RALEIGH_W_HBOX_H + +#include <raleigh/w/multicontainer.h> + +namespace raleigh { + class hbox : public multicontainer { + public: + //do not modify this list afterward + hbox(dllist<widget &> widgets); + + private: + coord determine_size() override; + void set_child_offsets() override; + }; +} + +#endif
\ No newline at end of file diff --git a/src/user/include/cxx/raleigh/w/multicontainer.h b/src/user/include/cxx/raleigh/w/multicontainer.h new file mode 100644 index 0000000..5ced74f --- /dev/null +++ b/src/user/include/cxx/raleigh/w/multicontainer.h @@ -0,0 +1,29 @@ +#ifndef RALEIGH_W_MULTICONTAINER_H +#define RALEIGH_W_MULTICONTAINER_H + +#include <raleigh/widget.h> +#include <structs/dllist.h> + +namespace raleigh { + class multicontainer : public widget { + public: + void notify_window_change() override; + void paint(_pixel_t *pixbuf, uint32_t pitch) override; + void handle_click(coord window_coords, enum mouse_packet::mouse_button click_type, bool up) override; + void notify_has_opaque_parent(widget *parent) override; + void notify_child_size_change(widget &from, coord old_size) override; + void on_mouse_move(coord window_coords) override; + + protected: + //do not modify this list afterward + //set size to determine_size() in derived constructor + multicontainer(dllist<widget &> widgets); + + virtual coord determine_size() = 0; + virtual void set_child_offsets() = 0; + + dllist<widget &> widgets; + }; +} + +#endif
\ No newline at end of file diff --git a/src/user/include/cxx/raleigh/w/vbox.h b/src/user/include/cxx/raleigh/w/vbox.h index 39f89e9..d51e61d 100644 --- a/src/user/include/cxx/raleigh/w/vbox.h +++ b/src/user/include/cxx/raleigh/w/vbox.h @@ -1,23 +1,17 @@ #ifndef RALEIGH_W_VBOX_H #define RALEIGH_W_VBOX_H -#include <raleigh/widget.h> -#include <structs/dllist.h> +#include <raleigh/w/multicontainer.h> namespace raleigh { - class vbox : public widget { + class vbox : public multicontainer { public: //do not modify this list afterward vbox(dllist<widget &> widgets); - void notify_window_change() override; - void paint(_pixel_t *pixbuf, uint32_t pitch) override; - void handle_click(coord window_coords, enum mouse_packet::mouse_button click_type, bool up) override; - void notify_has_opaque_parent(widget *parent) override; - void notify_child_size_change(widget &from, coord old_size) override; - void on_mouse_move(coord window_coords) override; private: - dllist<widget &> widgets; + coord determine_size() override; + void set_child_offsets() override; }; } diff --git a/src/user/include/cxx/raleigh/widget.h b/src/user/include/cxx/raleigh/widget.h index d499ed4..b53718a 100644 --- a/src/user/include/cxx/raleigh/widget.h +++ b/src/user/include/cxx/raleigh/widget.h @@ -16,6 +16,7 @@ namespace raleigh { widget *parent;//set to zero when root widget window *w; coord window_offset; + bool next_paint_full; //derived classes should not set this outside of the initializer //instead, they should call widget::set_size(coord) 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 <raleigh/w/hbox.h> + +namespace raleigh { + hbox::hbox(dllist<widget &> widgets) + : multicontainer(widgets) { + size = determine_size(); + } + + coord hbox::determine_size() { + uint32_t w = 0, h = 0; + for (dllist<widget &>::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<widget &>::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 <raleigh/w/vbox.h> + +namespace raleigh { + multicontainer::multicontainer(dllist<widget &> 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<widget &>::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<widget &>::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<widget &>::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<widget &>::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 <raleigh/w/vbox.h> namespace raleigh { - vbox::vbox(dllist<widget &> widgets) : widgets(widgets) { + vbox::vbox(dllist<widget &> widgets) + : multicontainer(widgets) { + size = determine_size(); + } + + coord vbox::determine_size() { uint32_t w = 0, h = 0; for (dllist<widget &>::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<widget &>::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<widget &>::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<widget &>::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<widget &>::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<widget &>::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<widget &>::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); } diff --git a/src/user/rhello/main.cpp b/src/user/rhello/main.cpp index 22b4fd5..8ea0bf0 100644 --- a/src/user/rhello/main.cpp +++ b/src/user/rhello/main.cpp @@ -3,6 +3,7 @@ #include <raleigh/w/button.h> #include <raleigh/w/label.h> #include <raleigh/w/entry.h> +#include <raleigh/w/hbox.h> #include <raleigh/w/vbox.h> #include <raleigh/runtime.h> @@ -16,6 +17,7 @@ using namespace raleigh; colorpicker *cp; label *p_l; window *p_w; +label *l; void onclick(button &from) { const _pixel_t pc = cp->get_picked_color(); @@ -25,23 +27,37 @@ void onclick(button &from) { p_w->show(); } +void onclick2(button &from) { + l->change_value("I can be changed on the fly."); +} + void main() { - label l("Hello, world! Close me with Alt+F4."); - padding pl(l, 2); + l = new label("Hello, world! Close me with Alt+F4."); + padding pl(*l, 2); label bl("Click me!"); padding pbl(bl, 4); button b(pbl, &onclick); padding pb(b, 2); - entry e(8, 31, "This window is made with the Raleigh widget toolkit for Portland OS.\n\nI am a text entry widget. My cursor can be used, but editing is not yet implemented."); + label b2l("Click me too!"); + padding pb2l(b2l, 4); + button b2(pb2l, &onclick2); + padding pb2(b2, 2); + + dllist<widget &> bbl; + bbl.add_front(pb2); + bbl.add_front(pb); + hbox bb(bbl); + + entry e(8, 31, "This window is made with the Raleigh widget toolkit for Portland OS.\n\nI am a text entry widget. You can move my cursor, but I cannot yet be edited."); padding pe(e, 2); cp = new colorpicker(); padding pcp(*cp, 2); dllist<widget &> wl; - wl.add_front(pb); + wl.add_front(bb); wl.add_front(pcp); wl.add_front(pe); wl.add_front(pl); |