瀏覽代碼

Merge branch 'compiled-bindings' of https://github.com/jkoritzinsky/Avalonia into compiled-bindings

Jeremy Koritzinsky 6 年之前
父節點
當前提交
b44cce0bd7

+ 5 - 9
build/NetFX.props

@@ -1,11 +1,7 @@
-<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <PropertyGroup Condition=" '$(TargetFramework)' == 'net461' and '$(OS)' == 'Unix' ">
-    <FrameworkPathOverride>/usr/lib/mono/4.6.1-api</FrameworkPathOverride>
-    <FrameworkPathOverride Condition="$([MSBuild]::IsOsPlatform('OSX'))">/Library/Frameworks/Mono.framework/Versions/Current/lib/mono/4.6.1-api</FrameworkPathOverride>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(TargetFramework)' == 'net47' and '$(OS)' == 'Unix' ">
-    <FrameworkPathOverride>/usr/lib/mono/4.7-api/</FrameworkPathOverride>
-    <FrameworkPathOverride Condition="$([MSBuild]::IsOsPlatform('OSX'))">/Library/Frameworks/Mono.framework/Versions/Current/lib/mono/4.7-api</FrameworkPathOverride>
-  </PropertyGroup>
+<Project>
+
+  <ItemGroup>
+    <PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.0-preview.2" PrivateAssets="All" />
+  </ItemGroup>
 
 </Project>

+ 7 - 5
samples/ControlCatalog/MainView.xaml

@@ -24,7 +24,6 @@
       <TabItem Header="CheckBox"><pages:CheckBoxPage/></TabItem>
       <TabItem Header="ComboBox"><pages:ComboBoxPage/></TabItem>
       <TabItem Header="ContextMenu"><pages:ContextMenuPage/></TabItem>
-      <!-- DataGrid is our special snowflake -->  
       <TabItem Header="DataGrid" 
                ScrollViewer.VerticalScrollBarVisibility="Disabled"
                ScrollViewer.HorizontalScrollBarVisibility="Disabled">
@@ -34,12 +33,15 @@
       <TabItem Header="Drag+Drop"><pages:DragAndDropPage/></TabItem>
       <TabItem Header="Expander"><pages:ExpanderPage/></TabItem>
       <TabItem Header="Image"><pages:ImagePage/></TabItem>
-      <TabItem Header="ItemsRepeater"><pages:ItemsRepeaterPage/></TabItem>
+      <TabItem Header="ItemsRepeater"
+               ScrollViewer.VerticalScrollBarVisibility="Disabled">
+        <pages:ItemsRepeaterPage/>
+      </TabItem>
       <TabItem Header="LayoutTransformControl"><pages:LayoutTransformControlPage/></TabItem>
       <TabItem Header="ListBox"><pages:ListBoxPage/></TabItem>
       <TabItem Header="Menu"><pages:MenuPage/></TabItem>
       <TabItem Header="Notifications"><pages:NotificationsPage/></TabItem>
-	  <TabItem Header="NumericUpDown"><pages:NumericUpDownPage/></TabItem>
+	    <TabItem Header="NumericUpDown"><pages:NumericUpDownPage/></TabItem>
       <TabItem Header="Pointers (Touch)"><pages:PointersPage/></TabItem>
       <TabItem Header="ProgressBar"><pages:ProgressBarPage/></TabItem>
       <TabItem Header="RadioButton"><pages:RadioButtonPage/></TabItem>
@@ -50,12 +52,12 @@
       <TabItem Header="ToolTip"><pages:ToolTipPage/></TabItem>
       <TabItem Header="TreeView"><pages:TreeViewPage/></TabItem>
       <TabItem Header="Viewbox"><pages:ViewboxPage/></TabItem>
-    <TabControl.Tag>
+      <TabControl.Tag>
         <ComboBox x:Name="Themes" SelectedIndex="0" Width="100" Margin="8" HorizontalAlignment="Right" VerticalAlignment="Bottom">
             <ComboBoxItem>Light</ComboBoxItem>
             <ComboBoxItem>Dark</ComboBoxItem>
         </ComboBox>
-    </TabControl.Tag>
+      </TabControl.Tag>
     </TabControl>
   </Grid>
 </UserControl>

+ 1 - 2
src/Avalonia.Base/Utilities/WeakEventHandlerManager.cs

