home *** CD-ROM | disk | FTP | other *** search
/ Executor 2.0 / executorv2.0.iso / pc / dos / extra / source / browser / browser.hqx / Browser / mouse.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-03-28  |  10.6 KB  |  522 lines

  1. #include "go.h"
  2. #include "display.h"
  3.  
  4. #include "disk.proto.h"
  5. #include "mouse.proto.h"
  6. #include "init.proto.h"
  7. #include "window.proto.h"
  8. #include "launch.proto.h"
  9. #include "inithotband.proto.h"
  10. #include "iconmanip.proto.h"
  11. #include "misc.proto.h"
  12. #include "menu.proto.h"
  13. #include "view.proto.h"
  14. #include "windlist.h"
  15.  
  16. ControlHandle (**g_selection)[];
  17.  
  18. int
  19. is_folder (ControlHandle c)
  20. {
  21.   enum actions action;
  22.  
  23.   action = (*(item **) (*c)->contrlData)->action;
  24.   return action == OPENDIR;
  25. }
  26.  
  27. int
  28. is_file (ControlHandle c)
  29. {
  30.   enum actions action;
  31.  
  32.   action = (*(item **) (*c)->contrlData)->action;
  33.   return action != OPENDIR && action != NOACTION;
  34. }
  35.  
  36. int
  37. is_on_hot_band (ControlHandle c)
  38. {
  39.   return (*c)->contrlOwner == g_hotband;
  40. }
  41.  
  42. int
  43. is_volume (ControlHandle c)
  44. {
  45.   StringPtr sp;
  46.   sp = (*c)->contrlTitle;
  47.   return sp[sp[0]] == ':';
  48. }
  49.  
  50. #define NON_EJECTABLE_BIT (1 << 5)
  51.  
  52. int
  53. is_ejectable (ControlHandle c)
  54. {
  55.   HParamBlockRec hpb;
  56.   int retval;
  57.   OSErr e;
  58.  
  59.   if (is_volume (c))
  60.     {
  61.       e = get_HParamBlockRec_from_ControlHandle (&hpb, c);
  62.       retval = e == noErr && !(hpb.volumeParam.ioVAtrb & NON_EJECTABLE_BIT);
  63.     }
  64.   else
  65.     retval = false;
  66.   return retval;
  67. }
  68.  
  69. void
  70. replaceselected (ControlHandle c)
  71. {
  72.   if ((**g_selection)[0] != 0)
  73.     {
  74.       (*(item **) ((*(**g_selection)[0])->contrlData))->selected = false;
  75.       Draw1Control ((**g_selection)[0]);
  76.     }
  77.   (**g_selection)[0] = c;
  78.   if (c != 0)
  79.     {
  80.       (*(item **) (*c)->contrlData)->selected = true;
  81.       Draw1Control (c);
  82.       menuchoices (true);
  83.       if (!is_file (c))
  84.         {
  85.           if (!is_volume (c))
  86.         disable_menu_item (get_info_menuid);
  87.       disable_menu_item (print_menuid);
  88.     }
  89.       if (is_on_hot_band (c))
  90.     disable_menu_item (send_to_hotband_menuid);
  91.       if (!is_ejectable (c))
  92.     disable_menu_item (eject_menuid);
  93.       if (is_volume (c))
  94.     disable_menu_item (duplicate_menuid);
  95.     }
  96.   else
  97.     {
  98.       menuchoices (false);
  99.     }
  100. }
  101.  
  102. short
  103. dirwindowexists (Rect * r)
  104. {
  105.   WindowPeek wp;
  106.  
  107. #ifdef THINK_C
  108.   for (wp = WindowList; wp != 0; wp = wp->nextWindow)
  109. #else
  110.   for (wp = LMGetWindowList (); wp != 0; wp = wp->nextWindow)
  111. #endif
  112.     if (((wp->port.portBits.rowBytes & 0xC000) == 0xC000) &&
  113.     -r->top == (**(*(CGrafPtr) wp).portPixMap).bounds.top &&
  114.     -r->left == (**(*(CGrafPtr) wp).portPixMap).bounds.left)
  115.       return true;
  116.   return false;
  117. }
  118.  
  119. static short
  120. true_vref (ControlHandle c)
  121. {
  122.   short retval;
  123.   
  124.   retval = ICON_VREF (c);
  125.   if (executor_p ())
  126.     {
  127.       OSErr err;
  128.       CInfoPBRec cpb;
  129.       
  130.       cpb.hFileInfo.ioVRefNum = ICON_VREF (c);
  131.       cpb.hFileInfo.ioDirID = ICON_PARENT_ID (c);
  132.       cpb.hFileInfo.ioFDirIndex = 0;
  133.       cpb.hFileInfo.ioNamePtr = ICON_TITLE (c);
  134.       err = unixmount (&cpb);
  135.       if (err == noErr)
  136.         retval = cpb.hFileInfo.ioVRefNum;
  137.     }
  138.   return retval;
  139. }
  140.  
  141. static WindowPtr
  142. find_wind_from_icon (ControlHandle c)
  143. {
  144.   WindowPeek retval;
  145.   short want_vref;
  146.   long want_folderid;
  147.  
  148. #if 0
  149.   want_vref = ICON_VREF (c);
  150. #else
  151.   want_vref = true_vref (c);
  152. #endif
  153.   want_folderid = ICON_FILENUM (c);
  154.   for (retval = WindowList; retval; retval = retval->nextWindow)
  155.     {
  156.       if (browser_window_p ((WindowPtr) retval) && WINDOW_VREF (retval) == want_vref
  157.           && WINDOW_FILENUM (retval) == want_folderid)
  158.         break;
  159.     }
  160.   return (WindowPtr) retval;
  161. }
  162.  
  163. static void
  164. windfromicon (ControlHandle c)
  165. {
  166.   CWindowPtr wp;
  167.   Handle h;
  168.   Rect r;
  169.   OSErr e;
  170.   CInfoPBRec dir;
  171.  
  172. /* TODO: move to .h file */
  173. #define DEFAULTWINDOWWIDTH    5
  174. #define DEFAULTWINDOWHEIGHT    4
  175. enum
  176.   {
  177.     HORIZONTAL_START = 20,
  178.     VERTICAL_START = 40,
  179.     HORIZONTAL_STAGGER = 15,
  180.     VERTICAL_STAGGER = 15
  181.   };
  182.  
  183.   wp = (CWindowPtr) (*c)->contrlOwner;
  184.   h = (*(item **) (*c)->contrlData)->path;
  185.   HandToHand (&h);
  186.   if (wp == (CWindowPtr) g_hotband)
  187.     {
  188.       SetRect (&r, 100, HOTBANDBOTTOM + VERTICAL_START,
  189.            100 + DEFAULTWINDOWWIDTH * ICONWIDTHUSED + HORIZONTAL_START,
  190.            100 + DEFAULTWINDOWHEIGHT * ICONHEIGHTUSED);
  191.     }
  192.   else
  193.     {
  194.       r = (*c)->contrlOwner->portRect;
  195.       OffsetRect (&r, -(*wp->portPixMap)->bounds.left + HORIZONTAL_STAGGER,
  196.           -(*wp->portPixMap)->bounds.top + VERTICAL_STAGGER);
  197.       appenddir (&h, (*c)->contrlTitle);
  198.     }
  199.   while (dirwindowexists (&r))
  200.     {
  201.       OffsetRect (&r, HORIZONTAL_STAGGER, VERTICAL_STAGGER);
  202.       if (r.top > qd.screenBits.bounds.bottom)
  203.     OffsetRect (&r, HORIZONTAL_STAGGER,
  204.             HOTBANDBOTTOM - r.top + VERTICAL_START);
  205.     }
  206.   if (r.left > qd.screenBits.bounds.right)
  207.     OffsetRect (&r, -r.left + HORIZONTAL_STAGGER,
  208.         HOTBANDBOTTOM - r.top + VERTICAL_START);
  209.  
  210.   dir.hFileInfo.ioVRefNum = (*(item **) (*c)->contrlData)->vrefnum;
  211.   dir.hFileInfo.ioDirID = (*(item **) (*c)->contrlData)->ioparid;
  212.   dir.hFileInfo.ioFDirIndex = 0;
  213.   dir.hFileInfo.ioNamePtr = (*c)->contrlTitle;
  214.   e = PBGetCatInfo (&dir, false);
  215.   wp = createdirwindow (&dir, &r, h, (*(item **) (*c)->contrlData)->vrefnum);
  216.   SelectWindow ((WindowPtr) wp);
  217.   showviewmenu (true);
  218.   ShowWindow ((WindowPtr) wp);
  219. }
  220.  
  221. void
  222. activateicon (ControlHandle c, boolean_t close_front_p, boolean_t bring_to_front_p)
  223. {
  224.   WindowPtr window_to_close;
  225.   
  226.   if (close_front_p)
  227.     {
  228.       window_to_close = FrontWindow ();
  229.       if (!browser_window_p (window_to_close))
  230.         window_to_close = 0;
  231.     }
  232.   else
  233.     window_to_close = 0;
  234.     
  235.   switch ((*(item **) (*c)->contrlData)->action)
  236.     {
  237.     WindowPtr w;
  238.     
  239.     case LAUNCH:
  240.       launchapp (c);
  241.       break;
  242.     case OPENDIR:
  243.       if (bring_to_front_p && (w = find_wind_from_icon (c)))
  244.         {
  245.           BringToFront (w);
  246.         }
  247.       else
  248.         windfromicon (c);
  249.       if (window_to_close)
  250.         disposedirwindow (window_to_close);
  251.       break;
  252.     case LAUNCHCREATOR:
  253.       launchcreator (c, appOpen);
  254.       /* TODO */
  255.       break;
  256.     case OPENDA:
  257.       launchda (c);
  258.       break;
  259.     case NOACTION:
  260. /* Do nothing */
  261.       break;
  262.     default:
  263.       break;
  264.     }
  265. }
  266.  
  267. pascal void
  268. scrollicons (ControlHandle c, short part)
  269. {
  270.   bandinfo *p;
  271.   short shown;
  272.  
  273.   p = &bands[g_currentband];
  274.   shown = p->bandpos + g_numdispinhotband;
  275.   if (part == inDownButton)
  276.     {
  277.       if (shown < p->numitems)
  278.     {
  279.       HideControl ((**p->items)[p->bandpos]);
  280.       p->bandpos++;
  281.       shiftband (p->bandpos, -1);
  282.     }
  283. /* shift everything over */
  284.     }
  285.   else if (part == inUpButton)
  286.     {
  287.       if (p->bandpos > 0)
  288.     {
  289.       if (shown <= p->numitems)
  290.         HideControl ((**p->items)[shown - 1]);
  291.       p->bandpos--;
  292.       shiftband (p->bandpos + 1, 1);
  293.     }
  294.     }
  295.   else
  296. /*-->*/ return;
  297. }
  298.  
  299. void
  300. offsetwindow (ControlHandle c, short offset)
  301. {
  302.   short old, new;
  303.   RgnHandle rgn;
  304.   Rect r;
  305.  
  306.   rgn = NewRgn ();
  307.   old = GetCtlValue (c);
  308.   SetCtlValue (c, old + offset);
  309.   new = GetCtlValue (c);
  310.   SetOrigin (0, new);
  311.   r = (*c)->contrlOwner->portRect;
  312.   r.right -= SCROLLBARWIDTH;
  313.  
  314. #if 1
  315.   ++r.right;
  316. #endif
  317.  
  318.   ScrollRect (&r, 0, old - new, rgn);
  319. #if 1
  320. /* TODO: figure out why this isn't a movecontrol */
  321.   OffsetRect (&(*c)->contrlRect, 0, new - old);
  322.   UpdtControl ((*c)->contrlOwner, rgn);
  323. #else /* 0 */
  324.   MoveControl (c, (*c)->contrlRect.left, (*c)->contrlRect.top + new - old);
  325. #endif /* 0 */
  326.   DisposeRgn (rgn);
  327. }
  328.  
  329. pascal void
  330. windowscroller (ControlHandle c, short part)
  331. {
  332.   switch (part)
  333.     {
  334.     case inUpButton:
  335.       offsetwindow (c, -SCROLLSPEED);
  336.       break;
  337.     case inDownButton:
  338.       offsetwindow (c, SCROLLSPEED);
  339.       break;
  340.     case inPageUp:
  341.       offsetwindow (c, (*c)->contrlRect.top - (*c)->contrlRect.bottom);
  342.       break;
  343.     case inPageDown:
  344.       offsetwindow (c, (*c)->contrlRect.bottom - (*c)->contrlRect.top);
  345.       break;
  346.     default:
  347.       break;
  348.     }
  349. }
  350.  
  351. boolean_t
  352. modifiers_to_close_front (short modifiers)
  353. {
  354.   return !!(modifiers & optionKey);
  355. }
  356.  
  357. boolean_t
  358. modifiers_to_bring_to_front (short modifiers)
  359. {
  360.   return !(modifiers & controlKey);
  361. }
  362.  
  363. void
  364. actoncontrol (ControlHandle c, short part, EventRecord * ev)
  365. {
  366.   short before, after;
  367.  
  368.   switch (part)
  369.     {
  370.     case inButton:
  371.     case INSELECTEDICON:
  372.     case INTEXT:
  373.       part = followcontrol (c, part);
  374.       if (part == inButton || part == INTEXT)
  375.     {
  376.       replaceselected (c);
  377.     }
  378.       else if (part == INSELECTEDICON)
  379.     {
  380.       if (ev->when - g_lastclick < GetDblTime ())
  381.         activateicon (c, modifiers_to_close_front (ev->modifiers),
  382.                       modifiers_to_bring_to_front (ev->modifiers));
  383.     }            /* else if (part == INTEXT) {
  384.                    } */
  385.       break;
  386.     case inThumb:
  387.       before = GetCtlValue (c);
  388.       if (TrackControl (c, ev->where, 0))
  389.     {
  390.       after = GetCtlValue (c);
  391. /* I don't like this, but it's the best way I could think of to avoid writing a
  392.  * duplicate function
  393.  */
  394.       SetCtlValue (c, before);
  395.       offsetwindow (c, after - before);
  396.     }
  397.       break;
  398.     case inUpButton:
  399.     case inDownButton:
  400.     case inPageUp:
  401.     case inPageDown:
  402.       TrackControl (c, ev->where, windowscroller);
  403.       break;
  404.     default:
  405.       break;
  406.     }
  407. }
  408.  
  409. void
  410. checkcontrol (EventRecord * ev, WindowPtr wp)
  411. {
  412.   short part;
  413.   ControlHandle c;
  414.   GrafPtr saveport;
  415.  
  416.   GetPort (&saveport);
  417.   SetPort (wp);
  418.   GlobalToLocal (&ev->where);
  419.   part = FindControl (ev->where, wp, &c);
  420.   if (c != (ControlHandle) 0)
  421.     {
  422.       actoncontrol (c, part, ev);
  423.     }
  424.   else if ((**g_selection)[0] != (ControlHandle) 0)
  425.     {
  426.       replaceselected (c);
  427.     }
  428.   SetPort (saveport);
  429. }
  430.  
  431. void
  432. mouseinhotband (EventRecord * ev)
  433. {
  434.   DialogPtr dp;
  435.   short item, part;
  436.   ControlHandle c;
  437.   Point p;
  438.   GrafPtr saveport;
  439.  
  440.   GetPort (&saveport);
  441.   SetPort (g_hotband);
  442.   p = ev->where;
  443.   GlobalToLocal (&p);
  444.   if ((part = FindControl (p, g_hotband, &c)) != 0)
  445.     {
  446.       if ((*c)->contrlDefProc != g_iconcdefproc)
  447.     {            /* see if it's an icon control */
  448.       if (DialogSelect (ev, &dp, &item) && (item <= NUMBANDS))
  449.         {
  450.           setband (item - 1);
  451.           ((WindowPeek) g_hotband)->refCon |= WIPEBIT;
  452.           InvalRect (&g_hotband->portRect);
  453.         }
  454.       else if (item == SORTBUTTON)
  455.         {
  456.           defaultsort ();
  457.         }
  458.       else if (item == HELPBUTTON)
  459.         {
  460.           help ();
  461.         }
  462.     }
  463.       else
  464.     actoncontrol (c, part, ev);
  465.     }
  466.   SetPort (saveport);
  467. }
  468.  
  469. void
  470. domousedown (EventRecord * ev)
  471. {
  472.   WindowPtr wp;
  473.   short where;
  474.  
  475.   where = FindWindow (ev->where, &wp);
  476.   if (wp && wp != FrontWindow ())
  477.     {
  478.       SelectWindow (wp);
  479.       replaceselected ((ControlHandle) 0);
  480.       showviewmenu (wp != g_hotband);
  481.     }
  482.  
  483.   if (wp == g_hotband)
  484.     {
  485.       mouseinhotband (ev);
  486.     }
  487.   else
  488.     {
  489.       switch (where)
  490.     {
  491.     case inDesk:
  492. /* DO NOTHING */
  493.       break;
  494.     case inMenuBar:
  495.       domenu (MenuSelect (ev->where));
  496.       break;
  497.     case inSysWindow:
  498.       SystemClick (ev, wp);
  499.       break;
  500.     case inContent:
  501.       checkcontrol (ev, wp);
  502.       break;
  503.     case inDrag:
  504.       dodragwin (ev->where, wp);
  505.       break;
  506.     case inGrow:
  507.       dogrowwin (ev->where, wp);
  508.       break;
  509.     case inGoAway:
  510.       dogoaway (ev->where, wp);
  511.       break;
  512.     case inZoomIn:
  513.     case inZoomOut:
  514.       do_zoom (where, ev->where, wp);
  515.       break;
  516.     default:
  517.       break;
  518.     }
  519.     }
  520.   g_lastclick = ev->when;
  521. }
  522.