Skip to content

Commit

Permalink
Merge branch 'v2_develop' into v2_3702_dim-auto-layout-fix
Browse files Browse the repository at this point in the history
  • Loading branch information
tig committed Aug 31, 2024
2 parents 6507b10 + 2f6ea90 commit 2734067
Show file tree
Hide file tree
Showing 9 changed files with 320 additions and 71 deletions.
62 changes: 32 additions & 30 deletions Terminal.Gui/View/View.Navigation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public partial class View // Focus and cross-view navigation management (TabStop
/// </summary>
/// <remarks>
/// <para>
/// If there is no next/previous view, the focus is set to the view itself.
/// If there is no next/previous view to advance to, the focus is set to the view itself.
/// </para>
/// </remarks>
/// <param name="direction"></param>
Expand All @@ -37,17 +37,19 @@ public bool AdvanceFocus (NavigationDirection direction, TabBehavior? behavior)
return true;
}

// AdvanceFocus did not advance
View [] index = GetSubviewFocusChain (direction, behavior);
// AdvanceFocus did not advance - do we wrap, or move up to the superview?

if (index.Length == 0)
View [] focusChain = GetSubviewFocusChain (direction, behavior);

if (focusChain.Length == 0)
{
return false;
}

// Special case TabGroup
if (behavior == TabBehavior.TabGroup)
{
if (direction == NavigationDirection.Forward && focused == index [^1] && SuperView is null)
if (direction == NavigationDirection.Forward && focused == focusChain [^1] && SuperView is null)
{
// We're at the top of the focus chain. Go back down the focus chain and focus the first TabGroup
View [] views = GetSubviewFocusChain (NavigationDirection.Forward, TabBehavior.TabGroup);
Expand All @@ -66,7 +68,7 @@ public bool AdvanceFocus (NavigationDirection direction, TabBehavior? behavior)
}
}

if (direction == NavigationDirection.Backward && focused == index [0])
if (direction == NavigationDirection.Backward && focused == focusChain [0])
{
// We're at the bottom of the focus chain
View [] views = GetSubviewFocusChain (NavigationDirection.Forward, TabBehavior.TabGroup);
Expand All @@ -86,38 +88,38 @@ public bool AdvanceFocus (NavigationDirection direction, TabBehavior? behavior)
}
}

int focusedIndex = index.IndexOf (Focused); // Will return -1 if Focused can't be found or is null
int next = 0;
int focusedIndex = focusChain.IndexOf (Focused); // Will return -1 if Focused can't be found or is null
var next = 0; // Assume we wrap to start of the focus chain

if (focusedIndex < index.Length - 1)
if (focusedIndex < focusChain.Length - 1)
{
// We're moving w/in the subviews
next = focusedIndex + 1;
}
else
{
// We're moving beyond the last subview

// Determine if focus should remain in this focus chain, or move to the superview's focus chain

// If we are TabStop and our SuperView has at least one other TabStop subview, move to the SuperView's chain
if (TabStop == TabBehavior.TabStop && SuperView is { } && SuperView.GetSubviewFocusChain (direction, behavior).Length > 1)
{
return false;
}

// TabGroup is special-cased.
if (focused?.TabStop == TabBehavior.TabGroup)
if (SuperView is { })
{
if (SuperView?.GetSubviewFocusChain (direction, TabBehavior.TabGroup)?.Length > 0)
// If we are TabStop, and we have at least one other focusable peer, move to the SuperView's chain
if (TabStop == TabBehavior.TabStop && SuperView is { } && SuperView.GetSubviewFocusChain (direction, behavior).Length > 1)
{
// Our superview has a TabGroup subview; signal we couldn't move so we nav out to it
return false;
}

// TabGroup is special-cased.
if (focused?.TabStop == TabBehavior.TabGroup)
{
if (SuperView?.GetSubviewFocusChain (direction, TabBehavior.TabGroup)?.Length > 0)
{
// Our superview has a TabGroup subview; signal we couldn't move so we nav out to it
return false;
}
}
}
}

View view = index [next];
View view = focusChain [next];

