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

Gtk/Wpf: Fix autosizing window when only width or height specified #1924

Merged
merged 1 commit into from
Apr 13, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/Eto.Gtk/Eto.Gtk.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ When building for the full framework, .NET Framework 4.6.1 or mono framework 5.1
</PropertyGroup>

<ItemGroup>
<PackageReference Include="GtkSharp" Version="3.22.25.74" />
<PackageReference Include="GtkSharp" Version="3.24.24.34" />
<PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.0" PrivateAssets="all" />
</ItemGroup>
<ItemGroup>
Expand Down
49 changes: 47 additions & 2 deletions src/Eto.Gtk/Forms/DialogHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,59 @@

namespace Eto.GtkSharp.Forms
{
public class EtoDialog : Gtk.Dialog
{
public EtoDialog()
: base("", null, Gtk.DialogFlags.DestroyWithParent)
{
}

public IGtkWindow Handler { get; set; }

#if GTK3
protected override void OnGetPreferredHeightForWidth(int width, out int minimum_height, out int natural_height)
{
base.OnGetPreferredHeightForWidth(width, out minimum_height, out natural_height);
var size = Handler.UserPreferredSize;
if (size.Height > 0)
natural_height = size.Height;
}

protected override void OnGetPreferredWidthForHeight(int height, out int minimum_width, out int natural_width)
{

base.OnGetPreferredWidthForHeight(height, out minimum_width, out natural_width);
var size = Handler.UserPreferredSize;
if (size.Width > 0)
natural_width = size.Width;
}

protected override void OnGetPreferredWidth(out int minimum_width, out int natural_width)
{
base.OnGetPreferredWidth(out minimum_width, out natural_width);
var size = Handler.UserPreferredSize;
if (size.Width > 0)
natural_width = size.Width;
}

protected override void OnGetPreferredHeight(out int minimum_height, out int natural_height)
{
base.OnGetPreferredHeight(out minimum_height, out natural_height);
var size = Handler.UserPreferredSize;
if (size.Height > 0)
natural_height = size.Height;
}
#endif
}

public class DialogHandler : GtkWindow<Gtk.Dialog, Dialog, Dialog.ICallback>, Dialog.IHandler
{
Gtk.Container btcontainer;
Button defaultButton;

public DialogHandler()
{
Control = new Gtk.Dialog("", null, Gtk.DialogFlags.DestroyWithParent);
Control = new EtoDialog { Handler = this };

Resizable = false;
}
Expand Down Expand Up @@ -195,7 +240,7 @@ public override void Close()
}

[GLib.ConnectBefore]
void Control_KeyPressEvent (object o, Gtk.KeyPressEventArgs args)
void Control_KeyPressEvent(object o, Gtk.KeyPressEventArgs args)
{
if (args.Event.Key == Gdk.Key.Escape && AbortButton != null)
{
Expand Down
45 changes: 44 additions & 1 deletion src/Eto.Gtk/Forms/FormHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,49 @@

namespace Eto.GtkSharp.Forms
{
public class EtoWindow : Gtk.Window
{
public IGtkWindow Handler { get; set; }
public EtoWindow(Gtk.WindowType type) : base(type)
{
}

#if GTK3
protected override void OnGetPreferredHeightForWidth(int width, out int minimum_height, out int natural_height)
{
base.OnGetPreferredHeightForWidth(width, out minimum_height, out natural_height);
var size = Handler.UserPreferredSize;
if (size.Height > 0)
natural_height = size.Height;
}

protected override void OnGetPreferredWidthForHeight(int height, out int minimum_width, out int natural_width)
{

base.OnGetPreferredWidthForHeight(height, out minimum_width, out natural_width);
var size = Handler.UserPreferredSize;
if (size.Width > 0)
natural_width = size.Width;
}

protected override void OnGetPreferredWidth(out int minimum_width, out int natural_width)
{
base.OnGetPreferredWidth(out minimum_width, out natural_width);
var size = Handler.UserPreferredSize;
if (size.Width > 0)
natural_width = size.Width;
}

protected override void OnGetPreferredHeight(out int minimum_height, out int natural_height)
{
base.OnGetPreferredHeight(out minimum_height, out natural_height);
var size = Handler.UserPreferredSize;
if (size.Height > 0)
natural_height = size.Height;
}
#endif
}

public class FormHandler : GtkWindow<Gtk.Window, Form, Form.ICallback>, Form.IHandler
{
public FormHandler(Gtk.Window window)
Expand All @@ -12,7 +55,7 @@ public FormHandler(Gtk.Window window)

public FormHandler()
{
Control = new Gtk.Window(Gtk.WindowType.Toplevel);
Control = new EtoWindow(Gtk.WindowType.Toplevel) { Handler = this };
#if GTK2
Control.AllowGrow = true;
#else
Expand Down
3 changes: 3 additions & 0 deletions src/Eto.Gtk/Forms/GtkWindow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ public interface IGtkWindow
bool CloseWindow(Action<CancelEventArgs> closing = null);

Gtk.Window Control { get; }

Size UserPreferredSize { get; }
}

public class GtkShrinkableVBox : Gtk.VBox
Expand Down Expand Up @@ -243,6 +245,7 @@ public override Size Size
}
set
{
UserPreferredSize = value;
var window = Control.GetWindow();
if (window != null)
{
Expand Down
22 changes: 19 additions & 3 deletions src/Eto.Wpf/Forms/WpfWindow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -305,9 +305,25 @@ protected override void SetSize()
if (IsAttached)
return;

var size = UserPreferredSize;
if (!Control.IsLoaded)
{
sw.SizeToContent sizing;
if (double.IsNaN(size.Width) && double.IsNaN(size.Height))
sizing = sw.SizeToContent.Manual;
else if (double.IsNaN(size.Width))
sizing = sw.SizeToContent.Width;
else if (double.IsNaN(size.Height))
sizing = sw.SizeToContent.Height;
else
sizing = sw.SizeToContent.WidthAndHeight;

Control.SizeToContent = sizing;
}

// don't set the minimum size of a window, just the preferred size
ContainerControl.Width = UserPreferredSize.Width;
ContainerControl.Height = UserPreferredSize.Height;
ContainerControl.Width = size.Width;
ContainerControl.Height = size.Height;
SetMinimumSize();
}

Expand Down Expand Up @@ -565,7 +581,7 @@ public override Size Size
if (IsAttached)
throw new NotSupportedException();

Control.SizeToContent = sw.SizeToContent.Manual;

base.Size = value;
if (!Control.IsLoaded)
{
Expand Down
68 changes: 68 additions & 0 deletions test/Eto.Test/UnitTests/Forms/WindowTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,80 @@
using System.Linq;
using System.Collections.Specialized;
using Eto.Drawing;
using System.Threading;

namespace Eto.Test.UnitTests.Forms
{
[TestFixture]
public class WindowTests : TestBase
{


[TestCase(true, true, true, false)]
[TestCase(true, true, false, true)]
[TestCase(true, false, true, false)]
[TestCase(true, false, false, true)]
[TestCase(false, true, true, false)]
[TestCase(false, true, false, true)]
[TestCase(false, false, true, false)]
[TestCase(false, false, false, true)]
public void FormShouldSizeWithLabelCorrectly(bool useForm, bool useSize, bool setWidth, bool setHeight)
{
bool wasClosed = false;
var mre = new ManualResetEvent(false);
Application.Instance.Invoke(() =>
{
var label = new Label();
label.TextColor = Colors.White;
label.Text = Sections.Controls.RichTextAreaSection.LoremText;

Window window = useForm ? (Window)new Form { ShowActivated = false } : new Dialog();
window.BackgroundColor = Colors.Blue;
// window.ShowInTaskbar = false;
// window.WindowStyle = WindowStyle.None;
// window.Resizable = true;
// window.Topmost = true;
window.Content = label;

if (useSize)
{
if (setWidth && setHeight)
window.Size = new Size(150, 150);
else if (setWidth)
window.Size = new Size(150, -1);
else if (setHeight)
window.Size = new Size(-1, 150);
}
else
{
if (setWidth && setHeight)
window.Width = window.Height = 150;
else if (setWidth)
window.Width = 150;
else if (setHeight)
window.Height = 150;
}

window.MouseDown += (sender, e) =>
{
window.Close();
};
window.Closed += (sender, e) =>
{
mre.Set();
wasClosed = true;
};

window.Owner = Application.Instance.MainForm;
if (window is Form f)
f.Show();
else if (window is Dialog d)
d.ShowModal();
});
mre.WaitOne(10000);
Assert.IsTrue(wasClosed, "#1 Form was not closed. You need to click on it to confirm it is sized correctly");
}

[Test]
public void WindowShouldReportInitialSize()
{
Expand Down