protected internal override void MouseHover (MarginMouseEventArgs args)
{
var loc = PointToLocation (args.X, args.Y, snapCharacters: true);
if (loc.Line < DocumentLocation.MinLine || loc.Column < DocumentLocation.MinColumn)
return;
var line = Document.GetLine (loc.Line);
var oldHoveredLine = HoveredLine;
HoveredLine = line;
HoveredLocation = loc;
OnHoveredLineChanged (new LineEventArgs (oldHoveredLine));
var hoverResult = new TextLineMarkerHoverResult ();
oldMarkers.ForEach (m => m.MouseHover (textEditor, args, hoverResult));
if (line != null) {
newMarkers.Clear ();
newMarkers.AddRange (line.Markers.Where (m => m is IActionTextLineMarker).Cast <IActionTextLineMarker> ());
var extraMarker = Document.GetExtendingTextMarker (loc.Line) as IActionTextLineMarker;
if (extraMarker != null && !oldMarkers.Contains (extraMarker))
newMarkers.Add (extraMarker);
foreach (var marker in newMarkers.Where (m => !oldMarkers.Contains (m))) {
marker.MouseHover (textEditor, args, hoverResult);
}
oldMarkers.Clear ();
var tmp = oldMarkers;
oldMarkers = newMarkers;
newMarkers = tmp;
var locNotSnapped = PointToLocation (args.X, args.Y, snapCharacters: false);
foreach (var marker in Document.GetTextSegmentMarkersAt (Document.GetOffset (locNotSnapped)).Where (m => m.IsVisible)) {
if (marker is IActionTextLineMarker) {
((IActionTextLineMarker)marker).MouseHover (textEditor, args, hoverResult);
}
}
} else {
oldMarkers.Clear ();
}
base.cursor = hoverResult.HasCursor ? hoverResult.Cursor : xtermCursor;
if (textEditor.TooltipMarkup != hoverResult.TooltipMarkup) {
textEditor.TooltipMarkup = null;
textEditor.TriggerTooltipQuery ();
}
if (!textEditor.GetTextEditorData ().SuppressTooltips)
textEditor.TooltipMarkup = hoverResult.TooltipMarkup;
if (args.Button != 1 && args.Y >= 0 && args.Y <= this.textEditor.Allocation.Height) {
// folding marker
int lineNr = args.LineNumber;
foreach (var shownFolding in GetFoldRectangles (lineNr)) {
if (shownFolding.Item1.Contains ((int)(args.X + this.XOffset), (int)args.Y)) {
ShowTooltip (shownFolding.Item2.Segment, shownFolding.Item1);
return;
}
}
ShowTooltip (TextSegment.Invalid, Gdk.Rectangle.Zero);
string link = GetLink != null ? GetLink (args) : null;
if (!String.IsNullOrEmpty (link)) {
base.cursor = textLinkCursor;
} else {
base.cursor = hoverResult.HasCursor ? hoverResult.Cursor : xtermCursor;
}
return;
}
if (inDrag)
return;
Caret.PreserveSelection = true;
switch (this.mouseSelectionMode) {
case MouseSelectionMode.SingleChar:
if (loc.Line != Caret.Line || !textEditor.GetTextEditorData ().IsCaretInVirtualLocation) {
if (!InSelectionDrag) {
textEditor.SetSelection (loc, loc);
} else {
textEditor.ExtendSelectionTo (loc);
}
Caret.Location = loc;
}
break;
case MouseSelectionMode.Word:
if (loc.Line != Caret.Line || !textEditor.GetTextEditorData ().IsCaretInVirtualLocation) {
int offset = textEditor.Document.LocationToOffset (loc);
int start;
int end;
// var data = textEditor.GetTextEditorData ();
if (offset < textEditor.SelectionAnchor) {
start = ScanWord (Document, offset, false);
end = ScanWord (Document, textEditor.SelectionAnchor, true);
Caret.Offset = start;
} else {
start = ScanWord (Document, textEditor.SelectionAnchor, false);
end = ScanWord (Document, offset, true);
Caret.Offset = end;
}
if (!textEditor.MainSelection.IsEmpty) {
if (Caret.Offset < mouseWordStart) {
textEditor.MainSelection = new Selection (Document.OffsetToLocation (mouseWordEnd), Caret.Location, textEditor.MainSelection.SelectionMode);
} else {
textEditor.MainSelection = new Selection (Document.OffsetToLocation (mouseWordStart), Caret.Location, textEditor.MainSelection.SelectionMode);
}
}
}
break;
case MouseSelectionMode.WholeLine:
//textEditor.SetSelectLines (loc.Line, textEditor.MainSelection.Anchor.Line);
DocumentLine line1 = textEditor.Document.GetLine (loc.Line);
DocumentLine line2 = textEditor.Document.GetLineByOffset (textEditor.SelectionAnchor);
var o2 = line1.Offset < line2.Offset ? line1.Offset : line1.EndOffsetIncludingDelimiter;
Caret.Offset = o2;
if (!textEditor.MainSelection.IsEmpty) {
if (mouseWordStart < o2) {
textEditor.MainSelection = new Selection (textEditor.OffsetToLocation (mouseWordStart), Caret.Location, textEditor.MainSelection.SelectionMode);
} else {
textEditor.MainSelection = new Selection (textEditor.OffsetToLocation (mouseWordEnd), Caret.Location, textEditor.MainSelection.SelectionMode);
}
}
break;
}
Caret.PreserveSelection = false;
//HACK: use cmd as Mac block select modifier because GTK currently makes it impossible to access alt/mod1
//NOTE: Mac cmd seems to be mapped as ControlMask from mouse events on older GTK, mod1 on newer
var blockSelModifier = !Platform.IsMac ? ModifierType.Mod1Mask
: (ModifierType.ControlMask | ModifierType.Mod1Mask);
//NOTE: also allow super for block select on X11 because most window managers use the alt modifier already
if (Platform.IsX11)
blockSelModifier |= (ModifierType.SuperMask | ModifierType.Mod4Mask);
if ((args.ModifierState & blockSelModifier) != 0) {
textEditor.SelectionMode = SelectionMode.Block;
} else {
if (textEditor.SelectionMode == SelectionMode.Block)
Document.CommitMultipleLineUpdate (textEditor.MainSelection.MinLine, textEditor.MainSelection.MaxLine);
textEditor.SelectionMode = SelectionMode.Normal;
}
InSelectionDrag = true;
base.MouseHover (args);
}