git.y1.nz

SameBoy

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

HexFiend/HFTextRepresenter.m

      1 //
      2 //  HFTextRepresenter.m
      3 //  HexFiend_2
      4 //
      5 //  Copyright 2007 ridiculous_fish. All rights reserved.
      6 //
      7 
      8 #import <HexFiend/HFTextRepresenter_Internal.h>
      9 #import <HexFiend/HFRepresenterTextView.h>
     10 #import <HexFiend/HFPasteboardOwner.h>
     11 #import <HexFiend/HFByteArray.h>
     12 #import <HexFiend/HFTextVisualStyleRun.h>
     13 
     14 @implementation HFTextRepresenter
     15 
     16 - (Class)_textViewClass {
     17     UNIMPLEMENTED();
     18 }
     19 
     20 - (instancetype)init {
     21     self = [super init];
     22     
     23     if (@available(macOS 10.14, *)) {
     24         _rowBackgroundColors = [[NSColor alternatingContentBackgroundColors] retain];
     25     } else {
     26         NSColor *color1 = [NSColor windowBackgroundColor];
     27         NSColor *color2 = [NSColor colorWithDeviceWhite:0.96 alpha:1];
     28         _rowBackgroundColors = [@[color1, color2] retain];
     29     }
     30     
     31     return self;
     32 }
     33 
     34 - (void)dealloc {
     35     if ([self isViewLoaded]) {
     36         [[self view] clearRepresenter];
     37     }
     38     [_rowBackgroundColors release];
     39     [super dealloc];
     40 }
     41 
     42 - (void)encodeWithCoder:(NSCoder *)coder {
     43     HFASSERT([coder allowsKeyedCoding]);
     44     [super encodeWithCoder:coder];
     45     [coder encodeBool:_behavesAsTextField forKey:@"HFBehavesAsTextField"];
     46     [coder encodeObject:_rowBackgroundColors forKey:@"HFRowBackgroundColors"];
     47 }
     48 
     49 - (instancetype)initWithCoder:(NSCoder *)coder {
     50     HFASSERT([coder allowsKeyedCoding]);
     51     self = [super initWithCoder:coder];
     52     _behavesAsTextField = [coder decodeBoolForKey:@"HFBehavesAsTextField"];
     53     _rowBackgroundColors = [[coder decodeObjectForKey:@"HFRowBackgroundColors"] retain];
     54     return self;
     55 }
     56 
     57 - (NSView *)createView {
     58     HFRepresenterTextView *view = [[[self _textViewClass] alloc] initWithRepresenter:self];
     59     [view setAutoresizingMask:NSViewHeightSizable];
     60     return view;
     61 }
     62 
     63 - (HFByteArrayDataStringType)byteArrayDataStringType {
     64     UNIMPLEMENTED();
     65 }
     66 
     67 - (HFRange)entireDisplayedRange {
     68     HFController *controller = [self controller];
     69     unsigned long long contentsLength = [controller contentsLength];
     70     HFASSERT(controller != NULL);
     71     HFFPRange displayedLineRange = [controller displayedLineRange];
     72     NSUInteger bytesPerLine = [controller bytesPerLine];
     73     unsigned long long lineStart = HFFPToUL(floorl(displayedLineRange.location));
     74     unsigned long long lineEnd = HFFPToUL(ceill(displayedLineRange.location + displayedLineRange.length));
     75     HFASSERT(lineEnd >= lineStart);
     76     HFRange byteRange = HFRangeMake(HFProductULL(bytesPerLine, lineStart), HFProductULL(lineEnd - lineStart, bytesPerLine));
     77     if (byteRange.length == 0) {
     78         /* This can happen if we are too small to even show one line */
     79         return HFRangeMake(0, 0);
     80     }
     81     else {
     82         HFASSERT(byteRange.location <= contentsLength);
     83         byteRange.length = MIN(byteRange.length, contentsLength - byteRange.location);
     84         HFASSERT(HFRangeIsSubrangeOfRange(byteRange, HFRangeMake(0, [controller contentsLength])));
     85         return byteRange;
     86     }
     87 }
     88 
     89 - (NSRect)furthestRectOnEdge:(NSRectEdge)edge forByteRange:(HFRange)byteRange {
     90     HFASSERT(byteRange.length > 0);
     91     HFRange displayedRange = [self entireDisplayedRange];
     92     HFRange intersection = HFIntersectionRange(displayedRange, byteRange);
     93     NSRect result = {{0,},};
     94     if (intersection.length > 0) {
     95         NSRange intersectionNSRange = NSMakeRange(ll2l(intersection.location - displayedRange.location), ll2l(intersection.length));
     96         if (intersectionNSRange.length > 0) {
     97             result = [[self view] furthestRectOnEdge:edge forRange:intersectionNSRange];
     98         }
     99     }
    100     else if (byteRange.location < displayedRange.location) {
    101         /* We're below it. */
    102         return NSMakeRect(-CGFLOAT_MAX, -CGFLOAT_MAX, 0, 0);
    103     }
    104     else if (byteRange.location >= HFMaxRange(displayedRange)) {
    105         /* We're above it */
    106         return NSMakeRect(CGFLOAT_MAX, CGFLOAT_MAX, 0, 0);
    107     }
    108     else {
    109         /* Shouldn't be possible to get here */
    110         [NSException raise:NSInternalInconsistencyException format:@"furthestRectOnEdge: expected an intersection, or a range below or above the byte range, but nothin'"];
    111     }
    112     return result;
    113 }
    114 
    115 - (NSPoint)locationOfCharacterAtByteIndex:(unsigned long long)index {
    116     NSPoint result;
    117     HFRange displayedRange = [self entireDisplayedRange];
    118     if (HFLocationInRange(index, displayedRange) || index == HFMaxRange(displayedRange)) {
    119         NSUInteger location = ll2l(index - displayedRange.location);
    120         result = [[self view] originForCharacterAtByteIndex:location];
    121     }
    122     else if (index < displayedRange.location) {
    123         result = NSMakePoint(-CGFLOAT_MAX, -CGFLOAT_MAX);
    124     }
    125     else {
    126         result = NSMakePoint(CGFLOAT_MAX, CGFLOAT_MAX);
    127     }
    128     return result;
    129 }
    130 
    131 - (HFTextVisualStyleRun *)styleForAttributes:(NSSet *)attributes range:(NSRange)range {
    132     HFTextVisualStyleRun *run = [[[HFTextVisualStyleRun alloc] init] autorelease];
    133     [run setRange:range];
    134     [run setForegroundColor:[NSColor blackColor]];
    135 
    136     return run;
    137 }
    138 
    139 - (NSArray *)stylesForRange:(HFRange)range {
    140     return nil;
    141 }
    142 
    143 - (void)updateText {
    144     HFController *controller = [self controller];
    145     HFRepresenterTextView *view = [self view];
    146     HFRange entireDisplayedRange = [self entireDisplayedRange];
    147     [view setData:[controller dataForRange:entireDisplayedRange]];
    148     [view setStyles:[self stylesForRange:entireDisplayedRange]];
    149     HFFPRange lineRange = [controller displayedLineRange];
    150     long double offsetLongDouble = lineRange.location - floorl(lineRange.location);
    151     CGFloat offset = ld2f(offsetLongDouble);
    152     [view setVerticalOffset:offset];
    153     [view setStartingLineBackgroundColorIndex:ll2l(HFFPToUL(floorl(lineRange.location)) % NSUIntegerMax)];
    154 }
    155 
    156 - (void)initializeView {
    157     [super initializeView];
    158     HFRepresenterTextView *view = [self view];
    159     HFController *controller = [self controller];
    160     if (controller) {
    161         [view setFont:[controller font]];
    162         [view setEditable:[controller editable]];
    163         [self updateText];
    164     }
    165     else {
    166         [view setFont:[NSFont fontWithName:HFDEFAULT_FONT size:HFDEFAULT_FONTSIZE]];
    167     }
    168 }
    169 
    170 - (void)scrollWheel:(NSEvent *)event {
    171     [[self controller] scrollWithScrollEvent:event];
    172 }
    173 
    174 - (void)selectAll:(id)sender {
    175     [[self controller] selectAll:sender];
    176 }
    177 
    178 - (double)selectionPulseAmount {
    179     return [[self controller] selectionPulseAmount];
    180 }
    181 
    182 - (void)controllerDidChange:(HFControllerPropertyBits)bits {
    183     if (bits & (HFControllerFont | HFControllerLineHeight)) {
    184         [[self view] setFont:[[self controller] font]];
    185     }
    186     if (bits & (HFControllerContentValue | HFControllerDisplayedLineRange | HFControllerByteRangeAttributes)) {
    187         [self updateText];
    188     }
    189     if (bits & (HFControllerSelectedRanges | HFControllerDisplayedLineRange)) {
    190         [[self view] updateSelectedRanges];
    191     }
    192     if (bits & (HFControllerEditable)) {
    193         [[self view] setEditable:[[self controller] editable]];
    194     }
    195     if (bits & (HFControllerAntialias)) {
    196         [[self view] setShouldAntialias:[[self controller] shouldAntialias]];
    197     }
    198     if (bits & (HFControllerShowCallouts)) {
    199         [[self view] setShouldDrawCallouts:[[self controller] shouldShowCallouts]];
    200     }
    201     if (bits & (HFControllerColorBytes)) {
    202         if([[self controller] shouldColorBytes]) {
    203             [[self view] setByteColoring: ^(uint8_t byte, uint8_t *r, uint8_t *g, uint8_t *b, uint8_t *a){
    204                 *r = *g = *b = (uint8_t)(255 * ((255-byte)/255.0*0.6+0.4));
    205                 *a = (uint8_t)(255 * 0.7);
    206             }];
    207         } else {
    208             [[self view] setByteColoring:NULL];
    209         }
    210     }
    211     [super controllerDidChange:bits];
    212 }
    213 
    214 - (double)maximumAvailableLinesForViewHeight:(CGFloat)viewHeight {
    215     return [[self view] maximumAvailableLinesForViewHeight:viewHeight];
    216 }
    217 
    218 - (NSUInteger)maximumBytesPerLineForViewWidth:(CGFloat)viewWidth {
    219     return [[self view] maximumBytesPerLineForViewWidth:viewWidth];
    220 }
    221 
    222 - (CGFloat)minimumViewWidthForBytesPerLine:(NSUInteger)bytesPerLine {
    223     return [[self view] minimumViewWidthForBytesPerLine:bytesPerLine];
    224 }
    225 
    226 - (NSUInteger)byteGranularity {
    227     HFRepresenterTextView *view = [self view];
    228     NSUInteger bytesPerColumn = MAX([view bytesPerColumn], 1u), bytesPerCharacter = [view bytesPerCharacter];
    229     return HFLeastCommonMultiple(bytesPerColumn, bytesPerCharacter);
    230 }
    231 
    232 - (NSArray *)displayedSelectedContentsRanges {
    233     HFController *controller = [self controller];
    234     NSArray *result;
    235     NSArray *selectedRanges = [controller selectedContentsRanges];
    236     HFRange displayedRange = [self entireDisplayedRange];
    237     
    238     HFASSERT(displayedRange.length <= NSUIntegerMax);
    239     NEW_ARRAY(NSValue *, clippedSelectedRanges, [selectedRanges count]);
    240     NSUInteger clippedRangeIndex = 0;
    241     FOREACH(HFRangeWrapper *, wrapper, selectedRanges) {
    242         HFRange selectedRange = [wrapper HFRange];
    243         BOOL clippedRangeIsVisible;
    244         NSRange clippedSelectedRange = {0,};
    245         /* Necessary because zero length ranges do not intersect anything */
    246         if (selectedRange.length == 0) {
    247             /* Remember that {6, 0} is considered a subrange of {3, 3} */
    248             clippedRangeIsVisible = HFRangeIsSubrangeOfRange(selectedRange, displayedRange);
    249             if (clippedRangeIsVisible) {
    250                 HFASSERT(selectedRange.location >= displayedRange.location);
    251                 clippedSelectedRange.location = ll2l(selectedRange.location - displayedRange.location);
    252                 clippedSelectedRange.length = 0;
    253             }
    254         }
    255         else {
    256             // selectedRange.length > 0
    257             clippedRangeIsVisible = HFIntersectsRange(selectedRange, displayedRange);
    258             if (clippedRangeIsVisible) {
    259                 HFRange intersectionRange = HFIntersectionRange(selectedRange, displayedRange);
    260                 HFASSERT(intersectionRange.location >= displayedRange.location);
    261                 clippedSelectedRange.location = ll2l(intersectionRange.location - displayedRange.location);
    262                 clippedSelectedRange.length = ll2l(intersectionRange.length);
    263             }
    264         }
    265         if (clippedRangeIsVisible) clippedSelectedRanges[clippedRangeIndex++] = [NSValue valueWithRange:clippedSelectedRange];
    266     }
    267     result = [NSArray arrayWithObjects:clippedSelectedRanges count:clippedRangeIndex];
    268     FREE_ARRAY(clippedSelectedRanges);
    269     return result;
    270 }
    271 
    272 //maps bookmark keys as NSNumber to byte locations as NSNumbers. Because bookmark callouts may extend beyond the lines containing them, allow a larger range by 10 lines.
    273 - (NSDictionary *)displayedBookmarkLocations {
    274     NSMutableDictionary *result = nil;
    275     HFController *controller = [self controller];
    276     NSUInteger rangeExtension = 10 * [controller bytesPerLine];
    277     HFRange displayedRange = [self entireDisplayedRange];
    278     
    279     HFRange includedRange = displayedRange;
    280     
    281     /* Extend the bottom */
    282     unsigned long long bottomExtension = MIN(includedRange.location, rangeExtension);
    283     includedRange.location -= bottomExtension;
    284     includedRange.length += bottomExtension;
    285     
    286     /* Extend the top */
    287     unsigned long long topExtension = MIN([controller contentsLength] - HFMaxRange(includedRange), rangeExtension);
    288     includedRange.length = HFSum(includedRange.length, topExtension);
    289     
    290     return result;
    291 }
    292 
    293 - (unsigned long long)byteIndexForCharacterIndex:(NSUInteger)characterIndex {
    294     HFController *controller = [self controller];
    295     HFFPRange lineRange = [controller displayedLineRange];
    296     unsigned long long scrollAmount = HFFPToUL(floorl(lineRange.location));
    297     unsigned long long byteIndex = HFProductULL(scrollAmount, [controller bytesPerLine]) + characterIndex * [[self view] bytesPerCharacter];
    298     return byteIndex;
    299 }
    300 
    301 - (void)beginSelectionWithEvent:(NSEvent *)event forCharacterIndex:(NSUInteger)characterIndex {
    302     [[self controller] beginSelectionWithEvent:event forByteIndex:[self byteIndexForCharacterIndex:characterIndex]];
    303 }
    304 
    305 - (void)continueSelectionWithEvent:(NSEvent *)event forCharacterIndex:(NSUInteger)characterIndex {
    306     [[self controller] continueSelectionWithEvent:event forByteIndex:[self byteIndexForCharacterIndex:characterIndex]];
    307 }
    308 
    309 - (void)endSelectionWithEvent:(NSEvent *)event forCharacterIndex:(NSUInteger)characterIndex {
    310     [[self controller] endSelectionWithEvent:event forByteIndex:[self byteIndexForCharacterIndex:characterIndex]];
    311 }
    312 
    313 - (void)insertText:(NSString *)text {
    314     USE(text);
    315     UNIMPLEMENTED_VOID();
    316 }
    317 
    318 - (void)copySelectedBytesToPasteboard:(NSPasteboard *)pb {
    319     USE(pb);
    320     UNIMPLEMENTED_VOID();
    321 }
    322 
    323 - (void)cutSelectedBytesToPasteboard:(NSPasteboard *)pb {
    324     [self copySelectedBytesToPasteboard:pb];
    325     [[self controller] deleteSelection];
    326 }
    327 
    328 - (NSData *)dataFromPasteboardString:(NSString *)string {
    329     USE(string);
    330     UNIMPLEMENTED();
    331 }
    332 
    333 - (BOOL)canPasteFromPasteboard:(NSPasteboard *)pb {
    334     REQUIRE_NOT_NULL(pb);
    335     if ([[self controller] editable]) {
    336         // we can paste if the pboard contains text or contains an HFByteArray
    337         return [HFPasteboardOwner unpackByteArrayFromPasteboard:pb] || [pb availableTypeFromArray:@[NSStringPboardType]];
    338     }
    339     return NO;
    340 }
    341 
    342 - (BOOL)canCut {
    343     /* We can cut if we are editable, we have at least one byte selected, and we are not in overwrite mode */
    344     HFController *controller = [self controller];
    345     if ([controller editMode] != HFInsertMode) return NO;
    346     if (! [controller editable]) return NO;
    347     
    348     FOREACH(HFRangeWrapper *, rangeWrapper, [controller selectedContentsRanges]) {
    349         if ([rangeWrapper HFRange].length > 0) return YES; //we have something selected
    350     }
    351     return NO; // we did not find anything selected
    352 }
    353 
    354 - (BOOL)pasteBytesFromPasteboard:(NSPasteboard *)pb {
    355     REQUIRE_NOT_NULL(pb);
    356     BOOL result = NO;
    357     HFByteArray *byteArray = [HFPasteboardOwner unpackByteArrayFromPasteboard:pb];
    358     if (byteArray) {
    359         [[self controller] insertByteArray:byteArray replacingPreviousBytes:0 allowUndoCoalescing:NO];
    360         result = YES;
    361     }
    362     else {
    363         NSString *stringType = [pb availableTypeFromArray:@[NSStringPboardType]];
    364         if (stringType) {
    365             NSString *stringValue = [pb stringForType:stringType];
    366             if (stringValue) {
    367                 NSData *data = [self dataFromPasteboardString:stringValue];
    368                 if (data) {
    369                     [[self controller] insertData:data replacingPreviousBytes:0 allowUndoCoalescing:NO];
    370                 }
    371             }
    372         }
    373     }
    374     return result;
    375 }
    376 
    377 @end

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