Reorganized File Structure
Added Documentation
This commit is contained in:
272
MathKit/MPFunctionsViewController.m
Normal file
272
MathKit/MPFunctionsViewController.m
Normal file
@@ -0,0 +1,272 @@
|
||||
//
|
||||
// MPFunctionsViewController.m
|
||||
// MathPad
|
||||
//
|
||||
// Created by Kim Wittenburg on 28.09.14.
|
||||
// Copyright (c) 2014 Kim Wittenburg. All rights reserved.
|
||||
//
|
||||
|
||||
#import "MPFunctionsViewController.h"
|
||||
|
||||
#import "MPExpression.h"
|
||||
#import "NSString+MPExpressionElement.h"
|
||||
#import "MPFunction.h"
|
||||
#import "MPSumFunction.h"
|
||||
#import "MPParenthesisFunction.h"
|
||||
#import "MPPowerFunction.h"
|
||||
#import "MPFractionFunction.h"
|
||||
|
||||
#import "MPFunctionLayout.h"
|
||||
|
||||
@class MPFunctionsCollectionView, MPFunctionTemplateView, MPFunctionTemplateItem;
|
||||
|
||||
@interface MPFunctionsCollectionView : NSCollectionView
|
||||
|
||||
@property (nonatomic, weak) MPFunctionTemplateItem *hoverItem;
|
||||
|
||||
@property (nonatomic, weak) id target;
|
||||
@property (nonatomic) SEL action;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@interface MPFunctionTemplateView : NSView
|
||||
|
||||
@property (nonatomic, strong) MPFunction *functionTemplate;
|
||||
@property (readonly, nonatomic, strong) MPFunctionLayout *functionTemplateLayout;
|
||||
@property (nonatomic, strong) NSTrackingArea *trackingArea;
|
||||
@property (nonatomic) BOOL mouseOver;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
|
||||
@interface MPFunctionTemplateItem : NSCollectionViewItem
|
||||
@property (nonatomic, copy) NSString *templateName;
|
||||
@end
|
||||
|
||||
|
||||
@implementation MPFunctionsCollectionView
|
||||
|
||||
- (void)mouseDown:(NSEvent *)theEvent
|
||||
{
|
||||
}
|
||||
|
||||
- (void)mouseUp:(NSEvent *)theEvent
|
||||
{
|
||||
NSPoint pointInView = [self convertPoint:theEvent.locationInWindow
|
||||
fromView:nil];
|
||||
for (NSUInteger index = 0; index < self.content.count; index++) {
|
||||
NSCollectionViewItem *viewItem = [self itemAtIndex:index];
|
||||
if (NSMouseInRect(pointInView, viewItem.view.frame, self.isFlipped)) {
|
||||
if (self.target && self.action) {
|
||||
[self.target performSelector:self.action
|
||||
withObject:[[viewItem.representedObject objectForKey:@"function" ] copy]
|
||||
afterDelay:0.0];
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
|
||||
@implementation MPFunctionTemplateView
|
||||
|
||||
- (void)updateTrackingAreas
|
||||
{
|
||||
if (!self.trackingArea) {
|
||||
self.trackingArea = [[NSTrackingArea alloc] initWithRect:self.bounds
|
||||
options:NSTrackingMouseEnteredAndExited|NSTrackingActiveInKeyWindow|NSTrackingInVisibleRect
|
||||
owner:self
|
||||
userInfo:nil];
|
||||
[self addTrackingArea:self.trackingArea];
|
||||
}
|
||||
[super updateTrackingAreas];
|
||||
}
|
||||
|
||||
- (void)mouseEntered:(NSEvent *)theEvent
|
||||
{
|
||||
self.mouseOver = YES;
|
||||
self.needsDisplay = YES;
|
||||
}
|
||||
|
||||
- (void)mouseExited:(NSEvent *)theEvent
|
||||
{
|
||||
self.mouseOver = NO;
|
||||
self.needsDisplay = YES;
|
||||
}
|
||||
|
||||
- (void)setFunctionTemplate:(MPFunction *)functionTemplate
|
||||
{
|
||||
_functionTemplate = functionTemplate;
|
||||
_functionTemplateLayout = nil;
|
||||
}
|
||||
|
||||
@synthesize functionTemplateLayout = _functionTemplateLayout;
|
||||
- (MPFunctionLayout *)functionTemplateLayout
|
||||
{
|
||||
|
||||
if (!_functionTemplateLayout) {
|
||||
_functionTemplateLayout = [MPFunctionLayout functionLayoutForFunction:self.functionTemplate
|
||||
parent:nil];
|
||||
_functionTemplateLayout.usesSmallSize = YES;
|
||||
}
|
||||
return _functionTemplateLayout;
|
||||
}
|
||||
|
||||
- (NSSize)intrinsicContentSize
|
||||
{
|
||||
return [self.functionTemplateLayout bounds].size;
|
||||
}
|
||||
|
||||
- (BOOL)isOpaque
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (void)drawRect:(NSRect)dirtyRect
|
||||
{
|
||||
if (self.mouseOver) {
|
||||
[[NSColor selectedTextBackgroundColor] set];
|
||||
NSBezierPath *background = [NSBezierPath bezierPathWithRoundedRect:self.bounds
|
||||
xRadius:10
|
||||
yRadius:10];
|
||||
[background fill];
|
||||
}
|
||||
[[NSColor textColor] set];
|
||||
NSPoint origin = NSMakePoint((self.bounds.size.width - self.functionTemplateLayout.bounds.size.width) / 2, (self.bounds.size.height - self.functionTemplateLayout.bounds.size.height) / 2);
|
||||
origin.y -= self.functionTemplateLayout.bounds.origin.y;
|
||||
[self.functionTemplateLayout drawAtPoint:origin];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
|
||||
@implementation MPFunctionTemplateItem
|
||||
|
||||
static void *MPFunctionTemplateViewMouseOverContext = @"MPFunctionTemplateViewMouseOverContext";
|
||||
|
||||
- (id)awakeAfterUsingCoder:(NSCoder *)aDecoder
|
||||
{
|
||||
return [super awakeAfterUsingCoder:aDecoder];
|
||||
}
|
||||
|
||||
- (void)observeValueForKeyPath:(NSString *)keyPath
|
||||
ofObject:(id)object
|
||||
change:(NSDictionary *)change
|
||||
context:(void *)context
|
||||
{
|
||||
if (context == MPFunctionTemplateViewMouseOverContext) {
|
||||
MPFunctionTemplateView *view = (MPFunctionTemplateView *)self.view;
|
||||
((MPFunctionsCollectionView *)self.collectionView).hoverItem = view.mouseOver ? self : nil;
|
||||
} else {
|
||||
[super observeValueForKeyPath:keyPath
|
||||
ofObject:object
|
||||
change:change
|
||||
context:context];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setRepresentedObject:(id)representedObject
|
||||
{
|
||||
MPFunctionTemplateView *view = (MPFunctionTemplateView *)self.view;
|
||||
view.functionTemplate = [representedObject objectForKey:@"function"];
|
||||
self.templateName = [representedObject objectForKey:@"name"];
|
||||
[view addObserver:self
|
||||
forKeyPath:@"mouseOver"
|
||||
options:0
|
||||
context:MPFunctionTemplateViewMouseOverContext];
|
||||
[super setRepresentedObject:representedObject];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
|
||||
@interface MPFunctionsViewController ()
|
||||
|
||||
@end
|
||||
|
||||
@implementation MPFunctionsViewController
|
||||
|
||||
- (id)init
|
||||
{
|
||||
return [self initWithNibName:@"MPFunctionsViewController"
|
||||
bundle:[NSBundle bundleForClass:[self class]]];
|
||||
}
|
||||
|
||||
- (void)awakeFromNib
|
||||
{
|
||||
MPFunction *sumFunction = [[MPSumFunction alloc] init];
|
||||
MPFunction *parenthesisFunction = [[MPParenthesisFunction alloc] init];
|
||||
MPFunction *powerFunction = [[MPPowerFunction alloc] init];
|
||||
MPPowerFunction *squareFunction = [[MPPowerFunction alloc] init];
|
||||
squareFunction.exponentExpression = [[MPExpression alloc] initWithElement:@"2"];
|
||||
MPPowerFunction *cubicFunction = [[MPPowerFunction alloc] init];
|
||||
cubicFunction.exponentExpression = [[MPExpression alloc] initWithElement:@"3"];
|
||||
MPFractionFunction *fractionFunction = [[MPFractionFunction alloc] init];
|
||||
self.functionPrototypes = @[
|
||||
@{@"function": sumFunction,
|
||||
@"name": NSLocalizedString(@"Sum", @"Sum Function Name")},
|
||||
@{@"function": parenthesisFunction,
|
||||
@"name": NSLocalizedString(@"Parenthesis", @"Parenthesis Function Name")},
|
||||
@{@"function": squareFunction,
|
||||
@"name": NSLocalizedString(@"Square", @"Square Function Name")},
|
||||
@{@"function": cubicFunction,
|
||||
@"name": NSLocalizedString(@"Cubic", @"Cubic Function Name")},
|
||||
@{@"function": powerFunction,
|
||||
@"name": NSLocalizedString(@"Power", @"Power Function Name")},
|
||||
@{@"function": fractionFunction,
|
||||
@"name": NSLocalizedString(@"Fraction", @"Fraction Function Name")}
|
||||
];
|
||||
[self.collectionView addObserver:self
|
||||
forKeyPath:@"hoverItem"
|
||||
options:0
|
||||
context:MPCollectionViewHoverItemChangeContext];
|
||||
self.collectionView.target = self.target;
|
||||
self.collectionView.action = self.action;
|
||||
}
|
||||
|
||||
static void *MPCollectionViewHoverItemChangeContext = @"MPCollectionViewHoverItemChangeContext";
|
||||
|
||||
- (void)setView:(NSView *)view
|
||||
{
|
||||
[super setView:view];
|
||||
}
|
||||
|
||||
- (void)setTarget:(id)target
|
||||
{
|
||||
_target = target;
|
||||
if (self.collectionView) {
|
||||
self.collectionView.target = target;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setAction:(SEL)action
|
||||
{
|
||||
_action = action;
|
||||
if (self.collectionView) {
|
||||
self.collectionView.action = action;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)observeValueForKeyPath:(NSString *)keyPath
|
||||
ofObject:(id)object
|
||||
change:(NSDictionary *)change
|
||||
context:(void *)context
|
||||
{
|
||||
if (context == MPCollectionViewHoverItemChangeContext) {
|
||||
self.currentDescription = self.collectionView.hoverItem.templateName;
|
||||
} else {
|
||||
[super observeValueForKeyPath:keyPath
|
||||
ofObject:object
|
||||
change:change
|
||||
context:context];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
Reference in New Issue
Block a user