Browse Source

Merge branch 'master' into add_common_math_operators_to_vector

pull/2761/head
Josua Jäger 7 years ago
committed by GitHub
parent
commit
e87aa47234
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      native/Avalonia.Native/inc/avalonia-native.h
  2. 4
      native/Avalonia.Native/src/OSX/Avalonia.Native.OSX.xcodeproj/project.pbxproj
  3. 24
      native/Avalonia.Native/src/OSX/app.mm
  4. 4
      native/Avalonia.Native/src/OSX/common.h
  5. 14
      native/Avalonia.Native/src/OSX/main.mm
  6. 59
      native/Avalonia.Native/src/OSX/platformthreading.mm
  7. 15
      src/Avalonia.Controls/ControlExtensions.cs
  8. 2
      src/Avalonia.Controls/Presenters/ScrollContentPresenter.cs
  9. 2
      src/Avalonia.Controls/TopLevel.cs
  10. 23
      src/Avalonia.Controls/TreeViewItem.cs
  11. 2
      src/Avalonia.Input/IMouseDevice.cs
  12. 4
      src/Avalonia.Input/InputExtensions.cs
  13. 5
      src/Avalonia.Input/MouseDevice.cs
  14. 4
      src/Avalonia.Themes.Default/TreeViewItem.xaml
  15. 18
      tests/Avalonia.Controls.UnitTests/TopLevelTests.cs

2
native/Avalonia.Native/inc/avalonia-native.h

@ -280,7 +280,7 @@ AVNCOM(IAvnPlatformThreadingInterface, 0b) : IUnknown
virtual bool GetCurrentThreadIsLoopThread() = 0;
virtual void SetSignaledCallback(IAvnSignaledCallback* cb) = 0;
virtual IAvnLoopCancellation* CreateLoopCancellation() = 0;
virtual void RunLoop(IAvnLoopCancellation* cancel) = 0;
virtual HRESULT RunLoop(IAvnLoopCancellation* cancel) = 0;
// Can't pass int* to sharpgentools for some reason
virtual void Signal(int priority) = 0;
virtual IUnknown* StartTimer(int priority, int ms, IAvnActionCallback* callback) = 0;

4
native/Avalonia.Native/src/OSX/Avalonia.Native.OSX.xcodeproj/project.pbxproj

@ -7,6 +7,7 @@
objects = {
/* Begin PBXBuildFile section */
1A002B9E232135EE00021753 /* app.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1A002B9D232135EE00021753 /* app.mm */; };
37A517B32159597E00FBA241 /* Screens.mm in Sources */ = {isa = PBXBuildFile; fileRef = 37A517B22159597E00FBA241 /* Screens.mm */; };
37C09D8821580FE4006A6758 /* SystemDialogs.mm in Sources */ = {isa = PBXBuildFile; fileRef = 37C09D8721580FE4006A6758 /* SystemDialogs.mm */; };
37DDA9B0219330F8002E132B /* AvnString.mm in Sources */ = {isa = PBXBuildFile; fileRef = 37DDA9AF219330F8002E132B /* AvnString.mm */; };
@ -22,6 +23,7 @@
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
1A002B9D232135EE00021753 /* app.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = app.mm; sourceTree = "<group>"; };
379860FE214DA0C000CD0246 /* KeyTransform.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KeyTransform.h; sourceTree = "<group>"; };
37A4E71A2178846A00EACBCD /* headers */ = {isa = PBXFileReference; lastKnownFileType = folder; name = headers; path = ../../inc; sourceTree = "<group>"; };
37A517B22159597E00FBA241 /* Screens.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = Screens.mm; sourceTree = "<group>"; };
@ -68,6 +70,7 @@
AB7A61E62147C814003C5833 = {
isa = PBXGroup;
children = (
1A002B9D232135EE00021753 /* app.mm */,
37DDA9B121933371002E132B /* AvnString.h */,
37DDA9AF219330F8002E132B /* AvnString.mm */,
37A4E71A2178846A00EACBCD /* headers */,
@ -164,6 +167,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
1A002B9E232135EE00021753 /* app.mm in Sources */,
5B8BD94F215BFEA6005ED2A7 /* clipboard.mm in Sources */,
5B21A982216530F500CEE36E /* cursor.mm in Sources */,
37DDA9B0219330F8002E132B /* AvnString.mm in Sources */,

