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

Screen implementation #1150

Closed
wants to merge 49 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
3e9bbb3
Added Win32 screen implementation
JurjenBiewenga Sep 7, 2017
d76ddc9
Forgot saving these
JurjenBiewenga Sep 7, 2017
4e55faf
Started work on GTK implementation
JurjenBiewenga Sep 8, 2017
87b74d5
Created a working implementation for Gtk3
JurjenBiewenga Sep 8, 2017
72844f4
Added logging for testing
JurjenBiewenga Sep 8, 2017
693b09d
Added gtk implementation
JurjenBiewenga Sep 8, 2017
abe48b4
Added equals, gethashcode, performance improvements
JurjenBiewenga Sep 9, 2017
b565e70
Resolving conflicts
JurjenBiewenga Sep 9, 2017
1af896a
Merge branch 'master' into Screen
JurjenBiewenga Sep 9, 2017
4e146c8
Replaced GetScreen with GetDefaultScreen
JurjenBiewenga Sep 10, 2017
1432b0d
Merge
JurjenBiewenga Sep 10, 2017
01f21c2
ScreenCount is now cached in gtk3
JurjenBiewenga Sep 10, 2017
0d5b7d1
Forgot to commit the name changed interface
JurjenBiewenga Sep 10, 2017
b3c0f53
Renamed GtkScreen to GdkScreen
JurjenBiewenga Sep 10, 2017
3624041
Created UnownedGdkScreen class
JurjenBiewenga Sep 10, 2017
58e0140
Added constructor to gdkscreen
JurjenBiewenga Sep 10, 2017
a9d8b80
Moved Screen data to its own class
JurjenBiewenga Sep 11, 2017
7433858
Screen no longer override Equals
JurjenBiewenga Sep 11, 2017
eb12e9f
Forcing recompile
JurjenBiewenga Sep 11, 2017
b00f027
Created platform specific Screen implementations
JurjenBiewenga Sep 13, 2017
57b1681
Merge
JurjenBiewenga Sep 13, 2017
4249db6
Revert "Merge"
JurjenBiewenga Sep 14, 2017
d458bc5
Added files to project
JurjenBiewenga Sep 14, 2017
e11fdc8
Merge branch 'master' into Screen
JurjenBiewenga Sep 14, 2017
5671f73
Added basic mac implementation
JurjenBiewenga Sep 14, 2017
28778dc
Cached allScreens
JurjenBiewenga Sep 14, 2017
562381e
Added caching to win32 implementation
JurjenBiewenga Sep 14, 2017
a505cd5
Changed formatting of privates
JurjenBiewenga Sep 14, 2017
47c35e5
Changed primary screen on osx to the screen with the menu bar
JurjenBiewenga Sep 14, 2017
2fc4e09
Mac/win32 implementation now use the AllScreens property to find the …
JurjenBiewenga Sep 14, 2017
305db08
Moved callback registration to constructor
JurjenBiewenga Sep 14, 2017
8cf6c86
Fixed helper functions
JurjenBiewenga Sep 14, 2017
7943590
Added Control.Catalog page
JurjenBiewenga Sep 14, 2017
aaa3a83
Moved things around
JurjenBiewenga Sep 14, 2017
188e7c2
Android PopupImpl now has a null Screens variable
JurjenBiewenga Sep 15, 2017
a3697dc
Moved Screens to Window
JurjenBiewenga Sep 15, 2017
2a8ab01
Removed remnant of Screens variable
JurjenBiewenga Sep 15, 2017
5b3862d
Added bounds to screen implementation
JurjenBiewenga Sep 16, 2017
b510d9c
Merge branch 'master' into Screen
JurjenBiewenga Sep 16, 2017
3c231f2
Moved a ScreenFromBounds and Primary to Screens class
JurjenBiewenga Sep 16, 2017
ae957e5
Restored draw dirty rects
JurjenBiewenga Sep 19, 2017
1ce1ec7
Added ScreenFromPoint and ScreenFromVisual
JurjenBiewenga Sep 19, 2017
60629d1
Merge branch 'master' into Screen
JurjenBiewenga Sep 22, 2017
1f52f8b
Fixed indentation
JurjenBiewenga Sep 23, 2017
319c0b8
Screens.Primary is now consistent with the other properties
JurjenBiewenga Sep 23, 2017
f92dc0c
Merge branch 'Screen' of https://github.com/JurjenBiewenga/Avalonia i…
JurjenBiewenga Sep 23, 2017
6fb5823
Merge
JurjenBiewenga Sep 23, 2017
03e633d
Merge branch 'master' into Screen
JurjenBiewenga Sep 23, 2017
a6007b6
Screens is now properly cached
JurjenBiewenga Sep 23, 2017
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
8 changes: 7 additions & 1 deletion samples/ControlCatalog/ControlCatalog.csproj
Expand Up @@ -75,6 +75,9 @@
<EmbeddedResource Include="Pages\SliderPage.xaml">
<SubType>Designer</SubType>
</EmbeddedResource>
<EmbeddedResource Include="Pages\ScreenPage.xaml">
<SubType>Designer</SubType>
</EmbeddedResource>
<EmbeddedResource Include="Pages\TextBoxPage.xaml">
<SubType>Designer</SubType>
</EmbeddedResource>
Expand Down Expand Up @@ -136,7 +139,10 @@
</Compile>
<Compile Include="Pages\SliderPage.xaml.cs">
<DependentUpon>SliderPage.xaml</DependentUpon>
</Compile>
</Compile>
<Compile Include="Pages\ScreenPage.xaml.cs">
<DependentUpon>ScreenPage.xaml</DependentUpon>
</Compile>
<Compile Include="Pages\TreeViewPage.xaml.cs">
<DependentUpon>TreeViewPage.xaml</DependentUpon>
</Compile>
Expand Down
19 changes: 14 additions & 5 deletions samples/ControlCatalog/MainView.xaml.cs
Expand Up @@ -13,11 +13,20 @@ public MainView()
{
this.InitializeComponent();
if (AvaloniaLocator.Current.GetService<IRuntimePlatform>().GetRuntimeInfo().IsDesktop)
((IList) this.FindControl<TabControl>("Sidebar").Items).Add(new TabItem()
{
Header = "Dialogs",
Content = new DialogsPage()
});
{
IList tabItems = ((IList)this.FindControl<TabControl>("Sidebar").Items);
tabItems.Add(new TabItem()
{
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this meant to be indented this far?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is how Rider does it, it indents to the same column. I prefer it this way but I don't mind changing it back.

Header = "Dialogs",
Content = new DialogsPage()
});
tabItems.Add(new TabItem()
{
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This also seems unusually indented

Header = "Screens",
Content = new ScreenPage()
});

}
}

