Skip to content

Commit

Permalink
Merge pull request #2684 from cwensley/curtis/loadcomplete-and-getpre…
Browse files Browse the repository at this point in the history
…ferredsize

Window OnLoadComplete and GetPreferredSize improvements
  • Loading branch information
cwensley authored Sep 23, 2024
2 parents 7f71c1d + d9817fc commit 550d37a
Show file tree
Hide file tree
Showing 22 changed files with 569 additions and 306 deletions.
32 changes: 18 additions & 14 deletions src/Eto.Gtk/Forms/DialogHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ public DialogHandler()
protected override void Initialize()
{
base.Initialize();
Control.Modal = true;
Control.KeyPressEvent += Connector.Control_KeyPressEvent;

var vbox = new EtoBox(Gtk.Orientation.Vertical, 0) { Handler = this };
Expand Down Expand Up @@ -96,14 +97,24 @@ public void ShowModal()
DisableAutoSizeUpdate++;
ReloadButtons();

Control.Modal = true;
Control.Child?.ShowAll();
if (!Control.IsRealized)
{
Control.Realize();
}
Control.QueueResize();
Callback.OnLoadComplete(Widget, EventArgs.Empty);

Control.ShowAll();
DisableAutoSizeUpdate--;

do
if (!WasClosed)
{
Control.Run();
} while (!WasClosed && !CloseWindow());
do
{
Control.Run();
} while (!WasClosed && !CloseWindow());
}

WasClosed = false;
Control.Hide();
Expand Down Expand Up @@ -185,20 +196,13 @@ public void RemoveDialogButton(bool positive, int index, Button item)
}
}

static readonly object WasClosedKey = new object();

bool WasClosed
{
get { return Widget.Properties.Get<bool>(WasClosedKey); }
set { Widget.Properties.Set(WasClosedKey, value); }
}

public override void Close()
{
if (CloseWindow())
if (Widget.Loaded && CloseWindow())
{
WasClosed = true;
Control.Hide();
Control.Unrealize();
WasClosed = true;
}
}

Expand Down
2 changes: 2 additions & 0 deletions src/Eto.Gtk/Forms/FormHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ public async void Show()
{
DisableAutoSizeUpdate++;
Control.Child.ShowAll();
Control.Realize();
Callback.OnLoadComplete(Widget, EventArgs.Empty);
if (ShowActivated || !Control.AcceptFocus)
Control.Show();
else
Expand Down
10 changes: 9 additions & 1 deletion src/Eto.Gtk/Forms/GtkControl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ public interface IGtkControl

void TriggerMouseEnterIfNeeded();
void TriggerMouseLeaveIfNeeded();

Control.ICallback Callback { get; }
}

public static class GtkControlExtensions
Expand Down Expand Up @@ -1150,8 +1152,12 @@ public virtual SizeF GetPreferredSize(SizeF availableSize)
{
if (!ContainerControl.IsRealized)
{
if (ContainerControl is Gtk.Window window)
window.Child.ShowAll();
else
ContainerControl.ShowAll();

ContainerControl.Realize();
ContainerControl.ShowAll();
}
#if GTK3
var requestMode = ContainerControl.RequestMode;
Expand Down Expand Up @@ -1236,6 +1242,8 @@ public bool IsMouseCaptured

Control IGtkControl.Widget => Widget;

Control.ICallback IGtkControl.Callback => Callback;

public void TriggerMouseEnterIfNeeded() => Connector.TriggerMouseEnterIfNeeded();
public void TriggerMouseLeaveIfNeeded() => Connector.TriggerMouseLeaveIfNeeded();

Expand Down
37 changes: 30 additions & 7 deletions src/Eto.Gtk/Forms/GtkWindow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ public interface IGtkWindow
Gtk.Window Control { get; }

Size UserPreferredSize { get; }

Window.ICallback Callback { get; }
}

public class GtkShrinkableVBox : Gtk.Box
Expand Down Expand Up @@ -188,7 +190,7 @@ private void SetMinMax(Size? size)
#endif
Control.SetGeometryHints(Control, geom, Gdk.WindowHints.MinSize);
}


public bool Minimizable
{
Expand All @@ -215,7 +217,7 @@ public bool ShowInTaskbar
get { return !Control.SkipTaskbarHint; }
set { Control.SkipTaskbarHint = !value; }
}

