diff options
author | Neil <nyamatongwe@gmail.com> | 2017-06-08 14:51:06 +1000 |
---|---|---|
committer | Neil <nyamatongwe@gmail.com> | 2017-06-08 14:51:06 +1000 |
commit | 69870956666618aa5c8194abf6fb2967fa14d064 (patch) | |
tree | 918076df19a01bab706645855f6bcea635bb52ff | |
parent | 37508011503a9e6b451759197754bbd04869a230 (diff) | |
download | scintilla-mirror-69870956666618aa5c8194abf6fb2967fa14d064.tar.gz |
Indented consistently by using astyle.
-rw-r--r-- | cocoa/InfoBar.h | 28 | ||||
-rw-r--r-- | cocoa/InfoBar.mm | 530 | ||||
-rw-r--r-- | cocoa/InfoBarCommunicator.h | 18 | ||||
-rw-r--r-- | cocoa/PlatCocoa.h | 154 | ||||
-rw-r--r-- | cocoa/PlatCocoa.mm | 2688 | ||||
-rw-r--r-- | cocoa/QuartzTextLayout.h | 73 | ||||
-rw-r--r-- | cocoa/QuartzTextStyle.h | 54 | ||||
-rw-r--r-- | cocoa/QuartzTextStyleAttribute.h | 38 | ||||
-rw-r--r-- | cocoa/ScintillaCocoa.h | 318 | ||||
-rw-r--r-- | cocoa/ScintillaCocoa.mm | 2712 | ||||
-rw-r--r-- | cocoa/ScintillaView.h | 110 | ||||
-rw-r--r-- | cocoa/ScintillaView.mm | 2494 |
12 files changed, 4281 insertions, 4936 deletions
diff --git a/cocoa/InfoBar.h b/cocoa/InfoBar.h index 1ce139530..382e65a9c 100644 --- a/cocoa/InfoBar.h +++ b/cocoa/InfoBar.h @@ -16,32 +16,30 @@ /** * Extended text cell for vertically aligned text. */ -@interface VerticallyCenteredTextFieldCell : NSTextFieldCell -{ +@interface VerticallyCenteredTextFieldCell : NSTextFieldCell { BOOL mIsEditingOrSelecting; } @end -@interface InfoBar : NSView <InfoBarCommunicator> -{ +@interface InfoBar : NSView <InfoBarCommunicator> { @private - NSImage* mBackground; - IBDisplay mDisplayMask; + NSImage *mBackground; + IBDisplay mDisplayMask; - float mScaleFactor; - NSPopUpButton* mZoomPopup; + float mScaleFactor; + NSPopUpButton *mZoomPopup; - int mCurrentCaretX; - int mCurrentCaretY; - NSTextField* mCaretPositionLabel; - NSTextField* mStatusTextLabel; + int mCurrentCaretX; + int mCurrentCaretY; + NSTextField *mCaretPositionLabel; + NSTextField *mStatusTextLabel; - id <InfoBarCommunicator> mCallback; + id <InfoBarCommunicator> mCallback; } -- (void) notify: (NotificationType) type message: (NSString*) message location: (NSPoint) location - value: (float) value; +- (void) notify: (NotificationType) type message: (NSString *) message location: (NSPoint) location + value: (float) value; - (void) setCallback: (id <InfoBarCommunicator>) callback; - (void) createItems; diff --git a/cocoa/InfoBar.mm b/cocoa/InfoBar.mm index 7f86ad697..eb37124a8 100644 --- a/cocoa/InfoBar.mm +++ b/cocoa/InfoBar.mm @@ -18,23 +18,20 @@ // Inspired by code from Daniel Jalkut, Red Sweater Software. -- (NSRect) drawingRectForBounds: (NSRect) theRect -{ +- (NSRect) drawingRectForBounds: (NSRect) theRect { // Get the parent's idea of where we should draw NSRect newRect = [super drawingRectForBounds: theRect]; // When the text field is being edited or selected, we have to turn off the magic because it - // screws up the configuration of the field editor. We sneak around this by intercepting - // selectWithFrame and editWithFrame and sneaking a reduced, centered rect in at the last minute. - if (mIsEditingOrSelecting == NO) - { + // screws up the configuration of the field editor. We sneak around this by intercepting + // selectWithFrame and editWithFrame and sneaking a reduced, centered rect in at the last minute. + if (mIsEditingOrSelecting == NO) { // Get our ideal size for current text NSSize textSize = [self cellSizeForBounds: theRect]; // Center that in the proposed rect CGFloat heightDelta = newRect.size.height - textSize.height; - if (heightDelta > 0) - { + if (heightDelta > 0) { newRect.size.height -= heightDelta; newRect.origin.y += ceil(heightDelta / 2); } @@ -45,32 +42,30 @@ //-------------------------------------------------------------------------------------------------- -- (void) selectWithFrame: (NSRect) aRect inView: (NSView*) controlView editor: (NSText*) textObj - delegate:(id) anObject start: (NSInteger) selStart length: (NSInteger) selLength -{ +- (void) selectWithFrame: (NSRect) aRect inView: (NSView *) controlView editor: (NSText *) textObj + delegate: (id) anObject start: (NSInteger) selStart length: (NSInteger) selLength { aRect = [self drawingRectForBounds: aRect]; mIsEditingOrSelecting = YES; [super selectWithFrame: aRect - inView: controlView - editor: textObj - delegate: anObject - start: selStart - length: selLength]; + inView: controlView + editor: textObj + delegate: anObject + start: selStart + length: selLength]; mIsEditingOrSelecting = NO; } //-------------------------------------------------------------------------------------------------- -- (void) editWithFrame: (NSRect) aRect inView: (NSView*) controlView editor: (NSText*) textObj - delegate: (id) anObject event: (NSEvent*) theEvent -{ +- (void) editWithFrame: (NSRect) aRect inView: (NSView *) controlView editor: (NSText *) textObj + delegate: (id) anObject event: (NSEvent *) theEvent { aRect = [self drawingRectForBounds: aRect]; mIsEditingOrSelecting = YES; [super editWithFrame: aRect - inView: controlView - editor: textObj - delegate: anObject - event: theEvent]; + inView: controlView + editor: textObj + delegate: anObject + event: theEvent]; mIsEditingOrSelecting = NO; } @@ -80,24 +75,22 @@ @implementation InfoBar -- (instancetype) initWithFrame: (NSRect) frame -{ - self = [super initWithFrame: frame]; - if (self) - { - NSBundle* bundle = [NSBundle bundleForClass: [InfoBar class]]; - - NSString* path = [bundle pathForResource: @"info_bar_bg" ofType: @"tiff" inDirectory: nil]; - mBackground = [[NSImage alloc] initWithContentsOfFile: path]; - if (!mBackground.valid) - NSLog(@"Background image for info bar is invalid."); - - mScaleFactor = 1.0; - mCurrentCaretX = 0; - mCurrentCaretY = 0; - [self createItems]; - } - return self; +- (instancetype) initWithFrame: (NSRect) frame { + self = [super initWithFrame: frame]; + if (self) { + NSBundle *bundle = [NSBundle bundleForClass: [InfoBar class]]; + + NSString *path = [bundle pathForResource: @"info_bar_bg" ofType: @"tiff" inDirectory: nil]; + mBackground = [[NSImage alloc] initWithContentsOfFile: path]; + if (!mBackground.valid) + NSLog(@"Background image for info bar is invalid."); + + mScaleFactor = 1.0; + mCurrentCaretX = 0; + mCurrentCaretY = 0; + [self createItems]; + } + return self; } //-------------------------------------------------------------------------------------------------- @@ -110,21 +103,19 @@ * @param location Carries the new location (e.g. caret) if the type is a caret change or similar type. * @param value Carries the new zoom value if the type is a zoom change. */ -- (void) notify: (NotificationType) type message: (NSString*) message location: (NSPoint) location - value: (float) value -{ - switch (type) - { - case IBNZoomChanged: - [self setScaleFactor: value adjustPopup: YES]; - break; - case IBNCaretChanged: - [self setCaretPosition: location]; - break; - case IBNStatusChanged: - mStatusTextLabel.stringValue = message; - break; - } +- (void) notify: (NotificationType) type message: (NSString *) message location: (NSPoint) location + value: (float) value { + switch (type) { + case IBNZoomChanged: + [self setScaleFactor: value adjustPopup: YES]; + break; + case IBNCaretChanged: + [self setCaretPosition: location]; + break; + case IBNStatusChanged: + mStatusTextLabel.stringValue = message; + break; + } } //-------------------------------------------------------------------------------------------------- @@ -132,94 +123,91 @@ /** * Used to set a protocol object we can use to send change notifications to. */ -- (void) setCallback: (id <InfoBarCommunicator>) callback -{ - mCallback = callback; +- (void) setCallback: (id <InfoBarCommunicator>) callback { + mCallback = callback; } //-------------------------------------------------------------------------------------------------- static NSString *DefaultScaleMenuLabels[] = { - @"20%", @"30%", @"50%", @"75%", @"100%", @"130%", @"160%", @"200%", @"250%", @"300%" + @"20%", @"30%", @"50%", @"75%", @"100%", @"130%", @"160%", @"200%", @"250%", @"300%" }; static float DefaultScaleMenuFactors[] = { - 0.2f, 0.3f, 0.5f, 0.75f, 1.0f, 1.3f, 1.6f, 2.0f, 2.5f, 3.0f + 0.2f, 0.3f, 0.5f, 0.75f, 1.0f, 1.3f, 1.6f, 2.0f, 2.5f, 3.0f }; static unsigned DefaultScaleMenuSelectedItemIndex = 4; static float BarFontSize = 10.0; -- (void) createItems -{ - // 1) The zoom popup. - unsigned numberOfDefaultItems = sizeof(DefaultScaleMenuLabels) / sizeof(NSString *); - - // Create the popup button. - mZoomPopup = [[NSPopUpButton alloc] initWithFrame: NSMakeRect(0.0, 0.0, 1.0, 1.0) pullsDown: NO]; - - // No border or background please. - [mZoomPopup.cell setBordered: NO]; - [mZoomPopup.cell setArrowPosition: NSPopUpArrowAtBottom]; - - // Fill it. - for (unsigned count = 0; count < numberOfDefaultItems; count++) - { - [mZoomPopup addItemWithTitle: NSLocalizedStringFromTable(DefaultScaleMenuLabels[count], @"ZoomValues", nil)]; - id currentItem = [mZoomPopup itemAtIndex: count]; - if (DefaultScaleMenuFactors[count] != 0.0) - [currentItem setRepresentedObject: @(DefaultScaleMenuFactors[count])]; - } - [mZoomPopup selectItemAtIndex: DefaultScaleMenuSelectedItemIndex]; - - // Hook it up. - mZoomPopup.target = self; - mZoomPopup.action = @selector(zoomItemAction:); - - // Set a suitable font. - mZoomPopup.font = [NSFont menuBarFontOfSize: BarFontSize]; - - // Make sure the popup is big enough to fit the cells. - [mZoomPopup sizeToFit]; - - // Don't let it become first responder - [mZoomPopup setRefusesFirstResponder: YES]; - - // put it in the scrollview. - [self addSubview: mZoomPopup]; - - // 2) The caret position label. - Class oldCellClass = [NSTextField cellClass]; - [NSTextField setCellClass: [VerticallyCenteredTextFieldCell class]]; - - mCaretPositionLabel = [[NSTextField alloc] initWithFrame: NSMakeRect(0.0, 0.0, 50.0, 1.0)]; - [mCaretPositionLabel setBezeled: NO]; - [mCaretPositionLabel setBordered: NO]; - [mCaretPositionLabel setEditable: NO]; - [mCaretPositionLabel setSelectable: NO]; - [mCaretPositionLabel setDrawsBackground: NO]; - mCaretPositionLabel.font = [NSFont menuBarFontOfSize: BarFontSize]; - - NSTextFieldCell* cell = mCaretPositionLabel.cell; - cell.placeholderString = @"0:0"; - cell.alignment = NSCenterTextAlignment; - - [self addSubview: mCaretPositionLabel]; - - // 3) The status text. - mStatusTextLabel = [[NSTextField alloc] initWithFrame: NSMakeRect(0.0, 0.0, 1.0, 1.0)]; - [mStatusTextLabel setBezeled: NO]; - [mStatusTextLabel setBordered: NO]; - [mStatusTextLabel setEditable: NO]; - [mStatusTextLabel setSelectable: NO]; - [mStatusTextLabel setDrawsBackground: NO]; - mStatusTextLabel.font = [NSFont menuBarFontOfSize: BarFontSize]; - - cell = mStatusTextLabel.cell; - cell.placeholderString = @""; - - [self addSubview: mStatusTextLabel]; - - // Restore original cell class so that everything else doesn't get broken - [NSTextField setCellClass: oldCellClass]; +- (void) createItems { + // 1) The zoom popup. + unsigned numberOfDefaultItems = sizeof(DefaultScaleMenuLabels) / sizeof(NSString *); + + // Create the popup button. + mZoomPopup = [[NSPopUpButton alloc] initWithFrame: NSMakeRect(0.0, 0.0, 1.0, 1.0) pullsDown: NO]; + + // No border or background please. + [mZoomPopup.cell setBordered: NO]; + [mZoomPopup.cell setArrowPosition: NSPopUpArrowAtBottom]; + + // Fill it. + for (unsigned count = 0; count < numberOfDefaultItems; count++) { + [mZoomPopup addItemWithTitle: NSLocalizedStringFromTable(DefaultScaleMenuLabels[count], @"ZoomValues", nil)]; + id currentItem = [mZoomPopup itemAtIndex: count]; + if (DefaultScaleMenuFactors[count] != 0.0) + [currentItem setRepresentedObject: @(DefaultScaleMenuFactors[count])]; + } + [mZoomPopup selectItemAtIndex: DefaultScaleMenuSelectedItemIndex]; + + // Hook it up. + mZoomPopup.target = self; + mZoomPopup.action = @selector(zoomItemAction:); + + // Set a suitable font. + mZoomPopup.font = [NSFont menuBarFontOfSize: BarFontSize]; + + // Make sure the popup is big enough to fit the cells. + [mZoomPopup sizeToFit]; + + // Don't let it become first responder + [mZoomPopup setRefusesFirstResponder: YES]; + + // put it in the scrollview. + [self addSubview: mZoomPopup]; + + // 2) The caret position label. + Class oldCellClass = [NSTextField cellClass]; + [NSTextField setCellClass: [VerticallyCenteredTextFieldCell class]]; + + mCaretPositionLabel = [[NSTextField alloc] initWithFrame: NSMakeRect(0.0, 0.0, 50.0, 1.0)]; + [mCaretPositionLabel setBezeled: NO]; + [mCaretPositionLabel setBordered: NO]; + [mCaretPositionLabel setEditable: NO]; + [mCaretPositionLabel setSelectable: NO]; + [mCaretPositionLabel setDrawsBackground: NO]; + mCaretPositionLabel.font = [NSFont menuBarFontOfSize: BarFontSize]; + + NSTextFieldCell *cell = mCaretPositionLabel.cell; + cell.placeholderString = @"0:0"; + cell.alignment = NSCenterTextAlignment; + + [self addSubview: mCaretPositionLabel]; + + // 3) The status text. + mStatusTextLabel = [[NSTextField alloc] initWithFrame: NSMakeRect(0.0, 0.0, 1.0, 1.0)]; + [mStatusTextLabel setBezeled: NO]; + [mStatusTextLabel setBordered: NO]; + [mStatusTextLabel setEditable: NO]; + [mStatusTextLabel setSelectable: NO]; + [mStatusTextLabel setDrawsBackground: NO]; + mStatusTextLabel.font = [NSFont menuBarFontOfSize: BarFontSize]; + + cell = mStatusTextLabel.cell; + cell.placeholderString = @""; + + [self addSubview: mStatusTextLabel]; + + // Restore original cell class so that everything else doesn't get broken + [NSTextField setCellClass: oldCellClass]; } //-------------------------------------------------------------------------------------------------- @@ -230,52 +218,45 @@ static float BarFontSize = 10.0; /** * Fill the background. */ -- (void) drawRect: (NSRect) rect -{ - // Since the background is seamless, we don't need to take care for the proper offset. - // Simply tile the background over the invalid rectangle. - NSPoint target = {rect.origin.x, 0}; - while (target.x < rect.origin.x + rect.size.width) - { - [mBackground drawAtPoint: target fromRect: NSZeroRect operation: NSCompositeCopy fraction: 1]; - target.x += mBackground.size.width; - } - - // Draw separator lines between items. - NSRect verticalLineRect; - CGFloat component = 190.0 / 255.0; - NSColor* lineColor = [NSColor colorWithDeviceRed: component green: component blue: component alpha: 1]; - - if (mDisplayMask & IBShowZoom) - { - verticalLineRect = mZoomPopup.frame; - verticalLineRect.origin.x += verticalLineRect.size.width + 1.0; - verticalLineRect.size.width = 1.0; - if (NSIntersectsRect(rect, verticalLineRect)) - { - [lineColor set]; - NSRectFill(verticalLineRect); - } - } - - if (mDisplayMask & IBShowCaretPosition) - { - verticalLineRect = mCaretPositionLabel.frame; - verticalLineRect.origin.x += verticalLineRect.size.width + 1.0; - verticalLineRect.size.width = 1.0; - if (NSIntersectsRect(rect, verticalLineRect)) - { - [lineColor set]; - NSRectFill(verticalLineRect); - } - } +- (void) drawRect: (NSRect) rect { + // Since the background is seamless, we don't need to take care for the proper offset. + // Simply tile the background over the invalid rectangle. + NSPoint target = {rect.origin.x, 0}; + while (target.x < rect.origin.x + rect.size.width) { + [mBackground drawAtPoint: target fromRect: NSZeroRect operation: NSCompositeCopy fraction: 1]; + target.x += mBackground.size.width; + } + + // Draw separator lines between items. + NSRect verticalLineRect; + CGFloat component = 190.0 / 255.0; + NSColor *lineColor = [NSColor colorWithDeviceRed: component green: component blue: component alpha: 1]; + + if (mDisplayMask & IBShowZoom) { + verticalLineRect = mZoomPopup.frame; + verticalLineRect.origin.x += verticalLineRect.size.width + 1.0; + verticalLineRect.size.width = 1.0; + if (NSIntersectsRect(rect, verticalLineRect)) { + [lineColor set]; + NSRectFill(verticalLineRect); + } + } + + if (mDisplayMask & IBShowCaretPosition) { + verticalLineRect = mCaretPositionLabel.frame; + verticalLineRect.origin.x += verticalLineRect.size.width + 1.0; + verticalLineRect.size.width = 1.0; + if (NSIntersectsRect(rect, verticalLineRect)) { + [lineColor set]; + NSRectFill(verticalLineRect); + } + } } //-------------------------------------------------------------------------------------------------- -- (BOOL) isOpaque -{ - return YES; +- (BOOL) isOpaque { + return YES; } //-------------------------------------------------------------------------------------------------- @@ -283,46 +264,38 @@ static float BarFontSize = 10.0; /** * Used to reposition our content depending on the size of the view. */ -- (void) setFrame: (NSRect) newFrame -{ - super.frame = newFrame; - [self positionSubViews]; +- (void) setFrame: (NSRect) newFrame { + super.frame = newFrame; + [self positionSubViews]; } //-------------------------------------------------------------------------------------------------- -- (void) positionSubViews -{ - NSRect currentBounds = {{0, 0}, {0, self.frame.size.height}}; - if (mDisplayMask & IBShowZoom) - { - [mZoomPopup setHidden: NO]; - currentBounds.size.width = mZoomPopup.frame.size.width; - mZoomPopup.frame = currentBounds; - currentBounds.origin.x += currentBounds.size.width + 1; // Add 1 for the separator. - } - else - [mZoomPopup setHidden: YES]; - - if (mDisplayMask & IBShowCaretPosition) - { - [mCaretPositionLabel setHidden: NO]; - currentBounds.size.width = mCaretPositionLabel.frame.size.width; - mCaretPositionLabel.frame = currentBounds; - currentBounds.origin.x += currentBounds.size.width + 1; - } - else - [mCaretPositionLabel setHidden: YES]; - - if (mDisplayMask & IBShowStatusText) - { - // The status text always takes the rest of the available space. - [mStatusTextLabel setHidden: NO]; - currentBounds.size.width = self.frame.size.width - currentBounds.origin.x; - mStatusTextLabel.frame = currentBounds; - } - else - [mStatusTextLabel setHidden: YES]; +- (void) positionSubViews { + NSRect currentBounds = {{0, 0}, {0, self.frame.size.height}}; + if (mDisplayMask & IBShowZoom) { + [mZoomPopup setHidden: NO]; + currentBounds.size.width = mZoomPopup.frame.size.width; + mZoomPopup.frame = currentBounds; + currentBounds.origin.x += currentBounds.size.width + 1; // Add 1 for the separator. + } else + [mZoomPopup setHidden: YES]; + + if (mDisplayMask & IBShowCaretPosition) { + [mCaretPositionLabel setHidden: NO]; + currentBounds.size.width = mCaretPositionLabel.frame.size.width; + mCaretPositionLabel.frame = currentBounds; + currentBounds.origin.x += currentBounds.size.width + 1; + } else + [mCaretPositionLabel setHidden: YES]; + + if (mDisplayMask & IBShowStatusText) { + // The status text always takes the rest of the available space. + [mStatusTextLabel setHidden: NO]; + currentBounds.size.width = self.frame.size.width - currentBounds.origin.x; + mStatusTextLabel.frame = currentBounds; + } else + [mStatusTextLabel setHidden: YES]; } //-------------------------------------------------------------------------------------------------- @@ -332,14 +305,12 @@ static float BarFontSize = 10.0; * * @param display Bitwise ORed IBDisplay values which determine what to show on the bar. */ -- (void) setDisplay: (IBDisplay) display -{ - if (mDisplayMask != display) - { - mDisplayMask = display; - [self positionSubViews]; - self.needsDisplay = YES; - } +- (void) setDisplay: (IBDisplay) display { + if (mDisplayMask != display) { + mDisplayMask = display; + [self positionSubViews]; + self.needsDisplay = YES; + } } //-------------------------------------------------------------------------------------------------- @@ -347,53 +318,43 @@ static float BarFontSize = 10.0; /** * Handler for selection changes in the zoom menu. */ -- (void) zoomItemAction: (id) sender -{ - NSNumber* selectedFactorObject = [[sender selectedCell] representedObject]; - - if (selectedFactorObject == nil) - { - NSLog(@"Scale popup action: setting arbitrary zoom factors is not yet supported."); - return; - } - else - { - [self setScaleFactor: selectedFactorObject.floatValue adjustPopup: NO]; - } +- (void) zoomItemAction: (id) sender { + NSNumber *selectedFactorObject = [[sender selectedCell] representedObject]; + + if (selectedFactorObject == nil) { + NSLog(@"Scale popup action: setting arbitrary zoom factors is not yet supported."); + return; + } else { + [self setScaleFactor: selectedFactorObject.floatValue adjustPopup: NO]; + } } //-------------------------------------------------------------------------------------------------- -- (void) setScaleFactor: (float) newScaleFactor adjustPopup: (BOOL) flag -{ - if (mScaleFactor != newScaleFactor) - { - mScaleFactor = newScaleFactor; - if (flag) - { - unsigned count = 0; - unsigned numberOfDefaultItems = sizeof(DefaultScaleMenuFactors) / sizeof(float); - - // We only work with some preset zoom values. If the given value does not correspond - // to one then show no selection. - while (count < numberOfDefaultItems && (fabs(newScaleFactor - DefaultScaleMenuFactors[count]) > 0.07)) - count++; - if (count == numberOfDefaultItems) - [mZoomPopup selectItemAtIndex: -1]; - else - { - [mZoomPopup selectItemAtIndex: count]; - - // Set scale factor to found preset value if it comes close. - mScaleFactor = DefaultScaleMenuFactors[count]; - } - } - else - { - // Internally set. Notify owner. - [mCallback notify: IBNZoomChanged message: nil location: NSZeroPoint value: newScaleFactor]; - } - } +- (void) setScaleFactor: (float) newScaleFactor adjustPopup: (BOOL) flag { + if (mScaleFactor != newScaleFactor) { + mScaleFactor = newScaleFactor; + if (flag) { + unsigned count = 0; + unsigned numberOfDefaultItems = sizeof(DefaultScaleMenuFactors) / sizeof(float); + + // We only work with some preset zoom values. If the given value does not correspond + // to one then show no selection. + while (count < numberOfDefaultItems && (fabs(newScaleFactor - DefaultScaleMenuFactors[count]) > 0.07)) + count++; + if (count == numberOfDefaultItems) + [mZoomPopup selectItemAtIndex: -1]; + else { + [mZoomPopup selectItemAtIndex: count]; + + // Set scale factor to found preset value if it comes close. + mScaleFactor = DefaultScaleMenuFactors[count]; + } + } else { + // Internally set. Notify owner. + [mCallback notify: IBNZoomChanged message: nil location: NSZeroPoint value: newScaleFactor]; + } + } } //-------------------------------------------------------------------------------------------------- @@ -401,19 +362,17 @@ static float BarFontSize = 10.0; /** * Called from the notification method to update the caret position display. */ -- (void) setCaretPosition: (NSPoint) position -{ - // Make the position one-based. - int newX = (int) position.x + 1; - int newY = (int) position.y + 1; - - if (mCurrentCaretX != newX || mCurrentCaretY != newY) - { - mCurrentCaretX = newX; - mCurrentCaretY = newY; - - mCaretPositionLabel.stringValue = [NSString stringWithFormat: @"%d:%d", newX, newY]; - } +- (void) setCaretPosition: (NSPoint) position { + // Make the position one-based. + int newX = (int) position.x + 1; + int newY = (int) position.y + 1; + + if (mCurrentCaretX != newX || mCurrentCaretY != newY) { + mCurrentCaretX = newX; + mCurrentCaretY = newY; + + mCaretPositionLabel.stringValue = [NSString stringWithFormat: @"%d:%d", newX, newY]; + } } //-------------------------------------------------------------------------------------------------- @@ -421,20 +380,19 @@ static float BarFontSize = 10.0; /** * Makes the bar resize to the smallest width that can accommodate the currently enabled items. */ -- (void) sizeToFit -{ - NSRect frame = self.frame; - frame.size.width = 0; - if (mDisplayMask & IBShowZoom) - frame.size.width += mZoomPopup.frame.size.width; +- (void) sizeToFit { + NSRect frame = self.frame; + frame.size.width = 0; + if (mDisplayMask & IBShowZoom) + frame.size.width += mZoomPopup.frame.size.width; - if (mDisplayMask & IBShowCaretPosition) - frame.size.width += mCaretPositionLabel.frame.size.width; + if (mDisplayMask & IBShowCaretPosition) + frame.size.width += mCaretPositionLabel.frame.size.width; - if (mDisplayMask & IBShowStatusText) - frame.size.width += mStatusTextLabel.frame.size.width; + if (mDisplayMask & IBShowStatusText) + frame.size.width += mStatusTextLabel.frame.size.width; - self.frame = frame; + self.frame = frame; } @end diff --git a/cocoa/InfoBarCommunicator.h b/cocoa/InfoBarCommunicator.h index 382f3bb8e..5a91dcb59 100644 --- a/cocoa/InfoBarCommunicator.h +++ b/cocoa/InfoBarCommunicator.h @@ -9,10 +9,10 @@ */ typedef NS_OPTIONS(NSUInteger, IBDisplay) { - IBShowZoom = 0x01, - IBShowCaretPosition = 0x02, - IBShowStatusText = 0x04, - IBShowAll = 0xFF + IBShowZoom = 0x01, + IBShowCaretPosition = 0x02, + IBShowStatusText = 0x04, + IBShowAll = 0xFF }; /** @@ -22,14 +22,14 @@ typedef NS_OPTIONS(NSUInteger, IBDisplay) { */ typedef NS_ENUM(NSInteger, NotificationType) { - IBNZoomChanged, // The user selected another zoom value. - IBNCaretChanged, // The caret in the editor changed. - IBNStatusChanged, // The application set a new status message. + IBNZoomChanged, // The user selected another zoom value. + IBNCaretChanged, // The caret in the editor changed. + IBNStatusChanged, // The application set a new status message. }; @protocol InfoBarCommunicator -- (void) notify: (NotificationType) type message: (NSString*) message location: (NSPoint) location - value: (float) value; +- (void) notify: (NotificationType) type message: (NSString *) message location: (NSPoint) location + value: (float) value; - (void) setCallback: (id <InfoBarCommunicator>) callback; @end diff --git a/cocoa/PlatCocoa.h b/cocoa/PlatCocoa.h index f8f1bd698..1394a7b16 100644 --- a/cocoa/PlatCocoa.h +++ b/cocoa/PlatCocoa.h @@ -21,101 +21,99 @@ #include "QuartzTextLayout.h" -NSRect PRectangleToNSRect(const Scintilla::PRectangle& rc); -Scintilla::PRectangle NSRectToPRectangle(NSRect& rc); +NSRect PRectangleToNSRect(const Scintilla::PRectangle &rc); +Scintilla::PRectangle NSRectToPRectangle(NSRect &rc); CFStringEncoding EncodingFromCharacterSet(bool unicode, int characterSet); -@interface ScintillaContextMenu : NSMenu -{ - Scintilla::ScintillaCocoa* owner; +@interface ScintillaContextMenu : NSMenu { + Scintilla::ScintillaCocoa *owner; } -- (void) handleCommand: (NSMenuItem*) sender; -- (void) setOwner: (Scintilla::ScintillaCocoa*) newOwner; +- (void) handleCommand: (NSMenuItem *) sender; +- (void) setOwner: (Scintilla::ScintillaCocoa *) newOwner; @end namespace Scintilla { // A class to do the actual text rendering for us using Quartz 2D. -class SurfaceImpl : public Surface -{ +class SurfaceImpl : public Surface { private: - bool unicodeMode; - float x; - float y; + bool unicodeMode; + float x; + float y; - CGContextRef gc; + CGContextRef gc; - /** The text layout instance */ - std::unique_ptr<QuartzTextLayout> textLayout; - int codePage; - int verticalDeviceResolution; + /** The text layout instance */ + std::unique_ptr<QuartzTextLayout> textLayout; + int codePage; + int verticalDeviceResolution; - /** If the surface is a bitmap context, contains a reference to the bitmap data. */ - std::unique_ptr<uint8_t[]> bitmapData; - /** If the surface is a bitmap context, stores the dimensions of the bitmap. */ - int bitmapWidth; - int bitmapHeight; + /** If the surface is a bitmap context, contains a reference to the bitmap data. */ + std::unique_ptr<uint8_t[]> bitmapData; + /** If the surface is a bitmap context, stores the dimensions of the bitmap. */ + int bitmapWidth; + int bitmapHeight; - /** Set the CGContext's fill colour to the specified desired colour. */ - void FillColour( const ColourDesired& back ); + /** Set the CGContext's fill colour to the specified desired colour. */ + void FillColour(const ColourDesired &back); - // 24-bit RGB+A bitmap data constants - static const int BITS_PER_COMPONENT = 8; - static const int BITS_PER_PIXEL = BITS_PER_COMPONENT * 4; - static const int BYTES_PER_PIXEL = BITS_PER_PIXEL / 8; + // 24-bit RGB+A bitmap data constants + static const int BITS_PER_COMPONENT = 8; + static const int BITS_PER_PIXEL = BITS_PER_COMPONENT * 4; + static const int BYTES_PER_PIXEL = BITS_PER_PIXEL / 8; public: - SurfaceImpl(); - ~SurfaceImpl() override; - - void Init(WindowID wid) override; - void Init(SurfaceID sid, WindowID wid) override; - void InitPixMap(int width, int height, Surface *surface_, WindowID wid) override; - CGContextRef GetContext() { return gc; } - - void Release() override; - bool Initialised() override; - void PenColour(ColourDesired fore) override; - - /** Returns a CGImageRef that represents the surface. Returns NULL if this is not possible. */ - CGImageRef GetImage(); - void CopyImageRectangle(Surface &surfaceSource, PRectangle srcRect, PRectangle dstRect); - - int LogPixelsY() override; - int DeviceHeightFont(int points) override; - void MoveTo(int x_, int y_) override; - void LineTo(int x_, int y_) override; - void Polygon(Scintilla::Point *pts, int npts, ColourDesired fore, ColourDesired back) override; - void RectangleDraw(PRectangle rc, ColourDesired fore, ColourDesired back) override; - void FillRectangle(PRectangle rc, ColourDesired back) override; - void FillRectangle(PRectangle rc, Surface &surfacePattern) override; - void RoundedRectangle(PRectangle rc, ColourDesired fore, ColourDesired back) override; - void AlphaRectangle(PRectangle rc, int cornerSize, ColourDesired fill, int alphaFill, - ColourDesired outline, int alphaOutline, int flags) override; - void DrawRGBAImage(PRectangle rc, int width, int height, const unsigned char *pixelsImage) override; - void Ellipse(PRectangle rc, ColourDesired fore, ColourDesired back) override; - void Copy(PRectangle rc, Scintilla::Point from, Surface &surfaceSource) override; - void DrawTextNoClip(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, ColourDesired fore, - ColourDesired back) override; - void DrawTextClipped(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, ColourDesired fore, - ColourDesired back) override; - void DrawTextTransparent(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, ColourDesired fore) override; - void MeasureWidths(Font &font_, const char *s, int len, XYPOSITION *positions) override; - XYPOSITION WidthText(Font &font_, const char *s, int len) override; - XYPOSITION WidthChar(Font &font_, char ch) override; - XYPOSITION Ascent(Font &font_) override; - XYPOSITION Descent(Font &font_) override; - XYPOSITION InternalLeading(Font &font_) override; - XYPOSITION ExternalLeading(Font &font_) override; - XYPOSITION Height(Font &font_) override; - XYPOSITION AverageCharWidth(Font &font_) override; - - void SetClip(PRectangle rc) override; - void FlushCachedState() override; - - void SetUnicodeMode(bool unicodeMode_) override; - void SetDBCSMode(int codePage_) override; + SurfaceImpl(); + ~SurfaceImpl() override; + + void Init(WindowID wid) override; + void Init(SurfaceID sid, WindowID wid) override; + void InitPixMap(int width, int height, Surface *surface_, WindowID wid) override; + CGContextRef GetContext() { return gc; } + + void Release() override; + bool Initialised() override; + void PenColour(ColourDesired fore) override; + + /** Returns a CGImageRef that represents the surface. Returns NULL if this is not possible. */ + CGImageRef GetImage(); + void CopyImageRectangle(Surface &surfaceSource, PRectangle srcRect, PRectangle dstRect); + + int LogPixelsY() override; + int DeviceHeightFont(int points) override; + void MoveTo(int x_, int y_) override; + void LineTo(int x_, int y_) override; + void Polygon(Scintilla::Point *pts, int npts, ColourDesired fore, ColourDesired back) override; + void RectangleDraw(PRectangle rc, ColourDesired fore, ColourDesired back) override; + void FillRectangle(PRectangle rc, ColourDesired back) override; + void FillRectangle(PRectangle rc, Surface &surfacePattern) override; + void RoundedRectangle(PRectangle rc, ColourDesired fore, ColourDesired back) override; + void AlphaRectangle(PRectangle rc, int cornerSize, ColourDesired fill, int alphaFill, + ColourDesired outline, int alphaOutline, int flags) override; + void DrawRGBAImage(PRectangle rc, int width, int height, const unsigned char *pixelsImage) override; + void Ellipse(PRectangle rc, ColourDesired fore, ColourDesired back) override; + void Copy(PRectangle rc, Scintilla::Point from, Surface &surfaceSource) override; + void DrawTextNoClip(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, ColourDesired fore, + ColourDesired back) override; + void DrawTextClipped(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, ColourDesired fore, + ColourDesired back) override; + void DrawTextTransparent(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, ColourDesired fore) override; + void MeasureWidths(Font &font_, const char *s, int len, XYPOSITION *positions) override; + XYPOSITION WidthText(Font &font_, const char *s, int len) override; + XYPOSITION WidthChar(Font &font_, char ch) override; + XYPOSITION Ascent(Font &font_) override; + XYPOSITION Descent(Font &font_) override; + XYPOSITION InternalLeading(Font &font_) override; + XYPOSITION ExternalLeading(Font &font_) override; + XYPOSITION Height(Font &font_) override; + XYPOSITION AverageCharWidth(Font &font_) override; + + void SetClip(PRectangle rc) override; + void FlushCachedState() override; + + void SetUnicodeMode(bool unicodeMode_) override; + void SetDBCSMode(int codePage_) override; }; // SurfaceImpl class } // Scintilla namespace diff --git a/cocoa/PlatCocoa.mm b/cocoa/PlatCocoa.mm index 2908bb206..6633f98ff 100644 --- a/cocoa/PlatCocoa.mm +++ b/cocoa/PlatCocoa.mm @@ -38,16 +38,15 @@ using namespace Scintilla; -extern sptr_t scintilla_send_message(void* sci, unsigned int iMessage, uptr_t wParam, sptr_t lParam); +extern sptr_t scintilla_send_message(void *sci, unsigned int iMessage, uptr_t wParam, sptr_t lParam); //-------------------------------------------------------------------------------------------------- /** * Converts a PRectangle as used by Scintilla to standard Obj-C NSRect structure . */ -NSRect PRectangleToNSRect(const PRectangle& rc) -{ - return NSMakeRect(rc.left, rc.top, rc.Width(), rc.Height()); +NSRect PRectangleToNSRect(const PRectangle &rc) { + return NSMakeRect(rc.left, rc.top, rc.Width(), rc.Height()); } //-------------------------------------------------------------------------------------------------- @@ -55,11 +54,10 @@ NSRect PRectangleToNSRect(const PRectangle& rc) /** * Converts an NSRect as used by the system to a native Scintilla rectangle. */ -PRectangle NSRectToPRectangle(NSRect& rc) -{ - return PRectangle(static_cast<XYPOSITION>(rc.origin.x), static_cast<XYPOSITION>(rc.origin.y), - static_cast<XYPOSITION>(NSMaxX(rc)), - static_cast<XYPOSITION>(NSMaxY(rc))); +PRectangle NSRectToPRectangle(NSRect &rc) { + return PRectangle(static_cast<XYPOSITION>(rc.origin.x), static_cast<XYPOSITION>(rc.origin.y), + static_cast<XYPOSITION>(NSMaxX(rc)), + static_cast<XYPOSITION>(NSMaxY(rc))); } //-------------------------------------------------------------------------------------------------- @@ -67,9 +65,8 @@ PRectangle NSRectToPRectangle(NSRect& rc) /** * Converts a PRectangle as used by Scintilla to a Quartz-style rectangle. */ -inline CGRect PRectangleToCGRect(PRectangle& rc) -{ - return CGRectMake(rc.left, rc.top, rc.Width(), rc.Height()); +inline CGRect PRectangleToCGRect(PRectangle &rc) { + return CGRectMake(rc.left, rc.top, rc.Width(), rc.Height()); } //-------------------------------------------------------------------------------------------------- @@ -77,14 +74,13 @@ inline CGRect PRectangleToCGRect(PRectangle& rc) /** * Converts a Quartz-style rectangle to a PRectangle structure as used by Scintilla. */ -inline PRectangle CGRectToPRectangle(const CGRect& rect) -{ - PRectangle rc; - rc.left = (int)(rect.origin.x + 0.5); - rc.top = (int)(rect.origin.y + 0.5); - rc.right = (int)(rect.origin.x + rect.size.width + 0.5); - rc.bottom = (int)(rect.origin.y + rect.size.height + 0.5); - return rc; +inline PRectangle CGRectToPRectangle(const CGRect &rect) { + PRectangle rc; + rc.left = (int)(rect.origin.x + 0.5); + rc.top = (int)(rect.origin.y + 0.5); + rc.right = (int)(rect.origin.x + rect.size.width + 0.5); + rc.bottom = (int)(rect.origin.y + rect.size.height + 0.5); + return rc; } //----------------- Point -------------------------------------------------------------------------- @@ -92,25 +88,22 @@ inline PRectangle CGRectToPRectangle(const CGRect& rect) /** * Converts a point given as a long into a native Point structure. */ -Scintilla::Point Scintilla::Point::FromLong(long lpoint) -{ - return Scintilla::Point( - Platform::LowShortFromLong(lpoint), - Platform::HighShortFromLong(lpoint) - ); +Scintilla::Point Scintilla::Point::FromLong(long lpoint) { + return Scintilla::Point( + Platform::LowShortFromLong(lpoint), + Platform::HighShortFromLong(lpoint) + ); } //----------------- Font --------------------------------------------------------------------------- -Font::Font(): fid(0) -{ +Font::Font(): fid(0) { } //-------------------------------------------------------------------------------------------------- -Font::~Font() -{ - Release(); +Font::~Font() { + Release(); } //-------------------------------------------------------------------------------------------------- @@ -122,11 +115,10 @@ static int FontCharacterSet(Font &f) { /** * Creates a CTFontRef with the given properties. */ -void Font::Create(const FontParameters &fp) -{ +void Font::Create(const FontParameters &fp) { Release(); - QuartzTextStyle* style = new QuartzTextStyle(); + QuartzTextStyle *style = new QuartzTextStyle(); fid = style; // Create the font with attributes @@ -137,234 +129,214 @@ void Font::Create(const FontParameters &fp) //-------------------------------------------------------------------------------------------------- -void Font::Release() -{ - if (fid) - delete static_cast<QuartzTextStyle*>( fid ); - fid = 0; +void Font::Release() { + if (fid) + delete static_cast<QuartzTextStyle *>(fid); + fid = 0; } //----------------- SurfaceImpl -------------------------------------------------------------------- -SurfaceImpl::SurfaceImpl() -{ - unicodeMode = true; - x = 0; - y = 0; - gc = NULL; +SurfaceImpl::SurfaceImpl() { + unicodeMode = true; + x = 0; + y = 0; + gc = NULL; - textLayout.reset(new QuartzTextLayout(nullptr)); - codePage = 0; - verticalDeviceResolution = 0; + textLayout.reset(new QuartzTextLayout(nullptr)); + codePage = 0; + verticalDeviceResolution = 0; - bitmapData.reset(); // Release will try and delete bitmapData if != nullptr - bitmapWidth = 0; - bitmapHeight = 0; + bitmapData.reset(); // Release will try and delete bitmapData if != nullptr + bitmapWidth = 0; + bitmapHeight = 0; - Release(); + Release(); } //-------------------------------------------------------------------------------------------------- -SurfaceImpl::~SurfaceImpl() -{ - Release(); +SurfaceImpl::~SurfaceImpl() { + Release(); } //-------------------------------------------------------------------------------------------------- -void SurfaceImpl::Release() -{ - textLayout->setContext(nullptr); - if (bitmapData) - { - bitmapData.reset(); - // We only "own" the graphics context if we are a bitmap context - if (gc) - CGContextRelease(gc); - } - gc = NULL; +void SurfaceImpl::Release() { + textLayout->setContext(nullptr); + if (bitmapData) { + bitmapData.reset(); + // We only "own" the graphics context if we are a bitmap context + if (gc) + CGContextRelease(gc); + } + gc = NULL; - bitmapWidth = 0; - bitmapHeight = 0; - x = 0; - y = 0; + bitmapWidth = 0; + bitmapHeight = 0; + x = 0; + y = 0; } //-------------------------------------------------------------------------------------------------- -bool SurfaceImpl::Initialised() -{ - // We are initalised if the graphics context is not null - return gc != NULL;// || port != NULL; +bool SurfaceImpl::Initialised() { + // We are initalised if the graphics context is not null + return gc != NULL;// || port != NULL; } //-------------------------------------------------------------------------------------------------- -void SurfaceImpl::Init(WindowID) -{ - // To be able to draw, the surface must get a CGContext handle. We save the graphics port, - // then acquire/release the context on an as-need basis (see above). - // XXX Docs on QDBeginCGContext are light, a better way to do this would be good. - // AFAIK we should not hold onto a context retrieved this way, thus the need for - // acquire/release of the context. +void SurfaceImpl::Init(WindowID) { + // To be able to draw, the surface must get a CGContext handle. We save the graphics port, + // then acquire/release the context on an as-need basis (see above). + // XXX Docs on QDBeginCGContext are light, a better way to do this would be good. + // AFAIK we should not hold onto a context retrieved this way, thus the need for + // acquire/release of the context. - Release(); + Release(); } //-------------------------------------------------------------------------------------------------- -void SurfaceImpl::Init(SurfaceID sid, WindowID) -{ - Release(); - gc = static_cast<CGContextRef>(sid); - CGContextSetLineWidth(gc, 1.0); - textLayout->setContext(gc); +void SurfaceImpl::Init(SurfaceID sid, WindowID) { + Release(); + gc = static_cast<CGContextRef>(sid); + CGContextSetLineWidth(gc, 1.0); + textLayout->setContext(gc); } //-------------------------------------------------------------------------------------------------- -void SurfaceImpl::InitPixMap(int width, int height, Surface* surface_, WindowID /* wid */) -{ - Release(); - - // Create a new bitmap context, along with the RAM for the bitmap itself - bitmapWidth = width; - bitmapHeight = height; - - const int bitmapBytesPerRow = (width * BYTES_PER_PIXEL); - const int bitmapByteCount = (bitmapBytesPerRow * height); - - // Create an RGB color space. - CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); - if (colorSpace == NULL) - return; - - // Create the bitmap. - bitmapData.reset(new uint8_t[bitmapByteCount]); - // create the context - gc = CGBitmapContextCreate(bitmapData.get(), - width, - height, - BITS_PER_COMPONENT, - bitmapBytesPerRow, - colorSpace, - kCGImageAlphaPremultipliedLast); - - if (gc == NULL) - { - // the context couldn't be created for some reason, - // and we have no use for the bitmap without the context - bitmapData.reset(); - } - textLayout->setContext (gc); - - // the context retains the color space, so we can release it - CGColorSpaceRelease(colorSpace); - - if (gc && bitmapData) - { - // "Erase" to white. - CGContextClearRect( gc, CGRectMake( 0, 0, width, height ) ); - CGContextSetRGBFillColor( gc, 1.0, 1.0, 1.0, 1.0 ); - CGContextFillRect( gc, CGRectMake( 0, 0, width, height ) ); - } - - if (surface_) - { - SurfaceImpl *psurfOther = static_cast<SurfaceImpl *>(surface_); - unicodeMode = psurfOther->unicodeMode; - codePage = psurfOther->codePage; - } - else - { - unicodeMode = true; - codePage = SC_CP_UTF8; - } -} - -//-------------------------------------------------------------------------------------------------- - -void SurfaceImpl::PenColour(ColourDesired fore) -{ - if (gc) - { - ColourDesired colour(fore.AsLong()); +void SurfaceImpl::InitPixMap(int width, int height, Surface *surface_, WindowID /* wid */) { + Release(); + + // Create a new bitmap context, along with the RAM for the bitmap itself + bitmapWidth = width; + bitmapHeight = height; + + const int bitmapBytesPerRow = (width * BYTES_PER_PIXEL); + const int bitmapByteCount = (bitmapBytesPerRow * height); + + // Create an RGB color space. + CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); + if (colorSpace == NULL) + return; + + // Create the bitmap. + bitmapData.reset(new uint8_t[bitmapByteCount]); + // create the context + gc = CGBitmapContextCreate(bitmapData.get(), + width, + height, + BITS_PER_COMPONENT, + bitmapBytesPerRow, + colorSpace, + kCGImageAlphaPremultipliedLast); + + if (gc == NULL) { + // the context couldn't be created for some reason, + // and we have no use for the bitmap without the context + bitmapData.reset(); + } + textLayout->setContext(gc); + + // the context retains the color space, so we can release it + CGColorSpaceRelease(colorSpace); + + if (gc && bitmapData) { + // "Erase" to white. + CGContextClearRect(gc, CGRectMake(0, 0, width, height)); + CGContextSetRGBFillColor(gc, 1.0, 1.0, 1.0, 1.0); + CGContextFillRect(gc, CGRectMake(0, 0, width, height)); + } - // Set the Stroke color to match - CGContextSetRGBStrokeColor(gc, colour.GetRed() / 255.0, colour.GetGreen() / 255.0, - colour.GetBlue() / 255.0, 1.0 ); - } + if (surface_) { + SurfaceImpl *psurfOther = static_cast<SurfaceImpl *>(surface_); + unicodeMode = psurfOther->unicodeMode; + codePage = psurfOther->codePage; + } else { + unicodeMode = true; + codePage = SC_CP_UTF8; + } } //-------------------------------------------------------------------------------------------------- -void SurfaceImpl::FillColour(const ColourDesired& back) -{ - if (gc) - { - ColourDesired colour(back.AsLong()); +void SurfaceImpl::PenColour(ColourDesired fore) { + if (gc) { + ColourDesired colour(fore.AsLong()); - // Set the Fill color to match - CGContextSetRGBFillColor(gc, colour.GetRed() / 255.0, colour.GetGreen() / 255.0, - colour.GetBlue() / 255.0, 1.0 ); - } + // Set the Stroke color to match + CGContextSetRGBStrokeColor(gc, colour.GetRed() / 255.0, colour.GetGreen() / 255.0, + colour.GetBlue() / 255.0, 1.0); + } } //-------------------------------------------------------------------------------------------------- -CGImageRef SurfaceImpl::GetImage() -{ - // For now, assume that GetImage can only be called on PixMap surfaces. - if (!bitmapData) - return nullptr; - - CGContextFlush(gc); +void SurfaceImpl::FillColour(const ColourDesired &back) { + if (gc) { + ColourDesired colour(back.AsLong()); - // Create an RGB color space. - CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); - if( colorSpace == NULL ) - return NULL; + // Set the Fill color to match + CGContextSetRGBFillColor(gc, colour.GetRed() / 255.0, colour.GetGreen() / 255.0, + colour.GetBlue() / 255.0, 1.0); + } +} - const int bitmapBytesPerRow = ((int) bitmapWidth * BYTES_PER_PIXEL); - const int bitmapByteCount = (bitmapBytesPerRow * (int) bitmapHeight); +//-------------------------------------------------------------------------------------------------- - // Make a copy of the bitmap data for the image creation and divorce it - // From the SurfaceImpl lifetime - CFDataRef dataRef = CFDataCreate(kCFAllocatorDefault, bitmapData.get(), bitmapByteCount); +CGImageRef SurfaceImpl::GetImage() { + // For now, assume that GetImage can only be called on PixMap surfaces. + if (!bitmapData) + return nullptr; - // Create a data provider. - CGDataProviderRef dataProvider = CGDataProviderCreateWithCFData(dataRef); + CGContextFlush(gc); - CGImageRef image = NULL; - if (dataProvider != NULL) - { - // Create the CGImage. - image = CGImageCreate(bitmapWidth, - bitmapHeight, - BITS_PER_COMPONENT, - BITS_PER_PIXEL, - bitmapBytesPerRow, - colorSpace, - kCGImageAlphaPremultipliedLast, - dataProvider, - NULL, - 0, - kCGRenderingIntentDefault); - } + // Create an RGB color space. + CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); + if (colorSpace == NULL) + return NULL; + + const int bitmapBytesPerRow = ((int) bitmapWidth * BYTES_PER_PIXEL); + const int bitmapByteCount = (bitmapBytesPerRow * (int) bitmapHeight); + + // Make a copy of the bitmap data for the image creation and divorce it + // From the SurfaceImpl lifetime + CFDataRef dataRef = CFDataCreate(kCFAllocatorDefault, bitmapData.get(), bitmapByteCount); + + // Create a data provider. + CGDataProviderRef dataProvider = CGDataProviderCreateWithCFData(dataRef); + + CGImageRef image = NULL; + if (dataProvider != NULL) { + // Create the CGImage. + image = CGImageCreate(bitmapWidth, + bitmapHeight, + BITS_PER_COMPONENT, + BITS_PER_PIXEL, + bitmapBytesPerRow, + colorSpace, + kCGImageAlphaPremultipliedLast, + dataProvider, + NULL, + 0, + kCGRenderingIntentDefault); + } - // The image retains the color space, so we can release it. - CGColorSpaceRelease(colorSpace); - colorSpace = NULL; + // The image retains the color space, so we can release it. + CGColorSpaceRelease(colorSpace); + colorSpace = NULL; - // Done with the data provider. - CGDataProviderRelease(dataProvider); - dataProvider = NULL; + // Done with the data provider. + CGDataProviderRelease(dataProvider); + dataProvider = NULL; - // Done with the data provider. - CFRelease(dataRef); + // Done with the data provider. + CFRelease(dataRef); - return image; + return image; } //-------------------------------------------------------------------------------------------------- @@ -374,9 +346,8 @@ CGImageRef SurfaceImpl::GetImage() * This is no longer called. * For Cocoa, all screens are treated as 72 DPI, even retina displays. */ -int SurfaceImpl::LogPixelsY() -{ - return 72; +int SurfaceImpl::LogPixelsY() { + return 72; } //-------------------------------------------------------------------------------------------------- @@ -385,325 +356,302 @@ int SurfaceImpl::LogPixelsY() * Converts the logical font height in points into a device height. * For Cocoa, points are always used for the result even on retina displays. */ -int SurfaceImpl::DeviceHeightFont(int points) -{ - return points; +int SurfaceImpl::DeviceHeightFont(int points) { + return points; } //-------------------------------------------------------------------------------------------------- -void SurfaceImpl::MoveTo(int x_, int y_) -{ - x = x_; - y = y_; +void SurfaceImpl::MoveTo(int x_, int y_) { + x = x_; + y = y_; } //-------------------------------------------------------------------------------------------------- -void SurfaceImpl::LineTo(int x_, int y_) -{ - CGContextBeginPath( gc ); +void SurfaceImpl::LineTo(int x_, int y_) { + CGContextBeginPath(gc); - // Because Quartz is based on floating point, lines are drawn with half their colour - // on each side of the line. Integer coordinates specify the INTERSECTION of the pixel - // division lines. If you specify exact pixel values, you get a line that - // is twice as thick but half as intense. To get pixel aligned rendering, - // we render the "middle" of the pixels by adding 0.5 to the coordinates. - CGContextMoveToPoint( gc, x + 0.5, y + 0.5 ); - CGContextAddLineToPoint( gc, x_ + 0.5, y_ + 0.5 ); - CGContextStrokePath( gc ); - x = x_; - y = y_; + // Because Quartz is based on floating point, lines are drawn with half their colour + // on each side of the line. Integer coordinates specify the INTERSECTION of the pixel + // division lines. If you specify exact pixel values, you get a line that + // is twice as thick but half as intense. To get pixel aligned rendering, + // we render the "middle" of the pixels by adding 0.5 to the coordinates. + CGContextMoveToPoint(gc, x + 0.5, y + 0.5); + CGContextAddLineToPoint(gc, x_ + 0.5, y_ + 0.5); + CGContextStrokePath(gc); + x = x_; + y = y_; } //-------------------------------------------------------------------------------------------------- void SurfaceImpl::Polygon(Scintilla::Point *pts, int npts, ColourDesired fore, - ColourDesired back) -{ - // Allocate memory for the array of points. - std::vector<CGPoint> points(npts); - - for (int i = 0;i < npts;i++) - { - // Quartz floating point issues: plot the MIDDLE of the pixels - points[i].x = pts[i].x + 0.5; - points[i].y = pts[i].y + 0.5; - } + ColourDesired back) { + // Allocate memory for the array of points. + std::vector<CGPoint> points(npts); + + for (int i = 0; i < npts; i++) { + // Quartz floating point issues: plot the MIDDLE of the pixels + points[i].x = pts[i].x + 0.5; + points[i].y = pts[i].y + 0.5; + } - CGContextBeginPath(gc); + CGContextBeginPath(gc); - // Set colours - FillColour(back); - PenColour(fore); + // Set colours + FillColour(back); + PenColour(fore); - // Draw the polygon - CGContextAddLines(gc, points.data(), npts); + // Draw the polygon + CGContextAddLines(gc, points.data(), npts); - // Explicitly close the path, so it is closed for stroking AND filling (implicit close = filling only) - CGContextClosePath( gc ); - CGContextDrawPath( gc, kCGPathFillStroke ); + // Explicitly close the path, so it is closed for stroking AND filling (implicit close = filling only) + CGContextClosePath(gc); + CGContextDrawPath(gc, kCGPathFillStroke); } //-------------------------------------------------------------------------------------------------- -void SurfaceImpl::RectangleDraw(PRectangle rc, ColourDesired fore, ColourDesired back) -{ - if (gc) - { - CGContextBeginPath( gc ); - FillColour(back); - PenColour(fore); +void SurfaceImpl::RectangleDraw(PRectangle rc, ColourDesired fore, ColourDesired back) { + if (gc) { + CGContextBeginPath(gc); + FillColour(back); + PenColour(fore); - // Quartz integer -> float point conversion fun (see comment in SurfaceImpl::LineTo) - // We subtract 1 from the Width() and Height() so that all our drawing is within the area defined - // by the PRectangle. Otherwise, we draw one pixel too far to the right and bottom. - CGContextAddRect( gc, CGRectMake( rc.left + 0.5, rc.top + 0.5, rc.Width() - 1, rc.Height() - 1 ) ); - CGContextDrawPath( gc, kCGPathFillStroke ); - } + // Quartz integer -> float point conversion fun (see comment in SurfaceImpl::LineTo) + // We subtract 1 from the Width() and Height() so that all our drawing is within the area defined + // by the PRectangle. Otherwise, we draw one pixel too far to the right and bottom. + CGContextAddRect(gc, CGRectMake(rc.left + 0.5, rc.top + 0.5, rc.Width() - 1, rc.Height() - 1)); + CGContextDrawPath(gc, kCGPathFillStroke); + } } //-------------------------------------------------------------------------------------------------- -void SurfaceImpl::FillRectangle(PRectangle rc, ColourDesired back) -{ - if (gc) - { - FillColour(back); - // Snap rectangle boundaries to nearest int - rc.left = lround(rc.left); - rc.right = lround(rc.right); - CGRect rect = PRectangleToCGRect(rc); - CGContextFillRect(gc, rect); - } +void SurfaceImpl::FillRectangle(PRectangle rc, ColourDesired back) { + if (gc) { + FillColour(back); + // Snap rectangle boundaries to nearest int + rc.left = lround(rc.left); + rc.right = lround(rc.right); + CGRect rect = PRectangleToCGRect(rc); + CGContextFillRect(gc, rect); + } } //-------------------------------------------------------------------------------------------------- -static void drawImageRefCallback(void *info, CGContextRef gc) -{ - CGImageRef pattern = static_cast<CGImageRef>(info); - CGContextDrawImage(gc, CGRectMake(0, 0, CGImageGetWidth(pattern), CGImageGetHeight(pattern)), pattern); +static void drawImageRefCallback(void *info, CGContextRef gc) { + CGImageRef pattern = static_cast<CGImageRef>(info); + CGContextDrawImage(gc, CGRectMake(0, 0, CGImageGetWidth(pattern), CGImageGetHeight(pattern)), pattern); } //-------------------------------------------------------------------------------------------------- -static void releaseImageRefCallback(void *info) -{ - CGImageRelease(static_cast<CGImageRef>(info)); +static void releaseImageRefCallback(void *info) { + CGImageRelease(static_cast<CGImageRef>(info)); } //-------------------------------------------------------------------------------------------------- -void SurfaceImpl::FillRectangle(PRectangle rc, Surface &surfacePattern) -{ - SurfaceImpl& patternSurface = static_cast<SurfaceImpl &>(surfacePattern); - - // For now, assume that copy can only be called on PixMap surfaces. Shows up black. - CGImageRef image = patternSurface.GetImage(); - if (image == NULL) - { - FillRectangle(rc, ColourDesired(0)); - return; - } - - const CGPatternCallbacks drawImageCallbacks = { 0, drawImageRefCallback, releaseImageRefCallback }; - - CGPatternRef pattern = CGPatternCreate(image, - CGRectMake(0, 0, patternSurface.bitmapWidth, patternSurface.bitmapHeight), - CGAffineTransformIdentity, - patternSurface.bitmapWidth, - patternSurface.bitmapHeight, - kCGPatternTilingNoDistortion, - true, - &drawImageCallbacks - ); - if (pattern != NULL) - { - // Create a pattern color space - CGColorSpaceRef colorSpace = CGColorSpaceCreatePattern( NULL ); - if( colorSpace != NULL ) { - - CGContextSaveGState( gc ); - CGContextSetFillColorSpace( gc, colorSpace ); - - // Unlike the documentation, you MUST pass in a "components" parameter: - // For coloured patterns it is the alpha value. - const CGFloat alpha = 1.0; - CGContextSetFillPattern( gc, pattern, &alpha ); - CGContextFillRect( gc, PRectangleToCGRect( rc ) ); - CGContextRestoreGState( gc ); - // Free the color space, the pattern and image - CGColorSpaceRelease( colorSpace ); - } /* colorSpace != NULL */ - colorSpace = NULL; - CGPatternRelease( pattern ); - pattern = NULL; - } /* pattern != NULL */ +void SurfaceImpl::FillRectangle(PRectangle rc, Surface &surfacePattern) { + SurfaceImpl &patternSurface = static_cast<SurfaceImpl &>(surfacePattern); + + // For now, assume that copy can only be called on PixMap surfaces. Shows up black. + CGImageRef image = patternSurface.GetImage(); + if (image == NULL) { + FillRectangle(rc, ColourDesired(0)); + return; + } + + const CGPatternCallbacks drawImageCallbacks = { 0, drawImageRefCallback, releaseImageRefCallback }; + + CGPatternRef pattern = CGPatternCreate(image, + CGRectMake(0, 0, patternSurface.bitmapWidth, patternSurface.bitmapHeight), + CGAffineTransformIdentity, + patternSurface.bitmapWidth, + patternSurface.bitmapHeight, + kCGPatternTilingNoDistortion, + true, + &drawImageCallbacks + ); + if (pattern != NULL) { + // Create a pattern color space + CGColorSpaceRef colorSpace = CGColorSpaceCreatePattern(NULL); + if (colorSpace != NULL) { + + CGContextSaveGState(gc); + CGContextSetFillColorSpace(gc, colorSpace); + + // Unlike the documentation, you MUST pass in a "components" parameter: + // For coloured patterns it is the alpha value. + const CGFloat alpha = 1.0; + CGContextSetFillPattern(gc, pattern, &alpha); + CGContextFillRect(gc, PRectangleToCGRect(rc)); + CGContextRestoreGState(gc); + // Free the color space, the pattern and image + CGColorSpaceRelease(colorSpace); + } /* colorSpace != NULL */ + colorSpace = NULL; + CGPatternRelease(pattern); + pattern = NULL; + } /* pattern != NULL */ } void SurfaceImpl::RoundedRectangle(PRectangle rc, ColourDesired fore, ColourDesired back) { - // This is only called from the margin marker drawing code for SC_MARK_ROUNDRECT - // The Win32 version does - // ::RoundRect(hdc, rc.left + 1, rc.top, rc.right - 1, rc.bottom, 8, 8 ); - // which is a rectangle with rounded corners each having a radius of 4 pixels. - // It would be almost as good just cutting off the corners with lines at - // 45 degrees as is done on GTK+. - - // Create a rectangle with semicircles at the corners - const int MAX_RADIUS = 4; - const int radius = std::min(MAX_RADIUS, static_cast<int>(std::min(rc.Height()/2, rc.Width()/2))); - - // Points go clockwise, starting from just below the top left - // Corners are kept together, so we can easily create arcs to connect them - CGPoint corners[4][3] = - { - { - { rc.left, rc.top + radius }, - { rc.left, rc.top }, - { rc.left + radius, rc.top }, - }, - { - { rc.right - radius - 1, rc.top }, - { rc.right - 1, rc.top }, - { rc.right - 1, rc.top + radius }, - }, - { - { rc.right - 1, rc.bottom - radius - 1 }, - { rc.right - 1, rc.bottom - 1 }, - { rc.right - radius - 1, rc.bottom - 1 }, - }, - { - { rc.left + radius, rc.bottom - 1 }, - { rc.left, rc.bottom - 1 }, - { rc.left, rc.bottom - radius - 1 }, - }, - }; - - // Align the points in the middle of the pixels - for( int i = 0; i < 4; ++ i ) - { - for( int j = 0; j < 3; ++ j ) - { - corners[i][j].x += 0.5; - corners[i][j].y += 0.5; - } - } - - PenColour( fore ); - FillColour( back ); - - // Move to the last point to begin the path - CGContextBeginPath( gc ); - CGContextMoveToPoint( gc, corners[3][2].x, corners[3][2].y ); - - for ( int i = 0; i < 4; ++ i ) - { - CGContextAddLineToPoint( gc, corners[i][0].x, corners[i][0].y ); - CGContextAddArcToPoint( gc, corners[i][1].x, corners[i][1].y, corners[i][2].x, corners[i][2].y, radius ); - } - - // Close the path to enclose it for stroking and for filling, then draw it - CGContextClosePath( gc ); - CGContextDrawPath( gc, kCGPathFillStroke ); + // This is only called from the margin marker drawing code for SC_MARK_ROUNDRECT + // The Win32 version does + // ::RoundRect(hdc, rc.left + 1, rc.top, rc.right - 1, rc.bottom, 8, 8 ); + // which is a rectangle with rounded corners each having a radius of 4 pixels. + // It would be almost as good just cutting off the corners with lines at + // 45 degrees as is done on GTK+. + + // Create a rectangle with semicircles at the corners + const int MAX_RADIUS = 4; + const int radius = std::min(MAX_RADIUS, static_cast<int>(std::min(rc.Height()/2, rc.Width()/2))); + + // Points go clockwise, starting from just below the top left + // Corners are kept together, so we can easily create arcs to connect them + CGPoint corners[4][3] = { + { + { rc.left, rc.top + radius }, + { rc.left, rc.top }, + { rc.left + radius, rc.top }, + }, + { + { rc.right - radius - 1, rc.top }, + { rc.right - 1, rc.top }, + { rc.right - 1, rc.top + radius }, + }, + { + { rc.right - 1, rc.bottom - radius - 1 }, + { rc.right - 1, rc.bottom - 1 }, + { rc.right - radius - 1, rc.bottom - 1 }, + }, + { + { rc.left + radius, rc.bottom - 1 }, + { rc.left, rc.bottom - 1 }, + { rc.left, rc.bottom - radius - 1 }, + }, + }; + + // Align the points in the middle of the pixels + for (int i = 0; i < 4; ++ i) { + for (int j = 0; j < 3; ++ j) { + corners[i][j].x += 0.5; + corners[i][j].y += 0.5; + } + } + + PenColour(fore); + FillColour(back); + + // Move to the last point to begin the path + CGContextBeginPath(gc); + CGContextMoveToPoint(gc, corners[3][2].x, corners[3][2].y); + + for (int i = 0; i < 4; ++ i) { + CGContextAddLineToPoint(gc, corners[i][0].x, corners[i][0].y); + CGContextAddArcToPoint(gc, corners[i][1].x, corners[i][1].y, corners[i][2].x, corners[i][2].y, radius); + } + + // Close the path to enclose it for stroking and for filling, then draw it + CGContextClosePath(gc); + CGContextDrawPath(gc, kCGPathFillStroke); } // DrawChamferedRectangle is a helper function for AlphaRectangle that either fills or strokes a // rectangle with its corners chamfered at 45 degrees. static void DrawChamferedRectangle(CGContextRef gc, PRectangle rc, int cornerSize, CGPathDrawingMode mode) { - // Points go clockwise, starting from just below the top left - CGPoint corners[4][2] = - { - { - { rc.left, rc.top + cornerSize }, - { rc.left + cornerSize, rc.top }, - }, - { - { rc.right - cornerSize - 1, rc.top }, - { rc.right - 1, rc.top + cornerSize }, - }, - { - { rc.right - 1, rc.bottom - cornerSize - 1 }, - { rc.right - cornerSize - 1, rc.bottom - 1 }, - }, - { - { rc.left + cornerSize, rc.bottom - 1 }, - { rc.left, rc.bottom - cornerSize - 1 }, - }, - }; - - // Align the points in the middle of the pixels - for( int i = 0; i < 4; ++ i ) - { - for( int j = 0; j < 2; ++ j ) - { - corners[i][j].x += 0.5; - corners[i][j].y += 0.5; - } - } - - // Move to the last point to begin the path - CGContextBeginPath( gc ); - CGContextMoveToPoint( gc, corners[3][1].x, corners[3][1].y ); - - for ( int i = 0; i < 4; ++ i ) - { - CGContextAddLineToPoint( gc, corners[i][0].x, corners[i][0].y ); - CGContextAddLineToPoint( gc, corners[i][1].x, corners[i][1].y ); - } - - // Close the path to enclose it for stroking and for filling, then draw it - CGContextClosePath( gc ); - CGContextDrawPath( gc, mode ); + // Points go clockwise, starting from just below the top left + CGPoint corners[4][2] = { + { + { rc.left, rc.top + cornerSize }, + { rc.left + cornerSize, rc.top }, + }, + { + { rc.right - cornerSize - 1, rc.top }, + { rc.right - 1, rc.top + cornerSize }, + }, + { + { rc.right - 1, rc.bottom - cornerSize - 1 }, + { rc.right - cornerSize - 1, rc.bottom - 1 }, + }, + { + { rc.left + cornerSize, rc.bottom - 1 }, + { rc.left, rc.bottom - cornerSize - 1 }, + }, + }; + + // Align the points in the middle of the pixels + for (int i = 0; i < 4; ++ i) { + for (int j = 0; j < 2; ++ j) { + corners[i][j].x += 0.5; + corners[i][j].y += 0.5; + } + } + + // Move to the last point to begin the path + CGContextBeginPath(gc); + CGContextMoveToPoint(gc, corners[3][1].x, corners[3][1].y); + + for (int i = 0; i < 4; ++ i) { + CGContextAddLineToPoint(gc, corners[i][0].x, corners[i][0].y); + CGContextAddLineToPoint(gc, corners[i][1].x, corners[i][1].y); + } + + // Close the path to enclose it for stroking and for filling, then draw it + CGContextClosePath(gc); + CGContextDrawPath(gc, mode); } void Scintilla::SurfaceImpl::AlphaRectangle(PRectangle rc, int cornerSize, ColourDesired fill, int alphaFill, - ColourDesired outline, int alphaOutline, int /*flags*/) -{ - if ( gc ) { - // Snap rectangle boundaries to nearest int - rc.left = lround(rc.left); - rc.right = lround(rc.right); - // Set the Fill color to match - CGContextSetRGBFillColor( gc, fill.GetRed() / 255.0, fill.GetGreen() / 255.0, fill.GetBlue() / 255.0, alphaFill / 255.0 ); - CGContextSetRGBStrokeColor( gc, outline.GetRed() / 255.0, outline.GetGreen() / 255.0, outline.GetBlue() / 255.0, alphaOutline / 255.0 ); - PRectangle rcFill = rc; - if (cornerSize == 0) { - // A simple rectangle, no rounded corners - if ((fill == outline) && (alphaFill == alphaOutline)) { - // Optimization for simple case - CGRect rect = PRectangleToCGRect( rcFill ); - CGContextFillRect( gc, rect ); - } else { - rcFill.left += 1.0; - rcFill.top += 1.0; - rcFill.right -= 1.0; - rcFill.bottom -= 1.0; - CGRect rect = PRectangleToCGRect( rcFill ); - CGContextFillRect( gc, rect ); - CGContextAddRect( gc, CGRectMake( rc.left + 0.5, rc.top + 0.5, rc.Width() - 1, rc.Height() - 1 ) ); - CGContextStrokePath( gc ); - } - } else { - // Approximate rounded corners with 45 degree chamfers. - // Drawing real circular arcs often leaves some over- or under-drawn pixels. - if ((fill == outline) && (alphaFill == alphaOutline)) { - // Specializing this case avoids a few stray light/dark pixels in corners. - rcFill.left -= 0.5; - rcFill.top -= 0.5; - rcFill.right += 0.5; - rcFill.bottom += 0.5; - DrawChamferedRectangle( gc, rcFill, cornerSize, kCGPathFill ); - } else { - rcFill.left += 0.5; - rcFill.top += 0.5; - rcFill.right -= 0.5; - rcFill.bottom -= 0.5; - DrawChamferedRectangle( gc, rcFill, cornerSize-1, kCGPathFill ); - DrawChamferedRectangle( gc, rc, cornerSize, kCGPathStroke ); - } - } - } + ColourDesired outline, int alphaOutline, int /*flags*/) { + if (gc) { + // Snap rectangle boundaries to nearest int + rc.left = lround(rc.left); + rc.right = lround(rc.right); + // Set the Fill color to match + CGContextSetRGBFillColor(gc, fill.GetRed() / 255.0, fill.GetGreen() / 255.0, fill.GetBlue() / 255.0, alphaFill / 255.0); + CGContextSetRGBStrokeColor(gc, outline.GetRed() / 255.0, outline.GetGreen() / 255.0, outline.GetBlue() / 255.0, alphaOutline / 255.0); + PRectangle rcFill = rc; + if (cornerSize == 0) { + // A simple rectangle, no rounded corners + if ((fill == outline) && (alphaFill == alphaOutline)) { + // Optimization for simple case + CGRect rect = PRectangleToCGRect(rcFill); + CGContextFillRect(gc, rect); + } else { + rcFill.left += 1.0; + rcFill.top += 1.0; + rcFill.right -= 1.0; + rcFill.bottom -= 1.0; + CGRect rect = PRectangleToCGRect(rcFill); + CGContextFillRect(gc, rect); + CGContextAddRect(gc, CGRectMake(rc.left + 0.5, rc.top + 0.5, rc.Width() - 1, rc.Height() - 1)); + CGContextStrokePath(gc); + } + } else { + // Approximate rounded corners with 45 degree chamfers. + // Drawing real circular arcs often leaves some over- or under-drawn pixels. + if ((fill == outline) && (alphaFill == alphaOutline)) { + // Specializing this case avoids a few stray light/dark pixels in corners. + rcFill.left -= 0.5; + rcFill.top -= 0.5; + rcFill.right += 0.5; + rcFill.bottom += 0.5; + DrawChamferedRectangle(gc, rcFill, cornerSize, kCGPathFill); + } else { + rcFill.left += 0.5; + rcFill.top += 0.5; + rcFill.right -= 0.5; + rcFill.bottom -= 0.5; + DrawChamferedRectangle(gc, rcFill, cornerSize-1, kCGPathFill); + DrawChamferedRectangle(gc, rc, cornerSize, kCGPathStroke); + } + } + } } static void ProviderReleaseData(void *, const void *data, size_t) { @@ -733,25 +681,25 @@ static CGImageRef ImageCreateFromRGBA(int width, int height, const unsigned char } dataProvider = CGDataProviderCreateWithData( - NULL, pixelsUpsideDown, bitmapByteCount, ProviderReleaseData); + NULL, pixelsUpsideDown, bitmapByteCount, ProviderReleaseData); } else { dataProvider = CGDataProviderCreateWithData( - NULL, pixelsImage, bitmapByteCount, NULL); + NULL, pixelsImage, bitmapByteCount, NULL); } if (dataProvider) { // Create the CGImage. image = CGImageCreate(width, - height, - 8, - 8 * 4, - bitmapBytesPerRow, - colorSpace, - kCGImageAlphaLast, - dataProvider, - NULL, - 0, - kCGRenderingIntentDefault); + height, + 8, + 8 * 4, + bitmapBytesPerRow, + colorSpace, + kCGImageAlphaLast, + dataProvider, + NULL, + 0, + kCGRenderingIntentDefault); CGDataProviderRelease(dataProvider); } @@ -772,167 +720,159 @@ void SurfaceImpl::DrawRGBAImage(PRectangle rc, int width, int height, const unsi } void SurfaceImpl::Ellipse(PRectangle rc, ColourDesired fore, ColourDesired back) { - CGRect ellipseRect = CGRectMake(rc.left, rc.top, rc.Width(), rc.Height()); - FillColour(back); - PenColour(fore); - CGContextBeginPath(gc); - CGContextAddEllipseInRect(gc, ellipseRect); - CGContextDrawPath(gc, kCGPathFillStroke); -} - -void SurfaceImpl::CopyImageRectangle(Surface &surfaceSource, PRectangle srcRect, PRectangle dstRect) -{ - SurfaceImpl& source = static_cast<SurfaceImpl &>(surfaceSource); - CGImageRef image = source.GetImage(); - - CGRect src = PRectangleToCGRect(srcRect); - CGRect dst = PRectangleToCGRect(dstRect); - - /* source from QuickDrawToQuartz2D.pdf on developer.apple.com */ - float w = (float) CGImageGetWidth(image); - float h = (float) CGImageGetHeight(image); - CGRect drawRect = CGRectMake (0, 0, w, h); - if (!CGRectEqualToRect (src, dst)) - { - CGFloat sx = CGRectGetWidth(dst) / CGRectGetWidth(src); - CGFloat sy = CGRectGetHeight(dst) / CGRectGetHeight(src); - CGFloat dx = CGRectGetMinX(dst) - (CGRectGetMinX(src) * sx); - CGFloat dy = CGRectGetMinY(dst) - (CGRectGetMinY(src) * sy); - drawRect = CGRectMake (dx, dy, w*sx, h*sy); - } - CGContextSaveGState (gc); - CGContextClipToRect (gc, dst); - CGContextDrawImage (gc, drawRect, image); - CGContextRestoreGState (gc); - CGImageRelease(image); + CGRect ellipseRect = CGRectMake(rc.left, rc.top, rc.Width(), rc.Height()); + FillColour(back); + PenColour(fore); + CGContextBeginPath(gc); + CGContextAddEllipseInRect(gc, ellipseRect); + CGContextDrawPath(gc, kCGPathFillStroke); +} + +void SurfaceImpl::CopyImageRectangle(Surface &surfaceSource, PRectangle srcRect, PRectangle dstRect) { + SurfaceImpl &source = static_cast<SurfaceImpl &>(surfaceSource); + CGImageRef image = source.GetImage(); + + CGRect src = PRectangleToCGRect(srcRect); + CGRect dst = PRectangleToCGRect(dstRect); + + /* source from QuickDrawToQuartz2D.pdf on developer.apple.com */ + float w = (float) CGImageGetWidth(image); + float h = (float) CGImageGetHeight(image); + CGRect drawRect = CGRectMake(0, 0, w, h); + if (!CGRectEqualToRect(src, dst)) { + CGFloat sx = CGRectGetWidth(dst) / CGRectGetWidth(src); + CGFloat sy = CGRectGetHeight(dst) / CGRectGetHeight(src); + CGFloat dx = CGRectGetMinX(dst) - (CGRectGetMinX(src) * sx); + CGFloat dy = CGRectGetMinY(dst) - (CGRectGetMinY(src) * sy); + drawRect = CGRectMake(dx, dy, w*sx, h*sy); + } + CGContextSaveGState(gc); + CGContextClipToRect(gc, dst); + CGContextDrawImage(gc, drawRect, image); + CGContextRestoreGState(gc); + CGImageRelease(image); } void SurfaceImpl::Copy(PRectangle rc, Scintilla::Point from, Surface &surfaceSource) { - // Maybe we have to make the Surface two contexts: - // a bitmap context which we do all the drawing on, and then a "real" context - // which we copy the output to when we call "Synchronize". Ugh! Gross and slow! - - // For now, assume that copy can only be called on PixMap surfaces - SurfaceImpl& source = static_cast<SurfaceImpl &>(surfaceSource); - - // Get the CGImageRef - CGImageRef image = source.GetImage(); - // If we could not get an image reference, fill the rectangle black - if ( image == NULL ) - { - FillRectangle( rc, ColourDesired( 0 ) ); - return; - } + // Maybe we have to make the Surface two contexts: + // a bitmap context which we do all the drawing on, and then a "real" context + // which we copy the output to when we call "Synchronize". Ugh! Gross and slow! + + // For now, assume that copy can only be called on PixMap surfaces + SurfaceImpl &source = static_cast<SurfaceImpl &>(surfaceSource); + + // Get the CGImageRef + CGImageRef image = source.GetImage(); + // If we could not get an image reference, fill the rectangle black + if (image == NULL) { + FillRectangle(rc, ColourDesired(0)); + return; + } - // Now draw the image on the surface + // Now draw the image on the surface - // Some fancy clipping work is required here: draw only inside of rc - CGContextSaveGState( gc ); - CGContextClipToRect( gc, PRectangleToCGRect( rc ) ); + // Some fancy clipping work is required here: draw only inside of rc + CGContextSaveGState(gc); + CGContextClipToRect(gc, PRectangleToCGRect(rc)); - //Platform::DebugPrintf(stderr, "Copy: CGContextDrawImage: (%d, %d) - (%d X %d)\n", rc.left - from.x, rc.top - from.y, source.bitmapWidth, source.bitmapHeight ); - CGContextDrawImage( gc, CGRectMake( rc.left - from.x, rc.top - from.y, source.bitmapWidth, source.bitmapHeight ), image ); + //Platform::DebugPrintf(stderr, "Copy: CGContextDrawImage: (%d, %d) - (%d X %d)\n", rc.left - from.x, rc.top - from.y, source.bitmapWidth, source.bitmapHeight ); + CGContextDrawImage(gc, CGRectMake(rc.left - from.x, rc.top - from.y, source.bitmapWidth, source.bitmapHeight), image); - // Undo the clipping fun - CGContextRestoreGState( gc ); + // Undo the clipping fun + CGContextRestoreGState(gc); - // Done with the image - CGImageRelease( image ); - image = NULL; + // Done with the image + CGImageRelease(image); + image = NULL; } //-------------------------------------------------------------------------------------------------- void SurfaceImpl::DrawTextNoClip(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, - ColourDesired fore, ColourDesired back) -{ - FillRectangle(rc, back); - DrawTextTransparent(rc, font_, ybase, s, len, fore); + ColourDesired fore, ColourDesired back) { + FillRectangle(rc, back); + DrawTextTransparent(rc, font_, ybase, s, len, fore); } //-------------------------------------------------------------------------------------------------- void SurfaceImpl::DrawTextClipped(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, - ColourDesired fore, ColourDesired back) -{ - CGContextSaveGState(gc); - CGContextClipToRect(gc, PRectangleToCGRect(rc)); - DrawTextNoClip(rc, font_, ybase, s, len, fore, back); - CGContextRestoreGState(gc); -} - -//-------------------------------------------------------------------------------------------------- - -CFStringEncoding EncodingFromCharacterSet(bool unicode, int characterSet) -{ - if (unicode) - return kCFStringEncodingUTF8; - - // Unsupported -> Latin1 as reasonably safe - enum { notSupported = kCFStringEncodingISOLatin1}; - - switch (characterSet) - { - case SC_CHARSET_ANSI: - return kCFStringEncodingISOLatin1; - case SC_CHARSET_DEFAULT: - return kCFStringEncodingISOLatin1; - case SC_CHARSET_BALTIC: - return kCFStringEncodingWindowsBalticRim; - case SC_CHARSET_CHINESEBIG5: - return kCFStringEncodingBig5; - case SC_CHARSET_EASTEUROPE: - return kCFStringEncodingWindowsLatin2; - case SC_CHARSET_GB2312: - return kCFStringEncodingGB_18030_2000; - case SC_CHARSET_GREEK: - return kCFStringEncodingWindowsGreek; - case SC_CHARSET_HANGUL: - return kCFStringEncodingEUC_KR; - case SC_CHARSET_MAC: - return kCFStringEncodingMacRoman; - case SC_CHARSET_OEM: - return kCFStringEncodingISOLatin1; - case SC_CHARSET_RUSSIAN: - return kCFStringEncodingKOI8_R; - case SC_CHARSET_CYRILLIC: - return kCFStringEncodingWindowsCyrillic; - case SC_CHARSET_SHIFTJIS: - return kCFStringEncodingShiftJIS; - case SC_CHARSET_SYMBOL: - return kCFStringEncodingMacSymbol; - case SC_CHARSET_TURKISH: - return kCFStringEncodingWindowsLatin5; - case SC_CHARSET_JOHAB: - return kCFStringEncodingWindowsKoreanJohab; - case SC_CHARSET_HEBREW: - return kCFStringEncodingWindowsHebrew; - case SC_CHARSET_ARABIC: - return kCFStringEncodingWindowsArabic; - case SC_CHARSET_VIETNAMESE: - return kCFStringEncodingWindowsVietnamese; - case SC_CHARSET_THAI: - return kCFStringEncodingISOLatinThai; - case SC_CHARSET_8859_15: - return kCFStringEncodingISOLatin1; - default: - return notSupported; - } + ColourDesired fore, ColourDesired back) { + CGContextSaveGState(gc); + CGContextClipToRect(gc, PRectangleToCGRect(rc)); + DrawTextNoClip(rc, font_, ybase, s, len, fore, back); + CGContextRestoreGState(gc); +} + +//-------------------------------------------------------------------------------------------------- + +CFStringEncoding EncodingFromCharacterSet(bool unicode, int characterSet) { + if (unicode) + return kCFStringEncodingUTF8; + + // Unsupported -> Latin1 as reasonably safe + enum { notSupported = kCFStringEncodingISOLatin1}; + + switch (characterSet) { + case SC_CHARSET_ANSI: + return kCFStringEncodingISOLatin1; + case SC_CHARSET_DEFAULT: + return kCFStringEncodingISOLatin1; + case SC_CHARSET_BALTIC: + return kCFStringEncodingWindowsBalticRim; + case SC_CHARSET_CHINESEBIG5: + return kCFStringEncodingBig5; + case SC_CHARSET_EASTEUROPE: + return kCFStringEncodingWindowsLatin2; + case SC_CHARSET_GB2312: + return kCFStringEncodingGB_18030_2000; + case SC_CHARSET_GREEK: + return kCFStringEncodingWindowsGreek; + case SC_CHARSET_HANGUL: + return kCFStringEncodingEUC_KR; + case SC_CHARSET_MAC: + return kCFStringEncodingMacRoman; + case SC_CHARSET_OEM: + return kCFStringEncodingISOLatin1; + case SC_CHARSET_RUSSIAN: + return kCFStringEncodingKOI8_R; + case SC_CHARSET_CYRILLIC: + return kCFStringEncodingWindowsCyrillic; + case SC_CHARSET_SHIFTJIS: + return kCFStringEncodingShiftJIS; + case SC_CHARSET_SYMBOL: + return kCFStringEncodingMacSymbol; + case SC_CHARSET_TURKISH: + return kCFStringEncodingWindowsLatin5; + case SC_CHARSET_JOHAB: + return kCFStringEncodingWindowsKoreanJohab; + case SC_CHARSET_HEBREW: + return kCFStringEncodingWindowsHebrew; + case SC_CHARSET_ARABIC: + return kCFStringEncodingWindowsArabic; + case SC_CHARSET_VIETNAMESE: + return kCFStringEncodingWindowsVietnamese; + case SC_CHARSET_THAI: + return kCFStringEncodingISOLatinThai; + case SC_CHARSET_8859_15: + return kCFStringEncodingISOLatin1; + default: + return notSupported; + } } void SurfaceImpl::DrawTextTransparent(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, - ColourDesired fore) -{ + ColourDesired fore) { CFStringEncoding encoding = EncodingFromCharacterSet(unicodeMode, FontCharacterSet(font_)); ColourDesired colour(fore.AsLong()); - CGColorRef color = CGColorCreateGenericRGB(colour.GetRed()/255.0,colour.GetGreen()/255.0,colour.GetBlue()/255.0,1.0); + CGColorRef color = CGColorCreateGenericRGB(colour.GetRed()/255.0, colour.GetGreen()/255.0, colour.GetBlue()/255.0, 1.0); - QuartzTextStyle* style = static_cast<QuartzTextStyle*>(font_.GetID()); + QuartzTextStyle *style = static_cast<QuartzTextStyle *>(font_.GetID()); style->setCTStyleColor(color); CGColorRelease(color); - textLayout->setText (reinterpret_cast<const UInt8*>(s), len, encoding, *static_cast<QuartzTextStyle*>(font_.GetID())); + textLayout->setText(reinterpret_cast<const UInt8 *>(s), len, encoding, *static_cast<QuartzTextStyle *>(font_.GetID())); textLayout->draw(rc.left, ybase); } @@ -950,10 +890,9 @@ static size_t utf8LengthFromLead(unsigned char uch) { //-------------------------------------------------------------------------------------------------- -void SurfaceImpl::MeasureWidths(Font &font_, const char *s, int len, XYPOSITION *positions) -{ +void SurfaceImpl::MeasureWidths(Font &font_, const char *s, int len, XYPOSITION *positions) { CFStringEncoding encoding = EncodingFromCharacterSet(unicodeMode, FontCharacterSet(font_)); - textLayout->setText (reinterpret_cast<const UInt8*>(s), len, encoding, *static_cast<QuartzTextStyle*>(font_.GetID())); + textLayout->setText(reinterpret_cast<const UInt8 *>(s), len, encoding, *static_cast<QuartzTextStyle *>(font_.GetID())); CTLineRef mLine = textLayout->getCTLine(); assert(mLine != NULL); @@ -981,7 +920,7 @@ void SurfaceImpl::MeasureWidths(Font &font_, const char *s, int len, XYPOSITION } } else if (codePage) { int ui = 0; - for (int i=0;i<len;) { + for (int i=0; i<len;) { size_t lenChar = Platform::IsDBCSLeadByte(codePage, s[i]) ? 2 : 1; CGFloat xPosition = CTLineGetOffsetForStringIndex(mLine, ui+1, NULL); for (unsigned int bytePos=0; (bytePos<lenChar) && (i<len); bytePos++) { @@ -990,7 +929,7 @@ void SurfaceImpl::MeasureWidths(Font &font_, const char *s, int len, XYPOSITION ui++; } } else { // Single byte encoding - for (int i=0;i<len;i++) { + for (int i=0; i<len; i++) { CGFloat xPosition = CTLineGetOffsetForStringIndex(mLine, i+1, NULL); positions[i] = static_cast<XYPOSITION>(xPosition); } @@ -999,60 +938,57 @@ void SurfaceImpl::MeasureWidths(Font &font_, const char *s, int len, XYPOSITION } XYPOSITION SurfaceImpl::WidthText(Font &font_, const char *s, int len) { - if (font_.GetID()) - { - CFStringEncoding encoding = EncodingFromCharacterSet(unicodeMode, FontCharacterSet(font_)); - textLayout->setText (reinterpret_cast<const UInt8*>(s), len, encoding, *static_cast<QuartzTextStyle*>(font_.GetID())); + if (font_.GetID()) { + CFStringEncoding encoding = EncodingFromCharacterSet(unicodeMode, FontCharacterSet(font_)); + textLayout->setText(reinterpret_cast<const UInt8 *>(s), len, encoding, *static_cast<QuartzTextStyle *>(font_.GetID())); - return static_cast<XYPOSITION>(textLayout->MeasureStringWidth()); - } - return 1; + return static_cast<XYPOSITION>(textLayout->MeasureStringWidth()); + } + return 1; } XYPOSITION SurfaceImpl::WidthChar(Font &font_, char ch) { - char str[2] = { ch, '\0' }; - if (font_.GetID()) - { - CFStringEncoding encoding = EncodingFromCharacterSet(unicodeMode, FontCharacterSet(font_)); - textLayout->setText (reinterpret_cast<const UInt8*>(str), 1, encoding, *static_cast<QuartzTextStyle*>(font_.GetID())); + char str[2] = { ch, '\0' }; + if (font_.GetID()) { + CFStringEncoding encoding = EncodingFromCharacterSet(unicodeMode, FontCharacterSet(font_)); + textLayout->setText(reinterpret_cast<const UInt8 *>(str), 1, encoding, *static_cast<QuartzTextStyle *>(font_.GetID())); - return textLayout->MeasureStringWidth(); - } - else - return 1; + return textLayout->MeasureStringWidth(); + } else + return 1; } // This string contains a good range of characters to test for size. const char sizeString[] = "`~!@#$%^&*()-_=+\\|[]{};:\"\'<,>.?/1234567890" -"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; XYPOSITION SurfaceImpl::Ascent(Font &font_) { - if (!font_.GetID()) - return 1; + if (!font_.GetID()) + return 1; - float ascent = static_cast<QuartzTextStyle*>( font_.GetID() )->getAscent(); + float ascent = static_cast<QuartzTextStyle *>(font_.GetID())->getAscent(); return ascent + 0.5f; } XYPOSITION SurfaceImpl::Descent(Font &font_) { - if (!font_.GetID()) - return 1; + if (!font_.GetID()) + return 1; - float descent = static_cast<QuartzTextStyle*>( font_.GetID() )->getDescent(); + float descent = static_cast<QuartzTextStyle *>(font_.GetID())->getDescent(); return descent + 0.5f; } XYPOSITION SurfaceImpl::InternalLeading(Font &) { - return 0; + return 0; } XYPOSITION SurfaceImpl::ExternalLeading(Font &font_) { - if (!font_.GetID()) - return 1; + if (!font_.GetID()) + return 1; - float leading = static_cast<QuartzTextStyle*>( font_.GetID() )->getLeading(); + float leading = static_cast<QuartzTextStyle *>(font_.GetID())->getLeading(); return leading + 0.5f; } @@ -1064,35 +1000,34 @@ XYPOSITION SurfaceImpl::Height(Font &font_) { XYPOSITION SurfaceImpl::AverageCharWidth(Font &font_) { - if (!font_.GetID()) - return 1; + if (!font_.GetID()) + return 1; - const int sizeStringLength = ELEMENTS( sizeString ); - XYPOSITION width = WidthText( font_, sizeString, sizeStringLength ); + const int sizeStringLength = ELEMENTS(sizeString); + XYPOSITION width = WidthText(font_, sizeString, sizeStringLength); - return (int) ((width / (float) sizeStringLength) + 0.5); + return (int)((width / (float) sizeStringLength) + 0.5); } void SurfaceImpl::SetClip(PRectangle rc) { - CGContextClipToRect( gc, PRectangleToCGRect( rc ) ); + CGContextClipToRect(gc, PRectangleToCGRect(rc)); } void SurfaceImpl::FlushCachedState() { - CGContextSynchronize( gc ); + CGContextSynchronize(gc); } void SurfaceImpl::SetUnicodeMode(bool unicodeMode_) { - unicodeMode = unicodeMode_; + unicodeMode = unicodeMode_; } void SurfaceImpl::SetDBCSMode(int codePage_) { - if (codePage_ && (codePage_ != SC_CP_UTF8)) - codePage = codePage_; + if (codePage_ && (codePage_ != SC_CP_UTF8)) + codePage = codePage_; } -Surface *Surface::Allocate(int) -{ - return new SurfaceImpl(); +Surface *Surface::Allocate(int) { + return new SurfaceImpl(); } //----------------- Window ------------------------------------------------------------------------- @@ -1101,131 +1036,108 @@ Surface *Surface::Allocate(int) // be either an NSWindow or NSView and the code will check the type // before performing an action. -Window::~Window() -{ +Window::~Window() { } // Window::Destroy needs to see definition of ListBoxImpl so is located after ListBoxImpl //-------------------------------------------------------------------------------------------------- -bool Window::HasFocus() -{ - NSView* container = (__bridge NSView *)(wid); - return container.window.firstResponder == container; +bool Window::HasFocus() { + NSView *container = (__bridge NSView *)(wid); + return container.window.firstResponder == container; } //-------------------------------------------------------------------------------------------------- -static CGFloat ScreenMax() -{ - return NSMaxY([NSScreen mainScreen].frame); +static CGFloat ScreenMax() { + return NSMaxY([NSScreen mainScreen].frame); } //-------------------------------------------------------------------------------------------------- -PRectangle Window::GetPosition() -{ - if (wid) - { - NSRect rect; - id idWin = (__bridge id)(wid); - NSWindow* win; - if ([idWin isKindOfClass: [NSView class]]) - { - // NSView - NSView* view = idWin; - win = view.window; - rect = [view convertRect: view.bounds toView: nil]; - rect = [win convertRectToScreen:rect]; - } - else - { - // NSWindow - win = idWin; - rect = win.frame; - } - CGFloat screenHeight = ScreenMax(); - // Invert screen positions to match Scintilla - return PRectangle( - static_cast<XYPOSITION>(NSMinX(rect)), static_cast<XYPOSITION>(screenHeight - NSMaxY(rect)), - static_cast<XYPOSITION>(NSMaxX(rect)), static_cast<XYPOSITION>(screenHeight - NSMinY(rect))); - } - else - { - return PRectangle(0, 0, 1, 1); - } -} - -//-------------------------------------------------------------------------------------------------- - -void Window::SetPosition(PRectangle rc) -{ - if (wid) - { - id idWin = (__bridge id)(wid); - if ([idWin isKindOfClass: [NSView class]]) - { - // NSView - // Moves this view inside the parent view - NSRect nsrc = NSMakeRect(rc.left, rc.bottom, rc.Width(), rc.Height()); - NSView* view = idWin; - nsrc = [view.window convertRectFromScreen:nsrc]; - view.frame = nsrc; - } - else - { - // NSWindow - PLATFORM_ASSERT([idWin isKindOfClass: [NSWindow class]]); - NSWindow* win = idWin; - CGFloat screenHeight = ScreenMax(); - NSRect nsrc = NSMakeRect(rc.left, screenHeight - rc.bottom, - rc.Width(), rc.Height()); - [win setFrame: nsrc display:YES]; - } - } -} - -//-------------------------------------------------------------------------------------------------- - -void Window::SetPositionRelative(PRectangle rc, Window window) -{ - PRectangle rcOther = window.GetPosition(); - rc.left += rcOther.left; - rc.right += rcOther.left; - rc.top += rcOther.top; - rc.bottom += rcOther.top; - SetPosition(rc); +PRectangle Window::GetPosition() { + if (wid) { + NSRect rect; + id idWin = (__bridge id)(wid); + NSWindow *win; + if ([idWin isKindOfClass: [NSView class]]) { + // NSView + NSView *view = idWin; + win = view.window; + rect = [view convertRect: view.bounds toView: nil]; + rect = [win convertRectToScreen: rect]; + } else { + // NSWindow + win = idWin; + rect = win.frame; + } + CGFloat screenHeight = ScreenMax(); + // Invert screen positions to match Scintilla + return PRectangle( + static_cast<XYPOSITION>(NSMinX(rect)), static_cast<XYPOSITION>(screenHeight - NSMaxY(rect)), + static_cast<XYPOSITION>(NSMaxX(rect)), static_cast<XYPOSITION>(screenHeight - NSMinY(rect))); + } else { + return PRectangle(0, 0, 1, 1); + } } //-------------------------------------------------------------------------------------------------- -PRectangle Window::GetClientPosition() -{ - // This means, in MacOS X terms, get the "frame bounds". Call GetPosition, just like on Win32. - return GetPosition(); +void Window::SetPosition(PRectangle rc) { + if (wid) { + id idWin = (__bridge id)(wid); + if ([idWin isKindOfClass: [NSView class]]) { + // NSView + // Moves this view inside the parent view + NSRect nsrc = NSMakeRect(rc.left, rc.bottom, rc.Width(), rc.Height()); + NSView *view = idWin; + nsrc = [view.window convertRectFromScreen: nsrc]; + view.frame = nsrc; + } else { + // NSWindow + PLATFORM_ASSERT([idWin isKindOfClass: [NSWindow class]]); + NSWindow *win = idWin; + CGFloat screenHeight = ScreenMax(); + NSRect nsrc = NSMakeRect(rc.left, screenHeight - rc.bottom, + rc.Width(), rc.Height()); + [win setFrame: nsrc display: YES]; + } + } } //-------------------------------------------------------------------------------------------------- -void Window::Show(bool show) -{ - if (wid) - { - id idWin = (__bridge id)(wid); - if ([idWin isKindOfClass: [NSWindow class]]) - { - NSWindow* win = idWin; - if (show) - { - [win orderFront:nil]; - } - else - { - [win orderOut:nil]; - } - } - } +void Window::SetPositionRelative(PRectangle rc, Window window) { + PRectangle rcOther = window.GetPosition(); + rc.left += rcOther.left; + rc.right += rcOther.left; + rc.top += rcOther.top; + rc.bottom += rcOther.top; + SetPosition(rc); +} + +//-------------------------------------------------------------------------------------------------- + +PRectangle Window::GetClientPosition() { + // This means, in MacOS X terms, get the "frame bounds". Call GetPosition, just like on Win32. + return GetPosition(); +} + +//-------------------------------------------------------------------------------------------------- + +void Window::Show(bool show) { + if (wid) { + id idWin = (__bridge id)(wid); + if ([idWin isKindOfClass: [NSWindow class]]) { + NSWindow *win = idWin; + if (show) { + [win orderFront: nil]; + } else { + [win orderOut: nil]; + } + } + } } //-------------------------------------------------------------------------------------------------- @@ -1233,25 +1145,20 @@ void Window::Show(bool show) /** * Invalidates the entire window or view so it is completely redrawn. */ -void Window::InvalidateAll() -{ - if (wid) - { - id idWin = (__bridge id)(wid); - NSView* container; - if ([idWin isKindOfClass: [NSView class]]) - { - container = idWin; - } - else - { - // NSWindow - NSWindow* win = idWin; - container = win.contentView; - container.needsDisplay = YES; - } - container.needsDisplay = YES; - } +void Window::InvalidateAll() { + if (wid) { + id idWin = (__bridge id)(wid); + NSView *container; + if ([idWin isKindOfClass: [NSView class]]) { + container = idWin; + } else { + // NSWindow + NSWindow *win = idWin; + container = win.contentView; + container.needsDisplay = YES; + } + container.needsDisplay = YES; + } } //-------------------------------------------------------------------------------------------------- @@ -1259,31 +1166,25 @@ void Window::InvalidateAll() /** * Invalidates part of the window or view so only this part redrawn. */ -void Window::InvalidateRectangle(PRectangle rc) -{ - if (wid) - { - id idWin = (__bridge id)(wid); - NSView* container; - if ([idWin isKindOfClass: [NSView class]]) - { - container = idWin; - } - else - { - // NSWindow - NSWindow* win = idWin; - container = win.contentView; - } - [container setNeedsDisplayInRect: PRectangleToNSRect(rc)]; - } -} - -//-------------------------------------------------------------------------------------------------- - -void Window::SetFont(Font&) -{ - // Implemented on list subclass on Cocoa. +void Window::InvalidateRectangle(PRectangle rc) { + if (wid) { + id idWin = (__bridge id)(wid); + NSView *container; + if ([idWin isKindOfClass: [NSView class]]) { + container = idWin; + } else { + // NSWindow + NSWindow *win = idWin; + container = win.contentView; + } + [container setNeedsDisplayInRect: PRectangleToNSRect(rc)]; + } +} + +//-------------------------------------------------------------------------------------------------- + +void Window::SetFont(Font &) { + // Implemented on list subclass on Cocoa. } //-------------------------------------------------------------------------------------------------- @@ -1292,91 +1193,79 @@ void Window::SetFont(Font&) * Converts the Scintilla cursor enum into an NSCursor and stores it in the associated NSView, * which then will take care to set up a new mouse tracking rectangle. */ -void Window::SetCursor(Cursor curs) -{ - if (wid) - { - id idWin = (__bridge id)(wid); - if ([idWin isKindOfClass: [SCIContentView class]]) - { - SCIContentView* container = idWin; - [container setCursor: curs]; - } - } +void Window::SetCursor(Cursor curs) { + if (wid) { + id idWin = (__bridge id)(wid); + if ([idWin isKindOfClass: [SCIContentView class]]) { + SCIContentView *container = idWin; + [container setCursor: curs]; + } + } } //-------------------------------------------------------------------------------------------------- -void Window::SetTitle(const char* s) -{ - if (wid) - { - id idWin = (__bridge id)(wid); - if ([idWin isKindOfClass: [NSWindow class]]) - { - NSWindow* win = idWin; - NSString* sTitle = @(s); - win.title = sTitle; - } - } +void Window::SetTitle(const char *s) { + if (wid) { + id idWin = (__bridge id)(wid); + if ([idWin isKindOfClass: [NSWindow class]]) { + NSWindow *win = idWin; + NSString *sTitle = @(s); + win.title = sTitle; + } + } } //-------------------------------------------------------------------------------------------------- -PRectangle Window::GetMonitorRect(Point) -{ - if (wid) - { - id idWin = (__bridge id)(wid); - if ([idWin isKindOfClass: [NSView class]]) - { - NSView* view = idWin; - idWin = view.window; - } - if ([idWin isKindOfClass: [NSWindow class]]) - { - PRectangle rcPosition = GetPosition(); - - NSWindow* win = idWin; - NSScreen* screen = win.screen; - NSRect rect = screen.visibleFrame; - CGFloat screenHeight = rect.origin.y + rect.size.height; - // Invert screen positions to match Scintilla - PRectangle rcWork( - static_cast<XYPOSITION>(NSMinX(rect)), static_cast<XYPOSITION>(screenHeight - NSMaxY(rect)), - static_cast<XYPOSITION>(NSMaxX(rect)), static_cast<XYPOSITION>(screenHeight - NSMinY(rect))); - PRectangle rcMonitor(rcWork.left - rcPosition.left, - rcWork.top - rcPosition.top, - rcWork.right - rcPosition.left, - rcWork.bottom - rcPosition.top); - return rcMonitor; - } - } - return PRectangle(); +PRectangle Window::GetMonitorRect(Point) { + if (wid) { + id idWin = (__bridge id)(wid); + if ([idWin isKindOfClass: [NSView class]]) { + NSView *view = idWin; + idWin = view.window; + } + if ([idWin isKindOfClass: [NSWindow class]]) { + PRectangle rcPosition = GetPosition(); + + NSWindow *win = idWin; + NSScreen *screen = win.screen; + NSRect rect = screen.visibleFrame; + CGFloat screenHeight = rect.origin.y + rect.size.height; + // Invert screen positions to match Scintilla + PRectangle rcWork( + static_cast<XYPOSITION>(NSMinX(rect)), static_cast<XYPOSITION>(screenHeight - NSMaxY(rect)), + static_cast<XYPOSITION>(NSMaxX(rect)), static_cast<XYPOSITION>(screenHeight - NSMinY(rect))); + PRectangle rcMonitor(rcWork.left - rcPosition.left, + rcWork.top - rcPosition.top, + rcWork.right - rcPosition.left, + rcWork.bottom - rcPosition.top); + return rcMonitor; + } + } + return PRectangle(); } //----------------- ImageFromXPM ------------------------------------------------------------------- // Convert an XPM image into an NSImage for use with Cocoa -static NSImage* ImageFromXPM(XPM* pxpm) -{ - NSImage* img = nil; - if (pxpm) - { - const int width = pxpm->GetWidth(); - const int height = pxpm->GetHeight(); - PRectangle rcxpm(0, 0, width, height); - std::unique_ptr<Surface> surfaceXPM(Surface::Allocate(SC_TECHNOLOGY_DEFAULT)); - surfaceXPM->InitPixMap(width, height, NULL, NULL); - SurfaceImpl* surfaceIXPM = static_cast<SurfaceImpl*>(surfaceXPM.get()); - CGContextClearRect(surfaceIXPM->GetContext(), CGRectMake(0, 0, width, height)); - pxpm->Draw(surfaceXPM.get(), rcxpm); - CGImageRef imageRef = surfaceIXPM->GetImage(); - img = [[NSImage alloc] initWithCGImage:imageRef size: NSZeroSize]; - CGImageRelease(imageRef); - } - return img; +static NSImage *ImageFromXPM(XPM *pxpm) { + NSImage *img = nil; + if (pxpm) { + const int width = pxpm->GetWidth(); + const int height = pxpm->GetHeight(); + PRectangle rcxpm(0, 0, width, height); + std::unique_ptr<Surface> surfaceXPM(Surface::Allocate(SC_TECHNOLOGY_DEFAULT)); + surfaceXPM->InitPixMap(width, height, NULL, NULL); + SurfaceImpl *surfaceIXPM = static_cast<SurfaceImpl *>(surfaceXPM.get()); + CGContextClearRect(surfaceIXPM->GetContext(), CGRectMake(0, 0, width, height)); + pxpm->Draw(surfaceXPM.get(), rcxpm); + CGImageRef imageRef = surfaceIXPM->GetImage(); + img = [[NSImage alloc] initWithCGImage: imageRef size: NSZeroSize]; + CGImageRelease(imageRef); + } + return img; } //----------------- ListBox and related classes ---------------------------------------------------- @@ -1389,10 +1278,10 @@ namespace { class IListBox { public: - virtual int Rows() = 0; - virtual NSImage* ImageForRow(NSInteger row) = 0; - virtual NSString* TextForRow(NSInteger row) = 0; - virtual void DoubleClick() = 0; + virtual int Rows() = 0; + virtual NSImage *ImageForRow(NSInteger row) = 0; + virtual NSString *TextForRow(NSInteger row) = 0; + virtual void DoubleClick() = 0; }; } // unnamed namespace @@ -1400,15 +1289,15 @@ public: //----------------- AutoCompletionDataSource ------------------------------------------------------- @interface AutoCompletionDataSource : -NSObject + NSObject #if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_5 -<NSTableViewDataSource> + <NSTableViewDataSource> #endif { - IListBox* box; + IListBox *box; } -@property IListBox* box; +@property IListBox *box; @end @@ -1416,39 +1305,32 @@ NSObject @synthesize box; -- (void) doubleClick: (id) sender -{ +- (void) doubleClick: (id) sender { #pragma unused(sender) - if (box) - { + if (box) { box->DoubleClick(); } } -- (id)tableView: (NSTableView*)aTableView objectValueForTableColumn: (NSTableColumn*)aTableColumn row: (NSInteger)rowIndex -{ +- (id) tableView: (NSTableView *) aTableView objectValueForTableColumn: (NSTableColumn *) aTableColumn row: (NSInteger) rowIndex { #pragma unused(aTableView) if (!box) return nil; - if ([(NSString*)aTableColumn.identifier isEqualToString: @"icon"]) - { + if ([(NSString *)aTableColumn.identifier isEqualToString: @"icon"]) { return box->ImageForRow(rowIndex); - } - else { + } else { return box->TextForRow(rowIndex); } } -- (void)tableView: (NSTableView*)aTableView setObjectValue: anObject forTableColumn: (NSTableColumn*)aTableColumn row: (NSInteger)rowIndex -{ +- (void) tableView: (NSTableView *) aTableView setObjectValue: anObject forTableColumn: (NSTableColumn *) aTableColumn row: (NSInteger) rowIndex { #pragma unused(aTableView) #pragma unused(anObject) #pragma unused(aTableColumn) #pragma unused(rowIndex) } -- (NSInteger)numberOfRowsInTableView: (NSTableView*)aTableView -{ +- (NSInteger) numberOfRowsInTableView: (NSTableView *) aTableView { #pragma unused(aTableView) if (!box) return 0; @@ -1461,475 +1343,410 @@ NSObject namespace { // unnamed namespace hides ListBoxImpl and associated classes -struct RowData -{ - int type; - std::string text; - RowData(int type_, const char* text_) : - type(type_), text(text_) - { - } +struct RowData { + int type; + std::string text; + RowData(int type_, const char *text_) : + type(type_), text(text_) { + } }; -class LinesData -{ - std::vector<RowData> lines; +class LinesData { + std::vector<RowData> lines; public: - LinesData() - { - } - ~LinesData() - { - } - int Length() const - { - return static_cast<int>(lines.size()); - } - void Clear() - { - lines.clear(); - } - void Add(int /* index */, int type, char* str) - { - lines.push_back(RowData(type, str)); - } - int GetType(size_t index) const - { - if (index < lines.size()) - { - return lines[index].type; - } - else - { - return 0; - } - } - const char* GetString(size_t index) const - { - if (index < lines.size()) - { - return lines[index].text.c_str(); - } - else - { - return 0; - } - } + LinesData() { + } + ~LinesData() { + } + int Length() const { + return static_cast<int>(lines.size()); + } + void Clear() { + lines.clear(); + } + void Add(int /* index */, int type, char *str) { + lines.push_back(RowData(type, str)); + } + int GetType(size_t index) const { + if (index < lines.size()) { + return lines[index].type; + } else { + return 0; + } + } + const char *GetString(size_t index) const { + if (index < lines.size()) { + return lines[index].text.c_str(); + } else { + return 0; + } + } }; -class ListBoxImpl : public ListBox, IListBox -{ +class ListBoxImpl : public ListBox, IListBox { private: - NSMutableDictionary *images; - int lineHeight; - bool unicodeMode; - int desiredVisibleRows; - XYPOSITION maxItemWidth; - unsigned int aveCharWidth; - XYPOSITION maxIconWidth; - Font font; - int maxWidth; - - NSTableView* table; - NSScrollView* scroller; - NSTableColumn* colIcon; - NSTableColumn* colText; - AutoCompletionDataSource* ds; - - LinesData ld; - CallBackAction doubleClickAction; - void* doubleClickActionData; + NSMutableDictionary *images; + int lineHeight; + bool unicodeMode; + int desiredVisibleRows; + XYPOSITION maxItemWidth; + unsigned int aveCharWidth; + XYPOSITION maxIconWidth; + Font font; + int maxWidth; + + NSTableView *table; + NSScrollView *scroller; + NSTableColumn *colIcon; + NSTableColumn *colText; + AutoCompletionDataSource *ds; + + LinesData ld; + CallBackAction doubleClickAction; + void *doubleClickActionData; public: - ListBoxImpl() : - images(nil), - lineHeight(10), - unicodeMode(false), - desiredVisibleRows(5), - maxItemWidth(0), - aveCharWidth(8), - maxIconWidth(0), - maxWidth(2000), - table(nil), - scroller(nil), - colIcon(nil), - colText(nil), - ds(nil), - doubleClickAction(nullptr), - doubleClickActionData(nullptr) - { - images = [[NSMutableDictionary alloc] init]; - } - ~ListBoxImpl() override { - } - - // ListBox methods - void SetFont(Font& font) override; - void Create(Window& parent, int ctrlID, Scintilla::Point pt, int lineHeight_, bool unicodeMode_, int technology_) override; - void SetAverageCharWidth(int width) override; - void SetVisibleRows(int rows) override; - int GetVisibleRows() const override; - PRectangle GetDesiredRect() override; - int CaretFromEdge() override; - void Clear() override; - void Append(char* s, int type = -1) override; - int Length() override; - void Select(int n) override; - int GetSelection() override; - int Find(const char* prefix) override; - void GetValue(int n, char* value, int len) override; - void RegisterImage(int type, const char* xpm_data) override; - void RegisterRGBAImage(int type, int width, int height, const unsigned char *pixelsImage) override; - void ClearRegisteredImages() override; - void SetDoubleClickAction(CallBackAction action, void* data) override - { - doubleClickAction = action; - doubleClickActionData = data; - } - void SetList(const char* list, char separator, char typesep) override; - - // To clean up when closed - void ReleaseViews(); - - // For access from AutoCompletionDataSource implement IListBox - int Rows() override; - NSImage* ImageForRow(NSInteger row) override; - NSString* TextForRow(NSInteger row) override; - void DoubleClick() override; -}; - -void ListBoxImpl::Create(Window& /*parent*/, int /*ctrlID*/, Scintilla::Point pt, - int lineHeight_, bool unicodeMode_, int) -{ - lineHeight = lineHeight_; - unicodeMode = unicodeMode_; - maxWidth = 2000; - - NSRect lbRect = NSMakeRect(pt.x,pt.y, 120, lineHeight * desiredVisibleRows); - NSWindow* winLB = [[NSWindow alloc] initWithContentRect: lbRect - styleMask: NSBorderlessWindowMask - backing: NSBackingStoreBuffered - defer: NO]; - [winLB setLevel:NSFloatingWindowLevel]; - [winLB setHasShadow:YES]; - NSRect scRect = NSMakeRect(0, 0, lbRect.size.width, lbRect.size.height); - scroller = [[NSScrollView alloc] initWithFrame: scRect]; - [scroller setHasVerticalScroller:YES]; - table = [[NSTableView alloc] initWithFrame: scRect]; - [table setHeaderView:nil]; - scroller.documentView = table; - colIcon = [[NSTableColumn alloc] initWithIdentifier:@"icon"]; - colIcon.width = 20; - [colIcon setEditable:NO]; - [colIcon setHidden:YES]; - NSImageCell* imCell = [[NSImageCell alloc] init]; - colIcon.dataCell = imCell; - [table addTableColumn:colIcon]; - colText = [[NSTableColumn alloc] initWithIdentifier:@"name"]; - colText.resizingMask = NSTableColumnAutoresizingMask; - [colText setEditable:NO]; - [table addTableColumn:colText]; - ds = [[AutoCompletionDataSource alloc] init]; - ds.box = this; - table.dataSource = ds; // Weak reference - scroller.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable; - [winLB.contentView addSubview: scroller]; - - table.target = ds; - table.doubleAction = @selector(doubleClick:); - table.selectionHighlightStyle = NSTableViewSelectionHighlightStyleSourceList; - wid = (__bridge_retained WindowID)winLB; -} - -void ListBoxImpl::SetFont(Font& font_) -{ - // NSCell setFont takes an NSFont* rather than a CTFontRef but they - // are the same thing toll-free bridged. - QuartzTextStyle* style = static_cast<QuartzTextStyle*>(font_.GetID()); - font.Release(); - font.SetID(new QuartzTextStyle(*style)); - NSFont *pfont = (__bridge NSFont *)style->getFontRef(); - [colText.dataCell setFont: pfont]; - CGFloat itemHeight = ceil(pfont.boundingRectForFont.size.height); - table.rowHeight = itemHeight; -} - -void ListBoxImpl::SetAverageCharWidth(int width) -{ - aveCharWidth = width; -} + ListBoxImpl() : + images(nil), + lineHeight(10), + unicodeMode(false), + desiredVisibleRows(5), + maxItemWidth(0), + aveCharWidth(8), + maxIconWidth(0), + maxWidth(2000), + table(nil), + scroller(nil), + colIcon(nil), + colText(nil), + ds(nil), + doubleClickAction(nullptr), + doubleClickActionData(nullptr) { + images = [[NSMutableDictionary alloc] init]; + } + ~ListBoxImpl() override { + } -void ListBoxImpl::SetVisibleRows(int rows) -{ - desiredVisibleRows = rows; -} + // ListBox methods + void SetFont(Font &font) override; + void Create(Window &parent, int ctrlID, Scintilla::Point pt, int lineHeight_, bool unicodeMode_, int technology_) override; + void SetAverageCharWidth(int width) override; + void SetVisibleRows(int rows) override; + int GetVisibleRows() const override; + PRectangle GetDesiredRect() override; + int CaretFromEdge() override; + void Clear() override; + void Append(char *s, int type = -1) override; + int Length() override; + void Select(int n) override; + int GetSelection() override; + int Find(const char *prefix) override; + void GetValue(int n, char *value, int len) override; + void RegisterImage(int type, const char *xpm_data) override; + void RegisterRGBAImage(int type, int width, int height, const unsigned char *pixelsImage) override; + void ClearRegisteredImages() override; + void SetDoubleClickAction(CallBackAction action, void *data) override { + doubleClickAction = action; + doubleClickActionData = data; + } + void SetList(const char *list, char separator, char typesep) override; -int ListBoxImpl::GetVisibleRows() const -{ - return desiredVisibleRows; -} + // To clean up when closed + void ReleaseViews(); -PRectangle ListBoxImpl::GetDesiredRect() -{ - PRectangle rcDesired; - rcDesired = GetPosition(); + // For access from AutoCompletionDataSource implement IListBox + int Rows() override; + NSImage *ImageForRow(NSInteger row) override; + NSString *TextForRow(NSInteger row) override; + void DoubleClick() override; +}; - // There appears to be an extra pixel above and below the row contents - CGFloat itemHeight = table.rowHeight + 2; +void ListBoxImpl::Create(Window & /*parent*/, int /*ctrlID*/, Scintilla::Point pt, + int lineHeight_, bool unicodeMode_, int) { + lineHeight = lineHeight_; + unicodeMode = unicodeMode_; + maxWidth = 2000; + + NSRect lbRect = NSMakeRect(pt.x, pt.y, 120, lineHeight * desiredVisibleRows); + NSWindow *winLB = [[NSWindow alloc] initWithContentRect: lbRect + styleMask: NSBorderlessWindowMask + backing: NSBackingStoreBuffered + defer: NO]; + [winLB setLevel: NSFloatingWindowLevel]; + [winLB setHasShadow: YES]; + NSRect scRect = NSMakeRect(0, 0, lbRect.size.width, lbRect.size.height); + scroller = [[NSScrollView alloc] initWithFrame: scRect]; + [scroller setHasVerticalScroller: YES]; + table = [[NSTableView alloc] initWithFrame: scRect]; + [table setHeaderView: nil]; + scroller.documentView = table; + colIcon = [[NSTableColumn alloc] initWithIdentifier: @"icon"]; + colIcon.width = 20; + [colIcon setEditable: NO]; + [colIcon setHidden: YES]; + NSImageCell *imCell = [[NSImageCell alloc] init]; + colIcon.dataCell = imCell; + [table addTableColumn: colIcon]; + colText = [[NSTableColumn alloc] initWithIdentifier: @"name"]; + colText.resizingMask = NSTableColumnAutoresizingMask; + [colText setEditable: NO]; + [table addTableColumn: colText]; + ds = [[AutoCompletionDataSource alloc] init]; + ds.box = this; + table.dataSource = ds; // Weak reference + scroller.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable; + [winLB.contentView addSubview: scroller]; + + table.target = ds; + table.doubleAction = @selector(doubleClick:); + table.selectionHighlightStyle = NSTableViewSelectionHighlightStyleSourceList; + wid = (__bridge_retained WindowID)winLB; +} + +void ListBoxImpl::SetFont(Font &font_) { + // NSCell setFont takes an NSFont* rather than a CTFontRef but they + // are the same thing toll-free bridged. + QuartzTextStyle *style = static_cast<QuartzTextStyle *>(font_.GetID()); + font.Release(); + font.SetID(new QuartzTextStyle(*style)); + NSFont *pfont = (__bridge NSFont *)style->getFontRef(); + [colText.dataCell setFont: pfont]; + CGFloat itemHeight = ceil(pfont.boundingRectForFont.size.height); + table.rowHeight = itemHeight; +} + +void ListBoxImpl::SetAverageCharWidth(int width) { + aveCharWidth = width; +} + +void ListBoxImpl::SetVisibleRows(int rows) { + desiredVisibleRows = rows; +} + +int ListBoxImpl::GetVisibleRows() const { + return desiredVisibleRows; +} + +PRectangle ListBoxImpl::GetDesiredRect() { + PRectangle rcDesired; + rcDesired = GetPosition(); + + // There appears to be an extra pixel above and below the row contents + CGFloat itemHeight = table.rowHeight + 2; + + int rows = Length(); + if ((rows == 0) || (rows > desiredVisibleRows)) + rows = desiredVisibleRows; + + rcDesired.bottom = rcDesired.top + static_cast<XYPOSITION>(itemHeight * rows); + rcDesired.right = rcDesired.left + maxItemWidth + aveCharWidth; + rcDesired.right += 4; // Ensures no truncation of text + + if (Length() > rows) { + [scroller setHasVerticalScroller: YES]; + rcDesired.right += [NSScroller scrollerWidthForControlSize: NSRegularControlSize + scrollerStyle: NSScrollerStyleLegacy]; + } else { + [scroller setHasVerticalScroller: NO]; + } + rcDesired.right += maxIconWidth; + rcDesired.right += 6; // For icon space - int rows = Length(); - if ((rows == 0) || (rows > desiredVisibleRows)) - rows = desiredVisibleRows; + return rcDesired; +} - rcDesired.bottom = rcDesired.top + static_cast<XYPOSITION>(itemHeight * rows); - rcDesired.right = rcDesired.left + maxItemWidth + aveCharWidth; - rcDesired.right += 4; // Ensures no truncation of text +int ListBoxImpl::CaretFromEdge() { + if (colIcon.hidden) + return 3; + else + return 6 + static_cast<int>(colIcon.width); +} - if (Length() > rows) - { - [scroller setHasVerticalScroller:YES]; - rcDesired.right += [NSScroller scrollerWidthForControlSize:NSRegularControlSize - scrollerStyle:NSScrollerStyleLegacy]; - } - else - { - [scroller setHasVerticalScroller:NO]; - } - rcDesired.right += maxIconWidth; - rcDesired.right += 6; // For icon space +void ListBoxImpl::ReleaseViews() { + [table setDataSource: nil]; + table = nil; + scroller = nil; + colIcon = nil; + colText = nil; + ds = nil; +} - return rcDesired; +void ListBoxImpl::Clear() { + maxItemWidth = 0; + maxIconWidth = 0; + ld.Clear(); } -int ListBoxImpl::CaretFromEdge() -{ - if (colIcon.hidden) - return 3; - else - return 6 + static_cast<int>(colIcon.width); +void ListBoxImpl::Append(char *s, int type) { + int count = Length(); + ld.Add(count, type, s); + + Scintilla::SurfaceImpl surface; + XYPOSITION width = surface.WidthText(font, s, static_cast<int>(strlen(s))); + if (width > maxItemWidth) { + maxItemWidth = width; + colText.width = maxItemWidth; + } + NSImage *img = images[@(type)]; + if (img) { + XYPOSITION widthIcon = static_cast<XYPOSITION>(img.size.width); + if (widthIcon > maxIconWidth) { + [colIcon setHidden: NO]; + maxIconWidth = widthIcon; + colIcon.width = maxIconWidth; + } + } } -void ListBoxImpl::ReleaseViews() -{ - [table setDataSource:nil]; - table = nil; - scroller = nil; - colIcon = nil; - colText = nil; - ds = nil; +void ListBoxImpl::SetList(const char *list, char separator, char typesep) { + Clear(); + size_t count = strlen(list) + 1; + std::vector<char> words(list, list+count); + char *startword = words.data(); + char *numword = NULL; + int i = 0; + for (; words[i]; i++) { + if (words[i] == separator) { + words[i] = '\0'; + if (numword) + *numword = '\0'; + Append(startword, numword?atoi(numword + 1):-1); + startword = words.data() + i + 1; + numword = NULL; + } else if (words[i] == typesep) { + numword = words.data() + i; + } + } + if (startword) { + if (numword) + *numword = '\0'; + Append(startword, numword?atoi(numword + 1):-1); + } + [table reloadData]; } -void ListBoxImpl::Clear() -{ - maxItemWidth = 0; - maxIconWidth = 0; - ld.Clear(); +int ListBoxImpl::Length() { + return ld.Length(); } -void ListBoxImpl::Append(char* s, int type) -{ - int count = Length(); - ld.Add(count, type, s); - - Scintilla::SurfaceImpl surface; - XYPOSITION width = surface.WidthText(font, s, static_cast<int>(strlen(s))); - if (width > maxItemWidth) - { - maxItemWidth = width; - colText.width = maxItemWidth; - } - NSImage *img = images[@(type)]; - if (img) - { - XYPOSITION widthIcon = static_cast<XYPOSITION>(img.size.width); - if (widthIcon > maxIconWidth) - { - [colIcon setHidden: NO]; - maxIconWidth = widthIcon; - colIcon.width = maxIconWidth; - } - } -} - -void ListBoxImpl::SetList(const char* list, char separator, char typesep) -{ - Clear(); - size_t count = strlen(list) + 1; - std::vector<char> words(list, list+count); - char* startword = words.data(); - char* numword = NULL; - int i = 0; - for (; words[i]; i++) - { - if (words[i] == separator) - { - words[i] = '\0'; - if (numword) - *numword = '\0'; - Append(startword, numword?atoi(numword + 1):-1); - startword = words.data() + i + 1; - numword = NULL; - } - else if (words[i] == typesep) - { - numword = words.data() + i; - } - } - if (startword) - { - if (numword) - *numword = '\0'; - Append(startword, numword?atoi(numword + 1):-1); - } - [table reloadData]; -} - -int ListBoxImpl::Length() -{ - return ld.Length(); +void ListBoxImpl::Select(int n) { + [table selectRowIndexes: [NSIndexSet indexSetWithIndex: n] byExtendingSelection: NO]; + [table scrollRowToVisible: n]; } -void ListBoxImpl::Select(int n) -{ - [table selectRowIndexes:[NSIndexSet indexSetWithIndex:n] byExtendingSelection:NO]; - [table scrollRowToVisible:n]; +int ListBoxImpl::GetSelection() { + return static_cast<int>(table.selectedRow); } -int ListBoxImpl::GetSelection() -{ - return static_cast<int>(table.selectedRow); +int ListBoxImpl::Find(const char *prefix) { + int count = Length(); + for (int i = 0; i < count; i++) { + const char *s = ld.GetString(i); + if (s && (s[0] != '\0') && (0 == strncmp(prefix, s, strlen(prefix)))) { + return i; + } + } + return - 1; } -int ListBoxImpl::Find(const char* prefix) -{ - int count = Length(); - for (int i = 0; i < count; i++) - { - const char* s = ld.GetString(i); - if (s && (s[0] != '\0') && (0 == strncmp(prefix, s, strlen(prefix)))) - { - return i; - } - } - return - 1; -} - -void ListBoxImpl::GetValue(int n, char* value, int len) -{ - const char* textString = ld.GetString(n); - if (textString == NULL) - { - value[0] = '\0'; - return; - } - strlcpy(value, textString, len); +void ListBoxImpl::GetValue(int n, char *value, int len) { + const char *textString = ld.GetString(n); + if (textString == NULL) { + value[0] = '\0'; + return; + } + strlcpy(value, textString, len); } -void ListBoxImpl::RegisterImage(int type, const char* xpm_data) -{ - XPM xpm(xpm_data); - NSImage* img = ImageFromXPM(&xpm); - images[@(type)] = img; +void ListBoxImpl::RegisterImage(int type, const char *xpm_data) { + XPM xpm(xpm_data); + NSImage *img = ImageFromXPM(&xpm); + images[@(type)] = img; } -void ListBoxImpl::RegisterRGBAImage(int type, int width, int height, const unsigned char *pixelsImage) -{ - CGImageRef imageRef = ImageCreateFromRGBA(width, height, pixelsImage, false); - NSImage *img = [[NSImage alloc] initWithCGImage:imageRef size: NSZeroSize]; - CGImageRelease(imageRef); - images[@(type)] = img; +void ListBoxImpl::RegisterRGBAImage(int type, int width, int height, const unsigned char *pixelsImage) { + CGImageRef imageRef = ImageCreateFromRGBA(width, height, pixelsImage, false); + NSImage *img = [[NSImage alloc] initWithCGImage: imageRef size: NSZeroSize]; + CGImageRelease(imageRef); + images[@(type)] = img; } -void ListBoxImpl::ClearRegisteredImages() -{ - [images removeAllObjects]; +void ListBoxImpl::ClearRegisteredImages() { + [images removeAllObjects]; } -int ListBoxImpl::Rows() -{ - return ld.Length(); +int ListBoxImpl::Rows() { + return ld.Length(); } -NSImage* ListBoxImpl::ImageForRow(NSInteger row) -{ - return images[@(ld.GetType(row))]; +NSImage *ListBoxImpl::ImageForRow(NSInteger row) { + return images[@(ld.GetType(row))]; } -NSString* ListBoxImpl::TextForRow(NSInteger row) -{ - const char* textString = ld.GetString(row); - NSString* sTitle; - if (unicodeMode) - sTitle = @(textString); - else - sTitle = [NSString stringWithCString:textString encoding:NSWindowsCP1252StringEncoding]; - return sTitle; +NSString *ListBoxImpl::TextForRow(NSInteger row) { + const char *textString = ld.GetString(row); + NSString *sTitle; + if (unicodeMode) + sTitle = @(textString); + else + sTitle = [NSString stringWithCString: textString encoding: NSWindowsCP1252StringEncoding]; + return sTitle; } -void ListBoxImpl::DoubleClick() -{ - if (doubleClickAction) - { - doubleClickAction(doubleClickActionData); - } +void ListBoxImpl::DoubleClick() { + if (doubleClickAction) { + doubleClickAction(doubleClickActionData); + } } } // unnamed namespace //----------------- ListBox ------------------------------------------------------------------------ -ListBox::ListBox() -{ +ListBox::ListBox() { } -ListBox::~ListBox() -{ +ListBox::~ListBox() { } -ListBox* ListBox::Allocate() -{ - ListBoxImpl* lb = new ListBoxImpl(); +ListBox *ListBox::Allocate() { + ListBoxImpl *lb = new ListBoxImpl(); return lb; } //-------------------------------------------------------------------------------------------------- -void Window::Destroy() -{ - ListBoxImpl *listbox = dynamic_cast<ListBoxImpl *>(this); - if (listbox) - { - listbox->ReleaseViews(); - } - if (wid) - { - id idWin = (__bridge id)(wid); - if ([idWin isKindOfClass: [NSWindow class]]) - { - CFBridgingRelease(wid); - } - } - wid = nullptr; +void Window::Destroy() { + ListBoxImpl *listbox = dynamic_cast<ListBoxImpl *>(this); + if (listbox) { + listbox->ReleaseViews(); + } + if (wid) { + id idWin = (__bridge id)(wid); + if ([idWin isKindOfClass: [NSWindow class]]) { + CFBridgingRelease(wid); + } + } + wid = nullptr; } //----------------- ScintillaContextMenu ----------------------------------------------------------- -@implementation ScintillaContextMenu : NSMenu +@implementation ScintillaContextMenu : +NSMenu // This NSMenu subclass serves also as target for menu commands and forwards them as // notification messages to the front end. -- (void) handleCommand: (NSMenuItem*) sender -{ - owner->HandleCommand(sender.tag); +- (void) handleCommand: (NSMenuItem *) sender { + owner->HandleCommand(sender.tag); } //-------------------------------------------------------------------------------------------------- -- (void) setOwner: (Scintilla::ScintillaCocoa*) newOwner -{ - owner = newOwner; +- (void) setOwner: (Scintilla::ScintillaCocoa *) newOwner { + owner = newOwner; } @end @@ -1937,32 +1754,28 @@ void Window::Destroy() //----------------- Menu --------------------------------------------------------------------------- Menu::Menu() - : mid(0) -{ + : mid(0) { } //-------------------------------------------------------------------------------------------------- -void Menu::CreatePopUp() -{ - Destroy(); - mid = (__bridge_retained MenuID)[[ScintillaContextMenu alloc] initWithTitle: @""]; +void Menu::CreatePopUp() { + Destroy(); + mid = (__bridge_retained MenuID)[[ScintillaContextMenu alloc] initWithTitle: @""]; } //-------------------------------------------------------------------------------------------------- -void Menu::Destroy() -{ - CFBridgingRelease(mid); - mid = nullptr; +void Menu::Destroy() { + CFBridgingRelease(mid); + mid = nullptr; } //-------------------------------------------------------------------------------------------------- -void Menu::Show(Point, Window &) -{ - // Cocoa menus are handled a bit differently. We only create the menu. The framework - // takes care to show it properly. +void Menu::Show(Point, Window &) { + // Cocoa menus are handled a bit differently. We only create the menu. The framework + // takes care to show it properly. } //----------------- ElapsedTime -------------------------------------------------------------------- @@ -1971,40 +1784,38 @@ void Menu::Show(Point, Window &) // and not for anything a user sees. ElapsedTime::ElapsedTime() { - struct timeval curTime; - gettimeofday( &curTime, NULL ); + struct timeval curTime; + gettimeofday(&curTime, NULL); - bigBit = curTime.tv_sec; - littleBit = curTime.tv_usec; + bigBit = curTime.tv_sec; + littleBit = curTime.tv_usec; } double ElapsedTime::Duration(bool reset) { - struct timeval curTime; - gettimeofday( &curTime, NULL ); - long endBigBit = curTime.tv_sec; - long endLittleBit = curTime.tv_usec; - double result = 1000000.0 * (endBigBit - bigBit); - result += endLittleBit - littleBit; - result /= 1000000.0; - if (reset) { - bigBit = endBigBit; - littleBit = endLittleBit; - } - return result; + struct timeval curTime; + gettimeofday(&curTime, NULL); + long endBigBit = curTime.tv_sec; + long endLittleBit = curTime.tv_usec; + double result = 1000000.0 * (endBigBit - bigBit); + result += endLittleBit - littleBit; + result /= 1000000.0; + if (reset) { + bigBit = endBigBit; + littleBit = endLittleBit; + } + return result; } //----------------- Platform ----------------------------------------------------------------------- -ColourDesired Platform::Chrome() -{ - return ColourDesired(0xE0, 0xE0, 0xE0); +ColourDesired Platform::Chrome() { + return ColourDesired(0xE0, 0xE0, 0xE0); } //-------------------------------------------------------------------------------------------------- -ColourDesired Platform::ChromeHighlight() -{ - return ColourDesired(0xFF, 0xFF, 0xFF); +ColourDesired Platform::ChromeHighlight() { + return ColourDesired(0xFF, 0xFF, 0xFF); } //-------------------------------------------------------------------------------------------------- @@ -2012,10 +1823,9 @@ ColourDesired Platform::ChromeHighlight() /** * Returns the currently set system font for the user. */ -const char *Platform::DefaultFont() -{ - NSString* name = [[NSUserDefaults standardUserDefaults] stringForKey: @"NSFixedPitchFont"]; - return name.UTF8String; +const char *Platform::DefaultFont() { + NSString *name = [[NSUserDefaults standardUserDefaults] stringForKey: @"NSFixedPitchFont"]; + return name.UTF8String; } //-------------------------------------------------------------------------------------------------- @@ -2023,10 +1833,9 @@ const char *Platform::DefaultFont() /** * Returns the currently set system font size for the user. */ -int Platform::DefaultFontSize() -{ - return static_cast<int>([[NSUserDefaults standardUserDefaults] - integerForKey: @"NSFixedPitchFontSize"]); +int Platform::DefaultFontSize() { + return static_cast<int>([[NSUserDefaults standardUserDefaults] + integerForKey: @"NSFixedPitchFontSize"]); } //-------------------------------------------------------------------------------------------------- @@ -2037,20 +1846,18 @@ int Platform::DefaultFontSize() * * @return time span in milliseconds */ -unsigned int Platform::DoubleClickTime() -{ - float threshold = [[NSUserDefaults standardUserDefaults] floatForKey: - @"com.apple.mouse.doubleClickThreshold"]; - if (threshold == 0) - threshold = 0.5; - return static_cast<unsigned int>(threshold * 1000.0); +unsigned int Platform::DoubleClickTime() { + float threshold = [[NSUserDefaults standardUserDefaults] floatForKey: + @"com.apple.mouse.doubleClickThreshold"]; + if (threshold == 0) + threshold = 0.5; + return static_cast<unsigned int>(threshold * 1000.0); } //-------------------------------------------------------------------------------------------------- -bool Platform::MouseButtonBounce() -{ - return false; +bool Platform::MouseButtonBounce() { + return false; } //-------------------------------------------------------------------------------------------------- @@ -2058,9 +1865,8 @@ bool Platform::MouseButtonBounce() /** * Helper method for the backend to reach through to the scintilla window. */ -long Platform::SendScintilla(WindowID w, unsigned int msg, unsigned long wParam, long lParam) -{ - return scintilla_send_message(w, msg, wParam, lParam); +long Platform::SendScintilla(WindowID w, unsigned int msg, unsigned long wParam, long lParam) { + return scintilla_send_message(w, msg, wParam, lParam); } //-------------------------------------------------------------------------------------------------- @@ -2068,69 +1874,63 @@ long Platform::SendScintilla(WindowID w, unsigned int msg, unsigned long wParam, /** * Helper method for the backend to reach through to the scintilla window. */ -long Platform::SendScintillaPointer(WindowID w, unsigned int msg, unsigned long wParam, void *lParam) -{ - return scintilla_send_message(w, msg, wParam, (long) lParam); +long Platform::SendScintillaPointer(WindowID w, unsigned int msg, unsigned long wParam, void *lParam) { + return scintilla_send_message(w, msg, wParam, (long) lParam); +} + +//-------------------------------------------------------------------------------------------------- + +bool Platform::IsDBCSLeadByte(int codePage, char ch) { + // Byte ranges found in Wikipedia articles with relevant search strings in each case + unsigned char uch = static_cast<unsigned char>(ch); + switch (codePage) { + case 932: + // Shift_jis + return ((uch >= 0x81) && (uch <= 0x9F)) || + ((uch >= 0xE0) && (uch <= 0xFC)); + // Lead bytes F0 to FC may be a Microsoft addition. + case 936: + // GBK + return (uch >= 0x81) && (uch <= 0xFE); + case 949: + // Korean Wansung KS C-5601-1987 + return (uch >= 0x81) && (uch <= 0xFE); + case 950: + // Big5 + return (uch >= 0x81) && (uch <= 0xFE); + case 1361: + // Korean Johab KS C-5601-1992 + return + ((uch >= 0x84) && (uch <= 0xD3)) || + ((uch >= 0xD8) && (uch <= 0xDE)) || + ((uch >= 0xE0) && (uch <= 0xF9)); + } + return false; } //-------------------------------------------------------------------------------------------------- -bool Platform::IsDBCSLeadByte(int codePage, char ch) -{ - // Byte ranges found in Wikipedia articles with relevant search strings in each case - unsigned char uch = static_cast<unsigned char>(ch); - switch (codePage) - { - case 932: - // Shift_jis - return ((uch >= 0x81) && (uch <= 0x9F)) || - ((uch >= 0xE0) && (uch <= 0xFC)); - // Lead bytes F0 to FC may be a Microsoft addition. - case 936: - // GBK - return (uch >= 0x81) && (uch <= 0xFE); - case 949: - // Korean Wansung KS C-5601-1987 - return (uch >= 0x81) && (uch <= 0xFE); - case 950: - // Big5 - return (uch >= 0x81) && (uch <= 0xFE); - case 1361: - // Korean Johab KS C-5601-1992 - return - ((uch >= 0x84) && (uch <= 0xD3)) || - ((uch >= 0xD8) && (uch <= 0xDE)) || - ((uch >= 0xE0) && (uch <= 0xF9)); - } - return false; -} - -//-------------------------------------------------------------------------------------------------- - -int Platform::DBCSCharLength(int /* codePage */, const char* /* s */) -{ - // DBCS no longer uses this. - return 1; +int Platform::DBCSCharLength(int /* codePage */, const char * /* s */) { + // DBCS no longer uses this. + return 1; } //-------------------------------------------------------------------------------------------------- -int Platform::DBCSCharMaxLength() -{ - return 2; +int Platform::DBCSCharMaxLength() { + return 2; } //-------------------------------------------------------------------------------------------------- -int Platform::Minimum(int a, int b) -{ - return (a < b) ? a : b; +int Platform::Minimum(int a, int b) { + return (a < b) ? a : b; } //-------------------------------------------------------------------------------------------------- int Platform::Maximum(int a, int b) { - return (a > b) ? a : b; + return (a > b) ? a : b; } //-------------------------------------------------------------------------------------------------- @@ -2138,23 +1938,21 @@ int Platform::Maximum(int a, int b) { //#define TRACE #ifdef TRACE -void Platform::DebugDisplay(const char *s) -{ - fprintf( stderr, "%s", s ); +void Platform::DebugDisplay(const char *s) { + fprintf(stderr, "%s", s); } //-------------------------------------------------------------------------------------------------- -void Platform::DebugPrintf(const char *format, ...) -{ - const int BUF_SIZE = 2000; - char buffer[BUF_SIZE]; +void Platform::DebugPrintf(const char *format, ...) { + const int BUF_SIZE = 2000; + char buffer[BUF_SIZE]; - va_list pArguments; - va_start(pArguments, format); - vsnprintf(buffer, BUF_SIZE, format, pArguments); - va_end(pArguments); - Platform::DebugDisplay(buffer); + va_list pArguments; + va_start(pArguments, format); + vsnprintf(buffer, BUF_SIZE, format, pArguments); + va_end(pArguments); + Platform::DebugDisplay(buffer); } #else @@ -2169,35 +1967,32 @@ void Platform::DebugPrintf(const char *, ...) {} static bool assertionPopUps = true; -bool Platform::ShowAssertionPopUps(bool assertionPopUps_) -{ - bool ret = assertionPopUps; - assertionPopUps = assertionPopUps_; - return ret; +bool Platform::ShowAssertionPopUps(bool assertionPopUps_) { + bool ret = assertionPopUps; + assertionPopUps = assertionPopUps_; + return ret; } //-------------------------------------------------------------------------------------------------- -void Platform::Assert(const char *c, const char *file, int line) -{ - char buffer[2000]; - snprintf(buffer, sizeof(buffer), "Assertion [%s] failed at %s %d\r\n", c, file, line); - Platform::DebugDisplay(buffer); +void Platform::Assert(const char *c, const char *file, int line) { + char buffer[2000]; + snprintf(buffer, sizeof(buffer), "Assertion [%s] failed at %s %d\r\n", c, file, line); + Platform::DebugDisplay(buffer); #ifdef DEBUG - // Jump into debugger in assert on Mac (CL269835) - ::Debugger(); + // Jump into debugger in assert on Mac (CL269835) + ::Debugger(); #endif } //-------------------------------------------------------------------------------------------------- -int Platform::Clamp(int val, int minVal, int maxVal) -{ - if (val > maxVal) - val = maxVal; - if (val < minVal) - val = minVal; - return val; +int Platform::Clamp(int val, int minVal, int maxVal) { + if (val > maxVal) + val = maxVal; + if (val < minVal) + val = minVal; + return val; } //----------------- DynamicLibrary ----------------------------------------------------------------- @@ -2208,10 +2003,9 @@ int Platform::Clamp(int val, int minVal, int maxVal) * @param modulePath The path to the module to load. * @return A library instance or NULL if the module could not be found or another problem occurred. */ -DynamicLibrary* DynamicLibrary::Load(const char* /* modulePath */) -{ - // Not implemented. - return NULL; +DynamicLibrary *DynamicLibrary::Load(const char * /* modulePath */) { + // Not implemented. + return NULL; } //-------------------------------------------------------------------------------------------------- diff --git a/cocoa/QuartzTextLayout.h b/cocoa/QuartzTextLayout.h index 33869ae6e..033859529 100644 --- a/cocoa/QuartzTextLayout.h +++ b/cocoa/QuartzTextLayout.h @@ -16,39 +16,33 @@ #include "QuartzTextStyle.h" -class QuartzTextLayout -{ +class QuartzTextLayout { public: - /** Create a text layout for drawing on the specified context. */ - explicit QuartzTextLayout( CGContextRef context ) - { + /** Create a text layout for drawing on the specified context. */ + explicit QuartzTextLayout(CGContextRef context) { mString = NULL; mLine = NULL; stringLength = 0; - setContext(context); - } + setContext(context); + } - ~QuartzTextLayout() - { - if ( mString != NULL ) - { + ~QuartzTextLayout() { + if (mString != NULL) { CFRelease(mString); mString = NULL; } - if ( mLine != NULL ) - { + if (mLine != NULL) { CFRelease(mLine); mLine = NULL; } - } + } - inline void setText( const UInt8* buffer, size_t byteLength, CFStringEncoding encoding, const QuartzTextStyle& r ) - { - CFStringRef str = CFStringCreateWithBytes( NULL, buffer, byteLength, encoding, false ); - if (!str) - return; + inline void setText(const UInt8 *buffer, size_t byteLength, CFStringEncoding encoding, const QuartzTextStyle &r) { + CFStringRef str = CFStringCreateWithBytes(NULL, buffer, byteLength, encoding, false); + if (!str) + return; - stringLength = CFStringGetLength(str); + stringLength = CFStringGetLength(str); CFMutableDictionaryRef stringAttribs = r.getCTStyle(); @@ -60,14 +54,13 @@ public: CFRelease(mLine); mLine = ::CTLineCreateWithAttributedString(mString); - CFRelease( str ); - } + CFRelease(str); + } - /** Draw the text layout into the current CGContext at the specified position. - * @param x The x axis position to draw the baseline in the current CGContext. - * @param y The y axis position to draw the baseline in the current CGContext. */ - void draw( float x, float y ) - { + /** Draw the text layout into the current CGContext at the specified position. + * @param x The x axis position to draw the baseline in the current CGContext. + * @param y The y axis position to draw the baseline in the current CGContext. */ + void draw(float x, float y) { if (mLine == NULL) return; @@ -78,31 +71,29 @@ public: // And finally, draw! ::CTLineDraw(mLine, gc); - } + } - float MeasureStringWidth() - { + float MeasureStringWidth() { if (mLine == NULL) return 0.0f; return static_cast<float>(::CTLineGetTypographicBounds(mLine, NULL, NULL, NULL)); } - CTLineRef getCTLine() { - return mLine; - } + CTLineRef getCTLine() { + return mLine; + } - CFIndex getStringLength() { - return stringLength; - } + CFIndex getStringLength() { + return stringLength; + } - inline void setContext (CGContextRef context) - { - gc = context; - } + inline void setContext(CGContextRef context) { + gc = context; + } private: - CGContextRef gc; + CGContextRef gc; CFAttributedStringRef mString; CTLineRef mLine; CFIndex stringLength; diff --git a/cocoa/QuartzTextStyle.h b/cocoa/QuartzTextStyle.h index 12cc0e0b2..8572f5270 100644 --- a/cocoa/QuartzTextStyle.h +++ b/cocoa/QuartzTextStyle.h @@ -10,72 +10,60 @@ #include "QuartzTextStyleAttribute.h" -class QuartzTextStyle -{ +class QuartzTextStyle { public: - QuartzTextStyle() - { + QuartzTextStyle() { fontRef = NULL; styleDict = CFDictionaryCreateMutable(kCFAllocatorDefault, 2, - &kCFTypeDictionaryKeyCallBacks, - &kCFTypeDictionaryValueCallBacks); + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); characterSet = 0; } - QuartzTextStyle(const QuartzTextStyle &other) - { + QuartzTextStyle(const QuartzTextStyle &other) { // Does not copy font colour attribute fontRef = static_cast<CTFontRef>(CFRetain(other.fontRef)); styleDict = CFDictionaryCreateMutable(kCFAllocatorDefault, 2, - &kCFTypeDictionaryKeyCallBacks, - &kCFTypeDictionaryValueCallBacks); + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); CFDictionaryAddValue(styleDict, kCTFontAttributeName, fontRef); characterSet = other.characterSet; } - ~QuartzTextStyle() - { - if (styleDict != NULL) - { + ~QuartzTextStyle() { + if (styleDict != NULL) { CFRelease(styleDict); styleDict = NULL; } - if (fontRef) - { + if (fontRef) { CFRelease(fontRef); fontRef = NULL; } } - CFMutableDictionaryRef getCTStyle() const - { + CFMutableDictionaryRef getCTStyle() const { return styleDict; } - void setCTStyleColor(CGColor *inColor) - { + void setCTStyleColor(CGColor *inColor) { CFDictionarySetValue(styleDict, kCTForegroundColorAttributeName, inColor); } - float getAscent() const - { + float getAscent() const { return static_cast<float>(::CTFontGetAscent(fontRef)); } - float getDescent() const - { + float getDescent() const { return static_cast<float>(::CTFontGetDescent(fontRef)); } - float getLeading() const - { + float getLeading() const { return static_cast<float>(::CTFontGetLeading(fontRef)); } - void setFontRef(CTFontRef inRef, int characterSet_) - { + void setFontRef(CTFontRef inRef, int characterSet_) { fontRef = inRef; characterSet = characterSet_; @@ -83,19 +71,17 @@ public: CFRelease(styleDict); styleDict = CFDictionaryCreateMutable(kCFAllocatorDefault, 2, - &kCFTypeDictionaryKeyCallBacks, - &kCFTypeDictionaryValueCallBacks); + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); CFDictionaryAddValue(styleDict, kCTFontAttributeName, fontRef); } - CTFontRef getFontRef() - { + CTFontRef getFontRef() { return fontRef; } - int getCharacterSet() - { + int getCharacterSet() { return characterSet; } diff --git a/cocoa/QuartzTextStyleAttribute.h b/cocoa/QuartzTextStyleAttribute.h index b9698645e..b916c7a2f 100644 --- a/cocoa/QuartzTextStyleAttribute.h +++ b/cocoa/QuartzTextStyleAttribute.h @@ -12,20 +12,17 @@ #ifndef _QUARTZ_TEXT_STYLE_ATTRIBUTE_H #define _QUARTZ_TEXT_STYLE_ATTRIBUTE_H -class QuartzFont -{ +class QuartzFont { public: - /** Create a font style from a name. */ - QuartzFont( const char* name, size_t length, float size, int weight, bool italic ) - { - assert( name != NULL && length > 0 && name[length] == '\0' ); + /** Create a font style from a name. */ + QuartzFont(const char *name, size_t length, float size, int weight, bool italic) { + assert(name != NULL && length > 0 && name[length] == '\0'); CFStringRef fontName = CFStringCreateWithCString(kCFAllocatorDefault, name, kCFStringEncodingMacRoman); assert(fontName != NULL); - bool bold = weight > SC_WEIGHT_NORMAL; + bool bold = weight > SC_WEIGHT_NORMAL; - if (bold || italic) - { + if (bold || italic) { CTFontSymbolicTraits desiredTrait = 0; CTFontSymbolicTraits traitMask = 0; @@ -44,35 +41,28 @@ public: // create a font and then a copy of it with the sym traits CTFontRef iFont = ::CTFontCreateWithName(fontName, size, NULL); fontid = ::CTFontCreateCopyWithSymbolicTraits(iFont, size, NULL, desiredTrait, traitMask); - if (fontid) - { + if (fontid) { CFRelease(iFont); - } - else - { + } else { // Traits failed so use base font fontid = iFont; } - } - else - { + } else { // create the font, no traits fontid = ::CTFontCreateWithName(fontName, size, NULL); } - if (!fontid) - { + if (!fontid) { // Failed to create requested font so use font always present fontid = ::CTFontCreateWithName((CFStringRef)@"Monaco", size, NULL); } CFRelease(fontName); - } + } - CTFontRef getFontID() - { - return fontid; - } + CTFontRef getFontID() { + return fontid; + } private: CTFontRef fontid; diff --git a/cocoa/ScintillaCocoa.h b/cocoa/ScintillaCocoa.h index 7b9231012..25fc133ca 100644 --- a/cocoa/ScintillaCocoa.h +++ b/cocoa/ScintillaCocoa.h @@ -62,7 +62,7 @@ #include "AutoComplete.h" #include "ScintillaBase.h" -extern "C" NSString* ScintillaRecPboardType; +extern "C" NSString *ScintillaRecPboardType; @class SCIContentView; @class SCIMarginView; @@ -73,15 +73,14 @@ extern "C" NSString* ScintillaRecPboardType; /** * Helper class to be used as timer target (NSTimer). */ -@interface TimerTarget : NSObject -{ - void* mTarget; - NSNotificationQueue* notificationQueue; +@interface TimerTarget : NSObject { + void *mTarget; + NSNotificationQueue *notificationQueue; } -- (id) init: (void*) target; -- (void) timerFired: (NSTimer*) timer; -- (void) idleTimerFired: (NSTimer*) timer; -- (void) idleTriggered: (NSNotification*) notification; +- (id) init: (void *) target; +- (void) timerFired: (NSTimer *) timer; +- (void) idleTimerFired: (NSTimer *) timer; +- (void) idleTriggered: (NSNotification *) notification; @end namespace Scintilla { @@ -89,169 +88,168 @@ namespace Scintilla { /** * Main scintilla class, implemented for OS X (Cocoa). */ -class ScintillaCocoa : public ScintillaBase -{ +class ScintillaCocoa : public ScintillaBase { private: - ScintillaView* sciView; - TimerTarget* timerTarget; - NSEvent* lastMouseEvent; + ScintillaView *sciView; + TimerTarget *timerTarget; + NSEvent *lastMouseEvent; - id<ScintillaNotificationProtocol> delegate; + id<ScintillaNotificationProtocol> delegate; - SciNotifyFunc notifyProc; - intptr_t notifyObj; + SciNotifyFunc notifyProc; + intptr_t notifyObj; - bool capturedMouse; + bool capturedMouse; - bool enteredSetScrollingSize; + bool enteredSetScrollingSize; - bool GetPasteboardData(NSPasteboard* board, SelectionText* selectedText); - void SetPasteboardData(NSPasteboard* board, const SelectionText& selectedText); - int TargetAsUTF8(char *text); - int EncodedFromUTF8(char *utf8, char *encoded) const; + bool GetPasteboardData(NSPasteboard *board, SelectionText *selectedText); + void SetPasteboardData(NSPasteboard *board, const SelectionText &selectedText); + int TargetAsUTF8(char *text); + int EncodedFromUTF8(char *utf8, char *encoded) const; - int scrollSpeed; - int scrollTicks; - CFRunLoopObserverRef observer; + int scrollSpeed; + int scrollTicks; + CFRunLoopObserverRef observer; - FindHighlightLayer *layerFindIndicator; + FindHighlightLayer *layerFindIndicator; protected: - Point GetVisibleOriginInMain() const override; - PRectangle GetClientRectangle() const override; - PRectangle GetClientDrawingRectangle() override; - Point ConvertPoint(NSPoint point); - void RedrawRect(PRectangle rc) override; - void DiscardOverdraw() override; - void Redraw() override; - - void Init(); - CaseFolder *CaseFolderForEncoding() override; - std::string CaseMapString(const std::string &s, int caseMapping) override; - void CancelModes() override; + Point GetVisibleOriginInMain() const override; + PRectangle GetClientRectangle() const override; + PRectangle GetClientDrawingRectangle() override; + Point ConvertPoint(NSPoint point); + void RedrawRect(PRectangle rc) override; + void DiscardOverdraw() override; + void Redraw() override; + + void Init(); + CaseFolder *CaseFolderForEncoding() override; + std::string CaseMapString(const std::string &s, int caseMapping) override; + void CancelModes() override; public: - ScintillaCocoa(ScintillaView* sciView_, SCIContentView* viewContent, SCIMarginView* viewMargin); - // Deleted so ScintillaCocoa objects can not be copied. - ScintillaCocoa(const ScintillaCocoa &) = delete; - ScintillaCocoa &operator=(const ScintillaCocoa &) = delete; - ~ScintillaCocoa() override; - void Finalise() override; - - void SetDelegate(id<ScintillaNotificationProtocol> delegate_); - void RegisterNotifyCallback(intptr_t windowid, SciNotifyFunc callback); - sptr_t WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) override; - - NSScrollView* ScrollContainer() const; - SCIContentView* ContentView(); - - bool SyncPaint(void* gc, PRectangle rc); - bool Draw(NSRect rect, CGContextRef gc); - void PaintMargin(NSRect aRect); - - sptr_t DefWndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) override; - void TickFor(TickReason reason) override; - bool FineTickerAvailable() override; - bool FineTickerRunning(TickReason reason) override; - void FineTickerStart(TickReason reason, int millis, int tolerance) override; - void FineTickerCancel(TickReason reason) override; - bool SetIdle(bool on) override; - void SetMouseCapture(bool on) override; - bool HaveMouseCapture() override; - void WillDraw(NSRect rect); - void ScrollText(Sci::Line linesToMove) override; - void SetVerticalScrollPos() override; - void SetHorizontalScrollPos() override; - bool ModifyScrollBars(Sci::Line nMax, Sci::Line nPage) override; - bool SetScrollingSize(void); - void Resize(); - void UpdateForScroll(); - - // Notifications for the owner. - void NotifyChange() override; - void NotifyFocus(bool focus) override; - void NotifyParent(SCNotification scn) override; - void NotifyURIDropped(const char *uri); - - bool HasSelection(); - bool CanUndo(); - bool CanRedo(); - void CopyToClipboard(const SelectionText &selectedText) override; - void Copy() override; - bool CanPaste() override; - void Paste() override; - void Paste(bool rectangular); - void CTPaint(void* gc, NSRect rc); - void CallTipMouseDown(NSPoint pt); - void CreateCallTipWindow(PRectangle rc) override; - void AddToPopUp(const char *label, int cmd = 0, bool enabled = true) override; - void ClaimSelection() override; - - NSPoint GetCaretPosition(); - - static sptr_t DirectFunction(sptr_t ptr, unsigned int iMessage, uptr_t wParam, sptr_t lParam); - - NSTimer *timers[tickPlatform+1]; - void TimerFired(NSTimer* timer); - void IdleTimerFired(); - static void UpdateObserver(CFRunLoopObserverRef observer, CFRunLoopActivity activity, void *sci); - void ObserverAdd(); - void ObserverRemove(); - void IdleWork() override; - void QueueIdleWork(WorkNeeded::workItems items, Sci::Position upTo) override; - int InsertText(NSString* input); - NSRange PositionsFromCharacters(NSRange rangeCharacters) const; - NSRange CharactersFromPositions(NSRange rangePositions) const; - NSString *RangeTextAsString(NSRange rangePositions) const; - NSInteger VisibleLineForIndex(NSInteger index); - NSRange RangeForVisibleLine(NSInteger lineVisible); - NSRect FrameForRange(NSRange rangeCharacters); - NSRect GetBounds() const; - void SelectOnlyMainSelection(); - void ConvertSelectionVirtualSpace(); - bool ClearAllSelections(); - void CompositionStart(); - void CompositionCommit(); - void CompositionUndo(); - void SetDocPointer(Document *document) override; - - bool KeyboardInput(NSEvent* event); - void MouseDown(NSEvent* event); - void RightMouseDown(NSEvent* event); - void MouseMove(NSEvent* event); - void MouseUp(NSEvent* event); - void MouseEntered(NSEvent* event); - void MouseExited(NSEvent* event); - void MouseWheel(NSEvent* event); - - // Drag and drop - void StartDrag() override; - bool GetDragData(id <NSDraggingInfo> info, NSPasteboard &pasteBoard, SelectionText* selectedText); - NSDragOperation DraggingEntered(id <NSDraggingInfo> info); - NSDragOperation DraggingUpdated(id <NSDraggingInfo> info); - void DraggingExited(id <NSDraggingInfo> info); - bool PerformDragOperation(id <NSDraggingInfo> info); - void DragScroll(); - - // Promote some methods needed for NSResponder actions. - void SelectAll() override; - void DeleteBackward(); - void Cut() override; - void Undo() override; - void Redo() override; - - bool ShouldDisplayPopupOnMargin(); - bool ShouldDisplayPopupOnText(); - NSMenu* CreateContextMenu(NSEvent* event); - void HandleCommand(NSInteger command); - - void ActiveStateChanged(bool isActive); - void WindowWillMove(); - - // Find indicator - void ShowFindIndicatorForRange(NSRange charRange, BOOL retaining); - void MoveFindIndicatorWithBounce(BOOL bounce); - void HideFindIndicator(); + ScintillaCocoa(ScintillaView *sciView_, SCIContentView *viewContent, SCIMarginView *viewMargin); + // Deleted so ScintillaCocoa objects can not be copied. + ScintillaCocoa(const ScintillaCocoa &) = delete; + ScintillaCocoa &operator=(const ScintillaCocoa &) = delete; + ~ScintillaCocoa() override; + void Finalise() override; + + void SetDelegate(id<ScintillaNotificationProtocol> delegate_); + void RegisterNotifyCallback(intptr_t windowid, SciNotifyFunc callback); + sptr_t WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) override; + + NSScrollView *ScrollContainer() const; + SCIContentView *ContentView(); + + bool SyncPaint(void *gc, PRectangle rc); + bool Draw(NSRect rect, CGContextRef gc); + void PaintMargin(NSRect aRect); + + sptr_t DefWndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) override; + void TickFor(TickReason reason) override; + bool FineTickerAvailable() override; + bool FineTickerRunning(TickReason reason) override; + void FineTickerStart(TickReason reason, int millis, int tolerance) override; + void FineTickerCancel(TickReason reason) override; + bool SetIdle(bool on) override; + void SetMouseCapture(bool on) override; + bool HaveMouseCapture() override; + void WillDraw(NSRect rect); + void ScrollText(Sci::Line linesToMove) override; + void SetVerticalScrollPos() override; + void SetHorizontalScrollPos() override; + bool ModifyScrollBars(Sci::Line nMax, Sci::Line nPage) override; + bool SetScrollingSize(void); + void Resize(); + void UpdateForScroll(); + + // Notifications for the owner. + void NotifyChange() override; + void NotifyFocus(bool focus) override; + void NotifyParent(SCNotification scn) override; + void NotifyURIDropped(const char *uri); + + bool HasSelection(); + bool CanUndo(); + bool CanRedo(); + void CopyToClipboard(const SelectionText &selectedText) override; + void Copy() override; + bool CanPaste() override; + void Paste() override; + void Paste(bool rectangular); + void CTPaint(void *gc, NSRect rc); + void CallTipMouseDown(NSPoint pt); + void CreateCallTipWindow(PRectangle rc) override; + void AddToPopUp(const char *label, int cmd = 0, bool enabled = true) override; + void ClaimSelection() override; + + NSPoint GetCaretPosition(); + + static sptr_t DirectFunction(sptr_t ptr, unsigned int iMessage, uptr_t wParam, sptr_t lParam); + + NSTimer *timers[tickPlatform+1]; + void TimerFired(NSTimer *timer); + void IdleTimerFired(); + static void UpdateObserver(CFRunLoopObserverRef observer, CFRunLoopActivity activity, void *sci); + void ObserverAdd(); + void ObserverRemove(); + void IdleWork() override; + void QueueIdleWork(WorkNeeded::workItems items, Sci::Position upTo) override; + int InsertText(NSString *input); + NSRange PositionsFromCharacters(NSRange rangeCharacters) const; + NSRange CharactersFromPositions(NSRange rangePositions) const; + NSString *RangeTextAsString(NSRange rangePositions) const; + NSInteger VisibleLineForIndex(NSInteger index); + NSRange RangeForVisibleLine(NSInteger lineVisible); + NSRect FrameForRange(NSRange rangeCharacters); + NSRect GetBounds() const; + void SelectOnlyMainSelection(); + void ConvertSelectionVirtualSpace(); + bool ClearAllSelections(); + void CompositionStart(); + void CompositionCommit(); + void CompositionUndo(); + void SetDocPointer(Document *document) override; + + bool KeyboardInput(NSEvent *event); + void MouseDown(NSEvent *event); + void RightMouseDown(NSEvent *event); + void MouseMove(NSEvent *event); + void MouseUp(NSEvent *event); + void MouseEntered(NSEvent *event); + void MouseExited(NSEvent *event); + void MouseWheel(NSEvent *event); + + // Drag and drop + void StartDrag() override; + bool GetDragData(id <NSDraggingInfo> info, NSPasteboard &pasteBoard, SelectionText *selectedText); + NSDragOperation DraggingEntered(id <NSDraggingInfo> info); + NSDragOperation DraggingUpdated(id <NSDraggingInfo> info); + void DraggingExited(id <NSDraggingInfo> info); + bool PerformDragOperation(id <NSDraggingInfo> info); + void DragScroll(); + + // Promote some methods needed for NSResponder actions. + void SelectAll() override; + void DeleteBackward(); + void Cut() override; + void Undo() override; + void Redo() override; + + bool ShouldDisplayPopupOnMargin(); + bool ShouldDisplayPopupOnText(); + NSMenu *CreateContextMenu(NSEvent *event); + void HandleCommand(NSInteger command); + + void ActiveStateChanged(bool isActive); + void WindowWillMove(); + + // Find indicator + void ShowFindIndicatorForRange(NSRange charRange, BOOL retaining); + void MoveFindIndicatorWithBounce(BOOL bounce); + void HideFindIndicator(); }; diff --git a/cocoa/ScintillaCocoa.mm b/cocoa/ScintillaCocoa.mm index 3fa0904bb..eeb0daf8f 100644 --- a/cocoa/ScintillaCocoa.mm +++ b/cocoa/ScintillaCocoa.mm @@ -28,7 +28,7 @@ using namespace Scintilla; -NSString* ScintillaRecPboardType = @"com.scintilla.utf16-plain-text.rectangular"; +NSString *ScintillaRecPboardType = @"com.scintilla.utf16-plain-text.rectangular"; //-------------------------------------------------------------------------------------------------- @@ -37,100 +37,99 @@ NSString* ScintillaRecPboardType = @"com.scintilla.utf16-plain-text.rectangular" #define SCI_SCMD ( SCI_CMD | SCI_SHIFT) #define SCI_SMETA ( SCI_META | SCI_SHIFT) -static const KeyToCommand macMapDefault[] = -{ - // OS X specific - {SCK_DOWN, SCI_CTRL, SCI_DOCUMENTEND}, - {SCK_DOWN, SCI_CSHIFT, SCI_DOCUMENTENDEXTEND}, - {SCK_UP, SCI_CTRL, SCI_DOCUMENTSTART}, - {SCK_UP, SCI_CSHIFT, SCI_DOCUMENTSTARTEXTEND}, - {SCK_LEFT, SCI_CTRL, SCI_VCHOME}, - {SCK_LEFT, SCI_CSHIFT, SCI_VCHOMEEXTEND}, - {SCK_RIGHT, SCI_CTRL, SCI_LINEEND}, - {SCK_RIGHT, SCI_CSHIFT, SCI_LINEENDEXTEND}, - - // Similar to Windows and GTK+ - // Where equivalent clashes with OS X standard, use Meta instead - {SCK_DOWN, SCI_NORM, SCI_LINEDOWN}, - {SCK_DOWN, SCI_SHIFT, SCI_LINEDOWNEXTEND}, - {SCK_DOWN, SCI_META, SCI_LINESCROLLDOWN}, - {SCK_DOWN, SCI_ASHIFT, SCI_LINEDOWNRECTEXTEND}, - {SCK_UP, SCI_NORM, SCI_LINEUP}, - {SCK_UP, SCI_SHIFT, SCI_LINEUPEXTEND}, - {SCK_UP, SCI_META, SCI_LINESCROLLUP}, - {SCK_UP, SCI_ASHIFT, SCI_LINEUPRECTEXTEND}, - {'[', SCI_CTRL, SCI_PARAUP}, - {'[', SCI_CSHIFT, SCI_PARAUPEXTEND}, - {']', SCI_CTRL, SCI_PARADOWN}, - {']', SCI_CSHIFT, SCI_PARADOWNEXTEND}, - {SCK_LEFT, SCI_NORM, SCI_CHARLEFT}, - {SCK_LEFT, SCI_SHIFT, SCI_CHARLEFTEXTEND}, - {SCK_LEFT, SCI_ALT, SCI_WORDLEFT}, - {SCK_LEFT, SCI_META, SCI_WORDLEFT}, - {SCK_LEFT, SCI_SMETA, SCI_WORDLEFTEXTEND}, - {SCK_LEFT, SCI_ASHIFT, SCI_CHARLEFTRECTEXTEND}, - {SCK_RIGHT, SCI_NORM, SCI_CHARRIGHT}, - {SCK_RIGHT, SCI_SHIFT, SCI_CHARRIGHTEXTEND}, - {SCK_RIGHT, SCI_ALT, SCI_WORDRIGHT}, - {SCK_RIGHT, SCI_META, SCI_WORDRIGHT}, - {SCK_RIGHT, SCI_SMETA, SCI_WORDRIGHTEXTEND}, - {SCK_RIGHT, SCI_ASHIFT, SCI_CHARRIGHTRECTEXTEND}, - {'/', SCI_CTRL, SCI_WORDPARTLEFT}, - {'/', SCI_CSHIFT, SCI_WORDPARTLEFTEXTEND}, - {'\\', SCI_CTRL, SCI_WORDPARTRIGHT}, - {'\\', SCI_CSHIFT, SCI_WORDPARTRIGHTEXTEND}, - {SCK_HOME, SCI_NORM, SCI_VCHOME}, - {SCK_HOME, SCI_SHIFT, SCI_VCHOMEEXTEND}, - {SCK_HOME, SCI_CTRL, SCI_DOCUMENTSTART}, - {SCK_HOME, SCI_CSHIFT, SCI_DOCUMENTSTARTEXTEND}, - {SCK_HOME, SCI_ALT, SCI_HOMEDISPLAY}, - {SCK_HOME, SCI_ASHIFT, SCI_VCHOMERECTEXTEND}, - {SCK_END, SCI_NORM, SCI_LINEEND}, - {SCK_END, SCI_SHIFT, SCI_LINEENDEXTEND}, - {SCK_END, SCI_CTRL, SCI_DOCUMENTEND}, - {SCK_END, SCI_CSHIFT, SCI_DOCUMENTENDEXTEND}, - {SCK_END, SCI_ALT, SCI_LINEENDDISPLAY}, - {SCK_END, SCI_ASHIFT, SCI_LINEENDRECTEXTEND}, - {SCK_PRIOR, SCI_NORM, SCI_PAGEUP}, - {SCK_PRIOR, SCI_SHIFT, SCI_PAGEUPEXTEND}, - {SCK_PRIOR, SCI_ASHIFT, SCI_PAGEUPRECTEXTEND}, - {SCK_NEXT, SCI_NORM, SCI_PAGEDOWN}, - {SCK_NEXT, SCI_SHIFT, SCI_PAGEDOWNEXTEND}, - {SCK_NEXT, SCI_ASHIFT, SCI_PAGEDOWNRECTEXTEND}, - {SCK_DELETE, SCI_NORM, SCI_CLEAR}, - {SCK_DELETE, SCI_SHIFT, SCI_CUT}, - {SCK_DELETE, SCI_CTRL, SCI_DELWORDRIGHT}, - {SCK_DELETE, SCI_CSHIFT, SCI_DELLINERIGHT}, - {SCK_INSERT, SCI_NORM, SCI_EDITTOGGLEOVERTYPE}, - {SCK_INSERT, SCI_SHIFT, SCI_PASTE}, - {SCK_INSERT, SCI_CTRL, SCI_COPY}, - {SCK_ESCAPE, SCI_NORM, SCI_CANCEL}, - {SCK_BACK, SCI_NORM, SCI_DELETEBACK}, - {SCK_BACK, SCI_SHIFT, SCI_DELETEBACK}, - {SCK_BACK, SCI_CTRL, SCI_DELWORDLEFT}, - {SCK_BACK, SCI_ALT, SCI_DELWORDLEFT}, - {SCK_BACK, SCI_CSHIFT, SCI_DELLINELEFT}, - {'z', SCI_CMD, SCI_UNDO}, - {'z', SCI_SCMD, SCI_REDO}, - {'x', SCI_CMD, SCI_CUT}, - {'c', SCI_CMD, SCI_COPY}, - {'v', SCI_CMD, SCI_PASTE}, - {'a', SCI_CMD, SCI_SELECTALL}, - {SCK_TAB, SCI_NORM, SCI_TAB}, - {SCK_TAB, SCI_SHIFT, SCI_BACKTAB}, - {SCK_RETURN, SCI_NORM, SCI_NEWLINE}, - {SCK_RETURN, SCI_SHIFT, SCI_NEWLINE}, - {SCK_ADD, SCI_CMD, SCI_ZOOMIN}, - {SCK_SUBTRACT, SCI_CMD, SCI_ZOOMOUT}, - {SCK_DIVIDE, SCI_CMD, SCI_SETZOOM}, - {'l', SCI_CMD, SCI_LINECUT}, - {'l', SCI_CSHIFT, SCI_LINEDELETE}, - {'t', SCI_CSHIFT, SCI_LINECOPY}, - {'t', SCI_CTRL, SCI_LINETRANSPOSE}, - {'d', SCI_CTRL, SCI_SELECTIONDUPLICATE}, - {'u', SCI_CTRL, SCI_LOWERCASE}, - {'u', SCI_CSHIFT, SCI_UPPERCASE}, - {0, 0, 0}, +static const KeyToCommand macMapDefault[] = { + // OS X specific + {SCK_DOWN, SCI_CTRL, SCI_DOCUMENTEND}, + {SCK_DOWN, SCI_CSHIFT, SCI_DOCUMENTENDEXTEND}, + {SCK_UP, SCI_CTRL, SCI_DOCUMENTSTART}, + {SCK_UP, SCI_CSHIFT, SCI_DOCUMENTSTARTEXTEND}, + {SCK_LEFT, SCI_CTRL, SCI_VCHOME}, + {SCK_LEFT, SCI_CSHIFT, SCI_VCHOMEEXTEND}, + {SCK_RIGHT, SCI_CTRL, SCI_LINEEND}, + {SCK_RIGHT, SCI_CSHIFT, SCI_LINEENDEXTEND}, + + // Similar to Windows and GTK+ + // Where equivalent clashes with OS X standard, use Meta instead + {SCK_DOWN, SCI_NORM, SCI_LINEDOWN}, + {SCK_DOWN, SCI_SHIFT, SCI_LINEDOWNEXTEND}, + {SCK_DOWN, SCI_META, SCI_LINESCROLLDOWN}, + {SCK_DOWN, SCI_ASHIFT, SCI_LINEDOWNRECTEXTEND}, + {SCK_UP, SCI_NORM, SCI_LINEUP}, + {SCK_UP, SCI_SHIFT, SCI_LINEUPEXTEND}, + {SCK_UP, SCI_META, SCI_LINESCROLLUP}, + {SCK_UP, SCI_ASHIFT, SCI_LINEUPRECTEXTEND}, + {'[', SCI_CTRL, SCI_PARAUP}, + {'[', SCI_CSHIFT, SCI_PARAUPEXTEND}, + {']', SCI_CTRL, SCI_PARADOWN}, + {']', SCI_CSHIFT, SCI_PARADOWNEXTEND}, + {SCK_LEFT, SCI_NORM, SCI_CHARLEFT}, + {SCK_LEFT, SCI_SHIFT, SCI_CHARLEFTEXTEND}, + {SCK_LEFT, SCI_ALT, SCI_WORDLEFT}, + {SCK_LEFT, SCI_META, SCI_WORDLEFT}, + {SCK_LEFT, SCI_SMETA, SCI_WORDLEFTEXTEND}, + {SCK_LEFT, SCI_ASHIFT, SCI_CHARLEFTRECTEXTEND}, + {SCK_RIGHT, SCI_NORM, SCI_CHARRIGHT}, + {SCK_RIGHT, SCI_SHIFT, SCI_CHARRIGHTEXTEND}, + {SCK_RIGHT, SCI_ALT, SCI_WORDRIGHT}, + {SCK_RIGHT, SCI_META, SCI_WORDRIGHT}, + {SCK_RIGHT, SCI_SMETA, SCI_WORDRIGHTEXTEND}, + {SCK_RIGHT, SCI_ASHIFT, SCI_CHARRIGHTRECTEXTEND}, + {'/', SCI_CTRL, SCI_WORDPARTLEFT}, + {'/', SCI_CSHIFT, SCI_WORDPARTLEFTEXTEND}, + {'\\', SCI_CTRL, SCI_WORDPARTRIGHT}, + {'\\', SCI_CSHIFT, SCI_WORDPARTRIGHTEXTEND}, + {SCK_HOME, SCI_NORM, SCI_VCHOME}, + {SCK_HOME, SCI_SHIFT, SCI_VCHOMEEXTEND}, + {SCK_HOME, SCI_CTRL, SCI_DOCUMENTSTART}, + {SCK_HOME, SCI_CSHIFT, SCI_DOCUMENTSTARTEXTEND}, + {SCK_HOME, SCI_ALT, SCI_HOMEDISPLAY}, + {SCK_HOME, SCI_ASHIFT, SCI_VCHOMERECTEXTEND}, + {SCK_END, SCI_NORM, SCI_LINEEND}, + {SCK_END, SCI_SHIFT, SCI_LINEENDEXTEND}, + {SCK_END, SCI_CTRL, SCI_DOCUMENTEND}, + {SCK_END, SCI_CSHIFT, SCI_DOCUMENTENDEXTEND}, + {SCK_END, SCI_ALT, SCI_LINEENDDISPLAY}, + {SCK_END, SCI_ASHIFT, SCI_LINEENDRECTEXTEND}, + {SCK_PRIOR, SCI_NORM, SCI_PAGEUP}, + {SCK_PRIOR, SCI_SHIFT, SCI_PAGEUPEXTEND}, + {SCK_PRIOR, SCI_ASHIFT, SCI_PAGEUPRECTEXTEND}, + {SCK_NEXT, SCI_NORM, SCI_PAGEDOWN}, + {SCK_NEXT, SCI_SHIFT, SCI_PAGEDOWNEXTEND}, + {SCK_NEXT, SCI_ASHIFT, SCI_PAGEDOWNRECTEXTEND}, + {SCK_DELETE, SCI_NORM, SCI_CLEAR}, + {SCK_DELETE, SCI_SHIFT, SCI_CUT}, + {SCK_DELETE, SCI_CTRL, SCI_DELWORDRIGHT}, + {SCK_DELETE, SCI_CSHIFT, SCI_DELLINERIGHT}, + {SCK_INSERT, SCI_NORM, SCI_EDITTOGGLEOVERTYPE}, + {SCK_INSERT, SCI_SHIFT, SCI_PASTE}, + {SCK_INSERT, SCI_CTRL, SCI_COPY}, + {SCK_ESCAPE, SCI_NORM, SCI_CANCEL}, + {SCK_BACK, SCI_NORM, SCI_DELETEBACK}, + {SCK_BACK, SCI_SHIFT, SCI_DELETEBACK}, + {SCK_BACK, SCI_CTRL, SCI_DELWORDLEFT}, + {SCK_BACK, SCI_ALT, SCI_DELWORDLEFT}, + {SCK_BACK, SCI_CSHIFT, SCI_DELLINELEFT}, + {'z', SCI_CMD, SCI_UNDO}, + {'z', SCI_SCMD, SCI_REDO}, + {'x', SCI_CMD, SCI_CUT}, + {'c', SCI_CMD, SCI_COPY}, + {'v', SCI_CMD, SCI_PASTE}, + {'a', SCI_CMD, SCI_SELECTALL}, + {SCK_TAB, SCI_NORM, SCI_TAB}, + {SCK_TAB, SCI_SHIFT, SCI_BACKTAB}, + {SCK_RETURN, SCI_NORM, SCI_NEWLINE}, + {SCK_RETURN, SCI_SHIFT, SCI_NEWLINE}, + {SCK_ADD, SCI_CMD, SCI_ZOOMIN}, + {SCK_SUBTRACT, SCI_CMD, SCI_ZOOMOUT}, + {SCK_DIVIDE, SCI_CMD, SCI_SETZOOM}, + {'l', SCI_CMD, SCI_LINECUT}, + {'l', SCI_CSHIFT, SCI_LINEDELETE}, + {'t', SCI_CSHIFT, SCI_LINECOPY}, + {'t', SCI_CTRL, SCI_LINETRANSPOSE}, + {'d', SCI_CTRL, SCI_SELECTIONDUPLICATE}, + {'u', SCI_CTRL, SCI_LOWERCASE}, + {'u', SCI_CSHIFT, SCI_UPPERCASE}, + {0, 0, 0}, }; //-------------------------------------------------------------------------------------------------- @@ -142,8 +141,7 @@ static const KeyToCommand macMapDefault[] = /** * Class to display the animated gold roundrect used on OS X for matches. */ -@interface FindHighlightLayer : CAGradientLayer -{ +@interface FindHighlightLayer : CAGradientLayer { @private NSString *sFind; int positionFind; @@ -154,15 +152,15 @@ static const KeyToCommand macMapDefault[] = CGFloat fontSize; } -@property (copy) NSString *sFind; -@property (assign) int positionFind; -@property (assign) BOOL retaining; -@property (assign) CGFloat widthText; -@property (assign) CGFloat heightLine; -@property (copy) NSString *sFont; -@property (assign) CGFloat fontSize; +@property(copy) NSString *sFind; +@property(assign) int positionFind; +@property(assign) BOOL retaining; +@property(assign) CGFloat widthText; +@property(assign) CGFloat heightLine; +@property(copy) NSString *sFont; +@property(assign) CGFloat fontSize; -- (void) animateMatch: (CGPoint)ptText bounce:(BOOL)bounce; +- (void) animateMatch: (CGPoint) ptText bounce: (BOOL) bounce; - (void) hideMatch; @end @@ -173,7 +171,7 @@ static const KeyToCommand macMapDefault[] = @synthesize sFind, positionFind, retaining, widthText, heightLine, sFont, fontSize; --(id) init { +- (id) init { if (self = [super init]) { [self setNeedsDisplayOnBoundsChange: YES]; // A gold to slightly redder gradient to match other applications @@ -202,15 +200,15 @@ static const KeyToCommand macMapDefault[] = const CGFloat paddingHighlightX = 4; const CGFloat paddingHighlightY = 2; --(void) drawInContext:(CGContextRef)context { +- (void) drawInContext: (CGContextRef) context { if (!sFind || !sFont) return; CFStringRef str = (__bridge CFStringRef)(sFind); CFMutableDictionaryRef styleDict = CFDictionaryCreateMutable(kCFAllocatorDefault, 2, - &kCFTypeDictionaryKeyCallBacks, - &kCFTypeDictionaryValueCallBacks); + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); CGColorRef color = CGColorCreateGenericRGB(0.0, 0.0, 0.0, 1.0); CFDictionarySetValue(styleDict, kCTForegroundColorAttributeName, color); CTFontRef fontRef = ::CTFontCreateWithName((CFStringRef)sFont, fontSize, NULL); @@ -229,7 +227,7 @@ const CGFloat paddingHighlightY = 2; CFRelease(styleDict); } -- (void) animateMatch: (CGPoint)ptText bounce:(BOOL)bounce { +- (void) animateMatch: (CGPoint) ptText bounce: (BOOL) bounce { if (!self.sFind || !(self.sFind).length) { [self hideMatch]; return; @@ -249,8 +247,8 @@ const CGFloat paddingHighlightY = 2; ptText.y -= flipper * height / 2.0; [CATransaction begin]; - [CATransaction setValue:@0.0f forKey:kCATransactionAnimationDuration]; - self.bounds = CGRectMake(0,0, width, height); + [CATransaction setValue: @0.0f forKey: kCATransactionAnimationDuration]; + self.bounds = CGRectMake(0, 0, width, height); self.position = ptText; if (bounce) { // Do not reset visibility when just moving @@ -261,7 +259,7 @@ const CGFloat paddingHighlightY = 2; [CATransaction commit]; if (bounce) { - CABasicAnimation *animBounce = [CABasicAnimation animationWithKeyPath:@"transform.scale"]; + CABasicAnimation *animBounce = [CABasicAnimation animationWithKeyPath: @"transform.scale"]; animBounce.duration = 0.15; animBounce.autoreverses = YES; animBounce.removedOnCompletion = NO; @@ -270,11 +268,11 @@ const CGFloat paddingHighlightY = 2; if (self.retaining) { - [self addAnimation: animBounce forKey:@"animateFound"]; + [self addAnimation: animBounce forKey: @"animateFound"]; } else { - CABasicAnimation *animFade = [CABasicAnimation animationWithKeyPath:@"opacity"]; + CABasicAnimation *animFade = [CABasicAnimation animationWithKeyPath: @"opacity"]; animFade.duration = 0.1; animFade.beginTime = 0.4; animFade.removedOnCompletion = NO; @@ -287,7 +285,7 @@ const CGFloat paddingHighlightY = 2; group.fillMode = kCAFillModeForwards; group.animations = @[animBounce, animFade]; - [self addAnimation:group forKey:@"animateFound"]; + [self addAnimation: group forKey: @"animateFound"]; } } } @@ -306,28 +304,25 @@ const CGFloat paddingHighlightY = 2; @implementation TimerTarget -- (id) init: (void*) target -{ - self = [super init]; - if (self != nil) - { - mTarget = target; +- (id) init: (void *) target { + self = [super init]; + if (self != nil) { + mTarget = target; - // Get the default notification queue for the thread which created the instance (usually the - // main thread). We need that later for idle event processing. - NSNotificationCenter* center = [NSNotificationCenter defaultCenter]; - notificationQueue = [[NSNotificationQueue alloc] initWithNotificationCenter: center]; - [center addObserver: self selector: @selector(idleTriggered:) name: @"Idle" object: nil]; - } - return self; + // Get the default notification queue for the thread which created the instance (usually the + // main thread). We need that later for idle event processing. + NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; + notificationQueue = [[NSNotificationQueue alloc] initWithNotificationCenter: center]; + [center addObserver: self selector: @selector(idleTriggered:) name: @"Idle" object: nil]; + } + return self; } //-------------------------------------------------------------------------------------------------- -- (void) dealloc -{ - NSNotificationCenter* center = [NSNotificationCenter defaultCenter]; - [center removeObserver:self]; +- (void) dealloc { + NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; + [center removeObserver: self]; } //-------------------------------------------------------------------------------------------------- @@ -335,10 +330,9 @@ const CGFloat paddingHighlightY = 2; /** * Method called by owning ScintillaCocoa object when it is destroyed. */ -- (void) ownerDestroyed -{ - mTarget = NULL; - notificationQueue = nil; +- (void) ownerDestroyed { + mTarget = NULL; + notificationQueue = nil; } //-------------------------------------------------------------------------------------------------- @@ -347,10 +341,9 @@ const CGFloat paddingHighlightY = 2; * Method called by a timer installed by ScintillaCocoa. This two step approach is needed because * a native Obj-C class is required as target for the timer. */ -- (void) timerFired: (NSTimer*) timer -{ - if (mTarget) - static_cast<ScintillaCocoa*>(mTarget)->TimerFired(timer); +- (void) timerFired: (NSTimer *) timer { + if (mTarget) + static_cast<ScintillaCocoa *>(mTarget)->TimerFired(timer); } //-------------------------------------------------------------------------------------------------- @@ -358,18 +351,17 @@ const CGFloat paddingHighlightY = 2; /** * Another timer callback for the idle timer. */ -- (void) idleTimerFired: (NSTimer*) timer -{ +- (void) idleTimerFired: (NSTimer *) timer { #pragma unused(timer) - // Idle timer event. - // Post a new idle notification, which gets executed when the run loop is idle. - // Since we are coalescing on name and sender there will always be only one actual notification - // even for multiple requests. - NSNotification *notification = [NSNotification notificationWithName: @"Idle" object: self]; - [notificationQueue enqueueNotification: notification - postingStyle: NSPostWhenIdle - coalesceMask: (NSNotificationCoalescingOnName | NSNotificationCoalescingOnSender) - forModes: @[NSDefaultRunLoopMode, NSModalPanelRunLoopMode]]; + // Idle timer event. + // Post a new idle notification, which gets executed when the run loop is idle. + // Since we are coalescing on name and sender there will always be only one actual notification + // even for multiple requests. + NSNotification *notification = [NSNotification notificationWithName: @"Idle" object: self]; + [notificationQueue enqueueNotification: notification + postingStyle: NSPostWhenIdle + coalesceMask: (NSNotificationCoalescingOnName | NSNotificationCoalescingOnSender) + forModes: @[NSDefaultRunLoopMode, NSModalPanelRunLoopMode]]; } //-------------------------------------------------------------------------------------------------- @@ -378,50 +370,46 @@ const CGFloat paddingHighlightY = 2; * Another step for idle events. The timer (for idle events) simply requests a notification on * idle time. Only when this notification is send we actually call back the editor. */ -- (void) idleTriggered: (NSNotification*) notification -{ +- (void) idleTriggered: (NSNotification *) notification { #pragma unused(notification) - if (mTarget) - static_cast<ScintillaCocoa*>(mTarget)->IdleTimerFired(); + if (mTarget) + static_cast<ScintillaCocoa *>(mTarget)->IdleTimerFired(); } @end //----------------- ScintillaCocoa ----------------------------------------------------------------- -ScintillaCocoa::ScintillaCocoa(ScintillaView* sciView_, SCIContentView* viewContent, SCIMarginView* viewMargin) -{ - vs.marginInside = false; - - // Don't retain since we're owned by view, which would cause a cycle - sciView = sciView_; - wMain = (__bridge WindowID)viewContent; - wMargin = (__bridge WindowID)viewMargin; - - timerTarget = [[TimerTarget alloc] init: this]; - lastMouseEvent = NULL; - delegate = NULL; - notifyObj = NULL; - notifyProc = NULL; - capturedMouse = false; - enteredSetScrollingSize = false; - scrollSpeed = 1; - scrollTicks = 2000; - observer = NULL; - layerFindIndicator = NULL; - imeInteraction = imeInline; - for (TickReason tr=tickCaret; tr<=tickPlatform; tr = static_cast<TickReason>(tr+1)) - { - timers[tr] = nil; - } - Init(); +ScintillaCocoa::ScintillaCocoa(ScintillaView *sciView_, SCIContentView *viewContent, SCIMarginView *viewMargin) { + vs.marginInside = false; + + // Don't retain since we're owned by view, which would cause a cycle + sciView = sciView_; + wMain = (__bridge WindowID)viewContent; + wMargin = (__bridge WindowID)viewMargin; + + timerTarget = [[TimerTarget alloc] init: this]; + lastMouseEvent = NULL; + delegate = NULL; + notifyObj = NULL; + notifyProc = NULL; + capturedMouse = false; + enteredSetScrollingSize = false; + scrollSpeed = 1; + scrollTicks = 2000; + observer = NULL; + layerFindIndicator = NULL; + imeInteraction = imeInline; + for (TickReason tr=tickCaret; tr<=tickPlatform; tr = static_cast<TickReason>(tr+1)) { + timers[tr] = nil; + } + Init(); } //-------------------------------------------------------------------------------------------------- -ScintillaCocoa::~ScintillaCocoa() -{ - [timerTarget ownerDestroyed]; +ScintillaCocoa::~ScintillaCocoa() { + [timerTarget ownerDestroyed]; } //-------------------------------------------------------------------------------------------------- @@ -429,19 +417,18 @@ ScintillaCocoa::~ScintillaCocoa() /** * Core initialization of the control. Everything that needs to be set up happens here. */ -void ScintillaCocoa::Init() -{ - Scintilla_LinkLexers(); +void ScintillaCocoa::Init() { + Scintilla_LinkLexers(); - // Tell Scintilla not to buffer: Quartz buffers drawing for us. - WndProc(SCI_SETBUFFEREDDRAW, 0, 0); + // Tell Scintilla not to buffer: Quartz buffers drawing for us. + WndProc(SCI_SETBUFFEREDDRAW, 0, 0); - // We are working with Unicode exclusively. - WndProc(SCI_SETCODEPAGE, SC_CP_UTF8, 0); + // We are working with Unicode exclusively. + WndProc(SCI_SETCODEPAGE, SC_CP_UTF8, 0); - // Add Mac specific key bindings. - for (int i = 0; macMapDefault[i].key; i++) - kmap.AssignCmdKey(macMapDefault[i].key, macMapDefault[i].modifiers, macMapDefault[i].msg); + // Add Mac specific key bindings. + for (int i = 0; macMapDefault[i].key; i++) + kmap.AssignCmdKey(macMapDefault[i].key, macMapDefault[i].modifiers, macMapDefault[i].msg); } @@ -450,21 +437,19 @@ void ScintillaCocoa::Init() /** * We need some clean up. Do it here. */ -void ScintillaCocoa::Finalise() -{ - ObserverRemove(); - for (TickReason tr=tickCaret; tr<=tickPlatform; tr = static_cast<TickReason>(tr+1)) - { - FineTickerCancel(tr); - } - ScintillaBase::Finalise(); +void ScintillaCocoa::Finalise() { + ObserverRemove(); + for (TickReason tr=tickCaret; tr<=tickPlatform; tr = static_cast<TickReason>(tr+1)) { + FineTickerCancel(tr); + } + ScintillaBase::Finalise(); } //-------------------------------------------------------------------------------------------------- void ScintillaCocoa::UpdateObserver(CFRunLoopObserverRef /* observer */, CFRunLoopActivity /* activity */, void *info) { - ScintillaCocoa* sci = static_cast<ScintillaCocoa*>(info); - sci->IdleWork(); + ScintillaCocoa *sci = static_cast<ScintillaCocoa *>(info); + sci->IdleWork(); } //-------------------------------------------------------------------------------------------------- @@ -474,19 +459,19 @@ void ScintillaCocoa::UpdateObserver(CFRunLoopObserverRef /* observer */, CFRunLo */ void ScintillaCocoa::ObserverAdd() { - if (!observer) { - CFRunLoopObserverContext context; - context.version = 0; - context.info = this; - context.retain = NULL; - context.release = NULL; - context.copyDescription = NULL; - - CFRunLoopRef mainRunLoop = CFRunLoopGetMain(); - observer = CFRunLoopObserverCreate(NULL, kCFRunLoopEntry | kCFRunLoopBeforeWaiting, - true, 0, UpdateObserver, &context); - CFRunLoopAddObserver(mainRunLoop, observer, kCFRunLoopCommonModes); - } + if (!observer) { + CFRunLoopObserverContext context; + context.version = 0; + context.info = this; + context.retain = NULL; + context.release = NULL; + context.copyDescription = NULL; + + CFRunLoopRef mainRunLoop = CFRunLoopGetMain(); + observer = CFRunLoopObserverCreate(NULL, kCFRunLoopEntry | kCFRunLoopBeforeWaiting, + true, 0, UpdateObserver, &context); + CFRunLoopAddObserver(mainRunLoop, observer, kCFRunLoopCommonModes); + } } //-------------------------------------------------------------------------------------------------- @@ -495,26 +480,26 @@ void ScintillaCocoa::ObserverAdd() { * Remove the run loop observer. */ void ScintillaCocoa::ObserverRemove() { - if (observer) { - CFRunLoopRef mainRunLoop = CFRunLoopGetMain(); - CFRunLoopRemoveObserver(mainRunLoop, observer, kCFRunLoopCommonModes); - CFRelease(observer); - } - observer = NULL; + if (observer) { + CFRunLoopRef mainRunLoop = CFRunLoopGetMain(); + CFRunLoopRemoveObserver(mainRunLoop, observer, kCFRunLoopCommonModes); + CFRelease(observer); + } + observer = NULL; } //-------------------------------------------------------------------------------------------------- void ScintillaCocoa::IdleWork() { - Editor::IdleWork(); - ObserverRemove(); + Editor::IdleWork(); + ObserverRemove(); } //-------------------------------------------------------------------------------------------------- void ScintillaCocoa::QueueIdleWork(WorkNeeded::workItems items, Sci::Position upTo) { - Editor::QueueIdleWork(items, upTo); - ObserverAdd(); + Editor::QueueIdleWork(items, upTo); + ObserverAdd(); } //-------------------------------------------------------------------------------------------------- @@ -527,12 +512,12 @@ static std::string EncodedBytesString(CFStringRef cfsRef, CFStringEncoding encod const CFRange rangeAll = {0, CFStringGetLength(cfsRef)}; CFIndex usedLen = 0; CFStringGetBytes(cfsRef, rangeAll, encoding, '?', false, - NULL, 0, &usedLen); + NULL, 0, &usedLen); std::string buffer(usedLen, '\0'); if (usedLen > 0) { CFStringGetBytes(cfsRef, rangeAll, encoding, '?', false, - reinterpret_cast<UInt8 *>(&buffer[0]), usedLen, NULL); + reinterpret_cast<UInt8 *>(&buffer[0]), usedLen, NULL); } return buffer; } @@ -571,8 +556,8 @@ public: } else { CFStringRef cfsVal = CFStringFromString(mixed, lenMixed, encoding); - NSString *sMapped = [(__bridge NSString *)cfsVal stringByFoldingWithOptions:NSCaseInsensitiveSearch - locale:[NSLocale currentLocale]]; + NSString *sMapped = [(__bridge NSString *)cfsVal stringByFoldingWithOptions: NSCaseInsensitiveSearch + locale: [NSLocale currentLocale]]; std::string encoded = EncodedBytesString((__bridge CFStringRef)sMapped, encoding); @@ -594,7 +579,7 @@ CaseFolder *ScintillaCocoa::CaseFolderForEncoding() { return new CaseFolderUnicode(); } else { CFStringEncoding encoding = EncodingFromCharacterSet(IsUnicodeMode(), - vs.styles[STYLE_DEFAULT].characterSet); + vs.styles[STYLE_DEFAULT].characterSet); if (pdoc->dbcsCodePage == 0) { CaseFolderTable *pcf = new CaseFolderTable(); pcf->StandardASCII(); @@ -606,8 +591,8 @@ CaseFolder *ScintillaCocoa::CaseFolderForEncoding() { if (!cfsVal) continue; - NSString *sMapped = [(__bridge NSString *)cfsVal stringByFoldingWithOptions:NSCaseInsensitiveSearch - locale:[NSLocale currentLocale]]; + NSString *sMapped = [(__bridge NSString *)cfsVal stringByFoldingWithOptions: NSCaseInsensitiveSearch + locale: [NSLocale currentLocale]]; std::string encoded = EncodedBytesString((__bridge CFStringRef)sMapped, encoding); @@ -630,41 +615,39 @@ CaseFolder *ScintillaCocoa::CaseFolderForEncoding() { /** * Case-fold the given string depending on the specified case mapping type. */ -std::string ScintillaCocoa::CaseMapString(const std::string &s, int caseMapping) -{ - if ((s.size() == 0) || (caseMapping == cmSame)) - return s; - - if (IsUnicodeMode()) { - std::string retMapped(s.length() * maxExpansionCaseConversion, 0); - size_t lenMapped = CaseConvertString(&retMapped[0], retMapped.length(), s.c_str(), s.length(), - (caseMapping == cmUpper) ? CaseConversionUpper : CaseConversionLower); - retMapped.resize(lenMapped); - return retMapped; - } - - CFStringEncoding encoding = EncodingFromCharacterSet(IsUnicodeMode(), - vs.styles[STYLE_DEFAULT].characterSet); +std::string ScintillaCocoa::CaseMapString(const std::string &s, int caseMapping) { + if ((s.size() == 0) || (caseMapping == cmSame)) + return s; - CFStringRef cfsVal = CFStringFromString(s.c_str(), s.length(), encoding); + if (IsUnicodeMode()) { + std::string retMapped(s.length() * maxExpansionCaseConversion, 0); + size_t lenMapped = CaseConvertString(&retMapped[0], retMapped.length(), s.c_str(), s.length(), + (caseMapping == cmUpper) ? CaseConversionUpper : CaseConversionLower); + retMapped.resize(lenMapped); + return retMapped; + } - NSString *sMapped; - switch (caseMapping) - { - case cmUpper: - sMapped = ((__bridge NSString *)cfsVal).uppercaseString; - break; - case cmLower: - sMapped = ((__bridge NSString *)cfsVal).lowercaseString; - break; - default: - sMapped = (__bridge NSString *)cfsVal; - } + CFStringEncoding encoding = EncodingFromCharacterSet(IsUnicodeMode(), + vs.styles[STYLE_DEFAULT].characterSet); + + CFStringRef cfsVal = CFStringFromString(s.c_str(), s.length(), encoding); + + NSString *sMapped; + switch (caseMapping) { + case cmUpper: + sMapped = ((__bridge NSString *)cfsVal).uppercaseString; + break; + case cmLower: + sMapped = ((__bridge NSString *)cfsVal).lowercaseString; + break; + default: + sMapped = (__bridge NSString *)cfsVal; + } - // Back to encoding - std::string result = EncodedBytesString((__bridge CFStringRef)sMapped, encoding); - CFRelease(cfsVal); - return result; + // Back to encoding + std::string result = EncodedBytesString((__bridge CFStringRef)sMapped, encoding); + CFRelease(cfsVal); + return result; } //-------------------------------------------------------------------------------------------------- @@ -673,8 +656,8 @@ std::string ScintillaCocoa::CaseMapString(const std::string &s, int caseMapping) * Cancel all modes, both for base class and any find indicator. */ void ScintillaCocoa::CancelModes() { - ScintillaBase::CancelModes(); - HideFindIndicator(); + ScintillaBase::CancelModes(); + HideFindIndicator(); } //-------------------------------------------------------------------------------------------------- @@ -682,9 +665,9 @@ void ScintillaCocoa::CancelModes() { /** * Helper function to get the scrolling view. */ -NSScrollView* ScintillaCocoa::ScrollContainer() const { - NSView* container = (__bridge NSView*)(wMain.GetID()); - return static_cast<NSScrollView*>(container.superview.superview); +NSScrollView *ScintillaCocoa::ScrollContainer() const { + NSView *container = (__bridge NSView *)(wMain.GetID()); + return static_cast<NSScrollView *>(container.superview.superview); } //-------------------------------------------------------------------------------------------------- @@ -692,9 +675,8 @@ NSScrollView* ScintillaCocoa::ScrollContainer() const { /** * Helper function to get the inner container which represents the actual "canvas" we work with. */ -SCIContentView* ScintillaCocoa::ContentView() -{ - return (__bridge SCIContentView*)(wMain.GetID()); +SCIContentView *ScintillaCocoa::ContentView() { + return (__bridge SCIContentView *)(wMain.GetID()); } //-------------------------------------------------------------------------------------------------- @@ -702,11 +684,10 @@ SCIContentView* ScintillaCocoa::ContentView() /** * Return the top left visible point relative to the origin point of the whole document. */ -Scintilla::Point ScintillaCocoa::GetVisibleOriginInMain() const -{ - NSScrollView *scrollView = ScrollContainer(); - NSRect contentRect = scrollView.contentView.bounds; - return Point(static_cast<XYPOSITION>(contentRect.origin.x), static_cast<XYPOSITION>(contentRect.origin.y)); +Scintilla::Point ScintillaCocoa::GetVisibleOriginInMain() const { + NSScrollView *scrollView = ScrollContainer(); + NSRect contentRect = scrollView.contentView.bounds; + return Point(static_cast<XYPOSITION>(contentRect.origin.x), static_cast<XYPOSITION>(contentRect.origin.y)); } //-------------------------------------------------------------------------------------------------- @@ -716,13 +697,12 @@ Scintilla::Point ScintillaCocoa::GetVisibleOriginInMain() const * in order to make scrolling working properly. * The returned value is in document coordinates. */ -PRectangle ScintillaCocoa::GetClientRectangle() const -{ - NSScrollView *scrollView = ScrollContainer(); - NSSize size = scrollView.contentView.bounds.size; - Point origin = GetVisibleOriginInMain(); - return PRectangle(origin.x, origin.y, static_cast<XYPOSITION>(origin.x+size.width), - static_cast<XYPOSITION>(origin.y + size.height)); +PRectangle ScintillaCocoa::GetClientRectangle() const { + NSScrollView *scrollView = ScrollContainer(); + NSSize size = scrollView.contentView.bounds.size; + Point origin = GetVisibleOriginInMain(); + return PRectangle(origin.x, origin.y, static_cast<XYPOSITION>(origin.x+size.width), + static_cast<XYPOSITION>(origin.y + size.height)); } //-------------------------------------------------------------------------------------------------- @@ -732,14 +712,14 @@ PRectangle ScintillaCocoa::GetClientRectangle() const */ PRectangle ScintillaCocoa::GetClientDrawingRectangle() { #if MAC_OS_X_VERSION_MAX_ALLOWED > 1080 - NSView *content = ContentView(); - if ([content respondsToSelector: @selector(setPreparedContentRect:)]) { - NSRect rcPrepared = content.preparedContentRect; - if (!NSIsEmptyRect(rcPrepared)) - return NSRectToPRectangle(rcPrepared); - } + NSView *content = ContentView(); + if ([content respondsToSelector: @selector(setPreparedContentRect:)]) { + NSRect rcPrepared = content.preparedContentRect; + if (!NSIsEmptyRect(rcPrepared)) + return NSRectToPRectangle(rcPrepared); + } #endif - return ScintillaCocoa::GetClientRectangle(); + return ScintillaCocoa::GetClientRectangle(); } //-------------------------------------------------------------------------------------------------- @@ -749,12 +729,11 @@ PRectangle ScintillaCocoa::GetClientDrawingRectangle() { * a native Point structure. Base coordinates are used for the top window used in the view hierarchy. * Returned value is in view coordinates. */ -Scintilla::Point ScintillaCocoa::ConvertPoint(NSPoint point) -{ - NSView* container = ContentView(); - NSPoint result = [container convertPoint: point fromView: nil]; - Scintilla::Point ptOrigin = GetVisibleOriginInMain(); - return Point(static_cast<XYPOSITION>(result.x - ptOrigin.x), static_cast<XYPOSITION>(result.y - ptOrigin.y)); +Scintilla::Point ScintillaCocoa::ConvertPoint(NSPoint point) { + NSView *container = ContentView(); + NSPoint result = [container convertPoint: point fromView: nil]; + Scintilla::Point ptOrigin = GetVisibleOriginInMain(); + return Point(static_cast<XYPOSITION>(result.x - ptOrigin.x), static_cast<XYPOSITION>(result.y - ptOrigin.y)); } //-------------------------------------------------------------------------------------------------- @@ -762,22 +741,20 @@ Scintilla::Point ScintillaCocoa::ConvertPoint(NSPoint point) /** * Do not clip like superclass as Cocoa is not reporting all of prepared area. */ -void ScintillaCocoa::RedrawRect(PRectangle rc) -{ - if (!rc.Empty()) - wMain.InvalidateRectangle(rc); +void ScintillaCocoa::RedrawRect(PRectangle rc) { + if (!rc.Empty()) + wMain.InvalidateRectangle(rc); } //-------------------------------------------------------------------------------------------------- -void ScintillaCocoa::DiscardOverdraw() -{ +void ScintillaCocoa::DiscardOverdraw() { #if MAC_OS_X_VERSION_MAX_ALLOWED > 1080 - // If running on 10.9, reset prepared area to visible area - NSView *content = ContentView(); - if ([content respondsToSelector: @selector(setPreparedContentRect:)]) { - content.preparedContentRect = content.visibleRect; - } + // If running on 10.9, reset prepared area to visible area + NSView *content = ContentView(); + if ([content respondsToSelector: @selector(setPreparedContentRect:)]) { + content.preparedContentRect = content.visibleRect; + } #endif } @@ -786,11 +763,10 @@ void ScintillaCocoa::DiscardOverdraw() /** * Ensure all of prepared content is also redrawn. */ -void ScintillaCocoa::Redraw() -{ - wMargin.InvalidateAll(); - DiscardOverdraw(); - wMain.InvalidateAll(); +void ScintillaCocoa::Redraw() { + wMargin.InvalidateAll(); + DiscardOverdraw(); + wMain.InvalidateAll(); } //-------------------------------------------------------------------------------------------------- @@ -807,9 +783,8 @@ void ScintillaCocoa::Redraw() * @param lParam The other of the two free parameters. A signed long. */ sptr_t ScintillaCocoa::DirectFunction(sptr_t ptr, unsigned int iMessage, uptr_t wParam, - sptr_t lParam) -{ - return reinterpret_cast<ScintillaCocoa *>(ptr)->WndProc(iMessage, wParam, lParam); + sptr_t lParam) { + return reinterpret_cast<ScintillaCocoa *>(ptr)->WndProc(iMessage, wParam, lParam); } //-------------------------------------------------------------------------------------------------- @@ -818,10 +793,9 @@ sptr_t ScintillaCocoa::DirectFunction(sptr_t ptr, unsigned int iMessage, uptr_t * This method is very similar to DirectFunction. On Windows it sends a message (not in the Obj-C sense) * to the target window. Here we simply call our fake window proc. */ -sptr_t scintilla_send_message(void* sci, unsigned int iMessage, uptr_t wParam, sptr_t lParam) -{ - ScintillaView *control = (__bridge ScintillaView*)(sci); - return [control message:iMessage wParam:wParam lParam:lParam]; +sptr_t scintilla_send_message(void *sci, unsigned int iMessage, uptr_t wParam, sptr_t lParam) { + ScintillaView *control = (__bridge ScintillaView *)(sci); + return [control message: iMessage wParam: wParam lParam: lParam]; } //-------------------------------------------------------------------------------------------------- @@ -834,69 +808,67 @@ sptr_t scintilla_send_message(void* sci, unsigned int iMessage, uptr_t wParam, s * would be system messages on Windows (e.g. for key down, mouse move etc.) are handled by * directly calling appropriate handlers. */ -sptr_t ScintillaCocoa::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) -{ - try { - switch (iMessage) - { - case SCI_GETDIRECTFUNCTION: - return reinterpret_cast<sptr_t>(DirectFunction); +sptr_t ScintillaCocoa::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { + try { + switch (iMessage) { + case SCI_GETDIRECTFUNCTION: + return reinterpret_cast<sptr_t>(DirectFunction); - case SCI_GETDIRECTPOINTER: - return reinterpret_cast<sptr_t>(this); + case SCI_GETDIRECTPOINTER: + return reinterpret_cast<sptr_t>(this); - case SCI_TARGETASUTF8: - return TargetAsUTF8(reinterpret_cast<char*>(lParam)); + case SCI_TARGETASUTF8: + return TargetAsUTF8(reinterpret_cast<char *>(lParam)); - case SCI_ENCODEDFROMUTF8: - return EncodedFromUTF8(reinterpret_cast<char*>(wParam), - reinterpret_cast<char*>(lParam)); + case SCI_ENCODEDFROMUTF8: + return EncodedFromUTF8(reinterpret_cast<char *>(wParam), + reinterpret_cast<char *>(lParam)); - case SCI_SETIMEINTERACTION: - // Only inline IME supported on Cocoa - break; + case SCI_SETIMEINTERACTION: + // Only inline IME supported on Cocoa + break; - case SCI_GRABFOCUS: - [ContentView().window makeFirstResponder:ContentView()]; - break; + case SCI_GRABFOCUS: + [ContentView().window makeFirstResponder: ContentView()]; + break; - case SCI_SETBUFFEREDDRAW: - // Buffered drawing not supported on Cocoa - view.bufferedDraw = false; - break; + case SCI_SETBUFFEREDDRAW: + // Buffered drawing not supported on Cocoa + view.bufferedDraw = false; + break; - case SCI_FINDINDICATORSHOW: - ShowFindIndicatorForRange(NSMakeRange(wParam, lParam-wParam), YES); - return 0; + case SCI_FINDINDICATORSHOW: + ShowFindIndicatorForRange(NSMakeRange(wParam, lParam-wParam), YES); + return 0; - case SCI_FINDINDICATORFLASH: - ShowFindIndicatorForRange(NSMakeRange(wParam, lParam-wParam), NO); - return 0; + case SCI_FINDINDICATORFLASH: + ShowFindIndicatorForRange(NSMakeRange(wParam, lParam-wParam), NO); + return 0; - case SCI_FINDINDICATORHIDE: - HideFindIndicator(); - return 0; + case SCI_FINDINDICATORHIDE: + HideFindIndicator(); + return 0; - case SCI_SETPHASESDRAW: { - sptr_t r = ScintillaBase::WndProc(iMessage, wParam, lParam); - [sciView updateIndicatorIME]; - return r; - } + case SCI_SETPHASESDRAW: { + sptr_t r = ScintillaBase::WndProc(iMessage, wParam, lParam); + [sciView updateIndicatorIME]; + return r; + } - case SCI_GETACCESSIBILITY: - return SC_ACCESSIBILITY_ENABLED; + case SCI_GETACCESSIBILITY: + return SC_ACCESSIBILITY_ENABLED; - default: - sptr_t r = ScintillaBase::WndProc(iMessage, wParam, lParam); + default: + sptr_t r = ScintillaBase::WndProc(iMessage, wParam, lParam); - return r; - } - } catch (std::bad_alloc &) { - errorStatus = SC_STATUS_BADALLOC; - } catch (...) { - errorStatus = SC_STATUS_FAILURE; - } - return 0l; + return r; + } + } catch (std::bad_alloc &) { + errorStatus = SC_STATUS_BADALLOC; + } catch (...) { + errorStatus = SC_STATUS_FAILURE; + } + return 0l; } //-------------------------------------------------------------------------------------------------- @@ -905,9 +877,8 @@ sptr_t ScintillaCocoa::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lPar * In Windows lingo this is the handler which handles anything that wasn't handled in the normal * window proc which would usually send the message back to generic window proc that Windows uses. */ -sptr_t ScintillaCocoa::DefWndProc(unsigned int, uptr_t, sptr_t) -{ - return 0; +sptr_t ScintillaCocoa::DefWndProc(unsigned int, uptr_t, sptr_t) { + return 0; } //-------------------------------------------------------------------------------------------------- @@ -915,16 +886,12 @@ sptr_t ScintillaCocoa::DefWndProc(unsigned int, uptr_t, sptr_t) /** * Handle any ScintillaCocoa-specific ticking or call superclass. */ -void ScintillaCocoa::TickFor(TickReason reason) -{ - if (reason == tickPlatform) - { - DragScroll(); - } - else - { - Editor::TickFor(reason); - } +void ScintillaCocoa::TickFor(TickReason reason) { + if (reason == tickPlatform) { + DragScroll(); + } else { + Editor::TickFor(reason); + } } //-------------------------------------------------------------------------------------------------- @@ -932,9 +899,8 @@ void ScintillaCocoa::TickFor(TickReason reason) /** * Report that this Editor subclass has a working implementation of FineTickerStart. */ -bool ScintillaCocoa::FineTickerAvailable() -{ - return true; +bool ScintillaCocoa::FineTickerAvailable() { + return true; } //-------------------------------------------------------------------------------------------------- @@ -942,9 +908,8 @@ bool ScintillaCocoa::FineTickerAvailable() /** * Is a particular timer currently running? */ -bool ScintillaCocoa::FineTickerRunning(TickReason reason) -{ - return timers[reason] != nil; +bool ScintillaCocoa::FineTickerRunning(TickReason reason) { + return timers[reason] != nil; } //-------------------------------------------------------------------------------------------------- @@ -952,21 +917,19 @@ bool ScintillaCocoa::FineTickerRunning(TickReason reason) /** * Start a fine-grained timer. */ -void ScintillaCocoa::FineTickerStart(TickReason reason, int millis, int tolerance) -{ - FineTickerCancel(reason); - NSTimer *fineTimer = [NSTimer timerWithTimeInterval: millis / 1000.0 - target: timerTarget - selector: @selector(timerFired:) - userInfo: nil - repeats: YES]; - if (tolerance && [fineTimer respondsToSelector: @selector(setTolerance:)]) - { - fineTimer.tolerance = tolerance / 1000.0; - } - timers[reason] = fineTimer; - [NSRunLoop.currentRunLoop addTimer: fineTimer forMode: NSDefaultRunLoopMode]; - [NSRunLoop.currentRunLoop addTimer: fineTimer forMode: NSModalPanelRunLoopMode]; +void ScintillaCocoa::FineTickerStart(TickReason reason, int millis, int tolerance) { + FineTickerCancel(reason); + NSTimer *fineTimer = [NSTimer timerWithTimeInterval: millis / 1000.0 + target: timerTarget + selector: @selector(timerFired:) + userInfo: nil + repeats: YES]; + if (tolerance && [fineTimer respondsToSelector: @selector(setTolerance:)]) { + fineTimer.tolerance = tolerance / 1000.0; + } + timers[reason] = fineTimer; + [NSRunLoop.currentRunLoop addTimer: fineTimer forMode: NSDefaultRunLoopMode]; + [NSRunLoop.currentRunLoop addTimer: fineTimer forMode: NSModalPanelRunLoopMode]; } //-------------------------------------------------------------------------------------------------- @@ -974,77 +937,64 @@ void ScintillaCocoa::FineTickerStart(TickReason reason, int millis, int toleranc /** * Cancel a fine-grained timer. */ -void ScintillaCocoa::FineTickerCancel(TickReason reason) -{ - if (timers[reason]) - { - [timers[reason] invalidate]; - timers[reason] = nil; - } +void ScintillaCocoa::FineTickerCancel(TickReason reason) { + if (timers[reason]) { + [timers[reason] invalidate]; + timers[reason] = nil; + } } //-------------------------------------------------------------------------------------------------- -bool ScintillaCocoa::SetIdle(bool on) -{ - if (idler.state != on) - { - idler.state = on; - if (idler.state) - { - // Scintilla ticks = milliseconds - NSTimer *idleTimer = [NSTimer scheduledTimerWithTimeInterval: timer.tickSize / 1000.0 - target: timerTarget - selector: @selector(idleTimerFired:) - userInfo: nil - repeats: YES]; - [NSRunLoop.currentRunLoop addTimer: idleTimer forMode: NSModalPanelRunLoopMode]; - idler.idlerID = (__bridge IdlerID)idleTimer; - } - else - if (idler.idlerID != NULL) - { - [(__bridge NSTimer*)(idler.idlerID) invalidate]; - idler.idlerID = 0; - } - } - return true; +bool ScintillaCocoa::SetIdle(bool on) { + if (idler.state != on) { + idler.state = on; + if (idler.state) { + // Scintilla ticks = milliseconds + NSTimer *idleTimer = [NSTimer scheduledTimerWithTimeInterval: timer.tickSize / 1000.0 + target: timerTarget + selector: @selector(idleTimerFired:) + userInfo: nil + repeats: YES]; + [NSRunLoop.currentRunLoop addTimer: idleTimer forMode: NSModalPanelRunLoopMode]; + idler.idlerID = (__bridge IdlerID)idleTimer; + } else if (idler.idlerID != NULL) { + [(__bridge NSTimer *)(idler.idlerID) invalidate]; + idler.idlerID = 0; + } + } + return true; } //-------------------------------------------------------------------------------------------------- -void ScintillaCocoa::CopyToClipboard(const SelectionText &selectedText) -{ - SetPasteboardData([NSPasteboard generalPasteboard], selectedText); +void ScintillaCocoa::CopyToClipboard(const SelectionText &selectedText) { + SetPasteboardData([NSPasteboard generalPasteboard], selectedText); } //-------------------------------------------------------------------------------------------------- -void ScintillaCocoa::Copy() -{ - if (!sel.Empty()) - { - SelectionText selectedText; - CopySelectionRange(&selectedText); - CopyToClipboard(selectedText); - } +void ScintillaCocoa::Copy() { + if (!sel.Empty()) { + SelectionText selectedText; + CopySelectionRange(&selectedText); + CopyToClipboard(selectedText); + } } //-------------------------------------------------------------------------------------------------- -bool ScintillaCocoa::CanPaste() -{ - if (!Editor::CanPaste()) - return false; +bool ScintillaCocoa::CanPaste() { + if (!Editor::CanPaste()) + return false; - return GetPasteboardData([NSPasteboard generalPasteboard], NULL); + return GetPasteboardData([NSPasteboard generalPasteboard], NULL); } //-------------------------------------------------------------------------------------------------- -void ScintillaCocoa::Paste() -{ - Paste(false); +void ScintillaCocoa::Paste() { + Paste(false); } //-------------------------------------------------------------------------------------------------- @@ -1052,52 +1002,51 @@ void ScintillaCocoa::Paste() /** * Pastes data from the paste board into the editor. */ -void ScintillaCocoa::Paste(bool forceRectangular) -{ - SelectionText selectedText; - bool ok = GetPasteboardData([NSPasteboard generalPasteboard], &selectedText); - if (forceRectangular) - selectedText.rectangular = forceRectangular; +void ScintillaCocoa::Paste(bool forceRectangular) { + SelectionText selectedText; + bool ok = GetPasteboardData([NSPasteboard generalPasteboard], &selectedText); + if (forceRectangular) + selectedText.rectangular = forceRectangular; - if (!ok || selectedText.Empty()) - // No data or no flavor we support. - return; + if (!ok || selectedText.Empty()) + // No data or no flavor we support. + return; - pdoc->BeginUndoAction(); - ClearSelection(false); - InsertPasteShape(selectedText.Data(), static_cast<int>(selectedText.Length()), - selectedText.rectangular ? pasteRectangular : pasteStream); - pdoc->EndUndoAction(); + pdoc->BeginUndoAction(); + ClearSelection(false); + InsertPasteShape(selectedText.Data(), static_cast<int>(selectedText.Length()), + selectedText.rectangular ? pasteRectangular : pasteStream); + pdoc->EndUndoAction(); - Redraw(); - EnsureCaretVisible(); + Redraw(); + EnsureCaretVisible(); } //-------------------------------------------------------------------------------------------------- -void ScintillaCocoa::CTPaint(void* gc, NSRect rc) { +void ScintillaCocoa::CTPaint(void *gc, NSRect rc) { #pragma unused(rc) - std::unique_ptr<Surface> surfaceWindow(Surface::Allocate(SC_TECHNOLOGY_DEFAULT)); - surfaceWindow->Init(gc, wMain.GetID()); - surfaceWindow->SetUnicodeMode(SC_CP_UTF8 == ct.codePage); - surfaceWindow->SetDBCSMode(ct.codePage); - ct.PaintCT(surfaceWindow.get()); - surfaceWindow->Release(); + std::unique_ptr<Surface> surfaceWindow(Surface::Allocate(SC_TECHNOLOGY_DEFAULT)); + surfaceWindow->Init(gc, wMain.GetID()); + surfaceWindow->SetUnicodeMode(SC_CP_UTF8 == ct.codePage); + surfaceWindow->SetDBCSMode(ct.codePage); + ct.PaintCT(surfaceWindow.get()); + surfaceWindow->Release(); } @interface CallTipView : NSControl { - ScintillaCocoa *sci; + ScintillaCocoa *sci; } @end @implementation CallTipView -- (NSView*) initWithFrame: (NSRect) frame { +- (NSView *) initWithFrame: (NSRect) frame { self = [super initWithFrame: frame]; if (self) { - sci = NULL; + sci = NULL; } return self; @@ -1109,37 +1058,37 @@ void ScintillaCocoa::CTPaint(void* gc, NSRect rc) { } - (void) setSci: (ScintillaCocoa *) sci_ { - sci = sci_; + sci = sci_; } - (void) drawRect: (NSRect) needsDisplayInRect { - if (sci) { - CGContextRef context = (CGContextRef) [NSGraphicsContext currentContext].graphicsPort; - sci->CTPaint(context, needsDisplayInRect); - } + if (sci) { + CGContextRef context = (CGContextRef) [NSGraphicsContext currentContext].graphicsPort; + sci->CTPaint(context, needsDisplayInRect); + } } - (void) mouseDown: (NSEvent *) event { - if (sci) { - sci->CallTipMouseDown(event.locationInWindow); - } + if (sci) { + sci->CallTipMouseDown(event.locationInWindow); + } } // On OS X, only the key view should modify the cursor so the calltip can't. // This view does not become key so resetCursorRects never called. - (void) resetCursorRects { - //[super resetCursorRects]; - //[self addCursorRect: [self bounds] cursor: [NSCursor arrowCursor]]; + //[super resetCursorRects]; + //[self addCursorRect: [self bounds] cursor: [NSCursor arrowCursor]]; } @end void ScintillaCocoa::CallTipMouseDown(NSPoint pt) { - NSRect rectBounds = ((__bridge NSView *)(ct.wDraw.GetID())).bounds; - Point location(static_cast<XYPOSITION>(pt.x), - static_cast<XYPOSITION>(rectBounds.size.height - pt.y)); - ct.MouseClick(location); - CallTipClick(); + NSRect rectBounds = ((__bridge NSView *)(ct.wDraw.GetID())).bounds; + Point location(static_cast<XYPOSITION>(pt.x), + static_cast<XYPOSITION>(rectBounds.size.height - pt.y)); + ct.MouseClick(location); + CallTipClick(); } static bool HeightDifferent(WindowID wCallTip, PRectangle rc) { @@ -1149,54 +1098,52 @@ static bool HeightDifferent(WindowID wCallTip, PRectangle rc) { } void ScintillaCocoa::CreateCallTipWindow(PRectangle rc) { - if (ct.wCallTip.Created() && HeightDifferent(ct.wCallTip.GetID(), rc)) { - ct.wCallTip.Destroy(); - } - if (!ct.wCallTip.Created()) { - NSRect ctRect = NSMakeRect(rc.top,rc.bottom, rc.Width(), rc.Height()); - NSWindow *callTip = [[NSWindow alloc] initWithContentRect: ctRect - styleMask: NSBorderlessWindowMask - backing: NSBackingStoreBuffered - defer: NO]; - [callTip setLevel:NSFloatingWindowLevel]; - [callTip setHasShadow:YES]; - NSRect ctContent = NSMakeRect(0,0, rc.Width(), rc.Height()); - CallTipView *caption = [[CallTipView alloc] initWithFrame: ctContent]; - caption.autoresizingMask = NSViewWidthSizable | NSViewMaxYMargin; - [caption setSci: this]; - [callTip.contentView addSubview: caption]; - [callTip orderFront:caption]; - ct.wCallTip = (__bridge_retained WindowID)callTip; - ct.wDraw = (__bridge WindowID)caption; - } -} - -void ScintillaCocoa::AddToPopUp(const char *label, int cmd, bool enabled) -{ - NSMenuItem* item; - ScintillaContextMenu *menu = (__bridge ScintillaContextMenu*)(popup.GetID()); - [menu setOwner: this]; - [menu setAutoenablesItems: NO]; - - if (cmd == 0) { - item = [NSMenuItem separatorItem]; - } else { - item = [[NSMenuItem alloc] init]; - item.title = @(label); - } - item.target = menu; - item.action = @selector(handleCommand:); - item.tag = cmd; - item.enabled = enabled; - - [menu addItem: item]; + if (ct.wCallTip.Created() && HeightDifferent(ct.wCallTip.GetID(), rc)) { + ct.wCallTip.Destroy(); + } + if (!ct.wCallTip.Created()) { + NSRect ctRect = NSMakeRect(rc.top, rc.bottom, rc.Width(), rc.Height()); + NSWindow *callTip = [[NSWindow alloc] initWithContentRect: ctRect + styleMask: NSBorderlessWindowMask + backing: NSBackingStoreBuffered + defer: NO]; + [callTip setLevel: NSFloatingWindowLevel]; + [callTip setHasShadow: YES]; + NSRect ctContent = NSMakeRect(0, 0, rc.Width(), rc.Height()); + CallTipView *caption = [[CallTipView alloc] initWithFrame: ctContent]; + caption.autoresizingMask = NSViewWidthSizable | NSViewMaxYMargin; + [caption setSci: this]; + [callTip.contentView addSubview: caption]; + [callTip orderFront: caption]; + ct.wCallTip = (__bridge_retained WindowID)callTip; + ct.wDraw = (__bridge WindowID)caption; + } +} + +void ScintillaCocoa::AddToPopUp(const char *label, int cmd, bool enabled) { + NSMenuItem *item; + ScintillaContextMenu *menu = (__bridge ScintillaContextMenu *)(popup.GetID()); + [menu setOwner: this]; + [menu setAutoenablesItems: NO]; + + if (cmd == 0) { + item = [NSMenuItem separatorItem]; + } else { + item = [[NSMenuItem alloc] init]; + item.title = @(label); + } + item.target = menu; + item.action = @selector(handleCommand:); + item.tag = cmd; + item.enabled = enabled; + + [menu addItem: item]; } // ------------------------------------------------------------------------------------------------- -void ScintillaCocoa::ClaimSelection() -{ - // Mac OS X does not have a primary selection. +void ScintillaCocoa::ClaimSelection() { + // Mac OS X does not have a primary selection. } // ------------------------------------------------------------------------------------------------- @@ -1205,14 +1152,13 @@ void ScintillaCocoa::ClaimSelection() * Returns the current caret position (which is tracked as an offset into the entire text string) * as a row:column pair. The result is zero-based. */ -NSPoint ScintillaCocoa::GetCaretPosition() -{ - const Sci::Line line = pdoc->LineFromPosition(sel.RangeMain().caret.Position()); - NSPoint result; +NSPoint ScintillaCocoa::GetCaretPosition() { + const Sci::Line line = pdoc->LineFromPosition(sel.RangeMain().caret.Position()); + NSPoint result; - result.y = line; - result.x = sel.RangeMain().caret.Position() - pdoc->LineStart(line); - return result; + result.y = line; + result.x = sel.RangeMain().caret.Position() - pdoc->LineStart(line); + return result; } // ------------------------------------------------------------------------------------------------- @@ -1222,96 +1168,84 @@ NSPoint ScintillaCocoa::GetCaretPosition() /** * Triggered by the tick timer on a regular basis to scroll the content during a drag operation. */ -void ScintillaCocoa::DragScroll() -{ - if (!posDrag.IsValid()) - { - scrollSpeed = 1; - scrollTicks = 2000; - return; - } - - // TODO: does not work for wrapped lines, fix it. - Sci::Line line = pdoc->LineFromPosition(posDrag.Position()); - Sci::Line currentVisibleLine = cs.DisplayFromDoc(line); - Sci::Line lastVisibleLine = std::min(topLine + LinesOnScreen(), cs.LinesDisplayed()) - 2; - - if (currentVisibleLine <= topLine && topLine > 0) - ScrollTo(topLine - scrollSpeed); - else - if (currentVisibleLine >= lastVisibleLine) - ScrollTo(topLine + scrollSpeed); - else - { - scrollSpeed = 1; - scrollTicks = 2000; - return; - } - - // TODO: also handle horizontal scrolling. - - if (scrollSpeed == 1) - { - scrollTicks -= timer.tickSize; - if (scrollTicks <= 0) - { - scrollSpeed = 5; - scrollTicks = 2000; - } - } +void ScintillaCocoa::DragScroll() { + if (!posDrag.IsValid()) { + scrollSpeed = 1; + scrollTicks = 2000; + return; + } + + // TODO: does not work for wrapped lines, fix it. + Sci::Line line = pdoc->LineFromPosition(posDrag.Position()); + Sci::Line currentVisibleLine = cs.DisplayFromDoc(line); + Sci::Line lastVisibleLine = std::min(topLine + LinesOnScreen(), cs.LinesDisplayed()) - 2; + + if (currentVisibleLine <= topLine && topLine > 0) + ScrollTo(topLine - scrollSpeed); + else if (currentVisibleLine >= lastVisibleLine) + ScrollTo(topLine + scrollSpeed); + else { + scrollSpeed = 1; + scrollTicks = 2000; + return; + } + + // TODO: also handle horizontal scrolling. + + if (scrollSpeed == 1) { + scrollTicks -= timer.tickSize; + if (scrollTicks <= 0) { + scrollSpeed = 5; + scrollTicks = 2000; + } + } } //----------------- DragProviderSource ------------------------------------------------------- -@interface DragProviderSource : NSObject <NSPasteboardItemDataProvider> -{ - SelectionText selectedText; +@interface DragProviderSource : NSObject <NSPasteboardItemDataProvider> { + SelectionText selectedText; } @end @implementation DragProviderSource -- (id)initWithSelectedText:(const SelectionText *)other -{ - self = [super init]; +- (id) initWithSelectedText: (const SelectionText *) other { + self = [super init]; - if (self) { - selectedText.Copy(*other); - } + if (self) { + selectedText.Copy(*other); + } - return self; + return self; } -- (void)pasteboard:(NSPasteboard *)pasteboard item:(NSPasteboardItem *)item provideDataForType:(NSString *)type -{ +- (void) pasteboard: (NSPasteboard *) pasteboard item: (NSPasteboardItem *) item provideDataForType: (NSString *) type { #pragma unused(item) - if (selectedText.Length() == 0) - return; + if (selectedText.Length() == 0) + return; - if (([type compare: NSPasteboardTypeString] != NSOrderedSame) && - ([type compare: ScintillaRecPboardType] != NSOrderedSame)) - return; + if (([type compare: NSPasteboardTypeString] != NSOrderedSame) && + ([type compare: ScintillaRecPboardType] != NSOrderedSame)) + return; - CFStringEncoding encoding = EncodingFromCharacterSet(selectedText.codePage == SC_CP_UTF8, - selectedText.characterSet); + CFStringEncoding encoding = EncodingFromCharacterSet(selectedText.codePage == SC_CP_UTF8, + selectedText.characterSet); - CFStringRef cfsVal = CFStringFromString(selectedText.Data(), selectedText.Length(), encoding); + CFStringRef cfsVal = CFStringFromString(selectedText.Data(), selectedText.Length(), encoding); - if ([type compare: NSPasteboardTypeString] == NSOrderedSame) - { - [pasteboard setString:(__bridge NSString *)cfsVal forType: NSStringPboardType]; - } - else if ([type compare: ScintillaRecPboardType] == NSOrderedSame) - { - // This is specific to scintilla, allows us to drag rectangular selections around the document. - if (selectedText.rectangular) - [pasteboard setString:(__bridge NSString *)cfsVal forType: ScintillaRecPboardType]; - } + if ([type compare: NSPasteboardTypeString] == NSOrderedSame) { + [pasteboard setString: (__bridge NSString *)cfsVal forType: NSStringPboardType]; + } else if ([type compare: ScintillaRecPboardType] == NSOrderedSame) { + // This is specific to scintilla, allows us to drag rectangular selections around the document. + if (selectedText.rectangular) + [pasteboard setString: (__bridge NSString *)cfsVal forType: ScintillaRecPboardType]; + } - if (cfsVal) - CFRelease(cfsVal); + if (cfsVal) + CFRelease(cfsVal); } @end @@ -1321,164 +1255,163 @@ void ScintillaCocoa::DragScroll() /** * Called when a drag operation was initiated from within Scintilla. */ -void ScintillaCocoa::StartDrag() -{ - if (sel.Empty()) - return; - - inDragDrop = ddDragging; - - FineTickerStart(tickPlatform, timer.tickSize, 0); - - // Put the data to be dragged on the drag pasteboard. - SelectionText selectedText; - NSPasteboard* pasteboard = [NSPasteboard pasteboardWithName: NSDragPboard]; - CopySelectionRange(&selectedText); - SetPasteboardData(pasteboard, selectedText); - - // calculate the bounds of the selection - PRectangle client = GetTextRectangle(); - Sci::Position selStart = sel.RangeMain().Start().Position(); - Sci::Position selEnd = sel.RangeMain().End().Position(); - Sci::Line startLine = pdoc->LineFromPosition(selStart); - Sci::Line endLine = pdoc->LineFromPosition(selEnd); - Point pt; - long startPos, endPos, ep; - PRectangle rcSel; - - if (startLine==endLine && WndProc(SCI_GETWRAPMODE, 0, 0) != SC_WRAP_NONE) { - // Komodo bug http://bugs.activestate.com/show_bug.cgi?id=87571 - // Scintilla bug https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3040200&group_id=2439 - // If the width on a wrapped-line selection is negative, - // find a better bounding rectangle. - - Point ptStart, ptEnd; - startPos = WndProc(SCI_GETLINESELSTARTPOSITION, startLine, 0); - endPos = WndProc(SCI_GETLINESELENDPOSITION, startLine, 0); - // step back a position if we're counting the newline - ep = WndProc(SCI_GETLINEENDPOSITION, startLine, 0); - if (endPos > ep) endPos = ep; - ptStart = LocationFromPosition(static_cast<int>(startPos)); - ptEnd = LocationFromPosition(static_cast<int>(endPos)); - if (ptStart.y == ptEnd.y) { - // We're just selecting part of one visible line - rcSel.left = ptStart.x; - rcSel.right = ptEnd.x < client.right ? ptEnd.x : client.right; - } else { - // Find the bounding box. - startPos = WndProc(SCI_POSITIONFROMLINE, startLine, 0); - rcSel.left = LocationFromPosition(static_cast<int>(startPos)).x; - rcSel.right = client.right; - } - rcSel.top = ptStart.y; - rcSel.bottom = ptEnd.y + vs.lineHeight; - if (rcSel.bottom > client.bottom) { - rcSel.bottom = client.bottom; - } - } else { - rcSel.top = rcSel.bottom = rcSel.right = rcSel.left = -1; - for (int l = startLine; l <= endLine; l++) { - startPos = WndProc(SCI_GETLINESELSTARTPOSITION, l, 0); - endPos = WndProc(SCI_GETLINESELENDPOSITION, l, 0); - if (endPos == startPos) continue; - // step back a position if we're counting the newline - ep = WndProc(SCI_GETLINEENDPOSITION, l, 0); - if (endPos > ep) endPos = ep; - pt = LocationFromPosition(static_cast<int>(startPos)); // top left of line selection - if (pt.x < rcSel.left || rcSel.left < 0) rcSel.left = pt.x; - if (pt.y < rcSel.top || rcSel.top < 0) rcSel.top = pt.y; - pt = LocationFromPosition(static_cast<int>(endPos)); // top right of line selection - pt.y += vs.lineHeight; // get to the bottom of the line - if (pt.x > rcSel.right || rcSel.right < 0) { - if (pt.x > client.right) - rcSel.right = client.right; - else - rcSel.right = pt.x; - } - if (pt.y > rcSel.bottom || rcSel.bottom < 0) { - if (pt.y > client.bottom) - rcSel.bottom = client.bottom; - else - rcSel.bottom = pt.y; - } - } - } - // must convert to global coordinates for drag regions, but also save the - // image rectangle for further calculations and copy operations - - // Prepare drag image. - NSRect selectionRectangle = PRectangleToNSRect(rcSel); - - SCIContentView* content = ContentView(); - - // To get a bitmap of the text we're dragging, we just use Paint on a pixmap surface. - SurfaceImpl sw; - sw.InitPixMap(static_cast<int>(client.Width()), static_cast<int>(client.Height()), NULL, NULL); - - const bool lastHideSelection = view.hideSelection; - view.hideSelection = true; - PRectangle imageRect = rcSel; - paintState = painting; - paintingAllText = true; - CGContextRef gcsw = sw.GetContext(); - CGContextTranslateCTM(gcsw, -client.left, -client.top); - Paint(&sw, client); - paintState = notPainting; - view.hideSelection = lastHideSelection; - - SurfaceImpl pixmap; - pixmap.InitPixMap(static_cast<int>(imageRect.Width()), static_cast<int>(imageRect.Height()), NULL, NULL); - pixmap.SetUnicodeMode(IsUnicodeMode()); - pixmap.SetDBCSMode(CodePage()); - - CGContextRef gc = pixmap.GetContext(); - // To make Paint() work on a bitmap, we have to flip our coordinates and translate the origin - CGContextTranslateCTM(gc, 0, imageRect.Height()); - CGContextScaleCTM(gc, 1.0, -1.0); - - pixmap.CopyImageRectangle(sw, imageRect, PRectangle(0.0f, 0.0f, imageRect.Width(), imageRect.Height())); - // XXX TODO: overwrite any part of the image that is not part of the - // selection to make it transparent. right now we just use - // the full rectangle which may include non-selected text. - - NSBitmapImageRep* bitmap = NULL; - CGImageRef imagePixmap = pixmap.GetImage(); - if (imagePixmap) - bitmap = [[NSBitmapImageRep alloc] initWithCGImage: imagePixmap]; - CGImageRelease(imagePixmap); - - NSImage* image = [[NSImage alloc] initWithSize: selectionRectangle.size]; - [image addRepresentation: bitmap]; - - NSImage* dragImage = [[NSImage alloc] initWithSize: selectionRectangle.size]; - dragImage.backgroundColor = [NSColor clearColor]; - [dragImage lockFocus]; - [image drawAtPoint: NSZeroPoint fromRect: NSZeroRect operation: NSCompositeSourceOver fraction: 0.5]; - [dragImage unlockFocus]; - - NSPoint startPoint; - startPoint.x = selectionRectangle.origin.x + client.left; - startPoint.y = selectionRectangle.origin.y + selectionRectangle.size.height + client.top; - - NSPasteboardItem *pbItem = [NSPasteboardItem new]; - DragProviderSource *dps = [[DragProviderSource alloc] initWithSelectedText:&selectedText]; - - NSArray *pbTypes = selectedText.rectangular ? - @[NSPasteboardTypeString, ScintillaRecPboardType] : - @[NSPasteboardTypeString]; - [pbItem setDataProvider:dps forTypes:pbTypes]; - NSDraggingItem *dragItem = [[NSDraggingItem alloc ]initWithPasteboardWriter:pbItem]; - - NSScrollView *scrollContainer = ScrollContainer(); - NSRect contentRect = scrollContainer.contentView.bounds; - NSRect draggingRect = NSOffsetRect(selectionRectangle, contentRect.origin.x, contentRect.origin.y); - [dragItem setDraggingFrame:draggingRect contents:dragImage]; - NSDraggingSession *dragSession = - [content beginDraggingSessionWithItems:@[dragItem] - event:lastMouseEvent - source:content]; - dragSession.animatesToStartingPositionsOnCancelOrFail = YES; - dragSession.draggingFormation = NSDraggingFormationNone; +void ScintillaCocoa::StartDrag() { + if (sel.Empty()) + return; + + inDragDrop = ddDragging; + + FineTickerStart(tickPlatform, timer.tickSize, 0); + + // Put the data to be dragged on the drag pasteboard. + SelectionText selectedText; + NSPasteboard *pasteboard = [NSPasteboard pasteboardWithName: NSDragPboard]; + CopySelectionRange(&selectedText); + SetPasteboardData(pasteboard, selectedText); + + // calculate the bounds of the selection + PRectangle client = GetTextRectangle(); + Sci::Position selStart = sel.RangeMain().Start().Position(); + Sci::Position selEnd = sel.RangeMain().End().Position(); + Sci::Line startLine = pdoc->LineFromPosition(selStart); + Sci::Line endLine = pdoc->LineFromPosition(selEnd); + Point pt; + long startPos, endPos, ep; + PRectangle rcSel; + + if (startLine==endLine && WndProc(SCI_GETWRAPMODE, 0, 0) != SC_WRAP_NONE) { + // Komodo bug http://bugs.activestate.com/show_bug.cgi?id=87571 + // Scintilla bug https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3040200&group_id=2439 + // If the width on a wrapped-line selection is negative, + // find a better bounding rectangle. + + Point ptStart, ptEnd; + startPos = WndProc(SCI_GETLINESELSTARTPOSITION, startLine, 0); + endPos = WndProc(SCI_GETLINESELENDPOSITION, startLine, 0); + // step back a position if we're counting the newline + ep = WndProc(SCI_GETLINEENDPOSITION, startLine, 0); + if (endPos > ep) endPos = ep; + ptStart = LocationFromPosition(static_cast<int>(startPos)); + ptEnd = LocationFromPosition(static_cast<int>(endPos)); + if (ptStart.y == ptEnd.y) { + // We're just selecting part of one visible line + rcSel.left = ptStart.x; + rcSel.right = ptEnd.x < client.right ? ptEnd.x : client.right; + } else { + // Find the bounding box. + startPos = WndProc(SCI_POSITIONFROMLINE, startLine, 0); + rcSel.left = LocationFromPosition(static_cast<int>(startPos)).x; + rcSel.right = client.right; + } + rcSel.top = ptStart.y; + rcSel.bottom = ptEnd.y + vs.lineHeight; + if (rcSel.bottom > client.bottom) { + rcSel.bottom = client.bottom; + } + } else { + rcSel.top = rcSel.bottom = rcSel.right = rcSel.left = -1; + for (int l = startLine; l <= endLine; l++) { + startPos = WndProc(SCI_GETLINESELSTARTPOSITION, l, 0); + endPos = WndProc(SCI_GETLINESELENDPOSITION, l, 0); + if (endPos == startPos) continue; + // step back a position if we're counting the newline + ep = WndProc(SCI_GETLINEENDPOSITION, l, 0); + if (endPos > ep) endPos = ep; + pt = LocationFromPosition(static_cast<int>(startPos)); // top left of line selection + if (pt.x < rcSel.left || rcSel.left < 0) rcSel.left = pt.x; + if (pt.y < rcSel.top || rcSel.top < 0) rcSel.top = pt.y; + pt = LocationFromPosition(static_cast<int>(endPos)); // top right of line selection + pt.y += vs.lineHeight; // get to the bottom of the line + if (pt.x > rcSel.right || rcSel.right < 0) { + if (pt.x > client.right) + rcSel.right = client.right; + else + rcSel.right = pt.x; + } + if (pt.y > rcSel.bottom || rcSel.bottom < 0) { + if (pt.y > client.bottom) + rcSel.bottom = client.bottom; + else + rcSel.bottom = pt.y; + } + } + } + // must convert to global coordinates for drag regions, but also save the + // image rectangle for further calculations and copy operations + + // Prepare drag image. + NSRect selectionRectangle = PRectangleToNSRect(rcSel); + + SCIContentView *content = ContentView(); + + // To get a bitmap of the text we're dragging, we just use Paint on a pixmap surface. + SurfaceImpl sw; + sw.InitPixMap(static_cast<int>(client.Width()), static_cast<int>(client.Height()), NULL, NULL); + + const bool lastHideSelection = view.hideSelection; + view.hideSelection = true; + PRectangle imageRect = rcSel; + paintState = painting; + paintingAllText = true; + CGContextRef gcsw = sw.GetContext(); + CGContextTranslateCTM(gcsw, -client.left, -client.top); + Paint(&sw, client); + paintState = notPainting; + view.hideSelection = lastHideSelection; + + SurfaceImpl pixmap; + pixmap.InitPixMap(static_cast<int>(imageRect.Width()), static_cast<int>(imageRect.Height()), NULL, NULL); + pixmap.SetUnicodeMode(IsUnicodeMode()); + pixmap.SetDBCSMode(CodePage()); + + CGContextRef gc = pixmap.GetContext(); + // To make Paint() work on a bitmap, we have to flip our coordinates and translate the origin + CGContextTranslateCTM(gc, 0, imageRect.Height()); + CGContextScaleCTM(gc, 1.0, -1.0); + + pixmap.CopyImageRectangle(sw, imageRect, PRectangle(0.0f, 0.0f, imageRect.Width(), imageRect.Height())); + // XXX TODO: overwrite any part of the image that is not part of the + // selection to make it transparent. right now we just use + // the full rectangle which may include non-selected text. + + NSBitmapImageRep *bitmap = NULL; + CGImageRef imagePixmap = pixmap.GetImage(); + if (imagePixmap) + bitmap = [[NSBitmapImageRep alloc] initWithCGImage: imagePixmap]; + CGImageRelease(imagePixmap); + + NSImage *image = [[NSImage alloc] initWithSize: selectionRectangle.size]; + [image addRepresentation: bitmap]; + + NSImage *dragImage = [[NSImage alloc] initWithSize: selectionRectangle.size]; + dragImage.backgroundColor = [NSColor clearColor]; + [dragImage lockFocus]; + [image drawAtPoint: NSZeroPoint fromRect: NSZeroRect operation: NSCompositeSourceOver fraction: 0.5]; + [dragImage unlockFocus]; + + NSPoint startPoint; + startPoint.x = selectionRectangle.origin.x + client.left; + startPoint.y = selectionRectangle.origin.y + selectionRectangle.size.height + client.top; + + NSPasteboardItem *pbItem = [NSPasteboardItem new]; + DragProviderSource *dps = [[DragProviderSource alloc] initWithSelectedText: &selectedText]; + + NSArray *pbTypes = selectedText.rectangular ? + @[NSPasteboardTypeString, ScintillaRecPboardType] : + @[NSPasteboardTypeString]; + [pbItem setDataProvider: dps forTypes: pbTypes]; + NSDraggingItem *dragItem = [[NSDraggingItem alloc ]initWithPasteboardWriter: pbItem]; + + NSScrollView *scrollContainer = ScrollContainer(); + NSRect contentRect = scrollContainer.contentView.bounds; + NSRect draggingRect = NSOffsetRect(selectionRectangle, contentRect.origin.x, contentRect.origin.y); + [dragItem setDraggingFrame: draggingRect contents: dragImage]; + NSDraggingSession *dragSession = + [content beginDraggingSessionWithItems: @[dragItem] + event: lastMouseEvent + source: content]; + dragSession.animatesToStartingPositionsOnCancelOrFail = YES; + dragSession.draggingFormation = NSDraggingFormationNone; } //-------------------------------------------------------------------------------------------------- @@ -1486,10 +1419,9 @@ void ScintillaCocoa::StartDrag() /** * Called when a drag operation reaches the control which was initiated outside. */ -NSDragOperation ScintillaCocoa::DraggingEntered(id <NSDraggingInfo> info) -{ - FineTickerStart(tickPlatform, timer.tickSize, 0); - return DraggingUpdated(info); +NSDragOperation ScintillaCocoa::DraggingEntered(id <NSDraggingInfo> info) { + FineTickerStart(tickPlatform, timer.tickSize, 0); + return DraggingUpdated(info); } //-------------------------------------------------------------------------------------------------- @@ -1499,27 +1431,26 @@ NSDragOperation ScintillaCocoa::DraggingEntered(id <NSDraggingInfo> info) * what drag operation we accept and update the drop caret position to indicate the * potential insertion point of the dragged data. */ -NSDragOperation ScintillaCocoa::DraggingUpdated(id <NSDraggingInfo> info) -{ - // Convert the drag location from window coordinates to view coordinates and - // from there to a text position to finally set the drag position. - Point location = ConvertPoint([info draggingLocation]); - SetDragPosition(SPositionFromLocation(location)); +NSDragOperation ScintillaCocoa::DraggingUpdated(id <NSDraggingInfo> info) { + // Convert the drag location from window coordinates to view coordinates and + // from there to a text position to finally set the drag position. + Point location = ConvertPoint([info draggingLocation]); + SetDragPosition(SPositionFromLocation(location)); - NSDragOperation sourceDragMask = [info draggingSourceOperationMask]; - if (sourceDragMask == NSDragOperationNone) - return sourceDragMask; + NSDragOperation sourceDragMask = [info draggingSourceOperationMask]; + if (sourceDragMask == NSDragOperationNone) + return sourceDragMask; - NSPasteboard* pasteboard = [info draggingPasteboard]; + NSPasteboard *pasteboard = [info draggingPasteboard]; - // Return what type of operation we will perform. Prefer move over copy. - if ([pasteboard.types containsObject: NSStringPboardType] || - [pasteboard.types containsObject: ScintillaRecPboardType]) - return (sourceDragMask & NSDragOperationMove) ? NSDragOperationMove : NSDragOperationCopy; + // Return what type of operation we will perform. Prefer move over copy. + if ([pasteboard.types containsObject: NSStringPboardType] || + [pasteboard.types containsObject: ScintillaRecPboardType]) + return (sourceDragMask & NSDragOperationMove) ? NSDragOperationMove : NSDragOperationCopy; - if ([pasteboard.types containsObject: NSFilenamesPboardType]) - return (sourceDragMask & NSDragOperationGeneric); - return NSDragOperationNone; + if ([pasteboard.types containsObject: NSFilenamesPboardType]) + return (sourceDragMask & NSDragOperationGeneric); + return NSDragOperationNone; } //-------------------------------------------------------------------------------------------------- @@ -1527,12 +1458,11 @@ NSDragOperation ScintillaCocoa::DraggingUpdated(id <NSDraggingInfo> info) /** * Resets the current drag position as we are no longer the drag target. */ -void ScintillaCocoa::DraggingExited(id <NSDraggingInfo> info) -{ +void ScintillaCocoa::DraggingExited(id <NSDraggingInfo> info) { #pragma unused(info) - SetDragPosition(SelectionPosition(Sci::invalidPosition)); - FineTickerCancel(tickPlatform); - inDragDrop = ddNone; + SetDragPosition(SelectionPosition(Sci::invalidPosition)); + FineTickerCancel(tickPlatform); + inDragDrop = ddNone; } //-------------------------------------------------------------------------------------------------- @@ -1540,60 +1470,53 @@ void ScintillaCocoa::DraggingExited(id <NSDraggingInfo> info) /** * Here is where the real work is done. Insert the text from the pasteboard. */ -bool ScintillaCocoa::PerformDragOperation(id <NSDraggingInfo> info) -{ - NSPasteboard* pasteboard = [info draggingPasteboard]; +bool ScintillaCocoa::PerformDragOperation(id <NSDraggingInfo> info) { + NSPasteboard *pasteboard = [info draggingPasteboard]; - if ([pasteboard.types containsObject: NSFilenamesPboardType]) - { - NSArray* files = [pasteboard propertyListForType: NSFilenamesPboardType]; - for (NSString* uri in files) - NotifyURIDropped(uri.UTF8String); - } - else - { - SelectionText text; - GetPasteboardData(pasteboard, &text); + if ([pasteboard.types containsObject: NSFilenamesPboardType]) { + NSArray *files = [pasteboard propertyListForType: NSFilenamesPboardType]; + for (NSString* uri in files) + NotifyURIDropped(uri.UTF8String); + } else { + SelectionText text; + GetPasteboardData(pasteboard, &text); - if (text.Length() > 0) - { - NSDragOperation operation = [info draggingSourceOperationMask]; - bool moving = (operation & NSDragOperationMove) != 0; + if (text.Length() > 0) { + NSDragOperation operation = [info draggingSourceOperationMask]; + bool moving = (operation & NSDragOperationMove) != 0; - DropAt(posDrag, text.Data(), text.Length(), moving, text.rectangular); - }; - } + DropAt(posDrag, text.Data(), text.Length(), moving, text.rectangular); + }; + } - return true; + return true; } //-------------------------------------------------------------------------------------------------- -void ScintillaCocoa::SetPasteboardData(NSPasteboard* board, const SelectionText &selectedText) -{ - if (selectedText.Length() == 0) - return; +void ScintillaCocoa::SetPasteboardData(NSPasteboard *board, const SelectionText &selectedText) { + if (selectedText.Length() == 0) + return; - CFStringEncoding encoding = EncodingFromCharacterSet(selectedText.codePage == SC_CP_UTF8, - selectedText.characterSet); + CFStringEncoding encoding = EncodingFromCharacterSet(selectedText.codePage == SC_CP_UTF8, + selectedText.characterSet); - CFStringRef cfsVal = CFStringFromString(selectedText.Data(), selectedText.Length(), encoding); + CFStringRef cfsVal = CFStringFromString(selectedText.Data(), selectedText.Length(), encoding); - NSArray *pbTypes = selectedText.rectangular ? - @[NSStringPboardType, ScintillaRecPboardType] : - @[NSStringPboardType]; - [board declareTypes:pbTypes owner:nil]; + NSArray *pbTypes = selectedText.rectangular ? + @[NSStringPboardType, ScintillaRecPboardType] : + @[NSStringPboardType]; + [board declareTypes: pbTypes owner: nil]; - if (selectedText.rectangular) - { - // This is specific to scintilla, allows us to drag rectangular selections around the document. - [board setString: (__bridge NSString *)cfsVal forType: ScintillaRecPboardType]; - } + if (selectedText.rectangular) { + // This is specific to scintilla, allows us to drag rectangular selections around the document. + [board setString: (__bridge NSString *)cfsVal forType: ScintillaRecPboardType]; + } - [board setString: (__bridge NSString *)cfsVal forType: NSStringPboardType]; + [board setString: (__bridge NSString *)cfsVal forType: NSStringPboardType]; - if (cfsVal) - CFRelease(cfsVal); + if (cfsVal) + CFRelease(cfsVal); } //-------------------------------------------------------------------------------------------------- @@ -1601,190 +1524,174 @@ void ScintillaCocoa::SetPasteboardData(NSPasteboard* board, const SelectionText /** * Helper method to retrieve the best fitting alternative from the general pasteboard. */ -bool ScintillaCocoa::GetPasteboardData(NSPasteboard* board, SelectionText* selectedText) -{ - NSArray* supportedTypes = @[ScintillaRecPboardType, - NSStringPboardType]; - NSString *bestType = [board availableTypeFromArray: supportedTypes]; - NSString* data = [board stringForType: bestType]; +bool ScintillaCocoa::GetPasteboardData(NSPasteboard *board, SelectionText *selectedText) { + NSArray *supportedTypes = @[ScintillaRecPboardType, + NSStringPboardType]; + NSString *bestType = [board availableTypeFromArray: supportedTypes]; + NSString *data = [board stringForType: bestType]; - if (data != nil) - { - if (selectedText != nil) - { - CFStringEncoding encoding = EncodingFromCharacterSet(IsUnicodeMode(), - vs.styles[STYLE_DEFAULT].characterSet); - CFRange rangeAll = {0, static_cast<CFIndex>(data.length)}; - CFIndex usedLen = 0; - CFStringGetBytes((CFStringRef)data, rangeAll, encoding, '?', - false, NULL, 0, &usedLen); + if (data != nil) { + if (selectedText != nil) { + CFStringEncoding encoding = EncodingFromCharacterSet(IsUnicodeMode(), + vs.styles[STYLE_DEFAULT].characterSet); + CFRange rangeAll = {0, static_cast<CFIndex>(data.length)}; + CFIndex usedLen = 0; + CFStringGetBytes((CFStringRef)data, rangeAll, encoding, '?', + false, NULL, 0, &usedLen); - std::vector<UInt8> buffer(usedLen); + std::vector<UInt8> buffer(usedLen); - CFStringGetBytes((CFStringRef)data, rangeAll, encoding, '?', - false, buffer.data(),usedLen, NULL); + CFStringGetBytes((CFStringRef)data, rangeAll, encoding, '?', + false, buffer.data(), usedLen, NULL); - bool rectangular = bestType == ScintillaRecPboardType; + bool rectangular = bestType == ScintillaRecPboardType; - std::string dest(reinterpret_cast<const char *>(buffer.data()), usedLen); + std::string dest(reinterpret_cast<const char *>(buffer.data()), usedLen); - selectedText->Copy(dest, pdoc->dbcsCodePage, - vs.styles[STYLE_DEFAULT].characterSet , rectangular, false); - } - return true; - } + selectedText->Copy(dest, pdoc->dbcsCodePage, + vs.styles[STYLE_DEFAULT].characterSet, rectangular, false); + } + return true; + } - return false; + return false; } //-------------------------------------------------------------------------------------------------- // Returns the target converted to UTF8. // Return the length in bytes. -int ScintillaCocoa::TargetAsUTF8(char *text) -{ - const int targetLength = targetEnd - targetStart; - if (IsUnicodeMode()) - { - if (text) - pdoc->GetCharRange(text, targetStart, targetLength); - } - else - { - // Need to convert - const CFStringEncoding encoding = EncodingFromCharacterSet(IsUnicodeMode(), - vs.styles[STYLE_DEFAULT].characterSet); - const std::string s = RangeText(targetStart, targetEnd); - CFStringRef cfsVal = CFStringFromString(s.c_str(), s.length(), encoding); - - const std::string tmputf = EncodedBytesString(cfsVal, kCFStringEncodingUTF8); - - if (text) - memcpy(text, tmputf.c_str(), tmputf.length()); - CFRelease(cfsVal); - return static_cast<int>(tmputf.length()); - } - return targetLength; +int ScintillaCocoa::TargetAsUTF8(char *text) { + const int targetLength = targetEnd - targetStart; + if (IsUnicodeMode()) { + if (text) + pdoc->GetCharRange(text, targetStart, targetLength); + } else { + // Need to convert + const CFStringEncoding encoding = EncodingFromCharacterSet(IsUnicodeMode(), + vs.styles[STYLE_DEFAULT].characterSet); + const std::string s = RangeText(targetStart, targetEnd); + CFStringRef cfsVal = CFStringFromString(s.c_str(), s.length(), encoding); + + const std::string tmputf = EncodedBytesString(cfsVal, kCFStringEncodingUTF8); + + if (text) + memcpy(text, tmputf.c_str(), tmputf.length()); + CFRelease(cfsVal); + return static_cast<int>(tmputf.length()); + } + return targetLength; } //-------------------------------------------------------------------------------------------------- // Returns the text in the range converted to an NSString. NSString *ScintillaCocoa::RangeTextAsString(NSRange rangePositions) const { - const std::string text = RangeText(static_cast<int>(rangePositions.location), - static_cast<int>(NSMaxRange(rangePositions))); - if (IsUnicodeMode()) - { - return @(text.c_str()); - } - else - { - // Need to convert - const CFStringEncoding encoding = EncodingFromCharacterSet(IsUnicodeMode(), - vs.styles[STYLE_DEFAULT].characterSet); - CFStringRef cfsVal = CFStringFromString(text.c_str(), text.length(), encoding); + const std::string text = RangeText(static_cast<int>(rangePositions.location), + static_cast<int>(NSMaxRange(rangePositions))); + if (IsUnicodeMode()) { + return @(text.c_str()); + } else { + // Need to convert + const CFStringEncoding encoding = EncodingFromCharacterSet(IsUnicodeMode(), + vs.styles[STYLE_DEFAULT].characterSet); + CFStringRef cfsVal = CFStringFromString(text.c_str(), text.length(), encoding); - return (__bridge NSString *)cfsVal; - } + return (__bridge NSString *)cfsVal; + } } //-------------------------------------------------------------------------------------------------- // Return character range of a line. NSRange ScintillaCocoa::RangeForVisibleLine(NSInteger lineVisible) { - const Range posRangeLine = RangeDisplayLine(static_cast<int>(lineVisible)); - return CharactersFromPositions(NSMakeRange(posRangeLine.First(), - posRangeLine.Last() - posRangeLine.First())); + const Range posRangeLine = RangeDisplayLine(static_cast<int>(lineVisible)); + return CharactersFromPositions(NSMakeRange(posRangeLine.First(), + posRangeLine.Last() - posRangeLine.First())); } //-------------------------------------------------------------------------------------------------- // Returns visible line number of a text position in characters. NSInteger ScintillaCocoa::VisibleLineForIndex(NSInteger index) { - const NSRange rangePosition = PositionsFromCharacters(NSMakeRange(index, 0)); - const int lineVisible = DisplayFromPosition(static_cast<int>(rangePosition.location)); - return lineVisible; + const NSRange rangePosition = PositionsFromCharacters(NSMakeRange(index, 0)); + const int lineVisible = DisplayFromPosition(static_cast<int>(rangePosition.location)); + return lineVisible; } //-------------------------------------------------------------------------------------------------- // Returns a rectangle that frames the range for use by the VoiceOver cursor. NSRect ScintillaCocoa::FrameForRange(NSRange rangeCharacters) { - const NSRange posRange = PositionsFromCharacters(rangeCharacters); + const NSRange posRange = PositionsFromCharacters(rangeCharacters); - NSUInteger rangeEnd = NSMaxRange(posRange); - const bool endsWithLineEnd = rangeCharacters.length && - (pdoc->GetColumn(static_cast<int>(rangeEnd)) == 0); + NSUInteger rangeEnd = NSMaxRange(posRange); + const bool endsWithLineEnd = rangeCharacters.length && + (pdoc->GetColumn(static_cast<int>(rangeEnd)) == 0); - Point ptStart = LocationFromPosition(static_cast<int>(posRange.location)); - const PointEnd peEndRange = static_cast<PointEnd>(peSubLineEnd|peLineEnd); - Point ptEnd = LocationFromPosition(static_cast<int>(rangeEnd), peEndRange); + Point ptStart = LocationFromPosition(static_cast<int>(posRange.location)); + const PointEnd peEndRange = static_cast<PointEnd>(peSubLineEnd|peLineEnd); + Point ptEnd = LocationFromPosition(static_cast<int>(rangeEnd), peEndRange); - NSRect rect = NSMakeRect(ptStart.x, ptStart.y, - ptEnd.x - ptStart.x, - ptEnd.y - ptStart.y); + NSRect rect = NSMakeRect(ptStart.x, ptStart.y, + ptEnd.x - ptStart.x, + ptEnd.y - ptStart.y); - rect.size.width += 2; // Shows the last character better - if (endsWithLineEnd) { - // Add a block to the right to indicate a line end is selected - rect.size.width += 20; - } + rect.size.width += 2; // Shows the last character better + if (endsWithLineEnd) { + // Add a block to the right to indicate a line end is selected + rect.size.width += 20; + } - rect.size.height += vs.lineHeight; + rect.size.height += vs.lineHeight; - // Adjust for margin and scroll - rect.origin.x = rect.origin.x - vs.textStart + vs.fixedColumnWidth; + // Adjust for margin and scroll + rect.origin.x = rect.origin.x - vs.textStart + vs.fixedColumnWidth; - return rect; + return rect; } //-------------------------------------------------------------------------------------------------- // Returns a rectangle that frames the range for use by the VoiceOver cursor. NSRect ScintillaCocoa::GetBounds() const { - return PRectangleToNSRect(GetClientRectangle()); + return PRectangleToNSRect(GetClientRectangle()); } //-------------------------------------------------------------------------------------------------- // Translates a UTF8 string into the document encoding. // Return the length of the result in bytes. -int ScintillaCocoa::EncodedFromUTF8(char *utf8, char *encoded) const -{ - const int inputLength = (lengthForEncode >= 0) ? lengthForEncode : static_cast<int>(strlen(utf8)); - if (IsUnicodeMode()) - { - if (encoded) - memcpy(encoded, utf8, inputLength); - return inputLength; - } - else - { - // Need to convert - const CFStringEncoding encoding = EncodingFromCharacterSet(IsUnicodeMode(), - vs.styles[STYLE_DEFAULT].characterSet); - - CFStringRef cfsVal = CFStringFromString(utf8, inputLength, encoding); - const std::string sEncoded = EncodedBytesString(cfsVal, encoding); - if (encoded) - memcpy(encoded, sEncoded.c_str(), sEncoded.length()); - CFRelease(cfsVal); - return static_cast<int>(sEncoded.length()); - } +int ScintillaCocoa::EncodedFromUTF8(char *utf8, char *encoded) const { + const int inputLength = (lengthForEncode >= 0) ? lengthForEncode : static_cast<int>(strlen(utf8)); + if (IsUnicodeMode()) { + if (encoded) + memcpy(encoded, utf8, inputLength); + return inputLength; + } else { + // Need to convert + const CFStringEncoding encoding = EncodingFromCharacterSet(IsUnicodeMode(), + vs.styles[STYLE_DEFAULT].characterSet); + + CFStringRef cfsVal = CFStringFromString(utf8, inputLength, encoding); + const std::string sEncoded = EncodedBytesString(cfsVal, encoding); + if (encoded) + memcpy(encoded, sEncoded.c_str(), sEncoded.length()); + CFRelease(cfsVal); + return static_cast<int>(sEncoded.length()); + } } //-------------------------------------------------------------------------------------------------- -void ScintillaCocoa::SetMouseCapture(bool on) -{ - capturedMouse = on; +void ScintillaCocoa::SetMouseCapture(bool on) { + capturedMouse = on; } //-------------------------------------------------------------------------------------------------- -bool ScintillaCocoa::HaveMouseCapture() -{ - return capturedMouse; +bool ScintillaCocoa::HaveMouseCapture() { + return capturedMouse; } //-------------------------------------------------------------------------------------------------- @@ -1792,31 +1699,29 @@ bool ScintillaCocoa::HaveMouseCapture() /** * Synchronously paint a rectangle of the window. */ -bool ScintillaCocoa::SyncPaint(void* gc, PRectangle rc) -{ - paintState = painting; - rcPaint = rc; - PRectangle rcText = GetTextRectangle(); - paintingAllText = rcPaint.Contains(rcText); - std::unique_ptr<Surface> sw(Surface::Allocate(SC_TECHNOLOGY_DEFAULT)); - CGContextSetAllowsAntialiasing((CGContextRef)gc, - vs.extraFontFlag != SC_EFF_QUALITY_NON_ANTIALIASED); - CGContextSetAllowsFontSmoothing((CGContextRef)gc, - vs.extraFontFlag == SC_EFF_QUALITY_LCD_OPTIMIZED); - CGContextSetAllowsFontSubpixelPositioning((CGContextRef)gc, - vs.extraFontFlag == SC_EFF_QUALITY_DEFAULT || - vs.extraFontFlag == SC_EFF_QUALITY_LCD_OPTIMIZED); - sw->Init(gc, wMain.GetID()); - Paint(sw.get(), rc); - const bool succeeded = paintState != paintAbandoned; - sw->Release(); - paintState = notPainting; - if (!succeeded) - { - NSView *marginView = (__bridge NSView*)(wMargin.GetID()); - [marginView setNeedsDisplay:YES]; - } - return succeeded; +bool ScintillaCocoa::SyncPaint(void *gc, PRectangle rc) { + paintState = painting; + rcPaint = rc; + PRectangle rcText = GetTextRectangle(); + paintingAllText = rcPaint.Contains(rcText); + std::unique_ptr<Surface> sw(Surface::Allocate(SC_TECHNOLOGY_DEFAULT)); + CGContextSetAllowsAntialiasing((CGContextRef)gc, + vs.extraFontFlag != SC_EFF_QUALITY_NON_ANTIALIASED); + CGContextSetAllowsFontSmoothing((CGContextRef)gc, + vs.extraFontFlag == SC_EFF_QUALITY_LCD_OPTIMIZED); + CGContextSetAllowsFontSubpixelPositioning((CGContextRef)gc, + vs.extraFontFlag == SC_EFF_QUALITY_DEFAULT || + vs.extraFontFlag == SC_EFF_QUALITY_LCD_OPTIMIZED); + sw->Init(gc, wMain.GetID()); + Paint(sw.get(), rc); + const bool succeeded = paintState != paintAbandoned; + sw->Release(); + paintState = notPainting; + if (!succeeded) { + NSView *marginView = (__bridge NSView *)(wMargin.GetID()); + [marginView setNeedsDisplay: YES]; + } + return succeeded; } //-------------------------------------------------------------------------------------------------- @@ -1824,26 +1729,24 @@ bool ScintillaCocoa::SyncPaint(void* gc, PRectangle rc) /** * Paint the margin into the SCIMarginView space. */ -void ScintillaCocoa::PaintMargin(NSRect aRect) -{ - CGContextRef gc = (CGContextRef) [NSGraphicsContext currentContext].graphicsPort; - - PRectangle rc = NSRectToPRectangle(aRect); - rcPaint = rc; - std::unique_ptr<Surface> sw(Surface::Allocate(SC_TECHNOLOGY_DEFAULT)); - if (sw) - { - CGContextSetAllowsAntialiasing(gc, - vs.extraFontFlag != SC_EFF_QUALITY_NON_ANTIALIASED); - CGContextSetAllowsFontSmoothing(gc, - vs.extraFontFlag == SC_EFF_QUALITY_LCD_OPTIMIZED); - CGContextSetAllowsFontSubpixelPositioning(gc, - vs.extraFontFlag == SC_EFF_QUALITY_DEFAULT || - vs.extraFontFlag == SC_EFF_QUALITY_LCD_OPTIMIZED); - sw->Init(gc, wMargin.GetID()); - PaintSelMargin(sw.get(), rc); - sw->Release(); - } +void ScintillaCocoa::PaintMargin(NSRect aRect) { + CGContextRef gc = (CGContextRef) [NSGraphicsContext currentContext].graphicsPort; + + PRectangle rc = NSRectToPRectangle(aRect); + rcPaint = rc; + std::unique_ptr<Surface> sw(Surface::Allocate(SC_TECHNOLOGY_DEFAULT)); + if (sw) { + CGContextSetAllowsAntialiasing(gc, + vs.extraFontFlag != SC_EFF_QUALITY_NON_ANTIALIASED); + CGContextSetAllowsFontSmoothing(gc, + vs.extraFontFlag == SC_EFF_QUALITY_LCD_OPTIMIZED); + CGContextSetAllowsFontSubpixelPositioning(gc, + vs.extraFontFlag == SC_EFF_QUALITY_DEFAULT || + vs.extraFontFlag == SC_EFF_QUALITY_LCD_OPTIMIZED); + sw->Init(gc, wMargin.GetID()); + PaintSelMargin(sw.get(), rc); + sw->Release(); + } } //-------------------------------------------------------------------------------------------------- @@ -1853,22 +1756,21 @@ void ScintillaCocoa::PaintMargin(NSRect aRect) * * @param rect The area that will be drawn, given in the sender's coordinate system. */ -void ScintillaCocoa::WillDraw(NSRect rect) -{ - RefreshStyleData(); - PRectangle rcWillDraw = NSRectToPRectangle(rect); - const int posAfterArea = PositionAfterArea(rcWillDraw); - const int posAfterMax = PositionAfterMaxStyling(posAfterArea, true); - pdoc->StyleToAdjustingLineDuration(posAfterMax); - StartIdleStyling(posAfterMax < posAfterArea); - NotifyUpdateUI(); - if (WrapLines(WrapScope::wsVisible)) { - // Wrap may have reduced number of lines so more lines may need to be styled - const int posAfterAreaWrapped = PositionAfterArea(rcWillDraw); - pdoc->EnsureStyledTo(posAfterAreaWrapped); - // The wrapping process has changed the height of some lines so redraw all. - Redraw(); - } +void ScintillaCocoa::WillDraw(NSRect rect) { + RefreshStyleData(); + PRectangle rcWillDraw = NSRectToPRectangle(rect); + const int posAfterArea = PositionAfterArea(rcWillDraw); + const int posAfterMax = PositionAfterMaxStyling(posAfterArea, true); + pdoc->StyleToAdjustingLineDuration(posAfterMax); + StartIdleStyling(posAfterMax < posAfterArea); + NotifyUpdateUI(); + if (WrapLines(WrapScope::wsVisible)) { + // Wrap may have reduced number of lines so more lines may need to be styled + const int posAfterAreaWrapped = PositionAfterArea(rcWillDraw); + pdoc->EnsureStyledTo(posAfterAreaWrapped); + // The wrapping process has changed the height of some lines so redraw all. + Redraw(); + } } //-------------------------------------------------------------------------------------------------- @@ -1876,8 +1778,7 @@ void ScintillaCocoa::WillDraw(NSRect rect) /** * ScrollText is empty because scrolling is handled by the NSScrollView. */ -void ScintillaCocoa::ScrollText(Sci::Line) -{ +void ScintillaCocoa::ScrollText(Sci::Line) { } //-------------------------------------------------------------------------------------------------- @@ -1885,15 +1786,14 @@ void ScintillaCocoa::ScrollText(Sci::Line) /** * Modifies the vertical scroll position to make the current top line show up as such. */ -void ScintillaCocoa::SetVerticalScrollPos() -{ - NSScrollView *scrollView = ScrollContainer(); - if (scrollView) { - NSClipView *clipView = scrollView.contentView; - NSRect contentRect = clipView.bounds; - [clipView scrollToPoint: NSMakePoint(contentRect.origin.x, topLine * vs.lineHeight)]; - [scrollView reflectScrolledClipView:clipView]; - } +void ScintillaCocoa::SetVerticalScrollPos() { + NSScrollView *scrollView = ScrollContainer(); + if (scrollView) { + NSClipView *clipView = scrollView.contentView; + NSRect contentRect = clipView.bounds; + [clipView scrollToPoint: NSMakePoint(contentRect.origin.x, topLine * vs.lineHeight)]; + [scrollView reflectScrolledClipView: clipView]; + } } //-------------------------------------------------------------------------------------------------- @@ -1901,23 +1801,22 @@ void ScintillaCocoa::SetVerticalScrollPos() /** * Modifies the horizontal scroll position to match xOffset. */ -void ScintillaCocoa::SetHorizontalScrollPos() -{ - PRectangle textRect = GetTextRectangle(); - - int maxXOffset = scrollWidth - static_cast<int>(textRect.Width()); - if (maxXOffset < 0) - maxXOffset = 0; - if (xOffset > maxXOffset) - xOffset = maxXOffset; - NSScrollView *scrollView = ScrollContainer(); - if (scrollView) { - NSClipView * clipView = scrollView.contentView; - NSRect contentRect = clipView.bounds; - [clipView scrollToPoint: NSMakePoint(xOffset, contentRect.origin.y)]; - [scrollView reflectScrolledClipView:clipView]; - } - MoveFindIndicatorWithBounce(NO); +void ScintillaCocoa::SetHorizontalScrollPos() { + PRectangle textRect = GetTextRectangle(); + + int maxXOffset = scrollWidth - static_cast<int>(textRect.Width()); + if (maxXOffset < 0) + maxXOffset = 0; + if (xOffset > maxXOffset) + xOffset = maxXOffset; + NSScrollView *scrollView = ScrollContainer(); + if (scrollView) { + NSClipView *clipView = scrollView.contentView; + NSRect contentRect = clipView.bounds; + [clipView scrollToPoint: NSMakePoint(xOffset, contentRect.origin.y)]; + [scrollView reflectScrolledClipView: clipView]; + } + MoveFindIndicatorWithBounce(NO); } //-------------------------------------------------------------------------------------------------- @@ -1930,10 +1829,9 @@ void ScintillaCocoa::SetHorizontalScrollPos() * @param nPage Number of lines per scroll page. * @return True if there was a change, otherwise false. */ -bool ScintillaCocoa::ModifyScrollBars(Sci::Line nMax, Sci::Line nPage) -{ +bool ScintillaCocoa::ModifyScrollBars(Sci::Line nMax, Sci::Line nPage) { #pragma unused(nMax, nPage) - return SetScrollingSize(); + return SetScrollingSize(); } bool ScintillaCocoa::SetScrollingSize(void) { @@ -1955,13 +1853,13 @@ bool ScintillaCocoa::SetScrollingSize(void) { docHeight = clipRect.size.height; CGFloat docWidth = scrollWidth; bool showHorizontalScroll = horizontalScrollBarVisible && - !Wrapping(); + !Wrapping(); if (!showHorizontalScroll) docWidth = clipRect.size.width; NSRect contentRect = {{0, 0}, {docWidth, docHeight}}; NSRect contentRectNow = inner.frame; changes = (contentRect.size.width != contentRectNow.size.width) || - (contentRect.size.height != contentRectNow.size.height); + (contentRect.size.height != contentRectNow.size.height); if (changes) { inner.frame = contentRect; } @@ -1976,10 +1874,9 @@ bool ScintillaCocoa::SetScrollingSize(void) { //-------------------------------------------------------------------------------------------------- -void ScintillaCocoa::Resize() -{ - SetScrollingSize(); - ChangeSize(); +void ScintillaCocoa::Resize() { + SetScrollingSize(); + ChangeSize(); } //-------------------------------------------------------------------------------------------------- @@ -1988,10 +1885,10 @@ void ScintillaCocoa::Resize() * Update fields to match scroll position after receiving a notification that the user has scrolled. */ void ScintillaCocoa::UpdateForScroll() { - Point ptOrigin = GetVisibleOriginInMain(); - xOffset = static_cast<int>(ptOrigin.x); - int newTop = Platform::Minimum(static_cast<int>(ptOrigin.y / vs.lineHeight), MaxScrollPos()); - SetTopLine(newTop); + Point ptOrigin = GetVisibleOriginInMain(); + xOffset = static_cast<int>(ptOrigin.x); + int newTop = Platform::Minimum(static_cast<int>(ptOrigin.y / vs.lineHeight), MaxScrollPos()); + SetTopLine(newTop); } //-------------------------------------------------------------------------------------------------- @@ -2004,9 +1901,8 @@ void ScintillaCocoa::UpdateForScroll() { * @param delegate_ A pointer to an object that implements ScintillaNotificationProtocol. */ -void ScintillaCocoa::SetDelegate(id<ScintillaNotificationProtocol> delegate_) -{ - delegate = delegate_; +void ScintillaCocoa::SetDelegate(id<ScintillaNotificationProtocol> delegate_) { + delegate = delegate_; } //-------------------------------------------------------------------------------------------------- @@ -2020,31 +1916,28 @@ void ScintillaCocoa::SetDelegate(id<ScintillaNotificationProtocol> delegate_) * @param callback The callback function to be used for future notifications. If NULL then no * notifications will be sent anymore. */ -void ScintillaCocoa::RegisterNotifyCallback(intptr_t windowid, SciNotifyFunc callback) -{ - notifyObj = windowid; - notifyProc = callback; +void ScintillaCocoa::RegisterNotifyCallback(intptr_t windowid, SciNotifyFunc callback) { + notifyObj = windowid; + notifyProc = callback; } //-------------------------------------------------------------------------------------------------- -void ScintillaCocoa::NotifyChange() -{ - if (notifyProc != NULL) - notifyProc(notifyObj, WM_COMMAND, Platform::LongFromTwoShorts(static_cast<short>(GetCtrlID()), SCEN_CHANGE), - (uintptr_t) this); +void ScintillaCocoa::NotifyChange() { + if (notifyProc != NULL) + notifyProc(notifyObj, WM_COMMAND, Platform::LongFromTwoShorts(static_cast<short>(GetCtrlID()), SCEN_CHANGE), + (uintptr_t) this); } //-------------------------------------------------------------------------------------------------- -void ScintillaCocoa::NotifyFocus(bool focus) -{ - if (notifyProc != NULL) - notifyProc(notifyObj, WM_COMMAND, Platform::LongFromTwoShorts(static_cast<short>(GetCtrlID()), - (focus ? SCEN_SETFOCUS : SCEN_KILLFOCUS)), - (uintptr_t) this); +void ScintillaCocoa::NotifyFocus(bool focus) { + if (notifyProc != NULL) + notifyProc(notifyObj, WM_COMMAND, Platform::LongFromTwoShorts(static_cast<short>(GetCtrlID()), + (focus ? SCEN_SETFOCUS : SCEN_KILLFOCUS)), + (uintptr_t) this); - Editor::NotifyFocus(focus); + Editor::NotifyFocus(focus); } //-------------------------------------------------------------------------------------------------- @@ -2055,77 +1948,68 @@ void ScintillaCocoa::NotifyFocus(bool focus) * * @param scn The notification to send. */ -void ScintillaCocoa::NotifyParent(SCNotification scn) -{ - scn.nmhdr.hwndFrom = (void*) this; - scn.nmhdr.idFrom = GetCtrlID(); - if (notifyProc != NULL) - notifyProc(notifyObj, WM_NOTIFY, GetCtrlID(), (uintptr_t) &scn); - if (delegate) - [delegate notification:&scn]; - if (scn.nmhdr.code == SCN_UPDATEUI) { - NSView *content = ContentView(); - if (scn.updated & SC_UPDATE_CONTENT) { - NSAccessibilityPostNotification(content, NSAccessibilityValueChangedNotification); - } - if (scn.updated & SC_UPDATE_SELECTION) { - NSAccessibilityPostNotification(content, NSAccessibilitySelectedTextChangedNotification); - } - } +void ScintillaCocoa::NotifyParent(SCNotification scn) { + scn.nmhdr.hwndFrom = (void *) this; + scn.nmhdr.idFrom = GetCtrlID(); + if (notifyProc != NULL) + notifyProc(notifyObj, WM_NOTIFY, GetCtrlID(), (uintptr_t) &scn); + if (delegate) + [delegate notification: &scn]; + if (scn.nmhdr.code == SCN_UPDATEUI) { + NSView *content = ContentView(); + if (scn.updated & SC_UPDATE_CONTENT) { + NSAccessibilityPostNotification(content, NSAccessibilityValueChangedNotification); + } + if (scn.updated & SC_UPDATE_SELECTION) { + NSAccessibilityPostNotification(content, NSAccessibilitySelectedTextChangedNotification); + } + } } //-------------------------------------------------------------------------------------------------- -void ScintillaCocoa::NotifyURIDropped(const char *uri) -{ - SCNotification scn; - scn.nmhdr.code = SCN_URIDROPPED; - scn.text = uri; +void ScintillaCocoa::NotifyURIDropped(const char *uri) { + SCNotification scn; + scn.nmhdr.code = SCN_URIDROPPED; + scn.text = uri; - NotifyParent(scn); + NotifyParent(scn); } //-------------------------------------------------------------------------------------------------- -bool ScintillaCocoa::HasSelection() -{ - return !sel.Empty(); +bool ScintillaCocoa::HasSelection() { + return !sel.Empty(); } //-------------------------------------------------------------------------------------------------- -bool ScintillaCocoa::CanUndo() -{ - return pdoc->CanUndo(); +bool ScintillaCocoa::CanUndo() { + return pdoc->CanUndo(); } //-------------------------------------------------------------------------------------------------- -bool ScintillaCocoa::CanRedo() -{ - return pdoc->CanRedo(); +bool ScintillaCocoa::CanRedo() { + return pdoc->CanRedo(); } //-------------------------------------------------------------------------------------------------- -void ScintillaCocoa::TimerFired(NSTimer* timer) -{ - for (TickReason tr=tickCaret; tr<=tickPlatform; tr = static_cast<TickReason>(tr+1)) - { - if (timers[tr] == timer) - { - TickFor(tr); - } - } +void ScintillaCocoa::TimerFired(NSTimer *timer) { + for (TickReason tr=tickCaret; tr<=tickPlatform; tr = static_cast<TickReason>(tr+1)) { + if (timers[tr] == timer) { + TickFor(tr); + } + } } //-------------------------------------------------------------------------------------------------- -void ScintillaCocoa::IdleTimerFired() -{ - bool more = Idle(); - if (!more) - SetIdle(false); +void ScintillaCocoa::IdleTimerFired() { + bool more = Idle(); + if (!more) + SetIdle(false); } //-------------------------------------------------------------------------------------------------- @@ -2136,9 +2020,8 @@ void ScintillaCocoa::IdleTimerFired() * @param rect The area to paint, given in the sender's coordinate system. * @param gc The context we can use to paint. */ -bool ScintillaCocoa::Draw(NSRect rect, CGContextRef gc) -{ - return SyncPaint(gc, NSRectToPRectangle(rect)); +bool ScintillaCocoa::Draw(NSRect rect, CGContextRef gc) { + return SyncPaint(gc, NSRectToPRectangle(rect)); } //-------------------------------------------------------------------------------------------------- @@ -2146,58 +2029,56 @@ bool ScintillaCocoa::Draw(NSRect rect, CGContextRef gc) /** * Helper function to translate OS X key codes to Scintilla key codes. */ -static inline UniChar KeyTranslate(UniChar unicodeChar, NSEventModifierFlags modifierFlags) -{ - switch (unicodeChar) - { - case NSDownArrowFunctionKey: - return SCK_DOWN; - case NSUpArrowFunctionKey: - return SCK_UP; - case NSLeftArrowFunctionKey: - return SCK_LEFT; - case NSRightArrowFunctionKey: - return SCK_RIGHT; - case NSHomeFunctionKey: - return SCK_HOME; - case NSEndFunctionKey: - return SCK_END; - case NSPageUpFunctionKey: - return SCK_PRIOR; - case NSPageDownFunctionKey: - return SCK_NEXT; - case NSDeleteFunctionKey: - return SCK_DELETE; - case NSInsertFunctionKey: - return SCK_INSERT; - case '\n': - case 3: - return SCK_RETURN; - case 27: - return SCK_ESCAPE; - case '+': - if (modifierFlags & NSNumericPadKeyMask) - return SCK_ADD; - else - return unicodeChar; - case '-': - if (modifierFlags & NSNumericPadKeyMask) - return SCK_SUBTRACT; - else - return unicodeChar; - case '/': - if (modifierFlags & NSNumericPadKeyMask) - return SCK_DIVIDE; - else - return unicodeChar; - case 127: - return SCK_BACK; - case '\t': - case 25: // Shift tab, return to unmodified tab and handle that via modifiers. - return SCK_TAB; - default: - return unicodeChar; - } +static inline UniChar KeyTranslate(UniChar unicodeChar, NSEventModifierFlags modifierFlags) { + switch (unicodeChar) { + case NSDownArrowFunctionKey: + return SCK_DOWN; + case NSUpArrowFunctionKey: + return SCK_UP; + case NSLeftArrowFunctionKey: + return SCK_LEFT; + case NSRightArrowFunctionKey: + return SCK_RIGHT; + case NSHomeFunctionKey: + return SCK_HOME; + case NSEndFunctionKey: + return SCK_END; + case NSPageUpFunctionKey: + return SCK_PRIOR; + case NSPageDownFunctionKey: + return SCK_NEXT; + case NSDeleteFunctionKey: + return SCK_DELETE; + case NSInsertFunctionKey: + return SCK_INSERT; + case '\n': + case 3: + return SCK_RETURN; + case 27: + return SCK_ESCAPE; + case '+': + if (modifierFlags & NSNumericPadKeyMask) + return SCK_ADD; + else + return unicodeChar; + case '-': + if (modifierFlags & NSNumericPadKeyMask) + return SCK_SUBTRACT; + else + return unicodeChar; + case '/': + if (modifierFlags & NSNumericPadKeyMask) + return SCK_DIVIDE; + else + return unicodeChar; + case 127: + return SCK_BACK; + case '\t': + case 25: // Shift tab, return to unmodified tab and handle that via modifiers. + return SCK_TAB; + default: + return unicodeChar; + } } //-------------------------------------------------------------------------------------------------- @@ -2208,14 +2089,13 @@ static inline UniChar KeyTranslate(UniChar unicodeChar, NSEventModifierFlags mod * @param modifiers An integer bit set of NSSEvent modifier flags. * @return A set of SCI_* modifier flags. */ -static int TranslateModifierFlags(NSUInteger modifiers) -{ - // Signal Control as SCI_META - return - (((modifiers & NSShiftKeyMask) != 0) ? SCI_SHIFT : 0) | - (((modifiers & NSCommandKeyMask) != 0) ? SCI_CTRL : 0) | - (((modifiers & NSAlternateKeyMask) != 0) ? SCI_ALT : 0) | - (((modifiers & NSControlKeyMask) != 0) ? SCI_META : 0); +static int TranslateModifierFlags(NSUInteger modifiers) { + // Signal Control as SCI_META + return + (((modifiers & NSShiftKeyMask) != 0) ? SCI_SHIFT : 0) | + (((modifiers & NSCommandKeyMask) != 0) ? SCI_CTRL : 0) | + (((modifiers & NSAlternateKeyMask) != 0) ? SCI_ALT : 0) | + (((modifiers & NSControlKeyMask) != 0) ? SCI_META : 0); } //-------------------------------------------------------------------------------------------------- @@ -2227,30 +2107,28 @@ static int TranslateModifierFlags(NSUInteger modifiers) * @param event The event instance associated with the key down event. * @return True if the input was handled, false otherwise. */ -bool ScintillaCocoa::KeyboardInput(NSEvent* event) -{ - // For now filter out function keys. - NSString* input = event.charactersIgnoringModifiers; +bool ScintillaCocoa::KeyboardInput(NSEvent *event) { + // For now filter out function keys. + NSString *input = event.charactersIgnoringModifiers; - bool handled = false; + bool handled = false; - // Handle each entry individually. Usually we only have one entry anyway. - for (size_t i = 0; i < input.length; i++) - { - const UniChar originalKey = [input characterAtIndex: i]; - NSEventModifierFlags modifierFlags = event.modifierFlags; - - UniChar key = KeyTranslate(originalKey, modifierFlags); + // Handle each entry individually. Usually we only have one entry anyway. + for (size_t i = 0; i < input.length; i++) { + const UniChar originalKey = [input characterAtIndex: i]; + NSEventModifierFlags modifierFlags = event.modifierFlags; - bool consumed = false; // Consumed as command? + UniChar key = KeyTranslate(originalKey, modifierFlags); - if (KeyDownWithModifiers(key, TranslateModifierFlags(modifierFlags), &consumed)) - handled = true; - if (consumed) - handled = true; - } + bool consumed = false; // Consumed as command? - return handled; + if (KeyDownWithModifiers(key, TranslateModifierFlags(modifierFlags), &consumed)) + handled = true; + if (consumed) + handled = true; + } + + return handled; } //-------------------------------------------------------------------------------------------------- @@ -2258,17 +2136,15 @@ bool ScintillaCocoa::KeyboardInput(NSEvent* event) /** * Used to insert already processed text provided by the Cocoa text input system. */ -int ScintillaCocoa::InsertText(NSString* input) -{ - CFStringEncoding encoding = EncodingFromCharacterSet(IsUnicodeMode(), - vs.styles[STYLE_DEFAULT].characterSet); - std::string encoded = EncodedBytesString((__bridge CFStringRef)input, encoding); +int ScintillaCocoa::InsertText(NSString *input) { + CFStringEncoding encoding = EncodingFromCharacterSet(IsUnicodeMode(), + vs.styles[STYLE_DEFAULT].characterSet); + std::string encoded = EncodedBytesString((__bridge CFStringRef)input, encoding); - if (encoded.length() > 0) - { - AddCharUTF(encoded.c_str(), static_cast<unsigned int>(encoded.length()), false); - } - return static_cast<int>(encoded.length()); + if (encoded.length() > 0) { + AddCharUTF(encoded.c_str(), static_cast<unsigned int>(encoded.length()), false); + } + return static_cast<int>(encoded.length()); } //-------------------------------------------------------------------------------------------------- @@ -2276,15 +2152,14 @@ int ScintillaCocoa::InsertText(NSString* input) /** * Convert from a range of characters to a range of bytes. */ -NSRange ScintillaCocoa::PositionsFromCharacters(NSRange rangeCharacters) const -{ - long start = pdoc->GetRelativePositionUTF16(0, static_cast<int>(rangeCharacters.location)); - if (start == INVALID_POSITION) - start = pdoc->Length(); - long end = pdoc->GetRelativePositionUTF16(static_cast<int>(start), static_cast<int>(rangeCharacters.length)); - if (end == INVALID_POSITION) - end = pdoc->Length(); - return NSMakeRange(start, end - start); +NSRange ScintillaCocoa::PositionsFromCharacters(NSRange rangeCharacters) const { + long start = pdoc->GetRelativePositionUTF16(0, static_cast<int>(rangeCharacters.location)); + if (start == INVALID_POSITION) + start = pdoc->Length(); + long end = pdoc->GetRelativePositionUTF16(static_cast<int>(start), static_cast<int>(rangeCharacters.length)); + if (end == INVALID_POSITION) + end = pdoc->Length(); + return NSMakeRange(start, end - start); } //-------------------------------------------------------------------------------------------------- @@ -2292,12 +2167,11 @@ NSRange ScintillaCocoa::PositionsFromCharacters(NSRange rangeCharacters) const /** * Convert from a range of characters from a range of bytes. */ -NSRange ScintillaCocoa::CharactersFromPositions(NSRange rangePositions) const -{ - const long start = pdoc->CountUTF16(0, static_cast<int>(rangePositions.location)); - const long len = pdoc->CountUTF16(static_cast<int>(rangePositions.location), - static_cast<int>(NSMaxRange(rangePositions))); - return NSMakeRange(start, len); +NSRange ScintillaCocoa::CharactersFromPositions(NSRange rangePositions) const { + const long start = pdoc->CountUTF16(0, static_cast<int>(rangePositions.location)); + const long len = pdoc->CountUTF16(static_cast<int>(rangePositions.location), + static_cast<int>(NSMaxRange(rangePositions))); + return NSMakeRange(start, len); } //-------------------------------------------------------------------------------------------------- @@ -2306,10 +2180,9 @@ NSRange ScintillaCocoa::CharactersFromPositions(NSRange rangePositions) const * Used to ensure that only one selection is active for input composition as composition * does not support multi-typing. */ -void ScintillaCocoa::SelectOnlyMainSelection() -{ - sel.SetSelection(sel.RangeMain()); - Redraw(); +void ScintillaCocoa::SelectOnlyMainSelection() { + sel.SetSelection(sel.RangeMain()); + Redraw(); } //-------------------------------------------------------------------------------------------------- @@ -2317,9 +2190,8 @@ void ScintillaCocoa::SelectOnlyMainSelection() /** * Convert virtual space before selection into real space. */ -void ScintillaCocoa::ConvertSelectionVirtualSpace() -{ - ClearBeforeTentativeStart(); +void ScintillaCocoa::ConvertSelectionVirtualSpace() { + ClearBeforeTentativeStart(); } //-------------------------------------------------------------------------------------------------- @@ -2328,10 +2200,9 @@ void ScintillaCocoa::ConvertSelectionVirtualSpace() * Erase all selected text and return whether the selection is now empty. * The selection may not be empty if the selection contained protected text. */ -bool ScintillaCocoa::ClearAllSelections() -{ - ClearSelection(true); - return sel.Empty(); +bool ScintillaCocoa::ClearAllSelections() { + ClearSelection(true); + return sel.Empty(); } //-------------------------------------------------------------------------------------------------- @@ -2339,13 +2210,11 @@ bool ScintillaCocoa::ClearAllSelections() /** * Start composing for IME. */ -void ScintillaCocoa::CompositionStart() -{ - if (!sel.Empty()) - { - NSLog(@"Selection not empty when starting composition"); - } - pdoc->TentativeStart(); +void ScintillaCocoa::CompositionStart() { + if (!sel.Empty()) { + NSLog(@"Selection not empty when starting composition"); + } + pdoc->TentativeStart(); } //-------------------------------------------------------------------------------------------------- @@ -2353,11 +2222,10 @@ void ScintillaCocoa::CompositionStart() /** * Commit the IME text. */ -void ScintillaCocoa::CompositionCommit() -{ - pdoc->TentativeCommit(); - pdoc->DecorationSetCurrentIndicator(INDIC_IME); - pdoc->DecorationFillRange(0, 0, pdoc->Length()); +void ScintillaCocoa::CompositionCommit() { + pdoc->TentativeCommit(); + pdoc->DecorationSetCurrentIndicator(INDIC_IME); + pdoc->DecorationFillRange(0, 0, pdoc->Length()); } //-------------------------------------------------------------------------------------------------- @@ -2365,9 +2233,8 @@ void ScintillaCocoa::CompositionCommit() /** * Remove the IME text. */ -void ScintillaCocoa::CompositionUndo() -{ - pdoc->TentativeUndo(); +void ScintillaCocoa::CompositionUndo() { + pdoc->TentativeUndo(); } //-------------------------------------------------------------------------------------------------- @@ -2375,14 +2242,13 @@ void ScintillaCocoa::CompositionUndo() * When switching documents discard any incomplete character composition state as otherwise tries to * act on the new document. */ -void ScintillaCocoa::SetDocPointer(Document *document) -{ - // Drop input composition. - NSTextInputContext *inctxt = [NSTextInputContext currentInputContext]; - [inctxt discardMarkedText]; - SCIContentView *inner = ContentView(); - [inner unmarkText]; - Editor::SetDocPointer(document); +void ScintillaCocoa::SetDocPointer(Document *document) { + // Drop input composition. + NSTextInputContext *inctxt = [NSTextInputContext currentInputContext]; + [inctxt discardMarkedText]; + SCIContentView *inner = ContentView(); + [inner unmarkText]; + Editor::SetDocPointer(document); } //-------------------------------------------------------------------------------------------------- @@ -2390,146 +2256,127 @@ void ScintillaCocoa::SetDocPointer(Document *document) /** * Called by the owning view when the mouse pointer enters the control. */ -void ScintillaCocoa::MouseEntered(NSEvent* event) -{ - if (!HaveMouseCapture()) - { - WndProc(SCI_SETCURSOR, (long int)SC_CURSORNORMAL, 0); +void ScintillaCocoa::MouseEntered(NSEvent *event) { + if (!HaveMouseCapture()) { + WndProc(SCI_SETCURSOR, (long int)SC_CURSORNORMAL, 0); - // Mouse location is given in screen coordinates and might also be outside of our bounds. - Point location = ConvertPoint(event.locationInWindow); - ButtonMove(location); - } + // Mouse location is given in screen coordinates and might also be outside of our bounds. + Point location = ConvertPoint(event.locationInWindow); + ButtonMove(location); + } } //-------------------------------------------------------------------------------------------------- -void ScintillaCocoa::MouseExited(NSEvent* /* event */) -{ - // Nothing to do here. +void ScintillaCocoa::MouseExited(NSEvent * /* event */) { + // Nothing to do here. } //-------------------------------------------------------------------------------------------------- -void ScintillaCocoa::MouseDown(NSEvent* event) -{ - Point location = ConvertPoint(event.locationInWindow); - NSTimeInterval time = event.timestamp; - bool command = (event.modifierFlags & NSCommandKeyMask) != 0; - bool shift = (event.modifierFlags & NSShiftKeyMask) != 0; - bool alt = (event.modifierFlags & NSAlternateKeyMask) != 0; +void ScintillaCocoa::MouseDown(NSEvent *event) { + Point location = ConvertPoint(event.locationInWindow); + NSTimeInterval time = event.timestamp; + bool command = (event.modifierFlags & NSCommandKeyMask) != 0; + bool shift = (event.modifierFlags & NSShiftKeyMask) != 0; + bool alt = (event.modifierFlags & NSAlternateKeyMask) != 0; - ButtonDown(Point(location.x, location.y), (int) (time * 1000), shift, command, alt); + ButtonDown(Point(location.x, location.y), (int)(time * 1000), shift, command, alt); } -void ScintillaCocoa::RightMouseDown(NSEvent *event) -{ - Point location = ConvertPoint(event.locationInWindow); - NSTimeInterval time = event.timestamp; - bool command = (event.modifierFlags & NSCommandKeyMask) != 0; - bool shift = (event.modifierFlags & NSShiftKeyMask) != 0; - bool alt = (event.modifierFlags & NSAlternateKeyMask) != 0; +void ScintillaCocoa::RightMouseDown(NSEvent *event) { + Point location = ConvertPoint(event.locationInWindow); + NSTimeInterval time = event.timestamp; + bool command = (event.modifierFlags & NSCommandKeyMask) != 0; + bool shift = (event.modifierFlags & NSShiftKeyMask) != 0; + bool alt = (event.modifierFlags & NSAlternateKeyMask) != 0; - RightButtonDownWithModifiers(Point(location.x, location.y), (int) (time * 1000), ModifierFlags(shift, command, alt)); + RightButtonDownWithModifiers(Point(location.x, location.y), (int)(time * 1000), ModifierFlags(shift, command, alt)); } //-------------------------------------------------------------------------------------------------- -void ScintillaCocoa::MouseMove(NSEvent* event) -{ - lastMouseEvent = event; +void ScintillaCocoa::MouseMove(NSEvent *event) { + lastMouseEvent = event; - ButtonMoveWithModifiers(ConvertPoint(event.locationInWindow), TranslateModifierFlags(event.modifierFlags)); + ButtonMoveWithModifiers(ConvertPoint(event.locationInWindow), TranslateModifierFlags(event.modifierFlags)); } //-------------------------------------------------------------------------------------------------- -void ScintillaCocoa::MouseUp(NSEvent* event) -{ - NSTimeInterval time = event.timestamp; - bool control = (event.modifierFlags & NSControlKeyMask) != 0; +void ScintillaCocoa::MouseUp(NSEvent *event) { + NSTimeInterval time = event.timestamp; + bool control = (event.modifierFlags & NSControlKeyMask) != 0; - ButtonUp(ConvertPoint(event.locationInWindow), (int) (time * 1000), control); + ButtonUp(ConvertPoint(event.locationInWindow), (int)(time * 1000), control); } //-------------------------------------------------------------------------------------------------- -void ScintillaCocoa::MouseWheel(NSEvent* event) -{ - bool command = (event.modifierFlags & NSCommandKeyMask) != 0; - int dY = 0; +void ScintillaCocoa::MouseWheel(NSEvent *event) { + bool command = (event.modifierFlags & NSCommandKeyMask) != 0; + int dY = 0; - // In order to make scrolling with larger offset smoother we scroll less lines the larger the - // delta value is. - if (event.deltaY < 0) - dY = -(int) sqrt(-10.0 * event.deltaY); - else - dY = (int) sqrt(10.0 * event.deltaY); + // In order to make scrolling with larger offset smoother we scroll less lines the larger the + // delta value is. + if (event.deltaY < 0) + dY = -(int) sqrt(-10.0 * event.deltaY); + else + dY = (int) sqrt(10.0 * event.deltaY); - if (command) - { - // Zoom! We play with the font sizes in the styles. - // Number of steps/line is ignored, we just care if sizing up or down. - if (dY > 0.5) - KeyCommand(SCI_ZOOMIN); - else if (dY < -0.5) - KeyCommand(SCI_ZOOMOUT); - } - else - { - } + if (command) { + // Zoom! We play with the font sizes in the styles. + // Number of steps/line is ignored, we just care if sizing up or down. + if (dY > 0.5) + KeyCommand(SCI_ZOOMIN); + else if (dY < -0.5) + KeyCommand(SCI_ZOOMOUT); + } else { + } } //-------------------------------------------------------------------------------------------------- // Helper methods for NSResponder actions. -void ScintillaCocoa::SelectAll() -{ - Editor::SelectAll(); +void ScintillaCocoa::SelectAll() { + Editor::SelectAll(); } -void ScintillaCocoa::DeleteBackward() -{ - KeyDown(SCK_BACK, false, false, false, nil); +void ScintillaCocoa::DeleteBackward() { + KeyDown(SCK_BACK, false, false, false, nil); } -void ScintillaCocoa::Cut() -{ - Editor::Cut(); +void ScintillaCocoa::Cut() { + Editor::Cut(); } -void ScintillaCocoa::Undo() -{ - Editor::Undo(); +void ScintillaCocoa::Undo() { + Editor::Undo(); } -void ScintillaCocoa::Redo() -{ - Editor::Redo(); +void ScintillaCocoa::Redo() { + Editor::Redo(); } //-------------------------------------------------------------------------------------------------- -bool ScintillaCocoa::ShouldDisplayPopupOnMargin() -{ - return displayPopupMenu == SC_POPUP_ALL; +bool ScintillaCocoa::ShouldDisplayPopupOnMargin() { + return displayPopupMenu == SC_POPUP_ALL; } -bool ScintillaCocoa::ShouldDisplayPopupOnText() -{ - return displayPopupMenu == SC_POPUP_ALL || displayPopupMenu == SC_POPUP_TEXT; +bool ScintillaCocoa::ShouldDisplayPopupOnText() { + return displayPopupMenu == SC_POPUP_ALL || displayPopupMenu == SC_POPUP_TEXT; } /** * Creates and returns a popup menu, which is then displayed by the Cocoa framework. */ -NSMenu* ScintillaCocoa::CreateContextMenu(NSEvent* /* event */) -{ - // Call ScintillaBase to create the context menu. - ContextMenu(Point(0, 0)); +NSMenu *ScintillaCocoa::CreateContextMenu(NSEvent * /* event */) { + // Call ScintillaBase to create the context menu. + ContextMenu(Point(0, 0)); - return (__bridge NSMenu*)(popup.GetID()); + return (__bridge NSMenu *)(popup.GetID()); } //-------------------------------------------------------------------------------------------------- @@ -2538,23 +2385,21 @@ NSMenu* ScintillaCocoa::CreateContextMenu(NSEvent* /* event */) * An intermediate function to forward context menu commands from the menu action handler to * scintilla. */ -void ScintillaCocoa::HandleCommand(NSInteger command) -{ - Command(static_cast<int>(command)); +void ScintillaCocoa::HandleCommand(NSInteger command) { + Command(static_cast<int>(command)); } //-------------------------------------------------------------------------------------------------- -void ScintillaCocoa::ActiveStateChanged(bool isActive) -{ - // If the window is being deactivated, lose the focus and turn off the ticking - if (!isActive) { - DropCaret(); - //SetFocusState( false ); - FineTickerCancel(tickCaret); - } else { - ShowCaretAtCurrentPosition(); - } +void ScintillaCocoa::ActiveStateChanged(bool isActive) { + // If the window is being deactivated, lose the focus and turn off the ticking + if (!isActive) { + DropCaret(); + //SetFocusState( false ); + FineTickerCancel(tickCaret); + } else { + ShowCaretAtCurrentPosition(); + } } //-------------------------------------------------------------------------------------------------- @@ -2564,8 +2409,8 @@ void ScintillaCocoa::ActiveStateChanged(bool isActive) * so cancel them. */ void ScintillaCocoa::WindowWillMove() { - AutoCompleteCancel(); - ct.CallTipCancel(); + AutoCompleteCancel(); + ct.CallTipCancel(); } // If building with old SDK, need to define version number for 10.8 @@ -2575,85 +2420,74 @@ void ScintillaCocoa::WindowWillMove() { //-------------------------------------------------------------------------------------------------- -void ScintillaCocoa::ShowFindIndicatorForRange(NSRange charRange, BOOL retaining) -{ +void ScintillaCocoa::ShowFindIndicatorForRange(NSRange charRange, BOOL retaining) { #if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_5 - NSView *content = ContentView(); - if (!layerFindIndicator) - { - layerFindIndicator = [[FindHighlightLayer alloc] init]; - [content setWantsLayer: YES]; - layerFindIndicator.geometryFlipped = content.layer.geometryFlipped; - if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_8) - { - // Content layer is unflipped on 10.9, but the indicator shows wrong unless flipped - layerFindIndicator.geometryFlipped = YES; - } - [content.layer addSublayer:layerFindIndicator]; - } - [layerFindIndicator removeAnimationForKey:@"animateFound"]; - - if (charRange.length) - { - CFStringEncoding encoding = EncodingFromCharacterSet(IsUnicodeMode(), - vs.styles[STYLE_DEFAULT].characterSet); - std::vector<char> buffer(charRange.length); - pdoc->GetCharRange(&buffer[0], static_cast<int>(charRange.location), static_cast<int>(charRange.length)); - - CFStringRef cfsFind = CFStringFromString(&buffer[0], charRange.length, encoding); - layerFindIndicator.sFind = (__bridge NSString *)cfsFind; - if (cfsFind) - CFRelease(cfsFind); - layerFindIndicator.retaining = retaining; - layerFindIndicator.positionFind = static_cast<int>(charRange.location); - // SCI_GETSTYLEAT reports a signed byte but want an unsigned to index into styles - const char styleByte = static_cast<char>(WndProc(SCI_GETSTYLEAT, charRange.location, 0)); - const long style = static_cast<unsigned char>(styleByte); - std::vector<char> bufferFontName(WndProc(SCI_STYLEGETFONT, style, 0) + 1); - WndProc(SCI_STYLEGETFONT, style, (sptr_t)&bufferFontName[0]); - layerFindIndicator.sFont = @(&bufferFontName[0]); - - layerFindIndicator.fontSize = WndProc(SCI_STYLEGETSIZEFRACTIONAL, style, 0) / - (float)SC_FONT_SIZE_MULTIPLIER; - layerFindIndicator.widthText = WndProc(SCI_POINTXFROMPOSITION, 0, charRange.location + charRange.length) - - WndProc(SCI_POINTXFROMPOSITION, 0, charRange.location); - layerFindIndicator.heightLine = WndProc(SCI_TEXTHEIGHT, 0, 0); - MoveFindIndicatorWithBounce(YES); - } - else - { - [layerFindIndicator hideMatch]; - } + NSView *content = ContentView(); + if (!layerFindIndicator) { + layerFindIndicator = [[FindHighlightLayer alloc] init]; + [content setWantsLayer: YES]; + layerFindIndicator.geometryFlipped = content.layer.geometryFlipped; + if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_8) { + // Content layer is unflipped on 10.9, but the indicator shows wrong unless flipped + layerFindIndicator.geometryFlipped = YES; + } + [content.layer addSublayer: layerFindIndicator]; + } + [layerFindIndicator removeAnimationForKey: @"animateFound"]; + + if (charRange.length) { + CFStringEncoding encoding = EncodingFromCharacterSet(IsUnicodeMode(), + vs.styles[STYLE_DEFAULT].characterSet); + std::vector<char> buffer(charRange.length); + pdoc->GetCharRange(&buffer[0], static_cast<int>(charRange.location), static_cast<int>(charRange.length)); + + CFStringRef cfsFind = CFStringFromString(&buffer[0], charRange.length, encoding); + layerFindIndicator.sFind = (__bridge NSString *)cfsFind; + if (cfsFind) + CFRelease(cfsFind); + layerFindIndicator.retaining = retaining; + layerFindIndicator.positionFind = static_cast<int>(charRange.location); + // SCI_GETSTYLEAT reports a signed byte but want an unsigned to index into styles + const char styleByte = static_cast<char>(WndProc(SCI_GETSTYLEAT, charRange.location, 0)); + const long style = static_cast<unsigned char>(styleByte); + std::vector<char> bufferFontName(WndProc(SCI_STYLEGETFONT, style, 0) + 1); + WndProc(SCI_STYLEGETFONT, style, (sptr_t)&bufferFontName[0]); + layerFindIndicator.sFont = @(&bufferFontName[0]); + + layerFindIndicator.fontSize = WndProc(SCI_STYLEGETSIZEFRACTIONAL, style, 0) / + (float)SC_FONT_SIZE_MULTIPLIER; + layerFindIndicator.widthText = WndProc(SCI_POINTXFROMPOSITION, 0, charRange.location + charRange.length) - + WndProc(SCI_POINTXFROMPOSITION, 0, charRange.location); + layerFindIndicator.heightLine = WndProc(SCI_TEXTHEIGHT, 0, 0); + MoveFindIndicatorWithBounce(YES); + } else { + [layerFindIndicator hideMatch]; + } #endif } -void ScintillaCocoa::MoveFindIndicatorWithBounce(BOOL bounce) -{ +void ScintillaCocoa::MoveFindIndicatorWithBounce(BOOL bounce) { #if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_5 - if (layerFindIndicator) - { - CGPoint ptText = CGPointMake( - WndProc(SCI_POINTXFROMPOSITION, 0, layerFindIndicator.positionFind), - WndProc(SCI_POINTYFROMPOSITION, 0, layerFindIndicator.positionFind)); - ptText.x = ptText.x - vs.fixedColumnWidth + xOffset; - ptText.y += topLine * vs.lineHeight; - if (!layerFindIndicator.geometryFlipped) - { - NSView *content = ContentView(); - ptText.y = content.bounds.size.height - ptText.y; - } - [layerFindIndicator animateMatch:ptText bounce:bounce]; - } + if (layerFindIndicator) { + CGPoint ptText = CGPointMake( + WndProc(SCI_POINTXFROMPOSITION, 0, layerFindIndicator.positionFind), + WndProc(SCI_POINTYFROMPOSITION, 0, layerFindIndicator.positionFind)); + ptText.x = ptText.x - vs.fixedColumnWidth + xOffset; + ptText.y += topLine * vs.lineHeight; + if (!layerFindIndicator.geometryFlipped) { + NSView *content = ContentView(); + ptText.y = content.bounds.size.height - ptText.y; + } + [layerFindIndicator animateMatch: ptText bounce: bounce]; + } #endif } -void ScintillaCocoa::HideFindIndicator() -{ +void ScintillaCocoa::HideFindIndicator() { #if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_5 - if (layerFindIndicator) - { - [layerFindIndicator hideMatch]; - } + if (layerFindIndicator) { + [layerFindIndicator hideMatch]; + } #endif } diff --git a/cocoa/ScintillaView.h b/cocoa/ScintillaView.h index 1bd9637a2..dc5dc030a 100644 --- a/cocoa/ScintillaView.h +++ b/cocoa/ScintillaView.h @@ -34,12 +34,12 @@ * <br> * WM_NOTIFY: wParam = control ID, lParam = ptr to SCNotification structure, with hwndFrom set to ScintillaCocoa* */ -typedef void(*SciNotifyFunc) (intptr_t windowid, unsigned int iMessage, uintptr_t wParam, uintptr_t lParam); +typedef void(*SciNotifyFunc)(intptr_t windowid, unsigned int iMessage, uintptr_t wParam, uintptr_t lParam); extern NSString *const SCIUpdateUINotification; @protocol ScintillaNotificationProtocol -- (void)notification: (SCNotification*)notification; +- (void) notification: (SCNotification *) notification; @end /** @@ -54,11 +54,11 @@ extern NSString *const SCIUpdateUINotification; * provides a canvas for painting the output. */ @interface SCIContentView : NSView < - NSTextInputClient, - NSUserInterfaceValidations, - NSDraggingSource, - NSDraggingDestination, - NSAccessibilityStaticText>; + NSTextInputClient, + NSUserInterfaceValidations, + NSDraggingSource, + NSDraggingDestination, + NSAccessibilityStaticText>; - (void) setCursor: (int) cursor; // Needed by ScintillaCocoa @@ -71,46 +71,46 @@ extern NSString *const SCIUpdateUINotification; */ @interface ScintillaView : NSView <InfoBarCommunicator, ScintillaNotificationProtocol>; -@property (nonatomic, unsafe_unretained) id<ScintillaNotificationProtocol> delegate; -@property (nonatomic, readonly) NSScrollView *scrollView; +@property(nonatomic, unsafe_unretained) id<ScintillaNotificationProtocol> delegate; +@property(nonatomic, readonly) NSScrollView *scrollView; + (Class) contentViewClass; -- (void) notify: (NotificationType) type message: (NSString*) message location: (NSPoint) location - value: (float) value; +- (void) notify: (NotificationType) type message: (NSString *) message location: (NSPoint) location + value: (float) value; - (void) setCallback: (id <InfoBarCommunicator>) callback; - (void) suspendDrawing: (BOOL) suspend; -- (void) notification: (SCNotification*) notification; +- (void) notification: (SCNotification *) notification; - (void) updateIndicatorIME; // Scroller handling - (void) setMarginWidth: (int) width; -- (SCIContentView*) content; +- (SCIContentView *) content; - (void) updateMarginCursors; // NSTextView compatibility layer. -- (NSString*) string; -- (void) setString: (NSString*) aString; +- (NSString *) string; +- (void) setString: (NSString *) aString; - (void) insertText: (id) aString; - (void) setEditable: (BOOL) editable; - (BOOL) isEditable; - (NSRange) selectedRange; - (NSRange) selectedRangePositions; -- (NSString*) selectedString; +- (NSString *) selectedString; - (void) deleteRange: (NSRange) range; -- (void)setFontName: (NSString*) font - size: (int) size - bold: (BOOL) bold - italic: (BOOL) italic; +- (void) setFontName: (NSString *) font + size: (int) size + bold: (BOOL) bold + italic: (BOOL) italic; // Native call through to the backend. -+ (sptr_t) directCall: (ScintillaView*) sender message: (unsigned int) message wParam: (uptr_t) wParam - lParam: (sptr_t) lParam; ++ (sptr_t) directCall: (ScintillaView *) sender message: (unsigned int) message wParam: (uptr_t) wParam + lParam: (sptr_t) lParam; - (sptr_t) message: (unsigned int) message wParam: (uptr_t) wParam lParam: (sptr_t) lParam; - (sptr_t) message: (unsigned int) message wParam: (uptr_t) wParam; - (sptr_t) message: (unsigned int) message; @@ -122,40 +122,40 @@ extern NSString *const SCIUpdateUINotification; - (long) getGeneralProperty: (int) property; - (long) getGeneralProperty: (int) property parameter: (long) parameter; - (long) getGeneralProperty: (int) property parameter: (long) parameter extra: (long) extra; -- (long) getGeneralProperty: (int) property ref: (const void*) ref; -- (void) setColorProperty: (int) property parameter: (long) parameter value: (NSColor*) value; -- (void) setColorProperty: (int) property parameter: (long) parameter fromHTML: (NSString*) fromHTML; -- (NSColor*) getColorProperty: (int) property parameter: (long) parameter; -- (void) setReferenceProperty: (int) property parameter: (long) parameter value: (const void*) value; -- (const void*) getReferenceProperty: (int) property parameter: (long) parameter; -- (void) setStringProperty: (int) property parameter: (long) parameter value: (NSString*) value; -- (NSString*) getStringProperty: (int) property parameter: (long) parameter; -- (void) setLexerProperty: (NSString*) name value: (NSString*) value; -- (NSString*) getLexerProperty: (NSString*) name; +- (long) getGeneralProperty: (int) property ref: (const void *) ref; +- (void) setColorProperty: (int) property parameter: (long) parameter value: (NSColor *) value; +- (void) setColorProperty: (int) property parameter: (long) parameter fromHTML: (NSString *) fromHTML; +- (NSColor *) getColorProperty: (int) property parameter: (long) parameter; +- (void) setReferenceProperty: (int) property parameter: (long) parameter value: (const void *) value; +- (const void *) getReferenceProperty: (int) property parameter: (long) parameter; +- (void) setStringProperty: (int) property parameter: (long) parameter value: (NSString *) value; +- (NSString *) getStringProperty: (int) property parameter: (long) parameter; +- (void) setLexerProperty: (NSString *) name value: (NSString *) value; +- (NSString *) getLexerProperty: (NSString *) name; // The delegate property should be used instead of registerNotifyCallback which is deprecated. -- (void) registerNotifyCallback: (intptr_t) windowid value: (SciNotifyFunc) callback __attribute__((deprecated)); - -- (void) setInfoBar: (NSView <InfoBarCommunicator>*) aView top: (BOOL) top; -- (void) setStatusText: (NSString*) text; - -- (BOOL) findAndHighlightText: (NSString*) searchText - matchCase: (BOOL) matchCase - wholeWord: (BOOL) wholeWord - scrollTo: (BOOL) scrollTo - wrap: (BOOL) wrap; - -- (BOOL) findAndHighlightText: (NSString*) searchText - matchCase: (BOOL) matchCase - wholeWord: (BOOL) wholeWord - scrollTo: (BOOL) scrollTo - wrap: (BOOL) wrap - backwards: (BOOL) backwards; - -- (int) findAndReplaceText: (NSString*) searchText - byText: (NSString*) newText - matchCase: (BOOL) matchCase - wholeWord: (BOOL) wholeWord - doAll: (BOOL) doAll; +- (void) registerNotifyCallback: (intptr_t) windowid value: (SciNotifyFunc) callback __attribute__ ( (deprecated)) ; + +- (void) setInfoBar: (NSView <InfoBarCommunicator> *) aView top: (BOOL) top; +- (void) setStatusText: (NSString *) text; + +- (BOOL) findAndHighlightText: (NSString *) searchText + matchCase: (BOOL) matchCase + wholeWord: (BOOL) wholeWord + scrollTo: (BOOL) scrollTo + wrap: (BOOL) wrap; + +- (BOOL) findAndHighlightText: (NSString *) searchText + matchCase: (BOOL) matchCase + wholeWord: (BOOL) wholeWord + scrollTo: (BOOL) scrollTo + wrap: (BOOL) wrap + backwards: (BOOL) backwards; + +- (int) findAndReplaceText: (NSString *) searchText + byText: (NSString *) newText + matchCase: (BOOL) matchCase + wholeWord: (BOOL) wholeWord + doAll: (BOOL) doAll; @end diff --git a/cocoa/ScintillaView.mm b/cocoa/ScintillaView.mm index df03add5f..ea6f6f510 100644 --- a/cocoa/ScintillaView.mm +++ b/cocoa/ScintillaView.mm @@ -17,221 +17,201 @@ using namespace Scintilla; // Add backend property to ScintillaView as a private category. // Specified here as backend accessed by SCIMarginView and SCIContentView. -@interface ScintillaView () -@property (nonatomic, readonly) Scintilla::ScintillaCocoa* backend; +@interface ScintillaView() +@property(nonatomic, readonly) Scintilla::ScintillaCocoa *backend; @end // Two additional cursors we need, which aren't provided by Cocoa. -static NSCursor* reverseArrowCursor; -static NSCursor* waitCursor; +static NSCursor *reverseArrowCursor; +static NSCursor *waitCursor; NSString *const SCIUpdateUINotification = @"SCIUpdateUI"; /** * Provide an NSCursor object that matches the Window::Cursor enumeration. */ -static NSCursor *cursorFromEnum(Window::Cursor cursor) -{ - switch (cursor) - { - case Window::cursorText: - return [NSCursor IBeamCursor]; - case Window::cursorArrow: - return [NSCursor arrowCursor]; - case Window::cursorWait: - return waitCursor; - case Window::cursorHoriz: - return [NSCursor resizeLeftRightCursor]; - case Window::cursorVert: - return [NSCursor resizeUpDownCursor]; - case Window::cursorReverseArrow: - return reverseArrowCursor; - case Window::cursorUp: - default: - return [NSCursor arrowCursor]; - } +static NSCursor *cursorFromEnum(Window::Cursor cursor) { + switch (cursor) { + case Window::cursorText: + return [NSCursor IBeamCursor]; + case Window::cursorArrow: + return [NSCursor arrowCursor]; + case Window::cursorWait: + return waitCursor; + case Window::cursorHoriz: + return [NSCursor resizeLeftRightCursor]; + case Window::cursorVert: + return [NSCursor resizeUpDownCursor]; + case Window::cursorReverseArrow: + return reverseArrowCursor; + case Window::cursorUp: + default: + return [NSCursor arrowCursor]; + } } // Add marginWidth and owner properties as a private category. -@interface SCIMarginView () -@property (assign) int marginWidth; -@property (nonatomic, weak) ScintillaView* owner; +@interface SCIMarginView() +@property(assign) int marginWidth; +@property(nonatomic, weak) ScintillaView *owner; @end @implementation SCIMarginView { - int marginWidth; - ScintillaView *__weak owner; - NSMutableArray *currentCursors; + int marginWidth; + ScintillaView *__weak owner; + NSMutableArray *currentCursors; } @synthesize marginWidth, owner; -- (instancetype)initWithScrollView:(NSScrollView *)aScrollView -{ - self = [super initWithScrollView:aScrollView orientation:NSVerticalRuler]; - if (self != nil) - { - owner = nil; - marginWidth = 20; - currentCursors = [NSMutableArray arrayWithCapacity:0]; - for (size_t i=0; i<=SC_MAX_MARGIN; i++) - { - [currentCursors addObject: reverseArrowCursor]; - } - self.clientView = aScrollView.documentView; - if ([self respondsToSelector: @selector(setAccessibilityLabel:)]) - self.accessibilityLabel = @"Scintilla Margin"; - } - return self; +- (instancetype) initWithScrollView: (NSScrollView *) aScrollView { + self = [super initWithScrollView: aScrollView orientation: NSVerticalRuler]; + if (self != nil) { + owner = nil; + marginWidth = 20; + currentCursors = [NSMutableArray arrayWithCapacity: 0]; + for (size_t i=0; i<=SC_MAX_MARGIN; i++) { + [currentCursors addObject: reverseArrowCursor]; + } + self.clientView = aScrollView.documentView; + if ([self respondsToSelector: @selector(setAccessibilityLabel:)]) + self.accessibilityLabel = @"Scintilla Margin"; + } + return self; } -- (void) setFrame: (NSRect) frame -{ - super.frame = frame; +- (void) setFrame: (NSRect) frame { + super.frame = frame; - [self.window invalidateCursorRectsForView: self]; + [self.window invalidateCursorRectsForView: self]; } -- (CGFloat)requiredThickness -{ - return marginWidth; +- (CGFloat) requiredThickness { + return marginWidth; } -- (void)drawHashMarksAndLabelsInRect:(NSRect)aRect -{ - if (owner) { - NSRect contentRect = self.scrollView.contentView.bounds; - NSRect marginRect = self.bounds; - // Ensure paint to bottom of view to avoid glitches - if (marginRect.size.height > contentRect.size.height) { - // Legacy scroll bar mode leaves a poorly painted corner - aRect = marginRect; - } - owner.backend->PaintMargin(aRect); - } +- (void) drawHashMarksAndLabelsInRect: (NSRect) aRect { + if (owner) { + NSRect contentRect = self.scrollView.contentView.bounds; + NSRect marginRect = self.bounds; + // Ensure paint to bottom of view to avoid glitches + if (marginRect.size.height > contentRect.size.height) { + // Legacy scroll bar mode leaves a poorly painted corner + aRect = marginRect; + } + owner.backend->PaintMargin(aRect); + } } /** * Called by the framework if it wants to show a context menu for the margin. */ -- (NSMenu*) menuForEvent: (NSEvent*) theEvent -{ - NSMenu *menu = [owner menuForEvent: theEvent]; - if (menu) { - return menu; - } else if (owner.backend->ShouldDisplayPopupOnMargin()) { - return owner.backend->CreateContextMenu(theEvent); - } else { - return nil; - } +- (NSMenu *) menuForEvent: (NSEvent *) theEvent { + NSMenu *menu = [owner menuForEvent: theEvent]; + if (menu) { + return menu; + } else if (owner.backend->ShouldDisplayPopupOnMargin()) { + return owner.backend->CreateContextMenu(theEvent); + } else { + return nil; + } } -- (void) mouseDown: (NSEvent *) theEvent -{ - NSClipView *textView = self.scrollView.contentView; - [textView.window makeFirstResponder:textView]; - owner.backend->MouseDown(theEvent); +- (void) mouseDown: (NSEvent *) theEvent { + NSClipView *textView = self.scrollView.contentView; + [textView.window makeFirstResponder: textView]; + owner.backend->MouseDown(theEvent); } -- (void) rightMouseDown: (NSEvent *) theEvent -{ - [NSMenu popUpContextMenu:[self menuForEvent: theEvent] withEvent:theEvent forView:self]; +- (void) rightMouseDown: (NSEvent *) theEvent { + [NSMenu popUpContextMenu: [self menuForEvent: theEvent] withEvent: theEvent forView: self]; - owner.backend->RightMouseDown(theEvent); + owner.backend->RightMouseDown(theEvent); } -- (void) mouseDragged: (NSEvent *) theEvent -{ - owner.backend->MouseMove(theEvent); +- (void) mouseDragged: (NSEvent *) theEvent { + owner.backend->MouseMove(theEvent); } -- (void) mouseMoved: (NSEvent *) theEvent -{ - owner.backend->MouseMove(theEvent); +- (void) mouseMoved: (NSEvent *) theEvent { + owner.backend->MouseMove(theEvent); } -- (void) mouseUp: (NSEvent *) theEvent -{ - owner.backend->MouseUp(theEvent); +- (void) mouseUp: (NSEvent *) theEvent { + owner.backend->MouseUp(theEvent); } // Not a simple button so return failure -- (BOOL)accessibilityPerformPress -{ - return NO; +- (BOOL) accessibilityPerformPress { + return NO; } /** * This method is called to give us the opportunity to define our mouse sensitive rectangle. */ -- (void) resetCursorRects -{ - [super resetCursorRects]; - - int x = 0; - NSRect marginRect = self.bounds; - size_t co = currentCursors.count; - for (size_t i=0; i<co; i++) - { - long cursType = owner.backend->WndProc(SCI_GETMARGINCURSORN, i, 0); - long width =owner.backend->WndProc(SCI_GETMARGINWIDTHN, i, 0); - NSCursor *cc = cursorFromEnum(static_cast<Window::Cursor>(cursType)); - currentCursors[i] = cc; - marginRect.origin.x = x; - marginRect.size.width = width; - [self addCursorRect: marginRect cursor: cc]; - [cc setOnMouseEntered: YES]; - x += width; - } +- (void) resetCursorRects { + [super resetCursorRects]; + + int x = 0; + NSRect marginRect = self.bounds; + size_t co = currentCursors.count; + for (size_t i=0; i<co; i++) { + long cursType = owner.backend->WndProc(SCI_GETMARGINCURSORN, i, 0); + long width =owner.backend->WndProc(SCI_GETMARGINWIDTHN, i, 0); + NSCursor *cc = cursorFromEnum(static_cast<Window::Cursor>(cursType)); + currentCursors[i] = cc; + marginRect.origin.x = x; + marginRect.size.width = width; + [self addCursorRect: marginRect cursor: cc]; + [cc setOnMouseEntered: YES]; + x += width; + } } @end // Add owner property as a private category. -@interface SCIContentView () -@property (nonatomic, weak) ScintillaView* owner; +@interface SCIContentView() +@property(nonatomic, weak) ScintillaView *owner; @end @implementation SCIContentView { - ScintillaView* __weak mOwner; - NSCursor* mCurrentCursor; - NSTrackingArea *trackingArea; + ScintillaView *__weak mOwner; + NSCursor *mCurrentCursor; + NSTrackingArea *trackingArea; - // Set when we are in composition mode and partial input is displayed. - NSRange mMarkedTextRange; + // Set when we are in composition mode and partial input is displayed. + NSRange mMarkedTextRange; } @synthesize owner = mOwner; //-------------------------------------------------------------------------------------------------- -- (NSView*) initWithFrame: (NSRect) frame -{ - self = [super initWithFrame: frame]; +- (NSView *) initWithFrame: (NSRect) frame { + self = [super initWithFrame: frame]; - if (self != nil) - { - // Some initialization for our view. - mCurrentCursor = [NSCursor arrowCursor]; - trackingArea = nil; - mMarkedTextRange = NSMakeRange(NSNotFound, 0); + if (self != nil) { + // Some initialization for our view. + mCurrentCursor = [NSCursor arrowCursor]; + trackingArea = nil; + mMarkedTextRange = NSMakeRange(NSNotFound, 0); - [self registerForDraggedTypes: @[NSStringPboardType, ScintillaRecPboardType, NSFilenamesPboardType]]; + [self registerForDraggedTypes: @[NSStringPboardType, ScintillaRecPboardType, NSFilenamesPboardType]]; - // Set up accessibility in the text role - if ([self respondsToSelector: @selector(setAccessibilityElement:)]) - { - self.accessibilityElement = TRUE; - self.accessibilityEnabled = TRUE; - self.accessibilityLabel = NSLocalizedString(@"Scintilla", nil); // No real localization - self.accessibilityRoleDescription = @"source code editor"; - self.accessibilityRole = NSAccessibilityTextAreaRole; - self.accessibilityIdentifier = @"Scintilla"; - } - } + // Set up accessibility in the text role + if ([self respondsToSelector: @selector(setAccessibilityElement:)]) { + self.accessibilityElement = TRUE; + self.accessibilityEnabled = TRUE; + self.accessibilityLabel = NSLocalizedString(@"Scintilla", nil); // No real localization + self.accessibilityRoleDescription = @"source code editor"; + self.accessibilityRole = NSAccessibilityTextAreaRole; + self.accessibilityIdentifier = @"Scintilla"; + } + } - return self; + return self; } //-------------------------------------------------------------------------------------------------- @@ -239,20 +219,18 @@ static NSCursor *cursorFromEnum(Window::Cursor cursor) /** * When the view is resized or scrolled we need to update our tracking area. */ -- (void) updateTrackingAreas -{ - if (trackingArea) - { - [self removeTrackingArea:trackingArea]; - } +- (void) updateTrackingAreas { + if (trackingArea) { + [self removeTrackingArea: trackingArea]; + } - int opts = (NSTrackingActiveAlways | NSTrackingInVisibleRect | NSTrackingMouseEnteredAndExited | NSTrackingMouseMoved); - trackingArea = [[NSTrackingArea alloc] initWithRect:self.bounds - options:opts - owner:self - userInfo:nil]; - [self addTrackingArea: trackingArea]; - [super updateTrackingAreas]; + int opts = (NSTrackingActiveAlways | NSTrackingInVisibleRect | NSTrackingMouseEnteredAndExited | NSTrackingMouseMoved); + trackingArea = [[NSTrackingArea alloc] initWithRect: self.bounds + options: opts + owner: self + userInfo: nil]; + [self addTrackingArea: trackingArea]; + [super updateTrackingAreas]; } //-------------------------------------------------------------------------------------------------- @@ -260,11 +238,10 @@ static NSCursor *cursorFromEnum(Window::Cursor cursor) /** * When the view is resized we need to let the backend know. */ -- (void) setFrame: (NSRect) frame -{ - super.frame = frame; +- (void) setFrame: (NSRect) frame { + super.frame = frame; - mOwner.backend->Resize(); + mOwner.backend->Resize(); } //-------------------------------------------------------------------------------------------------- @@ -272,14 +249,13 @@ static NSCursor *cursorFromEnum(Window::Cursor cursor) /** * Called by the backend if a new cursor must be set for the view. */ -- (void) setCursor: (int) cursor -{ - Window::Cursor eCursor = (Window::Cursor)cursor; - mCurrentCursor = cursorFromEnum(eCursor); +- (void) setCursor: (int) cursor { + Window::Cursor eCursor = (Window::Cursor)cursor; + mCurrentCursor = cursorFromEnum(eCursor); - // Trigger recreation of the cursor rectangle(s). - [self.window invalidateCursorRectsForView: self]; - [mOwner updateMarginCursors]; + // Trigger recreation of the cursor rectangle(s). + [self.window invalidateCursorRectsForView: self]; + [mOwner updateMarginCursors]; } //-------------------------------------------------------------------------------------------------- @@ -287,14 +263,13 @@ static NSCursor *cursorFromEnum(Window::Cursor cursor) /** * This method is called to give us the opportunity to define our mouse sensitive rectangle. */ -- (void) resetCursorRects -{ - [super resetCursorRects]; +- (void) resetCursorRects { + [super resetCursorRects]; - // We only have one cursor rect: our bounds. - const NSRect visibleBounds = mOwner.backend->GetBounds(); - [self addCursorRect: visibleBounds cursor: mCurrentCursor]; - [mCurrentCursor setOnMouseEntered: YES]; + // We only have one cursor rect: our bounds. + const NSRect visibleBounds = mOwner.backend->GetBounds(); + [self addCursorRect: visibleBounds cursor: mCurrentCursor]; + [mCurrentCursor setOnMouseEntered: YES]; } //-------------------------------------------------------------------------------------------------- @@ -302,24 +277,23 @@ static NSCursor *cursorFromEnum(Window::Cursor cursor) /** * Called before repainting. */ -- (void) viewWillDraw -{ - if (!mOwner) { - [super viewWillDraw]; - return; - } +- (void) viewWillDraw { + if (!mOwner) { + [super viewWillDraw]; + return; + } - const NSRect *rects; - NSInteger nRects = 0; - [self getRectsBeingDrawn:&rects count:&nRects]; - if (nRects > 0) { - NSRect rectUnion = rects[0]; - for (int i=0;i<nRects;i++) { - rectUnion = NSUnionRect(rectUnion, rects[i]); - } - mOwner.backend->WillDraw(rectUnion); - } - [super viewWillDraw]; + const NSRect *rects; + NSInteger nRects = 0; + [self getRectsBeingDrawn: &rects count: &nRects]; + if (nRects > 0) { + NSRect rectUnion = rects[0]; + for (int i=0; i<nRects; i++) { + rectUnion = NSUnionRect(rectUnion, rects[i]); + } + mOwner.backend->WillDraw(rectUnion); + } + [super viewWillDraw]; } //-------------------------------------------------------------------------------------------------- @@ -327,12 +301,11 @@ static NSCursor *cursorFromEnum(Window::Cursor cursor) /** * Called before responsive scrolling overdraw. */ -- (void) prepareContentInRect: (NSRect) rect -{ - if (mOwner) - mOwner.backend->WillDraw(rect); +- (void) prepareContentInRect: (NSRect) rect { + if (mOwner) + mOwner.backend->WillDraw(rect); #if MAC_OS_X_VERSION_MAX_ALLOWED > 1080 - [super prepareContentInRect: rect]; + [super prepareContentInRect: rect]; #endif } @@ -341,15 +314,14 @@ static NSCursor *cursorFromEnum(Window::Cursor cursor) /** * Gets called by the runtime when the view needs repainting. */ -- (void) drawRect: (NSRect) rect -{ - CGContextRef context = (CGContextRef) [NSGraphicsContext currentContext].graphicsPort; +- (void) drawRect: (NSRect) rect { + CGContextRef context = (CGContextRef) [NSGraphicsContext currentContext].graphicsPort; - if (!mOwner.backend->Draw(rect, context)) { - dispatch_async(dispatch_get_main_queue(), ^{ - [self setNeedsDisplay:YES]; - }); - } + if (!mOwner.backend->Draw(rect, context)) { + dispatch_async(dispatch_get_main_queue(), ^ { + [self setNeedsDisplay: YES]; + }); + } } //-------------------------------------------------------------------------------------------------- @@ -361,16 +333,14 @@ static NSCursor *cursorFromEnum(Window::Cursor cursor) * Note that because of returning YES here most coordinates we use now (e.g. for painting, * invalidating rectangles etc.) are given with +Y pointing down! */ -- (BOOL) isFlipped -{ - return YES; +- (BOOL) isFlipped { + return YES; } //-------------------------------------------------------------------------------------------------- -- (BOOL) isOpaque -{ - return YES; +- (BOOL) isOpaque { + return YES; } //-------------------------------------------------------------------------------------------------- @@ -378,10 +348,9 @@ static NSCursor *cursorFromEnum(Window::Cursor cursor) /** * Implement the "click through" behavior by telling the caller we accept the first mouse event too. */ -- (BOOL) acceptsFirstMouse: (NSEvent *) theEvent -{ +- (BOOL) acceptsFirstMouse: (NSEvent *) theEvent { #pragma unused(theEvent) - return YES; + return YES; } //-------------------------------------------------------------------------------------------------- @@ -389,9 +358,8 @@ static NSCursor *cursorFromEnum(Window::Cursor cursor) /** * Make this view accepting events as first responder. */ -- (BOOL) acceptsFirstResponder -{ - return YES; +- (BOOL) acceptsFirstResponder { + return YES; } //-------------------------------------------------------------------------------------------------- @@ -399,115 +367,105 @@ static NSCursor *cursorFromEnum(Window::Cursor cursor) /** * Called by the framework if it wants to show a context menu for the editor. */ -- (NSMenu*) menuForEvent: (NSEvent*) theEvent -{ - NSMenu *menu = [mOwner menuForEvent: theEvent]; - if (menu) { - return menu; - } else if (mOwner.backend->ShouldDisplayPopupOnText()) { - return mOwner.backend->CreateContextMenu(theEvent); - } else { - return nil; - } +- (NSMenu *) menuForEvent: (NSEvent *) theEvent { + NSMenu *menu = [mOwner menuForEvent: theEvent]; + if (menu) { + return menu; + } else if (mOwner.backend->ShouldDisplayPopupOnText()) { + return mOwner.backend->CreateContextMenu(theEvent); + } else { + return nil; + } } //-------------------------------------------------------------------------------------------------- // Adoption of NSTextInputClient protocol. -- (NSAttributedString *)attributedSubstringForProposedRange:(NSRange)aRange actualRange:(NSRangePointer)actualRange -{ - const NSInteger lengthCharacters = self.accessibilityNumberOfCharacters; - if (aRange.location > lengthCharacters) { - return nil; - } - const NSRange posRange = mOwner.backend->PositionsFromCharacters(aRange); - // The backend validated aRange and may have removed characters beyond the end of the document. - const NSRange charRange = mOwner.backend->CharactersFromPositions(posRange); - if (!NSEqualRanges(aRange, charRange)) - { - *actualRange = charRange; - } - - [mOwner message: SCI_SETTARGETRANGE wParam: posRange.location lParam: NSMaxRange(posRange)]; - std::string text([mOwner message: SCI_TARGETASUTF8] + 1, 0); - [mOwner message: SCI_TARGETASUTF8 wParam: 0 lParam: reinterpret_cast<sptr_t>(&text[0])]; - text = FixInvalidUTF8(text); - NSString *result = @(text.c_str()); - NSMutableAttributedString *asResult = [[NSMutableAttributedString alloc] initWithString:result]; - - const NSRange rangeAS = NSMakeRange(0, asResult.length); - // SCI_GETSTYLEAT reports a signed byte but want an unsigned to index into styles - const char styleByte = static_cast<char>([mOwner message: SCI_GETSTYLEAT wParam:posRange.location]); - const long style = static_cast<unsigned char>(styleByte); - std::string fontName([mOwner message: SCI_STYLEGETFONT wParam:style lParam:0] + 1, 0); - [mOwner message: SCI_STYLEGETFONT wParam:style lParam:(sptr_t)&fontName[0]]; - const CGFloat fontSize = [mOwner message: SCI_STYLEGETSIZEFRACTIONAL wParam:style] / 100.0f; - NSString *sFontName = @(fontName.c_str()); - NSFont *font = [NSFont fontWithName:sFontName size:fontSize]; - [asResult addAttribute:NSFontAttributeName value:font range:rangeAS]; - - return asResult; -} - -//-------------------------------------------------------------------------------------------------- - -- (NSUInteger) characterIndexForPoint: (NSPoint) point -{ - const NSRect rectPoint = {point, NSZeroSize}; - const NSRect rectInWindow = [self.window convertRectFromScreen:rectPoint]; - const NSRect rectLocal = [self.superview.superview convertRect:rectInWindow fromView:nil]; - - const long position = [mOwner message: SCI_CHARPOSITIONFROMPOINT - wParam: rectLocal.origin.x - lParam: rectLocal.origin.y]; - if (position == INVALID_POSITION) - { - return NSNotFound; - } - else - { - const NSRange index = mOwner.backend->CharactersFromPositions(NSMakeRange(position, 0)); - return index.location; - } -} - -//-------------------------------------------------------------------------------------------------- - -- (void) doCommandBySelector: (SEL) selector -{ +- (NSAttributedString *) attributedSubstringForProposedRange: (NSRange) aRange actualRange: (NSRangePointer) actualRange { + const NSInteger lengthCharacters = self.accessibilityNumberOfCharacters; + if (aRange.location > lengthCharacters) { + return nil; + } + const NSRange posRange = mOwner.backend->PositionsFromCharacters(aRange); + // The backend validated aRange and may have removed characters beyond the end of the document. + const NSRange charRange = mOwner.backend->CharactersFromPositions(posRange); + if (!NSEqualRanges(aRange, charRange)) { + *actualRange = charRange; + } + + [mOwner message: SCI_SETTARGETRANGE wParam: posRange.location lParam: NSMaxRange(posRange)]; + std::string text([mOwner message: SCI_TARGETASUTF8] + 1, 0); + [mOwner message: SCI_TARGETASUTF8 wParam: 0 lParam: reinterpret_cast<sptr_t>(&text[0])]; + text = FixInvalidUTF8(text); + NSString *result = @(text.c_str()); + NSMutableAttributedString *asResult = [[NSMutableAttributedString alloc] initWithString: result]; + + const NSRange rangeAS = NSMakeRange(0, asResult.length); + // SCI_GETSTYLEAT reports a signed byte but want an unsigned to index into styles + const char styleByte = static_cast<char>([mOwner message: SCI_GETSTYLEAT wParam: posRange.location]); + const long style = static_cast<unsigned char>(styleByte); + std::string fontName([mOwner message: SCI_STYLEGETFONT wParam: style lParam: 0] + 1, 0); + [mOwner message: SCI_STYLEGETFONT wParam: style lParam: (sptr_t)&fontName[0]]; + const CGFloat fontSize = [mOwner message: SCI_STYLEGETSIZEFRACTIONAL wParam: style] / 100.0f; + NSString *sFontName = @(fontName.c_str()); + NSFont *font = [NSFont fontWithName: sFontName size: fontSize]; + [asResult addAttribute: NSFontAttributeName value: font range: rangeAS]; + + return asResult; +} + +//-------------------------------------------------------------------------------------------------- + +- (NSUInteger) characterIndexForPoint: (NSPoint) point { + const NSRect rectPoint = {point, NSZeroSize}; + const NSRect rectInWindow = [self.window convertRectFromScreen: rectPoint]; + const NSRect rectLocal = [self.superview.superview convertRect: rectInWindow fromView: nil]; + + const long position = [mOwner message: SCI_CHARPOSITIONFROMPOINT + wParam: rectLocal.origin.x + lParam: rectLocal.origin.y]; + if (position == INVALID_POSITION) { + return NSNotFound; + } else { + const NSRange index = mOwner.backend->CharactersFromPositions(NSMakeRange(position, 0)); + return index.location; + } +} + +//-------------------------------------------------------------------------------------------------- + +- (void) doCommandBySelector: (SEL) selector { #pragma clang diagnostic push #pragma clang diagnostic ignored "-Warc-performSelector-leaks" - if ([self respondsToSelector: @selector(selector)]) - [self performSelector: selector withObject: nil]; + if ([self respondsToSelector: @selector(selector)]) + [self performSelector: selector withObject: nil]; #pragma clang diagnostic pop } //-------------------------------------------------------------------------------------------------- -- (NSRect) firstRectForCharacterRange: (NSRange) aRange actualRange: (NSRangePointer) actualRange -{ +- (NSRect) firstRectForCharacterRange: (NSRange) aRange actualRange: (NSRangePointer) actualRange { #pragma unused(actualRange) - const NSRange posRange = mOwner.backend->PositionsFromCharacters(aRange); + const NSRange posRange = mOwner.backend->PositionsFromCharacters(aRange); - NSRect rect; - rect.origin.x = [mOwner message: SCI_POINTXFROMPOSITION wParam: 0 lParam: posRange.location]; - rect.origin.y = [mOwner message: SCI_POINTYFROMPOSITION wParam: 0 lParam: posRange.location]; - const NSUInteger rangeEnd = NSMaxRange(posRange); - rect.size.width = [mOwner message: SCI_POINTXFROMPOSITION wParam: 0 lParam: rangeEnd] - rect.origin.x; - rect.size.height = [mOwner message: SCI_POINTYFROMPOSITION wParam: 0 lParam: rangeEnd] - rect.origin.y; - rect.size.height += [mOwner message: SCI_TEXTHEIGHT wParam: 0 lParam: 0]; - const NSRect rectInWindow = [self.superview.superview convertRect:rect toView:nil]; - const NSRect rectScreen = [self.window convertRectToScreen:rectInWindow]; + NSRect rect; + rect.origin.x = [mOwner message: SCI_POINTXFROMPOSITION wParam: 0 lParam: posRange.location]; + rect.origin.y = [mOwner message: SCI_POINTYFROMPOSITION wParam: 0 lParam: posRange.location]; + const NSUInteger rangeEnd = NSMaxRange(posRange); + rect.size.width = [mOwner message: SCI_POINTXFROMPOSITION wParam: 0 lParam: rangeEnd] - rect.origin.x; + rect.size.height = [mOwner message: SCI_POINTYFROMPOSITION wParam: 0 lParam: rangeEnd] - rect.origin.y; + rect.size.height += [mOwner message: SCI_TEXTHEIGHT wParam: 0 lParam: 0]; + const NSRect rectInWindow = [self.superview.superview convertRect: rect toView: nil]; + const NSRect rectScreen = [self.window convertRectToScreen: rectInWindow]; - return rectScreen; + return rectScreen; } //-------------------------------------------------------------------------------------------------- -- (BOOL) hasMarkedText -{ - return mMarkedTextRange.length > 0; +- (BOOL) hasMarkedText { + return mMarkedTextRange.length > 0; } //-------------------------------------------------------------------------------------------------- @@ -517,17 +475,14 @@ static NSCursor *cursorFromEnum(Window::Cursor cursor) * selection if there is any. * First removes the replacementRange. */ -- (void) insertText: (id) aString replacementRange: (NSRange) replacementRange -{ - if ((mMarkedTextRange.location != NSNotFound) && (replacementRange.location != NSNotFound)) - { +- (void) insertText: (id) aString replacementRange: (NSRange) replacementRange { + if ((mMarkedTextRange.location != NSNotFound) && (replacementRange.location != NSNotFound)) { NSLog(@"Trying to insertText when there is both a marked range and a replacement range"); } // Remove any previously marked text first. mOwner.backend->CompositionUndo(); - if (mMarkedTextRange.location != NSNotFound) - { + if (mMarkedTextRange.location != NSNotFound) { const NSRange posRangeMark = mOwner.backend->PositionsFromCharacters(mMarkedTextRange); [mOwner message: SCI_SETEMPTYSELECTION wParam: posRangeMark.location]; } @@ -538,8 +493,7 @@ static NSCursor *cursorFromEnum(Window::Cursor cursor) // Its replacing a non-existent position so do nothing. return; - if (replacementRange.location != NSNotFound) - { + if (replacementRange.location != NSNotFound) { const NSRange posRangeReplacement = mOwner.backend->PositionsFromCharacters(replacementRange); [mOwner message: SCI_DELETERANGE wParam: posRangeReplacement.location @@ -547,42 +501,38 @@ static NSCursor *cursorFromEnum(Window::Cursor cursor) [mOwner message: SCI_SETEMPTYSELECTION wParam: posRangeReplacement.location]; } - NSString* newText = @""; - if ([aString isKindOfClass:[NSString class]]) - newText = (NSString*) aString; - else if ([aString isKindOfClass:[NSAttributedString class]]) - newText = (NSString*) [aString string]; + NSString *newText = @""; + if ([aString isKindOfClass: [NSString class]]) + newText = (NSString *) aString; + else if ([aString isKindOfClass: [NSAttributedString class]]) + newText = (NSString *) [aString string]; mOwner.backend->InsertText(newText); } //-------------------------------------------------------------------------------------------------- -- (NSRange) markedRange -{ - return mMarkedTextRange; +- (NSRange) markedRange { + return mMarkedTextRange; } //-------------------------------------------------------------------------------------------------- -- (NSRange) selectedRange -{ - const NSRange posRangeSel = [mOwner selectedRangePositions]; - if (posRangeSel.length == 0) - { - NSTextInputContext *tic = [NSTextInputContext currentInputContext]; - // Chinese input causes malloc crash when empty selection returned with actual - // position so return NSNotFound. - // If this is applied to European input, it stops the accented character - // chooser from appearing. - // May need to add more input source names. - if ([tic.selectedKeyboardInputSource - isEqualToString:@"com.apple.inputmethod.TCIM.Cangjie"]) - { - return NSMakeRange(NSNotFound, 0); - } - } - return mOwner.backend->CharactersFromPositions(posRangeSel); +- (NSRange) selectedRange { + const NSRange posRangeSel = [mOwner selectedRangePositions]; + if (posRangeSel.length == 0) { + NSTextInputContext *tic = [NSTextInputContext currentInputContext]; + // Chinese input causes malloc crash when empty selection returned with actual + // position so return NSNotFound. + // If this is applied to European input, it stops the accented character + // chooser from appearing. + // May need to add more input source names. + if ([tic.selectedKeyboardInputSource + isEqualToString: @"com.apple.inputmethod.TCIM.Cangjie"]) { + return NSMakeRange(NSNotFound, 0); + } + } + return mOwner.backend->CharactersFromPositions(posRangeSel); } //-------------------------------------------------------------------------------------------------- @@ -596,114 +546,96 @@ static NSCursor *cursorFromEnum(Window::Cursor cursor) * @param range The range of the new text to select (given relative to the insertion point of the new text). * @param replacementRange The range to remove before insertion. */ -- (void) setMarkedText: (id) aString selectedRange: (NSRange)range replacementRange: (NSRange)replacementRange -{ - NSString* newText = @""; - if ([aString isKindOfClass:[NSString class]]) - newText = (NSString*) aString; - else - if ([aString isKindOfClass:[NSAttributedString class]]) - newText = (NSString*) [aString string]; - - // Replace marked text if there is one. - if (mMarkedTextRange.length > 0) - { - mOwner.backend->CompositionUndo(); - if (replacementRange.location != NSNotFound) - { - // This situation makes no sense and has not occurred in practice. - NSLog(@"Can not handle a replacement range when there is also a marked range"); - } - else - { - replacementRange = mMarkedTextRange; - const NSRange posRangeMark = mOwner.backend->PositionsFromCharacters(mMarkedTextRange); - [mOwner message: SCI_SETEMPTYSELECTION wParam: posRangeMark.location]; - } - } - else - { - // Must perform deletion before entering composition mode or else - // both document and undo history will not contain the deleted text - // leading to an inaccurate and unusable undo history. - - // Convert selection virtual space into real space - mOwner.backend->ConvertSelectionVirtualSpace(); - - if (replacementRange.location != NSNotFound) - { - const NSRange posRangeReplacement = mOwner.backend->PositionsFromCharacters(replacementRange); - [mOwner message: SCI_DELETERANGE - wParam: posRangeReplacement.location - lParam: posRangeReplacement.length]; - } - else // No marked or replacement range, so replace selection - { - if (!mOwner.backend->ScintillaCocoa::ClearAllSelections()) { - // Some of the selection is protected so can not perform composition here - return; - } - // Ensure only a single selection. - mOwner.backend->SelectOnlyMainSelection(); - const NSRange posRangeSel = [mOwner selectedRangePositions]; - replacementRange = mOwner.backend->CharactersFromPositions(posRangeSel); - } - } - - // To support IME input to multiple selections, the following code would - // need to insert newText at each selection, mark each piece of new text and then - // select range relative to each insertion. - - if (newText.length) - { - // Switching into composition. - mOwner.backend->CompositionStart(); - - NSRange posRangeCurrent = mOwner.backend->PositionsFromCharacters(NSMakeRange(replacementRange.location, 0)); - // Note: Scintilla internally works almost always with bytes instead chars, so we need to take - // this into account when determining selection ranges and such. - int lengthInserted = mOwner.backend->InsertText(newText); - posRangeCurrent.length = lengthInserted; - mMarkedTextRange = mOwner.backend->CharactersFromPositions(posRangeCurrent); - // Mark the just inserted text. Keep the marked range for later reset. - [mOwner setGeneralProperty: SCI_SETINDICATORCURRENT value: INDIC_IME]; - [mOwner setGeneralProperty: SCI_INDICATORFILLRANGE - parameter: posRangeCurrent.location - value: posRangeCurrent.length]; - } - else - { - mMarkedTextRange = NSMakeRange(NSNotFound, 0); - // Re-enable undo action collection if composition ended (indicated by an empty mark string). - mOwner.backend->CompositionCommit(); - } - - // Select the part which is indicated in the given range. It does not scroll the caret into view. - if (range.length > 0) - { - // range is in characters so convert to bytes for selection. - range.location += replacementRange.location; - NSRange posRangeSelect = mOwner.backend->PositionsFromCharacters(range); - [mOwner setGeneralProperty: SCI_SETSELECTION parameter: NSMaxRange(posRangeSelect) value: posRangeSelect.location]; - } -} - -//-------------------------------------------------------------------------------------------------- - -- (void) unmarkText -{ - if (mMarkedTextRange.length > 0) - { - mOwner.backend->CompositionCommit(); - mMarkedTextRange = NSMakeRange(NSNotFound, 0); - } -} - -//-------------------------------------------------------------------------------------------------- - -- (NSArray*) validAttributesForMarkedText -{ - return @[]; +- (void) setMarkedText: (id) aString selectedRange: (NSRange) range replacementRange: (NSRange) replacementRange { + NSString *newText = @""; + if ([aString isKindOfClass: [NSString class]]) + newText = (NSString *) aString; + else if ([aString isKindOfClass: [NSAttributedString class]]) + newText = (NSString *) [aString string]; + + // Replace marked text if there is one. + if (mMarkedTextRange.length > 0) { + mOwner.backend->CompositionUndo(); + if (replacementRange.location != NSNotFound) { + // This situation makes no sense and has not occurred in practice. + NSLog(@"Can not handle a replacement range when there is also a marked range"); + } else { + replacementRange = mMarkedTextRange; + const NSRange posRangeMark = mOwner.backend->PositionsFromCharacters(mMarkedTextRange); + [mOwner message: SCI_SETEMPTYSELECTION wParam: posRangeMark.location]; + } + } else { + // Must perform deletion before entering composition mode or else + // both document and undo history will not contain the deleted text + // leading to an inaccurate and unusable undo history. + + // Convert selection virtual space into real space + mOwner.backend->ConvertSelectionVirtualSpace(); + + if (replacementRange.location != NSNotFound) { + const NSRange posRangeReplacement = mOwner.backend->PositionsFromCharacters(replacementRange); + [mOwner message: SCI_DELETERANGE + wParam: posRangeReplacement.location + lParam: posRangeReplacement.length]; + } else { // No marked or replacement range, so replace selection + if (!mOwner.backend->ScintillaCocoa::ClearAllSelections()) { + // Some of the selection is protected so can not perform composition here + return; + } + // Ensure only a single selection. + mOwner.backend->SelectOnlyMainSelection(); + const NSRange posRangeSel = [mOwner selectedRangePositions]; + replacementRange = mOwner.backend->CharactersFromPositions(posRangeSel); + } + } + + // To support IME input to multiple selections, the following code would + // need to insert newText at each selection, mark each piece of new text and then + // select range relative to each insertion. + + if (newText.length) { + // Switching into composition. + mOwner.backend->CompositionStart(); + + NSRange posRangeCurrent = mOwner.backend->PositionsFromCharacters(NSMakeRange(replacementRange.location, 0)); + // Note: Scintilla internally works almost always with bytes instead chars, so we need to take + // this into account when determining selection ranges and such. + int lengthInserted = mOwner.backend->InsertText(newText); + posRangeCurrent.length = lengthInserted; + mMarkedTextRange = mOwner.backend->CharactersFromPositions(posRangeCurrent); + // Mark the just inserted text. Keep the marked range for later reset. + [mOwner setGeneralProperty: SCI_SETINDICATORCURRENT value: INDIC_IME]; + [mOwner setGeneralProperty: SCI_INDICATORFILLRANGE + parameter: posRangeCurrent.location + value: posRangeCurrent.length]; + } else { + mMarkedTextRange = NSMakeRange(NSNotFound, 0); + // Re-enable undo action collection if composition ended (indicated by an empty mark string). + mOwner.backend->CompositionCommit(); + } + + // Select the part which is indicated in the given range. It does not scroll the caret into view. + if (range.length > 0) { + // range is in characters so convert to bytes for selection. + range.location += replacementRange.location; + NSRange posRangeSelect = mOwner.backend->PositionsFromCharacters(range); + [mOwner setGeneralProperty: SCI_SETSELECTION parameter: NSMaxRange(posRangeSelect) value: posRangeSelect.location]; + } +} + +//-------------------------------------------------------------------------------------------------- + +- (void) unmarkText { + if (mMarkedTextRange.length > 0) { + mOwner.backend->CompositionCommit(); + mMarkedTextRange = NSMakeRange(NSNotFound, 0); + } +} + +//-------------------------------------------------------------------------------------------------- + +- (NSArray *) validAttributesForMarkedText { + return @[]; } // End of the NSTextInputClient protocol adoption. @@ -715,54 +647,47 @@ static NSCursor *cursorFromEnum(Window::Cursor cursor) * handles shortcuts. The input is then forwarded to the Cocoa text input system, which in turn does * its own input handling (character composition via NSTextInputClient protocol): */ -- (void) keyDown: (NSEvent *) theEvent -{ - if (mMarkedTextRange.length == 0) - mOwner.backend->KeyboardInput(theEvent); - NSArray* events = @[theEvent]; - [self interpretKeyEvents: events]; +- (void) keyDown: (NSEvent *) theEvent { + if (mMarkedTextRange.length == 0) + mOwner.backend->KeyboardInput(theEvent); + NSArray *events = @[theEvent]; + [self interpretKeyEvents: events]; } //-------------------------------------------------------------------------------------------------- -- (void) mouseDown: (NSEvent *) theEvent -{ - mOwner.backend->MouseDown(theEvent); +- (void) mouseDown: (NSEvent *) theEvent { + mOwner.backend->MouseDown(theEvent); } //-------------------------------------------------------------------------------------------------- -- (void) mouseDragged: (NSEvent *) theEvent -{ - mOwner.backend->MouseMove(theEvent); +- (void) mouseDragged: (NSEvent *) theEvent { + mOwner.backend->MouseMove(theEvent); } //-------------------------------------------------------------------------------------------------- -- (void) mouseUp: (NSEvent *) theEvent -{ - mOwner.backend->MouseUp(theEvent); +- (void) mouseUp: (NSEvent *) theEvent { + mOwner.backend->MouseUp(theEvent); } //-------------------------------------------------------------------------------------------------- -- (void) mouseMoved: (NSEvent *) theEvent -{ - mOwner.backend->MouseMove(theEvent); +- (void) mouseMoved: (NSEvent *) theEvent { + mOwner.backend->MouseMove(theEvent); } //-------------------------------------------------------------------------------------------------- -- (void) mouseEntered: (NSEvent *) theEvent -{ - mOwner.backend->MouseEntered(theEvent); +- (void) mouseEntered: (NSEvent *) theEvent { + mOwner.backend->MouseEntered(theEvent); } //-------------------------------------------------------------------------------------------------- -- (void) mouseExited: (NSEvent *) theEvent -{ - mOwner.backend->MouseExited(theEvent); +- (void) mouseExited: (NSEvent *) theEvent { + mOwner.backend->MouseExited(theEvent); } //-------------------------------------------------------------------------------------------------- @@ -774,13 +699,12 @@ static NSCursor *cursorFromEnum(Window::Cursor cursor) * Pinch gestures and key commands can be used for magnification. */ #ifdef SCROLL_WHEEL_MAGNIFICATION -- (void) scrollWheel: (NSEvent *) theEvent -{ - if (([theEvent modifierFlags] & NSCommandKeyMask) != 0) { - mOwner.backend->MouseWheel(theEvent); - } else { - [super scrollWheel:theEvent]; - } +- (void) scrollWheel: (NSEvent *) theEvent { + if (([theEvent modifierFlags] & NSCommandKeyMask) != 0) { + mOwner.backend->MouseWheel(theEvent); + } else { + [super scrollWheel: theEvent]; + } } #endif @@ -789,20 +713,19 @@ static NSCursor *cursorFromEnum(Window::Cursor cursor) /** * Ensure scrolling is aligned to whole lines instead of starting part-way through a line */ -- (NSRect)adjustScroll:(NSRect)proposedVisibleRect -{ - if (!mOwner) - return proposedVisibleRect; - NSRect rc = proposedVisibleRect; - // Snap to lines - NSRect contentRect = self.bounds; - if ((rc.origin.y > 0) && (NSMaxY(rc) < contentRect.size.height)) { - // Only snap for positions inside the document - allow outside - // for overshoot. - long lineHeight = mOwner.backend->WndProc(SCI_TEXTHEIGHT, 0, 0); - rc.origin.y = roundf(static_cast<XYPOSITION>(rc.origin.y) / lineHeight) * lineHeight; - } - return rc; +- (NSRect) adjustScroll: (NSRect) proposedVisibleRect { + if (!mOwner) + return proposedVisibleRect; + NSRect rc = proposedVisibleRect; + // Snap to lines + NSRect contentRect = self.bounds; + if ((rc.origin.y > 0) && (NSMaxY(rc) < contentRect.size.height)) { + // Only snap for positions inside the document - allow outside + // for overshoot. + long lineHeight = mOwner.backend->WndProc(SCI_TEXTHEIGHT, 0, 0); + rc.origin.y = roundf(static_cast<XYPOSITION>(rc.origin.y) / lineHeight) * lineHeight; + } + return rc; } //-------------------------------------------------------------------------------------------------- @@ -810,10 +733,9 @@ static NSCursor *cursorFromEnum(Window::Cursor cursor) /** * The editor is getting the foreground control (the one getting the input focus). */ -- (BOOL) becomeFirstResponder -{ - mOwner.backend->WndProc(SCI_SETFOCUS, 1, 0); - return YES; +- (BOOL) becomeFirstResponder { + mOwner.backend->WndProc(SCI_SETFOCUS, 1, 0); + return YES; } //-------------------------------------------------------------------------------------------------- @@ -821,10 +743,9 @@ static NSCursor *cursorFromEnum(Window::Cursor cursor) /** * The editor is losing the input focus. */ -- (BOOL) resignFirstResponder -{ - mOwner.backend->WndProc(SCI_SETFOCUS, 0, 0); - return YES; +- (BOOL) resignFirstResponder { + mOwner.backend->WndProc(SCI_SETFOCUS, 0, 0); + return YES; } //-------------------------------------------------------------------------------------------------- @@ -833,36 +754,31 @@ static NSCursor *cursorFromEnum(Window::Cursor cursor) * Implement NSDraggingSource. */ -- (NSDragOperation)draggingSession: (NSDraggingSession *) session -sourceOperationMaskForDraggingContext: (NSDraggingContext) context -{ +- (NSDragOperation) draggingSession: (NSDraggingSession *) session + sourceOperationMaskForDraggingContext: (NSDraggingContext) context { #pragma unused(session) - switch(context) - { - case NSDraggingContextOutsideApplication: - return NSDragOperationCopy | NSDragOperationMove | NSDragOperationDelete; + switch (context) { + case NSDraggingContextOutsideApplication: + return NSDragOperationCopy | NSDragOperationMove | NSDragOperationDelete; - case NSDraggingContextWithinApplication: - default: - return NSDragOperationCopy | NSDragOperationMove | NSDragOperationDelete; - } + case NSDraggingContextWithinApplication: + default: + return NSDragOperationCopy | NSDragOperationMove | NSDragOperationDelete; + } } -- (void)draggingSession:(NSDraggingSession *)session - movedToPoint:(NSPoint)screenPoint -{ +- (void) draggingSession: (NSDraggingSession *) session + movedToPoint: (NSPoint) screenPoint { #pragma unused(session, screenPoint) } -- (void)draggingSession:(NSDraggingSession *)session - endedAtPoint:(NSPoint)screenPoint - operation:(NSDragOperation)operation -{ +- (void) draggingSession: (NSDraggingSession *) session + endedAtPoint: (NSPoint) screenPoint + operation: (NSDragOperation) operation { #pragma unused(session, screenPoint) - if (operation == NSDragOperationDelete) - { - mOwner.backend->WndProc(SCI_CLEAR, 0, 0); - } + if (operation == NSDragOperationDelete) { + mOwner.backend->WndProc(SCI_CLEAR, 0, 0); + } } /** @@ -874,9 +790,8 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context /** * Called when an external drag operation enters the view. */ -- (NSDragOperation) draggingEntered: (id <NSDraggingInfo>) sender -{ - return mOwner.backend->DraggingEntered(sender); +- (NSDragOperation) draggingEntered: (id <NSDraggingInfo>) sender { + return mOwner.backend->DraggingEntered(sender); } //-------------------------------------------------------------------------------------------------- @@ -884,9 +799,8 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context /** * Called frequently during an external drag operation if we are the target. */ -- (NSDragOperation) draggingUpdated: (id <NSDraggingInfo>) sender -{ - return mOwner.backend->DraggingUpdated(sender); +- (NSDragOperation) draggingUpdated: (id <NSDraggingInfo>) sender { + return mOwner.backend->DraggingUpdated(sender); } //-------------------------------------------------------------------------------------------------- @@ -894,24 +808,21 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context /** * Drag image left the view. Clean up if necessary. */ -- (void) draggingExited: (id <NSDraggingInfo>) sender -{ - mOwner.backend->DraggingExited(sender); +- (void) draggingExited: (id <NSDraggingInfo>) sender { + mOwner.backend->DraggingExited(sender); } //-------------------------------------------------------------------------------------------------- -- (BOOL) prepareForDragOperation: (id <NSDraggingInfo>) sender -{ +- (BOOL) prepareForDragOperation: (id <NSDraggingInfo>) sender { #pragma unused(sender) - return YES; + return YES; } //-------------------------------------------------------------------------------------------------- -- (BOOL) performDragOperation: (id <NSDraggingInfo>) sender -{ - return mOwner.backend->PerformDragOperation(sender); +- (BOOL) performDragOperation: (id <NSDraggingInfo>) sender { + return mOwner.backend->PerformDragOperation(sender); } //-------------------------------------------------------------------------------------------------- @@ -919,106 +830,88 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context /** * Drag operation is done. Notify editor. */ -- (void) concludeDragOperation: (id <NSDraggingInfo>) sender -{ - // Clean up is the same as if we are no longer the drag target. - mOwner.backend->DraggingExited(sender); +- (void) concludeDragOperation: (id <NSDraggingInfo>) sender { + // Clean up is the same as if we are no longer the drag target. + mOwner.backend->DraggingExited(sender); } //-------------------------------------------------------------------------------------------------- // NSResponder actions. -- (void) selectAll: (id) sender -{ +- (void) selectAll: (id) sender { #pragma unused(sender) - mOwner.backend->SelectAll(); + mOwner.backend->SelectAll(); } -- (void) deleteBackward: (id) sender -{ +- (void) deleteBackward: (id) sender { #pragma unused(sender) - mOwner.backend->DeleteBackward(); + mOwner.backend->DeleteBackward(); } -- (void) cut: (id) sender -{ +- (void) cut: (id) sender { #pragma unused(sender) - mOwner.backend->Cut(); + mOwner.backend->Cut(); } -- (void) copy: (id) sender -{ +- (void) copy: (id) sender { #pragma unused(sender) - mOwner.backend->Copy(); + mOwner.backend->Copy(); } -- (void) paste: (id) sender -{ +- (void) paste: (id) sender { #pragma unused(sender) - if (mMarkedTextRange.location != NSNotFound) - { - [[NSTextInputContext currentInputContext] discardMarkedText]; - mOwner.backend->CompositionCommit(); - mMarkedTextRange = NSMakeRange(NSNotFound, 0); - } - mOwner.backend->Paste(); + if (mMarkedTextRange.location != NSNotFound) { + [[NSTextInputContext currentInputContext] discardMarkedText]; + mOwner.backend->CompositionCommit(); + mMarkedTextRange = NSMakeRange(NSNotFound, 0); + } + mOwner.backend->Paste(); } -- (void) undo: (id) sender -{ +- (void) undo: (id) sender { #pragma unused(sender) - if (mMarkedTextRange.location != NSNotFound) - { - [[NSTextInputContext currentInputContext] discardMarkedText]; - mOwner.backend->CompositionCommit(); - mMarkedTextRange = NSMakeRange(NSNotFound, 0); - } - mOwner.backend->Undo(); + if (mMarkedTextRange.location != NSNotFound) { + [[NSTextInputContext currentInputContext] discardMarkedText]; + mOwner.backend->CompositionCommit(); + mMarkedTextRange = NSMakeRange(NSNotFound, 0); + } + mOwner.backend->Undo(); } -- (void) redo: (id) sender -{ +- (void) redo: (id) sender { #pragma unused(sender) - mOwner.backend->Redo(); + mOwner.backend->Redo(); } -- (BOOL) canUndo -{ - return mOwner.backend->CanUndo() && (mMarkedTextRange.location == NSNotFound); +- (BOOL) canUndo { + return mOwner.backend->CanUndo() && (mMarkedTextRange.location == NSNotFound); } -- (BOOL) canRedo -{ - return mOwner.backend->CanRedo(); +- (BOOL) canRedo { + return mOwner.backend->CanRedo(); } -- (BOOL) validateUserInterfaceItem: (id <NSValidatedUserInterfaceItem>) anItem -{ - SEL action = anItem.action; - if (action==@selector(undo:)) { - return [self canUndo]; - } - else if (action==@selector(redo:)) { - return [self canRedo]; - } - else if (action==@selector(cut:) || action==@selector(copy:) || action==@selector(clear:)) { - return mOwner.backend->HasSelection(); - } - else if (action==@selector(paste:)) { - return mOwner.backend->CanPaste(); - } - return YES; +- (BOOL) validateUserInterfaceItem: (id <NSValidatedUserInterfaceItem>) anItem { + SEL action = anItem.action; + if (action==@selector(undo:)) { + return [self canUndo]; + } else if (action==@selector(redo:)) { + return [self canRedo]; + } else if (action==@selector(cut:) || action==@selector(copy:) || action==@selector(clear:)) { + return mOwner.backend->HasSelection(); + } else if (action==@selector(paste:)) { + return mOwner.backend->CanPaste(); + } + return YES; } -- (void) clear: (id) sender -{ - [self deleteBackward:sender]; +- (void) clear: (id) sender { + [self deleteBackward: sender]; } -- (BOOL) isEditable -{ - return mOwner.backend->WndProc(SCI_GETREADONLY, 0, 0) == 0; +- (BOOL) isEditable { + return mOwner.backend->WndProc(SCI_GETREADONLY, 0, 0) == 0; } #pragma mark - NSAccessibility @@ -1037,8 +930,8 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context * NSAccessibility : Text of the whole document as a string. */ - (id) accessibilityValue { - const sptr_t length = [mOwner message: SCI_GETLENGTH]; - return mOwner.backend->RangeTextAsString(NSMakeRange(0,static_cast<int>(length))); + const sptr_t length = [mOwner message: SCI_GETLENGTH]; + return mOwner.backend->RangeTextAsString(NSMakeRange(0, static_cast<int>(length))); } //-------------------------------------------------------------------------------------------------- @@ -1047,9 +940,9 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context * NSAccessibility : Line of the caret. */ - (NSInteger) accessibilityInsertionPointLineNumber { - const int caret = static_cast<int>([mOwner message: SCI_GETCURRENTPOS]); - const NSRange rangeCharactersCaret = mOwner.backend->CharactersFromPositions(NSMakeRange(caret, 0)); - return mOwner.backend->VisibleLineForIndex(rangeCharactersCaret.location); + const int caret = static_cast<int>([mOwner message: SCI_GETCURRENTPOS]); + const NSRange rangeCharactersCaret = mOwner.backend->CharactersFromPositions(NSMakeRange(caret, 0)); + return mOwner.backend->VisibleLineForIndex(rangeCharactersCaret.location); } //-------------------------------------------------------------------------------------------------- @@ -1057,8 +950,8 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context /** * NSAccessibility : Not implemented and not called by VoiceOver. */ -- (NSRange)accessibilityRangeForPosition:(NSPoint)point { - return NSMakeRange(0,0); +- (NSRange) accessibilityRangeForPosition: (NSPoint) point { + return NSMakeRange(0, 0); } //-------------------------------------------------------------------------------------------------- @@ -1067,9 +960,9 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context * NSAccessibility : Number of characters in the whole document. */ - (NSInteger) accessibilityNumberOfCharacters { - sptr_t length = [mOwner message: SCI_GETLENGTH]; - const NSRange posRange = mOwner.backend->CharactersFromPositions(NSMakeRange(length, 0)); - return posRange.location; + sptr_t length = [mOwner message: SCI_GETLENGTH]; + const NSRange posRange = mOwner.backend->CharactersFromPositions(NSMakeRange(length, 0)); + return posRange.location; } //-------------------------------------------------------------------------------------------------- @@ -1078,10 +971,10 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context * NSAccessibility : The selection text as a string. */ - (NSString *) accessibilitySelectedText { - const sptr_t positionBegin = [mOwner message: SCI_GETSELECTIONSTART]; - const sptr_t positionEnd = [mOwner message: SCI_GETSELECTIONEND]; - const NSRange posRangeSel = NSMakeRange(positionBegin, positionEnd-positionBegin); - return mOwner.backend->RangeTextAsString(posRangeSel); + const sptr_t positionBegin = [mOwner message: SCI_GETSELECTIONSTART]; + const sptr_t positionEnd = [mOwner message: SCI_GETSELECTIONEND]; + const NSRange posRangeSel = NSMakeRange(positionBegin, positionEnd-positionBegin); + return mOwner.backend->RangeTextAsString(posRangeSel); } //-------------------------------------------------------------------------------------------------- @@ -1090,10 +983,10 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context * NSAccessibility : The character range of the main selection. */ - (NSRange) accessibilitySelectedTextRange { - const sptr_t positionBegin = [mOwner message: SCI_GETSELECTIONSTART]; - const sptr_t positionEnd = [mOwner message: SCI_GETSELECTIONEND]; - const NSRange posRangeSel = NSMakeRange(positionBegin, positionEnd-positionBegin); - return mOwner.backend->CharactersFromPositions(posRangeSel); + const sptr_t positionBegin = [mOwner message: SCI_GETSELECTIONSTART]; + const sptr_t positionEnd = [mOwner message: SCI_GETSELECTIONEND]; + const NSRange posRangeSel = NSMakeRange(positionBegin, positionEnd-positionBegin); + return mOwner.backend->CharactersFromPositions(posRangeSel); } //-------------------------------------------------------------------------------------------------- @@ -1103,8 +996,8 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context * This method is the only setter required for reasonable VoiceOver behaviour. */ - (void) setAccessibilitySelectedTextRange: (NSRange) range { - NSRange rangePositions = mOwner.backend->PositionsFromCharacters(range); - [mOwner message: SCI_SETSELECTION wParam: rangePositions.location lParam:NSMaxRange(rangePositions)]; + NSRange rangePositions = mOwner.backend->PositionsFromCharacters(range); + [mOwner message: SCI_SETSELECTION wParam: rangePositions.location lParam: NSMaxRange(rangePositions)]; } //-------------------------------------------------------------------------------------------------- @@ -1113,14 +1006,14 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context * NSAccessibility : Range of the glyph at a character index. * Currently doesn't try to handle composite characters. */ -- (NSRange) accessibilityRangeForIndex: (NSInteger)index { - sptr_t length = [mOwner message: SCI_GETLENGTH]; - const NSRange rangeLength = mOwner.backend->CharactersFromPositions(NSMakeRange(length, 0)); - NSRange rangePositions = NSMakeRange(length, 0); - if (index < rangeLength.location) { - rangePositions = mOwner.backend->PositionsFromCharacters(NSMakeRange(index, 1)); - } - return mOwner.backend->CharactersFromPositions(rangePositions); +- (NSRange) accessibilityRangeForIndex: (NSInteger) index { + sptr_t length = [mOwner message: SCI_GETLENGTH]; + const NSRange rangeLength = mOwner.backend->CharactersFromPositions(NSMakeRange(length, 0)); + NSRange rangePositions = NSMakeRange(length, 0); + if (index < rangeLength.location) { + rangePositions = mOwner.backend->PositionsFromCharacters(NSMakeRange(index, 1)); + } + return mOwner.backend->CharactersFromPositions(rangePositions); } //-------------------------------------------------------------------------------------------------- @@ -1129,13 +1022,13 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context * NSAccessibility : All the text ranges. * Currently only returns the main selection. */ -- (NSArray<NSValue *>*) accessibilitySelectedTextRanges { - const sptr_t positionBegin = [mOwner message: SCI_GETSELECTIONSTART]; - const sptr_t positionEnd = [mOwner message: SCI_GETSELECTIONEND]; - const NSRange posRangeSel = NSMakeRange(positionBegin, positionEnd-positionBegin); - NSRange rangeCharacters = mOwner.backend->CharactersFromPositions(posRangeSel); - NSValue *valueRange = [NSValue valueWithRange:(NSRange)rangeCharacters]; - return @[valueRange]; +- (NSArray<NSValue *> *) accessibilitySelectedTextRanges { + const sptr_t positionBegin = [mOwner message: SCI_GETSELECTIONSTART]; + const sptr_t positionEnd = [mOwner message: SCI_GETSELECTIONEND]; + const NSRange posRangeSel = NSMakeRange(positionBegin, positionEnd-positionBegin); + NSRange rangeCharacters = mOwner.backend->CharactersFromPositions(posRangeSel); + NSValue *valueRange = [NSValue valueWithRange: (NSRange)rangeCharacters]; + return @[valueRange]; } //-------------------------------------------------------------------------------------------------- @@ -1144,14 +1037,14 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context * NSAccessibility : Character range currently visible. */ - (NSRange) accessibilityVisibleCharacterRange { - const sptr_t lineTopVisible = [mOwner message: SCI_GETFIRSTVISIBLELINE]; - const sptr_t lineTop = [mOwner message:SCI_DOCLINEFROMVISIBLE wParam:lineTopVisible]; - const sptr_t lineEndVisible = lineTopVisible + [mOwner message: SCI_LINESONSCREEN] - 1; - const sptr_t lineEnd = [mOwner message:SCI_DOCLINEFROMVISIBLE wParam:lineEndVisible]; - const sptr_t posStartView = [mOwner message: SCI_POSITIONFROMLINE wParam: lineTop]; - const sptr_t posEndView = [mOwner message: SCI_GETLINEENDPOSITION wParam: lineEnd]; - const NSRange posRangeSel = NSMakeRange(posStartView, posEndView-posStartView); - return mOwner.backend->CharactersFromPositions(posRangeSel); + const sptr_t lineTopVisible = [mOwner message: SCI_GETFIRSTVISIBLELINE]; + const sptr_t lineTop = [mOwner message: SCI_DOCLINEFROMVISIBLE wParam: lineTopVisible]; + const sptr_t lineEndVisible = lineTopVisible + [mOwner message: SCI_LINESONSCREEN] - 1; + const sptr_t lineEnd = [mOwner message: SCI_DOCLINEFROMVISIBLE wParam: lineEndVisible]; + const sptr_t posStartView = [mOwner message: SCI_POSITIONFROMLINE wParam: lineTop]; + const sptr_t posEndView = [mOwner message: SCI_GETLINEENDPOSITION wParam: lineEnd]; + const NSRange posRangeSel = NSMakeRange(posStartView, posEndView-posStartView); + return mOwner.backend->CharactersFromPositions(posRangeSel); } //-------------------------------------------------------------------------------------------------- @@ -1159,8 +1052,8 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context /** * NSAccessibility : Character range of a line. */ -- (NSRange)accessibilityRangeForLine:(NSInteger)line { - return mOwner.backend->RangeForVisibleLine(line); +- (NSRange) accessibilityRangeForLine: (NSInteger) line { + return mOwner.backend->RangeForVisibleLine(line); } //-------------------------------------------------------------------------------------------------- @@ -1168,8 +1061,8 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context /** * NSAccessibility : Line number of a text position in characters. */ -- (NSInteger)accessibilityLineForIndex:(NSInteger)index { - return mOwner.backend->VisibleLineForIndex(index); +- (NSInteger) accessibilityLineForIndex: (NSInteger) index { + return mOwner.backend->VisibleLineForIndex(index); } //-------------------------------------------------------------------------------------------------- @@ -1180,10 +1073,10 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context * Producing a nice rectangle is a little tricky particularly when including new * lines. Needs to improve the case where parts of two lines are included. */ -- (NSRect)accessibilityFrameForRange:(NSRange)range { - const NSRect rectInView = mOwner.backend->FrameForRange(range); - const NSRect rectInWindow = [self.superview.superview convertRect:rectInView toView:nil]; - return [self.window convertRectToScreen:rectInWindow]; +- (NSRect) accessibilityFrameForRange: (NSRange) range { + const NSRect rectInView = mOwner.backend->FrameForRange(range); + const NSRect rectInWindow = [self.superview.superview convertRect: rectInView toView: nil]; + return [self.window convertRectToScreen: rectInWindow]; } //-------------------------------------------------------------------------------------------------- @@ -1191,9 +1084,9 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context /** * NSAccessibility : A range of text as a string. */ -- (NSString *) accessibilityStringForRange:(NSRange)range { - const NSRange posRange = mOwner.backend->PositionsFromCharacters(range); - return mOwner.backend->RangeTextAsString(posRange); +- (NSString *) accessibilityStringForRange: (NSRange) range { + const NSRange posRange = mOwner.backend->PositionsFromCharacters(range); + return mOwner.backend->RangeTextAsString(posRange); } //-------------------------------------------------------------------------------------------------- @@ -1202,10 +1095,10 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context * NSAccessibility : A range of text as an attributed string. * Currently no attributes are set. */ -- (NSAttributedString *) accessibilityAttributedStringForRange:(NSRange)range { - const NSRange posRange = mOwner.backend->PositionsFromCharacters(range); - NSString *result = mOwner.backend->RangeTextAsString(posRange); - return [[NSMutableAttributedString alloc] initWithString:result]; +- (NSAttributedString *) accessibilityAttributedStringForRange: (NSRange) range { + const NSRange posRange = mOwner.backend->PositionsFromCharacters(range); + NSString *result = mOwner.backend->RangeTextAsString(posRange); + return [[NSMutableAttributedString alloc] initWithString: result]; } //-------------------------------------------------------------------------------------------------- @@ -1213,28 +1106,28 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context /** * NSAccessibility : Show the context menu at the caret. */ -- (BOOL)accessibilityPerformShowMenu { - const sptr_t caret = [mOwner message: SCI_GETCURRENTPOS]; - NSRect rect; - rect.origin.x = [mOwner message: SCI_POINTXFROMPOSITION wParam: 0 lParam: caret]; - rect.origin.y = [mOwner message: SCI_POINTYFROMPOSITION wParam: 0 lParam: caret]; - rect.origin.y += [mOwner message: SCI_TEXTHEIGHT wParam: 0 lParam: 0]; - rect.size.width = 1.0; - rect.size.height = 1.0; - NSRect rectInWindow = [self.superview.superview convertRect:rect toView:nil]; - NSPoint pt = rectInWindow.origin; - NSEvent *event = [NSEvent mouseEventWithType: NSRightMouseDown - location: pt - modifierFlags: 0 - timestamp: 0 - windowNumber: self.window.windowNumber - context: nil - eventNumber: 0 - clickCount: 1 - pressure: 0.0]; - NSMenu *menu = mOwner.backend->CreateContextMenu(event); - [NSMenu popUpContextMenu:menu withEvent:event forView:self]; - return YES; +- (BOOL) accessibilityPerformShowMenu { + const sptr_t caret = [mOwner message: SCI_GETCURRENTPOS]; + NSRect rect; + rect.origin.x = [mOwner message: SCI_POINTXFROMPOSITION wParam: 0 lParam: caret]; + rect.origin.y = [mOwner message: SCI_POINTYFROMPOSITION wParam: 0 lParam: caret]; + rect.origin.y += [mOwner message: SCI_TEXTHEIGHT wParam: 0 lParam: 0]; + rect.size.width = 1.0; + rect.size.height = 1.0; + NSRect rectInWindow = [self.superview.superview convertRect: rect toView: nil]; + NSPoint pt = rectInWindow.origin; + NSEvent *event = [NSEvent mouseEventWithType: NSRightMouseDown + location: pt + modifierFlags: 0 + timestamp: 0 + windowNumber: self.window.windowNumber + context: nil + eventNumber: 0 + clickCount: 1 + pressure: 0.0]; + NSMenu *menu = mOwner.backend->CreateContextMenu(event); + [NSMenu popUpContextMenu: menu withEvent: event forView: self]; + return YES; } //-------------------------------------------------------------------------------------------------- @@ -1245,23 +1138,23 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context //-------------------------------------------------------------------------------------------------- @implementation ScintillaView { - // The back end is kind of a controller and model in one. - // It uses the content view for display. - Scintilla::ScintillaCocoa* mBackend; + // The back end is kind of a controller and model in one. + // It uses the content view for display. + Scintilla::ScintillaCocoa *mBackend; - // This is the actual content to which the backend renders itself. - SCIContentView* mContent; + // This is the actual content to which the backend renders itself. + SCIContentView *mContent; - NSScrollView *scrollView; - SCIMarginView *marginView; + NSScrollView *scrollView; + SCIMarginView *marginView; - CGFloat zoomDelta; + CGFloat zoomDelta; - // Area to display additional controls (e.g. zoom info, caret position, status info). - NSView <InfoBarCommunicator>* mInfoBar; - BOOL mInfoBarAtTop; + // Area to display additional controls (e.g. zoom info, caret position, status info). + NSView <InfoBarCommunicator> *mInfoBar; + BOOL mInfoBarAtTop; - id<ScintillaNotificationProtocol> __unsafe_unretained mDelegate; + id<ScintillaNotificationProtocol> __unsafe_unretained mDelegate; } @synthesize backend = mBackend; @@ -1279,20 +1172,18 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context /** * Initialize custom cursor. */ -+ (void) initialize -{ - if (self == [ScintillaView class]) - { - NSBundle* bundle = [NSBundle bundleForClass: [ScintillaView class]]; ++ (void) initialize { + if (self == [ScintillaView class]) { + NSBundle *bundle = [NSBundle bundleForClass: [ScintillaView class]]; - NSString* path = [bundle pathForResource: @"mac_cursor_busy" ofType: @"tiff" inDirectory: nil]; - NSImage* image = [[NSImage alloc] initWithContentsOfFile: path]; - waitCursor = [[NSCursor alloc] initWithImage: image hotSpot: NSMakePoint(2, 2)]; + NSString *path = [bundle pathForResource: @"mac_cursor_busy" ofType: @"tiff" inDirectory: nil]; + NSImage *image = [[NSImage alloc] initWithContentsOfFile: path]; + waitCursor = [[NSCursor alloc] initWithImage: image hotSpot: NSMakePoint(2, 2)]; - path = [bundle pathForResource: @"mac_cursor_flipped" ofType: @"tiff" inDirectory: nil]; - image = [[NSImage alloc] initWithContentsOfFile: path]; - reverseArrowCursor = [[NSCursor alloc] initWithImage: image hotSpot: NSMakePoint(12, 2)]; - } + path = [bundle pathForResource: @"mac_cursor_flipped" ofType: @"tiff" inDirectory: nil]; + image = [[NSImage alloc] initWithContentsOfFile: path]; + reverseArrowCursor = [[NSCursor alloc] initWithImage: image hotSpot: NSMakePoint(12, 2)]; + } } //-------------------------------------------------------------------------------------------------- @@ -1301,9 +1192,8 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context * Specify the SCIContentView class. Can be overridden in a subclass to provide an SCIContentView subclass. */ -+ (Class) contentViewClass -{ - return [SCIContentView class]; ++ (Class) contentViewClass { + return [SCIContentView class]; } //-------------------------------------------------------------------------------------------------- @@ -1311,24 +1201,22 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context /** * Receives zoom messages, for example when a "pinch zoom" is performed on the trackpad. */ -- (void) magnifyWithEvent: (NSEvent *) event -{ +- (void) magnifyWithEvent: (NSEvent *) event { #if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_5 - zoomDelta += event.magnification * 10.0; + zoomDelta += event.magnification * 10.0; - if (fabs(zoomDelta)>=1.0) { - long zoomFactor = static_cast<long>([self getGeneralProperty: SCI_GETZOOM] + zoomDelta); - [self setGeneralProperty: SCI_SETZOOM parameter: zoomFactor value:0]; - zoomDelta = 0.0; - } + if (fabs(zoomDelta)>=1.0) { + long zoomFactor = static_cast<long>([self getGeneralProperty: SCI_GETZOOM] + zoomDelta); + [self setGeneralProperty: SCI_SETZOOM parameter: zoomFactor value: 0]; + zoomDelta = 0.0; + } #endif } -- (void) beginGestureWithEvent: (NSEvent *) event -{ +- (void) beginGestureWithEvent: (NSEvent *) event { // Scintilla is only interested in this event as the starft of a zoom #pragma unused(event) - zoomDelta = 0.0; + zoomDelta = 0.0; } //-------------------------------------------------------------------------------------------------- @@ -1336,10 +1224,9 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context /** * Sends a new notification of the given type to the default notification center. */ -- (void) sendNotification: (NSString*) notificationName -{ - NSNotificationCenter* center = [NSNotificationCenter defaultCenter]; - [center postNotificationName: notificationName object: self]; +- (void) sendNotification: (NSString *) notificationName { + NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; + [center postNotificationName: notificationName object: self]; } //-------------------------------------------------------------------------------------------------- @@ -1352,31 +1239,27 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context * @param location Carries the new location (e.g. caret) if the type is a caret change or similar type. * @param value Carries the new zoom value if the type is a zoom change. */ -- (void) notify: (NotificationType) type message: (NSString*) message location: (NSPoint) location - value: (float) value -{ +- (void) notify: (NotificationType) type message: (NSString *) message location: (NSPoint) location + value: (float) value { // These parameters are just to conform to the protocol #pragma unused(message) #pragma unused(location) - switch (type) - { - case IBNZoomChanged: - { - // Compute point increase/decrease based on default font size. - long fontSize = [self getGeneralProperty: SCI_STYLEGETSIZE parameter: STYLE_DEFAULT]; - int zoom = (int) (fontSize * (value - 1)); - [self setGeneralProperty: SCI_SETZOOM value: zoom]; - break; - } - default: - break; - }; + switch (type) { + case IBNZoomChanged: { + // Compute point increase/decrease based on default font size. + long fontSize = [self getGeneralProperty: SCI_STYLEGETSIZE parameter: STYLE_DEFAULT]; + int zoom = (int)(fontSize * (value - 1)); + [self setGeneralProperty: SCI_SETZOOM value: zoom]; + break; + } + default: + break; + }; } //-------------------------------------------------------------------------------------------------- -- (void) setCallback: (id <InfoBarCommunicator>) callback -{ +- (void) setCallback: (id <InfoBarCommunicator>) callback { // Not used. Only here to satisfy protocol. #pragma unused(callback) } @@ -1387,12 +1270,11 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context * Prevents drawing of the inner view to avoid flickering when doing many visual updates * (like clearing all marks and setting new ones etc.). */ -- (void) suspendDrawing: (BOOL) suspend -{ - if (suspend) - [self.window disableFlushWindow]; - else - [self.window enableFlushWindow]; +- (void) suspendDrawing: (BOOL) suspend { + if (suspend) + [self.window disableFlushWindow]; + else + [self.window enableFlushWindow]; } //-------------------------------------------------------------------------------------------------- @@ -1403,65 +1285,56 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context * A delegate can be set to receive all notifications. If set no handling takes place here, except * for action pertaining to internal stuff (like the info bar). */ -- (void) notification: (SCNotification*)scn -{ - // Parent notification. Details are passed as SCNotification structure. - - if (mDelegate != nil) - { - [mDelegate notification: scn]; - if (scn->nmhdr.code != SCN_ZOOM && scn->nmhdr.code != SCN_UPDATEUI) - return; - } - - switch (scn->nmhdr.code) - { - case SCN_MARGINCLICK: - { - if (scn->margin == 2) - { - // Click on the folder margin. Toggle the current line if possible. - long line = [self getGeneralProperty: SCI_LINEFROMPOSITION parameter: scn->position]; - [self setGeneralProperty: SCI_TOGGLEFOLD value: line]; - } - break; - }; - case SCN_MODIFIED: - { - // Decide depending on the modification type what to do. - // There can be more than one modification carried by one notification. - if (scn->modificationType & (SC_MOD_INSERTTEXT | SC_MOD_DELETETEXT)) - [self sendNotification: NSTextDidChangeNotification]; - break; - } - case SCN_ZOOM: - { - // A zoom change happened. Notify info bar if there is one. - float zoom = [self getGeneralProperty: SCI_GETZOOM parameter: 0]; - long fontSize = [self getGeneralProperty: SCI_STYLEGETSIZE parameter: STYLE_DEFAULT]; - float factor = (zoom / fontSize) + 1; - [mInfoBar notify: IBNZoomChanged message: nil location: NSZeroPoint value: factor]; - break; - } - case SCN_UPDATEUI: - { - // Triggered whenever changes in the UI state need to be reflected. - // These can be: caret changes, selection changes etc. - NSPoint caretPosition = mBackend->GetCaretPosition(); - [mInfoBar notify: IBNCaretChanged message: nil location: caretPosition value: 0]; - [self sendNotification: SCIUpdateUINotification]; - if (scn->updated & (SC_UPDATE_SELECTION | SC_UPDATE_CONTENT)) - { - [self sendNotification: NSTextViewDidChangeSelectionNotification]; - } - break; - } - case SCN_FOCUSOUT: - [self sendNotification: NSTextDidEndEditingNotification]; - break; - case SCN_FOCUSIN: // Nothing to do for now. - break; - } +- (void) notification: (SCNotification *) scn { + // Parent notification. Details are passed as SCNotification structure. + + if (mDelegate != nil) { + [mDelegate notification: scn]; + if (scn->nmhdr.code != SCN_ZOOM && scn->nmhdr.code != SCN_UPDATEUI) + return; + } + + switch (scn->nmhdr.code) { + case SCN_MARGINCLICK: { + if (scn->margin == 2) { + // Click on the folder margin. Toggle the current line if possible. + long line = [self getGeneralProperty: SCI_LINEFROMPOSITION parameter: scn->position]; + [self setGeneralProperty: SCI_TOGGLEFOLD value: line]; + } + break; + }; + case SCN_MODIFIED: { + // Decide depending on the modification type what to do. + // There can be more than one modification carried by one notification. + if (scn->modificationType & (SC_MOD_INSERTTEXT | SC_MOD_DELETETEXT)) + [self sendNotification: NSTextDidChangeNotification]; + break; + } + case SCN_ZOOM: { + // A zoom change happened. Notify info bar if there is one. + float zoom = [self getGeneralProperty: SCI_GETZOOM parameter: 0]; + long fontSize = [self getGeneralProperty: SCI_STYLEGETSIZE parameter: STYLE_DEFAULT]; + float factor = (zoom / fontSize) + 1; + [mInfoBar notify: IBNZoomChanged message: nil location: NSZeroPoint value: factor]; + break; + } + case SCN_UPDATEUI: { + // Triggered whenever changes in the UI state need to be reflected. + // These can be: caret changes, selection changes etc. + NSPoint caretPosition = mBackend->GetCaretPosition(); + [mInfoBar notify: IBNCaretChanged message: nil location: caretPosition value: 0]; + [self sendNotification: SCIUpdateUINotification]; + if (scn->updated & (SC_UPDATE_SELECTION | SC_UPDATE_CONTENT)) { + [self sendNotification: NSTextViewDidChangeSelectionNotification]; + } + break; + } + case SCN_FOCUSOUT: + [self sendNotification: NSTextDidEndEditingNotification]; + break; + case SCN_FOCUSIN: // Nothing to do for now. + break; + } } //-------------------------------------------------------------------------------------------------- @@ -1470,13 +1343,12 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context * Setup a special indicator used in the editor to provide visual feedback for * input composition, depending on language, keyboard etc. */ -- (void) updateIndicatorIME -{ - [self setColorProperty: SCI_INDICSETFORE parameter: INDIC_IME fromHTML: @"#FF0000"]; - const bool drawInBackground = [self message: SCI_GETPHASESDRAW] != 0; - [self setGeneralProperty: SCI_INDICSETUNDER parameter: INDIC_IME value: drawInBackground]; - [self setGeneralProperty: SCI_INDICSETSTYLE parameter: INDIC_IME value: INDIC_PLAIN]; - [self setGeneralProperty: SCI_INDICSETALPHA parameter: INDIC_IME value: 100]; +- (void) updateIndicatorIME { + [self setColorProperty: SCI_INDICSETFORE parameter: INDIC_IME fromHTML: @"#FF0000"]; + const bool drawInBackground = [self message: SCI_GETPHASESDRAW] != 0; + [self setGeneralProperty: SCI_INDICSETUNDER parameter: INDIC_IME value: drawInBackground]; + [self setGeneralProperty: SCI_INDICSETSTYLE parameter: INDIC_IME value: INDIC_PLAIN]; + [self setGeneralProperty: SCI_INDICSETALPHA parameter: INDIC_IME value: 100]; } //-------------------------------------------------------------------------------------------------- @@ -1484,113 +1356,109 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context /** * Initialization of the view. Used to setup a few other things we need. */ -- (instancetype) initWithFrame: (NSRect) frame -{ - self = [super initWithFrame:frame]; - if (self) - { - mContent = [[[[self class] contentViewClass] alloc] initWithFrame:NSZeroRect]; - mContent.owner = self; - - // Initialize the scrollers but don't show them yet. - // Pick an arbitrary size, just to make NSScroller selecting the proper scroller direction - // (horizontal or vertical). - NSRect scrollerRect = NSMakeRect(0, 0, 100, 10); - scrollView = [[NSScrollView alloc] initWithFrame: scrollerRect]; - scrollView.documentView = mContent; - [scrollView setHasVerticalScroller:YES]; - [scrollView setHasHorizontalScroller:YES]; - scrollView.autoresizingMask = NSViewWidthSizable|NSViewHeightSizable; - //[scrollView setScrollerStyle:NSScrollerStyleLegacy]; - //[scrollView setScrollerKnobStyle:NSScrollerKnobStyleDark]; - //[scrollView setHorizontalScrollElasticity:NSScrollElasticityNone]; - [self addSubview: scrollView]; - - marginView = [[SCIMarginView alloc] initWithScrollView:scrollView]; - marginView.owner = self; - marginView.ruleThickness = marginView.requiredThickness; - scrollView.verticalRulerView = marginView; - [scrollView setHasHorizontalRuler:NO]; - [scrollView setHasVerticalRuler:YES]; - [scrollView setRulersVisible:YES]; - - mBackend = new ScintillaCocoa(self, mContent, marginView); - - // Establish a connection from the back end to this container so we can handle situations - // which require our attention. - mBackend->SetDelegate(self); - - [self updateIndicatorIME]; - - NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; - [center addObserver:self - selector:@selector(applicationDidResignActive:) - name:NSApplicationDidResignActiveNotification - object:nil]; - - [center addObserver:self - selector:@selector(applicationDidBecomeActive:) - name:NSApplicationDidBecomeActiveNotification - object:nil]; - - [center addObserver:self - selector:@selector(windowWillMove:) - name:NSWindowWillMoveNotification - object:self.window]; - - [scrollView.contentView setPostsBoundsChangedNotifications:YES]; - [center addObserver:self - selector:@selector(scrollerAction:) - name:NSViewBoundsDidChangeNotification - object:scrollView.contentView]; - } - return self; -} - -//-------------------------------------------------------------------------------------------------- - -- (void) dealloc -{ - [[NSNotificationCenter defaultCenter] removeObserver:self]; - mBackend->Finalise(); - delete mBackend; - mBackend = NULL; - mContent.owner = nil; - [marginView setClientView:nil]; - [scrollView removeFromSuperview]; -} - -//-------------------------------------------------------------------------------------------------- - -- (void) applicationDidResignActive: (NSNotification *)note { +- (instancetype) initWithFrame: (NSRect) frame { + self = [super initWithFrame: frame]; + if (self) { + mContent = [[[[self class] contentViewClass] alloc] initWithFrame: NSZeroRect]; + mContent.owner = self; + + // Initialize the scrollers but don't show them yet. + // Pick an arbitrary size, just to make NSScroller selecting the proper scroller direction + // (horizontal or vertical). + NSRect scrollerRect = NSMakeRect(0, 0, 100, 10); + scrollView = [[NSScrollView alloc] initWithFrame: scrollerRect]; + scrollView.documentView = mContent; + [scrollView setHasVerticalScroller: YES]; + [scrollView setHasHorizontalScroller: YES]; + scrollView.autoresizingMask = NSViewWidthSizable|NSViewHeightSizable; + //[scrollView setScrollerStyle:NSScrollerStyleLegacy]; + //[scrollView setScrollerKnobStyle:NSScrollerKnobStyleDark]; + //[scrollView setHorizontalScrollElasticity:NSScrollElasticityNone]; + [self addSubview: scrollView]; + + marginView = [[SCIMarginView alloc] initWithScrollView: scrollView]; + marginView.owner = self; + marginView.ruleThickness = marginView.requiredThickness; + scrollView.verticalRulerView = marginView; + [scrollView setHasHorizontalRuler: NO]; + [scrollView setHasVerticalRuler: YES]; + [scrollView setRulersVisible: YES]; + + mBackend = new ScintillaCocoa(self, mContent, marginView); + + // Establish a connection from the back end to this container so we can handle situations + // which require our attention. + mBackend->SetDelegate(self); + + [self updateIndicatorIME]; + + NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; + [center addObserver: self + selector: @selector(applicationDidResignActive:) + name: NSApplicationDidResignActiveNotification + object: nil]; + + [center addObserver: self + selector: @selector(applicationDidBecomeActive:) + name: NSApplicationDidBecomeActiveNotification + object: nil]; + + [center addObserver: self + selector: @selector(windowWillMove:) + name: NSWindowWillMoveNotification + object: self.window]; + + [scrollView.contentView setPostsBoundsChangedNotifications: YES]; + [center addObserver: self + selector: @selector(scrollerAction:) + name: NSViewBoundsDidChangeNotification + object: scrollView.contentView]; + } + return self; +} + +//-------------------------------------------------------------------------------------------------- + +- (void) dealloc { + [[NSNotificationCenter defaultCenter] removeObserver: self]; + mBackend->Finalise(); + delete mBackend; + mBackend = NULL; + mContent.owner = nil; + [marginView setClientView: nil]; + [scrollView removeFromSuperview]; +} + +//-------------------------------------------------------------------------------------------------- + +- (void) applicationDidResignActive: (NSNotification *) note { #pragma unused(note) - mBackend->ActiveStateChanged(false); + mBackend->ActiveStateChanged(false); } //-------------------------------------------------------------------------------------------------- -- (void) applicationDidBecomeActive: (NSNotification *)note { +- (void) applicationDidBecomeActive: (NSNotification *) note { #pragma unused(note) - mBackend->ActiveStateChanged(true); + mBackend->ActiveStateChanged(true); } //-------------------------------------------------------------------------------------------------- -- (void) windowWillMove: (NSNotification *)note { +- (void) windowWillMove: (NSNotification *) note { #pragma unused(note) - mBackend->WindowWillMove(); + mBackend->WindowWillMove(); } //-------------------------------------------------------------------------------------------------- -- (void) viewDidMoveToWindow -{ - [super viewDidMoveToWindow]; +- (void) viewDidMoveToWindow { + [super viewDidMoveToWindow]; - [self positionSubViews]; + [self positionSubViews]; - // Enable also mouse move events for our window (and so this view). - [self.window setAcceptsMouseMovedEvents: YES]; + // Enable also mouse move events for our window (and so this view). + [self.window setAcceptsMouseMovedEvents: YES]; } //-------------------------------------------------------------------------------------------------- @@ -1598,38 +1466,35 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context /** * Used to position and size the parts of the editor (content, scrollers, info bar). */ -- (void) positionSubViews -{ - CGFloat scrollerWidth = [NSScroller scrollerWidthForControlSize:NSRegularControlSize - scrollerStyle:NSScrollerStyleLegacy]; - - NSSize size = self.frame.size; - NSRect barFrame = {{0, size.height - scrollerWidth}, {size.width, scrollerWidth}}; - BOOL infoBarVisible = mInfoBar != nil && !mInfoBar.hidden; - - // Horizontal offset of the content. Almost always 0 unless the vertical scroller - // is on the left side. - CGFloat contentX = 0; - NSRect scrollRect = {{contentX, 0}, {size.width, size.height}}; - - // Info bar frame. - if (infoBarVisible) - { - scrollRect.size.height -= scrollerWidth; - // Initial value already is as if the bar is at top. - if (!mInfoBarAtTop) - { - scrollRect.origin.y += scrollerWidth; - barFrame.origin.y = 0; - } - } +- (void) positionSubViews { + CGFloat scrollerWidth = [NSScroller scrollerWidthForControlSize: NSRegularControlSize + scrollerStyle: NSScrollerStyleLegacy]; + + NSSize size = self.frame.size; + NSRect barFrame = {{0, size.height - scrollerWidth}, {size.width, scrollerWidth}}; + BOOL infoBarVisible = mInfoBar != nil && !mInfoBar.hidden; + + // Horizontal offset of the content. Almost always 0 unless the vertical scroller + // is on the left side. + CGFloat contentX = 0; + NSRect scrollRect = {{contentX, 0}, {size.width, size.height}}; + + // Info bar frame. + if (infoBarVisible) { + scrollRect.size.height -= scrollerWidth; + // Initial value already is as if the bar is at top. + if (!mInfoBarAtTop) { + scrollRect.origin.y += scrollerWidth; + barFrame.origin.y = 0; + } + } - if (!NSEqualRects(scrollView.frame, scrollRect)) { - scrollView.frame = scrollRect; - } + if (!NSEqualRects(scrollView.frame, scrollRect)) { + scrollView.frame = scrollRect; + } - if (infoBarVisible) - mInfoBar.frame = barFrame; + if (infoBarVisible) + mInfoBar.frame = barFrame; } //-------------------------------------------------------------------------------------------------- @@ -1637,13 +1502,11 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context /** * Set the width of the margin. */ -- (void) setMarginWidth: (int) width -{ - if (marginView.ruleThickness != width) - { - marginView.marginWidth = width; - marginView.ruleThickness = marginView.requiredThickness; - } +- (void) setMarginWidth: (int) width { + if (marginView.ruleThickness != width) { + marginView.marginWidth = width; + marginView.ruleThickness = marginView.requiredThickness; + } } //-------------------------------------------------------------------------------------------------- @@ -1652,10 +1515,9 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context * Triggered by one of the scrollers when it gets manipulated by the user. Notify the backend * about the change. */ -- (void) scrollerAction: (id) sender -{ +- (void) scrollerAction: (id) sender { #pragma unused(sender) - mBackend->UpdateForScroll(); + mBackend->UpdateForScroll(); } //-------------------------------------------------------------------------------------------------- @@ -1663,14 +1525,13 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context /** * Used to reposition our content depending on the size of the view. */ -- (void) setFrame: (NSRect) newFrame -{ - NSRect previousFrame = self.frame; - super.frame = newFrame; - [self positionSubViews]; - if (!NSEqualRects(previousFrame, newFrame)) { - mBackend->Resize(); - } +- (void) setFrame: (NSRect) newFrame { + NSRect previousFrame = self.frame; + super.frame = newFrame; + [self positionSubViews]; + if (!NSEqualRects(previousFrame, newFrame)) { + mBackend->Resize(); + } } //-------------------------------------------------------------------------------------------------- @@ -1679,26 +1540,21 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context * Getter for the currently selected text in raw form (no formatting information included). * If there is no text available an empty string is returned. */ -- (NSString*) selectedString -{ - NSString *result = @""; +- (NSString *) selectedString { + NSString *result = @""; - const long length = mBackend->WndProc(SCI_GETSELTEXT, 0, 0); - if (length > 0) - { - std::string buffer(length + 1, '\0'); - try - { - mBackend->WndProc(SCI_GETSELTEXT, length + 1, (sptr_t) &buffer[0]); + const long length = mBackend->WndProc(SCI_GETSELTEXT, 0, 0); + if (length > 0) { + std::string buffer(length + 1, '\0'); + try { + mBackend->WndProc(SCI_GETSELTEXT, length + 1, (sptr_t) &buffer[0]); - result = @(buffer.c_str()); - } - catch (...) - { - } - } + result = @(buffer.c_str()); + } catch (...) { + } + } - return result; + return result; } //-------------------------------------------------------------------------------------------------- @@ -1706,13 +1562,11 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context /** * Delete a range from the document. */ -- (void) deleteRange: (NSRange) aRange -{ - if (aRange.length > 0) - { - NSRange posRange = mBackend->PositionsFromCharacters(aRange); - [self message: SCI_DELETERANGE wParam: posRange.location lParam: posRange.length]; - } +- (void) deleteRange: (NSRange) aRange { + if (aRange.length > 0) { + NSRange posRange = mBackend->PositionsFromCharacters(aRange); + [self message: SCI_DELETERANGE wParam: posRange.location lParam: posRange.length]; + } } //-------------------------------------------------------------------------------------------------- @@ -1721,26 +1575,21 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context * Getter for the current text in raw form (no formatting information included). * If there is no text available an empty string is returned. */ -- (NSString*) string -{ - NSString *result = @""; +- (NSString *) string { + NSString *result = @""; - const long length = mBackend->WndProc(SCI_GETLENGTH, 0, 0); - if (length > 0) - { - std::string buffer(length + 1, '\0'); - try - { - mBackend->WndProc(SCI_GETTEXT, length + 1, (sptr_t) &buffer[0]); + const long length = mBackend->WndProc(SCI_GETLENGTH, 0, 0); + if (length > 0) { + std::string buffer(length + 1, '\0'); + try { + mBackend->WndProc(SCI_GETTEXT, length + 1, (sptr_t) &buffer[0]); - result = @(buffer.c_str()); - } - catch (...) - { - } - } + result = @(buffer.c_str()); + } catch (...) { + } + } - return result; + return result; } //-------------------------------------------------------------------------------------------------- @@ -1748,45 +1597,40 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context /** * Setter for the current text (no formatting included). */ -- (void) setString: (NSString*) aString -{ - const char* text = aString.UTF8String; - mBackend->WndProc(SCI_SETTEXT, 0, (long) text); +- (void) setString: (NSString *) aString { + const char *text = aString.UTF8String; + mBackend->WndProc(SCI_SETTEXT, 0, (long) text); } //-------------------------------------------------------------------------------------------------- -- (void) insertString: (NSString*) aString atOffset: (int)offset -{ - const char* text = aString.UTF8String; - mBackend->WndProc(SCI_ADDTEXT, offset, (long) text); +- (void) insertString: (NSString *) aString atOffset: (int) offset { + const char *text = aString.UTF8String; + mBackend->WndProc(SCI_ADDTEXT, offset, (long) text); } //-------------------------------------------------------------------------------------------------- -- (void) setEditable: (BOOL) editable -{ - mBackend->WndProc(SCI_SETREADONLY, editable ? 0 : 1, 0); +- (void) setEditable: (BOOL) editable { + mBackend->WndProc(SCI_SETREADONLY, editable ? 0 : 1, 0); } //-------------------------------------------------------------------------------------------------- -- (BOOL) isEditable -{ - return mBackend->WndProc(SCI_GETREADONLY, 0, 0) == 0; +- (BOOL) isEditable { + return mBackend->WndProc(SCI_GETREADONLY, 0, 0) == 0; } //-------------------------------------------------------------------------------------------------- -- (SCIContentView*) content -{ - return mContent; +- (SCIContentView *) content { + return mContent; } //-------------------------------------------------------------------------------------------------- - (void) updateMarginCursors { - [self.window invalidateCursorRectsForView: marginView]; + [self.window invalidateCursorRectsForView: marginView]; } //-------------------------------------------------------------------------------------------------- @@ -1796,26 +1640,22 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context * the result heavily depend on the message that is used for the call. Refer to the Scintilla * documentation to learn what can be used here. */ -+ (sptr_t) directCall: (ScintillaView*) sender message: (unsigned int) message wParam: (uptr_t) wParam - lParam: (sptr_t) lParam -{ - return ScintillaCocoa::DirectFunction( - reinterpret_cast<sptr_t>(sender->mBackend), message, wParam, lParam); ++ (sptr_t) directCall: (ScintillaView *) sender message: (unsigned int) message wParam: (uptr_t) wParam + lParam: (sptr_t) lParam { + return ScintillaCocoa::DirectFunction( + reinterpret_cast<sptr_t>(sender->mBackend), message, wParam, lParam); } -- (sptr_t) message: (unsigned int) message wParam: (uptr_t) wParam lParam: (sptr_t) lParam -{ - return mBackend->WndProc(message, wParam, lParam); +- (sptr_t) message: (unsigned int) message wParam: (uptr_t) wParam lParam: (sptr_t) lParam { + return mBackend->WndProc(message, wParam, lParam); } -- (sptr_t) message: (unsigned int) message wParam: (uptr_t) wParam -{ - return mBackend->WndProc(message, wParam, 0); +- (sptr_t) message: (unsigned int) message wParam: (uptr_t) wParam { + return mBackend->WndProc(message, wParam, 0); } -- (sptr_t) message: (unsigned int) message -{ - return mBackend->WndProc(message, 0, 0); +- (sptr_t) message: (unsigned int) message { + return mBackend->WndProc(message, 0, 0); } //-------------------------------------------------------------------------------------------------- @@ -1827,9 +1667,8 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context * @param parameter Additional info for this property like a parameter or index. * @param value The actual value. It depends on the property what this parameter means. */ -- (void) setGeneralProperty: (int) property parameter: (long) parameter value: (long) value -{ - mBackend->WndProc(property, parameter, value); +- (void) setGeneralProperty: (int) property parameter: (long) parameter value: (long) value { + mBackend->WndProc(property, parameter, value); } //-------------------------------------------------------------------------------------------------- @@ -1840,9 +1679,8 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context * @param property Main property like SCI_STYLESETFORE for which a value is to be set. * @param value The actual value. It depends on the property what this parameter means. */ -- (void) setGeneralProperty: (int) property value: (long) value -{ - mBackend->WndProc(property, value, 0); +- (void) setGeneralProperty: (int) property value: (long) value { + mBackend->WndProc(property, value, 0); } //-------------------------------------------------------------------------------------------------- @@ -1855,9 +1693,8 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context * @param extra Yet another parameter if needed. * @result A generic value which must be interpreted depending on the property queried. */ -- (long) getGeneralProperty: (int) property parameter: (long) parameter extra: (long) extra -{ - return mBackend->WndProc(property, parameter, extra); +- (long) getGeneralProperty: (int) property parameter: (long) parameter extra: (long) extra { + return mBackend->WndProc(property, parameter, extra); } //-------------------------------------------------------------------------------------------------- @@ -1865,9 +1702,8 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context /** * Convenience function to avoid unneeded extra parameter. */ -- (long) getGeneralProperty: (int) property parameter: (long) parameter -{ - return mBackend->WndProc(property, parameter, 0); +- (long) getGeneralProperty: (int) property parameter: (long) parameter { + return mBackend->WndProc(property, parameter, 0); } //-------------------------------------------------------------------------------------------------- @@ -1875,9 +1711,8 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context /** * Convenience function to avoid unneeded parameters. */ -- (long) getGeneralProperty: (int) property -{ - return mBackend->WndProc(property, 0, 0); +- (long) getGeneralProperty: (int) property { + return mBackend->WndProc(property, 0, 0); } //-------------------------------------------------------------------------------------------------- @@ -1885,9 +1720,8 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context /** * Use this variant if you have to pass in a reference to something (e.g. a text range). */ -- (long) getGeneralProperty: (int) property ref: (const void*) ref -{ - return mBackend->WndProc(property, 0, (sptr_t) ref); +- (long) getGeneralProperty: (int) property ref: (const void *) ref { + return mBackend->WndProc(property, 0, (sptr_t) ref); } //-------------------------------------------------------------------------------------------------- @@ -1895,16 +1729,15 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context /** * Specialized property setter for colors. */ -- (void) setColorProperty: (int) property parameter: (long) parameter value: (NSColor*) value -{ - if (value.colorSpaceName != NSDeviceRGBColorSpace) - value = [value colorUsingColorSpaceName: NSDeviceRGBColorSpace]; - long red = static_cast<long>(value.redComponent * 255); - long green = static_cast<long>(value.greenComponent * 255); - long blue = static_cast<long>(value.blueComponent * 255); +- (void) setColorProperty: (int) property parameter: (long) parameter value: (NSColor *) value { + if (value.colorSpaceName != NSDeviceRGBColorSpace) + value = [value colorUsingColorSpaceName: NSDeviceRGBColorSpace]; + long red = static_cast<long>(value.redComponent * 255); + long green = static_cast<long>(value.greenComponent * 255); + long blue = static_cast<long>(value.blueComponent * 255); - long color = (blue << 16) + (green << 8) + red; - mBackend->WndProc(property, parameter, color); + long color = (blue << 16) + (green << 8) + red; + mBackend->WndProc(property, parameter, color); } //-------------------------------------------------------------------------------------------------- @@ -1913,44 +1746,42 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context * Another color property setting, which allows to specify the color as string like in HTML * documents (i.e. with leading # and either 3 hex digits or 6). */ -- (void) setColorProperty: (int) property parameter: (long) parameter fromHTML: (NSString*) fromHTML -{ - if (fromHTML.length > 3 && [fromHTML characterAtIndex: 0] == '#') - { - bool longVersion = fromHTML.length > 6; - int index = 1; - - char value[3] = {0, 0, 0}; - value[0] = static_cast<char>([fromHTML characterAtIndex: index++]); - if (longVersion) - value[1] = static_cast<char>([fromHTML characterAtIndex: index++]); - else - value[1] = value[0]; - - unsigned rawRed; - [[NSScanner scannerWithString: @(value)] scanHexInt: &rawRed]; - - value[0] = static_cast<char>([fromHTML characterAtIndex: index++]); - if (longVersion) - value[1] = static_cast<char>([fromHTML characterAtIndex: index++]); - else - value[1] = value[0]; - - unsigned rawGreen; - [[NSScanner scannerWithString: @(value)] scanHexInt: &rawGreen]; - - value[0] = static_cast<char>([fromHTML characterAtIndex: index++]); - if (longVersion) - value[1] = static_cast<char>([fromHTML characterAtIndex: index++]); - else - value[1] = value[0]; - - unsigned rawBlue; - [[NSScanner scannerWithString: @(value)] scanHexInt: &rawBlue]; - - long color = (rawBlue << 16) + (rawGreen << 8) + rawRed; - mBackend->WndProc(property, parameter, color); - } +- (void) setColorProperty: (int) property parameter: (long) parameter fromHTML: (NSString *) fromHTML { + if (fromHTML.length > 3 && [fromHTML characterAtIndex: 0] == '#') { + bool longVersion = fromHTML.length > 6; + int index = 1; + + char value[3] = {0, 0, 0}; + value[0] = static_cast<char>([fromHTML characterAtIndex: index++]); + if (longVersion) + value[1] = static_cast<char>([fromHTML characterAtIndex: index++]); + else + value[1] = value[0]; + + unsigned rawRed; + [[NSScanner scannerWithString: @(value)] scanHexInt: &rawRed]; + + value[0] = static_cast<char>([fromHTML characterAtIndex: index++]); + if (longVersion) + value[1] = static_cast<char>([fromHTML characterAtIndex: index++]); + else + value[1] = value[0]; + + unsigned rawGreen; + [[NSScanner scannerWithString: @(value)] scanHexInt: &rawGreen]; + + value[0] = static_cast<char>([fromHTML characterAtIndex: index++]); + if (longVersion) + value[1] = static_cast<char>([fromHTML characterAtIndex: index++]); + else + value[1] = value[0]; + + unsigned rawBlue; + [[NSScanner scannerWithString: @(value)] scanHexInt: &rawBlue]; + + long color = (rawBlue << 16) + (rawGreen << 8) + rawRed; + mBackend->WndProc(property, parameter, color); + } } //-------------------------------------------------------------------------------------------------- @@ -1958,14 +1789,13 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context /** * Specialized property getter for colors. */ -- (NSColor*) getColorProperty: (int) property parameter: (long) parameter -{ - long color = mBackend->WndProc(property, parameter, 0); - CGFloat red = (color & 0xFF) / 255.0; - CGFloat green = ((color >> 8) & 0xFF) / 255.0; - CGFloat blue = ((color >> 16) & 0xFF) / 255.0; - NSColor* result = [NSColor colorWithDeviceRed: red green: green blue: blue alpha: 1]; - return result; +- (NSColor *) getColorProperty: (int) property parameter: (long) parameter { + long color = mBackend->WndProc(property, parameter, 0); + CGFloat red = (color & 0xFF) / 255.0; + CGFloat green = ((color >> 8) & 0xFF) / 255.0; + CGFloat blue = ((color >> 16) & 0xFF) / 255.0; + NSColor *result = [NSColor colorWithDeviceRed: red green: green blue: blue alpha: 1]; + return result; } //-------------------------------------------------------------------------------------------------- @@ -1973,9 +1803,8 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context /** * Specialized property setter for references (pointers, addresses). */ -- (void) setReferenceProperty: (int) property parameter: (long) parameter value: (const void*) value -{ - mBackend->WndProc(property, parameter, (sptr_t) value); +- (void) setReferenceProperty: (int) property parameter: (long) parameter value: (const void *) value { + mBackend->WndProc(property, parameter, (sptr_t) value); } //-------------------------------------------------------------------------------------------------- @@ -1983,9 +1812,8 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context /** * Specialized property getter for references (pointers, addresses). */ -- (const void*) getReferenceProperty: (int) property parameter: (long) parameter -{ - return (const void*) mBackend->WndProc(property, parameter, 0); +- (const void *) getReferenceProperty: (int) property parameter: (long) parameter { + return (const void *) mBackend->WndProc(property, parameter, 0); } //-------------------------------------------------------------------------------------------------- @@ -1993,10 +1821,9 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context /** * Specialized property setter for string values. */ -- (void) setStringProperty: (int) property parameter: (long) parameter value: (NSString*) value -{ - const char* rawValue = value.UTF8String; - mBackend->WndProc(property, parameter, (sptr_t) rawValue); +- (void) setStringProperty: (int) property parameter: (long) parameter value: (NSString *) value { + const char *rawValue = value.UTF8String; + mBackend->WndProc(property, parameter, (sptr_t) rawValue); } @@ -2005,10 +1832,9 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context /** * Specialized property getter for string values. */ -- (NSString*) getStringProperty: (int) property parameter: (long) parameter -{ - const char* rawValue = (const char*) mBackend->WndProc(property, parameter, 0); - return @(rawValue); +- (NSString *) getStringProperty: (int) property parameter: (long) parameter { + const char *rawValue = (const char *) mBackend->WndProc(property, parameter, 0); + return @(rawValue); } //-------------------------------------------------------------------------------------------------- @@ -2016,11 +1842,10 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context /** * Specialized property setter for lexer properties, which are commonly passed as strings. */ -- (void) setLexerProperty: (NSString*) name value: (NSString*) value -{ - const char* rawName = name.UTF8String; - const char* rawValue = value.UTF8String; - mBackend->WndProc(SCI_SETPROPERTY, (sptr_t) rawName, (sptr_t) rawValue); +- (void) setLexerProperty: (NSString *) name value: (NSString *) value { + const char *rawName = name.UTF8String; + const char *rawValue = value.UTF8String; + mBackend->WndProc(SCI_SETPROPERTY, (sptr_t) rawName, (sptr_t) rawValue); } //-------------------------------------------------------------------------------------------------- @@ -2028,11 +1853,10 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context /** * Specialized property getter for references (pointers, addresses). */ -- (NSString*) getLexerProperty: (NSString*) name -{ - const char* rawName = name.UTF8String; - const char* result = (const char*) mBackend->WndProc(SCI_SETPROPERTY, (sptr_t) rawName, 0); - return @(result); +- (NSString *) getLexerProperty: (NSString *) name { + const char *rawName = name.UTF8String; + const char *result = (const char *) mBackend->WndProc(SCI_SETPROPERTY, (sptr_t) rawName, 0); + return @(result); } //-------------------------------------------------------------------------------------------------- @@ -2040,8 +1864,7 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context /** * Sets the notification callback */ -- (void) registerNotifyCallback: (intptr_t) windowid value: (SciNotifyFunc) callback -{ +- (void) registerNotifyCallback: (intptr_t) windowid value: (SciNotifyFunc) callback { mBackend->RegisterNotifyCallback(windowid, callback); } @@ -2053,22 +1876,19 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context * Set newBar to nil if you want to hide the bar again. * The info bar's height is set to the height of the scrollbar. */ -- (void) setInfoBar: (NSView <InfoBarCommunicator>*) newBar top: (BOOL) top -{ - if (mInfoBar != newBar) - { - [mInfoBar removeFromSuperview]; +- (void) setInfoBar: (NSView <InfoBarCommunicator> *) newBar top: (BOOL) top { + if (mInfoBar != newBar) { + [mInfoBar removeFromSuperview]; - mInfoBar = newBar; - mInfoBarAtTop = top; - if (mInfoBar != nil) - { - [self addSubview: mInfoBar]; - [mInfoBar setCallback: self]; - } + mInfoBar = newBar; + mInfoBarAtTop = top; + if (mInfoBar != nil) { + [self addSubview: mInfoBar]; + [mInfoBar setCallback: self]; + } - [self positionSubViews]; - } + [self positionSubViews]; + } } //-------------------------------------------------------------------------------------------------- @@ -2076,17 +1896,15 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context /** * Sets the edit's info bar status message. This call only has an effect if there is an info bar. */ -- (void) setStatusText: (NSString*) text -{ - if (mInfoBar != nil) - [mInfoBar notify: IBNStatusChanged message: text location: NSZeroPoint value: 0]; +- (void) setStatusText: (NSString *) text { + if (mInfoBar != nil) + [mInfoBar notify: IBNStatusChanged message: text location: NSZeroPoint value: 0]; } //-------------------------------------------------------------------------------------------------- -- (NSRange) selectedRange -{ - return [mContent selectedRange]; +- (NSRange) selectedRange { + return [mContent selectedRange]; } //-------------------------------------------------------------------------------------------------- @@ -2096,22 +1914,20 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context * Unlike selectedRange, this can return empty ranges inside the document. */ -- (NSRange) selectedRangePositions -{ - const sptr_t positionBegin = [self message: SCI_GETSELECTIONSTART]; - const sptr_t positionEnd = [self message: SCI_GETSELECTIONEND]; - return NSMakeRange(positionBegin, positionEnd-positionBegin); +- (NSRange) selectedRangePositions { + const sptr_t positionBegin = [self message: SCI_GETSELECTIONSTART]; + const sptr_t positionEnd = [self message: SCI_GETSELECTIONEND]; + return NSMakeRange(positionBegin, positionEnd-positionBegin); } //-------------------------------------------------------------------------------------------------- -- (void)insertText: (id) aString -{ - if ([aString isKindOfClass:[NSString class]]) - mBackend->InsertText(aString); - else if ([aString isKindOfClass:[NSAttributedString class]]) - mBackend->InsertText([aString string]); +- (void) insertText: (id) aString { + if ([aString isKindOfClass: [NSString class]]) + mBackend->InsertText(aString); + else if ([aString isKindOfClass: [NSAttributedString class]]) + mBackend->InsertText([aString string]); } //-------------------------------------------------------------------------------------------------- @@ -2119,18 +1935,17 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context /** * For backwards compatibility. */ -- (BOOL) findAndHighlightText: (NSString*) searchText - matchCase: (BOOL) matchCase - wholeWord: (BOOL) wholeWord - scrollTo: (BOOL) scrollTo - wrap: (BOOL) wrap -{ - return [self findAndHighlightText: searchText - matchCase: matchCase - wholeWord: wholeWord - scrollTo: scrollTo - wrap: wrap - backwards: NO]; +- (BOOL) findAndHighlightText: (NSString *) searchText + matchCase: (BOOL) matchCase + wholeWord: (BOOL) wholeWord + scrollTo: (BOOL) scrollTo + wrap: (BOOL) wrap { + return [self findAndHighlightText: searchText + matchCase: matchCase + wholeWord: wholeWord + scrollTo: scrollTo + wrap: wrap + backwards: NO]; } //-------------------------------------------------------------------------------------------------- @@ -2140,82 +1955,73 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context * * @result YES if something was found, NO otherwise. */ -- (BOOL) findAndHighlightText: (NSString*) searchText - matchCase: (BOOL) matchCase - wholeWord: (BOOL) wholeWord - scrollTo: (BOOL) scrollTo - wrap: (BOOL) wrap - backwards: (BOOL) backwards -{ - int searchFlags= 0; - if (matchCase) - searchFlags |= SCFIND_MATCHCASE; - if (wholeWord) - searchFlags |= SCFIND_WHOLEWORD; - - long selectionStart = [self getGeneralProperty: SCI_GETSELECTIONSTART parameter: 0]; - long selectionEnd = [self getGeneralProperty: SCI_GETSELECTIONEND parameter: 0]; - - // Sets the start point for the coming search to the beginning of the current selection. - // For forward searches we have therefore to set the selection start to the current selection end - // for proper incremental search. This does not harm as we either get a new selection if something - // is found or the previous selection is restored. - if (!backwards) - [self getGeneralProperty: SCI_SETSELECTIONSTART parameter: selectionEnd]; - [self setGeneralProperty: SCI_SEARCHANCHOR value: 0]; - sptr_t result; - const char* textToSearch = searchText.UTF8String; - - // The following call will also set the selection if something was found. - if (backwards) - { - result = [ScintillaView directCall: self - message: SCI_SEARCHPREV - wParam: searchFlags - lParam: (sptr_t) textToSearch]; - if (result < 0 && wrap) - { - // Try again from the end of the document if nothing could be found so far and - // wrapped search is set. - [self getGeneralProperty: SCI_SETSELECTIONSTART parameter: [self getGeneralProperty: SCI_GETTEXTLENGTH parameter: 0]]; - [self setGeneralProperty: SCI_SEARCHANCHOR value: 0]; - result = [ScintillaView directCall: self - message: SCI_SEARCHNEXT - wParam: searchFlags - lParam: (sptr_t) textToSearch]; - } - } - else - { - result = [ScintillaView directCall: self - message: SCI_SEARCHNEXT - wParam: searchFlags - lParam: (sptr_t) textToSearch]; - if (result < 0 && wrap) - { - // Try again from the start of the document if nothing could be found so far and - // wrapped search is set. - [self getGeneralProperty: SCI_SETSELECTIONSTART parameter: 0]; - [self setGeneralProperty: SCI_SEARCHANCHOR value: 0]; - result = [ScintillaView directCall: self - message: SCI_SEARCHNEXT - wParam: searchFlags - lParam: (sptr_t) textToSearch]; - } - } - - if (result >= 0) - { - if (scrollTo) - [self setGeneralProperty: SCI_SCROLLCARET value: 0]; - } - else - { - // Restore the former selection if we did not find anything. - [self setGeneralProperty: SCI_SETSELECTIONSTART value: selectionStart]; - [self setGeneralProperty: SCI_SETSELECTIONEND value: selectionEnd]; - } - return (result >= 0) ? YES : NO; +- (BOOL) findAndHighlightText: (NSString *) searchText + matchCase: (BOOL) matchCase + wholeWord: (BOOL) wholeWord + scrollTo: (BOOL) scrollTo + wrap: (BOOL) wrap + backwards: (BOOL) backwards { + int searchFlags= 0; + if (matchCase) + searchFlags |= SCFIND_MATCHCASE; + if (wholeWord) + searchFlags |= SCFIND_WHOLEWORD; + + long selectionStart = [self getGeneralProperty: SCI_GETSELECTIONSTART parameter: 0]; + long selectionEnd = [self getGeneralProperty: SCI_GETSELECTIONEND parameter: 0]; + + // Sets the start point for the coming search to the beginning of the current selection. + // For forward searches we have therefore to set the selection start to the current selection end + // for proper incremental search. This does not harm as we either get a new selection if something + // is found or the previous selection is restored. + if (!backwards) + [self getGeneralProperty: SCI_SETSELECTIONSTART parameter: selectionEnd]; + [self setGeneralProperty: SCI_SEARCHANCHOR value: 0]; + sptr_t result; + const char *textToSearch = searchText.UTF8String; + + // The following call will also set the selection if something was found. + if (backwards) { + result = [ScintillaView directCall: self + message: SCI_SEARCHPREV + wParam: searchFlags + lParam: (sptr_t) textToSearch]; + if (result < 0 && wrap) { + // Try again from the end of the document if nothing could be found so far and + // wrapped search is set. + [self getGeneralProperty: SCI_SETSELECTIONSTART parameter: [self getGeneralProperty: SCI_GETTEXTLENGTH parameter: 0]]; + [self setGeneralProperty: SCI_SEARCHANCHOR value: 0]; + result = [ScintillaView directCall: self + message: SCI_SEARCHNEXT + wParam: searchFlags + lParam: (sptr_t) textToSearch]; + } + } else { + result = [ScintillaView directCall: self + message: SCI_SEARCHNEXT + wParam: searchFlags + lParam: (sptr_t) textToSearch]; + if (result < 0 && wrap) { + // Try again from the start of the document if nothing could be found so far and + // wrapped search is set. + [self getGeneralProperty: SCI_SETSELECTIONSTART parameter: 0]; + [self setGeneralProperty: SCI_SEARCHANCHOR value: 0]; + result = [ScintillaView directCall: self + message: SCI_SEARCHNEXT + wParam: searchFlags + lParam: (sptr_t) textToSearch]; + } + } + + if (result >= 0) { + if (scrollTo) + [self setGeneralProperty: SCI_SCROLLCARET value: 0]; + } else { + // Restore the former selection if we did not find anything. + [self setGeneralProperty: SCI_SETSELECTIONSTART value: selectionStart]; + [self setGeneralProperty: SCI_SETSELECTIONEND value: selectionEnd]; + } + return (result >= 0) ? YES : NO; } //-------------------------------------------------------------------------------------------------- @@ -2225,108 +2031,100 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context * * @result Number of entries replaced, 0 if none. */ -- (int) findAndReplaceText: (NSString*) searchText - byText: (NSString*) newText - matchCase: (BOOL) matchCase - wholeWord: (BOOL) wholeWord - doAll: (BOOL) doAll -{ - // The current position is where we start searching for single occurrences. Otherwise we start at - // the beginning of the document. - long startPosition; - if (doAll) - startPosition = 0; // Start at the beginning of the text if we replace all occurrences. - else - // For a single replacement we start at the current caret position. - startPosition = [self getGeneralProperty: SCI_GETCURRENTPOS]; - long endPosition = [self getGeneralProperty: SCI_GETTEXTLENGTH]; - - int searchFlags= 0; - if (matchCase) - searchFlags |= SCFIND_MATCHCASE; - if (wholeWord) - searchFlags |= SCFIND_WHOLEWORD; - [self setGeneralProperty: SCI_SETSEARCHFLAGS value: searchFlags]; - [self setGeneralProperty: SCI_SETTARGETSTART value: startPosition]; - [self setGeneralProperty: SCI_SETTARGETEND value: endPosition]; - - const char* textToSearch = searchText.UTF8String; - long sourceLength = strlen(textToSearch); // Length in bytes. - const char* replacement = newText.UTF8String; - long targetLength = strlen(replacement); // Length in bytes. - sptr_t result; - - int replaceCount = 0; - if (doAll) - { - while (true) - { - result = [ScintillaView directCall: self - message: SCI_SEARCHINTARGET - wParam: sourceLength - lParam: (sptr_t) textToSearch]; - if (result < 0) - break; - - replaceCount++; - [ScintillaView directCall: self - message: SCI_REPLACETARGET - wParam: targetLength - lParam: (sptr_t) replacement]; - - // The replacement changes the target range to the replaced text. Continue after that till the end. - // The text length might be changed by the replacement so make sure the target end is the actual - // text end. - [self setGeneralProperty: SCI_SETTARGETSTART value: [self getGeneralProperty: SCI_GETTARGETEND]]; - [self setGeneralProperty: SCI_SETTARGETEND value: [self getGeneralProperty: SCI_GETTEXTLENGTH]]; - } - } - else - { - result = [ScintillaView directCall: self - message: SCI_SEARCHINTARGET - wParam: sourceLength - lParam: (sptr_t) textToSearch]; - replaceCount = (result < 0) ? 0 : 1; - - if (replaceCount > 0) - { - [ScintillaView directCall: self - message: SCI_REPLACETARGET - wParam: targetLength - lParam: (sptr_t) replacement]; - - // For a single replace we set the new selection to the replaced text. - [self setGeneralProperty: SCI_SETSELECTIONSTART value: [self getGeneralProperty: SCI_GETTARGETSTART]]; - [self setGeneralProperty: SCI_SETSELECTIONEND value: [self getGeneralProperty: SCI_GETTARGETEND]]; - } - } - - return replaceCount; -} - -//-------------------------------------------------------------------------------------------------- - -- (void) setFontName: (NSString*) font - size: (int) size - bold: (BOOL) bold - italic: (BOOL) italic -{ - for (int i = 0; i < 128; i++) - { - [self setGeneralProperty: SCI_STYLESETFONT - parameter: i - value: (sptr_t)font.UTF8String]; - [self setGeneralProperty: SCI_STYLESETSIZE - parameter: i - value: size]; - [self setGeneralProperty: SCI_STYLESETBOLD - parameter: i - value: bold]; - [self setGeneralProperty: SCI_STYLESETITALIC - parameter: i - value: italic]; - } +- (int) findAndReplaceText: (NSString *) searchText + byText: (NSString *) newText + matchCase: (BOOL) matchCase + wholeWord: (BOOL) wholeWord + doAll: (BOOL) doAll { + // The current position is where we start searching for single occurrences. Otherwise we start at + // the beginning of the document. + long startPosition; + if (doAll) + startPosition = 0; // Start at the beginning of the text if we replace all occurrences. + else + // For a single replacement we start at the current caret position. + startPosition = [self getGeneralProperty: SCI_GETCURRENTPOS]; + long endPosition = [self getGeneralProperty: SCI_GETTEXTLENGTH]; + + int searchFlags= 0; + if (matchCase) + searchFlags |= SCFIND_MATCHCASE; + if (wholeWord) + searchFlags |= SCFIND_WHOLEWORD; + [self setGeneralProperty: SCI_SETSEARCHFLAGS value: searchFlags]; + [self setGeneralProperty: SCI_SETTARGETSTART value: startPosition]; + [self setGeneralProperty: SCI_SETTARGETEND value: endPosition]; + + const char *textToSearch = searchText.UTF8String; + long sourceLength = strlen(textToSearch); // Length in bytes. + const char *replacement = newText.UTF8String; + long targetLength = strlen(replacement); // Length in bytes. + sptr_t result; + + int replaceCount = 0; + if (doAll) { + while (true) { + result = [ScintillaView directCall: self + message: SCI_SEARCHINTARGET + wParam: sourceLength + lParam: (sptr_t) textToSearch]; + if (result < 0) + break; + + replaceCount++; + [ScintillaView directCall: self + message: SCI_REPLACETARGET + wParam: targetLength + lParam: (sptr_t) replacement]; + + // The replacement changes the target range to the replaced text. Continue after that till the end. + // The text length might be changed by the replacement so make sure the target end is the actual + // text end. + [self setGeneralProperty: SCI_SETTARGETSTART value: [self getGeneralProperty: SCI_GETTARGETEND]]; + [self setGeneralProperty: SCI_SETTARGETEND value: [self getGeneralProperty: SCI_GETTEXTLENGTH]]; + } + } else { + result = [ScintillaView directCall: self + message: SCI_SEARCHINTARGET + wParam: sourceLength + lParam: (sptr_t) textToSearch]; + replaceCount = (result < 0) ? 0 : 1; + + if (replaceCount > 0) { + [ScintillaView directCall: self + message: SCI_REPLACETARGET + wParam: targetLength + lParam: (sptr_t) replacement]; + + // For a single replace we set the new selection to the replaced text. + [self setGeneralProperty: SCI_SETSELECTIONSTART value: [self getGeneralProperty: SCI_GETTARGETSTART]]; + [self setGeneralProperty: SCI_SETSELECTIONEND value: [self getGeneralProperty: SCI_GETTARGETEND]]; + } + } + + return replaceCount; +} + +//-------------------------------------------------------------------------------------------------- + +- (void) setFontName: (NSString *) font + size: (int) size + bold: (BOOL) bold + italic: (BOOL) italic { + for (int i = 0; i < 128; i++) { + [self setGeneralProperty: SCI_STYLESETFONT + parameter: i + value: (sptr_t)font.UTF8String]; + [self setGeneralProperty: SCI_STYLESETSIZE + parameter: i + value: size]; + [self setGeneralProperty: SCI_STYLESETBOLD + parameter: i + value: bold]; + [self setGeneralProperty: SCI_STYLESETITALIC + parameter: i + value: italic]; + } } //-------------------------------------------------------------------------------------------------- |