- fix alien-callback/SEH bug on win32
- list mouse gestures
- maybe simplify list into displaying list a sequence of strings
-- the mouse button overload sucks, use popup menus instead
- nested presentation mouse over is not right
- ui quick start doc
- x11: scroll up/down wiggles caret
- slider needs to be modelized
- some way of intercepting all gestures
- better help result ranking
-- minibuffer should show a title
- clean up listener's minibuffer-related code
- help search looks funny
+- menus should not require mouse to be held
+- tab completion: add a USE: if necessary
+ ui:
swap pick commands set-hash
dup commands>gestures "gestures" set-word-prop ;
-: categorize-commands ( seq -- hash )
- dup
- [ hash-keys ] map concat prune
- [ dup pick [ hash ] map-with concat ] map>hash
- nip ;
-
SYMBOL: +name+
SYMBOL: +quot+
SYMBOL: +listener+
SYMBOL: +keyboard+
-SYMBOL: +mouse+
+SYMBOL: +default+
-TUPLE: operation predicate mouse listener? ;
+TUPLE: operation predicate listener? default? ;
: (command) ( -- command )
+name+ get +keyboard+ get +quot+ get <command> ;
C: operation ( predicate hash -- operation )
swap [
(command) over set-delegate
- +mouse+ get over set-operation-mouse
+ +default+ get over set-operation-default?
+listener+ get over set-operation-listener?
] bind
[ set-operation-predicate ] keep ;
"predicate" word-prop
operations get [ operation-predicate = ] subset-with ;
-: mouse-operation ( obj gesture -- command )
- swap object-operations
- [ operation-mouse = ] subset-with
- dup empty? [ drop f ] [ peek ] if ;
+: default-operation ( obj -- command )
+ object-operations [ operation-default? ] find-last nip ;
: modify-operation ( quot operation -- operation )
clone
dup list-index swap control-value ?nth ;
: scroll>selected ( list -- )
- dup selected-rect swap scroll>rect ;
+ #! We change the rectangle's width to zero to avoid
+ #! scrolling right.
+ [ selected-rect rect-bounds { 0 1 } v* <rect> ] keep
+ scroll>rect ;
: list-empty? ( list -- ? ) control-value empty? ;
--- /dev/null
+! Copyright (C) 2005, 2006 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+IN: gadgets
+USING: arrays errors freetype gadgets-frames generic hashtables
+kernel math models namespaces opengl sequences ;
+
+: menu-loc ( world menu -- loc )
+ >r rect-dim r> pref-dim [v-] hand-loc get-global vmin ;
+
+TUPLE: menu-glass ;
+
+C: menu-glass ( menu world -- glass )
+ dup delegate>gadget
+ >r over menu-loc over set-rect-loc r>
+ [ add-gadget ] keep ;
+
+M: menu-glass layout* gadget-child prefer ;
+
+: retarget-drag ( gadget -- )
+ hand-gadget get-global hand-clicked get-global eq? [
+ drop
+ ] [
+ hand-loc get-global swap find-world move-hand
+ ] if ;
+
+: hide-menu ( -- )
+ find-world hide-glass f menu-mode? set-global ;
+
+\ menu-glass H{
+ { T{ button-up } [ hide-menu ] }
+ { T{ drag } [ retarget-drag ] }
+} set-gestures
+
+: show-menu ( gadget owner -- )
+ find-world [ <menu-glass> ] keep [ show-glass ] keep
+ t menu-mode? set-global ;
IN: gadgets-presentations
USING: arrays definitions gadgets gadgets-borders
gadgets-buttons gadgets-grids gadgets-labels gadgets-outliner
-gadgets-panes gadgets-paragraphs gadgets-theme generic
-hashtables tools io kernel prettyprint sequences strings
+gadgets-panes gadgets-paragraphs gadgets-theme
+generic hashtables tools io kernel prettyprint sequences strings
styles words help math models namespaces ;
! Clickable objects
: <command-presentation> ( target command -- button )
dup command-name f <bevel-button> -rot <presentation> ;
-: presentation-command* ( presentation gesture -- obj cmd )
- over presentation-command [
- dup T{ button-up f f 1 } = [
- drop
- dup presentation-object swap presentation-command
- ] [
- >r presentation-command dup r> mouse-operation
- ] if
- ] [
- >r presentation-object dup r> mouse-operation
- ] if ;
+: <commands-menu> ( target commands -- gadget )
+ [ hand-clicked get find-world hide-glass ] modify-operations
+ [ <command-presentation> ] map-with
+ make-pile 1 over set-pack-fill ;
-: invoke-presentation ( gadget modifiers button# -- )
- <button-up>
- presentation-command* dup [ invoke-command ] [ 2drop ] if ;
+: operations-menu ( presentation -- gadget )
+ dup presentation-object
+ dup object-operations <commands-menu>
+ swap show-menu ;
+
+: invoke-presentation ( presentation -- )
+ dup presentation-object swap presentation-command
+ [ dup default-operation ] unless*
+ invoke-command ;
: show-mouse-help ( presentation -- )
dup find-world [ world-status set-model* ] [ drop ] if* ;
dup hide-mouse-help delegate ungraft* ;
presentation H{
- { T{ button-up f f 1 } [ [ f 1 invoke-presentation ] if-clicked ] }
- { T{ button-up f f 2 } [ [ f 2 invoke-presentation ] if-clicked ] }
- { T{ button-up f f 3 } [ [ f 3 invoke-presentation ] if-clicked ] }
- { T{ button-up f { S+ } 1 } [ [ { S+ } 1 invoke-presentation ] if-clicked ] }
- { T{ button-up f { S+ } 2 } [ [ { S+ } 2 invoke-presentation ] if-clicked ] }
- { T{ button-up f { S+ } 3 } [ [ { S+ } 3 invoke-presentation ] if-clicked ] }
- { T{ mouse-leave } [ dup hide-mouse-help button-update ] }
- { T{ mouse-enter } [ dup show-mouse-help button-update ] }
+ { T{ button-up } [ [ invoke-presentation ] if-clicked ] }
+ { T{ button-down f f 3 } [ [ operations-menu ] if-clicked ] }
+ { T{ mouse-leave } [ global [ dup short. flush ] bind dup hide-mouse-help button-update ] }
+ { T{ mouse-enter } [ global [ dup short. flush ] bind dup show-mouse-help button-update ] }
} set-gestures
! Presentation help bar
-: <presentation-summary> ( model -- )
- [
- [
- presentation-object summary
- ] [
- "Mouse over a presentation for help."
- ] if*
- ] <filter> <label-control> dup reverse-video-theme ;
-
-: <gesture-help> ( model gesture -- gadget )
- [
- over [
- tuck presentation-command* nip dup [
- >r gesture>string ": " r> command-name append3
- ] [
- 2drop ""
- ] if
- ] [
- 2drop ""
- ] if
- ] curry <filter> <label-control> ;
-
-: <presentation-mouse-help> ( model -- help )
- { f { S+ } } [
- 3 [
- 1+ >r 2dup r> <button-up> <gesture-help>
- ] map nip
- ] map nip <grid>
- { 10 0 } over set-grid-gap ;
-
: <presentation-help> ( model -- gadget )
- [
- dup <presentation-summary> ,
- <presentation-mouse-help> ,
- ] { } make make-pile 1 over set-pack-fill ;
+ [ [ presentation-object summary ] [ "" ] if* ] <filter>
+ <label-control> dup reverse-video-theme ;
: <listener-button> ( gadget quot -- button )
[ call-listener ] curry <roll-button> ;
#! the current gadget, with all parents in between.
hand-gadget get-global parents <reversed> ;
+: update-clicked ( -- )
+ hand-gadget get-global hand-clicked set-global
+ hand-loc get-global hand-click-loc set-global ;
+
+SYMBOL: menu-mode?
+
: move-hand ( loc world -- )
dup hand-world set-global
under-hand >r over hand-loc set-global
pick-up hand-gadget set-global
+ menu-mode? get-global [ update-clicked ] when
under-hand r> hand-gestures ;
-: update-clicked ( -- )
- hand-gadget get-global hand-clicked set-global
- hand-loc get-global hand-click-loc set-global ;
-
: send-button-down ( gesture loc world -- )
move-hand
update-clicked
"gadgets/books.factor"
"gadgets/outliner.factor"
"gadgets/lists.factor"
+ "gadgets/menus.factor"
"text/document.factor"
"text/elements.factor"
"text/editor.factor"
! Objects
[ drop t ] H{
- { +mouse+ T{ button-up f f 1 } }
+ { +default+ t }
{ +name+ "Inspect" }
{ +quot+ [ inspect ] }
{ +listener+ t }
} define-operation
[ drop t ] H{
- { +mouse+ T{ button-up f { S+ } 1 } }
{ +name+ "Push" }
{ +quot+ [ ] }
{ +listener+ t }
} define-operation
-! Commands
-[ [ command? ] is? ] H{
- { +mouse+ T{ button-up f { S+ } 3 } }
- { +name+ "Inspect" }
- { +quot+ [ inspect ] }
- { +listener+ t }
-} define-operation
-
! Input
[ input? ] H{
- { +mouse+ T{ button-up f f 1 } }
+ { +default+ t }
{ +name+ "Input" }
{ +quot+ [ listener-gadget call-tool ] }
} define-operation
! Pathnames
[ pathname? ] H{
- { +mouse+ T{ button-up f f 1 } }
+ { +default+ t }
{ +name+ "Edit" }
{ +quot+ [ pathname-string edit-file ] }
} define-operation
[ pathname? ] H{
- { +mouse+ T{ button-up f f 2 } }
{ +name+ "Run file" }
{ +quot+ [ pathname-string [ run-file ] curry call-listener ] }
} define-operation
! Words
[ word? ] H{
- { +mouse+ T{ button-up f f 1 } }
+ { +default+ t }
{ +name+ "Browse" }
{ +keyboard+ T{ key-down f { A+ } "b" } }
{ +quot+ [ browser call-tool ] }
} define-operation
[ word? ] H{
- { +mouse+ T{ button-up f f 2 } }
{ +name+ "Edit" }
{ +keyboard+ T{ key-down f { A+ } "e" } }
{ +quot+ [ edit ] }
} define-operation
[ word? ] H{
- { +mouse+ T{ button-up f f 3 } }
{ +name+ "Documentation" }
{ +keyboard+ T{ key-down f { A+ } "h" } }
{ +quot+ [ help-gadget call-tool ] }
} define-operation
[ word? ] H{
- { +mouse+ T{ button-up f { S+ } 3 } }
{ +name+ "Usage" }
{ +keyboard+ T{ key-down f { A+ } "u" } }
{ +quot+ [ usage. ] }
} define-operation
[ word? ] H{
- { +mouse+ T{ button-up f { S+ } 2 } }
{ +name+ "Reload" }
{ +keyboard+ T{ key-down f { A+ } "r" } }
{ +quot+ [ reload ] }
! Vocabularies
[ vocab-link? ] H{
- { +mouse+ T{ button-up f f 1 } }
+ { +default+ t }
{ +name+ "Browse" }
{ +quot+ [ browser call-tool ] }
} define-operation
[ vocab-link? ] H{
- { +mouse+ T{ button-up f f 2 } }
{ +name+ "Enter in" }
{ +quot+ [ vocab-link-name [ set-in ] curry call-listener ] }
} define-operation
[ vocab-link? ] H{
- { +mouse+ T{ button-up f f 3 } }
{ +name+ "Use" }
{ +quot+ [ vocab-link-name [ use+ ] curry call-listener ] }
} define-operation
! Link
[ link? ] H{
- { +mouse+ T{ button-up f f 1 } }
+ { +default+ t }
{ +name+ "Follow" }
{ +quot+ [ help-gadget call-tool ] }
} define-operation
[ link? ] H{
- { +mouse+ T{ button-up f f 2 } }
{ +name+ "Edit" }
{ +quot+ [ edit ] }
} define-operation
[ link? ] H{
- { +mouse+ T{ button-up f { S+ } 2 } }
{ +name+ "Reload" }
{ +quot+ [ reload ] }
} define-operation
[ word-link? ] H{
- { +mouse+ T{ button-up f f 3 } }
{ +name+ "Definition" }
{ +quot+ [ link-name browser call-tool ] }
} define-operation
! Dataflow nodes
[ [ node? ] is? ] H{
- { +mouse+ T{ button-up f f 1 } }
+ { +default+ t }
{ +name+ "Show dataflow" }
{ +quot+ [ dataflow-gadget call-tool ] }
} define-operation
[ [ node? ] is? ] H{
- { +mouse+ T{ button-up f { S+ } 3 } }
{ +name+ "Inspect" }
{ +quot+ [ inspect ] }
{ +listener+ t }
all-words
[ word-completions ] curry
[ word-completion. ]
- <live-search> ;
+ <live-search> "Word search" <labelled-gadget> ;
: <help-search> ( string action -- gadget )
[ search-help ]
[ first ($link) ]
- <live-search> ;
+ <live-search> "Help search" <labelled-gadget> ;
: string-completion. ( pair quot -- )
>r first2 over completion>string swap r> call write-object ;
source-files get hash-keys natural-sort
[ string-completions ] curry
[ [ <pathname> ] string-completion. ]
- <live-search> ;
+ <live-search> "Source file search" <labelled-gadget> ;
: <vocabs-search> ( string action -- gadget )
vocabs
[ string-completions ] curry
[ [ <vocab-link> ] string-completion. ]
- <live-search> ;
+ <live-search> "Vocabulary search" <labelled-gadget> ;
: $commands ( elt -- )
dup array? [ first ] when commands commands. ;
-: <labelled-gadget> ( gadget title -- gadget )
+TUPLE: labelled-gadget content ;
+
+C: labelled-gadget ( gadget title -- gadget )
{
{ [ <label> dup reverse-video-theme ] f f @top }
- { [ ] f f @center }
- } make-frame ;
+ { f set-labelled-gadget-content f @center }
+ } make-frame* ;
+
+M: labelled-gadget focusable-child* labelled-gadget-content ;
: <labelled-pane> ( model quot title -- gadget )
>r <pane-control> <scroller> r> <labelled-gadget> ;
! UI code assumes that everything starts at { 0 0 }.
TUPLE: world
active?
-gadget
+gadget glass
title status
focus focused?
fonts handle
>r world get font-sprites first2 r> (draw-string) ;
M: world gadget-title world-gadget gadget-title ;
+
+M: world layout*
+ dup delegate layout*
+ dup world-glass [
+ >r dup rect-dim r> set-layout-dim
+ ] when* drop ;
+
+: hide-glass ( world -- )
+ dup world-glass [ unparent ] when*
+ f swap set-world-glass ;
+
+: show-glass ( gadget world -- )
+ [ hide-glass ] keep
+ [ add-gadget ] 2keep
+ set-world-glass ;