factor/basis/ui/gadgets/buttons/buttons.factor

259 lines
6.7 KiB
Factor
Raw Normal View History

! Copyright (C) 2005, 2008 Slava Pestov.
2007-09-20 18:09:08 -04:00
! See http://factorcode.org/license.txt for BSD license.
USING: accessors arrays kernel math models namespaces sequences
strings quotations assocs combinators classes colors
2008-11-21 00:54:27 -05:00
classes.tuple locals alien.c-types fry opengl opengl.gl
math.vectors ui.commands ui.gadgets ui.gadgets.borders
ui.gadgets.labels ui.gadgets.theme ui.gadgets.tracks
ui.gadgets.packs ui.gadgets.worlds ui.gestures ui.render
math.geometry.rect ;
2007-09-20 18:09:08 -04:00
IN: ui.gadgets.buttons
2008-07-11 01:46:15 -04:00
TUPLE: button < border pressed? selected? quot ;
2007-09-20 18:09:08 -04:00
: buttons-down? ( -- ? )
hand-buttons get-global empty? not ;
: button-rollover? ( button -- ? )
hand-gadget get-global child? ;
: mouse-clicked? ( gadget -- ? )
hand-clicked get-global child? ;
: button-update ( button -- )
dup mouse-clicked?
over button-rollover? and
buttons-down? and
>>pressed?
2007-09-20 18:09:08 -04:00
relayout-1 ;
: if-clicked ( button quot -- )
2008-11-21 00:54:27 -05:00
[ dup button-update dup button-rollover? ] dip [ drop ] if ;
2007-09-20 18:09:08 -04:00
: button-clicked ( button -- ) dup quot>> if-clicked ;
2007-09-20 18:09:08 -04:00
button H{
{ T{ button-up } [ button-clicked ] }
{ T{ button-down } [ button-update ] }
{ T{ mouse-leave } [ button-update ] }
{ T{ mouse-enter } [ button-update ] }
} set-gestures
: new-button ( label quot class -- button )
2008-07-11 01:46:15 -04:00
[ swap >label ] dip new-border swap >>quot ; inline
2008-07-11 01:46:15 -04:00
: <button> ( label quot -- button )
button new-button ;
2007-09-20 18:09:08 -04:00
TUPLE: button-paint plain rollover pressed selected ;
C: <button-paint> button-paint
2008-06-08 16:32:55 -04:00
: find-button ( gadget -- button )
2008-08-23 00:20:49 -04:00
[ button? ] find-parent ;
2007-10-31 01:04:54 -04:00
2007-09-20 18:09:08 -04:00
: button-paint ( button paint -- button paint )
2007-10-31 01:04:54 -04:00
over find-button {
2008-06-18 23:30:54 -04:00
{ [ dup pressed?>> ] [ drop pressed>> ] }
{ [ dup selected?>> ] [ drop selected>> ] }
{ [ dup button-rollover? ] [ drop rollover>> ] }
[ drop plain>> ]
2007-09-20 18:09:08 -04:00
} cond ;
M: button-paint draw-interior
button-paint dup [ draw-interior ] [ 2drop ] if ;
2007-09-20 18:09:08 -04:00
M: button-paint draw-boundary
button-paint dup [ draw-boundary ] [ 2drop ] if ;
2007-09-20 18:09:08 -04:00
2008-09-01 03:52:25 -04:00
: align-left ( button -- button )
{ 0 1/2 } >>align ; inline
2008-06-18 23:30:54 -04:00
: roll-button-theme ( button -- button )
f black <solid> dup f <button-paint> >>boundary
2008-09-01 03:52:25 -04:00
align-left ; inline
2007-09-20 18:09:08 -04:00
: <roll-button> ( label quot -- button )
<button> roll-button-theme ;
2007-09-20 18:09:08 -04:00
2008-06-18 23:30:54 -04:00
: <bevel-button-paint> ( -- paint )
2007-09-20 18:09:08 -04:00
plain-gradient
rollover-gradient
pressed-gradient
selected-gradient
2008-06-18 23:30:54 -04:00
<button-paint> ;
: bevel-button-theme ( gadget -- gadget )
<bevel-button-paint> >>interior
2008-07-11 01:46:15 -04:00
{ 5 5 } >>size
2008-06-18 23:30:54 -04:00
faint-boundary ; inline
2007-09-20 18:09:08 -04:00
: <bevel-button> ( label quot -- button )
2008-07-11 01:46:15 -04:00
<button> bevel-button-theme ;
2007-09-20 18:09:08 -04:00
TUPLE: repeat-button < button ;
2007-09-20 18:09:08 -04:00
repeat-button H{
{ T{ drag } [ button-clicked ] }
} set-gestures
: <repeat-button> ( label quot -- button )
#! Button that calls the quotation every 100ms as long as
#! the mouse is held down.
2008-07-11 01:46:15 -04:00
repeat-button new-button bevel-button-theme ;
2007-09-20 18:09:08 -04:00
TUPLE: checkmark-paint < caching-pen color last-vertices ;
: <checkmark-paint> ( color -- paint )
checkmark-paint new swap >>color ;
<PRIVATE
: checkmark-points ( dim -- points )
{
2008-11-18 22:57:50 -05:00
[ { 0 0 } v* { 0.5 0.5 } v+ ]
[ { 1 1 } v* { 0.5 0.5 } v+ ]
[ { 1 0 } v* { -0.3 0.5 } v+ ]
[ { 0 1 } v* { -0.3 0.5 } v+ ]
} cleave 4array ;
: checkmark-vertices ( dim -- vertices )
checkmark-points concat >c-float-array ;
PRIVATE>
M: checkmark-paint recompute-pen
swap dim>> checkmark-vertices >>last-vertices drop ;
M: checkmark-paint draw-interior
[ compute-pen ]
[ color>> gl-color ]
[ last-vertices>> gl-vertex-pointer ] tri
GL_LINES 0 4 glDrawArrays ;
: checkmark-theme ( gadget -- gadget )
2007-10-31 01:04:54 -04:00
f
f
black <solid>
black <checkmark-paint>
<button-paint> >>interior
black <solid> >>boundary ;
2007-09-20 18:09:08 -04:00
2007-10-31 01:04:54 -04:00
: <checkmark> ( -- gadget )
<gadget>
checkmark-theme
{ 14 14 } >>dim ;
2007-10-31 01:04:54 -04:00
: toggle-model ( model -- )
[ not ] change-model ;
: checkbox-theme ( gadget -- gadget )
2008-06-08 16:32:55 -04:00
f >>interior
{ 5 5 } >>gap
1/2 >>align ; inline
2007-10-31 01:04:54 -04:00
TUPLE: checkbox < button ;
2007-11-13 18:51:10 -05:00
2007-10-31 01:04:54 -04:00
: <checkbox> ( model label -- checkbox )
<checkmark> label-on-right checkbox-theme
[ model>> toggle-model ]
checkbox new-button
2008-09-01 03:52:25 -04:00
swap >>model
align-left ;
2007-10-31 01:04:54 -04:00
2007-11-13 18:51:10 -05:00
M: checkbox model-changed
swap value>> >>selected? relayout-1 ;
2007-11-13 18:51:10 -05:00
TUPLE: radio-paint < caching-pen color interior-vertices boundary-vertices ;
: <radio-paint> ( color -- paint ) radio-paint new swap >>color ;
<PRIVATE
2008-11-11 03:31:56 -05:00
: circle-steps 8 ;
PRIVATE>
M: radio-paint recompute-pen
swap dim>>
2008-11-11 03:31:56 -05:00
[ { 4 4 } swap { 9 9 } v- circle-steps circle-vertices >>interior-vertices ]
[ { 1 1 } swap { 3 3 } v- circle-steps circle-vertices >>boundary-vertices ] bi
drop ;
<PRIVATE
: (radio-paint) ( gadget paint -- )
[ compute-pen ] [ color>> gl-color ] bi ;
PRIVATE>
M: radio-paint draw-interior
[ (radio-paint) ] [ interior-vertices>> gl-vertex-pointer ] bi
GL_POLYGON 0 circle-steps glDrawArrays ;
M: radio-paint draw-boundary
[ (radio-paint) ] [ boundary-vertices>> gl-vertex-pointer ] bi
GL_LINE_LOOP 0 circle-steps glDrawArrays ;
:: radio-knob-theme ( gadget -- gadget )
[let | radio-paint [ black <radio-paint> ] |
gadget
f f radio-paint radio-paint <button-paint> >>interior
radio-paint >>boundary
{ 16 16 } >>dim
] ;
2007-10-31 01:04:54 -04:00
: <radio-knob> ( -- gadget )
<gadget> radio-knob-theme ;
2007-10-31 01:04:54 -04:00
TUPLE: radio-control < button value ;
2007-11-13 18:51:10 -05:00
: <radio-control> ( value model label -- control )
[ [ value>> ] keep set-control-value ]
radio-control new-button
swap >>model
2008-09-01 03:52:25 -04:00
swap >>value
align-left ; inline
2007-11-13 18:51:10 -05:00
M: radio-control model-changed
2008-09-01 23:43:23 -04:00
swap value>>
over value>> = >>selected?
2007-11-13 18:51:10 -05:00
relayout-1 ;
2007-10-31 01:04:54 -04:00
2008-11-21 00:54:27 -05:00
: <radio-controls> ( assoc model parent quot: ( value model label -- ) -- parent )
'[ _ swap _ call add-gadget ] assoc-each ; inline
2007-10-31 01:04:54 -04:00
: radio-button-theme ( gadget -- gadget )
2008-06-08 16:32:55 -04:00
{ 5 5 } >>gap
1/2 >>align ; inline
2007-10-31 01:04:54 -04:00
2007-11-14 16:35:17 -05:00
: <radio-button> ( value model label -- gadget )
<radio-knob> label-on-right radio-button-theme <radio-control> ;
2007-10-31 01:04:54 -04:00
: <radio-buttons> ( model assoc -- gadget )
<filled-pile>
2008-11-21 00:54:27 -05:00
spin [ <radio-button> ] <radio-controls>
{ 5 5 } >>gap ;
2007-10-31 01:04:54 -04:00
2007-11-14 16:35:17 -05:00
: <toggle-button> ( value model label -- gadget )
2008-07-11 01:46:15 -04:00
<radio-control> bevel-button-theme ;
2007-10-31 01:04:54 -04:00
: <toggle-buttons> ( model assoc -- gadget )
<shelf>
2008-11-21 00:54:27 -05:00
spin [ <toggle-button> ] <radio-controls> ;
2007-09-20 18:09:08 -04:00
: command-button-quot ( target command -- quot )
2008-11-21 00:54:27 -05:00
'[ _ _ invoke-command drop ] ;
2007-09-20 18:09:08 -04:00
: <command-button> ( target gesture command -- button )
2008-11-21 00:54:27 -05:00
[ command-string swap ] keep command-button-quot <bevel-button> ;
2007-09-20 18:09:08 -04:00
: <toolbar> ( target -- toolbar )
<shelf>
swap
"toolbar" over class command-map commands>> swap
2008-11-21 00:54:27 -05:00
'[ [ _ ] 2dip <command-button> add-gadget ] assoc-each ;
: add-toolbar ( track -- track )
dup <toolbar> f track-add ;