public override UIHandleResult OnMouseDown(MouseEventArgs args) { if (args.Button != MouseButtons.Left || !_viewer.EnabledEx) { return(UIHandleResult.Pass); } //テキスト選択ではないのでちょっと柄悪いが。UserControl->Controlの置き換えに伴う if (!_viewer.Focused) { _viewer.Focus(); } CharacterDocument document = _viewer.CharacterDocument; lock (document) { int col, row; _viewer.MousePosToTextPos(args.X, args.Y, out col, out row); int target_id = _viewer.GetTopLine().ID + row; TextSelection sel = _viewer.TextSelection; if (sel.State == SelectionState.Fixed) { sel.Clear(); //変なところでMouseDownしたとしてもClearだけはする } if (target_id <= document.LastLineNumber) { //if(InFreeSelectionMode) ExitFreeSelectionMode(); //if(InAutoSelectionMode) ExitAutoSelectionMode(); RangeType rt; //Debug.WriteLine(String.Format("MouseDown {0} {1}", sel.State, sel.PivotType)); //同じ場所でポチポチと押すとChar->Word->Line->Charとモード変化する if (sel.StartX != args.X || sel.StartY != args.Y) { rt = RangeType.Char; } else { rt = sel.PivotType == RangeType.Char ? RangeType.Word : sel.PivotType == RangeType.Word ? RangeType.Line : RangeType.Char; } //マウスを動かしていなくても、MouseDownとともにMouseMoveが来てしまうようだ GLine tl = document.FindLine(target_id); sel.StartSelection(tl, col, rt, args.X, args.Y); } } _viewer.Invalidate(); //NOTE 選択状態に変化のあった行のみ更新すればなおよし return(UIHandleResult.Capture); }
//_documentのうちどれを先頭(1行目)として表示するかを返す public virtual GLine GetTopLine() { return(_document.FindLine(_document.FirstLine.ID + _VScrollBar.Value)); }
public override UIHandleResult OnMouseMove(MouseEventArgs args) { if (args.Button != MouseButtons.Left) { return(UIHandleResult.Pass); } TextSelection sel = _viewer.TextSelection; if (sel.State == SelectionState.Fixed || sel.State == SelectionState.Empty) { return(UIHandleResult.Pass); } //クリックだけでもなぜかMouseDownの直後にMouseMoveイベントが来るのでこのようにしてガード。でないと単発クリックでも選択状態になってしまう if (sel.StartX == args.X && sel.StartY == args.Y) { return(UIHandleResult.Capture); } CharacterDocument document = _viewer.CharacterDocument; lock (document) { int topline_id = _viewer.GetTopLine().ID; SizeF pitch = _viewer.GetRenderProfile().Pitch; int row, col; _viewer.MousePosToTextPos_AllowNegative(args.X, args.Y, out col, out row); int viewheight = (int)Math.Floor(_viewer.ClientSize.Height / pitch.Width); int target_id = topline_id + row; GLine target_line = document.FindLineOrEdge(target_id); TextSelection.TextPoint point = sel.ConvertSelectionPosition(target_line, col); point.Line = RuntimeUtil.AdjustIntRange(point.Line, document.FirstLineNumber, document.LastLineNumber); if (_viewer.VScrollBar.Enabled) //スクロール可能なときは { VScrollBar vsc = _viewer.VScrollBar; if (target_id < topline_id) //前方スクロール { vsc.Value = point.Line - document.FirstLineNumber; } else if (point.Line >= topline_id + vsc.LargeChange) //後方スクロール { int newval = point.Line - document.FirstLineNumber - vsc.LargeChange + 1; if (newval < 0) { newval = 0; } if (newval > vsc.Maximum - vsc.LargeChange) { newval = vsc.Maximum - vsc.LargeChange + 1; } vsc.Value = newval; } } else //スクロール不可能なときは見えている範囲で { point.Line = RuntimeUtil.AdjustIntRange(point.Line, topline_id, topline_id + viewheight - 1); } //ここさぼっている //Debug.WriteLine(String.Format("MouseMove {0} {1} {2}", sel.State, sel.PivotType, args.X)); RangeType rt = sel.PivotType; if ((Control.ModifierKeys & Keys.Control) != Keys.None) { rt = RangeType.Word; } else if ((Control.ModifierKeys & Keys.Shift) != Keys.None) { rt = RangeType.Line; } GLine tl = document.FindLine(point.Line); sel.ExpandTo(tl, point.Column, rt); } _viewer.Invalidate(); //TODO 選択状態に変化のあった行のみ更新するようにすればなおよし return(UIHandleResult.Capture); }