Fix pointer shape and status bar messages for textareas and their scrollbars.

This commit is contained in:
Michael Drake 2013-03-11 12:57:33 +00:00
parent f3b515540e
commit 41e4928e25
7 changed files with 188 additions and 58 deletions

View File

@ -2618,8 +2618,10 @@ void browser_window_mouse_track(struct browser_window *bw,
bw->drag_type == DRAGGING_NONE) ||
bw->drag_type == DRAGGING_SCR_X) {
/* Start a scrollbar drag, or continue existing drag */
status = scrollbar_mouse_action(bw->scroll_x, mouse,
scr_x, scr_y);
status = scrollbar_mouse_status_to_message(
scrollbar_mouse_action(
bw->scroll_x, mouse,
scr_x, scr_y));
pointer = BROWSER_POINTER_DEFAULT;
if (status != NULL)
@ -2643,8 +2645,10 @@ void browser_window_mouse_track(struct browser_window *bw,
bw->drag_type == DRAGGING_NONE) ||
bw->drag_type == DRAGGING_SCR_Y) {
/* Start a scrollbar drag, or continue existing drag */
status = scrollbar_mouse_action(bw->scroll_y, mouse,
scr_x, scr_y);
status = scrollbar_mouse_status_to_message(
scrollbar_mouse_action(
bw->scroll_y, mouse,
scr_x, scr_y));
pointer = BROWSER_POINTER_DEFAULT;
if (status != NULL)
@ -2737,8 +2741,10 @@ void browser_window_mouse_click(struct browser_window *bw,
if (scr_x > 0 && scr_x < browser_window_get_scrollbar_len(bw,
true) &&
scr_y > 0 && scr_y < SCROLLBAR_WIDTH) {
status = scrollbar_mouse_action(bw->scroll_x, mouse,
scr_x, scr_y);
status = scrollbar_mouse_status_to_message(
scrollbar_mouse_action(
bw->scroll_x, mouse,
scr_x, scr_y));
pointer = BROWSER_POINTER_DEFAULT;
if (status != NULL)
@ -2758,8 +2764,10 @@ void browser_window_mouse_click(struct browser_window *bw,
if (scr_y > 0 && scr_y < browser_window_get_scrollbar_len(bw,
false) &&
scr_x > 0 && scr_x < SCROLLBAR_WIDTH) {
status = scrollbar_mouse_action(bw->scroll_y, mouse,
scr_x, scr_y);
status = scrollbar_mouse_status_to_message(
scrollbar_mouse_action(
bw->scroll_y, mouse,
scr_x, scr_y));
pointer = BROWSER_POINTER_DEFAULT;
if (status != NULL)

View File

@ -613,12 +613,12 @@ static void scrollbar_drag_start_internal(struct scrollbar *s, int x, int y,
/*
* Exported function. Documented in scrollbar.h
*/
const char *scrollbar_mouse_action(struct scrollbar *s,
scrollbar_mouse_status scrollbar_mouse_action(struct scrollbar *s,
browser_mouse_state mouse, int x, int y)
{
int x0, y0, x1, y1;
int val;
const char *status;
scrollbar_mouse_status status = SCROLLBAR_MOUSE_NONE;
bool h;
/* we want mouse presses and mouse drags that were not started at the
@ -642,7 +642,7 @@ const char *scrollbar_mouse_action(struct scrollbar *s,
if (!s->dragging && !(x >= x0 && x <= x1 && y >= y0 && y <= y1)) {
/* Not a drag and mouse outside scrollbar widget */
return NULL;
return SCROLLBAR_MOUSE_NONE;
}
@ -660,9 +660,9 @@ const char *scrollbar_mouse_action(struct scrollbar *s,
!(s->drag_content));
if (s->pair_drag) {
scrollbar_mouse_action(s->pair, mouse, x, y);
status = messages_get("ScrollBoth");
status = SCROLLBAR_MOUSE_BOTH;
} else
status = messages_get(h ? "ScrollH" : "ScrollV");
status = h ? SCROLLBAR_MOUSE_HRZ : SCROLLBAR_MOUSE_VRT;
return status;
}
@ -670,7 +670,7 @@ const char *scrollbar_mouse_action(struct scrollbar *s,
if (val < SCROLLBAR_WIDTH) {
/* left/up arrow */
status = messages_get(h ? "ScrollLeft" : "ScrollUp");
status = h ? SCROLLBAR_MOUSE_LFT : SCROLLBAR_MOUSE_UP;
if (but1)
scrollbar_set(s, s->offset - SCROLLBAR_WIDTH, false);
else if (but2)
@ -679,7 +679,7 @@ const char *scrollbar_mouse_action(struct scrollbar *s,
} else if (val < SCROLLBAR_WIDTH + s->bar_pos) {
/* well between left/up arrow and bar */
status = messages_get(h ? "ScrollPLeft" : "ScrollPUp");
status = h ? SCROLLBAR_MOUSE_PLFT : SCROLLBAR_MOUSE_PUP;
if (but1)
scrollbar_set(s, s->offset - s->length, false);
@ -689,7 +689,7 @@ const char *scrollbar_mouse_action(struct scrollbar *s,
} else if (val > s->length - SCROLLBAR_WIDTH) {
/* right/down arrow */
status = messages_get(h ? "ScrollRight" : "ScrollDown");
status = h ? SCROLLBAR_MOUSE_RGT : SCROLLBAR_MOUSE_DWN;
if (but1)
scrollbar_set(s, s->offset + SCROLLBAR_WIDTH, false);
@ -700,7 +700,7 @@ const char *scrollbar_mouse_action(struct scrollbar *s,
s->bar_len) {
/* well between right/down arrow and bar */
status = messages_get(h ? "ScrollPRight" : "ScrollPDown");
status = h ? SCROLLBAR_MOUSE_PRGT : SCROLLBAR_MOUSE_PDWN;
if (but1)
scrollbar_set(s, s->offset + s->length, false);
else if (but2)
@ -709,7 +709,7 @@ const char *scrollbar_mouse_action(struct scrollbar *s,
else {
/* scrollbar position indication bar */
status = messages_get(h ? "ScrollH" : "ScrollV");
status = h ? SCROLLBAR_MOUSE_HRZ : SCROLLBAR_MOUSE_VRT;
}
@ -726,6 +726,50 @@ const char *scrollbar_mouse_action(struct scrollbar *s,
}
/*
* Exported function. Documented in scrollbar.h
*/
const char *scrollbar_mouse_status_to_message(scrollbar_mouse_status status)
{
switch ((unsigned int) status) {
case SCROLLBAR_MOUSE_UP:
case SCROLLBAR_MOUSE_UP | SCROLLBAR_MOUSE_USED:
return messages_get("ScrollUp");
case SCROLLBAR_MOUSE_PUP:
case SCROLLBAR_MOUSE_PUP | SCROLLBAR_MOUSE_USED:
return messages_get("ScrollPUp");
case SCROLLBAR_MOUSE_VRT:
case SCROLLBAR_MOUSE_VRT | SCROLLBAR_MOUSE_USED:
return messages_get("ScrollV");
case SCROLLBAR_MOUSE_PDWN:
case SCROLLBAR_MOUSE_PDWN | SCROLLBAR_MOUSE_USED:
return messages_get("ScrollPDown");
case SCROLLBAR_MOUSE_DWN:
case SCROLLBAR_MOUSE_DWN | SCROLLBAR_MOUSE_USED:
return messages_get("ScrollDown");
case SCROLLBAR_MOUSE_LFT:
case SCROLLBAR_MOUSE_LFT | SCROLLBAR_MOUSE_USED:
return messages_get("ScrollLeft");
case SCROLLBAR_MOUSE_PLFT:
case SCROLLBAR_MOUSE_PLFT | SCROLLBAR_MOUSE_USED:
return messages_get("ScrollPLeft");
case SCROLLBAR_MOUSE_HRZ:
case SCROLLBAR_MOUSE_HRZ | SCROLLBAR_MOUSE_USED:
return messages_get("ScrollH");
case SCROLLBAR_MOUSE_PRGT:
case SCROLLBAR_MOUSE_PRGT | SCROLLBAR_MOUSE_USED:
return messages_get("ScrollPRight");
case SCROLLBAR_MOUSE_RGT:
case SCROLLBAR_MOUSE_RGT | SCROLLBAR_MOUSE_USED:
return messages_get("ScrollRight");
default:
break;
}
return NULL;
}
/*
* Exported function. Documented in scrollbar.h
*/

View File

@ -152,6 +152,23 @@ void scrollbar_set_extents(struct scrollbar *s, int length,
*/
bool scrollbar_is_horizontal(struct scrollbar *s);
/* Scrollbar mouse input status flags */
typedef enum {
SCROLLBAR_MOUSE_NONE = 0, /**< Not relevant */
SCROLLBAR_MOUSE_USED = (1 << 0), /**< Took action with input */
SCROLLBAR_MOUSE_BOTH = (1 << 1), /**< Scrolling both bars */
SCROLLBAR_MOUSE_UP = (1 << 2), /**< Hover: scroll up */
SCROLLBAR_MOUSE_PUP = (1 << 3), /**< Hover: scroll page up */
SCROLLBAR_MOUSE_VRT = (1 << 4), /**< Hover: vert. drag bar */
SCROLLBAR_MOUSE_PDWN = (1 << 5), /**< Hover: scroll page down */
SCROLLBAR_MOUSE_DWN = (1 << 6), /**< Hover: scroll down */
SCROLLBAR_MOUSE_LFT = (1 << 7), /**< Hover: scroll left */
SCROLLBAR_MOUSE_PLFT = (1 << 8), /**< Hover: scroll page left */
SCROLLBAR_MOUSE_HRZ = (1 << 9), /**< Hover: horiz. drag bar */
SCROLLBAR_MOUSE_PRGT = (1 << 10), /**< Hover: scroll page right */
SCROLLBAR_MOUSE_RGT = (1 << 11) /**< Hover: scroll right */
} scrollbar_mouse_status;
/**
* Handle mouse actions other then drag ends.
*
@ -159,11 +176,19 @@ bool scrollbar_is_horizontal(struct scrollbar *s);
* \param mouse mouse state
* \param x X coordinate of the mouse
* \param y Y coordinate of the mouse
* \return message for the status bar or NULL on failure
* \return the scrollbar mouse status
*/
const char *scrollbar_mouse_action(struct scrollbar *s,
scrollbar_mouse_status scrollbar_mouse_action(struct scrollbar *s,
browser_mouse_state mouse, int x, int y);
/**
* Get a status bar message from a scrollbar mouse input status.
*
* \param status Status to convert to message
* \return Message for the status bar or NULL on failure
*/
const char *scrollbar_mouse_status_to_message(scrollbar_mouse_status status);
/**
* Handle end of mouse drags.
*

View File

@ -2236,14 +2236,17 @@ bool textarea_keypress(struct textarea *ta, uint32_t key)
* \param mouse the mouse state at action moment
* \param x X coordinate
* \param y Y coordinate
* \return true if action was handled false otherwise
* \return textarea mouse state
*/
static bool textarea_mouse_scrollbar_action(struct textarea *ta,
browser_mouse_state mouse, int x, int y)
static textarea_mouse_status textarea_mouse_scrollbar_action(
struct textarea *ta, browser_mouse_state mouse, int x, int y)
{
int sx, sy; /* xy coord offset for scrollbar */
int sl; /* scrollbar length */
assert(SCROLLBAR_MOUSE_USED == (1 << 0));
assert(TEXTAREA_MOUSE_SCR_USED == (1 << 3));
/* Existing scrollbar drag */
if (ta->drag_info.type == TEXTAREA_DRAG_SCROLLBAR) {
/* Scrollbar drag in progress; pass input to scrollbar */
@ -2256,9 +2259,8 @@ static bool textarea_mouse_scrollbar_action(struct textarea *ta,
SCROLLBAR_WIDTH;
y -= ta->border_width;
}
scrollbar_mouse_action(ta->drag_info.data.scrollbar,
mouse, x, y);
return true;
return (scrollbar_mouse_action(ta->drag_info.data.scrollbar,
mouse, x, y) << 3);
}
/* Horizontal scrollbar */
@ -2271,8 +2273,8 @@ static bool textarea_mouse_scrollbar_action(struct textarea *ta,
(ta->bar_y != NULL ? SCROLLBAR_WIDTH : 0);
if (sx >= 0 && sy >= 0 && sx < sl && sy < SCROLLBAR_WIDTH) {
scrollbar_mouse_action(ta->bar_x, mouse, sx, sy);
return true;
return (scrollbar_mouse_action(ta->bar_x, mouse,
sx, sy) << 3);
}
}
@ -2285,22 +2287,23 @@ static bool textarea_mouse_scrollbar_action(struct textarea *ta,
sl = ta->vis_height - 2 * ta->border_width;
if (sx >= 0 && sy >= 0 && sx < SCROLLBAR_WIDTH && sy < sl) {
scrollbar_mouse_action(ta->bar_y, mouse, sx, sy);
return true;
return (scrollbar_mouse_action(ta->bar_y, mouse,
sx, sy) << 3);
}
}
return false;
return TEXTAREA_MOUSE_NONE;
}
/* exported interface, documented in textarea.h */
bool textarea_mouse_action(struct textarea *ta, browser_mouse_state mouse,
int x, int y)
textarea_mouse_status textarea_mouse_action(struct textarea *ta,
browser_mouse_state mouse, int x, int y)
{
int c_start, c_end;
unsigned int c_off;
struct textarea_msg msg;
textarea_mouse_status status = TEXTAREA_MOUSE_NONE;
if (ta->drag_info.type != TEXTAREA_DRAG_NONE &&
mouse == BROWSER_MOUSE_HOVER) {
@ -2309,21 +2312,26 @@ bool textarea_mouse_action(struct textarea *ta, browser_mouse_state mouse,
}
/* Mouse action might be a scrollbar's responsibility */
if (textarea_mouse_scrollbar_action(ta, mouse, x, y)) {
status = textarea_mouse_scrollbar_action(ta, mouse, x, y);
if (status != TEXTAREA_MOUSE_NONE) {
/* Mouse action was handled by a scrollbar */
return true;
return status;
}
status |= TEXTAREA_MOUSE_EDITOR;
/* Mouse action is textarea's responsibility */
if (mouse & BROWSER_MOUSE_DOUBLE_CLICK) {
/* Select word */
textarea_set_caret_xy(ta, x, y);
return textarea_select_fragment(ta);
textarea_select_fragment(ta);
status |= TEXTAREA_MOUSE_USED;
} else if (mouse & BROWSER_MOUSE_TRIPLE_CLICK) {
/* Select paragraph */
textarea_set_caret_xy(ta, x, y);
return textarea_select_paragraph(ta);
textarea_select_paragraph(ta);
status |= TEXTAREA_MOUSE_USED;
} else if (mouse & BROWSER_MOUSE_PRESS_1) {
/* Place caret */
@ -2335,6 +2343,7 @@ bool textarea_mouse_action(struct textarea *ta, browser_mouse_state mouse,
/* Clear selection */
textarea_clear_selection(ta);
}
status |= TEXTAREA_MOUSE_USED;
} else if (mouse & BROWSER_MOUSE_PRESS_2) {
c_start = textarea_get_caret(ta);
@ -2347,12 +2356,13 @@ bool textarea_mouse_action(struct textarea *ta, browser_mouse_state mouse,
c_start = ((unsigned)c_start > c_off) ?
ta->sel_end : ta->sel_start;
ta->drag_start_char = c_start;
return textarea_select(ta, c_start, c_off, false);
textarea_select(ta, c_start, c_off, false);
} else {
/* Select to caret */
ta->drag_start_char = c_start;
return textarea_select(ta, c_start, c_off, false);
textarea_select(ta, c_start, c_off, false);
}
status |= TEXTAREA_MOUSE_USED;
} else if (mouse & (BROWSER_MOUSE_DRAG_1 | BROWSER_MOUSE_DRAG_2)) {
/* Selection start */
@ -2367,7 +2377,8 @@ bool textarea_mouse_action(struct textarea *ta, browser_mouse_state mouse,
ta->callback(ta->data, &msg);
return textarea_select(ta, c_start, c_end, false);
textarea_select(ta, c_start, c_end, false);
status |= TEXTAREA_MOUSE_USED;
} else if (mouse &
(BROWSER_MOUSE_HOLDING_1 | BROWSER_MOUSE_HOLDING_2) &&
@ -2400,10 +2411,16 @@ bool textarea_mouse_action(struct textarea *ta, browser_mouse_state mouse,
need_redraw = textarea_scroll(ta, scrx, scry);
return textarea_select(ta, c_start, c_end, need_redraw);
textarea_select(ta, c_start, c_end, need_redraw);
status |= TEXTAREA_MOUSE_USED;
}
return true;
if (ta->sel_start != -1) {
/* Have selection */
status |= TEXTAREA_MOUSE_SELECTION;
}
return status;
}

View File

@ -196,6 +196,26 @@ void textarea_redraw(struct textarea *ta, int x, int y, colour bg, float scale,
*/
bool textarea_keypress(struct textarea *ta, uint32_t key);
/* Text area mouse input status flags */
typedef enum {
TEXTAREA_MOUSE_NONE = 0, /**< Not relevant */
TEXTAREA_MOUSE_USED = (1 << 0), /**< Took action with input */
TEXTAREA_MOUSE_EDITOR = (1 << 1), /**< Hover: caret pointer */
TEXTAREA_MOUSE_SELECTION= (1 << 2), /**< Hover: selection */
TEXTAREA_MOUSE_SCR_USED = (1 << 3), /**< Scrollbar action */
TEXTAREA_MOUSE_SCR_BOTH = (1 << 4), /**< Scrolling both bars */
TEXTAREA_MOUSE_SCR_UP = (1 << 5), /**< Hover: scroll up */
TEXTAREA_MOUSE_SCR_PUP = (1 << 6), /**< Hover: scroll page up */
TEXTAREA_MOUSE_SCR_VRT = (1 << 7), /**< Hover: vert. drag bar */
TEXTAREA_MOUSE_SCR_PDWN = (1 << 8), /**< Hover: scroll page down */
TEXTAREA_MOUSE_SCR_DWN = (1 << 9), /**< Hover: scroll down */
TEXTAREA_MOUSE_SCR_LFT = (1 << 10), /**< Hover: scroll left */
TEXTAREA_MOUSE_SCR_PLFT = (1 << 11), /**< Hover: scroll page left */
TEXTAREA_MOUSE_SCR_HRZ = (1 << 12), /**< Hover: horiz. drag bar */
TEXTAREA_MOUSE_SCR_PRGT = (1 << 13), /**< Hover: scroll page right */
TEXTAREA_MOUSE_SCR_RGT = (1 << 14) /**< Hover: scroll right */
} textarea_mouse_status;
/**
* Handles all kinds of mouse action
*
@ -203,10 +223,10 @@ bool textarea_keypress(struct textarea *ta, uint32_t key);
* \param mouse the mouse state at action moment
* \param x X coordinate
* \param y Y coordinate
* \return true if action was handled false otherwise
* \return the textarea mouse status
*/
bool textarea_mouse_action(struct textarea *ta, browser_mouse_state mouse,
int x, int y);
textarea_mouse_status textarea_mouse_action(struct textarea *ta,
browser_mouse_state mouse, int x, int y);
/**
* Clear any selection in the textarea.

View File

@ -1249,8 +1249,9 @@ const char *form_select_mouse_action(struct form_control *control,
* event is taking place on the scrollbar widget area
*/
x -= scrollbar_x;
return scrollbar_mouse_action(menu->scrollbar,
mouse, x, y);
return scrollbar_mouse_status_to_message(
scrollbar_mouse_action(menu->scrollbar,
mouse, x, y));
}

View File

@ -376,15 +376,19 @@ void html_mouse_action(struct content *c, struct browser_window *bw,
scroll_mouse_y = y - (box_y + box->padding[TOP] +
box->height + box->padding[BOTTOM] -
SCROLLBAR_WIDTH);
status = scrollbar_mouse_action(scr, mouse,
scroll_mouse_x, scroll_mouse_y);
status = scrollbar_mouse_status_to_message(
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(scr, mouse,
scroll_mouse_x, scroll_mouse_y);
status = scrollbar_mouse_status_to_message(
scrollbar_mouse_action(scr, mouse,
scroll_mouse_x,
scroll_mouse_y));
}
msg_data.explicit_status_text = status;
@ -586,10 +590,14 @@ void html_mouse_action(struct content *c, struct browser_window *bw,
* mistake; they will refer to the last box returned by box_at_point */
if (scrollbar) {
status = scrollbar_mouse_action(scrollbar, mouse,
scroll_mouse_x, scroll_mouse_y);
status = scrollbar_mouse_status_to_message(
scrollbar_mouse_action(scrollbar, mouse,
scroll_mouse_x,
scroll_mouse_y));
pointer = BROWSER_POINTER_DEFAULT;
} else if (gadget) {
textarea_mouse_status ta_status;
switch (gadget->type) {
case GADGET_SELECT:
status = messages_get("FormSelect");
@ -600,7 +608,7 @@ void html_mouse_action(struct content *c, struct browser_window *bw,
form_open_select_menu(c, gadget,
form_select_menu_callback,
c);
pointer = BROWSER_POINTER_DEFAULT;
pointer = BROWSER_POINTER_DEFAULT;
} else if (mouse & BROWSER_MOUSE_CLICK_1)
gui_create_form_select_menu(bw, gadget);
break;
@ -644,8 +652,6 @@ void html_mouse_action(struct content *c, struct browser_window *bw,
else
status = messages_get("FormTextbox");
pointer = get_pointer_shape(gadget_box, false);
if (click && (html->selection_type !=
HTML_SELECTION_TEXTAREA ||
html->selection_owner.textarea !=
@ -655,8 +661,17 @@ void html_mouse_action(struct content *c, struct browser_window *bw,
sel_owner, true);
}
textarea_mouse_action(gadget->data.text.ta, mouse,
x - gadget_box_x, y - gadget_box_y);
ta_status = textarea_mouse_action(gadget->data.text.ta,
mouse, x - gadget_box_x,
y - gadget_box_y);
if (ta_status & TEXTAREA_MOUSE_EDITOR) {
pointer = get_pointer_shape(gadget_box, false);
} else {
pointer = BROWSER_POINTER_DEFAULT;
status = scrollbar_mouse_status_to_message(
ta_status >> 3);
}
break;
case GADGET_HIDDEN:
/* not possible: no box generated */