protected override void DisposeAll()
 {
     base.DisposeAll();
     cachedCallsData.Clear();
     selectedCall = null;
     selectedCallPos = 0;
     selectedFrame = 0;
     timelineFrame = 0;
 }
        private void UpdateKeyInput()
        {
            if (!hasFocus || Event.current == null || selectedCall == null)
                return;

            EventType eventType = Event.current.type;

            //--------------- Check for repaint first --------------------
            if (eventType == EventType.keyDown || eventType == EventType.keyUp || eventType == EventType.mouseUp || eventType == EventType.mouseDrag)
                Repaint();
            //--------------- Check for repaint first --------------------

            if (eventType == EventType.keyDown && downTimeStamp == -1d)
            {
                downTimeStamp = vBugEnvironment.GetUnixTimestamp();
            }
            else if (eventType == EventType.keyUp || (downTimeStamp != -1 && vBugEnvironment.GetUnixTimestamp() - downTimeStamp > 0.3f))
            {
                if (eventType == EventType.keyUp)
                    downTimeStamp = -1d;

                if (selectedCall != null && cachedCallsData.Count > 0)
                {

                    //--------------- Get Key-direction --------------------
                    int direction = 0;
                    KeyCode keyCode = Event.current.keyCode;
                    if (keyCode == KeyCode.UpArrow)
                    {
                        direction = -1;
                    }
                    else if (keyCode == KeyCode.DownArrow)
                    {
                        direction = +1;
                    }
                    //--------------- Get Key-direction --------------------

                    if (direction != 0)
                    {

                        int cacheIdx = 0;
                        int callIdx = 0;
                        if (FindContainingCache(selectedCall, out cacheIdx, out callIdx))
                        {

                            //--------------- Increment / decrement --------------------
                            if (direction < 0 && cacheIdx > 0 && callIdx == 0)
                            {
                                cacheIdx -= 1;
                                callIdx = cachedCallsData[cacheIdx].calls.Length - 1;
                            }
                            else if (direction > 0 && cacheIdx < cachedCallsData.Count - 1 && callIdx == cachedCallsData[cacheIdx].calls.Length - 1)
                            {
                                cacheIdx += 1;
                                callIdx = 0;
                            }
                            else
                            {
                                callIdx = Mathf.Clamp(callIdx + direction, 0, cachedCallsData[cacheIdx].calls.Length - 1);
                            }
                            selectedCall = cachedCallsData[cacheIdx].calls[callIdx];
                            selectedCallPos = cachedCallsData[cacheIdx].y + (callIdx * ElementHeight);
                            selectedFrame = cachedCallsData[cacheIdx].frameNumber;
                            //--------------- Increment / decrement --------------------

                            //--------------- Snap scroll based on selection --------------------
                            if (selectedCall != null)
                            {
                                float selectedScreenPos = selectedCallPos - messagesScroll.y;
                                if (direction < 0 && selectedScreenPos < 0)
                                {
                                    messagesScroll.y -= ElementHeight;
                                }
                                else if (direction > 0 && selectedScreenPos > dragBarRect.y - ElementHeight)
                                {
                                    messagesScroll.y += Mathf.Abs(selectedScreenPos - dragBarRect.y) + ElementHeight;
                                }
                            }
                            //--------------- Snap scroll based on selection --------------------
                        }
                    }
                }
            }
        }
 private bool FindContainingCache(DebugLogCall selectedCall, out int cacheIdx, out int callIdx)
 {
     int i = cachedCallsData.Count;
     while (--i > -1)
     {
         CallCachdeData compair = cachedCallsData[i];
         int j = compair.calls.Length;
         while (--j > -1)
         {
             if (compair.calls[j] == selectedCall)
             {
                 cacheIdx = i;
                 callIdx = j;
                 return true;
             }
         }
     }
     cacheIdx = -1;
     callIdx = -1;
     return false;
 }
 private void PruneCache()
 {
     cachedCallsData.Clear();
     selectedCall = null;
     selectedCallPos = 0;
     selectedFrame = 0;
 }
        private void DrawAllAvailableLogs(float scrollPos)
        {
            if (cachedCallsData.Count == 0)
                return;

            int startX = 32;
            int halfHeight = ElementHeight / 2;
            float winWidth = this.position.width - 15;
            bool pingPong = false;

            Texture2D tA = VisualResources.proConsoleRowDark;
            Texture2D tB = VisualResources.proConsoleRowLight;
            Texture2D tSelection = VisualResources.proSelection;
            Texture2D tOrange = VisualResources.timelineOrange;
            Color alphaColor = new Color(1f, 1f, 1f, 0.35f);

            bool mouseUp = Event.current != null && Event.current.type == EventType.mouseUp;
            Vector2 mousePos = Event.current != null ? Event.current.mousePosition : Vector2.zero;

            int iMax = cachedCallsData.Count;
            GUILayoutUtility.GetRect(winWidth, cachedCallsData[iMax - 1].y + cachedCallsData[iMax - 1].height);

            for (int i = 0; i < iMax; i++)
            {
                CallCachdeData cached = cachedCallsData[i];
                float screenPos = cached.y - scrollPos;

                Rect rect = new Rect(0, cached.y, winWidth, cached.height);

                if (screenPos > -cached.height && screenPos < dragBarRect.y)
                {
                    pingPong = i % 2 == 0;
                    VisualResources.DrawTexture(rect, pingPong ? tA : tB);
                    Texture2D line = pingPong ? tB : tA;

                    //--------------- Box on right --------------------
                    float boxRightX = winWidth - BoxRightSize;
                    GUI.color = alphaColor;
                    if (cached.frameNumber == timelineFrame){
                        VisualResources.DrawTexture(new Rect(boxRightX, cached.y, BoxRightSize, cached.height), tOrange);
                    } else if (cached.frameNumber == selectedFrame && selectedCall != null) { //if selected - box on right
                        VisualResources.DrawTexture(new Rect(boxRightX, cached.y, BoxRightSize, cached.height), tSelection);
                    }
                    GUI.color = Color.white;
                    //--------------- Box on right --------------------

                    int cMax = cached.calls.Length;
                    for (int j = 0; j < cMax; j++) {

                        //--------------- Draw logs, selections & timestamp --------------------
                        DebugLogCall call = cached.calls[j];
                        float subPosY = cached.y + (j * ElementHeight);
                        Rect logRect = new Rect(0, subPosY, winWidth - BoxRightSize, ElementHeight);

                        if (mouseUp && logRect.Contains(mousePos))
                        {
                            double tapTimeStamp = vBugEnvironment.GetUnixTimestamp();

                            if (selectedCall == call && tapTimeStamp - doubleTapTimeStamp < 0.33f)
                                vBugWindowMediator.NotifyTimelineChange(cached.frameNumber, this.GetInstanceID());

                            selectedCall = call;
                            selectedCallPos = cached.y;
                            selectedFrame = cached.frameNumber;
                            doubleTapTimeStamp = tapTimeStamp;
                        }

                        if (selectedCall == call) //if selected
                            VisualResources.DrawTexture(logRect, tSelection);

                        Rect horLine = new Rect(0, logRect.y - 1, logRect.width - 4, 1);
                        if (j > 0)
                            VisualResources.DrawTexture(horLine, line);

                        logRect.height = halfHeight;
                        logRect.x = startX;
                        logRect.width -= startX;
                        GUI.Label(logRect, call.logString, EditorHelper.styleLabelLightGray12);

                        logRect.y += halfHeight;
                        GUI.color = alphaColor;
                        GUI.Label(logRect, cached.niceTimeStamp[j], EditorHelper.styleLabelLightGray12);
                        GUI.color = Color.white;
                        //--------------- Draw logs, selections & timestamp --------------------

                        //--------------- Vert line --------------------
                        Rect vertRect = new Rect(boxRightX, cached.y + 4, 1, cached.height - 8);
                        VisualResources.DrawTexture(vertRect, line);
                        //--------------- Vert line --------------------

                        //--------------- framenumber --------------------
                        Vector2 labelSize = EditorHelper.styleLabelLightGray12.CalcSize(new GUIContent(cached.niceFrameNumber));
                        GUI.Label(new Rect(
                            vertRect.x + (BoxRightSize / 2) - (labelSize.x / 2),
                            cached.y + (cached.height / 2) - (labelSize.y / 2),
                            100, ElementHeight), cached.niceFrameNumber, EditorHelper.styleLabelLightGray12);
                        //--------------- framenumber --------------------

                        //--------------- Draw icons --------------------
                        int subIconIdx = 0;
                        switch (call.type)
                        {
                            case LogType.Warning:
                                subIconIdx = 0;
                                break;
                            case LogType.Log:
                                subIconIdx = 1; //goed
                                break;
                            case LogType.Exception:
                                subIconIdx = 2;
                                break;
                            case LogType.Assert:
                            case LogType.Error:
                                subIconIdx = 3;
                                break;
                        }
                        VisualResources.DrawIcon(EditorIcon.consoleLogs, subIconIdx, new Vector2(0, subPosY), 1f, false);
                        //--------------- Draw icons --------------------
                    }

                }
            }
        }