public HitTestingVisitor(DrawContext dc, DrawingUtils.Metrics mtx, int clieckedPointX, int lineIndex)
 {
     ctx           = dc;
     ClickedPointX = clieckedPointX;
     m             = mtx;
     TextLineIndex = lineIndex;
 }
        public static void MouseMoveHelper(
            IPresentationDataAccess presentationDataAccess,
            DrawContext drawContext,
            Rectangle clientRectangle,
            IViewEvents viewEvents,
            Point pt,
            bool isLeftDrag,
            out CursorType newCursor
            )
        {
            newCursor = CursorType.Arrow;

            if (presentationDataAccess != null)
            {
                foreach (var i in DrawingUtils.GetVisibleMessagesIterator(drawContext, presentationDataAccess, clientRectangle))
                {
                    DrawingUtils.Metrics mtx = DrawingUtils.GetMetrics(i, drawContext);

                    if (pt.Y >= mtx.MessageRect.Top && pt.Y < mtx.MessageRect.Bottom)
                    {
                        if (isLeftDrag)
                        {
                            var hitTester = new HitTestingVisitor(drawContext, mtx, pt.X, i.TextLineIndex);
                            i.Message.Visit(hitTester);
                            MessageMouseEventFlag flags = MessageMouseEventFlag.ShiftIsHeld
                                                          | MessageMouseEventFlag.CapturedMouseMove;
                            if (pt.X < drawContext.CollapseBoxesAreaSize)
                            {
                                flags |= MessageMouseEventFlag.OulineBoxesArea;
                            }
                            viewEvents.OnMessageMouseEvent(i, hitTester.LineTextPosition, flags, pt);
                        }
                        if (i.Message.IsStartFrame() && mtx.OulineBox.Contains(pt))
                        {
                            newCursor = CursorType.Arrow;
                        }
                        else if (pt.X < drawContext.CollapseBoxesAreaSize)
                        {
                            newCursor = CursorType.RightToLeftArrow;
                        }
                        else if (pt.X >= drawContext.GetTextOffset(0, 0).X)
                        {
                            newCursor = CursorType.IBeam;
                        }
                        else
                        {
                            newCursor = CursorType.Arrow;
                        }
                    }
                }
            }
        }
        public static void MouseDownHelper(
            IPresentationDataAccess presentationDataAccess,
            DrawContext drawContext,
            Rectangle clientRectangle,
            IViewEvents viewEvents,
            Point pt,
            MessageMouseEventFlag flags,
            out bool captureTheMouse
            )
        {
            captureTheMouse = true;

            if (presentationDataAccess != null)
            {
                foreach (var i in DrawingUtils.GetVisibleMessagesIterator(drawContext, presentationDataAccess, clientRectangle))
                {
                    DrawingUtils.Metrics mtx = DrawingUtils.GetMetrics(i, drawContext);

                    // if user clicked line's outline box (collapse/expand cross)
                    if (i.Message.IsStartFrame() && mtx.OulineBox.Contains(pt.X, pt.Y) && i.TextLineIndex == 0)
                    //if (viewEvents.OnOulineBoxClicked(i.Message, (flags & MessageMouseEventFlag.CtrlIsHeld) != 0))
                    {
                        captureTheMouse = false;
                        break;
                    }

                    // if user clicked line area
                    if (mtx.MessageRect.Contains(pt.X, pt.Y))
                    {
                        var hitTester = new HitTestingVisitor(drawContext, mtx, pt.X, i.TextLineIndex);
                        i.Message.Visit(hitTester);
                        if ((flags & MessageMouseEventFlag.DblClick) != 0)
                        {
                            captureTheMouse = false;
                        }
                        if (pt.X < drawContext.CollapseBoxesAreaSize)
                        {
                            flags |= MessageMouseEventFlag.OulineBoxesArea;
                        }
                        viewEvents.OnMessageMouseEvent(i, hitTester.LineTextPosition, flags, pt);
                        break;
                    }
                }
            }
        }
        public static void PaintControl(DrawContext drawContext, IPresentationDataAccess presentationDataAccess,
                                        SelectionInfo selection, bool controlIsFocused, Rectangle dirtyRect, out int maxRight)
        {
            var drawingVisitor = new DrawingVisitor();

            drawingVisitor.ctx = drawContext;
            drawingVisitor.SearchResultHighlightingHandler = presentationDataAccess.CreateSearchResultHighlightingHandler();
            drawingVisitor.SelectionHighlightingHandler    = presentationDataAccess.CreateSelectionHighlightingHandler();
            drawingVisitor.HighlightingFiltersHandler      = presentationDataAccess.CreateHighlightingFiltersHandler();

            maxRight = 0;
            var  sel = selection;
            bool needToDrawCursor = drawContext.CursorState == true && controlIsFocused && sel.First.Message != null;

            var messagesToDraw = DrawingUtils.GetVisibleMessages(drawContext, presentationDataAccess, dirtyRect);

            var displayLinesEnum = presentationDataAccess.GetViewLines(messagesToDraw.begin, messagesToDraw.end);

            foreach (var il in displayLinesEnum)
            {
                drawingVisitor.DisplayIndex = il.LineIndex;
                drawingVisitor.TextLineIdx  = il.TextLineIndex;
                drawingVisitor.IsBookmarked = il.IsBookmarked;
                DrawingUtils.Metrics m = DrawingUtils.GetMetrics(il, drawContext);
                drawingVisitor.m = m;
                if (needToDrawCursor && sel.First.DisplayIndex == il.LineIndex)
                {
                    drawingVisitor.CursorPosition = sel.First;
                }
                else
                {
                    drawingVisitor.CursorPosition = null;
                }

                il.Message.Visit(drawingVisitor);

                maxRight = Math.Max(maxRight, m.OffsetTextRect.Right);
            }

            DrawFocusedMessageMark(drawContext, presentationDataAccess, messagesToDraw);

            drawingVisitor.SearchResultHighlightingHandler?.Dispose();
            drawingVisitor.SelectionHighlightingHandler?.Dispose();
            drawingVisitor.HighlightingFiltersHandler?.Dispose();
        }