diff --git a/Cocoa/Document.m b/Cocoa/Document.m index c9688f6..b477bbc 100644 --- a/Cocoa/Document.m +++ b/Cocoa/Document.m @@ -13,6 +13,7 @@ #import "GBPaletteEditorController.h" #import "GBObjectView.h" #import "GBPaletteView.h" +#import "GBHexStatusBarRepresenter.h" #import "NSObject+DefaultsObserver.h" #define likely(x) GB_likely(x) @@ -82,6 +83,7 @@ enum model { NSString *_lastConsoleInput; HFLineCountingRepresenter *_lineRep; + GBHexStatusBarRepresenter *_statusRep; CVImageBufferRef _cameraImage; AVCaptureSession *_cameraSession; @@ -878,7 +880,9 @@ static unsigned *multiplication_table_for_frequency(unsigned frequency) HFStringEncodingTextRepresenter *asciiRep = [[HFStringEncodingTextRepresenter alloc] init]; HFVerticalScrollerRepresenter *scrollRep = [[HFVerticalScrollerRepresenter alloc] init]; _lineRep = [[HFLineCountingRepresenter alloc] init]; - HFStatusBarRepresenter *statusRep = [[HFStatusBarRepresenter alloc] init]; + _statusRep = [[GBHexStatusBarRepresenter alloc] init]; + _statusRep.gb = &_gb; + _statusRep.bankForDescription = -1; _lineRep.lineNumberFormat = HFLineNumberFormatHexadecimal; @@ -888,14 +892,14 @@ static unsigned *multiplication_table_for_frequency(unsigned frequency) [_hexController addRepresenter:asciiRep]; [_hexController addRepresenter:scrollRep]; [_hexController addRepresenter:_lineRep]; - [_hexController addRepresenter:statusRep]; + [_hexController addRepresenter:_statusRep]; /* Tell the layout rep which reps it should lay out. */ [layoutRep addRepresenter:hexRep]; [layoutRep addRepresenter:scrollRep]; [layoutRep addRepresenter:asciiRep]; [layoutRep addRepresenter:_lineRep]; - [layoutRep addRepresenter:statusRep]; + [layoutRep addRepresenter:_statusRep]; [(NSView *)[hexRep view] setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; @@ -1827,6 +1831,7 @@ static bool is_path_writeable(const char *path) [sender setStringValue:[NSString stringWithFormat:@"$%x", bank]]; [(GBMemoryByteArray *)(_hexController.byteArray) setSelectedBank:bank]; + _statusRep.bankForDescription = bank; dispatch_async(dispatch_get_main_queue(), ^{ [_hexController reloadData]; }); @@ -1846,33 +1851,37 @@ static bool is_path_writeable(const char *path) - (IBAction)hexUpdateSpace:(NSPopUpButtonCell *)sender { self.memoryBankItem.enabled = [sender indexOfSelectedItem] != GBMemoryEntireSpace; + [_hexController setSelectedContentsRanges:@[[HFRangeWrapper withRange:HFRangeMake(0, 0)]]]; GBMemoryByteArray *byteArray = (GBMemoryByteArray *)(_hexController.byteArray); [byteArray setMode:(GB_memory_mode_t)[sender indexOfSelectedItem]]; - uint16_t bank; + uint16_t bank = -1; switch ((GB_memory_mode_t)[sender indexOfSelectedItem]) { case GBMemoryEntireSpace: + _statusRep.baseAddress = _lineRep.valueOffset = 0; + break; case GBMemoryROM: - _lineRep.valueOffset = 0; + _statusRep.baseAddress = _lineRep.valueOffset = 0; GB_get_direct_access(&_gb, GB_DIRECT_ACCESS_ROM, NULL, &bank); - byteArray.selectedBank = bank; break; case GBMemoryVRAM: - _lineRep.valueOffset = 0x8000; + _statusRep.baseAddress = _lineRep.valueOffset = 0x8000; GB_get_direct_access(&_gb, GB_DIRECT_ACCESS_VRAM, NULL, &bank); - byteArray.selectedBank = bank; break; case GBMemoryExternalRAM: - _lineRep.valueOffset = 0xA000; + _statusRep.baseAddress = _lineRep.valueOffset = 0xA000; GB_get_direct_access(&_gb, GB_DIRECT_ACCESS_CART_RAM, NULL, &bank); - byteArray.selectedBank = bank; break; case GBMemoryRAM: - _lineRep.valueOffset = 0xC000; + _statusRep.baseAddress = _lineRep.valueOffset = 0xC000; GB_get_direct_access(&_gb, GB_DIRECT_ACCESS_RAM, NULL, &bank); - byteArray.selectedBank = bank; break; } - [self.memoryBankInput setStringValue:[NSString stringWithFormat:@"$%x", byteArray.selectedBank]]; + byteArray.selectedBank = bank; + _statusRep.bankForDescription = bank; + if (bank != (uint16_t)-1) { + [self.memoryBankInput setStringValue:[NSString stringWithFormat:@"$%x", byteArray.selectedBank]]; + } + [_hexController reloadData]; for (NSView *view in self.memoryView.subviews) { [view setNeedsDisplay:true]; diff --git a/Cocoa/GBHexStatusBarRepresenter.h b/Cocoa/GBHexStatusBarRepresenter.h new file mode 100644 index 0000000..5551ded --- /dev/null +++ b/Cocoa/GBHexStatusBarRepresenter.h @@ -0,0 +1,10 @@ +#import +#import + + +@interface GBHexStatusBarRepresenter : HFRepresenter +@property GB_gameboy_t *gb; +@property (nonatomic) bool useDecimalLength; +@property (nonatomic) uint16_t bankForDescription; +@property (nonatomic) uint16_t baseAddress; +@end diff --git a/Cocoa/GBHexStatusBarRepresenter.m b/Cocoa/GBHexStatusBarRepresenter.m new file mode 100644 index 0000000..c3be66f --- /dev/null +++ b/Cocoa/GBHexStatusBarRepresenter.m @@ -0,0 +1,220 @@ +#import "GBHexStatusBarRepresenter.h" +#import + +@interface GBHexStatusBarView : NSView +{ + NSCell *_cell; + NSSize _cellSize; + GBHexStatusBarRepresenter *_representer; + NSDictionary *_cellAttributes; + bool _registeredForAppNotifications; +} + +- (void)setRepresenter:(GBHexStatusBarRepresenter *)rep; +- (void)setString:(NSString *)string; + +@end + + +@implementation GBHexStatusBarView + +- (void)_sharedInitStatusBarView +{ + NSMutableParagraphStyle *style = [[NSParagraphStyle defaultParagraphStyle] mutableCopy]; + [style setAlignment:NSCenterTextAlignment]; + style.lineBreakMode = NSLineBreakByTruncatingTail; + _cellAttributes = @{ + NSForegroundColorAttributeName: [NSColor windowFrameTextColor], + NSFontAttributeName: [NSFont labelFontOfSize:[NSFont smallSystemFontSize]], + NSParagraphStyleAttributeName: style, + }; + _cell = [[NSCell alloc] initTextCell:@""]; + [_cell setAlignment:NSCenterTextAlignment]; + [_cell setBackgroundStyle:NSBackgroundStyleRaised]; +} + +- (instancetype)initWithFrame:(NSRect)frame +{ + self = [super initWithFrame:frame]; + [self _sharedInitStatusBarView]; + return self; +} + +- (instancetype)initWithCoder:(NSCoder *)coder +{ + self = [super initWithCoder:coder]; + [self _sharedInitStatusBarView]; + return self; +} + +- (BOOL)isFlipped +{ + return true; +} + +- (void)setRepresenter:(GBHexStatusBarRepresenter *)rep +{ + _representer = rep; +} + +- (void)setString:(NSString *)string +{ + [_cell setAttributedStringValue:[[NSAttributedString alloc] initWithString:string attributes:_cellAttributes]]; + _cellSize = [_cell cellSize]; + [self setNeedsDisplay:true]; +} + +- (void)drawRect:(NSRect)clip +{ + NSRect bounds = [self bounds]; + NSRect cellRect = NSMakeRect(NSMinX(bounds), HFCeil(NSMidY(bounds) - _cellSize.height / 2), NSWidth(bounds), _cellSize.height); + [_cell drawWithFrame:cellRect inView:self]; +} + +- (void)setFrame:(NSRect)frame +{ + [super setFrame:frame]; + [self.window setContentBorderThickness:frame.origin.y + frame.size.height forEdge:NSMinYEdge]; +} + +- (void)mouseDown:(NSEvent *)event +{ + _representer.useDecimalLength ^= true; +} + +- (void)windowDidChangeKeyStatus:(NSNotification *)note +{ + [self setNeedsDisplay:true]; +} + +- (void)viewDidMoveToWindow +{ + HFRegisterViewForWindowAppearanceChanges(self, @selector(windowDidChangeKeyStatus:), !_registeredForAppNotifications); + _registeredForAppNotifications = true; + [self.window setContentBorderThickness:self.frame.origin.y + self.frame.size.height forEdge:NSMinYEdge]; + [super viewDidMoveToWindow]; +} + +- (void)viewWillMoveToWindow:(NSWindow *)newWindow +{ + HFUnregisterViewForWindowAppearanceChanges(self, NO); + [super viewWillMoveToWindow:newWindow]; +} + +- (void)dealloc +{ + HFUnregisterViewForWindowAppearanceChanges(self, _registeredForAppNotifications); +} + +@end + +@implementation GBHexStatusBarRepresenter + +- (instancetype)init +{ + self = [super init]; + return self; +} + +- (NSView *)createView { + GBHexStatusBarView *view = [[GBHexStatusBarView alloc] initWithFrame:NSMakeRect(0, 0, 100, 18)]; + [view setRepresenter:self]; + [view setAutoresizingMask:NSViewWidthSizable]; + return view; +} + +- (NSString *)describeLength:(unsigned long long)length +{ + if (self.useDecimalLength) { + return [NSString stringWithFormat:@"%llu byte%s", length, length == 1 ? "" : "s"]; + } + return [NSString stringWithFormat:@"$%llX byte%s", length, length == 1 ? "" : "s"]; +} + +- (NSString *)describeOffset:(unsigned long long)offset isRangeEnd:(bool)isRangeEnd +{ + if (!_gb) { + return [NSString stringWithFormat:@"$%llX", offset]; + } + return @(GB_debugger_describe_address(_gb, offset + _baseAddress, _bankForDescription, false, isRangeEnd)); +} + + +- (NSString *)stringForEmptySelectionAtOffset:(unsigned long long)offset length:(unsigned long long)length +{ + return [self describeOffset:offset isRangeEnd:false]; +} + +- (NSString *)stringForSingleByteSelectionAtOffset:(unsigned long long)offset length:(unsigned long long)length +{ + return [NSString stringWithFormat:@"Byte %@ selected", [self describeOffset:offset isRangeEnd:false]]; +} + +- (NSString *)stringForSingleRangeSelection:(HFRange)range length:(unsigned long long)length +{ + return [NSString stringWithFormat:@"Range %@ to %@ selected (%@)", + [self describeOffset:range.location isRangeEnd:false], + [self describeOffset:range.location + range.length isRangeEnd:true], + [self describeLength:range.length]]; +} + + +- (void)updateString +{ + NSString *string = nil; + HFController *controller = [self controller]; + if (controller) { + unsigned long long length = [controller contentsLength]; + NSArray *ranges = [controller selectedContentsRanges]; + NSUInteger rangeCount = [ranges count]; + if (rangeCount == 1) { + HFRange range = [ranges[0] HFRange]; + if (range.length == 0) { + string = [self stringForEmptySelectionAtOffset:range.location length:length]; + } + else if (range.length == 1) { + string = [self stringForSingleByteSelectionAtOffset:range.location length:length]; + } + else { + string = [self stringForSingleRangeSelection:range length:length]; + } + } + else { + string = @"Multiple ranges selected"; + } + } + if (! string) string = @""; + [[self view] setString:string]; +} + +- (void)setUseDecimalLength:(bool)useDecimalLength +{ + _useDecimalLength = useDecimalLength; + [self updateString]; +} + +- (void)setBaseAddress:(uint16_t)baseAddress +{ + _baseAddress = baseAddress; + [self updateString]; +} + +- (void) setBankForDescription:(uint16_t)bankForDescription +{ + _bankForDescription = bankForDescription; + [self updateString]; +} + +- (void)controllerDidChange:(HFControllerPropertyBits)bits +{ + if (bits & (HFControllerContentLength | HFControllerSelectedRanges)) { + [self updateString]; + } +} + ++ (NSPoint)defaultLayoutPosition +{ + return NSMakePoint(0, -1); +} + +@end diff --git a/Core/debugger.c b/Core/debugger.c index 779f577..c7f3bc1 100644 --- a/Core/debugger.c +++ b/Core/debugger.c @@ -2606,16 +2606,37 @@ const GB_bank_symbol_t *GB_debugger_find_symbol(GB_gameboy_t *gb, uint16_t addr, const GB_bank_symbol_t *symbol = GB_map_find_symbol(get_symbol_map(gb, bank), addr, prefer_local); if (symbol) return symbol; - if (bank != 0) return GB_map_find_symbol(get_symbol_map(gb, 0), addr, false); /* Maybe the symbol incorrectly uses bank 0? */ + if (bank != 0) return GB_map_find_symbol(get_symbol_map(gb, 0), addr, prefer_local); /* Maybe the symbol incorrectly uses bank 0? */ return NULL; } const char *GB_debugger_name_for_address(GB_gameboy_t *gb, uint16_t addr) { - const GB_bank_symbol_t *symbol = GB_debugger_find_symbol(gb, addr, false); - if (symbol && symbol->addr == addr) return symbol->name; - return NULL; + return GB_debugger_describe_address(gb, addr, -1, true, false); +} + +const char *GB_debugger_describe_address(GB_gameboy_t *gb, + uint16_t addr, uint16_t bank, + bool exact_match, bool prefer_local) +{ + if (bank == (uint16_t)-1) { + bank = bank_for_addr(gb, addr); + } + if (exact_match) { + const GB_bank_symbol_t *symbol = GB_map_find_symbol(get_symbol_map(gb, bank), addr, prefer_local); + if (symbol && symbol->addr == addr) return symbol->name; + if (bank != 0) symbol = GB_map_find_symbol(get_symbol_map(gb, 0), addr, prefer_local); /* Maybe the symbol incorrectly uses bank 0? */ + if (symbol && symbol->addr == addr) return symbol->name; + + return NULL; + } + + return debugger_value_to_string(gb, (value_t){ + .value = addr, + .bank = bank, + .has_bank = true, + }, true, prefer_local); } /* The public version of debugger_evaluate */ diff --git a/Core/debugger.h b/Core/debugger.h index 372cc1a..8b46b70 100644 --- a/Core/debugger.h +++ b/Core/debugger.h @@ -15,6 +15,8 @@ GB_debugger_execute_command(GB_gameboy_t *gb, char *input); /* Destroys input. * char *GB_debugger_complete_substring(GB_gameboy_t *gb, char *input, uintptr_t *context); /* Destroys input, result requires free */ void GB_debugger_load_symbol_file(GB_gameboy_t *gb, const char *path); const char *GB_debugger_name_for_address(GB_gameboy_t *gb, uint16_t addr); +/* Use -1 for bank to use the currently mapped bank */ +const char *GB_debugger_describe_address(GB_gameboy_t *gb, uint16_t addr, uint16_t bank, bool exact_match, bool prefer_local); bool GB_debugger_evaluate(GB_gameboy_t *gb, const char *string, uint16_t *result, uint16_t *result_bank); /* result_bank is -1 if unused. */ bool GB_debugger_is_stopped(GB_gameboy_t *gb); void GB_debugger_set_disabled(GB_gameboy_t *gb, bool disabled); diff --git a/HexFiend/HFStatusBarRepresenter.h b/HexFiend/HFStatusBarRepresenter.h deleted file mode 100644 index e70b893..0000000 --- a/HexFiend/HFStatusBarRepresenter.h +++ /dev/null @@ -1,31 +0,0 @@ -// -// HFStatusBarRepresenter.h -// HexFiend_2 -// -// Copyright 2007 ridiculous_fish. All rights reserved. -// - -#import - -/*! @enum HFStatusBarMode - The HFStatusBarMode enum is used to describe the format of the byte counts displayed by the status bar. -*/ -typedef NS_ENUM(NSUInteger, HFStatusBarMode) { - HFStatusModeDecimal, ///< The status bar should display byte counts in decimal - HFStatusModeHexadecimal, ///< The status bar should display byte counts in hexadecimal - HFStatusModeApproximate, ///< The text should display byte counts approximately (e.g. "56.3 KB") - HFSTATUSMODECOUNT ///< The number of modes, to allow easy cycling -}; - -/*! @class HFStatusBarRepresenter - @brief The HFRepresenter for the status bar. - - HFStatusBarRepresenter is a subclass of HFRepresenter responsible for showing the status bar, which displays information like the total length of the document, or the number of selected bytes. -*/ -@interface HFStatusBarRepresenter : HFRepresenter { - HFStatusBarMode statusMode; -} - -@property (nonatomic) HFStatusBarMode statusMode; - -@end diff --git a/HexFiend/HFStatusBarRepresenter.m b/HexFiend/HFStatusBarRepresenter.m deleted file mode 100644 index 883677f..0000000 --- a/HexFiend/HFStatusBarRepresenter.m +++ /dev/null @@ -1,240 +0,0 @@ -// -// HFStatusBarRepresenter.m -// HexFiend_2 -// -// Copyright 2007 ridiculous_fish. All rights reserved. -// - -#import -#import - -#define kHFStatusBarDefaultModeUserDefaultsKey @"HFStatusBarDefaultMode" - -@interface HFStatusBarView : NSView { - NSCell *cell; - NSSize cellSize; - HFStatusBarRepresenter *representer; - NSDictionary *cellAttributes; - BOOL registeredForAppNotifications; -} - -- (void)setRepresenter:(HFStatusBarRepresenter *)rep; -- (void)setString:(NSString *)string; - -@end - - -@implementation HFStatusBarView - -- (void)_sharedInitStatusBarView { - NSMutableParagraphStyle *style = [[[NSParagraphStyle defaultParagraphStyle] mutableCopy] autorelease]; - [style setAlignment:NSCenterTextAlignment]; - cellAttributes = [[NSDictionary alloc] initWithObjectsAndKeys:[NSColor windowFrameTextColor], NSForegroundColorAttributeName, [NSFont labelFontOfSize:[NSFont smallSystemFontSize]], NSFontAttributeName, style, NSParagraphStyleAttributeName, nil]; - cell = [[NSCell alloc] initTextCell:@""]; - [cell setAlignment:NSCenterTextAlignment]; - [cell setBackgroundStyle:NSBackgroundStyleRaised]; -} - -- (instancetype)initWithFrame:(NSRect)frame { - self = [super initWithFrame:frame]; - [self _sharedInitStatusBarView]; - return self; -} - -- (instancetype)initWithCoder:(NSCoder *)coder { - HFASSERT([coder allowsKeyedCoding]); - self = [super initWithCoder:coder]; - [self _sharedInitStatusBarView]; - return self; -} - -// nothing to do in encodeWithCoder - -- (BOOL)isFlipped { return YES; } - -- (void)setRepresenter:(HFStatusBarRepresenter *)rep { - representer = rep; -} - -- (void)setString:(NSString *)string { - [cell setAttributedStringValue:[[[NSAttributedString alloc] initWithString:string attributes:cellAttributes] autorelease]]; - cellSize = [cell cellSize]; - [self setNeedsDisplay:YES]; -} - -- (void)drawRect:(NSRect)clip { - USE(clip); - NSRect bounds = [self bounds]; - // [[NSColor colorWithCalibratedWhite:(CGFloat).91 alpha:1] set]; - // NSRectFill(clip); - - - NSRect cellRect = NSMakeRect(NSMinX(bounds), HFCeil(NSMidY(bounds) - cellSize.height / 2), NSWidth(bounds), cellSize.height); - [cell drawWithFrame:cellRect inView:self]; -} - -- (void)setFrame:(NSRect)frame -{ - [super setFrame:frame]; - [self.window setContentBorderThickness:frame.origin.y + frame.size.height forEdge:NSMinYEdge]; -} - - -- (void)mouseDown:(NSEvent *)event { - USE(event); - HFStatusBarMode newMode = ([representer statusMode] + 1) % HFSTATUSMODECOUNT; - [representer setStatusMode:newMode]; - [[NSUserDefaults standardUserDefaults] setInteger:newMode forKey:kHFStatusBarDefaultModeUserDefaultsKey]; -} - -- (void)windowDidChangeKeyStatus:(NSNotification *)note { - USE(note); - [self setNeedsDisplay:YES]; -} - -- (void)viewDidMoveToWindow { - HFRegisterViewForWindowAppearanceChanges(self, @selector(windowDidChangeKeyStatus:), !registeredForAppNotifications); - registeredForAppNotifications = YES; - [self.window setContentBorderThickness:self.frame.origin.y + self.frame.size.height forEdge:NSMinYEdge]; - [super viewDidMoveToWindow]; -} - -- (void)viewWillMoveToWindow:(NSWindow *)newWindow { - HFUnregisterViewForWindowAppearanceChanges(self, NO); - [super viewWillMoveToWindow:newWindow]; -} - -- (void)dealloc { - HFUnregisterViewForWindowAppearanceChanges(self, registeredForAppNotifications); - [cell release]; - [cellAttributes release]; - [super dealloc]; -} - -@end - -@implementation HFStatusBarRepresenter - -- (void)encodeWithCoder:(NSCoder *)coder { - HFASSERT([coder allowsKeyedCoding]); - [super encodeWithCoder:coder]; - [coder encodeInt64:statusMode forKey:@"HFStatusMode"]; -} - -- (instancetype)initWithCoder:(NSCoder *)coder { - HFASSERT([coder allowsKeyedCoding]); - self = [super initWithCoder:coder]; - statusMode = (NSUInteger)[coder decodeInt64ForKey:@"HFStatusMode"]; - return self; -} - -- (instancetype)init { - self = [super init]; - statusMode = [[NSUserDefaults standardUserDefaults] integerForKey:kHFStatusBarDefaultModeUserDefaultsKey]; - return self; -} - -- (NSView *)createView { - HFStatusBarView *view = [[HFStatusBarView alloc] initWithFrame:NSMakeRect(0, 0, 100, 18)]; - [view setRepresenter:self]; - [view setAutoresizingMask:NSViewWidthSizable]; - return view; -} - -- (NSString *)describeLength:(unsigned long long)length { - switch (statusMode) { - case HFStatusModeDecimal: return [NSString stringWithFormat:@"%llu byte%s", length, length == 1 ? "" : "s"]; - case HFStatusModeHexadecimal: return [NSString stringWithFormat:@"0x%llX byte%s", length, length == 1 ? "" : "s"]; - case HFStatusModeApproximate: return [NSString stringWithFormat:@"%@", HFDescribeByteCount(length)]; - default: [NSException raise:NSInternalInconsistencyException format:@"Unknown status mode %lu", (unsigned long)statusMode]; return @""; - } -} - -- (NSString *)describeOffset:(unsigned long long)offset { - switch (statusMode) { - case HFStatusModeDecimal: return [NSString stringWithFormat:@"%llu", offset]; - case HFStatusModeHexadecimal: return [NSString stringWithFormat:@"0x%llX", offset]; - case HFStatusModeApproximate: return [NSString stringWithFormat:@"%@", HFDescribeByteCount(offset)]; - default: [NSException raise:NSInternalInconsistencyException format:@"Unknown status mode %lu", (unsigned long)statusMode]; return @""; - } -} - -/* same as describeOffset, except we treat Approximate like Hexadecimal */ -- (NSString *)describeOffsetExcludingApproximate:(unsigned long long)offset { - switch (statusMode) { - case HFStatusModeDecimal: return [NSString stringWithFormat:@"%llu", offset]; - case HFStatusModeHexadecimal: - case HFStatusModeApproximate: return [NSString stringWithFormat:@"0x%llX", offset]; - default: [NSException raise:NSInternalInconsistencyException format:@"Unknown status mode %lu", (unsigned long)statusMode]; return @""; - } -} - -- (NSString *)stringForEmptySelectionAtOffset:(unsigned long long)offset length:(unsigned long long)length { - return [NSString stringWithFormat:@"%@ out of %@", [self describeOffset:offset], [self describeLength:length]]; -} - -- (NSString *)stringForSingleByteSelectionAtOffset:(unsigned long long)offset length:(unsigned long long)length { - return [NSString stringWithFormat:@"Byte %@ selected out of %@", [self describeOffset:offset], [self describeLength:length]]; -} - -- (NSString *)stringForSingleRangeSelection:(HFRange)range length:(unsigned long long)length { - return [NSString stringWithFormat:@"%@ selected at offset %@ out of %@", [self describeLength:range.length], [self describeOffsetExcludingApproximate:range.location], [self describeLength:length]]; -} - -- (NSString *)stringForMultipleSelectionsWithLength:(unsigned long long)multipleSelectionLength length:(unsigned long long)length { - return [NSString stringWithFormat:@"%@ selected at multiple offsets out of %@", [self describeLength:multipleSelectionLength], [self describeLength:length]]; -} - - -- (void)updateString { - NSString *string = nil; - HFController *controller = [self controller]; - if (controller) { - unsigned long long length = [controller contentsLength]; - NSArray *ranges = [controller selectedContentsRanges]; - NSUInteger rangeCount = [ranges count]; - if (rangeCount == 1) { - HFRange range = [ranges[0] HFRange]; - if (range.length == 0) { - string = [self stringForEmptySelectionAtOffset:range.location length:length]; - } - else if (range.length == 1) { - string = [self stringForSingleByteSelectionAtOffset:range.location length:length]; - } - else { - string = [self stringForSingleRangeSelection:range length:length]; - } - } - else { - unsigned long long totalSelectionLength = 0; - FOREACH(HFRangeWrapper *, wrapper, ranges) { - HFRange range = [wrapper HFRange]; - totalSelectionLength = HFSum(totalSelectionLength, range.length); - } - string = [self stringForMultipleSelectionsWithLength:totalSelectionLength length:length]; - } - } - if (! string) string = @""; - [[self view] setString:string]; -} - -- (HFStatusBarMode)statusMode { - return statusMode; -} - -- (void)setStatusMode:(HFStatusBarMode)mode { - statusMode = mode; - [self updateString]; -} - -- (void)controllerDidChange:(HFControllerPropertyBits)bits { - if (bits & (HFControllerContentLength | HFControllerSelectedRanges)) { - [self updateString]; - } -} - -+ (NSPoint)defaultLayoutPosition { - return NSMakePoint(0, -1); -} - -@end diff --git a/HexFiend/HexFiend.h b/HexFiend/HexFiend.h index 60d69a7..0253cb8 100644 --- a/HexFiend/HexFiend.h +++ b/HexFiend/HexFiend.h @@ -28,7 +28,6 @@ #import #import #import -#import #import #import #import