예제 #1
0
파일: fbtk.c 프로젝트: arczi84/NetSurf-68k
/* 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;
	}
}
예제 #2
0
파일: event.c 프로젝트: arczi84/NetSurf-68k
/* 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);
}
예제 #3
0
/* 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;
}
예제 #4
0
파일: fbtk.c 프로젝트: arczi84/NetSurf-68k
/* 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;
			}
		}
	}
}
예제 #5
0
/* 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);
}
예제 #6
0
/* 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;
}
예제 #7
0
static int
hscroll_redraw(fbtk_widget_t *widget, fbtk_callback_info *cbi)
{
	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 */
	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;
	nsfb_plot_rectangle_fill(root->u.root.fb, &rect, widget->fg);

	/* scroll well outline */
	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;

	nsfb_plot_rectangle_fill(root->u.root.fb, &rect, widget->bg);

	nsfb_update(root->u.root.fb, &bbox);

	return 0;
}
예제 #8
0
/* 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;
}
예제 #9
0
파일: event.c 프로젝트: arczi84/NetSurf-68k
/* 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);
}
예제 #10
0
파일: event.c 프로젝트: arczi84/NetSurf-68k
/* 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;
}
예제 #11
0
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;
    }
}
예제 #12
0
파일: text.c 프로젝트: pcwalton/NetSurf
/** 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);

	if (widget->height < 20) {
		border = 0;
	} else {
		border = (widget->height * 10) / 90;
	}

	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);
		border++;
	}

	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;

		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,
		     widget->width, widget->height, fh, border));
		/* Call the fb text plotting, baseline is 3/4 down the
		 * font, somewhere along the way the co-ordinate
		 * system for the baseline is to the "higher value
		 * pixel co-ordinate" due to this the + 1 is neccessary.
		 */
		fb_plotters.text(bbox.x0 + border,
			  bbox.y0 + (((fh * 3) + 3)/4) + border + 1,
			  widget->u.text.text,
			  strlen(widget->u.text.text),
			  &font_style);
	}

	nsfb_update(root->u.root.fb, &bbox);

	return 0;
}
예제 #13
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;
}
예제 #14
0
/** 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;
}
예제 #15
0
파일: event.c 프로젝트: arczi84/NetSurf-68k
/* 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;

		case NSFB_EVENT_RESIZE:
			/* Try to resize framebuffer */
			gui_resize(root,
					event->value.resize.w,
					event->value.resize.h);
			break;

		default:
			break;
		}
	} while (event->type == NSFB_EVENT_MOVE_RELATIVE ||
			event->type == NSFB_EVENT_MOVE_ABSOLUTE);
	return unused;
}
예제 #16
0
파일: event.c 프로젝트: arczi84/NetSurf-68k
/* 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);

}
예제 #17
0
파일: text.c 프로젝트: pcwalton/NetSurf
/** 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 fh;
	int padding;

	padding = (widget->height * FBTK_WIDGET_PADDING) / 200;

	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);
		padding++;
	}

	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;

		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));
		/* Call the fb text plotting, baseline is 3/4 down the
		 * font, somewhere along the way the co-ordinate
		 * system for the baseline is to the "higher value
		 * pixel co-ordinate" due to this the + 1 is neccessary.
		 */
		fb_plotters.text(bbox.x0 + padding,
			  bbox.y0 + (((fh * 3) + 3)/4) + padding + 1,
			  widget->u.text.text,
			  strlen(widget->u.text.text),
			  &font_style);
	}

	nsfb_update(root->u.root.fb, &bbox);

	return 0;
}