summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/kernel/window.c32
-rw-r--r--src/user/include/cxx/raleigh/w/button.h5
-rw-r--r--src/user/include/cxx/raleigh/w/entry.h25
-rw-r--r--src/user/include/cxx/raleigh/w/label.h5
-rw-r--r--src/user/include/cxx/raleigh/w/padding.h5
-rw-r--r--src/user/include/cxx/raleigh/w/vbox.h5
-rw-r--r--src/user/include/cxx/raleigh/widget.h5
-rw-r--r--src/user/include/cxx/raleigh/window.h2
-rw-r--r--src/user/include/knob/block.h3
-rw-r--r--src/user/include/knob/key.h8
-rw-r--r--src/user/knob/block.c10
-rw-r--r--src/user/raleigh/w/button.cpp11
-rw-r--r--src/user/raleigh/w/entry.cpp215
-rw-r--r--src/user/raleigh/w/label.cpp9
-rw-r--r--src/user/raleigh/w/padding.cpp16
-rw-r--r--src/user/raleigh/w/vbox.cpp12
-rw-r--r--src/user/raleigh/window.cpp26
-rw-r--r--src/user/rhello/main.cpp2
18 files changed, 306 insertions, 90 deletions
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<widget &> 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 <keypack.h>
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 <knob/format.h>
#include <knob/block.h>
#include <knob/heap.h>
+#include <knob/key.h>
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<widget &>::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<widget &>::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<widget &> wl;