161 lines
6.2 KiB
Objective-C
161 lines
6.2 KiB
Objective-C
//
|
|
// MPSumFunctionLayout.m
|
|
// MathPad
|
|
//
|
|
// Created by Kim Wittenburg on 23.04.14.
|
|
// Copyright (c) 2014 Kim Wittenburg. All rights reserved.
|
|
//
|
|
|
|
#import "MPSumFunctionLayout.h"
|
|
#import "MPSumFunction.h"
|
|
|
|
#import "NSIndexPath+MPAdditions.h"
|
|
|
|
#define kSumFunctionStartExpressionOffset 3
|
|
#define kSumFunctionTargetExpressionOffset 0
|
|
#define kSumFunctionSumExpressionOffset 3
|
|
#define kSumFunctionTrailingOffset 5
|
|
|
|
@implementation MPSumFunctionLayout
|
|
|
|
- (MPSumFunction *)sumFunction
|
|
{
|
|
return (MPSumFunction *)self.function;
|
|
}
|
|
|
|
- (NSUInteger)indexOfLeadingChild
|
|
{
|
|
return 2;
|
|
}
|
|
|
|
- (NSUInteger)indexOfTrailingChild
|
|
{
|
|
return 2;
|
|
}
|
|
|
|
- (CTLineRef)line
|
|
{
|
|
CTLineRef line = [self lineForPrivateCacheIndex:0 generator:^CTLineRef{
|
|
return [self createLineForString:@"∑"];
|
|
}];
|
|
return line;
|
|
}
|
|
|
|
- (NSRect)localLineBounds
|
|
{
|
|
NSRect lineBounds = CTLineGetBoundsWithOptions(self.line, 0);
|
|
CGFloat width = MAX(MAX([self childLayoutAtIndex:0].bounds.size.width, [self childLayoutAtIndex:1].bounds.size.width), lineBounds.size.width);
|
|
CGFloat xPosition = (width - lineBounds.size.width) / 2;
|
|
return NSMakeRect(xPosition, lineBounds.origin.y, lineBounds.size.width, lineBounds.size.height);
|
|
}
|
|
|
|
- (NSPoint)offsetOfChildLayoutAtIndex:(NSUInteger)index
|
|
{
|
|
NSRect childBounds = [self childLayoutAtIndex:index].bounds;
|
|
NSRect localLineBounds = [self localLineBounds];
|
|
NSPoint offset;
|
|
if (index == 0) {
|
|
// Start Expression
|
|
offset.x = localLineBounds.origin.x + localLineBounds.size.width / 2 - childBounds.size.width / 2;
|
|
offset.y = -kSumFunctionStartExpressionOffset - childBounds.size.height;
|
|
} else if (index == 1) {
|
|
// Target Expression
|
|
offset.x = localLineBounds.origin.x + localLineBounds.size.width / 2 - childBounds.size.width / 2;
|
|
offset.y = localLineBounds.size.height + kSumFunctionTargetExpressionOffset;
|
|
} else {
|
|
// Sum Expression
|
|
MPLayout *startExpressionLayout = [self childLayoutAtIndex:0];
|
|
MPLayout *targetExpressionLayout = [self childLayoutAtIndex:1];
|
|
CGFloat sumWidth = MAX(MAX(localLineBounds.origin.x + localLineBounds.size.width, startExpressionLayout.bounds.size.width), targetExpressionLayout.bounds.size.width);
|
|
offset.x = sumWidth + kSumFunctionSumExpressionOffset;
|
|
offset.y = 0;
|
|
}
|
|
return offset;
|
|
}
|
|
|
|
- (NSIndexPath *)indexPathForMousePoint:(NSPoint)point
|
|
{
|
|
// A single index is used to communicate back wether the
|
|
// selection should be before or after the function.
|
|
// A 0 means before, a 1 means after.
|
|
for (NSUInteger index = 0; index < self.function.numberOfChildren; index++) {
|
|
MPLayout *childLayout = [self childLayoutAtIndex:index];
|
|
NSRect childBounds = childLayout.bounds;
|
|
NSPoint childOffset = [self offsetOfChildLayoutAtIndex:index];
|
|
childBounds.origin.x += childOffset.x;
|
|
childBounds.origin.y += childOffset.y;
|
|
if (NSMouseInRect(point, childBounds, self.flipped)) {
|
|
NSPoint pointInChild = NSMakePoint(point.x - childOffset.x, point.y - childOffset.y);
|
|
NSIndexPath *subPath = [childLayout indexPathForMousePoint:pointInChild];
|
|
return [subPath indexPathByPreceedingIndex:index];
|
|
}
|
|
}
|
|
if (point.x < CTLineGetBoundsWithOptions(self.line, 0).size.width / 2) {
|
|
return [NSIndexPath indexPathWithIndex:0];
|
|
} else {
|
|
return [NSIndexPath indexPathWithIndex:1];
|
|
}
|
|
}
|
|
|
|
- (NSRect)generateBounds
|
|
{
|
|
NSRect lineBounds = CTLineGetBoundsWithOptions(self.line, 0);
|
|
NSRect startExpressionBounds = [self childLayoutAtIndex:0].bounds;
|
|
NSRect targetExpressionBounds = [self childLayoutAtIndex:1].bounds;
|
|
NSRect sumExpressionBounds = [self childLayoutAtIndex:2].bounds;
|
|
NSRect bounds = lineBounds;
|
|
|
|
bounds.size.width = MAX(lineBounds.size.width, startExpressionBounds.size.width);
|
|
bounds.size.height += startExpressionBounds.size.height + kSumFunctionStartExpressionOffset;
|
|
|
|
bounds.size.width = MAX(bounds.size.width, targetExpressionBounds.size.width);
|
|
bounds.size.height += targetExpressionBounds.size.height + kSumFunctionTargetExpressionOffset;
|
|
|
|
bounds.size.width += kSumFunctionSumExpressionOffset + sumExpressionBounds.size.width;
|
|
bounds.size.height = MAX(bounds.size.height, sumExpressionBounds.size.height);
|
|
|
|
bounds.origin.y -= targetExpressionBounds.size.height + kSumFunctionStartExpressionOffset;
|
|
bounds.size.width += kSumFunctionTrailingOffset;
|
|
return bounds;
|
|
}
|
|
|
|
- (void)draw
|
|
{
|
|
// Get the current context
|
|
CGContextRef context = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort];
|
|
|
|
// Set the text matrix
|
|
CGContextSetTextMatrix(context, CGAffineTransformIdentity);
|
|
|
|
// Draw the sum symbol
|
|
CTLineRef line = [self line];
|
|
CFRetain(line);
|
|
NSRect localLineBounds = [self localLineBounds];
|
|
CGContextSetTextPosition(context, localLineBounds.origin.x, 0);
|
|
CTLineDraw(line, context);
|
|
|
|
// Draw the start function
|
|
MPLayout *startExpressionLayout = [self childLayoutAtIndex:0];
|
|
NSPoint startExpressionLocation = NSMakePoint(localLineBounds.origin.x + localLineBounds.size.width / 2, 0);
|
|
startExpressionLocation.x -= startExpressionLayout.bounds.size.width / 2;
|
|
startExpressionLocation.y -= startExpressionLayout.bounds.size.height + kSumFunctionStartExpressionOffset;
|
|
[startExpressionLayout drawAtPoint:startExpressionLocation];
|
|
|
|
// Draw the target function
|
|
MPLayout *targetExpressionLayout = [self childLayoutAtIndex:1];
|
|
NSPoint targetExpressionLocation = NSMakePoint(localLineBounds.origin.x + localLineBounds.size.width / 2, localLineBounds.size.height);
|
|
targetExpressionLocation.x -= targetExpressionLayout.bounds.size.width / 2;
|
|
targetExpressionLocation.y += kSumFunctionTargetExpressionOffset;
|
|
[targetExpressionLayout drawAtPoint:targetExpressionLocation];
|
|
|
|
// Draw the sum function
|
|
MPLayout *sumExpressionLayout = [self childLayoutAtIndex:2];
|
|
CGFloat sumWidth = MAX(MAX(localLineBounds.origin.x + localLineBounds.size.width, startExpressionLayout.bounds.size.width), targetExpressionLayout.bounds.size.width);
|
|
sumWidth += kSumFunctionSumExpressionOffset;
|
|
[sumExpressionLayout drawAtPoint:NSMakePoint(sumWidth, 0)];
|
|
|
|
CFRelease(line);
|
|
}
|
|
|
|
@end
|