From 20ea5ea00fce47a834421d87d800226a5b7441cd Mon Sep 17 00:00:00 2001 From: Phil Mellor Date: Mon, 30 Dec 2002 22:56:30 +0000 Subject: [project @ 2002-12-30 22:56:30 by monkeyson] Forms are now interactive - user can manipulate checkbox, radio, text, textarea, select elements. svn path=/import/netsurf/; revision=76 --- desktop/browser.c | 147 ++++++++++++++++++++++++++++++++++++++++++++++++++---- desktop/browser.h | 18 ++++++- desktop/gui.h | 3 +- 3 files changed, 155 insertions(+), 13 deletions(-) (limited to 'desktop') diff --git a/desktop/browser.c b/desktop/browser.c index 7c1ce1226..be8cd1e0e 100644 --- a/desktop/browser.c +++ b/desktop/browser.c @@ -1,5 +1,5 @@ /** - * $Id: browser.c,v 1.18 2002/12/30 21:14:29 bursa Exp $ + * $Id: browser.c,v 1.19 2002/12/30 22:56:30 monkeyson Exp $ */ #include "netsurf/riscos/font.h" @@ -18,14 +18,6 @@ #include #include -struct box_selection -{ - struct box* box; - int actual_x; - int actual_y; - int plot_index; -}; - void browser_window_text_selection(struct browser_window* bw, int click_x, int click_y, int click_type); void browser_window_clear_text_selection(struct browser_window* bw); void browser_window_change_text_selection(struct browser_window* bw, struct box_position* new_start, struct box_position* new_end); @@ -181,7 +173,7 @@ void content_html_reformat(struct content* c, int width) c->data.html.fonts = font_new_set(); LOG(("XML to box")); - xml_to_box(c->data.html.markup, c->data.html.style, c->data.html.stylesheet, &selector, 0, c->data.html.layout, 0, 0, c->data.html.fonts, 0, 0); + xml_to_box(c->data.html.markup, c->data.html.style, c->data.html.stylesheet, &selector, 0, c->data.html.layout, 0, 0, c->data.html.fonts, 0, 0, 0, 0, &c->data.html.elements); LOG(("Layout document")); layout_document(c->data.html.layout->children, (unsigned long)width); @@ -519,7 +511,14 @@ int browser_window_message(struct browser_window* bw, struct browser_message* ms bw->future_content->main_fetch = NULL; previous_safety = gui_window_set_redraw_safety(bw->window, UNSAFE); if (bw->current_content != NULL) + { + int gc; + for (gc = 0; gc < bw->current_content->data.html.elements.numGadgets; gc++) + { + gui_remove_gadget(bw->current_content->data.html.elements.gadgets[gc]); + } cache_free(bw->current_content); + } bw->current_content = bw->future_content; bw->future_content = NULL; browser_window_reformat(bw); @@ -536,6 +535,131 @@ int browser_window_message(struct browser_window* bw, struct browser_message* ms return 0; } +void clear_radio_gadgets(struct browser_window* bw, struct box* box, struct gui_gadget* group) +{ + struct box* c; + if (box == NULL) + return; + if (box->gadget != 0) + { + if (box->gadget->type == GADGET_RADIO && box->gadget->name != 0 && box->gadget != group) + { + if (strcmp(box->gadget->name, group->name) == 0) + { + if (box->gadget->data.radio.selected) + { + box->gadget->data.radio.selected = 0; + gui_redraw_gadget(bw, box->gadget); + } + } + } + } + for (c = box->children; c != 0; c = c->next) + if (c->type != BOX_FLOAT_LEFT && c->type != BOX_FLOAT_RIGHT) + clear_radio_gadgets(bw, c, group); + + for (c = box->float_children; c != 0; c = c->next_float) + clear_radio_gadgets(bw, c, group); +} + +void gui_redraw_gadget2(struct browser_window* bw, struct box* box, struct gui_gadget* g, int x, int y) +{ + struct box* c; + + if (box->gadget == g) + { + gui_window_redraw(bw->window, x + box->x, y + box->y, x + box->x + box->width, y+box->y + box->height); + } + + for (c = box->children; c != 0; c = c->next) + if (c->type != BOX_FLOAT_LEFT && c->type != BOX_FLOAT_RIGHT) + gui_redraw_gadget2(bw, c, g, box->x + x, box->y + y); + + for (c = box->float_children; c != 0; c = c->next_float) + gui_redraw_gadget2(bw, c, g, box->x + x, box->y + y); +} + +void gui_redraw_gadget(struct browser_window* bw, struct gui_gadget* g) +{ + gui_redraw_gadget2(bw, bw->current_content->data.html.layout->children, g, 0, 0); +} + +void browser_window_gadget_select(struct browser_window* bw, struct gui_gadget* g, int item) +{ + struct formoption* o; + int count; + + count = 0; + o = g->data.select.items; + while (o != NULL) + { + if (g->data.select.multiple == 0) + o->selected = 0; + if (count == item) + o->selected = !(o->selected); + o = o->next; + count++; + } + + gui_redraw_gadget(bw, g); +} + +int browser_window_gadget_click(struct browser_window* bw, int click_x, int click_y) +{ + struct box_selection* click_boxes; + int found, plot_index; + int i; + + found = 0; + click_boxes = NULL; + plot_index = 0; + + box_under_area(bw->current_content->data.html.layout->children, + click_x, click_y, 0, 0, &click_boxes, &found, &plot_index); + + if (found == 0) + return 0; + + for (i = found - 1; i >= 0; i--) + { + if (click_boxes[i].box->type == BOX_INLINE && click_boxes[i].box->gadget != 0) + { + struct gui_gadget* g = click_boxes[i].box->gadget; + + /* gadget clicked */ + switch (g->type) + { + case GADGET_SELECT: + gui_gadget_combo(bw, g, click_x, click_y); + break; + case GADGET_CHECKBOX: + g->data.checkbox.selected = !g->data.checkbox.selected; + gui_redraw_gadget(bw, g); + break; + case GADGET_RADIO: + clear_radio_gadgets(bw, bw->current_content->data.html.layout->children, g); + g->data.radio.selected = -1; + gui_redraw_gadget(bw, g); + break; + case GADGET_ACTIONBUTTON: + g->data.actionbutt.pressed = -1; + gui_redraw_gadget(bw, g); + break; + case GADGET_TEXTAREA: + gui_edit_textarea(bw, g); + break; + case GADGET_TEXTBOX: + gui_edit_textbox(bw, g); + break; + } + + xfree(click_boxes); + return 1; + } + } + xfree(click_boxes); +} + int browser_window_action(struct browser_window* bw, struct browser_action* act) { switch (act->type) @@ -544,6 +668,7 @@ int browser_window_action(struct browser_window* bw, struct browser_action* act) browser_window_follow_link(bw, act->data.mouse.x, act->data.mouse.y, 0); break; case act_MOUSE_CLICK: + return browser_window_gadget_click(bw, act->data.mouse.x, act->data.mouse.y); break; case act_CLEAR_SELECTION: browser_window_text_selection(bw, act->data.mouse.x, act->data.mouse.y, 0); @@ -560,6 +685,8 @@ int browser_window_action(struct browser_window* bw, struct browser_action* act) case act_FOLLOW_LINK_NEW_WINDOW: browser_window_follow_link(bw, act->data.mouse.x, act->data.mouse.y, 2); break; + case act_GADGET_SELECT: + browser_window_gadget_select(bw, act->data.gadget_select.g, act->data.gadget_select.item); default: break; } diff --git a/desktop/browser.h b/desktop/browser.h index 50fc3faf7..9da3b1811 100644 --- a/desktop/browser.h +++ b/desktop/browser.h @@ -1,5 +1,5 @@ /** - * $Id: browser.h,v 1.4 2002/11/02 22:28:05 bursa Exp $ + * $Id: browser.h,v 1.5 2002/12/30 22:56:30 monkeyson Exp $ */ #ifndef _NETSURF_DESKTOP_BROWSER_H_ @@ -60,6 +60,7 @@ struct content int selected; /* 0 = unselected, 1 = selected */ } text_selection; struct font_set* fonts; + struct page_elements elements; } html; } data; struct fetch* main_fetch; @@ -124,7 +125,8 @@ struct browser_action enum { act_UNKNOWN, act_MOUSE_AT, act_MOUSE_CLICK, act_START_NEW_SELECTION, act_ALTER_SELECTION, act_CLEAR_SELECTION, - act_FOLLOW_LINK, act_FOLLOW_LINK_NEW_WINDOW + act_FOLLOW_LINK, act_FOLLOW_LINK_NEW_WINDOW, + act_GADGET_SELECT } type; union { struct { @@ -132,9 +134,21 @@ struct browser_action int y; action_buttons buttons; } mouse; + struct { + struct gui_gadget* g; + int item; + } gadget_select; } data; }; +struct box_selection +{ + struct box* box; + int actual_x; + int actual_y; + int plot_index; +}; + /* public functions */ struct browser_window* create_browser_window(int flags, int width, int height); diff --git a/desktop/gui.h b/desktop/gui.h index 6a6335d1a..4e6c7975a 100644 --- a/desktop/gui.h +++ b/desktop/gui.h @@ -1,5 +1,5 @@ /** - * $Id: gui.h,v 1.2 2002/10/15 10:41:12 monkeyson Exp $ + * $Id: gui.h,v 1.3 2002/12/30 22:56:30 monkeyson Exp $ */ #ifndef _NETSURF_DESKTOP_GUI_H_ @@ -45,4 +45,5 @@ int gui_file_to_filename(char* location, char* actual_filename, int size); void gui_window_start_throbber(gui_window* g); void gui_window_stop_throbber(gui_window* g); +void gui_gadget_combo(struct browser_window* bw, struct gui_gadget* g, int mx, int my); #endif -- cgit v1.2.3