//
// MPFunctionLayout.h
// MathPad
//
// Created by Kim Wittenburg on 07.08.14.
// Copyright (c) 2014 Kim Wittenburg. All rights reserved.
//
#import "MPLayout.h"
/*!
@header
This file contains the MPFunctionLayout class.
The MPFunctionLayout class is an abstract class that implements
many of the methods from the layout system. Concrete subclasses implement the
actual layout of a specific function and its children. For that reason
MPFunctionLayout features a private cache. In that cache any
subclass can store objects so they do not need to be recreated everytime the
function is rendered.
*/
@class MPFunctionLayout, MPFunction, MPExpressionLayout;
/*!
@class MPFunctionLayout
@abstract A function layout represents a @link
//apple_ref/occ/cl/MPFunction@/link.
@discussion MPFunctionLayout is an abstract class that
implements many required methods of the layout system. For more
information about the layout system see the documentation on the
@link //apple_ref/occ/cl/MPLayout@/link class.
*/
@interface MPFunctionLayout : MPLayout
/*!
@method functionLayoutForFunction:parent:
@abstract Creates a function layout that can draw the specified function.
@discussion This method is the preferred whay to construct function layouts.
@param function
The function to create a layout for. Must not be
nil.
@param parent
The parent of the created function layout. May be
nil.
@return A newly created function layout.
*/
+ (MPFunctionLayout *)functionLayoutForFunction:(MPFunction *)function
parent:(MPExpressionLayout *)parent;
/*!
@method initWithFunction:parent:
@abstract Initializes the receiver with the specified function and parent.
@discussion This method should not be called direcly. It is however possible
do perform custom initialization in sublcasses by overriding this method.
This method is the designated initializer of the
MPFunctionLayout class.
@param function
The function represented by the receiver. Must not be
nil.
@param parent
The parent of the receiver or nil if it does not
have one.
@return A newly initialized MPFunctionLayout instance.
*/
- (instancetype)initWithFunction:(MPFunction *)function
parent:(MPExpressionLayout *)parent;
/*!
@property function
@abstract The function represented by the receiver.
*/
@property (readonly, nonatomic, weak) MPFunction *function;
/*!
@method lineForPrivateCacheIndex:generator:
@abstract Returns the cached line for the specified private index.
@discussion This is a convenience method that calls @link
//apple_ref/occ/instm/MPFunctionLayout/objectForPrivateCacheIndex:generator:@/link.
See the documentation on that method for details.
@param index
The index of the line to retrieve. Private cache indexes start at 0.
@param generator
A block that generates a line in case there is no cached one.
@return The cached line or the newly generated one if there was no cache value.
*/
- (CTLineRef)lineForPrivateCacheIndex:(NSUInteger)index
generator:(CTLineRef (^)())generator;
/*!
@method objectForPrivateCacheIndex:generator:
@abstract Returns the cached value for the specified private index.
@discussion If there is no object in the private cache for the specified
index the specified generator is invoked. The result
of the generator is then stored at the specified
index and returned.
@param index
The index of the private cache item to retrieve. Private cache
indexes start at 0.
@param generator
A block that generates an object in case there is no cached one.
@return The cached object or the newly generated one if there was no
cache value.
*/
- (id)objectForPrivateCacheIndex:(NSUInteger)index
generator:(id (^)())generator;
@end
/*!
@category MPFunctionLayout (MPSubclassOverride)
@abstract The methods defined in this category must be implemented by any
concrete subclass of MPFunctionLayout.
*/
@interface MPFunctionLayout (MPSubclassOverride)
/* Apart from the methods below it is recommended (although not required) to
* implement a method in the following form:
* - (CustomFunctionType *)customFunction
* {
* return (CustomFunctionType *)self.function;
* }
*/
/*!
@method childAtIndexUsesSmallSize:
@abstract Determines whether the child expression at the specified index
should be drawn using the small font.
@discussion This method may be overridden to change the default behaviour.
@param index
The index of the child whose size is to be determined.
@return YES if the receiver's child at the specified
index should use the small font, NO
otherwise. The default implementation returns NO.
*/
- (BOOL)childAtIndexUsesSmallSize:(NSUInteger)index; // May be implemented
/*!
@method offsetOfChildLayoutAtIndex:
@abstract Implementation requirement from superclass. See @link
//apple_ref/occ/instm/MPLayout(MPSubclassImplement)/offsetOfChildLayoutAtIndex:@/link
for details.
*/
- (NSPoint)offsetOfChildLayoutAtIndex:(NSUInteger)index;
/*!
@method indexPathForLocalMousePoint:
@abstract Performs hit testing.
@discussion This method is called when the user selected a point in a
function that is not in any of its children. The return value of
this method identifies the position relative to the function
represented by the receiver where the caret is to be placed.
This method must be implemented by subclasses.
@param point
The location the user clicked at relative to the receiver.
@return An index path identifying the new caret position relative to the
function represented by the receiver. Use an index path
containing a single index to place the caret before or after the
represented function (0 means before, 1
means after).
*/
- (NSIndexPath *)indexPathForLocalMousePoint:(NSPoint)point;
/*!
@method generateBounds
@abstract Implementation requirement from superclass. See @link
//apple_ref/occ/instm/MPLayout(MPSubclassImplement)/generateBounds@/link
for details.
*/
- (NSRect)generateBounds;
/*!
@method draw
@abstract Implementation requirement from superclass. See @link
//apple_ref/occ/instm/MPLayout(MPSubclassImplement)/draw@/link
for details.
*/
- (void)draw;
/*!
@method indexOfLeadingChild
@abstract Identifies the index of the receiver's child that will get
selected when the cursor enters the function in the
direction of reading.
@discussion You may implement this method do override the default behaviour.
@return The index of the leading child. The default implementation
returns 0.
*/
- (NSUInteger)indexOfLeadingChild;
/*!
@method indexOfTrailingChild
@abstract Identifies the index of the receiver's child that will get
selected when the cursor enters the function in the
direction opposite to reading.
@discussion You may implement this method do override the default behaviour.
@return The index of the trailing child. The default implementation
returns 0.
*/
- (NSUInteger)indexOfTrailingChild;
/*!
@method indexOfChildBeforeChildAtIndex:
@abstract Identifies the index of the receiver's child that will get
selected when the cursor leaves the child at the specified
index in the direction opposite to reading.
@discussion Return NSNotFound from this method if the function
should be left when the child at the specified index is
left.
You may implement this method to override the default behaviour.
@param index
The index of the child the caret left.
@return The index of the child that is to be entered or
NSNotFound if there are no more children. The
default implementation returns NSNotFound.
*/
- (NSUInteger)indexOfChildBeforeChildAtIndex:(NSUInteger)index;
/*!
@method indexOfChildAfterChildAtIndex:
@abstract Identifies the index of the receiver's child that will get
selected when the cursor leaves the child at the specified
index in the direction of reading.
@discussion Return NSNotFound from this method if the function
should be left when the child at the specified index is
left.
You may implement this method to override the default behaviour.
@param index
The index of the child the caret left.
@return The index of the child that is to be entered or
NSNotFound if there are no more children.
*/
- (NSUInteger)indexOfChildAfterChildAtIndex:(NSUInteger)index;
/*!
@method indexOfChildBelowChildAtIndex:
@abstract Returns the index of the child that is graphically positioned
below the child at the specified index.
@discussion If there are no other children below the one at the specified
index this method should return index.
You may implement this method to override the default behaviour.
@param index
The index of the child whose neighbor is to be determined.
@return The index of the child directly below the one at the specified
index. The default implementation returns index.
*/
- (NSUInteger)indexOfChildBelowChildAtIndex:(NSUInteger)index;
/*!
@method indexOfChildAboveChildAtIndex:
@abstract Returns the index of the child that is graphically positioned
above the child at the specified index.
@discussion If there are no other children above the one at the specified
index this method should return index.
You may implement this method to override the default behaviour.
@param index
The index of the child whose neighbor is to be determined.
@return The index of the child directly above the one at the specified
index. The default implementation returns index.
*/
- (NSUInteger)indexOfChildAboveChildAtIndex:(NSUInteger)index;
/*!
@method indexesOfRemainingChildren
@abstract Returns the indexes of the receiver's children that should
replace the receiver if it is deleted.
@discussion You may implement this method to override the default behaviour.
@return The indexes of the children that replace the receiver when it is
deleted. The default implementation returns an empty index set.
*/
- (NSIndexSet *)indexesOfRemainingChildren;
@end