Browse Source

Merge remote-tracking branch 'nc4rrillo/windowing-prototype' into windowing-prototype

repro-window-close
Dan Walmsley 8 years ago
parent
commit
ebc8702f22
  1. 5
      src/Avalonia.Windowing/Avalonia.Windowing.csproj
  2. 17
      src/Avalonia.Windowing/Bindings/EventNotifier.cs
  3. 32
      src/Avalonia.Windowing/Bindings/Events.cs
  4. 105
      src/Avalonia.Windowing/Bindings/EventsLoop.cs
  5. 10
      src/Avalonia.Windowing/Bindings/EventsLoopProxy.cs
  6. 21
      src/Avalonia.Windowing/Bindings/GlWindow.cs
  7. 7
      src/Avalonia.Windowing/Bindings/IWindowWrapper.cs
  8. 12
      src/Avalonia.Windowing/Bindings/Monitor.cs
  9. 6
      src/Avalonia.Windowing/Bindings/Monitors.cs
  10. 19
      src/Avalonia.Windowing/Bindings/Units.cs
  11. 53
      src/Avalonia.Windowing/Bindings/Window.cs
  12. 7
      src/Avalonia.Windowing/WIndowingPlatform.cs
  13. 31
      src/Avalonia.Windowing/WindowImpl.cs

5
src/Avalonia.Windowing/Avalonia.Windowing.csproj

@ -11,6 +11,11 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Remove="Properties\AssemblyInfo.cs" /> <Compile Remove="Properties\AssemblyInfo.cs" />
<Compile Remove="Bindings\EventsLoopProxy.cs" />
<Compile Remove="Bindings\Window.cs" />
</ItemGroup>
<ItemGroup>
<None Remove="Bindings\Units.rs" />
</ItemGroup> </ItemGroup>
<PropertyGroup> <PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework> <TargetFramework>netstandard2.0</TargetFramework>

17
src/Avalonia.Windowing/Bindings/EventNotifier.cs

@ -0,0 +1,17 @@
using System;
using System.Runtime.InteropServices;
namespace Avalonia.Windowing.Bindings
{
public delegate void MouseEventCallback(IntPtr windowId, MouseEvent mouseEvent);
public delegate void ResizeEventCallback(IntPtr windowId, ResizeEvent resizeEvent);
public delegate void AwakenedEventCallback();
[StructLayout(LayoutKind.Sequential)]
public struct EventNotifier
{
public MouseEventCallback OnMouseEvent;
public AwakenedEventCallback OnAwakened;
public ResizeEventCallback OnResized;
}
}

32
src/Avalonia.Windowing/Bindings/Events.cs

@ -0,0 +1,32 @@
using System;
using System.Runtime.InteropServices;
namespace Avalonia.Windowing.Bindings
{
public enum MouseEventType : int
{
LeaveWindow,
LeftButtonDown,
LeftButtonUp,
RightButtonDown,
RightButtonUp,
MiddleButtonDown,
MiddleButtonUp,
Move,
Wheel,
NonClientLeftButtonDown
}
[StructLayout(LayoutKind.Sequential)]
public struct MouseEvent
{
public MouseEventType EventType { get; set; }
public LogicalPosition Position { get; set; }
}
[StructLayout(LayoutKind.Sequential)]
public struct ResizeEvent
{
public LogicalSize Size { get; set; }
}
}

105
src/Avalonia.Windowing/Bindings/EventsLoop.cs

