[project @ 2004-05-03 22:05:40 by bursa]
Implement dragging files into <input type="file" ...>. svn path=/import/netsurf/; revision=821
This commit is contained in:
parent
24c57d3215
commit
8da6079f6f
|
@ -65,6 +65,10 @@ input[type=image] { background-color: #ddd; color: #000; width: auto;
|
|||
height: auto; }
|
||||
input[type=checkbox], input[type=radio] { background-color: transparent;
|
||||
padding: 0 0.1em; border: 0; width: 1em; height: 1em; }
|
||||
input[type=file] { background-color: #ddd; color: #000;
|
||||
border-width: medium; border-color: #aaa #eee #eee #aaa;
|
||||
border-style: inset; width: 10em; height: 1.5em;
|
||||
font-style: italic; }
|
||||
|
||||
[align=left] { text-align: left; }
|
||||
[align=center] { text-align: center; }
|
||||
|
|
|
@ -48,6 +48,7 @@ Form_Submit:Submit
|
|||
Form_Reset:Reset
|
||||
Form_None:
|
||||
Form_Many:(Many)
|
||||
Form_Drop:Drop file here
|
||||
|
||||
Not2xx:Server returned an error
|
||||
|
||||
|
|
|
@ -39,6 +39,7 @@ Form_Submit:Soumettre
|
|||
Form_Reset:Effacer
|
||||
Form_None:
|
||||
Form_Many:(Plusieurs)
|
||||
Form_Drop:Drop file here
|
||||
|
||||
Not2xx:Le serveur a renvoyé une erreur
|
||||
|
||||
|
|
|
@ -663,7 +663,6 @@ int browser_window_gadget_click(struct browser_window* bw, unsigned long click_x
|
|||
break;
|
||||
case GADGET_TEXTBOX:
|
||||
case GADGET_PASSWORD:
|
||||
case GADGET_FILE:
|
||||
browser_window_input_click(bw,
|
||||
(unsigned int)click_boxes[i].actual_x,
|
||||
(unsigned int)click_boxes[i].actual_y,
|
||||
|
@ -682,6 +681,8 @@ int browser_window_gadget_click(struct browser_window* bw, unsigned long click_x
|
|||
break;
|
||||
case GADGET_RESET:
|
||||
break;
|
||||
case GADGET_FILE:
|
||||
break;
|
||||
}
|
||||
|
||||
xfree(click_boxes);
|
||||
|
@ -1188,8 +1189,7 @@ void browser_window_input_callback(struct browser_window *bw, char key, void *p)
|
|||
for (next_input = input->gadget->next;
|
||||
next_input != 0 && next_input->type != GADGET_TEXTBOX &&
|
||||
next_input->type != GADGET_TEXTAREA &&
|
||||
next_input->type != GADGET_PASSWORD &&
|
||||
next_input->type != GADGET_FILE;
|
||||
next_input->type != GADGET_PASSWORD;
|
||||
next_input = next_input->next)
|
||||
;
|
||||
if (!next_input) return;
|
||||
|
@ -1216,8 +1216,7 @@ void browser_window_input_callback(struct browser_window *bw, char key, void *p)
|
|||
for (prev_input = input->gadget->prev;
|
||||
prev_input != 0 && prev_input->type != GADGET_TEXTBOX &&
|
||||
prev_input->type != GADGET_TEXTAREA &&
|
||||
prev_input->type != GADGET_PASSWORD &&
|
||||
prev_input->type != GADGET_FILE;
|
||||
prev_input->type != GADGET_PASSWORD;
|
||||
prev_input = prev_input->prev)
|
||||
;
|
||||
if (!prev_input) return;
|
||||
|
@ -1548,8 +1547,7 @@ void browser_window_follow_link(struct browser_window *bw,
|
|||
if (click_type == 0 && click_boxes[i].box->gadget != NULL) {
|
||||
if (click_boxes[i].box->gadget->type == GADGET_TEXTBOX ||
|
||||
click_boxes[i].box->gadget->type == GADGET_TEXTAREA ||
|
||||
click_boxes[i].box->gadget->type == GADGET_PASSWORD ||
|
||||
click_boxes[i].box->gadget->type == GADGET_FILE) {
|
||||
click_boxes[i].box->gadget->type == GADGET_PASSWORD) {
|
||||
pointer = GUI_POINTER_CARET;
|
||||
done = 1;
|
||||
break;
|
||||
|
|
71
render/box.c
71
render/box.c
|
@ -76,7 +76,7 @@ static struct result box_select(xmlNode *n, struct status *status,
|
|||
static struct result box_input(xmlNode *n, struct status *status,
|
||||
struct css_style *style);
|
||||
static struct box *box_input_text(xmlNode *n, struct status *status,
|
||||
struct css_style *style, bool password, bool file);
|
||||
struct css_style *style, bool password);
|
||||
static struct result box_button(xmlNode *n, struct status *status,
|
||||
struct css_style *style);
|
||||
static struct result box_frameset(xmlNode *n, struct status *status,
|
||||
|
@ -607,8 +607,8 @@ struct css_style * box_get_style(struct content ** stylesheet,
|
|||
if (0 < size) {
|
||||
char *type = (char *) xmlGetProp(n, (const xmlChar *) "type");
|
||||
style->width.width = CSS_WIDTH_LENGTH;
|
||||
if (!type || stricmp(type, "text") == 0 ||
|
||||
stricmp(type, "password") == 0)
|
||||
if (!type || strcasecmp(type, "text") == 0 ||
|
||||
strcasecmp(type, "password") == 0)
|
||||
/* in characters for text or password */
|
||||
style->width.value.length.unit = CSS_UNIT_EX;
|
||||
else
|
||||
|
@ -1050,36 +1050,30 @@ struct result box_input(xmlNode *n, struct status *status,
|
|||
|
||||
type = (char *) xmlGetProp(n, (const xmlChar *) "type");
|
||||
|
||||
/* the default type is "text" */
|
||||
if (type == 0 || stricmp(type, "text") == 0)
|
||||
{
|
||||
box = box_input_text(n, status, style, false, false);
|
||||
if (type && strcasecmp(type, "password") == 0) {
|
||||
box = box_input_text(n, status, style, true);
|
||||
gadget = box->gadget;
|
||||
gadget->box = box;
|
||||
}
|
||||
else if (stricmp(type, "password") == 0)
|
||||
{
|
||||
box = box_input_text(n, status, style, true, false);
|
||||
gadget = box->gadget;
|
||||
|
||||
} else if (type && strcasecmp(type, "file") == 0) {
|
||||
box = box_create(style, NULL, 0,
|
||||
status->content->data.html.box_pool);
|
||||
box->type = BOX_INLINE_BLOCK;
|
||||
box->gadget = gadget = xcalloc(1, sizeof(struct form_control));
|
||||
gadget->box = box;
|
||||
}
|
||||
else if (stricmp(type, "file") == 0)
|
||||
{
|
||||
box = box_input_text(n, status, style, false, true);
|
||||
gadget = box->gadget;
|
||||
gadget->box = box;
|
||||
}
|
||||
else if (stricmp(type, "hidden") == 0)
|
||||
{
|
||||
gadget->type = GADGET_FILE;
|
||||
box->font = font_open(status->content->data.html.fonts, style);
|
||||
|
||||
} else if (type && strcasecmp(type, "hidden") == 0) {
|
||||
/* no box for hidden inputs */
|
||||
gadget = xcalloc(1, sizeof(struct form_control));
|
||||
gadget->type = GADGET_HIDDEN;
|
||||
|
||||
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "value")))
|
||||
gadget->value = s;
|
||||
}
|
||||
else if (stricmp(type, "checkbox") == 0 || stricmp(type, "radio") == 0)
|
||||
{
|
||||
|
||||
} else if (type && (strcasecmp(type, "checkbox") == 0 ||
|
||||
strcasecmp(type, "radio") == 0)) {
|
||||
box = box_create(style, NULL, 0,
|
||||
status->content->data.html.box_pool);
|
||||
box->gadget = gadget = xcalloc(1, sizeof(struct form_control));
|
||||
|
@ -1099,9 +1093,9 @@ struct result box_input(xmlNode *n, struct status *status,
|
|||
|
||||
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "value")))
|
||||
gadget->value = s;
|
||||
}
|
||||
else if (stricmp(type, "submit") == 0 || stricmp(type, "reset") == 0)
|
||||
{
|
||||
|
||||
} else if (type && (strcasecmp(type, "submit") == 0 ||
|
||||
strcasecmp(type, "reset") == 0)) {
|
||||
struct result result = box_button(n, status, style);
|
||||
struct box *inline_container, *inline_box;
|
||||
box = result.box;
|
||||
|
@ -1122,9 +1116,8 @@ struct result box_input(xmlNode *n, struct status *status,
|
|||
inline_box->font = font_open(status->content->data.html.fonts, style);
|
||||
box_add_child(inline_container, inline_box);
|
||||
box_add_child(box, inline_container);
|
||||
}
|
||||
else if (stricmp(type, "button") == 0)
|
||||
{
|
||||
|
||||
} else if (type && strcasecmp(type, "button") == 0) {
|
||||
struct result result = box_button(n, status, style);
|
||||
struct box *inline_container, *inline_box;
|
||||
box = result.box;
|
||||
|
@ -1145,9 +1138,8 @@ struct result box_input(xmlNode *n, struct status *status,
|
|||
inline_box->font = font_open(status->content->data.html.fonts, style);
|
||||
box_add_child(inline_container, inline_box);
|
||||
box_add_child(box, inline_container);
|
||||
}
|
||||
else if (stricmp(type, "image") == 0)
|
||||
{
|
||||
|
||||
} else if (type && strcasecmp(type, "image") == 0) {
|
||||
box = box_create(style, NULL, 0,
|
||||
status->content->data.html.box_pool);
|
||||
box->gadget = gadget = xcalloc(1, sizeof(struct form_control));
|
||||
|
@ -1160,6 +1152,12 @@ struct result box_input(xmlNode *n, struct status *status,
|
|||
image_types);
|
||||
xmlFree(s);
|
||||
}
|
||||
|
||||
} else {
|
||||
/* the default type is "text" */
|
||||
box = box_input_text(n, status, style, false);
|
||||
gadget = box->gadget;
|
||||
gadget->box = box;
|
||||
}
|
||||
|
||||
if (type != 0)
|
||||
|
@ -1177,7 +1175,7 @@ struct result box_input(xmlNode *n, struct status *status,
|
|||
}
|
||||
|
||||
struct box *box_input_text(xmlNode *n, struct status *status,
|
||||
struct css_style *style, bool password, bool file)
|
||||
struct css_style *style, bool password)
|
||||
{
|
||||
char *s;
|
||||
unsigned int i;
|
||||
|
@ -1214,9 +1212,6 @@ struct box *box_input_text(xmlNode *n, struct status *status,
|
|||
inline_box->text = xcalloc(inline_box->length + 1, 1);
|
||||
for (i = 0; i != inline_box->length; i++)
|
||||
inline_box->text[i] = '*';
|
||||
} else if (file) {
|
||||
box->gadget->type = GADGET_FILE;
|
||||
inline_box->text = xcalloc(inline_box->length + 1, 1);
|
||||
} else {
|
||||
box->gadget->type = GADGET_TEXTBOX;
|
||||
inline_box->text = xstrdup(box->gadget->value);
|
||||
|
@ -2243,7 +2238,7 @@ bool plugin_decode(struct content* content, char* url, struct box* box,
|
|||
/* The java plugin doesn't need the .class extension
|
||||
* so we strip it.
|
||||
*/
|
||||
if(stricmp((&po->classid[strlen(po->classid)-6]),
|
||||
if(strcasecmp((&po->classid[strlen(po->classid)-6]),
|
||||
".class") == 0)
|
||||
po->classid[strlen(po->classid)-6] = 0;
|
||||
}
|
||||
|
|
|
@ -135,7 +135,7 @@ struct form_successful_control *form_successful_controls(struct form *form,
|
|||
continue;
|
||||
|
||||
/* file */
|
||||
if (control->type == GADGET_FILE) {
|
||||
if (control->type == GADGET_FILE && control->value) {
|
||||
success_new = xcalloc(1, sizeof(*success_new));
|
||||
success_new->file = true;
|
||||
success_new->name = xstrdup(control->name);
|
||||
|
|
10
riscos/gui.c
10
riscos/gui.c
|
@ -989,11 +989,13 @@ void ro_msg_datasave(wimp_message* block)
|
|||
void ro_msg_dataload(wimp_message *message)
|
||||
{
|
||||
char *url = 0;
|
||||
gui_window *gui = 0;
|
||||
gui_window *gui;
|
||||
|
||||
if (message->data.data_xfer.w != wimp_ICON_BAR &&
|
||||
(gui = ro_lookup_gui_from_w(message->data.data_xfer.w)) == NULL) {
|
||||
return;
|
||||
gui = ro_lookup_gui_from_w(message->data.data_xfer.w);
|
||||
|
||||
if (gui) {
|
||||
if (ro_gui_window_dataload(gui, message))
|
||||
return;
|
||||
}
|
||||
|
||||
if (message->data.data_xfer.file_type != 0xfaf &&
|
||||
|
|
|
@ -147,6 +147,7 @@ bool ro_gui_window_keypress(gui_window *g, int key, bool toolbar);
|
|||
void ro_gui_scroll_request(wimp_scroll *scroll);
|
||||
int window_x_units(int x, wimp_window_state *state);
|
||||
int window_y_units(int y, wimp_window_state *state);
|
||||
bool ro_gui_window_dataload(gui_window *g, wimp_message *message);
|
||||
|
||||
/* in history.c */
|
||||
void ro_gui_history_init(void);
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "netsurf/render/html.h"
|
||||
#include "netsurf/riscos/gui.h"
|
||||
#include "netsurf/utils/log.h"
|
||||
#include "netsurf/utils/messages.h"
|
||||
#include "netsurf/utils/utils.h"
|
||||
|
||||
|
||||
|
@ -42,6 +43,8 @@ static void html_redraw_checkbox(int x, int y, int width, int height,
|
|||
bool selected);
|
||||
static void html_redraw_radio(int x, int y, int width, int height,
|
||||
bool selected);
|
||||
static void html_redraw_file(int x, int y, int width, int height,
|
||||
struct box *box, float scale);
|
||||
|
||||
bool gui_redraw_debug = false;
|
||||
|
||||
|
@ -231,6 +234,13 @@ void html_redraw_box(struct content *content, struct box * box,
|
|||
width, height,
|
||||
box->gadget->data.radio.selected);
|
||||
|
||||
} else if (box->gadget && box->gadget->type == GADGET_FILE) {
|
||||
colourtrans_set_font_colours(box->font->handle,
|
||||
current_background_color << 8,
|
||||
box->style->color << 8, 14, 0, 0, 0);
|
||||
html_redraw_file(x + padding_left, y - padding_top,
|
||||
width, height, box, scale);
|
||||
|
||||
} else if (box->text && box->font) {
|
||||
|
||||
if (content->data.html.text_selection.selected == 1) {
|
||||
|
@ -499,3 +509,38 @@ void html_redraw_radio(int x, int y, int width, int height,
|
|||
html_redraw_circle(x + width * 0.5, y - height * 0.5,
|
||||
width * 0.3 - 1, os_COLOUR_RED);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Plot a file upload input.
|
||||
*/
|
||||
|
||||
void html_redraw_file(int x, int y, int width, int height,
|
||||
struct box *box, float scale)
|
||||
{
|
||||
int text_width;
|
||||
const char *text;
|
||||
const char *sprite;
|
||||
|
||||
if (box->gadget->value) {
|
||||
text = box->gadget->value;
|
||||
sprite = "file_fff";
|
||||
} else {
|
||||
text = messages_get("Form_Drop");
|
||||
sprite = "drophere";
|
||||
}
|
||||
|
||||
text_width = font_width(box->font, text, strlen(text)) * 2 * scale;
|
||||
if (width < text_width + 8)
|
||||
x = x + width - text_width - 4;
|
||||
else
|
||||
x = x + 4;
|
||||
|
||||
font_paint(box->font->handle, text,
|
||||
font_OS_UNITS | font_GIVEN_FONT |
|
||||
font_KERN | font_GIVEN_TRFM,
|
||||
x, y - height * 0.75, 0, &trfm, 0);
|
||||
|
||||
/* xwimpspriteop_put_sprite_user_coords(sprite, x + 4, */
|
||||
/* y - height / 2 - 17, os_ACTION_OVERWRITE); */
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "netsurf/riscos/save_draw.h"
|
||||
#include "netsurf/riscos/theme.h"
|
||||
#include "netsurf/riscos/thumbnail.h"
|
||||
#include "netsurf/render/form.h"
|
||||
#include "netsurf/utils/log.h"
|
||||
#include "netsurf/utils/url.h"
|
||||
#include "netsurf/utils/utils.h"
|
||||
|
@ -1003,3 +1004,73 @@ int window_y_units(int y, wimp_window_state *state)
|
|||
{
|
||||
return y - (state->visible.y1 - state->yscroll);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Handle Message_DataLoad (file dragged in) for a window.
|
||||
*
|
||||
* \param g window
|
||||
* \param message Message_DataLoad block
|
||||
* \return true if the load was processed
|
||||
*
|
||||
* If the file was dragged into a form file input, it is used as the value.
|
||||
*/
|
||||
|
||||
bool ro_gui_window_dataload(gui_window *g, wimp_message *message)
|
||||
{
|
||||
struct browser_window *bw = g->data.browser.bw;
|
||||
struct box_selection *click_boxes = 0;
|
||||
int x, y;
|
||||
int i;
|
||||
int found = 0;
|
||||
int plot_index = 0;
|
||||
wimp_window_state state;
|
||||
|
||||
/* HTML content only. */
|
||||
if (!bw->current_content || bw->current_content->type != CONTENT_HTML)
|
||||
return false;
|
||||
|
||||
/* Ignore directories etc. */
|
||||
if (0x1000 <= message->data.data_xfer.file_type)
|
||||
return false;
|
||||
|
||||
/* Search for a file input at the drop point. */
|
||||
state.w = message->data.data_xfer.w;
|
||||
wimp_get_window_state(&state);
|
||||
x = window_x_units(message->data.data_xfer.pos.x, &state) / 2;
|
||||
y = -window_y_units(message->data.data_xfer.pos.y, &state) / 2;
|
||||
|
||||
box_under_area(bw->current_content,
|
||||
bw->current_content->data.html.layout->children,
|
||||
x, y, 0, 0, &click_boxes, &found, &plot_index);
|
||||
if (found == 0)
|
||||
return false;
|
||||
for (i = 0; i != found; i++) {
|
||||
if (click_boxes[i].box->gadget &&
|
||||
click_boxes[i].box->gadget->type ==
|
||||
GADGET_FILE)
|
||||
break;
|
||||
}
|
||||
if (i == found) {
|
||||
free(click_boxes);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Found: update form input. */
|
||||
free(click_boxes[i].box->gadget->value);
|
||||
click_boxes[i].box->gadget->value =
|
||||
strdup(message->data.data_xfer.file_name);
|
||||
|
||||
/* Redraw box. */
|
||||
box_coords(click_boxes[i].box, &x, &y);
|
||||
gui_window_redraw(bw->window, x, y,
|
||||
x + click_boxes[i].box->width,
|
||||
y + click_boxes[i].box->height);
|
||||
|
||||
/* send DataLoadAck */
|
||||
message->action = message_DATA_LOAD_ACK;
|
||||
message->your_ref = message->my_ref;
|
||||
wimp_send_message(wimp_USER_MESSAGE, message, message->sender);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue