home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 22 gnu / 22-gnu.zip / gwm18a.zip / data / mwm-menus.gwm < prev    next >
Lisp/Scheme  |  1995-07-03  |  32KB  |  1,183 lines

  1. ;;File: std-popups.gwm -- 
  2. ;;Author: colas@mirsa.inria.fr (Colas NAHABOO) -- Bull Research FRANCE
  3. ;;Author: Frederic CHARTON
  4. ;;Revision: 1.0 -- Sep 12 1989
  5. ;;State: Exp
  6. ;;GWM Version: 1.4
  7.  
  8.  
  9. ; Pop-ups
  10. ; =======
  11.  
  12. (defname 'pop-item-font screen. menuFontList)
  13. (defname 'pop-item-height screen. 18)
  14. (defname 'pop-label-font screen. menuFontList)
  15.  
  16.  
  17. (with (font menuFontList) (: item-height (+ 4 (height "A"))))
  18.  
  19. ; Offset for cascading menus :
  20. (: menu.offset.x 8)
  21. (: menu.offset.y -4)
  22.  
  23. (: menu-right-arrow 
  24.  (with (
  25.     borderwidth 0
  26.     fsm ()
  27.        )
  28.   (plug-make
  29.    (pixmap-make menuBackground "right-arrow" menuForeground)
  30.   )
  31.  )
  32. )
  33.  
  34.  
  35. ; Left and right plugs for items (-> 3D look)
  36. (de border-plug-make (top h)
  37.     (with ( foreground (if top menuTopShadowColor menuBottomShadowColor)
  38.         fsm ()
  39.         borderwidth 0
  40.           )
  41.     (plug-make (pixmap-make 2 h) )
  42.     )
  43. )
  44.  
  45. (: border-plug-right (border-plug-make () item-height))
  46. (: border-plug-left  (border-plug-make t item-height))
  47.  
  48. (: corner-plug (with (borderwidth 0 fsm ())
  49.         (plug-make (pixmap-make menuTopShadowColor 
  50.             "cornerPlug" menuBottomShadowColor) ) ))
  51.  
  52.  
  53. (: top-bar-menu 
  54.   (with (fsm () borderwidth 0 background menuTopShadowColor
  55.       bar-min-width 2
  56.       bar-max-width 2)
  57.      (bar-make () corner-plug)
  58.   )
  59. )
  60.  
  61. (: bottom-bar-menu 
  62.   (with (fsm () borderwidth 0 background menuBottomShadowColor
  63.       bar-min-width 2
  64.       bar-max-width 2)
  65.      (bar-make corner-plug ())
  66.   )
  67. )
  68.  
  69. ;-------------------------------------------------------------------------
  70.  
  71.  
  72. ; MENU.MAKE : args = list of items obtained by item-make or pop-label-make
  73. ; =========
  74. (df menu.make args
  75.  (with (
  76.     borderwidth 0
  77.     menu ()
  78.     cursor menu-cursor
  79.     myMenu (eval (+ '(menu-make) 
  80.             (+ 
  81.                 '(top-bar-menu) 
  82.                 '(blank-item-separator)
  83.                 args 
  84.                 '(blank-item-separator)
  85.                 '(bottom-bar-menu))))
  86.        )
  87.    (send-user-event 'make-opened-tile (menu-wob myMenu))
  88.  myMenu
  89.  )
  90. )
  91.  
  92.  
  93. ;-------------------------------------------------------------------------
  94. ; MENU.MOVE : places the menu inside the screen
  95. ; =========
  96. (de menu.move (theMenu x y)
  97.  (with (theMenuWob (menu-wob theMenu)
  98.     w (width theMenuWob)
  99.     h (height theMenuWob)
  100.        )
  101.   (if (> (+ y h) screen-height)
  102.           (: y (- screen-height h)))
  103.   (if (> (+ x w) screen-width)
  104.           (: x (- screen-width w)))
  105.   (move-window theMenuWob x y)
  106.  )
  107. )
  108.  
  109.  
  110.  
  111. ;-------------------------------------------------------------------------
  112.  
  113. ; MENU.POP : "pop" of a menu : args = (menu-to-pop button-to-use <'here>)
  114. ; ========
  115. (de menu.pop args
  116.   (with (menu-to-pop (if args (# 0 args) wob-menu) 
  117.       window-of-menu window)
  118.     (if (# 1 args) (: button-menu (# 1 args)))
  119.     (send-user-event 'update-items (menu-wob menu-to-pop))
  120.     (send-user-event 'activate-menu (menu-wob menu-to-pop))
  121.     (## 'current-valid-item (menu-wob menu-to-pop) 0)
  122.     (if (> (current-event-code) 5)
  123.       (send-user-event 'select-item (# 0 (# 'valid-items
  124.         (menu-wob menu-to-pop)))))
  125.     (## 'menu-son wob (menu-wob menu-to-pop))
  126.     (## 'already-popped (menu-wob menu-to-pop) t)
  127.     (## 'father (menu-wob menu-to-pop) wob)
  128.     (setq popping-window window)
  129.     (with (grab-keyboard-also t)
  130.       (if (member 'here args)
  131.     (pop-menu menu-to-pop 'here)
  132.     (pop-menu menu-to-pop)
  133.     ))
  134.     (send-user-event 'set-grabs (menu-wob menu-to-pop))
  135. ))
  136.  
  137. ;-------------------------------------------------------------------------
  138.  
  139.  
  140. ; Borders plugs of item separators
  141. (: separator-plug-left
  142.     (with (
  143.         fsm ()
  144.         borderwidth 0 
  145.         foreground menuBackground
  146.         plug-tile (pixmap-make 4 3)
  147.         foreground menuTopShadowColor
  148.           )
  149.     (draw-line plug-tile 0 0 0 2)
  150.     (draw-line plug-tile 1 0 1 2)
  151.     (plug-make plug-tile)
  152.     )
  153. )
  154. (: separator-plug-right
  155.     (with (
  156.         fsm ()
  157.         borderwidth 0
  158.         foreground menuBackground
  159.         plug-tile (pixmap-make 4 3)
  160.         foreground menuBottomShadowColor
  161.           )
  162.     (draw-line plug-tile 2 0 2 2)
  163.     (draw-line plug-tile 3 0 3 2)
  164.     (plug-make plug-tile)
  165.     )
  166. )
  167.  
  168. ; Blank item separator (space between two consecutive items)
  169. (: blank-item-separator
  170.    (with (fsm () borderwidth 0
  171.       background menuBackground
  172.           bar-min-width 3 )
  173.      (bar-make separator-plug-left () separator-plug-right )
  174.    )
  175. )
  176.  
  177. ; Item separator (line between two consecutive items)
  178. (: item-separator
  179.    (with (fsm () borderwidth 0
  180.       tile (pixmap-make menuBackground "itemSep" menuForeground)
  181.           bar-min-width 3 background menuBottomShadowColor)
  182.      (bar-make separator-plug-left () separator-plug-right )
  183.    )
  184. )
  185.  
  186.  
  187.  
  188. ;-------------------------------------------------------------------------
  189.  
  190. ; VARIOUS UTILITIES :
  191. ; =-=-=-=-=-=-=-=-=
  192.  
  193. ; Good button checking :
  194. (df check-button ()
  195.  (= button-menu (current-event-code))
  196. )
  197.  
  198.  
  199. (df valid-items eventual-wob
  200.  (if eventual-wob 
  201.   (with (wob (eval (# 0 eventual-wob)))
  202.    (# 'valid-items wob)
  203.   )
  204.    (# 'valid-items wob)
  205.  )
  206. )
  207.  
  208. (df set-valid-items args
  209. (with (item-nb (eval (# 0 args)) eventual-wob (eval (# 1 args)))
  210.  (if eventual-wob 
  211.   (with (wob (eval eventual-wob))
  212.    (## 'valid-items wob item-nb)
  213.   )
  214.    (## 'valid-items wob item-nb)
  215.  )
  216. )
  217. )
  218.  
  219. (df nb-valid-items ()
  220.   (length (# 'valid-items wob))
  221. )
  222.  
  223. (df current-valid-item eventual-wob
  224.  (if eventual-wob 
  225.   (with (wob (eval (# 0 eventual-wob)))
  226.    (# 'current-valid-item wob)
  227.   )
  228.    (# 'current-valid-item wob)
  229.  )
  230. )
  231.  
  232. (de set-current-valid-item (item-nb)
  233.   (## 'current-valid-item wob item-nb)
  234. )
  235.  
  236. ; Is the action "f.menu" ?
  237. (df action-is-f.menu ()
  238.  (= 'f.menu (# 0 (# 'action wob)))
  239. )
  240.  
  241. (df menu-wob-of-action ()
  242.  (menu-wob (eval (# 1 (# 'action wob))))
  243. )
  244.  
  245. (df menu-of-action ()
  246.  (eval (# 1 (# 'action wob)))
  247. )
  248.  
  249.  
  250. ; The oldest menu father of the menu
  251. (de menu-oldest-father (theWob)
  252.  (with (father (or (# 'father theWob) root-window))
  253.   (if (with (wob father) (= 'menu wob-status)) 
  254.    (menu-oldest-father father)
  255.    theWob
  256.   )
  257.  )
  258. )
  259.  
  260. ; The oldest father of the menu to grab
  261. (de oldest-father-for-grab (theWob)
  262.  (with (father (or (# 'father theWob) root-window))
  263.   (if (with (wob father) (= 'menu wob-status)) 
  264.    (menu-oldest-father father)
  265.    (if (# 'is-button-menu father) father theWob)
  266.   )
  267.  )
  268. )
  269.  
  270.  
  271. ; Setting of the current item :
  272. (df fix-current-item ()
  273.  (with (i 0 listOfValidItems (valid-items wob-parent) 
  274.         current-item (# i listOfValidItems))
  275.   (while current-item
  276.    (if (= wob current-item) 
  277.     (progn
  278.      (with (wob wob-parent) 
  279.     (## 'current-valid-item wob i)
  280.      )
  281.      (: current-item ())
  282.     )
  283.     (progn
  284.      (: i (+ i 1))
  285.      (: current-item (# i listOfValidItems))
  286.     )
  287.    )
  288.   )
  289.  )
  290. )
  291.  
  292. (: menus-basic-state
  293.  (state-make
  294.  (on (user-event 'select-item)
  295.    (wob-tile (# 'opened-tile wob)))
  296.   (on (user-event 'goto-opened) () opened)
  297.   (on (user-event 'goto-activable) () activable)
  298.   (on (user-event 'depop) (: wob-background menuBackground) activable)
  299.   (on (user-event 'unselect-item)
  300.          (progn
  301.                  (with (wob wob-parent)
  302.                  (if (# 'item-menu-son wob)
  303.                          (send-user-event 'depop (# 'menu-son wob)))
  304.                  )
  305.                  (: wob-background menuBackground)
  306.          )
  307.   )
  308.   (on (user-event 'test-item-menu-popped)
  309.    (if (action-is-f.menu)
  310.      (: in-item-menu-popped
  311.          (and (> cerx 0)
  312.               (> cery 0)
  313.               (< cerx wob-width)
  314.               (< cery wob-height)
  315.          )
  316.      )
  317.    )
  318.   )
  319.  )
  320. )
  321.  
  322. ;-------------------------------------------------------------------------
  323.  
  324.  
  325.  
  326. ; ========================================================================
  327. ; ITEMS' FSM : 4 states : activable / non-activable / closed / opened
  328. ; ========================================================================
  329.  
  330. (setq menus.fsm  
  331. (fsm-make 
  332. ;-----------------------------------------------------------ACTIVABLE
  333. (: activable
  334. (state-make
  335.  (on (buttonpress any any) 
  336.     (if (check-button)
  337.      (progn
  338.        (if (# (current-valid-item  wob-parent) (valid-items  wob-parent))
  339.        (send-user-event 
  340.         'unselect-item
  341.         (# (current-valid-item  wob-parent) (valid-items  wob-parent))
  342.         )
  343.      )
  344.     (if (action-is-f.menu)
  345.          (if (# 'already-popped wob)
  346.           (progn
  347.            (send-user-event 'unselect-item
  348.                 (# (current-valid-item  (menu-wob-of-action))
  349.                        (valid-items  (menu-wob-of-action))) 
  350.        )
  351.           )
  352.           (progn
  353.        (with (theWob wob wob wob-parent)
  354.             (## 'item-menu-son wob theWob)
  355.        )
  356.        (menu.move (menu-of-action) (- (+ wob-x wob-width) menu.offset.x) 
  357.                        (+ wob-y menu.offset.y))
  358.            (with (theMenu (menu-of-action) wob wob-parent) 
  359.         (menu.pop theMenu button-menu 'here))
  360.           )
  361.          )
  362.         )
  363.     (wob-tile (# 'opened-tile wob))
  364.     (send-user-event 'activate-menu (menu-oldest-father wob-parent))
  365.     (send-user-event 'goto-opened wob) 
  366.      )
  367.     )
  368.  )
  369.  (on (user-event 'update-items)
  370.    (if (not 
  371.         (with (condition (# 'enable-condition wob )
  372.            wob window-of-menu)
  373.     (eval condition))
  374.        )
  375.     (send-user-event 'disable-item wob) 
  376.     (set-valid-items (+ (valid-items wob-parent) (list wob)) wob-parent)
  377.    ) 
  378.  )
  379.  (on (user-event 'disable-item) () non-activable)
  380.  (on (user-event 'activate-menu) 
  381.   (if (= wob (# (current-valid-item wob-parent) (valid-items wob-parent)))
  382.     (if (or (not (action-is-f.menu)) 
  383.             (not (= wob (with (wob wob-parent) (# 'item-menu-son wob)))))
  384.          (: wob-background menuBackground) 
  385.     )
  386.   )
  387.  closed)
  388.  (on (user-event 'make-opened-tile) 
  389.     (## 'opened-tile wob (item-tile.make wob-width wob-height))
  390.  )
  391.  
  392.  menus-basic-state
  393. )
  394. )
  395. ;-----------------------------------------------------------NON-ACTIVABLE
  396. (: non-activable
  397.     (state-make
  398.      (on (buttonpress any any) 
  399.        (if (check-button) 
  400.         (send-user-event 'activate-menu (menu-oldest-father wob-parent))
  401.        )
  402.      )
  403.      (on (buttonrelease any any) 
  404.        (if (check-button) 
  405.            (send-user-event 'depop (menu-oldest-father wob-parent))
  406.        )
  407.      )
  408.      (on (user-event 'update-items)
  409.        (if 
  410.          (with  (condition (# 'enable-condition wob)
  411.              wob window-of-menu)
  412.            (eval condition))
  413.            (progn
  414.              (send-user-event 'enable-item wob) 
  415.              (set-valid-items (+ (valid-items wob-parent) (list wob)) 
  416.               wob-parent)
  417.            ) 
  418.        ) 
  419.      )
  420.      (on (user-event 'enable-item) () activable)
  421.     )
  422. )
  423. ;-----------------------------------------------------------CLOSED
  424. (: closed 
  425.    (state-make 
  426.    (on enter-window 
  427.     (progn
  428.      (: wob-tile (# 'opened-tile wob))
  429.      (if (action-is-f.menu)
  430.       (if (not (# 'already-popped wob))
  431.           (progn
  432.        (with (theWob wob theMenu (menu-wob-of-action) wob wob-parent)
  433.         (## 'item-menu-son wob theWob)
  434.        )
  435.        (menu.move (menu-of-action) (- (+ wob-x wob-width) menu.offset.x) 
  436.                        (+ wob-y menu.offset.y))
  437.            (with (theMenu (menu-of-action) wob wob-parent) 
  438.         (menu.pop theMenu button-menu 'here))
  439.        (fix-current-item)
  440.           )
  441.       )
  442.      )
  443.     )
  444.    opened)
  445.  
  446.    menus-basic-state
  447.   )
  448. )
  449. ;-----------------------------------------------------------OPENED
  450. (: opened
  451.    (state-make
  452.    (on (buttonpress any any)
  453.     (if (and (check-button) (action-is-f.menu))
  454.      (send-user-event 'activate-menu  (menu-oldest-father wob-parent))
  455.     )
  456.    )
  457.    (on (buttonrelease any any)
  458.     (if (check-button)
  459.      (if (action-is-f.menu)
  460.       (progn
  461.        (fix-current-item)
  462.        (with (wob  (menu-wob-of-action))
  463.         (## 'current-valid-item wob 0))
  464.        (with (theWob (oldest-father-for-grab wob-parent))
  465.     (if (# 'is-button-menu theWob) 
  466.      (send-user-event 'button-release theWob))
  467.        )
  468.        (send-user-event 'goto-activable  (menu-oldest-father wob-parent))
  469.        (send-user-event 'select-item 
  470.     (# 0 (valid-items  (menu-wob-of-action))) )
  471.       )
  472.       (progn
  473.        (setq std-popups.action (# 'action wob))
  474.        (send-user-event 'goto-activable (menu-oldest-father wob-parent))
  475.        (send-user-event 'depop (menu-oldest-father wob-parent))
  476.        (: wob-background menuBackground)
  477.        (wob wob-parent)
  478.        (wob (# 'father wob))
  479.        (with (window popping-window action-by-menu t) (eval std-popups.action))
  480.       )
  481.      ) 
  482.     )
  483.    )
  484.    (on leave-window
  485.     (if (action-is-f.menu)
  486.      (with (cerx (current-event-relative-x) 
  487.         cery (current-event-relative-y))
  488.       (if (not
  489.           (and (> cerx 0)
  490.                (> cery 0)
  491.                (< cerx wob-width)
  492.                (< cery wob-height)
  493.           ) )
  494.     (with (cex (current-event-x) cey (current-event-y)
  495.         in-menu-son ())
  496.     (send-user-event 'in-menu-son-test (menu-wob-of-action))
  497.     (if (not in-menu-son)
  498.          (progn
  499.           (: wob-background menuBackground )
  500.           (send-user-event 'goto-activable  (menu-wob-of-action))
  501.           (send-user-event 'unselect-item
  502.                 (# (current-valid-item  (menu-wob-of-action))
  503.                           (valid-items  (menu-wob-of-action))))
  504.           (send-user-event 'depop  (menu-wob-of-action))
  505.       (send-user-event 'goto-closed wob)
  506.          )
  507.         )
  508.     )
  509.      )
  510.      )
  511.      (progn
  512.       (: wob-background menuBackground )
  513.       (send-user-event 'goto-closed wob)
  514.      )
  515.     )
  516.    )
  517.    (on (user-event 'goto-closed) () closed)
  518.    (on (user-event 'unselect-item) (: wob-background menuBackground))
  519.    menus-basic-state
  520.   )
  521.  )
  522. )
  523. )
  524.  
  525.  
  526. ;-------------------------------------------------------------------------
  527.  
  528.  
  529. ; MNEMO-LABEL-MAKE : making of a label with is underlined mnemonic
  530. ; ================   or of the pixmap designed by the file "@file" .
  531. (de mnemo-label-make (label mnemo)
  532. (if (eq 0 (member "@" label))
  533.  (with ( pixmapFile (match "@\\(.*\\)" label 1))
  534.   (pixmap-make menuBackground pixmapFile menuForeground)
  535.  )
  536.  (if mnemo
  537.   (with (
  538.      foreground menuForeground
  539.      background menuBackground
  540.      before-mnemo (match (+ "\\(.*\\)" mnemo) label 1)
  541.      after-mnemo (match (+ "\\(.*" mnemo "\\)") label 1)
  542.      font menuFontList
  543.      x1 (if (and before-mnemo
  544.              (not (= before-mnemo "")))
  545.         (- (width before-mnemo) label-horizontal-margin) 
  546.           label-horizontal-margin)
  547.      x2 (- (width after-mnemo) label-horizontal-margin)
  548.      y (- item-height 6)
  549.         )
  550.    ;(? before-mnemo "!!" after-mnemo  "!!" x1 "!!" x2 "\n")
  551.    (draw-line (label-make label) (- x1 1) y (- x2 2) y)
  552.   )
  553.   (with (
  554.      foreground menuForeground
  555.      background menuBackground
  556.      font menuFontList
  557.     )
  558.    (label-make label)
  559.   )
  560.  )
  561. )
  562. )
  563.  
  564.  
  565. ;-------------------------------------------------------------------------
  566.  
  567.  
  568. ; ITEM-TILE.MAKE : making of the selected framework of an item
  569. ; ==============
  570. (de item-tile.make (w h)
  571.  (with (
  572.     foreground menuBackground
  573.     item-tile (pixmap-make (+ w (* 2 plug-separator)) h)
  574.     item-xmax (- w 5)
  575.     item-ymax (- h 1)
  576.        )
  577.  (with (foreground menuTopShadowColor)
  578.     (draw-line item-tile 4 0 item-xmax 0         )
  579.     (draw-line item-tile 4 1 item-xmax 1         )
  580.     (draw-line item-tile 4 0 4         item-ymax)
  581.     (draw-line item-tile 5 0 5         item-ymax)
  582.  )
  583.  (with (foreground menuBottomShadowColor)
  584.     (draw-line item-tile 4               item-ymax        item-xmax       item-ymax      )
  585.     (draw-line item-tile 5               (- item-ymax 1)  item-xmax       (- item-ymax 1))
  586.     (draw-line item-tile item-xmax       0                item-xmax       item-ymax      )
  587.     (draw-line item-tile (- item-xmax 1) 1                (- item-xmax 1) item-ymax      )
  588.  )
  589.  item-tile
  590.  )
  591. )
  592.  
  593.  
  594. ;-------------------------------------------------------------------------
  595.  
  596.  
  597. ; ITEM-MAKE  : 
  598. ; =========
  599. ; args : (label mnemonic action enable-condition blank-plug accelerator)
  600. (df item-make args
  601.     (with (
  602.        label (+ (# 0 args) "") ; assure que 'label' est une string
  603.        label-is-bitmap (eq 0 (member "@" label))
  604.        mnemo (# 1 args) action (# 2 args)
  605.        blank-plug (# 4 args) accelerator (# 5 args)
  606.            property (+ 
  607.                '(opened-tile ())
  608.                (list 'enable-condition (if (> (length args) 3) (# 3 args) t))
  609.                (list 'action action) 
  610.                (list 'mnemonic mnemo)
  611.                '(already-popped  ())
  612.             )
  613.        borderwidth 0
  614.        enable-pixmap (mnemo-label-make   label mnemo)
  615.        bar-min-width (+ 
  616.                (if label-is-bitmap 8 4)
  617.                (height enable-pixmap))
  618.        plug-separator 4
  619.        fsm menus.fsm
  620.        background menuBackground
  621.       )
  622.       (bar-make
  623.           (if label-is-bitmap (border-plug-make t bar-min-width)
  624.         border-plug-left)
  625.           (with (borderwidth 0 font pop-item-font
  626.                    menuForeground ; Dynamic binding hack--boo hiss
  627.                      (if shadeDisabled
  628.                          menuShadeColor
  629.                          menuForeground)
  630.                    background menuBackground
  631.              disable-pixmap (mnemo-label-make label mnemo)
  632.              property (list 'item-label label 'mnemo mnemo
  633.                     'enable-pixmap  enable-pixmap
  634.                     'disable-pixmap
  635.                              (if shadeDisabled disable-pixmap
  636.                               (with (foreground menuForeground)
  637.                     (draw-line disable-pixmap
  638.                            0 (/ (height disable-pixmap) 2) 
  639.                            (width disable-pixmap)
  640.                            (/ (height disable-pixmap) 2))))
  641.                   )
  642.              fsm 
  643.             (fsm-make (state-make 
  644.              (on (user-event 'enable-item) 
  645.                                  (: wob-tile (# 'enable-pixmap wob))
  646.              )
  647.              (on (user-event 'disable-item) 
  648.                                  (: wob-tile (# 'disable-pixmap wob))
  649.              )
  650.              )
  651.             ))
  652.             (plug-make enable-pixmap)
  653.         )
  654.           blank-plug 
  655.           (if (not (= (# 0 action) 'f.menu)) accelerator)
  656.           ()
  657.           (if (= (# 0 action) 'f.menu) menu-right-arrow)
  658.           (if label-is-bitmap (border-plug-make () bar-min-width) border-plug-right)
  659.   ) )
  660. )
  661.  
  662. ;-------------------------------------------------------------------------
  663.  
  664.  
  665. ; POP-LABEL-MAKE : making of the menu's title
  666. ; ==============
  667. (df pop-label-make (label)
  668.     (with (fsm ()
  669.        background menuBackground
  670.        foreground menuForeground
  671.        borderwidth 0
  672.        bar-min-width item-height bar-max-width item-height
  673.        plug-separator 4
  674.       ) 
  675.       (bar-make
  676.           border-plug-left
  677.           ()
  678.           (with (borderwidth 0 font pop-label-font 
  679.              background menuBackground foreground menuForeground) 
  680.             (plug-make (mnemo-label-make label ())))
  681.           ()
  682.           border-plug-right
  683.       )
  684.     )
  685. )
  686.  
  687.  
  688. ;-------------------------------------------------------------------------
  689.  
  690. (de youngest-son (theWob)
  691.  (with (wob theWob son (# 'menu-son wob))
  692.   (if son (youngest-son son) wob)
  693.  )
  694. )
  695.  
  696. (de propagate-key-event (user-evt-name)
  697.   (if (# 'menu-son wob) 
  698.    (send-user-event user-evt-name (youngest-son wob))
  699.    (send-user-event user-evt-name wob)
  700.   )
  701. )
  702.  
  703. ; UPDATE-GRAB : grabs the server with flag "grab-keyboard-also" to true
  704. ; ===========   on the menu oldest father of the wob, then grabs the server
  705. ;        on the oldest father with flag "grab-keyborad-also" to false.
  706. (de update-grab ()
  707.   (with (
  708.      o-father (oldest-father-for-grab wob)
  709.      m-o-father (menu-oldest-father wob)
  710.     )
  711.    (with (grab-keyboard-also t) (grab-server m-o-father))
  712.    (if (not (= o-father m-o-father)) (grab-server o-father))
  713.   )
  714. )
  715.  
  716.  
  717. ; MENUS' FSM :
  718. ; ==========
  719. (: pop-fsm 
  720.     (fsm-make 
  721.      (: pop-state (state-make 
  722.     (on enter-window
  723.     (progn 
  724.      (if (and (not (current-event-from-grab)) (# 'active wob))
  725.      (progn
  726.       (if (# 'menu-son wob)
  727.        (progn
  728.         (: in-item-menu-popped ())
  729.             (with (
  730.            cerx 
  731.            (current-event-relative-x)
  732.            cery 
  733.            (- (+ (current-event-relative-y) wob-y) 
  734.             (with (wob  (# 'item-menu-son wob)) wob-y))
  735.           )
  736.          (send-user-event 'test-item-menu-popped (# 'item-menu-son wob))
  737.         )
  738.         (if (not in-item-menu-popped)
  739.          (progn
  740.          (send-user-event 'goto-closed (# 'item-menu-son wob))
  741.          (send-user-event 'unselect-item (# 'item-menu-son wob))
  742.          ;(send-user-event 'depop (# 'menu-son wob))
  743.          )
  744.         )
  745.        )
  746.       )
  747.      )
  748.     ) )
  749.     )
  750.     (on (buttonpress any any) 
  751.       (if (check-button) 
  752.                (progn
  753.         (if (and double-click-required (= button-menu 1))
  754.          (progn 
  755.           (if (< (- (current-event-time) time-of-last-release) 
  756.              doubleClickTime)
  757.             (send-user-event 'double-click double-click-required)
  758.           )
  759.           (: double-click-required ())
  760.          )
  761.         )
  762.         (send-user-event 'activate-menu (menu-oldest-father wob))
  763.            )
  764.        )
  765.     )
  766.     (on (buttonrelease any any) 
  767.       (if (check-button) (send-user-event 'depop (menu-oldest-father wob))) )
  768.     (on (user-event 'depop) 
  769.      (progn
  770.       (if (# 'menu-son wob)
  771.        (send-user-event 'depop (# 'menu-son wob))
  772.       )
  773.       (update-grab)
  774.       (unpop-menu)
  775.       (with (father (or (# 'father wob) root-window))
  776.          (with (wob father)
  777.           (## 'already-popped wob ())
  778.           (## 'menu-son wob ())
  779.           (## 'item-menu-son wob ())
  780.          )
  781.          (send-user-event 'button-release father)
  782.          (with (wob father)
  783.           (if (not (= wob-status 'menu)) (ungrab-server))
  784.          )
  785.       )
  786.       (## 'menu-son wob ())
  787.       (## 'item-menu-son wob ())
  788.      )
  789.     )
  790.     (on (user-event 'activate-menu) 
  791.      (progn
  792.      (## 'active wob t)
  793.          (if (# 'menu-son wob)
  794.           (send-user-event 'activate-menu (# 'menu-son wob))
  795.      ) 
  796.      )
  797.     )
  798.     (on (user-event 'goto-activable) 
  799.      (progn
  800.      (## 'active wob ())
  801.          (if (# 'menu-son wob)
  802.           (send-user-event 'goto-activable (# 'menu-son wob))
  803.      ) 
  804.      )
  805.     )
  806.     (on (user-event 'update-items) (set-valid-items ()))
  807.     (on (user-event 'set-grabs) (update-grab))
  808.     (on (user-event 'in-menu-son-test)
  809.       (: in-menu-son (and (> cex wob-x) (> cey wob-y)
  810.                 (< cex (+ wob-x wob-width))
  811.                  (< cey (+ wob-y wob-height)))))
  812.  
  813.         ;--Keys Events :
  814.     ;--UP------------------------------------------------
  815.     (on (keypress (key-make "Up") alone) 
  816.      (propagate-key-event 'Up)
  817.     )
  818.     (on (user-event 'Up)
  819.      (if (valid-items)
  820.       (progn 
  821.        (send-user-event 'unselect-item (# (current-valid-item) (valid-items)))
  822.        (set-current-valid-item (% (- 
  823.          (if (> (current-valid-item) 0) (current-valid-item) (nb-valid-items))
  824.          1) (nb-valid-items))
  825.        )
  826.        (send-user-event 'select-item (# (current-valid-item) (valid-items)))
  827.       )
  828.      )
  829.     )
  830.     ;--DOWN----------------------------------------------
  831.     (on (keypress (key-make "Down") alone) 
  832.      (propagate-key-event 'Down)
  833.     )
  834.     (on (user-event 'Down)
  835.      (if (valid-items)
  836.       (progn 
  837.        (send-user-event 'unselect-item (# (current-valid-item) (valid-items)))
  838.        (set-current-valid-item (% (+ (current-valid-item) 1) (nb-valid-items)))
  839.        (send-user-event 'select-item (# (current-valid-item) (valid-items)))
  840.       )
  841.      )
  842.     )
  843.     ;--RIGHT---------------------------------------------
  844.     (on (keypress (key-make "Right") alone) 
  845.      (propagate-key-event 'Right)
  846.     )
  847.     (on (user-event 'Right)
  848.      (with (wob  (# (current-valid-item) (valid-items)))
  849.       (if (action-is-f.menu)
  850.        (with (theMenu (menu-wob-of-action))
  851.            (with (theWob wob wob wob-parent)
  852.             (## 'item-menu-son wob theWob)
  853.            )
  854.        (menu.move (menu-of-action) (- (+ wob-x wob-width) menu.offset.x) 
  855.                        (+ wob-y menu.offset.y))
  856.            (with (theMenu (menu-of-action) wob wob-parent) 
  857.         (menu.pop theMenu button-menu 'here))
  858.            (send-user-event 'goto-activable  theMenu)
  859.            (send-user-event 'select-item (# 0 (valid-items  theMenu)) )
  860.        )
  861.       )
  862.      )
  863.     )
  864.     ;--LEFT----------------------------------------------
  865.     (on (keypress (key-make "Left") alone) 
  866.      (propagate-key-event 'Left)
  867.     )
  868.     (on (user-event 'Left)
  869.      (if (not (= wob (menu-oldest-father wob)))
  870.       (progn
  871.           (send-user-event 'goto-activable  wob)
  872.           (send-user-event 'depop wob)
  873.       (update-grab)
  874.       )
  875.      )
  876.     )
  877.     (on (keypress (key-make "Return") alone) 
  878.      (propagate-key-event 'Return)
  879.     )
  880.     ;--RETURN--------------------------------------------
  881.     (on (user-event 'Return)
  882.      (if (valid-items)
  883.       (if (with (wob (# (current-valid-item) (valid-items)) )
  884.            (action-is-f.menu) )
  885.            (with (wob  (# (current-valid-item) (valid-items)))
  886.             (if (action-is-f.menu)
  887.              (with (theMenu (menu-wob-of-action))
  888.              (with (theWob wob wob wob-parent)
  889.               (## 'item-menu-son wob theWob)
  890.              )
  891.        (menu.move (menu-of-action) (- (+ wob-x wob-width) menu.offset.x) 
  892.                        (+ wob-y menu.offset.y))
  893.            (with (theMenu (menu-of-action) wob wob-parent) 
  894.         (menu.pop theMenu button-menu 'here))
  895.              (send-user-event 'goto-activable  theMenu)
  896.              (send-user-event 'select-item (# 0 (valid-items  theMenu)) )
  897.              )
  898.             )
  899.           )
  900.       (progn 
  901.        (send-user-event 'unselect-item (# (current-valid-item) (valid-items)))
  902.        (with (wob (# (current-valid-item) (valid-items)))
  903.             (setq std-popups.action (# 'action wob))
  904.             (send-user-event 'depop (menu-oldest-father wob-parent))
  905.             (: wob-background menuBackground)
  906.             (wob wob-parent)
  907.             (wob (# 'father wob))
  908.             (with (action-by-menu t) (eval std-popups.action))
  909.             (send-user-event 'goto-activable wob)
  910.        )
  911.       )
  912.       )
  913.      )
  914.     )
  915.     ;--ESCAPE--------------------------------------------
  916.     (on (keypress (key-make "Escape") alone) 
  917.      (propagate-key-event 'Escape)
  918.     )
  919.     (on (user-event 'Escape)
  920.      (if (valid-items)
  921.        (with (wob (# (current-valid-item) (valid-items)))
  922.         (send-user-event 'unselect-item wob)
  923.             (send-user-event 'depop (menu-oldest-father wob-parent))
  924.        )
  925.      )
  926.     )
  927.     ;--ANY KEY-------------------------------------------
  928.     (on (keypress any any)
  929.      (with (cec (current-event-code) cem (current-event-modifier))
  930.       (send-user-event 'keypress-any-any (menu-oldest-father wob))
  931.      )
  932.     )
  933.     (on (user-event 'keypress-any-any)
  934.         (progn
  935.           (with (theKey cec
  936.                 theAcceleratorItem
  937.                 (# (atom (+ "key"
  938.                     (itoa
  939.                      (keycode-to-keysym theKey alone))
  940.                     "m" (itoa cem)))
  941.                    (# 'accelerator-list wob))
  942.                 theMnemonicItem 
  943.                 (# (atom (+ "key"
  944.                     (itoa
  945.                      (keycode-to-keysym theKey alone))))
  946.                    (# 'mnemonic-list wob))
  947.                 theItem
  948.                 (if theAcceleratorItem theAcceleratorItem
  949.                   theMnemonicItem)
  950.                 enable (# 0 theItem)
  951.                 action (# 1 theItem)
  952.                 )
  953.         (if theItem
  954.             (if (eval enable)
  955.             (progn
  956.               (send-user-event 'Escape wob)
  957.               (wob (# 'father wob))
  958.               (with (action-by-menu t) (eval action))
  959.               (send-user-event 'goto-activable wob)
  960.               )
  961.               )
  962.           (if (# 'menu-son wob) 
  963.               (send-user-event 'keypress-any-any (# 'menu-son wob))
  964.             )
  965.           )
  966.         )
  967.           )
  968.         )
  969.      )
  970.    )
  971.  )
  972. )
  973.  
  974.  
  975. ;-------------------------------------------------------------------------
  976.  
  977.  
  978. ; MK-BLANK-PLUG : making of a "blank" pixmap 
  979. ; =============
  980. (de mk-blank-plug (w)
  981.  (with (fsm () foreground menuBackground borderwidth 0)
  982.   (plug-make (pixmap-make (+ 1 w) 1))
  983.  )
  984. )
  985.  
  986.  
  987. ;-------------------------------------------------------------------------
  988.  
  989. ;*******************************
  990. (load "mwm-functions")
  991. ;*******************************
  992.  
  993. ;-------------------------------------------------------------------------
  994. (de modifier-string.make (theModifiers)
  995.  (with (theRes ""
  996.     i 0 l (length theModifiers)
  997.        )
  998.   (while (< i l)
  999.    (with (modifier (# i theModifiers))
  1000.    (: theRes (+ theRes
  1001.     (if (= modifier 'any) ""
  1002.         (= modifier 'alone) ""
  1003.         (= modifier 'with-alt) "Alt+"
  1004.         (= modifier 'with-shift) "Shift+"
  1005.         (= modifier 'with-control) "Ctrl+"
  1006.         (= modifier 'with-lock) "Lock+"
  1007.         (= modifier 'with-modifier-1) "Mod1+"
  1008.         (= modifier 'with-modifier-2) "Mod2+"
  1009.         (= modifier 'with-modifier-3) "Mod3+"
  1010.         (= modifier 'with-modifier-4) "Mod4+"
  1011.         (= modifier 'with-modifier-5) "Mod5+"
  1012.         (= modifier 'with-button-1) "But1+"
  1013.         (= modifier 'with-button-2) "But2+"
  1014.         (= modifier 'with-button-3) "But3+"
  1015.         (= modifier 'with-button-4) "But4+"
  1016.         (= modifier 'with-button-5) "But5+"
  1017.         ""
  1018.     )
  1019.    ))
  1020.    )
  1021.    (: i (+ i 1))
  1022.   )
  1023.  theRes
  1024.  )
  1025. )
  1026.  
  1027.  
  1028.  
  1029. ;============================================================================
  1030. ; MWM-MENU.MAKE
  1031. ;============================================================================
  1032. (df mwm-menu.make args
  1033.  (with 
  1034.   (state pop-state
  1035.    mnemonic-list ()
  1036.    accelerator-list ()
  1037.    wgrabs window-grabs
  1038.    wbeh ()
  1039.    args-for-menu.make ()
  1040.    max-width-label 0
  1041.    max-width-acc 0
  1042.   )
  1043.  (with (font menuFontList)
  1044.  (for item args
  1045.   (with (label (# 0 item)
  1046.      acc   (# 2 item))
  1047.    (if (eq 0 (member "@" label))
  1048.      (with ( pixmapFile (match "@\\(.*\\)" label 1))
  1049.       (: label (pixmap-make menuBackground pixmapFile menuForeground))
  1050.      )
  1051.    )
  1052.     (if label
  1053.     (if (> (width label) max-width-label) 
  1054.         (: max-width-label (width label))))
  1055.     ))
  1056.  )
  1057.  (for item args
  1058.   (with (
  1059.      label           (# 0 item)
  1060.      mnemo           (# 1 item)
  1061.      acc             (# 2 item)
  1062.      key            (# 0 acc)
  1063.      modifier       (# 1 acc)
  1064.      fctn            (# 3 item)
  1065.      fctn.name       (# 0 fctn)
  1066.      fctn.name.string (match "[.]\\(.*\\)" fctn.name 1)
  1067.      transition       ()
  1068.      acc-string
  1069.                (+ 
  1070.                (if (= 'atom (type modifier))
  1071.                       (modifier-string.make (list modifier))
  1072.                 (modifier-string.make (sublist 1 (length modifier)
  1073.                               modifier) )
  1074.                )
  1075.                    key)
  1076.     )
  1077.    (if (= fctn.name 'f.separator)
  1078.     (: args-for-menu.make (+ args-for-menu.make '(item-separator)))
  1079.        (= fctn.name 'f.title)
  1080.     (: args-for-menu.make (+ args-for-menu.make '(item-separator item-separator)
  1081.                   (list (list 'pop-label-make label))
  1082.                   '(item-separator item-separator) ))
  1083.     ; else
  1084.     (progn
  1085.      (: args-for-menu.make
  1086.       (+ args-for-menu.make
  1087.        (list (list
  1088.         'item-make
  1089.         label
  1090.         mnemo
  1091.         fctn (eval (atom (+ "e." fctn.name.string))) 
  1092.         (if acc (mk-blank-plug 
  1093.             (with (font menuFontList)
  1094.              (- max-width-label (width label)))))
  1095.         (if acc 
  1096.         (with (borderwidth 0
  1097.                fsm ()
  1098.                font menuFontList
  1099.                foreground menuForeground
  1100.                background menuBackground
  1101.               )
  1102.         (plug-make (active-label-make acc-string)))
  1103.         )
  1104.        ))
  1105.       )
  1106.      )
  1107.      (if (= fctn.name 'f.menu)
  1108.        (progn
  1109.        (: wgrabs (+ wgrabs 
  1110.          (with (wob (menu-wob (eval (# 1 fctn)))) (# 'wgrabs wob))))
  1111.        (: wbeh (state-make wbeh 
  1112.                 (with (wob (menu-wob (eval (# 1 fctn)))) (# 'wfsm wob))))
  1113.        )
  1114.      )
  1115.      (if acc
  1116.       (progn
  1117.       (: transition
  1118.         (list 'on (list 'keypress (key-make key) modifier)
  1119.           (list 'if (eval (atom (+ "e." fctn.name.string))) 
  1120.             (list 'with '(action-by-menu t) fctn))
  1121.           )
  1122.       )
  1123.       (: wgrabs (+ wgrabs (list (eval (list 'keypress (key-make key) modifier)))))
  1124.       (: wbeh   (eval (list 'state-make transition 'wbeh)))
  1125.       (## (atom (+ "key" (itoa (key-make 
  1126.          (if (# (atom key) to-lower-case-list)
  1127.          (# (atom key) to-lower-case-list) key
  1128.          )
  1129.           )) "m" (itoa (eval modifier))) )
  1130.        'accelerator-list 
  1131.          (list (eval (atom (+ "e." fctn.name.string))) fctn) )
  1132.       )
  1133.      )
  1134.      (if mnemo
  1135.          (with (key mnemo modifier with-alt)
  1136.            (## (atom (+ "key" (itoa (key-make (setq key
  1137.            (if (# (atom mnemo) to-lower-case-list)
  1138.               (# (atom mnemo) to-lower-case-list) mnemo)))))) 
  1139.            'mnemonic-list 
  1140.            (list (eval (atom (+ "e." fctn.name.string))) fctn) )
  1141.            (: transition
  1142.           (list 'on (list 'keypress (key-make key) modifier)
  1143.             (list 'if (eval (atom (+ "e." fctn.name.string))) 
  1144.                   (list 'with '(action-by-menu t) fctn))
  1145.             )
  1146.           )
  1147.            (: wgrabs
  1148.           (+ wgrabs (list (eval
  1149.                    (list 'keypress (key-make key) modifier)))))
  1150.            (: wbeh   (eval (list 'state-make transition 'wbeh)))
  1151.            (## (atom (+ "key" (itoa
  1152.                    (key-make 
  1153.                     (if (# (atom key) to-lower-case-list)
  1154.                     (# (atom key) to-lower-case-list) key)
  1155.                      )) "m" (itoa (eval modifier))) )
  1156.            'accelerator-list 
  1157.          (list (eval (atom (+ "e." fctn.name.string))) fctn) )
  1158.            ))
  1159.     )
  1160.    )
  1161.   )
  1162.  )
  1163.  (with (
  1164.     fsm (fsm-make state)
  1165.     property '(father () valid-items () menu-son () item-menu-son () active ()
  1166.            current-valid-item 0 wgrabs () wfsm () )
  1167.     property (+ (list 'mnemonic-list mnemonic-list
  1168.               'accelerator-list accelerator-list) property)
  1169.     myMenu (eval (+ '(menu.make) args-for-menu.make))
  1170.     wob (menu-wob myMenu)
  1171.        )
  1172.   (## 'wfsm wob wbeh)
  1173.   (## 'wgrabs wob wgrabs)
  1174.   myMenu
  1175.  )
  1176. ))
  1177.  
  1178.  
  1179.  
  1180.  
  1181. ;------------------------------------------------------------Fin----------
  1182.  
  1183.