2014-07-10 16:11:09 +02:00
|
|
|
/*
|
|
|
|
* 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 "TGEditableCollectionItemView.h"
|
|
|
|
|
|
|
|
#import "TGCollectionMenuView.h"
|
|
|
|
#import "TGEditingScrollView.h"
|
|
|
|
|
|
|
|
#import "TGImageUtils.h"
|
|
|
|
#import "TGFont.h"
|
|
|
|
|
|
|
|
@interface TGEditableCollectionItemView () <TGEditingScrollViewDelegate>
|
|
|
|
{
|
|
|
|
TGEditingScrollView *_editingScrollView;
|
|
|
|
|
|
|
|
UIImageView *_deleteIndicator;
|
|
|
|
UIButton *_actionButton;
|
|
|
|
|
|
|
|
NSString *_optionText;
|
|
|
|
}
|
|
|
|
|
|
|
|
@end
|
|
|
|
|
|
|
|
@implementation TGEditableCollectionItemView
|
|
|
|
|
|
|
|
- (id)initWithFrame:(CGRect)frame
|
|
|
|
{
|
|
|
|
self = [super initWithFrame:frame];
|
|
|
|
if (self != nil)
|
|
|
|
{
|
|
|
|
_enableEditing = true;
|
|
|
|
|
|
|
|
_editingScrollView = [[TGEditingScrollView alloc] init];
|
|
|
|
_editingScrollView.editingDelegate = self;
|
|
|
|
[self addSubview:_editingScrollView];
|
|
|
|
}
|
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)prepareForReuse
|
|
|
|
{
|
|
|
|
[super prepareForReuse];
|
|
|
|
|
|
|
|
[_editingScrollView setOptionsAreRevealed:false];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (UIView *)editingContentView
|
|
|
|
{
|
|
|
|
return _editingScrollView;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSString *)optionText
|
|
|
|
{
|
|
|
|
if (_optionText == nil)
|
|
|
|
_optionText = TGLocalized(@"Common.Delete");
|
|
|
|
|
|
|
|
return _optionText;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)setOptionText:(NSString *)optionText
|
|
|
|
{
|
|
|
|
if (_actionButton != nil)
|
|
|
|
[_actionButton setTitle:optionText forState:UIControlStateNormal];
|
|
|
|
|
|
|
|
_optionText = optionText;
|
|
|
|
}
|
|
|
|
|
|
|
|
static TGCollectionMenuView *_findCollectionMenuView(UIView *baseView)
|
|
|
|
{
|
|
|
|
if (baseView == nil || [baseView isKindOfClass:[TGCollectionMenuView class]])
|
|
|
|
return (TGCollectionMenuView *)baseView;
|
|
|
|
|
|
|
|
return _findCollectionMenuView(baseView.superview);
|
|
|
|
}
|
|
|
|
|
|
|
|
- (TGCollectionMenuView *)_collectionMenuView
|
|
|
|
{
|
|
|
|
return _findCollectionMenuView(self.superview);
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)reorderSelfToFront
|
|
|
|
{
|
|
|
|
int index = -1;
|
|
|
|
int maxCellIndex = -1;
|
|
|
|
int selfIndex = -1;
|
|
|
|
for (UIView *sibling in self.superview.subviews)
|
|
|
|
{
|
|
|
|
index++;
|
|
|
|
|
|
|
|
if ([sibling isKindOfClass:[TGCollectionItemView class]])
|
|
|
|
maxCellIndex = MAX(index, maxCellIndex);
|
|
|
|
if (sibling == self)
|
|
|
|
selfIndex = index;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (maxCellIndex != -1 && selfIndex != -1 && maxCellIndex != selfIndex)
|
|
|
|
[self.superview exchangeSubviewAtIndex:maxCellIndex withSubviewAtIndex:selfIndex];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (UIButton *)actionButton
|
|
|
|
{
|
|
|
|
if (_actionButton == nil)
|
|
|
|
{
|
|
|
|
_actionButton = [[UIButton alloc] init];
|
2016-02-25 01:03:51 +01:00
|
|
|
_actionButton.backgroundColor = _indicatorMode == TGEditableCollectionItemViewIndicatorAdd ? TGAccentColor() : TGDestructiveAccentColor();
|
2014-07-10 16:11:09 +02:00
|
|
|
[_actionButton setTitle:self.optionText forState:UIControlStateNormal];
|
|
|
|
[_actionButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
|
|
|
|
_actionButton.titleLabel.font = TGSystemFontOfSize(18);
|
|
|
|
[_actionButton addTarget:self action:@selector(optionButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
|
|
|
|
[self addSubview:_actionButton];
|
|
|
|
}
|
|
|
|
|
|
|
|
return _actionButton;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)setEnableEditing:(bool)enableEditing
|
|
|
|
{
|
|
|
|
[self setEnableEditing:enableEditing animated:false];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)setEnableEditing:(bool)enableEditing animated:(bool)animated
|
|
|
|
{
|
|
|
|
if (_enableEditing != enableEditing)
|
|
|
|
{
|
|
|
|
_enableEditing = enableEditing;
|
|
|
|
|
|
|
|
if (!_enableEditing)
|
|
|
|
[_editingScrollView setOptionsAreRevealed:false animated:animated];
|
|
|
|
|
|
|
|
_editingScrollView.disableScroll = !_enableEditing;
|
|
|
|
|
|
|
|
if (_deleteIndicator != nil)
|
|
|
|
{
|
|
|
|
CGFloat deleteIndicatorAlpha = (_enableEditing && _showsDeleteIndicator) ? 1.0f : 0.0f;
|
|
|
|
if (ABS(_deleteIndicator.alpha - deleteIndicatorAlpha) > FLT_EPSILON)
|
|
|
|
{
|
|
|
|
if (animated)
|
|
|
|
{
|
|
|
|
[UIView animateWithDuration:0.3 animations:^
|
|
|
|
{
|
|
|
|
_deleteIndicator.alpha = deleteIndicatorAlpha;
|
|
|
|
}];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
_deleteIndicator.alpha = deleteIndicatorAlpha;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)editingScrollViewOptionsOffsetChanged:(TGEditingScrollView *)__unused editingScrollView
|
|
|
|
{
|
|
|
|
if (_editingScrollView.bounds.origin.x > FLT_EPSILON)
|
|
|
|
[self actionButton];
|
|
|
|
|
|
|
|
[self _layoutActionButton];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)editingScrollViewWillRevealOptions:(TGEditingScrollView *)__unused editingScrollView
|
|
|
|
{
|
|
|
|
[self reorderSelfToFront];
|
|
|
|
|
|
|
|
[[self _collectionMenuView] _setEditingCell:self editing:true];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)editingScrollViewDidHideOptions:(TGEditingScrollView *)__unused editingScrollView
|
|
|
|
{
|
|
|
|
[[self _collectionMenuView] _setEditingCell:self editing:false];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)setShowsDeleteIndicator:(bool)showsDeleteIndicator
|
|
|
|
{
|
|
|
|
[self setShowsDeleteIndicator:showsDeleteIndicator animated:false];
|
|
|
|
}
|
|
|
|
|
2016-02-25 01:03:51 +01:00
|
|
|
- (void)setIndicatorMode:(TGEditableCollectionItemViewIndicator)indicatorMode {
|
|
|
|
if (_indicatorMode != indicatorMode) {
|
|
|
|
_indicatorMode = indicatorMode;
|
|
|
|
if (_deleteIndicator != nil) {
|
|
|
|
_deleteIndicator.image = _indicatorMode == TGEditableCollectionItemViewIndicatorAdd ? [UIImage imageNamed:@"ModernMenuAddIcon.png"] : [UIImage imageNamed:@"ModernMenuDeleteIcon.png"];
|
|
|
|
}
|
|
|
|
if (_actionButton != nil) {
|
|
|
|
_actionButton.backgroundColor = _indicatorMode == TGEditableCollectionItemViewIndicatorAdd ? TGAccentColor() : TGDestructiveAccentColor();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-07-10 16:11:09 +02:00
|
|
|
- (void)setShowsDeleteIndicator:(bool)showsDeleteIndicator animated:(bool)animated
|
|
|
|
{
|
|
|
|
if (_showsDeleteIndicator != showsDeleteIndicator)
|
|
|
|
{
|
|
|
|
if (_deleteIndicator == nil)
|
|
|
|
{
|
2016-02-25 01:03:51 +01:00
|
|
|
_deleteIndicator = [[UIImageView alloc] initWithImage:_indicatorMode == TGEditableCollectionItemViewIndicatorAdd ? [UIImage imageNamed:@"ModernMenuAddIcon.png"] : [UIImage imageNamed:@"ModernMenuDeleteIcon.png"]];
|
2014-07-10 16:11:09 +02:00
|
|
|
_deleteIndicator.userInteractionEnabled = true;
|
|
|
|
[_deleteIndicator addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(deleteIndicatorTapGesture:)]];
|
|
|
|
|
|
|
|
_deleteIndicator.alpha = 0.0f;
|
|
|
|
[_editingScrollView addSubview:_deleteIndicator];
|
|
|
|
[self _layoutDeleteIndicator];
|
|
|
|
}
|
|
|
|
|
|
|
|
_showsDeleteIndicator = showsDeleteIndicator;
|
|
|
|
|
|
|
|
if (animated)
|
|
|
|
{
|
|
|
|
[UIView animateWithDuration:0.3 delay:0.0 options:0 animations:^
|
|
|
|
{
|
|
|
|
_deleteIndicator.alpha = _enableEditing && _showsDeleteIndicator ? 1.0f : 0.0f;
|
|
|
|
[self layoutSubviews];
|
|
|
|
|
|
|
|
if (!_showsDeleteIndicator)
|
|
|
|
[_editingScrollView setOptionsAreRevealed:false animated:false];
|
|
|
|
} completion:nil];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
_deleteIndicator.alpha = _enableEditing && _showsDeleteIndicator ? 1.0f : 0.0f;
|
|
|
|
|
|
|
|
if (!_showsDeleteIndicator)
|
|
|
|
[_editingScrollView setOptionsAreRevealed:false animated:false];
|
|
|
|
|
|
|
|
[self setNeedsLayout];
|
|
|
|
}
|
|
|
|
|
|
|
|
_editingScrollView.lockScroll = showsDeleteIndicator;
|
|
|
|
_editingScrollView.disableScroll = !_enableEditing;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)setShowsEditingOptions:(bool)showsEditingOptions animated:(bool)animated
|
|
|
|
{
|
|
|
|
if (showsEditingOptions != _editingScrollView.optionsAreRevealed)
|
|
|
|
{
|
|
|
|
if (showsEditingOptions)
|
|
|
|
{
|
|
|
|
[self actionButton];
|
|
|
|
[self _layoutActionButton];
|
|
|
|
}
|
|
|
|
|
|
|
|
if (showsEditingOptions || !animated)
|
|
|
|
{
|
|
|
|
[_editingScrollView setOptionsAreRevealed:true animated:animated];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
[UIView animateWithDuration:0.3 delay:0.0 options:0 animations:^
|
|
|
|
{
|
|
|
|
[_editingScrollView setOptionsAreRevealed:false animated:false];
|
|
|
|
} completion:nil];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)_layoutDeleteIndicator
|
|
|
|
{
|
|
|
|
CGSize deleteIndicatorSize = _deleteIndicator.bounds.size;
|
|
|
|
_deleteIndicator.frame = CGRectMake((_showsDeleteIndicator ? 12.0f : -deleteIndicatorSize.width), CGFloor((self.bounds.size.height - deleteIndicatorSize.height) / 2.0f) + 1.0f, deleteIndicatorSize.width, deleteIndicatorSize.height);
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)_layoutActionButton
|
|
|
|
{
|
|
|
|
CGRect bounds = _editingScrollView.bounds;
|
|
|
|
CGFloat optionsWidth = [_editingScrollView optionsWidth];
|
|
|
|
|
|
|
|
_actionButton.frame = CGRectMake(bounds.size.width - MIN(bounds.origin.x, optionsWidth), _optionsOffset.y, optionsWidth, bounds.size.height);
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)layoutSubviews
|
|
|
|
{
|
|
|
|
[super layoutSubviews];
|
|
|
|
|
|
|
|
CGRect bounds = self.bounds;
|
|
|
|
|
|
|
|
CGFloat separatorHeight = TGIsRetina() ? 0.5f : 1.0f;
|
|
|
|
|
|
|
|
_editingScrollView.contentSize = CGSizeMake(bounds.size.width + 82.0f, bounds.size.height + separatorHeight);
|
|
|
|
_editingScrollView.frame = CGRectMake(0.0f, 0.0f, bounds.size.width, bounds.size.height + separatorHeight);
|
|
|
|
|
|
|
|
if (_deleteIndicator != nil)
|
|
|
|
[self _layoutDeleteIndicator];
|
|
|
|
}
|
|
|
|
|
|
|
|
#pragma mark -
|
|
|
|
|
|
|
|
- (void)_requestSelection
|
|
|
|
{
|
|
|
|
[[self _collectionMenuView] _selectCell:self];
|
|
|
|
}
|
|
|
|
|
|
|
|
#pragma mark -
|
|
|
|
|
|
|
|
- (void)deleteIndicatorTapGesture:(UITapGestureRecognizer *)recognizer
|
|
|
|
{
|
|
|
|
if (recognizer.state == UIGestureRecognizerStateRecognized)
|
|
|
|
{
|
|
|
|
[self actionButton];
|
|
|
|
[self _layoutActionButton];
|
|
|
|
|
|
|
|
[_editingScrollView setOptionsAreRevealed:true animated:true];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)optionButtonPressed:(UIButton *)button
|
|
|
|
{
|
|
|
|
if (button == _actionButton)
|
|
|
|
[self deleteAction];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)deleteAction
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
@end
|