if (view.HasFocus)
{
Expand Down Expand Up @@ -259,7 +261,7 @@ internal bool RestoreFocus ()
{
if (Focused is null && _subviews?.Count > 0)
{
if (_previouslyMostFocused is { } /* && (behavior is null || _previouslyMostFocused.TabStop == behavior)*/)
if (_previouslyMostFocused is { })
{
return _previouslyMostFocused.SetFocus ();
}
Expand Down Expand Up @@ -355,6 +357,11 @@ public bool SetFocus ()
return focusSet;
}

/// <summary>
/// Caches the most focused subview when this view is losing focus. This is used by <see cref="RestoreFocus"/>.
/// </summary>
private View? _previouslyMostFocused;

/// <summary>
/// INTERNAL: Called when focus is going to change to this view. This method is called by <see cref="SetFocus"/> and
/// other methods that
Expand Down Expand Up @@ -625,7 +632,7 @@ private void SetHasFocusFalse (View? newFocusedView, bool traversingDown = false

if (SuperView is { })
{
SuperView._previouslyMostFocused = focusedPeer;
//SuperView._previouslyMostFocused = focusedPeer;
}

// Post-conditions - prove correctness
Expand All @@ -637,11 +644,6 @@ private void SetHasFocusFalse (View? newFocusedView, bool traversingDown = false
SetNeedsDisplay ();
}

/// <summary>
/// Caches the most focused subview when this view is losing focus. This is used by <see cref="RestoreFocus"/>.
/// </summary>
private View? _previouslyMostFocused;

private void NotifyFocusChanged (bool newHasFocus, View? previousFocusedView, View? focusedVew)
{
// Call the virtual method
Expand Down
29 changes: 24 additions & 5 deletions Terminal.Gui/Views/ColorPicker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ public void ApplyStyleChanges ()
Width = textFieldWidth
};
tfValue.HasFocusChanged += UpdateSingleBarValueFromTextField;
tfValue.Accept += (s, _)=>UpdateSingleBarValueFromTextField(s);
_textFields.Add (bar, tfValue);
}

Expand Down Expand Up @@ -153,6 +154,7 @@ private void CreateNameField ()
_tfName.Autocomplete = auto;

_tfName.HasFocusChanged += UpdateValueFromName;

Check warning on line 156 in Terminal.Gui/Views/ColorPicker.cs

View workflow job for this annotation

GitHub Actions / build_release

Nullability of reference types in type of parameter 'sender' of 'void ColorPicker.UpdateValueFromName(object sender, HasFocusEventArgs e)' doesn't match the target delegate 'EventHandler<HasFocusEventArgs>' (possibly because of nullability attributes).

Check warning on line 156 in Terminal.Gui/Views/ColorPicker.cs

View workflow job for this annotation

GitHub Actions / build_release

Nullability of reference types in type of parameter 'sender' of 'void ColorPicker.UpdateValueFromName(object sender, HasFocusEventArgs e)' doesn't match the target delegate 'EventHandler<HasFocusEventArgs>' (possibly because of nullability attributes).

Check warning on line 156 in Terminal.Gui/Views/ColorPicker.cs

View workflow job for this annotation

GitHub Actions / build_and_test_debug (ubuntu-latest)

Nullability of reference types in type of parameter 'sender' of 'void ColorPicker.UpdateValueFromName(object sender, HasFocusEventArgs e)' doesn't match the target delegate 'EventHandler<HasFocusEventArgs>' (possibly because of nullability attributes).

Check warning on line 156 in Terminal.Gui/Views/ColorPicker.cs

View workflow job for this annotation

GitHub Actions / build_and_test_debug (ubuntu-latest)

Nullability of reference types in type of parameter 'sender' of 'void ColorPicker.UpdateValueFromName(object sender, HasFocusEventArgs e)' doesn't match the target delegate 'EventHandler<HasFocusEventArgs>' (possibly because of nullability attributes).

Check warning on line 156 in Terminal.Gui/Views/ColorPicker.cs

View workflow job for this annotation

GitHub Actions / build_and_test_debug (windows-latest)

Nullability of reference types in type of parameter 'sender' of 'void ColorPicker.UpdateValueFromName(object sender, HasFocusEventArgs e)' doesn't match the target delegate 'EventHandler<HasFocusEventArgs>' (possibly because of nullability attributes).

Check warning on line 156 in Terminal.Gui/Views/ColorPicker.cs

View workflow job for this annotation

GitHub Actions / build_and_test_debug (windows-latest)

Nullability of reference types in type of parameter 'sender' of 'void ColorPicker.UpdateValueFromName(object sender, HasFocusEventArgs e)' doesn't match the target delegate 'EventHandler<HasFocusEventArgs>' (possibly because of nullability attributes).

Check warning on line 156 in Terminal.Gui/Views/ColorPicker.cs

View workflow job for this annotation

GitHub Actions / build_and_test_debug (macos-latest)

Nullability of reference types in type of parameter 'sender' of 'void ColorPicker.UpdateValueFromName(object sender, HasFocusEventArgs e)' doesn't match the target delegate 'EventHandler<HasFocusEventArgs>' (possibly because of nullability attributes).

Check warning on line 156 in Terminal.Gui/Views/ColorPicker.cs

View workflow job for this annotation

GitHub Actions / build_and_test_debug (macos-latest)

Nullability of reference types in type of parameter 'sender' of 'void ColorPicker.UpdateValueFromName(object sender, HasFocusEventArgs e)' doesn't match the target delegate 'EventHandler<HasFocusEventArgs>' (possibly because of nullability attributes).
_tfName.Accept += (_s, _) => UpdateValueFromName ();
}

private void CreateTextField ()
Expand Down Expand Up @@ -182,6 +184,7 @@ private void CreateTextField ()
Add (_tfHex);

_tfHex.HasFocusChanged += UpdateValueFromTextField;
_tfHex.Accept += (_,_)=> UpdateValueFromTextField();
}

