[comp.windows.news] Disabled menu items

rudolf@neptune.uucp (Jim Rudolf) (03/03/89)

Has anyone hacked together something in NeWS that will allow disabled menu
items similar to what is common in Sunview?  What I mean is, have a particular
menu item or items in gray, as well as ignoring the event if a disabled menu
item is selected.  I would be most appreciative if someone has already figured
this out so I don't have to :-).

Thanks for any help you can give me.

  -- Jim Rudolf

BTW, I called Springer-Verlag on 2/28 to find out about The NeWS Book.
I've been waiting anxiously for a supplement to the NeWS Manual.  They told me
it's publication date had been delayed again, and that I should call back in
about 2 weeks...rats.

----------------------------------------------------------------------------
Internet: rudolf@oce.orst.edu                 "All opinions herein are mine" 
UUCP: {tektronix,hp-pcd}!orstcs!oce.orst.edu!rudolf
----------------------------------------------------------------------------

steve@jtsv16.jts.COM (steve rosenberg) (03/04/89)

>Has anyone hacked together something in NeWS that will allow disabled menu
>items similar to what is common in Sunview?  What I mean is, have a particular
>menu item or items in gray, as well as ignoring the event if a disabled menu
>item is selected.  I would be most appreciative if someone has already figured
>this out so I don't have to :-).

