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

Layout Rewrite #556

Draft
wants to merge 4 commits into
base: develop
Choose a base branch
from
Draft
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
3 changes: 3 additions & 0 deletions Source/Eto.Gtk/Eto.Gtk2 - net45.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,9 @@
<Compile Include="..\Shared\BaseBitmapData.cs">
<Link>Drawing\BaseBitmapData.cs</Link>
</Compile>
<Compile Include="Forms\CustomLayoutHandler.cs">
<SubType>Code</SubType>
</Compile>
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSHARP.Targets" />
<PropertyGroup>
Expand Down
1 change: 1 addition & 0 deletions Source/Eto.Gtk/Eto.Gtk3 - net45.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,7 @@
<Compile Include="..\Shared\BaseBitmapData.cs">
<Link>Drawing\BaseBitmapData.cs</Link>
</Compile>
<Compile Include="Forms\CustomLayoutHandler.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSHARP.Targets" />
<PropertyGroup>
Expand Down
73 changes: 54 additions & 19 deletions Source/Eto.Gtk/Forms/Controls/LabelHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@
using Eto.Forms;
using Eto.Drawing;
using Eto.GtkSharp.Drawing;
using System.Threading;

namespace Eto.GtkSharp.Forms.Controls
{
public class LabelHandler : GtkControl<LabelHandler.EtoLabel, Label, Label.ICallback>, Label.IHandler
{
readonly Gtk.EventBox eventBox;
TextAlignment horizontalAlign = TextAlignment.Left;
VerticalAlignment verticalAlign = VerticalAlignment.Top;
static readonly object TextAlignment_Key = new object();
static readonly object VerticalAlignment_Key = new object();

public override Gtk.Widget ContainerControl
{
Expand All @@ -23,7 +24,7 @@ public override Gtk.Widget EventControl

public class EtoLabel : Gtk.Label
{
int wrapWidth;
int? wrapWidth;

public void ResetWidth()
{
Expand All @@ -32,33 +33,43 @@ public void ResetWidth()
}

#if GTK2

protected override void OnSizeRequested(ref Gtk.Requisition requisition)
{
//base.OnSizeRequested (ref requisition);
int width, height;
Layout.GetPixelSize(out width, out height);
requisition.Width = width;
requisition.Height = height;
}
#else
protected override void OnGetPreferredWidth (out int minimum_width, out int natural_width)
protected override void OnGetPreferredHeightForWidth(int width, out int minimum_height, out int natural_height)
{
base.OnGetPreferredWidth (out minimum_width, out natural_width);
//minimum_width = natural_width; // = 500; //this.Layout.Width;
var oldWidth = Layout.Width;
int pixelWidth, pixelHeight;
Layout.GetPixelSize(out pixelWidth, out pixelHeight);
natural_height = pixelHeight;
minimum_height = pixelHeight;

Layout.Width = oldWidth;
}

protected override void OnAdjustSizeRequest (Gtk.Orientation orientation, out int minimum_size, out int natural_size)
protected override void OnGetPreferredWidth(out int minimum_width, out int natural_width)
{
base.OnAdjustSizeRequest (orientation, out minimum_size, out natural_size);
if (orientation == Gtk.Orientation.Horizontal)
minimum_size = natural_size;
var width = Layout.Width;
Layout.Width = int.MaxValue;
int pixelWidth, pixelHeight;
Layout.GetPixelSize(out pixelWidth, out pixelHeight);
minimum_width = 0;
natural_width = pixelWidth;
Layout.Width = width;
}
#endif

protected override void OnSizeAllocated(Gdk.Rectangle allocation)
{
base.OnSizeAllocated(allocation);
SetWrapWidth(allocation.Width);
if (Wrap || wrapWidth == null)
SetWrapWidth(allocation.Width);
}

void SetWrapWidth(int width)
Expand Down Expand Up @@ -107,13 +118,16 @@ public WrapMode Wrap
Control.SingleLineMode = true;
break;
case WrapMode.Word:
// set to false then true to ensure size is recalculated at runtime
Control.Wrap = false;
Control.Wrap = true;
Control.Layout.Wrap = Pango.WrapMode.WordChar;
Control.LineWrapMode = Pango.WrapMode.WordChar;
Control.LineWrap = true;
Control.SingleLineMode = false;
break;
case WrapMode.Character:
Control.Wrap = false;
Control.Wrap = true;
Control.Layout.Wrap = Pango.WrapMode.Char;
Control.LineWrapMode = Pango.WrapMode.Char;
Expand Down Expand Up @@ -156,10 +170,10 @@ public override string Text

public TextAlignment TextAlignment
{
get { return horizontalAlign; }
get { return Widget.Properties.Get<TextAlignment>(TextAlignment_Key); }
set
{
horizontalAlign = value;
Widget.Properties.Set(TextAlignment_Key, value);
SetAlignment();
}
}
Expand All @@ -168,7 +182,7 @@ void SetAlignment()
{
float xalignment;
float yalignment;
switch (horizontalAlign)
switch (TextAlignment)
{
default:
xalignment = 0F;
Expand All @@ -180,7 +194,7 @@ void SetAlignment()
xalignment = 1F;
break;
}
switch (verticalAlign)
switch (VerticalAlignment)
{
case VerticalAlignment.Center:
yalignment = 0.5F;
Expand All @@ -193,15 +207,15 @@ void SetAlignment()
break;
}
Control.SetAlignment(xalignment, yalignment);
Control.Justify = horizontalAlign.ToGtk();
Control.Justify = TextAlignment.ToGtk();
}

public VerticalAlignment VerticalAlignment
{
get { return verticalAlign; }
get { return Widget.Properties.Get<VerticalAlignment>(VerticalAlignment_Key); }
set
{
verticalAlign = value;
Widget.Properties.Set(VerticalAlignment_Key, value);
SetAlignment();
}
}
Expand All @@ -216,5 +230,26 @@ public override Font Font
Control.Attributes = value != null ? ((FontHandler)value.Handler).Attributes : null;
}
}

public override Size GetPreferredSize(Size availableSize)
{
if (!Control.IsRealized)
Control.Realize();

var oldWidth = Control.Layout.Width;
Control.Layout.Width = Control.Wrap ? (int)Math.Round(availableSize.Width * Pango.Scale.PangoScale) : int.MaxValue;
int width, height;
Control.Layout.GetPixelSize(out width, out height);
Control.Layout.Width = oldWidth;
return new Size(width, height);
}

#if GTK3
public override void SetScale(bool scaled)
{
base.SetScale(scaled);
Control.Scaled = scaled;
}
#endif
}
}
8 changes: 8 additions & 0 deletions Source/Eto.Gtk/Forms/Controls/TabControlHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -86,5 +86,13 @@ public DockPosition TabPosition
get { return Control.TabPos.ToEto(); }
set { Control.TabPos = value.ToGtk(); }
}