24
native/Avalonia.Native/src/OSX/app.mm

@ -0,0 +1,24 @@
#include "common.h"
@interface AvnAppDelegate : NSObject<NSApplicationDelegate>
@end
extern NSApplicationActivationPolicy AvnDesiredActivationPolicy = NSApplicationActivationPolicyRegular;
@implementation AvnAppDelegate
- (void)applicationWillFinishLaunching:(NSNotification *)notification
{
[[NSApplication sharedApplication] setActivationPolicy: AvnDesiredActivationPolicy];
}
- (void)applicationDidFinishLaunching:(NSNotification *)notification
{
[NSApp activateIgnoringOtherApps:true];
}
@end
extern void InitializeAvnApp()
{
NSApplication* app = [NSApplication sharedApplication];
id delegate = [AvnAppDelegate new];
[app setDelegate:delegate];
}

4
native/Avalonia.Native/src/OSX/common.h

@ -19,12 +19,12 @@ extern IAvnClipboard* CreateClipboard();
extern IAvnCursorFactory* CreateCursorFactory();
extern IAvnGlFeature* GetGlFeature();
extern IAvnGlSurfaceRenderTarget* CreateGlRenderTarget(NSWindow* window, NSView* view);
extern void InitializeAvnApp();
extern NSApplicationActivationPolicy AvnDesiredActivationPolicy;
extern NSPoint ToNSPoint (AvnPoint p);
extern AvnPoint ToAvnPoint (NSPoint p);
extern AvnPoint ConvertPointY (AvnPoint p);
extern NSSize ToNSSize (AvnSize s);
#ifdef DEBUG
#define NSDebugLog(...) NSLog(__VA_ARGS__)
#else

14
native/Avalonia.Native/src/OSX/main.mm

@ -5,21 +5,14 @@
#define COM_GUIDS_MATERIALIZE
#include "common.h"
static BOOL ShowInDock = 1;
static void SetActivationPolicy()
{
[[NSApplication sharedApplication] setActivationPolicy: (ShowInDock ? NSApplicationActivationPolicyRegular : NSApplicationActivationPolicyAccessory)];
}
class MacOptions : public ComSingleObject<IAvnMacOptions, &IID_IAvnMacOptions>
{
public:
FORWARD_IUNKNOWN()
virtual HRESULT SetShowInDock(int show) override
{
ShowInDock = show;
SetActivationPolicy();
AvnDesiredActivationPolicy = show
? NSApplicationActivationPolicyRegular : NSApplicationActivationPolicyAccessory;
return S_OK;
}
};
@ -64,8 +57,9 @@ public:
{
@autoreleasepool{
[[ThreadingInitializer new] do];
return S_OK;
}
InitializeAvnApp();
return S_OK;
};
virtual IAvnMacOptions* GetMacOptions() override

59
native/Avalonia.Native/src/OSX/platformthreading.mm

