235 lines
8.3 KiB
Plaintext
235 lines
8.3 KiB
Plaintext
#import "TGFlutterPagPlatformView.h"
|
|
#import "TGFlutterPagDownloadManager.h"
|
|
|
|
#import <libpag/PAGFile.h>
|
|
#import <libpag/PAGImage.h>
|
|
#import <libpag/PAGScaleMode.h>
|
|
#import <libpag/PAGView.h>
|
|
#import <UIKit/UIKit.h>
|
|
|
|
@interface TGFlutterPagPlatformView : NSObject <FlutterPlatformView, PAGViewListener>
|
|
@property(nonatomic, strong) PAGView* pagView;
|
|
@property(nonatomic, weak) NSObject<FlutterPluginRegistrar>* registrar;
|
|
@end
|
|
|
|
@implementation TGFlutterPagPlatformView
|
|
|
|
- (instancetype)initWithFrame:(CGRect)frame
|
|
viewIdentifier:(int64_t)viewId
|
|
arguments:(id)arguments
|
|
registrar:(NSObject<FlutterPluginRegistrar>*)registrar {
|
|
self = [super init];
|
|
if (self) {
|
|
_registrar = registrar;
|
|
_pagView = [[PAGView alloc] initWithFrame:frame];
|
|
_pagView.backgroundColor = UIColor.clearColor;
|
|
_pagView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
|
|
[_pagView setScaleMode:PAGScaleModeLetterBox];
|
|
[_pagView addListener:self];
|
|
[self configureWithArguments:arguments];
|
|
}
|
|
return self;
|
|
}
|
|
|
|
- (UIView*)view {
|
|
return _pagView;
|
|
}
|
|
|
|
- (void)configureWithArguments:(id)arguments {
|
|
if (![arguments isKindOfClass:NSDictionary.class]) {
|
|
return;
|
|
}
|
|
NSDictionary* params = arguments;
|
|
int repeatCount = 1;
|
|
id repeatValue = params[@"repeatCount"];
|
|
if ([repeatValue respondsToSelector:@selector(intValue)]) {
|
|
repeatCount = [repeatValue intValue];
|
|
}
|
|
double initProgress = 0.0;
|
|
id progressValue = params[@"initProgress"];
|
|
if ([progressValue respondsToSelector:@selector(doubleValue)]) {
|
|
initProgress = [progressValue doubleValue];
|
|
}
|
|
BOOL autoPlay = NO;
|
|
id autoPlayValue = params[@"autoPlay"];
|
|
if ([autoPlayValue respondsToSelector:@selector(boolValue)]) {
|
|
autoPlay = [autoPlayValue boolValue];
|
|
}
|
|
NSDictionary<NSString*, NSData*>* imageReplacementsByName = [self imageReplacementsByNameFromParams:params];
|
|
|
|
[_pagView setRepeatCount:repeatCount];
|
|
[_pagView setProgress:initProgress];
|
|
|
|
NSString* assetName = [self nonEmptyString:params[@"assetName"]];
|
|
if (assetName.length > 0) {
|
|
NSString* package = [self nonEmptyString:params[@"package"]];
|
|
NSString* assetPath = [self assetPathForName:assetName package:package];
|
|
[self loadPath:assetPath initProgress:initProgress autoPlay:autoPlay imageReplacementsByName:imageReplacementsByName];
|
|
return;
|
|
}
|
|
|
|
NSString* url = [self nonEmptyString:params[@"url"]];
|
|
if (url.length > 0) {
|
|
__weak typeof(self) weakSelf = self;
|
|
[TGFlutterPagDownloadManager download:url completionHandler:^(NSData* data, NSError* error) {
|
|
if (data == nil || data.length == 0) {
|
|
return;
|
|
}
|
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
[weakSelf loadData:data initProgress:initProgress autoPlay:autoPlay imageReplacementsByName:imageReplacementsByName];
|
|
});
|
|
}];
|
|
return;
|
|
}
|
|
|
|
id bytesData = params[@"bytesData"];
|
|
if ([bytesData isKindOfClass:FlutterStandardTypedData.class]) {
|
|
FlutterStandardTypedData* typedData = bytesData;
|
|
if (typedData.type == FlutterStandardDataTypeUInt8) {
|
|
[self loadData:typedData.data initProgress:initProgress autoPlay:autoPlay imageReplacementsByName:imageReplacementsByName];
|
|
}
|
|
}
|
|
}
|
|
|
|
- (NSString*)nonEmptyString:(id)value {
|
|
if (![value isKindOfClass:NSString.class]) {
|
|
return nil;
|
|
}
|
|
NSString* text = [(NSString*)value stringByTrimmingCharactersInSet:NSCharacterSet.whitespaceAndNewlineCharacterSet];
|
|
return text.length > 0 ? text : nil;
|
|
}
|
|
|
|
- (NSString*)assetPathForName:(NSString*)assetName package:(NSString*)package {
|
|
NSString* resourcePath = nil;
|
|
if (package.length > 0) {
|
|
resourcePath = [_registrar lookupKeyForAsset:assetName fromPackage:package];
|
|
} else {
|
|
resourcePath = [_registrar lookupKeyForAsset:assetName];
|
|
}
|
|
return [[NSBundle mainBundle] pathForResource:resourcePath ofType:nil];
|
|
}
|
|
|
|
- (void)loadPath:(NSString*)path initProgress:(double)initProgress autoPlay:(BOOL)autoPlay imageReplacementsByName:(NSDictionary<NSString*, NSData*>*)imageReplacementsByName {
|
|
if (path.length == 0) {
|
|
return;
|
|
}
|
|
if (imageReplacementsByName.count > 0) {
|
|
PAGFile* file = [PAGFile Load:path];
|
|
[self applyImageReplacementsByName:imageReplacementsByName toFile:file];
|
|
[self setFile:file initProgress:initProgress autoPlay:autoPlay];
|
|
return;
|
|
}
|
|
if (![_pagView setPath:path]) {
|
|
return;
|
|
}
|
|
[_pagView setProgress:initProgress];
|
|
[_pagView flush];
|
|
if (autoPlay) {
|
|
[_pagView play];
|
|
}
|
|
}
|
|
|
|
- (void)loadData:(NSData*)data initProgress:(double)initProgress autoPlay:(BOOL)autoPlay imageReplacementsByName:(NSDictionary<NSString*, NSData*>*)imageReplacementsByName {
|
|
if (data == nil || data.length == 0) {
|
|
return;
|
|
}
|
|
PAGFile* file = [PAGFile Load:data.bytes size:data.length];
|
|
[self applyImageReplacementsByName:imageReplacementsByName toFile:file];
|
|
[self setFile:file initProgress:initProgress autoPlay:autoPlay];
|
|
}
|
|
|
|
- (void)setFile:(PAGFile*)file initProgress:(double)initProgress autoPlay:(BOOL)autoPlay {
|
|
if (file == nil || file.width <= 0 || file.height <= 0) {
|
|
return;
|
|
}
|
|
[_pagView setComposition:file];
|
|
[_pagView setProgress:initProgress];
|
|
[_pagView flush];
|
|
if (autoPlay) {
|
|
[_pagView play];
|
|
}
|
|
}
|
|
|
|
- (NSDictionary<NSString*, NSData*>*)imageReplacementsByNameFromParams:(NSDictionary*)params {
|
|
id raw = params[@"imageReplacementsByName"];
|
|
if (![raw isKindOfClass:NSDictionary.class]) {
|
|
return @{};
|
|
}
|
|
NSMutableDictionary<NSString*, NSData*>* result = [[NSMutableDictionary alloc] init];
|
|
[(NSDictionary*)raw enumerateKeysAndObjectsUsingBlock:^(id key, id value, BOOL* stop) {
|
|
if (![key isKindOfClass:NSString.class]) {
|
|
return;
|
|
}
|
|
NSString* layerName = [(NSString*)key stringByTrimmingCharactersInSet:NSCharacterSet.whitespaceAndNewlineCharacterSet];
|
|
if (layerName.length == 0) {
|
|
return;
|
|
}
|
|
NSData* data = nil;
|
|
if ([value isKindOfClass:FlutterStandardTypedData.class]) {
|
|
FlutterStandardTypedData* typedData = value;
|
|
if (typedData.type == FlutterStandardDataTypeUInt8) {
|
|
data = typedData.data;
|
|
}
|
|
} else if ([value isKindOfClass:NSData.class]) {
|
|
data = value;
|
|
}
|
|
if (data.length > 0) {
|
|
result[layerName] = data;
|
|
}
|
|
}];
|
|
return result;
|
|
}
|
|
|
|
- (void)applyImageReplacementsByName:(NSDictionary<NSString*, NSData*>*)imageReplacementsByName toFile:(PAGFile*)file {
|
|
if (file == nil || imageReplacementsByName == nil || imageReplacementsByName.count == 0) {
|
|
return;
|
|
}
|
|
[imageReplacementsByName enumerateKeysAndObjectsUsingBlock:^(NSString* layerName, NSData* data, BOOL* stop) {
|
|
if (![layerName isKindOfClass:NSString.class] || layerName.length == 0 ||
|
|
![data isKindOfClass:NSData.class] || data.length == 0) {
|
|
return;
|
|
}
|
|
PAGImage* image = [PAGImage FromBytes:data.bytes size:data.length];
|
|
if (image == nil) {
|
|
return;
|
|
}
|
|
[image setScaleMode:PAGScaleModeZoom];
|
|
[file replaceImageByName:layerName data:image];
|
|
}];
|
|
}
|
|
|
|
- (void)dealloc {
|
|
[_pagView removeListener:self];
|
|
[_pagView stop];
|
|
[_pagView setComposition:nil];
|
|
}
|
|
|
|
@end
|
|
|
|
@implementation TGFlutterPagPlatformViewFactory {
|
|
__weak NSObject<FlutterPluginRegistrar>* _registrar;
|
|
}
|
|
|
|
- (instancetype)initWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar {
|
|
self = [super init];
|
|
if (self) {
|
|
_registrar = registrar;
|
|
}
|
|
return self;
|
|
}
|
|
|
|
- (NSObject<FlutterMessageCodec>*)createArgsCodec {
|
|
return FlutterStandardMessageCodec.sharedInstance;
|
|
}
|
|
|
|
- (NSObject<FlutterPlatformView>*)createWithFrame:(CGRect)frame
|
|
viewIdentifier:(int64_t)viewId
|
|
arguments:(id)args {
|
|
return [[TGFlutterPagPlatformView alloc] initWithFrame:frame
|
|
viewIdentifier:viewId
|
|
arguments:args
|
|
registrar:_registrar];
|
|
}
|
|
|
|
@end
|