// // MPFunctionLayout.h // MathKit // // 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