@ -3,51 +3,6 @@ using System.Runtime.InteropServices;
namespace Avalonia.Windowing.Bindings namespace Avalonia.Windowing.Bindings
{ {
public enum MouseEventType : int
{
LeaveWindow,
LeftButtonDown,
LeftButtonUp,
RightButtonDown,
RightButtonUp,
MiddleButtonDown,
MiddleButtonUp,
Move,
Wheel,
NonClientLeftButtonDown
}
[StructLayout(LayoutKind.Sequential)]
public struct MouseEvent
{
public MouseEventType EventType { get; set; }
public LogicalPosition Position { get; set; }
}
[StructLayout(LayoutKind.Sequential)]
public struct ResizeEvent
{
public LogicalSize Size { get; set; }
}
[StructLayout(LayoutKind.Sequential)]
public struct LogicalPosition
{
public double X { get; set; }
public double Y { get; set; }
}
[StructLayout(LayoutKind.Sequential)]
public struct LogicalSize
{
public double Width { get; set; }
public double Height { get; set; }
}
public delegate void MouseEventCallback(IntPtr windowId, MouseEvent mouseEvent);
public delegate void ResizeEventCallback(IntPtr windowId, ResizeEvent mouseEvent);
public delegate void AwakenedEventCallback();
public class EventsLoop : IDisposable public class EventsLoop : IDisposable
{ {
[DllImport("winit_wrapper")] [DllImport("winit_wrapper")]
@ -60,43 +15,58 @@ namespace Avalonia.Windowing.Bindings
private static extern void winit_events_loop_run private static extern void winit_events_loop_run
( (
IntPtr handle, IntPtr handle,
MouseEventCallback callback, EventNotifier notifier
AwakenedEventCallback awakenedEventCallback, );
ResizeEventCallback resizeEventCallback
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void TimerDel();
[DllImport("winit_wrapper")]
private static extern void winit_events_loop_timer
(
TimerDel del2
); );
public IntPtr Handle { get; private set; } public IntPtr Handle { get; private set; }
private readonly EventsLoopProxy _eventsLoopProxy; private readonly EventsLoopProxy _eventsLoopProxy;
private readonly EventNotifier _notifier;
public event MouseEventCallback MouseEvent; public event MouseEventCallback OnMouseEvent;
public event AwakenedEventCallback Awakened; public event AwakenedEventCallback OnAwakened;
public event ResizeEventCallback Resized; public event ResizeEventCallback OnResized;
public EventsLoop() public EventsLoop()
{ {
Handle = winit_events_loop_new(out var elpHandle); Handle = winit_events_loop_new(out var elpHandle);
_eventsLoopProxy = new EventsLoopProxy(elpHandle); _eventsLoopProxy = new EventsLoopProxy(elpHandle);
_notifier = new EventNotifier()
{
OnMouseEvent = (IntPtr windowId, MouseEvent mouseEvent) => OnMouseEvent?.Invoke(windowId, mouseEvent),
OnResized = (IntPtr windowId, ResizeEvent resizeEvent) => OnResized?.Invoke(windowId, resizeEvent),
OnAwakened = () => OnAwakened?.Invoke()
};
} }
public void Run() public void Run()
{ {
// We need a delegate callback here to support talking back to the C# code.
// Send an event type enum and then unsafely construct the event
winit_events_loop_run( winit_events_loop_run(
Handle, Handle,
(windowId, mouseEvent) => { _notifier
MouseEvent?.Invoke(windowId, mouseEvent);
},
() =>
{
Awakened?.Invoke();
},
(windowId, ResizeEvent) => {
Resized?.Invoke(windowId, ResizeEvent);
}
); );
} }
static TimerDel del = new TimerDel(() =>
{
Console.WriteLine("WRK");
});
public void RunTimer()
{
winit_events_loop_timer(
del);
}
public void Wakeup() public void Wakeup()
{ {
_eventsLoopProxy.Wakeup(); _eventsLoopProxy.Wakeup();
@ -108,6 +78,11 @@ namespace Avalonia.Windowing.Bindings
winit_events_loop_destroy(Handle); winit_events_loop_destroy(Handle);
} }
public void GetAvailableMonitors()
{
// TODO
}
private class EventsLoopProxy : IDisposable private class EventsLoopProxy : IDisposable
{ {
[DllImport("winit_wrapper")] [DllImport("winit_wrapper")]

10
src/Avalonia.Windowing/Bindings/EventsLoopProxy.cs

@ -0,0 +1,10 @@
using System;
namespace Avalonia.Windowing.Bindings
{
public class EventsLoopProxy
{
public EventsLoopProxy()
{
}
}
}

21
src/Avalonia.Windowing/Bindings/GlWindow.cs

@ -34,6 +34,12 @@ namespace Avalonia.Windowing.Bindings
[DllImport("winit_wrapper")] [DllImport("winit_wrapper")]
private static extern void winit_gl_window_show(IntPtr handle); private static extern void winit_gl_window_show(IntPtr handle);
[DllImport("winit_wrapper")]
private static extern void winit_gl_window_hide(IntPtr handle);
[DllImport("winit_wrapper")]
private static extern void winit_gl_window_set_decorations(IntPtr handle, int visible);
[DllImport("winit_wrapper")] [DllImport("winit_wrapper")]
private static extern IntPtr winit_gl_window_get_proc_addr(IntPtr handle, string symbol); private static extern IntPtr winit_gl_window_get_proc_addr(IntPtr handle, string symbol);
@ -45,9 +51,12 @@ namespace Avalonia.Windowing.Bindings
private IntPtr _handle; private IntPtr _handle;
public IntPtr Id => winit_gl_window_get_id(_handle); public IntPtr Id => winit_gl_window_get_id(_handle);
public EventsLoop EventsLoop { get; }
public GlWindowWrapper(EventsLoop eventsLoop) public GlWindowWrapper(EventsLoop eventsLoop)
{ {
_handle = winit_gl_window_new(eventsLoop.Handle); EventsLoop = eventsLoop;
_handle = winit_gl_window_new(EventsLoop.Handle);
} }
public void Dispose() public void Dispose()
@ -100,5 +109,15 @@ namespace Avalonia.Windowing.Bindings
{ {
winit_gl_window_resize_context(_handle, width, height); winit_gl_window_resize_context(_handle, width, height);
} }
public void ToggleDecorations(bool visible)
{
winit_gl_window_set_decorations(_handle, visible ? 1 : 0);
}
public void Hide()
{
winit_gl_window_hide(_handle);
}
} }
} }

7
src/Avalonia.Windowing/Bindings/IWindowWrapper.cs

@ -7,10 +7,17 @@ namespace Avalonia.Windowing.Bindings
public interface IWindowWrapper : IDisposable public interface IWindowWrapper : IDisposable
{ {
IntPtr Id { get; } IntPtr Id { get; }
EventsLoop EventsLoop { get; }
void SetTitle(string title); void SetTitle(string title);
void SetSize(double width, double height); void SetSize(double width, double height);
(double, double) GetSize(); (double, double) GetSize();
(double, double) GetPosition(); (double, double) GetPosition();
void ToggleDecorations(bool visible);
void Show(); void Show();
void Hide();
} }
} }

