summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/user/include/cxx/raleigh/w/button.h4
-rw-r--r--src/user/include/cxx/raleigh/w/label.h12
-rw-r--r--src/user/include/cxx/raleigh/w/padding.h4
-rw-r--r--src/user/include/cxx/raleigh/w/vbox.h4
-rw-r--r--src/user/include/cxx/raleigh/widget.h28
-rw-r--r--src/user/include/cxx/raleigh/window.h6
-rw-r--r--src/user/include/cxx/structs/duple.h13
-rw-r--r--src/user/include/knob/key.h3
-rw-r--r--src/user/knob/key.c12
-rw-r--r--src/user/meminfo/meminfo.c31
-rw-r--r--src/user/meminfo/meminfo.cpp51
-rw-r--r--src/user/raleigh/w/button.cpp11
-rw-r--r--src/user/raleigh/w/label.cpp27
-rw-r--r--src/user/raleigh/w/padding.cpp7
-rw-r--r--src/user/raleigh/w/vbox.cpp21
-rw-r--r--src/user/raleigh/widget.cpp22
-rw-r--r--src/user/raleigh/window.cpp31
-rw-r--r--src/user/runtimes/cxx/extra.ld5
18 files changed, 209 insertions, 83 deletions
diff --git a/src/user/include/cxx/raleigh/w/button.h b/src/user/include/cxx/raleigh/w/button.h
index 03e17ab..71ccae2 100644
--- a/src/user/include/cxx/raleigh/w/button.h
+++ b/src/user/include/cxx/raleigh/w/button.h
@@ -12,10 +12,8 @@ namespace raleigh {
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_child_size_change(widget &child, coord old_size) override;
void notify_has_opaque_parent(widget *parent) override;
- void handle_key(struct key_packet kp) override;
- void on_focus() override;
- void on_unfocus() override;
private:
widget &inner;
void (*on_click)(button &);
diff --git a/src/user/include/cxx/raleigh/w/label.h b/src/user/include/cxx/raleigh/w/label.h
index 4b1dae2..a78ce46 100644
--- a/src/user/include/cxx/raleigh/w/label.h
+++ b/src/user/include/cxx/raleigh/w/label.h
@@ -7,19 +7,17 @@
namespace raleigh {
class label : public widget {
public:
- //this pointer is used directly, and the contents of the string should not be changed afterward
+ //value's data is copied
label(const char *value, const char *font="fixed-10", bool bg_transparent=true,
_pixel_t fg=RGB(00, 00, 00), _pixel_t bg=RGB(bf, bf, bf));
- void notify_window_change() override;
+ void change_value(const char *new_value);
+
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 handle_key(struct key_packet kp) override;
- void on_focus() override;
- void on_unfocus() override;
private:
- const char *const value;
+ char *value;
+ uint32_t v_size;
const struct font_info *const fi;
bool bg_transparent;
const _pixel_t fg;
diff --git a/src/user/include/cxx/raleigh/w/padding.h b/src/user/include/cxx/raleigh/w/padding.h
index 792e204..1bdb9ee 100644
--- a/src/user/include/cxx/raleigh/w/padding.h
+++ b/src/user/include/cxx/raleigh/w/padding.h
@@ -12,9 +12,7 @@ namespace raleigh {
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 handle_key(struct key_packet kp) override;
- void on_focus() override;
- void on_unfocus() override;
+ void notify_child_size_change(widget &child, coord old_size) override;
private:
widget &inner;
uint32_t pad_by;
diff --git a/src/user/include/cxx/raleigh/w/vbox.h b/src/user/include/cxx/raleigh/w/vbox.h
index 02bffd3..f715f95 100644
--- a/src/user/include/cxx/raleigh/w/vbox.h
+++ b/src/user/include/cxx/raleigh/w/vbox.h
@@ -14,9 +14,7 @@ namespace raleigh {
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 handle_key(struct key_packet kp) override;
- void on_focus() override;
- void on_unfocus() override;
+ void notify_child_size_change(widget &from, coord old_size) override;
private:
dllist<widget &> widgets;
};
diff --git a/src/user/include/cxx/raleigh/widget.h b/src/user/include/cxx/raleigh/widget.h
index 54b9287..1b2cf6f 100644
--- a/src/user/include/cxx/raleigh/widget.h
+++ b/src/user/include/cxx/raleigh/widget.h
@@ -12,12 +12,15 @@ namespace raleigh {
namespace raleigh {
class widget {
public:
- coord size;
-
- //set by window class (or parent widget)
+ //these three are set by window class (or parent widget)
+ widget *parent;//set to zero when root widget
window *w;
coord window_offset;
+ //derived classes should not set this outside of the initializer
+ //instead, they should call widget::set_size(coord)
+ coord size;
+
//fewest steps up that a widget can be redrawn without needing its parents
//if a widget is opaque, it will set this to a pointer to itself, and then call
// notify_has_opaque_parent on any children, passing itself as an argument.
@@ -25,14 +28,21 @@ namespace raleigh {
// and then call notify_has_opaque_parent on any children (with the opaque parent).
widget *closest_opaque;
- //called by window class (or parent widget)
- virtual void notify_window_change() = 0;
+ //these are called by window class (or parent widgets)
+ virtual void notify_window_change();
virtual void paint(_pixel_t *pixbuf, uint32_t pitch) = 0;
- virtual void handle_click(coord window_coords, enum mouse_packet::mouse_button click_type, bool up) = 0;
+ virtual void handle_click(coord window_coords, enum mouse_packet::mouse_button click_type, bool up);
virtual void notify_has_opaque_parent(widget *parent) = 0;
- virtual void handle_key(struct key_packet kp) = 0;
- virtual void on_focus() = 0;
- virtual void on_unfocus() = 0;
+ virtual void handle_key(struct key_packet kp);
+ virtual void on_focus();
+ virtual void on_unfocus();
+ //this next one is not to be called by child widgets
+ //they should call window::notify_widget_size_change(widget &), which will call this if necessary
+ virtual void notify_child_size_change(widget &child, coord old_size);
+
+ protected:
+ widget();
+ void set_size(coord to);
};
}
diff --git a/src/user/include/cxx/raleigh/window.h b/src/user/include/cxx/raleigh/window.h
index 21ae511..0dd9341 100644
--- a/src/user/include/cxx/raleigh/window.h
+++ b/src/user/include/cxx/raleigh/window.h
@@ -7,6 +7,8 @@ namespace raleigh {
#include <raleigh/runtime.h>
#include <raleigh/widget.h>
+#include <structs/dllist.h>
+#include <structs/duple.h>
#include <pland/syscall.h>
#include <raleigh/util.h>
@@ -16,7 +18,10 @@ namespace raleigh {
public:
//pass on_close to specify a close handler. if on_close returns false, the window will not be closed.
window(widget &root, _pixel_t bg_color=RGB(bf, bf, bf), bool (*on_close)(window &)=0);
+ void add_keybind(struct key_packet kp, void (*handler)(window &));
+
void notify_needs_paint(widget &from);
+ void notify_widget_size_change(widget &from, coord old_size);
enum try_actions_return_t {NONE, GOOD, DELETE};
try_actions_return_t try_actions();
void show();
@@ -31,6 +36,7 @@ namespace raleigh {
bool needs_repaint;
void paint_full();
bool (*on_close)(window &);
+ dllist<duple<struct key_packet, void (*)(window &)>> keybinds;
};
}
diff --git a/src/user/include/cxx/structs/duple.h b/src/user/include/cxx/structs/duple.h
new file mode 100644
index 0000000..874e4f6
--- /dev/null
+++ b/src/user/include/cxx/structs/duple.h
@@ -0,0 +1,13 @@
+#ifndef STRUCTS_DUPLE_H
+#define STRUCTS_DUPLE_H
+
+template<class at, class bt>
+class duple {
+public:
+ duple(at a, bt b)
+ : a(a), b(b) {}
+ at a;
+ bt b;
+};
+
+#endif \ No newline at end of file
diff --git a/src/user/include/knob/key.h b/src/user/include/knob/key.h
index d532afd..3597e2a 100644
--- a/src/user/include/knob/key.h
+++ b/src/user/include/knob/key.h
@@ -7,7 +7,8 @@ extern "C" {
#include <keypack.h>
-char key_to_char(struct key_packet kp) __attribute__ ((pure));
+char key_to_char(struct key_packet kp) __attribute__ ((const));
+bool match_side_agnostic(struct key_packet a, struct key_packet b) __attribute__ ((const));
#ifdef __cplusplus
}
diff --git a/src/user/knob/key.c b/src/user/knob/key.c
index 1506f3b..b2e3f5e 100644
--- a/src/user/knob/key.c
+++ b/src/user/knob/key.c
@@ -1,4 +1,5 @@
#include <keypack.h>
+#include <stdbool.h>
static const char no_mod[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, '\t','\n', 0, 0, 0, 0, 0,
@@ -48,7 +49,7 @@ static const char num[] = {
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '*', '+', '\n', '-', '.', '/'
};
-__attribute__ ((pure))
+__attribute__ ((const))
char key_to_char(struct key_packet kp) {
if (kp.key_id < 0x80) {
const char ch = (kp.modifiers & SHIFTS
@@ -64,4 +65,13 @@ char key_to_char(struct key_packet kp) {
else
return 0;
+}
+
+__attribute__ ((const))
+bool match_side_agnostic(struct key_packet a, struct key_packet b) {
+ return (a.key_id == b.key_id) &&
+ ((bool)(a.modifiers & SHIFTS) == (bool)(b.modifiers & SHIFTS)) &&
+ ((bool)(a.modifiers & CTRLS) == (bool)(b.modifiers & CTRLS)) &&
+ ((bool)(a.modifiers & ALTS) == (bool)(b.modifiers & ALTS)) &&
+ ((bool)(a.modifiers & WINS) == (bool)(b.modifiers & WINS));
} \ No newline at end of file
diff --git a/src/user/meminfo/meminfo.c b/src/user/meminfo/meminfo.c
deleted file mode 100644
index 3c3c45b..0000000
--- a/src/user/meminfo/meminfo.c
+++ /dev/null
@@ -1,31 +0,0 @@
-#include <popups/info.h>
-
-#include <pland/syscall.h>
-
-static const struct key_packet meminfo_quits[] = {
- { .key_id = KEY_ESCAPE, .modifiers = NO_MODS },
- { .key_id = KEY_F5, .modifiers = NO_MODS },
- { .key_id = 0 }
-};
-
-void main() {
- struct popup p;
-redo:
- info_popupf(&p,
- "kernel memory free: %uk\n"
- "userspace memory free: %uk / %uk\n"
- "Escape to quit, F5 to refresh.",
- (_pixel_t){.r = 0, .g = 0, .b = 0},
- (_pixel_t){.r = 0xbf, .g = 0xbf, .b = 0xbf},
- _kernel_dynamic_area_left() * 4,
- _total_userspace_left() * 4,
- _total_userspace_size() * 4
- );
- //hacky, i should really make info_popup take an arg
- p.quit_binds = meminfo_quits;
- make_modal(&p);
- if (p.quit_as.key_id == KEY_F5)
- //i should make popups have changable text
- //(make a new pixbuf but reuse the window)
- goto redo;
-} \ No newline at end of file
diff --git a/src/user/meminfo/meminfo.cpp b/src/user/meminfo/meminfo.cpp
new file mode 100644
index 0000000..2b035a4
--- /dev/null
+++ b/src/user/meminfo/meminfo.cpp
@@ -0,0 +1,51 @@
+#include <raleigh/w/padding.h>
+#include <raleigh/w/vbox.h>
+#include <raleigh/w/label.h>
+
+#include <raleigh/runtime.h>
+#include <raleigh/window.h>
+
+#include <pland/syscall.h>
+#include <knob/format.h>
+#include <pland/pcrt.h>
+
+using namespace raleigh;
+
+label *kmem;
+label *umem;
+
+void refresh(window &w) {
+ char *const kstr = format("kernel memory free: %uk", _kernel_dynamic_area_left() * 4);
+ char *const ustr = format("userspace memory free: %uk / %uk", _total_userspace_left() * 4, _total_userspace_size() * 4);
+
+ kmem->change_value(kstr);
+ umem->change_value(ustr);
+
+ free_block(kstr);
+ free_block(ustr);
+}
+
+void main() {
+ kmem = new label("");
+ umem = new label("");
+ label msg("press Alt+F4 to quit, or F5 to refresh");
+
+ padding pkmem(*kmem, 1);
+ padding pumem(*umem, 1);
+ padding pmsg(msg, 1);
+
+ dllist<widget &> ll;
+ ll.add_front(pmsg);
+ ll.add_front(pumem);
+ ll.add_front(pkmem);
+ vbox box(ll);
+
+ padding pbox(box, 3);
+ window w(pbox, RGB(bf, bf, bf), (bool (*)(window &))&__pcrt_quit);
+ w.add_keybind((struct key_packet){.key_id = key_packet::KEY_F5, .modifiers = key_packet::NO_MODS}, &refresh);
+
+ refresh(w);
+
+ w.show();
+ start_runtime();
+} \ No newline at end of file
diff --git a/src/user/raleigh/w/button.cpp b/src/user/raleigh/w/button.cpp
index a92167e..2abf9a9 100644
--- a/src/user/raleigh/w/button.cpp
+++ b/src/user/raleigh/w/button.cpp
@@ -8,6 +8,7 @@ namespace raleigh {
size = coord(inner.size.x + 2, inner.size.y + 2);
closest_opaque = this;
inner.notify_has_opaque_parent(this);
+ inner.parent = this;
}
void button::notify_window_change() {
@@ -49,11 +50,9 @@ namespace raleigh {
}
}
- void button::notify_has_opaque_parent(widget *parent) {}
-
- void button::handle_key(struct key_packet kp) {}
-
- void button::on_focus() {}
+ void button::notify_child_size_change(widget &child, coord old_size) {
+ set_size(coord(inner.size.x + 2, inner.size.y + 2));
+ }
- void button::on_unfocus() {}
+ void button::notify_has_opaque_parent(widget *parent) {}
} \ No newline at end of file
diff --git a/src/user/raleigh/w/label.cpp b/src/user/raleigh/w/label.cpp
index 046737f..21df2a2 100644
--- a/src/user/raleigh/w/label.cpp
+++ b/src/user/raleigh/w/label.cpp
@@ -4,12 +4,27 @@
namespace raleigh {
label::label(const char *value, const char *font, bool bg_transparent, _pixel_t fg, _pixel_t bg)
- : value(value), fi(get_font(font)), bg_transparent(bg_transparent), fg(fg), bg(bg) {
- size = coord(fi->space_width * (strlen(value) - 1) + fi->char_width, fi->char_height);
+ : fi(get_font(font)), bg_transparent(bg_transparent), fg(fg), bg(bg) {
+
+ v_size = strlen(value) + 1;
+ this->value = new char[v_size];
+ blockcpy(this->value, value, v_size);
+ size = coord(fi->space_width * (v_size - 2) + fi->char_width, fi->char_height);
+
closest_opaque = 0;
}
- void label::notify_window_change() {}
+ void label::change_value(const char *new_value) {
+ delete[] value;
+ const uint32_t ns = strlen(new_value) + 1;
+ if (ns != v_size) {
+ v_size = ns;
+ value = new char[ns];
+ set_size(coord(fi->space_width * (ns - 2) + fi->char_width, fi->char_height));
+ }
+ blockcpy(value, new_value, ns);
+ w->notify_needs_paint(*this);
+ }
void label::paint(_pixel_t *pixbuf, uint32_t pitch) {
if (!bg_transparent)
@@ -23,13 +38,7 @@ namespace raleigh {
}
}
- void label::handle_click(coord window_coords, enum mouse_packet::mouse_button click_type, bool up) { }
-
void label::notify_has_opaque_parent(widget *parent) {
closest_opaque = parent;
}
-
- void label::handle_key(struct key_packet kp) {};
- void label::on_focus() {};
- void label::on_unfocus() {};
} \ No newline at end of file
diff --git a/src/user/raleigh/w/padding.cpp b/src/user/raleigh/w/padding.cpp
index 87167c3..c1f7b85 100644
--- a/src/user/raleigh/w/padding.cpp
+++ b/src/user/raleigh/w/padding.cpp
@@ -5,6 +5,7 @@ namespace raleigh {
: inner(inner), pad_by(pad_by) {
size = coord(inner.size.x + pad_by * 2, inner.size.y + pad_by * 2);
closest_opaque = 0;
+ inner.parent = this;
}
void padding::notify_window_change() {
@@ -30,7 +31,7 @@ namespace raleigh {
inner.notify_has_opaque_parent(parent);
}
- void padding::handle_key(struct key_packet kp) {};
- void padding::on_focus() {};
- void padding::on_unfocus() {};
+ void padding::notify_child_size_change(widget &child, coord old_size) {
+ set_size(coord(inner.size.x + pad_by * 2, inner.size.y + pad_by * 2));
+ }
} \ No newline at end of file
diff --git a/src/user/raleigh/w/vbox.cpp b/src/user/raleigh/w/vbox.cpp
index 08c2539..263da2a 100644
--- a/src/user/raleigh/w/vbox.cpp
+++ b/src/user/raleigh/w/vbox.cpp
@@ -4,6 +4,7 @@ namespace raleigh {
vbox::vbox(dllist<widget &> widgets) : widgets(widgets) {
uint32_t w = 0, h = 0;
for (dllist<widget &>::node *n = widgets.first; n; n = n->next) {
+ n->d.parent = this;
h += n->d.size.y;
if (n->d.size.x > w)
w = n->d.size.x;
@@ -45,7 +46,21 @@ namespace raleigh {
n->d.notify_has_opaque_parent(parent);
}
- void vbox::handle_key(struct key_packet kp) {};
- void vbox::on_focus() {};
- void vbox::on_unfocus() {};
+ 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();
+ }
+ }
} \ No newline at end of file
diff --git a/src/user/raleigh/widget.cpp b/src/user/raleigh/widget.cpp
new file mode 100644
index 0000000..719cc06
--- /dev/null
+++ b/src/user/raleigh/widget.cpp
@@ -0,0 +1,22 @@
+#include <raleigh/widget.h>
+
+#include <knob/format.h>
+
+namespace raleigh {
+ widget::widget()
+ : parent(0) {}
+
+ void widget::notify_window_change() {}
+ void widget::handle_click(coord window_coords, enum mouse_packet::mouse_button click_type, bool up) {}
+ void widget::handle_key(struct key_packet kp) {}
+ void widget::on_focus() {}
+ void widget::on_unfocus() {}
+ void widget::notify_child_size_change(widget &child, coord old_size) {}
+
+ void widget::set_size(coord new_size) {
+ coord old_size = size;
+ size = new_size;
+ if (w)
+ w->notify_widget_size_change(*this, old_size);
+ }
+} \ No newline at end of file
diff --git a/src/user/raleigh/window.cpp b/src/user/raleigh/window.cpp
index 052422e..5d1a3de 100644
--- a/src/user/raleigh/window.cpp
+++ b/src/user/raleigh/window.cpp
@@ -1,7 +1,6 @@
#include <raleigh/runtime.h>
#include <raleigh/window.h>
-#include <popups/info.h>
-#include <knob/heap.h>
+#include <knob/key.h>
#include <knob/format.h>
@@ -44,8 +43,16 @@ namespace raleigh {
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)
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)
+ 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:
+ ;
+ }
else if (wa.action_type == wa.FOCUS_ENTER)
focussed->on_focus();
else if (wa.action_type == wa.FOCUS_LEAVE)
@@ -83,4 +90,22 @@ namespace raleigh {
focussed->on_focus();
}
}
+
+ void window::notify_widget_size_change(widget &from, coord old_size) {
+ if (from.parent)
+ from.parent->notify_child_size_change(from, old_size);
+ else {
+ size = root.size;
+ 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);
+ paint_full();
+ _resize_window(handle, size.x, size.y, pixbuf);
+ }
+ }
+
+ void window::add_keybind(struct key_packet kp, void (*handler)(window &)) {
+ keybinds.add_front(duple<struct key_packet, void (*)(window &)>(kp, handler));
+ }
} \ No newline at end of file
diff --git a/src/user/runtimes/cxx/extra.ld b/src/user/runtimes/cxx/extra.ld
index 8ce5419..048877e 100644
--- a/src/user/runtimes/cxx/extra.ld
+++ b/src/user/runtimes/cxx/extra.ld
@@ -5,4 +5,7 @@ _Znwj = get_block;
_Znaj = get_block;
/* void operator delete(void *, size_t) */
-_ZdlPvj = free_block; \ No newline at end of file
+_ZdlPvj = free_block;
+
+/* void operator delete[](void *) */
+_ZdaPv = free_block; \ No newline at end of file