mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
159 lines
3.8 KiB
Objective-C
159 lines
3.8 KiB
Objective-C
#import "TGPaintUndoManager.h"
|
|
|
|
#import "LegacyComponentsInternal.h"
|
|
|
|
#import <SSignalKit/SQueue.h>
|
|
|
|
@interface TGPaintUndoOperation : NSObject <NSCopying>
|
|
|
|
@property (nonatomic, readonly) NSInteger uuid;
|
|
@property (nonatomic, readonly) void (^block)(TGPaintUndoManager *);
|
|
|
|
- (void)performWithManager:(TGPaintUndoManager *)manager;
|
|
|
|
+ (instancetype)operationWithUUID:(NSInteger)uuid block:(void (^)(TGPaintUndoManager *manager))block;
|
|
|
|
@end
|
|
|
|
@interface TGPaintUndoManager ()
|
|
{
|
|
SQueue *_queue;
|
|
NSMutableArray *_operations;
|
|
NSMutableDictionary *_uuidToOperationMap;
|
|
}
|
|
@end
|
|
|
|
@implementation TGPaintUndoManager
|
|
|
|
- (instancetype)init
|
|
{
|
|
self = [super init];
|
|
if (self != nil)
|
|
{
|
|
_queue = [[SQueue alloc] init];
|
|
_operations = [[NSMutableArray alloc] init];
|
|
_uuidToOperationMap = [[NSMutableDictionary alloc] init];
|
|
}
|
|
return self;
|
|
}
|
|
|
|
- (id)copyWithZone:(NSZone *)__unused zone
|
|
{
|
|
TGPaintUndoManager *undoManager = [[TGPaintUndoManager alloc] init];
|
|
undoManager->_operations = [[NSMutableArray alloc] initWithArray:_operations copyItems:true];
|
|
undoManager->_uuidToOperationMap = [[NSMutableDictionary alloc] initWithDictionary:_uuidToOperationMap copyItems:true];
|
|
return undoManager;
|
|
}
|
|
|
|
- (bool)canUndo
|
|
{
|
|
return _operations.count > 0;
|
|
}
|
|
|
|
- (void)undo
|
|
{
|
|
[_queue dispatch:^
|
|
{
|
|
if (_operations.count == 0)
|
|
return;
|
|
|
|
NSNumber *key = _operations.lastObject;
|
|
TGPaintUndoOperation *operation = _uuidToOperationMap[key];
|
|
[_uuidToOperationMap removeObjectForKey:key];
|
|
[_operations removeLastObject];
|
|
|
|
TGDispatchOnMainThread(^
|
|
{
|
|
[operation performWithManager:self];
|
|
|
|
if (self.historyChanged != nil)
|
|
self.historyChanged();
|
|
});
|
|
}];
|
|
}
|
|
|
|
- (void)registerUndoWithUUID:(NSInteger)uuid block:(void (^)(TGPainting *, TGPhotoEntitiesContainerView *, NSInteger))block
|
|
{
|
|
[_queue dispatch:^
|
|
{
|
|
TGPaintUndoOperation *operation = [TGPaintUndoOperation operationWithUUID:uuid block:^(TGPaintUndoManager *manager)
|
|
{
|
|
[manager _performBlock:block uuid:uuid];
|
|
}];
|
|
|
|
NSNumber *key = @(uuid);
|
|
_uuidToOperationMap[key] = operation;
|
|
[_operations addObject:key];
|
|
|
|
[self _notifyOfHistoryChanges];
|
|
}];
|
|
}
|
|
|
|
- (void)unregisterUndoWithUUID:(NSInteger)uuid
|
|
{
|
|
[_queue dispatch:^
|
|
{
|
|
NSNumber *key = @(uuid);
|
|
[_uuidToOperationMap removeObjectForKey:key];
|
|
[_operations removeObject:key];
|
|
|
|
[self _notifyOfHistoryChanges];
|
|
}];
|
|
}
|
|
|
|
- (void)_performBlock:(void (^)(TGPainting *, TGPhotoEntitiesContainerView *, NSInteger))block uuid:(NSInteger)uuid
|
|
{
|
|
block(self.painting, self.entitiesContainer, uuid);
|
|
}
|
|
|
|
- (void)reset
|
|
{
|
|
[_queue dispatch:^
|
|
{
|
|
[_operations removeAllObjects];
|
|
[_uuidToOperationMap removeAllObjects];
|
|
|
|
[self _notifyOfHistoryChanges];
|
|
}];
|
|
}
|
|
|
|
- (void)_notifyOfHistoryChanges
|
|
{
|
|
TGDispatchOnMainThread(^
|
|
{
|
|
if (self.historyChanged != nil)
|
|
self.historyChanged();
|
|
});
|
|
}
|
|
|
|
@end
|
|
|
|
|
|
@implementation TGPaintUndoOperation
|
|
|
|
- (id)copyWithZone:(NSZone *)__unused zone
|
|
{
|
|
TGPaintUndoOperation *operation = [[TGPaintUndoOperation alloc] init];
|
|
operation->_uuid = _uuid;
|
|
operation->_block = [_block copy];
|
|
return operation;
|
|
}
|
|
|
|
- (void)performWithManager:(TGPaintUndoManager *)manager
|
|
{
|
|
self.block(manager);
|
|
}
|
|
|
|
+ (instancetype)operationWithUUID:(NSInteger)uuid block:(void (^)(TGPaintUndoManager *manager))block
|
|
{
|
|
if (uuid == 0 || block == nil)
|
|
return nil;
|
|
|
|
TGPaintUndoOperation *operation = [[TGPaintUndoOperation alloc] init];
|
|
operation->_uuid = uuid;
|
|
operation->_block = [block copy];
|
|
return operation;
|
|
}
|
|
|
|
@end
|