From 5e0243cfbaa9c5ba4cd9f09650b3290b5a777894 Mon Sep 17 00:00:00 2001 From: OronDF343 Date: Sun, 14 Aug 2016 16:24:29 +0300 Subject: [PATCH 1/6] Added PositionChanged event in TopLevel Implements #629 --- .../Platform/SkiaPlatform/WindowImpl.cs | 2 ++ .../Avalonia.Controls.csproj | 1 + .../Platform/ITopLevelImpl.cs | 5 ++++ .../PositionChangedEventArgs.cs | 27 +++++++++++++++++++ src/Avalonia.Controls/TopLevel.cs | 16 +++++++++++ src/Gtk/Avalonia.Gtk/WindowImpl.cs | 13 +++++++++ src/Windows/Avalonia.Win32/WindowImpl.cs | 6 +++++ src/iOS/Avalonia.iOS/AvaloniaView.cs | 12 ++++++++- 8 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 src/Avalonia.Controls/PositionChangedEventArgs.cs diff --git a/src/Android/Avalonia.Android/Platform/SkiaPlatform/WindowImpl.cs b/src/Android/Avalonia.Android/Platform/SkiaPlatform/WindowImpl.cs index 66f6aeb757..c5e3622404 100644 --- a/src/Android/Avalonia.Android/Platform/SkiaPlatform/WindowImpl.cs +++ b/src/Android/Avalonia.Android/Platform/SkiaPlatform/WindowImpl.cs @@ -87,6 +87,8 @@ namespace Avalonia.Android.Platform.SkiaPlatform public Action ScalingChanged { get; set; } + public Action PositionChanged { get; set; } + public View View => this; Action ITopLevelImpl.Activated { get; set; } diff --git a/src/Avalonia.Controls/Avalonia.Controls.csproj b/src/Avalonia.Controls/Avalonia.Controls.csproj index d6e5926727..40ff32cccc 100644 --- a/src/Avalonia.Controls/Avalonia.Controls.csproj +++ b/src/Avalonia.Controls/Avalonia.Controls.csproj @@ -56,6 +56,7 @@ + diff --git a/src/Avalonia.Controls/Platform/ITopLevelImpl.cs b/src/Avalonia.Controls/Platform/ITopLevelImpl.cs index f5d8344bda..281851a512 100644 --- a/src/Avalonia.Controls/Platform/ITopLevelImpl.cs +++ b/src/Avalonia.Controls/Platform/ITopLevelImpl.cs @@ -67,6 +67,11 @@ namespace Avalonia.Platform /// Action ScalingChanged { get; set; } + /// + /// Gets or sets a method called when the window's position changes. + /// + Action PositionChanged { get; set; } + /// /// Activates the window. /// diff --git a/src/Avalonia.Controls/PositionChangedEventArgs.cs b/src/Avalonia.Controls/PositionChangedEventArgs.cs new file mode 100644 index 0000000000..74c6e9ede1 --- /dev/null +++ b/src/Avalonia.Controls/PositionChangedEventArgs.cs @@ -0,0 +1,27 @@ +// Copyright (c) The Avalonia Project. All rights reserved. +// Licensed under the MIT license. See licence.md file in the project root for full license information. + +using System; + +namespace Avalonia.Controls +{ + /// + /// Provides data for the event. + /// + public class PositionChangedEventArgs : EventArgs + { + /// + /// Initializes a new instance of the class. + /// + /// The new window position. + public PositionChangedEventArgs(Point newPos) + { + NewPosition = newPos; + } + + /// + /// Gets the new window position. + /// + public Point NewPosition { get; } + } +} \ No newline at end of file diff --git a/src/Avalonia.Controls/TopLevel.cs b/src/Avalonia.Controls/TopLevel.cs index 59a3072c23..2ba359ce47 100644 --- a/src/Avalonia.Controls/TopLevel.cs +++ b/src/Avalonia.Controls/TopLevel.cs @@ -105,6 +105,7 @@ namespace Avalonia.Controls PlatformImpl.Input = HandleInput; PlatformImpl.Resized = HandleResized; PlatformImpl.ScalingChanged = HandleScalingChanged; + PlatformImpl.PositionChanged = HandlePositionChanged; _keyboardNavigationHandler?.SetOwner(this); _accessKeyHandler?.SetOwner(this); @@ -138,6 +139,11 @@ namespace Avalonia.Controls /// public event EventHandler Deactivated; + /// + /// Fired when the window position is changed. + /// + public event EventHandler PositionChanged; + /// /// Gets or sets the client size of the window. /// @@ -395,6 +401,16 @@ namespace Avalonia.Controls _inputManager.ProcessInput(e); } + /// + /// Handles a window position change notification from + /// . + /// + /// The window position. + private void HandlePositionChanged(Point pos) + { + PositionChanged?.Invoke(this, new PositionChangedEventArgs(pos)); + } + /// /// Starts moving a window with left button being held. Should be called from left mouse button press event handler /// diff --git a/src/Gtk/Avalonia.Gtk/WindowImpl.cs b/src/Gtk/Avalonia.Gtk/WindowImpl.cs index 26ad52135d..87f733b370 100644 --- a/src/Gtk/Avalonia.Gtk/WindowImpl.cs +++ b/src/Gtk/Avalonia.Gtk/WindowImpl.cs @@ -23,6 +23,8 @@ namespace Avalonia.Gtk private Size _lastClientSize; + private Point _lastPosition; + private Gtk.IMContext _imContext; private uint _lastKeyEventTimestamp; @@ -52,6 +54,7 @@ namespace Avalonia.Gtk DoubleBuffered = false; Realize(); _lastClientSize = ClientSize; + _lastPosition = Position; } protected override void OnRealized () @@ -175,6 +178,8 @@ namespace Avalonia.Gtk public Action ScalingChanged { get; set; } + public Action PositionChanged { get; set; } + public IPopupImpl CreatePopup() { return new PopupImpl(); @@ -338,6 +343,14 @@ namespace Avalonia.Gtk _lastClientSize = newSize; } + var newPosition = new Point(evnt.X, evnt.Y); + + if (newPosition != _lastPosition) + { + PositionChanged(newPosition); + _lastPosition = newPosition; + } + return true; } diff --git a/src/Windows/Avalonia.Win32/WindowImpl.cs b/src/Windows/Avalonia.Win32/WindowImpl.cs index 0b09d9ec91..721c834f14 100644 --- a/src/Windows/Avalonia.Win32/WindowImpl.cs +++ b/src/Windows/Avalonia.Win32/WindowImpl.cs @@ -55,6 +55,8 @@ namespace Avalonia.Win32 public Action ScalingChanged { get; set; } + public Action PositionChanged { get; set; } + public Thickness BorderThickness { get @@ -561,6 +563,10 @@ namespace Avalonia.Win32 } return IntPtr.Zero; + + case UnmanagedMethods.WindowsMessage.WM_MOVE: + PositionChanged?.Invoke(new Point(ToInt32(lParam) & 0xffff, ToInt32(lParam) >> 16)); + return IntPtr.Zero; } if (e != null && Input != null) diff --git a/src/iOS/Avalonia.iOS/AvaloniaView.cs b/src/iOS/Avalonia.iOS/AvaloniaView.cs index 505a88ecd5..8b14d09573 100644 --- a/src/iOS/Avalonia.iOS/AvaloniaView.cs +++ b/src/iOS/Avalonia.iOS/AvaloniaView.cs @@ -27,6 +27,7 @@ namespace Avalonia.iOS private readonly UIViewController _controller; private IInputRoot _inputRoot; private readonly KeyboardEventsHelper _keyboardHelper; + private Point _position; public AvaloniaView(UIWindow window, UIViewController controller) : base(onFrame => PlatformThreadingInterface.Instance.Render = onFrame) { @@ -72,6 +73,7 @@ namespace Avalonia.iOS public Action Paint { get; set; } public Action Resized { get; set; } public Action ScalingChanged { get; set; } + public Action PositionChanged { get; set; } public IPlatformHandle Handle => AvaloniaPlatformHandle; @@ -136,7 +138,15 @@ namespace Avalonia.iOS //Not supported } - public Point Position { get; set; } + public Point Position + { + get { return _position; } + set + { + _position = value; + PositionChanged?.Invoke(_position); + } + } public Size MaxClientSize => Bounds.Size.ToAvalonia(); public void SetTitle(string title) From 1071dc079c97c162b5f08229d1efd9a6da238d14 Mon Sep 17 00:00:00 2001 From: OronDF343 Date: Sun, 28 Aug 2016 02:26:55 +0300 Subject: [PATCH 2/6] Renamed PositionChangedEventArgs to PointEventArgs --- src/Avalonia.Controls/Avalonia.Controls.csproj | 2 +- .../{PositionChangedEventArgs.cs => PointEventArgs.cs} | 8 ++++---- src/Avalonia.Controls/TopLevel.cs | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) rename src/Avalonia.Controls/{PositionChangedEventArgs.cs => PointEventArgs.cs} (66%) diff --git a/src/Avalonia.Controls/Avalonia.Controls.csproj b/src/Avalonia.Controls/Avalonia.Controls.csproj index 40ff32cccc..ae3058e578 100644 --- a/src/Avalonia.Controls/Avalonia.Controls.csproj +++ b/src/Avalonia.Controls/Avalonia.Controls.csproj @@ -56,7 +56,7 @@ - + diff --git a/src/Avalonia.Controls/PositionChangedEventArgs.cs b/src/Avalonia.Controls/PointEventArgs.cs similarity index 66% rename from src/Avalonia.Controls/PositionChangedEventArgs.cs rename to src/Avalonia.Controls/PointEventArgs.cs index 74c6e9ede1..11a82cfd20 100644 --- a/src/Avalonia.Controls/PositionChangedEventArgs.cs +++ b/src/Avalonia.Controls/PointEventArgs.cs @@ -6,15 +6,15 @@ using System; namespace Avalonia.Controls { /// - /// Provides data for the event. + /// Provides data for events. /// - public class PositionChangedEventArgs : EventArgs + public class PointEventArgs : EventArgs { /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The new window position. - public PositionChangedEventArgs(Point newPos) + public PointEventArgs(Point newPos) { NewPosition = newPos; } diff --git a/src/Avalonia.Controls/TopLevel.cs b/src/Avalonia.Controls/TopLevel.cs index 2ba359ce47..47660b27e8 100644 --- a/src/Avalonia.Controls/TopLevel.cs +++ b/src/Avalonia.Controls/TopLevel.cs @@ -142,7 +142,7 @@ namespace Avalonia.Controls /// /// Fired when the window position is changed. /// - public event EventHandler PositionChanged; + public event EventHandler PositionChanged; /// /// Gets or sets the client size of the window. @@ -408,7 +408,7 @@ namespace Avalonia.Controls /// The window position. private void HandlePositionChanged(Point pos) { - PositionChanged?.Invoke(this, new PositionChangedEventArgs(pos)); + PositionChanged?.Invoke(this, new PointEventArgs(pos)); } /// From 371588bc2d1ca3623b3eec530cef2b61ed481569 Mon Sep 17 00:00:00 2001 From: OronDF343 Date: Sun, 28 Aug 2016 02:34:43 +0300 Subject: [PATCH 3/6] Renamed point data property --- src/Avalonia.Controls/PointEventArgs.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Avalonia.Controls/PointEventArgs.cs b/src/Avalonia.Controls/PointEventArgs.cs index 11a82cfd20..10d66eec6a 100644 --- a/src/Avalonia.Controls/PointEventArgs.cs +++ b/src/Avalonia.Controls/PointEventArgs.cs @@ -13,15 +13,15 @@ namespace Avalonia.Controls /// /// Initializes a new instance of the class. /// - /// The new window position. - public PointEventArgs(Point newPos) + /// The data. + public PointEventArgs(Point data) { - NewPosition = newPos; + Data = data; } /// - /// Gets the new window position. + /// Gets the data. /// - public Point NewPosition { get; } + public Point Data { get; } } } \ No newline at end of file From 66d0a56046303a1f487743665aec0ef9fe47108c Mon Sep 17 00:00:00 2001 From: OronDF343 Date: Thu, 8 Sep 2016 00:39:51 +0300 Subject: [PATCH 4/6] Fixed negative values on Win32 --- src/Windows/Avalonia.Win32/WindowImpl.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Windows/Avalonia.Win32/WindowImpl.cs b/src/Windows/Avalonia.Win32/WindowImpl.cs index 721c834f14..5c1e653184 100644 --- a/src/Windows/Avalonia.Win32/WindowImpl.cs +++ b/src/Windows/Avalonia.Win32/WindowImpl.cs @@ -565,7 +565,7 @@ namespace Avalonia.Win32 return IntPtr.Zero; case UnmanagedMethods.WindowsMessage.WM_MOVE: - PositionChanged?.Invoke(new Point(ToInt32(lParam) & 0xffff, ToInt32(lParam) >> 16)); + PositionChanged?.Invoke(new Point((short)(ToInt32(lParam) & 0xffff), (short)(ToInt32(lParam) >> 16))); return IntPtr.Zero; } From f4c5293ece8175024cb7411e0ee35a9cc01cab99 Mon Sep 17 00:00:00 2001 From: OronDF343 Date: Thu, 8 Sep 2016 00:44:35 +0300 Subject: [PATCH 5/6] Changed point name once again --- src/Avalonia.Controls/PointEventArgs.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Avalonia.Controls/PointEventArgs.cs b/src/Avalonia.Controls/PointEventArgs.cs index 10d66eec6a..4173d367d0 100644 --- a/src/Avalonia.Controls/PointEventArgs.cs +++ b/src/Avalonia.Controls/PointEventArgs.cs @@ -13,15 +13,15 @@ namespace Avalonia.Controls /// /// Initializes a new instance of the class. /// - /// The data. - public PointEventArgs(Point data) + /// The data. + public PointEventArgs(Point point) { - Data = data; + Point = point; } /// /// Gets the data. /// - public Point Data { get; } + public Point Point { get; } } -} \ No newline at end of file +} From 26f1f0b884f3fcba3dd1a791097a404bbfa1517f Mon Sep 17 00:00:00 2001 From: OronDF343 Date: Thu, 8 Sep 2016 23:01:12 +0300 Subject: [PATCH 6/6] Fixed bad diff tool errors --- src/Gtk/Avalonia.Gtk/WindowImpl.cs | 210 +-------- .../WindowImpl_BASE_46644.cs.orig | 404 ------------------ 2 files changed, 13 insertions(+), 601 deletions(-) delete mode 100644 src/Gtk/Avalonia.Gtk/WindowImpl_BASE_46644.cs.orig diff --git a/src/Gtk/Avalonia.Gtk/WindowImpl.cs b/src/Gtk/Avalonia.Gtk/WindowImpl.cs index bc60e5eb65..bb3c3e6b7b 100644 --- a/src/Gtk/Avalonia.Gtk/WindowImpl.cs +++ b/src/Gtk/Avalonia.Gtk/WindowImpl.cs @@ -10,15 +10,7 @@ namespace Avalonia.Gtk { private Gtk.Window _window; private Gtk.Window Window => _window ?? (_window = (Gtk.Window) Widget); - - -<<<<<<< HEAD - private Point _lastPosition; - - private Gtk.IMContext _imContext; -======= ->>>>>>> dfd4bbf34a7632465a84126b22495072945fa7d5 - + public WindowImpl(Gtk.WindowType type) : base(new PlatformHandleAwareWindow(type)) { Init(); @@ -38,6 +30,7 @@ namespace Avalonia.Gtk _lastPosition = Position; } private Size _lastClientSize; + private Point _lastPosition; void OnConfigureEvent(object o, Gtk.ConfigureEventArgs args) { var evnt = args.Event; @@ -49,6 +42,14 @@ namespace Avalonia.Gtk Resized(newSize); _lastClientSize = newSize; } + + var newPosition = new Point(evnt.X, evnt.Y); + + if (newPosition != _lastPosition) + { + PositionChanged(newPosition); + _lastPosition = newPosition; + } } public override Size ClientSize @@ -72,43 +73,7 @@ namespace Avalonia.Gtk Window.Title = title; } -<<<<<<< HEAD - - IntPtr IPlatformHandle.Handle => GetNativeWindow(); - public string HandleDescriptor => "HWND"; - - public Action Activated { get; set; } - - public Action Closed { get; set; } - - public Action Deactivated { get; set; } - - public Action Input { get; set; } - - public Action Paint { get; set; } - - public Action Resized { get; set; } - - public Action ScalingChanged { get; set; } - - public Action PositionChanged { get; set; } - - public IPopupImpl CreatePopup() - { - return new PopupImpl(); - } - - public void Invalidate(Rect rect) - { - if (base.GdkWindow != null) - base.GdkWindow.InvalidateRect( - new Rectangle((int) rect.X, (int) rect.Y, (int) rect.Width, (int) rect.Height), true); - } - - public Point PointToClient(Point point) -======= void OnFocusActivated(object sender, EventArgs eventArgs) ->>>>>>> dfd4bbf34a7632465a84126b22495072945fa7d5 { Activated(); } @@ -150,161 +115,12 @@ namespace Avalonia.Gtk return Disposable.Empty; } - -<<<<<<< HEAD - public void SetSystemDecorations(bool enabled) => Decorated = enabled; - - void ITopLevelImpl.Activate() - { - Activate(); - } - - private static InputModifiers GetModifierKeys(ModifierType state) - { - var rv = InputModifiers.None; - if (state.HasFlag(ModifierType.ControlMask)) - rv |= InputModifiers.Control; - if (state.HasFlag(ModifierType.ShiftMask)) - rv |= InputModifiers.Shift; - if (state.HasFlag(ModifierType.Mod1Mask)) - rv |= InputModifiers.Control; - if(state.HasFlag(ModifierType.Button1Mask)) - rv |= InputModifiers.LeftMouseButton; - if (state.HasFlag(ModifierType.Button2Mask)) - rv |= InputModifiers.RightMouseButton; - if (state.HasFlag(ModifierType.Button3Mask)) - rv |= InputModifiers.MiddleMouseButton; - return rv; - } - - protected override bool OnButtonPressEvent(EventButton evnt) - { - - var e = new RawMouseEventArgs( - GtkMouseDevice.Instance, - evnt.Time, - _inputRoot, - evnt.Button == 1 - ? RawMouseEventType.LeftButtonDown - : evnt.Button == 3 ? RawMouseEventType.RightButtonDown : RawMouseEventType.MiddleButtonDown, - new Point(evnt.X, evnt.Y), GetModifierKeys(evnt.State)); - Input(e); - return true; - } - - protected override bool OnScrollEvent(EventScroll evnt) - { - double step = 1; - var delta = new Vector(); - if (evnt.Direction == ScrollDirection.Down) - delta = new Vector(0, -step); - else if (evnt.Direction == ScrollDirection.Up) - delta = new Vector(0, step); - else if (evnt.Direction == ScrollDirection.Right) - delta = new Vector(-step, 0); - if (evnt.Direction == ScrollDirection.Left) - delta = new Vector(step, 0); - var e = new RawMouseWheelEventArgs(GtkMouseDevice.Instance, evnt.Time, _inputRoot, new Point(evnt.X, evnt.Y), delta, GetModifierKeys(evnt.State)); - Input(e); - return base.OnScrollEvent(evnt); - } - - protected override bool OnButtonReleaseEvent(EventButton evnt) - { - var e = new RawMouseEventArgs( - GtkMouseDevice.Instance, - evnt.Time, - _inputRoot, - evnt.Button == 1 - ? RawMouseEventType.LeftButtonUp - : evnt.Button == 3 ? RawMouseEventType.RightButtonUp : RawMouseEventType.MiddleButtonUp, - new Point(evnt.X, evnt.Y), GetModifierKeys(evnt.State)); - Input(e); - return true; - } - - protected override bool OnConfigureEvent(EventConfigure evnt) - { - var newSize = new Size(evnt.Width, evnt.Height); - - if (newSize != _lastClientSize) - { - Resized(newSize); - _lastClientSize = newSize; - } - - var newPosition = new Point(evnt.X, evnt.Y); - - if (newPosition != _lastPosition) - { - PositionChanged(newPosition); - _lastPosition = newPosition; - } - - return true; - } - - protected override void OnDestroyed() - { - Closed(); - } - - private bool ProcessKeyEvent(EventKey evnt) - { - _lastKeyEventTimestamp = evnt.Time; - if (_imContext.FilterKeypress(evnt)) - return true; - var e = new RawKeyEventArgs( - GtkKeyboardDevice.Instance, - evnt.Time, - evnt.Type == EventType.KeyPress ? RawKeyEventType.KeyDown : RawKeyEventType.KeyUp, - GtkKeyboardDevice.ConvertKey(evnt.Key), GetModifierKeys(evnt.State)); - Input(e); - return true; - } - - protected override bool OnKeyPressEvent(EventKey evnt) => ProcessKeyEvent(evnt); - - protected override bool OnKeyReleaseEvent(EventKey evnt) => ProcessKeyEvent(evnt); - - private void ImContext_Commit(object o, Gtk.CommitArgs args) - { - Input(new RawTextInputEventArgs(GtkKeyboardDevice.Instance, _lastKeyEventTimestamp, args.Str)); - } - - protected override bool OnExposeEvent(EventExpose evnt) - { - Paint(evnt.Area.ToAvalonia()); - return true; - } - - protected override void OnFocusActivated() - { - Activated(); - } - - protected override bool OnMotionNotifyEvent(EventMotion evnt) - { - var position = new Point(evnt.X, evnt.Y); - - GtkMouseDevice.Instance.SetClientPosition(position); - - var e = new RawMouseEventArgs( - GtkMouseDevice.Instance, - evnt.Time, - _inputRoot, - RawMouseEventType.Move, - position, GetModifierKeys(evnt.State)); - Input(e); - return true; - } -======= + public override void SetSystemDecorations(bool enabled) => Window.Decorated = enabled; ->>>>>>> dfd4bbf34a7632465a84126b22495072945fa7d5 - + public override void SetIcon(IWindowIconImpl icon) { Window.Icon = ((IconImpl)icon).Pixbuf; } } -} \ No newline at end of file +} diff --git a/src/Gtk/Avalonia.Gtk/WindowImpl_BASE_46644.cs.orig b/src/Gtk/Avalonia.Gtk/WindowImpl_BASE_46644.cs.orig deleted file mode 100644 index 26ad52135d..0000000000 --- a/src/Gtk/Avalonia.Gtk/WindowImpl_BASE_46644.cs.orig +++ /dev/null @@ -1,404 +0,0 @@ -// Copyright (c) The Avalonia Project. All rights reserved. -// Licensed under the MIT license. See licence.md file in the project root for full license information. - -using System; -using System.Reactive.Disposables; -using System.Runtime.InteropServices; -using Gdk; -using Avalonia.Controls; -using Avalonia.Input.Raw; -using Avalonia.Platform; -using Avalonia.Input; -using Avalonia.Threading; -using Action = System.Action; -using WindowEdge = Avalonia.Controls.WindowEdge; - -namespace Avalonia.Gtk -{ - using Gtk = global::Gtk; - - public class WindowImpl : Gtk.Window, IWindowImpl, IPlatformHandle - { - private IInputRoot _inputRoot; - - private Size _lastClientSize; - - private Gtk.IMContext _imContext; - - private uint _lastKeyEventTimestamp; - - private static readonly Gdk.Cursor DefaultCursor = new Gdk.Cursor(CursorType.LeftPtr); - - public WindowImpl() - : base(Gtk.WindowType.Toplevel) - { - DefaultSize = new Gdk.Size(900, 480); - Init(); - } - - public WindowImpl(Gtk.WindowType type) - : base(type) - { - Init(); - } - - private void Init() - { - Events = EventMask.PointerMotionMask | - EventMask.ButtonPressMask | - EventMask.ButtonReleaseMask; - _imContext = new Gtk.IMMulticontext(); - _imContext.Commit += ImContext_Commit; - DoubleBuffered = false; - Realize(); - _lastClientSize = ClientSize; - } - - protected override void OnRealized () - { - base.OnRealized (); - _imContext.ClientWindow = this.GdkWindow; - } - - public Size ClientSize - { - get - { - int width; - int height; - GetSize(out width, out height); - return new Size(width, height); - } - - set - { - Resize((int)value.Width, (int)value.Height); - } - } - - public Size MaxClientSize - { - get - { - // TODO: This should take into account things such as taskbar and window border - // thickness etc. - return new Size(Screen.Width, Screen.Height); - } - } - - public Avalonia.Controls.WindowState WindowState - { - get - { - switch (GdkWindow.State) - { - case Gdk.WindowState.Iconified: - return Controls.WindowState.Minimized; - case Gdk.WindowState.Maximized: - return Controls.WindowState.Maximized; - default: - return Controls.WindowState.Normal; - } - } - - set - { - switch (value) - { - case Controls.WindowState.Minimized: - GdkWindow.Iconify(); - break; - case Controls.WindowState.Maximized: - GdkWindow.Maximize(); - break; - case Controls.WindowState.Normal: - GdkWindow.Deiconify(); - GdkWindow.Unmaximize(); - break; - } - } - } - - public double Scaling => 1; - - IPlatformHandle ITopLevelImpl.Handle => this; - - [DllImport("libgdk-win32-2.0-0.dll", CallingConvention = CallingConvention.Cdecl)] - extern static IntPtr gdk_win32_drawable_get_handle(IntPtr gdkWindow); - - [DllImport("libgtk-x11-2.0.so.0", CallingConvention = CallingConvention.Cdecl)] - extern static IntPtr gdk_x11_drawable_get_xid(IntPtr gdkWindow); - - [DllImport("libgdk-quartz-2.0-0.dylib", CallingConvention = CallingConvention.Cdecl)] - extern static IntPtr gdk_quartz_window_get_nswindow(IntPtr gdkWindow); - - IntPtr _nativeWindow; - - IntPtr GetNativeWindow() - { - IntPtr h = GdkWindow.Handle; - if (_nativeWindow != IntPtr.Zero) - return _nativeWindow; - //Try whatever backend that works - try - { - return _nativeWindow = gdk_quartz_window_get_nswindow(h); - } - catch - { - } - try - { - return _nativeWindow = gdk_x11_drawable_get_xid(h); - } - catch - { - } - return _nativeWindow = gdk_win32_drawable_get_handle(h); - } - - - IntPtr IPlatformHandle.Handle => GetNativeWindow(); - public string HandleDescriptor => "HWND"; - - public Action Activated { get; set; } - - public Action Closed { get; set; } - - public Action Deactivated { get; set; } - - public Action Input { get; set; } - - public Action Paint { get; set; } - - public Action Resized { get; set; } - - public Action ScalingChanged { get; set; } - - public IPopupImpl CreatePopup() - { - return new PopupImpl(); - } - - public void Invalidate(Rect rect) - { - if (base.GdkWindow != null) - base.GdkWindow.InvalidateRect( - new Rectangle((int) rect.X, (int) rect.Y, (int) rect.Width, (int) rect.Height), true); - } - - public Point PointToClient(Point point) - { - int x, y; - GdkWindow.GetDeskrelativeOrigin(out x, out y); - - return new Point(point.X - x, point.Y - y); - } - - public Point PointToScreen(Point point) - { - int x, y; - GdkWindow.GetDeskrelativeOrigin(out x, out y); - - return new Point(point.X + x, point.Y + y); - } - - public void SetInputRoot(IInputRoot inputRoot) - { - _inputRoot = inputRoot; - } - - public void SetTitle(string title) - { - Title = title; - } - - - public void SetCursor(IPlatformHandle cursor) - { - GdkWindow.Cursor = cursor != null ? new Gdk.Cursor(cursor.Handle) : DefaultCursor; - } - - public void BeginMoveDrag() - { - int x, y; - ModifierType mod; - Screen.RootWindow.GetPointer(out x, out y, out mod); - BeginMoveDrag(1, x, y, 0); - } - - public void BeginResizeDrag(WindowEdge edge) - { - int x, y; - ModifierType mod; - Screen.RootWindow.GetPointer(out x, out y, out mod); - BeginResizeDrag((Gdk.WindowEdge) (int) edge, 1, x, y, 0); - } - - public Point Position - { - get - { - int x, y; - GetPosition(out x, out y); - return new Point(x, y); - } - set - { - Move((int)value.X, (int)value.Y); - } - } - - public IDisposable ShowDialog() - { - Modal = true; - Show(); - - return Disposable.Empty; - } - - public void SetSystemDecorations(bool enabled) => Decorated = enabled; - - void ITopLevelImpl.Activate() - { - Activate(); - } - - private static InputModifiers GetModifierKeys(ModifierType state) - { - var rv = InputModifiers.None; - if (state.HasFlag(ModifierType.ControlMask)) - rv |= InputModifiers.Control; - if (state.HasFlag(ModifierType.ShiftMask)) - rv |= InputModifiers.Shift; - if (state.HasFlag(ModifierType.Mod1Mask)) - rv |= InputModifiers.Control; - if(state.HasFlag(ModifierType.Button1Mask)) - rv |= InputModifiers.LeftMouseButton; - if (state.HasFlag(ModifierType.Button2Mask)) - rv |= InputModifiers.RightMouseButton; - if (state.HasFlag(ModifierType.Button3Mask)) - rv |= InputModifiers.MiddleMouseButton; - return rv; - } - - protected override bool OnButtonPressEvent(EventButton evnt) - { - - var e = new RawMouseEventArgs( - GtkMouseDevice.Instance, - evnt.Time, - _inputRoot, - evnt.Button == 1 - ? RawMouseEventType.LeftButtonDown - : evnt.Button == 3 ? RawMouseEventType.RightButtonDown : RawMouseEventType.MiddleButtonDown, - new Point(evnt.X, evnt.Y), GetModifierKeys(evnt.State)); - Input(e); - return true; - } - - protected override bool OnScrollEvent(EventScroll evnt) - { - double step = 1; - var delta = new Vector(); - if (evnt.Direction == ScrollDirection.Down) - delta = new Vector(0, -step); - else if (evnt.Direction == ScrollDirection.Up) - delta = new Vector(0, step); - else if (evnt.Direction == ScrollDirection.Right) - delta = new Vector(-step, 0); - if (evnt.Direction == ScrollDirection.Left) - delta = new Vector(step, 0); - var e = new RawMouseWheelEventArgs(GtkMouseDevice.Instance, evnt.Time, _inputRoot, new Point(evnt.X, evnt.Y), delta, GetModifierKeys(evnt.State)); - Input(e); - return base.OnScrollEvent(evnt); - } - - protected override bool OnButtonReleaseEvent(EventButton evnt) - { - var e = new RawMouseEventArgs( - GtkMouseDevice.Instance, - evnt.Time, - _inputRoot, - evnt.Button == 1 - ? RawMouseEventType.LeftButtonUp - : evnt.Button == 3 ? RawMouseEventType.RightButtonUp : RawMouseEventType.MiddleButtonUp, - new Point(evnt.X, evnt.Y), GetModifierKeys(evnt.State)); - Input(e); - return true; - } - - protected override bool OnConfigureEvent(EventConfigure evnt) - { - var newSize = new Size(evnt.Width, evnt.Height); - - if (newSize != _lastClientSize) - { - Resized(newSize); - _lastClientSize = newSize; - } - - return true; - } - - protected override void OnDestroyed() - { - Closed(); - } - - private bool ProcessKeyEvent(EventKey evnt) - { - _lastKeyEventTimestamp = evnt.Time; - if (_imContext.FilterKeypress(evnt)) - return true; - var e = new RawKeyEventArgs( - GtkKeyboardDevice.Instance, - evnt.Time, - evnt.Type == EventType.KeyPress ? RawKeyEventType.KeyDown : RawKeyEventType.KeyUp, - GtkKeyboardDevice.ConvertKey(evnt.Key), GetModifierKeys(evnt.State)); - Input(e); - return true; - } - - protected override bool OnKeyPressEvent(EventKey evnt) => ProcessKeyEvent(evnt); - - protected override bool OnKeyReleaseEvent(EventKey evnt) => ProcessKeyEvent(evnt); - - private void ImContext_Commit(object o, Gtk.CommitArgs args) - { - Input(new RawTextInputEventArgs(GtkKeyboardDevice.Instance, _lastKeyEventTimestamp, args.Str)); - } - - protected override bool OnExposeEvent(EventExpose evnt) - { - Paint(evnt.Area.ToAvalonia()); - return true; - } - - protected override void OnFocusActivated() - { - Activated(); - } - - protected override bool OnMotionNotifyEvent(EventMotion evnt) - { - var position = new Point(evnt.X, evnt.Y); - - GtkMouseDevice.Instance.SetClientPosition(position); - - var e = new RawMouseEventArgs( - GtkMouseDevice.Instance, - evnt.Time, - _inputRoot, - RawMouseEventType.Move, - position, GetModifierKeys(evnt.State)); - Input(e); - return true; - } - - public void SetIcon(IWindowIconImpl icon) - { - Icon = ((IconImpl)icon).Pixbuf; - } - } -}