Skip to content

Commit

Permalink
Can add and remove areas
Browse files Browse the repository at this point in the history
  • Loading branch information
p2 committed Dec 22, 2012
1 parent 15f2edc commit a6a8bb2
Show file tree
Hide file tree
Showing 16 changed files with 515 additions and 140 deletions.
10 changes: 8 additions & 2 deletions growth-charts-helper.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -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 */; };
Expand Down Expand Up @@ -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>"; };
Expand Down Expand Up @@ -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 */,
Expand Down Expand Up @@ -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 */,
Expand Down Expand Up @@ -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;
};
Expand Down
11 changes: 5 additions & 6 deletions growth-charts-helper/CHChartAreaView.h
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand All @@ -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

Expand All @@ -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;

Expand All @@ -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;
Expand All @@ -68,9 +70,6 @@
- (NSSet *)allDataTypes;
- (NSSet *)plotDataTypes;

- (BOOL)makeFirstResponder;
- (void)didBecomeFirstResponder;

- (BOOL)pointInside:(CGPoint)point withEvent:(NSEvent *)event;
- (NSSet *)areasAtPoint:(CGPoint)point;

Expand Down
135 changes: 53 additions & 82 deletions growth-charts-helper/CHChartAreaView.m
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,6 @@

@interface CHChartAreaView () {
CGRect inParentRect;

BOOL clickStartedInside;
BOOL clickDidMove;
}

@end
Expand Down Expand Up @@ -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.
*
Expand Down Expand Up @@ -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.
*/
Expand Down Expand Up @@ -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 (!!)
Expand Down Expand Up @@ -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 {
Expand Down
4 changes: 4 additions & 0 deletions growth-charts-helper/CHChartPDFView.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#import <Quartz/Quartz.h>

@class CHChart;
@class CHChartArea;
@class CHChartAreaView;


Expand All @@ -37,5 +38,8 @@
- (void)layoutSubviews;
- (void)didBecomeFirstResponder:(CHChartAreaView *)areaView;

- (CHChartAreaView *)didAddArea:(CHChartArea *)area;
- (void)didRemoveArea:(CHChartArea *)area;


@end
74 changes: 59 additions & 15 deletions growth-charts-helper/CHChartPDFView.m
Original file line number Diff line number Diff line change
Expand Up @@ -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];
}
}

Expand All @@ -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) {
Expand Down
Loading

0 comments on commit a6a8bb2

Please sign in to comment.