12
src/Avalonia.Windowing/Bindings/Monitor.cs

@ -0,0 +1,12 @@
using System;
using System.Runtime.InteropServices;
namespace Avalonia.Windowing.Bindings
{
[StructLayout(LayoutKind.Sequential)]
public struct Monitor
{
public LogicalSize Size { get; set; }
public LogicalPosition Position { get; set; }
}
}

6
src/Avalonia.Windowing/Bindings/Monitors.cs

@ -3,9 +3,15 @@ using Avalonia.Platform;
namespace Avalonia.Windowing.Bindings namespace Avalonia.Windowing.Bindings
{ {
public class Monitors : IScreenImpl public class Monitors : IScreenImpl
{ {
public int ScreenCount => 1; public int ScreenCount => 1;
public Screen[] AllScreens => new Screen[] { new Screen(Rect.Empty, Rect.Empty, true) }; public Screen[] AllScreens => new Screen[] { new Screen(Rect.Empty, Rect.Empty, true) };
public Monitors()
{
}
} }
} }

19
src/Avalonia.Windowing/Bindings/Units.cs

@ -0,0 +1,19 @@
using System;
using System.Runtime.InteropServices;
namespace Avalonia.Windowing.Bindings
{
[StructLayout(LayoutKind.Sequential)]
public struct LogicalPosition
{
public double X { get; set; }
public double Y { get; set; }
}
[StructLayout(LayoutKind.Sequential)]
public struct LogicalSize
{
public double Width { get; set; }
public double Height { get; set; }
}
}

53
src/Avalonia.Windowing/Bindings/Window.cs

@ -1,53 +0,0 @@
using System;
using System.Runtime.InteropServices;
namespace Avalonia.Windowing.Bindings
{
public class WindowWrapper : IWindowWrapper
{
[DllImport("winit_wrapper")]
private static extern IntPtr winit_window_new(IntPtr eventsLoopHandle);
[DllImport("winit_wrapper")]
private static extern IntPtr winit_window_destroy(IntPtr handle);
private IntPtr _handle;
public IntPtr Id => IntPtr.Zero;
public WindowWrapper(EventsLoop eventsLoop)
{
_handle = winit_window_new(eventsLoop.Handle);
}
public void Dispose()
{
winit_window_destroy(_handle);
}
public void SetTitle(string title)
{
}
public void SetSize(double width, double height)
{
throw new NotImplementedException();
}
public (double, double) GetSize()
{
return (0, 0);
}
public (double, double) GetPosition()
{
return (0, 0);
}
public void Show()
{
}
}
}

7
src/Avalonia.Windowing/WIndowingPlatform.cs

