| ofs | hex dump | ascii |
|---|
| 0000 | 89 50 4e 47 0d 0a 1a 0a 00 00 00 0d 49 48 44 52 00 00 00 40 00 00 00 40 08 06 00 00 00 aa 69 71 | .PNG........IHDR...@...@......iq |
| 0020 | de 00 00 00 04 73 42 49 54 08 08 08 08 7c 08 64 88 00 00 00 09 70 48 59 73 00 00 01 bb 00 00 01 | .....sBIT....|.d.....pHYs....... |
| 0040 | bb 01 3a ec e3 e2 00 00 00 19 74 45 58 74 53 6f 66 74 77 61 72 65 00 77 77 77 2e 69 6e 6b 73 63 | ..:.......tEXtSoftware.www.inksc |
| 0060 | 61 70 65 2e 6f 72 67 9b ee 3c 1a 00 00 09 69 49 44 41 54 78 da ed 5b 69 6c 54 55 14 c6 5d 63 e2 | ape.org..<....iIDATx..[ilTU..]c. |
| 0080 | 92 18 23 c6 1f 86 32 ad 65 69 81 52 68 29 dd a6 c5 25 fe 51 13 13 d7 c4 25 6a 8c 46 e3 1a 25 a8 | ..#...2.ei.Rh)...%.Q....%j.F..%. |
| 00a0 | 23 76 66 0a 2d 03 85 d2 d2 85 99 21 6a 42 fa 4b a3 10 e8 9b 96 c5 b6 b4 b5 40 f7 95 99 a1 68 db | #vf.-......!jB.K.........@....h. |
| 00c0 | 90 60 48 14 17 dc 9e f7 bb 9d d7 de 77 e7 dd f7 de 48 c9 bc 6a 49 6e 68 5f ef 7b 73 cf 77 cf f9 | .`H.........w....H..jInh_.{s.w.. |
| 00e0 | ce 77 ce 9d 37 4f 96 e5 79 33 31 26 26 26 bc e3 e3 e3 17 c9 90 75 46 fb d8 d8 58 d2 4c 7d e6 4c | .w..7O..y31&&&.......uF...X.L}.L |
| 0100 | 8c 19 79 08 31 2c c7 c0 70 76 54 fc e7 00 20 bb fa 58 0c 00 7c 31 07 c0 1c 00 73 00 cc 5e 00 0a | ..y.1,..pvT......X..|1....s..^.. |
| 0120 | bc a3 8b ec be f0 33 ec 70 37 9e d9 d8 3a 34 d6 c4 8f c6 9e ef 8e 15 ed ef 1d fa f8 eb 9e 61 65 | ......3.p7...:4...............ae |
| 0140 | 7c f0 55 5f 03 7f 7f a1 3f f8 e0 ac 00 e0 81 ed 23 d7 15 f8 43 3f 15 f8 42 b2 de b0 7b 83 72 fa | |.U_....?.......#...C?..B...{.r. |
| 0160 | 8e 13 72 a2 bb 51 5e e8 94 e8 48 22 3f a7 97 9f a4 7f e3 e7 e7 ef 3e 25 67 56 76 bf 6a 79 00 f2 | ..r..Q^...H"?.........>%gVv.jy.. |
| 0180 | 77 87 52 8d 0c 5f 55 de 29 27 15 1f 9a 32 3c d1 dd 20 af dc 7e 9c fc ed 94 60 fe 49 0a 54 ca 96 | w.R.._U.)'...2<.....~....`.I.T.. |
| 01a0 | 63 c7 2c 0f 40 81 37 f4 94 c8 f8 8c 9d 5d f2 3d c5 87 a7 0c b7 b9 1a e4 b4 b2 0e ba bb 5a f3 33 | c.,.@.7......].=.............Z.3 |
| 01c0 | 2b 7b e4 7b 36 4d cf 5f 52 da 34 6e 79 00 0a 7d c1 e2 28 43 2a ba e5 e4 4d 47 18 c3 03 f2 f2 6d | +{.{6M._R.4ny..}..(C*...MG.....m |
| 01e0 | ed 72 de ee 11 4d c3 d7 56 0d c8 8b 4b be 51 cd 4f db de 21 db 7d c1 d1 59 00 40 78 9f 62 c8 9a | .r...M..V...K.Q.O..!.}..Y.@x.b.. |
| 0200 | ca 5e 79 d1 e6 a3 53 86 2c 74 06 e4 65 5b db e4 dc da 61 4d c3 71 3d d5 73 8c 99 2f 91 f9 ad 72 | .^y...S.,t..e[....aM.q=.s../...r |
| 0220 | 1e 33 ff 81 cf 46 6e b2 76 08 f8 42 a3 59 55 7d aa 1d c4 80 61 b9 35 43 9a 86 23 04 56 94 7d 4b | .3...Fn.v..B.YU}....a.5C..#.V.}K |
| 0240 | 77 9a 71 77 39 bb 7a 30 7a fe 9e d3 99 96 05 20 6d 6b ff 7c 2c 9c 35 3c 65 4b 8b 9c a3 65 08 47 | w.qw9.z0z.......mk.|,.5<eK...e.G |
| 0260 | 70 ca 7c 84 ca 9a 5d bd 42 12 cd a9 1e 78 db b2 00 ac d8 d6 fe 02 bb 83 88 65 91 21 3c c1 21 05 | p.|...].B....x...........e.!<.!. |
| 0280 | ae de d9 29 9c bf b6 aa 9f 7a d5 d2 d2 96 2e cb 02 b0 cc d3 fa 29 16 99 b5 ab cf d0 90 28 82 f3 | ...).....z...........).......(.. |
| 02a0 | 6a 67 82 3c 8e 17 16 95 1c 3d 6f 59 00 f2 6a 86 6a 45 86 e7 d6 0e c9 29 06 04 c7 87 07 80 61 79 | jg.<.....=oY..j.jE.....)......ay |
| 02c0 | 01 c0 65 57 f7 5b 17 00 bb 2f 74 f8 92 08 8e d1 0b ac 50 82 76 40 2a 9d f2 0a 5f f8 0e 4b 02 40 | ..eW.[.../t.......P.v@*..._..K.@ |
| 02e0 | 16 77 4e 25 75 29 c1 35 98 26 38 84 07 9b 36 13 89 50 82 5c d6 90 c6 eb 2c 07 c0 7d 9f 9e 9e cf | .wN%u).5.&8...6..P.\....,..}.... |
| 0300 | 0a 9f 58 08 0e f9 3f 3a 3c da 84 42 29 bb b2 77 a3 e5 00 b0 fb 43 f7 c6 4a 70 b8 0e 29 6c 36 3c | ..X...?:<..B)..w.....C..Jp..)l6< |
| 0320 | 90 4e f1 fc 25 a5 cd c3 96 03 80 48 db bd 66 09 0e 63 35 e2 9c c9 ff f0 98 35 24 35 8a 80 02 8f | .N..%......H..f..c5......5$5.... |
| 0340 | 40 49 d2 4c b0 f9 c8 05 cb 01 40 76 65 04 8b 5b 5a da ac 4b 70 48 91 aa 38 77 0b e3 7c 5a 2f 30 | @I.L......@ve..[Z..KpH..8w..|Z/0 |
| 0360 | 84 88 7b d7 56 0f fc ea 70 c8 57 5a 0a 80 a5 9e 96 73 7a 04 07 19 0c 55 c8 d6 05 28 88 f2 05 71 | ..{.V...p.WZ.....sz....U...(...q |
| 0380 | 0e 5e 58 ca cc 07 21 42 35 4e 79 85 7f 24 c1 32 00 60 37 c8 a2 7e 36 ab f3 e1 25 39 35 83 ba 8d | .^X...!B5Ny..$.2.`7..~6...%95... |
| 03a0 | 12 76 3e 08 32 af 96 07 2a fc 90 65 00 c8 d9 15 b4 ad 24 8b 06 09 16 f8 a6 5d 99 36 3e 62 d0 f9 | .v>.2...*..e......$......].6>b.. |
| 03c0 | b8 9f 2d 9b 29 2f 08 e6 17 7a 43 1b 2c 03 00 21 b4 d7 d9 26 c7 92 92 26 95 e1 28 76 26 dd 37 28 | ..-.)/...zC.,..!...&...&..(v&.7( |
| 03e0 | a8 06 47 28 69 46 67 8f a0 90 14 57 97 77 7e 63 19 00 32 2a ba 6a d4 75 bf a4 32 06 2e 0f 00 72 | ..G(iFg....W.w~c..2*.j.u..2....r |
| 0400 | 34 ca 61 e8 03 b6 1a 44 1a cc 11 94 cd 00 50 f1 2a a2 0e 2f 5a 06 80 42 5f a8 6e ba 71 d9 43 c9 | 4.a....D......P.*../Z..B_.n.q.C. |
| 0420 | 8d 65 6e 76 40 e2 a6 7a 5a 65 84 0c 0b 1a 8c ca 60 e4 2e 3f 90 22 93 19 71 85 ec 91 59 d7 72 83 | .env@..zZe......`..?."..q...Y.r. |
| 0440 | 25 00 28 f0 86 fa 45 95 1c f1 0e ea de 22 40 14 6e 80 2e d0 52 7e d9 d5 03 34 a4 34 db 69 7b 42 | %.(...E......"@.n...R~...4.4.i{B |
| 0460 | 29 71 07 80 b6 c1 7d a1 3f 8d da e0 4a 2a 84 cb a3 bc 65 39 82 07 03 06 ae 22 f3 d4 69 73 b2 b9 | )q....}.?...J*....e9....."..is.. |
| 0480 | a2 ea 2a f9 83 4f c6 1d 80 ec ca a1 55 66 8c d7 94 b6 24 15 82 1b 90 ef d9 a2 49 2b 6c d2 cb a3 | ..*..O......Uf....$.......I+l... |
| 04a0 | c5 92 dd 17 76 c7 1d 80 54 4f 5b 25 16 8f 5c 8d dd d5 93 bf 46 03 1d 24 70 03 88 90 d5 01 ac fb | ....v...TO[%..\.....F..$p....... |
| 04c0 | 23 1c 70 86 80 94 69 f7 86 f7 c5 1d 80 14 4f 4b ab 96 1b 43 fc 40 f6 8a 52 99 99 93 23 34 57 91 | #.p...i.......OK...C.@..R...#4W. |
| 04e0 | 0e 51 00 69 02 e2 6e f8 2b ee 00 10 85 56 0f f6 06 d1 25 15 37 c6 9c 06 cd 03 72 8a 8a 22 94 c9 | .Q.i..n.+....V....%.7.....r..".. |
| 0500 | 90 c5 ca f3 b3 76 9c b8 33 ae 00 90 c5 9d 51 b3 f6 20 95 b2 22 37 46 36 58 be ad 8d a6 cb 7c 41 | .....v..3.....Q....."7F6X.....|A |
| 0520 | 99 6c 5a 52 6f 69 26 5e d6 bf 2e 6e 00 14 56 05 6f 36 dc 35 45 17 30 39 3c 2a a6 77 1c a7 e9 4e | .lZRoi&^...n..V.o6.5E.09<*.w...N |
| 0540 | 5c 3a 73 92 7a f3 91 a9 c6 6b 5e cd d0 5b 71 03 60 9d ff 54 56 2c 6e 8c 14 a6 b0 be cd 15 cd fa | \:s.z....k^..[q.`..TV,n......... |
| 0560 | 30 12 22 09 21 85 3c 0f 0e 20 b5 3f 27 a9 d5 9d 25 12 16 27 63 35 68 61 51 fd a3 18 89 ee c0 82 | 0.".!.<....?'...%..'c5haQ....... |
| 0580 | 4b 02 20 b7 66 f8 b5 7f 1f d3 41 ba 8b 70 6b d6 48 ed a1 94 ce d1 21 93 59 d1 fd 47 4a c9 c1 1b | K...f.....A..pk.H.....!.Y..GJ... |
| 05a0 | cd 1a 9f e0 3c b8 84 7b fe b9 85 2e e9 65 f2 c7 2b 62 06 80 ec 64 37 95 b6 5b 5b a9 e2 8b 2e 59 | ....<..{.....e..+b...d7..[[....Y |
| 05c0 | cd 0f dc 0b 57 67 ab 41 bd d2 19 05 14 04 d5 62 c8 69 97 d4 4d c2 e9 25 33 3b 9a 56 d5 71 0d 79 | ....Wg.A.......b.i..M..%3;.V.q.y |
| 05e0 | 6e 05 19 68 e0 fc 3d f5 59 ae 40 43 d2 a6 fa 3b 63 02 00 87 14 22 25 87 83 51 7b 0c 24 07 b7 67 | n..h..=.Y.@C...;c...."%..Q{.$..g |
| 0600 | 5b e1 f8 59 d4 22 c3 75 85 13 c0 23 9c aa fc 81 5c 7b 77 9e c3 61 d8 31 ba db 71 e8 16 9b 53 2a | [..Y.".u...#....\{w..a.1..q...S* |
| 0620 | 22 f7 fc 19 f1 b4 23 5a 9e 20 0e 81 da e1 f3 8a b4 4d 74 6b a7 40 e4 70 45 b8 68 95 c3 20 3f b6 | ".....#Z.........Mtk.@.pE.h...?. |
| 0640 | 91 aa d3 0a a7 21 90 ca 94 cd 4c 05 d9 49 fe 1f 65 af 25 b8 24 69 5e 5d dd 55 66 c2 22 d1 15 c8 | .....!....L..I..e.%.$i^].Uf."... |
| 0660 | 26 f7 fc 4e d7 ec ac 7f dd 14 00 6c 1b 9c 35 46 2f 05 c2 38 10 20 88 30 8b 00 b2 8c 33 86 36 52 | &..N.......l..5F/..8...0....3.6R |
| 0680 | 05 2d 32 68 80 24 ae a0 c2 81 09 78 a4 d0 1b 7c 83 1a e2 38 74 9b cd 25 6d 50 8c 21 a1 f1 9e 69 | .-2h.$.....x...|...8t..%mP.!...i |
| 06a0 | 62 74 4a 1f 45 9e 7b 21 cf 71 e8 6a 43 00 d0 06 37 4f 72 47 75 49 6e f2 c8 4b 3b 0d 42 2b 40 fc | btJ.E.{!.q.jC...7OrGuIn..K;.B+@. |
| 06c0 | f0 f7 e0 b9 8a 97 14 fa c3 5e b5 31 81 f7 23 f3 7e 34 13 0a 91 70 b8 5e 01 2e b1 f8 40 aa 21 00 | .........^.1..#.~4...p.^....@.!. |
| 06e0 | 19 3b bb 4a b1 08 bd 0e 30 4f 5a 98 cf 16 3d d8 51 bd 1e 00 00 e4 cb 68 64 0c 0d b0 da 55 00 38 | .;.J....0OZ...=.Q......hd....U.8 |
| 0700 | f6 df a4 10 9c ed 13 29 d9 7c 7a 94 4e 44 3e e7 39 43 00 52 b6 34 0f b0 ad 6a b8 b5 a8 c3 0b 16 | .......).|z.ND>.9C.R.4...j...... |
| 0720 | 67 bf 37 80 f0 58 51 d6 ae d3 f2 0a 52 22 e5 f9 04 85 92 a0 ad f6 33 df 26 8f b0 3c 09 83 fa a7 | g.7..XQ.....R"........3.&..<.... |
pre { line-height: 125%; }
td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
.highlight .hll { background-color: #ffffcc }
.highlight .c { color: #888888 } /* Comment */
.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.highlight .k { color: #008800; font-weight: bold } /* Keyword */
.highlight .ch { color: #888888 } /* Comment.Hashbang */
.highlight .cm { color: #888888 } /* Comment.Multiline */
.highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */
.highlight .cpf { color: #888888 } /* Comment.PreprocFile */
.highlight .c1 { color: #888888 } /* Comment.Single */
.highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */
.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */
.highlight .gr { color: #aa0000 } /* Generic.Error */
.highlight .gh { color: #333333 } /* Generic.Heading */
.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.highlight .go { color: #888888 } /* Generic.Output */
.highlight .gp { color: #555555 } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #666666 } /* Generic.Subheading */
.highlight .gt { color: #aa0000 } /* Generic.Traceback */
.highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */
.highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */
.highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */
.highlight .kp { color: #008800 } /* Keyword.Pseudo */
.highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */
.highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */
.highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */
.highlight .na { color: #336699 } /* Name.Attribute */
.highlight .nb { color: #003388 } /* Name.Builtin */
.highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */
.highlight .no { color: #003366; font-weight: bold } /* Name.Constant */
.highlight .nd { color: #555555 } /* Name.Decorator */
.highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */
.highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */
.highlight .nl { color: #336699; font-style: italic } /* Name.Label */
.highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */
.highlight .py { color: #336699; font-weight: bold } /* Name.Property */
.highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */
.highlight .nv { color: #336699 } /* Name.Variable */
.highlight .ow { color: #008800 } /* Operator.Word */
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
.highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */
.highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */
.highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */
.highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */
.highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */
.highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */
.highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */
.highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */
.highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */
.highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */
.highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */
.highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */
.highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */
.highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */
.highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */
.highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */
.highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */
.highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */
.highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */
.highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */
.highlight .vc { color: #336699 } /* Name.Variable.Class */
.highlight .vg { color: #dd7700 } /* Name.Variable.Global */
.highlight .vi { color: #3333bb } /* Name.Variable.Instance */
.highlight .vm { color: #336699 } /* Name.Variable.Magic */
.highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Windows;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media.TextFormatting;
using Tango.Scripting.Editors.Document;
using Tango.Scripting.Editors.Rendering;
using Tango.Scripting.Editors.Utils;
namespace Tango.Scripting.Editors.Editing
{
static class CaretNavigationCommandHandler
{
/// <summary>
/// Creates a new <see cref="TextAreaInputHandler"/> for the text area.
/// </summary>
public static TextAreaInputHandler Create(TextArea textArea)
{
TextAreaInputHandler handler = new TextAreaInputHandler(textArea);
handler.CommandBindings.AddRange(CommandBindings);
handler.InputBindings.AddRange(InputBindings);
return handler;
}
static readonly List<CommandBinding> CommandBindings = new List<CommandBinding>();
static readonly List<InputBinding> InputBindings = new List<InputBinding>();
static void AddBinding(ICommand command, ModifierKeys modifiers, Key key, ExecutedRoutedEventHandler handler)
{
CommandBindings.Add(new CommandBinding(command, handler));
InputBindings.Add(TextAreaDefaultInputHandler.CreateFrozenKeyBinding(command, modifiers, key));
}
static CaretNavigationCommandHandler()
{
const ModifierKeys None = ModifierKeys.None;
const ModifierKeys Ctrl = ModifierKeys.Control;
const ModifierKeys Shift = ModifierKeys.Shift;
const ModifierKeys Alt = ModifierKeys.Alt;
AddBinding(EditingCommands.MoveLeftByCharacter, None, Key.Left, OnMoveCaret(CaretMovementType.CharLeft));
AddBinding(EditingCommands.SelectLeftByCharacter, Shift, Key.Left, OnMoveCaretExtendSelection(CaretMovementType.CharLeft));
AddBinding(RectangleSelection.BoxSelectLeftByCharacter, Alt | Shift, Key.Left, OnMoveCaretBoxSelection(CaretMovementType.CharLeft));
AddBinding(EditingCommands.MoveRightByCharacter, None, Key.Right, OnMoveCaret(CaretMovementType.CharRight));
AddBinding(EditingCommands.SelectRightByCharacter, Shift, Key.Right, OnMoveCaretExtendSelection(CaretMovementType.CharRight));
AddBinding(RectangleSelection.BoxSelectRightByCharacter, Alt | Shift, Key.Right, OnMoveCaretBoxSelection(CaretMovementType.CharRight));
AddBinding(EditingCommands.MoveLeftByWord, Ctrl, Key.Left, OnMoveCaret(CaretMovementType.WordLeft));
AddBinding(EditingCommands.SelectLeftByWord, Ctrl | Shift, Key.Left, OnMoveCaretExtendSelection(CaretMovementType.WordLeft));
AddBinding(RectangleSelection.BoxSelectLeftByWord, Ctrl | Alt | Shift, Key.Left, OnMoveCaretBoxSelection(CaretMovementType.WordLeft));
AddBinding(EditingCommands.MoveRightByWord, Ctrl, Key.Right, OnMoveCaret(CaretMovementType.WordRight));
AddBinding(EditingCommands.SelectRightByWord, Ctrl | Shift, Key.Right, OnMoveCaretExtendSelection(CaretMovementType.WordRight));
AddBinding(RectangleSelection.BoxSelectRightByWord, Ctrl | Alt | Shift, Key.Right, OnMoveCaretBoxSelection(CaretMovementType.WordRight));
AddBinding(EditingCommands.MoveUpByLine, None, Key.Up, OnMoveCaret(CaretMovementType.LineUp));
AddBinding(EditingCommands.SelectUpByLine, Shift, Key.Up, OnMoveCaretExtendSelection(CaretMovementType.LineUp));
AddBinding(RectangleSelection.BoxSelectUpByLine, Alt | Shift, Key.Up, OnMoveCaretBoxSelection(CaretMovementType.LineUp));
AddBinding(EditingCommands.MoveDownByLine, None, Key.Down, OnMoveCaret(CaretMovementType.LineDown));
AddBinding(EditingCommands.SelectDownByLine, Shift, Key.Down, OnMoveCaretExtendSelection(CaretMovementType.LineDown));
AddBinding(RectangleSelection.BoxSelectDownByLine, Alt | Shift, Key.Down, OnMoveCaretBoxSelection(CaretMovementType.LineDown));
AddBinding(EditingCommands.MoveDownByPage, None, Key.PageDown, OnMoveCaret(CaretMovementType.PageDown));
AddBinding(EditingCommands.SelectDownByPage, Shift, Key.PageDown, OnMoveCaretExtendSelection(CaretMovementType.PageDown));
AddBinding(EditingCommands.MoveUpByPage, None, Key.PageUp, OnMoveCaret(CaretMovementType.PageUp));
AddBinding(EditingCommands.SelectUpByPage, Shift, Key.PageUp, OnMoveCaretExtendSelection(CaretMovementType.PageUp));
AddBinding(EditingCommands.MoveToLineStart, None, Key.Home, OnMoveCaret(CaretMovementType.LineStart));
AddBinding(EditingCommands.SelectToLineStart, Shift, Key.Home, OnMoveCaretExtendSelection(CaretMovementType.LineStart));
AddBinding(RectangleSelection.BoxSelectToLineStart, Alt | Shift, Key.Home, OnMoveCaretBoxSelection(CaretMovementType.LineStart));
AddBinding(EditingCommands.MoveToLineEnd, None, Key.End, OnMoveCaret(CaretMovementType.LineEnd));
AddBinding(EditingCommands.SelectToLineEnd, Shift, Key.End, OnMoveCaretExtendSelection(CaretMovementType.LineEnd));
AddBinding(RectangleSelection.BoxSelectToLineEnd, Alt | Shift, Key.End, OnMoveCaretBoxSelection(CaretMovementType.LineEnd));
AddBinding(EditingCommands.MoveToDocumentStart, Ctrl, Key.Home, OnMoveCaret(CaretMovementType.DocumentStart));
AddBinding(EditingCommands.SelectToDocumentStart, Ctrl | Shift, Key.Home, OnMoveCaretExtendSelection(CaretMovementType.DocumentStart));
AddBinding(EditingCommands.MoveToDocumentEnd, Ctrl, Key.End, OnMoveCaret(CaretMovementType.DocumentEnd));
AddBinding(EditingCommands.SelectToDocumentEnd, Ctrl | Shift, Key.End, OnMoveCaretExtendSelection(CaretMovementType.DocumentEnd));
CommandBindings.Add(new CommandBinding(ApplicationCommands.SelectAll, OnSelectAll));
TextAreaDefaultInputHandler.WorkaroundWPFMemoryLeak(InputBindings);
}
static void OnSelectAll(object target, ExecutedRoutedEventArgs args)
{
TextArea textArea = GetTextArea(target);
if (textArea != null && textArea.Document != null) {
args.Handled = true;
textArea.Caret.Offset = textArea.Document.TextLength;
textArea.Selection = SimpleSelection.Create(textArea, 0, textArea.Document.TextLength);
}
}
static TextArea GetTextArea(object target)
{
return target as TextArea;
}
enum CaretMovementType
{
CharLeft,
CharRight,
WordLeft,
WordRight,
LineUp,
LineDown,
PageUp,
PageDown,
LineStart,
LineEnd,
DocumentStart,
DocumentEnd
}
static ExecutedRoutedEventHandler OnMoveCaret(CaretMovementType direction)
{
return (target, args) => {
TextArea textArea = GetTextArea(target);
if (textArea != null && textArea.Document != null) {
args.Handled = true;
textArea.ClearSelection();
MoveCaret(textArea, direction);
textArea.Caret.BringCaretToView();
}
};
}
static ExecutedRoutedEventHandler OnMoveCaretExtendSelection(CaretMovementType direction)
{
return (target, args) => {
TextArea textArea = GetTextArea(target);
if (textArea != null && textArea.Document != null) {
args.Handled = true;
TextViewPosition oldPosition = textArea.Caret.Position;
MoveCaret(textArea, direction);
textArea.Selection = textArea.Selection.StartSelectionOrSetEndpoint(oldPosition, textArea.Caret.Position);
if (!textArea.Document.IsInUpdate) // if we're inside a larger update (e.g. called by EditingCommandHandler.OnDelete()), avoid calculating the caret rectangle now
textArea.Caret.BringCaretToView();
}
};
}
static ExecutedRoutedEventHandler OnMoveCaretBoxSelection(CaretMovementType direction)
{
return (target, args) => {
TextArea textArea = GetTextArea(target);
if (textArea != null && textArea.Document != null) {
args.Handled = true;
// First, convert the selection into a rectangle selection
// (this is required so that virtual space gets enabled for the caret movement)
if (textArea.Options.EnableRectangularSelection && !(textArea.Selection is RectangleSelection)) {
if (textArea.Selection.IsEmpty) {
textArea.Selection = new RectangleSelection(textArea, textArea.Caret.Position, textArea.Caret.Position);
} else {
// Convert normal selection to rectangle selection
textArea.Selection = new RectangleSelection(textArea, textArea.Selection.StartPosition, textArea.Caret.Position);
}
}
// Now move the caret and extend the selection
TextViewPosition oldPosition = textArea.Caret.Position;
MoveCaret(textArea, direction);
textArea.Selection = textArea.Selection.StartSelectionOrSetEndpoint(oldPosition, textArea.Caret.Position);
textArea.Caret.BringCaretToView();
}
};
}
#region Caret movement
static void MoveCaret(TextArea textArea, CaretMovementType direction)
{
DocumentLine caretLine = textArea.Document.GetLineByNumber(textArea.Caret.Line);
VisualLine visualLine = textArea.TextView.GetOrConstructVisualLine(caretLine);
TextViewPosition caretPosition = textArea.Caret.Position;
TextLine textLine = visualLine.GetTextLine(caretPosition.VisualColumn);
switch (direction) {
case CaretMovementType.CharLeft:
MoveCaretLeft(textArea, caretPosition, visualLine, CaretPositioningMode.Normal);
break;
case CaretMovementType.CharRight:
MoveCaretRight(textArea, caretPosition, visualLine, CaretPositioningMode.Normal);
break;
case CaretMovementType.WordLeft:
MoveCaretLeft(textArea, caretPosition, visualLine, CaretPositioningMode.WordStart);
break;
case CaretMovementType.WordRight:
MoveCaretRight(textArea, caretPosition, visualLine, CaretPositioningMode.WordStart);
break;
case CaretMovementType.LineUp:
case CaretMovementType.LineDown:
case CaretMovementType.PageUp:
case CaretMovementType.PageDown:
MoveCaretUpDown(textArea, direction, visualLine, textLine, caretPosition.VisualColumn);
break;
case CaretMovementType.DocumentStart:
SetCaretPosition(textArea, 0, 0);
break;
case CaretMovementType.DocumentEnd:
SetCaretPosition(textArea, -1, textArea.Document.TextLength);
break;
case CaretMovementType.LineStart:
MoveCaretToStartOfLine(textArea, visualLine);
break;
case CaretMovementType.LineEnd:
MoveCaretToEndOfLine(textArea, visualLine);
break;
default:
throw new NotSupportedException(direction.ToString());
}
}
#endregion
#region Home/End
static void MoveCaretToStartOfLine(TextArea textArea, VisualLine visualLine)
{
int newVC = visualLine.GetNextCaretPosition(-1, LogicalDirection.Forward, CaretPositioningMode.WordStart, textArea.Selection.EnableVirtualSpace);
if (newVC < 0)
throw ThrowUtil.NoValidCaretPosition();
// when the caret is already at the start of the text, jump to start before whitespace
if (newVC == textArea.Caret.VisualColumn)
newVC = 0;
int offset = visualLine.FirstDocumentLine.Offset + visualLine.GetRelativeOffset(newVC);
SetCaretPosition(textArea, newVC, offset);
}
static void MoveCaretToEndOfLine(TextArea textArea, VisualLine visualLine)
{
int newVC = visualLine.VisualLength;
int offset = visualLine.FirstDocumentLine.Offset + visualLine.GetRelativeOffset(newVC);
SetCaretPosition(textArea, newVC, offset);
}
#endregion
#region By-character / By-word movement
static void MoveCaretRight(TextArea textArea, TextViewPosition caretPosition, VisualLine visualLine, CaretPositioningMode mode)
{
int pos = visualLine.GetNextCaretPosition(caretPosition.VisualColumn, LogicalDirection.Forward, mode, textArea.Selection.EnableVirtualSpace);
if (pos >= 0) {
SetCaretPosition(textArea, pos, visualLine.GetRelativeOffset(pos) + visualLine.FirstDocumentLine.Offset);
} else {
// move to start of next line
DocumentLine nextDocumentLine = visualLine.LastDocumentLine.NextLine;
if (nextDocumentLine != null) {
VisualLine nextLine = textArea.TextView.GetOrConstructVisualLine(nextDocumentLine);
pos = nextLine.GetNextCaretPosition(-1, LogicalDirection.Forward, mode, textArea.Selection.EnableVirtualSpace);
if (pos < 0)
throw ThrowUtil.NoValidCaretPosition();
SetCaretPosition(textArea, pos, nextLine.GetRelativeOffset(pos) + nextLine.FirstDocumentLine.Offset);
} else {
// at end of document
Debug.Assert(visualLine.LastDocumentLine.Offset + visualLine.LastDocumentLine.TotalLength == textArea.Document.TextLength);
SetCaretPosition(textArea, -1, textArea.Document.TextLength);
}
}
}
static void MoveCaretLeft(TextArea textArea, TextViewPosition caretPosition, VisualLine visualLine, CaretPositioningMode mode)
{
int pos = visualLine.GetNextCaretPosition(caretPosition.VisualColumn, LogicalDirection.Backward, mode, textArea.Selection.EnableVirtualSpace);
if (pos >= 0) {
SetCaretPosition(textArea, pos, visualLine.GetRelativeOffset(pos) + visualLine.FirstDocumentLine.Offset);
} else {
// move to end of previous line
DocumentLine previousDocumentLine = visualLine.FirstDocumentLine.PreviousLine;
if (previousDocumentLine != null) {
VisualLine previousLine = textArea.TextView.GetOrConstructVisualLine(previousDocumentLine);
pos = previousLine.GetNextCaretPosition(previousLine.VisualLength + 1, LogicalDirection.Backward, mode, textArea.Selection.EnableVirtualSpace);
if (pos < 0)
throw ThrowUtil.NoValidCaretPosition();
SetCaretPosition(textArea, pos, previousLine.GetRelativeOffset(pos) + previousLine.FirstDocumentLine.Offset);
} else {
// at start of document
Debug.Assert(visualLine.FirstDocumentLine.Offset == 0);
SetCaretPosition(textArea, 0, 0);
}
}
}
#endregion
#region Line+Page up/down
static void MoveCaretUpDown(TextArea textArea, CaretMovementType direction, VisualLine visualLine, TextLine textLine, int caretVisualColumn)
{
// moving up/down happens using the desired visual X position
double xPos = textArea.Caret.DesiredXPos;
if (double.IsNaN(xPos))
xPos = visualLine.GetTextLineVisualXPosition(textLine, caretVisualColumn);
// now find the TextLine+VisualLine where the caret will end up in
VisualLine targetVisualLine = visualLine;
TextLine targetLine;
int textLineIndex = visualLine.TextLines.IndexOf(textLine);
switch (direction) {
case CaretMovementType.LineUp:
{
// Move up: move to the previous TextLine in the same visual line
// or move to the last TextLine of the previous visual line
int prevLineNumber = visualLine.FirstDocumentLine.LineNumber - 1;
if (textLineIndex > 0) {
targetLine = visualLine.TextLines[textLineIndex - 1];
} else if (prevLineNumber >= 1) {
DocumentLine prevLine = textArea.Document.GetLineByNumber(prevLineNumber);
targetVisualLine = textArea.TextView.GetOrConstructVisualLine(prevLine);
targetLine = targetVisualLine.TextLines[targetVisualLine.TextLines.Count - 1];
} else {
targetLine = null;
}
break;
}
case CaretMovementType.LineDown:
{
// Move down: move to the next TextLine in the same visual line
// or move to the first TextLine of the next visual line
int nextLineNumber = visualLine.LastDocumentLine.LineNumber + 1;
if (textLineIndex < visualLine.TextLines.Count - 1) {
targetLine = visualLine.TextLines[textLineIndex + 1];
} else if (nextLineNumber <= textArea.Document.LineCount) {
DocumentLine nextLine = textArea.Document.GetLineByNumber(nextLineNumber);
targetVisualLine = textArea.TextView.GetOrConstructVisualLine(nextLine);
targetLine = targetVisualLine.TextLines[0];
} else {
targetLine = null;
}
break;
}
case CaretMovementType.PageUp:
case CaretMovementType.PageDown:
{
// Page up/down: find the target line using its visual position
double yPos = visualLine.GetTextLineVisualYPosition(textLine, VisualYPosition.LineMiddle);
if (direction == CaretMovementType.PageUp)
yPos -= textArea.TextView.RenderSize.Height;
else
yPos += textArea.TextView.RenderSize.Height;
DocumentLine newLine = textArea.TextView.GetDocumentLineByVisualTop(yPos);
targetVisualLine = textArea.TextView.GetOrConstructVisualLine(newLine);
targetLine = targetVisualLine.GetTextLineByVisualYPosition(yPos);
break;
}
default:
throw new NotSupportedException(direction.ToString());
}
if (targetLine != null) {
double yPos = targetVisualLine.GetTextLineVisualYPosition(targetLine, VisualYPosition.LineMiddle);
int newVisualColumn = targetVisualLine.GetVisualColumn(new Point(xPos, yPos), textArea.Selection.EnableVirtualSpace);
SetCaretPosition(textArea, targetVisualLine, targetLine, newVisualColumn, false);
textArea.Caret.DesiredXPos = xPos;
}
}
#endregion
#region SetCaretPosition
static void SetCaretPosition(TextArea textArea, VisualLine targetVisualLine, TextLine targetLine,
int newVisualColumn, bool allowWrapToNextLine)
{
int targetLineStartCol = targetVisualLine.GetTextLineVisualStartColumn(targetLine);
if (!allowWrapToNextLine && newVisualColumn >= targetLineStartCol + targetLine.Length) {
if (newVisualColumn <= targetVisualLine.VisualLength)
newVisualColumn = targetLineStartCol + targetLine.Length - 1;
}
int newOffset = targetVisualLine.GetRelativeOffset(newVisualColumn) + targetVisualLine.FirstDocumentLine.Offset;
SetCaretPosition(textArea, newVisualColumn, newOffset);
}
static void SetCaretPosition(TextArea textArea, int newVisualColumn, int newOffset)
{
textArea.Caret.Position = new TextViewPosition(textArea.Document.GetLocation(newOffset), newVisualColumn);
textArea.Caret.DesiredXPos = double.NaN;
}
#endregion
}
}
|