mirror of
https://github.com/netsurf-browser/netsurf
synced 2024-12-25 21:46:57 +03:00
HTML drags now go via content msg.
This commit is contained in:
parent
9ec663f3a9
commit
4747bbbfb2
@ -78,7 +78,8 @@ typedef enum {
|
||||
CONTENT_MSG_SCROLL, /**< Request to scroll content */
|
||||
CONTENT_MSG_DRAGSAVE, /**< Allow drag saving of content */
|
||||
CONTENT_MSG_SAVELINK, /**< Allow URL to be saved */
|
||||
CONTENT_MSG_POINTER /**< Wants a specific mouse pointer set */
|
||||
CONTENT_MSG_POINTER, /**< Wants a specific mouse pointer set */
|
||||
CONTENT_MSG_DRAG /**< A drag started or ended */
|
||||
} content_msg;
|
||||
|
||||
/** RFC5988 metadata link */
|
||||
@ -152,14 +153,15 @@ union content_msg_data {
|
||||
} savelink;
|
||||
/** CONTENT_MSG_POINTER - Mouse pointer to set */
|
||||
browser_pointer_shape pointer;
|
||||
/** CONTENT_MSG_PASTE - Content requests that clipboard is pasted */
|
||||
/** CONTENT_MSG_DRAG - Drag start or end */
|
||||
struct {
|
||||
/* TODO: Get rid of these coords.
|
||||
* browser_window_paste_text doesn't take coords, but
|
||||
* RISC OS front end is doing something different. */
|
||||
int x;
|
||||
int y;
|
||||
} paste;
|
||||
enum {
|
||||
CONTENT_DRAG_NONE,
|
||||
CONTENT_DRAG_SCROLL,
|
||||
CONTENT_DRAG_SELECTION
|
||||
} type;
|
||||
const struct rect *rect;
|
||||
} drag;
|
||||
};
|
||||
|
||||
/** parameters to content redraw */
|
||||
|
@ -1545,6 +1545,25 @@ nserror browser_window_callback(hlcache_handle *c,
|
||||
browser_window_set_pointer(bw, event->data.pointer);
|
||||
break;
|
||||
|
||||
case CONTENT_MSG_DRAG:
|
||||
{
|
||||
browser_drag_type bdt = DRAGGING_NONE;
|
||||
|
||||
switch (event->data.drag.type) {
|
||||
case CONTENT_DRAG_NONE:
|
||||
bdt = DRAGGING_NONE;
|
||||
break;
|
||||
case CONTENT_DRAG_SCROLL:
|
||||
bdt = DRAGGING_SELECTION;
|
||||
break;
|
||||
case CONTENT_DRAG_SELECTION:
|
||||
bdt = DRAGGING_CONTENT_SCROLLBAR;
|
||||
break;
|
||||
}
|
||||
browser_window_set_drag_type(bw, bdt, event->data.drag.rect);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
@ -57,8 +57,6 @@ typedef enum {
|
||||
DRAGGING_SCR_X,
|
||||
DRAGGING_SCR_Y,
|
||||
DRAGGING_CONTENT_SCROLLBAR,
|
||||
DRAGGING_CONTENT_TEXTAREA_SCROLLBAR,
|
||||
DRAGGING_CONTENT_TEXTAREA_SELECTION,
|
||||
DRAGGING_OTHER
|
||||
} browser_drag_type;
|
||||
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include "render/box_textarea.h"
|
||||
#include "render/font.h"
|
||||
#include "render/form.h"
|
||||
#include "utils/log.h"
|
||||
|
||||
|
||||
static bool box_textarea_browser_caret_callback(struct browser_window *bw,
|
||||
@ -124,23 +125,20 @@ static bool box_textarea_browser_paste_callback(struct browser_window *bw,
|
||||
static void box_textarea_callback(void *data, struct textarea_msg *msg)
|
||||
{
|
||||
struct form_textarea_data *d = data;
|
||||
struct content *c = (struct content *)d->html;
|
||||
struct html_content *html = d->html;
|
||||
struct form_control *gadget = d->gadget;
|
||||
struct box *box = gadget->box;
|
||||
union content_msg_data msg_data;
|
||||
|
||||
switch (msg->type) {
|
||||
case TEXTAREA_MSG_DRAG_REPORT:
|
||||
if (msg->data.drag == TEXTAREA_DRAG_NONE) {
|
||||
/* Textarea drag finished */
|
||||
html->textarea = NULL;
|
||||
html_drag_type drag_type = HTML_DRAG_NONE;
|
||||
union html_drag_owner drag_owner;
|
||||
drag_owner.no_owner = true;
|
||||
|
||||
browser_window_set_drag_type(html->bw,
|
||||
DRAGGING_NONE, NULL);
|
||||
|
||||
msg_data.pointer = BROWSER_POINTER_AUTO;
|
||||
content_broadcast(c, CONTENT_MSG_POINTER, msg_data);
|
||||
html_set_drag_type(d->html, drag_type, drag_owner,
|
||||
NULL);
|
||||
} else {
|
||||
/* Textarea drag started */
|
||||
struct rect rect = {
|
||||
@ -149,16 +147,25 @@ static void box_textarea_callback(void *data, struct textarea_msg *msg)
|
||||
.x1 = INT_MAX,
|
||||
.y1 = INT_MAX
|
||||
};
|
||||
browser_drag_type bdt;
|
||||
html_drag_type drag_type;
|
||||
union html_drag_owner drag_owner;
|
||||
drag_owner.textarea = box;
|
||||
|
||||
if (msg->data.drag == TEXTAREA_DRAG_SCROLLBAR)
|
||||
bdt = DRAGGING_CONTENT_TEXTAREA_SCROLLBAR;
|
||||
else
|
||||
bdt = DRAGGING_CONTENT_TEXTAREA_SELECTION;
|
||||
switch (msg->data.drag) {
|
||||
case TEXTAREA_DRAG_SCROLLBAR:
|
||||
drag_type = HTML_DRAG_TEXTAREA_SCROLLBAR;
|
||||
break;
|
||||
case TEXTAREA_DRAG_SELECTION:
|
||||
drag_type = HTML_DRAG_TEXTAREA_SELECTION;
|
||||
break;
|
||||
default:
|
||||
LOG(("Drag type not handled."));
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
|
||||
browser_window_set_drag_type(html->bw, bdt, &rect);
|
||||
|
||||
html->textarea = msg->ta;
|
||||
html_set_drag_type(d->html, drag_type, drag_owner,
|
||||
&rect);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -343,8 +343,8 @@ html_create_html_data(html_content *c, const http_parameter *params)
|
||||
c->iframe = NULL;
|
||||
c->page = NULL;
|
||||
c->font_func = &nsfont;
|
||||
c->scrollbar = NULL;
|
||||
c->textarea = NULL;
|
||||
c->drag_type = HTML_DRAG_NONE;
|
||||
c->drag_owner.no_owner = true;
|
||||
c->scripts_count = 0;
|
||||
c->scripts = NULL;
|
||||
c->jscontext = NULL;
|
||||
@ -1308,6 +1308,29 @@ html_object_callback(hlcache_handle *object,
|
||||
content_broadcast(&c->base, event->type, event->data);
|
||||
break;
|
||||
|
||||
case CONTENT_MSG_DRAG:
|
||||
{
|
||||
html_drag_type drag_type = HTML_DRAG_NONE;
|
||||
union html_drag_owner drag_owner;
|
||||
drag_owner.content = box;
|
||||
|
||||
switch (event->data.drag.type) {
|
||||
case CONTENT_DRAG_NONE:
|
||||
drag_type = HTML_DRAG_NONE;
|
||||
drag_owner.no_owner = true;
|
||||
break;
|
||||
case CONTENT_DRAG_SCROLL:
|
||||
drag_type = HTML_DRAG_CONTENT_SCROLL;
|
||||
break;
|
||||
case CONTENT_DRAG_SELECTION:
|
||||
drag_type = HTML_DRAG_CONTENT_SELECTION;
|
||||
break;
|
||||
}
|
||||
html_set_drag_type(c, drag_type, drag_owner,
|
||||
event->data.drag.rect);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
@ -224,9 +224,10 @@ void html_mouse_track(struct content *c, struct browser_window *bw,
|
||||
browser_mouse_state mouse, int x, int y)
|
||||
{
|
||||
html_content *html = (html_content*) c;
|
||||
browser_drag_type drag_type = browser_window_get_drag_type(bw);
|
||||
union html_drag_owner drag_owner;
|
||||
|
||||
if (drag_type == DRAGGING_SELECTION && !mouse) {
|
||||
if (html->drag_type == HTML_DRAG_SELECTION && !mouse) {
|
||||
/* End of selection drag */
|
||||
int dir = -1;
|
||||
size_t idx;
|
||||
|
||||
@ -238,40 +239,37 @@ void html_mouse_track(struct content *c, struct browser_window *bw,
|
||||
if (idx != 0)
|
||||
selection_track(&html->sel, mouse, idx);
|
||||
|
||||
browser_window_set_drag_type(bw, DRAGGING_NONE, NULL);
|
||||
drag_owner.no_owner = true;
|
||||
html_set_drag_type(html, HTML_DRAG_NONE, drag_owner, NULL);
|
||||
}
|
||||
|
||||
switch (drag_type) {
|
||||
case DRAGGING_SELECTION: {
|
||||
struct box *box;
|
||||
int dir = -1;
|
||||
int dx, dy;
|
||||
if (html->drag_type == HTML_DRAG_SELECTION) {
|
||||
/* Selection drag */
|
||||
struct box *box;
|
||||
int dir = -1;
|
||||
int dx, dy;
|
||||
|
||||
if (selection_dragging_start(&html->sel))
|
||||
dir = 1;
|
||||
if (selection_dragging_start(&html->sel))
|
||||
dir = 1;
|
||||
|
||||
box = box_pick_text_box(html, x, y, dir, &dx, &dy);
|
||||
box = box_pick_text_box(html, x, y, dir, &dx, &dy);
|
||||
|
||||
if (box) {
|
||||
int pixel_offset;
|
||||
size_t idx;
|
||||
plot_font_style_t fstyle;
|
||||
if (box != NULL) {
|
||||
int pixel_offset;
|
||||
size_t idx;
|
||||
plot_font_style_t fstyle;
|
||||
|
||||
font_plot_style_from_css(box->style, &fstyle);
|
||||
font_plot_style_from_css(box->style, &fstyle);
|
||||
|
||||
nsfont.font_position_in_string(&fstyle,
|
||||
box->text, box->length,
|
||||
dx, &idx, &pixel_offset);
|
||||
nsfont.font_position_in_string(&fstyle,
|
||||
box->text, box->length,
|
||||
dx, &idx, &pixel_offset);
|
||||
|
||||
selection_track(&html->sel, mouse,
|
||||
box->byte_offset + idx);
|
||||
}
|
||||
selection_track(&html->sel, mouse,
|
||||
box->byte_offset + idx);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
html_mouse_action(c, bw, mouse, x, y);
|
||||
break;
|
||||
} else {
|
||||
html_mouse_action(c, bw, mouse, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
@ -356,29 +354,30 @@ void html_mouse_action(struct content *c, struct browser_window *bw,
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mouse && html->scrollbar != NULL) {
|
||||
/* drag end: scrollbar */
|
||||
html_overflow_scroll_drag_end(html->scrollbar, mouse, x, y);
|
||||
}
|
||||
if (html->drag_type == HTML_DRAG_SCROLLBAR) {
|
||||
struct scrollbar *scr = html->drag_owner.scrollbar;
|
||||
struct html_scrollbar_data *data = scrollbar_get_data(scr);
|
||||
|
||||
if (!mouse) {
|
||||
/* drag end: scrollbar */
|
||||
html_overflow_scroll_drag_end(scr, mouse, x, y);
|
||||
}
|
||||
|
||||
if (html->scrollbar != NULL) {
|
||||
struct html_scrollbar_data *data =
|
||||
scrollbar_get_data(html->scrollbar);
|
||||
box = data->box;
|
||||
box_coords(box, &box_x, &box_y);
|
||||
if (scrollbar_is_horizontal(html->scrollbar)) {
|
||||
if (scrollbar_is_horizontal(scr)) {
|
||||
scroll_mouse_x = x - box_x ;
|
||||
scroll_mouse_y = y - (box_y + box->padding[TOP] +
|
||||
box->height + box->padding[BOTTOM] -
|
||||
SCROLLBAR_WIDTH);
|
||||
status = scrollbar_mouse_action(html->scrollbar, mouse,
|
||||
status = scrollbar_mouse_action(scr, mouse,
|
||||
scroll_mouse_x, scroll_mouse_y);
|
||||
} else {
|
||||
scroll_mouse_x = x - (box_x + box->padding[LEFT] +
|
||||
box->width + box->padding[RIGHT] -
|
||||
SCROLLBAR_WIDTH);
|
||||
scroll_mouse_y = y - box_y;
|
||||
status = scrollbar_mouse_action(html->scrollbar, mouse,
|
||||
status = scrollbar_mouse_action(scr, mouse,
|
||||
scroll_mouse_x, scroll_mouse_y);
|
||||
}
|
||||
|
||||
@ -387,8 +386,35 @@ void html_mouse_action(struct content *c, struct browser_window *bw,
|
||||
return;
|
||||
}
|
||||
|
||||
if (html->drag_type == HTML_DRAG_TEXTAREA_SELECTION ||
|
||||
html->drag_type == HTML_DRAG_TEXTAREA_SCROLLBAR) {
|
||||
box = html->drag_owner.textarea;
|
||||
assert(box->gadget != NULL);
|
||||
assert(box->gadget->type == GADGET_TEXTAREA ||
|
||||
box->gadget->type == GADGET_PASSWORD ||
|
||||
box->gadget->type == GADGET_TEXTBOX);
|
||||
|
||||
box_coords(box, &box_x, &box_y);
|
||||
textarea_mouse_action(box->gadget->data.text.ta, mouse,
|
||||
x - box_x, y - box_y);
|
||||
|
||||
/* TODO: Set appropriate statusbar message */
|
||||
return;
|
||||
}
|
||||
|
||||
if (html->drag_type == HTML_DRAG_CONTENT_SELECTION ||
|
||||
html->drag_type == HTML_DRAG_CONTENT_SCROLL) {
|
||||
box = html->drag_owner.content;
|
||||
assert(box->object != NULL);
|
||||
|
||||
box_coords(box, &box_x, &box_y);
|
||||
content_mouse_track(box->object, bw, mouse,
|
||||
x - box_x, y - box_y);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Content related drags handled by now */
|
||||
browser_window_set_drag_type(bw, DRAGGING_NONE, NULL);
|
||||
assert(html->drag_type == HTML_DRAG_NONE);
|
||||
|
||||
/* search the box tree for a link, imagemap, form control, or
|
||||
* box with scrollbars
|
||||
@ -734,11 +760,16 @@ void html_mouse_action(struct content *c, struct browser_window *bw,
|
||||
/* key presses must be directed at the
|
||||
* main browser window, paste text
|
||||
* operations ignored */
|
||||
html_drag_type drag_type;
|
||||
union html_drag_owner drag_owner;
|
||||
|
||||
if (selection_dragging(&html->sel)) {
|
||||
browser_window_set_drag_type(bw,
|
||||
DRAGGING_SELECTION,
|
||||
NULL);
|
||||
drag_type = HTML_DRAG_SELECTION;
|
||||
drag_owner.no_owner = true;
|
||||
html_set_drag_type(html,
|
||||
drag_type,
|
||||
drag_owner,
|
||||
NULL);
|
||||
status = messages_get(
|
||||
"Selecting");
|
||||
}
|
||||
@ -845,35 +876,34 @@ void html_overflow_scroll_callback(void *client_data,
|
||||
html_content *html = (html_content *)data->c;
|
||||
struct box *box = data->box;
|
||||
union content_msg_data msg_data;
|
||||
html_drag_type drag_type;
|
||||
union html_drag_owner drag_owner;
|
||||
|
||||
switch(scrollbar_data->msg) {
|
||||
case SCROLLBAR_MSG_MOVED:
|
||||
html__redraw_a_box(html, box);
|
||||
break;
|
||||
case SCROLLBAR_MSG_SCROLL_START:
|
||||
{
|
||||
struct rect rect = {
|
||||
.x0 = scrollbar_data->x0,
|
||||
.y0 = scrollbar_data->y0,
|
||||
.x1 = scrollbar_data->x1,
|
||||
.y1 = scrollbar_data->y1
|
||||
};
|
||||
browser_window_set_drag_type(html->bw,
|
||||
DRAGGING_CONTENT_SCROLLBAR, &rect);
|
||||
case SCROLLBAR_MSG_MOVED:
|
||||
html__redraw_a_box(html, box);
|
||||
break;
|
||||
case SCROLLBAR_MSG_SCROLL_START:
|
||||
{
|
||||
struct rect rect = {
|
||||
.x0 = scrollbar_data->x0,
|
||||
.y0 = scrollbar_data->y0,
|
||||
.x1 = scrollbar_data->x1,
|
||||
.y1 = scrollbar_data->y1
|
||||
};
|
||||
drag_type = HTML_DRAG_SCROLLBAR;
|
||||
drag_owner.scrollbar = scrollbar_data->scrollbar;
|
||||
html_set_drag_type(html, drag_type, drag_owner, &rect);
|
||||
}
|
||||
break;
|
||||
case SCROLLBAR_MSG_SCROLL_FINISHED:
|
||||
drag_type = HTML_DRAG_NONE;
|
||||
drag_owner.no_owner = true;
|
||||
html_set_drag_type(html, drag_type, drag_owner, NULL);
|
||||
|
||||
html->scrollbar = scrollbar_data->scrollbar;
|
||||
}
|
||||
break;
|
||||
case SCROLLBAR_MSG_SCROLL_FINISHED:
|
||||
html->scrollbar = NULL;
|
||||
|
||||
browser_window_set_drag_type(html->bw,
|
||||
DRAGGING_NONE, NULL);
|
||||
|
||||
msg_data.pointer = BROWSER_POINTER_AUTO;
|
||||
content_broadcast(data->c, CONTENT_MSG_POINTER,
|
||||
msg_data);
|
||||
break;
|
||||
msg_data.pointer = BROWSER_POINTER_AUTO;
|
||||
content_broadcast(data->c, CONTENT_MSG_POINTER, msg_data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -912,3 +942,39 @@ void html_overflow_scroll_drag_end(struct scrollbar *scrollbar,
|
||||
scroll_mouse_x, scroll_mouse_y);
|
||||
}
|
||||
}
|
||||
|
||||
void html_set_drag_type(html_content *html, html_drag_type drag_type,
|
||||
union html_drag_owner drag_owner, const struct rect *rect)
|
||||
{
|
||||
union content_msg_data msg_data;
|
||||
|
||||
assert(html != NULL);
|
||||
|
||||
html->drag_type = drag_type;
|
||||
html->drag_owner = drag_owner;
|
||||
|
||||
switch (drag_type) {
|
||||
case HTML_DRAG_NONE:
|
||||
assert(drag_owner.no_owner == true);
|
||||
msg_data.drag.type = CONTENT_DRAG_NONE;
|
||||
break;
|
||||
|
||||
case HTML_DRAG_SCROLLBAR:
|
||||
case HTML_DRAG_TEXTAREA_SCROLLBAR:
|
||||
case HTML_DRAG_CONTENT_SCROLL:
|
||||
msg_data.drag.type = CONTENT_DRAG_SCROLL;
|
||||
break;
|
||||
|
||||
case HTML_DRAG_SELECTION:
|
||||
assert(drag_owner.no_owner == true);
|
||||
/* Fall through */
|
||||
case HTML_DRAG_TEXTAREA_SELECTION:
|
||||
case HTML_DRAG_CONTENT_SELECTION:
|
||||
msg_data.drag.type = CONTENT_DRAG_SELECTION;
|
||||
break;
|
||||
}
|
||||
msg_data.drag.rect = rect;
|
||||
|
||||
/* Inform the content's drag status change */
|
||||
content_broadcast((struct content *)html, CONTENT_MSG_DRAG, msg_data);
|
||||
}
|
||||
|
@ -27,6 +27,22 @@
|
||||
#include "desktop/selection.h"
|
||||
#include "render/html.h"
|
||||
|
||||
typedef enum {
|
||||
HTML_DRAG_NONE, /** No drag */
|
||||
HTML_DRAG_SELECTION, /** Own; Text selection */
|
||||
HTML_DRAG_SCROLLBAR, /** Not own; drag in scrollbar widget */
|
||||
HTML_DRAG_TEXTAREA_SELECTION, /** Not own; drag in textarea widget */
|
||||
HTML_DRAG_TEXTAREA_SCROLLBAR, /** Not own; drag in textarea widget */
|
||||
HTML_DRAG_CONTENT_SELECTION, /** Not own; drag in child content */
|
||||
HTML_DRAG_CONTENT_SCROLL /** Not own; drag in child content */
|
||||
} html_drag_type;
|
||||
union html_drag_owner {
|
||||
bool no_owner;
|
||||
struct box *content;
|
||||
struct scrollbar *scrollbar;
|
||||
struct box *textarea;
|
||||
}; /**< For drags we don't own */
|
||||
|
||||
/** Data specific to CONTENT_HTML. */
|
||||
typedef struct html_content {
|
||||
struct content base;
|
||||
@ -98,13 +114,10 @@ typedef struct html_content {
|
||||
* object within a page. */
|
||||
struct html_content *page;
|
||||
|
||||
/** Scrollbar capturing all mouse events, updated to any active HTML
|
||||
* scrollbar, or NULL when no scrollbar drags active */
|
||||
struct scrollbar *scrollbar;
|
||||
|
||||
/** Textarea capturing all mouse events, updated to any active HTML
|
||||
* textarea, or NULL when no textarea drags active */
|
||||
struct textarea *textarea;
|
||||
/* Current drag type */
|
||||
html_drag_type drag_type;
|
||||
/** Widget capturing all mouse events */
|
||||
union html_drag_owner drag_owner;
|
||||
|
||||
/** Open core-handled form SELECT menu,
|
||||
* or NULL if none currently open. */
|
||||
@ -128,6 +141,9 @@ void html_set_status(html_content *c, const char *extra);
|
||||
|
||||
void html__redraw_a_box(html_content *html, struct box *box);
|
||||
|
||||
void html_set_drag_type(html_content *html, html_drag_type drag_type,
|
||||
union html_drag_owner drag_owner, const struct rect *rect);
|
||||
|
||||
struct browser_window *html_get_browser_window(struct content *c);
|
||||
struct search_context *html_get_search(struct content *c);
|
||||
void html_set_search(struct content *c, struct search_context *s);
|
||||
|
Loading…
Reference in New Issue
Block a user