Browse Source

Add Window closing support

thread-issue-repro
Nelson Carrillo 8 years ago
parent
commit
48bb018769
  1. 4
      src/Avalonia.Windowing/Bindings/EventNotifier.cs
  2. 18
      src/Avalonia.Windowing/Bindings/EventsLoop.cs
  3. 19
      src/Avalonia.Windowing/Bindings/GlWindow.cs
  4. 12
      src/Avalonia.Windowing/WIndowingPlatform.cs
  5. 2
      src/Avalonia.Windowing/WindowImpl.cs

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

@ -9,7 +9,8 @@ namespace Avalonia.Windowing.Bindings
public delegate void KeyboardEventCallback(WindowId windowId, KeyboardEvent keyboardEvent);
public delegate void CharacterEventCallback(WindowId windowId, CharacterEvent characterEvent);
public delegate void AwakenedEventCallback();
public delegate byte ShouldExitEventLoopCallback(WindowId windowId);
[StructLayout(LayoutKind.Sequential)]
public struct EventNotifier
{
@ -18,5 +19,6 @@ namespace Avalonia.Windowing.Bindings
public ResizeEventCallback OnResized;
public KeyboardEventCallback OnKeyboardEvent;
public CharacterEventCallback OnCharacterEvent;
public ShouldExitEventLoopCallback OnShouldExitEventLoop;
}
}

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

@ -18,15 +18,6 @@ namespace Avalonia.Windowing.Bindings
EventNotifier notifier
);
[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; }
private readonly EventsLoopProxy _eventsLoopProxy;
private readonly EventNotifier _notifier;
@ -36,6 +27,7 @@ namespace Avalonia.Windowing.Bindings
public event MouseEventCallback OnMouseEvent;
public event AwakenedEventCallback OnAwakened;
public event ResizeEventCallback OnResized;
public event ShouldExitEventLoopCallback OnShouldExitEventLoop;
public EventsLoop()
{
@ -47,7 +39,8 @@ namespace Avalonia.Windowing.Bindings
OnKeyboardEvent = (windowId, keyboardEvent) => OnKeyboardEvent?.Invoke(windowId, keyboardEvent),
OnCharacterEvent = (windowId, characterEvent) => OnCharacterEvent?.Invoke(windowId, characterEvent),
OnResized = (windowId, resizeEvent) => OnResized?.Invoke(windowId, resizeEvent),
OnAwakened = () => OnAwakened?.Invoke()
OnAwakened = () => OnAwakened?.Invoke(),
OnShouldExitEventLoop = (windowId) => (byte)OnShouldExitEventLoop?.Invoke(windowId)
};
}
@ -59,11 +52,6 @@ namespace Avalonia.Windowing.Bindings
);
}
public void RunTimer(TimerDel del)
{
winit_events_loop_timer(del);
}
public void Wakeup()
{
_eventsLoopProxy.Wakeup();

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

@ -71,44 +71,56 @@ namespace Avalonia.Windowing.Bindings
_handle = winit_gl_window_new(EventsLoop.Handle);
}
private bool disposed = false;
public void Dispose()
{
winit_gl_window_destroy(_handle);
if (!disposed)
{
winit_gl_window_destroy(_handle);
disposed = true;
}
}
public void SetTitle(string title)
{
Contract.Requires<InvalidOperationException>(disposed != true);
winit_gl_window_set_title(_handle, title);
}
public void SetSize(double width, double height)
{
Contract.Requires<InvalidOperationException>(disposed != true);
winit_gl_window_set_size(_handle, width, height);
}
public void SetPosition(double x, double y)
{
Contract.Requires<InvalidOperationException>(disposed != true);
var position = new LogicalPosition { X = x, Y = y };
winit_gl_window_set_position(_handle, position);
}
public void Present()
{
Contract.Requires<InvalidOperationException>(disposed != true);
winit_gl_window_present(_handle);
}
public IntPtr GetProcAddress(string symbol)
{
Contract.Requires<InvalidOperationException>(disposed != true);
return winit_gl_window_get_proc_addr(_handle, symbol);
}
public (double, double) GetSize() {
Contract.Requires<InvalidOperationException>(disposed != true);
var size = winit_gl_window_get_size(_handle);
return (size.Width, size.Height);
}
public double GetScaleFactor ()
{
Contract.Requires<InvalidOperationException>(disposed != true);
return winit_gl_window_get_dpi_scale_factor(_handle);
}
@ -119,27 +131,32 @@ namespace Avalonia.Windowing.Bindings
public (double, double) GetPosition()
{
Contract.Requires<InvalidOperationException>(disposed != true);
var position = winit_gl_window_get_position(_handle);
return (position.X, position.Y);
}
public void Show()
{
Contract.Requires<InvalidOperationException>(disposed != true);
winit_gl_window_show(_handle);
}
public void ResizeContext(double width, double height)
{
Contract.Requires<InvalidOperationException>(disposed != true);
winit_gl_window_resize_context(_handle, width, height);
}
public void ToggleDecorations(bool visible)
{
Contract.Requires<InvalidOperationException>(disposed != true);
winit_gl_window_set_decorations(_handle, visible ? 1 : 0);
}
public void Hide()
{
Contract.Requires<InvalidOperationException>(disposed != true);
winit_gl_window_hide(_handle);
}

12
src/Avalonia.Windowing/WIndowingPlatform.cs

@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reactive.Disposables;
using System.Runtime.InteropServices;
using System.Threading;
@ -42,9 +43,18 @@ namespace Avalonia.Windowing
_eventsLoop.OnCharacterEvent += _eventsLoop_OnCharacterEvent;
_eventsLoop.OnAwakened += _eventsLoop_Awakened;
_eventsLoop.OnResized += _eventsLoop_Resized;
_eventsLoop.OnShouldExitEventLoop += _eventsLoop_OnShouldExitEventLoop;
_windows = new Dictionary<WindowId, WindowImpl>();
}
byte _eventsLoop_OnShouldExitEventLoop(WindowId windowId)
{
if (_windows.ContainsKey(windowId))
_windows.Remove(windowId);
return _windows.Any() ? (byte)0 : (byte)1;
}
void _eventsLoop_Resized(WindowId windowId, ResizeEvent resizeEvent)
{
Dispatcher.UIThread.RunJobs(DispatcherPriority.Layout);
@ -159,8 +169,6 @@ namespace Avalonia.Windowing
_eventsLoop.Wakeup();
}
private IList<TimerDel> timerTickers = new List<TimerDel>();
public IDisposable StartTimer(DispatcherPriority priority, TimeSpan interval, Action tick)
{
// TODO: Need a way to cancel a timer when Dispose is called.

2
src/Avalonia.Windowing/WindowImpl.cs

@ -131,7 +131,7 @@ namespace Avalonia.Windowing
public Point PointToClient(Point point)
{
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 Point PointToScreen(Point point)

Loading…
Cancel
Save