diff options
Diffstat (limited to 'framebuffer')
-rw-r--r-- | framebuffer/fbtk.h | 20 | ||||
-rw-r--r-- | framebuffer/fbtk/fbtk.c | 44 | ||||
-rw-r--r-- | framebuffer/fbtk/text.c | 28 | ||||
-rw-r--r-- | framebuffer/fbtk/widget.h | 8 | ||||
-rw-r--r-- | framebuffer/gui.c | 58 |
5 files changed, 144 insertions, 14 deletions
diff --git a/framebuffer/fbtk.h b/framebuffer/fbtk.h index e58795742..131ae6521 100644 --- a/framebuffer/fbtk.h +++ b/framebuffer/fbtk.h @@ -247,6 +247,16 @@ int fbtk_get_height(fbtk_widget_t *widget); */ bool fbtk_get_bbox(fbtk_widget_t *widget, struct nsfb_bbox_s *bbox); +/** Get a widget caret pos, if it owns caret. + * + * @param widget The widget to inspect. + * @param x If widget has caret, returns x-coord of caret within widget + * @param y If widget has caret, returns y-coord of caret within widget + * @param height If widget has caret, returns caret height + * @return true iff widget has caret + */ +bool fbtk_get_caret(fbtk_widget_t *widget, int *x, int *y, int *height); + /******************* Widget Manipulation **********************/ @@ -255,6 +265,16 @@ bool fbtk_get_bbox(fbtk_widget_t *widget, struct nsfb_bbox_s *bbox); */ bool fbtk_set_pos_and_size(fbtk_widget_t *widget, int x, int y, int width, int height); +/** Set caret owner and position + * + * @param widget widget to give caret to, or ensure caret is released from + * @param set true: caret to be set for widget, false: caret to be released + * @param x x-coordinate of caret top + * @param y y-coordinate of caret top + * @param height height of caret + */ +void fbtk_set_caret(fbtk_widget_t *widget, bool set, int x, int y, int height); + /** Map a widget and request it is redrawn. */ int fbtk_set_mapping(fbtk_widget_t *widget, bool mapped); diff --git a/framebuffer/fbtk/fbtk.c b/framebuffer/fbtk/fbtk.c index db298ebdc..8e8bc112c 100644 --- a/framebuffer/fbtk/fbtk.c +++ b/framebuffer/fbtk/fbtk.c @@ -220,6 +220,28 @@ fbtk_set_pos_and_size(fbtk_widget_t *widget, return false; } + +/* exported function docuemnted in fbtk.h */ +void +fbtk_set_caret(fbtk_widget_t *widget, bool set, + int x, int y, int height) +{ + fbtk_widget_t *root; + + assert(widget != NULL); + root = fbtk_get_root_widget(widget); + + if (set) { + root->u.root.caret.owner = widget; + root->u.root.caret.x = x; + root->u.root.caret.y = y; + root->u.root.caret.height = height; + + } else { + root->u.root.caret.owner = NULL; + } +} + /* exported function documented in fbtk.h */ int fbtk_destroy_widget(fbtk_widget_t *widget) @@ -429,6 +451,27 @@ fbtk_get_bbox(fbtk_widget_t *widget, nsfb_bbox_t *bbox) return true; } +bool +fbtk_get_caret(fbtk_widget_t *widget, int *x, int *y, int *height) +{ + fbtk_widget_t *root = fbtk_get_root_widget(widget); + + if (root->u.root.caret.owner == widget) { + *x = root->u.root.caret.x; + *y = root->u.root.caret.y; + *height = root->u.root.caret.height; + + return true; + + } else { + *x = 0; + *y = 0; + *height = 0; + + return false; + } +} + /* exported function documented in fbtk.h */ fbtk_widget_t * fbtk_get_widget_at(fbtk_widget_t *nwid, int x, int y) @@ -727,6 +770,7 @@ fbtk_init(nsfb_t *fb) root->type = FB_WIDGET_TYPE_ROOT; root->u.root.fb = fb; + root->u.root.caret.owner = NULL; nsfb_get_geometry(fb, &root->width, &root->height, NULL); diff --git a/framebuffer/fbtk/text.c b/framebuffer/fbtk/text.c index f50a5ad59..27968148f 100644 --- a/framebuffer/fbtk/text.c +++ b/framebuffer/fbtk/text.c @@ -50,6 +50,19 @@ /* Convert pixels to points, assuming a DPI of 90 */ #define px_to_pt(x) (((x) * 72) / FBTK_DPI) +/* Get a font style for a text input */ +static inline void +fb_text_font_style(fbtk_widget_t *widget, int font_height, + plot_font_style_t *font_style) +{ + font_style->family = PLOT_FONT_FAMILY_SANS_SERIF; + font_style->size = px_to_pt(font_height) * FONT_SIZE_SCALE; + font_style->weight = 400; + font_style->flags = FONTF_NONE; + font_style->background = widget->bg; + font_style->foreground = widget->fg; +} + /** Text redraw callback. * * Called when a text widget requires redrawing. @@ -94,13 +107,7 @@ fb_redraw_text(fbtk_widget_t *widget, fbtk_callback_info *cbi ) if (widget->u.text.text != NULL) { fh = widget->height - padding - padding; - font_style.family = PLOT_FONT_FAMILY_SANS_SERIF; - font_style.size = px_to_pt(fh) * FONT_SIZE_SCALE; - font_style.weight = 400; - font_style.flags = FONTF_NONE; - font_style.background = widget->bg; - font_style.foreground = widget->fg; - + fb_text_font_style(widget, fh, &font_style); FBTK_LOG(("plotting %p at %d,%d %d,%d w/h %d,%d font h %d padding %d", widget, bbox.x0, bbox.y0, bbox.x1, bbox.y1, widget->width, widget->height, fh, padding)); @@ -192,12 +199,7 @@ fb_redraw_text_button(fbtk_widget_t *widget, fbtk_callback_info *cbi ) if (widget->u.text.text != NULL) { fh = widget->height - border - border; - font_style.family = PLOT_FONT_FAMILY_SANS_SERIF; - font_style.size = px_to_pt(fh) * FONT_SIZE_SCALE; - font_style.weight = 400; - font_style.flags = FONTF_NONE; - font_style.background = widget->bg; - font_style.foreground = widget->fg; + fb_text_font_style(widget, fh, &font_style); LOG(("plotting %p at %d,%d %d,%d w/h %d,%d font h %d border %d", widget, bbox.x0, bbox.y0, bbox.x1, bbox.y1, diff --git a/framebuffer/fbtk/widget.h b/framebuffer/fbtk/widget.h index 060999bba..e31fa117d 100644 --- a/framebuffer/fbtk/widget.h +++ b/framebuffer/fbtk/widget.h @@ -161,6 +161,14 @@ struct fbtk_widget_s { struct fbtk_widget_s *prev; /* previous widget pointer wasin */ struct fbtk_widget_s *grabbed; /* widget that has grabbed pointer movement. */ struct fbtk_widget_s *input; + + /* caret */ + struct { + struct fbtk_widget_s *owner; /* widget / NULL */ + int x; /* relative to owner */ + int y; /* relative to owner */ + int height; + } caret; } root; /* bitmap */ diff --git a/framebuffer/gui.c b/framebuffer/gui.c index 10c2e46a1..216791d2b 100644 --- a/framebuffer/gui.c +++ b/framebuffer/gui.c @@ -308,12 +308,14 @@ fb_redraw(fbtk_widget_t *widget, { int x; int y; + int caret_x, caret_y, caret_h; struct rect clip; struct redraw_context ctx = { .interactive = true, .background_images = true, .plot = &fb_plotters }; + nsfb_t *nsfb = fbtk_get_nsfb(widget); LOG(("%d,%d to %d,%d", bwidget->redraw_box.x0, @@ -330,7 +332,7 @@ fb_redraw(fbtk_widget_t *widget, bwidget->redraw_box.x0 += x; bwidget->redraw_box.x1 += x; - nsfb_claim(fbtk_get_nsfb(widget), &bwidget->redraw_box); + nsfb_claim(nsfb, &bwidget->redraw_box); /* redraw bounding box is relative to window */ clip.x0 = bwidget->redraw_box.x0; @@ -343,6 +345,23 @@ fb_redraw(fbtk_widget_t *widget, (y - bwidget->scrolly) / bw->scale, &clip, &ctx); + if (fbtk_get_caret(widget, &caret_x, &caret_y, &caret_h)) { + /* This widget has caret, so render it */ + nsfb_bbox_t line; + nsfb_plot_pen_t pen; + + line.x0 = x - bwidget->scrollx + caret_x; + line.y0 = y - bwidget->scrolly + caret_y; + line.x1 = x - bwidget->scrollx + caret_x; + line.y1 = y - bwidget->scrolly + caret_y + caret_h; + + pen.stroke_type = NFSB_PLOT_OPTYPE_SOLID; + pen.stroke_width = 1; + pen.stroke_colour = 0xFF0000FF; + + nsfb_plot_line(nsfb, &line, &pen); + } + nsfb_update(fbtk_get_nsfb(widget), &bwidget->redraw_box); bwidget->redraw_box.y0 = bwidget->redraw_box.x0 = INT_MAX; @@ -1483,11 +1502,48 @@ gui_window_stop_throbber(struct gui_window *gw) void gui_window_place_caret(struct gui_window *g, int x, int y, int height) { + struct browser_widget_s *bwidget = fbtk_get_userpw(g->browser); + int c_x, c_y, c_h; + + if (fbtk_get_caret(g->browser, &c_x, &c_y, &c_h)) { + /* browser window already had caret: + * redraw its area to remove it first */ + fb_queue_redraw(g->browser, + c_x - bwidget->scrollx, + c_y - bwidget->scrolly, + c_x + 1 - bwidget->scrollx, + c_y + c_h - bwidget->scrolly); + } + + /* set new pos */ + fbtk_set_caret(g->browser, true, x, y, height); + + /* redraw new caret pos */ + fb_queue_redraw(g->browser, + x - bwidget->scrollx, + y - bwidget->scrolly, + x + 1 - bwidget->scrollx, + y + height - bwidget->scrolly); } void gui_window_remove_caret(struct gui_window *g) { + struct browser_widget_s *bwidget = fbtk_get_userpw(g->browser); + int c_x, c_y, c_h; + + if (fbtk_get_caret(g->browser, &c_x, &c_y, &c_h)) { + /* browser window already had caret: + * redraw its area to remove it first */ + fb_queue_redraw(g->browser, + c_x - bwidget->scrollx, + c_y - bwidget->scrolly, + c_x + 1 - bwidget->scrollx, + c_y + c_h - bwidget->scrolly); + } + + /* remove caret */ + fbtk_set_caret(g->browser, false, 0, 0, 0); } void |