static int hscrollarea_click(fbtk_widget_t *widget, fbtk_callback_info *cbi) { int hscroll; int hpos; int newpos; int ret = 0; if (cbi->event->type != NSFB_EVENT_KEY_DOWN) { /* end all drags, just in case */ if (fbtk_set_handler(widget, FBTK_CBT_POINTERMOVE, NULL, NULL) != NULL) fbtk_tgrab_pointer(widget); return 0; } if ((widget->u.scroll.maximum - widget->u.scroll.minimum) > 0) { hscroll = ((widget->width - 4) * widget->u.scroll.thumb) / (widget->u.scroll.maximum - widget->u.scroll.minimum) ; hpos = ((widget->width - 4) * widget->u.scroll.position) / (widget->u.scroll.maximum - widget->u.scroll.minimum) ; } else { hscroll = (widget->width - 4); hpos = 0; } if (cbi->x < hpos) { /* left of bar */ newpos = widget->u.scroll.position - widget->u.scroll.page; if (newpos < widget->u.scroll.minimum) newpos = widget->u.scroll.minimum; ret = fbtk_post_callback(cbi->context, FBTK_CBT_SCROLLX, newpos); } else if (cbi->x > (hpos + hscroll)) { /* right of bar */ newpos = widget->u.scroll.position + widget->u.scroll.page; if (newpos > widget->u.scroll.maximum) newpos = widget->u.scroll.maximum; ret = fbtk_post_callback(cbi->context, FBTK_CBT_SCROLLX, newpos); } else { /* on bar - start drag */ widget->u.scroll.drag = cbi->x; widget->u.scroll.drag_position = hpos; fbtk_set_handler(widget, FBTK_CBT_POINTERMOVE, hscroll_drag, widget); fbtk_tgrab_pointer(widget); } return ret; }
/* called back when movement in browser window */ static int fb_browser_window_move(fbtk_widget_t *widget, fbtk_callback_info *cbi) { browser_mouse_state mouse = 0; struct gui_window *gw = cbi->context; struct browser_widget_s *bwidget = fbtk_get_userpw(widget); float scale = browser_window_get_scale(gw->bw); int x = (cbi->x + bwidget->scrollx) / scale; int y = (cbi->y + bwidget->scrolly) / scale; if (gui_drag.state == GUI_DRAG_PRESSED && (abs(x - gui_drag.x) > 5 || abs(y - gui_drag.y) > 5)) { /* Drag started */ if (gui_drag.button == 1) { browser_window_mouse_click(gw->bw, BROWSER_MOUSE_DRAG_1, gui_drag.x, gui_drag.y); } else { browser_window_mouse_click(gw->bw, BROWSER_MOUSE_DRAG_2, gui_drag.x, gui_drag.y); } gui_drag.grabbed_pointer = fbtk_tgrab_pointer(widget); gui_drag.state = GUI_DRAG_DRAG; } if (gui_drag.state == GUI_DRAG_DRAG) { /* set up mouse state */ mouse |= BROWSER_MOUSE_DRAG_ON; if (gui_drag.button == 1) mouse |= BROWSER_MOUSE_HOLDING_1; else mouse |= BROWSER_MOUSE_HOLDING_2; } browser_window_mouse_track(gw->bw, mouse, x, y); return 0; }
/* called back when click in browser window */ static int fb_browser_window_click(fbtk_widget_t *widget, fbtk_callback_info *cbi) { struct gui_window *gw = cbi->context; struct browser_widget_s *bwidget = fbtk_get_userpw(widget); browser_mouse_state mouse; float scale = browser_window_get_scale(gw->bw); int x = (cbi->x + bwidget->scrollx) / scale; int y = (cbi->y + bwidget->scrolly) / scale; unsigned int time_now; static struct { enum { CLICK_SINGLE, CLICK_DOUBLE, CLICK_TRIPLE } type; unsigned int time; } last_click; if (cbi->event->type != NSFB_EVENT_KEY_DOWN && cbi->event->type != NSFB_EVENT_KEY_UP) return 0; LOG(("browser window clicked at %d,%d", cbi->x, cbi->y)); switch (cbi->event->type) { case NSFB_EVENT_KEY_DOWN: switch (cbi->event->value.keycode) { case NSFB_KEY_MOUSE_1: browser_window_mouse_click(gw->bw, BROWSER_MOUSE_PRESS_1, x, y); gui_drag.state = GUI_DRAG_PRESSED; gui_drag.button = 1; gui_drag.x = x; gui_drag.y = y; break; #if 0 case NSFB_KEY_MOUSE_3: browser_window_mouse_click(gw->bw, BROWSER_MOUSE_PRESS_2, x, y); gui_drag.state = GUI_DRAG_PRESSED; gui_drag.button = 2; gui_drag.x = x; gui_drag.y = y; break; #else case NSFB_KEY_MOUSE_2: /* scroll right */ if (browser_window_scroll_at_point(gw->bw, x, y, 100, 0) == false) widget_scroll_x(gw, 100, false); break; case NSFB_KEY_MOUSE_3: /* scroll left */ if (browser_window_scroll_at_point(gw->bw, x, y, -100, 0) == false) widget_scroll_x(gw, -100, false); break; #endif case NSFB_KEY_MOUSE_4: /* scroll up */ if (browser_window_scroll_at_point(gw->bw, x, y, 0, -100) == false) { widget_scroll_y(gw, -100, false); } break; case NSFB_KEY_MOUSE_5: /* scroll down */ if (browser_window_scroll_at_point(gw->bw, x, y, 0, 100) == false) { widget_scroll_y(gw, 100, false); } break; default: break; } break; case NSFB_EVENT_KEY_UP: mouse = 0; time_now = wallclock(); switch (cbi->event->value.keycode) { case NSFB_KEY_MOUSE_1: if (gui_drag.state == GUI_DRAG_DRAG) { /* End of a drag, rather than click */ if (gui_drag.grabbed_pointer) { /* need to ungrab pointer */ fbtk_tgrab_pointer(widget); gui_drag.grabbed_pointer = false; } gui_drag.state = GUI_DRAG_NONE; /* Tell core */ browser_window_mouse_track(gw->bw, 0, x, y); break; } /* This is a click; * clear PRESSED state and pass to core */ gui_drag.state = GUI_DRAG_NONE; mouse = BROWSER_MOUSE_CLICK_1; break; #if 0 case NSFB_KEY_MOUSE_3: if (gui_drag.state == GUI_DRAG_DRAG) { /* End of a drag, rather than click */ gui_drag.state = GUI_DRAG_NONE; if (gui_drag.grabbed_pointer) { /* need to ungrab pointer */ fbtk_tgrab_pointer(widget); gui_drag.grabbed_pointer = false; } /* Tell core */ browser_window_mouse_track(gw->bw, 0, x, y); break; } /* This is a click; * clear PRESSED state and pass to core */ gui_drag.state = GUI_DRAG_NONE; mouse = BROWSER_MOUSE_CLICK_2; break; #endif default: break; } /* Determine if it's a double or triple click, allowing * 0.5 seconds (50cs) between clicks */ if (time_now < last_click.time + 50 && cbi->event->value.keycode != NSFB_KEY_MOUSE_4 && cbi->event->value.keycode != NSFB_KEY_MOUSE_5) { if (last_click.type == CLICK_SINGLE) { /* Set double click */ mouse |= BROWSER_MOUSE_DOUBLE_CLICK; last_click.type = CLICK_DOUBLE; } else if (last_click.type == CLICK_DOUBLE) { /* Set triple click */ mouse |= BROWSER_MOUSE_TRIPLE_CLICK; last_click.type = CLICK_TRIPLE; } else { /* Set normal click */ last_click.type = CLICK_SINGLE; } } else { last_click.type = CLICK_SINGLE; } if (mouse) browser_window_mouse_click(gw->bw, mouse, x, y); last_click.time = time_now; break; default: break; } return 1; }
static int vscrollarea_click(fbtk_widget_t *widget, fbtk_callback_info *cbi) { int vscroll; int vpos; int newpos; int ret = 0; if (cbi->event->type != NSFB_EVENT_KEY_DOWN) { /* end all drags, just in case */ if (fbtk_set_handler(widget, FBTK_CBT_POINTERMOVE, NULL, NULL) != NULL) fbtk_tgrab_pointer(widget); return 0; } switch (cbi->event->value.keycode) { case NSFB_KEY_MOUSE_4: /* scroll up */ newpos = widget->u.scroll.position - widget->u.scroll.page; if (newpos < widget->u.scroll.minimum) newpos = widget->u.scroll.minimum; ret = fbtk_post_callback(cbi->context, FBTK_CBT_SCROLLY, newpos); break; case NSFB_KEY_MOUSE_5: /* scroll down */ newpos = widget->u.scroll.position + widget->u.scroll.page; if (newpos > widget->u.scroll.maximum) newpos = widget->u.scroll.maximum; ret = fbtk_post_callback(cbi->context, FBTK_CBT_SCROLLY, newpos); break; default: if ((widget->u.scroll.maximum - widget->u.scroll.minimum) > 0) { vscroll = ((widget->height - 4) * widget->u.scroll.thumb) / (widget->u.scroll.maximum - widget->u.scroll.minimum) ; vpos = ((widget->height - 4) * widget->u.scroll.position) / (widget->u.scroll.maximum - widget->u.scroll.minimum) ; } else { vscroll = (widget->height - 4); vpos = 0; } if (cbi->y < vpos) { /* above bar */ newpos = widget->u.scroll.position - widget->u.scroll.thumb; if (newpos < widget->u.scroll.minimum) newpos = widget->u.scroll.minimum; ret = fbtk_post_callback(cbi->context, FBTK_CBT_SCROLLY, newpos); } else if (cbi->y > (vpos + vscroll)) { /* below bar */ newpos = widget->u.scroll.position + widget->u.scroll.thumb; if (newpos > widget->u.scroll.maximum) newpos = widget->u.scroll.maximum; ret = fbtk_post_callback(cbi->context, FBTK_CBT_SCROLLY, newpos); } else { /* on bar - start drag */ widget->u.scroll.drag = cbi->y; widget->u.scroll.drag_position = vpos; fbtk_set_handler(widget, FBTK_CBT_POINTERMOVE, vscroll_drag, widget); fbtk_tgrab_pointer(widget); } } return ret; }
/* called back when click in browser window */ static int fb_browser_window_click(fbtk_widget_t *widget, fbtk_callback_info *cbi) { struct gui_window *gw = cbi->context; struct browser_widget_s *bwidget = fbtk_get_userpw(widget); float scale = gw->bw->scale; int x = (cbi->x + bwidget->scrollx) / scale; int y = (cbi->y + bwidget->scrolly) / scale; if (cbi->event->type != NSFB_EVENT_KEY_DOWN && cbi->event->type != NSFB_EVENT_KEY_UP) return 0; LOG(("browser window clicked at %d,%d", cbi->x, cbi->y)); switch (cbi->event->type) { case NSFB_EVENT_KEY_DOWN: switch (cbi->event->value.keycode) { case NSFB_KEY_MOUSE_1: browser_window_mouse_click(gw->bw, BROWSER_MOUSE_PRESS_1, x, y); gui_drag.state = GUI_DRAG_PRESSED; gui_drag.button = 1; gui_drag.x = x; gui_drag.y = y; break; case NSFB_KEY_MOUSE_3: browser_window_mouse_click(gw->bw, BROWSER_MOUSE_PRESS_2, x, y); gui_drag.state = GUI_DRAG_PRESSED; gui_drag.button = 2; gui_drag.x = x; gui_drag.y = y; break; case NSFB_KEY_MOUSE_4: /* scroll up */ if (browser_window_scroll_at_point(gw->bw, x, y, 0, -100) == false) widget_scroll_y(gw, -100, false); break; case NSFB_KEY_MOUSE_5: /* scroll down */ if (browser_window_scroll_at_point(gw->bw, x, y, 0, 100) == false) widget_scroll_y(gw, 100, false); break; default: break; } break; case NSFB_EVENT_KEY_UP: switch (cbi->event->value.keycode) { case NSFB_KEY_MOUSE_1: if (gui_drag.state == GUI_DRAG_DRAG) { /* End of a drag, rather than click */ if (gui_drag.grabbed_pointer) { /* need to ungrab pointer */ fbtk_tgrab_pointer(widget); gui_drag.grabbed_pointer = false; } gui_drag.state = GUI_DRAG_NONE; /* Tell core */ browser_window_mouse_track(gw->bw, 0, x, y); break; } /* This is a click; * clear PRESSED state and pass to core */ gui_drag.state = GUI_DRAG_NONE; browser_window_mouse_click(gw->bw, BROWSER_MOUSE_CLICK_1, x, y); break; case NSFB_KEY_MOUSE_3: if (gui_drag.state == GUI_DRAG_DRAG) { /* End of a drag, rather than click */ gui_drag.state = GUI_DRAG_NONE; if (gui_drag.grabbed_pointer) { /* need to ungrab pointer */ fbtk_tgrab_pointer(widget); gui_drag.grabbed_pointer = false; } /* Tell core */ browser_window_mouse_track(gw->bw, 0, x, y); break; } /* This is a click; * clear PRESSED state and pass to core */ gui_drag.state = GUI_DRAG_NONE; browser_window_mouse_click(gw->bw, BROWSER_MOUSE_CLICK_2, x, y); break; default: break; } break; default: break; } return 1; }