Blinking cursor

db4
Slava Pestov 2008-11-20 22:13:32 -06:00
parent f24036834e
commit 17b2566017
1 changed files with 61 additions and 34 deletions

View File

@ -2,17 +2,17 @@
! See http://factorcode.org/license.txt for BSD license.
USING: accessors arrays documents io kernel math models
namespaces make opengl opengl.gl sequences strings io.styles
math.vectors sorting colors combinators assocs math.order
ui.clipboards ui.commands ui.gadgets ui.gadgets.borders
ui.gadgets.buttons ui.gadgets.labels ui.gadgets.scrollers
ui.gadgets.theme ui.gadgets.wrappers ui.render ui.gestures
math.geometry.rect ;
math.vectors sorting colors combinators assocs math.order fry
calendar alarms ui.clipboards ui.commands ui.gadgets
ui.gadgets.borders ui.gadgets.buttons ui.gadgets.labels
ui.gadgets.scrollers ui.gadgets.theme ui.gadgets.wrappers
ui.render ui.gestures math.geometry.rect ;
IN: ui.gadgets.editors
TUPLE: editor < gadget
font color caret-color selection-color
caret mark
focused? ;
focused? blink blink-alarm ;
: <loc> ( -- loc ) { 0 0 } <model> ;
@ -64,14 +64,14 @@ M: editor ungraft*
caret>> set-model ;
: change-caret ( editor quot -- )
over >r >r dup editor-caret* swap model>> r> call r>
[ [ [ editor-caret* ] [ model>> ] bi ] dip call ] [ drop ] 2bi
set-caret ; inline
: mark>caret ( editor -- )
dup editor-caret* swap mark>> set-model ;
[ editor-caret* ] [ mark>> ] bi set-model ;
: change-caret&mark ( editor quot -- )
over >r change-caret r> mark>caret ; inline
[ change-caret ] [ drop mark>caret ] 2bi ; inline
: editor-line ( n editor -- str ) control-value nth ;
@ -85,8 +85,8 @@ M: editor ungraft*
: point>loc ( point editor -- loc )
[
>r first2 r> tuck y>line dup ,
>r dup editor-font* r>
[ first2 ] dip tuck y>line dup ,
[ dup editor-font* ] dip
rot editor-line x>offset ,
] { } make ;
@ -94,11 +94,35 @@ M: editor ungraft*
[ hand-rel ] keep point>loc ;
: click-loc ( editor model -- )
>r clicked-loc r> set-model ;
[ clicked-loc ] dip set-model ;
: focus-editor ( editor -- ) t >>focused? relayout-1 ;
: blink-caret ( editor -- )
[ not ] change-blink relayout-1 ;
: unfocus-editor ( editor -- ) f >>focused? relayout-1 ;
: start-blinking ( editor -- )
t >>blink
dup '[ _ blink-caret ] 750 milliseconds every >>blink-alarm drop ;
: stop-blinking ( editor -- )
blink-alarm>> cancel-alarm ;
: restart-blinking ( editor -- )
dup focused?>> [
[ stop-blinking ]
[ start-blinking ]
[ relayout-1 ]
tri
] [ drop ] if ;
: focus-editor ( editor -- )
dup start-blinking
t >>focused?
relayout-1 ;
: unfocus-editor ( editor -- )
dup stop-blinking
f >>focused?
relayout-1 ;
: (offset>x) ( font col# str -- x )
swap head-slice string-width ;
@ -106,7 +130,7 @@ M: editor ungraft*
: offset>x ( col# line# editor -- x )
[ editor-line ] keep editor-font* -rot (offset>x) ;
: loc>x ( loc editor -- x ) >r first2 swap r> offset>x ;
: loc>x ( loc editor -- x ) [ first2 swap ] dip offset>x ;
: line>y ( lines# editor -- y )
line-height * ;
@ -126,7 +150,7 @@ M: editor ungraft*
] [ drop ] if ;
: draw-caret ( -- )
editor get focused?>> [
editor get [ focused?>> ] [ blink>> ] bi and [
editor get
[ caret-color>> gl-color ]
[
@ -143,7 +167,7 @@ M: editor ungraft*
line-translation gl-translate ;
: draw-line ( editor str -- )
>r font>> r> { 0 0 } draw-string ;
[ font>> ] dip { 0 0 } draw-string ;
: first-visible-line ( editor -- n )
clip get rect-loc second origin get second -
@ -169,7 +193,7 @@ M: editor ungraft*
rot control-value <slice> ;
: with-editor-translation ( n quot -- )
>r line-translation origin get v+ r> with-translation ;
[ line-translation origin get v+ ] dip with-translation ;
inline
: draw-lines ( -- )
@ -199,7 +223,7 @@ M: editor ungraft*
editor get selection-start/end
over first [
2dup [
>r 2dup r> draw-selected-line
[ 2dup ] dip draw-selected-line
1 translate-lines
] each-line 2drop
] with-editor-translation ;
@ -217,7 +241,7 @@ M: editor pref-dim*
drop relayout ;
: caret/mark-changed ( model editor -- )
nip [ relayout-1 ] [ scroll>caret ] bi ;
nip [ restart-blinking ] [ scroll>caret ] bi ;
M: editor model-changed
{
@ -247,7 +271,9 @@ M: editor user-input*
M: editor gadget-text* editor-string % ;
: extend-selection ( editor -- )
dup request-focus dup caret>> click-loc ;
dup request-focus
dup restart-blinking
dup caret>> click-loc ;
: mouse-elt ( -- element )
hand-click# get {
@ -259,14 +285,15 @@ M: editor gadget-text* editor-string % ;
editor-mark* before? ;
: drag-selection-caret ( loc editor element -- loc )
>r [ drag-direction? ] 2keep
model>>
r> prev/next-elt ? ;
[
[ drag-direction? ] 2keep model>>
] dip prev/next-elt ? ;
: drag-selection-mark ( loc editor element -- loc )
>r [ drag-direction? not ] 2keep
nip dup editor-mark* swap model>>
r> prev/next-elt ? ;
[
[ drag-direction? not ] keep
[ editor-mark* ] [ model>> ] bi
] dip prev/next-elt ? ;
: drag-caret&mark ( editor -- caret mark )
dup clicked-loc swap mouse-elt
@ -285,15 +312,16 @@ M: editor gadget-text* editor-string % ;
over gadget-selection? [
drop nip remove-selection
] [
over >r >r dup editor-caret* swap model>>
r> call r> model>> remove-doc-range
[ [ [ editor-caret* ] [ model>> ] bi ] dip call ]
[ drop model>> ]
2bi remove-doc-range
] if ; inline
: editor-delete ( editor elt -- )
swap [ over >r rot next-elt r> swap ] delete/backspace ;
swap [ over [ rot next-elt ] dip swap ] delete/backspace ;
: editor-backspace ( editor elt -- )
swap [ over >r rot prev-elt r> ] delete/backspace ;
swap [ over [ rot prev-elt ] dip ] delete/backspace ;
: editor-select-prev ( editor elt -- )
swap [ rot prev-elt ] change-caret ;
@ -311,9 +339,8 @@ M: editor gadget-text* editor-string % ;
tuck caret>> set-model mark>> set-model ;
: select-elt ( editor elt -- )
over >r
>r dup editor-caret* swap model>> r> prev/next-elt
r> editor-select ;
[ [ [ editor-caret* ] [ model>> ] bi ] dip prev/next-elt ] [ drop ] 2bi
editor-select ;
: start-of-document ( editor -- ) T{ doc-elt } editor-prev ;