! Copyright (C) 2005, 2009 Slava Pestov. ! See https://factorcode.org/license.txt for BSD license. USING: accessors combinators kernel math math.rectangles math.vectors models namespaces opengl sequences sorting ui.commands ui.gadgets ui.gadgets.borders ui.gadgets.buttons ui.gadgets.glass ui.gadgets.packs ui.gadgets.worlds ui.gadgets.wrappers ui.gestures ui.operations ui.pens ui.pens.solid ui.theme ; FROM: ui.gadgets.wrappers => wrapper ; IN: ui.gadgets.menus rect show-glass ; PRIVATE> : show-menu ( owner menu -- ) [ (show-menu) ] keep request-focus ; TUPLE: menu-button < button ; >align ; inline MEMO: menu-button-pen-boundary ( -- pen ) f f roll-button-rollover-border dup dup ; MEMO: menu-button-pen-interior ( -- pen ) f f roll-button-selected-background f over ; : menu-button-theme ( menu-button -- menu-button ) menu-button-pen-boundary >>boundary menu-button-pen-interior >>interior align-left ; inline : ( label quot -- menu-button ) menu-button new-button menu-button-theme ; inline PRIVATE> GENERIC: ( target hook command -- menu-item ) M:: object ( target hook command -- menu-item ) command command-name [ hook call target command command-button-quot call hide-glass ] ; separator-pen M: separator-pen draw-interior color>> gl-color dim>> [ { 0 0.5 } v* ] [ { 1 0.5 } v* ] bi [ v>integer ] bi@ gl-line ; : ( items -- gadget ) [ ] dip add-gadgets ; PRIVATE> SINGLETON: ---- M: ---- 3drop { 0 5 } >>dim menu-border-color >>interior ; TUPLE: menu < wrapper items ; > [ menu-button? ] filter ; :: prepare-menu ( menu items -- ) f :> model items menu-buttons :> buttons buttons [ model add-connection ] each menu model >>model buttons >>items drop ; PRIVATE> M: menu-button model-changed swap value>> over = >>selected? relayout-1 ; M: menu-button handle-gesture [ { { [ over mouse-enter? ] [ nip activate-item ] } { [ over mouse-leave? ] [ nip inactivate-item ] } [ 2drop ] } cond ] 2keep call-next-method ; > ] [ control-value ] bi :> ( items curr ) curr [ items length :> max curr items index :> indx indx dir + max rem items nth ] [ items first ] if menu set-control-value ; : activate-menu-item ( menu -- ) control-value [ dup quot>> ( button -- ) call-effect ] when* ; PRIVATE> menu H{ { T{ key-down f f "ESC" } [ hide-glass ] } { T{ key-down f f "DOWN" } [ 1 next-item ] } { T{ key-down f f "UP" } [ -1 next-item ] } { T{ key-down f f "RET" } [ activate-menu-item ] } } set-gestures : ( gadgets -- menu ) [ { 0 3 } >>gap { 5 5 } menu-border-color >>boundary menu-background >>interior menu new-wrapper ] [ dupd prepare-menu ] bi ; : ( target hook commands -- menu ) [ ] 2with map ; : show-commands-menu ( target commands -- ) [ dup [ ] ] dip show-menu ; : ( target hook -- menu ) over object-operations [ primary-operation? ] partition [ reverse ] [ [ command-name ] sort-by ] bi* { ---- } glue ; : show-operations-menu ( gadget target hook -- ) show-menu ;