mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Merge commit 'e5186bd7ae1b9f8bc8b1a0130b725a26ee5755f2'
This commit is contained in:
commit
4e6579d5b6
@ -1126,6 +1126,26 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
|
||||
self.chatListDisplayNode.containerNode.updateEnableAdjacentFilterLoading(true)
|
||||
|
||||
self.chatListDisplayNode.containerNode.didBeginSelectingChats = { [weak self] in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
if !strongSelf.chatListDisplayNode.didBeginSelectingChatsWhileEditing {
|
||||
var isEditing = false
|
||||
strongSelf.chatListDisplayNode.containerNode.updateState { state in
|
||||
isEditing = state.editing
|
||||
return state
|
||||
}
|
||||
if !isEditing {
|
||||
strongSelf.editPressed()
|
||||
}
|
||||
strongSelf.chatListDisplayNode.didBeginSelectingChatsWhileEditing = true
|
||||
if let layout = strongSelf.validLayout {
|
||||
strongSelf.updateLayout(layout: layout, transition: .animated(duration: 0.2, curve: .easeInOut))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
guard case .root = self.groupId else {
|
||||
return
|
||||
}
|
||||
@ -1265,27 +1285,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
return true
|
||||
})
|
||||
}
|
||||
|
||||
self.chatListDisplayNode.containerNode.didBeginSelectingChats = { [weak self] in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
if !strongSelf.chatListDisplayNode.didBeginSelectingChatsWhileEditing {
|
||||
var isEditing = false
|
||||
strongSelf.chatListDisplayNode.containerNode.updateState { state in
|
||||
isEditing = state.editing
|
||||
return state
|
||||
}
|
||||
if !isEditing {
|
||||
strongSelf.editPressed()
|
||||
}
|
||||
strongSelf.chatListDisplayNode.didBeginSelectingChatsWhileEditing = true
|
||||
if let layout = strongSelf.validLayout {
|
||||
strongSelf.updateLayout(layout: layout, transition: .animated(duration: 0.2, curve: .easeInOut))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if !self.processedFeaturedFilters {
|
||||
let initializedFeatured = self.context.account.postbox.preferencesView(keys: [
|
||||
PreferencesKeys.chatListFiltersFeaturedState
|
||||
|
@ -1997,6 +1997,13 @@ public final class ChatListNode: ListView {
|
||||
}
|
||||
|
||||
private func handlePanSelection(location: CGPoint) {
|
||||
var location = location
|
||||
if location.y < self.insets.top {
|
||||
location.y = self.insets.top + 5.0
|
||||
} else if location.y > self.frame.height - self.insets.bottom {
|
||||
location.y = self.frame.height - self.insets.bottom - 5.0
|
||||
}
|
||||
|
||||
if let state = self.selectionPanState {
|
||||
if let peer = self.peerAtPoint(location) {
|
||||
if peer.id == state.initialPeerId {
|
||||
|
12
submodules/LegacyComponents/LegacyImages.xcassets/Camera/Flash.imageset/Contents.json
vendored
Normal file
12
submodules/LegacyComponents/LegacyImages.xcassets/Camera/Flash.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "ic_cam_flashon (1).pdf",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
BIN
submodules/LegacyComponents/LegacyImages.xcassets/Camera/Flash.imageset/ic_cam_flashon (1).pdf
vendored
Normal file
BIN
submodules/LegacyComponents/LegacyImages.xcassets/Camera/Flash.imageset/ic_cam_flashon (1).pdf
vendored
Normal file
Binary file not shown.
@ -60,7 +60,7 @@ typedef enum
|
||||
@property (nonatomic, copy) void(^finishedModeChange)(void);
|
||||
|
||||
@property (nonatomic, copy) void(^beganPositionChange)(bool targetPositionHasFlash, bool targetPositionHasZoom, void(^commitBlock)(void));
|
||||
@property (nonatomic, copy) void(^finishedPositionChange)(void);
|
||||
@property (nonatomic, copy) void(^finishedPositionChange)(bool targetPositionHasZoom);
|
||||
|
||||
@property (nonatomic, copy) void(^beganAdjustingFocus)(void);
|
||||
@property (nonatomic, copy) void(^finishedAdjustingFocus)(void);
|
||||
|
@ -6,15 +6,13 @@
|
||||
@property (nonatomic, assign) PGCameraFlashMode mode;
|
||||
@property (nonatomic, assign) UIInterfaceOrientation interfaceOrientation;
|
||||
|
||||
@property (nonatomic, copy) void(^becameActive)(void);
|
||||
@property (nonatomic, copy) void(^modeChanged)(PGCameraFlashMode mode);
|
||||
|
||||
- (void)setFlashUnavailable:(bool)unavailable;
|
||||
- (void)setFlashActive:(bool)active;
|
||||
|
||||
- (void)setHidden:(bool)hidden animated:(bool)animated;
|
||||
|
||||
- (void)dismissAnimated:(bool)animated;
|
||||
|
||||
@end
|
||||
|
||||
extern const CGFloat TGCameraFlashControlHeight;
|
||||
|
@ -18,6 +18,10 @@
|
||||
@class TGMediaPickerGallerySelectedItemsModel;
|
||||
@class TGMediaEditingContext;
|
||||
|
||||
@interface TGCameraCornersView : UIImageView
|
||||
|
||||
@end
|
||||
|
||||
@interface TGCameraMainView : UIView
|
||||
{
|
||||
UIInterfaceOrientation _interfaceOrientation;
|
||||
|
@ -27,7 +27,7 @@
|
||||
|
||||
- (void)setHidden:(bool)hidden animated:(bool)animated;
|
||||
|
||||
- (instancetype)initWithFrame:(CGRect)frame hasUltrawideCamera:(bool)hasUltrawideCamera hasTelephotoCamera:(bool)hasTelephotoCamera;
|
||||
- (instancetype)initWithFrame:(CGRect)frame hasUltrawideCamera:(bool)hasUltrawideCamera hasTelephotoCamera:(bool)hasTelephotoCamera minZoomLevel:(CGFloat)minZoomLevel maxZoomLevel:(CGFloat)maxZoomLevel;
|
||||
|
||||
@end
|
||||
|
||||
@ -38,4 +38,6 @@
|
||||
|
||||
- (void)setHidden:(bool)hidden animated:(bool)animated;
|
||||
|
||||
- (instancetype)initWithFrame:(CGRect)frame hasUltrawideCamera:(bool)hasUltrawideCamera hasTelephotoCamera:(bool)hasTelephotoCamera;
|
||||
|
||||
@end
|
||||
|
@ -690,7 +690,7 @@ NSString *const PGCameraAdjustingFocusKey = @"adjustingFocus";
|
||||
[strongSelf.captureSession setCurrentCameraPosition:targetCameraPosition];
|
||||
|
||||
if (strongSelf.finishedPositionChange != nil)
|
||||
strongSelf.finishedPositionChange();
|
||||
strongSelf.finishedPositionChange([PGCameraCaptureSession _isZoomAvailableForDevice:targetDevice]);
|
||||
|
||||
[strongSelf _subscribeForCameraChanges];
|
||||
}];
|
||||
|
@ -107,6 +107,7 @@ static CGPoint TGCameraControllerClampPointToScreenSize(__unused id self, __unus
|
||||
UIView *_backgroundView;
|
||||
TGCameraPreviewView *_previewView;
|
||||
TGCameraMainView *_interfaceView;
|
||||
TGCameraCornersView *_cornersView;
|
||||
UIView *_overlayView;
|
||||
TGCameraFocusCrosshairsControl *_focusControl;
|
||||
TGCameraRectangleView *_rectangleView;
|
||||
@ -318,6 +319,9 @@ static CGPoint TGCameraControllerClampPointToScreenSize(__unused id self, __unus
|
||||
_interfaceView.transform = CGAffineTransformMakeRotation(TGRotationForInterfaceOrientation(interfaceOrientation));
|
||||
_interfaceView.frame = CGRectMake(0, 0, referenceSize.width, referenceSize.height);
|
||||
}
|
||||
|
||||
_cornersView = [[TGCameraCornersView alloc] init];
|
||||
|
||||
if (_intent == TGCameraControllerPassportIdIntent)
|
||||
[_interfaceView setDocumentFrameHidden:false];
|
||||
_selectedItemsModel = [[TGMediaPickerGallerySelectedItemsModel alloc] initWithSelectionContext:nil items:[_items copy]];
|
||||
@ -451,7 +455,8 @@ static CGPoint TGCameraControllerClampPointToScreenSize(__unused id self, __unus
|
||||
}
|
||||
|
||||
[_autorotationCorrectionView addSubview:_interfaceView];
|
||||
|
||||
[_autorotationCorrectionView addSubview:_cornersView];
|
||||
|
||||
_photoSwipeGestureRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipe:)];
|
||||
_photoSwipeGestureRecognizer.delegate = self;
|
||||
[_autorotationCorrectionView addGestureRecognizer:_photoSwipeGestureRecognizer];
|
||||
@ -633,7 +638,9 @@ static CGPoint TGCameraControllerClampPointToScreenSize(__unused id self, __unus
|
||||
[strongSelf->_focusControl reset];
|
||||
|
||||
[strongSelf->_interfaceView setHasFlash:targetPositionHasFlash];
|
||||
[strongSelf->_interfaceView setHasZoom:targetPositionHasZoom];
|
||||
if (!targetPositionHasZoom) {
|
||||
[strongSelf->_interfaceView setHasZoom:targetPositionHasZoom];
|
||||
}
|
||||
strongSelf->_camera.zoomLevel = 0.0f;
|
||||
|
||||
strongSelf.view.userInteractionEnabled = false;
|
||||
@ -664,7 +671,7 @@ static CGPoint TGCameraControllerClampPointToScreenSize(__unused id self, __unus
|
||||
}
|
||||
};
|
||||
|
||||
_camera.finishedPositionChange = ^
|
||||
_camera.finishedPositionChange = ^(bool targetPositionHasZoom)
|
||||
{
|
||||
__strong TGCameraController *strongSelf = weakSelf;
|
||||
if (strongSelf == nil)
|
||||
@ -675,6 +682,10 @@ static CGPoint TGCameraControllerClampPointToScreenSize(__unused id self, __unus
|
||||
[strongSelf->_previewView endTransitionAnimated:true];
|
||||
[strongSelf->_interfaceView setZoomLevel:1.0f displayNeeded:false];
|
||||
|
||||
if (targetPositionHasZoom) {
|
||||
[strongSelf->_interfaceView setHasZoom:targetPositionHasZoom];
|
||||
}
|
||||
|
||||
if (strongSelf->_camera.hasFlash && strongSelf->_camera.flashActive)
|
||||
[strongSelf->_interfaceView setFlashActive:true];
|
||||
|
||||
@ -712,8 +723,7 @@ static CGPoint TGCameraControllerClampPointToScreenSize(__unused id self, __unus
|
||||
|
||||
TGDispatchOnMainThread(^
|
||||
{
|
||||
if (!strongSelf->_camera.isRecordingVideo)
|
||||
[strongSelf->_interfaceView setFlashActive:active];
|
||||
[strongSelf->_interfaceView setFlashActive:active];
|
||||
});
|
||||
};
|
||||
|
||||
@ -904,12 +914,22 @@ static CGPoint TGCameraControllerClampPointToScreenSize(__unused id self, __unus
|
||||
animation.duration = 0.2f;
|
||||
[_interfaceView.layer addAnimation:animation forKey:@"opacity"];
|
||||
|
||||
CABasicAnimation *cornersAnimation = [CABasicAnimation animationWithKeyPath:@"opacity"];
|
||||
cornersAnimation.fromValue = @(_cornersView.alpha);
|
||||
cornersAnimation.toValue = @(hidden ? 0.0f : 1.0f);
|
||||
cornersAnimation.duration = 0.2f;
|
||||
[_cornersView.layer addAnimation:cornersAnimation forKey:@"opacity"];
|
||||
|
||||
_interfaceView.alpha = hidden ? 0.0f : 1.0f;
|
||||
_cornersView.alpha = hidden ? 0.0 : 1.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
[_interfaceView.layer removeAllAnimations];
|
||||
_interfaceView.alpha = 0.0f;
|
||||
_interfaceView.alpha = hidden ? 0.0 : 1.0;
|
||||
|
||||
[_cornersView.layer removeAllAnimations];
|
||||
_cornersView.alpha = hidden ? 0.0 : 1.0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2156,6 +2176,7 @@ static CGPoint TGCameraControllerClampPointToScreenSize(__unused id self, __unus
|
||||
[UIView animateWithDuration:0.3f delay:0.1f options:UIViewAnimationOptionCurveLinear animations:^
|
||||
{
|
||||
_interfaceView.alpha = 1.0f;
|
||||
_cornersView.alpha = 1.0;
|
||||
} completion:nil];
|
||||
|
||||
_interfaceView.previewViewFrame = _previewView.frame;
|
||||
@ -2173,11 +2194,13 @@ static CGPoint TGCameraControllerClampPointToScreenSize(__unused id self, __unus
|
||||
|
||||
_backgroundView.alpha = 0.0f;
|
||||
_interfaceView.alpha = 0.0f;
|
||||
_cornersView.alpha = 0.0;
|
||||
|
||||
[UIView animateWithDuration:0.3f animations:^
|
||||
{
|
||||
_backgroundView.alpha = 1.0f;
|
||||
_interfaceView.alpha = 1.0f;
|
||||
_cornersView.alpha = 1.0;
|
||||
}];
|
||||
|
||||
CGRect fromFrame = rect;
|
||||
@ -2191,10 +2214,18 @@ static CGPoint TGCameraControllerClampPointToScreenSize(__unused id self, __unus
|
||||
frameAnimation.springSpeed = 20;
|
||||
frameAnimation.springBounciness = 1;
|
||||
[_previewView pop_addAnimation:frameAnimation forKey:@"frame"];
|
||||
|
||||
POPSpringAnimation *cornersFrameAnimation = [POPSpringAnimation animationWithPropertyNamed:kPOPViewFrame];
|
||||
cornersFrameAnimation.fromValue = [NSValue valueWithCGRect:fromFrame];
|
||||
cornersFrameAnimation.toValue = [NSValue valueWithCGRect:toFrame];
|
||||
cornersFrameAnimation.springSpeed = 20;
|
||||
cornersFrameAnimation.springBounciness = 1;
|
||||
[_cornersView pop_addAnimation:cornersFrameAnimation forKey:@"frame"];
|
||||
}
|
||||
else
|
||||
{
|
||||
_previewView.frame = toFrame;
|
||||
_cornersView.frame = toFrame;
|
||||
}
|
||||
|
||||
_interfaceView.previewViewFrame = toFrame;
|
||||
@ -2208,16 +2239,12 @@ static CGPoint TGCameraControllerClampPointToScreenSize(__unused id self, __unus
|
||||
_focusControl.active = false;
|
||||
_rectangleView.hidden = true;
|
||||
|
||||
[UIView animateWithDuration:0.3f animations:^
|
||||
{
|
||||
//[_context setApplicationStatusBarAlpha:1.0f];
|
||||
}];
|
||||
|
||||
[self setInterfaceHidden:true animated:true];
|
||||
|
||||
[UIView animateWithDuration:0.25f animations:^
|
||||
{
|
||||
_backgroundView.alpha = 0.0f;
|
||||
_cornersView.alpha = 0.0;
|
||||
}];
|
||||
|
||||
CGRect referenceFrame = CGRectZero;
|
||||
@ -2272,6 +2299,13 @@ static CGPoint TGCameraControllerClampPointToScreenSize(__unused id self, __unus
|
||||
[strongSelf dismiss];
|
||||
};
|
||||
[_previewView pop_addAnimation:frameAnimation forKey:@"frame"];
|
||||
|
||||
POPSpringAnimation *cornersAnimation = [POPSpringAnimation animationWithPropertyNamed:kPOPViewFrame];
|
||||
cornersAnimation.fromValue = [NSValue valueWithCGRect:_cornersView.frame];
|
||||
cornersAnimation.toValue = [NSValue valueWithCGRect:referenceFrame];
|
||||
cornersAnimation.springSpeed = 20;
|
||||
cornersAnimation.springBounciness = 1;
|
||||
[_cornersView pop_addAnimation:cornersAnimation forKey:@"frame"];
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -2328,6 +2362,7 @@ static CGPoint TGCameraControllerClampPointToScreenSize(__unused id self, __unus
|
||||
[UIView animateWithDuration:ABS(distance / velocity) animations:^
|
||||
{
|
||||
_previewView.frame = targetFrame;
|
||||
_cornersView.frame = targetFrame;
|
||||
} completion:^(__unused BOOL finished)
|
||||
{
|
||||
if (completion)
|
||||
@ -2344,11 +2379,13 @@ static CGPoint TGCameraControllerClampPointToScreenSize(__unused id self, __unus
|
||||
[UIView animateWithDuration:0.3 animations:^
|
||||
{
|
||||
_previewView.frame = frame;
|
||||
_cornersView.frame = frame;
|
||||
}];
|
||||
}
|
||||
else
|
||||
{
|
||||
_previewView.frame = frame;
|
||||
_cornersView.frame = frame;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2390,6 +2427,7 @@ static CGPoint TGCameraControllerClampPointToScreenSize(__unused id self, __unus
|
||||
[UIView animateWithDuration:0.3f delay:0.0f options:UIViewAnimationOptionCurveEaseInOut | UIViewAnimationOptionLayoutSubviews animations:^
|
||||
{
|
||||
_previewView.frame = frame;
|
||||
_cornersView.frame = frame;
|
||||
_overlayView.frame = frame;
|
||||
} completion:nil];
|
||||
}
|
||||
|
@ -2,21 +2,118 @@
|
||||
|
||||
#import "LegacyComponentsInternal.h"
|
||||
|
||||
#import "TGImageUtils.h"
|
||||
|
||||
#import "UIControl+HitTestEdgeInsets.h"
|
||||
|
||||
#import "TGCameraInterfaceAssets.h"
|
||||
#import <LegacyComponents/TGModernButton.h>
|
||||
|
||||
#import "POPBasicAnimation.h"
|
||||
|
||||
const CGFloat TGCameraFlashControlHeight = 44.0f;
|
||||
|
||||
@interface TGCameraFlashIcon: UIView
|
||||
{
|
||||
bool _active;
|
||||
CGFloat _progress;
|
||||
bool _on;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation TGCameraFlashIcon
|
||||
|
||||
- (instancetype)initWithFrame:(CGRect)frame {
|
||||
self = [super initWithFrame:frame];
|
||||
if (self != nil) {
|
||||
self.contentMode = UIViewContentModeRedraw;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)setOn:(bool)on animated:(bool)animated {
|
||||
_on = on;
|
||||
if (animated) {
|
||||
POPBasicAnimation *animation = [POPBasicAnimation animation];
|
||||
animation.property = [POPAnimatableProperty propertyWithName:@"progress" initializer:^(POPMutableAnimatableProperty *prop)
|
||||
{
|
||||
prop.readBlock = ^(TGCameraFlashIcon *view, CGFloat values[])
|
||||
{
|
||||
if (view != nil) {
|
||||
values[0] = view->_progress;
|
||||
}
|
||||
};
|
||||
|
||||
prop.writeBlock = ^(TGCameraFlashIcon *view, const CGFloat values[])
|
||||
{
|
||||
view->_progress = values[0];
|
||||
[view setNeedsDisplay];
|
||||
};
|
||||
|
||||
prop.threshold = 0.03f;
|
||||
}];
|
||||
animation.fromValue = @(_progress);
|
||||
animation.toValue = @(on ? 1.0 : 0.0);
|
||||
animation.duration = 0.2;
|
||||
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
|
||||
[self pop_addAnimation:animation forKey:@"progress"];
|
||||
} else {
|
||||
_progress = on ? 1.0 : 0.0;
|
||||
[self setNeedsDisplay];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setActive:(bool)active {
|
||||
_active = active;
|
||||
[self setNeedsDisplay];
|
||||
}
|
||||
|
||||
- (void)drawRect:(CGRect)__unused rect
|
||||
{
|
||||
CGContextRef context = UIGraphicsGetCurrentContext();
|
||||
CGRect bounds = CGRectMake(0, 0, rect.size.width, rect.size.height);
|
||||
|
||||
CGContextClearRect(context, bounds);
|
||||
|
||||
UIImage *iconImage = [UIImage imageNamed:@"Camera/Flash"];
|
||||
|
||||
if (_active && _on) {
|
||||
CGContextSetFillColorWithColor(context, [TGCameraInterfaceAssets accentColor].CGColor);
|
||||
CGContextFillEllipseInRect(context, CGRectInset(bounds, 2.5, 2.5));
|
||||
|
||||
[TGTintedImage(iconImage, [UIColor blackColor]) drawInRect:CGRectMake(0, 0, 30, 30)];
|
||||
} else {
|
||||
CGContextSetLineWidth(context, 1.0);
|
||||
CGContextSetStrokeColorWithColor(context, [UIColor colorWithWhite:1.0 alpha:0.5].CGColor);
|
||||
CGContextStrokeEllipseInRect(context, CGRectInset(bounds, 3.0, 3.0));
|
||||
|
||||
[TGTintedImage(iconImage, [UIColor whiteColor]) drawInRect:CGRectMake(0, 0, 30, 30)];
|
||||
}
|
||||
|
||||
CGFloat lineProgress = 1.0 - _progress;
|
||||
|
||||
if (lineProgress > 0.0) {
|
||||
CGMutablePathRef path = CGPathCreateMutable();
|
||||
CGPathMoveToPoint(path, NULL, 5, 5);
|
||||
CGPathAddLineToPoint(path, NULL, 5 + (bounds.size.width - 10.0) * lineProgress, 5 + (bounds.size.height - 10.0) * lineProgress);
|
||||
|
||||
CGPathRef strokedPath = CGPathCreateCopyByStrokingPath(path, NULL, 2.0f, kCGLineCapRound, kCGLineJoinMiter, 10);
|
||||
CGContextAddPath(context, strokedPath);
|
||||
CGPathRelease(strokedPath);
|
||||
CGPathRelease(path);
|
||||
|
||||
CGContextSetStrokeColorWithColor(context, [UIColor blackColor].CGColor);
|
||||
CGContextSetFillColorWithColor(context, [UIColor whiteColor].CGColor);
|
||||
CGContextDrawPath(context, kCGPathFillStroke);
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@interface TGCameraFlashControl ()
|
||||
{
|
||||
UIButton *_flashIconView;
|
||||
UIButton *_autoButton;
|
||||
UIButton *_onButton;
|
||||
UIButton *_offButton;
|
||||
|
||||
bool _active;
|
||||
TGCameraFlashIcon *_icon;
|
||||
UIButton *_button;
|
||||
}
|
||||
@end
|
||||
|
||||
@ -27,23 +124,22 @@ const CGFloat TGCameraFlashControlHeight = 44.0f;
|
||||
self = [super initWithFrame:frame];
|
||||
if (self != nil)
|
||||
{
|
||||
self.mode = PGCameraFlashModeOff;
|
||||
|
||||
self.hitTestEdgeInsets = UIEdgeInsetsMake(-10, -10, -10, -10);
|
||||
|
||||
_flashIconView = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 44, 44)];
|
||||
_flashIconView.adjustsImageWhenHighlighted = false;
|
||||
_flashIconView.contentMode = UIViewContentModeCenter;
|
||||
_flashIconView.exclusiveTouch = true;
|
||||
_flashIconView.hitTestEdgeInsets = UIEdgeInsetsMake(0, -10, 0, -10);
|
||||
_flashIconView.tag = -1;
|
||||
[_flashIconView setImage:[UIImage imageNamed:@"Camera/FlashOff"] forState:UIControlStateNormal];
|
||||
[_flashIconView addTarget:self action:@selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside];
|
||||
[self addSubview:_flashIconView];
|
||||
|
||||
[UIView performWithoutAnimation:^
|
||||
{
|
||||
self.mode = PGCameraFlashModeOff;
|
||||
[self setActive:false animated:false];
|
||||
}];
|
||||
_icon = [[TGCameraFlashIcon alloc] initWithFrame:CGRectMake(7, 7, 30, 30)];
|
||||
_icon.userInteractionEnabled = false;
|
||||
[self addSubview:_icon];
|
||||
|
||||
_button = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 44, 44)];
|
||||
_button.adjustsImageWhenHighlighted = false;
|
||||
_button.contentMode = UIViewContentModeCenter;
|
||||
_button.exclusiveTouch = true;
|
||||
_button.hitTestEdgeInsets = UIEdgeInsetsMake(0, -10, 0, -10);
|
||||
_button.tag = -1;
|
||||
[_button addTarget:self action:@selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside];
|
||||
[self addSubview:_button];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
@ -61,11 +157,11 @@ const CGFloat TGCameraFlashControlHeight = 44.0f;
|
||||
- (void)buttonPressed:(UIButton *)sender
|
||||
{
|
||||
if (_mode == PGCameraFlashModeOff) {
|
||||
self.mode = PGCameraFlashModeOn;
|
||||
[_flashIconView setImage:[UIImage imageNamed:@"Camera/FlashOn"] forState:UIControlStateNormal];
|
||||
self.mode = PGCameraFlashModeAuto;
|
||||
[_icon setOn:true animated:true];
|
||||
} else {
|
||||
self.mode = PGCameraFlashModeOff;
|
||||
[_flashIconView setImage:[UIImage imageNamed:@"Camera/FlashOff"] forState:UIControlStateNormal];
|
||||
[_icon setOn:false animated:true];
|
||||
}
|
||||
|
||||
if (self.modeChanged != nil)
|
||||
@ -75,35 +171,24 @@ const CGFloat TGCameraFlashControlHeight = 44.0f;
|
||||
- (void)setFlashUnavailable:(bool)unavailable
|
||||
{
|
||||
self.userInteractionEnabled = !unavailable;
|
||||
[self setActive:false animated:false];
|
||||
self.alpha = unavailable ? 0.4 : 1.0;
|
||||
}
|
||||
|
||||
- (void)setActive:(bool)active animated:(bool)animated
|
||||
- (void)setFlashActive:(bool)active
|
||||
{
|
||||
return;
|
||||
[_icon setActive:active];
|
||||
}
|
||||
|
||||
- (void)setMode:(PGCameraFlashMode)mode
|
||||
{
|
||||
_mode = mode;
|
||||
|
||||
[self setActive:false animated:_active];
|
||||
}
|
||||
|
||||
- (void)dismissAnimated:(bool)animated
|
||||
{
|
||||
if (animated && _active)
|
||||
[self setActive:false animated:animated];
|
||||
else
|
||||
[self setActive:false animated:false];
|
||||
[_icon setOn:mode == PGCameraFlashModeAuto animated:true];
|
||||
}
|
||||
|
||||
- (void)setHidden:(BOOL)hidden
|
||||
{
|
||||
self.alpha = hidden ? 0.0f : 1.0f;
|
||||
super.hidden = hidden;
|
||||
|
||||
[self setActive:false animated:false];
|
||||
}
|
||||
|
||||
- (void)setHidden:(bool)hidden animated:(bool)animated
|
||||
@ -123,16 +208,12 @@ const CGFloat TGCameraFlashControlHeight = 44.0f;
|
||||
|
||||
if (finished)
|
||||
self.hidden = hidden;
|
||||
|
||||
[self setActive:false animated:false];
|
||||
}];
|
||||
}
|
||||
else
|
||||
{
|
||||
self.alpha = hidden ? 0.0f : 1.0f;
|
||||
super.hidden = hidden;
|
||||
|
||||
[self setActive:false animated:false];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -11,6 +11,8 @@
|
||||
self = [super initWithFrame:frame];
|
||||
if (self != nil)
|
||||
{
|
||||
self.adjustsImageWhenHighlighted = false;
|
||||
self.modernHighlight = false;
|
||||
self.exclusiveTouch = true;
|
||||
self.backgroundColor = [TGCameraInterfaceAssets buttonColor];
|
||||
self.layer.cornerRadius = 24.0;
|
||||
@ -19,6 +21,16 @@
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)_setHighligtedAnimated:(bool)highlighted animated:(bool)animated {
|
||||
if (animated) {
|
||||
[UIView animateWithDuration:0.3 animations:^{
|
||||
self.layer.sublayerTransform = highlighted ? CATransform3DMakeScale(0.9, 0.9, 1.0) : CATransform3DIdentity;
|
||||
}];
|
||||
} else {
|
||||
self.layer.sublayerTransform = highlighted ? CATransform3DMakeScale(0.9, 0.9, 1.0) : CATransform3DIdentity;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setHidden:(BOOL)hidden
|
||||
{
|
||||
self.alpha = hidden ? 0.0f : 1.0f;
|
||||
@ -60,6 +72,8 @@
|
||||
self = [super initWithFrame:frame];
|
||||
if (self != nil)
|
||||
{
|
||||
self.adjustsImageWhenHighlighted = false;
|
||||
self.modernHighlight = false;
|
||||
self.exclusiveTouch = true;
|
||||
self.backgroundColor = [TGCameraInterfaceAssets buttonColor];
|
||||
self.layer.cornerRadius = 24.0;
|
||||
@ -68,6 +82,16 @@
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)_setHighligtedAnimated:(bool)highlighted animated:(bool)animated {
|
||||
if (animated) {
|
||||
[UIView animateWithDuration:0.3 animations:^{
|
||||
self.layer.sublayerTransform = highlighted ? CATransform3DMakeScale(0.9, 0.9, 1.0) : CATransform3DIdentity;
|
||||
}];
|
||||
} else {
|
||||
self.layer.sublayerTransform = highlighted ? CATransform3DMakeScale(0.9, 0.9, 1.0) : CATransform3DIdentity;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setHidden:(BOOL)hidden
|
||||
{
|
||||
self.alpha = hidden ? 0.0f : 1.0f;
|
||||
|
@ -82,6 +82,8 @@
|
||||
bool _displayedTooltip;
|
||||
TGMenuContainerView *_tooltipContainerView;
|
||||
NSTimer *_tooltipTimer;
|
||||
|
||||
bool _dismissingWheel;
|
||||
}
|
||||
@end
|
||||
|
||||
@ -261,21 +263,31 @@
|
||||
_toastView.userInteractionEnabled = false;
|
||||
[self addSubview:_toastView];
|
||||
|
||||
_zoomModeView = [[TGCameraZoomModeView alloc] initWithFrame:CGRectMake(floor((frame.size.width - 129.0) / 2.0), frame.size.height - _bottomPanelHeight - _bottomPanelOffset - 18 - 43, 129, 43) hasUltrawideCamera:hasUltrawideCamera hasTelephotoCamera:hasTelephotoCamera];
|
||||
_zoomModeView = [[TGCameraZoomModeView alloc] initWithFrame:CGRectMake(floor((frame.size.width - 129.0) / 2.0), frame.size.height - _bottomPanelHeight - _bottomPanelOffset - 18 - 43, 129, 43) hasUltrawideCamera:hasUltrawideCamera hasTelephotoCamera:hasTelephotoCamera minZoomLevel:hasUltrawideCamera ? 0.5 : 1.0 maxZoomLevel:8.0];
|
||||
_zoomModeView.zoomChanged = ^(CGFloat zoomLevel, bool done, bool animated) {
|
||||
__strong TGCameraMainPhoneView *strongSelf = weakSelf;
|
||||
if (strongSelf == nil)
|
||||
return;
|
||||
|
||||
if (!done) {
|
||||
[strongSelf->_zoomWheelView setZoomLevel:zoomLevel];
|
||||
[strongSelf->_zoomModeView setHidden:true animated:true];
|
||||
[strongSelf->_zoomWheelView setHidden:false animated:true];
|
||||
} else {
|
||||
if (done) {
|
||||
[strongSelf->_zoomWheelView setZoomLevel:zoomLevel];
|
||||
[strongSelf->_zoomModeView setZoomLevel:zoomLevel animated:false];
|
||||
[strongSelf->_zoomModeView setHidden:false animated:true];
|
||||
[strongSelf->_zoomWheelView setHidden:true animated:true];
|
||||
|
||||
if (!strongSelf->_zoomWheelView.isHidden) {
|
||||
strongSelf->_dismissingWheel = true;
|
||||
|
||||
TGDispatchAfter(0.6, dispatch_get_main_queue(), ^{
|
||||
if (strongSelf->_dismissingWheel) {
|
||||
[strongSelf->_zoomModeView setHidden:false animated:true];
|
||||
// [strongSelf->_zoomWheelView setHidden:true animated:true];
|
||||
}
|
||||
});
|
||||
}
|
||||
} else {
|
||||
strongSelf->_dismissingWheel = false;
|
||||
[strongSelf->_zoomWheelView setZoomLevel:zoomLevel];
|
||||
[strongSelf->_zoomModeView setHidden:true animated:true];
|
||||
// [strongSelf->_zoomWheelView setHidden:false animated:true];
|
||||
}
|
||||
|
||||
if (strongSelf.zoomChanged != nil)
|
||||
@ -284,7 +296,7 @@
|
||||
[_zoomModeView setZoomLevel:1.0];
|
||||
[self addSubview:_zoomModeView];
|
||||
|
||||
_zoomWheelView = [[TGCameraZoomWheelView alloc] initWithFrame:CGRectMake(0.0, frame.size.height - _bottomPanelHeight - _bottomPanelOffset - 132, frame.size.width, 132)];
|
||||
_zoomWheelView = [[TGCameraZoomWheelView alloc] initWithFrame:CGRectMake(0.0, frame.size.height - _bottomPanelHeight - _bottomPanelOffset - 132, frame.size.width, 132) hasUltrawideCamera:hasUltrawideCamera hasTelephotoCamera:hasTelephotoCamera];
|
||||
[_zoomWheelView setHidden:true animated:false];
|
||||
[_zoomWheelView setZoomLevel:1.0];
|
||||
_zoomWheelView.userInteractionEnabled = false;
|
||||
@ -440,13 +452,6 @@
|
||||
|
||||
#pragma mark - Actions
|
||||
|
||||
- (void)shutterButtonReleased
|
||||
{
|
||||
[super shutterButtonReleased];
|
||||
|
||||
[_flashControl dismissAnimated:true];
|
||||
}
|
||||
|
||||
- (void)updateForCameraModeChangeWithPreviousMode:(PGCameraMode)previousMode
|
||||
{
|
||||
[super updateForCameraModeChangeWithPreviousMode:previousMode];
|
||||
@ -490,7 +495,6 @@
|
||||
[self _attachControlsToTopPanel];
|
||||
|
||||
[self _layoutTopPanelSubviewsForInterfaceOrientation:orientation];
|
||||
[_flashControl dismissAnimated:false];
|
||||
|
||||
[UIView animateWithDuration:0.2f delay:0.0f options:UIViewAnimationOptionCurveEaseInOut animations:^
|
||||
{
|
||||
@ -512,7 +516,7 @@
|
||||
|
||||
- (void)setFlashActive:(bool)active
|
||||
{
|
||||
[_flashActiveView setActive:active animated:true];
|
||||
[_flashControl setFlashActive:active];
|
||||
}
|
||||
|
||||
- (void)setFlashUnavailable:(bool)unavailable
|
||||
@ -522,9 +526,6 @@
|
||||
|
||||
- (void)setHasFlash:(bool)hasFlash
|
||||
{
|
||||
if (!hasFlash)
|
||||
[_flashActiveView setActive:false animated:true];
|
||||
|
||||
[_flashControl setHidden:!hasFlash animated:true];
|
||||
}
|
||||
|
||||
@ -676,8 +677,6 @@
|
||||
}
|
||||
else
|
||||
{
|
||||
[_flashControl dismissAnimated:false];
|
||||
|
||||
_flipButton.transform = CGAffineTransformMakeRotation(TGRotationForInterfaceOrientation(orientation));
|
||||
_flashControl.transform = CGAffineTransformMakeRotation(TGRotationForInterfaceOrientation(orientation));
|
||||
_zoomModeView.interfaceOrientation = orientation;
|
||||
|
@ -14,6 +14,51 @@
|
||||
#import "TGMediaPickerPhotoCounterButton.h"
|
||||
#import "TGMediaPickerPhotoStripView.h"
|
||||
|
||||
@implementation TGCameraCornersView
|
||||
|
||||
- (instancetype)initWithFrame:(CGRect)frame {
|
||||
self = [super initWithFrame:frame];
|
||||
if (self != nil) {
|
||||
self.contentMode = UIViewContentModeScaleToFill;
|
||||
|
||||
static UIImage *cornersImage = nil;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^
|
||||
{
|
||||
CGSize size = CGSizeMake(50.0, 50.0);
|
||||
UIGraphicsBeginImageContextWithOptions(CGSizeMake(50.0, 50.0), false, 0.0f);
|
||||
CGContextRef context = UIGraphicsGetCurrentContext();
|
||||
|
||||
CGContextSetAlpha(context, 0.5);
|
||||
CGContextSetFillColorWithColor(context, [UIColor whiteColor].CGColor);
|
||||
CGContextSetBlendMode(context, kCGBlendModeCopy);
|
||||
|
||||
CGFloat width = 1.0;
|
||||
CGFloat length = 24.0;
|
||||
CGContextFillRect(context, CGRectMake(0, 0, length, width));
|
||||
CGContextFillRect(context, CGRectMake(0, 0, width, length));
|
||||
|
||||
CGContextFillRect(context, CGRectMake(size.width - length, 0, length, width));
|
||||
CGContextFillRect(context, CGRectMake(size.width - width, 0, width, length));
|
||||
|
||||
CGContextFillRect(context, CGRectMake(0, size.height - width, length, width));
|
||||
CGContextFillRect(context, CGRectMake(0, size.height - length, width, length));
|
||||
|
||||
CGContextFillRect(context, CGRectMake(size.width - length, size.height - width, length, width));
|
||||
CGContextFillRect(context, CGRectMake(size.width - width, size.height - length, width, length));
|
||||
|
||||
cornersImage = [UIGraphicsGetImageFromCurrentImageContext() stretchableImageWithLeftCapWidth:25 topCapHeight:25];
|
||||
UIGraphicsEndImageContext();
|
||||
});
|
||||
|
||||
self.image = cornersImage;
|
||||
self.userInteractionEnabled = false;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@interface TGCameraMainView ()
|
||||
{
|
||||
|
||||
|
@ -66,12 +66,20 @@
|
||||
[self reset];
|
||||
|
||||
_recordingTimer = [TGTimerTarget scheduledMainThreadTimerWithTarget:self action:@selector(recordingTimerEvent) interval:1.0 repeat:false];
|
||||
|
||||
[UIView animateWithDuration:0.2 animations:^{
|
||||
_backgroundView.alpha = 1.0;
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)stopRecording
|
||||
{
|
||||
[_recordingTimer invalidate];
|
||||
_recordingTimer = nil;
|
||||
|
||||
[UIView animateWithDuration:0.2 animations:^{
|
||||
_backgroundView.alpha = 0.0;
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)reset
|
||||
|
@ -227,6 +227,9 @@
|
||||
|
||||
@interface TGCameraZoomModeView ()
|
||||
{
|
||||
CGFloat _minZoomLevel;
|
||||
CGFloat _maxZoomLevel;
|
||||
|
||||
UIView *_backgroundView;
|
||||
|
||||
bool _hasUltrawideCamera;
|
||||
@ -240,13 +243,15 @@
|
||||
|
||||
@implementation TGCameraZoomModeView
|
||||
|
||||
- (instancetype)initWithFrame:(CGRect)frame hasUltrawideCamera:(bool)hasUltrawideCamera hasTelephotoCamera:(bool)hasTelephotoCamera
|
||||
- (instancetype)initWithFrame:(CGRect)frame hasUltrawideCamera:(bool)hasUltrawideCamera hasTelephotoCamera:(bool)hasTelephotoCamera minZoomLevel:(CGFloat)minZoomLevel maxZoomLevel:(CGFloat)maxZoomLevel
|
||||
{
|
||||
self = [super initWithFrame:frame];
|
||||
if (self != nil)
|
||||
{
|
||||
_hasUltrawideCamera = hasUltrawideCamera;
|
||||
_hasTelephotoCamera = hasTelephotoCamera;
|
||||
_minZoomLevel = minZoomLevel;
|
||||
_maxZoomLevel = maxZoomLevel;
|
||||
|
||||
_backgroundView = [[UIView alloc] initWithFrame:self.bounds];
|
||||
_backgroundView.backgroundColor = [UIColor colorWithWhite:0.0 alpha:0.15];
|
||||
@ -270,34 +275,39 @@
|
||||
[self addSubview:_rightItem];
|
||||
}
|
||||
|
||||
UIPanGestureRecognizer *gestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panGesture:)];
|
||||
// [self addGestureRecognizer:gestureRecognizer];
|
||||
UIPanGestureRecognizer *panGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panGesture:)];
|
||||
[self addGestureRecognizer:panGestureRecognizer];
|
||||
|
||||
UILongPressGestureRecognizer *pressGestureRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(pressGesture:)];
|
||||
[self addGestureRecognizer:pressGestureRecognizer];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)pressGesture:(UILongPressGestureRecognizer *)gestureRecognizer {
|
||||
switch (gestureRecognizer.state) {
|
||||
case UIGestureRecognizerStateBegan:
|
||||
self.zoomChanged(_zoomLevel, false, false);
|
||||
break;
|
||||
case UIGestureRecognizerStateEnded:
|
||||
self.zoomChanged(_zoomLevel, true, false);
|
||||
break;
|
||||
case UIGestureRecognizerStateCancelled:
|
||||
self.zoomChanged(_zoomLevel, true, false);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)panGesture:(UIPanGestureRecognizer *)gestureRecognizer {
|
||||
CGPoint translation = [gestureRecognizer translationInView:self];
|
||||
|
||||
switch (gestureRecognizer.state) {
|
||||
case UIGestureRecognizerStateBegan:
|
||||
self.zoomChanged(_zoomLevel, false, false);
|
||||
break;
|
||||
|
||||
case UIGestureRecognizerStateChanged:
|
||||
_zoomLevel = MAX(0.5, MIN(10.0, _zoomLevel - translation.x / 100.0));
|
||||
self.zoomChanged(_zoomLevel, false, false);
|
||||
break;
|
||||
|
||||
case UIGestureRecognizerStateEnded:
|
||||
self.zoomChanged(_zoomLevel, true, false);
|
||||
break;
|
||||
|
||||
case UIGestureRecognizerStateCancelled:
|
||||
self.zoomChanged(_zoomLevel, true, false);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -425,21 +435,85 @@
|
||||
|
||||
@interface TGCameraZoomWheelView ()
|
||||
{
|
||||
bool _hasUltrawideCamera;
|
||||
bool _hasTelephotoCamera;
|
||||
UIImageView *_backgroundView;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation TGCameraZoomWheelView
|
||||
|
||||
- (instancetype)initWithFrame:(CGRect)frame
|
||||
- (void)_drawLineInContext:(CGContextRef)context side:(CGFloat)side atAngle:(CGFloat)angle lineLength:(CGFloat)lineLength lineWidth:(CGFloat)lineWidth opaque:(bool)opaque {
|
||||
CGContextSaveGState(context);
|
||||
|
||||
CGContextTranslateCTM(context, side / 2.0, side / 2.0);
|
||||
CGContextRotateCTM(context, angle);
|
||||
CGContextTranslateCTM(context, -side / 2.0, -side / 2.0);
|
||||
|
||||
CGContextSetLineWidth(context, lineWidth);
|
||||
CGContextSetStrokeColorWithColor(context, [UIColor colorWithWhite:1.0 alpha:opaque ? 1.0 : 0.5].CGColor);
|
||||
CGContextMoveToPoint(context, side / 2.0, 4.0);
|
||||
CGContextAddLineToPoint(context, side / 2.0, 4.0 + lineLength);
|
||||
CGContextStrokePath(context);
|
||||
|
||||
CGContextRestoreGState(context);
|
||||
}
|
||||
|
||||
- (instancetype)initWithFrame:(CGRect)frame hasUltrawideCamera:(bool)hasUltrawideCamera hasTelephotoCamera:(bool)hasTelephotoCamera
|
||||
{
|
||||
self = [super initWithFrame:frame];
|
||||
if (self != nil)
|
||||
{
|
||||
self.clipsToBounds = true;
|
||||
_hasUltrawideCamera = true;// hasUltrawideCamera;
|
||||
_hasTelephotoCamera = true;//hasTelephotoCamera;
|
||||
|
||||
_backgroundView = [[UIImageView alloc] initWithFrame:CGRectMake(-28.0, 0.0, 446.0, 446.0)];
|
||||
_backgroundView.alpha = 0.75;
|
||||
self.clipsToBounds = true;
|
||||
|
||||
CGFloat side = floor(frame.size.width * 1.1435);
|
||||
CGFloat length = 17.0;
|
||||
CGFloat smallWidth = MAX(0.5, 1.0 - TGScreenPixel);
|
||||
CGFloat mediumWidth = 1.0;
|
||||
CGFloat bigWidth = 1.0 + TGScreenPixel;
|
||||
|
||||
CGFloat smallAngle = M_PI * 0.12;
|
||||
CGFloat finalAngle = 1.08;
|
||||
|
||||
UIGraphicsBeginImageContextWithOptions(CGSizeMake(side, side), false, 0.0f);
|
||||
CGContextRef context = UIGraphicsGetCurrentContext();
|
||||
|
||||
CGContextSetFillColorWithColor(context, [UIColor colorWithWhite:0.0 alpha:0.75].CGColor);
|
||||
CGContextFillEllipseInRect(context, CGRectMake(0, 0, side, side));
|
||||
|
||||
[self _drawLineInContext:context side:side atAngle:0.0 lineLength:length lineWidth:bigWidth opaque:true];
|
||||
|
||||
if (_hasUltrawideCamera) {
|
||||
for (NSInteger i = 0; i < 4; i++) {
|
||||
CGFloat angle = (smallAngle / 5.0) * (i + 1) + (0.007 * (i - 1));
|
||||
[self _drawLineInContext:context side:side atAngle:-angle lineLength:length lineWidth:smallWidth opaque:false];
|
||||
}
|
||||
[self _drawLineInContext:context side:side atAngle:-smallAngle lineLength:length lineWidth:bigWidth opaque:true];
|
||||
}
|
||||
if (_hasTelephotoCamera) {
|
||||
[self _drawLineInContext:context side:side atAngle:smallAngle lineLength:length lineWidth:bigWidth opaque:true];
|
||||
|
||||
for (NSInteger i = 0; i < 4; i++) {
|
||||
CGFloat angle = (smallAngle / 5.0) * (i + 1) + (0.01 * (i - 1));
|
||||
[self _drawLineInContext:context side:side atAngle:angle lineLength:length lineWidth:smallWidth opaque:false];
|
||||
}
|
||||
|
||||
[self _drawLineInContext:context side:side atAngle:finalAngle lineLength:length lineWidth:bigWidth opaque:true];
|
||||
} else {
|
||||
[self _drawLineInContext:context side:side atAngle:smallAngle lineLength:length lineWidth:mediumWidth opaque:true];
|
||||
|
||||
[self _drawLineInContext:context side:side atAngle:finalAngle lineLength:length lineWidth:bigWidth opaque:true];
|
||||
}
|
||||
|
||||
|
||||
UIImage *image = [UIGraphicsGetImageFromCurrentImageContext() stretchableImageWithLeftCapWidth:25 topCapHeight:25];
|
||||
UIGraphicsEndImageContext();
|
||||
|
||||
_backgroundView = [[UIImageView alloc] initWithFrame:CGRectMake(TGScreenPixelFloor((frame.size.width - side) / 2.0), 0.0, side, side)];
|
||||
_backgroundView.image = image;
|
||||
|
||||
[self addSubview:_backgroundView];
|
||||
}
|
||||
|
@ -11,8 +11,8 @@ const CGFloat TGPhotoPaintColorWeightGestureRange = 320.0f;
|
||||
const CGFloat TGPhotoPaintVerticalThreshold = 5.0f;
|
||||
const CGFloat TGPhotoPaintPreviewOffset = -70.0f;
|
||||
const CGFloat TGPhotoPaintPreviewScale = 2.0f;
|
||||
const CGFloat TGPhotoPaintDefaultBrushWeight = 0.22f;
|
||||
const CGFloat TGPhotoPaintDefaultColorLocation = 1.0f;
|
||||
const CGFloat TGPhotoPaintDefaultBrushWeight = 0.08f;
|
||||
const CGFloat TGPhotoPaintDefaultColorLocation = 0.0f;
|
||||
|
||||
@interface TGPhotoPaintColorPickerKnobCircleView : UIView
|
||||
{
|
||||
@ -97,7 +97,7 @@ const CGFloat TGPhotoPaintDefaultColorLocation = 1.0f;
|
||||
[self addGestureRecognizer:_tapGestureRecognizer];
|
||||
|
||||
_location = [self restoreLastColorLocation];
|
||||
_weight = 0.08f;
|
||||
_weight = TGPhotoPaintDefaultBrushWeight;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
@ -107,7 +107,7 @@ const CGFloat TGPhotoPaintDefaultColorLocation = 1.0f;
|
||||
NSNumber *lastColor = [[NSUserDefaults standardUserDefaults] objectForKey:@"TG_paintLastColorLocation_v0"];
|
||||
if (lastColor != nil)
|
||||
return [lastColor floatValue];
|
||||
|
||||
|
||||
return TGPhotoPaintDefaultColorLocation;
|
||||
}
|
||||
|
||||
|
@ -213,8 +213,10 @@ private func pushPeerReadState(network: Network, postbox: Postbox, stateManager:
|
||||
return .single(readState)
|
||||
case let .indexBased(maxIncomingReadIndex, _, _, _):
|
||||
return network.request(Api.functions.messages.readEncryptedHistory(peer: inputPeer, maxDate: maxIncomingReadIndex.timestamp))
|
||||
|> retryRequest
|
||||
|> mapToSignalPromotingError { _ -> Signal<PeerReadState, PeerReadStateValidationError> in
|
||||
|> mapError { _ in
|
||||
return PeerReadStateValidationError.retry
|
||||
}
|
||||
|> mapToSignal { _ -> Signal<PeerReadState, PeerReadStateValidationError> in
|
||||
return .single(readState)
|
||||
}
|
||||
}
|
||||
|
@ -2218,6 +2218,13 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
|
||||
}
|
||||
|
||||
private func handlePanSelection(location: CGPoint) {
|
||||
var location = location
|
||||
if location.y < self.insets.top {
|
||||
location.y = self.insets.top + 5.0
|
||||
} else if location.y > self.frame.height - self.insets.bottom {
|
||||
location.y = self.frame.height - self.insets.bottom - 5.0
|
||||
}
|
||||
|
||||
if let state = self.selectionPanState {
|
||||
if let messages = self.messagesAtPoint(location), let message = messages.first {
|
||||
if message.id == state.initialMessageId {
|
||||
|
@ -70,6 +70,8 @@ class ChatMessageInstantVideoItemNode: ChatMessageItemView, UIGestureRecognizerD
|
||||
}
|
||||
}
|
||||
|
||||
private var wasPlaying = false
|
||||
|
||||
required init() {
|
||||
self.contextSourceNode = ContextExtractedContentContainingNode()
|
||||
self.containerNode = ContextControllerSourceNode()
|
||||
@ -97,7 +99,7 @@ class ChatMessageInstantVideoItemNode: ChatMessageItemView, UIGestureRecognizerD
|
||||
return false
|
||||
}
|
||||
if strongSelf.appliedCurrentlyPlaying && !strongSelf.interactiveVideoNode.isPlaying {
|
||||
return false
|
||||
return strongSelf.interactiveVideoNode.frame.insetBy(dx: 0.15 * strongSelf.interactiveVideoNode.frame.width, dy: 0.15 * strongSelf.interactiveVideoNode.frame.height).contains(location)
|
||||
}
|
||||
if let action = strongSelf.gestureRecognized(gesture: .tap, location: location, recognizer: nil) {
|
||||
if case .action = action {
|
||||
@ -126,10 +128,24 @@ class ChatMessageInstantVideoItemNode: ChatMessageItemView, UIGestureRecognizerD
|
||||
case let .openContextMenu(tapMessage, selectAll, subFrame):
|
||||
strongSelf.recognizer?.cancel()
|
||||
item.controllerInteraction.openMessageContextMenu(tapMessage, selectAll, strongSelf, subFrame, gesture)
|
||||
if strongSelf.appliedCurrentlyPlaying && strongSelf.interactiveVideoNode.isPlaying {
|
||||
strongSelf.wasPlaying = true
|
||||
strongSelf.interactiveVideoNode.pause()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.contextSourceNode.willUpdateIsExtractedToContextPreview = { [weak self] extracted, _ in
|
||||
guard let strongSelf = self, let _ = strongSelf.item else {
|
||||
return
|
||||
}
|
||||
if !extracted && strongSelf.wasPlaying {
|
||||
strongSelf.wasPlaying = false
|
||||
strongSelf.interactiveVideoNode.play()
|
||||
}
|
||||
}
|
||||
|
||||
self.containerNode.addSubnode(self.contextSourceNode)
|
||||
self.containerNode.targetNodeForActivationProgress = self.contextSourceNode.contentNode
|
||||
self.addSubnode(self.containerNode)
|
||||
|
@ -777,9 +777,9 @@ class ChatMessageInteractiveInstantVideoNode: ASDisplayNode {
|
||||
if !self.bounds.contains(point) {
|
||||
return nil
|
||||
}
|
||||
if let playbackNode = self.playbackStatusNode, !self.isPlaying, !playbackNode.frame.insetBy(dx: 0.15 * playbackNode.frame.width, dy: 0.15 * playbackNode.frame.height).contains(point) {
|
||||
if let playbackNode = self.playbackStatusNode, !self.isPlaying, !playbackNode.frame.insetBy(dx: 0.2 * playbackNode.frame.width, dy: 0.2 * playbackNode.frame.height).contains(point) {
|
||||
let distanceFromCenter = point.distanceTo(playbackNode.position)
|
||||
if distanceFromCenter < 0.15 * playbackNode.frame.width {
|
||||
if distanceFromCenter < 0.2 * playbackNode.frame.width {
|
||||
return self.view
|
||||
} else {
|
||||
return playbackNode.view
|
||||
|
@ -11,12 +11,14 @@ private final class InstantVideoRadialStatusNodeParameters: NSObject {
|
||||
let progress: CGFloat
|
||||
let dimProgress: CGFloat
|
||||
let playProgress: CGFloat
|
||||
let hasSeek: Bool
|
||||
|
||||
init(color: UIColor, progress: CGFloat, dimProgress: CGFloat, playProgress: CGFloat) {
|
||||
init(color: UIColor, progress: CGFloat, dimProgress: CGFloat, playProgress: CGFloat, hasSeek: Bool) {
|
||||
self.color = color
|
||||
self.progress = progress
|
||||
self.dimProgress = dimProgress
|
||||
self.playProgress = playProgress
|
||||
self.hasSeek = hasSeek
|
||||
}
|
||||
}
|
||||
|
||||
@ -141,7 +143,7 @@ final class InstantVideoRadialStatusNode: ASDisplayNode, UIGestureRecognizerDele
|
||||
let center = CGPoint(x: self.bounds.width / 2.0, y: self.bounds.height / 2.0)
|
||||
let location = gestureRecognizer.location(in: self.view)
|
||||
let distanceFromCenter = location.distanceTo(center)
|
||||
if distanceFromCenter < self.bounds.width * 0.15 {
|
||||
if distanceFromCenter < self.bounds.width * 0.2 {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
@ -210,7 +212,7 @@ final class InstantVideoRadialStatusNode: ASDisplayNode, UIGestureRecognizerDele
|
||||
}
|
||||
|
||||
override func drawParameters(forAsyncLayer layer: _ASDisplayLayer) -> NSObjectProtocol? {
|
||||
return InstantVideoRadialStatusNodeParameters(color: self.color, progress: self.effectiveProgress, dimProgress: self.effectiveDimProgress, playProgress: self.effectivePlayProgress)
|
||||
return InstantVideoRadialStatusNodeParameters(color: self.color, progress: self.effectiveProgress, dimProgress: self.effectiveDimProgress, playProgress: self.effectivePlayProgress, hasSeek: self.hasSeek)
|
||||
}
|
||||
|
||||
@objc override class func draw(_ bounds: CGRect, withParameters parameters: Any?, isCancelled: () -> Bool, isRasterizing: Bool) {
|
||||
@ -239,20 +241,30 @@ final class InstantVideoRadialStatusNode: ASDisplayNode, UIGestureRecognizerDele
|
||||
progress = min(1.0, progress)
|
||||
|
||||
var lineWidth: CGFloat = 4.0
|
||||
lineWidth += 1.0 * parameters.dimProgress
|
||||
if parameters.hasSeek {
|
||||
lineWidth += 1.0 * parameters.dimProgress
|
||||
}
|
||||
|
||||
var pathDiameter = bounds.size.width - lineWidth - 8.0
|
||||
pathDiameter -= (18.0 * 2.0) * parameters.dimProgress
|
||||
|
||||
if !parameters.dimProgress.isZero {
|
||||
context.setStrokeColor(parameters.color.withAlphaComponent(0.2 * parameters.dimProgress).cgColor)
|
||||
context.setLineWidth(lineWidth)
|
||||
context.strokeEllipse(in: CGRect(x: (bounds.size.width - pathDiameter) / 2.0 , y: (bounds.size.height - pathDiameter) / 2.0, width: pathDiameter, height: pathDiameter))
|
||||
if parameters.hasSeek {
|
||||
pathDiameter -= (18.0 * 2.0) * parameters.dimProgress
|
||||
}
|
||||
|
||||
if !parameters.dimProgress.isZero {
|
||||
if parameters.hasSeek {
|
||||
context.setStrokeColor(parameters.color.withAlphaComponent(0.2 * parameters.dimProgress).cgColor)
|
||||
context.setLineWidth(lineWidth)
|
||||
context.strokeEllipse(in: CGRect(x: (bounds.size.width - pathDiameter) / 2.0 , y: (bounds.size.height - pathDiameter) / 2.0, width: pathDiameter, height: pathDiameter))
|
||||
}
|
||||
|
||||
if !parameters.playProgress.isZero {
|
||||
context.saveGState()
|
||||
context.translateBy(x: bounds.width / 2.0, y: bounds.height / 2.0)
|
||||
context.scaleBy(x: 1.0 + 1.4 * parameters.playProgress, y: 1.0 + 1.4 * parameters.playProgress)
|
||||
if parameters.hasSeek {
|
||||
context.scaleBy(x: 1.0 + 1.4 * parameters.playProgress, y: 1.0 + 1.4 * parameters.playProgress)
|
||||
} else {
|
||||
context.scaleBy(x: 1.0 + 0.7 * parameters.playProgress, y: 1.0 + 0.7 * parameters.playProgress)
|
||||
}
|
||||
context.translateBy(x: -bounds.width / 2.0, y: -bounds.height / 2.0)
|
||||
|
||||
let iconSize = CGSize(width: 15.0, height: 18.0)
|
||||
@ -272,12 +284,14 @@ final class InstantVideoRadialStatusNode: ASDisplayNode, UIGestureRecognizerDele
|
||||
path.lineCapStyle = .round
|
||||
path.stroke()
|
||||
|
||||
let handleSide = 16.0 * min(1.0, (parameters.dimProgress * 2.0))
|
||||
let handleSize = CGSize(width: handleSide, height: handleSide)
|
||||
let handlePosition = CGPoint(x: 0.5 * pathDiameter * cos(endAngle), y: 0.5 * pathDiameter * sin(endAngle)).offsetBy(dx: bounds.size.width / 2.0, dy: bounds.size.height / 2.0)
|
||||
let handleFrame = CGRect(origin: CGPoint(x: floorToScreenPixels(handlePosition.x - handleSize.width / 2.0), y: floorToScreenPixels(handlePosition.y - handleSize.height / 2.0)), size: handleSize)
|
||||
context.setFillColor(UIColor.white.cgColor)
|
||||
context.fillEllipse(in: handleFrame)
|
||||
if parameters.hasSeek {
|
||||
let handleSide = 16.0 * min(1.0, (parameters.dimProgress * 2.0))
|
||||
let handleSize = CGSize(width: handleSide, height: handleSide)
|
||||
let handlePosition = CGPoint(x: 0.5 * pathDiameter * cos(endAngle), y: 0.5 * pathDiameter * sin(endAngle)).offsetBy(dx: bounds.size.width / 2.0, dy: bounds.size.height / 2.0)
|
||||
let handleFrame = CGRect(origin: CGPoint(x: floorToScreenPixels(handlePosition.x - handleSize.width / 2.0), y: floorToScreenPixels(handlePosition.y - handleSize.height / 2.0)), size: handleSize)
|
||||
context.setFillColor(UIColor.white.cgColor)
|
||||
context.fillEllipse(in: handleFrame)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -296,11 +310,7 @@ final class InstantVideoRadialStatusNode: ASDisplayNode, UIGestureRecognizerDele
|
||||
if self.seeking {
|
||||
dimmed = true
|
||||
}
|
||||
|
||||
if !self.hasSeek {
|
||||
dimmed = false
|
||||
}
|
||||
|
||||
|
||||
if dimmed != self.dimmed {
|
||||
self.dimmed = dimmed
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user