mirror of
https://github.com/danog/Telegram.git
synced 2025-01-06 04:58:56 +01:00
323 lines
11 KiB
Objective-C
323 lines
11 KiB
Objective-C
/*
|
|
* This is the source code of Telegram for iOS v. 1.1
|
|
* It is licensed under GNU GPL v. 2 or later.
|
|
* You should have received a copy of the license in this archive (see LICENSE).
|
|
*
|
|
* Copyright Peter Iakovlev, 2013.
|
|
*/
|
|
|
|
#import "TGMessageImageView.h"
|
|
|
|
#import "UIImage+TG.h"
|
|
#import "TGModernButton.h"
|
|
|
|
#import "TGMessageImageViewOverlayView.h"
|
|
#import "TGMessageImageViewTimestampView.h"
|
|
#import "TGMessageImageAdditionalDataView.h"
|
|
#import "TGStaticBackdropImageData.h"
|
|
|
|
static const CGFloat circleDiameter = 50.0f;
|
|
|
|
static const CGFloat timestampWidth = 84.0f;
|
|
static const CGFloat timestampHeight = 18.0f;
|
|
static const CGFloat timestampRightPadding = 6.0f;
|
|
static const CGFloat timestampBottomPadding = 6.0f;
|
|
|
|
static const CGFloat additionalDataWidth = 160.0f;
|
|
static const CGFloat additionalDataHeight = 18.0f;
|
|
static const CGFloat additionalDataLeftPadding = 6.0f;
|
|
static const CGFloat additionalDataTopPadding = 6.0f;
|
|
|
|
@interface TGMessageImageView ()
|
|
{
|
|
TGModernButton *_buttonView;
|
|
UIImageView *_actionCircleImageView;
|
|
TGMessageImageViewOverlayView *_overlayView;
|
|
|
|
TGMessageImageViewTimestampView *_timestampView;
|
|
|
|
TGMessageImageAdditionalDataView *_additionalDataView;
|
|
TGStaticBackdropAreaData *_additionalDataBackdropArea;
|
|
}
|
|
|
|
@property (nonatomic, strong) NSString *viewIdentifier;
|
|
@property (nonatomic, strong) NSString *viewStateIdentifier;
|
|
|
|
@end
|
|
|
|
@implementation TGMessageImageView
|
|
|
|
- (void)loadUri:(NSString *)uri withOptions:(NSDictionary *)options
|
|
{
|
|
self.viewStateIdentifier = [[NSString alloc] initWithFormat:@"TGMessageImageView/%@", uri];
|
|
|
|
[super loadUri:uri withOptions:options];
|
|
}
|
|
|
|
- (void)willBecomeRecycled
|
|
{
|
|
self.viewStateIdentifier = nil;
|
|
|
|
[_timestampView setDisplayProgress:false];
|
|
|
|
[self reset];
|
|
}
|
|
|
|
- (instancetype)initWithFrame:(CGRect)frame
|
|
{
|
|
self = [super initWithFrame:frame];
|
|
if (self != nil)
|
|
{
|
|
_actionCircleImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, circleDiameter, circleDiameter)];
|
|
_actionCircleImageView.userInteractionEnabled = false;
|
|
|
|
_buttonView = [[TGModernButton alloc] initWithFrame:CGRectMake(0.0f, 0.0f, circleDiameter, circleDiameter)];
|
|
_buttonView.exclusiveTouch = true;
|
|
_buttonView.modernHighlight = true;
|
|
[_buttonView addTarget:self action:@selector(actionButtonPressed) forControlEvents:UIControlEventTouchUpInside];
|
|
|
|
_overlayView = [[TGMessageImageViewOverlayView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, circleDiameter, circleDiameter)];
|
|
_overlayView.userInteractionEnabled = false;
|
|
[_buttonView addSubview:_overlayView];
|
|
|
|
static UIImage *highlightImage = nil;
|
|
static dispatch_once_t onceToken;
|
|
dispatch_once(&onceToken, ^
|
|
{
|
|
UIGraphicsBeginImageContextWithOptions(CGSizeMake(circleDiameter, circleDiameter), false, 0.0f);
|
|
CGContextRef context = UIGraphicsGetCurrentContext();
|
|
CGContextSetFillColorWithColor(context, UIColorRGBA(0x000000, 0.4f).CGColor);
|
|
CGContextFillEllipseInRect(context, CGRectMake(0.0f, 0.0f, circleDiameter, circleDiameter));
|
|
highlightImage = UIGraphicsGetImageFromCurrentImageContext();
|
|
UIGraphicsEndImageContext();
|
|
});
|
|
|
|
_buttonView.highlightImage = highlightImage;
|
|
|
|
_timestampView = [[TGMessageImageViewTimestampView alloc] initWithFrame:CGRectMake(frame.size.width - timestampWidth - timestampRightPadding, frame.size.height - timestampHeight - timestampBottomPadding, timestampWidth, timestampHeight)];
|
|
_timestampView.userInteractionEnabled = false;
|
|
[self addSubview:_timestampView];
|
|
}
|
|
return self;
|
|
}
|
|
|
|
- (UIImage *)currentImage
|
|
{
|
|
return self.image;
|
|
}
|
|
|
|
- (void)setFrame:(CGRect)frame
|
|
{
|
|
[super setFrame:frame];
|
|
|
|
CGRect buttonFrame = _buttonView.frame;
|
|
buttonFrame.origin = CGPointMake(CGFloor(frame.size.width - buttonFrame.size.width) / 2.0f, CGFloor(frame.size.height - buttonFrame.size.height) / 2.0f);
|
|
if (!CGRectEqualToRect(_buttonView.frame, buttonFrame))
|
|
{
|
|
_buttonView.frame = buttonFrame;
|
|
_actionCircleImageView.frame = buttonFrame;
|
|
}
|
|
|
|
_timestampView.frame = CGRectMake(frame.size.width - timestampWidth - timestampRightPadding, frame.size.height - timestampHeight - timestampBottomPadding, timestampWidth, timestampHeight);
|
|
}
|
|
|
|
- (void)performTransitionToImage:(UIImage *)image duration:(NSTimeInterval)duration
|
|
{
|
|
[super performTransitionToImage:image duration:duration];
|
|
|
|
TGStaticBackdropImageData *backdropData = [image staticBackdropImageData];
|
|
UIImage *actionCircleImage = [backdropData backdropAreaForKey:TGStaticBackdropMessageActionCircle].background;
|
|
|
|
if (_actionCircleImageView.image == nil && actionCircleImage != nil && duration > DBL_EPSILON)
|
|
{
|
|
_actionCircleImageView.alpha = 0.0;
|
|
|
|
[UIView animateWithDuration:duration animations:^
|
|
{
|
|
_actionCircleImageView.alpha = 1.0;
|
|
} completion:^(__unused BOOL finished)
|
|
{
|
|
}];
|
|
}
|
|
|
|
_actionCircleImageView.image = actionCircleImage;
|
|
|
|
[_timestampView setBackdropArea:[backdropData backdropAreaForKey:TGStaticBackdropMessageTimestamp] transitionDuration:duration];
|
|
|
|
_additionalDataBackdropArea = [backdropData backdropAreaForKey:TGStaticBackdropMessageAdditionalData];
|
|
[_additionalDataView setBackdropArea:_additionalDataBackdropArea transitionDuration:duration];
|
|
}
|
|
|
|
- (void)setOverlayType:(int)overlayType
|
|
{
|
|
[self setOverlayType:overlayType animated:false];
|
|
}
|
|
|
|
- (void)setOverlayType:(int)overlayType animated:(bool)animated
|
|
{
|
|
if (_overlayType != overlayType)
|
|
{
|
|
_overlayType = overlayType;
|
|
|
|
switch (_overlayType)
|
|
{
|
|
case TGMessageImageViewOverlayDownload:
|
|
{
|
|
if (_actionCircleImageView.superview == nil)
|
|
{
|
|
[self addSubview:_actionCircleImageView];
|
|
[self addSubview:_buttonView];
|
|
}
|
|
|
|
_actionCircleImageView.alpha = 1.0f;
|
|
_buttonView.alpha = 1.0f;
|
|
|
|
[_overlayView setDownload];
|
|
|
|
break;
|
|
}
|
|
case TGMessageImageViewOverlayPlay:
|
|
{
|
|
if (_actionCircleImageView.superview == nil)
|
|
{
|
|
[self addSubview:_actionCircleImageView];
|
|
[self addSubview:_buttonView];
|
|
}
|
|
|
|
_actionCircleImageView.alpha = 1.0f;
|
|
_buttonView.alpha = 1.0f;
|
|
|
|
[_overlayView setPlay];
|
|
|
|
break;
|
|
}
|
|
case TGMessageImageViewOverlayProgress:
|
|
{
|
|
if (_actionCircleImageView.superview == nil)
|
|
{
|
|
[self addSubview:_actionCircleImageView];
|
|
[self addSubview:_buttonView];
|
|
}
|
|
|
|
_actionCircleImageView.alpha = 1.0f;
|
|
_buttonView.alpha = 1.0f;
|
|
|
|
[_overlayView setProgress:_progress animated:false];
|
|
|
|
break;
|
|
}
|
|
case TGMessageImageViewOverlayNone:
|
|
default:
|
|
{
|
|
if (_actionCircleImageView.superview != nil)
|
|
{
|
|
if (animated)
|
|
{
|
|
[UIView animateWithDuration:0.2 animations:^
|
|
{
|
|
_actionCircleImageView.alpha = 0.0f;
|
|
_buttonView.alpha = 0.0f;
|
|
} completion:^(BOOL finished)
|
|
{
|
|
if (finished)
|
|
{
|
|
[_actionCircleImageView removeFromSuperview];
|
|
[_buttonView removeFromSuperview];
|
|
}
|
|
}];
|
|
}
|
|
else
|
|
{
|
|
[_actionCircleImageView removeFromSuperview];
|
|
[_buttonView removeFromSuperview];
|
|
}
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
- (void)setProgress:(float)progress
|
|
{
|
|
[self setProgress:progress animated:false];
|
|
}
|
|
|
|
- (void)setProgress:(float)progress animated:(bool)animated
|
|
{
|
|
if (ABS(_progress - progress) > FLT_EPSILON)
|
|
{
|
|
_progress = progress;
|
|
|
|
if (_overlayType == TGMessageImageViewOverlayProgress)
|
|
[_overlayView setProgress:progress animated:animated];
|
|
}
|
|
}
|
|
|
|
- (void)setTimestampHidden:(bool)timestampHidden
|
|
{
|
|
_timestampView.hidden = timestampHidden;
|
|
}
|
|
|
|
- (void)setTimestampString:(NSString *)timestampString displayCheckmarks:(bool)displayCheckmarks checkmarkValue:(int)checkmarkValue animated:(bool)animated
|
|
{
|
|
[_timestampView setTimestampString:timestampString displayCheckmarks:displayCheckmarks checkmarkValue:checkmarkValue animated:animated];
|
|
}
|
|
|
|
- (void)setAdditionalDataString:(NSString *)additionalDataString
|
|
{
|
|
if (additionalDataString.length != 0)
|
|
{
|
|
if (_additionalDataView == nil)
|
|
{
|
|
_additionalDataView = [[TGMessageImageAdditionalDataView alloc] initWithFrame:CGRectMake(additionalDataLeftPadding, additionalDataTopPadding, additionalDataWidth, additionalDataHeight)];
|
|
}
|
|
|
|
[_additionalDataView setBackdropArea:_additionalDataBackdropArea transitionDuration:0.0];
|
|
[_additionalDataView setText:additionalDataString];
|
|
|
|
if (_additionalDataView.superview == nil)
|
|
[self addSubview:_additionalDataView];
|
|
}
|
|
else
|
|
[_additionalDataView removeFromSuperview];
|
|
}
|
|
|
|
- (void)setDisplayTimestampProgress:(bool)displayTimestampProgress
|
|
{
|
|
[_timestampView setDisplayProgress:displayTimestampProgress];
|
|
}
|
|
|
|
- (void)actionButtonPressed
|
|
{
|
|
TGMessageImageViewActionType action = TGMessageImageViewActionDownload;
|
|
|
|
switch (_overlayType)
|
|
{
|
|
case TGMessageImageViewOverlayDownload:
|
|
{
|
|
action = TGMessageImageViewActionDownload;
|
|
break;
|
|
}
|
|
case TGMessageImageViewOverlayProgress:
|
|
{
|
|
action = TGMessageImageViewActionCancelDownload;
|
|
break;
|
|
}
|
|
case TGMessageImageViewOverlayPlay:
|
|
{
|
|
action = TGMessageImageViewActionPlay;
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
|
|
id<TGMessageImageViewDelegate> delegate = _delegate;
|
|
if ([delegate respondsToSelector:@selector(messageImageViewActionButtonPressed:withAction:)])
|
|
[delegate messageImageViewActionButtonPressed:self withAction:action];
|
|
}
|
|
|
|
@end
|