private void InitializeComponent()
Expand Down
2 changes: 1 addition & 1 deletion samples/ControlCatalog/MainWindow.xaml.cs
Expand Up @@ -11,7 +11,7 @@ public MainWindow()
{
this.InitializeComponent();
this.AttachDevTools();
//Renderer.DrawDirtyRects = Renderer.DrawFps = true;
Renderer.DrawDirtyRects = Renderer.DrawFps = true;
}

private void InitializeComponent()
Expand Down
3 changes: 3 additions & 0 deletions samples/ControlCatalog/Pages/ScreenPage.xaml
@@ -0,0 +1,3 @@
<UserControl xmlns="https://github.com/avaloniaui">

</UserControl>
72 changes: 72 additions & 0 deletions samples/ControlCatalog/Pages/ScreenPage.xaml.cs
@@ -0,0 +1,72 @@
using System;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
using Avalonia.Media;
using Avalonia.Platform;

namespace ControlCatalog.Pages
{
public class ScreenPage : UserControl
{
private double leftMost;

public ScreenPage()
{
this.InitializeComponent();
}

private void InitializeComponent()
{
AvaloniaXamlLoader.Load(this);
}

protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e)
{
base.OnAttachedToVisualTree(e);
Window w = (Window)VisualRoot;
w.PositionChanged += (sender, args) => InvalidateVisual();
}

public override void Render(DrawingContext context)
{
base.Render(context);
Window w = (Window)VisualRoot;
Screen[] screens = w.Screens.All;

Pen p = new Pen(Brushes.Black);
if (screens != null)
foreach (Screen screen in screens)
{
if (screen.Bounds.X / 10f < leftMost)
{
leftMost = screen.Bounds.X / 10f;
InvalidateVisual();
return;
}

Rect boundsRect = new Rect(screen.Bounds.X / 10f + Math.Abs(leftMost), screen.Bounds.Y / 10f, screen.Bounds.Width / 10f,
screen.Bounds.Height / 10f);
Rect workingAreaRect = new Rect(screen.WorkingArea.X / 10f + Math.Abs(leftMost), screen.WorkingArea.Y / 10f, screen.WorkingArea.Width / 10f,
screen.WorkingArea.Height / 10f);
context.DrawRectangle(p, boundsRect);
context.DrawRectangle(p, workingAreaRect);

FormattedText text = new FormattedText();
text.Text = $"Bounds: {screen.Bounds.Width}:{screen.Bounds.Height}";
context.DrawText(Brushes.Black, boundsRect.Position.WithY(boundsRect.Size.Height), text);

text.Text = $"WorkArea: {screen.WorkingArea.Width}:{screen.WorkingArea.Height}";
context.DrawText(Brushes.Black, boundsRect.Position.WithY(boundsRect.Size.Height + 20), text);

text.Text = $"Primary: {screen.Primary}";
context.DrawText(Brushes.Black, boundsRect.Position.WithY(boundsRect.Size.Height + 40), text);

text.Text = $"Current: {screen.Equals(w.Screens.ScreenFromBounds(new Rect(w.Position, w.Bounds.Size)))}";
context.DrawText(Brushes.Black, boundsRect.Position.WithY(boundsRect.Size.Height + 60), text);
}

context.DrawRectangle(p, new Rect(w.Position.X / 10f + Math.Abs(leftMost), w.Position.Y / 10, w.Bounds.Width / 10, w.Bounds.Height / 10));
}
}
}
Expand Up @@ -36,6 +36,8 @@ public void Resize(Size value)
_clientSize = value;
UpdateParams();
}