public override Size GetPreferredSize(Size availableSize)
{
var size = base.GetPreferredSize(availableSize);
var tabSize = Control.GetNthPage(0).SizeRequest();
size.Height += 50; // TODO: Get actual size somehow
return size;
}
}
}
52 changes: 52 additions & 0 deletions Source/Eto.Gtk/Forms/CustomLayoutHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
using Eto.Forms;
using Eto.Drawing;
using Eto.GtkSharp.Forms.Controls;

namespace Eto.GtkSharp.Forms
{
public class CustomLayoutHandler : GtkContainer<Gtk.Fixed, CustomLayout, CustomLayout.ICallback>, CustomLayout.IHandler
{
public CustomLayoutHandler()
{
Control = new Gtk.Fixed();
}

public void Add(Control child)
{
var ctl = child.GetGtkControlHandler();

var widget = ctl.ContainerControl;
if (widget.Parent != null)
((Gtk.Container)widget.Parent).Remove(widget);
Control.Put(widget, 0, 0);
//ctl.CurrentLocation = Point.Empty;
widget.ShowAll();
}

public void Move(Control child, Rectangle location)
{
var ctl = child.GetGtkControlHandler();
Control.Move(ctl.ContainerControl, location.X, location.Y);
ctl.ContainerControl.SetSizeRequest(location.Width, location.Height);
ctl.CurrentLocation = new Point(location.X, location.Y);
}

public void RemoveAll()
{
foreach (var ctl in Control.Children)
{
Control.Remove(ctl);
}
}

public void Remove(Control child)
{
Control.Remove(child.GetContainerWidget());
}

public void Update()
{
Control.ResizeChildren();
}
}
}
18 changes: 18 additions & 0 deletions Source/Eto.Gtk/Forms/GtkControl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ public interface IGtkControl
Color? SelectedBackgroundColor { get; }

void SetBackgroundColor();

void SetScale(bool scaled);
}

public static class GtkControlExtensions
Expand Down Expand Up @@ -58,6 +60,7 @@ public abstract class GtkControl<TControl, TWidget, TCallback> : WidgetHandler<T
bool mouseDownHandled;
Color? cachedBackgroundColor;
Color? backgroundColor;

public static float ScrollAmount = 2f;

public override IntPtr NativeHandle { get { return Control.Handle; } }
Expand Down Expand Up @@ -659,5 +662,20 @@ public virtual bool ShowBorder
}
}

