mirror of
https://github.com/ctm/executor.git
synced 2024-09-25 22:56:22 +00:00
427 lines
12 KiB
C
427 lines
12 KiB
C
/* Copyright 1989, 1990 by Abacus Research and
|
|
* Development, Inc. All rights reserved.
|
|
*/
|
|
|
|
#if !defined (OMIT_RCSID_STRINGS)
|
|
char ROMlib_rcsid_listMouse[] =
|
|
"$Id: listMouse.c 63 2004-12-24 18:19:43Z ctm $";
|
|
#endif
|
|
|
|
/* Forward declarations in ListMgr.h (DO NOT DELETE THIS LINE) */
|
|
|
|
#include "rsys/common.h"
|
|
#include "EventMgr.h"
|
|
#include "ToolboxEvent.h"
|
|
#include "ToolboxUtil.h"
|
|
#include "OSEvent.h"
|
|
#include "ControlMgr.h"
|
|
#include "ListMgr.h"
|
|
|
|
#include "rsys/cquick.h"
|
|
#include "rsys/list.h"
|
|
#include "rsys/pstuff.h"
|
|
#include "rsys/hook.h"
|
|
|
|
A2(PRIVATE, void, findcell, Cell *, cp, ListHandle, list)
|
|
{
|
|
cp->h = CW((CW(cp->h) - Hx(list, rView.left)) / Hx(list, cellSize.h) +
|
|
Hx(list, visible.left));
|
|
cp->v = CW((CW(cp->v) - Hx(list, rView.top)) / Hx(list, cellSize.v) +
|
|
Hx(list, visible.top));
|
|
|
|
if (CW(cp->h) >= Hx(list, visible.right))
|
|
cp->h = CWC(32767);
|
|
if (CW(cp->v) >= Hx(list, visible.bottom))
|
|
cp->v = CWC(32767);
|
|
}
|
|
|
|
A4(PRIVATE, void, setselectnilflag, BOOLEAN, setit, Cell, cell,
|
|
ListHandle, list, BOOLEAN, hiliteempty)
|
|
{
|
|
GrafPtr saveport;
|
|
RgnHandle saveclip;
|
|
Rect r;
|
|
INTEGER *ip, off0wbit, off0, off1;
|
|
LISTDECL();
|
|
|
|
if ((ip = ROMlib_getoffp(cell, list))) {
|
|
off0wbit = CW(*ip);
|
|
if (setit)
|
|
*ip = CW(off0wbit | 0x8000);
|
|
else
|
|
*ip = CW(off0wbit & 0x7FFF);
|
|
if (PtInRect(cell, &HxX(list, visible)) &&
|
|
(!(off0wbit & 0x8000) ^ !setit)) {
|
|
off0 = off0wbit & 0x7FFF;
|
|
off1 = CW(ip[1]) & 0x7FFF;
|
|
if (hiliteempty || off0 != off1) {
|
|
|
|
C_LRect(&r, cell, list);
|
|
|
|
saveport = thePort;
|
|
SetPort(HxP(list, port));
|
|
saveclip = PORT_CLIP_REGION_X (thePort);
|
|
PORT_CLIP_REGION_X (thePort) = RM (NewRgn ());
|
|
ClipRect(&r);
|
|
|
|
LISTBEGIN(list);
|
|
/* #define TEMPORARY_HACK_DO_NOT_CHECK_IN */
|
|
#if !defined(TEMPORARY_HACK_DO_NOT_CHECK_IN)
|
|
LISTCALL(lHiliteMsg, setit, &r, cell, off0, off1 - off0, list);
|
|
#endif
|
|
LISTEND(list);
|
|
|
|
DisposeRgn (PORT_CLIP_REGION (thePort));
|
|
PORT_CLIP_REGION_X (thePort) = saveclip;
|
|
SetPort (saveport);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
A4(PRIVATE, void, rectvalue, register Rect *, rp, register INTEGER, value,
|
|
register ListHandle, list, BOOLEAN, hiliteempty)
|
|
{
|
|
register INTEGER *ip, *ep;
|
|
register INTEGER *sp;
|
|
Cell c;
|
|
LISTDECL();
|
|
|
|
LISTBEGIN(list);
|
|
for (c.v = CW(rp->top) ; c.v < CW(rp->bottom); c.v++) {
|
|
c.h = CW(rp->left);
|
|
if ((sp = ip = ROMlib_getoffp(c, list))) {
|
|
for (ep = ip + (CW(rp->right) - CW(rp->left)); ip != ep; ip++)
|
|
if (!(CW(*ip) & 0x8000) ^ !value) {
|
|
c.h = CW(rp->left) + (ip - sp);
|
|
setselectnilflag(value, c, list, hiliteempty);
|
|
}
|
|
}
|
|
}
|
|
LISTEND(list);
|
|
}
|
|
|
|
A5(PRIVATE, void, rect2value, register Rect *, in, register Rect *, butnotin,
|
|
register INTEGER, value, register ListHandle, list,
|
|
BOOLEAN, hiliteempty)
|
|
{
|
|
register INTEGER *ip;
|
|
Cell c;
|
|
|
|
for (c.v = CW(in->top) ; c.v < CW(in->bottom); c.v++)
|
|
for (c.h = CW(in->left) ; c.h < CW(in->right); c.h++)
|
|
if (!PtInRect(c, butnotin) && (ip = ROMlib_getoffp(c, list)))
|
|
if (!(CW(*ip) & 0x8000) ^ !value)
|
|
setselectnilflag(value, c, list, hiliteempty);
|
|
}
|
|
|
|
A1(PRIVATE, void, scrollbyvalues, ListHandle, list)
|
|
{
|
|
INTEGER h, v;
|
|
ControlHandle ch;
|
|
Point p;
|
|
|
|
h = (ch = HxP(list, hScroll)) ? GetCtlValue(ch) : Hx(list, visible.left);
|
|
v = (ch = HxP(list, vScroll)) ? GetCtlValue(ch) : Hx(list, visible.top);
|
|
C_LScroll(h - Hx(list, visible.left), v - Hx(list, visible.top), list);
|
|
HxX(list, visible.left) = CW(h);
|
|
HxX(list, visible.top) = CW(v);
|
|
p.h = Hx(list, cellSize.h);
|
|
p.v = Hx(list, cellSize.v);
|
|
C_LCellSize(p, list);
|
|
}
|
|
|
|
P2(PUBLIC, pascal void, ROMlib_mytrack, ControlHandle, ch, INTEGER, part)
|
|
{
|
|
INTEGER quant, page;
|
|
ListPtr lp;
|
|
|
|
lp = (ListPtr) (long) STARH((Handle) (long) MR(HxX(ch, contrlRfCon)));
|
|
|
|
page = ch == MR(lp->hScroll) ?
|
|
CW(lp->visible.right) - CW(lp->visible.left) - 1
|
|
:
|
|
CW(lp->visible.bottom) - CW(lp->visible.top) - 1;
|
|
|
|
switch (part) {
|
|
case inUpButton:
|
|
quant = -1;
|
|
break;
|
|
case inDownButton:
|
|
quant = 1;
|
|
break;
|
|
case inPageUp:
|
|
quant = -page;
|
|
break;
|
|
case inPageDown:
|
|
quant = page;
|
|
break;
|
|
default:
|
|
gui_assert(0);
|
|
quant = 0;
|
|
break;
|
|
}
|
|
SetCtlValue(ch, GetCtlValue(ch) + quant);
|
|
scrollbyvalues((ListHandle) (long) MR(HxX(ch, contrlRfCon)));
|
|
}
|
|
|
|
#if !defined (BINCOMPAT)
|
|
|
|
#define CALLCLICK(f) (CallPascalB(f))
|
|
|
|
#else /* BINCOMPAT */
|
|
|
|
typedef pascal BOOLEAN (*clickproc)( void );
|
|
|
|
#define CALLCLICK(f) ROMlib_CALLCLICK((clickproc)(f))
|
|
|
|
A1(static inline, BOOLEAN, ROMlib_CALLCLICK, clickproc, fp)
|
|
{
|
|
BOOLEAN retval;
|
|
|
|
ROMlib_hook(list_clicknumber);
|
|
HOOKSAVEREGS();
|
|
retval = CToPascalCall(fp, CTOP_Button);
|
|
HOOKRESTOREREGS();
|
|
return retval;
|
|
}
|
|
|
|
#endif /* BINCOMPAT */
|
|
|
|
P3(PUBLIC pascal trap, BOOLEAN, LClick, Point, pt, /* IMIV-273 */
|
|
INTEGER, mods, ListHandle, list)
|
|
{
|
|
ControlHandle ch, scrollh, scrollv;
|
|
Rect r, rswapped;
|
|
BOOLEAN doubleclick, ctlchanged;
|
|
BOOLEAN hiliteempty, onlyone, userects, disjoint, extend;
|
|
BOOLEAN initial;
|
|
enum { Off, On, UseSense } cellvalue; /* order is important here */
|
|
Byte flags;
|
|
EventRecord evt;
|
|
Rect anchor, oldselrect, newselrect, newcellr, pinrect;
|
|
Cell oldcell, newcell, c, cswapped, oldcellunswapped, newcellunswapped;
|
|
LONGINT l;
|
|
INTEGER dh, dv;
|
|
Point p;
|
|
|
|
doubleclick = FALSE;
|
|
if (PtInRect(pt, &HxX(list, rView))) {
|
|
TRAPBEGIN();
|
|
flags = Hx(list, selFlags);
|
|
newcell.h = CW(pt.h);
|
|
newcell.v = CW(pt.v);
|
|
findcell(&newcell, list);
|
|
if (newcell.h == HxX(list, lastClick.h) &&
|
|
newcell.v == HxX(list, lastClick.v) &&
|
|
TickCount() < Hx(list, clikTime) + CL(DoubleTime))
|
|
doubleclick = TRUE;
|
|
HxX(list, lastClick) = newcell;
|
|
hiliteempty = !(flags & lNoNilHilite);
|
|
if (((mods & shiftKey) || (flags & lExtendDrag)) &&
|
|
!(flags & lOnlyOne)) {
|
|
onlyone = FALSE;
|
|
disjoint = !(flags & lNoDisjoint);
|
|
userects = !(flags & lNoRect);
|
|
cellvalue = (flags & lUseSense) ? UseSense : On;
|
|
extend = (flags & lUseSense) ? FALSE : !(flags & lNoExtend);
|
|
} else if ((mods & cmdKey) && !(flags & lOnlyOne)) {
|
|
onlyone = FALSE;
|
|
disjoint = !(flags & lNoDisjoint);
|
|
userects = FALSE;
|
|
cellvalue = UseSense;
|
|
extend = FALSE;
|
|
} else {
|
|
onlyone = TRUE;
|
|
disjoint = FALSE;
|
|
userects = FALSE;
|
|
cellvalue = On;
|
|
extend = FALSE;
|
|
}
|
|
initial = C_LGetSelect(FALSE, &newcell, list);
|
|
if (cellvalue == UseSense)
|
|
cellvalue = initial ? Off : On;
|
|
if (!disjoint && !initial)
|
|
rectvalue(&HxX(list, dataBounds), Off, list, hiliteempty);
|
|
|
|
if (userects) {
|
|
anchor.top = anchor.bottom = 0;
|
|
if (extend) {
|
|
rswapped = HxX(list, dataBounds);
|
|
r.top = CW(rswapped.top);
|
|
r.left = CW(rswapped.left);
|
|
r.bottom = CW(rswapped.bottom);
|
|
r.right = CW(rswapped.right);
|
|
for (c.h = r.left; c.h < r.right ; c.h++)
|
|
for (c.v = r.top; c.v < r.bottom ; c.v++) {
|
|
cswapped.h = CW(c.h);
|
|
cswapped.v = CW(c.v);
|
|
if (C_LGetSelect(FALSE, &cswapped, list))
|
|
goto out1;
|
|
}
|
|
out1:
|
|
c.h = CW(cswapped.h);
|
|
c.v = CW(cswapped.v);
|
|
if (c.h != r.right) {
|
|
anchor.left = CW(c.h);
|
|
|
|
for (c.h = r.right-1; c.h >= r.left ; c.h--)
|
|
for (c.v = r.top; c.v < r.bottom ; c.v++) {
|
|
cswapped.h = CW(c.h);
|
|
cswapped.v = CW(c.v);
|
|
if (C_LGetSelect(FALSE, &cswapped, list))
|
|
goto out2;
|
|
}
|
|
out2:
|
|
c.h = CW(cswapped.h);
|
|
c.v = CW(cswapped.v);
|
|
anchor.right = CW(c.h + 1);
|
|
|
|
cswapped.h = CW(r.left);
|
|
cswapped.v = CW(r.top);
|
|
C_LGetSelect(TRUE, &cswapped, list);
|
|
anchor.top = cswapped.v;
|
|
|
|
for (c.v = r.bottom - 1; c.v >= r.top ; c.v--)
|
|
for (c.h = r.left; c.h < r.right ; c.h++) {
|
|
cswapped.h = CW(c.h);
|
|
cswapped.v = CW(c.v);
|
|
if (C_LGetSelect(FALSE, &cswapped, list))
|
|
goto out3;
|
|
}
|
|
out3:
|
|
anchor.bottom = CW(CW(cswapped.v) + 1);
|
|
}
|
|
}
|
|
if (anchor.top == anchor.bottom) {
|
|
anchor.top = newcell.v;
|
|
anchor.left = newcell.h;
|
|
anchor.bottom = CW(CW(anchor.top) + 1);
|
|
anchor.right = CW(CW(anchor.left) + 1);
|
|
}
|
|
c.h = CW(anchor.left);
|
|
c.v = CW(anchor.top);
|
|
C_LRect(&rswapped, c, list);
|
|
if (pt.h < CW(rswapped.right) && pt.v < CW(rswapped.bottom)) {
|
|
anchor.top = CW(CW(anchor.bottom) - 1);
|
|
anchor.left = CW(CW(anchor.right) - 1);
|
|
} else {
|
|
anchor.bottom = CW(CW(anchor.top) + 1);
|
|
anchor.right = CW(CW(anchor.left) + 1);
|
|
}
|
|
oldselrect = (flags & lUseSense) ? anchor : HxX(list, dataBounds);
|
|
}
|
|
|
|
HxX(list, clikTime) = CL(TickCount());
|
|
HxX(list, clikLoc.h) = CW(pt.h);
|
|
HxX(list, clikLoc.v) = CW(pt.v);
|
|
oldcell.h = CWC(32767);
|
|
|
|
evt.where.h = CW(pt.h);
|
|
evt.where.v = CW(pt.v);
|
|
pinrect = HxX(list, rView);
|
|
pinrect.left = CW(CW(pinrect.left) - 1);
|
|
pinrect.bottom = CW(CW(pinrect.bottom) - 1);
|
|
do {
|
|
HxX(list, mouseLoc) = evt.where;
|
|
if (HxP(list, lClikLoop))
|
|
if (CALLCLICK(HxP(list, lClikLoop)))
|
|
/*-->*/ break;
|
|
p.h = CW(evt.where.h);
|
|
p.v = CW(evt.where.v);
|
|
if (!PtInRect(p, &HxX(list, rView))) {
|
|
ctlchanged = FALSE;
|
|
scrollh = HxP(list, hScroll);
|
|
scrollv = HxP(list, vScroll);
|
|
dh = 0;
|
|
dv = 0;
|
|
if (CW(evt.where.h) < Hx(list, rView.left)) {
|
|
if (scrollh) {
|
|
SetCtlValue(scrollh, GetCtlValue(scrollh)-1);
|
|
ctlchanged = TRUE;
|
|
} else
|
|
dh = -1;
|
|
} else if (CW(evt.where.h) > Hx(list, rView.right)) {
|
|
if (scrollh) {
|
|
SetCtlValue(scrollh, GetCtlValue(scrollh)+1);
|
|
ctlchanged = TRUE;
|
|
} else
|
|
dh = 1;
|
|
}
|
|
if (CW(evt.where.v) < Hx(list, rView.top)) {
|
|
if (scrollv) {
|
|
SetCtlValue(scrollv, GetCtlValue(scrollv)-1);
|
|
ctlchanged = TRUE;
|
|
} else
|
|
dv = -1;
|
|
} else if (CW(evt.where.v) > Hx(list, rView.bottom)) {
|
|
if (scrollv) {
|
|
SetCtlValue(scrollv, GetCtlValue(scrollv)+1);
|
|
ctlchanged = TRUE;
|
|
} else
|
|
dv = 1;
|
|
}
|
|
if (ctlchanged)
|
|
scrollbyvalues(list);
|
|
else
|
|
C_LScroll(dh, dv, list);
|
|
}
|
|
p.h = CW(evt.where.h);
|
|
p.v = CW(evt.where.v);
|
|
l = PinRect(&pinrect, p);
|
|
newcell.h = CW(LoWord(l));
|
|
newcell.v = CW(HiWord(l));
|
|
findcell(&newcell, list);
|
|
if (userects) {
|
|
newcellr.top = newcell.v;
|
|
newcellr.left = newcell.h;
|
|
newcellr.bottom = CW(CW(newcellr.top) + 1);
|
|
newcellr.right = CW(CW(newcellr.left) + 1);
|
|
UnionRect(&anchor, &newcellr, &newselrect);
|
|
rect2value(&oldselrect, &newselrect, !cellvalue, list,
|
|
hiliteempty);
|
|
rectvalue(&newselrect, cellvalue, list, hiliteempty);
|
|
oldselrect = newselrect;
|
|
} else {
|
|
if (newcell.h != oldcell.h ||
|
|
newcell.v != oldcell.v) {
|
|
if (onlyone && oldcell.h != 32767) {
|
|
oldcellunswapped.h = CW(oldcell.h);
|
|
oldcellunswapped.v = CW(oldcell.v);
|
|
setselectnilflag(FALSE, oldcellunswapped, list,
|
|
hiliteempty);
|
|
}
|
|
newcellunswapped.h = CW(newcell.h);
|
|
newcellunswapped.v = CW(newcell.v);
|
|
setselectnilflag(cellvalue, newcellunswapped, list,
|
|
hiliteempty);
|
|
oldcell = newcell;
|
|
}
|
|
}
|
|
} while (!OSEventAvail(mUpMask, &evt) &&
|
|
(GlobalToLocal(&evt.where), TRUE));
|
|
TRAPEND();
|
|
} else if (((ch = HxP(list, hScroll)) && PtInRect(pt, &HxX(ch, contrlRect))) ||
|
|
((ch = HxP(list, vScroll)) && PtInRect(pt, &HxX(ch, contrlRect)))) {
|
|
if (TestControl(ch, pt) == inThumb) {
|
|
TrackControl(ch, pt, (ProcPtr) 0);
|
|
scrollbyvalues(list);
|
|
} else
|
|
TrackControl(ch, pt, (ProcPtr) P_ROMlib_mytrack);
|
|
}
|
|
return doubleclick;
|
|
return 0;
|
|
}
|
|
|
|
P1(PUBLIC pascal trap, LONGINT, LLastClick, ListHandle, list) /* IMIV-273 */
|
|
{
|
|
return ((LONGINT) Hx(list, lastClick.v) << 16) |
|
|
(unsigned short) Hx(list, lastClick.h);
|
|
}
|
|
|
|
P3(PUBLIC pascal trap, void, LSetSelect, BOOLEAN, setit, /* IMIV-273 */
|
|
Cell, cell, ListHandle, list)
|
|
{
|
|
setselectnilflag(setit, cell, list, TRUE);
|
|
}
|