factor/library/ui/panes.factor

160 lines
4.8 KiB
Factor
Raw Normal View History

2005-06-27 00:54:49 -04:00
! Copyright (C) 2005 Slava Pestov.
! See http://factor.sf.net/license.txt for BSD license.
2005-09-01 01:20:43 -04:00
IN: gadgets-presentations
2005-10-01 01:44:49 -04:00
DEFER: gadget.
2005-09-01 01:20:43 -04:00
IN: gadgets-panes
2005-10-07 20:26:21 -04:00
USING: arrays gadgets gadgets-buttons gadgets-editors
gadgets-labels gadgets-layouts gadgets-scrolling gadgets-theme
generic hashtables io kernel line-editor lists math namespaces
2005-09-28 23:29:00 -04:00
prettyprint sequences strings styles threads ;
2005-06-27 00:54:49 -04:00
! A pane is an area that can display text.
! output: pile
! current: shelf
! input: editor
2005-12-16 21:12:35 -05:00
TUPLE: pane output active current input prototype
continuation scrolls? ;
2005-06-27 00:54:49 -04:00
: add-output 2dup set-pane-output add-gadget ;
2005-09-25 00:18:12 -04:00
: <active-line> ( current input -- line )
2005-09-27 00:24:42 -04:00
[ 2array ] [ 1array ] if* make-shelf ;
2005-06-27 00:54:49 -04:00
2005-12-16 21:12:35 -05:00
: init-line ( pane -- )
dup pane-prototype clone swap set-pane-current ;
: prepare-line ( pane -- )
dup init-line dup pane-active unparent
2005-08-26 21:42:43 -04:00
[ dup pane-current swap pane-input <active-line> ] keep
2005-06-27 00:54:49 -04:00
2dup set-pane-active add-gadget ;
: pop-continuation ( pane -- quot )
dup pane-continuation f rot set-pane-continuation ;
2005-07-06 03:29:42 -04:00
: pane-eval ( string pane -- )
pop-continuation dup
[ [ continue-with ] in-thread ] when 2drop ;
2005-08-26 00:55:56 -04:00
SYMBOL: structured-input
: elements. ( quot -- )
[
2 nesting-limit set
2005-08-26 00:55:56 -04:00
5 length-limit set
2005-08-29 18:18:10 -04:00
<block pprint-elements block> newline
2005-08-26 00:55:56 -04:00
] with-pprint ;
2005-07-06 03:29:42 -04:00
: pane-call ( quot pane -- )
2005-08-26 00:55:56 -04:00
2dup [ elements. ] with-stream*
>r structured-input global set-hash
2005-09-03 18:44:45 -04:00
"\"structured-input\" \"gadgets-panes\" lookup global hash call"
r> pane-eval ;
2005-08-26 00:55:56 -04:00
: editor-commit ( editor -- line )
#! Add current line to the history, and clear the editor.
[ commit-history line-text get line-clear ] with-editor ;
2005-10-01 01:44:49 -04:00
: replace-input ( string pane -- )
pane-input set-editor-text ;
2005-10-07 20:26:21 -04:00
: <input-button> ( string -- button )
2005-10-27 16:17:50 -04:00
dup <label> dup editor-theme
swap [ nip pane get replace-input ] curry
2005-10-07 20:26:21 -04:00
<roll-button> ;
2005-09-28 23:29:00 -04:00
: print-input ( string pane -- )
2005-10-27 16:17:50 -04:00
[ <input-button> gadget. ] with-stream* ;
2005-09-28 23:29:00 -04:00
: pane-return ( pane -- )
2005-09-25 00:18:12 -04:00
dup pane-input dup [
2005-09-28 23:29:00 -04:00
editor-commit swap 2dup print-input 2dup pane-eval
2005-09-25 00:18:12 -04:00
] when 2drop ;
: pane-clear ( pane -- )
dup pane-output clear-incremental pane-current clear-gadget ;
2005-06-27 00:54:49 -04:00
: pane-actions ( line -- )
H{
2005-11-27 17:45:48 -05:00
{ [ button-down 1 ] [ pane-input [ click-editor ] when* ] }
{ [ "RETURN" ] [ pane-return ] }
{ [ "UP" ] [ pane-input [ [ history-prev ] with-editor ] when* ] }
{ [ "DOWN" ] [ pane-input [ [ history-next ] with-editor ] when* ] }
{ [ "CTRL" "l" ] [ pane get pane-clear ] }
} add-actions ;
2005-06-27 00:54:49 -04:00
2005-09-25 00:18:12 -04:00
C: pane ( input? scrolls? -- pane )
#! You can create output-only panes. If the scrolls flag is
#! set, the pane will scroll to the bottom when input is
#! added.
[ set-pane-scrolls? ] keep
2005-12-16 21:12:35 -05:00
<shelf> over set-pane-prototype
<pile> over set-delegate
<pile> <incremental> over add-output
2005-09-25 00:18:12 -04:00
swap [ "" <editor> over set-pane-input ] when
2005-12-16 21:12:35 -05:00
dup prepare-line dup pane-actions ;
2005-06-27 00:54:49 -04:00
M: pane focusable-child* ( pane -- editor )
2005-09-25 00:18:12 -04:00
pane-input [ t ] unless* ;
2005-08-24 21:52:10 -04:00
: prepare-print ( current -- gadget )
#! Optimization: if line has 1 child, add the child.
dup gadget-children {
{ [ dup empty? ] [ 2drop "" <label> ] }
{ [ dup length 1 = ] [ nip first ] }
{ [ t ] [ drop ] }
} cond ;
2005-08-24 21:52:10 -04:00
2005-12-16 21:12:35 -05:00
M: pane stream-terpri ( pane -- )
dup pane-current prepare-print
over pane-output add-incremental
prepare-line ;
2005-08-24 21:52:10 -04:00
2005-12-16 21:12:35 -05:00
: pane-write ( pane list -- )
2dup car swap pane-current stream-write cdr dup
[ over stream-terpri pane-write ] [ 2drop ] if ;
2005-06-27 00:54:49 -04:00
2005-12-16 21:12:35 -05:00
: pane-format ( style pane list -- )
3dup car -rot pane-current stream-format cdr dup
[ over stream-terpri pane-format ] [ 3drop ] if ;
2005-06-27 00:54:49 -04:00
! Panes are streams.
M: pane stream-flush ( pane -- ) drop ;
M: pane stream-readln ( pane -- line )
2005-09-18 01:37:28 -04:00
[ over set-pane-continuation stop ] callcc1 nip ;
2005-06-27 00:54:49 -04:00
2005-10-10 21:12:53 -04:00
: scroll-pane ( pane -- )
dup pane-scrolls? [ pane-input scroll>caret ] [ drop ] if ;
2005-09-25 00:18:12 -04:00
M: pane stream-write1 ( char pane -- )
2005-12-16 21:12:35 -05:00
[ pane-current stream-write1 ] keep scroll-pane ;
2005-12-16 21:12:35 -05:00
M: pane stream-write ( string style pane -- )
2005-10-10 21:12:53 -04:00
[ rot "\n" split pane-write ] keep scroll-pane ;
2005-06-27 00:54:49 -04:00
2005-12-16 21:12:35 -05:00
M: pane stream-format ( string style pane -- )
[ rot "\n" split pane-format ] keep scroll-pane ;
M: pane stream-break ( pane -- ) pane-current stream-break ;
M: pane stream-close ( pane -- ) drop ;
2005-09-25 00:18:12 -04:00
2005-12-16 21:12:35 -05:00
: ?pane-terpri ( pane -- )
dup pane-current gadget-children empty?
[ dup stream-terpri ] unless drop ;
2005-09-25 00:18:12 -04:00
: make-pane ( quot -- pane )
#! Execute the quotation with output to an output-only pane.
2005-12-16 21:12:35 -05:00
f f <pane> [ swap with-stream ] keep
dup ?pane-terpri pane-output ; inline
: with-pane ( pane quot -- )
#! Clear the pane and run the quotation in a scope with
#! stdio set to the pane.
>r dup pane-clear r> with-stream* ; inline
2005-12-16 21:12:35 -05:00
M: pane with-nested-stream ( style stream quot -- )
-rot >r >r make-pane r> drop r> pane-current add-gadget ;