home *** CD-ROM | disk | FTP | other *** search
/ Fish 'n' More 2 / fishmore-publicdomainlibraryvol.ii1991xetec.iso / disks / disk373.lzh / Multiplot / source / mplot_src / src.zoo / physio.c < prev    next >
C/C++ Source or Header  |  1990-08-02  |  54KB  |  1,322 lines

  1. #include "physio.h"
  2.  
  3. short tit;                   /* Flag for window title */
  4. void PToU();
  5.  
  6. /**********************************************************
  7. [                                                         ]
  8. [                InitWind()                               ]
  9. [                                                         ]
  10. [ Open interlace backdrop borderless window for rendering ]
  11. [ plot into.                                              ]
  12. [                                                         ]
  13. **********************************************************/
  14.  
  15. InitWind(Pict)
  16. struct Pict *Pict;
  17. {
  18.    newwindow.Screen = screen;
  19.    if (!(window = (struct Window *)OpenWindow(&newwindow)))
  20.       {
  21.          ErrorAlert(0);
  22.          FreeMemory(Pict);
  23.          CloseScreen(screen);
  24.          sexit(FALSE);
  25.       }
  26.    SetPointer(window,WaitSprite,26,14,-4,-4);
  27.    rp = window->RPort; vp = &window->WScreen->ViewPort;
  28.    SetDrMd(rp,JAM1); SetAPen(rp,1);
  29.    SetMenuStrip(window,&Project);
  30.    tit=TRUE;
  31.    return(1);
  32. }
  33.  
  34. /************************************************************
  35. [                                                           ]
  36. [            InitColours() and SavColours()                 ]
  37. [                                                           ]
  38. [ Open a default file, and read the new screen colours from ]
  39. [ it. Ditto for save.                                       ]
  40. [                                                           ]
  41. ************************************************************/
  42.  
  43. void InitColours()
  44. {
  45. int depth, i, r, g, b;
  46. FILE *fp;
  47.  
  48.    depth = 1 << screen->BitMap.Depth;   /* no easier way? */
  49.    strmfp(Def_file,StartDir,"MPlot.def");
  50.    if (!(fp = fopen(Def_file,"r")))
  51.       {
  52.          strcpy(Def_file,"s:");
  53.          strcat(Def_file,"MPlot.def");
  54.          fp = fopen(Def_file,"r");
  55.       }
  56.    if (!fp)
  57.       {
  58.           Message("  Can't open file MPlot.def     ");
  59.           SetRGB4(vp,0,15,10,5);   SetRGB4(vp,1,0,0,0);    SetRGB4(vp,2,15,15,15);
  60.           SetRGB4(vp,3,15,0,0);    SetRGB4(vp,4,0,0,0);    SetRGB4(vp,5,15,0,0);
  61.           SetRGB4(vp,6,0,12,0);    SetRGB4(vp,7,0,5,15);   SetRGB4(vp,8,13,13,0);
  62.           SetRGB4(vp,9,0,13,13);   SetRGB4(vp,10,15,0,15); SetRGB4(vp,11,10,10,0);
  63.           SetRGB4(vp,12,8,8,8);    SetRGB4(vp,13,5,5,0);   SetRGB4(vp,14,0,10,15);
  64.           SetRGB4(vp,15,15,8,0);
  65.       }
  66.    else
  67.       {
  68.          for (i=0; (i < depth) && (fscanf(fp,"%d %d %d\n",&r,&g,&b)==3); i++)
  69.            SetRGB4(vp,i,r,g,b);
  70.          fclose(fp);
  71.       }
  72. }
  73.  
  74.  
  75. SvColours()
  76. {
  77. int depth, i, r, g, b;
  78. FILE *fp;
  79. UWORD colour;               /* I only remember these typedefs */
  80. struct ColorMap *map;         /* when reading includes :-) */
  81.  
  82.    depth = 1 << screen->BitMap.Depth;   /* no easier way? */
  83.    map = vp->ColorMap;
  84.  
  85.    strmfp(Def_file,StartDir,"MPlot.def");
  86.  
  87.    if (!(fp = fopen(Def_file,"w")))
  88.       {
  89.          strcpy(Def_file,"s:");
  90.          strcat(Def_file,"MPlot.def");
  91.          fp = fopen(Def_file,"w");
  92.       }
  93.    if (!fp)
  94.       {
  95.           Message("  Can't open file MPlot.def     ");
  96.           return(0);
  97.       }
  98.    for (i=0; i < depth; i++)
  99.      {
  100.         colour = GetRGB4(map,i); /* each colour component encoded by 4 bits */
  101.         r = (colour & 0xf00) >> 8;
  102.         g = (colour & 0x0f0) >> 4;
  103.         b = (colour & 0x00f);
  104.         fprintf(fp,"%d %d %d\n",r,g,b);
  105.      }
  106.    fclose(fp);
  107.    return(1);
  108. }
  109.  
  110. /*************************************************************
  111. [                                                            ]
  112. [       CheckMenu(), ExcludeMenu() and AttrOnOff().          ]
  113. [                                                            ]
  114. [ Not nice, but keeps the Plot window menus up to date. Note ]
  115. [ this is run after the "Snooze pointer" is turned off. This ]
  116. [ creates the impression that the program runs faster than   ]
  117. [ it really does. Hope no-one has fast reflexes!             ]
  118. [                                                            ]
  119. *************************************************************/
  120.  
  121.  
  122. #define SELECT 0
  123. #define REGION 1
  124. #define LINE 2
  125. #define BOX 3
  126. #define SLIDE 4
  127. short MouseAction = SELECT;
  128.  
  129. CheckMenu(Pict)
  130. struct Pict *Pict;
  131. {
  132.    switch (Pict->Grid) {
  133.        case 0:
  134.                ExcludeMenu(&Tics,&Grid_si,&None);
  135.                ExcludeMenu(&StemNleaf,&BoxAxes,&NoAxes);
  136.                break;
  137.        case 1:
  138.                ExcludeMenu(&None,&Grid_si,&Tics);
  139.                ExcludeMenu(&StemNleaf,&BoxAxes,&NoAxes);
  140.                break;
  141.        case 2:
  142.                ExcludeMenu(&Grid_si,&Tics,&None);
  143.                ExcludeMenu(&BoxAxes,&StemNleaf,&NoAxes);
  144.                break;
  145.        case 3:
  146.                ExcludeMenu(&Tics,&Grid_si,&None);
  147.                ExcludeMenu(&BoxAxes,&StemNleaf,&NoAxes);
  148.                break;
  149.        case 4:
  150.                ExcludeMenu(&None,&Grid_si,&Tics);
  151.                ExcludeMenu(&BoxAxes,&StemNleaf,&NoAxes);
  152.                break;
  153.        case 5:
  154.                ExcludeMenu(&None,&Grid_si,&Tics);
  155.                ExcludeMenu(&NoAxes,&StemNleaf,&BoxAxes);
  156.                break;
  157.        default:
  158.                ExcludeMenu(&Tics,&Grid_si,&None);
  159.                ExcludeMenu(&StemNleaf,&BoxAxes,&NoAxes);
  160.                break;
  161.         }
  162.        switch (MouseAction) {
  163.        case SELECT: ExcludeMenu(&Select,&Zoom,&Slide); break;
  164.        case REGION: ExcludeMenu(&Zoom,&Select,&Slide); break;
  165.        case SLIDE:  ExcludeMenu(&Slide,&Zoom,&Select); break;
  166.        default: break;
  167.        }
  168.        return(1);
  169. }
  170.  
  171. ExcludeMenu(MItem1,MItem2,MItem3)
  172. struct MenuItem *MItem1, *MItem2, *MItem3;
  173. {
  174.     if (MItem2->Flags & CHECKED) MItem2->Flags &= ~CHECKED;
  175.     if (MItem3->Flags & CHECKED) MItem3->Flags &= ~CHECKED;
  176.     if (MItem1->Flags & CHECKED) return(0);
  177.     MItem1->Flags |= CHECKED;
  178.     return(1);
  179. }
  180.  
  181.  
  182. void AttrOnOff(Pict, item)
  183. struct Pict *Pict;
  184. int item;
  185. {
  186.    ClearMenuStrip(window);
  187.    switch(item) {
  188.    case SI_XREGION:
  189.       if (Pict->XRegionLock)
  190.         {
  191.            if (Xregion.Flags & CHECKED) ;
  192.            else Xregion.Flags |= CHECKED;
  193.         }
  194.       else if (Xregion.Flags & CHECKED) Xregion.Flags &= ~CHECKED;
  195.       break;
  196.    case SI_YREGION:
  197.       if (Pict->YRegionLock)
  198.         {
  199.            if (Yregion.Flags & CHECKED) ;
  200.            else Yregion.Flags |= CHECKED;
  201.         }
  202.       else if (Yregion.Flags & CHECKED) Yregion.Flags &= ~CHECKED;
  203.       break;
  204.    default: break;
  205.    }
  206.    SetMenuStrip(window, &Project);
  207. }
  208.  
  209. /************************************************************
  210. [                                                           ]
  211. [                     CleanUp()                             ]
  212. [                                                           ]
  213. [ Close interlace backdrop borderless window for rendering  ]
  214. [ plot into.                                                ]
  215. [                                                           ]
  216. ************************************************************/
  217.  
  218. void CleanUp()
  219. {ClearMenuStrip(window); CloseWindow(window);}
  220.  
  221. /************************************************************
  222. [                                                           ]
  223. [       PutXHair(), GetXHair() and KillXHair()              ]
  224. [                                                           ]
  225. [ Cross Hair handling. Works by drawing lines in COMPLIMENT ]
  226. [ then udrawing them by drawing them again.                 ]
  227. [                                                           ]
  228. ************************************************************/
  229.  
  230.  
  231. USHORT InvisPtr[] = {
  232.    0x0,0x0, 0x0,0x0, 0x0,0x0, 0x0,0x0, 0x0,0x0, 0x0,0x0, 0x0,0x0,
  233.    0x0,0x0, 0x0,0x0, 0x0,0x0, 0x0,0x0};
  234.  
  235. static short XHair = FALSE;
  236. static short WhiteBG = FALSE;
  237.  
  238. void PutXHair(x,y)
  239. short x,y;
  240. {Move(rp,0,y); Draw(rp,MAXHORIZ,y); Move(rp,x,0); Draw(rp,x,MAXVERT);}
  241.  
  242. void GetXHair(x,y)
  243. short *x, *y;
  244. {SetPointer(window,InvisPtr,9,9,0,0); PutXHair(*x,*y);}
  245.  
  246. void KillXHair(x,y)
  247. short x,y;
  248. {ClearPointer(window); PutXHair(x,y);}
  249.  
  250.  
  251. /************************************************************
  252. [                                                           ]
  253. [                     RubberBox()                           ]
  254. [                                                           ]
  255. [      Works same way as the cross hair handling            ]
  256. [                                                           ]
  257. ************************************************************/
  258.  
  259.  
  260. void RubberBox(x1, y1, x2, y2)
  261. short *x1, *y1, *x2, *y2;
  262. {
  263.    Move(rp,x1,y1);
  264.    if (XHair) {Draw(rp,x1,y2); Move(rp,x1,y1); Draw(rp,x2,y1);}
  265.    else {Draw(rp,x1,y2); Draw(rp,x2,y2); Draw(rp,x2,y1); Draw(rp,x1,y1);}
  266. }
  267.  
  268. /****************************************************************
  269. [                                                               ]
  270. [                     CheckUser(Pict)                           ]
  271. [                                                               ]
  272. [ The big bastard. This slug sits there waiting for you to move ]
  273. [ Is basically the entire user interface.                       ]
  274. [                                                               ]
  275. ****************************************************************/
  276. #define SHIFTED (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT)
  277.  
  278. extern int KEEP_GOING;
  279. extern char filename[150];
  280. extern int CALC_XMIN;
  281. extern int CALC_YMIN;
  282. extern struct Remember *Key;
  283.  
  284. struct TextBox *ExtraText=NULL;
  285. struct Selection *Sump=NULL;
  286. struct Remember *SumpKey=NULL;
  287.  
  288. CheckUser(Pict)
  289. struct Pict *Pict;
  290. {
  291.    ULONG class;
  292.    USHORT code, qual;
  293.  
  294.    static ULONG seconds, micros;
  295.    static ULONG Click_seconds=0, Click_micros=0;
  296.  
  297.    struct Selection *Seln, *TempSeln, *TempSump;
  298.    struct Remember *SelnKey=NULL;
  299.    struct TextBox *SelectedTextBox=NULL, *TempText, *GetSelectedText();
  300.    struct Plot *SelectedPlot=NULL, *GetSelectedPlot(), *TempPlot;
  301.    void KillText();
  302.    int retval = NOACTION, screensave(), CATCHUP;
  303.    static short x0, y0, x, y;
  304.    short tempx, tempy, x1, y1, count, RubberBand = FALSE, SlideBox = FALSE;
  305.    USHORT OldChoice;
  306.    FFP XMin, YMin, XMax, YMax;
  307.    struct PlotRegion *Reg;
  308.    struct Process  *OurTask;
  309.    struct Window   *old_pr_WindowPtr;
  310.    struct MenuItem *item;
  311.  
  312.    char plotname[150], def_drive[150], def_path[100], def_node[30],def_extn[20];
  313.    char Command[180];
  314.    char convert_tool[150];  /* string descibing path to current directory  */
  315.                             /* when started from workbench to locate tools */
  316.  
  317.  
  318.    AttrOnOff(Pict, SI_XREGION); AttrOnOff(Pict, SI_YREGION);
  319.    x1=x=window->MouseX; y1=y=window->MouseY;
  320.    SetDrMd(rp,COMPLEMENT);
  321.    if (XHair) GetXHair(&x,&y);
  322.    TempSeln=Seln=NULL; SelectedTextBox=NULL;
  323.  
  324.    do {
  325.       CATCHUP=FALSE;
  326.       while (msg = (struct IntuiMessage *) GetMsg(window->UserPort) ) {
  327.          class = msg->Class;
  328.          code = msg->Code; x = msg->MouseX; y = msg->MouseY;
  329.          seconds=msg->Seconds; micros=msg->Micros;
  330.          qual=msg->Qualifier;
  331.          ReplyMsg(msg);
  332.  
  333.        if (class == MENUPICK) {
  334.           while (code != MENUNULL) {
  335.             switch (MENUNUM(code)) {
  336.             case M_PROJECT:
  337.                switch(ITEMNUM(code)) {
  338.                case MI_QUIT:
  339.                   KEEP_GOING=FALSE;
  340.                   retval = QUIT;
  341.                   if (Sump) FreeRemember(&SumpKey,TRUE);
  342.                   Sump=NULL;
  343.                   break;
  344.                case MI_PRINT:
  345.                   SetPointer(window,WaitSprite,26,14,-4,-4);
  346.                   WrtPlt(Pict,FALSE);
  347.                   if (XHair) SetPointer(window,InvisPtr,9,9,0,0);
  348.                   else ClearPointer(window);
  349.                   break;
  350.                case MI_OPEN:         KEEP_GOING=TRUE; retval = QUIT; break;
  351.                case MI_SAVE:
  352.                   SetPointer(window,WaitSprite,26,14,-4,-4);
  353.                   SaveDat(Pict,FALSE);
  354.                   if (XHair) SetPointer(window,InvisPtr,9,9,0,0);
  355.                   else ClearPointer(window);
  356.                   break;
  357.                case MI_SAVEAS:
  358.                   switch (SUBNUM(code)) {
  359.                   case SI_HPGL:
  360.                     SetPointer(window,WaitSprite,26,14,-4,-4);
  361.                     WrtPlt(Pict,TRUE);
  362.                     if (XHair) SetPointer(window,InvisPtr,9,9,0,0);
  363.                     else ClearPointer(window);
  364.                     break;
  365.                   case SI_MCAD:
  366.                     SetPointer(window,WaitSprite,26,14,-4,-4);
  367.                     To_mCAD(Pict,TRUE);
  368.                     if (XHair) SetPointer(window,InvisPtr,9,9,0,0);
  369.                     else ClearPointer(window);
  370.                     break;
  371.                   case SI_IFF:
  372.                     SetPointer(window,WaitSprite,26,14,-4,-4);
  373.                     screensave();
  374.                     if (XHair) SetPointer(window,InvisPtr,9,9,0,0);
  375.                     else ClearPointer(window);
  376.                     break;
  377.                   case SI_DRAW:
  378.                     SetPointer(window,WaitSprite,26,14,-4,-4);
  379.                     strcpy(plotname,filename);
  380.                     strsfn(plotname,def_drive,def_path,def_node,def_extn);
  381.                     strcat(def_drive,def_path);
  382.                     strcat(def_node,".draw");
  383.  
  384.                      OurTask = (struct Process *)FindTask(0L);
  385.                      old_pr_WindowPtr = (struct Window *)OurTask->pr_WindowPtr;
  386.                      OurTask->pr_WindowPtr = (APTR)window;
  387.                      if (get_fname(window,screen,"Save File As...",def_node,def_drive)==NULL)
  388.                           {
  389.                              OurTask->pr_WindowPtr = (APTR)old_pr_WindowPtr;
  390.                              if (XHair) SetPointer(window,InvisPtr,9,9,0,0);
  391.                              else ClearPointer(window);
  392.                              break;
  393.                            }
  394.  
  395.                      OurTask->pr_WindowPtr = (APTR)old_pr_WindowPtr;
  396.                      strmfp(plotname,def_drive,def_node);
  397.                      if (To_mCAD(Pict,FALSE))
  398.                        {
  399.                          strmfp(convert_tool,StartDir,"plot2draw");
  400.                          sprintf(Command,"\"%s\" t:tempfile \"%s\"",convert_tool,plotname);
  401.                          Execute(Command,0,0);
  402.                          DeleteFile("t:tempfile");
  403.                        }
  404.                      if (XHair) SetPointer(window,InvisPtr,9,9,0,0);
  405.                      else ClearPointer(window);
  406.                      break;
  407.                   case SI_ICAD:
  408.                      SetPointer(window,WaitSprite,26,14,-4,-4);
  409.                      strcpy(plotname,filename);
  410.                      strsfn(plotname,def_drive,def_path,def_node,def_extn);
  411.                      strcat(def_drive,def_path);
  412.                      strcat(def_node,".iCAD");
  413.  
  414.                      OurTask = (struct Process *)FindTask(0L);
  415.                      old_pr_WindowPtr = (struct Window *)OurTask->pr_WindowPtr;
  416.                      OurTask->pr_WindowPtr = (APTR)window;
  417.                      if (get_fname(window,screen,"Save File As...",def_node,def_drive)==NULL)
  418.                           {
  419.                              OurTask->pr_WindowPtr = (APTR)old_pr_WindowPtr;
  420.                              if (XHair) SetPointer(window,InvisPtr,9,9,0,0);
  421.                              else ClearPointer(window);
  422.                              break;
  423.                            }
  424.                      OurTask->pr_WindowPtr = (APTR)old_pr_WindowPtr;
  425.                      strmfp(plotname,def_drive,def_node);
  426.                      if (To_mCAD(Pict,FALSE))
  427.                        {
  428.                          strmfp(convert_tool,StartDir,"txt_2_icad");
  429.                          sprintf(Command,"\"%s\" t:tempfile \"%s\"",convert_tool,plotname);
  430.                          Execute(Command,0,0);
  431.                          DeleteFile("t:tempfile");
  432.                        }
  433.                      if (XHair) SetPointer(window,InvisPtr,9,9,0,0);
  434.                      else ClearPointer(window);
  435.                      break;
  436.                   case SI_SAVEDAT:
  437.                     SetPointer(window,WaitSprite,26,14,-4,-4);
  438.                     SaveDat(Pict,TRUE);
  439.                     if (XHair) SetPointer(window,InvisPtr,9,9,0,0);
  440.                     else ClearPointer(window);
  441.                     break;
  442.                   default: break;
  443.                   }
  444.                   break;
  445.                default: break;
  446.                }
  447.                break;
  448.  
  449.             case M_EDIT:
  450.                switch (ITEMNUM(code)) {
  451.                case MI_UNDEL:
  452.                     if (!Sump) Message(" Nothing deleted to restore");
  453.                     else {
  454.                       if (Sump->SelectedPlot)  {
  455.                          for (TempSump=Sump;TempSump;TempSump=TempSump->NextSelection)
  456.                            {
  457.                               if (Pict->Plot) {
  458.                                  for (TempPlot=Pict->Plot;TempPlot->NextPlot;TempPlot=TempPlot->NextPlot) ;
  459.                                  TempPlot->NextPlot=TempSump->SelectedPlot;
  460.                                  for (TempPlot=TempPlot->NextPlot;TempPlot->Continued;TempPlot=TempPlot->NextPlot) ;
  461.                               }
  462.                               else {
  463.                                  Pict->Plot=TempSump->SelectedPlot;
  464.                                  for (TempPlot=Pict->Plot;TempPlot->Continued;TempPlot=TempPlot->NextPlot) ;
  465.                               }
  466.                               TempPlot->NextPlot=NULL;
  467.                            }
  468.                          FreeRemember(&SumpKey,TRUE);
  469.                          Sump=NULL;
  470.                       }
  471.                       else if (Sump->SelectedBox)  {
  472.                          for (TempSump=Sump;TempSump;TempSump=TempSump->NextSelection)
  473.                            {
  474.                               if (!ExtraText) {
  475.                                   ExtraText=TempSump->SelectedBox;
  476.                                   ExtraText->NextText=NULL;
  477.                               }
  478.                               else {
  479.                                   for (TempText=ExtraText;TempText->NextText;TempText=TempText->NextText) ;
  480.                                   TempText->NextText=TempSump->SelectedBox;
  481.                                   TempText->NextText->NextText=NULL;
  482.                               }
  483.                            }
  484.                          FreeRemember(&SumpKey,TRUE);
  485.                          Sump=NULL;
  486.                       }
  487.                     retval=max(retval,REDRAW);
  488.                     CALC_XMIN=TRUE;
  489.                     }
  490.                     break;
  491.                case MI_COPY:
  492.                     if (!Seln) Message("   Nothing selected to copy");
  493.                     else {
  494.                        SetPointer(window,WaitSprite,26,14,-4,-4);
  495.                        ClipCopy(Pict,Seln);
  496.                        if (XHair) SetPointer(window,InvisPtr,9,9,0,0);
  497.                        else ClearPointer(window);
  498.                     }
  499.                     break;
  500.                case MI_PASTE:
  501.                     SetPointer(window,WaitSprite,26,14,-4,-4);
  502.                     if (ClipPaste(Pict)) {retval=max(retval,REDRAW); CALC_XMIN=TRUE;}
  503.                     else {
  504.                        if (XHair) SetPointer(window,InvisPtr,9,9,0,0);
  505.                        else ClearPointer(window);
  506.                     }
  507.                     break;
  508.                case MI_CUT:
  509.                     if (!Seln) Message("   Nothing selected to cut");
  510.                     else {
  511.                        SetPointer(window,WaitSprite,26,14,-4,-4);
  512.                        if (ClipCopy(Pict,Seln)) {
  513.                            if (DeleteSeln(Pict,Seln,&SelnKey)) retval=max(retval,REFRESH);
  514.                            else {
  515.                               if (XHair) SetPointer(window,InvisPtr,9,9,0,0);
  516.                               else ClearPointer(window);
  517.                            }
  518.                        }
  519.                        else {
  520.                           if (XHair) SetPointer(window,InvisPtr,9,9,0,0);
  521.                           else ClearPointer(window);
  522.                        }
  523.                     }
  524.                     break;
  525.                case MI_ADDTEXT:
  526.                     if (!SelectedPlot)
  527.                       {
  528.                         if (ExtraText)
  529.                           {
  530.                              for (TempText=ExtraText;TempText->NextText;TempText=TempText->NextText);
  531.                              if (TempText->NextText=(struct TextBox *) AllocRemember(&Key,(sizeof(struct TextBox)),MEMF_CLEAR))
  532.                                {
  533.                                   TempText=TempText->NextText;
  534.                                   EditText(TempText->String);
  535.                                   TempText->x=400; TempText->y=200;
  536.                                   TempText->NextText=NULL;
  537.                                   retval = REDRAW;
  538.                                }
  539.                              else Message("  Not enough memory for text");
  540.                           }
  541.                         else
  542.                           {
  543.                              if (ExtraText=(struct TextBox *) AllocRemember(&Key,(sizeof(struct TextBox)),MEMF_CLEAR))
  544.                                {
  545.                                   TempText=ExtraText;
  546.                                   EditText(TempText->String);
  547.                                   TempText->x=400; TempText->y=200;
  548.                                   TempText->NextText=NULL;
  549.                                   retval = REDRAW;
  550.                                }
  551.                              else Message("  Not enough memory for text");
  552.                            }
  553.                       }
  554.                     else
  555.                       {
  556.                         EditText(SelectedPlot->Legend->String);
  557.                         Pict->RMargin=CALC_XMIN=TRUE; retval = REDRAW;
  558.                       }
  559.                     break;
  560.                case MI_DELETE:
  561.                     if (DeleteSeln(Pict,Seln,&SelnKey)) retval=max(retval,REFRESH);
  562.                     else Message(" Nothing selected to delete");
  563.                     break;
  564.                default: break;
  565.                }
  566.                break;
  567.  
  568.             case M_ACTIONS:
  569.                switch (ITEMNUM(code)) {
  570.                case MI_MACTION:
  571.                   switch (SUBNUM(code)) {
  572.                   case SI_SELECT:   MouseAction = SELECT;  break;
  573.                   case SI_ZOOM:     MouseAction = REGION; break;
  574.                   case SI_SLIDE:    MouseAction = SLIDE; break;
  575.                   default:          break;
  576.                   }
  577.                   CheckMenu(Pict);
  578.                   break;
  579.                case MI_FULLPLOT:  retval = max(retval,GETDATALIMITS); break;
  580.                case MI_REDRAW:    retval = max(retval,REDRAW); break;
  581.                case MI_GETHOWTO:  CALC_XMIN=TRUE; retval= max(retval,GETHOWTO); break;
  582.                case MI_LOCKS:
  583.                   switch (SUBNUM(code)) {
  584.                   case SI_LOCKSON:
  585.                      Pict->XRegionLock=Pict->YRegionLock=TRUE;
  586.                      AttrOnOff(Pict, SI_XREGION);
  587.                      AttrOnOff(Pict, SI_YREGION);
  588.                      break;
  589.                   case SI_LOCKSOFF:
  590.                      Pict->XRegionLock=Pict->YRegionLock=FALSE;
  591.                      AttrOnOff(Pict, SI_XREGION);
  592.                      AttrOnOff(Pict, SI_YREGION);
  593.                      break;
  594.                   case SI_YREGION:
  595.                      Pict->YRegionLock=!Pict->YRegionLock;
  596.                      AttrOnOff(Pict, SI_YREGION);
  597.                      break;
  598.                   case SI_XREGION:
  599.                      Pict->XRegionLock=!Pict->XRegionLock;
  600.                      AttrOnOff(Pict, SI_XREGION);
  601.                      break;
  602.                   default: break;
  603.                   }
  604.                   break;
  605.                default: break;
  606.                }
  607.                break;
  608.             case M_OPTIONS:
  609.                switch (ITEMNUM(code)) {
  610.                case MI_CROSSHAIR:
  611.                   if (XHair = !XHair) {GetXHair(&x,&y); x1=x; y1=y;}
  612.                   else KillXHair(x1,y1);
  613.                   break;
  614.                case MI_RMARGIN:
  615.                   if (Pict->RMargin) Pict->RMargin=FALSE;
  616.                   else Pict->RMargin=TRUE;
  617.                   CALC_XMIN=TRUE;
  618.                   retval=max(retval,REDRAW);
  619.                   break;
  620.                case MI_ERRBARS:
  621.                   if (Pict->ErrBar)
  622.                     {
  623.                       if (Pict->ShowErr) Pict->ShowErr = FALSE;
  624.                       else Pict->ShowErr = TRUE;
  625.                       retval=max(retval,REFRESH);
  626.                     }
  627.                   break;
  628.                case MI_GRID:
  629.                   switch (SUBNUM(code)) {
  630.                   case SI_NONE:
  631.                         if (Pict->Grid==0){Pict->Grid=1; retval=max(retval,REDRAW);}
  632.                         if ((Pict->Grid==2)||(Pict->Grid==3)) {Pict->Grid=4; retval=max(retval,REDRAW);}
  633.                         break;
  634.                   case SI_TICS:
  635.                         if ((Pict->Grid==1)||(Pict->Grid==5)){Pict->Grid=0; retval=max(retval,REFRESH);}
  636.                         if ((Pict->Grid==2)||(Pict->Grid==4)){Pict->Grid=3; retval=max(retval,REFRESH);}
  637.                         break;
  638.                   case SI_GRID:
  639.                         if (Pict->Grid!=2){Pict->Grid=2; retval=max(retval,REFRESH);}
  640.                         break;
  641.                   }
  642.                   break;
  643.                case MI_AXES:
  644.                   switch (SUBNUM(code)) {
  645.                   case SI_NOAXES:
  646.                         if (Pict->Grid!=5){Pict->Grid=5; retval=max(retval,REDRAW);}
  647.                         break;
  648.                   case SI_BOXAXES:
  649.                         if (Pict->Grid==0){Pict->Grid=3; retval=max(retval,REFRESH);}
  650.                         if ((Pict->Grid==1)||(Pict->Grid==5)){Pict->Grid=4; retval=max(retval,REFRESH);}
  651.                         break;
  652.                   case SI_STEMNLEAF:
  653.                         if ((Pict->Grid==2)||(Pict->Grid==3)){Pict->Grid=0; retval=max(retval,REFRESH);}
  654.                         if ((Pict->Grid==4)||(Pict->Grid==5)){Pict->Grid=1; retval=max(retval,REFRESH);}
  655.                         break;
  656.                   }
  657.                   break;
  658.                case MI_PALETTE:
  659.                   switch (SUBNUM(code)) {
  660.                   case SI_ALTERCOL:
  661.                      SetPointer(window,WaitSprite,26,14,-4,-4);
  662.                      DoColorWindow(screen, 150, 60, 1, TRUE);
  663.                      if (XHair) SetPointer(window,InvisPtr,9,9,0,0);
  664.                      else ClearPointer(window);
  665.                      break;
  666.                   case SI_SAVECOL:
  667.                      SetPointer(window,WaitSprite,26,14,-4,-4);
  668.                      SvColours();
  669.                      if (XHair) SetPointer(window,InvisPtr,9,9,0,0);
  670.                      else ClearPointer(window);
  671.                      break;
  672.                   default: break;
  673.                   }
  674.                   break;
  675.                case MI_SCREENTITLE:
  676.                   if (tit==TRUE) {ShowTitle(screen,FALSE);tit=FALSE;}
  677.                   else {ShowTitle(screen,TRUE); tit=TRUE;}
  678.                   break;
  679.                default: break;
  680.                }
  681.                break;
  682.             case M_FUNCTIONS:
  683.                switch (ITEMNUM(code)) {
  684.                case MI_SORT:
  685.                  if (!SelectedPlot) {Message("A Data Set Must Be Selected");}
  686.                  else
  687.                    {
  688.                       SetPointer(window,WaitSprite,26,14,-4,-4);
  689.                       if (SortData(Pict,SelectedPlot))
  690.                         {
  691.                            CALC_XMIN=CALC_YMIN=TRUE;
  692.                            retval = max(retval,GETDATALIMITS);
  693.                         }
  694.                       if (XHair) SetPointer(window,InvisPtr,9,9,0,0);
  695.                       else ClearPointer(window);
  696.                    }
  697.                  break;
  698.                case MI_SMOOTH:
  699.                  if (!SelectedPlot) {Message("A Data Set Must Be Selected");}
  700.                  else
  701.                    {
  702.                       SetPointer(window,WaitSprite,26,14,-4,-4);
  703.                       if (SmoothData(Pict,SelectedPlot)) {
  704.                           retval=max(retval,GETDATALIMITS);
  705.                           CALC_XMIN=CALC_YMIN=TRUE;
  706.                           }
  707.                       if (XHair) SetPointer(window,InvisPtr,9,9,0,0);
  708.                       else ClearPointer(window);
  709.                    }
  710.                  break;
  711.                case MI_LINEFIT:
  712.                  if (!SelectedPlot) {Message("A Data Set Must Be Selected");}
  713.                  else
  714.                    {
  715.                       SetPointer(window,WaitSprite,26,14,-4,-4);
  716.                       if (FitData(Pict,SelectedPlot)) {
  717.                           retval = max(retval,GETDATALIMITS);
  718.                           Pict->RMargin=CALC_XMIN=CALC_YMIN=TRUE;
  719.                           }
  720.                       if (XHair) SetPointer(window,InvisPtr,9,9,0,0);
  721.                       else ClearPointer(window);
  722.                    }
  723.                  break;
  724.                case MI_LOGFIT:
  725.                  if (!SelectedPlot) {Message("A Data Set Must Be Selected");}
  726.                  else
  727.                    {
  728.                       SetPointer(window,WaitSprite,26,14,-4,-4);
  729.                       if (FitLogData(Pict,SelectedPlot)) {
  730.                           retval=max(retval,GETDATALIMITS);
  731.                           Pict->RMargin=CALC_XMIN=CALC_YMIN=TRUE;
  732.                           }
  733.                       if (XHair) SetPointer(window,InvisPtr,9,9,0,0);
  734.                       else ClearPointer(window);
  735.                    }
  736.                  break;
  737.                default: break;
  738.                }
  739.                break;
  740.             default: break;
  741.             }                   /* switch */
  742.             item=(struct MenuItem *)ItemAddress(&Project,code);
  743.             code=item->NextSelect;
  744.           }                     /* While loop */
  745.         }                       /* if ((class == MENUPICK) ...*/
  746.         else  if ( class == RAWKEY) {
  747.               if (code ==95) ;      /* HELP key PRESSED */
  748.               else if (code ==69)   /* ESCAPE key PRESSED */
  749.                 {
  750.                    KEEP_GOING=FALSE;
  751.                    retval = QUIT;
  752.                    if (Sump) FreeRemember(&SumpKey,TRUE);
  753.                    Sump=NULL;
  754.                 }
  755.               else if (code ==70)   /* DELETE key PRESSED */
  756.                 {
  757.                   if (DeleteSeln(Pict,Seln,&SelnKey)) retval=max(retval,REDRAW);
  758.                   else Message(" Nothing selected to delete");
  759.                 }
  760.         }
  761.         else if (class == MOUSEBUTTONS) {
  762.                switch (code) {
  763.                case SELECTDOWN:
  764.                   if (MouseAction==SELECT)  {  /* Find the Data Set attached to nearest point */
  765.                      CATCHUP=TRUE; OldChoice=FALSE;
  766.                      SelectedPlot = GetSelectedPlot(Pict,&count,x,y);
  767.                      if (SelectedPlot) SelectedTextBox=NULL;
  768.                      else SelectedTextBox=GetSelectedText(Pict,x,y);
  769.  
  770.                      if ((Seln)&&(Seln->SelectedPlot)) {   /* If some Plots already selected */
  771.                        if (!SelectedPlot) {
  772.                          TempSeln=Seln;   /* Dump old Selection */
  773.                          while ((TempSeln)&&(TempSeln->SelectedPlot))
  774.                            {
  775.                               HighlightPlot(Pict,TempSeln->SelectedPlot); /* Unhighlight */
  776.                               TempSeln=TempSeln->NextSelection;
  777.                            }
  778.                           FreeRemember(&SelnKey,TRUE); Seln=NULL;
  779.                        }
  780.                        else {                           /* A selection */
  781.                          if (qual&SHIFTED) {            /* To be added to list */
  782.                            if (!CheckSeln(Seln,SelectedPlot)) {   /* It's a new one */
  783.                              TempSeln=Seln;
  784.                              while (TempSeln->NextSelection) TempSeln=TempSeln->NextSelection;
  785.                              TempSeln->NextSelection = (struct Selection *)AllocRemember(&SelnKey,sizeof(struct Selection),MEMF_CLEAR);
  786.                              if (TempSeln->NextSelection) {
  787.                                TempSeln=TempSeln->NextSelection;
  788.                                TempSeln->SelectedPlot=SelectedPlot; TempSeln->SelectedBox=NULL; TempSeln->NextSelection=NULL;
  789.                                HighlightPlot(Pict,SelectedPlot);
  790.                              }
  791.                              else Message("Not enough memory for selection");
  792.                            }
  793.                            else ;  /* if Already selected, do nothing */
  794.                          }
  795.                          else  { /* If not shifted, dump old select, get new */
  796.                            TempSeln=Seln;
  797.                            while ((TempSeln)&&(TempSeln->SelectedPlot)) {
  798.                              if (TempSeln->SelectedPlot==SelectedPlot) OldChoice=TRUE;
  799.                              else HighlightPlot(Pict,TempSeln->SelectedPlot); /* Unhighlight */
  800.                              TempSeln=TempSeln->NextSelection;
  801.                            }
  802.                            FreeRemember(&SelnKey,TRUE);
  803.                            Seln = (struct Selection *)AllocRemember(&SelnKey,sizeof(struct Selection),MEMF_CLEAR);
  804.                            if (Seln) {
  805.                              if (!OldChoice) HighlightPlot(Pict,SelectedPlot);
  806.                              Seln->SelectedPlot=SelectedPlot; Seln->SelectedBox=NULL; Seln->NextSelection=NULL;
  807.                            }
  808.                            else Message("Not enough memory for selection");
  809.                          }
  810.                        }
  811.                      }
  812.                      else if ((Seln)&&(Seln->SelectedBox)) {
  813.                        if (!SelectedTextBox) {
  814.                          TempSeln=Seln;   /* Dump old Selection */
  815.                          while ((TempSeln)&&(TempSeln->SelectedBox))
  816.                            {
  817.                               SlipperyBox(TempSeln->SelectedBox->x1,TempSeln->SelectedBox->y1,TempSeln->SelectedBox->x2,TempSeln->SelectedBox->y2);
  818.                               TempSeln=TempSeln->NextSelection;
  819.                            }
  820.                           FreeRemember(&SelnKey,TRUE); Seln=NULL;
  821.                        }
  822.                        else {             /* A selection */
  823.                          if (qual&SHIFTED) {            /* To be added to list */
  824.                            if (!CheckSelnText(Seln,SelectedTextBox)) {   /* It's a new one */
  825.                              TempSeln=Seln;
  826.                              while (TempSeln->NextSelection) TempSeln=TempSeln->NextSelection;
  827.                              TempSeln->NextSelection = (struct Selection *)AllocRemember(&SelnKey,sizeof(struct Selection),MEMF_CLEAR);
  828.                              if (TempSeln->NextSelection) {
  829.                                TempSeln=TempSeln->NextSelection;
  830.                                TempSeln->SelectedBox=SelectedTextBox; TempSeln->SelectedPlot=NULL; TempSeln->NextSelection=NULL;
  831.                                SlipperyBox(SelectedTextBox->x1,SelectedTextBox->y1,SelectedTextBox->x2,SelectedTextBox->y2);
  832.                              }
  833.                              else Message("Not enough memory for selection");
  834.                            }
  835.                            else ;  /* if Already selected, do nothing */
  836.                          }
  837.                          else  { /* If not shifted, dump old select, get new */
  838.                            TempSeln=Seln;
  839.                            while ((TempSeln)&&(TempSeln->SelectedBox)) {
  840.                              if (TempSeln->SelectedBox==SelectedTextBox) OldChoice=TRUE;
  841.                              else SlipperyBox(TempSeln->SelectedBox->x1,TempSeln->SelectedBox->y1,TempSeln->SelectedBox->x2,TempSeln->SelectedBox->y2);
  842.                              TempSeln=TempSeln->NextSelection;
  843.                            }
  844.                            FreeRemember(&SelnKey,TRUE);
  845.                            Seln = (struct Selection *)AllocRemember(&SelnKey,sizeof(struct Selection),MEMF_CLEAR);
  846.                            if (Seln) {
  847.                              if (!OldChoice) SlipperyBox(SelectedTextBox->x1,SelectedTextBox->y1,SelectedTextBox->x2,SelectedTextBox->y2);
  848.                              Seln->SelectedBox=SelectedTextBox; Seln->SelectedPlot=NULL; Seln->NextSelection=NULL;
  849.                            }
  850.                            else Message("Not enough memory for selection");
  851.                          }
  852.                          SlideBox = TRUE;
  853.                        }
  854.                      }
  855.                      if (!Seln) {
  856.                        if (SelectedPlot) {
  857.                          Seln = (struct Selection *)AllocRemember(&SelnKey,sizeof(struct Selection),MEMF_CLEAR);
  858.                          if (Seln) {
  859.                            Seln->SelectedPlot=SelectedPlot; Seln->SelectedBox=NULL; Seln->NextSelection=NULL;
  860.                            HighlightPlot(Pict,SelectedPlot);
  861.                          }
  862.                          else Message("Not enough memory for selection");
  863.                        }
  864.                        else if (SelectedTextBox) {
  865.                          Seln = (struct Selection *)AllocRemember(&SelnKey,sizeof(struct Selection),MEMF_CLEAR);
  866.                          if (Seln) {
  867.                            Seln->SelectedBox=SelectedTextBox; Seln->SelectedPlot=NULL; Seln->NextSelection=NULL;
  868.                            SlipperyBox(SelectedTextBox->x1,SelectedTextBox->y1,SelectedTextBox->x2,SelectedTextBox->y2);
  869.                            SlideBox = TRUE;
  870.                          }
  871.                          else Message("Not enough memory for selection");
  872.                        }
  873.                      }
  874.                   }    /** end of "if was select"  **/
  875.  
  876.                   if (DoubleClick(Click_seconds,Click_micros,seconds,micros)
  877.                        &&PrettyClose(x0,x)&&PrettyClose(y0,y))
  878.                       {
  879.                          if (MouseAction==SELECT) /* Find the Data Set attached to nearest point */
  880.                            {
  881.                               if ((Seln)&&(Seln->SelectedPlot)) {
  882.                                   if (CustomPlotWindow(Pict,SelectedPlot,count)) {
  883.                                      CALC_XMIN=TRUE; retval= REDRAW;
  884.                                      }
  885.                                    }
  886.                               else if ((Seln)&&(Seln->SelectedBox)) {
  887.                                   EditText(SelectedTextBox->String);
  888.                                   if (!strlen(SelectedTextBox->String))  {
  889.                                      if (DeleteSeln(Pict,Seln,&SelnKey))  {
  890.                                         CALC_XMIN=TRUE;
  891.                                         retval = REDRAW;
  892.                                      }
  893.                                   }
  894.                                }
  895.                                else {
  896.                                   if (y<(MAXVERT-YMAXP)) {
  897.                                      EditText(Pict->Title);
  898.                                      AllowForText(Pict);
  899.                                      retval = REDRAW;
  900.                                      }
  901.                                   else if (y>(MAXVERT-YMINP)) {
  902.                                      EditAxes('x',&Pict->Tics->NX,&Pict->CurrReg->XMin,&Pict->CurrReg->XMax,Pict->Tics->x);
  903.                                      AllowForText(Pict);
  904.                                      retval = REDRAW;
  905.                                      }
  906.                                   if (x<(XMINP)) {
  907.                                      EditAxes('y',&Pict->Tics->NY,&Pict->CurrReg->YMin,&Pict->CurrReg->YMax,Pict->Tics->y);
  908.                                      AllowForText(Pict);
  909.                                      retval = REDRAW;
  910.                                      }
  911.                                   }
  912.                            }
  913.                          else    /* is Zoom or Slide... */
  914.                            {         /* zoom out X 2 */
  915.                              RubberBand = FALSE;
  916.                              if (MouseAction == REGION)
  917.                                 {
  918.                            /*       RubberBox(x0,y0,x1,y1);  */
  919.                                   Reg=Pict->CurrReg;
  920.                                   XMin=Reg->XMin-(Reg->XMax-Reg->XMin)/2;
  921.                                   XMax=Reg->XMax+(Reg->XMin-XMin);
  922.                                   YMin=Reg->YMin-(Reg->YMax-Reg->YMin)/2;
  923.                                   YMax=Reg->YMax+(Reg->YMin-YMin);
  924.                                   if ((!Pict->XRegionLock)&&( ( (FullReg->XMax-FullReg->XMin)/(XMax-XMin) )<100 ))
  925.                                       {Reg->XMin = XMin; Reg->XMax = XMax;}
  926.                                   if ((!Pict->YRegionLock)&&(((FullReg->YMax-FullReg->YMin)/(YMax-YMin))<100))
  927.                                       {Reg->YMin = YMin; Reg->YMax = YMax;}
  928.                                   retval = REPLOT;
  929.                                 }
  930.                            }
  931.                       }
  932.                   if ((x1!=x)||(y1!=y)) {if(XHair) {PutXHair(x1,y1);PutXHair(x,y);}}
  933.                   x0=x1=x; y0=y1=y;
  934.                   if (MouseAction && !RubberBand)  /* BEGIN RUBBERBAND */
  935.                      {
  936.                         RubberBand = TRUE;
  937.                         if (MouseAction == REGION) {
  938.                            RubberBox(x0,y0,x,y);
  939.                         }
  940.                         else if (MouseAction == SLIDE) {
  941.                            Move(rp,x,y); Draw(rp,x,y);
  942.                         }
  943.                      }
  944.                   Click_seconds=seconds; Click_micros=micros;
  945.                   break;
  946.                case SELECTUP:  /* END RUBBERBAND */
  947.                   if (RubberBand)
  948.                     {
  949.                       RubberBand = FALSE;
  950.                       if (MouseAction == REGION) {
  951.                           RubberBox(x0,y0,x1,y1);
  952.                           Reg = Pict->CurrReg;
  953.                           if ((abs(x-x0) > 2) && (abs(y-y0) > 2)) {
  954.                              /* zoom in to new region */
  955.                              PToU(Pict,min(x0,x),MAXVERT-max(y0,y),&XMin,&YMin);
  956.                              PToU(Pict,max(x0,x),MAXVERT-min(y0,y),&XMax,&YMax);
  957.                              if ((!Pict->XRegionLock)&&( ( (FullReg->XMax-FullReg->XMin)/(XMax-XMin) )<100 ))
  958.                                {Reg->XMin = XMin; Reg->XMax = XMax;}
  959.                              if ((!Pict->YRegionLock)&&(((FullReg->YMax-FullReg->YMin)/(YMax-YMin))<100))
  960.                                {Reg->YMin = YMin; Reg->YMax = YMax;}
  961.                              retval = REPLOT;
  962.                           }
  963.                       }
  964.                       else if (MouseAction == SLIDE) {
  965.                           Move(rp,x0,y0); Draw(rp,x1,y1);
  966.                           PToU(Pict,x0,MAXVERT-y0,&XMin,&YMin);
  967.                           PToU(Pict,x,MAXVERT-y,&XMax,&YMax);
  968.                           Reg = Pict->CurrReg;
  969.                           if (!Pict->XRegionLock)
  970.                              {Reg->XMin += XMin-XMax; Reg->XMax += XMin-XMax;}
  971.                           if (!Pict->YRegionLock)
  972.                              {Reg->YMin += YMin-YMax; Reg->YMax += YMin-YMax;}
  973.                           retval = REPLOT;
  974.                       }
  975.                     }
  976.                   else if (SlideBox)
  977.                     {
  978.                        SlideBox=FALSE;
  979.                        if ((abs(x-x0)>2)||(abs(y-y0)>2)) retval=REFRESH;
  980.                     }
  981.                   break;
  982.                default: break;
  983.             } /* switch (code) */
  984.             break;
  985.          } /* else if (class == MENUBUTTONS) */
  986.       } /* while */
  987.       if ((class == MOUSEMOVE) && ((x1!=x)||(y1!=y)) )  {
  988.          if (XHair)  {PutXHair(x1,y1); PutXHair(x,y);}
  989.          if (RubberBand) {
  990.             if (MouseAction == REGION)
  991.                {RubberBox(x0,y0,x1,y1); RubberBox(x0,y0,x,y);}
  992.             else if (MouseAction == SLIDE)
  993.                {Move(rp,x0,y0); Draw(rp,x1,y1); Move(rp,x0,y0); Draw(rp,x,y);}
  994.          }
  995.          else if (SlideBox) {
  996.            tempx=x-x1; tempy=y-y1;
  997.  
  998.            for (TempSeln=Seln;TempSeln;TempSeln=TempSeln->NextSelection)
  999.              {
  1000.                 SlipperyBox(TempSeln->SelectedBox->x1,TempSeln->SelectedBox->y1,TempSeln->SelectedBox->x2,TempSeln->SelectedBox->y2);
  1001.              }
  1002.            for (TempSeln=Seln;TempSeln;TempSeln=TempSeln->NextSelection)
  1003.              {
  1004.                 TempSeln->SelectedBox->x1+=tempx; TempSeln->SelectedBox->x2+=tempx;
  1005.                 TempSeln->SelectedBox->y1+=tempy; TempSeln->SelectedBox->y2+=tempy;
  1006.                 TempSeln->SelectedBox->x+=tempx; TempSeln->SelectedBox->y-=tempy; /* Remember screen coords upside down */
  1007.              }
  1008.            for (TempSeln=Seln;TempSeln;TempSeln=TempSeln->NextSelection)
  1009.              {
  1010.                 SlipperyBox(TempSeln->SelectedBox->x1,TempSeln->SelectedBox->y1,TempSeln->SelectedBox->x2,TempSeln->SelectedBox->y2);
  1011.              }
  1012.          }
  1013.          x1 = x; y1 = y;
  1014.       }
  1015.       if ((retval==NOACTION)&&(!CATCHUP)) Wait(1 << window->UserPort->mp_SigBit);
  1016.    } while(retval == NOACTION);
  1017.  
  1018.    if (XHair) PutXHair(x1,y1);
  1019.    if (SelnKey) { FreeRemember(&SelnKey,TRUE); Seln=NULL;}
  1020.    SetDrMd(rp, JAM1);
  1021.    return(retval);
  1022. }
  1023.  
  1024. struct Plot *GetSelectedPlot(Pict,count,x,y)
  1025. struct Pict *Pict;
  1026. short x, y, *count;
  1027. {
  1028. int LOOKING, i;
  1029. short *xarray, *yarray;
  1030. struct Plot *Plot, *TempPlot;
  1031.  
  1032.    LOOKING=TRUE;
  1033.    Plot = Pict->Plot;
  1034.    *count=0;
  1035.    while (LOOKING) {
  1036.        TempPlot=Plot;
  1037.        do {
  1038.             if (Plot->Enabled)
  1039.               {
  1040.                   xarray = TempPlot->xp; yarray = TempPlot->yp;
  1041.                   for (i=0;i<TempPlot->NPts;i++)
  1042.                     {
  1043.                        if (PrettyClose(x,xarray[i])&&PrettyClose(y,MAXVERT-yarray[i]))
  1044.                           return(Plot);
  1045.                     }
  1046.                }
  1047.            } while ((TempPlot->Continued)&&(TempPlot=TempPlot->NextPlot));
  1048.        if (Plot=TempPlot->NextPlot) *count+=1;
  1049.        else LOOKING=FALSE;
  1050.    }
  1051.    return(NULL);
  1052. }
  1053.  
  1054.  
  1055. HighlightPlot(Pict,Plot)
  1056. struct Pict *Pict;
  1057. struct Plot *Plot;
  1058. {
  1059. short i,x,y;
  1060. short *xarray, *yarray;
  1061.  
  1062.   do {
  1063.         xarray = Plot->xp; yarray = Plot->yp;
  1064.         for (i=0;i<Plot->NPts;i++)
  1065.           {
  1066.             x=xarray[i]; y=MAXVERT-yarray[i];
  1067.             if (ClipPoint(x,y,XMINP,TMARGIN,XMAXP,MAXVERT-BMARGIN))
  1068.               {
  1069.                  Move(rp,x-5,y-5); Draw(rp,x+5,y-5);
  1070.                  Draw(rp,x+5,y+5); Draw(rp,x-5,y+5);
  1071.                  Draw(rp,x-5,y-5);
  1072.               }
  1073.           }
  1074.      } while ((Plot->Continued)&&(Plot=Plot->NextPlot));
  1075.   return(0);
  1076. }
  1077.  
  1078.  
  1079. PrettyClose(x,y)
  1080. int x,y;
  1081. {
  1082.   if ((y>x-5)&&(y<x+5)) return(TRUE);
  1083.   else return(FALSE);
  1084. }
  1085.  
  1086.  
  1087. extern struct TextFont *lf;
  1088. extern struct TextAttr lfont;
  1089. extern struct IntuiText Legend;
  1090. extern int CHARWIDTH, CHARHEIGHT;
  1091.  
  1092. IsInTextBox(x,y,TextBox,Flag)
  1093. short x,y,Flag;
  1094. struct TextBox *TextBox;
  1095. {
  1096. short boxlength, boxheight;
  1097.  
  1098.    if (lf)
  1099.        {
  1100.           Legend.IText=TextBox->String;
  1101.           boxlength= IntuiTextLength(&Legend);
  1102.           boxheight= lfont.ta_YSize;
  1103.         }
  1104.     else
  1105.         {
  1106.            boxlength= (strlen(TextBox->String)*CHARWIDTH);
  1107.            boxheight= CHARHEIGHT;
  1108.         }
  1109.   TextBox->x1=TextBox->x-10;
  1110.   if (Flag) TextBox->x2=TextBox->x+boxlength+10;  /* An extra text */
  1111.   else TextBox->x2=TextBox->x+boxlength+35;       /* A legend      */
  1112.   TextBox->y1=MAXVERT-TextBox->y-boxheight/2-3;
  1113.   TextBox->y2=MAXVERT-TextBox->y+boxheight/2;
  1114.   if ((x<TextBox->x2)&&(x>TextBox->x1)&&(y<TextBox->y2)&&(y>TextBox->y1)) return(TRUE);
  1115.   else return(FALSE);
  1116. }
  1117.  
  1118.  
  1119. SlipperyBox(x1, y1, x2, y2)
  1120. short x1, y1, x2, y2;
  1121. {
  1122.     Move(rp,x1,y1);
  1123.     Draw(rp,x2,y1);
  1124.     Draw(rp,x2,y2);
  1125.     Draw(rp,x1,y2);
  1126.     Draw(rp,x1,y1);
  1127.     return(TRUE);
  1128. }
  1129.  
  1130. CheckSeln(Seln,Plot)
  1131. struct Selection *Seln;
  1132. struct Plot *Plot;
  1133. {
  1134.  
  1135.    while ((Seln)&&(Seln->SelectedPlot))
  1136.      {
  1137.         if (Seln->SelectedPlot==Plot) return(TRUE);
  1138.         Seln=Seln->NextSelection;
  1139.      }
  1140.    return(FALSE);
  1141. }
  1142.  
  1143. CheckSelnText(Seln,TextBox)
  1144. struct Selection *Seln;
  1145. struct TextBox *TextBox;
  1146. {
  1147.  
  1148.    while ((Seln)&&(Seln->SelectedBox))
  1149.      {
  1150.         if (Seln->SelectedBox==TextBox) return(TRUE);
  1151.         Seln=Seln->NextSelection;
  1152.      }
  1153.    return(FALSE);
  1154. }
  1155.  
  1156. struct TextBox *GetSelectedText(Pict,x,y)
  1157. struct Pict *Pict;
  1158. short x, y;
  1159. {
  1160. struct Plot *Plot;
  1161. struct TextBox *TempText;
  1162.  
  1163.      for (Plot=Pict->Plot;Plot;Plot=Plot->NextPlot) {
  1164.        if (Plot->Enabled && strlen(Plot->Legend->String) && IsInTextBox(x,y,Plot->Legend,FALSE))
  1165.           return(Plot->Legend);
  1166.      }
  1167.      for (TempText=ExtraText;TempText;TempText=TempText->NextText) {
  1168.        if (TempText && IsInTextBox(x,y,TempText,TRUE))
  1169.           return(TempText);
  1170.      }
  1171.      return(NULL);
  1172.  }
  1173.  
  1174.  
  1175.  
  1176.  
  1177. DeleteSeln(Pict,Seln,SelnKey)
  1178. struct Pict *Pict;
  1179. struct Selection *Seln;
  1180. struct Remember **SelnKey;   /*** Note: Address of pointer passed. cf SumpKey ***/
  1181. {
  1182.    struct Selection *TempSeln, *TempSump;
  1183.    struct TextBox *GetSelectedText(), *TempText;
  1184.    struct Plot *Plot, *GetSelectedPlot();
  1185.    void KillText(), KillPlot();
  1186.    short legflag;
  1187.  
  1188.     if ((Seln)&&(Seln->SelectedPlot)) {   /* If some Plots selected */
  1189.         if (Sump) FreeRemember(&SumpKey,TRUE);
  1190.         Sump=NULL; TempSeln=Seln;
  1191.  
  1192.         while ((TempSeln)&&(TempSeln->SelectedPlot)) {
  1193.             KillPlot(Pict,TempSeln->SelectedPlot);
  1194.             TempSeln=TempSeln->NextSelection;
  1195.         }
  1196.         return(TRUE);
  1197.      }
  1198.      else if ((Seln)&&(Seln->SelectedBox)) {
  1199.         if (Sump) FreeRemember(&SumpKey,TRUE);
  1200.         Sump=NULL; TempSeln=Seln;
  1201.         while (TempSeln) {
  1202.           legflag=FALSE;
  1203.           for (Plot=Pict->Plot;Plot;Plot=Plot->NextPlot) {
  1204.               if (Plot->Legend==TempSeln->SelectedBox) {
  1205.                  /*** If legend, make a new text box for Plot structure ***/
  1206.                  legflag=TRUE; TempSump=NULL;
  1207.                  if (TempText=(struct TextBox *) AllocRemember(&Key,(sizeof(struct TextBox)),MEMF_CLEAR))
  1208.                    {
  1209.                       TempSump = (struct Selection *)AllocRemember(&SumpKey,sizeof(struct Selection),MEMF_CLEAR);
  1210.                       if (TempSump) {
  1211.                          TempSump->SelectedBox=TempSeln->SelectedBox;
  1212.                          TempSump->SelectedBox->NextText=NULL;
  1213.                          AddSump(TempSump);
  1214.                       }
  1215.                       else Message("Not enough memory for undelete");
  1216.                       Plot->Legend=TempText;
  1217.                       Plot->Legend->NextText=NULL;
  1218.                    }
  1219.                  else Message("Not enough memory for delete");
  1220.               }
  1221.           }
  1222.           if ((!legflag)&&(strlen(TempSeln->SelectedBox->String))) /* Not a legend, not deleted */
  1223.             {
  1224.  
  1225.                KillText(TempSeln->SelectedBox);
  1226.             }
  1227.           TempSeln=TempSeln->NextSelection;
  1228.         }
  1229.         FreeRemember(SelnKey,TRUE);
  1230.         return(TRUE);
  1231.      }
  1232.      else return(FALSE);
  1233. }
  1234.  
  1235.  
  1236. void KillText(TextBox)
  1237. struct TextBox *TextBox;
  1238. {
  1239. struct TextBox *TempText;
  1240. struct Selection *TempSump;
  1241.  
  1242.     if ((TextBox)&&(ExtraText==TextBox))    /* Check if is the first Text */
  1243.       {
  1244.          TempSump = (struct Selection *)AllocRemember(&SumpKey,sizeof(struct Selection),MEMF_CLEAR);
  1245.          if (TempSump) {
  1246.              TempSump->SelectedBox=ExtraText;
  1247.              AddSump(TempSump);
  1248.          }
  1249.          else Message("Not enough memory for undelete");
  1250.          ExtraText=ExtraText->NextText;
  1251.       }
  1252.     else if (TextBox)            /* Is in the middle of chain */
  1253.       {
  1254.          for (TempText=ExtraText;TempText->NextText&&TempText->NextText!=TextBox;TempText=TempText->NextText);
  1255.          if (TempText->NextText)
  1256.            {
  1257.               TempSump = (struct Selection *)AllocRemember(&SumpKey,sizeof(struct Selection),MEMF_CLEAR);
  1258.               if (TempSump) {
  1259.                   TempSump->SelectedBox=TempText->NextText;
  1260.                   AddSump(TempSump);
  1261.               }
  1262.               else Message("Not enough memory for undelete");
  1263.               TempText->NextText=TempText->NextText->NextText;
  1264.            }
  1265.       }
  1266. }
  1267.  
  1268. void KillPlot(Pict,Plot)
  1269. struct Pict *Pict;
  1270. struct Plot *Plot;
  1271. {
  1272. struct Plot *TempPlot;
  1273. struct Selection *TempSump;
  1274.  
  1275.     if (Pict->Plot==Plot)    /* Check if is the first data set */
  1276.       {
  1277.          TempSump = (struct Selection *)AllocRemember(&SumpKey,sizeof(struct Selection),MEMF_CLEAR);
  1278.          if (TempSump) {
  1279.              TempSump->SelectedPlot=Pict->Plot;
  1280.              AddSump(TempSump);
  1281.          }
  1282.          else Message("Not enough memory for undelete");
  1283.          while (Pict->Plot->Continued) Pict->Plot=Pict->Plot->NextPlot;
  1284.          Pict->Plot=Pict->Plot->NextPlot;
  1285.       }
  1286.     else             /* Is in the middle of chain */
  1287.       {
  1288.          TempPlot=Pict->Plot;
  1289.          while (TempPlot->NextPlot!=Plot) TempPlot=TempPlot->NextPlot;
  1290.          TempSump = (struct Selection *)AllocRemember(&SumpKey,sizeof(struct Selection),MEMF_CLEAR);
  1291.          if (TempSump) {
  1292.              TempSump->SelectedPlot=Plot;
  1293.              AddSump(TempSump);
  1294.          }
  1295.          else Message("Not enough memory for undelete");
  1296.          while (TempPlot->NextPlot->Continued)
  1297.               TempPlot->NextPlot=TempPlot->NextPlot->NextPlot;
  1298.          TempPlot->NextPlot=TempPlot->NextPlot->NextPlot;
  1299.       }
  1300.     Pict->NPlt--;
  1301. }
  1302.  
  1303. AddSump(NewSump)
  1304. struct Selection *NewSump;
  1305. {
  1306. struct Selection *TempSump;
  1307.  
  1308.   if (Sump)
  1309.     {
  1310.        for (TempSump=Sump;TempSump->NextSelection; TempSump=TempSump->NextSelection) ;
  1311.        TempSump->NextSelection=NewSump;
  1312.     }
  1313.   else Sump=NewSump;
  1314.   NewSump->NextSelection=NULL;
  1315.   return(0);
  1316. }
  1317.  
  1318.  
  1319.  
  1320.  
  1321.  
  1322.