(FILECREATED " 9-Jan-85 20:49:01" {PHYLUM}<LFG>PARSER>MENUPATCH.;1 9002 )
(* Copyright (c) 1985 by Xerox Corporation. All rights reserved.)
(PRETTYCOMPRINT MENUPATCHCOMS)
(RPAQQ MENUPATCHCOMS ((FNS MENU.HANDLER)))
(DEFINEQ
(MENU.HANDLER
[LAMBDA (MENU DSP KEEPCONTROLIFOUTFLG CHANGEOFFSETFLG NESTEDFLG)
(* rrb " 9-Jan-85 19:08")
(* handles details of watching mouse for menus.)
(RESETLST (RESETSAVE NIL (LIST (QUOTE \SMASHMENUIMAGEONRESET)
MENU))
(PROG (ITEM SUBITEMS SUBMENURESULT OLDBOXX OLDBOXY BOXX BOXY HELDSTATE
(MOUSEDOWN (LASTMOUSESTATE (NOT UP)))
(MOVEDLEFT "NESTED")
(LASTBUTTONSTATE LASTMOUSEBUTTONS)
(MGRIDSPEC (fetch (MENU MENUGRID) of MENU))
(HOLDTIMER (SETUPTIMER MENUHELDWAIT))
(HELDFN (fetch (MENU WHENHELDFN) of MENU))
(NROWS (fetch (MENU MENUROWS) of MENU))
(NCOLUMNS (fetch (MENU MENUCOLUMNS) of MENU)))
(COND
((AND MOUSEDOWN (STRICTLY/BETWEEN (SETQ BOXY (GRIDYCOORD (LASTMOUSEY DSP)
MGRIDSPEC))
-1 NROWS)
(STRICTLY/BETWEEN (SETQ BOXX (GRIDXCOORD (LASTMOUSEX DSP)
MGRIDSPEC))
-1 NCOLUMNS))
(* make a special check for when the last state was
down and save the information about which item that was
over.)
(\INVERTITEM (SETQ OLDBOXX BOXX)
(SETQ OLDBOXY BOXY)
MENU DSP)))
(RETURN (COND
([SETQ ITEM
(ERSETQ (until (COND
(MOUSEDOWN
(* if mouse has been down, process it)
(MOUSESTATE UP))
((MOUSESTATE (NOT UP))
(* mouse hasn't been down but just went down.)
[COND
((AND (NULL KEEPCONTROLIFOUTFLG)
(LASTMOUSESTATE RIGHT))
(DOWINDOWCOM (WHICHW LASTMOUSEX LASTMOUSEY)))
(T (SETQ MOUSEDOWN T)
(COND
(OLDBOXX
(* switch between boxing to flipping items.)
(\BOXITEM OLDBOXX OLDBOXY MENU
DSP)
(\INVERTITEM OLDBOXX OLDBOXY
MENU DSP]
NIL))
do (COND
[(AND (STRICTLY/BETWEEN (SETQ BOXY
(GRIDYCOORD (LASTMOUSEY
DSP)
MGRIDSPEC))
-1 NROWS)
(STRICTLY/BETWEEN (SETQ BOXX
(GRIDXCOORD (LASTMOUSEX
DSP)
MGRIDSPEC))
-1 NCOLUMNS))
(* BOXX and BOXY hold the number of the box pointed
at.)
(COND
((OR (NEQ BOXX OLDBOXX)
(NEQ BOXY OLDBOXY))
(* selected item has changed.)
(* uninvert old item if there was one.)
[COND
(OLDBOXX (COND
(MOUSEDOWN (\INVERTITEM OLDBOXX
OLDBOXY
MENU DSP)
)
(T (\BOXITEM OLDBOXX OLDBOXY
MENU DSP)))
(MENU.HELDSTATE.RESET OLDBOXX
OLDBOXY))
(T (SETQ HOLDTIMER (SETUPTIMER MENUHELDWAIT
HOLDTIMER]
(* invert new item)
(COND
(MOUSEDOWN (\INVERTITEM BOXX BOXY MENU DSP))
(T (\BOXITEM BOXX BOXY MENU DSP)))
(SETQ OLDBOXX BOXX)
(SETQ OLDBOXY BOXY))
((AND HELDFN (NULL HELDSTATE)
(TIMEREXPIRED? HOLDTIMER))
(* same button in same region for MENUHELDWAIT
milliseconds.)
(APPLY* HELDFN (GETMENUITEM MENU OLDBOXX
OLDBOXY)
MENU
(\FDECODE/BUTTON LASTBUTTONSTATE))
(SETQ HELDSTATE T]
(T (* cursor moved outside of the menu.)
(COND
(OLDBOXX (COND
((AND (IGREATERP BOXX 0)
(SETQ ITEM
(GETMENUITEM MENU OLDBOXX
OLDBOXY))
(SETQ SUBITEMS
(\MENUSUBITEMS MENU ITEM)))
(* There are subitems to be displayed)
(SETQ SUBMENURESULT
(MENU (NESTED.SUBMENU MENU
SUBITEMS)
(NESTED.SUBMENU.POS
MENU ITEM DSP)
NIL T))
(COND
((NEQ SUBMENURESULT MOVEDLEFT)
(* selected something from submenu)
(COND
(MOUSEDOWN (\INVERTITEM
OLDBOXX
OLDBOXY MENU
DSP))
(T (\BOXITEM OLDBOXX
OLDBOXY MENU
DSP)))
(MENU.HELDSTATE.RESET OLDBOXX
OLDBOXY)
(SETQ OLDBOXX)
(GO OUT)))
(SETQ SUBMENURESULT NIL)))
(COND
(MOUSEDOWN (\INVERTITEM OLDBOXX
OLDBOXY
MENU DSP))
(T (\BOXITEM OLDBOXX OLDBOXY MENU
DSP)))
(MENU.HELDSTATE.RESET OLDBOXX OLDBOXY)
(SETQ OLDBOXX)))
(* OLDBOXX denotes item inverted.)
(COND
((AND NESTEDFLG BOXX (IGREATERP 0 BOXX)
(ILESSP (LASTMOUSEX DSP)
0))
(* make sure the mouse has moved all the way out past the left including its border and outline size.
We know it has to be a pop up menu that will have 0 as its left edge.)
(* if this is a nested call and the user moved to the
left, return indication of this.)
(RETURN MOVEDLEFT))
((NOT KEEPCONTROLIFOUTFLG)
(RETURN)))
(SETQ OLDBOXX)))
(COND
((NEQ LASTBUTTONSTATE (SETQ LASTBUTTONSTATE
LASTMOUSEBUTTONS))
(* reset held timer)
(MENU.HELDSTATE.RESET OLDBOXX OLDBOXX)))
finally (* turn off inverse image. and call whenunheldfn is
necessary.)
OUT
(COND
(OLDBOXX (COND
(MOUSEDOWN (\INVERTITEM OLDBOXX
OLDBOXY
MENU DSP))
(T (\BOXITEM OLDBOXX OLDBOXY MENU
DSP)))
(MENU.HELDSTATE.RESET OLDBOXX OLDBOXY)
))
(* if called for, change the menu offset so the menu
will come up in the same place relative to the cursor
next time.)
[COND
((AND CHANGEOFFSETFLG OLDBOXX)
(SELECTQ (fetch (MENU CHANGEOFFSETFLG)
of MENU)
((Y NIL))
(replace (POSITION XCOORD)
of (fetch (MENU MENUOFFSET)
of MENU)
with (LASTMOUSEX DSP)))
(SELECTQ (fetch (MENU CHANGEOFFSETFLG)
of MENU)
((X NIL))
(replace (POSITION YCOORD)
of (fetch (MENU MENUOFFSET)
of MENU)
with (LASTMOUSEY DSP]
(RETURN (COND
(SUBMENURESULT)
(OLDBOXX (CONS (GETMENUITEM MENU
OLDBOXX
OLDBOXY)
(\FDECODE/BUTTON
LASTBUTTONSTATE]
(* no error)
(RETURN (CAR ITEM)))
(T (* user ↑E -
reset the menu selection.)
(* note -
this doesn't protect against ↑D. I would suggest that something be put on the reset list to clear the menu image in
the case of a ↑D.)
[COND
(OLDBOXX (COND
(MOUSEDOWN (\INVERTITEM OLDBOXX OLDBOXY MENU DSP))
(T (\BOXITEM OLDBOXX OLDBOXY MENU DSP]
(ERROR!])
)
(PUTPROPS MENUPATCH COPYRIGHT ("Xerox Corporation" 1985))
(DECLARE: DONTCOPY
(FILEMAP (NIL (230 8922 (MENU.HANDLER 240 . 8920)))))
STOP