public IScreenImpl Screen { get; }

public Point Position
{
Expand Down
9 changes: 9 additions & 0 deletions src/Avalonia.Controls/Platform/IScreenImpl.cs
@@ -0,0 +1,9 @@
namespace Avalonia.Platform
{
public interface IScreenImpl
{
int ScreenCount { get; }

Screen[] AllScreens { get; }
}
}
5 changes: 5 additions & 0 deletions src/Avalonia.Controls/Platform/IWindowBaseImpl.cs
Expand Up @@ -65,5 +65,10 @@ public interface IWindowBaseImpl : ITopLevelImpl
/// Sets the client size of the toplevel.
/// </summary>
void Resize(Size clientSize);

/// <summary>
/// Gets platform specific display information
/// </summary>
IScreenImpl Screen { get; }
}
}
18 changes: 18 additions & 0 deletions src/Avalonia.Controls/Platform/Screen.cs
@@ -0,0 +1,18 @@
namespace Avalonia.Platform
{
public class Screen
{
public Rect Bounds { get; }

public Rect WorkingArea { get; }

public bool Primary { get; }

public Screen(Rect bounds, Rect workingArea, bool primary)
{
this.Bounds = bounds;
this.WorkingArea = workingArea;
this.Primary = primary;
}
}
}
54 changes: 54 additions & 0 deletions src/Avalonia.Controls/Screens.cs
@@ -0,0 +1,54 @@
using System.Linq;
using Avalonia.Platform;
using Avalonia.Utilities;
using Avalonia.VisualTree;

namespace Avalonia.Controls
{
public class Screens
{
private readonly IScreenImpl _iScreenImpl;

public int ScreenCount => _iScreenImpl.ScreenCount;
public Screen[] All => _iScreenImpl?.AllScreens;
public Screen Primary => All.FirstOrDefault(x => x.Primary);

public Screens(IScreenImpl iScreenImpl)
{
_iScreenImpl = iScreenImpl;
}

public Screen ScreenFromBounds(Rect bounds){

Screen currMaxScreen = null;
double maxAreaSize = 0;
foreach (Screen screen in All)
{
double left = MathUtilities.Clamp(bounds.X, screen.Bounds.X, screen.Bounds.X + screen.Bounds.Width);
double top = MathUtilities.Clamp(bounds.Y, screen.Bounds.Y, screen.Bounds.Y + screen.Bounds.Height);
double right = MathUtilities.Clamp(bounds.X + bounds.Width, screen.Bounds.X, screen.Bounds.X + screen.Bounds.Width);
double bottom = MathUtilities.Clamp(bounds.Y + bounds.Height, screen.Bounds.Y, screen.Bounds.Y + screen.Bounds.Height);
double area = (right - left) * (bottom - top);
if (area > maxAreaSize)
{
maxAreaSize = area;
currMaxScreen = screen;
}
}

return currMaxScreen;
}

public Screen SceenFromPoint(Point point)
{
return All.FirstOrDefault(x=>x.Bounds.Contains(point));
}

public Screen ScreenFromVisual(IVisual visual)
{
Point tl = visual.PointToScreen(visual.Bounds.TopLeft);
Point br = visual.PointToScreen(visual.Bounds.BottomRight);
return ScreenFromBounds(new Rect(tl,br));
}
}
}
3 changes: 3 additions & 0 deletions src/Avalonia.Controls/Window.cs
Expand Up @@ -119,6 +119,7 @@ public Window(IWindowImpl impl)
: base(impl)
{
_maxPlatformClientSize = PlatformImpl?.MaxClientSize ?? default(Size);
Screens = new Screens(PlatformImpl?.Screen);
}

