private void InitGridLayout() { var gridOptions = new GridLayoutOptions(); for (var i = 0; i < 7; i++) { gridOptions.Columns.Add(new GridColumnDefinition()); } // row for day labels, always height of 3 gridOptions.Rows.Add(new GridRowDefinition() { Height = 3, Type = GridValueType.Pixels }); // rows for weeks changes depending on the days of the month and the day of week of 1st day var rowCount = NumberOfRowsNeeded; for (var i = 0; i < rowCount; i++) { gridOptions.Rows.Add(new GridRowDefinition() { Height = 1, Type = GridValueType.Pixels }); } // add the grid gridLayout = this.ProtectedPanel.Add(new GridLayout(gridOptions)).CenterBoth(); gridLayout.RefreshLayout(); // Adjust the dimensions of the grid layout whenever the parent size changes. This ensures that // all cells are the same size. If we were to just let the grid layout do its thing then it would // round down the last row /or column in some cases. this.SynchronizeForLifetime(nameof(Bounds), () => { var dayOfWeekHeight = 3; var leftOuterBorderWidth = 2; if (Width < MinWidth || Height < MinHeight) { return; } var cellWidth = (Width - leftOuterBorderWidth) / 7; var rowHeight = (Height - dayOfWeekHeight) / NumberOfRowsNeeded; for (var i = 0; i < gridOptions.Columns.Count; i++) { var col = gridOptions.Columns[i]; col.Width = i == 0 ? cellWidth + leftOuterBorderWidth : cellWidth; col.Type = GridValueType.Pixels; } var rowsAfterDayOfWeekHeaders = gridOptions.Rows.Skip(1); foreach (var row in rowsAfterDayOfWeekHeaders) { row.Height = rowHeight; row.Type = GridValueType.Pixels; } gridLayout.Width = leftOuterBorderWidth + (cellWidth * 7); gridLayout.Height = (rowHeight * NumberOfRowsNeeded) + dayOfWeekHeight; gridLayout.RefreshLayout(); }, gridLayout); }
/// <summary> /// Creates a new grid layout with the given options /// </summary> /// <param name="options">the options</param> public GridLayout(GridLayoutOptions options) { this.Options = options; this.SubscribeForLifetime(nameof(Bounds), HandleSizeChanged, this); ProtectedPanel.Controls.Removed.SubscribeForLifetime(HandleControlRemoved, this); }
public void HardRefresh(ConsoleString outputValue = null) { refreshLt?.Dispose(); refreshLt = new Lifetime(); var myLt = refreshLt; Controls.Clear(); var minHeight = SuperCompact ? 1 : 5; if (Width < 10 || Height < minHeight) { return; } def = CreateDefinition(); var options = new GridLayoutOptions() { Columns = new System.Collections.Generic.List <GridColumnDefinition>() { new GridColumnDefinition() { Type = GridValueType.Pixels, Width = 2 }, // 0 empty new GridColumnDefinition() { Type = GridValueType.RemainderValue, Width = 1 }, // 1 content new GridColumnDefinition() { Type = GridValueType.Pixels, Width = 2 }, // 2 empty }, Rows = new System.Collections.Generic.List <GridRowDefinition>() { new GridRowDefinition() { Type = GridValueType.Pixels, Height = 1, }, // 0 empty new GridRowDefinition() { Type = GridValueType.Pixels, Height = 1, }, // 1 welcome message new GridRowDefinition() { Type = GridValueType.Pixels, Height = 1, }, // 2 press escape message new GridRowDefinition() { Type = GridValueType.Pixels, Height = 1, }, // 3 empty new GridRowDefinition() { Type = GridValueType.Pixels, Height = 1, }, // 4 input new GridRowDefinition() { Type = GridValueType.Pixels, Height = 1, }, // 5 empty new GridRowDefinition() { Type = GridValueType.RemainderValue, Height = 1, }, // 6 output new GridRowDefinition() { Type = GridValueType.Pixels, Height = 1, }, // 7 empty } }; if (SuperCompact) { options.Rows.RemoveAt(0); // empty options.Rows.RemoveAt(0); // welcome options.Rows.RemoveAt(0); // press escape options.Rows.RemoveAt(0); // empty options.Rows.RemoveAt(options.Rows.Count - 1); // empty options.Rows.RemoveAt(options.Rows.Count - 1); // output options.Rows.RemoveAt(options.Rows.Count - 1); // empty } var gridLayout = Add(new GridLayout(options)); gridLayout.Fill(); gridLayout.RefreshLayout(); var top = SuperCompact ? 0 : 1; if (SuperCompact == false) { var welcomePanel = gridLayout.Add(new ConsolePanel(), 1, top++); welcomePanel.Add(new Label() { Text = WelcomeMessage }).CenterHorizontally(); var escapePanel = gridLayout.Add(new ConsolePanel(), 1, top++); escapePanel.Add(new Label() { Text = EscapeMessage }).CenterHorizontally(); top++; } var inputPanel = gridLayout.Add(new ConsolePanel() { }, 1, top++); inputPanel.Add(new Label() { Text = "CMD> ".ToConsoleString() }); InputBox = inputPanel.Add(new TextBox() { X = "CMD> ".Length, Width = inputPanel.Width - "CMD> ".Length, Foreground = ConsoleColor.Gray, Background = ConsoleColor.Black }); InputBox.RichTextEditor.TabHandler.TabCompletionHandlers.Add(new PowerArgsRichCommandLineReader(def, new List <ConsoleString>(), false)); OnInputBoxReady(); top++; ConsoleApp.Current.InvokeNextCycle(() => { if (myLt == refreshLt) { InputBox.Focused.SubscribeForLifetime(() => { if (focusLt != null && focusLt.IsExpired == false && focusLt.IsExpiring == false) { focusLt.Dispose(); } focusLt = new Lifetime(); Application.FocusManager.GlobalKeyHandlers.PushForLifetime(ConsoleKey.Tab, null, () => { var forgotten = OnHandleHey(new ConsoleKeyInfo('\t', ConsoleKey.Tab, false, false, false)); }, focusLt); Application.FocusManager.GlobalKeyHandlers.PushForLifetime(ConsoleKey.Tab, ConsoleModifiers.Shift, () => { var forgotten = OnHandleHey(new ConsoleKeyInfo('\t', ConsoleKey.Tab, true, false, false)); }, focusLt); }, refreshLt); InputBox.Unfocused.SubscribeForLifetime(() => { if (focusLt != null && focusLt.IsExpired == false && focusLt.IsExpiring == false) { focusLt.Dispose(); } }, refreshLt); InputBox.TryFocus(); } }); if (SuperCompact == false) { var outputPanel = gridLayout.Add(new ConsolePanel() { Background = ConsoleColor.Black }, 1, top); outputLabel = outputPanel.Add(new Label() { Text = string.IsNullOrWhiteSpace(outputValue?.StringValue) == false ? outputValue : string.IsNullOrWhiteSpace(outputLabel?.Text?.StringValue) == false ? outputLabel?.Text : CreateAssistiveText(), Mode = LabelRenderMode.MultiLineSmartWrap }).Fill(); } InputBox.KeyInputReceived.SubscribeForLifetime(async(keyInfo) => await OnHandleHey(keyInfo), InputBox); }