| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176 |
- Namespace mojox
- Alias TextHighlighter:Int( text:String,colors:Byte[],sol:Int,eol:Int,state:Int )
- #rem monkeydoc The TextDocument class.
- #end
- Class TextDocument
- #rem monkeydoc Invoked when text has changed.
- #end
- Field TextChanged:Void()
- #rem monkeydoc Invoked when lines modified.
- #end
- Field LinesModified:Void( first:Int,removed:Int,inserted:Int )
-
- #rem monkeydoc Creates a new text document.
- #end
- Method New()
-
- _lines.Push( New Line )
- End
- #rem monkeydoc Document text.
- #end
- Property Text:String()
-
- Return _text
-
- Setter( text:String )
-
- text=text.Replace( "~r~n","~n" )
- text=text.Replace( "~r","~n" )
-
- ReplaceText( 0,_text.Length,text )
- End
-
- #rem monkeydoc Length of doucment text.
- #end
- Property TextLength:Int()
-
- Return _text.Length
- End
-
- #rem monkeydoc Number of lines in document.
- #end
- Property NumLines:Int()
-
- Return _lines.Length
- End
- #rem monkeydoc @hidden
- #end
- Property Colors:Byte[]()
-
- Return _colors.Data
- End
-
- #rem monkeydoc @hidden
- #end
- Property TextHighlighter:TextHighlighter()
-
- Return _highlighter
-
- Setter( textHighlighter:TextHighlighter )
-
- _highlighter=textHighlighter
- End
-
- #rem monkeydoc @hidden
- #end
- Method LineState:Int( line:Int )
- If line>=0 And line<_lines.Length Return _lines[line].state
- Return -1
- End
-
- #rem monkeydoc Gets the index of the first character on a line.
- #end
- Method StartOfLine:Int( line:Int )
- If line<=0 Return 0
- If line<_lines.Length Return _lines[line-1].eol+1
- Return _text.Length
- End
-
- #rem monkeydoc Gets the index of the last character on a line.
- #end
- Method EndOfLine:Int( line:Int )
- If line<0 Return 0
- If line<_lines.Length Return _lines[line].eol
- Return _text.Length
- End
-
- #rem monkeydoc Finds the line containing a character.
- #end
- Method FindLine:Int( index:Int )
-
- If index<=0 Return 0
- If index>=_text.Length Return _lines.Length-1
-
- Local min:=0,max:=_lines.Length-1
-
- Repeat
- Local line:=(min+max)/2
- If index>_lines[line].eol
- min=line+1
- Else If max-min<2
- Return min
- Else
- max=line
- Endif
- Forever
- Return 0
- End
- #rem monkeydoc Gets line text.
- #end
- Method GetLine:String( line:Int )
- Return _text.Slice( StartOfLine( line ),EndOfLine( line ) )
- End
- #rem monkeydoc Appends text to the end of the document.
- #end
- Method AppendText( text:String )
-
- ReplaceText( _text.Length,_text.Length,text )
- End
-
- #rem monkeydoc Replaces text in the document.
- #end
- Method ReplaceText( anchor:Int,cursor:Int,text:String )
-
- Local min:=Min( anchor,cursor )
- Local max:=Max( anchor,cursor )
-
- Local eols1:=0,eols2:=0
- For Local i:=min Until max
- If _text[i]=10 eols1+=1
- Next
- For Local i:=0 Until text.Length
- If text[i]=10 eols2+=1
- Next
-
- Local dlines:=eols2-eols1
- Local dchars:=text.Length-(max-min)
-
- Local line0:=FindLine( min )
- Local line:=line0
- Local eol:=StartOfLine( line )-1
-
- ' Print "eols1="+eols1+", eols2="+eols2+", dlines="+dlines+", dchars="+dchars+" text="+text.Length
-
- 'Move data!
- '
- Local oldlen:=_text.Length
- _text=_text.Slice( 0,min )+text+_text.Slice( max )
-
- _colors.Resize( _text.Length )
- Local p:=_colors.Data.Data
- libc.memmove( p + min + text.Length, p + max , oldlen-max )
- libc.memset( p + min , 0 , text.Length )
-
- 'Update lines
- '
- If dlines>=0
-
- _lines.Resize( _lines.Length+dlines )
- Local i:=_lines.Length
- While i>line+eols2+1
- i-=1
- _lines.Data[i].eol=_lines[i-dlines].eol+dchars
- _lines.Data[i].state=_lines[i-dlines].state
- Wend
-
- Endif
- For Local i:=0 Until eols2+1
- eol=_text.Find( "~n",eol+1 )
- If eol=-1 eol=_text.Length
- _lines.Data[line+i].eol=eol
- _lines.Data[line+i].state=-1
- Next
-
- If dlines<0
- Local i:=line+eols2+1
- While i<_lines.Length+dlines
- _lines.Data[i].eol=_lines[i-dlines].eol+dchars
- _lines.Data[i].state=_lines[i-dlines].state
- i+=1
- Wend
- _lines.Resize( _lines.Length+dlines )
- Endif
- If _highlighter<>Null
-
- 'update highlighting
- '
- Local state:=-1
- If line state=_lines[line-1].state
-
- For Local i:=0 Until eols2+1
- state=_highlighter( _text,_colors.Data,StartOfLine( line ),EndOfLine( line ),state )
- _lines.Data[line].state=state
- line+=1
- Next
-
- While line<_lines.Length 'And state<>_lines[line].state
- state=_highlighter( _text,_colors.Data,StartOfLine( line ),EndOfLine( line ),state )
- _lines.Data[line].state=state
- line+=1
- End
- Endif
-
- LinesModified( line0,eols1+1,eols2+1 )
-
- TextChanged()
- End
-
- Private
-
- Struct Line
- Field eol:Int
- Field state:Int
- End
-
- Field _text:String
-
- Field _lines:=New Stack<Line>
- Field _colors:=New Stack<Byte>
- Field _highlighter:TextHighlighter
-
-
- End
- #rem monkeydoc The TextView class.
- #end
- Class TextView Extends ScrollableView
- #rem monkeydoc Invoked when cursor moves.
- #end
- Field CursorMoved:Void()
- #rem monkeydoc Creates a new text view.
- #end
- Method New()
- Style=GetStyle( "TextView" )
- _doc=New TextDocument
-
- _textColors=New Color[8]
-
- For Local i:=0 Until 7
- _textColors[i]=App.Theme.GetColor( "textview-color"+i )
- Next
- End
- Method New( text:String )
- Self.New()
-
- Document.Text=text
- End
-
- Method New( doc:TextDocument )
- Self.New()
-
- _doc=doc
- End
- #rem monkeydoc Text document.
- #end
- Property Document:TextDocument()
-
- Return _doc
-
- Setter( doc:TextDocument )
-
- _doc=doc
-
- _cursor=Clamp( _cursor,0,_doc.TextLength )
- _anchor=_cursor
-
- UpdateCursor()
- End
-
- #rem monkeydoc Text colors.
- #end
- Property TextColors:Color[]()
-
- Return _textColors
-
- Setter( textColors:Color[] )
-
- _textColors=textColors
- End
-
- #rem monkeydoc Selection color.
- #end
- Property SelectionColor:Color()
-
- Return _selColor
-
- Setter( selectionColor:Color )
-
- _selColor=selectionColor
- End
-
- #rem monkeydoc Cursor color.
- #end
- Property CursorColor:Color()
-
- Return _cursorColor
-
- Setter( cursorColor:Color )
- _cursorColor=cursorColor
- End
-
- #rem monkeydoc Block cursor flag.
- #end
- Property BlockCursor:Bool()
-
- Return _blockCursor
-
- Setter( blockCursor:Bool )
-
- _blockCursor=blockCursor
- End
- #rem monkeydoc Text.
- #end
- Property Text:String()
-
- Return _doc.Text
-
- Setter( text:String )
-
- _doc.Text=text
- End
-
- #rem monkeydoc Read only flags.
- #end
- Property ReadOnly:Bool()
-
- Return _readOnly
-
- Setter( readOnly:Bool )
-
- _readOnly=readOnly
- End
-
- #rem monkeydoc Tabstop.
- #end
- Property TabStop:Int()
-
- Return _tabStop
-
- Setter( tabStop:Int )
-
- _tabStop=tabStop
-
- InvalidateStyle()
- End
-
- #rem monkeydoc Cursor character index.
- #end
- Property Cursor:Int()
-
- Return _cursor
- End
-
- #rem monkeydoc Anchor character index.
- #end
- Property Anchor:Int()
-
- Return _anchor
- End
- #rem monkeydoc Cursor column.
- #end
- Property CursorColumn:Int()
-
- Return Column( _cursor )
- End
-
- #rem monkeydoc Cursor row.
- #end
- Property CursorRow:Int()
-
- Return Row( _cursor )
- End
-
- #rem monkeydoc Cursor rect.
- #end
- Property CursorRect:Recti()
- Return _cursorRect
- End
-
- #rem monkeydoc Approximate character width.
- #end
- Property CharWidth:Int()
-
- Return _charw
- End
-
- #rem monkeydoc Line height.
- #end
- Property LineHeight:Int()
-
- Return _charh
- End
- #rem monkeydoc True if undo available.
- #end
- Property CanUndo:Bool()
-
- Return Not _readOnly And Not _undos.Empty
- End
-
- #rem monkeydoc True if redo available.
- #end
- Property CanRedo:Bool()
-
- Return Not _readOnly And Not _redos.Empty
- End
-
- #rem monkeydoc True if cut available.
- #end
- Property CanCut:Bool()
-
- Return Not _readOnly And _anchor<>_cursor
- End
-
- #rem monkeydoc True if copy available.
- #end
- Property CanCopy:Bool()
-
- Return _anchor<>_cursor
- End
-
- #rem monkeydoc True if paste available.
- #end
- Property CanPaste:Bool()
-
- Return Not _readOnly And Not App.ClipboardTextEmpty
- End
-
- #rem monkeydoc Clears all text.
- #end
- Method Clear()
- SelectAll()
- ReplaceText( "" )
- End
-
- #rem monkeydoc Move cursor to line.
- #end
- Method GotoLine( line:Int )
-
- _anchor=_doc.StartOfLine( line )
- _cursor=_anchor
-
- UpdateCursor()
- End
-
- #rem monkeydoc Selects text in a range.
- #end
- Method SelectText( anchor:Int,cursor:Int )
- _anchor=Clamp( anchor,0,_doc.TextLength )
- _cursor=Clamp( cursor,0,_doc.TextLength )
-
- UpdateCursor()
- End
-
- #rem monkeydoc Appends text.
- #end
- Method AppendText( text:String )
-
- ' Local anchor:=_anchor
- ' Local cursor:=_cursor
-
- SelectText( _doc.TextLength,_doc.TextLength )
- ReplaceText( text )
-
- ' SelectText( anchor,cursor )
- End
-
- #rem monkeydoc Replaces current selection.
- #end
- Method ReplaceText( text:String )
-
- Local undo:=New UndoOp
- undo.text=_doc.Text.Slice( Min( _anchor,_cursor ),Max( _anchor,_cursor ) )
- undo.anchor=Min( _anchor,_cursor )
- undo.cursor=undo.anchor+text.Length
- _undos.Push( undo )
-
- ReplaceText( _anchor,_cursor,text )
- End
-
- 'non-undoable
- #rem monkeydoc @hidden
- #end
- Method ReplaceText( anchor:Int,cursor:Int,text:String )
-
- _redos.Clear()
-
- _doc.ReplaceText( anchor,cursor,text )
- _cursor=Min( anchor,cursor )+text.Length
- _anchor=_cursor
-
- UpdateCursor()
- End
-
- #rem monkeydoc Performs an undo.
- #end
- Method Undo()
- If _readOnly Return
-
- If _undos.Empty Return
-
- Local undo:=_undos.Pop()
- Local text:=undo.text
- Local anchor:=undo.anchor
- Local cursor:=undo.cursor
-
- undo.text=_doc.Text.Slice( anchor,cursor )
- undo.cursor=anchor+text.Length
-
- _redos.Push( undo )
-
- _doc.ReplaceText( anchor,cursor,text )
- _cursor=anchor+text.Length
- _anchor=_cursor
-
- UpdateCursor()
- End
-
- #rem monkeydoc Performs a redo.
- #end
- Method Redo()
- If _readOnly Return
-
- If _redos.Empty Return
- Local undo:=_redos.Pop()
-
- Local text:=undo.text
- Local anchor:=undo.anchor
- Local cursor:=undo.cursor
-
- undo.text=_doc.Text.Slice( anchor,cursor )
- undo.cursor=anchor+text.Length
-
- _undos.Push( undo )
-
- _doc.ReplaceText( anchor,cursor,text )
- _cursor=anchor+text.Length
- _anchor=_cursor
-
- UpdateCursor()
- End
-
- #rem monkeydoc Selects all text.
- #end
- Method SelectAll()
- SelectText( 0,_doc.TextLength )
- End
-
- #rem monkeydoc Performs a cut.
- #end
- Method Cut()
- If _readOnly Return
- Copy()
- ReplaceText( "" )
- End
-
- #rem monkeydoc Performs a copy.
- #end
- Method Copy()
- Local min:=Min( _anchor,_cursor )
- Local max:=Max( _anchor,_cursor )
- Local text:=_doc.Text.Slice( min,max )
- App.ClipboardText=text
- End
-
- #rem monkeydoc Performs a paste.
- #end
- Method Paste()
-
- If _readOnly Return
-
- If App.ClipboardTextEmpty Return
-
- Local text:String=App.ClipboardText
- text=text.Replace( "~r~n","~n" )
- text=text.Replace( "~r","~n" )
-
- If text ReplaceText( text )
- End
-
- Private
-
- Class UndoOp
- Field text:String
- Field anchor:Int
- Field cursor:Int
- End
-
- Field _doc:TextDocument
- Field _tabStop:Int=4
- Field _tabSpaces:String=" "
- Field _cursorColor:Color=New Color( 0,.5,1,1 )
- Field _selColor:Color=New Color( 1,1,1,.25 )
- Field _blockCursor:Bool=True
-
- #if __HOSTOS__="macos"
- Field _macosMode:Bool=True
- #else
- Field _macosMode:Bool=False
- #endif
-
- Field _textColors:Color[]
-
- Field _anchor:Int
- Field _cursor:Int
-
- Field _font:Font
- Field _charw:Int
- Field _charh:Int
- Field _tabw:Int
-
- Field _cursorRect:Recti
- Field _columnX:Int
-
- Field _undos:=New Stack<UndoOp>
- Field _redos:=New Stack<UndoOp>
-
- Field _dragging:Bool
-
- Field _readOnly:Bool
-
- Method Row:Int( index:Int )
- Return _doc.FindLine( index )
- End
-
- Method Column:Int( index:Int )
- Return index-_doc.StartOfLine( _doc.FindLine( index ) )
- End
-
- Method UpdateCursor()
-
- ValidateStyle()
-
- Local rect:=MakeCursorRect( _cursor )
-
- EnsureVisible( rect )
-
- If rect<>_cursorRect
-
- _cursorRect=rect
- _columnX=rect.X
-
- CursorMoved()
- Endif
-
- RequestRender()
- End
-
- Method MakeCursorRect:Recti( cursor:Int )
-
- ValidateStyle()
-
- Local line:=_doc.FindLine( cursor )
- Local text:=_doc.GetLine( line )
-
- Local x:=0.0,i0:=0,e:=cursor-_doc.StartOfLine( line )
-
- While i0<e
-
- Local i1:=text.Find( "~t",i0 )
- If i1=-1 i1=e
-
- If i1>i0
- If i1>e i1=e
- x+=_font.TextWidth( text.Slice( i0,i1 ) )
- If i1=e Exit
- Endif
-
- x=Int( (x+_tabw)/_tabw ) * _tabw
- i0=i1+1
-
- Wend
-
- Local w:=_charw
-
- If e<text.Length
- If text[e]=9
- ' w=Int( (x+_tabw)/_tabw ) * _tabw-x
- Else
- w=_font.TextWidth( text.Slice( e,e+1 ) )
- Endif
- Endif
-
- Local y:=line*_charh
-
- Return New Recti( x,y,x+w,y+_charh )
- End
-
- Method PointXToIndex:Int( px:Int,line:Int )
-
- ValidateStyle()
- Local text:=_doc.GetLine( line )
- Local sol:=_doc.StartOfLine( line )
-
- Local x:=0.0,i0:=0,e:=text.Length
-
- While i0<e
-
- Local i1:=text.Find( "~t",i0 )
- If i1=-1 i1=e
-
- If i1>i0
- For Local i:=i0 Until i1
- x+=_font.TextWidth( text.Slice( i,i+1 ) )
- If px<x Return sol+i
- Next
- If i1=e Exit
- Endif
-
- x=Int( (x+_tabw)/_tabw ) * _tabw
- If px<x Return sol+i0
-
- i0=i1+1
- Wend
-
- Return sol+e
-
- End
-
- Method PointToIndex:Int( p:Vec2i )
-
- If p.y<0 Return 0
-
- Local line:=p.y/_charh
- If line>_doc.NumLines Return _doc.TextLength
-
- Return PointXToIndex( p.x,line )
- End
-
- Method MoveLine( delta:Int )
-
- Local line:=Clamp( Row( _cursor )+delta,0,_doc.NumLines-1 )
-
- _cursor=PointXToIndex( _columnX,line )
-
- Local x:=_columnX
-
- UpdateCursor()
-
- _columnX=x
- End
-
- Protected
-
- Method OnValidateStyle() Override
-
- Local style:=RenderStyle
-
- _font=style.Font
-
- _charw=_font.TextWidth( "X" )
- _charh=_font.Height
-
- _tabw=_charw*_tabStop
-
- UpdateCursor()
- End
-
- Method OnMeasureContent:Vec2i() Override
- Return New Vec2i( 320*_charw,_doc.NumLines*_charh )
- ' Return New Vec2i( 160,_doc.NumLines*_charh )
- End
- Method OnRenderContent( canvas:Canvas ) Override
-
- Local clip:=VisibleRect
-
- Local firstVisLine:=Max( clip.Top/_charh,0 )
- Local lastVisLine:=Min( (clip.Bottom-1)/_charh+1,_doc.NumLines )
-
- If _cursor<>_anchor
-
- Local min:=MakeCursorRect( Min( _anchor,_cursor ) )
- Local max:=MakeCursorRect( Max( _anchor,_cursor ) )
-
- canvas.Color=_selColor
-
- If min.Y=max.Y
- canvas.DrawRect( min.Left,min.Top,max.Left-min.Left,min.Height )
- Else
- canvas.DrawRect( min.Left,min.Top,(clip.Right-min.Left),min.Height )
- canvas.DrawRect( 0,min.Bottom,clip.Right,max.Top-min.Bottom )
- canvas.DrawRect( 0,max.Top,max.Left,max.Height )
- Endif
-
- Else If Not _readOnly And App.KeyView=Self
-
- canvas.Color=_cursorColor
-
- If _blockCursor
- canvas.DrawRect( _cursorRect.X,_cursorRect.Y,_cursorRect.Width,_cursorRect.Height )
- Else
- canvas.DrawRect( _cursorRect.X-0,_cursorRect.Y,2,_cursorRect.Height )
- canvas.DrawRect( _cursorRect.X-2,_cursorRect.Y,6,2 )
- canvas.DrawRect( _cursorRect.X-2,_cursorRect.Y+_cursorRect.Height-2,6,2 )
- Endif
-
- Endif
- _textColors[0]=RenderStyle.TextColor
-
- For Local line:=firstVisLine Until lastVisLine
-
- Local sol:=_doc.StartOfLine( line )
- Local eol:=_doc.EndOfLine( line )
- Local text:=_doc.Text.Slice( sol,eol )
- Local colors:=_doc.Colors
-
- Local x:=0,y:=line*_charh,i0:=0
-
- While i0<text.Length
-
- Local i1:=text.Find( "~t",i0 )
- If i1=-1 i1=text.Length
-
- If i1>i0
-
- Local color:=colors[sol+i0]
- Local start:=i0
-
- Repeat
-
- While i0<i1 And colors[sol+i0]=color
- i0+=1
- Wend
-
- If i0>start
- If color<0 Or color>=_textColors.Length color=0
- canvas.Color=_textColors[color]
-
- Local t:=text.Slice( start,i0 )
- canvas.DrawText( t,x,y )
- x+=Style.Font.TextWidth( t )
- Endif
-
- If i0=i1 Exit
-
- color=colors[sol+i0]
- start=i0
- i0+=1
-
- Forever
-
- If i1=text.Length Exit
-
- Endif
-
- x=Int( (x+_tabw) / _tabw ) * _tabw
-
- i0=i1+1
-
- Wend
-
- Next
-
- End
-
- Method OnKeyDown:Bool( key:Key,modifiers:Modifier=Null )
-
- Select key
- Case Key.Backspace
-
- If _anchor=_cursor And _cursor>0 SelectText( _cursor-1,_cursor )
- ReplaceText( "" )
-
- Case Key.KeyDelete
-
- If _anchor=_cursor And _cursor<_doc.Text.Length SelectText( _cursor,_cursor+1 )
- ReplaceText( "" )
-
- Case Key.Tab
-
- Local min:=_doc.FindLine( Min( _cursor,_anchor ) )
- Local max:=_doc.FindLine( Max( _cursor,_anchor ) )
-
- If min=max
- ReplaceText( "~t" )
- Else
-
- 'block tab/untab
- Local lines:=New StringStack
-
- For Local i:=min Until max
- lines.Push( _doc.GetLine( i ) )
- Next
-
- Local go:=True
-
- If modifiers & Modifier.Shift
-
- For Local i:=0 Until lines.Length
-
- If Not lines[i].Trim()
- lines[i]+="~n"
- Continue
- Endif
-
- If lines[i][0]=9
- lines[i]=lines[i].Slice( 1 )+"~n"
- Continue
- Endif
-
- go=False
- Exit
- Next
- Else
-
- For Local i:=0 Until lines.Length
- lines[i]="~t"+lines[i]+"~n"
- Next
- Endif
-
- If go
- SelectText( _doc.StartOfLine( min ),_doc.StartOfLine( max ) )
- ReplaceText( lines.Join( "" ) )
- SelectText( _doc.StartOfLine( min ),_doc.StartOfLine( max ) )
- Return False
- Endif
-
- Endif
-
- Case Key.Enter
-
- ReplaceText( "~n" )
-
- 'auto indent!
- Local line:=CursorRow
- If line>0
-
- Local ptext:=_doc.GetLine( line-1 )
-
- Local indent:=ptext
- For Local i:=0 Until ptext.Length
- If ptext[i]<=32 Continue
- indent=ptext.Slice( 0,i )
- Exit
- Next
-
- If indent ReplaceText( indent )
-
- Endif
-
- Case Key.Left
-
- If _cursor
- _cursor-=1
- UpdateCursor()
- Endif
-
- Case Key.Right
-
- If _cursor<_doc.Text.Length
- _cursor+=1
- UpdateCursor()
- Endif
-
- Case Key.Home
-
- _cursor=_doc.StartOfLine( Row( _cursor ) )
- UpdateCursor()
-
- Case Key.KeyEnd
-
- _cursor=_doc.EndOfLine( Row( _cursor ) )
- UpdateCursor()
- Case Key.Up
-
- MoveLine( -1 )
-
- Case Key.Down
-
- MoveLine( 1 )
-
- Case Key.PageUp
-
- Local n:=VisibleRect.Height/_charh-1 'shouldn't really use cliprect here...
- MoveLine( -n )
-
- Case Key.PageDown
-
- Local n:=VisibleRect.Height/_charh-1
- MoveLine( n )
-
- Default
- Return False
- End
-
- Return True
- End
-
- Method OnControlKeyDown:bool( key:Key )
- Select key
- Case Key.A
- SelectAll()
- Case Key.X
- Cut()
- Case Key.C
- Copy()
- Case Key.V
- Paste()
- Case Key.Z
- Undo()
- Case Key.Y
- Redo()
- Case Key.Home
- _cursor=0
- UpdateCursor()
- Return True
- Case Key.KeyEnd
- _cursor=_doc.TextLength
- UpdateCursor()
- Return True
- End
-
- Return False
-
- End
-
- Method OnKeyEvent( event:KeyEvent ) Override
-
- If _readOnly Return
-
- Select event.Type
-
- Case EventType.KeyDown,EventType.KeyRepeat
-
- If _macosMode
-
- If event.Modifiers & Modifier.Gui
-
- Select event.Key
- Case Key.A,Key.X,Key.C,Key.V,Key.Z,Key.Y
-
- If Not OnControlKeyDown( event.Key ) Return
- End
-
- Else If event.Modifiers & Modifier.Control
-
- Select event.Key
- Case Key.A
-
- OnKeyDown( Key.Home )
-
- Case Key.E
-
- OnKeyDown( Key.KeyEnd )
- End
-
- Else
- Select event.Key
- Case Key.Home
-
- OnControlKeyDown( Key.Home )
-
- Case Key.KeyEnd
-
- OnControlKeyDown( Key.KeyEnd )
-
- Default
-
- If Not OnKeyDown( event.Key,event.Modifiers ) Return
- End
- Endif
-
- Else
-
- If event.Modifiers & Modifier.Control
-
- If Not OnControlKeyDown( event.Key ) Return
- Else
-
- If Not OnKeyDown( event.Key,event.Modifiers ) Return
- Endif
-
- Endif
-
- If Not (event.Modifiers & Modifier.Shift) _anchor=_cursor
-
- Case EventType.KeyChar
-
- If _undos.Length
-
- Local undo:=_undos.Top
- If Not undo.text And _cursor=undo.cursor
- ReplaceText( _anchor,_cursor,event.Text )
- undo.cursor=_cursor
- Return
- Endif
-
- Endif
-
- ReplaceText( event.Text )
-
- End
- End
-
- Method OnContentMouseEvent( event:MouseEvent ) Override
-
- Select event.Type
- Case EventType.MouseDown
-
- Return
-
- Case EventType.MouseClick
-
- _cursor=PointToIndex( event.Location )
- _anchor=_cursor
-
- _dragging=True
-
- MakeKeyView()
-
- UpdateCursor()
- Case EventType.MouseUp
-
- _dragging=False
-
- Case EventType.MouseMove
-
- If _dragging
-
- _cursor=PointToIndex( event.Location )
- UpdateCursor()
-
- Endif
-
- Case EventType.MouseWheel
-
- Return
- End
-
- event.Eat()
- End
-
- ' Method OnKeyViewChanged( oldKeyView:View,newKeyView:View ) Override
-
- ' If newKeyView=Self UpdateCursor()
- ' End
-
- End
|