committed by
GitHub
15 changed files with 888 additions and 824 deletions
@ -0,0 +1,15 @@ |
|||||
|
//
|
||||
|
// Created by Dan Walmsley on 05/05/2022.
|
||||
|
// Copyright (c) 2022 Avalonia. All rights reserved.
|
||||
|
//
|
||||
|
|
||||
|
#import <Foundation/Foundation.h> |
||||
|
#import "avalonia-native.h" |
||||
|
|
||||
|
@interface AutoFitContentView : NSView |
||||
|
-(AutoFitContentView* _Nonnull) initWithContent: (NSView* _Nonnull) content; |
||||
|
-(void) ShowTitleBar: (bool) show; |
||||
|
-(void) SetTitleBarHeightHint: (double) height; |
||||
|
|
||||
|
-(void) ShowBlur: (bool) show; |
||||
|
@end |
||||
@ -0,0 +1,104 @@ |
|||||
|
// |
||||
|
// Created by Dan Walmsley on 05/05/2022. |
||||
|
// Copyright (c) 2022 Avalonia. All rights reserved. |
||||
|
// |
||||
|
|
||||
|
#include "AvnView.h" |
||||
|
#import "AutoFitContentView.h" |
||||
|
|
||||
|
@implementation AutoFitContentView |
||||
|
{ |
||||
|
NSVisualEffectView* _titleBarMaterial; |
||||
|
NSBox* _titleBarUnderline; |
||||
|
NSView* _content; |
||||
|
NSVisualEffectView* _blurBehind; |
||||
|
double _titleBarHeightHint; |
||||
|
bool _settingSize; |
||||
|
} |
||||
|
|
||||
|
-(AutoFitContentView* _Nonnull) initWithContent:(NSView *)content |
||||
|
{ |
||||
|
_titleBarHeightHint = -1; |
||||
|
_content = content; |
||||
|
_settingSize = false; |
||||
|
|
||||
|
[self setAutoresizesSubviews:true]; |
||||
|
[self setWantsLayer:true]; |
||||
|
|
||||
|
_titleBarMaterial = [NSVisualEffectView new]; |
||||
|
[_titleBarMaterial setBlendingMode:NSVisualEffectBlendingModeWithinWindow]; |
||||
|
[_titleBarMaterial setMaterial:NSVisualEffectMaterialTitlebar]; |
||||
|
[_titleBarMaterial setWantsLayer:true]; |
||||
|
_titleBarMaterial.hidden = true; |
||||
|
|
||||
|
_titleBarUnderline = [NSBox new]; |
||||
|
_titleBarUnderline.boxType = NSBoxSeparator; |
||||
|
_titleBarUnderline.fillColor = [NSColor underPageBackgroundColor]; |
||||
|
_titleBarUnderline.hidden = true; |
||||
|
|
||||
|
[self addSubview:_titleBarMaterial]; |
||||
|
[self addSubview:_titleBarUnderline]; |
||||
|
|
||||
|
_blurBehind = [NSVisualEffectView new]; |
||||
|
[_blurBehind setBlendingMode:NSVisualEffectBlendingModeBehindWindow]; |
||||
|
[_blurBehind setMaterial:NSVisualEffectMaterialLight]; |
||||
|
[_blurBehind setWantsLayer:true]; |
||||
|
_blurBehind.hidden = true; |
||||
|
|
||||
|
[_blurBehind setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; |
||||
|
[_content setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; |
||||
|
|
||||
|
[self addSubview:_blurBehind]; |
||||
|
[self addSubview:_content]; |
||||
|
|
||||
|
[self setWantsLayer:true]; |
||||
|
return self; |
||||
|
} |
||||
|
|
||||
|
-(void) ShowBlur:(bool)show |
||||
|
{ |
||||
|
_blurBehind.hidden = !show; |
||||
|
} |
||||
|
|
||||
|
-(void) ShowTitleBar: (bool) show |
||||
|
{ |
||||
|
_titleBarMaterial.hidden = !show; |
||||
|
_titleBarUnderline.hidden = !show; |
||||
|
} |
||||
|
|
||||
|
-(void) SetTitleBarHeightHint: (double) height |
||||
|
{ |
||||
|
_titleBarHeightHint = height; |
||||
|
|
||||
|
[self setFrameSize:self.frame.size]; |
||||
|
} |
||||
|
|
||||
|
-(void)setFrameSize:(NSSize)newSize |
||||
|
{ |
||||
|
if(_settingSize) |
||||
|
{ |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
_settingSize = true; |
||||
|
[super setFrameSize:newSize]; |
||||
|
|
||||
|
auto window = objc_cast<AvnWindow>([self window]); |
||||
|
|
||||
|
// TODO get actual titlebar size |
||||
|
|
||||
|
double height = _titleBarHeightHint == -1 ? [window getExtendedTitleBarHeight] : _titleBarHeightHint; |
||||
|
|
||||
|
NSRect tbar; |
||||
|
tbar.origin.x = 0; |
||||
|
tbar.origin.y = newSize.height - height; |
||||
|
tbar.size.width = newSize.width; |
||||
|
tbar.size.height = height; |
||||
|
|
||||
|
[_titleBarMaterial setFrame:tbar]; |
||||
|
tbar.size.height = height < 1 ? 0 : 1; |
||||
|
[_titleBarUnderline setFrame:tbar]; |
||||
|
|
||||
|
_settingSize = false; |
||||
|
} |
||||
|
@end |
||||
@ -0,0 +1,29 @@ |
|||||
|
//
|
||||
|
// Created by Dan Walmsley on 05/05/2022.
|
||||
|
// Copyright (c) 2022 Avalonia. All rights reserved.
|
||||
|
//
|
||||
|
|
||||
|
#import <Foundation/Foundation.h> |
||||
|
|
||||
|
|
||||
|
#import <Foundation/Foundation.h> |
||||
|
#import <AppKit/AppKit.h> |
||||
|
#include "window.h" |
||||
|
#import "comimpl.h" |
||||
|
#import "common.h" |
||||
|
#import "WindowImpl.h" |
||||
|
#import "KeyTransform.h" |
||||
|
|
||||
|
@class AvnAccessibilityElement; |
||||
|
|
||||
|
@interface AvnView : NSView<NSTextInputClient, NSDraggingDestination> |
||||
|
-(AvnView* _Nonnull) initWithParent: (WindowBaseImpl* _Nonnull) parent; |
||||
|
-(NSEvent* _Nonnull) lastMouseDownEvent; |
||||
|
-(AvnPoint) translateLocalPoint:(AvnPoint)pt; |
||||
|
-(void) setSwRenderedFrame: (AvnFramebuffer* _Nonnull) fb dispose: (IUnknown* _Nonnull) dispose; |
||||
|
-(void) onClosed; |
||||
|
|
||||
|
-(AvnPlatformResizeReason) getResizeReason; |
||||
|
-(void) setResizeReason:(AvnPlatformResizeReason)reason; |
||||
|
+ (AvnPoint)toAvnPoint:(CGPoint)p; |
||||
|
@end |
||||
@ -0,0 +1,706 @@ |
|||||
|
// |
||||
|
// Created by Dan Walmsley on 05/05/2022. |
||||
|
// Copyright (c) 2022 Avalonia. All rights reserved. |
||||
|
// |
||||
|
|
||||
|
#import <AppKit/AppKit.h> |
||||
|
#import "AvnView.h" |
||||
|
#include "automation.h" |
||||
|
|
||||
|
@implementation AvnView |
||||
|
{ |
||||
|
ComPtr<WindowBaseImpl> _parent; |
||||
|
NSTrackingArea* _area; |
||||
|
bool _isLeftPressed, _isMiddlePressed, _isRightPressed, _isXButton1Pressed, _isXButton2Pressed; |
||||
|
AvnInputModifiers _modifierState; |
||||
|
NSEvent* _lastMouseDownEvent; |
||||
|
bool _lastKeyHandled; |
||||
|
AvnPixelSize _lastPixelSize; |
||||
|
NSObject<IRenderTarget>* _renderTarget; |
||||
|
AvnPlatformResizeReason _resizeReason; |
||||
|
AvnAccessibilityElement* _accessibilityChild; |
||||
|
} |
||||
|
|
||||
|
- (void)onClosed |
||||
|
{ |
||||
|
@synchronized (self) |
||||
|
{ |
||||
|
_parent = nullptr; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
- (NSEvent*) lastMouseDownEvent |
||||
|
{ |
||||
|
return _lastMouseDownEvent; |
||||
|
} |
||||
|
|
||||
|
- (void) updateRenderTarget |
||||
|
{ |
||||
|
[_renderTarget resize:_lastPixelSize withScale:static_cast<float>([[self window] backingScaleFactor])]; |
||||
|
[self setNeedsDisplayInRect:[self frame]]; |
||||
|
} |
||||
|
|
||||
|
-(AvnView*) initWithParent: (WindowBaseImpl*) parent |
||||
|
{ |
||||
|
self = [super init]; |
||||
|
_renderTarget = parent->renderTarget; |
||||
|
[self setWantsLayer:YES]; |
||||
|
[self setLayerContentsRedrawPolicy: NSViewLayerContentsRedrawDuringViewResize]; |
||||
|
|
||||
|
_parent = parent; |
||||
|
_area = nullptr; |
||||
|
_lastPixelSize.Height = 100; |
||||
|
_lastPixelSize.Width = 100; |
||||
|
[self registerForDraggedTypes: @[@"public.data", GetAvnCustomDataType()]]; |
||||
|
|
||||
|
_modifierState = AvnInputModifiersNone; |
||||
|
return self; |
||||
|
} |
||||
|
|
||||
|
- (BOOL)isFlipped |
||||
|
{ |
||||
|
return YES; |
||||
|
} |
||||
|
|
||||
|
- (BOOL)wantsUpdateLayer |
||||
|
{ |
||||
|
return YES; |
||||
|
} |
||||
|
|
||||
|
- (void)setLayer:(CALayer *)layer |
||||
|
{ |
||||
|
[_renderTarget setNewLayer: layer]; |
||||
|
[super setLayer: layer]; |
||||
|
} |
||||
|
|
||||
|
- (BOOL)isOpaque |
||||
|
{ |
||||
|
return YES; |
||||
|
} |
||||
|
|
||||
|
- (BOOL)acceptsFirstResponder |
||||
|
{ |
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
- (BOOL)acceptsFirstMouse:(NSEvent *)event |
||||
|
{ |
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
- (BOOL)canBecomeKeyView |
||||
|
{ |
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
-(void)setFrameSize:(NSSize)newSize |
||||
|
{ |
||||
|
[super setFrameSize:newSize]; |
||||
|
|
||||
|
if(_area != nullptr) |
||||
|
{ |
||||
|
[self removeTrackingArea:_area]; |
||||
|
_area = nullptr; |
||||
|
} |
||||
|
|
||||
|
if (_parent == nullptr) |
||||
|
{ |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
NSRect rect = NSZeroRect; |
||||
|
rect.size = newSize; |
||||
|
|
||||
|
NSTrackingAreaOptions options = NSTrackingActiveAlways | NSTrackingMouseMoved | NSTrackingMouseEnteredAndExited | NSTrackingEnabledDuringMouseDrag; |
||||
|
_area = [[NSTrackingArea alloc] initWithRect:rect options:options owner:self userInfo:nullptr]; |
||||
|
[self addTrackingArea:_area]; |
||||
|
|
||||
|
_parent->UpdateCursor(); |
||||
|
|
||||
|
auto fsize = [self convertSizeToBacking: [self frame].size]; |
||||
|
|
||||
|
if(_lastPixelSize.Width != (int)fsize.width || _lastPixelSize.Height != (int)fsize.height) |
||||
|
{ |
||||
|
_lastPixelSize.Width = (int)fsize.width; |
||||
|
_lastPixelSize.Height = (int)fsize.height; |
||||
|
[self updateRenderTarget]; |
||||
|
|
||||
|
auto reason = [self inLiveResize] ? ResizeUser : _resizeReason; |
||||
|
_parent->BaseEvents->Resized(AvnSize{newSize.width, newSize.height}, reason); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
- (void)updateLayer |
||||
|
{ |
||||
|
AvnInsidePotentialDeadlock deadlock; |
||||
|
if (_parent == nullptr) |
||||
|
{ |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
_parent->BaseEvents->RunRenderPriorityJobs(); |
||||
|
|
||||
|
if (_parent == nullptr) |
||||
|
{ |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
_parent->BaseEvents->Paint(); |
||||
|
} |
||||
|
|
||||
|
- (void)drawRect:(NSRect)dirtyRect |
||||
|
{ |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
-(void) setSwRenderedFrame: (AvnFramebuffer*) fb dispose: (IUnknown*) dispose |
||||
|
{ |
||||
|
@autoreleasepool { |
||||
|
[_renderTarget setSwFrame:fb]; |
||||
|
dispose->Release(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
- (AvnPoint) translateLocalPoint:(AvnPoint)pt |
||||
|
{ |
||||
|
pt.Y = [self bounds].size.height - pt.Y; |
||||
|
return pt; |
||||
|
} |
||||
|
|
||||
|
+ (AvnPoint)toAvnPoint:(CGPoint)p |
||||
|
{ |
||||
|
AvnPoint result; |
||||
|
|
||||
|
result.X = p.x; |
||||
|
result.Y = p.y; |
||||
|
|
||||
|
return result; |
||||
|
} |
||||
|
|
||||
|
- (void) viewDidChangeBackingProperties |
||||
|
{ |
||||
|
auto fsize = [self convertSizeToBacking: [self frame].size]; |
||||
|
_lastPixelSize.Width = (int)fsize.width; |
||||
|
_lastPixelSize.Height = (int)fsize.height; |
||||
|
[self updateRenderTarget]; |
||||
|
|
||||
|
if(_parent != nullptr) |
||||
|
{ |
||||
|
_parent->BaseEvents->ScalingChanged([_parent->Window backingScaleFactor]); |
||||
|
} |
||||
|
|
||||
|
[super viewDidChangeBackingProperties]; |
||||
|
} |
||||
|
|
||||
|
- (bool) ignoreUserInput:(bool)trigerInputWhenDisabled |
||||
|
{ |
||||
|
auto parentWindow = objc_cast<AvnWindow>([self window]); |
||||
|
|
||||
|
if(parentWindow == nil || ![parentWindow shouldTryToHandleEvents]) |
||||
|
{ |
||||
|
if(trigerInputWhenDisabled) |
||||
|
{ |
||||
|
auto window = dynamic_cast<WindowImpl*>(_parent.getRaw()); |
||||
|
|
||||
|
if(window != nullptr) |
||||
|
{ |
||||
|
window->WindowEvents->GotInputWhenDisabled(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return TRUE; |
||||
|
} |
||||
|
|
||||
|
return FALSE; |
||||
|
} |
||||
|
|
||||
|
- (void)mouseEvent:(NSEvent *)event withType:(AvnRawMouseEventType) type |
||||
|
{ |
||||
|
bool triggerInputWhenDisabled = type != Move; |
||||
|
|
||||
|
if([self ignoreUserInput: triggerInputWhenDisabled]) |
||||
|
{ |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
auto localPoint = [self convertPoint:[event locationInWindow] toView:self]; |
||||
|
auto avnPoint = [AvnView toAvnPoint:localPoint]; |
||||
|
auto point = [self translateLocalPoint:avnPoint]; |
||||
|
AvnVector delta = { 0, 0}; |
||||
|
|
||||
|
if(type == Wheel) |
||||
|
{ |
||||
|
auto speed = 5; |
||||
|
|
||||
|
if([event hasPreciseScrollingDeltas]) |
||||
|
{ |
||||
|
speed = 50; |
||||
|
} |
||||
|
|
||||
|
delta.X = [event scrollingDeltaX] / speed; |
||||
|
delta.Y = [event scrollingDeltaY] / speed; |
||||
|
|
||||
|
if(delta.X == 0 && delta.Y == 0) |
||||
|
{ |
||||
|
return; |
||||
|
} |
||||
|
} |
||||
|
else if (type == Magnify) |
||||
|
{ |
||||
|
delta.X = delta.Y = [event magnification]; |
||||
|
} |
||||
|
else if (type == Rotate) |
||||
|
{ |
||||
|
delta.X = delta.Y = [event rotation]; |
||||
|
} |
||||
|
else if (type == Swipe) |
||||
|
{ |
||||
|
delta.X = [event deltaX]; |
||||
|
delta.Y = [event deltaY]; |
||||
|
} |
||||
|
|
||||
|
uint32 timestamp = static_cast<uint32>([event timestamp] * 1000); |
||||
|
auto modifiers = [self getModifiers:[event modifierFlags]]; |
||||
|
|
||||
|
if(type != Move || |
||||
|
( |
||||
|
[self window] != nil && |
||||
|
( |
||||
|
[[self window] firstResponder] == nil |
||||
|
|| ![[[self window] firstResponder] isKindOfClass: [NSView class]] |
||||
|
) |
||||
|
) |
||||
|
) |
||||
|
[self becomeFirstResponder]; |
||||
|
|
||||
|
if(_parent != nullptr) |
||||
|
{ |
||||
|
_parent->BaseEvents->RawMouseEvent(type, timestamp, modifiers, point, delta); |
||||
|
} |
||||
|
|
||||
|
[super mouseMoved:event]; |
||||
|
} |
||||
|
|
||||
|
- (BOOL) resignFirstResponder |
||||
|
{ |
||||
|
_parent->BaseEvents->LostFocus(); |
||||
|
return YES; |
||||
|
} |
||||
|
|
||||
|
- (void)mouseMoved:(NSEvent *)event |
||||
|
{ |
||||
|
[self mouseEvent:event withType:Move]; |
||||
|
} |
||||
|
|
||||
|
- (void)mouseDown:(NSEvent *)event |
||||
|
{ |
||||
|
_isLeftPressed = true; |
||||
|
_lastMouseDownEvent = event; |
||||
|
[self mouseEvent:event withType:LeftButtonDown]; |
||||
|
} |
||||
|
|
||||
|
- (void)otherMouseDown:(NSEvent *)event |
||||
|
{ |
||||
|
_lastMouseDownEvent = event; |
||||
|
|
||||
|
switch(event.buttonNumber) |
||||
|
{ |
||||
|
case 2: |
||||
|
case 3: |
||||
|
_isMiddlePressed = true; |
||||
|
[self mouseEvent:event withType:MiddleButtonDown]; |
||||
|
break; |
||||
|
case 4: |
||||
|
_isXButton1Pressed = true; |
||||
|
[self mouseEvent:event withType:XButton1Down]; |
||||
|
break; |
||||
|
case 5: |
||||
|
_isXButton2Pressed = true; |
||||
|
[self mouseEvent:event withType:XButton2Down]; |
||||
|
break; |
||||
|
|
||||
|
default: |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
- (void)rightMouseDown:(NSEvent *)event |
||||
|
{ |
||||
|
_isRightPressed = true; |
||||
|
_lastMouseDownEvent = event; |
||||
|
[self mouseEvent:event withType:RightButtonDown]; |
||||
|
} |
||||
|
|
||||
|
- (void)mouseUp:(NSEvent *)event |
||||
|
{ |
||||
|
_isLeftPressed = false; |
||||
|
[self mouseEvent:event withType:LeftButtonUp]; |
||||
|
} |
||||
|
|
||||
|
- (void)otherMouseUp:(NSEvent *)event |
||||
|
{ |
||||
|
switch(event.buttonNumber) |
||||
|
{ |
||||
|
case 2: |
||||
|
case 3: |
||||
|
_isMiddlePressed = false; |
||||
|
[self mouseEvent:event withType:MiddleButtonUp]; |
||||
|
break; |
||||
|
case 4: |
||||
|
_isXButton1Pressed = false; |
||||
|
[self mouseEvent:event withType:XButton1Up]; |
||||
|
break; |
||||
|
case 5: |
||||
|
_isXButton2Pressed = false; |
||||
|
[self mouseEvent:event withType:XButton2Up]; |
||||
|
break; |
||||
|
|
||||
|
default: |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
- (void)rightMouseUp:(NSEvent *)event |
||||
|
{ |
||||
|
_isRightPressed = false; |
||||
|
[self mouseEvent:event withType:RightButtonUp]; |
||||
|
} |
||||
|
|
||||
|
- (void)mouseDragged:(NSEvent *)event |
||||
|
{ |
||||
|
[self mouseEvent:event withType:Move]; |
||||
|
[super mouseDragged:event]; |
||||
|
} |
||||
|
|
||||
|
- (void)otherMouseDragged:(NSEvent *)event |
||||
|
{ |
||||
|
[self mouseEvent:event withType:Move]; |
||||
|
[super otherMouseDragged:event]; |
||||
|
} |
||||
|
|
||||
|
- (void)rightMouseDragged:(NSEvent *)event |
||||
|
{ |
||||
|
[self mouseEvent:event withType:Move]; |
||||
|
[super rightMouseDragged:event]; |
||||
|
} |
||||
|
|
||||
|
- (void)scrollWheel:(NSEvent *)event |
||||
|
{ |
||||
|
[self mouseEvent:event withType:Wheel]; |
||||
|
[super scrollWheel:event]; |
||||
|
} |
||||
|
|
||||
|
- (void)magnifyWithEvent:(NSEvent *)event |
||||
|
{ |
||||
|
[self mouseEvent:event withType:Magnify]; |
||||
|
[super magnifyWithEvent:event]; |
||||
|
} |
||||
|
|
||||
|
- (void)rotateWithEvent:(NSEvent *)event |
||||
|
{ |
||||
|
[self mouseEvent:event withType:Rotate]; |
||||
|
[super rotateWithEvent:event]; |
||||
|
} |
||||
|
|
||||
|
- (void)swipeWithEvent:(NSEvent *)event |
||||
|
{ |
||||
|
[self mouseEvent:event withType:Swipe]; |
||||
|
[super swipeWithEvent:event]; |
||||
|
} |
||||
|
|
||||
|
- (void)mouseEntered:(NSEvent *)event |
||||
|
{ |
||||
|
[super mouseEntered:event]; |
||||
|
} |
||||
|
|
||||
|
- (void)mouseExited:(NSEvent *)event |
||||
|
{ |
||||
|
[self mouseEvent:event withType:LeaveWindow]; |
||||
|
[super mouseExited:event]; |
||||
|
} |
||||
|
|
||||
|
- (void) keyboardEvent: (NSEvent *) event withType: (AvnRawKeyEventType)type |
||||
|
{ |
||||
|
if([self ignoreUserInput: false]) |
||||
|
{ |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
auto key = s_KeyMap[[event keyCode]]; |
||||
|
|
||||
|
uint32_t timestamp = static_cast<uint32_t>([event timestamp] * 1000); |
||||
|
auto modifiers = [self getModifiers:[event modifierFlags]]; |
||||
|
|
||||
|
if(_parent != nullptr) |
||||
|
{ |
||||
|
_lastKeyHandled = _parent->BaseEvents->RawKeyEvent(type, timestamp, modifiers, key); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
- (BOOL)performKeyEquivalent:(NSEvent *)event |
||||
|
{ |
||||
|
bool result = _lastKeyHandled; |
||||
|
|
||||
|
_lastKeyHandled = false; |
||||
|
|
||||
|
return result; |
||||
|
} |
||||
|
|
||||
|
- (void)flagsChanged:(NSEvent *)event |
||||
|
{ |
||||
|
auto newModifierState = [self getModifiers:[event modifierFlags]]; |
||||
|
|
||||
|
bool isAltCurrentlyPressed = (_modifierState & Alt) == Alt; |
||||
|
bool isControlCurrentlyPressed = (_modifierState & Control) == Control; |
||||
|
bool isShiftCurrentlyPressed = (_modifierState & Shift) == Shift; |
||||
|
bool isCommandCurrentlyPressed = (_modifierState & Windows) == Windows; |
||||
|
|
||||
|
bool isAltPressed = (newModifierState & Alt) == Alt; |
||||
|
bool isControlPressed = (newModifierState & Control) == Control; |
||||
|
bool isShiftPressed = (newModifierState & Shift) == Shift; |
||||
|
bool isCommandPressed = (newModifierState & Windows) == Windows; |
||||
|
|
||||
|
|
||||
|
if (isAltPressed && !isAltCurrentlyPressed) |
||||
|
{ |
||||
|
[self keyboardEvent:event withType:KeyDown]; |
||||
|
} |
||||
|
else if (isAltCurrentlyPressed && !isAltPressed) |
||||
|
{ |
||||
|
[self keyboardEvent:event withType:KeyUp]; |
||||
|
} |
||||
|
|
||||
|
if (isControlPressed && !isControlCurrentlyPressed) |
||||
|
{ |
||||
|
[self keyboardEvent:event withType:KeyDown]; |
||||
|
} |
||||
|
else if (isControlCurrentlyPressed && !isControlPressed) |
||||
|
{ |
||||
|
[self keyboardEvent:event withType:KeyUp]; |
||||
|
} |
||||
|
|
||||
|
if (isShiftPressed && !isShiftCurrentlyPressed) |
||||
|
{ |
||||
|
[self keyboardEvent:event withType:KeyDown]; |
||||
|
} |
||||
|
else if(isShiftCurrentlyPressed && !isShiftPressed) |
||||
|
{ |
||||
|
[self keyboardEvent:event withType:KeyUp]; |
||||
|
} |
||||
|
|
||||
|
if(isCommandPressed && !isCommandCurrentlyPressed) |
||||
|
{ |
||||
|
[self keyboardEvent:event withType:KeyDown]; |
||||
|
} |
||||
|
else if(isCommandCurrentlyPressed && ! isCommandPressed) |
||||
|
{ |
||||
|
[self keyboardEvent:event withType:KeyUp]; |
||||
|
} |
||||
|
|
||||
|
_modifierState = newModifierState; |
||||
|
|
||||
|
[[self inputContext] handleEvent:event]; |
||||
|
[super flagsChanged:event]; |
||||
|
} |
||||
|
|
||||
|
- (void)keyDown:(NSEvent *)event |
||||
|
{ |
||||
|
[self keyboardEvent:event withType:KeyDown]; |
||||
|
[[self inputContext] handleEvent:event]; |
||||
|
[super keyDown:event]; |
||||
|
} |
||||
|
|
||||
|
- (void)keyUp:(NSEvent *)event |
||||
|
{ |
||||
|
[self keyboardEvent:event withType:KeyUp]; |
||||
|
[super keyUp:event]; |
||||
|
} |
||||
|
|
||||
|
- (AvnInputModifiers)getModifiers:(NSEventModifierFlags)mod |
||||
|
{ |
||||
|
unsigned int rv = 0; |
||||
|
|
||||
|
if (mod & NSEventModifierFlagControl) |
||||
|
rv |= Control; |
||||
|
if (mod & NSEventModifierFlagShift) |
||||
|
rv |= Shift; |
||||
|
if (mod & NSEventModifierFlagOption) |
||||
|
rv |= Alt; |
||||
|
if (mod & NSEventModifierFlagCommand) |
||||
|
rv |= Windows; |
||||
|
|
||||
|
if (_isLeftPressed) |
||||
|
rv |= LeftMouseButton; |
||||
|
if (_isMiddlePressed) |
||||
|
rv |= MiddleMouseButton; |
||||
|
if (_isRightPressed) |
||||
|
rv |= RightMouseButton; |
||||
|
if (_isXButton1Pressed) |
||||
|
rv |= XButton1MouseButton; |
||||
|
if (_isXButton2Pressed) |
||||
|
rv |= XButton2MouseButton; |
||||
|
|
||||
|
return (AvnInputModifiers)rv; |
||||
|
} |
||||
|
|
||||
|
- (BOOL)hasMarkedText |
||||
|
{ |
||||
|
return _lastKeyHandled; |
||||
|
} |
||||
|
|
||||
|
- (NSRange)markedRange |
||||
|
{ |
||||
|
return NSMakeRange(NSNotFound, 0); |
||||
|
} |
||||
|
|
||||
|
- (NSRange)selectedRange |
||||
|
{ |
||||
|
return NSMakeRange(NSNotFound, 0); |
||||
|
} |
||||
|
|
||||
|
- (void)setMarkedText:(id)string selectedRange:(NSRange)selectedRange replacementRange:(NSRange)replacementRange |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
|
||||
|
- (void)unmarkText |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
|
||||
|
- (NSArray<NSString *> *)validAttributesForMarkedText |
||||
|
{ |
||||
|
return [NSArray new]; |
||||
|
} |
||||
|
|
||||
|
- (NSAttributedString *)attributedSubstringForProposedRange:(NSRange)range actualRange:(NSRangePointer)actualRange |
||||
|
{ |
||||
|
return [NSAttributedString new]; |
||||
|
} |
||||
|
|
||||
|
- (void)insertText:(id)string replacementRange:(NSRange)replacementRange |
||||
|
{ |
||||
|
if(!_lastKeyHandled) |
||||
|
{ |
||||
|
if(_parent != nullptr) |
||||
|
{ |
||||
|
_lastKeyHandled = _parent->BaseEvents->RawTextInputEvent(0, [string UTF8String]); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
- (NSUInteger)characterIndexForPoint:(NSPoint)point |
||||
|
{ |
||||
|
return 0; |
||||
|
} |
||||
|
|
||||
|
- (NSRect)firstRectForCharacterRange:(NSRange)range actualRange:(NSRangePointer)actualRange |
||||
|
{ |
||||
|
CGRect result = { 0 }; |
||||
|
|
||||
|
return result; |
||||
|
} |
||||
|
|
||||
|
- (NSDragOperation)triggerAvnDragEvent: (AvnDragEventType) type info: (id <NSDraggingInfo>)info |
||||
|
{ |
||||
|
auto localPoint = [self convertPoint:[info draggingLocation] toView:self]; |
||||
|
auto avnPoint = [AvnView toAvnPoint:localPoint]; |
||||
|
auto point = [self translateLocalPoint:avnPoint]; |
||||
|
auto modifiers = [self getModifiers:[[NSApp currentEvent] modifierFlags]]; |
||||
|
NSDragOperation nsop = [info draggingSourceOperationMask]; |
||||
|
|
||||
|
auto effects = ConvertDragDropEffects(nsop); |
||||
|
int reffects = (int)_parent->BaseEvents |
||||
|
->DragEvent(type, point, modifiers, effects, |
||||
|
CreateClipboard([info draggingPasteboard], nil), |
||||
|
GetAvnDataObjectHandleFromDraggingInfo(info)); |
||||
|
|
||||
|
NSDragOperation ret = static_cast<NSDragOperation>(0); |
||||
|
|
||||
|
// Ensure that the managed part didn't add any new effects |
||||
|
reffects = (int)effects & reffects; |
||||
|
|
||||
|
// OSX requires exactly one operation |
||||
|
if((reffects & (int)AvnDragDropEffects::Copy) != 0) |
||||
|
ret = NSDragOperationCopy; |
||||
|
else if((reffects & (int)AvnDragDropEffects::Move) != 0) |
||||
|
ret = NSDragOperationMove; |
||||
|
else if((reffects & (int)AvnDragDropEffects::Link) != 0) |
||||
|
ret = NSDragOperationLink; |
||||
|
if(ret == 0) |
||||
|
ret = NSDragOperationNone; |
||||
|
return ret; |
||||
|
} |
||||
|
|
||||
|
- (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender |
||||
|
{ |
||||
|
return [self triggerAvnDragEvent: AvnDragEventType::Enter info:sender]; |
||||
|
} |
||||
|
|
||||
|
- (NSDragOperation)draggingUpdated:(id <NSDraggingInfo>)sender |
||||
|
{ |
||||
|
return [self triggerAvnDragEvent: AvnDragEventType::Over info:sender]; |
||||
|
} |
||||
|
|
||||
|
- (void)draggingExited:(id <NSDraggingInfo>)sender |
||||
|
{ |
||||
|
[self triggerAvnDragEvent: AvnDragEventType::Leave info:sender]; |
||||
|
} |
||||
|
|
||||
|
- (BOOL)prepareForDragOperation:(id <NSDraggingInfo>)sender |
||||
|
{ |
||||
|
return [self triggerAvnDragEvent: AvnDragEventType::Over info:sender] != NSDragOperationNone; |
||||
|
} |
||||
|
|
||||
|
- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender |
||||
|
{ |
||||
|
return [self triggerAvnDragEvent: AvnDragEventType::Drop info:sender] != NSDragOperationNone; |
||||
|
} |
||||
|
|
||||
|
- (void)concludeDragOperation:(nullable id <NSDraggingInfo>)sender |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
|
||||
|
- (AvnPlatformResizeReason)getResizeReason |
||||
|
{ |
||||
|
return _resizeReason; |
||||
|
} |
||||
|
|
||||
|
- (void)setResizeReason:(AvnPlatformResizeReason)reason |
||||
|
{ |
||||
|
_resizeReason = reason; |
||||
|
} |
||||
|
|
||||
|
- (AvnAccessibilityElement *) accessibilityChild |
||||
|
{ |
||||
|
if (_accessibilityChild == nil) |
||||
|
{ |
||||
|
auto peer = _parent->BaseEvents->GetAutomationPeer(); |
||||
|
|
||||
|
if (peer == nil) |
||||
|
return nil; |
||||
|
|
||||
|
_accessibilityChild = [AvnAccessibilityElement acquire:peer]; |
||||
|
} |
||||
|
|
||||
|
return _accessibilityChild; |
||||
|
} |
||||
|
|
||||
|
- (NSArray *)accessibilityChildren |
||||
|
{ |
||||
|
auto child = [self accessibilityChild]; |
||||
|
return NSAccessibilityUnignoredChildrenForOnlyChild(child); |
||||
|
} |
||||
|
|
||||
|
- (id)accessibilityHitTest:(NSPoint)point |
||||
|
{ |
||||
|
return [[self accessibilityChild] accessibilityHitTest:point]; |
||||
|
} |
||||
|
|
||||
|
- (id)accessibilityFocusedUIElement |
||||
|
{ |
||||
|
return [[self accessibilityChild] accessibilityFocusedUIElement]; |
||||
|
} |
||||
|
|
||||
|
@end |
||||
Loading…
Reference in new issue