don@BRILLIG.UMD.EDU (Don Hopkins) (08/28/88)
%! %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Class PulloutPieMenu % Copyright (C) 1988 by Don Hopkins (don@brillig.umd.edu) % % This program is provided free for unrestricted use and redistribution, % provided that the headers remain intact. No author or distributor % accepts any responsibility for any problems with this software. % % PulloutPieMenu is a subclass of PieMenu that uses cursor distance % from the menu center to specify an argument to the menu selection. % Each menu key has an array of possible arguments, from which the % cursor distance selects the argument value. The values in the % arrays are "Things" (cf. litemenu.ps & colordemo) that are painted % in the menu center as feedback. The /new method of class % PulloutPieMenu takes the same arguments that regular menus do, plus % an additional array of argument arrays. Each argument array % corresponds to a menu key. If you give just one argument array, it % is used for all the keys, the same as with the array of actions. % You can use getmenuarg and getmenuargindex in your menu actions to % retrieve the argument displayed when the key was selected. % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% systemdict begin % ------------------------------------ % % PulloutPieMenu /PulloutPieMenu PieMenu dictbegin /SliceWedges false def /HiLiteWithArrow? false def /PrinterMatch? false def /ArgBorder 2 def /EraseArgs? true def /MenuArgs null def /MenuArg null def /MenuArgIndex null def /PaintedArg null def dictend classbegin % [[args...]...] [keys...] [actions...] => menu /new { /new super send begin dup length MenuKeys length lt { [ exch aload pop % pad out args w/ last arg counttomark MenuKeys length exch sub {dup} repeat ] } if /MenuArgs exch def currentdict end } def % Need to make flipstype a no-op because /new takes a different number % of args! /flipstyle {currentdict} def /MenuGSave { /MenuGSave super send PrinterMatch? setprintermatch } def /DragProc { ChildMenu null eq { MenuGSave PieRadius dup translate CurrentEvent begin XLocation DeltaX add YLocation DeltaY add end SetMenuValue MenuValue PaintedValue ne { PaintMenuValue } if getmenuarg /PaintedArg load ne { PaintMenuArg } if grestore } if } def framebuffer /GLCanvas known { % SGI 4Sight? % Paint menus on the overlay plane /DamageProc { /damaged currentcanvas def dup getcanvaslocation 2 index setcanvas clipcanvaspath neg neg translate damaged setcanvas clipcanvas ParentMenu null ne {/DamageProc ParentMenu send} {pop} ifelse /paint self send true PaintedValue PaintSlice /PaintedArg load /PaintArg self send } def } { /DamageProc { MenuGSave damagepath clipcanvas /paint self send PaintedValue PaintSlice /PaintedArg load PaintArg newpath clipcanvas grestore } def } ifelse /PaintMenuArg { getmenuarg dup null eq /PaintedArg load null eq EraseArgs? or or { /PaintedArg load EraseArg } if dup PaintArg /PaintedArg exch store } def /EraseArg { % thing => - MenuGSave dup null eq { pop PieRadius dup translate MenuFillColor setcolor 0 0 LabelRadius Gap sub 3 sub 0 360 arc fill } { PieRadius dup translate MenuFillColor setcolor ThingSize 2 copy -.5 mul exch -.5 mul exch 4 -2 roll ArgBorder neg 5 1 roll insetrect % Some extra padding... rectpath fill } ifelse grestore } def /PaintArg { % thing => - MenuGSave dup null eq { pop PieRadius dup translate MenuBorderColor setcolor MenuLineWidth setlinewidth MenuLineCap setlinecap MenuItems { begin gsave newpath ang PieSliceWidth 2 div sub rotate NumbRadius 0 moveto LabelRadius Gap sub 4 sub 0 lineto MenuBorderColor setcolor stroke grestore end } forall } { PieRadius dup translate MenuTextColor setcolor dup ThingSize -.5 mul exch -.5 mul exch ShowThing } ifelse grestore } def /showat { PaintedArg null ne PaintedValue null ne and MenuCanvas null ne and MenuWidth null ne and { MenuGSave /PaintedArg load EraseArg /PaintedArg null store null PaintArg grestore } if /MenuArg null def /MenuArgIndex null def /showat super send } def /SetMenuValue { % x y => - /SetMenuValue super send /MenuArg MenuValue null eq {null true} {MenuArgs MenuValue get dup length 0 eq} ifelse { pop null /MenuArgIndex null def } { PieDistance PieRadius 1 sub min NumbRadius sub PieRadius NumbRadius sub div 1 index length mul floor /MenuArgIndex 1 index def get } ifelse def } def /getmenuargindex { % - => index MenuArgIndex } def /getmenuarg { % - => Thing /MenuArg load } def classend def end % systemdict
don@BRILLIG.UMD.EDU (Don Hopkins) (03/13/89)
You'll need the following class definition to run the Pseudo-Scientific Visualizer. The CyberSpace deck uses pullout pie menus if they're defined. You can select the "util... molecule" menu item over an object in CyberSpace, to view it with the visualizer. (I'll integrate them better later!) (PS: softmenu.ps doesn't wort work with pullout menus yet...) -Don %! %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Class PulloutPieMenu % Copyright (C) 1988 by Don Hopkins (don@brillig.umd.edu) % % This program is provided free for unrestricted use and redistribution, % provided that the headers remain intact. No author or distributor % accepts any responsibility for any problems with this software. % % PulloutPieMenu is a subclass of PieMenu that uses cursor distance % from the menu center to specify an argument to the menu selection. % Each menu key has an array of possible arguments, from which the % cursor distance selects the argument value. The values in the % arrays are "Things" (cf. litemenu.ps & colordemo) that are painted % in the menu center as feedback. The /new method of class % PulloutPieMenu takes the same arguments that regular menus do, plus % an additional array of argument arrays. Each argument array % corresponds to a menu key. If you give just one argument array, it % is used for all the keys, the same as with the array of actions. % You can use getmenuarg and getmenuargindex in your menu actions to % retrieve the argument displayed when the key was selected. % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% systemdict begin % ------------------------------------ % % PulloutPieMenu /PulloutPieMenu PieMenu dictbegin /SliceWedges false def /HiLiteWithArrow? false def /PrinterMatch? false def /ArgBorder 2 def /EraseArgs? true def /MenuArgs null def /MenuArg null def /MenuArgIndex null def /PaintedArg null def dictend classbegin % [[args...]...] [keys...] [actions...] => menu /new { /new super send begin dup length MenuKeys length lt { [ exch aload pop % pad out args w/ last arg counttomark MenuKeys length exch sub {dup} repeat ] } if /MenuArgs exch def currentdict end } def % Need to make flipstyle a no-op because /new takes a different number % of args, and actions might depend on MenuArg! Scratch that. % Instead, let's just make a new instance of ourselves, of % the same class. /flipstyle { 0 1 MenuActions length 1 sub { dup getmenuaction % fixed to use getmenuaction! dup type /dicttype eq { /flipstyle exch send % i menu' MenuActions 3 1 roll put % - } {pop pop} ifelse } for MenuArgs MenuKeys MenuActions /new ClassName load send dup /LabelMinRadius LabelMinRadius put % hack } def /MenuGSave { /MenuGSave super send PrinterMatch? setprintermatch } def /DragProc { ChildMenu null eq { MenuGSave PieRadius dup translate CurrentEvent begin XLocation DeltaX add YLocation DeltaY add end SetMenuValue MenuValue PaintedValue ne { PaintMenuValue } if getmenuarg /PaintedArg load ne { PaintMenuArg } if grestore } if } def framebuffer /GLCanvas known { % SGI 4Sight? % Paint menus on the overlay plane /paint { /paint super send /PaintedArg load /PaintArg self send } def } { /DamageProc { MenuGSave damagepath clipcanvas /paint self send PaintedValue PaintSlice /PaintedArg load PaintArg newpath clipcanvas grestore } def } ifelse /PaintMenuArg { getmenuarg dup null eq /PaintedArg load null eq EraseArgs? or or { % The null...pop is to get around the fact that 4Sight's ThingSize % recognizes [(string) /name] as a special case, and eats both, % which hoses us if we call it with just a /name, but with a % (string) on the stack before that. null /PaintedArg load EraseArg pop } if dup PaintArg /PaintedArg exch store } def /EraseArg { % thing => - MenuGSave dup null eq { pop PieRadius dup translate MenuFillColor setcolor 0 0 LabelRadius Gap sub 3 sub 0 360 arc fill } { PieRadius dup translate MenuFillColor setcolor % dup /toggle3 eq {/foo dbgbreak} if ThingSize 2 copy -.5 mul exch -.5 mul exch 4 -2 roll ArgBorder neg 5 1 roll insetrect % Some extra padding... rectpath fill } ifelse grestore } def /PaintArg { % thing => - MenuGSave dup null eq { pop PieRadius dup translate MenuBorderColor setcolor MenuLineWidth setlinewidth MenuLineCap setlinecap MenuItems { begin gsave newpath ang PieSliceWidth 2 div sub rotate NumbRadius 0 moveto LabelRadius Gap sub 4 sub 0 lineto MenuBorderColor setcolor stroke grestore end } forall } { PieRadius dup translate MenuTextColor setcolor dup ThingSize -.5 mul exch -.5 mul exch ShowThing } ifelse grestore } def /showat { PaintedArg null ne PaintedValue null ne and MenuCanvas null ne and MenuWidth null ne and { MenuGSave /PaintedArg load EraseArg /PaintedArg null store null PaintArg grestore } if /MenuArg null def /MenuArgIndex null def /showat super send } def /SetMenuValue { % x y => - /SetMenuValue super send /MenuArg MenuValue null eq {null true} {MenuArgs MenuValue get dup length 0 eq} ifelse { pop null /MenuArgIndex null def } { PieDistance PieRadius 1 sub min NumbRadius sub PieRadius NumbRadius sub div 1 index length mul floor /MenuArgIndex 1 index def get } ifelse def } def /getmenuargindex { % - => index MenuArgIndex } def /getmenuarg { % - => Thing /MenuArg load } def classend def end % systemdict