RenderHelper(ArrayList strings, ArrayList nodes, int indentation, int maxWidth, PSHostRawUserInterface rawUI) { Dbg.Assert(strings != null, "strings should not be null"); Dbg.Assert(nodes != null, "nodes should not be null"); if (nodes == null) { return; } foreach (ProgressNode node in nodes) { int lines = strings.Count; node.Render(strings, indentation, maxWidth, rawUI); if (node.Children != null) { // indent only if the rendering of node actually added lines to the strings. int indentationIncrement = (strings.Count > lines) ? 2 : 0; RenderHelper(strings, node.Children, indentation + indentationIncrement, maxWidth, rawUI); } } }
internal HeightTallyer(PSHostRawUserInterface rawUi, int maxHeight, int maxWidth) { _rawUi = rawUi; _maxHeight = maxHeight; _maxWidth = maxWidth; }
/// <summary> /// Renders a node in the "Minimal" style. /// </summary> /// <param name="strCollection"> /// List of strings to which the node's rendering will be appended. /// </param> /// <param name="indentation"> /// The indentation level (in BufferCells) at which the node should be rendered. /// </param> /// <param name="maxWidth"> /// The maximum number of BufferCells that the rendering is allowed to consume. /// </param> /// <param name="rawUI"> /// The PSHostRawUserInterface used to gauge string widths in the rendering. /// </param> private void RenderMinimal(List <string> strCollection, int indentation, int maxWidth, PSHostRawUserInterface rawUI) { string indent = StringUtil.Padding(indentation); // First line: Everything mushed into one line string percent = string.Empty; if (PercentComplete >= 0) { percent = StringUtil.Format("{0}% ", PercentComplete); } string secRemain = string.Empty; if (SecondsRemaining >= 0) { TimeSpan span = new TimeSpan(0, 0, SecondsRemaining); secRemain = span.ToString() + " "; } strCollection.Add( StringUtil.TruncateToBufferCellWidth( rawUI, StringUtil.Format( " {0}{1} {2}{3}{4} ", indent, Activity, percent, secRemain, StatusDescription), maxWidth)); }
InternalHostRawUserInterface(PSHostRawUserInterface externalRawUI, InternalHost parentHost) { // externalRawUI may be null _externalRawUI = externalRawUI; _parentHost = parentHost; }
private static void RenderFullDescription(string description, string indent, int maxWidth, PSHostRawUserInterface rawUi, List <string> strCollection, bool isFullPlus) { string oldDescription = StringUtil.Format(" {0}{1} ", indent, description); string newDescription; do { newDescription = StringUtil.TruncateToBufferCellWidth(rawUi, oldDescription, maxWidth); strCollection.Add(newDescription); if (oldDescription.Length == newDescription.Length) { break; } else { oldDescription = StringUtil.Format(" {0}{1}", indent, oldDescription.Substring(newDescription.Length)); } } while (isFullPlus); }
/// <summary> /// Renders a node in the "Compact" style. /// </summary> /// <param name="strCollection"> /// List of strings to which the node's rendering will be appended. /// </param> /// <param name="indentation"> /// The indentation level (in BufferCells) at which the node should be rendered. /// </param> /// <param name="maxWidth"> /// The maximum number of BufferCells that the rendering is allowed to consume. /// </param> /// <param name="rawUI"> /// The PSHostRawUserInterface used to gauge string widths in the rendering. /// </param> private void RenderCompact(List <string> strCollection, int indentation, int maxWidth, PSHostRawUserInterface rawUI) { string indent = StringUtil.Padding(indentation); // First line: the activity strCollection.Add( StringUtil.TruncateToBufferCellWidth( rawUI, StringUtil.Format(" {0}{1} ", indent, this.Activity), maxWidth)); indentation += 3; indent = StringUtil.Padding(indentation); // Second line: the status description with percentage and time remaining, if applicable. string percent = string.Empty; if (PercentComplete >= 0) { percent = StringUtil.Format("{0}% ", PercentComplete); } string secRemain = string.Empty; if (SecondsRemaining >= 0) { TimeSpan span = new TimeSpan(0, 0, SecondsRemaining); secRemain = span.ToString() + " "; } strCollection.Add( StringUtil.TruncateToBufferCellWidth( rawUI, StringUtil.Format( " {0}{1}{2}{3} ", indent, percent, secRemain, StatusDescription), maxWidth)); // Third line: The current operation if (!string.IsNullOrEmpty(CurrentOperation)) { strCollection.Add( StringUtil.TruncateToBufferCellWidth( rawUI, StringUtil.Format(" {0}{1} ", indent, this.CurrentOperation), maxWidth)); } }
/// <summary> /// Renders a single progress node as strings of text according to that node's style. The text is appended to the /// supplied list of strings. /// </summary> /// <param name="strCollection"> /// List of strings to which the node's rendering will be appended. /// </param> /// <param name="indentation"> /// The indentation level (in BufferCells) at which the node should be rendered. /// </param> /// <param name="maxWidth"> /// The maximum number of BufferCells that the rendering is allowed to consume. /// </param> /// <param name="rawUI"> /// The PSHostRawUserInterface used to gauge string widths in the rendering. /// </param> internal void Render(List <string> strCollection, int indentation, int maxWidth, PSHostRawUserInterface rawUI) { switch (Style) { case RenderStyle.FullPlus: RenderFull(strCollection, indentation, maxWidth, rawUI, isFullPlus: true); break; case RenderStyle.Full: RenderFull(strCollection, indentation, maxWidth, rawUI, isFullPlus: false); break; case RenderStyle.Compact: RenderCompact(strCollection, indentation, maxWidth, rawUI); break; case RenderStyle.Minimal: RenderMinimal(strCollection, indentation, maxWidth, rawUI); break; case RenderStyle.Invisible: // do nothing break; default: Debug.Assert(false, $"Unreachable code - unknown render style '{Style.ToString()}'"); break; } }
/// <summary> /// Renders a node in the "Full" style. /// </summary> /// <param name="strCollection"> /// List of strings to which the node's rendering will be appended. /// </param> /// <param name="indentation"> /// The indentation level (in BufferCells) at which the node should be rendered. /// </param> /// <param name="maxWidth"> /// The maximum number of BufferCells that the rendering is allowed to consume. /// </param> /// <param name="rawUI"> /// The PSHostRawUserInterface used to gauge string widths in the rendering. /// </param> /// <param name="isFullPlus"> /// Indicate if the full StatusDescription and CurrentOperation should be displayed. /// </param> private void RenderFull(List <string> strCollection, int indentation, int maxWidth, PSHostRawUserInterface rawUI, bool isFullPlus) { string indent = StringUtil.Padding(indentation); // First line: the activity strCollection.Add( StringUtil.TruncateToBufferCellWidth( rawUI, StringUtil.Format(" {0}{1} ", indent, this.Activity), maxWidth)); indentation += 3; indent = StringUtil.Padding(indentation); // Second line: the status description RenderFullDescription(this.StatusDescription, indent, maxWidth, rawUI, strCollection, isFullPlus); // Third line: the percentage thermometer. The size of this is proportional to the width we're allowed // to consume. -2 for the whitespace, -2 again for the brackets around thermo, -5 to not be too big if (PercentComplete >= 0) { int thermoWidth = Math.Max(3, maxWidth - indentation - 2 - 2 - 5); int mercuryWidth = 0; mercuryWidth = PercentComplete * thermoWidth / 100; if (PercentComplete < 100 && mercuryWidth == thermoWidth) { // back off a tad unless we're totally complete to prevent the appearance of completion before // the fact. mercuryWidth--; } strCollection.Add( StringUtil.TruncateToBufferCellWidth( rawUI, StringUtil.Format( " {0}[{1}{2}] ", indent, new string('o', mercuryWidth), StringUtil.Padding(thermoWidth - mercuryWidth)), maxWidth)); } // Fourth line: the seconds remaining if (SecondsRemaining >= 0) { TimeSpan span = new TimeSpan(0, 0, this.SecondsRemaining); strCollection.Add( StringUtil.TruncateToBufferCellWidth( rawUI, StringUtil.Format( " {0}{1} remaining. ", indent, span), maxWidth)); } // Fifth and Sixth lines: The current operation if (!string.IsNullOrEmpty(CurrentOperation)) { strCollection.Add(string.Empty); RenderFullDescription(this.CurrentOperation, indent, maxWidth, rawUI, strCollection, isFullPlus); } }
internal DisplayCellsPSHost(PSHostRawUserInterface rawUserInterface) { this._rawUserInterface = rawUserInterface; }
CompressToFit(PSHostRawUserInterface rawUi, int maxHeight, int maxWidth) { Dbg.Assert(_topLevelNodes != null, "Shouldn't need to compress if no data exists"); int nodesCompressed = 0; // This algorithm potentially makes many, many passes over the tree. It might be possible to optimize // that some, but I'm not trying to be too clever just yet. if ( CompressToFitHelper( rawUi, maxHeight, maxWidth, out nodesCompressed, ProgressNode.RenderStyle.FullPlus, ProgressNode.RenderStyle.Full)) { return(0); } if ( CompressToFitHelper( rawUi, maxHeight, maxWidth, out nodesCompressed, ProgressNode.RenderStyle.Full, ProgressNode.RenderStyle.Compact)) { return(0); } if ( CompressToFitHelper( rawUi, maxHeight, maxWidth, out nodesCompressed, ProgressNode.RenderStyle.Compact, ProgressNode.RenderStyle.Minimal)) { return(0); } if ( CompressToFitHelper( rawUi, maxHeight, maxWidth, out nodesCompressed, ProgressNode.RenderStyle.Minimal, ProgressNode.RenderStyle.Invisible)) { // The nodes that we compressed here are now invisible. return(nodesCompressed); } Dbg.Assert(false, "with all nodes invisible, we should never reach this point."); return(0); }
/// <summary> /// Returns null if host is null or if reading RawUI fields fails; otherwise returns a valid object. /// </summary> internal static HostDefaultData Create(PSHostRawUserInterface hostRawUI) { if (hostRawUI == null) { return(null); } HostDefaultData hostDefaultData = new HostDefaultData(); // Try to get values from the host. Catch-all okay because of 3rd party call-out. // Set ForegroundColor. try { hostDefaultData.SetValue(HostDefaultDataId.ForegroundColor, hostRawUI.ForegroundColor); } catch (Exception e) { CommandProcessorBase.CheckForSevereException(e); } // Set BackgroundColor. try { hostDefaultData.SetValue(HostDefaultDataId.BackgroundColor, hostRawUI.BackgroundColor); } catch (Exception e) { CommandProcessorBase.CheckForSevereException(e); } // Set CursorPosition. try { hostDefaultData.SetValue(HostDefaultDataId.CursorPosition, hostRawUI.CursorPosition); } catch (Exception e) { CommandProcessorBase.CheckForSevereException(e); } // Set WindowPosition. try { hostDefaultData.SetValue(HostDefaultDataId.WindowPosition, hostRawUI.WindowPosition); } catch (Exception e) { CommandProcessorBase.CheckForSevereException(e); } // Set CursorSize. try { hostDefaultData.SetValue(HostDefaultDataId.CursorSize, hostRawUI.CursorSize); } catch (Exception e) { CommandProcessorBase.CheckForSevereException(e); } // Set BufferSize. try { hostDefaultData.SetValue(HostDefaultDataId.BufferSize, hostRawUI.BufferSize); } catch (Exception e) { CommandProcessorBase.CheckForSevereException(e); } // Set WindowSize. try { hostDefaultData.SetValue(HostDefaultDataId.WindowSize, hostRawUI.WindowSize); } catch (Exception e) { CommandProcessorBase.CheckForSevereException(e); } // Set MaxWindowSize. try { hostDefaultData.SetValue(HostDefaultDataId.MaxWindowSize, hostRawUI.MaxWindowSize); } catch (Exception e) { CommandProcessorBase.CheckForSevereException(e); } // Set MaxPhysicalWindowSize. try { hostDefaultData.SetValue(HostDefaultDataId.MaxPhysicalWindowSize, hostRawUI.MaxPhysicalWindowSize); } catch (Exception e) { CommandProcessorBase.CheckForSevereException(e); } // Set WindowTitle. try { hostDefaultData.SetValue(HostDefaultDataId.WindowTitle, hostRawUI.WindowTitle); } catch (Exception e) { CommandProcessorBase.CheckForSevereException(e); } return(hostDefaultData); }
/// <summary> /// Helper function for Render(). Recursively renders nodes. /// </summary> /// <param name="strings"> /// The rendered strings so far. Additional rendering will be appended. /// </param> /// <param name="nodes"> /// The nodes to be rendered. All child nodes will also be rendered. /// </param> /// <param name="indentation"> /// The current indentation level (in BufferCells). /// </param> /// <param name="maxWidth"> /// The maximum number of BufferCells that the rendering can consume, horizontally. /// </param> /// <param name="rawUI"> /// The PSHostRawUserInterface used to gauge string widths in the rendering. /// </param> private void RenderHelper(List <string> strings, List <ProgressNode> nodes, int indentation, int maxWidth, PSHostRawUserInterface rawUI) { if (nodes is null) { return; } foreach (ProgressNode node in nodes) { int lines = strings.Count; node.Render(strings, indentation, maxWidth, rawUI); if (node.Children is not null) { // indent only if the rendering of node actually added lines to the strings. int indentationIncrement = (strings.Count > lines) ? 2 : 0; RenderHelper(strings, node.Children, indentation + indentationIncrement, maxWidth, rawUI); } } }
public SnoopPSHostUserInterface(TextBox outputTextBox) { this.outputTextBox = outputTextBox; this.rawUI = new SnoopPSHostRawUserInterface(this.outputTextBox); }
/// <summary> /// Creates a new instance of the TerminalPSHostRawUserInterface /// class with the given IConsoleHost implementation. /// </summary> /// <param name="logger">The ILogger implementation to use for this instance.</param> /// <param name="internalHost">The InternalHost instance from the origin runspace.</param> public TerminalPSHostRawUserInterface(ILogger logger, PSHost internalHost) { this.Logger = logger; this.internalRawUI = internalHost.UI.RawUI; }
public HostUI(IConsole control, UISettings settings, PSHostRawUserInterface rawUi) { _control = control; _settings = settings; _rawUI = rawUi; }