/programs/network/netsurf/netsurf/framebuffer/fbtk/bitmap.c |
---|
0,0 → 1,198 |
/* |
* Copyright 2010 Vincent Sanders <vince@simtec.co.uk> |
* |
* Framebuffer windowing toolkit bitmaped image widget |
* |
* This file is part of NetSurf, http://www.netsurf-browser.org/ |
* |
* NetSurf is free software; you can redistribute it and/or modify |
* it under the terms of the GNU General Public License as published by |
* the Free Software Foundation; version 2 of the License. |
* |
* NetSurf is distributed in the hope that it will be useful, |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
* GNU General Public License for more details. |
* |
* You should have received a copy of the GNU General Public License |
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
*/ |
#include <stdbool.h> |
#include <stdlib.h> |
#include <libnsfb.h> |
#include <libnsfb_plot.h> |
#include "desktop/browser.h" |
#include "framebuffer/gui.h" |
#include "framebuffer/fbtk.h" |
#include "framebuffer/image_data.h" |
#include "utils/log.h" |
#include <menuet/os.h> |
#include "widget.h" |
static int |
fb_redraw_bitmap(fbtk_widget_t *widget, fbtk_callback_info *cbi) |
{ |
LOG(("REDRAW BITMAP")); |
//__menuet__debug_out("REDRAW BITMAP"); |
nsfb_bbox_t bbox; |
nsfb_bbox_t rect; |
nsfb_t *nsfb; |
LOG(("REDRAW BITMAP 1 ")); |
//__menuet__debug_out("REDRAW BITMAP 1"); |
nsfb = fbtk_get_nsfb(widget); |
LOG(("REDRAW BITMAP 2")); |
//__menuet__debug_out("REDRAW BITMAP 2"); |
fbtk_get_bbox(widget, &bbox); |
rect = bbox; |
LOG(("REDRAW BITMAP 3 ")); |
//__menuet__debug_out("REDRAW BITMAP 3"); |
nsfb_claim(nsfb, &bbox); |
LOG(("REDRAW BITMAP 4")); |
//__menuet__debug_out("REDRAW BITMAP 4"); |
/* clear background */ |
if ((widget->bg & 0xFF000000) != 0) { |
/* transparent polygon filling isnt working so fake it */ |
LOG(("REDRAW BITMAP 5")); |
//__menuet__debug_out("REDRAW BITMAP 5"); |
nsfb_plot_rectangle_fill(nsfb, &bbox, widget->bg); |
} |
LOG(("REDRAW BITMAP 6")); |
//__menuet__debug_out("REDRAW BITMAP 6\n"); |
/* plot the image */ |
LOG(("STUB: DON'T REAL DRAW")); |
//__menuet__debug_out("STUB: DON'T REAL DRAW\n"); |
LOG(("pixdata is %x", (nsfb_colour_t *)widget->u.bitmap.bitmap->pixdata)); |
LOG(("pixdata is w:%d h:%d",widget->u.bitmap.bitmap->width, |
widget->u.bitmap.bitmap->height)); |
//hmm |
//int zap; |
//if (widget->u.bitmap.bitmap->width % 4 != 0) { |
// zap = widget->u.bitmap.bitmap->width + 2; } |
//nsfb_plot_rectangle_fill(nsfb, &rect, 0xFFFFFF); |
nsfb_plot_bitmap(nsfb, |
&rect, |
(nsfb_colour_t *)widget->u.bitmap.bitmap->pixdata, |
//0, 0, 0, |
widget->u.bitmap.bitmap->width, |
widget->u.bitmap.bitmap->height, |
widget->u.bitmap.bitmap->width, |
!widget->u.bitmap.bitmap->opaque); |
LOG(("REDRAW BITMAP 7")); |
//__menuet__debug_out("REDRAW BITMAP 7\n"); |
nsfb_update(nsfb, &bbox); |
LOG(("REDRAW BITMAP OK\n")); |
//__menuet__debug_out("REDRAW BITMAP OK\n"); |
return 0; |
} |
/* exported function documented in fbtk.h */ |
void |
fbtk_set_bitmap(fbtk_widget_t *widget, struct fbtk_bitmap *image) |
{ |
LOG(("SET BITMAP")); |
//__menuet__debug_out("set BITMAP"); |
if ((widget == NULL) || (widget->type != FB_WIDGET_TYPE_BITMAP)) |
return; |
widget->u.bitmap.bitmap = image; |
fbtk_request_redraw(widget); |
} |
/* exported function documented in fbtk.h */ |
fbtk_widget_t * |
fbtk_create_bitmap(fbtk_widget_t *parent, |
int x, |
int y, |
int width, |
int height, |
colour c, |
struct fbtk_bitmap *image) |
{ |
LOG(("CREATE BITMAP")); |
//__menuet__debug_out("cr BITMAP"); |
fbtk_widget_t *neww; |
neww = fbtk_widget_new(parent, FB_WIDGET_TYPE_BITMAP, x, y, width, height); |
neww->bg = c; |
neww->mapped = true; |
neww->u.bitmap.bitmap = image; |
fbtk_set_handler(neww, FBTK_CBT_REDRAW, fb_redraw_bitmap, NULL); |
return neww; |
} |
/* exported function documented in fbtk.h */ |
fbtk_widget_t * |
fbtk_create_button(fbtk_widget_t *parent, |
int x, |
int y, |
int width, |
int height, |
colour c, |
struct fbtk_bitmap *image, |
fbtk_callback click, |
void *pw) |
{ |
fbtk_widget_t *neww; |
LOG(("CREATE BUTTON BITMAP")); |
//__menuet__debug_out("cr bb BITMAP"); |
neww = fbtk_widget_new(parent, FB_WIDGET_TYPE_BITMAP, x, y, width, height); |
neww->bg = c; |
neww->mapped = true; |
neww->u.bitmap.bitmap = image; |
fbtk_set_handler(neww, FBTK_CBT_REDRAW, fb_redraw_bitmap, NULL); |
fbtk_set_handler(neww, FBTK_CBT_CLICK, click, pw); |
fbtk_set_handler(neww, FBTK_CBT_POINTERENTER, fbtk_set_ptr, &hand_image); |
return neww; |
} |
/* |
* Local Variables: |
* c-basic-offset:8 |
* End: |
*/ |
/programs/network/netsurf/netsurf/framebuffer/fbtk/event.c |
---|
0,0 → 1,344 |
/* |
* Copyright 2010 Vincent Sanders <vince@simtec.co.uk> |
* |
* Framebuffer windowing toolkit event processing. |
* |
* This file is part of NetSurf, http://www.netsurf-browser.org/ |
* |
* NetSurf is free software; you can redistribute it and/or modify |
* it under the terms of the GNU General Public License as published by |
* the Free Software Foundation; version 2 of the License. |
* |
* NetSurf is distributed in the hope that it will be useful, |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
* GNU General Public License for more details. |
* |
* You should have received a copy of the GNU General Public License |
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
*/ |
#include <sys/types.h> |
#include <stdint.h> |
#include <string.h> |
#include <stdbool.h> |
#include <libnsfb.h> |
#include <libnsfb_plot.h> |
#include <libnsfb_plot_util.h> |
#include <libnsfb_event.h> |
#include <libnsfb_cursor.h> |
#include "utils/utils.h" |
#include "utils/log.h" |
#include "css/css.h" |
#include "desktop/browser.h" |
#include "desktop/plotters.h" |
#include "desktop/textinput.h" |
#include "framebuffer/gui.h" |
#include "framebuffer/fbtk.h" |
#include "framebuffer/image_data.h" |
#include "widget.h" |
/* exported function documented in fbtk.h */ |
void |
fbtk_input(fbtk_widget_t *root, nsfb_event_t *event) |
{ |
fbtk_widget_t *input; |
root = fbtk_get_root_widget(root); |
/* obtain widget with input focus */ |
input = root->u.root.input; |
if (input == NULL) { |
LOG(("No widget has input focus.")); |
return; /* no widget with input */ |
} |
fbtk_post_callback(input, FBTK_CBT_INPUT, event); |
} |
/* exported function documented in fbtk.h */ |
void |
fbtk_click(fbtk_widget_t *widget, nsfb_event_t *event) |
{ |
fbtk_widget_t *root; |
fbtk_widget_t *clicked; |
nsfb_bbox_t cloc; |
int x, y; |
/* ensure we have the root widget */ |
root = fbtk_get_root_widget(widget); |
nsfb_cursor_loc_get(root->u.root.fb, &cloc); |
clicked = fbtk_get_widget_at(root, cloc.x0, cloc.y0); |
if (clicked == NULL) |
return; |
if (fbtk_get_handler(clicked, FBTK_CBT_INPUT) != NULL) { |
fbtk_set_focus(clicked); |
} |
x = fbtk_get_absx(clicked); |
y = fbtk_get_absy(clicked); |
LOG(("clicked %p at %d,%d", clicked, x, y)); |
/* post the click */ |
fbtk_post_callback(clicked, FBTK_CBT_CLICK, event, cloc.x0 - x, cloc.y0 - y); |
} |
/* exported function documented in fbtk.h */ |
bool |
fbtk_tgrab_pointer(fbtk_widget_t *widget) |
{ |
fbtk_widget_t *root; |
/* ensure we have the root widget */ |
root = fbtk_get_root_widget(widget); |
if (root->u.root.grabbed == widget) { |
/* release pointer grab */ |
root->u.root.grabbed = NULL; |
return true; |
} else if (root->u.root.grabbed == NULL) { |
/* set pointer grab */ |
root->u.root.grabbed = widget; |
return true; |
} |
/* pointer was already grabbed */ |
return false; |
} |
/* exported function documented in fbtk.h */ |
void |
fbtk_warp_pointer(fbtk_widget_t *widget, int x, int y, bool relative) |
{ |
fbtk_widget_t *root; |
fbtk_widget_t *moved; |
nsfb_bbox_t cloc; |
/* ensure we have the root widget */ |
root = fbtk_get_root_widget(widget); |
if (relative) { |
nsfb_cursor_loc_get(root->u.root.fb, &cloc); |
cloc.x0 += x; |
cloc.y0 += y; |
} else { |
cloc.x0 = x; |
cloc.y0 = y; |
} |
/* ensure cursor location lies within the root widget */ |
if (cloc.x0 < root->x) |
cloc.x0 = root->x; |
if (cloc.x0 >= (root->x + root->width)) |
cloc.x0 = (root->x + root->width) - 1; |
if (cloc.y0 < root->y) |
cloc.y0 = root->y; |
if (cloc.y0 >= (root->y + root->height)) |
cloc.y0 = (root->y + root->height) - 1; |
if (root->u.root.grabbed == NULL) { |
/* update the pointer cursor */ |
nsfb_cursor_loc_set(root->u.root.fb, &cloc); |
moved = fbtk_get_widget_at(root, cloc.x0, cloc.y0); |
x = fbtk_get_absx(moved); |
y = fbtk_get_absy(moved); |
/* post enter and leaving messages */ |
if (moved != root->u.root.prev) { |
fbtk_post_callback(root->u.root.prev, FBTK_CBT_POINTERLEAVE); |
root->u.root.prev = moved; |
fbtk_post_callback(root->u.root.prev, FBTK_CBT_POINTERENTER); |
} |
} else { |
/* pointer movement has been grabbed by a widget */ |
moved = root->u.root.grabbed; |
/* ensure pointer remains within widget boundary */ |
x = fbtk_get_absx(moved); |
y = fbtk_get_absy(moved); |
if (cloc.x0 < x) |
cloc.x0 = x; |
if (cloc.y0 < y) |
cloc.y0 = y; |
if (cloc.x0 > (x + moved->width)) |
cloc.x0 = (x + moved->width); |
if (cloc.y0 > (y + moved->height)) |
cloc.y0 = (y + moved->height); |
/* update the pointer cursor */ |
nsfb_cursor_loc_set(root->u.root.fb, &cloc); |
} |
/* post the movement */ |
fbtk_post_callback(moved, FBTK_CBT_POINTERMOVE, cloc.x0 - x, cloc.y0 - y); |
} |
/* exported function documented in fbtk.h */ |
bool |
fbtk_event(fbtk_widget_t *root, nsfb_event_t *event, int timeout) |
{ |
nsfb_bbox_t cloc; |
bool unused = false; /* is the event available */ |
bool move_pointer = false; /* whether pointer move events occured */ |
/* ensure we have the root widget */ |
root = fbtk_get_root_widget(root); |
do { |
if (nsfb_event(root->u.root.fb, event, timeout) == false) { |
if (move_pointer) |
fbtk_warp_pointer(root, cloc.x0, cloc.y0, |
false); |
return false; |
} |
if (move_pointer && event->type != NSFB_EVENT_MOVE_RELATIVE && |
event->type != NSFB_EVENT_MOVE_ABSOLUTE) { |
/* Flush the movements */ |
fbtk_warp_pointer(root, cloc.x0, cloc.y0, false); |
} else if (!move_pointer && |
event->type == NSFB_EVENT_MOVE_RELATIVE) { |
/* Get current pointer coords */ |
nsfb_cursor_loc_get(root->u.root.fb, &cloc); |
} |
switch (event->type) { |
case NSFB_EVENT_KEY_DOWN: |
case NSFB_EVENT_KEY_UP: |
if ((event->value.keycode >= NSFB_KEY_MOUSE_1) && |
(event->value.keycode <= NSFB_KEY_MOUSE_5)) { |
fbtk_click(root, event); |
} else { |
fbtk_input(root, event); |
} |
break; |
case NSFB_EVENT_CONTROL: |
unused = true; |
break; |
case NSFB_EVENT_MOVE_RELATIVE: |
/* Consecutive move events are consolidated into a |
* single pointer warp */ |
move_pointer = true; |
cloc.x0 += event->value.vector.x; |
cloc.y0 += event->value.vector.y; |
timeout = 0; |
break; |
case NSFB_EVENT_MOVE_ABSOLUTE: |
/* Consecutive move events are consolidated into a |
* single pointer warp */ |
move_pointer = true; |
cloc.x0 = event->value.vector.x; |
cloc.y0 = event->value.vector.y; |
timeout = 0; |
break; |
default: |
break; |
} |
} while (event->type == NSFB_EVENT_MOVE_RELATIVE || |
event->type == NSFB_EVENT_MOVE_ABSOLUTE); |
return unused; |
} |
static int keymap[] = { |
/* 0 1 2 3 4 5 6 7 8 9 */ |
-1, -1, -1, -1, -1, -1, -1, -1, 8, 9, /* 0 - 9 */ |
-1, -1, -1, 13, -1, -1, -1, -1, -1, -1, /* 10 - 19 */ |
-1, -1, -1, -1, -1, -1, -1, 27, -1, -1, /* 20 - 29 */ |
-1, -1, ' ', '!', '"', '#', '$', -1, '&','\'', /* 30 - 39 */ |
'(', ')', '*', '+', ',', '-', '.', '/', '0', '1', /* 40 - 49 */ |
'2', '3', '4', '5', '6', '7', '8', '9', ':', ';', /* 50 - 59 */ |
'<', '=', '>', '?', '@', -1, -1, -1, -1, -1, /* 60 - 69 */ |
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 70 - 79 */ |
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 80 - 89 */ |
-1, '[','\\', ']', '~', '_', '`', 'a', 'b', 'c', /* 90 - 99 */ |
'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', /* 100 - 109 */ |
'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', /* 110 - 119 */ |
'x', 'y', 'z', -1, -1, -1, -1, -1, -1, -1, /* 120 - 129 */ |
}; |
static int sh_keymap[] = { |
/* 0 1 2 3 4 5 6 7 8 9 */ |
-1, -1, -1, -1, -1, -1, -1, -1, 8, 9, /* 0 - 9 */ |
-1, -1, -1, 13, -1, -1, -1, -1, -1, -1, /* 10 - 19 */ |
-1, -1, -1, -1, -1, -1, -1, 27, -1, -1, /* 20 - 29 */ |
-1, -1, ' ', '!', '"', '~', '$', -1, '&', '@', /* 30 - 39 */ |
'(', ')', '*', '+', '<', '_', '>', '?', ')', '!', /* 40 - 49 */ |
'"', 243, '$', '%', '^', '&', '*', '(', ';', ':', /* 50 - 59 */ |
'<', '+', '>', '?', '@', -1, -1, -1, -1, -1, /* 60 - 69 */ |
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 70 - 79 */ |
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 80 - 89 */ |
-1, '{', '|', '}', '~', '_', 254, 'A', 'B', 'C', /* 90 - 99 */ |
'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', /* 100 - 109 */ |
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', /* 110 - 119 */ |
'X', 'Y', 'Z', -1, -1, -1, -1, -1, -1, -1, /* 120 - 129 */ |
}; |
/* exported function documented in fbtk.h */ |
int |
fbtk_keycode_to_ucs4(int code, fbtk_modifier_type mods) |
{ |
int ucs4 = -1; |
if (mods & FBTK_MOD_LSHIFT || mods & FBTK_MOD_RSHIFT) { |
if ((code >= 0) && (code < (int) NOF_ELEMENTS(sh_keymap))) |
ucs4 = sh_keymap[code]; |
} else if (mods == FBTK_MOD_CLEAR) { |
if ((code >= 0) && (code < (int) NOF_ELEMENTS(keymap))) |
ucs4 = keymap[code]; |
} else if (mods & FBTK_MOD_LCTRL || mods & FBTK_MOD_RCTRL) { |
switch (code) { |
case NSFB_KEY_a: |
ucs4 = KEY_SELECT_ALL; |
break; |
case NSFB_KEY_c: |
ucs4 = KEY_COPY_SELECTION; |
break; |
case NSFB_KEY_u: |
ucs4 = KEY_CUT_LINE; |
break; |
case NSFB_KEY_v: |
ucs4 = KEY_PASTE; |
break; |
case NSFB_KEY_x: |
ucs4 = KEY_CUT_SELECTION; |
break; |
case NSFB_KEY_z: |
ucs4 = KEY_CLEAR_SELECTION; |
break; |
default: |
break; |
} |
} |
return ucs4; |
} |
/* |
* Local Variables: |
* c-basic-offset:8 |
* End: |
*/ |
/programs/network/netsurf/netsurf/framebuffer/fbtk/fbtk.c |
---|
0,0 → 1,878 |
/* |
* Copyright 2008,2010 Vincent Sanders <vince@simtec.co.uk> |
* |
* Framebuffer windowing toolkit core. |
* |
* This file is part of NetSurf, http://www.netsurf-browser.org/ |
* |
* NetSurf is free software; you can redistribute it and/or modify |
* it under the terms of the GNU General Public License as published by |
* the Free Software Foundation; version 2 of the License. |
* |
* NetSurf is distributed in the hope that it will be useful, |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
* GNU General Public License for more details. |
* |
* You should have received a copy of the GNU General Public License |
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
*/ |
#include <sys/types.h> |
#include <assert.h> |
#include <stdint.h> |
#include <string.h> |
#include <stdbool.h> |
#include <stdarg.h> |
#include <libnsfb.h> |
#include <libnsfb_plot.h> |
#include <libnsfb_plot_util.h> |
#include <libnsfb_event.h> |
#include <libnsfb_cursor.h> |
#include "utils/utils.h" |
#include "utils/log.h" |
#include "css/css.h" |
#include "desktop/browser.h" |
#include "desktop/plotters.h" |
#include "framebuffer/gui.h" |
#include "framebuffer/fbtk.h" |
#include "framebuffer/image_data.h" |
#include "widget.h" |
#ifdef FBTK_LOGGING |
/* tree dump debug, also example of depth first tree walk */ |
static void |
dump_tk_tree(fbtk_widget_t *widget) |
{ |
widget = fbtk_get_root_widget(widget); |
int indent = 0; |
while (widget != NULL) { |
LOG(("%*s%p", indent, "", widget)); |
if (widget->first_child != NULL) { |
widget = widget->first_child; |
indent += 6; |
} else if (widget->next != NULL) { |
widget = widget->next; |
} else { |
while ((widget->parent != NULL) && |
(widget->parent->next == NULL)) { |
widget = widget->parent; |
indent -= 6; |
} |
if (widget->parent != NULL) { |
indent -= 6; |
widget = widget->parent->next; |
} else { |
widget = NULL; |
} |
} |
} |
} |
#endif |
/* exported function documented in fbtk.h */ |
void |
fbtk_request_redraw(fbtk_widget_t *widget) |
{ |
fbtk_widget_t *cwidget; |
fbtk_widget_t *pwidget; |
assert(widget != NULL); |
/* if widget not mapped do not try to redraw it */ |
pwidget = widget; |
while (pwidget != NULL) { |
if (pwidget->mapped == false) |
return; |
pwidget = pwidget->parent; |
} |
widget->redraw.needed = true; |
widget->redraw.x = 0; |
widget->redraw.y = 0; |
widget->redraw.width = widget->width; |
widget->redraw.height = widget->height; |
LOG(("redrawing %p %d,%d %d,%d", |
widget, |
widget->redraw.x, |
widget->redraw.y, |
widget->redraw.width, |
widget->redraw.height)); |
cwidget = widget->last_child; |
while (cwidget != NULL) { |
fbtk_request_redraw(cwidget); |
cwidget = cwidget->prev; |
} |
while (widget->parent != NULL) { |
widget = widget->parent; |
widget->redraw.child = true; |
} |
} |
/* exported function documented in fbtk.h */ |
int |
fbtk_set_mapping(fbtk_widget_t *widget, bool map) |
{ |
LOG(("setting mapping on %p to %d", widget, map)); |
widget->mapped = map; |
if (map) { |
fbtk_request_redraw(widget); |
} else { |
fbtk_request_redraw(widget->parent); |
} |
return 0; |
} |
/** swap the widget given with the next sibling. |
* |
* Swap a sibling widget with the next deepest in the hierachy |
*/ |
static void |
swap_siblings(fbtk_widget_t *lw) |
{ |
fbtk_widget_t *rw; /* the widget to swap lw with */ |
fbtk_widget_t *before; |
fbtk_widget_t *after; |
rw = lw->next; |
LOG(("Swapping %p with %p", lw, rw)); |
before = lw->prev; |
after = rw->next; |
if (before == NULL) { |
/* left widget is currently the first child */ |
lw->parent->first_child = rw; |
} else { |
before->next = rw; |
} |
rw->prev = before; |
rw->next = lw; |
if (after == NULL) { |
/* right widget is currently the last child */ |
rw->parent->last_child = lw; |
} else { |
after->prev = lw; |
} |
lw->next = after; |
lw->prev = rw; |
} |
/* exported function documented in fbtk.h */ |
int |
fbtk_set_zorder(fbtk_widget_t *widget, int z) |
{ |
while (z != 0) { |
if (z < 0) { |
if (widget->prev == NULL) |
break; /* cannot go any shallower */ |
/* swap with previous entry */ |
swap_siblings(widget->prev); |
z++; |
} else { |
if (widget->next == NULL) |
break; /* cannot go any deeper */ |
/* swap with subsequent entry */ |
swap_siblings(widget); |
z--; |
} |
} |
return z; |
} |
/* exported function documented in fbtk.h */ |
bool |
fbtk_set_pos_and_size(fbtk_widget_t *widget, |
int x, int y, |
int width, int height) |
{ |
if ((widget->x != x) || |
(widget->y != y) || |
(widget->width != width) || |
(widget->height != height)) { |
widget->x = x; |
widget->y = y; |
widget->width = width; |
widget->height = height; |
/* @todo This should limit the redrawn area to the sum |
* of the old and new widget dimensions, not redraw the lot. |
*/ |
fbtk_request_redraw(widget->parent); |
return true; |
} |
return false; |
} |
/* exported function docuemnted in fbtk.h */ |
void |
fbtk_set_caret(fbtk_widget_t *widget, bool set, |
int x, int y, int height, |
void (*remove_caret)(fbtk_widget_t *widget)) |
{ |
fbtk_widget_t *root; |
assert(widget != NULL); |
root = fbtk_get_root_widget(widget); |
if (root->u.root.caret.owner != NULL && |
root->u.root.caret.remove_cb != NULL) |
root->u.root.caret.remove_cb(widget); |
if (set) { |
assert(remove_caret != NULL); |
root->u.root.caret.owner = widget; |
root->u.root.caret.x = x; |
root->u.root.caret.y = y; |
root->u.root.caret.height = height; |
root->u.root.caret.remove_cb = remove_caret; |
} else { |
root->u.root.caret.owner = NULL; |
root->u.root.caret.remove_cb = NULL; |
} |
} |
/* exported function documented in fbtk.h */ |
int |
fbtk_destroy_widget(fbtk_widget_t *widget) |
{ |
fbtk_widget_t *parent; |
int ret = 0; |
ret = fbtk_post_callback(widget, FBTK_CBT_DESTROY); |
while (widget->first_child != NULL) { |
fbtk_destroy_widget(widget->first_child); |
} |
parent = widget->parent; |
if (parent != NULL) { |
/* unlink from siblings */ |
if (widget->prev != NULL) { |
widget->prev->next = widget->next; |
} else { |
/* must be the first widget, unlink from parent */ |
parent->first_child = widget->next; |
} |
if (widget->next != NULL) { |
widget->next->prev = widget->prev; |
} else { |
/* must be the last widget, unlink from parent */ |
parent->last_child = widget->prev; |
} |
free(widget); |
} |
return ret; |
} |
/* region coverage flags. */ |
enum { |
POINT_LEFTOF_REGION = 1, |
POINT_RIGHTOF_REGION = 2, |
POINT_ABOVE_REGION = 4, |
POINT_BELOW_REGION = 8, |
}; |
/* Computes where a point lies in respect to an area. */ |
#define REGION(x,y,cx1,cx2,cy1,cy2) \ |
(( (y) > (cy2) ? POINT_BELOW_REGION : 0) | \ |
( (y) < (cy1) ? POINT_ABOVE_REGION : 0) | \ |
( (x) > (cx2) ? POINT_RIGHTOF_REGION : 0) | \ |
( (x) < (cx1) ? POINT_LEFTOF_REGION : 0) ) |
/* swap two integers */ |
#define SWAP(a, b) do { int t; t=(a); (a)=(b); (b)=t; } while(0) |
/* exported function documented in fbtk.h */ |
bool |
fbtk_clip_rect(const bbox_t * clip, bbox_t * box) |
{ |
uint8_t region1; |
uint8_t region2; |
/* ensure co-ordinates are in ascending order */ |
if (box->x1 < box->x0) |
SWAP(box->x0, box->x1); |
if (box->y1 < box->y0) |
SWAP(box->y0, box->y1); |
region1 = REGION(box->x0, box->y0, clip->x0, clip->x1 - 1, clip->y0, clip->y1 - 1); |
region2 = REGION(box->x1, box->y1, clip->x0, clip->x1 - 1, clip->y0, clip->y1 - 1); |
/* area lies entirely outside the clipping rectangle */ |
if ((region1 | region2) && (region1 & region2)) |
return false; |
if (box->x0 < clip->x0) |
box->x0 = clip->x0; |
if (box->x0 > clip->x1) |
box->x0 = clip->x1; |
if (box->x1 < clip->x0) |
box->x1 = clip->x0; |
if (box->x1 > clip->x1) |
box->x1 = clip->x1; |
if (box->y0 < clip->y0) |
box->y0 = clip->y0; |
if (box->y0 > clip->y1) |
box->y0 = clip->y1; |
if (box->y1 < clip->y0) |
box->y1 = clip->y0; |
if (box->y1 > clip->y1) |
box->y1 = clip->y1; |
return true; |
} |
/* exported function documented in fbtk.h */ |
bool |
fbtk_clip_to_widget(fbtk_widget_t *widget, bbox_t * box) |
{ |
bbox_t wbox; |
wbox.x0 = 0; |
wbox.y0 = 0; |
wbox.x1 = widget->width; |
wbox.y1 = widget->height; |
return fbtk_clip_rect(&wbox, box); |
} |
/* internally exported function documented in widget.h */ |
int |
fbtk_set_ptr(fbtk_widget_t *widget, fbtk_callback_info *cbi) |
{ |
fbtk_widget_t *root = fbtk_get_root_widget(widget); |
struct fbtk_bitmap *bm = cbi->context; |
nsfb_cursor_set(root->u.root.fb, |
(nsfb_colour_t *)bm->pixdata, |
bm->width, |
bm->height, |
bm->width, |
bm->hot_x, |
bm->hot_y); |
return 0; |
} |
/* internally exported function documented in widget.h */ |
fbtk_widget_t * |
fbtk_get_root_widget(fbtk_widget_t *widget) |
{ |
while (widget->parent != NULL) |
widget = widget->parent; |
/* check root widget was found */ |
if (widget->type != FB_WIDGET_TYPE_ROOT) { |
LOG(("Widget with null parent that is not the root widget!")); |
return NULL; |
} |
return widget; |
} |
/* exported function documented in fbtk.h */ |
int |
fbtk_get_absx(fbtk_widget_t *widget) |
{ |
int x = widget->x; |
while (widget->parent != NULL) { |
widget = widget->parent; |
x += widget->x; |
} |
return x; |
} |
/* exported function documented in fbtk.h */ |
int |
fbtk_get_absy(fbtk_widget_t *widget) |
{ |
int y = widget->y; |
while (widget->parent != NULL) { |
widget = widget->parent; |
y += widget->y; |
} |
return y; |
} |
/* exported function documented in fbtk.h */ |
int |
fbtk_get_height(fbtk_widget_t *widget) |
{ |
return widget->height; |
} |
/* exported function documented in fbtk.h */ |
int |
fbtk_get_width(fbtk_widget_t *widget) |
{ |
return widget->width; |
} |
/* exported function documented in fbtk.h */ |
bool |
fbtk_get_bbox(fbtk_widget_t *widget, nsfb_bbox_t *bbox) |
{ |
bbox->x0 = widget->x; |
bbox->y0 = widget->y; |
bbox->x1 = widget->x + widget->width; |
bbox->y1 = widget->y + widget->height; |
widget = widget->parent; |
while (widget != NULL) { |
bbox->x0 += widget->x; |
bbox->y0 += widget->y; |
bbox->x1 += widget->x; |
bbox->y1 += widget->y; |
widget = widget->parent; |
} |
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) |
{ |
fbtk_widget_t *widget = NULL; /* found widget */ |
/* require the root widget to start */ |
nwid = fbtk_get_root_widget(nwid); |
while (nwid != NULL) { |
if ((nwid->mapped) && |
(x >= nwid->x) && |
(y >= nwid->y) && |
(x < (nwid->x + nwid->width)) && |
(y < (nwid->y + nwid->height))) { |
widget = nwid; |
x -= nwid->x; |
y -= nwid->y; |
nwid = nwid->first_child; |
} else { |
nwid = nwid->next; |
} |
} |
return widget; |
} |
/* internally exported function documented in widget.h */ |
fbtk_widget_t * |
fbtk_widget_new(fbtk_widget_t *parent, |
enum fbtk_widgettype_e type, |
int x, |
int y, |
int width, |
int height) |
{ |
LOG(("New widget...")); |
fbtk_widget_t *neww; /* new widget */ |
if (parent == NULL) |
{LOG(("parent null...")); |
return NULL;} |
LOG(("calloc...")); |
neww = calloc(1, sizeof(fbtk_widget_t)); |
if (neww == NULL) |
return NULL; |
LOG(("super!...")); |
LOG(("creating %p %d,%d %d,%d", neww, x, y, width, height)); |
/* make new window fit inside parent */ |
if (width == 0) { |
width = parent->width - x; |
} else if (width < 0) { |
width = parent->width + width - x; |
} |
if ((width + x) > parent->width) { |
width = parent->width - x; |
} |
if (height == 0) { |
height = parent->height - y; |
} else if (height < 0) { |
height = parent->height + height - y; |
} |
if ((height + y) > parent->height) { |
height = parent->height - y; |
} |
LOG(("using %p %d,%d %d,%d", neww, x, y, width, height)); |
/* set values */ |
neww->type = type; |
neww->x = x; |
neww->y = y; |
neww->width = width; |
neww->height = height; |
/* insert into widget heiarchy */ |
LOG(("into hierarchy...")); |
neww->parent = parent; |
if (parent->first_child == NULL) { |
/* no child widgets yet */ |
LOG(("no childs yet...")); |
parent->last_child = neww; |
} else { |
/* add new widget to front of sibling chain */ |
neww->next = parent->first_child; |
neww->next->prev = neww; |
LOG(("n front of sibling...")); |
} |
parent->first_child = neww; |
LOG(("Widget OK...")); |
return neww; |
} |
/* exported function documented in fbtk.h */ |
bool |
fbtk_get_redraw_pending(fbtk_widget_t *widget) |
{ |
fbtk_widget_t *root; |
/* ensure we have the root widget */ |
root = fbtk_get_root_widget(widget); |
return root->redraw.needed | root->redraw.child; |
} |
/** Perform a depth-first tree-walk, calling the redraw callback of the widgets in turn. |
* |
* This function makes no decisions of its own and simply walks the |
* widget tree depth first calling widgets redraw callbacks if flagged |
* to do so. |
* The tree search is optimised with a flag to indicate wether the |
* children of a node should be considered. |
*/ |
#include <menuet/os.h> |
static int |
do_redraw(nsfb_t *nsfb, fbtk_widget_t *widget) |
{ |
nsfb_bbox_t plot_ctx; |
fbtk_widget_t *cwidget; /* child widget */ |
LOG(("DO REDRAW")); |
//__menuet__debug_out("\n***********\nDO REDRAW\n********\n"); |
/* check if the widget requires redrawing */ |
if (widget->redraw.needed == true) { |
plot_ctx.x0 = fbtk_get_absx(widget) + widget->redraw.x; |
plot_ctx.y0 = fbtk_get_absy(widget) + widget->redraw.y; |
plot_ctx.x1 = plot_ctx.x0 + widget->redraw.width; |
plot_ctx.y1 = plot_ctx.y0 + widget->redraw.height; |
LOG(("clipping %p %d,%d %d,%d", |
widget, plot_ctx.x0, plot_ctx.y0, |
plot_ctx.x1, plot_ctx.y1)); |
if (nsfb_plot_set_clip(nsfb, &plot_ctx) == true) { |
LOG(("POST CALLBACK")); |
//__menuet__debug_out("\n***********\nPOST CALLBACK\n********\n"); |
fbtk_post_callback(widget, FBTK_CBT_REDRAW); |
} |
widget->redraw.needed = false; |
} |
LOG(("DO CHILD")); |
//__menuet__debug_out("\n***********\nDO CHILD\n********\n"); |
/* walk the widgets children if child flag is set */ |
if (widget->redraw.child) { |
LOG(("DO CHILD 2")); |
//__menuet__debug_out("\n***********\nDO CHILD 2\n********\n"); |
cwidget = widget->last_child; |
while (cwidget != NULL) { |
LOG(("DO CHILD 3 ZZZ")); |
//__menuet__debug_out("\n***********\nDO CHILD 3 ZZZ\n********\n"); |
do_redraw(nsfb, cwidget); |
cwidget = cwidget->prev; |
} |
LOG(("DO CHILD 4")); |
//__menuet__debug_out("\n***********\nDO CHILD 4\n********\n"); |
widget->redraw.child = false; |
} |
LOG(("SUP")); |
//__menuet__debug_out("\n***********\nFIN REDRAW\n********\n"); |
return 1; |
} |
/* exported function documented in fbtk.h */ |
int |
fbtk_redraw(fbtk_widget_t *widget) |
{ |
fbtk_widget_t *root; |
/* ensure we have the root widget */ |
root = fbtk_get_root_widget(widget); |
return do_redraw(root->u.root.fb, root); |
} |
/* exported function documented in fbtk.h */ |
fbtk_callback |
fbtk_get_handler(fbtk_widget_t *widget, fbtk_callback_type cbt) |
{ |
if ((cbt <= FBTK_CBT_START) || (cbt >= FBTK_CBT_END)) { |
/* type out of range, no way to report error so return NULL */ |
return NULL; |
} |
return widget->callback[cbt]; |
} |
/* exported function documented in fbtk.h */ |
fbtk_callback |
fbtk_set_handler(fbtk_widget_t *widget, |
fbtk_callback_type cbt, |
fbtk_callback cb, |
void *context) |
{ |
fbtk_callback prevcb; |
if ((cbt <= FBTK_CBT_START) || (cbt >= FBTK_CBT_END)) { |
/* type out of range, no way to report error so return NULL */ |
return NULL; |
} |
prevcb = widget->callback[cbt]; |
widget->callback[cbt] = cb; |
widget->callback_context[cbt] = context; |
return prevcb; |
} |
/* exported function docuemnted in fbtk.h */ |
int |
fbtk_post_callback(fbtk_widget_t *widget, fbtk_callback_type cbt, ...) |
{ |
LOG(("DO POST CALLBACK")); |
//__menuet__debug_out("\n***********\nDO POST CALLBACK\n********\n"); |
fbtk_callback_info cbi; |
int ret = 0; |
va_list ap; |
if (widget == NULL) |
return -1; |
/* if the widget is not mapped do not attempt to post any |
* events to it |
*/ |
if (widget->mapped == false) |
return ret; |
LOG(("DO POST CALLBACK 2")); |
//__menuet__debug_out("\n***********\nDO POST CALLBACK 2\n********\n"); |
if (widget->callback[cbt] != NULL) { |
cbi.type = cbt; |
cbi.context = widget->callback_context[cbt]; |
LOG(("DO POST CALLBACK 3 - VA")); |
//__menuet__debug_out("\n***********\nDO POST CALLBACK 3 - VA\n********\n"); |
va_start(ap, cbt); |
switch (cbt) { |
case FBTK_CBT_SCROLLX: |
//__menuet__debug_out("\n***********\n scroll x - VA\n********\n"); |
cbi.x = va_arg(ap,int); |
break; |
case FBTK_CBT_SCROLLY: |
//__menuet__debug_out("\n***********\n scroll y - VA\n********\n"); |
cbi.y = va_arg(ap,int); |
break; |
case FBTK_CBT_CLICK: |
//__menuet__debug_out("\n***********\n click - VA\n********\n"); |
cbi.event = va_arg(ap, void *); |
cbi.x = va_arg(ap, int); |
cbi.y = va_arg(ap, int); |
break; |
case FBTK_CBT_INPUT: |
//__menuet__debug_out("\n***********\n input - VA\n********\n"); |
cbi.event = va_arg(ap, void *); |
break; |
case FBTK_CBT_POINTERMOVE: |
//__menuet__debug_out("\n***********\n mouse move - VA\n********\n"); |
cbi.x = va_arg(ap, int); |
cbi.y = va_arg(ap, int); |
break; |
case FBTK_CBT_REDRAW: |
//__menuet__debug_out("\n***********\n red - VA\n********\n"); |
break; |
case FBTK_CBT_USER: |
//__menuet__debug_out("\n***********\n user - VA\n********\n"); |
break; |
case FBTK_CBT_STRIP_FOCUS: |
//__menuet__debug_out("\n***********\n focus - VA\n********\n"); |
break; |
default: |
//__menuet__debug_out("\n***********\n wtf - VA\n********\n"); |
break; |
} |
LOG(("DO POST CALLBACK free")); |
//__menuet__debug_out("\n***********\nDO POST CALLBACK free\n********\n"); |
va_end(ap); |
LOG(("DO CALLBACK YEAH")); |
//__menuet__debug_out("\n***********\nWTF IS THIS\n********\n"); |
char zupa[64]; |
sprintf (zupa, "ADDRESS of callback is %x \n",(widget->callback[cbt])); |
//__menuet__debug_out(zupa); |
LOG(("ADDRESS of callback is %x \n",(widget->callback[cbt]))); |
ret = (widget->callback[cbt])(widget, &cbi); |
LOG(("DO CALLBACK YEAH 2")); |
//__menuet__debug_out("\n***********\nWTF IS THIS!!!12121\n********\n"); |
} |
LOG(("DO POST CALLBACK OK")); |
//__menuet__debug_out("\n***********\nDO POST CALLBACK OK\n********\n"); |
return ret; |
} |
/* exported function docuemnted in fbtk.h */ |
void |
fbtk_set_focus(fbtk_widget_t *widget) |
{ |
fbtk_widget_t *root; |
/* ensure we have the root widget */ |
root = fbtk_get_root_widget(widget); |
if (root->u.root.input != NULL && |
root->u.root.input != widget) { |
/* inform previous holder of focus that it's being stripped |
* of focus */ |
fbtk_post_callback(root->u.root.input, FBTK_CBT_STRIP_FOCUS); |
} |
root->u.root.input = widget; |
} |
/* exported function docuemnted in fbtk.h */ |
nsfb_t * |
fbtk_get_nsfb(fbtk_widget_t *widget) |
{ |
fbtk_widget_t *root; |
/* ensure we have the root widget */ |
root = fbtk_get_root_widget(widget); |
return root->u.root.fb; |
} |
/* exported function docuemnted in fbtk.h */ |
fbtk_widget_t * |
fbtk_init(nsfb_t *fb) |
{ |
fbtk_widget_t *root; |
/* create and configure root widget */ |
root = calloc(1, sizeof(fbtk_widget_t)); |
if (root == NULL) |
return NULL; |
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); |
root->mapped = true; |
return root; |
} |
/* |
* Local Variables: |
* c-basic-offset:8 |
* End: |
*/ |
/programs/network/netsurf/netsurf/framebuffer/fbtk/fill.c |
---|
0,0 → 1,81 |
/* |
* Copyright 2010 Vincent Sanders <vince@simtec.co.uk> |
* |
* Framebuffer windowing toolkit filled area widget |
* |
* This file is part of NetSurf, http://www.netsurf-browser.org/ |
* |
* NetSurf is free software; you can redistribute it and/or modify |
* it under the terms of the GNU General Public License as published by |
* the Free Software Foundation; version 2 of the License. |
* |
* NetSurf is distributed in the hope that it will be useful, |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
* GNU General Public License for more details. |
* |
* You should have received a copy of the GNU General Public License |
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
*/ |
#include <stdbool.h> |
#include <stdlib.h> |
#include <libnsfb.h> |
#include <libnsfb_plot.h> |
#include "desktop/browser.h" |
#include "framebuffer/gui.h" |
#include "framebuffer/fbtk.h" |
#include "widget.h" |
static int |
fb_redraw_fill(fbtk_widget_t *widget, fbtk_callback_info *cbi) |
{ |
nsfb_bbox_t bbox; |
nsfb_t *nsfb; |
nsfb = fbtk_get_nsfb(widget); |
fbtk_get_bbox(widget, &bbox); |
nsfb_claim(nsfb, &bbox); |
/* clear background */ |
if ((widget->bg & 0xFF000000) != 0) { |
/* transparent polygon filling isnt working so fake it */ |
nsfb_plot_rectangle_fill(nsfb, &bbox, widget->bg); |
} |
nsfb_update(nsfb, &bbox); |
return 0; |
} |
/* exported function documented in fbtk.h */ |
fbtk_widget_t * |
fbtk_create_fill(fbtk_widget_t *parent, |
int x, |
int y, |
int width, |
int height, |
colour c) |
{ |
fbtk_widget_t *neww; |
neww = fbtk_widget_new(parent, FB_WIDGET_TYPE_FILL, x, y, width, height); |
neww->bg = c; |
neww->mapped = true; |
fbtk_set_handler(neww, FBTK_CBT_REDRAW, fb_redraw_fill, NULL); |
return neww; |
} |
/* |
* Local Variables: |
* c-basic-offset:8 |
* End: |
*/ |
/programs/network/netsurf/netsurf/framebuffer/fbtk/make.fbtk |
---|
0,0 → 1,7 |
OBJS = fbtk.o event.o fill.o bitmap.o user.o window.o \ |
text.o scroll.o osk.o |
OUTFILE = TEST.o |
CFLAGS += -I ../include/ -I ../ -I../../ -I./ -I/home/sourcerer/kos_src/newenginek/kolibri/include |
include $(MENUETDEV)/makefiles/Makefile_for_o_lib |
/programs/network/netsurf/netsurf/framebuffer/fbtk/osk.c |
---|
0,0 → 1,199 |
/* |
* Copyright 2010 Vincent Sanders <vince@simtec.co.uk> |
* |
* Framebuffer windowing toolkit on screen keyboard. |
* |
* This file is part of NetSurf, http://www.netsurf-browser.org/ |
* |
* NetSurf is free software; you can redistribute it and/or modify |
* it under the terms of the GNU General Public License as published by |
* the Free Software Foundation; version 2 of the License. |
* |
* NetSurf is distributed in the hope that it will be useful, |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
* GNU General Public License for more details. |
* |
* You should have received a copy of the GNU General Public License |
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
*/ |
#include <stdbool.h> |
#include <limits.h> |
#include <libnsfb.h> |
#include <libnsfb_plot.h> |
#include <libnsfb_event.h> |
#include <libnsfb_cursor.h> |
#include "utils/log.h" |
#include "desktop/browser.h" |
#include "framebuffer/gui.h" |
#include "framebuffer/fbtk.h" |
#include "framebuffer/image_data.h" |
#include "widget.h" |
struct kbd_button_s { |
int x; |
int y; |
int w; |
int h; |
const char *t; |
enum nsfb_key_code_e keycode; |
}; |
#define KEYCOUNT 58 |
static struct kbd_button_s kbdbase[KEYCOUNT] = { |
{ 0, 0, 20, 15, "`", NSFB_KEY_BACKQUOTE}, |
{ 20, 0, 20, 15, "1", NSFB_KEY_1}, |
{ 40, 0, 20, 15, "2", NSFB_KEY_2}, |
{ 60, 0, 20, 15, "3", NSFB_KEY_3}, |
{ 80, 0, 20, 15, "4", NSFB_KEY_4}, |
{ 100, 0, 20, 15, "5", NSFB_KEY_5}, |
{ 120, 0, 20, 15, "6", NSFB_KEY_6}, |
{ 140, 0, 20, 15, "7", NSFB_KEY_7}, |
{ 160, 0, 20, 15, "8", NSFB_KEY_8}, |
{ 180, 0, 20, 15, "9", NSFB_KEY_9}, |
{ 200, 0, 20, 15, "0", NSFB_KEY_0}, |
{ 220, 0, 20, 15, "-", NSFB_KEY_MINUS}, |
{ 240, 0, 20, 15, "=", NSFB_KEY_EQUALS}, |
{ 260, 0, 40, 15, "\xe2\x8c\xab", NSFB_KEY_BACKSPACE}, |
{ 0, 15, 30, 15, "\xe2\x86\xb9", NSFB_KEY_TAB}, |
{ 30, 15, 20, 15, "q", NSFB_KEY_q}, |
{ 50, 15, 20, 15, "w", NSFB_KEY_w}, |
{ 70, 15, 20, 15, "e", NSFB_KEY_e}, |
{ 90, 15, 20, 15, "r", NSFB_KEY_r}, |
{ 110, 15, 20, 15, "t", NSFB_KEY_t}, |
{ 130, 15, 20, 15, "y", NSFB_KEY_y}, |
{ 150, 15, 20, 15, "u", NSFB_KEY_u}, |
{ 170, 15, 20, 15, "i", NSFB_KEY_i}, |
{ 190, 15, 20, 15, "o", NSFB_KEY_o}, |
{ 210, 15, 20, 15, "p", NSFB_KEY_p}, |
{ 230, 15, 20, 15, "[", NSFB_KEY_LEFTBRACKET}, |
{ 250, 15, 20, 15, "]", NSFB_KEY_RIGHTBRACKET}, |
{ 275, 15, 25, 30, "\xe2\x8f\x8e", NSFB_KEY_RETURN}, |
{ 35, 30, 20, 15, "a", NSFB_KEY_a}, |
{ 55, 30, 20, 15, "s", NSFB_KEY_s}, |
{ 75, 30, 20, 15, "d", NSFB_KEY_d}, |
{ 95, 30, 20, 15, "f", NSFB_KEY_f}, |
{ 115, 30, 20, 15, "g", NSFB_KEY_g}, |
{ 135, 30, 20, 15, "h", NSFB_KEY_h}, |
{ 155, 30, 20, 15, "j", NSFB_KEY_j}, |
{ 175, 30, 20, 15, "k", NSFB_KEY_k}, |
{ 195, 30, 20, 15, "l", NSFB_KEY_l}, |
{ 215, 30, 20, 15, ";", NSFB_KEY_SEMICOLON}, |
{ 235, 30, 20, 15, "'", NSFB_KEY_l}, |
{ 255, 30, 20, 15, "#", NSFB_KEY_HASH}, |
{ 0, 45, 25, 15, "\xe2\x87\xa7", NSFB_KEY_LSHIFT}, |
{ 25, 45, 20, 15, "\\", NSFB_KEY_SLASH}, |
{ 45, 45, 20, 15, "z", NSFB_KEY_z}, |
{ 65, 45, 20, 15, "x", NSFB_KEY_x}, |
{ 85, 45, 20, 15, "c", NSFB_KEY_c}, |
{ 105, 45, 20, 15, "v", NSFB_KEY_v}, |
{ 125, 45, 20, 15, "b", NSFB_KEY_b}, |
{ 145, 45, 20, 15, "n", NSFB_KEY_n}, |
{ 165, 45, 20, 15, "m", NSFB_KEY_m}, |
{ 185, 45, 20, 15, ",", NSFB_KEY_COMMA}, |
{ 205, 45, 20, 15, ".", NSFB_KEY_PERIOD}, |
{ 225, 45, 20, 15, "/", NSFB_KEY_BACKSLASH}, |
{ 245, 45, 55, 15, "\xe2\x87\xa7", NSFB_KEY_RSHIFT}, |
{ 40, 67, 185, 15, "", NSFB_KEY_SPACE}, |
{ 250, 60, 20, 15, "\xe2\x96\xb2", NSFB_KEY_UP}, |
{ 230, 67, 20, 15, "\xe2\x97\x80", NSFB_KEY_LEFT}, |
{ 270, 67, 20, 15, "\xe2\x96\xb6", NSFB_KEY_RIGHT}, |
{ 250, 75, 20, 15, "\xe2\x96\xbc", NSFB_KEY_DOWN}, |
}; |
static fbtk_widget_t *osk; |
static int |
osk_close(fbtk_widget_t *widget, fbtk_callback_info *cbi) |
{ |
if (cbi->event->type != NSFB_EVENT_KEY_UP) |
return 0; |
fbtk_set_mapping(osk, false); |
return 0; |
} |
static int |
osk_click(fbtk_widget_t *widget, fbtk_callback_info *cbi) |
{ |
nsfb_event_t event; |
struct kbd_button_s *kbd_button = cbi->context; |
event.type = cbi->event->type; |
event.value.keycode = kbd_button->keycode; |
fbtk_input(widget, &event); |
return 0; |
} |
/* exported function documented in fbtk.h */ |
void |
fbtk_enable_oskb(fbtk_widget_t *fbtk) |
{ |
fbtk_widget_t *widget; |
int kloop; |
int maxx = 0; |
int maxy = 0; |
int ww; |
int wh; |
fbtk_widget_t *root = fbtk_get_root_widget(fbtk); |
int furniture_width = 18; |
for (kloop=0; kloop < KEYCOUNT; kloop++) { |
if ((kbdbase[kloop].x + kbdbase[kloop].w) > maxx) |
maxx=kbdbase[kloop].x + kbdbase[kloop].w; |
if ((kbdbase[kloop].y + kbdbase[kloop].h) > maxy) |
maxy=kbdbase[kloop].y + kbdbase[kloop].h; |
} |
ww = fbtk_get_width(root); |
/* scale window height apropriately */ |
wh = (maxy * ww) / maxx; |
osk = fbtk_create_window(root, 0, fbtk_get_height(root) - wh, 0, wh, 0xff202020); |
for (kloop=0; kloop < KEYCOUNT; kloop++) { |
widget = fbtk_create_text_button(osk, |
(kbdbase[kloop].x * ww) / maxx, |
(kbdbase[kloop].y * ww) / maxx, |
(kbdbase[kloop].w * ww) / maxx, |
(kbdbase[kloop].h *ww) / maxx, |
FB_FRAME_COLOUR, |
FB_COLOUR_BLACK, |
osk_click, |
&kbdbase[kloop]); |
fbtk_set_text(widget, kbdbase[kloop].t); |
} |
widget = fbtk_create_button(osk, |
fbtk_get_width(osk) - furniture_width, |
fbtk_get_height(osk) - furniture_width, |
furniture_width, |
furniture_width, |
FB_FRAME_COLOUR, |
&osk_image, |
osk_close, |
NULL); |
} |
/* exported function documented in fbtk.h */ |
void |
map_osk(void) |
{ |
fbtk_set_zorder(osk, INT_MIN); |
fbtk_set_mapping(osk, true); |
} |
/* |
* Local Variables: |
* c-basic-offset:8 |
* End: |
*/ |
/programs/network/netsurf/netsurf/framebuffer/fbtk/scroll.c |
---|
0,0 → 1,619 |
/* |
* Copyright 2010 Vincent Sanders <vince@simtec.co.uk> |
* |
* Framebuffer windowing toolkit scrollbar widgets |
* |
* This file is part of NetSurf, http://www.netsurf-browser.org/ |
* |
* NetSurf is free software; you can redistribute it and/or modify |
* it under the terms of the GNU General Public License as published by |
* the Free Software Foundation; version 2 of the License. |
* |
* NetSurf is distributed in the hope that it will be useful, |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
* GNU General Public License for more details. |
* |
* You should have received a copy of the GNU General Public License |
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
*/ |
#include <stdbool.h> |
#include <libnsfb.h> |
#include <libnsfb_plot.h> |
#include <libnsfb_event.h> |
#include <libnsfb_cursor.h> |
#include "utils/log.h" |
#include "desktop/browser.h" |
#include "framebuffer/gui.h" |
#include "framebuffer/fbtk.h" |
#include "framebuffer/image_data.h" |
#include "utils/log.h" |
#include <menuet/os.h> |
#include "widget.h" |
/* Vertical scroll widget */ |
static int |
vscroll_redraw(fbtk_widget_t *widget, fbtk_callback_info *cbi) |
{ |
LOG(("REDRAW SCROLL")); |
//__menuet__debug_out("REDRAW SCROLL"); |
int vscroll; |
int vpos; |
nsfb_bbox_t bbox; |
nsfb_bbox_t rect; |
LOG(("REDRAW SCROLL get rooot")); |
//__menuet__debug_out("REDRAW SCROLL get root"); |
fbtk_widget_t *root = fbtk_get_root_widget(widget); |
LOG(("REDRAW SCROLL get bbox")); |
//__menuet__debug_out("REDRAW SCROLL get bbox"); |
fbtk_get_bbox(widget, &bbox); |
LOG(("REDRAW SCROLL claim")); |
//__menuet__debug_out("REDRAW SCROLL claim"); |
nsfb_claim(root->u.root.fb, &bbox); |
rect = bbox; |
/* background */ |
//STUB |
nsfb_plot_rectangle_fill(root->u.root.fb, &rect, widget->bg); |
/* scroll well */ |
rect.x0 = bbox.x0 + 2; |
rect.y0 = bbox.y0 + 1; |
rect.x1 = bbox.x1 - 3; |
rect.y1 = bbox.y1 - 2; |
//STUB!!! |
nsfb_plot_rectangle_fill(root->u.root.fb, &rect, widget->fg); |
nsfb_plot_rectangle(root->u.root.fb, &rect, 1, 0xFF999999, false, false); |
LOG(("REDRAW SCROLL widg")); |
//__menuet__debug_out("REDRAW SCROLL widg"); |
/* scroll bar */ |
if ((widget->u.scroll.maximum - widget->u.scroll.minimum) > 0) { |
vscroll = ((widget->height - 4) * widget->u.scroll.thumb) / |
(widget->u.scroll.maximum - widget->u.scroll.minimum) ; |
vpos = ((widget->height - 4) * widget->u.scroll.position) / |
(widget->u.scroll.maximum - widget->u.scroll.minimum) ; |
} else { |
vscroll = (widget->height - 4); |
vpos = 0; |
} |
rect.x0 = bbox.x0 + 5; |
rect.y0 = bbox.y0 + 3 + vpos; |
rect.x1 = bbox.x0 + widget->width - 5; |
rect.y1 = bbox.y0 + vscroll + vpos; |
//STUB!!! |
nsfb_plot_rectangle_fill(root->u.root.fb, &rect, widget->bg); |
LOG(("REDRAW SCROLL upd")); |
//__menuet__debug_out("RED upd"); |
//STUB |
nsfb_update(root->u.root.fb, &bbox); //&bbox |
return 0; |
} |
static int |
vscroll_drag(fbtk_widget_t *widget, fbtk_callback_info *cbi) |
{ |
LOG(("REDRAG SCROLL")); |
//__menuet__debug_out("REDRAG SCROLL"); |
int newpos; |
fbtk_widget_t *scrollw = cbi->context; |
newpos = ((widget->u.scroll.drag_position + |
(cbi->y - widget->u.scroll.drag)) * |
(widget->u.scroll.maximum - widget->u.scroll.minimum)) / |
(widget->height - 4); |
if (newpos < scrollw->u.scroll.minimum) |
newpos = scrollw->u.scroll.minimum; |
if (newpos > (scrollw->u.scroll.maximum - scrollw->u.scroll.thumb )) |
newpos = (scrollw->u.scroll.maximum - scrollw->u.scroll.thumb); |
if (newpos == scrollw->u.scroll.position) |
return 0; |
return fbtk_post_callback(widget, FBTK_CBT_SCROLLY, newpos); |
} |
static int |
vscrollu_click(fbtk_widget_t *widget, fbtk_callback_info *cbi) |
{ |
LOG(("REDRAW Ck SCROLL")); |
//__menuet__debug_out("REDRAW Ck SCROLL"); |
int newpos; |
fbtk_widget_t *scrollw = cbi->context; |
if (cbi->event->type != NSFB_EVENT_KEY_DOWN) |
return 0; |
newpos = scrollw->u.scroll.position - scrollw->u.scroll.page; |
if (newpos < scrollw->u.scroll.minimum) |
newpos = scrollw->u.scroll.minimum; |
if (newpos == scrollw->u.scroll.position) |
return 0; |
return fbtk_post_callback(scrollw, FBTK_CBT_SCROLLY, newpos); |
} |
static int |
vscrolld_click(fbtk_widget_t *widget, fbtk_callback_info *cbi) |
{ |
LOG(("REDRAW SCROLL 2")); |
//__menuet__debug_out("REDRAW SCROLL 2"); |
int newpos; |
fbtk_widget_t *scrollw = cbi->context; |
if (cbi->event->type != NSFB_EVENT_KEY_DOWN) |
return 0; |
newpos = scrollw->u.scroll.position + scrollw->u.scroll.page; |
if (newpos > (scrollw->u.scroll.maximum - scrollw->u.scroll.thumb )) |
newpos = (scrollw->u.scroll.maximum - scrollw->u.scroll.thumb); |
if (newpos == scrollw->u.scroll.position) |
return 0; |
return fbtk_post_callback(scrollw, FBTK_CBT_SCROLLY, newpos); |
} |
static int |
vscrollarea_click(fbtk_widget_t *widget, fbtk_callback_info *cbi) |
{ |
LOG(("REDRAW SCROLL 3")); |
//__menuet__debug_out("REDRAW SCROLL 3"); |
int vscroll; |
int vpos; |
int newpos; |
int ret = 0; |
if (cbi->event->type != NSFB_EVENT_KEY_DOWN) { |
/* end all drags, just in case */ |
if (fbtk_set_handler(widget, FBTK_CBT_POINTERMOVE, NULL, NULL) != NULL) |
fbtk_tgrab_pointer(widget); |
return 0; |
} |
switch (cbi->event->value.keycode) { |
case NSFB_KEY_MOUSE_4: |
/* scroll up */ |
newpos = widget->u.scroll.position - widget->u.scroll.page; |
if (newpos < widget->u.scroll.minimum) |
newpos = widget->u.scroll.minimum; |
ret = fbtk_post_callback(cbi->context, FBTK_CBT_SCROLLY, newpos); |
break; |
case NSFB_KEY_MOUSE_5: |
/* scroll down */ |
newpos = widget->u.scroll.position + widget->u.scroll.page; |
if (newpos > widget->u.scroll.maximum) |
newpos = widget->u.scroll.maximum; |
ret = fbtk_post_callback(cbi->context, FBTK_CBT_SCROLLY, newpos); |
break; |
default: |
if ((widget->u.scroll.maximum - widget->u.scroll.minimum) > 0) { |
vscroll = ((widget->height - 4) * widget->u.scroll.thumb) / |
(widget->u.scroll.maximum - widget->u.scroll.minimum) ; |
vpos = ((widget->height - 4) * widget->u.scroll.position) / |
(widget->u.scroll.maximum - widget->u.scroll.minimum) ; |
} else { |
vscroll = (widget->height - 4); |
vpos = 0; |
} |
if (cbi->y < vpos) { |
/* above bar */ |
newpos = widget->u.scroll.position - widget->u.scroll.thumb; |
if (newpos < widget->u.scroll.minimum) |
newpos = widget->u.scroll.minimum; |
ret = fbtk_post_callback(cbi->context, FBTK_CBT_SCROLLY, newpos); |
} else if (cbi->y > (vpos + vscroll)) { |
/* below bar */ |
newpos = widget->u.scroll.position + widget->u.scroll.thumb; |
if (newpos > widget->u.scroll.maximum) |
newpos = widget->u.scroll.maximum; |
ret = fbtk_post_callback(cbi->context, FBTK_CBT_SCROLLY, newpos); |
} else { |
/* on bar - start drag */ |
widget->u.scroll.drag = cbi->y; |
widget->u.scroll.drag_position = vpos; |
fbtk_set_handler(widget, FBTK_CBT_POINTERMOVE, vscroll_drag, widget); |
fbtk_tgrab_pointer(widget); |
} |
} |
return ret; |
} |
/* exported function documented in fbtk.h */ |
fbtk_widget_t * |
fbtk_create_vscroll(fbtk_widget_t *parent, |
int x, |
int y, |
int width, |
int height, |
colour fg, |
colour bg, |
fbtk_callback callback, |
void *context) |
{ |
LOG(("REDRAW SCROLL 4")); |
//__menuet__debug_out("REDRAW SCROLL 4"); |
fbtk_widget_t *neww; |
neww = fbtk_widget_new(parent, |
FB_WIDGET_TYPE_VSCROLL, |
x, |
y + scrollu.height, |
width, |
height - scrollu.height - scrolld.height); |
neww->fg = fg; |
neww->bg = bg; |
neww->mapped = true; |
fbtk_set_handler(neww, FBTK_CBT_REDRAW, vscroll_redraw, NULL); |
fbtk_set_handler(neww, FBTK_CBT_CLICK, vscrollarea_click, neww); |
fbtk_set_handler(neww, FBTK_CBT_SCROLLY, callback, context); |
neww->u.scroll.btnul = fbtk_create_button(parent, |
x, |
y, |
width, |
scrollu.height, |
fg, |
&scrollu, |
vscrollu_click, |
neww); |
neww->u.scroll.btndr = fbtk_create_button(parent, |
x, |
y + height - scrolld.height, |
width, |
scrolld.height, |
fg, |
&scrolld, |
vscrolld_click, |
neww); |
return neww; |
} |
/* Horizontal scroll widget */ |
static int |
hscroll_redraw(fbtk_widget_t *widget, fbtk_callback_info *cbi) |
{ |
LOG(("REDRAW SCROLL 5")); |
//__menuet__debug_out("REDRAW SCROLL 5"); |
int hscroll; |
int hpos; |
nsfb_bbox_t bbox; |
nsfb_bbox_t rect; |
fbtk_widget_t *root = fbtk_get_root_widget(widget); |
fbtk_get_bbox(widget, &bbox); |
nsfb_claim(root->u.root.fb, &bbox); |
rect = bbox; |
/* background */ |
//STUB |
nsfb_plot_rectangle_fill(root->u.root.fb, &rect, widget->bg); |
/* scroll well */ |
rect.x0 = bbox.x0 + 1; |
rect.y0 = bbox.y0 + 2; |
rect.x1 = bbox.x1 - 2; |
rect.y1 = bbox.y1 - 3; |
//STUB |
nsfb_plot_rectangle_fill(root->u.root.fb, &rect, widget->fg); |
/* scroll well outline */ |
//STUB |
nsfb_plot_rectangle(root->u.root.fb, &rect, 1, 0xFF999999, false, false); |
if ((widget->u.scroll.maximum - widget->u.scroll.minimum) > 0) { |
hscroll = ((widget->width - 4) * widget->u.scroll.thumb) / |
(widget->u.scroll.maximum - widget->u.scroll.minimum) ; |
hpos = ((widget->width - 4) * widget->u.scroll.position) / |
(widget->u.scroll.maximum - widget->u.scroll.minimum) ; |
} else { |
hscroll = (widget->width - 4); |
hpos = 0; |
} |
LOG(("hscroll %d", hscroll)); |
rect.x0 = bbox.x0 + 3 + hpos; |
rect.y0 = bbox.y0 + 5; |
rect.x1 = bbox.x0 + hscroll + hpos; |
rect.y1 = bbox.y0 + widget->height - 5; |
//STUB |
nsfb_plot_rectangle_fill(root->u.root.fb, &rect, widget->bg); |
nsfb_update(root->u.root.fb, &bbox); |
return 0; |
} |
static int |
hscrolll_click(fbtk_widget_t *widget, fbtk_callback_info *cbi) |
{ |
LOG(("REDRAW SCROLL 6")); |
//__menuet__debug_out("REDRAW SCROLL 6"); |
int newpos; |
fbtk_widget_t *scrollw = cbi->context; |
if (cbi->event->type != NSFB_EVENT_KEY_DOWN) |
return 0; |
newpos = scrollw->u.scroll.position - scrollw->u.scroll.page; |
if (newpos < scrollw->u.scroll.minimum) |
newpos = scrollw->u.scroll.minimum; |
if (newpos == scrollw->u.scroll.position) { |
LOG(("horiz scroll was the same %d", newpos)); |
return 0; |
} |
return fbtk_post_callback(scrollw, FBTK_CBT_SCROLLX, newpos); |
} |
static int |
hscrollr_click(fbtk_widget_t *widget, fbtk_callback_info *cbi) |
{ |
LOG(("REDRAW SCROLL 7")); |
//__menuet__debug_out("REDRAW SCROLL 7"); |
int newpos; |
fbtk_widget_t *scrollw = cbi->context; |
if (cbi->event->type != NSFB_EVENT_KEY_DOWN) |
return 0; |
newpos = scrollw->u.scroll.position + scrollw->u.scroll.page; |
if (newpos > (scrollw->u.scroll.maximum - scrollw->u.scroll.thumb )) |
newpos = (scrollw->u.scroll.maximum - scrollw->u.scroll.thumb); |
if (newpos == scrollw->u.scroll.position) |
return 0; |
return fbtk_post_callback(scrollw, FBTK_CBT_SCROLLX, newpos); |
} |
static int |
hscroll_drag(fbtk_widget_t *widget, fbtk_callback_info *cbi) |
{ |
LOG(("REDRAW SCROLL 8")); |
//__menuet__debug_out("REDRAW SCROLL 8"); |
int newpos; |
fbtk_widget_t *scrollw = cbi->context; |
newpos = ((widget->u.scroll.drag_position + |
(cbi->x - widget->u.scroll.drag)) * |
(widget->u.scroll.maximum - widget->u.scroll.minimum)) / |
(widget->width - 4); |
if (newpos < scrollw->u.scroll.minimum) |
newpos = scrollw->u.scroll.minimum; |
if (newpos > (scrollw->u.scroll.maximum - scrollw->u.scroll.thumb )) |
newpos = (scrollw->u.scroll.maximum - scrollw->u.scroll.thumb); |
if (newpos == scrollw->u.scroll.position) |
return 0; |
return fbtk_post_callback(widget, FBTK_CBT_SCROLLX, newpos); |
} |
static int |
hscrollarea_click(fbtk_widget_t *widget, fbtk_callback_info *cbi) |
{ |
LOG(("REDRAW SCROLL 9")); |
//__menuet__debug_out("REDRAW SCROLL 9"); |
int hscroll; |
int hpos; |
int newpos; |
int ret = 0; |
if (cbi->event->type != NSFB_EVENT_KEY_DOWN) { |
/* end all drags, just in case */ |
if (fbtk_set_handler(widget, FBTK_CBT_POINTERMOVE, NULL, NULL) != NULL) |
fbtk_tgrab_pointer(widget); |
return 0; |
} |
if ((widget->u.scroll.maximum - widget->u.scroll.minimum) > 0) { |
hscroll = ((widget->width - 4) * widget->u.scroll.thumb) / |
(widget->u.scroll.maximum - widget->u.scroll.minimum) ; |
hpos = ((widget->width - 4) * widget->u.scroll.position) / |
(widget->u.scroll.maximum - widget->u.scroll.minimum) ; |
} else { |
hscroll = (widget->width - 4); |
hpos = 0; |
} |
if (cbi->x < hpos) { |
/* left of bar */ |
newpos = widget->u.scroll.position - widget->u.scroll.page; |
if (newpos < widget->u.scroll.minimum) |
newpos = widget->u.scroll.minimum; |
ret = fbtk_post_callback(cbi->context, FBTK_CBT_SCROLLX, newpos); |
} else if (cbi->x > (hpos + hscroll)) { |
/* right of bar */ |
newpos = widget->u.scroll.position + widget->u.scroll.page; |
if (newpos > widget->u.scroll.maximum) |
newpos = widget->u.scroll.maximum; |
ret = fbtk_post_callback(cbi->context, FBTK_CBT_SCROLLX, newpos); |
} else { |
/* on bar - start drag */ |
widget->u.scroll.drag = cbi->x; |
widget->u.scroll.drag_position = hpos; |
fbtk_set_handler(widget, FBTK_CBT_POINTERMOVE, hscroll_drag, widget); |
fbtk_tgrab_pointer(widget); |
} |
return ret; |
} |
/* exported function documented in fbtk.h */ |
fbtk_widget_t * |
fbtk_create_hscroll(fbtk_widget_t *parent, |
int x, |
int y, |
int width, |
int height, |
colour fg, |
colour bg, |
fbtk_callback callback, |
void *context) |
{ |
LOG(("REDRAW SCROLL 10")); |
//__menuet__debug_out("REDRAW SCROLL 10"); |
fbtk_widget_t *neww; |
neww = fbtk_widget_new(parent, |
FB_WIDGET_TYPE_HSCROLL, |
x + scrolll.width, |
y, |
width - scrolll.width - scrollr.width, |
height); |
neww->fg = fg; |
neww->bg = bg; |
neww->mapped = true; |
fbtk_set_handler(neww, FBTK_CBT_REDRAW, hscroll_redraw, NULL); |
fbtk_set_handler(neww, FBTK_CBT_CLICK, hscrollarea_click, neww); |
fbtk_set_handler(neww, FBTK_CBT_SCROLLX, callback, context); |
neww->u.scroll.btnul = fbtk_create_button(parent, |
x, |
y, |
scrolll.width, |
height, |
fg, |
&scrolll, |
hscrolll_click, |
neww); |
neww->u.scroll.btndr = fbtk_create_button(parent, |
x + width - scrollr.width, |
y, |
scrollr.width, |
height, |
fg, |
&scrollr, |
hscrollr_click, |
neww); |
return neww; |
} |
/* exported function documented in fbtk.h */ |
bool |
fbtk_set_scroll_parameters(fbtk_widget_t *widget, |
int min, |
int max, |
int thumb, |
int page) |
{ |
LOG(("REDRAW SCROLL 11")); |
//__menuet__debug_out("REDRAW SCROLL 11"); |
if (widget == NULL) |
return false; |
if ((widget->type != FB_WIDGET_TYPE_HSCROLL) && |
(widget->type != FB_WIDGET_TYPE_VSCROLL)) |
return false; |
widget->u.scroll.minimum = min; |
widget->u.scroll.maximum = max; |
widget->u.scroll.thumb = thumb; |
widget->u.scroll.page = page; |
if (widget->u.scroll.position > max) |
widget->u.scroll.position = max; |
if (widget->u.scroll.position < min) |
widget->u.scroll.position = min; |
fbtk_request_redraw(widget); |
return true; |
} |
/* exported function documented in fbtk.h */ |
bool |
fbtk_set_scroll_position(fbtk_widget_t *widget, int position) |
{ |
LOG(("REDRAW SCROLL 12")); |
//__menuet__debug_out("REDRAW SCROLL 12"); |
if (widget == NULL) |
return false; |
if ((widget->type != FB_WIDGET_TYPE_HSCROLL) && |
(widget->type != FB_WIDGET_TYPE_VSCROLL)) |
return false; |
if ((position < widget->u.scroll.minimum) || |
(position > widget->u.scroll.maximum)) |
return false; |
widget->u.scroll.position = position; |
fbtk_request_redraw(widget); |
return true; |
} |
/* |
* Local Variables: |
* c-basic-offset:8 |
* End: |
*/ |
/programs/network/netsurf/netsurf/framebuffer/fbtk/text.c |
---|
0,0 → 1,616 |
/* |
* Copyright 2010 Vincent Sanders <vince@simtec.co.uk> |
* |
* Framebuffer windowing toolkit scrollbar widgets. |
* |
* This file is part of NetSurf, http://www.netsurf-browser.org/ |
* |
* NetSurf is free software; you can redistribute it and/or modify |
* it under the terms of the GNU General Public License as published by |
* the Free Software Foundation; version 2 of the License. |
* |
* NetSurf is distributed in the hope that it will be useful, |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
* GNU General Public License for more details. |
* |
* You should have received a copy of the GNU General Public License |
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
*/ |
#include <stdbool.h> |
#include <stdlib.h> |
#include <string.h> |
#include <libnsfb.h> |
#include <libnsfb_plot.h> |
#include <libnsfb_plot_util.h> |
#include <libnsfb_event.h> |
#include "utils/log.h" |
#include "desktop/browser.h" |
#include "render/font.h" |
#include "framebuffer/gui.h" |
#include "framebuffer/fbtk.h" |
#include "framebuffer/font.h" |
#include "framebuffer/framebuffer.h" |
#include "framebuffer/image_data.h" |
#include "widget.h" |
//#define TEXT_WIDGET_BORDER 3 /**< The pixel border round a text widget. */ |
/* Lighten a colour by taking seven eights of each channel's intensity |
* and adding a full eighth |
*/ |
#define brighten_colour(c1) \ |
(((((7 * ((c1 >> 16) & 0xff)) >> 3) + 32) << 16) | \ |
((((7 * ((c1 >> 8) & 0xff)) >> 3) + 32) << 8) | \ |
((((7 * (c1 & 0xff)) >> 3) + 32) << 0)) |
/* 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, int *padding, |
plot_font_style_t *font_style) |
{ |
if (widget->u.text.outline) |
*padding = 1; |
else |
*padding = 0; |
#ifdef FB_USE_FREETYPE |
*padding += widget->height / 6; |
*font_height = widget->height - *padding - *padding; |
#else |
*font_height = font_regular.height; |
*padding = (widget->height - *padding - *font_height) / 2; |
#endif |
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. |
* |
* @param widget The widget to be redrawn. |
* @param cbi The callback parameters. |
* @return The callback result. |
*/ |
static int |
fb_redraw_text(fbtk_widget_t *widget, fbtk_callback_info *cbi ) |
{ |
nsfb_bbox_t bbox; |
nsfb_bbox_t rect; |
fbtk_widget_t *root; |
plot_font_style_t font_style; |
int caret_x, caret_y, caret_h; |
int fh; |
int padding; |
int scroll = 0; |
bool caret = false; |
fb_text_font_style(widget, &fh, &padding, &font_style); |
if (fbtk_get_caret(widget, &caret_x, &caret_y, &caret_h)) { |
caret = true; |
} |
root = fbtk_get_root_widget(widget); |
fbtk_get_bbox(widget, &bbox); |
rect = bbox; |
nsfb_claim(root->u.root.fb, &bbox); |
/* clear background */ |
if ((widget->bg & 0xFF000000) != 0) { |
/* transparent polygon filling isnt working so fake it */ |
nsfb_plot_rectangle_fill(root->u.root.fb, &bbox, widget->bg); |
} |
/* widget can have a single pixel outline border */ |
if (widget->u.text.outline) { |
rect.x1--; |
rect.y1--; |
nsfb_plot_rectangle(root->u.root.fb, &rect, 1, |
0x00000000, false, false); |
} |
if (widget->u.text.text != NULL) { |
int x = bbox.x0 + padding; |
int y = bbox.y0 + ((fh * 3 + 2) / 4) + padding; |
#ifdef FB_USE_FREETYPE |
/* Freetype renders text higher */ |
y += 1; |
#endif |
if (caret && widget->width - padding - padding < caret_x) { |
scroll = (widget->width - padding - padding) - caret_x; |
x += scroll; |
} |
/* Call the fb text plotting, baseline is 3/4 down the font */ |
fb_plotters.text(x, y, widget->u.text.text, |
widget->u.text.len, &font_style); |
} |
if (caret) { |
/* This widget has caret, so render it */ |
nsfb_t *nsfb = fbtk_get_nsfb(widget); |
nsfb_bbox_t line; |
nsfb_plot_pen_t pen; |
line.x0 = bbox.x0 + caret_x + scroll; |
line.y0 = bbox.y0 + caret_y; |
line.x1 = bbox.x0 + caret_x + scroll; |
line.y1 = bbox.y0 + 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(root->u.root.fb, &bbox); |
return 0; |
} |
/** Text button redraw callback. |
* |
* Called when a text widget requires redrawing. |
* |
* @param widget The widget to be redrawn. |
* @param cbi The callback parameters. |
* @return The callback result. |
*/ |
static int |
fb_redraw_text_button(fbtk_widget_t *widget, fbtk_callback_info *cbi ) |
{ |
nsfb_bbox_t bbox; |
nsfb_bbox_t rect; |
nsfb_bbox_t line; |
nsfb_plot_pen_t pen; |
plot_font_style_t font_style; |
int fh; |
int border; |
fbtk_widget_t *root = fbtk_get_root_widget(widget); |
fb_text_font_style(widget, &fh, &border, &font_style); |
pen.stroke_type = NFSB_PLOT_OPTYPE_SOLID; |
pen.stroke_width = 1; |
pen.stroke_colour = brighten_colour(widget->bg); |
fbtk_get_bbox(widget, &bbox); |
rect = bbox; |
rect.x1--; |
rect.y1--; |
nsfb_claim(root->u.root.fb, &bbox); |
/* clear background */ |
if ((widget->bg & 0xFF000000) != 0) { |
/* transparent polygon filling isnt working so fake it */ |
nsfb_plot_rectangle_fill(root->u.root.fb, &rect, widget->bg); |
} |
if (widget->u.text.outline) { |
line.x0 = rect.x0; |
line.y0 = rect.y0; |
line.x1 = rect.x0; |
line.y1 = rect.y1; |
nsfb_plot_line(root->u.root.fb, &line, &pen); |
line.x0 = rect.x0; |
line.y0 = rect.y0; |
line.x1 = rect.x1; |
line.y1 = rect.y0; |
nsfb_plot_line(root->u.root.fb, &line, &pen); |
pen.stroke_colour = darken_colour(widget->bg); |
line.x0 = rect.x0; |
line.y0 = rect.y1; |
line.x1 = rect.x1; |
line.y1 = rect.y1; |
nsfb_plot_line(root->u.root.fb, &line, &pen); |
line.x0 = rect.x1; |
line.y0 = rect.y0; |
line.x1 = rect.x1; |
line.y1 = rect.y1; |
nsfb_plot_line(root->u.root.fb, &line, &pen); |
} |
if (widget->u.text.text != NULL) { |
/* Call the fb text plotting, baseline is 3/4 down the font */ |
fb_plotters.text(bbox.x0 + border, |
bbox.y0 + ((fh * 3) / 4) + border, |
widget->u.text.text, |
widget->u.text.len, |
&font_style); |
} |
nsfb_update(root->u.root.fb, &bbox); |
return 0; |
} |
static void |
fb_text_input_remove_caret_cb(fbtk_widget_t *widget) |
{ |
int c_x, c_y, c_h; |
if (fbtk_get_caret(widget, &c_x, &c_y, &c_h)) { |
fbtk_request_redraw(widget); |
} |
} |
/** Routine called when text events occour in writeable widget. |
* |
* @param widget The widget reciving input events. |
* @param cbi The callback parameters. |
* @return The callback result. |
*/ |
static int |
text_input(fbtk_widget_t *widget, fbtk_callback_info *cbi) |
{ |
int value; |
static fbtk_modifier_type modifier = FBTK_MOD_CLEAR; |
char *temp; |
plot_font_style_t font_style; |
int fh; |
int border; |
bool caret_moved = false; |
fb_text_font_style(widget, &fh, &border, &font_style); |
if (cbi->event == NULL) { |
/* gain focus */ |
if (widget->u.text.text == NULL) |
widget->u.text.text = calloc(1,1); |
return 0; |
} |
value = cbi->event->value.keycode; |
if (cbi->event->type != NSFB_EVENT_KEY_DOWN) { |
switch (value) { |
case NSFB_KEY_RSHIFT: |
modifier &= ~FBTK_MOD_RSHIFT; |
break; |
case NSFB_KEY_LSHIFT: |
modifier &= ~FBTK_MOD_LSHIFT; |
break; |
case NSFB_KEY_RCTRL: |
modifier &= ~FBTK_MOD_RCTRL; |
break; |
case NSFB_KEY_LCTRL: |
modifier &= ~FBTK_MOD_LCTRL; |
break; |
default: |
break; |
} |
return 0; |
} |
switch (value) { |
case NSFB_KEY_BACKSPACE: |
if (widget->u.text.idx <= 0) |
break; |
memmove(widget->u.text.text + widget->u.text.idx - 1, |
widget->u.text.text + widget->u.text.idx, |
widget->u.text.len - widget->u.text.idx); |
widget->u.text.idx--; |
widget->u.text.len--; |
widget->u.text.text[widget->u.text.len] = 0; |
nsfont.font_width(&font_style, widget->u.text.text, |
widget->u.text.len, &widget->u.text.width); |
caret_moved = true; |
break; |
case NSFB_KEY_RETURN: |
widget->u.text.enter(widget->u.text.pw, widget->u.text.text); |
break; |
case NSFB_KEY_RIGHT: |
if (widget->u.text.idx < widget->u.text.len) { |
if (modifier == FBTK_MOD_CLEAR) |
widget->u.text.idx++; |
else |
widget->u.text.idx = widget->u.text.len; |
caret_moved = true; |
} |
break; |
case NSFB_KEY_LEFT: |
if (widget->u.text.idx > 0) { |
if (modifier == FBTK_MOD_CLEAR) |
widget->u.text.idx--; |
else |
widget->u.text.idx = 0; |
caret_moved = true; |
} |
break; |
case NSFB_KEY_PAGEUP: |
case NSFB_KEY_PAGEDOWN: |
case NSFB_KEY_UP: |
case NSFB_KEY_DOWN: |
/* Not handling any of these correctly yet, but avoid putting |
* charcters in the text widget when they're pressed. */ |
break; |
case NSFB_KEY_RSHIFT: |
modifier |= FBTK_MOD_RSHIFT; |
break; |
case NSFB_KEY_LSHIFT: |
modifier |= FBTK_MOD_LSHIFT; |
break; |
case NSFB_KEY_RCTRL: |
modifier |= FBTK_MOD_RCTRL; |
break; |
case NSFB_KEY_LCTRL: |
modifier |= FBTK_MOD_LCTRL; |
break; |
default: |
if (modifier & FBTK_MOD_LCTRL || modifier & FBTK_MOD_RCTRL) { |
/* CTRL pressed, don't enter any text */ |
if (value == NSFB_KEY_u) { |
/* CTRL+U: clear writable */ |
widget->u.text.idx = 0; |
widget->u.text.len = 0; |
widget->u.text.text[widget->u.text.len] = '\0'; |
widget->u.text.width = 0; |
caret_moved = true; |
} |
break; |
} |
/* allow for new character and null */ |
temp = realloc(widget->u.text.text, widget->u.text.len + 2); |
if (temp == NULL) { |
break; |
} |
widget->u.text.text = temp; |
memmove(widget->u.text.text + widget->u.text.idx + 1, |
widget->u.text.text + widget->u.text.idx, |
widget->u.text.len - widget->u.text.idx); |
widget->u.text.text[widget->u.text.idx] = |
fbtk_keycode_to_ucs4(value, modifier); |
widget->u.text.idx++; |
widget->u.text.len++; |
widget->u.text.text[widget->u.text.len] = '\0'; |
nsfont.font_width(&font_style, widget->u.text.text, |
widget->u.text.len, &widget->u.text.width); |
caret_moved = true; |
break; |
} |
if (caret_moved) { |
nsfont.font_width(&font_style, widget->u.text.text, |
widget->u.text.idx, &widget->u.text.idx_offset); |
fbtk_set_caret(widget, true, |
widget->u.text.idx_offset + border, |
border, |
widget->height - border - border, |
fb_text_input_remove_caret_cb); |
} |
fbtk_request_redraw(widget); |
return 0; |
} |
/** Routine called when click events occour in writeable widget. |
* |
* @param widget The widget reciving click events. |
* @param cbi The callback parameters. |
* @return The callback result. |
*/ |
static int |
text_input_click(fbtk_widget_t *widget, fbtk_callback_info *cbi) |
{ |
plot_font_style_t font_style; |
int fh; |
int border; |
size_t idx; |
fb_text_font_style(widget, &fh, &border, &font_style); |
widget->u.text.idx = widget->u.text.len; |
nsfont.font_position_in_string(&font_style, widget->u.text.text, |
widget->u.text.len, cbi->x - border, |
&idx, |
&widget->u.text.idx_offset); |
widget->u.text.idx = idx; |
fbtk_set_caret(widget, true, |
widget->u.text.idx_offset + border, |
border, |
widget->height - border - border, |
fb_text_input_remove_caret_cb); |
fbtk_request_redraw(widget); |
return 0; |
} |
/** Routine called when "stripped of focus" event occours for writeable widget. |
* |
* @param widget The widget reciving "stripped of focus" event. |
* @param cbi The callback parameters. |
* @return The callback result. |
*/ |
static int |
text_input_strip_focus(fbtk_widget_t *widget, fbtk_callback_info *cbi) |
{ |
fbtk_set_caret(widget, false, 0, 0, 0, NULL); |
return 0; |
} |
/* exported function documented in fbtk.h */ |
void |
fbtk_writable_text(fbtk_widget_t *widget, fbtk_enter_t enter, void *pw) |
{ |
widget->u.text.enter = enter; |
widget->u.text.pw = pw; |
fbtk_set_handler(widget, FBTK_CBT_INPUT, text_input, widget); |
} |
/* exported function documented in fbtk.h */ |
void |
fbtk_set_text(fbtk_widget_t *widget, const char *text) |
{ |
plot_font_style_t font_style; |
int c_x, c_y, c_h; |
int fh; |
int border; |
if ((widget == NULL) || (widget->type != FB_WIDGET_TYPE_TEXT)) |
return; |
if (widget->u.text.text != NULL) { |
if (strcmp(widget->u.text.text, text) == 0) |
return; /* text is being set to the same thing */ |
free(widget->u.text.text); |
} |
widget->u.text.text = strdup(text); |
widget->u.text.len = strlen(text); |
widget->u.text.idx = widget->u.text.len; |
fb_text_font_style(widget, &fh, &border, &font_style); |
nsfont.font_width(&font_style, widget->u.text.text, |
widget->u.text.len, &widget->u.text.width); |
nsfont.font_width(&font_style, widget->u.text.text, |
widget->u.text.idx, &widget->u.text.idx_offset); |
if (fbtk_get_caret(widget, &c_x, &c_y, &c_h)) { |
/* Widget has caret; move it to end of new string */ |
fbtk_set_caret(widget, true, |
widget->u.text.idx_offset + border, |
border, |
widget->height - border - border, |
fb_text_input_remove_caret_cb); |
} |
fbtk_request_redraw(widget); |
} |
/* exported function documented in fbtk.h */ |
fbtk_widget_t * |
fbtk_create_text(fbtk_widget_t *parent, |
int x, |
int y, |
int width, |
int height, |
colour bg, |
colour fg, |
bool outline) |
{ |
fbtk_widget_t *neww; |
neww = fbtk_widget_new(parent, FB_WIDGET_TYPE_TEXT, x, y, width, height); |
neww->fg = fg; |
neww->bg = bg; |
neww->mapped = true; |
neww->u.text.outline = outline; |
fbtk_set_handler(neww, FBTK_CBT_REDRAW, fb_redraw_text, NULL); |
return neww; |
} |
/* exported function documented in fbtk.h */ |
fbtk_widget_t * |
fbtk_create_writable_text(fbtk_widget_t *parent, |
int x, |
int y, |
int width, |
int height, |
colour bg, |
colour fg, |
bool outline, |
fbtk_enter_t enter, |
void *pw) |
{ |
fbtk_widget_t *neww; |
neww = fbtk_widget_new(parent, FB_WIDGET_TYPE_TEXT, x, y, width, height); |
neww->fg = fg; |
neww->bg = bg; |
neww->mapped = true; |
neww->u.text.outline = outline; |
neww->u.text.enter = enter; |
neww->u.text.pw = pw; |
fbtk_set_handler(neww, FBTK_CBT_REDRAW, fb_redraw_text, NULL); |
fbtk_set_handler(neww, FBTK_CBT_CLICK, text_input_click, pw); |
fbtk_set_handler(neww, FBTK_CBT_STRIP_FOCUS, text_input_strip_focus, NULL); |
fbtk_set_handler(neww, FBTK_CBT_INPUT, text_input, neww); |
return neww; |
} |
/* exported function documented in fbtk.h */ |
fbtk_widget_t * |
fbtk_create_text_button(fbtk_widget_t *parent, |
int x, |
int y, |
int width, |
int height, |
colour bg, |
colour fg, |
fbtk_callback click, |
void *pw) |
{ |
fbtk_widget_t *neww; |
neww = fbtk_widget_new(parent, FB_WIDGET_TYPE_TEXT, x, y, width, height); |
neww->fg = fg; |
neww->bg = bg; |
neww->mapped = true; |
neww->u.text.outline = true; |
fbtk_set_handler(neww, FBTK_CBT_REDRAW, fb_redraw_text_button, NULL); |
fbtk_set_handler(neww, FBTK_CBT_CLICK, click, pw); |
fbtk_set_handler(neww, FBTK_CBT_POINTERENTER, fbtk_set_ptr, &hand_image); |
return neww; |
} |
/* |
* Local Variables: |
* c-basic-offset:8 |
* End: |
*/ |
/programs/network/netsurf/netsurf/framebuffer/fbtk/user.c |
---|
0,0 → 1,64 |
/* |
* Copyright 2010 Vincent Sanders <vince@simtec.co.uk> |
* |
* Framebuffer windowing toolkit user widget. |
* |
* This file is part of NetSurf, http://www.netsurf-browser.org/ |
* |
* NetSurf is free software; you can redistribute it and/or modify |
* it under the terms of the GNU General Public License as published by |
* the Free Software Foundation; version 2 of the License. |
* |
* NetSurf is distributed in the hope that it will be useful, |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
* GNU General Public License for more details. |
* |
* You should have received a copy of the GNU General Public License |
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
*/ |
#include <stdlib.h> |
#include <stdbool.h> |
#include <libnsfb.h> |
#include "desktop/plotters.h" |
#include "framebuffer/gui.h" |
#include "framebuffer/fbtk.h" |
#include "widget.h" |
/* exported function documented in fbtk.h */ |
void * |
fbtk_get_userpw(fbtk_widget_t *widget) |
{ |
if ((widget == NULL) || |
(widget->type != FB_WIDGET_TYPE_USER)) |
return NULL; |
return widget->u.user.pw; |
} |
/* exported function documented in fbtk.h */ |
fbtk_widget_t * |
fbtk_create_user(fbtk_widget_t *parent, |
int x, |
int y, |
int width, |
int height, |
void *pw) |
{ |
fbtk_widget_t *neww; |
neww = fbtk_widget_new(parent, FB_WIDGET_TYPE_USER, x, y, width, height); |
neww->u.user.pw = pw; |
neww->mapped = true; |
return neww; |
} |
/* |
* Local Variables: |
* c-basic-offset:8 |
* End: |
*/ |
/programs/network/netsurf/netsurf/framebuffer/fbtk/widget.h |
---|
0,0 → 1,259 |
/* |
* Copyright 2010 Vincent Sanders <vince@simtec.co.uk> |
* |
* This file is part of NetSurf, http://www.netsurf-browser.org/ |
* |
* NetSurf is free software; you can redistribute it and/or modify |
* it under the terms of the GNU General Public License as published by |
* the Free Software Foundation; version 2 of the License. |
* |
* NetSurf is distributed in the hope that it will be useful, |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
* GNU General Public License for more details. |
* |
* You should have received a copy of the GNU General Public License |
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
*/ |
#ifndef NETSURF_FB_FBTK_WIDGET_H |
#define NETSURF_FB_FBTK_WIDGET_H |
#include <stdbool.h> |
enum fbtk_widgettype_e { |
FB_WIDGET_TYPE_ROOT = 0, |
FB_WIDGET_TYPE_WINDOW, |
FB_WIDGET_TYPE_BITMAP, |
FB_WIDGET_TYPE_FILL, |
FB_WIDGET_TYPE_TEXT, |
FB_WIDGET_TYPE_HSCROLL, |
FB_WIDGET_TYPE_VSCROLL, |
FB_WIDGET_TYPE_USER, |
}; |
/** Widget description. |
* |
* A widget is an entry in a tree structure which represents a |
* rectangular area with co-ordinates relative to its parent widget. |
* This area has a distinct set of callback operations for handling |
* events which occour within its boundries. A widget may have an |
* arbitrary number of child widgets. The order within the tree |
* determines a widgets z order. |
* |
* --- |
* A |
* | |
* +----------+ |
* +--->| Button 3 | |
* | +----------+ |
* | | A |
* | V | |
* | +----------+ |
* | | Button 2 | |
* | +----------+ |
* | | A |
* | V | |
* | +----------+ |
* | | Button 1 | |
* | +----------+ |
* | | A |
* | V | |
* --- | +----------+ |
* A | +->| Filled | |
* | | | +----------+ |
* +----------+ | | | |
* +---->| |-+ | V |
* | | Window 1 | | --- --- |
* | | |---+ A |
* | +----------+ | |
* | | A +----------+ --- |
* | | | +--->| Button 2 | A |
* | | | | +----------+ | |
* | | | | | A +-------------+ |
* | | | | | | +--->| Button Up | |
* | | | | | | | +-------------+ |
* | | | | | | | | A |
* | | | | | | | V | |
* | | | | | | | +-------------+ |
* | | | | | | | | Button Down | |
* | | | | | | | +-------------+ |
* | | | | | | | | A |
* | | | | | | | V | |
* | | | | | | | +-------------+ |
* | | | | | | | +->| Scroller | |
* | | | | V | | | +-------------+ |
* | | | | +----------+ | | | |
* | | | | | |-+ | V |
* | | | | | V Scroll | | --- |
* | | | | | |---+ |
* | | | | +----------+ |
* | | | | | A |
* | | | | V | |
* | | | | +----------+ |
* | | | | +->| Button 1 | |
* | | | | | +----------+ |
* | +----------+ | | | |
* | | |-+ | V |
* | | Window 2 | | --- |
* | | |---+ |
* | +----------+ |
* | | A |
* | V | |
* | +------------+ |
* --- | | Background | |
* A | +->| Bitmap | |
* | | | +------------+ |
* +------+ | | | |
* | |-+ | V |
* | Root | | --- |
* | |---+ |
* +------+ |
* | |
* V |
* --- |
* |
* Every widget is contained within this generic wrapper. The |
* integrated union provides for data specific to a widget type. |
*/ |
struct fbtk_widget_s { |
struct fbtk_widget_s *next; /* next lower z ordered widget in tree */ |
struct fbtk_widget_s *prev; /* next higher z ordered widget in tree */ |
struct fbtk_widget_s *parent; /* parent widget */ |
struct fbtk_widget_s *first_child; /* first child widget */ |
struct fbtk_widget_s *last_child; /* last child widget */ |
/* flags */ |
bool mapped; /**< The widget is mapped/visible . */ |
/* Generic properties */ |
int x; |
int y; |
int width; |
int height; |
colour bg; |
colour fg; |
/* event callback handlers */ |
fbtk_callback callback[FBTK_CBT_END]; |
void *callback_context[FBTK_CBT_END]; |
/* widget redraw */ |
struct { |
bool child; /* A child of this widget requires redrawing */ |
bool needed; /* the widget requires redrawing */ |
int x; |
int y; |
int width; |
int height; |
} redraw; |
enum fbtk_widgettype_e type; /**< The type of the widget */ |
union { |
/* toolkit base handle */ |
struct { |
nsfb_t *fb; |
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; |
void (*remove_cb)(fbtk_widget_t *widget); |
} caret; |
} root; |
/* bitmap */ |
struct { |
struct fbtk_bitmap *bitmap; |
} bitmap; |
/* text */ |
struct { |
char* text; |
bool outline; |
fbtk_enter_t enter; |
void *pw; |
int idx; /* caret pos in text */ |
int len; /* text length */ |
int width; /* text width in px */ |
int idx_offset; /* caret pos in pixels */ |
} text; |
/* application driven widget */ |
struct { |
void *pw; /* private data for user widget */ |
} user; |
struct { |
int minimum; /* lowest value of scrollbar */ |
int maximum; /* highest value of scrollbar */ |
int thumb; /* size of bar representing a page */ |
int page; /* amount to page document */ |
int position; /* position of bar */ |
int drag; /* offset to start of drag */ |
int drag_position; /* indicator bar pos at drag start */ |
struct fbtk_widget_s *btnul; /* scroll button up/left */ |
struct fbtk_widget_s *btndr; /* scroll button down/right*/ |
} scroll; |
} u; |
}; |
/* These functions are not considered part of the public API but are |
* not static as they are used by the higher level widget provision |
* routines |
*/ |
/** creates a new widget and insert it into to hierachy. |
* |
* The widget is set to defaults of false, 0 or NULL. |
* |
* @param parent The parent widget. The new widget will be added with |
* the shallowest z order relative to its siblings. |
* @param type The type of the widget. |
* @param x The x co-ordinate relative to the parent widget. |
* @param y The y co-ordinate relative to the parent widget. |
* @param width the widgets width. This will be clipped to the parent, if |
* the value is 0 the largest extent which can fit within the parent |
* is used, if the value is negative the largest value that will fit |
* within the parent less the value given will be used. |
* @param height the widgets width. This will be clipped to the parent, if |
* the value is 0 the largest extent which can fit within the parent |
* is used, if the value is negative the largest value that will fit |
* within the parent less the value given will be used. |
*/ |
fbtk_widget_t *fbtk_widget_new(fbtk_widget_t *parent, enum fbtk_widgettype_e type, int x, int y, int width, int height); |
/** find the root widget from any widget in the toolkit hierarchy. |
* |
* @param widget Any widget. |
* @return The root widget or NULL if \a widget was not valid. |
*/ |
fbtk_widget_t *fbtk_get_root_widget(fbtk_widget_t *widget); |
/** set pointer to bitmap in context. |
* |
* widget helper callback to set cursor image to the bitmap passed in |
* the callbacks private data. |
*/ |
int fbtk_set_ptr(fbtk_widget_t *widget, fbtk_callback_info *cbi); |
#endif |
/* |
* Local Variables: |
* c-basic-offset:8 |
* End: |
*/ |
/programs/network/netsurf/netsurf/framebuffer/fbtk/window.c |
---|
0,0 → 1,98 |
/* |
* Copyright 2010 Vincent Sanders <vince@simtec.co.uk> |
* |
* Framebuffer windowing toolkit window widget. |
* |
* This file is part of NetSurf, http://www.netsurf-browser.org/ |
* |
* NetSurf is free software; you can redistribute it and/or modify |
* it under the terms of the GNU General Public License as published by |
* the Free Software Foundation; version 2 of the License. |
* |
* NetSurf is distributed in the hope that it will be useful, |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
* GNU General Public License for more details. |
* |
* You should have received a copy of the GNU General Public License |
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
*/ |
#include <stdbool.h> |
#include <stdlib.h> |
#include <libnsfb.h> |
#include <libnsfb_plot.h> |
#include "desktop/browser.h" |
#include "framebuffer/gui.h" |
#include "framebuffer/fbtk.h" |
#include "utils/log.h" |
#include "widget.h" |
/** Window redraw callback. |
* |
* Called when a window requires redrawing. |
* |
* @param widget The widget to be redrawn. |
* @param cbi The callback parameters. |
* @return The callback result. |
*/ |
static int |
fb_redraw_window(fbtk_widget_t *widget, fbtk_callback_info *cbi) |
{ |
nsfb_bbox_t bbox; |
nsfb_t *nsfb; |
if ((widget->bg & 0xFF000000) == 0) |
return 0; |
nsfb = fbtk_get_nsfb(widget); |
fbtk_get_bbox(widget, &bbox); |
nsfb_claim(nsfb, &bbox); |
nsfb_plot_rectangle_fill(nsfb, &bbox, widget->bg); |
nsfb_update(nsfb, &bbox); |
return 0; |
} |
/* exported function documented in fbtk.h */ |
fbtk_widget_t * |
fbtk_create_window(fbtk_widget_t *parent, |
int x, |
int y, |
int width, |
int height, |
colour bg) |
{ |
LOG(("FBTK new window")); |
fbtk_widget_t *neww; |
if (parent == NULL) |
{LOG(("FBTK no parent window"));return NULL;} |
LOG(("FBTK new widget")); |
neww = fbtk_widget_new(parent, FB_WIDGET_TYPE_WINDOW, x, y, width, height); |
LOG(("FBTK set bg widget")); |
neww->bg = bg; |
LOG(("FBTK set handler")); |
fbtk_set_handler(neww, FBTK_CBT_REDRAW, fb_redraw_window, NULL); |
return neww; |
} |
/* |
* Local Variables: |
* c-basic-offset:8 |
* End: |
*/ |