From 76e39eac8cee2175ec62a191f7c91ca53857e80c Mon Sep 17 00:00:00 2001 From: Benji Dial Date: Fri, 5 Mar 2021 18:07:48 -0500 Subject: more raleigh, including button and vbox widgets --- makefile | 13 ++++---- src/user/include/cxx/raleigh/util.h | 16 ++++++---- src/user/include/cxx/raleigh/w/button.h | 26 +++++++++++++++ src/user/include/cxx/raleigh/w/label.h | 9 ++++-- src/user/include/cxx/raleigh/w/padding.h | 7 +++-- src/user/include/cxx/raleigh/w/vbox.h | 22 +++++++++++++ src/user/include/cxx/raleigh/widget.h | 9 ++++++ src/user/include/cxx/raleigh/window.h | 10 +++++- src/user/include/libfont/fonts.h | 3 ++ src/user/include/popups/info.h | 8 +++++ src/user/libfont/fonts.c | 12 +++++-- src/user/raleigh/runtime.cpp | 5 ++- src/user/raleigh/util.cpp | 24 +++++++++++--- src/user/raleigh/w/button.cpp | 54 ++++++++++++++++++++++++++++++++ src/user/raleigh/w/label.cpp | 29 ++++++++++------- src/user/raleigh/w/padding.cpp | 30 +++++++++--------- src/user/raleigh/w/vbox.cpp | 45 ++++++++++++++++++++++++++ src/user/raleigh/window.cpp | 51 ++++++++++++++++++++++++------ src/user/rhello/main.cpp | 34 ++++++++++++++++++-- 19 files changed, 343 insertions(+), 64 deletions(-) create mode 100644 src/user/include/cxx/raleigh/w/button.h create mode 100644 src/user/include/cxx/raleigh/w/vbox.h create mode 100644 src/user/raleigh/w/button.cpp create mode 100644 src/user/raleigh/w/vbox.cpp diff --git a/makefile b/makefile index 83c1013..d03c43d 100644 --- a/makefile +++ b/makefile @@ -1,6 +1,6 @@ kgccargs = -Wall -Wsuggest-attribute=pure -Wsuggest-attribute=const -m32 -mno-sse -Og -ggdb -ffreestanding -fno-asynchronous-unwind-tables -fno-pic -Isrc/shared/include -Isrc/lib ugccargs = ${kgccargs} -Isrc/user/include -ugppargs = ${ugccargs} -fno-rtti -Isrc/user/include/cxx +ugppargs = ${ugccargs} -fno-rtti -fno-exceptions -Isrc/user/include/cxx nasmargs = -f elf32 partlink = -r -m elf_i386 clink = -T src/user/runtimes/c/elf.ld @@ -102,9 +102,10 @@ obj/libfont.so: obj/libfont/bdf.o obj/libfont/pbf.o obj/libfont/fonts.o \ obj/popups.so: obj/popups/info.o obj/popups/popup.o ld ${partlink} $^ -o $@ -obj/raleigh.so: obj/raleigh/runtime.po obj/raleigh/window.po \ - obj/raleigh/w/label.po obj/raleigh/util.po \ - obj/raleigh/w/padding.po +obj/raleigh.so: obj/raleigh/runtime.po obj/raleigh/window.po \ + obj/raleigh/w/label.po obj/raleigh/util.po \ + obj/raleigh/w/padding.po obj/raleigh/w/button.po \ + obj/raleigh/w/vbox.po ld ${partlink} $^ -o $@ obj/init.elf: obj/init/init.o obj/knob.so obj/c.rto @@ -150,6 +151,6 @@ obj/mdemo.elf: obj/mdemo/main.o obj/popups.so obj/libfont.so \ obj/knob.so obj/c.rto ld ${clink} $^ -o $@ -obj/rhello.elf: obj/rhello/main.po obj/raleigh.so obj/libfont.so \ - obj/knob.so obj/cxx.rto +obj/rhello.elf: obj/rhello/main.po obj/raleigh.so obj/popups.so \ + obj/libfont.so obj/knob.so obj/cxx.rto ld ${cxxlink} $^ -o $@ \ No newline at end of file diff --git a/src/user/include/cxx/raleigh/util.h b/src/user/include/cxx/raleigh/util.h index d2ed13d..9142b69 100644 --- a/src/user/include/cxx/raleigh/util.h +++ b/src/user/include/cxx/raleigh/util.h @@ -5,11 +5,15 @@ #define RGB(R, G, B) ((_pixel_t){.r = 0x##R, .g = 0x##G, .b = 0x##B}) -struct coord { - uint32_t x; - uint32_t y; - coord(uint32_t x, uint32_t y); - coord(); -}; +namespace raleigh { + struct coord { + uint32_t x; + uint32_t y; + coord(uint32_t x, uint32_t y); + coord(); + }; + + void show_error_and_quitf(const char *fmt, ...) __attribute__ ((noreturn)); +} #endif \ No newline at end of file diff --git a/src/user/include/cxx/raleigh/w/button.h b/src/user/include/cxx/raleigh/w/button.h new file mode 100644 index 0000000..1847cf1 --- /dev/null +++ b/src/user/include/cxx/raleigh/w/button.h @@ -0,0 +1,26 @@ +#ifndef RALEIGH_W_BUTTON_H +#define RALEIGH_W_BUTTON_H + +#include + +namespace raleigh { + class button : public widget { + public: + button(widget &inner, void (*on_click)(button &), _pixel_t border_color=RGB(00, 00, 00), + _pixel_t bg_color=RGB(bf, bf, bf), _pixel_t pressed_color=RGB(9f, 9f, 9f)); + + void notify_window_change() override; + void paint(_pixel_t *pixbuf, uint32_t pitch) override; + bool try_handle_click(coord window_coords, enum mouse_packet::mouse_button click_type, bool up) override; + void notify_has_opaque_parent(widget *parent) override; + private: + widget &inner; + void (*on_click)(button &); + _pixel_t border_color; + _pixel_t bg_color; + _pixel_t pressed_color; + bool is_pressed; + }; +} + +#endif \ No newline at end of file diff --git a/src/user/include/cxx/raleigh/w/label.h b/src/user/include/cxx/raleigh/w/label.h index 51bf541..d133841 100644 --- a/src/user/include/cxx/raleigh/w/label.h +++ b/src/user/include/cxx/raleigh/w/label.h @@ -8,16 +8,19 @@ namespace raleigh { class label : public widget { public: //this pointer is used directly, and the contents of the string should not be changed afterward - label(const char *value, const char *font="fixed-10", - _pixel_t bg=RGB(bf, bf, bf), _pixel_t fg=RGB(00, 00, 00)); + 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 paint(_pixel_t *pixbuf, uint32_t pitch) override; + bool try_handle_click(coord window_coords, enum mouse_packet::mouse_button click_type, bool up) override __attribute__ ((const)); + void notify_has_opaque_parent(widget *parent) override; private: const char *const value; const struct font_info *const fi; - const _pixel_t bg; + bool bg_transparent; const _pixel_t fg; + const _pixel_t bg; }; } diff --git a/src/user/include/cxx/raleigh/w/padding.h b/src/user/include/cxx/raleigh/w/padding.h index 108cd28..216b984 100644 --- a/src/user/include/cxx/raleigh/w/padding.h +++ b/src/user/include/cxx/raleigh/w/padding.h @@ -6,14 +6,15 @@ namespace raleigh { class padding : public widget { public: - padding(uint32_t pad_by, _pixel_t color, widget &inner); + padding(widget &inner, uint32_t pad_by); void notify_window_change() override; void paint(_pixel_t *pixbuf, uint32_t pitch) override; + bool try_handle_click(coord window_coords, enum mouse_packet::mouse_button click_type, bool up) override; + void notify_has_opaque_parent(widget *parent) override; private: - uint32_t pad_by; - _pixel_t color; 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 new file mode 100644 index 0000000..aead128 --- /dev/null +++ b/src/user/include/cxx/raleigh/w/vbox.h @@ -0,0 +1,22 @@ +#ifndef RALEIGH_W_VBOX_H +#define RALEIGH_W_VBOX_H + +#include +#include + +namespace raleigh { + class vbox : public widget { + public: + //do not modify this list afterward + vbox(dllist widgets); + + void notify_window_change() override; + void paint(_pixel_t *pixbuf, uint32_t pitch) override; + bool try_handle_click(coord window_coords, enum mouse_packet::mouse_button click_type, bool up) override; + void notify_has_opaque_parent(widget *parent) override; + private: + dllist widgets; + }; +} + +#endif \ No newline at end of file diff --git a/src/user/include/cxx/raleigh/widget.h b/src/user/include/cxx/raleigh/widget.h index 1839333..de6c5a4 100644 --- a/src/user/include/cxx/raleigh/widget.h +++ b/src/user/include/cxx/raleigh/widget.h @@ -18,9 +18,18 @@ namespace raleigh { window *w; coord window_offset; + //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. + //in notify_has_opaque_parent's handler, it should set this if it isn't already set, + // 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; virtual void paint(_pixel_t *pixbuf, uint32_t pitch) = 0; + virtual bool try_handle_click(coord window_coords, enum mouse_packet::mouse_button click_type, bool up) = 0; + virtual void notify_has_opaque_parent(widget *parent) = 0; }; } diff --git a/src/user/include/cxx/raleigh/window.h b/src/user/include/cxx/raleigh/window.h index 7e45e22..f82f9a9 100644 --- a/src/user/include/cxx/raleigh/window.h +++ b/src/user/include/cxx/raleigh/window.h @@ -5,22 +5,30 @@ namespace raleigh { class window; } +#include #include #include #include namespace raleigh { class window { + friend void start_runtime(); public: - window(widget &root); + //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 notify_needs_paint(widget &from); enum try_actions_return_t {NONE, GOOD, DELETE}; try_actions_return_t try_actions(); + void show(); private: _window_handle_t handle; _pixel_t *pixbuf; coord size; widget &root; + _pixel_t bg_color; + bool needs_repaint; + void paint_full(); + bool (*on_close)(window &); }; } diff --git a/src/user/include/libfont/fonts.h b/src/user/include/libfont/fonts.h index 629ed5a..8c0e949 100644 --- a/src/user/include/libfont/fonts.h +++ b/src/user/include/libfont/fonts.h @@ -25,6 +25,9 @@ struct font_info *get_font(const char *name); //pitch is in pixels void put_char(const struct font_info *font, char ch, _pixel_t *pb_ptr, uint32_t pb_pitch, _pixel_t bg, _pixel_t fg); +//pitch is in pixels +void put_char_no_bg(const struct font_info *font, char ch, _pixel_t *pb_ptr, uint32_t pb_pitch, _pixel_t fg); + #ifdef __cplusplus } #endif diff --git a/src/user/include/popups/info.h b/src/user/include/popups/info.h index 36d557a..de6be57 100644 --- a/src/user/include/popups/info.h +++ b/src/user/include/popups/info.h @@ -1,6 +1,10 @@ #ifndef POPUPS_INFO_H #define POPUPS_INFO_H +#ifdef __cplusplus +extern "C" { +#endif + #include #include @@ -11,4 +15,8 @@ void info_popup(struct popup *into, const char *text, _pixel_t fg, _pixel_t bg); void info_popupf(struct popup *into, const char *text, _pixel_t fg, _pixel_t bg, ...); void info_popupf_v(struct popup *into, const char *text, _pixel_t fg, _pixel_t bg, va_list args); +#ifdef __cplusplus +} +#endif + #endif \ No newline at end of file diff --git a/src/user/libfont/fonts.c b/src/user/libfont/fonts.c index 51e127b..d63a5d9 100644 --- a/src/user/libfont/fonts.c +++ b/src/user/libfont/fonts.c @@ -58,11 +58,17 @@ struct font_info *get_font(const char *name) { //pitch is in pixels void put_char(const struct font_info *font, char ch, _pixel_t *pb_ptr, uint32_t pb_pitch, _pixel_t bg, _pixel_t fg) { -//char *const msg = format("put_char(font = 0x%x, ch = '%c', pb_ptr = 0x%x, pb_pitch = %u, bg = 0x%2x, fg = 0x%2x);", font, ch, pb_ptr, pb_pitch, bg, fg); -//_system_log(msg); -//free_block(msg); const bool *const bitmap = font->bitmaps[(uint8_t)ch] ? font->bitmaps[(uint8_t)ch] : font->bitmaps[0]; for (uint32_t y = 0; y < font->char_height; ++y) for (uint32_t x = 0; x < font->char_width; ++x) pb_ptr[y * pb_pitch + x] = bitmap[y * font->char_width + x] ? fg : bg; +} + +//pitch is in pixels +void put_char_no_bg(const struct font_info *font, char ch, _pixel_t *pb_ptr, uint32_t pb_pitch, _pixel_t fg) { + const bool *const bitmap = font->bitmaps[(uint8_t)ch] ? font->bitmaps[(uint8_t)ch] : font->bitmaps[0]; + for (uint32_t y = 0; y < font->char_height; ++y) + for (uint32_t x = 0; x < font->char_width; ++x) + if (bitmap[y * font->char_width + x]) + pb_ptr[y * pb_pitch + x] = fg; } \ No newline at end of file diff --git a/src/user/raleigh/runtime.cpp b/src/user/raleigh/runtime.cpp index 1152575..6dafed1 100644 --- a/src/user/raleigh/runtime.cpp +++ b/src/user/raleigh/runtime.cpp @@ -11,9 +11,12 @@ namespace raleigh { if (!open_windows.first) __pcrt_quit(); for (dllist::node *w = open_windows.first; w; w = w->next) - if (w->d.try_actions() == window::DELETE) + 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 958897b..db0982b 100644 --- a/src/user/raleigh/util.cpp +++ b/src/user/raleigh/util.cpp @@ -1,6 +1,22 @@ #include +#include +#include -coord::coord(uint32_t x, uint32_t y) - : x(x), y(y) {} -coord::coord() - : x(0), y(0) {} \ No newline at end of file +namespace raleigh { + coord::coord(uint32_t x, uint32_t y) + : x(x), y(y) {} + coord::coord() + : x(0), y(0) {} + + __attribute__ ((noreturn)) + void show_error_and_quitf(const char *fmt, ...) { + 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); + + __pcrt_quit(); + } +} \ No newline at end of file diff --git a/src/user/raleigh/w/button.cpp b/src/user/raleigh/w/button.cpp new file mode 100644 index 0000000..06d9c1d --- /dev/null +++ b/src/user/raleigh/w/button.cpp @@ -0,0 +1,54 @@ +#include + +namespace raleigh { + button::button(widget &inner, void (*on_click)(button &), + _pixel_t border_color, _pixel_t bg_color, _pixel_t pressed_color) + : inner(inner), on_click(on_click), 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; + inner.notify_has_opaque_parent(this); + } + + void button::notify_window_change() { + inner.window_offset = coord(window_offset.x + 1, window_offset.y + 1); + inner.w = w; + inner.notify_window_change(); + } + + void button::paint(_pixel_t *pixbuf, uint32_t pitch) { + 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.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; + } + } + + bool button::try_handle_click(coord window_coords, enum mouse_packet::mouse_button click_type, bool up) { + if (click_type != mouse_packet::LEFT) + return false; + if (up) { + is_pressed = false; + inner.window_offset = coord(window_offset.x + 1, window_offset.y + 1); + inner.notify_window_change(); + w->notify_needs_paint(*this); + on_click(*this); + } + else { + is_pressed = true; + inner.window_offset = coord(window_offset.x + 2, window_offset.y + 2); + inner.notify_window_change(); + w->notify_needs_paint(*this); + } + return true; + } + + 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 047126d..5b74175 100644 --- a/src/user/raleigh/w/label.cpp +++ b/src/user/raleigh/w/label.cpp @@ -3,25 +3,32 @@ #include namespace raleigh { - label::label(const char *value, const char *font, _pixel_t bg, _pixel_t fg) - : value(value), fi(get_font(font)), bg(bg), fg(fg) { - size = coord( - fi->space_width * (strlen(value) - 1) + fi->char_width, - fi->char_height - ); + 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); + closest_opaque = 0; } void label::notify_window_change() {} void label::paint(_pixel_t *pixbuf, uint32_t pitch) { - for (uint32_t y = window_offset.y; y < window_offset.y + size.y; ++y) - for (uint32_t x = window_offset.x; x < window_offset.x + size.x; ++x) - pixbuf[y * pitch + x] = bg; - + if (!bg_transparent) + for (uint32_t y = window_offset.y; y < window_offset.y + size.y; ++y) + for (uint32_t x = window_offset.x; x < window_offset.x + size.x; ++x) + pixbuf[y * pitch + x] = bg; _pixel_t *ptr = pixbuf + window_offset.y * pitch + window_offset.x; for (const char *c = value; *c; ++c) { - put_char(fi, *c, ptr, pitch, bg, fg); + put_char_no_bg(fi, *c, ptr, pitch, fg); ptr += fi->space_width; } } + + __attribute__ ((const)) + bool label::try_handle_click(coord window_coords, enum mouse_packet::mouse_button click_type, bool up) { + return false; + } + + void label::notify_has_opaque_parent(widget *parent) { + closest_opaque = parent; + } } \ No newline at end of file diff --git a/src/user/raleigh/w/padding.cpp b/src/user/raleigh/w/padding.cpp index 6833c5d..3dd027b 100644 --- a/src/user/raleigh/w/padding.cpp +++ b/src/user/raleigh/w/padding.cpp @@ -1,9 +1,10 @@ #include namespace raleigh { - padding::padding(uint32_t pad_by, _pixel_t color, widget &inner) - : pad_by(pad_by), color(color), inner(inner) { + padding::padding(widget &inner, uint32_t pad_by) + : inner(inner), pad_by(pad_by) { size = coord(inner.size.x + pad_by * 2, inner.size.y + pad_by * 2); + closest_opaque = 0; } void padding::notify_window_change() { @@ -13,19 +14,18 @@ namespace raleigh { } void padding::paint(_pixel_t *pixbuf, uint32_t pitch) { - for (uint32_t y = window_offset.y; y < window_offset.y + pad_by; ++y) - for (uint32_t x = window_offset.x; x < window_offset.x + size.x; ++x) - pixbuf[y * pitch + x] = color; - for (uint32_t y = window_offset.y + size.y - pad_by; y < window_offset.y + size.y; ++y) - for (uint32_t x = window_offset.x; x < window_offset.x + size.x; ++x) - pixbuf[y * pitch + x] = color; - for (uint32_t y = window_offset.y + pad_by; y < window_offset.y + size.y - pad_by; ++y) { - for (uint32_t x = window_offset.x; x < window_offset.x + pad_by; ++x) - pixbuf[y * pitch + x] = color; - for (uint32_t x = window_offset.x + size.x - pad_by; x < window_offset.x + size.x; ++x) - pixbuf[y * pitch + x] = color; - } - inner.paint(pixbuf, pitch); } + + bool padding::try_handle_click(coord window_coords, enum mouse_packet::mouse_button click_type, bool up) { + return (window_coords.x >= inner.window_offset.x) && + (window_coords.y >= inner.window_offset.y) && + (window_coords.x < inner.window_offset.x + inner.size.x) && + (window_coords.y < inner.window_offset.y + inner.size.y) && + inner.try_handle_click(window_coords, click_type, up); + } + + void padding::notify_has_opaque_parent(widget *parent) { + closest_opaque = parent; + } } \ No newline at end of file diff --git a/src/user/raleigh/w/vbox.cpp b/src/user/raleigh/w/vbox.cpp new file mode 100644 index 0000000..30b0902 --- /dev/null +++ b/src/user/raleigh/w/vbox.cpp @@ -0,0 +1,45 @@ +#include + +namespace raleigh { + vbox::vbox(dllist widgets) : widgets(widgets) { + uint32_t w = 0, h = 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; + } + size = coord(w, h); + closest_opaque = 0; + } + + void vbox::notify_window_change() { + uint32_t h = window_offset.y; + for (dllist::node *n = widgets.first; n; n = n->next) { + n->d.w = w; + n->d.window_offset = coord(window_offset.x + size.x / 2 - n->d.size.x / 2, h); + n->d.notify_window_change(); + 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); + } + + bool vbox::try_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; + } + return (window_coords.x >= n->d.window_offset.x) && + (window_coords.x < n->d.window_offset.x + n->d.size.x) && + n->d.try_handle_click(window_coords, click_type, up); + } + + void vbox::notify_has_opaque_parent(widget *parent) { + closest_opaque = parent; + } +} \ No newline at end of file diff --git a/src/user/raleigh/window.cpp b/src/user/raleigh/window.cpp index 4373b06..41eb9ce 100644 --- a/src/user/raleigh/window.cpp +++ b/src/user/raleigh/window.cpp @@ -1,20 +1,21 @@ #include #include +#include #include namespace raleigh { - window::window(widget &root) - : size(root.size), root(root) { + window::window(widget &root, _pixel_t bg_color, bool (*on_close)(window &)) + : handle(0), size(root.size), root(root), bg_color(bg_color), + needs_repaint(false), on_close(on_close) { root.w = this; root.window_offset = coord(0, 0); root.notify_window_change(); pixbuf = (_pixel_t *)get_block(size.x * size.y * sizeof(_pixel_t)); + 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); - root.paint(pixbuf, size.x); - handle = _new_window(size.x, size.y, pixbuf); - - open_windows.add_front(*this); + paint_full(); } window::try_actions_return_t window::try_actions() { @@ -22,14 +23,46 @@ namespace raleigh { window::try_actions_return_t got = NONE; while (1) { _get_win_action(handle, &wa); - if (!wa.action_type) + if (!wa.action_type) { + if (needs_repaint) { + needs_repaint = false; + _paint_window(handle); + } return got; + } 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)) - return DELETE; + if (!on_close || on_close(*this)) + return DELETE; got = GOOD; - //TODO + if (wa.action_type == wa.MOUSE_DOWN) + root.try_handle_click(coord(wa.as_mouse.x, wa.as_mouse.y), wa.as_mouse.which, false); + if (wa.action_type == wa.MOUSE_UP) + root.try_handle_click(coord(wa.as_mouse.x, wa.as_mouse.y), wa.as_mouse.which, true); } } + + void window::notify_needs_paint(widget &head) { + if (head.closest_opaque) + head.closest_opaque->paint(pixbuf, size.x); + else + paint_full(); + needs_repaint = true; + } + + void window::paint_full() { + for (uint32_t i = 0; i < size.x * size.y; ++i) + pixbuf[i] = bg_color; + root.paint(pixbuf, size.x); + } + + void window::show() { + if (handle) + return; + handle = _new_window(size.x, size.y, pixbuf); + if (!handle) + show_error_and_quitf("Failed to get window handle for requested window."); + open_windows.add_front(*this); + } } \ No newline at end of file diff --git a/src/user/rhello/main.cpp b/src/user/rhello/main.cpp index 750818c..c92b430 100644 --- a/src/user/rhello/main.cpp +++ b/src/user/rhello/main.cpp @@ -1,13 +1,43 @@ #include +#include #include +#include + #include #include +#include +#include + using namespace raleigh; +window *p_w; + +void onclick(button &from) { + p_w->show(); +} + void main() { label l("Hello, world! Close me with Alt+F4."); - padding p(4, RGB(bf, bf, bf), l); - window w(p); + padding pl(l, 2); + + label bl("Click me!"); + padding pbl(bl, 4); + button b(pbl, &onclick); + padding pb(b, 2); + + dllist wl; + wl.add_front(pb); + wl.add_front(pl); + vbox vb(wl); + padding pvb(vb, 2); + + window w(pvb, RGB(bf, bf, bf), (bool (*)(window &))&__pcrt_quit); + + label p_l("You clicked that button!"); + padding p_pl(p_l, 4); + p_w = new window(p_pl); + + w.show(); start_runtime(); } \ No newline at end of file -- cgit v1.2.3