@ -57,16 +57,36 @@ class PlatformThreadingInterface : public ComSingleObject<IAvnPlatformThreadingI
{
private:
Signaler* _signaler;
bool _wasRunningAtLeastOnce = false;
class LoopCancellation : public ComSingleObject<IAvnLoopCancellation, &IID_IAvnLoopCancellation>
{
public:
FORWARD_IUNKNOWN()
bool Cancelled = 0;
virtual void Cancel() override
bool Running = false;
bool Cancelled = false;
virtual void Cancel()
{
Cancelled = 1;
Cancelled = true;
if(Running)
{
Running = false;
dispatch_async(dispatch_get_main_queue(), ^{
[[NSApplication sharedApplication] stop:nil];
NSEvent* event = [NSEvent otherEventWithType:NSEventTypeApplicationDefined
location:NSMakePoint(0, 0)
modifierFlags:0
timestamp:0
windowNumber:0
context:nil
subtype:0
data1:0
data2:0];
[NSApp postEvent:event atStart:YES];
});
}
}
};
public:
@ -99,30 +119,17 @@ public:
return new LoopCancellation();
}
virtual void RunLoop(IAvnLoopCancellation* cancel) override
virtual HRESULT RunLoop(IAvnLoopCancellation* cancel) override
{
@autoreleasepool {
auto can = dynamic_cast<LoopCancellation*>(cancel);
[[NSApplication sharedApplication] activateIgnoringOtherApps:true];
while(true)
{
@autoreleasepool
{
if(can != NULL && can->Cancelled)
return;
NSEvent* ev = [[NSApplication sharedApplication]
nextEventMatchingMask:NSEventMaskAny
untilDate: [NSDate dateWithTimeIntervalSinceNow:1]
inMode:NSDefaultRunLoopMode
dequeue:true];
if(can != NULL && can->Cancelled)
return;
if(ev != NULL)
[[NSApplication sharedApplication] sendEvent:ev];
}
}
NSDebugLog(@"RunLoop exited");
}
auto can = dynamic_cast<LoopCancellation*>(cancel);
if(can->Cancelled)
return S_OK;
if(_wasRunningAtLeastOnce)
return E_FAIL;
can->Running = true;
_wasRunningAtLeastOnce = true;
[NSApp run];
return S_OK;
}
virtual void Signal(int priority) override

15
src/Avalonia.Controls/ControlExtensions.cs

@ -34,14 +34,17 @@ namespace Avalonia.Controls
{
Contract.Requires<ArgumentNullException>(control != null);
var ev = new RequestBringIntoViewEventArgs
if (control.IsEffectivelyVisible)
{
RoutedEvent = Control.RequestBringIntoViewEvent,
TargetObject = control,
TargetRect = rect,
};
var ev = new RequestBringIntoViewEventArgs
{
RoutedEvent = Control.RequestBringIntoViewEvent,
TargetObject = control,
TargetRect = rect,
};
control.RaiseEvent(ev);
control.RaiseEvent(ev);
}
}
/// <summary>

2
src/Avalonia.Controls/Presenters/ScrollContentPresenter.cs

@ -141,7 +141,7 @@ namespace Avalonia.Controls.Presenters
/// <returns>True if the scroll offset was changed; otherwise false.</returns>
public bool BringDescendantIntoView(IVisual target, Rect targetRect)
{
if (Child == null)
if (Child?.IsEffectivelyVisible != true)
{
return false;
}

2
src/Avalonia.Controls/TopLevel.cs

@ -269,8 +269,8 @@ namespace Avalonia.Controls
/// </summary>
protected virtual void HandleClosed()
{
(this as IInputRoot).MouseDevice?.TopLevelClosed(this);
PlatformImpl = null;
Closed?.Invoke(this, EventArgs.Empty);
Renderer?.Dispose();
Renderer = null;

23
src/Avalonia.Controls/TreeViewItem.cs

@ -42,6 +42,7 @@ namespace Avalonia.Controls
new FuncTemplate<IPanel>(() => new StackPanel());
private TreeView _treeView;
private IControl _header;
private bool _isExpanded;
private int _level;
@ -53,6 +54,7 @@ namespace Avalonia.Controls
SelectableMixin.Attach<TreeViewItem>(IsSelectedProperty);
FocusableProperty.OverrideDefaultValue<TreeViewItem>(true);
ItemsPanelProperty.OverrideDefaultValue<TreeViewItem>(DefaultPanel);
RequestBringIntoViewEvent.AddClassHandler<TreeViewItem>(x => x.OnRequestBringIntoView);
}
/// <summary>
@ -120,6 +122,21 @@ namespace Avalonia.Controls
ItemContainerGenerator.Clear();
}
protected virtual void OnRequestBringIntoView(RequestBringIntoViewEventArgs e)
{
if (e.TargetObject == this && _header != null)
{
var m = _header.TransformToVisual(this);
if (m.HasValue)
{
var bounds = new Rect(_header.Bounds.Size);
var rect = bounds.TransformToAABB(m.Value);
e.TargetRect = rect;
}
}
}
/// <inheritdoc/>
protected override void OnKeyDown(KeyEventArgs e)
{
@ -146,6 +163,12 @@ namespace Avalonia.Controls
// Don't call base.OnKeyDown - let events bubble up to containing TreeView.
}
protected override void OnTemplateApplied(TemplateAppliedEventArgs e)
{
base.OnTemplateApplied(e);
_header = e.NameScope.Find<IControl>("PART_Header");
}
private static int CalculateDistanceFromLogicalParent<T>(ILogical logical, int @default = -1) where T : class
{
var result = 0;

2
src/Avalonia.Input/IMouseDevice.cs

@ -16,6 +16,8 @@ namespace Avalonia.Input
[Obsolete("Use PointerEventArgs.GetPosition")]
PixelPoint Position { get; }
void TopLevelClosed(IInputRoot root);
void SceneInvalidated(IInputRoot root, Rect rect);
}
}