public bool Closeable
{
get => Control.Deletable;
Expand Down Expand Up @@ -262,9 +264,9 @@ public WindowStyle WindowStyle
}
}
}

protected virtual Gdk.WindowTypeHint DefaultTypeHint => Gdk.WindowTypeHint.Normal;

void SetTypeHint()
{
if (WindowStyle == WindowStyle.Default && (Minimizable || Maximizable))
Expand All @@ -284,7 +286,7 @@ public override Size Size
{
DisableAutoSizeUpdate++;
UserPreferredSize = value;

if (Widget.Loaded)
{
var diff = WindowDecorationSize;
Expand Down Expand Up @@ -447,7 +449,10 @@ public void HandleDeleteEvent(object o, Gtk.DeleteEventArgs args)

public void HandleShownEvent(object sender, EventArgs e)
{
Handler?.Callback.OnShown(Handler.Widget, EventArgs.Empty);
var h = Handler;
if (h == null || h.WasClosed)
return;
Application.Instance.AsyncInvoke(() => h.Callback.OnShown(Handler.Widget, EventArgs.Empty));
}

public void HandleWindowStateEvent(object o, Gtk.WindowStateEventArgs args)
Expand Down Expand Up @@ -615,12 +620,22 @@ public bool CloseWindow(Action<CancelEventArgs> closing = null)
return !args.Cancel;
}

static readonly object WasClosedKey = new object();

protected bool WasClosed
{
get { return Widget.Properties.Get<bool>(WasClosedKey); }
set { Widget.Properties.Set(WasClosedKey, value); }
}


public virtual void Close()
{
if (Widget.Loaded && CloseWindow())
{
Control.Hide();
Control.Unrealize();
WasClosed = true;
}
}

Expand Down Expand Up @@ -797,7 +812,7 @@ public void BringToFront()
if (WindowState == WindowState.Minimized)
Control.Present();
}

Control.GetWindow()?.Raise();
}

Expand Down Expand Up @@ -868,13 +883,21 @@ Size WindowDecorationSize
{
get
{
if (!Control.IsRealized)
{
Control.Child?.ShowAll();
Control.Realize();
}

var window = Control.GetWindow();
if (window == null)
return Size.Empty;
return window.FrameExtents.Size.ToEto() - Control.Allocation.Size.ToEto();
}
}

Window.ICallback IGtkWindow.Callback => Callback;

bool isInvalidated;

internal void PerformResize()
Expand Down
4 changes: 4 additions & 0 deletions src/Eto.Mac/Forms/DialogHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,8 @@ bool ShowAttached

public virtual void ShowModal()
{
Control.LayoutIfNeeded();
Callback.OnLoadComplete(Widget, EventArgs.Empty);
MacView.InMouseTrackingLoop = false;
session = null;
EnsureOwner();
Expand All @@ -160,6 +162,8 @@ public virtual void ShowModal()

public virtual Task ShowModalAsync()
{
Control.LayoutIfNeeded();
Callback.OnLoadComplete(Widget, EventArgs.Empty);
MacView.InMouseTrackingLoop = false;
var tcs = new TaskCompletionSource<bool>();
session = null;
Expand Down
2 changes: 2 additions & 0 deletions src/Eto.Mac/Forms/FormHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ protected override void Initialize()

public virtual void Show()
{
Control.LayoutIfNeeded();
Callback.OnLoadComplete(Widget, EventArgs.Empty);
var visible = Control.IsVisible;
if (ShowActivated)
{
Expand Down
10 changes: 9 additions & 1 deletion src/Eto.Mac/Forms/MacView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1343,12 +1343,20 @@ static void FireOnShown(Control control)
// don't use GetMacViewHandler() extension, as that will trigger OnShown for themed controls, which will
// trigger Shown multiple times for the same themed control
var handler = control.Handler as IMacViewHandler;
handler?.Callback.OnShown(control, EventArgs.Empty);
var isWindow = control is Window;

// Parent controls get shown event first, then children
if (!isWindow)
handler?.Callback.OnShown(control, EventArgs.Empty);

foreach (var ctl in control.VisualControls)
{
FireOnShown(ctl);
}

// Window fires shown after all child controls
if (isWindow)
handler?.Callback.OnShown(control, EventArgs.Empty);
}

protected virtual void FireOnShown() => FireOnShown(Widget);
Expand Down
34 changes: 10 additions & 24 deletions src/Eto.Mac/Forms/MacWindow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,9 @@ protected override SizeF GetNaturalSize(SizeF availableSize)
naturalSize.Height = preferredClientSize.Value.Height;
}

return naturalSize;
var frame = Control.FrameRectFor(new RectangleF(naturalSize).ToNS());

return frame.Size.ToEto();
}

public NSMenu MenuBar
Expand Down Expand Up @@ -788,7 +790,7 @@ private void PerformAutoSize()
if (UserPreferredSize.Height != -1)
availableSize.Height = UserPreferredSize.Height - borderSize.Height;
var size = GetPreferredSize(availableSize);
SetContentSize(size.ToNS());
SetSize(size.ToNS());
}
}

