mirror of
https://github.com/ctm/executor.git
synced 2024-12-22 13:30:41 +00:00
425 lines
8.5 KiB
C
425 lines
8.5 KiB
C
#include "go.h"
|
|
#include "display.h"
|
|
|
|
#include "mouse.proto.h"
|
|
#include "init.proto.h"
|
|
#include "window.proto.h"
|
|
#include "launch.proto.h"
|
|
#include "inithotband.proto.h"
|
|
#include "iconmanip.proto.h"
|
|
#include "misc.proto.h"
|
|
#include "menu.proto.h"
|
|
#include "view.proto.h"
|
|
|
|
ControlHandle (**g_selection)[];
|
|
|
|
int is_file (ControlHandle c)
|
|
{
|
|
enum actions action;
|
|
|
|
action = (*(item **) (*c)->contrlData)->action;
|
|
return action != OPENDIR && action != NOACTION;
|
|
}
|
|
|
|
int
|
|
is_on_hot_band (ControlHandle c)
|
|
{
|
|
return (*c)->contrlOwner == g_hotband;
|
|
}
|
|
|
|
int
|
|
is_volume (ControlHandle c)
|
|
{
|
|
StringPtr sp;
|
|
sp = (*c)->contrlTitle;
|
|
return sp[sp[0]] == ':';
|
|
}
|
|
|
|
#define NON_EJECTABLE_BIT (1 << 5)
|
|
|
|
int
|
|
is_ejectable (ControlHandle c)
|
|
{
|
|
HParamBlockRec hpb;
|
|
int retval;
|
|
OSErr e;
|
|
|
|
if (is_volume (c))
|
|
{
|
|
e = get_HParamBlockRec_from_ControlHandle (&hpb, c);
|
|
retval = e == noErr && !(hpb.volumeParam.ioVAtrb & NON_EJECTABLE_BIT);
|
|
}
|
|
else
|
|
retval = false;
|
|
return retval;
|
|
}
|
|
|
|
void
|
|
replaceselected (ControlHandle c)
|
|
{
|
|
if ((**g_selection)[0] != 0)
|
|
{
|
|
(*(item **) ((*(**g_selection)[0])->contrlData))->selected = false;
|
|
Draw1Control ((**g_selection)[0]);
|
|
}
|
|
(**g_selection)[0] = c;
|
|
if (c != 0)
|
|
{
|
|
(*(item **) (*c)->contrlData)->selected = true;
|
|
Draw1Control (c);
|
|
menuchoices (true);
|
|
if (!is_file (c))
|
|
disable_menu_item (get_info_menuid);
|
|
if (is_on_hot_band (c))
|
|
disable_menu_item (send_to_hotband_menuid);
|
|
if (!is_ejectable (c))
|
|
disable_menu_item (eject_menuid);
|
|
if (is_volume (c))
|
|
disable_menu_item (duplicate_menuid);
|
|
}
|
|
else
|
|
{
|
|
menuchoices (false);
|
|
}
|
|
}
|
|
|
|
short
|
|
dirwindowexists (Rect * r)
|
|
{
|
|
WindowPeek wp;
|
|
|
|
#ifdef THINK_C
|
|
for (wp = WindowList; wp != 0; wp = wp->nextWindow)
|
|
#else
|
|
for (wp = LMGetWindowList (); wp != 0; wp = wp->nextWindow)
|
|
#endif
|
|
if (((wp->port.portBits.rowBytes & 0xC000) == 0xC000) &&
|
|
-r->top == (**(*(CGrafPtr) wp).portPixMap).bounds.top &&
|
|
-r->left == (**(*(CGrafPtr) wp).portPixMap).bounds.left)
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
void
|
|
windfromicon (ControlHandle c)
|
|
{
|
|
CWindowPtr wp;
|
|
Handle h;
|
|
Rect r;
|
|
OSErr e;
|
|
CInfoPBRec dir;
|
|
|
|
/* TODO: move to .h file */
|
|
#define DEFAULTWINDOWWIDTH 5
|
|
#define DEFAULTWINDOWHEIGHT 4
|
|
enum
|
|
{
|
|
HORIZONTAL_START = 20,
|
|
VERTICAL_START = 40,
|
|
HORIZONTAL_STAGGER = 15,
|
|
VERTICAL_STAGGER = 15
|
|
};
|
|
|
|
wp = (CWindowPtr) (*c)->contrlOwner;
|
|
h = (*(item **) (*c)->contrlData)->path;
|
|
HandToHand (&h);
|
|
if (wp == (CWindowPtr) g_hotband)
|
|
{
|
|
SetRect (&r, 100, HOTBANDBOTTOM + VERTICAL_START,
|
|
100 + DEFAULTWINDOWWIDTH * ICONWIDTHUSED + HORIZONTAL_START,
|
|
100 + DEFAULTWINDOWHEIGHT * ICONHEIGHTUSED);
|
|
}
|
|
else
|
|
{
|
|
r = (*c)->contrlOwner->portRect;
|
|
OffsetRect (&r, -(*wp->portPixMap)->bounds.left,
|
|
-(*wp->portPixMap)->bounds.top + VERTICAL_STAGGER);
|
|
appenddir (&h, (*c)->contrlTitle);
|
|
}
|
|
while (dirwindowexists (&r))
|
|
{
|
|
OffsetRect (&r, 0, VERTICAL_STAGGER);
|
|
if (r.top > qd.screenBits.bounds.bottom)
|
|
OffsetRect (&r, HORIZONTAL_STAGGER,
|
|
HOTBANDBOTTOM - r.top + VERTICAL_START);
|
|
}
|
|
if (r.left > qd.screenBits.bounds.right)
|
|
OffsetRect (&r, -r.left + HORIZONTAL_STAGGER,
|
|
HOTBANDBOTTOM - r.top + VERTICAL_START);
|
|
|
|
dir.hFileInfo.ioVRefNum = (*(item **) (*c)->contrlData)->vrefnum;
|
|
dir.hFileInfo.ioDirID = (*(item **) (*c)->contrlData)->ioparid;
|
|
dir.hFileInfo.ioFDirIndex = 0;
|
|
dir.hFileInfo.ioNamePtr = (*c)->contrlTitle;
|
|
e = PBGetCatInfo (&dir, false);
|
|
wp = createdirwindow (&dir, &r, h, (*(item **) (*c)->contrlData)->vrefnum);
|
|
SelectWindow ((WindowPtr) wp);
|
|
showviewmenu (true);
|
|
ShowWindow ((WindowPtr) wp);
|
|
}
|
|
|
|
void
|
|
activateicon (ControlHandle c)
|
|
{
|
|
switch ((*(item **) (*c)->contrlData)->action)
|
|
{
|
|
case LAUNCH:
|
|
launchapp (c);
|
|
break;
|
|
case OPENDIR:
|
|
windfromicon (c);
|
|
break;
|
|
case LAUNCHCREATOR:
|
|
launchcreator (c, appOpen);
|
|
/* TODO */
|
|
break;
|
|
case OPENDA:
|
|
launchda (c);
|
|
break;
|
|
case NOACTION:
|
|
/* Do nothing */
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
pascal void
|
|
scrollicons (ControlHandle c, short part)
|
|
{
|
|
bandinfo *p;
|
|
short shown;
|
|
|
|
p = &bands[g_currentband];
|
|
shown = p->bandpos + g_numdispinhotband;
|
|
if (part == inDownButton)
|
|
{
|
|
if (shown < p->numitems)
|
|
{
|
|
HideControl ((**p->items)[p->bandpos]);
|
|
p->bandpos++;
|
|
shiftband (p->bandpos, -1);
|
|
}
|
|
/* shift everything over */
|
|
}
|
|
else if (part == inUpButton)
|
|
{
|
|
if (p->bandpos > 0)
|
|
{
|
|
if (shown <= p->numitems)
|
|
HideControl ((**p->items)[shown - 1]);
|
|
p->bandpos--;
|
|
shiftband (p->bandpos + 1, 1);
|
|
}
|
|
}
|
|
else
|
|
/*-->*/ return;
|
|
}
|
|
|
|
void
|
|
offsetwindow (ControlHandle c, short offset)
|
|
{
|
|
short old, new;
|
|
RgnHandle rgn;
|
|
Rect r;
|
|
|
|
rgn = NewRgn ();
|
|
old = GetCtlValue (c);
|
|
SetCtlValue (c, old + offset);
|
|
new = GetCtlValue (c);
|
|
SetOrigin (0, new);
|
|
r = (*c)->contrlOwner->portRect;
|
|
r.right -= SCROLLBARWIDTH;
|
|
|
|
#if 1
|
|
++r.right;
|
|
#endif
|
|
|
|
ScrollRect (&r, 0, old - new, rgn);
|
|
#if 1
|
|
/* TODO: figure out why this isn't a movecontrol */
|
|
OffsetRect (&(*c)->contrlRect, 0, new - old);
|
|
UpdtControl ((*c)->contrlOwner, rgn);
|
|
#else /* 0 */
|
|
MoveControl (c, (*c)->contrlRect.left, (*c)->contrlRect.top + new - old);
|
|
#endif /* 0 */
|
|
DisposeRgn (rgn);
|
|
}
|
|
|
|
pascal void
|
|
windowscroller (ControlHandle c, short part)
|
|
{
|
|
switch (part)
|
|
{
|
|
case inUpButton:
|
|
offsetwindow (c, -SCROLLSPEED);
|
|
break;
|
|
case inDownButton:
|
|
offsetwindow (c, SCROLLSPEED);
|
|
break;
|
|
case inPageUp:
|
|
offsetwindow (c, (*c)->contrlRect.top - (*c)->contrlRect.bottom);
|
|
break;
|
|
case inPageDown:
|
|
offsetwindow (c, (*c)->contrlRect.bottom - (*c)->contrlRect.top);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
void
|
|
actoncontrol (ControlHandle c, short part, EventRecord * ev)
|
|
{
|
|
short before, after;
|
|
|
|
switch (part)
|
|
{
|
|
case inButton:
|
|
case INSELECTEDICON:
|
|
case INTEXT:
|
|
part = followcontrol (c, part);
|
|
if (part == inButton || part == INTEXT)
|
|
{
|
|
replaceselected (c);
|
|
}
|
|
else if (part == INSELECTEDICON)
|
|
{
|
|
if (ev->when - g_lastclick < GetDblTime ())
|
|
activateicon (c);
|
|
} /* else if (part == INTEXT) {
|
|
} */
|
|
break;
|
|
case inThumb:
|
|
before = GetCtlValue (c);
|
|
if (TrackControl (c, ev->where, 0))
|
|
{
|
|
after = GetCtlValue (c);
|
|
/* I don't like this, but it's the best way I could think of to avoid writing a
|
|
* duplicate function
|
|
*/
|
|
SetCtlValue (c, before);
|
|
offsetwindow (c, after - before);
|
|
}
|
|
break;
|
|
case inUpButton:
|
|
case inDownButton:
|
|
case inPageUp:
|
|
case inPageDown:
|
|
TrackControl (c, ev->where, windowscroller);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
void
|
|
checkcontrol (EventRecord * ev, WindowPtr wp)
|
|
{
|
|
short part;
|
|
ControlHandle c;
|
|
GrafPtr saveport;
|
|
|
|
GetPort (&saveport);
|
|
SetPort (wp);
|
|
GlobalToLocal (&ev->where);
|
|
part = FindControl (ev->where, wp, &c);
|
|
if (c != (ControlHandle) 0)
|
|
{
|
|
actoncontrol (c, part, ev);
|
|
}
|
|
else if ((**g_selection)[0] != (ControlHandle) 0)
|
|
{
|
|
replaceselected (c);
|
|
}
|
|
SetPort (saveport);
|
|
}
|
|
|
|
void
|
|
mouseinhotband (EventRecord * ev)
|
|
{
|
|
DialogPtr dp;
|
|
short item, part;
|
|
ControlHandle c;
|
|
Point p;
|
|
GrafPtr saveport;
|
|
|
|
GetPort (&saveport);
|
|
SetPort (g_hotband);
|
|
p = ev->where;
|
|
GlobalToLocal (&p);
|
|
if ((part = FindControl (p, g_hotband, &c)) != 0)
|
|
{
|
|
if ((*c)->contrlDefProc != g_iconcdefproc)
|
|
{ /* see if it's an icon control */
|
|
if (DialogSelect (ev, &dp, &item) && (item <= NUMBANDS))
|
|
{
|
|
setband (item - 1);
|
|
((WindowPeek) g_hotband)->refCon |= WIPEBIT;
|
|
InvalRect (&g_hotband->portRect);
|
|
}
|
|
else if (item == SORTBUTTON)
|
|
{
|
|
defaultsort ();
|
|
}
|
|
else if (item == HELPBUTTON)
|
|
{
|
|
help ();
|
|
}
|
|
}
|
|
else
|
|
actoncontrol (c, part, ev);
|
|
}
|
|
SetPort (saveport);
|
|
}
|
|
|
|
void
|
|
domousedown (EventRecord * ev)
|
|
{
|
|
WindowPtr wp;
|
|
short where;
|
|
|
|
where = FindWindow (ev->where, &wp);
|
|
if (wp && ((WindowPeek) wp)->windowKind == userKind)
|
|
{
|
|
SelectWindow (wp);
|
|
replaceselected ((ControlHandle) 0);
|
|
showviewmenu (wp != g_hotband);
|
|
}
|
|
|
|
if (wp == g_hotband)
|
|
{
|
|
mouseinhotband (ev);
|
|
}
|
|
else
|
|
{
|
|
switch (where)
|
|
{
|
|
case inDesk:
|
|
/* DO NOTHING */
|
|
break;
|
|
case inMenuBar:
|
|
domenu (MenuSelect (ev->where));
|
|
break;
|
|
case inSysWindow:
|
|
SystemClick (ev, wp);
|
|
break;
|
|
case inContent:
|
|
checkcontrol (ev, wp);
|
|
break;
|
|
case inDrag:
|
|
dodragwin (ev->where, wp);
|
|
break;
|
|
case inGrow:
|
|
dogrowwin (ev->where, wp);
|
|
break;
|
|
case inGoAway:
|
|
dogoaway (ev->where, wp);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
g_lastclick = ev->when;
|
|
}
|