Example #1
0
        void HandlePendingEvents(Rect Canvas, List <DataStreamMeta> Streams)
        {
            System.Func <Vector2, TimeUnit?> CanvasPositionToTime = (Position) =>
            {
                return(PositionToTime(Canvas, Position));
            };

            System.Func <Vector2, StreamAndTime> CanvasPositionToStreamAndTime = (Position) =>
            {
                int?StreamIndex;
                var Time = PositionToTime(Canvas, Position, Streams, out StreamIndex);
                return(new StreamAndTime(Streams[StreamIndex.Value], Time.Value));
            };

            Input.ProcessScroll((ScrollTime) =>
            {
                ScrollTimeLeft.Time += ScrollTime.Time;
                StickyScroll         = false;
            });

            Input.ProcessSelect(CanvasPositionToTime, (SelectTime) =>
            {
                LastStickySelectTime = null;
                if (SelectTime.HasValue)
                {
                    OnSelectTime(SelectTime.Value);
                }
            });

            Input.ProcessHover(CanvasPositionToTime, (HoverTime) =>
            {
                OnMouseHover(HoverTime);
            });


            if (Input.MouseDragCurrentPosition.HasValue)
            {
                //	new drag
                if (CurrentDrag == null)
                {
                    CurrentDrag            = new DragMeta();
                    CurrentDrag.DragAmount = new TimeUnit(0);

                    CurrentDrag.GrabTime = PositionToTime(Canvas, Input.MouseDragCurrentPosition.Value, Streams, out CurrentDrag.StreamIndex);

                    //	check is draggable
                    CurrentDrag.Draggable = false;
                    try
                    {
                        var Stream = Streams[CurrentDrag.StreamIndex.Value];
                        CurrentDrag.Draggable = Stream.Draggable;
                    }
                    catch
                    {
                        CurrentDrag.Draggable = false;
                    }
                }
                else
                {
                    if (CurrentDrag.Draggable)
                    {
                        //	update drag
                        var NewDragTime = PositionToTime(Canvas, Input.MouseDragCurrentPosition.Value);
                        if (CurrentDrag.GrabTime.HasValue && NewDragTime.HasValue)
                        {
                            CurrentDrag.DragAmount = new TimeUnit(NewDragTime.Value.Time - CurrentDrag.GrabTime.Value.Time);
                        }
                    }
                }
                Input.MouseDragCurrentPosition = null;
            }

            //	drag released
            if (Input.MouseDragEndPosition.HasValue)
            {
                //	invoke the drag
                try
                {
                    var Stream = Streams[CurrentDrag.StreamIndex.Value];
                    if (Stream.OnDragged != null)
                    {
                        Stream.OnDragged(CurrentDrag.GrabTime.Value, CurrentDrag.DragAmount);
                    }
                }
                catch (System.Exception e)
                {
                    Debug.LogException(e);
                }
                CurrentDrag = null;
                Input.MouseDragEndPosition = null;
            }

            if (Input.MouseJumpPrevPos.HasValue)
            {
                try
                {
                    int?StreamIndex;
                    var JumpFromTime = PositionToTime(Canvas, Input.MouseJumpPrevPos.Value, Streams, out StreamIndex);
                    //	get prev pos in stream
                    var PrevItemTime = new TimeUnit(JumpFromTime.Value.Time - 1);
                    var PrevItem     = Bridge.GetNearestOrPrevStreamData(Streams[StreamIndex.Value], ref PrevItemTime);

                    //	want the item to appear under mouse (where we clicked)
                    var ScrollOffset = JumpFromTime.Value.Time - ScrollTimeLeft.Time;
                    var PrevTimeLeft = PrevItemTime.Time - ScrollOffset;
                    ScrollTimeLeft = new TimeUnit(PrevTimeLeft);
                }
                catch (System.Exception)
                {
                    //	probably no more data
                    EditorApplication.Beep();
                    //Debug.LogException(e);
                }
                finally
                {
                    Input.MouseJumpPrevPos = null;
                }
            }


            if (Input.MouseJumpNextPos.HasValue)
            {
                try
                {
                    int?StreamIndex;
                    var JumpFromTime = PositionToTime(Canvas, Input.MouseJumpNextPos.Value, Streams, out StreamIndex);
                    var NextItemTime = new TimeUnit(JumpFromTime.Value.Time + 1);
                    var NextItem     = Bridge.GetNearestOrNextStreamData(Streams[StreamIndex.Value], ref NextItemTime);

                    //	want the item to appear under mouse (where we clicked)
                    var ScrollOffset = JumpFromTime.Value.Time - ScrollTimeLeft.Time;
                    var NextTimeLeft = NextItemTime.Time - ScrollOffset;
                    ScrollTimeLeft = new TimeUnit(NextTimeLeft);
                }
                catch (System.Exception)
                {
                    //	probably no more data
                    EditorApplication.Beep();
                    //Debug.LogException(e);
                }
                finally
                {
                    Input.MouseJumpNextPos = null;
                }
            }


            Input.ProcessMenuClick(CanvasPositionToStreamAndTime, (StreamAndTime) =>
            {
                if (StreamAndTime.Stream.OnCreateContextMenu == null)
                {
                    EditorApplication.Beep();
                    return;
                }

                //	create the menu and add items to it
                var Menu = new GenericMenu();

                EnumCommand AppendMenuItem = (Label, Lambda) =>
                {
                    if (string.IsNullOrEmpty(Label) || Label.EndsWith("-"))
                    {
                        //	todo; use path
                        Menu.AddSeparator(null);
                    }
                    else if (Lambda == null)
                    {
                        Menu.AddDisabledItem(new GUIContent(Label));
                    }
                    else
                    {
                        //	argh damned delegates
                        GenericMenu.MenuFunction Callback = () => { Lambda(); };
                        Menu.AddItem(new GUIContent(Label), false, Callback);
                    }
                };

                StreamAndTime.Stream.OnCreateContextMenu(StreamAndTime.Time, AppendMenuItem);
                Menu.ShowAsContext();
            });
        }
