summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhil Mellor <phil@monkeyson.info>2002-12-30 22:56:30 +0000
committerPhil Mellor <phil@monkeyson.info>2002-12-30 22:56:30 +0000
commit20ea5ea00fce47a834421d87d800226a5b7441cd (patch)
tree81d2f6bf5cee5d048d74a9e9b7e52c5b67a6bbfb
parent8cce8f76b46c4b8298db1c4bdf5c4d1cfe43c25c (diff)
downloadnetsurf-20ea5ea00fce47a834421d87d800226a5b7441cd.tar.gz
netsurf-20ea5ea00fce47a834421d87d800226a5b7441cd.tar.bz2
[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
-rw-r--r--desktop/browser.c147
-rw-r--r--desktop/browser.h18
-rw-r--r--desktop/gui.h3
-rw-r--r--render/box.c315
-rw-r--r--render/box.h44
-rw-r--r--render/layout.c12
-rw-r--r--riscos/gui.c421
-rw-r--r--riscos/gui.h3
8 files changed, 911 insertions, 52 deletions
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 <time.h>
#include <ctype.h>
-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
diff --git a/render/box.c b/render/box.c
index e6726b02b..65694810b 100644
--- a/render/box.c
+++ b/render/box.c
@@ -1,5 +1,5 @@
/**
- * $Id: box.c,v 1.24 2002/12/30 02:06:03 monkeyson Exp $
+ * $Id: box.c,v 1.25 2002/12/30 22:56:30 monkeyson Exp $
*/
#include <assert.h>
@@ -19,7 +19,7 @@
* internal functions
*/
-struct box* box_gui_gadget(xmlNode * n, struct css_style* style);
+struct box* input(xmlNode * n, struct css_style* style, struct form* current_form);
void box_add_child(struct box * parent, struct box * child);
struct box * box_create(xmlNode * node, box_type type, struct css_style * style,
@@ -30,7 +30,9 @@ struct box * convert_xml_to_box(xmlNode * n, struct css_style * parent_style,
struct css_selector ** selector, unsigned int depth,
struct box * parent, struct box * inline_container,
const char *href, struct font_set *fonts,
- struct gui_gadget* current_select, struct formoption* current_option);
+ struct gui_gadget* current_select, struct formoption* current_option,
+ struct gui_gadget* current_textarea, struct form* current_form,
+ struct page_elements* elements);
struct css_style * box_get_style(struct css_stylesheet * stylesheet, struct css_style * parent_style,
xmlNode * n, struct css_selector * selector, unsigned int depth);
void box_normalise_block(struct box *block);
@@ -129,11 +131,14 @@ void xml_to_box(xmlNode * n, struct css_style * parent_style,
struct css_selector ** selector, unsigned int depth,
struct box * parent, struct box * inline_container,
const char *href, struct font_set *fonts,
- struct gui_gadget* current_select, struct formoption* current_option)
+ struct gui_gadget* current_select, struct formoption* current_option,
+ struct gui_gadget* current_textarea, struct form* current_form,
+ struct page_elements* elements)
{
LOG(("node %p", n));
convert_xml_to_box(n, parent_style, stylesheet,
- selector, depth, parent, inline_container, href, fonts, current_select, current_option);
+ selector, depth, parent, inline_container, href, fonts, current_select, current_option,
+ current_textarea, current_form, elements);
LOG(("normalising"));
box_normalise_block(parent->children);
}
@@ -149,7 +154,9 @@ struct box * convert_xml_to_box(xmlNode * n, struct css_style * parent_style,
struct css_selector ** selector, unsigned int depth,
struct box * parent, struct box * inline_container,
const char *href, struct font_set *fonts,
- struct gui_gadget* current_select, struct formoption* current_option)
+ struct gui_gadget* current_select, struct formoption* current_option,
+ struct gui_gadget* current_textarea, struct form* current_form,
+ struct page_elements* elements)
{
struct box * box;
struct box * inline_container_c;
@@ -184,10 +191,20 @@ struct box * convert_xml_to_box(xmlNode * n, struct css_style * parent_style,
}
}
- if (n->type == XML_TEXT_NODE ||
+ if (n->type == XML_ELEMENT_NODE && (strcmp((const char *) n->name, "form") == 0))
+ {
+ struct form* form = box_form(n);
+ if (form != NULL)
+ {
+ current_form = form;
+ add_form_element(elements, form);
+ }
+ }
+ else if (n->type == XML_TEXT_NODE ||
(n->type == XML_ELEMENT_NODE && (strcmp((const char *) n->name, "input") == 0)) ||
(n->type == XML_ELEMENT_NODE && (strcmp((const char *) n->name, "select") == 0)) ||
(n->type == XML_ELEMENT_NODE && (strcmp((const char *) n->name, "option") == 0)) ||
+ (n->type == XML_ELEMENT_NODE && (strcmp((const char *) n->name, "textarea") == 0)) ||
(n->type == XML_ELEMENT_NODE && (strcmp((const char *) n->name, "img") == 0)) ||
(n->type == XML_ELEMENT_NODE && (style->float_ == CSS_FLOAT_LEFT ||
style->float_ == CSS_FLOAT_RIGHT))) {
@@ -199,9 +216,14 @@ struct box * convert_xml_to_box(xmlNode * n, struct css_style * parent_style,
}
if (n->type == XML_TEXT_NODE) {
LOG2("TEXT NODE");
- if (current_option != 0)
+ if (current_textarea != 0)
{
char* thistext = squash_whitespace(tolat1(n->content));
+ textarea_addtext(current_textarea, thistext);
+ }
+ else if (current_option != 0)
+ {
+ char* thistext = (tolat1(n->content));
LOG2("adding to option");
option_addtext(current_option, thistext);
LOG2("freeing thistext");
@@ -224,25 +246,41 @@ struct box * convert_xml_to_box(xmlNode * n, struct css_style * parent_style,
}
} else if (strcmp((const char *) n->name, "img") == 0) {
LOG2(("image"));
- box = box_image(n, parent_style);
+ box = box_image(n, parent_style, href);
+ if (box != NULL)
+ {
+ box_add_child(inline_container, box);
+ add_img_element(elements, box->img);
+ }
+ } else if (strcmp((const char *) n->name, "textarea") == 0) {
+ LOG2(("textarea"));
+ box = box_textarea(n, parent_style, current_form);
if (box != NULL)
+ {
box_add_child(inline_container, box);
+ current_textarea = box->gadget;
+ add_gadget_element(elements, box->gadget);
+ }
} else if (strcmp((const char *) n->name, "select") == 0) {
LOG2(("select"));
- box = box_select(n, parent_style);
+ box = box_select(n, parent_style, current_form);
if (box != NULL)
{
box_add_child(inline_container, box);
current_select = box->gadget;
+ add_gadget_element(elements, box->gadget);
}
} else if (strcmp((const char *) n->name, "option") == 0) {
LOG2(("option"));
current_option = box_option(n, parent_style, current_select);
} else if (strcmp((const char *) n->name, "input") == 0) {
LOG2(("input"));
- box = box_gui_gadget(n, parent_style);
+ box = box_input(n, parent_style, current_form, elements);
if (box != NULL)
+ {
box_add_child(inline_container, box);
+ add_gadget_element(elements, box->gadget);
+ }
} else {
LOG2(("float"));
box = box_create(0, BOX_FLOAT_LEFT, 0, href);
@@ -264,14 +302,16 @@ struct box * convert_xml_to_box(xmlNode * n, struct css_style * parent_style,
for (c = n->children; c != 0; c = c->next)
inline_container_c = convert_xml_to_box(c, style, stylesheet,
selector, depth + 1, box, inline_container_c,
- href, fonts, current_select, current_option);
+ href, fonts, current_select, current_option,
+ current_textarea, current_form, elements);
inline_container = 0;
break;
case CSS_DISPLAY_INLINE: /* inline elements get no box, but their children do */
for (c = n->children; c != 0; c = c->next)
inline_container = convert_xml_to_box(c, style, stylesheet,
selector, depth + 1, parent, inline_container,
- href, fonts, current_select, current_option);
+ href, fonts, current_select, current_option,
+ current_textarea, current_form, elements);
break;
case CSS_DISPLAY_TABLE:
box = box_create(n, BOX_TABLE, style, href);
@@ -279,7 +319,8 @@ struct box * convert_xml_to_box(xmlNode * n, struct css_style * parent_style,
for (c = n->children; c != 0; c = c->next)
convert_xml_to_box(c, style, stylesheet,
selector, depth + 1, box, 0,
- href, fonts, current_select, current_option);
+ href, fonts, current_select, current_option,
+ current_textarea, current_form, elements);
inline_container = 0;
break;
case CSS_DISPLAY_TABLE_ROW_GROUP:
@@ -291,7 +332,8 @@ struct box * convert_xml_to_box(xmlNode * n, struct css_style * parent_style,
for (c = n->children; c != 0; c = c->next)
inline_container_c = convert_xml_to_box(c, style, stylesheet,
selector, depth + 1, box, inline_container_c,
- href, fonts, current_select, current_option);
+ href, fonts, current_select, current_option,
+ current_textarea, current_form, elements);
inline_container = 0;
break;
case CSS_DISPLAY_TABLE_ROW:
@@ -300,7 +342,8 @@ struct box * convert_xml_to_box(xmlNode * n, struct css_style * parent_style,
for (c = n->children; c != 0; c = c->next)
convert_xml_to_box(c, style, stylesheet,
selector, depth + 1, box, 0,
- href, fonts, current_select, current_option);
+ href, fonts, current_select, current_option,
+ current_textarea, current_form, elements);
inline_container = 0;
break;
case CSS_DISPLAY_TABLE_CELL:
@@ -315,7 +358,8 @@ struct box * convert_xml_to_box(xmlNode * n, struct css_style * parent_style,
for (c = n->children; c != 0; c = c->next)
inline_container_c = convert_xml_to_box(c, style, stylesheet,
selector, depth + 1, box, inline_container_c,
- href, fonts, current_select, current_option);
+ href, fonts, current_select, current_option,
+ current_textarea, current_form, elements);
inline_container = 0;
break;
default:
@@ -735,6 +779,55 @@ void box_normalise_inline_container(struct box *cont)
}
+void gadget_free(struct gui_gadget* g)
+{
+ struct formoption* o;
+
+ if (g->name != 0)
+ xfree(g->name);
+
+ switch (g->type)
+ {
+ case GADGET_HIDDEN:
+ if (g->data.hidden.value != 0)
+ xfree(g->data.hidden.value);
+ break;
+ case GADGET_RADIO:
+ if (g->data.checkbox.value != 0)
+ xfree(g->data.radio.value);
+ break;
+ case GADGET_CHECKBOX:
+ if (g->data.checkbox.value != 0)
+ xfree(g->data.checkbox.value);
+ break;
+ case GADGET_TEXTAREA:
+ if (g->data.textarea.text != 0)
+ xfree(g->data.textarea.text);
+ break;
+ case GADGET_TEXTBOX:
+ gui_remove_gadget(g);
+ if (g->data.textbox.text != 0)
+ xfree(g->data.textbox.text);
+ break;
+ case GADGET_ACTIONBUTTON:
+ if (g->data.actionbutt.label != 0)
+ xfree(g->data.actionbutt.label);
+ break;
+ case GADGET_SELECT:
+ o = g->data.select.items;
+ while (o != NULL)
+ {
+ if (o->text != 0)
+ xfree(o->text);
+ if (o->value != 0)
+ xfree(o->value);
+ xfree(o);
+ o = o->next;
+ }
+ break;
+ }
+}
+
/**
* free a box tree recursively
*/
@@ -754,7 +847,7 @@ void box_free(struct box *box)
// free(box->style);
if (box->gadget != 0)
{
- /* gadget_free(box->gadget); */
+ gadget_free(box->gadget);
free((void*)box->gadget);
}
@@ -775,12 +868,12 @@ void box_free(struct box *box)
}
}
-struct box* box_image(xmlNode * n, struct css_style* style)
+struct box* box_image(xmlNode * n, struct css_style* style, char* href)
{
struct box* box = 0;
char* s;
- box = box_create(n, BOX_INLINE, style, NULL);
+ box = box_create(n, BOX_INLINE, style, href);
box->img = xcalloc(1, sizeof(struct img));
box->text = 0;
@@ -811,7 +904,47 @@ struct box* box_image(xmlNode * n, struct css_style* style)
return box;
}
-struct box* box_select(xmlNode * n, struct css_style* style)
+struct box* box_textarea(xmlNode* n, struct css_style* style, struct form* current_form)
+{
+ struct box* box = 0;
+ char* s;
+
+ LOG2("creating box");
+ box = box_create(n, BOX_INLINE, style, NULL);
+ LOG2("creating gadget");
+ box->gadget = xcalloc(1, sizeof(struct gui_gadget));
+ box->gadget->type = GADGET_TEXTAREA;
+ box->gadget->form = current_form;
+
+ box->text = 0;
+ box->length = 0;
+ box->font = 0;
+
+ if ((s = (char *) xmlGetProp(n, (xmlChar *) "cols")))
+ {
+ box->gadget->data.textarea.cols = atoi(s);
+ free(s);
+ }
+ else
+ box->gadget->data.textarea.cols = 40;
+
+ if ((s = (char *) xmlGetProp(n, (xmlChar *) "rows")))
+ {
+ box->gadget->data.textarea.rows = atoi(s);
+ free(s);
+ }
+ else
+ box->gadget->data.textarea.rows = 16;
+
+ if ((s = (char *) xmlGetProp(n, (xmlChar *) "name")))
+ {
+ box->gadget->name = s;
+ }
+
+ return box;
+}
+
+struct box* box_select(xmlNode * n, struct css_style* style, struct form* current_form)
{
struct box* box = 0;
char* s;
@@ -821,6 +954,7 @@ struct box* box_select(xmlNode * n, struct css_style* style)
LOG2("creating gadget");
box->gadget = xcalloc(1, sizeof(struct gui_gadget));
box->gadget->type = GADGET_SELECT;
+ box->gadget->form = current_form;
box->text = 0;
box->length = 0;
@@ -834,6 +968,14 @@ struct box* box_select(xmlNode * n, struct css_style* style)
else
box->gadget->data.select.size = 1;
+ if ((s = (char *) xmlGetProp(n, (xmlChar *) "multiple"))) {
+ box->gadget->data.select.multiple = 1;
+ }
+
+ if ((s = (char *) xmlGetProp(n, (xmlChar *) "name"))) {
+ box->gadget->name = s;
+ }
+
box->gadget->data.select.items = NULL;
box->gadget->data.select.numitems = 0;
/* to do: multiple, name */
@@ -844,7 +986,9 @@ struct box* box_select(xmlNode * n, struct css_style* style)
struct formoption* box_option(xmlNode* n, struct css_style* style, struct gui_gadget* current_select)
{
struct formoption* option;
+ char* s;
assert(current_select != 0);
+
LOG2("realloc option");
if (current_select->data.select.items == 0)
{
@@ -862,11 +1006,35 @@ struct formoption* box_option(xmlNode* n, struct css_style* style, struct gui_ga
}
/* TO DO: set selected / value here */
+ if ((s = (char *) xmlGetProp(n, (xmlChar *) "selected"))) {
+ option->selected = -1;
+ free(s);
+ }
+
+ if ((s = (char *) xmlGetProp(n, (xmlChar *) "value"))) {
+ option->value = s;
+ }
LOG2("returning");
return option;
}
+void textarea_addtext(struct gui_gadget* textarea, char* text)
+{
+ assert (textarea != 0);
+ assert (text != 0);
+
+ if (textarea->data.textarea.text == 0)
+ {
+ textarea->data.textarea.text = strdup(text);
+ }
+ else
+ {
+ textarea->data.textarea.text = xrealloc(textarea->data.textarea.text, strlen(textarea->data.textarea.text) + strlen(text) + 1);
+ strcat(textarea->data.textarea.text, text);
+ }
+}
+
void option_addtext(struct formoption* option, char* text)
{
assert(option != 0);
@@ -887,7 +1055,7 @@ void option_addtext(struct formoption* option, char* text)
return;
}
-struct box* box_gui_gadget(xmlNode * n, struct css_style* style)
+struct box* box_input(xmlNode * n, struct css_style* style, struct form* current_form, struct page_elements* elements)
{
struct box* box = 0;
char* s;
@@ -895,6 +1063,53 @@ struct box* box_gui_gadget(xmlNode * n, struct css_style* style)
if ((type = (char *) xmlGetProp(n, (xmlChar *) "type")))
{
+ if (strcmp(type, "hidden") == 0)
+ {
+ struct gui_gadget* g = xcalloc(1, sizeof(struct gui_gadget));
+ g->type = GADGET_HIDDEN;
+ g->form = current_form;
+
+ if ((s = (char *) xmlGetProp(n, (xmlChar *) "value"))) {
+ g->data.hidden.value = s;
+ }
+
+ if ((s = (char *) xmlGetProp(n, (xmlChar *) "name"))) {
+ g->name = s;
+ }
+ }
+ if (strcmp(type, "checkbox") == 0 || strcmp(type, "radio") == 0)
+ {
+ box = box_create(n, BOX_INLINE, style, NULL);
+ box->gadget = xcalloc(1, sizeof(struct gui_gadget));
+ if (type[0] == 'c')
+ box->gadget->type = GADGET_CHECKBOX;
+ else
+ box->gadget->type = GADGET_RADIO;
+ box->gadget->form = current_form;
+
+ box->text = 0;
+ box->length = 0;
+ box->font = 0;
+
+ if ((s = (char *) xmlGetProp(n, (xmlChar *) "checked"))) {
+ if (type[0] == 'c')
+ box->gadget->data.checkbox.selected = -1;
+ else
+ box->gadget->data.radio.selected = -1;
+ free(s);
+ }
+
+ if ((s = (char *) xmlGetProp(n, (xmlChar *) "value"))) {
+ if (type[0] == 'c')
+ box->gadget->data.checkbox.value = s;
+ else
+ box->gadget->data.radio.value = s;
+ }
+
+ if ((s = (char *) xmlGetProp(n, (xmlChar *) "name"))) {
+ box->gadget->name = s;
+ }
+ }
if (strcmp(type, "submit") == 0 || strcmp(type, "reset") == 0)
{
//style->display = CSS_DISPLAY_BLOCK;
@@ -902,6 +1117,7 @@ struct box* box_gui_gadget(xmlNode * n, struct css_style* style)
box = box_create(n, BOX_INLINE, style, NULL);
box->gadget = xcalloc(1, sizeof(struct gui_gadget));
box->gadget->type = GADGET_ACTIONBUTTON;
+ box->gadget->form = current_form;
box->text = 0;
box->length = 0;
@@ -915,6 +1131,10 @@ struct box* box_gui_gadget(xmlNode * n, struct css_style* style)
box->gadget->data.actionbutt.label = strdup(type);
box->gadget->data.actionbutt.label[0] = toupper(type[0]);
}
+
+ if ((s = (char *) xmlGetProp(n, (xmlChar *) "name"))) {
+ box->gadget->name = s;
+ }
}
if (strcmp(type, "text") == 0 || strcmp(type, "password") == 0)
{
@@ -923,12 +1143,13 @@ struct box* box_gui_gadget(xmlNode * n, struct css_style* style)
box = box_create(n, BOX_INLINE, style, NULL);
box->gadget = xcalloc(1, sizeof(struct gui_gadget));
box->gadget->type = GADGET_TEXTBOX;
+ box->gadget->form = current_form;
box->text = 0;
box->length = 0;
box->font = 0;
- box->gadget->data.textbox.maxlength = 255;
+ box->gadget->data.textbox.maxlength = 32;
if ((s = (char *) xmlGetProp(n, (xmlChar *) "maxlength"))) {
box->gadget->data.textbox.maxlength = atoi(s);
free(s);
@@ -948,8 +1169,56 @@ struct box* box_gui_gadget(xmlNode * n, struct css_style* style)
free(s);
}
+ if ((s = (char *) xmlGetProp(n, (xmlChar *) "name"))) {
+ box->gadget->name = s;
+ }
}
free(type);
}
return box;
}
+
+struct form* box_form(xmlNode* n)
+{
+ struct form* form;
+ char* s;
+
+ form = xcalloc(1, sizeof(struct form*));
+
+ if ((s = (char *) xmlGetProp(n, (xmlChar *) "action"))) {
+ form->action = s;
+ }
+
+ if ((s = (char *) xmlGetProp(n, (xmlChar *) "method"))) {
+ if (strcmp(s, "get") == 0)
+ form->action = method_GET;
+ else if (strcmp(s, "post") == 0)
+ form->action = method_POST;
+ xfree(s);
+ }
+
+ return form;
+}
+
+void add_form_element(struct page_elements* pe, struct form* f)
+{
+ pe->forms = xrealloc(pe->forms, (pe->numForms + 1) * sizeof(struct form*));
+ pe->forms[pe->numForms] = f;
+ pe->numForms++;
+}
+
+void add_gadget_element(struct page_elements* pe, struct gadget* g)
+{
+ pe->gadgets = xrealloc(pe->gadgets, (pe->numGadgets + 1) * sizeof(struct gui_gadget*));
+ pe->gadgets[pe->numGadgets] = g;
+ pe->numGadgets++;
+}
+
+void add_img_element(struct page_elements* pe, struct img* i)
+{
+ pe->images = xrealloc(pe->images, (pe->numImages + 1) * sizeof(struct img*));
+ pe->images[pe->numImages] = i;
+ pe->numImages++;
+}
+
+
diff --git a/render/box.h b/render/box.h
index e978662ad..eb6589118 100644
--- a/render/box.h
+++ b/render/box.h
@@ -1,5 +1,5 @@
/**
- * $Id: box.h,v 1.14 2002/12/30 02:06:03 monkeyson Exp $
+ * $Id: box.h,v 1.15 2002/12/30 22:56:30 monkeyson Exp $
*/
#ifndef _NETSURF_RENDER_BOX_H_
@@ -35,16 +35,22 @@ struct formoption {
};
struct gui_gadget {
- enum { GADGET_HIDDEN = 0, GADGET_TEXTBOX, GADGET_RADIO, GADGET_OPTION,
+ enum { GADGET_HIDDEN = 0, GADGET_TEXTBOX, GADGET_RADIO, GADGET_CHECKBOX,
GADGET_SELECT, GADGET_TEXTAREA, GADGET_ACTIONBUTTON } type;
+ char* name;
+ struct form* form;
union {
struct {
+ char* value;
+ } hidden;
+ struct {
int maxlength;
char* text;
int size;
} textbox;
struct {
char* label;
+ int pressed;
} actionbutt;
struct {
int numitems;
@@ -52,6 +58,19 @@ struct gui_gadget {
int size;
int multiple;
} select;
+ struct {
+ int selected;
+ char* value;
+ } checkbox;
+ struct {
+ int selected;
+ char* value;
+ } radio;
+ struct {
+ int cols;
+ int rows;
+ char* text;
+ } textarea;
} data;
};
@@ -85,6 +104,23 @@ struct box {
struct img* img;
};
+struct form
+{
+ char* action; /* url */
+ enum {method_GET, method_POST} method;
+};
+
+struct page_elements
+{
+ struct form** forms;
+ struct gui_gadget** gadgets;
+ struct img** images;
+ int numForms;
+ int numGadgets;
+ int numImages;
+};
+
+
#define UNKNOWN_WIDTH ULONG_MAX
#define UNKNOWN_MAX_WIDTH ULONG_MAX
@@ -96,7 +132,9 @@ void xml_to_box(xmlNode * n, struct css_style * parent_style, struct css_stylesh
struct css_selector ** selector, unsigned int depth,
struct box * parent, struct box * inline_container,
const char *href, struct font_set *fonts,
- struct gui_gadget* current_select, struct formoption* current_option);
+ struct gui_gadget* current_select, struct formoption* current_option,
+ struct gui_gadget* current_textarea, struct form* current_form,
+ struct page_elements* elements);
void box_dump(struct box * box, unsigned int depth);
void box_free(struct box *box);
diff --git a/render/layout.c b/render/layout.c
index db1432c78..3015d8eeb 100644
--- a/render/layout.c
+++ b/render/layout.c
@@ -1,5 +1,5 @@
/**
- * $Id: layout.c,v 1.29 2002/12/30 02:06:03 monkeyson Exp $
+ * $Id: layout.c,v 1.30 2002/12/30 22:56:30 monkeyson Exp $
*/
#include <assert.h>
@@ -127,6 +127,9 @@ int gadget_width(struct gui_gadget* gadget)
/* should use wimp_textop via a gui wraper for these */
switch (gadget->type)
{
+ case GADGET_CHECKBOX:
+ case GADGET_RADIO:
+ return 22;
case GADGET_TEXTBOX:
return gadget->data.textbox.size * 8;
case GADGET_ACTIONBUTTON:
@@ -141,6 +144,8 @@ int gadget_width(struct gui_gadget* gadget)
current = current->next;
}
return max;
+ case GADGET_TEXTAREA:
+ return gadget->data.textarea.cols * 8 + 8;
default:
assert(0);
}
@@ -151,12 +156,17 @@ int gadget_height(struct gui_gadget* gadget)
{
switch (gadget->type)
{
+ case GADGET_CHECKBOX:
+ case GADGET_RADIO:
+ return 22;
case GADGET_TEXTBOX:
return 28;
case GADGET_ACTIONBUTTON:
return 28;
case GADGET_SELECT:
return 28;
+ case GADGET_TEXTAREA:
+ return gadget->data.textarea.rows * 16 + 8;
default:
assert(0);
}
diff --git a/riscos/gui.c b/riscos/gui.c
index 552388701..cf37e5798 100644
--- a/riscos/gui.c
+++ b/riscos/gui.c
@@ -1,5 +1,5 @@
/**
- * $Id: gui.c,v 1.11 2002/12/30 02:06:03 monkeyson Exp $
+ * $Id: gui.c,v 1.12 2002/12/30 22:56:30 monkeyson Exp $
*/
#include "netsurf/riscos/font.h"
@@ -192,6 +192,9 @@ wimp_menu* current_menu;
int current_menu_x, current_menu_y;
gui_window* current_gui;
+wimp_menu* combo_menu;
+struct gui_gadget* current_gadget;
+
void ro_gui_create_menu(wimp_menu* menu, int x, int y, gui_window* g)
{
current_menu = menu;
@@ -208,7 +211,7 @@ ro_theme* current_theme = NULL;
char* BROWSER_VALIDATION = "\0";
const char* task_name = "NetSurf";
-const wimp_MESSAGE_LIST(1) task_messages = { {0} };
+const wimp_MESSAGE_LIST(3) task_messages = { {message_DATA_SAVE, message_DATA_LOAD, 0} };
wimp_t task_handle;
wimp_i ro_gui_iconbar_i;
@@ -467,6 +470,8 @@ void ro_gui_window_redraw_box(gui_window* g, struct box * box, signed long x, si
const char * const noname = "";
const char * name = noname;
char *text;
+ char* select_text;
+ struct formoption* opt;
switch (box->type)
{
@@ -524,12 +529,26 @@ void ro_gui_window_redraw_box(gui_window* g, struct box * box, signed long x, si
switch (box->gadget->type)
{
- case GADGET_TEXTBOX:
+ case GADGET_TEXTAREA:
icon.flags = wimp_ICON_TEXT | wimp_ICON_BORDER |
wimp_ICON_VCENTRED | wimp_ICON_FILLED |
wimp_ICON_INDIRECTED |
(wimp_COLOUR_BLACK << wimp_ICON_FG_COLOUR_SHIFT) |
(wimp_COLOUR_WHITE << wimp_ICON_BG_COLOUR_SHIFT);
+ icon.data.indirected_text.text = box->gadget->data.textarea.text;
+ icon.data.indirected_text.size = strlen(box->gadget->data.textarea.text);
+ icon.data.indirected_text.validation = "R7;L";
+ fprintf(stderr, "writing GADGET TEXTAREA\n");
+ wimp_plot_icon(&icon);
+ break;
+
+
+ case GADGET_TEXTBOX:
+ icon.flags = wimp_ICON_TEXT | wimp_ICON_BORDER |
+ wimp_ICON_VCENTRED | wimp_ICON_FILLED |
+ wimp_ICON_INDIRECTED |
+ (wimp_COLOUR_DARK_GREY << wimp_ICON_FG_COLOUR_SHIFT) |
+ (wimp_COLOUR_WHITE << wimp_ICON_BG_COLOUR_SHIFT);
icon.data.indirected_text.text = box->gadget->data.textbox.text;
icon.data.indirected_text.size = box->gadget->data.textbox.maxlength;
icon.data.indirected_text.validation = " ";
@@ -541,11 +560,19 @@ void ro_gui_window_redraw_box(gui_window* g, struct box * box, signed long x, si
icon.flags = wimp_ICON_TEXT | wimp_ICON_BORDER |
wimp_ICON_VCENTRED | wimp_ICON_FILLED |
wimp_ICON_INDIRECTED | wimp_ICON_HCENTRED |
- (wimp_COLOUR_BLACK << wimp_ICON_FG_COLOUR_SHIFT) |
- (wimp_COLOUR_VERY_LIGHT_GREY << wimp_ICON_BG_COLOUR_SHIFT);
+ (wimp_COLOUR_BLACK << wimp_ICON_FG_COLOUR_SHIFT);
icon.data.indirected_text.text = box->gadget->data.actionbutt.label;
icon.data.indirected_text.size = strlen(box->gadget->data.actionbutt.label);
- icon.data.indirected_text.validation = "R5,3";
+ if (box->gadget->data.actionbutt.pressed)
+ {
+ icon.data.indirected_text.validation = "R2";
+ icon.flags |= (wimp_COLOUR_LIGHT_GREY << wimp_ICON_BG_COLOUR_SHIFT);
+ }
+ else
+ {
+ icon.data.indirected_text.validation = "R1";
+ icon.flags |= (wimp_COLOUR_VERY_LIGHT_GREY << wimp_ICON_BG_COLOUR_SHIFT);
+ }
fprintf(stderr, "writing GADGET ACTION\n");
wimp_plot_icon(&icon);
break;
@@ -556,13 +583,55 @@ void ro_gui_window_redraw_box(gui_window* g, struct box * box, signed long x, si
wimp_ICON_INDIRECTED | wimp_ICON_HCENTRED |
(wimp_COLOUR_BLACK << wimp_ICON_FG_COLOUR_SHIFT) |
(wimp_COLOUR_VERY_LIGHT_GREY << wimp_ICON_BG_COLOUR_SHIFT);
- icon.data.indirected_text.text = box->gadget->data.select.items->text;
- icon.data.indirected_text.size = strlen(box->gadget->data.select.items->text);
+ select_text = 0;
+ opt = box->gadget->data.select.items;
+ while (opt != NULL)
+ {
+ if (opt->selected)
+ {
+ if (select_text == 0)
+ select_text = opt->text;
+ else
+ select_text = "<Multiple>";
+ }
+ opt = opt->next;
+ }
+ if (select_text == 0)
+ select_text = "<None>";
+ icon.data.indirected_text.text = select_text;
+ icon.data.indirected_text.size = strlen(icon.data.indirected_text.text);
icon.data.indirected_text.validation = "R2";
fprintf(stderr, "writing GADGET ACTION\n");
wimp_plot_icon(&icon);
break;
+ case GADGET_CHECKBOX:
+ icon.flags = wimp_ICON_TEXT | wimp_ICON_SPRITE |
+ wimp_ICON_VCENTRED | wimp_ICON_HCENTRED |
+ wimp_ICON_INDIRECTED;
+ icon.data.indirected_text_and_sprite.text = "\0";
+ if (box->gadget->data.checkbox.selected)
+ icon.data.indirected_text_and_sprite.validation = "Sopton;";
+ else
+ icon.data.indirected_text_and_sprite.validation = "Soptoff;";
+ icon.data.indirected_text_and_sprite.size = 1;
+ wimp_plot_icon(&icon);
+ break;
+
+ case GADGET_RADIO:
+ icon.flags = wimp_ICON_TEXT | wimp_ICON_SPRITE |
+ wimp_ICON_VCENTRED | wimp_ICON_HCENTRED |
+ wimp_ICON_INDIRECTED;
+ icon.data.indirected_text_and_sprite.text = "\0";
+ if (box->gadget->data.radio.selected)
+ icon.data.indirected_text_and_sprite.validation = "Sradioon;";
+ else
+ icon.data.indirected_text_and_sprite.validation = "Sradiooff;";
+ icon.data.indirected_text_and_sprite.size = 1;
+ wimp_plot_icon(&icon);
+ break;
+
+
}
}
@@ -1165,6 +1234,16 @@ void ro_gui_window_click(gui_window* g, wimp_pointer* pointer)
{
if (g->data.browser.bw->current_content->type == CONTENT_HTML)
{
+ if (pointer->buttons == wimp_CLICK_SELECT)
+ {
+ msg.type = act_MOUSE_CLICK;
+ msg.data.mouse.x = x;
+ msg.data.mouse.y = y;
+ msg.data.mouse.buttons = act_BUTTON_NORMAL;
+ if (browser_window_action(g->data.browser.bw, &msg) == 1)
+ return;
+ msg.type = act_UNKNOWN;
+ }
if (pointer->buttons == wimp_CLICK_SELECT && g->data.browser.bw->current_content->data.html.text_selection.selected == 1)
msg.type = act_CLEAR_SELECTION;
else if (pointer->buttons == wimp_CLICK_ADJUST && g->data.browser.bw->current_content->data.html.text_selection.selected == 1)
@@ -1338,6 +1417,11 @@ void gui_multitask(void)
case wimp_USER_MESSAGE :
case wimp_USER_MESSAGE_RECORDED :
case wimp_USER_MESSAGE_ACKNOWLEDGE:
+ fprintf(stderr, "MESSAGE %d (%x) HAS ARRIVED\n", block.message.action);
+ if (block.message.action == message_DATA_SAVE)
+ ro_msg_datasave(&(block.message));
+ else if (block.message.action == message_DATA_LOAD)
+ ro_msg_dataload(&(block.message));
if (block.message.action == message_QUIT)
netsurf_quit = 1;
else
@@ -1349,6 +1433,28 @@ void gui_multitask(void)
}
+/*
+void ro_gui_keypress(wimp_key* key)
+{
+ gui_window* g;
+
+ if (key == NULL)
+ return;
+
+ g = ro_lookup_gui_toolbar_from_w(key->w);
+ if (g != NULL)
+ if (block.message.action == message_QUIT)
+ netsurf_quit = 1;
+ else
+ ro_gui_poll_queue(event, &block);
+ break;
+ default:
+ break;
+ }
+
+}
+*/
+
void ro_gui_keypress(wimp_key* key)
{
gui_window* g;
@@ -1398,7 +1504,15 @@ void ro_gui_menu_selection(wimp_selection* selection)
}
fprintf(stderr, "\n");
- if (current_menu == (wimp_menu*) &netsurf_iconbar_menu)
+ if (current_menu == combo_menu && selection->items[0] >= 0)
+ {
+ struct browser_action msg;
+ msg.type = act_GADGET_SELECT;
+ msg.data.gadget_select.g= current_gadget;
+ msg.data.gadget_select.item = selection->items[0];
+ browser_window_action(current_gui->data.browser.bw, &msg);
+ }
+ else if (current_menu == (wimp_menu*) &netsurf_iconbar_menu)
{
if (selection->items[0] == 1)
netsurf_quit = 1;
@@ -1446,7 +1560,12 @@ void ro_gui_menu_selection(wimp_selection* selection)
}
if (pointer.buttons == wimp_CLICK_ADJUST)
- ro_gui_create_menu(current_menu, current_menu_x, current_menu_y, current_gui);
+ {
+ if (current_menu == combo_menu)
+ gui_gadget_combo(current_gui->data.browser.bw, current_gadget, current_menu_x, current_menu_y);
+ else
+ ro_gui_create_menu(current_menu, current_menu_x, current_menu_y, current_gui);
+ }
}
void gui_poll(void)
@@ -1569,7 +1688,12 @@ void gui_poll(void)
case wimp_USER_MESSAGE :
case wimp_USER_MESSAGE_RECORDED :
case wimp_USER_MESSAGE_ACKNOWLEDGE:
- if (block.message.action == message_QUIT)
+ fprintf(stderr, "MESSAGE %d (%x) HAS ARRIVED\n", block.message.action);
+ if (block.message.action == message_DATA_SAVE)
+ ro_msg_datasave(&(block.message));
+ else if (block.message.action == message_DATA_LOAD)
+ ro_msg_dataload(&(block.message));
+ else if (block.message.action == message_QUIT)
netsurf_quit = 1;
break;
}
@@ -1636,3 +1760,278 @@ void gui_window_stop_throbber(gui_window* g)
g->throbber = 0;
wimp_set_icon_state(g->data.browser.toolbar, ro_theme_icon(current_theme, THEME_TOOLBAR, "TOOLBAR_THROBBER"), 0, 0);
}
+
+void gui_gadget_combo(struct browser_window* bw, struct gui_gadget* g, int mx, int my)
+{
+ int count = 0;
+ struct formoption* o;
+ wimp_pointer pointer;
+
+ if (combo_menu != NULL)
+ xfree(combo_menu);
+
+ o = g->data.select.items;
+ while (o != NULL)
+ {
+ count++;
+ o = o->next;
+ }
+
+ combo_menu = xcalloc(1, sizeof(wimp_menu_entry) * count + offsetof(wimp_menu, entries));
+
+ combo_menu->title_data.indirected_text.text = "Select";
+ combo_menu->title_fg = wimp_COLOUR_BLACK;
+ combo_menu->title_bg = wimp_COLOUR_LIGHT_GREY;
+ combo_menu->work_fg = wimp_COLOUR_BLACK;
+ combo_menu->work_bg = wimp_COLOUR_WHITE;
+ combo_menu->width = 0;
+ combo_menu->height = wimp_MENU_ITEM_HEIGHT;
+ combo_menu->gap = wimp_MENU_ITEM_GAP;
+
+ o = g->data.select.items;
+ count = 0;
+ while (o != NULL)
+ {
+ combo_menu->entries[count].menu_flags = 0;
+ if (count == 0)
+ combo_menu->entries[count].menu_flags = wimp_MENU_TITLE_INDIRECTED;
+ if (o->selected)
+ combo_menu->entries[count].menu_flags |= wimp_MENU_TICKED;
+ if (o->next == NULL)
+ combo_menu->entries[count].menu_flags |= wimp_MENU_LAST;
+
+ combo_menu->entries[count].sub_menu = wimp_NO_SUB_MENU;
+ combo_menu->entries[count].icon_flags = wimp_ICON_TEXT | wimp_ICON_INDIRECTED | wimp_ICON_FILLED | wimp_ICON_VCENTRED | (wimp_COLOUR_BLACK << wimp_ICON_FG_COLOUR_SHIFT) | (wimp_COLOUR_WHITE << wimp_ICON_BG_COLOUR_SHIFT) | (wimp_BUTTON_MENU_ICON << wimp_ICON_BUTTON_TYPE_SHIFT);
+ combo_menu->entries[count].data.indirected_text.text = o->text;
+ combo_menu->entries[count].data.indirected_text.validation = "\0";
+ combo_menu->entries[count].data.indirected_text.size = strlen(o->text);
+ count++;
+ o = o->next;
+ }
+
+ wimp_get_pointer_info(&pointer);
+ //wimp_create_menu(combo_menu, pointer.pos.x - 64, pointer.pos.y);
+ current_gadget = g;
+ ro_gui_create_menu(combo_menu, pointer.pos.x - 64, pointer.pos.y, bw->window);
+}
+
+void gui_edit_textarea(struct browser_window* bw, struct gui_gadget* g)
+{
+ FILE* file;
+
+ system("cdir <Wimp$ScrapDir>.NetSurf");
+ file = fopen("<Wimp$Scrapdir>.NetSurf.TextArea", "w");
+ if (g->data.textarea.text != 0)
+ fprintf(file, "%s", g->data.textarea.text);
+ fclose(file);
+
+ system("settype <Wimp$ScrapDir>.NetSurf.TextArea FFF");
+ system("filer_run <Wimp$ScrapDir>.NetSurf.TextArea");
+}
+
+struct msg_datasave {
+ wimp_w w;
+ wimp_i i;
+ os_coord pos;
+ int size;
+ int filetype;
+ char leafname[212];
+};
+
+typedef struct msg_datasave msg_datasave;
+
+void ro_msg_datasave(wimp_message* block)
+{
+ gui_window* gui;
+ struct browser_window* bw;
+ msg_datasave* data;
+ int x,y;
+ struct box_selection* click_boxes;
+ int found, plot_index;
+ int i;
+ int done = 0;
+ wimp_window_state state;
+
+ data = (msg_datasave*)block->data.reserved;
+
+ gui = ro_lookup_gui_from_w(data->w);
+ if (gui == NULL)
+ return;
+
+ bw = gui->data.browser.bw;
+
+ state.w = data->w;
+ wimp_get_window_state(&state);
+ x = browser_x_units(window_x_units(data->pos.x, &state));
+ y = browser_y_units(window_y_units(data->pos.y, &state));
+
+ found = 0;
+ click_boxes = NULL;
+ plot_index = 0;
+
+ box_under_area(bw->current_content->data.html.layout->children,
+ x, 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->gadget != NULL)
+ {
+ if (click_boxes[i].box->gadget->type == GADGET_TEXTAREA && data->filetype == 0xFFF)
+ {
+ /* load the text in! */
+ fprintf(stderr, "REPLYING TO MESSAGE MATE\n");
+ block->action = message_DATA_SAVE_ACK;
+ block->your_ref = block->my_ref;
+ block->my_ref = 0;
+ strcpy(block->data.reserved[24], "<Wimp$Scrap>");
+ wimp_send_message(wimp_USER_MESSAGE, block, block->sender);
+ }
+ }
+ }
+
+ xfree(click_boxes);
+}
+
+void ro_msg_dataload(wimp_message* block)
+{
+ gui_window* gui;
+ struct browser_window* bw;
+ msg_datasave* data;
+ int x,y;
+ struct box_selection* click_boxes;
+ int found, plot_index;
+ int i;
+ int done = 0;
+ wimp_window_state state;
+
+ data = (msg_datasave*)block->data.reserved;
+
+ gui = ro_lookup_gui_from_w(data->w);
+ if (gui == NULL)
+ return;
+
+ bw = gui->data.browser.bw;
+
+ state.w = data->w;
+ wimp_get_window_state(&state);
+ x = browser_x_units(window_x_units(data->pos.x, &state));
+ y = browser_y_units(window_y_units(data->pos.y, &state));
+
+ found = 0;
+ click_boxes = NULL;
+ plot_index = 0;
+
+ box_under_area(bw->current_content->data.html.layout->children,
+ x, 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->gadget != NULL)
+ {
+ if (click_boxes[i].box->gadget->type == GADGET_TEXTAREA && data->filetype == 0xFFF)
+ {
+ /* load the text in! */
+ if (click_boxes[i].box->gadget->data.textarea.text != 0)
+ xfree(click_boxes[i].box->gadget->data.textarea.text);
+ click_boxes[i].box->gadget->data.textarea.text = load(data->leafname);
+ gui_redraw_gadget(bw, click_boxes[i].box->gadget);
+ }
+ }
+ }
+
+ xfree(click_boxes);
+
+}
+
+struct browser_window* current_textbox_bw;
+struct gui_gadget* current_textbox = 0;
+wimp_w current_textbox_w;
+wimp_i current_textbox_i;
+
+void gui_set_gadget_extent(struct box* box, int x, int y, os_box* extent, struct gui_gadget* g)
+{
+ struct box* c;
+ if (box->gadget == g)
+ {
+ extent->x0 = x + box->x * 2;
+ extent->y0 = y - box->y * 2 - box->height * 2;
+ extent->x1 = x + box->x * 2 + box->width * 2;
+ extent->y1 = y - box->y * 2;
+ return;
+ }
+ for (c = box->children; c != 0; c = c->next)
+ if (c->type != BOX_FLOAT_LEFT && c->type != BOX_FLOAT_RIGHT)
+ gui_set_gadget_extent(c, x + box->x * 2, y - box->y * 2, extent, g);
+
+ for (c = box->float_children; c != 0; c = c->next_float)
+ gui_set_gadget_extent(c, x + box->x * 2, y - box->y * 2, extent, g);
+}
+
+void gui_edit_textbox(struct browser_window* bw, struct gui_gadget* g)
+{
+ wimp_icon_create icon;
+ wimp_pointer pointer;
+ wimp_window_state state;
+ int pointer_x;
+ int letter_x;
+ int textbox_x;
+ int offset;
+
+ wimp_get_pointer_info(&pointer);
+
+ if (current_textbox != 0)
+ {
+ wimp_delete_icon(current_textbox_w, current_textbox_i);
+ gui_redraw_gadget(current_textbox_bw, current_textbox);
+ }
+
+ current_textbox_bw = bw;
+ current_textbox_w = bw->window->data.browser.window;
+
+ icon.w = current_textbox_w;
+ gui_set_gadget_extent(bw->current_content->data.html.layout->children, 0, 0, &icon.icon.extent, g);
+ fprintf(stderr, "ICON EXTENT %d %d %d %d\n", icon.icon.extent.x0, icon.icon.extent.y0, icon.icon.extent.x1, icon.icon.extent.y1);
+ icon.icon.flags = wimp_ICON_TEXT | wimp_ICON_BORDER |
+ wimp_ICON_VCENTRED | wimp_ICON_FILLED |
+ wimp_ICON_INDIRECTED |
+ (wimp_COLOUR_BLACK << wimp_ICON_FG_COLOUR_SHIFT) |
+ (wimp_COLOUR_WHITE << wimp_ICON_BG_COLOUR_SHIFT) |
+ (wimp_BUTTON_WRITABLE << wimp_ICON_BUTTON_TYPE_SHIFT);
+ icon.icon.data.indirected_text.text = g->data.textbox.text;
+ icon.icon.data.indirected_text.size = g->data.textbox.maxlength;
+ icon.icon.data.indirected_text.validation = " ";
+ current_textbox_i = wimp_create_icon(&icon);
+ current_textbox = g;
+ gui_redraw_gadget(bw, current_textbox);
+
+ state.w = current_textbox_w;
+ wimp_get_window_state(&state);
+ pointer_x = window_x_units(pointer.pos.x, &state);
+ textbox_x = icon.icon.extent.x0;
+ offset = strlen(g->data.textbox.text);
+ while (offset > 0)
+ {
+ letter_x = wimptextop_string_width(g->data.textbox.text, offset);
+ if (letter_x < pointer_x - textbox_x)
+ break;
+ offset--;
+ }
+
+ wimp_set_caret_position(current_textbox_w, current_textbox_i, 0,0,-1, offset);
+}
+
+void gui_remove_gadget(struct gui_gadget* g)
+{
+ if (g == current_textbox && g != 0)
+ {
+ wimp_delete_icon(current_textbox_w, current_textbox_i);
+ gui_redraw_gadget(current_textbox_bw, current_textbox);
+ current_textbox = 0;
+ }
+}
diff --git a/riscos/gui.h b/riscos/gui.h
index 2ef75af0a..14716eac8 100644
--- a/riscos/gui.h
+++ b/riscos/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_RISCOS_GUI_H_
@@ -47,5 +47,6 @@ void ro_gui_window_click(gui_window* g, wimp_pointer* mouse);
void ro_gui_window_open(gui_window* g, wimp_open* open);
void ro_gui_window_redraw(gui_window* g, wimp_draw* redraw);
//void ro_gui_window_keypress(gui_window* g, wimp_key* key);
+void gui_remove_gadget(struct gui_gadget* g);
#endif