Expand Down Expand Up @@ -1170,33 +1172,17 @@ protected virtual void PositionWindow()

#region IMacContainer implementation

void SetContentSize(CGSize contentSize)
void SetSize(CGSize newSize)
{
if (MinimumSize != Size.Empty)
{
contentSize.Width = (nfloat)Math.Max(contentSize.Width, MinimumSize.Width);
contentSize.Height = (nfloat)Math.Max(contentSize.Height, MinimumSize.Height);
newSize.Width = (nfloat)Math.Max(newSize.Width, MinimumSize.Width);
newSize.Height = (nfloat)Math.Max(newSize.Height, MinimumSize.Height);
}

if (Widget.Loaded)
{
var clientSize = ClientSize;
var diffy = clientSize.Height - (int)contentSize.Height;
var diffx = clientSize.Width - (int)contentSize.Width;
var frame = Control.Frame;
if (diffx != 0 || setInitialSize)
{
frame.Width -= diffx;
}
if (diffy != 0 || setInitialSize)
{
frame.Y += diffy;
frame.Height -= diffy;
}
Control.SetFrame(frame, true, AnimateSizeChanges);
}
else
Control.SetContentSize(contentSize);
var frame = Control.Frame;
frame.Size = newSize;
Control.SetFrame(frame, Widget.Loaded, AnimateSizeChanges);
}

#endregion
Expand Down
2 changes: 2 additions & 0 deletions src/Eto.WinForms/Forms/WindowHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,8 @@ void Control_Load(object sender, EventArgs e)
Control.Size = size;
content.MinimumSize = content.MaximumSize = sd.Size.Empty;
ContainerContentControl.MinimumSize = sd.Size.Empty;

Callback.OnLoadComplete(Widget, EventArgs.Empty);
}

public override Size Size
Expand Down
12 changes: 12 additions & 0 deletions src/Eto.Wpf/Forms/DialogHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,18 @@ public void ShowModal()
if (owner != null && !owner.HasFocus)
owner.Focus();

if (Control.IsLoaded)
{
Callback.OnLoadComplete(Widget, EventArgs.Empty);
FireOnLoadComplete = false;
}
else
{
FireOnLoadComplete = true;
}

var _ = NativeHandle; // ensure SourceInitialized is called to get right size based on style flags

Control.ShowDialog();
WpfFrameworkElementHelper.ShouldCaptureMouse = false;

Expand Down
15 changes: 13 additions & 2 deletions src/Eto.Wpf/Forms/FormHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,21 @@ public FormHandler()
public virtual void Show()
{
Control.WindowStartupLocation = sw.WindowStartupLocation.Manual;
if (ApplicationHandler.Instance.IsStarted)
if (Control.IsLoaded)
{
Control.Show();
Callback.OnLoadComplete(Widget, EventArgs.Empty);
FireOnLoadComplete = false;
}
else
{
// We should trigger during the Control.Loaded event
FireOnLoadComplete = true;
}

var _ = NativeHandle; // ensure SourceInitialized is called to get right size based on style flags

if (ApplicationHandler.Instance.IsStarted)
Control.Show();
else
ApplicationHandler.Instance.DelayShownWindows.Add(Control);
WpfFrameworkElementHelper.ShouldCaptureMouse = false;
Expand Down
Loading

0 comments on commit 550d37a

Please sign in to comment.