DIRECTORY Basics USING [bitsPerWord], ColorWorld, Cursors, Graphics, InputFocus, Interminal, PopUpMenu USING [], PrincOps USING [BBptr, BitAddress, BBTableSpace], PrincOpsUtils USING [AlignedBBTable, BITBLT], Real USING [FixC], Rope USING [ROPE], RuntimeError, Terminal, TerminalExtras, TIPUser, UserProfile, VFonts, ViewerClasses, ViewerLocks, ViewerSpecs USING [screenH, screenW]; PopUpMenuImpl: CEDAR MONITOR IMPORTS PrincOpsUtils, ColorWorld, Cursors, Graphics, InputFocus, Interminal, Real, RuntimeError, Terminal, TerminalExtras, TIPUser, UserProfile, VFonts, ViewerLocks EXPORTS PopUpMenu = BEGIN localTipTable: Rope.ROPE = "PopUp.tip"; remoteTipTable: Rope.ROPE = "/Indigo/Chipndale/PopUpMenu5.1/PopUp.tip"; RopeList: TYPE = LIST OF Rope.ROPE; mSaved: REF; -- pointer to save area bits mHeight: INTEGER; -- menu height in mLines mWidthPixels: INTEGER; -- menu width in pixels mWidthBits: INTEGER; -- menu width in bits mX, mY: INTEGER; -- menu position mContext: Graphics.Context; -- menu context font: Graphics.FontRef _ NIL; fontHeight: INTEGER; -- in mLines lineHeight: INTEGER; blackBorderThick: INTEGER = 2; whiteBorderThick: INTEGER = 2; borderThick: INTEGER = blackBorderThick+whiteBorderThick; gSelection: CARDINAL _ 0; titleLines: CARDINAL; gLabel: Rope.ROPE; choiceList: RopeList; gDefault: CARDINAL; onColorScreen: BOOLEAN; screen: PrincOps.BitAddress; virtual: Terminal.Virtual; bitsPerPixel: CARDINAL; scWidthPixels: CARDINAL; -- Screen width in pixels scWidthBits: CARDINAL; -- Screen width in bits scWidthWords: CARDINAL; scHeight: CARDINAL; -- Screen height in pixels screenPoint: PrincOps.BitAddress; saveTable, restoreTable: PrincOps.BBTableSpace; saveBLT, restoreBLT: PrincOps.BBptr; myTipTable: TIPUser.TIPTable; menuOn: BOOL _ FALSE; -- monitored access only allDone: BOOL _ TRUE; -- monitored access only checkAllDone: CONDITION; InitFontGlobals: ENTRY UserProfile.ProfileChangedProc --PROC [reason: ProfileChangeReason]-- = BEGIN ENABLE UNWIND => NULL; ymin, ymax: REAL; vFont: VFonts.Font; lineHeightX: INT; IF menuOn THEN RETURN; lineHeightX _ MAX[-whiteBorderThick, MIN[20, UserProfile.Number[key: "PopUpMenu.LineHeightChange", default: 0]] ]; vFont_ VFonts.EstablishFont[ family: UserProfile.Token[key: "PopUpMenu.FontFamily", default: "Helvetica"], size: UserProfile.Number[key: "PopUpMenu.FontSize", default: 10], bold: UserProfile.Boolean[key: "PopUpMenu.FontBold", default: FALSE], italic: UserProfile.Boolean[key: "PopUpMenu.FontItalic", default: FALSE], defaultOnFailure: TRUE ]; font _ VFonts.GraphicsFont[vFont]; [ymin: ymin, ymax: ymax] _ Graphics.FontBox[font]; fontHeight _ Real.FixC[ymax-ymin+0.1]; --Round lineHeight _ fontHeight+whiteBorderThick+lineHeightX; END; InitTipTable: PROC [] = BEGIN tryAgain: BOOL_FALSE; myTipTable _ TIPUser.InstantiateNewTIPTable[localTipTable ! RuntimeError.UNCAUGHT => {tryAgain_TRUE; CONTINUE} ]; IF tryAgain THEN myTipTable _ TIPUser.InstantiateNewTIPTable[remoteTipTable]; END; HideCursor: PROC [onColor: BOOL] = INLINE BEGIN IF onColor THEN TerminalExtras.LockColorFrame[virtual]; END; RestoreCursor: PROC [onColor: BOOL] = INLINE BEGIN IF onColor THEN TerminalExtras.UnlockColorFrame[virtual] END; RequestSelection: PUBLIC PROC [ label: Rope.ROPE _ NIL, choice: LIST OF Rope.ROPE, default: CARDINAL _ 0] RETURNS [CARDINAL] = BEGIN ENABLE UNWIND => NULL; selection: CARDINAL; LockedRequestSelection: ENTRY PROCEDURE = BEGIN SmallMouseMovement: INTERNAL PROC [] = TRUSTED INLINE BEGIN m: Interminal.MousePosition; m _ Interminal.GetMousePosition[]; IF m.mouseY>0 THEN m.mouseY _ m.mouseY-1 ELSE m.mouseY _ m.mouseY+1; Interminal.SetMousePosition[m] END; virtual _ Terminal.Current[]; gDefault _ default; gLabel _ label; choiceList _ choice; allDone _ FALSE; menuOn _ FALSE; SmallMouseMovement[]; Cursors.SetCursor[menu]; WHILE NOT allDone DO WAIT checkAllDone; ENDLOOP; menuOn _ FALSE; selection _ gSelection; END; --of LockedRequestSelection InputFocus.CaptureButtons[PopUpNotify, myTipTable]; InputFocus.PushInputFocus[]; ViewerLocks.CallUnderViewerTreeLock[LockedRequestSelection]; InputFocus.PopInputFocus[]; InputFocus.ReleaseButtons[]; RETURN [selection] END; --of RequestSelection PopUpNotify: ENTRY ViewerClasses.NotifyProc = BEGIN ENABLE UNWIND => NULL; SetUpScreen: INTERNAL PROC [menuMousePos: TIPUser.TIPScreenCoords] = BEGIN PrepareMenu: INTERNAL PROC [onColor: BOOLEAN] = BEGIN AllocateBitmap: INTERNAL PROC [nWords: CARDINAL] RETURNS [REF] = INLINE BEGIN Words: TYPE = RECORD[SEQUENCE COMPUTED CARDINAL OF CARDINAL]; RETURN[NEW[Words[nWords]]]; END; ComputedSize: INTERNAL PROC[gLabel: Rope.ROPE, choiceList: RopeList] RETURNS [lines: CARDINAL_0, width: CARDINAL_0] = INLINE BEGIN IF gLabel#NIL THEN { lines_1; width _ Real.FixC[Graphics.RopeWidth[font, gLabel].xw+0.1]; }; titleLines _ lines; FOR l: RopeList _ choiceList, l.rest WHILE l#NIL DO lines_lines+1; width _ MAX[width, Real.FixC[Graphics.RopeWidth[font, l.first].xw+0.1]]; ENDLOOP END; -- of ComputedSize SetUpBW: INTERNAL PROC[] = BEGIN onColorScreen _ FALSE; TRUSTED{screen _ Terminal.GetBitBltTable[virtual].bbt.dst}; bitsPerPixel _ 1; scWidthPixels _ ViewerSpecs.screenW; scHeight _ ViewerSpecs.screenH; mContext _ Graphics.NewContext[NIL]; END; -- of SetUpBW SetUpColor: INTERNAL PROC[] = INLINE BEGIN m: Terminal.ColorMode = Terminal.GetColorMode[virtual]; IF m.full THEN { --sorry we do not know what to do SetUpBW[] } ELSE IF m.bitsPerPixelChannelA#0 THEN { onColorScreen _ TRUE; scWidthPixels _ virtual.colorWidth; --??????????? scHeight _ virtual.colorHeight; mContext _ ColorWorld.NewContext[]; bitsPerPixel_m.bitsPerPixelChannelA; screen.word _ virtual.colorBitmapA; screen.reserved _ 0; screen.bit _ 0; } ELSE --ERROR, but what do? -- SetUpBW[]; END; -- of SetUpColor mLines: CARDINAL; -- textlines of menu including header mWidthWords: CARDINAL; -- menu words per line [lines: mLines, width: mWidthPixels] _ ComputedSize[gLabel, choiceList]; mWidthPixels _ mWidthPixels + 2*borderThick; mHeight _ mLines*lineHeight + 2*borderThick; IF onColor THEN SetUpColor[] ELSE SetUpBW[]; scWidthBits _ scWidthPixels*bitsPerPixel; scWidthWords _ (scWidthBits+Basics.bitsPerWord-1)/Basics.bitsPerWord; mWidthBits _ mWidthPixels*bitsPerPixel; mWidthWords _ (mWidthBits+Basics.bitsPerWord-1)/Basics.bitsPerWord; mSaved _ AllocateBitmap[mWidthWords*mHeight]; TRUSTED { restoreBLT.dstBpl _ saveBLT.srcDesc.srcBpl _ scWidthBits; saveBLT.dst _ [LOOPHOLE[mSaved],,0]; saveBLT.dstBpl _ mWidthWords*Basics.bitsPerWord; saveBLT.width_ restoreBLT.width _ mWidthBits; saveBLT.height _ restoreBLT.height _ mHeight; restoreBLT.src _ [LOOPHOLE[mSaved],,0]; restoreBLT.srcDesc.srcBpl _ mWidthWords*Basics.bitsPerWord; }; END; -- of PrepareMenu PaintMenu: INTERNAL PROC[] = BEGIN titelAddHight: CARDINAL = 3; baseLine: CARDINAL = 4; cH: CARDINAL _ mHeight-borderThick+baseLine; Graphics.ClipBox[mContext, [mX, scHeight-mY-mHeight, mX+mWidthPixels, scHeight-mY]]; Graphics.Translate[mContext, mX, scHeight-mY-mHeight]; Graphics.SetColor[mContext, Graphics.white]; Graphics.DrawBox[mContext, [0, 0, mWidthPixels, mHeight]]; Graphics.SetColor[mContext, Graphics.black]; Graphics.DrawBox[mContext, [0, 0, mWidthPixels, blackBorderThick]]; Graphics.DrawBox[mContext, [0, 0, blackBorderThick, mHeight]]; Graphics.DrawBox[mContext, [0, mHeight-blackBorderThick, mWidthPixels, mHeight]]; Graphics.DrawBox[mContext, [mWidthPixels-blackBorderThick, 0, mWidthPixels, mHeight]]; IF gLabel#NIL THEN {cH_cH-lineHeight; Graphics.SetCP[mContext, borderThick, cH+titelAddHight]; Graphics.DrawRope[self: mContext, rope: gLabel, font: font]; }; FOR l: RopeList _ choiceList, l.rest WHILE l#NIL DO cH_cH-lineHeight; Graphics.SetCP[mContext, borderThick, cH]; Graphics.DrawRope[self: mContext, rope: l.first, font: font]; ENDLOOP; [] _ Graphics.SetPaintMode[mContext, invert]; IF titleLines=1 THEN Graphics.DrawBox[mContext, [blackBorderThick, mHeight-borderThick-lineHeight+1, mWidthPixels-blackBorderThick, mHeight-blackBorderThick]] END; -- of PaintMenu ComputeScreenPoint: INTERNAL PROC = TRUSTED INLINE BEGIN screenPoint.word _ screen.word + (LONG[mY]*scWidthWords) + ((LONG[mX]*bitsPerPixel)/Basics.bitsPerWord); screenPoint.bit _ (mX*bitsPerPixel) MOD Basics.bitsPerWord; END; BLTScreenToSaveArea: INTERNAL PROC = TRUSTED INLINE BEGIN saveBLT.src _ screenPoint; PrincOpsUtils.BITBLT[saveBLT]; END; gSelection _ 0; PrepareMenu[menuMousePos.color]; mX _ MIN[MAX[0, menuMousePos.mouseX], scWidthPixels-mWidthPixels]; mY _ MIN[MAX[0, scHeight-menuMousePos.mouseY], scHeight-mHeight]; ComputeScreenPoint[]; HideCursor[onColorScreen]; BLTScreenToSaveArea[]; PaintMenu[]; RestoreCursor[onColorScreen]; END; -- of SetUpScreen RestoreScreen: INTERNAL PROC = BEGIN BLTSavedToScreen: INTERNAL PROC = TRUSTED INLINE BEGIN restoreBLT.dst _ screenPoint; PrincOpsUtils.BITBLT[restoreBLT]; END; HideCursor[onColorScreen]; BLTSavedToScreen[]; RestoreCursor[onColorScreen]; mSaved _ NIL; END; -- of RestoreScreen SetDefaultPosition: INTERNAL PROC [] = TRUSTED INLINE BEGIN m: Interminal.MousePosition; IF gDefault=0 THEN RETURN; m _ Interminal.GetMousePosition[]; -- reads color m.mouseX _ mX+mWidthPixels/2; m.mouseY _ -- scHeight- -- ((gDefault-(1-titleLines))*lineHeight+mY+lineHeight/2); Interminal.SetMousePosition[m]; END; MoveCursor: INTERNAL PROC [mousePos: TIPUser.TIPScreenCoords] = INLINE BEGIN InvertPictureLine: INTERNAL PROC [pos: CARDINAL] = BEGIN cH: CARDINAL = mHeight-borderThick-lineHeight*pos; Graphics.DrawBox[mContext, [borderThick, cH, mWidthPixels-borderThick, cH+lineHeight]]; END; sel: CARDINAL; screenX, screenY: INTEGER; screenX _ mousePos.mouseX; screenY _ scHeight-mousePos.mouseY; IF mousePos.color # onColorScreen THEN sel_0 ELSE IF screenX<=(mX+blackBorderThick) OR screenX>=(mX+mWidthPixels-blackBorderThick) THEN sel_0 ELSE IF screenY<=(mY+borderThick) OR (screenY>=mY+mHeight-borderThick) THEN sel_0 ELSE sel _ (1-titleLines)+(screenY-borderThick-mY)/lineHeight; IF gSelection#sel THEN BEGIN IF gSelection#0 THEN InvertPictureLine[gSelection+titleLines]; gSelection _ sel; IF gSelection#0 THEN InvertPictureLine[gSelection+titleLines]; END; END; -- of MoveCursor IF allDone THEN {NOTIFY checkAllDone; RETURN}; FOR list: LIST OF REF ANY _ input, list.rest WHILE list#NIL DO WITH list.first SELECT FROM m: TIPUser.TIPScreenCoords => IF menuOn THEN MoveCursor[m] ELSE {menuOn _ TRUE; SetUpScreen[m]; SetDefaultPosition[]}; x: ATOM => SELECT x FROM $Hit => {RestoreScreen[]; allDone_TRUE; NOTIFY checkAllDone}; ENDCASE => NULL; ENDCASE => NULL; ENDLOOP; END; --of PopUpNotify TRUSTED BEGIN saveBLT _ PrincOpsUtils.AlignedBBTable[@saveTable]; restoreBLT _ PrincOpsUtils.AlignedBBTable[@restoreTable]; saveBLT.flags.disjoint _ TRUE; saveBLT.flags.disjointItems _ TRUE; restoreBLT.flags.disjoint _ TRUE; restoreBLT.flags.disjointItems _ TRUE; END; UserProfile.CallWhenProfileChanges[InitFontGlobals]; InitTipTable[]; END. ô--OldPopUpMenuImpl.mesa; --by Christian Jacobi --Some code copied from "Magnifier" of McGregor --Last Edited by: Christian Jacobi, November 9, 1983 12:14 pm -- work on black and white, 4bit and 8bit color mode. --global variables are protected with MONITOR --do not catch errors again; land in debugger --entry because global variables used --fakes a small movement of the mouse, such that --the tiptable-process signalizes an event --LockedRequestSelection --RequestSelection --computes lines and width (in pixels) of menu and save area --PrepareMenu --SetUpScreen --RestoreScreen --sets the cursor such that it points into the default field --use Interminal to do this: uses current intead of buffered mouseposition --MoveCursor --PopUpNotify Ê ˜Jšœ™Jšœ™Jšœ/™/Jšœ=™=J˜Jšœ5™5J˜šÏk ˜ Jšœ˜J˜ J˜J˜ J˜ J˜ Jšœ œ˜Jšœ œ#˜1Jšœœœ˜-Jšœœ˜Jšœœœ˜J˜ J˜ Jšœ˜J˜J˜ Jšœ˜Jšœ˜J˜ Jšœ œ˜%J˜—Jšœœ˜J˜šœ˜Jšœ˜—Jšœ ˜Jšœ˜J˜Jšœœ˜'Jšœœ.˜GJ˜Jš œ œœœœ˜#J˜J™Jšœ-™-J˜JšœœÏc˜*J˜Jšœ œž˜*Jšœœž˜.Jšœ œž˜*Jšœœž˜!Jšœž˜,J˜Jšœœ˜Jšœ œž ˜!Jšœ œ˜J˜Jšœœ˜Jšœœ˜Jšœ œ%˜9J˜Jšœ œ˜Jšœ œ˜Jšœ œ˜J˜Jšœ œ˜J˜Jšœœ˜J˜Jšœ˜J˜Jšœœ˜Jšœœž˜3Jšœ œž˜.Jšœœ˜Jšœ œž˜.Jšœ!˜!J˜Jšœ/˜/Jšœ$˜$J˜J˜J˜Jšœœœž˜/Jšœ œœž˜.Jšœ œ˜J˜šÏnœœ"œ#˜_š˜Jšœœœ˜—Jšœ œ˜Jšœ˜Jšœ œ˜Jšœœœ˜šœ-˜-JšœB˜BJšœ˜—šœ˜JšœN˜NJšœB˜BJšœE˜EJšœI˜IJšœ˜Jšœ˜—Jšœ#˜#J˜2Jšœ'ž˜.Jšœ5˜5Jšœ˜—J˜šŸ œœ˜Jš˜Jšœ œœ˜šœ<˜J˜QJ˜Všœœ˜˜J˜8Jšœ<˜šœ˜Jš˜Jšœœ*˜>J˜Jšœœ*˜>Jšœ˜—Jšœž˜J˜—Jšœ ™ Jšœ œœœ˜.šœœœœœœœ˜>šœ œ˜˜Jšœœ˜Jšœ œ(˜;—šœœ˜ šœ˜ Jšœ"œœ˜=Jšœœ˜——Jšœœ˜—Jšœ˜—Jšœž˜J˜—J˜šœ˜ Jšœ3˜3Jšœ9˜9Jšœœ˜Jšœœ˜#Jšœœ˜!Jšœ!˜&—Jšœ˜Jšœ4˜4J˜Jšœ˜J˜—…—*Þ;S