private void DisposeOldViews ()
Expand All @@ -192,7 +195,6 @@ private void DisposeOldViews ()

if (_textFields.TryGetValue (bar, out TextField? tf))
{
tf.HasFocusChanged -= UpdateSingleBarValueFromTextField;
Remove (tf);
tf.Dispose ();
}
Expand All @@ -214,7 +216,6 @@ private void DisposeOldViews ()
if (_tfHex != null)
{
Remove (_tfHex);
_tfHex.HasFocusChanged -= UpdateValueFromTextField;
_tfHex.Dispose ();
_tfHex = null;
}
Expand All @@ -229,7 +230,6 @@ private void DisposeOldViews ()
if (_tfName != null)
{
Remove (_tfName);
_tfName.HasFocusChanged -= UpdateValueFromName;
_tfName.Dispose ();
_tfName = null;
}
Expand Down Expand Up @@ -279,11 +279,18 @@ private void SyncSubViewValues (bool syncBars)

private void UpdateSingleBarValueFromTextField (object? sender, HasFocusEventArgs e)
{
// if the new value of Focused is true then it is an enter event so ignore
if (e.NewValue)
{
return;
}

// it is a leave event so update
UpdateSingleBarValueFromTextField (sender);
}
private void UpdateSingleBarValueFromTextField (object? sender)
{

foreach (KeyValuePair<IColorBar, TextField> kvp in _textFields)
{
if (kvp.Value == sender)
Expand All @@ -296,13 +303,19 @@ private void UpdateSingleBarValueFromTextField (object? sender, HasFocusEventArg
}
}

private void UpdateValueFromName (object? sender, HasFocusEventArgs e)
private void UpdateValueFromName (object sender, HasFocusEventArgs e)
{
// if the new value of Focused is true then it is an enter event so ignore
if (e.NewValue)
{
return;
}

// it is a leave event so update
UpdateValueFromName();
}
private void UpdateValueFromName ()
{
if (_tfName == null)
{
return;
Expand All @@ -321,11 +334,17 @@ private void UpdateValueFromName (object? sender, HasFocusEventArgs e)

private void UpdateValueFromTextField (object? sender, HasFocusEventArgs e)
{
if (e.NewValue)
// if the new value of Focused is true then it is an enter event so ignore
if (e.NewValue)
{
return;
}

// it is a leave event so update
UpdateValueFromTextField ();
}
private void UpdateValueFromTextField ()
{
if (_tfHex == null)
{
return;
Expand Down
4 changes: 4 additions & 0 deletions Terminal.Gui/Views/DatePicker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,7 @@ private void SetInitialProperties (DateTime date)

_calendar = new TableView
{
Id = "_calendar",
X = 0,
Y = Pos.Bottom (_dateLabel),
Height = 11,
Expand All @@ -206,6 +207,7 @@ private void SetInitialProperties (DateTime date)

_dateField = new DateField (DateTime.Now)
{
Id = "_dateField",
X = Pos.Right (_dateLabel),
Y = 0,
Width = Dim.Width (_calendar) - Dim.Width (_dateLabel),
Expand All @@ -215,6 +217,7 @@ private void SetInitialProperties (DateTime date)

_previousMonthButton = new Button
{
Id = "_previousMonthButton",
X = Pos.Center () - 2,
Y = Pos.Bottom (_calendar) - 1,
Width = 2,
Expand All @@ -234,6 +237,7 @@ private void SetInitialProperties (DateTime date)

_nextMonthButton = new Button
{
Id = "_nextMonthButton",
X = Pos.Right (_previousMonthButton) + 2,
Y = Pos.Bottom (_calendar) - 1,
Width = 2,
Expand Down
13 changes: 5 additions & 8 deletions Terminal.Gui/Views/Wizard/Wizard.cs
Original file line number Diff line number Diff line change
Expand Up @@ -351,14 +351,11 @@ public bool GoToStep (WizardStep newStep)

UpdateButtonsAndTitle ();

// Set focus to the nav buttons
if (BackButton.HasFocus)
{
BackButton.SetFocus ();
}
else

// Set focus on the contentview
if (newStep is { })
{
NextFinishButton.SetFocus ();
newStep.Subviews.ToArray () [0].SetFocus ();
}

if (OnStepChanged (oldStep, _currentStep))
Expand Down Expand Up @@ -543,7 +540,7 @@ private void UpdateButtonsAndTitle ()

SetNeedsLayout ();
LayoutSubviews ();
Draw ();
//Draw ();
}

private void Wizard_Closing (object sender, ToplevelClosingEventArgs obj)
Expand Down
28 changes: 18 additions & 10 deletions Terminal.Gui/Views/Wizard/WizardStep.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
/// the step is active; see also: <see cref="Wizard.StepChanged"/>. To enable or disable a step from being shown to the
/// user, set <see cref="View.Enabled"/>.
/// </remarks>
public class WizardStep : FrameView
public class WizardStep : View
{
///// <summary>
///// The title of the <see cref="WizardStep"/>.
Expand All @@ -36,19 +36,32 @@ public class WizardStep : FrameView
//private string title = string.Empty;

// The contentView works like the ContentView in FrameView.
private readonly View _contentView = new () { Id = "WizardContentView" };
private readonly TextView _helpTextView = new ();
private readonly View _contentView = new ()
{
CanFocus = true,
TabStop = TabBehavior.TabStop,
Id = "WizardStep._contentView"
};
private readonly TextView _helpTextView = new ()
{
CanFocus = true,
TabStop = TabBehavior.TabStop,
ReadOnly = true,
WordWrap = true,
AllowsTab = false,
Id = "WizardStep._helpTextView"
};

/// <summary>
/// Initializes a new instance of the <see cref="Wizard"/> class.
/// </summary>
public WizardStep ()
{
TabStop = TabBehavior.TabStop;
CanFocus = true;
BorderStyle = LineStyle.None;
base.Add (_contentView);

_helpTextView.ReadOnly = true;
_helpTextView.WordWrap = true;
base.Add (_helpTextView);

// BUGBUG: v2 - Disabling scrolling for now
Expand Down Expand Up @@ -144,11 +157,6 @@ public override View Add (View view)
/// <remarks></remarks>
public override View Remove (View view)
{
if (view is null)
{
return view;
}

SetNeedsDisplay ();
View container = view?.SuperView;

Expand Down
Loading

0 comments on commit 2734067

Please sign in to comment.