Example #2
0
        public void Draw(Rect CanvasRect, TimeUnit LeftTime, TimeUnit RightTime, TimeUnit?SelectedTime, TimeUnit?HoverTime, DataBridge Data, List <DataStreamMeta> Streams, DragMeta DragMeta)
        {
            EditorGUI.DrawRect(CanvasRect, CanvasBackgroundColour);
            //DrawWholeView (Canvas, LeftTime, RightTime, Data);

            var StreamRects = new Rect[Streams.Count];

            for (int s = 0; s < Streams.Count; s++)
            {
                var st0 = (s + 0) / (float)Streams.Count;
                var st1 = (s + 1) / (float)Streams.Count;

                var StreamBorder = 1;
                var Top          = Mathf.Lerp(CanvasRect.min.y + StreamBorder, CanvasRect.max.y, st0);
                var Bot          = Mathf.Lerp(CanvasRect.min.y + StreamBorder, CanvasRect.max.y, st1) - StreamBorder;
                var Left         = CanvasRect.min.x + StreamBorder;
                var Right        = CanvasRect.max.x - StreamBorder;
                var StreamRect   = new Rect(Left, Top, Right - Left, Bot - Top);
                StreamRects [s] = StreamRect;
            }

            var  DrawCap            = MaxDataDraws;
            Rect?FirstSelectionRect = null;

            //	draw streams
            for (int s = 0; s < Streams.Count; s++)
            {
                var StreamRect = StreamRects [s];
                var Stream     = Streams [s];
                EditorGUI.DrawRect(StreamRect, StreamBackgroundColour);
                var StreamColour = Stream.Colour;

                //	get all the data in the visible region
                var StreamDatas    = Data.GetStreamData(Stream, LeftTime, RightTime);
                var StreamDataRect = new Rect(0, 0, 1, 1);
                var MinWidthPx     = 1;

                System.Func <TimeUnit, TimeUnit, Color, DataState, Rect> DrawMarker = (DataTimeLeft, DataTimeRight, Colour, State) =>
                {
                    var LeftNorm  = GetTimeNormalised(LeftTime, RightTime, DataTimeLeft);
                    var RightNorm = GetTimeNormalised(LeftTime, RightTime, DataTimeRight);
                    StreamDataRect.x     = LeftNorm;
                    StreamDataRect.width = RightNorm - LeftNorm;
                    var DrawStreamDataRect = PopMath.RectMult(StreamDataRect, StreamRect);

                    DrawStreamDataRect.width = Mathf.Max(MinWidthPx, DrawStreamDataRect.width);
                    if (DrawStreamDataRect.width <= 2.0f)
                    {
                        DrawStreamDataRect.width = MinWidthPx;
                    }

                    //	giant rects kill performance (CPU renderer??)
                    DrawStreamDataRect = DrawStreamDataRect.ClipToParent(StreamRect);

                    if (State == DataState.Loaded)
                    {
                        EditorGUI.DrawRect(DrawStreamDataRect, Colour);
                    }
                    else
                    {
                        var StripeHeight = 2;
                        int i            = 0;
                        var yoffset      = (DrawStreamDataRect.height % StripeHeight) - (StripeHeight / 2.0f);
                        for (var y = 0; y < DrawStreamDataRect.height + StripeHeight; y += StripeHeight, i++)
                        {
                            if (i % 3 == 2)
                            {
                                continue;
                            }
                            var Rect = DrawStreamDataRect;
                            Rect.y      = y + yoffset + DrawStreamDataRect.yMin;
                            Rect.height = StripeHeight;
                            //	clip
                            if (Rect.yMin > DrawStreamDataRect.yMax)
                            {
                                continue;
                            }
                            Rect.yMin = Mathf.Max(Rect.yMin, DrawStreamDataRect.yMin);
                            Rect.yMax = Mathf.Min(Rect.yMax, DrawStreamDataRect.yMax);
                            EditorGUI.DrawRect(Rect, Colour);
                        }
                    }

                    return(DrawStreamDataRect);
                };

                System.Func <TimeUnit, TimeUnit, Color, DataState, Rect> DrawData = (DataTimeLeft, DataTimeRight, Colour, State) =>
                {
                    var DrawStreamDataRect = DrawMarker(DataTimeLeft, DataTimeRight, Colour, State);

                    //	put some notches in long data
                    //	gr: correct the notches for the clipping change
                    //	gr: also, on mega long data, this causes a giant loop. start & end at nearest (also fixes above)
                    var DurationMs      = DataTimeRight.Time - DataTimeLeft.Time;
                    var MaxLoopDuration = 10000;
                    var NotchStep       = Stream.NotchStepMs.HasValue ? Stream.NotchStepMs.Value : DurationMs;
                    for (int NotchMs = NotchStep; NotchMs < DurationMs && DurationMs < MaxLoopDuration; NotchMs += NotchStep)
                    {
                        var LeftNorm = GetTimeNormalised(LeftTime, RightTime, new TimeUnit(DataTimeLeft.Time + NotchMs));
                        //var RightNorm = LeftNorm;
                        StreamDataRect.x     = LeftNorm;
                        StreamDataRect.width = 0;
                        var NotchDrawStreamDataRect = PopMath.RectMult(StreamDataRect, StreamRect);
                        NotchDrawStreamDataRect.width = MinWidthPx;
                        NotchDrawStreamDataRect       = NotchDrawStreamDataRect.ClipToParent(StreamRect);
                        EditorGUI.DrawRect(NotchDrawStreamDataRect, BlockNotchColour);
                    }

                    //	change cursor if this is draggable
                    if (Stream.Draggable)
                    {
                        EditorGUIUtility.AddCursorRect(DrawStreamDataRect, MouseCursor.Pan);
                    }

                    return(DrawStreamDataRect);
                };

                System.Func <TimeUnit, Color, Rect> DrawLine = (DataTimeLeft, Colour) =>
                {
                    var SelectedTimeDuration = 16;
                    var DataTimeRight        = new TimeUnit(DataTimeLeft.Time + SelectedTimeDuration);
                    return(DrawMarker(DataTimeLeft, DataTimeRight, Colour, DataState.Loaded));
                };

                //	draw hover underneath
                if (HoverTime.HasValue)
                {
                    var SelectedTimeLeft = HoverTime.Value;
                    DrawLine(SelectedTimeLeft, HoverColour);
                }


                foreach (var StreamData in StreamDatas)
                {
                    if (DrawCap-- <= 0)
                    {
                        break;
                    }

                    DrawData(StreamData.GetStartTime(), StreamData.GetEndTime(), StreamColour, StreamData.GetStatus());

                    //	draw again offset by drag
                    if (DragMeta != null && DragMeta.Draggable && DragMeta.StreamIndex == s)
                    {
                        var DraggedStartTime = new TimeUnit(StreamData.GetStartTime().Time + DragMeta.DragAmount.Time);
                        var DraggedEndTime   = new TimeUnit(StreamData.GetEndTime().Time + DragMeta.DragAmount.Time);
                        DrawData(DraggedStartTime, DraggedEndTime, DragColour, StreamData.GetStatus());
                    }
                }

                //	draw selection over the top
                if (SelectedTime.HasValue)
                {
                    var SelectedTimeLeft = SelectedTime.Value;
                    var Rect             = DrawLine(SelectedTimeLeft, SelectionColour);
                    if (!FirstSelectionRect.HasValue)
                    {
                        FirstSelectionRect = Rect;
                    }
                }

                //	draw text over that
                var LabelStyle = new GUIStyle();
                LabelStyle.alignment        = TextAnchor.LowerLeft;
                LabelStyle.fontStyle        = StreamLabelFontStyle;
                LabelStyle.normal.textColor = StreamLabelColour;
                EditorGUI.DropShadowLabel(StreamRect, Stream.Name, LabelStyle);
            }


            //	draw time labels
            {
                var LabelStyle = new GUIStyle();
                LabelStyle.alignment        = TextAnchor.UpperLeft;
                LabelStyle.fontStyle        = TimeLabelFontStyle;
                LabelStyle.normal.textColor = TimeLabelColour;
                EditorGUI.DropShadowLabel(CanvasRect, "|< " + LeftTime.GetLabel(false), LabelStyle);
            }
            {
                var LabelStyle = new GUIStyle();
                LabelStyle.alignment        = TextAnchor.UpperRight;
                LabelStyle.fontStyle        = TimeLabelFontStyle;
                LabelStyle.normal.textColor = TimeLabelColour;
                EditorGUI.DropShadowLabel(CanvasRect, RightTime.GetLabel(false) + " >|", LabelStyle);
            }
            if (SelectedTime.HasValue && FirstSelectionRect.HasValue)
            {
                var LabelStyle = new GUIStyle();
                LabelStyle.alignment        = TextAnchor.UpperLeft;
                LabelStyle.fontStyle        = SelectedTimeLabelFontStyle;
                LabelStyle.normal.textColor = SelectedTimeLabelColour;
                var Label = "\n<<" + SelectedTime.Value.GetLabel(true);
                EditorGUI.DropShadowLabel(FirstSelectionRect.Value, Label, LabelStyle);
            }

            if (DrawCap <= 0)
            {
                Debug.Log("Exceeded draw cap");
            }
        }