/// <inheritdoc/>
Expand All @@ -135,6 +136,8 @@ public Window(IWindowImpl impl)
remove { _nameScope.Unregistered -= value; }
}

public Screens Screens { get; private set; }

/// <summary>
/// Gets the platform-specific window implementation.
/// </summary>
Expand Down
2 changes: 1 addition & 1 deletion src/Avalonia.Controls/WindowBase.cs
Expand Up @@ -90,7 +90,7 @@ public Point Position
impl.Position = value;
}
}

/// <summary>
/// Whether an auto-size operation is in progress.
/// </summary>
Expand Down
1 change: 1 addition & 0 deletions src/Gtk/Avalonia.Gtk/Avalonia.Gtk.csproj
Expand Up @@ -48,6 +48,7 @@
<Compile Include="FramebufferManager.cs" />
<Compile Include="IconImpl.cs" />
<Compile Include="KeyTransform.cs" />
<Compile Include="ScreenImpl.cs" />
<Compile Include="SurfaceFramebuffer.cs" />
<Compile Include="SystemDialogImpl.cs" />
<Compile Include="CursorFactory.cs" />
Expand Down
42 changes: 42 additions & 0 deletions src/Gtk/Avalonia.Gtk/ScreenImpl.cs
@@ -0,0 +1,42 @@
using System;
using Avalonia.Controls;
using Avalonia.Platform;
using Avalonia.Utilities;
using Gdk;
using Screen = Avalonia.Platform.Screen;
using Window = Gtk.Window;

namespace Avalonia.Gtk
{
internal class ScreenImpl : IScreenImpl
{
private Window window;

public int ScreenCount
{
get => window.Display.DefaultScreen.NMonitors;
}
public Screen[] AllScreens {
get
{
Screen[] screens = new Screen[ScreenCount];
var screen = window.Display.DefaultScreen;

for (short i = 0; i < screens.Length; i++)
{
Rectangle geometry = screen.GetMonitorGeometry(i);
Rect geometryRect = new Rect(geometry.X, geometry.Y, geometry.Width, geometry.Height);
Screen s = new Screen(geometryRect, geometryRect, false);
screens[i] = s;
}

return screens;
}
}

public ScreenImpl(Window window)
{
this.window = window;
}
}
}
3 changes: 3 additions & 0 deletions src/Gtk/Avalonia.Gtk/WindowImpl.cs
@@ -1,5 +1,6 @@
using System;
using System.Reactive.Disposables;
using Avalonia.Controls;
using Avalonia.Platform;
using Gdk;

Expand Down Expand Up @@ -66,6 +67,8 @@ public override Size ClientSize
}
}

public IScreenImpl Screen => new ScreenImpl(Window);

public void Resize(Size value)
{
Window.Resize((int)value.Width, (int)value.Height);
Expand Down
2 changes: 2 additions & 0 deletions src/Gtk/Avalonia.Gtk3/Avalonia.Gtk3.csproj
Expand Up @@ -53,6 +53,8 @@
<Compile Include="WindowBaseImpl.cs" />
<Compile Include="Interop\Utf8Buffer.cs" />
<Compile Include="WindowImpl.cs" />
<Compile Include="ScreenImpl.cs" />
<Compile Include="GtkScreen.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Avalonia.Base\Avalonia.Base.csproj" />
Expand Down
24 changes: 24 additions & 0 deletions src/Gtk/Avalonia.Gtk3/GtkScreen.cs
@@ -0,0 +1,24 @@
using Avalonia.Platform;

namespace Avalonia.Gtk3
{
public class GtkScreen : Screen
{
private readonly int _screenId;

public GtkScreen(Rect bounds, Rect workingArea, bool primary, int screenId) : base(bounds, workingArea, primary)
{
this._screenId = screenId;
}

public override int GetHashCode()
{
return _screenId;
}

public override bool Equals(object obj)
{
return (obj is GtkScreen screen) ? this._screenId == screen._screenId : base.Equals(obj);
}
}
}