Permalink
Browse files

Can add and remove areas

  • Loading branch information...
1 parent 15f2edc commit a6a8bb22a3f85d234759165edfc70a53e22bcf5f @p2 committed Dec 22, 2012
View
10 growth-charts-helper.xcodeproj/project.pbxproj
@@ -7,6 +7,7 @@
objects = {
/* Begin PBXBuildFile section */
+ EE9408A616860CDA001FC955 /* CHClickableView.m in Sources */ = {isa = PBXBuildFile; fileRef = EE9408A516860CDA001FC955 /* CHClickableView.m */; };
EEAECBFE16815E2F00E8ABE1 /* CHRectToStringTransformer.m in Sources */ = {isa = PBXBuildFile; fileRef = EEAECBFD16815E2F00E8ABE1 /* CHRectToStringTransformer.m */; };
EEAECC1716816B7800E8ABE1 /* CHFloatToStringTransformer.m in Sources */ = {isa = PBXBuildFile; fileRef = EEAECC1616816B7800E8ABE1 /* CHFloatToStringTransformer.m */; };
EEAECC1A16816C4500E8ABE1 /* CHDecimalNumberToStringTransformer.m in Sources */ = {isa = PBXBuildFile; fileRef = EEAECC1916816C4500E8ABE1 /* CHDecimalNumberToStringTransformer.m */; };
@@ -35,6 +36,8 @@
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
+ EE9408A416860CDA001FC955 /* CHClickableView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CHClickableView.h; sourceTree = "<group>"; };
+ EE9408A516860CDA001FC955 /* CHClickableView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CHClickableView.m; sourceTree = "<group>"; };
EEAECBFC16815E2F00E8ABE1 /* CHRectToStringTransformer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CHRectToStringTransformer.h; sourceTree = "<group>"; };
EEAECBFD16815E2F00E8ABE1 /* CHRectToStringTransformer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CHRectToStringTransformer.m; sourceTree = "<group>"; };
EEAECC1516816B7800E8ABE1 /* CHFloatToStringTransformer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CHFloatToStringTransformer.h; sourceTree = "<group>"; };
@@ -142,11 +145,11 @@
EEEB2D7B1680E014004DC719 /* growth-charts-helper */ = {
isa = PBXGroup;
children = (
+ EEEB2DD71680FA95004DC719 /* CHWindowController.h */,
+ EEEB2DD81680FA95004DC719 /* CHWindowController.m */,
EEEB2D871680E014004DC719 /* CHDocument.h */,
EEEB2D881680E014004DC719 /* CHDocument.m */,
EEEB2D8A1680E014004DC719 /* CHDocument.xib */,
- EEEB2DD71680FA95004DC719 /* CHWindowController.h */,
- EEEB2DD81680FA95004DC719 /* CHWindowController.m */,
EEEB2DDE16810422004DC719 /* CHChartPDFView.h */,
EEEB2DDF16810422004DC719 /* CHChartPDFView.m */,
EEEB2DD21680EE70004DC719 /* CHChartAreaView.h */,
@@ -201,6 +204,8 @@
children = (
EEEB2DE31681075A004DC719 /* CHDropView.h */,
EEEB2DE41681075A004DC719 /* CHDropView.m */,
+ EE9408A416860CDA001FC955 /* CHClickableView.h */,
+ EE9408A516860CDA001FC955 /* CHClickableView.m */,
EEEB2DDA1680FFC7004DC719 /* CHEnumToNumberTransformer.h */,
EEEB2DDB1680FFC7004DC719 /* CHEnumToNumberTransformer.m */,
EEAECC1516816B7800E8ABE1 /* CHFloatToStringTransformer.h */,
@@ -297,6 +302,7 @@
EEAECC1716816B7800E8ABE1 /* CHFloatToStringTransformer.m in Sources */,
EEAECC1A16816C4500E8ABE1 /* CHDecimalNumberToStringTransformer.m in Sources */,
EEEFDEB11682737B005C4D17 /* CHResizableChartAreaView.m in Sources */,
+ EE9408A616860CDA001FC955 /* CHClickableView.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
View
11 growth-charts-helper/CHChartAreaView.h
@@ -20,7 +20,7 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#import <Cocoa/Cocoa.h>
+#import "CHClickableView.h"
#import <QuartzCore/QuartzCore.h>
#import "CHChart.h"
@@ -39,7 +39,7 @@
*
* @attention Override "drawLayer:inContext:" in subclasses, not "drawRect:"!
*/
-@interface CHChartAreaView : NSView
+@interface CHChartAreaView : CHClickableView
@property (nonatomic, weak) CHChartArea *area; ///< The area model that describes the receiver
@@ -50,7 +50,6 @@
@property (nonatomic, copy) NSArray *areas; ///< An area can have any number of subareas
@property (nonatomic, weak) CHChartPDFView *pageView; ///< The PDFView we're residing in
-@property (nonatomic, assign) BOOL active;
- (void)setFromDictionary:(NSDictionary *)dict;
@@ -59,6 +58,9 @@
- (void)resetHighlight;
- (void)positionInFrame:(CGRect)targetRect onView:(NSView *)aView pageSize:(CGSize)pageSize;
+- (CHChartAreaView *)didAddArea:(CHChartArea *)area;
+- (void)didRemoveArea:(CHChartArea *)area;
+
- (CGRect)boundingBox;
- (CGRect)framingBox;
- (CGRect)outlineBox;
@@ -68,9 +70,6 @@
- (NSSet *)allDataTypes;
- (NSSet *)plotDataTypes;
-- (BOOL)makeFirstResponder;
-- (void)didBecomeFirstResponder;
-
- (BOOL)pointInside:(CGPoint)point withEvent:(NSEvent *)event;
- (NSSet *)areasAtPoint:(CGPoint)point;
View
135 growth-charts-helper/CHChartAreaView.m
@@ -28,9 +28,6 @@
@interface CHChartAreaView () {
CGRect inParentRect;
-
- BOOL clickStartedInside;
- BOOL clickDidMove;
}
@end
@@ -186,7 +183,7 @@ - (void)updateWithDataSource:(id<CHChartDataSource>)dataSource
-#pragma mark - Sizing
+#pragma mark - Adding to Views
/**
* This translates our relative position information into an actual frame within the given view.
*
@@ -217,7 +214,58 @@ - (void)positionInFrame:(CGRect)targetRect onView:(NSView *)aView pageSize:(CGSi
}
}
+- (CHChartAreaView *)didAddArea:(CHChartArea *)area
+{
+ if (!area) {
+ return nil;
+ }
+
+ // already have it
+ for (CHChartAreaView *subarea in _areas) {
+ if ([subarea.area isEqual:area]) {
+ return subarea;
+ }
+ }
+
+ // don't have it, make a view and add it to our array
+ CHChartAreaView *areaView = [area viewForParent:self];
+ areaView.pageView = _pageView;
+ if (!_areas) {
+ self.areas = @[areaView];
+ }
+ else {
+ self.areas = [_areas arrayByAddingObject:areaView];
+ }
+
+ [areaView positionInFrame:self.bounds onView:self pageSize:_pageSize];
+ return areaView;
+}
+
+- (void)didRemoveArea:(CHChartArea *)area
+{
+ if ([_areas count] > 0) {
+ NSMutableArray *newAreas = [NSMutableArray arrayWithCapacity:[_areas count] - 1];
+ for (CHChartAreaView *sibling in _areas) {
+ if (sibling.area != area) {
+ [newAreas addObject:sibling];
+ }
+ else {
+ [sibling removeFromSuperview];
+ }
+ }
+ self.areas = ([newAreas count] > 0) ? newAreas : nil;
+ }
+}
+
+
+- (void)didBecomeFirstResponder
+{
+ [_pageView didBecomeFirstResponder:self];
+}
+
+
+#pragma mark - Sizing
/**
* We override setFrame to update the relative frame when moving the box.
*/
@@ -300,52 +348,6 @@ - (CGRect)contentBox
-#pragma mark - First Responder
-- (BOOL)acceptsFirstResponder
-{
- return (clickStartedInside && !clickDidMove);
-}
-
-/**
- * Disregards mouse movements to make the object first responder anyway.
- */
-- (BOOL)makeFirstResponder
-{
- clickStartedInside = YES;
- clickDidMove = NO;
- return [[self window] makeFirstResponder:self];
-}
-
-- (BOOL)becomeFirstResponder
-{
- BOOL done = NO;
- if ([self acceptsFirstResponder]) {
- done = [super becomeFirstResponder];
- _active = done;
- [self setNeedsDisplay:YES];
-
- if (done) {
- [self didBecomeFirstResponder];
- }
- }
- return done;
-}
-
-- (void)didBecomeFirstResponder
-{
- [_pageView didBecomeFirstResponder:self];
-}
-
-- (BOOL)resignFirstResponder
-{
- BOOL done = [super resignFirstResponder];
- _active = done ? NO : _active;
- [self setNeedsDisplay:YES];
- return done;
-}
-
-
-
#pragma mark - Hit Detection
/**
* Collect all areas that are hit by the given point, which is in the coordinate system of our parent (!!)
@@ -398,43 +400,12 @@ - (BOOL)pointInside:(CGPoint)point withEvent:(NSEvent *)event
-#pragma mark - Mouse Handling
-- (void)mouseDown:(NSEvent *)theEvent
-{
- clickStartedInside = YES;
-}
-
-- (void)mouseMoved:(NSEvent *)theEvent
-{
- if (clickStartedInside) {
- clickDidMove = YES;
- }
-}
-
-- (void)mouseDragged:(NSEvent *)theEvent
-{
- if (clickStartedInside) {
- clickDidMove = YES;
- }
-}
-
-- (void)mouseUp:(NSEvent *)theEvent
-{
- if ([self acceptsFirstResponder]) {
- [[self window] makeFirstResponder:self];
- }
- clickStartedInside = NO;
- clickDidMove = NO;
-}
-
-
-
#pragma mark - Drawing
- (void)drawRect:(NSRect)dirtyRect
{
[NSGraphicsContext saveGraphicsState];
- if (_active) {
+ if (self.active) {
[[NSColor colorWithDeviceRed:0.f green:1.f blue:0.f alpha:0.25f] setFill];
}
else {
View
4 growth-charts-helper/CHChartPDFView.h
@@ -23,6 +23,7 @@
#import <Quartz/Quartz.h>
@class CHChart;
+@class CHChartArea;
@class CHChartAreaView;
@@ -37,5 +38,8 @@
- (void)layoutSubviews;
- (void)didBecomeFirstResponder:(CHChartAreaView *)areaView;
+- (CHChartAreaView *)didAddArea:(CHChartArea *)area;
+- (void)didRemoveArea:(CHChartArea *)area;
+
@end
View
74 growth-charts-helper/CHChartPDFView.m
@@ -107,28 +107,66 @@ - (void)layoutSubviews
#pragma mark - Area Handling
+- (void)setActiveArea:(CHChartAreaView *)activeArea
+{
+ if (activeArea != _activeArea) {
+ _activeArea.active = NO;
+ _activeArea = activeArea;
+ _activeArea.active = YES;
+ }
+}
+
- (void)didBecomeFirstResponder:(CHChartAreaView *)areaView
{
- // do not go ahead if an area's superview is active
- CHChartAreaView *superArea = areaView;
- while ((superArea = (CHChartAreaView *)[superArea superview])) {
- if (![superArea isKindOfClass:[CHChartAreaView class]]) {
- break;
- }
- if (superArea.active) {
- return;
- }
+ self.activeArea = areaView;
+
+ // make topmost view
+ CHChartAreaView *topmost = areaView;
+ while ([[topmost superview] isKindOfClass:[CHChartAreaView class]]) {
+ topmost = (CHChartAreaView *)[topmost superview];
}
- // alright, make this the active area
- self.activeArea = areaView;
+ NSView *currentTopmost = [[[topmost superview] subviews] lastObject];
+ if (currentTopmost != topmost) {
+ [topmost removeFromSuperview];
+ [[currentTopmost superview] addSubview:topmost positioned:NSWindowAbove relativeTo:currentTopmost];
+ }
}
-- (void)setActiveArea:(CHChartAreaView *)activeArea
+/**
+ * We only handle top-level areas here.
+ */
+- (CHChartAreaView *)didAddArea:(CHChartArea *)area
{
- if (activeArea != _activeArea) {
- _activeArea = activeArea;
- [_activeArea makeFirstResponder];
+ if (!area || area.parent) {
+ return nil;
+ }
+
+ // place
+ NSView *docView = [self documentView];
+ PDFPage *currentPage = [self.document pageAtIndex:0]; // TODO: support multi-page docs
+ NSSize pageSize = [self rowSizeForPage:currentPage];
+ NSRect pageFrame = NSMakeRect(0.f, 0.f, pageSize.width, pageSize.height);
+ NSSize origSize = [currentPage boundsForBox:[self displayBox]].size;
+
+ CHChartAreaView *areaView = [area viewForParent:self];
+ areaView.pageView = self;
+ [areaView positionInFrame:pageFrame onView:docView pageSize:origSize];
+
+ // first responder and return
+ [areaView makeFirstResponder];
+
+ return areaView;
+}
+
+/**
+ * Removes the given area.
+ */
+- (void)didRemoveArea:(CHChartArea *)area
+{
+ if ([area hasViewForParent:self]) {
+ CHChartAreaView *areaView = [area viewForParent:self];
+ [areaView removeFromSuperview];
}
}
@@ -145,6 +183,12 @@ - (void)setCursorForAreaOfInterest:(PDFAreaOfInterest)area
// [[NSCursor openHandCursor] set];
}
+- (void)mouseDown:(NSEvent *)theEvent
+{
+ self.activeArea = nil;
+ [[self window] makeFirstResponder:self];
+}
+
- (void)scrollWheel:(NSEvent *)event
{
if (event.deltaY < 0.f) {
View
23 growth-charts-helper/CHClickableView.h
@@ -0,0 +1,23 @@
+//
+// CHClickableView.h
+// growth-charts-helper
+//
+// Created by Pascal Pfiffner on 12/22/12.
+// Copyright (c) 2012 CHIP. All rights reserved.
+//
+
+#import <Cocoa/Cocoa.h>
+
+
+/**
+ * A view that can be clicked to become first responder.
+ */
+@interface CHClickableView : NSView
+
+@property (nonatomic, assign) BOOL active;
+
+- (BOOL)makeFirstResponder;
+- (void)didBecomeFirstResponder;
+
+
+@end
View
94 growth-charts-helper/CHClickableView.m
@@ -0,0 +1,94 @@
+//
+// CHClickableView.m
+// growth-charts-helper
+//
+// Created by Pascal Pfiffner on 12/22/12.
+// Copyright (c) 2012 CHIP. All rights reserved.
+//
+
+#import "CHClickableView.h"
+
+
+@interface CHClickableView () {
+ BOOL clickStartedInside;
+ BOOL clickDidMove;
+}
+
+@end
+
+
+@implementation CHClickableView
+
+
+#pragma mark - Active and First Responder
+- (void)setActive:(BOOL)active
+{
+ if (active != _active) {
+ _active = active;
+ [self setNeedsDisplay:YES];
+ }
+}
+
+- (BOOL)acceptsFirstResponder
+{
+ return (clickStartedInside && !clickDidMove);
+}
+
+/**
+ * Disregards mouse movements to make the object first responder anyway.
+ */
+- (BOOL)makeFirstResponder
+{
+ clickStartedInside = YES;
+ clickDidMove = NO;
+ return [[self window] makeFirstResponder:self];
+}
+
+- (BOOL)becomeFirstResponder
+{
+ if ([self acceptsFirstResponder]) {
+ if ([super becomeFirstResponder]) {
+ [self didBecomeFirstResponder];
+ return YES;
+ }
+ }
+ return NO;
+}
+
+- (void)didBecomeFirstResponder
+{
+}
+
+
+
+#pragma mark - Mouse Handling
+- (void)mouseDown:(NSEvent *)theEvent
+{
+ clickStartedInside = YES;
+}
+
+- (void)mouseMoved:(NSEvent *)theEvent
+{
+ if (clickStartedInside) {
+ clickDidMove = YES;
+ }
+}
+
+- (void)mouseDragged:(NSEvent *)theEvent
+{
+ if (clickStartedInside) {
+ clickDidMove = YES;
+ }
+}
+
+- (void)mouseUp:(NSEvent *)theEvent
+{
+ if ([self acceptsFirstResponder]) {
+ [[self window] makeFirstResponder:self];
+ }
+ clickStartedInside = NO;
+ clickDidMove = NO;
+}
+
+
+@end
View
2 growth-charts-helper/CHDocument.m
@@ -17,7 +17,7 @@ @implementation CHDocument
- (id)init
{
if ((self = [super init])) {
- // Add your subclass-specific initialization here.
+ self.hasUndoManager = YES;
}
return self;
}
View
8 growth-charts-helper/CHResizableChartAreaView.m
@@ -199,12 +199,4 @@ - (void)mouseExited:(NSEvent *)theEvent
}
-
-#pragma mark - First Responder
-- (void)didBecomeFirstResponder
-{
- [super didBecomeFirstResponder];
-}
-
-
@end
View
2 growth-charts-helper/CHWindowController.h
@@ -48,6 +48,8 @@
- (void)loadPDFAt:(NSURL *)url;
- (IBAction)handleFoundPDF:(id)sender;
- (void)unloadPDF:(id)sender;
+- (IBAction)addArea:(id)sender;
+- (IBAction)removeArea:(id)sender;
@end
View
35 growth-charts-helper/CHWindowController.m
@@ -63,6 +63,11 @@ - (void)awakeFromNib
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didDropFiles:) name:CHDropViewDroppedItemsNotificationName object:nil];
}
+- (NSUndoManager *)undoManager
+{
+ return [self pdfDocument].undoManager;
+}
+
- (void)didDropFiles:(NSNotification *)notification
{
NSArray *items = [[notification userInfo] objectForKey:CHDropViewDroppedItemsKey];
@@ -187,6 +192,12 @@ - (CHChart *)chart
return [self pdfDocument].chart;
}
+
+
+#pragma mark - Area Handling
+/**
+ * We are observing _pdf.activeArea, so whenever that one changes we will also enter this method.
+ */
- (void)setActiveArea:(CHChartArea *)activeArea
{
if (activeArea != _activeArea) {
@@ -204,6 +215,30 @@ - (void)changeActiveArea:(NSButton *)sender
}
}
+- (IBAction)addArea:(id)sender
+{
+ CHChartArea *newArea = [[self chart] newAreaInParentArea:_activeArea];
+ [_pdf didAddArea:newArea]; // we need to message this to the PDF View, sub-areas will auto-message their parent views (if there are any)
+
+ // make undoable
+ [self.undoManager registerUndoWithTarget:[self chart] selector:@selector(removeArea:) object:newArea];
+}
+
+- (IBAction)removeArea:(id)sender
+{
+ if (!_activeArea) {
+ return;
+ }
+
+ // make undoable
+ [self.undoManager registerUndoWithTarget:[self chart] selector:@selector(addArea:) object:_activeArea];
+
+ // remove
+ CHChartArea *currArea = _activeArea;
+ [[self chart] removeArea:currArea];
+ [_pdf didRemoveArea:currArea];
+}
+
#pragma mark - Key-Value Observing
View
5 growth-charts-helper/FromCharts/CHChart.h
@@ -11,6 +11,7 @@
#import "CHJSONHandling.h"
@class CHChart;
+@class CHChartArea;
@class CHValue;
@class PPRange;
@@ -64,7 +65,11 @@
+ (NSArray *)bundledCharts;
- (NSURL *)resourceURL;
+
- (NSUInteger)numAreas;
+- (CHChartArea *)newAreaInParentArea:(CHChartArea *)parent;
+- (void)addArea:(CHChartArea *)area;
+- (void)removeArea:(CHChartArea *)area;
@end
View
54 growth-charts-helper/FromCharts/CHChart.m
@@ -159,7 +159,10 @@ - (id)jsonObject
// add our areas
if ([_chartAreas count] > 0) {
NSMutableArray *areas = [NSMutableArray arrayWithCapacity:[_chartAreas count]];
- for (CHChartArea *area in _chartAreas) {
+
+ // we sort the area set so that versioned JSON files look the same as much as possible
+ NSSortDescriptor *rectSorter = [NSSortDescriptor sortDescriptorWithKey:@"frameString" ascending:NO];
+ for (CHChartArea *area in [_chartAreas sortedArrayUsingDescriptors:@[rectSorter]]) {
id obj = [area jsonObject];
if (obj) {
[areas addObject:obj];
@@ -197,6 +200,55 @@ - (NSUInteger)numAreas
return [_chartAreas count];
}
+- (CHChartArea *)newAreaInParentArea:(CHChartArea *)parent
+{
+ CHChartArea *newArea = [CHChartArea new];
+ newArea.chart = self;
+ newArea.parent = parent;
+ newArea.frame = CGRectMake(0.25f, 0.25f, 0.5f, 0.5f);
+ newArea.type = @"text";
+
+ [self addArea:newArea];
+ return newArea;
+}
+
+- (void)addArea:(CHChartArea *)area
+{
+ // it's a subarea
+ if (area.parent) {
+ [area.parent addArea:area];
+ }
+
+ // root area
+ else {
+ area.topmost = YES;
+ if (_chartAreas) {
+ self.chartAreas = [_chartAreas setByAddingObject:area];
+ }
+ else {
+ self.chartAreas = [NSSet setWithObject:area];
+ }
+ }
+}
+
+- (void)removeArea:(CHChartArea *)area
+{
+ BOOL hadParent = (nil != area.parent);
+
+ [area remove];
+
+ // root area, update area set
+ if (!hadParent) {
+ NSMutableSet *newAreas = [NSMutableSet setWithCapacity:[_chartAreas count] - 1];
+ for (CHChartArea *subarea in _chartAreas) {
+ if (area != subarea) {
+ [newAreas addObject:subarea];
+ }
+ }
+ self.chartAreas = newAreas;
+ }
+}
+
#pragma mark - Utilities
View
7 growth-charts-helper/FromCharts/CHChartArea.h
@@ -33,6 +33,7 @@
@interface CHChartArea : NSObject <CHJSONHandling>
@property (nonatomic, weak) CHChart *chart; ///< The chart to which we belong
+@property (nonatomic, weak) CHChartArea *parent; ///< Our parent area (if any)
@property (nonatomic, copy) NSString *type; ///< The type of the area
@property (nonatomic, copy) NSArray *outlinePoints; ///< An array of CGPoints (in NSValues) that define the path for our outline
@property (nonatomic, copy) NSDictionary *dictionary; ///< The dictionary representation defining the receiver, kept around to spawn the view objects
@@ -62,8 +63,14 @@
@property (nonatomic, assign) BOOL topmost; ///< YES if this area lies directly on the PDF, i.e. not nested in another area
@property (nonatomic, copy) NSArray *areas; ///< An area can have any number of subareas
+- (NSString *)frameString;
+
+- (BOOL)hasViewForParent:(id)parentView;
- (CHChartAreaView *)viewForParent:(id)parentView;
+- (void)addArea:(CHChartArea *)newArea;
+- (void)remove;
+
+ (NSCharacterSet *)outlinePathSplitSet;
View
83 growth-charts-helper/FromCharts/CHChartArea.m
@@ -46,6 +46,21 @@ + (id)newFromJSONObject:(id)object
}
+- (void)setChart:(CHChart *)chart
+{
+ if (chart != _chart) {
+ _chart = chart;
+
+ // update sub-areas
+ for (CHChartArea *subarea in _areas) {
+ subarea.chart = _chart;
+ }
+ }
+}
+
+
+
+#pragma mark - JSON Handling
/**
* Fill from a dictionary passed in from decoding JSON.
*/
@@ -170,6 +185,7 @@ - (BOOL)setFromJSONObject:(id)object
CHChartArea *area = [CHChartArea newFromJSONObject:areaDict];
if (area) {
area.chart = _chart;
+ area.parent = self;
area.topmost = NO;
area.page = self.page;
[myAreas addObject:area];
@@ -189,6 +205,7 @@ - (BOOL)setFromJSONObject:(id)object
return YES;
}
+
- (id)jsonObject
{
if ([_type length] < 1) {
@@ -201,7 +218,7 @@ - (id)jsonObject
if (_topmost && _page > 0) {
[dict setObject:[NSNumber numberWithUnsignedInteger:_page] forKey:@"page"];
}
- [dict setObject:NSStringFromCGRect(_frame) forKey:@"rect"];
+ [dict setObject:[self frameString] forKey:@"rect"];
// the outline
if ([_outlinePoints count] > 2) {
@@ -267,18 +284,58 @@ - (id)jsonObject
return dict;
}
+- (NSString *)frameString
+{
+ return NSStringFromCGRect(_frame);
+}
-#pragma mark - KVC
-- (void)setChart:(CHChart *)chart
+
+#pragma mark - Subareas
+- (void)addArea:(CHChartArea *)newArea
{
- if (chart != _chart) {
- _chart = chart;
-
- // update sub-areas
- for (CHChartArea *subarea in _areas) {
- subarea.chart = _chart;
+ // assimilate
+ newArea.chart = _chart;
+ newArea.parent = self;
+ newArea.topmost = NO;
+ newArea.page = self.page;
+
+ // add to array
+ if (!_areas) {
+ self.areas = @[newArea];
+ }
+ else {
+ self.areas = [_areas arrayByAddingObject:newArea];
+ }
+
+ // tell our views
+ for (id forView in _knownViews) {
+ CHChartAreaView *myView = [_knownViews objectForKey:forView];
+ CHChartAreaView *newView = [myView didAddArea:newArea];
+ if ([[newView window] isKeyWindow]) {
+ [newView makeFirstResponder];
+ }
+ }
+}
+
+- (void)remove
+{
+ // remove our views
+ for (id forView in _knownViews) {
+ if ([forView respondsToSelector:@selector(didRemoveArea:)]) {
+ [forView performSelector:@selector(didRemoveArea:) withObject:self];
+ }
+ }
+
+ // tell our parent to forget about us
+ if (_parent) {
+ NSMutableArray *newAreas = [NSMutableArray arrayWithCapacity:[_parent.areas count] - 1];
+ for (CHChartArea *sibling in _parent.areas) {
+ if (sibling != self) {
+ [newAreas addObject:sibling];
+ }
}
+ _parent.areas = ([newAreas count] > 0) ? newAreas : nil;
}
}
@@ -287,6 +344,14 @@ - (void)setChart:(CHChart *)chart
#pragma mark - Returning the View
/**
+ * Returns whether we hold a reference to a view in the given parent view.
+ */
+- (BOOL)hasViewForParent:(id)parentView
+{
+ return (nil != [_knownViews objectForKey:parentView]);
+}
+
+/**
* Returns a CHChartAreaView instance, newly created if not previously done for the parentView, from the properties of the receiver (including sub-areas).
*/
- (CHChartAreaView *)viewForParent:(id)parentView
View
108 growth-charts-helper/en.lproj/CHDocument.xib
@@ -3,12 +3,12 @@
<data>
<int key="IBDocument.SystemTarget">1070</int>
<string key="IBDocument.SystemVersion">12C60</string>
- <string key="IBDocument.InterfaceBuilderVersion">2840</string>
+ <string key="IBDocument.InterfaceBuilderVersion">2844</string>
<string key="IBDocument.AppKitVersion">1187.34</string>
<string key="IBDocument.HIToolboxVersion">625.00</string>
<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin</string>
- <string key="NS.object.0">2840</string>
+ <string key="NS.object.0">2844</string>
</object>
<array key="IBDocument.IntegratedClassDependencies">
<string>NSBox</string>
@@ -172,13 +172,13 @@
<int key="NSvFlags">18</int>
<string key="NSFrame">{{13, 10}, {374, 868}}</string>
<reference key="NSSuperview" ref="923488404"/>
- <reference key="NSNextKeyView" ref="94279693"/>
+ <reference key="NSNextKeyView" ref="355261897"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<array class="NSMutableArray" key="NSTabViewItems">
<object class="NSTabViewItem" id="791241501">
<string key="NSIdentifier">1</string>
<object class="NSView" key="NSView" id="94279693">
- <reference key="NSNextResponder" ref="632799389"/>
+ <nil key="NSNextResponder"/>
<int key="NSvFlags">256</int>
<array class="NSMutableArray" key="NSSubviews">
<object class="NSTextField" id="792253015">
@@ -540,7 +540,6 @@
<int key="NSvFlags">269</int>
<string key="NSFrame">{{121, 297}, {113, 32}}</string>
<reference key="NSSuperview" ref="94279693"/>
- <reference key="NSNextKeyView"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<bool key="NSEnabled">YES</bool>
<object class="NSButtonCell" key="NSCell" id="618169760">
@@ -561,7 +560,6 @@
</object>
</array>
<string key="NSFrame">{{10, 33}, {354, 822}}</string>
- <reference key="NSSuperview" ref="632799389"/>
<reference key="NSNextKeyView" ref="973488353"/>
<string key="NSReuseIdentifierKey">_NS:11</string>
</object>
@@ -572,15 +570,15 @@
<object class="NSTabViewItem" id="485818091">
<string key="NSIdentifier">2</string>
<object class="NSView" key="NSView" id="355261897">
- <nil key="NSNextResponder"/>
+ <reference key="NSNextResponder" ref="632799389"/>
<int key="NSvFlags">256</int>
<array class="NSMutableArray" key="NSSubviews">
<object class="NSButton" id="1022353586">
<reference key="NSNextResponder" ref="355261897"/>
- <int key="NSvFlags">268</int>
- <string key="NSFrame">{{128, 781}, {99, 32}}</string>
+ <int key="NSvFlags">269</int>
+ <string key="NSFrame">{{82, 776}, {99, 32}}</string>
<reference key="NSSuperview" ref="355261897"/>
- <reference key="NSNextKeyView" ref="967152815"/>
+ <reference key="NSNextKeyView" ref="1017797045"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<bool key="NSEnabled">YES</bool>
<object class="NSButtonCell" key="NSCell" id="108380117">
@@ -726,6 +724,7 @@
<int key="NSvFlags">10</int>
<string key="NSFrame">{{10, 311}, {334, 317}}</string>
<reference key="NSSuperview" ref="355261897"/>
+ <reference key="NSNextKeyView" ref="155982036"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<array class="NSMutableArray" key="NSTabViewItems">
<object class="NSTabViewItem" id="762433259">
@@ -1053,7 +1052,6 @@
<int key="NSvFlags">266</int>
<string key="NSFrame">{{57, 23}, {225, 22}}</string>
<reference key="NSSuperview" ref="242935908"/>
- <reference key="NSNextKeyView" ref="27707940"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<bool key="NSEnabled">YES</bool>
<object class="NSTextFieldCell" key="NSCell" id="580936543">
@@ -1445,6 +1443,7 @@
<int key="NSvFlags">274</int>
<string key="NSFrame">{{1, 1}, {324, 97}}</string>
<reference key="NSSuperview" ref="27707940"/>
+ <reference key="NSNextKeyView"/>
<string key="NSReuseIdentifierKey">_NS:11</string>
</object>
</array>
@@ -1574,8 +1573,33 @@
</object>
<bool key="NSAllowsLogicalLayoutDirection">NO</bool>
</object>
+ <object class="NSButton" id="1017797045">
+ <reference key="NSNextResponder" ref="355261897"/>
+ <int key="NSvFlags">269</int>
+ <string key="NSFrame">{{181, 776}, {90, 32}}</string>
+ <reference key="NSSuperview" ref="355261897"/>
+ <reference key="NSNextKeyView" ref="967152815"/>
+ <string key="NSReuseIdentifierKey">_NS:9</string>
+ <bool key="NSEnabled">YES</bool>
+ <object class="NSButtonCell" key="NSCell" id="43549578">
+ <int key="NSCellFlags">67108864</int>
+ <int key="NSCellFlags2">134217728</int>
+ <string key="NSContents">Remove</string>
+ <reference key="NSSupport" ref="653464429"/>
+ <string key="NSCellIdentifier">_NS:9</string>
+ <reference key="NSControlView" ref="1017797045"/>
+ <int key="NSButtonFlags">-2038284288</int>
+ <int key="NSButtonFlags2">129</int>
+ <string key="NSAlternateContents"/>
+ <string key="NSKeyEquivalent"/>
+ <int key="NSPeriodicDelay">200</int>
+ <int key="NSPeriodicInterval">25</int>
+ </object>
+ <bool key="NSAllowsLogicalLayoutDirection">NO</bool>
+ </object>
</array>
<string key="NSFrame">{{10, 33}, {354, 822}}</string>
+ <reference key="NSSuperview" ref="632799389"/>
<reference key="NSNextKeyView" ref="1022353586"/>
<string key="NSReuseIdentifierKey">_NS:28</string>
</object>
@@ -1584,13 +1608,13 @@
<reference key="NSTabView" ref="632799389"/>
</object>
</array>
- <reference key="NSSelectedTabViewItem" ref="791241501"/>
+ <reference key="NSSelectedTabViewItem" ref="485818091"/>
<reference key="NSFont" ref="653464429"/>
<int key="NSTvFlags">0</int>
<bool key="NSAllowTruncatedLabels">YES</bool>
<bool key="NSDrawsBackground">YES</bool>
<array class="NSMutableArray" key="NSSubviews">
- <reference ref="94279693"/>
+ <reference ref="355261897"/>
</array>
</object>
</array>
@@ -1613,7 +1637,7 @@
<reference key="NSSuperview"/>
<reference key="NSNextKeyView" ref="586073561"/>
</object>
- <string key="NSScreenRect">{{0, 0}, {2560, 1418}}</string>
+ <string key="NSScreenRect">{{0, 0}, {1440, 900}}</string>
<string key="NSMinSize">{800, 622}</string>
<string key="NSMaxSize">{10000000000000, 10000000000000}</string>
<bool key="NSWindowIsRestorable">YES</bool>
@@ -1700,6 +1724,22 @@
<int key="connectionID">100406</int>
</object>
<object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">addArea:</string>
+ <reference key="source" ref="512844837"/>
+ <reference key="destination" ref="1022353586"/>
+ </object>
+ <int key="connectionID">100407</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">removeArea:</string>
+ <reference key="source" ref="512844837"/>
+ <reference key="destination" ref="1017797045"/>
+ </object>
+ <int key="connectionID">100414</int>
+ </object>
+ <object class="IBConnectionRecord">
<object class="IBOutletConnection" key="connection">
<string key="label">delegate</string>
<reference key="source" ref="275939982"/>
@@ -2227,6 +2267,26 @@
</object>
<int key="connectionID">100395</int>
</object>
+ <object class="IBConnectionRecord">
+ <object class="IBBindingConnection" key="connection">
+ <string key="label">enabled: activeArea</string>
+ <reference key="source" ref="1017797045"/>
+ <reference key="destination" ref="512844837"/>
+ <object class="NSNibBindingConnector" key="connector">
+ <reference key="NSSource" ref="1017797045"/>
+ <reference key="NSDestination" ref="512844837"/>
+ <string key="NSLabel">enabled: activeArea</string>
+ <string key="NSBinding">enabled</string>
+ <string key="NSKeyPath">activeArea</string>
+ <object class="NSDictionary" key="NSOptions">
+ <string key="NS.key.0">NSValueTransformerName</string>
+ <string key="NS.object.0">NSIsNotNil</string>
+ </object>
+ <int key="NSNibBindingConnectorVersion">2</int>
+ </object>
+ </object>
+ <int key="connectionID">100413</int>
+ </object>
</array>
<object class="IBMutableOrderedSet" key="objectRecords">
<array key="orderedObjects">
@@ -2346,7 +2406,6 @@
<int key="objectID">100057</int>
<reference key="object" ref="355261897"/>
<array class="NSMutableArray" key="children">
- <reference ref="1022353586"/>
<reference ref="517149107"/>
<reference ref="484127948"/>
<reference ref="123121636"/>
@@ -2361,6 +2420,8 @@
<reference ref="83093504"/>
<reference ref="1068465578"/>
<reference ref="1053478417"/>
+ <reference ref="1022353586"/>
+ <reference ref="1017797045"/>
</array>
<reference key="parent" ref="485818091"/>
</object>
@@ -3228,6 +3289,19 @@
<reference key="object" ref="618169760"/>
<reference key="parent" ref="332538316"/>
</object>
+ <object class="IBObjectRecord">
+ <int key="objectID">100408</int>
+ <reference key="object" ref="1017797045"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="43549578"/>
+ </array>
+ <reference key="parent" ref="355261897"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">100409</int>
+ <reference key="object" ref="43549578"/>
+ <reference key="parent" ref="1017797045"/>
+ </object>
</array>
</object>
<dictionary class="NSMutableDictionary" key="flattenedProperties">
@@ -3372,6 +3446,8 @@
<string key="100400.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="100401.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="100402.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="100408.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="100409.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<boolean value="YES" key="5.IBNSWindowAutoPositionCentersHorizontal"/>
<boolean value="NO" key="5.IBNSWindowAutoPositionCentersVertical"/>
<string key="5.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
@@ -3382,7 +3458,7 @@
<nil key="activeLocalization"/>
<dictionary class="NSMutableDictionary" key="localizations"/>
<nil key="sourceID"/>
- <int key="maxID">100406</int>
+ <int key="maxID">100414</int>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes"/>
<int key="IBDocument.localizationMode">0</int>

0 comments on commit a6a8bb2

Please sign in to comment.