home *** CD-ROM | disk | FTP | other *** search
/ Carousel / CAROUSEL.cdr / mactosh / fonts / fontshow.sit / Menus.Pas < prev    next >
Pascal/Delphi Source File  |  1988-09-14  |  21KB  |  406 lines

  1. UNIT Menus(4);
  2. (* This unit contains menu handling routines for the FontShow program *)
  3. (* Version 1.0 by Richard Clark, September 1988 *)
  4. (* Version 1.1, September 13, 1988 -- Modified the Copy command so that it gets a new picture *)
  5. (*              each time Copy is selected instead of using the old WindowPict.  Fixed the    *)
  6. (*              field that specifies what type is being placed into the scrap -- using a      *)
  7. (*              Pascal string was getting it confused.  Also added a TEXT item to the scrap   *)
  8. (*              containing the entire ASCII character set.                                    *)
  9.  
  10. {$U-}
  11. {$D+}
  12.  
  13. INTERFACE
  14.  
  15.   {$U Globals}
  16.   {$U Windows}
  17.  
  18.    USES
  19.      MemTypes, QuickDraw, OSIntf, ToolIntf, PackIntf,
  20.      Globals, Windows;
  21.  
  22.       PROCEDURE InitMyMenus;                           (* Construct our menus and choose an initial font and size *)
  23.       PROCEDURE AdjustMenus (forceRedraw : Boolean);   (* Hilight our menus according to the type of the frontmost window *)
  24.       PROCEDURE DoMenus (menuCode : LONGINT);          (* Process a keypress or MouseDown in the menus *)
  25.  
  26.       PROCEDURE SetFontMenu;                           (* Set the chack mark to our current font *)
  27.       PROCEDURE SetSizeMenu;                           (* Show the sizes available in our current font *)
  28.  
  29. IMPLEMENTATION
  30.  
  31.   CONST
  32.           mApple  = 128;                                  (* Apple Menu *)
  33.           iaAbout = 1;
  34.  
  35.           mFile   = 129;                                  (* File Menu *)
  36.           ifNew   = 1;
  37.           ifClose = 2;
  38.     { ------- }
  39.           ifQuit  = 4;
  40.  
  41.           mEdit   = 130;                                  (* Edit Menu *)
  42.           ieUndo  = 1;
  43.     { ------- }
  44.           ieCut   = 3;
  45.           ieCopy  = 4;
  46.           iePaste = 5;
  47.     ieClear = 6;
  48.  
  49.           mFont   = 131;                                  (* Font Menu *)
  50.                                                     (* Items to be added *)
  51.  
  52.           mSize   = 132;                                  (* Size Menu *)
  53.                                                     (* We don't use item numbers here since we'll use *)
  54.                                                     (* the point sizes in the menu directly.  You can *)
  55.                                                     (* add other sizes directly by editing the menu   *)
  56.                                                     (* and re-compiling.                              *)
  57.  
  58.   VAR
  59.           AppleMenu,
  60.     FileMenu,
  61.     EditMenu,
  62.     FontMenu,
  63.     SizeMenu        : MenuHandle;                   (* Our menus *)
  64.           menuState       : INTEGER;                      (* For which kind of window are the menus currently set? *)
  65.  
  66.  
  67.   PROCEDURE InitMyMenus;
  68.   (* This procedure loads in our menus and sets them to their initial state *)
  69.      BEGIN
  70.           AppleMenu := GetMenu(mApple);                   (* Load the Apple Menu *)
  71.           AddResMenu(AppleMenu, 'DRVR');                  (* Append our list of desk accessories *)
  72.           InsertMenu(AppleMenu, 0);                       (* And append this to the menu bar *)
  73.  
  74.           FileMenu := GetMenu(mFile);                     (* Load the File menu *)
  75.           InsertMenu(FIleMenu, 0);
  76.  
  77.           EditMenu := GetMenu(mEdit);                     (* Load the Edit menu *)
  78.           InsertMenu(EditMenu, 0);
  79.  
  80.           FontMenu := GetMenu(mFont);                     (* Load the (empty) Font menu *)
  81.           AddResMenu(FontMenu, 'FONT');                   (* Ask the system to append a list of the available fonts *)
  82.           InsertMenu(FontMenu, 0);
  83.  
  84.           SizeMenu := GetMenu(mSize);                     (* Load the Size menu *)
  85.           InsertMenu(SizeMenu, 0);
  86.  
  87.           menuState := 0;                                 (* The menus need to have their initial states set-up *)
  88.  
  89.           DrawMenuBar;                                    (* AdjustMenus expects that the menu bar has already been drawn *)
  90.           SetFontMenu;                                    (* Put a check-mark by the current font *)
  91.           SetSizeMenu;                                    (* Show which sizes of the current font are available *)
  92.           AdjustMenus(TRUE);                              (* Adjust the menus and force a redraw of the menu bar *)
  93.      END; (* InitMyMenus *)
  94.  
  95.  
  96.   PROCEDURE AdjustMenus;
  97.   (* Set up our menus according to which window is in front.  The settings are:   *)
  98.   (*                                                                              *)
  99.   (*                            -- Window in front --                             *)
  100.   (*   Menu  |   No Windows  |  Font Window  |  About Window  |  Desk Accessory | *)
  101.   (*   ------+---------------+---------------+----------------+-----------------| *)
  102.   (*   Apple |  Enabled      |  Enabled      | Enabled        | Enabled         | *)
  103.   (*   ------+---------------+---------------+----------------+-----------------| *)
  104.   (*   File  |  Open & Quit  |  Enabled      | Enabled        | Enabled         | *)
  105.   (*         |  are Enabled, |               |                |                 | *)
  106.   (*         |  Close is     |               |                |                 | *)
  107.   (*         |  Disabled     |               |                |                 | *)
  108.   (*   ------+---------------+---------------+----------------+-----------------| *)
  109.   (*   Edit  |  Disabled     |  Only "Copy"  | Disabled       | Enabled         | *)
  110.   (*         |               |  is Enabled   |                |                 | *)
  111.   (*   ------+---------------+---------------+----------------+-----------------| *)
  112.   (*   Font  | Disabled      | Enabled       | Disabled       | Disabled        | *)
  113.   (*   ------+---------------+---------------+----------------+-----------------| *)
  114.   (*   Size  | Disabled      | Enabled       | Disabled       | Disabled        | *)
  115.   (*   ------+---------------+---------------+----------------+-----------------| *)
  116.   (*                                                                              *)
  117.  
  118.   CONST
  119.              NoWindows      = 0;                           (* Codes which represent our current window state *)
  120.              FontWindowUp   = 1;
  121.              AboutWindowUp  = 2;
  122.              DeskAccUp      = 3;
  123.  
  124.         VAR
  125.              inFront        : WindowPeek;                  (* The current frontmost window *)
  126.              lastState      : INTEGER;                     (* The current state of our menus *)
  127.  
  128.   BEGIN
  129.           lastState := menuState;                       (* record the last activation state of the menus *)
  130.  
  131.           inFront := WindowPeek(FrontWindow);           (* Get the front window *)
  132.           SetFontMenu;                                  (* Place a check mark by the current font *)
  133.           SetSizeMenu;                                  (* Mark off the currently available sizes *)
  134.           IF (inFront = NIL) THEN                       (* No windows are up *)
  135.           BEGIN
  136.                   menuState := NoWindows;
  137.                   DisableItem(FileMenu, ifClose);             (* (the rest of the file menu is always enabled) *)
  138.                   DisableItem(EditMenu, 0);                   (* This disables the whole menu *)
  139.                   DisableItem(FontMenu, 0);
  140.                   DisableItem(SizeMenu, 0);
  141.           END ELSE                                      (* We have at least one window open *)
  142.           BEGIN
  143.                EnableItem(FileMenu, ifClose);              (* Allow the user to close it from the File menu *)
  144.                   IF (inFront^.refCon = wFont) THEN
  145.                      BEGIN                                       (* This is a Font window *)
  146.                         menuState := FontWindowUp;
  147.                           EnableItem(FontMenu, 0);                  (* Turn on the Font and Size Menus *)
  148.                           EnableItem(SizeMenu, 0);
  149.                           EnableItem(EditMenu, 0);                  (* Enable the Edit menu, and disable all items but "Copy" *)
  150.         DisableItem(EditMenu, ieUndo);
  151.         DisableItem(EditMenu, 2);
  152.         DisableItem(EditMenu, ieCut);
  153.         DisableItem(EditMenu, iePaste);
  154.         DisableItem(EditMenu, ieClear);
  155.       END ELSE                                    (* It's a DA or the About window, *)
  156.                      BEGIN                                       (* so turn off the Font and Size menus *)
  157.                           DisableItem(FontMenu, 0);
  158.                           DisableItem(SizeMenu, 0);
  159.                           IF (inFront^.windowKind < 0) THEN
  160.                              BEGIN                                     (* This is a desk accessory, *)
  161.                                   menuState := DeskAccUp;                 (* so supply the Edit menu *)
  162.                                   EnableItem(EditMenu, 0);
  163.           DisableItem(EditMenu, ieUndo);          (* Turn on everything except the dividing line *)
  164.           DisableItem(EditMenu, 2);
  165.           EnableItem(EditMenu, ieCut);
  166.           EnableItem(EditMenu, ieCopy);
  167.           EnableItem(EditMenu, iePaste);
  168.           EnableItem(EditMenu, ieClear);
  169.                              END ELSE
  170.                              BEGIN                                     (* If it's the About window, supply only the File menu *)
  171.                                   menuState := AboutWindowUp;
  172.                                   DisableItem(EditMenu, 0);
  173.                              END;
  174.                      END;  (* We have a DA or the About window *)
  175.              END;  (* else (inFront <> nil )*)
  176.  
  177.           IF (menuState <> lastState) OR (forceRedraw) THEN
  178.                 DrawMenuBar;                               (* Redraw if we've made some changes, or if we're told to *)
  179.                                                   (* (we'll need to force a redraw if the current font or   *)
  180.                                                   (*  font size is changed, otherwise the change won't be   *)
  181.                                                   (* displayed                                              *)
  182.   END; (* AdjustMenus *)
  183.  
  184.  
  185.      PROCEDURE DoMenus;
  186.   (* This procedure takes the LONGINT value returned by MenuSelect and MenuKey, parses out the *)
  187.   (* requested menu and item numbers, then takes the appropriate action.                       *)
  188.         VAR
  189.              inMenu,                                       (* The currently selected menu *)
  190.     inItem      : INTEGER;                        (* The currently selected item *)
  191.  
  192.           PROCEDURE DoAppleMenu (inItem : INTEGER);     
  193.     (* This procedure processes requestds in the Apple menu *)
  194.              VAR 
  195.                   oldPort   : GrafPtr;                        (* These are used when opening a Desk Accessory *)
  196.                   DAName    : Str255;
  197.                   scratch   : INTEGER;
  198.  
  199.           BEGIN
  200.                IF (inItem = iaAbout) THEN                  (* The user select "About FontShow╔" *)
  201.                        DoAbout                                   (* Open the "About" window *)
  202.                   ELSE
  203.                   BEGIN                                       (* The user chose a Desk Accessory *)
  204.                        GetPort(oldPort);                         (* Save and restore the current GrafPort as some *)
  205.                                                   (* Desk Accessories change the port and forget   *)
  206.                                                   (* to set it back.                               *)
  207.                        GetItem(AppleMenu, inItem, DAName);       (* Get the text of the selected menu item *)
  208.                        scratch := OpenDeskAcc(DAName);           (* Open the Desk Accessory.  Scratch is the DA's *)
  209.         IF (scratch = 0) THEN                     (* reference number (if the open was successful),*)
  210.            SysBeep(5);                            (* or 0 if the open failed.                      *)
  211.                        SetPort(oldPort);                         (* restore our GrafPort *)
  212.                   END;
  213.       AdjustMenus(FALSE);                         (* Update the Menus, but don't force a redraw *)
  214.           END; (* DoAppleMenu *)
  215.  
  216.           PROCEDURE DoFileMenu (inItem : INTEGER);
  217.     (* This procedure handles requests in the File menu *)
  218.           BEGIN
  219.                CASE inItem OF
  220.                     ifNew   :  OpenAWindow;                   (* Open a new Font window using the current Font and Size values *)
  221.                     ifClose :  BEGIN 
  222.                      CloseAWindow(FrontWindow);   (* Close the frontmost window *)
  223.                      AdjustMenus(FALSE);          (* And update the menus to reflect our new state *)
  224.                    END;
  225.                     ifQuit  :  Quit := TRUE;                  (* Tell the main loop that we are done *)
  226.                END; (* CASE *)
  227.           END; (* DoFileMenu *)
  228.  
  229.  
  230.     PROCEDURE DoEditMenu (inItem : INTEGER);
  231.     (* This procedure handles requests in the Edit menu *)
  232.           VAR
  233.       inFront   : WindowPeek;
  234.       gridPict  : PicHandle;
  235.       scrapErr  : LONGINT;
  236.       scrapLen  : LONGINT;
  237.       pType,
  238.       tType     : resType;
  239.       allChars  : Str255;
  240.       count     : INTEGER;
  241.       
  242.     BEGIN
  243.       IF (SystemEdit(inItem - 1) = FALSE) THEN    (* Try to have the Desk Manager handle it *)
  244.       BEGIN                                       (* Sorry, it must be a request for the application *)
  245.         inFront := WindowPeek(FrontWindow);       (* Get the current window, so we can Copy its picture *)
  246.         IF (inItem = ieCopy) THEN                 (* We only accept Copy commands *)
  247.         BEGIN
  248.           IF (inFront^.refCon = wFont) THEN       (* ...and only if it's a Font window *)
  249.           BEGIN
  250.             gridPict := CreateFontPict(inFront^.port.txFont, inFront^.port.txSize);
  251.             if (gridPict <> nil) THEN
  252.             BEGIN
  253.               scrapLen := ORD(GetHandleSize(Handle(gridPict))); (* Calculate the size of our picture *)
  254.               scrapErr := ZeroScrap;                (* Erase the old entries in the clipboard *)
  255.               IF ((scrapErr = noErr)                (* If we cleared out the Clipboard, and we have *)
  256.                  AND (scrapLen <> 0)) THEN          (* something to put in it, then... *)
  257.               BEGIN
  258.                 HLock(Handle(gridPict));  (* Lock down our picture *)
  259.                 PType[1] := 'P';
  260.                 PType[2] := 'I';
  261.                 PType[3] := 'C';
  262.                 PType[4] := 'T';
  263.                 scrapErr := PutScrap(scrapLen, pType, Ptr(gridPict^)); (* and place it into the clipboard *)
  264.                 HUnlock(Handle(gridPict));(* Unlock our picture *)
  265.                 
  266.                 {$R- Turn off range checking.  (Warning -- Do not try this at home!)}
  267.                 FOR count := 0 TO 255 DO
  268.                   allChars[count] := CHR(count);
  269.                 {$R+}
  270.                 
  271.                 tType[1] := 'T';
  272.                 tType[2] := 'E';
  273.                 tType[3] := 'X';
  274.                 tType[4] := 'T';
  275.                 
  276.                 scrapErr := PutScrap(256, tType, @allChars);  (* Add the same information as a text string *)
  277.               END;
  278.               KillPicture(gridPict);
  279.             END;
  280.           END;
  281.         END; (* if this is a COPY command *)
  282.       END; (* IF *)
  283.           END; (* DoEditMenu *)
  284.  
  285.  
  286.           PROCEDURE DoFontMenu (inItem : INTEGER);
  287.     (* This procedure handles requests in the Font menu *)
  288.              VAR
  289.                   fName : Str255;                             (* The name of the selected font *)
  290.                   fNum  : integer;                            (* The number of the selected font *)
  291.  
  292.           BEGIN
  293.                GetItem(FontMenu, inItem, fName);           (* Get the text of the selected menu item *)
  294.                GetFNum(fName, fNum);                       (* Convert it to a font number *)
  295.                currFont := fNum;                           (* Set our font number to this *)
  296.                AttachWindowPict(WindowPeek(FrontWindow));  (* Replace the picture on the frontmost window *)
  297.                                                   (* with a picture of the selected font. *)
  298.                AdjustMenus(TRUE);                          (* Update the menus (including the checkmark in *)
  299.                                                   (* the Font menu and the information in the Size*)
  300.                                                   (* menu) and redraw the menus (to show the changes) *)
  301.           END; (* DoFontMenu *)
  302.  
  303.  
  304.           PROCEDURE DoSizeMenu (inItem : integer);
  305.     (* This procedure handles requests in the Size menu *)
  306.              VAR
  307.                   sizeString : Str255;                        (* The text of the selected item *)
  308.                   scratch    : LONGINT;                       (* The new size *)
  309.                   count      : INTEGER;                       (* Used when isolating the size number -- see below *)
  310.  
  311.           BEGIN
  312.                GetItem(SizeMenu, inItem, sizeString);      (* Get the selected text *)
  313.                INSERT(' ', sizeString, length(sizeString) + 1); (* Append a space *)
  314.                                                   (* Since the entries in the Size menu are of the *)
  315.                                                   (* form "<size> points", we need to search for   *)
  316.                                                   (* the first <space> character and delete every- *)
  317.                                                   (* thing from that point forward.  We appended   *)
  318.                                                   (* the spece (above) to guarantee that if the    *)
  319.                                                   (* menus are ever changed to numbers only, we    *)
  320.                                                   (* would still find something.                   *)
  321.                count := 1;
  322.                WHILE (sizeString[count] <> ' ') DO         (* Scan for the first space character *)
  323.                     count := count + 1;
  324.                DELETE(sizeString, count, length(sizeString) - count + 1); (* Get rid of everything from the *)
  325.                                                   (* space to the end of the string (including the *)
  326.                                                   (* space itself.                                 *)
  327.                StringToNum(sizeString, scratch);           (* Convert the new string (number only) into a   *)
  328.                                                   (* number. Since StringToNum wants a LONGINT,    *)
  329.                                                   (* we'll supply one.                             *)
  330.                currSize := scratch;                        (* Set the current size global *)
  331.                AttachWindowPict(WindowPeek(FrontWindow));  (* Change the frontmost window's PICT to reflect *)
  332.                                                   (* the new size *)
  333.                AdjustMenus(TRUE);                          (* And update the size menu to match, forcing a  *)
  334.                                                   (* redraw when done.                             *)
  335.           END; (* DoSizeMenu *)
  336.  
  337.   BEGIN (* DoMenus *)
  338.           IF (menuCode <> 0) THEN                       (* Only do this if the user selected an active item *)
  339.              BEGIN
  340.                   inMenu := HiWord(menuCode);                 (* Extract the Menu and Item codes *)
  341.                   inItem := LoWord(menuCode);
  342.                   CASE inMenu OF                              (* Dispatch the menu request *)
  343.                        mApple :  DoAppleMenu(inItem);
  344.                        mFile  :     DoFileMenu(inItem);
  345.                        mEdit  :     DoEditMenu(inItem);
  346.                        mFont  :     DoFontMenu(inItem);
  347.                        mSize  :  DoSizeMenu(inItem);
  348.                   END; (* CASE *)
  349.              END;
  350.              HiliteMenu(0);                                (* Un-hilite the selected menu *)
  351.   END; (* DoMenus *)
  352.  
  353.  
  354.      PROCEDURE SetFontMenu;
  355.   (* This procedure sets the checkmark in the Font menu to point to the currently selected font *)
  356.         VAR
  357.               fName,                                       (* The current font's name *)
  358.      itemString : Str255;                         (* The text of the menu item being examined *)
  359.               numItems,                                    (* How many entries are in this menu? *)
  360.      itemCount  : INTEGER;                        (* Loop control *)
  361.  
  362.      BEGIN
  363.           GetFontName(currFont, fName);                 (* Get the name of the current font *)
  364.           numItems := CountMItems(FontMenu);
  365.           FOR itemCount := 1 TO numItems DO             (* Compare the name to each item in the Font *)
  366.              BEGIN                                         (* menu, and place a checkmark if they match *)
  367.                   GetItem(FontMenu, itemCount, itemString);   (* Otherwise, remove any checkmark that may exist *)
  368.                   CheckItem(FontMenu, itemCount, itemString = fName);
  369.              END;
  370.      END; (* SetFontMenu *)
  371.  
  372.  
  373.      PROCEDURE SetSizeMenu;
  374.   (* This procedure sets the entries in the size menu to reflect the available sizes of the current *)
  375.   (* font.  It also places a checkmark by the currently selected size.                              *)
  376.         VAR
  377.              itemString : Str255;                          (* The menu item being examined *)
  378.              numItems,                                     (* How many items are in our menu? *)
  379.     itemCount  : INTEGER;                         (* Loop control *)
  380.              count      : INTEGER;                         (* Used when scanning for a space *)
  381.              scratch    : LONGINT;                         (* Used by StringToNum *)
  382.  
  383.      BEGIN
  384.           numItems := CountMItems(SizeMenu);              
  385.           FOR itemCount := 1 TO numItems DO             (* For each entry in the Size menu... *)
  386.              BEGIN
  387.                 GetItem(SizeMenu, itemCount, itemString);     (* Get the item *)
  388.                                                   (* Extract the number from the string (as in DoSizeMenu) *)
  389.                 INSERT(' ', itemString, length(itemString) + 1); 
  390.                 count := 1;
  391.                 WHILE (itemString[count] <> ' ') DO
  392.                     count := count + 1;
  393.                 DELETE(itemString, count, length(itemString) - count + 1);
  394.  
  395.                 StringToNum(itemString, scratch);             (* Convert the string to a number *)
  396.  
  397.                 IF RealFont(currFont, scratch) THEN           (* If this font exists at this size, *)
  398.                     SetItemStyle(SizeMenu, itemCount, [outline]) (* then outline it in the menu.  *)
  399.                 ELSE
  400.                     SetItemStyle(SizeMenu, itemCount, []);       (* Otherwise, make it plain *)
  401.  
  402.                  CheckItem(SizeMenu, itemCount, scratch = currSize); (* Place a checkmark here if it's the *)
  403.     END;                                          (* current size.  Otherwise, remove any checkmark *)
  404.     END;  (* SetSizeMenu *)
  405.  
  406. END.