4
src/Avalonia.Input/InputExtensions.cs

@ -13,6 +13,8 @@ namespace Avalonia.Input
/// </summary>
public static class InputExtensions
{
private static readonly Func<IVisual, bool> s_hitTestDelegate = IsHitTestVisible;
/// <summary>
/// Returns the active input elements at a point on an <see cref="IInputElement"/>.
/// </summary>
@ -25,7 +27,7 @@ namespace Avalonia.Input
{
Contract.Requires<ArgumentNullException>(element != null);
return element.GetVisualsAt(p, IsHitTestVisible).Cast<IInputElement>();
return element.GetVisualsAt(p, s_hitTestDelegate).Cast<IInputElement>();
}
/// <summary>

5
src/Avalonia.Input/MouseDevice.cs

@ -86,6 +86,11 @@ namespace Avalonia.Input
ProcessRawEvent(margs);
}
public void TopLevelClosed(IInputRoot root)
{
ClearPointerOver(this, 0, root, PointerPointProperties.None, KeyModifiers.None);
}
public void SceneInvalidated(IInputRoot root, Rect rect)
{
var clientPoint = root.PointToClient(Position);

4
src/Avalonia.Themes.Default/TreeViewItem.xaml

@ -16,7 +16,9 @@
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
TemplatedControl.IsTemplateFocusTarget="True">
<Grid ColumnDefinitions="16, *"
<Grid Name="PART_Header"
ColumnDefinitions="16, Auto"
HorizontalAlignment="Left"
Margin="{TemplateBinding Level, Mode=OneWay, Converter={StaticResource LeftMarginConverter}}" >
<ToggleButton Name="expander"
Focusable="False"

18
tests/Avalonia.Controls.UnitTests/TopLevelTests.cs

@ -224,6 +224,24 @@ namespace Avalonia.Controls.UnitTests
}
}
[Fact]
public void Close_Should_Notify_MouseDevice()
{
using (UnitTestApplication.Start(TestServices.StyledWindow))
{
var impl = new Mock<ITopLevelImpl>();
var mouseDevice = new Mock<IMouseDevice>();
impl.SetupAllProperties();
impl.Setup(x => x.MouseDevice).Returns(mouseDevice.Object);
var target = new TestTopLevel(impl.Object);
impl.Object.Closed();
mouseDevice.Verify(x => x.TopLevelClosed(target));
}
}
private FuncControlTemplate<TestTopLevel> CreateTemplate()
{
return new FuncControlTemplate<TestTopLevel>((x, scope) =>

Loading…
Cancel
Save