@@ -40,49 +40,14 @@ namespace ICSharpCode.AvalonEdit.Editing
4040 /// </summary>
4141 sealed class SelectionMouseHandler : ITextAreaInputHandler
4242 {
43- #region enum SelectionMode
44- enum SelectionMode
45- {
46- /// <summary>
47- /// no selection (no mouse button down)
48- /// </summary>
49- None ,
50- /// <summary>
51- /// left mouse button down on selection, might be normal click
52- /// or might be drag'n'drop
53- /// </summary>
54- PossibleDragStart ,
55- /// <summary>
56- /// dragging text
57- /// </summary>
58- Drag ,
59- /// <summary>
60- /// normal selection (click+drag)
61- /// </summary>
62- Normal ,
63- /// <summary>
64- /// whole-word selection (double click+drag or ctrl+click+drag)
65- /// </summary>
66- WholeWord ,
67- /// <summary>
68- /// whole-line selection (triple click+drag)
69- /// </summary>
70- WholeLine ,
71- /// <summary>
72- /// rectangular selection (alt+click+drag)
73- /// </summary>
74- Rectangular
75- }
76- #endregion
77-
7843 readonly TextArea textArea ;
7944
80- SelectionMode mode ;
45+ MouseSelectionMode mode ;
8146 AnchorSegment startWord ;
8247 Point possibleDragStartMousePos ;
8348
8449 #region Constructor + Attach + Detach
85- public SelectionMouseHandler ( TextArea textArea )
50+ internal SelectionMouseHandler ( TextArea textArea )
8651 {
8752 if ( textArea == null )
8853 throw new ArgumentNullException ( "textArea" ) ;
@@ -101,15 +66,15 @@ private static void OnLostMouseCapture(object sender, MouseEventArgs e)
10166 {
10267 SelectionMouseHandler handler = textArea . DefaultInputHandler . MouseSelection as SelectionMouseHandler ;
10368 if ( handler != null )
104- handler . mode = SelectionMode . None ;
69+ handler . mode = MouseSelectionMode . None ;
10570 }
10671 }
10772
108- public TextArea TextArea {
73+ TextArea ITextAreaInputHandler . TextArea {
10974 get { return textArea ; }
11075 }
11176
112- public void Attach ( )
77+ void ITextAreaInputHandler . Attach ( )
11378 {
11479 textArea . MouseLeftButtonDown += textArea_MouseLeftButtonDown ;
11580 textArea . MouseMove += textArea_MouseMove ;
@@ -123,9 +88,9 @@ public void Attach()
12388 }
12489 }
12590
126- public void Detach ( )
91+ void ITextAreaInputHandler . Detach ( )
12792 {
128- mode = SelectionMode . None ;
93+ mode = MouseSelectionMode . None ;
12994 textArea . MouseLeftButtonDown -= textArea_MouseLeftButtonDown ;
13095 textArea . MouseMove -= textArea_MouseMove ;
13196 textArea . MouseLeftButtonUp -= textArea_MouseLeftButtonUp ;
@@ -239,7 +204,7 @@ void textArea_Drop(object sender, DragEventArgs e)
239204 e . Effects = effect ;
240205 if ( effect != DragDropEffects . None ) {
241206 int start = textArea . Caret . Offset ;
242- if ( mode == SelectionMode . Drag && textArea . Selection . Contains ( start ) ) {
207+ if ( mode == MouseSelectionMode . Drag && textArea . Selection . Contains ( start ) ) {
243208 Debug . WriteLine ( "Drop: did not drop: drop target is inside selection" ) ;
244209 e . Effects = DragDropEffects . None ;
245210 } else {
@@ -324,7 +289,7 @@ void textArea_QueryContinueDrag(object sender, QueryContinueDragEventArgs e)
324289 void StartDrag ( )
325290 {
326291 // prevent nested StartDrag calls
327- mode = SelectionMode . Drag ;
292+ mode = MouseSelectionMode . Drag ;
328293
329294 // mouse capture and Drag'n'Drop doesn't mix
330295 textArea . ReleaseMouseCapture ( ) ;
@@ -391,7 +356,7 @@ void StartDrag()
391356 void textArea_QueryCursor ( object sender , QueryCursorEventArgs e )
392357 {
393358 if ( ! e . Handled ) {
394- if ( mode != SelectionMode . None ) {
359+ if ( mode != MouseSelectionMode . None ) {
395360 // during selection, use IBeam cursor even outside the text area
396361 e . Cursor = Cursors . IBeam ;
397362 e . Handled = true ;
@@ -418,7 +383,7 @@ void textArea_QueryCursor(object sender, QueryCursorEventArgs e)
418383 #region LeftButtonDown
419384 void textArea_MouseLeftButtonDown ( object sender , MouseButtonEventArgs e )
420385 {
421- mode = SelectionMode . None ;
386+ mode = MouseSelectionMode . None ;
422387 if ( ! e . Handled && e . ChangedButton == MouseButton . Left ) {
423388 ModifierKeys modifiers = Keyboard . Modifiers ;
424389 bool shift = ( modifiers & ModifierKeys . Shift ) == ModifierKeys . Shift ;
@@ -428,7 +393,7 @@ void textArea_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
428393 int offset = GetOffsetFromMousePosition ( e , out visualColumn , out isAtEndOfLine ) ;
429394 if ( textArea . Selection . Contains ( offset ) ) {
430395 if ( textArea . CaptureMouse ( ) ) {
431- mode = SelectionMode . PossibleDragStart ;
396+ mode = MouseSelectionMode . PossibleDragStart ;
432397 possibleDragStartMousePos = e . GetPosition ( textArea ) ;
433398 }
434399 e . Handled = true ;
@@ -445,26 +410,26 @@ void textArea_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
445410 }
446411 if ( textArea . CaptureMouse ( ) ) {
447412 if ( ( modifiers & ModifierKeys . Alt ) == ModifierKeys . Alt && textArea . Options . EnableRectangularSelection ) {
448- mode = SelectionMode . Rectangular ;
413+ mode = MouseSelectionMode . Rectangular ;
449414 if ( shift && textArea . Selection is RectangleSelection ) {
450415 textArea . Selection = textArea . Selection . StartSelectionOrSetEndpoint ( oldPosition , textArea . Caret . Position ) ;
451416 }
452417 } else if ( e . ClickCount == 1 && ( ( modifiers & ModifierKeys . Control ) == 0 ) ) {
453- mode = SelectionMode . Normal ;
418+ mode = MouseSelectionMode . Normal ;
454419 if ( shift && ! ( textArea . Selection is RectangleSelection ) ) {
455420 textArea . Selection = textArea . Selection . StartSelectionOrSetEndpoint ( oldPosition , textArea . Caret . Position ) ;
456421 }
457422 } else {
458423 SimpleSegment startWord ;
459424 if ( e . ClickCount == 3 ) {
460- mode = SelectionMode . WholeLine ;
425+ mode = MouseSelectionMode . WholeLine ;
461426 startWord = GetLineAtMousePosition ( e ) ;
462427 } else {
463- mode = SelectionMode . WholeWord ;
428+ mode = MouseSelectionMode . WholeWord ;
464429 startWord = GetWordAtMousePosition ( e ) ;
465430 }
466431 if ( startWord == SimpleSegment . Invalid ) {
467- mode = SelectionMode . None ;
432+ mode = MouseSelectionMode . None ;
468433 textArea . ReleaseMouseCapture ( ) ;
469434 return ;
470435 }
@@ -484,6 +449,28 @@ void textArea_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
484449 }
485450 e . Handled = true ;
486451 }
452+
453+ public MouseSelectionMode MouseSelectionMode
454+ {
455+ get { return mode ; }
456+ set {
457+ if ( mode == value )
458+ return ;
459+ if ( value == MouseSelectionMode . None ) {
460+ mode = MouseSelectionMode . None ;
461+ textArea . ReleaseMouseCapture ( ) ;
462+ } else if ( textArea . CaptureMouse ( ) ) {
463+ switch ( value ) {
464+ case MouseSelectionMode . Normal :
465+ case MouseSelectionMode . Rectangular :
466+ mode = value ;
467+ break ;
468+ default :
469+ throw new NotImplementedException ( "Programmatically starting mouse selection is only supported for normal and rectangular selections." ) ;
470+ }
471+ }
472+ }
473+ }
487474 #endregion
488475
489476 #region Mouse Position <-> Text coordinates
@@ -585,15 +572,15 @@ void textArea_MouseMove(object sender, MouseEventArgs e)
585572 {
586573 if ( e . Handled )
587574 return ;
588- if ( mode == SelectionMode . Normal || mode == SelectionMode . WholeWord || mode == SelectionMode . WholeLine || mode == SelectionMode . Rectangular ) {
575+ if ( mode == MouseSelectionMode . Normal || mode == MouseSelectionMode . WholeWord || mode == MouseSelectionMode . WholeLine || mode == MouseSelectionMode . Rectangular ) {
589576 e . Handled = true ;
590577 if ( textArea . TextView . VisualLinesValid ) {
591578 // If the visual lines are not valid, don't extend the selection.
592579 // Extending the selection forces a VisualLine refresh, and it is sufficient
593580 // to do that on MouseUp, we don't have to do it every MouseMove.
594581 ExtendSelectionToMouse ( e ) ;
595582 }
596- } else if ( mode == SelectionMode . PossibleDragStart ) {
583+ } else if ( mode == MouseSelectionMode . PossibleDragStart ) {
597584 e . Handled = true ;
598585 Vector mouseMovement = e . GetPosition ( textArea ) - possibleDragStartMousePos ;
599586 if ( Math . Abs ( mouseMovement . X ) > SystemParameters . MinimumHorizontalDragDistance
@@ -616,7 +603,7 @@ void SetCaretOffsetToMousePosition(MouseEventArgs e, ISegment allowedSegment)
616603 int visualColumn ;
617604 bool isAtEndOfLine ;
618605 int offset ;
619- if ( mode == SelectionMode . Rectangular ) {
606+ if ( mode == MouseSelectionMode . Rectangular ) {
620607 offset = GetOffsetFromMousePositionFirstTextLineOnly ( e . GetPosition ( textArea . TextView ) , out visualColumn ) ;
621608 isAtEndOfLine = true ;
622609 } else {
@@ -634,16 +621,16 @@ void SetCaretOffsetToMousePosition(MouseEventArgs e, ISegment allowedSegment)
634621 void ExtendSelectionToMouse ( MouseEventArgs e )
635622 {
636623 TextViewPosition oldPosition = textArea . Caret . Position ;
637- if ( mode == SelectionMode . Normal || mode == SelectionMode . Rectangular ) {
624+ if ( mode == MouseSelectionMode . Normal || mode == MouseSelectionMode . Rectangular ) {
638625 SetCaretOffsetToMousePosition ( e ) ;
639- if ( mode == SelectionMode . Normal && textArea . Selection is RectangleSelection )
626+ if ( mode == MouseSelectionMode . Normal && textArea . Selection is RectangleSelection )
640627 textArea . Selection = new SimpleSelection ( textArea , oldPosition , textArea . Caret . Position ) ;
641- else if ( mode == SelectionMode . Rectangular && ! ( textArea . Selection is RectangleSelection ) )
628+ else if ( mode == MouseSelectionMode . Rectangular && ! ( textArea . Selection is RectangleSelection ) )
642629 textArea . Selection = new RectangleSelection ( textArea , oldPosition , textArea . Caret . Position ) ;
643630 else
644631 textArea . Selection = textArea . Selection . StartSelectionOrSetEndpoint ( oldPosition , textArea . Caret . Position ) ;
645- } else if ( mode == SelectionMode . WholeWord || mode == SelectionMode . WholeLine ) {
646- var newWord = ( mode == SelectionMode . WholeLine ) ? GetLineAtMousePosition ( e ) : GetWordAtMousePosition ( e ) ;
632+ } else if ( mode == MouseSelectionMode . WholeWord || mode == MouseSelectionMode . WholeLine ) {
633+ var newWord = ( mode == MouseSelectionMode . WholeLine ) ? GetLineAtMousePosition ( e ) : GetWordAtMousePosition ( e ) ;
647634 if ( newWord != SimpleSegment . Invalid ) {
648635 textArea . Selection = Selection . Create ( textArea ,
649636 Math . Min ( newWord . Offset , startWord . Offset ) ,
@@ -662,17 +649,17 @@ void ExtendSelectionToMouse(MouseEventArgs e)
662649 #region MouseLeftButtonUp
663650 void textArea_MouseLeftButtonUp ( object sender , MouseButtonEventArgs e )
664651 {
665- if ( mode == SelectionMode . None || e . Handled )
652+ if ( mode == MouseSelectionMode . None || e . Handled )
666653 return ;
667654 e . Handled = true ;
668- if ( mode == SelectionMode . PossibleDragStart ) {
655+ if ( mode == MouseSelectionMode . PossibleDragStart ) {
669656 // -> this was not a drag start (mouse didn't move after mousedown)
670657 SetCaretOffsetToMousePosition ( e ) ;
671658 textArea . ClearSelection ( ) ;
672- } else if ( mode == SelectionMode . Normal || mode == SelectionMode . WholeWord || mode == SelectionMode . WholeLine || mode == SelectionMode . Rectangular ) {
659+ } else if ( mode == MouseSelectionMode . Normal || mode == MouseSelectionMode . WholeWord || mode == MouseSelectionMode . WholeLine || mode == MouseSelectionMode . Rectangular ) {
673660 ExtendSelectionToMouse ( e ) ;
674661 }
675- mode = SelectionMode . None ;
662+ mode = MouseSelectionMode . None ;
676663 textArea . ReleaseMouseCapture ( ) ;
677664 }
678665 #endregion
0 commit comments