From 1a5ece4f52ef17c7c868e95eb26e98137d5cab6f Mon Sep 17 00:00:00 2001 From: Benji Dial Date: Sun, 7 Mar 2021 23:19:48 -0500 Subject: keyboard support in raleigh, word wrap and more in entry widget --- src/kernel/window.c | 32 +++-- src/user/include/cxx/raleigh/w/button.h | 5 +- src/user/include/cxx/raleigh/w/entry.h | 25 +++- src/user/include/cxx/raleigh/w/label.h | 5 +- src/user/include/cxx/raleigh/w/padding.h | 5 +- src/user/include/cxx/raleigh/w/vbox.h | 5 +- src/user/include/cxx/raleigh/widget.h | 5 +- src/user/include/cxx/raleigh/window.h | 2 + src/user/include/knob/block.h | 3 + src/user/include/knob/key.h | 8 ++ src/user/knob/block.c | 10 ++ src/user/raleigh/w/button.cpp | 11 +- src/user/raleigh/w/entry.cpp | 215 ++++++++++++++++++++++++------- src/user/raleigh/w/label.cpp | 9 +- src/user/raleigh/w/padding.cpp | 16 ++- src/user/raleigh/w/vbox.cpp | 12 +- src/user/raleigh/window.cpp | 26 +++- src/user/rhello/main.cpp | 2 +- 18 files changed, 306 insertions(+), 90 deletions(-) (limited to 'src') diff --git a/src/kernel/window.c b/src/kernel/window.c index 9487211..b1d5f92 100644 --- a/src/kernel/window.c +++ b/src/kernel/window.c @@ -272,6 +272,17 @@ static void paint_all() { paint_and_above(bottom_window); } +static void send_action(struct window *w, struct window_action packet) { + struct window_action *next_next = w->next_action_write + 1; + if (next_next >= AB_END(w->action_buffer)) + next_next = w->action_buffer; + if (next_next != w->next_action_read) { + *(w->next_action_write) = packet; + w->next_action_write = next_next; + unwait(w->from_task, (struct wait){.mode = WINDOW_ACTION}); + } +} + struct window *new_window(uint16_t width, uint16_t height, const struct pixel *pixel_buffer) { if (!pixel_buffer) { logf(LOG_WARN, "Refusing to create window with null pixel buffer for task %s.", active_task->name); @@ -298,14 +309,18 @@ got_window: w->next_action_read = ab; w->next_action_write = ab; - if (top_window) + if (top_window) { + send_action(top_window, (struct window_action){.action_type = FOCUS_LEAVE}); top_window->above = w; + } else bottom_window = w; w->above = 0; w->below = top_window; top_window = w; + send_action(top_window, (struct window_action){.action_type = FOCUS_ENTER}); + w->from_task = active_task; paint_and_above(w); @@ -313,8 +328,10 @@ got_window: } static void del_no_paint(struct window *w) { - if (w == top_window) + if (w == top_window) { top_window = w->below; + send_action(top_window, (struct window_action){.action_type = FOCUS_ENTER}); + } if (w == bottom_window) bottom_window = w->above; if (w->below) @@ -384,17 +401,6 @@ struct window_action next_window_action(struct window *w) { return *action; } -static void send_action(struct window *w, struct window_action packet) { - struct window_action *next_next = w->next_action_write + 1; - if (next_next >= AB_END(w->action_buffer)) - next_next = w->action_buffer; - if (next_next != w->next_action_read) { - *(w->next_action_write) = packet; - w->next_action_write = next_next; - unwait(w->from_task, (struct wait){.mode = WINDOW_ACTION}); - } -} - #define RUN_COMMAND_FILE "sys/winspace.rc" enum wm_action { diff --git a/src/user/include/cxx/raleigh/w/button.h b/src/user/include/cxx/raleigh/w/button.h index 1847cf1..03e17ab 100644 --- a/src/user/include/cxx/raleigh/w/button.h +++ b/src/user/include/cxx/raleigh/w/button.h @@ -11,8 +11,11 @@ namespace raleigh { 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 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: widget &inner; void (*on_click)(button &); diff --git a/src/user/include/cxx/raleigh/w/entry.h b/src/user/include/cxx/raleigh/w/entry.h index 7ea2973..fcae122 100644 --- a/src/user/include/cxx/raleigh/w/entry.h +++ b/src/user/include/cxx/raleigh/w/entry.h @@ -12,10 +12,13 @@ namespace raleigh { const char *font="fixed-10", _pixel_t bg=RGB(ff, ff, ff), _pixel_t fg=RGB(00, 00, 00), _pixel_t border_color=RGB(00, 00, 00)); - void notify_window_change(); - void paint(_pixel_t *pixbuf, uint32_t pitch); - bool try_handle_click(coord window_coords, enum mouse_packet::mouse_button click_type, bool up); - void notify_has_opaque_parent(widget *parent); + 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 handle_key(struct key_packet kp) override; + void on_focus() override; + void on_unfocus() override; private: uint32_t rows; uint32_t cols; @@ -40,12 +43,26 @@ namespace raleigh { uint32_t end_d; bool first_paint; + bool has_focus; + bool had_focus_last_paint; bool text_changed_since_last_paint; uint32_t cur_y_last_paint; uint32_t cur_x_last_paint; uint32_t cur_d_last_paint; + //uses cur_x, not cur_d; sets both + //will not modify cur_y + void ensure_cursor_in_line(); + void paint_text(_pixel_t *pixbuf, uint32_t pitch); + //sets line_indices[from_y + 1 .. end_y + 1], end_y, end_x and end_d + void get_indices(uint32_t from_y, uint32_t from_x, uint32_t from_d); + + //these four return true on success, and do not send a paint request to the window + bool cursor_left(); + bool cursor_right(); + bool cursor_up(); + bool cursor_down(); }; } diff --git a/src/user/include/cxx/raleigh/w/label.h b/src/user/include/cxx/raleigh/w/label.h index d133841..4b1dae2 100644 --- a/src/user/include/cxx/raleigh/w/label.h +++ b/src/user/include/cxx/raleigh/w/label.h @@ -13,8 +13,11 @@ namespace raleigh { 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 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; const struct font_info *const fi; diff --git a/src/user/include/cxx/raleigh/w/padding.h b/src/user/include/cxx/raleigh/w/padding.h index 216b984..792e204 100644 --- a/src/user/include/cxx/raleigh/w/padding.h +++ b/src/user/include/cxx/raleigh/w/padding.h @@ -10,8 +10,11 @@ namespace raleigh { 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 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: 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 aead128..02bffd3 100644 --- a/src/user/include/cxx/raleigh/w/vbox.h +++ b/src/user/include/cxx/raleigh/w/vbox.h @@ -12,8 +12,11 @@ namespace raleigh { 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 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: dllist widgets; }; diff --git a/src/user/include/cxx/raleigh/widget.h b/src/user/include/cxx/raleigh/widget.h index de6c5a4..54b9287 100644 --- a/src/user/include/cxx/raleigh/widget.h +++ b/src/user/include/cxx/raleigh/widget.h @@ -28,8 +28,11 @@ namespace raleigh { //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 handle_click(coord window_coords, enum mouse_packet::mouse_button click_type, bool up) = 0; 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; }; } diff --git a/src/user/include/cxx/raleigh/window.h b/src/user/include/cxx/raleigh/window.h index f82f9a9..21ae511 100644 --- a/src/user/include/cxx/raleigh/window.h +++ b/src/user/include/cxx/raleigh/window.h @@ -20,11 +20,13 @@ namespace raleigh { enum try_actions_return_t {NONE, GOOD, DELETE}; try_actions_return_t try_actions(); void show(); + void focus(widget &w); private: _window_handle_t handle; _pixel_t *pixbuf; coord size; widget &root; + widget *focussed; _pixel_t bg_color; bool needs_repaint; void paint_full(); diff --git a/src/user/include/knob/block.h b/src/user/include/knob/block.h index 565c334..27cb83b 100644 --- a/src/user/include/knob/block.h +++ b/src/user/include/knob/block.h @@ -28,6 +28,9 @@ bool strequ(const char *a, const char *b) __attribute__ ((pure)); //this replacement happens in place, with no memory allocation void str_trunc_fill(char *str, uint32_t len); +//returns first index of any character of delims or the null terminator in str +uint32_t str_find_any(const char *str, const char *delims) __attribute__ ((pure)); + #ifdef __cplusplus } #endif diff --git a/src/user/include/knob/key.h b/src/user/include/knob/key.h index 90509fc..d532afd 100644 --- a/src/user/include/knob/key.h +++ b/src/user/include/knob/key.h @@ -1,8 +1,16 @@ #ifndef KNOB_KEY_H #define KNOB_KEY_H +#ifdef __cplusplus +extern "C" { +#endif + #include char key_to_char(struct key_packet kp) __attribute__ ((pure)); +#ifdef __cplusplus +} +#endif + #endif \ No newline at end of file diff --git a/src/user/knob/block.c b/src/user/knob/block.c index 1720f94..5b4590f 100644 --- a/src/user/knob/block.c +++ b/src/user/knob/block.c @@ -73,4 +73,14 @@ void str_trunc_fill(char *str, uint32_t len) { str[j] = ' '; str[len] = '\0'; } +} + +__attribute__ ((pure)) +uint32_t str_find_any(const char *str, const char *delims) { + const char *i; + for (i = str; *i; ++i) + for (const char *j = delims; *j; ++j) + if (*i == *j) + return i - str; + return i - str; } \ No newline at end of file diff --git a/src/user/raleigh/w/button.cpp b/src/user/raleigh/w/button.cpp index 06d9c1d..a92167e 100644 --- a/src/user/raleigh/w/button.cpp +++ b/src/user/raleigh/w/button.cpp @@ -31,9 +31,9 @@ namespace raleigh { } } - bool button::try_handle_click(coord window_coords, enum mouse_packet::mouse_button click_type, bool up) { + void button::handle_click(coord window_coords, enum mouse_packet::mouse_button click_type, bool up) { if (click_type != mouse_packet::LEFT) - return false; + return; if (up) { is_pressed = false; inner.window_offset = coord(window_offset.x + 1, window_offset.y + 1); @@ -47,8 +47,13 @@ namespace raleigh { inner.notify_window_change(); w->notify_needs_paint(*this); } - return true; } void button::notify_has_opaque_parent(widget *parent) {} + + void button::handle_key(struct key_packet kp) {} + + void button::on_focus() {} + + void button::on_unfocus() {} } \ No newline at end of file diff --git a/src/user/raleigh/w/entry.cpp b/src/user/raleigh/w/entry.cpp index de8bd82..1c6f91e 100644 --- a/src/user/raleigh/w/entry.cpp +++ b/src/user/raleigh/w/entry.cpp @@ -2,55 +2,76 @@ #include #include #include +#include namespace raleigh { entry::entry(uint32_t rows, uint32_t cols, const char *default_text, 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) { - size = coord(fi->space_width * (cols - 1) + fi->char_width + 6, fi->space_height * (rows - 1) + fi->char_height + 6); + line_indices(new uint32_t[rows + 1]), first_paint(true), + 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; - end_x = 0; - end_y = 0; + const uint32_t l = strlen(default_text); + const uint32_t cl = l > rows * cols - 1 ? rows * cols - 1 : l; + blockcpy(data, default_text, cl); + data[cl] = '\0'; + line_indices[0] = 0; - for (end_d = 0; default_text[end_d]; ++end_d) { - if (end_d == rows * cols - 1) - break; - data[end_d] = default_text[end_d]; - if ((default_text[end_d] == '\n') || (++end_x == cols)) { - if (end_y == rows - 1) - break; - line_indices[++end_y] = end_d + 1; - end_x = 0; - } - } - line_indices[end_y + 1] = end_d; + get_indices(0, 0, 0); cur_x = end_x; cur_y = end_y; cur_d = end_d; - data[end_d] = '\0'; } - void entry::notify_window_change() {} - - void entry::paint_text(_pixel_t *pixbuf, uint32_t pitch) { - uint32_t y = 0; - uint32_t x = -1; - for (const char *i = data; *i; ++i) { - if (*i == '\n') { - ++y; - x = -1; + void entry::get_indices(uint32_t from_y, uint32_t from_x, uint32_t from_d) { + while (1) { + const uint32_t ln = str_find_any(data + from_d, " \n"); + bool quit_after = !data[from_d + ln]; + if ((from_x + ln <= cols) || (ln >= cols)) { + from_x += ln; + from_d += ln; + if (data[from_d] == '\n') { + ++from_y; + from_x = 0; + line_indices[from_y] = from_d + 1; + } + else + ++from_x; + ++from_d; + if (from_x >= cols) { + ++from_y; + from_x = 0; + line_indices[from_y] = from_d; + } + if (quit_after) + break; } else { - if (++x == cols) { - ++y; - x = 0; - } - put_char_no_bg(fi, *i, pixbuf + (window_offset.y + 3 + y * fi->space_height) * pitch + (window_offset.x + 3 + x * fi->space_width), pitch, fg); + ++from_y; + from_x = 0; + line_indices[from_y] = from_d; } } + line_indices[from_y + 1] = from_d; + end_y = from_y; + end_x = from_x; + end_d = from_d; + } + + void entry::notify_window_change() {} + + void entry::paint_text(_pixel_t *pixbuf, uint32_t pitch) { + for (uint32_t y = 0; y <= end_y; ++y) { + const char *const line = data + line_indices[y]; + const uint32_t len = line_indices[y + 1] - line_indices[y] >= cols ? cols : line_indices[y + 1] - line_indices[y]; + for (uint32_t x = 0; x < len; ++x) + if ((line[x] != '\n') && line[x]) + put_char_no_bg(fi, line[x], pixbuf + (window_offset.y + 3 + y * fi->space_height) * pitch + (window_offset.x + 3 + x * fi->space_width), pitch, fg); + } } void entry::paint(_pixel_t *pixbuf, uint32_t pitch) { @@ -83,28 +104,40 @@ namespace raleigh { text_changed_since_last_paint = false; } - else { + else if (had_focus_last_paint) { for (uint32_t y = 0; y < fi->char_height; ++y) { old_cur_ptr[y * pitch] = bg; old_cur_ptr[y * pitch + 1] = bg; } - if (data[cur_d_last_paint] && (data[cur_d_last_paint] != '\n')) + if (data[cur_d_last_paint] && (data[cur_d_last_paint] != '\n') && (cur_d_last_paint < line_indices[cur_y_last_paint + 1])) put_char_no_bg(fi, data[cur_d_last_paint], old_cur_ptr, pitch, fg); } - for (uint32_t y = 0; y < fi->char_height; ++y) { - cur_ptr[y * pitch] = fg; - cur_ptr[y * pitch + 1] = fg; - } + if (has_focus) + for (uint32_t y = 0; y < fi->char_height; ++y) { + cur_ptr[y * pitch] = fg; + cur_ptr[y * pitch + 1] = fg; + } cur_y_last_paint = cur_y; cur_x_last_paint = cur_x; cur_d_last_paint = cur_d; + had_focus_last_paint = has_focus; + } + + void entry::ensure_cursor_in_line() { + cur_d = line_indices[cur_y] + cur_x; + if (cur_d >= line_indices[cur_y + 1]) { + cur_d = line_indices[cur_y + 1] - 1; + if (data[cur_d] && (data[cur_d] != '\n')) + ++cur_d; + cur_x = cur_d - line_indices[cur_y]; + } } - bool entry::try_handle_click(coord window_coords, enum mouse_packet::mouse_button click_type, bool up) { + void entry::handle_click(coord window_coords, enum mouse_packet::mouse_button click_type, bool up) { if (up || (click_type != mouse_packet::LEFT)) - return false; + return; if (window_coords.x - window_offset.x < 3) window_coords.x = 3 + window_offset.x; @@ -121,18 +154,110 @@ namespace raleigh { cur_y = end_y; cur_x = end_x; } + ensure_cursor_in_line(); + + if (has_focus) + w->notify_needs_paint(*this); + else + w->focus(*this); + } + + void entry::notify_has_opaque_parent(widget *parent) {} + + bool entry::cursor_left() { + if (cur_x) { + --cur_x; + --cur_d; + return true; + } + if (!cur_y) + return false; + + --cur_y; + cur_x = line_indices[cur_y + 1] - line_indices[cur_y] - 1; + if (cur_x == cols) + --cur_x; cur_d = line_indices[cur_y] + cur_x; + return true; + } + + bool entry::cursor_right() { + if (cur_d >= (end_d - 1)) + return false; + + ++cur_d; + ++cur_x; if (cur_d >= line_indices[cur_y + 1]) { - cur_d = line_indices[cur_y + 1] - 1; - if (data[cur_d] != '\n') - ++cur_d; - cur_x = cur_d - line_indices[cur_y]; + cur_x = 0; + ++cur_y; + cur_d = line_indices[cur_y]; } - w->notify_needs_paint(*this); return true; } - void entry::notify_has_opaque_parent(widget *parent) {} + bool entry::cursor_up() { + if (!cur_y) + return false; + + --cur_y; + ensure_cursor_in_line(); + return true; + } + + bool entry::cursor_down() { + if (cur_y == end_y) + return false; + + ++cur_y; + ensure_cursor_in_line(); + return true; + } + + void entry::handle_key(struct key_packet kp) { + switch (kp.key_id) { + case kp.KEY_LEFT_ARROW: + if (cursor_left() && has_focus) + w->notify_needs_paint(*this); + break; + case kp.KEY_RIGHT_ARROW: + if (cursor_right() && has_focus) + w->notify_needs_paint(*this); + break; + case kp.KEY_DOWN_ARROW: + if (cursor_down() && has_focus) + w->notify_needs_paint(*this); + break; + case kp.KEY_UP_ARROW: + if (cursor_up() && has_focus) + w->notify_needs_paint(*this); + break; + case kp.KEY_HOME: + if (cur_x) { + cur_x = 0; + if (has_focus) + w->notify_needs_paint(*this); + } + break; + case kp.KEY_END: + cur_x = cols; + ensure_cursor_in_line(); + if (has_focus) + w->notify_needs_paint(*this); + break; + default: + break; + } + } + + void entry::on_focus() { + has_focus = true; + w->notify_needs_paint(*this); + } + + void entry::on_unfocus() { + has_focus = false; + w->notify_needs_paint(*this); + } } \ No newline at end of file diff --git a/src/user/raleigh/w/label.cpp b/src/user/raleigh/w/label.cpp index 5b74175..046737f 100644 --- a/src/user/raleigh/w/label.cpp +++ b/src/user/raleigh/w/label.cpp @@ -23,12 +23,13 @@ namespace raleigh { } } - __attribute__ ((const)) - bool label::try_handle_click(coord window_coords, enum mouse_packet::mouse_button click_type, bool up) { - return false; - } + 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 0f93216..87167c3 100644 --- a/src/user/raleigh/w/padding.cpp +++ b/src/user/raleigh/w/padding.cpp @@ -17,16 +17,20 @@ namespace raleigh { 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::handle_click(coord window_coords, enum mouse_packet::mouse_button click_type, bool up) { + if ((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.handle_click(window_coords, click_type, up); } void padding::notify_has_opaque_parent(widget *parent) { closest_opaque = parent; inner.notify_has_opaque_parent(parent); } + + void padding::handle_key(struct key_packet kp) {}; + void padding::on_focus() {}; + void padding::on_unfocus() {}; } \ No newline at end of file diff --git a/src/user/raleigh/w/vbox.cpp b/src/user/raleigh/w/vbox.cpp index 51b87ed..08c2539 100644 --- a/src/user/raleigh/w/vbox.cpp +++ b/src/user/raleigh/w/vbox.cpp @@ -27,16 +27,16 @@ namespace raleigh { n->d.paint(pixbuf, pitch); } - bool vbox::try_handle_click(coord window_coords, enum mouse_packet::mouse_button click_type, bool up) { + 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; } - 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); + 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) { @@ -44,4 +44,8 @@ namespace raleigh { for (dllist::node *n = widgets.first; n; n = n->next) n->d.notify_has_opaque_parent(parent); } + + void vbox::handle_key(struct key_packet kp) {}; + void vbox::on_focus() {}; + void vbox::on_unfocus() {}; } \ No newline at end of file diff --git a/src/user/raleigh/window.cpp b/src/user/raleigh/window.cpp index c23545b..052422e 100644 --- a/src/user/raleigh/window.cpp +++ b/src/user/raleigh/window.cpp @@ -7,8 +7,8 @@ namespace raleigh { 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) { + : handle(0), size(root.size), root(root), focussed(&root), + bg_color(bg_color), on_close(on_close) { root.w = this; root.window_offset = coord(0, 0); root.notify_window_change(); @@ -18,6 +18,8 @@ namespace raleigh { 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); paint_full(); + root.on_focus(); + needs_repaint = false; } window::try_actions_return_t window::try_actions() { @@ -39,9 +41,15 @@ namespace raleigh { return DELETE; got = GOOD; 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); + 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) + focussed->handle_key(wa.as_key); + else if (wa.action_type == wa.FOCUS_ENTER) + focussed->on_focus(); + else if (wa.action_type == wa.FOCUS_LEAVE) + focussed->on_unfocus(); } } @@ -67,4 +75,12 @@ namespace raleigh { show_error_and_quitf("Failed to get window handle for requested window."); open_windows.add_front(*this); } + + void window::focus(widget &w) { + if (focussed != &w) { + focussed->on_unfocus(); + focussed = &w; + focussed->on_focus(); + } + } } \ No newline at end of file diff --git a/src/user/rhello/main.cpp b/src/user/rhello/main.cpp index f179317..45329b5 100644 --- a/src/user/rhello/main.cpp +++ b/src/user/rhello/main.cpp @@ -27,7 +27,7 @@ void main() { button b(pbl, &onclick); padding pb(b, 2); - entry e(6, 20, "I'm a text entry!\nEventually you will be able to edit me."); + 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."); padding pe(e, 2); dllist wl; -- cgit v1.2.3