Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add View.LayoutComplete event #587

Closed
wants to merge 15 commits into from
2 changes: 1 addition & 1 deletion Example/demo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -627,7 +627,7 @@ static void Main ()
var bottom2 = new Label ("This should go on the bottom of another top-level!");
top.Add (bottom2);

Application.Loaded += (sender, e) => {
top.LayoutComplete += (sender, e) => {
bottom.X = win.X;
bottom.Y = Pos.Bottom (win) - Pos.Top (win) - margin;
bottom2.X = Pos.Left (win);
Expand Down
39 changes: 36 additions & 3 deletions Terminal.Gui/Core/View.cs
Original file line number Diff line number Diff line change
Expand Up @@ -891,7 +891,8 @@ public virtual void Redraw (Rect region)
Application.CurrentView = view;

// Ensure we don't make the Driver's clip rect any bigger
if (Driver.Clip.IsEmpty || Driver.Clip.Contains(RectToScreen (view.Frame))) {
if (SuperView != null && SuperView.Bounds.Contains (RectToScreen (Frame))) {
//if (Driver.Clip.IsEmpty || Driver.Clip.Contains(RectToScreen (view.Frame))) {
var savedClip = view.ClipToBounds ();
view.Redraw (view.Bounds);
Driver.Clip = savedClip;
Expand Down Expand Up @@ -1274,15 +1275,45 @@ List<View> TopologicalSort (HashSet<View> nodes, HashSet<(View From, View To)> e
}

/// <summary>
/// This virtual method is invoked when a view starts executing or
/// when the dimensions of the view have changed, for example in
/// Event arguments for the <see cref="LayoutComplete"/> event.
/// </summary>
public class LayoutEventArgs : EventArgs {
/// <summary>
/// The view-relative bounds of the <see cref="View"/> before it was laid out.
/// </summary>
public Rect OldBounds { get; set; }
}

/// <summary>
/// Fired after the Views's <see cref="LayoutSubviews"/> method has completed.
/// </summary>
/// <remarks>
/// Subscribe to this event to perform tasks when the <see cref="View"/> has been resized or the layout has otherwise changed.
/// </remarks>
public event EventHandler<LayoutEventArgs> LayoutComplete;

/// <summary>
/// Raises the <see cref="LayoutComplete"/> event. Called from <see cref="LayoutSubviews"/> after all sub-views have been laid out.
/// </summary>
internal virtual void OnLayoutComplete (LayoutEventArgs args)
{
LayoutComplete?.Invoke (this, args);
}

/// <summary>
/// Invoked when a view starts executing or when the dimensions of the view have changed, for example in
/// response to the container view or terminal resizing.
/// </summary>
/// <remarks>
/// Calls <see cref="OnLayoutComplete"/> (which raises the <see cref="LayoutComplete"/> event) before it returns.
/// </remarks>
public virtual void LayoutSubviews ()
{
if (!layoutNeeded)
return;

Rect oldBounds = Bounds;

// Sort out the dependencies of the X, Y, Width, Height properties
var nodes = new HashSet<View> ();
var edges = new HashSet<(View, View)> ();
Expand Down Expand Up @@ -1319,6 +1350,8 @@ public virtual void LayoutSubviews ()
}

layoutNeeded = false;

OnLayoutComplete (new LayoutEventArgs () { OldBounds = oldBounds });
}

/// <inheritdoc cref="ToString"/>
Expand Down
2 changes: 1 addition & 1 deletion Terminal.Gui/Core/Window.cs
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ public override void Redraw (Rect bounds)
{
//var padding = 0;
Application.CurrentView = this;
var scrRect = RectToScreen (new Rect(0, 0, Frame.Width, Frame.Height));
var scrRect = RectToScreen (new Rect (0, 0, Frame.Width, Frame.Height));

// BUGBUG: Why do we draw the frame twice? This call is here to clear the content area, I think. Why not just clear that area?
if (NeedDisplay != null && !NeedDisplay.IsEmpty) {
Expand Down
2 changes: 1 addition & 1 deletion Terminal.Gui/Views/ComboBox.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public ComboBox(int x, int y, int w, int h, IList<string> source)
SetValue (searchset [listview.SelectedItem]);
};

Application.Loaded += (object sender, Application.ResizedEventArgs e) => {
LayoutComplete += (sender, a) => {
// Determine if this view is hosted inside a dialog
for (View view = this.SuperView; view != null; view = view.SuperView) {
if (view is Dialog) {
Expand Down
8 changes: 6 additions & 2 deletions Terminal.Gui/Views/ScrollView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -404,11 +404,15 @@ public override void Redraw(Rect region)
Driver.SetAttribute (ColorScheme.Normal);
Clear ();

if (Driver.Clip.IsEmpty || Driver.Clip.Contains (RectToScreen (Frame))) {
var savedClip = ClipToBounds ();
contentView.Redraw (contentView.Bounds);
contentView.Redraw (contentView.Frame);
Driver.Clip = savedClip;
} else {
contentView.Redraw (contentView.Bounds);
}
vertical.Redraw (vertical.Bounds);
horizontal.Redraw (vertical.Bounds);
Driver.Clip = savedClip;
Driver.SetAttribute (ColorScheme.Normal);
}

Expand Down
4 changes: 2 additions & 2 deletions Terminal.Gui/Views/StatusBar.cs
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ public StatusBar (StatusItem [] items) : base ()
Width = Dim.Fill ();
Height = 1;

Application.Loaded += (sender, e) => {
LayoutComplete += (sender, e) => {
X = 0;
Height = 1;
#if SNAP_TO_TOP
Expand All @@ -132,7 +132,7 @@ public StatusBar (StatusItem [] items) : base ()
case StatusBarStyle.SnapToBottom:
#endif
if (Parent == null) {
Y = e.Rows - 1;
Y = Driver.Rows - 1;
} else {
Y = Pos.Bottom (Parent);
}
Expand Down
8 changes: 4 additions & 4 deletions Terminal.Gui/Windows/Dialog.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ public Dialog (ustring title, int width, int height, params Button [] buttons) :
Add (b);
}
}

LayoutComplete += (sender, a) => AdjustButtonLayout ();
}

/// <summary>
Expand All @@ -60,11 +62,9 @@ public void AddButton (Button button)
Add (button);
}

///<inheritdoc cref="LayoutSubviews"/>
public override void LayoutSubviews ()
// TODO: Dialog should use Computed Layout to layout buttons #570
public void AdjustButtonLayout ()
{
base.LayoutSubviews ();

int buttonSpace = 0;
int maxHeight = 0;

Expand Down
2 changes: 1 addition & 1 deletion UICatalog/Scenarios/ComputedLayout.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public override void Setup ()
ColorScheme = Colors.Error
};

Application.Resized += (sender, a) => {
Win.LayoutComplete += (sender, a) => {
horizontalRuler.Text = rule.Repeat ((int)Math.Ceiling ((double)(horizontalRuler.Bounds.Width) / (double)rule.Length)) [0..(horizontalRuler.Bounds.Width)];
verticalRuler.Text = vrule.Repeat ((int)Math.Ceiling ((double)(verticalRuler.Bounds.Height*2) / (double)rule.Length)) [0..(verticalRuler.Bounds.Height*2)];
};
Expand Down
9 changes: 7 additions & 2 deletions UICatalog/Scenarios/Scrolling.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ namespace UICatalog {
class Scrolling : Scenario {
public override void Setup ()
{
Win.X = 1;
Win.Y = 2;
Win.Width = Dim.Fill () - 4;
Win.Height = Dim.Fill () - 2;
var label = new Label ("ScrollView (new Rect (2, 2, 50, 20)) with a 200, 100 ContentSize...") {
X = 0, Y = 0,
ColorScheme = Colors.Dialog
Expand Down Expand Up @@ -42,8 +46,9 @@ public override void Setup ()
};
scrollView.Add (verticalRuler);

Application.Resized += (sender, a) => {
horizontalRuler.Text = rule.Repeat ((int)Math.Ceiling ((double)(horizontalRuler.Bounds.Width) / (double)rule.Length)) [0..(horizontalRuler.Bounds.Width)];
Win.LayoutComplete += (sender, a) => {
horizontalRuler.Text = rule.Repeat ((int)Math.Ceiling ((double)(horizontalRuler.Bounds.Width) / (double)rule.Length)) [0..(horizontalRuler.Bounds.Width)] +
"\n" + "| ".Repeat ((int)Math.Ceiling ((double)(horizontalRuler.Bounds.Width) / (double)rule.Length)) [0..(horizontalRuler.Bounds.Width)];
verticalRuler.Text = vrule.Repeat ((int)Math.Ceiling ((double)(verticalRuler.Bounds.Height * 2) / (double)rule.Length)) [0..(verticalRuler.Bounds.Height * 2)];
};

Expand Down