3b/cl-opengl

The value MENU-STATUS is not of type SB-SYS:SYSTEM-AREA-POINTER when binding SB-ALIEN::VALUE

asarch opened this issue ยท 10 comments

How would you create a menu and attach it to the right button?

(defun menu-status (status x y)
  (format t "Menu item: ~d~%" status))

(glut:create-menu menu-status)
(glut:add-menu-entry "Full Screen\tF5" +fullscreen+)
(glut:add-menu-entry "Exit\tAlt+x" +exit+)
(glut:attach-menu :right-button)

Looks like you need to use defcallback.

Where is it?

(defcallback menu-status (status x y)
    (format t "Menu item: ~d~%" status))

; in: DEFCALLBACK MENU-STATUS                                                                                                                        
;     (DEFCALLBACK MENU-STATUS (STATUS X Y) (FORMAT T "Menu item: ~d~%" STATUS))                                                                     
;                                                                                                                                                    
; caught STYLE-WARNING:                                                                                                                              
;   undefined function: COMMON-LISP-USER::DEFCALLBACK                                                                                                
;                                                                                                                                                    
; caught WARNING:                                                                                                                                    
;   undefined variable: COMMON-LISP-USER::MENU-STATUS                                                                                                
                                                                                                                                                     
;     (FORMAT T "Menu item: ~d~%" STATUS)                                                                                                            
;                                                                                                                                                    
; caught WARNING:                                                                                                                                    
;   undefined variable: COMMON-LISP-USER::STATUS                                                                                                     
                                                                                                                                                     
;     (STATUS X Y)                                                                                                                                   
;                                                                                                                                                    
; caught STYLE-WARNING:                                                                                                                              
;   undefined function: COMMON-LISP-USER::STATUS                                                                                                     
;                                                                                                                                                    
; caught WARNING:                                                                                                                                    
;   undefined variable: COMMON-LISP-USER::X                                                                                                          
;                                                                                                                                                    
; caught WARNING:
;   undefined variable: COMMON-LISP-USER::Y
; 
; compilation unit finished
;   Undefined functions:
;     DEFCALLBACK STATUS
;   Undefined variables:
;     MENU-STATUS STATUS X Y
;   caught 4 WARNING conditions
;   caught 2 STYLE-WARNING conditions

Use apropos. ๐Ÿ™‚

3b commented

made an attempt at wrapping the glut menu API for the glut CLOS wrappers, at https://github.com/3b/cl-opengl/tree/glut-menu (example use in https://github.com/3b/cl-opengl/blob/glut-menu/examples/misc/glut-menu.lisp )

Not sure if that is a good interface or not, in particular it is fairly static currently, though possibly that could be improved without changing it much.

Why glut-menu.lisp is not when you do?:

$ git clone https://github.com/3b/cl-opengl

I mean, where is glut::menu-mixin?

@asarch check out the glut-menu branch.

@3b Looks great!

This interface was bit of an exercise in making it as CLOS-y as possible, so I'd try to somehow drop the defmenu macro. Perhaps the :menus option can take the full menu list or the menu list could be specified by adding a method to a glut:menus generic function?

Also, I'd try to attach this behaviour to the main glut:window class without requiring a mixin.

3b commented

hmm, building it directly into window does seem like a good idea. Was distracted by menus having separate IDs in GLUT, but probably makes more sense to just let window instances own their own menus instead of trying to have global menus that can be attached to multiple windows.

Maybe have :left-menu, :right-menu,:middle-menu options to window that take a menu description, and just always build new menu(s) when window is created. If those are stored individually, people can override the accessor to return the menu description for their class instead if they want to. Possibly also add a generic that windows could override to build their own menus manually.

Also need to think about dynamic update of menus, but that's probably simpler with single owner too. Maybe just an :around method on (setf left-menu) and similar would be enough, and if the menu has been created in GLUT, it can diff the 2 descriptions and update the existing menus (or even just wipe and recreate them).

@3b yeah, that sounds even simpler/leaner. ๐Ÿ‘

3b commented

update menu API to work directly with base-window class. you can pass a menu description (list of items and submenus) to :left-menu,:right-menu,and :middle-menu initargs, or (setf (left-menu window) menu-description) etc for existing window instances.

Example is updated with new usage, including changing menu contents in response to menu clicks.

Menus are owned by a window instance, so changing one won't affect other instances of same window class. Currently it just recreates menus from scratch when you call (setf left-menu) and similar, unless old and new are tree-equal (assuming window exists), but probably good enough for most simple use.

Probably still some edge cases in things like how it handles duplicate names, or whether things get cleaned up properly on bad exits. Will try actually using it a bit and see how it looks.