1 line
11 KiB
C
Executable File
1 line
11 KiB
C
Executable File
/* Copyright (c) 2017, Computer History Museum
|
|
All rights reserved.
|
|
Redistribution and use in source and binary forms, with or without modification, are permitted (subject to
|
|
the limitations in the disclaimer below) provided that the following conditions are met:
|
|
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
|
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
|
|
disclaimer in the documentation and/or other materials provided with the distribution.
|
|
* Neither the name of Computer History Museum nor the names of its contributors may be used to endorse or promote products
|
|
derived from this software without specific prior written permission.
|
|
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE
|
|
COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
|
DAMAGE. */
|
|
|
|
#include "lmgr.h"
|
|
#define FILE_NUM 49
|
|
/* Copyright (c) 1990-1992 by the University of Illinois Board of Trustees */
|
|
/* Copyright (c) 1992 by Qualcomm, Inc. */
|
|
|
|
#pragma segment LMgr
|
|
|
|
/************************************************************************
|
|
* FirstSelected - find the first selection (if any)
|
|
************************************************************************/
|
|
Boolean FirstSelected(Cell *c,ListHandle list)
|
|
{
|
|
c->h = c->v = 0;
|
|
return(LGetSelect(True,c,list));
|
|
}
|
|
|
|
/************************************************************************
|
|
* Next1Selected - get the index (plus 1) of the next selected cell
|
|
* in a 1-dimensional list.
|
|
* returns 0 if no (more) cells selected
|
|
************************************************************************/
|
|
short Next1Selected(short thisOne,ListHandle list)
|
|
{
|
|
Point c;
|
|
c.h = 0;
|
|
c.v = thisOne;
|
|
if (LGetSelect(True,&c,list)) return(c.v+1);
|
|
else return(0);
|
|
}
|
|
|
|
/************************************************************************
|
|
* InWhich1Cell - over which cell (in a 1dim list) is the point?
|
|
************************************************************************/
|
|
short InWhich1Cell(Point mouse,ListHandle list)
|
|
{
|
|
Rect rView = (*list)->rView;
|
|
short cellHi = (*list)->cellSize.v;
|
|
short scroll = (*list)->visible.top;
|
|
short cell;
|
|
|
|
if (!PtInRect(mouse,&rView)) return(0);
|
|
|
|
cell = scroll + (mouse.v-rView.top)/cellHi + 1;
|
|
return(cell);
|
|
}
|
|
|
|
|
|
/************************************************************************
|
|
* Cell1Selected - is a cell in a 1dim list selected?
|
|
************************************************************************/
|
|
Boolean Cell1Selected(short which,ListHandle list)
|
|
{
|
|
Point pt;
|
|
|
|
pt.h = 0; pt.v = which-1;
|
|
return(LGetSelect(False,&pt,list));
|
|
}
|
|
|
|
/************************************************************************
|
|
* SelectSingleCell - select just once cell in a list
|
|
************************************************************************/
|
|
void SelectSingleCell(short which,ListHandle list)
|
|
{
|
|
Point c;
|
|
|
|
c.h = c.v = 0;
|
|
while (LGetSelect(True,&c,list)) LSetSelect(False,c,list);
|
|
if (which>=0)
|
|
{
|
|
c.v = which;
|
|
LSetSelect(True,c,list);
|
|
LAutoScroll(list);
|
|
}
|
|
}
|
|
|
|
|
|
/**********************************************************************
|
|
* MyLDragRgn - make a drag region out of the selected cells
|
|
**********************************************************************/
|
|
RgnHandle MyLDragRgn(ListHandle lHand)
|
|
{
|
|
RgnHandle rgn;
|
|
short s;
|
|
Rect first,r;
|
|
|
|
if (rgn = NewRgn())
|
|
{
|
|
s = 0;
|
|
first = (*lHand)->rView;
|
|
first.bottom = first.top + (*lHand)->cellSize.v;
|
|
OffsetRect(&first,0,-(*lHand)->visible.top*(*lHand)->cellSize.v);
|
|
|
|
while (s=Next1Selected(s,lHand))
|
|
{
|
|
r = first;
|
|
OffsetRect(&r,0,(s-1)*(*lHand)->cellSize.v);
|
|
RgnPlusRect(rgn,&r);
|
|
}
|
|
OutlineRgn(rgn,1);
|
|
GlobalizeRgn(rgn);
|
|
}
|
|
return(rgn);
|
|
}
|
|
/**********************************************************************
|
|
* MyLDragTracker - track a drag in a list rect
|
|
**********************************************************************/
|
|
short MyLDragTracker(DragReference drag,Point pt,short flags,ListHandle lHand)
|
|
{
|
|
Rect r = (*lHand)->rView;
|
|
short scroll = 0;
|
|
short theCell = 0;
|
|
SAVE_STUFF;
|
|
SET_COLORS;
|
|
|
|
ASSERT(flags&ldtInterstice);
|
|
|
|
if (pt.v<r.top) scroll = -1;
|
|
else if (pt.v>r.bottom) scroll = 1;
|
|
|
|
if (scroll)
|
|
{
|
|
HideDragHilite(drag);
|
|
LScroll(0,scroll*(*lHand)->cellSize.v,lHand);
|
|
}
|
|
|
|
if (flags&ldtInterstice)
|
|
{
|
|
if (pt.v<r.top)
|
|
theCell = 1;
|
|
else if (pt.v>r.bottom)
|
|
theCell = (*lHand)->dataBounds.bottom;
|
|
else
|
|
theCell = InWhich1Cell(pt,lHand);
|
|
|
|
if (theCell>(*lHand)->dataBounds.bottom)
|
|
theCell = (*lHand)->dataBounds.bottom;
|
|
|
|
Cell1Rect(lHand,theCell,&r);
|
|
|
|
if (pt.v>(r.top+r.bottom)/2)
|
|
{
|
|
r.top = r.bottom-1;
|
|
r.bottom++;
|
|
}
|
|
else
|
|
{
|
|
theCell--;
|
|
r.top--;
|
|
r.bottom = r.top+2;
|
|
}
|
|
InsetRect(&r,-8,0);
|
|
|
|
if (!(flags&ldtIgnoreSelection) &&
|
|
(theCell==0 && Cell1Selected(1,lHand) ||
|
|
Cell1Selected(theCell,lHand) ||
|
|
theCell<(*lHand)->dataBounds.bottom && Cell1Selected(theCell+1,lHand)))
|
|
{
|
|
HideDragHilite(drag);
|
|
return(-1);
|
|
}
|
|
ShowDragRectHilite(drag,&r,True);
|
|
}
|
|
REST_STUFF;
|
|
return(theCell);
|
|
}
|
|
|
|
/**********************************************************************
|
|
* Cell1Rect - get the rectangle for a given (1-based, 1-dim) cell
|
|
**********************************************************************/
|
|
Rect *Cell1Rect(ListHandle lHand,short cell,Rect *r)
|
|
{
|
|
*r = (*lHand)->rView;
|
|
r->bottom = r->top + (*lHand)->cellSize.v;
|
|
OffsetRect(r,0,(*lHand)->cellSize.v * (cell-(*lHand)->visible.top-1));
|
|
return(r);
|
|
}
|
|
|
|
/************************************************************************
|
|
* ListApp1 - handle an App1 event for a list
|
|
* returns True if handled
|
|
************************************************************************/
|
|
Boolean ListApp1(EventRecord *event, ListHandle lHand)
|
|
{
|
|
short page = RoundDiv((*lHand)->rView.bottom-(*lHand)->rView.top,(*lHand)->cellSize.v)-1;
|
|
switch(event->message & charCodeMask)
|
|
{
|
|
case homeChar:
|
|
page = -REAL_BIG/2;
|
|
break;
|
|
case endChar:
|
|
page = REAL_BIG/2;
|
|
break;
|
|
case pageUpChar:
|
|
page *= -1;
|
|
break;
|
|
case pageDownChar:
|
|
break;
|
|
default:
|
|
return(False);
|
|
}
|
|
LScroll(0,page,lHand);
|
|
return(True);
|
|
}
|
|
|
|
/**********************************************************************
|
|
* LClickWDrag - handle a list click, but allow dragging
|
|
**********************************************************************/
|
|
Boolean LClickWDrag(Point pt, short modifiers, ListHandle lHand, Boolean *drag,void (*hook)(short cell,ListHandle lHand))
|
|
{
|
|
Point glob;
|
|
short cell;
|
|
|
|
*drag = False;
|
|
glob = pt;
|
|
LocalToGlobal(&glob);
|
|
|
|
if ((*lHand)->rView.right-pt.h<GROW_SIZE) return(LClick(pt,modifiers,lHand));
|
|
else
|
|
{
|
|
cell = InWhich1Cell(pt,lHand);
|
|
if (hook) (*hook)(cell,lHand);
|
|
if (*drag = MyWaitMouseMoved(glob,True)) return(False);
|
|
else if (!hook) return (LClick(pt,modifiers,lHand));
|
|
}
|
|
return(False);
|
|
}
|
|
|
|
/**********************************************************************
|
|
* ResizeList - resize a list
|
|
**********************************************************************/
|
|
void ResizeList(ListHandle lHand,Rect *r,Point c)
|
|
{
|
|
Rect oldR = (*lHand)->rView;
|
|
WindowPtr winWP = (*lHand)->port;
|
|
MyWindowPtr win = GetWindowMyWindowPtr(winWP);
|
|
|
|
LSetDrawingMode(False,lHand);
|
|
(*lHand)->rView = *r;
|
|
(*lHand)->cellSize = c;
|
|
LSize(r->right-r->left,r->bottom-r->top,lHand);
|
|
LSetDrawingMode(True,lHand);
|
|
InvalWindowRect(winWP,&oldR);
|
|
InvalWindowRect(winWP,r);
|
|
if (IsMyWindow(winWP)) win->dontGreyOnMe = *r;
|
|
}
|
|
|
|
/************************************************************************
|
|
* MyListHilite - general hilite function for ldef's to use
|
|
************************************************************************/
|
|
void MyListHilite(Boolean lSelect,Rect *lRect,Cell lCell,ListHandle lHandle)
|
|
{
|
|
MyWindowPtr win = GetPortMyWindowPtr(GetQDGlobalsThePort());
|
|
SAVE_STUFF;
|
|
|
|
if (win) {
|
|
RGBBackColor(&win->backColor);
|
|
HiInvertRect(lRect);
|
|
}
|
|
REST_STUFF;
|
|
}
|
|
|
|
// List manager glue stuff
|
|
#undef LAddColumn
|
|
#undef LAddRow
|
|
#undef LDelColumn
|
|
#undef LDelRow
|
|
#undef LSize
|
|
#undef LSetDrawingMode
|
|
#undef LScroll
|
|
#undef LAutoScroll
|
|
#undef LUpdate
|
|
#undef LActivate
|
|
#undef LCellSize
|
|
#undef LClick
|
|
#undef LAddToCell
|
|
#undef LClrCell
|
|
#undef LSetCell
|
|
#undef LSetSelect
|
|
#undef LDraw
|
|
|
|
short MyLAddColumn(short count, short colNum, ListRef lHandle) {short val;SAVE_STUFF;SET_COLORS;val=LAddColumn(count, colNum, lHandle);REST_STUFF;return(val);}
|
|
short MyLAddRow(short count, short rowNum, ListRef lHandle) {short val;SAVE_STUFF;SET_COLORS;val=LAddRow(count, rowNum, lHandle);REST_STUFF;return(val);}
|
|
void MyLDelColumn(short count, short colNum, ListRef lHandle) {SAVE_STUFF;SET_COLORS;LDelColumn(count, colNum, lHandle);REST_STUFF;}
|
|
void MyLDelRow(short count, short rowNum, ListRef lHandle) {SAVE_STUFF;SET_COLORS;LDelRow( count, rowNum, lHandle);REST_STUFF;}
|
|
void MyLSize(short listWidth, short listHeight, ListRef lHandle) {SAVE_STUFF;SET_COLORS;LSize( listWidth, listHeight, lHandle);REST_STUFF;}
|
|
void MyLSetDrawingMode(Boolean drawIt, ListRef lHandle) {SAVE_STUFF;SET_COLORS;LSetDrawingMode( drawIt, lHandle);REST_STUFF;}
|
|
void MyLScroll(short dCols, short dRows, ListRef lHandle) {SAVE_STUFF;SET_COLORS;LScroll( dCols, dRows, lHandle);REST_STUFF;}
|
|
void MyLAutoScroll(ListRef lHandle) {SAVE_STUFF;SET_COLORS;LAutoScroll( lHandle);REST_STUFF;}
|
|
void MyLActivate(Boolean act, ListRef lHandle) {SAVE_STUFF;SET_COLORS;LActivate( act, lHandle);REST_STUFF;}
|
|
void MyLCellSize(Point cSize, ListRef lHandle) {SAVE_STUFF;SET_COLORS;LCellSize( cSize, lHandle);REST_STUFF;}
|
|
Boolean MyLClick(Point pt, short modifiers, ListRef lHandle) {Boolean val;SAVE_STUFF;SET_COLORS;val=LClick( pt, modifiers, lHandle)&&!(modifiers&cmdKey);REST_STUFF;return(val);}
|
|
void MyLAddToCell(const void *dataPtr, short dataLen, Cell theCell, ListRef lHandle) {SAVE_STUFF;SET_COLORS;LAddToCell( dataPtr, dataLen, theCell, lHandle);REST_STUFF;}
|
|
void MyLClrCell(Cell theCell, ListRef lHandle) {SAVE_STUFF;SET_COLORS;LClrCell( theCell, lHandle);REST_STUFF;}
|
|
void MyLSetSelect(Boolean setIt, Cell theCell, ListRef lHandle) {SAVE_STUFF;SET_COLORS;LSetSelect( setIt, theCell, lHandle);REST_STUFF;}
|
|
void MyLDraw(Cell theCell, ListRef lHandle) {SAVE_STUFF;SET_COLORS;LDraw( theCell, lHandle);REST_STUFF;}
|
|
void MyLSetCell(const void *dataPtr, short dataLen, Cell theCell, ListRef lHandle) {SAVE_STUFF;SET_COLORS;LSetCell(dataPtr, dataLen, theCell, lHandle);REST_STUFF;}
|
|
void MyLUpdate(RgnHandle theRgn, ListRef lHandle)
|
|
{
|
|
GrafPtr origPort;
|
|
Rect r=(*lHandle)->rView;
|
|
RgnHandle sectRgn = NewRgn();
|
|
SAVE_STUFF;
|
|
SET_COLORS;
|
|
if (sectRgn)
|
|
{
|
|
if (theRgn)
|
|
{
|
|
RectRgn(sectRgn,&r);
|
|
SectRgn(sectRgn,theRgn,sectRgn);
|
|
GetPort(&origPort);
|
|
SetPort((**lHandle).port);
|
|
EraseRgn(sectRgn);
|
|
SetPort(origPort);
|
|
}
|
|
DisposeRgn(sectRgn);
|
|
}
|
|
LUpdate( theRgn, lHandle);
|
|
REST_STUFF;
|
|
}
|