Archived
1

Improved Functions Template Chooser

This commit is contained in:
Kim Wittenburg
2014-09-30 22:19:08 +02:00
parent a382b1f10b
commit 8f2f773909
3 changed files with 79 additions and 65 deletions

View File

@@ -24,7 +24,7 @@
@interface MPExpressionView () @interface MPExpressionView ()
@property (nonatomic, weak) NSButton *functionsButton; @property (nonatomic, strong) NSButton *functionsButton;
@property (nonatomic, strong) NSPopover *functionsPopover; @property (nonatomic, strong) NSPopover *functionsPopover;
@property (nonatomic, strong) MPFunctionsViewController *functionsViewController; @property (nonatomic, strong) MPFunctionsViewController *functionsViewController;
@@ -312,30 +312,31 @@
expressionStorage.expressionView = self; expressionStorage.expressionView = self;
_expressionStorage = expressionStorage; _expressionStorage = expressionStorage;
NSBundle *frameworkBundle = [NSBundle bundleForClass:[self class]]; [self initializeButtons];
NSImage *image = [frameworkBundle imageForResource:@"FunctionsButtonDisclosure"];
[image setName:@"FunctionsButtonDisclosure"];
// Setup the Functions Button
NSButton *button = [[NSButton alloc] initWithFrame:NSZeroRect];
button.target = self;
button.action = @selector(showFunctions:);
button.buttonType = NSMomentaryChangeButton;
button.bezelStyle = NSShadowlessSquareBezelStyle;
button.bordered = NO;
NSFont *font = [NSFont fontWithName:@"Times New Roman" size:25.0];
NSAttributedString *attributedTitle = [[NSAttributedString alloc] initWithString:@"Σ" attributes:@{NSFontAttributeName: font, NSForegroundColorAttributeName: [NSColor colorWithWhite:.61 alpha:1]}];
button.attributedTitle = attributedTitle;
button.imagePosition = NSImageLeft;
button.image = image;
self.functionsButton = button;
[self addSubview:self.functionsButton];
// Setup Selection
self.selection = [[MPRangePath alloc] initWithRange:NSMakeRange(0, 0)]; self.selection = [[MPRangePath alloc] initWithRange:NSMakeRange(0, 0)];
self.caretBlinkRate = 1.0; self.caretBlinkRate = 1.0;
[self restartCaretTimer]; [self restartCaretTimer];
} }
- (void)initializeButtons
{
NSButton *functionsButton = self.functionsButton;
[self addSubview:functionsButton];
NSDictionary *variableBindings = NSDictionaryOfVariableBindings(functionsButton);
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"[functionsButton]-10-|"
options:0
metrics:nil
views:variableBindings]];
[self addConstraint:[NSLayoutConstraint constraintWithItem:functionsButton
attribute:NSLayoutAttributeCenterY
relatedBy:NSLayoutRelationEqual
toItem:self
attribute:NSLayoutAttributeCenterY
multiplier:1
constant:0]];
}
#pragma mark Properties #pragma mark Properties
- (void)setExpressionStorage:(MPExpressionStorage *)expressionStorage - (void)setExpressionStorage:(MPExpressionStorage *)expressionStorage
{ {
@@ -358,6 +359,29 @@
self.needsDisplay = YES; self.needsDisplay = YES;
} }
- (NSButton *)functionsButton
{
if (!_functionsButton) {
NSBundle *frameworkBundle = [NSBundle bundleForClass:[self class]];
NSImage *image = [frameworkBundle imageForResource:@"FunctionsButtonDisclosure"];
[image setName:@"FunctionsButtonDisclosure"];
NSButton *button = [[NSButton alloc] initWithFrame:NSMakeRect(0, 0, 100, 100)];
button.translatesAutoresizingMaskIntoConstraints = NO;
button.target = self;
button.action = @selector(showFunctions:);
button.buttonType = NSMomentaryChangeButton;
button.bezelStyle = NSShadowlessSquareBezelStyle;
button.bordered = NO;
NSFont *font = [NSFont fontWithName:@"Times New Roman" size:25.0];
NSAttributedString *attributedTitle = [[NSAttributedString alloc] initWithString:@"Σ" attributes:@{NSFontAttributeName: font, NSForegroundColorAttributeName: [NSColor colorWithWhite:.61 alpha:1]}];
button.attributedTitle = attributedTitle;
button.imagePosition = NSImageLeft;
button.image = image;
_functionsButton = button;
}
return _functionsButton;
}
#pragma mark Actions #pragma mark Actions
- (void)showFunctions:(id)sender - (void)showFunctions:(id)sender
{ {
@@ -429,16 +453,6 @@
[super setFrame:frameRect]; [super setFrame:frameRect];
} }
- (void)layout
{
NSSize buttonSize = [self.functionsButton fittingSize];
self.functionsButton.frame = NSMakeRect(self.bounds.size.width - buttonSize.width - 10,
(self.bounds.size.height - buttonSize.height) / 2,
buttonSize.width,
buttonSize.height);
[super layout];
}
- (NSSize)intrinsicContentSize - (NSSize)intrinsicContentSize
{ {
NSSize size = self.expressionStorage.rootLayout.bounds.size; NSSize size = self.expressionStorage.rootLayout.bounds.size;
@@ -458,7 +472,7 @@
NSString *characters = theEvent.characters; NSString *characters = theEvent.characters;
if ([characters isEqualToString:@"("]) { if ([characters isEqualToString:@"("]) {
[self insertParenthesisFunction]; [self insertParenthesisFunction:nil];
return; return;
} }
@@ -466,7 +480,7 @@
NSString *decimalSeparator = [NSRegularExpression escapedPatternForString:[[NSLocale currentLocale] objectForKey:NSLocaleDecimalSeparator]]; NSString *decimalSeparator = [NSRegularExpression escapedPatternForString:[[NSLocale currentLocale] objectForKey:NSLocaleDecimalSeparator]];
NSMutableCharacterSet *allowedCharacters = [NSMutableCharacterSet alphanumericCharacterSet]; NSMutableCharacterSet *allowedCharacters = [NSMutableCharacterSet alphanumericCharacterSet];
[allowedCharacters addCharactersInString:[NSString stringWithFormat:@"+-*= %@", decimalSeparator]]; [allowedCharacters addCharactersInString:[NSString stringWithFormat:@"+-*= !%@", decimalSeparator]];
if (characters.length == 1 && [characters stringByTrimmingCharactersInSet:allowedCharacters].length == 0) { if (characters.length == 1 && [characters stringByTrimmingCharactersInSet:allowedCharacters].length == 0) {
[self.expressionStorage replaceSymbolsInRangePath:self.selection withElements:@[characters]]; [self.expressionStorage replaceSymbolsInRangePath:self.selection withElements:@[characters]];
@@ -476,7 +490,7 @@
} }
} }
- (void)insertParenthesisFunction - (void)insertParenthesisFunction:(id)sender
{ {
MPExpression *selectedElementsExpression = [self.expressionStorage subexpressionWithRangePath:self.selection]; MPExpression *selectedElementsExpression = [self.expressionStorage subexpressionWithRangePath:self.selection];
MPParenthesisFunction *function = [[MPParenthesisFunction alloc] init]; MPParenthesisFunction *function = [[MPParenthesisFunction alloc] init];
@@ -700,7 +714,7 @@
MPExpression *newTargetExpression = [self.expressionStorage elementAtIndexPath:newTargetExpressionPath]; MPExpression *newTargetExpression = [self.expressionStorage elementAtIndexPath:newTargetExpressionPath];
NSIndexPath *newSelectionLocation = [functionPath indexPathByReplacingLastIndexWithIndex:[newTargetExpression locationOfElementAtIndex:functionPath.lastIndex]]; NSIndexPath *newSelectionLocation = [functionPath indexPathByReplacingLastIndexWithIndex:[newTargetExpression locationOfElementAtIndex:functionPath.lastIndex]];
[self.expressionStorage replaceSymbolsInRangePath:MPMakeRangePath(functionPath, 1) withElements:remainder]; [self.expressionStorage replaceSymbolsInRangePath:MPMakeRangePath(newSelectionLocation, 1) withElements:remainder];
self.selection = MPMakeRangePath(newSelectionLocation, 0); self.selection = MPMakeRangePath(newSelectionLocation, 0);
} }
} }

