private ProfileEventData.ProfileContext.Event GetEventFromMousePositionInContext(FindEventContext findContext, ProfileEventData.ProfileContext.Event profileEvent)
        {
            if (findContext.Time >= profileEvent.Time &&
                findContext.Time <= profileEvent.EndTime)
            {
                // could be in this one, if the depth is good
                if (findContext.TargetDepth == profileEvent.Level)
                {
                    return(profileEvent);
                }

                // depth isn't correct, search the childs
                if (profileEvent.Child != null)
                {
                    ProfileEventData.ProfileContext.Event child = profileEvent.Child;

                    while (child != null)
                    {
                        profileEvent = GetEventFromMousePositionInContext(findContext, child);

                        if (profileEvent != null)
                        {
                            return(profileEvent);
                        }

                        child = child.Sibling;
                    }
                }
            }

            return(null);
        }
        private void ComputeContextSelectionTimes(ProfileEventData.ProfileContext context, ProfileEventData.ProfileContext.Event profileEvent)
        {
            if (profileEvent.Inside(m_RangeStart, m_RangeEnd))
            {
                // Only consider the included time
                Time start = profileEvent.Time;
                Time end   = profileEvent.Time + profileEvent.Length;

                if (start < m_RangeStart)
                {
                    start = m_RangeStart;
                }
                if (end > m_RangeEnd)
                {
                    end = m_RangeEnd;
                }

                // Add
                // profileEvent.m_ProfileID += end-start;
                SelectionInfo oldVal = (SelectionInfo)m_SelectionTimes[profileEvent.ProfileID];
                if (oldVal.m_context.ContainsKey(context.Name) == false)
                {
                    oldVal.m_context.Add(context.Name, new SelectionInfoContext((end - start), 1));
                }
                else
                {
                    SelectionInfoContext selContext;
                    selContext              = (SelectionInfoContext)oldVal.m_context[context.Name];
                    selContext.m_TotalTime += (end - start);
                    selContext.m_Calls++;
                    oldVal.m_context[context.Name] = selContext;
                }

                m_SelectionTimes[profileEvent.ProfileID] = oldVal;
                // Childs
                if (profileEvent.Child != null)
                {
                    ProfileEventData.ProfileContext.Event child = profileEvent.Child;

                    while (child != null)
                    {
                        ComputeContextSelectionTimes(context, child);
                        child = child.Sibling;
                    }
                }
            }
        }
        private ProfileEventData.ProfileContext.Event GetEventFromMousePosition(int x, int y)
        {
            if (x < 0 || x > ClientSize.Width)
            {
                return(null);
            }

            int contextmaxy  = (int)m_YOffset;
            int contextStart = (int)m_YOffset;

            FindEventContext findContext = new FindEventContext();

            int width = ClientSize.Width;

            findContext.Time = ConvertXToTime(x);

            // find which context it's in
            foreach (ProfileEventData.ProfileContext context in m_Data.Contexts.Values)
            {
                if (context.Heads.Count == 0)
                {
                    continue;
                }

                contextmaxy += TitleHeight;
                contextmaxy += ((context.MaxLevel + 1) * EventHeight);

                if (y < contextmaxy)
                {
                    findContext.TargetDepth = ((y - contextStart) - TitleHeight) / (EventHeight);

                    foreach (ProfileEventData.ProfileContext.Event profileEvent in context.Heads)
                    {
                        ProfileEventData.ProfileContext.Event foundEvent = GetEventFromMousePositionInContext(findContext, profileEvent);

                        if (foundEvent != null)
                        {
                            return(foundEvent);
                        }
                    }
                }

                contextStart = contextmaxy;
            }

            return(null);
        }
        private void ProfileEventsViewer_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
        {
            m_LastX = e.X;
            m_LastY = e.Y;

            if (e.Button == MouseButtons.Left)
            {
                if (shiftIsDown)
                {
                    m_MouseMode = MouseMode.Pan;
                    Capture     = true;
                }
                else if (ctrlIsDown)
                {
                    m_FocusTime = ConvertXToTime(e.X);
                    m_MouseMode = MouseMode.ZoomOnLocation;
                    Capture     = true;
                }
                else
                {
                    if (openFileName != null)
                    {
                        m_eventSelection = GetEventFromMousePosition(e.X, e.Y);
                        Invalidate();
                    }
                }
            }

            if (e.Button == MouseButtons.Right)
            {
                Capture      = true;
                m_MouseMode  = MouseMode.MarkRange;
                m_RangeStart = ConvertXToTime(e.X);
                m_RangeEnd   = m_RangeStart;
                m_FocusTime  = m_RangeStart;
            }
        }
        private void DrawEvent(ProfileEventData.ProfileContext.Event profileEvent, ref DrawEventContext drawContext)
        {
            Pen   activeRectPen = rectPen;
            float rectOffset    = 0;

            if (profileEvent == m_eventSelection)
            {
                activeRectPen = rectPenSelected;
                rectOffset    = 1.5f;
            }

            if (profileEvent.Inside(m_TimeStart, m_TimeEnd))
            {
                Int64 screenXEnd = (Int64)((profileEvent.Time + profileEvent.Length - m_TimeStart) / drawContext.m_TimeStepPerPixel);
                if (!drawContext.overDraw.ShouldDraw(screenXEnd))
                {
                    return;
                }

                // compute screen X size
                Int64 screenX      = (Int64)((profileEvent.Time - m_TimeStart) / drawContext.m_TimeStepPerPixel);
                Int64 screenLength = (Int64)((profileEvent.Length) / drawContext.m_TimeStepPerPixel);
                Int64 screenXE     = screenX + screenLength;
                bool  nulSized     = (screenLength == 0);


                // draw a rectangle
                rectBrush.Color = m_Data.GetProfileColor(profileEvent.ProfileID);
                screenX         = Math.Max(-20, screenX);
                screenXE        = Math.Min(ClientSize.Width + 20, screenXE);
                if (screenXE == screenX)
                {
                    screenXE++;
                }
                screenLength = screenXE - screenX;

                int offsetY = 0;
                if (profileEvent.EventType == ProfileEventViewer.ProfileEventData.ProfileContext.Event.EventStart)
                {
                    drawContext.Graphics.FillRectangle(rectBrush, screenX, drawContext.m_Y, screenLength, EventHeight);
                    drawContext.Graphics.DrawRectangle(activeRectPen, screenX + rectOffset, drawContext.m_Y + rectOffset, screenLength - (rectOffset * 2), EventHeight - (rectOffset * 2));
                }
                else
                {
                    //drawContext.Graphics.FillRectangle(rectBrush, screenX, drawContext.m_Y, screenLength, MarkerHeight);
                    offsetY = -2 * EventHeight;

                    rectBrush.Color = Color.Red;
                    drawContext.Graphics.FillRectangle(rectBrush, screenX, drawContext.m_Y + offsetY, screenLength, EventHeight);
                    drawContext.Graphics.DrawRectangle(activeRectPen, screenX + rectOffset, drawContext.m_Y + offsetY + rectOffset, screenLength - (rectOffset * 2), EventHeight - (rectOffset * 2));
                }


                // set the clip region and display the profile name (if there's any chance it could fit)
                if ((screenLength > 20) || (profileEvent == m_eventSelection))
                {
                    Region oldClipRegion = drawContext.Graphics.Clip;
                    drawContext.Graphics.SetClip(new Rectangle((int)screenX + 1, drawContext.m_Y + offsetY, (int)screenLength - 1, EventHeight));

                    string profileName = String.Format("{0}{1}", (screenX < 0) ? "<< " : "", m_Data.GetProfileName(profileEvent.ProfileID));
                    string profileTime = String.Format("{0}{1}", (screenX < 0) ? "<< " : "", TimeToString((UInt64)profileEvent.Length));
                    drawContext.Graphics.DrawString(profileName, barFont, fontBrush, Math.Max(screenX + 1, 0), drawContext.m_Y - 0 + offsetY);
                    drawContext.Graphics.DrawString(profileTime, barFont, fontBrush, Math.Max(screenX + 1, 0), drawContext.m_Y + 10 + offsetY);

                    drawContext.Graphics.Clip = oldClipRegion;
                }

                // must draw the childs (if we were not too small)
                if (profileEvent.Child != null && screenLength > 1)
                {
                    drawContext.Graphics.FillRectangle(selfBrush, screenX, drawContext.m_Y + EventHeight, screenLength, EventHeight);

                    drawContext.m_Y += EventHeight;
                    Int64 keepColumn = drawContext.overDraw.Reset();

                    ProfileEventData.ProfileContext.Event child = profileEvent.Child;

                    while (child != null)
                    {
                        DrawEvent(child, ref drawContext);
                        child = child.Sibling;
                    }

                    drawContext.overDraw.Reset(keepColumn);

                    drawContext.m_Y -= EventHeight;
                }
            }
        }