I think that the following file implements the feature that you are
looking for.  It has only been tested in mono on NeWS 1.1.  It does
the gray-out by "spraying" white pixels over the menu choice (bitmap
fonts can't be set to an intermediate shade of gray).  You will note
that the MenuFont has been set to 18 point Helvetica.  That seemed to
work best with the gray-out pattern used.  Change the font and you may
have to change the gray-out pattern.

You can disable/enable menu choices by sending the following messages
to your menu object:

	index -or- key /disable
	index -or- key /enable

This menu sub-class also does another interesting thing.  It provides
a click-or-drag feature so that if the user "clicks" the menu button
(i.e.  press and release without moving) the menu will pop-up and stay
up until a choice is made by clicking again.  The press-drag technique
can still be used.  The damping factor (amount of movement before drag
is assumed) can be adjusted by changing the class variable Damping.
Nervous hands need more.

Either place the following file in your user.ps or run it from there,
and redefine the default menu:

/DefaultMenu LitePRMenu+ store


%%% - cut here -
% litemenu enhancements for enable/disable and click-or-drag
%
/LitePRMenu+ LitePullRightMenu
dictbegin
    % enable/disable feature
    /Mf	false def			% flag (for mask proc)
    /Mw 0 def /Mh 0 def			% mask width and height
    /Ms1 nullstring def			% strings for gray-out image source
    /Ms2 nullstring def
    % click or drag
    /DownX 0 def
    /DownY 0 def
    /MenuClicked? false def		% true if this menu has been clicked
dictend
classbegin

    /Damping 4 def
    /MenuFont	 /Helvetica findfont 18 scalefont def

    % dimmed choice stuff
    /MaskStr1	20 string def
    /MaskStr2	20 string def
    0 1 19 {MaskStr1 exch 16#55 put} for
    0 1 19 {MaskStr2 exch 16#AA put} for

    /disable {				% index -or- key => -
	dup type /integertype eq not {
	    /searchkey self send pop
	} if
	% stack now => index
	MenuItems exch get			% => menuitems(dict)
	begin
	    /ok? false def
	end
    } def

    /enable {				% index -or- key => -
	dup type /integertype eq not {
	    /searchkey self send pop
	} if
	% stack now => index
	MenuItems exch get			% => menuitems(dict)
	begin
	    /ok? true def
	end
    } def

    /domenu {				% menu => -
	MenuValue null eq {
	    pop
	} {
	    /domenu super send
	} ifelse
    } def

    /layout {
	/layout super send
	MenuItems {
	    begin
		currentdict /ok? known not {
		    /ok? true def
		} if
	    end
	} forall
    } def

    /PaintMenuItems {
	MenuTextColor setcolor
	MenuItems {
	    begin
		X Y X Y W H ok? /Key load x y
	    end				% get the interesting stuff from the
	    % MenuItems dict
	    ShowThing % => X Y X Y W H ok?    (show this menu choice "thing")
	    { pop pop pop pop }		% this choice is enabled
	    {				% gray out this choice
		gsave			% => X Y X Y W H
		    2 copy			% => X Y X Y W H W H
		    /Mh exch def /Mw exch def
		    newpath rectpath clip	% clip area to be grayed
		    translate 0 0 moveto
		    Mw Mh scale
		    MaskStr1 0 Mw 8 div ceiling 1 sub getinterval /Ms1 exch def
		    MaskStr2 0 Mw 8 div ceiling 1 sub getinterval /Ms2 exch def
		    /Mf false def
		    1 setgray		% use white to do the gray-out
		    Mw Mh true [ Mw 0 0 Mh 0 0 ] {
			Mf {
			    /Mf false def Ms1
			} {
			    /Mf true def Ms2
			} ifelse
		    } imagemask		% spatter white over the thing
		grestore
	    } ifelse
	} forall
    } def


    /PaintMenuValue { % - => - (Highlights current item, un-hilighting prev.)
	MenuGSave
	PaintedValue PaintBox
	MenuValue dup null ne {
	    MenuItems exch get begin ok? end {
		MenuValue PaintBox
	    } {
		/MenuValue null store
	    } ifelse
	} {
	    pop
	} ifelse
	/PaintedValue MenuValue store
	grestore
    } def

    /showat {				% x y -or- event => -
	MenuClicked? not {		% only save loc if not yet clicked
	    dup type /eventtype eq {
		dup begin
		    framebuffer setcanvas
		    XLocation YLocation
		end % ... xloc yloc
	    } {
		2 copy			% ... xloc yloc
	    } ifelse
	    /DownY exch def
	    /DownX exch def
	    /showat super send		% only send to super if not clicked
	} if
    } def

    /DownProc {				% dummy proc to swallow down stroke
					% of click
    } def

    /UpProc {
	MenuClicked? not {		% only test for click/drag
					% if not yet done
	    framebuffer setcanvas
	    CurrentEvent begin
		XLocation YLocation
	    end
	    % see if mouse moved more
	    % than damping factor (dragged),
	    % or stayed relatively still (clicked)
	    dup				% => x y y
	    DownY Damping add le exch	% => x bool y
	    DownY Damping sub ge and exch	% => bool x
	    dup DownX Damping add le exch	% => bool bool x
	    DownX Damping sub ge and		% => bool bool
	    and {
		/MenuClicked? true def	% menu was clicked
	    } {
		/UpProc super send		% send up event if dragged
	    } ifelse
	} {
	    /UpProc super send
	} ifelse
    } def

    /makeinterests { % - => -
        /MenuInterests [
            ParentMenu null eq {
                MenuButton /UpProc UpTransition null eventmgrinterest
            } if
	    MouseDragged /DragProc  null MenuCanvas eventmgrinterest
	    MenuButton /DownProc DownTransition null eventmgrinterest
	    /EnterEvent /EnterProc null MenuCanvas eventmgrinterest
	    /ExitEvent /ExitProc null MenuCanvas eventmgrinterest
	    /Damaged /DamageProc null MenuCanvas eventmgrinterest
	] def
    } def

    /popdown {
	/MenuClicked? false def
	/popdown super send
    } def

classend
def


%% end of file

_________________________________________________________________________
Steve Rosenberg		  |	steve@jtsv16.jts.com
JTS Computer Systems Ltd. |	uunet!jtsv16!steve
Toronto +1 416 665 8910   |	...![sun|...]!suncan!jtsv16!steve  
__________________________|______________________________________________