public virtual Size GetPreferredSize(Size availableSize)
{
var preferredSize = PreferredSize;

var request = Control.SizeRequest().ToEto();
if (preferredSize.Width == -1)
preferredSize.Width = request.Width;
if (preferredSize.Height == -1)
preferredSize.Height = request.Height;
return preferredSize;
}

public virtual void SetScale(bool scaled)
{
}
}
}
6 changes: 4 additions & 2 deletions Source/Eto.Gtk/Forms/GtkPanel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -108,11 +108,13 @@ public Control Content
if (content != null)
alignment.Remove(content.GetContainerWidget());
content = value;
var widget = content.GetContainerWidget();
if (widget != null)
var controlHandler = content.GetGtkControlHandler();
if (controlHandler != null)
{
var widget = controlHandler.ContainerControl;
if (widget.Parent != null)
((Gtk.Container)widget.Parent).Remove(widget);
controlHandler.SetScale(true);
alignment.Child = widget;
widget.ShowAll();
}
Expand Down
23 changes: 15 additions & 8 deletions Source/Eto.Gtk/Forms/GtkWindow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ public abstract class GtkWindow<TControl, TWidget, TCallback> : GtkPanel<TContro
Gtk.AccelGroup accelGroup;
Rectangle? restoreBounds;
Point? currentLocation;
Size? initialSize;
Size initialSize = new Size(-1, -1);
WindowState state;
WindowStyle style;
bool topmost;
Expand Down Expand Up @@ -185,20 +185,23 @@ public override Size Size
get
{
var window = Control.GetWindow();
return window != null ? window.FrameExtents.Size.ToEto() : initialSize ?? Control.DefaultSize.ToEto();
return Widget.Loaded && window != null ? window.FrameExtents.Size.ToEto() : initialSize;
}
set
{
var window = Control.GetWindow();
if (window != null)
if (Widget.Loaded && window != null)
{
var diff = window.FrameExtents.Size.ToEto() - Control.Allocation.Size.ToEto();
Control.Resize(value.Width - diff.Width, value.Height - diff.Height);
}
else
{
Control.Resize(value.Width, value.Height);
initialSize = value;
if (initialSize.Width > 0)
Control.WidthRequest = initialSize.Width;
if (initialSize.Height > 0)
Control.HeightRequest = initialSize.Height;
}
}
}
Expand All @@ -208,17 +211,21 @@ void HandleControlRealized(object sender, EventArgs e)
var allocation = Control.Allocation.Size;
var minSize = MinimumSize;

if (initialSize != null)
if (initialSize.Width > 0 || initialSize.Height > 0)
{
var gdkWindow = Control.GetWindow();
var frameExtents = gdkWindow.FrameExtents.Size.ToEto();
// HACK: get twice to get 'real' size? Ubuntu 14.04 returns inflated size the first call.
frameExtents = gdkWindow.FrameExtents.Size.ToEto();

var diff = frameExtents - Control.Allocation.Size.ToEto();
allocation.Width = initialSize.Value.Width - diff.Width;
allocation.Height = initialSize.Value.Height - diff.Height;
initialSize = null;
if (initialSize.Width < 0)
initialSize.Width = allocation.Width + diff.Width;
if (initialSize.Height < 0)
initialSize.Height = allocation.Height + diff.Height;
allocation.Width = initialSize.Width - diff.Width;
allocation.Height = initialSize.Height - diff.Height;
initialSize = Size.Empty;
}

if (Resizable)
Expand Down
4 changes: 3 additions & 1 deletion Source/Eto.Gtk/Forms/TableLayoutHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -157,9 +157,11 @@ bool Attach(Control child, int x, int y)
}

controls[y, x] = child;
var widget = child.GetContainerWidget();
var childHandler = child.GetGtkControlHandler();
var widget = childHandler.ContainerControl;
if (widget.Parent != null)
((Gtk.Container)widget.Parent).Remove(widget);
childHandler.SetScale(columnScale[x] || x == lastColumnScale);
Control.Attach(widget, (uint)x, (uint)x + 1, (uint)y, (uint)y + 1, GetColumnOptions(x), GetRowOptions(y), 0, 0);
widget.ShowAll();
return true;
Expand Down
1 change: 1 addition & 0 deletions Source/Eto.Gtk/Platform.cs
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ public static void AddTo(Eto.Platform p)
p.Add<Screen.IScreensHandler>(() => new ScreensHandler());
p.Add<Keyboard.IHandler>(() => new KeyboardHandler());
p.Add<FixedMaskedTextProvider.IHandler>(() => new FixedMaskedTextProviderHandler());
p.Add<CustomLayout.IHandler>(() => new CustomLayoutHandler());

// IO
p.Add<SystemIcons.IHandler>(() => new SystemIconsHandler());
Expand Down
Loading