(defextern |←XMenuCreate|(external string) external) (defextern |←XMenuAddPane|(external external fix) fix) (defextern |←XMenuAddSelection|(external fix t external fix) fix) (defextern |←XMenuInsertPane|(external fix external fix) fix) (defextern |←XMenuInsertSelection|(external fix fix t external fix) fix) ;(defextern |←XMenuFindPane|(external string) fix) ;(defextern |←XMenuFindSelection|(external fix string) fix) (defextern |←XMenuChangePane|(external fix external) fix) (defextern |←XMenuChangeSelection|(external fix fix t fix external fix) fix) (defextern |←XMenuSetPane|(external fix fix) fix) (defextern |←XMenuSetSelection|(external fix fix fix) fix) (defextern |←XMenuDeletePane|(external fix) fix) (defextern |←XMenuDeleteSelection|(external fix fix) fix) ;(defextern |←XMenuRecompute|(external) fix) ;(defextern |←XMenuEventHandler|(external) fix) (defextern |←XMenuLocate|(external fix fix fix fix t t t t) fix) ;(defextern |←XMenuSetFreeze|(external fix) fix) (defextern |←XMenuActivate|(external t t fix fix fix t) fix) (defextern |←XMenuDestroy|(external) fix) (setq #:sys-package:colon 'menu) (defstruct :x def ; liste de (string cstring et liste de (string cstring value)) (selection 0) (pane 0)) (unless (boundp ':x:all-menus) (defvar :x:all-menus ())) (de #:bitmap:x:create-menu (menu) (let ((newmenu (:x:make)) (extend (|←XMenuCreate| (|←rootwindow|) "lelisp"))) (:extend newmenu extend) (newl :x:all-menus newmenu) newmenu)) (de :x:kill-menu (menu) (mapc (lambda (l) (|←free| (caddr l)) (mapc (lambda (def) (|←free| (caddr def))) (cdddr l))) (:x:def menu)) (setq :x:all-menus (delq menu :x:all-menus)) (|←XMenuDestroy| (:extend menu))) (defvar :x:pane 0) (defvar :x:selection 0) (defvar :x:result 0) (defvar :x:x-menu) (defvar :x:y-menu) (defvar :x:w-menu) (defvar :x:h-menu) (de :x:activate-menu (menu x y) (setq :x:selection (:x:selection menu)) (setq :x:pane (:x:pane menu)) (|←XMenuLocate| (:extend menu) :x:pane :x:selection x y ':x:x-menu ':x:y-menu ':x:w-menu ':x:h-menu) (setq :x:x-menu (or (fixp :x:x-menu) (cdr (loc :x:x-menu)))) (setq :x:y-menu (or (fixp :x:y-menu) (cdr (loc :x:y-menu)))) (setq x (max (add1 (sub x :x:x-menu)) (min x (add (sub (bitxmax) :x:w-menu) (sub x :x:x-menu))))) (setq y (max (add1 (sub y :x:y-menu)) (min y (add (sub (bitymax) :x:h-menu) (sub y :x:y-menu))))) (cond ((eqn (|←XMenuActivate| (:extend menu) ':x:pane ':x:selection x y #$ffff ':x:result) 1) (:x:selection menu -1) (:x:pane menu :x:pane) menu :x:result) (t (:x:selection menu -1) (:x:pane menu 0) ()))) (de :x:menu-insert-item-list (menu choix name active) (setq name (string name)) (let ((cname (|←cstring| name (slen name)))) (or (and (eqn 0 choix) (neqn -1 (|←XMenuInsertPane| (:extend menu) choix cname active))) (|←XMenuAddPane| (:extend menu) cname active)) (:x:def menu (nconc (firstn choix (:x:def menu)) (ncons (list name active cname)) (nthcdr choix (:x:def menu)))))) (de :x:menu-insert-item (menu choix item name active value) (setq name (string name)) (let ((cname (|←cstring| name (slen name)))) (or (and (eqn 0 item) (neqn -1 (|←XMenuInsertSelection| (:extend menu) choix item value cname active))) (|←XMenuAddSelection| (:extend menu) choix value cname active)) (let ((ilist (nth choix (:x:def menu)))) (rplacd (cddr ilist) (nconc (firstn item (cdddr ilist)) (ncons (list name active cname value)) (nthcdr item (cdddr ilist))))))) (de :x:menu-delete-item-list (menu choix) (|←XMenuDeletePane| (:extend menu) choix) ; il manque un FREE des chaines C (:x:def menu (nconc (firstn choix (:x:def menu)) (nthcdr (add1 choix) (:x:def menu))))) (de :x:menu-delete-item (menu choix item) (|←XMenuDeleteSelection| (:extend menu) choix item) (let ((ilist (nth choix (:x:def menu)))) (rplacd (cddr ilist) (nconc (firstn item (cdddr ilist)) (nthcdr (add1 item) (cdddr ilist)))))) (de :x:menu-modify-item-list (menu choix name active) (when name (setq name (string name)) (let ((cname (|←cstring| name (slen name)))) (|←XMenuChangePane| (:extend menu) choix cname) (rplaca (nth choix (:x:def menu)) name) (rplaca (cddr (nth choix (:x:def menu))) cname))) (when active (|←XMenuSetPane| (:extend menu) choix active) (rplaca (cdr (nth choix (:x:def menu))) active))) (de :x:menu-modify-item (menu choix item name active value) (let (cname) (when name (setq name (string name)) (setq cname (|←cstring| name (slen name))) (|←XMenuChangeSelection| (:extend menu) choix item value (if value 1 0) cname (if name 1 0))) (when (or name value) (let ((itemdef (nth item (cdddr (nth choix (:x:def menu)))))) (when name (rplaca itemdef name)) (when name (rplaca (cddr itemdef) cname)) (when value (rplaca (cdddr itemdef) value)))) (when active (let ((itemdef (nth item (cdddr (nth choix (:x:def menu)))))) (rplaca (cdr itemdef) active) (|←XMenuSetSelection| (:extend menu) choix item active))))) (de :x:rebuild-menu (menu) (let ((def (:x:def menu))) (:x:def menu ()) (:extend menu (|←XMenuCreate| (|←rootwindow|) "lelisp")) (mapc (lambda (ilist) (menu-insert-item-list menu 0 (car ilist) (cadr ilist)) (mapc (lambda (item) (menu-insert-item menu 0 0 (car item) (cadr item) (cadddr item))) (reverse (cdddr ilist)))) (reverse def))))