From ab85971994517ccbac8fe75633646554cdefa00e Mon Sep 17 00:00:00 2001 From: Robert Sesek Date: Thu, 2 Jul 2020 13:34:03 -0400 Subject: [PATCH] Modernize the source view classes. --- MacGDBp.xcodeproj/project.pbxproj | 8 +- Source/BSLineNumberRulerView.h | 11 +- Source/BSLineNumberRulerView.mm | 56 +++++----- Source/BSSourceView.h | 19 +--- Source/{BSSourceView.mm => BSSourceView.m} | 120 ++++++++++----------- Source/BSSourceViewTextView.m | 4 +- 6 files changed, 96 insertions(+), 122 deletions(-) rename Source/{BSSourceView.mm => BSSourceView.m} (74%) diff --git a/MacGDBp.xcodeproj/project.pbxproj b/MacGDBp.xcodeproj/project.pbxproj index 114a8a3..b14f34b 100644 --- a/MacGDBp.xcodeproj/project.pbxproj +++ b/MacGDBp.xcodeproj/project.pbxproj @@ -27,7 +27,7 @@ 1E67E6FD0F3C052000E68F1B /* PreferencesPathsArrayController.m in Sources */ = {isa = PBXBuildFile; fileRef = 1E67E6FC0F3C052000E68F1B /* PreferencesPathsArrayController.m */; }; 1E6B5947116106FE001189D2 /* LoggingController.m in Sources */ = {isa = PBXBuildFile; fileRef = 1E6B5946116106FE001189D2 /* LoggingController.m */; }; 1E6B594C11610993001189D2 /* Log.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1E6B594A11610993001189D2 /* Log.xib */; }; - 1E7188690D839F6300969277 /* BSSourceView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1E7188650D839F6300969277 /* BSSourceView.mm */; }; + 1E7188690D839F6300969277 /* BSSourceView.m in Sources */ = {isa = PBXBuildFile; fileRef = 1E7188650D839F6300969277 /* BSSourceView.m */; }; 1E822CDD0DA28AC30027A23F /* Breakpoint.m in Sources */ = {isa = PBXBuildFile; fileRef = 1E822CDC0DA28AC30027A23F /* Breakpoint.m */; }; 1E87EFD1232B800900FF6348 /* BreakpointManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 1E4C7AF80DA401C7000A9DC7 /* BreakpointManager.m */; }; 1E87EFD4232B806D00FF6348 /* Breakpoint.m in Sources */ = {isa = PBXBuildFile; fileRef = 1E822CDC0DA28AC30027A23F /* Breakpoint.m */; }; @@ -115,7 +115,7 @@ 1E6B5945116106FE001189D2 /* LoggingController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LoggingController.h; path = Source/LoggingController.h; sourceTree = ""; }; 1E6B5946116106FE001189D2 /* LoggingController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = LoggingController.m; path = Source/LoggingController.m; sourceTree = ""; }; 1E7188640D839F6300969277 /* BSSourceView.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = BSSourceView.h; path = Source/BSSourceView.h; sourceTree = ""; }; - 1E7188650D839F6300969277 /* BSSourceView.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = BSSourceView.mm; path = Source/BSSourceView.mm; sourceTree = ""; }; + 1E7188650D839F6300969277 /* BSSourceView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = BSSourceView.m; path = Source/BSSourceView.m; sourceTree = ""; }; 1E822CDB0DA28AC30027A23F /* Breakpoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Breakpoint.h; path = Source/Breakpoint.h; sourceTree = ""; }; 1E822CDC0DA28AC30027A23F /* Breakpoint.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Breakpoint.m; path = Source/Breakpoint.m; sourceTree = ""; }; 1E87EFD2232B805800FF6348 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; }; @@ -286,7 +286,7 @@ isa = PBXGroup; children = ( 1E7188640D839F6300969277 /* BSSourceView.h */, - 1E7188650D839F6300969277 /* BSSourceView.mm */, + 1E7188650D839F6300969277 /* BSSourceView.m */, 1EDA9CF612DD13B300596211 /* BSLineNumberRulerView.h */, 1EDA9CF712DD13B300596211 /* BSLineNumberRulerView.mm */, 1E1181481319805E003BFEF1 /* BSSourceViewTextView.h */, @@ -548,7 +548,7 @@ 1E02C5F60C610724006F1752 /* DebuggerController.m in Sources */, 1E35FC760C6579CA0030F527 /* NSXMLElementAdditions.m in Sources */, 1E3F9D941CBAB57B005D896B /* PreferenceNames.m in Sources */, - 1E7188690D839F6300969277 /* BSSourceView.mm in Sources */, + 1E7188690D839F6300969277 /* BSSourceView.m in Sources */, 1E822CDD0DA28AC30027A23F /* Breakpoint.m in Sources */, 1E4C7AF90DA401C7000A9DC7 /* BreakpointManager.m in Sources */, 1EFF70C30DFDC018006B9D33 /* BreakpointController.m in Sources */, diff --git a/Source/BSLineNumberRulerView.h b/Source/BSLineNumberRulerView.h index b125222..ae937b5 100644 --- a/Source/BSLineNumberRulerView.h +++ b/Source/BSLineNumberRulerView.h @@ -15,7 +15,6 @@ */ #import -#include @class BSSourceView; @@ -24,17 +23,9 @@ // http://www.noodlesoft.com/blog/2008/10/05/displaying-line-numbers-with-nstextview/ // However, all code is original. @interface BSLineNumberRulerView : NSRulerView -{ - @private - BSSourceView* sourceView_; // Weak, owns this. - - // A vector (thus 0-based) map of line numbers (indices) to character indices - // in the text storage. - std::vector lineIndex_; -} // Designated initializer. -- (id)initWithSourceView:(BSSourceView*)sourceView; +- (instancetype)initWithSourceView:(BSSourceView*)sourceView; // Performs layout and redraws the line number view. - (void)performLayout; diff --git a/Source/BSLineNumberRulerView.mm b/Source/BSLineNumberRulerView.mm index 0db146d..b51143f 100644 --- a/Source/BSLineNumberRulerView.mm +++ b/Source/BSLineNumberRulerView.mm @@ -17,6 +17,7 @@ #import "BSLineNumberRulerView.h" #include +#include #import "Breakpoint.h" #import "BSSourceView.h" @@ -42,15 +43,20 @@ const CGFloat kRulerRightPadding = 2.5; // }} +@implementation BSLineNumberRulerView { + BSSourceView* _sourceView; // Weak, owns this. -@implementation BSLineNumberRulerView + // A vector (thus 0-based) map of line numbers (indices) to character indices + // in the text storage. + std::vector _lineIndex; +} -- (id)initWithSourceView:(BSSourceView*)sourceView +- (instancetype)initWithSourceView:(BSSourceView*)sourceView { if (self = [super initWithScrollView:[sourceView scrollView] orientation:NSVerticalRuler]) { - sourceView_ = sourceView; - [self setClientView:[[sourceView_ scrollView] documentView]]; + _sourceView = sourceView; + [self setClientView:[[_sourceView scrollView] documentView]]; [self setRuleThickness:kDefaultWidth]; } return self; @@ -58,7 +64,7 @@ const CGFloat kRulerRightPadding = 2.5; - (void)awakeFromNib { - [self setClientView:[[sourceView_ scrollView] documentView]]; + [self setClientView:[[_sourceView scrollView] documentView]]; [self setRuleThickness:kDefaultWidth]; } @@ -74,7 +80,7 @@ const CGFloat kRulerRightPadding = 2.5; toPoint:NSMakePoint(NSMaxX(rect), NSMaxY(rect))]; // Get some common elements of the source view. - NSTextView* textView = [sourceView_ textView]; + NSTextView* textView = [_sourceView textView]; NSLayoutManager* layoutManager = [textView layoutManager]; NSTextContainer* textContainer = [textView textContainer]; NSRect visibleRect = [[[self scrollView] contentView] bounds]; @@ -87,20 +93,20 @@ const CGFloat kRulerRightPadding = 2.5; // Load any markers. The superview takes care of filtering out for just the // curently displayed file. - NSSet* markers = [sourceView_ markers]; + NSSet* markers = [_sourceView markers]; // Go through the lines. const NSRange kNullRange = NSMakeRange(NSNotFound, 0); const CGFloat yOffset = [textView textContainerInset].height; - const size_t lineCount = lineIndex_.size(); + const size_t lineCount = _lineIndex.size(); std::vector::iterator element = - std::lower_bound(lineIndex_.begin(), - lineIndex_.end(), + std::lower_bound(_lineIndex.begin(), + _lineIndex.end(), characterRange.location); - for (NSUInteger line = std::distance(lineIndex_.begin(), element); + for (NSUInteger line = std::distance(_lineIndex.begin(), element); line < lineCount; ++line) { - NSUInteger firstCharacterIndex = lineIndex_[line]; + NSUInteger firstCharacterIndex = _lineIndex[line]; // Stop after iterating past the end of the visible range. if (firstCharacterIndex > NSMaxRange(characterRange)) break; @@ -130,7 +136,7 @@ const CGFloat kRulerRightPadding = 2.5; if ([markers containsObject:@(lineNumber)]) { [self drawBreakpointInRect:drawRect]; } - if (sourceView_.markedLine == lineNumber) { + if (_sourceView.markedLine == lineNumber) { [self drawProgramCounterInRect:drawRect]; } } @@ -142,10 +148,10 @@ const CGFloat kRulerRightPadding = 2.5; [self computeLineIndex]; // Determine the width of the ruler based on the line count. - if (lineIndex_.empty()) { + if (_lineIndex.empty()) { [self setRuleThickness:kDefaultWidth]; } else { - NSUInteger lastElement = lineIndex_.back() + 1; + NSUInteger lastElement = _lineIndex.back() + 1; NSAttributedString* lastElementString = [self attributedStringForLineNumber:lastElement]; NSSize boundingSize = [lastElementString size]; [self setRuleThickness:std::max(kDefaultWidth, boundingSize.width)]; @@ -157,7 +163,7 @@ const CGFloat kRulerRightPadding = 2.5; - (NSUInteger)lineNumberAtPoint:(NSPoint)point { // Get some common elements of the source view. - NSTextView* textView = [sourceView_ textView]; + NSTextView* textView = [_sourceView textView]; NSLayoutManager* layoutManager = [textView layoutManager]; NSTextContainer* textContainer = [textView textContainer]; NSRect visibleRect = [[[self scrollView] contentView] bounds]; @@ -165,9 +171,9 @@ const CGFloat kRulerRightPadding = 2.5; const CGFloat kWidth = NSWidth([self bounds]); const NSRange kNullRange = NSMakeRange(NSNotFound, 0); - const size_t lineCount = lineIndex_.size(); + const size_t lineCount = _lineIndex.size(); for (NSUInteger line = 0; line < lineCount; ++line) { - NSUInteger firstCharacterIndex = lineIndex_[line]; + NSUInteger firstCharacterIndex = _lineIndex[line]; NSUInteger rectCount; NSRectArray frameRects = @@ -191,7 +197,7 @@ const CGFloat kRulerRightPadding = 2.5; point = [self convertPoint:point fromView:nil]; NSUInteger line = [self lineNumberAtPoint:point]; if (line != NSNotFound) - [sourceView_.delegate gutterClickedAtLine:line forFile:sourceView_.file]; + [_sourceView.delegate gutterClickedAtLine:line forFile:_sourceView.file]; } // Private ///////////////////////////////////////////////////////////////////// @@ -202,27 +208,27 @@ const CGFloat kRulerRightPadding = 2.5; */ - (void)computeLineIndex { - lineIndex_.clear(); + _lineIndex.clear(); - NSString* text = [[sourceView_ textView] string]; + NSString* text = [[_sourceView textView] string]; NSUInteger stringLength = [text length]; NSUInteger index = 0; while (index < stringLength) { - lineIndex_.push_back(index); + _lineIndex.push_back(index); index = NSMaxRange([text lineRangeForRange:NSMakeRange(index, 0)]); } - if (lineIndex_.empty()) + if (_lineIndex.empty()) return; NSUInteger lineEnd, contentEnd; [text getLineStart:NULL end:&lineEnd contentsEnd:&contentEnd - forRange:NSMakeRange(lineIndex_.back(), 0)]; + forRange:NSMakeRange(_lineIndex.back(), 0)]; if (contentEnd < lineEnd) - lineIndex_.push_back(index); + _lineIndex.push_back(index); } /** diff --git a/Source/BSSourceView.h b/Source/BSSourceView.h index 2bfb18d..f02d619 100644 --- a/Source/BSSourceView.h +++ b/Source/BSSourceView.h @@ -26,25 +26,12 @@ // // Rather than setting the string of the text view directly, use the provided // methods to load from a file path or to load a string as a virtual file. -@interface BSSourceView : NSView { - @private - BSSourceViewTextView* textView_; - BSLineNumberRulerView* ruler_; - NSScrollView* scrollView_; - - // Line numbers to mark. - NSSet* markers_; - - NSString* file_; - NSUInteger markedLine_; - - id __weak delegate_; -} +@interface BSSourceView : NSView @property (nonatomic, readonly) NSTextView* textView; @property (nonatomic, readonly) NSScrollView* scrollView; -@property (nonatomic, retain) NSSet* markers; -@property (nonatomic, retain) NSString* file; +@property (nonatomic, copy) NSSet* markers; +@property (nonatomic, copy) NSString* file; @property (nonatomic, assign) NSUInteger markedLine; @property (nonatomic, weak) id delegate; diff --git a/Source/BSSourceView.mm b/Source/BSSourceView.m similarity index 74% rename from Source/BSSourceView.mm rename to Source/BSSourceView.m index 42f7da9..144e6aa 100644 --- a/Source/BSSourceView.mm +++ b/Source/BSSourceView.m @@ -25,41 +25,34 @@ - (void)setPlainTextStringFromFile:(NSString*)filePath; @end -@implementation BSSourceView +@implementation BSSourceView { + BSSourceViewTextView* _textView; + BSLineNumberRulerView* _ruler; + NSScrollView* _scrollView; -@synthesize textView = textView_; -@synthesize scrollView = scrollView_; -@synthesize markers = markers_; -@synthesize markedLine = markedLine_; -@synthesize delegate = delegate_; -@synthesize file = file_; + // Line numbers to mark. + NSSet* _markers; + + NSString* _file; +} -/** - * Initializes the source view with the path of a file - */ - (id)initWithFrame:(NSRect)frame { if (self = [super initWithFrame:frame]) { [self setupViews]; - [[NSNotificationCenter defaultCenter] - addObserver:self - selector:@selector(errorHighlightingFile:) - name:NSFileHandleReadToEndOfFileCompletionNotification - object:nil - ]; } return self; } - (void)setMarkers:(NSSet*)markers { - markers_ = [markers copy]; - [ruler_ setNeedsDisplay:YES]; + _markers = [markers copy]; + [_ruler setNeedsDisplay:YES]; } - (void)setMarkedLine:(NSUInteger)markedLine { - markedLine_ = markedLine; - [ruler_ setNeedsDisplay:YES]; - [textView_ setNeedsDisplay:YES]; + _markedLine = markedLine; + [_ruler setNeedsDisplay:YES]; + [_textView setNeedsDisplay:YES]; } /** @@ -68,10 +61,10 @@ */ - (void)setFile:(NSString*)f { - file_ = f; + _file = [f copy]; if (![[NSFileManager defaultManager] fileExistsAtPath:f]) { - [textView_ setString:@""]; + [_textView setString:@""]; return; } @@ -83,14 +76,14 @@ */ - (void)setString:(NSString*)source asFile:(NSString*)path { - file_ = path; + _file = [path copy]; // Write the source out as a temporary file so it can be highlighted. NSError* error = nil; NSString* tmpPath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"MacGDBpHighlighter"]; [source writeToFile:tmpPath atomically:NO encoding:NSUTF8StringEncoding error:&error]; if (error) { - [textView_ setString:source]; + [_textView setString:source]; return; } @@ -112,22 +105,22 @@ */ - (void)scrollToLine:(NSUInteger)line { - if ([[textView_ textStorage] length] == 0) + if ([[_textView textStorage] length] == 0) return; // go through the document until we find the NSRange for the line we want NSUInteger rangeIndex = 0; for (NSUInteger i = 0; i < line; i++) { - rangeIndex = NSMaxRange([[textView_ string] lineRangeForRange:NSMakeRange(rangeIndex, 0)]); + rangeIndex = NSMaxRange([[_textView string] lineRangeForRange:NSMakeRange(rangeIndex, 0)]); } // now get the true start/end markers for it NSUInteger lineStart, lineEnd; - [[textView_ string] getLineStart:&lineStart + [[_textView string] getLineStart:&lineStart end:NULL contentsEnd:&lineEnd forRange:NSMakeRange(rangeIndex - 1, 0)]; - [textView_ scrollRangeToVisible:[[textView_ string] + [_textView scrollRangeToVisible:[[_textView string] lineRangeForRange:NSMakeRange(lineStart, lineEnd - lineStart)]]; } @@ -151,42 +144,41 @@ - (void)setupViews { // Create the scroll view. - scrollView_ = [[NSScrollView alloc] initWithFrame:[self bounds]]; - [scrollView_ setHasHorizontalScroller:YES]; - [scrollView_ setHasVerticalScroller:YES]; - [scrollView_ setAutohidesScrollers:YES]; - [scrollView_ setBorderType:NSBezelBorder]; - [scrollView_ setAutoresizingMask:(NSViewWidthSizable | NSViewHeightSizable)]; - [[scrollView_ contentView] setAutoresizesSubviews:YES]; - [self addSubview:scrollView_]; + _scrollView = [[NSScrollView alloc] initWithFrame:[self bounds]]; + [_scrollView setHasHorizontalScroller:YES]; + [_scrollView setHasVerticalScroller:YES]; + [_scrollView setAutohidesScrollers:YES]; + [_scrollView setBorderType:NSBezelBorder]; + [_scrollView setAutoresizingMask:(NSViewWidthSizable | NSViewHeightSizable)]; + [[_scrollView contentView] setAutoresizesSubviews:YES]; + [self addSubview:_scrollView]; // add the text view to the scroll view NSRect textFrame; textFrame.origin = NSMakePoint(0.0, 0.0); - textFrame.size = [scrollView_ contentSize]; - textView_ = [[BSSourceViewTextView alloc] initWithFrame:textFrame]; - [textView_ setSourceView:self]; - [textView_ setEditable:NO]; - [textView_ setFont:[[self class] sourceFont]]; - [textView_ setHorizontallyResizable:YES]; - [textView_ setVerticallyResizable:YES]; - [textView_ setMinSize:textFrame.size]; - [textView_ setMaxSize:NSMakeSize(FLT_MAX, FLT_MAX)]; - [[textView_ textContainer] setContainerSize:NSMakeSize(FLT_MAX, FLT_MAX)]; - [[textView_ textContainer] setWidthTracksTextView:NO]; - [[textView_ textContainer] setHeightTracksTextView:NO]; - [textView_ setAutoresizingMask:NSViewNotSizable]; - [scrollView_ setDocumentView:textView_]; + textFrame.size = [_scrollView contentSize]; + _textView = [[BSSourceViewTextView alloc] initWithFrame:textFrame]; + [_textView setSourceView:self]; + [_textView setEditable:NO]; + [_textView setFont:[[self class] sourceFont]]; + [_textView setHorizontallyResizable:YES]; + [_textView setVerticallyResizable:YES]; + [_textView setMinSize:textFrame.size]; + [_textView setMaxSize:NSMakeSize(FLT_MAX, FLT_MAX)]; + [[_textView textContainer] setContainerSize:NSMakeSize(FLT_MAX, FLT_MAX)]; + [[_textView textContainer] setWidthTracksTextView:NO]; + [[_textView textContainer] setHeightTracksTextView:NO]; + [_textView setAutoresizingMask:NSViewNotSizable]; + [_scrollView setDocumentView:_textView]; // Set up the ruler. - ruler_ = [[BSLineNumberRulerView alloc] initWithSourceView:self]; - [scrollView_ setVerticalRulerView:ruler_]; - [scrollView_ setHasHorizontalRuler:NO]; - [scrollView_ setHasVerticalRuler:YES]; - [scrollView_ setRulersVisible:YES]; - - NSArray* types = [NSArray arrayWithObject:NSFilenamesPboardType]; - [self registerForDraggedTypes:types]; + _ruler = [[BSLineNumberRulerView alloc] initWithSourceView:self]; + [_scrollView setVerticalRulerView:_ruler]; + [_scrollView setHasHorizontalRuler:NO]; + [_scrollView setHasVerticalRuler:YES]; + [_scrollView setRulersVisible:YES]; + + [self registerForDraggedTypes:@[ NSFilenamesPboardType ]]; } NSString* ColorHEXStringINIDirective(NSString* directive, NSColor* color) { @@ -248,12 +240,12 @@ NSString* ColorHEXStringINIDirective(NSString* directive, NSColor* color) { } if (source) { - [[textView_ textStorage] setAttributedString:source]; + [[_textView textStorage] setAttributedString:source]; } else { [self setPlainTextStringFromFile:filePath]; } - [ruler_ performLayout]; + [_ruler performLayout]; if (handler) { handler(); @@ -277,12 +269,12 @@ NSString* ColorHEXStringINIDirective(NSString* directive, NSColor* color) { error:&error]; if (error) { NSLog(@"Error reading file at %@: %@", filePath, error); - if ([delegate_ respondsToSelector:@selector(error:whileHighlightingFile:)]) { - [delegate_ error:error whileHighlightingFile:filePath]; + if ([_delegate respondsToSelector:@selector(error:whileHighlightingFile:)]) { + [_delegate error:error whileHighlightingFile:filePath]; } return; } - [textView_ setString:contents]; + [_textView setString:contents]; } // Drag Handlers /////////////////////////////////////////////////////////////// diff --git a/Source/BSSourceViewTextView.m b/Source/BSSourceViewTextView.m index 9a7370e..79fc0eb 100644 --- a/Source/BSSourceViewTextView.m +++ b/Source/BSSourceViewTextView.m @@ -20,8 +20,6 @@ @implementation BSSourceViewTextView -@synthesize sourceView = sourceView_; - - (void)drawRect:(NSRect)rect { [super drawRect:rect]; @@ -32,7 +30,7 @@ NSRange fragRange; NSRect fragRect = [layoutManager lineFragmentRectForGlyphAtIndex:i effectiveRange:&fragRange]; - if ([sourceView_ markedLine] == line) { + if ([_sourceView markedLine] == line) { fragRect = [self convertRect:fragRect fromView:self]; fragRect.origin.x = rect.origin.x; // Flush all the way to the edge. [[[NSColor redColor] colorWithAlphaComponent:0.25] set]; -- 2.22.5