factor/basis/ui/gadgets/editors/editors.factor

627 lines
17 KiB
Factor
Raw Normal View History

! Copyright (C) 2006, 2009 Slava Pestov
2007-09-20 18:09:08 -04:00
! See http://factorcode.org/license.txt for BSD license.
USING: accessors arrays documents documents.elements kernel math
2009-02-26 17:15:28 -05:00
math.ranges models models.arrow namespaces locals fry make opengl
opengl.gl sequences strings math.vectors math.functions sorting colors
colors.constants combinators assocs math.order calendar alarms
continuations ui.clipboards ui.commands ui.gadgets ui.gadgets.borders
ui.gadgets.buttons ui.gadgets.labels ui.gadgets.scrollers
ui.gadgets.menus ui.gadgets.wrappers ui.render ui.pens.solid
ui.gadgets.line-support ui.text ui.gestures ui.baseline-alignment
2009-03-19 18:36:38 -04:00
math.rectangles splitting unicode.categories grouping ;
EXCLUDE: fonts => selection ;
2007-09-20 18:09:08 -04:00
IN: ui.gadgets.editors
TUPLE: editor < line-gadget
caret-color
2007-09-20 18:09:08 -04:00
caret mark
2008-11-20 23:13:32 -05:00
focused? blink blink-alarm ;
2007-09-20 18:09:08 -04:00
: <loc> ( -- loc ) { 0 0 } <model> ;
2007-09-20 18:09:08 -04:00
: init-editor-locs ( editor -- editor )
<loc> >>caret
<loc> >>mark ; inline
2007-09-20 18:09:08 -04:00
: editor-theme ( editor -- editor )
COLOR: red >>caret-color
monospace-font >>font ; inline
2007-09-20 18:09:08 -04:00
: new-editor ( class -- editor )
new-line-gadget
<document> >>model
init-editor-locs
2008-07-11 01:46:15 -04:00
editor-theme ; inline
2007-10-31 01:04:54 -04:00
: <editor> ( -- editor )
editor new-editor ;
2007-09-20 18:09:08 -04:00
: activate-editor-model ( editor model -- )
2dup add-connection
dup activate-model
swap model>> add-loc ;
2007-09-20 18:09:08 -04:00
: deactivate-editor-model ( editor model -- )
2dup remove-connection
dup deactivate-model
swap model>> remove-loc ;
2007-09-20 18:09:08 -04:00
2008-11-20 23:14:35 -05:00
: blink-caret ( editor -- )
[ not ] change-blink relayout-1 ;
2008-11-21 00:29:16 -05:00
SYMBOL: blink-interval
750 milliseconds blink-interval set-global
2008-11-20 23:14:35 -05:00
: stop-blinking ( editor -- )
2008-11-20 23:15:07 -05:00
[ [ cancel-alarm ] when* f ] change-blink-alarm drop ;
2008-11-20 23:14:35 -05:00
2008-11-30 14:50:09 -05:00
: start-blinking ( editor -- )
[ stop-blinking ] [
t >>blink
dup '[ _ blink-caret ] blink-interval get every
>>blink-alarm drop
] bi ;
2008-11-20 23:14:35 -05:00
: restart-blinking ( editor -- )
dup focused?>> [
[ start-blinking ]
[ relayout-1 ]
2008-11-30 14:50:09 -05:00
bi
2008-11-20 23:14:35 -05:00
] [ drop ] if ;
2007-09-20 18:09:08 -04:00
M: editor graft*
2007-11-14 16:35:17 -05:00
dup
dup caret>> activate-editor-model
dup mark>> activate-editor-model ;
2007-09-20 18:09:08 -04:00
M: editor ungraft*
2007-11-14 16:35:17 -05:00
dup
2008-11-20 23:14:35 -05:00
dup stop-blinking
dup caret>> deactivate-editor-model
dup mark>> deactivate-editor-model ;
2007-09-20 18:09:08 -04:00
: editor-caret ( editor -- loc ) caret>> value>> ;
2007-09-20 18:09:08 -04:00
: editor-mark ( editor -- loc ) mark>> value>> ;
2007-09-20 18:09:08 -04:00
2007-12-30 21:15:59 -05:00
: set-caret ( loc editor -- )
2009-10-04 17:43:00 -04:00
[ model>> validate-loc ] [ caret>> ] bi set-model ;
2007-12-30 21:15:59 -05:00
2007-09-20 18:09:08 -04:00
: change-caret ( editor quot -- )
[ [ [ editor-caret ] [ model>> ] bi ] dip call ] [ drop ] 2bi
2007-12-30 21:15:59 -05:00
set-caret ; inline
2007-09-20 18:09:08 -04:00
: mark>caret ( editor -- )
[ editor-caret ] [ mark>> ] bi set-model ;
2007-09-20 18:09:08 -04:00
: change-caret&mark ( editor quot -- )
2008-11-20 23:13:32 -05:00
[ change-caret ] [ drop mark>caret ] 2bi ; inline
2007-09-20 18:09:08 -04:00
: editor-line ( n editor -- str ) control-value nth ;
:: point>loc ( point editor -- loc )
point second editor y>line {
{ [ dup 0 < ] [ drop { 0 0 } ] }
{ [ dup editor model>> last-line# > ] [ drop editor model>> doc-end ] }
[| n |
n
point first
editor font>>
n editor editor-line
x>offset 2array
]
} cond ;
2007-09-20 18:09:08 -04:00
: clicked-loc ( editor -- loc )
[ hand-rel ] keep point>loc ;
2007-09-20 18:09:08 -04:00
: click-loc ( editor model -- )
2008-11-20 23:13:32 -05:00
[ clicked-loc ] dip set-model ;
2007-09-20 18:09:08 -04:00
2008-11-20 23:13:32 -05:00
: focus-editor ( editor -- )
[ start-blinking ] [ t >>focused? relayout-1 ] bi ;
2008-11-20 23:13:32 -05:00
: unfocus-editor ( editor -- )
[ stop-blinking ] [ f >>focused? relayout-1 ] bi ;
2007-09-20 18:09:08 -04:00
: loc>x ( loc editor -- x )
[ first2 swap ] dip [ editor-line ] [ font>> ] bi swap offset>x round ;
2007-09-20 18:09:08 -04:00
: loc>point ( loc editor -- loc )
2009-02-14 21:46:35 -05:00
[ loc>x ] [ [ first ] dip line>y ceiling ] 2bi 2array ;
2007-09-20 18:09:08 -04:00
: caret-loc ( editor -- loc )
[ editor-caret ] keep loc>point ;
2007-09-20 18:09:08 -04:00
: caret-dim ( editor -- dim )
2009-10-04 17:43:00 -04:00
[ 0 ] dip line-height 2array ;
2007-09-20 18:09:08 -04:00
: scroll>caret ( editor -- )
2008-08-29 19:44:19 -04:00
dup graft-state>> second [
[
2009-04-03 20:50:46 -04:00
[ caret-loc ] [ caret-dim { 2 1 } v+ ] bi <rect>
] keep scroll>rect
] [ drop ] if ;
2007-09-20 18:09:08 -04:00
: draw-caret? ( editor -- ? )
[ focused?>> ] [ blink>> ] bi and ;
: draw-caret ( editor -- )
dup draw-caret? [
2008-11-11 03:31:56 -05:00
[ caret-color>> gl-color ]
[
[ caret-loc ] [ caret-dim ] bi
over v+ gl-line
2008-11-11 03:31:56 -05:00
] bi
] [ drop ] if ;
2007-09-20 18:09:08 -04:00
: selection-start/end ( editor -- start end )
[ editor-mark ] [ editor-caret ] bi sort-pair ;
2007-09-20 18:09:08 -04:00
SYMBOL: selected-lines
2007-09-20 18:09:08 -04:00
TUPLE: selected-line start end first? last? ;
2007-09-20 18:09:08 -04:00
: compute-selection ( editor -- assoc )
dup gadget-selection? [
[ selection-start/end [ [ first ] bi@ [a,b] ] 2keep ] keep model>>
'[ [ _ _ ] keep _ start/end-on-line 2array ] H{ } map>assoc
] [ drop f ] if ;
:: draw-selection ( line pair editor -- )
pair [ editor font>> line offset>x ] map :> pair
editor selection-color>> gl-color
pair first 0 2array
pair second pair first - round 1 max editor line-height 2array
gl-fill-rect ;
: draw-unselected-line ( line editor -- )
font>> swap draw-text ;
: draw-selected-line ( line pair editor -- )
over all-equal? [
[ nip draw-unselected-line ] [ draw-selection ] 3bi
] [
[ draw-selection ]
[
[ [ first2 ] [ selection-color>> ] bi* <selection> ] keep
draw-unselected-line
] 3bi
] if ;
2007-09-20 18:09:08 -04:00
M: editor draw-line ( line index editor -- )
[ selected-lines get at ] dip over
[ draw-selected-line ] [ nip draw-unselected-line ] if ;
2007-09-20 18:09:08 -04:00
M: editor draw-gadget*
dup compute-selection selected-lines [
[ draw-lines ] [ draw-caret ] bi
] with-variable ;
2007-09-20 18:09:08 -04:00
M: editor pref-dim*
! Add some space for the caret.
[ font>> ] [ control-value ] bi text-dim { 1 0 } v+ ;
2007-09-20 18:09:08 -04:00
M: editor baseline font>> font-metrics ascent>> ;
M: editor cap-height font>> font-metrics cap-height>> ;
2008-06-08 16:32:55 -04:00
: contents-changed ( model editor -- )
2008-07-11 01:46:15 -04:00
swap
over caret>> [ over validate-loc ] (change-model)
over mark>> [ over validate-loc ] (change-model)
drop relayout ;
2008-06-08 16:32:55 -04:00
: caret/mark-changed ( model editor -- )
2008-11-20 23:13:32 -05:00
nip [ restart-blinking ] [ scroll>caret ] bi ;
M: editor model-changed
{
2008-07-11 01:46:15 -04:00
{ [ 2dup model>> eq? ] [ contents-changed ] }
{ [ 2dup caret>> eq? ] [ caret/mark-changed ] }
{ [ 2dup mark>> eq? ] [ caret/mark-changed ] }
} cond ;
2007-09-20 18:09:08 -04:00
M: editor gadget-selection?
selection-start/end = not ;
M: editor gadget-selection
2009-10-04 17:43:00 -04:00
[ selection-start/end ] [ model>> ] bi doc-range ;
2007-09-20 18:09:08 -04:00
: remove-selection ( editor -- )
2009-10-04 17:43:00 -04:00
[ selection-start/end ] [ model>> ] bi remove-doc-range ;
2007-09-20 18:09:08 -04:00
M: editor user-input*
2009-10-04 17:43:00 -04:00
[ selection-start/end ] [ model>> ] bi set-doc-range t ;
2007-09-20 18:09:08 -04:00
: editor-string ( editor -- string )
model>> doc-string ;
2007-09-20 18:09:08 -04:00
: set-editor-string ( string editor -- )
model>> set-doc-string ;
2007-09-20 18:09:08 -04:00
M: editor gadget-text* editor-string % ;
: extend-selection ( editor -- )
2008-11-20 23:13:32 -05:00
dup request-focus
dup restart-blinking
dup caret>> click-loc ;
2008-02-06 20:23:39 -05:00
: mouse-elt ( -- element )
hand-click# get {
{ 1 one-char-elt }
{ 2 one-word-elt }
} at one-line-elt or ;
: drag-direction? ( loc editor -- ? )
editor-mark before? ;
: drag-selection-caret ( loc editor element -- loc )
2008-11-20 23:13:32 -05:00
[
[ drag-direction? ] 2keep model>>
] dip prev/next-elt ? ;
: drag-selection-mark ( loc editor element -- loc )
2008-11-20 23:13:32 -05:00
[
2009-10-04 17:43:00 -04:00
[ drag-direction? not ]
[ editor-mark ]
[ model>> ] tri
2008-11-20 23:13:32 -05:00
] dip prev/next-elt ? ;
: drag-caret&mark ( editor -- caret mark )
2009-10-04 17:43:00 -04:00
[ clicked-loc ] [ mouse-elt ] bi
[ drag-selection-caret ]
[ drag-selection-mark ] 3bi ;
: drag-selection ( editor -- )
dup drag-caret&mark
pick mark>> set-model
swap caret>> set-model ;
2007-09-20 18:09:08 -04:00
: editor-cut ( editor clipboard -- )
[ gadget-copy ] [ drop remove-selection ] 2bi ;
2007-09-20 18:09:08 -04:00
: delete/backspace ( editor quot -- )
2007-09-20 18:09:08 -04:00
over gadget-selection? [
drop remove-selection
2007-09-20 18:09:08 -04:00
] [
[ [ [ editor-caret ] [ model>> ] bi ] dip call ]
2008-11-20 23:13:32 -05:00
[ drop model>> ]
2bi remove-doc-range
2007-09-20 18:09:08 -04:00
] if ; inline
: editor-delete ( editor elt -- )
'[ dupd _ next-elt ] delete/backspace ;
2007-09-20 18:09:08 -04:00
: editor-backspace ( editor elt -- )
'[ over [ _ prev-elt ] dip ] delete/backspace ;
2007-09-20 18:09:08 -04:00
: editor-select-prev ( editor elt -- )
'[ _ prev-elt ] change-caret ;
2007-09-20 18:09:08 -04:00
: editor-prev ( editor elt -- )
[ editor-select-prev ] [ drop mark>caret ] 2bi ;
2007-09-20 18:09:08 -04:00
: editor-select-next ( editor elt -- )
'[ _ next-elt ] change-caret ;
2007-09-20 18:09:08 -04:00
: editor-next ( editor elt -- )
dupd editor-select-next mark>caret ;
: editor-select ( from to editor -- )
[ mark>> set-model ] [ caret>> set-model ] bi-curry bi* ;
2007-09-20 18:09:08 -04:00
: select-elt ( editor elt -- )
[ [ [ editor-caret ] [ model>> ] bi ] dip prev/next-elt ] [ drop ] 2bi
2008-11-20 23:13:32 -05:00
editor-select ;
2007-09-20 18:09:08 -04:00
: start-of-document ( editor -- ) doc-elt editor-prev ;
2007-09-20 18:09:08 -04:00
: end-of-document ( editor -- ) doc-elt editor-next ;
2007-09-20 18:09:08 -04:00
: position-caret ( editor -- )
mouse-elt dup one-char-elt =
[ drop dup extend-selection dup mark>> click-loc ]
[ select-elt ] if ;
2007-09-20 18:09:08 -04:00
2008-06-08 16:32:55 -04:00
: delete-next-character ( editor -- )
char-elt editor-delete ;
2007-09-20 18:09:08 -04:00
2008-06-08 16:32:55 -04:00
: delete-previous-character ( editor -- )
char-elt editor-backspace ;
2007-09-20 18:09:08 -04:00
2008-06-08 16:32:55 -04:00
: delete-previous-word ( editor -- )
word-elt editor-delete ;
2007-09-20 18:09:08 -04:00
2008-06-08 16:32:55 -04:00
: delete-next-word ( editor -- )
word-elt editor-backspace ;
2007-09-20 18:09:08 -04:00
2008-06-08 16:32:55 -04:00
: delete-to-start-of-line ( editor -- )
one-line-elt editor-delete ;
2007-09-20 18:09:08 -04:00
2008-06-08 16:32:55 -04:00
: delete-to-end-of-line ( editor -- )
one-line-elt editor-backspace ;
2007-09-20 18:09:08 -04:00
: com-undo ( editor -- )
model>> undo ;
: com-redo ( editor -- )
model>> redo ;
editor "editing" f {
{ undo-action com-undo }
{ redo-action com-redo }
2007-09-20 18:09:08 -04:00
{ T{ key-down f f "DELETE" } delete-next-character }
{ T{ key-down f { S+ } "DELETE" } delete-next-character }
{ T{ key-down f f "BACKSPACE" } delete-previous-character }
{ T{ key-down f { S+ } "BACKSPACE" } delete-previous-character }
{ T{ key-down f { C+ } "DELETE" } delete-previous-word }
{ T{ key-down f { C+ } "BACKSPACE" } delete-next-word }
{ T{ key-down f { A+ } "DELETE" } delete-to-start-of-line }
{ T{ key-down f { A+ } "BACKSPACE" } delete-to-end-of-line }
} define-command-map
: com-paste ( editor -- ) clipboard get paste-clipboard ;
2007-09-20 18:09:08 -04:00
2008-06-08 16:32:55 -04:00
: paste-selection ( editor -- ) selection get paste-clipboard ;
2007-09-20 18:09:08 -04:00
: com-cut ( editor -- ) clipboard get editor-cut ;
2007-09-20 18:09:08 -04:00
editor "clipboard" f {
{ cut-action com-cut }
2009-02-21 17:42:57 -05:00
{ copy-action com-copy }
{ paste-action com-paste }
2007-09-20 18:09:08 -04:00
{ T{ button-up } com-copy-selection }
2009-02-21 17:42:57 -05:00
{ T{ button-up f f 2 } paste-selection }
2007-09-20 18:09:08 -04:00
} define-command-map
: previous-character ( editor -- )
dup gadget-selection? [
dup selection-start/end drop
over set-caret mark>caret
] [
char-elt editor-prev
] if ;
2007-09-20 18:09:08 -04:00
: next-character ( editor -- )
dup gadget-selection? [
dup selection-start/end nip
over set-caret mark>caret
] [
char-elt editor-next
] if ;
2007-09-20 18:09:08 -04:00
: previous-word ( editor -- ) word-elt editor-prev ;
2007-09-20 18:09:08 -04:00
: next-word ( editor -- ) word-elt editor-next ;
2007-09-20 18:09:08 -04:00
: start-of-line ( editor -- ) one-line-elt editor-prev ;
2007-09-20 18:09:08 -04:00
: end-of-line ( editor -- ) one-line-elt editor-next ;
2007-09-20 18:09:08 -04:00
editor "caret-motion" f {
{ T{ button-down } position-caret }
{ T{ key-down f f "LEFT" } previous-character }
{ T{ key-down f f "RIGHT" } next-character }
{ T{ key-down f { C+ } "LEFT" } previous-word }
{ T{ key-down f { C+ } "RIGHT" } next-word }
{ T{ key-down f f "HOME" } start-of-line }
{ T{ key-down f f "END" } end-of-line }
{ T{ key-down f { C+ } "HOME" } start-of-document }
{ T{ key-down f { C+ } "END" } end-of-document }
} define-command-map
2008-12-11 17:47:38 -05:00
: clear-editor ( editor -- )
model>> clear-doc ;
2008-12-11 17:47:38 -05:00
: select-all ( editor -- ) doc-elt select-elt ;
2007-09-20 18:09:08 -04:00
: select-line ( editor -- ) one-line-elt select-elt ;
2007-09-20 18:09:08 -04:00
: select-word ( editor -- ) one-word-elt select-elt ;
2007-09-20 18:09:08 -04:00
: selected-token ( editor -- string )
2007-12-13 16:34:36 -05:00
dup gadget-selection?
[ dup select-word ] unless
gadget-selection ;
2008-06-08 16:32:55 -04:00
: select-previous-character ( editor -- )
char-elt editor-select-prev ;
2007-09-20 18:09:08 -04:00
2008-06-08 16:32:55 -04:00
: select-next-character ( editor -- )
char-elt editor-select-next ;
2007-09-20 18:09:08 -04:00
2008-06-08 16:32:55 -04:00
: select-previous-word ( editor -- )
word-elt editor-select-prev ;
2007-09-20 18:09:08 -04:00
2008-06-08 16:32:55 -04:00
: select-next-word ( editor -- )
word-elt editor-select-next ;
2007-09-20 18:09:08 -04:00
2008-06-08 16:32:55 -04:00
: select-start-of-line ( editor -- )
one-line-elt editor-select-prev ;
2007-09-20 18:09:08 -04:00
2008-06-08 16:32:55 -04:00
: select-end-of-line ( editor -- )
one-line-elt editor-select-next ;
2007-09-20 18:09:08 -04:00
2008-06-08 16:32:55 -04:00
: select-start-of-document ( editor -- )
doc-elt editor-select-prev ;
2007-09-20 18:09:08 -04:00
2008-06-08 16:32:55 -04:00
: select-end-of-document ( editor -- )
doc-elt editor-select-next ;
2007-09-20 18:09:08 -04:00
editor "selection" f {
{ T{ button-down f { S+ } 1 } extend-selection }
{ T{ button-up f { S+ } 1 } com-copy-selection }
{ T{ drag } drag-selection }
{ gain-focus focus-editor }
{ lose-focus unfocus-editor }
{ delete-action remove-selection }
{ select-all-action select-all }
2007-09-20 18:09:08 -04:00
{ T{ key-down f { C+ } "l" } select-line }
{ T{ key-down f { S+ } "LEFT" } select-previous-character }
{ T{ key-down f { S+ } "RIGHT" } select-next-character }
2008-02-10 21:32:26 -05:00
{ T{ key-down f { S+ C+ } "LEFT" } select-previous-word }
{ T{ key-down f { S+ C+ } "RIGHT" } select-next-word }
2007-09-20 18:09:08 -04:00
{ T{ key-down f { S+ } "HOME" } select-start-of-line }
{ T{ key-down f { S+ } "END" } select-end-of-line }
{ T{ key-down f { S+ C+ } "HOME" } select-start-of-document }
{ T{ key-down f { S+ C+ } "END" } select-end-of-document }
} define-command-map
: editor-menu ( editor -- )
{
com-undo
com-redo
----
com-cut
com-copy
com-paste
} show-commands-menu ;
editor "misc" f {
{ T{ button-down f f 3 } editor-menu }
} define-command-map
2007-12-14 01:16:47 -05:00
! Multi-line editors
TUPLE: multiline-editor < editor ;
2007-12-14 01:16:47 -05:00
: <multiline-editor> ( -- editor )
multiline-editor new-editor ;
2007-12-14 01:16:47 -05:00
2009-01-25 23:56:35 -05:00
: previous-line ( editor -- ) line-elt editor-prev ;
: next-line ( editor -- ) line-elt editor-next ;
2009-02-16 02:03:50 -05:00
<PRIVATE
2009-01-25 23:56:35 -05:00
: page-elt ( editor -- editor element ) dup visible-lines 1 - <page-elt> ;
2009-02-16 02:03:50 -05:00
PRIVATE>
: previous-page ( editor -- ) page-elt editor-prev ;
: next-page ( editor -- ) page-elt editor-next ;
: select-previous-line ( editor -- ) line-elt editor-select-prev ;
: select-next-line ( editor -- ) line-elt editor-select-next ;
: select-previous-page ( editor -- ) page-elt editor-select-prev ;
: select-next-page ( editor -- ) page-elt editor-select-next ;
2009-01-25 23:56:35 -05:00
: insert-newline ( editor -- )
"\n" swap user-input* drop ;
: change-selection ( editor quot -- )
'[ gadget-selection @ ] keep user-input* drop ; inline
: join-lines ( string -- string' )
"\n" split
[ rest-slice [ [ blank? ] trim-head-slice ] change-each ]
[ but-last-slice [ [ blank? ] trim-tail-slice ] change-each ]
2009-01-25 23:56:35 -05:00
[ " " join ]
tri ;
: this-line-and-next ( document line -- start end )
[ nip 0 swap 2array ]
[ [ nip 1 + ] [ 1 + swap doc-line length ] 2bi 2array ]
2009-01-25 23:56:35 -05:00
2bi ;
: last-line? ( document line -- ? )
[ last-line# ] dip = ;
: com-join-lines ( editor -- )
dup gadget-selection?
[ [ join-lines ] change-selection ] [
[ model>> ] [ editor-caret first ] bi
2dup last-line? [ 2drop ] [
[ this-line-and-next ] [ drop ] 2bi
[ join-lines ] change-doc-range
] if
] if ;
multiline-editor "multiline" f {
{ T{ key-down f f "UP" } previous-line }
{ T{ key-down f f "DOWN" } next-line }
{ T{ key-down f { S+ } "UP" } select-previous-line }
{ T{ key-down f { S+ } "DOWN" } select-next-line }
2009-02-16 02:03:50 -05:00
{ T{ key-down f f "PAGE_UP" } previous-page }
{ T{ key-down f f "PAGE_DOWN" } next-page }
{ T{ key-down f { S+ } "PAGE_UP" } select-previous-page }
{ T{ key-down f { S+ } "PAGE_DOWN" } select-next-page }
2007-12-14 01:16:47 -05:00
{ T{ key-down f f "RET" } insert-newline }
{ T{ key-down f { S+ } "RET" } insert-newline }
{ T{ key-down f f "ENTER" } insert-newline }
2009-01-25 23:56:35 -05:00
{ T{ key-down f { C+ } "j" } com-join-lines }
2007-12-14 01:16:47 -05:00
} define-command-map
2008-07-11 16:07:46 -04:00
TUPLE: source-editor < multiline-editor ;
2007-12-14 01:16:47 -05:00
: <source-editor> ( -- editor )
source-editor new-editor ;
! A useful model
: <element-model> ( editor element -- model )
[ [ caret>> ] [ model>> ] bi ] dip
2009-02-26 17:15:28 -05:00
'[ _ _ elt-string ] <arrow> ;
2008-12-11 17:47:38 -05:00
! Fields wrap an editor
TUPLE: field < border editor min-cols max-cols ;
2007-12-14 01:16:47 -05:00
: field-theme ( gadget -- gadget )
{ 2 2 } >>size
{ 1 0 } >>fill
COLOR: gray <solid> >>boundary ; inline
2007-11-01 13:50:02 -04:00
: <field-border> ( gadget -- border )
{ 2 2 } <border>
{ 1 0 } >>fill
field-theme ;
2007-11-01 13:50:02 -04:00
2008-12-11 17:47:38 -05:00
: new-field ( class -- gadget )
[ <editor> ] dip new-border
dup gadget-child >>editor
field-theme ; inline
2008-12-11 17:47:38 -05:00
! For line-gadget-width
M: field font>> editor>> font>> ;
2008-12-11 17:47:38 -05:00
M: field pref-dim*
dup
[ editor>> pref-dim ] keep
[ line-gadget-width ] [ drop second ] 2bi 2array
border-pref-dim ;
2008-12-11 17:47:38 -05:00
TUPLE: model-field < field field-model ;
: <model-field> ( model -- gadget )
model-field new-field swap >>field-model ;
2007-11-01 13:50:02 -04:00
2008-12-11 17:47:38 -05:00
M: model-field graft*
2008-08-31 17:19:24 -04:00
[ [ field-model>> value>> ] [ editor>> ] bi set-editor-string ]
[ dup editor>> model>> add-connection ]
bi ;
2007-11-01 13:50:02 -04:00
2008-12-11 17:47:38 -05:00
M: model-field ungraft*
dup editor>> model>> remove-connection ;
2007-11-01 13:50:02 -04:00
2008-12-11 17:47:38 -05:00
M: model-field model-changed
nip [ editor>> editor-string ] [ field-model>> ] bi set-model ;
2008-12-11 17:47:38 -05:00
TUPLE: action-field < field quot ;
: <action-field> ( quot -- gadget )
action-field new-field swap >>quot ;
: invoke-action-field ( field -- )
[ editor>> editor-string ]
[ editor>> clear-editor ]
[ quot>> ]
tri call( string -- ) ;
2008-12-11 17:47:38 -05:00
action-field H{
{ T{ key-down f f "RET" } [ invoke-action-field ] }
} set-gestures