private TimelineNode BuildTimelineTree(BinaryReader reader) { uint numEvents = reader.ReadUInt32(); TimelineNode root = new TimelineNode(CompilerData.CompileCategory.Thread.ToString(), 0, 0, CompilerData.CompileCategory.Thread); TimelineNode parent = root; for (uint i = 0u; i < numEvents; ++i) { TimelineNode newNode = LoadNode(reader); //Find parent node while (parent != root && (newNode.Start >= (parent.Start + parent.Duration))) { parent = parent.Parent; } parent.AddChild(newNode); parent = newNode.Duration == 0 ? parent : newNode; } AdjustNodeProperties(root); return(root); }
private TimelineNode BuildTimelineRoot(BinaryReader reader, UnitValue unit) { uint numTracks = reader.ReadUInt32(); TimelineNode root = new TimelineNode("", 0, 0, CompilerData.CompileCategory.Timeline); InitializeNodeRecursive(root); for (uint i = 0; i < numTracks; ++i) { TimelineNode tree = BuildTimelineTree(reader); if (tree.Children.Count > 0 && tree.Children[0].Category == CompilerData.CompileCategory.ExecuteCompiler) { //skip the thread for the main track tree = tree.Children[0]; tree.Value = unit; } //Initialize nodes InitializeNodeRecursive(tree, GetBaseDepthLevel(root, tree)); root.MaxDepthLevel = Math.Max(root.MaxDepthLevel, tree.MaxDepthLevel); root.AddChild(tree); } AdjustNodeProperties(root); root.Value = unit; root.Label = unit.Name + " ( " + Common.UIConverters.GetTimeStr(root.Duration) + " )"; return(root.Children.Count > 0? root : null); }
private void CreateContextualMenu(TimelineNode node) { ThreadHelper.ThrowIfNotOnUIThread(); System.Windows.Forms.ContextMenuStrip contextMenuStrip = new System.Windows.Forms.ContextMenuStrip(); bool isVisualStudio = EditorContext.IsEnvironment(EditorContext.ExecutionEnvironment.VisualStudio); if (node.Value is CompileValue) { var value = node.Value as CompileValue; if (isVisualStudio && node.Category == CompilerData.CompileCategory.Include) { contextMenuStrip.Items.Add(Common.UIHelpers.CreateContextItem("Open Location (Experimental)", (sender, e) => EditorUtils.OpenFile(value.Name))); } if (value.Name.Length > 0) { contextMenuStrip.Items.Add(Common.UIHelpers.CreateContextItem("Copy Name", (sender, e) => Clipboard.SetText(value.Name))); } } else if (node.Value is UnitValue) { var value = node.Value as UnitValue; if (value.Name.Length > 0) { contextMenuStrip.Items.Add(Common.UIHelpers.CreateContextItem("Copy Name", (sender, e) => Clipboard.SetText(value.Name))); } } contextMenuStrip.Show(System.Windows.Forms.Control.MousePosition); }
private void RenderFake(DrawingContext drawingContext, TimelineNode node) { double posX = TimeToPixel(node.Start); double width = TimeToPixel(node.Duration); double posY = DepthToPixel(node.DepthLevel); drawingContext.DrawRectangle(this.Foreground, null, new Rect(posX, posY, width, NodeHeight * (1 + node.MaxDepthLevel - node.DepthLevel))); }
private void ComputeFlatNameListRecursive(List <string> list, TimelineNode node) { list.Add(node.Label); foreach (TimelineNode child in node.Children) { ComputeFlatNameListRecursive(list, child); } }
private void OnScrollViewerLoaded(object sender, RoutedEventArgs e) { //Fix the issue with the colored corner square ((Rectangle)scrollViewer.Template.FindName("Corner", scrollViewer)).Fill = scrollViewer.Background; SetupCanvas(); FocusNode(FocusPending == null? Root : FocusPending); FocusPending = null; RefreshAll(); }
private void AdjustNodeProperties(TimelineNode node) { if (node.Children.Count > 0) { node.Start = node.Children[0].Start; foreach (TimelineNode child in node.Children) { node.Duration = Math.Max(node.Duration, (child.Start + child.Duration) - node.Start); } } }
private uint GetBaseDepthLevel(TimelineNode root, TimelineNode input) { uint maxLevel = 1; foreach (TimelineNode child in root.Children) { maxLevel = Math.Max(maxLevel, GetSectionDepthLevel(child, input.Start, input.Start + input.Duration) + 2); } return(maxLevel); }
private void SetRoot(TimelineNode root) { Root = root; nodeSearchBox.SetData(ComputeFlatNameList()); pixelToTimeRatio = -1.0; restoreScrollX = -1.0; restoreScrollY = -1.0; SetupCanvas(); RefreshAll(); }
private void InitializeNodeRecursive(TimelineNode node, uint baseDepth = 0) { node.DepthLevel = node.Parent == null ? baseDepth : node.Parent.DepthLevel + 1; node.MaxDepthLevel = node.DepthLevel; node.UIColor = Common.Colors.GetCategoryBackground(node.Category); foreach (TimelineNode child in node.Children) { InitializeNodeRecursive(child, baseDepth); node.MaxDepthLevel = Math.Max(node.MaxDepthLevel, child.MaxDepthLevel); } }
public TimelineNode LoadTimeline(UnitValue unit) { ThreadHelper.ThrowIfNotOnUIThread(); if (unit == null) { return(null); } uint timelineId = unit.Index; //compute full path uint timelineFileNum = timelineId / timelinePacking; uint timelineInFileNum = timelineId % timelinePacking; string fullPath = CompilerData.Instance.GetScoreFullPath() + ".t" + timelineFileNum.ToString().PadLeft(TIMELINE_FILE_NUM_DIGITS, '0'); TimelineNode root = null; if (File.Exists(fullPath)) { FileStream fileStream = File.Open(fullPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); using (BinaryReader reader = new BinaryReader(fileStream)) { uint thisVersion = reader.ReadUInt32(); if (thisVersion == CompilerData.VERSION) { for (uint i = 0; i < timelineInFileNum && !ReachedEndOfStream(reader); ++i) { SkipTimeline(reader); } if (!ReachedEndOfStream(reader)) { root = BuildTimelineRoot(reader, unit); } } else { OutputLog.Error("Version mismatch! Expected " + CompilerData.VERSION + " - Found " + thisVersion + " - Please export again with matching Data Exporter"); } } fileStream.Close(); } return(root); }
private uint GetSectionDepthLevel(TimelineNode node, uint from, uint to) { if (node.Start > to || (node.Start + node.Duration) < from) { //early exit, no overlap return(0); } uint level = node.DepthLevel; foreach (TimelineNode child in node.Children) { level = Math.Max(level, GetSectionDepthLevel(child, from, to)); } return(level); }
private TimelineNode FindNodeByValueRecursive(TimelineNode node, object value) { if (node.Value == value) { return(node); } foreach (TimelineNode child in node.Children) { TimelineNode found = FindNodeByValueRecursive(child, value); if (found != null) { return(found); } } return(null); }
TimelineNode FindNodeByNameRecursive(TimelineNode node, string name) { if (node.Label == name) { return(node); } foreach (TimelineNode child in node.Children) { TimelineNode found = FindNodeByNameRecursive(child, name); if (found != null) { return(found); } } return(null); }
private void SetHoverNode(TimelineNode node) { if (node != Hover) { //Close Tooltip tooltip.IsOpen = false; tooltipTimer.Stop(); Hover = node; //Start Tooltip if applicable if (Hover != null) { tooltipTimer.Start(); } RenderOverlay(); } }
private void FocusNode(TimelineNode node) { if (node != null && Root != null) { const double margin = 10; double viewPortWidth = scrollViewer.ViewportWidth - 2 * margin; double zoom = node.Duration == 0? GetMaxZoom() : (viewPortWidth > 0 ? viewPortWidth / node.Duration : 0); pixelToTimeRatio = Math.Max(Math.Min(zoom, GetMaxZoom()), GetMinZoom()); double scrollOffset = (node.Start * pixelToTimeRatio) - margin; double verticalOffset = ((node.DepthLevel + 0.5) * NodeHeight) - (scrollViewer.ViewportHeight * 0.5); canvas.Width = Root.Duration * pixelToTimeRatio; scrollViewer.ScrollToHorizontalOffset(scrollOffset); scrollViewer.ScrollToVerticalOffset(verticalOffset); RefreshZoomSlider(); } }
private void RenderNodeRecursive(DrawingContext drawingContext, TimelineNode node, double clipTimeStart, double clipTimeEnd, double clipDepth, double fakeDurationThreshold) { //Clipping and LODs if (node.Duration == 0 || node.Start > clipTimeEnd || (node.Start + node.Duration) < clipTimeStart || node.DepthLevel > clipDepth) { return; } else if (node.Duration < fakeDurationThreshold) { RenderFake(drawingContext, node); } else { RenderNodeSingle(drawingContext, node, node.UIColor, clipTimeStart, clipTimeEnd); foreach (TimelineNode child in node.Children) { RenderNodeRecursive(drawingContext, child, clipTimeStart, clipTimeEnd, clipDepth, fakeDurationThreshold); } } }
private void RenderNodeSingle(DrawingContext drawingContext, TimelineNode node, Brush brush, double clipTimeStart, double clipTimeEnd) { double posY = DepthToPixel(node.DepthLevel); double pixelStart = TimeToPixel(Math.Max(clipTimeStart, node.Start)); double pixelEnd = TimeToPixel(Math.Min(clipTimeEnd, node.Start + node.Duration)); double screenWidth = pixelEnd - pixelStart; drawingContext.DrawRectangle(brush, borderPen, new Rect(pixelStart, posY, screenWidth, NodeHeight)); //Render text if (screenWidth >= textRenderMinWidth) { var UIText = new FormattedText(node.Label, CultureInfo.InvariantCulture, FlowDirection.LeftToRight, Font, 12, Common.Colors.GetCategoryForeground(), VisualTreeHelper.GetDpi(this).PixelsPerDip); UIText.MaxTextWidth = Math.Min(screenWidth, UIText.Width); UIText.MaxTextHeight = NodeHeight; double textPosX = (pixelEnd + pixelStart - UIText.Width) * 0.5; double textPosY = posY + (NodeHeight - UIText.Height) * 0.5; drawingContext.DrawText(UIText, new Point(textPosX, textPosY)); } }
private TimelineNode GetNodeAtPosition(TimelineNode node, double time, uint depth) { if (time >= node.Start && time <= (node.Start + node.Duration)) { if (depth == node.DepthLevel) { return(node); } else { foreach (TimelineNode child in node.Children) { TimelineNode found = GetNodeAtPosition(child, time, depth); if (found != null) { return(found); } } } } return(null); }
public void FocusNode(CompileValue value) { FocusPending = FindNodeByValue(value); FocusNode(FocusPending); }
public void AddChild(TimelineNode childNode) { Children.Add(childNode); childNode.Parent = this; }