未验证 提交 69d0a8e7 编写于 作者: T Tong Mu 提交者: GitHub

System mouse cursor: macOS (#18131)

* Untested macOS impl

* Workable mac

* Modernize

* Simplify

* Address comments

* Refactor with FlutterPlugin

* Cached dict

* Update per comments

* format

* Remove device arg

* Format

* Update license

* Update licences

* Doc update
上级 a25040c5
......@@ -959,6 +959,8 @@ FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterEngin
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterEngine_Internal.h
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterExternalTextureGL.h
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterExternalTextureGL.mm
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterMouseCursorPlugin.h
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterMouseCursorPlugin.mm
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterTextInputModel.h
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterTextInputModel.mm
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterTextInputPlugin.h
......
......@@ -54,6 +54,8 @@ source_set("flutter_framework_source") {
"framework/Source/FlutterEngine_Internal.h",
"framework/Source/FlutterExternalTextureGL.h",
"framework/Source/FlutterExternalTextureGL.mm",
"framework/Source/FlutterMouseCursorPlugin.h",
"framework/Source/FlutterMouseCursorPlugin.mm",
"framework/Source/FlutterTextInputModel.h",
"framework/Source/FlutterTextInputModel.mm",
"framework/Source/FlutterTextInputPlugin.h",
......
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#import <Cocoa/Cocoa.h>
#import "flutter/shell/platform/darwin/common/framework/Headers/FlutterBinaryMessenger.h"
#import "flutter/shell/platform/darwin/macos/framework/Headers/FlutterViewController.h"
/**
* A plugin to handle mouse cursor.
*
* Responsible for bridging the native macOS mouse cursor system with the
* Flutter framework mouse cursor classes, via system channels.
*/
@interface FlutterMouseCursorPlugin : NSObject <FlutterPlugin>
@end
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#import <objc/message.h>
#import "FlutterMouseCursorPlugin.h"
#import "flutter/shell/platform/darwin/common/framework/Headers/FlutterCodecs.h"
static NSString* const kMouseCursorChannel = @"flutter/mousecursor";
static NSString* const kActivateSystemCursorMethod = @"activateSystemCursor";
static NSString* const kKindKey = @"kind";
static NSString* const kKindValueNone = @"none";
/**
* Maps a Flutter's constant to a platform's cursor object.
*
* Returns the arrow cursor for unknown constants, including kSystemShapeNone.
*/
static NSCursor* GetCursorForKind(NSString* kind) {
// The following mapping must be kept in sync with Flutter framework's
// mouse_cursor.dart
if ([kind isEqualToString:@"basic"])
return [NSCursor arrowCursor];
else if ([kind isEqualToString:@"click"])
return [NSCursor pointingHandCursor];
else if ([kind isEqualToString:@"text"])
return [NSCursor IBeamCursor];
else if ([kind isEqualToString:@"forbidden"])
return [NSCursor operationNotAllowedCursor];
else if ([kind isEqualToString:@"grab"])
return [NSCursor openHandCursor];
else if ([kind isEqualToString:@"grabbing"])
return [NSCursor closedHandCursor];
else
return [NSCursor arrowCursor];
}
@interface FlutterMouseCursorPlugin ()
/**
* Whether the cursor is currently hidden.
*/
@property(nonatomic) BOOL hidden;
/**
* Handles the method call that activates a system cursor.
*
* Returns a FlutterError if the arguments can not be recognized. Otherwise
* returns nil.
*/
- (FlutterError*)activateSystemCursor:(nonnull NSDictionary*)arguments;
/**
* Displays the specified cursor.
*
* Unhides the cursor before displaying the cursor, and updates
* internal states.
*/
- (void)displayCursorObject:(nonnull NSCursor*)cursorObject;
/**
* Hides the cursor.
*/
- (void)hide;
/**
* Handles all method calls from Flutter.
*/
- (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result;
@end
@implementation FlutterMouseCursorPlugin
#pragma mark - Private
NSMutableDictionary* cachedSystemCursors;
- (instancetype)init {
self = [super init];
if (self) {
cachedSystemCursors = [NSMutableDictionary dictionary];
}
return self;
}
- (void)dealloc {
if (_hidden) {
[NSCursor unhide];
}
}
- (FlutterError*)activateSystemCursor:(nonnull NSDictionary*)arguments {
NSString* kindArg = arguments[kKindKey];
if (!kindArg) {
return [FlutterError errorWithCode:@"error"
message:@"Missing argument"
details:@"Missing argument while trying to activate system cursor"];
}
if ([kindArg isEqualToString:kKindValueNone]) {
[self hide];
return nil;
}
NSCursor* cursorObject = [FlutterMouseCursorPlugin cursorFromKind:kindArg];
[self displayCursorObject:cursorObject];
return nil;
}
- (void)displayCursorObject:(nonnull NSCursor*)cursorObject {
[cursorObject set];
if (_hidden) {
[NSCursor unhide];
}
_hidden = NO;
}
- (void)hide {
if (!_hidden) {
[NSCursor hide];
}
_hidden = YES;
}
+ (NSCursor*)cursorFromKind:(NSString*)kind {
NSCursor* cachedValue = [cachedSystemCursors objectForKey:kind];
if (!cachedValue) {
cachedValue = GetCursorForKind(kind);
[cachedSystemCursors setValue:cachedValue forKey:kind];
}
return cachedValue;
}
#pragma mark - FlutterPlugin implementation
+ (void)registerWithRegistrar:(id<FlutterPluginRegistrar>)registrar {
FlutterMethodChannel* channel = [FlutterMethodChannel methodChannelWithName:kMouseCursorChannel
binaryMessenger:registrar.messenger];
FlutterMouseCursorPlugin* instance = [[FlutterMouseCursorPlugin alloc] init];
[registrar addMethodCallDelegate:instance channel:channel];
}
- (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result {
NSString* method = call.method;
if ([method isEqualToString:kActivateSystemCursorMethod]) {
result([self activateSystemCursor:call.arguments]);
} else {
result(FlutterMethodNotImplemented);
}
}
@end
......@@ -9,6 +9,7 @@
#import "flutter/shell/platform/darwin/common/framework/Headers/FlutterCodecs.h"
#import "flutter/shell/platform/darwin/macos/framework/Headers/FlutterEngine.h"
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterEngine_Internal.h"
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterMouseCursorPlugin.h"
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterTextInputPlugin.h"
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterView.h"
#import "flutter/shell/platform/embedder/embedder.h"
......@@ -350,6 +351,7 @@ static void CommonInit(FlutterViewController* controller) {
}
- (void)addInternalPlugins {
[FlutterMouseCursorPlugin registerWithRegistrar:[self registrarForPlugin:@"mousecursor"]];
_textInputPlugin = [[FlutterTextInputPlugin alloc] initWithViewController:self];
_keyEventChannel =
[FlutterBasicMessageChannel messageChannelWithName:@"flutter/keyevent"
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册