git.y1.nz

SameBoy

Accurate GB/GBC emulator
download: https://git.y1.nz/archives/sameboy.tar.gz
README | Files | Log | Refs | LICENSE

HexFiend/HFController.h

      1 //
      2 //  HFController.h
      3 //  HexFiend_2
      4 //
      5 //  Copyright 2007 ridiculous_fish. All rights reserved.
      6 //
      7 
      8 #import <Cocoa/Cocoa.h>
      9 
     10 #import <HexFiend/HFTypes.h>
     11 
     12 /*! @header HFController
     13     @abstract The HFController.h header contains the HFController class, which is a central class in Hex Fiend. 
     14 */
     15 
     16 @class HFRepresenter, HFByteArray, HFFileReference, HFControllerCoalescedUndo, HFByteRangeAttributeArray;
     17 
     18 /*! @enum HFControllerPropertyBits
     19     The HFControllerPropertyBits bitmask is used to inform the HFRepresenters of a change in the current state that they may need to react to.  A bitmask of the changed properties is passed to representerChangedProperties:.  It is common for multiple properties to be included in such a bitmask.        
     20 */
     21 typedef NS_OPTIONS(NSUInteger, HFControllerPropertyBits) {
     22     HFControllerContentValue = 1 << 0,		/*!< Indicates that the contents of the ByteArray has changed within the document.  There is no indication as to what the change is.  If redisplaying everything is expensive, Representers should cache their displayed data and compute any changes manually. */
     23     HFControllerContentLength = 1 << 1,		/*!< Indicates that the length of the ByteArray has changed. */
     24     HFControllerDisplayedLineRange = 1 << 2,	/*!< Indicates that the displayedLineRange property of the document has changed (e.g. the user scrolled). */
     25     HFControllerSelectedRanges = 1 << 3,	/*!< Indicates that the selectedContentsRanges property of the document has changed (e.g. the user selected some other range). */    
     26     HFControllerSelectionPulseAmount = 1 << 4,	/*!< Indicates that the amount of "pulse" to show in the Find pulse indicator has changed. */    
     27     HFControllerBytesPerLine = 1 << 5,		/*!< Indicates that the number of bytes to show per line has changed. */        
     28     HFControllerBytesPerColumn = 1 << 6,	/*!< Indicates that the number of bytes per column (byte grouping) has changed. */
     29     HFControllerEditable = 1 << 7,		/*!< Indicates that the document has become (or is no longer) editable. */
     30     HFControllerFont = 1 << 8,			/*!< Indicates that the font property has changed. */
     31     HFControllerAntialias = 1 << 9,		/*!< Indicates that the shouldAntialias property has changed. */
     32     HFControllerLineHeight = 1 << 10,		/*!< Indicates that the lineHeight property has changed. */
     33     HFControllerViewSizeRatios = 1 << 11,	/*!< Indicates that the optimum size for each view may have changed; used by HFLayoutController after font changes. */
     34     HFControllerByteRangeAttributes = 1 << 12,  /*!< Indicates that some attributes of the ByteArray has changed within the document.  There is no indication as to what the change is. */
     35     HFControllerByteGranularity = 1 << 13,       /*!< Indicates that the byte granularity has changed.  For example, when moving from ASCII to UTF-16, the byte granularity increases from 1 to 2. */
     36     HFControllerBookmarks = 1 << 14,       /*!< Indicates that a bookmark has been added or removed. */
     37     HFControllerColorBytes = 1 << 15,   /*!< Indicates that the shouldColorBytes property has changed. */
     38     HFControllerShowCallouts = 1 << 16, /*!< Indicates that the shouldShowCallouts property has changed. */
     39     HFControllerHideNullBytes = 1 << 17, /*!< Indicates that the shouldHideNullBytes property has changed. */
     40 };
     41 
     42 /*! @enum HFControllerMovementDirection
     43     
     44 The HFControllerMovementDirection enum is used to specify a direction (either left or right) in various text editing APIs.  HexFiend does not support left-to-right languages.
     45 */
     46 typedef NS_ENUM(NSInteger, HFControllerMovementDirection) {
     47     HFControllerDirectionLeft,
     48     HFControllerDirectionRight
     49 };
     50 
     51 /*! @enum HFControllerSelectionTransformation
     52     
     53 The HFControllerSelectionTransformation enum is used to specify what happens to the selection in various APIs.  This is mainly interesting for text-editing style Representers.
     54 */
     55 typedef NS_ENUM(NSInteger, HFControllerSelectionTransformation) {
     56     HFControllerDiscardSelection,   /*!< The selection should be discarded. */
     57     HFControllerShiftSelection,	    /*!< The selection should be moved, without changing its length. */
     58     HFControllerExtendSelection	    /*!< The selection should be extended, changing its length. */
     59 };
     60 
     61 /*! @enum HFControllerMovementGranularity
     62     
     63 The HFControllerMovementGranularity enum is used to specify the granularity of text movement in various APIs.  This is mainly interesting for text-editing style Representers.
     64 */
     65 typedef NS_ENUM(NSInteger, HFControllerMovementGranularity) {
     66     HFControllerMovementByte, /*!< Move by individual bytes */
     67     HFControllerMovementColumn, /*!< Move by a column */
     68     HFControllerMovementLine, /*!< Move by lines */
     69     HFControllerMovementPage, /*!< Move by pages */
     70     HFControllerMovementDocument /*!< Move by the whole document */
     71 };
     72 
     73 /*! @enum HFEditMode
     74  
     75 HFEditMode enumerates the different edit modes that a document might be in.
     76  */
     77 typedef NS_ENUM(NSInteger, HFEditMode) {
     78     HFInsertMode,
     79     HFOverwriteMode,
     80     HFReadOnlyMode,
     81 } ;
     82 
     83 /*! @class HFController
     84 @brief A central class that acts as the controller layer for HexFiend.framework
     85 
     86 HFController acts as the controller layer in the MVC architecture of HexFiend.  The HFController plays several significant central roles, including:
     87  - Mediating between the data itself (in the HFByteArray) and the views of the data (the @link HFRepresenter HFRepresenters@endlink).
     88  - Propagating changes to the views.
     89  - Storing properties common to all Representers, such as the currently diplayed range, the currently selected range(s), the font, etc.
     90  - Handling text editing actions, such as selection changes or insertions/deletions.
     91 
     92 An HFController is the top point of ownership for a HexFiend object graph.  It retains both its ByteArray (model) and its array of Representers (views).
     93 
     94 You create an HFController via <tt>[[HFController alloc] init]</tt>.  After that, give it an HFByteArray via setByteArray:, and some Representers via addRepresenter:.  Then insert the Representers' views in a window, and you're done.
     95 
     96 */
     97 @interface HFController : NSObject <NSCoding> {
     98 @private
     99     NSMutableArray *representers;
    100     HFByteArray *byteArray;
    101     NSMutableArray *selectedContentsRanges;
    102     HFRange displayedContentsRange;
    103     HFFPRange displayedLineRange;
    104     NSUInteger bytesPerLine;
    105     NSUInteger bytesPerColumn;
    106     CGFloat lineHeight;
    107     
    108     NSUInteger currentPropertyChangeToken;
    109     NSMutableArray *additionalPendingTransactions;
    110     HFControllerPropertyBits propertiesToUpdateInCurrentTransaction;
    111     
    112     NSUndoManager *undoManager;
    113     NSMutableSet *undoOperations;
    114     HFControllerCoalescedUndo *undoCoalescer;
    115     
    116     unsigned long long selectionAnchor;
    117     HFRange selectionAnchorRange;
    118     
    119     CFAbsoluteTime pulseSelectionStartTime, pulseSelectionCurrentTime;
    120     NSTimer *pulseSelectionTimer;
    121     
    122     /* Basic cache support */
    123     HFRange cachedRange;
    124     NSData *cachedData;
    125     NSUInteger cachedGenerationIndex;
    126     
    127     struct {
    128         unsigned antialias:1;
    129         unsigned colorbytes:1;
    130         unsigned showcallouts:1;
    131         unsigned hideNullBytes:1;
    132         HFEditMode editMode:2;
    133         unsigned editable:1;
    134         unsigned selectable:1;
    135         unsigned selectionInProgress:1;
    136         unsigned shiftExtendSelection:1;
    137         unsigned commandExtendSelection:1;
    138         unsigned livereload:1;
    139     } _hfflags;
    140 }
    141 
    142 /*! @name Representer handling.
    143    Methods for modifying the list of HFRepresenters attached to a controller.  Attached representers receive the controllerDidChange: message when various properties of the controller change.  A representer may only be attached to one controller at a time.  Representers are retained by the controller.
    144 */
    145 //@{ 
    146 /// Gets the current array of representers attached to this controller.
    147 @property (readonly, copy) NSArray *representers;
    148 
    149 /// Adds a new representer to this controller.
    150 - (void)addRepresenter:(HFRepresenter *)representer;
    151 
    152 /// Removes an existing representer from this controller.  The representer must be present in the array of representers.
    153 - (void)removeRepresenter:(HFRepresenter *)representer;
    154 
    155 //@}
    156 
    157 /*! @name Property transactions
    158    Methods for temporarily delaying notifying representers of property changes.  There is a property transaction stack, and all property changes are collected until the last token is popped off the stack, at which point all representers are notified of all collected changes via representerChangedProperties:.  To use this, call beginPropertyChangeTransaction, and record the token that is returned.  Pass it to endPropertyChangeTransaction: to notify representers of all changed properties in bulk.
    159 
    160   Tokens cannot be popped out of order - they are used only as a correctness check.
    161 */
    162 //@{
    163 /*! Begins delaying property change transactions.  Returns a token that should be passed to endPropertyChangeTransactions:. */
    164 - (NSUInteger)beginPropertyChangeTransaction;
    165 
    166 /*! Pass a token returned from beginPropertyChangeTransaction to this method to pop the transaction off the stack and, if the stack is empty, to notify Representers of all collected changes.  Tokens cannot be popped out of order - they are used strictly as a correctness check. */
    167 - (void)endPropertyChangeTransaction:(NSUInteger)token;
    168 //@}
    169 
    170 /*! @name Byte array
    171    Set and get the byte array. */
    172 //@{ 
    173 
    174 /*! The byte array must be non-nil.  In general, HFRepresenters should not use this to determine what bytes to display.  Instead they should use copyBytes:range: or dataForRange: below. */
    175 @property (nonatomic, strong) HFByteArray *byteArray;
    176 
    177 /*! Replaces the entire byte array with a new one, preserving as much of the selection as possible.  Unlike setByteArray:, this method is undoable, and intended to be used from representers that make a global change (such as Replace All). */
    178 - (void)replaceByteArray:(HFByteArray *)newArray;
    179 //@}
    180 
    181 /*! @name Properties shared between all representers
    182     The following properties are considered global among all HFRepresenters attached to the receiver.
    183 */
    184 //@{ 
    185 /*! Returns the number of lines on which the cursor may be placed.  This is always at least 1, and is equivalent to (unsigned long long)(HFRoundUpToNextMultiple(contentsLength, bytesPerLine) / bytesPerLine) */
    186 - (unsigned long long)totalLineCount;
    187 
    188 /*! Indicates the number of bytes per line, which is a global property among all the line-oriented representers. */
    189 - (NSUInteger)bytesPerLine;
    190 
    191 /*! Returns the height of a line, in points.  This is generally determined by the font.  Representers that wish to align things to lines should use this. */
    192 - (CGFloat)lineHeight;
    193 
    194 //@}
    195 
    196 /*! @name Selection pulsing
    197     Used to show the current selection after a change, similar to Find in Safari
    198 */
    199 //{@
    200 
    201 /*! Begins selection pulsing (e.g. following a successful Find operation). Representers will receive callbacks indicating that HFControllerSelectionPulseAmount has changed. */
    202 - (void)pulseSelection;
    203 
    204 /*! Return the amount that the "Find pulse indicator" should show.  0 means no pulse, 1 means maximum pulse.  This is useful for Representers that support find and replace. */
    205 - (double)selectionPulseAmount;
    206 //@}
    207 
    208 /*! @name Selection handling
    209     Methods for manipulating the current selected ranges.  Hex Fiend supports discontiguous selection.
    210 */
    211 //{@
    212 
    213 /*! An array of HFRangeWrappers, representing the selected ranges.  It satisfies the following:
    214  The array is non-nil.
    215  There always is at least one selected range.
    216  If any range has length 0, that range is the only range.
    217  No range extends beyond the contentsLength, with the exception of a single zero-length range at the end.
    218 
    219  When setting, the setter MUST obey the above criteria. A zero length range when setting or getting represents the cursor position. */
    220 @property (nonatomic, copy) NSArray *selectedContentsRanges;
    221 
    222 /*! Selects the entire contents. */
    223 - (IBAction)selectAll:(id)sender;
    224 
    225 /*! Returns the smallest value in the selected contents ranges, or the insertion location if the selection is empty. */
    226 - (unsigned long long)minimumSelectionLocation;
    227 
    228 /*! Returns the largest HFMaxRange of the selected contents ranges, or the insertion location if the selection is empty. */
    229 - (unsigned long long)maximumSelectionLocation;
    230 
    231 /*! Convenience method for creating a byte array containing all of the selected bytes.  If the selection has length 0, this returns an empty byte array. */
    232 - (HFByteArray *)byteArrayForSelectedContentsRanges;
    233 //@}
    234 
    235 /* Number of bytes used in each column for a text-style representer. */
    236 @property (nonatomic) NSUInteger bytesPerColumn;
    237 
    238 /*! @name Edit Mode
    239    Determines what mode we're in, read-only, overwrite or insert. */
    240 @property (nonatomic) HFEditMode editMode;
    241 
    242 /*! @name Displayed line range
    243     Methods for setting and getting the current range of displayed lines. 
    244 */
    245 //{@
    246 /*! Get the current displayed line range.  The displayed line range is an HFFPRange (range of long doubles) containing the lines that are currently displayed.
    247 
    248   The values may be fractional.  That is, if only the bottom half of line 4 through the top two thirds of line 8 is shown, then the displayedLineRange.location will be 4.5 and the displayedLineRange.length will be 3.17 ( = 7.67 - 4.5).  Representers are expected to be able to handle such fractional values.
    249  
    250   When setting the displayed line range, the given range must be nonnegative, and the maximum of the range must be no larger than the total line count.
    251   
    252 */
    253 @property (nonatomic) HFFPRange displayedLineRange;
    254 
    255 /*! Modify the displayedLineRange so that as much of the given range as can fit is visible. If possible, moves by as little as possible so that the visible ranges before and afterward intersect with each other. */
    256 - (void)maximizeVisibilityOfContentsRange:(HFRange)range;
    257 
    258 /*! Modify the displayedLineRange as to center the given contents range.  If the range is near the bottom or top, this will center as close as possible.  If contents range is too large to fit, it centers the top of the range.  contentsRange may be empty. */
    259 - (void)centerContentsRange:(HFRange)range;
    260 
    261 //@}
    262 
    263 /*! The current font. */
    264 @property (nonatomic, copy) NSFont *font;
    265 
    266 /*! The undo manager. If no undo manager is set, then undo is not supported. By default the undo manager is nil.
    267 */
    268 @property (nonatomic, strong) NSUndoManager *undoManager;
    269 
    270 /*! Whether the user can edit the document. */
    271 @property (nonatomic) BOOL editable;
    272 
    273 /*! Whether the text should be antialiased. Note that Mac OS X settings may prevent antialiasing text below a certain point size. */
    274 @property (nonatomic) BOOL shouldAntialias;
    275 
    276 /*! When enabled, characters have a background color that correlates to their byte values. */
    277 @property (nonatomic) BOOL shouldColorBytes;
    278 
    279 /*! When enabled, byte bookmarks display callout-style labels attached to them. */
    280 @property (nonatomic) BOOL shouldShowCallouts;
    281 
    282 /*! When enabled, null bytes are hidden in the hex view. */
    283 @property (nonatomic) BOOL shouldHideNullBytes;
    284 
    285 /*! When enabled, unmodified documents are auto refreshed to their latest on disk state. */
    286 @property (nonatomic) BOOL shouldLiveReload;
    287 
    288 /*! Representer initiated property changes
    289     Called from a representer to indicate when some internal property of the representer has changed which requires that some properties be recalculated.
    290 */
    291 //@{
    292 /*! Callback for a representer-initiated change to some property.  For example, if some property of a view changes that would cause the number of bytes per line to change, then the representer should call this method which will trigger the HFController to recompute the relevant properties. */
    293 
    294 - (void)representer:(HFRepresenter *)rep changedProperties:(HFControllerPropertyBits)properties;
    295 //@}
    296 
    297 /*! @name Mouse selection
    298     Methods to handle mouse selection.  Representers that allow text selection should call beginSelectionWithEvent:forByteIndex: upon receiving a mouseDown event, and then continueSelectionWithEvent:forByteIndex: for mouseDragged events, terminating with endSelectionWithEvent:forByteIndex: upon receiving the mouse up.  HFController will compute the correct selected ranges and propagate any changes via the HFControllerPropertyBits mechanism. */
    299 //@{
    300 /*! Begin a selection session, with a mouse down at the given byte index. */
    301 - (void)beginSelectionWithEvent:(NSEvent *)event forByteIndex:(unsigned long long)byteIndex;
    302 
    303 /*! Continue a selection session, whe the user drags over the given byte index. */
    304 - (void)continueSelectionWithEvent:(NSEvent *)event forByteIndex:(unsigned long long)byteIndex;
    305 
    306 /*! End a selection session, with a mouse up at the given byte index. */
    307 - (void)endSelectionWithEvent:(NSEvent *)event forByteIndex:(unsigned long long)byteIndex;
    308 
    309 /*! @name Scrollling
    310     Support for the mouse wheel and scroll bars. */
    311 //@{
    312 /*! Trigger scrolling appropriate for the given scroll event.  */
    313 - (void)scrollWithScrollEvent:(NSEvent *)scrollEvent;
    314 
    315 /*! Trigger scrolling by the given number of lines.  If lines is positive, then the document is scrolled down; otherwise it is scrolled up.  */
    316 - (void)scrollByLines:(long double)lines;
    317 
    318 //@}
    319 
    320 /*! @name Keyboard navigation
    321     Support for chaging the selection via the keyboard
    322 */
    323 
    324 /*! General purpose navigation function.  Modify the selection in the given direction by the given number of bytes.  The selection is modifed according to the given transformation.  If useAnchor is set, then anchored selection is used; otherwise any anchor is discarded.
    325  
    326  This has a few limitations:
    327   - Only HFControllerDirectionLeft and HFControllerDirectionRight movement directions are supported.
    328   - Anchored selection is not supported for HFControllerShiftSelection (useAnchor must be NO)
    329 */
    330 - (void)moveInDirection:(HFControllerMovementDirection)direction byByteCount:(unsigned long long)amountToMove withSelectionTransformation:(HFControllerSelectionTransformation)transformation usingAnchor:(BOOL)useAnchor;
    331 
    332 /*! Navigation designed for key events. */
    333 - (void)moveInDirection:(HFControllerMovementDirection)direction withGranularity:(HFControllerMovementGranularity)granularity andModifySelection:(BOOL)extendSelection;
    334 - (void)moveToLineBoundaryInDirection:(HFControllerMovementDirection)direction andModifySelection:(BOOL)extendSelection;
    335 
    336 /*! @name Text editing
    337     Methods to support common text editing operations */
    338 //@{
    339 
    340 /*! Replaces the selection with the given data.  For something like a hex view representer, it takes two keypresses to create a whole byte; the way this is implemented, the first keypress goes into the data as a complete byte, and the second one (if any) replaces it.  If previousByteCount > 0, then that many prior bytes are replaced, without breaking undo coalescing.  For previousByteCount to be > 0, the following must be true: There is only one selected range, and it is of length 0, and its location >= previousByteCount 
    341     
    342     These functions return YES if they succeed, and NO if they fail.  Currently they may fail only in overwrite mode, if you attempt to insert data that would require lengthening the byte array.
    343     
    344     These methods are undoable.
    345  */
    346 - (BOOL)insertByteArray:(HFByteArray *)byteArray replacingPreviousBytes:(unsigned long long)previousByteCount allowUndoCoalescing:(BOOL)allowUndoCoalescing;
    347 - (BOOL)insertData:(NSData *)data replacingPreviousBytes:(unsigned long long)previousByteCount allowUndoCoalescing:(BOOL)allowUndoCoalescing;
    348 
    349 /*! Deletes the selection. This operation is undoable. */
    350 - (void)deleteSelection;
    351 
    352 /*! If the selection is empty, deletes one byte in a given direction, which must be HFControllerDirectionLeft or HFControllerDirectionRight; if the selection is not empty, deletes the selection. Undoable. */
    353 - (void)deleteDirection:(HFControllerMovementDirection)direction;
    354 
    355 //@}
    356 
    357 /*! @name Reading data
    358     Methods for reading data */
    359 
    360 /*! Returns an NSData representing the given HFRange.  The length of the HFRange must be of a size that can reasonably be fit in memory.  This method may cache the result. */
    361 - (NSData *)dataForRange:(HFRange)range;
    362 
    363 /*! Copies data within the given HFRange into an in-memory buffer.  This is equivalent to [[controller byteArray] copyBytes:bytes range:range]. */
    364 - (void)copyBytes:(unsigned char *)bytes range:(HFRange)range;
    365 
    366 /*! Returns total number of bytes.  This is equivalent to [[controller byteArray] length]. */
    367 - (unsigned long long)contentsLength;
    368 
    369 - (void) reloadData;
    370 - (void)_ensureVisibilityOfLocation:(unsigned long long)location;
    371 @end
    372 
    373 /*! A notification posted whenever any of the HFController's properties change.  The object is the HFController.  The userInfo contains one key, HFControllerChangedPropertiesKey, which contains an NSNumber with the changed properties as a HFControllerPropertyBits bitmask.  This is useful for external objects to be notified of changes.  HFRepresenters added to the HFController are notified via the controllerDidChange: message.
    374 */
    375 extern NSString * const HFControllerDidChangePropertiesNotification;
    376 
    377 /*! @name HFControllerDidChangePropertiesNotification keys 
    378 */
    379 //@{
    380 extern NSString * const HFControllerChangedPropertiesKey; //!< A key in the HFControllerDidChangeProperties containing a bitmask of the changed properties, as a HFControllerPropertyBits
    381 //@}
    382 
    383 /*! A notification posted from prepareForChangeInFile:fromWritingByteArray: because we are about to write a ByteArray to a file.  The object is the FileReference.
    384   Currently, HFControllers do not listen for this notification.  This is because under GC there is no way of knowing whether the controller is live or not.  However, pasteboard owners do listen for it, because as long as we own a pasteboard we are guaranteed to be live.
    385 */
    386 extern NSString * const HFPrepareForChangeInFileNotification;
    387 
    388 /*! @name HFPrepareForChangeInFileNotification keys 
    389 */
    390 //@{
    391 extern NSString * const HFChangeInFileByteArrayKey; //!< A key in the HFPrepareForChangeInFileNotification specifying the byte array that will be written
    392 extern NSString * const HFChangeInFileModifiedRangesKey; //!< A key in the HFPrepareForChangeInFileNotification specifying the array of HFRangeWrappers indicating which parts of the file will be modified
    393 extern NSString * const HFChangeInFileShouldCancelKey; //!< A key in the HFPrepareForChangeInFileNotification specifying an NSValue containing a pointer to a BOOL.  If set to YES, then someone was unable to prepare and the file should not be saved.  It's a good idea to check if this value points to YES; if so your notification handler does not have to do anything.
    394 extern NSString * const HFChangeInFileHintKey; //!< The hint parameter that you may pass to clearDependenciesOnRanges:inFile:hint:
    395 //@}

This webpage is intended to be an accessible preview of this repository. To get a fuller picture, clone it and use the git CLI.