home *** CD-ROM | disk | FTP | other *** search
/ Info-Mac 3 / Info_Mac_1994-01.iso / Development / Source / Macintosh Tracker 1.1 Source / Tracker Client Folder / CSongList.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-06-05  |  12.6 KB  |  478 lines  |  [TEXT/KAHL]

  1. /* CSongList.c */
  2.  
  3. #include "CSongList.h"
  4. #include "CVScrollBar.h"
  5. #include "CMyDocument.h"
  6. #include "CWindow.h"
  7. #include "CArray.h"
  8. #include "CApplication.h"
  9. #include "Memory.h"
  10. #include "MenuController.h"
  11. #include "LocationConstants.h"
  12. #include "CMyApplication.h"
  13.  
  14.  
  15. #define InitialOffset (1)
  16. #define MarkerInset (5)
  17. #define SELECTIONTHICKNESS (2)
  18. #define MaxTypedCharDelay (30)
  19.  
  20.  
  21. void                CSongList::ISongList(CMyDocument* TheDocument, CWindow* TheWindow)
  22.     {
  23.         LongPoint            Start,Extent;
  24.         CVScrollBar*    OurScroller;
  25.         FontInfo            MyFontInfo;
  26.  
  27.         Document = TheDocument;
  28.         GetRect(ScrollingListLocID,&Start,&Extent);
  29.         IViewRect(Start,Extent,TheWindow,TheWindow);
  30.  
  31.         GetRect(ScrollingListBarLocID,&Start,&Extent);
  32.         OurScroller = new CVScrollBar;
  33.         VScroll = OurScroller;
  34.         OurScroller->IVScrollBar(Start,Extent,this,TheWindow,TheWindow);
  35.  
  36.         LastClickTime = TickCount();
  37.         LastCharTime = TickCount();
  38.         StartingIndex = 0;
  39.         CharBufferLength = 0;
  40.  
  41.         SetUpPort();
  42.         Window->SetText(systemFont,0,srcCopy,12,0);
  43.         GetFontInfo(&MyFontInfo);
  44.         LineHeight = MyFontInfo.leading + MyFontInfo.ascent + MyFontInfo.descent;
  45.     }
  46.  
  47.  
  48. void                CSongList::DoMouseDown(MyEventRec Event)
  49.     {
  50.         long                SongIndex;
  51.         long                CurrentIndex;
  52.  
  53.         BecomeKeyReceiver();
  54.         Event.Where = MyGlobalToLocal(Event.Where);
  55.         SongIndex = StartingIndex + (Event.Where.y / LineHeight);
  56.  
  57.         if (((Event.Modifiers & optionKey) != 0) && (Document->Selection != -1))
  58.             {
  59.                 MyBoolean            InWindow;
  60.  
  61.              MoveSelection:
  62.                 CurrentIndex = -1;
  63.                 InWindow = False;
  64.                 do
  65.                     {
  66.                         long                    Index2;
  67.  
  68.                         Event.Where = MyGlobalToLocal(GetLongMouseLoc());
  69.                         if ((Event.Where.y < 0) && (StartingIndex > 0))
  70.                             {
  71.                                 Hook(VScrollUpOne,0,0);
  72.                             }
  73.                         if ((Event.Where.y > Extent.y) && (StartingIndex <
  74.                             Document->ListOfSongs->GetNumElements() - ((Extent.y - 2) / LineHeight)))
  75.                             {
  76.                                 Hook(VScrollDownOne,0,0);
  77.                             }
  78.                         Index2 = StartingIndex + (Event.Where.y / LineHeight);
  79.                         if ((Event.Where.x >= 0) && (Event.Where.x < Extent.x))
  80.                             {
  81.                                 if ((CurrentIndex != Index2) || !InWindow)
  82.                                     {
  83.                                         InWindow = True;
  84.                                         Redraw(CurrentIndex - 1,CurrentIndex);
  85.                                         CurrentIndex = Index2;
  86.                                         SetUpPort();
  87.                                         Window->ResetPen();
  88.                                         Window->LEraseRect(LongPointOf(1,(CurrentIndex - StartingIndex)
  89.                                             * LineHeight - SELECTIONTHICKNESS - 1),LongPointOf(Extent.x - 2,1));
  90.                                         Window->LPaintRect(LongPointOf(1,(CurrentIndex - StartingIndex)
  91.                                             * LineHeight - SELECTIONTHICKNESS),
  92.                                             LongPointOf(Extent.x - 2,2 * SELECTIONTHICKNESS));
  93.                                         Window->LEraseRect(LongPointOf(1,(CurrentIndex - StartingIndex)
  94.                                             * LineHeight + SELECTIONTHICKNESS),LongPointOf(Extent.x - 2,1));
  95.                                     }
  96.                             }
  97.                          else
  98.                             {
  99.                                 if ((CurrentIndex != Index2) || InWindow)
  100.                                     {
  101.                                         InWindow = False;
  102.                                         Redraw(CurrentIndex - 1,CurrentIndex);
  103.                                         CurrentIndex = Index2;
  104.                                     }
  105.                             }
  106.                         RelinquishCPUJudiciously();
  107.                     } while (StillDown());
  108.                 Redraw(CurrentIndex - 1,CurrentIndex);
  109.                 if (InWindow)
  110.                     {
  111.                         /* only move item if mouse released inside the pane */
  112.                         Document->MoveSong(Document->Selection,CurrentIndex);
  113.                     }
  114.                 return;
  115.             }
  116.  
  117.         if ((Event.When - LastClickTime < DoubleTime)
  118.             && (SongIndex == Document->Selection))
  119.             {
  120.                 /* double click--stop current song and play new song */
  121.                 Document->StartThisSong(SongIndex);
  122.             }
  123.          else
  124.             {
  125.                 /* single click--just change the selection */
  126.                 if ((SongIndex >= 0) && (SongIndex < Document->ListOfSongs->GetNumElements()))
  127.                     {
  128.                         Document->SetNewSelection(SongIndex);
  129.                     }
  130.                 while (StillDown())
  131.                     {
  132.                         Event.Where = MyGlobalToLocal(GetLongMouseLoc());
  133.                         CurrentIndex = StartingIndex + (Event.Where.y / LineHeight);
  134.                         if (CurrentIndex != SongIndex)
  135.                             {
  136.                                 goto MoveSelection;
  137.                             }
  138.                         RelinquishCPUJudiciously();
  139.                     }
  140.             }
  141.         LastClickTime = Event.When;
  142.     }
  143.  
  144.  
  145. MyBoolean        CSongList::DoKeyDown(MyEventRec Event)
  146.     {
  147.         long                Temp;
  148.  
  149.         switch (Event.Message & charCodeMask)
  150.             {
  151.                 case (uchar)0x1e:  /* macintosh up arrow */
  152.                     if (Document->Selection > 0)
  153.                         {
  154.                             long            StartTemp;
  155.  
  156.                             Document->SetNewSelection(Document->Selection - 1);
  157.                          GetSelectionOnScreen:
  158.                             StartTemp = StartingIndex;
  159.                             while (Document->Selection < StartTemp)
  160.                                 {
  161.                                     StartTemp -= 1;
  162.                                 }
  163.                             while (Document->Selection > StartTemp
  164.                                 + ((Extent.y - 2) / LineHeight) - 1)
  165.                                 {
  166.                                     StartTemp += 1;
  167.                                 }
  168.                             Hook(VScrollToLocation,StartTemp,0);
  169.                         }
  170.                     return True;
  171.                 case (uchar)0x1f:  /* macintosh down arrow */
  172.                     if (Document->Selection < Document->ListOfSongs->GetNumElements() - 1)
  173.                         {
  174.                             Document->SetNewSelection(Document->Selection + 1);
  175.                             goto GetSelectionOnScreen;
  176.                         }
  177.                     return True;
  178.                 case (uchar)0x0d:  /* return key */
  179.                 case (uchar)0x03:  /* enter key */
  180.                     Document->StartThisSong(Document->Selection);
  181.                     return True;
  182.                 default:
  183.                     BecomeKeyReceiver();
  184.                     if (TickCount() - LastCharTime > MaxTypedCharDelay)
  185.                         {
  186.                             CharBufferLength = 0;
  187.                         }
  188.                     if (CharBufferLength < MAXTYPEDCHARS)
  189.                         {
  190.                             CharBuffer[CharBufferLength] = Event.Message & charCodeMask;
  191.                             CharBufferLength += 1;
  192.                         }
  193.                     Temp = 0;
  194.                     while (Temp < Document->ListOfSongs->GetNumElements())
  195.                         {
  196.                             SongRec*            TempSongLoc;
  197.  
  198.                             TempSongLoc = Document->ListOfSongs->GetElementAddress(Temp);
  199.                             /* we won't move memory... I promise! */
  200.                             if (TempSongLoc->SongName[0] >= CharBufferLength)
  201.                                 {
  202.                                     MyBoolean                OK;
  203.                                     short                        Scan;
  204.                                     char                        First;
  205.                                     char                        Second;
  206.  
  207.                                     OK = True;
  208.                                     Scan = 0;
  209.                                     while ((Scan < CharBufferLength) && OK)
  210.                                         {
  211.                                             First = CharBuffer[Scan];
  212.                                             Second = TempSongLoc->SongName[Scan + 1];
  213.                                             if ((First >= 'A') && (First <= 'Z'))
  214.                                                 {
  215.                                                     First = First - 'A' + 'a';
  216.                                                 }
  217.                                             if ((Second >= 'A') && (Second <= 'Z'))
  218.                                                 {
  219.                                                     Second = Second - 'A' + 'a';
  220.                                                 }
  221.                                             OK = (First == Second);
  222.                                             Scan += 1;
  223.                                         }
  224.                                     if (OK)
  225.                                         {
  226.                                             Document->SetNewSelection(Temp);
  227.                                             LastCharTime = TickCount();
  228.                                             goto GetSelectionOnScreen;
  229.                                         }
  230.                                 }
  231.                             Temp += 1;
  232.                         }
  233.                     Document->SetNewSelection(-1);
  234.                     LastCharTime = TickCount();
  235.                     return True;
  236.             }
  237.     }
  238.  
  239.  
  240. void                CSongList::DoUpdate(void)
  241.     {
  242.         SetUpPort();
  243.         Window->ResetPen();
  244.         Window->LFrameRect(ZeroPoint,Extent);
  245.         Redraw(StartingIndex,StartingIndex + ((Extent.y - 2) / LineHeight + 1));
  246.     }
  247.  
  248.  
  249. MyBoolean        CSongList::DoMenuCommand(ushort MenuCommandValue)
  250.     {
  251.         long                Temp;
  252.         long                StartTemp;
  253.  
  254.         switch (MenuCommandValue)
  255.             {
  256.                 case mFileClose:
  257.                     Document->GoAway();
  258.                     return True;
  259.                 case mFileSaveAs:
  260.                     Document->SaveFileAs();
  261.                     return True;
  262.                 case mFileSave:
  263.                     Document->SaveFile();
  264.                     return True;
  265.                 case mDeleteSelection:
  266.                     Document->RemoveSongFromList(Document->Selection);
  267.                     Temp = Document->Selection;
  268.                     Document->SetNewSelection(-1);
  269.                     return True;
  270.                 case mPlaySelection:
  271.                     Document->StartThisSong(Document->Selection);
  272.                     return True;
  273.                 case mStopPlaying:
  274.                     Document->CancelCurrentSong();
  275.                     return True;
  276.                 case mIncreaseVolume:
  277.                     Document->DoVolumeUp();
  278.                     return True;
  279.                 case mDecreaseVolume:
  280.                     Document->DoVolumeDown();
  281.                     return True;
  282.                 case mShowSelection:
  283.                     StartTemp = StartingIndex;
  284.                     while (Document->Selection < StartTemp)
  285.                         {
  286.                             StartTemp -= 1;
  287.                         }
  288.                     while (Document->Selection > StartTemp + ((Extent.y - 2) / LineHeight) - 1)
  289.                         {
  290.                             StartTemp += 1;
  291.                         }
  292.                     Hook(VScrollToLocation,StartTemp,0);
  293.                     return True;
  294.                 case mShowPlaying:
  295.                     StartTemp = StartingIndex;
  296.                     while (Document->Playing < StartTemp)
  297.                         {
  298.                             StartTemp -= 1;
  299.                         }
  300.                     while (Document->Playing > StartTemp + ((Extent.y - 2) / LineHeight) - 1)
  301.                         {
  302.                             StartTemp += 1;
  303.                         }
  304.                     Hook(VScrollToLocation,StartTemp,0);
  305.                     return True;
  306.                 default:
  307.                     return Application->DoMenuCommand(MenuCommandValue);
  308.             }
  309.     }
  310.  
  311.  
  312. void                CSongList::EnableMenuItems(void)
  313.     {
  314.         Application->EnableMenuItems();
  315.         MyEnableItem(mFileClose);
  316.         MyEnableItem(mFileSaveAs);
  317.         if (!Document->UpToDate)
  318.             {
  319.                 MyEnableItem(mFileSave);
  320.             }
  321.         if (Document->Playing != -1)
  322.             {
  323.                 MyEnableItem(mStopPlaying);
  324.                 MyEnableItem(mIncreaseVolume);
  325.                 MyEnableItem(mDecreaseVolume);
  326.             }
  327.         if (Document->Selection != -1)
  328.             {
  329.                 MyEnableItem(mDeleteSelection);
  330.                 MyEnableItem(mPlaySelection);
  331.             }
  332.         if (Document->Selection != -1)
  333.             {
  334.                 MyEnableItem(mShowSelection);
  335.             }
  336.         if (Document->Playing != -1)
  337.             {
  338.                 MyEnableItem(mShowPlaying);
  339.             }
  340.     }
  341.  
  342.  
  343. void                CSongList::Redraw(long Start, long End)
  344.     {
  345.         long                Scan;
  346.         LongPoint        TopLeft;
  347.         LongPoint        BottomRight;
  348.         Handle            String;
  349.         SongRec            Temp;
  350.  
  351.         SetUpPort();
  352.         Window->SetClipRect(LongPointOf(1,1),LongPointOf(Extent.x - 2,Extent.y - 2));
  353.         Window->SetText(systemFont,0,srcCopy,12,0);
  354.         for (Scan = Start; Scan <= End; Scan += 1)
  355.             {
  356.                 TopLeft.x = 1;
  357.                 TopLeft.y = (Scan - StartingIndex) * LineHeight + 1;
  358.                 BottomRight.x = Extent.x - 2;
  359.                 BottomRight.y = LineHeight;
  360.                 if (Scan != Document->Selection)
  361.                     {
  362.                         Window->LEraseRect(TopLeft,BottomRight);
  363.                         Window->SetTextMode(srcCopy);
  364.                         Window->SetPenMode(patCopy);
  365.                     }
  366.                  else
  367.                     {
  368.                         Window->LPaintRect(TopLeft,BottomRight);
  369.                         Window->SetTextMode(srcBic);
  370.                         Window->SetPenMode(patBic);
  371.                     }
  372.                 TopLeft.x += 5;
  373.                 BottomRight.x -= 5;
  374.                 if (Scan == Document->Playing)
  375.                     {
  376.                         Window->LPaintOval(LongPointOf(TopLeft.x,TopLeft.y + MarkerInset
  377.                             + InitialOffset),LongPointOf(LineHeight - MarkerInset * 2,
  378.                             LineHeight - MarkerInset * 2));
  379.                     }
  380.                 TopLeft.x += LineHeight - MarkerInset * 2 + 8;
  381.                 BottomRight.x -= LineHeight - MarkerInset * 2 + 8;
  382.                 if (Document->ListOfSongs->GetElement(Scan,&Temp))
  383.                     {
  384.                         String = PString2Handle(Temp.SongName);
  385.                         Window->LDrawText(TopLeft,BottomRight,String,JustifyLeft);
  386.                         ReleaseHandle(String);
  387.                     }
  388.             }
  389.     }
  390.  
  391.  
  392. void                CSongList::RecalculateScrollBars(void)
  393.     {
  394.         VScroll->SetPosition(StartingIndex,Document->ListOfSongs->GetNumElements()
  395.             - ((Extent.y - 2) / LineHeight) + 1);
  396.     }
  397.  
  398.  
  399. long                CSongList::Hook(short OperationID, long Operand1, long Operand2)
  400.     {
  401.         SetUpPort();
  402.         Window->SetClipRect(LongPointOf(1,1),LongPointOf(Extent.x - 2,Extent.y - 2));
  403.         switch (OperationID)
  404.             {
  405.                 case VScrollToLocation:
  406.                     {
  407.                         long                Delta;
  408.  
  409.                         if (Operand1 < 0)
  410.                             {
  411.                                 Operand1 = 0;
  412.                             }
  413.                         if ((Operand1 > Document->ListOfSongs->GetNumElements()
  414.                             - ((Extent.y - 2) / LineHeight)) && (Document->ListOfSongs->GetNumElements()
  415.                             - ((Extent.y - 2) / LineHeight) > 0))
  416.                             {
  417.                                 Operand1 = Document->ListOfSongs->GetNumElements()
  418.                                     - ((Extent.y - 2) / LineHeight);
  419.                             }
  420.                         Delta = Operand1 - StartingIndex; /* how many cells to move down by */
  421.                         Window->ScrollLong(LongPointOf(1,1),LongPointOf(Extent.x - 2,Extent.y - 2),
  422.                             LongPointOf(0,(-Delta) * LineHeight));
  423.                         StartingIndex += Delta;
  424.                         if (Delta < 0)
  425.                             {
  426.                                 /* shifted image down; opened at top */
  427.                                 Redraw(StartingIndex,StartingIndex - Delta);
  428.                             }
  429.                          else
  430.                             {
  431.                                 /* shifted up, opened at bottom */
  432.                                 Redraw(StartingIndex + ((Extent.y - 2) / LineHeight) - Delta,
  433.                                     StartingIndex + ((Extent.y - 2) / LineHeight) + 1);
  434.                             }
  435.                         VScroll->SetPosition(StartingIndex,Document->ListOfSongs->GetNumElements()
  436.                             - ((Extent.y - 2) / LineHeight) + 1);
  437.                     }
  438.                     return 0;
  439.                 case VScrollUpOne:
  440.                     if (StartingIndex - 1 >= 0)
  441.                         {
  442.                             return Hook(VScrollToLocation,StartingIndex - 1,0);
  443.                         }
  444.                     return 0;
  445.                 case VScrollUpPage:
  446.                     if (StartingIndex - ((Extent.y - 2) / LineHeight - 1) < 0)
  447.                         {
  448.                             return Hook(VScrollToLocation,0,0);
  449.                         }
  450.                      else
  451.                         {
  452.                             return Hook(VScrollToLocation,StartingIndex
  453.                                 - (Extent.y / LineHeight - 1),0);
  454.                         }
  455.                 case VScrollDownOne:
  456.                     if (StartingIndex + 1 <= Document->ListOfSongs->GetNumElements()
  457.                         - ((Extent.y - 2) / LineHeight))
  458.                         {
  459.                             return Hook(VScrollToLocation,StartingIndex + 1,0);
  460.                         }
  461.                     return 0;
  462.                 case VScrollDownPage:
  463.                     if (StartingIndex + ((Extent.y - 2) / LineHeight - 1)
  464.                         > Document->ListOfSongs->GetNumElements() - ((Extent.y - 2) / LineHeight))
  465.                         {
  466.                             return Hook(VScrollToLocation,Document->ListOfSongs->GetNumElements()
  467.                                 - ((Extent.y - 2) / LineHeight),0);
  468.                         }
  469.                      else
  470.                         {
  471.                             return Hook(VScrollToLocation,StartingIndex
  472.                                 + ((Extent.y - 2) / LineHeight - 1),0);
  473.                         }
  474.                 default:
  475.                     return inherited::Hook(OperationID,Operand1,Operand2);
  476.             }
  477.     }
  478.