home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1995 January / macformat-020.iso / Shareware City / Developers / OutOfPhase1.01Source / OutOfPhase Folder / AlgoWaveTableWindow.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-10-01  |  31.0 KB  |  1,022 lines  |  [TEXT/KAHL]

  1. /* AlgoWaveTableWindow.c */
  2. /*****************************************************************************/
  3. /*                                                                           */
  4. /*    Out Of Phase:  Digital Music Synthesis on General Purpose Computers    */
  5. /*    Copyright (C) 1994  Thomas R. Lawrence                                 */
  6. /*                                                                           */
  7. /*    This program is free software; you can redistribute it and/or modify   */
  8. /*    it under the terms of the GNU General Public License as published by   */
  9. /*    the Free Software Foundation; either version 2 of the License, or      */
  10. /*    (at your option) any later version.                                    */
  11. /*                                                                           */
  12. /*    This program is distributed in the hope that it will be useful,        */
  13. /*    but WITHOUT ANY WARRANTY; without even the implied warranty of         */
  14. /*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          */
  15. /*    GNU General Public License for more details.                           */
  16. /*                                                                           */
  17. /*    You should have received a copy of the GNU General Public License      */
  18. /*    along with this program; if not, write to the Free Software            */
  19. /*    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.              */
  20. /*                                                                           */
  21. /*    Thomas R. Lawrence can be reached at tomlaw@world.std.com.             */
  22. /*                                                                           */
  23. /*****************************************************************************/
  24.  
  25. #include "MiscInfo.h"
  26. #include "Audit.h"
  27. #include "Debug.h"
  28. #include "Definitions.h"
  29.  
  30. #include "AlgoWaveTableWindow.h"
  31. #include "MainWindowStuff.h"
  32. #include "AlgoWaveTableObject.h"
  33. #include "AlgoWaveTableList.h"
  34. #include "TextEdit.h"
  35. #include "IconButton.h"
  36. #include "WindowDispatcher.h"
  37. #include "Memory.h"
  38. #include "Alert.h"
  39. #include "Numbers.h"
  40. #include "GrowIcon.h"
  41. #include "DataMunging.h"
  42. #include "Main.h"
  43. #include "EditImages.h"
  44. #include "FindDialog.h"
  45. #include "WaveTableSizeDialog.h"
  46. #include "GlobalWindowMenuList.h"
  47.  
  48.  
  49. #define WINSIZEX (490)
  50. #define WINSIZEY (300)
  51. #define TITLEINDENT (8)
  52.  
  53. #define NAMEEDITX (80)
  54. #define NAMEEDITY (1)
  55. #define NAMEEDITWIDTH (80)
  56. #define NAMEEDITHEIGHT (19)
  57.  
  58. #define NUMFRAMESEDITX (240)
  59. #define NUMFRAMESEDITY (1)
  60. #define NUMFRAMESEDITWIDTH (80)
  61. #define NUMFRAMESEDITHEIGHT (19)
  62.  
  63. #define NUMTABLESEDITX (400)
  64. #define NUMTABLESEDITY (1)
  65. #define NUMTABLESEDITWIDTH (80)
  66. #define NUMTABLESEDITHEIGHT (19)
  67.  
  68. #define BITS8X (10)
  69. #define BITS8Y (NUMFRAMESEDITY + NUMFRAMESEDITHEIGHT + 4)
  70. #define BITS8WIDTH (32)
  71. #define BITS8HEIGHT (32)
  72.  
  73. #define BITS16X (BITS8X + BITS8WIDTH + 1)
  74. #define BITS16Y (BITS8Y)
  75. #define BITS16WIDTH (BITS8WIDTH)
  76. #define BITS16HEIGHT (BITS8HEIGHT)
  77.  
  78. #define NAMEX (3)
  79. #define NAMEY (4)
  80.  
  81. #define NUMFRAMESX (170)
  82. #define NUMFRAMESY (4)
  83.  
  84. #define NUMTABLESX (330)
  85. #define NUMTABLESY (4)
  86.  
  87. #define FUNCTIONEDITX (-1)
  88. #define FUNCTIONEDITY (BITS16Y + BITS16HEIGHT + 4)
  89. #define FUNCTIONEDITWIDTH(Width) ((Width) + 2)
  90. #define FUNCTIONEDITHEIGHT(Height) ((Height) - FUNCTIONEDITY + 1)
  91.  
  92.  
  93. struct AlgoWaveTableWindowRec
  94.     {
  95.         MainWindowRec*                    MainWindow;
  96.         AlgoWaveTableObjectRec*    AlgoWaveTableObject;
  97.         AlgoWaveTableListRec*        AlgoWaveTableList;
  98.  
  99.         WinType*                                ScreenID;
  100.         TextEditRec*                        NameEdit;
  101.         TextEditRec*                        FunctionEdit;
  102.         TextEditRec*                        NumFramesEdit;
  103.         TextEditRec*                        NumTablesEdit;
  104.         TextEditRec*                        ActiveTextEdit;
  105.         IconButtonRec*                    Bits8Button;
  106.         IconButtonRec*                    Bits16Button;
  107.         MyBoolean                                BitsChanged;
  108.         GenericWindowRec*                MyGenericWindow; /* how the window event dispatcher knows us */
  109.         MenuItemType*                        MyMenuItem;
  110.     };
  111.  
  112.  
  113. /* create a new algorithmic wave table editing window */
  114. AlgoWaveTableWindowRec*    NewAlgoWaveTableWindow(struct MainWindowRec* MainWindow,
  115.                                             struct AlgoWaveTableObjectRec* AlgoWaveTableObject,
  116.                                             struct AlgoWaveTableListRec* AlgoWaveTableList,
  117.                                             OrdType WinX, OrdType WinY, OrdType WinWidth, OrdType WinHeight)
  118.     {
  119.         AlgoWaveTableWindowRec*    Window;
  120.         char*                                        StringTemp;
  121.  
  122.         /* deal with window placement */
  123.         if ((WinWidth < 100) || (WinHeight < 100) || ((eOptionKey & CheckModifiers()) != 0))
  124.             {
  125.                 WinX = 20 + WindowOtherEdgeWidths(eDocumentWindow);
  126.                 WinY = 20 + WindowTitleBarHeight(eDocumentWindow);
  127.                 WinWidth = WINSIZEX;
  128.                 WinHeight = WINSIZEY;
  129.             }
  130.         MakeWindowFitOnScreen(&WinX,&WinY,&WinWidth,&WinHeight);
  131.  
  132.         Window = (AlgoWaveTableWindowRec*)AllocPtrCanFail(
  133.             sizeof(AlgoWaveTableWindowRec),"AlgoWaveTableWindowRec");
  134.         if (Window == NIL)
  135.             {
  136.              FailurePoint1:
  137.                 AlertHalt("There is not enough memory available to display the algorithmic "
  138.                     "wave table editor.",NIL);
  139.                 return NIL;
  140.             }
  141.         Window->MainWindow = MainWindow;
  142.         Window->AlgoWaveTableObject = AlgoWaveTableObject;
  143.         Window->AlgoWaveTableList = AlgoWaveTableList;
  144.         Window->BitsChanged = False;
  145.  
  146.         Window->ScreenID = MakeNewWindow(eDocumentWindow,eWindowClosable,
  147.             eWindowZoomable,eWindowResizable,WinX,WinY,WinWidth,WinHeight,
  148.             (void (*)(void*))&AlgoWaveTableWindowUpdator,Window);
  149.         if (Window->ScreenID == 0)
  150.             {
  151.              FailurePoint2:
  152.                 ReleasePtr((char*)Window);
  153.                 goto FailurePoint1;
  154.             }
  155.  
  156.         /* create name edit */
  157.         Window->NameEdit = NewTextEdit(Window->ScreenID,eTENoScrollBars,
  158.             GetScreenFont(),9,NAMEEDITX,NAMEEDITY,NAMEEDITWIDTH,NAMEEDITHEIGHT);
  159.         if (Window->NameEdit == NIL)
  160.             {
  161.              FailurePoint3:
  162.                 KillWindow(Window->ScreenID);
  163.                 goto FailurePoint2;
  164.             }
  165.         /* install new text in name edit */
  166.         StringTemp = AlgoWaveTableObjectGetNameCopy(AlgoWaveTableObject);
  167.         if (StringTemp == NIL)
  168.             {
  169.              FailurePoint4:
  170.                 DisposeTextEdit(Window->NameEdit);
  171.                 goto FailurePoint3;
  172.             }
  173.         TextEditNewRawData(Window->NameEdit,StringTemp,"\x0a");
  174.         ReleasePtr(StringTemp);
  175.         TextEditHasBeenSaved(Window->NameEdit);
  176.  
  177.         /* create function edit */
  178.         Window->FunctionEdit = NewTextEdit(Window->ScreenID,eTEVScrollBar | eTEHScrollBar,
  179.             GetMonospacedFont(),9,FUNCTIONEDITX,FUNCTIONEDITY
  180.             + GetFontHeight(GetScreenFont(),9),FUNCTIONEDITWIDTH(WinWidth),
  181.             FUNCTIONEDITHEIGHT(WinHeight) - GetFontHeight(GetScreenFont(),9));
  182.         if (Window->FunctionEdit == NIL)
  183.             {
  184.              FailurePoint5:
  185.                 goto FailurePoint4;
  186.             }
  187.         SetTextEditTabSize(Window->FunctionEdit,MainWindowGetTabSize(MainWindow));
  188.         StringTemp = AlgoWaveTableObjectGetFormulaCopy(AlgoWaveTableObject);
  189.         if (StringTemp == NIL)
  190.             {
  191.              FailurePoint6:
  192.                 DisposeTextEdit(Window->FunctionEdit);
  193.                 goto FailurePoint5;
  194.             }
  195.         TextEditNewRawData(Window->FunctionEdit,StringTemp,"\x0a");
  196.         ReleasePtr(StringTemp);
  197.         TextEditHasBeenSaved(Window->FunctionEdit);
  198.         SetTextEditAutoIndent(Window->FunctionEdit,True);
  199.  
  200.         Window->NumFramesEdit = NewTextEdit(Window->ScreenID,eTENoScrollBars,
  201.             GetScreenFont(),9,NUMFRAMESEDITX,NUMFRAMESEDITY,NUMFRAMESEDITWIDTH,NUMFRAMESEDITHEIGHT);
  202.         if (Window->NumFramesEdit == NIL)
  203.             {
  204.              FailurePoint7:
  205.                 goto FailurePoint6;
  206.             }
  207.         StringTemp = IntegerToString(AlgoWaveTableObjectGetNumFrames(AlgoWaveTableObject));
  208.         if (StringTemp == NIL)
  209.             {
  210.              FailurePoint8:
  211.                 DisposeTextEdit(Window->NumFramesEdit);
  212.                 goto FailurePoint7;
  213.             }
  214.         TextEditNewRawData(Window->NumFramesEdit,StringTemp,"\x0a");
  215.         ReleasePtr(StringTemp);
  216.         TextEditHasBeenSaved(Window->NumFramesEdit);
  217.  
  218.         Window->NumTablesEdit = NewTextEdit(Window->ScreenID,eTENoScrollBars,
  219.             GetScreenFont(),9,NUMTABLESEDITX,NUMTABLESEDITY,NUMTABLESEDITWIDTH,NUMTABLESEDITHEIGHT);
  220.         if (Window->NumTablesEdit == NIL)
  221.             {
  222.              FailurePoint9:
  223.                 goto FailurePoint8;
  224.             }
  225.         StringTemp = IntegerToString(AlgoWaveTableObjectGetNumTables(AlgoWaveTableObject));
  226.         if (StringTemp == NIL)
  227.             {
  228.              FailurePoint10:
  229.                 DisposeTextEdit(Window->NumTablesEdit);
  230.                 goto FailurePoint9;
  231.             }
  232.         TextEditNewRawData(Window->NumTablesEdit,StringTemp,"\x0a");
  233.         ReleasePtr(StringTemp);
  234.         TextEditHasBeenSaved(Window->NumTablesEdit);
  235.  
  236.         Window->Bits8Button = NewIconButtonPreparedBitmaps(Window->ScreenID,BITS8X,BITS8Y,
  237.             BITS8WIDTH,BITS8HEIGHT,Bits8Unselected,Bits8MouseDown,Bits8Selected,Bits8Selected,
  238.             eIconRadioMode);
  239.         if (Window->Bits8Button == NIL)
  240.             {
  241.              FailurePoint11:
  242.                 goto FailurePoint10;
  243.             }
  244.         Window->Bits16Button = NewIconButtonPreparedBitmaps(Window->ScreenID,BITS16X,BITS16Y,
  245.             BITS16WIDTH,BITS16HEIGHT,Bits16Unselected,Bits16MouseDown,Bits16Selected,
  246.             Bits16Selected,eIconRadioMode);
  247.         if (Window->Bits16Button == NIL)
  248.             {
  249.              FailurePoint12:
  250.                 DisposeIconButton(Window->Bits8Button);
  251.                 goto FailurePoint11;
  252.             }
  253.         switch (AlgoWaveTableObjectGetNumBits(AlgoWaveTableObject))
  254.             {
  255.                 case eSample16bit:
  256.                     SetIconButtonState(Window->Bits16Button,True);
  257.                     break;
  258.                 case eSample8bit:
  259.                     SetIconButtonState(Window->Bits8Button,True);
  260.                     break;
  261.                 default:
  262.                     EXECUTE(PRERR(ForceAbort,"NewAlgoWaveTableWindow:  bad num bits"));
  263.                     break;
  264.             }
  265.  
  266.         Window->MyGenericWindow = CheckInNewWindow(Window->ScreenID,Window,
  267.             (void (*)(void*,MyBoolean,OrdType,OrdType,ModifierFlags))&AlgoWaveTableWindowDoIdle,
  268.             (void (*)(void*))&AlgoWaveTableWindowBecomeActive,
  269.             (void (*)(void*))&AlgoWaveTableWindowBecomeInactive,
  270.             (void (*)(void*))&AlgoWaveTableWindowJustResized,
  271.             (void (*)(OrdType,OrdType,ModifierFlags,void*))&AlgoWaveTableWindowDoMouseDown,
  272.             (void (*)(unsigned char,ModifierFlags,void*))&AlgoWaveTableWindowDoKeyDown,
  273.             (void (*)(void*))&AlgoWaveTableWindowClose,
  274.             (void (*)(void*))&AlgoWaveTableWindowMenuSetup,
  275.             (void (*)(void*,MenuItemType*))&AlgoWaveTableWindowDoMenuCommand);
  276.         if (Window->MyGenericWindow == NIL)
  277.             {
  278.              FailurePoint13:
  279.                 DisposeIconButton(Window->Bits16Button);
  280.                 goto FailurePoint12;
  281.             }
  282.  
  283.         Window->MyMenuItem = MakeNewMenuItem(mmWindowMenu,"x",0);
  284.         if (Window->MyMenuItem == NIL)
  285.             {
  286.              FailurePoint14:
  287.                 CheckOutDyingWindow(Window->MyGenericWindow);
  288.                 goto FailurePoint13;
  289.             }
  290.         if (!RegisterWindowMenuItem(Window->MyMenuItem,(void (*)(void*))&ActivateThisWindow,
  291.             Window->ScreenID))
  292.             {
  293.              FailurePoint15:
  294.                 KillMenuItem(Window->MyMenuItem);
  295.                 goto FailurePoint14;
  296.             }
  297.  
  298.         Window->ActiveTextEdit = Window->FunctionEdit;
  299.         AlgoWaveTableWindowResetTitlebar(Window);
  300.  
  301.         return Window;
  302.     }
  303.  
  304.  
  305. /* write data back to the object and dispose of the window */
  306. void                                DisposeAlgoWaveTableWindow(AlgoWaveTableWindowRec* Window)
  307.     {
  308.         CheckPtrExistence(Window);
  309.  
  310.         /* save the data */
  311.         if (!AlgoWaveTableWindowWritebackModifiedData(Window))
  312.             {
  313.                 /* failed -- now what? */
  314.             }
  315.  
  316.         AlgoWaveTableObjectClosingWindowNotify(Window->AlgoWaveTableObject,
  317.             GetWindowXStart(Window->ScreenID),GetWindowYStart(Window->ScreenID),
  318.             GetWindowWidth(Window->ScreenID),GetWindowHeight(Window->ScreenID));
  319.         DeregisterWindowMenuItem(Window->MyMenuItem);
  320.         KillMenuItem(Window->MyMenuItem);
  321.         CheckOutDyingWindow(Window->MyGenericWindow);
  322.         DisposeTextEdit(Window->NameEdit);
  323.         DisposeTextEdit(Window->FunctionEdit);
  324.         DisposeTextEdit(Window->NumFramesEdit);
  325.         DisposeTextEdit(Window->NumTablesEdit);
  326.         DisposeIconButton(Window->Bits16Button);
  327.         DisposeIconButton(Window->Bits8Button);
  328.         KillWindow(Window->ScreenID);
  329.         ReleasePtr((char*)Window);
  330.     }
  331.  
  332.  
  333. /* find out if the wave table has been modified since the last file save */
  334. MyBoolean                        HasAlgoWaveTableWindowBeenModified(AlgoWaveTableWindowRec* Window)
  335.     {
  336.         CheckPtrExistence(Window);
  337.         return Window->BitsChanged
  338.             || TextEditDoesItNeedToBeSaved(Window->NameEdit)
  339.             || TextEditDoesItNeedToBeSaved(Window->FunctionEdit)
  340.             || TextEditDoesItNeedToBeSaved(Window->NumFramesEdit)
  341.             || TextEditDoesItNeedToBeSaved(Window->NumTablesEdit);
  342.     }
  343.  
  344.  
  345. /* highlight a line in the formula edit box */
  346. void                                AlgoWaveTableWindowHiliteLine(AlgoWaveTableWindowRec* Window,
  347.                                             long LineNumber)
  348.     {
  349.         CheckPtrExistence(Window);
  350.         if (Window->ActiveTextEdit != Window->FunctionEdit)
  351.             {
  352.                 DisableTextEditSelection(Window->ActiveTextEdit);
  353.                 Window->ActiveTextEdit = Window->FunctionEdit;
  354.                 EnableTextEditSelection(Window->ActiveTextEdit);
  355.             }
  356.         SetTextEditSelection(Window->FunctionEdit,LineNumber,0,LineNumber + 1,0);
  357.         TextEditShowSelection(Window->FunctionEdit);
  358.     }
  359.  
  360.  
  361. /* bring the window to the top and give it the focus */
  362. void                                AlgoWaveTableWindowBringToTop(AlgoWaveTableWindowRec* Window)
  363.     {
  364.         CheckPtrExistence(Window);
  365.         ActivateThisWindow(Window->ScreenID);
  366.     }
  367.  
  368.  
  369. void                                AlgoWaveTableWindowDoIdle(AlgoWaveTableWindowRec* Window,
  370.                                             MyBoolean CheckCursorFlag, OrdType XLoc, OrdType YLoc,
  371.                                             ModifierFlags Modifiers)
  372.     {
  373.         CheckPtrExistence(Window);
  374.         TextEditUpdateCursor(Window->ActiveTextEdit);
  375.         if (CheckCursorFlag)
  376.             {
  377.                 if (TextEditIBeamTest(Window->NameEdit,XLoc,YLoc)
  378.                     || TextEditIBeamTest(Window->FunctionEdit,XLoc,YLoc)
  379.                     || TextEditIBeamTest(Window->NumFramesEdit,XLoc,YLoc)
  380.                     || TextEditIBeamTest(Window->NumTablesEdit,XLoc,YLoc))
  381.                     {
  382.                         SetIBeamCursor();
  383.                     }
  384.                  else
  385.                     {
  386.                         SetArrowCursor();
  387.                     }
  388.             }
  389.     }
  390.  
  391.  
  392. void                                AlgoWaveTableWindowBecomeActive(AlgoWaveTableWindowRec* Window)
  393.     {
  394.         OrdType                        XSize;
  395.         OrdType                        YSize;
  396.  
  397.         CheckPtrExistence(Window);
  398.         EnableTextEditSelection(Window->ActiveTextEdit);
  399.         XSize = GetWindowWidth(Window->ScreenID);
  400.         YSize = GetWindowHeight(Window->ScreenID);
  401.         SetClipRect(Window->ScreenID,XSize - 15,YSize - 15,XSize,YSize);
  402.         DrawBitmap(Window->ScreenID,XSize-15,YSize-15,GetGrowIcon(True/*enablegrowicon*/));
  403.     }
  404.  
  405.  
  406. void                                AlgoWaveTableWindowBecomeInactive(AlgoWaveTableWindowRec* Window)
  407.     {
  408.         OrdType                        XSize;
  409.         OrdType                        YSize;
  410.  
  411.         CheckPtrExistence(Window);
  412.         DisableTextEditSelection(Window->ActiveTextEdit);
  413.         XSize = GetWindowWidth(Window->ScreenID);
  414.         YSize = GetWindowHeight(Window->ScreenID);
  415.         SetClipRect(Window->ScreenID,XSize - 15,YSize - 15,XSize,YSize);
  416.         DrawBitmap(Window->ScreenID,XSize-15,YSize-15,GetGrowIcon(False/*disablegrowicon*/));
  417.     }
  418.  
  419.  
  420. void                                AlgoWaveTableWindowJustResized(AlgoWaveTableWindowRec* Window)
  421.     {
  422.         OrdType                        XSize;
  423.         OrdType                        YSize;
  424.         OrdType                        FontHeight;
  425.  
  426.         CheckPtrExistence(Window);
  427.         XSize = GetWindowWidth(Window->ScreenID);
  428.         YSize = GetWindowHeight(Window->ScreenID);
  429.         SetClipRect(Window->ScreenID,0,0,XSize,YSize);
  430.         DrawBoxErase(Window->ScreenID,0,0,XSize,YSize);
  431.         FontHeight = GetFontHeight(GetScreenFont(),9);
  432.         SetTextEditPosition(Window->FunctionEdit,FUNCTIONEDITX,FUNCTIONEDITY + FontHeight,
  433.             FUNCTIONEDITWIDTH(XSize),FUNCTIONEDITHEIGHT(YSize) - FontHeight);
  434.     }
  435.  
  436.  
  437. void                                AlgoWaveTableWindowDoMouseDown(OrdType XLoc, OrdType YLoc,
  438.                                             ModifierFlags Modifiers, AlgoWaveTableWindowRec* Window)
  439.     {
  440.         CheckPtrExistence(Window);
  441.         if ((XLoc >= GetWindowWidth(Window->ScreenID) - 15)
  442.             && (XLoc < GetWindowWidth(Window->ScreenID))
  443.             && (YLoc >= GetWindowHeight(Window->ScreenID) - 15)
  444.             && (YLoc < GetWindowHeight(Window->ScreenID)))
  445.             {
  446.                 UserGrowWindow(Window->ScreenID,XLoc,YLoc);
  447.                 AlgoWaveTableWindowJustResized(Window);
  448.             }
  449.         else if (TextEditHitTest(Window->NameEdit,XLoc,YLoc))
  450.             {
  451.                 if (Window->ActiveTextEdit != Window->NameEdit)
  452.                     {
  453.                         DisableTextEditSelection(Window->ActiveTextEdit);
  454.                         Window->ActiveTextEdit = Window->NameEdit;
  455.                         EnableTextEditSelection(Window->ActiveTextEdit);
  456.                     }
  457.                 TextEditDoMouseDown(Window->NameEdit,XLoc,YLoc,Modifiers);
  458.             }
  459.         else if (TextEditHitTest(Window->FunctionEdit,XLoc,YLoc))
  460.             {
  461.                 if (Window->ActiveTextEdit != Window->FunctionEdit)
  462.                     {
  463.                         DisableTextEditSelection(Window->ActiveTextEdit);
  464.                         Window->ActiveTextEdit = Window->FunctionEdit;
  465.                         EnableTextEditSelection(Window->ActiveTextEdit);
  466.                     }
  467.                 TextEditDoMouseDown(Window->FunctionEdit,XLoc,YLoc,Modifiers);
  468.             }
  469.         else if (TextEditHitTest(Window->NumFramesEdit,XLoc,YLoc))
  470.             {
  471.                 long                            OldNumFrames;
  472.                 long                            NewNumFrames;
  473.                 char*                            NewStringTemp;
  474.  
  475.                 OldNumFrames = AlgoWaveTableWindowGetNumFrames(Window);
  476.                 NewNumFrames = AskForNewWaveTableSize(OldNumFrames);
  477.                 NewStringTemp = IntegerToString(NewNumFrames);
  478.                 if (NewStringTemp != NIL)
  479.                     {
  480.                         TextEditNewRawData(Window->NumFramesEdit,NewStringTemp,"\x0a");
  481.                         ReleasePtr(NewStringTemp);
  482.                     }
  483.             }
  484.         else if (TextEditHitTest(Window->NumTablesEdit,XLoc,YLoc))
  485.             {
  486.                 if (Window->ActiveTextEdit != Window->NumTablesEdit)
  487.                     {
  488.                         DisableTextEditSelection(Window->ActiveTextEdit);
  489.                         Window->ActiveTextEdit = Window->NumTablesEdit;
  490.                         EnableTextEditSelection(Window->ActiveTextEdit);
  491.                     }
  492.                 TextEditDoMouseDown(Window->NumTablesEdit,XLoc,YLoc,Modifiers);
  493.             }
  494.         else if (IconButtonHitTest(Window->Bits8Button,XLoc,YLoc))
  495.             {
  496.                 if (IconButtonMouseDown(Window->Bits8Button,XLoc,YLoc,NIL,NIL))
  497.                     {
  498.                         Window->BitsChanged = True;
  499.                         SetIconButtonState(Window->Bits16Button,False);
  500.                     }
  501.             }
  502.         else if (IconButtonHitTest(Window->Bits16Button,XLoc,YLoc))
  503.             {
  504.                 if (IconButtonMouseDown(Window->Bits16Button,XLoc,YLoc,NIL,NIL))
  505.                     {
  506.                         Window->BitsChanged = True;
  507.                         SetIconButtonState(Window->Bits8Button,False);
  508.                     }
  509.             }
  510.     }
  511.  
  512.  
  513. void                                AlgoWaveTableWindowDoKeyDown(unsigned char KeyCode,
  514.                                             ModifierFlags Modifiers,AlgoWaveTableWindowRec* Window)
  515.     {
  516.         CheckPtrExistence(Window);
  517.         TextEditDoKeyPressed(Window->ActiveTextEdit,KeyCode,Modifiers);
  518.     }
  519.  
  520.  
  521. void                                AlgoWaveTableWindowClose(AlgoWaveTableWindowRec* Window)
  522.     {
  523.         CheckPtrExistence(Window);
  524.         DisposeAlgoWaveTableWindow(Window);
  525.     }
  526.  
  527.  
  528. void                                AlgoWaveTableWindowUpdator(AlgoWaveTableWindowRec* Window)
  529.     {
  530.         OrdType                        XSize;
  531.         OrdType                        YSize;
  532.         FontType                    ScreenFont;
  533.  
  534.         CheckPtrExistence(Window);
  535.         ScreenFont = GetScreenFont();
  536.         TextEditFullRedraw(Window->NameEdit);
  537.         TextEditFullRedraw(Window->FunctionEdit);
  538.         TextEditFullRedraw(Window->NumFramesEdit);
  539.         TextEditFullRedraw(Window->NumTablesEdit);
  540.         RedrawIconButton(Window->Bits16Button);
  541.         RedrawIconButton(Window->Bits8Button);
  542.         XSize = GetWindowWidth(Window->ScreenID);
  543.         YSize = GetWindowHeight(Window->ScreenID);
  544.         SetClipRect(Window->ScreenID,0,0,XSize,YSize);
  545.         DrawTextLine(Window->ScreenID,ScreenFont,9,"Name:",5,NAMEX,NAMEY,ePlain);
  546.         DrawTextLine(Window->ScreenID,ScreenFont,9,"Num Tables:",11,
  547.             NUMTABLESX,NUMTABLESY,ePlain);
  548.         DrawTextLine(Window->ScreenID,ScreenFont,9,"Num Frames:",11,
  549.             NUMFRAMESX,NUMFRAMESY,ePlain);
  550.         DrawTextLine(Window->ScreenID,ScreenFont,9,"Waveform Generating Function:",29,
  551.             FUNCTIONEDITX + TITLEINDENT,FUNCTIONEDITY,eBold);
  552.         SetClipRect(Window->ScreenID,XSize - 15,YSize - 15,XSize,YSize);
  553.         DrawBitmap(Window->ScreenID,XSize-15,YSize-15,
  554.             GetGrowIcon(Window->MyGenericWindow == GetCurrentWindowID()));
  555.     }
  556.  
  557.  
  558. void                                AlgoWaveTableWindowMenuSetup(AlgoWaveTableWindowRec* Window)
  559.     {
  560.         CheckPtrExistence(Window);
  561.         MainWindowEnableGlobalMenus(Window->MainWindow);
  562.         EnableMenuItem(mPaste);
  563.         ChangeItemName(mPaste,"Paste Text");
  564.         if (TextEditIsThereValidSelection(Window->ActiveTextEdit))
  565.             {
  566.                 EnableMenuItem(mCut);
  567.                 ChangeItemName(mCut,"Cut Text");
  568.                 EnableMenuItem(mCopy);
  569.                 ChangeItemName(mCopy,"Copy Text");
  570.                 EnableMenuItem(mClear);
  571.                 ChangeItemName(mClear,"Clear Text");
  572.             }
  573.         EnableMenuItem(mShiftLeft);
  574.         EnableMenuItem(mShiftRight);
  575.         EnableMenuItem(mBalanceParens);
  576.         EnableMenuItem(mSelectAll);
  577.         ChangeItemName(mSelectAll,"Select All Text");
  578.         if (TextEditCanWeUndo(Window->ActiveTextEdit))
  579.             {
  580.                 EnableMenuItem(mUndo);
  581.                 ChangeItemName(mUndo,"Undo Text Change");
  582.             }
  583.         ChangeItemName(mCloseFile,"Close Algorithmic Wave Table Editor");
  584.         EnableMenuItem(mCloseFile);
  585.         ChangeItemName(mBuildFunction,"Build Wave Table");
  586.         EnableMenuItem(mBuildFunction);
  587.         ChangeItemName(mUnbuildFunction,"Unbuild Wave Table");
  588.         EnableMenuItem(mUnbuildFunction);
  589.         ChangeItemName(mAlgoSampToSample,"Open Algorithmic Wave Table As New Wave Table");
  590.         EnableMenuItem(mAlgoSampToSample);
  591.         ChangeItemName(mDeleteObject,"Delete Algorithmic Wave Table");
  592.         EnableMenuItem(mDeleteObject);
  593.         EnableMenuItem(mFind);
  594.         if (PtrSize(GlobalSearchString) != 0)
  595.             {
  596.                 EnableMenuItem(mFindAgain);
  597.                 if ((Window->ActiveTextEdit != NIL)
  598.                     && TextEditIsThereValidSelection(Window->ActiveTextEdit))
  599.                     {
  600.                         EnableMenuItem(mReplace);
  601.                         EnableMenuItem(mReplaceAndFindAgain);
  602.                     }
  603.             }
  604.         EnableMenuItem(mShowSelection);
  605.         if ((Window->ActiveTextEdit != NIL)
  606.             && TextEditIsThereValidSelection(Window->ActiveTextEdit))
  607.             {
  608.                 EnableMenuItem(mEnterSelection);
  609.             }
  610.         SetItemCheckmark(Window->MyMenuItem);
  611.     }
  612.  
  613.  
  614. void                                AlgoWaveTableWindowDoMenuCommand(AlgoWaveTableWindowRec* Window,
  615.                                             MenuItemType* MenuItem)
  616.     {
  617.         CheckPtrExistence(Window);
  618.         if (MainWindowDoGlobalMenuItem(Window->MainWindow,MenuItem))
  619.             {
  620.             }
  621.         else if (MenuItem == mPaste)
  622.             {
  623.                 TextEditDoMenuPaste(Window->ActiveTextEdit);
  624.             }
  625.         else if (MenuItem == mCut)
  626.             {
  627.                 TextEditDoMenuCut(Window->ActiveTextEdit);
  628.             }
  629.         else if (MenuItem == mCopy)
  630.             {
  631.                 TextEditDoMenuCopy(Window->ActiveTextEdit);
  632.             }
  633.         else if (MenuItem == mClear)
  634.             {
  635.                 TextEditDoMenuClear(Window->ActiveTextEdit);
  636.             }
  637.         else if (MenuItem == mSelectAll)
  638.             {
  639.                 TextEditDoMenuSelectAll(Window->ActiveTextEdit);
  640.             }
  641.         else if (MenuItem == mUndo)
  642.             {
  643.                 TextEditDoMenuUndo(Window->ActiveTextEdit);
  644.             }
  645.         else if (MenuItem == mCloseFile)
  646.             {
  647.                 AlgoWaveTableWindowClose(Window);
  648.             }
  649.         else if (MenuItem == mShiftLeft)
  650.             {
  651.                 TextEditShiftSelectionLeftOneTab(Window->ActiveTextEdit);
  652.             }
  653.         else if (MenuItem == mShiftRight)
  654.             {
  655.                 TextEditShiftSelectionRightOneTab(Window->ActiveTextEdit);
  656.             }
  657.         else if (MenuItem == mBalanceParens)
  658.             {
  659.                 TextEditBalanceParens(Window->ActiveTextEdit);
  660.             }
  661.         else if (MenuItem == mBuildFunction)
  662.             {
  663.                 AlgoWaveTableObjectBuild(Window->AlgoWaveTableObject);
  664.             }
  665.         else if (MenuItem == mUnbuildFunction)
  666.             {
  667.                 AlgoWaveTableObjectUnbuild(Window->AlgoWaveTableObject);
  668.             }
  669.         else if (MenuItem == mAlgoSampToSample)
  670.             {
  671.                 if (AlgoWaveTableObjectMakeUpToDate(Window->AlgoWaveTableObject))
  672.                     {
  673.                         char*                    Buffer;
  674.                         long                    NumTables;
  675.                         long                    SliceSize;
  676.                         long                    BytesPerSlice;
  677.  
  678.                         NumTables = AlgoWaveTableObjectGetNumTables(Window->AlgoWaveTableObject);
  679.                         SliceSize = AlgoWaveTableObjectGetNumFrames(Window->AlgoWaveTableObject);
  680.                         BytesPerSlice = SliceSize;
  681.                         if (eSample16bit == AlgoWaveTableObjectGetNumBits(Window->AlgoWaveTableObject))
  682.                             {
  683.                                 BytesPerSlice *= 2;
  684.                             }
  685.                         Buffer = AllocPtrCanFail(BytesPerSlice * NumTables,"AlgoWaveTableTemp");
  686.                         if (Buffer == NIL)
  687.                             {
  688.                                 AlertHalt("There is not enough memory to convert the wave table.",NIL);
  689.                             }
  690.                          else
  691.                             {
  692.                                 long                    Scan;
  693.  
  694.                                 for (Scan = 0; Scan < NumTables; Scan += 1)
  695.                                     {
  696.                                         char*                    OneSlice;
  697.  
  698.                                         OneSlice = AlgoWaveTableObjectGetRawSlice(
  699.                                             Window->AlgoWaveTableObject,Scan);
  700.                                         PRNGCHK(Buffer,&(Buffer[Scan * BytesPerSlice]),BytesPerSlice);
  701.                                         CopyData(OneSlice,&(Buffer[Scan * BytesPerSlice]),BytesPerSlice);
  702.                                     }
  703.                                 MainWindowCopyRawWaveTableAndOpen(Window->MainWindow,Buffer,
  704.                                     AlgoWaveTableObjectGetNumBits(Window->AlgoWaveTableObject),
  705.                                     NumTables,SliceSize);
  706.                                 ReleasePtr(Buffer);
  707.                             }
  708.                     }
  709.             }
  710.         else if (MenuItem == mDeleteObject)
  711.             {
  712.                 AlgoWaveTableListDeleteAlgoWaveTable(Window->AlgoWaveTableList,
  713.                     Window->AlgoWaveTableObject);
  714.             }
  715.         else if (MenuItem == mFind)
  716.             {
  717.                 if (Window->ActiveTextEdit != Window->FunctionEdit)
  718.                     {
  719.                         DisableTextEditSelection(Window->ActiveTextEdit);
  720.                         Window->ActiveTextEdit = Window->FunctionEdit;
  721.                         EnableTextEditSelection(Window->ActiveTextEdit);
  722.                     }
  723.                 switch (DoFindDialog(&GlobalSearchString,&GlobalReplaceString,
  724.                     mCut,mPaste,mCopy,mUndo,mSelectAll,mClear))
  725.                     {
  726.                         default:
  727.                             EXECUTE(PRERR(ForceAbort,
  728.                                 "AlgoWaveTableWindowDoMenuCommand:  bad value from DoFindDialog"));
  729.                             break;
  730.                         case eFindCancel:
  731.                         case eDontFind:
  732.                             break;
  733.                         case eFindFromStart:
  734.                             SetTextEditInsertionPoint(Window->ActiveTextEdit,0,0);
  735.                             TextEditFindAgain(Window->ActiveTextEdit,GlobalSearchString);
  736.                             TextEditShowSelection(Window->ActiveTextEdit);
  737.                             break;
  738.                         case eFindAgain:
  739.                             TextEditFindAgain(Window->ActiveTextEdit,GlobalSearchString);
  740.                             TextEditShowSelection(Window->ActiveTextEdit);
  741.                             break;
  742.                     }
  743.             }
  744.         else if (MenuItem == mFindAgain)
  745.             {
  746.                 if (Window->ActiveTextEdit != Window->FunctionEdit)
  747.                     {
  748.                         DisableTextEditSelection(Window->ActiveTextEdit);
  749.                         Window->ActiveTextEdit = Window->FunctionEdit;
  750.                         EnableTextEditSelection(Window->ActiveTextEdit);
  751.                     }
  752.                 TextEditFindAgain(Window->ActiveTextEdit,GlobalSearchString);
  753.                 TextEditShowSelection(Window->ActiveTextEdit);
  754.             }
  755.         else if (MenuItem == mReplace)
  756.             {
  757.                 if (Window->ActiveTextEdit != Window->FunctionEdit)
  758.                     {
  759.                         DisableTextEditSelection(Window->ActiveTextEdit);
  760.                         Window->ActiveTextEdit = Window->FunctionEdit;
  761.                         EnableTextEditSelection(Window->ActiveTextEdit);
  762.                     }
  763.                 if (TextEditIsThereValidSelection(Window->ActiveTextEdit))
  764.                     {
  765.                         TextEditInsertRawData(Window->ActiveTextEdit,GlobalReplaceString,
  766.                             SYSTEMLINEFEED);
  767.                     }
  768.             }
  769.         else if (MenuItem == mReplaceAndFindAgain)
  770.             {
  771.                 if (Window->ActiveTextEdit != Window->FunctionEdit)
  772.                     {
  773.                         DisableTextEditSelection(Window->ActiveTextEdit);
  774.                         Window->ActiveTextEdit = Window->FunctionEdit;
  775.                         EnableTextEditSelection(Window->ActiveTextEdit);
  776.                     }
  777.                 if (TextEditIsThereValidSelection(Window->ActiveTextEdit))
  778.                     {
  779.                         TextEditInsertRawData(Window->ActiveTextEdit,GlobalReplaceString,
  780.                             SYSTEMLINEFEED);
  781.                         TextEditFindAgain(Window->ActiveTextEdit,GlobalSearchString);
  782.                         TextEditShowSelection(Window->ActiveTextEdit);
  783.                     }
  784.             }
  785.         else if (MenuItem == mShowSelection)
  786.             {
  787.                 TextEditShowSelection(Window->ActiveTextEdit);
  788.             }
  789.         else if (MenuItem == mEnterSelection)
  790.             {
  791.                 char*                        NewString;
  792.  
  793.                 NewString = TextEditGetSelection(Window->ActiveTextEdit);
  794.                 if (NewString != NIL)
  795.                     {
  796.                         ReleasePtr(GlobalSearchString);
  797.                         GlobalSearchString = NewString;
  798.                     }
  799.             }
  800.         else
  801.             {
  802.                 EXECUTE(PRERR(AllowResume,"AlgoWaveTableWindowDoMenuCommand:  unknown menu command"));
  803.             }
  804.     }
  805.  
  806.  
  807. /* get a copy of the algorithmic wave table's name */
  808. char*                                AlgoWaveTableWindowGetNameCopy(AlgoWaveTableWindowRec* Window)
  809.     {
  810.         char*                            ReturnValue;
  811.  
  812.         CheckPtrExistence(Window);
  813.         ReturnValue = TextEditGetRawData(Window->NameEdit,"\x0a");
  814.         if (ReturnValue != NIL)
  815.             {
  816.                 SetTag(ReturnValue,"AlgoWaveTableNameCopy");
  817.             }
  818.         return ReturnValue;
  819.     }
  820.  
  821.  
  822. /* get a copy of the algorithmic wave table's formula */
  823. char*                                AlgoWaveTableWindowGetFormulaCopy(AlgoWaveTableWindowRec* Window)
  824.     {
  825.         char*                            ReturnValue;
  826.  
  827.         CheckPtrExistence(Window);
  828.         ReturnValue = TextEditGetRawData(Window->FunctionEdit,"\x0a");
  829.         if (ReturnValue != NIL)
  830.             {
  831.                 SetTag(ReturnValue,"AlgoWaveTableFormulaCopy");
  832.             }
  833.         return ReturnValue;
  834.     }
  835.  
  836.  
  837. /* get the number of bits used for this algorithmic wave table */
  838. NumBitsType                    AlgoWaveTableWindowGetNumBits(AlgoWaveTableWindowRec* Window)
  839.     {
  840.         CheckPtrExistence(Window);
  841.         if (GetIconButtonState(Window->Bits16Button))
  842.             {
  843.                 return eSample16bit;
  844.             }
  845.          else
  846.             {
  847.                 return eSample8bit;
  848.             }
  849.     }
  850.  
  851.  
  852. /* get the number of periods in the table */
  853. long                                AlgoWaveTableWindowGetNumTables(AlgoWaveTableWindowRec* Window)
  854.     {
  855.         long                            ReturnValue;
  856.         char*                            StringTemp;
  857.  
  858.         CheckPtrExistence(Window);
  859.         StringTemp = TextEditGetRawData(Window->NumTablesEdit,"\x0a");
  860.         if (StringTemp != NIL)
  861.             {
  862.                 ReturnValue = StringToInteger(StringTemp,PtrSize(StringTemp));
  863.                 ReleasePtr(StringTemp);
  864.             }
  865.          else
  866.             {
  867.                 ReturnValue = 0;
  868.             }
  869.         if (ReturnValue < 0)
  870.             {
  871.                 ReturnValue = 0;
  872.             }
  873.         return ReturnValue;
  874.     }
  875.  
  876.  
  877. /* get the number of frames in each period */
  878. long                                AlgoWaveTableWindowGetNumFrames(AlgoWaveTableWindowRec* Window)
  879.     {
  880.         long                            ReturnValue;
  881.         char*                            StringTemp;
  882.  
  883.         CheckPtrExistence(Window);
  884.         StringTemp = TextEditGetRawData(Window->NumFramesEdit,"\x0a");
  885.         if (StringTemp != NIL)
  886.             {
  887.                 ReturnValue = StringToInteger(StringTemp,PtrSize(StringTemp));
  888.                 ReleasePtr(StringTemp);
  889.             }
  890.          else
  891.             {
  892.                 ReturnValue = 0;
  893.             }
  894.         return ReturnValue;
  895.     }
  896.  
  897.  
  898. /* the name of the file has changed, so update the title bar of the window.  the */
  899. /* NewFilename is a non-null-terminated string which must be disposed by the caller */
  900. void                                AlgoWaveTableWindowGlobalNameChange(AlgoWaveTableWindowRec* Window,
  901.                                             char* NewFilename)
  902.     {
  903.         char*                            LocalNameCopy;
  904.  
  905.         CheckPtrExistence(Window);
  906.         CheckPtrExistence(NewFilename);
  907.         LocalNameCopy = AlgoWaveTableWindowGetNameCopy(Window);
  908.         if (LocalNameCopy != NIL)
  909.             {
  910.                 char*                            SeparatorString;
  911.  
  912.                 SeparatorString = StringToBlockCopy(":  ");
  913.                 if (SeparatorString != NIL)
  914.                     {
  915.                         char*                            LeftHalfOfString;
  916.  
  917.                         LeftHalfOfString = ConcatBlockCopy(NewFilename,SeparatorString);
  918.                         if (LeftHalfOfString != NIL)
  919.                             {
  920.                                 char*                            TotalString;
  921.  
  922.                                 TotalString = ConcatBlockCopy(LeftHalfOfString,LocalNameCopy);
  923.                                 if (TotalString != NIL)
  924.                                     {
  925.                                         char*                            NullTerminatedString;
  926.  
  927.                                         NullTerminatedString = BlockToStringCopy(TotalString);
  928.                                         if (NullTerminatedString != NIL)
  929.                                             {
  930.                                                 SetWindowName(Window->ScreenID,NullTerminatedString);
  931.                                                 ChangeItemName(Window->MyMenuItem,NullTerminatedString);
  932.                                                 ReleasePtr(NullTerminatedString);
  933.                                             }
  934.                                         ReleasePtr(TotalString);
  935.                                     }
  936.                                 ReleasePtr(LeftHalfOfString);
  937.                             }
  938.                         ReleasePtr(SeparatorString);
  939.                     }
  940.                 ReleasePtr(LocalNameCopy);
  941.             }
  942.     }
  943.  
  944.  
  945. /* reset the title bar name of the window even if the filename hasn't changed */
  946. void                                AlgoWaveTableWindowResetTitlebar(AlgoWaveTableWindowRec* Window)
  947.     {
  948.         char*                            DocumentName;
  949.  
  950.         CheckPtrExistence(Window);
  951.         DocumentName = GetCopyOfDocumentName(Window->MainWindow);
  952.         if (DocumentName != NIL)
  953.             {
  954.                 AlgoWaveTableWindowGlobalNameChange(Window,DocumentName);
  955.                 ReleasePtr(DocumentName);
  956.             }
  957.     }
  958.  
  959.  
  960. /* write back all modified data to the object */
  961. MyBoolean                        AlgoWaveTableWindowWritebackModifiedData(AlgoWaveTableWindowRec* Window)
  962.     {
  963.         MyBoolean                    SuccessFlag = True;
  964.  
  965.         CheckPtrExistence(Window);
  966.  
  967.         if (TextEditDoesItNeedToBeSaved(Window->NameEdit))
  968.             {
  969.                 char*                        String;
  970.  
  971.                 String = AlgoWaveTableWindowGetNameCopy(Window);
  972.                 if (String != NIL)
  973.                     {
  974.                         AlgoWaveTableObjectNewName(Window->AlgoWaveTableObject,String);
  975.                         TextEditHasBeenSaved(Window->NameEdit);
  976.                     }
  977.                  else
  978.                     {
  979.                         SuccessFlag = False;
  980.                     }
  981.             }
  982.  
  983.         if (TextEditDoesItNeedToBeSaved(Window->FunctionEdit))
  984.             {
  985.                 char*                        String;
  986.  
  987.                 String = AlgoWaveTableWindowGetFormulaCopy(Window);
  988.                 if (String != NIL)
  989.                     {
  990.                         AlgoWaveTableObjectNewFormula(Window->AlgoWaveTableObject,String);
  991.                         TextEditHasBeenSaved(Window->FunctionEdit);
  992.                     }
  993.                  else
  994.                     {
  995.                         SuccessFlag = False;
  996.                     }
  997.             }
  998.  
  999.         if (TextEditDoesItNeedToBeSaved(Window->NumFramesEdit))
  1000.             {
  1001.                 AlgoWaveTableObjectPutNumFrames(Window->AlgoWaveTableObject,
  1002.                     AlgoWaveTableWindowGetNumFrames(Window));
  1003.                 TextEditHasBeenSaved(Window->NumFramesEdit);
  1004.             }
  1005.  
  1006.         if (TextEditDoesItNeedToBeSaved(Window->NumTablesEdit))
  1007.             {
  1008.                 AlgoWaveTableObjectPutNumTables(Window->AlgoWaveTableObject,
  1009.                     AlgoWaveTableWindowGetNumTables(Window));
  1010.                 TextEditHasBeenSaved(Window->NumTablesEdit);
  1011.             }
  1012.  
  1013.         if (Window->BitsChanged)
  1014.             {
  1015.                 AlgoWaveTableObjectPutNumBits(Window->AlgoWaveTableObject,
  1016.                     AlgoWaveTableWindowGetNumBits(Window));
  1017.                 Window->BitsChanged = False;
  1018.             }
  1019.  
  1020.         return SuccessFlag;
  1021.     }
  1022.