mirror of
https://github.com/ctm/executor.git
synced 2025-02-20 11:28:56 +00:00
369 lines
8.7 KiB
C
369 lines
8.7 KiB
C
#include "go.h"
|
|
#include <string.h>
|
|
#include "xfer.h"
|
|
#include "display.h"
|
|
|
|
#include "inithotband.proto.h"
|
|
#include "init.proto.h"
|
|
#include "initicons.proto.h"
|
|
#include "mouse.proto.h"
|
|
#include "misc.proto.h"
|
|
#include "view.proto.h"
|
|
|
|
DialogPtr g_hotband;
|
|
bandinfo bands[NUMBANDS];
|
|
short g_currentband;
|
|
Handle g_iconcdefproc;
|
|
short g_numdispinhotband;
|
|
|
|
void
|
|
additemtohotband (short whichband, char **path, long parid, short vrefnum,
|
|
short action)
|
|
{
|
|
bandinfo *p;
|
|
ControlHandle c;
|
|
Str255 s;
|
|
item **ih;
|
|
|
|
p = &bands[whichband];
|
|
checkgrowitemarray (p->numitems, p->items);
|
|
tail (*path, s);
|
|
c = (**p->items)[p->numitems] = getnewiconcontrol (g_hotband, path, parid,
|
|
vrefnum, s);
|
|
ih = (item **) (*c)->contrlData;
|
|
(*ih)->action = action;
|
|
|
|
/* setoneicon calls PBGetCatInfo which crashes when called with an offline volume */
|
|
if (whichband != VOLBAND)
|
|
setoneicon (c);
|
|
else
|
|
(*(item **) (*c)->contrlData)->iconfam = &g_diskiconsptr;
|
|
if (g_currentband != whichband)
|
|
setband (whichband);
|
|
if (p->bandpos + g_numdispinhotband > p->numitems)
|
|
{
|
|
MoveControl (c, (p->numitems - p->bandpos) * ICONWIDTHUSED + FIRSTICONX, 0);
|
|
ShowControl (c);
|
|
}
|
|
p->numitems++;
|
|
checkhotbandcontrol ();
|
|
}
|
|
|
|
void
|
|
adjust_ctl_value (ControlHandle c, bandinfo *p)
|
|
{
|
|
if (p->bandpos == 0)
|
|
SetCtlValue (c, 0);
|
|
else if (p->bandpos == p->numitems - g_numdispinhotband)
|
|
SetCtlValue (c, 2);
|
|
else
|
|
SetCtlValue (c, 1);
|
|
}
|
|
|
|
void
|
|
checkhotbandcontrol (void)
|
|
{
|
|
Rect r;
|
|
ControlHandle c;
|
|
short type;
|
|
bandinfo *p;
|
|
short new_hilite_val;
|
|
int old_ctl_val;
|
|
|
|
GetDItem (g_hotband, SCROLLITEM, &type, (Handle *) &c, &r);
|
|
old_ctl_val = GetCtlValue (c);
|
|
p = &bands[g_currentband];
|
|
if (p->numitems > g_numdispinhotband)
|
|
{
|
|
new_hilite_val = 0;
|
|
adjust_ctl_value (c, p);
|
|
}
|
|
else
|
|
{
|
|
if (p->bandpos > 0)
|
|
{
|
|
/* FIXME - what the hell does this mean? The offset is the same as the start? */
|
|
shiftband (p->bandpos, p->bandpos);
|
|
p->bandpos = 0;
|
|
}
|
|
new_hilite_val = 255;
|
|
}
|
|
if (GetCtlValue (c) != old_ctl_val || (*c)->contrlHilite != new_hilite_val)
|
|
{
|
|
if ((*c)->contrlHilite != new_hilite_val)
|
|
HiliteControl (c, new_hilite_val);
|
|
Draw1Control (c);
|
|
}
|
|
}
|
|
|
|
void
|
|
shiftband (short start, short offset)
|
|
{
|
|
ControlHandle c;
|
|
bandinfo *p;
|
|
short pixoffset, first, last, i, x, y;
|
|
short type, old_ctl_val;
|
|
Rect r;
|
|
|
|
GetDItem (g_hotband, SCROLLITEM, &type, (Handle *) & c, &r);
|
|
old_ctl_val = GetCtlValue (c);
|
|
p = &bands[g_currentband];
|
|
pixoffset = offset * ICONWIDTHUSED;
|
|
last = start + g_numdispinhotband;
|
|
if (last > p->numitems)
|
|
last = p->numitems;
|
|
if (offset < 0)
|
|
{
|
|
for (i = start; i < last; i++)
|
|
MoveControl ((**p->items)[i],
|
|
(*(**p->items)[i])->contrlRect.left + pixoffset,
|
|
(*(**p->items)[i])->contrlRect.top);
|
|
}
|
|
else
|
|
{
|
|
for (i = last - 1; i >= start; i--)
|
|
MoveControl ((**p->items)[i],
|
|
(*(**p->items)[i])->contrlRect.left + pixoffset,
|
|
(*(**p->items)[i])->contrlRect.top);
|
|
}
|
|
|
|
y = (*(**p->items)[start])->contrlRect.top;
|
|
if (offset < 0)
|
|
{
|
|
first = p->bandpos + g_numdispinhotband + offset;
|
|
last = first - offset;
|
|
if (last > p->numitems)
|
|
last = p->numitems;
|
|
if (first <= p->numitems && first > 0)
|
|
x = (*(**p->items)[first - 1])->contrlRect.left + ICONWIDTHUSED;
|
|
}
|
|
else
|
|
{
|
|
first = start - offset;
|
|
last = start;
|
|
x = (*(**p->items)[start])->contrlRect.left - pixoffset;
|
|
}
|
|
|
|
for (i = first; i < last; i++)
|
|
{
|
|
MoveControl ((**p->items)[i], x, y);
|
|
ShowControl ((**p->items)[i]);
|
|
x += ICONWIDTHUSED;
|
|
}
|
|
adjust_ctl_value (c, p);
|
|
if (GetCtlValue (c) != old_ctl_val)
|
|
Draw1Control (c);
|
|
}
|
|
|
|
void
|
|
removeitemfromhotband (ControlHandle c)
|
|
{
|
|
/* NOTE: this only works for items in the current band */
|
|
short pos, i;
|
|
bandinfo *p;
|
|
|
|
p = &bands[g_currentband];
|
|
pos = ((*c)->contrlRect.left - FIRSTICONX) / ICONWIDTHUSED + p->bandpos;
|
|
p->numitems--;
|
|
for (i = pos; i < p->numitems; i++)
|
|
(**p->items)[i] = (**p->items)[i + 1];
|
|
DisposHandle ((*(item **) (*c)->contrlData)->path);
|
|
DisposeControl (c);
|
|
shiftband (pos, -1);
|
|
checkhotbandcontrol ();
|
|
}
|
|
|
|
void
|
|
copycontroltohotband (ControlHandle c)
|
|
{
|
|
Handle newpath;
|
|
typeinfo *tip;
|
|
item **ih;
|
|
opendirinfo **infoh;
|
|
short i, band;
|
|
GrafPtr saveport;
|
|
|
|
ih = (item **) (*c)->contrlData;
|
|
newpath = (*ih)->path;
|
|
HandToHand (&newpath);
|
|
appenddir (&newpath, (*c)->contrlTitle);
|
|
if ((*ih)->action == OPENDIR)
|
|
{
|
|
band = FOLDERBAND;
|
|
}
|
|
else
|
|
{
|
|
tip = gettypeinfo ((*(*ih)->iconfam)->type);
|
|
band = tip->band;
|
|
}
|
|
hashicons (c);
|
|
additemtohotband (band, (char **) newpath, (*ih)->ioparid,
|
|
(*ih)->vrefnum, (*ih)->action);
|
|
|
|
if (band == FONTBAND || band == DABAND)
|
|
{
|
|
ParamText ((StringPtr) "\pFonts and Desk Accessories are not yet implemented in the hot band.",
|
|
0, 0, 0);
|
|
NoteAlert (FOUR_PARAM_ALERT, (ProcPtr) 0);
|
|
}
|
|
infoh = (opendirinfo **) ((WindowPeek) (*c)->contrlOwner)->refCon;
|
|
for (i = 0; i < (*infoh)->numitems; i++)
|
|
setoneicon ((**(*infoh)->items)[i]);
|
|
GetPort (&saveport);
|
|
SetPort ((*c)->contrlOwner);
|
|
InvalRect (&(*c)->contrlOwner->portRect);
|
|
SetPort (saveport);
|
|
}
|
|
|
|
void
|
|
selectiontohotband (void)
|
|
{
|
|
copycontroltohotband ((**g_selection)[0]);
|
|
}
|
|
|
|
void
|
|
addvolumes (void)
|
|
{
|
|
OSErr e;
|
|
ParamBlockRec pb;
|
|
short i, len;
|
|
Str255 s;
|
|
char **path;
|
|
|
|
e = noErr;
|
|
pb.volumeParam.ioNamePtr = s;
|
|
for (i = 1; e == noErr; i++)
|
|
{
|
|
pb.volumeParam.ioVolIndex = i;
|
|
e = PBGetVInfo (&pb, false);
|
|
/* todo: figure out which type of disk icon to use */
|
|
if (e == noErr)
|
|
{
|
|
len = pb.volumeParam.ioNamePtr[0];
|
|
path = (char **) NewHandle (len + 2);
|
|
PtoCstr (pb.volumeParam.ioNamePtr);
|
|
strcpy (*path, (char *) pb.volumeParam.ioNamePtr);
|
|
(*path)[len] = ':';
|
|
(*path)[len + 1] = 0;
|
|
additemtohotband (VOLBAND, path, 0, pb.volumeParam.ioVRefNum, OPENDIR);
|
|
}
|
|
}
|
|
g_iconcdefproc = (*(**bands[VOLBAND].items)[0])->contrlDefProc;
|
|
}
|
|
|
|
void
|
|
resetvolumes (void)
|
|
{
|
|
bandinfo *p;
|
|
ControlHandle c;
|
|
short i;
|
|
GrafPtr saveport;
|
|
|
|
p = &bands[VOLBAND];
|
|
for (i = p->numitems - 1; i >= 0; i--)
|
|
{
|
|
c = (**p->items)[i];
|
|
DisposHandle ((*(item **) (*c)->contrlData)->path);
|
|
DisposeControl (c);
|
|
}
|
|
p->numitems = 0;
|
|
|
|
addvolumes ();
|
|
for (i = 0; i < p->numitems; i++)
|
|
(*(item **) (*(**p->items)[i])->contrlData)->iconfam = &g_diskiconsptr;
|
|
GetPort (&saveport);
|
|
SetPort (g_hotband);
|
|
InvalRect (&g_hotband->portRect);
|
|
SetPort (saveport);
|
|
}
|
|
|
|
void
|
|
fillbands (FILE * f)
|
|
{
|
|
/* todo: check the value of e after the getinfo calls */
|
|
CInfoPBRec cpb;
|
|
short c, whichband, action;
|
|
OSErr e;
|
|
char **path;
|
|
short volume;
|
|
typeinfo *tip;
|
|
|
|
cpb.hFileInfo.ioFDirIndex = 0;
|
|
while ((c = getc (f)) && (c != EOF) && (c != '\n'))
|
|
{
|
|
ungetc (c, f);
|
|
e = getonefileinfo (f, &cpb, &path, &volume);
|
|
if (cpb.hFileInfo.ioFlAttrib & DIRBIT)
|
|
{
|
|
whichband = FOLDERBAND;
|
|
action = OPENDIR;
|
|
}
|
|
else
|
|
{
|
|
tip = gettypeinfo (cpb.hFileInfo.ioFlFndrInfo.fdType);
|
|
whichband = tip->band;
|
|
action = tip->action;
|
|
}
|
|
if (e == noErr)
|
|
additemtohotband (whichband, path, cpb.hFileInfo.ioFlParID,
|
|
volume, action);
|
|
#if 0
|
|
else
|
|
printf ("couldn't find %s\n", *path);
|
|
#endif
|
|
}
|
|
}
|
|
|
|
void
|
|
inithotband (FILE * f)
|
|
{
|
|
short type;
|
|
Handle h;
|
|
Rect r;
|
|
short i, j;
|
|
|
|
g_hotband = GetNewDialog (HOTBANDRESID, (Ptr) 0, (WindowPtr) - 1);
|
|
MoveWindow (g_hotband, 0, MENUBARHEIGHT, false);
|
|
SizeWindow (g_hotband, qd.screenBits.bounds.right, HOTBANDHEIGHT, true);
|
|
|
|
GetDItem (g_hotband, SCROLLITEM, &type, &h, &r);
|
|
SetCtlMin ((ControlHandle) h, 0);
|
|
SetCtlMax ((ControlHandle) h, 2);
|
|
MoveControl ((ControlHandle) h, FIRSTICONX - ICONWIDTHUSED / 2, 0);
|
|
SizeControl ((ControlHandle) h, qd.screenBits.bounds.right -
|
|
(*(ControlHandle) h)->contrlRect.left, ICONHEIGHTUSED);
|
|
SetDItem (g_hotband, SCROLLITEM, type, h, &(*(ControlHandle) h)->contrlRect);
|
|
SetCtlAction ((ControlHandle) h, scrollicons);
|
|
g_numdispinhotband = (qd.screenBits.bounds.right - FIRSTICONX) / ICONWIDTHUSED;
|
|
if (g_numdispinhotband < 1)
|
|
g_numdispinhotband = 1;
|
|
|
|
for (i = 0; i < NUMBANDS; i++)
|
|
{
|
|
bands[i].bandpos = 0;
|
|
bands[i].numitems = 0;
|
|
bands[i].sortorder = ALPHABETIC;
|
|
bands[i].items =
|
|
(ControlHandle (**)[])NewHandle (BANDARRAYSIZE * sizeof (ControlHandle));
|
|
}
|
|
inithash ();
|
|
/* This line is important. g_currentband must be initialized before setband is called */
|
|
g_currentband = APPBAND;
|
|
addvolumes ();
|
|
|
|
if (f != 0)
|
|
fillbands (f);
|
|
|
|
for (j = 0; j < NUMBANDS; j++)
|
|
if (j != VOLBAND && j != FOLDERBAND)
|
|
for (i = 0; i < bands[j].numitems; i++)
|
|
hashicons ((**bands[j].items)[i]);
|
|
|
|
seticons ();
|
|
if (bands[APPBAND].numitems > 0)
|
|
setband (APPBAND);
|
|
else
|
|
setband (VOLBAND);
|
|
ShowWindow (g_hotband);
|
|
}
|