mirror of
https://github.com/TelegramMessenger/Telegram-iOS.git
synced 2026-07-06 03:33:41 +02:00
Merge commit '01a3152ce4'
This commit is contained in:
commit
5ecbcc0f19
40 changed files with 532 additions and 1012 deletions
|
|
@ -10,6 +10,8 @@
|
|||
@class TGSuggestionContext;
|
||||
@class TGVideoEditAdjustments;
|
||||
|
||||
@protocol TGPhotoPaintStickersContext;
|
||||
|
||||
typedef enum {
|
||||
TGCameraControllerGenericIntent,
|
||||
TGCameraControllerPassportIntent,
|
||||
|
|
@ -39,6 +41,7 @@ typedef enum {
|
|||
@property (nonatomic, assign) bool hasSchedule;
|
||||
@property (nonatomic, assign) bool reminder;
|
||||
@property (nonatomic, strong) TGSuggestionContext *suggestionContext;
|
||||
@property (nonatomic, strong) id<TGPhotoPaintStickersContext> stickersContext;
|
||||
@property (nonatomic, assign) bool shortcut;
|
||||
|
||||
@property (nonatomic, strong) NSString *forcedCaption;
|
||||
|
|
|
|||
|
|
@ -3,10 +3,12 @@
|
|||
|
||||
@protocol TGMediaEditableItem;
|
||||
@class TGMediaEditingContext;
|
||||
@protocol TGPhotoPaintStickersContext;
|
||||
|
||||
@protocol TGModernGalleryEditableItem <TGModernGalleryItem>
|
||||
|
||||
@property (nonatomic, strong) TGMediaEditingContext *editingContext;
|
||||
@property (nonatomic, strong) id<TGPhotoPaintStickersContext> stickersContext;
|
||||
|
||||
- (id<TGMediaEditableItem>)editableMediaItem;
|
||||
- (TGPhotoEditorTab)toolbarTabs;
|
||||
|
|
|
|||
|
|
@ -18,6 +18,8 @@
|
|||
|
||||
@property (nonatomic, readonly) UIImage *stillImage;
|
||||
|
||||
@property (nonatomic, readonly) bool hasAnimation;
|
||||
|
||||
+ (instancetype)dataWithPaintingData:(NSData *)data image:(UIImage *)image stillImage:(UIImage *)stillImage entities:(NSArray *)entities undoManager:(TGPaintUndoManager *)undoManager;
|
||||
|
||||
+ (instancetype)dataWithPaintingImagePath:(NSString *)imagePath entities:(NSArray *)entities;
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
#import <CoreMedia/CoreMedia.h>
|
||||
|
||||
@class TGPaintingData;
|
||||
@class TGStickerMaskDescription;
|
||||
|
||||
@protocol TGPhotoPaintEntityRenderer <NSObject>
|
||||
|
||||
|
|
@ -12,12 +13,16 @@
|
|||
|
||||
@protocol TGPhotoPaintStickerRenderView <NSObject>
|
||||
|
||||
- (int64_t)documentId;
|
||||
- (UIImage *)image;
|
||||
|
||||
@end
|
||||
|
||||
@protocol TGPhotoPaintStickersContext <NSObject>
|
||||
|
||||
- (int64_t)documentIdForDocument:(id)document;
|
||||
- (TGStickerMaskDescription *)maskDescriptionForDocument:(id)document;
|
||||
|
||||
- (UIView<TGPhotoPaintStickerRenderView> *)stickerViewForDocument:(id)document;
|
||||
|
||||
@property (nonatomic, copy) void(^presentStickersController)(void(^)(id, bool, UIView *, CGRect));
|
||||
|
|
|
|||
|
|
@ -2,6 +2,6 @@
|
|||
|
||||
@interface TGPhotoVideoEditor : NSObject
|
||||
|
||||
+ (void)presentWithContext:(id<LegacyComponentsContext>)context controller:(TGViewController *)controller caption:(NSString *)caption entities:(NSArray *)entities withItem:(id<TGMediaEditableItem, TGMediaSelectableItem>)item recipientName:(NSString *)recipientName completion:(void (^)(id<TGMediaEditableItem>, TGMediaEditingContext *))completion dismissed:(void (^)())dismissed;
|
||||
+ (void)presentWithContext:(id<LegacyComponentsContext>)context controller:(TGViewController *)controller caption:(NSString *)caption entities:(NSArray *)entities withItem:(id<TGMediaEditableItem, TGMediaSelectableItem>)item recipientName:(NSString *)recipientName stickersContext:(id<TGPhotoPaintStickersContext>)stickersContext completion:(void (^)(id<TGMediaEditableItem>, TGMediaEditingContext *))completion dismissed:(void (^)())dismissed;
|
||||
|
||||
@end
|
||||
|
|
|
|||
|
|
@ -286,6 +286,14 @@ const NSUInteger PGCurveDataStep = 2;
|
|||
return _parameters;
|
||||
}
|
||||
|
||||
- (id)displayValue {
|
||||
if (self.disabled) {
|
||||
return [PGCurvesToolValue defaultValue];
|
||||
} else {
|
||||
return [super displayValue];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)updateParameters
|
||||
{
|
||||
PGCurvesToolValue *value = (PGCurvesToolValue *)self.displayValue;
|
||||
|
|
|
|||
|
|
@ -33,6 +33,8 @@
|
|||
|
||||
@property (nonatomic, assign) bool standalone;
|
||||
|
||||
@property (nonatomic, assign) bool disableAll;
|
||||
|
||||
- (instancetype)initWithOriginalSize:(CGSize)originalSize adjustments:(id<TGMediaEditAdjustments>)adjustments forVideo:(bool)forVideo enableStickers:(bool)enableStickers;
|
||||
|
||||
- (void)cleanup;
|
||||
|
|
@ -43,6 +45,7 @@
|
|||
- (void)setCIImage:(CIImage *)ciImage;
|
||||
|
||||
- (void)processAnimated:(bool)animated completion:(void (^)(void))completion;
|
||||
- (void)reprocess;
|
||||
|
||||
- (void)createResultImageWithCompletion:(void (^)(UIImage *image))completion;
|
||||
- (UIImage *)currentResultImage;
|
||||
|
|
|
|||
|
|
@ -320,6 +320,12 @@
|
|||
} synchronous:synchronous];
|
||||
}
|
||||
|
||||
- (void)reprocess {
|
||||
if ([_currentInput isKindOfClass:[PGVideoMovie class]]) {
|
||||
[(PGVideoMovie *)_currentInput reprocessCurrent];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)updateProcessChain {
|
||||
[GPUImageFramebuffer setMark:self.forVideo];
|
||||
|
||||
|
|
@ -477,6 +483,15 @@
|
|||
}
|
||||
}
|
||||
|
||||
- (void)setDisableAll:(bool)disableAll {
|
||||
_disableAll = disableAll;
|
||||
|
||||
for (PGPhotoTool *tool in self.tools)
|
||||
{
|
||||
tool.disabled = disableAll;
|
||||
}
|
||||
}
|
||||
|
||||
- (SSignal *)histogramSignal
|
||||
{
|
||||
return [[SSignal single:_currentHistogram] then:_histogramPipe.signalProducer()];
|
||||
|
|
|
|||
|
|
@ -81,6 +81,9 @@
|
|||
|
||||
- (id)displayValue
|
||||
{
|
||||
if (self.disabled)
|
||||
return @(self.defaultValue);
|
||||
|
||||
if (self.beingEdited)
|
||||
return self.tempValue;
|
||||
|
||||
|
|
@ -91,8 +94,14 @@
|
|||
{
|
||||
_disabled = disabled;
|
||||
|
||||
if (self.beingEdited)
|
||||
if (!self.beingEdited) {
|
||||
[self updateParameters];
|
||||
[self updatePassParameters];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)updatePassParameters {
|
||||
|
||||
}
|
||||
|
||||
- (void)setBeingEdited:(bool)beingEdited
|
||||
|
|
|
|||
|
|
@ -53,6 +53,15 @@
|
|||
return true;
|
||||
}
|
||||
|
||||
+ (instancetype)defaultValue {
|
||||
PGTintToolValue *value = [[PGTintToolValue alloc] init];
|
||||
value.shadowsColor = [UIColor clearColor];
|
||||
value.shadowsIntensity = 50.0f;
|
||||
value.highlightsColor = [UIColor clearColor];
|
||||
value.highlightsIntensity = 50.0f;
|
||||
return value;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
|
|
@ -80,13 +89,7 @@
|
|||
_maximumValue = 100;
|
||||
_defaultValue = 0;
|
||||
|
||||
PGTintToolValue *value = [[PGTintToolValue alloc] init];
|
||||
value.shadowsColor = [UIColor clearColor];
|
||||
value.shadowsIntensity = 50.0f;
|
||||
value.highlightsColor = [UIColor clearColor];
|
||||
value.highlightsIntensity = 50.0f;
|
||||
|
||||
self.value = value;
|
||||
self.value = [PGTintToolValue defaultValue];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
|
@ -150,6 +153,14 @@
|
|||
return _parameters;
|
||||
}
|
||||
|
||||
- (id)displayValue {
|
||||
if (self.disabled) {
|
||||
return [PGTintToolValue defaultValue];
|
||||
} else {
|
||||
return [super displayValue];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)updateParameters
|
||||
{
|
||||
PGTintToolValue *value = (PGTintToolValue *)self.displayValue;
|
||||
|
|
|
|||
|
|
@ -23,4 +23,6 @@
|
|||
- (void)cancelProcessing;
|
||||
- (void)processMovieFrame:(CMSampleBufferRef)movieSampleBuffer;
|
||||
|
||||
- (void)reprocessCurrent;
|
||||
|
||||
@end
|
||||
|
|
|
|||
|
|
@ -116,6 +116,7 @@ NSString *const kYUVVideoRangeConversionForLAFragmentShaderString = SHADER_STRIN
|
|||
@implementation PGVideoMovie
|
||||
{
|
||||
bool videoEncodingIsFinished;
|
||||
bool _shouldReprocessCurrentFrame;
|
||||
}
|
||||
|
||||
@synthesize asset = _asset;
|
||||
|
|
@ -124,20 +125,19 @@ NSString *const kYUVVideoRangeConversionForLAFragmentShaderString = SHADER_STRIN
|
|||
#pragma mark -
|
||||
#pragma mark Initialization and teardown
|
||||
|
||||
- (UIInterfaceOrientation)orientationForTrack:(AVAsset *)asset
|
||||
{
|
||||
- (UIInterfaceOrientation)orientationForTrack:(AVAsset *)asset {
|
||||
AVAssetTrack *videoTrack = [[asset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];
|
||||
CGSize size = [videoTrack naturalSize];
|
||||
CGAffineTransform txf = [videoTrack preferredTransform];
|
||||
|
||||
if (size.width == txf.tx && size.height == txf.ty)
|
||||
CGAffineTransform trackTransform = [videoTrack preferredTransform];
|
||||
|
||||
if (trackTransform.a == -1 && trackTransform.d == -1) {
|
||||
return UIInterfaceOrientationLandscapeRight;
|
||||
else if (txf.tx == 0 && txf.ty == 0)
|
||||
} else if (trackTransform.a == 1 && trackTransform.d == 1) {
|
||||
return UIInterfaceOrientationLandscapeLeft;
|
||||
else if (txf.tx == 0 && txf.ty == size.width)
|
||||
} else if (trackTransform.b == -1 && trackTransform.c == 1) {
|
||||
return UIInterfaceOrientationPortraitUpsideDown;
|
||||
else
|
||||
} else {
|
||||
return UIInterfaceOrientationPortrait;
|
||||
}
|
||||
}
|
||||
|
||||
- (instancetype)initWithAsset:(AVAsset *)asset
|
||||
|
|
@ -341,8 +341,10 @@ NSString *const kYUVVideoRangeConversionForLAFragmentShaderString = SHADER_STRIN
|
|||
|
||||
- (void)processPixelBufferAtTime:(CMTime)outputItemTime
|
||||
{
|
||||
if ([playerItemOutput hasNewPixelBufferForItemTime:outputItemTime])
|
||||
if ([playerItemOutput hasNewPixelBufferForItemTime:outputItemTime] || _shouldReprocessCurrentFrame)
|
||||
{
|
||||
_shouldReprocessCurrentFrame = false;
|
||||
|
||||
__unsafe_unretained PGVideoMovie *weakSelf = self;
|
||||
CVPixelBufferRef pixelBuffer = [playerItemOutput copyPixelBufferForItemTime:outputItemTime itemTimeForDisplay:NULL];
|
||||
if (pixelBuffer != NULL)
|
||||
|
|
@ -355,6 +357,10 @@ NSString *const kYUVVideoRangeConversionForLAFragmentShaderString = SHADER_STRIN
|
|||
}
|
||||
}
|
||||
|
||||
- (void)reprocessCurrent {
|
||||
_shouldReprocessCurrentFrame = true;
|
||||
}
|
||||
|
||||
- (BOOL)readNextVideoFrameFromOutput:(AVAssetReaderOutput *)readerVideoTrackOutput;
|
||||
{
|
||||
if (reader.status == AVAssetReaderStatusReading && !videoEncodingIsFinished)
|
||||
|
|
@ -544,6 +550,8 @@ NSString *const kYUVVideoRangeConversionForLAFragmentShaderString = SHADER_STRIN
|
|||
[currentTarget setInputRotation:kGPUImageRotate180 atIndex:targetTextureIndex];
|
||||
} else if (orientation == UIInterfaceOrientationPortraitUpsideDown) {
|
||||
[currentTarget setInputRotation:kGPUImageRotateLeft atIndex:targetTextureIndex];
|
||||
} else {
|
||||
[currentTarget setInputRotation:kGPUImageNoRotation atIndex:targetTextureIndex];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1147,6 +1147,7 @@ static CGPoint TGCameraControllerClampPointToScreenSize(__unused id self, __unus
|
|||
|
||||
galleryItem.selectionContext = _selectionContext;
|
||||
galleryItem.editingContext = _editingContext;
|
||||
galleryItem.stickersContext = _stickersContext;
|
||||
|
||||
if (enumerationBlock != nil)
|
||||
enumerationBlock(galleryItem);
|
||||
|
|
@ -1652,6 +1653,7 @@ static CGPoint TGCameraControllerClampPointToScreenSize(__unused id self, __unus
|
|||
intent = TGPhotoEditorControllerSignupAvatarIntent;
|
||||
}
|
||||
TGPhotoEditorController *controller = [[TGPhotoEditorController alloc] initWithContext:windowContext item:image intent:(TGPhotoEditorControllerFromCameraIntent | intent) adjustments:nil caption:nil screenImage:image availableTabs:[TGPhotoEditorController defaultTabsForAvatarIntent] selectedTab:TGPhotoEditorCropTab];
|
||||
controller.stickersContext = _stickersContext;
|
||||
__weak TGPhotoEditorController *weakController = controller;
|
||||
controller.beginTransitionIn = ^UIView *(CGRect *referenceFrame, __unused UIView **parentView)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@
|
|||
#import "TGMemoryImageCache.h"
|
||||
#import "TGMediaAsset.h"
|
||||
|
||||
#import "TGPaintingData.h"
|
||||
|
||||
@interface TGMediaImageUpdate : NSObject
|
||||
|
||||
@property (nonatomic, readonly, strong) id<TGMediaEditableItem> item;
|
||||
|
|
@ -749,6 +751,9 @@
|
|||
if (![editorValues toolsApplied] && ![editorValues hasPainting])
|
||||
return [SSignal complete];
|
||||
|
||||
if ([editorValues.paintingData hasAnimation])
|
||||
return [SSignal complete];
|
||||
|
||||
NSURL *url = [self _fullSizeImageUrlForItem:item];
|
||||
if (url != nil)
|
||||
return [SSignal single:url];
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
@synthesize selectionContext;
|
||||
@synthesize editingContext;
|
||||
@synthesize stickersContext;
|
||||
|
||||
- (NSString *)uniqueId
|
||||
{
|
||||
|
|
|
|||
|
|
@ -900,7 +900,7 @@
|
|||
}
|
||||
|
||||
if (adjustments.sendAsGif)
|
||||
disabledButtons |= TGPhotoEditorToolsTab | TGPhotoEditorQualityTab;
|
||||
disabledButtons |= TGPhotoEditorQualityTab;
|
||||
|
||||
[_portraitToolbarView setEditButtonsHighlighted:highlightedButtons];
|
||||
[_landscapeToolbarView setEditButtonsHighlighted:highlightedButtons];
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
@synthesize selectionContext;
|
||||
@synthesize editingContext;
|
||||
@synthesize stickersContext;
|
||||
|
||||
- (NSString *)uniqueId
|
||||
{
|
||||
|
|
|
|||
|
|
@ -20,6 +20,9 @@
|
|||
|
||||
#import "TGMediaPickerGalleryPhotoItem.h"
|
||||
|
||||
#import "TGPhotoEntitiesContainerView.h"
|
||||
#import "TGPhotoPaintController.h"
|
||||
|
||||
#import <LegacyComponents/TGMenuView.h>
|
||||
|
||||
@interface TGMediaPickerGalleryPhotoItemView ()
|
||||
|
|
@ -33,6 +36,10 @@
|
|||
UIView *_temporaryRepView;
|
||||
PHLivePhotoView *_livePhotoView;
|
||||
|
||||
UIView *_contentWrapperView;
|
||||
TGPhotoEntitiesContainerView *_entitiesContainerView;
|
||||
|
||||
SMetaDisposable *_adjustmentsDisposable;
|
||||
SMetaDisposable *_attributesDisposable;
|
||||
|
||||
TGMenuContainerView *_tooltipContainerView;
|
||||
|
|
@ -54,6 +61,7 @@
|
|||
{
|
||||
__weak TGMediaPickerGalleryPhotoItemView *weakSelf = self;
|
||||
_imageView = [[TGModernGalleryImageItemImageView alloc] init];
|
||||
_imageView.clipsToBounds = true;
|
||||
_imageView.progressChanged = ^(CGFloat value)
|
||||
{
|
||||
__strong TGMediaPickerGalleryPhotoItemView *strongSelf = weakSelf;
|
||||
|
|
@ -70,17 +78,27 @@
|
|||
};
|
||||
[self.scrollView addSubview:_imageView];
|
||||
|
||||
_contentWrapperView = [[UIView alloc] init];
|
||||
[_imageView addSubview:_contentWrapperView];
|
||||
|
||||
_entitiesContainerView = [[TGPhotoEntitiesContainerView alloc] init];
|
||||
_entitiesContainerView.userInteractionEnabled = false;
|
||||
[_contentWrapperView addSubview:_entitiesContainerView];
|
||||
|
||||
_fileInfoLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 200, 20)];
|
||||
_fileInfoLabel.backgroundColor = [UIColor clearColor];
|
||||
_fileInfoLabel.font = TGSystemFontOfSize(13);
|
||||
_fileInfoLabel.textAlignment = NSTextAlignmentCenter;
|
||||
_fileInfoLabel.textColor = [UIColor whiteColor];
|
||||
|
||||
_adjustmentsDisposable = [[SMetaDisposable alloc] init];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[_adjustmentsDisposable dispose];
|
||||
[_attributesDisposable dispose];
|
||||
}
|
||||
|
||||
|
|
@ -106,6 +124,8 @@
|
|||
{
|
||||
[super setItem:item synchronously:synchronously];
|
||||
|
||||
_entitiesContainerView.stickersContext = item.stickersContext;
|
||||
|
||||
_imageSize = item.asset.originalSize;
|
||||
[self reset];
|
||||
|
||||
|
|
@ -175,6 +195,17 @@
|
|||
}];
|
||||
}
|
||||
}];
|
||||
|
||||
SSignal *adjustmentsSignal = [item.editingContext adjustmentsSignalForItem:item.editableMediaItem];
|
||||
[_adjustmentsDisposable setDisposable:[[adjustmentsSignal deliverOn:[SQueue mainQueue]] startWithNext:^(__unused id<TGMediaEditAdjustments> next)
|
||||
{
|
||||
__strong TGMediaPickerGalleryPhotoItemView *strongSelf = weakSelf;
|
||||
if (strongSelf == nil)
|
||||
return;
|
||||
|
||||
[strongSelf layoutEntities];
|
||||
[strongSelf->_entitiesContainerView setupWithPaintingData:next.paintingData];
|
||||
}]];
|
||||
}
|
||||
|
||||
if (item.immediateThumbnailImage != nil)
|
||||
|
|
@ -199,25 +230,6 @@
|
|||
strongSelf->_livePhotoView.frame = strongSelf->_imageView.frame;
|
||||
}]];
|
||||
|
||||
// if (item.asset.subtypes & TGMediaAssetSubtypePhotoLive)
|
||||
// {
|
||||
// _livePhotoView = [[PHLivePhotoView alloc] init];
|
||||
// _livePhotoView.muted = true;
|
||||
// _livePhotoView.contentMode = UIViewContentModeScaleAspectFill;
|
||||
// _livePhotoView.hidden = self.imageView.hidden;
|
||||
// _livePhotoView.frame = CGRectMake((self.containerView.frame.size.width - _imageSize.width) / 2.0f, (self.containerView.frame.size.height - _imageSize.height) / 2.0f, _imageSize.width, _imageSize.height);
|
||||
// [self.containerView addSubview:_livePhotoView];
|
||||
//
|
||||
// [[[TGMediaAssetImageSignals livePhotoForAsset:item.asset] deliverOn:[SQueue mainQueue]] startWithNext:^(PHLivePhoto *next)
|
||||
// {
|
||||
// __strong TGMediaPickerGalleryPhotoItemView *strongSelf = weakSelf;
|
||||
// if (strongSelf == nil)
|
||||
// return;
|
||||
//
|
||||
// strongSelf->_livePhotoView.livePhoto = next;
|
||||
// }];
|
||||
// }
|
||||
|
||||
if (!item.asFile)
|
||||
return;
|
||||
|
||||
|
|
@ -407,4 +419,55 @@
|
|||
}
|
||||
}
|
||||
|
||||
- (void)setFrame:(CGRect)frame {
|
||||
[super setFrame:frame];
|
||||
|
||||
[self layoutEntities];
|
||||
}
|
||||
|
||||
- (void)layoutEntities {
|
||||
if (self.item == nil) {
|
||||
return;
|
||||
}
|
||||
TGVideoEditAdjustments *adjustments = (TGVideoEditAdjustments *)[self.item.editingContext adjustmentsForItem:self.item.editableMediaItem];
|
||||
CGSize videoFrameSize = self.item.asset.originalSize;
|
||||
CGRect cropRect = CGRectMake(0, 0, videoFrameSize.width, videoFrameSize.height);
|
||||
UIImageOrientation orientation = UIImageOrientationUp;
|
||||
bool mirrored = false;
|
||||
if (adjustments != nil)
|
||||
{
|
||||
videoFrameSize = adjustments.cropRect.size;
|
||||
cropRect = adjustments.cropRect;
|
||||
orientation = adjustments.cropOrientation;
|
||||
mirrored = adjustments.cropMirrored;
|
||||
}
|
||||
|
||||
[self _layoutPlayerViewWithCropRect:cropRect videoFrameSize:videoFrameSize orientation:orientation mirrored:mirrored];
|
||||
}
|
||||
|
||||
- (void)_layoutPlayerViewWithCropRect:(CGRect)cropRect videoFrameSize:(CGSize)videoFrameSize orientation:(UIImageOrientation)orientation mirrored:(bool)mirrored
|
||||
{
|
||||
CGSize originalSize = self.item.asset.originalSize;
|
||||
CGRect rect = [TGPhotoPaintController fittedCropRect:cropRect originalSize:originalSize keepOriginalSize:true];
|
||||
_entitiesContainerView.frame = CGRectMake(0, 0, rect.size.width, rect.size.height);
|
||||
|
||||
CGSize fittedOriginalSize = TGScaleToSize(originalSize, [TGPhotoPaintController maximumPaintingSize]);
|
||||
CGSize rotatedSize = fittedOriginalSize;
|
||||
CGPoint centerPoint = CGPointMake(rotatedSize.width / 2.0f, rotatedSize.height / 2.0f);
|
||||
|
||||
CGFloat scale = fittedOriginalSize.width / originalSize.width;
|
||||
CGPoint offset = TGPaintSubtractPoints(centerPoint, [TGPhotoPaintController fittedCropRect:cropRect centerScale:scale]);
|
||||
|
||||
CGPoint boundsCenter = TGPaintCenterOfRect(_contentWrapperView.bounds);
|
||||
_entitiesContainerView.center = TGPaintAddPoints(boundsCenter, offset);
|
||||
|
||||
CGSize fittedContentSize = [TGPhotoPaintController fittedContentSize:cropRect orientation:UIImageOrientationUp originalSize:originalSize];
|
||||
CGRect fittedCropRect = [TGPhotoPaintController fittedCropRect:cropRect originalSize:originalSize keepOriginalSize:false];
|
||||
_contentWrapperView.frame = CGRectMake(0.0f, 0.0f, fittedContentSize.width, fittedContentSize.height);
|
||||
|
||||
CGFloat contentScale = _imageView.bounds.size.width / fittedCropRect.size.width;
|
||||
_contentWrapperView.transform = CGAffineTransformMakeScale(contentScale, contentScale);
|
||||
_contentWrapperView.frame = CGRectMake(0.0f, 0.0f, _imageView.bounds.size.width, _imageView.bounds.size.height);
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
|
||||
@synthesize selectionContext;
|
||||
@synthesize editingContext;
|
||||
@synthesize stickersContext;
|
||||
|
||||
- (CGSize)dimensions
|
||||
{
|
||||
|
|
|
|||
|
|
@ -30,6 +30,8 @@
|
|||
#import "TGMediaPickerScrubberHeaderView.h"
|
||||
|
||||
#import "TGPhotoEditorPreviewView.h"
|
||||
#import "TGPhotoEntitiesContainerView.h"
|
||||
#import "TGPhotoPaintController.h"
|
||||
|
||||
#import <LegacyComponents/TGModernGalleryVideoView.h>
|
||||
#import "TGModernGalleryVideoContentView.h"
|
||||
|
|
@ -69,11 +71,12 @@
|
|||
|
||||
UILabel *_fileInfoLabel;
|
||||
|
||||
// TGModernGalleryVideoView *_videoView;
|
||||
TGPhotoEditorPreviewView *_videoView;
|
||||
PGPhotoEditor *_photoEditor;
|
||||
|
||||
UIImageView *_paintingImageView;
|
||||
UIView *_contentWrapperView;
|
||||
TGPhotoEntitiesContainerView *_entitiesContainerView;
|
||||
|
||||
NSTimer *_positionTimer;
|
||||
TGObserverProxy *_didPlayToEndObserver;
|
||||
|
|
@ -101,8 +104,6 @@
|
|||
|
||||
bool _sendAsGif;
|
||||
bool _autoplayed;
|
||||
|
||||
bool _ignoreNextAdjustmentsChange;
|
||||
}
|
||||
|
||||
@property (nonatomic, strong) TGMediaPickerGalleryVideoItem *item;
|
||||
|
|
@ -149,6 +150,14 @@
|
|||
_paintingImageView = [[UIImageView alloc] init];
|
||||
[_playerContainerView addSubview:_paintingImageView];
|
||||
|
||||
_contentWrapperView = [[UIView alloc] init];
|
||||
[_playerContainerView addSubview:_contentWrapperView];
|
||||
|
||||
_entitiesContainerView = [[TGPhotoEntitiesContainerView alloc] init];
|
||||
_entitiesContainerView.hidden = true;
|
||||
_entitiesContainerView.userInteractionEnabled = false;
|
||||
[_contentWrapperView addSubview:_entitiesContainerView];
|
||||
|
||||
_curtainView = [[UIView alloc] init];
|
||||
_curtainView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
|
||||
_curtainView.backgroundColor = [UIColor blackColor];
|
||||
|
|
@ -363,6 +372,7 @@
|
|||
|
||||
_scrubberView.allowsTrimming = false;
|
||||
_videoDimensions = item.dimensions;
|
||||
_entitiesContainerView.stickersContext = item.stickersContext;
|
||||
|
||||
__weak TGMediaPickerGalleryVideoItemView *weakSelf = self;
|
||||
[_videoDurationVar set:[[[item.durationSignal deliverOn:[SQueue mainQueue]] catch:^SSignal *(__unused id error)
|
||||
|
|
@ -427,23 +437,21 @@
|
|||
if (strongSelf == nil)
|
||||
return;
|
||||
|
||||
if (!strongSelf->_ignoreNextAdjustmentsChange)
|
||||
{
|
||||
[strongSelf _layoutPlayerView];
|
||||
TGVideoEditAdjustments *adjustments = (TGVideoEditAdjustments *)[strongSelf.item.editingContext adjustmentsForItem:strongSelf.item.editableMediaItem];
|
||||
strongSelf->_paintingImageView.image = adjustments.paintingData.image;
|
||||
|
||||
strongSelf->_sendAsGif = adjustments.sendAsGif;
|
||||
[strongSelf _mutePlayer:adjustments.sendAsGif];
|
||||
|
||||
if (adjustments.sendAsGif || ([strongSelf itemIsLivePhoto]))
|
||||
[strongSelf setPlayButtonHidden:true animated:false];
|
||||
|
||||
[_photoEditor importAdjustments:adjustments];
|
||||
}
|
||||
else
|
||||
{
|
||||
strongSelf->_ignoreNextAdjustmentsChange = false;
|
||||
[strongSelf _layoutPlayerView];
|
||||
TGVideoEditAdjustments *adjustments = (TGVideoEditAdjustments *)[strongSelf.item.editingContext adjustmentsForItem:strongSelf.item.editableMediaItem];
|
||||
strongSelf->_paintingImageView.image = adjustments.paintingData.image;
|
||||
|
||||
strongSelf->_sendAsGif = adjustments.sendAsGif;
|
||||
[strongSelf _mutePlayer:adjustments.sendAsGif];
|
||||
|
||||
if (adjustments.sendAsGif || ([strongSelf itemIsLivePhoto]))
|
||||
[strongSelf setPlayButtonHidden:true animated:false];
|
||||
|
||||
[strongSelf->_entitiesContainerView setupWithPaintingData:adjustments.paintingData];
|
||||
[strongSelf->_photoEditor importAdjustments:adjustments];
|
||||
|
||||
if (!strongSelf.isPlaying) {
|
||||
[strongSelf->_photoEditor reprocess];
|
||||
}
|
||||
}]];
|
||||
}
|
||||
|
|
@ -740,6 +748,27 @@
|
|||
_imageView.frame = CGRectMake(-cropRect.origin.x * ratio, -cropRect.origin.y * ratio, _videoDimensions.width * ratio, _videoDimensions.height * ratio);
|
||||
_paintingImageView.frame = _imageView.frame;
|
||||
_videoView.frame = _imageView.frame;
|
||||
|
||||
CGRect rect = [TGPhotoPaintController fittedCropRect:cropRect originalSize:_videoDimensions keepOriginalSize:true];
|
||||
_entitiesContainerView.frame = CGRectMake(0, 0, rect.size.width, rect.size.height);
|
||||
|
||||
CGSize fittedOriginalSize = TGScaleToSize(_videoDimensions, [TGPhotoPaintController maximumPaintingSize]);
|
||||
CGSize rotatedSize = fittedOriginalSize;
|
||||
CGPoint centerPoint = CGPointMake(rotatedSize.width / 2.0f, rotatedSize.height / 2.0f);
|
||||
|
||||
CGFloat scale = fittedOriginalSize.width / _videoDimensions.width;
|
||||
CGPoint offset = TGPaintSubtractPoints(centerPoint, [TGPhotoPaintController fittedCropRect:cropRect centerScale:scale]);
|
||||
|
||||
CGPoint boundsCenter = TGPaintCenterOfRect(_contentWrapperView.bounds);
|
||||
_entitiesContainerView.center = TGPaintAddPoints(boundsCenter, offset);
|
||||
|
||||
CGSize fittedContentSize = [TGPhotoPaintController fittedContentSize:cropRect orientation:UIImageOrientationUp originalSize:_videoDimensions];
|
||||
CGRect fittedCropRect = [TGPhotoPaintController fittedCropRect:cropRect originalSize:_videoDimensions keepOriginalSize:false];
|
||||
_contentWrapperView.frame = CGRectMake(0.0f, 0.0f, fittedContentSize.width, fittedContentSize.height);
|
||||
|
||||
CGFloat contentScale = _playerWrapperView.bounds.size.width / fittedCropRect.size.width;
|
||||
_contentWrapperView.transform = CGAffineTransformMakeScale(contentScale, contentScale);
|
||||
_contentWrapperView.frame = CGRectMake(0.0f, 0.0f, _playerWrapperView.bounds.size.width, _playerWrapperView.bounds.size.height);
|
||||
}
|
||||
|
||||
- (void)singleTap
|
||||
|
|
@ -752,8 +781,10 @@
|
|||
{
|
||||
[super setIsVisible:isVisible];
|
||||
|
||||
if (!isVisible && _player != nil)
|
||||
if (!isVisible && _player != nil) {
|
||||
[self stopPlayer];
|
||||
[self setPlayButtonHidden:false animated:false];
|
||||
}
|
||||
}
|
||||
|
||||
- (UIView *)headerView
|
||||
|
|
@ -783,13 +814,12 @@
|
|||
{
|
||||
if (_videoView != nil)
|
||||
{
|
||||
UIImage *image = nil;
|
||||
|
||||
UIGraphicsBeginImageContextWithOptions(_videoView.bounds.size, true, [UIScreen mainScreen].scale);
|
||||
|
||||
if (_lastRenderedScreenImage != nil)
|
||||
return _lastRenderedScreenImage;
|
||||
|
||||
UIImage *image = nil;
|
||||
|
||||
UIGraphicsBeginImageContextWithOptions(_videoView.bounds.size, true, [UIScreen mainScreen].scale);
|
||||
AVAssetImageGenerator *generator = [[AVAssetImageGenerator alloc] initWithAsset:_player.currentItem.asset];
|
||||
generator.appliesPreferredTrackTransform = true;
|
||||
generator.maximumSize = TGFitSize(_videoDimensions, CGSizeMake(1280.0f, 1280.0f));
|
||||
|
|
@ -826,11 +856,16 @@
|
|||
generator.requestedTimeToleranceBefore = kCMTimeZero;
|
||||
CGImageRef imageRef = [generator copyCGImageAtTime:_player.currentTime actualTime:nil error:NULL];
|
||||
|
||||
_lastRenderedScreenImage = [UIImage imageWithCGImage:imageRef];
|
||||
CGImageRelease(imageRef);
|
||||
|
||||
TGVideoEditAdjustments *adjustments = (TGVideoEditAdjustments *)[self.item.editingContext adjustmentsForItem:self.item.editableMediaItem];
|
||||
|
||||
UIImage *renderedImage = [UIImage imageWithCGImage:imageRef];
|
||||
CGImageRelease(imageRef);
|
||||
|
||||
if (adjustments.toolsApplied) {
|
||||
renderedImage = [PGPhotoEditor resultImageForImage:renderedImage adjustments:adjustments];
|
||||
}
|
||||
_lastRenderedScreenImage = renderedImage;
|
||||
|
||||
CGSize originalSize = _videoDimensions;
|
||||
CGRect cropRect = CGRectMake(0, 0, _videoDimensions.width, _videoDimensions.height);
|
||||
UIImageOrientation cropOrientation = UIImageOrientationUp;
|
||||
|
|
@ -846,7 +881,7 @@
|
|||
|
||||
CGRect drawRect = CGRectMake(-cropRect.origin.x * ratio, -cropRect.origin.y * ratio, originalSize.width * ratio, originalSize.height * ratio);
|
||||
[_lastRenderedScreenImage drawInRect:drawRect];
|
||||
|
||||
|
||||
if (_paintingImageView.image != nil)
|
||||
[_paintingImageView.image drawInRect:drawRect];
|
||||
}
|
||||
|
|
@ -994,6 +1029,8 @@
|
|||
// };
|
||||
// }
|
||||
// [_videoView cleanupPlayer];
|
||||
_photoEditor.previewOutput = nil;
|
||||
|
||||
[_videoView removeFromSuperview];
|
||||
_videoView = nil;
|
||||
|
||||
|
|
@ -1054,23 +1091,20 @@
|
|||
}
|
||||
|
||||
strongSelf->_didPlayToEndObserver = [[TGObserverProxy alloc] initWithTarget:strongSelf targetSelector:@selector(playerItemDidPlayToEndTime:) name:AVPlayerItemDidPlayToEndTimeNotification object:playerItem];
|
||||
|
||||
// strongSelf->_videoView = [[TGModernGalleryVideoView alloc] initWithFrame:strongSelf->_playerView.bounds player:strongSelf->_player];
|
||||
// strongSelf->_videoView.frame = strongSelf->_imageView.frame;
|
||||
// strongSelf->_videoView.playerLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
|
||||
// strongSelf->_videoView.playerLayer.opaque = false;
|
||||
// strongSelf->_videoView.playerLayer.backgroundColor = nil;
|
||||
// [strongSelf->_playerContainerView insertSubview:strongSelf->_videoView belowSubview:strongSelf->_paintingImageView];
|
||||
|
||||
|
||||
TGVideoEditAdjustments *adjustments = (TGVideoEditAdjustments *)[strongSelf.item.editingContext adjustmentsForItem:strongSelf.item.editableMediaItem];
|
||||
|
||||
strongSelf->_videoView = [[TGPhotoEditorPreviewView alloc] initWithFrame:strongSelf->_imageView.frame];
|
||||
strongSelf->_videoView.customTouchDownHandling = true;
|
||||
strongSelf->_videoView.userInteractionEnabled = false;
|
||||
[strongSelf->_playerContainerView insertSubview:strongSelf->_videoView belowSubview:strongSelf->_paintingImageView];
|
||||
|
||||
strongSelf->_entitiesContainerView.hidden = false;
|
||||
|
||||
[strongSelf->_videoView setNeedsTransitionIn];
|
||||
[strongSelf->_videoView performTransitionInIfNeeded];
|
||||
|
||||
strongSelf->_photoEditor = [[PGPhotoEditor alloc] initWithOriginalSize:_videoDimensions adjustments:adjustments forVideo:true enableStickers:true];
|
||||
strongSelf->_photoEditor = [[PGPhotoEditor alloc] initWithOriginalSize:strongSelf->_videoDimensions adjustments:adjustments forVideo:true enableStickers:true];
|
||||
strongSelf->_photoEditor.previewOutput = strongSelf->_videoView;
|
||||
[strongSelf->_photoEditor setPlayerItem:playerItem];
|
||||
[strongSelf->_photoEditor processAnimated:false completion:nil];
|
||||
|
|
@ -1229,12 +1263,17 @@
|
|||
_wasPlayingBeforeScrubbing = self.isPlaying;
|
||||
|
||||
[self pausePressed];
|
||||
|
||||
[self setPlayButtonHidden:true animated:false];
|
||||
}
|
||||
|
||||
- (void)videoScrubberDidEndScrubbing:(TGMediaPickerGalleryVideoScrubber *)__unused videoScrubber
|
||||
{
|
||||
if (_wasPlayingBeforeScrubbing)
|
||||
if (_wasPlayingBeforeScrubbing) {
|
||||
[self play];
|
||||
} else {
|
||||
[self setPlayButtonHidden:false animated:true];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)videoScrubber:(TGMediaPickerGalleryVideoScrubber *)__unused videoScrubber valueDidChange:(NSTimeInterval)position
|
||||
|
|
@ -1260,6 +1299,8 @@
|
|||
[self preparePlayerAndPlay:false];
|
||||
|
||||
[self pausePressed];
|
||||
|
||||
[self setPlayButtonHidden:true animated:false];
|
||||
}
|
||||
|
||||
- (void)videoScrubberDidEndEditing:(TGMediaPickerGalleryVideoScrubber *)__unused videoScrubber
|
||||
|
|
@ -1267,6 +1308,8 @@
|
|||
_shouldResetScrubber = false;
|
||||
[self updatePlayerRange:videoScrubber.trimEndValue];
|
||||
[self updateEditAdjusments];
|
||||
|
||||
[self setPlayButtonHidden:false animated:true];
|
||||
}
|
||||
|
||||
- (void)videoScrubber:(TGMediaPickerGalleryVideoScrubber *)__unused videoScrubber editingStartValueDidChange:(NSTimeInterval)startValue
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
@interface TGMediaPickerModernGalleryMixin ()
|
||||
{
|
||||
TGMediaEditingContext *_editingContext;
|
||||
id<TGPhotoPaintStickersContext> _stickersContext;
|
||||
bool _asFile;
|
||||
|
||||
__weak TGViewController *_parentController;
|
||||
|
|
@ -59,6 +60,7 @@
|
|||
_context = context;
|
||||
_parentController = parentController;
|
||||
_editingContext = asFile ? nil : editingContext;
|
||||
_stickersContext = asFile? nil : stickersContext;
|
||||
_asFile = asFile;
|
||||
_itemsLimit = itemsLimit;
|
||||
|
||||
|
|
@ -81,7 +83,7 @@
|
|||
}
|
||||
};
|
||||
|
||||
NSArray *galleryItems = fetchResult != nil ? [self prepareGalleryItemsForFetchResult:fetchResult selectionContext:selectionContext editingContext:editingContext asFile:asFile enumerationBlock:enumerationBlock] : [self prepareGalleryItemsForMomentList:momentList selectionContext:selectionContext editingContext:editingContext asFile:asFile enumerationBlock:enumerationBlock];
|
||||
NSArray *galleryItems = [self prepareGalleryItemsForFetchResult:fetchResult selectionContext:selectionContext editingContext:editingContext stickersContext:stickersContext asFile:asFile enumerationBlock:enumerationBlock];
|
||||
|
||||
TGMediaPickerGalleryModel *model = [[TGMediaPickerGalleryModel alloc] initWithContext:[_windowManager context] items:galleryItems focusItem:focusItem selectionContext:selectionContext editingContext:editingContext hasCaptions:hasCaptions allowCaptionEntities:allowCaptionEntities hasTimer:hasTimer onlyCrop:onlyCrop inhibitDocumentCaptions:inhibitDocumentCaptions hasSelectionPanel:true hasCamera:false recipientName:recipientName];
|
||||
_galleryModel = model;
|
||||
|
|
@ -312,7 +314,7 @@
|
|||
}
|
||||
|
||||
__block id<TGModernGalleryItem> focusItem = nil;
|
||||
NSArray *galleryItems = [self prepareGalleryItemsForFetchResult:fetchResult selectionContext:_galleryModel.selectionContext editingContext:_editingContext asFile:_asFile enumerationBlock:^(TGMediaPickerGalleryItem *item)
|
||||
NSArray *galleryItems = [self prepareGalleryItemsForFetchResult:fetchResult selectionContext:_galleryModel.selectionContext editingContext:_editingContext stickersContext:_stickersContext asFile:_asFile enumerationBlock:^(TGMediaPickerGalleryItem *item)
|
||||
{
|
||||
if (focusItem == nil && [item isEqual:_galleryController.currentItem])
|
||||
focusItem = item;
|
||||
|
|
@ -321,7 +323,7 @@
|
|||
[_galleryModel _replaceItems:galleryItems focusingOnItem:focusItem];
|
||||
}
|
||||
|
||||
- (NSArray *)prepareGalleryItemsForFetchResult:(TGMediaAssetFetchResult *)fetchResult selectionContext:(TGMediaSelectionContext *)selectionContext editingContext:(TGMediaEditingContext *)editingContext asFile:(bool)asFile enumerationBlock:(void (^)(TGMediaPickerGalleryItem *))enumerationBlock
|
||||
- (NSArray *)prepareGalleryItemsForFetchResult:(TGMediaAssetFetchResult *)fetchResult selectionContext:(TGMediaSelectionContext *)selectionContext editingContext:(TGMediaEditingContext *)editingContext stickersContext:(id<TGPhotoPaintStickersContext>)stickersContext asFile:(bool)asFile enumerationBlock:(void (^)(TGMediaPickerGalleryItem *))enumerationBlock
|
||||
{
|
||||
NSMutableArray *galleryItems = [[NSMutableArray alloc] init];
|
||||
|
||||
|
|
@ -350,16 +352,14 @@
|
|||
|
||||
default:
|
||||
{
|
||||
if (false && asset.subtypes & TGMediaAssetSubtypePhotoLive)
|
||||
galleryItem = [[TGMediaPickerGalleryVideoItem alloc] initWithAsset:asset];
|
||||
else
|
||||
galleryItem = [[TGMediaPickerGalleryPhotoItem alloc] initWithAsset:asset];
|
||||
galleryItem = [[TGMediaPickerGalleryPhotoItem alloc] initWithAsset:asset];
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
galleryItem.selectionContext = selectionContext;
|
||||
galleryItem.editingContext = editingContext;
|
||||
galleryItem.stickersContext = stickersContext;
|
||||
|
||||
if (enumerationBlock != nil)
|
||||
enumerationBlock(galleryItem);
|
||||
|
|
@ -373,65 +373,6 @@
|
|||
return galleryItems;
|
||||
}
|
||||
|
||||
- (NSArray *)prepareGalleryItemsForMomentList:(TGMediaAssetMomentList *)momentList selectionContext:(TGMediaSelectionContext *)selectionContext editingContext:(TGMediaEditingContext *)editingContext asFile:(bool)asFile enumerationBlock:(void (^)(TGMediaPickerGalleryItem *))enumerationBlock
|
||||
{
|
||||
NSMutableArray *galleryItems = [[NSMutableArray alloc] init];
|
||||
|
||||
for (NSUInteger i = 0; i < momentList.count; i++)
|
||||
{
|
||||
TGMediaAssetMoment *moment = momentList[i];
|
||||
|
||||
for (NSUInteger k = 0; k < moment.assetCount; k++)
|
||||
{
|
||||
TGMediaAsset *asset = [moment.fetchResult assetAtIndex:k];
|
||||
|
||||
TGMediaPickerGalleryItem *galleryItem = nil;
|
||||
switch (asset.type)
|
||||
{
|
||||
case TGMediaAssetVideoType:
|
||||
{
|
||||
TGMediaPickerGalleryVideoItem *videoItem = [[TGMediaPickerGalleryVideoItem alloc] initWithAsset:asset];
|
||||
videoItem.selectionContext = selectionContext;
|
||||
videoItem.editingContext = editingContext;
|
||||
|
||||
galleryItem = videoItem;
|
||||
}
|
||||
break;
|
||||
|
||||
case TGMediaAssetGifType:
|
||||
{
|
||||
TGMediaPickerGalleryGifItem *gifItem = [[TGMediaPickerGalleryGifItem alloc] initWithAsset:asset];
|
||||
gifItem.selectionContext = selectionContext;
|
||||
gifItem.editingContext = editingContext;
|
||||
|
||||
galleryItem = gifItem;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
TGMediaPickerGalleryPhotoItem *photoItem = [[TGMediaPickerGalleryPhotoItem alloc] initWithAsset:asset];
|
||||
photoItem.selectionContext = selectionContext;
|
||||
photoItem.editingContext = editingContext;
|
||||
|
||||
galleryItem = photoItem;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (enumerationBlock != nil)
|
||||
enumerationBlock(galleryItem);
|
||||
|
||||
galleryItem.asFile = asFile;
|
||||
|
||||
if (galleryItem != nil)
|
||||
[galleryItems addObject:galleryItem];
|
||||
}
|
||||
}
|
||||
|
||||
return galleryItems;
|
||||
}
|
||||
|
||||
- (void)setThumbnailSignalForItem:(SSignal *(^)(id))thumbnailSignalForItem
|
||||
{
|
||||
[_galleryModel.interfaceView setThumbnailSignalForItem:thumbnailSignalForItem];
|
||||
|
|
|
|||
|
|
@ -139,6 +139,16 @@
|
|||
return [stickers allObjects];
|
||||
}
|
||||
|
||||
- (bool)hasAnimation
|
||||
{
|
||||
for (TGPhotoPaintEntity *entity in self.entities)
|
||||
{
|
||||
if ([entity isKindOfClass:[TGPhotoPaintStickerEntity class]] && ((TGPhotoPaintStickerEntity *)entity).animated)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
- (BOOL)isEqual:(id)object
|
||||
{
|
||||
if (object == self)
|
||||
|
|
|
|||
|
|
@ -39,7 +39,6 @@
|
|||
#import "TGPhotoToolsController.h"
|
||||
#import "TGPhotoPaintController.h"
|
||||
#import "TGPhotoQualityController.h"
|
||||
#import "TGPhotoEditorItemController.h"
|
||||
|
||||
#import "TGMessageImageViewOverlayView.h"
|
||||
|
||||
|
|
@ -587,6 +586,7 @@
|
|||
|
||||
bool hasImageAdjustments = editorValues.toolsApplied || saveOnly;
|
||||
bool hasPainting = editorValues.hasPainting;
|
||||
bool hasAnimation = editorValues.paintingData.hasAnimation;
|
||||
|
||||
SSignal *(^imageCropSignal)(UIImage *, bool) = ^(UIImage *image, bool resize)
|
||||
{
|
||||
|
|
@ -647,14 +647,14 @@
|
|||
{
|
||||
if (!hasImageAdjustments)
|
||||
{
|
||||
if (hasPainting && self.didFinishRenderingFullSizeImage != nil)
|
||||
if (hasPainting && !hasAnimation && self.didFinishRenderingFullSizeImage != nil)
|
||||
self.didFinishRenderingFullSizeImage(image);
|
||||
|
||||
return image;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!saveOnly && self.didFinishRenderingFullSizeImage != nil)
|
||||
if (!saveOnly && !hasAnimation && self.didFinishRenderingFullSizeImage != nil)
|
||||
self.didFinishRenderingFullSizeImage(image);
|
||||
|
||||
return TGPhotoEditorFitImage(image, TGPhotoEditorResultImageMaxSize);
|
||||
|
|
|
|||
|
|
@ -1,26 +0,0 @@
|
|||
#import <LegacyComponents/TGViewController.h>
|
||||
|
||||
#import "PGPhotoEditorItem.h"
|
||||
|
||||
@class PGPhotoEditor;
|
||||
@class TGPhotoEditorPreviewView;
|
||||
|
||||
@interface TGPhotoEditorItemController : TGViewController
|
||||
|
||||
@property (nonatomic, copy) void(^editorItemUpdated)(void);
|
||||
@property (nonatomic, copy) void(^beginTransitionIn)(void);
|
||||
@property (nonatomic, copy) void(^beginTransitionOut)(void);
|
||||
@property (nonatomic, copy) void(^finishedCombinedTransition)(void);
|
||||
|
||||
@property (nonatomic, assign) CGFloat toolbarLandscapeSize;
|
||||
@property (nonatomic, assign) bool initialAppearance;
|
||||
@property (nonatomic, assign) bool skipProcessingOnCompletion;
|
||||
|
||||
- (instancetype)initWithContext:(id<LegacyComponentsContext>)context editorItem:(id<PGPhotoEditorItem>)editorItem photoEditor:(PGPhotoEditor *)photoEditor previewView:(TGPhotoEditorPreviewView *)previewView;
|
||||
|
||||
- (void)attachPreviewView:(TGPhotoEditorPreviewView *)previewView;
|
||||
|
||||
- (void)prepareForCombinedAppearance;
|
||||
- (void)finishedCombinedAppearance;
|
||||
|
||||
@end
|
||||
|
|
@ -1,701 +0,0 @@
|
|||
#import "TGPhotoEditorItemController.h"
|
||||
|
||||
#import "LegacyComponentsInternal.h"
|
||||
#import "TGImageUtils.h"
|
||||
|
||||
#import "TGPhotoEditorTabController.h"
|
||||
|
||||
#import <LegacyComponents/TGPhotoEditorUtils.h>
|
||||
|
||||
#import "PGPhotoEditor.h"
|
||||
#import "PGPhotoEditorItem.h"
|
||||
#import "PGPhotoFilter.h"
|
||||
#import "PGPhotoTool.h"
|
||||
|
||||
#import "TGPhotoEditorPreviewView.h"
|
||||
#import "TGPhotoEditorToolButtonsView.h"
|
||||
|
||||
#import <LegacyComponents/TGPhotoEditorAnimation.h>
|
||||
#import "TGPhotoEditorInterfaceAssets.h"
|
||||
|
||||
@interface TGPhotoEditorItemController () <TGViewControllerNavigationBarAppearance>
|
||||
{
|
||||
id<PGPhotoEditorItem> _editorItem;
|
||||
|
||||
UIView *_wrapperView;
|
||||
UIView *_portraitToolsWrapperView;
|
||||
UIView *_landscapeToolsWrapperView;
|
||||
|
||||
UIView <TGPhotoEditorToolView> *_toolAreaView;
|
||||
UIView <TGPhotoEditorToolView> *_portraitToolControlView;
|
||||
UIView <TGPhotoEditorToolView> *_landscapeToolControlView;
|
||||
|
||||
TGPhotoEditorToolButtonsView *_portraitButtonsView;
|
||||
TGPhotoEditorToolButtonsView *_landscapeButtonsView;
|
||||
|
||||
UIView *_initialPreviewSuperview;
|
||||
bool _dismissing;
|
||||
bool _animating;
|
||||
|
||||
bool _enhanceInitialAppearance;
|
||||
}
|
||||
|
||||
@property (nonatomic, weak) PGPhotoEditor *photoEditor;
|
||||
@property (nonatomic, weak) TGPhotoEditorPreviewView *previewView;
|
||||
|
||||
@end
|
||||
|
||||
@implementation TGPhotoEditorItemController
|
||||
|
||||
- (instancetype)initWithContext:(id<LegacyComponentsContext>)context editorItem:(id<PGPhotoEditorItem>)editorItem photoEditor:(PGPhotoEditor *)photoEditor previewView:(TGPhotoEditorPreviewView *)previewView
|
||||
{
|
||||
self = [super initWithContext:context];
|
||||
if (self != nil)
|
||||
{
|
||||
_editorItem = editorItem;
|
||||
_editorItem.beingEdited = true;
|
||||
_editorItem.tempValue = [_editorItem.value copy];
|
||||
|
||||
self.photoEditor = photoEditor;
|
||||
self.previewView = previewView;
|
||||
|
||||
_initialPreviewSuperview = previewView.superview;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
TGPhotoEditorPreviewView *previewView = self.previewView;
|
||||
previewView.touchedDown = nil;
|
||||
previewView.touchedUp = nil;
|
||||
}
|
||||
|
||||
- (void)loadView
|
||||
{
|
||||
[super loadView];
|
||||
|
||||
__weak TGPhotoEditorItemController *weakSelf = self;
|
||||
void(^interactionEnded)(void) = ^
|
||||
{
|
||||
__strong TGPhotoEditorItemController *strongSelf = weakSelf;
|
||||
if (strongSelf == nil)
|
||||
return;
|
||||
|
||||
if ([strongSelf shouldAutorotate])
|
||||
[TGViewController attemptAutorotation];
|
||||
};
|
||||
|
||||
_wrapperView = [[UIView alloc] initWithFrame:CGRectZero];
|
||||
_wrapperView.alpha = 0.0f;
|
||||
_wrapperView.backgroundColor = [UIColor blackColor];
|
||||
[self.view addSubview:_wrapperView];
|
||||
|
||||
TGPhotoEditorPreviewView *previewView = self.previewView;
|
||||
if (previewView != nil)
|
||||
[self attachPreviewView:previewView];
|
||||
|
||||
PGPhotoEditor *photoEditor = self.photoEditor;
|
||||
|
||||
_toolAreaView = [_editorItem itemAreaViewWithChangeBlock:^(id __unused newValue)
|
||||
{
|
||||
__strong TGPhotoEditorItemController *strongSelf = weakSelf;
|
||||
if (strongSelf == nil)
|
||||
return;
|
||||
|
||||
[strongSelf->_portraitToolControlView setValue:newValue];
|
||||
[strongSelf->_landscapeToolControlView setValue:newValue];
|
||||
|
||||
PGPhotoEditor *photoEditor = strongSelf.photoEditor;
|
||||
[photoEditor processAnimated:false completion:nil];
|
||||
}];
|
||||
_toolAreaView.interactionEnded = interactionEnded;
|
||||
|
||||
if (_toolAreaView != nil)
|
||||
[self.view addSubview:_toolAreaView];
|
||||
|
||||
_portraitToolsWrapperView = [[UIView alloc] initWithFrame:CGRectZero];
|
||||
[_wrapperView addSubview:_portraitToolsWrapperView];
|
||||
|
||||
_landscapeToolsWrapperView = [[UIView alloc] initWithFrame:CGRectZero];
|
||||
[_wrapperView addSubview:_landscapeToolsWrapperView];
|
||||
|
||||
_portraitToolControlView = [_editorItem itemControlViewWithChangeBlock:^(id newValue, bool animated)
|
||||
{
|
||||
__strong TGPhotoEditorItemController *strongSelf = weakSelf;
|
||||
if (strongSelf == nil)
|
||||
return;
|
||||
|
||||
[strongSelf->_toolAreaView setValue:newValue];
|
||||
[strongSelf->_landscapeToolControlView setValue:newValue];
|
||||
|
||||
PGPhotoEditor *photoEditor = strongSelf.photoEditor;
|
||||
[photoEditor processAnimated:animated completion:nil];
|
||||
}];
|
||||
_portraitToolControlView.backgroundColor = [TGPhotoEditorInterfaceAssets panelBackgroundColor];
|
||||
_portraitToolControlView.clipsToBounds = true;
|
||||
_portraitToolControlView.interactionEnded = interactionEnded;
|
||||
_portraitToolControlView.layer.rasterizationScale = TGScreenScaling();
|
||||
_portraitToolControlView.isLandscape = false;
|
||||
|
||||
if ([_portraitToolControlView respondsToSelector:@selector(setHistogramSignal:)])
|
||||
[_portraitToolControlView setHistogramSignal:photoEditor.histogramSignal];
|
||||
|
||||
[_portraitToolsWrapperView addSubview:_portraitToolControlView];
|
||||
|
||||
_landscapeToolControlView = [_editorItem itemControlViewWithChangeBlock:^(id newValue, bool animated)
|
||||
{
|
||||
__strong TGPhotoEditorItemController *strongSelf = weakSelf;
|
||||
if (strongSelf == nil)
|
||||
return;
|
||||
|
||||
[strongSelf->_toolAreaView setValue:newValue];
|
||||
[strongSelf->_portraitToolControlView setValue:newValue];
|
||||
|
||||
PGPhotoEditor *photoEditor = strongSelf.photoEditor;
|
||||
[photoEditor processAnimated:animated completion:nil];
|
||||
}];
|
||||
_landscapeToolControlView.backgroundColor = [TGPhotoEditorInterfaceAssets panelBackgroundColor];
|
||||
_landscapeToolControlView.clipsToBounds = true;
|
||||
_landscapeToolControlView.interactionEnded = interactionEnded;
|
||||
_landscapeToolControlView.layer.rasterizationScale = TGScreenScaling();
|
||||
_landscapeToolControlView.isLandscape = true;
|
||||
_landscapeToolControlView.toolbarLandscapeSize = self.toolbarLandscapeSize;
|
||||
|
||||
if ([UIDevice currentDevice].userInterfaceIdiom != UIUserInterfaceIdiomPad)
|
||||
{
|
||||
if ([_landscapeToolControlView respondsToSelector:@selector(setHistogramSignal:)])
|
||||
[_landscapeToolControlView setHistogramSignal:photoEditor.histogramSignal];
|
||||
|
||||
[_landscapeToolsWrapperView addSubview:_landscapeToolControlView];
|
||||
}
|
||||
|
||||
void(^cancelPressed)(void) = ^
|
||||
{
|
||||
__strong TGPhotoEditorItemController *strongSelf = weakSelf;
|
||||
if (strongSelf == nil)
|
||||
return;
|
||||
|
||||
if (strongSelf->_toolAreaView.isTracking || strongSelf->_portraitToolControlView.isTracking || strongSelf->_landscapeToolControlView.isTracking || strongSelf->_animating)
|
||||
return;
|
||||
|
||||
|
||||
if (![strongSelf->_portraitToolControlView buttonPressed:true])
|
||||
return;
|
||||
|
||||
strongSelf->_editorItem.beingEdited = false;
|
||||
strongSelf->_editorItem.tempValue = nil;
|
||||
|
||||
[strongSelf transitionOutWithCompletion:^
|
||||
{
|
||||
[strongSelf removeFromParentViewController];
|
||||
[strongSelf.view removeFromSuperview];
|
||||
}];
|
||||
|
||||
PGPhotoEditor *photoEditor = strongSelf.photoEditor;
|
||||
[photoEditor processAnimated:false completion:nil];
|
||||
};
|
||||
|
||||
void(^confirmPressed)(void) = ^
|
||||
{
|
||||
__strong TGPhotoEditorItemController *strongSelf = weakSelf;
|
||||
if (strongSelf == nil)
|
||||
return;
|
||||
|
||||
if (strongSelf->_toolAreaView.isTracking || strongSelf->_portraitToolControlView.isTracking || strongSelf->_landscapeToolControlView.isTracking || strongSelf->_animating)
|
||||
return;
|
||||
|
||||
if (![strongSelf->_portraitToolControlView buttonPressed:false])
|
||||
return;
|
||||
|
||||
id value = strongSelf->_editorItem.tempValue;
|
||||
if ([value conformsToProtocol:@protocol(PGCustomToolValue)])
|
||||
value = [(id<PGCustomToolValue>)value cleanValue];
|
||||
|
||||
strongSelf->_editorItem.value = value;
|
||||
strongSelf->_editorItem.beingEdited = false;
|
||||
strongSelf->_editorItem.tempValue = nil;
|
||||
|
||||
if (strongSelf.editorItemUpdated != nil)
|
||||
strongSelf.editorItemUpdated();
|
||||
|
||||
[strongSelf transitionOutWithCompletion:^
|
||||
{
|
||||
[strongSelf removeFromParentViewController];
|
||||
[strongSelf.view removeFromSuperview];
|
||||
}];
|
||||
};
|
||||
|
||||
NSString *cancelButton = TGLocalized(@"Common.Cancel");
|
||||
if (self.initialAppearance)
|
||||
cancelButton = TGLocalized(@"PhotoEditor.Skip");
|
||||
NSString *doneButton = TGLocalized(@"PhotoEditor.Set");
|
||||
|
||||
_portraitButtonsView = [[TGPhotoEditorToolButtonsView alloc] initWithCancelButton:cancelButton doneButton:doneButton];
|
||||
_portraitButtonsView.cancelPressed = cancelPressed;
|
||||
_portraitButtonsView.confirmPressed = confirmPressed;
|
||||
[_portraitToolsWrapperView addSubview:_portraitButtonsView];
|
||||
|
||||
_landscapeButtonsView = [[TGPhotoEditorToolButtonsView alloc] initWithCancelButton:cancelButton doneButton:doneButton];
|
||||
_landscapeButtonsView.cancelPressed = cancelPressed;
|
||||
_landscapeButtonsView.confirmPressed = confirmPressed;
|
||||
[_landscapeToolsWrapperView addSubview:_landscapeButtonsView];
|
||||
}
|
||||
|
||||
- (void)attachPreviewView:(TGPhotoEditorPreviewView *)previewView
|
||||
{
|
||||
self.previewView = previewView;
|
||||
_initialPreviewSuperview = previewView.superview;
|
||||
[self.view insertSubview:previewView aboveSubview:_wrapperView];
|
||||
|
||||
__weak TGPhotoEditorItemController *weakSelf = self;
|
||||
void(^interactionEnded)(void) = ^
|
||||
{
|
||||
__strong TGPhotoEditorItemController *strongSelf = weakSelf;
|
||||
if (strongSelf == nil)
|
||||
return;
|
||||
|
||||
if ([strongSelf shouldAutorotate])
|
||||
[TGViewController attemptAutorotation];
|
||||
};
|
||||
|
||||
previewView.touchedDown = ^
|
||||
{
|
||||
__strong TGPhotoEditorItemController *strongSelf = weakSelf;
|
||||
if (strongSelf == nil)
|
||||
return;
|
||||
|
||||
strongSelf->_editorItem.beingEdited = false;
|
||||
|
||||
PGPhotoEditor *photoEditor = strongSelf->_photoEditor;
|
||||
[photoEditor processAnimated:false completion:nil];
|
||||
};
|
||||
|
||||
previewView.touchedUp = ^
|
||||
{
|
||||
__strong TGPhotoEditorItemController *strongSelf = weakSelf;
|
||||
if (strongSelf == nil)
|
||||
return;
|
||||
|
||||
strongSelf->_editorItem.beingEdited = true;
|
||||
|
||||
PGPhotoEditor *photoEditor = strongSelf->_photoEditor;
|
||||
[photoEditor processAnimated:false completion:nil];
|
||||
};
|
||||
previewView.interactionEnded = interactionEnded;
|
||||
|
||||
if (!_enhanceInitialAppearance)
|
||||
return;
|
||||
|
||||
[_editorItem setTempValue:@(50)];
|
||||
|
||||
PGPhotoEditor *photoEditor = self.photoEditor;
|
||||
if (photoEditor.readyForProcessing && !self.skipProcessingOnCompletion)
|
||||
{
|
||||
[photoEditor processAnimated:false completion:^
|
||||
{
|
||||
TGDispatchOnMainThread(^
|
||||
{
|
||||
TGPhotoEditorPreviewView *previewView = self.previewView;
|
||||
[previewView performTransitionInWithCompletion:nil];
|
||||
});
|
||||
}];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (self.finishedCombinedTransition != nil)
|
||||
self.finishedCombinedTransition();
|
||||
}
|
||||
}
|
||||
|
||||
- (void)viewDidAppear:(BOOL)animated
|
||||
{
|
||||
[super viewDidAppear:animated];
|
||||
[self transitionIn];
|
||||
}
|
||||
|
||||
- (BOOL)shouldAutorotate
|
||||
{
|
||||
TGPhotoEditorPreviewView *previewView = self.previewView;
|
||||
return (!previewView.isTracking && !(_toolAreaView != nil && _toolAreaView.isTracking) && !_portraitToolControlView.isTracking && !_landscapeToolControlView.isTracking && [super shouldAutorotate]);
|
||||
}
|
||||
|
||||
- (BOOL)prefersStatusBarHidden
|
||||
{
|
||||
if ([self inFormSheet])
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
- (UIBarStyle)requiredNavigationBarStyle
|
||||
{
|
||||
return UIBarStyleDefault;
|
||||
}
|
||||
|
||||
- (bool)navigationBarShouldBeHidden
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
- (void)_applyDefaultEnhanceIfNeeded
|
||||
{
|
||||
if (_dismissing || fabsf([_editorItem.displayValue floatValue]) > FLT_EPSILON)
|
||||
return;
|
||||
|
||||
_animating = true;
|
||||
|
||||
POPBasicAnimation *animation = [POPBasicAnimation animation];
|
||||
POPAnimatableProperty *valueProperty = [POPAnimatableProperty propertyWithName:@"org.telegram.enhanceValue" initializer:^(POPMutableAnimatableProperty *prop)
|
||||
{
|
||||
prop.readBlock = ^(TGPhotoEditorItemController *obj, CGFloat values[])
|
||||
{
|
||||
values[0] = [[obj->_portraitToolControlView value] floatValue];
|
||||
};
|
||||
prop.writeBlock = ^(TGPhotoEditorItemController *obj, const CGFloat values[])
|
||||
{
|
||||
[obj->_portraitToolControlView setValue:@(values[0])];
|
||||
[obj->_landscapeToolControlView setValue:@(values[0])];
|
||||
};
|
||||
}];
|
||||
animation.property = valueProperty;
|
||||
animation.fromValue = @(0);
|
||||
animation.toValue = @(50.0f);
|
||||
animation.duration = 0.3f;
|
||||
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
|
||||
animation.completionBlock = ^(__unused POPAnimation *animation, __unused BOOL finished)
|
||||
{
|
||||
_animating = false;
|
||||
|
||||
if (_enhanceInitialAppearance)
|
||||
return;
|
||||
|
||||
[_editorItem setTempValue:@(50)];
|
||||
|
||||
PGPhotoEditor *photoEditor = self.photoEditor;
|
||||
[photoEditor processAnimated:true completion:nil];
|
||||
};
|
||||
[self pop_addAnimation:animation forKey:@"enhanceValue"];
|
||||
}
|
||||
|
||||
#pragma mark - Transition
|
||||
|
||||
- (void)prepareForCombinedAppearance
|
||||
{
|
||||
_enhanceInitialAppearance = true;
|
||||
|
||||
_wrapperView.backgroundColor = [UIColor clearColor];
|
||||
_portraitToolControlView.backgroundColor = [UIColor clearColor];
|
||||
_landscapeToolControlView.backgroundColor = [UIColor clearColor];
|
||||
}
|
||||
|
||||
- (void)finishedCombinedAppearance
|
||||
{
|
||||
_wrapperView.backgroundColor = [UIColor blackColor];
|
||||
_portraitToolControlView.backgroundColor = [TGPhotoEditorInterfaceAssets panelBackgroundColor];
|
||||
_landscapeToolControlView.backgroundColor = [TGPhotoEditorInterfaceAssets panelBackgroundColor];
|
||||
}
|
||||
|
||||
- (void)transitionIn
|
||||
{
|
||||
if (UIInterfaceOrientationIsPortrait(self.interfaceOrientation))
|
||||
_portraitToolControlView.layer.shouldRasterize = true;
|
||||
else
|
||||
_landscapeToolControlView.layer.shouldRasterize = true;
|
||||
|
||||
CGRect targetFrame;
|
||||
CGRect toolTargetFrame;
|
||||
switch (self.interfaceOrientation)
|
||||
{
|
||||
case UIInterfaceOrientationLandscapeLeft:
|
||||
{
|
||||
targetFrame = _landscapeButtonsView.frame;
|
||||
_landscapeButtonsView.frame = CGRectOffset(_landscapeButtonsView.frame, -_landscapeButtonsView.frame.size.width, 0);
|
||||
toolTargetFrame = _landscapeToolsWrapperView.frame;
|
||||
_landscapeToolsWrapperView.frame = CGRectOffset(_landscapeToolsWrapperView.frame, -_landscapeToolsWrapperView.frame.size.width / 2 - 20, 0);
|
||||
}
|
||||
break;
|
||||
case UIInterfaceOrientationLandscapeRight:
|
||||
{
|
||||
targetFrame = _landscapeButtonsView.frame;
|
||||
_landscapeButtonsView.frame = CGRectOffset(_landscapeButtonsView.frame, _landscapeButtonsView.frame.size.width, 0);
|
||||
toolTargetFrame = _landscapeToolsWrapperView.frame;
|
||||
_landscapeToolsWrapperView.frame = CGRectOffset(_landscapeToolsWrapperView.frame, _landscapeToolsWrapperView.frame.size.width / 2 + 20, 0);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
targetFrame = _portraitButtonsView.frame;
|
||||
_portraitButtonsView.frame = CGRectOffset(_portraitButtonsView.frame, 0, _portraitButtonsView.frame.size.height);
|
||||
toolTargetFrame = _portraitToolsWrapperView.frame;
|
||||
_portraitToolsWrapperView.frame = CGRectOffset(_portraitToolsWrapperView.frame, 0, _portraitToolsWrapperView.frame.size.height / 2 + 20);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
void (^animationBlock)(void) = ^
|
||||
{
|
||||
if (UIInterfaceOrientationIsPortrait(self.interfaceOrientation)) {
|
||||
_portraitButtonsView.frame = targetFrame;
|
||||
_portraitToolsWrapperView.frame = toolTargetFrame;
|
||||
}
|
||||
else {
|
||||
_landscapeButtonsView.frame = targetFrame;
|
||||
_landscapeToolsWrapperView.frame = toolTargetFrame;
|
||||
}
|
||||
};
|
||||
|
||||
[UIView animateWithDuration:0.3f animations:^
|
||||
{
|
||||
_wrapperView.alpha = 1.0f;
|
||||
} completion:^(BOOL finished)
|
||||
{
|
||||
if (finished)
|
||||
{
|
||||
_portraitToolControlView.layer.shouldRasterize = false;
|
||||
_landscapeToolControlView.layer.shouldRasterize = false;
|
||||
}
|
||||
}];
|
||||
|
||||
if ([_editorItem.identifier isEqualToString:@"enhance"])
|
||||
[self _applyDefaultEnhanceIfNeeded];
|
||||
|
||||
if (iosMajorVersion() >= 7)
|
||||
[UIView animateWithDuration:0.4f delay:0.0f usingSpringWithDamping:1.0f initialSpringVelocity:0.0f options:UIViewAnimationOptionCurveLinear animations:animationBlock completion:nil];
|
||||
else
|
||||
[UIView animateWithDuration:0.3f delay:0.0f options:UIViewAnimationOptionAllowUserInteraction animations:animationBlock completion:nil];
|
||||
|
||||
if (self.beginTransitionIn != nil)
|
||||
self.beginTransitionIn();
|
||||
}
|
||||
|
||||
- (void)transitionOutWithCompletion:(void (^)(void))completion
|
||||
{
|
||||
_dismissing = true;
|
||||
|
||||
TGPhotoEditorPreviewView *previewView = self.previewView;
|
||||
previewView.interactionEnded = nil;
|
||||
|
||||
if (self.beginTransitionOut != nil)
|
||||
self.beginTransitionOut();
|
||||
|
||||
UIView *snapshotView = [previewView snapshotViewAfterScreenUpdates:false];
|
||||
snapshotView.frame = previewView.frame;
|
||||
[previewView.superview addSubview:snapshotView];
|
||||
|
||||
_wrapperView.backgroundColor = [UIColor clearColor];
|
||||
|
||||
[_initialPreviewSuperview addSubview:self.previewView];
|
||||
|
||||
if (UIInterfaceOrientationIsPortrait(self.interfaceOrientation))
|
||||
_portraitToolControlView.layer.shouldRasterize = true;
|
||||
else
|
||||
_landscapeToolControlView.layer.shouldRasterize = true;
|
||||
|
||||
[_toolAreaView.superview bringSubviewToFront:_toolAreaView];
|
||||
|
||||
[UIView animateWithDuration:0.3f animations:^
|
||||
{
|
||||
_wrapperView.alpha = 0.0f;
|
||||
snapshotView.alpha = 0.0f;
|
||||
_toolAreaView.alpha = 0.0f;
|
||||
} completion:^(__unused BOOL finished)
|
||||
{
|
||||
dispatch_async(dispatch_get_main_queue(), ^
|
||||
{
|
||||
if (completion != nil)
|
||||
completion();
|
||||
});
|
||||
}];
|
||||
|
||||
void (^animationBlock)(void) = ^
|
||||
{
|
||||
switch (self.interfaceOrientation)
|
||||
{
|
||||
case UIInterfaceOrientationLandscapeLeft:
|
||||
{
|
||||
_landscapeButtonsView.frame = CGRectOffset(_landscapeButtonsView.frame, -_landscapeButtonsView.frame.size.width, 0);
|
||||
}
|
||||
break;
|
||||
case UIInterfaceOrientationLandscapeRight:
|
||||
{
|
||||
_landscapeButtonsView.frame = CGRectOffset(_landscapeButtonsView.frame, _landscapeButtonsView.frame.size.width, 0);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
_portraitButtonsView.frame = CGRectOffset(_portraitButtonsView.frame, 0, _portraitButtonsView.frame.size.height);
|
||||
}
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
UIInterfaceOrientation orientation = [[LegacyComponentsGlobals provider] applicationStatusBarOrientation];
|
||||
if ([self inFormSheet] || [UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad)
|
||||
{
|
||||
orientation = UIInterfaceOrientationPortrait;
|
||||
}
|
||||
else if ([self.presentingViewController isKindOfClass:[TGNavigationController class]] &&
|
||||
[(TGNavigationController *)self.presentingViewController presentationStyle] == TGNavigationControllerPresentationStyleInFormSheet)
|
||||
{
|
||||
orientation = UIInterfaceOrientationPortrait;
|
||||
}
|
||||
|
||||
if (UIInterfaceOrientationIsPortrait(orientation))
|
||||
_landscapeToolsWrapperView.hidden = true;
|
||||
else
|
||||
_portraitToolsWrapperView.hidden = true;
|
||||
|
||||
if (iosMajorVersion() >= 7)
|
||||
{
|
||||
[UIView animateWithDuration:0.4f delay:0.0f usingSpringWithDamping:1.0f initialSpringVelocity:0.0f options:UIViewAnimationOptionCurveLinear animations:animationBlock completion:nil];
|
||||
}
|
||||
else
|
||||
{
|
||||
[UIView animateWithDuration:0.3f delay:0.0f options:UIViewAnimationOptionAllowUserInteraction animations:animationBlock completion:nil];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Layout
|
||||
|
||||
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
|
||||
{
|
||||
[self.view setNeedsLayout];
|
||||
|
||||
if (_toolAreaView != nil)
|
||||
{
|
||||
_toolAreaView.alpha = 0.0f;
|
||||
|
||||
[UIView animateWithDuration:duration / 2 delay:duration / 2 options:UIViewAnimationOptionCurveLinear animations:^
|
||||
{
|
||||
_toolAreaView.alpha = 1.0f;
|
||||
} completion:nil];
|
||||
}
|
||||
|
||||
[super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];
|
||||
}
|
||||
|
||||
- (void)viewWillLayoutSubviews
|
||||
{
|
||||
[super viewWillLayoutSubviews];
|
||||
|
||||
[self updateLayout:[[LegacyComponentsGlobals provider] applicationStatusBarOrientation]];
|
||||
}
|
||||
|
||||
- (CGSize)referenceViewSize
|
||||
{
|
||||
if (self.parentViewController != nil)
|
||||
{
|
||||
TGPhotoEditorController *controller = (TGPhotoEditorController *)self.parentViewController;
|
||||
return [controller referenceViewSize];
|
||||
}
|
||||
|
||||
return CGSizeZero;
|
||||
}
|
||||
|
||||
- (void)updateLayout:(UIInterfaceOrientation)orientation
|
||||
{
|
||||
CGSize referenceSize = [self referenceViewSize];
|
||||
|
||||
if ([self inFormSheet] || [UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad)
|
||||
{
|
||||
orientation = UIInterfaceOrientationPortrait;
|
||||
}
|
||||
else if ([self.presentingViewController isKindOfClass:[TGNavigationController class]] &&
|
||||
[(TGNavigationController *)self.presentingViewController presentationStyle] == TGNavigationControllerPresentationStyleInFormSheet)
|
||||
{
|
||||
orientation = UIInterfaceOrientationPortrait;
|
||||
}
|
||||
|
||||
CGFloat screenSide = MAX(referenceSize.width, referenceSize.height) + 2 * TGPhotoEditorPanelSize;
|
||||
_wrapperView.frame = CGRectMake((referenceSize.width - screenSide) / 2, (referenceSize.height - screenSide) / 2, screenSide, screenSide);
|
||||
|
||||
CGFloat panelToolbarPortraitSize = TGPhotoEditorPanelSize + TGPhotoEditorToolbarSize;
|
||||
CGFloat panelToolbarLandscapeSize = TGPhotoEditorPanelSize + self.toolbarLandscapeSize;
|
||||
|
||||
switch (orientation)
|
||||
{
|
||||
case UIInterfaceOrientationLandscapeLeft:
|
||||
{
|
||||
[UIView performWithoutAnimation:^
|
||||
{
|
||||
_landscapeToolsWrapperView.frame = CGRectMake(0, (screenSide - referenceSize.height) / 2, panelToolbarLandscapeSize, _landscapeToolsWrapperView.frame.size.height);
|
||||
_landscapeToolControlView.frame = CGRectMake(panelToolbarLandscapeSize - TGPhotoEditorPanelSize, 0, TGPhotoEditorPanelSize, _landscapeToolsWrapperView.frame.size.height);
|
||||
|
||||
if (!_dismissing)
|
||||
_landscapeButtonsView.frame = CGRectMake(0, 0, [_landscapeButtonsView landscapeSize], referenceSize.height);
|
||||
}];
|
||||
|
||||
_landscapeToolsWrapperView.frame = CGRectMake((screenSide - referenceSize.width) / 2, (screenSide - referenceSize.height) / 2, panelToolbarLandscapeSize, referenceSize.height);
|
||||
|
||||
_landscapeToolControlView.frame = CGRectMake(panelToolbarLandscapeSize - TGPhotoEditorPanelSize, 0, TGPhotoEditorPanelSize, _landscapeToolsWrapperView.frame.size.height);
|
||||
|
||||
_portraitToolsWrapperView.frame = CGRectMake((screenSide - referenceSize.width) / 2, screenSide - panelToolbarPortraitSize, referenceSize.width, panelToolbarPortraitSize);
|
||||
}
|
||||
break;
|
||||
|
||||
case UIInterfaceOrientationLandscapeRight:
|
||||
{
|
||||
[UIView performWithoutAnimation:^
|
||||
{
|
||||
_landscapeToolsWrapperView.frame = CGRectMake(screenSide - panelToolbarLandscapeSize, (screenSide - referenceSize.height) / 2, panelToolbarLandscapeSize, _landscapeToolsWrapperView.frame.size.height);
|
||||
_landscapeToolControlView.frame = CGRectMake(0, 0, TGPhotoEditorPanelSize, _landscapeToolsWrapperView.frame.size.height);
|
||||
|
||||
if (!_dismissing)
|
||||
_landscapeButtonsView.frame = CGRectMake(panelToolbarLandscapeSize - [_landscapeButtonsView landscapeSize], 0, [_landscapeButtonsView landscapeSize], referenceSize.height);
|
||||
}];
|
||||
|
||||
_landscapeToolsWrapperView.frame = CGRectMake((screenSide + referenceSize.width) / 2 - panelToolbarLandscapeSize, (screenSide - referenceSize.height) / 2, panelToolbarLandscapeSize, referenceSize.height);
|
||||
|
||||
_landscapeToolControlView.frame = CGRectMake(0, 0, TGPhotoEditorPanelSize, _landscapeToolsWrapperView.frame.size.height);
|
||||
|
||||
_portraitToolsWrapperView.frame = CGRectMake((screenSide - referenceSize.width) / 2, screenSide - panelToolbarPortraitSize, referenceSize.width, panelToolbarPortraitSize);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
CGFloat x = _landscapeToolsWrapperView.frame.origin.x;
|
||||
if (x < screenSide / 2)
|
||||
x = 0;
|
||||
else
|
||||
x = screenSide - TGPhotoEditorPanelSize;
|
||||
_landscapeToolsWrapperView.frame = CGRectMake(x, (screenSide - referenceSize.height) / 2, panelToolbarLandscapeSize, referenceSize.height);
|
||||
|
||||
_portraitToolsWrapperView.frame = CGRectMake((screenSide - referenceSize.width) / 2, (screenSide + referenceSize.height) / 2 - panelToolbarPortraitSize, referenceSize.width, panelToolbarPortraitSize);
|
||||
|
||||
if (!_dismissing)
|
||||
_portraitButtonsView.frame = CGRectMake(0, _portraitToolsWrapperView.frame.size.height - TGPhotoEditorToolButtonsViewSize, _portraitToolsWrapperView.frame.size.width, TGPhotoEditorToolButtonsViewSize);
|
||||
|
||||
_portraitToolControlView.frame = CGRectMake(0, 0, _portraitToolsWrapperView.frame.size.width, _portraitToolsWrapperView.frame.size.height - _portraitButtonsView.frame.size.height);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
PGPhotoEditor *photoEditor = self.photoEditor;
|
||||
TGPhotoEditorPreviewView *previewView = self.previewView;
|
||||
|
||||
if (_dismissing || previewView.superview != self.view)
|
||||
return;
|
||||
|
||||
bool hasOnScreenNavigation = false;
|
||||
if (iosMajorVersion() >= 11)
|
||||
hasOnScreenNavigation = (self.viewLoaded && self.view.safeAreaInsets.bottom > FLT_EPSILON) || self.context.safeAreaInset.bottom > FLT_EPSILON;
|
||||
|
||||
CGRect containerFrame = [TGPhotoEditorTabController photoContainerFrameForParentViewFrame:CGRectMake(0, 0, referenceSize.width, referenceSize.height) toolbarLandscapeSize:self.toolbarLandscapeSize orientation:orientation panelSize:TGPhotoEditorPanelSize hasOnScreenNavigation:hasOnScreenNavigation];
|
||||
CGSize fittedSize = TGScaleToSize(photoEditor.rotatedCropSize, containerFrame.size);
|
||||
previewView.frame = CGRectMake(containerFrame.origin.x + (containerFrame.size.width - fittedSize.width) / 2,
|
||||
containerFrame.origin.y + (containerFrame.size.height - fittedSize.height) / 2,
|
||||
fittedSize.width,
|
||||
fittedSize.height);
|
||||
|
||||
[UIView performWithoutAnimation:^
|
||||
{
|
||||
_toolAreaView.frame = CGRectMake(CGRectGetMidX(previewView.frame) - containerFrame.size.width / 2, CGRectGetMidY(previewView.frame) - containerFrame.size.height / 2, containerFrame.size.width, containerFrame.size.height);
|
||||
_toolAreaView.actualAreaSize = previewView.frame.size;
|
||||
}];
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
@ -14,6 +14,7 @@
|
|||
@property (nonatomic, copy) void(^interactionEnded)(void);
|
||||
|
||||
@property (nonatomic, readonly) bool isTracking;
|
||||
@property (nonatomic, assign) bool customTouchDownHandling;
|
||||
|
||||
- (void)setSnapshotImage:(UIImage *)image;
|
||||
- (void)setSnapshotView:(UIView *)view;
|
||||
|
|
|
|||
|
|
@ -228,7 +228,8 @@
|
|||
if (self.touchedDown != nil)
|
||||
self.touchedDown();
|
||||
|
||||
[self setActualImageHidden:true animated:false];
|
||||
if (!self.customTouchDownHandling)
|
||||
[self setActualImageHidden:true animated:false];
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
@ -240,7 +241,8 @@
|
|||
if (self.touchedUp != nil)
|
||||
self.touchedUp();
|
||||
|
||||
[self setActualImageHidden:false animated:false];
|
||||
if (!self.customTouchDownHandling)
|
||||
[self setActualImageHidden:false animated:false];
|
||||
|
||||
if (self.interactionEnded != nil)
|
||||
self.interactionEnded();
|
||||
|
|
|
|||
|
|
@ -1,13 +1,21 @@
|
|||
#import "TGPhotoPaintSparseView.h"
|
||||
#import "TGPhotoPaintStickersContext.h"
|
||||
|
||||
@class TGPaintingData;
|
||||
@class TGPhotoPaintEntity;
|
||||
@class TGPhotoPaintEntityView;
|
||||
|
||||
@interface TGPhotoEntitiesContainerView : TGPhotoPaintSparseView
|
||||
|
||||
@property (nonatomic, strong) id<TGPhotoPaintStickersContext> stickersContext;
|
||||
|
||||
@property (nonatomic, readonly) NSUInteger entitiesCount;
|
||||
@property (nonatomic, copy) void (^entitySelected)(TGPhotoPaintEntityView *);
|
||||
@property (nonatomic, copy) void (^entityRemoved)(TGPhotoPaintEntityView *);
|
||||
|
||||
- (void)setupWithPaintingData:(TGPaintingData *)paintingData;
|
||||
- (TGPhotoPaintEntityView *)createEntityViewWithEntity:(TGPhotoPaintEntity *)entity;
|
||||
|
||||
- (TGPhotoPaintEntityView *)viewForUUID:(NSInteger)uuid;
|
||||
- (void)removeViewWithUUID:(NSInteger)uuid;
|
||||
- (void)removeAll;
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
#import "TGPhotoPaintEntityView.h"
|
||||
#import "TGPhotoStickerEntityView.h"
|
||||
#import "TGPhotoTextEntityView.h"
|
||||
#import "TGPaintingData.h"
|
||||
|
||||
#import <LegacyComponents/TGPhotoEditorUtils.h>
|
||||
|
||||
|
|
@ -74,6 +75,48 @@
|
|||
return MAX(0, (NSInteger)self.subviews.count - 1);
|
||||
}
|
||||
|
||||
- (void)setupWithPaintingData:(TGPaintingData *)paintingData {
|
||||
[self removeAll];
|
||||
for (TGPhotoPaintEntity *entity in paintingData.entities) {
|
||||
[self createEntityViewWithEntity:entity];
|
||||
}
|
||||
}
|
||||
|
||||
- (TGPhotoPaintEntityView *)createEntityViewWithEntity:(TGPhotoPaintEntity *)entity {
|
||||
if ([entity isKindOfClass:[TGPhotoPaintStickerEntity class]])
|
||||
return [self _createStickerViewWithEntity:(TGPhotoPaintStickerEntity *)entity];
|
||||
else if ([entity isKindOfClass:[TGPhotoPaintTextEntity class]])
|
||||
return [self _createTextViewWithEntity:(TGPhotoPaintTextEntity *)entity];
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (TGPhotoStickerEntityView *)_createStickerViewWithEntity:(TGPhotoPaintStickerEntity *)entity
|
||||
{
|
||||
TGPhotoStickerEntityView *stickerView = [[TGPhotoStickerEntityView alloc] initWithEntity:entity context:self.stickersContext];
|
||||
[self _commonEntityViewSetup:stickerView entity:entity];
|
||||
[self addSubview:stickerView];
|
||||
|
||||
return stickerView;
|
||||
}
|
||||
|
||||
- (TGPhotoTextEntityView *)_createTextViewWithEntity:(TGPhotoPaintTextEntity *)entity
|
||||
{
|
||||
TGPhotoTextEntityView *textView = [[TGPhotoTextEntityView alloc] initWithEntity:entity];
|
||||
[textView sizeToFit];
|
||||
|
||||
[self _commonEntityViewSetup:textView entity:entity];
|
||||
[self addSubview:textView];
|
||||
|
||||
return textView;
|
||||
}
|
||||
|
||||
- (void)_commonEntityViewSetup:(TGPhotoPaintEntityView *)entityView entity:(TGPhotoPaintEntity *)entity
|
||||
{
|
||||
entityView.transform = CGAffineTransformRotate(CGAffineTransformMakeScale(entity.scale, entity.scale), entity.angle);
|
||||
entityView.center = entity.position;
|
||||
}
|
||||
|
||||
- (TGPhotoPaintEntityView *)viewForUUID:(NSInteger)uuid
|
||||
{
|
||||
for (TGPhotoPaintEntityView *view in self.subviews)
|
||||
|
|
|
|||
|
|
@ -17,6 +17,11 @@
|
|||
|
||||
+ (CGRect)photoContainerFrameForParentViewFrame:(CGRect)parentViewFrame toolbarLandscapeSize:(CGFloat)toolbarLandscapeSize orientation:(UIInterfaceOrientation)orientation panelSize:(CGFloat)panelSize hasOnScreenNavigation:(bool)hasOnScreenNavigation;
|
||||
|
||||
+ (CGSize)fittedContentSize:(CGRect)cropRect orientation:(UIImageOrientation)orientation originalSize:(CGSize)originalSize;
|
||||
+ (CGRect)fittedCropRect:(CGRect)cropRect originalSize:(CGSize)originalSize keepOriginalSize:(bool)originalSize;
|
||||
+ (CGPoint)fittedCropRect:(CGRect)cropRect centerScale:(CGFloat)scale;
|
||||
+ (CGSize)maximumPaintingSize;
|
||||
|
||||
@end
|
||||
|
||||
extern const CGFloat TGPhotoPaintTopPanelSize;
|
||||
|
|
|
|||
|
|
@ -163,7 +163,7 @@ const CGFloat TGPhotoPaintStickerKeyboardSize = 260.0f;
|
|||
else
|
||||
_undoManager = [[TGPaintUndoManager alloc] init];
|
||||
|
||||
CGSize size = TGScaleToSize(photoEditor.originalSize, [self maximumPaintingSize]);
|
||||
CGSize size = TGScaleToSize(photoEditor.originalSize, [TGPhotoPaintController maximumPaintingSize]);
|
||||
_painting = [[TGPainting alloc] initWithSize:size undoManager:_undoManager imageData:[_photoEditor.paintingData data]];
|
||||
_undoManager.painting = _painting;
|
||||
|
||||
|
|
@ -238,6 +238,7 @@ const CGFloat TGPhotoPaintStickerKeyboardSize = 260.0f;
|
|||
|
||||
_entitiesContainerView = [[TGPhotoEntitiesContainerView alloc] init];
|
||||
_entitiesContainerView.clipsToBounds = true;
|
||||
_entitiesContainerView.stickersContext = _stickersContext;
|
||||
_entitiesContainerView.entitySelected = ^(TGPhotoPaintEntityView *sender)
|
||||
{
|
||||
__strong TGPhotoPaintController *strongSelf = weakSelf;
|
||||
|
|
@ -377,6 +378,11 @@ const CGFloat TGPhotoPaintStickerKeyboardSize = 260.0f;
|
|||
[self controllerInsetUpdated:UIEdgeInsetsZero];
|
||||
}
|
||||
|
||||
- (void)setStickersContext:(id<TGPhotoPaintStickersContext>)stickersContext {
|
||||
_stickersContext = stickersContext;
|
||||
_entitiesContainerView.stickersContext = stickersContext;
|
||||
}
|
||||
|
||||
- (void)setupCanvas
|
||||
{
|
||||
__weak TGPhotoPaintController *weakSelf = self;
|
||||
|
|
@ -451,7 +457,14 @@ const CGFloat TGPhotoPaintStickerKeyboardSize = 260.0f;
|
|||
[super viewDidLoad];
|
||||
|
||||
PGPhotoEditor *photoEditor = _photoEditor;
|
||||
[self setupWithPaintingData:photoEditor.paintingData];
|
||||
[_entitiesContainerView setupWithPaintingData:photoEditor.paintingData];
|
||||
for (TGPhotoPaintEntityView *view in _entitiesContainerView.subviews)
|
||||
{
|
||||
if (![view isKindOfClass:[TGPhotoPaintEntityView class]])
|
||||
continue;
|
||||
|
||||
[self _commonEntityViewSetup:view];
|
||||
}
|
||||
|
||||
__weak TGPhotoPaintController *weakSelf = self;
|
||||
_undoManager.historyChanged = ^
|
||||
|
|
@ -614,17 +627,6 @@ const CGFloat TGPhotoPaintStickerKeyboardSize = 260.0f;
|
|||
|
||||
#pragma mark - Data Handling
|
||||
|
||||
- (void)setupWithPaintingData:(TGPaintingData *)paintingData
|
||||
{
|
||||
if (paintingData == nil)
|
||||
return;
|
||||
|
||||
for (TGPhotoPaintEntity *entity in paintingData.entities)
|
||||
{
|
||||
[self _createEntityViewWithEntity:entity];
|
||||
}
|
||||
}
|
||||
|
||||
- (TGPaintingData *)_prepareResultData
|
||||
{
|
||||
if (_resultData != nil)
|
||||
|
|
@ -782,12 +784,14 @@ const CGFloat TGPhotoPaintStickerKeyboardSize = 260.0f;
|
|||
TGPhotoPaintEntityView *entityView = nil;
|
||||
if ([entity isKindOfClass:[TGPhotoPaintStickerEntity class]])
|
||||
{
|
||||
TGPhotoStickerEntityView *stickerView = [self _createStickerViewWithEntity:(TGPhotoPaintStickerEntity *)entity];
|
||||
TGPhotoStickerEntityView *stickerView = (TGPhotoStickerEntityView *)[_entitiesContainerView createEntityViewWithEntity:entity];
|
||||
[self _commonEntityViewSetup:stickerView];
|
||||
entityView = stickerView;
|
||||
}
|
||||
else
|
||||
{
|
||||
TGPhotoTextEntityView *textView = [self _createTextViewWithEntity:(TGPhotoPaintTextEntity *)entity];
|
||||
TGPhotoTextEntityView *textView = (TGPhotoTextEntityView *)[_entitiesContainerView createEntityViewWithEntity:entity];
|
||||
[self _commonEntityViewSetup:textView];
|
||||
entityView = textView;
|
||||
}
|
||||
|
||||
|
|
@ -934,13 +938,10 @@ const CGFloat TGPhotoPaintStickerKeyboardSize = 260.0f;
|
|||
}
|
||||
}
|
||||
|
||||
- (void)_commonEntityViewSetup:(TGPhotoPaintEntityView *)entityView entity:(TGPhotoPaintEntity *)entity
|
||||
- (void)_commonEntityViewSetup:(TGPhotoPaintEntityView *)entityView
|
||||
{
|
||||
[self hideMenu];
|
||||
|
||||
entityView.transform = CGAffineTransformRotate(CGAffineTransformMakeScale(entity.scale, entity.scale), entity.angle);
|
||||
entityView.center = entity.position;
|
||||
|
||||
|
||||
__weak TGPhotoPaintController *weakSelf = self;
|
||||
entityView.shouldTouchEntity = ^bool (__unused TGPhotoPaintEntityView *sender)
|
||||
{
|
||||
|
|
@ -967,6 +968,29 @@ const CGFloat TGPhotoPaintStickerKeyboardSize = 260.0f;
|
|||
|
||||
[strongSelf updateActionsView];
|
||||
};
|
||||
|
||||
if ([entityView isKindOfClass:[TGPhotoTextEntityView class]]) {
|
||||
TGPhotoTextEntityView *textView = (TGPhotoTextEntityView *)entityView;
|
||||
|
||||
__weak TGPhotoPaintController *weakSelf = self;
|
||||
textView.beganEditing = ^(TGPhotoTextEntityView *sender)
|
||||
{
|
||||
__strong TGPhotoPaintController *strongSelf = weakSelf;
|
||||
if (strongSelf == nil)
|
||||
return;
|
||||
|
||||
[strongSelf bringTextEntityViewFront:sender];
|
||||
};
|
||||
|
||||
textView.finishedEditing = ^(__unused TGPhotoTextEntityView *sender)
|
||||
{
|
||||
__strong TGPhotoPaintController *strongSelf = weakSelf;
|
||||
if (strongSelf == nil)
|
||||
return;
|
||||
|
||||
[strongSelf sendTextEntityViewBack];
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
- (void)_registerEntityRemovalUndo:(TGPhotoPaintEntity *)entity
|
||||
|
|
@ -977,55 +1001,6 @@ const CGFloat TGPhotoPaintStickerKeyboardSize = 260.0f;
|
|||
}];
|
||||
}
|
||||
|
||||
- (TGPhotoPaintEntityView *)_createEntityViewWithEntity:(TGPhotoPaintEntity *)entity
|
||||
{
|
||||
if ([entity isKindOfClass:[TGPhotoPaintStickerEntity class]])
|
||||
return [self _createStickerViewWithEntity:(TGPhotoPaintStickerEntity *)entity];
|
||||
else if ([entity isKindOfClass:[TGPhotoPaintTextEntity class]])
|
||||
return [self _createTextViewWithEntity:(TGPhotoPaintTextEntity *)entity];
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (TGPhotoStickerEntityView *)_createStickerViewWithEntity:(TGPhotoPaintStickerEntity *)entity
|
||||
{
|
||||
TGPhotoStickerEntityView *stickerView = [[TGPhotoStickerEntityView alloc] initWithEntity:entity context:self.stickersContext];
|
||||
[self _commonEntityViewSetup:stickerView entity:entity];
|
||||
[_entitiesContainerView addSubview:stickerView];
|
||||
|
||||
return stickerView;
|
||||
}
|
||||
|
||||
- (TGPhotoTextEntityView *)_createTextViewWithEntity:(TGPhotoPaintTextEntity *)entity
|
||||
{
|
||||
TGPhotoTextEntityView *textView = [[TGPhotoTextEntityView alloc] initWithEntity:entity];
|
||||
[textView sizeToFit];
|
||||
|
||||
__weak TGPhotoPaintController *weakSelf = self;
|
||||
textView.beganEditing = ^(TGPhotoTextEntityView *sender)
|
||||
{
|
||||
__strong TGPhotoPaintController *strongSelf = weakSelf;
|
||||
if (strongSelf == nil)
|
||||
return;
|
||||
|
||||
[strongSelf bringTextEntityViewFront:sender];
|
||||
};
|
||||
|
||||
textView.finishedEditing = ^(__unused TGPhotoTextEntityView *sender)
|
||||
{
|
||||
__strong TGPhotoPaintController *strongSelf = weakSelf;
|
||||
if (strongSelf == nil)
|
||||
return;
|
||||
|
||||
[strongSelf sendTextEntityViewBack];
|
||||
};
|
||||
|
||||
[self _commonEntityViewSetup:textView entity:entity];
|
||||
[_entitiesContainerView addSubview:textView];
|
||||
|
||||
return textView;
|
||||
}
|
||||
|
||||
#pragma mark Stickers
|
||||
|
||||
- (void)presentStickersView
|
||||
|
|
@ -1034,7 +1009,7 @@ const CGFloat TGPhotoPaintStickerKeyboardSize = 260.0f;
|
|||
_stickersContext.presentStickersController(^(id document, bool animated, UIView *view, CGRect rect) {
|
||||
__strong TGPhotoPaintController *strongSelf = weakSelf;
|
||||
if (strongSelf != nil) {
|
||||
UIView *snapshot = [view snapshotViewAfterScreenUpdates:false];
|
||||
// UIView *snapshot = [view snapshotViewAfterScreenUpdates:false];
|
||||
[strongSelf createNewStickerWithDocument:document animated:animated transitionPoint:CGPointZero stickersView:nil snapshotView:nil];
|
||||
}
|
||||
});
|
||||
|
|
@ -1092,7 +1067,8 @@ const CGFloat TGPhotoPaintStickerKeyboardSize = 260.0f;
|
|||
TGPhotoPaintStickerEntity *entity = [[TGPhotoPaintStickerEntity alloc] initWithDocument:document baseSize:[self _stickerBaseSizeForCurrentPainting] animated:animated];
|
||||
[self _setStickerEntityPosition:entity];
|
||||
|
||||
TGPhotoStickerEntityView *stickerView = [self _createStickerViewWithEntity:entity];
|
||||
TGPhotoStickerEntityView *stickerView = (TGPhotoStickerEntityView *)[_entitiesContainerView createEntityViewWithEntity:entity];
|
||||
[self _commonEntityViewSetup:stickerView];
|
||||
// stickerView.hidden = true;
|
||||
|
||||
CGFloat rotation = entity.angle - [self startRotation];
|
||||
|
|
@ -1137,7 +1113,8 @@ const CGFloat TGPhotoPaintStickerKeyboardSize = 260.0f;
|
|||
entity.position = [self startPositionRelativeToEntity:nil];
|
||||
entity.angle = [self startRotation];
|
||||
|
||||
TGPhotoTextEntityView *textView = [self _createTextViewWithEntity:entity];
|
||||
TGPhotoTextEntityView *textView = (TGPhotoTextEntityView *)[_entitiesContainerView createEntityViewWithEntity:entity];
|
||||
[self _commonEntityViewSetup:textView];
|
||||
|
||||
[self selectEntityView:textView];
|
||||
|
||||
|
|
@ -1293,7 +1270,7 @@ const CGFloat TGPhotoPaintStickerKeyboardSize = 260.0f;
|
|||
return [self _brushBaseWeightForCurrentPainting] + [self _brushWeightRangeForCurrentPainting] * size;
|
||||
}
|
||||
|
||||
- (CGSize)maximumPaintingSize
|
||||
+ (CGSize)maximumPaintingSize
|
||||
{
|
||||
static dispatch_once_t onceToken;
|
||||
static CGSize size;
|
||||
|
|
@ -1511,11 +1488,15 @@ const CGFloat TGPhotoPaintStickerKeyboardSize = 260.0f;
|
|||
|
||||
- (CGSize)fittedContentSize
|
||||
{
|
||||
CGSize fittedOriginalSize = TGScaleToSize(_photoEditor.originalSize, [self maximumPaintingSize]);
|
||||
CGFloat scale = fittedOriginalSize.width / _photoEditor.originalSize.width;
|
||||
return [TGPhotoPaintController fittedContentSize:_photoEditor.cropRect orientation:_photoEditor.cropOrientation originalSize:_photoEditor.originalSize];
|
||||
}
|
||||
|
||||
+ (CGSize)fittedContentSize:(CGRect)cropRect orientation:(UIImageOrientation)orientation originalSize:(CGSize)originalSize {
|
||||
CGSize fittedOriginalSize = TGScaleToSize(originalSize, [TGPhotoPaintController maximumPaintingSize]);
|
||||
CGFloat scale = fittedOriginalSize.width / originalSize.width;
|
||||
|
||||
CGSize size = CGSizeMake(_photoEditor.cropRect.size.width * scale, _photoEditor.cropRect.size.height * scale);
|
||||
if (_photoEditor.cropOrientation == UIImageOrientationLeft || _photoEditor.cropOrientation == UIImageOrientationRight)
|
||||
CGSize size = CGSizeMake(cropRect.size.width * scale, cropRect.size.height * scale);
|
||||
if (orientation == UIImageOrientationLeft || orientation == UIImageOrientationRight)
|
||||
size = CGSizeMake(size.height, size.width);
|
||||
|
||||
return CGSizeMake(floor(size.width), floor(size.height));
|
||||
|
|
@ -1523,20 +1504,29 @@ const CGFloat TGPhotoPaintStickerKeyboardSize = 260.0f;
|
|||
|
||||
- (CGRect)fittedCropRect:(bool)originalSize
|
||||
{
|
||||
CGSize fittedOriginalSize = TGScaleToSize(_photoEditor.originalSize, [self maximumPaintingSize]);
|
||||
CGFloat scale = fittedOriginalSize.width / _photoEditor.originalSize.width;
|
||||
return [TGPhotoPaintController fittedCropRect:_photoEditor.cropRect originalSize:_photoEditor.originalSize keepOriginalSize:originalSize];
|
||||
}
|
||||
|
||||
+ (CGRect)fittedCropRect:(CGRect)cropRect originalSize:(CGSize)originalSize keepOriginalSize:(bool)keepOriginalSize {
|
||||
CGSize fittedOriginalSize = TGScaleToSize(originalSize, [TGPhotoPaintController maximumPaintingSize]);
|
||||
CGFloat scale = fittedOriginalSize.width / originalSize.width;
|
||||
|
||||
CGSize size = fittedOriginalSize;
|
||||
if (!originalSize)
|
||||
size = CGSizeMake(_photoEditor.cropRect.size.width * scale, _photoEditor.cropRect.size.height * scale);
|
||||
if (!keepOriginalSize)
|
||||
size = CGSizeMake(cropRect.size.width * scale, cropRect.size.height * scale);
|
||||
|
||||
return CGRectMake(-_photoEditor.cropRect.origin.x * scale, -_photoEditor.cropRect.origin.y * scale, size.width, size.height);
|
||||
return CGRectMake(-cropRect.origin.x * scale, -cropRect.origin.y * scale, size.width, size.height);
|
||||
}
|
||||
|
||||
- (CGPoint)fittedCropCenterScale:(CGFloat)scale
|
||||
{
|
||||
CGSize size = CGSizeMake(_photoEditor.cropRect.size.width * scale, _photoEditor.cropRect.size.height * scale);
|
||||
CGRect rect = CGRectMake(_photoEditor.cropRect.origin.x * scale, _photoEditor.cropRect.origin.y * scale, size.width, size.height);
|
||||
return [TGPhotoPaintController fittedCropRect:_photoEditor.cropRect centerScale:scale];
|
||||
}
|
||||
|
||||
+ (CGPoint)fittedCropRect:(CGRect)cropRect centerScale:(CGFloat)scale
|
||||
{
|
||||
CGSize size = CGSizeMake(cropRect.size.width * scale, cropRect.size.height * scale);
|
||||
CGRect rect = CGRectMake(cropRect.origin.x * scale, cropRect.origin.y * scale, size.width, size.height);
|
||||
|
||||
return CGPointMake(CGRectGetMidX(rect), CGRectGetMidY(rect));
|
||||
}
|
||||
|
|
@ -1615,10 +1605,6 @@ const CGFloat TGPhotoPaintStickerKeyboardSize = 260.0f;
|
|||
if (ABS(maxScale - minScale) < 0.01f)
|
||||
maxScale = minScale;
|
||||
|
||||
|
||||
if (iosMajorVersion() >= 11) {
|
||||
_scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
|
||||
}
|
||||
_scrollView.contentInset = UIEdgeInsetsZero;
|
||||
|
||||
if (_scrollView.minimumZoomScale != 0.05f)
|
||||
|
|
@ -1751,7 +1737,7 @@ const CGFloat TGPhotoPaintStickerKeyboardSize = 260.0f;
|
|||
_entitiesContainerView.frame = CGRectMake(0, 0, rect.size.width, rect.size.height);
|
||||
_entitiesContainerView.transform = CGAffineTransformMakeRotation(_photoEditor.cropRotation);
|
||||
|
||||
CGSize fittedOriginalSize = TGScaleToSize(_photoEditor.originalSize, [self maximumPaintingSize]);
|
||||
CGSize fittedOriginalSize = TGScaleToSize(_photoEditor.originalSize, [TGPhotoPaintController maximumPaintingSize]);
|
||||
CGSize rotatedSize = TGRotatedContentSize(fittedOriginalSize, _photoEditor.cropRotation);
|
||||
CGPoint centerPoint = CGPointMake(rotatedSize.width / 2.0f, rotatedSize.height / 2.0f);
|
||||
|
||||
|
|
@ -2269,18 +2255,9 @@ const CGFloat TGPhotoPaintStickerKeyboardSize = 260.0f;
|
|||
|
||||
- (void)_setStickerEntityPosition:(TGPhotoPaintStickerEntity *)entity
|
||||
{
|
||||
TGDocumentMediaAttachment *document = entity.document;
|
||||
TGDocumentAttributeSticker *sticker = nil;
|
||||
// for (id attribute in document.attributes)
|
||||
// {
|
||||
// if ([attribute isKindOfClass:[TGDocumentAttributeSticker class]])
|
||||
// {
|
||||
// sticker = (TGDocumentAttributeSticker *)attribute;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
|
||||
TGPhotoMaskPosition *position = nil; // [self _positionForMask:sticker documentId:document.documentId];
|
||||
TGStickerMaskDescription *mask = [_stickersContext maskDescriptionForDocument:entity.document];
|
||||
int64_t documentId = [_stickersContext documentIdForDocument:entity.document];
|
||||
TGPhotoMaskPosition *position = [self _positionForMaskDescription:mask documentId:documentId];
|
||||
if (position != nil)
|
||||
{
|
||||
entity.position = position.center;
|
||||
|
|
@ -2294,12 +2271,12 @@ const CGFloat TGPhotoPaintStickerKeyboardSize = 260.0f;
|
|||
}
|
||||
}
|
||||
|
||||
- (TGPhotoMaskPosition *)_positionForMask:(TGDocumentAttributeSticker *)sticker documentId:(int64_t)documentId
|
||||
- (TGPhotoMaskPosition *)_positionForMaskDescription:(TGStickerMaskDescription *)mask documentId:(int64_t)documentId
|
||||
{
|
||||
if (sticker.mask == nil)
|
||||
if (mask == nil)
|
||||
return nil;
|
||||
|
||||
TGPhotoMaskAnchor anchor = [TGPhotoMaskPosition anchorOfMask:sticker.mask];
|
||||
TGPhotoMaskAnchor anchor = [TGPhotoMaskPosition anchorOfMask:mask];
|
||||
if (anchor == TGPhotoMaskAnchorNone)
|
||||
return nil;
|
||||
|
||||
|
|
@ -2352,12 +2329,12 @@ const CGFloat TGPhotoPaintStickerKeyboardSize = 260.0f;
|
|||
break;
|
||||
}
|
||||
|
||||
CGFloat scale = referenceWidth / baseSize.width * sticker.mask.zoom;
|
||||
CGFloat scale = referenceWidth / baseSize.width * mask.zoom;
|
||||
|
||||
CGPoint xComp = CGPointMake(sin(M_PI_2 - angle) * referenceWidth * sticker.mask.point.x,
|
||||
cos(M_PI_2 - angle) * referenceWidth * sticker.mask.point.x);
|
||||
CGPoint yComp = CGPointMake(cos(M_PI_2 + angle) * referenceWidth * sticker.mask.point.y,
|
||||
sin(M_PI_2 + angle) * referenceWidth * sticker.mask.point.y);
|
||||
CGPoint xComp = CGPointMake(sin(M_PI_2 - angle) * referenceWidth * mask.point.x,
|
||||
cos(M_PI_2 - angle) * referenceWidth * mask.point.x);
|
||||
CGPoint yComp = CGPointMake(cos(M_PI_2 + angle) * referenceWidth * mask.point.y,
|
||||
sin(M_PI_2 + angle) * referenceWidth * mask.point.y);
|
||||
|
||||
CGPoint position = CGPointMake(referencePoint.x + xComp.x + yComp.x, referencePoint.y + xComp.y + yComp.y);
|
||||
|
||||
|
|
@ -2425,21 +2402,13 @@ const CGFloat TGPhotoPaintStickerKeyboardSize = 260.0f;
|
|||
continue;
|
||||
|
||||
TGPhotoPaintStickerEntity *entity = view.entity;
|
||||
TGDocumentMediaAttachment *document = entity.document;
|
||||
TGDocumentAttributeSticker *sticker = nil;
|
||||
for (id attribute in document.attributes)
|
||||
{
|
||||
if ([attribute isKindOfClass:[TGDocumentAttributeSticker class]])
|
||||
{
|
||||
sticker = (TGDocumentAttributeSticker *)attribute;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ([TGPhotoMaskPosition anchorOfMask:sticker.mask] != anchor)
|
||||
TGStickerMaskDescription *mask = [_stickersContext maskDescriptionForDocument:view.entity.document];
|
||||
int64_t maskDocumentId = [_stickersContext documentIdForDocument:entity.document];
|
||||
|
||||
if ([TGPhotoMaskPosition anchorOfMask:mask] != anchor)
|
||||
continue;
|
||||
|
||||
if ((documentId == document.documentId || _faces.count > 1) && TGPaintDistance(entity.position, anchorPoint) < minDistance)
|
||||
if ((documentId == maskDocumentId || _faces.count > 1) && TGPaintDistance(entity.position, anchorPoint) < minDistance)
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@
|
|||
#import <LegacyComponents/TGPaintingData.h>
|
||||
|
||||
#import "TGPhotoEditorController.h"
|
||||
#import "TGPhotoEditorItemController.h"
|
||||
#import "TGPhotoEditorPreviewView.h"
|
||||
#import "TGPhotoEditorHUDView.h"
|
||||
|
||||
|
|
@ -62,7 +61,6 @@ const CGFloat TGPhotoEditorToolsLandscapePanelSize = TGPhotoEditorToolsPanelSize
|
|||
|
||||
@property (nonatomic, weak) PGPhotoEditor *photoEditor;
|
||||
@property (nonatomic, weak) TGPhotoEditorPreviewView *previewView;
|
||||
@property (nonatomic, weak) TGPhotoEditorItemController *editorItemController;
|
||||
|
||||
@end
|
||||
|
||||
|
|
@ -147,23 +145,36 @@ const CGFloat TGPhotoEditorToolsLandscapePanelSize = TGPhotoEditorToolsPanelSize
|
|||
TGPhotoEditorPreviewView *previewView = _previewView;
|
||||
previewView.hidden = true;
|
||||
previewView.interactionEnded = _interactionEnded;
|
||||
|
||||
bool forVideo = _photoEditor.forVideo;
|
||||
previewView.touchedUp = ^
|
||||
{
|
||||
__strong TGPhotoToolsController *strongSelf = weakSelf;
|
||||
if (strongSelf != nil)
|
||||
if (strongSelf != nil) {
|
||||
[strongSelf->_hudView setText:nil];
|
||||
|
||||
if (forVideo) {
|
||||
strongSelf->_photoEditor.disableAll = false;
|
||||
}
|
||||
}
|
||||
};
|
||||
previewView.touchedDown = ^
|
||||
{
|
||||
__strong TGPhotoToolsController *strongSelf = weakSelf;
|
||||
if (strongSelf != nil)
|
||||
if (strongSelf != nil) {
|
||||
[strongSelf->_hudView setText:TGLocalized(@"PhotoEditor.Original")];
|
||||
|
||||
if (forVideo) {
|
||||
strongSelf->_photoEditor.disableAll = true;
|
||||
}
|
||||
}
|
||||
};
|
||||
previewView.tapped = ^{
|
||||
__strong TGPhotoToolsController *strongSelf = weakSelf;
|
||||
if (strongSelf != nil)
|
||||
[strongSelf setPreview:!strongSelf->_preview animated:true];
|
||||
};
|
||||
previewView.customTouchDownHandling = forVideo;
|
||||
[self.view addSubview:_previewView];
|
||||
|
||||
_wrapperView = [[TGPhotoToolsWrapperView alloc] initWithFrame:CGRectZero];
|
||||
|
|
@ -241,10 +252,6 @@ const CGFloat TGPhotoEditorToolsLandscapePanelSize = TGPhotoEditorToolsPanelSize
|
|||
|
||||
- (BOOL)shouldAutorotate
|
||||
{
|
||||
TGPhotoEditorItemController *controller = self.editorItemController;
|
||||
if (controller != nil)
|
||||
return [controller shouldAutorotate];
|
||||
|
||||
bool toolTracking = _toolAreaView.isTracking || _portraitToolControlView.isTracking || _landscapeToolControlView.isTracking;
|
||||
|
||||
TGPhotoEditorPreviewView *previewView = self.previewView;
|
||||
|
|
@ -342,6 +349,7 @@ const CGFloat TGPhotoEditorToolsLandscapePanelSize = TGPhotoEditorToolsPanelSize
|
|||
TGPhotoEditorPreviewView *previewView = self.previewView;
|
||||
previewView.touchedUp = nil;
|
||||
previewView.touchedDown = nil;
|
||||
previewView.tapped = nil;
|
||||
previewView.interactionEnded = nil;
|
||||
|
||||
[_toolAreaView.superview bringSubviewToFront:_toolAreaView];
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
#import "TGPhotoVideoEditor.h"
|
||||
|
||||
#import "TGMediaEditingContext.h"b
|
||||
#import "TGMediaEditingContext.h"
|
||||
|
||||
#import "TGMediaPickerGalleryModel.h"
|
||||
#import "TGMediaPickerGalleryPhotoItem.h"
|
||||
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
@implementation TGPhotoVideoEditor
|
||||
|
||||
+ (void)presentWithContext:(id<LegacyComponentsContext>)context controller:(TGViewController *)controller caption:(NSString *)caption entities:(NSArray *)entities withItem:(id<TGMediaEditableItem, TGMediaSelectableItem>)item recipientName:(NSString *)recipientName completion:(void (^)(id<TGMediaEditableItem>, TGMediaEditingContext *))completion dismissed:(void (^)())dismissed
|
||||
+ (void)presentWithContext:(id<LegacyComponentsContext>)context controller:(TGViewController *)controller caption:(NSString *)caption entities:(NSArray *)entities withItem:(id<TGMediaEditableItem, TGMediaSelectableItem>)item recipientName:(NSString *)recipientName stickersContext:(id<TGPhotoPaintStickersContext>)stickersContext completion:(void (^)(id<TGMediaEditableItem>, TGMediaEditingContext *))completion dismissed:(void (^)())dismissed
|
||||
{
|
||||
id<LegacyComponentsOverlayWindowManager> windowManager = [context makeOverlayWindowManager];
|
||||
id<LegacyComponentsContext> windowContext = [windowManager context];
|
||||
|
|
@ -28,6 +28,7 @@
|
|||
else
|
||||
galleryItem = [[TGMediaPickerGalleryPhotoItem alloc] initWithAsset:item];
|
||||
galleryItem.editingContext = editingContext;
|
||||
galleryItem.stickersContext = stickersContext;
|
||||
|
||||
TGMediaPickerGalleryModel *model = [[TGMediaPickerGalleryModel alloc] initWithContext:windowContext items:@[galleryItem] focusItem:galleryItem selectionContext:nil editingContext:editingContext hasCaptions:true allowCaptionEntities:true hasTimer:false onlyCrop:false inhibitDocumentCaptions:false hasSelectionPanel:false hasCamera:false recipientName:recipientName];
|
||||
model.controller = galleryController;
|
||||
|
|
|
|||
|
|
@ -256,7 +256,7 @@ public func legacyAttachmentMenu(context: AccountContext, peer: Peer, editMediaO
|
|||
|
||||
present(legacyController, nil)
|
||||
|
||||
TGPhotoVideoEditor.present(with: legacyController.context, controller: emptyController, caption: "", entities: [], withItem: item, recipientName: recipientName, completion: { result, editingContext in
|
||||
TGPhotoVideoEditor.present(with: legacyController.context, controller: emptyController, caption: "", entities: [], withItem: item, recipientName: recipientName, stickersContext: paintStickersContext, completion: { result, editingContext in
|
||||
let intent: TGMediaAssetsControllerIntent = TGMediaAssetsControllerSendMediaIntent
|
||||
let signals = TGCameraController.resultSignals(for: nil, editingContext: editingContext, currentItem: result as! TGMediaSelectableItem, storeAssets: false, saveEditedPhotos: false, descriptionGenerator: legacyAssetPickerItemGenerator())
|
||||
sendMessagesWithSignals(signals, false, 0)
|
||||
|
|
|
|||
|
|
@ -19,11 +19,21 @@ public func guessMimeTypeByFileExtension(_ ext: String) -> String {
|
|||
return TGMimeTypeMap.mimeType(forExtension: ext) ?? "application/binary"
|
||||
}
|
||||
|
||||
public func configureLegacyAssetPicker(_ controller: TGMediaAssetsController, context: AccountContext, peer: Peer, captionsEnabled: Bool = true, storeCreatedAssets: Bool = true, showFileTooltip: Bool = false, initialCaption: String, hasSchedule: Bool, presentWebSearch: (() -> Void)?, presentSelectionLimitExceeded: @escaping () -> Void, presentSchedulePicker: @escaping (@escaping (Int32) -> Void) -> Void) {
|
||||
public func configureLegacyAssetPicker(_ controller: TGMediaAssetsController, context: AccountContext, peer: Peer, captionsEnabled: Bool = true, storeCreatedAssets: Bool = true, showFileTooltip: Bool = false, initialCaption: String, hasSchedule: Bool, presentWebSearch: (() -> Void)?, presentSelectionLimitExceeded: @escaping () -> Void, presentSchedulePicker: @escaping (@escaping (Int32) -> Void) -> Void, presentStickers: @escaping (@escaping (TelegramMediaFile, Bool, UIView, CGRect) -> Void) -> Void) {
|
||||
let isSecretChat = peer.id.namespace == Namespaces.Peer.SecretChat
|
||||
|
||||
let paintStickersContext = LegacyPaintStickersContext(context: context)
|
||||
paintStickersContext.presentStickersController = { completion in
|
||||
presentStickers({ file, animated, view, rect in
|
||||
let coder = PostboxEncoder()
|
||||
coder.encodeRootObject(file)
|
||||
completion?(coder.makeData(), animated, view, rect)
|
||||
})
|
||||
}
|
||||
|
||||
controller.captionsEnabled = captionsEnabled
|
||||
controller.inhibitDocumentCaptions = false
|
||||
controller.stickersContext = paintStickersContext
|
||||
controller.suggestionContext = legacySuggestionContext(context: context, peerId: peer.id)
|
||||
if peer.id != context.account.peerId {
|
||||
if peer is TelegramUser {
|
||||
|
|
|
|||
|
|
@ -50,6 +50,10 @@ class LegacyPaintStickerView: UIView, TGPhotoPaintStickerRenderView {
|
|||
}
|
||||
}
|
||||
|
||||
func documentId() -> Int64 {
|
||||
return self.file.fileId.id
|
||||
}
|
||||
|
||||
private func setup() {
|
||||
if let dimensions = self.file.dimensions {
|
||||
if self.file.isAnimatedSticker {
|
||||
|
|
|
|||
|
|
@ -301,6 +301,41 @@ public final class LegacyPaintStickersContext: NSObject, TGPhotoPaintStickersCon
|
|||
public init(context: AccountContext) {
|
||||
self.context = context
|
||||
}
|
||||
|
||||
public func documentId(forDocument document: Any!) -> Int64 {
|
||||
if let data = document as? Data{
|
||||
let decoder = PostboxDecoder(buffer: MemoryBuffer(data: data))
|
||||
if let file = decoder.decodeRootObject() as? TelegramMediaFile {
|
||||
return file.fileId.id
|
||||
} else {
|
||||
return 0
|
||||
}
|
||||
} else {
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
public func maskDescription(forDocument document: Any!) -> TGStickerMaskDescription? {
|
||||
if let data = document as? Data{
|
||||
let decoder = PostboxDecoder(buffer: MemoryBuffer(data: data))
|
||||
if let file = decoder.decodeRootObject() as? TelegramMediaFile {
|
||||
for attribute in file.attributes {
|
||||
if case let .Sticker(_, _, maskData) = attribute {
|
||||
if let maskData = maskData {
|
||||
return TGStickerMaskDescription(n: maskData.n, point: CGPoint(x: maskData.x, y: maskData.y), zoom: CGFloat(maskData.zoom))
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
public func stickerView(forDocument document: Any!) -> (UIView & TGPhotoPaintStickerRenderView)! {
|
||||
if let data = document as? Data{
|
||||
|
|
|
|||
|
|
@ -6046,6 +6046,14 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||
}
|
||||
})
|
||||
}
|
||||
}, presentStickers: { [weak self] completion in
|
||||
if let strongSelf = self {
|
||||
let controller = DrawingStickersScreen(context: strongSelf.context, selectSticker: { fileReference, node, rect in
|
||||
completion(fileReference.media, fileReference.media.isAnimatedSticker, node.view, rect)
|
||||
return true
|
||||
})
|
||||
strongSelf.present(controller, in: .window(.root))
|
||||
}
|
||||
})
|
||||
}
|
||||
}, openFileGallery: {
|
||||
|
|
@ -6287,6 +6295,14 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||
}
|
||||
})
|
||||
}
|
||||
}, presentStickers: { [weak self] completion in
|
||||
if let strongSelf = self {
|
||||
let controller = DrawingStickersScreen(context: strongSelf.context, selectSticker: { fileReference, node, rect in
|
||||
completion(fileReference.media, fileReference.media.isAnimatedSticker, node.view, rect)
|
||||
return true
|
||||
})
|
||||
strongSelf.present(controller, in: .window(.root))
|
||||
}
|
||||
})
|
||||
controller.descriptionGenerator = legacyAssetPickerItemGenerator()
|
||||
controller.completionBlock = { [weak legacyController] signals, silentPosting, scheduleTime in
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import ShareController
|
|||
import LegacyUI
|
||||
import LegacyMediaPickerUI
|
||||
|
||||
func presentedLegacyCamera(context: AccountContext, peer: Peer, cameraView: TGAttachmentCameraView?, menuController: TGMenuSheetController?, parentController: ViewController, editingMedia: Bool, saveCapturedPhotos: Bool, mediaGrouping: Bool, initialCaption: String, hasSchedule: Bool, sendMessagesWithSignals: @escaping ([Any]?, Bool, Int32) -> Void, recognizedQRCode: @escaping (String) -> Void = { _ in }, presentSchedulePicker: @escaping (@escaping (Int32) -> Void) -> Void) {
|
||||
func presentedLegacyCamera(context: AccountContext, peer: Peer, cameraView: TGAttachmentCameraView?, menuController: TGMenuSheetController?, parentController: ViewController, editingMedia: Bool, saveCapturedPhotos: Bool, mediaGrouping: Bool, initialCaption: String, hasSchedule: Bool, sendMessagesWithSignals: @escaping ([Any]?, Bool, Int32) -> Void, recognizedQRCode: @escaping (String) -> Void = { _ in }, presentSchedulePicker: @escaping (@escaping (Int32) -> Void) -> Void, presentStickers: @escaping (@escaping (TelegramMediaFile, Bool, UIView, CGRect) -> Void) -> Void) {
|
||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||
let legacyController = LegacyController(presentation: .custom, theme: presentationData.theme)
|
||||
legacyController.supportedOrientations = ViewControllerSupportedOrientations(regularSize: .portrait, compactSize: .portrait)
|
||||
|
|
@ -58,6 +58,16 @@ func presentedLegacyCamera(context: AccountContext, peer: Peer, cameraView: TGAt
|
|||
}
|
||||
}
|
||||
|
||||
let paintStickersContext = LegacyPaintStickersContext(context: context)
|
||||
paintStickersContext.presentStickersController = { completion in
|
||||
presentStickers({ file, animated, view, rect in
|
||||
let coder = PostboxEncoder()
|
||||
coder.encodeRootObject(file)
|
||||
completion?(coder.makeData(), animated, view, rect)
|
||||
})
|
||||
}
|
||||
|
||||
controller.stickersContext = paintStickersContext
|
||||
controller.isImportant = true
|
||||
controller.shouldStoreCapturedAssets = saveCapturedPhotos && !isSecretChat
|
||||
controller.allowCaptions = true
|
||||
|
|
|
|||
|
|
@ -112,8 +112,8 @@ class LegacyWebSearchItem: NSObject, TGMediaEditableItem, TGMediaSelectableItem
|
|||
|
||||
private class LegacyWebSearchGalleryItem: TGModernGalleryImageItem, TGModernGalleryEditableItem, TGModernGallerySelectableItem {
|
||||
var selectionContext: TGMediaSelectionContext!
|
||||
|
||||
var editingContext: TGMediaEditingContext!
|
||||
var stickersContext: TGPhotoPaintStickersContext!
|
||||
let item: LegacyWebSearchItem
|
||||
|
||||
init(item: LegacyWebSearchItem) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue