diff --git a/scintilla/cocoa/Framework.mk b/scintilla/cocoa/Framework.mk new file mode 100644 index 00000000..88358ac2 --- /dev/null +++ b/scintilla/cocoa/Framework.mk @@ -0,0 +1,85 @@ +### start defines ### + +ARCH=-arch i386 +CC=gcc -x c++ $(ARCH) +CO=gcc -x objective-c++ $(ARCH) + +INST_NAME=-install_name @executable_path/../Frameworks/Sci.framework/Versions/A/Sci +LD=gcc $(ARCH) -dynamiclib -framework Cocoa $(INST_NAME) + +gDEFs=-DSCI_NAMESPACE -DSCI_LEXER + +INCS=-I../src/ -I../include/ -I. +CCX=$(CC) $(gDEFs) $(INCS) +CCO=$(CO) $(gDEFs) $(INCS) + +BLD=build/framebuild + +SCI_LEXERS=LexAPDL.o LexASY.o LexAU3.o LexAVE.o LexAbaqus.o LexAda.o LexAsm.o LexAsn1.o \ + LexBaan.o LexBash.o LexBasic.o LexBullant.o LexCLW.o LexCOBOL.o LexCPP.o LexCSS.o \ + LexCaml.o LexCmake.o LexConf.o LexCrontab.o LexCsound.o LexD.o LexEScript.o LexEiffel.o \ + LexErlang.o LexFlagship.o LexForth.o LexFortran.o LexGAP.o LexGui4Cli.o LexHTML.o \ + LexHaskell.o LexInno.o LexKix.o LexLisp.o LexLout.o LexLua.o LexMMIXAL.o LexMPT.o \ + LexMSSQL.o LexMagik.o LexMarkdown.o LexMatlab.o LexMetapost.o LexMySQL.o LexNimrod.o \ + LexNsis.o LexOpal.o LexOthers.o LexPB.o LexPLM.o LexPOV.o LexPS.o LexPascal.o LexPerl.o \ + LexPowerPro.o LexPowerShell.o LexProgress.o LexPython.o LexR.o LexRebol.o LexRuby.o \ + LexSML.o LexSQL.o LexScriptol.o LexSmalltalk.o LexSorcus.o LexSpecman.o LexSpice.o \ + LexTACL.o LexTADS3.o LexTAL.o LexTCL.o LexTeX.o LexVB.o LexVHDL.o LexVerilog.o LexYAML.o + +SCI_OBJ=AutoComplete.o CallTip.o CellBuffer.o CharClassify.o ContractionState.o Decoration.o \ + Document.o DocumentAccessor.o Editor.o ExternalLexer.o Indicator.o KeyMap.o KeyWords.o \ + LineMarker.o PerLine.o PositionCache.o PropSet.o RESearch.o RunStyles.o ScintillaBase.o \ + Style.o StyleContext.o UniConversion.o ViewStyle.o WindowAccessor.o XPM.o Selection.o $(SCI_LEXERS) +COC_OBJ=PlatCocoa.o ScintillaCocoa.o ScintillaView.o InfoBar.o + +OBJ=$(SCI_OBJ) $(COC_OBJ) +OBJS=$(addprefix $(BLD)/,$(OBJ)) + +TARG=$(APP)/Versions/A/Sci +APP=$(BLD)/Sci.framework +### end defines ### + +### start targets ### + +all: $(BLD) $(TARG) + +$(APP): $(BLD) + -rm -rf $(APP) + -mkdir $(APP) + -mkdir $(APP)/Versions + -mkdir $(APP)/Versions/A + -mkdir $(APP)/Versions/A/Headers + -mkdir $(APP)/Versions/A/Resources + -ln -sf `pwd`/$(APP)/Versions/A `pwd`/$(APP)/Versions/Current + -ln -sf `pwd`/$(APP)/Versions/A/Headers `pwd`/$(APP)/Headers + -ln -sf `pwd`/$(APP)/Versions/A/Resources `pwd`/$(APP)/Resources + -cp *.h $(APP)/Headers/ + -cp ../src/*.h $(APP)/Headers/ + -cp ../include/*.h $(APP)/Headers/ + -cp -R ScintillaFramework/English.lproj $(APP)/Resources + -cp res/*.png $(APP)/Resources + -cp ScintillaFramework/Info.plist $(APP)/Resources + +$(TARG) : $(OBJS) $(APP) + $(LD) $(OBJS) $(gDEFs) -o $(TARG) -lstdc++ + -ln `pwd`/$(TARG) `pwd`/$(APP)/Sci + +$(BLD): + -mkdir build + -mkdir $(BLD) + +clean: + -rm -rf $(BLD) + +$(BLD)/%.o : ../src/%.cxx + $(CCX) -c ../src/$< -o $@ + +$(BLD)/%.o : %.mm + $(CCO) -c $< -o $@ + +### get around to filling out the real dependencies later ### +$(BLD)/AutoComplete.o : ../src/AutoComplete.cxx ../src/AutoComplete.h ../include/Platform.h + +$(BLD)/CallTip.o : ../src/CallTip.cxx ../src/CallTip.h ../include/Platform.h + +### end targets ### \ No newline at end of file diff --git a/scintilla/cocoa/InfoBar.h b/scintilla/cocoa/InfoBar.h new file mode 100644 index 00000000..96248115 --- /dev/null +++ b/scintilla/cocoa/InfoBar.h @@ -0,0 +1,55 @@ + +/** + * Scintilla source code edit control + * InfoBar.h - Implements special info bar with zoom info, caret position etc. to be used with + * ScintillaView. + * + * Mike Lischke + * + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * This file is dual licensed under LGPL v2.1 and the Scintilla license (http://www.scintilla.org/License.txt). + */ + +#import +#import "InfoBarCommunicator.h" + +/** + * Extended text cell for vertically aligned text. + */ +@interface VerticallyCenteredTextFieldCell : NSTextFieldCell +{ + BOOL mIsEditingOrSelecting; +} + +@end + +@interface InfoBar : NSView +{ +@private + NSImage* mBackground; + IBDisplay mDisplayMask; + + float mScaleFactor; + NSPopUpButton* mZoomPopup; + + int mCurrentCaretX; + int mCurrentCaretY; + NSTextField* mCaretPositionLabel; + NSTextField* mStatusTextLabel; + + id mCallback; +} + +- (void) notify: (NotificationType) type message: (NSString*) message location: (NSPoint) location + value: (float) value; +- (void) setCallback: (id ) callback; + +- (void) createItems; +- (void) layout; +- (void) setDisplay: (IBDisplay) display; +- (void) zoomItemAction: (id) sender; +- (void) setScaleFactor: (float) newScaleFactor adjustPopup: (BOOL) flag; +- (void) setCaretPosition: (NSPoint) position; +- (void) sizeToFit; + +@end diff --git a/scintilla/cocoa/InfoBar.mm b/scintilla/cocoa/InfoBar.mm new file mode 100644 index 00000000..27b9aa12 --- /dev/null +++ b/scintilla/cocoa/InfoBar.mm @@ -0,0 +1,448 @@ + +/** + * Scintilla source code edit control + * InfoBar.mm - Implements special info bar with zoom info, caret position etc. to be used with + * ScintillaView. + * + * Mike Lischke + * + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * This file is dual licensed under LGPL v2.1 and the Scintilla license (http://www.scintilla.org/License.txt). + */ + +#import "InfoBar.h" + +//-------------------------------------------------------------------------------------------------- + +@implementation VerticallyCenteredTextFieldCell + +// Inspired by code from Daniel Jalkut, Red Sweater Software. + +- (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) + { + // Get our ideal size for current text + NSSize textSize = [self cellSizeForBounds: theRect]; + + // Center that in the proposed rect + float heightDelta = newRect.size.height - textSize.height; + if (heightDelta > 0) + { + newRect.size.height -= heightDelta; + newRect.origin.y += ceil(heightDelta / 2); + } + } + + return newRect; +} + +//-------------------------------------------------------------------------------------------------- + +- (void) selectWithFrame: (NSRect) aRect inView: (NSView*) controlView editor: (NSText*) textObj + delegate:(id) anObject start: (int) selStart length: (int) selLength +{ + aRect = [self drawingRectForBounds: aRect]; + mIsEditingOrSelecting = YES; + [super selectWithFrame: aRect + 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 +{ + aRect = [self drawingRectForBounds: aRect]; + mIsEditingOrSelecting = YES; + [super editWithFrame: aRect + inView: controlView + editor: textObj + delegate: anObject + event: theEvent]; + mIsEditingOrSelecting = NO; +} + +@end + +//-------------------------------------------------------------------------------------------------- + +@implementation InfoBar + +- (id) initWithFrame: (NSRect) frame +{ + self = [super initWithFrame: frame]; + if (self) + { + NSBundle* bundle = [NSBundle bundleForClass: [InfoBar class]]; + + NSString* path = [bundle pathForResource: @"info_bar_bg" ofType: @"png" inDirectory: nil]; + mBackground = [[[NSImage alloc] initWithContentsOfFile: path] retain]; + if (![mBackground isValid]) + NSLog(@"Background image for info bar is invalid."); + + mScaleFactor = 1.0; + mCurrentCaretX = 0; + mCurrentCaretY = 0; + [self createItems]; + } + return self; +} + +//-------------------------------------------------------------------------------------------------- + +/** + * Called by a connected compontent (usually the info bar) if something changed there. + * + * @param type The type of the notification. + * @param message Carries the new status message if the type is a status message change. + * @param location Carries the new location (e.g. caret) if the type is a caret change or similar type. + * @param location 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 setStringValue: message]; + break; + } +} + +//-------------------------------------------------------------------------------------------------- + +/** + * Used to set a protocol object we can use to send change notifications to. + */ +- (void) setCallback: (id ) callback +{ + mCallback = callback; +} + +//-------------------------------------------------------------------------------------------------- + +static NSString *DefaultScaleMenuLabels[] = { + @"20%", @"30%", @"50%", @"75%", @"100%", @"130%", @"160%", @"200%", @"250%", @"300%" +}; +static float DefaultScaleMenuFactors[] = { + 0.2, 0.3, 0.5, 0.75, 1.0, 1.3, 1.6, 2.0, 2.5, 3.0 +}; +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 allocWithZone:[self zone]] 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: [NSNumber numberWithFloat: DefaultScaleMenuFactors[count]]]; + } + [mZoomPopup selectItemAtIndex: DefaultScaleMenuSelectedItemIndex]; + + // Hook it up. + [mZoomPopup setTarget: self]; + [mZoomPopup setAction: @selector(zoomItemAction:)]; + + // Set a suitable font. + [mZoomPopup setFont: [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]; + [mZoomPopup release]; + + // 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 setFont: [NSFont menuBarFontOfSize: BarFontSize]]; + + NSTextFieldCell* cell = [mCaretPositionLabel cell]; + [cell setPlaceholderString: @"0:0"]; + [cell setAlignment: NSCenterTextAlignment]; + + [self addSubview: mCaretPositionLabel]; + [mCaretPositionLabel release]; + + // 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 setFont: [NSFont menuBarFontOfSize: BarFontSize]]; + + cell = [mStatusTextLabel cell]; + [cell setPlaceholderString: @""]; + + [self addSubview: mStatusTextLabel]; + [mStatusTextLabel release]; + + // Restore original cell class so that everything else doesn't get broken + [NSTextField setCellClass: oldCellClass]; +} + +//-------------------------------------------------------------------------------------------------- + +- (void) dealloc +{ + [mBackground release]; + [super dealloc]; +} + +//-------------------------------------------------------------------------------------------------- + +/** + * 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; + float 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; +} + +//-------------------------------------------------------------------------------------------------- + +/** + * Used to reposition our content depending on the size of the view. + */ +- (void) setFrame: (NSRect) newFrame +{ + [super setFrame: newFrame]; + [self layout]; +} + +//-------------------------------------------------------------------------------------------------- + +- (void) layout +{ + NSRect currentBounds = {0, 0, 0, [self frame].size.height}; + if (mDisplayMask & IBShowZoom) + { + [mZoomPopup setHidden: NO]; + currentBounds.size.width = [mZoomPopup frame].size.width; + [mZoomPopup setFrame: 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 setFrame: 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 setFrame: currentBounds]; + } + else + [mStatusTextLabel setHidden: YES]; +} + +//-------------------------------------------------------------------------------------------------- + +/** + * Used to switch the visible parts of the info bar. + * + * @param display Bitwise ORed IBDisplay values which determine what to show on the bar. + */ +- (void) setDisplay: (IBDisplay) display +{ + if (mDisplayMask != display) + { + mDisplayMask = display; + [self layout]; + [self needsDisplay]; + } +} + +//-------------------------------------------------------------------------------------------------- + +/** + * 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) 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]; + } + } +} + +//-------------------------------------------------------------------------------------------------- + +/** + * 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 setStringValue: [NSString stringWithFormat: @"%d:%d", newX, newY]]; + } +} + +//-------------------------------------------------------------------------------------------------- + +/** + * Makes the bar resize to the smallest width that can accomodate the currently enabled items. + */ +- (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 & IBShowStatusText) + frame.size.width += [mStatusTextLabel frame].size.width; + + [self setFrame: frame]; +} + +@end diff --git a/scintilla/cocoa/InfoBarCommunicator.h b/scintilla/cocoa/InfoBarCommunicator.h new file mode 100644 index 00000000..ba8ae7a1 --- /dev/null +++ b/scintilla/cocoa/InfoBarCommunicator.h @@ -0,0 +1,35 @@ +/* + * InfoBarCommunicator.h - Definitions of a communication protocol and other data types used for + * the info bar implementation. + * + * Mike Lischke + * + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * This file is dual licensed under LGPL v2.1 and the Scintilla license (http://www.scintilla.org/License.txt). + */ + +enum IBDisplay { + IBShowZoom = 0x01, + IBShowCaretPosition = 0x02, + IBShowStatusText = 0x04, + IBShowAll = 0xFF +}; + +/** + * The info bar communicator protocol is used for communication between ScintillaView and its + * information bar component. Using this protocol decouples any potential info target from the main + * ScintillaView implementation. The protocol is used two-way. + */ + +enum NotificationType { + 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) setCallback: (id ) callback; +@end + diff --git a/scintilla/cocoa/PlatCocoa.h b/scintilla/cocoa/PlatCocoa.h new file mode 100644 index 00000000..a85462e8 --- /dev/null +++ b/scintilla/cocoa/PlatCocoa.h @@ -0,0 +1,119 @@ + +/** + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * This file is dual licensed under LGPL v2.1 and the Scintilla license (http://www.scintilla.org/License.txt). + */ + +#ifndef PLATCOCOA_H +#define PLATCOCOA_H + +#include +#include +#include + +#include + +#include + +#include +#include "QuartzTextLayout.h" + +#include "Platform.h" +#include "Scintilla.h" + +NSRect PRectangleToNSRect(Scintilla::PRectangle& rc); +Scintilla::PRectangle NSRectToPRectangle(NSRect& rc); + +@interface ScintillaContextMenu : NSMenu +{ + Scintilla::ScintillaCocoa* owner; +} +- (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 +{ +private: + bool unicodeMode; + float x; + float y; + + CGContextRef gc; + + /** The text layout instance */ + QuartzTextLayout* textLayout; + /** If the surface is a bitmap context, contains a reference to the bitmap data. */ + 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 allocated colour. */ + void FillColour( const ColourAllocated& 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; +public: + SurfaceImpl(); + ~SurfaceImpl(); + + void Init(WindowID wid); + void Init(SurfaceID sid, WindowID wid); + void InitPixMap(int width, int height, Surface *surface_, WindowID wid); + CGContextRef GetContext() { return gc; } + + void Release(); + bool Initialised(); + void PenColour(ColourAllocated fore); + + /** 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(); + int DeviceHeightFont(int points); + void MoveTo(int x_, int y_); + void LineTo(int x_, int y_); + void Polygon(Scintilla::Point *pts, int npts, ColourAllocated fore, ColourAllocated back); + void RectangleDraw(PRectangle rc, ColourAllocated fore, ColourAllocated back); + void FillRectangle(PRectangle rc, ColourAllocated back); + void FillRectangle(PRectangle rc, Surface &surfacePattern); + void RoundedRectangle(PRectangle rc, ColourAllocated fore, ColourAllocated back); + void AlphaRectangle(PRectangle rc, int cornerSize, ColourAllocated fill, int alphaFill, + ColourAllocated outline, int alphaOutline, int flags); + void Ellipse(PRectangle rc, ColourAllocated fore, ColourAllocated back); + void Copy(PRectangle rc, Scintilla::Point from, Surface &surfaceSource); + void DrawTextNoClip(PRectangle rc, Font &font_, int ybase, const char *s, int len, ColourAllocated fore, + ColourAllocated back); + void DrawTextClipped(PRectangle rc, Font &font_, int ybase, const char *s, int len, ColourAllocated fore, + ColourAllocated back); + void DrawTextTransparent(PRectangle rc, Font &font_, int ybase, const char *s, int len, ColourAllocated fore); + void MeasureWidths(Font &font_, const char *s, int len, int *positions); + int WidthText(Font &font_, const char *s, int len); + int WidthChar(Font &font_, char ch); + int Ascent(Font &font_); + int Descent(Font &font_); + int InternalLeading(Font &font_); + int ExternalLeading(Font &font_); + int Height(Font &font_); + int AverageCharWidth(Font &font_); + + int SetPalette(Scintilla::Palette *pal, bool inBackGround); + void SetClip(PRectangle rc); + void FlushCachedState(); + + void SetUnicodeMode(bool unicodeMode_); + void SetDBCSMode(int codePage); +}; // SurfaceImpl class + +} // Scintilla namespace + +#endif diff --git a/scintilla/cocoa/PlatCocoa.mm b/scintilla/cocoa/PlatCocoa.mm new file mode 100644 index 00000000..09591c20 --- /dev/null +++ b/scintilla/cocoa/PlatCocoa.mm @@ -0,0 +1,2124 @@ +/** + * Scintilla source code edit control + * PlatCocoa.mm - implementation of platform facilities on MacOS X/Cocoa + * + * Written by Mike Lischke + * Based on PlatMacOSX.cxx + * Based on work by Evan Jones (c) 2002 + * Based on PlatGTK.cxx Copyright 1998-2002 by Neil Hodgson + * The License.txt file describes the conditions under which this software may be distributed. + * + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * This file is dual licensed under LGPL v2.1 and the Scintilla license (http://www.scintilla.org/License.txt). + */ + +#import + +#include "PlatCocoa.h" + +#include +#include +#include +#include +#include +#include + +#include "XPM.h" + +#import + +#import // Temporary + +using namespace Scintilla; + +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(PRectangle& rc) +{ + return NSMakeRect(rc.left, rc.top, rc.Width(), rc.Height()); +} + +//-------------------------------------------------------------------------------------------------- + +/** + * Converts an NSRect as used by the system to a native Scintilla rectangle. + */ +PRectangle NSRectToPRectangle(NSRect& rc) +{ + return PRectangle(rc.origin.x, rc.origin.y, rc.size.width + rc.origin.x, rc.size.height + rc.origin.y); +} + +//-------------------------------------------------------------------------------------------------- + +/** + * Converts a PRctangle as used by Scintilla to a Quartz-style rectangle. + */ +inline CGRect PRectangleToCGRect(PRectangle& rc) +{ + return CGRectMake(rc.left, rc.top, rc.Width(), rc.Height()); +} + +//-------------------------------------------------------------------------------------------------- + +/** + * 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; +} + +//----------------- Point -------------------------------------------------------------------------- + +/** + * 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) + ); +} + +//----------------- Palette ------------------------------------------------------------------------ + +// The Palette implementation is only here because we would get linker errors if not. +// We don't use indexed colors in ScintillaCocoa. + +Scintilla::Palette::Palette() +{ +} + +//-------------------------------------------------------------------------------------------------- + +Scintilla::Palette::~Palette() +{ +} + +//-------------------------------------------------------------------------------------------------- + +void Scintilla::Palette::Release() +{ +} + +//-------------------------------------------------------------------------------------------------- + +/** + * Used to transform a given color, if needed. If the caller tries to find a color that matches the + * desired color then we simply pass it on, as we support the full color space. + */ +void Scintilla::Palette::WantFind(ColourPair &cp, bool want) +{ + if (!want) + cp.allocated.Set(cp.desired.AsLong()); + + // Don't do anything if the caller wants the color it has already set. +} + +//-------------------------------------------------------------------------------------------------- + +void Scintilla::Palette::Allocate(Window& w) +{ + // Nothing to allocate as we don't use palettes. +} + +//----------------- Font --------------------------------------------------------------------------- + +Font::Font(): fid(0) +{ +} + +//-------------------------------------------------------------------------------------------------- + +Font::~Font() +{ + Release(); +} + +//-------------------------------------------------------------------------------------------------- + +/** + * Creates a Quartz 2D font with the given properties. + * TODO: rewrite to use NSFont. + */ +void Font::Create(const char *faceName, int characterSet, int size, bool bold, bool italic, + int extraFontFlag) +{ + // TODO: How should I handle the characterSet request? + Release(); + + QuartzTextStyle* style = new QuartzTextStyle(); + fid = style; + + // Find the font + QuartzFont font(faceName, strlen(faceName)); + + // We set Font, Size, Bold, Italic + QuartzTextSize textSize(size); + QuartzTextBold isBold(bold); + QuartzTextItalic isItalic(italic); + + // Actually set the attributes + QuartzTextStyleAttribute* attributes[] = { &font, &textSize, &isBold, &isItalic }; + style->setAttributes(attributes, sizeof(attributes) / sizeof(*attributes)); + style->setFontFeature(kLigaturesType, kCommonLigaturesOffSelector); +} + +//-------------------------------------------------------------------------------------------------- + +void Font::Release() +{ + if (fid) + delete reinterpret_cast( fid ); + fid = 0; +} + +//----------------- SurfaceImpl -------------------------------------------------------------------- + +SurfaceImpl::SurfaceImpl() +{ + bitmapData = NULL; // Release will try and delete bitmapData if != NULL + gc = NULL; + textLayout = new QuartzTextLayout(NULL); + Release(); +} + +//-------------------------------------------------------------------------------------------------- + +SurfaceImpl::~SurfaceImpl() +{ + Release(); + delete textLayout; +} + +//-------------------------------------------------------------------------------------------------- + +void SurfaceImpl::Release() +{ + textLayout->setContext (NULL); + if ( bitmapData != NULL ) + { + delete[] bitmapData; + // We only "own" the graphics context if we are a bitmap context + if (gc != NULL) + CGContextRelease(gc); + } + bitmapData = NULL; + gc = NULL; + + 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; +} + +//-------------------------------------------------------------------------------------------------- + +void SurfaceImpl::Init(WindowID wid) +{ + // To be able to draw, the surface must get a CGContext handle. We save the graphics port, + // then aquire/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 + // aquire/release of the context. + + Release(); +} + +//-------------------------------------------------------------------------------------------------- + +void SurfaceImpl::Init(SurfaceID sid, WindowID wid) +{ + Release(); + gc = reinterpret_cast(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 = new uint8_t[bitmapByteCount]; + if (bitmapData != NULL) + { + // create the context + gc = CGBitmapContextCreate(bitmapData, + 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 + delete[] bitmapData; + bitmapData = NULL; + } + textLayout->setContext (gc); + } + + // the context retains the color space, so we can release it + CGColorSpaceRelease(colorSpace); + + if (gc != NULL && bitmapData != NULL) + { + // "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 ) ); + } +} + +//-------------------------------------------------------------------------------------------------- + +void SurfaceImpl::PenColour(ColourAllocated fore) +{ + if (gc) + { + ColourDesired colour(fore.AsLong()); + + // Set the Stroke color to match + CGContextSetRGBStrokeColor(gc, colour.GetRed() / 255.0, colour.GetGreen() / 255.0, + colour.GetBlue() / 255.0, 1.0 ); + } +} + +//-------------------------------------------------------------------------------------------------- + +void SurfaceImpl::FillColour(const ColourAllocated& back) +{ + if (gc) + { + ColourDesired colour(back.AsLong()); + + // Set the Fill color to match + CGContextSetRGBFillColor(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 == NULL) + return NULL; + + CGContextFlush(gc); + + // 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); + + // Create a data provider. + CGDataProviderRef dataProvider = CGDataProviderCreateWithData(NULL, bitmapData, bitmapByteCount, + NULL); + 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; + + // Done with the data provider. + CGDataProviderRelease(dataProvider); + dataProvider = NULL; + + return image; +} + +//-------------------------------------------------------------------------------------------------- + +/** + * Returns the vertical logical device resolution of the main monitor. + */ +int SurfaceImpl::LogPixelsY() +{ + NSSize deviceResolution = [[[[NSScreen mainScreen] deviceDescription] + objectForKey: NSDeviceResolution] sizeValue]; + return (int) deviceResolution.height; +} + +//-------------------------------------------------------------------------------------------------- + +/** + * Converts the logical font height (in dpi) into a pixel height for the current main screen. + */ +int SurfaceImpl::DeviceHeightFont(int points) +{ + int logPix = LogPixelsY(); + return (points * logPix + logPix / 2) / 72; +} + +//-------------------------------------------------------------------------------------------------- + +void SurfaceImpl::MoveTo(int x_, int y_) +{ + x = x_; + y = y_; +} + +//-------------------------------------------------------------------------------------------------- + +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 + // divison 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, ColourAllocated fore, + ColourAllocated back) +{ + // Allocate memory for the array of points. + CGPoint *points = new CGPoint[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); + + // Set colours + FillColour(back); + PenColour(fore); + + // Draw the polygon + CGContextAddLines(gc, points, npts); + + // TODO: Should the path be automatically closed, or is that the caller's responsability? + // Explicitly close the path, so it is closed for stroking AND filling (implicit close = filling only) + CGContextClosePath( gc ); + CGContextDrawPath( gc, kCGPathFillStroke ); + + // Deallocate memory. + delete points; + points = NULL; +} + +//-------------------------------------------------------------------------------------------------- + +void SurfaceImpl::RectangleDraw(PRectangle rc, ColourAllocated fore, ColourAllocated 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. + // TODO: Create some version of PRectangleToCGRect to do this conversion for us? + 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, ColourAllocated back) +{ + if (gc) + { + FillColour(back); + CGRect rect = PRectangleToCGRect(rc); + CGContextFillRect(gc, rect); + } +} + +//-------------------------------------------------------------------------------------------------- + +void drawImageRefCallback(CGImageRef pattern, CGContextRef gc) +{ + CGContextDrawImage(gc, CGRectMake(0, 0, CGImageGetWidth(pattern), CGImageGetHeight(pattern)), pattern); +} + +//-------------------------------------------------------------------------------------------------- + +void SurfaceImpl::FillRectangle(PRectangle rc, Surface &surfacePattern) +{ + SurfaceImpl& patternSurface = static_cast(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, ColourAllocated(0)); + return; + } + + const CGPatternCallbacks drawImageCallbacks = { 0, + reinterpret_cast(drawImageRefCallback), NULL }; + + 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 float 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; + CGImageRelease( image ); + image = NULL; + } /* pattern != NULL */ +} + +void SurfaceImpl::RoundedRectangle(PRectangle rc, ColourAllocated fore, ColourAllocated back) { + // TODO: Look at the Win32 API to determine what this is supposed to do: + // ::RoundRect(hdc, rc.left + 1, rc.top, rc.right - 1, rc.bottom, 8, 8 ); + + // Create a rectangle with semicircles at the corners + const int MAX_RADIUS = 4; + int radius = Platform::Minimum( MAX_RADIUS, rc.Height()/2 ); + radius = Platform::Minimum( radius, 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 + // TODO: Should I include these +0.5 in the array creation code above? + for( int i = 0; i < 4*3; ++ i ) + { + CGPoint* c = (CGPoint*) corners; + c[i].x += 0.5; + c[i].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 ); +} + +void Scintilla::SurfaceImpl::AlphaRectangle(PRectangle rc, int /*cornerSize*/, ColourAllocated fill, int alphaFill, + ColourAllocated /*outline*/, int /*alphaOutline*/, int /*flags*/) +{ + if ( gc ) { + ColourDesired colour( fill.AsLong() ); + + // Set the Fill color to match + CGContextSetRGBFillColor( gc, colour.GetRed() / 255.0, colour.GetGreen() / 255.0, colour.GetBlue() / 255.0, alphaFill / 100.0 ); + CGRect rect = PRectangleToCGRect( rc ); + CGContextFillRect( gc, rect ); + } +} + +void SurfaceImpl::Ellipse(PRectangle rc, ColourAllocated fore, ColourAllocated back) { + // Drawing an ellipse with bezier curves. Code modified from: + // http://www.codeguru.com/gdi/ellipse.shtml + // MAGICAL CONSTANT to map ellipse to beziers 2/3*(sqrt(2)-1) + const double EToBConst = 0.2761423749154; + + CGSize offset = CGSizeMake((int)(rc.Width() * EToBConst), (int)(rc.Height() * EToBConst)); + CGPoint centre = CGPointMake((rc.left + rc.right) / 2, (rc.top + rc.bottom) / 2); + + // The control point array + CGPoint cCtlPt[13]; + + // Assign values to all the control points + cCtlPt[0].x = + cCtlPt[1].x = + cCtlPt[11].x = + cCtlPt[12].x = rc.left + 0.5; + cCtlPt[5].x = + cCtlPt[6].x = + cCtlPt[7].x = rc.right - 0.5; + cCtlPt[2].x = + cCtlPt[10].x = centre.x - offset.width + 0.5; + cCtlPt[4].x = + cCtlPt[8].x = centre.x + offset.width + 0.5; + cCtlPt[3].x = + cCtlPt[9].x = centre.x + 0.5; + + cCtlPt[2].y = + cCtlPt[3].y = + cCtlPt[4].y = rc.top + 0.5; + cCtlPt[8].y = + cCtlPt[9].y = + cCtlPt[10].y = rc.bottom - 0.5; + cCtlPt[7].y = + cCtlPt[11].y = centre.y + offset.height + 0.5; + cCtlPt[1].y = + cCtlPt[5].y = centre.y - offset.height + 0.5; + cCtlPt[0].y = + cCtlPt[12].y = + cCtlPt[6].y = centre.y + 0.5; + + FillColour(back); + PenColour(fore); + + CGContextBeginPath( gc ); + CGContextMoveToPoint( gc, cCtlPt[0].x, cCtlPt[0].y ); + + for ( int i = 1; i < 13; i += 3 ) + { + CGContextAddCurveToPoint( gc, cCtlPt[i].x, cCtlPt[i].y, cCtlPt[i+1].x, cCtlPt[i+1].y, cCtlPt[i+2].x, cCtlPt[i+2].y ); + } + + // Close the path to enclose it for stroking and for filling, then draw it + CGContextClosePath( gc ); + CGContextDrawPath( gc, kCGPathFillStroke ); +} + +void SurfaceImpl::CopyImageRectangle(Surface &surfaceSource, PRectangle srcRect, PRectangle dstRect) +{ + SurfaceImpl& source = static_cast(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)) + { + float sx = CGRectGetWidth(dst) / CGRectGetWidth(src); + float sy = CGRectGetHeight(dst) / CGRectGetHeight(src); + float dx = CGRectGetMinX(dst) - (CGRectGetMinX(src) * sx); + float 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); +} + +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(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, ColourAllocated( 0 ) ); + return; + } + + // 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 ) ); + + //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 ); + + // Done with the image + CGImageRelease( image ); + image = NULL; +} + +//-------------------------------------------------------------------------------------------------- + +void SurfaceImpl::DrawTextNoClip(PRectangle rc, Font &font_, int ybase, const char *s, int len, + ColourAllocated fore, ColourAllocated back) +{ + FillRectangle(rc, back); + DrawTextTransparent(rc, font_, ybase, s, len, fore); +} + +//-------------------------------------------------------------------------------------------------- + +void SurfaceImpl::DrawTextClipped(PRectangle rc, Font &font_, int ybase, const char *s, int len, + ColourAllocated fore, ColourAllocated back) +{ + CGContextSaveGState(gc); + CGContextClipToRect(gc, PRectangleToCGRect(rc)); + DrawTextNoClip(rc, font_, ybase, s, len, fore, back); + CGContextRestoreGState(gc); +} + +//-------------------------------------------------------------------------------------------------- + +void SurfaceImpl::DrawTextTransparent(PRectangle rc, Font &font_, int ybase, const char *s, int len, + ColourAllocated fore) +{ + textLayout->setText (reinterpret_cast(s), len, *reinterpret_cast(font_.GetID())); + + // The Quartz RGB fill color influences the ATSUI color + FillColour(fore); + + // Draw text vertically flipped as OS X uses a coordinate system where +Y is upwards. + textLayout->draw(rc.left, ybase, true); +} + +//-------------------------------------------------------------------------------------------------- + +void SurfaceImpl::MeasureWidths(Font &font_, const char *s, int len, int *positions) +{ + // sample at http://developer.apple.com/samplecode/ATSUICurveAccessDemo/listing1.html + // sample includes use of ATSUGetGlyphInfo which would be better for older + // OSX systems. We should expand to using that on older systems as well. + for (int i = 0; i < len; i++) + positions [i] = 0; + + // We need the right X coords, so we have to append a char to get the left coord of thast extra char + char* buf = (char*) malloc (len+1); + if (!buf) + return; + + memcpy (buf, s, len); + buf [len] = '.'; + + textLayout->setText (reinterpret_cast(buf), len+1, *reinterpret_cast(font_.GetID())); + ATSUGlyphInfoArray* theGlyphInfoArrayPtr; + ByteCount theArraySize; + + // Get the GlyphInfoArray + ATSUTextLayout layout = textLayout->getLayout(); + if ( noErr == ATSUGetGlyphInfo (layout, 0, textLayout->getLength(), &theArraySize, NULL)) + { + theGlyphInfoArrayPtr = (ATSUGlyphInfoArray *) malloc (theArraySize + sizeof(ItemCount) + sizeof(ATSUTextLayout)); + if (theGlyphInfoArrayPtr) + { + if (noErr == ATSUGetGlyphInfo (layout, 0, textLayout->getLength(), &theArraySize, theGlyphInfoArrayPtr)) + { + // do not count the first item, which is at the beginning of the line + for ( UniCharCount unicodePosition = 1, i = 0; i < len && unicodePosition < theGlyphInfoArrayPtr->numGlyphs; unicodePosition ++ ) + { + // The ideal position is the x coordinate of the glyph, relative to the beginning of the line + int position = (int)( theGlyphInfoArrayPtr->glyphs[unicodePosition].idealX + 0.5 ); // These older APIs return float values + unsigned char uch = s[i]; + positions[i++] = position; + + // If we are using unicode (UTF8), map the Unicode position back to the UTF8 characters, + // as 1 unicode character can map to multiple UTF8 characters. + // See: http://www.tbray.org/ongoing/When/200x/2003/04/26/UTF + // Or: http://www.cl.cam.ac.uk/~mgk25/unicode.html + if ( unicodeMode ) + { + unsigned char mask = 0xc0; + int count = 1; + // Add one additonal byte for each extra high order one in the byte + while ( uch >= mask && count < 8 ) + { + positions[i++] = position; + count ++; + mask = mask >> 1 | 0x80; // add an additional one in the highest order position + } + } + } + } + + // Free the GlyphInfoArray + free (theGlyphInfoArrayPtr); + } + } + free (buf); +} + +int SurfaceImpl::WidthText(Font &font_, const char *s, int len) { + if (font_.GetID()) + { + textLayout->setText (reinterpret_cast(s), len, *reinterpret_cast(font_.GetID())); + + // TODO: Maybe I should add some sort of text measurement features to QuartzTextLayout? + unsigned long actualNumberOfBounds = 0; + ATSTrapezoid glyphBounds; + + // We get a single bound, since the text should only require one. If it requires more, there is an issue + if ( ATSUGetGlyphBounds( textLayout->getLayout(), 0, 0, kATSUFromTextBeginning, kATSUToTextEnd, kATSUseDeviceOrigins, 1, &glyphBounds, &actualNumberOfBounds ) != noErr || actualNumberOfBounds != 1 ) + { + Platform::DebugDisplay( "ATSUGetGlyphBounds failed in WidthText" ); + return 0; + } + + //Platform::DebugPrintf( "WidthText: \"%*s\" = %ld\n", len, s, Fix2Long( glyphBounds.upperRight.x - glyphBounds.upperLeft.x ) ); + return Fix2Long( glyphBounds.upperRight.x - glyphBounds.upperLeft.x ); + } + return 1; +} + +int SurfaceImpl::WidthChar(Font &font_, char ch) { + char str[2] = { ch, '\0' }; + if (font_.GetID()) + { + textLayout->setText (reinterpret_cast(str), 1, *reinterpret_cast(font_.GetID())); + + // TODO: Maybe I should add some sort of text measurement features to QuartzTextLayout? + unsigned long actualNumberOfBounds = 0; + ATSTrapezoid glyphBounds; + + // We get a single bound, since the text should only require one. If it requires more, there is an issue + if ( ATSUGetGlyphBounds( textLayout->getLayout(), 0, 0, kATSUFromTextBeginning, kATSUToTextEnd, kATSUseDeviceOrigins, 1, &glyphBounds, &actualNumberOfBounds ) != noErr || actualNumberOfBounds != 1 ) + { + Platform::DebugDisplay( "ATSUGetGlyphBounds failed in WidthChar" ); + return 0; + } + + return Fix2Long( glyphBounds.upperRight.x - glyphBounds.upperLeft.x ); + } + else + return 1; +} + +// Three possible strategies for determining ascent and descent of font: +// 1) Call ATSUGetGlyphBounds with string containing all letters, numbers and punctuation. +// 2) Use the ascent and descent fields of the font. +// 3) Call ATSUGetGlyphBounds with string as 1 but also including accented capitals. +// Smallest values given by 1 and largest by 3 with 2 in between. +// Techniques 1 and 2 sometimes chop off extreme portions of ascenders and +// descenders but are mostly OK except for accented characters which are +// rarely used in code. + +// This string contains a good range of characters to test for size. +const char sizeString[] = "`~!@#$%^&*()-_=+\\|[]{};:\"\'<,>.?/1234567890" +"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; + +int SurfaceImpl::Ascent(Font &font_) { + if (!font_.GetID()) + return 1; + + ATSUTextMeasurement ascent = reinterpret_cast( font_.GetID() )->getAttribute( kATSUAscentTag ); + return Fix2Long( ascent ); +} + +int SurfaceImpl::Descent(Font &font_) { + if (!font_.GetID()) + return 1; + + ATSUTextMeasurement descent = reinterpret_cast( font_.GetID() )->getAttribute( kATSUDescentTag ); + return Fix2Long( descent ); +} + +int SurfaceImpl::InternalLeading(Font &) { + // TODO: How do we get EM_Size? + // internal leading = ascent - descent - EM_size + return 0; +} + +int SurfaceImpl::ExternalLeading(Font &font_) { + if (!font_.GetID()) + return 1; + + ATSUTextMeasurement lineGap = reinterpret_cast( font_.GetID() )->getAttribute( kATSULeadingTag ); + return Fix2Long( lineGap ); +} + +int SurfaceImpl::Height(Font &font_) { + return Ascent(font_) + Descent(font_); +} + +int SurfaceImpl::AverageCharWidth(Font &font_) { + + if (!font_.GetID()) + return 1; + + const int sizeStringLength = (sizeof( sizeString ) / sizeof( sizeString[0] ) - 1); + int width = WidthText( font_, sizeString, sizeStringLength ); + + return (int) ((width / (float) sizeStringLength) + 0.5); + + /* + ATSUStyle textStyle = reinterpret_cast( font_.GetID() )->getATSUStyle(); + ATSUFontID fontID; + + ByteCount actualSize = 0; + if ( ATSUGetAttribute( textStyle, kATSUFontTag, sizeof( fontID ), &fontID, &actualSize ) != noErr ) + { + Platform::DebugDisplay( "ATSUGetAttribute failed" ); + return 1; + } + + ATSFontMetrics metrics; + memset( &metrics, 0, sizeof( metrics ) ); + if ( ATSFontGetHorizontalMetrics( fontID, kATSOptionFlagsDefault, &metrics ) != noErr ) + { + Platform::DebugDisplay( "ATSFontGetHorizontalMetrics failed in AverageCharWidth" ); + return 1; + } + + printf( "%f %f %f\n", metrics.avgAdvanceWidth * 32, metrics.ascent * 32, metrics.descent * 32 ); + + return (int) (metrics.avgAdvanceWidth + 0.5);*/ +} + +int SurfaceImpl::SetPalette(Scintilla::Palette *, bool) { + // Mac OS X is always true colour (I think) so this doesn't matter + return 0; +} + +void SurfaceImpl::SetClip(PRectangle rc) { + CGContextClipToRect( gc, PRectangleToCGRect( rc ) ); +} + +void SurfaceImpl::FlushCachedState() { + CGContextSynchronize( gc ); +} + +void SurfaceImpl::SetUnicodeMode(bool unicodeMode_) { + unicodeMode = unicodeMode_; +} + +void SurfaceImpl::SetDBCSMode(int codePage) { + // TODO: Implement this for code pages != UTF-8 +} + +Surface *Surface::Allocate() +{ + return new SurfaceImpl(); +} + +//----------------- Window ------------------------------------------------------------------------- + +Window::~Window() { +} + +//-------------------------------------------------------------------------------------------------- + +void Window::Destroy() +{ + if (windowRef) + { + // not used + } + wid = 0; +} + +//-------------------------------------------------------------------------------------------------- + +bool Window::HasFocus() +{ + NSView* container = reinterpret_cast(wid); + return [[container window] firstResponder] == container; +} + +//-------------------------------------------------------------------------------------------------- + +PRectangle Window::GetPosition() +{ + NSRect rect= [reinterpret_cast(wid) frame]; + + return PRectangle(NSMinX(rect), NSMinY(rect), NSMaxX(rect), NSMaxY(rect)); +} + +//-------------------------------------------------------------------------------------------------- + +void Window::SetPosition(PRectangle rc) +{ + // Moves this view inside the parent view + if ( wid ) + { + // Set the frame on the view, the function handles the rest + // CGRect r = PRectangleToCGRect( rc ); + // HIViewSetFrame( reinterpret_cast( wid ), &r ); + } +} + +//-------------------------------------------------------------------------------------------------- + +void Window::SetPositionRelative(PRectangle rc, Window window) { + // // used to actually move child windows (ie. listbox/calltip) so we have to move + // // the window, not the hiview + // if (windowRef) { + // // we go through some contortions here to get an accurate location for our + // // child windows. This is necessary due to the multiple ways an embedding + // // app may be setup. See SciTest/main.c (GOOD && BAD) for test case. + // WindowRef relativeWindow = GetControlOwner(reinterpret_cast( window.GetID() )); + // WindowRef thisWindow = reinterpret_cast( windowRef ); + // + // Rect portBounds; + // ::GetWindowBounds(relativeWindow, kWindowStructureRgn, &portBounds); + // //fprintf(stderr, "portBounds %d %d %d %d\n", portBounds.left, portBounds.top, portBounds.right, portBounds.bottom); + // PRectangle hbounds = window.GetPosition(); + // //fprintf(stderr, "hbounds %d %d %d %d\n", hbounds.left, hbounds.top, hbounds.right, hbounds.bottom); + // HIViewRef parent = HIViewGetSuperview(reinterpret_cast( window.GetID() )); + // Rect pbounds; + // GetControlBounds(parent, &pbounds); + // //fprintf(stderr, "pbounds %d %d %d %d\n", pbounds.left, pbounds.top, pbounds.right, pbounds.bottom); + // + // PRectangle bounds; + // bounds.top = portBounds.top + pbounds.top + hbounds.top + rc.top; + // bounds.bottom = bounds.top + rc.Height(); + // bounds.left = portBounds.left + pbounds.left + hbounds.left + rc.left; + // bounds.right = bounds.left + rc.Width(); + // //fprintf(stderr, "bounds %d %d %d %d\n", bounds.left, bounds.top, bounds.right, bounds.bottom); + // + // MoveWindow(thisWindow, bounds.left, bounds.top, false); + // SizeWindow(thisWindow, bounds.Width(), bounds.Height(), true); + // + // SetPosition(PRectangle(0,0,rc.Width(),rc.Height())); + // } else { + // 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 ) { + // HIViewSetVisible( reinterpret_cast( wid ), show ); + // } + // // this is necessary for calltip/listbox + // if (windowRef) { + // WindowRef thisWindow = reinterpret_cast( windowRef ); + // if (show) { + // ShowWindow( thisWindow ); + // DrawControls( thisWindow ); + // } else + // HideWindow( thisWindow ); + // } +} + +//-------------------------------------------------------------------------------------------------- + +/** + * Invalidates the entire window (here an NSView) so it is completely redrawn. + */ +void Window::InvalidateAll() +{ + if (wid) + { + NSView* container = reinterpret_cast(wid); + container.needsDisplay = YES; + } +} + +//-------------------------------------------------------------------------------------------------- + +/** + * Invalidates part of the window (here an NSView) so only this part redrawn. + */ +void Window::InvalidateRectangle(PRectangle rc) +{ + if (wid) + { + NSView* container = reinterpret_cast(wid); + [container setNeedsDisplayInRect: PRectangleToNSRect(rc)]; + } +} + +//-------------------------------------------------------------------------------------------------- + +void Window::SetFont(Font &) +{ + // TODO: Do I need to implement this? MSDN: specifies the font that a control is to use when drawing text. +} + +//-------------------------------------------------------------------------------------------------- + +/** + * 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) + { + InnerView* container = reinterpret_cast(wid); + [container setCursor: curs]; + } +} + +//-------------------------------------------------------------------------------------------------- + +void Window::SetTitle(const char *s) +{ + // WindowRef window = GetControlOwner(reinterpret_cast( wid )); + // CFStringRef title = CFStringCreateWithCString(kCFAllocatorDefault, s, kCFStringEncodingMacRoman); + // SetWindowTitleWithCFString(window, title); + // CFRelease(title); +} + +//-------------------------------------------------------------------------------------------------- + +PRectangle Window::GetMonitorRect(Point) +{ + return PRectangle(); +} + +//----------------- ListBox ------------------------------------------------------------------------ + +ListBox::ListBox() +{ +} + +//-------------------------------------------------------------------------------------------------- + +ListBox::~ListBox() +{ +} + +//-------------------------------------------------------------------------------------------------- + +static const OSType scintillaListBoxType = 'sclb'; + +enum { + kItemsPerContainer = 1, + kIconColumn = 'icon', + kTextColumn = 'text' +}; +static SInt32 kScrollBarWidth = 0; + +class LineData { + int *types; + CFStringRef *strings; + int len; + int maximum; +public: + LineData() :types(0), strings(0), len(0), maximum(0) {} + ~LineData() { + Clear(); + } + void Clear() { + delete []types; + types = 0; + for (int i=0; i= maximum) { + if (index >= len) { + int lenNew = (index+1) * 2; + int *typesNew = new int[lenNew]; + CFStringRef *stringsNew = new CFStringRef[lenNew]; + for (int i=0; i( kEventParamMouseButton, typeMouseButton, &inMouseButton ); + + UInt32 inClickCount; + event.GetParameter( kEventParamClickCount, &inClickCount ); + if (inMouseButton == kEventMouseButtonPrimary && inClickCount == 2) { + // handle our single mouse click now + ListBoxImpl* listbox = reinterpret_cast( inUserData ); + const WindowRef window = GetControlOwner(listbox->lb); + const HIViewRef rootView = HIViewGetRoot( window ); + HIViewRef targetView = NULL; + HIViewGetViewForMouseEvent( rootView, inEvent, &targetView ); + if ( targetView == listbox->lb ) + { + if (listbox->doubleClickAction != NULL) { + listbox->doubleClickAction(listbox->doubleClickActionData); + } + } + } + */ + } + } + } + return eventNotHandledErr; +} + +#ifdef DB_TABLE_ROW_HEIGHT +void ListBoxImpl::SetRowHeight(DataBrowserItemID itemID) +{ + // XXX does not seem to have any effect + //SetDataBrowserTableViewItemRowHeight(lb, itemID, lineHeight); +} +#endif + +void ListBoxImpl::DrawRow(DataBrowserItemID item, + DataBrowserPropertyID property, + DataBrowserItemState itemState, + const Rect *theRect) +{ + Rect row = *theRect; + row.left = 0; + + ColourPair fore; + + if (itemState == kDataBrowserItemIsSelected) { + long systemVersion; + Gestalt( gestaltSystemVersion, &systemVersion ); + // Panther DB starts using kThemeBrushSecondaryHighlightColor for inactive browser hilighting + if ( (systemVersion >= 0x00001030) )//&& (IsControlActive( lb ) == false) ) + ;//SetThemePen( kThemeBrushSecondaryHighlightColor, 32, true ); + else + ; //SetThemePen( kThemeBrushAlternatePrimaryHighlightColor, 32, true ); + + PaintRect(&row); + fore = ColourDesired(0xff,0xff,0xff); + } + + int widthPix = xset.GetWidth() + 2; + int pixId = ld.GetType(item - 1); + XPM *pxpm = xset.Get(pixId); + + char s[255]; + GetValue(item - 1, s, 255); + + Surface *surfaceItem = Surface::Allocate(); + if (surfaceItem) { + CGContextRef cgContext; + GrafPtr port; + Rect bounds; + + //GetControlBounds(lb, &bounds); + GetPort( &port ); + QDBeginCGContext( port, &cgContext ); + + CGContextSaveGState( cgContext ); + CGContextTranslateCTM(cgContext, 0, bounds.bottom - bounds.top); + CGContextScaleCTM(cgContext, 1.0, -1.0); + + surfaceItem->Init(cgContext, NULL); + + int left = row.left; + if (pxpm) { + PRectangle rc(left + 1, row.top, + left + 1 + widthPix, row.bottom); + pxpm->Draw(surfaceItem, rc); + } + + // draw the text + PRectangle trc(left + 2 + widthPix, row.top, row.right, row.bottom); + int ascent = surfaceItem->Ascent(font) - surfaceItem->InternalLeading(font); + int ytext = trc.top + ascent + 1; + trc.bottom = ytext + surfaceItem->Descent(font) + 1; + surfaceItem->DrawTextTransparent( trc, font, ytext, s, strlen(s), fore.allocated ); + + CGContextRestoreGState( cgContext ); + QDEndCGContext( port, &cgContext ); + delete surfaceItem; + } +} + + +pascal void ListBoxDrawItemCallback(ControlRef browser, DataBrowserItemID item, + DataBrowserPropertyID property, + DataBrowserItemState itemState, + const Rect *theRect, SInt16 gdDepth, + Boolean colorDevice) +{ + if (property != kIconColumn) return; + ListBoxImpl* lbThis = NULL; + //OSStatus err; + //err = GetControlProperty( browser, scintillaListBoxType, 0, sizeof( lbThis ), NULL, &lbThis ); + // adjust our rect + lbThis->DrawRow(item, property, itemState, theRect); + +} + +void ListBoxImpl::ConfigureDataBrowser() +{ + DataBrowserViewStyle viewStyle; + //DataBrowserSelectionFlags selectionFlags; + //GetDataBrowserViewStyle(lb, &viewStyle); + + //SetDataBrowserHasScrollBars(lb, false, true); + //SetDataBrowserListViewHeaderBtnHeight(lb, 0); + //GetDataBrowserSelectionFlags(lb, &selectionFlags); + //SetDataBrowserSelectionFlags(lb, selectionFlags |= kDataBrowserSelectOnlyOne); + // if you change the hilite style, also change the style in ListBoxDrawItemCallback + //SetDataBrowserTableViewHiliteStyle(lb, kDataBrowserTableViewFillHilite); + + Rect insetRect; + //GetDataBrowserScrollBarInset(lb, &insetRect); + + insetRect.right = kScrollBarWidth - 1; + //SetDataBrowserScrollBarInset(lb, &insetRect); + + switch (viewStyle) + { + case kDataBrowserListView: + { + DataBrowserListViewColumnDesc iconCol; + iconCol.headerBtnDesc.version = kDataBrowserListViewLatestHeaderDesc; + iconCol.headerBtnDesc.minimumWidth = 0; + iconCol.headerBtnDesc.maximumWidth = maxWidth; + iconCol.headerBtnDesc.titleOffset = 0; + iconCol.headerBtnDesc.titleString = NULL; + iconCol.headerBtnDesc.initialOrder = kDataBrowserOrderIncreasing; + + iconCol.headerBtnDesc.btnFontStyle.flags = kControlUseJustMask; + iconCol.headerBtnDesc.btnFontStyle.just = teFlushLeft; + + iconCol.headerBtnDesc.btnContentInfo.contentType = kControlContentTextOnly; + + iconCol.propertyDesc.propertyID = kIconColumn; + iconCol.propertyDesc.propertyType = kDataBrowserCustomType; + iconCol.propertyDesc.propertyFlags = kDataBrowserListViewSelectionColumn; + + //AddDataBrowserListViewColumn(lb, &iconCol, kDataBrowserListViewAppendColumn); + } break; + + } +} + +void ListBoxImpl::InstallDataBrowserCustomCallbacks() +{ + /* + DataBrowserCustomCallbacks callbacks; + + callbacks.version = kDataBrowserLatestCustomCallbacks; + verify_noerr(InitDataBrowserCustomCallbacks(&callbacks)); + callbacks.u.v1.drawItemCallback = NewDataBrowserDrawItemUPP(ListBoxDrawItemCallback); + callbacks.u.v1.hitTestCallback = NULL;//NewDataBrowserHitTestUPP(ListBoxHitTestCallback); + callbacks.u.v1.trackingCallback = NULL;//NewDataBrowserTrackingUPP(ListBoxTrackingCallback); + callbacks.u.v1.editTextCallback = NULL; + callbacks.u.v1.dragRegionCallback = NULL; + callbacks.u.v1.acceptDragCallback = NULL; + callbacks.u.v1.receiveDragCallback = NULL; + + SetDataBrowserCustomCallbacks(lb, &callbacks); + */ +} + +void ListBoxImpl::SetFont(Font &font_) { + // Having to do this conversion is LAME + QuartzTextStyle *ts = reinterpret_cast( font_.GetID() ); + ControlFontStyleRec style; + ATSUAttributeValuePtr value; + ATSUFontID fontID; + style.flags = kControlUseFontMask | kControlUseSizeMask | kControlAddToMetaFontMask; + ts->getAttribute( kATSUFontTag, sizeof(fontID), &fontID, NULL ); + ATSUFontIDtoFOND(fontID, &style.font, NULL); + ts->getAttribute( kATSUSizeTag, sizeof(Fixed), &value, NULL ); + style.size = ((SInt16)FixRound((SInt32)value)); + //SetControlFontStyle(lb, &style); + +#ifdef DB_TABLE_ROW_HEIGHT + // XXX this doesn't *stick* + ATSUTextMeasurement ascent = ts->getAttribute( kATSUAscentTag ); + ATSUTextMeasurement descent = ts->getAttribute( kATSUDescentTag ); + lineHeight = Fix2Long( ascent ) + Fix2Long( descent ); + //SetDataBrowserTableViewRowHeight(lb, lineHeight + lineLeading); +#endif + + // !@&^#%$ we cant copy Font, but we need one for our custom drawing + Str255 fontName255; + char fontName[256]; + FMGetFontFamilyName(style.font, fontName255); + + CFStringRef fontNameCF = ::CFStringCreateWithPascalString( kCFAllocatorDefault, fontName255, kCFStringEncodingMacRoman ); + ::CFStringGetCString( fontNameCF, fontName, (CFIndex)255, kCFStringEncodingMacRoman ); + + font.Create((const char *)fontName, 0, style.size, false, false); +} + +void ListBoxImpl::SetAverageCharWidth(int width) { + aveCharWidth = width; +} + +void ListBoxImpl::SetVisibleRows(int rows) { + desiredVisibleRows = rows; +} + +int ListBoxImpl::GetVisibleRows() const { + // XXX Windows & GTK do this, but it seems incorrect to me. Other logic + // to do with visible rows is essentially the same across platforms. + return desiredVisibleRows; + /* + // This would be more correct + int rows = Length(); + if ((rows == 0) || (rows > desiredVisibleRows)) + rows = desiredVisibleRows; + return rows; + */ +} + +PRectangle ListBoxImpl::GetDesiredRect() { + PRectangle rcDesired = GetPosition(); + + // XXX because setting the line height on the table doesnt + // *stick*, we'll have to suffer and just use whatever + // the table desides is the correct height. + UInt16 itemHeight;// = lineHeight; + //GetDataBrowserTableViewRowHeight(lb, &itemHeight); + + int rows = Length(); + if ((rows == 0) || (rows > desiredVisibleRows)) + rows = desiredVisibleRows; + + rcDesired.bottom = itemHeight * rows; + rcDesired.right = rcDesired.left + maxItemWidth + aveCharWidth; + + if (Length() > rows) + rcDesired.right += kScrollBarWidth; + rcDesired.right += IconWidth(); + + // Set the column width + //SetDataBrowserTableViewColumnWidth (lb, UInt16 (rcDesired.right - rcDesired.left)); + return rcDesired; +} + +void ListBoxImpl::ShowHideScrollbar() { + int rows = Length(); + if (rows > desiredVisibleRows) { + //SetDataBrowserHasScrollBars(lb, false, true); + } else { + //SetDataBrowserHasScrollBars(lb, false, false); + } +} + +int ListBoxImpl::IconWidth() { + return xset.GetWidth() + 2; +} + +int ListBoxImpl::CaretFromEdge() { + return 0; +} + +void ListBoxImpl::Clear() { + // passing NULL to "items" arg 4 clears the list + maxItemWidth = 0; + ld.Clear(); + //AddDataBrowserItems (lb, kDataBrowserNoItem, 0, NULL, kDataBrowserItemNoProperty); +} + +void ListBoxImpl::Append(char *s, int type) { + int count = Length(); + CFStringRef r = CFStringCreateWithCString(NULL, s, kTextEncodingMacRoman); + ld.Add(count, type, r); + + Scintilla::SurfaceImpl surface; + unsigned int width = surface.WidthText (font, s, strlen (s)); + if (width > maxItemWidth) + maxItemWidth = width; + + DataBrowserItemID items[1]; + items[0] = count + 1; + //AddDataBrowserItems (lb, kDataBrowserNoItem, 1, items, kDataBrowserItemNoProperty); + ShowHideScrollbar(); +} + +void ListBoxImpl::SetList(const char* list, char separator, char typesep) { + // XXX copied from PlatGTK, should be in base class + Clear(); + int count = strlen(list) + 1; + char *words = new char[count]; + if (words) { + memcpy(words, list, count); + char *startword = words; + 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 + i + 1; + numword = NULL; + } else if (words[i] == typesep) { + numword = words + i; + } + } + if (startword) { + if (numword) + *numword = '\0'; + Append(startword, numword?atoi(numword + 1):-1); + } + delete []words; + } +} + +int ListBoxImpl::Length() { + UInt32 numItems = 0; + //GetDataBrowserItemCount(lb, kDataBrowserNoItem, false, kDataBrowserItemAnyState, &numItems); + return (int)numItems; +} + +void ListBoxImpl::Select(int n) { + DataBrowserItemID items[1]; + items[0] = n + 1; + //SetDataBrowserSelectedItems(lb, 1, items, kDataBrowserItemsAssign); + //RevealDataBrowserItem(lb, items[0], kIconColumn, kDataBrowserRevealOnly); + // force update on selection + //Draw1Control(lb); +} + +int ListBoxImpl::GetSelection() { + Handle selectedItems = NewHandle(0); + //GetDataBrowserItems(lb, kDataBrowserNoItem, true, kDataBrowserItemIsSelected, selectedItems); + UInt32 numSelectedItems = GetHandleSize(selectedItems)/sizeof(DataBrowserItemID); + if (numSelectedItems == 0) { + return -1; + } + HLock( selectedItems ); + DataBrowserItemID *individualItem = (DataBrowserItemID*)( *selectedItems ); + DataBrowserItemID selected[numSelectedItems]; + selected[0] = *individualItem; + HUnlock( selectedItems ); + return selected[0] - 1; +} + +int ListBoxImpl::Find(const char *prefix) { + int count = Length(); + char s[255]; + for (int i = 0; i < count; i++) { + GetValue(i, s, 255); + if ((s[0] != '\0') && (0 == strncmp(prefix, s, strlen(prefix)))) { + return i; + } + } + return - 1; +} + +void ListBoxImpl::GetValue(int n, char *value, int len) { + CFStringRef textString = ld.GetString(n); + if (textString == NULL) { + value[0] = '\0'; + return; + } + CFIndex numUniChars = CFStringGetLength( textString ); + + // XXX how do we know the encoding of the listbox? + CFStringEncoding encoding = kCFStringEncodingUTF8; //( IsUnicodeMode() ? kCFStringEncodingUTF8 : kCFStringEncodingASCII); + CFIndex maximumByteLength = CFStringGetMaximumSizeForEncoding( numUniChars, encoding ) + 1; + char* text = new char[maximumByteLength]; + CFIndex usedBufferLength = 0; + CFStringGetBytes( textString, CFRangeMake( 0, numUniChars ), encoding, + '?', false, reinterpret_cast( text ), + maximumByteLength, &usedBufferLength ); + text[usedBufferLength] = '\0'; // null terminate the ASCII/UTF8 string + + if (text && len > 0) { + strncpy(value, text, len); + value[len - 1] = '\0'; + } else { + value[0] = '\0'; + } + delete text; +} + +void ListBoxImpl::Sort() { + // TODO: Implement this + fprintf(stderr, "ListBox::Sort\n"); +} + +void ListBoxImpl::RegisterImage(int type, const char *xpm_data) { + xset.Add(type, xpm_data); +} + +void ListBoxImpl::ClearRegisteredImages() { + xset.Clear(); +} + +//----------------- ScintillaContextMenu ----------------------------------------------------------- + +@implementation ScintillaContextMenu : NSMenu + +// This NSMenu subclass serves also as target for menu commands and forwards them as +// notfication messages to the front end. + +- (void) handleCommand: (NSMenuItem*) sender +{ + owner->HandleCommand([sender tag]); +} + +//-------------------------------------------------------------------------------------------------- + +- (void) setOwner: (Scintilla::ScintillaCocoa*) newOwner +{ + owner = newOwner; +} + +@end + +//----------------- Menu --------------------------------------------------------------------------- + +Menu::Menu() + : mid(0) +{ +} + +//-------------------------------------------------------------------------------------------------- + +void Menu::CreatePopUp() +{ + Destroy(); + mid = [[ScintillaContextMenu alloc] initWithTitle: @""]; +} + +//-------------------------------------------------------------------------------------------------- + +void Menu::Destroy() +{ + ScintillaContextMenu* menu = reinterpret_cast(mid); + [menu release]; + mid = NULL; +} + +//-------------------------------------------------------------------------------------------------- + +void Menu::Show(Point pt, Window &) +{ + // Cocoa menus are handled a bit differently. We only create the menu. The framework + // takes care to show it properly. +} + +//----------------- ElapsedTime -------------------------------------------------------------------- + +// TODO: Consider if I should be using GetCurrentEventTime instead of gettimeoday +ElapsedTime::ElapsedTime() { + struct timeval curTime; + int retVal; + retVal = gettimeofday( &curTime, NULL ); + + bigBit = curTime.tv_sec; + littleBit = curTime.tv_usec; +} + +double ElapsedTime::Duration(bool reset) { + struct timeval curTime; + int retVal; + retVal = 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::ChromeHighlight() +{ + return ColourDesired(0xFF, 0xFF, 0xFF); +} + +//-------------------------------------------------------------------------------------------------- + +/** + * Returns the currently set system font for the user. + */ +const char *Platform::DefaultFont() +{ + NSString* name = [[NSUserDefaults standardUserDefaults] stringForKey: @"NSFixedPitchFont"]; + return [name UTF8String]; +} + +//-------------------------------------------------------------------------------------------------- + +/** + * Returns the currently set system font size for the user. + */ +int Platform::DefaultFontSize() +{ + return [[NSUserDefaults standardUserDefaults] integerForKey: @"NSFixedPitchFontSize"]; +} + +//-------------------------------------------------------------------------------------------------- + +/** + * Returns the time span in which two consequtive mouse clicks must occur to be considered as + * double click. + * + * @return + */ +unsigned int Platform::DoubleClickTime() +{ + float threshold = [[NSUserDefaults standardUserDefaults] floatForKey: + @"com.apple.mouse.doubleClickThreshold"]; + if (threshold == 0) + threshold = 0.5; + return static_cast(threshold / kEventDurationMillisecond); +} + +//-------------------------------------------------------------------------------------------------- + +bool Platform::MouseButtonBounce() +{ + return false; +} + +//-------------------------------------------------------------------------------------------------- + +/** + * Helper method for the backend to reach through to the scintiall window. + */ +long Platform::SendScintilla(WindowID w, unsigned int msg, unsigned long wParam, long lParam) +{ + return scintilla_send_message(w, msg, wParam, lParam); +} + +//-------------------------------------------------------------------------------------------------- + +/** + * Helper method for the backend to reach through to the scintiall window. + */ +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) +{ + // No support for DBCS. + return false; +} + +//-------------------------------------------------------------------------------------------------- + +int Platform::DBCSCharLength(int codePage, const char* s) +{ + // No support for DBCS. + return 1; +} + +//-------------------------------------------------------------------------------------------------- + +int Platform::DBCSCharMaxLength() +{ + // No support for DBCS. + return 2; +} + +//-------------------------------------------------------------------------------------------------- + +int Platform::Minimum(int a, int b) +{ + return (a < b) ? a : b; +} + +//-------------------------------------------------------------------------------------------------- + +int Platform::Maximum(int a, int b) { + return (a > b) ? a : b; +} + +//-------------------------------------------------------------------------------------------------- + +//#define TRACE +#ifdef TRACE + +void Platform::DebugDisplay(const char *s) +{ + fprintf( stderr, s ); +} + +//-------------------------------------------------------------------------------------------------- + +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); +} + +#else + +void Platform::DebugDisplay(const char *) {} + +void Platform::DebugPrintf(const char *, ...) {} + +#endif + +//-------------------------------------------------------------------------------------------------- + +static bool assertionPopUps = true; + +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]; + sprintf(buffer, "Assertion [%s] failed at %s %d", c, file, line); + strcat(buffer, "\r\n"); + Platform::DebugDisplay(buffer); +#ifdef DEBUG + // 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; +} + +//----------------- DynamicLibrary ----------------------------------------------------------------- + +/** + * Implements the platform specific part of library loading. + * + * @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 occured. + */ +DynamicLibrary* DynamicLibrary::Load(const char* modulePath) +{ + return NULL; +} + +//-------------------------------------------------------------------------------------------------- + diff --git a/scintilla/cocoa/QuartzTextLayout.h b/scintilla/cocoa/QuartzTextLayout.h new file mode 100644 index 00000000..c032da99 --- /dev/null +++ b/scintilla/cocoa/QuartzTextLayout.h @@ -0,0 +1,141 @@ +/* + * QuartzTextLayout.h + * + * Original Code by Evan Jones on Wed Oct 02 2002. + * Contributors: + * Shane Caraveo, ActiveState + * Bernd Paradies, Adobe + * + */ + +#ifndef _QUARTZ_TEXT_LAYOUT_H +#define _QUARTZ_TEXT_LAYOUT_H + +#include + +#include "QuartzTextStyle.h" + +class QuartzTextLayout +{ +public: + /** Create a text layout for drawing on the specified context. */ + QuartzTextLayout( CGContextRef context ) : layout( NULL ), unicode_string( NULL ), unicode_length( 0 ) + { + OSStatus err = ATSUCreateTextLayout( &layout ); + if (0 != err) + layout = NULL; + + setContext(context); + + ATSUAttributeTag tag = kATSULineLayoutOptionsTag; + ByteCount size = sizeof( ATSLineLayoutOptions ); + ATSLineLayoutOptions rendering = kATSLineUseDeviceMetrics; //| kATSLineFractDisable | kATSLineUseQDRendering + ATSUAttributeValuePtr valuePtr = &rendering; + err = ATSUSetLayoutControls( layout, 1, &tag, &size, &valuePtr ); + } + + ~QuartzTextLayout() + { + if (NULL != layout) + ATSUDisposeTextLayout( layout ); + layout = NULL; + + if ( unicode_string != NULL ) + { + delete[] unicode_string; + unicode_string = NULL; + unicode_length = 0; + } + } + + /** Assign a string to the text layout object. */ + // TODO: Create a UTF8 version + // TODO: Optimise the ASCII version by not copying so much + OSStatus setText( const UInt8* buffer, size_t byteLength, CFStringEncoding encoding ) + { + if (NULL == layout) + return -1; + CFStringRef str = CFStringCreateWithBytes( NULL, buffer, byteLength, encoding, false ); + if (!str) + return -1; + + unicode_length = CFStringGetLength( str ); + if (unicode_string) + delete[] unicode_string; + unicode_string = new UniChar[ unicode_length ]; + CFStringGetCharacters( str, CFRangeMake( 0, unicode_length ), unicode_string ); + + CFRelease( str ); + str = NULL; + + OSStatus err; + err = ATSUSetTextPointerLocation( layout, unicode_string, kATSUFromTextBeginning, kATSUToTextEnd, unicode_length ); + if( err != noErr ) return err; + + // Turn on the default font fallbacks + return ATSUSetTransientFontMatching( layout, true ); + } + + inline void setText( const UInt8* buffer, size_t byteLength, const QuartzTextStyle& r ) + { + this->setText( buffer, byteLength, kCFStringEncodingUTF8 ); + ATSUSetRunStyle( layout, r.getATSUStyle(), 0, unicode_length ); + } + + /** Apply the specified text style on the entire range of text. */ + void setStyle( const QuartzTextStyle& style ) + { + ATSUSetRunStyle( layout, style.getATSUStyle(), kATSUFromTextBeginning, kATSUToTextEnd ); + } + + /** Draw the text layout into the current CGContext at the specified position, flipping the CGContext's Y axis if required. + * @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. + * @param flipTextYAxis If true, the CGContext's Y axis will be flipped before drawing the text, and restored afterwards. Use this when drawing in an HIView's CGContext, where the origin is the top left corner. */ + void draw( float x, float y, bool flipTextYAxis = false ) + { + if (NULL == layout || 0 == unicode_length) + return; + if ( flipTextYAxis ) + { + CGContextSaveGState( gc ); + CGContextScaleCTM( gc, 1.0, -1.0 ); + y = -y; + } + + OSStatus err; + err = ATSUDrawText( layout, kATSUFromTextBeginning, kATSUToTextEnd, X2Fix( x ), X2Fix( y ) ); + + if ( flipTextYAxis ) CGContextRestoreGState( gc ); + } + + /** Sets a single text layout control on the ATSUTextLayout object. + * @param tag The control to set. + * @param size The size of the parameter pointed to by value. + * @param value A pointer to the new value for the control. + */ + void setControl( ATSUAttributeTag tag, ByteCount size, ATSUAttributeValuePtr value ) + { + ATSUSetLayoutControls( layout, 1, &tag, &size, &value ); + } + + ATSUTextLayout getLayout() { + return layout; + } + + inline CFIndex getLength() const { return unicode_length; } + inline void setContext (CGContextRef context) + { + gc = context; + if (NULL != layout) + setControl( kATSUCGContextTag, sizeof( gc ), &gc ); + } + +private: + ATSUTextLayout layout; + UniChar* unicode_string; + int unicode_length; + CGContextRef gc; +}; + +#endif diff --git a/scintilla/cocoa/QuartzTextStyle.h b/scintilla/cocoa/QuartzTextStyle.h new file mode 100644 index 00000000..58f08491 --- /dev/null +++ b/scintilla/cocoa/QuartzTextStyle.h @@ -0,0 +1,90 @@ +/* + * QuartzTextStyle.h + * + * Created by Evan Jones on Wed Oct 02 2002. + * + */ + +#ifndef _QUARTZ_TEXT_STYLE_H +#define _QUARTZ_TEXT_STYLE_H + +#include "QuartzTextStyleAttribute.h" + +class QuartzTextStyle +{ +public: + QuartzTextStyle() + { + ATSUCreateStyle( &style ); + } + + ~QuartzTextStyle() + { + if ( style != NULL ) + ATSUDisposeStyle( style ); + style = NULL; + } + + void setAttribute( ATSUAttributeTag tag, ByteCount size, ATSUAttributeValuePtr value ) + { + ATSUSetAttributes( style, 1, &tag, &size, &value ); + } + + void setAttribute( QuartzTextStyleAttribute& attribute ) + { + setAttribute( attribute.getTag(), attribute.getSize(), attribute.getValuePtr() ); + } + + void getAttribute( ATSUAttributeTag tag, ByteCount size, ATSUAttributeValuePtr value, ByteCount* actualSize ) + { + ATSUGetAttribute( style, tag, size, value, actualSize ); + } + + template + T getAttribute( ATSUAttributeTag tag ) + { + T value; + ByteCount actualSize; + ATSUGetAttribute( style, tag, sizeof( T ), &value, &actualSize ); + return value; + } + + // TODO: Is calling this actually faster than calling setAttribute multiple times? + void setAttributes( QuartzTextStyleAttribute* attributes[], int number ) + { + // Create the parallel arrays and initialize them properly + ATSUAttributeTag* tags = new ATSUAttributeTag[ number ]; + ByteCount* sizes = new ByteCount[ number ]; + ATSUAttributeValuePtr* values = new ATSUAttributeValuePtr[ number ]; + + for ( int i = 0; i < number; ++ i ) + { + tags[i] = attributes[i]->getTag(); + sizes[i] = attributes[i]->getSize(); + values[i] = attributes[i]->getValuePtr(); + } + + ATSUSetAttributes( style, number, tags, sizes, values ); + + // Free the arrays that were allocated + delete[] tags; + delete[] sizes; + delete[] values; + } + + void setFontFeature( ATSUFontFeatureType featureType, ATSUFontFeatureSelector selector ) + { + ATSUSetFontFeatures( style, 1, &featureType, &selector ); + } + + const ATSUStyle& getATSUStyle() const + { + return style; + } + +private: + ATSUStyle style; +}; + +#endif + diff --git a/scintilla/cocoa/QuartzTextStyleAttribute.h b/scintilla/cocoa/QuartzTextStyleAttribute.h new file mode 100644 index 00000000..21f6abc4 --- /dev/null +++ b/scintilla/cocoa/QuartzTextStyleAttribute.h @@ -0,0 +1,142 @@ +/** + * QuartzTextStyleAttribute.h + * + * Original Code by Evan Jones on Wed Oct 02 2002. + * Contributors: + * Shane Caraveo, ActiveState + * Bernd Paradies, Adobe + * + */ + + +#ifndef _QUARTZ_TEXT_STYLE_ATTRIBUTE_H +#define _QUARTZ_TEXT_STYLE_ATTRIBUTE_H + +class QuartzTextStyleAttribute +{ +public: + QuartzTextStyleAttribute() {} + virtual ~QuartzTextStyleAttribute() {} + virtual ByteCount getSize() const = 0; + virtual ATSUAttributeValuePtr getValuePtr() = 0; + virtual ATSUAttributeTag getTag() const = 0; +}; + +class QuartzTextSize : public QuartzTextStyleAttribute +{ +public: + QuartzTextSize( float points ) + { + size = X2Fix( points ); + } + + ByteCount getSize() const + { + return sizeof( size ); + } + + ATSUAttributeValuePtr getValuePtr() + { + return &size; + } + + ATSUAttributeTag getTag() const + { + return kATSUSizeTag; + } + +private: + Fixed size; +}; + +class QuartzTextStyleAttributeBoolean : public QuartzTextStyleAttribute +{ +public: + QuartzTextStyleAttributeBoolean( bool newVal ) : value( newVal ) {} + + ByteCount getSize() const + { + return sizeof( value ); + } + ATSUAttributeValuePtr getValuePtr() + { + return &value; + } + + virtual ATSUAttributeTag getTag() const = 0; + +private: + Boolean value; +}; + +class QuartzTextBold : public QuartzTextStyleAttributeBoolean +{ +public: + QuartzTextBold( bool newVal ) : QuartzTextStyleAttributeBoolean( newVal ) {} + ATSUAttributeTag getTag() const + { + return kATSUQDBoldfaceTag; + } +}; + +class QuartzTextItalic : public QuartzTextStyleAttributeBoolean +{ +public: + QuartzTextItalic( bool newVal ) : QuartzTextStyleAttributeBoolean( newVal ) {} + ATSUAttributeTag getTag() const + { + return kATSUQDItalicTag; + } +}; + +class QuartzTextUnderline : public QuartzTextStyleAttributeBoolean +{ +public: + QuartzTextUnderline( bool newVal ) : QuartzTextStyleAttributeBoolean( newVal ) {} + ATSUAttributeTag getTag() const { + return kATSUQDUnderlineTag; + } +}; + +class QuartzFont : public QuartzTextStyleAttribute +{ +public: + /** Create a font style from a name. */ + QuartzFont( const char* name, int length ) + { + assert( name != NULL && length > 0 && name[length] == '\0' ); + // try to create font + OSStatus err = ATSUFindFontFromName( const_cast( name ), length, kFontFullName, (unsigned) kFontNoPlatform, kFontRomanScript, (unsigned) kFontNoLanguage, &fontid ); + + // need a fallback if font isn't installed + if( err != noErr || fontid == kATSUInvalidFontID ) + ::ATSUFindFontFromName( "Lucida Grande", 13, kFontFullName, (unsigned) kFontNoPlatform, kFontRomanScript, (unsigned) kFontNoLanguage, &fontid ); + } + + ByteCount getSize() const + { + return sizeof( fontid ); + } + + ATSUAttributeValuePtr getValuePtr() + { + return &fontid; + } + + ATSUAttributeTag getTag() const + { + return kATSUFontTag; + } + + ATSUFontID getFontID() const + { + return fontid; + } + +private: + ATSUFontID fontid; +}; + + +#endif + diff --git a/scintilla/cocoa/SciTest.mk b/scintilla/cocoa/SciTest.mk new file mode 100644 index 00000000..9023def7 --- /dev/null +++ b/scintilla/cocoa/SciTest.mk @@ -0,0 +1,54 @@ +### start defines ### +NAME=Editor + +ARCH=-arch i386 +CC=gcc -x c++ $(ARCH) +CO=gcc -x objective-c++ $(ARCH) +LD=gcc $(ARCH) -framework Cocoa + +gDEFs=-DSCI_NAMESPACE -DSCI_LEXER + +INCS=-I../src/ -I../include/ -I. +CCX=$(CC) $(gDEFs) $(INCS) +CCO=$(CO) $(gDEFs) $(INCS) + +BLD=build/SciAppBuild +TARG=$(APP)/Contents/MacOS/$(NAME) +APP=$(BLD)/$(NAME).app + +all: $(BLD) $(TARG) + +clean: + -rm -rf $(BLD) + +$(APP): + -rm -rf $(APP) + -mkdir $(APP) + -mkdir $(APP)/Contents/ + -mkdir $(APP)/Contents/Frameworks/ + -mkdir $(APP)/Contents/MacOS/ + -mkdir $(APP)/Contents/Resources/ + -cp ScintillaTest/Info.plist $(APP)/Contents/Info.plist.bak + -sed "s/\$${EXECUTABLE_NAME}/$(NAME)/g" < $(APP)/Contents/Info.plist.bak > $(APP)/Contents/Info.plist.bak2 + -sed "s/\$${PRODUCT_NAME}/$(NAME)/g" < $(APP)/Contents/Info.plist.bak2 > $(APP)/Contents/Info.plist + -rm $(APP)/Contents/Info.plist.bak $(APP)/Contents/Info.plist.bak2 + -cp -r ScintillaTest/English.lproj $(APP)/Contents/Resources/ + /Developer/usr/bin/ibtool --errors --warnings --notices --output-format human-readable-text \ + --compile $(APP)/Contents/Resources/English.lproj/MainMenu.nib ScintillaTest/English.lproj/MainMenu.xib + -cp ScintillaTest/TestData.sql $(APP)/Contents/Resources/ + -make -f Framework.mk all + +$(TARG) : $(BLD)/main.o $(BLD)/AppController.o $(APP) + -cp -R build/framebuild/Sci.framework $(APP)/Contents/Frameworks/ + $(LD) $(BLD)/main.o $(BLD)/AppController.o $(APP)/Contents/Frameworks/Sci.framework/Sci -o $(TARG) -lstdc++ + + +$(BLD) : + -mkdir build + -mkdir $(BLD) + +$(BLD)/%.o : ScintillaTest/%.mm + $(CCO) -c $< -o $@ + +$(BLD)/%.o : ScintillaTest/%.m + $(CCO) -c $< -o $@ diff --git a/scintilla/cocoa/ScintillaCallTip.h b/scintilla/cocoa/ScintillaCallTip.h new file mode 100644 index 00000000..74c551ac --- /dev/null +++ b/scintilla/cocoa/ScintillaCallTip.h @@ -0,0 +1,63 @@ +/* + * ScintillaMacOSX.h + * tutorial + * + * Created by Evan Jones on Sun Sep 01 2002. + * + */ +#ifndef SCINTILLA_CALLTIP_H +#define SCINTILLA_CALLTIP_H + +#include "TView.h" + +#include +#include +#include +#include +#include + +#include "Platform.h" +#include "Scintilla.h" + +static const OSType scintillaCallTipType = 'Scct'; + +namespace Scintilla { + +class ScintillaCallTip : public TView +{ +public: + // Private so ScintillaCallTip objects can not be copied + ScintillaCallTip(const ScintillaCallTip &) : TView( NULL ) {} + ScintillaCallTip &operator=(const ScintillaCallTip &) { return * this; } + ~ScintillaCallTip() {}; + +public: + /** This is the class ID that we've assigned to Scintilla. */ + static const CFStringRef kScintillaCallTipClassID; + static const ControlKind kScintillaCallTipKind; + + ScintillaCallTip( void* windowid ); + + /** Returns the HIView object kind, needed to subclass TView. */ + virtual ControlKind GetKind() { return kScintillaCallTipKind; } + +private: + + virtual ControlPartCode HitTest( const HIPoint& where ); + virtual void Draw( RgnHandle rgn, CGContextRef gc ); + virtual OSStatus MouseDown( HIPoint& location, UInt32 modifiers, EventMouseButton button, UInt32 clickCount ); + virtual OSStatus MouseUp( HIPoint& location, UInt32 modifiers, EventMouseButton button, UInt32 clickCount ); + virtual OSStatus MouseDragged( HIPoint& location, UInt32 modifiers, EventMouseButton button, UInt32 clickCount ); + +public: + static HIViewRef Create(); +private: + static OSStatus Construct( HIViewRef inControl, TView** outView ); + +}; + + +} + + +#endif diff --git a/scintilla/cocoa/ScintillaCallTip.mm b/scintilla/cocoa/ScintillaCallTip.mm new file mode 100644 index 00000000..db72ee17 --- /dev/null +++ b/scintilla/cocoa/ScintillaCallTip.mm @@ -0,0 +1,117 @@ + +#include "ScintillaCocoa.h" +#include "ScintillaCallTip.h" +#include "CallTip.h" + +using namespace Scintilla; + +const CFStringRef ScintillaCallTip::kScintillaCallTipClassID = CFSTR( "org.scintilla.calltip" ); +const ControlKind ScintillaCallTip::kScintillaCallTipKind = { 'ejon', 'Scct' }; + +ScintillaCallTip::ScintillaCallTip( void* windowid ) : + TView( reinterpret_cast( windowid ) ) +{ + ActivateInterface( kMouse ); + // debugPrint = true; +} + +void ScintillaCallTip::Draw( + RgnHandle /*inLimitRgn*/, + CGContextRef inContext ) +{ + // Get a reference to the Scintilla C++ object + CallTip* ctip = NULL; + OSStatus err; + err = GetControlProperty( GetViewRef(), scintillaCallTipType, 0, sizeof( ctip ), NULL, &ctip ); + assert(err == noErr); + if (ctip == NULL) return; + + Rect contentBounds; + GetControlBounds(GetViewRef(), &contentBounds); + + HIRect controlFrame; + HIViewGetFrame( GetViewRef(), &controlFrame ); + + // what is the global pos? + Surface *surfaceWindow = Surface::Allocate(); + if (surfaceWindow) { + surfaceWindow->Init(inContext, GetViewRef()); + ctip->PaintCT(surfaceWindow); + surfaceWindow->Release(); + delete surfaceWindow; + } + +} + +ControlPartCode ScintillaCallTip::HitTest( const HIPoint& where ) +{ + if ( CGRectContainsPoint( Bounds(), where ) ) + return 1; + else + return kControlNoPart; +} + +OSStatus ScintillaCallTip::MouseDown(HIPoint& location, UInt32 /*inKeyModifiers*/, EventMouseButton button, UInt32 /*inClickCount*/ ) +{ + if ( button != kEventMouseButtonPrimary ) return eventNotHandledErr; + CallTip* ctip = NULL; + ScintillaCocoa *sciThis = NULL; + OSStatus err = GetControlProperty( GetViewRef(), scintillaCallTipType, 0, sizeof( ctip ), NULL, &ctip ); + err = GetControlProperty( GetViewRef(), scintillaMacOSType, 0, sizeof( sciThis ), NULL, &sciThis ); + ctip->MouseClick( Scintilla::Point( static_cast( location.x ), static_cast( location.y ) )); + sciThis->CallTipClick(); + return noErr; +} + +OSStatus ScintillaCallTip::MouseUp(HIPoint& /*inMouseLocation*/, UInt32 /*inKeyModifiers*/, EventMouseButton button, UInt32 /*inClickCount*/ ) +{ + if ( button != kEventMouseButtonPrimary ) return eventNotHandledErr; + return noErr; +} + +OSStatus ScintillaCallTip::MouseDragged( HIPoint& location, UInt32 /*modifiers*/, EventMouseButton /*button*/, UInt32 /*clickCount*/ ) +{ + SetThemeCursor( kThemeArrowCursor ); + return noErr; +} + +HIViewRef ScintillaCallTip::Create() +{ + // Register the HIView, if needed + static bool registered = false; + + if ( not registered ) + { + TView::RegisterSubclass( kScintillaCallTipClassID, Construct ); + registered = true; + } + + OSStatus err = noErr; + EventRef event = CreateInitializationEvent(); + assert( event != NULL ); + + HIViewRef control = NULL; + err = HIObjectCreate( kScintillaCallTipClassID, event, reinterpret_cast( &control ) ); + ReleaseEvent( event ); + if ( err == noErr ) { + Platform::DebugPrintf("ScintillaCallTip::Create control %08X\n",control); + return control; + } + return NULL; +} + +OSStatus ScintillaCallTip::Construct( HIViewRef inControl, TView** outView ) +{ + *outView = new ScintillaCallTip( inControl ); + Platform::DebugPrintf("ScintillaCallTip::Construct scintilla %08X\n",*outView); + if ( *outView != NULL ) + return noErr; + else + return memFullErr; +} + +extern "C" { +HIViewRef scintilla_calltip_new() { + return ScintillaCallTip::Create(); +} +} diff --git a/scintilla/cocoa/ScintillaCocoa.h b/scintilla/cocoa/ScintillaCocoa.h new file mode 100644 index 00000000..03b239c8 --- /dev/null +++ b/scintilla/cocoa/ScintillaCocoa.h @@ -0,0 +1,211 @@ +/* + * ScintillaCocoa.h + * + * Mike Lischke + * + * Based on ScintillaMacOSX.h + * Original code by Evan Jones on Sun Sep 01 2002. + * Contributors: + * Shane Caraveo, ActiveState + * Bernd Paradies, Adobe + * + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * This file is dual licensed under LGPL v2.1 and the Scintilla license (http://www.scintilla.org/License.txt). + */ + +#include +#include +#include +#include +#include + +#include + +#ifdef SCI_LEXER +#include "SciLexer.h" +#include "PropSet.h" +#include "PropSetSimple.h" +#include "Accessor.h" +#include "KeyWords.h" +#endif + +#include "SVector.h" +#include "SplitVector.h" +#include "Partitioning.h" +#include "RunStyles.h" +#include "ContractionState.h" +#include "CellBuffer.h" +#include "CallTip.h" +#include "KeyMap.h" +#include "Indicator.h" +#include "XPM.h" +#include "LineMarker.h" +#include "Style.h" +#include "AutoComplete.h" +#include "ViewStyle.h" +#include "CharClassify.h" +#include "Decoration.h" +#include "Document.h" +#include "Selection.h" +#include "PositionCache.h" +#include "Editor.h" +//#include "ScintillaCallTip.h" + +#include "ScintillaBase.h" + +extern "C" NSString* ScintillaRecPboardType; + +@class ScintillaView; + +/** + * Helper class to be used as timer target (NSTimer). + */ +@interface TimerTarget : NSObject +{ + void* mTarget; + NSNotificationQueue* notificationQueue; +} +- (id) init: (void*) target; +- (void) timerFired: (NSTimer*) timer; +- (void) idleTimerFired: (NSTimer*) timer; +- (void) idleTriggered: (NSNotification*) notification; +@end + +namespace Scintilla { + +/** + * On the Mac, there is no WM_COMMAND or WM_NOTIFY message that can be sent + * back to the parent. Therefore, there must be a callback handler that acts + * like a Windows WndProc, where Scintilla can send notifications to. Use + * ScintillaCocoa::RegisterNotifyHandler() to register such a handler. + * Message format is: + *
+ * WM_COMMAND: HIWORD (wParam) = notification code, LOWORD (wParam) = 0 (no control ID), lParam = ScintillaCocoa* + *
+ * WM_NOTIFY: wParam = 0 (no 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); + +/** + * Scintilla sends these two messages to the nofity handler. Please refer + * to the Windows API doc for details about the message format. + */ +#define WM_COMMAND 1001 +#define WM_NOTIFY 1002 + +/** + * Main scintilla class, implemented for OS X (Cocoa). + */ +class ScintillaCocoa : public ScintillaBase +{ +private: + TimerTarget* timerTarget; + NSEvent* lastMouseEvent; + + SciNotifyFunc notifyProc; + intptr_t notifyObj; + + bool capturedMouse; + + // Private so ScintillaCocoa objects can not be copied + ScintillaCocoa(const ScintillaCocoa &) : ScintillaBase() {} + ScintillaCocoa &operator=(const ScintillaCocoa &) { return * this; } + + bool GetPasteboardData(NSPasteboard* board, SelectionText* selectedText); + void SetPasteboardData(NSPasteboard* board, const SelectionText& selectedText); + + int scrollSpeed; + int scrollTicks; +protected: + NSView* ContentView(); + PRectangle GetClientRectangle(); + Point ConvertPoint(NSPoint point); + + virtual void Initialise(); + virtual void Finalise(); +public: + ScintillaCocoa(NSView* view); + virtual ~ScintillaCocoa(); + + void RegisterNotifyCallback(intptr_t windowid, SciNotifyFunc callback); + sptr_t WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam); + + ScintillaView* TopContainer(); + + void SyncPaint(void* gc, PRectangle rc); + void Draw(NSRect rect, CGContextRef gc); + + virtual sptr_t DefWndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam); + void SetTicking(bool on); + bool SetIdle(bool on); + void SetMouseCapture(bool on); + bool HaveMouseCapture(); + void SetVerticalScrollPos(); + void SetHorizontalScrollPos(); + bool ModifyScrollBars(int nMax, int nPage); + void Resize(); + void DoScroll(float position, NSScrollerPart part, bool horizontal); + + // Notifications for the owner. + void NotifyChange(); + void NotifyFocus(bool focus); + void NotifyParent(SCNotification scn); + void NotifyURIDropped(const char *uri); + + bool HasSelection(); + bool CanUndo(); + bool CanRedo(); + virtual void CopyToClipboard(const SelectionText &selectedText); + virtual void Copy(); + virtual bool CanPaste(); + virtual void Paste(); + virtual void Paste(bool rectangular); + virtual void CreateCallTipWindow(PRectangle rc); + virtual void AddToPopUp(const char *label, int cmd = 0, bool enabled = true); + virtual void ClaimSelection(); + + NSPoint GetCaretPosition(); + + static sptr_t DirectFunction(ScintillaCocoa *sciThis, unsigned int iMessage, uptr_t wParam, sptr_t lParam); + + void TimerFired(NSTimer* timer); + void IdleTimerFired(); + int InsertText(NSString* input); + + bool KeyboardInput(NSEvent* event); + void MouseDown(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(); + bool GetDragData(id info, NSPasteboard &pasteBoard, SelectionText* selectedText); + NSDragOperation DraggingEntered(id info); + NSDragOperation DraggingUpdated(id info); + void DraggingExited(id info); + bool PerformDragOperation(id info); + void DragScroll(); + + // Promote some methods needed for NSResponder actions. + virtual void SelectAll(); + void DeleteBackward(); + virtual void Cut(); + virtual void Undo(); + virtual void Redo(); + + virtual NSMenu* CreateContextMenu(NSEvent* event); + void HandleCommand(NSInteger command); + +// virtual OSStatus ActiveStateChanged(); +// +// virtual void CallTipClick(); + +}; + + +} + + diff --git a/scintilla/cocoa/ScintillaCocoa.mm b/scintilla/cocoa/ScintillaCocoa.mm new file mode 100644 index 00000000..9cb14a4b --- /dev/null +++ b/scintilla/cocoa/ScintillaCocoa.mm @@ -0,0 +1,1471 @@ + +/** + * Scintilla source code edit control + * ScintillaCocoa.mm - Cocoa subclass of ScintillaBase + * + * Written by Mike Lischke + * + * Loosely based on ScintillaMacOSX.cxx. + * Copyright 2003 by Evan Jones + * Based on ScintillaGTK.cxx Copyright 1998-2002 by Neil Hodgson + * The License.txt file describes the conditions under which this software may be distributed. + * + * Copyright (c) 2009, 2010 Sun Microsystems, Inc. All rights reserved. + * This file is dual licensed under LGPL v2.1 and the Scintilla license (http://www.scintilla.org/License.txt). + */ + +#import + +#import // Temporary + +#include "ScintillaView.h" +#include "PlatCocoa.h" + +using namespace Scintilla; + +#ifndef WM_UNICHAR +#define WM_UNICHAR 0x0109 +#endif + +NSString* ScintillaRecPboardType = @"com.scintilla.utf16-plain-text.rectangular"; + +//-------------------------------------------------------------------------------------------------- + +// Define keyboard shortcuts (equivalents) the Mac way. +#define SCI_CMD ( SCI_ALT | SCI_CTRL) +#define SCI_SCMD ( SCI_CMD | SCI_SHIFT) + +static const KeyToCommand macMapDefault[] = +{ + {SCK_DOWN, SCI_CMD, SCI_DOCUMENTEND}, + {SCK_UP, SCI_CMD, SCI_DOCUMENTSTART}, + {SCK_LEFT, SCI_CMD, SCI_VCHOME}, + {SCK_LEFT, SCI_SCMD, SCI_VCHOMEEXTEND}, + {SCK_RIGHT, SCI_CMD, SCI_LINEEND}, + {SCK_RIGHT, SCI_SCMD, SCI_LINEENDEXTEND}, + {SCK_DOWN, SCI_NORM, SCI_LINEDOWN}, + {SCK_DOWN, SCI_SHIFT, SCI_LINEDOWNEXTEND}, + {SCK_DOWN, SCI_CTRL, SCI_LINESCROLLDOWN}, + {SCK_DOWN, SCI_ASHIFT, SCI_LINEDOWNRECTEXTEND}, + {SCK_UP, SCI_NORM, SCI_LINEUP}, + {SCK_UP, SCI_SHIFT, SCI_LINEUPEXTEND}, + {SCK_UP, SCI_CTRL, 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_CSHIFT, SCI_WORDLEFTEXTEND}, + {SCK_LEFT, SCI_ASHIFT, SCI_WORDLEFTEXTEND}, + {SCK_RIGHT, SCI_NORM, SCI_CHARRIGHT}, + {SCK_RIGHT, SCI_SHIFT, SCI_CHARRIGHTEXTEND}, + {SCK_RIGHT, SCI_ALT, SCI_WORDRIGHT}, + {SCK_RIGHT, SCI_CSHIFT, SCI_WORDRIGHTEXTEND}, + {SCK_RIGHT, SCI_ASHIFT, SCI_WORDRIGHTEXTEND}, + {'/', 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_UNDO}, + {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}, +}; + +//-------------------------------------------------------------------------------------------------- + +@implementation TimerTarget + +- (id) init: (void*) target +{ + [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; +} + +//-------------------------------------------------------------------------------------------------- + +- (void) dealloc +{ + [notificationQueue release]; + [super dealloc]; +} + +//-------------------------------------------------------------------------------------------------- + +/** + * 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 +{ + reinterpret_cast(mTarget)->TimerFired(timer); +} + +//-------------------------------------------------------------------------------------------------- + +/** + * Another timer callback for the idle timer. + */ +- (void) idleTimerFired: (NSTimer*) 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: nil]; +} + +//-------------------------------------------------------------------------------------------------- + +/** + * 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 +{ + reinterpret_cast(mTarget)->IdleTimerFired(); +} + +@end + +//----------------- ScintillaCocoa ----------------------------------------------------------------- + +ScintillaCocoa::ScintillaCocoa(NSView* view) +{ + wMain= [view retain]; + timerTarget = [[[TimerTarget alloc] init: this] retain]; + Initialise(); +} + +//-------------------------------------------------------------------------------------------------- + +ScintillaCocoa::~ScintillaCocoa() +{ + SetTicking(false); + [timerTarget release]; + NSView* container = ContentView(); + [container release]; +} + +//-------------------------------------------------------------------------------------------------- + +/** + * Core initialization of the control. Everything that needs to be set up happens here. + */ +void ScintillaCocoa::Initialise() +{ + notifyObj = NULL; + notifyProc = NULL; + + capturedMouse = false; + + // 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); + + // Add Mac specific key bindings. + for (int i = 0; macMapDefault[i].key; i++) + kmap.AssignCmdKey(macMapDefault[i].key, macMapDefault[i].modifiers, macMapDefault[i].msg); + +} + +//-------------------------------------------------------------------------------------------------- + +/** + * We need some clean up. Do it here. + */ +void ScintillaCocoa::Finalise() +{ + SetTicking(false); + ScintillaBase::Finalise(); +} + +//-------------------------------------------------------------------------------------------------- + +/** + * Helper function to get the outer container which represents the Scintilla editor on application side. + */ +ScintillaView* ScintillaCocoa::TopContainer() +{ + NSView* container = static_cast(wMain.GetID()); + return static_cast([container superview]); +} + +//-------------------------------------------------------------------------------------------------- + +/** + * Helper function to get the inner container which represents the actual "canvas" we work with. + */ +NSView* ScintillaCocoa::ContentView() +{ + return static_cast(wMain.GetID()); +} + +//-------------------------------------------------------------------------------------------------- + +/** + * Instead of returning the size of the inner view we have to return the visible part of it + * in order to make scrolling working properly. + */ +PRectangle ScintillaCocoa::GetClientRectangle() +{ + NSView* host = ContentView(); + NSSize size = [host frame].size; + return PRectangle(0, 0, size.width, size.height); +} + +//-------------------------------------------------------------------------------------------------- + +/** + * Converts the given point from base coordinates to local coordinates and at the same time into + * a native Point structure. Base coordinates are used for the top window used in the view hierarchy. + */ +Scintilla::Point ScintillaCocoa::ConvertPoint(NSPoint point) +{ + NSView* container = ContentView(); + NSPoint result = [container convertPoint: point fromView: nil]; + + return Point(result.x, result.y); +} + +//-------------------------------------------------------------------------------------------------- + +/** + * A function to directly execute code that would usually go the long way via window messages. + * However this is a Windows metapher and not used here, hence we just call our fake + * window proc. The given parameters directly reflect the message parameters used on Windows. + * + * @param sciThis The target which is to be called. + * @param iMessage A code that indicates which message was sent. + * @param wParam One of the two free parameters for the message. Traditionally a word sized parameter + * (hence the w prefix). + * @param lParam The other of the two free parameters. A signed long. + */ +sptr_t ScintillaCocoa::DirectFunction(ScintillaCocoa *sciThis, unsigned int iMessage, uptr_t wParam, + sptr_t lParam) +{ + return sciThis->WndProc(iMessage, wParam, lParam); +} + +//-------------------------------------------------------------------------------------------------- + +/** + * 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 = reinterpret_cast(sci); + ScintillaCocoa* scintilla = [control backend]; + return scintilla->WndProc(iMessage, wParam, lParam); +} + +//-------------------------------------------------------------------------------------------------- + +/** + * That's our fake window procedure. On Windows each window has a dedicated procedure to handle + * commands (also used to synchronize UI and background threads), which is not the case in Cocoa. + * + * Messages handled here are almost solely for special commands of the backend. Everything which + * would be sytem 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) +{ + switch (iMessage) + { + case SCI_GETDIRECTFUNCTION: + return reinterpret_cast(DirectFunction); + + case SCI_GETDIRECTPOINTER: + return reinterpret_cast(this); + + case SCI_GRABFOCUS: + // TODO: implement it + break; + + case WM_UNICHAR: + // Special case not used normally. Characters passed in this way will be inserted + // regardless of their value or modifier states. That means no command interpretation is + // performed. + if (IsUnicodeMode()) + { + NSString* input = [[NSString stringWithCharacters: (const unichar*) &wParam length: 1] autorelease]; + const char* utf8 = [input UTF8String]; + AddCharUTF((char*) utf8, strlen(utf8), false); + return 1; + } + return 0; + + default: + unsigned int r = ScintillaBase::WndProc(iMessage, wParam, lParam); + + return r; + } + return 0l; +} + +//-------------------------------------------------------------------------------------------------- + +/** + * 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; +} + +//-------------------------------------------------------------------------------------------------- + +/** + * Enables or disables a timer that can trigger background processing at a regular interval, like + * drag scrolling or caret blinking. + */ +void ScintillaCocoa::SetTicking(bool on) +{ + if (timer.ticking != on) + { + timer.ticking = on; + if (timer.ticking) + { + // Scintilla ticks = milliseconds + // Using userInfo as flag to distinct between tick and idle timer. + NSTimer* tickTimer = [NSTimer scheduledTimerWithTimeInterval: timer.tickSize / 1000.0 + target: timerTarget + selector: @selector(timerFired:) + userInfo: nil + repeats: YES]; + timer.tickerID = reinterpret_cast(tickTimer); + } + else + if (timer.tickerID != NULL) + { + [reinterpret_cast(timer.tickerID) invalidate]; + timer.tickerID = 0; + } + } + timer.ticksToWait = caret.period; +} + +//-------------------------------------------------------------------------------------------------- + +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]; + idler.idlerID = reinterpret_cast(idleTimer); + } + else + if (idler.idlerID != NULL) + { + [reinterpret_cast(idler.idlerID) invalidate]; + idler.idlerID = 0; + } + } + return true; +} + +//-------------------------------------------------------------------------------------------------- + +void ScintillaCocoa::CopyToClipboard(const SelectionText &selectedText) +{ + SetPasteboardData([NSPasteboard generalPasteboard], selectedText); +} + +//-------------------------------------------------------------------------------------------------- + +void ScintillaCocoa::Copy() +{ + if (!sel.Empty()) + { + SelectionText selectedText; + CopySelectionRange(&selectedText); + CopyToClipboard(selectedText); + } +} + +//-------------------------------------------------------------------------------------------------- + +bool ScintillaCocoa::CanPaste() +{ + if (!Editor::CanPaste()) + return false; + + return GetPasteboardData([NSPasteboard generalPasteboard], NULL); +} + +//-------------------------------------------------------------------------------------------------- + +void ScintillaCocoa::Paste() +{ + Paste(false); +} + +//-------------------------------------------------------------------------------------------------- + +/** + * 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; + + if (!ok || !selectedText.s) + // No data or no flavor we support. + return; + + pdoc->BeginUndoAction(); + ClearSelection(); + if (selectedText.rectangular) + { + SelectionPosition selStart = sel.RangeMain().Start(); + PasteRectangular(selStart, selectedText.s, selectedText.len); + } + else + if (pdoc->InsertString(sel.RangeMain().caret.Position(), selectedText.s, selectedText.len)) + SetEmptySelection(sel.RangeMain().caret.Position() + selectedText.len); + + pdoc->EndUndoAction(); + + Redraw(); + EnsureCaretVisible(); +} + +//-------------------------------------------------------------------------------------------------- + +void ScintillaCocoa::CreateCallTipWindow(PRectangle rc) +{ +/* + // create a calltip window + if (!ct.wCallTip.Created()) { + WindowClass windowClass = kHelpWindowClass; + WindowAttributes attributes = kWindowNoAttributes; + Rect contentBounds; + WindowRef outWindow; + + // convert PRectangle to Rect + // this adjustment gets the calltip window placed in the correct location relative + // to our editor window + Rect bounds; + OSStatus err; + err = GetWindowBounds( this->GetOwner(), kWindowGlobalPortRgn, &bounds ); + assert( err == noErr ); + contentBounds.top = rc.top + bounds.top; + contentBounds.bottom = rc.bottom + bounds.top; + contentBounds.right = rc.right + bounds.left; + contentBounds.left = rc.left + bounds.left; + + // create our calltip hiview + HIViewRef ctw = scintilla_calltip_new(); + CallTip* objectPtr = &ct; + ScintillaCocoa* sciThis = this; + SetControlProperty( ctw, scintillaMacOSType, 0, sizeof( this ), &sciThis ); + SetControlProperty( ctw, scintillaCallTipType, 0, sizeof( objectPtr ), &objectPtr ); + + CreateNewWindow(windowClass, attributes, &contentBounds, &outWindow); + ControlRef root; + CreateRootControl(outWindow, &root); + + HIViewRef hiroot = HIViewGetRoot (outWindow); + HIViewAddSubview(hiroot, ctw); + + HIRect boundsRect; + HIViewGetFrame(hiroot, &boundsRect); + HIViewSetFrame( ctw, &boundsRect ); + + // bind the size of the calltip to the size of it's container window + HILayoutInfo layout = { + kHILayoutInfoVersionZero, + { + { NULL, kHILayoutBindTop, 0 }, + { NULL, kHILayoutBindLeft, 0 }, + { NULL, kHILayoutBindBottom, 0 }, + { NULL, kHILayoutBindRight, 0 } + }, + { + { NULL, kHILayoutScaleAbsolute, 0 }, + { NULL, kHILayoutScaleAbsolute, 0 } + + }, + { + { NULL, kHILayoutPositionTop, 0 }, + { NULL, kHILayoutPositionLeft, 0 } + } + }; + HIViewSetLayoutInfo(ctw, &layout); + + ct.wCallTip = root; + ct.wDraw = ctw; + ct.wCallTip.SetWindow(outWindow); + HIViewSetVisible(ctw,true); + + } +*/ +} + + +void ScintillaCocoa::AddToPopUp(const char *label, int cmd, bool enabled) +{ + NSMenuItem* item; + ScintillaContextMenu *menu= reinterpret_cast(popup.GetID()); + [menu setOwner: this]; + [menu setAutoenablesItems: NO]; + + if (cmd == 0) + item = [NSMenuItem separatorItem]; + else + item = [[NSMenuItem alloc] init]; + + [item setTarget: menu]; + [item setAction: @selector(handleCommand:)]; + [item setTag: cmd]; + [item setTitle: [NSString stringWithUTF8String: label]]; + [item setEnabled: enabled]; + + [menu addItem: item]; +} + +// ------------------------------------------------------------------------------------------------- + +void ScintillaCocoa::ClaimSelection() +{ + // Mac OS X does not have a primary selection. +} + +// ------------------------------------------------------------------------------------------------- + +/** + * 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() +{ + NSPoint result; + + result.y = pdoc->LineFromPosition(sel.RangeMain().caret.Position()); + result.x = sel.RangeMain().caret.Position() - pdoc->LineStart(result.y); + return result; +} + +// ------------------------------------------------------------------------------------------------- + +#pragma segment Drag + +/** + * 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. + int line = pdoc->LineFromPosition(posDrag.Position()); + int currentVisibleLine = cs.DisplayFromDoc(line); + int lastVisibleLine = Platform::Minimum(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; + } + } + +} + +//-------------------------------------------------------------------------------------------------- + +/** + * Called when a drag operation was initiated from within Scintilla. + */ +void ScintillaCocoa::StartDrag() +{ + if (sel.Empty()) + return; + + // Put the data to be dragged on the drag pasteboard. + SelectionText selectedText; + NSPasteboard* pasteboard = [NSPasteboard pasteboardWithName: NSDragPboard]; + CopySelectionRange(&selectedText); + SetPasteboardData(pasteboard, selectedText); + + // Prepare drag image. + PRectangle localRectangle = RectangleFromRange(sel.RangeMain().Start().Position(), sel.RangeMain().End().Position()); + NSRect selectionRectangle = PRectangleToNSRect(localRectangle); + + NSView* content = ContentView(); + +#if 0 // TODO: fix initialization of the drag image with CGImageRef. + // To get a bitmap of the text we're dragging, we just use Paint on a pixmap surface. + SurfaceImpl *sw = new SurfaceImpl(); + SurfaceImpl *pixmap = NULL; + + bool lastHideSelection = hideSelection; + hideSelection = true; + if (sw) + { + pixmap = new SurfaceImpl(); + if (pixmap) + { + PRectangle client = GetClientRectangle(); + PRectangle imageRect = NSRectToPRectangle(selectionRectangle); + paintState = painting; + //sw->InitPixMap(client.Width(), client.Height(), NULL, NULL); + sw->InitPixMap(imageRect.Width(), imageRect.Height(), NULL, NULL); + paintingAllText = true; + Paint(sw, imageRect); + paintState = notPainting; + + pixmap->InitPixMap(imageRect.Width(), imageRect.Height(), NULL, NULL); + + 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, 0, 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. + } + sw->Release(); + delete sw; + } + hideSelection = lastHideSelection; + + NSBitmapImageRep* bitmap = NULL; + if (pixmap) + { + bitmap = [[[NSBitmapImageRep alloc] initWithCGImage: pixmap->GetImage()] autorelease]; + pixmap->Release(); + delete pixmap; + } +#else + + // Poor man's drag image: take a snapshot of the content view. + [content lockFocus]; + NSBitmapImageRep* bitmap = [[[NSBitmapImageRep alloc] initWithFocusedViewRect: selectionRectangle] autorelease]; + [bitmap setColorSpaceName: NSDeviceRGBColorSpace]; + [content unlockFocus]; + +#endif + + NSImage* image = [[[NSImage alloc] initWithSize: selectionRectangle.size] autorelease]; + [image addRepresentation: bitmap]; + + NSImage* dragImage = [[[NSImage alloc] initWithSize: selectionRectangle.size] autorelease]; + [dragImage setBackgroundColor: [NSColor clearColor]]; + [dragImage lockFocus]; + [image dissolveToPoint: NSMakePoint(0.0, 0.0) fraction: 0.5]; + [dragImage unlockFocus]; + + NSPoint startPoint; + startPoint.x = selectionRectangle.origin.x; + startPoint.y = selectionRectangle.origin.y + selectionRectangle.size.height; + [content dragImage: dragImage + at: startPoint + offset: NSZeroSize + event: lastMouseEvent // Set in MouseMove. + pasteboard: pasteboard + source: content + slideBack: YES]; +} + +//-------------------------------------------------------------------------------------------------- + +/** + * Called when a drag operation reaches the control which was initiated outside. + */ +NSDragOperation ScintillaCocoa::DraggingEntered(id info) +{ + inDragDrop = ddDragging; + return DraggingUpdated(info); +} + +//-------------------------------------------------------------------------------------------------- + +/** + * Called frequently during a drag operation if we are the target. Keep telling the caller + * 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 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; + + 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; + + if ([[pasteboard types] containsObject: NSFilenamesPboardType]) + return (sourceDragMask & NSDragOperationGeneric); + return NSDragOperationNone; +} + +//-------------------------------------------------------------------------------------------------- + +/** + * Resets the current drag position as we are no longer the drag target. + */ +void ScintillaCocoa::DraggingExited(id info) +{ + SetDragPosition(SelectionPosition(invalidPosition)); + inDragDrop = ddNone; +} + +//-------------------------------------------------------------------------------------------------- + +/** + * Here is where the real work is done. Insert the text from the pasteboard. + */ +bool ScintillaCocoa::PerformDragOperation(id 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 (text.len > 0) + { + NSDragOperation operation = [info draggingSourceOperationMask]; + bool moving = (operation & NSDragOperationMove) != 0; + + DropAt(posDrag, text.s, moving, text.rectangular); + }; + } + + return true; +} + +//-------------------------------------------------------------------------------------------------- + +void ScintillaCocoa::SetPasteboardData(NSPasteboard* board, const SelectionText &selectedText) +{ + if (selectedText.len == 0) + return; + + NSString *string; + string = [NSString stringWithUTF8String: selectedText.s]; + + [board declareTypes:[NSArray arrayWithObjects: + NSStringPboardType, + selectedText.rectangular ? ScintillaRecPboardType : nil, + nil] owner:nil]; + + if (selectedText.rectangular) + { + // This is specific to scintilla, allows us to drag rectangular selections around the document. + [board setString: string forType: ScintillaRecPboardType]; + } + + [board setString: string forType: NSStringPboardType]; + +} + +//-------------------------------------------------------------------------------------------------- + +/** + * Helper method to retrieve the best fitting alternative from the general pasteboard. + */ +bool ScintillaCocoa::GetPasteboardData(NSPasteboard* board, SelectionText* selectedText) +{ + NSArray* supportedTypes = [NSArray arrayWithObjects: ScintillaRecPboardType, + NSStringPboardType, + nil]; + NSString *bestType = [board availableTypeFromArray: supportedTypes]; + NSString* data = [board stringForType: bestType]; + + if (data != nil) + { + if (selectedText != nil) + { + char* text = (char*) [data UTF8String]; + bool rectangular = bestType == ScintillaRecPboardType; + selectedText->Copy(text, strlen(text) + 1, SC_CP_UTF8, SC_CHARSET_DEFAULT , rectangular, false); + } + return true; + } + + return false; +} + +//-------------------------------------------------------------------------------------------------- + +void ScintillaCocoa::SetMouseCapture(bool on) +{ + capturedMouse = on; + /* + if (mouseDownCaptures) + { + if (capturedMouse) + WndProc(SCI_SETCURSOR, Window::cursorArrow, 0); + else + // Reset to normal. Actual image will be set on mouse move. + WndProc(SCI_SETCURSOR, (unsigned int) SC_CURSORNORMAL, 0); + } + */ +} + +//-------------------------------------------------------------------------------------------------- + +bool ScintillaCocoa::HaveMouseCapture() +{ + return capturedMouse; +} + +//-------------------------------------------------------------------------------------------------- + +/** + * Synchronously paint a rectangle of the window. + */ +void ScintillaCocoa::SyncPaint(void* gc, PRectangle rc) +{ + paintState = painting; + rcPaint = rc; + PRectangle rcText = GetTextRectangle(); + paintingAllText = rcPaint.Contains(rcText); + Surface *sw = Surface::Allocate(); + if (sw) + { + sw->Init(gc, wMain.GetID()); + Paint(sw, rc); + if (paintState == paintAbandoned) + { + // Do a full paint. + rcPaint = GetClientRectangle(); + paintState = painting; + paintingAllText = true; + Paint(sw, rcPaint); + } + sw->Release(); + delete sw; + } + paintState = notPainting; +} + +//-------------------------------------------------------------------------------------------------- + +/** + * Modfies the vertical scroll position to make the current top line show up as such. + */ +void ScintillaCocoa::SetVerticalScrollPos() +{ + ScintillaView* topContainer = TopContainer(); + + // Convert absolute coordinate into the range [0..1]. Keep in mind that the visible area + // does *not* belong to the scroll range. + float relativePosition = (float) topLine / MaxScrollPos(); + [topContainer setVerticalScrollPosition: relativePosition]; +} + +//-------------------------------------------------------------------------------------------------- + +void ScintillaCocoa::SetHorizontalScrollPos() +{ + ScintillaView* topContainer = TopContainer(); + PRectangle textRect = GetTextRectangle(); + + // Convert absolute coordinate into the range [0..1]. Keep in mind that the visible area + // does *not* belong to the scroll range. + float relativePosition = (float) xOffset / (scrollWidth - textRect.Width()); + [topContainer setHorizontalScrollPosition: relativePosition]; +} + +//-------------------------------------------------------------------------------------------------- + +/** + * Used to adjust both scrollers to reflect the current scroll range and position in the editor. + * + * @param nMax Number of lines in the editor. + * @param nPage Number of lines per scroll page. + * @return True if there was a change, otherwise false. + */ +bool ScintillaCocoa::ModifyScrollBars(int nMax, int nPage) +{ + // Input values are given in lines, not pixels, so we have to convert. + int lineHeight = WndProc(SCI_TEXTHEIGHT, 0, 0); + PRectangle bounds = GetTextRectangle(); + ScintillaView* topContainer = TopContainer(); + + // Set page size to the same value as the scroll range to hide the scrollbar. + int scrollRange = lineHeight * (nMax + 1); // +1 because the caller subtracted one. + int pageSize; + if (verticalScrollBarVisible) + pageSize = bounds.Height(); + else + pageSize = scrollRange; + bool verticalChange = [topContainer setVerticalScrollRange: scrollRange page: pageSize]; + + scrollRange = scrollWidth; + if (horizontalScrollBarVisible) + pageSize = bounds.Width(); + else + pageSize = scrollRange; + bool horizontalChange = [topContainer setHorizontalScrollRange: scrollRange page: pageSize]; + + return verticalChange || horizontalChange; +} + +//-------------------------------------------------------------------------------------------------- + +void ScintillaCocoa::Resize() +{ + ChangeSize(); +} + +//-------------------------------------------------------------------------------------------------- + +/** + * Called by the frontend control when the user manipulates one of the scrollers. + * + * @param position The relative position of the scroller in the range of [0..1]. + * @param part Specifies which part was clicked on by the user, so we can handle thumb tracking + * as well as page and line scrolling. + * @param horizontal True if the horizontal scroller was hit, otherwise false. + */ +void ScintillaCocoa::DoScroll(float position, NSScrollerPart part, bool horizontal) +{ + // If the given scroller part is not the knob (or knob slot) then the given position is not yet + // current and we have to update it. + if (horizontal) + { + // Horizontal offset is given in pixels. + PRectangle textRect = GetTextRectangle(); + int offset = (int) (position * (scrollWidth - textRect.Width())); + int smallChange = (int) (textRect.Width() / 30); + if (smallChange < 5) + smallChange = 5; + switch (part) + { + case NSScrollerDecrementLine: + offset -= smallChange; + break; + case NSScrollerDecrementPage: + offset -= textRect.Width(); + break; + case NSScrollerIncrementLine: + offset += smallChange; + break; + case NSScrollerIncrementPage: + offset += textRect.Width(); + break; + }; + HorizontalScrollTo(offset); + } + else + { + // VerticalScrolling is by line. + int topLine = (int) (position * MaxScrollPos()); + int page = LinesOnScreen(); + switch (part) + { + case NSScrollerDecrementLine: + topLine--; + break; + case NSScrollerDecrementPage: + topLine -= page; + break; + case NSScrollerIncrementLine: + topLine++; + break; + case NSScrollerIncrementPage: + topLine += page; + break; + }; + ScrollTo(topLine, true); + } +} + +//-------------------------------------------------------------------------------------------------- + +/** + * Used to register a callback function for a given window. This is used to emulate the way + * Windows notfies other controls (mainly up in the view hierarchy) about certain events. + * + * @param windowid A handle to a window. That value is generic and can be anything. It is passed + * through to the callback. + * @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::NotifyChange() +{ + if (notifyProc != NULL) + notifyProc(notifyObj, WM_COMMAND, (uintptr_t) (SCEN_CHANGE << 16), (uintptr_t) this); +} + +//-------------------------------------------------------------------------------------------------- + +void ScintillaCocoa::NotifyFocus(bool focus) +{ + if (notifyProc != NULL) + notifyProc(notifyObj, WM_COMMAND, (uintptr_t) ((focus ? SCEN_SETFOCUS : SCEN_KILLFOCUS) << 16), (uintptr_t) this); +} + +//-------------------------------------------------------------------------------------------------- + +/** + * Used to send a notification (as WM_NOTIFY call) to the procedure, which has been set by the call + * to RegisterNotifyCallback (so it is not necessarily the parent window). + * + * @param scn The notification to send. + */ +void ScintillaCocoa::NotifyParent(SCNotification scn) +{ + if (notifyProc != NULL) + { + scn.nmhdr.hwndFrom = (void*) this; + scn.nmhdr.idFrom = (unsigned int) wMain.GetID(); + notifyProc(notifyObj, WM_NOTIFY, (uintptr_t) 0, (uintptr_t) &scn); + } +} + +//-------------------------------------------------------------------------------------------------- + +void ScintillaCocoa::NotifyURIDropped(const char *uri) +{ + SCNotification scn; + scn.nmhdr.code = SCN_URIDROPPED; + scn.text = uri; + + NotifyParent(scn); +} + +//-------------------------------------------------------------------------------------------------- + +bool ScintillaCocoa::HasSelection() +{ + return !sel.Empty(); +} + +//-------------------------------------------------------------------------------------------------- + +bool ScintillaCocoa::CanUndo() +{ + return pdoc->CanUndo(); +} + +//-------------------------------------------------------------------------------------------------- + +bool ScintillaCocoa::CanRedo() +{ + return pdoc->CanRedo(); +} + +//-------------------------------------------------------------------------------------------------- + +void ScintillaCocoa::TimerFired(NSTimer* timer) +{ + Tick(); + DragScroll(); +} + +//-------------------------------------------------------------------------------------------------- + +void ScintillaCocoa::IdleTimerFired() +{ + bool more = Idle(); + if (!more) + SetIdle(false); +} + +//-------------------------------------------------------------------------------------------------- + +/** + * Main entry point for drawing the control. + * + * @param rect The area to paint, given in the sender's coordinate. + * @param gc The context we can use to paint. + */ +void ScintillaCocoa::Draw(NSRect rect, CGContextRef gc) +{ + SyncPaint(gc, NSRectToPRectangle(rect)); +} + +//-------------------------------------------------------------------------------------------------- + +/** + * Helper function to translate OS X key codes to Scintilla key codes. + */ +static inline UniChar KeyTranslate(UniChar unicodeChar) +{ + 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 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; + } +} + +//-------------------------------------------------------------------------------------------------- + +/** + * Main keyboard input handling method. It is called for any key down event, including function keys, + * numeric keypad input and whatnot. + * + * @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. + NSUInteger modifiers = [event modifierFlags]; + + NSString* input = [event characters]; + + bool control = (modifiers & NSControlKeyMask) != 0; + bool shift = (modifiers & NSShiftKeyMask) != 0; + bool command = (modifiers & NSCommandKeyMask) != 0; + bool alt = (modifiers & NSAlternateKeyMask) != 0; + + bool handled = false; + + // Handle each entry individually. Usually we only have one entry anway. + for (int i = 0; i < input.length; i++) + { + const UniChar originalKey = [input characterAtIndex: i]; + UniChar key = KeyTranslate(originalKey); + + bool consumed = false; // Consumed as command? + + // Signal command as control + alt. This leaves us without command + control and command + alt + // but that's what we get when we have a modifier key more than other platforms. + if (KeyDown(key, shift, control || command, alt || command, &consumed)) + handled = true; + if (consumed) + handled = true; + } + + return handled; +} + +//-------------------------------------------------------------------------------------------------- + +/** + * Used to insert already processed text provided by the Cocoa text input system. + */ +int ScintillaCocoa::InsertText(NSString* input) +{ + const char* utf8 = [input UTF8String]; + AddCharUTF((char*) utf8, strlen(utf8), false); + return true; +} + +//-------------------------------------------------------------------------------------------------- + +/** + * 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); + + // 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::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 control = ([event modifierFlags] & NSControlKeyMask) != 0; + + ButtonDown(Point(location.x, location.y), (int) (time * 1000), shift, control, command); +} + +//-------------------------------------------------------------------------------------------------- + +void ScintillaCocoa::MouseMove(NSEvent* event) +{ + lastMouseEvent = event; + + ButtonMove(ConvertPoint([event locationInWindow])); +} + +//-------------------------------------------------------------------------------------------------- + +void ScintillaCocoa::MouseUp(NSEvent* event) +{ + NSTimeInterval time = [event timestamp]; + bool control = ([event modifierFlags] & NSControlKeyMask) != 0; + + ButtonUp(ConvertPoint([event locationInWindow]), (int) (time * 1000), control); +} + +//-------------------------------------------------------------------------------------------------- + +void ScintillaCocoa::MouseWheel(NSEvent* event) +{ + bool command = ([event modifierFlags] & NSCommandKeyMask) != 0; + bool shift = ([event modifierFlags] & NSShiftKeyMask) != 0; + int delta; + if (shift) + delta = 10 * [event deltaX]; // Arbitrary scale factor. + else + { + // In order to make scrolling with larger offset smoother we scroll less lines the larger the + // delta value is. + if ([event deltaY] < 0) + delta = -(int) sqrt(-10.0 * [event deltaY]); + else + delta = (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 (delta > 0) + KeyCommand(SCI_ZOOMIN); + else + KeyCommand(SCI_ZOOMOUT); + } + else + if (shift) + HorizontalScrollTo(xOffset - delta); + else + ScrollTo(topLine - delta, true); +} + +//-------------------------------------------------------------------------------------------------- + +// Helper methods for NSResponder actions. + +void ScintillaCocoa::SelectAll() +{ + Editor::SelectAll(); +} + +void ScintillaCocoa::DeleteBackward() +{ + KeyDown(SCK_BACK, false, false, false, nil); +} + +void ScintillaCocoa::Cut() +{ + Editor::Cut(); +} + +void ScintillaCocoa::Undo() +{ + Editor::Undo(); +} + +void ScintillaCocoa::Redo() +{ + Editor::Undo(); +} + +//-------------------------------------------------------------------------------------------------- + +/** + * 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)); + + return reinterpret_cast(popup.GetID()); +} + +//-------------------------------------------------------------------------------------------------- + +/** + * An intermediate function to forward context menu commands from the menu action handler to + * scintilla. + */ +void ScintillaCocoa::HandleCommand(NSInteger command) +{ + Command(command); +} + +//-------------------------------------------------------------------------------------------------- + +//OSStatus ScintillaCocoa::ActiveStateChanged() +//{ +// // If the window is being deactivated, lose the focus and turn off the ticking +// if ( ! this->IsActive() ) { +// DropCaret(); +// //SetFocusState( false ); +// SetTicking( false ); +// } else { +// ShowCaretAtCurrentPosition(); +// } +// return noErr; +//} +// + +//-------------------------------------------------------------------------------------------------- + diff --git a/scintilla/cocoa/ScintillaFramework/English.lproj/InfoPlist.strings b/scintilla/cocoa/ScintillaFramework/English.lproj/InfoPlist.strings new file mode 100644 index 00000000..85e4bb6f Binary files /dev/null and b/scintilla/cocoa/ScintillaFramework/English.lproj/InfoPlist.strings differ diff --git a/scintilla/cocoa/ScintillaFramework/Info.plist b/scintilla/cocoa/ScintillaFramework/Info.plist new file mode 100644 index 00000000..08f1e5d8 --- /dev/null +++ b/scintilla/cocoa/ScintillaFramework/Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFile + + CFBundleIdentifier + com.sun.${PRODUCT_NAME:identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleSignature + ???? + CFBundleVersion + 1.0 + NSPrincipalClass + + + diff --git a/scintilla/cocoa/ScintillaFramework/ScintillaFramework.xcodeproj/project.pbxproj b/scintilla/cocoa/ScintillaFramework/ScintillaFramework.xcodeproj/project.pbxproj new file mode 100644 index 00000000..4c96bca7 --- /dev/null +++ b/scintilla/cocoa/ScintillaFramework/ScintillaFramework.xcodeproj/project.pbxproj @@ -0,0 +1,969 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 45; + objects = { + +/* Begin PBXBuildFile section */ + 11374AAA10514AA900651FE9 /* LexMarkdown.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 11374AA910514AA900651FE9 /* LexMarkdown.cxx */; }; + 2744E4DC0FC1682C00E85C33 /* AutoComplete.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E4CF0FC1682C00E85C33 /* AutoComplete.cxx */; }; + 2744E4DD0FC1682C00E85C33 /* CallTip.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E4D00FC1682C00E85C33 /* CallTip.cxx */; }; + 2744E4DE0FC1682C00E85C33 /* CellBuffer.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E4D10FC1682C00E85C33 /* CellBuffer.cxx */; }; + 2744E4DF0FC1682C00E85C33 /* CharClassify.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E4D20FC1682C00E85C33 /* CharClassify.cxx */; }; + 2744E4E00FC1682C00E85C33 /* ContractionState.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E4D30FC1682C00E85C33 /* ContractionState.cxx */; }; + 2744E4E10FC1682C00E85C33 /* Decoration.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E4D40FC1682C00E85C33 /* Decoration.cxx */; }; + 2744E4E20FC1682C00E85C33 /* Document.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E4D50FC1682C00E85C33 /* Document.cxx */; }; + 2744E4E30FC1682C00E85C33 /* DocumentAccessor.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E4D60FC1682C00E85C33 /* DocumentAccessor.cxx */; }; + 2744E4E40FC1682C00E85C33 /* Editor.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E4D70FC1682C00E85C33 /* Editor.cxx */; }; + 2744E4E50FC1682C00E85C33 /* ExternalLexer.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E4D80FC1682C00E85C33 /* ExternalLexer.cxx */; }; + 2744E4E60FC1682C00E85C33 /* Indicator.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E4D90FC1682C00E85C33 /* Indicator.cxx */; }; + 2744E4E70FC1682C00E85C33 /* KeyMap.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E4DA0FC1682C00E85C33 /* KeyMap.cxx */; }; + 2744E4E80FC1682C00E85C33 /* KeyWords.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E4DB0FC1682C00E85C33 /* KeyWords.cxx */; }; + 2744E5360FC1684700E85C33 /* LexAbaqus.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E4E90FC1684700E85C33 /* LexAbaqus.cxx */; }; + 2744E5370FC1684700E85C33 /* LexAda.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E4EA0FC1684700E85C33 /* LexAda.cxx */; }; + 2744E5380FC1684700E85C33 /* LexAPDL.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E4EB0FC1684700E85C33 /* LexAPDL.cxx */; }; + 2744E5390FC1684700E85C33 /* LexAsm.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E4EC0FC1684700E85C33 /* LexAsm.cxx */; }; + 2744E53A0FC1684700E85C33 /* LexAsn1.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E4ED0FC1684700E85C33 /* LexAsn1.cxx */; }; + 2744E53B0FC1684700E85C33 /* LexASY.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E4EE0FC1684700E85C33 /* LexASY.cxx */; }; + 2744E53C0FC1684700E85C33 /* LexAU3.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E4EF0FC1684700E85C33 /* LexAU3.cxx */; }; + 2744E53D0FC1684700E85C33 /* LexAVE.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E4F00FC1684700E85C33 /* LexAVE.cxx */; }; + 2744E53E0FC1684700E85C33 /* LexBaan.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E4F10FC1684700E85C33 /* LexBaan.cxx */; }; + 2744E53F0FC1684700E85C33 /* LexBash.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E4F20FC1684700E85C33 /* LexBash.cxx */; }; + 2744E5400FC1684700E85C33 /* LexBasic.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E4F30FC1684700E85C33 /* LexBasic.cxx */; }; + 2744E5410FC1684700E85C33 /* LexBullant.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E4F40FC1684700E85C33 /* LexBullant.cxx */; }; + 2744E5420FC1684700E85C33 /* LexCaml.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E4F50FC1684700E85C33 /* LexCaml.cxx */; }; + 2744E5430FC1684700E85C33 /* LexCLW.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E4F60FC1684700E85C33 /* LexCLW.cxx */; }; + 2744E5440FC1684700E85C33 /* LexCmake.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E4F70FC1684700E85C33 /* LexCmake.cxx */; }; + 2744E5450FC1684700E85C33 /* LexCOBOL.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E4F80FC1684700E85C33 /* LexCOBOL.cxx */; }; + 2744E5460FC1684700E85C33 /* LexConf.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E4F90FC1684700E85C33 /* LexConf.cxx */; }; + 2744E5470FC1684700E85C33 /* LexCPP.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E4FA0FC1684700E85C33 /* LexCPP.cxx */; }; + 2744E5480FC1684700E85C33 /* LexCrontab.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E4FB0FC1684700E85C33 /* LexCrontab.cxx */; }; + 2744E5490FC1684700E85C33 /* LexCsound.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E4FC0FC1684700E85C33 /* LexCsound.cxx */; }; + 2744E54A0FC1684700E85C33 /* LexCSS.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E4FD0FC1684700E85C33 /* LexCSS.cxx */; }; + 2744E54B0FC1684700E85C33 /* LexD.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E4FE0FC1684700E85C33 /* LexD.cxx */; }; + 2744E54C0FC1684700E85C33 /* LexEiffel.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E4FF0FC1684700E85C33 /* LexEiffel.cxx */; }; + 2744E54D0FC1684700E85C33 /* LexErlang.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E5000FC1684700E85C33 /* LexErlang.cxx */; }; + 2744E54E0FC1684700E85C33 /* LexEScript.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E5010FC1684700E85C33 /* LexEScript.cxx */; }; + 2744E54F0FC1684700E85C33 /* LexFlagship.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E5020FC1684700E85C33 /* LexFlagship.cxx */; }; + 2744E5500FC1684700E85C33 /* LexForth.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E5030FC1684700E85C33 /* LexForth.cxx */; }; + 2744E5510FC1684700E85C33 /* LexFortran.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E5040FC1684700E85C33 /* LexFortran.cxx */; }; + 2744E5520FC1684700E85C33 /* LexGAP.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E5050FC1684700E85C33 /* LexGAP.cxx */; }; + 2744E5530FC1684700E85C33 /* LexGui4Cli.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E5060FC1684700E85C33 /* LexGui4Cli.cxx */; }; + 2744E5540FC1684700E85C33 /* LexHaskell.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E5070FC1684700E85C33 /* LexHaskell.cxx */; }; + 2744E5550FC1684700E85C33 /* LexHTML.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E5080FC1684700E85C33 /* LexHTML.cxx */; }; + 2744E5560FC1684700E85C33 /* LexInno.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E5090FC1684700E85C33 /* LexInno.cxx */; }; + 2744E5570FC1684700E85C33 /* LexKix.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E50A0FC1684700E85C33 /* LexKix.cxx */; }; + 2744E5580FC1684700E85C33 /* LexLisp.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E50B0FC1684700E85C33 /* LexLisp.cxx */; }; + 2744E5590FC1684700E85C33 /* LexLout.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E50C0FC1684700E85C33 /* LexLout.cxx */; }; + 2744E55A0FC1684700E85C33 /* LexLua.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E50D0FC1684700E85C33 /* LexLua.cxx */; }; + 2744E55B0FC1684700E85C33 /* LexMagik.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E50E0FC1684700E85C33 /* LexMagik.cxx */; }; + 2744E55C0FC1684700E85C33 /* LexMatlab.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E50F0FC1684700E85C33 /* LexMatlab.cxx */; }; + 2744E55D0FC1684700E85C33 /* LexMetapost.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E5100FC1684700E85C33 /* LexMetapost.cxx */; }; + 2744E55E0FC1684700E85C33 /* LexMMIXAL.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E5110FC1684700E85C33 /* LexMMIXAL.cxx */; }; + 2744E55F0FC1684700E85C33 /* LexMPT.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E5120FC1684700E85C33 /* LexMPT.cxx */; }; + 2744E5600FC1684700E85C33 /* LexMSSQL.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E5130FC1684700E85C33 /* LexMSSQL.cxx */; }; + 2744E5610FC1684700E85C33 /* LexMySQL.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E5140FC1684700E85C33 /* LexMySQL.cxx */; }; + 2744E5620FC1684700E85C33 /* LexNimrod.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E5150FC1684700E85C33 /* LexNimrod.cxx */; }; + 2744E5630FC1684700E85C33 /* LexNsis.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E5160FC1684700E85C33 /* LexNsis.cxx */; }; + 2744E5640FC1684700E85C33 /* LexOpal.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E5170FC1684700E85C33 /* LexOpal.cxx */; }; + 2744E5650FC1684700E85C33 /* LexOthers.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E5180FC1684700E85C33 /* LexOthers.cxx */; }; + 2744E5660FC1684700E85C33 /* LexPascal.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E5190FC1684700E85C33 /* LexPascal.cxx */; }; + 2744E5670FC1684700E85C33 /* LexPB.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E51A0FC1684700E85C33 /* LexPB.cxx */; }; + 2744E5680FC1684700E85C33 /* LexPerl.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E51B0FC1684700E85C33 /* LexPerl.cxx */; }; + 2744E5690FC1684700E85C33 /* LexPLM.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E51C0FC1684700E85C33 /* LexPLM.cxx */; }; + 2744E56A0FC1684700E85C33 /* LexPOV.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E51D0FC1684700E85C33 /* LexPOV.cxx */; }; + 2744E56B0FC1684700E85C33 /* LexPowerPro.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E51E0FC1684700E85C33 /* LexPowerPro.cxx */; }; + 2744E56C0FC1684700E85C33 /* LexPowerShell.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E51F0FC1684700E85C33 /* LexPowerShell.cxx */; }; + 2744E56D0FC1684700E85C33 /* LexProgress.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E5200FC1684700E85C33 /* LexProgress.cxx */; }; + 2744E56E0FC1684700E85C33 /* LexPS.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E5210FC1684700E85C33 /* LexPS.cxx */; }; + 2744E56F0FC1684700E85C33 /* LexPython.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E5220FC1684700E85C33 /* LexPython.cxx */; }; + 2744E5700FC1684700E85C33 /* LexR.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E5230FC1684700E85C33 /* LexR.cxx */; }; + 2744E5710FC1684700E85C33 /* LexRebol.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E5240FC1684700E85C33 /* LexRebol.cxx */; }; + 2744E5720FC1684700E85C33 /* LexRuby.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E5250FC1684700E85C33 /* LexRuby.cxx */; }; + 2744E5730FC1684700E85C33 /* LexScriptol.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E5260FC1684700E85C33 /* LexScriptol.cxx */; }; + 2744E5740FC1684700E85C33 /* LexSmalltalk.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E5270FC1684700E85C33 /* LexSmalltalk.cxx */; }; + 2744E5750FC1684700E85C33 /* LexSML.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E5280FC1684700E85C33 /* LexSML.cxx */; }; + 2744E5760FC1684700E85C33 /* LexSorcus.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E5290FC1684700E85C33 /* LexSorcus.cxx */; }; + 2744E5770FC1684700E85C33 /* LexSpecman.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E52A0FC1684700E85C33 /* LexSpecman.cxx */; }; + 2744E5780FC1684700E85C33 /* LexSpice.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E52B0FC1684700E85C33 /* LexSpice.cxx */; }; + 2744E5790FC1684700E85C33 /* LexSQL.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E52C0FC1684700E85C33 /* LexSQL.cxx */; }; + 2744E57A0FC1684700E85C33 /* LexTACL.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E52D0FC1684700E85C33 /* LexTACL.cxx */; }; + 2744E57B0FC1684700E85C33 /* LexTADS3.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E52E0FC1684700E85C33 /* LexTADS3.cxx */; }; + 2744E57C0FC1684700E85C33 /* LexTAL.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E52F0FC1684700E85C33 /* LexTAL.cxx */; }; + 2744E57D0FC1684700E85C33 /* LexTCL.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E5300FC1684700E85C33 /* LexTCL.cxx */; }; + 2744E57E0FC1684700E85C33 /* LexTeX.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E5310FC1684700E85C33 /* LexTeX.cxx */; }; + 2744E57F0FC1684700E85C33 /* LexVB.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E5320FC1684700E85C33 /* LexVB.cxx */; }; + 2744E5800FC1684700E85C33 /* LexVerilog.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E5330FC1684700E85C33 /* LexVerilog.cxx */; }; + 2744E5810FC1684700E85C33 /* LexVHDL.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E5340FC1684700E85C33 /* LexVHDL.cxx */; }; + 2744E5820FC1684700E85C33 /* LexYAML.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E5350FC1684700E85C33 /* LexYAML.cxx */; }; + 2744E5900FC1685C00E85C33 /* LineMarker.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E5830FC1685C00E85C33 /* LineMarker.cxx */; }; + 2744E5910FC1685C00E85C33 /* PerLine.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E5840FC1685C00E85C33 /* PerLine.cxx */; }; + 2744E5920FC1685C00E85C33 /* PositionCache.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E5850FC1685C00E85C33 /* PositionCache.cxx */; }; + 2744E5930FC1685C00E85C33 /* PropSet.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E5860FC1685C00E85C33 /* PropSet.cxx */; }; + 2744E5940FC1685C00E85C33 /* RESearch.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E5870FC1685C00E85C33 /* RESearch.cxx */; }; + 2744E5950FC1685C00E85C33 /* RunStyles.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E5880FC1685C00E85C33 /* RunStyles.cxx */; }; + 2744E5960FC1685C00E85C33 /* ScintillaBase.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E5890FC1685C00E85C33 /* ScintillaBase.cxx */; }; + 2744E5970FC1685C00E85C33 /* Style.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E58A0FC1685C00E85C33 /* Style.cxx */; }; + 2744E5980FC1685C00E85C33 /* StyleContext.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E58B0FC1685C00E85C33 /* StyleContext.cxx */; }; + 2744E5990FC1685C00E85C33 /* UniConversion.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E58C0FC1685C00E85C33 /* UniConversion.cxx */; }; + 2744E59A0FC1685C00E85C33 /* ViewStyle.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E58D0FC1685C00E85C33 /* ViewStyle.cxx */; }; + 2744E59B0FC1685C00E85C33 /* WindowAccessor.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E58E0FC1685C00E85C33 /* WindowAccessor.cxx */; }; + 2744E59C0FC1685C00E85C33 /* XPM.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2744E58F0FC1685C00E85C33 /* XPM.cxx */; }; + 2744E5A40FC168A100E85C33 /* InfoBar.h in Headers */ = {isa = PBXBuildFile; fileRef = 2744E59D0FC168A100E85C33 /* InfoBar.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 2744E5AA0FC168A100E85C33 /* ScintillaView.h in Headers */ = {isa = PBXBuildFile; fileRef = 2744E5A30FC168A100E85C33 /* ScintillaView.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 2744E5AC0FC168B200E85C33 /* InfoBarCommunicator.h in Headers */ = {isa = PBXBuildFile; fileRef = 2744E5AB0FC168B200E85C33 /* InfoBarCommunicator.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 2744E5B20FC168C500E85C33 /* InfoBar.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2744E5AD0FC168C500E85C33 /* InfoBar.mm */; }; + 2744E5B30FC168C500E85C33 /* PlatCocoa.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2744E5AE0FC168C500E85C33 /* PlatCocoa.mm */; }; + 2744E5B50FC168C500E85C33 /* ScintillaCocoa.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2744E5B00FC168C500E85C33 /* ScintillaCocoa.mm */; }; + 2744E5B60FC168C500E85C33 /* ScintillaView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2744E5B10FC168C500E85C33 /* ScintillaView.mm */; }; + 277B5BDA104EE6B900F40CE4 /* Selection.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 277B5BD9104EE6B900F40CE4 /* Selection.cxx */; }; + 277B5BDD104EE6CF00F40CE4 /* PropSetSimple.h in Headers */ = {isa = PBXBuildFile; fileRef = 277B5BDB104EE6CF00F40CE4 /* PropSetSimple.h */; }; + 277B5BDE104EE6CF00F40CE4 /* Selection.h in Headers */ = {isa = PBXBuildFile; fileRef = 277B5BDC104EE6CF00F40CE4 /* Selection.h */; }; + 2791F3C60FC19F71009DBCF9 /* PlatCocoa.h in Headers */ = {isa = PBXBuildFile; fileRef = 2744E59E0FC168A100E85C33 /* PlatCocoa.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 2791F3C70FC19F71009DBCF9 /* Platform.h in Headers */ = {isa = PBXBuildFile; fileRef = 2744E4850FC1678600E85C33 /* Platform.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 2791F3C80FC19F71009DBCF9 /* SciLexer.h in Headers */ = {isa = PBXBuildFile; fileRef = 2744E4870FC1678600E85C33 /* SciLexer.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 2791F3C90FC19F71009DBCF9 /* Scintilla.h in Headers */ = {isa = PBXBuildFile; fileRef = 2744E4880FC1678600E85C33 /* Scintilla.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 2791F3E00FC1A390009DBCF9 /* ScintillaCocoa.h in Headers */ = {isa = PBXBuildFile; fileRef = 2744E5A20FC168A100E85C33 /* ScintillaCocoa.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 2791F3E30FC1A3AE009DBCF9 /* QuartzTextLayout.h in Headers */ = {isa = PBXBuildFile; fileRef = 2744E59F0FC168A100E85C33 /* QuartzTextLayout.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 2791F3E40FC1A3AE009DBCF9 /* QuartzTextStyleAttribute.h in Headers */ = {isa = PBXBuildFile; fileRef = 2744E5A00FC168A100E85C33 /* QuartzTextStyleAttribute.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 2791F3E50FC1A3AE009DBCF9 /* Accessor.h in Headers */ = {isa = PBXBuildFile; fileRef = 2744E4830FC1678600E85C33 /* Accessor.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 2791F3E60FC1A3AE009DBCF9 /* KeyWords.h in Headers */ = {isa = PBXBuildFile; fileRef = 2744E4840FC1678600E85C33 /* KeyWords.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 2791F3E70FC1A3AE009DBCF9 /* PropSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 2744E4860FC1678600E85C33 /* PropSet.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 2791F3E80FC1A3AE009DBCF9 /* ScintillaWidget.h in Headers */ = {isa = PBXBuildFile; fileRef = 2744E48A0FC1678600E85C33 /* ScintillaWidget.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 2791F3EA0FC1A3AE009DBCF9 /* WindowAccessor.h in Headers */ = {isa = PBXBuildFile; fileRef = 2744E48C0FC1678600E85C33 /* WindowAccessor.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 2791F3EB0FC1A3BD009DBCF9 /* AutoComplete.h in Headers */ = {isa = PBXBuildFile; fileRef = 2744E4990FC1681200E85C33 /* AutoComplete.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 2791F3EC0FC1A3BD009DBCF9 /* CallTip.h in Headers */ = {isa = PBXBuildFile; fileRef = 2744E49A0FC1681200E85C33 /* CallTip.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 2791F3ED0FC1A3BD009DBCF9 /* CellBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 2744E49B0FC1681200E85C33 /* CellBuffer.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 2791F3EE0FC1A3BD009DBCF9 /* CharacterSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 2744E49C0FC1681200E85C33 /* CharacterSet.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 2791F3EF0FC1A3BD009DBCF9 /* CharClassify.h in Headers */ = {isa = PBXBuildFile; fileRef = 2744E49D0FC1681200E85C33 /* CharClassify.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 2791F3F00FC1A3BD009DBCF9 /* ContractionState.h in Headers */ = {isa = PBXBuildFile; fileRef = 2744E49E0FC1681200E85C33 /* ContractionState.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 2791F3F10FC1A3BD009DBCF9 /* Decoration.h in Headers */ = {isa = PBXBuildFile; fileRef = 2744E49F0FC1681200E85C33 /* Decoration.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 2791F3F20FC1A3BD009DBCF9 /* Document.h in Headers */ = {isa = PBXBuildFile; fileRef = 2744E4A00FC1681200E85C33 /* Document.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 2791F3F30FC1A3BD009DBCF9 /* DocumentAccessor.h in Headers */ = {isa = PBXBuildFile; fileRef = 2744E4A10FC1681200E85C33 /* DocumentAccessor.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 2791F3F40FC1A3BD009DBCF9 /* Editor.h in Headers */ = {isa = PBXBuildFile; fileRef = 2744E4A20FC1681200E85C33 /* Editor.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 2791F3F50FC1A3BD009DBCF9 /* ExternalLexer.h in Headers */ = {isa = PBXBuildFile; fileRef = 2744E4A30FC1681200E85C33 /* ExternalLexer.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 2791F3F60FC1A3BD009DBCF9 /* Indicator.h in Headers */ = {isa = PBXBuildFile; fileRef = 2744E4A40FC1681200E85C33 /* Indicator.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 2791F3F70FC1A3BD009DBCF9 /* KeyMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 2744E4A50FC1681200E85C33 /* KeyMap.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 2791F3F80FC1A3BD009DBCF9 /* LineMarker.h in Headers */ = {isa = PBXBuildFile; fileRef = 2744E4A60FC1681200E85C33 /* LineMarker.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 2791F3F90FC1A3BD009DBCF9 /* Partitioning.h in Headers */ = {isa = PBXBuildFile; fileRef = 2744E4A70FC1681200E85C33 /* Partitioning.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 2791F3FA0FC1A3BD009DBCF9 /* PerLine.h in Headers */ = {isa = PBXBuildFile; fileRef = 2744E4A80FC1681200E85C33 /* PerLine.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 2791F3FB0FC1A3BD009DBCF9 /* PositionCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 2744E4A90FC1681200E85C33 /* PositionCache.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 2791F3FC0FC1A3BD009DBCF9 /* RESearch.h in Headers */ = {isa = PBXBuildFile; fileRef = 2744E4AA0FC1681200E85C33 /* RESearch.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 2791F3FD0FC1A3BD009DBCF9 /* RunStyles.h in Headers */ = {isa = PBXBuildFile; fileRef = 2744E4AB0FC1681200E85C33 /* RunStyles.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 2791F3FE0FC1A3BD009DBCF9 /* ScintillaBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 2744E4AC0FC1681200E85C33 /* ScintillaBase.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 2791F3FF0FC1A3BD009DBCF9 /* SplitVector.h in Headers */ = {isa = PBXBuildFile; fileRef = 2744E4AD0FC1681200E85C33 /* SplitVector.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 2791F4000FC1A3BD009DBCF9 /* Style.h in Headers */ = {isa = PBXBuildFile; fileRef = 2744E4AE0FC1681200E85C33 /* Style.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 2791F4010FC1A3BD009DBCF9 /* StyleContext.h in Headers */ = {isa = PBXBuildFile; fileRef = 2744E4AF0FC1681200E85C33 /* StyleContext.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 2791F4020FC1A3BD009DBCF9 /* SVector.h in Headers */ = {isa = PBXBuildFile; fileRef = 2744E4B00FC1681200E85C33 /* SVector.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 2791F4030FC1A3BD009DBCF9 /* UniConversion.h in Headers */ = {isa = PBXBuildFile; fileRef = 2744E4B10FC1681200E85C33 /* UniConversion.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 2791F4040FC1A3BD009DBCF9 /* ViewStyle.h in Headers */ = {isa = PBXBuildFile; fileRef = 2744E4B20FC1681200E85C33 /* ViewStyle.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 2791F4050FC1A3BD009DBCF9 /* XPM.h in Headers */ = {isa = PBXBuildFile; fileRef = 2744E4B30FC1681200E85C33 /* XPM.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 27FEF4540FC1B413005E115A /* info_bar_bg.png in Resources */ = {isa = PBXBuildFile; fileRef = 27FEF4510FC1B413005E115A /* info_bar_bg.png */; }; + 27FEF4550FC1B413005E115A /* mac_cursor_busy.png in Resources */ = {isa = PBXBuildFile; fileRef = 27FEF4520FC1B413005E115A /* mac_cursor_busy.png */; }; + 27FEF4560FC1B413005E115A /* mac_cursor_flipped.png in Resources */ = {isa = PBXBuildFile; fileRef = 27FEF4530FC1B413005E115A /* mac_cursor_flipped.png */; }; + 8DC2EF530486A6940098B216 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C1666FE841158C02AAC07 /* InfoPlist.strings */; }; + 8DC2EF570486A6940098B216 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7B1FEA5585E11CA2CBB /* Cocoa.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 0867D69BFE84028FC02AAC07 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = ""; }; + 0867D6A5FE840307C02AAC07 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = ""; }; + 089C1667FE841158C02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = ""; }; + 1058C7B1FEA5585E11CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = ""; }; + 11374AA910514AA900651FE9 /* LexMarkdown.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexMarkdown.cxx; path = ../../src/LexMarkdown.cxx; sourceTree = SOURCE_ROOT; }; + 2744E4830FC1678600E85C33 /* Accessor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Accessor.h; path = ../../include/Accessor.h; sourceTree = SOURCE_ROOT; }; + 2744E4840FC1678600E85C33 /* KeyWords.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = KeyWords.h; path = ../../include/KeyWords.h; sourceTree = SOURCE_ROOT; }; + 2744E4850FC1678600E85C33 /* Platform.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Platform.h; path = ../../include/Platform.h; sourceTree = SOURCE_ROOT; }; + 2744E4860FC1678600E85C33 /* PropSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PropSet.h; path = ../../include/PropSet.h; sourceTree = SOURCE_ROOT; }; + 2744E4870FC1678600E85C33 /* SciLexer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SciLexer.h; path = ../../include/SciLexer.h; sourceTree = SOURCE_ROOT; }; + 2744E4880FC1678600E85C33 /* Scintilla.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Scintilla.h; path = ../../include/Scintilla.h; sourceTree = SOURCE_ROOT; }; + 2744E48A0FC1678600E85C33 /* ScintillaWidget.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ScintillaWidget.h; path = ../../include/ScintillaWidget.h; sourceTree = SOURCE_ROOT; }; + 2744E48C0FC1678600E85C33 /* WindowAccessor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WindowAccessor.h; path = ../../include/WindowAccessor.h; sourceTree = SOURCE_ROOT; }; + 2744E4990FC1681200E85C33 /* AutoComplete.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AutoComplete.h; path = ../../src/AutoComplete.h; sourceTree = SOURCE_ROOT; }; + 2744E49A0FC1681200E85C33 /* CallTip.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CallTip.h; path = ../../src/CallTip.h; sourceTree = SOURCE_ROOT; }; + 2744E49B0FC1681200E85C33 /* CellBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CellBuffer.h; path = ../../src/CellBuffer.h; sourceTree = SOURCE_ROOT; }; + 2744E49C0FC1681200E85C33 /* CharacterSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CharacterSet.h; path = ../../src/CharacterSet.h; sourceTree = SOURCE_ROOT; }; + 2744E49D0FC1681200E85C33 /* CharClassify.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CharClassify.h; path = ../../src/CharClassify.h; sourceTree = SOURCE_ROOT; }; + 2744E49E0FC1681200E85C33 /* ContractionState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ContractionState.h; path = ../../src/ContractionState.h; sourceTree = SOURCE_ROOT; }; + 2744E49F0FC1681200E85C33 /* Decoration.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Decoration.h; path = ../../src/Decoration.h; sourceTree = SOURCE_ROOT; }; + 2744E4A00FC1681200E85C33 /* Document.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Document.h; path = ../../src/Document.h; sourceTree = SOURCE_ROOT; }; + 2744E4A10FC1681200E85C33 /* DocumentAccessor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DocumentAccessor.h; path = ../../src/DocumentAccessor.h; sourceTree = SOURCE_ROOT; }; + 2744E4A20FC1681200E85C33 /* Editor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Editor.h; path = ../../src/Editor.h; sourceTree = SOURCE_ROOT; }; + 2744E4A30FC1681200E85C33 /* ExternalLexer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ExternalLexer.h; path = ../../src/ExternalLexer.h; sourceTree = SOURCE_ROOT; }; + 2744E4A40FC1681200E85C33 /* Indicator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Indicator.h; path = ../../src/Indicator.h; sourceTree = SOURCE_ROOT; }; + 2744E4A50FC1681200E85C33 /* KeyMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = KeyMap.h; path = ../../src/KeyMap.h; sourceTree = SOURCE_ROOT; }; + 2744E4A60FC1681200E85C33 /* LineMarker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LineMarker.h; path = ../../src/LineMarker.h; sourceTree = SOURCE_ROOT; }; + 2744E4A70FC1681200E85C33 /* Partitioning.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Partitioning.h; path = ../../src/Partitioning.h; sourceTree = SOURCE_ROOT; }; + 2744E4A80FC1681200E85C33 /* PerLine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PerLine.h; path = ../../src/PerLine.h; sourceTree = SOURCE_ROOT; }; + 2744E4A90FC1681200E85C33 /* PositionCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PositionCache.h; path = ../../src/PositionCache.h; sourceTree = SOURCE_ROOT; }; + 2744E4AA0FC1681200E85C33 /* RESearch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RESearch.h; path = ../../src/RESearch.h; sourceTree = SOURCE_ROOT; }; + 2744E4AB0FC1681200E85C33 /* RunStyles.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RunStyles.h; path = ../../src/RunStyles.h; sourceTree = SOURCE_ROOT; }; + 2744E4AC0FC1681200E85C33 /* ScintillaBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ScintillaBase.h; path = ../../src/ScintillaBase.h; sourceTree = SOURCE_ROOT; }; + 2744E4AD0FC1681200E85C33 /* SplitVector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SplitVector.h; path = ../../src/SplitVector.h; sourceTree = SOURCE_ROOT; }; + 2744E4AE0FC1681200E85C33 /* Style.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Style.h; path = ../../src/Style.h; sourceTree = SOURCE_ROOT; }; + 2744E4AF0FC1681200E85C33 /* StyleContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = StyleContext.h; path = ../../src/StyleContext.h; sourceTree = SOURCE_ROOT; }; + 2744E4B00FC1681200E85C33 /* SVector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SVector.h; path = ../../src/SVector.h; sourceTree = SOURCE_ROOT; }; + 2744E4B10FC1681200E85C33 /* UniConversion.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = UniConversion.h; path = ../../src/UniConversion.h; sourceTree = SOURCE_ROOT; }; + 2744E4B20FC1681200E85C33 /* ViewStyle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ViewStyle.h; path = ../../src/ViewStyle.h; sourceTree = SOURCE_ROOT; }; + 2744E4B30FC1681200E85C33 /* XPM.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = XPM.h; path = ../../src/XPM.h; sourceTree = SOURCE_ROOT; }; + 2744E4CF0FC1682C00E85C33 /* AutoComplete.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AutoComplete.cxx; path = ../../src/AutoComplete.cxx; sourceTree = SOURCE_ROOT; }; + 2744E4D00FC1682C00E85C33 /* CallTip.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CallTip.cxx; path = ../../src/CallTip.cxx; sourceTree = SOURCE_ROOT; }; + 2744E4D10FC1682C00E85C33 /* CellBuffer.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CellBuffer.cxx; path = ../../src/CellBuffer.cxx; sourceTree = SOURCE_ROOT; }; + 2744E4D20FC1682C00E85C33 /* CharClassify.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CharClassify.cxx; path = ../../src/CharClassify.cxx; sourceTree = SOURCE_ROOT; }; + 2744E4D30FC1682C00E85C33 /* ContractionState.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ContractionState.cxx; path = ../../src/ContractionState.cxx; sourceTree = SOURCE_ROOT; }; + 2744E4D40FC1682C00E85C33 /* Decoration.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Decoration.cxx; path = ../../src/Decoration.cxx; sourceTree = SOURCE_ROOT; }; + 2744E4D50FC1682C00E85C33 /* Document.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Document.cxx; path = ../../src/Document.cxx; sourceTree = SOURCE_ROOT; }; + 2744E4D60FC1682C00E85C33 /* DocumentAccessor.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DocumentAccessor.cxx; path = ../../src/DocumentAccessor.cxx; sourceTree = SOURCE_ROOT; }; + 2744E4D70FC1682C00E85C33 /* Editor.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Editor.cxx; path = ../../src/Editor.cxx; sourceTree = SOURCE_ROOT; }; + 2744E4D80FC1682C00E85C33 /* ExternalLexer.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ExternalLexer.cxx; path = ../../src/ExternalLexer.cxx; sourceTree = SOURCE_ROOT; }; + 2744E4D90FC1682C00E85C33 /* Indicator.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Indicator.cxx; path = ../../src/Indicator.cxx; sourceTree = SOURCE_ROOT; }; + 2744E4DA0FC1682C00E85C33 /* KeyMap.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = KeyMap.cxx; path = ../../src/KeyMap.cxx; sourceTree = SOURCE_ROOT; }; + 2744E4DB0FC1682C00E85C33 /* KeyWords.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = KeyWords.cxx; path = ../../src/KeyWords.cxx; sourceTree = SOURCE_ROOT; }; + 2744E4E90FC1684700E85C33 /* LexAbaqus.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexAbaqus.cxx; path = ../../src/LexAbaqus.cxx; sourceTree = SOURCE_ROOT; }; + 2744E4EA0FC1684700E85C33 /* LexAda.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexAda.cxx; path = ../../src/LexAda.cxx; sourceTree = SOURCE_ROOT; }; + 2744E4EB0FC1684700E85C33 /* LexAPDL.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexAPDL.cxx; path = ../../src/LexAPDL.cxx; sourceTree = SOURCE_ROOT; }; + 2744E4EC0FC1684700E85C33 /* LexAsm.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexAsm.cxx; path = ../../src/LexAsm.cxx; sourceTree = SOURCE_ROOT; }; + 2744E4ED0FC1684700E85C33 /* LexAsn1.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexAsn1.cxx; path = ../../src/LexAsn1.cxx; sourceTree = SOURCE_ROOT; }; + 2744E4EE0FC1684700E85C33 /* LexASY.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexASY.cxx; path = ../../src/LexASY.cxx; sourceTree = SOURCE_ROOT; }; + 2744E4EF0FC1684700E85C33 /* LexAU3.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexAU3.cxx; path = ../../src/LexAU3.cxx; sourceTree = SOURCE_ROOT; }; + 2744E4F00FC1684700E85C33 /* LexAVE.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexAVE.cxx; path = ../../src/LexAVE.cxx; sourceTree = SOURCE_ROOT; }; + 2744E4F10FC1684700E85C33 /* LexBaan.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexBaan.cxx; path = ../../src/LexBaan.cxx; sourceTree = SOURCE_ROOT; }; + 2744E4F20FC1684700E85C33 /* LexBash.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexBash.cxx; path = ../../src/LexBash.cxx; sourceTree = SOURCE_ROOT; }; + 2744E4F30FC1684700E85C33 /* LexBasic.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexBasic.cxx; path = ../../src/LexBasic.cxx; sourceTree = SOURCE_ROOT; }; + 2744E4F40FC1684700E85C33 /* LexBullant.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexBullant.cxx; path = ../../src/LexBullant.cxx; sourceTree = SOURCE_ROOT; }; + 2744E4F50FC1684700E85C33 /* LexCaml.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexCaml.cxx; path = ../../src/LexCaml.cxx; sourceTree = SOURCE_ROOT; }; + 2744E4F60FC1684700E85C33 /* LexCLW.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexCLW.cxx; path = ../../src/LexCLW.cxx; sourceTree = SOURCE_ROOT; }; + 2744E4F70FC1684700E85C33 /* LexCmake.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexCmake.cxx; path = ../../src/LexCmake.cxx; sourceTree = SOURCE_ROOT; }; + 2744E4F80FC1684700E85C33 /* LexCOBOL.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexCOBOL.cxx; path = ../../src/LexCOBOL.cxx; sourceTree = SOURCE_ROOT; }; + 2744E4F90FC1684700E85C33 /* LexConf.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexConf.cxx; path = ../../src/LexConf.cxx; sourceTree = SOURCE_ROOT; }; + 2744E4FA0FC1684700E85C33 /* LexCPP.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexCPP.cxx; path = ../../src/LexCPP.cxx; sourceTree = SOURCE_ROOT; }; + 2744E4FB0FC1684700E85C33 /* LexCrontab.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexCrontab.cxx; path = ../../src/LexCrontab.cxx; sourceTree = SOURCE_ROOT; }; + 2744E4FC0FC1684700E85C33 /* LexCsound.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexCsound.cxx; path = ../../src/LexCsound.cxx; sourceTree = SOURCE_ROOT; }; + 2744E4FD0FC1684700E85C33 /* LexCSS.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexCSS.cxx; path = ../../src/LexCSS.cxx; sourceTree = SOURCE_ROOT; }; + 2744E4FE0FC1684700E85C33 /* LexD.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexD.cxx; path = ../../src/LexD.cxx; sourceTree = SOURCE_ROOT; }; + 2744E4FF0FC1684700E85C33 /* LexEiffel.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexEiffel.cxx; path = ../../src/LexEiffel.cxx; sourceTree = SOURCE_ROOT; }; + 2744E5000FC1684700E85C33 /* LexErlang.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexErlang.cxx; path = ../../src/LexErlang.cxx; sourceTree = SOURCE_ROOT; }; + 2744E5010FC1684700E85C33 /* LexEScript.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexEScript.cxx; path = ../../src/LexEScript.cxx; sourceTree = SOURCE_ROOT; }; + 2744E5020FC1684700E85C33 /* LexFlagship.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexFlagship.cxx; path = ../../src/LexFlagship.cxx; sourceTree = SOURCE_ROOT; }; + 2744E5030FC1684700E85C33 /* LexForth.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexForth.cxx; path = ../../src/LexForth.cxx; sourceTree = SOURCE_ROOT; }; + 2744E5040FC1684700E85C33 /* LexFortran.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexFortran.cxx; path = ../../src/LexFortran.cxx; sourceTree = SOURCE_ROOT; }; + 2744E5050FC1684700E85C33 /* LexGAP.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexGAP.cxx; path = ../../src/LexGAP.cxx; sourceTree = SOURCE_ROOT; }; + 2744E5060FC1684700E85C33 /* LexGui4Cli.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexGui4Cli.cxx; path = ../../src/LexGui4Cli.cxx; sourceTree = SOURCE_ROOT; }; + 2744E5070FC1684700E85C33 /* LexHaskell.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexHaskell.cxx; path = ../../src/LexHaskell.cxx; sourceTree = SOURCE_ROOT; }; + 2744E5080FC1684700E85C33 /* LexHTML.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexHTML.cxx; path = ../../src/LexHTML.cxx; sourceTree = SOURCE_ROOT; }; + 2744E5090FC1684700E85C33 /* LexInno.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexInno.cxx; path = ../../src/LexInno.cxx; sourceTree = SOURCE_ROOT; }; + 2744E50A0FC1684700E85C33 /* LexKix.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexKix.cxx; path = ../../src/LexKix.cxx; sourceTree = SOURCE_ROOT; }; + 2744E50B0FC1684700E85C33 /* LexLisp.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexLisp.cxx; path = ../../src/LexLisp.cxx; sourceTree = SOURCE_ROOT; }; + 2744E50C0FC1684700E85C33 /* LexLout.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexLout.cxx; path = ../../src/LexLout.cxx; sourceTree = SOURCE_ROOT; }; + 2744E50D0FC1684700E85C33 /* LexLua.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexLua.cxx; path = ../../src/LexLua.cxx; sourceTree = SOURCE_ROOT; }; + 2744E50E0FC1684700E85C33 /* LexMagik.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexMagik.cxx; path = ../../src/LexMagik.cxx; sourceTree = SOURCE_ROOT; }; + 2744E50F0FC1684700E85C33 /* LexMatlab.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexMatlab.cxx; path = ../../src/LexMatlab.cxx; sourceTree = SOURCE_ROOT; }; + 2744E5100FC1684700E85C33 /* LexMetapost.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexMetapost.cxx; path = ../../src/LexMetapost.cxx; sourceTree = SOURCE_ROOT; }; + 2744E5110FC1684700E85C33 /* LexMMIXAL.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexMMIXAL.cxx; path = ../../src/LexMMIXAL.cxx; sourceTree = SOURCE_ROOT; }; + 2744E5120FC1684700E85C33 /* LexMPT.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexMPT.cxx; path = ../../src/LexMPT.cxx; sourceTree = SOURCE_ROOT; }; + 2744E5130FC1684700E85C33 /* LexMSSQL.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexMSSQL.cxx; path = ../../src/LexMSSQL.cxx; sourceTree = SOURCE_ROOT; }; + 2744E5140FC1684700E85C33 /* LexMySQL.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexMySQL.cxx; path = ../../src/LexMySQL.cxx; sourceTree = SOURCE_ROOT; }; + 2744E5150FC1684700E85C33 /* LexNimrod.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexNimrod.cxx; path = ../../src/LexNimrod.cxx; sourceTree = SOURCE_ROOT; }; + 2744E5160FC1684700E85C33 /* LexNsis.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexNsis.cxx; path = ../../src/LexNsis.cxx; sourceTree = SOURCE_ROOT; }; + 2744E5170FC1684700E85C33 /* LexOpal.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexOpal.cxx; path = ../../src/LexOpal.cxx; sourceTree = SOURCE_ROOT; }; + 2744E5180FC1684700E85C33 /* LexOthers.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexOthers.cxx; path = ../../src/LexOthers.cxx; sourceTree = SOURCE_ROOT; }; + 2744E5190FC1684700E85C33 /* LexPascal.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexPascal.cxx; path = ../../src/LexPascal.cxx; sourceTree = SOURCE_ROOT; }; + 2744E51A0FC1684700E85C33 /* LexPB.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexPB.cxx; path = ../../src/LexPB.cxx; sourceTree = SOURCE_ROOT; }; + 2744E51B0FC1684700E85C33 /* LexPerl.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexPerl.cxx; path = ../../src/LexPerl.cxx; sourceTree = SOURCE_ROOT; }; + 2744E51C0FC1684700E85C33 /* LexPLM.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexPLM.cxx; path = ../../src/LexPLM.cxx; sourceTree = SOURCE_ROOT; }; + 2744E51D0FC1684700E85C33 /* LexPOV.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexPOV.cxx; path = ../../src/LexPOV.cxx; sourceTree = SOURCE_ROOT; }; + 2744E51E0FC1684700E85C33 /* LexPowerPro.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexPowerPro.cxx; path = ../../src/LexPowerPro.cxx; sourceTree = SOURCE_ROOT; }; + 2744E51F0FC1684700E85C33 /* LexPowerShell.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexPowerShell.cxx; path = ../../src/LexPowerShell.cxx; sourceTree = SOURCE_ROOT; }; + 2744E5200FC1684700E85C33 /* LexProgress.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexProgress.cxx; path = ../../src/LexProgress.cxx; sourceTree = SOURCE_ROOT; }; + 2744E5210FC1684700E85C33 /* LexPS.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexPS.cxx; path = ../../src/LexPS.cxx; sourceTree = SOURCE_ROOT; }; + 2744E5220FC1684700E85C33 /* LexPython.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexPython.cxx; path = ../../src/LexPython.cxx; sourceTree = SOURCE_ROOT; }; + 2744E5230FC1684700E85C33 /* LexR.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexR.cxx; path = ../../src/LexR.cxx; sourceTree = SOURCE_ROOT; }; + 2744E5240FC1684700E85C33 /* LexRebol.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexRebol.cxx; path = ../../src/LexRebol.cxx; sourceTree = SOURCE_ROOT; }; + 2744E5250FC1684700E85C33 /* LexRuby.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexRuby.cxx; path = ../../src/LexRuby.cxx; sourceTree = SOURCE_ROOT; }; + 2744E5260FC1684700E85C33 /* LexScriptol.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexScriptol.cxx; path = ../../src/LexScriptol.cxx; sourceTree = SOURCE_ROOT; }; + 2744E5270FC1684700E85C33 /* LexSmalltalk.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexSmalltalk.cxx; path = ../../src/LexSmalltalk.cxx; sourceTree = SOURCE_ROOT; }; + 2744E5280FC1684700E85C33 /* LexSML.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexSML.cxx; path = ../../src/LexSML.cxx; sourceTree = SOURCE_ROOT; }; + 2744E5290FC1684700E85C33 /* LexSorcus.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexSorcus.cxx; path = ../../src/LexSorcus.cxx; sourceTree = SOURCE_ROOT; }; + 2744E52A0FC1684700E85C33 /* LexSpecman.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexSpecman.cxx; path = ../../src/LexSpecman.cxx; sourceTree = SOURCE_ROOT; }; + 2744E52B0FC1684700E85C33 /* LexSpice.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexSpice.cxx; path = ../../src/LexSpice.cxx; sourceTree = SOURCE_ROOT; }; + 2744E52C0FC1684700E85C33 /* LexSQL.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexSQL.cxx; path = ../../src/LexSQL.cxx; sourceTree = SOURCE_ROOT; }; + 2744E52D0FC1684700E85C33 /* LexTACL.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexTACL.cxx; path = ../../src/LexTACL.cxx; sourceTree = SOURCE_ROOT; }; + 2744E52E0FC1684700E85C33 /* LexTADS3.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexTADS3.cxx; path = ../../src/LexTADS3.cxx; sourceTree = SOURCE_ROOT; }; + 2744E52F0FC1684700E85C33 /* LexTAL.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexTAL.cxx; path = ../../src/LexTAL.cxx; sourceTree = SOURCE_ROOT; }; + 2744E5300FC1684700E85C33 /* LexTCL.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexTCL.cxx; path = ../../src/LexTCL.cxx; sourceTree = SOURCE_ROOT; }; + 2744E5310FC1684700E85C33 /* LexTeX.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexTeX.cxx; path = ../../src/LexTeX.cxx; sourceTree = SOURCE_ROOT; }; + 2744E5320FC1684700E85C33 /* LexVB.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexVB.cxx; path = ../../src/LexVB.cxx; sourceTree = SOURCE_ROOT; }; + 2744E5330FC1684700E85C33 /* LexVerilog.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexVerilog.cxx; path = ../../src/LexVerilog.cxx; sourceTree = SOURCE_ROOT; }; + 2744E5340FC1684700E85C33 /* LexVHDL.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexVHDL.cxx; path = ../../src/LexVHDL.cxx; sourceTree = SOURCE_ROOT; }; + 2744E5350FC1684700E85C33 /* LexYAML.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexYAML.cxx; path = ../../src/LexYAML.cxx; sourceTree = SOURCE_ROOT; }; + 2744E5830FC1685C00E85C33 /* LineMarker.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LineMarker.cxx; path = ../../src/LineMarker.cxx; sourceTree = SOURCE_ROOT; }; + 2744E5840FC1685C00E85C33 /* PerLine.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PerLine.cxx; path = ../../src/PerLine.cxx; sourceTree = SOURCE_ROOT; }; + 2744E5850FC1685C00E85C33 /* PositionCache.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PositionCache.cxx; path = ../../src/PositionCache.cxx; sourceTree = SOURCE_ROOT; }; + 2744E5860FC1685C00E85C33 /* PropSet.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PropSet.cxx; path = ../../src/PropSet.cxx; sourceTree = SOURCE_ROOT; }; + 2744E5870FC1685C00E85C33 /* RESearch.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RESearch.cxx; path = ../../src/RESearch.cxx; sourceTree = SOURCE_ROOT; }; + 2744E5880FC1685C00E85C33 /* RunStyles.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RunStyles.cxx; path = ../../src/RunStyles.cxx; sourceTree = SOURCE_ROOT; }; + 2744E5890FC1685C00E85C33 /* ScintillaBase.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ScintillaBase.cxx; path = ../../src/ScintillaBase.cxx; sourceTree = SOURCE_ROOT; }; + 2744E58A0FC1685C00E85C33 /* Style.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Style.cxx; path = ../../src/Style.cxx; sourceTree = SOURCE_ROOT; }; + 2744E58B0FC1685C00E85C33 /* StyleContext.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = StyleContext.cxx; path = ../../src/StyleContext.cxx; sourceTree = SOURCE_ROOT; }; + 2744E58C0FC1685C00E85C33 /* UniConversion.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = UniConversion.cxx; path = ../../src/UniConversion.cxx; sourceTree = SOURCE_ROOT; }; + 2744E58D0FC1685C00E85C33 /* ViewStyle.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ViewStyle.cxx; path = ../../src/ViewStyle.cxx; sourceTree = SOURCE_ROOT; }; + 2744E58E0FC1685C00E85C33 /* WindowAccessor.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = WindowAccessor.cxx; path = ../../src/WindowAccessor.cxx; sourceTree = SOURCE_ROOT; }; + 2744E58F0FC1685C00E85C33 /* XPM.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = XPM.cxx; path = ../../src/XPM.cxx; sourceTree = SOURCE_ROOT; }; + 2744E59D0FC168A100E85C33 /* InfoBar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = InfoBar.h; path = ../InfoBar.h; sourceTree = SOURCE_ROOT; }; + 2744E59E0FC168A100E85C33 /* PlatCocoa.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PlatCocoa.h; path = ../PlatCocoa.h; sourceTree = SOURCE_ROOT; }; + 2744E59F0FC168A100E85C33 /* QuartzTextLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = QuartzTextLayout.h; path = ../QuartzTextLayout.h; sourceTree = SOURCE_ROOT; }; + 2744E5A00FC168A100E85C33 /* QuartzTextStyleAttribute.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = QuartzTextStyleAttribute.h; path = ../QuartzTextStyleAttribute.h; sourceTree = SOURCE_ROOT; }; + 2744E5A20FC168A100E85C33 /* ScintillaCocoa.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ScintillaCocoa.h; path = ../ScintillaCocoa.h; sourceTree = ""; }; + 2744E5A30FC168A100E85C33 /* ScintillaView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ScintillaView.h; path = ../ScintillaView.h; sourceTree = ""; }; + 2744E5AB0FC168B200E85C33 /* InfoBarCommunicator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = InfoBarCommunicator.h; path = ../InfoBarCommunicator.h; sourceTree = SOURCE_ROOT; }; + 2744E5AD0FC168C500E85C33 /* InfoBar.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = InfoBar.mm; path = ../InfoBar.mm; sourceTree = SOURCE_ROOT; }; + 2744E5AE0FC168C500E85C33 /* PlatCocoa.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = PlatCocoa.mm; path = ../PlatCocoa.mm; sourceTree = SOURCE_ROOT; }; + 2744E5B00FC168C500E85C33 /* ScintillaCocoa.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = ScintillaCocoa.mm; path = ../ScintillaCocoa.mm; sourceTree = ""; }; + 2744E5B10FC168C500E85C33 /* ScintillaView.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = ScintillaView.mm; path = ../ScintillaView.mm; sourceTree = ""; }; + 277B5BD9104EE6B900F40CE4 /* Selection.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Selection.cxx; path = ../../src/Selection.cxx; sourceTree = SOURCE_ROOT; }; + 277B5BDB104EE6CF00F40CE4 /* PropSetSimple.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PropSetSimple.h; path = ../../src/PropSetSimple.h; sourceTree = SOURCE_ROOT; }; + 277B5BDC104EE6CF00F40CE4 /* Selection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Selection.h; path = ../../src/Selection.h; sourceTree = SOURCE_ROOT; }; + 27FEF4510FC1B413005E115A /* info_bar_bg.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = info_bar_bg.png; sourceTree = ""; }; + 27FEF4520FC1B413005E115A /* mac_cursor_busy.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = mac_cursor_busy.png; sourceTree = ""; }; + 27FEF4530FC1B413005E115A /* mac_cursor_flipped.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = mac_cursor_flipped.png; sourceTree = ""; }; + 32DBCF5E0370ADEE00C91783 /* Scintilla_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Scintilla_Prefix.pch; sourceTree = ""; }; + 8DC2EF5A0486A6940098B216 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 8DC2EF5B0486A6940098B216 /* Scintilla.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Scintilla.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + D2F7E79907B2D74100F64583 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = /System/Library/Frameworks/CoreData.framework; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 8DC2EF560486A6940098B216 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 8DC2EF570486A6940098B216 /* Cocoa.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 034768DFFF38A50411DB9C8B /* Products */ = { + isa = PBXGroup; + children = ( + 8DC2EF5B0486A6940098B216 /* Scintilla.framework */, + ); + name = Products; + sourceTree = ""; + }; + 0867D691FE84028FC02AAC07 /* Scintilla */ = { + isa = PBXGroup; + children = ( + 2744E47D0FC1674E00E85C33 /* Lexers */, + 2744E47C0FC1674100E85C33 /* Backend */, + 08FB77AEFE84172EC02AAC07 /* Classes */, + 32C88DFF0371C24200C91783 /* Other Sources */, + 089C1665FE841158C02AAC07 /* Resources */, + 0867D69AFE84028FC02AAC07 /* External Frameworks and Libraries */, + 034768DFFF38A50411DB9C8B /* Products */, + ); + name = Scintilla; + sourceTree = ""; + }; + 0867D69AFE84028FC02AAC07 /* External Frameworks and Libraries */ = { + isa = PBXGroup; + children = ( + 1058C7B0FEA5585E11CA2CBB /* Linked Frameworks */, + 1058C7B2FEA5585E11CA2CBB /* Other Frameworks */, + ); + name = "External Frameworks and Libraries"; + sourceTree = ""; + }; + 089C1665FE841158C02AAC07 /* Resources */ = { + isa = PBXGroup; + children = ( + 27FEF4500FC1B413005E115A /* res */, + 8DC2EF5A0486A6940098B216 /* Info.plist */, + 089C1666FE841158C02AAC07 /* InfoPlist.strings */, + ); + name = Resources; + sourceTree = ""; + }; + 08FB77AEFE84172EC02AAC07 /* Classes */ = { + isa = PBXGroup; + children = ( + 2744E4980FC167ED00E85C33 /* Source Files */, + 2744E4970FC167E400E85C33 /* Header Files */, + ); + name = Classes; + sourceTree = ""; + }; + 1058C7B0FEA5585E11CA2CBB /* Linked Frameworks */ = { + isa = PBXGroup; + children = ( + 1058C7B1FEA5585E11CA2CBB /* Cocoa.framework */, + ); + name = "Linked Frameworks"; + sourceTree = ""; + }; + 1058C7B2FEA5585E11CA2CBB /* Other Frameworks */ = { + isa = PBXGroup; + children = ( + 0867D6A5FE840307C02AAC07 /* AppKit.framework */, + D2F7E79907B2D74100F64583 /* CoreData.framework */, + 0867D69BFE84028FC02AAC07 /* Foundation.framework */, + ); + name = "Other Frameworks"; + sourceTree = ""; + }; + 2744E47C0FC1674100E85C33 /* Backend */ = { + isa = PBXGroup; + children = ( + 2744E47F0FC1676400E85C33 /* Source Files */, + 2744E47E0FC1675800E85C33 /* Header Files */, + ); + name = Backend; + sourceTree = ""; + }; + 2744E47D0FC1674E00E85C33 /* Lexers */ = { + isa = PBXGroup; + children = ( + 11374AA910514AA900651FE9 /* LexMarkdown.cxx */, + 2744E4E90FC1684700E85C33 /* LexAbaqus.cxx */, + 2744E4EA0FC1684700E85C33 /* LexAda.cxx */, + 2744E4EB0FC1684700E85C33 /* LexAPDL.cxx */, + 2744E4EC0FC1684700E85C33 /* LexAsm.cxx */, + 2744E4ED0FC1684700E85C33 /* LexAsn1.cxx */, + 2744E4EE0FC1684700E85C33 /* LexASY.cxx */, + 2744E4EF0FC1684700E85C33 /* LexAU3.cxx */, + 2744E4F00FC1684700E85C33 /* LexAVE.cxx */, + 2744E4F10FC1684700E85C33 /* LexBaan.cxx */, + 2744E4F20FC1684700E85C33 /* LexBash.cxx */, + 2744E4F30FC1684700E85C33 /* LexBasic.cxx */, + 2744E4F40FC1684700E85C33 /* LexBullant.cxx */, + 2744E4F50FC1684700E85C33 /* LexCaml.cxx */, + 2744E4F60FC1684700E85C33 /* LexCLW.cxx */, + 2744E4F70FC1684700E85C33 /* LexCmake.cxx */, + 2744E4F80FC1684700E85C33 /* LexCOBOL.cxx */, + 2744E4F90FC1684700E85C33 /* LexConf.cxx */, + 2744E4FA0FC1684700E85C33 /* LexCPP.cxx */, + 2744E4FB0FC1684700E85C33 /* LexCrontab.cxx */, + 2744E4FC0FC1684700E85C33 /* LexCsound.cxx */, + 2744E4FD0FC1684700E85C33 /* LexCSS.cxx */, + 2744E4FE0FC1684700E85C33 /* LexD.cxx */, + 2744E4FF0FC1684700E85C33 /* LexEiffel.cxx */, + 2744E5000FC1684700E85C33 /* LexErlang.cxx */, + 2744E5010FC1684700E85C33 /* LexEScript.cxx */, + 2744E5020FC1684700E85C33 /* LexFlagship.cxx */, + 2744E5030FC1684700E85C33 /* LexForth.cxx */, + 2744E5040FC1684700E85C33 /* LexFortran.cxx */, + 2744E5050FC1684700E85C33 /* LexGAP.cxx */, + 2744E5060FC1684700E85C33 /* LexGui4Cli.cxx */, + 2744E5070FC1684700E85C33 /* LexHaskell.cxx */, + 2744E5080FC1684700E85C33 /* LexHTML.cxx */, + 2744E5090FC1684700E85C33 /* LexInno.cxx */, + 2744E50A0FC1684700E85C33 /* LexKix.cxx */, + 2744E50B0FC1684700E85C33 /* LexLisp.cxx */, + 2744E50C0FC1684700E85C33 /* LexLout.cxx */, + 2744E50D0FC1684700E85C33 /* LexLua.cxx */, + 2744E50E0FC1684700E85C33 /* LexMagik.cxx */, + 2744E50F0FC1684700E85C33 /* LexMatlab.cxx */, + 2744E5100FC1684700E85C33 /* LexMetapost.cxx */, + 2744E5110FC1684700E85C33 /* LexMMIXAL.cxx */, + 2744E5120FC1684700E85C33 /* LexMPT.cxx */, + 2744E5130FC1684700E85C33 /* LexMSSQL.cxx */, + 2744E5140FC1684700E85C33 /* LexMySQL.cxx */, + 2744E5150FC1684700E85C33 /* LexNimrod.cxx */, + 2744E5160FC1684700E85C33 /* LexNsis.cxx */, + 2744E5170FC1684700E85C33 /* LexOpal.cxx */, + 2744E5180FC1684700E85C33 /* LexOthers.cxx */, + 2744E5190FC1684700E85C33 /* LexPascal.cxx */, + 2744E51A0FC1684700E85C33 /* LexPB.cxx */, + 2744E51B0FC1684700E85C33 /* LexPerl.cxx */, + 2744E51C0FC1684700E85C33 /* LexPLM.cxx */, + 2744E51D0FC1684700E85C33 /* LexPOV.cxx */, + 2744E51E0FC1684700E85C33 /* LexPowerPro.cxx */, + 2744E51F0FC1684700E85C33 /* LexPowerShell.cxx */, + 2744E5200FC1684700E85C33 /* LexProgress.cxx */, + 2744E5210FC1684700E85C33 /* LexPS.cxx */, + 2744E5220FC1684700E85C33 /* LexPython.cxx */, + 2744E5230FC1684700E85C33 /* LexR.cxx */, + 2744E5240FC1684700E85C33 /* LexRebol.cxx */, + 2744E5250FC1684700E85C33 /* LexRuby.cxx */, + 2744E5260FC1684700E85C33 /* LexScriptol.cxx */, + 2744E5270FC1684700E85C33 /* LexSmalltalk.cxx */, + 2744E5280FC1684700E85C33 /* LexSML.cxx */, + 2744E5290FC1684700E85C33 /* LexSorcus.cxx */, + 2744E52A0FC1684700E85C33 /* LexSpecman.cxx */, + 2744E52B0FC1684700E85C33 /* LexSpice.cxx */, + 2744E52C0FC1684700E85C33 /* LexSQL.cxx */, + 2744E52D0FC1684700E85C33 /* LexTACL.cxx */, + 2744E52E0FC1684700E85C33 /* LexTADS3.cxx */, + 2744E52F0FC1684700E85C33 /* LexTAL.cxx */, + 2744E5300FC1684700E85C33 /* LexTCL.cxx */, + 2744E5310FC1684700E85C33 /* LexTeX.cxx */, + 2744E5320FC1684700E85C33 /* LexVB.cxx */, + 2744E5330FC1684700E85C33 /* LexVerilog.cxx */, + 2744E5340FC1684700E85C33 /* LexVHDL.cxx */, + 2744E5350FC1684700E85C33 /* LexYAML.cxx */, + ); + name = Lexers; + sourceTree = ""; + }; + 2744E47E0FC1675800E85C33 /* Header Files */ = { + isa = PBXGroup; + children = ( + 277B5BDB104EE6CF00F40CE4 /* PropSetSimple.h */, + 277B5BDC104EE6CF00F40CE4 /* Selection.h */, + 2744E4990FC1681200E85C33 /* AutoComplete.h */, + 2744E49A0FC1681200E85C33 /* CallTip.h */, + 2744E49B0FC1681200E85C33 /* CellBuffer.h */, + 2744E49C0FC1681200E85C33 /* CharacterSet.h */, + 2744E49D0FC1681200E85C33 /* CharClassify.h */, + 2744E49E0FC1681200E85C33 /* ContractionState.h */, + 2744E49F0FC1681200E85C33 /* Decoration.h */, + 2744E4A00FC1681200E85C33 /* Document.h */, + 2744E4A10FC1681200E85C33 /* DocumentAccessor.h */, + 2744E4A20FC1681200E85C33 /* Editor.h */, + 2744E4A30FC1681200E85C33 /* ExternalLexer.h */, + 2744E4A40FC1681200E85C33 /* Indicator.h */, + 2744E4A50FC1681200E85C33 /* KeyMap.h */, + 2744E4A60FC1681200E85C33 /* LineMarker.h */, + 2744E4A70FC1681200E85C33 /* Partitioning.h */, + 2744E4A80FC1681200E85C33 /* PerLine.h */, + 2744E4A90FC1681200E85C33 /* PositionCache.h */, + 2744E4AA0FC1681200E85C33 /* RESearch.h */, + 2744E4AB0FC1681200E85C33 /* RunStyles.h */, + 2744E4AC0FC1681200E85C33 /* ScintillaBase.h */, + 2744E4AD0FC1681200E85C33 /* SplitVector.h */, + 2744E4AE0FC1681200E85C33 /* Style.h */, + 2744E4AF0FC1681200E85C33 /* StyleContext.h */, + 2744E4B00FC1681200E85C33 /* SVector.h */, + 2744E4B10FC1681200E85C33 /* UniConversion.h */, + 2744E4B20FC1681200E85C33 /* ViewStyle.h */, + 2744E4B30FC1681200E85C33 /* XPM.h */, + ); + name = "Header Files"; + sourceTree = ""; + }; + 2744E47F0FC1676400E85C33 /* Source Files */ = { + isa = PBXGroup; + children = ( + 277B5BD9104EE6B900F40CE4 /* Selection.cxx */, + 2744E4CF0FC1682C00E85C33 /* AutoComplete.cxx */, + 2744E4D00FC1682C00E85C33 /* CallTip.cxx */, + 2744E4D10FC1682C00E85C33 /* CellBuffer.cxx */, + 2744E4D20FC1682C00E85C33 /* CharClassify.cxx */, + 2744E4D30FC1682C00E85C33 /* ContractionState.cxx */, + 2744E4D40FC1682C00E85C33 /* Decoration.cxx */, + 2744E4D50FC1682C00E85C33 /* Document.cxx */, + 2744E4D60FC1682C00E85C33 /* DocumentAccessor.cxx */, + 2744E4D70FC1682C00E85C33 /* Editor.cxx */, + 2744E4D80FC1682C00E85C33 /* ExternalLexer.cxx */, + 2744E4D90FC1682C00E85C33 /* Indicator.cxx */, + 2744E4DA0FC1682C00E85C33 /* KeyMap.cxx */, + 2744E4DB0FC1682C00E85C33 /* KeyWords.cxx */, + 2744E5830FC1685C00E85C33 /* LineMarker.cxx */, + 2744E5840FC1685C00E85C33 /* PerLine.cxx */, + 2744E5850FC1685C00E85C33 /* PositionCache.cxx */, + 2744E5860FC1685C00E85C33 /* PropSet.cxx */, + 2744E5870FC1685C00E85C33 /* RESearch.cxx */, + 2744E5880FC1685C00E85C33 /* RunStyles.cxx */, + 2744E5890FC1685C00E85C33 /* ScintillaBase.cxx */, + 2744E58A0FC1685C00E85C33 /* Style.cxx */, + 2744E58B0FC1685C00E85C33 /* StyleContext.cxx */, + 2744E58C0FC1685C00E85C33 /* UniConversion.cxx */, + 2744E58D0FC1685C00E85C33 /* ViewStyle.cxx */, + 2744E58E0FC1685C00E85C33 /* WindowAccessor.cxx */, + 2744E58F0FC1685C00E85C33 /* XPM.cxx */, + ); + name = "Source Files"; + sourceTree = ""; + }; + 2744E4970FC167E400E85C33 /* Header Files */ = { + isa = PBXGroup; + children = ( + 2744E59D0FC168A100E85C33 /* InfoBar.h */, + 2744E5AB0FC168B200E85C33 /* InfoBarCommunicator.h */, + 2744E59E0FC168A100E85C33 /* PlatCocoa.h */, + 2744E59F0FC168A100E85C33 /* QuartzTextLayout.h */, + 2744E5A00FC168A100E85C33 /* QuartzTextStyleAttribute.h */, + 2744E5A20FC168A100E85C33 /* ScintillaCocoa.h */, + 2744E5A30FC168A100E85C33 /* ScintillaView.h */, + 2744E4830FC1678600E85C33 /* Accessor.h */, + 2744E4840FC1678600E85C33 /* KeyWords.h */, + 2744E4850FC1678600E85C33 /* Platform.h */, + 2744E4860FC1678600E85C33 /* PropSet.h */, + 2744E4870FC1678600E85C33 /* SciLexer.h */, + 2744E4880FC1678600E85C33 /* Scintilla.h */, + 2744E48A0FC1678600E85C33 /* ScintillaWidget.h */, + 2744E48C0FC1678600E85C33 /* WindowAccessor.h */, + ); + name = "Header Files"; + sourceTree = ""; + }; + 2744E4980FC167ED00E85C33 /* Source Files */ = { + isa = PBXGroup; + children = ( + 2744E5AD0FC168C500E85C33 /* InfoBar.mm */, + 2744E5AE0FC168C500E85C33 /* PlatCocoa.mm */, + 2744E5B00FC168C500E85C33 /* ScintillaCocoa.mm */, + 2744E5B10FC168C500E85C33 /* ScintillaView.mm */, + ); + name = "Source Files"; + sourceTree = ""; + }; + 27FEF4500FC1B413005E115A /* res */ = { + isa = PBXGroup; + children = ( + 27FEF4510FC1B413005E115A /* info_bar_bg.png */, + 27FEF4520FC1B413005E115A /* mac_cursor_busy.png */, + 27FEF4530FC1B413005E115A /* mac_cursor_flipped.png */, + ); + name = res; + path = ../res; + sourceTree = SOURCE_ROOT; + }; + 32C88DFF0371C24200C91783 /* Other Sources */ = { + isa = PBXGroup; + children = ( + 32DBCF5E0370ADEE00C91783 /* Scintilla_Prefix.pch */, + ); + name = "Other Sources"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + 8DC2EF500486A6940098B216 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 2791F3EB0FC1A3BD009DBCF9 /* AutoComplete.h in Headers */, + 2791F3EC0FC1A3BD009DBCF9 /* CallTip.h in Headers */, + 2791F3ED0FC1A3BD009DBCF9 /* CellBuffer.h in Headers */, + 2791F3EE0FC1A3BD009DBCF9 /* CharacterSet.h in Headers */, + 2791F3EF0FC1A3BD009DBCF9 /* CharClassify.h in Headers */, + 2791F3F00FC1A3BD009DBCF9 /* ContractionState.h in Headers */, + 2791F3F10FC1A3BD009DBCF9 /* Decoration.h in Headers */, + 2791F3F20FC1A3BD009DBCF9 /* Document.h in Headers */, + 2791F3F30FC1A3BD009DBCF9 /* DocumentAccessor.h in Headers */, + 2791F3F40FC1A3BD009DBCF9 /* Editor.h in Headers */, + 2791F3F50FC1A3BD009DBCF9 /* ExternalLexer.h in Headers */, + 2791F3F60FC1A3BD009DBCF9 /* Indicator.h in Headers */, + 2791F3F70FC1A3BD009DBCF9 /* KeyMap.h in Headers */, + 2791F3F80FC1A3BD009DBCF9 /* LineMarker.h in Headers */, + 2791F3F90FC1A3BD009DBCF9 /* Partitioning.h in Headers */, + 2791F3FA0FC1A3BD009DBCF9 /* PerLine.h in Headers */, + 2791F3FB0FC1A3BD009DBCF9 /* PositionCache.h in Headers */, + 2791F3FC0FC1A3BD009DBCF9 /* RESearch.h in Headers */, + 2791F3FD0FC1A3BD009DBCF9 /* RunStyles.h in Headers */, + 2791F3FE0FC1A3BD009DBCF9 /* ScintillaBase.h in Headers */, + 2791F3FF0FC1A3BD009DBCF9 /* SplitVector.h in Headers */, + 2791F4000FC1A3BD009DBCF9 /* Style.h in Headers */, + 2791F4010FC1A3BD009DBCF9 /* StyleContext.h in Headers */, + 2791F4020FC1A3BD009DBCF9 /* SVector.h in Headers */, + 2791F4030FC1A3BD009DBCF9 /* UniConversion.h in Headers */, + 2791F4040FC1A3BD009DBCF9 /* ViewStyle.h in Headers */, + 2791F4050FC1A3BD009DBCF9 /* XPM.h in Headers */, + 2744E5A40FC168A100E85C33 /* InfoBar.h in Headers */, + 2744E5AC0FC168B200E85C33 /* InfoBarCommunicator.h in Headers */, + 2791F3C60FC19F71009DBCF9 /* PlatCocoa.h in Headers */, + 2791F3E30FC1A3AE009DBCF9 /* QuartzTextLayout.h in Headers */, + 2791F3E40FC1A3AE009DBCF9 /* QuartzTextStyleAttribute.h in Headers */, + 2791F3E00FC1A390009DBCF9 /* ScintillaCocoa.h in Headers */, + 2744E5AA0FC168A100E85C33 /* ScintillaView.h in Headers */, + 2791F3E50FC1A3AE009DBCF9 /* Accessor.h in Headers */, + 2791F3E60FC1A3AE009DBCF9 /* KeyWords.h in Headers */, + 2791F3C70FC19F71009DBCF9 /* Platform.h in Headers */, + 2791F3E70FC1A3AE009DBCF9 /* PropSet.h in Headers */, + 2791F3C80FC19F71009DBCF9 /* SciLexer.h in Headers */, + 2791F3C90FC19F71009DBCF9 /* Scintilla.h in Headers */, + 2791F3E80FC1A3AE009DBCF9 /* ScintillaWidget.h in Headers */, + 2791F3EA0FC1A3AE009DBCF9 /* WindowAccessor.h in Headers */, + 277B5BDD104EE6CF00F40CE4 /* PropSetSimple.h in Headers */, + 277B5BDE104EE6CF00F40CE4 /* Selection.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 8DC2EF4F0486A6940098B216 /* Scintilla */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1DEB91AD08733DA50010E9CD /* Build configuration list for PBXNativeTarget "Scintilla" */; + buildPhases = ( + 8DC2EF500486A6940098B216 /* Headers */, + 8DC2EF520486A6940098B216 /* Resources */, + 8DC2EF540486A6940098B216 /* Sources */, + 8DC2EF560486A6940098B216 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Scintilla; + productInstallPath = "$(HOME)/Library/Frameworks"; + productName = Scintilla; + productReference = 8DC2EF5B0486A6940098B216 /* Scintilla.framework */; + productType = "com.apple.product-type.framework"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 0867D690FE84028FC02AAC07 /* Project object */ = { + isa = PBXProject; + buildConfigurationList = 1DEB91B108733DA50010E9CD /* Build configuration list for PBXProject "ScintillaFramework" */; + compatibilityVersion = "Xcode 3.1"; + hasScannedForEncodings = 1; + mainGroup = 0867D691FE84028FC02AAC07 /* Scintilla */; + productRefGroup = 034768DFFF38A50411DB9C8B /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 8DC2EF4F0486A6940098B216 /* Scintilla */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 8DC2EF520486A6940098B216 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 8DC2EF530486A6940098B216 /* InfoPlist.strings in Resources */, + 27FEF4540FC1B413005E115A /* info_bar_bg.png in Resources */, + 27FEF4550FC1B413005E115A /* mac_cursor_busy.png in Resources */, + 27FEF4560FC1B413005E115A /* mac_cursor_flipped.png in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 8DC2EF540486A6940098B216 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 2744E4DC0FC1682C00E85C33 /* AutoComplete.cxx in Sources */, + 2744E4DD0FC1682C00E85C33 /* CallTip.cxx in Sources */, + 2744E4DE0FC1682C00E85C33 /* CellBuffer.cxx in Sources */, + 2744E4DF0FC1682C00E85C33 /* CharClassify.cxx in Sources */, + 2744E4E00FC1682C00E85C33 /* ContractionState.cxx in Sources */, + 2744E4E10FC1682C00E85C33 /* Decoration.cxx in Sources */, + 2744E4E20FC1682C00E85C33 /* Document.cxx in Sources */, + 2744E4E30FC1682C00E85C33 /* DocumentAccessor.cxx in Sources */, + 2744E4E40FC1682C00E85C33 /* Editor.cxx in Sources */, + 2744E4E50FC1682C00E85C33 /* ExternalLexer.cxx in Sources */, + 2744E4E60FC1682C00E85C33 /* Indicator.cxx in Sources */, + 2744E4E70FC1682C00E85C33 /* KeyMap.cxx in Sources */, + 2744E4E80FC1682C00E85C33 /* KeyWords.cxx in Sources */, + 2744E5360FC1684700E85C33 /* LexAbaqus.cxx in Sources */, + 2744E5370FC1684700E85C33 /* LexAda.cxx in Sources */, + 2744E5380FC1684700E85C33 /* LexAPDL.cxx in Sources */, + 2744E5390FC1684700E85C33 /* LexAsm.cxx in Sources */, + 2744E53A0FC1684700E85C33 /* LexAsn1.cxx in Sources */, + 2744E53B0FC1684700E85C33 /* LexASY.cxx in Sources */, + 2744E53C0FC1684700E85C33 /* LexAU3.cxx in Sources */, + 2744E53D0FC1684700E85C33 /* LexAVE.cxx in Sources */, + 2744E53E0FC1684700E85C33 /* LexBaan.cxx in Sources */, + 2744E53F0FC1684700E85C33 /* LexBash.cxx in Sources */, + 2744E5400FC1684700E85C33 /* LexBasic.cxx in Sources */, + 2744E5410FC1684700E85C33 /* LexBullant.cxx in Sources */, + 2744E5420FC1684700E85C33 /* LexCaml.cxx in Sources */, + 2744E5430FC1684700E85C33 /* LexCLW.cxx in Sources */, + 2744E5440FC1684700E85C33 /* LexCmake.cxx in Sources */, + 2744E5450FC1684700E85C33 /* LexCOBOL.cxx in Sources */, + 2744E5460FC1684700E85C33 /* LexConf.cxx in Sources */, + 2744E5470FC1684700E85C33 /* LexCPP.cxx in Sources */, + 2744E5480FC1684700E85C33 /* LexCrontab.cxx in Sources */, + 2744E5490FC1684700E85C33 /* LexCsound.cxx in Sources */, + 2744E54A0FC1684700E85C33 /* LexCSS.cxx in Sources */, + 2744E54B0FC1684700E85C33 /* LexD.cxx in Sources */, + 2744E54C0FC1684700E85C33 /* LexEiffel.cxx in Sources */, + 2744E54D0FC1684700E85C33 /* LexErlang.cxx in Sources */, + 2744E54E0FC1684700E85C33 /* LexEScript.cxx in Sources */, + 2744E54F0FC1684700E85C33 /* LexFlagship.cxx in Sources */, + 2744E5500FC1684700E85C33 /* LexForth.cxx in Sources */, + 2744E5510FC1684700E85C33 /* LexFortran.cxx in Sources */, + 2744E5520FC1684700E85C33 /* LexGAP.cxx in Sources */, + 2744E5530FC1684700E85C33 /* LexGui4Cli.cxx in Sources */, + 2744E5540FC1684700E85C33 /* LexHaskell.cxx in Sources */, + 2744E5550FC1684700E85C33 /* LexHTML.cxx in Sources */, + 2744E5560FC1684700E85C33 /* LexInno.cxx in Sources */, + 2744E5570FC1684700E85C33 /* LexKix.cxx in Sources */, + 2744E5580FC1684700E85C33 /* LexLisp.cxx in Sources */, + 2744E5590FC1684700E85C33 /* LexLout.cxx in Sources */, + 2744E55A0FC1684700E85C33 /* LexLua.cxx in Sources */, + 2744E55B0FC1684700E85C33 /* LexMagik.cxx in Sources */, + 2744E55C0FC1684700E85C33 /* LexMatlab.cxx in Sources */, + 2744E55D0FC1684700E85C33 /* LexMetapost.cxx in Sources */, + 2744E55E0FC1684700E85C33 /* LexMMIXAL.cxx in Sources */, + 2744E55F0FC1684700E85C33 /* LexMPT.cxx in Sources */, + 2744E5600FC1684700E85C33 /* LexMSSQL.cxx in Sources */, + 2744E5610FC1684700E85C33 /* LexMySQL.cxx in Sources */, + 2744E5620FC1684700E85C33 /* LexNimrod.cxx in Sources */, + 2744E5630FC1684700E85C33 /* LexNsis.cxx in Sources */, + 2744E5640FC1684700E85C33 /* LexOpal.cxx in Sources */, + 2744E5650FC1684700E85C33 /* LexOthers.cxx in Sources */, + 2744E5660FC1684700E85C33 /* LexPascal.cxx in Sources */, + 2744E5670FC1684700E85C33 /* LexPB.cxx in Sources */, + 2744E5680FC1684700E85C33 /* LexPerl.cxx in Sources */, + 2744E5690FC1684700E85C33 /* LexPLM.cxx in Sources */, + 2744E56A0FC1684700E85C33 /* LexPOV.cxx in Sources */, + 2744E56B0FC1684700E85C33 /* LexPowerPro.cxx in Sources */, + 2744E56C0FC1684700E85C33 /* LexPowerShell.cxx in Sources */, + 2744E56D0FC1684700E85C33 /* LexProgress.cxx in Sources */, + 2744E56E0FC1684700E85C33 /* LexPS.cxx in Sources */, + 2744E56F0FC1684700E85C33 /* LexPython.cxx in Sources */, + 2744E5700FC1684700E85C33 /* LexR.cxx in Sources */, + 2744E5710FC1684700E85C33 /* LexRebol.cxx in Sources */, + 2744E5720FC1684700E85C33 /* LexRuby.cxx in Sources */, + 2744E5730FC1684700E85C33 /* LexScriptol.cxx in Sources */, + 2744E5740FC1684700E85C33 /* LexSmalltalk.cxx in Sources */, + 2744E5750FC1684700E85C33 /* LexSML.cxx in Sources */, + 2744E5760FC1684700E85C33 /* LexSorcus.cxx in Sources */, + 2744E5770FC1684700E85C33 /* LexSpecman.cxx in Sources */, + 2744E5780FC1684700E85C33 /* LexSpice.cxx in Sources */, + 2744E5790FC1684700E85C33 /* LexSQL.cxx in Sources */, + 2744E57A0FC1684700E85C33 /* LexTACL.cxx in Sources */, + 2744E57B0FC1684700E85C33 /* LexTADS3.cxx in Sources */, + 2744E57C0FC1684700E85C33 /* LexTAL.cxx in Sources */, + 2744E57D0FC1684700E85C33 /* LexTCL.cxx in Sources */, + 2744E57E0FC1684700E85C33 /* LexTeX.cxx in Sources */, + 2744E57F0FC1684700E85C33 /* LexVB.cxx in Sources */, + 2744E5800FC1684700E85C33 /* LexVerilog.cxx in Sources */, + 2744E5810FC1684700E85C33 /* LexVHDL.cxx in Sources */, + 2744E5820FC1684700E85C33 /* LexYAML.cxx in Sources */, + 2744E5900FC1685C00E85C33 /* LineMarker.cxx in Sources */, + 2744E5910FC1685C00E85C33 /* PerLine.cxx in Sources */, + 2744E5920FC1685C00E85C33 /* PositionCache.cxx in Sources */, + 2744E5930FC1685C00E85C33 /* PropSet.cxx in Sources */, + 2744E5940FC1685C00E85C33 /* RESearch.cxx in Sources */, + 2744E5950FC1685C00E85C33 /* RunStyles.cxx in Sources */, + 2744E5960FC1685C00E85C33 /* ScintillaBase.cxx in Sources */, + 2744E5970FC1685C00E85C33 /* Style.cxx in Sources */, + 2744E5980FC1685C00E85C33 /* StyleContext.cxx in Sources */, + 2744E5990FC1685C00E85C33 /* UniConversion.cxx in Sources */, + 2744E59A0FC1685C00E85C33 /* ViewStyle.cxx in Sources */, + 2744E59B0FC1685C00E85C33 /* WindowAccessor.cxx in Sources */, + 2744E59C0FC1685C00E85C33 /* XPM.cxx in Sources */, + 2744E5B20FC168C500E85C33 /* InfoBar.mm in Sources */, + 2744E5B30FC168C500E85C33 /* PlatCocoa.mm in Sources */, + 2744E5B50FC168C500E85C33 /* ScintillaCocoa.mm in Sources */, + 2744E5B60FC168C500E85C33 /* ScintillaView.mm in Sources */, + 277B5BDA104EE6B900F40CE4 /* Selection.cxx in Sources */, + 11374AAA10514AA900651FE9 /* LexMarkdown.cxx in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 089C1666FE841158C02AAC07 /* InfoPlist.strings */ = { + isa = PBXVariantGroup; + children = ( + 089C1667FE841158C02AAC07 /* English */, + ); + name = InfoPlist.strings; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 1DEB91AE08733DA50010E9CD /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = NO; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + FRAMEWORK_VERSION = A; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_MODEL_TUNING = G5; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = Scintilla_Prefix.pch; + GCC_PREPROCESSOR_DEFINITIONS = ( + SCI_NAMESPACE, + SCI_LEXER, + ); + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "@executable_path/../Frameworks"; + PRODUCT_NAME = Scintilla; + WRAPPER_EXTENSION = framework; + }; + name = Debug; + }; + 1DEB91AF08733DA50010E9CD /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + FRAMEWORK_VERSION = A; + GCC_MODEL_TUNING = G5; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = Scintilla_Prefix.pch; + GCC_PREPROCESSOR_DEFINITIONS = ( + SCI_NAMESPACE, + SCI_LEXER, + ); + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "@executable_path/../Frameworks"; + PRODUCT_NAME = Scintilla; + WRAPPER_EXTENSION = framework; + }; + name = Release; + }; + 1DEB91B208733DA50010E9CD /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + ONLY_ACTIVE_ARCH = YES; + PREBINDING = NO; + SDKROOT = macosx10.5; + }; + name = Debug; + }; + 1DEB91B308733DA50010E9CD /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + PREBINDING = NO; + SDKROOT = macosx10.5; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1DEB91AD08733DA50010E9CD /* Build configuration list for PBXNativeTarget "Scintilla" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1DEB91AE08733DA50010E9CD /* Debug */, + 1DEB91AF08733DA50010E9CD /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 1DEB91B108733DA50010E9CD /* Build configuration list for PBXProject "ScintillaFramework" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1DEB91B208733DA50010E9CD /* Debug */, + 1DEB91B308733DA50010E9CD /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 0867D690FE84028FC02AAC07 /* Project object */; +} diff --git a/scintilla/cocoa/ScintillaFramework/Scintilla_Prefix.pch b/scintilla/cocoa/ScintillaFramework/Scintilla_Prefix.pch new file mode 100644 index 00000000..d14300bd --- /dev/null +++ b/scintilla/cocoa/ScintillaFramework/Scintilla_Prefix.pch @@ -0,0 +1,7 @@ +// +// Prefix header for all source files of the 'Scintilla' target in the 'Scintilla' project. +// + +#ifdef __OBJC__ + #import +#endif diff --git a/scintilla/cocoa/ScintillaListBox.h b/scintilla/cocoa/ScintillaListBox.h new file mode 100644 index 00000000..9f6b722f --- /dev/null +++ b/scintilla/cocoa/ScintillaListBox.h @@ -0,0 +1,64 @@ + +/* + * ScintillaMacOSX.h + * tutorial + * + * Created by Evan Jones on Sun Sep 01 2002. + * + */ + +#ifndef SCINTILLA_LISTBOX_H +#define SCINTILLA_LISTBOX_H + +#include "TView.h" + +#include +#include +#include +#include +#include + +#include "Platform.h" +#include "Scintilla.h" + +static const OSType scintillaListBoxType = 'sclb'; + +namespace Scintilla { + +class ScintillaListBox : public TView +{ +public: + // Private so ScintillaListBox objects can not be copied + ScintillaListBox(const ScintillaListBox &) : TView( NULL ) {} + ScintillaListBox &operator=(const ScintillaListBox &) { return * this; } + ~ScintillaListBox() {}; + +public: + /** This is the class ID that we've assigned to Scintilla. */ + static const CFStringRef kScintillaListBoxClassID; + static const ControlKind kScintillaListBoxKind; + + ScintillaListBox( void* windowid ); + + /** Returns the HIView object kind, needed to subclass TView. */ + virtual ControlKind GetKind() { return kScintillaListBoxKind; } + +private: + + virtual ControlPartCode HitTest( const HIPoint& where ); + virtual void Draw( RgnHandle rgn, CGContextRef gc ); + virtual OSStatus MouseDown( HIPoint& location, UInt32 modifiers, EventMouseButton button, UInt32 clickCount ); + virtual OSStatus MouseUp( HIPoint& location, UInt32 modifiers, EventMouseButton button, UInt32 clickCount ); + +public: + static HIViewRef Create(); +private: + static OSStatus Construct( HIViewRef inControl, TView** outView ); + +}; + + +} + + +#endif diff --git a/scintilla/cocoa/ScintillaListBox.mm b/scintilla/cocoa/ScintillaListBox.mm new file mode 100644 index 00000000..8c517859 --- /dev/null +++ b/scintilla/cocoa/ScintillaListBox.mm @@ -0,0 +1,110 @@ + +#include "ScintillaCocoa.h" +#include "ScintillaListBox.h" + +using namespace Scintilla; + +const CFStringRef ScintillaListBox::kScintillaListBoxClassID = CFSTR( "org.scintilla.listbox" ); +const ControlKind ScintillaListBox::kScintillaListBoxKind = { 'ejon', 'Sclb' }; + +ScintillaListBox::ScintillaListBox( void* windowid ) : + TView( reinterpret_cast( windowid ) ) +{ + ActivateInterface( kMouse ); + // debugPrint = true; +} + +void ScintillaListBox::Draw( + RgnHandle /*inLimitRgn*/, + CGContextRef inContext ) +{ + Rect contentBounds; + GetControlBounds(GetViewRef(), &contentBounds); + + HIRect controlFrame; + HIViewGetFrame( GetViewRef(), &controlFrame ); + + // what is the global pos? + Surface *surfaceWindow = Surface::Allocate(); + if (surfaceWindow) + { + surfaceWindow->Init(inContext, GetViewRef()); + + // TODO: Implement or find workaround + // ctip->PaintCT(surfaceWindow); + surfaceWindow->Release(); + delete surfaceWindow; + } + +} + +ControlPartCode ScintillaListBox::HitTest( const HIPoint& where ) +{ + if ( CGRectContainsPoint( Bounds(), where ) ) + return 1; + else + return kControlNoPart; +} + +OSStatus ScintillaListBox::MouseDown(HIPoint& location, UInt32 /*inKeyModifiers*/, EventMouseButton button, UInt32 /*inClickCount*/ ) +{ + if ( button != kEventMouseButtonPrimary ) return eventNotHandledErr; + ListBox* ctip = NULL; + ScintillaCocoa *sciThis = NULL; + OSStatus err = GetControlProperty( GetViewRef(), scintillaListBoxType, 0, sizeof( ctip ), NULL, &ctip ); + err = GetControlProperty( GetViewRef(), scintillaMacOSType, 0, sizeof( sciThis ), NULL, &sciThis ); + + // TODO: Implement of find work around. + // ctip->MouseClick( Scintilla::Point( static_cast( location.x ), static_cast( location.y ) )); + + // TODO: still needed? + // sciThis->ListBoxClick(); + return noErr; +} + +OSStatus ScintillaListBox::MouseUp(HIPoint& /*inMouseLocation*/, UInt32 /*inKeyModifiers*/, EventMouseButton button, UInt32 /*inClickCount*/ ) +{ + if ( button != kEventMouseButtonPrimary ) return eventNotHandledErr; + return noErr; +} + +HIViewRef ScintillaListBox::Create() +{ + // Register the HIView, if needed + static bool registered = false; + + if ( not registered ) + { + TView::RegisterSubclass( kScintillaListBoxClassID, Construct ); + registered = true; + } + + OSStatus err = noErr; + EventRef event = CreateInitializationEvent(); + assert( event != NULL ); + + HIViewRef control = NULL; + err = HIObjectCreate( kScintillaListBoxClassID, event, reinterpret_cast( &control ) ); + ReleaseEvent( event ); + if ( err == noErr ) { + Platform::DebugPrintf("ScintillaListBox::Create control %08X\n",control); + return control; + } + return NULL; +} + +OSStatus ScintillaListBox::Construct( HIViewRef inControl, TView** outView ) +{ + *outView = new ScintillaListBox( inControl ); + Platform::DebugPrintf("ScintillaListBox::Construct scintilla %08X\n",*outView); + if ( *outView != NULL ) + return noErr; + else + return memFullErr; +} + +extern "C" { +HIViewRef scintilla_listbox_new() { + return ScintillaListBox::Create(); +} +} diff --git a/scintilla/cocoa/ScintillaTest/AppController.h b/scintilla/cocoa/ScintillaTest/AppController.h new file mode 100644 index 00000000..fe84e0a6 --- /dev/null +++ b/scintilla/cocoa/ScintillaTest/AppController.h @@ -0,0 +1,23 @@ +/** + * AppController.h + * SciTest + * + * Created by Mike Lischke on 01.04.09. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * This file is dual licensed under LGPL v2.1 and the Scintilla license (http://www.scintilla.org/License.txt). + */ + +#import + +#import "ScintillaView.h" +#import "InfoBar.h" + +@interface AppController : NSObject { + IBOutlet NSBox *mEditHost; + ScintillaView* mEditor; +} + +- (void) awakeFromNib; +- (void) setupEditor; + +@end diff --git a/scintilla/cocoa/ScintillaTest/AppController.mm b/scintilla/cocoa/ScintillaTest/AppController.mm new file mode 100644 index 00000000..217bc9cf --- /dev/null +++ b/scintilla/cocoa/ScintillaTest/AppController.mm @@ -0,0 +1,215 @@ +/** + * AppController.m + * ScintillaTest + * + * Created by Mike Lischke on 01.04.09. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * This file is dual licensed under LGPL v2.1 and the Scintilla license (http://www.scintilla.org/License.txt). + */ + +#import "AppController.h" + +const char major_keywords[] = + "accessible add all alter analyze and as asc asensitive " + "before between bigint binary blob both by " + "call cascade case change char character check collate column condition connection constraint " + "continue convert create cross current_date current_time current_timestamp current_user cursor " + "database databases day_hour day_microsecond day_minute day_second dec decimal declare default " + "delayed delete desc describe deterministic distinct distinctrow div double drop dual " + "each else elseif enclosed escaped exists exit explain " + "false fetch float float4 float8 for force foreign from fulltext " + "goto grant group " + "having high_priority hour_microsecond hour_minute hour_second " + "if ignore in index infile inner inout insensitive insert int int1 int2 int3 int4 int8 integer " + "interval into is iterate " + "join " + "key keys kill " + "label leading leave left like limit linear lines load localtime localtimestamp lock long " + "longblob longtext loop low_priority " + "master_ssl_verify_server_cert match mediumblob mediumint mediumtext middleint minute_microsecond " + "minute_second mod modifies " + "natural not no_write_to_binlog null numeric " + "on optimize option optionally or order out outer outfile " + "precision primary procedure purge " + "range read reads read_only read_write real references regexp release rename repeat replace " + "require restrict return revoke right rlike " + "schema schemas second_microsecond select sensitive separator set show smallint spatial specific " + "sql sqlexception sqlstate sqlwarning sql_big_result sql_calc_found_rows sql_small_result ssl " + "starting straight_join " + "table terminated then tinyblob tinyint tinytext to trailing trigger true " + "undo union unique unlock unsigned update upgrade usage use using utc_date utc_time utc_timestamp " + "values varbinary varchar varcharacter varying " + "when where while with write " + "xor " + "year_month " + "zerofill"; + +const char procedure_keywords[] = // Not reserved words but intrinsic part of procedure definitions. + "begin comment end"; + +const char client_keywords[] = // Definition of keywords only used by clients, not the server itself. + "delimiter"; + +const char user_keywords[] = // Definition of own keywords, not used by MySQL. + "edit"; + +//-------------------------------------------------------------------------------------------------- + +@implementation AppController + +- (void) awakeFromNib +{ + // Manually set up the scintilla editor. Create an instance and dock it to our edit host. + // Leave some free space around the new view to avoid overlapping with the box borders. + NSRect newFrame = mEditHost.frame; + newFrame.size.width -= 2 * newFrame.origin.x; + newFrame.size.height -= 3 * newFrame.origin.y; + + mEditor = [[[ScintillaView alloc] initWithFrame: newFrame] autorelease]; + + [mEditHost.contentView addSubview: mEditor]; + [mEditor setAutoresizesSubviews: YES]; + [mEditor setAutoresizingMask: NSViewWidthSizable | NSViewHeightSizable]; + + // Let's load some text for the editor, as initial content. + NSError* error = nil; + + NSString* path = [[NSBundle mainBundle] pathForResource: @"TestData" + ofType: @"sql" inDirectory: nil]; + + NSString* sql = [NSString stringWithContentsOfFile: path + encoding: NSUTF8StringEncoding + error: &error]; + if (error && [[error domain] isEqual: NSCocoaErrorDomain]) + NSLog(@"%@", error); + + [mEditor setString: sql]; + + [self setupEditor]; +} + +//-------------------------------------------------------------------------------------------------- + +/** + * Initialize scintilla editor (styles, colors, markers, folding etc.]. + */ +- (void) setupEditor +{ + // Lexer type is MySQL. + [mEditor setGeneralProperty: SCI_SETLEXER parameter: SCLEX_MYSQL value: 0]; + // alternatively: [mEditor setEditorProperty: SCI_SETLEXERLANGUAGE parameter: nil value: (sptr_t) "mysql"]; + + // Number of styles we use with this lexer. + [mEditor setGeneralProperty: SCI_SETSTYLEBITS parameter: 5 value: 0]; + + // Keywords to highlight. Indices are: + // 0 - Major keywords (reserved keywords) + // 1 - Normal keywords (everything not reserved but integral part of the language) + // 2 - Database objects + // 3 - Function keywords + // 4 - System variable keywords + // 5 - Procedure keywords (keywords used in procedures like "begin" and "end") + // 6..8 - User keywords 1..3 + [mEditor setReferenceProperty: SCI_SETKEYWORDS parameter: 0 value: major_keywords]; + [mEditor setReferenceProperty: SCI_SETKEYWORDS parameter: 5 value: procedure_keywords]; + [mEditor setReferenceProperty: SCI_SETKEYWORDS parameter: 6 value: client_keywords]; + [mEditor setReferenceProperty: SCI_SETKEYWORDS parameter: 7 value: user_keywords]; + + // Colors and styles for various syntactic elements. First the default style. + [mEditor setStringProperty: SCI_STYLESETFONT parameter: STYLE_DEFAULT value: @"Andale Mono"]; + // [mEditor setStringProperty: SCI_STYLESETFONT parameter: STYLE_DEFAULT value: @"Monospac821 BT"]; // Very pleasing programmer's font. + [mEditor setGeneralProperty: SCI_STYLESETSIZE parameter: STYLE_DEFAULT value: 14]; + [mEditor setColorProperty: SCI_STYLESETFORE parameter: STYLE_DEFAULT value: [NSColor blackColor]]; + + [mEditor setColorProperty: SCI_STYLESETFORE parameter: SCE_MYSQL_DEFAULT value: [NSColor blackColor]]; + [mEditor setColorProperty: SCI_STYLESETFORE parameter: SCE_MYSQL_COMMENT fromHTML: @"#097BF7"]; + [mEditor setColorProperty: SCI_STYLESETFORE parameter: SCE_MYSQL_COMMENTLINE fromHTML: @"#097BF7"]; + [mEditor setColorProperty: SCI_STYLESETFORE parameter: SCE_MYSQL_HIDDENCOMMAND fromHTML: @"#097BF7"]; + [mEditor setColorProperty: SCI_STYLESETBACK parameter: SCE_MYSQL_HIDDENCOMMAND fromHTML: @"#F0F0F0"]; + + [mEditor setColorProperty: SCI_STYLESETFORE parameter: SCE_MYSQL_VARIABLE fromHTML: @"378EA5"]; + [mEditor setColorProperty: SCI_STYLESETFORE parameter: SCE_MYSQL_SYSTEMVARIABLE fromHTML: @"378EA5"]; + [mEditor setColorProperty: SCI_STYLESETFORE parameter: SCE_MYSQL_KNOWNSYSTEMVARIABLE fromHTML: @"#3A37A5"]; + + [mEditor setColorProperty: SCI_STYLESETFORE parameter: SCE_MYSQL_NUMBER fromHTML: @"#7F7F00"]; + [mEditor setColorProperty: SCI_STYLESETFORE parameter: SCE_MYSQL_SQSTRING fromHTML: @"#FFAA3E"]; + + // Note: if we were using ANSI quotes we would set the DQSTRING to the same color as the + // the back tick string. + [mEditor setColorProperty: SCI_STYLESETFORE parameter: SCE_MYSQL_DQSTRING fromHTML: @"#274A6D"]; + + // Keyword highlighting. + [mEditor setColorProperty: SCI_STYLESETFORE parameter: SCE_MYSQL_MAJORKEYWORD fromHTML: @"#007F00"]; + [mEditor setGeneralProperty: SCI_STYLESETBOLD parameter: SCE_MYSQL_MAJORKEYWORD value: 1]; + [mEditor setColorProperty: SCI_STYLESETFORE parameter: SCE_MYSQL_KEYWORD fromHTML: @"#007F00"]; + [mEditor setGeneralProperty: SCI_STYLESETBOLD parameter: SCE_MYSQL_KEYWORD value: 1]; + [mEditor setColorProperty: SCI_STYLESETFORE parameter: SCE_MYSQL_PROCEDUREKEYWORD fromHTML: @"#56007F"]; + [mEditor setGeneralProperty: SCI_STYLESETBOLD parameter: SCE_MYSQL_PROCEDUREKEYWORD value: 1]; + [mEditor setColorProperty: SCI_STYLESETFORE parameter: SCE_MYSQL_USER1 fromHTML: @"#808080"]; + [mEditor setColorProperty: SCI_STYLESETFORE parameter: SCE_MYSQL_USER2 fromHTML: @"#808080"]; + [mEditor setColorProperty: SCI_STYLESETBACK parameter: SCE_MYSQL_USER2 fromHTML: @"#F0E0E0"]; + + // The following 3 styles have no impact as we did not set a keyword list for any of them. + [mEditor setColorProperty: SCI_STYLESETFORE parameter: SCE_MYSQL_DATABASEOBJECT value: [NSColor redColor]]; + [mEditor setColorProperty: SCI_STYLESETFORE parameter: SCE_MYSQL_FUNCTION value: [NSColor redColor]]; + + [mEditor setColorProperty: SCI_STYLESETFORE parameter: SCE_MYSQL_IDENTIFIER value: [NSColor blackColor]]; + [mEditor setColorProperty: SCI_STYLESETFORE parameter: SCE_MYSQL_QUOTEDIDENTIFIER fromHTML: @"#274A6D"]; + [mEditor setGeneralProperty: SCI_STYLESETBOLD parameter: SCE_SQL_OPERATOR value: 1]; + + // Line number style. + [mEditor setColorProperty: SCI_STYLESETFORE parameter: STYLE_LINENUMBER fromHTML: @"#F0F0F0"]; + [mEditor setColorProperty: SCI_STYLESETBACK parameter: STYLE_LINENUMBER fromHTML: @"#808080"]; + + [mEditor setGeneralProperty: SCI_SETMARGINTYPEN parameter: 0 value: SC_MARGIN_NUMBER]; + [mEditor setGeneralProperty: SCI_SETMARGINWIDTHN parameter: 0 value: 35]; + + // Markers. + [mEditor setGeneralProperty: SCI_SETMARGINWIDTHN parameter: 1 value: 16]; + + // Some special lexer properties. + [mEditor setLexerProperty: @"fold" value: @"1"]; + [mEditor setLexerProperty: @"fold.compact" value: @"0"]; + [mEditor setLexerProperty: @"fold.comment" value: @"1"]; + [mEditor setLexerProperty: @"fold.preprocessor" value: @"1"]; + + // Folder setup. + [mEditor setGeneralProperty: SCI_SETMARGINWIDTHN parameter: 2 value: 16]; + [mEditor setGeneralProperty: SCI_SETMARGINMASKN parameter: 2 value: SC_MASK_FOLDERS]; + [mEditor setGeneralProperty: SCI_SETMARGINSENSITIVEN parameter: 2 value: 1]; + [mEditor setGeneralProperty: SCI_MARKERDEFINE parameter: SC_MARKNUM_FOLDEROPEN value: SC_MARK_BOXMINUS]; + [mEditor setGeneralProperty: SCI_MARKERDEFINE parameter: SC_MARKNUM_FOLDER value: SC_MARK_BOXPLUS]; + [mEditor setGeneralProperty: SCI_MARKERDEFINE parameter: SC_MARKNUM_FOLDERSUB value: SC_MARK_VLINE]; + [mEditor setGeneralProperty: SCI_MARKERDEFINE parameter: SC_MARKNUM_FOLDERTAIL value: SC_MARK_LCORNER]; + [mEditor setGeneralProperty: SCI_MARKERDEFINE parameter: SC_MARKNUM_FOLDEREND value: SC_MARK_BOXPLUSCONNECTED]; + [mEditor setGeneralProperty: SCI_MARKERDEFINE parameter: SC_MARKNUM_FOLDEROPENMID value: SC_MARK_BOXMINUSCONNECTED]; + [mEditor setGeneralProperty + : SCI_MARKERDEFINE parameter: SC_MARKNUM_FOLDERMIDTAIL value: SC_MARK_TCORNER]; + for (int n= 25; n < 32; ++n) // Markers 25..31 are reserved for folding. + { + [mEditor setColorProperty: SCI_MARKERSETFORE parameter: n value: [NSColor whiteColor]]; + [mEditor setColorProperty: SCI_MARKERSETBACK parameter: n value: [NSColor blackColor]]; + } + + // Init markers & indicators for highlighting of syntax errors. + [mEditor setColorProperty: SCI_INDICSETFORE parameter: 0 value: [NSColor redColor]]; + [mEditor setGeneralProperty: SCI_INDICSETUNDER parameter: 0 value: 1]; + [mEditor setGeneralProperty: SCI_INDICSETSTYLE parameter: 0 value: INDIC_SQUIGGLE]; + + [mEditor setColorProperty: SCI_MARKERSETBACK parameter: 0 fromHTML: @"#B1151C"]; + + [mEditor setColorProperty: SCI_SETSELBACK parameter: 1 value: [NSColor selectedTextBackgroundColor]]; + + // Uncomment if you wanna see auto wrapping in action. + //[mEditor setGeneralProperty: SCI_SETWRAPMODE parameter: SC_WRAP_WORD value: 0]; + + InfoBar* infoBar = [[[InfoBar alloc] initWithFrame: NSMakeRect(0, 0, 400, 0)] autorelease]; + [infoBar setDisplay: IBShowAll]; + [mEditor setInfoBar: infoBar top: NO]; + [mEditor setStatusText: @"Operation complete"]; +} + +@end + +//-------------------------------------------------------------------------------------------------- + diff --git a/scintilla/cocoa/ScintillaTest/English.lproj/InfoPlist.strings b/scintilla/cocoa/ScintillaTest/English.lproj/InfoPlist.strings new file mode 100644 index 00000000..85e4bb6f Binary files /dev/null and b/scintilla/cocoa/ScintillaTest/English.lproj/InfoPlist.strings differ diff --git a/scintilla/cocoa/ScintillaTest/English.lproj/MainMenu.xib b/scintilla/cocoa/ScintillaTest/English.lproj/MainMenu.xib new file mode 100644 index 00000000..253d29d9 --- /dev/null +++ b/scintilla/cocoa/ScintillaTest/English.lproj/MainMenu.xib @@ -0,0 +1,3185 @@ + + + + 1050 + 9G55 + 677 + 949.43 + 353.00 + + YES + + + + YES + com.apple.InterfaceBuilderKit + com.apple.InterfaceBuilder.CocoaPlugin + + + YES + + YES + + + YES + + + + YES + + NSApplication + + + FirstResponder + + + NSApplication + + + AMainMenu + + YES + + + NewApplication + + 1048576 + 2147483647 + + NSImage + NSMenuCheckmark + + + NSImage + NSMenuMixedState + + submenuAction: + + NewApplication + + YES + + + About NewApplication + + 2147483647 + + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + UHJlZmVyZW5jZXPigKY + , + 1048576 + 2147483647 + + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Services + + 1048576 + 2147483647 + + + submenuAction: + + Services + + YES + + _NSServicesMenu + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Hide NewApplication + h + 1048576 + 2147483647 + + + + + + Hide Others + h + 1572864 + 2147483647 + + + + + + Show All + + 1048576 + 2147483647 + + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Quit NewApplication + q + 1048576 + 2147483647 + + + + + _NSAppleMenu + + + + + File + + 1048576 + 2147483647 + + + submenuAction: + + File + + YES + + + New + n + 1048576 + 2147483647 + + + + + + T3BlbuKApg + o + 1048576 + 2147483647 + + + + + + Open Recent + + 1048576 + 2147483647 + + + submenuAction: + + Open Recent + + YES + + + Clear Menu + + 1048576 + 2147483647 + + + + + _NSRecentDocumentsMenu + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Close + w + 1048576 + 2147483647 + + + + + + Save + s + 1048576 + 2147483647 + + + + + + U2F2ZSBBc+KApg + S + 1179648 + 2147483647 + + + + + + Revert to Saved + + 2147483647 + + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Page Setup... + P + 1179648 + 2147483647 + + + + + + + UHJpbnTigKY + p + 1048576 + 2147483647 + + + + + + + + + Edit + + 1048576 + 2147483647 + + + submenuAction: + + Edit + + YES + + + Undo + z + 1048576 + 2147483647 + + + + + + Redo + Z + 1179648 + 2147483647 + + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Cut + x + 1048576 + 2147483647 + + + + + + Copy + c + 1048576 + 2147483647 + + + + + + Paste + v + 1048576 + 2147483647 + + + + + + Delete + + 1048576 + 2147483647 + + + + + + Select All + a + 1048576 + 2147483647 + + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Find + + 1048576 + 2147483647 + + + submenuAction: + + Find + + YES + + + RmluZOKApg + f + 1048576 + 2147483647 + + + 1 + + + + Find Next + g + 1048576 + 2147483647 + + + 2 + + + + Find Previous + G + 1179648 + 2147483647 + + + 3 + + + + Use Selection for Find + e + 1048576 + 2147483647 + + + 7 + + + + Jump to Selection + j + 1048576 + 2147483647 + + + + + + + + + Spelling and Grammar + + 1048576 + 2147483647 + + + submenuAction: + + Spelling and Grammar + + YES + + + U2hvdyBTcGVsbGluZ+KApg + : + 1048576 + 2147483647 + + + + + + Check Spelling + ; + 1048576 + 2147483647 + + + + + + Check Spelling While Typing + + 1048576 + 2147483647 + + + + + + Check Grammar With Spelling + + 1048576 + 2147483647 + + + + + + + + + Substitutions + + 1048576 + 2147483647 + + + submenuAction: + + Substitutions + + YES + + + Smart Copy/Paste + f + 1048576 + 2147483647 + + + 1 + + + + Smart Quotes + g + 1048576 + 2147483647 + + + 2 + + + + Smart Links + G + 1179648 + 2147483647 + + + 3 + + + + + + + Speech + + 1048576 + 2147483647 + + + submenuAction: + + Speech + + YES + + + Start Speaking + + 1048576 + 2147483647 + + + + + + Stop Speaking + + 1048576 + 2147483647 + + + + + + + + + + + + Format + + 2147483647 + + + submenuAction: + + Format + + YES + + + Font + + 2147483647 + + + submenuAction: + + Font + + YES + + + Show Fonts + t + 1048576 + 2147483647 + + + + + + Bold + b + 1048576 + 2147483647 + + + 2 + + + + Italic + i + 1048576 + 2147483647 + + + 1 + + + + Underline + u + 1048576 + 2147483647 + + + + + + YES + YES + + + 2147483647 + + + + + + Bigger + + + 1048576 + 2147483647 + + + 3 + + + + Smaller + - + 1048576 + 2147483647 + + + 4 + + + + YES + YES + + + 2147483647 + + + + + + Kern + + 2147483647 + + + submenuAction: + + Kern + + YES + + + Use Default + + 2147483647 + + + + + + Use None + + 2147483647 + + + + + + Tighten + + 2147483647 + + + + + + Loosen + + 2147483647 + + + + + + + + + Ligature + + 2147483647 + + + submenuAction: + + Ligature + + YES + + + Use Default + + 2147483647 + + + + + + Use None + + 2147483647 + + + + + + Use All + + 2147483647 + + + + + + + + + Baseline + + 2147483647 + + + submenuAction: + + Baseline + + YES + + + Use Default + + 2147483647 + + + + + + Superscript + + 2147483647 + + + + + + Subscript + + 2147483647 + + + + + + Raise + + 2147483647 + + + + + + Lower + + 2147483647 + + + + + + + + + YES + YES + + + 2147483647 + + + + + + Show Colors + C + 1048576 + 2147483647 + + + + + + YES + YES + + + 2147483647 + + + + + + Copy Style + c + 1572864 + 2147483647 + + + + + + Paste Style + v + 1572864 + 2147483647 + + + + + _NSFontMenu + + + + + Text + + 2147483647 + + + submenuAction: + + Text + + YES + + + Align Left + { + 1048576 + 2147483647 + + + + + + Center + | + 1048576 + 2147483647 + + + + + + Justify + + 2147483647 + + + + + + Align Right + } + 1048576 + 2147483647 + + + + + + YES + YES + + + 2147483647 + + + + + + Show Ruler + + 2147483647 + + + + + + Copy Ruler + c + 1310720 + 2147483647 + + + + + + Paste Ruler + v + 1310720 + 2147483647 + + + + + + + + + + + + View + + 1048576 + 2147483647 + + + submenuAction: + + View + + YES + + + Show Toolbar + t + 1572864 + 2147483647 + + + + + + Q3VzdG9taXplIFRvb2xiYXLigKY + + 1048576 + 2147483647 + + + + + + + + + Window + + 1048576 + 2147483647 + + + submenuAction: + + Window + + YES + + + Minimize + m + 1048576 + 2147483647 + + + + + + Zoom + + 1048576 + 2147483647 + + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Bring All to Front + + 1048576 + 2147483647 + + + + + _NSWindowsMenu + + + + + Help + + 1048576 + 2147483647 + + + submenuAction: + + Help + + YES + + + NewApplication Help + ? + 1048576 + 2147483647 + + + + + + + + _NSMainMenu + + + 15 + 2 + {{335, 58}, {982, 692}} + 1946157056 + Window + NSWindow + + {3.40282e+38, 3.40282e+38} + + + 319 + + YES + + + 18 + + YES + + + 256 + {{1, 1}, {842, 640}} + + + + {{17, 16}, {844, 656}} + + {0, 0} + + 67239424 + 0 + Scintilla Editor + + LucidaGrande + 1.100000e+01 + 3100 + + + 6 + System + textBackgroundColor + + 3 + MQA + + + + 3 + MCAwLjgwMDAwMDAxAA + + + + 1 + 0 + 2 + NO + + + + 289 + {{872, 12}, {96, 32}} + + YES + + 67239424 + 134217728 + Quit + + LucidaGrande + 1.300000e+01 + 1044 + + + -2038284033 + 129 + + + 200 + 25 + + + + {982, 692} + + + {{0, 0}, {1440, 878}} + {3.40282e+38, 3.40282e+38} + + + NSFontManager + + + AppController + + + + + YES + + + performMiniaturize: + + + + 37 + + + + arrangeInFront: + + + + 39 + + + + print: + + + + 86 + + + + runPageLayout: + + + + 87 + + + + clearRecentDocuments: + + + + 127 + + + + orderFrontStandardAboutPanel: + + + + 142 + + + + performClose: + + + + 193 + + + + toggleContinuousSpellChecking: + + + + 222 + + + + undo: + + + + 223 + + + + copy: + + + + 224 + + + + checkSpelling: + + + + 225 + + + + paste: + + + + 226 + + + + stopSpeaking: + + + + 227 + + + + cut: + + + + 228 + + + + showGuessPanel: + + + + 230 + + + + redo: + + + + 231 + + + + selectAll: + + + + 232 + + + + startSpeaking: + + + + 233 + + + + delete: + + + + 235 + + + + performZoom: + + + + 240 + + + + performFindPanelAction: + + + + 241 + + + + centerSelectionInVisibleArea: + + + + 245 + + + + toggleGrammarChecking: + + + + 347 + + + + toggleSmartInsertDelete: + + + + 355 + + + + toggleAutomaticQuoteSubstitution: + + + + 356 + + + + toggleAutomaticLinkDetection: + + + + 357 + + + + showHelp: + + + + 360 + + + + saveDocument: + + + + 362 + + + + saveDocumentAs: + + + + 363 + + + + revertDocumentToSaved: + + + + 364 + + + + runToolbarCustomizationPalette: + + + + 365 + + + + toggleToolbarShown: + + + + 366 + + + + hide: + + + + 367 + + + + hideOtherApplications: + + + + 368 + + + + unhideAllApplications: + + + + 370 + + + + newDocument: + + + + 373 + + + + openDocument: + + + + 374 + + + + addFontTrait: + + + + 421 + + + + addFontTrait: + + + + 422 + + + + modifyFont: + + + + 423 + + + + orderFrontFontPanel: + + + + 424 + + + + modifyFont: + + + + 425 + + + + raiseBaseline: + + + + 426 + + + + lowerBaseline: + + + + 427 + + + + copyFont: + + + + 428 + + + + subscript: + + + + 429 + + + + superscript: + + + + 430 + + + + tightenKerning: + + + + 431 + + + + underline: + + + + 432 + + + + orderFrontColorPanel: + + + + 433 + + + + useAllLigatures: + + + + 434 + + + + loosenKerning: + + + + 435 + + + + pasteFont: + + + + 436 + + + + unscript: + + + + 437 + + + + useStandardKerning: + + + + 438 + + + + useStandardLigatures: + + + + 439 + + + + turnOffLigatures: + + + + 440 + + + + turnOffKerning: + + + + 441 + + + + alignLeft: + + + + 442 + + + + alignJustified: + + + + 443 + + + + copyRuler: + + + + 444 + + + + alignCenter: + + + + 445 + + + + toggleRuler: + + + + 446 + + + + alignRight: + + + + 447 + + + + pasteRuler: + + + + 448 + + + + terminate: + + + + 449 + + + + mEditHost + + + + 454 + + + + terminate: + + + + 455 + + + + + YES + + 0 + + YES + + + + + + -2 + + + RmlsZSdzIE93bmVyA + + + -1 + + + First Responder + + + -3 + + + Application + + + 29 + + + YES + + + + + + + + + + MainMenu + + + 19 + + + YES + + + + + + 56 + + + YES + + + + + + 103 + + + YES + + + + 1 + + + 217 + + + YES + + + + + + 83 + + + YES + + + + + + 81 + + + YES + + + + + + + + + + + + + + + + 75 + + + 3 + + + 80 + + + 8 + + + 78 + + + 6 + + + 72 + + + + + 82 + + + 9 + + + 124 + + + YES + + + + + + 77 + + + 5 + + + 73 + + + 1 + + + 79 + + + 7 + + + 112 + + + 10 + + + 74 + + + 2 + + + 125 + + + YES + + + + + + 126 + + + + + 205 + + + YES + + + + + + + + + + + + + + + + + + 202 + + + + + 198 + + + + + 207 + + + + + 214 + + + + + 199 + + + + + 203 + + + + + 197 + + + + + 206 + + + + + 215 + + + + + 218 + + + YES + + + + + + 216 + + + YES + + + + + + 200 + + + YES + + + + + + + + + 219 + + + + + 201 + + + + + 204 + + + + + 220 + + + YES + + + + + + + + + + 213 + + + + + 210 + + + + + 221 + + + + + 208 + + + + + 209 + + + + + 106 + + + YES + + + + 2 + + + 111 + + + + + 57 + + + YES + + + + + + + + + + + + + + + + 58 + + + + + 134 + + + + + 150 + + + + + 136 + + + 1111 + + + 144 + + + + + 129 + + + 121 + + + 143 + + + + + 236 + + + + + 131 + + + YES + + + + + + 149 + + + + + 145 + + + + + 130 + + + + + 24 + + + YES + + + + + + + + + 92 + + + + + 5 + + + + + 239 + + + + + 23 + + + + + 295 + + + YES + + + + + + 296 + + + YES + + + + + + + 297 + + + + + 298 + + + + + 211 + + + YES + + + + + + 212 + + + YES + + + + + + + 195 + + + + + 196 + + + + + 346 + + + + + 348 + + + YES + + + + + + 349 + + + YES + + + + + + + + 350 + + + + + 351 + + + + + 354 + + + + + 371 + + + YES + + + + + + 372 + + + YES + + + + + + + 375 + + + YES + + + + + + 376 + + + YES + + + + + + + 377 + + + YES + + + + + + 378 + + + YES + + + + + + 379 + + + YES + + + + + + + + + + + + + 380 + + + + + 381 + + + + + 382 + + + + + 383 + + + + + 384 + + + + + 385 + + + + + 386 + + + + + 387 + + + + + 388 + + + YES + + + + + + + + + + + + + + + + + + + + + 389 + + + + + 390 + + + + + 391 + + + + + 392 + + + + + 393 + + + + + 394 + + + + + 395 + + + + + 396 + + + + + 397 + + + YES + + + + + + 398 + + + YES + + + + + + 399 + + + YES + + + + + + 400 + + + + + 401 + + + + + 402 + + + + + 403 + + + + + 404 + + + + + 405 + + + YES + + + + + + + + + + 406 + + + + + 407 + + + + + 408 + + + + + 409 + + + + + 410 + + + + + 411 + + + YES + + + + + + + + 412 + + + + + 413 + + + + + 414 + + + + + 415 + + + YES + + + + + + + + + 416 + + + + + 417 + + + + + 418 + + + + + 419 + + + + + 420 + + + + + 450 + + + + + 451 + + + + + 452 + + + YES + + + + + + 453 + + + + + + + YES + + YES + -1.IBPluginDependency + -2.IBPluginDependency + -3.IBPluginDependency + 103.IBPluginDependency + 103.ImportedFromIB2 + 106.IBPluginDependency + 106.ImportedFromIB2 + 106.editorWindowContentRectSynchronizationRect + 111.IBPluginDependency + 111.ImportedFromIB2 + 112.IBPluginDependency + 112.ImportedFromIB2 + 124.IBPluginDependency + 124.ImportedFromIB2 + 125.IBPluginDependency + 125.ImportedFromIB2 + 125.editorWindowContentRectSynchronizationRect + 126.IBPluginDependency + 126.ImportedFromIB2 + 129.IBPluginDependency + 129.ImportedFromIB2 + 130.IBPluginDependency + 130.ImportedFromIB2 + 130.editorWindowContentRectSynchronizationRect + 131.IBPluginDependency + 131.ImportedFromIB2 + 134.IBPluginDependency + 134.ImportedFromIB2 + 136.IBPluginDependency + 136.ImportedFromIB2 + 143.IBPluginDependency + 143.ImportedFromIB2 + 144.IBPluginDependency + 144.ImportedFromIB2 + 145.IBPluginDependency + 145.ImportedFromIB2 + 149.IBPluginDependency + 149.ImportedFromIB2 + 150.IBPluginDependency + 150.ImportedFromIB2 + 19.IBPluginDependency + 19.ImportedFromIB2 + 195.IBPluginDependency + 195.ImportedFromIB2 + 196.IBPluginDependency + 196.ImportedFromIB2 + 197.IBPluginDependency + 197.ImportedFromIB2 + 198.IBPluginDependency + 198.ImportedFromIB2 + 199.IBPluginDependency + 199.ImportedFromIB2 + 200.IBPluginDependency + 200.ImportedFromIB2 + 200.editorWindowContentRectSynchronizationRect + 201.IBPluginDependency + 201.ImportedFromIB2 + 202.IBPluginDependency + 202.ImportedFromIB2 + 203.IBPluginDependency + 203.ImportedFromIB2 + 204.IBPluginDependency + 204.ImportedFromIB2 + 205.IBPluginDependency + 205.ImportedFromIB2 + 205.editorWindowContentRectSynchronizationRect + 206.IBPluginDependency + 206.ImportedFromIB2 + 207.IBPluginDependency + 207.ImportedFromIB2 + 208.IBPluginDependency + 208.ImportedFromIB2 + 209.IBPluginDependency + 209.ImportedFromIB2 + 210.IBPluginDependency + 210.ImportedFromIB2 + 211.IBPluginDependency + 211.ImportedFromIB2 + 212.IBPluginDependency + 212.ImportedFromIB2 + 212.editorWindowContentRectSynchronizationRect + 213.IBPluginDependency + 213.ImportedFromIB2 + 214.IBPluginDependency + 214.ImportedFromIB2 + 215.IBPluginDependency + 215.ImportedFromIB2 + 216.IBPluginDependency + 216.ImportedFromIB2 + 217.IBPluginDependency + 217.ImportedFromIB2 + 218.IBPluginDependency + 218.ImportedFromIB2 + 219.IBPluginDependency + 219.ImportedFromIB2 + 220.IBPluginDependency + 220.ImportedFromIB2 + 220.editorWindowContentRectSynchronizationRect + 221.IBPluginDependency + 221.ImportedFromIB2 + 23.IBPluginDependency + 23.ImportedFromIB2 + 236.IBPluginDependency + 236.ImportedFromIB2 + 239.IBPluginDependency + 239.ImportedFromIB2 + 24.IBPluginDependency + 24.ImportedFromIB2 + 24.editorWindowContentRectSynchronizationRect + 29.IBEditorWindowLastContentRect + 29.IBPluginDependency + 29.ImportedFromIB2 + 29.WindowOrigin + 29.editorWindowContentRectSynchronizationRect + 295.IBPluginDependency + 296.IBPluginDependency + 296.editorWindowContentRectSynchronizationRect + 297.IBPluginDependency + 298.IBPluginDependency + 346.IBPluginDependency + 346.ImportedFromIB2 + 348.IBPluginDependency + 348.ImportedFromIB2 + 349.IBPluginDependency + 349.ImportedFromIB2 + 349.editorWindowContentRectSynchronizationRect + 350.IBPluginDependency + 350.ImportedFromIB2 + 351.IBPluginDependency + 351.ImportedFromIB2 + 354.IBPluginDependency + 354.ImportedFromIB2 + 371.IBEditorWindowLastContentRect + 371.IBWindowTemplateEditedContentRect + 371.NSWindowTemplate.visibleAtLaunch + 371.editorWindowContentRectSynchronizationRect + 371.windowTemplate.maxSize + 372.IBPluginDependency + 375.IBPluginDependency + 376.IBEditorWindowLastContentRect + 376.IBPluginDependency + 377.IBPluginDependency + 378.IBPluginDependency + 379.IBPluginDependency + 380.IBPluginDependency + 381.IBPluginDependency + 382.IBPluginDependency + 383.IBPluginDependency + 384.IBPluginDependency + 385.IBPluginDependency + 386.IBPluginDependency + 387.IBPluginDependency + 388.IBEditorWindowLastContentRect + 388.IBPluginDependency + 389.IBPluginDependency + 390.IBPluginDependency + 391.IBPluginDependency + 392.IBPluginDependency + 393.IBPluginDependency + 394.IBPluginDependency + 395.IBPluginDependency + 396.IBPluginDependency + 397.IBPluginDependency + 398.IBPluginDependency + 399.IBPluginDependency + 400.IBPluginDependency + 401.IBPluginDependency + 402.IBPluginDependency + 403.IBPluginDependency + 404.IBPluginDependency + 405.IBPluginDependency + 406.IBPluginDependency + 407.IBPluginDependency + 408.IBPluginDependency + 409.IBPluginDependency + 410.IBPluginDependency + 411.IBPluginDependency + 412.IBPluginDependency + 413.IBPluginDependency + 414.IBPluginDependency + 415.IBPluginDependency + 416.IBPluginDependency + 417.IBPluginDependency + 418.IBPluginDependency + 419.IBPluginDependency + 420.IBPluginDependency + 450.IBPluginDependency + 451.IBPluginDependency + 452.IBPluginDependency + 453.IBPluginDependency + 5.IBPluginDependency + 5.ImportedFromIB2 + 56.IBPluginDependency + 56.ImportedFromIB2 + 57.IBEditorWindowLastContentRect + 57.IBPluginDependency + 57.ImportedFromIB2 + 57.editorWindowContentRectSynchronizationRect + 58.IBPluginDependency + 58.ImportedFromIB2 + 72.IBPluginDependency + 72.ImportedFromIB2 + 73.IBPluginDependency + 73.ImportedFromIB2 + 74.IBPluginDependency + 74.ImportedFromIB2 + 75.IBPluginDependency + 75.ImportedFromIB2 + 77.IBPluginDependency + 77.ImportedFromIB2 + 78.IBPluginDependency + 78.ImportedFromIB2 + 79.IBPluginDependency + 79.ImportedFromIB2 + 80.IBPluginDependency + 80.ImportedFromIB2 + 81.IBPluginDependency + 81.ImportedFromIB2 + 81.editorWindowContentRectSynchronizationRect + 82.IBPluginDependency + 82.ImportedFromIB2 + 83.IBPluginDependency + 83.ImportedFromIB2 + 92.IBPluginDependency + 92.ImportedFromIB2 + + + YES + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilderKit + com.apple.InterfaceBuilderKit + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + {{596, 852}, {216, 23}} + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + {{522, 812}, {146, 23}} + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + {{436, 809}, {64, 6}} + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + {{608, 612}, {275, 83}} + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + {{187, 434}, {243, 243}} + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + {{608, 612}, {167, 43}} + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + {{608, 612}, {241, 103}} + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + {{525, 802}, {197, 73}} + {{207, 285}, {478, 20}} + com.apple.InterfaceBuilder.CocoaPlugin + + {74, 862} + {{6, 978}, {478, 20}} + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + {{475, 832}, {234, 43}} + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + {{608, 612}, {215, 63}} + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + {{274, 369}, {982, 692}} + {{274, 369}, {982, 692}} + + {{33, 99}, {480, 360}} + {3.40282e+38, 3.40282e+38} + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + {{437, 242}, {86, 43}} + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + {{523, 2}, {178, 283}} + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + {{219, 102}, {245, 183}} + com.apple.InterfaceBuilder.CocoaPlugin + + {{23, 794}, {245, 183}} + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + {{145, 474}, {199, 203}} + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + + + + YES + + YES + + + YES + + + + + YES + + YES + + + YES + + + + 458 + + + + YES + + AppController + NSObject + + mEditHost + NSBox + + + IBProjectSource + AppController.h + + + + + 0 + ../ScintillaTest.xcodeproj + 3 + + diff --git a/scintilla/cocoa/ScintillaTest/Info.plist b/scintilla/cocoa/ScintillaTest/Info.plist new file mode 100644 index 00000000..abf64b2f --- /dev/null +++ b/scintilla/cocoa/ScintillaTest/Info.plist @@ -0,0 +1,28 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFile + + CFBundleIdentifier + com.sun.${PRODUCT_NAME:identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + 1.0 + NSMainNibFile + MainMenu + NSPrincipalClass + NSApplication + + diff --git a/scintilla/cocoa/ScintillaTest/Scintilla-Info.plist b/scintilla/cocoa/ScintillaTest/Scintilla-Info.plist new file mode 100644 index 00000000..b3f87c07 --- /dev/null +++ b/scintilla/cocoa/ScintillaTest/Scintilla-Info.plist @@ -0,0 +1,20 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + com.sun.${PRODUCT_NAME:identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + FMWK + CFBundleSignature + ???? + CFBundleVersion + 1.0 + + diff --git a/scintilla/cocoa/ScintillaTest/ScintillaTest.xcodeproj/project.pbxproj b/scintilla/cocoa/ScintillaTest/ScintillaTest.xcodeproj/project.pbxproj new file mode 100644 index 00000000..43f5b79c --- /dev/null +++ b/scintilla/cocoa/ScintillaTest/ScintillaTest.xcodeproj/project.pbxproj @@ -0,0 +1,381 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 45; + objects = { + +/* Begin PBXBuildFile section */ + 1DDD58160DA1D0A300B32029 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1DDD58140DA1D0A300B32029 /* MainMenu.xib */; }; + 271FA52C0F850BE20033D021 /* AppController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 271FA52B0F850BE20033D021 /* AppController.mm */; }; + 2791F4490FC1A8E9009DBCF9 /* TestData.sql in Resources */ = {isa = PBXBuildFile; fileRef = 2791F4480FC1A8E9009DBCF9 /* TestData.sql */; }; + 27AF7EC30FC2C351007160EF /* Scintilla.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2744E5EA0FC16BE200E85C33 /* Scintilla.framework */; }; + 27AF7ECA0FC2C388007160EF /* Scintilla.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 2744E5EA0FC16BE200E85C33 /* Scintilla.framework */; }; + 8D11072B0486CEB800E47090 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */; }; + 8D11072D0486CEB800E47090 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; settings = {ATTRIBUTES = (); }; }; + 8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 2744E5E90FC16BE200E85C33 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 2744E5E20FC16BE200E85C33 /* ScintillaFramework.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 8DC2EF5B0486A6940098B216; + remoteInfo = Scintilla; + }; + 27AF7EC60FC2C36A007160EF /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 2744E5E20FC16BE200E85C33 /* ScintillaFramework.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = 8DC2EF4F0486A6940098B216; + remoteInfo = Scintilla; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 272133C20F973596006BE49A /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + 27AF7ECA0FC2C388007160EF /* Scintilla.framework in CopyFiles */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 089C165DFE840E0CC02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = ""; }; + 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = ""; }; + 13E42FB307B3F0F600E4EEF1 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = /System/Library/Frameworks/CoreData.framework; sourceTree = ""; }; + 1DDD58150DA1D0A300B32029 /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = English.lproj/MainMenu.xib; sourceTree = ""; }; + 271FA52A0F850BE20033D021 /* AppController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppController.h; sourceTree = ""; }; + 271FA52B0F850BE20033D021 /* AppController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = AppController.mm; sourceTree = ""; wrapsLines = 0; }; + 2744E5E20FC16BE200E85C33 /* ScintillaFramework.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = ScintillaFramework.xcodeproj; path = ../ScintillaFramework/ScintillaFramework.xcodeproj; sourceTree = SOURCE_ROOT; }; + 2791F4480FC1A8E9009DBCF9 /* TestData.sql */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = TestData.sql; sourceTree = ""; }; + 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 29B97324FDCFA39411CA2CEA /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = ""; }; + 29B97325FDCFA39411CA2CEA /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = ""; }; + 32CA4F630368D1EE00C91783 /* ScintillaTest_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScintillaTest_Prefix.pch; sourceTree = ""; }; + 8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 8D1107320486CEB800E47090 /* ScintillaTest.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ScintillaTest.app; sourceTree = BUILT_PRODUCTS_DIR; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 8D11072E0486CEB800E47090 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 27AF7EC30FC2C351007160EF /* Scintilla.framework in Frameworks */, + 8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 080E96DDFE201D6D7F000001 /* Classes */ = { + isa = PBXGroup; + children = ( + 271FA52A0F850BE20033D021 /* AppController.h */, + 271FA52B0F850BE20033D021 /* AppController.mm */, + ); + name = Classes; + sourceTree = ""; + }; + 1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */ = { + isa = PBXGroup; + children = ( + 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */, + ); + name = "Linked Frameworks"; + sourceTree = ""; + }; + 1058C7A2FEA54F0111CA2CBB /* Other Frameworks */ = { + isa = PBXGroup; + children = ( + 29B97324FDCFA39411CA2CEA /* AppKit.framework */, + 13E42FB307B3F0F600E4EEF1 /* CoreData.framework */, + 29B97325FDCFA39411CA2CEA /* Foundation.framework */, + ); + name = "Other Frameworks"; + sourceTree = ""; + }; + 19C28FACFE9D520D11CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 8D1107320486CEB800E47090 /* ScintillaTest.app */, + ); + name = Products; + sourceTree = ""; + }; + 2744E5E30FC16BE200E85C33 /* Products */ = { + isa = PBXGroup; + children = ( + 2744E5EA0FC16BE200E85C33 /* Scintilla.framework */, + ); + name = Products; + sourceTree = ""; + }; + 29B97314FDCFA39411CA2CEA /* ScintillaTest */ = { + isa = PBXGroup; + children = ( + 2744E5E20FC16BE200E85C33 /* ScintillaFramework.xcodeproj */, + 080E96DDFE201D6D7F000001 /* Classes */, + 29B97315FDCFA39411CA2CEA /* Other Sources */, + 29B97317FDCFA39411CA2CEA /* Resources */, + 29B97323FDCFA39411CA2CEA /* Frameworks */, + 19C28FACFE9D520D11CA2CBB /* Products */, + ); + name = ScintillaTest; + sourceTree = ""; + }; + 29B97315FDCFA39411CA2CEA /* Other Sources */ = { + isa = PBXGroup; + children = ( + 32CA4F630368D1EE00C91783 /* ScintillaTest_Prefix.pch */, + 29B97316FDCFA39411CA2CEA /* main.m */, + ); + name = "Other Sources"; + sourceTree = ""; + }; + 29B97317FDCFA39411CA2CEA /* Resources */ = { + isa = PBXGroup; + children = ( + 2791F4480FC1A8E9009DBCF9 /* TestData.sql */, + 8D1107310486CEB800E47090 /* Info.plist */, + 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */, + 1DDD58140DA1D0A300B32029 /* MainMenu.xib */, + ); + name = Resources; + sourceTree = ""; + }; + 29B97323FDCFA39411CA2CEA /* Frameworks */ = { + isa = PBXGroup; + children = ( + 1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */, + 1058C7A2FEA54F0111CA2CBB /* Other Frameworks */, + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 8D1107260486CEB800E47090 /* ScintillaTest */ = { + isa = PBXNativeTarget; + buildConfigurationList = C01FCF4A08A954540054247B /* Build configuration list for PBXNativeTarget "ScintillaTest" */; + buildPhases = ( + 8D1107290486CEB800E47090 /* Resources */, + 8D11072C0486CEB800E47090 /* Sources */, + 8D11072E0486CEB800E47090 /* Frameworks */, + 272133C20F973596006BE49A /* CopyFiles */, + ); + buildRules = ( + ); + dependencies = ( + 27AF7EC70FC2C36A007160EF /* PBXTargetDependency */, + ); + name = ScintillaTest; + productInstallPath = "$(HOME)/Applications"; + productName = ScintillaTest; + productReference = 8D1107320486CEB800E47090 /* ScintillaTest.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 29B97313FDCFA39411CA2CEA /* Project object */ = { + isa = PBXProject; + buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "ScintillaTest" */; + compatibilityVersion = "Xcode 3.1"; + hasScannedForEncodings = 1; + mainGroup = 29B97314FDCFA39411CA2CEA /* ScintillaTest */; + projectDirPath = ""; + projectReferences = ( + { + ProductGroup = 2744E5E30FC16BE200E85C33 /* Products */; + ProjectRef = 2744E5E20FC16BE200E85C33 /* ScintillaFramework.xcodeproj */; + }, + ); + projectRoot = ""; + targets = ( + 8D1107260486CEB800E47090 /* ScintillaTest */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXReferenceProxy section */ + 2744E5EA0FC16BE200E85C33 /* Scintilla.framework */ = { + isa = PBXReferenceProxy; + fileType = wrapper.framework; + path = Scintilla.framework; + remoteRef = 2744E5E90FC16BE200E85C33 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; +/* End PBXReferenceProxy section */ + +/* Begin PBXResourcesBuildPhase section */ + 8D1107290486CEB800E47090 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 8D11072B0486CEB800E47090 /* InfoPlist.strings in Resources */, + 1DDD58160DA1D0A300B32029 /* MainMenu.xib in Resources */, + 2791F4490FC1A8E9009DBCF9 /* TestData.sql in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 8D11072C0486CEB800E47090 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 8D11072D0486CEB800E47090 /* main.m in Sources */, + 271FA52C0F850BE20033D021 /* AppController.mm in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 27AF7EC70FC2C36A007160EF /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = Scintilla; + targetProxy = 27AF7EC60FC2C36A007160EF /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */ = { + isa = PBXVariantGroup; + children = ( + 089C165DFE840E0CC02AAC07 /* English */, + ); + name = InfoPlist.strings; + sourceTree = ""; + }; + 1DDD58140DA1D0A300B32029 /* MainMenu.xib */ = { + isa = PBXVariantGroup; + children = ( + 1DDD58150DA1D0A300B32029 /* English */, + ); + name = MainMenu.xib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + C01FCF4B08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "\"$(SRCROOT)/../../../../MySQL/Workbench/5.2/ext/scintilla/cocoa/ScintillaFramework/build/Debug\"", + ); + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_MODEL_TUNING = G5; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = ScintillaTest_Prefix.pch; + GCC_PREPROCESSOR_DEFINITIONS = ( + SCI_LEXER, + SCI_NAMESPACE, + ); + HEADER_SEARCH_PATHS = "../..//**"; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "$(HOME)/Applications"; + LIBRARY_SEARCH_PATHS = "$(inherited)"; + OTHER_LDFLAGS = ""; + PRODUCT_NAME = ScintillaTest; + USER_HEADER_SEARCH_PATHS = ""; + }; + name = Debug; + }; + C01FCF4C08A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "\"$(SRCROOT)/../../../../MySQL/Workbench/5.2/ext/scintilla/cocoa/ScintillaFramework/build/Debug\"", + ); + GCC_MODEL_TUNING = G5; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = ScintillaTest_Prefix.pch; + GCC_PREPROCESSOR_DEFINITIONS = ( + SCI_LEXER, + SCI_NAMESPACE, + ); + HEADER_SEARCH_PATHS = "../..//**"; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "$(HOME)/Applications"; + LIBRARY_SEARCH_PATHS = "$(inherited)"; + OTHER_LDFLAGS = ""; + PRODUCT_NAME = ScintillaTest; + USER_HEADER_SEARCH_PATHS = ""; + }; + name = Release; + }; + C01FCF4F08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + ONLY_ACTIVE_ARCH = YES; + OTHER_LDFLAGS = ""; + PREBINDING = NO; + SDKROOT = macosx10.5; + }; + name = Debug; + }; + C01FCF5008A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + OTHER_LDFLAGS = ""; + PREBINDING = NO; + SDKROOT = macosx10.5; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + C01FCF4A08A954540054247B /* Build configuration list for PBXNativeTarget "ScintillaTest" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4B08A954540054247B /* Debug */, + C01FCF4C08A954540054247B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C01FCF4E08A954540054247B /* Build configuration list for PBXProject "ScintillaTest" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4F08A954540054247B /* Debug */, + C01FCF5008A954540054247B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; +} diff --git a/scintilla/cocoa/ScintillaTest/ScintillaTest_Prefix.pch b/scintilla/cocoa/ScintillaTest/ScintillaTest_Prefix.pch new file mode 100644 index 00000000..b3d5ee7e --- /dev/null +++ b/scintilla/cocoa/ScintillaTest/ScintillaTest_Prefix.pch @@ -0,0 +1,7 @@ +// +// Prefix header for all source files of the 'ScintillaTest' target in the 'ScintillaTest' project +// + +#ifdef __OBJC__ + #import +#endif diff --git a/scintilla/cocoa/ScintillaTest/TestData.sql b/scintilla/cocoa/ScintillaTest/TestData.sql new file mode 100644 index 00000000..4967885c --- /dev/null +++ b/scintilla/cocoa/ScintillaTest/TestData.sql @@ -0,0 +1,215 @@ +-- MySQL Administrator dump 1.4 +-- +-- ------------------------------------------------------ +-- Server version 5.0.45 + + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; +/*!40101 SET NAMES utf8 */; + +/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO,ANSI_QUOTES' */; + +/** + * Foldable multiline comment. + */ + +-- { +-- Create schema sakila +-- } + +CREATE DATABASE IF NOT EXISTS sakila; +USE sakila; +DROP TABLE IF EXISTS "sakila"."actor_info"; +DROP VIEW IF EXISTS "sakila"."actor_info"; +CREATE TABLE "sakila"."actor_info" ( + "actor_id" smallint(5) unsigned, + "first_name" varchar(45), + "last_name" varchar(45), + "film_info" varchar(341) +); +DROP TABLE IF EXISTS "sakila"."actor"; +CREATE TABLE "sakila"."actor" ( + "actor_id" smallint(5) unsigned NOT NULL auto_increment, + "first_name" varchar(45) NOT NULL, + "last_name" varchar(45) NOT NULL, + "last_update" timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP, + PRIMARY KEY ("actor_id"), + KEY "idx_actor_last_name" ("last_name") +) ENGINE=InnoDB AUTO_INCREMENT=201 DEFAULT CHARSET=utf8; +INSERT INTO "sakila"."actor" VALUES (1,'PENELOPE','GUINESS','2006-02-15 04:34:33'), + (2,'NICK','WAHLBERG','2006-02-15 04:34:33'), + (3,'ED','CHASE','2006-02-15 04:34:33'), + (4,'JENNIFER','DAVIS','2006-02-15 04:34:33'), + (149,'RUSSELL','TEMPLE','2006-02-15 04:34:33'), + (150,'JAYNE','NOLTE','2006-02-15 04:34:33'), + (151,'GEOFFREY','HESTON','2006-02-15 04:34:33'), + (152,'BEN','HARRIS','2006-02-15 04:34:33'), + (153,'MINNIE','KILMER','2006-02-15 04:34:33'), + (154,'MERYL','GIBSON','2006-02-15 04:34:33'), + (155,'IAN','TANDY','2006-02-15 04:34:33'), + (156,'FAY','WOOD','2006-02-15 04:34:33'), + (157,'GRETA','MALDEN','2006-02-15 04:34:33'), + (158,'VIVIEN','BASINGER','2006-02-15 04:34:33'), + (159,'LAURA','BRODY','2006-02-15 04:34:33'), + (160,'CHRIS','DEPP','2006-02-15 04:34:33'), + (161,'HARVEY','HOPE','2006-02-15 04:34:33'), + (162,'OPRAH','KILMER','2006-02-15 04:34:33'), + (163,'CHRISTOPHER','WEST','2006-02-15 04:34:33'), + (164,'HUMPHREY','WILLIS','2006-02-15 04:34:33'), + (165,'AL','GARLAND','2006-02-15 04:34:33'), + (166,'NICK','DEGENERES','2006-02-15 04:34:33'), + (167,'LAURENCE','BULLOCK','2006-02-15 04:34:33'), + (168,'WILL','WILSON','2006-02-15 04:34:33'), + (169,'KENNETH','HOFFMAN','2006-02-15 04:34:33'), + (170,'MENA','HOPPER','2006-02-15 04:34:33'), + (171,'OLYMPIA','PFEIFFER','2006-02-15 04:34:33'), + (190,'AUDREY','BAILEY','2006-02-15 04:34:33'), + (191,'GREGORY','GOODING','2006-02-15 04:34:33'), + (192,'JOHN','SUVARI','2006-02-15 04:34:33'), + (193,'BURT','TEMPLE','2006-02-15 04:34:33'), + (194,'MERYL','ALLEN','2006-02-15 04:34:33'), + (195,'JAYNE','SILVERSTONE','2006-02-15 04:34:33'), + (196,'BELA','WALKEN','2006-02-15 04:34:33'), + (197,'REESE','WEST','2006-02-15 04:34:33'), + (198,'MARY','KEITEL','2006-02-15 04:34:33'), + (199,'JULIA','FAWCETT','2006-02-15 04:34:33'), + (200,'THORA','TEMPLE','2006-02-15 04:34:33'); + +DROP TRIGGER /*!50030 IF EXISTS */ "sakila"."payment_date"; + +DELIMITER $$ + +CREATE DEFINER = "root"@"localhost" TRIGGER "sakila"."payment_date" BEFORE INSERT ON "payment" FOR EACH ROW SET NEW.payment_date = NOW() $$ + +DELIMITER ; + + +DROP TABLE IF EXISTS "sakila"."sales_by_store"; +DROP VIEW IF EXISTS "sakila"."sales_by_store"; +CREATE ALGORITHM=UNDEFINED DEFINER="root"@"localhost" SQL SECURITY DEFINER VIEW "sakila"."sales_by_store" AS select concat("c"."city",_utf8',',"cy"."country") AS "store",concat("m"."first_name",_utf8' ',"m"."last_name") AS "manager",sum("p"."amount") AS "total_sales" from ((((((("sakila"."payment" "p" join "sakila"."rental" "r" on(("p"."rental_id" = "r"."rental_id"))) join "sakila"."inventory" "i" on(("r"."inventory_id" = "i"."inventory_id"))) join "sakila"."store" "s" on(("i"."store_id" = "s"."store_id"))) join "sakila"."address" "a" on(("s"."address_id" = "a"."address_id"))) join "sakila"."city" "c" on(("a"."city_id" = "c"."city_id"))) join "sakila"."country" "cy" on(("c"."country_id" = "cy"."country_id"))) join "sakila"."staff" "m" on(("s"."manager_staff_id" = "m"."staff_id"))) group by "s"."store_id" order by "cy"."country","c"."city"; + +-- +-- View structure for view `staff_list` +-- + +CREATE VIEW staff_list +AS +SELECT s.staff_id AS ID, CONCAT(s.first_name, _utf8' ', s.last_name) AS name, a.address AS address, a.postal_code AS `zip code`, a.phone AS phone, + city.city AS city, country.country AS country, s.store_id AS SID +FROM staff AS s JOIN address AS a ON s.address_id = a.address_id JOIN city ON a.city_id = city.city_id + JOIN country ON city.country_id = country.country_id; + +-- +-- View structure for view `actor_info` +-- + +CREATE DEFINER=CURRENT_USER SQL SECURITY INVOKER VIEW actor_info +AS +SELECT +a.actor_id, +a.first_name, +a.last_name, +GROUP_CONCAT(DISTINCT CONCAT(c.name, ': ', + (SELECT GROUP_CONCAT(f.title ORDER BY f.title SEPARATOR ', ') + FROM sakila.film f + INNER JOIN sakila.film_category fc + ON f.film_id = fc.film_id + INNER JOIN sakila.film_actor fa + ON f.film_id = fa.film_id + WHERE fc.category_id = c.category_id + AND fa.actor_id = a.actor_id + ) + ) + ORDER BY c.name SEPARATOR '; ') +AS film_info +FROM sakila.actor a +LEFT JOIN sakila.film_actor fa + ON a.actor_id = fa.actor_id +LEFT JOIN sakila.film_category fc + ON fa.film_id = fc.film_id +LEFT JOIN sakila.category c + ON fc.category_id = c.category_id +GROUP BY a.actor_id, a.first_name, a.last_name; + +DELIMITER $$ + +CREATE FUNCTION get_customer_balance(p_customer_id INT, p_effective_date DATETIME) RETURNS DECIMAL(5,2) + DETERMINISTIC + READS SQL DATA +BEGIN + + #OK, WE NEED TO CALCULATE THE CURRENT BALANCE GIVEN A CUSTOMER_ID AND A DATE + #THAT WE WANT THE BALANCE TO BE EFFECTIVE FOR. THE BALANCE IS: + # 1) RENTAL FEES FOR ALL PREVIOUS RENTALS + # 2) ONE DOLLAR FOR EVERY DAY THE PREVIOUS RENTALS ARE OVERDUE + # 3) IF A FILM IS MORE THAN RENTAL_DURATION * 2 OVERDUE, CHARGE THE REPLACEMENT_COST + # 4) SUBTRACT ALL PAYMENTS MADE BEFORE THE DATE SPECIFIED + + DECLARE v_rentfees DECIMAL(5,2); #FEES PAID TO RENT THE VIDEOS INITIALLY + DECLARE v_overfees INTEGER; #LATE FEES FOR PRIOR RENTALS + DECLARE v_payments DECIMAL(5,2); #SUM OF PAYMENTS MADE PREVIOUSLY + + SELECT IFNULL(SUM(film.rental_rate),0) INTO v_rentfees + FROM film, inventory, rental + WHERE film.film_id = inventory.film_id + AND inventory.inventory_id = rental.inventory_id + AND rental.rental_date <= p_effective_date + AND rental.customer_id = p_customer_id; + + SELECT IFNULL(SUM(IF((TO_DAYS(rental.return_date) - TO_DAYS(rental.rental_date)) > film.rental_duration, + ((TO_DAYS(rental.return_date) - TO_DAYS(rental.rental_date)) - film.rental_duration),0)),0) INTO v_overfees + FROM rental, inventory, film + WHERE film.film_id = inventory.film_id + AND inventory.inventory_id = rental.inventory_id + AND rental.rental_date <= p_effective_date + AND rental.customer_id = p_customer_id; + + + SELECT IFNULL(SUM(payment.amount),0) INTO v_payments + FROM payment + + WHERE payment.payment_date <= p_effective_date + AND payment.customer_id = p_customer_id; + + RETURN v_rentfees + v_overfees - v_payments; +END $$ + +DELIMITER ; + +DELIMITER $$ + +CREATE FUNCTION inventory_in_stock(p_inventory_id INT) RETURNS BOOLEAN +READS SQL DATA +BEGIN + DECLARE v_rentals INT; + DECLARE v_out INT; + + #AN ITEM IS IN-STOCK IF THERE ARE EITHER NO ROWS IN THE rental TABLE + #FOR THE ITEM OR ALL ROWS HAVE return_date POPULATED + + SELECT COUNT(*) INTO v_rentals + FROM rental + WHERE inventory_id = p_inventory_id; + + IF v_rentals = 0 THEN + RETURN TRUE; + END IF; + + SELECT COUNT(rental_id) INTO v_out + FROM inventory LEFT JOIN rental USING(inventory_id) + WHERE inventory.inventory_id = p_inventory_id + AND rental.return_date IS NULL; + + IF v_out > 0 THEN + RETURN FALSE; + ELSE + RETURN TRUE; + END IF; +END $$ + +DELIMITER ; + diff --git a/scintilla/cocoa/ScintillaTest/main.m b/scintilla/cocoa/ScintillaTest/main.m new file mode 100644 index 00000000..59ff6b2e --- /dev/null +++ b/scintilla/cocoa/ScintillaTest/main.m @@ -0,0 +1,15 @@ +/** + * main.m + * ScintillaTest + * + * Created by Mike Lischke on 02.04.09. + * Copyright Sun Microsystems, Inc 2009. All rights reserved. + * This file is dual licensed under LGPL v2.1 and the Scintilla license (http://www.scintilla.org/License.txt). + */ + +#import + +int main(int argc, char *argv[]) +{ + return NSApplicationMain(argc, (const char **) argv); +} diff --git a/scintilla/cocoa/ScintillaView.h b/scintilla/cocoa/ScintillaView.h new file mode 100644 index 00000000..3e76d3cc --- /dev/null +++ b/scintilla/cocoa/ScintillaView.h @@ -0,0 +1,120 @@ + +/** + * Declaration of the native Cocoa View that serves as container for the scintilla parts. + * + * Created by Mike Lischke. + * + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * This file is dual licensed under LGPL v2.1 and the Scintilla license (http://www.scintilla.org/License.txt). + */ + +#import + +#import "Platform.h" +#import "Scintilla.h" +#import "SciLexer.h" + +#import "InfoBarCommunicator.h" +#import "ScintillaCocoa.h" + +@class ScintillaView; + +extern NSString *SCIUpdateUINotification; + +/** + * InnerView is the Cocoa interface to the Scintilla backend. It handles text input and + * provides a canvas for painting the output. + */ +@interface InnerView : NSView +{ +@private + ScintillaView* mOwner; + NSCursor* mCurrentCursor; + NSTrackingRectTag mCurrentTrackingRect; + + // Set when we are in composition mode and partial input is displayed. + NSRange mMarkedTextRange; + + // Caret position when a drag operation started. + int mLastPosition; +} + +- (void) dealloc; +- (void) removeMarkedText; +- (void) setCursor: (Scintilla::Window::Cursor) cursor; + +@property (retain) ScintillaView* owner; +@end + +@interface ScintillaView : NSView +{ +@private + // 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. + InnerView* mContent; + + NSScroller* mHorizontalScroller; + NSScroller* mVerticalScroller; + + // Area to display additional controls (e.g. zoom info, caret position, status info). + NSView * mInfoBar; + BOOL mInfoBarAtTop; + int mInitialInfoBarWidth; +} + +- (void) dealloc; +- (void) layout; + +- (void) sendNotification: (NSString*) notificationName; +- (void) notify: (NotificationType) type message: (NSString*) message location: (NSPoint) location + value: (float) value; +- (void) setCallback: (id ) callback; + +// Scroller handling +- (BOOL) setVerticalScrollRange: (int) range page: (int) page; +- (void) setVerticalScrollPosition: (float) position; +- (BOOL) setHorizontalScrollRange: (int) range page: (int) page; +- (void) setHorizontalScrollPosition: (float) position; + +- (void) scrollerAction: (id) sender; +- (InnerView*) content; + +// NSTextView compatibility layer. +- (NSString*) string; +- (void) setString: (NSString*) aString; +- (void) insertText: (NSString*) aString; +- (void) setEditable: (BOOL) editable; +- (BOOL) isEditable; +- (NSRange) selectedRange; + +- (NSString*) selectedString; + +// Native call through to the backend. ++ (sptr_t) directCall: (ScintillaView*) sender message: (unsigned int) message wParam: (uptr_t) wParam + lParam: (sptr_t) lParam; + +// Back end properties getters and setters. +- (void) setGeneralProperty: (int) property parameter: (long) parameter value: (long) value; +- (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; + +- (void) setInfoBar: (NSView *) aView top: (BOOL) top; +- (void) setStatusText: (NSString*) text; + +@property Scintilla::ScintillaCocoa* backend; + +@end diff --git a/scintilla/cocoa/ScintillaView.mm b/scintilla/cocoa/ScintillaView.mm new file mode 100644 index 00000000..1863bd93 --- /dev/null +++ b/scintilla/cocoa/ScintillaView.mm @@ -0,0 +1,1376 @@ + +/** + * Implementation of the native Cocoa View that serves as container for the scintilla parts. + * + * Created by Mike Lischke. + * + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * This file is dual licensed under LGPL v2.1 and the Scintilla license (http://www.scintilla.org/License.txt). + */ + +#import "ScintillaView.h" + +using namespace Scintilla; + +// Two additional cursors we need, which aren't provided by Cocoa. +static NSCursor* reverseArrowCursor; +static NSCursor* waitCursor; + +// The scintilla indicator used for keyboard input. +#define INPUT_INDICATOR INDIC_MAX - 1 + +NSString *SCIUpdateUINotification = @"SCIUpdateUI"; + +@implementation InnerView + +@synthesize owner = mOwner; + +//-------------------------------------------------------------------------------------------------- + +- (NSView*) initWithFrame: (NSRect) frame +{ + self = [super initWithFrame: frame]; + + if (self != nil) + { + // Some initialization for our view. + mCurrentCursor = [[NSCursor arrowCursor] retain]; + mCurrentTrackingRect = 0; + mMarkedTextRange = NSMakeRange(NSNotFound, 0); + + [self registerForDraggedTypes: [NSArray arrayWithObjects: + NSStringPboardType, ScintillaRecPboardType, NSFilenamesPboardType, nil]]; + } + + return self; +} + +//-------------------------------------------------------------------------------------------------- + +/** + * When the view is resized we need to update our tracking rectangle and let the backend know. + */ +- (void) setFrame: (NSRect) frame +{ + [super setFrame: frame]; + + // Make the content also a tracking rectangle for mouse events. + if (mCurrentTrackingRect != 0) + [self removeTrackingRect: mCurrentTrackingRect]; + mCurrentTrackingRect = [self addTrackingRect: [self bounds] + owner: self + userData: nil + assumeInside: YES]; + mOwner.backend->Resize(); +} + +//-------------------------------------------------------------------------------------------------- + +/** + * Called by the backend if a new cursor must be set for the view. + */ +- (void) setCursor: (Window::Cursor) cursor +{ + [mCurrentCursor autorelease]; + switch (cursor) + { + case Window::cursorText: + mCurrentCursor = [NSCursor IBeamCursor]; + break; + case Window::cursorArrow: + mCurrentCursor = [NSCursor arrowCursor]; + break; + case Window::cursorWait: + mCurrentCursor = waitCursor; + break; + case Window::cursorHoriz: + mCurrentCursor = [NSCursor resizeLeftRightCursor]; + break; + case Window::cursorVert: + mCurrentCursor = [NSCursor resizeUpDownCursor]; + break; + case Window::cursorReverseArrow: + mCurrentCursor = reverseArrowCursor; + break; + case Window::cursorUp: + default: + mCurrentCursor = [NSCursor arrowCursor]; + break; + } + + [mCurrentCursor retain]; + + // Trigger recreation of the cursor rectangle(s). + [[self window] invalidateCursorRectsForView: self]; +} + +//-------------------------------------------------------------------------------------------------- + +/** + * This method is called to give us the opportunity to define our mouse sensitive rectangle. + */ +- (void) resetCursorRects +{ + [super resetCursorRects]; + + // We only have one cursor rect: our bounds. + NSRect bounds = [self bounds]; + [self addCursorRect: [self bounds] cursor: mCurrentCursor]; + [mCurrentCursor setOnMouseEntered: YES]; +} + +//-------------------------------------------------------------------------------------------------- + +/** + * Gets called by the runtime when the view needs repainting. + */ +- (void) drawRect: (NSRect) rect +{ + CGContextRef context = (CGContextRef) [[NSGraphicsContext currentContext] graphicsPort]; + + mOwner.backend->Draw(rect, context); +} + +//-------------------------------------------------------------------------------------------------- + +/** + * Windows uses a client coordinate system where the upper left corner is the origin in a window + * (and so does Scintilla). We have to adjust for that. However by returning YES here, we are + * already done with that. + * 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) isOpaque +{ + return YES; +} + +//-------------------------------------------------------------------------------------------------- + +/** + * Implement the "click through" behavior by telling the caller we accept the first mouse event too. + */ +- (BOOL) acceptsFirstMouse: (NSEvent *) theEvent +{ + return YES; +} + +//-------------------------------------------------------------------------------------------------- + +/** + * Make this view accepting events as first responder. + */ +- (BOOL) acceptsFirstResponder +{ + return YES; +} + +//-------------------------------------------------------------------------------------------------- + +/** + * Called by the framework if it wants to show a context menu for the editor. + */ +- (NSMenu*) menuForEvent: (NSEvent*) theEvent +{ + return mOwner.backend->CreateContextMenu(theEvent); +} + +//-------------------------------------------------------------------------------------------------- + +// Adoption of NSTextInput protocol. + +- (NSAttributedString*) attributedSubstringFromRange: (NSRange) range +{ + return nil; +} + +//-------------------------------------------------------------------------------------------------- + +- (NSUInteger) characterIndexForPoint: (NSPoint) point +{ + return NSNotFound; +} + +//-------------------------------------------------------------------------------------------------- + +- (NSInteger) conversationIdentifier +{ + return (NSInteger) self; + +} + +//-------------------------------------------------------------------------------------------------- + +- (void) doCommandBySelector: (SEL) selector +{ + if ([self respondsToSelector: @selector(selector)]) + [self performSelector: selector withObject: nil]; +} + +//-------------------------------------------------------------------------------------------------- + +- (NSRect) firstRectForCharacterRange: (NSRange) range +{ + return NSZeroRect; +} + +//-------------------------------------------------------------------------------------------------- + +- (BOOL) hasMarkedText +{ + return mMarkedTextRange.length > 0; +} + +//-------------------------------------------------------------------------------------------------- + +/** + * General text input. Used to insert new text at the current input position, replacing the current + * selection if there is any. + */ +- (void) insertText: (id) aString +{ + // Remove any previously marked text first. + [self removeMarkedText]; + mOwner.backend->InsertText((NSString*) aString); +} + +//-------------------------------------------------------------------------------------------------- + +- (NSRange) markedRange +{ + return mMarkedTextRange; +} + +//-------------------------------------------------------------------------------------------------- + +- (NSRange) selectedRange +{ + int begin = [mOwner getGeneralProperty: SCI_GETSELECTIONSTART parameter: 0]; + int end = [mOwner getGeneralProperty: SCI_GETSELECTIONEND parameter: 0]; + return NSMakeRange(begin, end - begin); +} + +//-------------------------------------------------------------------------------------------------- + +/** + * Called by the input manager to set text which might be combined with further input to form + * the final text (e.g. composition of ^ and a to â). + * + * @param aString The text to insert, either what has been marked already or what is selected already + * or simply added at the current insertion point. Depending on what is available. + * @param range The range of the new text to select (given relative to the insertion point of the new text). + */ +- (void) setMarkedText: (id) aString selectedRange: (NSRange) range +{ + // Since we did not return any valid attribute for marked text (see validAttributesForMarkedText) + // we can safely assume the passed in text is an NSString instance. + NSString* newText = (NSString*) aString; + int currentPosition = [mOwner getGeneralProperty: SCI_GETCURRENTPOS parameter: 0]; + + // Replace marked text if there is one. + if (mMarkedTextRange.length > 0) + { + // We have already marked text. Replace that. + [mOwner setGeneralProperty: SCI_SETSELECTIONSTART + parameter: mMarkedTextRange.location + value: 0]; + [mOwner setGeneralProperty: SCI_SETSELECTIONEND + parameter: mMarkedTextRange.location + mMarkedTextRange.length + value: 0]; + currentPosition = mMarkedTextRange.location; + } + + mOwner.backend->InsertText(newText); + + mMarkedTextRange.location = currentPosition; + mMarkedTextRange.length = [newText length]; + + // Mark the just inserted text. Keep the marked range for later reset. + [mOwner setGeneralProperty: SCI_SETINDICATORCURRENT parameter: INPUT_INDICATOR value: 0]; + [mOwner setGeneralProperty: SCI_INDICATORFILLRANGE + parameter: mMarkedTextRange.location + value: mMarkedTextRange.length]; + + // Select the part which is indicated in the given range. + if (range.length > 0) + { + [mOwner setGeneralProperty: SCI_SETSELECTIONSTART + parameter: currentPosition + range.location + value: 0]; + [mOwner setGeneralProperty: SCI_SETSELECTIONEND + parameter: currentPosition + range.location + range.length + value: 0]; + } +} + +//-------------------------------------------------------------------------------------------------- + +- (void) unmarkText +{ + if (mMarkedTextRange.length > 0) + { + [mOwner setGeneralProperty: SCI_SETINDICATORCURRENT parameter: INPUT_INDICATOR value: 0]; + [mOwner setGeneralProperty: SCI_INDICATORCLEARRANGE + parameter: mMarkedTextRange.location + value: mMarkedTextRange.length]; + mMarkedTextRange = NSMakeRange(NSNotFound, 0); + } +} + +//-------------------------------------------------------------------------------------------------- + +/** + * Removes any currently marked text. + */ +- (void) removeMarkedText +{ + if (mMarkedTextRange.length > 0) + { + // We have already marked text. Replace that. + [mOwner setGeneralProperty: SCI_SETSELECTIONSTART + parameter: mMarkedTextRange.location + value: 0]; + [mOwner setGeneralProperty: SCI_SETSELECTIONEND + parameter: mMarkedTextRange.location + mMarkedTextRange.length + value: 0]; + mOwner.backend->InsertText(@""); + mMarkedTextRange = NSMakeRange(NSNotFound, 0); + } +} + +//-------------------------------------------------------------------------------------------------- + +- (NSArray*) validAttributesForMarkedText +{ + return nil; +} + +// End of the NSTextInput protocol adoption. + +//-------------------------------------------------------------------------------------------------- + +/** + * Generic input method. It is used to pass on keyboard input to Scintilla. The control itself only + * handles shortcuts. The input is then forwarded to the Cocoa text input system, which in turn does + * its own input handling (character composition via NSTextInput protocol): + */ +- (void) keyDown: (NSEvent *) theEvent +{ + mOwner.backend->KeyboardInput(theEvent); + NSArray* events = [NSArray arrayWithObject: theEvent]; + [self interpretKeyEvents: events]; +} + +//-------------------------------------------------------------------------------------------------- + +- (void) mouseDown: (NSEvent *) theEvent +{ + mOwner.backend->MouseDown(theEvent); +} + +//-------------------------------------------------------------------------------------------------- + +- (void) mouseDragged: (NSEvent *) theEvent +{ + mOwner.backend->MouseMove(theEvent); +} + +//-------------------------------------------------------------------------------------------------- + +- (void) mouseUp: (NSEvent *) theEvent +{ + mOwner.backend->MouseUp(theEvent); +} + +//-------------------------------------------------------------------------------------------------- + +- (void) mouseMoved: (NSEvent *) theEvent +{ + mOwner.backend->MouseMove(theEvent); +} + +//-------------------------------------------------------------------------------------------------- + +- (void) mouseEntered: (NSEvent *) theEvent +{ + mOwner.backend->MouseEntered(theEvent); +} + +//-------------------------------------------------------------------------------------------------- + +- (void) mouseExited: (NSEvent *) theEvent +{ + mOwner.backend->MouseExited(theEvent); +} + +//-------------------------------------------------------------------------------------------------- + +- (void) scrollWheel: (NSEvent *) theEvent +{ + mOwner.backend->MouseWheel(theEvent); +} + +//-------------------------------------------------------------------------------------------------- + +/** + * The editor is getting the foreground control (the one getting the input focus). + */ +- (BOOL) becomeFirstResponder +{ + mOwner.backend->WndProc(SCI_SETFOCUS, 1, 0); + return YES; +} + +//-------------------------------------------------------------------------------------------------- + +/** + * The editor is losing the input focus. + */ +- (BOOL) resignFirstResponder +{ + mOwner.backend->WndProc(SCI_SETFOCUS, 0, 0); + return YES; +} + +//-------------------------------------------------------------------------------------------------- + +/** + * Called when an external drag operation enters the view. + */ +- (NSDragOperation) draggingEntered: (id ) sender +{ + return mOwner.backend->DraggingEntered(sender); +} + +//-------------------------------------------------------------------------------------------------- + +/** + * Called frequently during an external drag operation if we are the target. + */ +- (NSDragOperation) draggingUpdated: (id ) sender +{ + return mOwner.backend->DraggingUpdated(sender); +} + +//-------------------------------------------------------------------------------------------------- + +/** + * Drag image left the view. Clean up if necessary. + */ +- (void) draggingExited: (id ) sender +{ + mOwner.backend->DraggingExited(sender); +} + +//-------------------------------------------------------------------------------------------------- + +- (BOOL) prepareForDragOperation: (id ) sender +{ + return YES; +} + +//-------------------------------------------------------------------------------------------------- + +- (BOOL) performDragOperation: (id ) sender +{ + return mOwner.backend->PerformDragOperation(sender); +} + +//-------------------------------------------------------------------------------------------------- + +/** + * Returns operations we allow as drag source. + */ +- (NSDragOperation) draggingSourceOperationMaskForLocal: (BOOL) flag +{ + return NSDragOperationCopy | NSDragOperationMove; +} + +//-------------------------------------------------------------------------------------------------- + +/** + * Drag operation is done. Notify editor. + */ +- (void) concludeDragOperation: (id ) 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 +{ + mOwner.backend->SelectAll(); +} + +- (void) deleteBackward: (id) sender +{ + mOwner.backend->DeleteBackward(); +} + +- (void) cut: (id) sender +{ + mOwner.backend->Cut(); +} + +- (void) copy: (id) sender +{ + mOwner.backend->Copy(); +} + +- (void) paste: (id) sender +{ + mOwner.backend->Paste(); +} + +- (void) undo: (id) sender +{ + mOwner.backend->Undo(); +} + +- (void) redo: (id) sender +{ + mOwner.backend->Redo(); +} + +//-------------------------------------------------------------------------------------------------- + +- (void) dealloc +{ + [mCurrentCursor release]; + [super dealloc]; +} + +@end + +//-------------------------------------------------------------------------------------------------- + +@implementation ScintillaView + +@synthesize backend = mBackend; + +/** + * ScintiallView is a composite control made from an NSView and an embedded NSView that is + * used as canvas for the output (by the backend, using its CGContext), plus other elements + * (scrollers, info bar). + */ + +//-------------------------------------------------------------------------------------------------- + +/** + * Initialize custom cursor. + */ ++ (void) initialize +{ + if (self == [ScintillaView class]) + { + NSBundle* bundle = [NSBundle bundleForClass: [ScintillaView class]]; + + NSString* path = [bundle pathForResource: @"mac_cursor_busy" ofType: @"png" inDirectory: nil]; + NSImage* image = [[[NSImage alloc] initWithContentsOfFile: path] autorelease]; + waitCursor = [[NSCursor alloc] initWithImage: image hotSpot: NSMakePoint(2, 2)]; + + path = [bundle pathForResource: @"mac_cursor_flipped" ofType: @"png" inDirectory: nil]; + image = [[[NSImage alloc] initWithContentsOfFile: path] autorelease]; + reverseArrowCursor = [[NSCursor alloc] initWithImage: image hotSpot: NSMakePoint(12, 2)]; + } +} + +//-------------------------------------------------------------------------------------------------- + +/** + * 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]; +} + +//-------------------------------------------------------------------------------------------------- + +/** + * Called by a connected compontent (usually the info bar) if something changed there. + * + * @param type The type of the notification. + * @param message Carries the new status message if the type is a status message change. + * @param location Carries the new location (e.g. caret) if the type is a caret change or similar type. + * @param location 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: + { + // Compute point increase/decrease based on default font size. + int fontSize = [self getGeneralProperty: SCI_STYLEGETSIZE parameter: STYLE_DEFAULT]; + int zoom = (int) (fontSize * (value - 1)); + [self setGeneralProperty: SCI_SETZOOM parameter: zoom value: 0]; + break; + } + }; +} + +//-------------------------------------------------------------------------------------------------- + +- (void) setCallback: (id ) callback +{ + // Not used. Only here to satisfy protocol. +} + +//-------------------------------------------------------------------------------------------------- + +/** + * Notification function used by Scintilla to call us back (e.g. for handling clicks on the + * folder margin or changes in the editor). + */ +static void notification(intptr_t windowid, unsigned int iMessage, uintptr_t wParam, uintptr_t lParam) +{ + // WM_NOTIFY means we got a parent notification with a special notification structure. + // Here we don't really differentiate between parent and own notifications and handle both. + ScintillaView* editor; + switch (iMessage) + { + case WM_NOTIFY: + { + // Parent notification. Details are passed as SCNotification structure. + SCNotification* scn = reinterpret_cast(lParam); + editor = reinterpret_cast(scn->nmhdr.idFrom).owner; + switch (scn->nmhdr.code) + { + case SCN_MARGINCLICK: + { + if (scn->margin == 2) + { + // Click on the folder margin. Toggle the current line if possible. + int line = [editor getGeneralProperty: SCI_LINEFROMPOSITION parameter: scn->position]; + [editor setGeneralProperty: SCI_TOGGLEFOLD parameter: line value: 0]; + } + 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)) + [editor sendNotification: NSTextDidChangeNotification]; + break; + } + case SCN_ZOOM: + { + // A zoom change happend. Notify info bar if there is one. + float zoom = [editor getGeneralProperty: SCI_GETZOOM parameter: 0]; + int fontSize = [editor getGeneralProperty: SCI_STYLEGETSIZE parameter: STYLE_DEFAULT]; + float factor = (zoom / fontSize) + 1; + [editor->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 = editor->mBackend->GetCaretPosition(); + [editor->mInfoBar notify: IBNCaretChanged message: nil location: caretPosition value: 0]; + [editor sendNotification: SCIUpdateUINotification]; + break; + } + } + break; + } + case WM_COMMAND: + { + // Notifications for the editor itself. + ScintillaCocoa* backend = reinterpret_cast(lParam); + editor = backend->TopContainer(); + switch (wParam >> 16) + { + case SCEN_KILLFOCUS: + [editor sendNotification: NSTextDidEndEditingNotification]; + break; + case SCEN_SETFOCUS: // Nothing to do for now. + break; + } + break; + } + }; +} + +//-------------------------------------------------------------------------------------------------- + +/** + * Initialization of the view. Used to setup a few other things we need. + */ +- (id) initWithFrame: (NSRect) frame +{ + self = [super initWithFrame:frame]; + if (self) + { + mContent = [[[InnerView alloc] init] autorelease]; + mBackend = new ScintillaCocoa(mContent); + mContent.owner = self; + [self addSubview: mContent]; + + // 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); + mHorizontalScroller = [[[NSScroller alloc] initWithFrame: scrollerRect] autorelease]; + [mHorizontalScroller setHidden: YES]; + [mHorizontalScroller setTarget: self]; + [mHorizontalScroller setAction: @selector(scrollerAction:)]; + [self addSubview: mHorizontalScroller]; + + scrollerRect.size = NSMakeSize(10, 100); + mVerticalScroller = [[[NSScroller alloc] initWithFrame: scrollerRect] autorelease]; + [mVerticalScroller setHidden: YES]; + [mVerticalScroller setTarget: self]; + [mVerticalScroller setAction: @selector(scrollerAction:)]; + [self addSubview: mVerticalScroller]; + + // Establish a connection from the back end to this container so we can handle situations + // which require our attention. + mBackend->RegisterNotifyCallback(nil, notification); + + // Setup a special indicator used in the editor to provide visual feedback for + // input composition, depending on language, keyboard etc. + [self setColorProperty: SCI_INDICSETFORE parameter: INPUT_INDICATOR fromHTML: @"#FF9A00"]; + [self setGeneralProperty: SCI_INDICSETUNDER parameter: INPUT_INDICATOR value: 1]; + [self setGeneralProperty: SCI_INDICSETSTYLE parameter: INPUT_INDICATOR value: INDIC_ROUNDBOX]; + [self setGeneralProperty: SCI_INDICSETALPHA parameter: INPUT_INDICATOR value: 100]; + } + return self; +} + +//-------------------------------------------------------------------------------------------------- + +- (void) dealloc +{ + [mInfoBar release]; + delete mBackend; + [super dealloc]; +} + +//-------------------------------------------------------------------------------------------------- + +- (void) viewDidMoveToWindow +{ + [super viewDidMoveToWindow]; + + [self layout]; + + // Enable also mouse move events for our window (and so this view). + [[self window] setAcceptsMouseMovedEvents: YES]; +} + +//-------------------------------------------------------------------------------------------------- + +/** + * Used to position and size the parts of the editor (content, scrollers, info bar). + */ +- (void) layout +{ + int scrollerWidth = [NSScroller scrollerWidth]; + + NSSize size = [self frame].size; + NSRect hScrollerRect = {0, 0, size.width, scrollerWidth}; + NSRect vScrollerRect = {size.width - scrollerWidth, 0, scrollerWidth, size.height}; + NSRect barFrame = {0, size.height - scrollerWidth, size.width, scrollerWidth}; + BOOL infoBarVisible = mInfoBar != nil && ![mInfoBar isHidden]; + + // Horizontal offset of the content. Almost always 0 unless the vertical scroller + // is on the left side. + int contentX = 0; + + // Vertical scroller frame calculation. + if (![mVerticalScroller isHidden]) + { + // Consider user settings (left vs right vertical scrollbar). + BOOL isLeft = [[[NSUserDefaults standardUserDefaults] stringForKey: @"NSScrollerPosition"] + isEqualToString: @"left"]; + if (isLeft) + { + vScrollerRect.origin.x = 0; + hScrollerRect.origin.x = scrollerWidth; + contentX = scrollerWidth; + }; + + size.width -= scrollerWidth; + hScrollerRect.size.width -= scrollerWidth; + } + + // Same for horizontal scroller. + if (![mHorizontalScroller isHidden]) + { + // Make room for the h-scroller. + size.height -= scrollerWidth; + vScrollerRect.size.height -= scrollerWidth; + vScrollerRect.origin.y += scrollerWidth; + }; + + // Info bar frame. + if (infoBarVisible) + { + // Initial value already is as if the bar is at top. + if (mInfoBarAtTop) + { + vScrollerRect.size.height -= scrollerWidth; + size.height -= scrollerWidth; + } + else + { + // Layout info bar and h-scroller side by side in a friendly manner. + int nativeWidth = mInitialInfoBarWidth; + int remainingWidth = barFrame.size.width; + + barFrame.origin.y = 0; + + if ([mHorizontalScroller isHidden]) + { + // H-scroller is not visible, so take the full space. + vScrollerRect.origin.y += scrollerWidth; + vScrollerRect.size.height -= scrollerWidth; + size.height -= scrollerWidth; + } + else + { + // If the left offset of the h-scroller is > 0 then the v-scroller is on the left side. + // In this case we take the full width, otherwise what has been given to the h-scroller + // and content up to now. + if (hScrollerRect.origin.x == 0) + remainingWidth = size.width; + + // Note: remainingWidth can become < 0, which hides the scroller. + remainingWidth -= nativeWidth; + + hScrollerRect.origin.x = nativeWidth; + hScrollerRect.size.width = remainingWidth; + barFrame.size.width = nativeWidth; + } + } + } + + NSRect contentRect = {contentX, vScrollerRect.origin.y, size.width, size.height}; + [mContent setFrame: contentRect]; + + if (infoBarVisible) + [mInfoBar setFrame: barFrame]; + if (![mHorizontalScroller isHidden]) + [mHorizontalScroller setFrame: hScrollerRect]; + if (![mVerticalScroller isHidden]) + [mVerticalScroller setFrame: vScrollerRect]; +} + +//-------------------------------------------------------------------------------------------------- + +/** + * Called by the backend to adjust the vertical scroller (range and page). + * + * @param range Determines the total size of the scroll area used in the editor. + * @param page Determines how many pixels a page is. + * @result Returns YES if anything changed, otherwise NO. + */ +- (BOOL) setVerticalScrollRange: (int) range page: (int) page +{ + BOOL result = NO; + BOOL hideScroller = page >= range; + + if ([mVerticalScroller isHidden] != hideScroller) + { + result = YES; + [mVerticalScroller setHidden: hideScroller]; + if (!hideScroller) + [mVerticalScroller setFloatValue: 0]; + [self layout]; + } + + if (!hideScroller) + { + [mVerticalScroller setEnabled: YES]; + + CGFloat currentProportion = [mVerticalScroller knobProportion]; + CGFloat newProportion = page / (CGFloat) range; + if (currentProportion != newProportion) + { + result = YES; + [mVerticalScroller setKnobProportion: newProportion]; + } + } + + return result; +} + +//-------------------------------------------------------------------------------------------------- + +/** + * Used to set the position of the vertical scroll thumb. + * + * @param position The relative position in the rang [0..1]; + */ +- (void) setVerticalScrollPosition: (float) position +{ + [mVerticalScroller setFloatValue: position]; +} + +//-------------------------------------------------------------------------------------------------- + +/** + * Called by the backend to adjust the horizontal scroller (range and page). + * + * @param range Determines the total size of the scroll area used in the editor. + * @param page Determines how many pixels a page is. + * @result Returns YES if anything changed, otherwise NO. + */ +- (BOOL) setHorizontalScrollRange: (int) range page: (int) page +{ + BOOL result = NO; + BOOL hideScroller = page >= range; + + if ([mHorizontalScroller isHidden] != hideScroller) + { + result = YES; + [mHorizontalScroller setHidden: hideScroller]; + [self layout]; + } + + if (!hideScroller) + { + [mHorizontalScroller setEnabled: YES]; + + CGFloat currentProportion = [mHorizontalScroller knobProportion]; + CGFloat newProportion = page / (CGFloat) range; + if (currentProportion != newProportion) + { + result = YES; + [mHorizontalScroller setKnobProportion: newProportion]; + } + } + + return result; +} + +//-------------------------------------------------------------------------------------------------- + +/** + * Used to set the position of the vertical scroll thumb. + * + * @param position The relative position in the rang [0..1]; + */ +- (void) setHorizontalScrollPosition: (float) position +{ + [mHorizontalScroller setFloatValue: position]; +} + +//-------------------------------------------------------------------------------------------------- + +/** + * Triggered by one of the scrollers when it gets manipulated by the user. Notify the backend + * about the change. + */ +- (void) scrollerAction: (id) sender +{ + float position = [sender floatValue]; + mBackend->DoScroll(position, [sender hitPart], sender == mHorizontalScroller); +} + +//-------------------------------------------------------------------------------------------------- + +/** + * Used to reposition our content depending on the size of the view. + */ +- (void) setFrame: (NSRect) newFrame +{ + [super setFrame: newFrame]; + [self layout]; +} + +//-------------------------------------------------------------------------------------------------- + +/** + * 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 = @""; + + char *buffer(0); + const int length = mBackend->WndProc(SCI_GETSELTEXT, 0, 0); + if (length > 0) + { + buffer = new char[length + 1]; + try + { + mBackend->WndProc(SCI_GETSELTEXT, length + 1, (sptr_t) buffer); + mBackend->WndProc(SCI_SETSAVEPOINT, 0, 0); + + result = [NSString stringWithUTF8String: buffer]; + delete[] buffer; + } + catch (...) + { + delete[] buffer; + buffer = 0; + } + } + + return result; +} + +//-------------------------------------------------------------------------------------------------- + +/** + * 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 = @""; + + char *buffer(0); + const int length = mBackend->WndProc(SCI_GETLENGTH, 0, 0); + if (length > 0) + { + buffer = new char[length + 1]; + try + { + mBackend->WndProc(SCI_GETTEXT, length + 1, (sptr_t) buffer); + mBackend->WndProc(SCI_SETSAVEPOINT, 0, 0); + + result = [NSString stringWithUTF8String: buffer]; + delete[] buffer; + } + catch (...) + { + delete[] buffer; + buffer = 0; + } + } + + return result; +} + +//-------------------------------------------------------------------------------------------------- + +/** + * 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) 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); +} + +//-------------------------------------------------------------------------------------------------- + +- (BOOL) isEditable +{ + return mBackend->WndProc(SCI_GETREADONLY, 0, 0) != 0; +} + +//-------------------------------------------------------------------------------------------------- + +- (InnerView*) content +{ + return mContent; +} + +//-------------------------------------------------------------------------------------------------- + +/** + * Direct call into the backend to allow uninterpreted access to it. The values to be passed in and + * 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(sender->mBackend, message, wParam, lParam); +} + +//-------------------------------------------------------------------------------------------------- + +/** + * This is a helper method to set properties in the backend, with native parameters. + * + * @param property Main property like SCI_STYLESETFORE for which a value is to be set. + * @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); +} + +//-------------------------------------------------------------------------------------------------- + +/** + * This is a helper method to get a property in the backend, with native parameters. + * + * @param property Main property like SCI_STYLESETFORE for which a value is to get. + * @param parameter Additional info for this property like a parameter or index. + * @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); +} + +//-------------------------------------------------------------------------------------------------- + +/** + * Convenience function to avoid unneeded extra parameter. + */ +- (long) getGeneralProperty: (int) property parameter: (long) parameter +{ + return mBackend->WndProc(property, parameter, 0); +} + +//-------------------------------------------------------------------------------------------------- + +/** + * Convenience function to avoid unneeded parameters. + */ +- (long) getGeneralProperty: (int) property +{ + return mBackend->WndProc(property, 0, 0); +} + +//-------------------------------------------------------------------------------------------------- + +/** + * 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); +} + +//-------------------------------------------------------------------------------------------------- + +/** + * 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 = [value redComponent] * 255; + long green = [value greenComponent] * 255; + long blue = [value blueComponent] * 255; + + long color = (blue << 16) + (green << 8) + red; + mBackend->WndProc(property, parameter, color); +} + +//-------------------------------------------------------------------------------------------------- + +/** + * 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] = [fromHTML characterAtIndex: index++]; + if (longVersion) + value[1] = [fromHTML characterAtIndex: index++]; + else + value[1] = value[0]; + + unsigned rawRed; + [[NSScanner scannerWithString: [NSString stringWithUTF8String: value]] scanHexInt: &rawRed]; + + value[0] = [fromHTML characterAtIndex: index++]; + if (longVersion) + value[1] = [fromHTML characterAtIndex: index++]; + else + value[1] = value[0]; + + unsigned rawGreen; + [[NSScanner scannerWithString: [NSString stringWithUTF8String: value]] scanHexInt: &rawGreen]; + + value[0] = [fromHTML characterAtIndex: index++]; + if (longVersion) + value[1] = [fromHTML characterAtIndex: index++]; + else + value[1] = value[0]; + + unsigned rawBlue; + [[NSScanner scannerWithString: [NSString stringWithUTF8String: value]] scanHexInt: &rawBlue]; + + long color = (rawBlue << 16) + (rawGreen << 8) + rawRed; + mBackend->WndProc(property, parameter, color); + } +} + +//-------------------------------------------------------------------------------------------------- + +/** + * Specialized property getter for colors. + */ +- (NSColor*) getColorProperty: (int) property parameter: (long) parameter +{ + int color = mBackend->WndProc(property, parameter, 0); + float red = (color & 0xFF) / 255.0; + float green = ((color >> 8) & 0xFF) / 255.0; + float blue = ((color >> 16) & 0xFF) / 255.0; + NSColor* result = [NSColor colorWithDeviceRed: red green: green blue: blue alpha: 1]; + return result; +} + +//-------------------------------------------------------------------------------------------------- + +/** + * 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); +} + +//-------------------------------------------------------------------------------------------------- + +/** + * Specialized property getter for references (pointers, addresses). + */ +- (const void*) getReferenceProperty: (int) property parameter: (long) parameter +{ + return (const void*) mBackend->WndProc(property, parameter, 0); +} + +//-------------------------------------------------------------------------------------------------- + +/** + * 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); +} + + +//-------------------------------------------------------------------------------------------------- + +/** + * Specialized property getter for string values. + */ +- (NSString*) getStringProperty: (int) property parameter: (long) parameter +{ + const char* rawValue = (const char*) mBackend->WndProc(property, parameter, 0); + return [NSString stringWithUTF8String: rawValue]; +} + +//-------------------------------------------------------------------------------------------------- + +/** + * 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); +} + +//-------------------------------------------------------------------------------------------------- + +/** + * 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 [NSString stringWithUTF8String: result]; +} + +//-------------------------------------------------------------------------------------------------- + +/** + * Sets the new control which is displayed as info bar at the top or bottom of the editor. + * Set newBar to nil if you want to hide the bar again. + * When aligned to bottom position then the info bar and the horizontal scroller share the available + * space. The info bar will then only get the width it is currently set to less a minimal amount + * reserved for the scroller. At the top position it gets the full width of the control. + * The info bar's height is set to the height of the scrollbar. + */ +- (void) setInfoBar: (NSView *) newBar top: (BOOL) top +{ + if (mInfoBar != newBar) + { + [mInfoBar removeFromSuperview]; + + mInfoBar = newBar; + mInfoBarAtTop = top; + if (mInfoBar != nil) + { + [self addSubview: mInfoBar]; + [mInfoBar setCallback: self]; + + // Keep the initial width as reference for layout changes. + mInitialInfoBarWidth = [mInfoBar frame].size.width; + } + + [self layout]; + } +} + +//-------------------------------------------------------------------------------------------------- + +/** + * 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]; +} + +- (NSRange) selectedRange +{ + return [mContent selectedRange]; +} + +- (void)insertText: (NSString*)text +{ + [mContent insertText: text]; +} + +@end + +//-------------------------------------------------------------------------------------------------- + diff --git a/scintilla/cocoa/res/info_bar_bg.png b/scintilla/cocoa/res/info_bar_bg.png new file mode 100644 index 00000000..79010fa7 Binary files /dev/null and b/scintilla/cocoa/res/info_bar_bg.png differ diff --git a/scintilla/cocoa/res/mac_cursor_busy.png b/scintilla/cocoa/res/mac_cursor_busy.png new file mode 100644 index 00000000..9ac82769 Binary files /dev/null and b/scintilla/cocoa/res/mac_cursor_busy.png differ diff --git a/scintilla/cocoa/res/mac_cursor_flipped.png b/scintilla/cocoa/res/mac_cursor_flipped.png new file mode 100644 index 00000000..2c984f24 Binary files /dev/null and b/scintilla/cocoa/res/mac_cursor_flipped.png differ diff --git a/scintilla/doc/annotations.png b/scintilla/doc/annotations.png new file mode 100644 index 00000000..9d9b2470 Binary files /dev/null and b/scintilla/doc/annotations.png differ diff --git a/scintilla/doc/styledmargin.png b/scintilla/doc/styledmargin.png new file mode 100644 index 00000000..3aaf35b0 Binary files /dev/null and b/scintilla/doc/styledmargin.png differ diff --git a/scintilla/gtk/scintilla.mak b/scintilla/gtk/scintilla.mak deleted file mode 100644 index 9ab9e191..00000000 --- a/scintilla/gtk/scintilla.mak +++ /dev/null @@ -1,611 +0,0 @@ -# Make file for GTK+/Scintilla on Windows Visual C++ -# Borland C++ does not work -# Copyright 1998-2000 by Neil Hodgson -# The License.txt file describes the conditions under which this software may be distributed. -# This makefile is for using Visual C++ with nmake or Borland C++ with make depending on -# the setting of the VENDOR macro. If no VENDOR is defined n the command line then -# the tool used is automatically detected. -# Usage for Microsoft: -# nmake -f scintilla.mak -# Usage for Borland: -# make -f scintilla.mak -# For debug versions define DEBUG on the command line, for Borland: -# make DEBUG=1 -f scintilla.mak -# The main makefile uses mingw32 gcc and may be more current than this file. - -.SUFFIXES: .cxx - -DIR_O=. -DIR_BIN=..\bin - -COMPONENT=$(DIR_BIN)\Scintilla.dll -LEXCOMPONENT=$(DIR_BIN)\SciLexer.dll -STATIC_LIB=$(DIR_BIN)\Scintilla-static.lib - -!IFNDEF VENDOR -!IFDEF _NMAKE_VER -#Microsoft nmake so make default VENDOR MICROSOFT -VENDOR=MICROSOFT -!ELSE -VENDOR=BORLAND -!ENDIF -!ENDIF - -!IF "$(VENDOR)"=="MICROSOFT" - -CC=cl -RC=rc -LD=link - -!IFDEF USE_GTK2 -MARSHALLER=$(DIR_O)\scintilla-marshal.obj -GTK_TOP= ../../gtk2 -TOP = $(GTK_TOP) -!INCLUDE $(TOP)/glib/build/win32/make.msc - -GTK_INCLUDES= -I$(GTK_TOP)/gtk+ \ - -I$(GTK_TOP)/gtk+/gdk \ - -I$(GTK_TOP)/glib/glib \ - -I$(GTK_TOP)/glib/gmodule \ - -I$(GTK_TOP)/glib \ - -I$(GTK_TOP)\libiconv\include \ - -I$(GTK_TOP)\pango \ - -I$(GTK_TOP)\atk -ALL_GTK_LIBS=$(GTK2_LIBS) $(GLIB_LIBS) $(LIBICONV_LIBS) -!ELSE -GTK_TOP= ../../win32gtk -GTK_INCLUDES= -I $(GTK_TOP)/gtk+ -I $(GTK_TOP)/gtk+/gdk -I $(GTK_TOP)/glib -I $(GTK_TOP)/glib/gmodule -ALL_GTK_LIBS=$(GTK_TOP)/gtk+/gtk/gtk-1.3.lib \ - $(GTK_TOP)/gtk+/gdk/gdk-1.3.lib \ - $(GTK_TOP)/glib/gmodule/gmodule-1.3.lib \ - $(GTK_TOP)/glib/glib-1.3.lib -!ENDIF - -INCLUDEDIRS=-I ../include -I ../src $(GTK_INCLUDES) -CXXFLAGS=/TP /W4 -EHsc -DGTK -D_CRT_SECURE_NO_DEPRECATE=1 -CFLAGS=/W4 -DGTK -# For something scary:/Wp64 -CXXDEBUG=/Zi /Od /MDd -DDEBUG -CXXNDEBUG=/Ox /MD -DNDEBUG -NAMEFLAG=-Fo -LDFLAGS=/opt:nowin98 -LDDEBUG=/DEBUG -#LIBS=KERNEL32.lib USER32.lib GDI32.lib IMM32.lib OLE32.LIB -LIBS=$(ALL_GTK_LIBS) - -!IFDEF QUIET -CC=@$(CC) -CXXDEBUG=$(CXXDEBUG) /nologo -CXXNDEBUG=$(CXXNDEBUG) /nologo -LDFLAGS=$(LDFLAGS) /nologo -!ENDIF - -!ELSE -# BORLAND -!error Borland C++ not supported - -CC=bcc32 -RC=brcc32 -r -LD=ilink32 - -INCLUDEDIRS=-I../include -I../src -CXXFLAGS = -v -CXXFLAGS=-P -tWM -w -w-prc -w-inl -RT- -x -# Above turns off warnings for clarfying parentheses and inlines with for not expanded -CXXDEBUG=-v -DDEBUG -CXXNDEBUG=-O1 -DNDEBUG -NAMEFLAG=-o -LDFLAGS= -LDDEBUG=-v -LIBS=import32 cw32mt - -!ENDIF - -!IFDEF DEBUG -CXXFLAGS=$(CXXFLAGS) $(CXXDEBUG) -LDFLAGS=$(LDDEBUG) $(LDFLAGS) -!ELSE -CXXFLAGS=$(CXXFLAGS) $(CXXNDEBUG) -!ENDIF - -#ALL: $(STATIC_LIB) $(COMPONENT) $(LEXCOMPONENT) $(DIR_O)\ScintillaGTKS.obj $(DIR_O)\WindowAccessor.obj -ALL: $(STATIC_LIB) $(DIR_O)\ScintillaGTKS.obj $(DIR_O)\WindowAccessor.obj - -clean:: - -del /q $(DIR_O)\*.obj $(DIR_O)\*.pdb $(COMPONENT) $(LEXCOMPONENT) $(DIR_O)\*.res $(DIR_BIN)\*.map - -SOBJS=\ - $(DIR_O)\AutoComplete.obj \ - $(DIR_O)\CallTip.obj \ - $(DIR_O)\CellBuffer.obj \ - $(DIR_O)\ContractionState.obj \ - $(DIR_O)\CharClassify.obj \ - $(DIR_O)\Decoration.obj \ - $(DIR_O)\Document.obj \ - $(DIR_O)\Editor.obj \ - $(DIR_O)\ExternalLexer.obj \ - $(DIR_O)\Indicator.obj \ - $(DIR_O)\KeyMap.obj \ - $(DIR_O)\LineMarker.obj \ - $(DIR_O)\PlatGTK.obj \ - $(DIR_O)\PositionCache.obj \ - $(MARSHALLER) \ - $(DIR_O)\RESearch.obj \ - $(DIR_O)\RunStyles.obj \ - $(DIR_O)\PropSet.obj \ - $(DIR_O)\ScintillaBase.obj \ - $(DIR_O)\ScintillaGTK.obj \ - $(DIR_O)\Selection.obj \ - $(DIR_O)\Style.obj \ - $(DIR_O)\UniConversion.obj \ - $(DIR_O)\ViewStyle.obj \ - $(DIR_O)\XPM.obj - -#++Autogenerated -- run src/LexGen.py to regenerate -#**LEXOBJS=\\\n\(\t$(DIR_O)\\\*.obj \\\n\) -LEXOBJS=\ - $(DIR_O)\LexAbaqus.obj \ - $(DIR_O)\LexAda.obj \ - $(DIR_O)\LexAPDL.obj \ - $(DIR_O)\LexAsm.obj \ - $(DIR_O)\LexAsn1.obj \ - $(DIR_O)\LexASY.obj \ - $(DIR_O)\LexAU3.obj \ - $(DIR_O)\LexAVE.obj \ - $(DIR_O)\LexBaan.obj \ - $(DIR_O)\LexBash.obj \ - $(DIR_O)\LexBasic.obj \ - $(DIR_O)\LexBullant.obj \ - $(DIR_O)\LexCaml.obj \ - $(DIR_O)\LexCLW.obj \ - $(DIR_O)\LexCmake.obj \ - $(DIR_O)\LexCOBOL.obj \ - $(DIR_O)\LexConf.obj \ - $(DIR_O)\LexCPP.obj \ - $(DIR_O)\LexCrontab.obj \ - $(DIR_O)\LexCsound.obj \ - $(DIR_O)\LexCSS.obj \ - $(DIR_O)\LexD.obj \ - $(DIR_O)\LexEiffel.obj \ - $(DIR_O)\LexErlang.obj \ - $(DIR_O)\LexEScript.obj \ - $(DIR_O)\LexFlagship.obj \ - $(DIR_O)\LexForth.obj \ - $(DIR_O)\LexFortran.obj \ - $(DIR_O)\LexGAP.obj \ - $(DIR_O)\LexGui4Cli.obj \ - $(DIR_O)\LexHaskell.obj \ - $(DIR_O)\LexHTML.obj \ - $(DIR_O)\LexInno.obj \ - $(DIR_O)\LexKix.obj \ - $(DIR_O)\LexLisp.obj \ - $(DIR_O)\LexLout.obj \ - $(DIR_O)\LexLua.obj \ - $(DIR_O)\LexMagik.obj \ - $(DIR_O)\LexMatlab.obj \ - $(DIR_O)\LexMetapost.obj \ - $(DIR_O)\LexMMIXAL.obj \ - $(DIR_O)\LexMPT.obj \ - $(DIR_O)\LexMSSQL.obj \ - $(DIR_O)\LexMySQL.obj \ - $(DIR_O)\LexNimrod.obj \ - $(DIR_O)\LexNsis.obj \ - $(DIR_O)\LexOpal.obj \ - $(DIR_O)\LexOthers.obj \ - $(DIR_O)\LexPascal.obj \ - $(DIR_O)\LexPB.obj \ - $(DIR_O)\LexPerl.obj \ - $(DIR_O)\LexPLM.obj \ - $(DIR_O)\LexPOV.obj \ - $(DIR_O)\LexPowerPro.obj \ - $(DIR_O)\LexPowerShell.obj \ - $(DIR_O)\LexProgress.obj \ - $(DIR_O)\LexPS.obj \ - $(DIR_O)\LexPython.obj \ - $(DIR_O)\LexR.obj \ - $(DIR_O)\LexRebol.obj \ - $(DIR_O)\LexRuby.obj \ - $(DIR_O)\LexScriptol.obj \ - $(DIR_O)\LexSmalltalk.obj \ - $(DIR_O)\LexSML.obj \ - $(DIR_O)\LexSorcus.obj \ - $(DIR_O)\LexSpecman.obj \ - $(DIR_O)\LexSpice.obj \ - $(DIR_O)\LexSQL.obj \ - $(DIR_O)\LexTACL.obj \ - $(DIR_O)\LexTADS3.obj \ - $(DIR_O)\LexTAL.obj \ - $(DIR_O)\LexTCL.obj \ - $(DIR_O)\LexTeX.obj \ - $(DIR_O)\LexVB.obj \ - $(DIR_O)\LexVerilog.obj \ - $(DIR_O)\LexVHDL.obj \ - $(DIR_O)\LexYAML.obj \ - -#--Autogenerated -- end of automatically generated section - -LOBJS=\ - $(DIR_O)\AutoComplete.obj \ - $(DIR_O)\CallTip.obj \ - $(DIR_O)\CellBuffer.obj \ - $(DIR_O)\ContractionState.obj \ - $(DIR_O)\CharClassify.obj \ - $(DIR_O)\Decoration.obj \ - $(DIR_O)\Document.obj \ - $(DIR_O)\DocumentAccessor.obj \ - $(DIR_O)\Editor.obj \ - $(DIR_O)\Indicator.obj \ - $(DIR_O)\KeyMap.obj \ - $(DIR_O)\KeyWords.obj \ - $(DIR_O)\LineMarker.obj \ - $(DIR_O)\PlatGTK.obj \ - $(DIR_O)\PositionCache.obj \ - $(MARSHALLER) \ - $(DIR_O)\RESearch.obj \ - $(DIR_O)\RunStyles.obj \ - $(DIR_O)\PropSet.obj \ - $(DIR_O)\ScintillaBaseL.obj \ - $(DIR_O)\ScintillaGTKL.obj \ - $(DIR_O)\Selection.obj \ - $(DIR_O)\Style.obj \ - $(DIR_O)\StyleContext.obj \ - $(DIR_O)\UniConversion.obj \ - $(DIR_O)\ViewStyle.obj \ - $(DIR_O)\XPM.obj \ - $(DIR_O)\ExternalLexer.obj \ - $(LEXOBJS) - -!IF "$(VENDOR)"=="MICROSOFT" - -$(STATIC_LIB): $(LOBJS) #$(DIR_O)\ScintRes.res - lib.exe /OUT:$@ $(LOBJS) $(LIBS) - -$(COMPONENT): $(SOBJS) #$(DIR_O)\ScintRes.res - $(LD) $(LDFLAGS) /DLL /OUT:$@ $(SOBJS) $(LIBS) - -$(DIR_O)\ScintRes.res : ScintRes.rc - $(RC) /fo$@ $(*B).rc - -$(LEXCOMPONENT): $(LOBJS) #$(DIR_O)\ScintRes.res - $(LD) $(LDFLAGS) /DLL /OUT:$@ $(LOBJS) $(LIBS) - -!ELSE - -$(STATIC_LIB): $(LOBJS) #$(DIR_O)\ScintRes.res - $(LD) /OUT:$@ $(LOBJS) $(LIBS) - -$(COMPONENT): $(SOBJS) ScintRes.res - $(LD) $(LDFLAGS) -Tpd -c c0d32 $(SOBJS), $@, , $(LIBS), , ScintRes.res - -$(DIR_O)\ScintRes.res: ScintRes.rc - $(RC) $*.rc - -$(LEXCOMPONENT): $(LOBJS) - $(LD) $(LDFLAGS) -Tpd -c c0d32 $(LOBJS), $@, , $(LIBS), , ScintRes.res - -!ENDIF - -# Define how to build all the objects and what they depend on - -# Most of the source is in ..\src with a couple in this directory -{..\src}.cxx{$(DIR_O)}.obj: - $(CC) $(INCLUDEDIRS) $(CXXFLAGS) -c $(NAMEFLAG)$@ $< -{.}.cxx{$(DIR_O)}.obj: - $(CC) $(INCLUDEDIRS) $(CXXFLAGS) -c $(NAMEFLAG)$@ $< -{.}.c{$(DIR_O)}.obj: - $(CC) $(INCLUDEDIRS) $(CFLAGS) -c $(NAMEFLAG)$@ $< - -# Some source files are compiled into more than one object because of different conditional compilation -$(DIR_O)\ScintillaBaseL.obj: ..\src\ScintillaBase.cxx - $(CC) $(INCLUDEDIRS) $(CXXFLAGS) -DSCI_LEXER -c $(NAMEFLAG)$@ ..\src\ScintillaBase.cxx - -$(DIR_O)\ScintillaGTKL.obj: ScintillaGTK.cxx - $(CC) $(INCLUDEDIRS) $(CXXFLAGS) -DSCI_LEXER -c $(NAMEFLAG)$@ ScintillaGTK.cxx - -$(DIR_O)\ScintillaGTKS.obj: ScintillaGTK.cxx - $(CC) $(INCLUDEDIRS) $(CXXFLAGS) -DSTATIC_BUILD -c $(NAMEFLAG)$@ ScintillaGTK.cxx - -# Dependencies - -# All lexers depend on this set of headers -LEX_HEADERS=..\include\Platform.h ..\include\PropSet.h \ - ..\include\Accessor.h ..\include\KeyWords.h \ - ..\include\Scintilla.h ..\include\SciLexer.h ..\src\StyleContext.h - -$(DIR_O)\AutoComplete.obj: ../src/AutoComplete.cxx ../include/Platform.h \ - ../include/PropSet.h ../src/AutoComplete.h - -$(DIR_O)\CallTip.obj: ../src/CallTip.cxx ../include/Platform.h \ - ../include/Scintilla.h ../src/CallTip.h - -$(DIR_O)\CellBuffer.obj: ../src/CellBuffer.cxx ../include/Platform.h \ - ../include/Scintilla.h ../src/SVector.h ../src/SplitVector.h \ - ../src/Partitioning.h ../src/CellBuffer.h - -$(DIR_O)\CharClassify.obj: ../src/CharClassify.cxx ../src/CharClassify.h - -$(DIR_O)\ContractionState.obj: ../src/ContractionState.cxx ../include/Platform.h \ - ../src/ContractionState.h - -$(DIR_O)\Document.obj: ../src/Document.cxx ../include/Platform.h \ - ../include/Scintilla.h ../src/SVector.h ../src/SplitVector.h \ - ../src/Partitioning.h ../src/CellBuffer.h ../src/CharClassify.h \ - ../src/Document.h ../src/RESearch.h - -$(DIR_O)\DocumentAccessor.obj: ../src/DocumentAccessor.cxx ../include/Platform.h \ - ../include/PropSet.h ../src/SVector.h \ - ../include/Accessor.h ../src/DocumentAccessor.h ../src/SplitVector.h \ - ../src/Partitioning.h ../src/CellBuffer.h ../include/Scintilla.h \ - ../src/CharClassify.h ../src/Document.h - -$(DIR_O)\Editor.obj: ../src/Editor.cxx ../include/Platform.h ../include/Scintilla.h \ - ../src/ContractionState.h ../src/SVector.h ../src/SplitVector.h \ - ../src/Partitioning.h ../src/CellBuffer.h ../src/KeyMap.h \ - ../src/RunStyles.h ../src/Indicator.h ../src/XPM.h ../src/LineMarker.h \ - ../src/Style.h ../src/ViewStyle.h ../src/CharClassify.h \ - ../src/Document.h ../src/Editor.h ../src/Selection.h ../src/PositionCache.h - -$(DIR_O)\ExternalLexer.obj: ../src/ExternalLexer.cxx ../include/Platform.h \ - ../include/Scintilla.h ../include/SciLexer.h ../include/PropSet.h \ - ../include/Accessor.h ../src/DocumentAccessor.h \ - ../include/KeyWords.h ../src/ExternalLexer.h - -$(DIR_O)\Indicator.obj: ../src/Indicator.cxx ../include/Platform.h \ - ../include/Scintilla.h ../src/SplitVector.h ../src/Partitioning.h \ - ../src/RunStyles.h ../src/Indicator.h - -$(DIR_O)\KeyMap.obj: ../src/KeyMap.cxx ../include/Platform.h ../include/Scintilla.h \ - ../src/KeyMap.h - -$(DIR_O)\KeyWords.obj: ../src/KeyWords.cxx ../include/Platform.h \ - ../include/PropSet.h ../include/Accessor.h \ - ../include/KeyWords.h ../include/Scintilla.h ../include/SciLexer.h - -#++Autogenerated -- run src/LexGen.py to regenerate -#**\n\($(DIR_O)\\\*.obj: ..\\src\\\*.cxx $(LEX_HEADERS)\n\n\) - -$(DIR_O)\LexAbaqus.obj: ..\src\LexAbaqus.cxx $(LEX_HEADERS) - -$(DIR_O)\LexAda.obj: ..\src\LexAda.cxx $(LEX_HEADERS) - -$(DIR_O)\LexAPDL.obj: ..\src\LexAPDL.cxx $(LEX_HEADERS) - -$(DIR_O)\LexAsm.obj: ..\src\LexAsm.cxx $(LEX_HEADERS) - -$(DIR_O)\LexAsn1.obj: ..\src\LexAsn1.cxx $(LEX_HEADERS) - -$(DIR_O)\LexASY.obj: ..\src\LexASY.cxx $(LEX_HEADERS) - -$(DIR_O)\LexAU3.obj: ..\src\LexAU3.cxx $(LEX_HEADERS) - -$(DIR_O)\LexAVE.obj: ..\src\LexAVE.cxx $(LEX_HEADERS) - -$(DIR_O)\LexBaan.obj: ..\src\LexBaan.cxx $(LEX_HEADERS) - -$(DIR_O)\LexBash.obj: ..\src\LexBash.cxx $(LEX_HEADERS) - -$(DIR_O)\LexBasic.obj: ..\src\LexBasic.cxx $(LEX_HEADERS) - -$(DIR_O)\LexBullant.obj: ..\src\LexBullant.cxx $(LEX_HEADERS) - -$(DIR_O)\LexCaml.obj: ..\src\LexCaml.cxx $(LEX_HEADERS) - -$(DIR_O)\LexCLW.obj: ..\src\LexCLW.cxx $(LEX_HEADERS) - -$(DIR_O)\LexCmake.obj: ..\src\LexCmake.cxx $(LEX_HEADERS) - -$(DIR_O)\LexCOBOL.obj: ..\src\LexCOBOL.cxx $(LEX_HEADERS) - -$(DIR_O)\LexConf.obj: ..\src\LexConf.cxx $(LEX_HEADERS) - -$(DIR_O)\LexCPP.obj: ..\src\LexCPP.cxx $(LEX_HEADERS) - -$(DIR_O)\LexCrontab.obj: ..\src\LexCrontab.cxx $(LEX_HEADERS) - -$(DIR_O)\LexCsound.obj: ..\src\LexCsound.cxx $(LEX_HEADERS) - -$(DIR_O)\LexCSS.obj: ..\src\LexCSS.cxx $(LEX_HEADERS) - -$(DIR_O)\LexD.obj: ..\src\LexD.cxx $(LEX_HEADERS) - -$(DIR_O)\LexEiffel.obj: ..\src\LexEiffel.cxx $(LEX_HEADERS) - -$(DIR_O)\LexErlang.obj: ..\src\LexErlang.cxx $(LEX_HEADERS) - -$(DIR_O)\LexEScript.obj: ..\src\LexEScript.cxx $(LEX_HEADERS) - -$(DIR_O)\LexFlagship.obj: ..\src\LexFlagship.cxx $(LEX_HEADERS) - -$(DIR_O)\LexForth.obj: ..\src\LexForth.cxx $(LEX_HEADERS) - -$(DIR_O)\LexFortran.obj: ..\src\LexFortran.cxx $(LEX_HEADERS) - -$(DIR_O)\LexGAP.obj: ..\src\LexGAP.cxx $(LEX_HEADERS) - -$(DIR_O)\LexGui4Cli.obj: ..\src\LexGui4Cli.cxx $(LEX_HEADERS) - -$(DIR_O)\LexHaskell.obj: ..\src\LexHaskell.cxx $(LEX_HEADERS) - -$(DIR_O)\LexHTML.obj: ..\src\LexHTML.cxx $(LEX_HEADERS) - -$(DIR_O)\LexInno.obj: ..\src\LexInno.cxx $(LEX_HEADERS) - -$(DIR_O)\LexKix.obj: ..\src\LexKix.cxx $(LEX_HEADERS) - -$(DIR_O)\LexLisp.obj: ..\src\LexLisp.cxx $(LEX_HEADERS) - -$(DIR_O)\LexLout.obj: ..\src\LexLout.cxx $(LEX_HEADERS) - -$(DIR_O)\LexLua.obj: ..\src\LexLua.cxx $(LEX_HEADERS) - -$(DIR_O)\LexMagik.obj: ..\src\LexMagik.cxx $(LEX_HEADERS) - -$(DIR_O)\LexMatlab.obj: ..\src\LexMatlab.cxx $(LEX_HEADERS) - -$(DIR_O)\LexMetapost.obj: ..\src\LexMetapost.cxx $(LEX_HEADERS) - -$(DIR_O)\LexMMIXAL.obj: ..\src\LexMMIXAL.cxx $(LEX_HEADERS) - -$(DIR_O)\LexMPT.obj: ..\src\LexMPT.cxx $(LEX_HEADERS) - -$(DIR_O)\LexMSSQL.obj: ..\src\LexMSSQL.cxx $(LEX_HEADERS) - -$(DIR_O)\LexMySQL.obj: ..\src\LexMySQL.cxx $(LEX_HEADERS) - -$(DIR_O)\LexNimrod.obj: ..\src\LexNimrod.cxx $(LEX_HEADERS) - -$(DIR_O)\LexNsis.obj: ..\src\LexNsis.cxx $(LEX_HEADERS) - -$(DIR_O)\LexOpal.obj: ..\src\LexOpal.cxx $(LEX_HEADERS) - -$(DIR_O)\LexOthers.obj: ..\src\LexOthers.cxx $(LEX_HEADERS) - -$(DIR_O)\LexPascal.obj: ..\src\LexPascal.cxx $(LEX_HEADERS) - -$(DIR_O)\LexPB.obj: ..\src\LexPB.cxx $(LEX_HEADERS) - -$(DIR_O)\LexPerl.obj: ..\src\LexPerl.cxx $(LEX_HEADERS) - -$(DIR_O)\LexPLM.obj: ..\src\LexPLM.cxx $(LEX_HEADERS) - -$(DIR_O)\LexPOV.obj: ..\src\LexPOV.cxx $(LEX_HEADERS) - -$(DIR_O)\LexPowerPro.obj: ..\src\LexPowerPro.cxx $(LEX_HEADERS) - -$(DIR_O)\LexPowerShell.obj: ..\src\LexPowerShell.cxx $(LEX_HEADERS) - -$(DIR_O)\LexProgress.obj: ..\src\LexProgress.cxx $(LEX_HEADERS) - -$(DIR_O)\LexPS.obj: ..\src\LexPS.cxx $(LEX_HEADERS) - -$(DIR_O)\LexPython.obj: ..\src\LexPython.cxx $(LEX_HEADERS) - -$(DIR_O)\LexR.obj: ..\src\LexR.cxx $(LEX_HEADERS) - -$(DIR_O)\LexRebol.obj: ..\src\LexRebol.cxx $(LEX_HEADERS) - -$(DIR_O)\LexRuby.obj: ..\src\LexRuby.cxx $(LEX_HEADERS) - -$(DIR_O)\LexScriptol.obj: ..\src\LexScriptol.cxx $(LEX_HEADERS) - -$(DIR_O)\LexSmalltalk.obj: ..\src\LexSmalltalk.cxx $(LEX_HEADERS) - -$(DIR_O)\LexSML.obj: ..\src\LexSML.cxx $(LEX_HEADERS) - -$(DIR_O)\LexSorcus.obj: ..\src\LexSorcus.cxx $(LEX_HEADERS) - -$(DIR_O)\LexSpecman.obj: ..\src\LexSpecman.cxx $(LEX_HEADERS) - -$(DIR_O)\LexSpice.obj: ..\src\LexSpice.cxx $(LEX_HEADERS) - -$(DIR_O)\LexSQL.obj: ..\src\LexSQL.cxx $(LEX_HEADERS) - -$(DIR_O)\LexTACL.obj: ..\src\LexTACL.cxx $(LEX_HEADERS) - -$(DIR_O)\LexTADS3.obj: ..\src\LexTADS3.cxx $(LEX_HEADERS) - -$(DIR_O)\LexTAL.obj: ..\src\LexTAL.cxx $(LEX_HEADERS) - -$(DIR_O)\LexTCL.obj: ..\src\LexTCL.cxx $(LEX_HEADERS) - -$(DIR_O)\LexTeX.obj: ..\src\LexTeX.cxx $(LEX_HEADERS) - -$(DIR_O)\LexVB.obj: ..\src\LexVB.cxx $(LEX_HEADERS) - -$(DIR_O)\LexVerilog.obj: ..\src\LexVerilog.cxx $(LEX_HEADERS) - -$(DIR_O)\LexVHDL.obj: ..\src\LexVHDL.cxx $(LEX_HEADERS) - -$(DIR_O)\LexYAML.obj: ..\src\LexYAML.cxx $(LEX_HEADERS) - - -#--Autogenerated -- end of automatically generated section - -$(DIR_O)\LineMarker.obj: ../src/LineMarker.cxx ../include/Platform.h \ - ../include/Scintilla.h ../src/XPM.h ../src/LineMarker.h - -$(DIR_O)\PlatGTK.obj: PlatGTK.cxx ../include/Platform.h \ - ../src/UniConversion.h ../src/XPM.h - -$(DIR_O)\PositionCache.obj: ../src/Editor.cxx ../include/Platform.h ../include/Scintilla.h \ - ../src/ContractionState.h ../src/SVector.h ../src/SplitVector.h \ - ../src/Partitioning.h ../src/CellBuffer.h ../src/KeyMap.h \ - ../src/RunStyles.h ../src/Indicator.h ../src/XPM.h ../src/LineMarker.h \ - ../src/Style.h ../src/ViewStyle.h ../src/CharClassify.h \ - ../src/Decoration.h ../src/Document.h ../src/Editor.h ../src/Selection.h ../src/PositionCache.h - -$(DIR_O)\PropSet.obj: ../src/PropSet.cxx ../include/Platform.h ../include/PropSet.h - -$(DIR_O)\RESearch.obj: ../src/RESearch.cxx ../src/CharClassify.h ../src/RESearch.h - -$(DIR_O)\RunStyles.obj: ../src/RunStyles.cxx ../include/Platform.h \ - ../include/Scintilla.h ../src/SplitVector.h ../src/Partitioning.h \ - ../src/RunStyles.h - -$(DIR_O)\ScintillaBase.obj: ../src/ScintillaBase.cxx ../include/Platform.h \ - ../include/Scintilla.h ../include/PropSet.h \ - ../src/ContractionState.h ../src/SVector.h ../src/SplitVector.h \ - ../src/Partitioning.h ../src/RunStyles.h ../src/CellBuffer.h \ - ../src/CallTip.h ../src/KeyMap.h ../src/Indicator.h ../src/XPM.h \ - ../src/LineMarker.h ../src/Style.h ../src/ViewStyle.h \ - ../src/AutoComplete.h ../src/CharClassify.h ../src/Document.h \ - ../src/Editor.h ../src/Selection.h ../src/ScintillaBase.h - -$(DIR_O)\ScintillaBaseL.obj: ../src/ScintillaBase.cxx ../include/Platform.h \ - ../include/Scintilla.h ../include/PropSet.h \ - ../src/ContractionState.h ../src/SVector.h ../src/SplitVector.h \ - ../src/Partitioning.h ../src/RunStyles.h ../src/CellBuffer.h \ - ../src/CallTip.h ../src/KeyMap.h ../src/Indicator.h ../src/XPM.h \ - ../src/LineMarker.h ../src/Style.h ../src/ViewStyle.h \ - ../src/AutoComplete.h ../src/CharClassify.h ../src/Document.h \ - ../src/Editor.h ../src/Selection.h ../src/ScintillaBase.h - -$(DIR_O)\ScintillaGTK.obj: ScintillaGTK.cxx ../include/Platform.h \ - ../include/Scintilla.h ../src/ContractionState.h \ - ../src/SVector.h ../src/SplitVector.h ../src/Partitioning.h \ - ../src/RunStyles.h ../src/CellBuffer.h ../src/CallTip.h ../src/KeyMap.h \ - ../src/Indicator.h ../src/XPM.h ../src/LineMarker.h ../src/Style.h \ - ../src/AutoComplete.h ../src/ViewStyle.h ../src/CharClassify.h \ - ../src/Document.h ../src/Editor.h ../src/ScintillaBase.h \ - ../src/Selection.h ../src/UniConversion.h - -$(DIR_O)\ScintillaGTKL.obj: ScintillaGTK.cxx ../include/Platform.h \ - ../include/Scintilla.h ../src/ContractionState.h \ - ../src/SVector.h ../src/SplitVector.h ../src/Partitioning.h \ - ../src/RunStyles.h ../src/CellBuffer.h ../src/CallTip.h ../src/KeyMap.h \ - ../src/Indicator.h ../src/XPM.h ../src/LineMarker.h ../src/Style.h \ - ../src/AutoComplete.h ../src/ViewStyle.h ../src/CharClassify.h \ - ../src/Document.h ../src/Editor.h ../src/ScintillaBase.h \ - ../src/Selection.h ../src/UniConversion.h - -$(DIR_O)\ScintillaGTKS.obj: ScintillaGTK.cxx ../include/Platform.h \ - ../include/Scintilla.h ../src/ContractionState.h \ - ../src/SVector.h ../src/SplitVector.h ../src/Partitioning.h \ - ../src/RunStyles.h ../src/CellBuffer.h ../src/CallTip.h ../src/KeyMap.h \ - ../src/Indicator.h ../src/XPM.h ../src/LineMarker.h ../src/Style.h \ - ../src/AutoComplete.h ../src/ViewStyle.h ../src/CharClassify.h \ - ../src/Document.h ../src/Editor.h ../src/ScintillaBase.h \ - ../src/Selection.h ../src/UniConversion.h - -$(DIR_O)\Selection.obj: ../src/Selection.cxx ../include/Platform.h ../include/Scintilla.h \ - ../src/Selection.h - -$(DIR_O)\Style.obj: ../src/Style.cxx ../include/Platform.h ../include/Scintilla.h \ - ../src/Style.h - -$(DIR_O)\StyleContext.obj: ../src/StyleContext.cxx ../include/Platform.h \ - ../include/PropSet.h ../include/Accessor.h \ - ../src/StyleContext.h - -$(DIR_O)\UniConversion.obj: ../src/UniConversion.cxx ../src/UniConversion.h - -$(DIR_O)\ViewStyle.obj: ../src/ViewStyle.cxx ../include/Platform.h \ - ../include/Scintilla.h ../src/SplitVector.h ../src/Partitioning.h \ - ../src/RunStyles.h ../src/Indicator.h ../src/XPM.h ../src/LineMarker.h \ - ../src/Style.h ../src/ViewStyle.h - -$(DIR_O)\WindowAccessor.obj: ../src/WindowAccessor.cxx ../include/Platform.h \ - ../include/PropSet.h ../include/Accessor.h \ - ../include/WindowAccessor.h ../include/Scintilla.h - -$(DIR_O)\XPM.obj: ../src/XPM.cxx ../include/Platform.h ../src/XPM.h diff --git a/scintilla/include/SString.h b/scintilla/include/SString.h deleted file mode 100644 index e376f59c..00000000 --- a/scintilla/include/SString.h +++ /dev/null @@ -1,289 +0,0 @@ -// SciTE - Scintilla based Text Editor -/** @file SString.h - ** A simple string class. - **/ -// Copyright 1998-2004 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -#ifndef SSTRING_H -#define SSTRING_H - - -// These functions are implemented because each platform calls them something different. -int CompareCaseInsensitive(const char *a, const char *b); -int CompareNCaseInsensitive(const char *a, const char *b, size_t len); -bool EqualCaseInsensitive(const char *a, const char *b); - -#ifdef SCI_NAMESPACE -namespace Scintilla { -#endif - -// Define another string class. -// While it would be 'better' to use std::string, that doubles the executable size. -// An SString may contain embedded nul characters. - -/** - * Base class from which the two other classes (SBuffer & SString) - * are derived. - */ -class SContainer { -public: - /** Type of string lengths (sizes) and positions (indexes). */ - typedef size_t lenpos_t; - /** Out of bounds value indicating that the string argument should be measured. */ - enum { measure_length=0xffffffffU}; - -protected: - char *s; ///< The C string - lenpos_t sSize; ///< The size of the buffer, less 1: ie. the maximum size of the string - - SContainer() : s(0), sSize(0) {} - ~SContainer() { - delete []s; // Suppose it was allocated using StringAllocate - s = 0; - sSize = 0; - } - /** Size of buffer. */ - lenpos_t size() const { - if (s) { - return sSize; - } else { - return 0; - } - } -public: - /** - * Allocate uninitialized memory big enough to fit a string of the given length. - * @return the pointer to the new string - */ - static char *StringAllocate(lenpos_t len); - /** - * Duplicate a buffer/C string. - * Allocate memory of the given size, or big enough to fit the string if length isn't given; - * then copy the given string in the allocated memory. - * @return the pointer to the new string - */ - static char *StringAllocate( - const char *s, ///< The string to duplicate - lenpos_t len=measure_length); ///< The length of memory to allocate. Optional. -}; - - -/** - * @brief A string buffer class. - * - * Main use is to ask an API the length of a string it can provide, - * then to allocate a buffer of the given size, and to provide this buffer - * to the API to put the string. - * This class is intended to be shortlived, to be transformed as SString - * as soon as it holds the string, so it has little members. - * Note: we assume the buffer is filled by the API. If the length can be shorter, - * we should set sLen to strlen(sb.ptr()) in related SString constructor and assignment. - */ -class SBuffer : protected SContainer { -public: - SBuffer(lenpos_t len) { - s = StringAllocate(len); - if (s) { - *s = '\0'; - sSize = len; - } else { - sSize = 0; - } - } -private: - /// Copy constructor - // Here only to be on the safe size, user should avoid returning SBuffer values. - SBuffer(const SBuffer &source) : SContainer() { - s = StringAllocate(source.s, source.sSize); - sSize = (s) ? source.sSize : 0; - } - /// Default assignment operator - // Same here, shouldn't be used - SBuffer &operator=(const SBuffer &source) { - if (this != &source) { - delete []s; - s = StringAllocate(source.s, source.sSize); - sSize = (s) ? source.sSize : 0; - } - return *this; - } -public: - /** Provide direct read/write access to buffer. */ - char *ptr() { - return s; - } - /** Ownership of the buffer have been taken, so release it. */ - void reset() { - s = 0; - sSize = 0; - } - /** Size of buffer. */ - lenpos_t size() const { - return SContainer::size(); - } -}; - - -/** - * @brief A simple string class. - * - * Hold the length of the string for quick operations, - * can have a buffer bigger than the string to avoid too many memory allocations and copies. - * May have embedded zeroes as a result of @a substitute, but relies too heavily on C string - * functions to allow reliable manipulations of these strings, other than simple appends, etc. - */ -class SString : protected SContainer { - lenpos_t sLen; ///< The size of the string in s - lenpos_t sizeGrowth; ///< Minimum growth size when appending strings - enum { sizeGrowthDefault = 64 }; - - bool grow(lenpos_t lenNew); - SString &assign(const char *sOther, lenpos_t sSize_=measure_length); - -public: - SString() : sLen(0), sizeGrowth(sizeGrowthDefault) {} - SString(const SString &source) : SContainer(), sizeGrowth(sizeGrowthDefault) { - s = StringAllocate(source.s, source.sLen); - sSize = sLen = (s) ? source.sLen : 0; - } - SString(const char *s_) : sizeGrowth(sizeGrowthDefault) { - s = StringAllocate(s_); - sSize = sLen = (s) ? strlen(s) : 0; - } - SString(SBuffer &buf) : sizeGrowth(sizeGrowthDefault) { - s = buf.ptr(); - sSize = sLen = buf.size(); - // Consumes the given buffer! - buf.reset(); - } - SString(const char *s_, lenpos_t first, lenpos_t last) : sizeGrowth(sizeGrowthDefault) { - // note: expects the "last" argument to point one beyond the range end (a la STL iterators) - s = StringAllocate(s_ + first, last - first); - sSize = sLen = (s) ? last - first : 0; - } - SString(int i); - SString(double d, int precision); - ~SString() { - sLen = 0; - } - void clear() { - if (s) { - *s = '\0'; - } - sLen = 0; - } - /** Size of buffer. */ - lenpos_t size() const { - return SContainer::size(); - } - /** Size of string in buffer. */ - lenpos_t length() const { - return sLen; - } - /** Read access to a character of the string. */ - char operator[](lenpos_t i) const { - return (s && i < sSize) ? s[i] : '\0'; - } - SString &operator=(const char *source) { - return assign(source); - } - SString &operator=(const SString &source) { - if (this != &source) { - assign(source.s, source.sLen); - } - return *this; - } - bool operator==(const SString &sOther) const; - bool operator!=(const SString &sOther) const { - return !operator==(sOther); - } - bool operator==(const char *sOther) const; - bool operator!=(const char *sOther) const { - return !operator==(sOther); - } - bool contains(char ch) const { - return (s && *s) ? strchr(s, ch) != 0 : false; - } - void setsizegrowth(lenpos_t sizeGrowth_) { - sizeGrowth = sizeGrowth_; - } - const char *c_str() const { - return s ? s : ""; - } - /** Give ownership of buffer to caller which must use delete[] to free buffer. */ - char *detach() { - char *sRet = s; - s = 0; - sSize = 0; - sLen = 0; - return sRet; - } - SString substr(lenpos_t subPos, lenpos_t subLen=measure_length) const; - SString &lowercase(lenpos_t subPos = 0, lenpos_t subLen=measure_length); - SString &uppercase(lenpos_t subPos = 0, lenpos_t subLen=measure_length); - SString &append(const char *sOther, lenpos_t sLenOther=measure_length, char sep = '\0'); - SString &operator+=(const char *sOther) { - return append(sOther, static_cast(measure_length)); - } - SString &operator+=(const SString &sOther) { - return append(sOther.s, sOther.sLen); - } - SString &operator+=(char ch) { - return append(&ch, 1); - } - SString &appendwithseparator(const char *sOther, char sep) { - return append(sOther, strlen(sOther), sep); - } - SString &insert(lenpos_t pos, const char *sOther, lenpos_t sLenOther=measure_length); - - /** - * Remove @a len characters from the @a pos position, included. - * Characters at pos + len and beyond replace characters at pos. - * If @a len is 0, or greater than the length of the string - * starting at @a pos, the string is just truncated at @a pos. - */ - void remove(lenpos_t pos, lenpos_t len); - - SString &change(lenpos_t pos, char ch) { - if (pos < sLen) { // character changed must be in string bounds - *(s + pos) = ch; - } - return *this; - } - /** Read an integral numeric value from the string. */ - int value() const { - return s ? atoi(s) : 0; - } - bool startswith(const char *prefix); - bool endswith(const char *suffix); - int search(const char *sFind, lenpos_t start=0) const; - bool contains(const char *sFind) const { - return search(sFind) >= 0; - } - int substitute(char chFind, char chReplace); - int substitute(const char *sFind, const char *sReplace); - int remove(const char *sFind) { - return substitute(sFind, ""); - } -}; - - -/** - * Duplicate a C string. - * Allocate memory of the given size, or big enough to fit the string if length isn't given; - * then copy the given string in the allocated memory. - * @return the pointer to the new string - */ -inline char *StringDup( - const char *s, ///< The string to duplicate - SContainer::lenpos_t len=SContainer::measure_length) ///< The length of memory to allocate. Optional. -{ - return SContainer::StringAllocate(s, len); -} - -#ifdef SCI_NAMESPACE -} -#endif - -#endif diff --git a/scintilla/macosx/ExtInput.cxx b/scintilla/macosx/ExtInput.cxx new file mode 100644 index 00000000..a26b4872 --- /dev/null +++ b/scintilla/macosx/ExtInput.cxx @@ -0,0 +1,608 @@ +/******************************************************************************* + +Copyright (c) 2007 Adobe Systems Incorporated + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +********************************************************************************/ + +#include "ScintillaMacOSX.h" +#include "ExtInput.h" + +using namespace Scintilla; + +// uncomment this for a log to /dev/console +// #define LOG_TSM 1 + +#if LOG_TSM +FILE* logFile = NULL; +#endif + +static EventHandlerUPP tsmHandler; + +static EventTypeSpec tsmSpecs[] = { + { kEventClassTextInput, kEventTextInputUpdateActiveInputArea }, +// { kEventClassTextInput, kEventTextInputUnicodeForKeyEvent }, + { kEventClassTextInput, kEventTextInputOffsetToPos }, + { kEventClassTextInput, kEventTextInputPosToOffset }, + { kEventClassTextInput, kEventTextInputGetSelectedText } +}; + +#define kScintillaTSM 'ScTs' + +// The following structure is attached to the HIViewRef as property kScintillaTSM + +struct TSMData +{ + HIViewRef view; // this view + TSMDocumentID docid; // the TSM document ID + EventHandlerRef handler; // the event handler + ScintillaMacOSX* scintilla; // the Scintilla pointer + int styleMask; // the document style mask + int indicStyle [3]; // indicator styles save + int indicColor [3]; // indicator colors save + int selStart; // starting position of selection (Scintilla offset) + int selLength; // UTF-8 number of characters + int selCur; // current position (Scintilla offset) + int inhibitRecursion; // true to stop recursion + bool active; // true if this is active +}; + +static const int numSpecs = 5; + + +// Fetch a range of text as UTF-16; delete the buffer after use + +static char* getTextPortion (TSMData* data, UInt32 start, UInt32 size) +{ + Scintilla::TextRange range; + range.chrg.cpMin = start; + range.chrg.cpMax = start + size; + range.lpstrText = new char [size + 1]; + range.lpstrText [size] = 0; + data->scintilla->WndProc (SCI_GETTEXTRANGE, 0, (uptr_t) &range); + return range.lpstrText; +} + +static pascal OSStatus doHandleTSM (EventHandlerCallRef, EventRef inEvent, void* userData); + +void ExtInput::attach (HIViewRef viewRef) +{ + if (NULL == tsmHandler) + tsmHandler = NewEventHandlerUPP (doHandleTSM); + ::UseInputWindow (NULL, FALSE); + +#ifdef LOG_TSM + if (NULL == logFile) + logFile = fopen ("/dev/console", "a"); +#endif + + // create and attach the TSM data + TSMData* data = new TSMData; + + data->view = viewRef; + data->active = false; + data->inhibitRecursion = 0; + + ::GetControlProperty (viewRef, scintillaMacOSType, 0, sizeof( data->scintilla ), NULL, &data->scintilla); + + if (NULL != data->scintilla) + { + // create the TSM document ref + InterfaceTypeList interfaceTypes; + interfaceTypes[0] = kUnicodeDocumentInterfaceType; + ::NewTSMDocument (1, interfaceTypes, &data->docid, (long) viewRef); + // install my event handler + ::InstallControlEventHandler (viewRef, tsmHandler, numSpecs, tsmSpecs, data, &data->handler); + + ::SetControlProperty (viewRef, kScintillaTSM, 0, sizeof (data), &data); + } + else + delete data; +} + +static TSMData* getTSMData (HIViewRef viewRef) +{ + TSMData* data = NULL; + UInt32 n; + ::GetControlProperty (viewRef, kScintillaTSM, 0, sizeof (data), &n, (UInt32*) &data); + return data; +} + +void ExtInput::detach (HIViewRef viewRef) +{ + TSMData* data = getTSMData (viewRef); + if (NULL != data) + { + ::DeleteTSMDocument (data->docid); + ::RemoveEventHandler (data->handler); + delete data; + } +} + +void ExtInput::activate (HIViewRef viewRef, bool on) +{ + TSMData* data = getTSMData (viewRef); + if (NULL == data) + return; + + if (on) + { + ::ActivateTSMDocument (data->docid); + HIRect bounds; + ::HIViewGetBounds (viewRef, &bounds); + ::HIViewConvertRect (&bounds, viewRef, NULL); + RgnHandle hRgn = ::NewRgn(); + ::SetRectRgn (hRgn, (short) bounds.origin.x, (short) bounds.origin.y, + (short) (bounds.origin.x + bounds.size.width), + (short) (bounds.origin.y + bounds.size.height)); +#if LOG_TSM + fprintf (logFile, "TSMSetInlineInputRegion (%08lX, %ld:%ld-%ld:%ld)\n", + (long) data->docid, (long) bounds.origin.x, (long) bounds.origin.y, + (long) (bounds.origin.x + bounds.size.width), (long) (bounds.origin.y + bounds.size.height)); + fflush (logFile); +#endif + ::TSMSetInlineInputRegion (data->docid, HIViewGetWindow (data->view), hRgn); + ::DisposeRgn (hRgn); + ::UseInputWindow (NULL, FALSE); + } + else + { +#if LOG_TSM + fprintf (logFile, "DeactivateTSMDocument (%08lX)\n", (long) data->docid); + fflush (logFile); +#endif + ::DeactivateTSMDocument (data->docid); + } +} + +static void startInput (TSMData* data, bool delSelection = true) +{ + if (!data->active && 0 == data->inhibitRecursion) + { + data->active = true; + + // Delete any selection + if( delSelection ) + data->scintilla->WndProc (SCI_REPLACESEL, 0, reinterpret_cast("")); + + // need all style bits because we do indicators + data->styleMask = data->scintilla->WndProc (SCI_GETSTYLEBITS, 0, 0); + data->scintilla->WndProc (SCI_SETSTYLEBITS, 5, 0); + + // Set the target range for successive replacements + data->selStart = + data->selCur = data->scintilla->WndProc (SCI_GETCURRENTPOS, 0, 0); + data->selLength = 0; + + // save needed styles + for (int i = 0; i < 2; i++) + { + data->indicStyle [i] = data->scintilla->WndProc (SCI_INDICGETSTYLE, i, 0); + data->indicColor [i] = data->scintilla->WndProc (SCI_INDICGETFORE, i, 0); + } + // set styles and colors + data->scintilla->WndProc (SCI_INDICSETSTYLE, 0, INDIC_SQUIGGLE); + data->scintilla->WndProc (SCI_INDICSETFORE, 0, 0x808080); + data->scintilla->WndProc (SCI_INDICSETSTYLE, 1, INDIC_PLAIN); // selected converted + data->scintilla->WndProc (SCI_INDICSETFORE, 1, 0x808080); + data->scintilla->WndProc (SCI_INDICSETSTYLE, 2, INDIC_PLAIN); // selected raw + data->scintilla->WndProc (SCI_INDICSETFORE, 2, 0x0000FF); + // stop Undo + data->scintilla->WndProc (SCI_BEGINUNDOACTION, 0, 0); + } +} + +static void stopInput (TSMData* data, int pos) +{ + if (data->active && 0 == data->inhibitRecursion) + { + // First fix the doc - this may cause more messages + // but do not fall into recursion + data->inhibitRecursion++; + ::FixTSMDocument (data->docid); + data->inhibitRecursion--; + data->active = false; + + // Remove indicator styles + data->scintilla->WndProc (SCI_STARTSTYLING, data->selStart, INDICS_MASK); + data->scintilla->WndProc (SCI_SETSTYLING, pos - data->selStart, 0); + // Restore old indicator styles and colors + data->scintilla->WndProc (SCI_SETSTYLEBITS, data->styleMask, 0); + for (int i = 0; i < 2; i++) + { + data->scintilla->WndProc (SCI_INDICSETSTYLE, i, data->indicStyle [i]); + data->scintilla->WndProc (SCI_INDICSETFORE, i, data->indicColor [i]); + } + + // remove selection and re-allow selections to display + data->scintilla->WndProc (SCI_SETSEL, pos, pos); + data->scintilla->WndProc (SCI_TARGETFROMSELECTION, 0, 0); + data->scintilla->WndProc (SCI_HIDESELECTION, 0, 0); + + // move the caret behind the current area + data->scintilla->WndProc (SCI_SETCURRENTPOS, pos, 0); + // re-enable Undo + data->scintilla->WndProc (SCI_ENDUNDOACTION, 0, 0); + // re-colorize + int32_t startLine = data->scintilla->WndProc (SCI_LINEFROMPOSITION, data->selStart, 0); + int32_t startPos = data->scintilla->WndProc (SCI_POSITIONFROMLINE, startLine, 0); + int32_t endLine = data->scintilla->WndProc (SCI_LINEFROMPOSITION, pos, 0); + if (endLine == startLine) + endLine++; + int32_t endPos = data->scintilla->WndProc (SCI_POSITIONFROMLINE, endLine, 0); + + data->scintilla->WndProc (SCI_COLOURISE, startPos, endPos); + } +} + +void ExtInput::stop (HIViewRef viewRef) +{ + TSMData* data = getTSMData (viewRef); + if (NULL != data) + stopInput (data, data->selStart + data->selLength); +} + +static char* UTF16toUTF8 (const UniChar* buf, int len, int& utf8len) +{ + CFStringRef str = CFStringCreateWithCharactersNoCopy (NULL, buf, (UInt32) len, kCFAllocatorNull); + CFRange range = { 0, len }; + CFIndex bufLen; + CFStringGetBytes (str, range, kCFStringEncodingUTF8, '?', false, NULL, 0, &bufLen); + UInt8* utf8buf = new UInt8 [bufLen+1]; + CFStringGetBytes (str, range, kCFStringEncodingUTF8, '?', false, utf8buf, bufLen, NULL); + utf8buf [bufLen] = 0; + CFRelease (str); + utf8len = (int) bufLen; + return (char*) utf8buf; +} + +static int UCS2Length (const char* buf, int len) +{ + int n = 0; + while (len > 0) + { + int bytes = 0; + char ch = *buf; + while (ch & 0x80) + bytes++, ch <<= 1; + len -= bytes; + n += bytes; + } + return n; +} + +static int UTF8Length (const UniChar* buf, int len) +{ + int n = 0; + while (len > 0) + { + UInt32 uch = *buf++; + len--; + if (uch >= 0xD800 && uch <= 0xDBFF && len > 0) + { + UInt32 uch2 = *buf; + if (uch2 >= 0xDC00 && uch2 <= 0xDFFF) + { + buf++; + len--; + uch = ((uch & 0x3FF) << 10) + (uch2 & 0x3FF); + } + } + n++; + if (uch > 0x7F) + n++; + if (uch > 0x7FF) + n++; + if (uch > 0xFFFF) + n++; + if (uch > 0x1FFFFF) + n++; + if (uch > 0x3FFFFFF) + n++; + } + return n; +} + +static OSStatus handleTSMUpdateActiveInputArea (TSMData* data, EventRef inEvent) +{ + UInt32 fixLength; + int caretPos = -1; + UInt32 actualSize; + ::TextRangeArray* hiliteRanges = NULL; + char* hiliteBuffer = NULL; + bool done; + + // extract the text + UniChar* buffer = NULL; + UniChar temp [128]; + UniChar* text = temp; + + // get the fix length (in bytes) + OSStatus err = ::GetEventParameter (inEvent, kEventParamTextInputSendFixLen, + typeLongInteger, NULL, sizeof (long), NULL, &fixLength); + // need the size (in bytes) + if (noErr == err) + err = ::GetEventParameter (inEvent, kEventParamTextInputSendText, + typeUnicodeText, NULL, 256, &actualSize, temp); + + // then allocate and fetch if necessary + UInt32 textLength = actualSize / sizeof (UniChar); + fixLength /= sizeof (UniChar); + + if (noErr == err) + { + // this indicates that we are completely done + done = (fixLength == textLength || fixLength < 0); + if (textLength >= 128) + { + buffer = text = new UniChar [textLength]; + err = ::GetEventParameter (inEvent, kEventParamTextInputSendText, + typeUnicodeText, NULL, actualSize, NULL, (void*) text); + } + + // set the text now, but convert it to UTF-8 first + int utf8len; + char* utf8 = UTF16toUTF8 (text, textLength, utf8len); + data->scintilla->WndProc (SCI_SETTARGETSTART, data->selStart, 0); + data->scintilla->WndProc (SCI_SETTARGETEND, data->selStart + data->selLength, 0); + data->scintilla->WndProc (SCI_HIDESELECTION, 1, 0); + data->scintilla->WndProc (SCI_REPLACETARGET, utf8len, (sptr_t) utf8); + data->selLength = utf8len; + delete [] utf8; + } + + // attempt to extract the array of hilite ranges + if (noErr == err) + { + ::TextRangeArray tempTextRangeArray; + OSStatus tempErr = ::GetEventParameter (inEvent, kEventParamTextInputSendHiliteRng, + typeTextRangeArray, NULL, sizeof (::TextRangeArray), &actualSize, &tempTextRangeArray); + if (noErr == tempErr) + { + // allocate memory and get the stuff! + hiliteBuffer = new char [actualSize]; + hiliteRanges = (::TextRangeArray*) hiliteBuffer; + err = ::GetEventParameter (inEvent, kEventParamTextInputSendHiliteRng, + typeTextRangeArray, NULL, actualSize, NULL, hiliteRanges); + if (noErr != err) + { + delete [] hiliteBuffer; + hiliteBuffer = NULL; + hiliteRanges = NULL; + } + } + } +#if LOG_TSM + fprintf (logFile, "kEventTextInputUpdateActiveInputArea:\n" + " TextLength = %ld\n" + " FixLength = %ld\n", + (long) textLength, (long) fixLength); + fflush (logFile); +#endif + + if (NULL != hiliteRanges) + { + for (int i = 0; i < hiliteRanges->fNumOfRanges; i++) + { +#if LOG_TSM + fprintf (logFile, " Range #%d: %ld-%ld (%d)\n", + i+1, + hiliteRanges->fRange[i].fStart, + hiliteRanges->fRange[i].fEnd, + hiliteRanges->fRange[i].fHiliteStyle); + fflush (logFile); +#endif + // start and end of range, zero based + long bgn = long (hiliteRanges->fRange[i].fStart) / sizeof (UniChar); + long end = long (hiliteRanges->fRange[i].fEnd) / sizeof (UniChar); + if (bgn >= 0 && end >= 0) + { + // move the caret if this is requested + if (hiliteRanges->fRange[i].fHiliteStyle == kTSMHiliteCaretPosition) + caretPos = bgn; + else + { + // determine which style to use + int style; + switch (hiliteRanges->fRange[i].fHiliteStyle) + { + case kTSMHiliteRawText: style = INDIC0_MASK; break; + case kTSMHiliteSelectedRawText: style = INDIC0_MASK; break; + case kTSMHiliteConvertedText: style = INDIC1_MASK; break; + case kTSMHiliteSelectedConvertedText: style = INDIC2_MASK; break; + default: style = INDIC0_MASK; + } + // bgn and end are Unicode offsets from the starting pos + // use the text buffer to determine the UTF-8 offsets + long utf8bgn = data->selStart + UTF8Length (text, bgn); + long utf8size = UTF8Length (text + bgn, end - bgn); + // set indicators + int oldEnd = data->scintilla->WndProc (SCI_GETENDSTYLED, 0, 0); + data->scintilla->WndProc (SCI_STARTSTYLING, utf8bgn, INDICS_MASK); + data->scintilla->WndProc (SCI_SETSTYLING, utf8size, style & ~1); + data->scintilla->WndProc (SCI_STARTSTYLING, oldEnd, 31); + } + } + } + } + if (noErr == err) + { + // if the fixed length is == to the new text, we are done + if (done) + stopInput (data, data->selStart + UTF8Length (text, textLength)); + else if (caretPos >= 0) + { + data->selCur = data->selStart + UTF8Length (text, caretPos); + data->scintilla->WndProc (SCI_SETCURRENTPOS, data->selCur, 0); + } + } + + delete [] hiliteBuffer; + delete [] buffer; + return err; +} + +struct MacPoint { + short v; + short h; +}; + +static OSErr handleTSMOffset2Pos (TSMData* data, EventRef inEvent) +{ + long offset; + + // get the offfset to convert + OSStatus err = ::GetEventParameter (inEvent, kEventParamTextInputSendTextOffset, + typeLongInteger, NULL, sizeof (long), NULL, &offset); + if (noErr == err) + { + // where is the caret now? + HIPoint where; + + int line = (int) data->scintilla->WndProc (SCI_LINEFROMPOSITION, data->selCur, 0); + where.x = data->scintilla->WndProc (SCI_POINTXFROMPOSITION, 0, data->selCur); + where.y = data->scintilla->WndProc (SCI_POINTYFROMPOSITION, 0, data->selCur) + + data->scintilla->WndProc (SCI_TEXTHEIGHT, line, 0); + // convert to window coords + ::HIViewConvertPoint (&where, data->view, NULL); + // convert to screen coords + Rect global; + GetWindowBounds (HIViewGetWindow (data->view), kWindowStructureRgn, &global); + MacPoint pt; + pt.h = (short) where.x + global.left; + pt.v = (short) where.y + global.top; + + // set the result + err = ::SetEventParameter (inEvent, kEventParamTextInputReplyPoint, typeQDPoint, sizeof (MacPoint), &pt); +#if LOG_TSM + fprintf (logFile, "kEventTextInputOffsetToPos:\n" + " Offset: %ld\n" + " Pos: %ld:%ld (orig = %ld:%ld)\n", offset, + (long) pt.h, (long) pt.v, + (long) where.x, (long) where.y); + fflush (logFile); +#endif + } + return err; +} + +static OSErr handleTSMPos2Offset (TSMData* data, EventRef inEvent) +{ + MacPoint qdPosition; + long offset; + short regionClass; + + // retrieve the global point to convert + OSStatus err = ::GetEventParameter (inEvent, kEventParamTextInputSendCurrentPoint, + typeQDPoint, NULL, sizeof (MacPoint), NULL, &qdPosition); + if (noErr == err) + { +#if LOG_TSM + fprintf (logFile, "kEventTextInputPosToOffset:\n" + " Pos: %ld:%ld\n", (long) qdPosition.v, (long) qdPosition.h); + fflush (logFile); +#endif + // convert to local coordinates + HIRect rect; + rect.origin.x = qdPosition.h; + rect.origin.y = qdPosition.v; + rect.size.width = + rect.size.height = 1; + ::HIViewConvertRect (&rect, NULL, data->view); + + // we always report the position to be within the composition; + // coords inside the same pane are clipped to the composition, + // and if the position is outside, then we deactivate this instance + // this leaves the edit open and active so we can edit multiple panes + regionClass = kTSMInsideOfActiveInputArea; + + // compute the offset (relative value) + offset = data->scintilla->WndProc (SCI_POSITIONFROMPOINTCLOSE, (uptr_t) rect.origin.x, (sptr_t) rect.origin.y); + if (offset >= 0) + { + // convert to a UTF-16 offset (Brute Force) + char* buf = getTextPortion (data, 0, offset); + offset = UCS2Length (buf, offset); + delete [] buf; + +#if LOG_TSM + fprintf (logFile, " Offset: %ld (class %ld)\n", offset, (long) regionClass); + fflush (logFile); +#endif + // store the offset + err = ::SetEventParameter (inEvent, kEventParamTextInputReplyTextOffset, typeLongInteger, sizeof (long), &offset); + if (noErr == err) + err = ::SetEventParameter (inEvent, kEventParamTextInputReplyRegionClass, typeShortInteger, sizeof (short), ®ionClass); + } + else + { + // not this pane! + err = eventNotHandledErr; + ExtInput::activate (data->view, false); + } + + } + return err; +} + +static OSErr handleTSMGetText (TSMData* data, EventRef inEvent) +{ + char* buf = getTextPortion (data, data->selStart, data->selLength); + +#if LOG_TSM + fprintf (logFile, "kEventTextInputGetSelectedText:\n" + " Text: \"%s\"\n", buf); + fflush (logFile); +#endif + OSStatus status = ::SetEventParameter (inEvent, kEventParamTextInputReplyText, typeUTF8Text, data->selLength, buf); + delete [] buf; + return status; +} + +static pascal OSStatus doHandleTSM (EventHandlerCallRef, EventRef inEvent, void* userData) +{ + TSMData* data = (TSMData*) userData; + + OSStatus err = eventNotHandledErr; + + switch (::GetEventKind (inEvent)) + { + case kEventTextInputUpdateActiveInputArea: + // Make sure that input has been started + startInput (data); + err = handleTSMUpdateActiveInputArea (data, inEvent); + break; +// case kEventTextInputUnicodeForKeyEvent: +// err = handleTSMUnicodeInput (inEvent); +// break; + case kEventTextInputOffsetToPos: + err = handleTSMOffset2Pos (data, inEvent); + break; + case kEventTextInputPosToOffset: + err = handleTSMPos2Offset (data, inEvent); + break; + case kEventTextInputGetSelectedText: + // Make sure that input has been started + startInput (data, false); + err = handleTSMGetText (data, inEvent); + break; + } + return err; +} + diff --git a/scintilla/macosx/ExtInput.h b/scintilla/macosx/ExtInput.h new file mode 100644 index 00000000..2e97015c --- /dev/null +++ b/scintilla/macosx/ExtInput.h @@ -0,0 +1,64 @@ +/******************************************************************************* + +Copyright (c) 2007 Adobe Systems Incorporated + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +********************************************************************************/ + +#ifndef _ExtInput_h +#define _ExtInput_h + +#include +#include "Scintilla.h" + +namespace Scintilla +{ + +/** +The ExtInput class provides TSM input services to Scintilla. +It uses the indicators 0 and 1 (see SCI_INDICSETSTYLE) to apply +underlines to partially converted text. +*/ + +class ExtInput +{ +public: + /** + Attach extended input to a HIView with attached Scintilla. This installs the needed + event handlers etc. + */ + static void attach (HIViewRef ref); + /** + Detach extended input from a HIViewwith attached Scintilla. + */ + static void detach (HIViewRef ref); + /** + Activate or deactivate extended input. This method should be called whenever + the view gains or loses focus. + */ + static void activate (HIViewRef ref, bool on); + /** + Terminate extended input. + */ + static void stop (HIViewRef ref); +}; + +} // end namespace + +#endif diff --git a/scintilla/macosx/PlatMacOSX.cxx b/scintilla/macosx/PlatMacOSX.cxx new file mode 100644 index 00000000..50f3fa04 --- /dev/null +++ b/scintilla/macosx/PlatMacOSX.cxx @@ -0,0 +1,1852 @@ +// Scintilla source code edit control +// PlatMacOSX.cxx - implementation of platform facilities on MacOS X/Carbon +// Based on work by Evan Jones (c) 2002 +// Based on PlatGTK.cxx Copyright 1998-2002 by Neil Hodgson +// The License.txt file describes the conditions under which this software may be distributed. + +#include +#include +#include + +#include + +#include + +#include +#include "QuartzTextLayout.h" +#include "TCarbonEvent.h" + +#include "Platform.h" +#include "Scintilla.h" +#include "PlatMacOSX.h" +#include "XPM.h" + +using namespace Scintilla; + +#include "ScintillaWidget.h" + + +extern sptr_t scintilla_send_message(void* sci, unsigned int iMessage, uptr_t wParam, sptr_t lParam); + +inline CGRect PRectangleToCGRect( PRectangle& rc ) { + return CGRectMake( rc.left, rc.top, rc.Width(), rc.Height() ); +} + +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; +} + +Scintilla::Point Scintilla::Point::FromLong(long lpoint) { + return Scintilla::Point( + Platform::LowShortFromLong(lpoint), + Platform::HighShortFromLong(lpoint)); +} + +// The Palette is just ignored on Mac OS X. OS X runs "Millions" or "Thousands" of colours. +Scintilla::Palette::Palette() { +} + +Scintilla::Palette::~Palette() { +} + +void Scintilla::Palette::Release() { +} + +// Do nothing if it "wants" a colour. Copy the colour from desired to allocated if it is "finding" a colour. +void Scintilla::Palette::WantFind(ColourPair &cp, bool want) { + if (want) { + } else { + cp.allocated.Set(cp.desired.AsLong()); + } +} + +void Scintilla::Palette::Allocate(Window &/*w*/) { + // OS X always runs in thousands or millions of colours +} + +Font::Font() : fid(0) {} + +Font::~Font() { Release(); } + + +void Font::Create(const char *faceName, int /*characterSet*/, + int size, bool bold, bool italic, int /*extraFontFlag*/) { + // TODO: How should I handle the characterSet request? + Release(); + + fid = new QuartzTextStyle(); + + // Find the font + QuartzFont font( faceName, strlen( faceName ) ); + + // We set Font, Size, Bold, Italic + QuartzTextSize textSize( size ); + QuartzTextBold isBold( bold ); + QuartzTextItalic isItalic( italic ); + + // Actually set the attributes + QuartzTextStyleAttribute* attributes[] = { &font, &textSize, &isBold, &isItalic }; + reinterpret_cast( fid )->setAttributes( attributes, sizeof( attributes ) / sizeof( *attributes ) ); + + //ATSStyleRenderingOptions rendering = kATSStyleNoAntiAliasing; + //reinterpret_cast( fid )->setAttribute( kATSUStyleRenderingOptionsTag, sizeof( rendering ), &rendering ); + + // TODO: Why do I have to manually set this? + reinterpret_cast( fid )->setFontFeature( kLigaturesType, kCommonLigaturesOffSelector ); +} + +void Font::Release() { + if (fid) + delete reinterpret_cast( fid ); + + fid = 0; +} + +SurfaceImpl::SurfaceImpl() { + bitmapData = NULL; // Release will try and delete bitmapData if != NULL + gc = NULL; + textLayout = new QuartzTextLayout(NULL); + Release(); +} + +SurfaceImpl::~SurfaceImpl() { + Release(); + delete textLayout; +} + +void SurfaceImpl::Release() { + textLayout->setContext (NULL); + if ( bitmapData != NULL ) + { + delete[] bitmapData; + // We only "own" the graphics context if we are a bitmap context + if ( gc != NULL ) CGContextRelease( gc ); + } + bitmapData = NULL; + gc = NULL; + + bitmapWidth = 0; + bitmapHeight = 0; + x = 0; + y = 0; + //inited = false; +} + +bool SurfaceImpl::Initialised() { + // We are initalised if the graphics context is not null + return gc != NULL;// || port != NULL; +} + +void SurfaceImpl::Init(WindowID /*wid*/) { + // To be able to draw, the surface must get a CGContext handle. We save the graphics port, + // then aquire/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 + // aquire/release of the context. + + Release(); +} + +void SurfaceImpl::Init(SurfaceID sid, WindowID /*wid*/) { + Release(); + gc = reinterpret_cast( 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 = new uint8_t[ bitmapByteCount ]; + if( bitmapData != NULL ) { + // create the context + gc = CGBitmapContextCreate( bitmapData, + 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 + delete[] bitmapData; + bitmapData = NULL; + } + textLayout->setContext (gc); + } + + // the context retains the color space, so we can release it + CGColorSpaceRelease( colorSpace ); + + if ( gc != NULL && bitmapData != NULL ) + { + // "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 ) ); + } +} + +void SurfaceImpl::PenColour(ColourAllocated fore) { + if (gc) { + ColourDesired colour( fore.AsLong() ); + + // Set the Stroke color to match + CGContextSetRGBStrokeColor( gc, colour.GetRed() / 255.0, colour.GetGreen() / 255.0, colour.GetBlue() / 255.0, 1.0 ); + } +} + +void SurfaceImpl::FillColour(const ColourAllocated& back) { + if (gc) { + ColourDesired colour( back.AsLong() ); + + // Set the Fill color to match + CGContextSetRGBFillColor( 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 == NULL ) return NULL; + + CGContextFlush( gc ); + + // 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); + + // Create a data provider + CGDataProviderRef dataProvider = CGDataProviderCreateWithData( NULL, bitmapData, bitmapByteCount, NULL ); + 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; + + // Done with the data provider + CGDataProviderRelease( dataProvider ); + dataProvider = NULL; + + return image; +} + +int SurfaceImpl::LogPixelsY() { + return 72; +} + +int SurfaceImpl::DeviceHeightFont(int points) { + int logPix = LogPixelsY(); + return (points * logPix + logPix / 2) / 72; +} + +void SurfaceImpl::MoveTo(int x_, int y_) { + x = x_; + y = y_; +} + +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 + // divison 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, ColourAllocated fore, + ColourAllocated back) { + // Allocate memory for the array of points + CGPoint *points = new CGPoint[ 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 ); + + // Set colours + FillColour(back); + PenColour(fore); + + // Draw the polygon + CGContextAddLines( gc, points, npts ); + // TODO: Should the path be automatically closed, or is that the caller's responsability? + // Explicitly close the path, so it is closed for stroking AND filling (implicit close = filling only) + CGContextClosePath( gc ); + CGContextDrawPath( gc, kCGPathFillStroke ); + + // Deallocate memory + delete [] points; + points = NULL; +} + +void SurfaceImpl::RectangleDraw(PRectangle rc, ColourAllocated fore, ColourAllocated 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. + // TODO: Create some version of PRectangleToCGRect to do this conversion for us? + 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, ColourAllocated back) { + if ( gc ) { + //CGContextBeginPath( gc ); + FillColour(back); + + CGRect rect = PRectangleToCGRect( rc ); + + CGContextFillRect( gc, rect ); + //CGContextDrawPath( gc, kCGPathFill ); + } +} + +void drawImageRefCallback( CGImageRef pattern, CGContextRef gc ) +{ + CGContextDrawImage( gc, CGRectMake( 0, 0, CGImageGetWidth( pattern ), CGImageGetHeight( pattern ) ), pattern ); +} + +void SurfaceImpl::FillRectangle(PRectangle rc, Surface &surfacePattern) { + SurfaceImpl& patternSurface = static_cast(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, ColourAllocated(0)); + return; + } + + const CGPatternCallbacks drawImageCallbacks = { 0, reinterpret_cast( drawImageRefCallback ), NULL }; + + 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 float 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; + CGImageRelease( image ); + image = NULL; + } /* pattern != NULL */ +} + +void SurfaceImpl::RoundedRectangle(PRectangle rc, ColourAllocated fore, ColourAllocated back) { + // TODO: Look at the Win32 API to determine what this is supposed to do: + // ::RoundRect(hdc, rc.left + 1, rc.top, rc.right - 1, rc.bottom, 8, 8 ); + + // Create a rectangle with semicircles at the corners + const int MAX_RADIUS = 4; + int radius = Platform::Minimum( MAX_RADIUS, rc.Height()/2 ); + radius = Platform::Minimum( radius, 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 + // TODO: Should I include these +0.5 in the array creation code above? + for( int i = 0; i < 4*3; ++ i ) + { + CGPoint* c = (CGPoint*) corners; + c[i].x += 0.5; + c[i].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 ); +} + +void Scintilla::SurfaceImpl::AlphaRectangle(PRectangle rc, int /*cornerSize*/, ColourAllocated fill, int alphaFill, + ColourAllocated /*outline*/, int /*alphaOutline*/, int /*flags*/) +{ + if ( gc ) { + ColourDesired colour( fill.AsLong() ); + + // Set the Fill color to match + CGContextSetRGBFillColor( gc, colour.GetRed() / 255.0, colour.GetGreen() / 255.0, colour.GetBlue() / 255.0, alphaFill / 100.0 ); + CGRect rect = PRectangleToCGRect( rc ); + CGContextFillRect( gc, rect ); + } +} + +void SurfaceImpl::Ellipse(PRectangle rc, ColourAllocated fore, ColourAllocated back) { + // Drawing an ellipse with bezier curves. Code modified from: + // http://www.codeguru.com/gdi/ellipse.shtml + // MAGICAL CONSTANT to map ellipse to beziers 2/3*(sqrt(2)-1) + const double EToBConst = 0.2761423749154; + + CGSize offset = CGSizeMake((int)(rc.Width() * EToBConst), (int)(rc.Height() * EToBConst)); + CGPoint centre = CGPointMake((rc.left + rc.right) / 2, (rc.top + rc.bottom) / 2); + + // The control point array + CGPoint cCtlPt[13]; + + // Assign values to all the control points + cCtlPt[0].x = + cCtlPt[1].x = + cCtlPt[11].x = + cCtlPt[12].x = rc.left + 0.5; + cCtlPt[5].x = + cCtlPt[6].x = + cCtlPt[7].x = rc.right - 0.5; + cCtlPt[2].x = + cCtlPt[10].x = centre.x - offset.width + 0.5; + cCtlPt[4].x = + cCtlPt[8].x = centre.x + offset.width + 0.5; + cCtlPt[3].x = + cCtlPt[9].x = centre.x + 0.5; + + cCtlPt[2].y = + cCtlPt[3].y = + cCtlPt[4].y = rc.top + 0.5; + cCtlPt[8].y = + cCtlPt[9].y = + cCtlPt[10].y = rc.bottom - 0.5; + cCtlPt[7].y = + cCtlPt[11].y = centre.y + offset.height + 0.5; + cCtlPt[1].y = + cCtlPt[5].y = centre.y - offset.height + 0.5; + cCtlPt[0].y = + cCtlPt[12].y = + cCtlPt[6].y = centre.y + 0.5; + + FillColour(back); + PenColour(fore); + + CGContextBeginPath( gc ); + CGContextMoveToPoint( gc, cCtlPt[0].x, cCtlPt[0].y ); + + for ( int i = 1; i < 13; i += 3 ) + { + CGContextAddCurveToPoint( gc, cCtlPt[i].x, cCtlPt[i].y, cCtlPt[i+1].x, cCtlPt[i+1].y, cCtlPt[i+2].x, cCtlPt[i+2].y ); + } + + // Close the path to enclose it for stroking and for filling, then draw it + CGContextClosePath( gc ); + CGContextDrawPath( gc, kCGPathFillStroke ); +} + +void SurfaceImpl::CopyImageRectangle(Surface &surfaceSource, PRectangle srcRect, PRectangle dstRect) +{ + SurfaceImpl& source = static_cast(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)) + { + float sx = CGRectGetWidth(dst) / CGRectGetWidth(src); + float sy = CGRectGetHeight(dst) / CGRectGetHeight(src); + float dx = CGRectGetMinX(dst) - (CGRectGetMinX(src) * sx); + float 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); +} + +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(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, ColourAllocated( 0 ) ); + return; + } + + // 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 ) ); + + //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 ); + + // Done with the image + CGImageRelease( image ); + image = NULL; +} + +void SurfaceImpl::DrawTextNoClip(PRectangle rc, Font &font_, int ybase, const char *s, int len, + ColourAllocated fore, ColourAllocated back) { + + FillRectangle(rc, back); + DrawTextTransparent( rc, font_, ybase, s, len, fore ); +} + +void SurfaceImpl::DrawTextClipped(PRectangle rc, Font &font_, int ybase, const char *s, int len, + ColourAllocated fore, ColourAllocated back) { + + CGContextSaveGState( gc ); + CGContextClipToRect( gc, PRectangleToCGRect( rc ) ); + DrawTextNoClip( rc, font_, ybase, s, len, fore, back ); + CGContextRestoreGState( gc ); +} + +void SurfaceImpl::DrawTextTransparent(PRectangle rc, Font &font_, int ybase, const char *s, int len, ColourAllocated fore) { + textLayout->setText (reinterpret_cast(s), len, *reinterpret_cast(font_.GetID())); + + // The Quartz RGB fill color influences the ATSUI color + FillColour(fore); + // Draw the text, with the Y axis flipped + textLayout->draw( rc.left, ybase, true ); +} + +void SurfaceImpl::MeasureWidths(Font &font_, const char *s, int len, int *positions) { + // sample at http://developer.apple.com/samplecode/ATSUICurveAccessDemo/listing1.html + // sample includes use of ATSUGetGlyphInfo which would be better for older + // OSX systems. We should expand to using that on older systems as well. + for (int i = 0; i < len; i++) + positions [i] = 0; + + // We need the right X coords, so we have to append a char to get the left coord of thast extra char + char* buf = (char*) malloc (len+1); + if (!buf) + return; + + memcpy (buf, s, len); + buf [len] = '.'; + + textLayout->setText (reinterpret_cast(buf), len+1, *reinterpret_cast(font_.GetID())); + ATSUGlyphInfoArray* theGlyphInfoArrayPtr; + ByteCount theArraySize; + + // Get the GlyphInfoArray + ATSUTextLayout layout = textLayout->getLayout(); + if ( noErr == ATSUGetGlyphInfo (layout, 0, textLayout->getLength(), &theArraySize, NULL)) + { + theGlyphInfoArrayPtr = (ATSUGlyphInfoArray *) malloc (theArraySize + sizeof(ItemCount) + sizeof(ATSUTextLayout)); + if (theGlyphInfoArrayPtr) + { + if (noErr == ATSUGetGlyphInfo (layout, 0, textLayout->getLength(), &theArraySize, theGlyphInfoArrayPtr)) + { + // do not count the first item, which is at the beginning of the line + for ( UniCharCount unicodePosition = 1, i = 0; i < len && unicodePosition < theGlyphInfoArrayPtr->numGlyphs; unicodePosition ++ ) + { + // The ideal position is the x coordinate of the glyph, relative to the beginning of the line + int position = (int)( theGlyphInfoArrayPtr->glyphs[unicodePosition].idealX + 0.5 ); // These older APIs return float values + unsigned char uch = s[i]; + positions[i++] = position; + + // If we are using unicode (UTF8), map the Unicode position back to the UTF8 characters, + // as 1 unicode character can map to multiple UTF8 characters. + // See: http://www.tbray.org/ongoing/When/200x/2003/04/26/UTF + // Or: http://www.cl.cam.ac.uk/~mgk25/unicode.html + if ( unicodeMode ) + { + unsigned char mask = 0xc0; + int count = 1; + // Add one additonal byte for each extra high order one in the byte + while ( uch >= mask && count < 8 ) + { + positions[i++] = position; + count ++; + mask = mask >> 1 | 0x80; // add an additional one in the highest order position + } + } + } + } + + // Free the GlyphInfoArray + free (theGlyphInfoArrayPtr); + } + } + free (buf); +} + +int SurfaceImpl::WidthText(Font &font_, const char *s, int len) { + if (font_.GetID()) + { + textLayout->setText (reinterpret_cast(s), len, *reinterpret_cast(font_.GetID())); + + // TODO: Maybe I should add some sort of text measurement features to QuartzTextLayout? + unsigned long actualNumberOfBounds = 0; + ATSTrapezoid glyphBounds; + + // We get a single bound, since the text should only require one. If it requires more, there is an issue + if ( ATSUGetGlyphBounds( textLayout->getLayout(), 0, 0, kATSUFromTextBeginning, kATSUToTextEnd, kATSUseDeviceOrigins, 1, &glyphBounds, &actualNumberOfBounds ) != noErr || actualNumberOfBounds != 1 ) + { + Platform::DebugDisplay( "ATSUGetGlyphBounds failed in WidthText" ); + return 0; + } + + //Platform::DebugPrintf( "WidthText: \"%*s\" = %ld\n", len, s, Fix2Long( glyphBounds.upperRight.x - glyphBounds.upperLeft.x ) ); + return Fix2Long( glyphBounds.upperRight.x - glyphBounds.upperLeft.x ); + } + return 1; +} + +int SurfaceImpl::WidthChar(Font &font_, char ch) { + char str[2] = { ch, '\0' }; + if (font_.GetID()) + { + textLayout->setText (reinterpret_cast(str), 1, *reinterpret_cast(font_.GetID())); + + // TODO: Maybe I should add some sort of text measurement features to QuartzTextLayout? + unsigned long actualNumberOfBounds = 0; + ATSTrapezoid glyphBounds; + + // We get a single bound, since the text should only require one. If it requires more, there is an issue + if ( ATSUGetGlyphBounds( textLayout->getLayout(), 0, 0, kATSUFromTextBeginning, kATSUToTextEnd, kATSUseDeviceOrigins, 1, &glyphBounds, &actualNumberOfBounds ) != noErr || actualNumberOfBounds != 1 ) + { + Platform::DebugDisplay( "ATSUGetGlyphBounds failed in WidthChar" ); + return 0; + } + + return Fix2Long( glyphBounds.upperRight.x - glyphBounds.upperLeft.x ); + } + else + return 1; +} + +// Three possible strategies for determining ascent and descent of font: +// 1) Call ATSUGetGlyphBounds with string containing all letters, numbers and punctuation. +// 2) Use the ascent and descent fields of the font. +// 3) Call ATSUGetGlyphBounds with string as 1 but also including accented capitals. +// Smallest values given by 1 and largest by 3 with 2 in between. +// Techniques 1 and 2 sometimes chop off extreme portions of ascenders and +// descenders but are mostly OK except for accented characters which are +// rarely used in code. + +// This string contains a good range of characters to test for size. +const char sizeString[] = "`~!@#$%^&*()-_=+\\|[]{};:\"\'<,>.?/1234567890" + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; + +int SurfaceImpl::Ascent(Font &font_) { + if (!font_.GetID()) + return 1; + + ATSUTextMeasurement ascent = reinterpret_cast( font_.GetID() )->getAttribute( kATSUAscentTag ); + return Fix2Long( ascent ); +} + +int SurfaceImpl::Descent(Font &font_) { + if (!font_.GetID()) + return 1; + + ATSUTextMeasurement descent = reinterpret_cast( font_.GetID() )->getAttribute( kATSUDescentTag ); + return Fix2Long( descent ); +} + +int SurfaceImpl::InternalLeading(Font &) { + // TODO: How do we get EM_Size? + // internal leading = ascent - descent - EM_size + return 0; +} + +int SurfaceImpl::ExternalLeading(Font &font_) { + if (!font_.GetID()) + return 1; + + ATSUTextMeasurement lineGap = reinterpret_cast( font_.GetID() )->getAttribute( kATSULeadingTag ); + return Fix2Long( lineGap ); +} + +int SurfaceImpl::Height(Font &font_) { + return Ascent(font_) + Descent(font_); +} + +int SurfaceImpl::AverageCharWidth(Font &font_) { + + if (!font_.GetID()) + return 1; + + const int sizeStringLength = (sizeof( sizeString ) / sizeof( sizeString[0] ) - 1); + int width = WidthText( font_, sizeString, sizeStringLength ); + + return (int) ((width / (float) sizeStringLength) + 0.5); + + /* + ATSUStyle textStyle = reinterpret_cast( font_.GetID() )->getATSUStyle(); + ATSUFontID fontID; + + ByteCount actualSize = 0; + if ( ATSUGetAttribute( textStyle, kATSUFontTag, sizeof( fontID ), &fontID, &actualSize ) != noErr ) + { +Platform::DebugDisplay( "ATSUGetAttribute failed" ); + return 1; + } + + ATSFontMetrics metrics; + memset( &metrics, 0, sizeof( metrics ) ); + if ( ATSFontGetHorizontalMetrics( fontID, kATSOptionFlagsDefault, &metrics ) != noErr ) + { + Platform::DebugDisplay( "ATSFontGetHorizontalMetrics failed in AverageCharWidth" ); + return 1; + } + + printf( "%f %f %f\n", metrics.avgAdvanceWidth * 32, metrics.ascent * 32, metrics.descent * 32 ); + + return (int) (metrics.avgAdvanceWidth + 0.5);*/ +} + +int SurfaceImpl::SetPalette(Scintilla::Palette *, bool) { + // Mac OS X is always true colour (I think) so this doesn't matter + return 0; +} + +void SurfaceImpl::SetClip(PRectangle rc) { + CGContextClipToRect( gc, PRectangleToCGRect( rc ) ); +} + +void SurfaceImpl::FlushCachedState() { + CGContextSynchronize( gc ); +} + +void SurfaceImpl::SetUnicodeMode(bool unicodeMode_) { + unicodeMode = unicodeMode_; +} + +void SurfaceImpl::SetDBCSMode(int codePage) { + // TODO: Implement this for code pages != UTF-8 +} + +Surface *Surface::Allocate() { + return new SurfaceImpl( ); +} + +Window::~Window() { +} + +void Window::Destroy() { + if (windowRef) { + DisposeWindow(reinterpret_cast( windowRef )); + } + wid = 0; +} + +bool Window::HasFocus() { + // TODO: Test this + return HIViewSubtreeContainsFocus( reinterpret_cast( wid ) ); +} + +PRectangle Window::GetPosition() { + // Before any size allocated pretend its 1000 wide so not scrolled + PRectangle rc(0, 0, 1000, 1000); + + // The frame rectangle gives the position of this view inside the parent view + if (wid) { + HIRect controlFrame; + HIViewGetFrame( reinterpret_cast( wid ), &controlFrame ); + rc = CGRectToPRectangle( controlFrame ); + } + + return rc; +} + +void Window::SetPosition(PRectangle rc) { + // Moves this view inside the parent view + if ( wid ) + { + // Set the frame on the view, the function handles the rest + CGRect r = PRectangleToCGRect( rc ); + HIViewSetFrame( reinterpret_cast( wid ), &r ); + } +} + +void Window::SetPositionRelative(PRectangle rc, Window window) { + // used to actually move child windows (ie. listbox/calltip) so we have to move + // the window, not the hiview + if (windowRef) { + // we go through some contortions here to get an accurate location for our + // child windows. This is necessary due to the multiple ways an embedding + // app may be setup. See SciTest/main.c (GOOD && BAD) for test case. + WindowRef relativeWindow = GetControlOwner(reinterpret_cast( window.GetID() )); + WindowRef thisWindow = reinterpret_cast( windowRef ); + + Rect portBounds; + ::GetWindowBounds(relativeWindow, kWindowStructureRgn, &portBounds); + //fprintf(stderr, "portBounds %d %d %d %d\n", portBounds.left, portBounds.top, portBounds.right, portBounds.bottom); + PRectangle hbounds = window.GetPosition(); + //fprintf(stderr, "hbounds %d %d %d %d\n", hbounds.left, hbounds.top, hbounds.right, hbounds.bottom); + HIViewRef parent = HIViewGetSuperview(reinterpret_cast( window.GetID() )); + Rect pbounds; + GetControlBounds(parent, &pbounds); + //fprintf(stderr, "pbounds %d %d %d %d\n", pbounds.left, pbounds.top, pbounds.right, pbounds.bottom); + + PRectangle bounds; + bounds.top = portBounds.top + pbounds.top + hbounds.top + rc.top; + bounds.bottom = bounds.top + rc.Height(); + bounds.left = portBounds.left + pbounds.left + hbounds.left + rc.left; + bounds.right = bounds.left + rc.Width(); + //fprintf(stderr, "bounds %d %d %d %d\n", bounds.left, bounds.top, bounds.right, bounds.bottom); + + MoveWindow(thisWindow, bounds.left, bounds.top, false); + SizeWindow(thisWindow, bounds.Width(), bounds.Height(), true); + + SetPosition(PRectangle(0,0,rc.Width(),rc.Height())); + } else { + 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 ) { + HIViewSetVisible( reinterpret_cast( wid ), show ); + } + // this is necessary for calltip/listbox + if (windowRef) { + WindowRef thisWindow = reinterpret_cast( windowRef ); + if (show) { + ShowWindow( thisWindow ); + DrawControls( thisWindow ); + } else + HideWindow( thisWindow ); + } +} + +void Window::InvalidateAll() { + if ( wid ) { + HIViewSetNeedsDisplay( reinterpret_cast( wid ), true ); + } +} + +void Window::InvalidateRectangle(PRectangle rc) { + if (wid) { + // Create a rectangular region + RgnHandle region = NewRgn(); + SetRectRgn( region, rc.left, rc.top, rc.right, rc.bottom ); + + // Make that region invalid + HIViewSetNeedsDisplayInRegion( reinterpret_cast( wid ), region, true ); + DisposeRgn( region ); + } +} + +void Window::SetFont(Font &) { + // TODO: Do I need to implement this? MSDN: specifies the font that a control is to use when drawing text. +} + +void Window::SetCursor(Cursor curs) { + if (wid) { + // TODO: This isn't really implemented correctly. I should be using + // mouse tracking rectangles to only set the mouse cursor when it is over the control + ThemeCursor cursor; + + switch ( curs ) { + case cursorText: + cursor = kThemeIBeamCursor; + break; + case cursorArrow: + cursor = kThemeArrowCursor; + break; + case cursorWait: + cursor = kThemeWatchCursor; + break; + case cursorHoriz: + cursor = kThemeResizeLeftRightCursor; + break; + case cursorVert: + cursor = kThemeResizeUpDownCursor; + break; + case cursorReverseArrow: + case cursorUp: + default: + cursor = kThemeArrowCursor; + break; + } + + SetThemeCursor( cursor ); + } +} + +void Window::SetTitle(const char *s) { + WindowRef window = GetControlOwner(reinterpret_cast( wid )); + CFStringRef title = CFStringCreateWithCString(kCFAllocatorDefault, s, kCFStringEncodingMacRoman); + SetWindowTitleWithCFString(window, title); + CFRelease(title); +} + +PRectangle Window::GetMonitorRect(Point) { + return PRectangle(); +} + +ListBox::ListBox() {} + +ListBox::~ListBox() {} + +static const OSType scintillaListBoxType = 'sclb'; + +enum { + kItemsPerContainer = 1, + kIconColumn = 'icon', + kTextColumn = 'text' +}; +static SInt32 kScrollBarWidth = 0; + +class LineData { + int *types; + CFStringRef *strings; + int len; + int maximum; +public: + LineData() :types(0), strings(0), len(0), maximum(0) {} + ~LineData() { + Clear(); + } + void Clear() { + delete []types; + types = 0; + for (int i=0; i= maximum) { + if (index >= len) { + int lenNew = (index+1) * 2; + int *typesNew = new int[lenNew]; + CFStringRef *stringsNew = new CFStringRef[lenNew]; + for (int i=0; i( kEventParamMouseButton, typeMouseButton, &inMouseButton ); + + UInt32 inClickCount; + event.GetParameter( kEventParamClickCount, &inClickCount ); + if (inMouseButton == kEventMouseButtonPrimary && inClickCount == 2) { + // handle our single mouse click now + ListBoxImpl* listbox = reinterpret_cast( inUserData ); + const WindowRef window = GetControlOwner(listbox->lb); + const HIViewRef rootView = HIViewGetRoot( window ); + HIViewRef targetView = NULL; + HIViewGetViewForMouseEvent( rootView, inEvent, &targetView ); + if ( targetView == listbox->lb ) + { + if (listbox->doubleClickAction != NULL) { + listbox->doubleClickAction(listbox->doubleClickActionData); + } + } + } + } + } + } + return eventNotHandledErr; +} + +#ifdef DB_TABLE_ROW_HEIGHT +void ListBoxImpl::SetRowHeight(DataBrowserItemID itemID) +{ + // XXX does not seem to have any effect + SetDataBrowserTableViewItemRowHeight(lb, itemID, lineHeight); +} +#endif + +void ListBoxImpl::DrawRow(DataBrowserItemID item, + DataBrowserPropertyID property, + DataBrowserItemState itemState, + const Rect *theRect) +{ + Rect row = *theRect; + row.left = 0; + + ColourPair fore; + + if (itemState == kDataBrowserItemIsSelected) { + long systemVersion; + Gestalt( gestaltSystemVersion, &systemVersion ); + // Panther DB starts using kThemeBrushSecondaryHighlightColor for inactive browser hilighting + if ( (systemVersion >= 0x00001030) && (IsControlActive( lb ) == false) ) + SetThemePen( kThemeBrushSecondaryHighlightColor, 32, true ); + else + //SetThemePen( kThemeBrushPrimaryHighlightColor, 32, true ); + SetThemePen( kThemeBrushAlternatePrimaryHighlightColor, 32, true ); + + PaintRect(&row); + fore = ColourDesired(0xff,0xff,0xff); + } + + int widthPix = xset.GetWidth() + 2; + int pixId = ld.GetType(item - 1); + XPM *pxpm = xset.Get(pixId); + + char s[255]; + GetValue(item - 1, s, 255); + + Surface *surfaceItem = Surface::Allocate(); + if (surfaceItem) { + CGContextRef cgContext; + GrafPtr port; + Rect bounds; + + GetControlBounds(lb, &bounds); + GetPort( &port ); + QDBeginCGContext( port, &cgContext ); + + CGContextSaveGState( cgContext ); + CGContextTranslateCTM(cgContext, 0, bounds.bottom - bounds.top); + CGContextScaleCTM(cgContext, 1.0, -1.0); + + surfaceItem->Init(cgContext, NULL); + + int left = row.left; + if (pxpm) { + PRectangle rc(left + 1, row.top, + left + 1 + widthPix, row.bottom); + pxpm->Draw(surfaceItem, rc); + } + + // draw the text + PRectangle trc(left + 2 + widthPix, row.top, row.right, row.bottom); + int ascent = surfaceItem->Ascent(font) - surfaceItem->InternalLeading(font); + int ytext = trc.top + ascent + 1; + trc.bottom = ytext + surfaceItem->Descent(font) + 1; + surfaceItem->DrawTextTransparent( trc, font, ytext, s, strlen(s), fore.allocated ); + + CGContextRestoreGState( cgContext ); + QDEndCGContext( port, &cgContext ); + delete surfaceItem; + } +} + + +pascal void ListBoxDrawItemCallback(ControlRef browser, DataBrowserItemID item, + DataBrowserPropertyID property, + DataBrowserItemState itemState, + const Rect *theRect, SInt16 gdDepth, + Boolean colorDevice) +{ + if (property != kIconColumn) return; + ListBoxImpl* lbThis = NULL; + OSStatus err; + err = GetControlProperty( browser, scintillaListBoxType, 0, sizeof( lbThis ), NULL, &lbThis ); + // adjust our rect + lbThis->DrawRow(item, property, itemState, theRect); + +} + +void ListBoxImpl::ConfigureDataBrowser() +{ + DataBrowserViewStyle viewStyle; + DataBrowserSelectionFlags selectionFlags; + ::GetDataBrowserViewStyle(lb, &viewStyle); + + ::SetDataBrowserHasScrollBars(lb, false, true); + ::SetDataBrowserListViewHeaderBtnHeight(lb, 0); + ::GetDataBrowserSelectionFlags(lb, &selectionFlags); + ::SetDataBrowserSelectionFlags(lb, selectionFlags |= kDataBrowserSelectOnlyOne); + // if you change the hilite style, also change the style in ListBoxDrawItemCallback + ::SetDataBrowserTableViewHiliteStyle(lb, kDataBrowserTableViewFillHilite); + + Rect insetRect; + ::GetDataBrowserScrollBarInset(lb, &insetRect); + + insetRect.right = kScrollBarWidth - 1; + ::SetDataBrowserScrollBarInset(lb, &insetRect); + + switch (viewStyle) + { + case kDataBrowserListView: + { + DataBrowserListViewColumnDesc iconCol; + iconCol.headerBtnDesc.version = kDataBrowserListViewLatestHeaderDesc; + iconCol.headerBtnDesc.minimumWidth = 0; + iconCol.headerBtnDesc.maximumWidth = maxWidth; + iconCol.headerBtnDesc.titleOffset = 0; + iconCol.headerBtnDesc.titleString = NULL; + iconCol.headerBtnDesc.initialOrder = kDataBrowserOrderIncreasing; + + iconCol.headerBtnDesc.btnFontStyle.flags = kControlUseJustMask; + iconCol.headerBtnDesc.btnFontStyle.just = teFlushLeft; + + iconCol.headerBtnDesc.btnContentInfo.contentType = kControlContentTextOnly; + + iconCol.propertyDesc.propertyID = kIconColumn; + iconCol.propertyDesc.propertyType = kDataBrowserCustomType; + iconCol.propertyDesc.propertyFlags = kDataBrowserListViewSelectionColumn; + + ::AddDataBrowserListViewColumn(lb, &iconCol, kDataBrowserListViewAppendColumn); + } break; + + } +} + +void ListBoxImpl::InstallDataBrowserCustomCallbacks() +{ + DataBrowserCustomCallbacks callbacks; + + callbacks.version = kDataBrowserLatestCustomCallbacks; + verify_noerr(InitDataBrowserCustomCallbacks(&callbacks)); + callbacks.u.v1.drawItemCallback = NewDataBrowserDrawItemUPP(ListBoxDrawItemCallback); + callbacks.u.v1.hitTestCallback = NULL;//NewDataBrowserHitTestUPP(ListBoxHitTestCallback); + callbacks.u.v1.trackingCallback = NULL;//NewDataBrowserTrackingUPP(ListBoxTrackingCallback); + callbacks.u.v1.editTextCallback = NULL; + callbacks.u.v1.dragRegionCallback = NULL; + callbacks.u.v1.acceptDragCallback = NULL; + callbacks.u.v1.receiveDragCallback = NULL; + + SetDataBrowserCustomCallbacks(lb, &callbacks); +} + +void ListBoxImpl::SetFont(Font &font_) { + // Having to do this conversion is LAME + QuartzTextStyle *ts = reinterpret_cast( font_.GetID() ); + ControlFontStyleRec style; + ATSUAttributeValuePtr value; + ATSUFontID fontID; + style.flags = kControlUseFontMask | kControlUseSizeMask | kControlAddToMetaFontMask; + ts->getAttribute( kATSUFontTag, sizeof(fontID), &fontID, NULL ); + ATSUFontIDtoFOND(fontID, &style.font, NULL); + ts->getAttribute( kATSUSizeTag, sizeof(Fixed), &value, NULL ); + style.size = ((SInt16)FixRound((SInt32)value)); + SetControlFontStyle(lb, &style); + +#ifdef DB_TABLE_ROW_HEIGHT + // XXX this doesn't *stick* + ATSUTextMeasurement ascent = ts->getAttribute( kATSUAscentTag ); + ATSUTextMeasurement descent = ts->getAttribute( kATSUDescentTag ); + lineHeight = Fix2Long( ascent ) + Fix2Long( descent ); + SetDataBrowserTableViewRowHeight(lb, lineHeight + lineLeading); +#endif + + // !@&^#%$ we cant copy Font, but we need one for our custom drawing + Str255 fontName255; + char fontName[256]; + FMGetFontFamilyName(style.font, fontName255); + + CFStringRef fontNameCF = ::CFStringCreateWithPascalString( kCFAllocatorDefault, fontName255, kCFStringEncodingMacRoman ); + ::CFStringGetCString( fontNameCF, fontName, (CFIndex)255, kCFStringEncodingMacRoman ); + + font.Create((const char *)fontName, 0, style.size, false, false); +} + +void ListBoxImpl::SetAverageCharWidth(int width) { + aveCharWidth = width; +} + +void ListBoxImpl::SetVisibleRows(int rows) { + desiredVisibleRows = rows; +} + +int ListBoxImpl::GetVisibleRows() const { + // XXX Windows & GTK do this, but it seems incorrect to me. Other logic + // to do with visible rows is essentially the same across platforms. + return desiredVisibleRows; + /* + // This would be more correct + int rows = Length(); + if ((rows == 0) || (rows > desiredVisibleRows)) + rows = desiredVisibleRows; + return rows; + */ +} + +PRectangle ListBoxImpl::GetDesiredRect() { + PRectangle rcDesired = GetPosition(); + + // XXX because setting the line height on the table doesnt + // *stick*, we'll have to suffer and just use whatever + // the table desides is the correct height. + UInt16 itemHeight;// = lineHeight; + GetDataBrowserTableViewRowHeight(lb, &itemHeight); + + int rows = Length(); + if ((rows == 0) || (rows > desiredVisibleRows)) + rows = desiredVisibleRows; + + rcDesired.bottom = itemHeight * rows; + rcDesired.right = rcDesired.left + maxItemWidth + aveCharWidth; + + if (Length() > rows) + rcDesired.right += kScrollBarWidth; + rcDesired.right += IconWidth(); + + // Set the column width + ::SetDataBrowserTableViewColumnWidth (lb, UInt16 (rcDesired.right - rcDesired.left)); + return rcDesired; +} + +void ListBoxImpl::ShowHideScrollbar() { + int rows = Length(); + if (rows > desiredVisibleRows) { + ::SetDataBrowserHasScrollBars(lb, false, true); + } else { + ::SetDataBrowserHasScrollBars(lb, false, false); + } +} + +int ListBoxImpl::IconWidth() { + return xset.GetWidth() + 2; +} + +int ListBoxImpl::CaretFromEdge() { + return 0; +} + +void ListBoxImpl::Clear() { + // passing NULL to "items" arg 4 clears the list + maxItemWidth = 0; + ld.Clear(); + AddDataBrowserItems (lb, kDataBrowserNoItem, 0, NULL, kDataBrowserItemNoProperty); +} + +void ListBoxImpl::Append(char *s, int type) { + int count = Length(); + CFStringRef r = CFStringCreateWithCString(NULL, s, kTextEncodingMacRoman); + ld.Add(count, type, r); + + Scintilla::SurfaceImpl surface; + unsigned int width = surface.WidthText (font, s, strlen (s)); + if (width > maxItemWidth) + maxItemWidth = width; + + DataBrowserItemID items[1]; + items[0] = count + 1; + AddDataBrowserItems (lb, kDataBrowserNoItem, 1, items, kDataBrowserItemNoProperty); + ShowHideScrollbar(); +} + +void ListBoxImpl::SetList(const char* list, char separator, char typesep) { + // XXX copied from PlatGTK, should be in base class + Clear(); + int count = strlen(list) + 1; + char *words = new char[count]; + if (words) { + memcpy(words, list, count); + char *startword = words; + 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 + i + 1; + numword = NULL; + } else if (words[i] == typesep) { + numword = words + i; + } + } + if (startword) { + if (numword) + *numword = '\0'; + Append(startword, numword?atoi(numword + 1):-1); + } + delete []words; + } +} + +int ListBoxImpl::Length() { + UInt32 numItems = 0; + GetDataBrowserItemCount(lb, kDataBrowserNoItem, false, kDataBrowserItemAnyState, &numItems); + return (int)numItems; +} + +void ListBoxImpl::Select(int n) { + DataBrowserItemID items[1]; + items[0] = n + 1; + SetDataBrowserSelectedItems(lb, 1, items, kDataBrowserItemsAssign); + RevealDataBrowserItem(lb, items[0], kIconColumn, kDataBrowserRevealOnly); + // force update on selection + Draw1Control(lb); +} + +int ListBoxImpl::GetSelection() { + Handle selectedItems = NewHandle(0); + GetDataBrowserItems(lb, kDataBrowserNoItem, true, kDataBrowserItemIsSelected, selectedItems); + UInt32 numSelectedItems = GetHandleSize(selectedItems)/sizeof(DataBrowserItemID); + if (numSelectedItems == 0) { + return -1; + } + HLock( selectedItems ); + DataBrowserItemID *individualItem = (DataBrowserItemID*)( *selectedItems ); + DataBrowserItemID selected[numSelectedItems]; + selected[0] = *individualItem; + HUnlock( selectedItems ); + return selected[0] - 1; +} + +int ListBoxImpl::Find(const char *prefix) { + int count = Length(); + char s[255]; + for (int i = 0; i < count; i++) { + GetValue(i, s, 255); + if (s[0] != NULL && (0 == strncmp(prefix, s, strlen(prefix)))) { + return i; + } + } + return - 1; +} + +void ListBoxImpl::GetValue(int n, char *value, int len) { + CFStringRef textString = ld.GetString(n); + if (textString == NULL) { + value[0] = '\0'; + return; + } + CFIndex numUniChars = CFStringGetLength( textString ); + + // XXX how do we know the encoding of the listbox? + CFStringEncoding encoding = kCFStringEncodingUTF8; //( IsUnicodeMode() ? kCFStringEncodingUTF8 : kCFStringEncodingASCII); + CFIndex maximumByteLength = CFStringGetMaximumSizeForEncoding( numUniChars, encoding ) + 1; + char* text = new char[maximumByteLength]; + CFIndex usedBufferLength = 0; + CFStringGetBytes( textString, CFRangeMake( 0, numUniChars ), encoding, + '?', false, reinterpret_cast( text ), + maximumByteLength, &usedBufferLength ); + text[usedBufferLength] = '\0'; // null terminate the ASCII/UTF8 string + + if (text && len > 0) { + strncpy(value, text, len); + value[len - 1] = '\0'; + } else { + value[0] = '\0'; + } + delete []text; +} + +void ListBoxImpl::Sort() { + // TODO: Implement this + fprintf(stderr, "ListBox::Sort\n"); +} + +void ListBoxImpl::RegisterImage(int type, const char *xpm_data) { + xset.Add(type, xpm_data); +} + +void ListBoxImpl::ClearRegisteredImages() { + xset.Clear(); +} + +Menu::Menu() : mid(0) { } + +void Menu::CreatePopUp() { + // TODO: Could I just feed a constant menu ID parameter, or does + // it really need to be unique? + static int nextMenuID = 1; + Destroy(); + OSStatus err; + err = CreateNewMenu( nextMenuID++, 0, reinterpret_cast( &mid ) ); +} + +void Menu::Destroy() { + if ( mid != NULL ) + { + ReleaseMenu( reinterpret_cast( mid ) ); + mid = NULL; + } +} + +void Menu::Show(Point pt, Window &) { + UInt32 userSelection = 0; + SInt16 menuId = 0; + MenuItemIndex menuItem = 0; + ::Point globalPoint; + globalPoint.h = pt.x; + globalPoint.v = pt.y; + OSStatus err; + err = ContextualMenuSelect( reinterpret_cast( mid ), globalPoint, + false, kCMHelpItemRemoveHelp, NULL, + NULL, &userSelection, + &menuId, + &menuItem + ); +} + +// TODO: Consider if I should be using GetCurrentEventTime instead of gettimeoday +ElapsedTime::ElapsedTime() { + struct timeval curTime; + int retVal; + retVal = gettimeofday( &curTime, NULL ); + + bigBit = curTime.tv_sec; + littleBit = curTime.tv_usec; +} + +double ElapsedTime::Duration(bool reset) { + struct timeval curTime; + int retVal; + retVal = 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; +} + +ColourDesired Platform::Chrome() { + RGBColor c; + GetThemeBrushAsColor(kThemeBrushButtonActiveDarkShadow , 24, true, &c); + return ColourDesired(c.red>>8, c.green>>8, c.blue>>8); +} + +ColourDesired Platform::ChromeHighlight() { + RGBColor c; + GetThemeBrushAsColor(kThemeBrushButtonInactiveLightShadow , 24, true, &c); + return ColourDesired(c.red>>8, c.green>>8, c.blue>>8); +} + +static Str255 PlatformDefaultFontName; +const char *Platform::DefaultFont() { + long fid = HighShortFromLong(GetScriptVariable(smCurrentScript, smScriptAppFondSize)); + FMGetFontFamilyName(fid, PlatformDefaultFontName); + char* defaultFontName = (char*) PlatformDefaultFontName; + defaultFontName[defaultFontName[0]+1] = 0; + ++defaultFontName; + + return defaultFontName; +} + +int Platform::DefaultFontSize() { + return LowShortFromLong(GetScriptVariable(smCurrentScript, smScriptAppFondSize)); +} + +unsigned int Platform::DoubleClickTime() { + // Convert from ticks to milliseconds. I think it would be better to use the events to tell us + // when we have a double and triple click, but what do I know? + return static_cast( TicksToEventTime( GetDblTime() ) / kEventDurationMillisecond ); +} + +bool Platform::MouseButtonBounce() { + return false; +} + +bool Platform::IsKeyDown(int keyCode) { + return false; + // TODO: Map Scintilla/Windows key codes to Mac OS X key codes + // TODO: Do I need this? + /* + // Inspired by code at: http://www.sover.net/~jams/Morgan/docs/GameInputMethods.txt + + // Get the keys + KeyMap keys; + GetKeys( keys ); + + // Calculate the key map index + long keyMapIndex = keys[keyCode/8]; + // Calculate the individual bit to check + short bitToCheck = keyCode % 8; + // Check the status of the key + return ( keyMapIndex >> bitToCheck ) & 0x01; + */ +} + +long Platform::SendScintilla(WindowID w, unsigned int msg, unsigned long wParam, long lParam) { + return scintilla_send_message( w, msg, wParam, lParam ); +} + +bool Platform::IsDBCSLeadByte(int /*codePage*/, char /*ch*/) { + // TODO: Implement this for code pages != UTF-8 + return false; +} + +int Platform::DBCSCharLength(int /*codePage*/, const char* /*s*/) { + // TODO: Implement this for code pages != UTF-8 + return 1; +} + +int Platform::DBCSCharMaxLength() { + // TODO: Implement this for code pages != UTF-8 + //return CFStringGetMaximumSizeForEncoding( 1, CFStringEncoding encoding ); + return 2; +} + +// These are utility functions not really tied to a platform +int Platform::Minimum(int a, int b) { + if (a < b) + return a; + else + return b; +} + +int Platform::Maximum(int a, int b) { + if (a > b) + return a; + else + return b; +} + +//#define TRACE +#ifdef TRACE + +void Platform::DebugDisplay(const char *s) { + fprintf( stderr, s ); +} + +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); +} + +#else + +void Platform::DebugDisplay(const char *) {} + +void Platform::DebugPrintf(const char *, ...) {} + +#endif + +// Not supported for GTK+ +static bool assertionPopUps = true; + +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]; + sprintf(buffer, "Assertion [%s] failed at %s %d", c, file, line); + strcat(buffer, "\r\n"); + Platform::DebugDisplay(buffer); +#ifdef DEBUG + // 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; +} diff --git a/scintilla/macosx/PlatMacOSX.h b/scintilla/macosx/PlatMacOSX.h new file mode 100644 index 00000000..e2dcb351 --- /dev/null +++ b/scintilla/macosx/PlatMacOSX.h @@ -0,0 +1,99 @@ +#ifndef PLATMACOSX_H +#define PLATMACOSX_H + +#include +#include +#include + +#include + +#include + +#include +#include "QuartzTextLayout.h" + +#include "Platform.h" +#include "Scintilla.h" + +namespace Scintilla { + +class SurfaceImpl : public Surface { +private: + bool unicodeMode; + float x; + float y; + + CGContextRef gc; + + + /** The text layout instance */ + QuartzTextLayout* textLayout; + /** If the surface is a bitmap context, contains a reference to the bitmap data. */ + 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 allocated colour. */ + void FillColour( const ColourAllocated& 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; +public: + SurfaceImpl(); + ~SurfaceImpl(); + + void Init(WindowID wid); + void Init(SurfaceID sid, WindowID wid); + void InitPixMap(int width, int height, Surface *surface_, WindowID wid); + CGContextRef GetContext() { return gc; } + + void Release(); + bool Initialised(); + void PenColour(ColourAllocated fore); + + /** 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(); + int DeviceHeightFont(int points); + void MoveTo(int x_, int y_); + void LineTo(int x_, int y_); + void Polygon(Scintilla::Point *pts, int npts, ColourAllocated fore, ColourAllocated back); + void RectangleDraw(PRectangle rc, ColourAllocated fore, ColourAllocated back); + void FillRectangle(PRectangle rc, ColourAllocated back); + void FillRectangle(PRectangle rc, Surface &surfacePattern); + void RoundedRectangle(PRectangle rc, ColourAllocated fore, ColourAllocated back); + void AlphaRectangle(PRectangle rc, int cornerSize, ColourAllocated fill, int alphaFill, + ColourAllocated outline, int alphaOutline, int flags); + void Ellipse(PRectangle rc, ColourAllocated fore, ColourAllocated back); + void Copy(PRectangle rc, Scintilla::Point from, Surface &surfaceSource); + + void DrawTextNoClip(PRectangle rc, Font &font_, int ybase, const char *s, int len, ColourAllocated fore, ColourAllocated back); + void DrawTextClipped(PRectangle rc, Font &font_, int ybase, const char *s, int len, ColourAllocated fore, ColourAllocated back); + void DrawTextTransparent(PRectangle rc, Font &font_, int ybase, const char *s, int len, ColourAllocated fore); + void MeasureWidths(Font &font_, const char *s, int len, int *positions); + int WidthText(Font &font_, const char *s, int len); + int WidthChar(Font &font_, char ch); + int Ascent(Font &font_); + int Descent(Font &font_); + int InternalLeading(Font &font_); + int ExternalLeading(Font &font_); + int Height(Font &font_); + int AverageCharWidth(Font &font_); + + int SetPalette(Scintilla::Palette *pal, bool inBackGround); + void SetClip(PRectangle rc); + void FlushCachedState(); + + void SetUnicodeMode(bool unicodeMode_); + void SetDBCSMode(int codePage); +}; + +} + +#endif diff --git a/scintilla/macosx/QuartzTextLayout.h b/scintilla/macosx/QuartzTextLayout.h new file mode 100644 index 00000000..02906325 --- /dev/null +++ b/scintilla/macosx/QuartzTextLayout.h @@ -0,0 +1,141 @@ +/* + * QuartzTextLayout.h + * + * Original Code by Evan Jones on Wed Oct 02 2002. + * Contributors: + * Shane Caraveo, ActiveState + * Bernd Paradies, Adobe + * + */ + +#ifndef _QUARTZ_TEXT_LAYOUT_H +#define _QUARTZ_TEXT_LAYOUT_H + +#include + +#include "QuartzTextStyle.h" + +class QuartzTextLayout +{ +public: + /** Create a text layout for drawing on the specified context. */ + QuartzTextLayout( CGContextRef context ) : layout( NULL ), unicode_string( NULL ), unicode_length( 0 ) + { + OSStatus err = ATSUCreateTextLayout( &layout ); + if (0 != err) + layout = NULL; + + setContext(context); + + ATSUAttributeTag tag = kATSULineLayoutOptionsTag; + ByteCount size = sizeof( ATSLineLayoutOptions ); + ATSLineLayoutOptions rendering = kATSLineUseDeviceMetrics; //| kATSLineFractDisable | kATSLineUseQDRendering + ATSUAttributeValuePtr valuePtr = &rendering; + err = ATSUSetLayoutControls( layout, 1, &tag, &size, &valuePtr ); + } + + ~QuartzTextLayout() + { + if (NULL != layout) + ATSUDisposeTextLayout( layout ); + layout = NULL; + + if ( unicode_string != NULL ) + { + delete[] unicode_string; + unicode_string = NULL; + unicode_length = 0; + } + } + + /** Assign a string to the text layout object. */ + // TODO: Create a UTF8 version + // TODO: Optimise the ASCII version by not copying so much + OSStatus setText( const UInt8* buffer, size_t byteLength, CFStringEncoding encoding ) + { + if (NULL == layout) + return -1; + CFStringRef str = CFStringCreateWithBytes( NULL, buffer, byteLength, encoding, false ); + if (!str) + return -1; + + unicode_length = CFStringGetLength( str ); + if (unicode_string) + delete[] unicode_string; + unicode_string = new UniChar[ unicode_length ]; + CFStringGetCharacters( str, CFRangeMake( 0, unicode_length ), unicode_string ); + + CFRelease( str ); + str = NULL; + + OSStatus err; + err = ATSUSetTextPointerLocation( layout, unicode_string, kATSUFromTextBeginning, kATSUToTextEnd, unicode_length ); + if( err != noErr ) return err; + + // Turn on the default font fallbacks + return ATSUSetTransientFontMatching( layout, true ); + } + + inline void setText( const UInt8* buffer, size_t byteLength, const QuartzTextStyle& r ) + { + this->setText( buffer, byteLength, kCFStringEncodingUTF8 ); + ATSUSetRunStyle( layout, r.getATSUStyle(), 0, unicode_length ); + } + + /** Apply the specified text style on the entire range of text. */ + void setStyle( const QuartzTextStyle& style ) + { + ATSUSetRunStyle( layout, style.getATSUStyle(), kATSUFromTextBeginning, kATSUToTextEnd ); + } + + /** Draw the text layout into the current CGContext at the specified position, flipping the CGContext's Y axis if required. + * @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. + * @param flipTextYAxis If true, the CGContext's Y axis will be flipped before drawing the text, and restored afterwards. Use this when drawing in an HIView's CGContext, where the origin is the top left corner. */ + void draw( float x, float y, bool flipTextYAxis = false ) + { + if (NULL == layout || 0 == unicode_length) + return; + if ( flipTextYAxis ) + { + CGContextSaveGState( gc ); + CGContextScaleCTM( gc, 1.0, -1.0 ); + y = -y; + } + + OSStatus err; + err = ATSUDrawText( layout, kATSUFromTextBeginning, kATSUToTextEnd, X2Fix( x ), X2Fix( y ) ); + + if ( flipTextYAxis ) CGContextRestoreGState( gc ); + } + + /** Sets a single text layout control on the ATSUTextLayout object. + * @param tag The control to set. + * @param size The size of the parameter pointed to by value. + * @param value A pointer to the new value for the control. + */ + void setControl( ATSUAttributeTag tag, ByteCount size, ATSUAttributeValuePtr value ) + { + ATSUSetLayoutControls( layout, 1, &tag, &size, &value ); + } + + ATSUTextLayout getLayout() { + return layout; + } + + inline CFIndex getLength() const { return unicode_length; } + inline void setContext (CGContextRef context) + { + gc = context; + if (NULL != layout) + setControl( kATSUCGContextTag, sizeof( gc ), &gc ); + } + +private: + ATSUTextLayout layout; + UniChar* unicode_string; + int unicode_length; + CGContextRef gc; +}; + +#endif diff --git a/scintilla/macosx/QuartzTextStyle.h b/scintilla/macosx/QuartzTextStyle.h new file mode 100644 index 00000000..171281f9 --- /dev/null +++ b/scintilla/macosx/QuartzTextStyle.h @@ -0,0 +1,94 @@ +/* + * QuartzTextStyle.h + * wtf + * + * Created by Evan Jones on Wed Oct 02 2002. + * Copyright (c) 2002 __MyCompanyName__. All rights reserved. + * + */ + +#include + +#ifndef _QUARTZ_TEXT_STYLE_H +#define _QUARTZ_TEXT_STYLE_H + +#include "QuartzTextStyleAttribute.h" + +class QuartzTextStyle +{ +public: + QuartzTextStyle() + { + ATSUCreateStyle( &style ); + } + + ~QuartzTextStyle() + { + if ( style != NULL ) + ATSUDisposeStyle( style ); + style = NULL; + } + + void setAttribute( ATSUAttributeTag tag, ByteCount size, ATSUAttributeValuePtr value ) + { + ATSUSetAttributes( style, 1, &tag, &size, &value ); + } + + void setAttribute( QuartzTextStyleAttribute& attribute ) + { + setAttribute( attribute.getTag(), attribute.getSize(), attribute.getValuePtr() ); + } + + void getAttribute( ATSUAttributeTag tag, ByteCount size, ATSUAttributeValuePtr value, ByteCount* actualSize ) + { + ATSUGetAttribute( style, tag, size, value, actualSize ); + } + + template + T getAttribute( ATSUAttributeTag tag ) + { + T value; + ByteCount actualSize; + ATSUGetAttribute( style, tag, sizeof( T ), &value, &actualSize ); + return value; + } + + // TODO: Is calling this actually faster than calling setAttribute multiple times? + void setAttributes( QuartzTextStyleAttribute* attributes[], int number ) + { + // Create the parallel arrays and initialize them properly + ATSUAttributeTag* tags = new ATSUAttributeTag[ number ]; + ByteCount* sizes = new ByteCount[ number ]; + ATSUAttributeValuePtr* values = new ATSUAttributeValuePtr[ number ]; + + for ( int i = 0; i < number; ++ i ) + { + tags[i] = attributes[i]->getTag(); + sizes[i] = attributes[i]->getSize(); + values[i] = attributes[i]->getValuePtr(); + } + + ATSUSetAttributes( style, number, tags, sizes, values ); + + // Free the arrays that were allocated + delete[] tags; + delete[] sizes; + delete[] values; + } + + void setFontFeature( ATSUFontFeatureType featureType, ATSUFontFeatureSelector selector ) + { + ATSUSetFontFeatures( style, 1, &featureType, &selector ); + } + + const ATSUStyle& getATSUStyle() const + { + return style; + } + +private: + ATSUStyle style; +}; + +#endif + diff --git a/scintilla/macosx/QuartzTextStyleAttribute.h b/scintilla/macosx/QuartzTextStyleAttribute.h new file mode 100644 index 00000000..9ebbe0d8 --- /dev/null +++ b/scintilla/macosx/QuartzTextStyleAttribute.h @@ -0,0 +1,144 @@ +/* + * QuartzTextStyleAttribute.h + * + * Original Code by Evan Jones on Wed Oct 02 2002. + * Contributors: + * Shane Caraveo, ActiveState + * Bernd Paradies, Adobe + * + */ + + +#include + +#ifndef _QUARTZ_TEXT_STYLE_ATTRIBUTE_H +#define _QUARTZ_TEXT_STYLE_ATTRIBUTE_H + +class QuartzTextStyleAttribute +{ +public: + QuartzTextStyleAttribute() {} + virtual ~QuartzTextStyleAttribute() {} + virtual ByteCount getSize() const = 0; + virtual ATSUAttributeValuePtr getValuePtr() = 0; + virtual ATSUAttributeTag getTag() const = 0; +}; + +class QuartzTextSize : public QuartzTextStyleAttribute +{ +public: + QuartzTextSize( float points ) + { + size = X2Fix( points ); + } + + ByteCount getSize() const + { + return sizeof( size ); + } + + ATSUAttributeValuePtr getValuePtr() + { + return &size; + } + + ATSUAttributeTag getTag() const + { + return kATSUSizeTag; + } + +private: + Fixed size; +}; + +class QuartzTextStyleAttributeBoolean : public QuartzTextStyleAttribute +{ +public: + QuartzTextStyleAttributeBoolean( bool newVal ) : value( newVal ) {} + + ByteCount getSize() const + { + return sizeof( value ); + } + ATSUAttributeValuePtr getValuePtr() + { + return &value; + } + + virtual ATSUAttributeTag getTag() const = 0; + +private: + Boolean value; +}; + +class QuartzTextBold : public QuartzTextStyleAttributeBoolean +{ +public: + QuartzTextBold( bool newVal ) : QuartzTextStyleAttributeBoolean( newVal ) {} + ATSUAttributeTag getTag() const + { + return kATSUQDBoldfaceTag; + } +}; + +class QuartzTextItalic : public QuartzTextStyleAttributeBoolean +{ +public: + QuartzTextItalic( bool newVal ) : QuartzTextStyleAttributeBoolean( newVal ) {} + ATSUAttributeTag getTag() const + { + return kATSUQDItalicTag; + } +}; + +class QuartzTextUnderline : public QuartzTextStyleAttributeBoolean +{ +public: + QuartzTextUnderline( bool newVal ) : QuartzTextStyleAttributeBoolean( newVal ) {} + ATSUAttributeTag getTag() const { + return kATSUQDUnderlineTag; + } +}; + +class QuartzFont : public QuartzTextStyleAttribute +{ +public: + /** Create a font style from a name. */ + QuartzFont( const char* name, int length ) + { + assert( name != NULL && length > 0 && name[length] == '\0' ); + // try to create font + OSStatus err = ATSUFindFontFromName( const_cast( name ), length, kFontFullName, (unsigned) kFontNoPlatform, kFontRomanScript, (unsigned) kFontNoLanguage, &fontid ); + + // need a fallback if font isn't installed + if( err != noErr || fontid == kATSUInvalidFontID ) + ::ATSUFindFontFromName( "Lucida Grande", 13, kFontFullName, (unsigned) kFontNoPlatform, kFontRomanScript, (unsigned) kFontNoLanguage, &fontid ); + } + + ByteCount getSize() const + { + return sizeof( fontid ); + } + + ATSUAttributeValuePtr getValuePtr() + { + return &fontid; + } + + ATSUAttributeTag getTag() const + { + return kATSUFontTag; + } + + ATSUFontID getFontID() const + { + return fontid; + } + +private: + ATSUFontID fontid; +}; + + +#endif + diff --git a/scintilla/macosx/SciTest/English.lproj/InfoPlist.strings b/scintilla/macosx/SciTest/English.lproj/InfoPlist.strings new file mode 100644 index 00000000..42b037c0 Binary files /dev/null and b/scintilla/macosx/SciTest/English.lproj/InfoPlist.strings differ diff --git a/scintilla/macosx/SciTest/English.lproj/main.nib/classes.nib b/scintilla/macosx/SciTest/English.lproj/main.nib/classes.nib new file mode 100644 index 00000000..3f89d050 --- /dev/null +++ b/scintilla/macosx/SciTest/English.lproj/main.nib/classes.nib @@ -0,0 +1,4 @@ +{ +IBClasses = (); +IBVersion = 1; +} diff --git a/scintilla/macosx/SciTest/English.lproj/main.nib/info.nib b/scintilla/macosx/SciTest/English.lproj/main.nib/info.nib new file mode 100644 index 00000000..aae9f6b7 --- /dev/null +++ b/scintilla/macosx/SciTest/English.lproj/main.nib/info.nib @@ -0,0 +1,19 @@ + + + + + IBFramework Version + 345.0 + IBOldestOS + 3 + IBOpenObjects + + 29 + 166 + + IBSystem Version + 7B44 + targetFramework + IBCarbonFramework + + diff --git a/scintilla/macosx/SciTest/English.lproj/main.nib/objects.xib b/scintilla/macosx/SciTest/English.lproj/main.nib/objects.xib new file mode 100644 index 00000000..e78d4aa4 --- /dev/null +++ b/scintilla/macosx/SciTest/English.lproj/main.nib/objects.xib @@ -0,0 +1,271 @@ + + + IBCarbonFramework + + NSApplication + + + + main + + + Foo + + Foo + + + About Foo + 0 + abou + + + _NSAppleMenu + + + + File + + File + + + New + n + new + + + Open… + o + open + + + TRUE + + + Close + w + clos + + + Save + s + save + + + Save As… + S + svas + + + Revert + r + rvrt + + + TRUE + + + Page Setup… + P + page + + + Print… + p + prnt + + + + + + Edit + + Edit + + + Undo + z + undo + + + Redo + Z + redo + + + TRUE + + + Cut + x + cut + + + Copy + c + copy + + + Paste + v + past + + + Delete + clea + + + Select All + a + sall + + + TRUE + + + Special Characters… + chrp + + + + + + Window + + Window + + + Zoom Window + zoom + + + TRUE + Minimize Window + m + mini + + + TRUE + Minimize All Windows + m + 1572864 + mina + + + TRUE + + + TRUE + Bring All to Front + bfrt + + + TRUE + Arrange in Front + 1572864 + frnt + + + _NSWindowsMenu + + + + _NSMainMenu + + + + + + + + + + + + + + + + + + + + + + + + + 204 300 564 780 + Window + + 0 0 360 480 + 0 0 480 360 + + FALSE + TRUE + TRUE + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Files Owner + + MainWindow + + MenuBar + + + 200 + diff --git a/scintilla/macosx/SciTest/Info.plist b/scintilla/macosx/SciTest/Info.plist new file mode 100644 index 00000000..6a665130 --- /dev/null +++ b/scintilla/macosx/SciTest/Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + SciTest + CFBundleIconFile + + CFBundleIdentifier + com.apple.myCarbonApp + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + 1.0 + CSResourcesFileMapped + + + diff --git a/scintilla/macosx/SciTest/SciTest.xcode/project.pbxproj b/scintilla/macosx/SciTest/SciTest.xcode/project.pbxproj new file mode 100644 index 00000000..c771cc54 --- /dev/null +++ b/scintilla/macosx/SciTest/SciTest.xcode/project.pbxproj @@ -0,0 +1,289 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 42; + objects = { + +/* Begin PBXBuildFile section */ + 3002B123087DCEC600CEAF79 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3002B122087DCEC600CEAF79 /* main.cpp */; }; + 30973FF8086B7F4F0088809C /* libscintilla.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 30973FF7086B7F4F0088809C /* libscintilla.a */; }; + 8D0C4E8D0486CD37000505A6 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 0867D6AAFE840B52C02AAC07 /* InfoPlist.strings */; }; + 8D0C4E8E0486CD37000505A6 /* main.nib in Resources */ = {isa = PBXBuildFile; fileRef = 02345980000FD03B11CA0E72 /* main.nib */; }; + 8D0C4E920486CD37000505A6 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 20286C33FDCF999611CA2CEA /* Carbon.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 0867D6ABFE840B52C02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = ""; }; + 1870340FFE93FCAF11CA0CD7 /* English */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = English; path = English.lproj/main.nib; sourceTree = ""; }; + 20286C33FDCF999611CA2CEA /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = /System/Library/Frameworks/Carbon.framework; sourceTree = ""; }; + 3002B122087DCEC600CEAF79 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = ""; }; + 30973FF7086B7F4F0088809C /* libscintilla.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libscintilla.a; path = ../../bin/libscintilla.a; sourceTree = SOURCE_ROOT; }; + 32DBCF6D0370B57F00C91783 /* SciTest_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SciTest_Prefix.pch; sourceTree = ""; }; + 4A9504C8FFE6A3BC11CA0CBA /* ApplicationServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ApplicationServices.framework; path = /System/Library/Frameworks/ApplicationServices.framework; sourceTree = ""; }; + 4A9504CAFFE6A41611CA0CBA /* CoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreServices.framework; path = /System/Library/Frameworks/CoreServices.framework; sourceTree = ""; }; + 8D0C4E960486CD37000505A6 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; }; + 8D0C4E970486CD37000505A6 /* SciTest.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SciTest.app; sourceTree = BUILT_PRODUCTS_DIR; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 8D0C4E910486CD37000505A6 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 8D0C4E920486CD37000505A6 /* Carbon.framework in Frameworks */, + 30973FF8086B7F4F0088809C /* libscintilla.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 195DF8CFFE9D517E11CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 8D0C4E970486CD37000505A6 /* SciTest.app */, + ); + name = Products; + sourceTree = ""; + }; + 20286C29FDCF999611CA2CEA /* SciTest */ = { + isa = PBXGroup; + children = ( + 20286C2AFDCF999611CA2CEA /* Sources */, + 20286C2CFDCF999611CA2CEA /* Resources */, + 20286C32FDCF999611CA2CEA /* External Frameworks and Libraries */, + 195DF8CFFE9D517E11CA2CBB /* Products */, + ); + name = SciTest; + sourceTree = ""; + }; + 20286C2AFDCF999611CA2CEA /* Sources */ = { + isa = PBXGroup; + children = ( + 3002B122087DCEC600CEAF79 /* main.cpp */, + 32DBCF6D0370B57F00C91783 /* SciTest_Prefix.pch */, + ); + name = Sources; + sourceTree = ""; + }; + 20286C2CFDCF999611CA2CEA /* Resources */ = { + isa = PBXGroup; + children = ( + 8D0C4E960486CD37000505A6 /* Info.plist */, + 0867D6AAFE840B52C02AAC07 /* InfoPlist.strings */, + 02345980000FD03B11CA0E72 /* main.nib */, + ); + name = Resources; + sourceTree = ""; + }; + 20286C32FDCF999611CA2CEA /* External Frameworks and Libraries */ = { + isa = PBXGroup; + children = ( + 30973FF7086B7F4F0088809C /* libscintilla.a */, + 20286C33FDCF999611CA2CEA /* Carbon.framework */, + 4A9504CAFFE6A41611CA0CBA /* CoreServices.framework */, + 4A9504C8FFE6A3BC11CA0CBA /* ApplicationServices.framework */, + ); + name = "External Frameworks and Libraries"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 8D0C4E890486CD37000505A6 /* SciTest */ = { + isa = PBXNativeTarget; + buildConfigurationList = 304E977D0C0519E500702100 /* Build configuration list for PBXNativeTarget "SciTest" */; + buildPhases = ( + 8D0C4E8C0486CD37000505A6 /* Resources */, + 8D0C4E8F0486CD37000505A6 /* Sources */, + 8D0C4E910486CD37000505A6 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = SciTest; + productInstallPath = "$(HOME)/Applications"; + productName = SciTest; + productReference = 8D0C4E970486CD37000505A6 /* SciTest.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 20286C28FDCF999611CA2CEA /* Project object */ = { + isa = PBXProject; + buildConfigurationList = 304E97810C0519E500702100 /* Build configuration list for PBXProject "SciTest" */; + compatibilityVersion = "Xcode 2.4"; + hasScannedForEncodings = 1; + mainGroup = 20286C29FDCF999611CA2CEA /* SciTest */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 8D0C4E890486CD37000505A6 /* SciTest */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 8D0C4E8C0486CD37000505A6 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 8D0C4E8D0486CD37000505A6 /* InfoPlist.strings in Resources */, + 8D0C4E8E0486CD37000505A6 /* main.nib in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 8D0C4E8F0486CD37000505A6 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 3002B123087DCEC600CEAF79 /* main.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 02345980000FD03B11CA0E72 /* main.nib */ = { + isa = PBXVariantGroup; + children = ( + 1870340FFE93FCAF11CA0CD7 /* English */, + ); + name = main.nib; + sourceTree = ""; + }; + 0867D6AAFE840B52C02AAC07 /* InfoPlist.strings */ = { + isa = PBXVariantGroup; + children = ( + 0867D6ABFE840B52C02AAC07 /* English */, + ); + name = InfoPlist.strings; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 304E977E0C0519E500702100 /* Development */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = SciTest_Prefix.pch; + HEADER_SEARCH_PATHS = ( + .., + ../../include, + ../../src, + ); + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "$(HOME)/Applications"; + LIBRARY_SEARCH_PATHS = ../../bin; + OTHER_CFLAGS = ( + "-DSCI_NAMESPACE=1", + "-DSCI_NAMESPACE", + "-DMACOSX", + "-DSCI_LEXER", + ); + OTHER_CPLUSPLUSFLAGS = ( + "-DSCI_NAMESPACE=1", + "-DSCI_NAMESPACE", + "-DMACOSX", + "-DSCI_LEXER", + ); + PRODUCT_NAME = SciTest; + WRAPPER_EXTENSION = app; + ZERO_LINK = YES; + }; + name = Development; + }; + 304E977F0C0519E500702100 /* Deployment */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = YES; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = SciTest_Prefix.pch; + HEADER_SEARCH_PATHS = ( + .., + ../../include, + ../../src, + ); + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "$(HOME)/Applications"; + LIBRARY_SEARCH_PATHS = ""; + PRODUCT_NAME = SciTest; + WRAPPER_EXTENSION = app; + ZERO_LINK = NO; + }; + name = Deployment; + }; + 304E97800C0519E500702100 /* Default */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = SciTest_Prefix.pch; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "$(HOME)/Applications"; + LIBRARY_SEARCH_PATHS = ""; + PRODUCT_NAME = SciTest; + WRAPPER_EXTENSION = app; + }; + name = Default; + }; + 304E97820C0519E500702100 /* Development */ = { + isa = XCBuildConfiguration; + buildSettings = { + }; + name = Development; + }; + 304E97830C0519E500702100 /* Deployment */ = { + isa = XCBuildConfiguration; + buildSettings = { + }; + name = Deployment; + }; + 304E97840C0519E500702100 /* Default */ = { + isa = XCBuildConfiguration; + buildSettings = { + }; + name = Default; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 304E977D0C0519E500702100 /* Build configuration list for PBXNativeTarget "SciTest" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 304E977E0C0519E500702100 /* Development */, + 304E977F0C0519E500702100 /* Deployment */, + 304E97800C0519E500702100 /* Default */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Default; + }; + 304E97810C0519E500702100 /* Build configuration list for PBXProject "SciTest" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 304E97820C0519E500702100 /* Development */, + 304E97830C0519E500702100 /* Deployment */, + 304E97840C0519E500702100 /* Default */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Default; + }; +/* End XCConfigurationList section */ + }; + rootObject = 20286C28FDCF999611CA2CEA /* Project object */; +} diff --git a/scintilla/macosx/SciTest/SciTest_Prefix.pch b/scintilla/macosx/SciTest/SciTest_Prefix.pch new file mode 100644 index 00000000..33b85484 --- /dev/null +++ b/scintilla/macosx/SciTest/SciTest_Prefix.pch @@ -0,0 +1,5 @@ +// +// Prefix header for all source files of the 'SciTest' target in the 'SciTest' project. +// + +#include diff --git a/scintilla/macosx/SciTest/main.cpp b/scintilla/macosx/SciTest/main.cpp new file mode 100644 index 00000000..21713718 --- /dev/null +++ b/scintilla/macosx/SciTest/main.cpp @@ -0,0 +1,255 @@ +// +// main.c +// SciTest +// +// Copyright (c) 2005-2006 ActiveState Software Inc. +// All rights reserved. +// +// Created by Shane Caraveo on 3/20/05. +// + +#include +#include "TView.h" +#include "TCarbonEvent.h" +#include "ScintillaMacOSX.h" + +extern "C" HIViewRef scintilla_new(void); + +const HILayoutInfo kBindToParentLayout = { + kHILayoutInfoVersionZero, + { { NULL, kHILayoutBindTop }, { NULL, kHILayoutBindLeft }, { NULL, kHILayoutBindBottom }, { NULL, kHILayoutBindRight } }, + { { NULL, kHILayoutScaleAbsolute, 0 }, { NULL, kHILayoutScaleAbsolute, 0 } }, + { { NULL, kHILayoutPositionTop, 0 }, { NULL, kHILayoutPositionLeft, 0 } } +}; + +using namespace Scintilla; + +/* XPM */ +static char *ac_class[] = { +/* columns rows colors chars-per-pixel */ +"18 12 24 1", +" c black", +". c #403030", +"X c #473636", +"o c #4E3C3C", +"O c #474141", +"+ c #5F4C4C", +"@ c #756362", +"# c #98342C", +"$ c #A0392F", +"% c #B24235", +"& c #B2443C", +"* c #B34E3E", +"= c #B54E44", +"- c #B65146", +"; c #B7584F", +": c #B8554C", +"> c #B75A50", +", c #B95852", +"< c #B96259", +"1 c #B89B9B", +"2 c #BCA0A0", +"3 c #C1A5A5", +"4 c gray100", +"5 c None", +/* pixels */ +"555555555555555555", +"55553$$$$$$$#@5555", +"55552;%&&==;=o5555", +"55551>&&*=;:=.5555", +"55551>&*=;::=.5555", +"55551>*==:::-X5555", +"55551>==:::,;.5555", +"55551<==:;,<>.5555", +"55551<;;;;<<;.5555", +"55551;-==;;;;X5555", +"55555+XX..X..O5555", +"555555555555555555" +}; + +const char keywords[]="and and_eq asm auto bitand bitor bool break " +"case catch char class compl const const_cast continue " +"default delete do double dynamic_cast else enum explicit export extern false float for " +"friend goto if inline int long mutable namespace new not not_eq " +"operator or or_eq private protected public " +"register reinterpret_cast return short signed sizeof static static_cast struct switch " +"template this throw true try typedef typeid typename union unsigned using " +"virtual void volatile wchar_t while xor xor_eq"; + +pascal OSStatus WindowEventHandler(EventHandlerCallRef inCallRef, + EventRef inEvent, + void* inUserData ) +{ + HIViewRef sciView = *reinterpret_cast( inUserData ); + WindowRef window = GetControlOwner(sciView); + ScintillaMacOSX* scintilla; + GetControlProperty( sciView, scintillaMacOSType, 0, sizeof( scintilla ), NULL, &scintilla ); + TCarbonEvent event( inEvent ); + + // If the window is not active, let the standard window handler execute. + if ( ! IsWindowActive( window ) ) return eventNotHandledErr; + + const HIViewRef rootView = HIViewGetRoot( window ); + assert( rootView != NULL ); + + if ( event.GetKind() == kEventMouseDown ) + { + UInt32 inKeyModifiers; + event.GetParameter( kEventParamKeyModifiers, &inKeyModifiers ); + + EventMouseButton inMouseButton; + event.GetParameter( kEventParamMouseButton, typeMouseButton, &inMouseButton ); + if (inMouseButton == kEventMouseButtonTertiary) { + if (inKeyModifiers & optionKey) { + const char *test = "\001This is a test calltip This is a test calltip This is a test calltip"; + scintilla->WndProc( SCI_CALLTIPSHOW, 0, (long int)test ); + } else { + char *list = "test_1?0 test_2 test_3 test_4 test_5 test_6 test_7 test_8 test_9 test_10 test_11 test_12"; + scintilla->WndProc( SCI_AUTOCSHOW, 0, (long int)list ); + } + return noErr; + } + } + + return eventNotHandledErr; +} + +int main(int argc, char* argv[]) +{ + IBNibRef nibRef; + WindowRef window; + + OSStatus err; + + // Create a Nib reference passing the name of the nib file (without the .nib extension) + // CreateNibReference only searches into the application bundle. + err = CreateNibReference(CFSTR("main"), &nibRef); + require_noerr( err, CantGetNibRef ); + + // Once the nib reference is created, set the menu bar. "MainMenu" is the name of the menu bar + // object. This name is set in InterfaceBuilder when the nib is created. + err = SetMenuBarFromNib(nibRef, CFSTR("MenuBar")); + require_noerr( err, CantSetMenuBar ); + + // Then create a window. "MainWindow" is the name of the window object. This name is set in + // InterfaceBuilder when the nib is created. + err = CreateWindowFromNib(nibRef, CFSTR("MainWindow"), &window); + require_noerr( err, CantCreateWindow ); + + // We don't need the nib reference anymore. + DisposeNibReference(nibRef); + + HIRect boundsRect; + // GOOD and BAD methods off embedding into a window. This is used + // to test Window::SetPositionRelative under different situations. +#define GOOD +#ifdef GOOD +#ifdef USE_CONTROL + ControlRef root; + GetRootControl(window, &root); +#else + HIViewRef root; + HIViewFindByID(HIViewGetRoot(window), + kHIViewWindowContentID, + &root); +#endif + HIViewGetBounds(root, &boundsRect); + +#else // BAD like mozilla + HIViewRef root; + root = HIViewGetRoot(window); + + Rect cBounds, sBounds; + GetWindowBounds(window, kWindowContentRgn, &cBounds); + GetWindowBounds(window, kWindowStructureRgn, &sBounds); + boundsRect.origin.x = cBounds.left - sBounds.left; + boundsRect.origin.y = cBounds.top - sBounds.top; + boundsRect.size.width = cBounds.right - cBounds.left; + boundsRect.size.height = cBounds.bottom - cBounds.top; +#endif + + // get a scintilla control, and add it to it's parent container + HIViewRef sciView; + sciView = scintilla_new(); + HIViewAddSubview(root, sciView); + + // some scintilla init + ScintillaMacOSX* scintilla; + GetControlProperty( sciView, scintillaMacOSType, 0, sizeof( scintilla ), NULL, &scintilla ); + + scintilla->WndProc( SCI_SETLEXER, SCLEX_CPP, 0); + scintilla->WndProc( SCI_SETSTYLEBITS, 5, 0); + + scintilla->WndProc(SCI_STYLESETFORE, 0, 0x808080); // White space + scintilla->WndProc(SCI_STYLESETFORE, 1, 0x007F00); // Comment + scintilla->WndProc(SCI_STYLESETITALIC, 1, 1); // Comment + scintilla->WndProc(SCI_STYLESETFORE, 2, 0x007F00); // Line comment + scintilla->WndProc(SCI_STYLESETITALIC, 2, 1); // Line comment + scintilla->WndProc(SCI_STYLESETFORE, 3, 0x3F703F); // Doc comment + scintilla->WndProc(SCI_STYLESETITALIC, 3, 1); // Doc comment + scintilla->WndProc(SCI_STYLESETFORE, 4, 0x7F7F00); // Number + scintilla->WndProc(SCI_STYLESETFORE, 5, 0x7F0000); // Keyword + scintilla->WndProc(SCI_STYLESETBOLD, 5, 1); // Keyword + scintilla->WndProc(SCI_STYLESETFORE, 6, 0x7F007F); // String + scintilla->WndProc(SCI_STYLESETFORE, 7, 0x7F007F); // Character + scintilla->WndProc(SCI_STYLESETFORE, 8, 0x804080); // UUID + scintilla->WndProc(SCI_STYLESETFORE, 9, 0x007F7F); // Preprocessor + scintilla->WndProc(SCI_STYLESETFORE,10, 0x000000); // Operators + scintilla->WndProc(SCI_STYLESETBOLD,10, 1); // Operators + scintilla->WndProc(SCI_STYLESETFORE,11, 0x000000); // Identifiers + + + scintilla->WndProc(SCI_SETKEYWORDS, 0, (sptr_t)(char *)keywords); // Keyword + + /* + these fail compilation on osx now + scintilla->WndProc( SCI_SETPROPERTY, "fold", (long int)"1"); + scintilla->WndProc( SCI_SETPROPERTY, "fold.compact", (long int)"0"); + scintilla->WndProc( SCI_SETPROPERTY, "fold.comment", (long int)"1"); + scintilla->WndProc( SCI_SETPROPERTY, "fold.preprocessor", (long int)"1"); + */ + + scintilla->WndProc( SCI_REGISTERIMAGE, 0, (long int)ac_class); + + scintilla->WndProc( SCI_SETMARGINTYPEN, 0, (long int)SC_MARGIN_NUMBER); + scintilla->WndProc( SCI_SETMARGINWIDTHN, 0, (long int)30); + scintilla->WndProc( SCI_SETMARGINTYPEN, 1, (long int)SC_MARGIN_SYMBOL); + scintilla->WndProc( SCI_SETMARGINMASKN, 1, (long int)SC_MASK_FOLDERS); + scintilla->WndProc( SCI_SETMARGINWIDTHN, 1, (long int)20); + scintilla->WndProc( SCI_SETMARGINTYPEN, 2, (long int)SC_MARGIN_SYMBOL); + scintilla->WndProc( SCI_SETMARGINWIDTHN, 2, (long int)16); + //scintilla->WndProc( SCI_SETWRAPMODE, SC_WRAP_WORD, 0); + //scintilla->WndProc( SCI_SETWRAPVISUALFLAGS, SC_WRAPVISUALFLAG_END | SC_WRAPVISUALFLAG_START, 0); + + // set the size of scintilla to the size of the container + HIViewSetFrame( sciView, &boundsRect ); + + // bind the size of scintilla to the size of it's container window + HIViewSetLayoutInfo(sciView, &kBindToParentLayout); + + // setup some event handling + static const EventTypeSpec kWindowMouseEvents[] = + { + { kEventClassMouse, kEventMouseDown }, + }; + + InstallEventHandler( GetWindowEventTarget( window ), WindowEventHandler, + GetEventTypeCount( kWindowMouseEvents ), kWindowMouseEvents, &sciView, NULL ); + + // show scintilla + ShowControl(sciView); + + SetAutomaticControlDragTrackingEnabledForWindow(window, true); + + // The window was created hidden so show it. + ShowWindow( window ); + + // Call the event loop + RunApplicationEventLoop(); + +CantCreateWindow: +CantSetMenuBar: +CantGetNibRef: + return err; +} + diff --git a/scintilla/macosx/SciTest/version.plist b/scintilla/macosx/SciTest/version.plist new file mode 100644 index 00000000..ed07389d --- /dev/null +++ b/scintilla/macosx/SciTest/version.plist @@ -0,0 +1,16 @@ + + + + + BuildVersion + 92 + CFBundleVersion + 1.0 + ProductBuildVersion + 7K571 + ProjectName + NibPBTemplates + SourceVersion + 1200000 + + diff --git a/scintilla/macosx/ScintillaCallTip.cxx b/scintilla/macosx/ScintillaCallTip.cxx new file mode 100644 index 00000000..3b87acb2 --- /dev/null +++ b/scintilla/macosx/ScintillaCallTip.cxx @@ -0,0 +1,117 @@ + +#include "ScintillaMacOSX.h" +#include "ScintillaCallTip.h" +#include "CallTip.h" + +using namespace Scintilla; + +const CFStringRef ScintillaCallTip::kScintillaCallTipClassID = CFSTR( "org.scintilla.calltip" ); +const ControlKind ScintillaCallTip::kScintillaCallTipKind = { 'ejon', 'Scct' }; + +ScintillaCallTip::ScintillaCallTip( void* windowid ) : + TView( reinterpret_cast( windowid ) ) +{ + ActivateInterface( kMouse ); + // debugPrint = true; +} + +void ScintillaCallTip::Draw( + RgnHandle /*inLimitRgn*/, + CGContextRef inContext ) +{ + // Get a reference to the Scintilla C++ object + CallTip* ctip = NULL; + OSStatus err; + err = GetControlProperty( GetViewRef(), scintillaCallTipType, 0, sizeof( ctip ), NULL, &ctip ); + assert(err == noErr); + if (ctip == NULL) return; + + Rect contentBounds; + GetControlBounds(GetViewRef(), &contentBounds); + + HIRect controlFrame; + HIViewGetFrame( GetViewRef(), &controlFrame ); + + // what is the global pos? + Surface *surfaceWindow = Surface::Allocate(); + if (surfaceWindow) { + surfaceWindow->Init(inContext, GetViewRef()); + ctip->PaintCT(surfaceWindow); + surfaceWindow->Release(); + delete surfaceWindow; + } + +} + +ControlPartCode ScintillaCallTip::HitTest( const HIPoint& where ) +{ + if ( CGRectContainsPoint( Bounds(), where ) ) + return 1; + else + return kControlNoPart; +} + +OSStatus ScintillaCallTip::MouseDown(HIPoint& location, UInt32 /*inKeyModifiers*/, EventMouseButton button, UInt32 /*inClickCount*/ ) +{ + if ( button != kEventMouseButtonPrimary ) return eventNotHandledErr; + CallTip* ctip = NULL; + ScintillaMacOSX *sciThis = NULL; + OSStatus err = GetControlProperty( GetViewRef(), scintillaCallTipType, 0, sizeof( ctip ), NULL, &ctip ); + err = GetControlProperty( GetViewRef(), scintillaMacOSType, 0, sizeof( sciThis ), NULL, &sciThis ); + ctip->MouseClick( Scintilla::Point( static_cast( location.x ), static_cast( location.y ) )); + sciThis->CallTipClick(); + return noErr; +} + +OSStatus ScintillaCallTip::MouseUp(HIPoint& /*inMouseLocation*/, UInt32 /*inKeyModifiers*/, EventMouseButton button, UInt32 /*inClickCount*/ ) +{ + if ( button != kEventMouseButtonPrimary ) return eventNotHandledErr; + return noErr; +} + +OSStatus ScintillaCallTip::MouseDragged( HIPoint& location, UInt32 /*modifiers*/, EventMouseButton /*button*/, UInt32 /*clickCount*/ ) +{ + SetThemeCursor( kThemeArrowCursor ); + return noErr; +} + +HIViewRef ScintillaCallTip::Create() +{ + // Register the HIView, if needed + static bool registered = false; + + if ( not registered ) + { + TView::RegisterSubclass( kScintillaCallTipClassID, Construct ); + registered = true; + } + + OSStatus err = noErr; + EventRef event = CreateInitializationEvent(); + assert( event != NULL ); + + HIViewRef control = NULL; + err = HIObjectCreate( kScintillaCallTipClassID, event, reinterpret_cast( &control ) ); + ReleaseEvent( event ); + if ( err == noErr ) { + Platform::DebugPrintf("ScintillaCallTip::Create control %08X\n",control); + return control; + } + return NULL; +} + +OSStatus ScintillaCallTip::Construct( HIViewRef inControl, TView** outView ) +{ + *outView = new ScintillaCallTip( inControl ); + Platform::DebugPrintf("ScintillaCallTip::Construct scintilla %08X\n",*outView); + if ( *outView != NULL ) + return noErr; + else + return memFullErr; +} + +extern "C" { +HIViewRef scintilla_calltip_new() { + return ScintillaCallTip::Create(); +} +} diff --git a/scintilla/macosx/ScintillaCallTip.h b/scintilla/macosx/ScintillaCallTip.h new file mode 100644 index 00000000..0d8526b7 --- /dev/null +++ b/scintilla/macosx/ScintillaCallTip.h @@ -0,0 +1,64 @@ +/* + * ScintillaMacOSX.h + * tutorial + * + * Created by Evan Jones on Sun Sep 01 2002. + * Copyright (c) 2002 __MyCompanyName__. All rights reserved. + * + */ +#ifndef SCINTILLA_CALLTIP_H +#define SCINTILLA_CALLTIP_H + +#include "TView.h" + +#include +#include +#include +#include +#include + +#include "Platform.h" +#include "Scintilla.h" + +static const OSType scintillaCallTipType = 'Scct'; + +namespace Scintilla { + +class ScintillaCallTip : public TView +{ +public: + // Private so ScintillaCallTip objects can not be copied + ScintillaCallTip(const ScintillaCallTip &) : TView( NULL ) {} + ScintillaCallTip &operator=(const ScintillaCallTip &) { return * this; } + ~ScintillaCallTip() {}; + +public: + /** This is the class ID that we've assigned to Scintilla. */ + static const CFStringRef kScintillaCallTipClassID; + static const ControlKind kScintillaCallTipKind; + + ScintillaCallTip( void* windowid ); + + /** Returns the HIView object kind, needed to subclass TView. */ + virtual ControlKind GetKind() { return kScintillaCallTipKind; } + +private: + + virtual ControlPartCode HitTest( const HIPoint& where ); + virtual void Draw( RgnHandle rgn, CGContextRef gc ); + virtual OSStatus MouseDown( HIPoint& location, UInt32 modifiers, EventMouseButton button, UInt32 clickCount ); + virtual OSStatus MouseUp( HIPoint& location, UInt32 modifiers, EventMouseButton button, UInt32 clickCount ); + virtual OSStatus MouseDragged( HIPoint& location, UInt32 modifiers, EventMouseButton button, UInt32 clickCount ); + +public: + static HIViewRef Create(); +private: + static OSStatus Construct( HIViewRef inControl, TView** outView ); + +}; + + +} + + +#endif diff --git a/scintilla/macosx/ScintillaListBox.cxx b/scintilla/macosx/ScintillaListBox.cxx new file mode 100644 index 00000000..431e4b4f --- /dev/null +++ b/scintilla/macosx/ScintillaListBox.cxx @@ -0,0 +1,103 @@ + +#include "ScintillaMacOSX.h" +#include "ScintillaListBox.h" + +using namespace Scintilla; + +const CFStringRef ScintillaListBox::kScintillaListBoxClassID = CFSTR( "org.scintilla.listbox" ); +const ControlKind ScintillaListBox::kScintillaListBoxKind = { 'ejon', 'Sclb' }; + +ScintillaListBox::ScintillaListBox( void* windowid ) : + TView( reinterpret_cast( windowid ) ) +{ + ActivateInterface( kMouse ); + // debugPrint = true; +} + +void ScintillaListBox::Draw( + RgnHandle /*inLimitRgn*/, + CGContextRef inContext ) +{ + Rect contentBounds; + GetControlBounds(GetViewRef(), &contentBounds); + + HIRect controlFrame; + HIViewGetFrame( GetViewRef(), &controlFrame ); + + // what is the global pos? + Surface *surfaceWindow = Surface::Allocate(); + if (surfaceWindow) { + surfaceWindow->Init(inContext, GetViewRef()); + ctip->PaintCT(surfaceWindow); + surfaceWindow->Release(); + delete surfaceWindow; + } + +} + +ControlPartCode ScintillaListBox::HitTest( const HIPoint& where ) +{ + if ( CGRectContainsPoint( Bounds(), where ) ) + return 1; + else + return kControlNoPart; +} + +OSStatus ScintillaListBox::MouseDown(HIPoint& location, UInt32 /*inKeyModifiers*/, EventMouseButton button, UInt32 /*inClickCount*/ ) +{ + if ( button != kEventMouseButtonPrimary ) return eventNotHandledErr; + ListBox* ctip = NULL; + ScintillaMacOSX *sciThis = NULL; + OSStatus err = GetControlProperty( GetViewRef(), scintillaListBoxType, 0, sizeof( ctip ), NULL, &ctip ); + err = GetControlProperty( GetViewRef(), scintillaMacOSType, 0, sizeof( sciThis ), NULL, &sciThis ); + ctip->MouseClick( Scintilla::Point( static_cast( location.x ), static_cast( location.y ) )); + sciThis->ListBoxClick(); + return noErr; +} + +OSStatus ScintillaListBox::MouseUp(HIPoint& /*inMouseLocation*/, UInt32 /*inKeyModifiers*/, EventMouseButton button, UInt32 /*inClickCount*/ ) +{ + if ( button != kEventMouseButtonPrimary ) return eventNotHandledErr; + return noErr; +} + +HIViewRef ScintillaListBox::Create() +{ + // Register the HIView, if needed + static bool registered = false; + + if ( not registered ) + { + TView::RegisterSubclass( kScintillaListBoxClassID, Construct ); + registered = true; + } + + OSStatus err = noErr; + EventRef event = CreateInitializationEvent(); + assert( event != NULL ); + + HIViewRef control = NULL; + err = HIObjectCreate( kScintillaListBoxClassID, event, reinterpret_cast( &control ) ); + ReleaseEvent( event ); + if ( err == noErr ) { + Platform::DebugPrintf("ScintillaListBox::Create control %08X\n",control); + return control; + } + return NULL; +} + +OSStatus ScintillaListBox::Construct( HIViewRef inControl, TView** outView ) +{ + *outView = new ScintillaListBox( inControl ); + Platform::DebugPrintf("ScintillaListBox::Construct scintilla %08X\n",*outView); + if ( *outView != NULL ) + return noErr; + else + return memFullErr; +} + +extern "C" { +HIViewRef scintilla_listbox_new() { + return ScintillaListBox::Create(); +} +} diff --git a/scintilla/macosx/ScintillaListBox.h b/scintilla/macosx/ScintillaListBox.h new file mode 100644 index 00000000..a8582c26 --- /dev/null +++ b/scintilla/macosx/ScintillaListBox.h @@ -0,0 +1,63 @@ +/* + * ScintillaMacOSX.h + * tutorial + * + * Created by Evan Jones on Sun Sep 01 2002. + * Copyright (c) 2002 __MyCompanyName__. All rights reserved. + * + */ +#ifndef SCINTILLA_LISTBOX_H +#define SCINTILLA_LISTBOX_H + +#include "TView.h" + +#include +#include +#include +#include +#include + +#include "Platform.h" +#include "Scintilla.h" + +static const OSType scintillaListBoxType = 'sclb'; + +namespace Scintilla { + +class ScintillaListBox : public TView +{ +public: + // Private so ScintillaListBox objects can not be copied + ScintillaListBox(const ScintillaListBox &) : TView( NULL ) {} + ScintillaListBox &operator=(const ScintillaListBox &) { return * this; } + ~ScintillaListBox() {}; + +public: + /** This is the class ID that we've assigned to Scintilla. */ + static const CFStringRef kScintillaListBoxClassID; + static const ControlKind kScintillaListBoxKind; + + ScintillaListBox( void* windowid ); + + /** Returns the HIView object kind, needed to subclass TView. */ + virtual ControlKind GetKind() { return kScintillaListBoxKind; } + +private: + + virtual ControlPartCode HitTest( const HIPoint& where ); + virtual void Draw( RgnHandle rgn, CGContextRef gc ); + virtual OSStatus MouseDown( HIPoint& location, UInt32 modifiers, EventMouseButton button, UInt32 clickCount ); + virtual OSStatus MouseUp( HIPoint& location, UInt32 modifiers, EventMouseButton button, UInt32 clickCount ); + +public: + static HIViewRef Create(); +private: + static OSStatus Construct( HIViewRef inControl, TView** outView ); + +}; + + +} + + +#endif diff --git a/scintilla/macosx/ScintillaMacOSX.cxx b/scintilla/macosx/ScintillaMacOSX.cxx new file mode 100644 index 00000000..e4f2f8c0 --- /dev/null +++ b/scintilla/macosx/ScintillaMacOSX.cxx @@ -0,0 +1,2242 @@ +// Scintilla source code edit control +// ScintillaMacOSX.cxx - Mac OS X subclass of ScintillaBase +// Copyright 2003 by Evan Jones +// Based on ScintillaGTK.cxx Copyright 1998-2002 by Neil Hodgson +// The License.txt file describes the conditions under which this software may be distributed. + + +#include "ScintillaMacOSX.h" +#ifdef EXT_INPUT +// External Input Editor +#include "ExtInput.h" +#else +#include "UniConversion.h" +#endif + +using namespace Scintilla; + +const CFStringRef ScintillaMacOSX::kScintillaClassID = CFSTR( "org.scintilla.scintilla" ); +const ControlKind ScintillaMacOSX::kScintillaKind = { 'ejon', 'Scin' }; + +extern "C" HIViewRef scintilla_calltip_new(void); + +#ifndef WM_UNICHAR +#define WM_UNICHAR 0x0109 +#endif + +// required for paste/dragdrop, see comment in paste function below +static int BOMlen(unsigned char *cstr) { + switch(cstr[0]) { + case 0xEF: // BOM_UTF8 + if (cstr[1] == 0xBB && cstr[2] == 0xBF) { + return 3; + } + break; + case 0xFE: + if (cstr[1] == 0xFF) { + if (cstr[2] == 0x00 && cstr[3] == 0x00) { + return 4; + } + return 2; + } + break; + case 0xFF: + if (cstr[1] == 0xFE) { + if (cstr[2] == 0x00 && cstr[3] == 0x00) { + return 4; + } + return 2; + } + break; + case 0x00: + if (cstr[1] == 0x00) { + if (cstr[2] == 0xFE && cstr[3] == 0xFF) { + return 4; + } + if (cstr[2] == 0xFF && cstr[3] == 0xFE) { + return 4; + } + return 2; + } + break; + } + + return 0; +} + +#ifdef EXT_INPUT +#define SCI_CMD ( SCI_ALT | SCI_CTRL | SCI_SHIFT) + +static const KeyToCommand macMapDefault[] = { + {SCK_DOWN, SCI_CMD, SCI_DOCUMENTEND}, + {SCK_UP, SCI_CMD, SCI_DOCUMENTSTART}, + {SCK_LEFT, SCI_CMD, SCI_VCHOME}, + {SCK_RIGHT, SCI_CMD, SCI_LINEEND}, + {SCK_DOWN, SCI_NORM, SCI_LINEDOWN}, + {SCK_DOWN, SCI_SHIFT, SCI_LINEDOWNEXTEND}, + {SCK_DOWN, SCI_CTRL, SCI_LINESCROLLDOWN}, + {SCK_DOWN, SCI_ASHIFT, SCI_LINEDOWNRECTEXTEND}, + {SCK_UP, SCI_NORM, SCI_LINEUP}, + {SCK_UP, SCI_SHIFT, SCI_LINEUPEXTEND}, + {SCK_UP, SCI_CTRL, 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_CSHIFT, 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_CSHIFT, 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_HOMEDISPLAYEXTEND}, + {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_LINEENDDISPLAYEXTEND}, + {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_UNDO}, + {SCK_BACK, SCI_CSHIFT, SCI_DELLINELEFT}, + {'Z', SCI_CTRL, SCI_UNDO}, + {'Y', SCI_CTRL, SCI_REDO}, + {'X', SCI_CTRL, SCI_CUT}, + {'C', SCI_CTRL, SCI_COPY}, + {'V', SCI_CTRL, SCI_PASTE}, + {'A', SCI_CTRL, 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_CTRL, SCI_ZOOMIN}, + {SCK_SUBTRACT, SCI_CTRL, SCI_ZOOMOUT}, + {SCK_DIVIDE, SCI_CTRL, SCI_SETZOOM}, + //'L', SCI_CTRL, SCI_FORMFEED, + {'L', SCI_CTRL, 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}, +}; +#endif + +ScintillaMacOSX::ScintillaMacOSX( void* windowid ) : + TView( reinterpret_cast( windowid ) ) +{ + notifyObj = NULL; + notifyProc = NULL; + wMain = windowid; + OSStatus err; + err = GetThemeMetric( kThemeMetricScrollBarWidth, &scrollBarFixedSize ); + assert( err == noErr ); + + mouseTrackingRef = NULL; + mouseTrackingID.signature = scintillaMacOSType; + mouseTrackingID.id = (SInt32)this; + capturedMouse = false; + + // Enable keyboard events and mouse events +#if !defined(CONTAINER_HANDLES_EVENTS) + ActivateInterface( kKeyboardFocus ); + ActivateInterface( kMouse ); + ActivateInterface( kDragAndDrop ); +#endif + ActivateInterface( kMouseTracking ); + + Initialise(); + + // Create some bounds rectangle which will just get reset to the correct rectangle later + Rect tempScrollRect; + tempScrollRect.top = -1; + tempScrollRect.left = 400; + tempScrollRect.bottom = 300; + tempScrollRect.right = 450; + + // Create the scroll bar with fake values that will get set correctly later + err = CreateScrollBarControl( this->GetOwner(), &tempScrollRect, 0, 0, 100, 100, true, LiveScrollHandler, &vScrollBar ); + assert( vScrollBar != NULL && err == noErr ); + err = CreateScrollBarControl( this->GetOwner(), &tempScrollRect, 0, 0, 100, 100, true, LiveScrollHandler, &hScrollBar ); + assert( hScrollBar != NULL && err == noErr ); + + // Set a property on the scrollbars to store a pointer to the Scintilla object + ScintillaMacOSX* objectPtr = this; + err = SetControlProperty( vScrollBar, scintillaMacOSType, 0, sizeof( this ), &objectPtr ); + assert( err == noErr ); + err = SetControlProperty( hScrollBar, scintillaMacOSType, 0, sizeof( this ), &objectPtr ); + assert( err == noErr ); + + // set this into our parent control so we can be retrieved easily at a later time + // (see scintilla_send below) + err = SetControlProperty( reinterpret_cast( windowid ), scintillaMacOSType, 0, sizeof( this ), &objectPtr ); + assert( err == noErr ); + + // Tell Scintilla not to buffer: Quartz buffers drawing for us + // TODO: Can we disable this option on Mac OS X? + WndProc( SCI_SETBUFFEREDDRAW, 0, 0 ); + // Turn on UniCode mode + WndProc( SCI_SETCODEPAGE, SC_CP_UTF8, 0 ); + + const EventTypeSpec commandEventInfo[] = { + { kEventClassCommand, kEventProcessCommand }, + { kEventClassCommand, kEventCommandUpdateStatus }, + }; + + err = InstallEventHandler( GetControlEventTarget( reinterpret_cast( windowid ) ), + CommandEventHandler, + GetEventTypeCount( commandEventInfo ), + commandEventInfo, + this, NULL); +#ifdef EXT_INPUT + ExtInput::attach (GetViewRef()); + for (int i = 0; macMapDefault[i].key; i++) + { + this->kmap.AssignCmdKey(macMapDefault[i].key, macMapDefault[i].modifiers, macMapDefault[i].msg); + } +#endif +} + +ScintillaMacOSX::~ScintillaMacOSX() { + // If the window is closed and the timer is not removed, + // A segment violation will occur when it attempts to fire the timer next. + if ( mouseTrackingRef != NULL ) { + ReleaseMouseTrackingRegion(mouseTrackingRef); + } + mouseTrackingRef = NULL; + SetTicking(false); +#ifdef EXT_INPUT + ExtInput::detach (GetViewRef()); +#endif +} + +void ScintillaMacOSX::Initialise() { + // TODO: Do anything here? Maybe this stuff should be here instead of the constructor? +} + +void ScintillaMacOSX::Finalise() { + SetTicking(false); + ScintillaBase::Finalise(); +} + +// -------------------------------------------------------------------------------------------------------------- +// +// IsDropInFinderTrash - Returns true if the given dropLocation AEDesc is a descriptor of the Finder's Trash. +// +#pragma segment Drag + +Boolean IsDropInFinderTrash(AEDesc *dropLocation) +{ + OSErr result; + AEDesc dropSpec; + FSSpec *theSpec; + CInfoPBRec thePB; + short trashVRefNum; + long trashDirID; + + // Coerce the dropLocation descriptor into an FSSpec. If there's no dropLocation or + // it can't be coerced into an FSSpec, then it couldn't have been the Trash. + + if ((dropLocation->descriptorType != typeNull) && + (AECoerceDesc(dropLocation, typeFSS, &dropSpec) == noErr)) + { + unsigned char flags = HGetState((Handle)dropSpec.dataHandle); + + HLock((Handle)dropSpec.dataHandle); + theSpec = (FSSpec *) *dropSpec.dataHandle; + + // Get the directory ID of the given dropLocation object. + + thePB.dirInfo.ioCompletion = 0L; + thePB.dirInfo.ioNamePtr = (StringPtr) &theSpec->name; + thePB.dirInfo.ioVRefNum = theSpec->vRefNum; + thePB.dirInfo.ioFDirIndex = 0; + thePB.dirInfo.ioDrDirID = theSpec->parID; + + result = PBGetCatInfoSync(&thePB); + + HSetState((Handle)dropSpec.dataHandle, flags); + AEDisposeDesc(&dropSpec); + + if (result != noErr) + return false; + + // If the result is not a directory, it must not be the Trash. + + if (!(thePB.dirInfo.ioFlAttrib & (1 << 4))) + return false; + + // Get information about the Trash folder. + + FindFolder(theSpec->vRefNum, kTrashFolderType, kCreateFolder, &trashVRefNum, &trashDirID); + + // If the directory ID of the dropLocation object is the same as the directory ID + // returned by FindFolder, then the drop must have occurred into the Trash. + + if (thePB.dirInfo.ioDrDirID == trashDirID) + return true; + } + + return false; + +} // IsDropInFinderTrash + +HIPoint ScintillaMacOSX::GetLocalPoint(::Point pt) +{ + // get the mouse position so we can offset it + Rect bounds; + GetWindowBounds( GetOwner(), kWindowStructureRgn, &bounds ); + + PRectangle hbounds = wMain.GetPosition(); + HIViewRef parent = HIViewGetSuperview(GetViewRef()); + Rect pbounds; + GetControlBounds(parent, &pbounds); + + bounds.left += pbounds.left + hbounds.left; + bounds.top += pbounds.top + hbounds.top; + + HIPoint offset = { pt.h - bounds.left, pt.v - bounds.top }; + return offset; +} + +void ScintillaMacOSX::StartDrag() { + if (sel.Empty()) return; + + // calculate the bounds of the selection + PRectangle client = GetTextRectangle(); + int selStart = sel.RangeMain().Start().Position(); + int selEnd = sel.RangeMain().End().Position(); + int startLine = pdoc->LineFromPosition(selStart); + int endLine = pdoc->LineFromPosition(selEnd); + Point pt; + int startPos, endPos, ep; + Rect rcSel; + 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(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(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 + PRectangle imageRect = PRectangle(rcSel.left, rcSel.top, rcSel.right, rcSel.bottom); + QDLocalToGlobalRect(GetWindowPort(GetOwner()), &rcSel); + + // get the mouse position so we can offset it + HIPoint offset = GetLocalPoint(mouseDownEvent.where); + offset.y = (imageRect.top * 1.0) - offset.y; + offset.x = (imageRect.left * 1.0) - offset.x; + + // to get a bitmap of the text we're dragging, we just use Paint on a + // pixmap surface. + SurfaceImpl *sw = new SurfaceImpl(); + SurfaceImpl *pixmap = NULL; + + if (sw) { + pixmap = new SurfaceImpl(); + if (pixmap) { + client = GetClientRectangle(); + paintState = painting; + sw->InitPixMap( client.Width(), client.Height(), NULL, NULL ); + paintingAllText = true; + Paint(sw, imageRect); + paintState = notPainting; + + pixmap->InitPixMap( imageRect.Width(), imageRect.Height(), NULL, NULL ); + + CGContextRef gc = pixmap->GetContext(); + + // to make Paint() work on a bitmap, we have to flip our coordinates + // and translate the origin + //fprintf(stderr, "translate to %d\n", client.Height() ); + CGContextTranslateCTM(gc, 0, imageRect.Height()); + CGContextScaleCTM(gc, 1.0, -1.0); + + pixmap->CopyImageRectangle( *sw, imageRect, PRectangle( 0, 0, 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. + } + sw->Release(); + delete sw; + } + + // now we initiate the drag session + + RgnHandle dragRegion = NewRgn(); + RgnHandle tempRegion; + DragRef inDrag; + DragAttributes attributes; + AEDesc dropLocation; + SInt16 mouseDownModifiers, mouseUpModifiers; + bool copyText; + CGImageRef image = NULL; + + RectRgn(dragRegion, &rcSel); + + SelectionText selectedText; + CopySelectionRange(&selectedText); + PasteboardRef theClipboard; + SetPasteboardData(theClipboard, selectedText); + NewDragWithPasteboard( theClipboard, &inDrag); + CFRelease( theClipboard ); + + // Set the item's bounding rectangle in global coordinates. + SetDragItemBounds(inDrag, 1, &rcSel); + + // Prepare the drag region. + tempRegion = NewRgn(); + CopyRgn(dragRegion, tempRegion); + InsetRgn(tempRegion, 1, 1); + DiffRgn(dragRegion, tempRegion, dragRegion); + DisposeRgn(tempRegion); + + // if we have a pixmap, lets use that + if (pixmap) { + image = pixmap->GetImage(); + SetDragImageWithCGImage (inDrag, image, &offset, kDragStandardTranslucency); + } + + // Drag the text. TrackDrag will return userCanceledErr if the drop whooshed back for any reason. + inDragDrop = ddDragging; + OSErr error = TrackDrag(inDrag, &mouseDownEvent, dragRegion); + inDragDrop = ddNone; + + // Check to see if the drop occurred in the Finder's Trash. If the drop occurred + // in the Finder's Trash and a copy operation wasn't specified, delete the + // source selection. Note that we can continute to get the attributes, drop location + // modifiers, etc. of the drag until we dispose of it using DisposeDrag. + if (error == noErr) { + GetDragAttributes(inDrag, &attributes); + if (!(attributes & kDragInsideSenderApplication)) + { + GetDropLocation(inDrag, &dropLocation); + + GetDragModifiers(inDrag, 0L, &mouseDownModifiers, &mouseUpModifiers); + copyText = (mouseDownModifiers | mouseUpModifiers) & optionKey; + + if ((!copyText) && (IsDropInFinderTrash(&dropLocation))) + { + // delete the selected text from the buffer + ClearSelection(); + } + + AEDisposeDesc(&dropLocation); + } + } + + // Dispose of this drag, 'cause we're done. + DisposeDrag(inDrag); + DisposeRgn(dragRegion); + + if (pixmap) { + CGImageRelease(image); + pixmap->Release(); + delete pixmap; + } +} + +void ScintillaMacOSX::SetDragCursor(DragRef inDrag) +{ + DragAttributes attributes; + SInt16 modifiers = 0; + ThemeCursor cursor = kThemeCopyArrowCursor; + GetDragAttributes( inDrag, &attributes ); + + if ( attributes & kDragInsideSenderWindow ) { + GetDragModifiers(inDrag, &modifiers, NULL, NULL); + switch (modifiers & ~btnState) // Filter out btnState (on for drop) + { + case optionKey: + // it's a copy, leave it as a copy arrow + break; + + case cmdKey: + case cmdKey | optionKey: + default: + // what to do with these? rectangular drag? + cursor = kThemeArrowCursor; + break; + } + } + SetThemeCursor(cursor); +} + +bool ScintillaMacOSX::DragEnter(DragRef inDrag ) +{ + if (!DragWithin(inDrag)) + return false; + + DragAttributes attributes; + GetDragAttributes( inDrag, &attributes ); + + // only show the drag hilight if the drag has left the sender window per HI spec + if( attributes & kDragHasLeftSenderWindow ) + { + HIRect textFrame; + RgnHandle hiliteRgn = NewRgn(); + + // get the text view's frame ... + HIViewGetFrame( GetViewRef(), &textFrame ); + + // ... and convert it into a region for ShowDragHilite + HIShapeRef textShape = HIShapeCreateWithRect( &textFrame ); + HIShapeGetAsQDRgn( textShape, hiliteRgn ); + CFRelease( textShape ); + + // add the drag hilight to the inside of the text view + ShowDragHilite( inDrag, hiliteRgn, true ); + + DisposeRgn( hiliteRgn ); + } + SetDragCursor(inDrag); + return true; +} + +Scintilla::Point ScintillaMacOSX::GetDragPoint(DragRef inDrag) +{ + ::Point mouse, globalMouse; + GetDragMouse(inDrag, &mouse, &globalMouse); + HIPoint hiPoint = GetLocalPoint (globalMouse); + return Point(static_cast(hiPoint.x), static_cast(hiPoint.y)); +} + + +void ScintillaMacOSX::DragScroll() +{ +#define RESET_SCROLL_TIMER(lines) \ + scrollSpeed = (lines); \ + scrollTicks = 2000; + + if (!posDrag.IsValid()) { + RESET_SCROLL_TIMER(1); + return; + } + Point dragMouse = LocationFromPosition(posDrag); + int line = pdoc->LineFromPosition(posDrag.Position()); + int currentVisibleLine = cs.DisplayFromDoc(line); + int lastVisibleLine = Platform::Minimum(topLine + LinesOnScreen() - 1, pdoc->LinesTotal() - 1); + + if (currentVisibleLine <= topLine && topLine > 0) { + ScrollTo( topLine - scrollSpeed ); + } else if (currentVisibleLine >= lastVisibleLine) { + ScrollTo( topLine + scrollSpeed ); + } else { + RESET_SCROLL_TIMER(1); + return; + } + if (scrollSpeed == 1) { + scrollTicks -= timer.tickSize; + if (scrollTicks <= 0) { + RESET_SCROLL_TIMER(5); + } + } + + SetDragPosition(SPositionFromLocation(dragMouse)); + +#undef RESET_SCROLL_TIMER +} + +bool ScintillaMacOSX::DragWithin(DragRef inDrag ) +{ + PasteboardRef pasteBoard; + bool isFileURL = false; + if (!GetDragData(inDrag, pasteBoard, NULL, &isFileURL)) { + return false; + } + + Point pt = GetDragPoint (inDrag); + SetDragPosition(SPositionFromLocation(pt)); + SetDragCursor(inDrag); + + return true; +} + +bool ScintillaMacOSX::DragLeave(DragRef inDrag ) +{ + HideDragHilite( inDrag ); + SetDragPosition(SelectionPosition(invalidPosition)); + WndProc(SCI_SETCURSOR, Window::cursorArrow, 0); + return true; +} + +enum +{ + kFormatBad, + kFormatText, + kFormatUnicode, + kFormatUTF8, + kFormatFile +}; + +bool ScintillaMacOSX::GetDragData(DragRef inDrag, PasteboardRef &pasteBoard, + SelectionText *selectedText, bool *isFileURL) +{ + // TODO: add support for special flavors: flavorTypeHFS and flavorTypePromiseHFS so we + // can handle files being dropped on the editor + OSStatus status; + status = GetDragPasteboard(inDrag, &pasteBoard); + if (status != noErr) { + return false; + } + return GetPasteboardData(pasteBoard, selectedText, isFileURL); +} + +void ScintillaMacOSX::SetPasteboardData(PasteboardRef &theClipboard, const SelectionText &selectedText) +{ + if (selectedText.len == 0) + return; + + CFStringEncoding encoding = ( IsUnicodeMode() ? kCFStringEncodingUTF8 : kCFStringEncodingMacRoman); + + // Create a CFString from the ASCII/UTF8 data, convert it to UTF16 + CFStringRef string = CFStringCreateWithBytes( NULL, reinterpret_cast( selectedText.s ), selectedText.len - 1, encoding, false ); + + PasteboardCreate( kPasteboardClipboard, &theClipboard ); + PasteboardClear( theClipboard ); + + CFDataRef data = NULL; + if (selectedText.rectangular) { + // This is specific to scintilla, allows us to drag rectangular selections + // around the document + data = CFStringCreateExternalRepresentation ( kCFAllocatorDefault, string, kCFStringEncodingUnicode, 0 ); + if (data) { + PasteboardPutItemFlavor( theClipboard, (PasteboardItemID)1, + CFSTR("com.scintilla.utf16-plain-text.rectangular"), + data, 0 ); + CFRelease(data); + } + } + data = CFStringCreateExternalRepresentation ( kCFAllocatorDefault, string, kCFStringEncodingUnicode, 0 ); + if (data) { + PasteboardPutItemFlavor( theClipboard, (PasteboardItemID)1, + CFSTR("public.utf16-plain-text"), + data, 0 ); + CFRelease(data); + data = NULL; + } + data = CFStringCreateExternalRepresentation ( kCFAllocatorDefault, string, kCFStringEncodingMacRoman, 0 ); + if (data) { + PasteboardPutItemFlavor( theClipboard, (PasteboardItemID)1, + CFSTR("com.apple.traditional-mac-plain-text"), + data, 0 ); + CFRelease(data); + data = NULL; + } + CFRelease(string); +} + +bool ScintillaMacOSX::GetPasteboardData(PasteboardRef &pasteBoard, + SelectionText *selectedText, + bool *isFileURL) +{ + // how many items in the pasteboard? + CFDataRef data; + CFStringRef textString = NULL; + bool isRectangular = selectedText ? selectedText->rectangular : false; + ItemCount i, itemCount; + OSStatus status = PasteboardGetItemCount(pasteBoard, &itemCount); + if (status != noErr) { + return false; + } + + // as long as we didn't get our text, let's loop on the items. We stop as soon as we get it + CFArrayRef flavorTypeArray = NULL; + bool haveMatch = false; + for (i = 1; i <= itemCount; i++) + { + PasteboardItemID itemID; + CFIndex j, flavorCount = 0; + + status = PasteboardGetItemIdentifier(pasteBoard, i, &itemID); + if (status != noErr) { + return false; + } + + // how many flavors in this item? + status = PasteboardCopyItemFlavors(pasteBoard, itemID, &flavorTypeArray); + if (status != noErr) { + return false; + } + + if (flavorTypeArray != NULL) + flavorCount = CFArrayGetCount(flavorTypeArray); + + // as long as we didn't get our text, let's loop on the flavors. We stop as soon as we get it + for(j = 0; j < flavorCount; j++) + { + CFDataRef flavorData; + CFStringRef flavorType = (CFStringRef)CFArrayGetValueAtIndex(flavorTypeArray, j); + if (flavorType != NULL) + { + int format = kFormatBad; + if (UTTypeConformsTo(flavorType, CFSTR("public.file-url"))) { + format = kFormatFile; + *isFileURL = true; + } + else if (UTTypeConformsTo(flavorType, CFSTR("com.scintilla.utf16-plain-text.rectangular"))) { + format = kFormatUnicode; + isRectangular = true; + } + else if (UTTypeConformsTo(flavorType, CFSTR("public.utf16-plain-text"))) { // this is 'utxt' + format = kFormatUnicode; + } + else if (UTTypeConformsTo(flavorType, CFSTR("public.utf8-plain-text"))) { + format = kFormatUTF8; + } + else if (UTTypeConformsTo(flavorType, CFSTR("com.apple.traditional-mac-plain-text"))) { // this is 'TEXT' + format = kFormatText; + } + if (format == kFormatBad) + continue; + + // if we got a flavor match, and we have no textString, we just want + // to know that we can accept this data, so jump out now + if (selectedText == NULL) { + haveMatch = true; + goto PasteboardDataRetrieved; + } + if (PasteboardCopyItemFlavorData(pasteBoard, itemID, flavorType, &flavorData) == noErr) + { + CFIndex dataSize = CFDataGetLength (flavorData); + const UInt8* dataBytes = CFDataGetBytePtr (flavorData); + switch (format) + { + case kFormatFile: + case kFormatText: + data = CFDataCreate (NULL, dataBytes, dataSize); + textString = CFStringCreateFromExternalRepresentation (NULL, data, kCFStringEncodingMacRoman); + break; + case kFormatUnicode: + data = CFDataCreate (NULL, dataBytes, dataSize); + textString = CFStringCreateFromExternalRepresentation (NULL, data, kCFStringEncodingUnicode); + break; + case kFormatUTF8: + data = CFDataCreate (NULL, dataBytes, dataSize); + textString = CFStringCreateFromExternalRepresentation (NULL, data, kCFStringEncodingUTF8); + break; + } + CFRelease (flavorData); + goto PasteboardDataRetrieved; + } + } + } + } +PasteboardDataRetrieved: + if (flavorTypeArray != NULL) CFRelease(flavorTypeArray); + int newlen = 0; + if (textString != NULL) { + selectedText->s = GetStringFromCFString(textString, &selectedText->len); + selectedText->rectangular = isRectangular; + // Default allocator releases both the CFString and the UniChar buffer (text) + CFRelease( textString ); + textString = NULL; + } + if (haveMatch || selectedText != NULL && selectedText->s != NULL) { + return true; + } + return false; +} + +char *ScintillaMacOSX::GetStringFromCFString(CFStringRef &textString, int *textLen) +{ + + // Allocate a buffer, plus the null byte + CFIndex numUniChars = CFStringGetLength( textString ); + CFStringEncoding encoding = ( IsUnicodeMode() ? kCFStringEncodingUTF8 : kCFStringEncodingMacRoman); + CFIndex maximumByteLength = CFStringGetMaximumSizeForEncoding( numUniChars, encoding ) + 1; + char* cstring = new char[maximumByteLength]; + CFIndex usedBufferLength = 0; + CFIndex numCharsConverted; + numCharsConverted = CFStringGetBytes( textString, CFRangeMake( 0, numUniChars ), encoding, + '?', false, reinterpret_cast( cstring ), + maximumByteLength, &usedBufferLength ); + cstring[usedBufferLength] = '\0'; // null terminate the ASCII/UTF8 string + + // determine whether a BOM is in the string. Apps like Emacs prepends a BOM + // to the string, CFStrinGetBytes reflects that (though it may change in the conversion) + // so we need to remove it before pasting into our buffer. TextWrangler has no + // problem dealing with BOM when pasting into it. + int bomLen = BOMlen((unsigned char *)cstring); + + // convert line endings to the document line ending + *textLen = 0; + char *result = Document::TransformLineEnds(textLen, + cstring + bomLen, + usedBufferLength - bomLen, + pdoc->eolMode); + delete[] cstring; + return result; +} + +OSStatus ScintillaMacOSX::DragReceive(DragRef inDrag ) +{ + // dragleave IS called, but for some reason (probably to do with inDrag) + // the hide hilite does not happen unless we do it here + HideDragHilite( inDrag ); + + PasteboardRef pasteBoard; + SelectionText selectedText; + CFStringRef textString = NULL; + bool isFileURL = false; + if (!GetDragData(inDrag, pasteBoard, &selectedText, &isFileURL)) { + return dragNotAcceptedErr; + } + + if (isFileURL) { + NotifyURIDropped(selectedText.s); + } else { + // figure out if this is a move or a paste + DragAttributes attributes; + SInt16 modifiers = 0; + GetDragAttributes( inDrag, &attributes ); + bool moving = true; + + SelectionPosition position = SPositionFromLocation(GetDragPoint(inDrag)); + if ( attributes & kDragInsideSenderWindow ) { + GetDragModifiers(inDrag, NULL, NULL, &modifiers); + switch (modifiers & ~btnState) // Filter out btnState (on for drop) + { + case optionKey: + // default is copy text + moving = false; + break; + case cmdKey: + case cmdKey | optionKey: + default: + // what to do with these? rectangular drag? + break; + } + } + + DropAt(position, selectedText.s, moving, selectedText.rectangular); + } + + return noErr; +} + +// Extended UTF8-UTF6-conversion to handle surrogate pairs correctly (CL265070) +void ScintillaMacOSX::InsertCharacters (const UniChar* buf, int len) +{ + CFStringRef str = CFStringCreateWithCharactersNoCopy (NULL, buf, (UInt32) len, kCFAllocatorNull); + CFStringEncoding encoding = ( IsUnicodeMode() ? kCFStringEncodingUTF8 : kCFStringEncodingMacRoman); + CFRange range = { 0, len }; + CFIndex bufLen; + CFStringGetBytes (str, range, encoding, '?', false, NULL, 0, &bufLen); + UInt8* utf8buf = new UInt8 [bufLen]; + CFStringGetBytes (str, range, encoding, '?', false, utf8buf, bufLen, NULL); + AddCharUTF ((char*) utf8buf, bufLen, false); + delete [] utf8buf; + CFRelease (str); +} + +/** The simulated message loop. */ +sptr_t ScintillaMacOSX::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { + switch (iMessage) { + case SCI_GETDIRECTFUNCTION: + Platform::DebugDisplay( "ScintillaMacOSX::WndProc: Returning DirectFunction address.\n" ); + return reinterpret_cast( DirectFunction ); + + case SCI_GETDIRECTPOINTER: + Platform::DebugDisplay( "ScintillaMacOSX::WndProc: Returning Direct pointer address.\n" ); + return reinterpret_cast( this ); + + case SCI_GRABFOCUS: + Platform::DebugDisplay( "ScintillaMacOSX::WndProc: Got an unhandled message. Ignoring it.\n" ); + break; + case WM_UNICHAR: + if (IsUnicodeMode()) { + // Extended UTF8-UTF6-conversion to handle surrogate pairs correctly (CL265070) + UniChar wcs[1] = { (UniChar) wParam}; + InsertCharacters(wcs, 1); + return 1; + } else { + return 0; + } + + default: + unsigned int r = ScintillaBase::WndProc(iMessage, wParam, lParam); + + return r; + } + return 0l; +} + +sptr_t ScintillaMacOSX::DefWndProc(unsigned int, uptr_t, sptr_t) { + return 0; +} + +void ScintillaMacOSX::SetTicking(bool on) { + if (timer.ticking != on) { + timer.ticking = on; + if (timer.ticking) { + // Scintilla ticks = milliseconds + EventLoopTimerRef timerRef = NULL; + InstallTimer( timer.tickSize * kEventDurationMillisecond, &timerRef ); + assert( timerRef != NULL ); + timer.tickerID = reinterpret_cast( timerRef ); + } else if ( timer.tickerID != NULL ) { + RemoveEventLoopTimer( reinterpret_cast( timer.tickerID ) ); + } + } + timer.ticksToWait = caret.period; +} + +bool ScintillaMacOSX::SetIdle(bool on) { + if (on) { + // Start idler, if it's not running. + if (idler.state == false) { + idler.state = true; + EventLoopTimerRef idlTimer; + InstallEventLoopIdleTimer(GetCurrentEventLoop(), + timer.tickSize * kEventDurationMillisecond, + 75 * kEventDurationMillisecond, + IdleTimerEventHandler, this, &idlTimer); + idler.idlerID = reinterpret_cast( idlTimer ); + } + } else { + // Stop idler, if it's running + if (idler.state == true) { + idler.state = false; + if (idler.idlerID != NULL) + RemoveEventLoopTimer( reinterpret_cast( idler.idlerID ) ); + } + } + return true; +} + +pascal void ScintillaMacOSX::IdleTimerEventHandler( EventLoopTimerRef inTimer, + EventLoopIdleTimerMessage inState, + void *scintilla ) +{ + ScintillaMacOSX *sciThis = reinterpret_cast( scintilla ); + bool ret = sciThis->Idle(); + if (ret == false) { + sciThis->SetIdle(false); + } +} + +void ScintillaMacOSX::SetMouseCapture(bool on) { + capturedMouse = on; + if (mouseDownCaptures) { + if (capturedMouse) { + WndProc(SCI_SETCURSOR, Window::cursorArrow, 0); + } else { + // reset to normal, buttonmove will change for other area's in the editor + WndProc(SCI_SETCURSOR, (long int)SC_CURSORNORMAL, 0); + } + } +} + +bool ScintillaMacOSX::HaveMouseCapture() { + return capturedMouse; +} + +// The default GetClientRectangle calls GetClientPosition on wMain. +// We override it to return "view local" co-ordinates so we can draw properly +// plus we need to remove the space occupied by the scroll bars +PRectangle ScintillaMacOSX::GetClientRectangle() { + PRectangle rc = wMain.GetClientPosition(); + if (verticalScrollBarVisible) + rc.right -= scrollBarFixedSize + 1; + if (horizontalScrollBarVisible && (wrapState == eWrapNone)) + rc.bottom -= scrollBarFixedSize + 1; + // Move to origin + rc.right -= rc.left; + rc.bottom -= rc.top; + rc.left = 0; + rc.top = 0; + return rc; +} + +// Synchronously paint a rectangle of the window. +void ScintillaMacOSX::SyncPaint(void* gc, PRectangle rc) { + paintState = painting; + rcPaint = rc; + PRectangle rcText = GetTextRectangle(); + paintingAllText = rcPaint.Contains(rcText); + //Platform::DebugPrintf("ScintillaMacOSX::SyncPaint %0d,%0d %0d,%0d\n", + // rcPaint.left, rcPaint.top, rcPaint.right, rcPaint.bottom); + Surface *sw = Surface::Allocate(); + if (sw) { + sw->Init( gc, wMain.GetID() ); + Paint(sw, rc); + if (paintState == paintAbandoned) { + // do a FULL paint. + rcPaint = GetClientRectangle(); + paintState = painting; + paintingAllText = true; + Paint(sw, rcPaint); + wMain.InvalidateAll(); + } + sw->Release(); + delete sw; + } + paintState = notPainting; +} + +void ScintillaMacOSX::ScrollText(int /*linesToMove*/) { + // This function will invalidate the correct regions of the view, + // So shortly after this happens, draw will be called. + // But I'm not quite sure how this works ... + // I have a feeling that it is only supposed to work in conjunction with an HIScrollView. + // TODO: Cook up my own bitblt scroll: Grab the bits on screen, blit them shifted, invalidate the remaining stuff + //CGRect r = CGRectMake( 0, 0, rc.Width(), rc.Height() ); + //HIViewScrollRect( reinterpret_cast( wMain.GetID() ), NULL, 0, vs.lineHeight * linesToMove ); + wMain.InvalidateAll(); +} + +void ScintillaMacOSX::SetVerticalScrollPos() { + SetControl32BitValue( vScrollBar, topLine ); +} + +void ScintillaMacOSX::SetHorizontalScrollPos() { + SetControl32BitValue( hScrollBar, xOffset ); +} + +bool ScintillaMacOSX::ModifyScrollBars(int nMax, int nPage) { + Platform::DebugPrintf( "nMax: %d nPage: %d hScroll (%d -> %d) page: %d\n", nMax, nPage, 0, scrollWidth, GetTextRectangle().Width() ); + // Minimum value = 0 + // TODO: This is probably not needed, since we set this when the scroll bars are created + SetControl32BitMinimum( vScrollBar, 0 ); + SetControl32BitMinimum( hScrollBar, 0 ); + + // Maximum vertical value = nMax + 1 - nPage (lines available to scroll) + SetControl32BitMaximum( vScrollBar, Platform::Maximum( nMax + 1 - nPage, 0 ) ); + // Maximum horizontal value = scrollWidth - GetTextRectangle().Width() (pixels available to scroll) + SetControl32BitMaximum( hScrollBar, Platform::Maximum( scrollWidth - GetTextRectangle().Width(), 0 ) ); + + // Vertical page size = nPage + SetControlViewSize( vScrollBar, nPage ); + // Horizontal page size = TextRectangle().Width() + SetControlViewSize( hScrollBar, GetTextRectangle().Width() ); + + // TODO: Verify what this return value is for + // The scroll bar components will handle if they need to be rerendered or not + return false; +} + +void ScintillaMacOSX::ReconfigureScrollBars() { + PRectangle rc = wMain.GetClientPosition(); + Resize(rc.Width(), rc.Height()); +} + +void ScintillaMacOSX::Resize(int width, int height) { + // Get the horizontal/vertical size of the scroll bars + GetThemeMetric( kThemeMetricScrollBarWidth, &scrollBarFixedSize ); + + bool showSBHorizontal = horizontalScrollBarVisible && (wrapState == eWrapNone); + HIRect scrollRect; + if (verticalScrollBarVisible) { + scrollRect.origin.x = width - scrollBarFixedSize; + scrollRect.origin.y = 0; + scrollRect.size.width = scrollBarFixedSize; + if (showSBHorizontal) { + scrollRect.size.height = Platform::Maximum(1, height - scrollBarFixedSize); + } else { + scrollRect.size.height = height; + } + + HIViewSetFrame( vScrollBar, &scrollRect ); + if (HIViewGetSuperview(vScrollBar) == NULL) { + HIViewSetDrawingEnabled( vScrollBar, true ); + HIViewSetVisible(vScrollBar, true); + HIViewAddSubview(GetViewRef(), vScrollBar ); + Draw1Control(vScrollBar); + } + } else if (HIViewGetSuperview(vScrollBar) != NULL) { + HIViewSetDrawingEnabled( vScrollBar, false ); + HIViewRemoveFromSuperview(vScrollBar); + } + + if (showSBHorizontal) { + scrollRect.origin.x = 0; + // Always draw the scrollbar to avoid the "potiential" horizontal scroll bar and to avoid the resize box. + // This should be "good enough". Best would be to avoid the resize box. + // Even better would be to embed Scintilla inside an HIScrollView, which would handle this for us. + scrollRect.origin.y = height - scrollBarFixedSize; + if (verticalScrollBarVisible) { + scrollRect.size.width = Platform::Maximum( 1, width - scrollBarFixedSize ); + } else { + scrollRect.size.width = width; + } + scrollRect.size.height = scrollBarFixedSize; + + HIViewSetFrame( hScrollBar, &scrollRect ); + if (HIViewGetSuperview(hScrollBar) == NULL) { + HIViewSetDrawingEnabled( hScrollBar, true ); + HIViewAddSubview( GetViewRef(), hScrollBar ); + Draw1Control(hScrollBar); + } + } else if (HIViewGetSuperview(hScrollBar) != NULL) { + HIViewSetDrawingEnabled( hScrollBar, false ); + HIViewRemoveFromSuperview(hScrollBar); + } + + ChangeSize(); + + // fixup mouse tracking regions, this causes mouseenter/exit to work + if (HIViewGetSuperview(GetViewRef()) != NULL) { + RgnHandle rgn = NewRgn(); + HIRect r; + HIViewGetFrame( reinterpret_cast( GetViewRef() ), &r ); + SetRectRgn(rgn, short (r.origin.x), short (r.origin.y), + short (r.origin.x + r.size.width - (verticalScrollBarVisible ? scrollBarFixedSize : 0)), + short (r.origin.y + r.size.height - (showSBHorizontal ? scrollBarFixedSize : 0))); + if (mouseTrackingRef == NULL) { + CreateMouseTrackingRegion(GetOwner(), rgn, NULL, + kMouseTrackingOptionsLocalClip, + mouseTrackingID, NULL, + GetControlEventTarget( GetViewRef() ), + &mouseTrackingRef); + } else { + ChangeMouseTrackingRegion(mouseTrackingRef, rgn, NULL); + } + DisposeRgn(rgn); + } else { + if (mouseTrackingRef != NULL) { + ReleaseMouseTrackingRegion(mouseTrackingRef); + } + mouseTrackingRef = NULL; + } +} + +pascal void ScintillaMacOSX::LiveScrollHandler( HIViewRef control, SInt16 part ) +{ + int currentValue = GetControl32BitValue( control ); + int min = GetControl32BitMinimum( control ); + int max = GetControl32BitMaximum( control ); + int page = GetControlViewSize( control ); + + // Get a reference to the Scintilla C++ object + ScintillaMacOSX* scintilla = NULL; + OSStatus err; + err = GetControlProperty( control, scintillaMacOSType, 0, sizeof( scintilla ), NULL, &scintilla ); + assert( err == noErr && scintilla != NULL ); + + int singleScroll = 0; + if ( control == scintilla->vScrollBar ) + { + // Vertical single scroll = one line + // TODO: Is there a Scintilla preference for this somewhere? + singleScroll = 1; + } else { + assert( control == scintilla->hScrollBar ); + // Horizontal single scroll = 20 pixels (hardcoded from ScintillaWin) + // TODO: Is there a Scintilla preference for this somewhere? + singleScroll = 20; + } + + // Determine the new value + int newValue = 0; + switch ( part ) + { + case kControlUpButtonPart: + newValue = Platform::Maximum( currentValue - singleScroll, min ); + break; + + case kControlDownButtonPart: + // the the user scrolls to the right, allow more scroll space + if ( control == scintilla->hScrollBar && currentValue >= max) { + // change the max value + scintilla->scrollWidth += singleScroll; + SetControl32BitMaximum( control, + Platform::Maximum( scintilla->scrollWidth - scintilla->GetTextRectangle().Width(), 0 ) ); + max = GetControl32BitMaximum( control ); + scintilla->SetScrollBars(); + } + newValue = Platform::Minimum( currentValue + singleScroll, max ); + break; + + case kControlPageUpPart: + newValue = Platform::Maximum( currentValue - page, min ); + break; + + case kControlPageDownPart: + newValue = Platform::Minimum( currentValue + page, max ); + break; + + case kControlIndicatorPart: + case kControlNoPart: + newValue = currentValue; + break; + + default: + assert( false ); + return; + } + + // Set the new value + if ( control == scintilla->vScrollBar ) + { + scintilla->ScrollTo( newValue ); + } else { + assert( control == scintilla->hScrollBar ); + scintilla->HorizontalScrollTo( newValue ); + } +} + +bool ScintillaMacOSX::ScrollBarHit(HIPoint location) { + // is this on our scrollbars? If so, track them + HIViewRef view; + // view is null if on editor, otherwise on scrollbar + HIViewGetSubviewHit(reinterpret_cast(wMain.GetID()), + &location, true, &view); + if (view) { + HIViewPartCode part; + + // make the point local to a scrollbar + PRectangle client = GetClientRectangle(); + if (view == vScrollBar) { + location.x -= client.Width(); + } else if (view == hScrollBar) { + location.y -= client.Height(); + } else { + fprintf(stderr, "got a subview hit, but not a scrollbar???\n"); + return false; + } + + HIViewGetPartHit(view, &location, &part); + + switch (part) + { + case kControlUpButtonPart: + case kControlDownButtonPart: + case kControlPageUpPart: + case kControlPageDownPart: + case kControlIndicatorPart: + ::Point p; + p.h = location.x; + p.v = location.y; + // We are assuming Appearance 1.1 or later, so we + // have the "live scroll" variant of the scrollbar, + // which lets you pass the action proc to TrackControl + // for the thumb (this was illegal in previous + // versions of the defproc). + isTracking = true; + ::TrackControl(view, p, ScintillaMacOSX::LiveScrollHandler); + ::HiliteControl(view, 0); + isTracking = false; + // The mouseup was eaten by TrackControl, however if we + // do not get a mouseup in the scintilla xbl widget, + // many bad focus issues happen. Simply post a mouseup + // and this firey pit becomes a bit cooler. + PostEvent(mouseUp, 0); + break; + default: + fprintf(stderr, "PlatformScrollBarHit part %d\n", part); + } + return true; + } + return false; +} + +void ScintillaMacOSX::NotifyFocus(bool focus) { +#ifdef EXT_INPUT + ExtInput::activate (GetViewRef(), focus); +#endif + if (NULL != notifyProc) + notifyProc (notifyObj, WM_COMMAND, + (uintptr_t) ((focus ? SCEN_SETFOCUS : SCEN_KILLFOCUS) << 16), + (uintptr_t) GetViewRef()); +} + +void ScintillaMacOSX::NotifyChange() { + if (NULL != notifyProc) + notifyProc (notifyObj, WM_COMMAND, + (uintptr_t) (SCEN_CHANGE << 16), + (uintptr_t) GetViewRef()); +} + +void ScintillaMacOSX::registerNotifyCallback(intptr_t windowid, SciNotifyFunc callback) { + notifyObj = windowid; + notifyProc = callback; +} + +void ScintillaMacOSX::NotifyParent(SCNotification scn) { + if (NULL != notifyProc) { + scn.nmhdr.hwndFrom = (void*) this; + scn.nmhdr.idFrom = (unsigned int)wMain.GetID(); + notifyProc (notifyObj, WM_NOTIFY, (uintptr_t) 0, (uintptr_t) &scn); + } +} + +void ScintillaMacOSX::NotifyKey(int key, int modifiers) { + SCNotification scn; + scn.nmhdr.code = SCN_KEY; + scn.ch = key; + scn.modifiers = modifiers; + + NotifyParent(scn); +} + +void ScintillaMacOSX::NotifyURIDropped(const char *list) { + SCNotification scn; + scn.nmhdr.code = SCN_URIDROPPED; + scn.text = list; + + NotifyParent(scn); +} + +#ifndef EXT_INPUT +// Extended UTF8-UTF6-conversion to handle surrogate pairs correctly (CL265070) +int ScintillaMacOSX::KeyDefault(int key, int modifiers) { + if (!(modifiers & SCI_CTRL) && !(modifiers & SCI_ALT) && (key < 256)) { + AddChar(key); + return 1; + } else { + // Pass up to container in case it is an accelerator + NotifyKey(key, modifiers); + return 0; + } + //Platform::DebugPrintf("SK-key: %d %x %x\n",key, modifiers); +} +#endif + +template +struct StupidMap +{ +public: + T key; + U value; +}; + +template +inline static U StupidMapFindFunction( const StupidMap* elements, size_t length, const T& desiredKey ) +{ + for ( size_t i = 0; i < length; ++ i ) + { + if ( elements[i].key == desiredKey ) + { + return elements[i].value; + } + } + + return NULL; +} + +// NOTE: If this macro is used on a StupidMap that isn't defined by StupidMap x[] = ... +// The size calculation will fail! +#define StupidMapFind( x, y ) StupidMapFindFunction( x, sizeof(x)/sizeof(*x), y ) + +pascal OSStatus ScintillaMacOSX::CommandEventHandler( EventHandlerCallRef /*inCallRef*/, EventRef event, void* data ) +{ + // TODO: Verify automatically that each constant only appears once? + const StupidMap processCommands[] = { + { kHICommandCopy, &ScintillaMacOSX::Copy }, + { kHICommandPaste, &ScintillaMacOSX::Paste }, + { kHICommandCut, &ScintillaMacOSX::Cut }, + { kHICommandUndo, &ScintillaMacOSX::Undo }, + { kHICommandRedo, &ScintillaMacOSX::Redo }, + { kHICommandClear, &ScintillaMacOSX::ClearSelection }, + { kHICommandSelectAll, &ScintillaMacOSX::SelectAll }, + }; + const StupidMap canProcessCommands[] = { + { kHICommandCopy, &ScintillaMacOSX::HasSelection }, + { kHICommandPaste, &ScintillaMacOSX::CanPaste }, + { kHICommandCut, &ScintillaMacOSX::HasSelection }, + { kHICommandUndo, &ScintillaMacOSX::CanUndo }, + { kHICommandRedo, &ScintillaMacOSX::CanRedo }, + { kHICommandClear, &ScintillaMacOSX::HasSelection }, + { kHICommandSelectAll, &ScintillaMacOSX::AlwaysTrue }, + }; + + HICommand command; + OSStatus result = GetEventParameter( event, kEventParamDirectObject, typeHICommand, NULL, sizeof( command ), NULL, &command ); + assert( result == noErr ); + + UInt32 kind = GetEventKind( event ); + Platform::DebugPrintf("ScintillaMacOSX::CommandEventHandler kind %d\n", kind); + + ScintillaMacOSX* scintilla = reinterpret_cast( data ); + assert( scintilla != NULL ); + + if ( kind == kEventProcessCommand ) + { +#ifdef EXT_INPUT + // We are getting a HI command, so stop extended input + ExtInput::stop (scintilla->GetViewRef()); +#endif + // Find the method pointer that matches this command + void (ScintillaMacOSX::*methodPtr)() = StupidMapFind( processCommands, command.commandID ); + + if ( methodPtr != NULL ) + { + // Call the method if we found it, and tell the caller that we handled this event + (scintilla->*methodPtr)(); + result = noErr; + } else { + // tell the caller that we did not handle the event + result = eventNotHandledErr; + } + } + // The default Mac OS X text editor does not handle these events to enable/disable menu items + // Why not? I think it should, so Scintilla does. + else if ( kind == kEventCommandUpdateStatus && ( command.attributes & kHICommandFromMenu ) ) + { + // Find the method pointer that matches this command + bool (ScintillaMacOSX::*methodPtr)() = StupidMapFind( canProcessCommands, command.commandID ); + + if ( methodPtr != NULL ) { + // Call the method if we found it: enabling/disabling menu items + if ( (scintilla->*methodPtr)() ) { + EnableMenuItem( command.menu.menuRef, command.menu.menuItemIndex ); + } else { + DisableMenuItem( command.menu.menuRef, command.menu.menuItemIndex ); + } + result = noErr; + } else { + // tell the caller that we did not handle the event + result = eventNotHandledErr; + } + } else { + // Unhandled event: We should never get here + assert( false ); + result = eventNotHandledErr; + } + + return result; +} + +bool ScintillaMacOSX::HasSelection() +{ + return ( !sel.Empty() ); +} + +bool ScintillaMacOSX::CanUndo() +{ + return pdoc->CanUndo(); +} + +bool ScintillaMacOSX::CanRedo() +{ + return pdoc->CanRedo(); +} + +bool ScintillaMacOSX::AlwaysTrue() +{ + return true; +} + +void ScintillaMacOSX::CopyToClipboard(const SelectionText &selectedText) { + PasteboardRef theClipboard; + SetPasteboardData(theClipboard, selectedText); + // Done with the CFString + CFRelease( theClipboard ); +} + +void ScintillaMacOSX::Copy() +{ + if (!sel.Empty()) { +#ifdef EXT_INPUT + ExtInput::stop (GetViewRef()); +#endif + SelectionText selectedText; + CopySelectionRange(&selectedText); + fprintf(stderr, "copied text is rectangular? %d\n", selectedText.rectangular); + CopyToClipboard(selectedText); + } +} + +bool ScintillaMacOSX::CanPaste() +{ + if (!Editor::CanPaste()) + return false; + + PasteboardRef theClipboard; + bool isFileURL = false; + + PasteboardCreate( kPasteboardClipboard, &theClipboard ); + bool ok = GetPasteboardData(theClipboard, NULL, &isFileURL); + CFRelease( theClipboard ); + return ok; +} + +void ScintillaMacOSX::Paste() +{ + Paste(false); +} + +// XXX there is no system flag (I can find) to tell us that a paste is rectangular, so +// applications must implement an additional command (eg. option-V like BBEdit) +// in order to provide rectangular paste +void ScintillaMacOSX::Paste(bool forceRectangular) +{ + PasteboardRef theClipboard; + SelectionText selectedText; + selectedText.rectangular = forceRectangular; + bool isFileURL = false; + PasteboardCreate( kPasteboardClipboard, &theClipboard ); + bool ok = GetPasteboardData(theClipboard, &selectedText, &isFileURL); + CFRelease( theClipboard ); + fprintf(stderr, "paste is rectangular? %d\n", selectedText.rectangular); + if (!ok || !selectedText.s) + // no data or no flavor we support + return; + + pdoc->BeginUndoAction(); + ClearSelection(); + if (selectedText.rectangular) { + SelectionPosition selStart = sel.RangeMain().Start(); + PasteRectangular(selStart, selectedText.s, selectedText.len); + } else + if ( pdoc->InsertString( sel.RangeMain().caret.Position(), selectedText.s, selectedText.len ) ) { + SetEmptySelection( sel.RangeMain().caret.Position() + selectedText.len ); + } + + pdoc->EndUndoAction(); + + Redraw(); + EnsureCaretVisible(); +} + +void ScintillaMacOSX::CreateCallTipWindow(PRectangle rc) { + // create a calltip window + if (!ct.wCallTip.Created()) { + WindowClass windowClass = kHelpWindowClass; + WindowAttributes attributes = kWindowNoAttributes; + Rect contentBounds; + WindowRef outWindow; + + // convert PRectangle to Rect + // this adjustment gets the calltip window placed in the correct location relative + // to our editor window + Rect bounds; + OSStatus err; + err = GetWindowBounds( this->GetOwner(), kWindowGlobalPortRgn, &bounds ); + assert( err == noErr ); + contentBounds.top = rc.top + bounds.top; + contentBounds.bottom = rc.bottom + bounds.top; + contentBounds.right = rc.right + bounds.left; + contentBounds.left = rc.left + bounds.left; + + // create our calltip hiview + HIViewRef ctw = scintilla_calltip_new(); + CallTip* objectPtr = &ct; + ScintillaMacOSX* sciThis = this; + SetControlProperty( ctw, scintillaMacOSType, 0, sizeof( this ), &sciThis ); + SetControlProperty( ctw, scintillaCallTipType, 0, sizeof( objectPtr ), &objectPtr ); + + CreateNewWindow(windowClass, attributes, &contentBounds, &outWindow); + ControlRef root; + CreateRootControl(outWindow, &root); + + HIViewRef hiroot = HIViewGetRoot (outWindow); + HIViewAddSubview(hiroot, ctw); + + HIRect boundsRect; + HIViewGetFrame(hiroot, &boundsRect); + HIViewSetFrame( ctw, &boundsRect ); + + // bind the size of the calltip to the size of it's container window + HILayoutInfo layout = { + kHILayoutInfoVersionZero, + { + { NULL, kHILayoutBindTop, 0 }, + { NULL, kHILayoutBindLeft, 0 }, + { NULL, kHILayoutBindBottom, 0 }, + { NULL, kHILayoutBindRight, 0 } + }, + { + { NULL, kHILayoutScaleAbsolute, 0 }, + { NULL, kHILayoutScaleAbsolute, 0 } + + }, + { + { NULL, kHILayoutPositionTop, 0 }, + { NULL, kHILayoutPositionLeft, 0 } + } + }; + HIViewSetLayoutInfo(ctw, &layout); + + ct.wCallTip = root; + ct.wDraw = ctw; + ct.wCallTip.SetWindow(outWindow); + HIViewSetVisible(ctw,true); + + } +} + +void ScintillaMacOSX::CallTipClick() +{ + ScintillaBase::CallTipClick(); +} + +void ScintillaMacOSX::AddToPopUp( const char *label, int cmd, bool enabled ) +{ + // Translate stuff into menu item attributes + MenuItemAttributes attributes = 0; + if ( label[0] == '\0' ) attributes |= kMenuItemAttrSeparator; + if ( ! enabled ) attributes |= kMenuItemAttrDisabled; + + // Translate Scintilla commands into Mac OS commands + // TODO: If I create an AEDesc, OS X may insert these standard + // text editing commands into the menu for me + MenuCommand macCommand; + switch( cmd ) + { + case idcmdUndo: + macCommand = kHICommandUndo; + break; + case idcmdRedo: + macCommand = kHICommandRedo; + break; + case idcmdCut: + macCommand = kHICommandCut; + break; + case idcmdCopy: + macCommand = kHICommandCopy; + break; + case idcmdPaste: + macCommand = kHICommandPaste; + break; + case idcmdDelete: + macCommand = kHICommandClear; + break; + case idcmdSelectAll: + macCommand = kHICommandSelectAll; + break; + case 0: + macCommand = 0; + break; + default: + assert( false ); + return; + } + + CFStringRef string = CFStringCreateWithCString( NULL, label, kCFStringEncodingUTF8 ); + OSStatus err; + err = AppendMenuItemTextWithCFString( reinterpret_cast( popup.GetID() ), + string, attributes, macCommand, NULL ); + assert( err == noErr ); + + CFRelease( string ); + string = NULL; +} + +void ScintillaMacOSX::ClaimSelection() { + // Mac OS X does not have a primary selection +} + +/** A wrapper function to permit external processes to directly deliver messages to our "message loop". */ +sptr_t ScintillaMacOSX::DirectFunction( + ScintillaMacOSX *sciThis, unsigned int iMessage, uptr_t wParam, sptr_t lParam) { + return sciThis->WndProc(iMessage, wParam, lParam); +} + +sptr_t scintilla_send_message(void* sci, unsigned int iMessage, uptr_t wParam, sptr_t lParam) { + HIViewRef control = reinterpret_cast(sci); + // Platform::DebugPrintf("scintilla_send_message %08X control %08X\n",sci,control); + // Get a reference to the Scintilla C++ object + ScintillaMacOSX* scintilla = NULL; + OSStatus err; + err = GetControlProperty( control, scintillaMacOSType, 0, sizeof( scintilla ), NULL, &scintilla ); + assert( err == noErr && scintilla != NULL ); + //Platform::DebugPrintf("scintilla_send_message scintilla %08X\n",scintilla); + + return scintilla->WndProc(iMessage, wParam, lParam); +} + +void ScintillaMacOSX::TimerFired( EventLoopTimerRef ) +{ + Tick(); + DragScroll(); +} + +OSStatus ScintillaMacOSX::BoundsChanged( UInt32 /*inOptions*/, const HIRect& inOriginalBounds, const HIRect& inCurrentBounds, RgnHandle /*inInvalRgn*/ ) +{ + // If the width or height changed, modify the scroll bars and notify Scintilla + // This event is also delivered when the window moves, and we don't care about that + if ( inOriginalBounds.size.width != inCurrentBounds.size.width || inOriginalBounds.size.height != inCurrentBounds.size.height ) + { + Resize( static_cast( inCurrentBounds.size.width ), static_cast( inCurrentBounds.size.height ) ); + } + return noErr; +} + +void ScintillaMacOSX::Draw( RgnHandle rgn, CGContextRef gc ) +{ + Rect invalidRect; + GetRegionBounds( rgn, &invalidRect ); + + // NOTE: We get draw events that include the area covered by the scroll bar. No fear: Scintilla correctly ignores them + SyncPaint( gc, PRectangle( invalidRect.left, invalidRect.top, invalidRect.right, invalidRect.bottom ) ); +} + +ControlPartCode ScintillaMacOSX::HitTest( const HIPoint& where ) +{ + if ( CGRectContainsPoint( Bounds(), where ) ) + return 1; + else + return kControlNoPart; +} + +OSStatus ScintillaMacOSX::SetFocusPart( ControlPartCode desiredFocus, RgnHandle /*invalidRgn*/, Boolean /*inFocusEverything*/, ControlPartCode* outActualFocus ) +{ + assert( outActualFocus != NULL ); + + if ( desiredFocus == 0 ) { + // We are losing the focus + SetFocusState(false); + } else { + // We are getting the focus + SetFocusState(true); + } + + *outActualFocus = desiredFocus; + return noErr; +} + +// Map Mac Roman character codes to their equivalent Scintilla codes +static inline int KeyTranslate( UniChar unicodeChar ) +{ + switch ( unicodeChar ) + { + case kDownArrowCharCode: + return SCK_DOWN; + case kUpArrowCharCode: + return SCK_UP; + case kLeftArrowCharCode: + return SCK_LEFT; + case kRightArrowCharCode: + return SCK_RIGHT; + case kHomeCharCode: + return SCK_HOME; + case kEndCharCode: + return SCK_END; +#ifndef EXT_INPUT + case kPageUpCharCode: + return SCK_PRIOR; + case kPageDownCharCode: + return SCK_NEXT; +#endif + case kDeleteCharCode: + return SCK_DELETE; + // TODO: Is there an insert key in the mac world? My insert key is the "help" key + case kHelpCharCode: + return SCK_INSERT; + case kEnterCharCode: + case kReturnCharCode: + return SCK_RETURN; +#ifdef EXT_INPUT + // BP 2006-08-22: These codes below should not be translated. Otherwise TextInput() will fail for keys like SCK_ADD, which is '+'. + case kBackspaceCharCode: + return SCK_BACK; + case kFunctionKeyCharCode: + case kBellCharCode: + case kVerticalTabCharCode: + case kFormFeedCharCode: + case 14: + case 15: + case kCommandCharCode: + case kCheckCharCode: + case kAppleLogoCharCode: + case 21: + case 22: + case 23: + case 24: + case 25: + case 26: + case kEscapeCharCode: + return 0; // ignore + default: + return unicodeChar; +#else + case kEscapeCharCode: + return SCK_ESCAPE; + case kBackspaceCharCode: + return SCK_BACK; + case '\t': + return SCK_TAB; + case '+': + return SCK_ADD; + case '-': + return SCK_SUBTRACT; + case '/': + return SCK_DIVIDE; + case kFunctionKeyCharCode: + return kFunctionKeyCharCode; + default: + return 0; +#endif + } +} + +static inline UniChar GetCharacterWithoutModifiers( EventRef rawKeyboardEvent ) +{ + UInt32 keyCode; + // Get the key code from the raw key event + GetEventParameter( rawKeyboardEvent, kEventParamKeyCode, typeUInt32, NULL, sizeof( keyCode ), NULL, &keyCode ); + + // Get the current keyboard layout + // TODO: If this is a performance sink, we need to cache these values + SInt16 lastKeyLayoutID = GetScriptVariable( /*currentKeyScript*/ GetScriptManagerVariable(smKeyScript), smScriptKeys); + Handle uchrHandle = GetResource('uchr', lastKeyLayoutID); + + if (uchrHandle) { + // Translate the key press ignoring ctrl and option + UInt32 ignoredDeadKeys = 0; + UInt32 ignoredActualLength = 0; + UniChar unicodeKey = 0; + // (((modifiers & shiftKey) >> 8) & 0xFF) + OSStatus err; + err = UCKeyTranslate( reinterpret_cast( *uchrHandle ), keyCode, kUCKeyActionDown, + /* modifierKeyState */ 0, LMGetKbdType(), kUCKeyTranslateNoDeadKeysMask, &ignoredDeadKeys, + /* buffer length */ 1, + /* actual length */ &ignoredActualLength, + /* string */ &unicodeKey ); + assert( err == noErr ); + + return unicodeKey; + } + return 0; +} + +// Text input is very annoying: +// If the control key is pressed, or if the key is a "special" key (eg. arrow keys, function keys, whatever) +// we let Scintilla handle it. If scintilla does not handle it, we do nothing (eventNotHandledErr). +// Otherwise, the event is just some text and we add it to the buffer +OSStatus ScintillaMacOSX::TextInput( TCarbonEvent& event ) +{ + // Obtain the number of bytes of text + UInt32 actualSize = 0; + OSStatus err; + err = event.GetParameterSize( kEventParamTextInputSendText, &actualSize ); + assert( err == noErr ); + assert( actualSize != 0 ); + + const int numUniChars = actualSize / sizeof( UniChar ); + +#ifdef EXT_INPUT + UniChar* text = new UniChar [numUniChars]; + err = event.GetParameter( kEventParamTextInputSendText, typeUnicodeText, actualSize, text ); + PLATFORM_ASSERT( err == noErr ); + + int modifiers = GetCurrentEventKeyModifiers(); + + // Loop over all characters in sequence + for (int i = 0; i < numUniChars; i++) + { + UniChar key = KeyTranslate( text[i] ); + if (!key) + continue; + + bool consumed = false; + + // need to go here first so e.g. Tab indentation works + KeyDown ((int) key, (modifiers & shiftKey) != 0 || (modifiers & cmdKey) != 0, (modifiers & controlKey) != 0 || (modifiers & cmdKey) != 0, + (modifiers & optionKey) != 0 || (modifiers & cmdKey) != 0, &consumed); + + // BP 2007-01-08: 1452623 Second Cmd+s to save doc inserts an "s" into the text on Mac. + // At this point we need to ignore all cmd/option keys with char value smaller than 32 + if( !consumed ) + consumed = ( modifiers & ( cmdKey | optionKey ) ) != 0 && text[i] < 32; + + // If not consumed, insert the original key + if (!consumed) + InsertCharacters (text+i, 1); + } + + delete[] text; + return noErr; +#else + // Allocate a buffer for the text using Core Foundation + UniChar* text = reinterpret_cast( CFAllocatorAllocate( CFAllocatorGetDefault(), actualSize, 0 ) ); + assert( text != NULL ); + + // Get a copy of the text + err = event.GetParameter( kEventParamTextInputSendText, typeUnicodeText, actualSize, text ); + assert( err == noErr ); + + // TODO: This is a gross hack to ignore function keys + // Surely we can do better? + if ( numUniChars == 1 && text[0] == kFunctionKeyCharCode ) return eventNotHandledErr; + int modifiers = GetCurrentEventKeyModifiers(); + int scintillaKey = KeyTranslate( text[0] ); + + // Create a CFString which wraps and takes ownership of the "text" buffer + CFStringRef string = CFStringCreateWithCharactersNoCopy( NULL, text, numUniChars, NULL ); + assert( string != NULL ); + //delete text; + text = NULL; + + // If we have a single unicode character that is special or + // to process a command. Try to do some translation. + if ( numUniChars == 1 && ( modifiers & controlKey || scintillaKey != 0 ) ) { + // If we have a modifier, we need to get the character without modifiers + if ( modifiers & controlKey ) { + EventRef rawKeyboardEvent = NULL; + event.GetParameter( + kEventParamTextInputSendKeyboardEvent, + typeEventRef, + sizeof( EventRef ), + &rawKeyboardEvent ); + assert( rawKeyboardEvent != NULL ); + scintillaKey = GetCharacterWithoutModifiers( rawKeyboardEvent ); + + // Make sure that we still handle special characters correctly + int temp = KeyTranslate( scintillaKey ); + if ( temp != 0 ) scintillaKey = temp; + + // TODO: This is a gross Unicode hack: ASCII chars have a value < 127 + if ( scintillaKey <= 127 ) { + scintillaKey = toupper( (char) scintillaKey ); + } + } + + // Code taken from Editor::KeyDown + // It is copied here because we don't want to feed the key via + // KeyDefault if there is no special action + DwellEnd(false); + int scintillaModifiers = ( (modifiers & shiftKey) ? SCI_SHIFT : 0) | ( (modifiers & controlKey) ? SCI_CTRL : 0) | + ( (modifiers & optionKey) ? SCI_ALT : 0); + int msg = kmap.Find( scintillaKey, scintillaModifiers ); + if (msg) { + // The keymap has a special event for this key: perform the operation + WndProc(msg, 0, 0); + err = noErr; + } else { + // We do not handle this event + err = eventNotHandledErr; + } + } else { + CFStringEncoding encoding = ( IsUnicodeMode() ? kCFStringEncodingUTF8 : kCFStringEncodingASCII); + + // Allocate the buffer (don't forget the null!) + CFIndex maximumByteLength = CFStringGetMaximumSizeForEncoding( numUniChars, encoding ) + 1; + char* buffer = new char[maximumByteLength]; + + CFIndex usedBufferLength = 0; + CFIndex numCharsConverted; + numCharsConverted = CFStringGetBytes( string, CFRangeMake( 0, numUniChars ), encoding, + '?', false, reinterpret_cast( buffer ), + maximumByteLength, &usedBufferLength ); + assert( numCharsConverted == numUniChars ); + buffer[usedBufferLength] = '\0'; // null terminate + + // Add all the characters to the document + // NOTE: OS X doesn't specify that text input events provide only a single character + // if we get a single character, add it as a character + // otherwise, we insert the entire string + if ( numUniChars == 1 ) { + AddCharUTF( buffer, usedBufferLength ); + } else { + // WARNING: This is an untested code path as with my US keyboard, I only enter a single character at a time + if (pdoc->InsertString(sel.RangeMain().caret.Position(), buffer, usedBufferLength)) { + SetEmptySelection(sel.RangeMain().caret.Position() + usedBufferLength); + } + } + + // Free the buffer that was allocated + delete[] buffer; + buffer = NULL; + err = noErr; + } + + // Default allocator releases both the CFString and the UniChar buffer (text) + CFRelease( string ); + string = NULL; + + return err; +#endif +} + +UInt32 ScintillaMacOSX::GetBehaviors() +{ + return TView::GetBehaviors() | kControlGetsFocusOnClick | kControlSupportsEmbedding; +} + +OSStatus ScintillaMacOSX::MouseEntered(HIPoint& location, UInt32 /*inKeyModifiers*/, EventMouseButton /*inMouseButton*/, UInt32 /*inClickCount*/ ) +{ + if (!HaveMouseCapture() && HIViewGetSuperview(GetViewRef()) != NULL) { + HIViewRef view; + HIViewGetSubviewHit(reinterpret_cast(wMain.GetID()), &location, true, &view); + if (view) { + // the hit is on a subview (ie. scrollbars) + WndProc(SCI_SETCURSOR, Window::cursorArrow, 0); + } else { + // reset to normal, buttonmove will change for other area's in the editor + WndProc(SCI_SETCURSOR, (long int)SC_CURSORNORMAL, 0); + ButtonMove( Point( static_cast( location.x ), static_cast( location.y ) ) ); + } + return noErr; + } + return eventNotHandledErr; +} + +OSStatus ScintillaMacOSX::MouseExited(HIPoint& location, UInt32 modifiers, EventMouseButton button, UInt32 clickCount ) +{ + if (HIViewGetSuperview(GetViewRef()) != NULL) { + if (HaveMouseCapture()) { + ButtonUp( Scintilla::Point( static_cast( location.x ), static_cast( location.y ) ), + static_cast( GetCurrentEventTime() / kEventDurationMillisecond ), + (modifiers & controlKey) != 0 ); + } + WndProc(SCI_SETCURSOR, Window::cursorArrow, 0); + return noErr; + } + return eventNotHandledErr; +} + + +OSStatus ScintillaMacOSX::MouseDown( HIPoint& location, UInt32 modifiers, EventMouseButton button, UInt32 clickCount , TCarbonEvent& inEvent) +{ + ConvertEventRefToEventRecord( inEvent.GetEventRef(), &mouseDownEvent ); + return MouseDown(location, modifiers, button, clickCount); +} + +OSStatus ScintillaMacOSX::MouseDown( EventRecord *event ) +{ + HIPoint pt = GetLocalPoint(event->where); + int button = kEventMouseButtonPrimary; + mouseDownEvent = *event; + + if ( event->modifiers & controlKey ) + button = kEventMouseButtonSecondary; + return MouseDown(pt, event->modifiers, button, 1); +} + +OSStatus ScintillaMacOSX::MouseDown( HIPoint& location, UInt32 modifiers, EventMouseButton button, UInt32 /*clickCount*/ ) +{ + // We only deal with the first mouse button + if ( button != kEventMouseButtonPrimary ) return eventNotHandledErr; + // TODO: Verify that Scintilla wants the time in milliseconds + if (!HaveMouseCapture() && HIViewGetSuperview(GetViewRef()) != NULL) { + if (ScrollBarHit(location)) return noErr; + } + ButtonDown( Scintilla::Point( static_cast( location.x ), static_cast( location.y ) ), + static_cast( GetCurrentEventTime() / kEventDurationMillisecond ), + (modifiers & shiftKey) != 0, + (modifiers & controlKey) != 0, + (modifiers & cmdKey) ); +#if !defined(CONTAINER_HANDLES_EVENTS) + OSStatus err; + err = SetKeyboardFocus( this->GetOwner(), this->GetViewRef(), 1 ); + ::SetUserFocusWindow(::HIViewGetWindow( this->GetViewRef() )); + return noErr; +#else + return eventNotHandledErr; // allow event to go to container +#endif +} + +OSStatus ScintillaMacOSX::MouseUp( EventRecord *event ) +{ + HIPoint pt = GetLocalPoint(event->where); + int button = kEventMouseButtonPrimary; + if ( event->modifiers & controlKey ) + button = kEventMouseButtonSecondary; + return MouseUp(pt, event->modifiers, button, 1); +} + +OSStatus ScintillaMacOSX::MouseUp( HIPoint& location, UInt32 modifiers, EventMouseButton button, UInt32 /*clickCount*/ ) +{ + // We only deal with the first mouse button + if ( button != kEventMouseButtonPrimary ) return eventNotHandledErr; + ButtonUp( Scintilla::Point( static_cast( location.x ), static_cast( location.y ) ), + static_cast( GetCurrentEventTime() / kEventDurationMillisecond ), + (modifiers & controlKey) != 0 ); + +#if !defined(CONTAINER_HANDLES_EVENTS) + return noErr; +#else + return eventNotHandledErr; // allow event to go to container +#endif +} + +OSStatus ScintillaMacOSX::MouseDragged( EventRecord *event ) +{ + HIPoint pt = GetLocalPoint(event->where); + int button = 0; + if ( event->modifiers & btnStateBit ) { + button = kEventMouseButtonPrimary; + if ( event->modifiers & controlKey ) + button = kEventMouseButtonSecondary; + } + return MouseDragged(pt, event->modifiers, button, 1); +} + +OSStatus ScintillaMacOSX::MouseDragged( HIPoint& location, UInt32 modifiers, EventMouseButton button, UInt32 clickCount ) +{ +#if !defined(CONTAINER_HANDLES_EVENTS) + ButtonMove( Scintilla::Point( static_cast( location.x ), static_cast( location.y ) ) ); + return noErr; +#else + if (HaveMouseCapture() && !inDragDrop) { + MouseTrackingResult mouseStatus = 0; + ::Point theQDPoint; + UInt32 outModifiers; + EventTimeout inTimeout=0.1; + while (mouseStatus != kMouseTrackingMouseReleased) { + ButtonMove( Scintilla::Point( static_cast( location.x ), static_cast( location.y ) ) ); + TrackMouseLocationWithOptions((GrafPtr)-1, + kTrackMouseLocationOptionDontConsumeMouseUp, + inTimeout, + &theQDPoint, + &outModifiers, + &mouseStatus); + location = GetLocalPoint(theQDPoint); + } + ButtonUp( Scintilla::Point( static_cast( location.x ), static_cast( location.y ) ), + static_cast( GetCurrentEventTime() / kEventDurationMillisecond ), + (modifiers & controlKey) != 0 ); + } else { + if (!HaveMouseCapture() && HIViewGetSuperview(GetViewRef()) != NULL) { + HIViewRef view; + HIViewGetSubviewHit(reinterpret_cast(wMain.GetID()), &location, true, &view); + if (view) { + // the hit is on a subview (ie. scrollbars) + WndProc(SCI_SETCURSOR, Window::cursorArrow, 0); + return eventNotHandledErr; + } else { + // reset to normal, buttonmove will change for other area's in the editor + WndProc(SCI_SETCURSOR, (long int)SC_CURSORNORMAL, 0); + } + } + ButtonMove( Scintilla::Point( static_cast( location.x ), static_cast( location.y ) ) ); + } + return eventNotHandledErr; // allow event to go to container +#endif +} + +OSStatus ScintillaMacOSX::MouseWheelMoved( EventMouseWheelAxis axis, SInt32 delta, UInt32 modifiers ) +{ + if ( axis != 1 ) return eventNotHandledErr; + + if ( modifiers & controlKey ) { + // 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 ( delta > 0 ) { + KeyCommand( SCI_ZOOMIN ); + } else { + KeyCommand( SCI_ZOOMOUT ); + } + } else { + // Decide if this should be optimized? + ScrollTo( topLine - delta ); + } + + return noErr; +} + +OSStatus ScintillaMacOSX::ContextualMenuClick( HIPoint& location ) +{ + // convert screen coords to window relative + Rect bounds; + OSStatus err; + err = GetWindowBounds( this->GetOwner(), kWindowContentRgn, &bounds ); + assert( err == noErr ); + location.x += bounds.left; + location.y += bounds.top; + ContextMenu( Scintilla::Point( static_cast( location.x ), static_cast( location.y ) ) ); + return noErr; +} + +OSStatus ScintillaMacOSX::ActiveStateChanged() +{ + // If the window is being deactivated, lose the focus and turn off the ticking + if ( ! this->IsActive() ) { + DropCaret(); + //SetFocusState( false ); + SetTicking( false ); + } else { + ShowCaretAtCurrentPosition(); + } + return noErr; +} + +HIViewRef ScintillaMacOSX::Create() +{ + // Register the HIView, if needed + static bool registered = false; + + if ( not registered ) { + TView::RegisterSubclass( kScintillaClassID, Construct ); + registered = true; + } + + OSStatus err = noErr; + EventRef event = CreateInitializationEvent(); + assert( event != NULL ); + + HIViewRef control = NULL; + err = HIObjectCreate( kScintillaClassID, event, reinterpret_cast( &control ) ); + ReleaseEvent( event ); + if ( err == noErr ) { + Platform::DebugPrintf("ScintillaMacOSX::Create control %08X\n",control); + return control; + } + return NULL; +} + +OSStatus ScintillaMacOSX::Construct( HIViewRef inControl, TView** outView ) +{ + *outView = new ScintillaMacOSX( inControl ); + Platform::DebugPrintf("ScintillaMacOSX::Construct scintilla %08X\n",*outView); + if ( *outView != NULL ) + return noErr; + else + return memFullErr; // could be a lie +} + +extern "C" { +HIViewRef scintilla_new() { + return ScintillaMacOSX::Create(); +} +} diff --git a/scintilla/macosx/ScintillaMacOSX.h b/scintilla/macosx/ScintillaMacOSX.h new file mode 100644 index 00000000..f9348204 --- /dev/null +++ b/scintilla/macosx/ScintillaMacOSX.h @@ -0,0 +1,234 @@ +/* + * ScintillaMacOSX.h + * tutorial + * + * Original code by Evan Jones on Sun Sep 01 2002. + * Contributors: + * Shane Caraveo, ActiveState + * Bernd Paradies, Adobe + * + */ +#include "TView.h" + +#include +#include +#include +#include +#include + +#include + +#include "Platform.h" +#include "Scintilla.h" +#include "PlatMacOSX.h" + + +#include "ScintillaWidget.h" +#ifdef SCI_LEXER +#include "SciLexer.h" +#include "PropSet.h" +#include "PropSetSimple.h" +#include "Accessor.h" +#include "KeyWords.h" +#endif +#include "SVector.h" +#include "SplitVector.h" +#include "Partitioning.h" +#include "RunStyles.h" +#include "ContractionState.h" +#include "CellBuffer.h" +#include "CallTip.h" +#include "KeyMap.h" +#include "Indicator.h" +#include "XPM.h" +#include "LineMarker.h" +#include "Style.h" +#include "AutoComplete.h" +#include "ViewStyle.h" +#include "CharClassify.h" +#include "Decoration.h" +#include "Document.h" +#include "Selection.h" +#include "PositionCache.h" +#include "Editor.h" +#include "ScintillaBase.h" +#include "ScintillaCallTip.h" + +static const OSType scintillaMacOSType = 'Scin'; + +namespace Scintilla { + +/** +On the Mac, there is no WM_COMMAND or WM_NOTIFY message that can be sent +back to the parent. Therefore, there must be a callback handler that acts +like a Windows WndProc, where Scintilla can send notifications to. Use +ScintillaMacOSX::registerNotifyHandler() to register such a handler. +Messgae format is: +
+WM_COMMAND: HIWORD (wParam) = notification code, LOWORD (wParam) = 0 (no control ID), lParam = ScintillaMacOSX* +
+WM_NOTIFY: wParam = 0 (no control ID), lParam = ptr to SCNotification structure, with hwndFrom set to ScintillaMacOSX* +*/ +typedef void(*SciNotifyFunc) (intptr_t windowid, unsigned int iMessage, uintptr_t wParam, uintptr_t lParam); + +/** +Scintilla sends these two messages to the nofity handler. Please refer +to the Windows API doc for details about the message format. +*/ +#define WM_COMMAND 1001 +#define WM_NOTIFY 1002 + +class ScintillaMacOSX : public ScintillaBase, public TView +{ + public: + HIViewRef vScrollBar; + HIViewRef hScrollBar; + SInt32 scrollBarFixedSize; + SciNotifyFunc notifyProc; + intptr_t notifyObj; + + bool capturedMouse; + // true if scintilla initiated the drag session + bool inDragSession() { return inDragDrop == ddDragging; }; + bool isTracking; + + // Private so ScintillaMacOSX objects can not be copied + ScintillaMacOSX(const ScintillaMacOSX &) : ScintillaBase(), TView( NULL ) {} + ScintillaMacOSX &operator=(const ScintillaMacOSX &) { return * this; } + +public: + /** This is the class ID that we've assigned to Scintilla. */ + static const CFStringRef kScintillaClassID; + static const ControlKind kScintillaKind; + + ScintillaMacOSX( void* windowid ); + virtual ~ScintillaMacOSX(); + //~ static void ClassInit(GtkObjectClass* object_class, GtkWidgetClass *widget_class); + + /** Returns the HIView object kind, needed to subclass TView. */ + virtual ControlKind GetKind() { return kScintillaKind; } + + /// Register the notify callback + void registerNotifyCallback(intptr_t windowid, SciNotifyFunc callback); +private: + virtual void Initialise(); + virtual void Finalise(); + + // pasteboard support + bool GetPasteboardData(PasteboardRef &pasteBoard, + SelectionText *selectedText, bool *isFileURL); + void SetPasteboardData(PasteboardRef &pasteBoard, + const SelectionText &selectedText); + char *GetStringFromCFString(CFStringRef &textString, int *textLen); + + // Drag and drop + virtual void StartDrag(); + Scintilla::Point GetDragPoint(DragRef inDrag); + bool GetDragData(DragRef inDrag, PasteboardRef &pasteBoard, + SelectionText *selectedText, + bool *isFileURL); + void SetDragCursor(DragRef inDrag); + virtual bool DragEnter(DragRef inDrag ); + virtual bool DragWithin(DragRef inDrag ); + virtual bool DragLeave(DragRef inDrag ); + virtual OSStatus DragReceive(DragRef inDrag ); + void DragScroll(); + int scrollSpeed; + int scrollTicks; + + EventRecord mouseDownEvent; + MouseTrackingRef mouseTrackingRef; + MouseTrackingRegionID mouseTrackingID; + HIPoint GetLocalPoint(::Point pt); + + void InsertCharacters (const UniChar* buf, int len); + static pascal void IdleTimerEventHandler(EventLoopTimerRef inTimer, + EventLoopIdleTimerMessage inState, + void *scintilla ); + +public: // Public for scintilla_send_message + virtual sptr_t WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam); + + void SyncPaint( void* gc, PRectangle rc); + //void FullPaint( void* gc ); + virtual void Draw( RgnHandle rgn, CGContextRef gc ); + + virtual sptr_t DefWndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam); + virtual void SetTicking(bool on); + virtual bool SetIdle(bool on); + virtual void SetMouseCapture(bool on); + virtual bool HaveMouseCapture(); + virtual PRectangle GetClientRectangle(); + + virtual void ScrollText(int linesToMove); + virtual void SetVerticalScrollPos(); + virtual void SetHorizontalScrollPos(); + virtual bool ModifyScrollBars(int nMax, int nPage); + virtual void ReconfigureScrollBars(); + void Resize(int width, int height); + static pascal void LiveScrollHandler( ControlHandle control, SInt16 part ); + bool ScrollBarHit(HIPoint location); + + virtual void NotifyChange(); + virtual void NotifyFocus(bool focus); + virtual void NotifyParent(SCNotification scn); + void NotifyKey(int key, int modifiers); + void NotifyURIDropped(const char *list); +#ifndef EXT_INPUT + // Extended UTF8-UTF6-conversion to handle surrogate pairs correctly (CL265070) + virtual int KeyDefault(int key, int modifiers); +#endif + static pascal OSStatus CommandEventHandler( EventHandlerCallRef inCallRef, EventRef inEvent, void* data ); + + bool HasSelection(); + bool CanUndo(); + bool CanRedo(); + bool AlwaysTrue(); + virtual void CopyToClipboard(const SelectionText &selectedText); + virtual void Copy(); + virtual bool CanPaste(); + virtual void Paste(); + virtual void Paste(bool rectangular); + virtual void CreateCallTipWindow(PRectangle rc); + virtual void AddToPopUp(const char *label, int cmd = 0, bool enabled = true); + virtual void ClaimSelection(); + + static sptr_t DirectFunction(ScintillaMacOSX *sciThis, + unsigned int iMessage, uptr_t wParam, sptr_t lParam); + + /** Timer event handler. Simply turns around and calls Tick. */ + virtual void TimerFired( EventLoopTimerRef ); + virtual OSStatus BoundsChanged( UInt32 inOptions, const HIRect& inOriginalBounds, const HIRect& inCurrentBounds, RgnHandle inInvalRgn ); + virtual ControlPartCode HitTest( const HIPoint& where ); + virtual OSStatus SetFocusPart( ControlPartCode desiredFocus, RgnHandle, Boolean, ControlPartCode* outActualFocus ); + virtual OSStatus TextInput( TCarbonEvent& event ); + + // Configure the features of this control + virtual UInt32 GetBehaviors(); + + virtual OSStatus MouseDown( HIPoint& location, UInt32 modifiers, EventMouseButton button, UInt32 clickCount, TCarbonEvent& inEvent ); + virtual OSStatus MouseDown( HIPoint& location, UInt32 modifiers, EventMouseButton button, UInt32 clickCount ); + virtual OSStatus MouseDown( EventRecord *rec ); + virtual OSStatus MouseUp( HIPoint& location, UInt32 modifiers, EventMouseButton button, UInt32 clickCount ); + virtual OSStatus MouseUp( EventRecord *rec ); + virtual OSStatus MouseDragged( HIPoint& location, UInt32 modifiers, EventMouseButton button, UInt32 clickCount ); + virtual OSStatus MouseDragged( EventRecord *rec ); + virtual OSStatus MouseEntered( HIPoint& location, UInt32 modifiers, EventMouseButton button, UInt32 clickCount ); + virtual OSStatus MouseExited( HIPoint& location, UInt32 modifiers, EventMouseButton button, UInt32 clickCount ); + virtual OSStatus MouseWheelMoved( EventMouseWheelAxis axis, SInt32 delta, UInt32 modifiers ); + virtual OSStatus ContextualMenuClick( HIPoint& location ); + + virtual OSStatus ActiveStateChanged(); + + virtual void CallTipClick(); + + +public: + static HIViewRef Create(); +private: + static OSStatus Construct( HIViewRef inControl, TView** outView ); + +}; + + +} diff --git a/scintilla/macosx/TCarbonEvent.cxx b/scintilla/macosx/TCarbonEvent.cxx new file mode 100644 index 00000000..6fe98c8c --- /dev/null +++ b/scintilla/macosx/TCarbonEvent.cxx @@ -0,0 +1,519 @@ +/* + File: TCarbonEvent.cp + + Version: 1.0 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc. + ("Apple") in consideration of your agreement to the following terms, and your + use, installation, modification or redistribution of this Apple software + constitutes acceptance of these terms. If you do not agree with these terms, + please do not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and subject + to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs + copyrights in this original Apple software (the "Apple Software"), to use, + reproduce, modify and redistribute the Apple Software, with or without + modifications, in source and/or binary forms; provided that if you redistribute + the Apple Software in its entirety and without modifications, you must retain + this notice and the following text and disclaimers in all such redistributions of + the Apple Software. Neither the name, trademarks, service marks or logos of + Apple Computer, Inc. may be used to endorse or promote products derived from the + Apple Software without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or implied, + are granted by Apple herein, including but not limited to any patent rights that + may be infringed by your derivative works or by other works in which the Apple + Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO + WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED + WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION + OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT + (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + Copyright © 2002 Apple Computer, Inc., All Rights Reserved +*/ + +#include "TCarbonEvent.h" + +//----------------------------------------------------------------------------------- +// TCarbonEvent constructor +//----------------------------------------------------------------------------------- +// +TCarbonEvent::TCarbonEvent( + UInt32 inClass, + UInt32 inKind ) +{ + CreateEvent( NULL, inClass, inKind, GetCurrentEventTime(), 0, &fEvent ); +} + +//----------------------------------------------------------------------------------- +// TCarbonEvent constructor +//----------------------------------------------------------------------------------- +// +TCarbonEvent::TCarbonEvent( + EventRef inEvent ) +{ + fEvent = inEvent; + RetainEvent( fEvent ); +} + +//----------------------------------------------------------------------------------- +// TCarbonEvent destructor +//----------------------------------------------------------------------------------- +// +TCarbonEvent::~TCarbonEvent() +{ + ReleaseEvent( fEvent ); +} + +//----------------------------------------------------------------------------------- +// GetClass +//----------------------------------------------------------------------------------- +// +UInt32 TCarbonEvent::GetClass() const +{ + return GetEventClass( fEvent ); +} + +//----------------------------------------------------------------------------------- +// GetKind +//----------------------------------------------------------------------------------- +// +UInt32 TCarbonEvent::GetKind() const +{ + return GetEventKind( fEvent ); +} + +//----------------------------------------------------------------------------------- +// SetTime +//----------------------------------------------------------------------------------- +// +void TCarbonEvent::SetTime( + EventTime inTime ) +{ + SetEventTime( fEvent, inTime ); +} + +//----------------------------------------------------------------------------------- +// GetTime +//----------------------------------------------------------------------------------- +// +EventTime TCarbonEvent::GetTime() const +{ + return GetEventTime( fEvent ); +} + +//----------------------------------------------------------------------------------- +// Retain +//----------------------------------------------------------------------------------- +// +void TCarbonEvent::Retain() +{ + RetainEvent( fEvent ); +} + +//----------------------------------------------------------------------------------- +// Release +//----------------------------------------------------------------------------------- +// +void TCarbonEvent::Release() +{ + ReleaseEvent( fEvent ); +} + +//----------------------------------------------------------------------------------- +// PostToQueue +//----------------------------------------------------------------------------------- +// +OSStatus TCarbonEvent::PostToQueue( + EventQueueRef inQueue, + EventPriority inPriority ) +{ + return PostEventToQueue( inQueue, fEvent, inPriority ); +} + +//----------------------------------------------------------------------------------- +// SetParameter +//----------------------------------------------------------------------------------- +// +OSStatus TCarbonEvent::SetParameter( + EventParamName inName, + EventParamType inType, + UInt32 inSize, + const void* inData ) +{ + return SetEventParameter( fEvent, inName, inType, inSize, inData ); +} + +//----------------------------------------------------------------------------------- +// GetParameter +//----------------------------------------------------------------------------------- +// +OSStatus TCarbonEvent::GetParameter( + EventParamName inName, + EventParamType inType, + UInt32 inBufferSize, + void* outData ) +{ + return GetEventParameter( fEvent, inName, inType, NULL, inBufferSize, NULL, outData ); +} + +//----------------------------------------------------------------------------------- +// GetParameterType +//----------------------------------------------------------------------------------- +// +OSStatus TCarbonEvent::GetParameterType( + EventParamName inName, + EventParamType* outType ) +{ + return GetEventParameter( fEvent, inName, typeWildCard, outType, 0, NULL, NULL ); +} + +//----------------------------------------------------------------------------------- +// GetParameterSize +//----------------------------------------------------------------------------------- +// +OSStatus TCarbonEvent::GetParameterSize( + EventParamName inName, + UInt32* outSize ) +{ + return GetEventParameter( fEvent, inName, typeWildCard, NULL, 0, outSize, NULL ); +} + +//----------------------------------------------------------------------------------- +// SetParameter +//----------------------------------------------------------------------------------- +// +OSStatus TCarbonEvent::SetParameter( + EventParamName inName, + Boolean inValue ) +{ + return SetParameter( inName, typeBoolean, inValue ); +} + +//----------------------------------------------------------------------------------- +// GetParameter +//----------------------------------------------------------------------------------- +// +OSStatus TCarbonEvent::GetParameter( + EventParamName inName, + Boolean* outValue ) +{ + return GetParameter( inName, typeBoolean, outValue ); +} + +//----------------------------------------------------------------------------------- +// SetParameter +//----------------------------------------------------------------------------------- +// +OSStatus TCarbonEvent::SetParameter( + EventParamName inName, + bool inValue ) +{ + return SetParameter( inName, typeBoolean, (Boolean) inValue ); +} + +//----------------------------------------------------------------------------------- +// GetParameter +//----------------------------------------------------------------------------------- +// +OSStatus TCarbonEvent::GetParameter( + EventParamName inName, + bool* outValue ) +{ + return GetParameter( inName, sizeof( Boolean ), (Boolean*) outValue ); +} + +//----------------------------------------------------------------------------------- +// SetParameter +//----------------------------------------------------------------------------------- +// +OSStatus TCarbonEvent::SetParameter( + EventParamName inName, + Point inPt ) +{ + return SetParameter( inName, typeQDPoint, inPt ); +} + +//----------------------------------------------------------------------------------- +// GetParameter +//----------------------------------------------------------------------------------- +// +OSStatus TCarbonEvent::GetParameter( + EventParamName inName, + Point* outPt ) +{ + return GetParameter( inName, typeQDPoint, outPt ); +} + +//----------------------------------------------------------------------------------- +// SetParameter +//----------------------------------------------------------------------------------- +// +OSStatus TCarbonEvent::SetParameter( + EventParamName inName, + const HIPoint& inPt ) +{ + return SetParameter( inName, typeHIPoint, inPt ); +} + +//----------------------------------------------------------------------------------- +// GetParameter +//----------------------------------------------------------------------------------- +// +OSStatus TCarbonEvent::GetParameter( + EventParamName inName, + HIPoint* outPt ) +{ + return GetParameter( inName, typeHIPoint, outPt ); +} + +//----------------------------------------------------------------------------------- +// SetParameter +//----------------------------------------------------------------------------------- +// +OSStatus TCarbonEvent::SetParameter( + EventParamName inName, + const Rect& inRect ) +{ + return SetParameter( inName, typeQDRectangle, inRect ); +} + +//----------------------------------------------------------------------------------- +// GetParameter +//----------------------------------------------------------------------------------- +// +OSStatus TCarbonEvent::GetParameter( + EventParamName inName, + Rect* outRect ) +{ + return GetParameter( inName, typeQDRectangle, outRect ); +} + +//----------------------------------------------------------------------------------- +// SetParameter +//----------------------------------------------------------------------------------- +// +OSStatus TCarbonEvent::SetParameter( + EventParamName inName, + const HIRect& inRect ) +{ + return SetParameter( inName, typeHIRect, inRect ); +} + +//----------------------------------------------------------------------------------- +// GetParameter +//----------------------------------------------------------------------------------- +// +OSStatus TCarbonEvent::GetParameter( + EventParamName inName, + HIRect* outRect ) +{ + return GetParameter( inName, typeHIRect, outRect ); +} + +//----------------------------------------------------------------------------------- +// SetParameter +//----------------------------------------------------------------------------------- +// +OSStatus TCarbonEvent::SetParameter( + EventParamName inName, + const HISize& inSize ) +{ + return SetParameter( inName, typeHISize, inSize ); +} + +//----------------------------------------------------------------------------------- +// GetParameter +//----------------------------------------------------------------------------------- +// +OSStatus TCarbonEvent::GetParameter( + EventParamName inName, + HISize* outSize ) +{ + return GetParameter( inName, typeHISize, outSize ); +} + +//----------------------------------------------------------------------------------- +// SetParameter +//----------------------------------------------------------------------------------- +// +OSStatus TCarbonEvent::SetParameter( + EventParamName inName, + RgnHandle inRegion ) +{ + return SetParameter( inName, typeQDRgnHandle, inRegion ); +} + +//----------------------------------------------------------------------------------- +// GetParameter +//----------------------------------------------------------------------------------- +// +OSStatus TCarbonEvent::GetParameter( + EventParamName inName, + RgnHandle* outRegion ) +{ + return GetParameter( inName, typeQDRgnHandle, outRegion ); +} + +//----------------------------------------------------------------------------------- +// SetParameter +//----------------------------------------------------------------------------------- +// +OSStatus TCarbonEvent::SetParameter( + EventParamName inName, + WindowRef inWindow ) +{ + return SetParameter( inName, typeWindowRef, inWindow ); +} + +//----------------------------------------------------------------------------------- +// GetParameter +//----------------------------------------------------------------------------------- +// +OSStatus TCarbonEvent::GetParameter( + EventParamName inName, + WindowRef* outWindow ) +{ + return GetParameter( inName, typeWindowRef, outWindow ); +} + +//----------------------------------------------------------------------------------- +// SetParameter +//----------------------------------------------------------------------------------- +// +OSStatus TCarbonEvent::SetParameter( + EventParamName inName, + ControlRef inControl ) +{ + return SetParameter( inName, typeControlRef, inControl ); +} + +//----------------------------------------------------------------------------------- +// GetParameter +//----------------------------------------------------------------------------------- +// +OSStatus TCarbonEvent::GetParameter( + EventParamName inName, + ControlRef* outControl ) +{ + return GetParameter( inName, typeControlRef, outControl ); +} + +//----------------------------------------------------------------------------------- +// SetParameter +//----------------------------------------------------------------------------------- +// +OSStatus TCarbonEvent::SetParameter( + EventParamName inName, + MenuRef inMenu ) +{ + return SetParameter( inName, typeMenuRef, inMenu ); +} + +//----------------------------------------------------------------------------------- +// GetParameter +//----------------------------------------------------------------------------------- +// +OSStatus TCarbonEvent::GetParameter( + EventParamName inName, + MenuRef* outMenu ) +{ + return GetParameter( inName, typeMenuRef, outMenu ); +} + +//----------------------------------------------------------------------------------- +// SetParameter +//----------------------------------------------------------------------------------- +// +OSStatus TCarbonEvent::SetParameter( + EventParamName inName, + DragRef inDrag ) +{ + return SetParameter( inName, typeDragRef, inDrag ); +} + +//----------------------------------------------------------------------------------- +// GetParameter +//----------------------------------------------------------------------------------- +// +OSStatus TCarbonEvent::GetParameter( + EventParamName inName, + DragRef* outDrag ) +{ + return GetParameter( inName, typeDragRef, outDrag ); +} + +//----------------------------------------------------------------------------------- +// SetParameter +//----------------------------------------------------------------------------------- +// +OSStatus TCarbonEvent::SetParameter( + EventParamName inName, + UInt32 inValue ) +{ + return SetParameter( inName, typeUInt32, inValue ); +} + +//----------------------------------------------------------------------------------- +// GetParameter +//----------------------------------------------------------------------------------- +// +OSStatus TCarbonEvent::GetParameter( + EventParamName inName, + UInt32* outValue ) +{ + return GetParameter( inName, typeUInt32, outValue ); +} + +//----------------------------------------------------------------------------------- +// SetParameter +//----------------------------------------------------------------------------------- +// +OSStatus TCarbonEvent::SetParameter( + EventParamName inName, + const HICommand& inValue ) +{ + return SetParameter( inName, typeHICommand, inValue ); +} + +//----------------------------------------------------------------------------------- +// GetParameter +//----------------------------------------------------------------------------------- +// +OSStatus TCarbonEvent::GetParameter( + EventParamName inName, + HICommand* outValue ) +{ + return GetParameter( inName, typeHICommand, outValue ); +} + +//----------------------------------------------------------------------------------- +// SetParameter +//----------------------------------------------------------------------------------- +// +OSStatus TCarbonEvent::SetParameter( + EventParamName inName, + const ControlPartCode& inValue ) +{ + return SetParameter( inName, typeControlPartCode, inValue ); +} + +//----------------------------------------------------------------------------------- +// GetParameter +//----------------------------------------------------------------------------------- +// +OSStatus TCarbonEvent::GetParameter( + EventParamName inName, + ControlPartCode* outValue ) +{ + return GetParameter( inName, typeControlPartCode, outValue ); +} diff --git a/scintilla/macosx/TCarbonEvent.h b/scintilla/macosx/TCarbonEvent.h new file mode 100644 index 00000000..0c1e2cf7 --- /dev/null +++ b/scintilla/macosx/TCarbonEvent.h @@ -0,0 +1,230 @@ +/* + File: TCarbonEvent.h + + Version: 1.0 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc. + ("Apple") in consideration of your agreement to the following terms, and your + use, installation, modification or redistribution of this Apple software + constitutes acceptance of these terms. If you do not agree with these terms, + please do not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and subject + to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs + copyrights in this original Apple software (the "Apple Software"), to use, + reproduce, modify and redistribute the Apple Software, with or without + modifications, in source and/or binary forms; provided that if you redistribute + the Apple Software in its entirety and without modifications, you must retain + this notice and the following text and disclaimers in all such redistributions of + the Apple Software. Neither the name, trademarks, service marks or logos of + Apple Computer, Inc. may be used to endorse or promote products derived from the + Apple Software without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or implied, + are granted by Apple herein, including but not limited to any patent rights that + may be infringed by your derivative works or by other works in which the Apple + Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO + WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED + WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION + OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT + (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + Copyright © 2002 Apple Computer, Inc., All Rights Reserved +*/ + +#ifndef TCarbonEvent_H_ +#define TCarbonEvent_H_ + +#include + +class TCarbonEvent +{ +public: + // Construction/Destruction + TCarbonEvent( + UInt32 inClass, + UInt32 inKind ); + TCarbonEvent( + EventRef inEvent ); + virtual ~TCarbonEvent(); + + UInt32 GetClass() const; + UInt32 GetKind() const; + + // Time + void SetTime( + EventTime inTime ); + EventTime GetTime() const; + + // Retention + void Retain(); + void Release(); + + // Accessors + operator EventRef&() + { return fEvent; }; + EventRef GetEventRef() + { return fEvent; } + + // Posting + OSStatus PostToQueue( + EventQueueRef inQueue, + EventPriority inPriority = kEventPriorityStandard ); + + // Parameters + OSStatus SetParameter( + EventParamName inName, + EventParamType inType, + UInt32 inSize, + const void* inData ); + OSStatus GetParameter( + EventParamName inName, + EventParamType inType, + UInt32 inBufferSize, + void* outData ); + + OSStatus GetParameterType( + EventParamName inName, + EventParamType* outType ); + OSStatus GetParameterSize( + EventParamName inName, + UInt32* outSize ); + + // Simple parameters + OSStatus SetParameter( + EventParamName inName, + Boolean inValue ); + OSStatus GetParameter( + EventParamName inName, + Boolean* outValue ); + + OSStatus SetParameter( + EventParamName inName, + bool inValue ); + OSStatus GetParameter( + EventParamName inName, + bool* outValue ); + + OSStatus SetParameter( + EventParamName inName, + Point inPt ); + OSStatus GetParameter( + EventParamName inName, + Point* outPt ); + + OSStatus SetParameter( + EventParamName inName, + const HIPoint& inPt ); + + OSStatus GetParameter( + EventParamName inName, + HIPoint* outPt ); + + OSStatus SetParameter( + EventParamName inName, + const Rect& inRect ); + OSStatus GetParameter( + EventParamName inName, + Rect* outRect ); + + OSStatus SetParameter( + EventParamName inName, + const HIRect& inRect ); + OSStatus GetParameter( + EventParamName inName, + HIRect* outRect ); + + OSStatus SetParameter( + EventParamName inName, + const HISize& inSize ); + OSStatus GetParameter( + EventParamName inName, + HISize* outSize ); + + OSStatus SetParameter( + EventParamName inName, + RgnHandle inRegion ); + OSStatus GetParameter( + EventParamName inName, + RgnHandle* outRegion ); + + OSStatus SetParameter( + EventParamName inName, + WindowRef inWindow ); + OSStatus GetParameter( + EventParamName inName, + WindowRef* outWindow ); + + OSStatus SetParameter( + EventParamName inName, + ControlRef inControl ); + OSStatus GetParameter( + EventParamName inName, + ControlRef* outControl ); + + OSStatus SetParameter( + EventParamName inName, + MenuRef inMenu ); + OSStatus GetParameter( + EventParamName inName, + MenuRef* outMenu ); + + OSStatus SetParameter( + EventParamName inName, + DragRef inDrag ); + OSStatus GetParameter( + EventParamName inName, + DragRef* outDrag ); + + OSStatus SetParameter( + EventParamName inName, + UInt32 inValue ); + OSStatus GetParameter( + EventParamName inName, + UInt32* outValue ); + + OSStatus SetParameter( + EventParamName inName, + const HICommand& inValue ); + OSStatus GetParameter( + EventParamName inName, + HICommand* outValue ); + + OSStatus SetParameter( + EventParamName inName, + const ControlPartCode& inValue ); + OSStatus GetParameter( + EventParamName inName, + ControlPartCode* outValue ); + + // Template parameters + template OSStatus SetParameter( + EventParamName inName, + EventParamType inType, + const T& inValue ) + { + return SetParameter( inName, inType, sizeof( T ), &inValue ); + } + + template OSStatus GetParameter( + EventParamName inName, + EventParamType inType, + T* outValue ) + { + return GetParameter( inName, inType, sizeof( T ), outValue ); + } + +private: + EventRef fEvent; +}; + +#endif // TCarbonEvent_H_ diff --git a/scintilla/macosx/TRect.h b/scintilla/macosx/TRect.h new file mode 100644 index 00000000..b8a9f4b5 --- /dev/null +++ b/scintilla/macosx/TRect.h @@ -0,0 +1,496 @@ +/* + File: TRect.h + + Version: 1.0 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc. + ("Apple") in consideration of your agreement to the following terms, and your + use, installation, modification or redistribution of this Apple software + constitutes acceptance of these terms. If you do not agree with these terms, + please do not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and subject + to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs + copyrights in this original Apple software (the "Apple Software"), to use, + reproduce, modify and redistribute the Apple Software, with or without + modifications, in source and/or binary forms; provided that if you redistribute + the Apple Software in its entirety and without modifications, you must retain + this notice and the following text and disclaimers in all such redistributions of + the Apple Software. Neither the name, trademarks, service marks or logos of + Apple Computer, Inc. may be used to endorse or promote products derived from the + Apple Software without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or implied, + are granted by Apple herein, including but not limited to any patent rights that + may be infringed by your derivative works or by other works in which the Apple + Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO + WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED + WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION + OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT + (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + Copyright © 2002 Apple Computer, Inc., All Rights Reserved +*/ + +#ifndef TRect_H_ +#define TRect_H_ + +#include + +class TRect + : public HIRect +{ +public: + // Construction/Destruction + TRect(); + TRect( + const HIRect* inRect ); + TRect( + const HIRect& inRect ); + TRect( + const HIPoint& inOrigin, + const HISize& inSize ); + TRect( + float inX, + float inY, + float inWidth, + float inHeight ); + TRect( + const Rect& inRect ); + ~TRect(); + + // Operators + operator HIRect*() + { return this; } + operator Rect() const; + + // Accessors + float MinX() const + { return CGRectGetMinX( *this ); } + float MaxX() const + { return CGRectGetMaxX( *this ); } + float MinY() const + { return CGRectGetMinY( *this ); } + float MaxY() const + { return CGRectGetMaxY( *this ); } + + float Width() const + { return CGRectGetWidth( *this ); } + float Height() const + { return CGRectGetHeight( *this ); } + + const HIPoint& Origin() const + { return origin; } + const HISize& Size() const + { return size; } + + float CenterX() const + { return CGRectGetMidX( *this ); } + float CenterY() const + { return CGRectGetMidY( *this ); } + HIPoint Center() const; + + // Modifiers + const HIRect& Inset( + float inX, + float inY ); + const HIRect& Outset( + float inX, + float inY ); + const HIRect& MoveBy( + float inDx, + float inDy ); + const HIRect& MoveTo( + float inX, + float inY ); + + const HIRect& Set( + const HIRect* inRect ); + const HIRect& Set( + const HIRect& inRect ); + const HIRect& Set( + float inX, + float inY, + float inWidth, + float inHeight ); + const HIRect& Set( + const Rect* inRect ); + + const HIRect& SetAroundCenter( + float inCenterX, + float inCenterY, + float inWidth, + float inHeight ); + + const HIRect& SetWidth( + float inWidth ); + const HIRect& SetHeight( + float inHeight ); + + const HIRect& SetOrigin( + const HIPoint& inOrigin ); + const HIRect& SetOrigin( + float inX, + float inY ); + const HIRect& SetSize( + const HISize& inSize ); + const HIRect& SetSize( + float inWidth, + float inHeight ); + + // Tests + bool Contains( + const HIPoint& inPoint ); + bool Contains( + const HIRect& inRect ); + bool Contains( + const Point& inPoint ); + bool Contains( + const Rect& inRect ); +}; + +//----------------------------------------------------------------------------------- +// TRect constructor +//----------------------------------------------------------------------------------- +// +inline TRect::TRect() +{ +} + +//----------------------------------------------------------------------------------- +// TRect constructor +//----------------------------------------------------------------------------------- +// +inline TRect::TRect( + const HIRect* inRect ) +{ + *this = *inRect; +} + +//----------------------------------------------------------------------------------- +// TRect constructor +//----------------------------------------------------------------------------------- +// +inline TRect::TRect( + const HIRect& inRect ) +{ + origin = inRect.origin; + size = inRect.size; +} + +//----------------------------------------------------------------------------------- +// TRect constructor +//----------------------------------------------------------------------------------- +// +inline TRect::TRect( + const HIPoint& inOrigin, + const HISize& inSize ) +{ + origin = inOrigin; + size = inSize; +} + +//----------------------------------------------------------------------------------- +// TRect constructor +//----------------------------------------------------------------------------------- +// +inline TRect::TRect( + float inX, + float inY, + float inWidth, + float inHeight ) +{ + *this = CGRectMake( inX, inY, inWidth, inHeight ); +} + +//----------------------------------------------------------------------------------- +// TRect destructor +//----------------------------------------------------------------------------------- +// +inline TRect::~TRect() +{ +} + +//----------------------------------------------------------------------------------- +// TRect constructor +//----------------------------------------------------------------------------------- +// +inline TRect::TRect( + const Rect& inRect ) +{ + Set( &inRect ); +} + +//----------------------------------------------------------------------------------- +// Rect operator +//----------------------------------------------------------------------------------- +// Converts the HIRect to a QD rect and returns it +// +inline TRect::operator Rect() const +{ + Rect qdRect; + + qdRect.top = (SInt16) MinY(); + qdRect.left = (SInt16) MinX(); + qdRect.bottom = (SInt16) MaxY(); + qdRect.right = (SInt16) MaxX(); + + return qdRect; +} + +//----------------------------------------------------------------------------------- +// Center +//----------------------------------------------------------------------------------- +// +inline HIPoint TRect::Center() const +{ + return CGPointMake( CGRectGetMidX( *this ), CGRectGetMidY( *this ) ); +} + +//----------------------------------------------------------------------------------- +// Inset +//----------------------------------------------------------------------------------- +// +inline const HIRect& TRect::Inset( + float inX, + float inY ) +{ + *this = CGRectInset( *this, inX, inY ); + + return *this; +} + +//----------------------------------------------------------------------------------- +// Outset +//----------------------------------------------------------------------------------- +// +inline const HIRect& TRect::Outset( + float inX, + float inY ) +{ + *this = CGRectInset( *this, -inX, -inY ); + + return *this; +} + +//----------------------------------------------------------------------------------- +// MoveBy +//----------------------------------------------------------------------------------- +// +inline const HIRect& TRect::MoveBy( + float inDx, + float inDy ) +{ + origin = CGPointMake( MinX() + inDx, MinY() + inDy ); + + return *this; +} + +//----------------------------------------------------------------------------------- +// MoveTo +//----------------------------------------------------------------------------------- +// +inline const HIRect& TRect::MoveTo( + float inX, + float inY ) +{ + origin = CGPointMake( inX, inY ); + + return *this; +} + +//----------------------------------------------------------------------------------- +// Set +//----------------------------------------------------------------------------------- +// +inline const HIRect& TRect::Set( + const HIRect* inRect ) +{ + *this = *inRect; + + return *this; +} + +//----------------------------------------------------------------------------------- +// Set +//----------------------------------------------------------------------------------- +// +inline const HIRect& TRect::Set( + const HIRect& inRect ) +{ + *this = inRect; + + return *this; +} + +//----------------------------------------------------------------------------------- +// Set +//----------------------------------------------------------------------------------- +// +inline const HIRect& TRect::Set( + float inX, + float inY, + float inWidth, + float inHeight ) +{ + *this = CGRectMake( inX, inY, inWidth, inHeight ); + + return *this; +} + +//----------------------------------------------------------------------------------- +// Set +//----------------------------------------------------------------------------------- +// +inline const HIRect& TRect::Set( + const Rect* inRect ) +{ + origin.x = inRect->left; + origin.y = inRect->top; + size.width = inRect->right - inRect->left; + size.height = inRect->bottom - inRect->top; + + return *this; +} + +//----------------------------------------------------------------------------------- +// SetAroundCenter +//----------------------------------------------------------------------------------- +// Sets the rectangle by specifying dimensions around a center point +// +inline const HIRect& TRect::SetAroundCenter( + float inCenterX, + float inCenterY, + float inWidth, + float inHeight ) +{ + *this = CGRectMake( inCenterX - inWidth/2, inCenterY - inHeight/2, inWidth, inHeight ); + + return *this; +} + +//----------------------------------------------------------------------------------- +// SetWidth +//----------------------------------------------------------------------------------- +// +inline const HIRect& TRect::SetWidth( + float inWidth ) +{ + size.width = inWidth; + + return *this; +} + +//----------------------------------------------------------------------------------- +// SetHeight +//----------------------------------------------------------------------------------- +// +inline const HIRect& TRect::SetHeight( + float inHeight ) +{ + size.height = inHeight; + + return *this; +} + +//----------------------------------------------------------------------------------- +// SetOrigin +//----------------------------------------------------------------------------------- +// +inline const HIRect& TRect::SetOrigin( + const HIPoint& inOrigin ) +{ + origin = inOrigin; + + return *this; +} + +//----------------------------------------------------------------------------------- +// SetOrigin +//----------------------------------------------------------------------------------- +// +inline const HIRect& TRect::SetOrigin( + float inX, + float inY ) +{ + origin = CGPointMake( inX, inY ); + + return *this; +} + +//----------------------------------------------------------------------------------- +// SetSize +//----------------------------------------------------------------------------------- +// +inline const HIRect& TRect::SetSize( + const HISize& inSize ) +{ + size = inSize; + + return *this; +} + +//----------------------------------------------------------------------------------- +// SetSize +//----------------------------------------------------------------------------------- +// +inline const HIRect& TRect::SetSize( + float inWidth, + float inHeight ) +{ + size = CGSizeMake( inWidth, inHeight ); + + return *this; +} + +//----------------------------------------------------------------------------------- +// Contains +//----------------------------------------------------------------------------------- +// +inline bool TRect::Contains( + const HIPoint& inPoint ) +{ + return CGRectContainsPoint( *this, inPoint ); +} + +//----------------------------------------------------------------------------------- +// Contains +//----------------------------------------------------------------------------------- +// +inline bool TRect::Contains( + const HIRect& inRect ) +{ + return CGRectContainsRect( *this, inRect ); +} + +//----------------------------------------------------------------------------------- +// Contains +//----------------------------------------------------------------------------------- +// +inline bool TRect::Contains( + const Point& inPoint ) +{ + return Contains( CGPointMake( inPoint.h, inPoint.v ) ); +} + +//----------------------------------------------------------------------------------- +// Contains +//----------------------------------------------------------------------------------- +// +inline bool TRect::Contains( + const Rect& inRect ) +{ + return Contains( CGRectMake( inRect.left, inRect.top, + inRect.right - inRect.left, inRect.bottom - inRect.top ) ); +} + +#endif // TRect_H_ diff --git a/scintilla/macosx/TView.cxx b/scintilla/macosx/TView.cxx new file mode 100644 index 00000000..aa0c634e --- /dev/null +++ b/scintilla/macosx/TView.cxx @@ -0,0 +1,1442 @@ +/* + File: TView.cp + + Version: 1.0 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc. + ("Apple") in consideration of your agreement to the following terms, and your + use, installation, modification or redistribution of this Apple software + constitutes acceptance of these terms. If you do not agree with these terms, + please do not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and subject + to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs + copyrights in this original Apple software (the "Apple Software"), to use, + reproduce, modify and redistribute the Apple Software, with or without + modifications, in source and/or binary forms; provided that if you redistribute + the Apple Software in its entirety and without modifications, you must retain + this notice and the following text and disclaimers in all such redistributions of + the Apple Software. Neither the name, trademarks, service marks or logos of + Apple Computer, Inc. may be used to endorse or promote products derived from the + Apple Software without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or implied, + are granted by Apple herein, including but not limited to any patent rights that + may be infringed by your derivative works or by other works in which the Apple + Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO + WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED + WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION + OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT + (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + Copyright © 2002 Apple Computer, Inc., All Rights Reserved +*/ + +/* + NOTE: This is NOWHERE near a completely exhaustive implementation of a view. There are + many more carbon events one could intercept and hook into this. +*/ + +#include "TView.h" + +//----------------------------------------------------------------------------------- +// constants +//----------------------------------------------------------------------------------- +// +const EventTypeSpec kHIObjectEvents[] = +{ { kEventClassHIObject, kEventHIObjectConstruct }, + { kEventClassHIObject, kEventHIObjectInitialize }, + { kEventClassHIObject, kEventHIObjectDestruct } +}; + +const EventTypeSpec kHIViewEvents[] = +{ { kEventClassCommand, kEventCommandProcess }, + { kEventClassCommand, kEventCommandUpdateStatus }, + + { kEventClassControl, kEventControlInitialize }, + { kEventClassControl, kEventControlDraw }, + { kEventClassControl, kEventControlHitTest }, + { kEventClassControl, kEventControlGetPartRegion }, + { kEventClassControl, kEventControlGetData }, + { kEventClassControl, kEventControlSetData }, + { kEventClassControl, kEventControlGetOptimalBounds }, + { kEventClassControl, kEventControlBoundsChanged }, + { kEventClassControl, kEventControlTrack }, + { kEventClassControl, kEventControlGetSizeConstraints }, + { kEventClassControl, kEventControlHit }, + + { kEventClassControl, kEventControlHiliteChanged }, + { kEventClassControl, kEventControlActivate }, + { kEventClassControl, kEventControlDeactivate }, + { kEventClassControl, kEventControlValueFieldChanged }, + { kEventClassControl, kEventControlTitleChanged }, + { kEventClassControl, kEventControlEnabledStateChanged }, +}; + +// This param name was accidentally left unexported for +// the release of Jaguar. +const EventParamName kEventParamControlLikesDrag = 'cldg'; + +//----------------------------------------------------------------------------------- +// TView constructor +//----------------------------------------------------------------------------------- +// +TView::TView( + HIViewRef inControl ) + : fViewRef( inControl ) +{ + verify_noerr( InstallEventHandler( GetControlEventTarget( fViewRef ), ViewEventHandler, + GetEventTypeCount( kHIViewEvents ), kHIViewEvents, this, &fHandler ) ); + + mouseEventHandler = NULL; + fAutoInvalidateFlags = 0; + debugPrint = false; +} + +//----------------------------------------------------------------------------------- +// TView destructor +//----------------------------------------------------------------------------------- +// +TView::~TView() +{ + // If we have installed our custom mouse events handler on the window, + // go forth and remove it. Note: -1 is used to indicate that no handler has + // been installed yet, but we want to once we get a window. + if ( mouseEventHandler != NULL && mouseEventHandler != reinterpret_cast( -1 ) ) + RemoveEventHandler( mouseEventHandler ); + mouseEventHandler = NULL; +} + +//----------------------------------------------------------------------------------- +// Initialize +//----------------------------------------------------------------------------------- +// Called during HIObject construction, this is your subclasses' chance to extract +// any parameters it might have added to the initialization event passed into the +// HIObjectCreate call. +// +OSStatus TView::Initialize( TCarbonEvent& /*inEvent*/ ) +{ + return noErr; +} + +//----------------------------------------------------------------------------------- +// GetBehaviors +//----------------------------------------------------------------------------------- +// Returns our behaviors. Any subclass that overrides this should OR in its behaviors +// into the inherited behaviors. +// +UInt32 TView::GetBehaviors() +{ + return kControlSupportsDataAccess | kControlSupportsGetRegion; +} + +//----------------------------------------------------------------------------------- +// Draw +//----------------------------------------------------------------------------------- +// Draw your view. You should draw based on VIEW coordinates, not frame coordinates. +// +void TView::Draw( + RgnHandle /*inLimitRgn*/, + CGContextRef /*inContext*/ ) +{ +} + +//----------------------------------------------------------------------------------- +// HitTest +//----------------------------------------------------------------------------------- +// Asks your view to return what part of itself (if any) is hit by the point given +// to it. The point is in VIEW coordinates, so you should get the view rect to do +// bounds checking. +// +ControlPartCode TView::HitTest( + const HIPoint& /*inWhere*/ ) +{ + return kControlNoPart; +} + +//----------------------------------------------------------------------------------- +// GetRegion +//----------------------------------------------------------------------------------- +// This is called when someone wants to know certain metrics regarding this view. +// The base class does nothing. Subclasses should handle their own parts, such as +// the content region by overriding this method. The structure region is, by default, +// the view's bounds. If a subclass does not have a region for a given part, it +// should always call the inherited method. +// +OSStatus TView::GetRegion( + ControlPartCode inPart, + RgnHandle outRgn ) +{ +#pragma unused( inPart, outRgn ) + + return eventNotHandledErr; +} + +//----------------------------------------------------------------------------------- +// PrintDebugInfo +//----------------------------------------------------------------------------------- +// This is called when asked to print debugging information. +// +void TView::PrintDebugInfo() +{ +} + +//----------------------------------------------------------------------------------- +// GetData +//----------------------------------------------------------------------------------- +// Gets some data from our view. Subclasses should override to handle their own +// defined data tags. If a tag is not understood by the subclass, it should call the +// inherited method. As a convienience, we map the request for ControlKind into our +// GetKind method. +// +OSStatus TView::GetData( + OSType inTag, + ControlPartCode inPart, + Size inSize, + Size* outSize, + void* inPtr ) +{ +#pragma unused( inPart ) + + OSStatus err = noErr; + + switch( inTag ) + { + case kControlKindTag: + if ( inPtr ) + { + if ( inSize != sizeof( ControlKind ) ) + err = errDataSizeMismatch; + else + ( *(ControlKind *) inPtr ) = GetKind(); + } + *outSize = sizeof( ControlKind ); + break; + + default: + err = eventNotHandledErr; + break; + } + + return err; +} + +//----------------------------------------------------------------------------------- +// SetData +//----------------------------------------------------------------------------------- +// Sets some data on our control. Subclasses should override to handle their own +// defined data tags. If a tag is not understood by the subclass, it should call the +// inherited method. +// +OSStatus TView::SetData( + OSType inTag, + ControlPartCode inPart, + Size inSize, + const void* inPtr ) +{ +#pragma unused( inTag, inPart, inSize, inPtr ) + + return eventNotHandledErr; +} + +//----------------------------------------------------------------------------------- +// GetOptimalSize +//----------------------------------------------------------------------------------- +// Someone wants to know this view's optimal size and text baseline, probably to help +// do some type of layout. The base class does nothing, but subclasses should +// override and do something meaningful here. +// +OSStatus TView::GetOptimalSize( + HISize* outSize, + float* outBaseLine ) +{ +#pragma unused( outSize, outBaseLine ) + + return eventNotHandledErr; +} + +//----------------------------------------------------------------------------------- +// GetSizeConstraints +//----------------------------------------------------------------------------------- +// Someone wants to know this view's minimum and maximum sizes, probably to help +// do some type of layout. The base class does nothing, but subclasses should +// override and do something meaningful here. +// +OSStatus TView::GetSizeConstraints( + HISize* outMin, + HISize* outMax ) +{ +#pragma unused( outMin, outMax ) + + return eventNotHandledErr; +} + +//----------------------------------------------------------------------------------- +// BoundsChanged +//----------------------------------------------------------------------------------- +// The bounds of our view have changed. Subclasses can override here to make note +// of it and flush caches, etc. The base class does nothing. +// +OSStatus TView::BoundsChanged( + UInt32 inOptions, + const HIRect& inOriginalBounds, + const HIRect& inCurrentBounds, + RgnHandle inInvalRgn ) +{ +#pragma unused( inOptions, inOriginalBounds, inCurrentBounds, inInvalRgn ) + + return eventNotHandledErr; +} + +//----------------------------------------------------------------------------------- +// ControlHit +//----------------------------------------------------------------------------------- +// The was hit. Subclasses can overide to care about what part was hit. +// +OSStatus TView::ControlHit( + ControlPartCode inPart, + UInt32 inModifiers ) +{ +#pragma unused( inPart, inModifiers ) + + return eventNotHandledErr; +} + +//----------------------------------------------------------------------------------- +// HiliteChanged +//----------------------------------------------------------------------------------- +// The hilite of our view has changed. Subclasses can override here to make note +// of it and flush caches, etc. The base class does nothing. +// +OSStatus TView::HiliteChanged( + ControlPartCode inOriginalPart, + ControlPartCode inCurrentPart, + RgnHandle inInvalRgn ) +{ +#pragma unused( inOriginalPart, inCurrentPart, inInvalRgn ) + + return eventNotHandledErr; +} + +//----------------------------------------------------------------------------------- +// DragEnter +//----------------------------------------------------------------------------------- +// A drag has entered our bounds. The Drag and Drop interface also should have been +// activated or else this method will NOT be called. If true is returned, this view +// likes the drag and will receive drag within/leave/receive messages as appropriate. +// If false is returned, it is assumed the drag is not valid for this view, and no +// further drag activity will flow into this view unless the drag leaves and is +// re-entered. +// +bool TView::DragEnter( + DragRef inDrag ) +{ +#pragma unused( inDrag ) + + return false; +} + +//----------------------------------------------------------------------------------- +// DragWithin +//----------------------------------------------------------------------------------- +// A drag has moved within our bounds. In order for this method to be called, the +// view must have signaled the drag as being desirable in the DragEnter method. The +// Drag and Drop interface also should have been activated. +// +bool TView::DragWithin( + DragRef inDrag ) +{ +#pragma unused( inDrag ) + + return false; +} + +//----------------------------------------------------------------------------------- +// DragLeave +//----------------------------------------------------------------------------------- +// A drag has left. Deal with it. Subclasses should override as necessary. The +// Drag and Drop interface should be activated in order for this method to be valid. +// The drag must have also been accepted in the DragEnter method, else this method +// will NOT be called. +// +bool TView::DragLeave( + DragRef inDrag ) +{ +#pragma unused( inDrag ) + + return false; +} + +//----------------------------------------------------------------------------------- +// DragReceive +//----------------------------------------------------------------------------------- +// Deal with receiving a drag. By default we return dragNotAcceptedErr. I'm not sure +// if this is correct, or eventNotHandledErr. Time will tell... +// +OSStatus TView::DragReceive( + DragRef inDrag ) +{ +#pragma unused( inDrag ) + + return dragNotAcceptedErr; +} + +//----------------------------------------------------------------------------------- +// Track +//----------------------------------------------------------------------------------- +// Default tracking method. Subclasses should override as necessary. We do nothing +// here in the base class, so we return eventNotHandledErr. +// +OSStatus TView::Track( + TCarbonEvent& inEvent, + ControlPartCode* outPart ) +{ +#pragma unused( inEvent, outPart ) + + return eventNotHandledErr; +} + +//----------------------------------------------------------------------------------- +// SetFocusPart +//----------------------------------------------------------------------------------- +// Handle focusing. Our base behavior is to punt. +// +OSStatus TView::SetFocusPart( + ControlPartCode inDesiredFocus, + RgnHandle inInvalidRgn, + Boolean inFocusEverything, + ControlPartCode* outActualFocus ) +{ +#pragma unused( inDesiredFocus, inInvalidRgn, inFocusEverything, outActualFocus ) + + return eventNotHandledErr; +} + +//----------------------------------------------------------------------------------- +// ProcessCommand +//----------------------------------------------------------------------------------- +// Process a command. Subclasses should override as necessary. +// +OSStatus TView::ProcessCommand( + const HICommand& inCommand ) +{ +#pragma unused( inCommand ) + + return eventNotHandledErr; +} + +//----------------------------------------------------------------------------------- +// UpdateCommandStatus +//----------------------------------------------------------------------------------- +// Update the status for a command. Subclasses should override as necessary. +// +OSStatus +TView::UpdateCommandStatus( + const HICommand& inCommand ) +{ +#pragma unused( inCommand ) + + return eventNotHandledErr; +} + +OSStatus TView::MouseDown(HIPoint& /*inMouseLocation*/, UInt32 /*inKeyModifiers*/, EventMouseButton /*inMouseButton*/, UInt32 /*inClickCount*/ , + TCarbonEvent& /*inEvent*/) +{ + return eventNotHandledErr; +} + +OSStatus TView::MouseUp(HIPoint& /*inMouseLocation*/, UInt32 /*inKeyModifiers*/, EventMouseButton /*inMouseButton*/, UInt32 /*inClickCount*/ ) +{ + return eventNotHandledErr; +} + +OSStatus TView::MouseDragged(HIPoint& /*inMouseLocation*/, UInt32 /*inKeyModifiers*/, EventMouseButton /*inMouseButton*/, UInt32 /*inClickCount*/ ) +{ + return eventNotHandledErr; +} + +OSStatus TView::MouseEntered(HIPoint& /*inMouseLocation*/, UInt32 /*inKeyModifiers*/, EventMouseButton /*inMouseButton*/, UInt32 /*inClickCount*/ ) +{ + return eventNotHandledErr; +} + +OSStatus TView::MouseExited(HIPoint& /*inMouseLocation*/, UInt32 /*inKeyModifiers*/, EventMouseButton /*inMouseButton*/, UInt32 /*inClickCount*/ ) +{ + return eventNotHandledErr; +} + +OSStatus TView::MouseWheelMoved( EventMouseWheelAxis /*inAxis*/, SInt32 /*inDelta*/, UInt32 /*inKeyModifiers*/ ) +{ + return eventNotHandledErr; +} + +OSStatus TView::ContextualMenuClick( HIPoint& /*inMouseLocation*/ ) +{ + return eventNotHandledErr; +} + + +//----------------------------------------------------------------------------------- +// ActivateInterface +//----------------------------------------------------------------------------------- +// This routine is used to allow a subclass to turn on a specific event or suite of +// events, like Drag and Drop. This allows us to keep event traffic down if we are +// not interested, but register for the events if we are. +// +OSStatus TView::ActivateInterface( + TView::Interface inInterface ) +{ + OSStatus result = noErr; + + switch( inInterface ) + { + case kDragAndDrop: + { + static const EventTypeSpec kDragEvents[] = + { + { kEventClassControl, kEventControlDragEnter }, + { kEventClassControl, kEventControlDragLeave }, + { kEventClassControl, kEventControlDragWithin }, + { kEventClassControl, kEventControlDragReceive } + }; + + result = AddEventTypesToHandler( fHandler, GetEventTypeCount( kDragEvents ), + kDragEvents ); + + SetControlDragTrackingEnabled( GetViewRef(), true); + } + break; + + case kKeyboardFocus: + { + static const EventTypeSpec kKeyboardFocusEvents[] = + { + { kEventClassControl, kEventControlSetFocusPart }, + { kEventClassTextInput, kEventTextInputUnicodeForKeyEvent }, + }; + + result = AddEventTypesToHandler( fHandler, GetEventTypeCount( kKeyboardFocusEvents ), + kKeyboardFocusEvents ); + } + break; + + case kMouse: + { + if ( mouseEventHandler == NULL ) + { + // This case is quite different: Mouse events are delivered to the window, not the controls. + // mouse wheel events are the exception: They ARE delivered to the control + static const EventTypeSpec kControlMouseEvents[] = + { + { kEventClassMouse, kEventMouseWheelMoved }, + { kEventClassControl, kEventControlContextualMenuClick }, + // So we can reinstall our events when the window changes + { kEventClassControl, kEventControlOwningWindowChanged }, + }; + + result = AddEventTypesToHandler( fHandler, GetEventTypeCount( kControlMouseEvents ), + kControlMouseEvents ); + } + + if ( this->GetOwner() != NULL ) + { + // We use "-1" to indicate that we want to install an event handler once we get a window + if ( mouseEventHandler != NULL && mouseEventHandler != reinterpret_cast( -1 ) ) + { + result = RemoveEventHandler( mouseEventHandler ); + } + mouseEventHandler = NULL; + + static const EventTypeSpec kWindowMouseEvents[] = + { + { kEventClassMouse, kEventMouseDown }, + { kEventClassMouse, kEventMouseUp }, + { kEventClassMouse, kEventMouseMoved }, + { kEventClassMouse, kEventMouseDragged }, + }; + + result = InstallEventHandler( GetWindowEventTarget( this->GetOwner() ), WindowEventHandler, + GetEventTypeCount( kWindowMouseEvents ), kWindowMouseEvents, + this, &mouseEventHandler ); + } + // If we have no window yet. Set the mouseEventHandler to -1 so when we get one we + // will install the event handler + else + { + mouseEventHandler = reinterpret_cast( -1 ); + } + } + break; + case kMouseTracking: + { + { + static const EventTypeSpec kControlMouseEvents[] = + { + { kEventClassMouse, kEventMouseEntered }, // only works if mousetracking is started + { kEventClassMouse, kEventMouseExited }, // only works if mousetracking is started + }; + + result = AddEventTypesToHandler( fHandler, GetEventTypeCount( kControlMouseEvents ), + kControlMouseEvents ); + } + } + + //default: + // assert( false ); + } + + return result; +} + +OSStatus TView::InstallTimer( EventTimerInterval inFireDelay, EventLoopTimerRef* outTimer ) +{ + return InstallEventLoopTimer( GetCurrentEventLoop(), inFireDelay, inFireDelay, TimerEventHandler, this, outTimer ); +} + +//----------------------------------------------------------------------------------- +// RegisterSubclass +//----------------------------------------------------------------------------------- +// This routine should be called by subclasses so they can be created as HIObjects. +// +OSStatus TView::RegisterSubclass( + CFStringRef inID, + ConstructProc inProc ) +{ + return HIObjectRegisterSubclass( inID, kHIViewClassID, 0, ObjectEventHandler, + GetEventTypeCount( kHIObjectEvents ), kHIObjectEvents, (void*) inProc, NULL ); +} + +//----------------------------------------------------------------------------------- +// ObjectEventHandler +//----------------------------------------------------------------------------------- +// Our static event handler proc. We handle any HIObject based events directly in +// here at present. +// +pascal OSStatus TView::ObjectEventHandler( + EventHandlerCallRef inCallRef, + EventRef inEvent, + void* inUserData ) +{ + OSStatus result = eventNotHandledErr; + TView* view = (TView*) inUserData; + TCarbonEvent event( inEvent ); + + switch ( event.GetClass() ) + { + case kEventClassHIObject: + switch ( event.GetKind() ) + { + case kEventHIObjectConstruct: + { + ControlRef control; // ControlRefs are HIObjectRefs + TView* view; + + result = event.GetParameter( kEventParamHIObjectInstance, + typeHIObjectRef, (HIObjectRef*)&control ); + require_noerr( result, ParameterMissing ); + + // on entry for our construct event, we're passed the + // creation proc we registered with for this class. + // we use it now to create the instance, and then we + // replace the instance parameter data with said instance + // as type void. + + result = (*(ConstructProc)inUserData)( control, &view ); + if ( result == noErr ) + event.SetParameter( kEventParamHIObjectInstance, + typeVoidPtr, view ); + } + break; + + case kEventHIObjectInitialize: + result = CallNextEventHandler( inCallRef, inEvent ); + if ( result == noErr ) + result = view->Initialize( event ); + break; + + case kEventHIObjectDestruct: + delete view; + break; + } + break; + } + +ParameterMissing: + + return result; +} + +//----------------------------------------------------------------------------------- +// ViewEventHandler +//----------------------------------------------------------------------------------- +// Our static event handler proc. We handle all non-HIObject events here. +// +pascal OSStatus TView::ViewEventHandler( + EventHandlerCallRef inCallRef, + EventRef inEvent, + void* inUserData ) +{ + OSStatus result; + TView* view = (TView*) inUserData; + TCarbonEvent event( inEvent ); + //if (view->debugPrint) + // fprintf(stderr,"TView::ViewEventHandler\n"); + result = view->HandleEvent( inCallRef, event ); + + return result; +} + + +pascal OSStatus TView::WindowEventHandler( + EventHandlerCallRef inCallRef, + EventRef inEvent, + void* inUserData ) +{ + TView* view = reinterpret_cast( inUserData ); + TCarbonEvent event( inEvent ); + + const WindowRef window = view->GetOwner(); + if (NULL == window) + return eventNotHandledErr; + + // If the window is not active, let the standard window handler execute. + if ( ! IsWindowActive( window ) ) return eventNotHandledErr; + if (view->debugPrint) + fprintf(stderr,"TView::WindowEventHandler\n"); + + const HIViewRef rootView = HIViewGetRoot( window ); + if (NULL == rootView) + return eventNotHandledErr; + + // TODO: On OS X 10.3, test if this bug still exists + // This is a hack to work around a bug in the OS. See: + // http://lists.apple.com/archives/carbon-development/2002/Sep/29/keventmousemovedeventsno.004.txt + OSStatus err; + if ( event.GetKind() == kEventMouseMoved ) + { + // We need to set some parameters correctly + event.SetParameter( kEventParamWindowRef, window ); + + HIPoint ptMouse; + event.GetParameter( kEventParamMouseLocation, &ptMouse ); + + // convert screen coords to window relative + Rect bounds; + err = GetWindowBounds( window, kWindowStructureRgn, &bounds ); + if( err == noErr ) + { + ptMouse.x -= bounds.left; + ptMouse.y -= bounds.top; + event.SetParameter( kEventParamWindowMouseLocation, ptMouse ); + } + } + + HIViewRef targetView = NULL; + err = HIViewGetViewForMouseEvent( rootView, inEvent, &targetView ); + //if (view->debugPrint) + // fprintf(stderr,"TView::WindowEventHandler root[%08X] viewRef[%08X] targetView[%08X]\n", rootView, view->GetViewRef(), targetView); + if ( targetView == view->GetViewRef() || event.GetKind() == kEventMouseDragged ) + { + return view->HandleEvent( inCallRef, event ); + } + + return eventNotHandledErr; +} + +pascal void TView::TimerEventHandler( EventLoopTimerRef inTimer, void* view ) +{ + reinterpret_cast( view )->TimerFired( inTimer ); +} + +//----------------------------------------------------------------------------------- +// HandleEvent +//----------------------------------------------------------------------------------- +// Our object's virtual event handler method. I'm not sure if we need this these days. +// We used to do various things with it, but those days are long gone... +// +OSStatus TView::HandleEvent( + EventHandlerCallRef inCallRef, + TCarbonEvent& inEvent ) +{ +#pragma unused( inCallRef ) + + OSStatus result = eventNotHandledErr; + HIPoint where; + OSType tag; + void * ptr; + Size size, outSize; + UInt32 features; + RgnHandle region = NULL; + ControlPartCode part; + RgnHandle invalRgn; + + switch ( inEvent.GetClass() ) + { + case kEventClassCommand: + { + HICommand command; + + result = inEvent.GetParameter( kEventParamDirectObject, &command ); + require_noerr( result, MissingParameter ); + + switch ( inEvent.GetKind() ) + { + case kEventCommandProcess: + result = ProcessCommand( command ); + break; + + case kEventCommandUpdateStatus: + result = UpdateCommandStatus( command ); + break; + } + } + break; + + case kEventClassControl: + switch ( inEvent.GetKind() ) + { + case kEventControlInitialize: + features = GetBehaviors(); + inEvent.SetParameter( kEventParamControlFeatures, features ); + result = noErr; + break; + + case kEventControlDraw: + { + CGContextRef context = NULL; + + inEvent.GetParameter( kEventParamRgnHandle, ®ion ); + inEvent.GetParameter( kEventParamCGContextRef, typeCGContextRef, &context ); + + Draw( region, context ); + result = noErr; + } + break; + + case kEventControlHitTest: + inEvent.GetParameter( kEventParamMouseLocation, typeHIPoint, &where ); + part = HitTest( where ); + inEvent.SetParameter( kEventParamControlPart, typeControlPartCode, part ); + result = noErr; + break; + + case kEventControlGetPartRegion: + inEvent.GetParameter( kEventParamControlPart, typeControlPartCode, &part ); + inEvent.GetParameter( kEventParamControlRegion, ®ion ); + result = GetRegion( part, region ); + break; + + case kEventControlGetData: + inEvent.GetParameter( kEventParamControlPart, typeControlPartCode, &part ); + inEvent.GetParameter( kEventParamControlDataTag, typeEnumeration, &tag ); + inEvent.GetParameter( kEventParamControlDataBuffer, typePtr, (Ptr*)&ptr ); + inEvent.GetParameter( kEventParamControlDataBufferSize, typeLongInteger, &size ); + + result = GetData( tag, part, size, &outSize, ptr ); + + if ( result == noErr ) + verify_noerr( inEvent.SetParameter( kEventParamControlDataBufferSize, typeLongInteger, outSize ) ); + break; + + case kEventControlSetData: + inEvent.GetParameter( kEventParamControlPart, typeControlPartCode, &part ); + inEvent.GetParameter( kEventParamControlDataTag, typeEnumeration, &tag ); + inEvent.GetParameter( kEventParamControlDataBuffer, typePtr, (Ptr*)&ptr ); + inEvent.GetParameter( kEventParamControlDataBufferSize, typeLongInteger, &size ); + + result = SetData( tag, part, size, ptr ); + break; + + case kEventControlGetOptimalBounds: + { + HISize size; + float floatBaseLine; + + result = GetOptimalSize( &size, &floatBaseLine ); + if ( result == noErr ) + { + Rect bounds; + SInt16 baseLine; + + GetControlBounds( GetViewRef(), &bounds ); + + bounds.bottom = bounds.top + (SInt16)size.height; + bounds.right = bounds.left + (SInt16)size.width; + baseLine = (SInt16)floatBaseLine; + + inEvent.SetParameter( kEventParamControlOptimalBounds, bounds ); + inEvent.SetParameter( kEventParamControlOptimalBaselineOffset, typeShortInteger, baseLine ); + } + } + break; + + case kEventControlBoundsChanged: + { + HIRect prevRect, currRect; + UInt32 attrs; + + inEvent.GetParameter( kEventParamAttributes, &attrs ); + inEvent.GetParameter( kEventParamOriginalBounds, &prevRect ); + inEvent.GetParameter( kEventParamCurrentBounds, &currRect ); + inEvent.GetParameter( kEventParamControlInvalRgn, &invalRgn ); + + result = BoundsChanged( attrs, prevRect, currRect, invalRgn ); + + if ( mouseEventHandler != NULL ) + { + ActivateInterface( kMouse ); + } + + } + break; + + case kEventControlHit: + { + UInt32 modifiers; + + inEvent.GetParameter( kEventParamControlPart, typeControlPartCode, &part ); + inEvent.GetParameter( kEventParamKeyModifiers, &modifiers ); + + result = ControlHit( part, modifiers ); + } + break; + + case kEventControlHiliteChanged: + { + ControlPartCode prevPart, currPart; + + inEvent.GetParameter( kEventParamControlPreviousPart, typeControlPartCode, &prevPart ); + inEvent.GetParameter( kEventParamControlCurrentPart, typeControlPartCode, &currPart ); + inEvent.GetParameter( kEventParamControlInvalRgn, &invalRgn ); + + result = HiliteChanged( prevPart, currPart, invalRgn ); + + if ( GetAutoInvalidateFlags() & kAutoInvalidateOnHilite ) + Invalidate(); + } + break; + + case kEventControlActivate: + result = ActiveStateChanged(); + + if ( GetAutoInvalidateFlags() & kAutoInvalidateOnActivate ) + Invalidate(); + break; + + case kEventControlDeactivate: + result = ActiveStateChanged(); + + if ( GetAutoInvalidateFlags() & kAutoInvalidateOnActivate ) + Invalidate(); + break; + + case kEventControlValueFieldChanged: + result = ValueChanged(); + + if ( GetAutoInvalidateFlags() & kAutoInvalidateOnValueChange ) + Invalidate(); + break; + + case kEventControlTitleChanged: + result = TitleChanged(); + + if ( GetAutoInvalidateFlags() & kAutoInvalidateOnTitleChange ) + Invalidate(); + break; + + case kEventControlEnabledStateChanged: + result = EnabledStateChanged(); + + if ( GetAutoInvalidateFlags() & kAutoInvalidateOnEnable ) + Invalidate(); + break; + + case kEventControlDragEnter: + case kEventControlDragLeave: + case kEventControlDragWithin: + { + DragRef drag; + bool likesDrag; + + inEvent.GetParameter( kEventParamDragRef, &drag ); + + switch ( inEvent.GetKind() ) + { + case kEventControlDragEnter: + likesDrag = DragEnter( drag ); + // Why only if likesDrag? What if it doesn't? No parameter? + if ( likesDrag ) + result = inEvent.SetParameter( kEventParamControlLikesDrag, likesDrag ); + break; + + case kEventControlDragLeave: + DragLeave( drag ); + result = noErr; + break; + + case kEventControlDragWithin: + DragWithin( drag ); + result = noErr; + break; + } + } + break; + + case kEventControlDragReceive: + { + DragRef drag; + + inEvent.GetParameter( kEventParamDragRef, &drag ); + + result = DragReceive( drag ); + } + break; + + case kEventControlTrack: + { + ControlPartCode part; + + result = Track( inEvent, &part ); + if ( result == noErr ) + verify_noerr( inEvent.SetParameter( kEventParamControlPart, typeControlPartCode, part ) ); + } + break; + + case kEventControlGetSizeConstraints: + { + HISize minSize, maxSize; + + result = GetSizeConstraints( &minSize, &maxSize ); + + if ( result == noErr ) + { + verify_noerr( inEvent.SetParameter( kEventParamMinimumSize, minSize ) ); + verify_noerr( inEvent.SetParameter( kEventParamMaximumSize, maxSize ) ); + } + } + break; + + case kEventControlSetFocusPart: + { + ControlPartCode desiredFocus; + RgnHandle invalidRgn; + Boolean focusEverything; + ControlPartCode actualFocus; + + result = inEvent.GetParameter( kEventParamControlPart, typeControlPartCode, &desiredFocus ); + require_noerr( result, MissingParameter ); + + inEvent.GetParameter( kEventParamControlInvalRgn, &invalidRgn ); + + focusEverything = false; // a good default in case the parameter doesn't exist + + inEvent.GetParameter( kEventParamControlFocusEverything, &focusEverything ); + + result = SetFocusPart( desiredFocus, invalidRgn, focusEverything, &actualFocus ); + + if ( result == noErr ) + verify_noerr( inEvent.SetParameter( kEventParamControlPart, typeControlPartCode, actualFocus ) ); + } + break; + + case kEventControlOwningWindowChanged: + { + // If our owning window has changed, reactivate the mouse interface + if ( mouseEventHandler != NULL ) + { + ActivateInterface( kMouse ); + } + } + break; + + case kEventControlContextualMenuClick: + { + HIPoint ptMouse; + inEvent.GetParameter( kEventParamMouseLocation, &ptMouse ); + result = ContextualMenuClick( ptMouse ); + } + break; + + // some other kind of Control event + default: + break; + } + break; + + case kEventClassTextInput: + result = TextInput( inEvent ); + break; + + case kEventClassMouse: + { + result = inEvent.GetParameter( kEventParamWindowMouseLocation, typeHIPoint, &where ); + HIViewConvertPoint( &where, NULL, fViewRef ); + + UInt32 inKeyModifiers; + result = inEvent.GetParameter( kEventParamKeyModifiers, &inKeyModifiers ); + if( result != noErr ) + inKeyModifiers = 0; + EventMouseButton inMouseButton = 0; + result = inEvent.GetParameter( kEventParamMouseButton, typeMouseButton, &inMouseButton ); + if (noErr != result) + // assume no button is pressed if there is no button info + inMouseButton = 0; + UInt32 inClickCount; + result = inEvent.GetParameter( kEventParamClickCount, &inClickCount ); + if( result != noErr ) + inClickCount = 0; + + switch ( inEvent.GetKind() ) + { + case kEventMouseWheelMoved: + { + EventMouseWheelAxis inAxis; + result = inEvent.GetParameter( kEventParamMouseWheelAxis, typeMouseWheelAxis, &inAxis ); + + SInt32 inDelta; + result = inEvent.GetParameter( kEventParamMouseWheelDelta, typeSInt32, &inDelta ); + + result = MouseWheelMoved( inAxis, inDelta, inKeyModifiers ); + break; + } + case kEventMouseDown: + result = MouseDown( where, inKeyModifiers, inMouseButton, inClickCount, inEvent ); + break; + case kEventMouseUp: + result = MouseUp( where, inKeyModifiers, inMouseButton, inClickCount ); + break; + case kEventMouseExited: + result = MouseExited( where, inKeyModifiers, inMouseButton, inClickCount ); + break; + case kEventMouseEntered: + result = MouseEntered( where, inKeyModifiers, inMouseButton, inClickCount ); + break; + case kEventMouseMoved: + case kEventMouseDragged: + result = MouseDragged( where, inKeyModifiers, inMouseButton, inClickCount ); + break; + default:; + } + break; + } + // some other event class + default: + break; + } + +MissingParameter: + return result; +} + +//----------------------------------------------------------------------------------- +// CreateInitializationEvent +//----------------------------------------------------------------------------------- +// Create a basic intialization event containing the parent control and bounds. At +// present we set the bounds to empty and the parent to NULL. In theory, after creating +// this event, any subclass could add its own parameter to receive in its +// Initialize method. +// +EventRef TView::CreateInitializationEvent() +{ + OSStatus result = noErr; + EventRef event; + + result = CreateEvent( NULL, kEventClassHIObject, kEventHIObjectInitialize, + GetCurrentEventTime(), 0, &event ); + require_noerr_action( result, CantCreateEvent, event = NULL ); + +CantCreateEvent: + return event; +} + +//----------------------------------------------------------------------------------- +// Frame +//----------------------------------------------------------------------------------- +// +HIRect TView::Frame() +{ + HIRect frame; + + HIViewGetFrame( GetViewRef(), &frame ); + + return frame; +} + +//----------------------------------------------------------------------------------- +// SetFrame +//----------------------------------------------------------------------------------- +// +OSStatus TView::SetFrame( + const HIRect& inFrame ) +{ + OSStatus err; + + err = HIViewSetFrame( GetViewRef(), &inFrame ); + + return err; +} + +//----------------------------------------------------------------------------------- +// Bounds +//----------------------------------------------------------------------------------- +// +HIRect TView::Bounds() +{ + HIRect bounds; + + HIViewGetBounds( GetViewRef(), &bounds ); + + return bounds; +} + +//----------------------------------------------------------------------------------- +// Show +//----------------------------------------------------------------------------------- +// +OSStatus TView::Show() +{ + return HIViewSetVisible( GetViewRef(), true ); +} + +//----------------------------------------------------------------------------------- +// Hide +//----------------------------------------------------------------------------------- +// +OSStatus TView::Hide() +{ + return HIViewSetVisible( GetViewRef(), false ); +} + +//----------------------------------------------------------------------------------- +// GetEventTarget +//----------------------------------------------------------------------------------- +// +EventTargetRef TView::GetEventTarget() +{ + return HIObjectGetEventTarget( (HIObjectRef) GetViewRef() ); +} + +//----------------------------------------------------------------------------------- +// AddSubView +//----------------------------------------------------------------------------------- +// +OSStatus TView::AddSubView( + TView* inSubView ) +{ + return HIViewAddSubview( GetViewRef(), inSubView->GetViewRef() );; +} + +//----------------------------------------------------------------------------------- +// RemoveFromSuperView +//----------------------------------------------------------------------------------- +// +OSStatus TView::RemoveFromSuperView() +{ + return HIViewRemoveFromSuperview( GetViewRef() ); +} + +//----------------------------------------------------------------------------------- +// GetHilite +//----------------------------------------------------------------------------------- +// +ControlPartCode TView::GetHilite() +{ + return GetControlHilite( GetViewRef() ); +} + +//----------------------------------------------------------------------------------- +// GetValue +//----------------------------------------------------------------------------------- +// +SInt32 TView::GetValue() +{ + return GetControl32BitValue( GetViewRef() ); +} + +//----------------------------------------------------------------------------------- +// SetValue +//----------------------------------------------------------------------------------- +// +void TView::SetValue( + SInt32 inValue ) +{ + SetControl32BitValue( GetViewRef(), inValue ); +} + +//----------------------------------------------------------------------------------- +// GetMinimum +//----------------------------------------------------------------------------------- +// +SInt32 TView::GetMinimum() +{ + return GetControlMinimum( GetViewRef() ); +} + +//----------------------------------------------------------------------------------- +// SetMinimum +//----------------------------------------------------------------------------------- +// +void TView::SetMinimum( + SInt32 inMinimum ) +{ + SetControlMinimum( GetViewRef(), inMinimum ); +} + +//----------------------------------------------------------------------------------- +// GetMaximum +//----------------------------------------------------------------------------------- +// +SInt32 TView::GetMaximum() +{ + return GetControlMaximum( GetViewRef() ); +} + +//----------------------------------------------------------------------------------- +// SetMaximum +//----------------------------------------------------------------------------------- +// +void TView::SetMaximum( + SInt32 inMaximum ) +{ + SetControlMaximum( GetViewRef(), inMaximum ); +} + +//----------------------------------------------------------------------------------- +// GetOwner +//----------------------------------------------------------------------------------- +// +WindowRef TView::GetOwner() +{ + return GetControlOwner( GetViewRef() ); +} + +//----------------------------------------------------------------------------------- +// Hilite +//----------------------------------------------------------------------------------- +// +void TView::Hilite( + ControlPartCode inPart) +{ + return HiliteControl( GetViewRef(), inPart ); +} + +//----------------------------------------------------------------------------------- +// Invalidate +//----------------------------------------------------------------------------------- +// +OSStatus TView::Invalidate() +{ + return HIViewSetNeedsDisplay( GetViewRef(), true ); +} + +void TView::TimerFired( EventLoopTimerRef inTimer ) +{ +#pragma unused( inTimer ) +} + + +//----------------------------------------------------------------------------------- +// IsVisible +//----------------------------------------------------------------------------------- +// +Boolean TView::IsVisible() +{ + return IsControlVisible( GetViewRef() ); +} + +//----------------------------------------------------------------------------------- +// IsEnabled +//----------------------------------------------------------------------------------- +// +Boolean TView::IsEnabled() +{ + return IsControlEnabled( GetViewRef() ); +} + +//----------------------------------------------------------------------------------- +// IsActive +//----------------------------------------------------------------------------------- +// +Boolean TView::IsActive() +{ + return IsControlActive( GetViewRef() ); +} + +//----------------------------------------------------------------------------------- +// ActiveStateChanged +//----------------------------------------------------------------------------------- +// Default activation method. Subclasses should override as necessary. We do nothing +// here in the base class, so we return eventNotHandledErr. +// +OSStatus TView::ActiveStateChanged() +{ + return eventNotHandledErr; +} + +//----------------------------------------------------------------------------------- +// ValueChanged +//----------------------------------------------------------------------------------- +// Default value changed method. Subclasses should override as necessary. We do +// nothing here in the base class, so we return eventNotHandledErr. +// +OSStatus TView::ValueChanged() +{ + return eventNotHandledErr; +} + +//----------------------------------------------------------------------------------- +// TitleChanged +//----------------------------------------------------------------------------------- +// Default title changed method. Subclasses should override as necessary. We +// do nothing here in the base class, so we return eventNotHandledErr. +// +OSStatus TView::TitleChanged() +{ + return eventNotHandledErr; +} + +//----------------------------------------------------------------------------------- +// EnabledStateChanged +//----------------------------------------------------------------------------------- +// Default enable method. Subclasses should override as necessary. We +// do nothing here in the base class, so we return eventNotHandledErr. +// +OSStatus TView::EnabledStateChanged() +{ + return eventNotHandledErr; +} + +//----------------------------------------------------------------------------------- +// TextInput +//----------------------------------------------------------------------------------- +// Default text (Unicode) input method. Subclasses should override as necessary. We +// do nothing here in the base class, so we return eventNotHandledErr. +// +OSStatus TView::TextInput( + TCarbonEvent& inEvent ) +{ +#pragma unused( inEvent ) + + return eventNotHandledErr; +} + +//----------------------------------------------------------------------------------- +// ChangeAutoInvalidateFlags +//----------------------------------------------------------------------------------- +// Change behavior for auto-invalidating views on certain actions. +// +void TView::ChangeAutoInvalidateFlags( + OptionBits inSetThese, + OptionBits inClearThese ) +{ + fAutoInvalidateFlags = ( ( fAutoInvalidateFlags | inSetThese ) & ( ~inClearThese ) ); +} diff --git a/scintilla/macosx/TView.h b/scintilla/macosx/TView.h new file mode 100644 index 00000000..004b10df --- /dev/null +++ b/scintilla/macosx/TView.h @@ -0,0 +1,286 @@ +/* + File: TView.h + + Version: 1.0 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc. + ("Apple") in consideration of your agreement to the following terms, and your + use, installation, modification or redistribution of this Apple software + constitutes acceptance of these terms. If you do not agree with these terms, + please do not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and subject + to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs + copyrights in this original Apple software (the "Apple Software"), to use, + reproduce, modify and redistribute the Apple Software, with or without + modifications, in source and/or binary forms; provided that if you redistribute + the Apple Software in its entirety and without modifications, you must retain + this notice and the following text and disclaimers in all such redistributions of + the Apple Software. Neither the name, trademarks, service marks or logos of + Apple Computer, Inc. may be used to endorse or promote products derived from the + Apple Software without specific prior written permission from Apple. Except as + expressly stated in this notice, no other rights or licenses, express or implied, + are granted by Apple herein, including but not limited to any patent rights that + may be infringed by your derivative works or by other works in which the Apple + Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO + WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED + WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION + OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT + (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + Copyright © 2002 Apple Computer, Inc., All Rights Reserved +*/ + +#ifndef TView_H_ +#define TView_H_ + +#include + +#include "TCarbonEvent.h" +#include "TRect.h" + +#define PURE_VIRTUAL 0 + +class TView +{ +public: + // Bounds and Frame + OSStatus SetFrame( + const HIRect& inBounds ); + HIRect Frame(); + HIRect Bounds(); + + // Visibility + OSStatus Show(); + OSStatus Hide(); + + EventTargetRef GetEventTarget(); + + OSStatus AddSubView( + TView* inSubView ); + OSStatus RemoveFromSuperView(); + + // Accessors + HIViewRef GetViewRef() const + { return fViewRef; } + void Hilite( + ControlPartCode inPart ); + ControlPartCode GetHilite(); + WindowRef GetOwner(); + SInt32 GetValue(); + void SetValue( + SInt32 inValue ); + SInt32 GetMinimum(); + void SetMinimum( + SInt32 inMinimum ); + SInt32 GetMaximum(); + void SetMaximum( + SInt32 inMaximum ); + + // State + Boolean IsVisible(); + Boolean IsEnabled(); + Boolean IsActive(); + + OSStatus Invalidate(); // was SetNeedsDisplay() + + // A "fake" event handler + virtual void TimerFired( EventLoopTimerRef inTimer ); + +protected: + // Autoinvalidation + enum { + kAutoInvalidateOnActivate = (1 << 0), + kAutoInvalidateOnHilite = (1 << 1), + kAutoInvalidateOnEnable = (1 << 2), + kAutoInvalidateOnValueChange = (1 << 3), + kAutoInvalidateOnTitleChange = (1 << 4) + }; + void ChangeAutoInvalidateFlags( + OptionBits inSetFlags, + OptionBits inClearFlags ); + OptionBits GetAutoInvalidateFlags() + { return fAutoInvalidateFlags; } + + // Types + typedef OSStatus (*ConstructProc)( + ControlRef inBaseControl, + TView** outView ); + + // Construction/Destruction + TView( HIViewRef inControl ); + virtual ~TView(); + + virtual ControlKind GetKind() = PURE_VIRTUAL; + virtual UInt32 GetBehaviors(); + + // Handlers + virtual OSStatus ActiveStateChanged(); + virtual OSStatus BoundsChanged( + UInt32 inOptions, + const HIRect& inOriginalBounds, + const HIRect& inCurrentBounds, + RgnHandle inInvalRgn ); + virtual OSStatus ControlHit( + ControlPartCode inPart, + UInt32 inModifiers ); + virtual OSStatus EnabledStateChanged(); + virtual void Draw( + RgnHandle inLimitRgn, + CGContextRef inContext ); + virtual OSStatus GetData( + OSType inTag, + ControlPartCode inPart, + Size inSize, + Size* outSize, + void* inPtr ); + virtual OSStatus GetRegion( + ControlPartCode inPart, + RgnHandle outRgn ); + virtual OSStatus HiliteChanged( + ControlPartCode inOriginalPart, + ControlPartCode inCurrentPart, + RgnHandle inInvalRgn ); + virtual ControlPartCode HitTest( + const HIPoint& inWhere ); + virtual OSStatus Initialize( + TCarbonEvent& inEvent ); + virtual OSStatus SetData( + OSType inTag, + ControlPartCode inPart, + Size inSize, + const void* inPtr ); + virtual OSStatus SetFocusPart( + ControlPartCode inDesiredFocus, + RgnHandle inNnvalidRgn, + Boolean inFocusEverything, + ControlPartCode* outActualFocus ); + virtual OSStatus TextInput( + TCarbonEvent& inEvent ); + virtual OSStatus TitleChanged(); + virtual OSStatus Track( + TCarbonEvent& inEvent, + ControlPartCode* outPartHit ); + virtual OSStatus ValueChanged(); + + // Sizing + virtual OSStatus GetSizeConstraints( + HISize* outMin, + HISize* outMax ); + virtual OSStatus GetOptimalSize( + HISize* outSize, + float* outBaseLine ); + + // Accessors + WindowRef GetWindowRef() + { return GetControlOwner( GetViewRef() ); } + + + // Drag and drop + virtual bool DragEnter( + DragRef inDrag ); + virtual bool DragWithin( + DragRef inDrag ); + virtual bool DragLeave( + DragRef inDrag ); + virtual OSStatus DragReceive( + DragRef inDrag ); + + // Command processing + virtual OSStatus ProcessCommand( + const HICommand& inCommand ); + virtual OSStatus UpdateCommandStatus( + const HICommand& inCommand ); + + // Mouse events + virtual OSStatus MouseDown( + HIPoint& inMouseLocation, + UInt32 inKeyModifiers, + EventMouseButton inMouseButton, + UInt32 inClickCount, + TCarbonEvent& inEvent); + virtual OSStatus MouseUp( + HIPoint& inMouseLocation, + UInt32 inKeyModifiers, + EventMouseButton inMouseButton, + UInt32 inClickCount ); + virtual OSStatus MouseDragged( + HIPoint& inMouseLocation, + UInt32 inKeyModifiers, + EventMouseButton inMouseButton, + UInt32 inClickCount ); + virtual OSStatus MouseEntered( + HIPoint& inMouseLocation, + UInt32 inKeyModifiers, + EventMouseButton inMouseButton, + UInt32 inClickCount ); + virtual OSStatus MouseExited( + HIPoint& inMouseLocation, + UInt32 inKeyModifiers, + EventMouseButton inMouseButton, + UInt32 inClickCount ); + virtual OSStatus MouseWheelMoved( EventMouseWheelAxis inAxis, SInt32 inDelta, UInt32 inKeyModifiers ); + virtual OSStatus ContextualMenuClick( HIPoint& inMouseLocation ); + + // Utility + static OSStatus RegisterSubclass( + CFStringRef inID, + ConstructProc inProc ); + static EventRef CreateInitializationEvent(); + enum Interface { + kDragAndDrop = 1, + kKeyboardFocus, + kMouse, + kMouseTracking + }; + virtual OSStatus ActivateInterface( + Interface inInterface ); + + OSStatus InstallTimer( + EventTimerInterval inFireDelay, + EventLoopTimerRef* outTimer ); + + // Debugging + virtual void PrintDebugInfo(); + Boolean debugPrint; +private: + static pascal OSStatus ObjectEventHandler( + EventHandlerCallRef inCallRef, + EventRef inEvent, + void* inUserData ); + static pascal OSStatus ViewEventHandler( + EventHandlerCallRef inCallRef, + EventRef inEvent, + void* inUserData ); + static pascal OSStatus WindowEventHandler( + EventHandlerCallRef inCallRef, + EventRef inEvent, + void* inUserData ); + static pascal void TimerEventHandler( + EventLoopTimerRef inTimer, + void* inUserData ); + OSStatus HandleEvent( + EventHandlerCallRef inCallRef, + TCarbonEvent& inEvent ); + + HIViewRef fViewRef; + EventHandlerRef fHandler; + + EventHandlerRef mouseEventHandler; + OptionBits fAutoInvalidateFlags; + +}; + +typedef TView* TViewPtr; + +#endif // TView_H_ diff --git a/scintilla/macosx/deps.mak b/scintilla/macosx/deps.mak new file mode 100644 index 00000000..a03366b6 --- /dev/null +++ b/scintilla/macosx/deps.mak @@ -0,0 +1,375 @@ +ExtInput.o: ExtInput.cxx ScintillaMacOSX.h TView.h TCarbonEvent.h TRect.h \ + ../include/Platform.h ../include/Scintilla.h PlatMacOSX.h \ + QuartzTextLayout.h QuartzTextStyle.h QuartzTextStyleAttribute.h \ + ../include/ScintillaWidget.h ../include/SciLexer.h ../include/PropSet.h \ + ../include/Accessor.h ../include/KeyWords.h ../src/SVector.h \ + ../src/SplitVector.h ../src/Partitioning.h ../src/RunStyles.h \ + ../src/ContractionState.h ../src/CellBuffer.h ../src/CallTip.h \ + ../src/KeyMap.h ../src/Indicator.h ../src/XPM.h ../src/LineMarker.h \ + ../src/Style.h ../src/AutoComplete.h ../src/ViewStyle.h \ + ../src/CharClassify.h ../src/Decoration.h ../src/Document.h \ + ../src/Selection.h ../src/PositionCache.h ../src/Editor.h \ + ../src/ScintillaBase.h ScintillaCallTip.h ExtInput.h +PlatMacOSX.o: PlatMacOSX.cxx QuartzTextLayout.h QuartzTextStyle.h \ + QuartzTextStyleAttribute.h TCarbonEvent.h ../include/Platform.h \ + ../include/Scintilla.h PlatMacOSX.h ../src/XPM.h \ + ../include/ScintillaWidget.h +ScintillaCallTip.o: ScintillaCallTip.cxx ScintillaMacOSX.h TView.h \ + TCarbonEvent.h TRect.h ../include/Platform.h ../include/Scintilla.h \ + PlatMacOSX.h QuartzTextLayout.h QuartzTextStyle.h \ + QuartzTextStyleAttribute.h ../include/ScintillaWidget.h \ + ../include/SciLexer.h ../include/PropSet.h ../include/Accessor.h \ + ../include/KeyWords.h ../src/SVector.h ../src/SplitVector.h \ + ../src/Partitioning.h ../src/RunStyles.h ../src/ContractionState.h \ + ../src/CellBuffer.h ../src/CallTip.h ../src/KeyMap.h ../src/Indicator.h \ + ../src/XPM.h ../src/LineMarker.h ../src/Style.h ../src/AutoComplete.h \ + ../src/ViewStyle.h ../src/CharClassify.h ../src/Decoration.h \ + ../src/Document.h ../src/Selection.h ../src/PositionCache.h \ + ../src/Editor.h ../src/ScintillaBase.h ScintillaCallTip.h +ScintillaListBox.o: ScintillaListBox.cxx ScintillaMacOSX.h TView.h \ + TCarbonEvent.h TRect.h ../include/Platform.h ../include/Scintilla.h \ + PlatMacOSX.h QuartzTextLayout.h QuartzTextStyle.h \ + QuartzTextStyleAttribute.h ../include/ScintillaWidget.h \ + ../include/SciLexer.h ../include/PropSet.h ../include/Accessor.h \ + ../include/KeyWords.h ../src/SVector.h ../src/SplitVector.h \ + ../src/Partitioning.h ../src/RunStyles.h ../src/ContractionState.h \ + ../src/CellBuffer.h ../src/CallTip.h ../src/KeyMap.h ../src/Indicator.h \ + ../src/XPM.h ../src/LineMarker.h ../src/Style.h ../src/AutoComplete.h \ + ../src/ViewStyle.h ../src/CharClassify.h ../src/Decoration.h \ + ../src/Document.h ../src/Selection.h ../src/PositionCache.h \ + ../src/Editor.h ../src/ScintillaBase.h ScintillaCallTip.h \ + ScintillaListBox.h +ScintillaMacOSX.o: ScintillaMacOSX.cxx ScintillaMacOSX.h TView.h \ + TCarbonEvent.h TRect.h ../include/Platform.h ../include/Scintilla.h \ + PlatMacOSX.h QuartzTextLayout.h QuartzTextStyle.h \ + QuartzTextStyleAttribute.h ../include/ScintillaWidget.h \ + ../include/SciLexer.h ../include/PropSet.h ../include/Accessor.h \ + ../include/KeyWords.h ../src/SVector.h ../src/SplitVector.h \ + ../src/Partitioning.h ../src/RunStyles.h ../src/ContractionState.h \ + ../src/CellBuffer.h ../src/CallTip.h ../src/KeyMap.h ../src/Indicator.h \ + ../src/XPM.h ../src/LineMarker.h ../src/Style.h ../src/AutoComplete.h \ + ../src/ViewStyle.h ../src/CharClassify.h ../src/Decoration.h \ + ../src/Document.h ../src/Selection.h ../src/PositionCache.h \ + ../src/Editor.h ../src/ScintillaBase.h ScintillaCallTip.h \ + ../src/UniConversion.h +TCarbonEvent.o: TCarbonEvent.cxx TCarbonEvent.h +TView.o: TView.cxx TView.h TCarbonEvent.h TRect.h +AutoComplete.o: ../src/AutoComplete.cxx ../include/Platform.h \ + ../src/CharClassify.h ../src/AutoComplete.h +CallTip.o: ../src/CallTip.cxx ../include/Platform.h \ + ../include/Scintilla.h ../src/CallTip.h +CellBuffer.o: ../src/CellBuffer.cxx ../include/Platform.h \ + ../include/Scintilla.h ../src/SplitVector.h ../src/Partitioning.h \ + ../src/CellBuffer.h +CharClassify.o: ../src/CharClassify.cxx ../src/CharClassify.h +ContractionState.o: ../src/ContractionState.cxx ../include/Platform.h \ + ../src/SplitVector.h ../src/Partitioning.h ../src/RunStyles.h \ + ../src/ContractionState.h +Decoration.o: ../src/Decoration.cxx ../include/Platform.h \ + ../include/Scintilla.h ../src/SplitVector.h ../src/Partitioning.h \ + ../src/RunStyles.h ../src/Decoration.h +Document.o: ../src/Document.cxx ../include/Platform.h \ + ../include/Scintilla.h ../src/SplitVector.h ../src/Partitioning.h \ + ../src/RunStyles.h ../src/CellBuffer.h ../src/PerLine.h \ + ../src/CharClassify.h ../src/Decoration.h ../src/Document.h \ + ../src/RESearch.h +DocumentAccessor.o: ../src/DocumentAccessor.cxx ../include/Platform.h \ + ../include/PropSet.h ../include/Accessor.h ../src/DocumentAccessor.h \ + ../src/SplitVector.h ../src/Partitioning.h ../src/RunStyles.h \ + ../src/CellBuffer.h ../include/Scintilla.h ../src/CharClassify.h \ + ../src/Decoration.h ../src/Document.h +Editor.o: ../src/Editor.cxx ../include/Platform.h ../include/Scintilla.h \ + ../src/SplitVector.h ../src/Partitioning.h ../src/RunStyles.h \ + ../src/ContractionState.h ../src/CellBuffer.h ../src/KeyMap.h \ + ../src/Indicator.h ../src/XPM.h ../src/LineMarker.h ../src/Style.h \ + ../src/ViewStyle.h ../src/CharClassify.h ../src/Decoration.h \ + ../src/Document.h ../src/Selection.h ../src/PositionCache.h \ + ../src/Editor.h +ExternalLexer.o: ../src/ExternalLexer.cxx ../include/Platform.h \ + ../include/Scintilla.h ../include/SciLexer.h ../include/PropSet.h \ + ../include/Accessor.h ../src/DocumentAccessor.h ../include/KeyWords.h \ + ../src/ExternalLexer.h +Indicator.o: ../src/Indicator.cxx ../include/Platform.h \ + ../include/Scintilla.h ../src/Indicator.h +KeyMap.o: ../src/KeyMap.cxx ../include/Platform.h ../include/Scintilla.h \ + ../src/KeyMap.h +KeyWords.o: ../src/KeyWords.cxx ../include/Platform.h \ + ../include/PropSet.h ../include/Accessor.h ../include/KeyWords.h \ + ../include/Scintilla.h ../include/SciLexer.h +LexAPDL.o: ../src/LexAPDL.cxx ../include/Platform.h ../include/PropSet.h \ + ../include/Accessor.h ../src/StyleContext.h ../include/KeyWords.h \ + ../include/Scintilla.h ../include/SciLexer.h +LexASY.o: ../src/LexASY.cxx ../include/Platform.h ../include/PropSet.h \ + ../include/Accessor.h ../src/StyleContext.h ../include/KeyWords.h \ + ../include/Scintilla.h ../include/SciLexer.h ../src/CharacterSet.h +LexAU3.o: ../src/LexAU3.cxx ../include/Platform.h ../include/PropSet.h \ + ../include/Accessor.h ../src/StyleContext.h ../include/KeyWords.h \ + ../include/Scintilla.h ../include/SciLexer.h +LexAVE.o: ../src/LexAVE.cxx ../include/Platform.h ../include/PropSet.h \ + ../include/Accessor.h ../src/StyleContext.h ../include/KeyWords.h \ + ../include/Scintilla.h ../include/SciLexer.h +LexAbaqus.o: ../src/LexAbaqus.cxx ../include/Platform.h \ + ../include/PropSet.h ../include/Accessor.h ../src/StyleContext.h \ + ../include/KeyWords.h ../include/Scintilla.h ../include/SciLexer.h +LexAda.o: ../src/LexAda.cxx ../include/Platform.h ../include/Accessor.h \ + ../src/StyleContext.h ../include/PropSet.h ../include/KeyWords.h \ + ../include/SciLexer.h +LexAsm.o: ../src/LexAsm.cxx ../include/Platform.h ../include/PropSet.h \ + ../include/Accessor.h ../src/StyleContext.h ../include/KeyWords.h \ + ../include/Scintilla.h ../include/SciLexer.h +LexAsn1.o: ../src/LexAsn1.cxx ../include/Platform.h ../include/PropSet.h \ + ../include/Accessor.h ../src/StyleContext.h ../include/KeyWords.h \ + ../include/Scintilla.h ../include/SciLexer.h +LexBaan.o: ../src/LexBaan.cxx ../include/Platform.h ../include/PropSet.h \ + ../include/Accessor.h ../src/StyleContext.h ../include/KeyWords.h \ + ../include/Scintilla.h ../include/SciLexer.h +LexBash.o: ../src/LexBash.cxx ../include/Platform.h ../include/PropSet.h \ + ../include/Accessor.h ../src/StyleContext.h ../include/KeyWords.h \ + ../include/Scintilla.h ../include/SciLexer.h ../src/CharacterSet.h +LexBasic.o: ../src/LexBasic.cxx ../include/Platform.h \ + ../include/PropSet.h ../include/Accessor.h ../src/StyleContext.h \ + ../include/KeyWords.h ../include/Scintilla.h ../include/SciLexer.h +LexBullant.o: ../src/LexBullant.cxx ../include/Platform.h \ + ../include/PropSet.h ../include/Accessor.h ../include/KeyWords.h \ + ../include/Scintilla.h ../include/SciLexer.h +LexCLW.o: ../src/LexCLW.cxx ../include/Platform.h ../include/PropSet.h \ + ../include/Accessor.h ../src/StyleContext.h ../include/KeyWords.h \ + ../include/Scintilla.h ../include/SciLexer.h +LexCOBOL.o: ../src/LexCOBOL.cxx ../include/Platform.h \ + ../include/PropSet.h ../include/Accessor.h ../include/KeyWords.h \ + ../include/Scintilla.h ../include/SciLexer.h ../src/StyleContext.h +LexCPP.o: ../src/LexCPP.cxx ../include/Platform.h ../include/PropSet.h \ + ../include/Accessor.h ../src/StyleContext.h ../include/KeyWords.h \ + ../include/Scintilla.h ../include/SciLexer.h ../src/CharacterSet.h +LexCSS.o: ../src/LexCSS.cxx ../include/Platform.h ../include/PropSet.h \ + ../include/Accessor.h ../src/StyleContext.h ../include/KeyWords.h \ + ../include/Scintilla.h ../include/SciLexer.h +LexCaml.o: ../src/LexCaml.cxx ../include/Platform.h ../include/PropSet.h \ + ../src/PropSetSimple.h ../include/Accessor.h ../src/StyleContext.h \ + ../include/KeyWords.h ../include/Scintilla.h ../include/SciLexer.h +LexCmake.o: ../src/LexCmake.cxx ../include/Platform.h \ + ../src/CharClassify.h ../include/PropSet.h ../include/Accessor.h \ + ../include/KeyWords.h ../include/Scintilla.h ../include/SciLexer.h +LexConf.o: ../src/LexConf.cxx ../include/Platform.h ../include/PropSet.h \ + ../include/Accessor.h ../include/KeyWords.h ../include/Scintilla.h \ + ../include/SciLexer.h +LexCrontab.o: ../src/LexCrontab.cxx ../include/Platform.h \ + ../include/PropSet.h ../include/Accessor.h ../include/KeyWords.h \ + ../include/Scintilla.h ../include/SciLexer.h +LexCsound.o: ../src/LexCsound.cxx ../include/Platform.h \ + ../include/PropSet.h ../include/Accessor.h ../src/StyleContext.h \ + ../include/KeyWords.h ../include/Scintilla.h ../include/SciLexer.h +LexD.o: ../src/LexD.cxx ../include/Platform.h ../include/PropSet.h \ + ../include/Accessor.h ../src/StyleContext.h ../include/KeyWords.h \ + ../include/Scintilla.h ../include/SciLexer.h +LexEScript.o: ../src/LexEScript.cxx ../include/Platform.h \ + ../include/PropSet.h ../include/Accessor.h ../src/StyleContext.h \ + ../include/KeyWords.h ../include/Scintilla.h ../include/SciLexer.h +LexEiffel.o: ../src/LexEiffel.cxx ../include/Platform.h \ + ../include/PropSet.h ../include/Accessor.h ../src/StyleContext.h \ + ../include/KeyWords.h ../include/Scintilla.h ../include/SciLexer.h +LexErlang.o: ../src/LexErlang.cxx ../include/Platform.h \ + ../include/PropSet.h ../include/Accessor.h ../src/StyleContext.h \ + ../include/KeyWords.h ../include/Scintilla.h ../include/SciLexer.h +LexFlagship.o: ../src/LexFlagship.cxx ../include/Platform.h \ + ../include/PropSet.h ../include/Accessor.h ../src/StyleContext.h \ + ../include/KeyWords.h ../include/Scintilla.h ../include/SciLexer.h +LexForth.o: ../src/LexForth.cxx ../include/Platform.h \ + ../include/PropSet.h ../include/Accessor.h ../src/StyleContext.h \ + ../include/KeyWords.h ../include/Scintilla.h ../include/SciLexer.h +LexFortran.o: ../src/LexFortran.cxx ../include/Platform.h \ + ../include/PropSet.h ../include/Accessor.h ../src/StyleContext.h \ + ../include/KeyWords.h ../include/Scintilla.h ../include/SciLexer.h +LexGAP.o: ../src/LexGAP.cxx ../include/Platform.h ../include/PropSet.h \ + ../include/Accessor.h ../src/StyleContext.h ../include/KeyWords.h \ + ../include/Scintilla.h ../include/SciLexer.h +LexGui4Cli.o: ../src/LexGui4Cli.cxx ../include/Platform.h \ + ../include/PropSet.h ../include/Accessor.h ../src/StyleContext.h \ + ../include/KeyWords.h ../include/Scintilla.h ../include/SciLexer.h +LexHTML.o: ../src/LexHTML.cxx ../include/Platform.h ../include/PropSet.h \ + ../include/Accessor.h ../src/StyleContext.h ../include/KeyWords.h \ + ../include/Scintilla.h ../include/SciLexer.h ../src/CharacterSet.h +LexHaskell.o: ../src/LexHaskell.cxx ../include/Platform.h \ + ../include/PropSet.h ../src/PropSetSimple.h ../include/Accessor.h \ + ../src/StyleContext.h ../include/KeyWords.h ../include/Scintilla.h \ + ../include/SciLexer.h +LexInno.o: ../src/LexInno.cxx ../include/Platform.h ../src/CharClassify.h \ + ../include/PropSet.h ../include/Accessor.h ../src/StyleContext.h \ + ../include/KeyWords.h ../include/Scintilla.h ../include/SciLexer.h +LexKix.o: ../src/LexKix.cxx ../include/Platform.h ../include/PropSet.h \ + ../include/Accessor.h ../src/StyleContext.h ../include/KeyWords.h \ + ../include/Scintilla.h ../include/SciLexer.h +LexLisp.o: ../src/LexLisp.cxx ../include/Platform.h ../include/PropSet.h \ + ../include/Accessor.h ../include/KeyWords.h ../include/Scintilla.h \ + ../include/SciLexer.h ../src/StyleContext.h +LexLout.o: ../src/LexLout.cxx ../include/Platform.h ../include/PropSet.h \ + ../include/Accessor.h ../src/StyleContext.h ../include/KeyWords.h \ + ../include/Scintilla.h ../include/SciLexer.h +LexLua.o: ../src/LexLua.cxx ../include/Platform.h ../include/PropSet.h \ + ../include/Accessor.h ../src/StyleContext.h ../include/KeyWords.h \ + ../include/Scintilla.h ../include/SciLexer.h ../src/CharacterSet.h +LexMMIXAL.o: ../src/LexMMIXAL.cxx ../include/Platform.h \ + ../include/PropSet.h ../include/Accessor.h ../src/StyleContext.h \ + ../include/KeyWords.h ../include/Scintilla.h ../include/SciLexer.h +LexMPT.o: ../src/LexMPT.cxx ../include/Platform.h ../include/PropSet.h \ + ../include/Accessor.h ../include/KeyWords.h ../include/Scintilla.h \ + ../include/SciLexer.h +LexMSSQL.o: ../src/LexMSSQL.cxx ../include/Platform.h \ + ../include/PropSet.h ../include/Accessor.h ../include/KeyWords.h \ + ../include/Scintilla.h ../include/SciLexer.h +LexMagik.o: ../src/LexMagik.cxx ../include/Platform.h \ + ../include/PropSet.h ../include/Accessor.h ../src/StyleContext.h \ + ../include/KeyWords.h ../include/Scintilla.h ../include/SciLexer.h +LexMatlab.o: ../src/LexMatlab.cxx ../include/Platform.h \ + ../include/PropSet.h ../include/Accessor.h ../src/StyleContext.h \ + ../include/KeyWords.h ../include/Scintilla.h ../include/SciLexer.h +LexMetapost.o: ../src/LexMetapost.cxx ../include/Platform.h \ + ../include/PropSet.h ../include/Accessor.h ../include/KeyWords.h \ + ../include/Scintilla.h ../include/SciLexer.h ../src/StyleContext.h +LexMySQL.o: ../src/LexMySQL.cxx ../include/Platform.h \ + ../include/PropSet.h ../include/Accessor.h ../src/StyleContext.h \ + ../include/KeyWords.h ../include/Scintilla.h ../include/SciLexer.h +LexNimrod.o: ../src/LexNimrod.cxx ../include/Platform.h \ + ../include/PropSet.h ../include/Accessor.h ../src/StyleContext.h \ + ../include/KeyWords.h ../include/Scintilla.h ../include/SciLexer.h +LexNsis.o: ../src/LexNsis.cxx ../include/Platform.h ../src/CharClassify.h \ + ../include/PropSet.h ../include/Accessor.h ../include/KeyWords.h \ + ../include/Scintilla.h ../include/SciLexer.h +LexOpal.o: ../src/LexOpal.cxx ../include/Platform.h ../include/PropSet.h \ + ../include/Accessor.h ../include/KeyWords.h ../include/Scintilla.h \ + ../include/SciLexer.h ../src/StyleContext.h +LexOthers.o: ../src/LexOthers.cxx ../include/Platform.h \ + ../src/CharClassify.h ../include/PropSet.h ../include/Accessor.h \ + ../include/KeyWords.h ../include/Scintilla.h ../include/SciLexer.h +LexPB.o: ../src/LexPB.cxx ../include/Platform.h ../include/PropSet.h \ + ../include/Accessor.h ../src/StyleContext.h ../include/KeyWords.h \ + ../include/Scintilla.h ../include/SciLexer.h +LexPLM.o: ../src/LexPLM.cxx ../include/Platform.h ../include/PropSet.h \ + ../include/Accessor.h ../include/KeyWords.h ../include/Scintilla.h \ + ../include/SciLexer.h ../src/StyleContext.h +LexPOV.o: ../src/LexPOV.cxx ../include/Platform.h ../include/PropSet.h \ + ../include/Accessor.h ../src/StyleContext.h ../include/KeyWords.h \ + ../include/Scintilla.h ../include/SciLexer.h +LexPS.o: ../src/LexPS.cxx ../include/Platform.h ../include/PropSet.h \ + ../include/Accessor.h ../src/StyleContext.h ../include/KeyWords.h \ + ../include/Scintilla.h ../include/SciLexer.h +LexPascal.o: ../src/LexPascal.cxx ../include/Platform.h \ + ../include/PropSet.h ../include/Accessor.h ../include/KeyWords.h \ + ../include/Scintilla.h ../include/SciLexer.h ../src/StyleContext.h \ + ../src/CharacterSet.h +LexPerl.o: ../src/LexPerl.cxx ../include/Platform.h ../include/PropSet.h \ + ../include/Accessor.h ../src/StyleContext.h ../include/KeyWords.h \ + ../include/Scintilla.h ../include/SciLexer.h ../src/CharacterSet.h +LexPowerPro.o: ../src/LexPowerPro.cxx ../include/Platform.h \ + ../include/PropSet.h ../include/Accessor.h ../src/StyleContext.h \ + ../include/KeyWords.h ../include/Scintilla.h ../include/SciLexer.h \ + ../src/CharacterSet.h +LexPowerShell.o: ../src/LexPowerShell.cxx ../include/Platform.h \ + ../include/PropSet.h ../include/Accessor.h ../src/StyleContext.h \ + ../include/KeyWords.h ../include/Scintilla.h ../include/SciLexer.h +LexProgress.o: ../src/LexProgress.cxx ../include/Platform.h \ + ../include/PropSet.h ../include/Accessor.h ../src/StyleContext.h \ + ../include/KeyWords.h ../include/Scintilla.h ../include/SciLexer.h +LexPython.o: ../src/LexPython.cxx ../include/Platform.h \ + ../include/PropSet.h ../include/Accessor.h ../src/StyleContext.h \ + ../include/KeyWords.h ../include/Scintilla.h ../include/SciLexer.h +LexR.o: ../src/LexR.cxx ../include/Platform.h ../include/PropSet.h \ + ../include/Accessor.h ../src/StyleContext.h ../include/KeyWords.h \ + ../include/Scintilla.h ../include/SciLexer.h +LexRebol.o: ../src/LexRebol.cxx ../include/Platform.h \ + ../include/PropSet.h ../include/Accessor.h ../include/KeyWords.h \ + ../include/Scintilla.h ../include/SciLexer.h ../src/StyleContext.h +LexRuby.o: ../src/LexRuby.cxx ../include/Platform.h ../include/PropSet.h \ + ../include/Accessor.h ../include/KeyWords.h ../include/Scintilla.h \ + ../include/SciLexer.h +LexSML.o: ../src/LexSML.cxx ../include/Platform.h ../include/PropSet.h \ + ../include/Accessor.h ../src/StyleContext.h ../include/KeyWords.h \ + ../include/Scintilla.h ../include/SciLexer.h +LexSQL.o: ../src/LexSQL.cxx ../include/Platform.h ../include/PropSet.h \ + ../include/Accessor.h ../src/StyleContext.h ../include/KeyWords.h \ + ../include/Scintilla.h ../include/SciLexer.h +LexScriptol.o: ../src/LexScriptol.cxx ../include/Platform.h \ + ../include/PropSet.h ../include/Accessor.h ../include/KeyWords.h \ + ../include/Scintilla.h ../include/SciLexer.h +LexSmalltalk.o: ../src/LexSmalltalk.cxx ../include/Platform.h \ + ../include/PropSet.h ../include/Accessor.h ../src/StyleContext.h \ + ../include/KeyWords.h ../include/Scintilla.h ../include/SciLexer.h +LexSorcus.o: ../src/LexSorcus.cxx ../include/Platform.h \ + ../include/PropSet.h ../include/Accessor.h ../src/StyleContext.h \ + ../include/KeyWords.h ../include/Scintilla.h ../include/SciLexer.h +LexSpecman.o: ../src/LexSpecman.cxx ../include/Platform.h \ + ../include/PropSet.h ../include/Accessor.h ../src/StyleContext.h \ + ../include/KeyWords.h ../include/Scintilla.h ../include/SciLexer.h +LexSpice.o: ../src/LexSpice.cxx ../include/Platform.h \ + ../include/Accessor.h ../src/StyleContext.h ../include/PropSet.h \ + ../include/KeyWords.h ../include/SciLexer.h +LexTACL.o: ../src/LexTACL.cxx ../include/Platform.h ../include/PropSet.h \ + ../include/Accessor.h ../include/KeyWords.h ../include/Scintilla.h \ + ../include/SciLexer.h ../src/StyleContext.h +LexTADS3.o: ../src/LexTADS3.cxx ../include/Platform.h \ + ../include/PropSet.h ../include/Accessor.h ../src/StyleContext.h \ + ../include/KeyWords.h ../include/Scintilla.h ../include/SciLexer.h +LexTAL.o: ../src/LexTAL.cxx ../include/Platform.h ../include/PropSet.h \ + ../include/Accessor.h ../include/KeyWords.h ../include/Scintilla.h \ + ../include/SciLexer.h ../src/StyleContext.h +LexTCL.o: ../src/LexTCL.cxx ../include/Platform.h ../include/PropSet.h \ + ../include/Accessor.h ../src/StyleContext.h ../include/KeyWords.h \ + ../include/Scintilla.h ../include/SciLexer.h +LexTeX.o: ../src/LexTeX.cxx ../include/Platform.h ../include/PropSet.h \ + ../include/Accessor.h ../include/KeyWords.h ../include/Scintilla.h \ + ../include/SciLexer.h ../src/StyleContext.h +LexVB.o: ../src/LexVB.cxx ../include/Platform.h ../include/PropSet.h \ + ../include/Accessor.h ../src/StyleContext.h ../include/KeyWords.h \ + ../include/Scintilla.h ../include/SciLexer.h +LexVHDL.o: ../src/LexVHDL.cxx ../include/Platform.h ../include/PropSet.h \ + ../include/Accessor.h ../src/StyleContext.h ../include/KeyWords.h \ + ../include/Scintilla.h ../include/SciLexer.h +LexVerilog.o: ../src/LexVerilog.cxx ../include/Platform.h \ + ../include/PropSet.h ../include/Accessor.h ../src/StyleContext.h \ + ../include/KeyWords.h ../include/Scintilla.h ../include/SciLexer.h +LexYAML.o: ../src/LexYAML.cxx ../include/Platform.h ../include/PropSet.h \ + ../include/Accessor.h ../src/StyleContext.h ../include/KeyWords.h \ + ../include/Scintilla.h ../include/SciLexer.h +LineMarker.o: ../src/LineMarker.cxx ../include/Platform.h \ + ../include/Scintilla.h ../src/XPM.h ../src/LineMarker.h +PerLine.o: ../src/PerLine.cxx ../include/Platform.h \ + ../include/Scintilla.h ../src/SplitVector.h ../src/Partitioning.h \ + ../src/CellBuffer.h ../src/PerLine.h +PositionCache.o: ../src/PositionCache.cxx ../include/Platform.h \ + ../include/Scintilla.h ../src/SplitVector.h ../src/Partitioning.h \ + ../src/RunStyles.h ../src/ContractionState.h ../src/CellBuffer.h \ + ../src/KeyMap.h ../src/Indicator.h ../src/XPM.h ../src/LineMarker.h \ + ../src/Style.h ../src/ViewStyle.h ../src/CharClassify.h \ + ../src/Decoration.h ../src/Document.h ../src/Selection.h \ + ../src/PositionCache.h +PropSet.o: ../src/PropSet.cxx ../include/Platform.h ../include/PropSet.h \ + ../src/PropSetSimple.h +RESearch.o: ../src/RESearch.cxx ../src/CharClassify.h ../src/RESearch.h +RunStyles.o: ../src/RunStyles.cxx ../include/Platform.h \ + ../include/Scintilla.h ../src/SplitVector.h ../src/Partitioning.h \ + ../src/RunStyles.h +ScintillaBase.o: ../src/ScintillaBase.cxx ../include/Platform.h \ + ../include/Scintilla.h ../include/PropSet.h ../src/PropSetSimple.h \ + ../include/SciLexer.h ../include/Accessor.h ../src/DocumentAccessor.h \ + ../include/KeyWords.h ../src/SplitVector.h ../src/Partitioning.h \ + ../src/RunStyles.h ../src/ContractionState.h ../src/CellBuffer.h \ + ../src/CallTip.h ../src/KeyMap.h ../src/Indicator.h ../src/XPM.h \ + ../src/LineMarker.h ../src/Style.h ../src/ViewStyle.h \ + ../src/AutoComplete.h ../src/CharClassify.h ../src/Decoration.h \ + ../src/Document.h ../src/Selection.h ../src/PositionCache.h \ + ../src/Editor.h ../src/ScintillaBase.h +Selection.o: ../src/Selection.cxx ../include/Platform.h \ + ../include/Scintilla.h ../src/Selection.h +Style.o: ../src/Style.cxx ../include/Platform.h ../include/Scintilla.h \ + ../src/Style.h +StyleContext.o: ../src/StyleContext.cxx ../include/Platform.h \ + ../include/PropSet.h ../include/Accessor.h ../src/StyleContext.h +UniConversion.o: ../src/UniConversion.cxx ../src/UniConversion.h +ViewStyle.o: ../src/ViewStyle.cxx ../include/Platform.h \ + ../include/Scintilla.h ../src/SplitVector.h ../src/Partitioning.h \ + ../src/RunStyles.h ../src/Indicator.h ../src/XPM.h ../src/LineMarker.h \ + ../src/Style.h ../src/ViewStyle.h +WindowAccessor.o: ../src/WindowAccessor.cxx ../include/Platform.h \ + ../include/PropSet.h ../include/Accessor.h ../include/WindowAccessor.h \ + ../include/Scintilla.h +XPM.o: ../src/XPM.cxx ../include/Platform.h ../src/XPM.h diff --git a/scintilla/macosx/makefile b/scintilla/macosx/makefile new file mode 100644 index 00000000..2eb08709 --- /dev/null +++ b/scintilla/macosx/makefile @@ -0,0 +1,115 @@ +# Make file for Scintilla on Mac OS X +# Copyright 2002 by Evan Jones +# Based on the GTK makefile Copyright 1998-2001 by Neil Hodgson +# The License.txt file describes the conditions under which this software may be distributed. +# This makefile assumes that Apple's version of GCC 3.1 is used and changes will be needed to use other compilers. +# GNU make does not like \r\n line endings so should be saved to CVS in binary form. + +.SUFFIXES: .cxx .c .o .h .a +CC = g++ +CCOMP = gcc +LIBTOOL = libtool + +GCC_MAJOR := $(shell $(CC) -v 2>&1 | \ + grep version | cut -d' ' -f3 | cut -d'.' -f1) + +# We call it "libscintilla" so when you add it to a Project Builder project, +# Project Builder will link it correctly. +STATICLIB=../bin/libscintilla.a +DYNAMICLIB=../bin/libscintilla.dylib + +vpath %.h ../src ../include +vpath %.cxx ../src + +INCLUDEDIRS=-I ../include -I ../src + +ifeq ($(GCC_MAJOR),3) +# 10.4 will have GCC 4 or better, so this should only ever happen +# on a 10.3 or older PPC box +ARCHFLAGS=-arch ppc -faltivec -mcpu=7400 -mtune=7400 -mpowerpc -mpowerpc-gfxopt +else +ifndef NATIVE +ARCH_BASE_FLAGS=/Developer/SDKs/MacOSX10.5.sdk -arch ppc -arch i386 +ARCHFLAGS=-isysroot $(ARCH_BASE_FLAGS) +LINK_FLAGS=-Wl,-syslibroot,$(ARCH_BASE_FLAGS) +DYN_FLAGS=$(LINK_FLAGS) -framework Carbon -bundle +endif +endif + +OPTIONS=-Wall -Wno-missing-braces -Wno-char-subscripts -DSCI_NAMESPACE -DMACOSX -DSCI_LEXER + +#DEBUG = 1 + +ifdef DEBUG +DFLAGS=-DDEBUG -g +else +DFLAGS=-DNDEBUG -Os +endif + +ifdef CONTAINER_HANDLES_EVENTS +CONTAINER=-DCONTAINER_HANDLES_EVENTS=1 +endif + +ifdef EXT_INPUT +EXT_INPUT=-DEXT_INPUT +EXTOBS=ExtInput.o +endif + +.cxx.o: + $(CC) $(CXXFLAGS) $(OPTIONS) $(DFLAGS) $(CONTAINER) $(ARCHFLAGS) $(EXT_INPUT) $(INCLUDEDIRS) -c $< +.c.o: + $(CCOMP) $(CXXFLAGS) $(OPTIONS) $(DFLAGS) $(CONTAINER) $(ARCHFLAGS) $(EXT_INPUT) $(INCLUDEDIRS) -w -c $< + +#++Autogenerated -- run src/LexGen.py to regenerate +#**LEXOBJS=\\\n\(\*.o \) +LEXOBJS=\ +LexAbaqus.o LexAda.o LexAPDL.o LexAsm.o LexAsn1.o LexASY.o LexAU3.o LexAVE.o \ +LexBaan.o LexBash.o LexBasic.o LexBullant.o LexCaml.o LexCLW.o LexCmake.o \ +LexCOBOL.o LexConf.o LexCPP.o LexCrontab.o LexCsound.o LexCSS.o LexD.o \ +LexEiffel.o LexErlang.o LexEScript.o LexFlagship.o LexForth.o LexFortran.o \ +LexGAP.o LexGui4Cli.o LexHaskell.o LexHTML.o LexInno.o LexKix.o LexLisp.o \ +LexLout.o LexLua.o LexMagik.o LexMarkdown.o LexMatlab.o LexMetapost.o \ +LexMMIXAL.o LexMPT.o LexMSSQL.o LexMySQL.o LexNimrod.o LexNsis.o LexOpal.o \ +LexOthers.o LexPascal.o LexPB.o LexPerl.o LexPLM.o LexPOV.o LexPowerPro.o \ +LexPowerShell.o LexProgress.o LexPS.o LexPython.o LexR.o LexRebol.o LexRuby.o \ +LexScriptol.o LexSmalltalk.o LexSML.o LexSorcus.o LexSpecman.o LexSpice.o \ +LexSQL.o LexTACL.o LexTADS3.o LexTAL.o LexTCL.o LexTeX.o LexVB.o LexVerilog.o \ +LexVHDL.o LexYAML.o +#--Autogenerated -- end of automatically generated section + +# The LEXOBJS have to be treated specially as the functions in them are not called from external code + +all: $(STATICLIB) $(LEXOBJS) + +shared: $(DYNAMICLIB) $(LEXOBJS) + +clean: + rm -f *.o $(COMPLIB) + +deps: + $(CC) -MM -DSCI_NAMESPACE -DMACOSX -DSCI_LEXER $(CXXFLAGS) $(INCLUDEDIRS) *.cxx ../src/*.cxx >deps.mak + +COMPLIB=DocumentAccessor.o WindowAccessor.o KeyWords.o StyleContext.o \ + CharClassify.o Decoration.o Document.o PerLine.o CallTip.o PositionCache.o \ + ScintillaBase.o ContractionState.o Editor.o ExternalLexer.o PropSet.o PlatMacOSX.o \ + KeyMap.o LineMarker.o ScintillaMacOSX.o CellBuffer.o ViewStyle.o \ + RESearch.o RunStyles.o Selection.o Style.o Indicator.o AutoComplete.o UniConversion.o XPM.o \ + TCarbonEvent.o TView.o ScintillaCallTip.o $(EXTOBS) \ + $(LEXOBJS) + +$(STATICLIB): $(COMPLIB) + $(LIBTOOL) -static -o $@ $^ + +$(DYNAMICLIB): $(COMPLIB) + $(CC) -dynamic -o $@ $(DYN_FLAGS) $^ + +# Generate header files from Scintilla.iface +../include/Scintilla_gen.h: ../include/HFacer.py ../include/Face.py ../include/Scintilla.iface + cd ../include && python HFacer.py +../include/SciLexer_gen.h: ../include/HFacer.py ../include/Face.py ../include/Scintilla.iface + cd ../include && python HFacer.py +../include/Scintilla.h: ../include/Scintilla_gen.h +../include/SciLexer.h: ../include/SciLexer_gen.h + +# Automatically generate header dependencies with "make deps" +include deps.mak diff --git a/scintilla/src/FontQuality.h b/scintilla/src/FontQuality.h new file mode 100644 index 00000000..3ec94f0c --- /dev/null +++ b/scintilla/src/FontQuality.h @@ -0,0 +1,12 @@ +// Scintilla source code edit control +/** @file FontQuality.h + ** Definitions to control font anti-aliasing. + **/ +// Copyright 1998-2009 by Neil Hodgson +// The License.txt file describes the conditions under which this software may be distributed. + +#define SC_EFF_QUALITY_MASK 0xF +#define SC_EFF_QUALITY_DEFAULT 0 +#define SC_EFF_QUALITY_NON_ANTIALIASED 1 +#define SC_EFF_QUALITY_ANTIALIASED 2 +#define SC_EFF_QUALITY_LCD_OPTIMIZED 3 diff --git a/scintilla/src/LexMarkdown.cxx b/scintilla/src/LexMarkdown.cxx new file mode 100644 index 00000000..9e69b313 --- /dev/null +++ b/scintilla/src/LexMarkdown.cxx @@ -0,0 +1,412 @@ +/****************************************************************** + * LexMarkdown.cxx + * + * A simple Markdown lexer for scintilla. + * + * Includes highlighting for some extra features from the + * Pandoc implementation; strikeout, using '#.' as a default + * ordered list item marker, and delimited code blocks. + * + * Limitations: + * + * Standard indented code blocks are not highlighted at all, + * as it would conflict with other indentation schemes. Use + * delimited code blocks for blanket highlighting of an + * entire code block. Embedded HTML is not highlighted either. + * Blanket HTML highlighting has issues, because some Markdown + * implementations allow Markdown markup inside of the HTML. Also, + * there is a following blank line issue that can't be ignored, + * explained in the next paragraph. Embedded HTML and code + * blocks would be better supported with language specific + * highlighting. + * + * The highlighting aims to accurately reflect correct syntax, + * but a few restrictions are relaxed. Delimited code blocks are + * highlighted, even if the line following the code block is not blank. + * Requiring a blank line after a block, breaks the highlighting + * in certain cases, because of the way Scintilla ends up calling + * the lexer. + * + * Written by Jon Strait - jstrait@moonloop.net + * + * The License.txt file describes the conditions under which this + * software may be distributed. + * + *****************************************************************/ + +#include +#include +#include +#include +#include + +#include "Platform.h" + +#include "PropSet.h" +#include "Accessor.h" +#include "StyleContext.h" +#include "KeyWords.h" +#include "Scintilla.h" +#include "SciLexer.h" + +#ifdef SCI_NAMESPACE +using namespace Scintilla; +#endif + +static inline bool IsNewline(const int ch) { + return (ch == '\n' || ch == '\r'); +} + +// True if can follow ch down to the end with possibly trailing whitespace +static bool FollowToLineEnd(const int ch, const int state, const unsigned int endPos, StyleContext &sc) { + unsigned int i = 0; + while (sc.GetRelative(++i) == ch) + ; + // Skip over whitespace + while (IsASpaceOrTab(sc.GetRelative(i)) && sc.currentPos + i < endPos) + ++i; + if (IsNewline(sc.GetRelative(i)) || sc.currentPos + i == endPos) { + sc.Forward(i); + sc.ChangeState(state); + sc.SetState(SCE_MARKDOWN_LINE_BEGIN); + return true; + } + else return false; +} + +// Set the state on text section from current to length characters, +// then set the rest until the newline to default, except for any characters matching token +static void SetStateAndZoom(const int state, const int length, const int token, StyleContext &sc) { + sc.SetState(state); + sc.Forward(length); + sc.SetState(SCE_MARKDOWN_DEFAULT); + sc.Forward(); + bool started = false; + while (sc.More() && !IsNewline(sc.ch)) { + if (sc.ch == token && !started) { + sc.SetState(state); + started = true; + } + else if (sc.ch != token) { + sc.SetState(SCE_MARKDOWN_DEFAULT); + started = false; + } + sc.Forward(); + } + sc.SetState(SCE_MARKDOWN_LINE_BEGIN); +} + +// Does the previous line have more than spaces and tabs? +static bool HasPrevLineContent(StyleContext &sc) { + int i = 0; + // Go back to the previous newline + while ((--i + sc.currentPos) && !IsNewline(sc.GetRelative(i))) + ; + while (--i + sc.currentPos) { + if (IsNewline(sc.GetRelative(i))) + break; + if (!IsASpaceOrTab(sc.GetRelative(i))) + return true; + } + return false; +} + +static bool IsValidHrule(const unsigned int endPos, StyleContext &sc) { + int c, count = 1; + unsigned int i = 0; + while (++i) { + c = sc.GetRelative(i); + if (c == sc.ch) + ++count; + // hit a terminating character + else if (!IsASpaceOrTab(c) || sc.currentPos + i == endPos) { + // Are we a valid HRULE + if ((IsNewline(c) || sc.currentPos + i == endPos) && + count >= 3 && !HasPrevLineContent(sc)) { + sc.SetState(SCE_MARKDOWN_HRULE); + sc.Forward(i); + sc.SetState(SCE_MARKDOWN_LINE_BEGIN); + return true; + } + else { + sc.SetState(SCE_MARKDOWN_DEFAULT); + return false; + } + } + } + return false; +} + +static void ColorizeMarkdownDoc(unsigned int startPos, int length, int initStyle, + WordList **, Accessor &styler) { + unsigned int endPos = startPos + length; + int precharCount = 0; + // Don't advance on a new loop iteration and retry at the same position. + // Useful in the corner case of having to start at the beginning file position + // in the default state. + bool freezeCursor = false; + + StyleContext sc(startPos, length, initStyle, styler); + + while (sc.More()) { + // Skip past escaped characters + if (sc.ch == '\\') { + sc.Forward(); + continue; + } + + // A blockquotes resets the line semantics + if (sc.state == SCE_MARKDOWN_BLOCKQUOTE) + sc.SetState(SCE_MARKDOWN_LINE_BEGIN); + + // Conditional state-based actions + if (sc.state == SCE_MARKDOWN_CODE2) { + if (sc.Match("``") && sc.GetRelative(-2) != ' ') { + sc.Forward(2); + sc.SetState(SCE_MARKDOWN_DEFAULT); + } + } + else if (sc.state == SCE_MARKDOWN_CODE) { + if (sc.ch == '`' && sc.chPrev != ' ') + sc.ForwardSetState(SCE_MARKDOWN_DEFAULT); + } + /* De-activated because it gets in the way of other valid indentation + * schemes, for example multiple paragraphs inside a list item. + // Code block + else if (sc.state == SCE_MARKDOWN_CODEBK) { + bool d = true; + if (IsNewline(sc.ch)) { + if (sc.chNext != '\t') { + for (int c = 1; c < 5; ++c) { + if (sc.GetRelative(c) != ' ') + d = false; + } + } + } + else if (sc.atLineStart) { + if (sc.ch != '\t' ) { + for (int i = 0; i < 4; ++i) { + if (sc.GetRelative(i) != ' ') + d = false; + } + } + } + if (!d) + sc.SetState(SCE_MARKDOWN_LINE_BEGIN); + } + */ + // Strong + else if (sc.state == SCE_MARKDOWN_STRONG1) { + if (sc.Match("**") && sc.chPrev != ' ') { + sc.Forward(2); + sc.SetState(SCE_MARKDOWN_DEFAULT); + } + } + else if (sc.state == SCE_MARKDOWN_STRONG2) { + if (sc.Match("__") && sc.chPrev != ' ') { + sc.Forward(2); + sc.SetState(SCE_MARKDOWN_DEFAULT); + } + } + // Emphasis + else if (sc.state == SCE_MARKDOWN_EM1) { + if (sc.ch == '*' && sc.chPrev != ' ') + sc.ForwardSetState(SCE_MARKDOWN_DEFAULT); + } + else if (sc.state == SCE_MARKDOWN_EM2) { + if (sc.ch == '_' && sc.chPrev != ' ') + sc.ForwardSetState(SCE_MARKDOWN_DEFAULT); + } + else if (sc.state == SCE_MARKDOWN_CODEBK) { + if (sc.atLineStart && sc.Match("~~~")) { + int i = 1; + while (!IsNewline(sc.GetRelative(i)) && sc.currentPos + i < endPos) + i++; + sc.Forward(i); + sc.SetState(SCE_MARKDOWN_DEFAULT); + } + } + else if (sc.state == SCE_MARKDOWN_STRIKEOUT) { + if (sc.Match("~~") && sc.chPrev != ' ') { + sc.Forward(2); + sc.SetState(SCE_MARKDOWN_DEFAULT); + } + } + else if (sc.state == SCE_MARKDOWN_LINE_BEGIN) { + // Header + if (sc.Match("######")) + SetStateAndZoom(SCE_MARKDOWN_HEADER6, 6, '#', sc); + else if (sc.Match("#####")) + SetStateAndZoom(SCE_MARKDOWN_HEADER5, 5, '#', sc); + else if (sc.Match("####")) + SetStateAndZoom(SCE_MARKDOWN_HEADER4, 4, '#', sc); + else if (sc.Match("###")) + SetStateAndZoom(SCE_MARKDOWN_HEADER3, 3, '#', sc); + else if (sc.Match("##")) + SetStateAndZoom(SCE_MARKDOWN_HEADER2, 2, '#', sc); + else if (sc.Match("#")) { + // Catch the special case of an unordered list + if (sc.chNext == '.' && IsASpaceOrTab(sc.GetRelative(2))) { + precharCount = 0; + sc.SetState(SCE_MARKDOWN_PRECHAR); + } + else + SetStateAndZoom(SCE_MARKDOWN_HEADER1, 1, '#', sc); + } + // Code block + else if (sc.Match("~~~")) { + if (!HasPrevLineContent(sc)) + sc.SetState(SCE_MARKDOWN_CODEBK); + else + sc.SetState(SCE_MARKDOWN_DEFAULT); + } + else if (sc.ch == '=') { + if (HasPrevLineContent(sc) && FollowToLineEnd('=', SCE_MARKDOWN_HEADER1, endPos, sc)) + ; + else + sc.SetState(SCE_MARKDOWN_DEFAULT); + } + else if (sc.ch == '-') { + if (HasPrevLineContent(sc) && FollowToLineEnd('-', SCE_MARKDOWN_HEADER2, endPos, sc)) + ; + else { + precharCount = 0; + sc.SetState(SCE_MARKDOWN_PRECHAR); + } + } + else if (IsNewline(sc.ch)) + sc.SetState(SCE_MARKDOWN_LINE_BEGIN); + else { + precharCount = 0; + sc.SetState(SCE_MARKDOWN_PRECHAR); + } + } + + // The header lasts until the newline + else if (sc.state == SCE_MARKDOWN_HEADER1 || sc.state == SCE_MARKDOWN_HEADER2 || + sc.state == SCE_MARKDOWN_HEADER3 || sc.state == SCE_MARKDOWN_HEADER4 || + sc.state == SCE_MARKDOWN_HEADER5 || sc.state == SCE_MARKDOWN_HEADER6) { + if (IsNewline(sc.ch)) + sc.SetState(SCE_MARKDOWN_LINE_BEGIN); + } + + // New state only within the initial whitespace + if (sc.state == SCE_MARKDOWN_PRECHAR) { + // Blockquote + if (sc.ch == '>' && precharCount < 5) + sc.SetState(SCE_MARKDOWN_BLOCKQUOTE); + /* + // Begin of code block + else if (!HasPrevLineContent(sc) && (sc.chPrev == '\t' || precharCount >= 4)) + sc.SetState(SCE_MARKDOWN_CODEBK); + */ + // HRule - Total of three or more hyphens, asterisks, or underscores + // on a line by themselves + else if ((sc.ch == '-' || sc.ch == '*' || sc.ch == '_') && IsValidHrule(endPos, sc)) + ; + // Unordered list + else if ((sc.ch == '-' || sc.ch == '*' || sc.ch == '+') && IsASpaceOrTab(sc.chNext)) { + sc.SetState(SCE_MARKDOWN_ULIST_ITEM); + sc.ForwardSetState(SCE_MARKDOWN_DEFAULT); + } + // Ordered list + else if (IsADigit(sc.ch)) { + int digitCount = 0; + while (IsADigit(sc.GetRelative(++digitCount))) + ; + if (sc.GetRelative(digitCount) == '.' && + IsASpaceOrTab(sc.GetRelative(digitCount + 1))) { + sc.SetState(SCE_MARKDOWN_OLIST_ITEM); + sc.Forward(digitCount + 1); + sc.SetState(SCE_MARKDOWN_DEFAULT); + } + } + // Alternate Ordered list + else if (sc.ch == '#' && sc.chNext == '.' && IsASpaceOrTab(sc.GetRelative(2))) { + sc.SetState(SCE_MARKDOWN_OLIST_ITEM); + sc.Forward(2); + sc.SetState(SCE_MARKDOWN_DEFAULT); + } + else if (sc.ch != ' ' || precharCount > 2) + sc.SetState(SCE_MARKDOWN_DEFAULT); + else + ++precharCount; + } + + // New state anywhere in doc + if (sc.state == SCE_MARKDOWN_DEFAULT) { + if (sc.atLineStart && sc.ch == '#') { + sc.SetState(SCE_MARKDOWN_LINE_BEGIN); + freezeCursor = true; + } + // Links and Images + if (sc.Match("![") || sc.ch == '[') { + int i = 0, j = 0, k = 0; + int len = endPos - sc.currentPos; + while (i < len && (sc.GetRelative(++i) != ']' || sc.GetRelative(i - 1) == '\\')) + ; + if (sc.GetRelative(i) == ']') { + j = i; + if (sc.GetRelative(++i) == '(') { + while (i < len && (sc.GetRelative(++i) != ')' || sc.GetRelative(i - 1) == '\\')) + ; + if (sc.GetRelative(i) == ')') + k = i; + } + else if (sc.GetRelative(i) == '[' || sc.GetRelative(++i) == '[') { + while (i < len && (sc.GetRelative(++i) != ']' || sc.GetRelative(i - 1) == '\\')) + ; + if (sc.GetRelative(i) == ']') + k = i; + } + } + // At least a link text + if (j) { + sc.SetState(SCE_MARKDOWN_LINK); + sc.Forward(j); + // Also has a URL or reference portion + if (k) + sc.Forward(k - j); + sc.ForwardSetState(SCE_MARKDOWN_DEFAULT); + } + } + // Code - also a special case for alternate inside spacing + if (sc.Match("``") && sc.GetRelative(3) != ' ') { + sc.SetState(SCE_MARKDOWN_CODE2); + sc.Forward(); + } + else if (sc.ch == '`' && sc.chNext != ' ') { + sc.SetState(SCE_MARKDOWN_CODE); + } + // Strong + else if (sc.Match("**") && sc.GetRelative(2) != ' ') { + sc.SetState(SCE_MARKDOWN_STRONG1); + sc.Forward(); + } + else if (sc.Match("__") && sc.GetRelative(2) != ' ') { + sc.SetState(SCE_MARKDOWN_STRONG2); + sc.Forward(); + } + // Emphasis + else if (sc.ch == '*' && sc.chNext != ' ') + sc.SetState(SCE_MARKDOWN_EM1); + else if (sc.ch == '_' && sc.chNext != ' ') + sc.SetState(SCE_MARKDOWN_EM2); + // Strikeout + else if (sc.Match("~~") && sc.GetRelative(2) != ' ') { + sc.SetState(SCE_MARKDOWN_STRIKEOUT); + sc.Forward(); + } + // Beginning of line + else if (IsNewline(sc.ch)) + sc.SetState(SCE_MARKDOWN_LINE_BEGIN); + } + // Advance if not holding back the cursor for this iteration. + if (!freezeCursor) + sc.Forward(); + freezeCursor = false; + } + sc.Complete(); +} + +LexerModule lmMarkdown(SCLEX_MARKDOWN, ColorizeMarkdownDoc, "markdown");