View File

@@ -14,11 +14,11 @@
#import "MPParenthesisFunction.h" #import "MPParenthesisFunction.h"
@class MPFunctionTemplatePrototype; @class MPFunctionTemplateItem;
@interface MPFunctionsCollectionView : NSCollectionView @interface MPFunctionsCollectionView : NSCollectionView
@property (nonatomic, weak) MPFunctionTemplatePrototype *hoverItem; @property (nonatomic, weak) MPFunctionTemplateItem *hoverItem;
@property (nonatomic, weak) id target; @property (nonatomic, weak) id target;
@property (nonatomic) SEL action; @property (nonatomic) SEL action;
@@ -37,7 +37,8 @@
@interface MPFunctionTemplatePrototype : NSCollectionViewItem @interface MPFunctionTemplateItem : NSCollectionViewItem
@property (nonatomic, copy) NSString *templateName;
@end @end
@@ -56,7 +57,7 @@
if (NSMouseInRect(pointInView, viewItem.view.frame, self.isFlipped)) { if (NSMouseInRect(pointInView, viewItem.view.frame, self.isFlipped)) {
if (self.target && self.action) { if (self.target && self.action) {
[self.target performSelector:self.action [self.target performSelector:self.action
withObject:[viewItem.representedObject copy] withObject:[[viewItem.representedObject objectForKey:@"function" ] copy]
afterDelay:0.0]; afterDelay:0.0];
} }
break; break;
@@ -103,6 +104,7 @@
@synthesize functionTemplateLayout = _functionTemplateLayout; @synthesize functionTemplateLayout = _functionTemplateLayout;
- (MPFunctionLayout *)functionTemplateLayout - (MPFunctionLayout *)functionTemplateLayout
{ {
if (!_functionTemplateLayout) { if (!_functionTemplateLayout) {
_functionTemplateLayout = [MPFunctionLayout functionLayoutForFunction:self.functionTemplate _functionTemplateLayout = [MPFunctionLayout functionLayoutForFunction:self.functionTemplate
parent:nil]; parent:nil];
@@ -140,21 +142,13 @@
@implementation MPFunctionTemplatePrototype @implementation MPFunctionTemplateItem
static void *MPFunctionTemplateViewMouseOverContext = @"MPFunctionTemplateViewMouseOverContext"; static void *MPFunctionTemplateViewMouseOverContext = @"MPFunctionTemplateViewMouseOverContext";
- (id)initWithCoder:(NSCoder *)aDecoder - (id)awakeAfterUsingCoder:(NSCoder *)aDecoder
{ {
self = [super initWithCoder:aDecoder]; return [super awakeAfterUsingCoder:aDecoder];
if (self) {
MPFunctionTemplateView *view = (MPFunctionTemplateView *)self.view;
[view addObserver:self
forKeyPath:@"mouseOver"
options:0
context:MPFunctionTemplateViewMouseOverContext];
}
return self;
} }
- (void)observeValueForKeyPath:(NSString *)keyPath - (void)observeValueForKeyPath:(NSString *)keyPath
@@ -175,8 +169,14 @@ static void *MPFunctionTemplateViewMouseOverContext = @"MPFunctionTemplateViewMo
- (void)setRepresentedObject:(id)representedObject - (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]; [super setRepresentedObject:representedObject];
((MPFunctionTemplateView *)self.view).functionTemplate = representedObject;
} }
@end @end
@@ -195,21 +195,14 @@ static void *MPFunctionTemplateViewMouseOverContext = @"MPFunctionTemplateViewMo
bundle:[NSBundle bundleForClass:[self class]]]; bundle:[NSBundle bundleForClass:[self class]]];
} }
- (id)initWithNibName:(NSString *)nibNameOrNil - (void)awakeFromNib
bundle:(NSBundle *)nibBundleOrNil
{ {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; self.functionPrototypes = @[
if (self) { @{@"function": [[MPSumFunction alloc] init],
self.functionPrototypes = @[[[MPSumFunction alloc] init], [[MPParenthesisFunction alloc] init]]; @"name": NSLocalizedString(@"Sum", @"Sum Function Name")},
} @{@"function": [[MPParenthesisFunction alloc] init],
return self; @"name": NSLocalizedString(@"Parenthesis", @"Parenthesis Function Name")}
} ];
static void *MPCollectionViewHoverItemChangeContext = @"MPCollectionViewHoverItemChangeContext";
- (void)loadView
{
[super loadView];
[self.collectionView addObserver:self [self.collectionView addObserver:self
forKeyPath:@"hoverItem" forKeyPath:@"hoverItem"
options:0 options:0
@@ -218,6 +211,13 @@ static void *MPCollectionViewHoverItemChangeContext = @"MPCollectionViewHoverIte
self.collectionView.action = self.action; self.collectionView.action = self.action;
} }
static void *MPCollectionViewHoverItemChangeContext = @"MPCollectionViewHoverItemChangeContext";
- (void)setView:(NSView *)view
{
[super setView:view];
}
- (void)setTarget:(id)target - (void)setTarget:(id)target
{ {
_target = target; _target = target;
@@ -240,7 +240,7 @@ static void *MPCollectionViewHoverItemChangeContext = @"MPCollectionViewHoverIte
context:(void *)context context:(void *)context
{ {
if (context == MPCollectionViewHoverItemChangeContext) { if (context == MPCollectionViewHoverItemChangeContext) {
self.currentDescription = [[self.collectionView.hoverItem.representedObject class] performSelector:@selector(localizedFunctionName)]; self.currentDescription = self.collectionView.hoverItem.templateName;
} else { } else {
[super observeValueForKeyPath:keyPath [super observeValueForKeyPath:keyPath
ofObject:object ofObject:object

View File

@@ -69,7 +69,7 @@
</constraints> </constraints>
<point key="canvasLocation" x="-101" y="140.5"/> <point key="canvasLocation" x="-101" y="140.5"/>
</customView> </customView>
<collectionViewItem id="4Wf-e2-Nmy" customClass="MPFunctionTemplatePrototype"> <collectionViewItem id="4Wf-e2-Nmy" customClass="MPFunctionTemplateItem">
<connections> <connections>
<outlet property="view" destination="dE9-Vu-psk" id="hX8-fz-7FR"/> <outlet property="view" destination="dE9-Vu-psk" id="hX8-fz-7FR"/>
</connections> </connections>