mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-24 07:05:35 +00:00
Build ChatListUI
This commit is contained in:
@@ -0,0 +1,545 @@
|
||||
#import "TGPhotoEditorCurvesToolView.h"
|
||||
|
||||
#import "LegacyComponentsInternal.h"
|
||||
#import "TGFont.h"
|
||||
#import "TGImageUtils.h"
|
||||
|
||||
typedef enum
|
||||
{
|
||||
TGCurvesSegmentNone,
|
||||
TGCurvesSegmentBlacks,
|
||||
TGCurvesSegmentShadows,
|
||||
TGCurvesSegmentMidtones,
|
||||
TGCurvesSegmentHighlights,
|
||||
TGCurvesSegmentWhites
|
||||
} TGCurvesSegment;
|
||||
|
||||
@interface TGPhotoEditorCurvesToolView () <UIGestureRecognizerDelegate>
|
||||
{
|
||||
TGCurvesSegment _activeSegment;
|
||||
|
||||
UILabel *_blacksLevelLabel;
|
||||
UILabel *_shadowsLevelLabel;
|
||||
UILabel *_midtonesLevelLabel;
|
||||
UILabel *_highlightsLevelLabel;
|
||||
UILabel *_whitesLevelLabel;
|
||||
|
||||
UIView *_selectionView;
|
||||
|
||||
UILongPressGestureRecognizer *_pressGestureRecognizer;
|
||||
UIPanGestureRecognizer *_panGestureRecognizer;
|
||||
UITapGestureRecognizer *_doubleTapGestureRecognizer;
|
||||
|
||||
NSArray *_interpolatedCurveValues;
|
||||
CAShapeLayer *_curveLayer;
|
||||
bool _appeared;
|
||||
}
|
||||
|
||||
@property (nonatomic, weak) PGCurvesTool *curvesTool;
|
||||
|
||||
@end
|
||||
|
||||
@implementation TGPhotoEditorCurvesToolView
|
||||
|
||||
@synthesize valueChanged = _valueChanged;
|
||||
@synthesize value = _value;
|
||||
@synthesize interactionBegan = _interactionBegan;
|
||||
@synthesize interactionEnded = _interactionEnded;
|
||||
@synthesize actualAreaSize;
|
||||
@synthesize isLandscape;
|
||||
@synthesize toolbarLandscapeSize;
|
||||
|
||||
- (instancetype)initWithEditorItem:(id<PGPhotoEditorItem>)__unused editorItem
|
||||
{
|
||||
self = [self initWithFrame:CGRectZero];
|
||||
if (self != nil)
|
||||
{
|
||||
self.backgroundColor = [UIColor clearColor];
|
||||
self.contentMode = UIViewContentModeRedraw;
|
||||
|
||||
_activeSegment = TGCurvesSegmentNone;
|
||||
|
||||
_selectionView = [[UIView alloc] initWithFrame:CGRectZero];
|
||||
_selectionView.alpha = 0.0f;
|
||||
_selectionView.backgroundColor = [UIColor whiteColor];
|
||||
_selectionView.userInteractionEnabled = false;
|
||||
//[self addSubview:_selectionView];
|
||||
|
||||
_blacksLevelLabel = [self _levelLabel];
|
||||
_blacksLevelLabel.text = @"0.00";
|
||||
[self addSubview:_blacksLevelLabel];
|
||||
|
||||
_shadowsLevelLabel = [self _levelLabel];
|
||||
_shadowsLevelLabel.text = @"0.00";
|
||||
[self addSubview:_shadowsLevelLabel];
|
||||
|
||||
_midtonesLevelLabel = [self _levelLabel];
|
||||
_midtonesLevelLabel.text = @"0.00";
|
||||
[self addSubview:_midtonesLevelLabel];
|
||||
|
||||
_highlightsLevelLabel = [self _levelLabel];
|
||||
_highlightsLevelLabel.text = @"0.00";
|
||||
[self addSubview:_highlightsLevelLabel];
|
||||
|
||||
_whitesLevelLabel = [self _levelLabel];
|
||||
_whitesLevelLabel.text = @"0.00";
|
||||
[self addSubview:_whitesLevelLabel];
|
||||
|
||||
_panGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)];
|
||||
_panGestureRecognizer.delegate = self;
|
||||
[self addGestureRecognizer:_panGestureRecognizer];
|
||||
|
||||
_pressGestureRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handlePress:)];
|
||||
_pressGestureRecognizer.delegate = self;
|
||||
_pressGestureRecognizer.minimumPressDuration = 0.1f;
|
||||
[self addGestureRecognizer:_pressGestureRecognizer];
|
||||
|
||||
_doubleTapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleDoubleTap:)];
|
||||
_doubleTapGestureRecognizer.numberOfTapsRequired = 2;
|
||||
[self addGestureRecognizer:_doubleTapGestureRecognizer];
|
||||
|
||||
if ([editorItem isKindOfClass:[PGCurvesTool class]])
|
||||
{
|
||||
PGCurvesTool *curvesTool = (PGCurvesTool *)editorItem;
|
||||
self.curvesTool = curvesTool;
|
||||
[self setValue:editorItem.value];
|
||||
}
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (UILabel *)_levelLabel
|
||||
{
|
||||
UILabel *label = [[UILabel alloc] initWithFrame:CGRectZero];
|
||||
label.backgroundColor = [UIColor clearColor];
|
||||
label.font = [TGFont systemFontOfSize:13];
|
||||
label.textAlignment = NSTextAlignmentCenter;
|
||||
label.textColor = [UIColor colorWithWhite:1.0f alpha:0.75f];
|
||||
return label;
|
||||
}
|
||||
|
||||
- (void)setValue:(id)value
|
||||
{
|
||||
if (![value isKindOfClass:[PGCurvesToolValue class]])
|
||||
return;
|
||||
|
||||
_value = value;
|
||||
|
||||
[self updateCurve];
|
||||
[self updateValueLabels];
|
||||
}
|
||||
|
||||
- (void)updateCurve
|
||||
{
|
||||
if (CGRectEqualToRect([self _actualArea], CGRectZero))
|
||||
return;
|
||||
|
||||
PGCurvesToolValue *curvesToolValue = (PGCurvesToolValue *)_value;
|
||||
|
||||
PGCurvesValue *curvesValue = nil;
|
||||
switch (curvesToolValue.activeType)
|
||||
{
|
||||
case PGCurvesTypeLuminance:
|
||||
curvesValue = curvesToolValue.luminanceCurve;
|
||||
break;
|
||||
|
||||
case PGCurvesTypeRed:
|
||||
curvesValue = curvesToolValue.redCurve;
|
||||
break;
|
||||
|
||||
case PGCurvesTypeGreen:
|
||||
curvesValue = curvesToolValue.greenCurve;
|
||||
break;
|
||||
|
||||
case PGCurvesTypeBlue:
|
||||
curvesValue = curvesToolValue.blueCurve;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
NSArray *points = [curvesValue interpolateCurve];
|
||||
[self renderCurveWithPoints:points color:[TGPhotoEditorCurvesToolView colorForCurveType:curvesToolValue.activeType] lineWidth:2];
|
||||
}
|
||||
|
||||
- (void)updateValueLabels
|
||||
{
|
||||
PGCurvesToolValue *curvesToolValue = (PGCurvesToolValue *)_value;
|
||||
|
||||
PGCurvesValue *curvesValue = nil;
|
||||
switch (curvesToolValue.activeType)
|
||||
{
|
||||
case PGCurvesTypeLuminance:
|
||||
curvesValue = curvesToolValue.luminanceCurve;
|
||||
break;
|
||||
|
||||
case PGCurvesTypeRed:
|
||||
curvesValue = curvesToolValue.redCurve;
|
||||
break;
|
||||
|
||||
case PGCurvesTypeGreen:
|
||||
curvesValue = curvesToolValue.greenCurve;
|
||||
break;
|
||||
|
||||
case PGCurvesTypeBlue:
|
||||
curvesValue = curvesToolValue.blueCurve;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
_blacksLevelLabel.text = [NSString stringWithFormat:@"%0.2f", curvesValue.blacksLevel / 100.0f];
|
||||
_shadowsLevelLabel.text = [NSString stringWithFormat:@"%0.2f", curvesValue.shadowsLevel / 100.0f];
|
||||
_midtonesLevelLabel.text = [NSString stringWithFormat:@"%0.2f", curvesValue.midtonesLevel / 100.0f];
|
||||
_highlightsLevelLabel.text = [NSString stringWithFormat:@"%0.2f", curvesValue.highlightsLevel / 100.0f];
|
||||
_whitesLevelLabel.text = [NSString stringWithFormat:@"%0.2f", curvesValue.whitesLevel / 100.0f];
|
||||
}
|
||||
|
||||
+ (UIColor *)colorForCurveType:(PGCurvesType)curveType
|
||||
{
|
||||
switch (curveType)
|
||||
{
|
||||
case PGCurvesTypeLuminance:
|
||||
return [UIColor whiteColor];
|
||||
|
||||
case PGCurvesTypeRed:
|
||||
return UIColorRGB(0xed3d4c);
|
||||
|
||||
case PGCurvesTypeGreen:
|
||||
return UIColorRGB(0x10ee9d);
|
||||
|
||||
case PGCurvesTypeBlue:
|
||||
return UIColorRGB(0x3377fb);
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
- (bool)buttonPressed:(bool)__unused cancelButton
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
- (bool)isTracking
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
- (void)handlePress:(UILongPressGestureRecognizer *)gestureRecognizer
|
||||
{
|
||||
switch (gestureRecognizer.state)
|
||||
{
|
||||
case UIGestureRecognizerStateBegan:
|
||||
[self selectSegmentWithPoint:[gestureRecognizer locationInView:gestureRecognizer.view]];
|
||||
break;
|
||||
|
||||
case UIGestureRecognizerStateEnded:
|
||||
case UIGestureRecognizerStateCancelled:
|
||||
case UIGestureRecognizerStateFailed:
|
||||
[self unselectSegments];
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)handlePan:(UIPanGestureRecognizer *)gestureRecognizer
|
||||
{
|
||||
switch (gestureRecognizer.state)
|
||||
{
|
||||
case UIGestureRecognizerStateBegan:
|
||||
[self selectSegmentWithPoint:[gestureRecognizer locationInView:gestureRecognizer.view]];
|
||||
break;
|
||||
|
||||
case UIGestureRecognizerStateChanged:
|
||||
{
|
||||
PGCurvesToolValue *newValue = [(PGCurvesToolValue *)_value copy];
|
||||
|
||||
CGPoint translation = [gestureRecognizer translationInView:gestureRecognizer.view];
|
||||
CGFloat delta = MIN(2, -1 * translation.y / 8.0f);
|
||||
|
||||
PGCurvesValue *curveValue = nil;
|
||||
switch (newValue.activeType)
|
||||
{
|
||||
case PGCurvesTypeLuminance:
|
||||
curveValue = newValue.luminanceCurve;
|
||||
break;
|
||||
|
||||
case PGCurvesTypeRed:
|
||||
curveValue = newValue.redCurve;
|
||||
break;
|
||||
|
||||
case PGCurvesTypeGreen:
|
||||
curveValue = newValue.greenCurve;
|
||||
break;
|
||||
|
||||
case PGCurvesTypeBlue:
|
||||
curveValue = newValue.blueCurve;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
switch (_activeSegment)
|
||||
{
|
||||
case TGCurvesSegmentBlacks:
|
||||
curveValue.blacksLevel = MAX(0, MIN(100, curveValue.blacksLevel + delta));
|
||||
break;
|
||||
|
||||
case TGCurvesSegmentShadows:
|
||||
curveValue.shadowsLevel = MAX(0, MIN(100, curveValue.shadowsLevel + delta));
|
||||
break;
|
||||
|
||||
case TGCurvesSegmentMidtones:
|
||||
curveValue.midtonesLevel = MAX(0, MIN(100, curveValue.midtonesLevel + delta));
|
||||
break;
|
||||
|
||||
case TGCurvesSegmentHighlights:
|
||||
curveValue.highlightsLevel = MAX(0, MIN(100, curveValue.highlightsLevel + delta));
|
||||
break;
|
||||
|
||||
case TGCurvesSegmentWhites:
|
||||
curveValue.whitesLevel = MAX(0, MIN(100, curveValue.whitesLevel + delta));
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
_value = newValue;
|
||||
|
||||
[self updateCurve];
|
||||
[self updateValueLabels];
|
||||
|
||||
if (self.valueChanged != nil)
|
||||
self.valueChanged(newValue, false);
|
||||
|
||||
[gestureRecognizer setTranslation:CGPointZero inView:gestureRecognizer.view];
|
||||
}
|
||||
break;
|
||||
|
||||
case UIGestureRecognizerStateEnded:
|
||||
case UIGestureRecognizerStateCancelled:
|
||||
case UIGestureRecognizerStateFailed:
|
||||
{
|
||||
[self unselectSegments];
|
||||
|
||||
if (self.interactionEnded != nil)
|
||||
self.interactionEnded();
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)handleDoubleTap:(UITapGestureRecognizer *)__unused gestureRecognizer
|
||||
{
|
||||
PGCurvesToolValue *value = [_value copy];
|
||||
if (value == nil)
|
||||
return;
|
||||
|
||||
switch (value.activeType) {
|
||||
case PGCurvesTypeLuminance:
|
||||
value.luminanceCurve = [PGCurvesValue defaultValue];
|
||||
break;
|
||||
|
||||
case PGCurvesTypeRed:
|
||||
value.redCurve = [PGCurvesValue defaultValue];
|
||||
break;
|
||||
|
||||
case PGCurvesTypeGreen:
|
||||
value.greenCurve = [PGCurvesValue defaultValue];
|
||||
break;
|
||||
|
||||
case PGCurvesTypeBlue:
|
||||
value.blueCurve = [PGCurvesValue defaultValue];
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
_value = value;
|
||||
|
||||
[self updateCurve];
|
||||
[self updateValueLabels];
|
||||
|
||||
self.valueChanged(value, false);
|
||||
}
|
||||
|
||||
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
|
||||
{
|
||||
if (gestureRecognizer == _pressGestureRecognizer || gestureRecognizer == _panGestureRecognizer)
|
||||
{
|
||||
CGPoint location = [gestureRecognizer locationInView:self];
|
||||
CGRect actualArea = [self _actualArea];
|
||||
|
||||
return CGRectContainsPoint(actualArea, location);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
|
||||
{
|
||||
if (gestureRecognizer == _pressGestureRecognizer || otherGestureRecognizer == _pressGestureRecognizer)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
- (void)selectSegmentWithPoint:(CGPoint)point
|
||||
{
|
||||
if (_activeSegment != TGCurvesSegmentNone)
|
||||
return;
|
||||
|
||||
CGRect actualArea = [self _actualArea];
|
||||
CGFloat segmentWidth = actualArea.size.width / 5.0f;
|
||||
|
||||
point = CGPointMake(point.x - actualArea.origin.x, point.y - actualArea.origin.y);
|
||||
|
||||
_activeSegment = (TGCurvesSegment)(floor(point.x / segmentWidth) + 1);
|
||||
|
||||
[UIView animateWithDuration:0.2f animations:^
|
||||
{
|
||||
_selectionView.alpha = 0.11f;
|
||||
}];
|
||||
|
||||
_selectionView.frame = CGRectMake(actualArea.origin.x + (_activeSegment - 1) * segmentWidth, actualArea.origin.y, segmentWidth, actualArea.size.height);
|
||||
}
|
||||
|
||||
- (void)unselectSegments
|
||||
{
|
||||
if (_activeSegment == TGCurvesSegmentNone)
|
||||
return;
|
||||
|
||||
_activeSegment = TGCurvesSegmentNone;
|
||||
|
||||
[UIView animateWithDuration:0.3f animations:^
|
||||
{
|
||||
_selectionView.alpha = 0.0f;
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)drawRect:(CGRect)__unused rect
|
||||
{
|
||||
CGRect actualArea = [self _actualArea];
|
||||
CGContextRef context = UIGraphicsGetCurrentContext();
|
||||
|
||||
CGFloat segmentWidth = actualArea.size.width / 5.0f;
|
||||
|
||||
CGContextSetStrokeColorWithColor(context, [UIColor colorWithWhite:1.0f alpha:0.6f].CGColor);
|
||||
CGContextSetLineWidth(context, 1 - TGRetinaPixel);
|
||||
|
||||
for (NSUInteger i = 0; i < 4; i++)
|
||||
{
|
||||
CGContextMoveToPoint(context, actualArea.origin.x + segmentWidth + i * segmentWidth, actualArea.origin.y);
|
||||
CGContextAddLineToPoint(context, actualArea.origin.x + segmentWidth + i * segmentWidth, actualArea.origin.y + actualArea.size.height);
|
||||
CGContextStrokePath(context);
|
||||
}
|
||||
|
||||
CGContextSetStrokeColorWithColor(context, [UIColor colorWithWhite:1.0f alpha:0.6f].CGColor);
|
||||
CGContextSetLineWidth(context, 1.5f);
|
||||
|
||||
CGFloat lengths[] = { 7, 4 };
|
||||
CGContextSetLineDash(context, 0.0, lengths, 2);
|
||||
|
||||
CGContextMoveToPoint(context, actualArea.origin.x, actualArea.origin.y + actualArea.size.height);
|
||||
CGContextAddLineToPoint(context, actualArea.origin.x + actualArea.size.width, actualArea.origin.y );
|
||||
CGContextStrokePath(context);
|
||||
|
||||
CGContextSetLineDash(context, 0.0, NULL, 0);
|
||||
}
|
||||
|
||||
- (CGRect)_actualArea
|
||||
{
|
||||
return CGRectMake((self.frame.size.width - self.actualAreaSize.width) / 2, (self.frame.size.height - self.actualAreaSize.height) / 2, self.actualAreaSize.width, self.actualAreaSize.height);
|
||||
}
|
||||
|
||||
- (CGPoint)_viewPointWithPoint:(CGPoint)point actualArea:(CGRect)actualArea
|
||||
{
|
||||
return CGPointMake(point.x * actualArea.size.width, (1.0 - point.y) * actualArea.size.height);
|
||||
}
|
||||
|
||||
- (void)renderCurveWithPoints:(NSArray *)points color:(UIColor *)color lineWidth:(CGFloat)lineWidth
|
||||
{
|
||||
UIBezierPath *path = [UIBezierPath bezierPath];
|
||||
CGRect actualArea = [self _actualArea];
|
||||
|
||||
[points enumerateObjectsUsingBlock:^(NSValue *value, NSUInteger index, __unused BOOL *stop)
|
||||
{
|
||||
CGPoint point = [self _viewPointWithPoint:value.CGPointValue actualArea:actualArea];
|
||||
|
||||
if (index == 0)
|
||||
[path moveToPoint:point];
|
||||
else
|
||||
[path addLineToPoint:point];
|
||||
}];
|
||||
|
||||
if (_curveLayer == nil)
|
||||
{
|
||||
_curveLayer = [[CAShapeLayer alloc] init];
|
||||
_curveLayer.fillColor = [UIColor clearColor].CGColor;
|
||||
_curveLayer.lineWidth = lineWidth;
|
||||
[_curveLayer setLineCap:kCALineCapRound];
|
||||
[self.layer addSublayer:_curveLayer];
|
||||
}
|
||||
|
||||
[UIView performWithoutAnimation:^
|
||||
{
|
||||
_curveLayer.strokeColor = color.CGColor;
|
||||
_curveLayer.path = [path CGPath];
|
||||
_curveLayer.frame = CGRectMake(actualArea.origin.x, actualArea.origin.y, actualArea.size.width, actualArea.size.height);
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)transitionIn
|
||||
{
|
||||
_appeared = true;
|
||||
self.alpha = 0.0f;
|
||||
|
||||
[UIView animateWithDuration:0.2f animations:^
|
||||
{
|
||||
self.alpha = 1.0f;
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)layoutSubviews
|
||||
{
|
||||
CGRect actualArea = [self _actualArea];
|
||||
CGFloat segmentWidth = actualArea.size.width / 5.0f;
|
||||
|
||||
CGFloat bottomOffset = 4.0f;
|
||||
|
||||
[_blacksLevelLabel sizeToFit];
|
||||
_blacksLevelLabel.frame = CGRectMake(actualArea.origin.x, actualArea.origin.y + actualArea.size.height - ceil(_blacksLevelLabel.frame.size.height) - bottomOffset, segmentWidth, ceil(_blacksLevelLabel.frame.size.height));
|
||||
|
||||
[_shadowsLevelLabel sizeToFit];
|
||||
_shadowsLevelLabel.frame = CGRectMake(actualArea.origin.x + segmentWidth, actualArea.origin.y + actualArea.size.height - ceil(_shadowsLevelLabel.frame.size.height) - bottomOffset, segmentWidth, ceil(_shadowsLevelLabel.frame.size.height));
|
||||
|
||||
[_midtonesLevelLabel sizeToFit];
|
||||
_midtonesLevelLabel.frame = CGRectMake(actualArea.origin.x + segmentWidth * 2, actualArea.origin.y + actualArea.size.height - ceil(_midtonesLevelLabel.frame.size.height) - bottomOffset, segmentWidth, ceil(_midtonesLevelLabel.frame.size.height));
|
||||
|
||||
[_highlightsLevelLabel sizeToFit];
|
||||
_highlightsLevelLabel.frame = CGRectMake(actualArea.origin.x + segmentWidth * 3, actualArea.origin.y + actualArea.size.height - ceil(_highlightsLevelLabel.frame.size.height) - bottomOffset, segmentWidth, ceil(_highlightsLevelLabel.frame.size.height));
|
||||
|
||||
[_whitesLevelLabel sizeToFit];
|
||||
_whitesLevelLabel.frame = CGRectMake(actualArea.origin.x + segmentWidth * 4, actualArea.origin.y + actualArea.size.height - ceil(_whitesLevelLabel.frame.size.height) - bottomOffset, segmentWidth, ceil(_whitesLevelLabel.frame.size.height));
|
||||
|
||||
_curveLayer.frame = CGRectMake(actualArea.origin.x, actualArea.origin.y, actualArea.size.width, actualArea.size.height);
|
||||
|
||||
[self updateCurve];
|
||||
|
||||
[self updateValueLabels];
|
||||
if (!_appeared)
|
||||
[self transitionIn];
|
||||
}
|
||||
|
||||
@end
|
||||
Reference in New Issue
Block a user