Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Unfinished cursor tracking and area resizing

  • Loading branch information...
commit 507642b91d034ed77731f1ae5def71a71cee95fa 1 parent 9e50022
Pascal Pfiffner authored
6 growth-charts-helper.xcodeproj/project.pbxproj
View
@@ -31,6 +31,7 @@
EEEB2DE016810423004DC719 /* CHChartPDFView.m in Sources */ = {isa = PBXBuildFile; fileRef = EEEB2DDF16810422004DC719 /* CHChartPDFView.m */; };
EEEB2DE21681047B004DC719 /* Quartz.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EEEB2DE11681047B004DC719 /* Quartz.framework */; };
EEEB2DE51681075A004DC719 /* CHDropView.m in Sources */ = {isa = PBXBuildFile; fileRef = EEEB2DE41681075A004DC719 /* CHDropView.m */; };
+ EEEFDEB11682737B005C4D17 /* CHResizableChartAreaView.m in Sources */ = {isa = PBXBuildFile; fileRef = EEEFDEB01682737B005C4D17 /* CHResizableChartAreaView.m */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
@@ -82,6 +83,8 @@
EEEB2DE11681047B004DC719 /* Quartz.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Quartz.framework; path = System/Library/Frameworks/Quartz.framework; sourceTree = SDKROOT; };
EEEB2DE31681075A004DC719 /* CHDropView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CHDropView.h; sourceTree = "<group>"; };
EEEB2DE41681075A004DC719 /* CHDropView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CHDropView.m; sourceTree = "<group>"; };
+ EEEFDEAF1682737B005C4D17 /* CHResizableChartAreaView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CHResizableChartAreaView.h; sourceTree = "<group>"; };
+ EEEFDEB01682737B005C4D17 /* CHResizableChartAreaView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CHResizableChartAreaView.m; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -148,6 +151,8 @@
EEEB2DDF16810422004DC719 /* CHChartPDFView.m */,
EEEB2DD21680EE70004DC719 /* CHChartAreaView.h */,
EEEB2DD31680EE70004DC719 /* CHChartAreaView.m */,
+ EEEFDEAF1682737B005C4D17 /* CHResizableChartAreaView.h */,
+ EEEFDEB01682737B005C4D17 /* CHResizableChartAreaView.m */,
EEEB2DB91680EA29004DC719 /* FromCharts */,
EEEB2DDD168100EA004DC719 /* Helpers */,
EEEB2D8D1680E014004DC719 /* MainMenu.xib */,
@@ -291,6 +296,7 @@
EEAECBFE16815E2F00E8ABE1 /* CHRectToStringTransformer.m in Sources */,
EEAECC1716816B7800E8ABE1 /* CHFloatToStringTransformer.m in Sources */,
EEAECC1A16816C4500E8ABE1 /* CHDecimalNumberToStringTransformer.m in Sources */,
+ EEEFDEB11682737B005C4D17 /* CHResizableChartAreaView.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
4 growth-charts-helper/CHChartAreaView.h
View
@@ -55,6 +55,7 @@
- (void)setFromDictionary:(NSDictionary *)dict;
+- (void)setup;
- (void)reset;
- (void)resetHighlight;
@@ -68,6 +69,9 @@
- (NSSet *)allDataTypes;
- (NSSet *)plotDataTypes;
+- (BOOL)makeFirstResponder;
+- (void)didBecomeFirstResponder;
+
- (BOOL)pointInside:(CGPoint)point withEvent:(NSEvent *)event;
- (NSSet *)areasAtPoint:(CGPoint)point;
120 growth-charts-helper/CHChartAreaView.m
View
@@ -23,9 +23,13 @@
#import "CHChartAreaView.h"
#import "CHChartArea.h"
#import "CHChartPDFView.h"
+#import "CHResizableChartAreaView.h" // our subclass
-@interface CHChartAreaView ()
+@interface CHChartAreaView () {
+ BOOL clickStartedInside;
+ BOOL clickDidMove;
+}
@end
@@ -42,19 +46,24 @@ - (void)dealloc
- (id)initWithFrame:(CGRect)frame
{
if ((self = [super initWithFrame:frame])) {
-// self.opaque = NO;
-// self.backgroundColor = [UIColor clearColor];
-// self.autoresizingMask = UIViewAutoresizingNone;
-// self.clipsToBounds = NO;
-
-// self.clearsContextBeforeDrawing = NO;
-// self.contentMode = UIViewContentModeRedraw;
-// ((CATiledLayer *)self.layer).levelsOfDetail = 4;
-// ((CATiledLayer *)self.layer).levelsOfDetailBias = 3; // we use (levelsOfDetail - 1) because we only need more detail when zoomed in, no less details when zoomed out
+ [self setup];
}
return self;
}
+- (void)setup
+{
+ // self.opaque = NO;
+ // self.backgroundColor = [UIColor clearColor];
+ // self.autoresizingMask = UIViewAutoresizingNone;
+ // self.clipsToBounds = NO;
+
+ // self.clearsContextBeforeDrawing = NO;
+ // self.contentMode = UIViewContentModeRedraw;
+ // ((CATiledLayer *)self.layer).levelsOfDetail = 4;
+ // ((CATiledLayer *)self.layer).levelsOfDetailBias = 3; // we use (levelsOfDetail - 1) because we only need more detail when zoomed in, no less details when zoomed out
+}
+
- (void)setArea:(CHChartArea *)area
{
@@ -271,29 +280,48 @@ - (CGRect)contentBox
-#pragma mark - Drawing
-- (void)setActive:(BOOL)flag
+#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
{
- if (flag != _active) {
- _active = flag;
+ 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];
+}
-- (void)drawRect:(NSRect)dirtyRect
+- (BOOL)resignFirstResponder
{
- [NSGraphicsContext saveGraphicsState];
-
- 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];
- }
-
- [NSBezierPath fillRect:self.bounds];
- [NSGraphicsContext restoreGraphicsState];
+ BOOL done = [super resignFirstResponder];
+ _active = done ? NO : _active;
+ [self setNeedsDisplay:YES];
+ return done;
}
@@ -348,22 +376,50 @@ - (BOOL)pointInside:(CGPoint)point withEvent:(NSEvent *)event
return NSPointInRect(location, [self bounds]);
}
-
- (void)mouseDown:(NSEvent *)theEvent
{
- //DLog(@"%@ -- %@", self, theEvent);
+ clickStartedInside = YES;
+}
+
+- (void)mouseMoved:(NSEvent *)theEvent
+{
+ if (clickStartedInside) {
+ clickDidMove = YES;
+ }
}
- (void)mouseDragged:(NSEvent *)theEvent
{
- if (_active) {
-
+ if (clickStartedInside) {
+ clickDidMove = YES;
}
}
- (void)mouseUp:(NSEvent *)theEvent
{
- [_pageView didGetClicked:self];
+ if ([self acceptsFirstResponder]) {
+ [[self window] makeFirstResponder:self];
+ }
+ clickStartedInside = NO;
+ clickDidMove = NO;
+}
+
+
+
+#pragma mark - Drawing
+- (void)drawRect:(NSRect)dirtyRect
+{
+ [NSGraphicsContext saveGraphicsState];
+
+ 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];
+ }
+
+ [NSBezierPath fillRect:self.bounds];
+ [NSGraphicsContext restoreGraphicsState];
}
@@ -371,7 +427,7 @@ - (void)mouseUp:(NSEvent *)theEvent
#pragma mark - Class Registration
+ (Class)registeredClassForType:(NSString *)aType
{
- return self;
+ return [CHResizableChartAreaView class];
}
2  growth-charts-helper/CHChartPDFView.h
View
@@ -35,7 +35,7 @@
@property (nonatomic, strong) CHChartAreaView *activeArea;
- (void)layoutSubviews;
-- (void)didGetClicked:(CHChartAreaView *)areaView;
+- (void)didBecomeFirstResponder:(CHChartAreaView *)areaView;
@end
17 growth-charts-helper/CHChartPDFView.m
View
@@ -121,7 +121,7 @@ - (void)layoutSubviews
#pragma mark - Area Handling
-- (void)didGetClicked:(CHChartAreaView *)areaView
+- (void)didBecomeFirstResponder:(CHChartAreaView *)areaView
{
// do not go ahead if an area's superview is active
CHChartAreaView *superArea = areaView;
@@ -141,15 +141,24 @@ - (void)didGetClicked:(CHChartAreaView *)areaView
- (void)setActiveArea:(CHChartAreaView *)activeArea
{
if (activeArea != _activeArea) {
- _activeArea.active = NO;
_activeArea = activeArea;
- _activeArea.active = YES;
+ [_activeArea makeFirstResponder];
}
}
-#pragma mark - Mouse Wheel
+#pragma mark - Mouse Handling
+- (PDFAreaOfInterest)areaOfInterestForMouse:(NSEvent *)theEvent
+{
+ return kPDFControlArea;
+}
+
+- (void)setCursorForAreaOfInterest:(PDFAreaOfInterest)area
+{
+// [[NSCursor openHandCursor] set];
+}
+
- (void)scrollWheel:(NSEvent *)event
{
if (event.deltaY < 0.f) {
31 growth-charts-helper/CHResizableChartAreaView.h
View
@@ -0,0 +1,31 @@
+/*
+ CHResizableChartAreaView.h
+ growth-charts-helper
+
+ Created by Pascal Pfiffner on 12/19/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 "CHChartAreaView.h"
+
+
+/**
+ * Makes chart areas resizeable via mouse.
+ */
+@interface CHResizableChartAreaView : CHChartAreaView
+
+@end
210 growth-charts-helper/CHResizableChartAreaView.m
View
@@ -0,0 +1,210 @@
+/*
+ CHResizableChartAreaView.m
+ growth-charts-helper
+
+ Created by Pascal Pfiffner on 12/19/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 "CHResizableChartAreaView.h"
+
+
+@interface CHResizableChartAreaView () {
+ NSPoint dragStartPoint;
+ NSInteger mouseActionEffect; // 0 = drag, 1 and -1 = resize width, 2 and -2 = resize height
+}
+
+@property (nonatomic, strong) NSTrackingArea *tracker;
+
+@end
+
+
+@implementation CHResizableChartAreaView
+
+/**
+ * We add tracking areas upon setup.
+ */
+- (void)setup
+{
+ [super setup];
+ [self updateTrackingAreas];
+}
+
+
+
+#pragma mark - Tracking Areas
+- (void)updateTrackingAreas
+{
+ // full size tracker
+ if (_tracker) {
+ [self removeTrackingArea:_tracker];
+ }
+ self.tracker = [[NSTrackingArea alloc] initWithRect:self.bounds
+ options:(NSTrackingMouseEnteredAndExited | NSTrackingMouseMoved | NSTrackingActiveInKeyWindow) // NSTrackingCursorUpdate
+ owner:self
+ userInfo:nil];
+ [self addTrackingArea:_tracker];
+}
+
+- (void)cursorUpdateDOESNOTWORKLIKEIWANTITTOWORK:(NSEvent *)theEvent
+{
+ if (self.active) {
+ NSPoint location = [self convertPoint:[theEvent locationInWindow] fromView:nil];
+ NSSize mySize = self.bounds.size;
+
+ if (location.x < 3.f) { // resize left
+ [[NSCursor resizeLeftRightCursor] set];
+ }
+ else if (location.x > mySize.width - 3.f) { // resize right
+ [[NSCursor resizeLeftRightCursor] set];
+ }
+ else if (location.y < 3.f) { // resize bottom
+ [[NSCursor resizeUpDownCursor] set];
+ }
+ else if (location.y > mySize.height - 3.f) { // resize right
+ [[NSCursor resizeUpDownCursor] set];
+ }
+ else { // drag
+ [[NSCursor openHandCursor] set];
+ }
+ }
+ else {
+ [[NSCursor pointingHandCursor] set];
+ }
+}
+
+
+
+#pragma mark - Mouse Handling
+- (void)mouseEntered:(NSEvent *)theEvent
+{
+ [super mouseEntered:theEvent];
+
+ if (self.active) {
+ [[NSCursor openHandCursor] push];
+ }
+ else {
+ [[NSCursor pointingHandCursor] push];
+ }
+}
+
+- (void)mouseMoved:(NSEvent *)theEvent
+{
+ [super mouseMoved:theEvent];
+
+ // mouse moves but does NOT drag
+ NSPoint location = [self convertPoint:[theEvent locationInWindow] fromView:nil];
+ if (self.active && NSPointInRect(location, self.bounds)) {
+ NSSize mySize = self.bounds.size;
+
+ if (location.x < 3.f) { // resize left
+ mouseActionEffect = -1;
+ [[NSCursor resizeLeftRightCursor] set];
+ }
+ else if (location.x > mySize.width - 3.f) { // resize right
+ mouseActionEffect = 1;
+ [[NSCursor resizeLeftRightCursor] set];
+ }
+ else if (location.y < 3.f) { // resize bottom
+ mouseActionEffect = -2;
+ [[NSCursor resizeUpDownCursor] set];
+ }
+ else if (location.y > mySize.height - 3.f) { // resize right
+ mouseActionEffect = 2;
+ [[NSCursor resizeUpDownCursor] set];
+ }
+ else { // drag
+ mouseActionEffect = 0;
+ [[NSCursor openHandCursor] set];
+ }
+ }
+}
+
+- (void)mouseDown:(NSEvent *)theEvent
+{
+ [super mouseDown:theEvent];
+
+ if (self.active) {
+ dragStartPoint = [theEvent locationInWindow];
+ [[NSCursor closedHandCursor] push];
+ }
+}
+
+- (void)mouseDragged:(NSEvent *)theEvent
+{
+ [super mouseDragged:theEvent];
+
+ // mouse drags
+ if (self.active) {
+ NSPoint currentPoint = [theEvent locationInWindow];
+ NSRect myFrame = self.frame;
+
+ // move it
+ if (0 == mouseActionEffect) {
+ myFrame.origin.x -= dragStartPoint.x - currentPoint.x;
+ myFrame.origin.y -= dragStartPoint.y - currentPoint.y;
+ }
+
+ // resize width
+ else if (1 == ABS(mouseActionEffect)) {
+ CGFloat diff = currentPoint.x - dragStartPoint.x;
+ myFrame.size.width += diff * mouseActionEffect;
+ if (mouseActionEffect < 0) {
+ myFrame.origin.x -= -1 * diff;
+ }
+ }
+
+ // resize height
+ else if (2 == ABS(mouseActionEffect)) {
+ CGFloat diff = currentPoint.y - dragStartPoint.y;
+ myFrame.size.height += diff * (mouseActionEffect / 2);
+ if (mouseActionEffect < 0) {
+ myFrame.origin.y -= -1* diff;
+ }
+ }
+
+ self.frame = myFrame;
+ dragStartPoint = currentPoint;
+ }
+}
+
+- (void)mouseUp:(NSEvent *)theEvent
+{
+ [super mouseUp:theEvent];
+
+ if (self.active) {
+ dragStartPoint = NSZeroPoint;
+ [NSCursor pop];
+ }
+}
+
+- (void)mouseExited:(NSEvent *)theEvent
+{
+ [super mouseExited:theEvent];
+ [NSCursor pop];
+}
+
+
+
+#pragma mark - First Responder
+- (void)didBecomeFirstResponder
+{
+ [super didBecomeFirstResponder];
+}
+
+
+@end
Please sign in to comment.
Something went wrong with that request. Please try again.