git.y1.nz

SameBoy

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

Cocoa/GBHexStatusBarRepresenter.m

      1 #import "GBHexStatusBarRepresenter.h"
      2 #import <HexFiend/HFFunctions.h>
      3 
      4 @interface GBHexStatusBarView : NSView
      5 {
      6     NSCell *_cell;
      7     NSSize _cellSize;
      8     GBHexStatusBarRepresenter *_representer;
      9     NSDictionary *_cellAttributes;
     10     bool _registeredForAppNotifications;
     11 }
     12 
     13 - (void)setRepresenter:(GBHexStatusBarRepresenter *)rep;
     14 - (void)setString:(NSString *)string;
     15 
     16 @end
     17 
     18 
     19 @implementation GBHexStatusBarView
     20 
     21 - (void)_sharedInitStatusBarView
     22 {
     23     NSMutableParagraphStyle *style = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
     24     [style setAlignment:NSCenterTextAlignment];
     25     style.lineBreakMode = NSLineBreakByTruncatingTail;
     26     _cellAttributes = @{
     27         NSForegroundColorAttributeName: [NSColor windowFrameTextColor],
     28         NSFontAttributeName: [NSFont labelFontOfSize:[NSFont smallSystemFontSize]],
     29         NSParagraphStyleAttributeName: style,
     30     };
     31     _cell = [[NSCell alloc] initTextCell:@""];
     32     [_cell setAlignment:NSCenterTextAlignment];
     33     [_cell setBackgroundStyle:NSBackgroundStyleRaised];
     34 }
     35 
     36 - (instancetype)initWithFrame:(NSRect)frame
     37 {
     38     self = [super initWithFrame:frame];
     39     [self _sharedInitStatusBarView];
     40     return self;
     41 }
     42 
     43 - (instancetype)initWithCoder:(NSCoder *)coder
     44 {
     45     self = [super initWithCoder:coder];
     46     [self _sharedInitStatusBarView];
     47     return self;
     48 }
     49 
     50 - (BOOL)isFlipped
     51 {
     52     return true;
     53 }
     54 
     55 - (void)setRepresenter:(GBHexStatusBarRepresenter *)rep
     56 {
     57     _representer = rep;
     58 }
     59 
     60 - (void)setString:(NSString *)string
     61 {
     62     [_cell setAttributedStringValue:[[NSAttributedString alloc] initWithString:string attributes:_cellAttributes]];
     63     _cellSize = [_cell cellSize];
     64     [self setNeedsDisplay:true];
     65 }
     66 
     67 - (void)drawRect:(NSRect)clip
     68 {
     69     NSRect bounds = [self bounds];
     70     NSRect cellRect = NSMakeRect(NSMinX(bounds), HFCeil(NSMidY(bounds) - _cellSize.height / 2), NSWidth(bounds), _cellSize.height);
     71     [_cell drawWithFrame:cellRect inView:self];
     72 }
     73 
     74 - (void)setFrame:(NSRect)frame
     75 {
     76     [super setFrame:frame];
     77     [self.window setContentBorderThickness:frame.origin.y + frame.size.height forEdge:NSMinYEdge];
     78 }
     79 
     80 - (void)mouseDown:(NSEvent *)event
     81 {
     82     _representer.useDecimalLength ^= true;
     83 }
     84 
     85 - (void)windowDidChangeKeyStatus:(NSNotification *)note
     86 {
     87     [self setNeedsDisplay:true];
     88 }
     89 
     90 - (void)viewDidMoveToWindow
     91 {
     92     HFRegisterViewForWindowAppearanceChanges(self, @selector(windowDidChangeKeyStatus:), !_registeredForAppNotifications);
     93     _registeredForAppNotifications = true;
     94     [self.window setContentBorderThickness:self.frame.origin.y + self.frame.size.height forEdge:NSMinYEdge];
     95     [super viewDidMoveToWindow];
     96 }
     97 
     98 - (void)viewWillMoveToWindow:(NSWindow *)newWindow
     99 {
    100     HFUnregisterViewForWindowAppearanceChanges(self, NO);
    101     [super viewWillMoveToWindow:newWindow];
    102 }
    103 
    104 - (void)dealloc
    105 {
    106     HFUnregisterViewForWindowAppearanceChanges(self, _registeredForAppNotifications);
    107 }
    108 
    109 @end
    110 
    111 @implementation GBHexStatusBarRepresenter
    112 
    113 - (instancetype)init
    114 {
    115     self = [super init];
    116     return self;
    117 }
    118 
    119 - (NSView *)createView {
    120     GBHexStatusBarView *view = [[GBHexStatusBarView alloc] initWithFrame:NSMakeRect(0, 0, 100, 18)];
    121     [view setRepresenter:self];
    122     [view setAutoresizingMask:NSViewWidthSizable];
    123     return view;
    124 }
    125 
    126 - (NSString *)describeLength:(unsigned long long)length
    127 {
    128     if (self.useDecimalLength) {
    129         return [NSString stringWithFormat:@"%llu byte%s", length, length == 1 ? "" : "s"];
    130     }
    131     return [NSString stringWithFormat:@"$%llX byte%s", length, length == 1 ? "" : "s"];
    132 }
    133 
    134 - (NSString *)describeOffset:(unsigned long long)offset isRangeEnd:(bool)isRangeEnd
    135 {
    136     if (!_gb) {
    137         return [NSString stringWithFormat:@"$%llX", offset];
    138     }
    139     return @(GB_debugger_describe_address(_gb, offset + _baseAddress, offset < 0x4000? -1 :_bankForDescription, false, isRangeEnd));
    140 }
    141 
    142 
    143 - (NSString *)stringForEmptySelectionAtOffset:(unsigned long long)offset length:(unsigned long long)length
    144 {
    145     return [self describeOffset:offset isRangeEnd:false];
    146 }
    147 
    148 - (NSString *)stringForSingleByteSelectionAtOffset:(unsigned long long)offset length:(unsigned long long)length
    149 {
    150     return [NSString stringWithFormat:@"Byte %@ selected", [self describeOffset:offset isRangeEnd:false]];
    151 }
    152 
    153 - (NSString *)stringForSingleRangeSelection:(HFRange)range length:(unsigned long long)length
    154 {
    155     return [NSString stringWithFormat:@"Range %@ to %@ selected (%@)",
    156             [self describeOffset:range.location isRangeEnd:false],
    157             [self describeOffset:range.location + range.length isRangeEnd:true],
    158             [self describeLength:range.length]];
    159 }
    160 
    161 
    162 - (void)updateString
    163 {
    164     NSString *string = nil;
    165     HFController *controller = [self controller];
    166     if (controller) {
    167         unsigned long long length = [controller contentsLength];
    168         NSArray *ranges = [controller selectedContentsRanges];
    169         NSUInteger rangeCount = [ranges count];
    170         if (rangeCount == 1) {
    171             HFRange range = [ranges[0] HFRange];
    172             if (range.length == 0) {
    173                 string = [self stringForEmptySelectionAtOffset:range.location length:length];
    174             }
    175             else if (range.length == 1) {
    176                 string = [self stringForSingleByteSelectionAtOffset:range.location length:length];
    177             }
    178             else {
    179                 string = [self stringForSingleRangeSelection:range length:length];
    180             }
    181         }
    182         else {
    183             string = @"Multiple ranges selected";
    184         }
    185     }
    186     if (! string) string = @"";
    187     [[self view] setString:string];
    188 }
    189 
    190 - (void)setUseDecimalLength:(bool)useDecimalLength
    191 {
    192     _useDecimalLength = useDecimalLength;
    193     [self updateString];
    194 }
    195 
    196 - (void)setBaseAddress:(uint16_t)baseAddress
    197 {
    198     _baseAddress = baseAddress;
    199     [self updateString];
    200 }
    201 
    202 - (void) setBankForDescription:(uint16_t)bankForDescription
    203 {
    204     _bankForDescription = bankForDescription;
    205     [self updateString];
    206 }
    207 
    208 - (void)controllerDidChange:(HFControllerPropertyBits)bits
    209 {
    210     if (bits & (HFControllerContentLength | HFControllerSelectedRanges)) {
    211         [self updateString];
    212     }
    213 }
    214 
    215 + (NSPoint)defaultLayoutPosition
    216 {
    217     return NSMakePoint(0, -1);
    218 }
    219 
    220 @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.