1
0
mirror of https://github.com/danog/Telegram.git synced 2025-01-06 04:58:56 +01:00
Telegram/Telegraph/TGMessageImageView.m
2014-07-10 18:11:09 +04:00

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