summaryrefslogtreecommitdiff
path: root/amiga
diff options
context:
space:
mode:
authorChris Young <chris@unsatisfactorysoftware.co.uk>2012-01-11 21:41:55 +0000
committerChris Young <chris@unsatisfactorysoftware.co.uk>2012-01-11 21:41:55 +0000
commit9f08a052d08967409d62affdcef256d6cd219efc (patch)
tree307f683ccaeeeea2560647a8bcdc32b4fd5bc8a9 /amiga
parent3e9983abf2bdd282e1dfef9a2c83797a787cc6ea (diff)
downloadnetsurf-9f08a052d08967409d62affdcef256d6cd219efc.tar.gz
netsurf-9f08a052d08967409d62affdcef256d6cd219efc.tar.bz2
Allow confining the pointer to part of the window during drags. Actually
we aren't acting on this for any current drag types, but if we need to do so in the future (eg. frame resizing), this is the code to do it. The trap lasts 10 IntuiTicks so is re-asserted on every mouse move when an active drag is in effect. Drag type must be set to GDRAGGING_NONE to clear. svn path=/trunk/netsurf/; revision=13401
Diffstat (limited to 'amiga')
-rwxr-xr-xamiga/gui.c66
-rwxr-xr-xamiga/gui.h2
2 files changed, 67 insertions, 1 deletions
diff --git a/amiga/gui.c b/amiga/gui.c
index 9b5e15423..804b58909 100755
--- a/amiga/gui.c
+++ b/amiga/gui.c
@@ -1090,6 +1090,54 @@ void ami_gui_scroll_internal(struct gui_window_2 *gwin, int xs, int ys)
}
}
+struct IBox *ami_ns_rect_to_ibox(struct gui_window_2 *gwin, const struct rect *rect)
+{
+ struct IBox *bbox, *ibox;
+
+ ibox = AllocVec(sizeof(struct IBox), MEMF_CLEAR | MEMF_PRIVATE);
+ if(ibox == NULL) return NULL;
+
+ GetAttr(SPACE_AreaBox, (Object *)gwin->objects[GID_BROWSER], (ULONG *)&bbox);
+
+ ibox->Left = gwin->win->MouseX + (rect->x0 * gwin->bw->scale);
+ ibox->Top = gwin->win->MouseY + (rect->y0 * gwin->bw->scale);
+
+ ibox->Width = (rect->x1 - rect->x0) * gwin->bw->scale;
+ ibox->Height = (rect->y1 - rect->y0) * gwin->bw->scale;
+
+ if(ibox->Left < bbox->Left) ibox->Left = bbox->Left;
+ if(ibox->Top < bbox->Top) ibox->Top = bbox->Top;
+
+ if((ibox->Left > (bbox->Left + bbox->Width)) ||
+ (ibox->Top > (bbox->Top + bbox->Height)) ||
+ (ibox->Width < 0) || (ibox->Height < 0))
+ {
+ FreeVec(ibox);
+ return NULL;
+ }
+
+ return ibox;
+}
+
+void ami_gui_trap_mouse(struct gui_window_2 *gwin)
+{
+ switch(gwin->drag_op)
+ {
+ case GDRAGGING_NONE:
+ case GDRAGGING_SCROLLBAR:
+ case GDRAGGING_OTHER:
+ break;
+
+ default:
+ if(gwin->ptr_lock)
+ {
+ SetWindowAttrs(gwin->win, WA_GrabFocus, 10,
+ WA_MouseLimits, gwin->ptr_lock, TAG_DONE);
+ }
+ break;
+ }
+}
+
void ami_handle_msg(void)
{
struct IntuiMessage *message = NULL;
@@ -1249,6 +1297,8 @@ void ami_handle_msg(void)
switch(result & WMHI_CLASSMASK) // class
{
case WMHI_MOUSEMOVE:
+ ami_gui_trap_mouse(gwin); /* re-assert mouse area */
+
drag_x_move = 0;
drag_y_move = 0;
@@ -3846,7 +3896,21 @@ bool gui_window_scroll_start(struct gui_window *g)
bool gui_window_drag_start(struct gui_window *g, gui_drag_type type,
const struct rect *rect)
{
- DebugPrintF("drag start\n");
+ g->shared->drag_op = type;
+ if(rect) g->shared->ptr_lock = ami_ns_rect_to_ibox(g->shared, rect);
+
+ if(type == GDRAGGING_NONE)
+ {
+ SetWindowAttrs(gwin->win, WA_GrabFocus, 0,
+ WA_MouseLimits, NULL, TAG_DONE);
+
+ if(gwin->ptr_lock)
+ {
+ FreeVec(gwin->ptr_lock);
+ gwin->ptr_lock = NULL;
+ }
+ }
+
return true;
}
diff --git a/amiga/gui.h b/amiga/gui.h
index 118470221..8b53f6377 100755
--- a/amiga/gui.h
+++ b/amiga/gui.h
@@ -106,6 +106,8 @@ struct gui_window_2 {
struct AppIcon *appicon; /* iconify appicon */
struct DiskObject *dobj; /* iconify appicon */
struct Hook search_ico_hook;
+ gui_drag_type drag_op;
+ struct IBox *ptr_lock;
};
struct gui_window