Skip to content

Instantly share code, notes, and snippets.

@Me1000
Created January 16, 2012 23:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Me1000/1623499 to your computer and use it in GitHub Desktop.
Save Me1000/1623499 to your computer and use it in GitHub Desktop.
// Created by Randall Luecke or RCLConcepts
// Copyright 2010 all rights reserved
/*
Canvas object is an abstract view class that takes care of all the resizing, rotating, and repositiong
*/
@import <Foundation/CPObject.j>
var SMResizeLeft = 1 << 0,
SMResizeCenter = 1 << 1,
SMResizeRight = 1 << 2,
SMResizeTop = 1 << 3,
SMResizeBottom = 1 << 4;
@implementation CanvasObject : CPView
{
BOOL isSelected @accessors;
id delegate @accessors;
CGPoint dragBeginPoint;
SMResizeMask resizeMask;
}
- (id)initWithFrame:(CGRect)aRect
{
self = [super initWithFrame:aRect];
if (self)
{
dragBeginPoint = nil;
}
return self;
}
- (void)setIsSelected:(BOOL)aBool {
isSelected = aBool;
[self setNeedsDisplay:YES];
if ( aBool )
[delegate hasBeenSelected:self];
}
- (id)_dragVerticalHitTestForPoint:(CGPoint)aPoint
{
var bounds = [self bounds];
if (aPoint.y < 7)
return SMResizeTop;
else if (ABS(aPoint.y - CGRectGetMidY(bounds)) < 7)
return SMResizeCenter;
else if (aPoint.y > bounds.size.height - 7)
return SMResizeBottom;
else
return CPNotFound;
}
- (id)_dragHorizontalHitTestForPoint:(CGPoint)aPoint
{
var bounds = [self bounds];
if (aPoint.x < 7)
return SMResizeLeft;
else if (ABS(aPoint.x - CGRectGetMidX(bounds)) < 7)
return SMResizeCenter;
else if (aPoint.x > bounds.size.width - 7)
return SMResizeRight;
else
return CPNotFound;
}
// --- CPView Methods
- (void)drawRect:(CGRect)aRect
{
if (!isSelected)
return;
var context = [[CPGraphicsContext currentContext] graphicsPort];
[[CPColor grayColor] setStroke];
CGContextSetLineWidth(context, 2.0);
// FIX ME: clean this up... we should go from the edge of one circle to the edge of another...
CGContextStrokeRect(context, aRect);
// now draw the little resizy thingies
// top left
var circle = CGRectMake(1,1,5,5);
CGContextStrokeEllipseInRect(context, circle);
// top center
circle = CGRectMake(CGRectGetMidX(aRect) - 5,1,5,5);
CGContextStrokeEllipseInRect(context, circle);
// top right
circle = CGRectMake(CGRectGetMaxX(aRect) - 6,1,5,5);
CGContextStrokeEllipseInRect(context, circle);
// center left
circle = CGRectMake(1, CGRectGetMidY(aRect) - 3,5,5);
CGContextStrokeEllipseInRect(context, circle);
// center right
circle = CGRectMake(CGRectGetMaxX(aRect) - 6, CGRectGetMidY(aRect) -3,5,5);
CGContextStrokeEllipseInRect(context, circle);
// bottom left
circle = CGRectMake(1, CGRectGetMaxY(aRect) -6,5,5);
CGContextStrokeEllipseInRect(context, circle);
// bottom center
circle = CGRectMake(CGRectGetMidX(aRect) - 6, CGRectGetMaxY(aRect) -5,5,5);
CGContextStrokeEllipseInRect(context, circle);
// bottom right
circle = CGRectMake(CGRectGetMaxX(aRect) - 6, CGRectGetMaxY(aRect) -5,5,5);
CGContextStrokeEllipseInRect(context, circle);
}
// --- CPResponder Methods
- (void)mouseDown:(CPEvent)theEvent
{
// when the mouse is clicked register the location it was clicked from within the view
// we will use that location to recalculate the views new position in mouse dragged
dragBeginPoint = [self convertPoint:[theEvent locationInWindow] fromView:nil];
[self setIsSelected:YES];
[self setNeedsDisplay:YES];
var verticalMask = [self _dragVerticalHitTestForPoint:dragBeginPoint],
horizontalMask = [self _dragHorizontalHitTestForPoint:dragBeginPoint];
if (verticalMask === CPNotFound || horizontalMask === CPNotFound || verticalMask === horizontalMask)
return;
resizeMask = verticalMask | horizontalMask;
// reset it early here so we don't drag it around...
dragBeginPoint = nil;
}
- (void)mouseDragged:(CPEvent)theEvent
{
if (!dragBeginPoint && !resizeMask)
return;
var dragPoint = [[self superview] convertPoint:[theEvent locationInWindow] fromView:nil],
currentFrame = [self frame],
newY = { },
newX = { };
if (dragBeginPoint)
{
var newOrigin = CGPointMake(dragPoint.x - dragBeginPoint.x, dragPoint.y - dragBeginPoint.y);
if ( [delegate item:self shouldMoveToLocation:newOrigin] )
var newFrame = CGRectMake(newOrigin.x, newOrigin.y, currentFrame.size.width, currentFrame.size.height);
}
if (resizeMask)
{
if (resizeMask & SMResizeTop)
{
newY.origin = dragPoint.y;
newY.size = size = currentFrame.size.height + (currentFrame.origin.y - dragPoint.y);
}
if (resizeMask & SMResizeBottom)
{
newY.size = dragPoint.y - currentFrame.origin.y;
}
if (resizeMask & SMResizeLeft)
{
newX.origin = dragPoint.x;
newX.size = currentFrame.size.width + (currentFrame.origin.x - dragPoint.x);
}
else if (resizeMask & SMResizeRight)
{
newX.size = dragPoint.x - currentFrame.origin.x;
}
var newFrame = CGRectMake(newX["origin"] || currentFrame.origin.x, newY["origin"] || currentFrame.origin.y, newX["size"] || currentFrame.size.width, newY["size"] || currentFrame.size.height);
}
[self setFrame:newFrame];
}
- (void)mouseUp:(CPEvent)anEvent
{
dragBeginPoint = nil;
resizeMask = nil;
// register the undo here
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment