Archived
1
This repository has been archived on 2022-08-08. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
mathpad/MathPad/MPFunctionLayout.m
Kim Wittenburg 82259f87e2 Model Redesign: Added Reference Frames
Added Inverse Functions
UI Redesign
Cleaned Code
2014-10-07 20:25:54 +02:00

143 lines
4.2 KiB
Objective-C

//
// MPFunctionLayout.m
// MathPad
//
// Created by Kim Wittenburg on 07.08.14.
// Copyright (c) 2014 Kim Wittenburg. All rights reserved.
//
#import "MPFunctionLayout.h"
#import "MPFunction.h"
#import "MPExpressionLayout.h"
#import "MPSumFunction.h"
#import "MPSumFunctionLayout.h"
#import "MPParenthesisFunction.h"
#import "MPParenthesisFunctionLayout.h"
#import "MPPowerFunctionLayout.h"
#import "NSIndexPath+MPAdditions.h"
@implementation MPFunctionLayout
#pragma mark Creation Methods
+ (MPFunctionLayout *)functionLayoutForFunction:(MPFunction *)function
parent:(MPExpressionLayout *)parent
{
Class class = [function class];
if (class == [MPSumFunction class]) {
return [[MPSumFunctionLayout alloc] initWithFunction:function parent:parent];
} else if (class == [MPParenthesisFunction class]) {
return [[MPParenthesisFunctionLayout alloc] initWithFunction:function parent:parent];
} else if (class == [MPPowerFunction class]) {
return [[MPPowerFunctionLayout alloc] initWithFunction:function parent:parent];
}
return [[self alloc] initWithFunction:function
parent:parent];
}
- (instancetype)initWithFunction:(MPFunction *)function
parent:(MPExpressionLayout *)parent
{
self = [super initWithParent:parent];
if (self) {
_function = function;
}
return self;
}
#pragma mark Cache Methods
- (CTLineRef)lineForPrivateCacheIndex:(NSUInteger)index
generator:(CTLineRef (^)())generator
{
NSUInteger actualIndex = self.function.numberOfChildren + index;
id (^actualGenerator)() = ^{
CTLineRef line = generator();
return CFBridgingRelease(line);
};
id lineObject = [self cachableObjectForIndex:actualIndex
generator:actualGenerator];
return (__bridge CTLineRef)(lineObject);
}
- (id)objectForPrivateCacheIndex:(NSUInteger)index
generator:(id (^)())generator
{
NSUInteger actualIndex = self.function.numberOfChildren + index;
return [self cachableObjectForIndex:actualIndex generator:generator];
}
- (MPLayout *)childLayoutAtIndex:(NSUInteger)index
{
return [self cachableObjectForIndex:index generator:^id{
MPExpression *child = [self.function childAtIndex:index];
MPExpressionLayout *layout = [[MPExpressionLayout alloc] initWithExpression:child
parent:self];
layout.flipped = self.flipped;
layout.usesSmallSize = self.usesSmallSize ? YES : [self childAtIndexUsesSmallSize:index];
return layout;
}];
}
- (BOOL)childAtIndexUsesSmallSize:(NSUInteger)index
{
return NO;
}
- (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];
}
}
return [self indexPathForLocalMousePoint:point];
}
- (NSUInteger)indexOfLeadingChild
{
return 0;
}
- (NSUInteger)indexOfTrailingChild
{
return 0;
}
- (NSUInteger)indexOfChildBeforeChildAtIndex:(NSUInteger)index
{
return NSNotFound;
}
- (NSUInteger)indexOfChildAfterChildAtIndex:(NSUInteger)index
{
return NSNotFound;
}
- (NSUInteger)indexOfChildBelowChildAtIndex:(NSUInteger)index
{
return index;
}
- (NSUInteger)indexOfChildAboveChildAtIndex:(NSUInteger)index
{
return index;
}
- (NSIndexSet *)indexesOfRemainingChildren
{
return [NSIndexSet indexSet];
}
@end