private void AddNode(ArrayList nodes, ProgressNode nodeToAdd) { nodes.Add(nodeToAdd); PendingProgress pendingProgress = this; pendingProgress.nodeCount = pendingProgress.nodeCount + 1; }
HandleIncomingProgressRecord(Int64 sourceId, ProgressRecord record) { Dbg.Assert(record != null, "record should not be null"); if (_pendingProgress == null) { Dbg.Assert(_progPane == null, "If there is no data struct, there shouldn't be a pane, either."); _pendingProgress = new PendingProgress(); } _pendingProgress.Update(sourceId, record); if (_progPane == null) { // This is the first time we've received a progress record. // Create a progress pane, // then show it, // then create and start timer to update it. _progPane = new ProgressPane(this); if (_progPaneUpdateTimer == null && _progPane != null) { _progPane.Show(_pendingProgress); _progPaneUpdateTimer = new Timer(new TimerCallback(ProgressPaneUpdateTimerElapsed), null, UpdateTimerThreshold, Timeout.Infinite); } } }
HandleIncomingProgressRecord(long sourceId, ProgressRecord record) { Dbg.Assert(record != null, "record should not be null"); if (_pendingProgress == null) { Dbg.Assert(_progPane == null, "If there is no data struct, there shouldn't be a pane, either."); _pendingProgress = new PendingProgress(); } _pendingProgress.Update(sourceId, record); if (_progPane == null) { // This is the first time we've received a progress record // Create a progress pane // Set up a update flag // Create a timer for updating the flag _progPane = new ProgressPane(this); if (_progPaneUpdateTimer == null) { // Show a progress pane at the first time we've received a progress record progPaneUpdateFlag = 1; // The timer will be auto restarted every 'UpdateTimerThreshold' ms _progPaneUpdateTimer = new Timer(new TimerCallback(ProgressPaneUpdateTimerElapsed), null, UpdateTimerThreshold, UpdateTimerThreshold); } } if (Interlocked.CompareExchange(ref progPaneUpdateFlag, 0, 1) == 1 || record.RecordType == ProgressRecordType.Completed) { // Update the progress pane only when the timer set up the update flag or WriteProgress is completed. // As a result, we do not block WriteProgress and whole script and eliminate unnecessary console locks and updates. if (SupportsVirtualTerminal && PSStyle.Instance.Progress.UseOSCIndicator) { int percentComplete = record.PercentComplete; if (percentComplete < 0) { // Write-Progress allows for negative percent complete, but not greater than 100 // but OSC sequence is limited from 0 to 100. percentComplete = 0; } // OSC sequence to turn on progress indicator // https://github.com/microsoft/terminal/issues/6700 Console.Write($"\x1b]9;4;1;{percentComplete}\x1b\\"); } // If VT is not supported, we change ProgressView to classic if (!SupportsVirtualTerminal) { PSStyle.Instance.Progress.View = ProgressView.Classic; } _progPane.Show(_pendingProgress); } }
private void RemoveNodeAndPromoteChildren(ArrayList nodes, int indexToRemove) { ProgressNode item = (ProgressNode)nodes[indexToRemove]; if (item != null) { if (item.Children == null) { this.RemoveNode(nodes, indexToRemove); return; } else { for (int i = 0; i < item.Children.Count; i++) { ((ProgressNode)item.Children[i]).ParentActivityId = -1; } nodes.RemoveAt(indexToRemove); PendingProgress pendingProgress = this; pendingProgress.nodeCount = pendingProgress.nodeCount - 1; nodes.InsertRange(indexToRemove, item.Children); return; } } else { return; } }
private void RemoveNode(ArrayList nodes, int indexToRemove) { nodes.RemoveAt(indexToRemove); PendingProgress pendingProgress = this; pendingProgress.nodeCount = pendingProgress.nodeCount - 1; }
internal void Show(PendingProgress pendingProgress) { bool flag; this.bufSize = this.rawui.BufferSize; int width = this.bufSize.Width; Size windowSize = this.rawui.WindowSize; int num = Math.Max(5, windowSize.Height / 3); string[] strArrays = pendingProgress.Render(width, num, this.rawui); if (strArrays != null) { BufferCell[,] bufferCellArray = this.rawui.NewBufferCellArray(strArrays, this.ui.ProgressForegroundColor, this.ui.ProgressBackgroundColor); if (this.progressRegion != null) { if (bufferCellArray.GetLength(0) != this.progressRegion.GetLength(0) || bufferCellArray.GetLength(1) != this.progressRegion.GetLength(1)) { flag = true; } else { flag = false; } bool flag1 = flag; this.progressRegion = bufferCellArray; if (!flag1) { this.rawui.SetBufferContents(this.location, this.progressRegion); return; } else { if (this.IsShowing) { this.Hide(); } this.Show(); return; } } else { this.progressRegion = bufferCellArray; this.Show(); return; } } else { this.Hide(); this.progressRegion = null; return; } }
HandleIncomingProgressRecord(Int64 sourceId, ProgressRecord record) { Dbg.Assert(record != null, "record should not be null"); if (_pendingProgress == null) { Dbg.Assert(_progPane == null, "If there is no data struct, there shouldn't be a pane, either."); _pendingProgress = new PendingProgress(); } _pendingProgress.Update(sourceId, record); if (_progPane == null) { // This is the first time we've received a progress record // Create a progress pane // Set up a update flag // Create a timer for updating the flag _progPane = new ProgressPane(this); if (_progPaneUpdateTimer == null) { // Show a progress pane at the first time we've received a progress record progPaneUpdateFlag = 1; // The timer will be auto restarted every 'UpdateTimerThreshold' ms _progPaneUpdateTimer = new Timer(new TimerCallback(ProgressPaneUpdateTimerElapsed), null, UpdateTimerThreshold, UpdateTimerThreshold); } } if (Interlocked.CompareExchange(ref progPaneUpdateFlag, 0, 1) == 1 || record.RecordType == ProgressRecordType.Completed) { // Update the progress pane only when the timer set up the update flag or WriteProgress is completed. // As a result, we do not block WriteProgress and whole script and eliminate unnecessary console locks and updates. _progPane.Show(_pendingProgress); // Reset the cursor back to where it started if (record.RecordType == ProgressRecordType.Completed) { _progPane.Hide(); } } }
HandleIncomingProgressRecord(Int64 sourceId, ProgressRecord record) { Dbg.Assert(record != null, "record should not be null"); if (_pendingProgress == null) { Dbg.Assert(_progPane == null, "If there is no data struct, there shouldn't be a pane, either."); _pendingProgress = new PendingProgress(); } _pendingProgress.Update(sourceId, record); if (_progPane == null) { // This is the first time we've received a progress record. Create a progress pane, then show it. _progPane = new ProgressPane(this); } _progPane.Show(_pendingProgress); }
HandleIncomingProgressRecord(Int64 sourceId, ProgressRecord record) { Dbg.Assert(record != null, "record should not be null"); if (_pendingProgress == null) { Dbg.Assert(_progPane == null, "If there is no data struct, there shouldn't be a pane, either."); _pendingProgress = new PendingProgress(); } _pendingProgress.Update(sourceId, record); if (_progPane == null) { // This is the first time we've received a progress record. Create a pane to show it, and // then show it. _progPane = new ProgressPane(this); } _progPane.Show(_pendingProgress); }
Show(PendingProgress pendingProgress) { Dbg.Assert(pendingProgress != null, "pendingProgress may not be null"); _bufSize = _rawui.BufferSize; // In order to keep from slicing any CJK double-cell characters that might be present in the screen buffer, // we use the full width of the buffer. int maxWidth = _bufSize.Width; int maxHeight = Math.Max(5, _rawui.WindowSize.Height / 3); string[] contents = pendingProgress.Render(maxWidth, maxHeight, _rawui); if (contents == null) { // There's nothing to show. Hide(); _progressRegion = null; return; } // NTRAID#Windows OS Bugs-1061752-2004/12/15-sburns should read a skin setting here... BufferCell[,] newRegion = _rawui.NewBufferCellArray(contents, _ui.ProgressForegroundColor, _ui.ProgressBackgroundColor); Dbg.Assert(newRegion != null, "NewBufferCellArray has failed!"); if (_progressRegion == null) { // we've never shown this pane before. _progressRegion = newRegion; Show(); } else { // We have shown the pane before. We have to be smart about when we restore the saved region to minimize // flicker. We need to decide if the new contents will change the dimensions of the progress pane // currently being shown. If it will, then restore the saved region, and show the new one. Otherwise, // just blast the new one on top of the last one shown. // We're only checking size, not content, as we assume that the content will always change upon receipt // of a new ProgressRecord. That's not guaranteed, of course, but it's a good bet. So checking content // would usually result in detection of a change, so why bother? bool sizeChanged = (newRegion.GetLength(0) != _progressRegion.GetLength(0)) || (newRegion.GetLength(1) != _progressRegion.GetLength(1)) ? true : false; _progressRegion = newRegion; if (sizeChanged) { if (IsShowing) { Hide(); } Show(); } else { _rawui.SetBufferContents(_location, _progressRegion); } } }
internal static void VisitNodes(ArrayList nodes, PendingProgress.NodeVisitor v) { if (nodes != null) { int num = 0; while (num < nodes.Count) { ProgressNode item = (ProgressNode)nodes[num]; if (v.Visit(item, nodes, num)) { if (item.Children != null) { PendingProgress.NodeVisitor.VisitNodes(item.Children, v); } num++; } else { return; } } return; } else { return; } }
Show(PendingProgress pendingProgress) { Dbg.Assert(pendingProgress != null, "pendingProgress may not be null"); _bufSize = _rawui.BufferSize; // In order to keep from slicing any CJK double-cell characters that might be present in the screen buffer, // we use the full width of the buffer. int maxWidth = _bufSize.Width; int maxHeight = Math.Max(5, _rawui.WindowSize.Height / 3); _content = pendingProgress.Render(maxWidth, maxHeight, _rawui); if (_content == null) { // There's nothing to show. Hide(); _progressRegion = null; return; } BufferCell[,] newRegion; if (ProgressNode.IsMinimalProgressRenderingEnabled()) { // Legacy progress rendering relies on a BufferCell which defines a character, foreground color, and background color // per cell. This model doesn't work with ANSI escape sequences. However, there is existing logic on rendering that // relies on the existence of the BufferCell to know if something has been rendered previously. Here we are creating // an empty BufferCell, but using the second dimension to capture the number of rows so that we can clear that many // elsewhere in Hide(). newRegion = new BufferCell[0, _content.Length]; } else { newRegion = _rawui.NewBufferCellArray(_content, _ui.ProgressForegroundColor, _ui.ProgressBackgroundColor); } Dbg.Assert(newRegion != null, "NewBufferCellArray has failed!"); if (_progressRegion == null) { // we've never shown this pane before. _progressRegion = newRegion; Show(); } else { // We have shown the pane before. We have to be smart about when we restore the saved region to minimize // flicker. We need to decide if the new contents will change the dimensions of the progress pane // currently being shown. If it will, then restore the saved region, and show the new one. Otherwise, // just blast the new one on top of the last one shown. // We're only checking size, not content, as we assume that the content will always change upon receipt // of a new ProgressRecord. That's not guaranteed, of course, but it's a good bet. So checking content // would usually result in detection of a change, so why bother? bool sizeChanged = (newRegion.GetLength(0) != _progressRegion.GetLength(0)) || (newRegion.GetLength(1) != _progressRegion.GetLength(1)); _progressRegion = newRegion; if (sizeChanged) { if (IsShowing) { Hide(); } Show(); } else { if (ProgressNode.IsMinimalProgressRenderingEnabled()) { WriteContent(); } else { _rawui.SetBufferContents(_location, _progressRegion); } } } }
private void HandleIncomingProgressRecord(long sourceId, ProgressRecord record) { if (this.pendingProgress == null) { this.pendingProgress = new PendingProgress(); } this.pendingProgress.Update(sourceId, record); if (this.progPane == null) { this.progPane = new ProgressPane(this); } this.progPane.Show(this.pendingProgress); }
internal void ResetProgress() { if (this.progPane != null) { this.progPane.Hide(); this.progPane = null; } this.pendingProgress = null; }