Browse files

Hook up interface to currently selected area

  • Loading branch information...
1 parent 504439f commit 469aa6d46613900df65486c9f4d64a36ce0f926c @p2 committed Dec 19, 2012
View
20 growth-charts-helper.xcodeproj/project.pbxproj
@@ -7,6 +7,9 @@
objects = {
/* Begin PBXBuildFile section */
+ 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 */; };
EEEB2D761680E014004DC719 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EEEB2D751680E014004DC719 /* Cocoa.framework */; };
EEEB2D801680E014004DC719 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = EEEB2D7E1680E014004DC719 /* InfoPlist.strings */; };
EEEB2D821680E014004DC719 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = EEEB2D811680E014004DC719 /* main.m */; };
@@ -31,6 +34,12 @@
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
+ 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>"; };
+ EEAECC1616816B7800E8ABE1 /* CHFloatToStringTransformer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CHFloatToStringTransformer.m; sourceTree = "<group>"; };
+ EEAECC1816816C4500E8ABE1 /* CHDecimalNumberToStringTransformer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CHDecimalNumberToStringTransformer.h; sourceTree = "<group>"; };
+ EEAECC1916816C4500E8ABE1 /* CHDecimalNumberToStringTransformer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CHDecimalNumberToStringTransformer.m; sourceTree = "<group>"; };
EEEB2D711680E014004DC719 /* growth-charts-helper.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "growth-charts-helper.app"; sourceTree = BUILT_PRODUCTS_DIR; };
EEEB2D751680E014004DC719 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
EEEB2D781680E014004DC719 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; };
@@ -132,9 +141,9 @@
children = (
EEEB2D871680E014004DC719 /* CHDocument.h */,
EEEB2D881680E014004DC719 /* CHDocument.m */,
+ EEEB2D8A1680E014004DC719 /* CHDocument.xib */,
EEEB2DD71680FA95004DC719 /* CHWindowController.h */,
EEEB2DD81680FA95004DC719 /* CHWindowController.m */,
- EEEB2D8A1680E014004DC719 /* CHDocument.xib */,
EEEB2DDE16810422004DC719 /* CHChartPDFView.h */,
EEEB2DDF16810422004DC719 /* CHChartPDFView.m */,
EEEB2DD21680EE70004DC719 /* CHChartAreaView.h */,
@@ -189,6 +198,12 @@
EEEB2DE41681075A004DC719 /* CHDropView.m */,
EEEB2DDA1680FFC7004DC719 /* CHEnumToNumberTransformer.h */,
EEEB2DDB1680FFC7004DC719 /* CHEnumToNumberTransformer.m */,
+ EEAECC1516816B7800E8ABE1 /* CHFloatToStringTransformer.h */,
+ EEAECC1616816B7800E8ABE1 /* CHFloatToStringTransformer.m */,
+ EEAECC1816816C4500E8ABE1 /* CHDecimalNumberToStringTransformer.h */,
+ EEAECC1916816C4500E8ABE1 /* CHDecimalNumberToStringTransformer.m */,
+ EEAECBFC16815E2F00E8ABE1 /* CHRectToStringTransformer.h */,
+ EEAECBFD16815E2F00E8ABE1 /* CHRectToStringTransformer.m */,
);
name = Helpers;
sourceTree = "<group>";
@@ -273,6 +288,9 @@
EEEB2DDC1680FFC7004DC719 /* CHEnumToNumberTransformer.m in Sources */,
EEEB2DE016810423004DC719 /* CHChartPDFView.m in Sources */,
EEEB2DE51681075A004DC719 /* CHDropView.m in Sources */,
+ EEAECBFE16815E2F00E8ABE1 /* CHRectToStringTransformer.m in Sources */,
+ EEAECC1716816B7800E8ABE1 /* CHFloatToStringTransformer.m in Sources */,
+ EEAECC1A16816C4500E8ABE1 /* CHDecimalNumberToStringTransformer.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
View
10 growth-charts-helper/CHChartAreaView.h
@@ -24,7 +24,9 @@
#import <QuartzCore/QuartzCore.h>
#import "CHChart.h"
-#define kCHChartAreaViewDebugDrawing 0
+@class CHChartArea;
+@class CHChartPDFView;
+
/**
* A chart area represents an area on a PDF file to draw content into.
@@ -39,13 +41,18 @@
*/
@interface CHChartAreaView : NSView
+@property (nonatomic, weak) CHChartArea *area; ///< The area model that describes the receiver
+
@property (nonatomic, assign) CGPoint origin; ///< Origin between 0 and 1 relative to its parent's grid
@property (nonatomic, assign) CGSize size; ///< Size between 0 and 1 relative to its parent's grid
@property (nonatomic, assign) CGPathRef outline; ///< The outline of the area. We do *not* clip to this area, but you can use it to do so.
@property (nonatomic, assign) CGSize pageSize; ///< The size of the page we're currently displayed on, in screen pixels
@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;
- (void)reset;
@@ -64,7 +71,6 @@
- (BOOL)pointInside:(CGPoint)point withEvent:(NSEvent *)event;
- (NSSet *)areasAtPoint:(CGPoint)point;
-+ (BOOL)registerClass:(Class)areaClass forType:(NSString *)aType;
+ (Class)registeredClassForType:(NSString *)aType;
+ (NSCharacterSet *)outlinePathSplitSet;
View
124 growth-charts-helper/CHChartAreaView.m
@@ -21,6 +21,8 @@
*/
#import "CHChartAreaView.h"
+#import "CHChartArea.h"
+#import "CHChartPDFView.h"
@interface CHChartAreaView ()
@@ -54,23 +56,24 @@ - (id)initWithFrame:(CGRect)frame
}
+- (void)setArea:(CHChartArea *)area
+{
+ if (area != _area) {
+ _area = area;
+
+ // set some properties
+ self.origin = area.frame.origin;
+ self.size = area.frame.size;
+ }
+}
+
+
/**
* The chart area model keeps a dictionary around, subclasses of the view can override this method to receive more properties for its configuration.
* Don't forget to call super, the base implementation assigns origin and size!
*/
- (void)setFromDictionary:(NSDictionary *)dict
{
- // rect to origin and size
- NSString *rectString = [dict objectForKey:@"rect"];
- if ([rectString isKindOfClass:[NSString class]]) {
- NSRect rect = NSRectFromString(rectString);
- self.origin = rect.origin;
- self.size = rect.size;
- }
- else if (rectString) {
- DLog(@"\"rect\" must be a NSString, but I got a %@, discarding", NSStringFromClass([rectString class]));
- }
-
// outline path
NSString *outlineString = [dict objectForKey:@"outline"];
if ([outlineString isKindOfClass:[NSString class]]) {
@@ -199,28 +202,11 @@ - (void)positionInFrame:(CGRect)targetRect onView:(NSView *)aView pageSize:(CGSi
// position subareas
for (CHChartAreaView *area in _areas) {
+ area.pageView = _pageView;
[area positionInFrame:self.bounds onView:self pageSize:pageSize];
}
}
-
-/**
- * Overridden so we can adjust our tile size if needed
- */
-- (void)setFrame:(CGRect)aFrame
-{
- // re-cache all data points if the frame SIZE changed
- if (!CGSizeEqualToSize(aFrame.size, [self frame].size)) {
- CGFloat screenScale = 1.f; //[[UIScreen mainScreen] scale];
- CGFloat max = fmaxf(aFrame.size.width * screenScale, aFrame.size.height * screenScale);
- CGFloat tileWidth = ((max < 512.f) ? 512.f : 1024.f);
-
- ((CATiledLayer *)self.layer).tileSize = CGSizeMake(tileWidth, tileWidth);
- //[self setNeedsDisplay];
- }
- [super setFrame:aFrame];
-}
-
/**
* The rect in our own coordinate system describing the area needed to cover all our subviews.
*
@@ -286,32 +272,28 @@ - (CGRect)contentBox
#pragma mark - Drawing
-- (void)drawRect:(NSRect)dirtyRect
+- (void)setActive:(BOOL)flag
{
- [[NSColor colorWithDeviceRed:1.f green:0.f blue:0.f alpha:0.25f] setFill];
- [NSBezierPath fillRect:self.bounds];
+ if (flag != _active) {
+ _active = flag;
+ [self setNeedsDisplay:YES];
+ }
}
-/**
- * This is the drawing method we use, "drawRect:" is the wrong one if you intend to create subclasses!
- */
-- (void)drawLayer:(CATiledLayer *)aLayer inContext:(CGContextRef)ctx
+
+- (void)drawRect:(NSRect)dirtyRect
{
- CGRect clip = CGContextGetClipBoundingBox(ctx);
+ [NSGraphicsContext saveGraphicsState];
- // fill background area
- CGContextSaveGState(ctx);
-// CGContextSetFillColorWithColor(ctx, [self.backgroundColor CGColor]);
- CGContextFillRect(ctx, CGRectIntersection(clip, self.bounds));
- CGContextRestoreGState(ctx);
+ if (_active) {
+ [[NSColor colorWithDeviceRed:0.f green:1.f blue:0.f alpha:0.25f] setFill];
+ }
+ else {
+ [[NSColor colorWithDeviceRed:0.f green:0.f blue:1.f alpha:0.25f] setFill];
+ }
- // debug: fill bounding box
-#if kCHChartAreaViewDebugDrawing
- CGContextSaveGState(ctx);
- CGContextSetFillColorWithColor(ctx, [[[UIColor greenColor] colorWithAlphaComponent:0.25f] CGColor]);
- CGContextFillRect(ctx, CGRectIntersection(clip, [self boundingBox]));
- CGContextRestoreGState(ctx);
-#endif
+ [NSBezierPath fillRect:self.bounds];
+ [NSGraphicsContext restoreGraphicsState];
}
@@ -367,42 +349,26 @@ - (BOOL)pointInside:(CGPoint)point withEvent:(NSEvent *)event
}
-
-#pragma mark - Class Registration
-/**
- * You MUST include this in subclasses if you want your subclass to automatically be used for specific area types
- */
-+ (void)load
+- (void)mouseDown:(NSEvent *)theEvent
{
- [CHChartAreaView registerClass:self forType:nil];
+ //DLog(@"%@ -- %@", self, theEvent);
}
-
-static NSMutableDictionary *registeredAreaClasses = nil;
-
-/**
- * Registeres the given class to represent areas of given type
- * @return A bool indicating whether the class was successfully registered
- */
-+ (BOOL)registerClass:(Class)areaClass forType:(NSString *)aType
+- (void)mouseDragged:(NSEvent *)theEvent
{
- if ([aType length] < 1) {
- return NO;
- }
-
- // got a type, register if no type is yet registered for that
- if (!registeredAreaClasses) {
- registeredAreaClasses = [NSMutableDictionary new];
- }
- else if ([registeredAreaClasses objectForKey:aType]) {
- DLog(@"The class \"%@\" already registered for type \"%@\"", NSStringFromClass([registeredAreaClasses objectForKey:aType]), aType);
- return NO;
+ if (_active) {
+
}
-
- [registeredAreaClasses setObject:areaClass forKey:aType];
- return YES;
}
+- (void)mouseUp:(NSEvent *)theEvent
+{
+ [_pageView didGetClicked:self];
+}
+
+
+
+#pragma mark - Class Registration
+ (Class)registeredClassForType:(NSString *)aType
{
return self;
@@ -434,7 +400,7 @@ + (NSCharacterSet *)outlinePathSplitSet
#pragma mark - Utilities
- (NSString *)description
{
- return [NSString stringWithFormat:@"%@ <%p> {%@,%@}, %d sub-areas", NSStringFromClass([self class]), self, NSStringFromCGPoint(_origin), NSStringFromCGSize(_size), [_areas count]];
+ return [NSString stringWithFormat:@"%@ <%p> {%@,%@}, %d sub-areas", NSStringFromClass([self class]), self, NSStringFromCGPoint(_origin), NSStringFromCGSize(_size), (int)[_areas count]];
}
View
4 growth-charts-helper/CHChartPDFView.h
@@ -23,6 +23,7 @@
#import <Quartz/Quartz.h>
@class CHChart;
+@class CHChartAreaView;
/**
@@ -31,8 +32,11 @@
@interface CHChartPDFView : PDFView
@property (nonatomic, strong) CHChart *chart;
+@property (nonatomic, strong) CHChartAreaView *activeArea;
- (void)layoutSubviews;
+- (void)didGetClicked:(CHChartAreaView *)areaView;
+
@end
View
71 growth-charts-helper/CHChartPDFView.m
@@ -54,8 +54,8 @@ - (void)drawPagePost:(PDFPage *)page
NSUInteger pageNum = [self.document indexForPage:page] + 1;
NSSize pageSize = [self rowSizeForPage:page];
- //NSRect pageBounds = [page boundsForBox:[self displayBox]]; // kPDFDisplayBoxCropBox is our default display mode, not kPDFDisplayBoxMediaBox
NSRect pageFrame = NSMakeRect(0.f, 0.f, pageSize.width, pageSize.height);
+ NSSize origSize = [page boundsForBox:[self displayBox]].size; // kPDFDisplayBoxCropBox is our default display mode, not kPDFDisplayBoxMediaBox
// remove old areas
if ([_addedAreas count] > 0) {
@@ -73,7 +73,8 @@ - (void)drawPagePost:(PDFPage *)page
for (CHChartArea *area in areas) {
if (pageNum == area.page) {
CHChartAreaView *areaView = [area view];
- [areaView positionInFrame:pageFrame onView:docView pageSize:docView.bounds.size];
+ areaView.pageView = self;
+ [areaView positionInFrame:pageFrame onView:docView pageSize:origSize];
[_addedAreas addObject:areaView];
}
@@ -118,58 +119,32 @@ - (void)layoutSubviews
}
-/**
- * We need this to override PDFView subviews intercepting our mouse events.
- */
-- (NSView *)hitTest:(NSPoint)aPoint
-{
- /*/
- for (NSView *view in [self subviews]) {
- DLog(@"-> %@", view);
- for (NSView *view2 in [view subviews]) {
- DLog(@"--> %@", view2);
- for (NSView *view3 in [view2 subviews]) {
- DLog(@"---> %@", view3);
- for (NSView *view4 in [view3 subviews]) {
- DLog(@"----> %@", view4);
- if ([view4 isKindOfClass:NSClassFromString(@"PDFDisplayView")]) {
- CGPoint inPoint = [view4 convertPoint:aPoint fromView:self];
- if (NSPointInRect(inPoint, view4.bounds)) {
- return self;
- }
- }
- }
- }
- }
- } //*/
- return [super hitTest:aPoint];
-}
-
-
-#pragma mark - Mouse Clicks and Drags
-- (void)mouseDown:(NSEvent *)theEvent
+#pragma mark - Area Handling
+- (void)didGetClicked:(CHChartAreaView *)areaView
{
- // mouseInCloseBox and trackingCloseBoxHit are instance variables
- if (NSPointInRect([self convertPoint:[theEvent locationInWindow] fromView:nil], NSZeroRect)) {
- }
- else if ([theEvent clickCount] > 1) {
- [[self window] miniaturize:self];
- return;
- }
-}
-
-- (void)mouseDragged:(NSEvent *)theEvent
-{
- //NSPoint windowOrigin;
- //NSWindow *window = [self window];
+ // 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 convertPoint:[theEvent locationInWindow] fromView:nil]
+ // alright, make this the active area
+ self.activeArea = areaView;
}
-- (void)mouseUp:(NSEvent *)theEvent
+- (void)setActiveArea:(CHChartAreaView *)activeArea
{
-
+ if (activeArea != _activeArea) {
+ _activeArea.active = NO;
+ _activeArea = activeArea;
+ _activeArea.active = YES;
+ }
}
View
31 growth-charts-helper/CHDecimalNumberToStringTransformer.h
@@ -0,0 +1,31 @@
+/*
+ CHDecimalNumberToStringTransformer.h
+ growth-charts-helper
+
+ Created by Pascal Pfiffner on 12/18/12.
+ Copyright (c) 2012 CHIP. All rights reserved.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#import <Foundation/Foundation.h>
+
+
+/**
+ * Transform NSDecimalNumber to NSString and vice versa.
+ */
+@interface CHDecimalNumberToStringTransformer : NSValueTransformer
+
+@end
View
56 growth-charts-helper/CHDecimalNumberToStringTransformer.m
@@ -0,0 +1,56 @@
+/*
+ CHDecimalNumberToStringTransformer.m
+ growth-charts-helper
+
+ Created by Pascal Pfiffner on 12/18/12.
+ Copyright (c) 2012 CHIP. All rights reserved.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#import "CHDecimalNumberToStringTransformer.h"
+
+
+@implementation CHDecimalNumberToStringTransformer
+
+
++ (Class)transformedValueClass
+{
+ return [NSString class];
+}
+
++ (BOOL)allowsReverseTransformation
+{
+ return YES;
+}
+
+/**
+ * NSDecimalNumber -> NSString.
+ */
+- (id)transformedValue:(id)value
+{
+ return [value description];
+}
+
+/**
+ * NSString -> NSDecimalNumber.
+ */
+- (id)reverseTransformedValue:(id)value
+{
+ return [NSDecimalNumber decimalNumberWithString:value];
+}
+
+
+@end
View
2 growth-charts-helper/CHEnumToNumberTransformer.h
@@ -1,5 +1,5 @@
/*
- CHGenderToNumberTransformer.h
+ CHEnumToNumberTransformer.h
growth-charts-helper
Created by Pascal Pfiffner on 12/18/12.
View
13 growth-charts-helper/CHEnumToNumberTransformer.m
@@ -1,5 +1,5 @@
/*
- CHGenderToNumberTransformer.m
+ CHEnumToNumberTransformer.m
growth-charts-helper
Created by Pascal Pfiffner on 12/18/12.
@@ -23,22 +23,17 @@
#import "CHEnumToNumberTransformer.h"
-@interface CHEnumToNumberTransformer ()
-
-@end
-
-
@implementation CHEnumToNumberTransformer
+ (Class)transformedValueClass
{
- return [NSNumber class];
+ return [NSNumber class];
}
+ (BOOL)allowsReverseTransformation
{
- return YES;
+ return YES;
}
/**
@@ -54,7 +49,7 @@ - (id)transformedValue:(id)value
*/
- (id)reverseTransformedValue:(id)value
{
- return value;
+ return value;
}
View
31 growth-charts-helper/CHFloatToStringTransformer.h
@@ -0,0 +1,31 @@
+/*
+ CHFloatToStringTransformer.h
+ growth-charts-helper
+
+ Created by Pascal Pfiffner on 12/18/12.
+ Copyright (c) 2012 CHIP. All rights reserved.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#import <Foundation/Foundation.h>
+
+
+/**
+ * Transform NSNumber to NSString and vice versa.
+ */
+@interface CHFloatToStringTransformer : NSValueTransformer
+
+@end
View
56 growth-charts-helper/CHFloatToStringTransformer.m
@@ -0,0 +1,56 @@
+/*
+ CHFloatToStringTransformer.m
+ growth-charts-helper
+
+ Created by Pascal Pfiffner on 12/18/12.
+ Copyright (c) 2012 CHIP. All rights reserved.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#import "CHFloatToStringTransformer.h"
+
+
+@implementation CHFloatToStringTransformer
+
+
++ (Class)transformedValueClass
+{
+ return [NSString class];
+}
+
++ (BOOL)allowsReverseTransformation
+{
+ return YES;
+}
+
+/**
+ * NSNumber -> NSString.
+ */
+- (id)transformedValue:(id)value
+{
+ return [value description];
+}
+
+/**
+ * NSString -> NSNumber.
+ */
+- (id)reverseTransformedValue:(id)value
+{
+ return [NSNumber numberWithDouble:[value doubleValue]];
+}
+
+
+@end
View
31 growth-charts-helper/CHRectToStringTransformer.h
@@ -0,0 +1,31 @@
+/*
+ CHRectToStringTransformer.h
+ growth-charts-helper
+
+ Created by Pascal Pfiffner on 12/18/12.
+ Copyright (c) 2012 CHIP. All rights reserved.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#import <Foundation/Foundation.h>
+
+
+/**
+ * Transform a CGRect to an NSString.
+ */
+@interface CHRectToStringTransformer : NSValueTransformer
+
+@end
View
48 growth-charts-helper/CHRectToStringTransformer.m
@@ -0,0 +1,48 @@
+/*
+ CHRectToStringTransformer.m
+ growth-charts-helper
+
+ Created by Pascal Pfiffner on 12/18/12.
+ Copyright (c) 2012 CHIP. All rights reserved.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#import "CHRectToStringTransformer.h"
+
+
+@implementation CHRectToStringTransformer
+
+
++ (Class)transformedValueClass
+{
+ return [NSString class];
+}
+
++ (BOOL)allowsReverseTransformation
+{
+ return NO;
+}
+
+/**
+ * Since the transformer can't be fed a struct we get it packed into an NSValue.
+ */
+- (id)transformedValue:(id)value
+{
+ return NSStringFromCGRect([value rectValue]);
+}
+
+
+@end
View
4 growth-charts-helper/CHWindowController.h
@@ -23,6 +23,7 @@
#import <Cocoa/Cocoa.h>
@class CHChart;
+@class CHChartArea;
@class CHChartPDFView;
@class CHDropView;
@@ -33,11 +34,14 @@
@interface CHWindowController : NSWindowController <NSSplitViewDelegate>
@property (nonatomic, readonly, strong) CHChart *chart;
+@property (nonatomic, readonly, weak) CHChartArea *activeArea;
@property (nonatomic, readonly, strong) CHChartPDFView *pdf;
@property (nonatomic, weak) IBOutlet NSView *leftPane;
@property (nonatomic, weak) IBOutlet NSView *rightPane;
@property (nonatomic, strong) IBOutlet CHDropView *dropWell;
+@property (nonatomic, weak) IBOutlet NSTabView *optionsBox;
+@property (nonatomic, weak) IBOutlet NSBox *hierarchyBox;
@end
View
98 growth-charts-helper/CHWindowController.m
@@ -23,13 +23,20 @@
#import "CHWindowController.h"
#import "CHDocument.h"
#import "CHChartPDFView.h"
+#import "CHChartAreaView.h"
+#import "CHChartArea.h"
#import "CHDropView.h"
-@interface CHWindowController ()
+@interface CHWindowController () {
+ NSUInteger currentAreaIndex;
+}
+@property (nonatomic, readwrite, weak) CHChartArea *activeArea;
@property (nonatomic, readwrite, strong) CHChartPDFView *pdf;
+@property (nonatomic, strong) NSMutableArray *currentAreaStack;
+
- (void)loadPDFAt:(NSURL *)url;
- (void)didDropFiles:(NSNotification *)notification;
@@ -82,7 +89,11 @@ - (void)loadPDFAt:(NSURL *)url
return;
}
- [_pdf removeFromSuperview];
+ // get rid of the old view
+ if (_pdf) {
+ [_pdf removeFromSuperview];
+ [_pdf removeObserver:self forKeyPath:@"activeArea"];
+ }
// create the PDF doc view
self.pdf = [CHChartPDFView new];
@@ -100,16 +111,97 @@ - (void)loadPDFAt:(NSURL *)url
[_dropWell removeFromSuperview];
[_leftPane addSubview:_pdf];
[_pdf layoutSubviews];
+
+ // we need to observe the active area
+ [_pdf addObserver:self forKeyPath:@"activeArea" options:0 context:NULL];
}
-#pragma mark - Properties
+#pragma mark - Chart Handling
- (CHChart *)chart
{
return ((CHDocument *)self.document).chart;
}
+- (void)setActiveArea:(CHChartArea *)activeArea
+{
+ if (activeArea != _activeArea) {
+ [self willChangeValueForKey:@"activeArea"];
+ _activeArea = activeArea;
+ [self didChangeValueForKey:@"activeArea"];
+ }
+}
+
+- (void)changeActiveArea:(NSButton *)sender
+{
+ if ([_currentAreaStack count] > sender.tag) {
+ currentAreaIndex = sender.tag;
+ _pdf.activeArea = ((CHChartAreaView *)[_currentAreaStack objectAtIndex:currentAreaIndex]);
+ }
+}
+
+
+
+#pragma mark - Key-Value Observing
+- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
+{
+ self.activeArea = _pdf.activeArea.area;
+
+ // do we need to change our stack?
+ NSView *boxContent = [_hierarchyBox contentView];
+ if (!_pdf.activeArea || ![_currentAreaStack containsObject:_pdf.activeArea]) {
+ [_currentAreaStack removeAllObjects];
+ [[boxContent subviews] makeObjectsPerformSelector:@selector(removeFromSuperviewWithoutNeedingDisplay)];
+
+ if (_pdf.activeArea) {
+ if (!_currentAreaStack) {
+ self.currentAreaStack = [NSMutableArray array];
+ }
+ CGSize boxSize = _hierarchyBox.bounds.size;
+ CGFloat y = 10.f;
+ NSUInteger tag = 0;
+ currentAreaIndex = 0;
+
+ // loop area and parent areas
+ CHChartAreaView *areaView = _pdf.activeArea;
+ while ([areaView isKindOfClass:[CHChartAreaView class]]) {
+ NSRect buttonFrame = NSMakeRect(10.f, y, boxSize.width - 20.f, 22.f);
+ NSButton *button = [[NSButton alloc] initWithFrame:buttonFrame];
+ [button setButtonType:NSPushOnPushOffButton];
+ [button setBezelStyle:NSTexturedRoundedBezelStyle];
+ button.title = areaView.area.type;
+ button.tag = tag;
+ [button setState:(_pdf.activeArea == areaView) ? NSOnState : NSOffState];
+
+ [button setTarget:self];
+ [button setAction:@selector(changeActiveArea:)];
+
+ [boxContent addSubview:button];
+ [_currentAreaStack addObject:areaView];
+
+ y += buttonFrame.size.height + 5.f;
+ tag++;
+ areaView = (CHChartAreaView *)[areaView superview];
+ }
+
+ // adjust size
+ NSRect optFrame = _optionsBox.frame;
+ NSRect hierFrame = _hierarchyBox.frame;
+ hierFrame.size.height = y + 19.f;
+ hierFrame.origin.y = optFrame.origin.y - 8.f - hierFrame.size.height;
+ _hierarchyBox.frame = hierFrame;
+ }
+ }
+
+ // no, just update button status
+ else {
+ for (NSButton *button in [boxContent subviews]) {
+ [button setState:(button.tag == currentAreaIndex) ? NSOnState : NSOffState];
+ }
+ }
+}
+
#pragma mark - Split View Delegate
View
2 growth-charts-helper/FromCharts/CHChart.m
@@ -158,7 +158,7 @@ - (NSUInteger)numAreas
#pragma mark - Utilities
- (NSString *)description
{
- return [NSString stringWithFormat:@"%@ <%p> \"%@\" at %@, %d areas", NSStringFromClass([self class]), self, _name, _resourceName, [_chartAreas count]];
+ return [NSString stringWithFormat:@"%@ <%p> \"%@\" at %@, %d areas", NSStringFromClass([self class]), self, _name, _resourceName, (int)[_chartAreas count]];
}
View
21 growth-charts-helper/FromCharts/CHChartArea.h
@@ -34,8 +34,29 @@
@property (nonatomic, weak) CHChart *chart; ///< The chart to which we belong
@property (nonatomic, copy) NSString *type; ///< The type of the area
@property (nonatomic, copy) NSDictionary *dictionary; ///< The dictionary representation defining the receiver, kept around to spawn the view objects
+
@property (nonatomic, assign) NSUInteger page; ///< 1 by default. The page number of the PDF this area resides on
+@property (nonatomic, assign) CGRect frame; ///< The frame as specified
+@property (nonatomic, assign) CGFloat frameOriginX;
+@property (nonatomic, assign) CGFloat frameOriginY;
+@property (nonatomic, assign) CGFloat frameSizeWidth;
+@property (nonatomic, assign) CGFloat frameSizeHeight;
+
+@property (nonatomic, copy) NSString *fontName; ///< Text areas: font name
+@property (nonatomic, strong) NSNumber *fontSize; ///< Text areas: font size
+
+@property (nonatomic, copy) NSString *dataType; ///< Value areas: data type
+
+@property (nonatomic, copy) NSString *xAxisUnitName; ///< Plot areas: X axis unit name
+@property (nonatomic, copy) NSString *xAxisDataType; ///< Plot areas: X axis data type
+@property (nonatomic, strong) NSDecimalNumber *xAxisFrom; ///< Plot areas: X axis starting point
+@property (nonatomic, strong) NSDecimalNumber *xAxisTo; ///< Plot areas: X axis ending point
+@property (nonatomic, copy) NSString *yAxisUnitName; ///< Plot areas: Y axis unit name
+@property (nonatomic, copy) NSString *yAxisDataType; ///< Plot areas: Y axis data type
+@property (nonatomic, strong) NSDecimalNumber *yAxisFrom; ///< Plot areas: Y axis starting point
+@property (nonatomic, strong) NSDecimalNumber *yAxisTo; ///< Plot areas: Y axis ending point
+@property (nonatomic, readonly, 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
+ (id)newAreaOnChart:(CHChart *)chart withDictionary:(NSDictionary *)dict;
View
112 growth-charts-helper/FromCharts/CHChartArea.m
@@ -26,6 +26,8 @@
@interface CHChartArea ()
+@property (nonatomic, readwrite, assign) BOOL topmost;
+
@end
@@ -36,6 +38,7 @@ + (id)newAreaOnChart:(CHChart *)chart withDictionary:(NSDictionary *)dict
{
CHChartArea *this = [self new];
this.chart = chart;
+ this.topmost = YES;
[this setFromDictionary:dict];
return this;
@@ -75,7 +78,58 @@ - (void)setFromDictionary:(NSDictionary *)dict
[muteDict removeObjectForKey:@"page"];
}
- // add sub-areas
+ // frame
+ NSString *rectString = [dict objectForKey:@"rect"];
+ if ([rectString isKindOfClass:[NSString class]]) {
+ NSRect rect = NSRectFromString(rectString);
+ self.frame = CGRectMake(rect.origin.x, rect.origin.y, rect.size.width, rect.size.height);
+ }
+ else if (rectString) {
+ DLog(@"\"rect\" must be a NSString, but I got a %@, discarding", NSStringFromClass([rectString class]));
+ }
+
+ // fonts
+ NSString *aFontName = [dict objectForKey:@"fontName"];
+ if ([aFontName isKindOfClass:[NSString class]]) {
+ self.fontName = aFontName;
+ }
+ NSNumber *aFontSize = [dict objectForKey:@"fontSize"];
+ if ([aFontSize isKindOfClass:[NSNumber class]]) {
+ self.fontSize = aFontSize;
+ }
+ else if (aFontSize) {
+ DLog(@"\"fontSize\" must be a number, but I got a %@, discarding", NSStringFromClass([aFontSize class]));
+ }
+
+ // data and value areas
+ NSString *aDataType = [dict objectForKey:@"dataType"];
+ if ([aDataType isKindOfClass:[NSString class]]) {
+ self.dataType = aDataType;
+ }
+
+ // plot areas
+ NSDictionary *axesDict = [dict objectForKey:@"axes"];
+ if ([axesDict isKindOfClass:[NSDictionary class]]) {
+
+ // x
+ NSDictionary *xAxisDict = [axesDict objectForKey:@"x"];
+ self.xAxisUnitName = [xAxisDict objectForKey:@"unit"];
+ self.xAxisDataType = [xAxisDict objectForKey:@"datatype"];
+ self.xAxisFrom = [NSDecimalNumber decimalNumberWithString:[xAxisDict objectForKey:@"from"]];
+ self.xAxisTo = [NSDecimalNumber decimalNumberWithString:[xAxisDict objectForKey:@"to"]];
+
+ // y
+ NSDictionary *yAxisDict = [axesDict objectForKey:@"y"];
+ self.yAxisUnitName = [yAxisDict objectForKey:@"unit"];
+ self.yAxisDataType = [yAxisDict objectForKey:@"datatype"];
+ self.yAxisFrom = [NSDecimalNumber decimalNumberWithString:[yAxisDict objectForKey:@"from"]];
+ self.yAxisTo = [NSDecimalNumber decimalNumberWithString:[yAxisDict objectForKey:@"to"]];
+ }
+ else if ([@"plot" isEqualToString:_type]) {
+ DLog(@"This plot area does not have axes! %@", dict);
+ }
+
+ // ** sub-areas
NSArray *areas = [dict objectForKey:@"areas"];
if ([areas isKindOfClass:[NSArray class]] && [areas count] > 0) {
NSMutableArray *myAreas = [NSMutableArray arrayWithCapacity:[areas count]];
@@ -85,6 +139,7 @@ - (void)setFromDictionary:(NSDictionary *)dict
if ([areaDict isKindOfClass:[NSDictionary class]]) {
CHChartArea *area = [CHChartArea newAreaOnChart:_chart withDictionary:areaDict];
if (area) {
+ area.topmost = NO;
area.page = self.page;
[myAreas addObject:area];
}
@@ -114,8 +169,8 @@ - (CHChartAreaView *)view
return nil;
}
- // all properties
- [view setFromDictionary:_dictionary];
+ // update properties
+ view.area = self;
// sub-areas
if ([_areas count] > 0) {
@@ -133,9 +188,58 @@ - (CHChartAreaView *)view
#pragma mark - Utilities
+- (CGFloat)frameOriginX
+{
+ return _frame.origin.x;
+}
+
+- (void)setFrameOriginX:(CGFloat)x
+{
+ CGRect fr = _frame;
+ fr.origin.x = x;
+ self.frame = fr;
+}
+
+- (CGFloat)frameOriginY
+{
+ return _frame.origin.y;
+}
+
+- (void)setFrameOriginY:(CGFloat)y
+{
+ CGRect fr = _frame;
+ fr.origin.y = y;
+ self.frame = fr;
+}
+
+- (CGFloat)frameSizeWidth
+{
+ return _frame.size.width;
+}
+
+- (void)setFrameSizeWidth:(CGFloat)w
+{
+ CGRect fr = _frame;
+ fr.size.width = w;
+ self.frame = fr;
+}
+
+- (CGFloat)frameSizeHeight
+{
+ return _frame.size.height;
+}
+
+- (void)setFrameSizeHeight:(CGFloat)h
+{
+ CGRect fr = _frame;
+ fr.size.height = h;
+ self.frame = fr;
+}
+
+
- (NSString *)description
{
- return [NSString stringWithFormat:@"%@ <%p> type \"%@\", %d sub-areas", NSStringFromClass([self class]), self, _type, [_areas count]];
+ return [NSString stringWithFormat:@"%@ <%p> type \"%@\", %d sub-areas", NSStringFromClass([self class]), self, _type, (int)[_areas count]];
}
View
20 growth-charts-helper/FromCharts/CHDateUnit.m
@@ -27,40 +27,40 @@ - (NSString *)stringValueForNumber:(NSDecimalNumber *)number withSize:(CHValueSt
}
else {
if (CHValueStringSizeLong == size) {
- [parts addObject:[NSString stringWithFormat:@"%d years", comp.year]];
+ [parts addObject:[NSString stringWithFormat:@"%d years", (int)comp.year]];
}
else if (CHValueStringSizeCompact == size) {
- [parts addObject:[NSString stringWithFormat:@"%dy", comp.year]];
+ [parts addObject:[NSString stringWithFormat:@"%dy", (int)comp.year]];
}
else {
- [parts addObject:[NSString stringWithFormat:@"%d y", comp.year]];
+ [parts addObject:[NSString stringWithFormat:@"%d y", (int)comp.year]];
}
}
}
// months
if (comp.month > 0) {
if (CHValueStringSizeLong == size) {
- [parts addObject:[NSString stringWithFormat:@"%d month%@", comp.month, (1 == comp.month ? @"" : @"s")]];
+ [parts addObject:[NSString stringWithFormat:@"%d month%@", (int)comp.month, (1 == comp.month ? @"" : @"s")]];
}
else if (CHValueStringSizeCompact == size) {
- [parts addObject:[NSString stringWithFormat:@"%dm", comp.month]];
+ [parts addObject:[NSString stringWithFormat:@"%dm", (int)comp.month]];
}
else {
- [parts addObject:[NSString stringWithFormat:@"%d mth", comp.month]];
+ [parts addObject:[NSString stringWithFormat:@"%d mth", (int)comp.month]];
}
}
// days
if (comp.day > 0) {
if (CHValueStringSizeLong == size) {
- [parts addObject:[NSString stringWithFormat:@"%d day%@", comp.day, (1 == comp.day ? @"" : @"s")]];
+ [parts addObject:[NSString stringWithFormat:@"%d day%@", (int)comp.day, (1 == comp.day ? @"" : @"s")]];
}
else if (CHValueStringSizeCompact == size) {
- [parts addObject:[NSString stringWithFormat:@"%dd", comp.day]];
+ [parts addObject:[NSString stringWithFormat:@"%dd", (int)comp.day]];
}
else {
- [parts addObject:[NSString stringWithFormat:@"%d d", comp.day]];
+ [parts addObject:[NSString stringWithFormat:@"%d d", (int)comp.day]];
}
}
@@ -142,7 +142,7 @@ - (NSDecimalNumber *)numberInBaseUnit:(NSDecimalNumber *)number
NSDate *date = [self dateValueFor:number fromDate:self.referenceDate];
NSDateComponents *comp = [[NSCalendar currentCalendar] components:NSSecondCalendarUnit fromDate:self.referenceDate toDate:date options:0];
- return [NSDecimalNumber decimalNumberWithString:[NSString stringWithFormat:@"%i", comp.second]];
+ return [NSDecimalNumber decimalNumberWithString:[NSString stringWithFormat:@"%d", (int)comp.second]];
}
View
2,331 growth-charts-helper/en.lproj/CHDocument.xib
2,197 additions, 134 deletions not shown because the diff is too large. Please use a local Git client to view these changes.

0 comments on commit 469aa6d

Please sign in to comment.