-- Compiler menu/nb -- MStone November 26, 1980 5:50 PM -- Tiberi January 25, 1980 1:37 PM -- MStone February 15, 1984 11:24:17 am PST DIRECTORY MenuDefs: FROM "MenuDefs", Graphics USING [Context], ControllerDefs USING [AppendFont, CurrentStyle], Rope USING [Length,ROPE], ScreenDefs USING [SetFunction, SetFillParms, BoxFill, InvertBox, GreyType, EraseBox], ScreenDefsExtras USING [ShowMenuString], StyleDefs: FROM "StyleDefs", RefreshDefs: FROM "RefreshDefs", GriffinFontDefs: FROM "GriffinFontDefs", PointDefs: FROM "PointDefs", GraphicsColor USING [IntensityToColor], ObjectDefs: FROM "ObjectDefs" USING [MenuOrientation, StartObject, ObjectProc, ForAllObjects, ReplotBoxFromObject, Object], GriffinMemoryDefs USING [CZone]; GriffinMenu: PROGRAM IMPORTS Rope, ObjectDefs, GriffinFontDefs, GriffinMemoryDefs, ScreenDefs, ControllerDefs, RefreshDefs, GraphicsColor, PointDefs, ScreenDefsExtras EXPORTS MenuDefs = BEGIN OPEN MenuDefs, ObjectDefs, GriffinMemoryDefs; X: INTEGER = PointDefs.X; Y: INTEGER = PointDefs.Y; ROPE: TYPE = Rope.ROPE; menuLineWidth: INTEGER = 3; menuMargin: INTEGER = 4; menuTopMargin: INTEGER = 1; menuStyle: StyleDefs.StyleHandle _ NIL; menuFont: GriffinFontDefs.FontDescriptorHandle _ CZone.NEW[GriffinFontDefs.FontDescriptor _ [name: "Cream", rotation: 0, face: 0, points: 10]]; menuHeight: INTEGER _ 0; menuBaseLine: REAL _ 0; menuGrey: ScreenDefs.GreyType _ GraphicsColor.IntensityToColor[.5]; twoLineWidth: INTEGER = 2*menuLineWidth; MenuStyle: PUBLIC PROCEDURE RETURNS [StyleDefs.StyleHandle] = BEGIN RETURN [menuStyle] END; CreateMenu: PUBLIC PROCEDURE [orientation: MenuOrientation, tl: PointDefs.ScrPt, title: ROPE] RETURNS [menu: MenuHandle] = BEGIN menu _ NARROW [StartObject [menu]]; -- a MenuHandle is a REF menu Object menu.head _ NIL; menu.validEncoding _ TRUE; menu.style _ menuStyle; menu.orientation _ orientation; menu.visible _ FALSE; menu.tl _ tl; -- leave space for enclosing box SELECT orientation FROM vertical => BEGIN menu.br [X] _ tl [X] + twoLineWidth-1; menu.br [Y] _ tl [Y] + menuLineWidth-1; END; horizontal => BEGIN menu.br [X] _ tl [X] + menuLineWidth-1; menu.br [Y] _ tl [Y] + twoLineWidth + menuHeight; END; ENDCASE; IF title # NIL AND Rope.Length[title] > 0 THEN AddMenuItem [menu, title, NullMenuProc].inverted _ TRUE; END; NullMenuProc: MenuProc = BEGIN END; ItemWidth: PROCEDURE [string:ROPE] RETURNS [INTEGER] = INLINE BEGIN RETURN [ PointDefs.ObjValToScrVal[GriffinFontDefs.StringWidth[string,menuFont, menuStyle.orientation]] + menuMargin - 1]; END; AddMenuItem: PUBLIC PROCEDURE [menu: MenuHandle, string: ROPE, proc: MenuProc] RETURNS [MenuItemHandle] = BEGIN newitem: MenuItemHandle; rover: MenuItemHandle; first: BOOLEAN _ FALSE; newitem _ CZone.NEW[MenuItem]; newitem^ _ [link: NIL, menu: menu, selected: FALSE, inverted: FALSE, tl: , br: , string: NIL, proc: proc]; IF menu.head=NIL THEN BEGIN first _ TRUE; menu.head _ newitem END ELSE BEGIN FOR rover _ NARROW[menu.head], rover.link UNTIL rover.link = NIL DO ENDLOOP; --find end rover.link _ newitem END; SELECT menu.orientation FROM vertical => BEGIN newitem.tl [X] _ menu.tl [X] + menuLineWidth; newitem.tl [Y] _ menu.br [Y] + 1; END; horizontal => BEGIN newitem.tl [X] _ menu.br [X] + 1; newitem.tl [Y] _ menu.tl [Y] + menuLineWidth; END; ENDCASE; newitem.string _ string; SELECT menu.orientation FROM vertical => BEGIN width: INTEGER _ ItemWidth[string]; IF first OR menu.tl[X] + width + twoLineWidth > menu.br [X] THEN ChangeMenuWidth[menu, width] ELSE newitem.br [X] _ menu.br [X] - menuLineWidth; newitem.br [Y] _ newitem.tl [Y] + menuHeight; menu.br [Y] _ newitem.br [Y] + menuLineWidth; END; horizontal => BEGIN newitem.br [X] _ newitem.tl [X] + ItemWidth[string]; newitem.br [Y] _ menu.br [Y] - menuLineWidth; menu.br [X] _ newitem.br [X] + menuLineWidth END; ENDCASE; IF menu.visible THEN RefreshDefs.EraseAndSave[menu]; RETURN [newitem]; END; ChangeMenuWidth: PROCEDURE [menu: MenuHandle, width: INTEGER] = BEGIN OPEN ObjectDefs; WidenMenu: MenuProc = BEGIN item.br [X] _ item.tl [X] + width; END; IF menu.orientation # vertical THEN ERROR; ForAllMenuItems [menu, WidenMenu]; menu.br [X] _ menu.tl [X] + width + twoLineWidth; IF menu.visible THEN RefreshDefs.EraseAndSave[menu]; END; ForAllMenus: PUBLIC PROCEDURE [proc: PROCEDURE [menu: MenuHandle]] = BEGIN OPEN ObjectDefs; IsMenu: ObjectProc = BEGIN WITH obj SELECT FROM mref: REF Object[menu] => proc[mref]; ENDCASE; END; ForAllObjects[IsMenu]; END; ForAllMenuItems: PUBLIC PROCEDURE [menu: MenuHandle, proc: MenuProc] = BEGIN rover: MenuItemHandle; FOR rover _ NARROW[menu.head], rover.link UNTIL rover = NIL DO proc [rover] ENDLOOP; END; PlotMenu: PUBLIC PROCEDURE [menu: MenuHandle, dc: Graphics.Context] = BEGIN tl, br: PointDefs.ScrPt; showItem: MenuProc = {ShowItem[item,dc]}; ScreenDefs.EraseBox[menu.tl, menu.br, dc]; ScreenDefs.SetFunction[opaque]; ScreenDefs.SetFillParms[menuGrey]; menu.visible _ TRUE; --top edge: tl _ menu.tl; br [X] _ menu.br[X]; br [Y] _ tl [Y] + menuLineWidth - 1; ScreenDefs.BoxFill [tl, br, dc]; --left edge: br [X] _ tl [X] + menuLineWidth - 1; br [Y] _ menu.br [Y]; tl _ menu.tl; ScreenDefs.BoxFill [tl, br, dc]; -- the right edge: tl [X] _ menu.br [X] - menuLineWidth + 1; tl [Y] _ menu.tl [Y]; br _ menu.br; ScreenDefs.BoxFill [tl, br, dc]; -- the bottom edge: tl [X] _ menu.tl [X]; tl [Y] _ menu.br [Y] - menuLineWidth + 1; br _ menu.br; ScreenDefs.BoxFill [tl, br, dc]; ForAllMenuItems [menu, showItem]; END; ShowMenu: PUBLIC PROCEDURE [menu: MenuHandle] = BEGIN menu.visible _ TRUE; RefreshDefs.PlotAndMark[menu]; END; HideMenu: PUBLIC PROCEDURE [menu: MenuHandle] = BEGIN menu.visible _ FALSE; RefreshDefs.EraseAndSave[menu]; END; ShowItem: PROCEDURE [item: MenuItemHandle, dc: Graphics.Context] = BEGIN tl, br: PointDefs.ScrPt; tl _ item.tl; br _ IF item.menu.orientation = vertical THEN [item.br[X], item.br[Y] + menuLineWidth] ELSE [item.br[X] + menuLineWidth, item.br[Y]]; IF item.menu.orientation = vertical THEN tl [Y] _ item.br [Y]+1 -- bottom edges ELSE tl [X] _ item.br [X]+1; -- right edges ScreenDefs.SetFunction[opaque]; ScreenDefs.SetFillParms[menuGrey]; ScreenDefs.BoxFill [tl, br, dc]; ScreenDefsExtras.ShowMenuString[MenuAnchorPoint[item], item.string, dc]; -- GriffinFontDefs.DisplayString [item.string, -- PointDefs.ScrToObj[MenuAnchorPoint[item]], -- StyleDefs.Anchor [center], -- StyleDefs.Orientation [or0], menuFont, dc]; IF item.inverted THEN ScreenDefs.InvertBox[item.tl, item.br, dc]; END; OverWhichItem: PUBLIC PROCEDURE [pt: PointDefs.ScrPt] RETURNS [lastitem: MenuItemHandle] = BEGIN lastover: MenuHandle _ NIL; IsOverMenu: PROCEDURE[m: MenuHandle] = BEGIN IF m.visible AND pt [X] IN [m.tl[X]..m.br[X]] AND pt [Y] IN [m.tl[Y]..m.br[Y]] THEN lastover _ m; END; LastItemOver: MenuProc = BEGIN IF pt [X] IN [item.tl [X] .. item.br [X]] AND pt [Y] IN [item.tl [Y] .. item.br [Y]] THEN lastitem _ item END; lastitem _ NIL; ForAllMenus[IsOverMenu]; IF lastover = NIL THEN RETURN [NIL]; -- which menu item? ForAllMenuItems[lastover, LastItemOver]; END; IsOverItem: PUBLIC PROCEDURE [pt: PointDefs.ScrPt, item: MenuItemHandle] RETURNS [BOOLEAN] = BEGIN IF pt [X] IN [item.tl [X]..item.br [X]] AND pt [Y] IN [item.tl [Y]..item.br [Y]] THEN RETURN [TRUE] ELSE RETURN [FALSE]; END; BugItem: PUBLIC PROCEDURE [item: MenuItemHandle] = BEGIN item.proc [item] END; --questions about menus: WhichMenu: PUBLIC PROCEDURE [item: MenuItemHandle] RETURNS [menu: MenuHandle] = BEGIN RETURN [item.menu] END; IsSelected: PUBLIC PROCEDURE [item: MenuItemHandle] RETURNS [BOOLEAN] = BEGIN RETURN [item.selected] END; MenuString: PUBLIC PROCEDURE [item: MenuItemHandle] RETURNS [ROPE] = BEGIN RETURN [item.string] END; MenuAnchorPoint: PUBLIC PROCEDURE [item: MenuItemHandle] RETURNS [pt: PointDefs.ScrPt] = BEGIN pt[X] _ (item.br[X]+item.tl[X])/2 + 1; pt[Y] _ item.tl[Y] + menuTopMargin; END; --changing things: SetMenuString: PUBLIC PROCEDURE [item: MenuItemHandle, string: ROPE] = BEGIN menu: MenuHandle = item.menu; width: INTEGER _ 0; FindWidest: MenuProc = BEGIN w: INTEGER _ ItemWidth[item.string]; IF w>width THEN width _ w; END; item.string _ string; IF menu.visible THEN RefreshDefs.EraseAndSave[menu]; ForAllMenuItems [menu, FindWidest]; ChangeMenuWidth[menu, width]; IF menu.visible THEN RefreshDefs.EraseAndSave[menu]; END; SelectOnly: PUBLIC MenuProc = BEGIN ForAllMenuItems[item.menu, Deselect]; Select[item]; END; Select: PUBLIC MenuProc = BEGIN item.selected _ TRUE; ClearMenuItem[item] END; Deselect: PUBLIC MenuProc = BEGIN IF item.selected THEN BEGIN item.selected _ FALSE; ClearMenuItem[item]; END; END; HighlightMenuItem: PUBLIC MenuProc = BEGIN wasInverted: BOOLEAN = item.inverted; item.inverted _ ~ item.selected; IF item.menu.visible AND wasInverted # item.inverted THEN ObjectDefs.ReplotBoxFromObject[item.tl, item.br, item.menu, NIL]; END; ClearMenuItem: PUBLIC MenuProc = BEGIN wasInverted: BOOLEAN = item.inverted; item.inverted _ item.selected; IF item.menu.visible AND wasInverted # item.inverted THEN ObjectDefs.ReplotBoxFromObject[item.tl, item.br, item.menu, NIL]; END; --called early on, right after the Controller initialization InitMenuStyle: PUBLIC PROCEDURE = BEGIN OPEN GriffinFontDefs; [] _ ControllerDefs.AppendFont[menuFont]; --adds the font and makes it current menuStyle _ CZone.NEW[StyleDefs.Style]; menuStyle^ _ ControllerDefs.CurrentStyle[]^; --includes current font menuStyle.color _ [0,0,128]; -- 50% grey menuStyle.fillcolor _ [0,0,128]; menuStyle.backgndcolor _ [0,0,128]; menuStyle.anchor _ center; menuStyle.orientation _ or0; menuHeight _ PointDefs.ObjValToScrVal[GriffinFontDefs.MaxHeight[menuFont]] + menuTopMargin-1; menuBaseLine _ GriffinFontDefs.MaxPosExtent[menuFont]; END; END. Êÿ˜JšéÏc‰œÏk œ žœžœžœ#žœ žœžœXžœžœžœ"žœ žœžœ"žœžœnžœžœžœžœ žœžœ+žœžœ žœžœžœ žœžœžœžœžœžœžœ)žœ9žœcžœžœZžœÏn œžœž œžœžœžœ žœŸ œžœž œ<žœžœžœžœ%œ žœžœIžœ!žœ žœžœ žœžœžœžœžœžœ žœžœžœžœ žœžœžœ žœžœžœ4žœžœžœžœŸ œž œ žœžœžœžœžœžœužœŸ œžœž œžœžœžœ8žœžœžœžœžœ žœžœžœ žœžœžœ žœžœžœžœžœ žœžœžœžœžœ œžœžœžœžœžœ žœ žœ žœžœžœžœ žœžœ žœžœžœžœžœžœ žœžœžœ žœ$žœžœ žœ žœ žœ žœžœžœžœžœžœžœžœ$žœ žœžœžœžœžœžœžœ!žœ žœŸœž œžœžœžœ$žœ žœ žœ žœžœžœžœ.žœ žœžœžœ!žœŸ œžœž œž œžœžœ#žœžœžœžœ žœžœžœžœŸœžœž œ'žœžœ žœžœ žœžœžœžœŸœžœž œ-žœÂžœ œžœ žœžœžœ9 œžœžœžœ žœ3œžœ žœžœ žœ3œžœ žœžœ žœižœŸœžœž œžœžœ!žœŸœžœž œžœžœ"žœÐbnœž œ1žœ-žœ#žœ žœ žœžœ žœžœžœ#žœžœ žœœžœžœ žœœ­Ïiªžœžœ-žœŸ œžœž œžœžœžœŸ œž œžœžœžœžœžœžœžœžœžœžœžœžœžœžœžœžœžœžœ žœžœžœžœžœ žœžœžœžœ žœžœ žœžœžœžœœ)žœŸ œžœž œ/žœžœžœžœžœžœ žœ žœžœžœžœ žœ žœžœžœžœžœžœžœžœŸœžœž œžœžœœŸ œžœž œžœžœžœ žœŸ œžœž œžœžœžœžœžœŸ œžœž œžœžœžœžœžœŸœžœž œžœžœžœ žœ žœ žœ žœžœœŸ œžœž œ žœžœ&žœžœžœžœ žœ žœžœžœcžœžœ!žœÏb œžœ žœ5žœ¢œžœ žœžœžœ¢œžœ žœžœžœžœžœžœžœ¢œžœ žœžœ3žœžœ žœ=žœžœ¢ œžœ žœžœ1žœžœ žœ=žœžœ=Ÿ œžœž œžœžœ<%œžœ@œ œ’žœžœ˜‡M—…—&Š-