summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBenji Dial <benji6283@gmail.com>2021-03-08 18:06:38 -0500
committerBenji Dial <benji6283@gmail.com>2021-03-08 18:06:38 -0500
commitfd4557c4adddf710979a42e9f9d470bc8b3f77bd (patch)
tree485ff6f0514cc1918f8758927a1e2da2198e7d8a /src
parent920f1f010284d59bad86f78355ed90ac2f3e1d2c (diff)
downloadportland-os-fd4557c4adddf710979a42e9f9d470bc8b3f77bd.tar.gz
hbox, better painting logic in raleigh
Diffstat (limited to 'src')
-rw-r--r--src/user/include/cxx/raleigh/w/entry.h1
-rw-r--r--src/user/include/cxx/raleigh/w/hbox.h18
-rw-r--r--src/user/include/cxx/raleigh/w/multicontainer.h29
-rw-r--r--src/user/include/cxx/raleigh/w/vbox.h14
-rw-r--r--src/user/include/cxx/raleigh/widget.h1
-rw-r--r--src/user/raleigh/w/button.cpp20
-rw-r--r--src/user/raleigh/w/entry.cpp8
-rw-r--r--src/user/raleigh/w/hbox.cpp29
-rw-r--r--src/user/raleigh/w/multicontainer.cpp53
-rw-r--r--src/user/raleigh/w/padding.cpp4
-rw-r--r--src/user/raleigh/w/vbox.cpp64
-rw-r--r--src/user/raleigh/widget.cpp2
-rw-r--r--src/user/raleigh/window.cpp1
-rw-r--r--src/user/rhello/main.cpp24
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);