Permalink
Browse files

Implement support for dynamic alignment guides when moving objects. I…

…mplements Issue #14.
  • Loading branch information...
sprang committed Feb 9, 2014
1 parent 2b86168 commit 43aa96d8740d96de716926cafc061be6e4e6a297
View
@@ -91,6 +91,7 @@
@property (nonatomic, weak) UIView *toolOptionsView;
@property (nonatomic, readonly) float thinWidth;
@property (nonatomic, strong) IBOutlet UIView *activityView;
@property (nonatomic, strong) NSArray *dynamicGuides;
- (CGRect) convertRectToView:(CGRect)rect;
- (CGPoint) convertPointToDocumentSpace:(CGPoint)pt;
View
@@ -66,6 +66,7 @@ @implementation WDCanvas
@synthesize verticalRuler = verticalRuler_;
@synthesize toolOptionsView = toolOptionsView_;
@synthesize activityView = activityView_;
@synthesize dynamicGuides = dynamicGuides_;
- (id)initWithFrame:(CGRect)frame
{
@@ -996,6 +997,12 @@ - (void) setMarquee:(NSValue *)marquee
[self invalidateSelectionView];
}
- (void) setDynamicGuides:(NSArray *)dynamicGuides
{
dynamicGuides_ = dynamicGuides;
[self invalidateSelectionView];
}
- (void) setShapeUnderConstruction:(WDPath *)path
{
shapeUnderConstruction_ = path;
@@ -281,6 +281,10 @@ - (void) drawView
[self.canvas.shapeUnderConstruction drawOpenGLHighlightWithTransform:CGAffineTransformIdentity viewTransform:effective];
}
if (self.canvas.dynamicGuides && self.canvas.dynamicGuides.count) {
[self.canvas.dynamicGuides makeObjectsPerformSelector:@selector(render:) withObject:canvas_];
}
[context presentRenderbuffer:GL_RENDERBUFFER_OES];
}
@@ -153,6 +153,7 @@ - (NSString *) localizedTitleForKey:(NSString *)key
map_[@"Snap to Points"] = NSLocalizedString(@"Snap to Points", @"Snap to Points");
map_[@"Snap to Edges"] = NSLocalizedString(@"Snap to Edges", @"Snap to Edges");
map_[@"Snap to Grid"] = NSLocalizedString(@"Snap to Grid", @"Snap to Grid");
map_[@"Dynamic Guides"] = NSLocalizedString(@"Dynamic Guides", @"Dynamic 'Smart' alignment guides");
map_[@"Grid"] = NSLocalizedString(@"Grid", @"Grid");
map_[@"Grid Spacing"] = NSLocalizedString(@"Grid Spacing", @"Grid Spacing");
map_[@"Isolate Active Layer"] = NSLocalizedString(@"Isolate Active Layer", @"Isolate Active Layer");
@@ -288,6 +289,15 @@ - (void) takeSnapToGridFrom:(id)sender
[[NSUserDefaults standardUserDefaults] synchronize];
}
- (void) takeDynamicGuidesFrom:(id)sender
{
UISwitch *mySwitch = (UISwitch *)sender;
drawing_.dynamicGuides = mySwitch.isOn;
[[NSUserDefaults standardUserDefaults] setBool:mySwitch.isOn forKey:WDDynamicGuides];
[[NSUserDefaults standardUserDefaults] synchronize];
}
- (void) takeShowGridFrom:(id)sender
{
UISwitch *mySwitch = (UISwitch *)sender;
@@ -48,11 +48,14 @@
- (WDElement *) singleSelection;
- (NSMutableArray *) orderedSelectedObjects;
- (NSArray *) sortedSelectionForLayer:(WDLayer *)layer;
- (NSArray *) unselectedObjects;
- (BOOL) isSelected:(WDElement *)element;
- (BOOL) isSelectedOrSubelementIsSelected:(WDElement *)element;
- (CGRect) selectionBounds;
- (CGRect) selectionStyleBounds;
- (NSSet *) selectedPaths;
- (BOOL) allSelectedObjectsAreRootObjects;
@@ -341,6 +341,31 @@ - (BOOL) allSiblingsSelected:(WDPath *)path
return NO;
}
- (NSArray *) unselectedObjects
{
NSMutableArray *result = [NSMutableArray array];
for (WDLayer *layer in drawing_.layers) {
if (layer.hidden) {
// don't snap to objects on hidden layers
continue;
}
if (self.drawing.isolateActiveLayer && layer != self.drawing.activeLayer) {
// ignore non-isolated layers
continue;
}
NSArray *unselected = [layer.elements filter:^BOOL(id obj) {
return ![selectedObjects_ containsObject:obj];
}];
[result addObjectsFromArray:unselected];
}
return result;
}
- (NSMutableArray *) orderedSelectedObjects
{
NSMutableArray *ordered = [NSMutableArray array];
@@ -389,6 +414,17 @@ - (CGRect) selectionBounds
return bounds;
}
- (CGRect) selectionStyleBounds
{
CGRect bounds = CGRectNull;
for (WDElement *element in selectedObjects_) {
bounds = CGRectUnion(bounds, element.styleBounds);
}
return bounds;
}
- (NSSet *) selectedPaths
{
NSMutableSet *selectedPaths = [NSMutableSet set];
@@ -65,6 +65,7 @@ BOOL WDRenderingMetaDataOutlineOnly(WDRenderingMetaData metaData);
@property (nonatomic, assign) BOOL snapToEdges;
@property (nonatomic, assign) BOOL snapToPoints;
@property (nonatomic, assign) BOOL snapToGrid;
@property (nonatomic, assign) BOOL dynamicGuides;
@property (nonatomic, assign) BOOL showGrid;
@property (nonatomic, assign) BOOL isolateActiveLayer;
@property (nonatomic, assign) BOOL outlineMode;
@@ -118,6 +119,7 @@ BOOL WDRenderingMetaDataOutlineOnly(WDRenderingMetaData metaData);
extern NSString *WDSnapToPoints;
extern NSString *WDSnapToEdges;
extern NSString *WDSnapToGrid;
extern NSString *WDDynamicGuides;
extern NSString *WDShowGrid;
extern NSString *WDGridSpacing;
extern NSString *WDIsolateActiveLayer;
@@ -47,6 +47,7 @@
NSString *WDIsolateActiveLayer = @"WDIsolateActiveLayer";
NSString *WDOutlineMode = @"WDOutlineMode";
NSString *WDSnapToGrid = @"WDSnapToGrid";
NSString *WDDynamicGuides = @"WDDynamicGuides";
NSString *WDShowGrid = @"WDShowGrid";
NSString *WDGridSpacing = @"WDGridSpacing";
NSString *WDRulersVisible = @"WDRulersVisible";
@@ -146,7 +147,7 @@ - (id) initWithSize:(CGSize)size andUnits:(NSString *)units
// each drawing saves its own settings, but when a user alters them they become the default settings for new documents
// since this is a new document, look up the values in the defaults...
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSArray *keyArray = @[WDShowGrid, WDSnapToGrid, WDSnapToPoints, WDSnapToEdges, WDRulersVisible];
NSArray *keyArray = @[WDShowGrid, WDSnapToGrid, WDSnapToPoints, WDSnapToEdges, WDDynamicGuides, WDRulersVisible];
for (NSString *key in keyArray) {
settings_[key] = @([defaults boolForKey:key]);
}
@@ -298,6 +299,10 @@ - (NSUInteger) snapFlags
flags |= kWDSnapEdges;
}
if ([settings_[WDDynamicGuides] boolValue]) {
flags |= kWDSnapDynamicGuides;
}
return flags;
}
@@ -830,6 +835,19 @@ - (void) setSnapToGrid:(BOOL)snap
[self.document markChanged];
}
- (BOOL) dynamicGuides
{
return [settings_[WDDynamicGuides] boolValue];
}
- (void) setDynamicGuides:(BOOL)dynamicGuides
{
settings_[WDDynamicGuides] = @(dynamicGuides);
// this isn't an undoable action so it does not dirty the document
[self.document markChanged];
}
- (BOOL) isolateActiveLayer
{
return [settings_[WDIsolateActiveLayer] boolValue];
@@ -0,0 +1,57 @@
//
// WDDynamicGuide.h
// Inkpad
//
// Created by Steve Sprang on 2/7/14.
// Copyright (c) 2014 Taptrix, Inc. All rights reserved.
//
#import <Foundation/Foundation.h>
@class WDCanvas;
//
// WDExtent
//
@interface WDExtent : NSObject
@property (nonatomic) double min;
@property (nonatomic) double max;
+ (WDExtent *) extentWithMin:(double)min max:(double)max;
@end
//
// WDDynamicGuide
//
static NSComparator guideCompare = ^(id a, id b){
return [a compare:b];
};
@interface WDDynamicGuide : NSObject
// the position of the guide
@property (nonatomic) double offset;
// contains an extent for every object aligned to this guide
@property (nonatomic) NSMutableSet *extents;
// the min/max of all the extents
@property (nonatomic) double minExtent;
@property (nonatomic) double maxExtent;
@property (nonatomic, getter=isVertical) BOOL vertical;
+ (WDDynamicGuide *) verticalGuideWithOffset:(double)offset;
+ (WDDynamicGuide *) horizontalGuideWithOffset:(double)offset;
+ (void) generateGuidesForBoundingBox:(CGRect)bbox
horizontalGuides:(NSMutableArray *)horizontal
verticalGuides:(NSMutableArray *)vertical;
- (void) addExtent:(WDExtent *)extent;
- (void) addExtentsFromSet:(NSSet *)extents;
- (void) render:(WDCanvas *)canvas;
@end
Oops, something went wrong.

0 comments on commit 43aa96d

Please sign in to comment.