4 * Finding the posisiton and changing the shape of the mouse pointer
6 * © 1994-1998 Straylight
9 /*----- Licensing note ----------------------------------------------------*
11 * This file is part of Straylight's Glass.
13 * Glass is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2, or (at your option)
18 * Glass is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with Glass. If not, write to the Free Software Foundation,
25 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
28 /*----- Header files ------------------------------------------------------*/
31 * ANSI standard headers
44 #include "steel/Steel.h"
46 #include "steel/pointer.h"
61 /*----- Tables ------------------------------------------------------------*/
64 * This table defines the mapping from drag zones to pointer shapes, to
65 * indicate to the user what operations are possible. There is some
66 * redundancy since there are some 'reserved' zone numbers, and they go up
67 * to &F. Each entry takes up 20 bytes, though, so things aren't exactly
68 * critical as a result of this.
83 "ptr_lr",11,4, /* 4 */
84 "ptr_tlbr",9,5, /* 5 */
85 "ptr_trbl",9,5, /* 6 */
86 "ptr_hand",10,9, /* 7 */
87 "ptr_lr",11,4, /* 8 */
88 "ptr_trbl",9,5, /* 9 */
89 "ptr_tlbr",9,5, /* a */
93 "ptr_lr",11,4, /* e */
97 /*----- Main code ---------------------------------------------------------*/
100 * BOOL window__inSizedBox(int px,int py,int x,int y,int d)
103 * Returns whether the point passed as (px,py) is contained within the
104 * square box with bottom-left corner (x,y) and side length d.
110 * TRUE if the point lies within the box, or FALSE if not
113 static BOOL window__inSizedBox(int px,int py,int x,int y,int d)
117 d=(d+wimpt_dy()-1) &~ (wimpt_dy()-1);
118 if (px>=x && py>=y && px<=x+d && py<=y+d)
125 * int window__pointerInfo(glass_windPointer *w,int from,BOOL zones)
128 * Returns the icon number of the icon which the pointer is over. Guides
129 * are also checked for.
132 * glass_windPointer *w == the window to use info from
133 * int from == number to search down from (or -1 for the top). This is
134 * useful for selection, multiple clicks moving down overlapping icons.
135 * BOOL zones == search for drag zones. If this is set, the routine
136 * searches for selected icons only. If it is clear, zones are not
140 * An icon number, or -1 for the background.
143 #define HW window__HANDLEWIDTH
145 int window__pointerInfo(glass_windPointer *w,int from,BOOL zones)
155 /* --- Find out where the pointer is in the window --- */
157 wimpt_noerr(wimp_get_point_info(&m));
160 zones=zones&&!w->renumber;
161 ox=w->def->desc.w.box.x0-w->def->desc.w.scx;
162 oy=w->def->desc.w.box.y1-w->def->desc.w.scy;
166 /* --- Start the search from the right place --- *
168 * The search can be relative to an icon, for the depth-selection system
169 * to work. If this is the case, we do two passes through the icon array
170 * and start off half-way through. If we're just searching from the top
171 * then we just do one pass.
176 i=w->def->desc.w.nicons-1;
185 /* --- The main search loop --- *
187 * There's nothing really exciting about this. It's just a brute-force
188 * rectangle comparison. If it finds something, then it returns
191 * We try to be a little cleverer -- we check if the pointer is anywhere
192 * near the icon rectangle and only read the actual bounding area if it
193 * is really worthwhile.
198 while (i>=0) /* Find higher icons first... */
200 if (w->def->i[i].i.flags & wimp_IDELETED)
203 continue; /* Don't find deleted icons... */
205 if (m.x>=w->def->i[i].i.box.x0-20-HW &&
206 m.x<=w->def->i[i].i.box.x1+20+HW &&
207 m.y>=w->def->i[i].i.box.y0-20-HW &&
208 m.y<=w->def->i[i].i.box.y1+32+HW)
209 { /* Roughly in the right place */
211 /* --- Find the actual bounding box of the icon --- */
213 window_boundingBox(w,i,&box);
215 /* --- If we're searching for drag zones, do that --- */
217 if (w->def->i[i].selected && zones)
219 if (window__inSizedBox(m.x,
222 box.y0-wimpt_dy()-HW,
224 return (i | window__BOTTOMRIGHT);
225 if (window__inSizedBox(m.x,
227 box.x0-wimpt_dx()-HW,
228 box.y0-wimpt_dy()-HW,
230 return (i | window__BOTTOMLEFT);
231 if (window__inSizedBox(m.x,
233 box.x0-wimpt_dx()-HW,
236 return (i | window__TOPLEFT);
237 if (window__inSizedBox(m.x,
242 return (i | window__TOPRIGHT);
243 if (gPrefs_current()->sEdgeHandles)
245 if (window__inSizedBox(m.x,
247 box.x0+(box.x1-box.x0-HW*2)/2,
248 box.y0-wimpt_dy()-HW,
250 return (i | window__BOTTOM);
251 if (window__inSizedBox(m.x,
254 box.y0+(box.y1-box.y0-HW*2)/2,
256 return (i | window__RIGHT);
257 if (window__inSizedBox(m.x,
259 box.x0-wimpt_dx()-HW,
260 box.y0+(box.y1-box.y0-HW*2)/2,
262 return (i | window__LEFT);
263 if (window__inSizedBox(m.x,
265 box.x0+(box.x1-box.x0-HW*2)/2,
268 return (i | window__TOP);
272 /* --- If no match in the zones, check the actual icon --- *
274 * If it's in the icon, then we've found a match. If we're searching
275 * for drag zones, and it's not selected, then just remember we've
276 * found an icon, so don't try to match guidelines. Otherwise, we
277 * just return the match.
280 if (m.x>=box.x0 && m.x<box.x1 && m.y>=box.y0 && m.y<box.y1)
283 if (w->def->i[i].selected)
284 return (i | window__MAIN);
293 i=w->def->desc.w.nicons-1;
296 /* --- We couldn't find anything in the icons, so try guidelines --- */
300 for (i=0;i<glass_GUIDELIMIT;i++)
302 if (w->guide[i].active)
304 if (w->guide[i].horiz && abs(m.y-w->guide[i].coord)<8)
305 return (i | window__HORGUIDE);
306 else if (abs(m.x-w->guide[i].coord)<8)
307 return (i | window__VERGUIDE);
312 /* --- Not a sausage, so we failed --- */
320 * BOOL window__pointerOverIcon(glass_windPointer *w,int icon)
323 * Informs the caller if the pointer is over the bounding box of the icon
327 * glass_windPointer *w == window containing icon
328 * int icon == icon to check for
331 BOOL window__pointerOverIcon(glass_windPointer *w,int icon)
336 wimpt_noerr(wimp_get_wind_state(w->h,&s));
337 wimpt_noerr(wimp_get_point_info(&m));
338 window_boundingBox(w,icon,&box);
339 m.x-=s.o.box.x0-s.o.x;
340 m.y-=s.o.box.y1-s.o.y;
341 return (m.x>=box.x0 && m.x<=box.x1 && m.y>=box.y0 && m.y<=box.y1);
345 * void window__setPtrShape(int icon)
348 * Sets the pointer shape accoding to the 'drag zone' part of the given
352 * int icon == the icon number
355 void window__setPtrShape(int icon)
363 if (window__qDragType()!=-1)
364 icon=window__qDragType();
365 icon=(icon&window__ZONEMASK)>>24;
368 if (window__ptr[icon].name[0])
370 sid.s.name=window__ptr[icon].name;
372 pointer_set_shape(resspr_area(),
375 window__ptr[icon].y);
378 pointer_reset_shape();