From 02ab2db00f3ccd9e9e912877122fe32d8369e5e1 Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Mon, 4 Oct 2010 15:50:39 +0000 Subject: Add flexible toolbar support and docuemnt it svn path=/trunk/netsurf/; revision=10862 --- Docs/BUILDING-Framebuffer | 17 +- Docs/USING-Framebuffer | 181 +++++++++++++++++++++ framebuffer/gui.c | 389 ++++++++++++++++++++++++++++++++-------------- framebuffer/options.h | 5 +- 4 files changed, 467 insertions(+), 125 deletions(-) create mode 100644 Docs/USING-Framebuffer diff --git a/Docs/BUILDING-Framebuffer b/Docs/BUILDING-Framebuffer index 70a1d7db5..b6583df71 100644 --- a/Docs/BUILDING-Framebuffer +++ b/Docs/BUILDING-Framebuffer @@ -88,8 +88,9 @@ The font system is configured at runtime by several options. The fb_font_monochrome option causes the renderer to use monochrome - glyph rendering which is faster but less visually appealing. The - remaining seven options control the files to be used for font faces. + glyph rendering which is faster to plot but slower to render and + much less visually appealing. The remaining seven options control + the files to be used for font faces. fb_face_sans_serif - The sans serif face fb_face_sans_serif_bold - The bold sans serif face @@ -160,17 +161,17 @@ Index: framebuffer/font_freetype.c using the NetSurf Framebuffer library (libnsfb). This library provides an abstraction layer to input and output devices. - The frontend used by libnsfb is selected by using the -fe switch to - netsurf when executed. A frontend in this context is simply the - combination of input and output devices. + The surface used by libnsfb is selected by using the -f switch to + NetSurf when executed. A surface in this context is simply the + combination of input and output devices. - A frontend output device may be any linearly mapped area of + A surface output device may be any linearly mapped area of memory. The framebuffer may be treated as values at 32, 16 or 8 bits per pixel. The input device is typically selected to complement the - output device and is completely specific to the frontend. + output device and is completely specific to the surface. There are several configuration options which may influence the - framebuffer frontends. These are: + framebuffer surfaces. These are: fb_refresh - The refresh rate (for physical displays) fb_depth - The depth (in bits per pixel) of the framebuffer diff --git a/Docs/USING-Framebuffer b/Docs/USING-Framebuffer new file mode 100644 index 000000000..e63d47ae2 --- /dev/null +++ b/Docs/USING-Framebuffer @@ -0,0 +1,181 @@ +-------------------------------------------------------------------------------- + Usage Instructions for Framebuffer NetSurf 2nd October 2010 +-------------------------------------------------------------------------------- + + This document provides usage instructions for the Framebuffer version of + NetSurf. + + Framebuffer NetSurf has been tested on Ubuntu and Debian. + +Overview +======== + + What it is + ---------- + + The NetSurf framebuffer front end is primarily intended for kiosk + and embedded applications where there is insufficient Operating + System support for a full graphical windowing environment. + + The framebuffer frontend features: + + * A trivial occluded rectangle window management toolkit + + * Font handling system using either: + - A trivial internal monochrome bitmap glyph set. + - An interface to fully anti-aliased glyphs using libfreetype 2 + + * Uses libnsfb to provide transparent support for: + - Numerous surface providers allowing usage on Linux, X, SDL, VNC + and any mapped linear memory region. + - Surface depths of 8, 16, 24 and 32bpp + - Optimised software plotters for lines, rectangles, polygons, + arbitrary ellipses (including circles), cubic and quadratic + splines, font glyphs and 32bpp RGBA bitmaps. + - Abstracted input handling. + + What it is not + -------------- + + The framebuffer frontend is not a replacement for full native + ports. It lacks functionality and flexibility compared to such + implementations. + + Limitations include: + - Single window interface. + - No tabbed interface. + - Expects to control the entire plotting surface. + - No ability to re-size a surface after initialisation. + - Inflexible input character mapping. + - Limited history view. + + In addition it should be noted support for some libnsfb surfaces has + been implemented purely for debugging functionality (SDL + especially) and is not intended to replace native surface + handlers. + + If a high level windowing system is available then a native NetSurf + frontend is almost certainly a better choice than attempting to use + the framebuffer frontend. + + If there is a graphical environment which supports GTK then using + the GTK frontend is a vastly superior choice. The framebuffer + frontend will appear exceptionally limited on such capable systems. + + +Configuring +=========== + + Several resources are set at *compile* time and are not changeable at + run time such as the icon bitmaps, the font system to use and what + default surface to use. Refer to the BUILDING-Framebuffer document + for details. + + Toolkit Options + --------------- + + The trivial toolkit has some configuration parameters allowing the + user to alter specific aspects of the UI. All the sizes are in + surface pixels however that is mapped. + + fb_furniture_size + This is the size allowed for the scroll bar elements. + + fb_toolbar_size + The height of the toolbar. + + fb_toolbar_layout + The layout of the toolbar, layout uses a string to define buttons + type and position each character adds an element to the toolbar: + + b - back + l - local history + f - forward + s - stop + r - refresh + u - url bar expands to fit remaining space + t - throbber/activity indicator + c - close the current window + + The default layout is "blfsrut" there should be no more than a + single url bar entry. If the option is set to the empty string (no + spaces permitted) the toolbar is disabled altogether. + + fb_osk + Whether the on screen keyboard should be enabled for input. + + + Framebuffer Surface + ------------------- + + There are four command line switches which override compiled in + defaults these are: + + -f + Selects a surface handler to pass to libnsfb instead of the + default. (e.g. x, sdl, mem, linux) + + -b + Selects the pixel depth to pass to libnsfb instead of the + compiled in default. (one of 8, 16, 24, 32) + + -w + Selects the surface width to pass to libnsfb instead of the + compiled in default. + + -h + Selects the surface height to pass to libnsfb instead of the + compiled in default. + + As with any NetSurf frontend run-time configuration is read from a + "Choices-fb" file. This file is a simple key:value list. In addition + to the standard values supported by the NetSurf core there are a + number of values to control specific aspects of the framebuffer + version. + + The libnsfb surface parameters are controlled with: + + fb_refresh - The refresh rate (for physical displays) + fb_depth - The depth (in bits per pixel) of the surface + fb_device - The path to the device (for physical displays) + fb_input_devpath - The path to the input devices (for linux input layer) + fb_input_glob - The input device selection glob (for linux input layer) + window_width - The width of the framebuffer + window_height - The height of the framebuffer + + The defaults are for 800 by 600 pixels at 16bpp and 70Hz refresh rate. + + The documentation of libnsfb should be consulted for further + information about supported surfaces and their configuration. + + Fonts + ----- + + If the compile time option is set to use the freetype font system + then several configuration options are available. If the simple + bitmap glyphs are used none of these options apply. + + The font glyphs are, by default, rendered as 256 level transparency + which gives excellent visual results even on small font sizes. + + The default font is the Vera truetype font set. The default path they + are sourced from is /usr/share/fonts/truetype/ttf-bitstream-vera/ . + + The font selection may be changed by placing truetype font files + in the resources path. The resource files will be the generic names + sans_serif.ttf, sans_serif_bold.ttf etc. The selection may also be + overridden by setting options. + + The font system is configured at run-time by several options. The + fb_font_monochrome option causes the renderer to use monochrome + glyph rendering which is faster to plot but slower to render and + much less visually appealing. The remaining seven options control + the files to be used for font faces. + + fb_face_sans_serif - The sans serif face + fb_face_sans_serif_bold - The bold sans serif face + fb_face_sans_serif_italic - The italic sans serif face + fb_face_sans_serif_italic_bold - The bold italic sans serif face. + fb_face_monospace - The monospaced font + fb_face_serif - The serif font + fb_serif_bold - The bold serif font diff --git a/framebuffer/gui.c b/framebuffer/gui.c index 078c9e458..2d0598bc3 100644 --- a/framebuffer/gui.c +++ b/framebuffer/gui.c @@ -59,6 +59,8 @@ #include "desktop/history_core.h" #include "content/fetch.h" +#define NSFB_TOOLBAR_DEFAULT_LAYOUT "blfsrut" + char *default_stylesheet_url; char *quirks_stylesheet_url; char *adblock_stylesheet_url; @@ -836,6 +838,16 @@ fb_osk_click(fbtk_widget_t *widget, fbtk_callback_info *cbi) return 0; } +/* close browser window icon click routine */ +static int +fb_close_click(fbtk_widget_t *widget, fbtk_callback_info *cbi) +{ + if (cbi->event->type != NSFB_EVENT_KEY_DOWN) + return 0; + + netsurf_quit = true; + return 0; +} static int fb_scroll_callback(fbtk_widget_t *widget, fbtk_callback_info *cbi) @@ -893,121 +905,283 @@ fb_localhistory_btn_clik(fbtk_widget_t *widget, fbtk_callback_info *cbi) } - -static void -create_toolbar(struct gui_window *gw, int toolbar_height) +/** Create a toolbar window and populate it with buttons. + * + * The toolbar layout uses a character to define buttons type and position: + * b - back + * l - local history + * f - forward + * s - stop + * r - refresh + * u - url bar expands to fit remaining space + * t - throbber/activity indicator + * c - close the current window + * + * The default layout is "blfsrut" there should be no more than a + * single url bar entry or behaviour will be undefined. + * + * @param gw Parent window + * @param toolbar_height The height in pixels of the toolbar + * @param padding The padding in pixels round each element of the toolbar + * @param frame_col Frame colour. + * @param toolbar_layout A string defining which buttons and controls + * should be added to the toolbar. May be empty + * string to disable the bar.. + * + */ +static fbtk_widget_t * +create_toolbar(struct gui_window *gw, + int toolbar_height, + int padding, + colour frame_col, + const char *toolbar_layout) { fbtk_widget_t *toolbar; fbtk_widget_t *widget; - int url_bar_height = 0; - int xpos = 0; - int spacing_width = 0; - - spacing_width = 2; - - xpos = spacing_width; - - url_bar_height = toolbar_height - 6; - - toolbar = fbtk_create_window(gw->window, 0, 0, 0, toolbar_height, FB_FRAME_COLOUR); - fbtk_set_handler(toolbar, FBTK_CBT_POINTERENTER, set_ptr_default_move, NULL); - - /* back button */ - gw->back = fbtk_create_button(toolbar, xpos, spacing_width, left_arrow.width, -spacing_width, FB_FRAME_COLOUR, &left_arrow, fb_leftarrow_click, gw); - xpos += left_arrow.width + spacing_width; - - /* history window */ - widget = fbtk_create_button(toolbar, - xpos, - spacing_width, - history_image.width, - -spacing_width, - FB_FRAME_COLOUR, - &history_image, - fb_localhistory_btn_clik, - gw); - xpos += fbtk_get_width(widget) + spacing_width; - - /* forward button */ - gw->forward = fbtk_create_button(toolbar, - xpos, - spacing_width, - right_arrow.width, - -spacing_width, - FB_FRAME_COLOUR, - &right_arrow, - fb_rightarrow_click, - gw); - xpos += right_arrow.width + spacing_width; - - /* stop button */ - widget = fbtk_create_button(toolbar, - xpos, - spacing_width, - stop_image.width, - -spacing_width, - FB_FRAME_COLOUR, - &stop_image, - fb_stop_click, - gw->bw); - xpos += stop_image.width + spacing_width; - - /* reload button */ - widget = fbtk_create_button(toolbar, - xpos, - spacing_width, - reload.width, - -spacing_width, - FB_FRAME_COLOUR, - &reload, - fb_reload_click, - gw->bw); - xpos += reload.width + spacing_width; - - /* url widget */ - xpos += spacing_width; /* extra spacing for url bar */ - gw->url = fbtk_create_writable_text(toolbar, - xpos, - spacing_width, - -(2 * spacing_width + throbber0.width), - -spacing_width, - FB_COLOUR_WHITE, - FB_COLOUR_BLACK, - true, - fb_url_enter, - gw->bw); - fbtk_set_handler(gw->url, FBTK_CBT_POINTERENTER, fb_url_move, gw->bw); - xpos += fbtk_get_width(gw->url) + spacing_width; - - /* throbber */ - gw->throbber = fbtk_create_bitmap(toolbar, - xpos, - spacing_width, - throbber0.width, - -spacing_width, - FB_FRAME_COLOUR, &throbber0); + + int xpos; /* The position of the next widget. */ + int xlhs; /* extent of the left hand side widgets */ + int xdir = 1; /* the direction of movement + or - 1 */ + const char *itmtype; /* type of the next item */ + + if (toolbar_layout == NULL) { + toolbar_layout = NSFB_TOOLBAR_DEFAULT_LAYOUT; + } + + LOG(("Using toolbar layout %s", toolbar_layout)); + + itmtype = toolbar_layout; + + if (*itmtype == 0) { + return NULL; + } + + toolbar = fbtk_create_window(gw->window, 0, 0, 0, + toolbar_height, + frame_col); + + if (toolbar == NULL) { + return NULL; + } + + fbtk_set_handler(toolbar, + FBTK_CBT_POINTERENTER, + set_ptr_default_move, + NULL); + + + xpos = padding; + + /* loop proceeds creating widget on the left hand side until + * it runs out of layout or encounters a url bar declaration + * wherupon it works backwards from the end of the layout + * untill the space left is for the url bar + */ + while ((itmtype >= toolbar_layout) && + (*itmtype != 0) && + (xdir !=0)) { + + LOG(("toolbar adding %c", *itmtype)); + + + switch (*itmtype) { + + case 'b': /* back */ + widget = fbtk_create_button(toolbar, + (xdir == 1) ? xpos : + xpos - left_arrow.width, + padding, + left_arrow.width, + -padding, + frame_col, + &left_arrow, + fb_leftarrow_click, + gw); + gw->back = widget; /* keep reference */ + break; + + case 'l': /* local history */ + widget = fbtk_create_button(toolbar, + (xdir == 1) ? xpos : + xpos - history_image.width, + padding, + history_image.width, + -padding, + frame_col, + &history_image, + fb_localhistory_btn_clik, + gw); + break; + + case 'f': /* forward */ + widget = fbtk_create_button(toolbar, + (xdir == 1)?xpos : + xpos - right_arrow.width, + padding, + right_arrow.width, + -padding, + frame_col, + &right_arrow, + fb_rightarrow_click, + gw); + gw->forward = widget; + break; + + case 'c': /* close the current window */ + widget = fbtk_create_button(toolbar, + (xdir == 1)?xpos : + xpos - stop_image_g.width, + padding, + stop_image_g.width, + -padding, + frame_col, + &stop_image_g, + fb_close_click, + gw->bw); + break; + + case 's': /* stop */ + widget = fbtk_create_button(toolbar, + (xdir == 1)?xpos : + xpos - stop_image.width, + padding, + stop_image.width, + -padding, + frame_col, + &stop_image, + fb_stop_click, + gw->bw); + break; + + case 'r': /* reload */ + widget = fbtk_create_button(toolbar, + (xdir == 1)?xpos : + xpos - reload.width, + padding, + reload.width, + -padding, + frame_col, + &reload, + fb_reload_click, + gw->bw); + break; + + case 't': /* throbber/activity indicator */ + widget = fbtk_create_bitmap(toolbar, + (xdir == 1)?xpos : + xpos - throbber0.width, + padding, + throbber0.width, + -padding, + frame_col, + &throbber0); + gw->throbber = widget; + break; + + + case 'u': /* url bar*/ + if (xdir == -1) { + /* met the u going backwards add url + * now we know available extent + */ + + widget = fbtk_create_writable_text(toolbar, + xlhs, + padding, + xpos - xlhs, + -padding, + FB_COLOUR_WHITE, + FB_COLOUR_BLACK, + true, + fb_url_enter, + gw->bw); + + fbtk_set_handler(widget, + FBTK_CBT_POINTERENTER, + fb_url_move, gw->bw); + + gw->url = widget; /* keep reference */ + + /* toolbar is complete */ + xdir = 0; + break; + } + /* met url going forwards, note position and + * reverse direction + */ + itmtype = toolbar_layout + strlen(toolbar_layout); + xdir = -1; + xlhs = xpos; + xpos = (2 * fbtk_get_width(toolbar)); + widget = toolbar; + break; + + default: + xdir = 0; + LOG(("Unknown element %c in toolbar layout", *itmtype)); + break; + + } + + xpos += (xdir * (fbtk_get_width(widget) + padding)); + + LOG(("xpos is %d",xpos)); + + itmtype += xdir; + } fbtk_set_mapping(toolbar, true); + return toolbar; } static void -create_normal_browser_window(struct gui_window *gw, - int furniture_width, - int toolbar_height) +create_browser_widget(struct gui_window *gw, int toolbar_height, int furniture_width) +{ + struct browser_widget_s *browser_widget; + browser_widget = calloc(1, sizeof(struct browser_widget_s)); + + gw->browser = fbtk_create_user(gw->window, + 0, + toolbar_height, + -furniture_width, + -furniture_width, + browser_widget); + + fbtk_set_handler(gw->browser, FBTK_CBT_REDRAW, fb_browser_window_redraw, gw); + fbtk_set_handler(gw->browser, FBTK_CBT_INPUT, fb_browser_window_input, gw); + fbtk_set_handler(gw->browser, FBTK_CBT_CLICK, fb_browser_window_click, gw); + fbtk_set_handler(gw->browser, FBTK_CBT_POINTERMOVE, fb_browser_window_move, gw); +} + +static void +create_normal_browser_window(struct gui_window *gw, int furniture_width) { fbtk_widget_t *widget; + fbtk_widget_t *toolbar; int statusbar_width = 0; + int toolbar_height = option_fb_toolbar_size; + + LOG(("Normal window")); gw->window = fbtk_create_window(fbtk, 0, 0, 0, 0, 0); statusbar_width = option_toolbar_status_width * fbtk_get_width(gw->window) / 10000; + /* toolbar */ + toolbar = create_toolbar(gw, + toolbar_height, + 2, + FB_FRAME_COLOUR, + option_fb_toolbar_layout); - LOG(("Normal window")); - - create_toolbar(gw, toolbar_height); + /* set the actually created toolbar height */ + if (toolbar != NULL) { + toolbar_height = fbtk_get_height(toolbar); + } else { + toolbar_height = 0; + } /* status bar */ gw->status = fbtk_create_text(gw->window, @@ -1065,27 +1239,11 @@ create_normal_browser_window(struct gui_window *gw, fb_scroll_callback, gw); + /* browser widget */ + create_browser_widget(gw, toolbar_height, option_fb_furniture_size); } -static void -create_browser_widget(struct gui_window *gw, int toolbar_height, int furniture_width) -{ - struct browser_widget_s *browser_widget; - browser_widget = calloc(1, sizeof(struct browser_widget_s)); - - gw->browser = fbtk_create_user(gw->window, - 0, - toolbar_height, - -furniture_width, - -furniture_width, - browser_widget); - - fbtk_set_handler(gw->browser, FBTK_CBT_REDRAW, fb_browser_window_redraw, gw); - fbtk_set_handler(gw->browser, FBTK_CBT_INPUT, fb_browser_window_input, gw); - fbtk_set_handler(gw->browser, FBTK_CBT_CLICK, fb_browser_window_click, gw); - fbtk_set_handler(gw->browser, FBTK_CBT_POINTERMOVE, fb_browser_window_move, gw); -} struct gui_window * gui_create_browser_window(struct browser_window *bw, @@ -1107,9 +1265,8 @@ gui_create_browser_window(struct browser_window *bw, switch(bw->browser_window_type) { case BROWSER_WINDOW_NORMAL: - create_normal_browser_window(gw, option_fb_furniture_size, option_fb_toolbar_size); + create_normal_browser_window(gw, option_fb_furniture_size); gw->localhistory = fb_create_localhistory(bw, fbtk, option_fb_furniture_size); - create_browser_widget(gw, option_fb_toolbar_size, option_fb_furniture_size); /* map and request redraw of gui window */ fbtk_set_mapping(gw->window, true); diff --git a/framebuffer/options.h b/framebuffer/options.h index fff5fd192..00d5277f5 100644 --- a/framebuffer/options.h +++ b/framebuffer/options.h @@ -28,6 +28,7 @@ extern char *option_fb_input_devpath; extern char *option_fb_input_glob; extern int option_fb_furniture_size; /* toolkit furniture size */ extern int option_fb_toolbar_size; /* toolbar furniture size */ +extern char *option_fb_toolbar_layout; /* toolbar layout */ extern bool option_fb_osk; /* enable on screen keyboard */ extern bool option_fb_font_monochrome; /* render font monochrome */ @@ -47,6 +48,7 @@ extern char *option_fb_face_serif_bold; /* bold serif face */ char *option_fb_input_glob = 0; \ int option_fb_furniture_size = 18; \ int option_fb_toolbar_size = 30; \ + char *option_fb_toolbar_layout; \ bool option_fb_osk = false; \ bool option_fb_font_monochrome = false; \ char *option_fb_face_sans_serif; \ @@ -65,7 +67,8 @@ extern char *option_fb_face_serif_bold; /* bold serif face */ { "fb_input_glob", OPTION_STRING, &option_fb_input_glob }, \ { "fb_furniture_size", OPTION_INTEGER, &option_fb_furniture_size }, \ { "fb_toolbar_size", OPTION_INTEGER, &option_fb_toolbar_size }, \ - { "fb_font_osk", OPTION_BOOL, &option_fb_osk }, \ + { "fb_toolbar_layout", OPTION_STRING, &option_fb_toolbar_layout }, \ + { "fb_osk", OPTION_BOOL, &option_fb_osk }, \ { "fb_font_monochrome", OPTION_BOOL, &option_fb_font_monochrome }, \ { "fb_face_sans_serif", OPTION_STRING, &option_fb_face_sans_serif }, \ { "fb_face_sans_serif_bold", OPTION_STRING, &option_fb_face_sans_serif_bold }, \ -- cgit v1.2.3