summaryrefslogtreecommitdiff
path: root/render
diff options
context:
space:
mode:
Diffstat (limited to 'render')
-rw-r--r--render/box_textarea.c43
-rw-r--r--render/html.c27
-rw-r--r--render/html_interaction.c200
-rw-r--r--render/html_internal.h30
4 files changed, 206 insertions, 94 deletions
diff --git a/render/box_textarea.c b/render/box_textarea.c
index f5a45ec94..2bbeab31e 100644
--- a/render/box_textarea.c
+++ b/render/box_textarea.c
@@ -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;
-
- if (msg->data.drag == TEXTAREA_DRAG_SCROLLBAR)
- bdt = DRAGGING_CONTENT_TEXTAREA_SCROLLBAR;
- else
- bdt = DRAGGING_CONTENT_TEXTAREA_SELECTION;
-
- browser_window_set_drag_type(html->bw, bdt, &rect);
-
- html->textarea = msg->ta;
+ html_drag_type drag_type;
+ union html_drag_owner drag_owner;
+ drag_owner.textarea = box;
+
+ 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;
+ }
+
+ html_set_drag_type(d->html, drag_type, drag_owner,
+ &rect);
}
break;
diff --git a/render/html.c b/render/html.c
index 85e377095..c135db198 100644
--- a/render/html.c
+++ b/render/html.c
@@ -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);
}
diff --git a/render/html_interaction.c b/render/html_interaction.c
index b66868257..c33d654a7 100644
--- a/render/html_interaction.c
+++ b/render/html_interaction.c
@@ -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);
-
- html->scrollbar = scrollbar_data->scrollbar;
- }
- break;
- case SCROLLBAR_MSG_SCROLL_FINISHED:
- html->scrollbar = NULL;
-
- browser_window_set_drag_type(html->bw,
- DRAGGING_NONE, NULL);
+ 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);
- 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);
+}
diff --git a/render/html_internal.h b/render/html_internal.h
index d09121675..85f3f8a70 100644
--- a/render/html_internal.h
+++ b/render/html_internal.h
@@ -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);