This is the full commented code for the structured main menu:
-- The language still misses very basic functionality like primitive integers -- and strings. Hence, the code relies on native C symbols, which are -- prefixed with an underscore (e.g., `_255` and `_("Story")`). -- `Pico` is a simple graphical library based on SDL. -- Includes auxiliary files ^"prelude.ceu" ^"int.ceu" ^"float.ceu" ^"pico.ceu" -- Sets the initial window properties output Pico.Set.Title _("Pingus") output Pico.Set.Size [_641,_481] output Pico.Set.Zoom [_100,_100] output Pico.Set.Grid _0 output Pico.Set.Color.Clear [_0,_0,_0,_255] output Pico.Clear output Pico.Set.Auto _0 -- Menu enumeration type Menu = <Story=(),Editor=(),Levelsets=(),Options=(),Exit=()> -- Task to show a single button: -- - receives point and label to show -- - terminates on a mouse click task menu_button: [pos:Point,lbl:_(char*)] -> () -> () { var size: Size -- get dimensions to detect click output Pico.Get.Size.Image [/size, _("data/images/menuitem.png")] -- task to show itself on every Draw event spawn { every evt?Draw { -- draw image with label on top output Pico.Draw.Image [arg.pos, _("data/images/menuitem.png")] output Pico.Set.Font [_("data/fonts/film-cryptic/Filmcryptic.ttf"),_45] output Pico.Draw.Text [arg.pos, arg.lbl] } } -- awaits a mouse click inside its region to terminate await evt?Mouse?Button?Down until isPointVsRect [pos,[arg.pos,size]] where { var pos = evt!Mouse!Button!Down.pos } } -- Task to show the main menu: -- - spawns a `menu_button` task for each button in the menu -- - terminates when any button is clicked -- - returns the `Menu` enumeration associated with the click task main_menu: () -> () -> Menu { -- spawns multiple tasks in parallel to wait for the buttons par { -- spawns and awaits each button await spawn menu_button [[_(-125),_( 35)], _("Story")] -- returns the associated enumeration return Menu.Story } with { await spawn menu_button [[_( 125),_( 35)], _("Editor")] return Menu.Editor } with { await spawn menu_button [[_(-125),_( -35)], _("Levelsets")] return Menu.Levelsets } with { await spawn menu_button [[_( 125),_( -35)], _("Options")] return Menu.Options } with { await spawn menu_button [[_( 0),_(-105)], _("Exit")] return Menu.Exit } } -- Main application: -- - a loop that alternates between the menu and the chosen button spawn { loop { -- spawns the main menu and awaits its termination var opt = await spawn main_menu () -- maps the chosen button to a label to show next var lbl: _(char*) = ifs { opt ? Story { _("Story") } opt ? Editor { _("Editor") } opt ? Levelsets { _("Levelsets") } opt ? Options { _("Options") } opt ? Exit { _("Exit") } } -- shows and awaits the chosen button in the center of the screen await spawn menu_button [[_0,_0], lbl] } } -- Enters the engine main loop. -- Now the application is entirely reactive. -- In this code, only the individual buttons (`menu_button` task) react to -- events (evt?Draw and evt?Mouse). call pico_loop ()
Comment on @_fsantanna.