@ -41,9 +41,9 @@ namespace Avalonia.Windowing
public WindowingPlatform() public WindowingPlatform()
{ {
_eventsLoop = new EventsLoop(); _eventsLoop = new EventsLoop();
_eventsLoop.MouseEvent += _eventsLoop_MouseEvent; _eventsLoop.OnMouseEvent += _eventsLoop_MouseEvent;
_eventsLoop.Awakened += _eventsLoop_Awakened; _eventsLoop.OnAwakened += _eventsLoop_Awakened;
_eventsLoop.Resized += _eventsLoop_Resized; _eventsLoop.OnResized += _eventsLoop_Resized;
_windows = new Dictionary<IntPtr, WindowImpl>(); _windows = new Dictionary<IntPtr, WindowImpl>();
} }
@ -129,6 +129,7 @@ namespace Avalonia.Windowing
public IDisposable StartTimer(DispatcherPriority priority, TimeSpan interval, Action tick) public IDisposable StartTimer(DispatcherPriority priority, TimeSpan interval, Action tick)
{ {
_eventsLoop.RunTimer();
return Disposable.Create(() => { }); return Disposable.Create(() => { });
} }
} }

31
src/Avalonia.Windowing/WindowImpl.cs

@ -23,16 +23,16 @@ namespace Avalonia.Windowing
public WindowState WindowState { get; set; } public WindowState WindowState { get; set; }
public Action<WindowState> WindowStateChanged { get; set; } public Action<WindowState> WindowStateChanged { get; set; }
public Func<bool> Closing { get; set; } public Func<bool> Closing { get; set; }
public Point Position public Point Position
{ {
get get
{ {
var (x, y) = _windowWrapper.GetPosition(); var (x, y) = _windowWrapper.GetPosition();
return new Point(x, y); return new Point(x, y);
} }
set set
{ {
var x = value; var x = value;
} }
} }
@ -46,8 +46,9 @@ namespace Avalonia.Windowing
public IScreenImpl Screen => new Monitors(); public IScreenImpl Screen => new Monitors();
public Size ClientSize { public Size ClientSize
get {
get
{ {
var (width, height) = _windowWrapper.GetSize(); var (width, height) = _windowWrapper.GetSize();
return new Size(width, height); return new Size(width, height);
@ -94,6 +95,7 @@ namespace Avalonia.Windowing
public void Hide() public void Hide()
{ {
_windowWrapper.Hide();
} }
public void Invalidate(Rect rect) public void Invalidate(Rect rect)
@ -110,14 +112,14 @@ namespace Avalonia.Windowing
public Point PointToScreen(Point point) public Point PointToScreen(Point point)
{ {
var position = Position; var position = Position;
return new Point(point.X - position.X, point.Y - position.Y);; return new Point(point.X - position.X, point.Y - position.Y); ;
} }
public void Resize(Size clientSize) public void Resize(Size clientSize)
{ {
if (clientSize == ClientSize) if (clientSize == ClientSize)
return; return;
// This is where we size the window accordingly.. // This is where we size the window accordingly..
_windowWrapper.SetSize(clientSize.Width, clientSize.Height); _windowWrapper.SetSize(clientSize.Width, clientSize.Height);
//Resized(clientSize); //Resized(clientSize);
@ -140,6 +142,7 @@ namespace Avalonia.Windowing
public void SetSystemDecorations(bool enabled) public void SetSystemDecorations(bool enabled)
{ {
_windowWrapper.ToggleDecorations(enabled);
} }
public void SetTitle(string title) public void SetTitle(string title)
@ -165,22 +168,22 @@ namespace Avalonia.Windowing
{ {
} }
public void OnMouseEvent(MouseEvent evt) public void OnMouseEvent(MouseEvent evt)
{ {
Dispatcher.UIThread.RunJobs(DispatcherPriority.Input); Dispatcher.UIThread.RunJobs(DispatcherPriority.Input);
if(evt.EventType == MouseEventType.Move) if (evt.EventType == MouseEventType.Move)
{ {
_lastPosition = evt.Position; _lastPosition = evt.Position;
} }
Input(new RawMouseEventArgs(MouseDevice, (uint)Environment.TickCount, _inputRoot, (RawMouseEventType)evt.EventType, new Point(_lastPosition.X, _lastPosition.Y), InputModifiers.None)); Input(new RawMouseEventArgs(MouseDevice, (uint)Environment.TickCount, _inputRoot, (RawMouseEventType)evt.EventType, new Point(_lastPosition.X, _lastPosition.Y), InputModifiers.None));
} }
public void OnResizeEvent(ResizeEvent evt) public void OnResizeEvent(ResizeEvent evt)
{ {
Resized?.Invoke(ClientSize); Resized?.Invoke(ClientSize);
Paint?.Invoke(new Rect(ClientSize)); Paint?.Invoke(new Rect(ClientSize));
} }
} }
} }
Loading…
Cancel
Save