@@ -161,9 +161,8 @@ namespace Avalonia.Utilities
                 for (int c = 0; c < _count; ++c)
                 {
                     var reference = _data[c].Subscriber;
-                    TSubscriber instance;
 
-                    if (reference != null && reference.TryGetTarget(out instance) && instance == s)
+                    if (reference != null && reference.TryGetTarget(out TSubscriber instance) && Equals(instance, s.Target))
                     {
                         _data[c] = default;
                         removed = true;

+ 6 - 0
src/Avalonia.Controls/Primitives/PopupPositioning/ManagedPopupPositioner.cs

@@ -100,6 +100,12 @@ namespace Avalonia.Controls.Primitives.PopupPositioning
                                    ?? screens.FirstOrDefault(s => s.Bounds.Contains(parentGeometry.TopLeft))
                                    ?? screens.FirstOrDefault(s => s.Bounds.Intersects(parentGeometry))
                                    ?? screens.FirstOrDefault();
+
+                if (targetScreen != null && targetScreen.WorkingArea.IsEmpty)
+                {
+                    return targetScreen.Bounds;
+                }
+                
                 return targetScreen?.WorkingArea
                        ?? new Rect(0, 0, double.MaxValue, double.MaxValue);
             }

+ 72 - 57
src/Avalonia.Input/KeyGesture.cs

@@ -1,41 +1,56 @@
+// 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.Collections.Generic;
 using System.Linq;
 
 namespace Avalonia.Input
 {
+    /// <summary>
+    /// Defines a keyboard input combination.
+    /// </summary>
     public sealed class KeyGesture : IEquatable<KeyGesture>
     {
-        public KeyGesture()
+        private static readonly Dictionary<string, Key> s_keySynonyms = new Dictionary<string, Key>
+        {
+            { "+", Key.OemPlus }, { "-", Key.OemMinus }, { ".", Key.OemPeriod }
+        };
+
+        [Obsolete("Use constructor taking KeyModifiers")]
+        public KeyGesture(Key key, InputModifiers modifiers)
         {
-            
+            Key = key;
+            KeyModifiers = (KeyModifiers)(((int)modifiers) & 0xf);
         }
 
-        public KeyGesture(Key key, InputModifiers modifiers = InputModifiers.None)
+        public KeyGesture(Key key, KeyModifiers modifiers = KeyModifiers.None)
         {
             Key = key;
-            Modifiers = modifiers;
+            KeyModifiers = modifiers;
         }
-        
+
         public bool Equals(KeyGesture other)
         {
             if (ReferenceEquals(null, other)) return false;
             if (ReferenceEquals(this, other)) return true;
-            return Key == other.Key && Modifiers == other.Modifiers;
+
+            return Key == other.Key && KeyModifiers == other.KeyModifiers;
         }
 
         public override bool Equals(object obj)
         {
             if (ReferenceEquals(null, obj)) return false;
             if (ReferenceEquals(this, obj)) return true;
-            return obj is KeyGesture && Equals((KeyGesture) obj);
+
+            return obj is KeyGesture && Equals((KeyGesture)obj);
         }
 
         public override int GetHashCode()
         {
             unchecked
             {
-                return ((int) Key*397) ^ (int) Modifiers;
+                return ((int)Key * 397) ^ (int)KeyModifiers;
             }
         }
 
@@ -49,85 +64,85 @@ namespace Avalonia.Input
             return !Equals(left, right);
         }
 
-        public Key Key { get; set; }
+        public Key Key { get; }
 
         [Obsolete("Use KeyModifiers")]
-        public InputModifiers Modifiers
-        {
-            get => (InputModifiers)KeyModifiers;
-            set => KeyModifiers = (KeyModifiers)(((int)value) & 0xf);
-        }
-        
-        public KeyModifiers KeyModifiers { get; set; }
+        public InputModifiers Modifiers => (InputModifiers)KeyModifiers;
 
-        
-        static readonly Dictionary<string, Key> KeySynonyms = new Dictionary<string, Key>
-        {
-            {"+", Key.OemPlus },
-            {"-", Key.OemMinus},
-            {".", Key.OemPeriod }
-        };
-
-        //TODO: Move that to external key parser
-        static Key ParseKey(string key)
-        {
-            Key rv;
-            if (KeySynonyms.TryGetValue(key.ToLower(), out rv))
-                return rv;
-            return (Key)Enum.Parse(typeof (Key), key, true);
-        }
-
-        static InputModifiers ParseModifier(string modifier)
-        {
-            if (modifier.Equals("ctrl", StringComparison.OrdinalIgnoreCase))
-                return InputModifiers.Control;
-            return (InputModifiers) Enum.Parse(typeof (InputModifiers), modifier, true);
-        }
+        public KeyModifiers KeyModifiers { get; }
 
         public static KeyGesture Parse(string gesture)
         {
-            //string.Split can't be used here because "Ctrl++" is a perfectly valid key gesture
+            // string.Split can't be used here because "Ctrl++" is a perfectly valid key gesture
 
-            var parts = new List<string>();
+            var key = Key.None;
+            var keyModifiers = KeyModifiers.None;
 
             var cstart = 0;
+
             for (var c = 0; c <= gesture.Length; c++)
             {
                 var ch = c == gesture.Length ? '\0' : gesture[c];
-                if (c == gesture.Length || (ch == '+' && cstart != c))
+                bool isLast = c == gesture.Length;
+
+                if (isLast || (ch == '+' && cstart != c))
                 {
-                    parts.Add(gesture.Substring(cstart, c - cstart));
+                    var partSpan = gesture.AsSpan(cstart, c - cstart).Trim();
+
+                    if (isLast)
+                    {
+                        key = ParseKey(partSpan.ToString());
+                    }
+                    else
+                    {
+                        keyModifiers |= ParseModifier(partSpan);
+                    }
+
                     cstart = c + 1;
                 }
             }
-            for (var c = 0; c < parts.Count; c++)
-                parts[c] = parts[c].Trim();
 
-            var rv = new KeyGesture();
 
-            for (var c = 0; c < parts.Count; c++)
-            {
-                if (c == parts.Count - 1)
-                    rv.Key = ParseKey(parts[c]);
-                else
-                    rv.Modifiers |= ParseModifier(parts[c]);
-            }
-            return rv;
+            return new KeyGesture(key, keyModifiers);
         }
 
         public override string ToString()
         {
             var parts = new List<string>();
-            foreach (var flag in Enum.GetValues(typeof (InputModifiers)).Cast<InputModifiers>())
+
+            foreach (var flag in Enum.GetValues(typeof(KeyModifiers)).Cast<KeyModifiers>())
             {
-                if (Modifiers.HasFlag(flag) && flag != InputModifiers.None)
+                if (KeyModifiers.HasFlag(flag) && flag != KeyModifiers.None)
+                {
                     parts.Add(flag.ToString());
+                }
             }
+
             parts.Add(Key.ToString());
+
             return string.Join(" + ", parts);
         }
 
-        public bool Matches(KeyEventArgs keyEvent) => ResolveNumPadOperationKey(keyEvent.Key) == Key && keyEvent.Modifiers == Modifiers;
+        public bool Matches(KeyEventArgs keyEvent) => ResolveNumPadOperationKey(keyEvent.Key) == Key && keyEvent.KeyModifiers == KeyModifiers;
+
+        // TODO: Move that to external key parser
+        private static Key ParseKey(string key)
+        {
+            if (s_keySynonyms.TryGetValue(key.ToLower(), out Key rv))
+                return rv;
+
+            return (Key)Enum.Parse(typeof(Key), key, true);
+        }
+
+        private static KeyModifiers ParseModifier(ReadOnlySpan<char> modifier)
+        {
+            if (modifier.Equals("ctrl".AsSpan(), StringComparison.OrdinalIgnoreCase))
+            {
+                return KeyModifiers.Control;
+            }
+
+            return (KeyModifiers)Enum.Parse(typeof(KeyModifiers), modifier.ToString(), true);
+        }
 
         private Key ResolveNumPadOperationKey(Key key)
         {

+ 2 - 2
src/Avalonia.X11/X11KeyTransform.cs

@@ -104,8 +104,8 @@ namespace Avalonia.X11
             {X11Key.x, Key.X},
             {X11Key.y, Key.Y},
             {X11Key.z, Key.Z},
-            {X11Key.Meta_L, Key.LWin },
-            {X11Key.Meta_R, Key.RWin },
+            {X11Key.Super_L, Key.LWin },
+            {X11Key.Super_R, Key.RWin },
             {X11Key.Menu, Key.Apps},
             //{ X11Key.?, Key.Sleep }
             {X11Key.KP_0, Key.NumPad0},

+ 3 - 1
src/Windows/Avalonia.Win32/WindowsMountedVolumeInfoListener.cs

@@ -32,9 +32,11 @@ namespace Avalonia.Win32
             var allDrives = DriveInfo.GetDrives();
 
             var mountVolInfos = allDrives
+                                .Where(p => p.IsReady)
                                 .Select(p => new MountedVolumeInfo()
                                 {
-                                    VolumeLabel = p.VolumeLabel,
+                                    VolumeLabel = string.IsNullOrEmpty(p.VolumeLabel.Trim()) ? p.RootDirectory.FullName 
+                                                                                             : $"{p.VolumeLabel} ({p.Name})",
                                     VolumePath = p.RootDirectory.FullName,
                                     VolumeSizeBytes = (ulong)p.TotalSize
                                 })

+ 18 - 2
tests/Avalonia.Base.UnitTests/WeakEventHandlerManagerTests.cs

@@ -36,7 +36,7 @@ namespace Avalonia.Base.UnitTests
         }
 
         [Fact]
-        public void EventShoudBePassedToSubscriber()
+        public void EventShouldBePassedToSubscriber()
         {
             bool handled = false;
             var subscriber = new Subscriber(() => handled = true);
@@ -47,7 +47,23 @@ namespace Avalonia.Base.UnitTests
             Assert.True(handled);
         }
 
- 
+        [Fact]
+        public void EventShouldNotBeRaisedAfterUnsubscribe()
+        {
+            bool handled = false;
+            var subscriber = new Subscriber(() => handled = true);
+            var source = new EventSource();
+            WeakEventHandlerManager.Subscribe<EventSource, EventArgs, Subscriber>(source, "Event",
+                subscriber.OnEvent);
+
+            WeakEventHandlerManager.Unsubscribe<EventArgs, Subscriber>(source, "Event",
+                subscriber.OnEvent);
+
+            source.Fire();
+
+            Assert.False(handled);
+        }
+
         [Fact]
         public void EventHandlerShouldNotBeKeptAlive()
         {

+ 2 - 2
tests/Avalonia.Controls.UnitTests/Utils/HotKeyManagerTests.cs

@@ -24,8 +24,8 @@ namespace Avalonia.Controls.UnitTests.Utils
                     .Bind<IWindowingPlatform>().ToConstant(new WindowingPlatformMock())
                     .Bind<IStyler>().ToConstant(styler.Object);
 
-                var gesture1 = new KeyGesture {Key = Key.A, Modifiers = InputModifiers.Control};
-                var gesture2 = new KeyGesture {Key = Key.B, Modifiers = InputModifiers.Control};
+                var gesture1 = new KeyGesture(Key.A, InputModifiers.Control);
+                var gesture2 = new KeyGesture(Key.B, InputModifiers.Control);
 
                 var tl = new Window();
                 var button = new Button();

+ 6 - 14
tests/Avalonia.Input.UnitTests/KeyGestureTests.cs

@@ -1,8 +1,4 @@
-using System;
 using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
 using Xunit;
 
 namespace Avalonia.Input.UnitTests
@@ -11,13 +7,11 @@ namespace Avalonia.Input.UnitTests
     {
         public static readonly IEnumerable<object[]> SampleData = new object[][]
         {
-            new object[]{"Ctrl+A", new KeyGesture {Key = Key.A, Modifiers = InputModifiers.Control}},
-            new object[]{"  \tShift\t+Alt +B", new KeyGesture {Key = Key.B, Modifiers = InputModifiers.Shift|InputModifiers.Alt} },
-            new object[]{"Control++", new KeyGesture {Key = Key.OemPlus, Modifiers = InputModifiers.Control} }
+            new object[]{"Ctrl+A", new KeyGesture(Key.A, InputModifiers.Control)},
+            new object[]{"  \tShift\t+Alt +B", new KeyGesture(Key.B, InputModifiers.Shift | InputModifiers.Alt) },
+            new object[]{"Control++", new KeyGesture(Key.OemPlus, InputModifiers.Control) }
         };
-            
-            
-            
+
         [Theory]
         [MemberData(nameof(SampleData))]
         public void Key_Gesture_Is_Able_To_Parse_Sample_Data(string text, KeyGesture gesture)
@@ -31,10 +25,8 @@ namespace Avalonia.Input.UnitTests
         [InlineData(Key.OemPeriod, Key.Decimal)]
         public void Key_Gesture_Matches_NumPad_To_Regular_Digit(Key gestureKey, Key pressedKey)
         {
-            var keyGesture = new KeyGesture
-            {
-                Key = gestureKey
-            };
+            var keyGesture = new KeyGesture(gestureKey);
+
             Assert.True(keyGesture.Matches(new KeyEventArgs
             {
                 Key = pressedKey